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