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.177 2006/10/27 21:30:02 chrfranke 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 if (!con
->permissive
) {
963 pout("Error SMART Selective Self-Test Log Data Structure Revision not recognized\n"
964 "Revision number should be 1 but is %d. To be safe, aborting WRITE LOG.\n"
965 "To fix revision number, add one '-T permissive' option.\n", data
->logversion
);
969 pout("SMART Selective Self-Test Log Data Structure Revision should be 1 but is %d\n"
970 "'-T permissive' specified, now trying to fix it by WRITE LOG.\n", data
->logversion
);
971 data
->logversion
= 1;
974 // Host is NOT allowed to write selective self-test log if a selective
975 // self-test is in progress.
976 if (0<data
->currentspan
&& data
->currentspan
<6 && ((sv
->self_test_exec_status
)>>4)==15) {
977 pout("Error SMART Selective or other Self-Test in progress.\n");
983 memset(data
->span
+i
, 0, sizeof(struct test_span
));
985 // Set spans for testing
986 for (i
=0; i
<con
->smartselectivenumspans
; i
++){
987 data
->span
[i
].start
= con
->smartselectivespan
[i
][0];
988 data
->span
[i
].end
= con
->smartselectivespan
[i
][1];
991 // host must initialize to zero before initiating selective self-test
995 // Perform off-line scan after selective test?
996 if (1 == con
->scanafterselect
)
998 data
->flags
&= ~SELECTIVE_FLAG_DOSCAN
;
999 else if (2 == con
->scanafterselect
)
1001 data
->flags
|= SELECTIVE_FLAG_DOSCAN
;
1003 // Must clear active and pending flags before writing
1004 data
->flags
&= ~(SELECTIVE_FLAG_ACTIVE
);
1005 data
->flags
&= ~(SELECTIVE_FLAG_PENDING
);
1007 // modify pending time?
1008 if (con
->pendingtime
)
1009 data
->pendingtime
=(unsigned short)(con
->pendingtime
-1);
1011 // Set checksum to zero, then compute checksum
1013 for (i
=0; i
<512; i
++)
1017 data
->checksum
=cksum
;
1019 // swap endian order if needed
1022 swap2((char *)&(data
->logversion
));
1024 swap8((char *)&(data
->span
[i
].start
));
1025 swap8((char *)&(data
->span
[i
].end
));
1027 swap8((char *)&(data
->currentlba
));
1028 swap2((char *)&(data
->currentspan
));
1029 swap2((char *)&(data
->flags
));
1030 swap2((char *)&(data
->pendingtime
));
1033 // write new selective self-test log
1034 if (smartcommandhandler(device
, WRITE_LOG
, 0x09, (char *)data
)){
1035 syserror("Error Write Selective Self-Test Log failed");
1042 // This corrects some quantities that are byte reversed in the SMART
1044 void fixsamsungerrorlog(struct ata_smart_errorlog
*data
){
1047 // FIXED IN SAMSUNG -25 FIRMWARE???
1048 // Device error count in bytes 452-3
1049 swap2((char *)&(data
->ata_error_count
));
1051 // FIXED IN SAMSUNG -22a FIRMWARE
1052 // step through 5 error log data structures
1053 for (i
=0; i
<5; i
++){
1054 // step through 5 command data structures
1056 // Command data structure 4-byte millisec timestamp. These are
1057 // bytes (N+8, N+9, N+10, N+11).
1058 swap4((char *)&(data
->errorlog_struct
[i
].commands
[j
].timestamp
));
1059 // Error data structure two-byte hour life timestamp. These are
1060 // bytes (N+28, N+29).
1061 swap2((char *)&(data
->errorlog_struct
[i
].error_struct
.timestamp
));
1066 // NEEDED ONLY FOR SAMSUNG -22 (some) -23 AND -24?? FIRMWARE
1067 void fixsamsungerrorlog2(struct ata_smart_errorlog
*data
){
1068 // Device error count in bytes 452-3
1069 swap2((char *)&(data
->ata_error_count
));
1073 // Reads the Summary SMART Error Log (log #1). The Comprehensive SMART
1074 // Error Log is #2, and the Extended Comprehensive SMART Error log is
1076 int ataReadErrorLog (int device
, struct ata_smart_errorlog
*data
){
1078 // get data from device
1079 if (smartcommandhandler(device
, READ_LOG
, 0x01, (char *)data
)){
1080 syserror("Error SMART Error Log Read failed");
1084 // compute its checksum, and issue a warning if needed
1085 if (checksum((unsigned char *)data
))
1086 checksumwarning("SMART ATA Error Log Structure");
1088 // Some disks have the byte order reversed in some SMART Summary
1089 // Error log entries
1090 if (con
->fixfirmwarebug
== FIX_SAMSUNG
)
1091 fixsamsungerrorlog(data
);
1092 else if (con
->fixfirmwarebug
== FIX_SAMSUNG2
)
1093 fixsamsungerrorlog2(data
);
1095 // Correct endian order if necessary
1099 // Device error count in bytes 452-3
1100 swap2((char *)&(data
->ata_error_count
));
1102 // step through 5 error log data structures
1103 for (i
=0; i
<5; i
++){
1104 // step through 5 command data structures
1106 // Command data structure 4-byte millisec timestamp
1107 swap4((char *)&(data
->errorlog_struct
[i
].commands
[j
].timestamp
));
1108 // Error data structure life timestamp
1109 swap2((char *)&(data
->errorlog_struct
[i
].error_struct
.timestamp
));
1116 int ataReadSmartThresholds (int device
, struct ata_smart_thresholds_pvt
*data
){
1118 // get data from device
1119 if (smartcommandhandler(device
, READ_THRESHOLDS
, 0, (char *)data
)){
1120 syserror("Error SMART Thresholds Read failed");
1124 // compute its checksum, and issue a warning if needed
1125 if (checksum((unsigned char *)data
))
1126 checksumwarning("SMART Attribute Thresholds Structure");
1128 // byte swap if needed
1130 swap2((char *)&(data
->revnumber
));
1135 int ataEnableSmart (int device
){
1136 if (smartcommandhandler(device
, ENABLE
, 0, NULL
)){
1137 syserror("Error SMART Enable failed");
1143 int ataDisableSmart (int device
){
1145 if (smartcommandhandler(device
, DISABLE
, 0, NULL
)){
1146 syserror("Error SMART Disable failed");
1152 int ataEnableAutoSave(int device
){
1153 if (smartcommandhandler(device
, AUTOSAVE
, 241, NULL
)){
1154 syserror("Error SMART Enable Auto-save failed");
1160 int ataDisableAutoSave(int device
){
1162 if (smartcommandhandler(device
, AUTOSAVE
, 0, NULL
)){
1163 syserror("Error SMART Disable Auto-save failed");
1169 // In *ALL* ATA standards the Enable/Disable AutoOffline command is
1170 // marked "OBSOLETE". It is defined in SFF-8035i Revision 2, and most
1171 // vendors still support it for backwards compatibility. IBM documents
1172 // it for some drives.
1173 int ataEnableAutoOffline (int device
){
1175 /* timer hard coded to 4 hours */
1176 if (smartcommandhandler(device
, AUTO_OFFLINE
, 248, NULL
)){
1177 syserror("Error SMART Enable Automatic Offline failed");
1183 // Another Obsolete Command. See comments directly above, associated
1184 // with the corresponding Enable command.
1185 int ataDisableAutoOffline (int device
){
1187 if (smartcommandhandler(device
, AUTO_OFFLINE
, 0, NULL
)){
1188 syserror("Error SMART Disable Automatic Offline failed");
1194 // If SMART is enabled, supported, and working, then this call is
1195 // guaranteed to return 1, else zero. Note that it should return 1
1196 // regardless of whether the disk's SMART status is 'healthy' or
1198 int ataDoesSmartWork(int device
){
1199 int retval
=smartcommandhandler(device
, STATUS
, 0, NULL
);
1207 // This function uses a different interface (DRIVE_TASK) than the
1208 // other commands in this file.
1209 int ataSmartStatus2(int device
){
1210 return smartcommandhandler(device
, STATUS_CHECK
, 0, NULL
);
1213 // This is the way to execute ALL tests: offline, short self-test,
1214 // extended self test, with and without captive mode, etc.
1215 int ataSmartTest(int device
, int testtype
, struct ata_smart_values
*sv
) {
1216 char cmdmsg
[128],*type
,*captive
;
1217 int errornum
, cap
, retval
, select
=0;
1219 // Boolean, if set, says test is captive
1220 cap
=testtype
& CAPTIVE_MASK
;
1222 // Set up strings that describe the type of test
1228 if (testtype
==OFFLINE_FULL_SCAN
)
1230 else if (testtype
==SHORT_SELF_TEST
|| testtype
==SHORT_CAPTIVE_SELF_TEST
)
1231 type
="Short self-test";
1232 else if (testtype
==EXTEND_SELF_TEST
|| testtype
==EXTEND_CAPTIVE_SELF_TEST
)
1233 type
="Extended self-test";
1234 else if (testtype
==CONVEYANCE_SELF_TEST
|| testtype
==CONVEYANCE_CAPTIVE_SELF_TEST
)
1235 type
="Conveyance self-test";
1236 else if ((select
=(testtype
==SELECTIVE_SELF_TEST
|| testtype
==SELECTIVE_CAPTIVE_SELF_TEST
)))
1237 type
="Selective self-test";
1239 type
="[Unrecognized] self-test";
1241 // If doing a selective self-test, first use WRITE_LOG to write the
1242 // selective self-test log.
1243 if (select
&& (retval
=ataWriteSelectiveSelfTestLog(device
, sv
))) {
1245 pout("Can't start selective self-test without aborting current test: use '-X' option to smartctl.\n");
1249 // Print ouf message that we are sending the command to test
1250 if (testtype
==ABORT_SELF_TEST
)
1251 sprintf(cmdmsg
,"Abort SMART off-line mode self-test routine");
1253 sprintf(cmdmsg
,"Execute SMART %s routine immediately in %s mode",type
,captive
);
1254 pout("Sending command: \"%s\".\n",cmdmsg
);
1258 pout("SPAN STARTING_LBA ENDING_LBA\n");
1259 for (i
= 0; i
< con
->smartselectivenumspans
; i
++)
1260 pout(" %d %20"PRId64
" %20"PRId64
"\n", i
,
1261 con
->smartselectivespan
[i
][0],
1262 con
->smartselectivespan
[i
][1]);
1265 // Now send the command to test
1266 errornum
=smartcommandhandler(device
, IMMEDIATE_OFFLINE
, testtype
, NULL
);
1268 if (errornum
&& !(cap
&& errno
==EIO
)){
1270 sprintf(errormsg
,"Command \"%s\" failed",cmdmsg
);
1276 // Since the command succeeded, tell user
1277 if (testtype
==ABORT_SELF_TEST
)
1278 pout("Self-testing aborted!\n");
1280 pout("Drive command \"%s\" successful.\nTesting has begun.\n",cmdmsg
);
1284 /* Test Time Functions */
1285 int TestTime(struct ata_smart_values
*data
,int testtype
){
1287 case OFFLINE_FULL_SCAN
:
1288 return (int) data
->total_time_to_complete_off_line
;
1289 case SHORT_SELF_TEST
:
1290 case SHORT_CAPTIVE_SELF_TEST
:
1291 return (int) data
->short_test_completion_time
;
1292 case EXTEND_SELF_TEST
:
1293 case EXTEND_CAPTIVE_SELF_TEST
:
1294 return (int) data
->extend_test_completion_time
;
1295 case CONVEYANCE_SELF_TEST
:
1296 case CONVEYANCE_CAPTIVE_SELF_TEST
:
1297 return (int) data
->conveyance_test_completion_time
;
1303 // This function tells you both about the ATA error log and the
1304 // self-test error log capability (introduced in ATA-5). The bit is
1305 // poorly documented in the ATA/ATAPI standard. Starting with ATA-6,
1306 // SMART error logging is also indicated in bit 0 of DEVICE IDENTIFY
1307 // word 84 and 87. Top two bits must match the pattern 01. BEFORE
1308 // ATA-6 these top two bits still had to match the pattern 01, but the
1309 // remaining bits were reserved (==0).
1310 int isSmartErrorLogCapable (struct ata_smart_values
*data
, struct ata_identify_device
*identity
){
1312 unsigned short word84
=identity
->command_set_extension
;
1313 unsigned short word87
=identity
->csf_default
;
1314 int isata6
=identity
->major_rev_num
& (0x01<<6);
1315 int isata7
=identity
->major_rev_num
& (0x01<<7);
1317 if ((isata6
|| isata7
) && (word84
>>14) == 0x01 && (word84
& 0x01))
1320 if ((isata6
|| isata7
) && (word87
>>14) == 0x01 && (word87
& 0x01))
1323 // otherwise we'll use the poorly documented capability bit
1324 return data
->errorlog_capability
& 0x01;
1327 // See previous function. If the error log exists then the self-test
1328 // log should (must?) also exist.
1329 int isSmartTestLogCapable (struct ata_smart_values
*data
, struct ata_identify_device
*identity
){
1331 unsigned short word84
=identity
->command_set_extension
;
1332 unsigned short word87
=identity
->csf_default
;
1333 int isata6
=identity
->major_rev_num
& (0x01<<6);
1334 int isata7
=identity
->major_rev_num
& (0x01<<7);
1336 if ((isata6
|| isata7
) && (word84
>>14) == 0x01 && (word84
& 0x02))
1339 if ((isata6
|| isata7
) && (word87
>>14) == 0x01 && (word87
& 0x02))
1343 // otherwise we'll use the poorly documented capability bit
1344 return data
->errorlog_capability
& 0x01;
1348 int isGeneralPurposeLoggingCapable(struct ata_identify_device
*identity
){
1349 unsigned short word84
=identity
->command_set_extension
;
1350 unsigned short word87
=identity
->csf_default
;
1352 // If bit 14 of word 84 is set to one and bit 15 of word 84 is
1353 // cleared to zero, the contents of word 84 contains valid support
1354 // information. If not, support information is not valid in this
1356 if ((word84
>>14) == 0x01)
1357 // If bit 5 of word 84 is set to one, the device supports the
1358 // General Purpose Logging feature set.
1359 return (word84
& (0x01 << 5));
1361 // If bit 14 of word 87 is set to one and bit 15 of word 87 is
1362 // cleared to zero, the contents of words (87:85) contain valid
1363 // information. If not, information is not valid in these words.
1364 if ((word87
>>14) == 0x01)
1365 // If bit 5 of word 87 is set to one, the device supports
1366 // the General Purpose Logging feature set.
1367 return (word87
& (0x01 << 5));
1374 // SMART self-test capability is also indicated in bit 1 of DEVICE
1375 // IDENTIFY word 87 (if top two bits of word 87 match pattern 01).
1376 // However this was only introduced in ATA-6 (but self-test log was in
1378 int isSupportExecuteOfflineImmediate(struct ata_smart_values
*data
){
1379 return data
->offline_data_collection_capability
& 0x01;
1381 // Note in the ATA-5 standard, the following bit is listed as "Vendor
1382 // Specific". So it may not be reliable. The only use of this that I
1383 // have found is in IBM drives, where it is well-documented. See for
1384 // example page 170, section 13.32.1.18 of the IBM Travelstar 40GNX
1385 // hard disk drive specifications page 164 Revision 1.1 22 Apr 2002.
1386 int isSupportAutomaticTimer(struct ata_smart_values
*data
){
1387 return data
->offline_data_collection_capability
& 0x02;
1389 int isSupportOfflineAbort(struct ata_smart_values
*data
){
1390 return data
->offline_data_collection_capability
& 0x04;
1392 int isSupportOfflineSurfaceScan(struct ata_smart_values
*data
){
1393 return data
->offline_data_collection_capability
& 0x08;
1395 int isSupportSelfTest (struct ata_smart_values
*data
){
1396 return data
->offline_data_collection_capability
& 0x10;
1398 int isSupportConveyanceSelfTest(struct ata_smart_values
*data
){
1399 return data
->offline_data_collection_capability
& 0x20;
1401 int isSupportSelectiveSelfTest(struct ata_smart_values
*data
){
1402 return data
->offline_data_collection_capability
& 0x40;
1407 // Loop over all valid attributes. If they are prefailure attributes
1408 // and are at or below the threshold value, then return the ID of the
1409 // first failing attribute found. Return 0 if all prefailure
1410 // attributes are in bounds. The spec says "Bit 0
1411 // -Pre-failure/advisory - If the value of this bit equals zero, an
1412 // attribute value less than or equal to its corresponding attribute
1413 // threshold indicates an advisory condition where the usage or age of
1414 // the device has exceeded its intended design life period. If the
1415 // value of this bit equals one, an atribute value less than or equal
1416 // to its corresponding attribute threshold indicates a pre-failure
1417 // condition where imminent loss of data is being predicted."
1420 // onlyfailed=0 : are or were any age or prefailure attributes <= threshold
1421 // onlyfailed=1: are any prefailure attributes <= threshold now
1422 int ataCheckSmart(struct ata_smart_values
*data
,
1423 struct ata_smart_thresholds_pvt
*thresholds
,
1427 // loop over all attributes
1428 for (i
=0; i
<NUMBER_ATA_SMART_ATTRIBUTES
; i
++){
1430 // pointers to disk's values and vendor's thresholds
1431 struct ata_smart_attribute
*disk
=data
->vendor_attributes
+i
;
1432 struct ata_smart_threshold_entry
*thre
=thresholds
->thres_entries
+i
;
1434 // consider only valid attributes
1435 if (disk
->id
&& thre
->id
){
1436 int failednow
,failedever
;
1438 failednow
=disk
->current
<= thre
->threshold
;
1439 failedever
=disk
->worst
<= thre
->threshold
;
1441 if (!onlyfailed
&& failedever
)
1444 if (onlyfailed
&& failednow
&& ATTRIBUTE_FLAGS_PREFAILURE(disk
->flags
))
1453 // This checks the n'th attribute in the attribute list, NOT the
1454 // attribute with id==n. If the attribute does not exist, or the
1455 // attribute is > threshold, then returns zero. If the attribute is
1456 // <= threshold (failing) then we the attribute number if it is a
1457 // prefail attribute. Else we return minus the attribute number if it
1458 // is a usage attribute.
1459 int ataCheckAttribute(struct ata_smart_values
*data
,
1460 struct ata_smart_thresholds_pvt
*thresholds
,
1462 struct ata_smart_attribute
*disk
;
1463 struct ata_smart_threshold_entry
*thre
;
1465 if (n
<0 || n
>=NUMBER_ATA_SMART_ATTRIBUTES
|| !data
|| !thresholds
)
1468 // pointers to disk's values and vendor's thresholds
1469 disk
=data
->vendor_attributes
+n
;
1470 thre
=thresholds
->thres_entries
+n
;
1475 // consider only valid attributes, check for failure
1476 if (!disk
->id
|| !thre
->id
|| (disk
->id
!= thre
->id
) || disk
->current
> thre
->threshold
)
1479 // We have found a failed attribute. Return positive or negative?
1480 if (ATTRIBUTE_FLAGS_PREFAILURE(disk
->flags
))
1483 return -1*(disk
->id
);
1487 // This routine prints the raw value of an attribute as a text string
1488 // into out. It also returns this 48-bit number as a long long. The
1489 // array defs[] contains non-zero values if particular attributes have
1490 // non-default interpretations.
1492 int64_t ataPrintSmartAttribRawValue(char *out
,
1493 struct ata_smart_attribute
*attribute
,
1494 unsigned char *defs
){
1498 unsigned char select
;
1500 // convert the six individual bytes to a long long (8 byte) integer.
1501 // This is the value that we'll eventually return.
1503 for (j
=0; j
<6; j
++) {
1504 // This looks a bit roundabout, but is necessary. Don't
1505 // succumb to the temptation to use raw[j]<<(8*j) since under
1506 // the normal rules this will be promoted to the native type.
1507 // On a 32 bit machine this might then overflow.
1509 temp
= attribute
->raw
[j
];
1514 // convert quantities to three two-byte words
1515 for (j
=0; j
<3; j
++){
1516 word
[j
] = attribute
->raw
[2*j
+1];
1518 word
[j
] |= attribute
->raw
[2*j
];
1521 // if no data array, Attributes have default interpretations
1523 select
=defs
[attribute
->id
];
1527 // Print six one-byte quantities.
1530 out
+=sprintf(out
, "%d ", attribute
->raw
[5-j
]);
1531 out
+=sprintf(out
, "%d ", attribute
->raw
[0]);
1535 // Print three two-byte quantities
1537 out
+=sprintf(out
, "%d %d %d", word
[2], word
[1], word
[0]);
1541 // Print one six-byte quantity
1543 out
+=sprintf(out
, "%"PRIu64
, rawvalue
);
1547 // This switch statement is where we handle Raw attributes
1548 // that are stored in an unusual vendor-specific format,
1549 switch (attribute
->id
){
1552 out
+=sprintf(out
, "%d", word
[0]);
1553 // if second nonzero then it stores the average spin-up time
1555 out
+=sprintf(out
, " (Average %d)", word
[1]);
1561 int64_t tmp1
=rawvalue
/60;
1562 int64_t tmp2
=rawvalue
%60;
1563 out
+=sprintf(out
, "%"PRIu64
"h+%02"PRIu64
"m", tmp1
, tmp2
);
1565 else if (select
==3){
1567 int64_t hours
=rawvalue
/3600;
1568 int64_t minutes
=(rawvalue
-3600*hours
)/60;
1569 int64_t seconds
=rawvalue
%60;
1570 out
+=sprintf(out
, "%"PRIu64
"h+%02"PRIu64
"m+%02"PRIu64
"s", hours
, minutes
, seconds
);
1572 else if (select
==4){
1573 // 30-second counter
1574 int64_t tmp1
=rawvalue
/120;
1575 int64_t tmp2
=(rawvalue
-120*tmp1
)/2;
1576 out
+=sprintf(out
, "%"PRIu64
"h+%02"PRIu64
"m", tmp1
, tmp2
);
1580 out
+=sprintf(out
, "%"PRIu64
, rawvalue
); //stored in hours
1582 // Load unload cycles
1586 long load
=attribute
->raw
[0] + (attribute
->raw
[1]<<8) + (attribute
->raw
[2]<<16);
1587 long unload
=attribute
->raw
[3] + (attribute
->raw
[4]<<8) + (attribute
->raw
[5]<<16);
1588 out
+=sprintf(out
, "%lu/%lu", load
, unload
);
1592 out
+=sprintf(out
, "%"PRIu64
, rawvalue
);
1597 // ten times temperature in Celsius
1599 int tenths
=word
[0]%10;
1600 out
+=sprintf(out
, "%d.%d", deg
, tenths
);
1603 // unknown attribute
1604 out
+=sprintf(out
, "%"PRIu64
, rawvalue
);
1606 out
+=sprintf(out
, "%d", word
[0]);
1607 if (!(rawvalue
==word
[0])) {
1608 int min
=word
[1]<word
[2]?word
[1]:word
[2];
1609 int max
=word
[1]>word
[2]?word
[1]:word
[2];
1610 // The other bytes are in use. Try IBM's model
1611 out
+=sprintf(out
, " (Lifetime Min/Max %d/%d)", min
, max
);
1616 out
+=sprintf(out
, "%"PRIu64
, rawvalue
);
1619 // Return the full value
1624 // Note some attribute names appear redundant because different
1625 // manufacturers use different attribute IDs for an attribute with the
1626 // same name. The variable val should contain a non-zero value if a particular
1627 // attributes has a non-default interpretation.
1628 void ataPrintSmartAttribName(char *out
, unsigned char id
, unsigned char *definitions
){
1632 // If no data array, use default interpretations
1634 val
=definitions
[id
];
1641 name
="Raw_Read_Error_Rate";
1644 name
="Throughput_Performance";
1647 name
="Spin_Up_Time";
1650 name
="Start_Stop_Count";
1653 name
="Reallocated_Sector_Ct";
1656 name
="Read_Channel_Margin";
1659 name
="Seek_Error_Rate";
1662 name
="Seek_Time_Performance";
1667 name
="Power_On_Minutes";
1670 name
="Temperature_Celsius";
1673 name
="Power_On_Seconds";
1676 name
="Power_On_Half_Minutes";
1679 name
="Power_On_Hours";
1684 name
="Spin_Retry_Count";
1687 name
="Calibration_Retry_Count";
1690 name
="Power_Cycle_Count";
1693 name
="Read_Soft_Error_Rate";
1696 // Western Digital uses this for temperature.
1697 // It's identical to Attribute 194 except that it
1698 // has a failure threshold set to correspond to the
1699 // max allowed operating temperature of the drive, which
1700 // is typically 55C. So if this attribute has failed
1701 // in the past, it indicates that the drive temp exceeded
1702 // 55C sometime in the past.
1703 name
="Temperature_Celsius";
1706 name
="G-Sense_Error_Rate";
1712 name
="Emergency_Retract_Cycle_Ct";
1715 name
="Power-Off_Retract_Count";
1720 name
="Load_Cycle_Count";
1725 // Samsung SV1204H with RK100-13 firmware
1726 name
="Temperature_Celsius_x10";
1729 // for disks with no temperature Attribute
1730 name
="Unknown_Attribute";
1733 name
="Temperature_Celsius";
1738 // Fujitsu name="ECC_On_The_Fly_Count";
1739 name
="Hardware_ECC_Recovered";
1742 name
="Reallocated_Event_Count";
1745 name
="Current_Pending_Sector";
1751 name
="Off-line_Scan_UNC_Sector_Ct";
1754 name
="Offline_Uncorrectable";
1759 name
="UDMA_CRC_Error_Count";
1764 // Fujitsu MHS2020AT
1765 name
="Write_Error_Count";
1769 name
="Multi_Zone_Error_Rate";
1777 name
="Detected_TA_Count";
1780 name
="Soft_Read_Error_Rate";
1786 name
="TA_Increase_Count";
1787 // Maxtor: Data Address Mark Errors
1791 name
="Run_Out_Cancel";
1792 // Maxtor: ECC Errors
1796 name
="Shock_Count_Write_Opern";
1797 // Maxtor: Soft ECC Correction
1801 name
="Shock_Rate_Write_Opern";
1802 // Maxtor: Thermal Aspirates
1806 name
="Flying_Height";
1810 name
="Spin_High_Current";
1818 name
="Offline_Seek_Performnce";
1823 name
="Temperature_Celsius";
1831 name
="G-Sense_Error_Rate";
1834 name
="Loaded_Hours";
1837 name
="Load_Retry_Count";
1840 name
="Load_Friction";
1843 name
="Load_Cycle_Count";
1846 name
="Load-in_Time";
1849 name
="Torq-amp_Count";
1852 name
="Power-off_Retract_Count";
1855 // seen in IBM DTPA-353750
1856 name
="Head_Amplitude";
1859 name
="Temperature_Celsius";
1862 name
="Head_Flying_Hours";
1865 name
="Read_Error_Retry_Rate";
1868 name
="Unknown_Attribute";
1871 sprintf(out
,"%3hu %s",(short int)id
,name
);
1875 // Returns raw value of Attribute with ID==id. This will be in the
1876 // range 0 to 2^48-1 inclusive. If the Attribute does not exist,
1878 int64_t ATAReturnAttributeRawValue(unsigned char id
, struct ata_smart_values
*data
) {
1881 // valid Attribute IDs are in the range 1 to 255 inclusive.
1885 // loop over Attributes to see if there is one with the desired ID
1886 for (i
=0; i
<NUMBER_ATA_SMART_ATTRIBUTES
; i
++) {
1887 struct ata_smart_attribute
*ap
= data
->vendor_attributes
+ i
;
1889 // we've found the desired Attribute. Return its value
1893 for (j
=0; j
<6; j
++) {
1894 // This looks a bit roundabout, but is necessary. Don't
1895 // succumb to the temptation to use raw[j]<<(8*j) since under
1896 // the normal rules this will be promoted to the native type.
1897 // On a 32 bit machine this might then overflow.
1904 } // found desired Attribute
1905 } // loop over Attributes
1907 // fall-through: no such Attribute found
1911 // Return Temperature Attribute raw value selected according to possible
1912 // non-default interpretations. If the Attribute does not exist, return 0
1913 unsigned char ATAReturnTemperatureValue(/*const*/ struct ata_smart_values
*data
, const unsigned char *defs
){
1915 for (i
= 0; i
< 3; i
++) {
1916 static const unsigned char ids
[3] = {194, 9, 220};
1917 unsigned char id
= ids
[i
];
1918 unsigned char select
= (defs
? defs
[id
] : 0);
1919 int64_t raw
; unsigned temp
;
1920 if (!( (id
== 194 && select
<= 1) // ! -v 194,unknown
1921 || (id
== 9 && select
== 2) // -v 9,temp
1922 || (id
== 220 && select
== 1))) // -v 220,temp
1924 raw
= ATAReturnAttributeRawValue(id
, data
);
1927 temp
= (unsigned short)raw
; // ignore possible min/max values in high words
1928 if (id
== 194 && select
== 1) // -v 194,10xCelsius
1929 temp
= (temp
+5) / 10;
1930 if (!(0 < temp
&& temp
<= 255))
1934 // No valid attribute found