]> git.proxmox.com Git - mirror_smartmontools-debian.git/blame - atacmds.cpp
Imported Upstream version 6.1+svn3812
[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>
ee38a438 7 * Copyright (C) 2008-13 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
ee38a438 38const char * atacmds_cpp_cvsid = "$Id: atacmds.cpp 3777 2013-02-19 18:32:15Z samm2 $"
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
137const char * map_old_vendor_opts[][2] = {
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') {
175 // "N,format"
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, ':')) {
199 if (!( sscanf(fmtname, "%*[^:]%n:%8[012345rvwz]%n", &n1, byteorder, &n2) >= 1
200 && n2 == (int)strlen(fmtname)))
201 return false;
202 fmtname[n1] = 0;
203 if (strchr(byteorder, 'v'))
204 flags |= (ATTRFLAG_NO_NORMVAL|ATTRFLAG_NO_WORSTVAL);
205 if (strchr(byteorder, 'w'))
206 flags |= ATTRFLAG_NO_WORSTVAL;
207 }
208
bed94269 209 // Find format name
2127e193 210 for (i = 0; ; i++) {
bed94269
GI
211 if (i >= num_format_names)
212 return false; // Not found
213 if (!strcmp(fmtname, format_names[i].name))
2127e193 214 break;
832b75ed 215 }
bed94269
GI
216 ata_attr_raw_format format = format_names[i].format;
217
a23d5117
GI
218 // 64-bit formats use the normalized and worst value bytes.
219 if (!*byteorder && (format == RAWFMT_RAW64 || format == RAWFMT_HEX64))
220 flags |= (ATTRFLAG_NO_NORMVAL|ATTRFLAG_NO_WORSTVAL);
832b75ed 221
2127e193 222 if (!id) {
bed94269
GI
223 // "N,format" -> set format for all entries
224 for (i = 0; i < MAX_ATTRIBUTE_NUM; i++) {
225 if (defs[i].priority >= priority)
226 continue;
227 if (attrname[0])
228 defs[i].name = attrname;
229 defs[i].priority = priority;
230 defs[i].raw_format = format;
231 defs[i].flags = flags;
ee38a438 232 snprintf(defs[i].byteorder, sizeof(defs[i].byteorder), "%s", byteorder);
bed94269
GI
233 }
234 }
235 else if (defs[id].priority <= priority) {
236 // "id,format[,name]"
237 if (attrname[0])
238 defs[id].name = attrname;
239 defs[id].raw_format = format;
240 defs[id].priority = priority;
241 defs[id].flags = flags;
ee38a438 242 snprintf(defs[id].byteorder, sizeof(defs[id].byteorder), "%s", byteorder);
832b75ed
GG
243 }
244
bed94269 245 return true;
832b75ed
GG
246}
247
bed94269 248
2127e193
GI
249// Return a multiline string containing a list of valid arguments for
250// parse_attribute_def(). The strings are preceeded by tabs and followed
832b75ed 251// (except for the last) by newlines.
2127e193
GI
252std::string create_vendor_attribute_arg_list()
253{
254 std::string s;
bed94269
GI
255 unsigned i;
256 for (i = 0; i < num_format_names; i++)
a23d5117 257 s += strprintf("%s\tN,%s[:012345rvwz][,ATTR_NAME]",
bed94269
GI
258 (i>0 ? "\n" : ""), format_names[i].name);
259 for (i = 0; i < num_old_vendor_opts; i++)
260 s += strprintf("\n\t%s", map_old_vendor_opts[i][0]);
832b75ed
GG
261 return s;
262}
263
ee38a438
GI
264
265// Parse firmwarebug def (-F option).
266// Return false on error.
267bool parse_firmwarebug_def(const char * opt, firmwarebug_defs & firmwarebugs)
268{
269 if (!strcmp(opt, "none"))
270 firmwarebugs.set(BUG_NONE);
271 else if (!strcmp(opt, "nologdir"))
272 firmwarebugs.set(BUG_NOLOGDIR);
273 else if (!strcmp(opt, "samsung"))
274 firmwarebugs.set(BUG_SAMSUNG);
275 else if (!strcmp(opt, "samsung2"))
276 firmwarebugs.set(BUG_SAMSUNG2);
277 else if (!strcmp(opt, "samsung3"))
278 firmwarebugs.set(BUG_SAMSUNG3);
279 else if (!strcmp(opt, "xerrorlba"))
280 firmwarebugs.set(BUG_XERRORLBA);
281 else
282 return false;
283 return true;
284}
285
286// Return a string of valid argument words for parse_firmwarebug_def()
287const char * get_valid_firmwarebug_args()
288{
289 return "none, nologdir, samsung, samsung2, samsung3, xerrorlba";
290}
291
292
832b75ed
GG
293// swap two bytes. Point to low address
294void swap2(char *location){
295 char tmp=*location;
296 *location=*(location+1);
297 *(location+1)=tmp;
298 return;
299}
300
301// swap four bytes. Point to low address
302void swap4(char *location){
303 char tmp=*location;
304 *location=*(location+3);
305 *(location+3)=tmp;
306 swap2(location+1);
307 return;
308}
309
310// swap eight bytes. Points to low address
311void swap8(char *location){
312 char tmp=*location;
313 *location=*(location+7);
314 *(location+7)=tmp;
315 tmp=*(location+1);
316 *(location+1)=*(location+6);
317 *(location+6)=tmp;
318 swap4(location+2);
319 return;
320}
321
a7e8ffec
GI
322// Invalidate serial number and WWN and adjust checksum in IDENTIFY data
323static void invalidate_serno(ata_identify_device * id)
324{
a37e7145 325 unsigned char sum = 0;
a7e8ffec
GI
326 unsigned i;
327 for (i = 0; i < sizeof(id->serial_no); i++) {
a37e7145
GG
328 sum += id->serial_no[i]; sum -= id->serial_no[i] = 'X';
329 }
a7e8ffec
GI
330 unsigned char * b = (unsigned char *)id;
331 for (i = 2*108; i < 2*112; i++) { // words108-111: WWN
332 sum += b[i]; sum -= b[i] = 0x00;
333 }
334
a37e7145
GG
335#ifndef __NetBSD__
336 bool must_swap = !!isbigendian();
337 if (must_swap)
338 swapx(id->words088_255+255-88);
339#endif
340 if ((id->words088_255[255-88] & 0x00ff) == 0x00a5)
341 id->words088_255[255-88] += sum << 8;
342#ifndef __NetBSD__
343 if (must_swap)
344 swapx(id->words088_255+255-88);
345#endif
346}
347
2127e193 348static const char * const commandstrings[]={
832b75ed
GG
349 "SMART ENABLE",
350 "SMART DISABLE",
351 "SMART AUTOMATIC ATTRIBUTE SAVE",
352 "SMART IMMEDIATE OFFLINE",
353 "SMART AUTO OFFLINE",
354 "SMART STATUS",
355 "SMART STATUS CHECK",
356 "SMART READ ATTRIBUTE VALUES",
357 "SMART READ ATTRIBUTE THRESHOLDS",
358 "SMART READ LOG",
359 "IDENTIFY DEVICE",
360 "IDENTIFY PACKET DEVICE",
361 "CHECK POWER MODE",
362 "SMART WRITE LOG",
363 "WARNING (UNDEFINED COMMAND -- CONTACT DEVELOPERS AT " PACKAGE_BUGREPORT ")\n"
364};
365
2127e193 366
ee38a438 367static const char * preg(const ata_register & r, char (& buf)[8])
2127e193
GI
368{
369 if (!r.is_set())
370 //return "n/a ";
371 return "....";
ee38a438
GI
372 snprintf(buf, sizeof(buf), "0x%02x", r.val());
373 return buf;
2127e193
GI
374}
375
cfbba5b9 376static void print_regs(const char * prefix, const ata_in_regs & r, const char * suffix = "\n")
2127e193 377{
ee38a438 378 char bufs[7][8];
2127e193
GI
379 pout("%s FR=%s, SC=%s, LL=%s, LM=%s, LH=%s, DEV=%s, CMD=%s%s", prefix,
380 preg(r.features, bufs[0]), preg(r.sector_count, bufs[1]), preg(r.lba_low, bufs[2]),
381 preg(r.lba_mid, bufs[3]), preg(r.lba_high, bufs[4]), preg(r.device, bufs[5]),
382 preg(r.command, bufs[6]), suffix);
383}
384
cfbba5b9 385static void print_regs(const char * prefix, const ata_out_regs & r, const char * suffix = "\n")
2127e193 386{
ee38a438 387 char bufs[7][8];
2127e193
GI
388 pout("%sERR=%s, SC=%s, LL=%s, LM=%s, LH=%s, DEV=%s, STS=%s%s", prefix,
389 preg(r.error, bufs[0]), preg(r.sector_count, bufs[1]), preg(r.lba_low, bufs[2]),
390 preg(r.lba_mid, bufs[3]), preg(r.lba_high, bufs[4]), preg(r.device, bufs[5]),
391 preg(r.status, bufs[6]), suffix);
392}
393
a37e7145 394static void prettyprint(const unsigned char *p, const char *name){
832b75ed 395 pout("\n===== [%s] DATA START (BASE-16) =====\n", name);
a37e7145 396 for (int i=0; i<512; i+=16, p+=16)
d008864d 397#define P(n) (' ' <= p[n] && p[n] <= '~' ? (int)p[n] : '.')
a37e7145
GG
398 // print complete line to avoid slow tty output and extra lines in syslog.
399 pout("%03d-%03d: %02x %02x %02x %02x %02x %02x %02x %02x "
a23d5117
GI
400 "%02x %02x %02x %02x %02x %02x %02x %02x"
401 " |%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c|"
402 "%c",
a37e7145
GG
403 i, i+16-1,
404 p[ 0], p[ 1], p[ 2], p[ 3], p[ 4], p[ 5], p[ 6], p[ 7],
a23d5117
GI
405 p[ 8], p[ 9], p[10], p[11], p[12], p[13], p[14], p[15],
406 P( 0), P( 1), P( 2), P( 3), P( 4), P( 5), P( 6), P( 7),
407 P( 8), P( 9), P(10), P(11), P(12), P(13), P(14), P(15),
408 '\n');
409#undef P
832b75ed
GG
410 pout("===== [%s] DATA END (512 Bytes) =====\n\n", name);
411}
412
413// This function provides the pretty-print reporting for SMART
414// commands: it implements the various -r "reporting" options for ATA
415// ioctls.
2127e193
GI
416int smartcommandhandler(ata_device * device, smart_command_set command, int select, char *data){
417 // TODO: Rework old stuff below
832b75ed
GG
418 // This conditional is true for commands that return data
419 int getsdata=(command==PIDENTIFY ||
420 command==IDENTIFY ||
421 command==READ_LOG ||
422 command==READ_THRESHOLDS ||
423 command==READ_VALUES ||
4d59bff9 424 command==CHECK_POWER_MODE);
832b75ed
GG
425
426 int sendsdata=(command==WRITE_LOG);
427
428 // If reporting is enabled, say what the command will be before it's executed
cfbba5b9 429 if (ata_debugmode) {
832b75ed
GG
430 // conditional is true for commands that use parameters
431 int usesparam=(command==READ_LOG ||
432 command==AUTO_OFFLINE ||
433 command==AUTOSAVE ||
434 command==IMMEDIATE_OFFLINE ||
435 command==WRITE_LOG);
436
2127e193 437 pout("\nREPORT-IOCTL: Device=%s Command=%s", device->get_dev_name(), commandstrings[command]);
832b75ed
GG
438 if (usesparam)
439 pout(" InputParameter=%d\n", select);
440 else
441 pout("\n");
442 }
443
444 if ((getsdata || sendsdata) && !data){
445 pout("REPORT-IOCTL: Unable to execute command %s : data destination address is NULL\n", commandstrings[command]);
446 return -1;
447 }
448
449 // The reporting is cleaner, and we will find coding bugs faster, if
450 // the commands that failed clearly return empty (zeroed) data
451 // structures
452 if (getsdata) {
453 if (command==CHECK_POWER_MODE)
454 data[0]=0;
455 else
456 memset(data, '\0', 512);
457 }
458
459
a37e7145 460 // if requested, pretty-print the input data structure
cfbba5b9 461 if (ata_debugmode > 1 && sendsdata)
2127e193 462 //pout("REPORT-IOCTL: Device=%s Command=%s\n", device->get_dev_name(), commandstrings[command]);
a37e7145 463 prettyprint((unsigned char *)data, commandstrings[command]);
832b75ed 464
832b75ed 465 // now execute the command
2127e193
GI
466 int retval = -1;
467 {
468 ata_cmd_in in;
469 // Set common register values
470 switch (command) {
471 default: // SMART commands
472 in.in_regs.command = ATA_SMART_CMD;
473 in.in_regs.lba_high = SMART_CYL_HI; in.in_regs.lba_mid = SMART_CYL_LOW;
474 break;
475 case IDENTIFY: case PIDENTIFY: case CHECK_POWER_MODE: // Non SMART commands
476 break;
477 }
478 // Set specific values
479 switch (command) {
480 case IDENTIFY:
481 in.in_regs.command = ATA_IDENTIFY_DEVICE;
482 in.set_data_in(data, 1);
483 break;
484 case PIDENTIFY:
485 in.in_regs.command = ATA_IDENTIFY_PACKET_DEVICE;
486 in.set_data_in(data, 1);
487 break;
488 case CHECK_POWER_MODE:
489 in.in_regs.command = ATA_CHECK_POWER_MODE;
490 in.out_needed.sector_count = true; // Powermode returned here
491 break;
492 case READ_VALUES:
493 in.in_regs.features = ATA_SMART_READ_VALUES;
494 in.set_data_in(data, 1);
495 break;
496 case READ_THRESHOLDS:
497 in.in_regs.features = ATA_SMART_READ_THRESHOLDS;
498 in.in_regs.lba_low = 1; // TODO: CORRECT ???
499 in.set_data_in(data, 1);
500 break;
501 case READ_LOG:
502 in.in_regs.features = ATA_SMART_READ_LOG_SECTOR;
503 in.in_regs.lba_low = select;
504 in.set_data_in(data, 1);
505 break;
506 case WRITE_LOG:
507 in.in_regs.features = ATA_SMART_WRITE_LOG_SECTOR;
508 in.in_regs.lba_low = select;
509 in.set_data_out(data, 1);
510 break;
511 case ENABLE:
512 in.in_regs.features = ATA_SMART_ENABLE;
513 in.in_regs.lba_low = 1; // TODO: CORRECT ???
514 break;
515 case DISABLE:
516 in.in_regs.features = ATA_SMART_DISABLE;
517 in.in_regs.lba_low = 1; // TODO: CORRECT ???
518 break;
519 case STATUS_CHECK:
520 in.out_needed.lba_high = in.out_needed.lba_mid = true; // Status returned here
521 case STATUS:
522 in.in_regs.features = ATA_SMART_STATUS;
523 break;
524 case AUTO_OFFLINE:
525 in.in_regs.features = ATA_SMART_AUTO_OFFLINE;
526 in.in_regs.sector_count = select; // Caution: Non-DATA command!
527 break;
528 case AUTOSAVE:
529 in.in_regs.features = ATA_SMART_AUTOSAVE;
530 in.in_regs.sector_count = select; // Caution: Non-DATA command!
531 break;
532 case IMMEDIATE_OFFLINE:
533 in.in_regs.features = ATA_SMART_IMMEDIATE_OFFLINE;
534 in.in_regs.lba_low = select;
535 break;
536 default:
537 pout("Unrecognized command %d in smartcommandhandler()\n"
538 "Please contact " PACKAGE_BUGREPORT "\n", command);
539 device->set_err(ENOSYS);
2127e193
GI
540 return -1;
541 }
542
cfbba5b9 543 if (ata_debugmode)
2127e193
GI
544 print_regs(" Input: ", in.in_regs,
545 (in.direction==ata_cmd_in::data_in ? " IN\n":
546 in.direction==ata_cmd_in::data_out ? " OUT\n":"\n"));
547
548 ata_cmd_out out;
e165493d
GI
549
550 int64_t start_usec = -1;
551 if (ata_debugmode)
552 start_usec = smi()->get_timer_usec();
553
2127e193
GI
554 bool ok = device->ata_pass_through(in, out);
555
e165493d
GI
556 if (start_usec >= 0) {
557 int64_t duration_usec = smi()->get_timer_usec() - start_usec;
558 if (duration_usec >= 500)
559 pout(" [Duration: %.3fs]\n", duration_usec / 1000000.0);
560 }
561
cfbba5b9 562 if (ata_debugmode && out.out_regs.is_set())
2127e193
GI
563 print_regs(" Output: ", out.out_regs);
564
565 if (ok) switch (command) {
566 default:
567 retval = 0;
568 break;
569 case CHECK_POWER_MODE:
a7e8ffec
GI
570 if (out.out_regs.sector_count.is_set()) {
571 data[0] = out.out_regs.sector_count;
572 retval = 0;
573 }
574 else {
575 pout("CHECK POWER MODE: incomplete response, ATA output registers missing\n");
576 device->set_err(ENOSYS);
577 retval = -1;
578 }
2127e193
GI
579 break;
580 case STATUS_CHECK:
581 // Cyl low and Cyl high unchanged means "Good SMART status"
582 if ((out.out_regs.lba_high == SMART_CYL_HI) &&
583 (out.out_regs.lba_mid == SMART_CYL_LOW))
584 retval = 0;
585 // These values mean "Bad SMART status"
586 else if ((out.out_regs.lba_high == SRET_STATUS_HI_EXCEEDED) &&
587 (out.out_regs.lba_mid == SRET_STATUS_MID_EXCEEDED))
588 retval = 1;
589 else if (out.out_regs.lba_mid == SMART_CYL_LOW) {
590 retval = 0;
cfbba5b9 591 if (ata_debugmode)
2127e193
GI
592 pout("SMART STATUS RETURN: half healthy response sequence, "
593 "probable SAT/USB truncation\n");
594 } else if (out.out_regs.lba_mid == SRET_STATUS_MID_EXCEEDED) {
595 retval = 1;
cfbba5b9 596 if (ata_debugmode)
2127e193
GI
597 pout("SMART STATUS RETURN: half unhealthy response sequence, "
598 "probable SAT/USB truncation\n");
a7e8ffec
GI
599 }
600 else if (!out.out_regs.is_set()) {
601 pout("SMART STATUS RETURN: incomplete response, ATA output registers missing\n");
602 device->set_err(ENOSYS);
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);
a7e8ffec 611 device->set_err(EIO);
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;
2127e193
GI
1277 pout("Span %d changed from %"PRIu64"-%"PRIu64" (%"PRIu64" sectors)\n",
1278 i, start, end, oldsize);
1279 pout(" to %"PRIu64"-%"PRIu64" (%"PRIu64" sectors) (%"PRIu64" spans)\n",
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)) {
1296 pout("Invalid selective self-test span %d: %"PRIu64"-%"PRIu64" (%"PRIu64" sectors)\n",
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);
1479
1480 for (unsigned i = 0; i < nsectors; i++) {
1481 for (unsigned j = 0; j < 4; j++)
1482 swapx(&log->error_logs[i].commands[j].timestamp);
1483 swapx(&log->error_logs[i].error.timestamp);
1484 }
1485 }
1486
ee38a438
GI
1487 if (firmwarebugs.is_set(BUG_XERRORLBA))
1488 fix_exterrlog_lba(log, nsectors);
1489
2127e193
GI
1490 return true;
1491}
1492
1493
1494int ataReadSmartThresholds (ata_device * device, struct ata_smart_thresholds_pvt *data){
832b75ed
GG
1495
1496 // get data from device
1497 if (smartcommandhandler(device, READ_THRESHOLDS, 0, (char *)data)){
832b75ed
GG
1498 return -1;
1499 }
1500
1501 // compute its checksum, and issue a warning if needed
2127e193 1502 if (checksum(data))
832b75ed
GG
1503 checksumwarning("SMART Attribute Thresholds Structure");
1504
a37e7145 1505 // swap endian order if needed
832b75ed
GG
1506 if (isbigendian())
1507 swap2((char *)&(data->revnumber));
1508
1509 return 0;
1510}
1511
2127e193 1512int ataEnableSmart (ata_device * device ){
832b75ed 1513 if (smartcommandhandler(device, ENABLE, 0, NULL)){
832b75ed
GG
1514 return -1;
1515 }
1516 return 0;
1517}
1518
2127e193 1519int ataDisableSmart (ata_device * device ){
832b75ed
GG
1520
1521 if (smartcommandhandler(device, DISABLE, 0, NULL)){
832b75ed
GG
1522 return -1;
1523 }
1524 return 0;
1525}
1526
2127e193 1527int ataEnableAutoSave(ata_device * device){
832b75ed 1528 if (smartcommandhandler(device, AUTOSAVE, 241, NULL)){
832b75ed
GG
1529 return -1;
1530 }
1531 return 0;
1532}
1533
2127e193 1534int ataDisableAutoSave(ata_device * device){
832b75ed
GG
1535
1536 if (smartcommandhandler(device, AUTOSAVE, 0, NULL)){
832b75ed
GG
1537 return -1;
1538 }
1539 return 0;
1540}
1541
1542// In *ALL* ATA standards the Enable/Disable AutoOffline command is
1543// marked "OBSOLETE". It is defined in SFF-8035i Revision 2, and most
1544// vendors still support it for backwards compatibility. IBM documents
1545// it for some drives.
2127e193 1546int ataEnableAutoOffline (ata_device * device){
832b75ed
GG
1547
1548 /* timer hard coded to 4 hours */
1549 if (smartcommandhandler(device, AUTO_OFFLINE, 248, NULL)){
832b75ed
GG
1550 return -1;
1551 }
1552 return 0;
1553}
1554
1555// Another Obsolete Command. See comments directly above, associated
1556// with the corresponding Enable command.
2127e193 1557int ataDisableAutoOffline (ata_device * device){
832b75ed
GG
1558
1559 if (smartcommandhandler(device, AUTO_OFFLINE, 0, NULL)){
832b75ed
GG
1560 return -1;
1561 }
1562 return 0;
1563}
1564
1565// If SMART is enabled, supported, and working, then this call is
1566// guaranteed to return 1, else zero. Note that it should return 1
1567// regardless of whether the disk's SMART status is 'healthy' or
1568// 'failing'.
2127e193 1569int ataDoesSmartWork(ata_device * device){
832b75ed
GG
1570 int retval=smartcommandhandler(device, STATUS, 0, NULL);
1571
1572 if (-1 == retval)
1573 return 0;
1574
1575 return 1;
1576}
1577
1578// This function uses a different interface (DRIVE_TASK) than the
1579// other commands in this file.
2127e193 1580int ataSmartStatus2(ata_device * device){
832b75ed
GG
1581 return smartcommandhandler(device, STATUS_CHECK, 0, NULL);
1582}
1583
1584// This is the way to execute ALL tests: offline, short self-test,
1585// extended self test, with and without captive mode, etc.
2127e193 1586// TODO: Move to ataprint.cpp ?
d008864d
GI
1587int ataSmartTest(ata_device * device, int testtype, bool force,
1588 const ata_selective_selftest_args & selargs,
2127e193 1589 const ata_smart_values * sv, uint64_t num_sectors)
a37e7145 1590{
2127e193 1591 char cmdmsg[128]; const char *type, *captive;
a7e8ffec 1592 int cap, retval, select=0;
832b75ed
GG
1593
1594 // Boolean, if set, says test is captive
1595 cap=testtype & CAPTIVE_MASK;
1596
1597 // Set up strings that describe the type of test
1598 if (cap)
1599 captive="captive";
1600 else
1601 captive="off-line";
1602
1603 if (testtype==OFFLINE_FULL_SCAN)
1604 type="off-line";
1605 else if (testtype==SHORT_SELF_TEST || testtype==SHORT_CAPTIVE_SELF_TEST)
1606 type="Short self-test";
1607 else if (testtype==EXTEND_SELF_TEST || testtype==EXTEND_CAPTIVE_SELF_TEST)
1608 type="Extended self-test";
1609 else if (testtype==CONVEYANCE_SELF_TEST || testtype==CONVEYANCE_CAPTIVE_SELF_TEST)
1610 type="Conveyance self-test";
1611 else if ((select=(testtype==SELECTIVE_SELF_TEST || testtype==SELECTIVE_CAPTIVE_SELF_TEST)))
1612 type="Selective self-test";
1613 else
cfbba5b9 1614 type = 0;
d008864d
GI
1615
1616 // Check whether another test is already running
1617 if (type && (sv->self_test_exec_status >> 4) == 0xf) {
1618 if (!force) {
1619 pout("Can't start self-test without aborting current test (%d0%% remaining),\n"
1620 "%srun 'smartctl -X' to abort test.\n",
1621 sv->self_test_exec_status & 0x0f,
1622 (!select ? "add '-t force' option to override, or " : ""));
1623 return -1;
1624 }
1625 }
1626 else
1627 force = false;
1628
832b75ed
GG
1629 // If doing a selective self-test, first use WRITE_LOG to write the
1630 // selective self-test log.
2127e193
GI
1631 ata_selective_selftest_args selargs_io = selargs; // filled with info about actual spans
1632 if (select && (retval = ataWriteSelectiveSelfTestLog(device, selargs_io, sv, num_sectors))) {
832b75ed
GG
1633 if (retval==-4)
1634 pout("Can't start selective self-test without aborting current test: use '-X' option to smartctl.\n");
1635 return retval;
1636 }
1637
1638 // Print ouf message that we are sending the command to test
1639 if (testtype==ABORT_SELF_TEST)
ee38a438 1640 snprintf(cmdmsg, sizeof(cmdmsg), "Abort SMART off-line mode self-test routine");
cfbba5b9 1641 else if (!type)
ee38a438 1642 snprintf(cmdmsg, sizeof(cmdmsg), "SMART EXECUTE OFF-LINE IMMEDIATE subcommand 0x%02x", testtype);
832b75ed 1643 else
ee38a438 1644 snprintf(cmdmsg, sizeof(cmdmsg), "Execute SMART %s routine immediately in %s mode", type, captive);
832b75ed
GG
1645 pout("Sending command: \"%s\".\n",cmdmsg);
1646
1647 if (select) {
1648 int i;
1649 pout("SPAN STARTING_LBA ENDING_LBA\n");
2127e193 1650 for (i = 0; i < selargs_io.num_spans; i++)
832b75ed 1651 pout(" %d %20"PRId64" %20"PRId64"\n", i,
2127e193
GI
1652 selargs_io.span[i].start,
1653 selargs_io.span[i].end);
832b75ed
GG
1654 }
1655
1656 // Now send the command to test
a7e8ffec
GI
1657 if (smartcommandhandler(device, IMMEDIATE_OFFLINE, testtype, NULL)) {
1658 if (!(cap && device->get_errno() == EIO)) {
1659 pout("Command \"%s\" failed: %s\n", cmdmsg, device->get_errmsg());
1660 return -1;
1661 }
832b75ed
GG
1662 }
1663
1664 // Since the command succeeded, tell user
1665 if (testtype==ABORT_SELF_TEST)
1666 pout("Self-testing aborted!\n");
cfbba5b9
GI
1667 else {
1668 pout("Drive command \"%s\" successful.\n", cmdmsg);
1669 if (type)
d008864d 1670 pout("Testing has begun%s.\n", (force ? " (previous test aborted)" : ""));
cfbba5b9 1671 }
832b75ed
GG
1672 return 0;
1673}
1674
1675/* Test Time Functions */
2127e193
GI
1676int TestTime(const ata_smart_values *data, int testtype)
1677{
832b75ed
GG
1678 switch (testtype){
1679 case OFFLINE_FULL_SCAN:
1680 return (int) data->total_time_to_complete_off_line;
1681 case SHORT_SELF_TEST:
1682 case SHORT_CAPTIVE_SELF_TEST:
1683 return (int) data->short_test_completion_time;
1684 case EXTEND_SELF_TEST:
1685 case EXTEND_CAPTIVE_SELF_TEST:
d008864d
GI
1686 if (data->extend_test_completion_time_b == 0xff
1687 && data->extend_test_completion_time_w != 0x0000
1688 && data->extend_test_completion_time_w != 0xffff)
1689 return data->extend_test_completion_time_w; // ATA-8
1690 else
1691 return data->extend_test_completion_time_b;
832b75ed
GG
1692 case CONVEYANCE_SELF_TEST:
1693 case CONVEYANCE_CAPTIVE_SELF_TEST:
1694 return (int) data->conveyance_test_completion_time;
1695 default:
1696 return 0;
1697 }
1698}
1699
1700// This function tells you both about the ATA error log and the
1701// self-test error log capability (introduced in ATA-5). The bit is
1702// poorly documented in the ATA/ATAPI standard. Starting with ATA-6,
1703// SMART error logging is also indicated in bit 0 of DEVICE IDENTIFY
1704// word 84 and 87. Top two bits must match the pattern 01. BEFORE
1705// ATA-6 these top two bits still had to match the pattern 01, but the
1706// remaining bits were reserved (==0).
2127e193
GI
1707int isSmartErrorLogCapable (const ata_smart_values * data, const ata_identify_device * identity)
1708{
832b75ed
GG
1709 unsigned short word84=identity->command_set_extension;
1710 unsigned short word87=identity->csf_default;
1711 int isata6=identity->major_rev_num & (0x01<<6);
1712 int isata7=identity->major_rev_num & (0x01<<7);
1713
1714 if ((isata6 || isata7) && (word84>>14) == 0x01 && (word84 & 0x01))
1715 return 1;
1716
1717 if ((isata6 || isata7) && (word87>>14) == 0x01 && (word87 & 0x01))
1718 return 1;
1719
1720 // otherwise we'll use the poorly documented capability bit
1721 return data->errorlog_capability & 0x01;
1722}
1723
1724// See previous function. If the error log exists then the self-test
1725// log should (must?) also exist.
2127e193
GI
1726int isSmartTestLogCapable (const ata_smart_values * data, const ata_identify_device *identity)
1727{
832b75ed
GG
1728 unsigned short word84=identity->command_set_extension;
1729 unsigned short word87=identity->csf_default;
1730 int isata6=identity->major_rev_num & (0x01<<6);
1731 int isata7=identity->major_rev_num & (0x01<<7);
1732
1733 if ((isata6 || isata7) && (word84>>14) == 0x01 && (word84 & 0x02))
1734 return 1;
1735
1736 if ((isata6 || isata7) && (word87>>14) == 0x01 && (word87 & 0x02))
1737 return 1;
1738
1739
1740 // otherwise we'll use the poorly documented capability bit
2127e193 1741 return data->errorlog_capability & 0x01;
832b75ed
GG
1742}
1743
1744
2127e193
GI
1745int isGeneralPurposeLoggingCapable(const ata_identify_device *identity)
1746{
832b75ed
GG
1747 unsigned short word84=identity->command_set_extension;
1748 unsigned short word87=identity->csf_default;
1749
1750 // If bit 14 of word 84 is set to one and bit 15 of word 84 is
1751 // cleared to zero, the contents of word 84 contains valid support
1752 // information. If not, support information is not valid in this
1753 // word.
1754 if ((word84>>14) == 0x01)
1755 // If bit 5 of word 84 is set to one, the device supports the
1756 // General Purpose Logging feature set.
1757 return (word84 & (0x01 << 5));
1758
1759 // If bit 14 of word 87 is set to one and bit 15 of word 87 is
1760 // cleared to zero, the contents of words (87:85) contain valid
1761 // information. If not, information is not valid in these words.
1762 if ((word87>>14) == 0x01)
1763 // If bit 5 of word 87 is set to one, the device supports
1764 // the General Purpose Logging feature set.
1765 return (word87 & (0x01 << 5));
1766
1767 // not capable
1768 return 0;
1769}
1770
1771
1772// SMART self-test capability is also indicated in bit 1 of DEVICE
1773// IDENTIFY word 87 (if top two bits of word 87 match pattern 01).
1774// However this was only introduced in ATA-6 (but self-test log was in
1775// ATA-5).
2127e193
GI
1776int isSupportExecuteOfflineImmediate(const ata_smart_values *data)
1777{
1778 return data->offline_data_collection_capability & 0x01;
832b75ed 1779}
2127e193 1780
832b75ed
GG
1781// Note in the ATA-5 standard, the following bit is listed as "Vendor
1782// Specific". So it may not be reliable. The only use of this that I
1783// have found is in IBM drives, where it is well-documented. See for
1784// example page 170, section 13.32.1.18 of the IBM Travelstar 40GNX
1785// hard disk drive specifications page 164 Revision 1.1 22 Apr 2002.
2127e193
GI
1786int isSupportAutomaticTimer(const ata_smart_values * data)
1787{
1788 return data->offline_data_collection_capability & 0x02;
832b75ed 1789}
2127e193
GI
1790int isSupportOfflineAbort(const ata_smart_values *data)
1791{
1792 return data->offline_data_collection_capability & 0x04;
832b75ed 1793}
2127e193
GI
1794int isSupportOfflineSurfaceScan(const ata_smart_values * data)
1795{
832b75ed
GG
1796 return data->offline_data_collection_capability & 0x08;
1797}
2127e193
GI
1798int isSupportSelfTest (const ata_smart_values * data)
1799{
832b75ed
GG
1800 return data->offline_data_collection_capability & 0x10;
1801}
2127e193
GI
1802int isSupportConveyanceSelfTest(const ata_smart_values * data)
1803{
832b75ed
GG
1804 return data->offline_data_collection_capability & 0x20;
1805}
2127e193
GI
1806int isSupportSelectiveSelfTest(const ata_smart_values * data)
1807{
832b75ed
GG
1808 return data->offline_data_collection_capability & 0x40;
1809}
1810
bed94269
GI
1811// Get attribute state
1812ata_attr_state ata_get_attr_state(const ata_smart_attribute & attr,
cfbba5b9
GI
1813 int attridx,
1814 const ata_smart_threshold_entry * thresholds,
1815 const ata_vendor_attr_defs & defs,
1816 unsigned char * threshval /* = 0 */)
bed94269
GI
1817{
1818 if (!attr.id)
1819 return ATTRSTATE_NON_EXISTING;
832b75ed 1820
bed94269
GI
1821 // Normalized values (current,worst,threshold) not valid
1822 // if specified by '-v' option.
1823 // (Some SSD disks uses these bytes to store raw value).
1824 if (defs[attr.id].flags & ATTRFLAG_NO_NORMVAL)
1825 return ATTRSTATE_NO_NORMVAL;
832b75ed 1826
cfbba5b9
GI
1827 // Normally threshold is at same index as attribute
1828 int i = attridx;
1829 if (thresholds[i].id != attr.id) {
1830 // Find threshold id in table
1831 for (i = 0; thresholds[i].id != attr.id; ) {
1832 if (++i >= NUMBER_ATA_SMART_ATTRIBUTES)
1833 // Threshold id missing or thresholds cannot be read
1834 return ATTRSTATE_NO_THRESHOLD;
1835 }
1836 }
1837 unsigned char threshold = thresholds[i].threshold;
832b75ed 1838
cfbba5b9
GI
1839 // Return threshold if requested
1840 if (threshval)
1841 *threshval = threshold;
832b75ed 1842
bed94269
GI
1843 // Don't report a failed attribute if its threshold is 0.
1844 // ATA-3 (X3T13/2008D Revision 7b) declares 0x00 as the "always passing"
1845 // threshold (Later ATA versions declare all thresholds as "obsolete").
1846 // In practice, threshold value 0 is often used for usage attributes.
cfbba5b9 1847 if (!threshold)
bed94269 1848 return ATTRSTATE_OK;
832b75ed 1849
bed94269 1850 // Failed now if current value is below threshold
cfbba5b9 1851 if (attr.current <= threshold)
bed94269 1852 return ATTRSTATE_FAILED_NOW;
832b75ed 1853
a23d5117 1854 // Failed in the past if worst value is below threshold
cfbba5b9 1855 if (!(defs[attr.id].flags & ATTRFLAG_NO_WORSTVAL) && attr.worst <= threshold)
bed94269 1856 return ATTRSTATE_FAILED_PAST;
832b75ed 1857
bed94269 1858 return ATTRSTATE_OK;
832b75ed
GG
1859}
1860
bed94269
GI
1861// Get default raw value print format
1862static ata_attr_raw_format get_default_raw_format(unsigned char id)
a37e7145 1863{
bed94269
GI
1864 switch (id) {
1865 case 3: // Spin-up time
1866 return RAWFMT_RAW16_OPT_AVG16;
a37e7145 1867
bed94269
GI
1868 case 5: // Reallocated sector count
1869 case 196: // Reallocated event count
1870 return RAWFMT_RAW16_OPT_RAW16;
1871
e165493d
GI
1872 case 9: // Power on hours
1873 return RAWFMT_RAW24_OPT_RAW8;
1874
bed94269
GI
1875 case 190: // Temperature
1876 case 194:
1877 return RAWFMT_TEMPMINMAX;
1878
1879 default:
1880 return RAWFMT_RAW48;
a37e7145 1881 }
bed94269
GI
1882}
1883
1884// Get attribute raw value.
1885uint64_t ata_get_attr_raw_value(const ata_smart_attribute & attr,
1886 const ata_vendor_attr_defs & defs)
1887{
a23d5117
GI
1888 const ata_vendor_attr_defs::entry & def = defs[attr.id];
1889
1890 // Use default byteorder if not specified
1891 const char * byteorder = def.byteorder;
1892 if (!*byteorder) {
cfbba5b9
GI
1893 switch (def.raw_format) {
1894 case RAWFMT_RAW64:
1895 case RAWFMT_HEX64:
1896 byteorder = "543210wv"; break;
e165493d
GI
1897 case RAWFMT_RAW56:
1898 case RAWFMT_HEX56:
cfbba5b9
GI
1899 case RAWFMT_RAW24_DIV_RAW32:
1900 case RAWFMT_MSEC24_HOUR32:
1901 byteorder = "r543210"; break;
1902 default:
1903 byteorder = "543210"; break;
1904 }
a23d5117
GI
1905 }
1906
1907 // Build 64-bit value from selected bytes
1908 uint64_t rawvalue = 0;
1909 for (int i = 0; byteorder[i]; i++) {
1910 unsigned char b;
1911 switch (byteorder[i]) {
1912 case '0': b = attr.raw[0]; break;
1913 case '1': b = attr.raw[1]; break;
1914 case '2': b = attr.raw[2]; break;
1915 case '3': b = attr.raw[3]; break;
1916 case '4': b = attr.raw[4]; break;
1917 case '5': b = attr.raw[5]; break;
1918 case 'r': b = attr.reserv; break;
1919 case 'v': b = attr.current; break;
1920 case 'w': b = attr.worst; break;
1921 default : b = 0; break;
1922 }
1923 rawvalue <<= 8; rawvalue |= b;
a37e7145 1924 }
a23d5117 1925
bed94269 1926 return rawvalue;
a37e7145
GG
1927}
1928
1929
bed94269
GI
1930// Format attribute raw value.
1931std::string ata_format_attr_raw_value(const ata_smart_attribute & attr,
1932 const ata_vendor_attr_defs & defs)
1933{
a23d5117 1934 // Get 48 bit or 64 bit raw value
bed94269 1935 uint64_t rawvalue = ata_get_attr_raw_value(attr, defs);
832b75ed 1936
a7e8ffec
GI
1937 // Split into bytes and words
1938 unsigned char raw[6];
1939 raw[0] = (unsigned char) rawvalue;
1940 raw[1] = (unsigned char)(rawvalue >> 8);
1941 raw[2] = (unsigned char)(rawvalue >> 16);
1942 raw[3] = (unsigned char)(rawvalue >> 24);
1943 raw[4] = (unsigned char)(rawvalue >> 32);
1944 raw[5] = (unsigned char)(rawvalue >> 40);
832b75ed 1945 unsigned word[3];
bed94269
GI
1946 word[0] = raw[0] | (raw[1] << 8);
1947 word[1] = raw[2] | (raw[3] << 8);
1948 word[2] = raw[4] | (raw[5] << 8);
832b75ed 1949
bed94269
GI
1950 // Get print format
1951 ata_attr_raw_format format = defs[attr.id].raw_format;
1952 if (format == RAWFMT_DEFAULT)
1953 format = get_default_raw_format(attr.id);
1954
1955 // Print
1956 std::string s;
1957 switch (format) {
1958 case RAWFMT_RAW8:
1959 s = strprintf("%d %d %d %d %d %d",
1960 raw[5], raw[4], raw[3], raw[2], raw[1], raw[0]);
832b75ed 1961 break;
bed94269
GI
1962
1963 case RAWFMT_RAW16:
1964 s = strprintf("%u %u %u", word[2], word[1], word[0]);
1965 break;
1966
1967 case RAWFMT_RAW48:
e165493d 1968 case RAWFMT_RAW56:
a23d5117 1969 case RAWFMT_RAW64:
bed94269
GI
1970 s = strprintf("%"PRIu64, rawvalue);
1971 break;
1972
1973 case RAWFMT_HEX48:
1974 s = strprintf("0x%012"PRIx64, rawvalue);
1975 break;
1976
e165493d
GI
1977 case RAWFMT_HEX56:
1978 s = strprintf("0x%014"PRIx64, rawvalue);
1979 break;
1980
bed94269
GI
1981 case RAWFMT_HEX64:
1982 s = strprintf("0x%016"PRIx64, rawvalue);
1983 break;
1984
1985 case RAWFMT_RAW16_OPT_RAW16:
1986 s = strprintf("%u", word[0]);
2127e193 1987 if (word[1] || word[2])
e165493d 1988 s += strprintf(" (%u %u)", word[2], word[1]);
2127e193 1989 break;
bed94269
GI
1990
1991 case RAWFMT_RAW16_OPT_AVG16:
1992 s = strprintf("%u", word[0]);
1993 if (word[1])
1994 s += strprintf(" (Average %u)", word[1]);
1995 break;
1996
e165493d
GI
1997 case RAWFMT_RAW24_OPT_RAW8:
1998 s = strprintf("%u", (unsigned)(rawvalue & 0x00ffffffULL));
1999 if (raw[3] || raw[4] || raw[5])
2000 s += strprintf(" (%d %d %d)", raw[5], raw[4], raw[3]);
2001 break;
2002
cfbba5b9
GI
2003 case RAWFMT_RAW24_DIV_RAW24:
2004 s = strprintf("%u/%u",
2005 (unsigned)(rawvalue >> 24), (unsigned)(rawvalue & 0x00ffffffULL));
2006 break;
2007
2008 case RAWFMT_RAW24_DIV_RAW32:
2009 s = strprintf("%u/%u",
2010 (unsigned)(rawvalue >> 32), (unsigned)(rawvalue & 0xffffffffULL));
bed94269
GI
2011 break;
2012
2013 case RAWFMT_MIN2HOUR:
2014 {
832b75ed 2015 // minutes
bed94269
GI
2016 int64_t temp = word[0]+(word[1]<<16);
2017 int64_t tmp1 = temp/60;
2018 int64_t tmp2 = temp%60;
2019 s = strprintf("%"PRIu64"h+%02"PRIu64"m", tmp1, tmp2);
2127e193 2020 if (word[2])
bed94269 2021 s += strprintf(" (%u)", word[2]);
832b75ed 2022 }
bed94269
GI
2023 break;
2024
2025 case RAWFMT_SEC2HOUR:
2026 {
832b75ed 2027 // seconds
bed94269
GI
2028 int64_t hours = rawvalue/3600;
2029 int64_t minutes = (rawvalue-3600*hours)/60;
2030 int64_t seconds = rawvalue%60;
2031 s = strprintf("%"PRIu64"h+%02"PRIu64"m+%02"PRIu64"s", hours, minutes, seconds);
832b75ed 2032 }
a37e7145 2033 break;
bed94269
GI
2034
2035 case RAWFMT_HALFMIN2HOUR:
2036 {
2037 // 30-second counter
2038 int64_t hours = rawvalue/120;
2039 int64_t minutes = (rawvalue-120*hours)/2;
2040 s += strprintf("%"PRIu64"h+%02"PRIu64"m", hours, minutes);
832b75ed 2041 }
832b75ed 2042 break;
bed94269 2043
cfbba5b9
GI
2044 case RAWFMT_MSEC24_HOUR32:
2045 {
2046 // hours + milliseconds
2047 unsigned hours = (unsigned)(rawvalue & 0xffffffffULL);
2048 unsigned milliseconds = (unsigned)(rawvalue >> 32);
2049 unsigned seconds = milliseconds / 1000;
2050 s = strprintf("%uh+%02um+%02u.%03us",
2051 hours, seconds / 60, seconds % 60, milliseconds % 1000);
2052 }
2053 break;
2054
bed94269 2055 case RAWFMT_TEMPMINMAX:
832b75ed 2056 // Temperature
d008864d
GI
2057 {
2058 // Search for possible min/max values
2059 // 00 HH 00 LL 00 TT (Hitachi/IBM)
2060 // 00 00 HH LL 00 TT (Maxtor, Samsung)
2061 // 00 00 00 HH LL TT (WDC)
2062 unsigned char lo = 0, hi = 0;
2063 int cnt = 0;
2064 for (int i = 1; i < 6; i++) {
2065 if (raw[i])
2066 switch (cnt++) {
2067 case 0:
2068 lo = raw[i];
2069 break;
2070 case 1:
2071 if (raw[i] < lo) {
2072 hi = lo; lo = raw[i];
2073 }
2074 else
2075 hi = raw[i];
2076 break;
2077 }
bed94269 2078 }
d008864d
GI
2079
2080 unsigned char t = raw[0];
2081 if (cnt == 0)
2082 s = strprintf("%d", t);
2083 else if (cnt == 2 && 0 < lo && lo <= t && t <= hi && hi < 128)
2084 s = strprintf("%d (Min/Max %d/%d)", t, lo, hi);
bed94269 2085 else
d008864d 2086 s = strprintf("%d (%d %d %d %d %d)", t, raw[5], raw[4], raw[3], raw[2], raw[1]);
832b75ed 2087 }
832b75ed 2088 break;
bed94269
GI
2089
2090 case RAWFMT_TEMP10X:
2091 // ten times temperature in Celsius
2092 s = strprintf("%d.%d", word[0]/10, word[0]%10);
2127e193 2093 break;
bed94269 2094
832b75ed 2095 default:
bed94269
GI
2096 s = "?"; // Should not happen
2097 break;
832b75ed 2098 }
832b75ed 2099
bed94269
GI
2100 return s;
2101}
832b75ed 2102
bed94269
GI
2103// Attribute names shouldn't be longer than 23 chars, otherwise they break the
2104// output of smartctl.
ee38a438 2105static const char * get_default_attr_name(unsigned char id, int rpm)
bed94269 2106{
ee38a438
GI
2107 bool hdd = (rpm > 1), ssd = (rpm == 1);
2108
2109 static const char Unknown_HDD_Attribute[] = "Unknown_HDD_Attribute";
2110 static const char Unknown_SSD_Attribute[] = "Unknown_SSD_Attribute";
2111
bed94269 2112 switch (id) {
832b75ed 2113 case 1:
bed94269 2114 return "Raw_Read_Error_Rate";
832b75ed 2115 case 2:
bed94269 2116 return "Throughput_Performance";
832b75ed 2117 case 3:
bed94269 2118 return "Spin_Up_Time";
832b75ed 2119 case 4:
bed94269 2120 return "Start_Stop_Count";
832b75ed 2121 case 5:
bed94269 2122 return "Reallocated_Sector_Ct";
832b75ed 2123 case 6:
ee38a438 2124 if (ssd) return Unknown_SSD_Attribute;
bed94269 2125 return "Read_Channel_Margin";
832b75ed 2126 case 7:
ee38a438 2127 if (ssd) return Unknown_SSD_Attribute;
bed94269 2128 return "Seek_Error_Rate";
832b75ed 2129 case 8:
ee38a438 2130 if (ssd) return Unknown_SSD_Attribute;
bed94269 2131 return "Seek_Time_Performance";
832b75ed 2132 case 9:
bed94269 2133 return "Power_On_Hours";
832b75ed 2134 case 10:
ee38a438 2135 if (ssd) return Unknown_SSD_Attribute;
bed94269 2136 return "Spin_Retry_Count";
832b75ed 2137 case 11:
ee38a438 2138 if (ssd) return Unknown_SSD_Attribute;
bed94269 2139 return "Calibration_Retry_Count";
832b75ed 2140 case 12:
bed94269 2141 return "Power_Cycle_Count";
832b75ed 2142 case 13:
bed94269 2143 return "Read_Soft_Error_Rate";
eb07ddf2 2144 case 175:
ee38a438 2145 if (hdd) return Unknown_HDD_Attribute;
bed94269 2146 return "Program_Fail_Count_Chip";
eb07ddf2 2147 case 176:
ee38a438 2148 if (hdd) return Unknown_HDD_Attribute;
bed94269 2149 return "Erase_Fail_Count_Chip";
eb07ddf2 2150 case 177:
ee38a438 2151 if (hdd) return Unknown_HDD_Attribute;
bed94269 2152 return "Wear_Leveling_Count";
2127e193 2153 case 178:
ee38a438 2154 if (hdd) return Unknown_HDD_Attribute;
bed94269 2155 return "Used_Rsvd_Blk_Cnt_Chip";
2127e193 2156 case 179:
ee38a438 2157 if (hdd) return Unknown_HDD_Attribute;
bed94269 2158 return "Used_Rsvd_Blk_Cnt_Tot";
2127e193 2159 case 180:
ee38a438 2160 if (hdd) return Unknown_HDD_Attribute;
bed94269 2161 return "Unused_Rsvd_Blk_Cnt_Tot";
eb07ddf2 2162 case 181:
bed94269 2163 return "Program_Fail_Cnt_Total";
eb07ddf2 2164 case 182:
ee38a438 2165 if (hdd) return Unknown_HDD_Attribute;
bed94269 2166 return "Erase_Fail_Count_Total";
2127e193 2167 case 183:
bed94269 2168 return "Runtime_Bad_Block";
eb07ddf2 2169 case 184:
bed94269 2170 return "End-to-End_Error";
a37e7145 2171 case 187:
bed94269 2172 return "Reported_Uncorrect";
eb07ddf2 2173 case 188:
bed94269 2174 return "Command_Timeout";
a37e7145 2175 case 189:
ee38a438 2176 if (ssd) return Unknown_SSD_Attribute;
bed94269 2177 return "High_Fly_Writes";
4d59bff9
GG
2178 case 190:
2179 // Western Digital uses this for temperature.
2180 // It's identical to Attribute 194 except that it
2181 // has a failure threshold set to correspond to the
2182 // max allowed operating temperature of the drive, which
2183 // is typically 55C. So if this attribute has failed
2184 // in the past, it indicates that the drive temp exceeded
2185 // 55C sometime in the past.
bed94269 2186 return "Airflow_Temperature_Cel";
832b75ed 2187 case 191:
ee38a438 2188 if (ssd) return Unknown_SSD_Attribute;
bed94269 2189 return "G-Sense_Error_Rate";
832b75ed 2190 case 192:
bed94269 2191 return "Power-Off_Retract_Count";
832b75ed 2192 case 193:
ee38a438 2193 if (ssd) return Unknown_SSD_Attribute;
bed94269 2194 return "Load_Cycle_Count";
832b75ed 2195 case 194:
bed94269 2196 return "Temperature_Celsius";
832b75ed 2197 case 195:
bed94269
GI
2198 // Fujitsu: "ECC_On_The_Fly_Count";
2199 return "Hardware_ECC_Recovered";
832b75ed 2200 case 196:
bed94269 2201 return "Reallocated_Event_Count";
832b75ed 2202 case 197:
bed94269 2203 return "Current_Pending_Sector";
832b75ed 2204 case 198:
bed94269 2205 return "Offline_Uncorrectable";
832b75ed 2206 case 199:
bed94269 2207 return "UDMA_CRC_Error_Count";
832b75ed 2208 case 200:
ee38a438 2209 if (ssd) return Unknown_SSD_Attribute;
bed94269
GI
2210 // Western Digital
2211 return "Multi_Zone_Error_Rate";
832b75ed 2212 case 201:
ee38a438 2213 if (ssd) return Unknown_SSD_Attribute;
bed94269 2214 return "Soft_Read_Error_Rate";
832b75ed 2215 case 202:
ee38a438 2216 if (ssd) return Unknown_SSD_Attribute;
bed94269
GI
2217 // Fujitsu: "TA_Increase_Count"
2218 return "Data_Address_Mark_Errs";
832b75ed
GG
2219 case 203:
2220 // Fujitsu
bed94269 2221 return "Run_Out_Cancel";
832b75ed 2222 // Maxtor: ECC Errors
832b75ed 2223 case 204:
bed94269
GI
2224 // Fujitsu: "Shock_Count_Write_Opern"
2225 return "Soft_ECC_Correction";
832b75ed 2226 case 205:
bed94269
GI
2227 // Fujitsu: "Shock_Rate_Write_Opern"
2228 return "Thermal_Asperity_Rate";
832b75ed
GG
2229 case 206:
2230 // Fujitsu
ee38a438 2231 if (ssd) return Unknown_SSD_Attribute;
bed94269 2232 return "Flying_Height";
832b75ed
GG
2233 case 207:
2234 // Maxtor
ee38a438 2235 if (ssd) return Unknown_SSD_Attribute;
bed94269 2236 return "Spin_High_Current";
832b75ed
GG
2237 case 208:
2238 // Maxtor
ee38a438 2239 if (ssd) return Unknown_SSD_Attribute;
bed94269 2240 return "Spin_Buzz";
832b75ed
GG
2241 case 209:
2242 // Maxtor
ee38a438 2243 if (ssd) return Unknown_SSD_Attribute;
bed94269 2244 return "Offline_Seek_Performnce";
832b75ed 2245 case 220:
ee38a438 2246 if (ssd) return Unknown_SSD_Attribute;
bed94269 2247 return "Disk_Shift";
832b75ed 2248 case 221:
ee38a438 2249 if (ssd) return Unknown_SSD_Attribute;
bed94269 2250 return "G-Sense_Error_Rate";
832b75ed 2251 case 222:
ee38a438 2252 if (ssd) return Unknown_SSD_Attribute;
bed94269 2253 return "Loaded_Hours";
832b75ed 2254 case 223:
ee38a438 2255 if (ssd) return Unknown_SSD_Attribute;
bed94269 2256 return "Load_Retry_Count";
832b75ed 2257 case 224:
ee38a438 2258 if (ssd) return Unknown_SSD_Attribute;
bed94269 2259 return "Load_Friction";
832b75ed 2260 case 225:
ee38a438 2261 if (ssd) return Unknown_SSD_Attribute;
bed94269 2262 return "Load_Cycle_Count";
832b75ed 2263 case 226:
ee38a438 2264 if (ssd) return Unknown_SSD_Attribute;
bed94269 2265 return "Load-in_Time";
832b75ed 2266 case 227:
ee38a438 2267 if (ssd) return Unknown_SSD_Attribute;
bed94269 2268 return "Torq-amp_Count";
832b75ed 2269 case 228:
bed94269 2270 return "Power-off_Retract_Count";
832b75ed
GG
2271 case 230:
2272 // seen in IBM DTPA-353750
ee38a438 2273 if (ssd) return Unknown_SSD_Attribute;
bed94269 2274 return "Head_Amplitude";
832b75ed 2275 case 231:
bed94269
GI
2276 return "Temperature_Celsius";
2277 case 232:
2278 // seen in Intel X25-E SSD
2279 return "Available_Reservd_Space";
2280 case 233:
2281 // seen in Intel X25-E SSD
ee38a438 2282 if (hdd) return Unknown_HDD_Attribute;
bed94269 2283 return "Media_Wearout_Indicator";
832b75ed 2284 case 240:
ee38a438 2285 if (ssd) return Unknown_SSD_Attribute;
bed94269
GI
2286 return "Head_Flying_Hours";
2287 case 241:
2288 return "Total_LBAs_Written";
2289 case 242:
2290 return "Total_LBAs_Read";
832b75ed 2291 case 250:
bed94269
GI
2292 return "Read_Error_Retry_Rate";
2293 case 254:
ee38a438 2294 if (ssd) return Unknown_SSD_Attribute;
bed94269 2295 return "Free_Fall_Sensor";
832b75ed 2296 default:
bed94269 2297 return "Unknown_Attribute";
832b75ed 2298 }
832b75ed
GG
2299}
2300
bed94269 2301// Get attribute name
ee38a438
GI
2302std::string ata_get_smart_attr_name(unsigned char id, const ata_vendor_attr_defs & defs,
2303 int rpm /* = 0 */)
2127e193 2304{
bed94269
GI
2305 if (!defs[id].name.empty())
2306 return defs[id].name;
2307 else
ee38a438 2308 return get_default_attr_name(id, rpm);
bed94269
GI
2309}
2310
2311// Find attribute index for attribute id, -1 if not found.
2312int ata_find_attr_index(unsigned char id, const ata_smart_values & smartval)
2313{
2314 if (!id)
832b75ed 2315 return -1;
2127e193 2316 for (int i = 0; i < NUMBER_ATA_SMART_ATTRIBUTES; i++) {
bed94269
GI
2317 if (smartval.vendor_attributes[i].id == id)
2318 return i;
2319 }
832b75ed
GG
2320 return -1;
2321}
2322
4d59bff9
GG
2323// Return Temperature Attribute raw value selected according to possible
2324// non-default interpretations. If the Attribute does not exist, return 0
bed94269 2325unsigned char ata_return_temperature_value(const ata_smart_values * data, const ata_vendor_attr_defs & defs)
2127e193 2326{
ee38a438
GI
2327 for (int i = 0; i < 4; i++) {
2328 static const unsigned char ids[4] = {194, 190, 9, 220};
4d59bff9 2329 unsigned char id = ids[i];
bed94269 2330 const ata_attr_raw_format format = defs[id].raw_format;
ee38a438 2331 if (!( ((id == 194 || id == 190) && format == RAWFMT_DEFAULT)
bed94269 2332 || format == RAWFMT_TEMPMINMAX || format == RAWFMT_TEMP10X))
4d59bff9 2333 continue;
bed94269
GI
2334 int idx = ata_find_attr_index(id, *data);
2335 if (idx < 0)
4d59bff9 2336 continue;
bed94269 2337 uint64_t raw = ata_get_attr_raw_value(data->vendor_attributes[idx], defs);
d008864d
GI
2338 unsigned temp;
2339 // ignore possible min/max values in high words
bed94269 2340 if (format == RAWFMT_TEMP10X) // -v N,temp10x
d008864d
GI
2341 temp = ((unsigned short)raw + 5) / 10;
2342 else
2343 temp = (unsigned char)raw;
2344 if (!(0 < temp && temp < 128))
4d59bff9
GG
2345 continue;
2346 return temp;
2347 }
2348 // No valid attribute found
2349 return 0;
2350}
a37e7145 2351
2127e193 2352
a37e7145 2353// Read SCT Status
2127e193 2354int ataReadSCTStatus(ata_device * device, ata_sct_status_response * sts)
a37e7145
GG
2355{
2356 // read SCT status via SMART log 0xe0
2357 memset(sts, 0, sizeof(*sts));
2358 if (smartcommandhandler(device, READ_LOG, 0xe0, (char *)sts)){
ee38a438 2359 pout("Read SCT Status failed: %s\n", device->get_errmsg());
a37e7145
GG
2360 return -1;
2361 }
2362
2363 // swap endian order if needed
2364 if (isbigendian()){
2365 swapx(&sts->format_version);
2366 swapx(&sts->sct_version);
2367 swapx(&sts->sct_spec);
2368 swapx(&sts->ext_status_code);
2369 swapx(&sts->action_code);
2370 swapx(&sts->function_code);
2371 swapx(&sts->over_limit_count);
2372 swapx(&sts->under_limit_count);
2373 }
2374
2375 // Check format version
2376 if (!(sts->format_version == 2 || sts->format_version == 3)) {
ee38a438 2377 pout("Unknown SCT Status format version %u, should be 2 or 3.\n", sts->format_version);
a37e7145
GG
2378 return -1;
2379 }
2380 return 0;
2381}
2382
2383// Read SCT Temperature History Table and Status
2127e193 2384int ataReadSCTTempHist(ata_device * device, ata_sct_temperature_history_table * tmh,
a37e7145
GG
2385 ata_sct_status_response * sts)
2386{
2387 // Check initial status
2388 if (ataReadSCTStatus(device, sts))
2389 return -1;
2390
2391 // Do nothing if other SCT command is executing
2392 if (sts->ext_status_code == 0xffff) {
2393 pout("Another SCT command is executing, abort Read Data Table\n"
2394 "(SCT ext_status_code 0x%04x, action_code=%u, function_code=%u)\n",
2395 sts->ext_status_code, sts->action_code, sts->function_code);
2396 return -1;
2397 }
2398
2399 ata_sct_data_table_command cmd; memset(&cmd, 0, sizeof(cmd));
2400 // CAUTION: DO NOT CHANGE THIS VALUE (SOME ACTION CODES MAY ERASE DISK)
2401 cmd.action_code = 5; // Data table command
2402 cmd.function_code = 1; // Read table
2403 cmd.table_id = 2; // Temperature History Table
2404
7f0798ef
GI
2405 // swap endian order if needed
2406 if (isbigendian()) {
2407 swapx(&cmd.action_code);
2408 swapx(&cmd.function_code);
2409 swapx(&cmd.table_id);
2410 }
2411
a37e7145
GG
2412 // write command via SMART log page 0xe0
2413 if (smartcommandhandler(device, WRITE_LOG, 0xe0, (char *)&cmd)){
ee38a438 2414 pout("Write SCT Data Table failed: %s\n", device->get_errmsg());
a37e7145
GG
2415 return -1;
2416 }
2417
2418 // read SCT data via SMART log page 0xe1
2419 memset(tmh, 0, sizeof(*tmh));
2420 if (smartcommandhandler(device, READ_LOG, 0xe1, (char *)tmh)){
ee38a438 2421 pout("Read SCT Data Table failed: %s\n", device->get_errmsg());
a37e7145
GG
2422 return -1;
2423 }
2424
2425 // re-read and check SCT status
2426 if (ataReadSCTStatus(device, sts))
2427 return -1;
2428
2429 if (!(sts->ext_status_code == 0 && sts->action_code == 5 && sts->function_code == 1)) {
ee38a438 2430 pout("Unexpected SCT status 0x%04x (action_code=%u, function_code=%u)\n",
a37e7145
GG
2431 sts->ext_status_code, sts->action_code, sts->function_code);
2432 return -1;
2433 }
2434
2435 // swap endian order if needed
2436 if (isbigendian()){
2437 swapx(&tmh->format_version);
2438 swapx(&tmh->sampling_period);
2439 swapx(&tmh->interval);
ee38a438
GI
2440 swapx(&tmh->cb_index);
2441 swapx(&tmh->cb_size);
a37e7145
GG
2442 }
2443 return 0;
2444}
2445
2446// Set SCT Temperature Logging Interval
2127e193 2447int ataSetSCTTempInterval(ata_device * device, unsigned interval, bool persistent)
a37e7145
GG
2448{
2449 // Check initial status
2450 ata_sct_status_response sts;
2451 if (ataReadSCTStatus(device, &sts))
2452 return -1;
2453
2454 // Do nothing if other SCT command is executing
2455 if (sts.ext_status_code == 0xffff) {
2456 pout("Another SCT command is executing, abort Feature Control\n"
2457 "(SCT ext_status_code 0x%04x, action_code=%u, function_code=%u)\n",
2458 sts.ext_status_code, sts.action_code, sts.function_code);
2459 return -1;
2460 }
2461
2462 ata_sct_feature_control_command cmd; memset(&cmd, 0, sizeof(cmd));
2463 // CAUTION: DO NOT CHANGE THIS VALUE (SOME ACTION CODES MAY ERASE DISK)
2464 cmd.action_code = 4; // Feature Control command
2465 cmd.function_code = 1; // Set state
2466 cmd.feature_code = 3; // Temperature logging interval
2467 cmd.state = interval;
2468 cmd.option_flags = (persistent ? 0x01 : 0x00);
2469
7f0798ef
GI
2470 // swap endian order if needed
2471 if (isbigendian()) {
2472 swapx(&cmd.action_code);
2473 swapx(&cmd.function_code);
2474 swapx(&cmd.feature_code);
2475 swapx(&cmd.state);
2476 swapx(&cmd.option_flags);
2477 }
2478
a37e7145
GG
2479 // write command via SMART log page 0xe0
2480 if (smartcommandhandler(device, WRITE_LOG, 0xe0, (char *)&cmd)){
ee38a438 2481 pout("Write SCT Feature Control Command failed: %s\n", device->get_errmsg());
a37e7145
GG
2482 return -1;
2483 }
2484
2485 // re-read and check SCT status
2486 if (ataReadSCTStatus(device, &sts))
2487 return -1;
2488
2489 if (!(sts.ext_status_code == 0 && sts.action_code == 4 && sts.function_code == 1)) {
ee38a438 2490 pout("Unexpected SCT status 0x%04x (action_code=%u, function_code=%u)\n",
a37e7145
GG
2491 sts.ext_status_code, sts.action_code, sts.function_code);
2492 return -1;
2493 }
2494 return 0;
2495}
2496
7f0798ef
GI
2497// Get/Set SCT Error Recovery Control
2498static int ataGetSetSCTErrorRecoveryControltime(ata_device * device, unsigned type,
2499 bool set, unsigned short & time_limit)
2500{
2501 // Check initial status
2502 ata_sct_status_response sts;
2503 if (ataReadSCTStatus(device, &sts))
2504 return -1;
2505
2506 // Do nothing if other SCT command is executing
2507 if (sts.ext_status_code == 0xffff) {
2508 pout("Another SCT command is executing, abort Error Recovery Control\n"
2509 "(SCT ext_status_code 0x%04x, action_code=%u, function_code=%u)\n",
2510 sts.ext_status_code, sts.action_code, sts.function_code);
2511 return -1;
2512 }
2513
2514 ata_sct_error_recovery_control_command cmd; memset(&cmd, 0, sizeof(cmd));
2515 // CAUTION: DO NOT CHANGE THIS VALUE (SOME ACTION CODES MAY ERASE DISK)
2516 cmd.action_code = 3; // Error Recovery Control command
2517 cmd.function_code = (set ? 1 : 2); // 1=Set timer, 2=Get timer
2518 cmd.selection_code = type; // 1=Read timer, 2=Write timer
2519 if (set)
2520 cmd.time_limit = time_limit;
2521
2522 // swap endian order if needed
2523 if (isbigendian()) {
2524 swapx(&cmd.action_code);
2525 swapx(&cmd.function_code);
2526 swapx(&cmd.selection_code);
2527 swapx(&cmd.time_limit);
2528 }
2529
2530 // write command via SMART log page 0xe0
2531 // TODO: Debug output
2532 ata_cmd_in in;
2533 in.in_regs.command = ATA_SMART_CMD;
2534 in.in_regs.lba_high = SMART_CYL_HI; in.in_regs.lba_mid = SMART_CYL_LOW;
2535 in.in_regs.features = ATA_SMART_WRITE_LOG_SECTOR;
2536 in.in_regs.lba_low = 0xe0;
2537 in.set_data_out(&cmd, 1);
2538
2539 if (!set)
2540 // Time limit returned in ATA registers
2541 in.out_needed.sector_count = in.out_needed.lba_low = true;
2542
2543 ata_cmd_out out;
2544 if (!device->ata_pass_through(in, out)) {
ee38a438 2545 pout("Write SCT (%cet) Error Recovery Control Command failed: %s\n",
cfbba5b9 2546 (!set ? 'G' : 'S'), device->get_errmsg());
7f0798ef
GI
2547 return -1;
2548 }
2549
2550 // re-read and check SCT status
2551 if (ataReadSCTStatus(device, &sts))
2552 return -1;
2553
2554 if (!(sts.ext_status_code == 0 && sts.action_code == 3 && sts.function_code == (set ? 1 : 2))) {
ee38a438 2555 pout("Unexpected SCT status 0x%04x (action_code=%u, function_code=%u)\n",
7f0798ef
GI
2556 sts.ext_status_code, sts.action_code, sts.function_code);
2557 return -1;
2558 }
2559
2560 if (!set) {
2561 // Check whether registers are properly returned by ioctl()
2562 if (!(out.out_regs.sector_count.is_set() && out.out_regs.lba_low.is_set())) {
2563 // TODO: Output register support should be checked within each ata_pass_through()
2564 // implementation before command is issued.
ee38a438
GI
2565 pout("SMART WRITE LOG does not return COUNT and LBA_LOW register\n");
2566 return -1;
2567 }
2568 if ( out.out_regs.sector_count == in.in_regs.sector_count
2569 && out.out_regs.lba_low == in.in_regs.lba_low ) {
2570 // 0xe001 (5734.5s) - this is most likely a broken ATA pass-through implementation
2571 pout("SMART WRITE LOG returns COUNT and LBA_LOW register unchanged\n");
7f0798ef
GI
2572 return -1;
2573 }
ee38a438 2574
7f0798ef
GI
2575 // Return value to caller
2576 time_limit = out.out_regs.sector_count | (out.out_regs.lba_low << 8);
2577 }
2578
2579 return 0;
2580}
2581
2582// Get SCT Error Recovery Control
2583int ataGetSCTErrorRecoveryControltime(ata_device * device, unsigned type, unsigned short & time_limit)
2584{
2585 return ataGetSetSCTErrorRecoveryControltime(device, type, false/*get*/, time_limit);
2586}
2587
2588// Set SCT Error Recovery Control
2589int ataSetSCTErrorRecoveryControltime(ata_device * device, unsigned type, unsigned short time_limit)
2590{
2591 return ataGetSetSCTErrorRecoveryControltime(device, type, true/*set*/, time_limit);
2592}
2593
2594
2127e193 2595// Print one self-test log entry.
cfbba5b9
GI
2596// Returns:
2597// -1: self-test failed
2598// 1: extended self-test completed without error
2599// 0: otherwise
2600int ataPrintSmartSelfTestEntry(unsigned testnum, unsigned char test_type,
2601 unsigned char test_status,
2602 unsigned short timestamp,
2603 uint64_t failing_lba,
2604 bool print_error_only, bool & print_header)
2605{
2606 // Check status and type for return value
2607 int retval = 0;
2608 switch (test_status >> 4) {
2609 case 0x0:
2610 if ((test_type & 0x0f) == 0x02)
2611 retval = 1; // extended self-test completed without error
2612 break;
2613 case 0x3: case 0x4:
2614 case 0x5: case 0x6:
2615 case 0x7: case 0x8:
2616 retval = -1; // self-test failed
2617 break;
2618 }
2619
2620 if (retval >= 0 && print_error_only)
2621 return retval;
2622
2623 std::string msgtest;
2127e193
GI
2624 switch (test_type) {
2625 case 0x00: msgtest = "Offline"; break;
2626 case 0x01: msgtest = "Short offline"; break;
2627 case 0x02: msgtest = "Extended offline"; break;
2628 case 0x03: msgtest = "Conveyance offline"; break;
2629 case 0x04: msgtest = "Selective offline"; break;
2630 case 0x7f: msgtest = "Abort offline test"; break;
2631 case 0x81: msgtest = "Short captive"; break;
2632 case 0x82: msgtest = "Extended captive"; break;
2633 case 0x83: msgtest = "Conveyance captive"; break;
2634 case 0x84: msgtest = "Selective captive"; break;
2635 default:
2636 if ((0x40 <= test_type && test_type <= 0x7e) || 0x90 <= test_type)
cfbba5b9 2637 msgtest = strprintf("Vendor (0x%02x)", test_type);
2127e193 2638 else
cfbba5b9 2639 msgtest = strprintf("Reserved (0x%02x)", test_type);
2127e193
GI
2640 }
2641
cfbba5b9 2642 std::string msgstat;
2127e193
GI
2643 switch (test_status >> 4) {
2644 case 0x0: msgstat = "Completed without error"; break;
2645 case 0x1: msgstat = "Aborted by host"; break;
2646 case 0x2: msgstat = "Interrupted (host reset)"; break;
cfbba5b9
GI
2647 case 0x3: msgstat = "Fatal or unknown error"; break;
2648 case 0x4: msgstat = "Completed: unknown failure"; break;
2649 case 0x5: msgstat = "Completed: electrical failure"; break;
2650 case 0x6: msgstat = "Completed: servo/seek failure"; break;
2651 case 0x7: msgstat = "Completed: read failure"; break;
2652 case 0x8: msgstat = "Completed: handling damage??"; break;
2127e193 2653 case 0xf: msgstat = "Self-test routine in progress"; break;
cfbba5b9 2654 default: msgstat = strprintf("Unknown status (0x%x)", test_status >> 4);
2127e193
GI
2655 }
2656
2127e193
GI
2657 // Print header once
2658 if (print_header) {
2659 print_header = false;
2660 pout("Num Test_Description Status Remaining LifeTime(hours) LBA_of_first_error\n");
2661 }
2662
2663 char msglba[32];
cfbba5b9 2664 if (retval < 0 && failing_lba < 0xffffffffffffULL)
2127e193 2665 snprintf(msglba, sizeof(msglba), "%"PRIu64, failing_lba);
ee38a438
GI
2666 else {
2667 msglba[0] = '-'; msglba[1] = 0;
2668 }
2127e193 2669
cfbba5b9
GI
2670 pout("#%2u %-19s %-29s %1d0%% %8u %s\n", testnum,
2671 msgtest.c_str(), msgstat.c_str(), test_status & 0x0f, timestamp, msglba);
2127e193 2672
cfbba5b9 2673 return retval;
2127e193
GI
2674}
2675
2676// Print Smart self-test log, used by smartctl and smartd.
2677// return value is:
2678// bottom 8 bits: number of entries found where self-test showed an error
2679// remaining bits: if nonzero, power on hours of last self-test where error was found
2680int ataPrintSmartSelfTestlog(const ata_smart_selftestlog * data, bool allentries,
ee38a438 2681 firmwarebug_defs firmwarebugs)
2127e193
GI
2682{
2683 if (allentries)
2684 pout("SMART Self-test log structure revision number %d\n",(int)data->revnumber);
ee38a438 2685 if (data->revnumber != 0x0001 && allentries && !firmwarebugs.is_set(BUG_SAMSUNG))
2127e193
GI
2686 pout("Warning: ATA Specification requires self-test log structure revision number = 1\n");
2687 if (data->mostrecenttest==0){
2688 if (allentries)
2689 pout("No self-tests have been logged. [To run self-tests, use: smartctl -t]\n\n");
2690 return 0;
2691 }
2692
2693 bool noheaderprinted = true;
cfbba5b9
GI
2694 int errcnt = 0, hours = 0, igncnt = 0;
2695 int testno = 0, ext_ok_testno = -1;
2127e193
GI
2696
2697 // print log
2698 for (int i = 20; i >= 0; i--) {
2699 // log is a circular buffer
2700 int j = (i+data->mostrecenttest)%21;
2701 const ata_smart_selftestlog_struct * log = data->selftest_struct+j;
2702
2703 if (nonempty(log, sizeof(*log))) {
2704 // count entry based on non-empty structures -- needed for
2705 // Seagate only -- other vendors don't have blank entries 'in
2706 // the middle'
2707 testno++;
2708
2709 // T13/1321D revision 1c: (Data structure Rev #1)
2710
2711 //The failing LBA shall be the LBA of the uncorrectable sector
2712 //that caused the test to fail. If the device encountered more
2713 //than one uncorrectable sector during the test, this field
2714 //shall indicate the LBA of the first uncorrectable sector
2715 //encountered. If the test passed or the test failed for some
2716 //reason other than an uncorrectable sector, the value of this
2717 //field is undefined.
2718
2719 // This is true in ALL ATA-5 specs
2720 uint64_t lba48 = (log->lbafirstfailure < 0xffffffff ? log->lbafirstfailure : 0xffffffffffffULL);
2721
2722 // Print entry
cfbba5b9
GI
2723 int state = ataPrintSmartSelfTestEntry(testno,
2724 log->selftestnumber, log->selfteststatus,
2725 log->timestamp, lba48, !allentries, noheaderprinted);
2127e193 2726
cfbba5b9 2727 if (state < 0) {
f4ebf3d1 2728 // Self-test showed an error
cfbba5b9
GI
2729 if (ext_ok_testno < 0) {
2730 errcnt++;
f4ebf3d1 2731
cfbba5b9
GI
2732 // keep track of time of most recent error
2733 if (!hours)
2734 hours = log->timestamp;
2735 }
2736 else
2737 // Newer successful extended self-test exits
2738 igncnt++;
2739 }
2740 else if (state > 0 && ext_ok_testno < 0) {
2741 // Latest successful extended self-test
2742 ext_ok_testno = testno;
f4ebf3d1 2743 }
2127e193
GI
2744 }
2745 }
cfbba5b9
GI
2746
2747 if (igncnt)
2748 pout("%d of %d failed self-tests are outdated by newer successful extended offline self-test #%2d\n",
2749 igncnt, igncnt+errcnt, ext_ok_testno);
2750
2751 if (!allentries && !noheaderprinted)
2127e193
GI
2752 pout("\n");
2753
cfbba5b9 2754 return ((hours << 8) | errcnt);
2127e193
GI
2755}
2756
a37e7145
GG
2757
2758/////////////////////////////////////////////////////////////////////////////
2759// Pseudo-device to parse "smartctl -r ataioctl,2 ..." output and simulate
2760// an ATA device with same behaviour
2761
2127e193
GI
2762namespace {
2763
2764class parsed_ata_device
2765: public /*implements*/ ata_device_with_command_set
2766{
2767public:
2768 parsed_ata_device(smart_interface * intf, const char * dev_name);
2769
2770 virtual ~parsed_ata_device() throw();
2771
2772 virtual bool is_open() const;
2773
2774 virtual bool open();
a37e7145 2775
2127e193 2776 virtual bool close();
a37e7145 2777
2127e193
GI
2778 virtual bool ata_identify_is_cached() const;
2779
2780protected:
2781 virtual int ata_command_interface(smart_command_set command, int select, char * data);
2782
2783private:
2784 // Table of parsed commands, return value, data
2785 struct parsed_ata_command
2786 {
2787 smart_command_set command;
2788 int select;
2789 int retval, errval;
2790 char * data;
2791 };
2792
2793 enum { max_num_commands = 32 };
2794 parsed_ata_command m_command_table[max_num_commands];
2795
2796 int m_num_commands;
2797 int m_next_replay_command;
2798 bool m_replay_out_of_sync;
2799 bool m_ata_identify_is_cached;
2800};
a37e7145
GG
2801
2802static const char * nextline(const char * s, int & lineno)
2803{
2804 for (s += strcspn(s, "\r\n"); *s == '\r' || *s == '\n'; s++) {
2805 if (*s == '\r' && s[1] == '\n')
2806 s++;
2807 lineno++;
2808 }
2809 return s;
2810}
2811
2812static int name2command(const char * s)
2813{
2814 for (int i = 0; i < (int)(sizeof(commandstrings)/sizeof(commandstrings[0])); i++) {
2815 if (!strcmp(s, commandstrings[i]))
2816 return i;
2817 }
2818 return -1;
2819}
2820
2821static bool matchcpy(char * dest, size_t size, const char * src, const regmatch_t & srcmatch)
2822{
2823 if (srcmatch.rm_so < 0)
2824 return false;
2825 size_t n = srcmatch.rm_eo - srcmatch.rm_so;
2826 if (n >= size)
2827 n = size-1;
2828 memcpy(dest, src + srcmatch.rm_so, n);
2829 dest[n] = 0;
2830 return true;
2831}
2832
2833static inline int matchtoi(const char * src, const regmatch_t & srcmatch, int defval)
2834{
2835 if (srcmatch.rm_so < 0)
2836 return defval;
2837 return atoi(src + srcmatch.rm_so);
2838}
2839
2127e193
GI
2840parsed_ata_device::parsed_ata_device(smart_interface * intf, const char * dev_name)
2841: smart_device(intf, dev_name, "ata", ""),
2842 m_num_commands(0),
2843 m_next_replay_command(0),
2844 m_replay_out_of_sync(false),
2845 m_ata_identify_is_cached(false)
2846{
2847 memset(m_command_table, 0, sizeof(m_command_table));
2848}
2849
2850parsed_ata_device::~parsed_ata_device() throw()
2851{
2852 close();
2853}
2854
2855bool parsed_ata_device::is_open() const
2856{
2857 return (m_num_commands > 0);
2858}
a37e7145
GG
2859
2860// Parse stdin and build command table
2127e193 2861bool parsed_ata_device::open()
a37e7145 2862{
2127e193
GI
2863 const char * pathname = get_dev_name();
2864 if (strcmp(pathname, "-"))
2865 return set_err(EINVAL);
a37e7145
GG
2866 pathname = "<stdin>";
2867 // Fill buffer
2868 char buffer[64*1024];
2869 int size = 0;
2870 while (size < (int)sizeof(buffer)) {
2871 int nr = fread(buffer, 1, sizeof(buffer), stdin);
2872 if (nr <= 0)
2873 break;
2874 size += nr;
2875 }
2127e193
GI
2876 if (size <= 0)
2877 return set_err(ENOENT, "%s: Unexpected EOF", pathname);
2878 if (size >= (int)sizeof(buffer))
2879 return set_err(EIO, "%s: Buffer overflow", pathname);
a37e7145
GG
2880 buffer[size] = 0;
2881
2882 // Regex to match output from "-r ataioctl,2"
2883 static const char pattern[] = "^"
2884 "(" // (1
2127e193 2885 "REPORT-IOCTL: DeviceF?D?=[^ ]+ Command=([A-Z ]*[A-Z])" // (2)
a37e7145
GG
2886 "(" // (3
2887 "( InputParameter=([0-9]+))?" // (4 (5))
2888 "|"
2889 "( returned (-?[0-9]+)( errno=([0-9]+)[^\r\n]*)?)" // (6 (7) (8 (9)))
2890 ")" // )
2891 "[\r\n]" // EOL match necessary to match optional parts above
2892 "|"
2893 "===== \\[([A-Z ]*[A-Z])\\] DATA START " // (10)
2127e193
GI
2894 "|"
2895 " *(En|Dis)abled status cached by OS, " // (11)
a37e7145
GG
2896 ")"; // )
2897
2898 // Compile regex
cfbba5b9 2899 const regular_expression regex(pattern, REG_EXTENDED);
a37e7145
GG
2900
2901 // Parse buffer
2902 const char * errmsg = 0;
2903 int i = -1, state = 0, lineno = 1;
2904 for (const char * line = buffer; *line; line = nextline(line, lineno)) {
2905 // Match line
2127e193 2906 if (!(line[0] == 'R' || line[0] == '=' || line[0] == ' '))
a37e7145 2907 continue;
2127e193 2908 const int nmatch = 1+11;
a37e7145 2909 regmatch_t match[nmatch];
2127e193 2910 if (!regex.execute(line, nmatch, match))
a37e7145
GG
2911 continue;
2912
2913 char cmdname[40];
2914 if (matchcpy(cmdname, sizeof(cmdname), line, match[2])) { // "REPORT-IOCTL:... Command=%s ..."
2915 int nc = name2command(cmdname);
2916 if (nc < 0) {
2917 errmsg = "Unknown ATA command name"; break;
2918 }
2919 if (match[7].rm_so < 0) { // "returned %d"
2920 // Start of command
2921 if (!(state == 0 || state == 2)) {
2922 errmsg = "Missing REPORT-IOCTL result"; break;
2923 }
2127e193 2924 if (++i >= max_num_commands) {
a37e7145
GG
2925 errmsg = "Too many ATA commands"; break;
2926 }
2127e193
GI
2927 m_command_table[i].command = (smart_command_set)nc;
2928 m_command_table[i].select = matchtoi(line, match[5], 0); // "InputParameter=%d"
a37e7145
GG
2929 state = 1;
2930 }
2931 else {
2932 // End of command
2127e193 2933 if (!(state == 1 && (int)m_command_table[i].command == nc)) {
a37e7145
GG
2934 errmsg = "Missing REPORT-IOCTL start"; break;
2935 }
2127e193
GI
2936 m_command_table[i].retval = matchtoi(line, match[7], -1); // "returned %d"
2937 m_command_table[i].errval = matchtoi(line, match[9], 0); // "errno=%d"
a37e7145
GG
2938 state = 2;
2939 }
2940 }
2941 else if (matchcpy(cmdname, sizeof(cmdname), line, match[10])) { // "===== [%s] DATA START "
2942 // Start of sector hexdump
2943 int nc = name2command(cmdname);
2127e193 2944 if (!(state == (nc == WRITE_LOG ? 1 : 2) && (int)m_command_table[i].command == nc)) {
a37e7145
GG
2945 errmsg = "Unexpected DATA START"; break;
2946 }
2947 line = nextline(line, lineno);
2948 char * data = (char *)malloc(512);
2949 unsigned j;
2950 for (j = 0; j < 32; j++) {
2951 unsigned b[16];
2952 unsigned u1, u2; int n1 = -1;
2953 if (!(sscanf(line, "%3u-%3u: "
2954 "%2x %2x %2x %2x %2x %2x %2x %2x "
2955 "%2x %2x %2x %2x %2x %2x %2x %2x%n",
2956 &u1, &u2,
2957 b+ 0, b+ 1, b+ 2, b+ 3, b+ 4, b+ 5, b+ 6, b+ 7,
2958 b+ 8, b+ 9, b+10, b+11, b+12, b+13, b+14, b+15, &n1) == 18
2959 && n1 >= 56 && u1 == j*16 && u2 == j*16+15))
2960 break;
2961 for (unsigned k = 0; k < 16; k++)
2962 data[j*16+k] = b[k];
2963 line = nextline(line, lineno);
2964 }
2965 if (j < 32) {
2966 free(data);
2967 errmsg = "Incomplete sector hex dump"; break;
2968 }
2127e193 2969 m_command_table[i].data = data;
a37e7145
GG
2970 if (nc != WRITE_LOG)
2971 state = 0;
2972 }
2127e193
GI
2973 else if (match[11].rm_so > 0) { // "(En|Dis)abled status cached by OS"
2974 m_ata_identify_is_cached = true;
2975 }
a37e7145
GG
2976 }
2977
2978 if (!(state == 0 || state == 2))
2979 errmsg = "Missing REPORT-IOCTL result";
2980
2981 if (!errmsg && i < 0)
2982 errmsg = "No information found";
2983
2127e193
GI
2984 m_num_commands = i+1;
2985 m_next_replay_command = 0;
2986 m_replay_out_of_sync = false;
a37e7145
GG
2987
2988 if (errmsg) {
2127e193
GI
2989 close();
2990 return set_err(EIO, "%s(%d): Syntax error: %s", pathname, lineno, errmsg);
a37e7145 2991 }
2127e193 2992 return true;
a37e7145
GG
2993}
2994
2995// Report warnings and free command table
2127e193 2996bool parsed_ata_device::close()
a37e7145 2997{
2127e193 2998 if (m_replay_out_of_sync)
a37e7145 2999 pout("REPLAY-IOCTL: Warning: commands replayed out of sync\n");
2127e193
GI
3000 else if (m_next_replay_command != 0)
3001 pout("REPLAY-IOCTL: Warning: %d command(s) not replayed\n", m_num_commands-m_next_replay_command);
a37e7145 3002
2127e193
GI
3003 for (int i = 0; i < m_num_commands; i++) {
3004 if (m_command_table[i].data) {
3005 free(m_command_table[i].data); m_command_table[i].data = 0;
a37e7145
GG
3006 }
3007 }
2127e193
GI
3008 m_num_commands = 0;
3009 m_next_replay_command = 0;
3010 m_replay_out_of_sync = false;
3011 return true;
3012}
3013
3014
3015bool parsed_ata_device::ata_identify_is_cached() const
3016{
3017 return m_ata_identify_is_cached;
a37e7145
GG
3018}
3019
2127e193 3020
a37e7145 3021// Simulate ATA command from command table
2127e193 3022int parsed_ata_device::ata_command_interface(smart_command_set command, int select, char * data)
a37e7145 3023{
2127e193
GI
3024 // Find command, try round-robin if out of sync
3025 int i = m_next_replay_command;
a37e7145 3026 for (int j = 0; ; j++) {
2127e193 3027 if (j >= m_num_commands) {
a37e7145
GG
3028 pout("REPLAY-IOCTL: Warning: Command not found\n");
3029 errno = ENOSYS;
3030 return -1;
3031 }
2127e193 3032 if (m_command_table[i].command == command && m_command_table[i].select == select)
a37e7145 3033 break;
2127e193
GI
3034 if (!m_replay_out_of_sync) {
3035 m_replay_out_of_sync = true;
a37e7145
GG
3036 pout("REPLAY-IOCTL: Warning: Command #%d is out of sync\n", i+1);
3037 }
2127e193 3038 if (++i >= m_num_commands)
a37e7145
GG
3039 i = 0;
3040 }
2127e193
GI
3041 m_next_replay_command = i;
3042 if (++m_next_replay_command >= m_num_commands)
3043 m_next_replay_command = 0;
a37e7145
GG
3044
3045 // Return command data
3046 switch (command) {
3047 case IDENTIFY:
3048 case PIDENTIFY:
3049 case READ_VALUES:
3050 case READ_THRESHOLDS:
3051 case READ_LOG:
2127e193
GI
3052 if (m_command_table[i].data)
3053 memcpy(data, m_command_table[i].data, 512);
a37e7145
GG
3054 break;
3055 case WRITE_LOG:
2127e193 3056 if (!(m_command_table[i].data && !memcmp(data, m_command_table[i].data, 512)))
a37e7145
GG
3057 pout("REPLAY-IOCTL: Warning: WRITE LOG data does not match\n");
3058 break;
3059 case CHECK_POWER_MODE:
3060 data[0] = (char)0xff;
3061 default:
3062 break;
3063 }
3064
2127e193
GI
3065 if (m_command_table[i].errval)
3066 errno = m_command_table[i].errval;
3067 return m_command_table[i].retval;
3068}
3069
3070} // namespace
3071
3072ata_device * get_parsed_ata_device(smart_interface * intf, const char * dev_name)
3073{
3074 return new parsed_ata_device(intf, dev_name);
a37e7145 3075}