4 * Home page of code is: http://smartmontools.sourceforge.net
6 * Copyright (C) 2002-6 Bruce Allen <smartmontools-support@lists.sourceforge.net>
7 * Copyright (C) 1999-2000 Michael Cornwell <cornwell@acm.org>
8 * Copyright (C) 2000 Andre Hedrick <andre@linux-ide.org>
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2, or (at your option)
15 * You should have received a copy of the GNU General Public License
16 * (for example COPYING); if not, write to the Free
17 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 * This code was originally developed as a Senior Thesis by Michael Cornwell
20 * at the Concurrent Systems Laboratory (now part of the Storage Systems
21 * Research Center), Jack Baskin School of Engineering, University of
22 * California, Santa Cruz. http://ssrc.soe.ucsc.edu/
39 const char *atacmds_c_cvsid
="$Id: atacmds.cpp,v 1.176 2006/08/25 06:06:24 sxzzsf Exp $"
40 ATACMDS_H_CVSID CONFIG_H_CVSID EXTERN_H_CVSID INT64_H_CVSID SCSIATA_H_CVSID UTILITY_H_CVSID
;
42 // to hold onto exit code for atexit routine
43 extern int exitstatus
;
45 // for passing global control variables
46 extern smartmonctrl
*con
;
48 // These Drive Identity tables are taken from hdparm 5.2, and are also
49 // given in the ATA/ATAPI specs for the IDENTIFY DEVICE command. Note
50 // that SMART was first added into the ATA/ATAPI-3 Standard with
51 // Revision 3 of the document, July 25, 1995. Look at the "Document
52 // Status" revision commands at the beginning of
53 // http://www.t13.org/project/d2008r6.pdf to see this.
54 #define NOVAL_0 0x0000
55 #define NOVAL_1 0xffff
56 /* word 81: minor version number */
57 #define MINOR_MAX 0x22
58 const char *minor_str
[] = { /* word 81 value: */
59 "Device does not report version", /* 0x0000 */
60 "ATA-1 X3T9.2 781D prior to revision 4", /* 0x0001 */
61 "ATA-1 published, ANSI X3.221-1994", /* 0x0002 */
62 "ATA-1 X3T9.2 781D revision 4", /* 0x0003 */
63 "ATA-2 published, ANSI X3.279-1996", /* 0x0004 */
64 "ATA-2 X3T10 948D prior to revision 2k", /* 0x0005 */
65 "ATA-3 X3T10 2008D revision 1", /* 0x0006 */ /* SMART NOT INCLUDED */
66 "ATA-2 X3T10 948D revision 2k", /* 0x0007 */
67 "ATA-3 X3T10 2008D revision 0", /* 0x0008 */
68 "ATA-2 X3T10 948D revision 3", /* 0x0009 */
69 "ATA-3 published, ANSI X3.298-199x", /* 0x000a */
70 "ATA-3 X3T10 2008D revision 6", /* 0x000b */ /* 1st VERSION WITH SMART */
71 "ATA-3 X3T13 2008D revision 7 and 7a", /* 0x000c */
72 "ATA/ATAPI-4 X3T13 1153D revision 6", /* 0x000d */
73 "ATA/ATAPI-4 T13 1153D revision 13", /* 0x000e */
74 "ATA/ATAPI-4 X3T13 1153D revision 7", /* 0x000f */
75 "ATA/ATAPI-4 T13 1153D revision 18", /* 0x0010 */
76 "ATA/ATAPI-4 T13 1153D revision 15", /* 0x0011 */
77 "ATA/ATAPI-4 published, ANSI NCITS 317-1998", /* 0x0012 */
78 "ATA/ATAPI-5 T13 1321D revision 3", /* 0x0013 */
79 "ATA/ATAPI-4 T13 1153D revision 14", /* 0x0014 */
80 "ATA/ATAPI-5 T13 1321D revision 1", /* 0x0015 */
81 "ATA/ATAPI-5 published, ANSI NCITS 340-2000", /* 0x0016 */
82 "ATA/ATAPI-4 T13 1153D revision 17", /* 0x0017 */
83 "ATA/ATAPI-6 T13 1410D revision 0", /* 0x0018 */
84 "ATA/ATAPI-6 T13 1410D revision 3a", /* 0x0019 */
85 "ATA/ATAPI-7 T13 1532D revision 1", /* 0x001a */
86 "ATA/ATAPI-6 T13 1410D revision 2", /* 0x001b */
87 "ATA/ATAPI-6 T13 1410D revision 1", /* 0x001c */
88 "ATA/ATAPI-7 published, ANSI INCITS 397-2005",/* 0x001d */
89 "ATA/ATAPI-7 T13 1532D revision 0", /* 0x001e */
90 "reserved", /* 0x001f */
91 "reserved", /* 0x0020 */
92 "ATA/ATAPI-7 T13 1532D revision 4a", /* 0x0021 */
93 "ATA/ATAPI-6 published, ANSI INCITS 361-2002" /* 0x0022 */
96 // NOTE ATA/ATAPI-4 REV 4 was the LAST revision where the device
97 // attribute structures were NOT completely vendor specific. So any
98 // disk that is ATA/ATAPI-4 or above can not be trusted to show the
99 // vendor values in sensible format.
101 // Negative values below are because it doesn't support SMART
102 const int actual_ver
[] = {
104 0, /* 0x0000 WARNING: */
105 1, /* 0x0001 WARNING: */
106 1, /* 0x0002 WARNING: */
107 1, /* 0x0003 WARNING: */
108 2, /* 0x0004 WARNING: This array */
109 2, /* 0x0005 WARNING: corresponds */
110 -3, /*<== */ /* 0x0006 WARNING: *exactly* */
111 2, /* 0x0007 WARNING: to the ATA/ */
112 -3, /*<== */ /* 0x0008 WARNING: ATAPI version */
113 2, /* 0x0009 WARNING: listed in */
114 3, /* 0x000a WARNING: the */
115 3, /* 0x000b WARNING: minor_str */
116 3, /* 0x000c WARNING: array */
117 4, /* 0x000d WARNING: above. */
118 4, /* 0x000e WARNING: */
119 4, /* 0x000f WARNING: If you change */
120 4, /* 0x0010 WARNING: that one, */
121 4, /* 0x0011 WARNING: change this one */
122 4, /* 0x0012 WARNING: too!!! */
123 5, /* 0x0013 WARNING: */
124 4, /* 0x0014 WARNING: */
125 5, /* 0x0015 WARNING: */
126 5, /* 0x0016 WARNING: */
127 4, /* 0x0017 WARNING: */
128 6, /* 0x0018 WARNING: */
129 6, /* 0x0019 WARNING: */
130 7, /* 0x001a WARNING: */
131 6, /* 0x001b WARNING: */
132 6, /* 0x001c WARNING: */
133 7, /* 0x001d WARNING: */
134 7, /* 0x001e WARNING: */
135 0, /* 0x001f WARNING: */
136 0, /* 0x0020 WARNING: */
137 7, /* 0x0021 WARNING: */
138 6 /* 0x0022 WARNING: */
141 // When you add additional items to this list, you should then:
142 // 0 -- update this list
143 // 1 -- modify the following function parse_attribute_def()
144 // 2 -- if needed, modify ataPrintSmartAttribRawValue()
145 // 3 - if needed, modify ataPrintSmartAttribName()
146 // 4 -- add #define PRESET_N_DESCRIPTION at top of knowndrives.c
147 // 5 -- add drive in question into knowndrives[] table in knowndrives.c
148 // 6 -- update smartctl.8
149 // 7 -- update smartd.8
150 // 8 -- do "make smartd.conf.5" to update smartd.conf.5
151 // 9 -- update CHANGELOG file
152 const char *vendorattributeargs
[] = {
168 "200,writeerrorcount",
178 "201,detectedtacount",
180 "192,emergencyretractcyclect",
182 "198,offlinescanuncsectorct",
183 // NULL should always terminate the array
187 // This are the meanings of the Self-test failure checkpoint byte.
188 // This is in the self-test log at offset 4 bytes into the self-test
189 // descriptor and in the SMART READ DATA structure at byte offset
190 // 371. These codes are not well documented. The meanings returned by
191 // this routine are used (at least) by Maxtor and IBM. Returns NULL if
192 // not recognized. Currently the maximum length is 15 bytes.
193 const char *SelfTestFailureCodeName(unsigned char which
){
199 return "Servo_Basic";
201 return "Servo_Random";
203 return "G-list_Scan";
205 return "Handling_Damage";
213 // This is a utility function for parsing pairs like "9,minutes" or
214 // "220,temp", and putting the correct flag into the attributedefs
215 // array. Returns 1 if problem, 0 if pair has been recongized.
216 int parse_attribute_def(char *pair
, unsigned char **defsptr
){
221 // If array does not exist, allocate it
222 if (!*defsptr
&& !(*defsptr
=(unsigned char *)calloc(MAX_ATTRIBUTE_NUM
, 1))){
223 pout("Out of memory in parse_attribute_def\n");
229 // look along list and see if we find the pair
230 for (i
=0; vendorattributeargs
[i
] && strcmp(pair
, vendorattributeargs
[i
]); i
++);
234 // attribute 9 is power on time in minutes
238 // attribute 9 is power-on-time in seconds
242 // attribute 9 is temperature in celsius
246 // attribute 220 is temperature in celsius
250 // print all attributes in raw 8-bit form
251 for (j
=0; j
<MAX_ATTRIBUTE_NUM
; j
++)
255 // print all attributes in raw 16-bit form
256 for (j
=0; j
<MAX_ATTRIBUTE_NUM
; j
++)
260 // print all attributes in raw 48-bit form
261 for (j
=0; j
<MAX_ATTRIBUTE_NUM
; j
++)
265 // attribute 200 is write error count
269 // attribute 9 increments once every 30 seconds (power on time
274 // attribute 194 is ten times disk temp in Celsius
278 // attribute 194 is unknown
282 // Hitachi : Attributes 193 has 2 values : 1 load, 1 normal unload
301 // At this point, either the pair was not found, or it is of the
302 // form N,uninterpreted, in which case we need to parse N
303 j
=sscanf(pair
,"%d,%14s", &i
, temp
);
305 // if no match to pattern, unrecognized
306 if (j
!=2 || i
<0 || i
>255)
309 // check for recognized strings
310 if (!strcmp(temp
, "raw8")) {
315 // check for recognized strings
316 if (!strcmp(temp
, "raw16")) {
321 // check for recognized strings
322 if (!strcmp(temp
, "raw48")) {
327 // didn't recognize the string
331 // Structure used in sorting the array vendorattributeargs[].
332 typedef struct vaa_pair_s
{
334 const char *padded_vaa
;
337 // Returns a copy of s with all numbers of less than three digits padded with
338 // leading zeros. Returns NULL if there isn't enough memory available. The
339 // memory for the string is dynamically allocated and should be freed by the
341 char *pad_numbers(const char *s
)
345 int i
, len
, ndigits
= 0;
347 // Allocate the maximum possible amount of memory needed.
348 if (!(t
= (char *)malloc(strlen(s
)*2+2)))
351 // Copy the string s to t, padding any numbers of less than three digits
352 // with leading zeros. The string is copied backwards to simplify the code.
355 while (( r
-- >= s
)) {
356 if (isdigit((int)*r
))
358 else if (ndigits
> 0) {
359 while (ndigits
++ < 3)
367 // Reverse the string in t.
369 for (i
= 0; i
< len
/2; i
++) {
378 // Comparison function for qsort(). Used by sort_vendorattributeargs().
379 int compare_vaa_pairs(const void *a
, const void *b
)
381 vaa_pair
*p
= (vaa_pair
*)a
;
382 vaa_pair
*q
= (vaa_pair
*)b
;
384 return strcmp(p
->padded_vaa
, q
->padded_vaa
);
387 // Returns a sorted list of vendorattributeargs or NULL if there is not enough
388 // memory available. The memory for the list is allocated dynamically and
389 // should be freed by the caller.
390 // To perform the sort, any numbers in the strings are padded out to three
391 // digits by adding leading zeros. For example,
393 // "9,minutes" becomes "009,minutes"
394 // "N,raw16" becomes "N,raw016"
396 // and the original strings are paired with the padded strings. The list of
397 // pairs is then sorted by comparing the padded strings (using strcmp) and the
398 // result is then the list of unpadded strings.
400 const char **sort_vendorattributeargs(void) {
401 const char **ps
, **sorted_list
= NULL
;
402 vaa_pair
*pairs
, *pp
;
405 // Figure out how many strings are in vendorattributeargs[] (not including
406 // the terminating NULL).
407 count
= (sizeof vendorattributeargs
) / sizeof(char *) - 1;
409 // Construct a list of pairs of strings from vendorattributeargs[] and their
410 // padded equivalents.
411 if (!(pairs
= (vaa_pair
*)malloc(sizeof(vaa_pair
) * count
)))
413 for (ps
= vendorattributeargs
, pp
= pairs
; *ps
; ps
++, pp
++) {
415 if (!(pp
->padded_vaa
= pad_numbers(*ps
)))
419 // Sort the array of vaa_pair structures by comparing the padded strings
421 qsort(pairs
, count
, sizeof(vaa_pair
), compare_vaa_pairs
);
423 // Construct the sorted list of strings.
424 if (!(sorted_list
= (const char **)malloc(sizeof vendorattributeargs
)))
426 for (ps
= sorted_list
, pp
= pairs
, i
= 0; i
< count
; ps
++, pp
++, i
++)
432 for (i
= 0; i
< count
; i
++)
433 if (pairs
[i
].padded_vaa
)
434 free((void *)pairs
[i
].padded_vaa
);
438 // If there was a problem creating the list then sorted_list should now
443 // Function to return a multiline string containing a list of the arguments in
444 // vendorattributeargs[]. The strings are preceeded by tabs and followed
445 // (except for the last) by newlines.
446 // This function allocates the required memory for the string and the caller
447 // must use free() to free it. It returns NULL if the required memory can't
449 char *create_vendor_attribute_arg_list(void){
450 const char **ps
, **sorted
;
454 // Get a sorted list of vendor attribute arguments. If the sort fails
455 // (which should only happen if the system is really low on memory) then just
456 // use the unordered list.
457 if (!(sorted
= (const char **) sort_vendorattributeargs()))
458 sorted
= vendorattributeargs
;
460 // Calculate the required number of characters
461 len
= 1; // At least one char ('\0')
462 for (ps
= sorted
; *ps
!= NULL
; ps
++) {
463 len
+= 1; // For the tab
464 len
+= strlen(*ps
); // For the actual argument string
466 len
++; // For the newline if required
469 // Attempt to allocate memory for the string
470 if (!(s
= (char *)malloc(len
)))
473 // Construct the string
475 for (ps
= sorted
; *ps
!= NULL
; ps
++) {
482 free((char **)sorted
);
484 // Return a pointer to the string
488 // swap two bytes. Point to low address
489 void swap2(char *location
){
491 *location
=*(location
+1);
496 // swap four bytes. Point to low address
497 void swap4(char *location
){
499 *location
=*(location
+3);
505 // swap eight bytes. Points to low address
506 void swap8(char *location
){
508 *location
=*(location
+7);
511 *(location
+1)=*(location
+6);
517 static char *commandstrings
[]={
520 "SMART AUTOMATIC ATTRIBUTE SAVE",
521 "SMART IMMEDIATE OFFLINE",
522 "SMART AUTO OFFLINE",
524 "SMART STATUS CHECK",
525 "SMART READ ATTRIBUTE VALUES",
526 "SMART READ ATTRIBUTE THRESHOLDS",
529 "IDENTIFY PACKET DEVICE",
532 "WARNING (UNDEFINED COMMAND -- CONTACT DEVELOPERS AT " PACKAGE_BUGREPORT
")\n"
535 void prettyprint(unsigned char *stuff
, char *name
){
537 pout("\n===== [%s] DATA START (BASE-16) =====\n", name
);
538 for (i
=0; i
<32; i
++){
539 pout("%03d-%03d: ", 16*i
, 16*(i
+1)-1);
541 pout("%02x ",*stuff
++);
542 pout("%02x\n",*stuff
++);
544 pout("===== [%s] DATA END (512 Bytes) =====\n\n", name
);
547 // This function provides the pretty-print reporting for SMART
548 // commands: it implements the various -r "reporting" options for ATA
550 int smartcommandhandler(int device
, smart_command_set command
, int select
, char *data
){
553 // This conditional is true for commands that return data
554 int getsdata
=(command
==PIDENTIFY
||
557 command
==READ_THRESHOLDS
||
558 command
==READ_VALUES
||
559 command
==CHECK_POWER_MODE
);
561 int sendsdata
=(command
==WRITE_LOG
);
563 // If reporting is enabled, say what the command will be before it's executed
564 if (con
->reportataioctl
){
565 // conditional is true for commands that use parameters
566 int usesparam
=(command
==READ_LOG
||
567 command
==AUTO_OFFLINE
||
569 command
==IMMEDIATE_OFFLINE
||
572 pout("\nREPORT-IOCTL: DeviceFD=%d Command=%s", device
, commandstrings
[command
]);
574 pout(" InputParameter=%d\n", select
);
579 if ((getsdata
|| sendsdata
) && !data
){
580 pout("REPORT-IOCTL: Unable to execute command %s : data destination address is NULL\n", commandstrings
[command
]);
584 // The reporting is cleaner, and we will find coding bugs faster, if
585 // the commands that failed clearly return empty (zeroed) data
588 if (command
==CHECK_POWER_MODE
)
591 memset(data
, '\0', 512);
595 // If reporting is enabled, say what input was sent to the command
596 if (con
->reportataioctl
&& sendsdata
){
597 pout("REPORT-IOCTL: DeviceFD=%d Command=%s", device
, commandstrings
[command
]);
598 // if requested, pretty-print the output data structure
599 if (con
->reportataioctl
>1)
600 prettyprint((unsigned char *)data
, commandstrings
[command
]);
603 // In case the command produces an error, we'll want to know what it is:
606 // now execute the command
607 switch (con
->controller_type
) {
608 case CONTROLLER_3WARE_678K
:
609 case CONTROLLER_3WARE_678K_CHAR
:
610 case CONTROLLER_3WARE_9000_CHAR
:
611 retval
=escalade_command_interface(device
, con
->controller_port
-1, con
->controller_type
, command
, select
, data
);
612 if (retval
&& con
->controller_port
<=0)
613 pout("WARNING: apparently missing '-d 3ware,N' disk specification\n");
615 case CONTROLLER_MARVELL_SATA
:
616 retval
=marvell_command_interface(device
, command
, select
, data
);
619 retval
=sat_command_interface(device
, command
, select
, data
);
622 retval
=highpoint_command_interface(device
, command
, select
, data
);
625 retval
=ata_command_interface(device
, command
, select
, data
);
628 // If reporting is enabled, say what output was produced by the command
629 if (con
->reportataioctl
){
631 pout("REPORT-IOCTL: DeviceFD=%d Command=%s returned %d errno=%d [%s]\n",
632 device
, commandstrings
[command
], retval
, errno
, strerror(errno
));
634 pout("REPORT-IOCTL: DeviceFD=%d Command=%s returned %d\n",
635 device
, commandstrings
[command
], retval
);
637 // if requested, pretty-print the output data structure
638 if (con
->reportataioctl
>1 && getsdata
) {
639 if (command
==CHECK_POWER_MODE
)
640 pout("Sector Count Register (BASE-16): %02x\n", (unsigned char)(*data
));
642 prettyprint((unsigned char *)data
, commandstrings
[command
]);
649 // This function computes the checksum of a single disk sector (512
650 // bytes). Returns zero if checksum is OK, nonzero if the checksum is
651 // incorrect. The size (512) is correct for all SMART structures.
652 unsigned char checksum(unsigned char *buffer
){
656 for (i
=0; i
<512; i
++)
662 // returns -1 if command fails or the device is in Sleep mode, else
663 // value of Sector Count register. Sector Count result values:
664 // 00h device is in Standby mode.
665 // 80h device is in Idle mode.
666 // FFh device is in Active mode or Idle mode.
668 int ataCheckPowerMode(int device
) {
669 unsigned char result
;
671 if ((smartcommandhandler(device
, CHECK_POWER_MODE
, 0, (char *)&result
)))
674 if (result
!=0 && result
!=0x80 && result
!=0xff)
675 pout("ataCheckPowerMode(): ATA CHECK POWER MODE returned unknown Sector Count Register value %02x\n", result
);
683 // Reads current Device Identity info (512 bytes) into buf. Returns 0
684 // if all OK. Returns -1 if no ATA Device identity can be
685 // established. Returns >0 if Device is ATA Packet Device (not SMART
686 // capable). The value of the integer helps identify the type of
687 // Packet device, which is useful so that the user can connect the
688 // formal device number with whatever object is inside their computer.
689 int ataReadHDIdentity (int device
, struct ata_identify_device
*buf
){
690 unsigned short *rawshort
=(unsigned short *)buf
;
691 unsigned char *rawbyte
=(unsigned char *)buf
;
693 // See if device responds either to IDENTIFY DEVICE or IDENTIFY
695 if ((smartcommandhandler(device
, IDENTIFY
, 0, (char *)buf
))){
696 if (smartcommandhandler(device
, PIDENTIFY
, 0, (char *)buf
)){
702 // if machine is big-endian, swap byte order as needed
703 // (the NetBSD kernel does deliver the results in host byte order)
707 // swap various capability words that are needed
709 swap2((char *)(buf
->words047_079
+i
));
711 for (i
=80; i
<=87; i
++)
712 swap2((char *)(rawshort
+i
));
714 for (i
=0; i
<168; i
++)
715 swap2((char *)(buf
->words088_255
+i
));
719 // If there is a checksum there, validate it
720 if ((rawshort
[255] & 0x00ff) == 0x00a5 && checksum(rawbyte
))
721 checksumwarning("Drive Identity Structure");
723 // If this is a PACKET DEVICE, return device type
724 if (rawbyte
[1] & 0x80)
725 return 1+(rawbyte
[1] & 0x1f);
727 // Not a PACKET DEVICE
731 // Returns ATA version as an integer, and a pointer to a string
732 // describing which revision. Note that Revision 0 of ATA-3 does NOT
733 // support SMART. For this one case we return -3 rather than +3 as
734 // the version number. See notes above.
735 int ataVersionInfo (const char** description
, struct ata_identify_device
*drive
, unsigned short *minor
){
736 unsigned short major
;
739 // check that arrays at the top of this file are defined
741 if (sizeof(minor_str
) != sizeof(char *)*(1+MINOR_MAX
)){
742 pout("Internal error in ataVersionInfo(). minor_str[] size %d\n"
743 "is not consistent with value of MINOR_MAX+1 = %d\n",
744 (int)(sizeof(minor_str
)/sizeof(char *)), MINOR_MAX
+1);
748 if (sizeof(actual_ver
) != sizeof(int)*(1+MINOR_MAX
)){
749 pout("Internal error in ataVersionInfo(). actual_ver[] size %d\n"
750 "is not consistent with value of MINOR_MAX = %d\n",
751 (int)(sizeof(actual_ver
)/sizeof(int)), MINOR_MAX
+1);
756 // get major and minor ATA revision numbers
757 major
=drive
->major_rev_num
;
758 *minor
=drive
->minor_rev_num
;
760 // First check if device has ANY ATA version information in it
761 if (major
==NOVAL_0
|| major
==NOVAL_1
) {
766 // The minor revision number has more information - try there first
767 if (*minor
&& (*minor
<=MINOR_MAX
)){
768 int std
= actual_ver
[*minor
];
770 *description
=minor_str
[*minor
];
775 // HDPARM has a very complicated algorithm from here on. Since SMART only
776 // exists on ATA-3 and later standards, let's punt on this. If you don't
777 // like it, please fix it. The code's in CVS.
779 if (major
& (0x1<<i
))
789 // returns 1 if SMART supported, 0 if SMART unsupported, -1 if can't tell
790 int ataSmartSupport(struct ata_identify_device
*drive
){
791 unsigned short word82
=drive
->command_set_1
;
792 unsigned short word83
=drive
->command_set_2
;
794 // check if words 82/83 contain valid info
795 if ((word83
>>14) == 0x01)
796 // return value of SMART support bit
797 return word82
& 0x0001;
799 // since we can're rely on word 82, we don't know if SMART supported
803 // returns 1 if SMART enabled, 0 if SMART disabled, -1 if can't tell
804 int ataIsSmartEnabled(struct ata_identify_device
*drive
){
805 unsigned short word85
=drive
->cfs_enable_1
;
806 unsigned short word87
=drive
->csf_default
;
808 // check if words 85/86/87 contain valid info
809 if ((word87
>>14) == 0x01)
810 // return value of SMART enabled bit
811 return word85
& 0x0001;
813 // Since we can't rely word85, we don't know if SMART is enabled.
818 // Reads SMART attributes into *data
819 int ataReadSmartValues(int device
, struct ata_smart_values
*data
){
821 if (smartcommandhandler(device
, READ_VALUES
, 0, (char *)data
)){
822 syserror("Error SMART Values Read failed");
827 if (checksum((unsigned char *)data
))
828 checksumwarning("SMART Attribute Data Structure");
830 // byte swap if needed
833 swap2((char *)&(data
->revnumber
));
834 swap2((char *)&(data
->total_time_to_complete_off_line
));
835 swap2((char *)&(data
->smart_capability
));
836 for (i
=0; i
<NUMBER_ATA_SMART_ATTRIBUTES
; i
++){
837 struct ata_smart_attribute
*x
=data
->vendor_attributes
+i
;
838 swap2((char *)&(x
->flags
));
846 // This corrects some quantities that are byte reversed in the SMART
848 void fixsamsungselftestlog(struct ata_smart_selftestlog
*data
){
851 // bytes 508/509 (numbered from 0) swapped (swap of self-test index
852 // with one byte of reserved.
853 swap2((char *)&(data
->mostrecenttest
));
855 // LBA low register (here called 'selftestnumber", containing
856 // information about the TYPE of the self-test) is byte swapped with
857 // Self-test execution status byte. These are bytes N, N+1 in the
860 swap2((char *)&(data
->selftest_struct
[i
].selftestnumber
));
865 // Reads the Self Test Log (log #6)
866 int ataReadSelfTestLog (int device
, struct ata_smart_selftestlog
*data
){
868 // get data from device
869 if (smartcommandhandler(device
, READ_LOG
, 0x06, (char *)data
)){
870 syserror("Error SMART Error Self-Test Log Read failed");
874 // compute its checksum, and issue a warning if needed
875 if (checksum((unsigned char *)data
))
876 checksumwarning("SMART Self-Test Log Structure");
878 // fix firmware bugs in self-test log
879 if (con
->fixfirmwarebug
== FIX_SAMSUNG
)
880 fixsamsungselftestlog(data
);
882 // fix endian order, if needed
885 swap2((char*)&(data
->revnumber
));
886 for (i
=0; i
<21; i
++){
887 struct ata_smart_selftestlog_struct
*x
=data
->selftest_struct
+i
;
888 swap2((char *)&(x
->timestamp
));
889 swap4((char *)&(x
->lbafirstfailure
));
897 // Reads the Log Directory (log #0). Note: NO CHECKSUM!!
898 int ataReadLogDirectory (int device
, struct ata_smart_log_directory
*data
){
900 // get data from device
901 if (smartcommandhandler(device
, READ_LOG
, 0x00, (char *)data
)){
905 // swap endian order if needed
907 swap2((char *)&(data
->logversion
));
914 // Reads the selective self-test log (log #9)
915 int ataReadSelectiveSelfTestLog(int device
, struct ata_selective_self_test_log
*data
){
917 // get data from device
918 if (smartcommandhandler(device
, READ_LOG
, 0x09, (char *)data
)){
919 syserror("Error SMART Read Selective Self-Test Log failed");
923 // compute its checksum, and issue a warning if needed
924 if (checksum((unsigned char *)data
))
925 checksumwarning("SMART Selective Self-Test Log Structure");
927 // swap endian order if needed
930 swap2((char *)&(data
->logversion
));
932 swap8((char *)&(data
->span
[i
].start
));
933 swap8((char *)&(data
->span
[i
].end
));
935 swap8((char *)&(data
->currentlba
));
936 swap2((char *)&(data
->currentspan
));
937 swap2((char *)&(data
->flags
));
938 swap2((char *)&(data
->pendingtime
));
941 if (data
->logversion
!= 1)
942 pout("SMART Selective Self-Test Log Data Structure Revision Number (%d) should be 1\n", data
->logversion
);
947 // Writes the selective self-test log (log #9)
948 int ataWriteSelectiveSelfTestLog(int device
, struct ata_smart_values
*sv
){
950 struct ata_selective_self_test_log sstlog
, *data
=&sstlog
;
951 unsigned char cksum
=0;
952 unsigned char *ptr
=(unsigned char *)data
;
955 if (ataReadSelectiveSelfTestLog(device
, data
)) {
956 pout("Since Read failed, will not attempt to WRITE Selective Self-test Log\n");
960 // Fix logversion if needed
961 if (data
->logversion
!=1) {
962 pout("Error SMART Selective Self-Test Log Data Structure Revision not recognized\n"
963 "Revision number should be 1 but is %d. To be safe, aborting WRITE LOG\n", data
->logversion
);
967 // Host is NOT allowed to write selective self-test log if a selective
968 // self-test is in progress.
969 if (0<data
->currentspan
&& data
->currentspan
<6 && ((sv
->self_test_exec_status
)>>4)==15) {
970 pout("Error SMART Selective or other Self-Test in progress.\n");
976 memset(data
->span
+i
, 0, sizeof(struct test_span
));
978 // Set spans for testing
979 for (i
=0; i
<con
->smartselectivenumspans
; i
++){
980 data
->span
[i
].start
= con
->smartselectivespan
[i
][0];
981 data
->span
[i
].end
= con
->smartselectivespan
[i
][1];
984 // host must initialize to zero before initiating selective self-test
988 // Perform off-line scan after selective test?
989 if (1 == con
->scanafterselect
)
991 data
->flags
&= ~SELECTIVE_FLAG_DOSCAN
;
992 else if (2 == con
->scanafterselect
)
994 data
->flags
|= SELECTIVE_FLAG_DOSCAN
;
996 // Must clear active and pending flags before writing
997 data
->flags
&= ~(SELECTIVE_FLAG_ACTIVE
);
998 data
->flags
&= ~(SELECTIVE_FLAG_PENDING
);
1000 // modify pending time?
1001 if (con
->pendingtime
)
1002 data
->pendingtime
=(unsigned short)(con
->pendingtime
-1);
1004 // Set checksum to zero, then compute checksum
1006 for (i
=0; i
<512; i
++)
1010 data
->checksum
=cksum
;
1012 // swap endian order if needed
1015 swap2((char *)&(data
->logversion
));
1017 swap8((char *)&(data
->span
[i
].start
));
1018 swap8((char *)&(data
->span
[i
].end
));
1020 swap8((char *)&(data
->currentlba
));
1021 swap2((char *)&(data
->currentspan
));
1022 swap2((char *)&(data
->flags
));
1023 swap2((char *)&(data
->pendingtime
));
1026 // write new selective self-test log
1027 if (smartcommandhandler(device
, WRITE_LOG
, 0x09, (char *)data
)){
1028 syserror("Error Write Selective Self-Test Log failed");
1035 // This corrects some quantities that are byte reversed in the SMART
1037 void fixsamsungerrorlog(struct ata_smart_errorlog
*data
){
1040 // FIXED IN SAMSUNG -25 FIRMWARE???
1041 // Device error count in bytes 452-3
1042 swap2((char *)&(data
->ata_error_count
));
1044 // FIXED IN SAMSUNG -22a FIRMWARE
1045 // step through 5 error log data structures
1046 for (i
=0; i
<5; i
++){
1047 // step through 5 command data structures
1049 // Command data structure 4-byte millisec timestamp. These are
1050 // bytes (N+8, N+9, N+10, N+11).
1051 swap4((char *)&(data
->errorlog_struct
[i
].commands
[j
].timestamp
));
1052 // Error data structure two-byte hour life timestamp. These are
1053 // bytes (N+28, N+29).
1054 swap2((char *)&(data
->errorlog_struct
[i
].error_struct
.timestamp
));
1059 // NEEDED ONLY FOR SAMSUNG -22 (some) -23 AND -24?? FIRMWARE
1060 void fixsamsungerrorlog2(struct ata_smart_errorlog
*data
){
1061 // Device error count in bytes 452-3
1062 swap2((char *)&(data
->ata_error_count
));
1066 // Reads the Summary SMART Error Log (log #1). The Comprehensive SMART
1067 // Error Log is #2, and the Extended Comprehensive SMART Error log is
1069 int ataReadErrorLog (int device
, struct ata_smart_errorlog
*data
){
1071 // get data from device
1072 if (smartcommandhandler(device
, READ_LOG
, 0x01, (char *)data
)){
1073 syserror("Error SMART Error Log Read failed");
1077 // compute its checksum, and issue a warning if needed
1078 if (checksum((unsigned char *)data
))
1079 checksumwarning("SMART ATA Error Log Structure");
1081 // Some disks have the byte order reversed in some SMART Summary
1082 // Error log entries
1083 if (con
->fixfirmwarebug
== FIX_SAMSUNG
)
1084 fixsamsungerrorlog(data
);
1085 else if (con
->fixfirmwarebug
== FIX_SAMSUNG2
)
1086 fixsamsungerrorlog2(data
);
1088 // Correct endian order if necessary
1092 // Device error count in bytes 452-3
1093 swap2((char *)&(data
->ata_error_count
));
1095 // step through 5 error log data structures
1096 for (i
=0; i
<5; i
++){
1097 // step through 5 command data structures
1099 // Command data structure 4-byte millisec timestamp
1100 swap4((char *)&(data
->errorlog_struct
[i
].commands
[j
].timestamp
));
1101 // Error data structure life timestamp
1102 swap2((char *)&(data
->errorlog_struct
[i
].error_struct
.timestamp
));
1109 int ataReadSmartThresholds (int device
, struct ata_smart_thresholds_pvt
*data
){
1111 // get data from device
1112 if (smartcommandhandler(device
, READ_THRESHOLDS
, 0, (char *)data
)){
1113 syserror("Error SMART Thresholds Read failed");
1117 // compute its checksum, and issue a warning if needed
1118 if (checksum((unsigned char *)data
))
1119 checksumwarning("SMART Attribute Thresholds Structure");
1121 // byte swap if needed
1123 swap2((char *)&(data
->revnumber
));
1128 int ataEnableSmart (int device
){
1129 if (smartcommandhandler(device
, ENABLE
, 0, NULL
)){
1130 syserror("Error SMART Enable failed");
1136 int ataDisableSmart (int device
){
1138 if (smartcommandhandler(device
, DISABLE
, 0, NULL
)){
1139 syserror("Error SMART Disable failed");
1145 int ataEnableAutoSave(int device
){
1146 if (smartcommandhandler(device
, AUTOSAVE
, 241, NULL
)){
1147 syserror("Error SMART Enable Auto-save failed");
1153 int ataDisableAutoSave(int device
){
1155 if (smartcommandhandler(device
, AUTOSAVE
, 0, NULL
)){
1156 syserror("Error SMART Disable Auto-save failed");
1162 // In *ALL* ATA standards the Enable/Disable AutoOffline command is
1163 // marked "OBSOLETE". It is defined in SFF-8035i Revision 2, and most
1164 // vendors still support it for backwards compatibility. IBM documents
1165 // it for some drives.
1166 int ataEnableAutoOffline (int device
){
1168 /* timer hard coded to 4 hours */
1169 if (smartcommandhandler(device
, AUTO_OFFLINE
, 248, NULL
)){
1170 syserror("Error SMART Enable Automatic Offline failed");
1176 // Another Obsolete Command. See comments directly above, associated
1177 // with the corresponding Enable command.
1178 int ataDisableAutoOffline (int device
){
1180 if (smartcommandhandler(device
, AUTO_OFFLINE
, 0, NULL
)){
1181 syserror("Error SMART Disable Automatic Offline failed");
1187 // If SMART is enabled, supported, and working, then this call is
1188 // guaranteed to return 1, else zero. Note that it should return 1
1189 // regardless of whether the disk's SMART status is 'healthy' or
1191 int ataDoesSmartWork(int device
){
1192 int retval
=smartcommandhandler(device
, STATUS
, 0, NULL
);
1200 // This function uses a different interface (DRIVE_TASK) than the
1201 // other commands in this file.
1202 int ataSmartStatus2(int device
){
1203 return smartcommandhandler(device
, STATUS_CHECK
, 0, NULL
);
1206 // This is the way to execute ALL tests: offline, short self-test,
1207 // extended self test, with and without captive mode, etc.
1208 int ataSmartTest(int device
, int testtype
, struct ata_smart_values
*sv
) {
1209 char cmdmsg
[128],*type
,*captive
;
1210 int errornum
, cap
, retval
, select
=0;
1212 // Boolean, if set, says test is captive
1213 cap
=testtype
& CAPTIVE_MASK
;
1215 // Set up strings that describe the type of test
1221 if (testtype
==OFFLINE_FULL_SCAN
)
1223 else if (testtype
==SHORT_SELF_TEST
|| testtype
==SHORT_CAPTIVE_SELF_TEST
)
1224 type
="Short self-test";
1225 else if (testtype
==EXTEND_SELF_TEST
|| testtype
==EXTEND_CAPTIVE_SELF_TEST
)
1226 type
="Extended self-test";
1227 else if (testtype
==CONVEYANCE_SELF_TEST
|| testtype
==CONVEYANCE_CAPTIVE_SELF_TEST
)
1228 type
="Conveyance self-test";
1229 else if ((select
=(testtype
==SELECTIVE_SELF_TEST
|| testtype
==SELECTIVE_CAPTIVE_SELF_TEST
)))
1230 type
="Selective self-test";
1232 type
="[Unrecognized] self-test";
1234 // If doing a selective self-test, first use WRITE_LOG to write the
1235 // selective self-test log.
1236 if (select
&& (retval
=ataWriteSelectiveSelfTestLog(device
, sv
))) {
1238 pout("Can't start selective self-test without aborting current test: use '-X' option to smartctl.\n");
1242 // Print ouf message that we are sending the command to test
1243 if (testtype
==ABORT_SELF_TEST
)
1244 sprintf(cmdmsg
,"Abort SMART off-line mode self-test routine");
1246 sprintf(cmdmsg
,"Execute SMART %s routine immediately in %s mode",type
,captive
);
1247 pout("Sending command: \"%s\".\n",cmdmsg
);
1251 pout("SPAN STARTING_LBA ENDING_LBA\n");
1252 for (i
= 0; i
< con
->smartselectivenumspans
; i
++)
1253 pout(" %d %20"PRId64
" %20"PRId64
"\n", i
,
1254 con
->smartselectivespan
[i
][0],
1255 con
->smartselectivespan
[i
][1]);
1258 // Now send the command to test
1259 errornum
=smartcommandhandler(device
, IMMEDIATE_OFFLINE
, testtype
, NULL
);
1261 if (errornum
&& !(cap
&& errno
==EIO
)){
1263 sprintf(errormsg
,"Command \"%s\" failed",cmdmsg
);
1269 // Since the command succeeded, tell user
1270 if (testtype
==ABORT_SELF_TEST
)
1271 pout("Self-testing aborted!\n");
1273 pout("Drive command \"%s\" successful.\nTesting has begun.\n",cmdmsg
);
1277 /* Test Time Functions */
1278 int TestTime(struct ata_smart_values
*data
,int testtype
){
1280 case OFFLINE_FULL_SCAN
:
1281 return (int) data
->total_time_to_complete_off_line
;
1282 case SHORT_SELF_TEST
:
1283 case SHORT_CAPTIVE_SELF_TEST
:
1284 return (int) data
->short_test_completion_time
;
1285 case EXTEND_SELF_TEST
:
1286 case EXTEND_CAPTIVE_SELF_TEST
:
1287 return (int) data
->extend_test_completion_time
;
1288 case CONVEYANCE_SELF_TEST
:
1289 case CONVEYANCE_CAPTIVE_SELF_TEST
:
1290 return (int) data
->conveyance_test_completion_time
;
1296 // This function tells you both about the ATA error log and the
1297 // self-test error log capability (introduced in ATA-5). The bit is
1298 // poorly documented in the ATA/ATAPI standard. Starting with ATA-6,
1299 // SMART error logging is also indicated in bit 0 of DEVICE IDENTIFY
1300 // word 84 and 87. Top two bits must match the pattern 01. BEFORE
1301 // ATA-6 these top two bits still had to match the pattern 01, but the
1302 // remaining bits were reserved (==0).
1303 int isSmartErrorLogCapable (struct ata_smart_values
*data
, struct ata_identify_device
*identity
){
1305 unsigned short word84
=identity
->command_set_extension
;
1306 unsigned short word87
=identity
->csf_default
;
1307 int isata6
=identity
->major_rev_num
& (0x01<<6);
1308 int isata7
=identity
->major_rev_num
& (0x01<<7);
1310 if ((isata6
|| isata7
) && (word84
>>14) == 0x01 && (word84
& 0x01))
1313 if ((isata6
|| isata7
) && (word87
>>14) == 0x01 && (word87
& 0x01))
1316 // otherwise we'll use the poorly documented capability bit
1317 return data
->errorlog_capability
& 0x01;
1320 // See previous function. If the error log exists then the self-test
1321 // log should (must?) also exist.
1322 int isSmartTestLogCapable (struct ata_smart_values
*data
, struct ata_identify_device
*identity
){
1324 unsigned short word84
=identity
->command_set_extension
;
1325 unsigned short word87
=identity
->csf_default
;
1326 int isata6
=identity
->major_rev_num
& (0x01<<6);
1327 int isata7
=identity
->major_rev_num
& (0x01<<7);
1329 if ((isata6
|| isata7
) && (word84
>>14) == 0x01 && (word84
& 0x02))
1332 if ((isata6
|| isata7
) && (word87
>>14) == 0x01 && (word87
& 0x02))
1336 // otherwise we'll use the poorly documented capability bit
1337 return data
->errorlog_capability
& 0x01;
1341 int isGeneralPurposeLoggingCapable(struct ata_identify_device
*identity
){
1342 unsigned short word84
=identity
->command_set_extension
;
1343 unsigned short word87
=identity
->csf_default
;
1345 // If bit 14 of word 84 is set to one and bit 15 of word 84 is
1346 // cleared to zero, the contents of word 84 contains valid support
1347 // information. If not, support information is not valid in this
1349 if ((word84
>>14) == 0x01)
1350 // If bit 5 of word 84 is set to one, the device supports the
1351 // General Purpose Logging feature set.
1352 return (word84
& (0x01 << 5));
1354 // If bit 14 of word 87 is set to one and bit 15 of word 87 is
1355 // cleared to zero, the contents of words (87:85) contain valid
1356 // information. If not, information is not valid in these words.
1357 if ((word87
>>14) == 0x01)
1358 // If bit 5 of word 87 is set to one, the device supports
1359 // the General Purpose Logging feature set.
1360 return (word87
& (0x01 << 5));
1367 // SMART self-test capability is also indicated in bit 1 of DEVICE
1368 // IDENTIFY word 87 (if top two bits of word 87 match pattern 01).
1369 // However this was only introduced in ATA-6 (but self-test log was in
1371 int isSupportExecuteOfflineImmediate(struct ata_smart_values
*data
){
1372 return data
->offline_data_collection_capability
& 0x01;
1374 // Note in the ATA-5 standard, the following bit is listed as "Vendor
1375 // Specific". So it may not be reliable. The only use of this that I
1376 // have found is in IBM drives, where it is well-documented. See for
1377 // example page 170, section 13.32.1.18 of the IBM Travelstar 40GNX
1378 // hard disk drive specifications page 164 Revision 1.1 22 Apr 2002.
1379 int isSupportAutomaticTimer(struct ata_smart_values
*data
){
1380 return data
->offline_data_collection_capability
& 0x02;
1382 int isSupportOfflineAbort(struct ata_smart_values
*data
){
1383 return data
->offline_data_collection_capability
& 0x04;
1385 int isSupportOfflineSurfaceScan(struct ata_smart_values
*data
){
1386 return data
->offline_data_collection_capability
& 0x08;
1388 int isSupportSelfTest (struct ata_smart_values
*data
){
1389 return data
->offline_data_collection_capability
& 0x10;
1391 int isSupportConveyanceSelfTest(struct ata_smart_values
*data
){
1392 return data
->offline_data_collection_capability
& 0x20;
1394 int isSupportSelectiveSelfTest(struct ata_smart_values
*data
){
1395 return data
->offline_data_collection_capability
& 0x40;
1400 // Loop over all valid attributes. If they are prefailure attributes
1401 // and are at or below the threshold value, then return the ID of the
1402 // first failing attribute found. Return 0 if all prefailure
1403 // attributes are in bounds. The spec says "Bit 0
1404 // -Pre-failure/advisory - If the value of this bit equals zero, an
1405 // attribute value less than or equal to its corresponding attribute
1406 // threshold indicates an advisory condition where the usage or age of
1407 // the device has exceeded its intended design life period. If the
1408 // value of this bit equals one, an atribute value less than or equal
1409 // to its corresponding attribute threshold indicates a pre-failure
1410 // condition where imminent loss of data is being predicted."
1413 // onlyfailed=0 : are or were any age or prefailure attributes <= threshold
1414 // onlyfailed=1: are any prefailure attributes <= threshold now
1415 int ataCheckSmart(struct ata_smart_values
*data
,
1416 struct ata_smart_thresholds_pvt
*thresholds
,
1420 // loop over all attributes
1421 for (i
=0; i
<NUMBER_ATA_SMART_ATTRIBUTES
; i
++){
1423 // pointers to disk's values and vendor's thresholds
1424 struct ata_smart_attribute
*disk
=data
->vendor_attributes
+i
;
1425 struct ata_smart_threshold_entry
*thre
=thresholds
->thres_entries
+i
;
1427 // consider only valid attributes
1428 if (disk
->id
&& thre
->id
){
1429 int failednow
,failedever
;
1431 failednow
=disk
->current
<= thre
->threshold
;
1432 failedever
=disk
->worst
<= thre
->threshold
;
1434 if (!onlyfailed
&& failedever
)
1437 if (onlyfailed
&& failednow
&& ATTRIBUTE_FLAGS_PREFAILURE(disk
->flags
))
1446 // This checks the n'th attribute in the attribute list, NOT the
1447 // attribute with id==n. If the attribute does not exist, or the
1448 // attribute is > threshold, then returns zero. If the attribute is
1449 // <= threshold (failing) then we the attribute number if it is a
1450 // prefail attribute. Else we return minus the attribute number if it
1451 // is a usage attribute.
1452 int ataCheckAttribute(struct ata_smart_values
*data
,
1453 struct ata_smart_thresholds_pvt
*thresholds
,
1455 struct ata_smart_attribute
*disk
;
1456 struct ata_smart_threshold_entry
*thre
;
1458 if (n
<0 || n
>=NUMBER_ATA_SMART_ATTRIBUTES
|| !data
|| !thresholds
)
1461 // pointers to disk's values and vendor's thresholds
1462 disk
=data
->vendor_attributes
+n
;
1463 thre
=thresholds
->thres_entries
+n
;
1468 // consider only valid attributes, check for failure
1469 if (!disk
->id
|| !thre
->id
|| (disk
->id
!= thre
->id
) || disk
->current
> thre
->threshold
)
1472 // We have found a failed attribute. Return positive or negative?
1473 if (ATTRIBUTE_FLAGS_PREFAILURE(disk
->flags
))
1476 return -1*(disk
->id
);
1480 // This routine prints the raw value of an attribute as a text string
1481 // into out. It also returns this 48-bit number as a long long. The
1482 // array defs[] contains non-zero values if particular attributes have
1483 // non-default interpretations.
1485 int64_t ataPrintSmartAttribRawValue(char *out
,
1486 struct ata_smart_attribute
*attribute
,
1487 unsigned char *defs
){
1491 unsigned char select
;
1493 // convert the six individual bytes to a long long (8 byte) integer.
1494 // This is the value that we'll eventually return.
1496 for (j
=0; j
<6; j
++) {
1497 // This looks a bit roundabout, but is necessary. Don't
1498 // succumb to the temptation to use raw[j]<<(8*j) since under
1499 // the normal rules this will be promoted to the native type.
1500 // On a 32 bit machine this might then overflow.
1502 temp
= attribute
->raw
[j
];
1507 // convert quantities to three two-byte words
1508 for (j
=0; j
<3; j
++){
1509 word
[j
] = attribute
->raw
[2*j
+1];
1511 word
[j
] |= attribute
->raw
[2*j
];
1514 // if no data array, Attributes have default interpretations
1516 select
=defs
[attribute
->id
];
1520 // Print six one-byte quantities.
1523 out
+=sprintf(out
, "%d ", attribute
->raw
[5-j
]);
1524 out
+=sprintf(out
, "%d ", attribute
->raw
[0]);
1528 // Print three two-byte quantities
1530 out
+=sprintf(out
, "%d %d %d", word
[2], word
[1], word
[0]);
1534 // Print one six-byte quantity
1536 out
+=sprintf(out
, "%"PRIu64
, rawvalue
);
1540 // This switch statement is where we handle Raw attributes
1541 // that are stored in an unusual vendor-specific format,
1542 switch (attribute
->id
){
1545 out
+=sprintf(out
, "%d", word
[0]);
1546 // if second nonzero then it stores the average spin-up time
1548 out
+=sprintf(out
, " (Average %d)", word
[1]);
1554 int64_t tmp1
=rawvalue
/60;
1555 int64_t tmp2
=rawvalue
%60;
1556 out
+=sprintf(out
, "%"PRIu64
"h+%02"PRIu64
"m", tmp1
, tmp2
);
1558 else if (select
==3){
1560 int64_t hours
=rawvalue
/3600;
1561 int64_t minutes
=(rawvalue
-3600*hours
)/60;
1562 int64_t seconds
=rawvalue
%60;
1563 out
+=sprintf(out
, "%"PRIu64
"h+%02"PRIu64
"m+%02"PRIu64
"s", hours
, minutes
, seconds
);
1565 else if (select
==4){
1566 // 30-second counter
1567 int64_t tmp1
=rawvalue
/120;
1568 int64_t tmp2
=(rawvalue
-120*tmp1
)/2;
1569 out
+=sprintf(out
, "%"PRIu64
"h+%02"PRIu64
"m", tmp1
, tmp2
);
1573 out
+=sprintf(out
, "%"PRIu64
, rawvalue
); //stored in hours
1575 // Load unload cycles
1579 long load
=attribute
->raw
[0] + (attribute
->raw
[1]<<8) + (attribute
->raw
[2]<<16);
1580 long unload
=attribute
->raw
[3] + (attribute
->raw
[4]<<8) + (attribute
->raw
[5]<<16);
1581 out
+=sprintf(out
, "%lu/%lu", load
, unload
);
1585 out
+=sprintf(out
, "%"PRIu64
, rawvalue
);
1590 // ten times temperature in Celsius
1592 int tenths
=word
[0]%10;
1593 out
+=sprintf(out
, "%d.%d", deg
, tenths
);
1596 // unknown attribute
1597 out
+=sprintf(out
, "%"PRIu64
, rawvalue
);
1599 out
+=sprintf(out
, "%d", word
[0]);
1600 if (!(rawvalue
==word
[0])) {
1601 int min
=word
[1]<word
[2]?word
[1]:word
[2];
1602 int max
=word
[1]>word
[2]?word
[1]:word
[2];
1603 // The other bytes are in use. Try IBM's model
1604 out
+=sprintf(out
, " (Lifetime Min/Max %d/%d)", min
, max
);
1609 out
+=sprintf(out
, "%"PRIu64
, rawvalue
);
1612 // Return the full value
1617 // Note some attribute names appear redundant because different
1618 // manufacturers use different attribute IDs for an attribute with the
1619 // same name. The variable val should contain a non-zero value if a particular
1620 // attributes has a non-default interpretation.
1621 void ataPrintSmartAttribName(char *out
, unsigned char id
, unsigned char *definitions
){
1625 // If no data array, use default interpretations
1627 val
=definitions
[id
];
1634 name
="Raw_Read_Error_Rate";
1637 name
="Throughput_Performance";
1640 name
="Spin_Up_Time";
1643 name
="Start_Stop_Count";
1646 name
="Reallocated_Sector_Ct";
1649 name
="Read_Channel_Margin";
1652 name
="Seek_Error_Rate";
1655 name
="Seek_Time_Performance";
1660 name
="Power_On_Minutes";
1663 name
="Temperature_Celsius";
1666 name
="Power_On_Seconds";
1669 name
="Power_On_Half_Minutes";
1672 name
="Power_On_Hours";
1677 name
="Spin_Retry_Count";
1680 name
="Calibration_Retry_Count";
1683 name
="Power_Cycle_Count";
1686 name
="Read_Soft_Error_Rate";
1689 // Western Digital uses this for temperature.
1690 // It's identical to Attribute 194 except that it
1691 // has a failure threshold set to correspond to the
1692 // max allowed operating temperature of the drive, which
1693 // is typically 55C. So if this attribute has failed
1694 // in the past, it indicates that the drive temp exceeded
1695 // 55C sometime in the past.
1696 name
="Temperature_Celsius";
1699 name
="G-Sense_Error_Rate";
1705 name
="Emergency_Retract_Cycle_Ct";
1708 name
="Power-Off_Retract_Count";
1713 name
="Load_Cycle_Count";
1718 // Samsung SV1204H with RK100-13 firmware
1719 name
="Temperature_Celsius_x10";
1722 // for disks with no temperature Attribute
1723 name
="Unknown_Attribute";
1726 name
="Temperature_Celsius";
1731 // Fujitsu name="ECC_On_The_Fly_Count";
1732 name
="Hardware_ECC_Recovered";
1735 name
="Reallocated_Event_Count";
1738 name
="Current_Pending_Sector";
1744 name
="Off-line_Scan_UNC_Sector_Ct";
1747 name
="Offline_Uncorrectable";
1752 name
="UDMA_CRC_Error_Count";
1757 // Fujitsu MHS2020AT
1758 name
="Write_Error_Count";
1762 name
="Multi_Zone_Error_Rate";
1770 name
="Detected_TA_Count";
1773 name
="Soft_Read_Error_Rate";
1779 name
="TA_Increase_Count";
1780 // Maxtor: Data Address Mark Errors
1784 name
="Run_Out_Cancel";
1785 // Maxtor: ECC Errors
1789 name
="Shock_Count_Write_Opern";
1790 // Maxtor: Soft ECC Correction
1794 name
="Shock_Rate_Write_Opern";
1795 // Maxtor: Thermal Aspirates
1799 name
="Flying_Height";
1803 name
="Spin_High_Current";
1811 name
="Offline_Seek_Performnce";
1816 name
="Temperature_Celsius";
1824 name
="G-Sense_Error_Rate";
1827 name
="Loaded_Hours";
1830 name
="Load_Retry_Count";
1833 name
="Load_Friction";
1836 name
="Load_Cycle_Count";
1839 name
="Load-in_Time";
1842 name
="Torq-amp_Count";
1845 name
="Power-off_Retract_Count";
1848 // seen in IBM DTPA-353750
1849 name
="Head_Amplitude";
1852 name
="Temperature_Celsius";
1855 name
="Head_Flying_Hours";
1858 name
="Read_Error_Retry_Rate";
1861 name
="Unknown_Attribute";
1864 sprintf(out
,"%3hu %s",(short int)id
,name
);
1868 // Returns raw value of Attribute with ID==id. This will be in the
1869 // range 0 to 2^48-1 inclusive. If the Attribute does not exist,
1871 int64_t ATAReturnAttributeRawValue(unsigned char id
, struct ata_smart_values
*data
) {
1874 // valid Attribute IDs are in the range 1 to 255 inclusive.
1878 // loop over Attributes to see if there is one with the desired ID
1879 for (i
=0; i
<NUMBER_ATA_SMART_ATTRIBUTES
; i
++) {
1880 struct ata_smart_attribute
*ap
= data
->vendor_attributes
+ i
;
1882 // we've found the desired Attribute. Return its value
1886 for (j
=0; j
<6; j
++) {
1887 // This looks a bit roundabout, but is necessary. Don't
1888 // succumb to the temptation to use raw[j]<<(8*j) since under
1889 // the normal rules this will be promoted to the native type.
1890 // On a 32 bit machine this might then overflow.
1897 } // found desired Attribute
1898 } // loop over Attributes
1900 // fall-through: no such Attribute found
1904 // Return Temperature Attribute raw value selected according to possible
1905 // non-default interpretations. If the Attribute does not exist, return 0
1906 unsigned char ATAReturnTemperatureValue(/*const*/ struct ata_smart_values
*data
, const unsigned char *defs
){
1908 for (i
= 0; i
< 3; i
++) {
1909 static const unsigned char ids
[3] = {194, 9, 220};
1910 unsigned char id
= ids
[i
];
1911 unsigned char select
= (defs
? defs
[id
] : 0);
1912 int64_t raw
; unsigned temp
;
1913 if (!( (id
== 194 && select
<= 1) // ! -v 194,unknown
1914 || (id
== 9 && select
== 2) // -v 9,temp
1915 || (id
== 220 && select
== 1))) // -v 220,temp
1917 raw
= ATAReturnAttributeRawValue(id
, data
);
1920 temp
= (unsigned short)raw
; // ignore possible min/max values in high words
1921 if (id
== 194 && select
== 1) // -v 194,10xCelsius
1922 temp
= (temp
+5) / 10;
1923 if (!(0 < temp
&& temp
<= 255))
1927 // No valid attribute found