]> git.proxmox.com Git - mirror_smartmontools-debian.git/blame - atacmds.cpp
Updated changelog
[mirror_smartmontools-debian.git] / atacmds.cpp
CommitLineData
832b75ed 1/*
4d59bff9 2 * atacmds.cpp
832b75ed
GG
3 *
4 * Home page of code is: http://smartmontools.sourceforge.net
5 *
cfbba5b9 6 * Copyright (C) 2002-11 Bruce Allen <smartmontools-support@lists.sourceforge.net>
d008864d 7 * Copyright (C) 2008-12 Christian Franke <smartmontools-support@lists.sourceforge.net>
832b75ed
GG
8 * Copyright (C) 1999-2000 Michael Cornwell <cornwell@acm.org>
9 * Copyright (C) 2000 Andre Hedrick <andre@linux-ide.org>
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2, or (at your option)
14 * any later version.
15 *
16 * You should have received a copy of the GNU General Public License
17 * (for example COPYING); if not, write to the Free
18 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 *
20 * This code was originally developed as a Senior Thesis by Michael Cornwell
21 * at the Concurrent Systems Laboratory (now part of the Storage Systems
22 * Research Center), Jack Baskin School of Engineering, University of
23 * California, Santa Cruz. http://ssrc.soe.ucsc.edu/
24 *
25 */
26
27#include <stdio.h>
28#include <string.h>
29#include <errno.h>
30#include <stdlib.h>
31#include <ctype.h>
32
33#include "config.h"
34#include "int64.h"
35#include "atacmds.h"
832b75ed 36#include "utility.h"
2127e193 37#include "dev_ata_cmd_set.h" // for parsed_ata_device
832b75ed 38
e165493d 39const char * atacmds_cpp_cvsid = "$Id: atacmds.cpp 3528 2012-03-25 17:13:47Z chrfranke $"
2127e193 40 ATACMDS_H_CVSID;
832b75ed 41
cfbba5b9
GI
42// Print ATA debug messages?
43unsigned char ata_debugmode = 0;
44
45// Suppress serial number?
46// (also used in scsiprint.cpp)
47bool dont_print_serial_number = false;
48
832b75ed 49
2127e193
GI
50#define SMART_CYL_LOW 0x4F
51#define SMART_CYL_HI 0xC2
52
53// SMART RETURN STATUS yields SMART_CYL_HI,SMART_CYL_LOW to indicate drive
54// is healthy and SRET_STATUS_HI_EXCEEDED,SRET_STATUS_MID_EXCEEDED to
55// indicate that a threshhold exceeded condition has been detected.
56// Those values (byte pairs) are placed in ATA register "LBA 23:8".
57#define SRET_STATUS_HI_EXCEEDED 0x2C
58#define SRET_STATUS_MID_EXCEEDED 0xF4
59
832b75ed
GG
60// These Drive Identity tables are taken from hdparm 5.2, and are also
61// given in the ATA/ATAPI specs for the IDENTIFY DEVICE command. Note
62// that SMART was first added into the ATA/ATAPI-3 Standard with
63// Revision 3 of the document, July 25, 1995. Look at the "Document
64// Status" revision commands at the beginning of
a23d5117
GI
65// http://www.t13.org/Documents/UploadedDocuments/project/d2008r7b-ATA-3.pdf
66// to see this.
832b75ed
GG
67#define NOVAL_0 0x0000
68#define NOVAL_1 0xffff
69/* word 81: minor version number */
70#define MINOR_MAX 0x22
2127e193 71static const char * const minor_str[] = { /* word 81 value: */
832b75ed
GG
72 "Device does not report version", /* 0x0000 */
73 "ATA-1 X3T9.2 781D prior to revision 4", /* 0x0001 */
74 "ATA-1 published, ANSI X3.221-1994", /* 0x0002 */
75 "ATA-1 X3T9.2 781D revision 4", /* 0x0003 */
76 "ATA-2 published, ANSI X3.279-1996", /* 0x0004 */
77 "ATA-2 X3T10 948D prior to revision 2k", /* 0x0005 */
78 "ATA-3 X3T10 2008D revision 1", /* 0x0006 */ /* SMART NOT INCLUDED */
79 "ATA-2 X3T10 948D revision 2k", /* 0x0007 */
80 "ATA-3 X3T10 2008D revision 0", /* 0x0008 */
81 "ATA-2 X3T10 948D revision 3", /* 0x0009 */
82 "ATA-3 published, ANSI X3.298-199x", /* 0x000a */
83 "ATA-3 X3T10 2008D revision 6", /* 0x000b */ /* 1st VERSION WITH SMART */
84 "ATA-3 X3T13 2008D revision 7 and 7a", /* 0x000c */
85 "ATA/ATAPI-4 X3T13 1153D revision 6", /* 0x000d */
86 "ATA/ATAPI-4 T13 1153D revision 13", /* 0x000e */
87 "ATA/ATAPI-4 X3T13 1153D revision 7", /* 0x000f */
88 "ATA/ATAPI-4 T13 1153D revision 18", /* 0x0010 */
89 "ATA/ATAPI-4 T13 1153D revision 15", /* 0x0011 */
90 "ATA/ATAPI-4 published, ANSI NCITS 317-1998", /* 0x0012 */
91 "ATA/ATAPI-5 T13 1321D revision 3", /* 0x0013 */
92 "ATA/ATAPI-4 T13 1153D revision 14", /* 0x0014 */
93 "ATA/ATAPI-5 T13 1321D revision 1", /* 0x0015 */
94 "ATA/ATAPI-5 published, ANSI NCITS 340-2000", /* 0x0016 */
95 "ATA/ATAPI-4 T13 1153D revision 17", /* 0x0017 */
96 "ATA/ATAPI-6 T13 1410D revision 0", /* 0x0018 */
97 "ATA/ATAPI-6 T13 1410D revision 3a", /* 0x0019 */
98 "ATA/ATAPI-7 T13 1532D revision 1", /* 0x001a */
99 "ATA/ATAPI-6 T13 1410D revision 2", /* 0x001b */
100 "ATA/ATAPI-6 T13 1410D revision 1", /* 0x001c */
4d59bff9 101 "ATA/ATAPI-7 published, ANSI INCITS 397-2005",/* 0x001d */
832b75ed
GG
102 "ATA/ATAPI-7 T13 1532D revision 0", /* 0x001e */
103 "reserved", /* 0x001f */
104 "reserved", /* 0x0020 */
105 "ATA/ATAPI-7 T13 1532D revision 4a", /* 0x0021 */
106 "ATA/ATAPI-6 published, ANSI INCITS 361-2002" /* 0x0022 */
107};
108
109// NOTE ATA/ATAPI-4 REV 4 was the LAST revision where the device
110// attribute structures were NOT completely vendor specific. So any
111// disk that is ATA/ATAPI-4 or above can not be trusted to show the
112// vendor values in sensible format.
113
114// Negative values below are because it doesn't support SMART
2127e193 115static const int actual_ver[] = {
832b75ed
GG
116 /* word 81 value: */
117 0, /* 0x0000 WARNING: */
118 1, /* 0x0001 WARNING: */
119 1, /* 0x0002 WARNING: */
120 1, /* 0x0003 WARNING: */
121 2, /* 0x0004 WARNING: This array */
122 2, /* 0x0005 WARNING: corresponds */
123 -3, /*<== */ /* 0x0006 WARNING: *exactly* */
124 2, /* 0x0007 WARNING: to the ATA/ */
125 -3, /*<== */ /* 0x0008 WARNING: ATAPI version */
126 2, /* 0x0009 WARNING: listed in */
127 3, /* 0x000a WARNING: the */
128 3, /* 0x000b WARNING: minor_str */
129 3, /* 0x000c WARNING: array */
130 4, /* 0x000d WARNING: above. */
131 4, /* 0x000e WARNING: */
132 4, /* 0x000f WARNING: If you change */
133 4, /* 0x0010 WARNING: that one, */
134 4, /* 0x0011 WARNING: change this one */
135 4, /* 0x0012 WARNING: too!!! */
136 5, /* 0x0013 WARNING: */
137 4, /* 0x0014 WARNING: */
138 5, /* 0x0015 WARNING: */
139 5, /* 0x0016 WARNING: */
140 4, /* 0x0017 WARNING: */
141 6, /* 0x0018 WARNING: */
142 6, /* 0x0019 WARNING: */
143 7, /* 0x001a WARNING: */
144 6, /* 0x001b WARNING: */
145 6, /* 0x001c WARNING: */
4d59bff9 146 7, /* 0x001d WARNING: */
832b75ed
GG
147 7, /* 0x001e WARNING: */
148 0, /* 0x001f WARNING: */
149 0, /* 0x0020 WARNING: */
150 7, /* 0x0021 WARNING: */
151 6 /* 0x0022 WARNING: */
152};
153
cfbba5b9
GI
154// Compile time check of above array sizes
155typedef char assert_sizeof_minor_str [sizeof(minor_str) /sizeof(minor_str[0]) == MINOR_MAX+1 ? 1 : -1];
156typedef char assert_sizeof_actual_ver[sizeof(actual_ver)/sizeof(actual_ver[0]) == MINOR_MAX+1 ? 1 : -1];
157
2127e193
GI
158// Get ID and increase flag of current pending or offline
159// uncorrectable attribute.
bed94269 160unsigned char get_unc_attr_id(bool offline, const ata_vendor_attr_defs & defs,
2127e193
GI
161 bool & increase)
162{
163 unsigned char id = (!offline ? 197 : 198);
e9583e0c
GI
164 const ata_vendor_attr_defs::entry & def = defs[id];
165 if (def.flags & ATTRFLAG_INCREASING)
166 increase = true; // '-v 19[78],increasing' option
167 else if (def.name.empty() || (id == 198 && def.name == "Offline_Scan_UNC_SectCt"))
168 increase = false; // no or '-v 198,offlinescanuncsectorct' option
169 else
170 id = 0; // other '-v 19[78],...' option
2127e193
GI
171 return id;
172}
173
bed94269 174#if 0 // TODO: never used
832b75ed
GG
175// This are the meanings of the Self-test failure checkpoint byte.
176// This is in the self-test log at offset 4 bytes into the self-test
177// descriptor and in the SMART READ DATA structure at byte offset
178// 371. These codes are not well documented. The meanings returned by
179// this routine are used (at least) by Maxtor and IBM. Returns NULL if
180// not recognized. Currently the maximum length is 15 bytes.
181const char *SelfTestFailureCodeName(unsigned char which){
182
183 switch (which) {
184 case 0:
185 return "Write_Test";
186 case 1:
187 return "Servo_Basic";
188 case 2:
189 return "Servo_Random";
190 case 3:
191 return "G-list_Scan";
192 case 4:
193 return "Handling_Damage";
194 case 5:
195 return "Read_Scan";
196 default:
197 return NULL;
198 }
199}
bed94269
GI
200#endif
201
832b75ed 202
bed94269
GI
203// Table of raw print format names
204struct format_name_entry
832b75ed 205{
bed94269
GI
206 const char * name;
207 ata_attr_raw_format format;
208};
209
210const format_name_entry format_names[] = {
211 {"raw8" , RAWFMT_RAW8},
212 {"raw16" , RAWFMT_RAW16},
213 {"raw48" , RAWFMT_RAW48},
214 {"hex48" , RAWFMT_HEX48},
e165493d
GI
215 {"raw56" , RAWFMT_RAW56},
216 {"hex56" , RAWFMT_HEX56},
bed94269
GI
217 {"raw64" , RAWFMT_RAW64},
218 {"hex64" , RAWFMT_HEX64},
219 {"raw16(raw16)" , RAWFMT_RAW16_OPT_RAW16},
220 {"raw16(avg16)" , RAWFMT_RAW16_OPT_AVG16},
e165493d 221 {"raw24(raw8)" , RAWFMT_RAW24_OPT_RAW8},
cfbba5b9
GI
222 {"raw24/raw24" , RAWFMT_RAW24_DIV_RAW24},
223 {"raw24/raw32" , RAWFMT_RAW24_DIV_RAW32},
bed94269
GI
224 {"sec2hour" , RAWFMT_SEC2HOUR},
225 {"min2hour" , RAWFMT_MIN2HOUR},
226 {"halfmin2hour" , RAWFMT_HALFMIN2HOUR},
cfbba5b9 227 {"msec24hour32" , RAWFMT_MSEC24_HOUR32},
bed94269
GI
228 {"tempminmax" , RAWFMT_TEMPMINMAX},
229 {"temp10x" , RAWFMT_TEMP10X},
230};
231
232const unsigned num_format_names = sizeof(format_names)/sizeof(format_names[0]);
233
234// Table to map old to new '-v' option arguments
235const char * map_old_vendor_opts[][2] = {
236 { "9,halfminutes" , "9,halfmin2hour,Power_On_Half_Minutes"},
237 { "9,minutes" , "9,min2hour,Power_On_Minutes"},
238 { "9,seconds" , "9,sec2hour,Power_On_Seconds"},
239 { "9,temp" , "9,tempminmax,Temperature_Celsius"},
240 {"192,emergencyretractcyclect" , "192,raw48,Emerg_Retract_Cycle_Ct"},
241 {"193,loadunload" , "193,raw24/raw24"},
242 {"194,10xCelsius" , "194,temp10x,Temperature_Celsius_x10"},
243 {"194,unknown" , "194,raw48,Unknown_Attribute"},
244 {"197,increasing" , "197,raw48+,Total_Pending_Sectors"}, // '+' sets flag
e9583e0c 245 {"198,offlinescanuncsectorct" , "198,raw48,Offline_Scan_UNC_SectCt"}, // see also get_unc_attr_id() above
bed94269
GI
246 {"198,increasing" , "198,raw48+,Total_Offl_Uncorrectabl"}, // '+' sets flag
247 {"200,writeerrorcount" , "200,raw48,Write_Error_Count"},
248 {"201,detectedtacount" , "201,raw48,Detected_TA_Count"},
249 {"220,temp" , "220,raw48,Temperature_Celsius"},
250};
251
252const unsigned num_old_vendor_opts = sizeof(map_old_vendor_opts)/sizeof(map_old_vendor_opts[0]);
253
254// Parse vendor attribute display def (-v option).
255// Return false on error.
256bool parse_attribute_def(const char * opt, ata_vendor_attr_defs & defs,
257 ata_vendor_def_prior priority)
258{
259 // Map old -> new options
260 unsigned i;
261 for (i = 0; i < num_old_vendor_opts; i++) {
262 if (!strcmp(opt, map_old_vendor_opts[i][0])) {
263 opt = map_old_vendor_opts[i][1];
264 break;
265 }
266 }
267
268 // Parse option
269 int len = strlen(opt);
270 int id = 0, n1 = -1, n2 = -1;
271 char fmtname[32+1], attrname[32+1];
272 if (opt[0] == 'N') {
273 // "N,format"
274 if (!( sscanf(opt, "N,%32[^,]%n,%32[^,]%n", fmtname, &n1, attrname, &n2) >= 1
275 && (n1 == len || n2 == len)))
276 return false;
2127e193
GI
277 }
278 else {
bed94269
GI
279 // "id,format[+][,name]"
280 if (!( sscanf(opt, "%d,%32[^,]%n,%32[^,]%n", &id, fmtname, &n1, attrname, &n2) >= 2
281 && 1 <= id && id <= 255 && (n1 == len || n2 == len)))
282 return false;
2127e193 283 }
bed94269
GI
284 if (n1 == len)
285 attrname[0] = 0;
2127e193 286
bed94269
GI
287 unsigned flags = 0;
288 // For "-v 19[78],increasing" above
289 if (fmtname[strlen(fmtname)-1] == '+') {
290 fmtname[strlen(fmtname)-1] = 0;
291 flags = ATTRFLAG_INCREASING;
292 }
293
a23d5117
GI
294 // Split "format[:byteorder]"
295 char byteorder[8+1] = "";
296 if (strchr(fmtname, ':')) {
297 if (!( sscanf(fmtname, "%*[^:]%n:%8[012345rvwz]%n", &n1, byteorder, &n2) >= 1
298 && n2 == (int)strlen(fmtname)))
299 return false;
300 fmtname[n1] = 0;
301 if (strchr(byteorder, 'v'))
302 flags |= (ATTRFLAG_NO_NORMVAL|ATTRFLAG_NO_WORSTVAL);
303 if (strchr(byteorder, 'w'))
304 flags |= ATTRFLAG_NO_WORSTVAL;
305 }
306
bed94269 307 // Find format name
2127e193 308 for (i = 0; ; i++) {
bed94269
GI
309 if (i >= num_format_names)
310 return false; // Not found
311 if (!strcmp(fmtname, format_names[i].name))
2127e193 312 break;
832b75ed 313 }
bed94269
GI
314 ata_attr_raw_format format = format_names[i].format;
315
a23d5117
GI
316 // 64-bit formats use the normalized and worst value bytes.
317 if (!*byteorder && (format == RAWFMT_RAW64 || format == RAWFMT_HEX64))
318 flags |= (ATTRFLAG_NO_NORMVAL|ATTRFLAG_NO_WORSTVAL);
832b75ed 319
2127e193 320 if (!id) {
bed94269
GI
321 // "N,format" -> set format for all entries
322 for (i = 0; i < MAX_ATTRIBUTE_NUM; i++) {
323 if (defs[i].priority >= priority)
324 continue;
325 if (attrname[0])
326 defs[i].name = attrname;
327 defs[i].priority = priority;
328 defs[i].raw_format = format;
329 defs[i].flags = flags;
a23d5117 330 strcpy(defs[i].byteorder, byteorder);
bed94269
GI
331 }
332 }
333 else if (defs[id].priority <= priority) {
334 // "id,format[,name]"
335 if (attrname[0])
336 defs[id].name = attrname;
337 defs[id].raw_format = format;
338 defs[id].priority = priority;
339 defs[id].flags = flags;
a23d5117 340 strcpy(defs[id].byteorder, byteorder);
832b75ed
GG
341 }
342
bed94269 343 return true;
832b75ed
GG
344}
345
bed94269 346
2127e193
GI
347// Return a multiline string containing a list of valid arguments for
348// parse_attribute_def(). The strings are preceeded by tabs and followed
832b75ed 349// (except for the last) by newlines.
2127e193
GI
350std::string create_vendor_attribute_arg_list()
351{
352 std::string s;
bed94269
GI
353 unsigned i;
354 for (i = 0; i < num_format_names; i++)
a23d5117 355 s += strprintf("%s\tN,%s[:012345rvwz][,ATTR_NAME]",
bed94269
GI
356 (i>0 ? "\n" : ""), format_names[i].name);
357 for (i = 0; i < num_old_vendor_opts; i++)
358 s += strprintf("\n\t%s", map_old_vendor_opts[i][0]);
832b75ed
GG
359 return s;
360}
361
362// swap two bytes. Point to low address
363void swap2(char *location){
364 char tmp=*location;
365 *location=*(location+1);
366 *(location+1)=tmp;
367 return;
368}
369
370// swap four bytes. Point to low address
371void swap4(char *location){
372 char tmp=*location;
373 *location=*(location+3);
374 *(location+3)=tmp;
375 swap2(location+1);
376 return;
377}
378
379// swap eight bytes. Points to low address
380void swap8(char *location){
381 char tmp=*location;
382 *location=*(location+7);
383 *(location+7)=tmp;
384 tmp=*(location+1);
385 *(location+1)=*(location+6);
386 *(location+6)=tmp;
387 swap4(location+2);
388 return;
389}
390
a7e8ffec
GI
391// Invalidate serial number and WWN and adjust checksum in IDENTIFY data
392static void invalidate_serno(ata_identify_device * id)
393{
a37e7145 394 unsigned char sum = 0;
a7e8ffec
GI
395 unsigned i;
396 for (i = 0; i < sizeof(id->serial_no); i++) {
a37e7145
GG
397 sum += id->serial_no[i]; sum -= id->serial_no[i] = 'X';
398 }
a7e8ffec
GI
399 unsigned char * b = (unsigned char *)id;
400 for (i = 2*108; i < 2*112; i++) { // words108-111: WWN
401 sum += b[i]; sum -= b[i] = 0x00;
402 }
403
a37e7145
GG
404#ifndef __NetBSD__
405 bool must_swap = !!isbigendian();
406 if (must_swap)
407 swapx(id->words088_255+255-88);
408#endif
409 if ((id->words088_255[255-88] & 0x00ff) == 0x00a5)
410 id->words088_255[255-88] += sum << 8;
411#ifndef __NetBSD__
412 if (must_swap)
413 swapx(id->words088_255+255-88);
414#endif
415}
416
2127e193 417static const char * const commandstrings[]={
832b75ed
GG
418 "SMART ENABLE",
419 "SMART DISABLE",
420 "SMART AUTOMATIC ATTRIBUTE SAVE",
421 "SMART IMMEDIATE OFFLINE",
422 "SMART AUTO OFFLINE",
423 "SMART STATUS",
424 "SMART STATUS CHECK",
425 "SMART READ ATTRIBUTE VALUES",
426 "SMART READ ATTRIBUTE THRESHOLDS",
427 "SMART READ LOG",
428 "IDENTIFY DEVICE",
429 "IDENTIFY PACKET DEVICE",
430 "CHECK POWER MODE",
431 "SMART WRITE LOG",
432 "WARNING (UNDEFINED COMMAND -- CONTACT DEVELOPERS AT " PACKAGE_BUGREPORT ")\n"
433};
434
2127e193
GI
435
436static const char * preg(const ata_register & r, char * buf)
437{
438 if (!r.is_set())
439 //return "n/a ";
440 return "....";
441 sprintf(buf, "0x%02x", r.val()); return buf;
442}
443
cfbba5b9 444static void print_regs(const char * prefix, const ata_in_regs & r, const char * suffix = "\n")
2127e193
GI
445{
446 char bufs[7][4+1+13];
447 pout("%s FR=%s, SC=%s, LL=%s, LM=%s, LH=%s, DEV=%s, CMD=%s%s", prefix,
448 preg(r.features, bufs[0]), preg(r.sector_count, bufs[1]), preg(r.lba_low, bufs[2]),
449 preg(r.lba_mid, bufs[3]), preg(r.lba_high, bufs[4]), preg(r.device, bufs[5]),
450 preg(r.command, bufs[6]), suffix);
451}
452
cfbba5b9 453static void print_regs(const char * prefix, const ata_out_regs & r, const char * suffix = "\n")
2127e193
GI
454{
455 char bufs[7][4+1+13];
456 pout("%sERR=%s, SC=%s, LL=%s, LM=%s, LH=%s, DEV=%s, STS=%s%s", prefix,
457 preg(r.error, bufs[0]), preg(r.sector_count, bufs[1]), preg(r.lba_low, bufs[2]),
458 preg(r.lba_mid, bufs[3]), preg(r.lba_high, bufs[4]), preg(r.device, bufs[5]),
459 preg(r.status, bufs[6]), suffix);
460}
461
a37e7145 462static void prettyprint(const unsigned char *p, const char *name){
832b75ed 463 pout("\n===== [%s] DATA START (BASE-16) =====\n", name);
a37e7145 464 for (int i=0; i<512; i+=16, p+=16)
d008864d 465#define P(n) (' ' <= p[n] && p[n] <= '~' ? (int)p[n] : '.')
a37e7145
GG
466 // print complete line to avoid slow tty output and extra lines in syslog.
467 pout("%03d-%03d: %02x %02x %02x %02x %02x %02x %02x %02x "
a23d5117
GI
468 "%02x %02x %02x %02x %02x %02x %02x %02x"
469 " |%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c|"
470 "%c",
a37e7145
GG
471 i, i+16-1,
472 p[ 0], p[ 1], p[ 2], p[ 3], p[ 4], p[ 5], p[ 6], p[ 7],
a23d5117
GI
473 p[ 8], p[ 9], p[10], p[11], p[12], p[13], p[14], p[15],
474 P( 0), P( 1), P( 2), P( 3), P( 4), P( 5), P( 6), P( 7),
475 P( 8), P( 9), P(10), P(11), P(12), P(13), P(14), P(15),
476 '\n');
477#undef P
832b75ed
GG
478 pout("===== [%s] DATA END (512 Bytes) =====\n\n", name);
479}
480
481// This function provides the pretty-print reporting for SMART
482// commands: it implements the various -r "reporting" options for ATA
483// ioctls.
2127e193
GI
484int smartcommandhandler(ata_device * device, smart_command_set command, int select, char *data){
485 // TODO: Rework old stuff below
832b75ed
GG
486 // This conditional is true for commands that return data
487 int getsdata=(command==PIDENTIFY ||
488 command==IDENTIFY ||
489 command==READ_LOG ||
490 command==READ_THRESHOLDS ||
491 command==READ_VALUES ||
4d59bff9 492 command==CHECK_POWER_MODE);
832b75ed
GG
493
494 int sendsdata=(command==WRITE_LOG);
495
496 // If reporting is enabled, say what the command will be before it's executed
cfbba5b9 497 if (ata_debugmode) {
832b75ed
GG
498 // conditional is true for commands that use parameters
499 int usesparam=(command==READ_LOG ||
500 command==AUTO_OFFLINE ||
501 command==AUTOSAVE ||
502 command==IMMEDIATE_OFFLINE ||
503 command==WRITE_LOG);
504
2127e193 505 pout("\nREPORT-IOCTL: Device=%s Command=%s", device->get_dev_name(), commandstrings[command]);
832b75ed
GG
506 if (usesparam)
507 pout(" InputParameter=%d\n", select);
508 else
509 pout("\n");
510 }
511
512 if ((getsdata || sendsdata) && !data){
513 pout("REPORT-IOCTL: Unable to execute command %s : data destination address is NULL\n", commandstrings[command]);
514 return -1;
515 }
516
517 // The reporting is cleaner, and we will find coding bugs faster, if
518 // the commands that failed clearly return empty (zeroed) data
519 // structures
520 if (getsdata) {
521 if (command==CHECK_POWER_MODE)
522 data[0]=0;
523 else
524 memset(data, '\0', 512);
525 }
526
527
a37e7145 528 // if requested, pretty-print the input data structure
cfbba5b9 529 if (ata_debugmode > 1 && sendsdata)
2127e193 530 //pout("REPORT-IOCTL: Device=%s Command=%s\n", device->get_dev_name(), commandstrings[command]);
a37e7145 531 prettyprint((unsigned char *)data, commandstrings[command]);
832b75ed 532
832b75ed 533 // now execute the command
2127e193
GI
534 int retval = -1;
535 {
536 ata_cmd_in in;
537 // Set common register values
538 switch (command) {
539 default: // SMART commands
540 in.in_regs.command = ATA_SMART_CMD;
541 in.in_regs.lba_high = SMART_CYL_HI; in.in_regs.lba_mid = SMART_CYL_LOW;
542 break;
543 case IDENTIFY: case PIDENTIFY: case CHECK_POWER_MODE: // Non SMART commands
544 break;
545 }
546 // Set specific values
547 switch (command) {
548 case IDENTIFY:
549 in.in_regs.command = ATA_IDENTIFY_DEVICE;
550 in.set_data_in(data, 1);
551 break;
552 case PIDENTIFY:
553 in.in_regs.command = ATA_IDENTIFY_PACKET_DEVICE;
554 in.set_data_in(data, 1);
555 break;
556 case CHECK_POWER_MODE:
557 in.in_regs.command = ATA_CHECK_POWER_MODE;
558 in.out_needed.sector_count = true; // Powermode returned here
559 break;
560 case READ_VALUES:
561 in.in_regs.features = ATA_SMART_READ_VALUES;
562 in.set_data_in(data, 1);
563 break;
564 case READ_THRESHOLDS:
565 in.in_regs.features = ATA_SMART_READ_THRESHOLDS;
566 in.in_regs.lba_low = 1; // TODO: CORRECT ???
567 in.set_data_in(data, 1);
568 break;
569 case READ_LOG:
570 in.in_regs.features = ATA_SMART_READ_LOG_SECTOR;
571 in.in_regs.lba_low = select;
572 in.set_data_in(data, 1);
573 break;
574 case WRITE_LOG:
575 in.in_regs.features = ATA_SMART_WRITE_LOG_SECTOR;
576 in.in_regs.lba_low = select;
577 in.set_data_out(data, 1);
578 break;
579 case ENABLE:
580 in.in_regs.features = ATA_SMART_ENABLE;
581 in.in_regs.lba_low = 1; // TODO: CORRECT ???
582 break;
583 case DISABLE:
584 in.in_regs.features = ATA_SMART_DISABLE;
585 in.in_regs.lba_low = 1; // TODO: CORRECT ???
586 break;
587 case STATUS_CHECK:
588 in.out_needed.lba_high = in.out_needed.lba_mid = true; // Status returned here
589 case STATUS:
590 in.in_regs.features = ATA_SMART_STATUS;
591 break;
592 case AUTO_OFFLINE:
593 in.in_regs.features = ATA_SMART_AUTO_OFFLINE;
594 in.in_regs.sector_count = select; // Caution: Non-DATA command!
595 break;
596 case AUTOSAVE:
597 in.in_regs.features = ATA_SMART_AUTOSAVE;
598 in.in_regs.sector_count = select; // Caution: Non-DATA command!
599 break;
600 case IMMEDIATE_OFFLINE:
601 in.in_regs.features = ATA_SMART_IMMEDIATE_OFFLINE;
602 in.in_regs.lba_low = select;
603 break;
604 default:
605 pout("Unrecognized command %d in smartcommandhandler()\n"
606 "Please contact " PACKAGE_BUGREPORT "\n", command);
607 device->set_err(ENOSYS);
2127e193
GI
608 return -1;
609 }
610
cfbba5b9 611 if (ata_debugmode)
2127e193
GI
612 print_regs(" Input: ", in.in_regs,
613 (in.direction==ata_cmd_in::data_in ? " IN\n":
614 in.direction==ata_cmd_in::data_out ? " OUT\n":"\n"));
615
616 ata_cmd_out out;
e165493d
GI
617
618 int64_t start_usec = -1;
619 if (ata_debugmode)
620 start_usec = smi()->get_timer_usec();
621
2127e193
GI
622 bool ok = device->ata_pass_through(in, out);
623
e165493d
GI
624 if (start_usec >= 0) {
625 int64_t duration_usec = smi()->get_timer_usec() - start_usec;
626 if (duration_usec >= 500)
627 pout(" [Duration: %.3fs]\n", duration_usec / 1000000.0);
628 }
629
cfbba5b9 630 if (ata_debugmode && out.out_regs.is_set())
2127e193
GI
631 print_regs(" Output: ", out.out_regs);
632
633 if (ok) switch (command) {
634 default:
635 retval = 0;
636 break;
637 case CHECK_POWER_MODE:
a7e8ffec
GI
638 if (out.out_regs.sector_count.is_set()) {
639 data[0] = out.out_regs.sector_count;
640 retval = 0;
641 }
642 else {
643 pout("CHECK POWER MODE: incomplete response, ATA output registers missing\n");
644 device->set_err(ENOSYS);
645 retval = -1;
646 }
2127e193
GI
647 break;
648 case STATUS_CHECK:
649 // Cyl low and Cyl high unchanged means "Good SMART status"
650 if ((out.out_regs.lba_high == SMART_CYL_HI) &&
651 (out.out_regs.lba_mid == SMART_CYL_LOW))
652 retval = 0;
653 // These values mean "Bad SMART status"
654 else if ((out.out_regs.lba_high == SRET_STATUS_HI_EXCEEDED) &&
655 (out.out_regs.lba_mid == SRET_STATUS_MID_EXCEEDED))
656 retval = 1;
657 else if (out.out_regs.lba_mid == SMART_CYL_LOW) {
658 retval = 0;
cfbba5b9 659 if (ata_debugmode)
2127e193
GI
660 pout("SMART STATUS RETURN: half healthy response sequence, "
661 "probable SAT/USB truncation\n");
662 } else if (out.out_regs.lba_mid == SRET_STATUS_MID_EXCEEDED) {
663 retval = 1;
cfbba5b9 664 if (ata_debugmode)
2127e193
GI
665 pout("SMART STATUS RETURN: half unhealthy response sequence, "
666 "probable SAT/USB truncation\n");
a7e8ffec
GI
667 }
668 else if (!out.out_regs.is_set()) {
669 pout("SMART STATUS RETURN: incomplete response, ATA output registers missing\n");
670 device->set_err(ENOSYS);
671 retval = -1;
672 }
673 else {
2127e193 674 // We haven't gotten output that makes sense; print out some debugging info
a23d5117
GI
675 pout("Error SMART Status command failed\n");
676 pout("Please get assistance from %s\n", PACKAGE_HOMEPAGE);
677 pout("Register values returned from SMART Status command are:\n");
678 print_regs(" ", out.out_regs);
a7e8ffec 679 device->set_err(EIO);
2127e193
GI
680 retval = -1;
681 }
682 break;
683 }
832b75ed
GG
684 }
685
a37e7145 686 // If requested, invalidate serial number before any printing is done
cfbba5b9 687 if ((command == IDENTIFY || command == PIDENTIFY) && !retval && dont_print_serial_number)
a37e7145
GG
688 invalidate_serno((ata_identify_device *)data);
689
832b75ed 690 // If reporting is enabled, say what output was produced by the command
cfbba5b9 691 if (ata_debugmode) {
2127e193
GI
692 if (device->get_errno())
693 pout("REPORT-IOCTL: Device=%s Command=%s returned %d errno=%d [%s]\n",
694 device->get_dev_name(), commandstrings[command], retval,
695 device->get_errno(), device->get_errmsg());
832b75ed 696 else
2127e193
GI
697 pout("REPORT-IOCTL: Device=%s Command=%s returned %d\n",
698 device->get_dev_name(), commandstrings[command], retval);
832b75ed
GG
699
700 // if requested, pretty-print the output data structure
cfbba5b9 701 if (ata_debugmode > 1 && getsdata) {
832b75ed
GG
702 if (command==CHECK_POWER_MODE)
703 pout("Sector Count Register (BASE-16): %02x\n", (unsigned char)(*data));
704 else
705 prettyprint((unsigned char *)data, commandstrings[command]);
706 }
707 }
2127e193 708
832b75ed
GG
709 return retval;
710}
711
a7e8ffec
GI
712// Get capacity and sector sizes from IDENTIFY data
713void ata_get_size_info(const ata_identify_device * id, ata_size_info & sizes)
2127e193 714{
a7e8ffec
GI
715 sizes.sectors = sizes.capacity = 0;
716 sizes.log_sector_size = sizes.phy_sector_size = 0;
717 sizes.log_sector_offset = 0;
718
719 // Return if no LBA support
720 if (!(id->words047_079[49-47] & 0x0200))
721 return;
722
723 // Determine 28-bit LBA capacity
724 unsigned lba28 = (unsigned)id->words047_079[61-47] << 16
725 | (unsigned)id->words047_079[60-47] ;
726
727 // Determine 48-bit LBA capacity if supported
728 uint64_t lba48 = 0;
729 if ((id->command_set_2 & 0xc400) == 0x4400)
730 lba48 = (uint64_t)id->words088_255[103-88] << 48
731 | (uint64_t)id->words088_255[102-88] << 32
732 | (uint64_t)id->words088_255[101-88] << 16
733 | (uint64_t)id->words088_255[100-88] ;
734
735 // Return if capacity unknown (ATAPI CD/DVD)
736 if (!(lba28 || lba48))
737 return;
738
739 // Determine sector sizes
740 sizes.log_sector_size = sizes.phy_sector_size = 512;
741
742 unsigned short word106 = id->words088_255[106-88];
743 if ((word106 & 0xc000) == 0x4000) {
744 // Long Logical/Physical Sectors (LLS/LPS) ?
745 if (word106 & 0x1000)
746 // Logical sector size is specified in 16-bit words
747 sizes.log_sector_size = sizes.phy_sector_size =
748 ((id->words088_255[118-88] << 16) | id->words088_255[117-88]) << 1;
749
750 if (word106 & 0x2000)
751 // Physical sector size is multiple of logical sector size
752 sizes.phy_sector_size <<= (word106 & 0x0f);
753
754 unsigned short word209 = id->words088_255[209-88];
755 if ((word209 & 0xc000) == 0x4000)
756 sizes.log_sector_offset = (word209 & 0x3fff) * sizes.log_sector_size;
757 }
758
759 // Some early 4KiB LLS disks (Samsung N3U-3) return bogus lba28 value
760 if (lba48 >= lba28 || (lba48 && sizes.log_sector_size > 512))
761 sizes.sectors = lba48;
762 else
763 sizes.sectors = lba28;
764
765 sizes.capacity = sizes.sectors * sizes.log_sector_size;
2127e193 766}
832b75ed
GG
767
768// This function computes the checksum of a single disk sector (512
769// bytes). Returns zero if checksum is OK, nonzero if the checksum is
770// incorrect. The size (512) is correct for all SMART structures.
2127e193
GI
771unsigned char checksum(const void * data)
772{
773 unsigned char sum = 0;
774 for (int i = 0; i < 512; i++)
775 sum += ((const unsigned char *)data)[i];
776 return sum;
777}
778
779// Copies n bytes (or n-1 if n is odd) from in to out, but swaps adjacents
780// bytes.
781static void swapbytes(char * out, const char * in, size_t n)
782{
783 for (size_t i = 0; i < n; i += 2) {
784 out[i] = in[i+1];
785 out[i+1] = in[i];
786 }
787}
788
789// Copies in to out, but removes leading and trailing whitespace.
790static void trim(char * out, const char * in)
791{
792 // Find the first non-space character (maybe none).
793 int first = -1;
832b75ed 794 int i;
2127e193
GI
795 for (i = 0; in[i]; i++)
796 if (!isspace((int)in[i])) {
797 first = i;
798 break;
799 }
832b75ed 800
2127e193
GI
801 if (first == -1) {
802 // There are no non-space characters.
803 out[0] = '\0';
804 return;
805 }
806
807 // Find the last non-space character.
808 for (i = strlen(in)-1; i >= first && isspace((int)in[i]); i--)
809 ;
810 int last = i;
811
812 strncpy(out, in+first, last-first+1);
813 out[last-first+1] = '\0';
814}
815
816// Convenience function for formatting strings from ata_identify_device
cfbba5b9 817void ata_format_id_string(char * out, const unsigned char * in, int n)
2127e193 818{
cfbba5b9 819 bool must_swap = true;
2127e193
GI
820#ifdef __NetBSD__
821 /* NetBSD kernel delivers IDENTIFY data in host byte order (but all else is LE) */
cfbba5b9 822 // TODO: Handle NetBSD case in os_netbsd.cpp
2127e193
GI
823 if (isbigendian())
824 must_swap = !must_swap;
825#endif
826
827 char tmp[65];
828 n = n > 64 ? 64 : n;
829 if (!must_swap)
cfbba5b9 830 strncpy(tmp, (const char *)in, n);
2127e193 831 else
cfbba5b9 832 swapbytes(tmp, (const char *)in, n);
2127e193
GI
833 tmp[n] = '\0';
834 trim(out, tmp);
832b75ed
GG
835}
836
837// returns -1 if command fails or the device is in Sleep mode, else
838// value of Sector Count register. Sector Count result values:
839// 00h device is in Standby mode.
840// 80h device is in Idle mode.
841// FFh device is in Active mode or Idle mode.
842
2127e193 843int ataCheckPowerMode(ata_device * device) {
832b75ed
GG
844 unsigned char result;
845
846 if ((smartcommandhandler(device, CHECK_POWER_MODE, 0, (char *)&result)))
847 return -1;
848
849 if (result!=0 && result!=0x80 && result!=0xff)
850 pout("ataCheckPowerMode(): ATA CHECK POWER MODE returned unknown Sector Count Register value %02x\n", result);
851
852 return (int)result;
853}
854
d008864d
GI
855// Issue a no-data ATA command with optional sector count register value
856bool ata_nodata_command(ata_device * device, unsigned char command,
857 int sector_count /* = -1 */)
858{
859 ata_cmd_in in;
860 in.in_regs.command = command;
861 if (sector_count >= 0)
862 in.in_regs.sector_count = sector_count;
863
864 return device->ata_pass_through(in);
865}
866
867// Issue SET FEATURES command with optional sector count register value
868bool ata_set_features(ata_device * device, unsigned char features,
869 int sector_count /* = -1 */)
870{
871 ata_cmd_in in;
872 in.in_regs.command = ATA_SET_FEATURES;
873 in.in_regs.features = features;
874 if (sector_count >= 0)
875 in.in_regs.sector_count = sector_count;
876
877 return device->ata_pass_through(in);
878}
879
832b75ed
GG
880// Reads current Device Identity info (512 bytes) into buf. Returns 0
881// if all OK. Returns -1 if no ATA Device identity can be
882// established. Returns >0 if Device is ATA Packet Device (not SMART
883// capable). The value of the integer helps identify the type of
884// Packet device, which is useful so that the user can connect the
885// formal device number with whatever object is inside their computer.
cfbba5b9
GI
886int ata_read_identity(ata_device * device, ata_identify_device * buf, bool fix_swapped_id)
887{
832b75ed
GG
888 unsigned short *rawshort=(unsigned short *)buf;
889 unsigned char *rawbyte =(unsigned char *)buf;
890
891 // See if device responds either to IDENTIFY DEVICE or IDENTIFY
892 // PACKET DEVICE
cfbba5b9 893 bool packet = false;
832b75ed
GG
894 if ((smartcommandhandler(device, IDENTIFY, 0, (char *)buf))){
895 if (smartcommandhandler(device, PIDENTIFY, 0, (char *)buf)){
896 return -1;
897 }
cfbba5b9
GI
898 packet = true;
899 }
900
901 unsigned i;
902 if (fix_swapped_id) {
903 // Swap ID strings
904 for (i = 0; i < sizeof(buf->serial_no)-1; i += 2)
905 swap2((char *)(buf->serial_no+i));
906 for (i = 0; i < sizeof(buf->fw_rev)-1; i += 2)
907 swap2((char *)(buf->fw_rev+i));
908 for (i = 0; i < sizeof(buf->model)-1; i += 2)
909 swap2((char *)(buf->model+i));
832b75ed
GG
910 }
911
912#ifndef __NetBSD__
913 // if machine is big-endian, swap byte order as needed
a37e7145 914 // NetBSD kernel delivers IDENTIFY data in host byte order
cfbba5b9 915 // TODO: Handle NetBSD case in os_netbsd.cpp
832b75ed 916 if (isbigendian()){
832b75ed
GG
917
918 // swap various capability words that are needed
919 for (i=0; i<33; i++)
920 swap2((char *)(buf->words047_079+i));
921
922 for (i=80; i<=87; i++)
923 swap2((char *)(rawshort+i));
924
925 for (i=0; i<168; i++)
926 swap2((char *)(buf->words088_255+i));
927 }
928#endif
929
930 // If there is a checksum there, validate it
931 if ((rawshort[255] & 0x00ff) == 0x00a5 && checksum(rawbyte))
932 checksumwarning("Drive Identity Structure");
cfbba5b9
GI
933
934 // AT Attachment 8 - ATA/ATAPI Command Set (ATA8-ACS)
935 // T13/1699-D Revision 6a (Final Draft), September 6, 2008.
936 // Sections 7.16.7 and 7.17.6:
937 //
938 // Word 0 of IDENTIFY DEVICE data:
939 // Bit 15 = 0 : ATA device
940 //
941 // Word 0 of IDENTIFY PACKET DEVICE data:
942 // Bits 15:14 = 10b : ATAPI device
943 // Bits 15:14 = 11b : Reserved
944 // Bits 12:8 : Device type (SPC-4, e.g 0x05 = CD/DVD)
945
946 // CF+ and CompactFlash Specification Revision 4.0, May 24, 2006.
947 // Section 6.2.1.6:
948 //
949 // Word 0 of IDENTIFY DEVICE data:
950 // 848Ah = Signature for CompactFlash Storage Card
951 // 044Ah = Alternate value turns on ATA device while preserving all retired bits
952 // 0040h = Alternate value turns on ATA device while zeroing all retired bits
953
954 // Assume ATA if IDENTIFY DEVICE returns CompactFlash Signature
955 if (!packet && rawbyte[1] == 0x84 && rawbyte[0] == 0x8a)
956 return 0;
957
832b75ed
GG
958 // If this is a PACKET DEVICE, return device type
959 if (rawbyte[1] & 0x80)
960 return 1+(rawbyte[1] & 0x1f);
961
962 // Not a PACKET DEVICE
963 return 0;
964}
965
966// Returns ATA version as an integer, and a pointer to a string
967// describing which revision. Note that Revision 0 of ATA-3 does NOT
968// support SMART. For this one case we return -3 rather than +3 as
969// the version number. See notes above.
2127e193
GI
970int ataVersionInfo(const char ** description, const ata_identify_device * drive, unsigned short * minor)
971{
832b75ed 972 // get major and minor ATA revision numbers
2127e193 973 unsigned short major = drive->major_rev_num;
832b75ed
GG
974 *minor=drive->minor_rev_num;
975
976 // First check if device has ANY ATA version information in it
977 if (major==NOVAL_0 || major==NOVAL_1) {
978 *description=NULL;
a23d5117 979 return 0; // No info found
832b75ed
GG
980 }
981
982 // The minor revision number has more information - try there first
983 if (*minor && (*minor<=MINOR_MAX)){
984 int std = actual_ver[*minor];
985 if (std) {
986 *description=minor_str[*minor];
987 return std;
988 }
989 }
a37e7145 990
cfbba5b9
GI
991 // Try new ATA-8 ACS minor revision numbers.
992 // Table 55 of T13/2015-D Revision 4a (ACS-2), December 9, 2010.
a37e7145
GG
993 // (not in actual_ver/minor_str to avoid large sparse tables)
994 const char *desc;
995 switch (*minor) {
996 case 0x0027: desc = "ATA-8-ACS revision 3c"; break;
2127e193 997 case 0x0028: desc = "ATA-8-ACS revision 6"; break;
a37e7145 998 case 0x0029: desc = "ATA-8-ACS revision 4"; break;
cfbba5b9 999 case 0x0031: desc = "ACS-2 revision 2"; break;
a37e7145 1000 case 0x0033: desc = "ATA-8-ACS revision 3e"; break;
1953ff6d 1001 case 0x0039: desc = "ATA-8-ACS revision 4c"; break;
a37e7145
GG
1002 case 0x0042: desc = "ATA-8-ACS revision 3f"; break;
1003 case 0x0052: desc = "ATA-8-ACS revision 3b"; break;
1004 case 0x0107: desc = "ATA-8-ACS revision 2d"; break;
cfbba5b9 1005 case 0x0110: desc = "ACS-2 revision 3"; break;
a37e7145
GG
1006 default: desc = 0; break;
1007 }
1008 if (desc) {
1009 *description = desc;
1010 return 8;
1011 }
1012
832b75ed
GG
1013 // HDPARM has a very complicated algorithm from here on. Since SMART only
1014 // exists on ATA-3 and later standards, let's punt on this. If you don't
1015 // like it, please fix it. The code's in CVS.
2127e193 1016 int i;
832b75ed
GG
1017 for (i=15; i>0; i--)
1018 if (major & (0x1<<i))
1019 break;
1020
1021 *description=NULL;
1022 if (i==0)
1023 return 1;
1024 else
1025 return i;
1026}
1027
a7e8ffec
GI
1028// Get World Wide Name (WWN) fields.
1029// Return NAA field or -1 if WWN is unsupported.
1030// Table 34 of T13/1699-D Revision 6a (ATA8-ACS), September 6, 2008.
1031// (WWN was introduced in ATA/ATAPI-7 and is mandatory since ATA8-ACS Revision 3b)
1032int ata_get_wwn(const ata_identify_device * id, unsigned & oui, uint64_t & unique_id)
1033{
1034 // Don't use word 84 to be compatible with some older ATA-7 disks
1035 unsigned short word087 = id->csf_default;
1036 if ((word087 & 0xc100) != 0x4100)
1037 return -1; // word not valid or WWN support bit 8 not set
1038
1039 unsigned short word108 = id->words088_255[108-88];
1040 unsigned short word109 = id->words088_255[109-88];
1041 unsigned short word110 = id->words088_255[110-88];
1042 unsigned short word111 = id->words088_255[111-88];
1043
1044 oui = ((word108 & 0x0fff) << 12) | (word109 >> 4);
1045 unique_id = ((uint64_t)(word109 & 0xf) << 32)
1046 | (unsigned)((word110 << 16) | word111);
1047 return (word108 >> 12);
1048}
1049
832b75ed 1050// returns 1 if SMART supported, 0 if SMART unsupported, -1 if can't tell
2127e193
GI
1051int ataSmartSupport(const ata_identify_device * drive)
1052{
832b75ed
GG
1053 unsigned short word82=drive->command_set_1;
1054 unsigned short word83=drive->command_set_2;
1055
1056 // check if words 82/83 contain valid info
1057 if ((word83>>14) == 0x01)
1058 // return value of SMART support bit
1059 return word82 & 0x0001;
1060
1061 // since we can're rely on word 82, we don't know if SMART supported
1062 return -1;
1063}
1064
1065// returns 1 if SMART enabled, 0 if SMART disabled, -1 if can't tell
2127e193
GI
1066int ataIsSmartEnabled(const ata_identify_device * drive)
1067{
832b75ed
GG
1068 unsigned short word85=drive->cfs_enable_1;
1069 unsigned short word87=drive->csf_default;
1070
1071 // check if words 85/86/87 contain valid info
1072 if ((word87>>14) == 0x01)
1073 // return value of SMART enabled bit
1074 return word85 & 0x0001;
1075
1076 // Since we can't rely word85, we don't know if SMART is enabled.
1077 return -1;
1078}
1079
1080
1081// Reads SMART attributes into *data
2127e193 1082int ataReadSmartValues(ata_device * device, struct ata_smart_values *data){
832b75ed
GG
1083
1084 if (smartcommandhandler(device, READ_VALUES, 0, (char *)data)){
a7e8ffec 1085 pout("Error SMART Values Read failed: %s\n", device->get_errmsg());
832b75ed
GG
1086 return -1;
1087 }
1088
1089 // compute checksum
2127e193 1090 if (checksum(data))
832b75ed
GG
1091 checksumwarning("SMART Attribute Data Structure");
1092
a37e7145 1093 // swap endian order if needed
832b75ed
GG
1094 if (isbigendian()){
1095 int i;
1096 swap2((char *)&(data->revnumber));
1097 swap2((char *)&(data->total_time_to_complete_off_line));
1098 swap2((char *)&(data->smart_capability));
d008864d 1099 swapx(&data->extend_test_completion_time_w);
832b75ed
GG
1100 for (i=0; i<NUMBER_ATA_SMART_ATTRIBUTES; i++){
1101 struct ata_smart_attribute *x=data->vendor_attributes+i;
1102 swap2((char *)&(x->flags));
1103 }
1104 }
1105
1106 return 0;
1107}
1108
1109
1110// This corrects some quantities that are byte reversed in the SMART
1111// SELF TEST LOG
2127e193
GI
1112static void fixsamsungselftestlog(ata_smart_selftestlog * data)
1113{
832b75ed
GG
1114 // bytes 508/509 (numbered from 0) swapped (swap of self-test index
1115 // with one byte of reserved.
1116 swap2((char *)&(data->mostrecenttest));
1117
1118 // LBA low register (here called 'selftestnumber", containing
1119 // information about the TYPE of the self-test) is byte swapped with
1120 // Self-test execution status byte. These are bytes N, N+1 in the
1121 // entries.
2127e193 1122 for (int i = 0; i < 21; i++)
832b75ed
GG
1123 swap2((char *)&(data->selftest_struct[i].selftestnumber));
1124
1125 return;
1126}
1127
1128// Reads the Self Test Log (log #6)
2127e193
GI
1129int ataReadSelfTestLog (ata_device * device, ata_smart_selftestlog * data,
1130 unsigned char fix_firmwarebug)
1131{
832b75ed
GG
1132
1133 // get data from device
1134 if (smartcommandhandler(device, READ_LOG, 0x06, (char *)data)){
a7e8ffec 1135 pout("Error SMART Error Self-Test Log Read failed: %s\n", device->get_errmsg());
832b75ed
GG
1136 return -1;
1137 }
1138
1139 // compute its checksum, and issue a warning if needed
2127e193 1140 if (checksum(data))
832b75ed
GG
1141 checksumwarning("SMART Self-Test Log Structure");
1142
1143 // fix firmware bugs in self-test log
2127e193 1144 if (fix_firmwarebug == FIX_SAMSUNG)
832b75ed
GG
1145 fixsamsungselftestlog(data);
1146
a37e7145 1147 // swap endian order if needed
832b75ed
GG
1148 if (isbigendian()){
1149 int i;
1150 swap2((char*)&(data->revnumber));
1151 for (i=0; i<21; i++){
1152 struct ata_smart_selftestlog_struct *x=data->selftest_struct+i;
1153 swap2((char *)&(x->timestamp));
1154 swap4((char *)&(x->lbafirstfailure));
1155 }
1156 }
1157
1158 return 0;
1159}
1160
2127e193
GI
1161// Print checksum warning for multi sector log
1162static void check_multi_sector_sum(const void * data, unsigned nsectors, const char * msg)
1163{
1164 unsigned errs = 0;
1165 for (unsigned i = 0; i < nsectors; i++) {
1166 if (checksum((const unsigned char *)data + i*512))
1167 errs++;
1168 }
1169 if (errs > 0) {
1170 if (nsectors == 1)
1171 checksumwarning(msg);
1172 else
1173 checksumwarning(strprintf("%s (%u/%u)", msg, errs, nsectors).c_str());
1174 }
1175}
832b75ed 1176
2127e193
GI
1177// Read SMART Extended Self-test Log
1178bool ataReadExtSelfTestLog(ata_device * device, ata_smart_extselftestlog * log,
1179 unsigned nsectors)
1180{
1181 if (!ataReadLogExt(device, 0x07, 0x00, 0, log, nsectors))
1182 return false;
1183
1184 check_multi_sector_sum(log, nsectors, "SMART Extended Self-test Log Structure");
1185
1186 if (isbigendian()) {
1187 swapx(&log->log_desc_index);
1188 for (unsigned i = 0; i < nsectors; i++) {
1189 for (unsigned j = 0; j < 19; j++)
1190 swapx(&log->log_descs[i].timestamp);
1191 }
832b75ed 1192 }
2127e193
GI
1193 return true;
1194}
832b75ed 1195
2127e193
GI
1196
1197// Read GP Log page(s)
1198bool ataReadLogExt(ata_device * device, unsigned char logaddr,
1199 unsigned char features, unsigned page,
1200 void * data, unsigned nsectors)
1201{
1202 ata_cmd_in in;
1203 in.in_regs.command = ATA_READ_LOG_EXT;
1204 in.in_regs.features = features; // log specific
1205 in.set_data_in_48bit(data, nsectors);
1206 in.in_regs.lba_low = logaddr;
1207 in.in_regs.lba_mid_16 = page;
1208
1209 if (!device->ata_pass_through(in)) { // TODO: Debug output
1210 if (nsectors <= 1) {
1211 pout("ATA_READ_LOG_EXT (addr=0x%02x:0x%02x, page=%u, n=%u) failed: %s\n",
1212 logaddr, features, page, nsectors, device->get_errmsg());
1213 return false;
1214 }
1215
1216 // Recurse to retry with single sectors,
1217 // multi-sector reads may not be supported by ioctl.
1218 for (unsigned i = 0; i < nsectors; i++) {
1219 if (!ataReadLogExt(device, logaddr,
1220 features, page + i,
1221 (char *)data + 512*i, 1))
1222 return false;
1223 }
832b75ed 1224 }
2127e193
GI
1225
1226 return true;
1227}
1228
1229// Read SMART Log page(s)
1230bool ataReadSmartLog(ata_device * device, unsigned char logaddr,
1231 void * data, unsigned nsectors)
1232{
1233 ata_cmd_in in;
1234 in.in_regs.command = ATA_SMART_CMD;
1235 in.in_regs.features = ATA_SMART_READ_LOG_SECTOR;
1236 in.set_data_in(data, nsectors);
1237 in.in_regs.lba_high = SMART_CYL_HI;
1238 in.in_regs.lba_mid = SMART_CYL_LOW;
1239 in.in_regs.lba_low = logaddr;
1240
1241 if (!device->ata_pass_through(in)) { // TODO: Debug output
1242 pout("ATA_SMART_READ_LOG failed: %s\n", device->get_errmsg());
1243 return false;
1244 }
1245 return true;
1246}
1247
1248
1249
1250// Reads the SMART or GPL Log Directory (log #0)
1251int ataReadLogDirectory(ata_device * device, ata_smart_log_directory * data, bool gpl)
1252{
1253 if (!gpl) { // SMART Log directory
1254 if (smartcommandhandler(device, READ_LOG, 0x00, (char *)data))
1255 return -1;
1256 }
1257 else { // GP Log directory
1258 if (!ataReadLogExt(device, 0x00, 0x00, 0, data, 1))
1259 return -1;
1260 }
1261
1262 // swap endian order if needed
1263 if (isbigendian())
1264 swapx(&data->logversion);
1265
832b75ed
GG
1266 return 0;
1267}
1268
1269
1270// Reads the selective self-test log (log #9)
2127e193 1271int ataReadSelectiveSelfTestLog(ata_device * device, struct ata_selective_self_test_log *data){
832b75ed
GG
1272
1273 // get data from device
1274 if (smartcommandhandler(device, READ_LOG, 0x09, (char *)data)){
a7e8ffec 1275 pout("Error SMART Read Selective Self-Test Log failed: %s\n", device->get_errmsg());
832b75ed
GG
1276 return -1;
1277 }
1278
1279 // compute its checksum, and issue a warning if needed
2127e193 1280 if (checksum(data))
832b75ed
GG
1281 checksumwarning("SMART Selective Self-Test Log Structure");
1282
1283 // swap endian order if needed
1284 if (isbigendian()){
1285 int i;
1286 swap2((char *)&(data->logversion));
1287 for (i=0;i<5;i++){
1288 swap8((char *)&(data->span[i].start));
1289 swap8((char *)&(data->span[i].end));
1290 }
1291 swap8((char *)&(data->currentlba));
1292 swap2((char *)&(data->currentspan));
1293 swap2((char *)&(data->flags));
1294 swap2((char *)&(data->pendingtime));
1295 }
1296
1297 if (data->logversion != 1)
2127e193 1298 pout("Note: selective self-test log revision number (%d) not 1 implies that no selective self-test has ever been run\n", data->logversion);
832b75ed
GG
1299
1300 return 0;
1301}
1302
1303// Writes the selective self-test log (log #9)
2127e193 1304int ataWriteSelectiveSelfTestLog(ata_device * device, ata_selective_selftest_args & args,
cfbba5b9
GI
1305 const ata_smart_values * sv, uint64_t num_sectors,
1306 const ata_selective_selftest_args * prev_args)
2127e193 1307{
a37e7145
GG
1308 // Disk size must be known
1309 if (!num_sectors) {
1310 pout("Disk size is unknown, unable to check selective self-test spans\n");
1311 return -1;
1312 }
1313
1314 // Read log
832b75ed 1315 struct ata_selective_self_test_log sstlog, *data=&sstlog;
832b75ed 1316 unsigned char *ptr=(unsigned char *)data;
832b75ed
GG
1317 if (ataReadSelectiveSelfTestLog(device, data)) {
1318 pout("Since Read failed, will not attempt to WRITE Selective Self-test Log\n");
1319 return -1;
1320 }
1321
2127e193
GI
1322 // Set log version
1323 data->logversion = 1;
832b75ed
GG
1324
1325 // Host is NOT allowed to write selective self-test log if a selective
1326 // self-test is in progress.
1327 if (0<data->currentspan && data->currentspan<6 && ((sv->self_test_exec_status)>>4)==15) {
1328 pout("Error SMART Selective or other Self-Test in progress.\n");
1329 return -4;
1330 }
a37e7145
GG
1331
1332 // Set start/end values based on old spans for special -t select,... options
1333 int i;
2127e193
GI
1334 for (i = 0; i < args.num_spans; i++) {
1335 int mode = args.span[i].mode;
1336 uint64_t start = args.span[i].start;
1337 uint64_t end = args.span[i].end;
a37e7145
GG
1338 if (mode == SEL_CONT) {// redo or next dependig on last test status
1339 switch (sv->self_test_exec_status >> 4) {
1340 case 1: case 2: // Aborted/Interrupted by host
1341 pout("Continue Selective Self-Test: Redo last span\n");
1342 mode = SEL_REDO;
1343 break;
1344 default: // All others
1345 pout("Continue Selective Self-Test: Start next span\n");
1346 mode = SEL_NEXT;
1347 break;
1348 }
1349 }
cfbba5b9
GI
1350
1351 if ( (mode == SEL_REDO || mode == SEL_NEXT)
1352 && prev_args && i < prev_args->num_spans
1353 && !data->span[i].start && !data->span[i].end) {
1354 // Some drives do not preserve the selective self-test log accross
1355 // power-cyles. If old span on drive is cleared use span provided
1356 // by caller. This is used by smartd (first span only).
1357 data->span[i].start = prev_args->span[i].start;
1358 data->span[i].end = prev_args->span[i].end;
1359 }
1360
a37e7145
GG
1361 switch (mode) {
1362 case SEL_RANGE: // -t select,START-END
1363 break;
1364 case SEL_REDO: // -t select,redo... => Redo current
1365 start = data->span[i].start;
1366 if (end > 0) { // -t select,redo+SIZE
1367 end--; end += start; // [oldstart, oldstart+SIZE)
1368 }
1369 else // -t select,redo
1370 end = data->span[i].end; // [oldstart, oldend]
1371 break;
1372 case SEL_NEXT: // -t select,next... => Do next
1373 if (data->span[i].end == 0) {
1374 start = end = 0; break; // skip empty spans
1375 }
1376 start = data->span[i].end + 1;
1377 if (start >= num_sectors)
1378 start = 0; // wrap around
1379 if (end > 0) { // -t select,next+SIZE
1380 end--; end += start; // (oldend, oldend+SIZE]
1381 }
1382 else { // -t select,next
1383 uint64_t oldsize = data->span[i].end - data->span[i].start + 1;
1384 end = start + oldsize - 1; // (oldend, oldend+oldsize]
1385 if (end >= num_sectors) {
1386 // Adjust size to allow round-robin testing without future size decrease
1387 uint64_t spans = (num_sectors + oldsize-1) / oldsize;
1388 uint64_t newsize = (num_sectors + spans-1) / spans;
1389 uint64_t newstart = num_sectors - newsize, newend = num_sectors - 1;
2127e193
GI
1390 pout("Span %d changed from %"PRIu64"-%"PRIu64" (%"PRIu64" sectors)\n",
1391 i, start, end, oldsize);
1392 pout(" to %"PRIu64"-%"PRIu64" (%"PRIu64" sectors) (%"PRIu64" spans)\n",
1393 newstart, newend, newsize, spans);
a37e7145
GG
1394 start = newstart; end = newend;
1395 }
1396 }
1397 break;
1398 default:
1399 pout("ataWriteSelectiveSelfTestLog: Invalid mode %d\n", mode);
1400 return -1;
1401 }
1402 // Range check
1403 if (start < num_sectors && num_sectors <= end) {
1404 if (end != ~(uint64_t)0) // -t select,N-max
1405 pout("Size of self-test span %d decreased according to disk size\n", i);
1406 end = num_sectors - 1;
1407 }
1408 if (!(start <= end && end < num_sectors)) {
1409 pout("Invalid selective self-test span %d: %"PRIu64"-%"PRIu64" (%"PRIu64" sectors)\n",
1410 i, start, end, num_sectors);
1411 return -1;
1412 }
2127e193
GI
1413 // Return the actual mode and range to caller.
1414 args.span[i].mode = mode;
1415 args.span[i].start = start;
1416 args.span[i].end = end;
a37e7145
GG
1417 }
1418
832b75ed
GG
1419 // Clear spans
1420 for (i=0; i<5; i++)
1421 memset(data->span+i, 0, sizeof(struct test_span));
1422
1423 // Set spans for testing
2127e193
GI
1424 for (i = 0; i < args.num_spans; i++){
1425 data->span[i].start = args.span[i].start;
1426 data->span[i].end = args.span[i].end;
832b75ed
GG
1427 }
1428
1429 // host must initialize to zero before initiating selective self-test
1430 data->currentlba=0;
1431 data->currentspan=0;
1432
1433 // Perform off-line scan after selective test?
2127e193 1434 if (args.scan_after_select == 1)
832b75ed
GG
1435 // NO
1436 data->flags &= ~SELECTIVE_FLAG_DOSCAN;
2127e193 1437 else if (args.scan_after_select == 2)
832b75ed
GG
1438 // YES
1439 data->flags |= SELECTIVE_FLAG_DOSCAN;
1440
1441 // Must clear active and pending flags before writing
1442 data->flags &= ~(SELECTIVE_FLAG_ACTIVE);
1443 data->flags &= ~(SELECTIVE_FLAG_PENDING);
1444
1445 // modify pending time?
2127e193
GI
1446 if (args.pending_time)
1447 data->pendingtime = (unsigned short)(args.pending_time-1);
832b75ed
GG
1448
1449 // Set checksum to zero, then compute checksum
1450 data->checksum=0;
a37e7145 1451 unsigned char cksum=0;
832b75ed
GG
1452 for (i=0; i<512; i++)
1453 cksum+=ptr[i];
1454 cksum=~cksum;
1455 cksum+=1;
1456 data->checksum=cksum;
1457
a37e7145 1458 // swap endian order if needed
832b75ed 1459 if (isbigendian()){
832b75ed 1460 swap2((char *)&(data->logversion));
cfbba5b9
GI
1461 for (int b = 0; b < 5; b++) {
1462 swap8((char *)&(data->span[b].start));
1463 swap8((char *)&(data->span[b].end));
832b75ed
GG
1464 }
1465 swap8((char *)&(data->currentlba));
1466 swap2((char *)&(data->currentspan));
1467 swap2((char *)&(data->flags));
1468 swap2((char *)&(data->pendingtime));
1469 }
1470
1471 // write new selective self-test log
1472 if (smartcommandhandler(device, WRITE_LOG, 0x09, (char *)data)){
a7e8ffec 1473 pout("Error Write Selective Self-Test Log failed: %s\n", device->get_errmsg());
832b75ed
GG
1474 return -3;
1475 }
1476
1477 return 0;
1478}
1479
1480// This corrects some quantities that are byte reversed in the SMART
1481// ATA ERROR LOG.
2127e193
GI
1482static void fixsamsungerrorlog(ata_smart_errorlog * data)
1483{
832b75ed
GG
1484 // FIXED IN SAMSUNG -25 FIRMWARE???
1485 // Device error count in bytes 452-3
1486 swap2((char *)&(data->ata_error_count));
1487
1488 // FIXED IN SAMSUNG -22a FIRMWARE
1489 // step through 5 error log data structures
2127e193 1490 for (int i = 0; i < 5; i++){
832b75ed 1491 // step through 5 command data structures
2127e193 1492 for (int j = 0; j < 5; j++)
832b75ed
GG
1493 // Command data structure 4-byte millisec timestamp. These are
1494 // bytes (N+8, N+9, N+10, N+11).
1495 swap4((char *)&(data->errorlog_struct[i].commands[j].timestamp));
1496 // Error data structure two-byte hour life timestamp. These are
1497 // bytes (N+28, N+29).
1498 swap2((char *)&(data->errorlog_struct[i].error_struct.timestamp));
1499 }
1500 return;
1501}
1502
1503// NEEDED ONLY FOR SAMSUNG -22 (some) -23 AND -24?? FIRMWARE
2127e193
GI
1504static void fixsamsungerrorlog2(ata_smart_errorlog * data)
1505{
832b75ed
GG
1506 // Device error count in bytes 452-3
1507 swap2((char *)&(data->ata_error_count));
1508 return;
1509}
1510
1511// Reads the Summary SMART Error Log (log #1). The Comprehensive SMART
1512// Error Log is #2, and the Extended Comprehensive SMART Error log is
1513// #3
2127e193
GI
1514int ataReadErrorLog (ata_device * device, ata_smart_errorlog *data,
1515 unsigned char fix_firmwarebug)
1516{
832b75ed
GG
1517
1518 // get data from device
1519 if (smartcommandhandler(device, READ_LOG, 0x01, (char *)data)){
a7e8ffec 1520 pout("Error SMART Error Log Read failed: %s\n", device->get_errmsg());
832b75ed
GG
1521 return -1;
1522 }
1523
1524 // compute its checksum, and issue a warning if needed
2127e193 1525 if (checksum(data))
832b75ed
GG
1526 checksumwarning("SMART ATA Error Log Structure");
1527
1528 // Some disks have the byte order reversed in some SMART Summary
1529 // Error log entries
2127e193 1530 if (fix_firmwarebug == FIX_SAMSUNG)
832b75ed 1531 fixsamsungerrorlog(data);
2127e193 1532 else if (fix_firmwarebug == FIX_SAMSUNG2)
832b75ed
GG
1533 fixsamsungerrorlog2(data);
1534
a37e7145 1535 // swap endian order if needed
832b75ed
GG
1536 if (isbigendian()){
1537 int i,j;
1538
1539 // Device error count in bytes 452-3
1540 swap2((char *)&(data->ata_error_count));
1541
1542 // step through 5 error log data structures
1543 for (i=0; i<5; i++){
1544 // step through 5 command data structures
1545 for (j=0; j<5; j++)
1546 // Command data structure 4-byte millisec timestamp
1547 swap4((char *)&(data->errorlog_struct[i].commands[j].timestamp));
1548 // Error data structure life timestamp
1549 swap2((char *)&(data->errorlog_struct[i].error_struct.timestamp));
1550 }
1551 }
1552
1553 return 0;
1554}
1555
2127e193
GI
1556// Read Extended Comprehensive Error Log
1557bool ataReadExtErrorLog(ata_device * device, ata_smart_exterrlog * log,
1558 unsigned nsectors)
1559{
1560 if (!ataReadLogExt(device, 0x03, 0x00, 0, log, nsectors))
1561 return false;
1562
1563 check_multi_sector_sum(log, nsectors, "SMART Extended Comprehensive Error Log Structure");
1564
1565 if (isbigendian()) {
1566 swapx(&log->device_error_count);
1567 swapx(&log->error_log_index);
1568
1569 for (unsigned i = 0; i < nsectors; i++) {
1570 for (unsigned j = 0; j < 4; j++)
1571 swapx(&log->error_logs[i].commands[j].timestamp);
1572 swapx(&log->error_logs[i].error.timestamp);
1573 }
1574 }
1575
1576 return true;
1577}
1578
1579
1580int ataReadSmartThresholds (ata_device * device, struct ata_smart_thresholds_pvt *data){
832b75ed
GG
1581
1582 // get data from device
1583 if (smartcommandhandler(device, READ_THRESHOLDS, 0, (char *)data)){
a7e8ffec 1584 pout("Error SMART Thresholds Read failed: %s\n", device->get_errmsg());
832b75ed
GG
1585 return -1;
1586 }
1587
1588 // compute its checksum, and issue a warning if needed
2127e193 1589 if (checksum(data))
832b75ed
GG
1590 checksumwarning("SMART Attribute Thresholds Structure");
1591
a37e7145 1592 // swap endian order if needed
832b75ed
GG
1593 if (isbigendian())
1594 swap2((char *)&(data->revnumber));
1595
1596 return 0;
1597}
1598
2127e193 1599int ataEnableSmart (ata_device * device ){
832b75ed 1600 if (smartcommandhandler(device, ENABLE, 0, NULL)){
a7e8ffec 1601 pout("Error SMART Enable failed: %s\n", device->get_errmsg());
832b75ed
GG
1602 return -1;
1603 }
1604 return 0;
1605}
1606
2127e193 1607int ataDisableSmart (ata_device * device ){
832b75ed
GG
1608
1609 if (smartcommandhandler(device, DISABLE, 0, NULL)){
a7e8ffec 1610 pout("Error SMART Disable failed: %s\n", device->get_errmsg());
832b75ed
GG
1611 return -1;
1612 }
1613 return 0;
1614}
1615
2127e193 1616int ataEnableAutoSave(ata_device * device){
832b75ed 1617 if (smartcommandhandler(device, AUTOSAVE, 241, NULL)){
a7e8ffec 1618 pout("Error SMART Enable Auto-save failed: %s\n", device->get_errmsg());
832b75ed
GG
1619 return -1;
1620 }
1621 return 0;
1622}
1623
2127e193 1624int ataDisableAutoSave(ata_device * device){
832b75ed
GG
1625
1626 if (smartcommandhandler(device, AUTOSAVE, 0, NULL)){
a7e8ffec 1627 pout("Error SMART Disable Auto-save failed: %s\n", device->get_errmsg());
832b75ed
GG
1628 return -1;
1629 }
1630 return 0;
1631}
1632
1633// In *ALL* ATA standards the Enable/Disable AutoOffline command is
1634// marked "OBSOLETE". It is defined in SFF-8035i Revision 2, and most
1635// vendors still support it for backwards compatibility. IBM documents
1636// it for some drives.
2127e193 1637int ataEnableAutoOffline (ata_device * device){
832b75ed
GG
1638
1639 /* timer hard coded to 4 hours */
1640 if (smartcommandhandler(device, AUTO_OFFLINE, 248, NULL)){
a7e8ffec 1641 pout("Error SMART Enable Automatic Offline failed: %s\n", device->get_errmsg());
832b75ed
GG
1642 return -1;
1643 }
1644 return 0;
1645}
1646
1647// Another Obsolete Command. See comments directly above, associated
1648// with the corresponding Enable command.
2127e193 1649int ataDisableAutoOffline (ata_device * device){
832b75ed
GG
1650
1651 if (smartcommandhandler(device, AUTO_OFFLINE, 0, NULL)){
a7e8ffec 1652 pout("Error SMART Disable Automatic Offline failed: %s\n", device->get_errmsg());
832b75ed
GG
1653 return -1;
1654 }
1655 return 0;
1656}
1657
1658// If SMART is enabled, supported, and working, then this call is
1659// guaranteed to return 1, else zero. Note that it should return 1
1660// regardless of whether the disk's SMART status is 'healthy' or
1661// 'failing'.
2127e193 1662int ataDoesSmartWork(ata_device * device){
832b75ed
GG
1663 int retval=smartcommandhandler(device, STATUS, 0, NULL);
1664
1665 if (-1 == retval)
1666 return 0;
1667
1668 return 1;
1669}
1670
1671// This function uses a different interface (DRIVE_TASK) than the
1672// other commands in this file.
2127e193 1673int ataSmartStatus2(ata_device * device){
832b75ed
GG
1674 return smartcommandhandler(device, STATUS_CHECK, 0, NULL);
1675}
1676
1677// This is the way to execute ALL tests: offline, short self-test,
1678// extended self test, with and without captive mode, etc.
2127e193 1679// TODO: Move to ataprint.cpp ?
d008864d
GI
1680int ataSmartTest(ata_device * device, int testtype, bool force,
1681 const ata_selective_selftest_args & selargs,
2127e193 1682 const ata_smart_values * sv, uint64_t num_sectors)
a37e7145 1683{
2127e193 1684 char cmdmsg[128]; const char *type, *captive;
a7e8ffec 1685 int cap, retval, select=0;
832b75ed
GG
1686
1687 // Boolean, if set, says test is captive
1688 cap=testtype & CAPTIVE_MASK;
1689
1690 // Set up strings that describe the type of test
1691 if (cap)
1692 captive="captive";
1693 else
1694 captive="off-line";
1695
1696 if (testtype==OFFLINE_FULL_SCAN)
1697 type="off-line";
1698 else if (testtype==SHORT_SELF_TEST || testtype==SHORT_CAPTIVE_SELF_TEST)
1699 type="Short self-test";
1700 else if (testtype==EXTEND_SELF_TEST || testtype==EXTEND_CAPTIVE_SELF_TEST)
1701 type="Extended self-test";
1702 else if (testtype==CONVEYANCE_SELF_TEST || testtype==CONVEYANCE_CAPTIVE_SELF_TEST)
1703 type="Conveyance self-test";
1704 else if ((select=(testtype==SELECTIVE_SELF_TEST || testtype==SELECTIVE_CAPTIVE_SELF_TEST)))
1705 type="Selective self-test";
1706 else
cfbba5b9 1707 type = 0;
d008864d
GI
1708
1709 // Check whether another test is already running
1710 if (type && (sv->self_test_exec_status >> 4) == 0xf) {
1711 if (!force) {
1712 pout("Can't start self-test without aborting current test (%d0%% remaining),\n"
1713 "%srun 'smartctl -X' to abort test.\n",
1714 sv->self_test_exec_status & 0x0f,
1715 (!select ? "add '-t force' option to override, or " : ""));
1716 return -1;
1717 }
1718 }
1719 else
1720 force = false;
1721
832b75ed
GG
1722 // If doing a selective self-test, first use WRITE_LOG to write the
1723 // selective self-test log.
2127e193
GI
1724 ata_selective_selftest_args selargs_io = selargs; // filled with info about actual spans
1725 if (select && (retval = ataWriteSelectiveSelfTestLog(device, selargs_io, sv, num_sectors))) {
832b75ed
GG
1726 if (retval==-4)
1727 pout("Can't start selective self-test without aborting current test: use '-X' option to smartctl.\n");
1728 return retval;
1729 }
1730
1731 // Print ouf message that we are sending the command to test
1732 if (testtype==ABORT_SELF_TEST)
1733 sprintf(cmdmsg,"Abort SMART off-line mode self-test routine");
cfbba5b9
GI
1734 else if (!type)
1735 sprintf(cmdmsg, "SMART EXECUTE OFF-LINE IMMEDIATE subcommand 0x%02x", testtype);
832b75ed
GG
1736 else
1737 sprintf(cmdmsg,"Execute SMART %s routine immediately in %s mode",type,captive);
1738 pout("Sending command: \"%s\".\n",cmdmsg);
1739
1740 if (select) {
1741 int i;
1742 pout("SPAN STARTING_LBA ENDING_LBA\n");
2127e193 1743 for (i = 0; i < selargs_io.num_spans; i++)
832b75ed 1744 pout(" %d %20"PRId64" %20"PRId64"\n", i,
2127e193
GI
1745 selargs_io.span[i].start,
1746 selargs_io.span[i].end);
832b75ed
GG
1747 }
1748
1749 // Now send the command to test
a7e8ffec
GI
1750 if (smartcommandhandler(device, IMMEDIATE_OFFLINE, testtype, NULL)) {
1751 if (!(cap && device->get_errno() == EIO)) {
1752 pout("Command \"%s\" failed: %s\n", cmdmsg, device->get_errmsg());
1753 return -1;
1754 }
832b75ed
GG
1755 }
1756
1757 // Since the command succeeded, tell user
1758 if (testtype==ABORT_SELF_TEST)
1759 pout("Self-testing aborted!\n");
cfbba5b9
GI
1760 else {
1761 pout("Drive command \"%s\" successful.\n", cmdmsg);
1762 if (type)
d008864d 1763 pout("Testing has begun%s.\n", (force ? " (previous test aborted)" : ""));
cfbba5b9 1764 }
832b75ed
GG
1765 return 0;
1766}
1767
1768/* Test Time Functions */
2127e193
GI
1769int TestTime(const ata_smart_values *data, int testtype)
1770{
832b75ed
GG
1771 switch (testtype){
1772 case OFFLINE_FULL_SCAN:
1773 return (int) data->total_time_to_complete_off_line;
1774 case SHORT_SELF_TEST:
1775 case SHORT_CAPTIVE_SELF_TEST:
1776 return (int) data->short_test_completion_time;
1777 case EXTEND_SELF_TEST:
1778 case EXTEND_CAPTIVE_SELF_TEST:
d008864d
GI
1779 if (data->extend_test_completion_time_b == 0xff
1780 && data->extend_test_completion_time_w != 0x0000
1781 && data->extend_test_completion_time_w != 0xffff)
1782 return data->extend_test_completion_time_w; // ATA-8
1783 else
1784 return data->extend_test_completion_time_b;
832b75ed
GG
1785 case CONVEYANCE_SELF_TEST:
1786 case CONVEYANCE_CAPTIVE_SELF_TEST:
1787 return (int) data->conveyance_test_completion_time;
1788 default:
1789 return 0;
1790 }
1791}
1792
1793// This function tells you both about the ATA error log and the
1794// self-test error log capability (introduced in ATA-5). The bit is
1795// poorly documented in the ATA/ATAPI standard. Starting with ATA-6,
1796// SMART error logging is also indicated in bit 0 of DEVICE IDENTIFY
1797// word 84 and 87. Top two bits must match the pattern 01. BEFORE
1798// ATA-6 these top two bits still had to match the pattern 01, but the
1799// remaining bits were reserved (==0).
2127e193
GI
1800int isSmartErrorLogCapable (const ata_smart_values * data, const ata_identify_device * identity)
1801{
832b75ed
GG
1802 unsigned short word84=identity->command_set_extension;
1803 unsigned short word87=identity->csf_default;
1804 int isata6=identity->major_rev_num & (0x01<<6);
1805 int isata7=identity->major_rev_num & (0x01<<7);
1806
1807 if ((isata6 || isata7) && (word84>>14) == 0x01 && (word84 & 0x01))
1808 return 1;
1809
1810 if ((isata6 || isata7) && (word87>>14) == 0x01 && (word87 & 0x01))
1811 return 1;
1812
1813 // otherwise we'll use the poorly documented capability bit
1814 return data->errorlog_capability & 0x01;
1815}
1816
1817// See previous function. If the error log exists then the self-test
1818// log should (must?) also exist.
2127e193
GI
1819int isSmartTestLogCapable (const ata_smart_values * data, const ata_identify_device *identity)
1820{
832b75ed
GG
1821 unsigned short word84=identity->command_set_extension;
1822 unsigned short word87=identity->csf_default;
1823 int isata6=identity->major_rev_num & (0x01<<6);
1824 int isata7=identity->major_rev_num & (0x01<<7);
1825
1826 if ((isata6 || isata7) && (word84>>14) == 0x01 && (word84 & 0x02))
1827 return 1;
1828
1829 if ((isata6 || isata7) && (word87>>14) == 0x01 && (word87 & 0x02))
1830 return 1;
1831
1832
1833 // otherwise we'll use the poorly documented capability bit
2127e193 1834 return data->errorlog_capability & 0x01;
832b75ed
GG
1835}
1836
1837
2127e193
GI
1838int isGeneralPurposeLoggingCapable(const ata_identify_device *identity)
1839{
832b75ed
GG
1840 unsigned short word84=identity->command_set_extension;
1841 unsigned short word87=identity->csf_default;
1842
1843 // If bit 14 of word 84 is set to one and bit 15 of word 84 is
1844 // cleared to zero, the contents of word 84 contains valid support
1845 // information. If not, support information is not valid in this
1846 // word.
1847 if ((word84>>14) == 0x01)
1848 // If bit 5 of word 84 is set to one, the device supports the
1849 // General Purpose Logging feature set.
1850 return (word84 & (0x01 << 5));
1851
1852 // If bit 14 of word 87 is set to one and bit 15 of word 87 is
1853 // cleared to zero, the contents of words (87:85) contain valid
1854 // information. If not, information is not valid in these words.
1855 if ((word87>>14) == 0x01)
1856 // If bit 5 of word 87 is set to one, the device supports
1857 // the General Purpose Logging feature set.
1858 return (word87 & (0x01 << 5));
1859
1860 // not capable
1861 return 0;
1862}
1863
1864
1865// SMART self-test capability is also indicated in bit 1 of DEVICE
1866// IDENTIFY word 87 (if top two bits of word 87 match pattern 01).
1867// However this was only introduced in ATA-6 (but self-test log was in
1868// ATA-5).
2127e193
GI
1869int isSupportExecuteOfflineImmediate(const ata_smart_values *data)
1870{
1871 return data->offline_data_collection_capability & 0x01;
832b75ed 1872}
2127e193 1873
832b75ed
GG
1874// Note in the ATA-5 standard, the following bit is listed as "Vendor
1875// Specific". So it may not be reliable. The only use of this that I
1876// have found is in IBM drives, where it is well-documented. See for
1877// example page 170, section 13.32.1.18 of the IBM Travelstar 40GNX
1878// hard disk drive specifications page 164 Revision 1.1 22 Apr 2002.
2127e193
GI
1879int isSupportAutomaticTimer(const ata_smart_values * data)
1880{
1881 return data->offline_data_collection_capability & 0x02;
832b75ed 1882}
2127e193
GI
1883int isSupportOfflineAbort(const ata_smart_values *data)
1884{
1885 return data->offline_data_collection_capability & 0x04;
832b75ed 1886}
2127e193
GI
1887int isSupportOfflineSurfaceScan(const ata_smart_values * data)
1888{
832b75ed
GG
1889 return data->offline_data_collection_capability & 0x08;
1890}
2127e193
GI
1891int isSupportSelfTest (const ata_smart_values * data)
1892{
832b75ed
GG
1893 return data->offline_data_collection_capability & 0x10;
1894}
2127e193
GI
1895int isSupportConveyanceSelfTest(const ata_smart_values * data)
1896{
832b75ed
GG
1897 return data->offline_data_collection_capability & 0x20;
1898}
2127e193
GI
1899int isSupportSelectiveSelfTest(const ata_smart_values * data)
1900{
832b75ed
GG
1901 return data->offline_data_collection_capability & 0x40;
1902}
1903
bed94269
GI
1904// Get attribute state
1905ata_attr_state ata_get_attr_state(const ata_smart_attribute & attr,
cfbba5b9
GI
1906 int attridx,
1907 const ata_smart_threshold_entry * thresholds,
1908 const ata_vendor_attr_defs & defs,
1909 unsigned char * threshval /* = 0 */)
bed94269
GI
1910{
1911 if (!attr.id)
1912 return ATTRSTATE_NON_EXISTING;
832b75ed 1913
bed94269
GI
1914 // Normalized values (current,worst,threshold) not valid
1915 // if specified by '-v' option.
1916 // (Some SSD disks uses these bytes to store raw value).
1917 if (defs[attr.id].flags & ATTRFLAG_NO_NORMVAL)
1918 return ATTRSTATE_NO_NORMVAL;
832b75ed 1919
cfbba5b9
GI
1920 // Normally threshold is at same index as attribute
1921 int i = attridx;
1922 if (thresholds[i].id != attr.id) {
1923 // Find threshold id in table
1924 for (i = 0; thresholds[i].id != attr.id; ) {
1925 if (++i >= NUMBER_ATA_SMART_ATTRIBUTES)
1926 // Threshold id missing or thresholds cannot be read
1927 return ATTRSTATE_NO_THRESHOLD;
1928 }
1929 }
1930 unsigned char threshold = thresholds[i].threshold;
832b75ed 1931
cfbba5b9
GI
1932 // Return threshold if requested
1933 if (threshval)
1934 *threshval = threshold;
832b75ed 1935
bed94269
GI
1936 // Don't report a failed attribute if its threshold is 0.
1937 // ATA-3 (X3T13/2008D Revision 7b) declares 0x00 as the "always passing"
1938 // threshold (Later ATA versions declare all thresholds as "obsolete").
1939 // In practice, threshold value 0 is often used for usage attributes.
cfbba5b9 1940 if (!threshold)
bed94269 1941 return ATTRSTATE_OK;
832b75ed 1942
bed94269 1943 // Failed now if current value is below threshold
cfbba5b9 1944 if (attr.current <= threshold)
bed94269 1945 return ATTRSTATE_FAILED_NOW;
832b75ed 1946
a23d5117 1947 // Failed in the past if worst value is below threshold
cfbba5b9 1948 if (!(defs[attr.id].flags & ATTRFLAG_NO_WORSTVAL) && attr.worst <= threshold)
bed94269 1949 return ATTRSTATE_FAILED_PAST;
832b75ed 1950
bed94269 1951 return ATTRSTATE_OK;
832b75ed
GG
1952}
1953
bed94269
GI
1954// Get default raw value print format
1955static ata_attr_raw_format get_default_raw_format(unsigned char id)
a37e7145 1956{
bed94269
GI
1957 switch (id) {
1958 case 3: // Spin-up time
1959 return RAWFMT_RAW16_OPT_AVG16;
a37e7145 1960
bed94269
GI
1961 case 5: // Reallocated sector count
1962 case 196: // Reallocated event count
1963 return RAWFMT_RAW16_OPT_RAW16;
1964
e165493d
GI
1965 case 9: // Power on hours
1966 return RAWFMT_RAW24_OPT_RAW8;
1967
bed94269
GI
1968 case 190: // Temperature
1969 case 194:
1970 return RAWFMT_TEMPMINMAX;
1971
1972 default:
1973 return RAWFMT_RAW48;
a37e7145 1974 }
bed94269
GI
1975}
1976
1977// Get attribute raw value.
1978uint64_t ata_get_attr_raw_value(const ata_smart_attribute & attr,
1979 const ata_vendor_attr_defs & defs)
1980{
a23d5117
GI
1981 const ata_vendor_attr_defs::entry & def = defs[attr.id];
1982
1983 // Use default byteorder if not specified
1984 const char * byteorder = def.byteorder;
1985 if (!*byteorder) {
cfbba5b9
GI
1986 switch (def.raw_format) {
1987 case RAWFMT_RAW64:
1988 case RAWFMT_HEX64:
1989 byteorder = "543210wv"; break;
e165493d
GI
1990 case RAWFMT_RAW56:
1991 case RAWFMT_HEX56:
cfbba5b9
GI
1992 case RAWFMT_RAW24_DIV_RAW32:
1993 case RAWFMT_MSEC24_HOUR32:
1994 byteorder = "r543210"; break;
1995 default:
1996 byteorder = "543210"; break;
1997 }
a23d5117
GI
1998 }
1999
2000 // Build 64-bit value from selected bytes
2001 uint64_t rawvalue = 0;
2002 for (int i = 0; byteorder[i]; i++) {
2003 unsigned char b;
2004 switch (byteorder[i]) {
2005 case '0': b = attr.raw[0]; break;
2006 case '1': b = attr.raw[1]; break;
2007 case '2': b = attr.raw[2]; break;
2008 case '3': b = attr.raw[3]; break;
2009 case '4': b = attr.raw[4]; break;
2010 case '5': b = attr.raw[5]; break;
2011 case 'r': b = attr.reserv; break;
2012 case 'v': b = attr.current; break;
2013 case 'w': b = attr.worst; break;
2014 default : b = 0; break;
2015 }
2016 rawvalue <<= 8; rawvalue |= b;
a37e7145 2017 }
a23d5117 2018
bed94269 2019 return rawvalue;
a37e7145
GG
2020}
2021
2022
bed94269
GI
2023// Format attribute raw value.
2024std::string ata_format_attr_raw_value(const ata_smart_attribute & attr,
2025 const ata_vendor_attr_defs & defs)
2026{
a23d5117 2027 // Get 48 bit or 64 bit raw value
bed94269 2028 uint64_t rawvalue = ata_get_attr_raw_value(attr, defs);
832b75ed 2029
a7e8ffec
GI
2030 // Split into bytes and words
2031 unsigned char raw[6];
2032 raw[0] = (unsigned char) rawvalue;
2033 raw[1] = (unsigned char)(rawvalue >> 8);
2034 raw[2] = (unsigned char)(rawvalue >> 16);
2035 raw[3] = (unsigned char)(rawvalue >> 24);
2036 raw[4] = (unsigned char)(rawvalue >> 32);
2037 raw[5] = (unsigned char)(rawvalue >> 40);
832b75ed 2038 unsigned word[3];
bed94269
GI
2039 word[0] = raw[0] | (raw[1] << 8);
2040 word[1] = raw[2] | (raw[3] << 8);
2041 word[2] = raw[4] | (raw[5] << 8);
832b75ed 2042
bed94269
GI
2043 // Get print format
2044 ata_attr_raw_format format = defs[attr.id].raw_format;
2045 if (format == RAWFMT_DEFAULT)
2046 format = get_default_raw_format(attr.id);
2047
2048 // Print
2049 std::string s;
2050 switch (format) {
2051 case RAWFMT_RAW8:
2052 s = strprintf("%d %d %d %d %d %d",
2053 raw[5], raw[4], raw[3], raw[2], raw[1], raw[0]);
832b75ed 2054 break;
bed94269
GI
2055
2056 case RAWFMT_RAW16:
2057 s = strprintf("%u %u %u", word[2], word[1], word[0]);
2058 break;
2059
2060 case RAWFMT_RAW48:
e165493d 2061 case RAWFMT_RAW56:
a23d5117 2062 case RAWFMT_RAW64:
bed94269
GI
2063 s = strprintf("%"PRIu64, rawvalue);
2064 break;
2065
2066 case RAWFMT_HEX48:
2067 s = strprintf("0x%012"PRIx64, rawvalue);
2068 break;
2069
e165493d
GI
2070 case RAWFMT_HEX56:
2071 s = strprintf("0x%014"PRIx64, rawvalue);
2072 break;
2073
bed94269
GI
2074 case RAWFMT_HEX64:
2075 s = strprintf("0x%016"PRIx64, rawvalue);
2076 break;
2077
2078 case RAWFMT_RAW16_OPT_RAW16:
2079 s = strprintf("%u", word[0]);
2127e193 2080 if (word[1] || word[2])
e165493d 2081 s += strprintf(" (%u %u)", word[2], word[1]);
2127e193 2082 break;
bed94269
GI
2083
2084 case RAWFMT_RAW16_OPT_AVG16:
2085 s = strprintf("%u", word[0]);
2086 if (word[1])
2087 s += strprintf(" (Average %u)", word[1]);
2088 break;
2089
e165493d
GI
2090 case RAWFMT_RAW24_OPT_RAW8:
2091 s = strprintf("%u", (unsigned)(rawvalue & 0x00ffffffULL));
2092 if (raw[3] || raw[4] || raw[5])
2093 s += strprintf(" (%d %d %d)", raw[5], raw[4], raw[3]);
2094 break;
2095
cfbba5b9
GI
2096 case RAWFMT_RAW24_DIV_RAW24:
2097 s = strprintf("%u/%u",
2098 (unsigned)(rawvalue >> 24), (unsigned)(rawvalue & 0x00ffffffULL));
2099 break;
2100
2101 case RAWFMT_RAW24_DIV_RAW32:
2102 s = strprintf("%u/%u",
2103 (unsigned)(rawvalue >> 32), (unsigned)(rawvalue & 0xffffffffULL));
bed94269
GI
2104 break;
2105
2106 case RAWFMT_MIN2HOUR:
2107 {
832b75ed 2108 // minutes
bed94269
GI
2109 int64_t temp = word[0]+(word[1]<<16);
2110 int64_t tmp1 = temp/60;
2111 int64_t tmp2 = temp%60;
2112 s = strprintf("%"PRIu64"h+%02"PRIu64"m", tmp1, tmp2);
2127e193 2113 if (word[2])
bed94269 2114 s += strprintf(" (%u)", word[2]);
832b75ed 2115 }
bed94269
GI
2116 break;
2117
2118 case RAWFMT_SEC2HOUR:
2119 {
832b75ed 2120 // seconds
bed94269
GI
2121 int64_t hours = rawvalue/3600;
2122 int64_t minutes = (rawvalue-3600*hours)/60;
2123 int64_t seconds = rawvalue%60;
2124 s = strprintf("%"PRIu64"h+%02"PRIu64"m+%02"PRIu64"s", hours, minutes, seconds);
832b75ed 2125 }
a37e7145 2126 break;
bed94269
GI
2127
2128 case RAWFMT_HALFMIN2HOUR:
2129 {
2130 // 30-second counter
2131 int64_t hours = rawvalue/120;
2132 int64_t minutes = (rawvalue-120*hours)/2;
2133 s += strprintf("%"PRIu64"h+%02"PRIu64"m", hours, minutes);
832b75ed 2134 }
832b75ed 2135 break;
bed94269 2136
cfbba5b9
GI
2137 case RAWFMT_MSEC24_HOUR32:
2138 {
2139 // hours + milliseconds
2140 unsigned hours = (unsigned)(rawvalue & 0xffffffffULL);
2141 unsigned milliseconds = (unsigned)(rawvalue >> 32);
2142 unsigned seconds = milliseconds / 1000;
2143 s = strprintf("%uh+%02um+%02u.%03us",
2144 hours, seconds / 60, seconds % 60, milliseconds % 1000);
2145 }
2146 break;
2147
bed94269 2148 case RAWFMT_TEMPMINMAX:
832b75ed 2149 // Temperature
d008864d
GI
2150 {
2151 // Search for possible min/max values
2152 // 00 HH 00 LL 00 TT (Hitachi/IBM)
2153 // 00 00 HH LL 00 TT (Maxtor, Samsung)
2154 // 00 00 00 HH LL TT (WDC)
2155 unsigned char lo = 0, hi = 0;
2156 int cnt = 0;
2157 for (int i = 1; i < 6; i++) {
2158 if (raw[i])
2159 switch (cnt++) {
2160 case 0:
2161 lo = raw[i];
2162 break;
2163 case 1:
2164 if (raw[i] < lo) {
2165 hi = lo; lo = raw[i];
2166 }
2167 else
2168 hi = raw[i];
2169 break;
2170 }
bed94269 2171 }
d008864d
GI
2172
2173 unsigned char t = raw[0];
2174 if (cnt == 0)
2175 s = strprintf("%d", t);
2176 else if (cnt == 2 && 0 < lo && lo <= t && t <= hi && hi < 128)
2177 s = strprintf("%d (Min/Max %d/%d)", t, lo, hi);
bed94269 2178 else
d008864d 2179 s = strprintf("%d (%d %d %d %d %d)", t, raw[5], raw[4], raw[3], raw[2], raw[1]);
832b75ed 2180 }
832b75ed 2181 break;
bed94269
GI
2182
2183 case RAWFMT_TEMP10X:
2184 // ten times temperature in Celsius
2185 s = strprintf("%d.%d", word[0]/10, word[0]%10);
2127e193 2186 break;
bed94269 2187
832b75ed 2188 default:
bed94269
GI
2189 s = "?"; // Should not happen
2190 break;
832b75ed 2191 }
832b75ed 2192
bed94269
GI
2193 return s;
2194}
832b75ed 2195
bed94269
GI
2196// Attribute names shouldn't be longer than 23 chars, otherwise they break the
2197// output of smartctl.
2198static const char * get_default_attr_name(unsigned char id)
2199{
2200 switch (id) {
832b75ed 2201 case 1:
bed94269 2202 return "Raw_Read_Error_Rate";
832b75ed 2203 case 2:
bed94269 2204 return "Throughput_Performance";
832b75ed 2205 case 3:
bed94269 2206 return "Spin_Up_Time";
832b75ed 2207 case 4:
bed94269 2208 return "Start_Stop_Count";
832b75ed 2209 case 5:
bed94269 2210 return "Reallocated_Sector_Ct";
832b75ed 2211 case 6:
bed94269 2212 return "Read_Channel_Margin";
832b75ed 2213 case 7:
bed94269 2214 return "Seek_Error_Rate";
832b75ed 2215 case 8:
bed94269 2216 return "Seek_Time_Performance";
832b75ed 2217 case 9:
bed94269 2218 return "Power_On_Hours";
832b75ed 2219 case 10:
bed94269 2220 return "Spin_Retry_Count";
832b75ed 2221 case 11:
bed94269 2222 return "Calibration_Retry_Count";
832b75ed 2223 case 12:
bed94269 2224 return "Power_Cycle_Count";
832b75ed 2225 case 13:
bed94269 2226 return "Read_Soft_Error_Rate";
eb07ddf2 2227 case 175:
bed94269 2228 return "Program_Fail_Count_Chip";
eb07ddf2 2229 case 176:
bed94269 2230 return "Erase_Fail_Count_Chip";
eb07ddf2 2231 case 177:
bed94269 2232 return "Wear_Leveling_Count";
2127e193 2233 case 178:
bed94269 2234 return "Used_Rsvd_Blk_Cnt_Chip";
2127e193 2235 case 179:
bed94269 2236 return "Used_Rsvd_Blk_Cnt_Tot";
2127e193 2237 case 180:
bed94269 2238 return "Unused_Rsvd_Blk_Cnt_Tot";
eb07ddf2 2239 case 181:
bed94269 2240 return "Program_Fail_Cnt_Total";
eb07ddf2 2241 case 182:
bed94269 2242 return "Erase_Fail_Count_Total";
2127e193 2243 case 183:
bed94269 2244 return "Runtime_Bad_Block";
eb07ddf2 2245 case 184:
bed94269 2246 return "End-to-End_Error";
a37e7145 2247 case 187:
bed94269 2248 return "Reported_Uncorrect";
eb07ddf2 2249 case 188:
bed94269 2250 return "Command_Timeout";
a37e7145 2251 case 189:
bed94269 2252 return "High_Fly_Writes";
4d59bff9
GG
2253 case 190:
2254 // Western Digital uses this for temperature.
2255 // It's identical to Attribute 194 except that it
2256 // has a failure threshold set to correspond to the
2257 // max allowed operating temperature of the drive, which
2258 // is typically 55C. So if this attribute has failed
2259 // in the past, it indicates that the drive temp exceeded
2260 // 55C sometime in the past.
bed94269 2261 return "Airflow_Temperature_Cel";
832b75ed 2262 case 191:
bed94269 2263 return "G-Sense_Error_Rate";
832b75ed 2264 case 192:
bed94269 2265 return "Power-Off_Retract_Count";
832b75ed 2266 case 193:
bed94269 2267 return "Load_Cycle_Count";
832b75ed 2268 case 194:
bed94269 2269 return "Temperature_Celsius";
832b75ed 2270 case 195:
bed94269
GI
2271 // Fujitsu: "ECC_On_The_Fly_Count";
2272 return "Hardware_ECC_Recovered";
832b75ed 2273 case 196:
bed94269 2274 return "Reallocated_Event_Count";
832b75ed 2275 case 197:
bed94269 2276 return "Current_Pending_Sector";
832b75ed 2277 case 198:
bed94269 2278 return "Offline_Uncorrectable";
832b75ed 2279 case 199:
bed94269 2280 return "UDMA_CRC_Error_Count";
832b75ed 2281 case 200:
bed94269
GI
2282 // Western Digital
2283 return "Multi_Zone_Error_Rate";
832b75ed 2284 case 201:
bed94269 2285 return "Soft_Read_Error_Rate";
832b75ed 2286 case 202:
bed94269
GI
2287 // Fujitsu: "TA_Increase_Count"
2288 return "Data_Address_Mark_Errs";
832b75ed
GG
2289 case 203:
2290 // Fujitsu
bed94269 2291 return "Run_Out_Cancel";
832b75ed 2292 // Maxtor: ECC Errors
832b75ed 2293 case 204:
bed94269
GI
2294 // Fujitsu: "Shock_Count_Write_Opern"
2295 return "Soft_ECC_Correction";
832b75ed 2296 case 205:
bed94269
GI
2297 // Fujitsu: "Shock_Rate_Write_Opern"
2298 return "Thermal_Asperity_Rate";
832b75ed
GG
2299 case 206:
2300 // Fujitsu
bed94269 2301 return "Flying_Height";
832b75ed
GG
2302 case 207:
2303 // Maxtor
bed94269 2304 return "Spin_High_Current";
832b75ed
GG
2305 case 208:
2306 // Maxtor
bed94269 2307 return "Spin_Buzz";
832b75ed
GG
2308 case 209:
2309 // Maxtor
bed94269 2310 return "Offline_Seek_Performnce";
832b75ed 2311 case 220:
bed94269 2312 return "Disk_Shift";
832b75ed 2313 case 221:
bed94269 2314 return "G-Sense_Error_Rate";
832b75ed 2315 case 222:
bed94269 2316 return "Loaded_Hours";
832b75ed 2317 case 223:
bed94269 2318 return "Load_Retry_Count";
832b75ed 2319 case 224:
bed94269 2320 return "Load_Friction";
832b75ed 2321 case 225:
bed94269 2322 return "Load_Cycle_Count";
832b75ed 2323 case 226:
bed94269 2324 return "Load-in_Time";
832b75ed 2325 case 227:
bed94269 2326 return "Torq-amp_Count";
832b75ed 2327 case 228:
bed94269 2328 return "Power-off_Retract_Count";
832b75ed
GG
2329 case 230:
2330 // seen in IBM DTPA-353750
bed94269 2331 return "Head_Amplitude";
832b75ed 2332 case 231:
bed94269
GI
2333 return "Temperature_Celsius";
2334 case 232:
2335 // seen in Intel X25-E SSD
2336 return "Available_Reservd_Space";
2337 case 233:
2338 // seen in Intel X25-E SSD
2339 return "Media_Wearout_Indicator";
832b75ed 2340 case 240:
bed94269
GI
2341 return "Head_Flying_Hours";
2342 case 241:
2343 return "Total_LBAs_Written";
2344 case 242:
2345 return "Total_LBAs_Read";
832b75ed 2346 case 250:
bed94269
GI
2347 return "Read_Error_Retry_Rate";
2348 case 254:
2349 return "Free_Fall_Sensor";
832b75ed 2350 default:
bed94269 2351 return "Unknown_Attribute";
832b75ed 2352 }
832b75ed
GG
2353}
2354
bed94269
GI
2355// Get attribute name
2356std::string ata_get_smart_attr_name(unsigned char id, const ata_vendor_attr_defs & defs)
2127e193 2357{
bed94269
GI
2358 if (!defs[id].name.empty())
2359 return defs[id].name;
2360 else
2361 return get_default_attr_name(id);
2362}
2363
2364// Find attribute index for attribute id, -1 if not found.
2365int ata_find_attr_index(unsigned char id, const ata_smart_values & smartval)
2366{
2367 if (!id)
832b75ed 2368 return -1;
2127e193 2369 for (int i = 0; i < NUMBER_ATA_SMART_ATTRIBUTES; i++) {
bed94269
GI
2370 if (smartval.vendor_attributes[i].id == id)
2371 return i;
2372 }
832b75ed
GG
2373 return -1;
2374}
2375
4d59bff9
GG
2376// Return Temperature Attribute raw value selected according to possible
2377// non-default interpretations. If the Attribute does not exist, return 0
bed94269 2378unsigned char ata_return_temperature_value(const ata_smart_values * data, const ata_vendor_attr_defs & defs)
2127e193
GI
2379{
2380 for (int i = 0; i < 3; i++) {
4d59bff9
GG
2381 static const unsigned char ids[3] = {194, 9, 220};
2382 unsigned char id = ids[i];
bed94269
GI
2383 const ata_attr_raw_format format = defs[id].raw_format;
2384 if (!( (id == 194 && format == RAWFMT_DEFAULT)
2385 || format == RAWFMT_TEMPMINMAX || format == RAWFMT_TEMP10X))
4d59bff9 2386 continue;
bed94269
GI
2387 int idx = ata_find_attr_index(id, *data);
2388 if (idx < 0)
4d59bff9 2389 continue;
bed94269 2390 uint64_t raw = ata_get_attr_raw_value(data->vendor_attributes[idx], defs);
d008864d
GI
2391 unsigned temp;
2392 // ignore possible min/max values in high words
bed94269 2393 if (format == RAWFMT_TEMP10X) // -v N,temp10x
d008864d
GI
2394 temp = ((unsigned short)raw + 5) / 10;
2395 else
2396 temp = (unsigned char)raw;
2397 if (!(0 < temp && temp < 128))
4d59bff9
GG
2398 continue;
2399 return temp;
2400 }
2401 // No valid attribute found
2402 return 0;
2403}
a37e7145 2404
2127e193 2405
a37e7145 2406// Read SCT Status
2127e193 2407int ataReadSCTStatus(ata_device * device, ata_sct_status_response * sts)
a37e7145
GG
2408{
2409 // read SCT status via SMART log 0xe0
2410 memset(sts, 0, sizeof(*sts));
2411 if (smartcommandhandler(device, READ_LOG, 0xe0, (char *)sts)){
a7e8ffec 2412 pout("Error Read SCT Status failed: %s\n", device->get_errmsg());
a37e7145
GG
2413 return -1;
2414 }
2415
2416 // swap endian order if needed
2417 if (isbigendian()){
2418 swapx(&sts->format_version);
2419 swapx(&sts->sct_version);
2420 swapx(&sts->sct_spec);
2421 swapx(&sts->ext_status_code);
2422 swapx(&sts->action_code);
2423 swapx(&sts->function_code);
2424 swapx(&sts->over_limit_count);
2425 swapx(&sts->under_limit_count);
2426 }
2427
2428 // Check format version
2429 if (!(sts->format_version == 2 || sts->format_version == 3)) {
2430 pout("Error unknown SCT Status format version %u, should be 2 or 3.\n", sts->format_version);
2431 return -1;
2432 }
2433 return 0;
2434}
2435
2436// Read SCT Temperature History Table and Status
2127e193 2437int ataReadSCTTempHist(ata_device * device, ata_sct_temperature_history_table * tmh,
a37e7145
GG
2438 ata_sct_status_response * sts)
2439{
2440 // Check initial status
2441 if (ataReadSCTStatus(device, sts))
2442 return -1;
2443
2444 // Do nothing if other SCT command is executing
2445 if (sts->ext_status_code == 0xffff) {
2446 pout("Another SCT command is executing, abort Read Data Table\n"
2447 "(SCT ext_status_code 0x%04x, action_code=%u, function_code=%u)\n",
2448 sts->ext_status_code, sts->action_code, sts->function_code);
2449 return -1;
2450 }
2451
2452 ata_sct_data_table_command cmd; memset(&cmd, 0, sizeof(cmd));
2453 // CAUTION: DO NOT CHANGE THIS VALUE (SOME ACTION CODES MAY ERASE DISK)
2454 cmd.action_code = 5; // Data table command
2455 cmd.function_code = 1; // Read table
2456 cmd.table_id = 2; // Temperature History Table
2457
7f0798ef
GI
2458 // swap endian order if needed
2459 if (isbigendian()) {
2460 swapx(&cmd.action_code);
2461 swapx(&cmd.function_code);
2462 swapx(&cmd.table_id);
2463 }
2464
a37e7145
GG
2465 // write command via SMART log page 0xe0
2466 if (smartcommandhandler(device, WRITE_LOG, 0xe0, (char *)&cmd)){
a7e8ffec 2467 pout("Error Write SCT Data Table command failed: %s\n", device->get_errmsg());
a37e7145
GG
2468 return -1;
2469 }
2470
2471 // read SCT data via SMART log page 0xe1
2472 memset(tmh, 0, sizeof(*tmh));
2473 if (smartcommandhandler(device, READ_LOG, 0xe1, (char *)tmh)){
a7e8ffec 2474 pout("Error Read SCT Data Table failed: %s\n", device->get_errmsg());
a37e7145
GG
2475 return -1;
2476 }
2477
2478 // re-read and check SCT status
2479 if (ataReadSCTStatus(device, sts))
2480 return -1;
2481
2482 if (!(sts->ext_status_code == 0 && sts->action_code == 5 && sts->function_code == 1)) {
a23d5117 2483 pout("Error unexpected SCT status 0x%04x (action_code=%u, function_code=%u)\n",
a37e7145
GG
2484 sts->ext_status_code, sts->action_code, sts->function_code);
2485 return -1;
2486 }
2487
2488 // swap endian order if needed
2489 if (isbigendian()){
2490 swapx(&tmh->format_version);
2491 swapx(&tmh->sampling_period);
2492 swapx(&tmh->interval);
2493 }
2494
2495 // Check format version
2496 if (tmh->format_version != 2) {
2497 pout("Error unknown SCT Temperature History Format Version (%u), should be 2.\n", tmh->format_version);
2498 return -1;
2499 }
2500 return 0;
2501}
2502
2503// Set SCT Temperature Logging Interval
2127e193 2504int ataSetSCTTempInterval(ata_device * device, unsigned interval, bool persistent)
a37e7145
GG
2505{
2506 // Check initial status
2507 ata_sct_status_response sts;
2508 if (ataReadSCTStatus(device, &sts))
2509 return -1;
2510
2511 // Do nothing if other SCT command is executing
2512 if (sts.ext_status_code == 0xffff) {
2513 pout("Another SCT command is executing, abort Feature Control\n"
2514 "(SCT ext_status_code 0x%04x, action_code=%u, function_code=%u)\n",
2515 sts.ext_status_code, sts.action_code, sts.function_code);
2516 return -1;
2517 }
2518
2519 ata_sct_feature_control_command cmd; memset(&cmd, 0, sizeof(cmd));
2520 // CAUTION: DO NOT CHANGE THIS VALUE (SOME ACTION CODES MAY ERASE DISK)
2521 cmd.action_code = 4; // Feature Control command
2522 cmd.function_code = 1; // Set state
2523 cmd.feature_code = 3; // Temperature logging interval
2524 cmd.state = interval;
2525 cmd.option_flags = (persistent ? 0x01 : 0x00);
2526
7f0798ef
GI
2527 // swap endian order if needed
2528 if (isbigendian()) {
2529 swapx(&cmd.action_code);
2530 swapx(&cmd.function_code);
2531 swapx(&cmd.feature_code);
2532 swapx(&cmd.state);
2533 swapx(&cmd.option_flags);
2534 }
2535
a37e7145
GG
2536 // write command via SMART log page 0xe0
2537 if (smartcommandhandler(device, WRITE_LOG, 0xe0, (char *)&cmd)){
a7e8ffec 2538 pout("Error Write SCT Feature Control Command failed: %s\n", device->get_errmsg());
a37e7145
GG
2539 return -1;
2540 }
2541
2542 // re-read and check SCT status
2543 if (ataReadSCTStatus(device, &sts))
2544 return -1;
2545
2546 if (!(sts.ext_status_code == 0 && sts.action_code == 4 && sts.function_code == 1)) {
2547 pout("Error unexcepted SCT status 0x%04x (action_code=%u, function_code=%u)\n",
2548 sts.ext_status_code, sts.action_code, sts.function_code);
2549 return -1;
2550 }
2551 return 0;
2552}
2553
7f0798ef
GI
2554// Get/Set SCT Error Recovery Control
2555static int ataGetSetSCTErrorRecoveryControltime(ata_device * device, unsigned type,
2556 bool set, unsigned short & time_limit)
2557{
2558 // Check initial status
2559 ata_sct_status_response sts;
2560 if (ataReadSCTStatus(device, &sts))
2561 return -1;
2562
2563 // Do nothing if other SCT command is executing
2564 if (sts.ext_status_code == 0xffff) {
2565 pout("Another SCT command is executing, abort Error Recovery Control\n"
2566 "(SCT ext_status_code 0x%04x, action_code=%u, function_code=%u)\n",
2567 sts.ext_status_code, sts.action_code, sts.function_code);
2568 return -1;
2569 }
2570
2571 ata_sct_error_recovery_control_command cmd; memset(&cmd, 0, sizeof(cmd));
2572 // CAUTION: DO NOT CHANGE THIS VALUE (SOME ACTION CODES MAY ERASE DISK)
2573 cmd.action_code = 3; // Error Recovery Control command
2574 cmd.function_code = (set ? 1 : 2); // 1=Set timer, 2=Get timer
2575 cmd.selection_code = type; // 1=Read timer, 2=Write timer
2576 if (set)
2577 cmd.time_limit = time_limit;
2578
2579 // swap endian order if needed
2580 if (isbigendian()) {
2581 swapx(&cmd.action_code);
2582 swapx(&cmd.function_code);
2583 swapx(&cmd.selection_code);
2584 swapx(&cmd.time_limit);
2585 }
2586
2587 // write command via SMART log page 0xe0
2588 // TODO: Debug output
2589 ata_cmd_in in;
2590 in.in_regs.command = ATA_SMART_CMD;
2591 in.in_regs.lba_high = SMART_CYL_HI; in.in_regs.lba_mid = SMART_CYL_LOW;
2592 in.in_regs.features = ATA_SMART_WRITE_LOG_SECTOR;
2593 in.in_regs.lba_low = 0xe0;
2594 in.set_data_out(&cmd, 1);
2595
2596 if (!set)
2597 // Time limit returned in ATA registers
2598 in.out_needed.sector_count = in.out_needed.lba_low = true;
2599
2600 ata_cmd_out out;
2601 if (!device->ata_pass_through(in, out)) {
cfbba5b9
GI
2602 pout("Error Write SCT (%cet) Error Recovery Control Command failed: %s\n",
2603 (!set ? 'G' : 'S'), device->get_errmsg());
7f0798ef
GI
2604 return -1;
2605 }
2606
2607 // re-read and check SCT status
2608 if (ataReadSCTStatus(device, &sts))
2609 return -1;
2610
2611 if (!(sts.ext_status_code == 0 && sts.action_code == 3 && sts.function_code == (set ? 1 : 2))) {
2612 pout("Error unexcepted SCT status 0x%04x (action_code=%u, function_code=%u)\n",
2613 sts.ext_status_code, sts.action_code, sts.function_code);
2614 return -1;
2615 }
2616
2617 if (!set) {
2618 // Check whether registers are properly returned by ioctl()
2619 if (!(out.out_regs.sector_count.is_set() && out.out_regs.lba_low.is_set())) {
2620 // TODO: Output register support should be checked within each ata_pass_through()
2621 // implementation before command is issued.
2622 pout("Error SMART WRITE LOG does not return COUNT and LBA_LOW register\n");
2623 return -1;
2624 }
2625 // Return value to caller
2626 time_limit = out.out_regs.sector_count | (out.out_regs.lba_low << 8);
2627 }
2628
2629 return 0;
2630}
2631
2632// Get SCT Error Recovery Control
2633int ataGetSCTErrorRecoveryControltime(ata_device * device, unsigned type, unsigned short & time_limit)
2634{
2635 return ataGetSetSCTErrorRecoveryControltime(device, type, false/*get*/, time_limit);
2636}
2637
2638// Set SCT Error Recovery Control
2639int ataSetSCTErrorRecoveryControltime(ata_device * device, unsigned type, unsigned short time_limit)
2640{
2641 return ataGetSetSCTErrorRecoveryControltime(device, type, true/*set*/, time_limit);
2642}
2643
2644
2127e193 2645// Print one self-test log entry.
cfbba5b9
GI
2646// Returns:
2647// -1: self-test failed
2648// 1: extended self-test completed without error
2649// 0: otherwise
2650int ataPrintSmartSelfTestEntry(unsigned testnum, unsigned char test_type,
2651 unsigned char test_status,
2652 unsigned short timestamp,
2653 uint64_t failing_lba,
2654 bool print_error_only, bool & print_header)
2655{
2656 // Check status and type for return value
2657 int retval = 0;
2658 switch (test_status >> 4) {
2659 case 0x0:
2660 if ((test_type & 0x0f) == 0x02)
2661 retval = 1; // extended self-test completed without error
2662 break;
2663 case 0x3: case 0x4:
2664 case 0x5: case 0x6:
2665 case 0x7: case 0x8:
2666 retval = -1; // self-test failed
2667 break;
2668 }
2669
2670 if (retval >= 0 && print_error_only)
2671 return retval;
2672
2673 std::string msgtest;
2127e193
GI
2674 switch (test_type) {
2675 case 0x00: msgtest = "Offline"; break;
2676 case 0x01: msgtest = "Short offline"; break;
2677 case 0x02: msgtest = "Extended offline"; break;
2678 case 0x03: msgtest = "Conveyance offline"; break;
2679 case 0x04: msgtest = "Selective offline"; break;
2680 case 0x7f: msgtest = "Abort offline test"; break;
2681 case 0x81: msgtest = "Short captive"; break;
2682 case 0x82: msgtest = "Extended captive"; break;
2683 case 0x83: msgtest = "Conveyance captive"; break;
2684 case 0x84: msgtest = "Selective captive"; break;
2685 default:
2686 if ((0x40 <= test_type && test_type <= 0x7e) || 0x90 <= test_type)
cfbba5b9 2687 msgtest = strprintf("Vendor (0x%02x)", test_type);
2127e193 2688 else
cfbba5b9 2689 msgtest = strprintf("Reserved (0x%02x)", test_type);
2127e193
GI
2690 }
2691
cfbba5b9 2692 std::string msgstat;
2127e193
GI
2693 switch (test_status >> 4) {
2694 case 0x0: msgstat = "Completed without error"; break;
2695 case 0x1: msgstat = "Aborted by host"; break;
2696 case 0x2: msgstat = "Interrupted (host reset)"; break;
cfbba5b9
GI
2697 case 0x3: msgstat = "Fatal or unknown error"; break;
2698 case 0x4: msgstat = "Completed: unknown failure"; break;
2699 case 0x5: msgstat = "Completed: electrical failure"; break;
2700 case 0x6: msgstat = "Completed: servo/seek failure"; break;
2701 case 0x7: msgstat = "Completed: read failure"; break;
2702 case 0x8: msgstat = "Completed: handling damage??"; break;
2127e193 2703 case 0xf: msgstat = "Self-test routine in progress"; break;
cfbba5b9 2704 default: msgstat = strprintf("Unknown status (0x%x)", test_status >> 4);
2127e193
GI
2705 }
2706
2127e193
GI
2707 // Print header once
2708 if (print_header) {
2709 print_header = false;
2710 pout("Num Test_Description Status Remaining LifeTime(hours) LBA_of_first_error\n");
2711 }
2712
2713 char msglba[32];
cfbba5b9 2714 if (retval < 0 && failing_lba < 0xffffffffffffULL)
2127e193
GI
2715 snprintf(msglba, sizeof(msglba), "%"PRIu64, failing_lba);
2716 else
2717 strcpy(msglba, "-");
2718
cfbba5b9
GI
2719 pout("#%2u %-19s %-29s %1d0%% %8u %s\n", testnum,
2720 msgtest.c_str(), msgstat.c_str(), test_status & 0x0f, timestamp, msglba);
2127e193 2721
cfbba5b9 2722 return retval;
2127e193
GI
2723}
2724
2725// Print Smart self-test log, used by smartctl and smartd.
2726// return value is:
2727// bottom 8 bits: number of entries found where self-test showed an error
2728// remaining bits: if nonzero, power on hours of last self-test where error was found
2729int ataPrintSmartSelfTestlog(const ata_smart_selftestlog * data, bool allentries,
2730 unsigned char fix_firmwarebug)
2731{
2732 if (allentries)
2733 pout("SMART Self-test log structure revision number %d\n",(int)data->revnumber);
2734 if ((data->revnumber!=0x0001) && allentries && fix_firmwarebug != FIX_SAMSUNG)
2735 pout("Warning: ATA Specification requires self-test log structure revision number = 1\n");
2736 if (data->mostrecenttest==0){
2737 if (allentries)
2738 pout("No self-tests have been logged. [To run self-tests, use: smartctl -t]\n\n");
2739 return 0;
2740 }
2741
2742 bool noheaderprinted = true;
cfbba5b9
GI
2743 int errcnt = 0, hours = 0, igncnt = 0;
2744 int testno = 0, ext_ok_testno = -1;
2127e193
GI
2745
2746 // print log
2747 for (int i = 20; i >= 0; i--) {
2748 // log is a circular buffer
2749 int j = (i+data->mostrecenttest)%21;
2750 const ata_smart_selftestlog_struct * log = data->selftest_struct+j;
2751
2752 if (nonempty(log, sizeof(*log))) {
2753 // count entry based on non-empty structures -- needed for
2754 // Seagate only -- other vendors don't have blank entries 'in
2755 // the middle'
2756 testno++;
2757
2758 // T13/1321D revision 1c: (Data structure Rev #1)
2759
2760 //The failing LBA shall be the LBA of the uncorrectable sector
2761 //that caused the test to fail. If the device encountered more
2762 //than one uncorrectable sector during the test, this field
2763 //shall indicate the LBA of the first uncorrectable sector
2764 //encountered. If the test passed or the test failed for some
2765 //reason other than an uncorrectable sector, the value of this
2766 //field is undefined.
2767
2768 // This is true in ALL ATA-5 specs
2769 uint64_t lba48 = (log->lbafirstfailure < 0xffffffff ? log->lbafirstfailure : 0xffffffffffffULL);
2770
2771 // Print entry
cfbba5b9
GI
2772 int state = ataPrintSmartSelfTestEntry(testno,
2773 log->selftestnumber, log->selfteststatus,
2774 log->timestamp, lba48, !allentries, noheaderprinted);
2127e193 2775
cfbba5b9 2776 if (state < 0) {
f4ebf3d1 2777 // Self-test showed an error
cfbba5b9
GI
2778 if (ext_ok_testno < 0) {
2779 errcnt++;
f4ebf3d1 2780
cfbba5b9
GI
2781 // keep track of time of most recent error
2782 if (!hours)
2783 hours = log->timestamp;
2784 }
2785 else
2786 // Newer successful extended self-test exits
2787 igncnt++;
2788 }
2789 else if (state > 0 && ext_ok_testno < 0) {
2790 // Latest successful extended self-test
2791 ext_ok_testno = testno;
f4ebf3d1 2792 }
2127e193
GI
2793 }
2794 }
cfbba5b9
GI
2795
2796 if (igncnt)
2797 pout("%d of %d failed self-tests are outdated by newer successful extended offline self-test #%2d\n",
2798 igncnt, igncnt+errcnt, ext_ok_testno);
2799
2800 if (!allentries && !noheaderprinted)
2127e193
GI
2801 pout("\n");
2802
cfbba5b9 2803 return ((hours << 8) | errcnt);
2127e193
GI
2804}
2805
a37e7145
GG
2806
2807/////////////////////////////////////////////////////////////////////////////
2808// Pseudo-device to parse "smartctl -r ataioctl,2 ..." output and simulate
2809// an ATA device with same behaviour
2810
2127e193
GI
2811namespace {
2812
2813class parsed_ata_device
2814: public /*implements*/ ata_device_with_command_set
2815{
2816public:
2817 parsed_ata_device(smart_interface * intf, const char * dev_name);
2818
2819 virtual ~parsed_ata_device() throw();
2820
2821 virtual bool is_open() const;
2822
2823 virtual bool open();
a37e7145 2824
2127e193 2825 virtual bool close();
a37e7145 2826
2127e193
GI
2827 virtual bool ata_identify_is_cached() const;
2828
2829protected:
2830 virtual int ata_command_interface(smart_command_set command, int select, char * data);
2831
2832private:
2833 // Table of parsed commands, return value, data
2834 struct parsed_ata_command
2835 {
2836 smart_command_set command;
2837 int select;
2838 int retval, errval;
2839 char * data;
2840 };
2841
2842 enum { max_num_commands = 32 };
2843 parsed_ata_command m_command_table[max_num_commands];
2844
2845 int m_num_commands;
2846 int m_next_replay_command;
2847 bool m_replay_out_of_sync;
2848 bool m_ata_identify_is_cached;
2849};
a37e7145
GG
2850
2851static const char * nextline(const char * s, int & lineno)
2852{
2853 for (s += strcspn(s, "\r\n"); *s == '\r' || *s == '\n'; s++) {
2854 if (*s == '\r' && s[1] == '\n')
2855 s++;
2856 lineno++;
2857 }
2858 return s;
2859}
2860
2861static int name2command(const char * s)
2862{
2863 for (int i = 0; i < (int)(sizeof(commandstrings)/sizeof(commandstrings[0])); i++) {
2864 if (!strcmp(s, commandstrings[i]))
2865 return i;
2866 }
2867 return -1;
2868}
2869
2870static bool matchcpy(char * dest, size_t size, const char * src, const regmatch_t & srcmatch)
2871{
2872 if (srcmatch.rm_so < 0)
2873 return false;
2874 size_t n = srcmatch.rm_eo - srcmatch.rm_so;
2875 if (n >= size)
2876 n = size-1;
2877 memcpy(dest, src + srcmatch.rm_so, n);
2878 dest[n] = 0;
2879 return true;
2880}
2881
2882static inline int matchtoi(const char * src, const regmatch_t & srcmatch, int defval)
2883{
2884 if (srcmatch.rm_so < 0)
2885 return defval;
2886 return atoi(src + srcmatch.rm_so);
2887}
2888
2127e193
GI
2889parsed_ata_device::parsed_ata_device(smart_interface * intf, const char * dev_name)
2890: smart_device(intf, dev_name, "ata", ""),
2891 m_num_commands(0),
2892 m_next_replay_command(0),
2893 m_replay_out_of_sync(false),
2894 m_ata_identify_is_cached(false)
2895{
2896 memset(m_command_table, 0, sizeof(m_command_table));
2897}
2898
2899parsed_ata_device::~parsed_ata_device() throw()
2900{
2901 close();
2902}
2903
2904bool parsed_ata_device::is_open() const
2905{
2906 return (m_num_commands > 0);
2907}
a37e7145
GG
2908
2909// Parse stdin and build command table
2127e193 2910bool parsed_ata_device::open()
a37e7145 2911{
2127e193
GI
2912 const char * pathname = get_dev_name();
2913 if (strcmp(pathname, "-"))
2914 return set_err(EINVAL);
a37e7145
GG
2915 pathname = "<stdin>";
2916 // Fill buffer
2917 char buffer[64*1024];
2918 int size = 0;
2919 while (size < (int)sizeof(buffer)) {
2920 int nr = fread(buffer, 1, sizeof(buffer), stdin);
2921 if (nr <= 0)
2922 break;
2923 size += nr;
2924 }
2127e193
GI
2925 if (size <= 0)
2926 return set_err(ENOENT, "%s: Unexpected EOF", pathname);
2927 if (size >= (int)sizeof(buffer))
2928 return set_err(EIO, "%s: Buffer overflow", pathname);
a37e7145
GG
2929 buffer[size] = 0;
2930
2931 // Regex to match output from "-r ataioctl,2"
2932 static const char pattern[] = "^"
2933 "(" // (1
2127e193 2934 "REPORT-IOCTL: DeviceF?D?=[^ ]+ Command=([A-Z ]*[A-Z])" // (2)
a37e7145
GG
2935 "(" // (3
2936 "( InputParameter=([0-9]+))?" // (4 (5))
2937 "|"
2938 "( returned (-?[0-9]+)( errno=([0-9]+)[^\r\n]*)?)" // (6 (7) (8 (9)))
2939 ")" // )
2940 "[\r\n]" // EOL match necessary to match optional parts above
2941 "|"
2942 "===== \\[([A-Z ]*[A-Z])\\] DATA START " // (10)
2127e193
GI
2943 "|"
2944 " *(En|Dis)abled status cached by OS, " // (11)
a37e7145
GG
2945 ")"; // )
2946
2947 // Compile regex
cfbba5b9 2948 const regular_expression regex(pattern, REG_EXTENDED);
a37e7145
GG
2949
2950 // Parse buffer
2951 const char * errmsg = 0;
2952 int i = -1, state = 0, lineno = 1;
2953 for (const char * line = buffer; *line; line = nextline(line, lineno)) {
2954 // Match line
2127e193 2955 if (!(line[0] == 'R' || line[0] == '=' || line[0] == ' '))
a37e7145 2956 continue;
2127e193 2957 const int nmatch = 1+11;
a37e7145 2958 regmatch_t match[nmatch];
2127e193 2959 if (!regex.execute(line, nmatch, match))
a37e7145
GG
2960 continue;
2961
2962 char cmdname[40];
2963 if (matchcpy(cmdname, sizeof(cmdname), line, match[2])) { // "REPORT-IOCTL:... Command=%s ..."
2964 int nc = name2command(cmdname);
2965 if (nc < 0) {
2966 errmsg = "Unknown ATA command name"; break;
2967 }
2968 if (match[7].rm_so < 0) { // "returned %d"
2969 // Start of command
2970 if (!(state == 0 || state == 2)) {
2971 errmsg = "Missing REPORT-IOCTL result"; break;
2972 }
2127e193 2973 if (++i >= max_num_commands) {
a37e7145
GG
2974 errmsg = "Too many ATA commands"; break;
2975 }
2127e193
GI
2976 m_command_table[i].command = (smart_command_set)nc;
2977 m_command_table[i].select = matchtoi(line, match[5], 0); // "InputParameter=%d"
a37e7145
GG
2978 state = 1;
2979 }
2980 else {
2981 // End of command
2127e193 2982 if (!(state == 1 && (int)m_command_table[i].command == nc)) {
a37e7145
GG
2983 errmsg = "Missing REPORT-IOCTL start"; break;
2984 }
2127e193
GI
2985 m_command_table[i].retval = matchtoi(line, match[7], -1); // "returned %d"
2986 m_command_table[i].errval = matchtoi(line, match[9], 0); // "errno=%d"
a37e7145
GG
2987 state = 2;
2988 }
2989 }
2990 else if (matchcpy(cmdname, sizeof(cmdname), line, match[10])) { // "===== [%s] DATA START "
2991 // Start of sector hexdump
2992 int nc = name2command(cmdname);
2127e193 2993 if (!(state == (nc == WRITE_LOG ? 1 : 2) && (int)m_command_table[i].command == nc)) {
a37e7145
GG
2994 errmsg = "Unexpected DATA START"; break;
2995 }
2996 line = nextline(line, lineno);
2997 char * data = (char *)malloc(512);
2998 unsigned j;
2999 for (j = 0; j < 32; j++) {
3000 unsigned b[16];
3001 unsigned u1, u2; int n1 = -1;
3002 if (!(sscanf(line, "%3u-%3u: "
3003 "%2x %2x %2x %2x %2x %2x %2x %2x "
3004 "%2x %2x %2x %2x %2x %2x %2x %2x%n",
3005 &u1, &u2,
3006 b+ 0, b+ 1, b+ 2, b+ 3, b+ 4, b+ 5, b+ 6, b+ 7,
3007 b+ 8, b+ 9, b+10, b+11, b+12, b+13, b+14, b+15, &n1) == 18
3008 && n1 >= 56 && u1 == j*16 && u2 == j*16+15))
3009 break;
3010 for (unsigned k = 0; k < 16; k++)
3011 data[j*16+k] = b[k];
3012 line = nextline(line, lineno);
3013 }
3014 if (j < 32) {
3015 free(data);
3016 errmsg = "Incomplete sector hex dump"; break;
3017 }
2127e193 3018 m_command_table[i].data = data;
a37e7145
GG
3019 if (nc != WRITE_LOG)
3020 state = 0;
3021 }
2127e193
GI
3022 else if (match[11].rm_so > 0) { // "(En|Dis)abled status cached by OS"
3023 m_ata_identify_is_cached = true;
3024 }
a37e7145
GG
3025 }
3026
3027 if (!(state == 0 || state == 2))
3028 errmsg = "Missing REPORT-IOCTL result";
3029
3030 if (!errmsg && i < 0)
3031 errmsg = "No information found";
3032
2127e193
GI
3033 m_num_commands = i+1;
3034 m_next_replay_command = 0;
3035 m_replay_out_of_sync = false;
a37e7145
GG
3036
3037 if (errmsg) {
2127e193
GI
3038 close();
3039 return set_err(EIO, "%s(%d): Syntax error: %s", pathname, lineno, errmsg);
a37e7145 3040 }
2127e193 3041 return true;
a37e7145
GG
3042}
3043
3044// Report warnings and free command table
2127e193 3045bool parsed_ata_device::close()
a37e7145 3046{
2127e193 3047 if (m_replay_out_of_sync)
a37e7145 3048 pout("REPLAY-IOCTL: Warning: commands replayed out of sync\n");
2127e193
GI
3049 else if (m_next_replay_command != 0)
3050 pout("REPLAY-IOCTL: Warning: %d command(s) not replayed\n", m_num_commands-m_next_replay_command);
a37e7145 3051
2127e193
GI
3052 for (int i = 0; i < m_num_commands; i++) {
3053 if (m_command_table[i].data) {
3054 free(m_command_table[i].data); m_command_table[i].data = 0;
a37e7145
GG
3055 }
3056 }
2127e193
GI
3057 m_num_commands = 0;
3058 m_next_replay_command = 0;
3059 m_replay_out_of_sync = false;
3060 return true;
3061}
3062
3063
3064bool parsed_ata_device::ata_identify_is_cached() const
3065{
3066 return m_ata_identify_is_cached;
a37e7145
GG
3067}
3068
2127e193 3069
a37e7145 3070// Simulate ATA command from command table
2127e193 3071int parsed_ata_device::ata_command_interface(smart_command_set command, int select, char * data)
a37e7145 3072{
2127e193
GI
3073 // Find command, try round-robin if out of sync
3074 int i = m_next_replay_command;
a37e7145 3075 for (int j = 0; ; j++) {
2127e193 3076 if (j >= m_num_commands) {
a37e7145
GG
3077 pout("REPLAY-IOCTL: Warning: Command not found\n");
3078 errno = ENOSYS;
3079 return -1;
3080 }
2127e193 3081 if (m_command_table[i].command == command && m_command_table[i].select == select)
a37e7145 3082 break;
2127e193
GI
3083 if (!m_replay_out_of_sync) {
3084 m_replay_out_of_sync = true;
a37e7145
GG
3085 pout("REPLAY-IOCTL: Warning: Command #%d is out of sync\n", i+1);
3086 }
2127e193 3087 if (++i >= m_num_commands)
a37e7145
GG
3088 i = 0;
3089 }
2127e193
GI
3090 m_next_replay_command = i;
3091 if (++m_next_replay_command >= m_num_commands)
3092 m_next_replay_command = 0;
a37e7145
GG
3093
3094 // Return command data
3095 switch (command) {
3096 case IDENTIFY:
3097 case PIDENTIFY:
3098 case READ_VALUES:
3099 case READ_THRESHOLDS:
3100 case READ_LOG:
2127e193
GI
3101 if (m_command_table[i].data)
3102 memcpy(data, m_command_table[i].data, 512);
a37e7145
GG
3103 break;
3104 case WRITE_LOG:
2127e193 3105 if (!(m_command_table[i].data && !memcmp(data, m_command_table[i].data, 512)))
a37e7145
GG
3106 pout("REPLAY-IOCTL: Warning: WRITE LOG data does not match\n");
3107 break;
3108 case CHECK_POWER_MODE:
3109 data[0] = (char)0xff;
3110 default:
3111 break;
3112 }
3113
2127e193
GI
3114 if (m_command_table[i].errval)
3115 errno = m_command_table[i].errval;
3116 return m_command_table[i].retval;
3117}
3118
3119} // namespace
3120
3121ata_device * get_parsed_ata_device(smart_interface * intf, const char * dev_name)
3122{
3123 return new parsed_ata_device(intf, dev_name);
a37e7145 3124}