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