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