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