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