smartmontools  SVN Rev 4347
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-15 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 4332 2016-08-17 21:16:29Z 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 
1101 // Read GP Log page(s)
1102 bool ataReadLogExt(ata_device * device, unsigned char logaddr,
1103  unsigned char features, unsigned page,
1104  void * data, unsigned nsectors)
1105 {
1106  ata_cmd_in in;
1108  in.in_regs.features = features; // log specific
1109  in.set_data_in_48bit(data, nsectors);
1110  in.in_regs.lba_low = logaddr;
1111  in.in_regs.lba_mid_16 = page;
1112 
1113  if (!device->ata_pass_through(in)) { // TODO: Debug output
1114  if (nsectors <= 1) {
1115  pout("ATA_READ_LOG_EXT (addr=0x%02x:0x%02x, page=%u, n=%u) failed: %s\n",
1116  logaddr, features, page, nsectors, device->get_errmsg());
1117  return false;
1118  }
1119 
1120  // Recurse to retry with single sectors,
1121  // multi-sector reads may not be supported by ioctl.
1122  for (unsigned i = 0; i < nsectors; i++) {
1123  if (!ataReadLogExt(device, logaddr,
1124  features, page + i,
1125  (char *)data + 512*i, 1))
1126  return false;
1127  }
1128  }
1129 
1130  return true;
1131 }
1132 
1133 // Read SMART Log page(s)
1134 bool ataReadSmartLog(ata_device * device, unsigned char logaddr,
1135  void * data, unsigned nsectors)
1136 {
1137  ata_cmd_in in;
1140  in.set_data_in(data, nsectors);
1143  in.in_regs.lba_low = logaddr;
1144 
1145  if (!device->ata_pass_through(in)) { // TODO: Debug output
1146  pout("ATA_SMART_READ_LOG failed: %s\n", device->get_errmsg());
1147  return false;
1148  }
1149  return true;
1150 }
1151 
1152 
1153 
1154 // Reads the SMART or GPL Log Directory (log #0)
1156 {
1157  if (!gpl) { // SMART Log directory
1158  if (smartcommandhandler(device, READ_LOG, 0x00, (char *)data))
1159  return -1;
1160  }
1161  else { // GP Log directory
1162  if (!ataReadLogExt(device, 0x00, 0x00, 0, data, 1))
1163  return -1;
1164  }
1165 
1166  // swap endian order if needed
1167  if (isbigendian())
1168  swapx(&data->logversion);
1169 
1170  return 0;
1171 }
1172 
1173 
1174 // Reads the selective self-test log (log #9)
1176 
1177  // get data from device
1178  if (smartcommandhandler(device, READ_LOG, 0x09, (char *)data)){
1179  return -1;
1180  }
1181 
1182  // compute its checksum, and issue a warning if needed
1183  if (checksum(data))
1184  checksumwarning("SMART Selective Self-Test Log Structure");
1185 
1186  // swap endian order if needed
1187  if (isbigendian()){
1188  int i;
1189  swap2((char *)&(data->logversion));
1190  for (i=0;i<5;i++){
1191  swap8((char *)&(data->span[i].start));
1192  swap8((char *)&(data->span[i].end));
1193  }
1194  swap8((char *)&(data->currentlba));
1195  swap2((char *)&(data->currentspan));
1196  swap2((char *)&(data->flags));
1197  swap2((char *)&(data->pendingtime));
1198  }
1199 
1200  return 0;
1201 }
1202 
1203 // Writes the selective self-test log (log #9)
1205  const ata_smart_values * sv, uint64_t num_sectors,
1206  const ata_selective_selftest_args * prev_args)
1207 {
1208  // Disk size must be known
1209  if (!num_sectors) {
1210  pout("Disk size is unknown, unable to check selective self-test spans\n");
1211  return -1;
1212  }
1213 
1214  // Read log
1215  struct ata_selective_self_test_log sstlog, *data=&sstlog;
1216  unsigned char *ptr=(unsigned char *)data;
1217  if (ataReadSelectiveSelfTestLog(device, data)) {
1218  pout("SMART Read Selective Self-test Log failed: %s\n", device->get_errmsg());
1219  pout("Since Read failed, will not attempt to WRITE Selective Self-test Log\n");
1220  return -1;
1221  }
1222 
1223  // Set log version
1224  data->logversion = 1;
1225 
1226  // Host is NOT allowed to write selective self-test log if a selective
1227  // self-test is in progress.
1228  if (0<data->currentspan && data->currentspan<6 && ((sv->self_test_exec_status)>>4)==15) {
1229  pout("SMART Selective or other Self-test in progress\n");
1230  return -4;
1231  }
1232 
1233  // Set start/end values based on old spans for special -t select,... options
1234  int i;
1235  for (i = 0; i < args.num_spans; i++) {
1236  int mode = args.span[i].mode;
1237  uint64_t start = args.span[i].start;
1238  uint64_t end = args.span[i].end;
1239  if (mode == SEL_CONT) {// redo or next dependig on last test status
1240  switch (sv->self_test_exec_status >> 4) {
1241  case 1: case 2: // Aborted/Interrupted by host
1242  pout("Continue Selective Self-Test: Redo last span\n");
1243  mode = SEL_REDO;
1244  break;
1245  default: // All others
1246  pout("Continue Selective Self-Test: Start next span\n");
1247  mode = SEL_NEXT;
1248  break;
1249  }
1250  }
1251 
1252  if ( (mode == SEL_REDO || mode == SEL_NEXT)
1253  && prev_args && i < prev_args->num_spans
1254  && !data->span[i].start && !data->span[i].end) {
1255  // Some drives do not preserve the selective self-test log accross
1256  // power-cyles. If old span on drive is cleared use span provided
1257  // by caller. This is used by smartd (first span only).
1258  data->span[i].start = prev_args->span[i].start;
1259  data->span[i].end = prev_args->span[i].end;
1260  }
1261 
1262  switch (mode) {
1263  case SEL_RANGE: // -t select,START-END
1264  break;
1265  case SEL_REDO: // -t select,redo... => Redo current
1266  start = data->span[i].start;
1267  if (end > 0) { // -t select,redo+SIZE
1268  end--; end += start; // [oldstart, oldstart+SIZE)
1269  }
1270  else // -t select,redo
1271  end = data->span[i].end; // [oldstart, oldend]
1272  break;
1273  case SEL_NEXT: // -t select,next... => Do next
1274  if (data->span[i].end == 0) {
1275  start = end = 0; break; // skip empty spans
1276  }
1277  start = data->span[i].end + 1;
1278  if (start >= num_sectors)
1279  start = 0; // wrap around
1280  if (end > 0) { // -t select,next+SIZE
1281  end--; end += start; // (oldend, oldend+SIZE]
1282  }
1283  else { // -t select,next
1284  uint64_t oldsize = data->span[i].end - data->span[i].start + 1;
1285  end = start + oldsize - 1; // (oldend, oldend+oldsize]
1286  if (end >= num_sectors) {
1287  // Adjust size to allow round-robin testing without future size decrease
1288  uint64_t spans = (num_sectors + oldsize-1) / oldsize;
1289  uint64_t newsize = (num_sectors + spans-1) / spans;
1290  uint64_t newstart = num_sectors - newsize, newend = num_sectors - 1;
1291  pout("Span %d changed from %" PRIu64 "-%" PRIu64 " (%" PRIu64 " sectors)\n",
1292  i, start, end, oldsize);
1293  pout(" to %" PRIu64 "-%" PRIu64 " (%" PRIu64 " sectors) (%" PRIu64 " spans)\n",
1294  newstart, newend, newsize, spans);
1295  start = newstart; end = newend;
1296  }
1297  }
1298  break;
1299  default:
1300  pout("ataWriteSelectiveSelfTestLog: Invalid mode %d\n", mode);
1301  return -1;
1302  }
1303  // Range check
1304  if (start < num_sectors && num_sectors <= end) {
1305  if (end != ~(uint64_t)0) // -t select,N-max
1306  pout("Size of self-test span %d decreased according to disk size\n", i);
1307  end = num_sectors - 1;
1308  }
1309  if (!(start <= end && end < num_sectors)) {
1310  pout("Invalid selective self-test span %d: %" PRIu64 "-%" PRIu64 " (%" PRIu64 " sectors)\n",
1311  i, start, end, num_sectors);
1312  return -1;
1313  }
1314  // Return the actual mode and range to caller.
1315  args.span[i].mode = mode;
1316  args.span[i].start = start;
1317  args.span[i].end = end;
1318  }
1319 
1320  // Clear spans
1321  for (i=0; i<5; i++)
1322  memset(data->span+i, 0, sizeof(struct test_span));
1323 
1324  // Set spans for testing
1325  for (i = 0; i < args.num_spans; i++){
1326  data->span[i].start = args.span[i].start;
1327  data->span[i].end = args.span[i].end;
1328  }
1329 
1330  // host must initialize to zero before initiating selective self-test
1331  data->currentlba=0;
1332  data->currentspan=0;
1333 
1334  // Perform off-line scan after selective test?
1335  if (args.scan_after_select == 1)
1336  // NO
1337  data->flags &= ~SELECTIVE_FLAG_DOSCAN;
1338  else if (args.scan_after_select == 2)
1339  // YES
1340  data->flags |= SELECTIVE_FLAG_DOSCAN;
1341 
1342  // Must clear active and pending flags before writing
1343  data->flags &= ~(SELECTIVE_FLAG_ACTIVE);
1344  data->flags &= ~(SELECTIVE_FLAG_PENDING);
1345 
1346  // modify pending time?
1347  if (args.pending_time)
1348  data->pendingtime = (unsigned short)(args.pending_time-1);
1349 
1350  // Set checksum to zero, then compute checksum
1351  data->checksum=0;
1352  unsigned char cksum=0;
1353  for (i=0; i<512; i++)
1354  cksum+=ptr[i];
1355  cksum=~cksum;
1356  cksum+=1;
1357  data->checksum=cksum;
1358 
1359  // swap endian order if needed
1360  if (isbigendian()){
1361  swap2((char *)&(data->logversion));
1362  for (int b = 0; b < 5; b++) {
1363  swap8((char *)&(data->span[b].start));
1364  swap8((char *)&(data->span[b].end));
1365  }
1366  swap8((char *)&(data->currentlba));
1367  swap2((char *)&(data->currentspan));
1368  swap2((char *)&(data->flags));
1369  swap2((char *)&(data->pendingtime));
1370  }
1371 
1372  // write new selective self-test log
1373  if (smartcommandhandler(device, WRITE_LOG, 0x09, (char *)data)){
1374  pout("Write Selective Self-test Log failed: %s\n", device->get_errmsg());
1375  return -3;
1376  }
1377 
1378  return 0;
1379 }
1380 
1381 // This corrects some quantities that are byte reversed in the SMART
1382 // ATA ERROR LOG.
1384 {
1385  // FIXED IN SAMSUNG -25 FIRMWARE???
1386  // Device error count in bytes 452-3
1387  swap2((char *)&(data->ata_error_count));
1388 
1389  // FIXED IN SAMSUNG -22a FIRMWARE
1390  // step through 5 error log data structures
1391  for (int i = 0; i < 5; i++){
1392  // step through 5 command data structures
1393  for (int j = 0; j < 5; j++)
1394  // Command data structure 4-byte millisec timestamp. These are
1395  // bytes (N+8, N+9, N+10, N+11).
1396  swap4((char *)&(data->errorlog_struct[i].commands[j].timestamp));
1397  // Error data structure two-byte hour life timestamp. These are
1398  // bytes (N+28, N+29).
1399  swap2((char *)&(data->errorlog_struct[i].error_struct.timestamp));
1400  }
1401  return;
1402 }
1403 
1404 // NEEDED ONLY FOR SAMSUNG -22 (some) -23 AND -24?? FIRMWARE
1406 {
1407  // Device error count in bytes 452-3
1408  swap2((char *)&(data->ata_error_count));
1409  return;
1410 }
1411 
1412 // Reads the Summary SMART Error Log (log #1). The Comprehensive SMART
1413 // Error Log is #2, and the Extended Comprehensive SMART Error log is
1414 // #3
1416  firmwarebug_defs firmwarebugs)
1417 {
1418 
1419  // get data from device
1420  if (smartcommandhandler(device, READ_LOG, 0x01, (char *)data)){
1421  return -1;
1422  }
1423 
1424  // compute its checksum, and issue a warning if needed
1425  if (checksum(data))
1426  checksumwarning("SMART ATA Error Log Structure");
1427 
1428  // Some disks have the byte order reversed in some SMART Summary
1429  // Error log entries
1430  if (firmwarebugs.is_set(BUG_SAMSUNG))
1431  fixsamsungerrorlog(data);
1432  else if (firmwarebugs.is_set(BUG_SAMSUNG2))
1433  fixsamsungerrorlog2(data);
1434 
1435  // swap endian order if needed
1436  if (isbigendian()){
1437  int i,j;
1438 
1439  // Device error count in bytes 452-3
1440  swap2((char *)&(data->ata_error_count));
1441 
1442  // step through 5 error log data structures
1443  for (i=0; i<5; i++){
1444  // step through 5 command data structures
1445  for (j=0; j<5; j++)
1446  // Command data structure 4-byte millisec timestamp
1447  swap4((char *)&(data->errorlog_struct[i].commands[j].timestamp));
1448  // Error data structure life timestamp
1449  swap2((char *)&(data->errorlog_struct[i].error_struct.timestamp));
1450  }
1451  }
1452 
1453  return 0;
1454 }
1455 
1456 
1457 // Fix LBA byte ordering of Extended Comprehensive Error Log
1458 // if little endian instead of ATA register ordering is provided
1459 template <class T>
1460 static inline void fix_exterrlog_lba_cmd(T & cmd)
1461 {
1462  T org = cmd;
1463  cmd.lba_mid_register_hi = org.lba_high_register;
1464  cmd.lba_low_register_hi = org.lba_mid_register_hi;
1465  cmd.lba_high_register = org.lba_mid_register;
1466  cmd.lba_mid_register = org.lba_low_register_hi;
1467 }
1468 
1469 static void fix_exterrlog_lba(ata_smart_exterrlog * log, unsigned nsectors)
1470 {
1471  for (unsigned i = 0; i < nsectors; i++) {
1472  for (int ei = 0; ei < 4; ei++) {
1475  for (int ci = 0; ci < 5; ci++)
1476  fix_exterrlog_lba_cmd(entry.commands[ci]);
1477  }
1478  }
1479 }
1480 
1481 // Read Extended Comprehensive Error Log
1483  unsigned page, unsigned nsectors, firmwarebug_defs firmwarebugs)
1484 {
1485  if (!ataReadLogExt(device, 0x03, 0x00, page, log, nsectors))
1486  return false;
1487 
1488  check_multi_sector_sum(log, nsectors, "SMART Extended Comprehensive Error Log Structure");
1489 
1490  if (isbigendian()) {
1491  swapx(&log->device_error_count);
1492  swapx(&log->error_log_index);
1493  for (unsigned i = 0; i < nsectors; i++) {
1494  for (unsigned j = 0; j < 4; j++) {
1495  for (unsigned k = 0; k < 5; k++)
1496  swapx(&log[i].error_logs[j].commands[k].timestamp);
1497  swapx(&log[i].error_logs[j].error.timestamp);
1498  }
1499  }
1500  }
1501 
1502  if (firmwarebugs.is_set(BUG_XERRORLBA))
1503  fix_exterrlog_lba(log, nsectors);
1504 
1505  return true;
1506 }
1507 
1508 
1510 
1511  // get data from device
1512  if (smartcommandhandler(device, READ_THRESHOLDS, 0, (char *)data)){
1513  return -1;
1514  }
1515 
1516  // compute its checksum, and issue a warning if needed
1517  if (checksum(data))
1518  checksumwarning("SMART Attribute Thresholds Structure");
1519 
1520  // swap endian order if needed
1521  if (isbigendian())
1522  swap2((char *)&(data->revnumber));
1523 
1524  return 0;
1525 }
1526 
1527 int ataEnableSmart (ata_device * device ){
1528  if (smartcommandhandler(device, ENABLE, 0, NULL)){
1529  return -1;
1530  }
1531  return 0;
1532 }
1533 
1534 int ataDisableSmart (ata_device * device ){
1535 
1536  if (smartcommandhandler(device, DISABLE, 0, NULL)){
1537  return -1;
1538  }
1539  return 0;
1540 }
1541 
1543  if (smartcommandhandler(device, AUTOSAVE, 241, NULL)){
1544  return -1;
1545  }
1546  return 0;
1547 }
1548 
1550 
1551  if (smartcommandhandler(device, AUTOSAVE, 0, NULL)){
1552  return -1;
1553  }
1554  return 0;
1555 }
1556 
1557 // In *ALL* ATA standards the Enable/Disable AutoOffline command is
1558 // marked "OBSOLETE". It is defined in SFF-8035i Revision 2, and most
1559 // vendors still support it for backwards compatibility. IBM documents
1560 // it for some drives.
1562 
1563  /* timer hard coded to 4 hours */
1564  if (smartcommandhandler(device, AUTO_OFFLINE, 248, NULL)){
1565  return -1;
1566  }
1567  return 0;
1568 }
1569 
1570 // Another Obsolete Command. See comments directly above, associated
1571 // with the corresponding Enable command.
1573 
1574  if (smartcommandhandler(device, AUTO_OFFLINE, 0, NULL)){
1575  return -1;
1576  }
1577  return 0;
1578 }
1579 
1580 // If SMART is enabled, supported, and working, then this call is
1581 // guaranteed to return 1, else zero. Note that it should return 1
1582 // regardless of whether the disk's SMART status is 'healthy' or
1583 // 'failing'.
1585  int retval=smartcommandhandler(device, STATUS, 0, NULL);
1586 
1587  if (-1 == retval)
1588  return 0;
1589 
1590  return 1;
1591 }
1592 
1593 // This function uses a different interface (DRIVE_TASK) than the
1594 // other commands in this file.
1596  return smartcommandhandler(device, STATUS_CHECK, 0, NULL);
1597 }
1598 
1599 // This is the way to execute ALL tests: offline, short self-test,
1600 // extended self test, with and without captive mode, etc.
1601 // TODO: Move to ataprint.cpp ?
1602 int ataSmartTest(ata_device * device, int testtype, bool force,
1603  const ata_selective_selftest_args & selargs,
1604  const ata_smart_values * sv, uint64_t num_sectors)
1605 {
1606  char cmdmsg[128]; const char *type, *captive;
1607  int cap, retval, select=0;
1608 
1609  // Boolean, if set, says test is captive
1610  cap=testtype & CAPTIVE_MASK;
1611 
1612  // Set up strings that describe the type of test
1613  if (cap)
1614  captive="captive";
1615  else
1616  captive="off-line";
1617 
1618  if (testtype==OFFLINE_FULL_SCAN)
1619  type="off-line";
1620  else if (testtype==SHORT_SELF_TEST || testtype==SHORT_CAPTIVE_SELF_TEST)
1621  type="Short self-test";
1622  else if (testtype==EXTEND_SELF_TEST || testtype==EXTEND_CAPTIVE_SELF_TEST)
1623  type="Extended self-test";
1624  else if (testtype==CONVEYANCE_SELF_TEST || testtype==CONVEYANCE_CAPTIVE_SELF_TEST)
1625  type="Conveyance self-test";
1626  else if ((select=(testtype==SELECTIVE_SELF_TEST || testtype==SELECTIVE_CAPTIVE_SELF_TEST)))
1627  type="Selective self-test";
1628  else
1629  type = 0;
1630 
1631  // Check whether another test is already running
1632  if (type && (sv->self_test_exec_status >> 4) == 0xf) {
1633  if (!force) {
1634  pout("Can't start self-test without aborting current test (%d0%% remaining),\n"
1635  "%srun 'smartctl -X' to abort test.\n",
1636  sv->self_test_exec_status & 0x0f,
1637  (!select ? "add '-t force' option to override, or " : ""));
1638  return -1;
1639  }
1640  }
1641  else
1642  force = false;
1643 
1644  // If doing a selective self-test, first use WRITE_LOG to write the
1645  // selective self-test log.
1646  ata_selective_selftest_args selargs_io = selargs; // filled with info about actual spans
1647  if (select && (retval = ataWriteSelectiveSelfTestLog(device, selargs_io, sv, num_sectors))) {
1648  if (retval==-4)
1649  pout("Can't start selective self-test without aborting current test: use '-X' option to smartctl.\n");
1650  return retval;
1651  }
1652 
1653  // Print ouf message that we are sending the command to test
1654  if (testtype==ABORT_SELF_TEST)
1655  snprintf(cmdmsg, sizeof(cmdmsg), "Abort SMART off-line mode self-test routine");
1656  else if (!type)
1657  snprintf(cmdmsg, sizeof(cmdmsg), "SMART EXECUTE OFF-LINE IMMEDIATE subcommand 0x%02x", testtype);
1658  else
1659  snprintf(cmdmsg, sizeof(cmdmsg), "Execute SMART %s routine immediately in %s mode", type, captive);
1660  pout("Sending command: \"%s\".\n",cmdmsg);
1661 
1662  if (select) {
1663  int i;
1664  pout("SPAN STARTING_LBA ENDING_LBA\n");
1665  for (i = 0; i < selargs_io.num_spans; i++)
1666  pout(" %d %20" PRId64 " %20" PRId64 "\n", i,
1667  selargs_io.span[i].start,
1668  selargs_io.span[i].end);
1669  }
1670 
1671  // Now send the command to test
1672  if (smartcommandhandler(device, IMMEDIATE_OFFLINE, testtype, NULL)) {
1673  if (!(cap && device->get_errno() == EIO)) {
1674  pout("Command \"%s\" failed: %s\n", cmdmsg, device->get_errmsg());
1675  return -1;
1676  }
1677  }
1678 
1679  // Since the command succeeded, tell user
1680  if (testtype==ABORT_SELF_TEST)
1681  pout("Self-testing aborted!\n");
1682  else {
1683  pout("Drive command \"%s\" successful.\n", cmdmsg);
1684  if (type)
1685  pout("Testing has begun%s.\n", (force ? " (previous test aborted)" : ""));
1686  }
1687  return 0;
1688 }
1689 
1690 /* Test Time Functions */
1691 int TestTime(const ata_smart_values *data, int testtype)
1692 {
1693  switch (testtype){
1694  case OFFLINE_FULL_SCAN:
1695  return (int) data->total_time_to_complete_off_line;
1696  case SHORT_SELF_TEST:
1698  return (int) data->short_test_completion_time;
1699  case EXTEND_SELF_TEST:
1701  if (data->extend_test_completion_time_b == 0xff
1702  && data->extend_test_completion_time_w != 0x0000
1703  && data->extend_test_completion_time_w != 0xffff)
1704  return data->extend_test_completion_time_w; // ATA-8
1705  else
1706  return data->extend_test_completion_time_b;
1707  case CONVEYANCE_SELF_TEST:
1709  return (int) data->conveyance_test_completion_time;
1710  default:
1711  return 0;
1712  }
1713 }
1714 
1715 // This function tells you both about the ATA error log and the
1716 // self-test error log capability (introduced in ATA-5). The bit is
1717 // poorly documented in the ATA/ATAPI standard. Starting with ATA-6,
1718 // SMART error logging is also indicated in bit 0 of DEVICE IDENTIFY
1719 // word 84 and 87. Top two bits must match the pattern 01. BEFORE
1720 // ATA-6 these top two bits still had to match the pattern 01, but the
1721 // remaining bits were reserved (==0).
1723 {
1724  unsigned short word84=identity->command_set_extension;
1725  unsigned short word87=identity->csf_default;
1726  int isata6=identity->major_rev_num & (0x01<<6);
1727  int isata7=identity->major_rev_num & (0x01<<7);
1728 
1729  if ((isata6 || isata7) && (word84>>14) == 0x01 && (word84 & 0x01))
1730  return 1;
1731 
1732  if ((isata6 || isata7) && (word87>>14) == 0x01 && (word87 & 0x01))
1733  return 1;
1734 
1735  // otherwise we'll use the poorly documented capability bit
1736  return data->errorlog_capability & 0x01;
1737 }
1738 
1739 // See previous function. If the error log exists then the self-test
1740 // log should (must?) also exist.
1742 {
1743  unsigned short word84=identity->command_set_extension;
1744  unsigned short word87=identity->csf_default;
1745  int isata6=identity->major_rev_num & (0x01<<6);
1746  int isata7=identity->major_rev_num & (0x01<<7);
1747 
1748  if ((isata6 || isata7) && (word84>>14) == 0x01 && (word84 & 0x02))
1749  return 1;
1750 
1751  if ((isata6 || isata7) && (word87>>14) == 0x01 && (word87 & 0x02))
1752  return 1;
1753 
1754 
1755  // otherwise we'll use the poorly documented capability bit
1756  return data->errorlog_capability & 0x01;
1757 }
1758 
1759 
1761 {
1762  unsigned short word84=identity->command_set_extension;
1763  unsigned short word87=identity->csf_default;
1764 
1765  // If bit 14 of word 84 is set to one and bit 15 of word 84 is
1766  // cleared to zero, the contents of word 84 contains valid support
1767  // information. If not, support information is not valid in this
1768  // word.
1769  if ((word84>>14) == 0x01)
1770  // If bit 5 of word 84 is set to one, the device supports the
1771  // General Purpose Logging feature set.
1772  return (word84 & (0x01 << 5));
1773 
1774  // If bit 14 of word 87 is set to one and bit 15 of word 87 is
1775  // cleared to zero, the contents of words (87:85) contain valid
1776  // information. If not, information is not valid in these words.
1777  if ((word87>>14) == 0x01)
1778  // If bit 5 of word 87 is set to one, the device supports
1779  // the General Purpose Logging feature set.
1780  return (word87 & (0x01 << 5));
1781 
1782  // not capable
1783  return 0;
1784 }
1785 
1786 
1787 // SMART self-test capability is also indicated in bit 1 of DEVICE
1788 // IDENTIFY word 87 (if top two bits of word 87 match pattern 01).
1789 // However this was only introduced in ATA-6 (but self-test log was in
1790 // ATA-5).
1792 {
1793  return data->offline_data_collection_capability & 0x01;
1794 }
1795 
1796 // Note in the ATA-5 standard, the following bit is listed as "Vendor
1797 // Specific". So it may not be reliable. The only use of this that I
1798 // have found is in IBM drives, where it is well-documented. See for
1799 // example page 170, section 13.32.1.18 of the IBM Travelstar 40GNX
1800 // hard disk drive specifications page 164 Revision 1.1 22 Apr 2002.
1802 {
1803  return data->offline_data_collection_capability & 0x02;
1804 }
1806 {
1807  return data->offline_data_collection_capability & 0x04;
1808 }
1810 {
1811  return data->offline_data_collection_capability & 0x08;
1812 }
1814 {
1815  return data->offline_data_collection_capability & 0x10;
1816 }
1818 {
1819  return data->offline_data_collection_capability & 0x20;
1820 }
1822 {
1823  return data->offline_data_collection_capability & 0x40;
1824 }
1825 
1826 // Get attribute state
1828  int attridx,
1829  const ata_smart_threshold_entry * thresholds,
1830  const ata_vendor_attr_defs & defs,
1831  unsigned char * threshval /* = 0 */)
1832 {
1833  if (!attr.id)
1834  return ATTRSTATE_NON_EXISTING;
1835 
1836  // Normalized values (current,worst,threshold) not valid
1837  // if specified by '-v' option.
1838  // (Some SSD disks uses these bytes to store raw value).
1839  if (defs[attr.id].flags & ATTRFLAG_NO_NORMVAL)
1840  return ATTRSTATE_NO_NORMVAL;
1841 
1842  // Normally threshold is at same index as attribute
1843  int i = attridx;
1844  if (thresholds[i].id != attr.id) {
1845  // Find threshold id in table
1846  for (i = 0; thresholds[i].id != attr.id; ) {
1847  if (++i >= NUMBER_ATA_SMART_ATTRIBUTES)
1848  // Threshold id missing or thresholds cannot be read
1849  return ATTRSTATE_NO_THRESHOLD;
1850  }
1851  }
1852  unsigned char threshold = thresholds[i].threshold;
1853 
1854  // Return threshold if requested
1855  if (threshval)
1856  *threshval = threshold;
1857 
1858  // Don't report a failed attribute if its threshold is 0.
1859  // ATA-3 (X3T13/2008D Revision 7b) declares 0x00 as the "always passing"
1860  // threshold (Later ATA versions declare all thresholds as "obsolete").
1861  // In practice, threshold value 0 is often used for usage attributes.
1862  if (!threshold)
1863  return ATTRSTATE_OK;
1864 
1865  // Failed now if current value is below threshold
1866  if (attr.current <= threshold)
1867  return ATTRSTATE_FAILED_NOW;
1868 
1869  // Failed in the past if worst value is below threshold
1870  if (!(defs[attr.id].flags & ATTRFLAG_NO_WORSTVAL) && attr.worst <= threshold)
1871  return ATTRSTATE_FAILED_PAST;
1872 
1873  return ATTRSTATE_OK;
1874 }
1875 
1876 // Get attribute raw value.
1878  const ata_vendor_attr_defs & defs)
1879 {
1880  const ata_vendor_attr_defs::entry & def = defs[attr.id];
1881  // TODO: Allow Byteorder in DEFAULT entry
1882 
1883  // Use default byteorder if not specified
1884  const char * byteorder = def.byteorder;
1885  if (!*byteorder) {
1886  switch (def.raw_format) {
1887  case RAWFMT_RAW64:
1888  case RAWFMT_HEX64:
1889  byteorder = "543210wv"; break;
1890  case RAWFMT_RAW56:
1891  case RAWFMT_HEX56:
1893  case RAWFMT_MSEC24_HOUR32:
1894  byteorder = "r543210"; break;
1895  default:
1896  byteorder = "543210"; break;
1897  }
1898  }
1899 
1900  // Build 64-bit value from selected bytes
1901  uint64_t rawvalue = 0;
1902  for (int i = 0; byteorder[i]; i++) {
1903  unsigned char b;
1904  switch (byteorder[i]) {
1905  case '0': b = attr.raw[0]; break;
1906  case '1': b = attr.raw[1]; break;
1907  case '2': b = attr.raw[2]; break;
1908  case '3': b = attr.raw[3]; break;
1909  case '4': b = attr.raw[4]; break;
1910  case '5': b = attr.raw[5]; break;
1911  case 'r': b = attr.reserv; break;
1912  case 'v': b = attr.current; break;
1913  case 'w': b = attr.worst; break;
1914  default : b = 0; break;
1915  }
1916  rawvalue <<= 8; rawvalue |= b;
1917  }
1918 
1919  return rawvalue;
1920 }
1921 
1922 // Helper functions for RAWFMT_TEMPMINMAX
1923 static inline int check_temp_word(unsigned word)
1924 {
1925  if (word <= 0x7f)
1926  return 0x11; // >= 0, signed byte or word
1927  if (word <= 0xff)
1928  return 0x01; // < 0, signed byte
1929  if (0xff80 <= word)
1930  return 0x10; // < 0, signed word
1931  return 0x00;
1932 }
1933 
1934 static bool check_temp_range(int t, unsigned char ut1, unsigned char ut2,
1935  int & lo, int & hi)
1936 {
1937  int t1 = (signed char)ut1, t2 = (signed char)ut2;
1938  if (t1 > t2) {
1939  int tx = t1; t1 = t2; t2 = tx;
1940  }
1941 
1942  if ( -60 <= t1 && t1 <= t && t <= t2 && t2 <= 120
1943  && !(t1 == -1 && t2 <= 0) ) {
1944  lo = t1; hi = t2;
1945  return true;
1946  }
1947  return false;
1948 }
1949 
1950 // Format attribute raw value.
1952  const ata_vendor_attr_defs & defs)
1953 {
1954  // Get 48 bit or 64 bit raw value
1955  uint64_t rawvalue = ata_get_attr_raw_value(attr, defs);
1956 
1957  // Split into bytes and words
1958  unsigned char raw[6];
1959  raw[0] = (unsigned char) rawvalue;
1960  raw[1] = (unsigned char)(rawvalue >> 8);
1961  raw[2] = (unsigned char)(rawvalue >> 16);
1962  raw[3] = (unsigned char)(rawvalue >> 24);
1963  raw[4] = (unsigned char)(rawvalue >> 32);
1964  raw[5] = (unsigned char)(rawvalue >> 40);
1965  unsigned word[3];
1966  word[0] = raw[0] | (raw[1] << 8);
1967  word[1] = raw[2] | (raw[3] << 8);
1968  word[2] = raw[4] | (raw[5] << 8);
1969 
1970  // Get print format
1971  ata_attr_raw_format format = defs[attr.id].raw_format;
1972  if (format == RAWFMT_DEFAULT) {
1973  // Get format from DEFAULT entry
1974  format = get_default_attr_defs()[attr.id].raw_format;
1975  if (format == RAWFMT_DEFAULT)
1976  // Unknown Attribute
1977  format = RAWFMT_RAW48;
1978  }
1979 
1980  // Print
1981  std::string s;
1982  switch (format) {
1983  case RAWFMT_RAW8:
1984  s = strprintf("%d %d %d %d %d %d",
1985  raw[5], raw[4], raw[3], raw[2], raw[1], raw[0]);
1986  break;
1987 
1988  case RAWFMT_RAW16:
1989  s = strprintf("%u %u %u", word[2], word[1], word[0]);
1990  break;
1991 
1992  case RAWFMT_RAW48:
1993  case RAWFMT_RAW56:
1994  case RAWFMT_RAW64:
1995  s = strprintf("%" PRIu64, rawvalue);
1996  break;
1997 
1998  case RAWFMT_HEX48:
1999  s = strprintf("0x%012" PRIx64, rawvalue);
2000  break;
2001 
2002  case RAWFMT_HEX56:
2003  s = strprintf("0x%014" PRIx64, rawvalue);
2004  break;
2005 
2006  case RAWFMT_HEX64:
2007  s = strprintf("0x%016" PRIx64, rawvalue);
2008  break;
2009 
2011  s = strprintf("%u", word[0]);
2012  if (word[1] || word[2])
2013  s += strprintf(" (%u %u)", word[2], word[1]);
2014  break;
2015 
2017  s = strprintf("%u", word[0]);
2018  if (word[1])
2019  s += strprintf(" (Average %u)", word[1]);
2020  break;
2021 
2022  case RAWFMT_RAW24_OPT_RAW8:
2023  s = strprintf("%u", (unsigned)(rawvalue & 0x00ffffffULL));
2024  if (raw[3] || raw[4] || raw[5])
2025  s += strprintf(" (%d %d %d)", raw[5], raw[4], raw[3]);
2026  break;
2027 
2029  s = strprintf("%u/%u",
2030  (unsigned)(rawvalue >> 24), (unsigned)(rawvalue & 0x00ffffffULL));
2031  break;
2032 
2034  s = strprintf("%u/%u",
2035  (unsigned)(rawvalue >> 32), (unsigned)(rawvalue & 0xffffffffULL));
2036  break;
2037 
2038  case RAWFMT_MIN2HOUR:
2039  {
2040  // minutes
2041  int64_t temp = word[0]+(word[1]<<16);
2042  int64_t tmp1 = temp/60;
2043  int64_t tmp2 = temp%60;
2044  s = strprintf("%" PRIu64 "h+%02" PRIu64 "m", tmp1, tmp2);
2045  if (word[2])
2046  s += strprintf(" (%u)", word[2]);
2047  }
2048  break;
2049 
2050  case RAWFMT_SEC2HOUR:
2051  {
2052  // seconds
2053  int64_t hours = rawvalue/3600;
2054  int64_t minutes = (rawvalue-3600*hours)/60;
2055  int64_t seconds = rawvalue%60;
2056  s = strprintf("%" PRIu64 "h+%02" PRIu64 "m+%02" PRIu64 "s", hours, minutes, seconds);
2057  }
2058  break;
2059 
2060  case RAWFMT_HALFMIN2HOUR:
2061  {
2062  // 30-second counter
2063  int64_t hours = rawvalue/120;
2064  int64_t minutes = (rawvalue-120*hours)/2;
2065  s += strprintf("%" PRIu64 "h+%02" PRIu64 "m", hours, minutes);
2066  }
2067  break;
2068 
2069  case RAWFMT_MSEC24_HOUR32:
2070  {
2071  // hours + milliseconds
2072  unsigned hours = (unsigned)(rawvalue & 0xffffffffULL);
2073  unsigned milliseconds = (unsigned)(rawvalue >> 32);
2074  unsigned seconds = milliseconds / 1000;
2075  s = strprintf("%uh+%02um+%02u.%03us",
2076  hours, seconds / 60, seconds % 60, milliseconds % 1000);
2077  }
2078  break;
2079 
2080  case RAWFMT_TEMPMINMAX:
2081  // Temperature
2082  {
2083  // Search for possible min/max values
2084  // [5][4][3][2][1][0] raw[]
2085  // [ 2 ] [ 1 ] [ 0 ] word[]
2086  // xx HH xx LL xx TT (Hitachi/HGST)
2087  // xx LL xx HH xx TT (Kingston SSDs)
2088  // 00 00 HH LL xx TT (Maxtor, Samsung, Seagate, Toshiba)
2089  // 00 00 00 HH LL TT (WDC)
2090  // CC CC HH LL xx TT (WDC, CCCC=over temperature count)
2091  // (xx = 00/ff, possibly sign extension of lower byte)
2092 
2093  int t = (signed char)raw[0];
2094  int lo = 0, hi = 0;
2095 
2096  int tformat;
2097  int ctw0 = check_temp_word(word[0]);
2098  if (!word[2]) {
2099  if (!word[1] && ctw0)
2100  // 00 00 00 00 xx TT
2101  tformat = 0;
2102  else if (ctw0 && check_temp_range(t, raw[2], raw[3], lo, hi))
2103  // 00 00 HL LH xx TT
2104  tformat = 1;
2105  else if (!raw[3] && check_temp_range(t, raw[1], raw[2], lo, hi))
2106  // 00 00 00 HL LH TT
2107  tformat = 2;
2108  else
2109  tformat = -1;
2110  }
2111  else if (ctw0) {
2112  if ( (ctw0 & check_temp_word(word[1]) & check_temp_word(word[2])) != 0x00
2113  && check_temp_range(t, raw[2], raw[4], lo, hi) )
2114  // xx HL xx LH xx TT
2115  tformat = 3;
2116  else if ( word[2] < 0x7fff
2117  && check_temp_range(t, raw[2], raw[3], lo, hi)
2118  && hi >= 40 )
2119  // CC CC HL LH xx TT
2120  tformat = 4;
2121  else
2122  tformat = -2;
2123  }
2124  else
2125  tformat = -3;
2126 
2127  switch (tformat) {
2128  case 0:
2129  s = strprintf("%d", t);
2130  break;
2131  case 1: case 2: case 3:
2132  s = strprintf("%d (Min/Max %d/%d)", t, lo, hi);
2133  break;
2134  case 4:
2135  s = strprintf("%d (Min/Max %d/%d #%d)", t, lo, hi, word[2]);
2136  break;
2137  default:
2138  s = strprintf("%d (%d %d %d %d %d)", raw[0], raw[5], raw[4], raw[3], raw[2], raw[1]);
2139  break;
2140  }
2141  }
2142  break;
2143 
2144  case RAWFMT_TEMP10X:
2145  // ten times temperature in Celsius
2146  s = strprintf("%d.%d", word[0]/10, word[0]%10);
2147  break;
2148 
2149  default:
2150  s = "?"; // Should not happen
2151  break;
2152  }
2153 
2154  return s;
2155 }
2156 
2157 // Get attribute name
2158 std::string ata_get_smart_attr_name(unsigned char id, const ata_vendor_attr_defs & defs,
2159  int rpm /* = 0 */)
2160 {
2161  if (!defs[id].name.empty())
2162  return defs[id].name;
2163  else {
2165  if (def.name.empty())
2166  return "Unknown_Attribute";
2167  else if ((def.flags & ATTRFLAG_HDD_ONLY) && rpm == 1)
2168  return "Unknown_SSD_Attribute";
2169  else if ((def.flags & ATTRFLAG_SSD_ONLY) && rpm > 1)
2170  return "Unknown_HDD_Attribute";
2171  else
2172  return def.name;
2173  }
2174 }
2175 
2176 // Find attribute index for attribute id, -1 if not found.
2177 int ata_find_attr_index(unsigned char id, const ata_smart_values & smartval)
2178 {
2179  if (!id)
2180  return -1;
2181  for (int i = 0; i < NUMBER_ATA_SMART_ATTRIBUTES; i++) {
2182  if (smartval.vendor_attributes[i].id == id)
2183  return i;
2184  }
2185  return -1;
2186 }
2187 
2188 // Return Temperature Attribute raw value selected according to possible
2189 // non-default interpretations. If the Attribute does not exist, return 0
2191 {
2192  for (int i = 0; i < 4; i++) {
2193  static const unsigned char ids[4] = {194, 190, 9, 220};
2194  unsigned char id = ids[i];
2195  const ata_attr_raw_format format = defs[id].raw_format;
2196  if (!( ((id == 194 || id == 190) && format == RAWFMT_DEFAULT)
2197  || format == RAWFMT_TEMPMINMAX || format == RAWFMT_TEMP10X))
2198  continue;
2199  int idx = ata_find_attr_index(id, *data);
2200  if (idx < 0)
2201  continue;
2203  unsigned temp;
2204  // ignore possible min/max values in high words
2205  if (format == RAWFMT_TEMP10X) // -v N,temp10x
2206  temp = ((unsigned short)raw + 5) / 10;
2207  else
2208  temp = (unsigned char)raw;
2209  if (!(0 < temp && temp < 128))
2210  continue;
2211  return temp;
2212  }
2213  // No valid attribute found
2214  return 0;
2215 }
2216 
2217 
2218 // Read SCT Status
2220 {
2221  // read SCT status via SMART log 0xe0
2222  memset(sts, 0, sizeof(*sts));
2223  if (smartcommandhandler(device, READ_LOG, 0xe0, (char *)sts)){
2224  pout("Read SCT Status failed: %s\n", device->get_errmsg());
2225  return -1;
2226  }
2227 
2228  // swap endian order if needed
2229  if (isbigendian()){
2230  swapx(&sts->format_version);
2231  swapx(&sts->sct_version);
2232  swapx(&sts->sct_spec);
2233  swapx(&sts->ext_status_code);
2234  swapx(&sts->action_code);
2235  swapx(&sts->function_code);
2236  swapx(&sts->over_limit_count);
2237  swapx(&sts->under_limit_count);
2238  swapx(&sts->smart_status);
2239  }
2240 
2241  // Check format version
2242  if (!(sts->format_version == 2 || sts->format_version == 3)) {
2243  pout("Unknown SCT Status format version %u, should be 2 or 3.\n", sts->format_version);
2244  return -1;
2245  }
2246  return 0;
2247 }
2248 
2249 // Read SCT Temperature History Table
2252 {
2253  // Initial SCT status must be provided by caller
2254 
2255  // Do nothing if other SCT command is executing
2256  if (sts->ext_status_code == 0xffff) {
2257  pout("Another SCT command is executing, abort Read Data Table\n"
2258  "(SCT ext_status_code 0x%04x, action_code=%u, function_code=%u)\n",
2259  sts->ext_status_code, sts->action_code, sts->function_code);
2260  return -1;
2261  }
2262 
2263  ata_sct_data_table_command cmd; memset(&cmd, 0, sizeof(cmd));
2264  // CAUTION: DO NOT CHANGE THIS VALUE (SOME ACTION CODES MAY ERASE DISK)
2265  cmd.action_code = 5; // Data table command
2266  cmd.function_code = 1; // Read table
2267  cmd.table_id = 2; // Temperature History Table
2268 
2269  // swap endian order if needed
2270  if (isbigendian()) {
2271  swapx(&cmd.action_code);
2272  swapx(&cmd.function_code);
2273  swapx(&cmd.table_id);
2274  }
2275 
2276  // write command via SMART log page 0xe0
2277  if (smartcommandhandler(device, WRITE_LOG, 0xe0, (char *)&cmd)){
2278  pout("Write SCT Data Table failed: %s\n", device->get_errmsg());
2279  return -1;
2280  }
2281 
2282  // read SCT data via SMART log page 0xe1
2283  memset(tmh, 0, sizeof(*tmh));
2284  if (smartcommandhandler(device, READ_LOG, 0xe1, (char *)tmh)){
2285  pout("Read SCT Data Table failed: %s\n", device->get_errmsg());
2286  return -1;
2287  }
2288 
2289  // re-read and check SCT status
2290  if (ataReadSCTStatus(device, sts))
2291  return -1;
2292 
2293  if (!(sts->ext_status_code == 0 && sts->action_code == 5 && sts->function_code == 1)) {
2294  pout("Unexpected SCT status 0x%04x (action_code=%u, function_code=%u)\n",
2295  sts->ext_status_code, sts->action_code, sts->function_code);
2296  return -1;
2297  }
2298 
2299  // swap endian order if needed
2300  if (isbigendian()){
2301  swapx(&tmh->format_version);
2302  swapx(&tmh->sampling_period);
2303  swapx(&tmh->interval);
2304  swapx(&tmh->cb_index);
2305  swapx(&tmh->cb_size);
2306  }
2307  return 0;
2308 }
2309 
2310 // Common function for Get/Set SCT Feature Control:
2311 // Write Cache, Write Cache Reordering, etc.
2312 static int ataGetSetSCTFeatureControl(ata_device * device, unsigned short feature_code,
2313  unsigned short state, bool persistent, bool set)
2314 {
2315  // Check initial status
2317  if (ataReadSCTStatus(device, &sts))
2318  return -1;
2319 
2320  // Do nothing if other SCT command is executing
2321  if (sts.ext_status_code == 0xffff) {
2322  pout("Another SCT command is executing, abort Feature Control\n"
2323  "(SCT ext_status_code 0x%04x, action_code=%u, function_code=%u)\n",
2324  sts.ext_status_code, sts.action_code, sts.function_code);
2325  return -1;
2326  }
2327 
2328  ata_sct_feature_control_command cmd; memset(&cmd, 0, sizeof(cmd));
2329  // CAUTION: DO NOT CHANGE THIS VALUE (SOME ACTION CODES MAY ERASE DISK)
2330  cmd.action_code = 4; // Feature Control command
2331  cmd.function_code = (set ? 1 : 2); // 1=Set, 2=Get
2332  cmd.feature_code = feature_code;
2333  cmd.state = state;
2334  cmd.option_flags = (persistent ? 0x01 : 0x00);
2335 
2336  // swap endian order if needed
2337  if (isbigendian()) {
2338  swapx(&cmd.action_code);
2339  swapx(&cmd.function_code);
2340  swapx(&cmd.feature_code);
2341  swapx(&cmd.state);
2342  swapx(&cmd.option_flags);
2343  }
2344 
2345  // write command via SMART log page 0xe0
2346  // TODO: Debug output
2347  ata_cmd_in in;
2351  in.in_regs.lba_low = 0xe0;
2352  in.set_data_out(&cmd, 1);
2353 
2354  if (!set)
2355  // Time limit returned in ATA registers
2356  in.out_needed.sector_count = in.out_needed.lba_low = true;
2357 
2358  ata_cmd_out out;
2359  if (!device->ata_pass_through(in, out)) {
2360  pout("Write SCT (%cet) Feature Control Command failed: %s\n",
2361  (!set ? 'G' : 'S'), device->get_errmsg());
2362  return -1;
2363  }
2364  state = out.out_regs.sector_count | (out.out_regs.lba_low << 8);
2365 
2366  // re-read and check SCT status
2367  if (ataReadSCTStatus(device, &sts))
2368  return -1;
2369 
2370  if (!(sts.ext_status_code == 0 && sts.action_code == 4 && sts.function_code == (set ? 1 : 2))) {
2371  pout("Unexpected SCT status 0x%04x (action_code=%u, function_code=%u)\n",
2372  sts.ext_status_code, sts.action_code, sts.function_code);
2373  return -1;
2374  }
2375  return state;
2376 }
2377 
2378 // Get/Set Write Cache Reordering
2379 int ataGetSetSCTWriteCacheReordering(ata_device * device, bool enable, bool persistent, bool set)
2380 {
2381  return ataGetSetSCTFeatureControl(device, 2 /* Enable/Disable Write Cache Reordering */,
2382  (enable ? 1 : 2), persistent, set);
2383 }
2384 
2385 // Get/Set Write Cache (force enable, force disable,
2386 int ataGetSetSCTWriteCache(ata_device * device, unsigned short state, bool persistent, bool set)
2387 {
2388  return ataGetSetSCTFeatureControl(device, 1 /* Enable/Disable Write Cache */,
2389  state, persistent, set);
2390 }
2391 
2392 // Set SCT Temperature Logging Interval
2393 int ataSetSCTTempInterval(ata_device * device, unsigned interval, bool persistent)
2394 {
2395  // Check initial status
2397  if (ataReadSCTStatus(device, &sts))
2398  return -1;
2399 
2400  // Do nothing if other SCT command is executing
2401  if (sts.ext_status_code == 0xffff) {
2402  pout("Another SCT command is executing, abort Feature Control\n"
2403  "(SCT ext_status_code 0x%04x, action_code=%u, function_code=%u)\n",
2404  sts.ext_status_code, sts.action_code, sts.function_code);
2405  return -1;
2406  }
2407 
2408  ata_sct_feature_control_command cmd; memset(&cmd, 0, sizeof(cmd));
2409  // CAUTION: DO NOT CHANGE THIS VALUE (SOME ACTION CODES MAY ERASE DISK)
2410  cmd.action_code = 4; // Feature Control command
2411  cmd.function_code = 1; // Set state
2412  cmd.feature_code = 3; // Temperature logging interval
2413  cmd.state = interval;
2414  cmd.option_flags = (persistent ? 0x01 : 0x00);
2415 
2416  // swap endian order if needed
2417  if (isbigendian()) {
2418  swapx(&cmd.action_code);
2419  swapx(&cmd.function_code);
2420  swapx(&cmd.feature_code);
2421  swapx(&cmd.state);
2422  swapx(&cmd.option_flags);
2423  }
2424 
2425  // write command via SMART log page 0xe0
2426  if (smartcommandhandler(device, WRITE_LOG, 0xe0, (char *)&cmd)){
2427  pout("Write SCT Feature Control Command failed: %s\n", device->get_errmsg());
2428  return -1;
2429  }
2430 
2431  // re-read and check SCT status
2432  if (ataReadSCTStatus(device, &sts))
2433  return -1;
2434 
2435  if (!(sts.ext_status_code == 0 && sts.action_code == 4 && sts.function_code == 1)) {
2436  pout("Unexpected SCT status 0x%04x (action_code=%u, function_code=%u)\n",
2437  sts.ext_status_code, sts.action_code, sts.function_code);
2438  return -1;
2439  }
2440  return 0;
2441 }
2442 
2443 // Get/Set SCT Error Recovery Control
2444 static int ataGetSetSCTErrorRecoveryControltime(ata_device * device, unsigned type,
2445  bool set, unsigned short & time_limit)
2446 {
2447  // Check initial status
2449  if (ataReadSCTStatus(device, &sts))
2450  return -1;
2451 
2452  // Do nothing if other SCT command is executing
2453  if (sts.ext_status_code == 0xffff) {
2454  pout("Another SCT command is executing, abort Error Recovery Control\n"
2455  "(SCT ext_status_code 0x%04x, action_code=%u, function_code=%u)\n",
2456  sts.ext_status_code, sts.action_code, sts.function_code);
2457  return -1;
2458  }
2459 
2460  ata_sct_error_recovery_control_command cmd; memset(&cmd, 0, sizeof(cmd));
2461  // CAUTION: DO NOT CHANGE THIS VALUE (SOME ACTION CODES MAY ERASE DISK)
2462  cmd.action_code = 3; // Error Recovery Control command
2463  cmd.function_code = (set ? 1 : 2); // 1=Set timer, 2=Get timer
2464  cmd.selection_code = type; // 1=Read timer, 2=Write timer
2465  if (set)
2466  cmd.time_limit = time_limit;
2467 
2468  // swap endian order if needed
2469  if (isbigendian()) {
2470  swapx(&cmd.action_code);
2471  swapx(&cmd.function_code);
2472  swapx(&cmd.selection_code);
2473  swapx(&cmd.time_limit);
2474  }
2475 
2476  // write command via SMART log page 0xe0
2477  // TODO: Debug output
2478  ata_cmd_in in;
2482  in.in_regs.lba_low = 0xe0;
2483  in.set_data_out(&cmd, 1);
2484 
2485  if (!set)
2486  // Time limit returned in ATA registers
2487  in.out_needed.sector_count = in.out_needed.lba_low = true;
2488 
2489  ata_cmd_out out;
2490  if (!device->ata_pass_through(in, out)) {
2491  pout("Write SCT (%cet) Error Recovery Control Command failed: %s\n",
2492  (!set ? 'G' : 'S'), device->get_errmsg());
2493  return -1;
2494  }
2495 
2496  // re-read and check SCT status
2497  if (ataReadSCTStatus(device, &sts))
2498  return -1;
2499 
2500  if (!(sts.ext_status_code == 0 && sts.action_code == 3 && sts.function_code == (set ? 1 : 2))) {
2501  pout("Unexpected SCT status 0x%04x (action_code=%u, function_code=%u)\n",
2502  sts.ext_status_code, sts.action_code, sts.function_code);
2503  return -1;
2504  }
2505 
2506  if (!set) {
2507  // Check whether registers are properly returned by ioctl()
2508  if (!(out.out_regs.sector_count.is_set() && out.out_regs.lba_low.is_set())) {
2509  // TODO: Output register support should be checked within each ata_pass_through()
2510  // implementation before command is issued.
2511  pout("SMART WRITE LOG does not return COUNT and LBA_LOW register\n");
2512  return -1;
2513  }
2514  if ( out.out_regs.sector_count == in.in_regs.sector_count
2515  && out.out_regs.lba_low == in.in_regs.lba_low ) {
2516  // 0xe001 (5734.5s) - this is most likely a broken ATA pass-through implementation
2517  pout("SMART WRITE LOG returns COUNT and LBA_LOW register unchanged\n");
2518  return -1;
2519  }
2520 
2521  // Return value to caller
2522  time_limit = out.out_regs.sector_count | (out.out_regs.lba_low << 8);
2523  }
2524 
2525  return 0;
2526 }
2527 
2528 // Get SCT Error Recovery Control
2529 int ataGetSCTErrorRecoveryControltime(ata_device * device, unsigned type, unsigned short & time_limit)
2530 {
2531  return ataGetSetSCTErrorRecoveryControltime(device, type, false/*get*/, time_limit);
2532 }
2533 
2534 // Set SCT Error Recovery Control
2535 int ataSetSCTErrorRecoveryControltime(ata_device * device, unsigned type, unsigned short time_limit)
2536 {
2537  return ataGetSetSCTErrorRecoveryControltime(device, type, true/*set*/, time_limit);
2538 }
2539 
2540 
2541 // Print one self-test log entry.
2542 // Returns:
2543 // -1: self-test failed
2544 // 1: extended self-test completed without error
2545 // 0: otherwise
2546 int ataPrintSmartSelfTestEntry(unsigned testnum, unsigned char test_type,
2547  unsigned char test_status,
2548  unsigned short timestamp,
2549  uint64_t failing_lba,
2550  bool print_error_only, bool & print_header)
2551 {
2552  // Check status and type for return value
2553  int retval = 0;
2554  switch (test_status >> 4) {
2555  case 0x0:
2556  if ((test_type & 0x0f) == 0x02)
2557  retval = 1; // extended self-test completed without error
2558  break;
2559  case 0x3: case 0x4:
2560  case 0x5: case 0x6:
2561  case 0x7: case 0x8:
2562  retval = -1; // self-test failed
2563  break;
2564  }
2565 
2566  if (retval >= 0 && print_error_only)
2567  return retval;
2568 
2569  std::string msgtest;
2570  switch (test_type) {
2571  case 0x00: msgtest = "Offline"; break;
2572  case 0x01: msgtest = "Short offline"; break;
2573  case 0x02: msgtest = "Extended offline"; break;
2574  case 0x03: msgtest = "Conveyance offline"; break;
2575  case 0x04: msgtest = "Selective offline"; break;
2576  case 0x7f: msgtest = "Abort offline test"; break;
2577  case 0x81: msgtest = "Short captive"; break;
2578  case 0x82: msgtest = "Extended captive"; break;
2579  case 0x83: msgtest = "Conveyance captive"; break;
2580  case 0x84: msgtest = "Selective captive"; break;
2581  default:
2582  if ((0x40 <= test_type && test_type <= 0x7e) || 0x90 <= test_type)
2583  msgtest = strprintf("Vendor (0x%02x)", test_type);
2584  else
2585  msgtest = strprintf("Reserved (0x%02x)", test_type);
2586  }
2587 
2588  std::string msgstat;
2589  switch (test_status >> 4) {
2590  case 0x0: msgstat = "Completed without error"; break;
2591  case 0x1: msgstat = "Aborted by host"; break;
2592  case 0x2: msgstat = "Interrupted (host reset)"; break;
2593  case 0x3: msgstat = "Fatal or unknown error"; break;
2594  case 0x4: msgstat = "Completed: unknown failure"; break;
2595  case 0x5: msgstat = "Completed: electrical failure"; break;
2596  case 0x6: msgstat = "Completed: servo/seek failure"; break;
2597  case 0x7: msgstat = "Completed: read failure"; break;
2598  case 0x8: msgstat = "Completed: handling damage??"; break;
2599  case 0xf: msgstat = "Self-test routine in progress"; break;
2600  default: msgstat = strprintf("Unknown status (0x%x)", test_status >> 4);
2601  }
2602 
2603  // Print header once
2604  if (print_header) {
2605  print_header = false;
2606  pout("Num Test_Description Status Remaining LifeTime(hours) LBA_of_first_error\n");
2607  }
2608 
2609  char msglba[32];
2610  if (retval < 0 && failing_lba < 0xffffffffffffULL)
2611  snprintf(msglba, sizeof(msglba), "%" PRIu64, failing_lba);
2612  else {
2613  msglba[0] = '-'; msglba[1] = 0;
2614  }
2615 
2616  pout("#%2u %-19s %-29s %1d0%% %8u %s\n", testnum,
2617  msgtest.c_str(), msgstat.c_str(), test_status & 0x0f, timestamp, msglba);
2618 
2619  return retval;
2620 }
2621 
2622 // Print Smart self-test log, used by smartctl and smartd.
2623 // return value is:
2624 // bottom 8 bits: number of entries found where self-test showed an error
2625 // remaining bits: if nonzero, power on hours of last self-test where error was found
2627  firmwarebug_defs firmwarebugs)
2628 {
2629  if (allentries)
2630  pout("SMART Self-test log structure revision number %d\n",(int)data->revnumber);
2631  if (data->revnumber != 0x0001 && allentries && !firmwarebugs.is_set(BUG_SAMSUNG))
2632  pout("Warning: ATA Specification requires self-test log structure revision number = 1\n");
2633  if (data->mostrecenttest==0){
2634  if (allentries)
2635  pout("No self-tests have been logged. [To run self-tests, use: smartctl -t]\n");
2636  return 0;
2637  }
2638 
2639  bool noheaderprinted = true;
2640  int errcnt = 0, hours = 0, igncnt = 0;
2641  int testno = 0, ext_ok_testno = -1;
2642 
2643  // print log
2644  for (int i = 20; i >= 0; i--) {
2645  // log is a circular buffer
2646  int j = (i+data->mostrecenttest)%21;
2647  const ata_smart_selftestlog_struct * log = data->selftest_struct+j;
2648 
2649  if (nonempty(log, sizeof(*log))) {
2650  // count entry based on non-empty structures -- needed for
2651  // Seagate only -- other vendors don't have blank entries 'in
2652  // the middle'
2653  testno++;
2654 
2655  // T13/1321D revision 1c: (Data structure Rev #1)
2656 
2657  //The failing LBA shall be the LBA of the uncorrectable sector
2658  //that caused the test to fail. If the device encountered more
2659  //than one uncorrectable sector during the test, this field
2660  //shall indicate the LBA of the first uncorrectable sector
2661  //encountered. If the test passed or the test failed for some
2662  //reason other than an uncorrectable sector, the value of this
2663  //field is undefined.
2664 
2665  // This is true in ALL ATA-5 specs
2666  uint64_t lba48 = (log->lbafirstfailure < 0xffffffff ? log->lbafirstfailure : 0xffffffffffffULL);
2667 
2668  // Print entry
2669  int state = ataPrintSmartSelfTestEntry(testno,
2670  log->selftestnumber, log->selfteststatus,
2671  log->timestamp, lba48, !allentries, noheaderprinted);
2672 
2673  if (state < 0) {
2674  // Self-test showed an error
2675  if (ext_ok_testno < 0) {
2676  errcnt++;
2677 
2678  // keep track of time of most recent error
2679  if (!hours)
2680  hours = log->timestamp;
2681  }
2682  else
2683  // Newer successful extended self-test exits
2684  igncnt++;
2685  }
2686  else if (state > 0 && ext_ok_testno < 0) {
2687  // Latest successful extended self-test
2688  ext_ok_testno = testno;
2689  }
2690  }
2691  }
2692 
2693  if (igncnt)
2694  pout("%d of %d failed self-tests are outdated by newer successful extended offline self-test #%2d\n",
2695  igncnt, igncnt+errcnt, ext_ok_testno);
2696 
2697  if (!allentries && !noheaderprinted)
2698  pout("\n");
2699 
2700  return ((hours << 8) | errcnt);
2701 }
2702 
2703 
2704 /////////////////////////////////////////////////////////////////////////////
2705 // Pseudo-device to parse "smartctl -r ataioctl,2 ..." output and simulate
2706 // an ATA device with same behaviour
2707 
2708 namespace {
2709 
2711 : public /*implements*/ ata_device_with_command_set
2712 {
2713 public:
2714  parsed_ata_device(smart_interface * intf, const char * dev_name);
2715 
2716  virtual ~parsed_ata_device() throw();
2717 
2718  virtual bool is_open() const;
2719 
2720  virtual bool open();
2721 
2722  virtual bool close();
2723 
2724  virtual bool ata_identify_is_cached() const;
2725 
2726 protected:
2727  virtual int ata_command_interface(smart_command_set command, int select, char * data);
2728 
2729 private:
2730  // Table of parsed commands, return value, data
2732  {
2734  int select;
2735  int retval, errval;
2736  char * data;
2737  };
2738 
2739  enum { max_num_commands = 32 };
2740  parsed_ata_command m_command_table[max_num_commands];
2741 
2746 };
2747 
2748 static const char * nextline(const char * s, int & lineno)
2749 {
2750  for (s += strcspn(s, "\r\n"); *s == '\r' || *s == '\n'; s++) {
2751  if (*s == '\r' && s[1] == '\n')
2752  s++;
2753  lineno++;
2754  }
2755  return s;
2756 }
2757 
2758 static int name2command(const char * s)
2759 {
2760  for (int i = 0; i < (int)(sizeof(commandstrings)/sizeof(commandstrings[0])); i++) {
2761  if (!strcmp(s, commandstrings[i]))
2762  return i;
2763  }
2764  return -1;
2765 }
2766 
2767 static bool matchcpy(char * dest, size_t size, const char * src, const regmatch_t & srcmatch)
2768 {
2769  if (srcmatch.rm_so < 0)
2770  return false;
2771  size_t n = srcmatch.rm_eo - srcmatch.rm_so;
2772  if (n >= size)
2773  n = size-1;
2774  memcpy(dest, src + srcmatch.rm_so, n);
2775  dest[n] = 0;
2776  return true;
2777 }
2778 
2779 static inline int matchtoi(const char * src, const regmatch_t & srcmatch, int defval)
2780 {
2781  if (srcmatch.rm_so < 0)
2782  return defval;
2783  return atoi(src + srcmatch.rm_so);
2784 }
2785 
2786 parsed_ata_device::parsed_ata_device(smart_interface * intf, const char * dev_name)
2787 : smart_device(intf, dev_name, "ata", ""),
2788  m_num_commands(0),
2789  m_next_replay_command(0),
2790  m_replay_out_of_sync(false),
2791  m_ata_identify_is_cached(false)
2792 {
2793  memset(m_command_table, 0, sizeof(m_command_table));
2794 }
2795 
2797 {
2798  close();
2799 }
2800 
2802 {
2803  return (m_num_commands > 0);
2804 }
2805 
2806 // Parse stdin and build command table
2808 {
2809  const char * pathname = get_dev_name();
2810  if (strcmp(pathname, "-"))
2811  return set_err(EINVAL);
2812  pathname = "<stdin>";
2813  // Fill buffer
2814  char buffer[64*1024];
2815  int size = 0;
2816  while (size < (int)sizeof(buffer)) {
2817  int nr = fread(buffer, 1, sizeof(buffer), stdin);
2818  if (nr <= 0)
2819  break;
2820  size += nr;
2821  }
2822  if (size <= 0)
2823  return set_err(ENOENT, "%s: Unexpected EOF", pathname);
2824  if (size >= (int)sizeof(buffer))
2825  return set_err(EIO, "%s: Buffer overflow", pathname);
2826  buffer[size] = 0;
2827 
2828  // Regex to match output from "-r ataioctl,2"
2829  static const char pattern[] = "^"
2830  "(" // (1
2831  "REPORT-IOCTL: DeviceF?D?=[^ ]+ Command=([A-Z ]*[A-Z])" // (2)
2832  "(" // (3
2833  "( InputParameter=([0-9]+))?" // (4 (5))
2834  "|"
2835  "( returned (-?[0-9]+)( errno=([0-9]+)[^\r\n]*)?)" // (6 (7) (8 (9)))
2836  ")" // )
2837  "[\r\n]" // EOL match necessary to match optional parts above
2838  "|"
2839  "===== \\[([A-Z ]*[A-Z])\\] DATA START " // (10)
2840  "|"
2841  " *(En|Dis)abled status cached by OS, " // (11)
2842  ")"; // )
2843 
2844  // Compile regex
2845  const regular_expression regex(pattern, REG_EXTENDED);
2846 
2847  // Parse buffer
2848  const char * errmsg = 0;
2849  int i = -1, state = 0, lineno = 1;
2850  for (const char * line = buffer; *line; line = nextline(line, lineno)) {
2851  // Match line
2852  if (!(line[0] == 'R' || line[0] == '=' || line[0] == ' '))
2853  continue;
2854  const int nmatch = 1+11;
2855  regmatch_t match[nmatch];
2856  if (!regex.execute(line, nmatch, match))
2857  continue;
2858 
2859  char cmdname[40];
2860  if (matchcpy(cmdname, sizeof(cmdname), line, match[2])) { // "REPORT-IOCTL:... Command=%s ..."
2861  int nc = name2command(cmdname);
2862  if (nc < 0) {
2863  errmsg = "Unknown ATA command name"; break;
2864  }
2865  if (match[7].rm_so < 0) { // "returned %d"
2866  // Start of command
2867  if (!(state == 0 || state == 2)) {
2868  errmsg = "Missing REPORT-IOCTL result"; break;
2869  }
2870  if (++i >= max_num_commands) {
2871  errmsg = "Too many ATA commands"; break;
2872  }
2874  m_command_table[i].select = matchtoi(line, match[5], 0); // "InputParameter=%d"
2875  state = 1;
2876  }
2877  else {
2878  // End of command
2879  if (!(state == 1 && (int)m_command_table[i].command == nc)) {
2880  errmsg = "Missing REPORT-IOCTL start"; break;
2881  }
2882  m_command_table[i].retval = matchtoi(line, match[7], -1); // "returned %d"
2883  m_command_table[i].errval = matchtoi(line, match[9], 0); // "errno=%d"
2884  state = 2;
2885  }
2886  }
2887  else if (matchcpy(cmdname, sizeof(cmdname), line, match[10])) { // "===== [%s] DATA START "
2888  // Start of sector hexdump
2889  int nc = name2command(cmdname);
2890  if (!(state == (nc == WRITE_LOG ? 1 : 2) && (int)m_command_table[i].command == nc)) {
2891  errmsg = "Unexpected DATA START"; break;
2892  }
2893  line = nextline(line, lineno);
2894  char * data = (char *)malloc(512);
2895  unsigned j;
2896  for (j = 0; j < 32; j++) {
2897  unsigned b[16];
2898  unsigned u1, u2; int n1 = -1;
2899  if (!(sscanf(line, "%3u-%3u: "
2900  "%2x %2x %2x %2x %2x %2x %2x %2x "
2901  "%2x %2x %2x %2x %2x %2x %2x %2x%n",
2902  &u1, &u2,
2903  b+ 0, b+ 1, b+ 2, b+ 3, b+ 4, b+ 5, b+ 6, b+ 7,
2904  b+ 8, b+ 9, b+10, b+11, b+12, b+13, b+14, b+15, &n1) == 18
2905  && n1 >= 56 && u1 == j*16 && u2 == j*16+15))
2906  break;
2907  for (unsigned k = 0; k < 16; k++)
2908  data[j*16+k] = b[k];
2909  line = nextline(line, lineno);
2910  }
2911  if (j < 32) {
2912  free(data);
2913  errmsg = "Incomplete sector hex dump"; break;
2914  }
2915  m_command_table[i].data = data;
2916  if (nc != WRITE_LOG)
2917  state = 0;
2918  }
2919  else if (match[11].rm_so > 0) { // "(En|Dis)abled status cached by OS"
2920  m_ata_identify_is_cached = true;
2921  }
2922  }
2923 
2924  if (!(state == 0 || state == 2))
2925  errmsg = "Missing REPORT-IOCTL result";
2926 
2927  if (!errmsg && i < 0)
2928  errmsg = "No information found";
2929 
2930  m_num_commands = i+1;
2932  m_replay_out_of_sync = false;
2933 
2934  if (errmsg) {
2935  close();
2936  return set_err(EIO, "%s(%d): Syntax error: %s", pathname, lineno, errmsg);
2937  }
2938  return true;
2939 }
2940 
2941 // Report warnings and free command table
2943 {
2945  pout("REPLAY-IOCTL: Warning: commands replayed out of sync\n");
2946  else if (m_next_replay_command != 0)
2947  pout("REPLAY-IOCTL: Warning: %d command(s) not replayed\n", m_num_commands-m_next_replay_command);
2948 
2949  for (int i = 0; i < m_num_commands; i++) {
2950  if (m_command_table[i].data) {
2951  free(m_command_table[i].data); m_command_table[i].data = 0;
2952  }
2953  }
2954  m_num_commands = 0;
2956  m_replay_out_of_sync = false;
2957  return true;
2958 }
2959 
2960 
2962 {
2963  return m_ata_identify_is_cached;
2964 }
2965 
2966 
2967 // Simulate ATA command from command table
2969 {
2970  // Find command, try round-robin if out of sync
2971  int i = m_next_replay_command;
2972  for (int j = 0; ; j++) {
2973  if (j >= m_num_commands) {
2974  pout("REPLAY-IOCTL: Warning: Command not found\n");
2975  errno = ENOSYS;
2976  return -1;
2977  }
2978  if (m_command_table[i].command == command && m_command_table[i].select == select)
2979  break;
2980  if (!m_replay_out_of_sync) {
2981  m_replay_out_of_sync = true;
2982  pout("REPLAY-IOCTL: Warning: Command #%d is out of sync\n", i+1);
2983  }
2984  if (++i >= m_num_commands)
2985  i = 0;
2986  }
2990 
2991  // Return command data
2992  switch (command) {
2993  case IDENTIFY:
2994  case PIDENTIFY:
2995  case READ_VALUES:
2996  case READ_THRESHOLDS:
2997  case READ_LOG:
2998  if (m_command_table[i].data)
2999  memcpy(data, m_command_table[i].data, 512);
3000  break;
3001  case WRITE_LOG:
3002  if (!(m_command_table[i].data && !memcmp(data, m_command_table[i].data, 512)))
3003  pout("REPLAY-IOCTL: Warning: WRITE LOG data does not match\n");
3004  break;
3005  case CHECK_POWER_MODE:
3006  data[0] = (char)0xff;
3007  default:
3008  break;
3009  }
3010 
3011  if (m_command_table[i].errval)
3012  errno = m_command_table[i].errval;
3013  return m_command_table[i].retval;
3014 }
3015 
3016 } // namespace
3017 
3018 ata_device * get_parsed_ata_device(smart_interface * intf, const char * dev_name)
3019 {
3020  return new parsed_ata_device(intf, dev_name);
3021 }
unsigned short int timestamp
Definition: atacmds.h:412
unsigned short command_set_extension
Definition: atacmds.h:140
u8 raw[128]
Definition: megaraid.h:86
#define CONVEYANCE_CAPTIVE_SELF_TEST
Definition: atacmds.h:119
#define ATA_SMART_READ_LOG_SECTOR
Definition: atacmds.h:100
virtual int64_t get_timer_usec()
Get microseconds since some unspecified starting point.
unsigned char errorlog_capability
Definition: atacmds.h:221
#define ATA_SMART_WRITE_LOG_SECTOR
Definition: atacmds.h:101
#define SMART_CYL_HI
Definition: atacmds.cpp:51
int isSupportSelectiveSelfTest(const ata_smart_values *data)
Definition: atacmds.cpp:1821
#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:135
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:1482
unsigned phy_sector_size
Definition: atacmds.h:998
int ata_find_attr_index(unsigned char id, const ata_smart_values &smartval)
Definition: atacmds.cpp:2177
uint64_t end
Definition: atacmds.h:491
#define NUMBER_ATA_SMART_ATTRIBUTES
Definition: atacmds.h:124
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:2158
unsigned short function_code
Definition: atacmds.h:575
int isSupportExecuteOfflineImmediate(const ata_smart_values *data)
Definition: atacmds.cpp:1791
struct test_span span[5]
Definition: atacmds.h:499
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:156
unsigned short currentspan
Definition: atacmds.h:503
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:385
unsigned short format_version
Definition: atacmds.h:528
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:2190
unsigned short csf_default
Definition: atacmds.h:143
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:316
unsigned short smart_status
Definition: atacmds.h:548
virtual bool is_open() const
Return true if device is open.
Definition: atacmds.cpp:2801
static int check_temp_word(unsigned word)
Definition: atacmds.cpp:1923
unsigned short error_log_index
Definition: atacmds.h:397
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:398
int ataReadSelectiveSelfTestLog(ata_device *device, struct ata_selective_self_test_log *data)
Definition: atacmds.cpp:1175
int TestTime(const ata_smart_values *data, int testtype)
Definition: atacmds.cpp:1691
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:104
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:158
unsigned char extend_test_completion_time_b
Definition: atacmds.h:224
Adapter class to implement new ATA pass through old interface.
unsigned char reserv
Definition: atacmds.h:159
ATA Input registers (for 28-bit commands)
int ataGetSetSCTWriteCache(ata_device *device, unsigned short state, bool persistent, bool set)
Definition: atacmds.cpp:2386
int ataGetSCTErrorRecoveryControltime(ata_device *device, unsigned type, unsigned short &time_limit)
Definition: atacmds.cpp:2529
#define ATA_SMART_AUTOSAVE
Definition: atacmds.h:97
#define EXTEND_SELF_TEST
Definition: atacmds.h:113
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:1204
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:1542
unsigned char self_test_exec_status
Definition: atacmds.h:216
ata_attr_raw_format
Definition: atacmds.h:661
static void swapbytes(char *out, const char *in, size_t n)
Definition: atacmds.cpp:732
ata_smart_exterrlog_command commands[5]
Definition: atacmds.h:384
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:995
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:1749
static int ataGetSetSCTFeatureControl(ata_device *device, unsigned short feature_code, unsigned short state, bool persistent, bool set)
Definition: atacmds.cpp:2312
bool is_set(firmwarebug_t bug) const
Definition: atacmds.h:741
#define ATA_IDENTIFY_DEVICE
Definition: atacmds.h:72
unsigned int lbafirstfailure
Definition: atacmds.h:414
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:1827
ata_register lba_mid
unsigned short function_code
Definition: atacmds.h:590
struct ata_smart_extselftestlog_desc log_descs[19]
Definition: atacmds.h:461
unsigned short log_desc_index
Definition: atacmds.h:460
#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:2379
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:603
const ata_vendor_attr_defs & get_default_attr_defs()
ata_attr_raw_format raw_format
Definition: atacmds.h:701
uint8_t id
struct ata_smart_attribute vendor_attributes[NUMBER_ATA_SMART_ATTRIBUTES]
Definition: atacmds.h:214
ata_in_regs_48bit in_regs
Input registers.
unsigned short command_set_1
Definition: atacmds.h:138
int ataDisableSmart(ata_device *device)
Definition: atacmds.cpp:1534
unsigned short action_code
Definition: atacmds.h:574
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:1460
unsigned short flags
Definition: atacmds.h:155
ptr_t data
Definition: megaraid.h:94
Definition: atacmds.h:245
unsigned short function_code
Definition: atacmds.h:536
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:1951
unsigned short command_set_2
Definition: atacmds.h:139
#define SELECTIVE_SELF_TEST
Definition: atacmds.h:115
static bool matchcpy(char *dest, size_t size, const char *src, const regmatch_t &srcmatch)
Definition: atacmds.cpp:2767
enum ata_cmd_in::@27 direction
I/O direction.
void set_data_in(void *buf, unsigned nsectors)
Prepare for 28-bit DATA IN command.
unsigned short pendingtime
Definition: atacmds.h:506
uint64_t start
Definition: atacmds.h:490
unsigned short ext_status_code
Definition: atacmds.h:534
#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:1102
static void fix_exterrlog_lba(ata_smart_exterrlog *log, unsigned nsectors)
Definition: atacmds.cpp:1469
#define ATA_CHECK_POWER_MODE
Definition: atacmds.h:71
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:220
unsigned log_sector_offset
Definition: atacmds.h:999
const char *const map_old_vendor_opts[][2]
Definition: atacmds.cpp:138
unsigned short words088_255[168]
Definition: atacmds.h:144
int ataReadSCTStatus(ata_device *device, ata_sct_status_response *sts)
Definition: atacmds.cpp:2219
int ataReadSmartValues(ata_device *device, struct ata_smart_values *data)
Definition: atacmds.cpp:988
unsigned short sct_spec
Definition: atacmds.h:530
unsigned int over_limit_count
Definition: atacmds.h:546
unsigned log_sector_size
Definition: atacmds.h:997
unsigned short device_error_count
Definition: atacmds.h:399
ata_attr_state
Definition: atacmds.h:896
#define ABORT_SELF_TEST
Definition: atacmds.h:116
void swapx(unsigned short *p)
Definition: atacmds.h:1014
int isSupportOfflineSurfaceScan(const ata_smart_values *data)
Definition: atacmds.cpp:1809
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:1405
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:152
static int matchtoi(const char *src, const regmatch_t &srcmatch, int defval)
Definition: atacmds.cpp:2779
struct ata_smart_errorlog_struct errorlog_struct[5]
Definition: atacmds.h:315
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:2968
unsigned short int total_time_to_complete_off_line
Definition: atacmds.h:217
struct ata_smart_selftestlog_struct selftest_struct[21]
Definition: atacmds.h:424
unsigned short action_code
Definition: atacmds.h:535
const char * name
Definition: atacmds.cpp:109
int isSupportConveyanceSelfTest(const ata_smart_values *data)
Definition: atacmds.cpp:1817
void pout(const char *fmt,...)
Definition: smartctl.cpp:1170
const unsigned num_old_vendor_opts
Definition: atacmds.cpp:155
#define OFFLINE_FULL_SCAN
Definition: atacmds.h:111
ptr_t buffer
Definition: megaraid.h:89
unsigned char fw_rev[8]
Definition: atacmds.h:133
int ataEnableAutoOffline(ata_device *device)
Definition: atacmds.cpp:1561
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:2961
int isSupportOfflineAbort(const ata_smart_values *data)
Definition: atacmds.cpp:1805
struct ata_smart_errorlog_command_struct commands[5]
Definition: atacmds.h:304
ata_device * get_parsed_ata_device(smart_interface *intf, const char *dev_name)
Definition: atacmds.cpp:3018
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:2546
#define ATA_SMART_READ_VALUES
Definition: atacmds.h:95
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:1877
unsigned short option_flags
Definition: atacmds.h:578
int ataEnableSmart(ata_device *device)
Definition: atacmds.cpp:1527
#define CONVEYANCE_SELF_TEST
Definition: atacmds.h:114
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:1509
Definition: atacmds.h:55
static int name2command(const char *s)
Definition: atacmds.cpp:2758
ata_register features
static void trim(char *out, const char *in)
Definition: atacmds.cpp:741
int ataDisableAutoSave(ata_device *device)
Definition: atacmds.cpp:1549
static void fixsamsungerrorlog(ata_smart_errorlog *data)
Definition: atacmds.cpp:1383
u8 b[12]
Definition: megaraid.h:96
#define SELECTIVE_FLAG_PENDING
Definition: atacmds.h:514
#define ATA_SMART_AUTO_OFFLINE
Definition: atacmds.h:108
unsigned short cfs_enable_1
Definition: atacmds.h:141
int ataSetSCTTempInterval(ata_device *device, unsigned interval, bool persistent)
Definition: atacmds.cpp:2393
bool parse_firmwarebug_def(const char *opt, firmwarebug_defs &firmwarebugs)
Definition: atacmds.cpp:287
unsigned short major_rev_num
Definition: atacmds.h:136
int isGeneralPurposeLoggingCapable(const ata_identify_device *identity)
Definition: atacmds.cpp:1760
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:1217
#define CAPTIVE_MASK
Definition: atacmds.h:121
unsigned short table_id
Definition: atacmds.h:591
#define EXTEND_CAPTIVE_SELF_TEST
Definition: atacmds.h:118
static bool check_temp_range(int t, unsigned char ut1, unsigned char ut2, int &lo, int &hi)
Definition: atacmds.cpp:1934
static int ataGetSetSCTErrorRecoveryControltime(ata_device *device, unsigned type, bool set, unsigned short &time_limit)
Definition: atacmds.cpp:2444
#define SELECTIVE_CAPTIVE_SELF_TEST
Definition: atacmds.h:120
const char * atacmds_cpp_cvsid
Definition: atacmds.cpp:39
unsigned char short_test_completion_time
Definition: atacmds.h:223
unsigned char mostrecenttest
Definition: atacmds.h:426
#define ATA_SMART_READ_THRESHOLDS
Definition: atacmds.h:96
unsigned short sct_version
Definition: atacmds.h:529
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:226
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:1602
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:589
ATA device access.
ata_register sector_count
#define SHORT_SELF_TEST
Definition: atacmds.h:112
#define ATA_SMART_IMMEDIATE_OFFLINE
Definition: atacmds.h:99
unsigned char serial_no[20]
Definition: atacmds.h:131
int ataPrintSmartSelfTestlog(const ata_smart_selftestlog *data, bool allentries, firmwarebug_defs firmwarebugs)
Definition: atacmds.cpp:2626
unsigned long long uint64_t
Definition: int64.h:54
unsigned short timestamp
Definition: atacmds.h:445
#define MAX_ATTRIBUTE_NUM
Definition: atacmds.h:940
unsigned short int logversion
Definition: atacmds.h:480
unsigned char conveyance_test_completion_time
Definition: atacmds.h:225
unsigned short feature_code
Definition: atacmds.h:576
int isSupportAutomaticTimer(const ata_smart_values *data)
Definition: atacmds.cpp:1801
void set_data_in_48bit(void *buf, unsigned nsectors)
Prepare for 48-bit DATA IN command.
unsigned char selfteststatus
Definition: atacmds.h:411
unsigned char selftestnumber
Definition: atacmds.h:410
unsigned char id
Definition: atacmds.h:246
ata_register command
int ataSmartStatus2(ata_device *device)
Definition: atacmds.cpp:1595
unsigned int under_limit_count
Definition: atacmds.h:547
union @41 entry
unsigned char offline_data_collection_capability
Definition: atacmds.h:219
#define SRET_STATUS_MID_EXCEEDED
Definition: atacmds.cpp:58
unsigned short int revnumber
Definition: atacmds.h:423
ATA pass through input parameters.
parsed_ata_command m_command_table[max_num_commands]
Definition: atacmds.cpp:2740
unsigned char checksum
Definition: atacmds.h:508
unsigned char threshold
Definition: atacmds.h:247
#define ATA_SMART_ENABLE
Definition: atacmds.h:103
unsigned short flags
Definition: atacmds.h:504
int ataReadSCTTempHist(ata_device *device, ata_sct_temperature_history_table *tmh, ata_sct_status_response *sts)
Definition: atacmds.cpp:2250
ata_reg_alias_16 lba_mid_16
void set(firmwarebug_t bug)
Definition: atacmds.h:744
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:1572
virtual bool open()
Open device, return false on error.
Definition: atacmds.cpp:2807
unsigned short int revnumber
Definition: atacmds.h:213
uint64_t capacity
Definition: atacmds.h:996
ata_register lba_low
unsigned char model[40]
Definition: atacmds.h:134
int isSmartErrorLogCapable(const ata_smart_values *data, const ata_identify_device *identity)
Definition: atacmds.cpp:1722
#define ATA_SET_FEATURES
Definition: atacmds.h:77
ata_vendor_def_prior
Definition: atacmds.h:653
ata_register lba_high
int isSupportSelfTest(const ata_smart_values *data)
Definition: atacmds.cpp:1813
static const char * nextline(const char *s, int &lineno)
Definition: atacmds.cpp:2748
u8 cmd
Definition: megaraid.h:80
unsigned char worst
Definition: atacmds.h:157
int ataReadErrorLog(ata_device *device, ata_smart_errorlog *data, firmwarebug_defs firmwarebugs)
Definition: atacmds.cpp:1415
static const char *const commandstrings[]
Definition: atacmds.cpp:368
#define ATA_READ_LOG_EXT
Definition: atacmds.h:91
const char * get_dev_name() const
Get device (path)name.
int ataSetSCTErrorRecoveryControltime(ata_device *device, unsigned type, unsigned short time_limit)
Definition: atacmds.cpp:2535
Definition: atacmds.h:50
#define SELECTIVE_FLAG_ACTIVE
Definition: atacmds.h:515
int ataDoesSmartWork(ata_device *device)
Definition: atacmds.cpp:1584
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:2942
ATA Output registers (for 28-bit commands)
#define SELECTIVE_FLAG_DOSCAN
Definition: atacmds.h:513
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:1155
#define P(n)
struct ata_smart_errorlog_error_struct error_struct
Definition: atacmds.h:305
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:1134
#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:498
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:117
int isSmartTestLogCapable(const ata_smart_values *data, const ata_identify_device *identity)
Definition: atacmds.cpp:1741
unsigned short int revnumber
Definition: atacmds.h:257
#define ATA_SMART_STATUS
Definition: atacmds.h:105