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