smartmontools SVN Rev 5640
Utility to control and monitor storage systems with "S.M.A.R.T."
ataprint.cpp
Go to the documentation of this file.
1/*
2 * ataprint.cpp
3 *
4 * Home page of code is: https://www.smartmontools.org
5 *
6 * Copyright (C) 2002-11 Bruce Allen
7 * Copyright (C) 2008-24 Christian Franke
8 * Copyright (C) 1999-2000 Michael Cornwell <cornwell@acm.org>
9 *
10 * SPDX-License-Identifier: GPL-2.0-or-later
11 */
12
13#include "config.h"
14#define __STDC_FORMAT_MACROS 1 // enable PRI* for C++
15
16#include <ctype.h>
17#include <errno.h>
18#include <inttypes.h>
19#include <stdio.h>
20#include <stdlib.h>
21#include <string.h>
22
23#include "atacmdnames.h"
24#include "atacmds.h"
25#include "ataidentify.h"
26#include "dev_interface.h"
27#include "ataprint.h"
28#include "smartctl.h"
29#include "sg_unaligned.h"
30#include "utility.h"
31#include "knowndrives.h"
32
33#include "farmcmds.h"
34#include "farmprint.h"
35
36const char * ataprint_cpp_cvsid = "$Id: ataprint.cpp 5619 2024-10-15 09:33:51Z chrfranke $"
38
39
40static const char * infofound(const char *output) {
41 return (*output ? output : "[No Information Found]");
42}
43
44// Return true if '-T permissive' is specified,
45// used to ignore missing capabilities
46static bool is_permissive()
47{
49 return false;
51 return true;
52}
53
54/* For the given Command Register (CR) and Features Register (FR), attempts
55 * to construct a string that describes the contents of the Status
56 * Register (ST) and Error Register (ER). If the meanings of the flags of
57 * the error register are not known for the given command then it returns an
58 * empty string.
59 *
60 * The meanings of the flags of the error register for all commands are
61 * described in the ATA spec and could all be supported here in theory.
62 * Currently, only a few commands are supported (those that have been seen
63 * to produce errors). If many more are to be added then this function
64 * should probably be redesigned.
65 */
66
67static std::string format_st_er_desc(
68 unsigned char CR, unsigned char FR,
69 unsigned char ST, unsigned char ER,
70 unsigned short SC,
71 const ata_smart_errorlog_error_struct * lba28_regs,
72 const ata_smart_exterrlog_error * lba48_regs
73)
74{
75 const char *error_flag[8];
76 int i, print_lba=0, print_sector=0;
77
78 // Set of character strings corresponding to different error codes.
79 // Please keep in alphabetic order if you add more.
80 const char *abrt = "ABRT"; // ABORTED
81 const char *amnf = "AMNF"; // ADDRESS MARK NOT FOUND
82 const char *ccto = "CCTO"; // COMMAND COMPLETION TIMED OUT
83 const char *eom = "EOM"; // END OF MEDIA
84 const char *icrc = "ICRC"; // INTERFACE CRC ERROR
85 const char *idnf = "IDNF"; // ID NOT FOUND
86 const char *ili = "ILI"; // MEANING OF THIS BIT IS COMMAND-SET SPECIFIC
87 const char *mc = "MC"; // MEDIA CHANGED
88 const char *mcr = "MCR"; // MEDIA CHANGE REQUEST
89 const char *nm = "NM"; // NO MEDIA
90 const char *obs = "obs"; // OBSOLETE
91 const char *tk0nf = "TK0NF"; // TRACK 0 NOT FOUND
92 const char *unc = "UNC"; // UNCORRECTABLE
93 const char *wp = "WP"; // WRITE PROTECTED
94
95 /* If for any command the Device Fault flag of the status register is
96 * not used then used_device_fault should be set to 0 (in the CR switch
97 * below)
98 */
99 int uses_device_fault = 1;
100
101 /* A value of NULL means that the error flag isn't used */
102 for (i = 0; i < 8; i++)
103 error_flag[i] = NULL;
104
105 std::string str;
106
107 switch (CR) {
108 case 0x10: // RECALIBRATE
109 error_flag[2] = abrt;
110 error_flag[1] = tk0nf;
111 break;
112 case 0x20: /* READ SECTOR(S) */
113 case 0x21: // READ SECTOR(S)
114 case 0x24: // READ SECTOR(S) EXT
115 case 0xC4: /* READ MULTIPLE */
116 case 0x29: // READ MULTIPLE EXT
117 error_flag[6] = unc;
118 error_flag[5] = mc;
119 error_flag[4] = idnf;
120 error_flag[3] = mcr;
121 error_flag[2] = abrt;
122 error_flag[1] = nm;
123 error_flag[0] = amnf;
124 print_lba=1;
125 break;
126 case 0x22: // READ LONG (with retries)
127 case 0x23: // READ LONG (without retries)
128 error_flag[4] = idnf;
129 error_flag[2] = abrt;
130 error_flag[0] = amnf;
131 print_lba=1;
132 break;
133 case 0x2a: // READ STREAM DMA
134 case 0x2b: // READ STREAM PIO
135 if (CR==0x2a)
136 error_flag[7] = icrc;
137 error_flag[6] = unc;
138 error_flag[5] = mc;
139 error_flag[4] = idnf;
140 error_flag[3] = mcr;
141 error_flag[2] = abrt;
142 error_flag[1] = nm;
143 error_flag[0] = ccto;
144 print_lba=1;
145 print_sector=SC;
146 break;
147 case 0x3A: // WRITE STREAM DMA
148 case 0x3B: // WRITE STREAM PIO
149 if (CR==0x3A)
150 error_flag[7] = icrc;
151 error_flag[6] = wp;
152 error_flag[5] = mc;
153 error_flag[4] = idnf;
154 error_flag[3] = mcr;
155 error_flag[2] = abrt;
156 error_flag[1] = nm;
157 error_flag[0] = ccto;
158 print_lba=1;
159 print_sector=SC;
160 break;
161 case 0x25: // READ DMA EXT
162 case 0x26: // READ DMA QUEUED EXT
163 case 0xC7: // READ DMA QUEUED
164 case 0xC8: // READ DMA (with retries)
165 case 0xC9: // READ DMA (without retries, obsolete since ATA-5)
166 case 0x60: // READ FPDMA QUEUED (NCQ)
167 error_flag[7] = icrc;
168 error_flag[6] = unc;
169 error_flag[5] = mc;
170 error_flag[4] = idnf;
171 error_flag[3] = mcr;
172 error_flag[2] = abrt;
173 error_flag[1] = nm;
174 error_flag[0] = amnf;
175 print_lba=1;
176 if (CR==0x25 || CR==0xC8)
177 print_sector=SC;
178 break;
179 case 0x30: /* WRITE SECTOR(S) */
180 case 0x31: // WRITE SECTOR(S)
181 case 0x34: // WRITE SECTOR(S) EXT
182 case 0xC5: /* WRITE MULTIPLE */
183 case 0x39: // WRITE MULTIPLE EXT
184 case 0xCE: // WRITE MULTIPLE FUA EXT
185 error_flag[6] = wp;
186 error_flag[5] = mc;
187 error_flag[4] = idnf;
188 error_flag[3] = mcr;
189 error_flag[2] = abrt;
190 error_flag[1] = nm;
191 print_lba=1;
192 break;
193 case 0x32: // WRITE LONG (with retries)
194 case 0x33: // WRITE LONG (without retries)
195 error_flag[4] = idnf;
196 error_flag[2] = abrt;
197 print_lba=1;
198 break;
199 case 0x3C: // WRITE VERIFY
200 error_flag[6] = unc;
201 error_flag[4] = idnf;
202 error_flag[2] = abrt;
203 error_flag[0] = amnf;
204 print_lba=1;
205 break;
206 case 0x40: // READ VERIFY SECTOR(S) with retries
207 case 0x41: // READ VERIFY SECTOR(S) without retries
208 case 0x42: // READ VERIFY SECTOR(S) EXT
209 error_flag[6] = unc;
210 error_flag[5] = mc;
211 error_flag[4] = idnf;
212 error_flag[3] = mcr;
213 error_flag[2] = abrt;
214 error_flag[1] = nm;
215 error_flag[0] = amnf;
216 print_lba=1;
217 break;
218 case 0xA0: /* PACKET */
219 /* Bits 4-7 are all used for sense key (a 'command packet set specific error
220 * indication' according to the ATA/ATAPI-7 standard), so "Sense key" will
221 * be repeated in the error description string if more than one of those
222 * bits is set.
223 */
224 error_flag[7] = "Sense key (bit 3)",
225 error_flag[6] = "Sense key (bit 2)",
226 error_flag[5] = "Sense key (bit 1)",
227 error_flag[4] = "Sense key (bit 0)",
228 error_flag[2] = abrt;
229 error_flag[1] = eom;
230 error_flag[0] = ili;
231 break;
232 case 0xA1: /* IDENTIFY PACKET DEVICE */
233 case 0xEF: /* SET FEATURES */
234 case 0x00: /* NOP */
235 case 0xC6: /* SET MULTIPLE MODE */
236 error_flag[2] = abrt;
237 break;
238 case 0x2F: // READ LOG EXT
239 error_flag[6] = unc;
240 error_flag[4] = idnf;
241 error_flag[2] = abrt;
242 error_flag[0] = obs;
243 break;
244 case 0x3F: // WRITE LOG EXT
245 error_flag[4] = idnf;
246 error_flag[2] = abrt;
247 error_flag[0] = obs;
248 break;
249 case 0xB0: /* SMART */
250 switch(FR) {
251 case 0xD0: // SMART READ DATA
252 case 0xD1: // SMART READ ATTRIBUTE THRESHOLDS
253 case 0xD5: /* SMART READ LOG */
254 error_flag[6] = unc;
255 error_flag[4] = idnf;
256 error_flag[2] = abrt;
257 error_flag[0] = obs;
258 break;
259 case 0xD6: /* SMART WRITE LOG */
260 error_flag[4] = idnf;
261 error_flag[2] = abrt;
262 error_flag[0] = obs;
263 break;
264 case 0xD2: // Enable/Disable Attribute Autosave
265 case 0xD3: // SMART SAVE ATTRIBUTE VALUES (ATA-3)
266 case 0xD8: // SMART ENABLE OPERATIONS
267 case 0xD9: /* SMART DISABLE OPERATIONS */
268 case 0xDA: /* SMART RETURN STATUS */
269 case 0xDB: // Enable/Disable Auto Offline (SFF)
270 error_flag[2] = abrt;
271 break;
272 case 0xD4: // SMART EXECUTE IMMEDIATE OFFLINE
273 error_flag[4] = idnf;
274 error_flag[2] = abrt;
275 break;
276 default:
277 return str; // ""
278 break;
279 }
280 break;
281 case 0xB1: /* DEVICE CONFIGURATION */
282 switch (FR) {
283 case 0xC0: /* DEVICE CONFIGURATION RESTORE */
284 error_flag[2] = abrt;
285 break;
286 default:
287 return str; // ""
288 break;
289 }
290 break;
291 case 0xCA: // WRITE DMA (with retries)
292 case 0xCB: // WRITE DMA (without retries, obsolete since ATA-5)
293 case 0x35: // WRITE DMA EXT
294 case 0x3D: // WRITE DMA FUA EXT
295 case 0xCC: // WRITE DMA QUEUED
296 case 0x36: // WRITE DMA QUEUED EXT
297 case 0x3E: // WRITE DMA QUEUED FUA EXT
298 case 0x61: // WRITE FPDMA QUEUED (NCQ)
299 error_flag[7] = icrc;
300 error_flag[6] = wp;
301 error_flag[5] = mc;
302 error_flag[4] = idnf;
303 error_flag[3] = mcr;
304 error_flag[2] = abrt;
305 error_flag[1] = nm;
306 error_flag[0] = amnf;
307 print_lba=1;
308 if (CR==0x35)
309 print_sector=SC;
310 break;
311 case 0xE4: // READ BUFFER
312 case 0xE8: // WRITE BUFFER
313 error_flag[2] = abrt;
314 break;
315 default:
316 return str; // ""
317 }
318
319 /* We ignore any status flags other than Device Fault and Error */
320
321 if (uses_device_fault && (ST & (1 << 5))) {
322 str = "Device Fault";
323 if (ST & 1) // Error flag
324 str += "; ";
325 }
326 if (ST & 1) { // Error flag
327 int count = 0;
328
329 str += "Error: ";
330 for (i = 7; i >= 0; i--)
331 if ((ER & (1 << i)) && (error_flag[i])) {
332 if (count++ > 0)
333 str += ", ";
334 str += error_flag[i];
335 }
336 }
337
338 // If the error was a READ or WRITE error, print the Logical Block
339 // Address (LBA) at which the read or write failed.
340 if (print_lba) {
341 // print number of sectors, if known, and append to print string
342 if (print_sector)
343 str += strprintf(" %d sectors", print_sector);
344
345 if (lba28_regs) {
346 unsigned lba;
347 // bits 24-27: bits 0-3 of DH
348 lba = 0xf & lba28_regs->drive_head;
349 lba <<= 8;
350 // bits 16-23: CH
351 lba |= lba28_regs->cylinder_high;
352 lba <<= 8;
353 // bits 8-15: CL
354 lba |= lba28_regs->cylinder_low;
355 lba <<= 8;
356 // bits 0-7: SN
357 lba |= lba28_regs->sector_number;
358 str += strprintf(" at LBA = 0x%08x = %u", lba, lba);
359 }
360 else if (lba48_regs) {
361 // This assumes that upper LBA registers are 0 for 28-bit commands
362 // (TODO: detect 48-bit commands above)
363 uint64_t lba48;
364 lba48 = lba48_regs->lba_high_register_hi;
365 lba48 <<= 8;
366 lba48 |= lba48_regs->lba_mid_register_hi;
367 lba48 <<= 8;
368 lba48 |= lba48_regs->lba_low_register_hi;
369 lba48 |= lba48_regs->device_register & 0xf;
370 lba48 <<= 8;
371 lba48 |= lba48_regs->lba_high_register;
372 lba48 <<= 8;
373 lba48 |= lba48_regs->lba_mid_register;
374 lba48 <<= 8;
375 lba48 |= lba48_regs->lba_low_register;
376 str += strprintf(" at LBA = 0x%08" PRIx64 " = %" PRIu64, lba48, lba48);
377 }
378 }
379
380 return str;
381}
382
383static inline std::string format_st_er_desc(
385{
386 return format_st_er_desc(
387 data->commands[4].commandreg,
388 data->commands[4].featuresreg,
389 data->error_struct.status,
390 data->error_struct.error_register,
391 data->error_struct.sector_count,
392 &data->error_struct, (const ata_smart_exterrlog_error *)0);
393}
394
395static inline std::string format_st_er_desc(
397{
398 return format_st_er_desc(
399 data->commands[4].command_register,
400 data->commands[4].features_register,
401 data->error.status_register,
402 data->error.error_register,
403 data->error.count_register_hi << 8 | data->error.count_register,
404 (const ata_smart_errorlog_error_struct *)0, &data->error);
405}
406
407
408static const char * get_form_factor(unsigned short word168)
409{
410 // Bits 0:3 are the form factor
411 // Table A.32 of T13/2161-D (ACS-3) Revision 5, October 28, 2013
412 // Table 247 of T13/BSR INCITS 529 (ACS-4) Revision 20, October 26, 2017
413 // Table 265 of T13/BSR INCITS 574 (ACS-6) Revision 3, March 30, 2023
414 switch (word168 & 0xF) {
415 case 0x1: return "5.25 inches";
416 case 0x2: return "3.5 inches";
417 case 0x3: return "2.5 inches";
418 case 0x4: return "1.8 inches";
419 case 0x5: return "< 1.8 inches";
420 case 0x6: return "mSATA"; // ACS-4
421 case 0x7: return "M.2"; // ACS-4
422 case 0x8: return "MicroSSD"; // ACS-4
423 case 0x9: return "CFast"; // ACS-4
424 default : return 0;
425 }
426}
427
428static int find_msb(unsigned short word)
429{
430 for (int bit = 15; bit >= 0; bit--)
431 if (word & (1 << bit))
432 return bit;
433 return -1;
434}
435
436static const char * get_ata_major_version(const ata_identify_device * drive)
437{
438 // Table 13 of T13/1153D (ATA/ATAPI-4) revision 18, August 19, 1998
439 // Table 29 of T13/1699-D (ATA8-ACS) Revision 6a, September 6, 2008
440 // Table 55 of T13/BSR INCITS 529 (ACS-4) Revision 20, October 26, 2017
441 // Table 57 of T13/BSR INCITS 558 (ACS-5) Revision 10, March 3, 2021
442 switch (find_msb(drive->major_rev_num)) {
443 case 15: return "ACS >5 (15)";
444 case 14: return "ACS >5 (14)";
445 case 13: return "ACS >5 (13)";
446 case 12: return "ACS-5";
447 case 11: return "ACS-4";
448 case 10: return "ACS-3";
449 case 9: return "ACS-2";
450 case 8: return "ATA8-ACS";
451 case 7: return "ATA/ATAPI-7";
452 case 6: return "ATA/ATAPI-6";
453 case 5: return "ATA/ATAPI-5";
454 case 4: return "ATA/ATAPI-4";
455 case 3: return "ATA-3";
456 case 2: return "ATA-2";
457 case 1: return "ATA-1";
458 default: return 0;
459 }
460}
461
462static const char * get_ata_minor_version(const ata_identify_device * drive)
463{
464 // Table 10 of X3T13/2008D (ATA-3) Revision 7b, January 27, 1997
465 // Table 28 of T13/1410D (ATA/ATAPI-6) Revision 3b, February 26, 2002
466 // Table 31 of T13/1699-D (ATA8-ACS) Revision 6a, September 6, 2008
467 // Table 52 of T13/2015-D (ACS-2) Revision 7, June 22, 2011
468 // Table 47 of T13/2161-D (ACS-3) Revision 5, October 28, 2013
469 // Table 57 of T13/BSR INCITS 529 (ACS-4) Revision 20, October 26, 2017
470 // Table 59 of T13/BSR INCITS 558 (ACS-5) Revision 10, March 3, 2021
471 // Table 59 of T13/BSR INCITS 574 (ACS-6) Revision 3, March 30, 2023
472 switch (drive->minor_rev_num) {
473 case 0x0001: return "ATA-1 X3T9.2/781D prior to revision 4";
474 case 0x0002: return "ATA-1 published, ANSI X3.221-1994";
475 case 0x0003: return "ATA-1 X3T9.2/781D revision 4";
476 case 0x0004: return "ATA-2 published, ANSI X3.279-1996";
477 case 0x0005: return "ATA-2 X3T10/948D prior to revision 2k";
478 case 0x0006: return "ATA-3 X3T10/2008D revision 1";
479 case 0x0007: return "ATA-2 X3T10/948D revision 2k";
480 case 0x0008: return "ATA-3 X3T10/2008D revision 0";
481 case 0x0009: return "ATA-2 X3T10/948D revision 3";
482 case 0x000a: return "ATA-3 published, ANSI X3.298-1997";
483 case 0x000b: return "ATA-3 X3T10/2008D revision 6"; // 1st ATA-3 revision with SMART
484 case 0x000c: return "ATA-3 X3T13/2008D revision 7 and 7a";
485 case 0x000d: return "ATA/ATAPI-4 X3T13/1153D revision 6";
486 case 0x000e: return "ATA/ATAPI-4 T13/1153D revision 13";
487 case 0x000f: return "ATA/ATAPI-4 X3T13/1153D revision 7";
488 case 0x0010: return "ATA/ATAPI-4 T13/1153D revision 18";
489 case 0x0011: return "ATA/ATAPI-4 T13/1153D revision 15";
490 case 0x0012: return "ATA/ATAPI-4 published, ANSI NCITS 317-1998";
491 case 0x0013: return "ATA/ATAPI-5 T13/1321D revision 3";
492 case 0x0014: return "ATA/ATAPI-4 T13/1153D revision 14";
493 case 0x0015: return "ATA/ATAPI-5 T13/1321D revision 1";
494 case 0x0016: return "ATA/ATAPI-5 published, ANSI NCITS 340-2000";
495 case 0x0017: return "ATA/ATAPI-4 T13/1153D revision 17";
496 case 0x0018: return "ATA/ATAPI-6 T13/1410D revision 0";
497 case 0x0019: return "ATA/ATAPI-6 T13/1410D revision 3a";
498 case 0x001a: return "ATA/ATAPI-7 T13/1532D revision 1";
499 case 0x001b: return "ATA/ATAPI-6 T13/1410D revision 2";
500 case 0x001c: return "ATA/ATAPI-6 T13/1410D revision 1";
501 case 0x001d: return "ATA/ATAPI-7 published, ANSI INCITS 397-2005";
502 case 0x001e: return "ATA/ATAPI-7 T13/1532D revision 0";
503 case 0x001f: return "ACS-3 T13/2161-D revision 3b";
504
505 case 0x0021: return "ATA/ATAPI-7 T13/1532D revision 4a";
506 case 0x0022: return "ATA/ATAPI-6 published, ANSI INCITS 361-2002";
507
508 case 0x0030: return "ACS-5 T13/BSR INCITS 558 revision 10";
509
510 case 0x0027: return "ATA8-ACS T13/1699-D revision 3c";
511 case 0x0028: return "ATA8-ACS T13/1699-D revision 6";
512 case 0x0029: return "ATA8-ACS T13/1699-D revision 4";
513
514 case 0x0031: return "ACS-2 T13/2015-D revision 2";
515
516 case 0x0033: return "ATA8-ACS T13/1699-D revision 3e";
517
518 case 0x0039: return "ATA8-ACS T13/1699-D revision 4c";
519
520 case 0x0042: return "ATA8-ACS T13/1699-D revision 3f";
521
522 case 0x0052: return "ATA8-ACS T13/1699-D revision 3b";
523
524 case 0x005e: return "ACS-4 T13/BSR INCITS 529 revision 5";
525
526 case 0x006d: return "ACS-3 T13/2161-D revision 5";
527
528 case 0x0073: return "ACS-6 T13/BSR INCITS 558 revision 2";
529
530 case 0x0082: return "ACS-2 published, ANSI INCITS 482-2012";
531
532 case 0x009c: return "ACS-4 published, ANSI INCITS 529-2018";
533
534 case 0x0107: return "ATA8-ACS T13/1699-D revision 2d";
535
536 case 0x010a: return "ACS-3 published, ANSI INCITS 522-2014";
537
538 case 0x0110: return "ACS-2 T13/2015-D revision 3";
539
540 case 0x011b: return "ACS-3 T13/2161-D revision 4";
541
542 default: return 0;
543 }
544}
545
546static const char * get_pata_version(unsigned short word222, char (& buf)[32])
547{
548 // Table 29 of T13/1699-D (ATA8-ACS) Revision 6a, September 6, 2008
549 // Table 57 of T13/BSR INCITS 558 (ACS-5) Revision 10, March 3, 2021
550 switch (word222 & 0x0fff) {
551 default: snprintf(buf, sizeof(buf),
552 "Unknown (0x%03x)", word222 & 0x0fff); return buf;
553 case 0x001:
554 case 0x003: return "ATA8-APT"; // OBS-ACS-5
555 case 0x002: return "ATA/ATAPI-7"; // OBS-ACS-5
556 }
557}
558
559static const char * get_sata_version(unsigned short word222)
560{
561 // Table 29 of T13/1699-D (ATA8-ACS) Revision 6a, September 6, 2008
562 // Table 50 of T13/2015-D (ACS-2) Revision 7, June 22, 2011
563 // Table 45 of T13/2161-D (ACS-3) Revision 5, October 28, 2013
564 // Table 55 of T13/BSR INCITS 529 (ACS-4) Revision 20, October 26, 2017
565 // Table 57 of T13/BSR INCITS 558 (ACS-5) Revision 10, March 3, 2021
566 switch (find_msb(word222 & 0x0fff)) {
567 case 11: return "SATA >3.5 (11)";
568 case 10: return "SATA 3.5"; // ACS-5
569 case 9: return "SATA 3.4"; // ACS-5
570 case 8: return "SATA 3.3"; // ACS-4
571 case 7: return "SATA 3.2"; // ACS-4
572 case 6: return "SATA 3.1"; // ACS-3
573 case 5: return "SATA 3.0"; // ACS-2
574 case 4: return "SATA 2.6";
575 case 3: return "SATA 2.5";
576 case 2: return "SATA II Ext";
577 case 1: return "SATA 1.0a";
578 case 0: return "ATA8-AST";
579 default: return 0;
580 }
581}
582
583static const char * get_sata_speed(int speed)
584{
585 if (speed <= 0)
586 return 0;
587 // Table 29 of T13/1699-D (ATA8-ACS) Revision 6a, September 6, 2008
588 // Table 50 of T13/2015-D (ACS-2) Revision 7, June 22, 2011
589 // Table 45 of T13/2161-D (ACS-3) Revision 5, October 28, 2013
590 // Table 57 of T13/BSR INCITS 558 (ACS-5) Revision 10, March 3, 2021
591 switch (speed) {
592 default: return ">6.0 Gb/s (7)";
593 case 6: return ">6.0 Gb/s (6)";
594 case 5: return ">6.0 Gb/s (5)";
595 case 4: return ">6.0 Gb/s (4)";
596 case 3: return "6.0 Gb/s"; // ACS-3
597 case 2: return "3.0 Gb/s";
598 case 1: return "1.5 Gb/s"; // ATA8-ACS
599 }
600}
601
602static void jset_sata_speed(const char * key, int value, int speed, const char * str)
603{
604 if (speed <= 0)
605 return;
606 json::ref jref = jglb["interface_speed"][key];
607 jref["sata_value"] = value;
608 if (str)
609 jref["string"] = str;
610 int ups;
611 switch (speed) {
612 case 3: ups = 60; break;
613 case 2: ups = 30; break;
614 case 1: ups = 15; break;
615 default: return;
616 }
617 jref["units_per_second"] = ups;
618 jref["bits_per_unit"] = 100000000;
619}
620
621static void print_sata_version_and_speed(unsigned short word222,
622 unsigned short word076,
623 unsigned short word077)
624{
625 int allspeeds = (!(word076 & 0x0001) ? (word076 & 0x00fe) : 0);
626 int maxspeed = (allspeeds ? find_msb(allspeeds) : 0);
627 int curspeed = (!(word077 & 0x0001) ? ((word077 >> 1) & 0x7) : 0);
628
629 const char * verstr = get_sata_version(word222);
630 const char * maxstr = get_sata_speed(maxspeed);
631 const char * curstr = get_sata_speed(curspeed);
632 jout("SATA Version is: %s%s%s%s%s%s\n",
633 (verstr ? verstr : "Unknown"),
634 (maxstr ? ", " : ""), (maxstr ? maxstr : ""),
635 (curstr ? " (current: " : ""), (curstr ? curstr : ""),
636 (curstr ? ")" : ""));
637 if (verstr)
638 jglb["sata_version"]["string"] = verstr;
639 jglb["sata_version"]["value"] = word222 & 0x0fff;
640 jset_sata_speed("max", allspeeds, maxspeed, maxstr);
641 jset_sata_speed("current", curspeed, curspeed, curstr);
642}
643
644static void print_drive_info(const ata_identify_device * drive,
645 const ata_size_info & sizes, int rpm,
646 const drive_settings * dbentry, const char * dbversion)
647{
648 // format drive information (with byte swapping as needed)
649 char model[40+1], serial[20+1], firmware[8+1];
650 ata_format_id_string(model, drive->model, sizeof(model)-1);
651 ata_format_id_string(serial, drive->serial_no, sizeof(serial)-1);
652 ata_format_id_string(firmware, drive->fw_rev, sizeof(firmware)-1);
653
654 // Print model family if known
655 if (dbentry && *dbentry->modelfamily) {
656 jout("Model Family: %s\n", dbentry->modelfamily);
657 jglb["model_family"] = dbentry->modelfamily;
658 }
659
660 jout("Device Model: %s\n", infofound(model));
661 jglb["model_name"] = model;
662
664 jout("Serial Number: %s\n", infofound(serial));
665 jglb["serial_number"] = serial;
666
667 unsigned oui = 0; uint64_t unique_id = 0;
668 int naa = ata_get_wwn(drive, oui, unique_id);
669 if (naa >= 0) {
670 jout("LU WWN Device Id: %x %06x %09" PRIx64 "\n", naa, oui, unique_id);
671 jglb["wwn"]["naa"] = naa;
672 jglb["wwn"]["oui"] = oui;
673 jglb["wwn"]["id"] = unique_id;
674 }
675 }
676
677 // Additional Product Identifier (OEM Id) string in words 170-173
678 // (e08130r1, added in ACS-2 Revision 1, December 17, 2008)
679 if (0x2020 <= drive->words088_255[170-88] && drive->words088_255[170-88] <= 0x7e7e) {
680 char add[8+1];
681 ata_format_id_string(add, (const unsigned char *)(drive->words088_255+(170-88)), sizeof(add)-1);
682 if (add[0]) {
683 jout("Add. Product Id: %s\n", add);
684 jglb["ata_additional_product_id"] = add;
685 }
686 }
687
688 jout("Firmware Version: %s\n", infofound(firmware));
689 jglb["firmware_version"] = firmware;
690
691 if (sizes.capacity) {
692 // Print capacity
693 char num[64], cap[32];
694 jout("User Capacity: %s bytes [%s]\n",
695 format_with_thousands_sep(num, sizeof(num), sizes.capacity),
696 format_capacity(cap, sizeof(cap), sizes.capacity));
697 jglb["user_capacity"]["blocks"].set_unsafe_uint64(sizes.sectors);
698 jglb["user_capacity"]["bytes"].set_unsafe_uint64(sizes.capacity);
699
700 // Print sector sizes.
701 if (sizes.phy_sector_size == sizes.log_sector_size)
702 jout("Sector Size: %u bytes logical/physical\n", sizes.log_sector_size);
703 else {
704 jout("Sector Sizes: %u bytes logical, %u bytes physical",
705 sizes.log_sector_size, sizes.phy_sector_size);
706 if (sizes.log_sector_offset)
707 pout(" (offset %u bytes)", sizes.log_sector_offset);
708 jout("\n");
709 }
710 jglb["logical_block_size"] = sizes.log_sector_size;
711 jglb["physical_block_size"] = sizes.phy_sector_size;
712 }
713
714 // Print nominal media rotation rate if reported
715 if (rpm) {
716 if (rpm == 1)
717 jout("Rotation Rate: Solid State Device\n");
718 else if (rpm > 1)
719 jout("Rotation Rate: %d rpm\n", rpm);
720 else
721 pout("Rotation Rate: Unknown (0x%04x)\n", -rpm);
722 if (rpm > 0)
723 jglb["rotation_rate"] = (rpm == 1 ? 0 : rpm);
724 }
725
726 // Print form factor if reported
727 unsigned short word168 = drive->words088_255[168-88];
728 if (word168) {
729 const char * form_factor = get_form_factor(word168);
730 if (form_factor)
731 jout("Form Factor: %s\n", form_factor);
732 else
733 jout("Form Factor: Unknown (0x%04x)\n", word168);
734 jglb["form_factor"]["ata_value"] = word168;
735 if (form_factor)
736 jglb["form_factor"]["name"] = form_factor;
737 }
738
739 // Print TRIM support
740 bool trim_sup = !!(drive->words088_255[169-88] & 0x0001);
741 unsigned short word069 = drive->words047_079[69-47];
742 bool trim_det = !!(word069 & 0x4000), trim_zeroed = !!(word069 & 0x0020);
743 if (trim_sup || rpm == 1) // HDD: if supported (SMR), SSD: always
744 jout("TRIM Command: %s%s%s\n",
745 (!trim_sup ? "Unavailable" : "Available"),
746 (!(trim_sup && trim_det) ? "" : ", deterministic"),
747 (!(trim_sup && trim_zeroed) ? "" : ", zeroed") );
748 jglb["trim"]["supported"] = trim_sup;
749 if (trim_sup) {
750 jglb["trim"]["deterministic"] = trim_det;
751 jglb["trim"]["zeroed"] = trim_zeroed;
752 }
753
754 // Print Zoned Device Capabilities if reported
755 // (added in ACS-4, obsoleted in ACS-5)
756 unsigned short zoned_caps = word069 & 0x3;
757 if (zoned_caps) {
758 jout("Zoned Device: %s\n",
759 (zoned_caps == 0x1 ? "Host Aware Zones" :
760 zoned_caps == 0x2 ? "Device managed zones" : "Unknown (0x3)"));
761 if (zoned_caps < 0x3)
762 jglb["zoned_device"]["capabilities"] = (zoned_caps == 0x1 ? "host_aware" : "device_managed");
763 }
764
765 // See if drive is recognized
766 jout("Device is: %s%s%s\n",
767 (dbentry ? "In smartctl database" : "Not in smartctl database"),
768 (*dbversion ? " " : ""), (*dbversion ? dbversion : ""));
769 jglb["in_smartctl_database"] = !!dbentry;
770
771 // Print ATA version
772 std::string ataver;
773 if ( (drive->major_rev_num != 0x0000 && drive->major_rev_num != 0xffff)
774 || (drive->minor_rev_num != 0x0000 && drive->minor_rev_num != 0xffff)) {
775 const char * majorver = get_ata_major_version(drive);
776 const char * minorver = get_ata_minor_version(drive);
777
778 if (majorver && minorver && str_starts_with(minorver, majorver)) {
779 // Major and minor strings match, print minor string only
780 ataver = minorver;
781 }
782 else {
783 if (majorver)
784 ataver = majorver;
785 else
786 ataver = strprintf("Unknown(0x%04x)", drive->major_rev_num);
787
788 if (minorver)
789 ataver += strprintf(", %s", minorver);
790 else if (drive->minor_rev_num != 0x0000 && drive->minor_rev_num != 0xffff)
791 ataver += strprintf(" (unknown minor revision code: 0x%04x)", drive->minor_rev_num);
792 else
793 ataver += " (minor revision not indicated)";
794 }
795 }
796 jout("ATA Version is: %s\n", infofound(ataver.c_str()));
797 if (!ataver.empty()) {
798 jglb["ata_version"]["string"] = ataver;
799 jglb["ata_version"]["major_value"] = drive->major_rev_num;
800 jglb["ata_version"]["minor_value"] = drive->minor_rev_num;
801 }
802
803 // Print Transport specific version
804 unsigned short word222 = drive->words088_255[222-88];
805 if (word222 != 0x0000 && word222 != 0xffff) switch (word222 >> 12) {
806 case 0x0: // PATA
807 {
808 char buf[32] = "";
809 pout("Transport Type: Parallel, %s\n", get_pata_version(word222, buf));
810 }
811 break;
812 case 0x1: // SATA
814 drive->words047_079[76-47],
815 drive->words047_079[77-47]);
816 break;
817 case 0xe: // PCIe (ACS-4)
818 pout("Transport Type: PCIe (0x%03x)\n", word222 & 0x0fff);
819 break;
820 default:
821 pout("Transport Type: Unknown (0x%04x)\n", word222);
822 break;
823 }
824
825 jout_startup_datetime("Local Time is: ");
826
827 // Print warning message, if there is one
828 if (dbentry && *dbentry->warningmsg)
829 pout("\n==> WARNING: %s\n\n", dbentry->warningmsg);
830}
831
832static const char *OfflineDataCollectionStatus(unsigned char status_byte)
833{
834 unsigned char stat=status_byte & 0x7f;
835
836 switch(stat){
837 case 0x00:
838 return "was never started";
839 case 0x02:
840 return "was completed without error";
841 case 0x03:
842 if (status_byte == 0x03)
843 return "is in progress";
844 else
845 return "is in a Reserved state";
846 case 0x04:
847 return "was suspended by an interrupting command from host";
848 case 0x05:
849 return "was aborted by an interrupting command from host";
850 case 0x06:
851 return "was aborted by the device with a fatal error";
852 default:
853 if (stat >= 0x40)
854 return "is in a Vendor Specific state";
855 else
856 return "is in a Reserved state";
857 }
858}
859
860
861// prints verbose value Off-line data collection status byte
863{
864 json::ref jref = jglb["ata_smart_data"]["offline_data_collection"]["status"];
865
866 jout("Offline data collection status: (0x%02x)\t",
867 (int)data->offline_data_collection_status);
868 jref["value"] = data->offline_data_collection_status;
869
870 // Off-line data collection status byte is not a reserved
871 // or vendor specific value
872 jout("Offline data collection activity\n"
873 "\t\t\t\t\t%s.\n", OfflineDataCollectionStatus(data->offline_data_collection_status));
874 jref["string"] = OfflineDataCollectionStatus(data->offline_data_collection_status);
875 switch (data->offline_data_collection_status & 0x7f) {
876 case 0x02: jref["passed"] = true; break;
877 case 0x06: jref["passed"] = false; break;
878 }
879
880 // Report on Automatic Data Collection Status. Only IBM documents
881 // this bit. See SFF 8035i Revision 2 for details.
882 if (data->offline_data_collection_status & 0x80)
883 pout("\t\t\t\t\tAuto Offline Data Collection: Enabled.\n");
884 else
885 pout("\t\t\t\t\tAuto Offline Data Collection: Disabled.\n");
886
887 return;
888}
889
891 firmwarebug_defs firmwarebugs)
892{
893 unsigned char status = data->self_test_exec_status;
894 jout("Self-test execution status: ");
895
896 switch (data->self_test_exec_status >> 4) {
897 case 0:
898 jout("(%4d)\tThe previous self-test routine completed\n\t\t\t\t\t", status);
899 jout("without error or no self-test has ever \n\t\t\t\t\tbeen run.\n");
900 break;
901 case 1:
902 jout("(%4d)\tThe self-test routine was aborted by\n\t\t\t\t\t", status);
903 jout("the host.\n");
904 break;
905 case 2:
906 jout("(%4d)\tThe self-test routine was interrupted\n\t\t\t\t\t", status);
907 jout("by the host with a hard or soft reset.\n");
908 break;
909 case 3:
910 jout("(%4d)\tA fatal error or unknown test error\n\t\t\t\t\t", status);
911 jout("occurred while the device was executing\n\t\t\t\t\t");
912 jout("its self-test routine and the device \n\t\t\t\t\t");
913 jout("was unable to complete the self-test \n\t\t\t\t\t");
914 jout("routine.\n");
915 break;
916 case 4:
917 jout("(%4d)\tThe previous self-test completed having\n\t\t\t\t\t", status);
918 jout("a test element that failed and the test\n\t\t\t\t\t");
919 jout("element that failed is not known.\n");
920 break;
921 case 5:
922 jout("(%4d)\tThe previous self-test completed having\n\t\t\t\t\t", status);
923 jout("the electrical element of the test\n\t\t\t\t\t");
924 jout("failed.\n");
925 break;
926 case 6:
927 jout("(%4d)\tThe previous self-test completed having\n\t\t\t\t\t", status);
928 jout("the servo (and/or seek) element of the \n\t\t\t\t\t");
929 jout("test failed.\n");
930 break;
931 case 7:
932 jout("(%4d)\tThe previous self-test completed having\n\t\t\t\t\t", status);
933 jout("the read element of the test failed.\n");
934 break;
935 case 8:
936 jout("(%4d)\tThe previous self-test completed having\n\t\t\t\t\t", status);
937 jout("a test element that failed and the\n\t\t\t\t\t");
938 jout("device is suspected of having handling\n\t\t\t\t\t");
939 jout("damage.\n");
940 break;
941 case 15:
942 if (firmwarebugs.is_set(BUG_SAMSUNG3) && data->self_test_exec_status == 0xf0) {
943 pout("(%4d)\tThe previous self-test routine completed\n\t\t\t\t\t", status);
944 pout("with unknown result or self-test in\n\t\t\t\t\t");
945 pout("progress with less than 10%% remaining.\n");
946 }
947 else {
948 jout("(%4d)\tSelf-test routine in progress...\n\t\t\t\t\t", status);
949 jout("%1d0%% of test remaining.\n", status & 0x0f);
950 }
951 break;
952 default:
953 jout("(%4d)\tReserved.\n", status);
954 break;
955 }
956
957 json::ref jref = jglb["ata_smart_data"]["self_test"]["status"];
958
959 jref["value"] = status;
960 const char * msg;
961 // TODO: Use common function for smartctl/smartd
962 switch (status >> 4) {
963 case 0x0: msg = "completed without error"; break;
964 case 0x1: msg = "was aborted by the host"; break;
965 case 0x2: msg = "was interrupted by the host with a reset"; break;
966 case 0x3: msg = "could not complete due to a fatal or unknown error"; break;
967 case 0x4: msg = "completed with error (unknown test element)"; break;
968 case 0x5: msg = "completed with error (electrical test element)"; break;
969 case 0x6: msg = "completed with error (servo/seek test element)"; break;
970 case 0x7: msg = "completed with error (read test element)"; break;
971 case 0x8: msg = "completed with error (handling damage?)"; break;
972 default: msg = 0;
973 }
974 if (msg) {
975 jref["string"] = msg;
976 switch (status >> 4) {
977 case 0x1: case 0x2: case 0x3: break; // aborted -> unknown
978 default: jref["passed"] = ((status >> 4) == 0x0);
979 }
980 }
981 else if ((status >> 4) == 0xf) {
982 jref["string"] = strprintf("in progress, %u0%% remaining", status & 0xf);
983 jref["remaining_percent"] = (status & 0xf) * 10;
984 }
985}
986
988{
989 jout("Total time to complete Offline \n");
990 jout("data collection: \t\t(%5d) seconds.\n",
991 (int)data->total_time_to_complete_off_line);
992
993 jglb["ata_smart_data"]["offline_data_collection"]["completion_seconds"] =
994 data->total_time_to_complete_off_line;
995}
996
998{
999 json::ref jref = jglb["ata_smart_data"]["capabilities"];
1000
1001 jout("Offline data collection\n");
1002 jout("capabilities: \t\t\t (0x%02x) ",
1003 (int)data->offline_data_collection_capability);
1004 jref["values"][0] = data->offline_data_collection_capability;
1005
1006 if (data->offline_data_collection_capability == 0x00){
1007 jout("\tOffline data collection not supported.\n");
1008 }
1009 else {
1011 "SMART execute Offline immediate." :
1012 "No SMART execute Offline immediate.");
1013 jref["exec_offline_immediate_supported"] = isSupportExecuteOfflineImmediate(data);
1014
1015 // TODO: Bit 1 is vendor specific
1016 pout( "\t\t\t\t\t%s\n", isSupportAutomaticTimer(data)?
1017 "Auto Offline data collection on/off support.":
1018 "No Auto Offline data collection support.");
1019
1020 jout( "\t\t\t\t\t%s\n", isSupportOfflineAbort(data)?
1021 "Abort Offline collection upon new\n\t\t\t\t\tcommand.":
1022 "Suspend Offline collection upon new\n\t\t\t\t\tcommand.");
1023 jref["offline_is_aborted_upon_new_cmd"] = isSupportOfflineAbort(data);
1024
1025 jout( "\t\t\t\t\t%s\n", isSupportOfflineSurfaceScan(data)?
1026 "Offline surface scan supported.":
1027 "No Offline surface scan supported.");
1028 jref["offline_surface_scan_supported"] = isSupportOfflineSurfaceScan(data);
1029
1030 jout( "\t\t\t\t\t%s\n", isSupportSelfTest(data)?
1031 "Self-test supported.":
1032 "No Self-test supported.");
1033 jref["self_tests_supported"] = isSupportSelfTest(data);
1034
1035 jout( "\t\t\t\t\t%s\n", isSupportConveyanceSelfTest(data)?
1036 "Conveyance Self-test supported.":
1037 "No Conveyance Self-test supported.");
1038 jref["conveyance_self_test_supported"] = isSupportConveyanceSelfTest(data);
1039
1040 jout( "\t\t\t\t\t%s\n", isSupportSelectiveSelfTest(data)?
1041 "Selective Self-test supported.":
1042 "No Selective Self-test supported.");
1043 jref["selective_self_test_supported"] = isSupportSelectiveSelfTest(data);
1044 }
1045}
1046
1048{
1049 json::ref jref = jglb["ata_smart_data"]["capabilities"];
1050
1051 jout("SMART capabilities: ");
1052 jout("(0x%04x)\t", (int)data->smart_capability);
1053 jref["values"][1] = data->smart_capability;
1054
1055 if (data->smart_capability == 0x00)
1056 jout("Automatic saving of SMART data\t\t\t\t\tis not implemented.\n");
1057 else {
1058 jout("%s\n", (data->smart_capability & 0x01)?
1059 "Saves SMART data before entering\n\t\t\t\t\tpower-saving mode.":
1060 "Does not save SMART data before\n\t\t\t\t\tentering power-saving mode.");
1061 jref["attribute_autosave_enabled"] = !!(data->smart_capability & 0x01);
1062
1063 // TODO: Info possibly invalid or misleading
1064 // ATA-3 - ATA-5: Bit shall be set
1065 // ATA-6 - ACS-3: Bit shall be set to indicate support for
1066 // SMART ENABLE/DISABLE ATTRIBUTE AUTOSAVE
1067 if (data->smart_capability & 0x02)
1068 pout("\t\t\t\t\tSupports SMART auto save timer.\n");
1069 }
1070}
1071
1073{
1074 bool capable = isSmartErrorLogCapable(data, identity);
1075 jout("Error logging capability: (0x%02x)\tError logging %ssupported.\n",
1076 data->errorlog_capability, (capable ? "" : "NOT "));
1077 jglb["ata_smart_data"]["capabilities"]["error_logging_supported"] = capable;
1078}
1079
1081{
1082 jout("Short self-test routine \n");
1083 if (isSupportSelfTest(data)) {
1084 jout("recommended polling time: \t (%4d) minutes.\n",
1085 (int)data->short_test_completion_time);
1086 jglb["ata_smart_data"]["self_test"]["polling_minutes"]["short"] =
1087 data->short_test_completion_time;
1088 }
1089 else
1090 jout("recommended polling time: \t Not Supported.\n");
1091}
1092
1094{
1095 jout("Extended self-test routine\n");
1096 if (isSupportSelfTest(data)) {
1097 jout("recommended polling time: \t (%4d) minutes.\n",
1099 jglb["ata_smart_data"]["self_test"]["polling_minutes"]["extended"] =
1101 }
1102 else
1103 jout("recommended polling time: \t Not Supported.\n");
1104}
1105
1107{
1108 jout("Conveyance self-test routine\n");
1110 jout("recommended polling time: \t (%4d) minutes.\n",
1111 (int)data->conveyance_test_completion_time);
1112 jglb["ata_smart_data"]["self_test"]["polling_minutes"]["conveyance"] =
1113 data->conveyance_test_completion_time;
1114 }
1115 else
1116 jout("recommended polling time: \t Not Supported.\n");
1117}
1118
1119// Check SMART attribute table for Threshold failure
1120// onlyfailed=0: are or were any age or prefailure attributes <= threshold
1121// onlyfailed=1: are any prefailure attributes <= threshold now
1123 const ata_smart_thresholds_pvt * thresholds,
1124 const ata_vendor_attr_defs & defs, int onlyfailed)
1125{
1126 for (int i = 0; i < NUMBER_ATA_SMART_ATTRIBUTES; i++) {
1127 const ata_smart_attribute & attr = data->vendor_attributes[i];
1128
1129 ata_attr_state state = ata_get_attr_state(attr, i, thresholds->thres_entries, defs);
1130
1131 if (!onlyfailed) {
1132 if (state >= ATTRSTATE_FAILED_PAST)
1133 return attr.id;
1134 }
1135 else {
1137 return attr.id;
1138 }
1139 }
1140 return 0;
1141}
1142
1143static void set_json_globals_from_smart_attrib(int id, const char * name,
1144 const ata_vendor_attr_defs & defs,
1145 uint64_t rawval)
1146{
1147 switch (id) {
1148 case 9:
1149 if (!str_starts_with(name, "Power_On_"))
1150 return;
1151 {
1152 int minutes = -1;
1153 switch (defs[id].raw_format) {
1154 case RAWFMT_RAW48: case RAWFMT_RAW64:
1156 case RAWFMT_SEC2HOUR: minutes = (rawval / 60) % 60; rawval /= 60*60; break;
1157 case RAWFMT_MIN2HOUR: minutes = rawval % 60; rawval /= 60; break;
1158 case RAWFMT_HALFMIN2HOUR: minutes = (rawval / 2) % 60; rawval /= 2*60; break;
1159 case RAWFMT_DEFAULT: // No database entry:
1160 rawval &= 0xffffffffULL; // ignore milliseconds from RAWFMT_MSEC24_HOUR32
1161 break;
1163 minutes = (int)(rawval >> 32) / (1000*60);
1164 if (minutes >= 60)
1165 minutes = -1;
1166 rawval &= 0xffffffffULL;
1167 break;
1168 default: return;
1169 }
1170 if (rawval > 0x00ffffffULL)
1171 return; // assume bogus value
1172 jglb["power_on_time"]["hours"] = rawval;
1173 if (minutes >= 0)
1174 jglb["power_on_time"]["minutes"] = minutes;
1175 }
1176 break;
1177 case 12:
1178 if (strcmp(name, "Power_Cycle_Count"))
1179 return;
1180 switch (defs[id].raw_format) {
1181 case RAWFMT_DEFAULT: case RAWFMT_RAW48: case RAWFMT_RAW64:
1183 default: return;
1184 }
1185 if (rawval > 0x00ffffffULL)
1186 return; // assume bogus value
1187 jglb["power_cycle_count"] = rawval;
1188 break;
1189 //case 194:
1190 // Temperature set separately from ata_return_temperature_value() below
1191 }
1192}
1193
1194// onlyfailed=0 : print all attribute values
1195// onlyfailed=1: just ones that are currently failed and have prefailure bit set
1196// onlyfailed=2: ones that are failed, or have failed with or without prefailure bit set
1198 const ata_smart_thresholds_pvt * thresholds,
1199 const ata_vendor_attr_defs & defs, int rpm,
1200 int onlyfailed, unsigned char format)
1201{
1202 bool brief = !!(format & ata_print_options::FMT_BRIEF);
1203 bool hexid = !!(format & ata_print_options::FMT_HEX_ID);
1204 bool hexval = !!(format & ata_print_options::FMT_HEX_VAL);
1205 bool needheader = true;
1206
1207 // step through all vendor attributes
1208 for (int i = 0, ji = 0; i < NUMBER_ATA_SMART_ATTRIBUTES; i++) {
1209 const ata_smart_attribute & attr = data->vendor_attributes[i];
1210
1211 // Check attribute and threshold
1212 unsigned char threshold = 0;
1213 ata_attr_state state = ata_get_attr_state(attr, i, thresholds->thres_entries, defs, &threshold);
1214 if (state == ATTRSTATE_NON_EXISTING)
1215 continue;
1216
1217 // These break out of the loop if we are only printing certain entries...
1218 if (onlyfailed == 1 && !(ATTRIBUTE_FLAGS_PREFAILURE(attr.flags) && state == ATTRSTATE_FAILED_NOW))
1219 continue;
1220
1221 if (onlyfailed == 2 && state < ATTRSTATE_FAILED_PAST)
1222 continue;
1223
1224 // print header only if needed
1225 if (needheader) {
1226 if (!onlyfailed) {
1227 jout("SMART Attributes Data Structure revision number: %d\n",(int)data->revnumber);
1228 jglb["ata_smart_attributes"]["revision"] = data->revnumber;
1229 jout("Vendor Specific SMART Attributes with Thresholds:\n");
1230 }
1231 if (!brief)
1232 jout("ID#%s ATTRIBUTE_NAME FLAG VALUE WORST THRESH TYPE UPDATED WHEN_FAILED RAW_VALUE\n",
1233 (!hexid ? "" : " "));
1234 else
1235 jout("ID#%s ATTRIBUTE_NAME FLAGS VALUE WORST THRESH FAIL RAW_VALUE\n",
1236 (!hexid ? "" : " "));
1237 needheader = false;
1238 }
1239
1240 // Format value, worst, threshold
1241 std::string valstr, worstr, threstr;
1242 if (state > ATTRSTATE_NO_NORMVAL)
1243 valstr = (!hexval ? strprintf("%.3d", attr.current)
1244 : strprintf("0x%02x", attr.current));
1245 else
1246 valstr = (!hexval ? "---" : "----");
1247 if (!(defs[attr.id].flags & ATTRFLAG_NO_WORSTVAL))
1248 worstr = (!hexval ? strprintf("%.3d", attr.worst)
1249 : strprintf("0x%02x", attr.worst));
1250 else
1251 worstr = (!hexval ? "---" : "----");
1252 if (state > ATTRSTATE_NO_THRESHOLD)
1253 threstr = (!hexval ? strprintf("%.3d", threshold)
1254 : strprintf("0x%02x", threshold));
1255 else
1256 threstr = (!hexval ? "---" : "----");
1257
1258 // Print line for each valid attribute
1259 std::string idstr = (!hexid ? strprintf("%3d", attr.id)
1260 : strprintf("0x%02x", attr.id));
1261 std::string attrname = ata_get_smart_attr_name(attr.id, defs, rpm);
1262 std::string rawstr = ata_format_attr_raw_value(attr, defs);
1263
1264 char flagstr[] = {
1265 (ATTRIBUTE_FLAGS_PREFAILURE(attr.flags) ? 'P' : '-'),
1266 (ATTRIBUTE_FLAGS_ONLINE(attr.flags) ? 'O' : '-'),
1267 (ATTRIBUTE_FLAGS_PERFORMANCE(attr.flags) ? 'S' : '-'),
1268 (ATTRIBUTE_FLAGS_ERRORRATE(attr.flags) ? 'R' : '-'),
1269 (ATTRIBUTE_FLAGS_EVENTCOUNT(attr.flags) ? 'C' : '-'),
1270 (ATTRIBUTE_FLAGS_SELFPRESERVING(attr.flags) ? 'K' : '-'),
1271 (ATTRIBUTE_FLAGS_OTHER(attr.flags) ? '+' : ' '),
1272 0
1273 };
1274
1275 if (!brief)
1276 jout("%s %-24s0x%04x %-4s %-4s %-4s %-10s%-9s%-12s%s\n",
1277 idstr.c_str(), attrname.c_str(), attr.flags,
1278 valstr.c_str(), worstr.c_str(), threstr.c_str(),
1279 (ATTRIBUTE_FLAGS_PREFAILURE(attr.flags) ? "Pre-fail" : "Old_age"),
1280 (ATTRIBUTE_FLAGS_ONLINE(attr.flags) ? "Always" : "Offline"),
1281 (state == ATTRSTATE_FAILED_NOW ? "FAILING_NOW" :
1282 state == ATTRSTATE_FAILED_PAST ? "In_the_past"
1283 : " -" ) ,
1284 rawstr.c_str());
1285 else
1286 jout("%s %-24s%s %-4s %-4s %-4s %-5s%s\n",
1287 idstr.c_str(), attrname.c_str(), flagstr,
1288 valstr.c_str(), worstr.c_str(), threstr.c_str(),
1289 (state == ATTRSTATE_FAILED_NOW ? "NOW" :
1290 state == ATTRSTATE_FAILED_PAST ? "Past"
1291 : "-" ),
1292 rawstr.c_str());
1293
1294 if (!jglb.is_enabled())
1295 continue;
1296
1297 json::ref jref = jglb["ata_smart_attributes"]["table"][ji++];
1298 jref["id"] = attr.id;
1299 jref["name"] = attrname;
1300 if (state > ATTRSTATE_NO_NORMVAL)
1301 jref["value"] = attr.current;
1302 if (!(defs[attr.id].flags & ATTRFLAG_NO_WORSTVAL))
1303 jref["worst"] = attr.worst;
1304 if (state > ATTRSTATE_NO_THRESHOLD) {
1305 jref["thresh"] = threshold;
1306 jref["when_failed"] = (state == ATTRSTATE_FAILED_NOW ? "now" :
1307 state == ATTRSTATE_FAILED_PAST ? "past"
1308 : "" );
1309 }
1310
1311 json::ref jreff = jref["flags"];
1312 jreff["value"] = attr.flags;
1313 jreff["string"] = flagstr;
1314 jreff["prefailure"] = !!ATTRIBUTE_FLAGS_PREFAILURE(attr.flags);
1315 jreff["updated_online"] = !!ATTRIBUTE_FLAGS_ONLINE(attr.flags);
1316 jreff["performance"] = !!ATTRIBUTE_FLAGS_PERFORMANCE(attr.flags);
1317 jreff["error_rate"] = !!ATTRIBUTE_FLAGS_ERRORRATE(attr.flags);
1318 jreff["event_count"] = !!ATTRIBUTE_FLAGS_EVENTCOUNT(attr.flags);
1319 jreff["auto_keep"] = !!ATTRIBUTE_FLAGS_SELFPRESERVING(attr.flags);
1320 if (ATTRIBUTE_FLAGS_OTHER(attr.flags))
1321 jreff["other"] = ATTRIBUTE_FLAGS_OTHER(attr.flags);
1322
1323 uint64_t rawval = ata_get_attr_raw_value(attr, defs);
1324 jref["raw"]["value"] = rawval;
1325 jref["raw"]["string"] = rawstr;
1326
1327 set_json_globals_from_smart_attrib(attr.id, attrname.c_str(), defs, rawval);
1328 }
1329
1330 if (!needheader) {
1331 if (!onlyfailed && brief) {
1332 int n = (!hexid ? 28 : 29);
1333 jout("%*s||||||_ K auto-keep\n"
1334 "%*s|||||__ C event count\n"
1335 "%*s||||___ R error rate\n"
1336 "%*s|||____ S speed/performance\n"
1337 "%*s||_____ O updated online\n"
1338 "%*s|______ P prefailure warning\n",
1339 n, "", n, "", n, "", n, "", n, "", n, "");
1340 }
1341 pout("\n");
1342 }
1343
1344 if (!jglb.is_enabled())
1345 return;
1346
1347 // Protocol independent temperature
1348 unsigned char t = ata_return_temperature_value(data, defs);
1349 if (t)
1350 jglb["temperature"]["current"] = t;
1351}
1352
1353// Print SMART related SCT capabilities
1355{
1356 unsigned short sctcaps = drive->words088_255[206-88];
1357 if (!(sctcaps & 0x01))
1358 return;
1359 json::ref jref = jglb["ata_sct_capabilities"];
1360 jout("SCT capabilities: \t (0x%04x)\tSCT Status supported.\n", sctcaps);
1361 jref["value"] = sctcaps;
1362 if (sctcaps & 0x08)
1363 jout("\t\t\t\t\tSCT Error Recovery Control supported.\n");
1364 jref["error_recovery_control_supported"] = !!(sctcaps & 0x08);
1365 if (sctcaps & 0x10)
1366 jout("\t\t\t\t\tSCT Feature Control supported.\n");
1367 jref["feature_control_supported"] = !!(sctcaps & 0x10);
1368 if (sctcaps & 0x20)
1369 jout("\t\t\t\t\tSCT Data Table supported.\n");
1370 jref["data_table_supported"] = !!(sctcaps & 0x20);
1371}
1372
1373
1375 firmwarebug_defs firmwarebugs)
1376{
1377 jout("General SMART Values:\n");
1378
1380
1381 if (isSupportSelfTest(data)){
1382 PrintSmartSelfExecStatus(data, firmwarebugs);
1383 }
1384
1388
1390
1391 jout( "\t\t\t\t\t%s\n", isGeneralPurposeLoggingCapable(drive)?
1392 "General Purpose Logging supported.":
1393 "No General Purpose Logging support.");
1394 jglb["ata_smart_data"]["capabilities"]["gp_logging_supported"] =
1396
1397 if (isSupportSelfTest(data)){
1400 }
1403
1404 ataPrintSCTCapability(drive);
1405
1406 jout("\n");
1407}
1408
1409// Get # sectors of a log addr, 0 if log does not exist.
1410static unsigned GetNumLogSectors(const ata_smart_log_directory * logdir, unsigned logaddr, bool gpl)
1411{
1412 if (!logdir)
1413 return 0;
1414 if (logaddr > 0xff)
1415 return 0;
1416 if (logaddr == 0)
1417 return 1;
1418 unsigned n = logdir->entry[logaddr-1].numsectors;
1419 if (gpl)
1420 // GP logs may have >255 sectors
1421 n |= logdir->entry[logaddr-1].reserved << 8;
1422 return n;
1423}
1424
1425// Get name of log.
1426static const char * GetLogName(unsigned logaddr)
1427{
1428 // Table A.2 of T13/2015-D (ACS-2) Revision 7, June 22, 2011
1429 // Table 112 of Serial ATA Revision 3.2, August 7, 2013
1430 // Table A.2 of T13/2161-D (ACS-3) Revision 5, October 28, 2013
1431 // Table 213 of T13/BSR INCITS 529 (ACS-4) Revision 20, October 26, 2017
1432 // Table 213 of T13/BSR INCITS 558 (ACS-5) Revision 10, March 3, 2021
1433 // Table 223 of T13/BSR INCITS 574 (ACS-6) Revision 3, March 30, 2023
1434 switch (logaddr) {
1435 case 0x00: return "Log Directory";
1436 case 0x01: return "Summary SMART error log";
1437 case 0x02: return "Comprehensive SMART error log";
1438 case 0x03: return "Ext. Comprehensive SMART error log";
1439 case 0x04: return "Device Statistics log";
1440 case 0x05: return "Reserved for CFA"; // ACS-2
1441 case 0x06: return "SMART self-test log"; // OBS-ACS-5
1442 case 0x07: return "Extended self-test log"; // OBS-ACS-5
1443 case 0x08: return "Power Conditions log"; // ACS-2
1444 case 0x09: return "Selective self-test log";
1445 case 0x0a: return "Device Statistics Notification"; // ACS-3
1446 case 0x0b: return "Reserved for CFA"; // ACS-3
1447 case 0x0c: return "Pending Defects log"; // ACS-4
1448 case 0x0d: return "LPS Mis-alignment log"; // ACS-2
1449 case 0x0e: return "Reserved for ZAC-2"; // ACS-4
1450 case 0x0f: return "Sense Data for Successful NCQ Cmds log"; // ACS-4
1451 case 0x10: return "NCQ Command Error log";
1452 case 0x11: return "SATA Phy Event Counters log";
1453 //case 0x12: return "SATA NCQ Queue Management log"; // SATA 3.0/3.1, ACS-3
1454 case 0x12: return "SATA NCQ Non-Data log"; // SATA 3.2, ACS-4
1455 case 0x13: return "SATA NCQ Send and Receive log"; // SATA 3.1, ACS-3
1456 case 0x14: return "Hybrid Information log"; // SATA 3.2, ACS-4
1457 case 0x15: return "Rebuild Assist log"; // SATA 3.2, ACS-4
1458 case 0x16: return "Out Of Band Management Control log"; // ACS-5
1459 case 0x17: return "Reserved for Serial ATA";
1460 case 0x18: return "Command Duration Limits log"; // ACS-5
1461 case 0x19: return "LBA Status log"; // ACS-3
1462
1463 case 0x20: return "Streaming performance log"; // OBS-8
1464 case 0x21: return "Write stream error log";
1465 case 0x22: return "Read stream error log";
1466 case 0x23: return "Delayed sector log"; // OBS-8
1467 case 0x24: return "Current Device Internal Status Data log"; // ACS-3
1468 case 0x25: return "Saved Device Internal Status Data log"; // ACS-3
1469
1470 case 0x2f: return "Set Sector Configuration"; // ACS-4
1471 case 0x30: return "IDENTIFY DEVICE data log"; // ACS-3
1472
1473 case 0x42: return "Mutate Configurations log"; // ACS-5
1474
1475 case 0x47: return "Concurrent Positioning Ranges log"; // ACS-5
1476
1477 case 0x53: return "Sense Data log"; // ACS-5
1478
1479 case 0x59: return "Power Consumption Control log"; // ACS-6
1480
1481 case 0x61: return "Capacity/Model Number Mapping log"; // ACS-6
1482
1483 case 0xe0: return "SCT Command/Status";
1484 case 0xe1: return "SCT Data Transfer";
1485 default:
1486 if (0xa0 <= logaddr && logaddr <= 0xdf)
1487 return "Device vendor specific log";
1488 if (0x80 <= logaddr && logaddr <= 0x9f)
1489 return "Host vendor specific log";
1490 return "Reserved";
1491 }
1492 /*NOTREACHED*/
1493}
1494
1495// Get log access permissions
1496static const char * get_log_rw(unsigned logaddr)
1497{
1498 if ( ( logaddr <= 0x08)
1499 || (0x0c <= logaddr && logaddr <= 0x0d)
1500 || (0x0f <= logaddr && logaddr <= 0x14)
1501 || (0x19 == logaddr)
1502 || (0x20 <= logaddr && logaddr <= 0x25)
1503 || (0x2f <= logaddr && logaddr <= 0x30)
1504 || (0x42 == logaddr)
1505 || (0x47 == logaddr)
1506 || (0x53 == logaddr)
1507 || (0x59 == logaddr)
1508 || (0x61 == logaddr))
1509 return "R/O";
1510
1511 if ( ( logaddr <= 0x0a)
1512 || (0x15 <= logaddr && logaddr <= 0x16)
1513 || (0x18 == logaddr)
1514 || (0x80 <= logaddr && logaddr <= 0x9f)
1515 || (0xe0 <= logaddr && logaddr <= 0xe1))
1516 return "R/W";
1517
1518 if (0xa0 <= logaddr && logaddr <= 0xdf)
1519 return "VS"; // Vendor specific
1520
1521 return "-"; // Unknown/Reserved
1522}
1523
1524// Init a fake log directory, assume that standard logs are supported
1526 const ata_print_options & options)
1527{
1528 memset(logdir, 0, sizeof(*logdir));
1529 logdir->logversion = 255;
1530 logdir->entry[0x01-1].numsectors = 1;
1531 logdir->entry[0x03-1].numsectors = (options.smart_ext_error_log + (4-1)) / 4;
1532 logdir->entry[0x04-1].numsectors = 8;
1533 logdir->entry[0x06-1].numsectors = 1;
1534 logdir->entry[0x07-1].numsectors = (options.smart_ext_selftest_log + (19-1)) / 19;
1535 logdir->entry[0x09-1].numsectors = 1;
1536 logdir->entry[0x11-1].numsectors = 1;
1537 return logdir;
1538}
1539
1540// Print SMART and/or GP Log Directory
1542 const ata_smart_log_directory * smartlogdir)
1543{
1544 json::ref jref = jglb["ata_log_directory"];
1545 if (gplogdir) {
1546 jout("General Purpose Log Directory Version %u\n", gplogdir->logversion);
1547 jref["gp_dir_version"] = gplogdir->logversion;
1548 }
1549 if (smartlogdir) {
1550 jout("SMART %sLog Directory Version %u%s\n",
1551 (gplogdir ? " " : ""), smartlogdir->logversion,
1552 (smartlogdir->logversion==1 ? " [multi-sector log support]" : ""));
1553 jref["smart_dir_version"] = smartlogdir->logversion;
1554 jref["smart_dir_multi_sector"] = (smartlogdir->logversion == 1);
1555 }
1556
1557 jout("Address Access R/W Size Description\n");
1558
1559 for (unsigned i = 0, ji = 0; i <= 0xff; i++) {
1560 // Get number of sectors
1561 unsigned smart_numsect = GetNumLogSectors(smartlogdir, i, false);
1562 unsigned gp_numsect = GetNumLogSectors(gplogdir , i, true );
1563
1564 if (!(smart_numsect || gp_numsect))
1565 continue; // Log does not exist
1566
1567 const char * acc; unsigned size;
1568 if (smart_numsect == gp_numsect) {
1569 acc = "GPL,SL"; size = gp_numsect;
1570 }
1571 else if (!smart_numsect) {
1572 acc = "GPL"; size = gp_numsect;
1573 }
1574 else if (!gp_numsect) {
1575 acc = " SL"; size = smart_numsect;
1576 }
1577 else {
1578 acc = 0; size = 0;
1579 }
1580
1581 unsigned i2 = i;
1582 if (acc && ((0x80 <= i && i < 0x9f) || (0xa0 <= i && i < 0xdf))) {
1583 // Find range of Host/Device vendor specific logs with same size
1584 unsigned imax = (i < 0x9f ? 0x9f : 0xdf);
1585 for (unsigned j = i+1; j <= imax; j++) {
1586 unsigned sn = GetNumLogSectors(smartlogdir, j, false);
1587 unsigned gn = GetNumLogSectors(gplogdir , j, true );
1588
1589 if (!(sn == smart_numsect && gn == gp_numsect))
1590 break;
1591 i2 = j;
1592 }
1593 }
1594
1595 const char * name = GetLogName(i);
1596 const char * rw = get_log_rw(i);
1597
1598 if (i2 > i)
1599 jout("0x%02x-0x%02x %-6s %-3s %5u %s\n", i, i2, acc, rw, size, name);
1600 else if (acc)
1601 jout( "0x%02x %-6s %-3s %5u %s\n", i, acc, rw, size, name);
1602 else {
1603 // GPL and SL support different sizes
1604 jout( "0x%02x %-6s %-3s %5u %s\n", i, "GPL", rw, gp_numsect, name);
1605 jout( "0x%02x %-6s %-3s %5u %s\n", i, "SL", rw, smart_numsect, name);
1606 }
1607
1608 for (;;) {
1609 json::ref jrefi = jref["table"][ji++];
1610 jrefi["address"] = i;
1611 jrefi["name"] = name;
1612 if (rw[0] == 'R' && rw[1] && rw[2]) {
1613 jrefi["read"] = true;
1614 jrefi["write"] = (rw[2] == 'W');
1615 }
1616 if (gp_numsect)
1617 jrefi["gp_sectors"] = gp_numsect;
1618 if (smart_numsect)
1619 jrefi["smart_sectors"] = smart_numsect;
1620 if (i >= i2)
1621 break;
1622 i++;
1623 }
1624 }
1625 jout("\n");
1626}
1627
1628// Print hexdump of log pages.
1629// Format is compatible with 'xxd -r'.
1630static void PrintLogPages(const char * type, const unsigned char * data,
1631 unsigned char logaddr, unsigned page,
1632 unsigned num_pages, unsigned max_pages)
1633{
1634 pout("%s Log 0x%02x [%s], Page %u-%u (of %u)\n",
1635 type, logaddr, GetLogName(logaddr), page, page+num_pages-1, max_pages);
1636 for (unsigned i = 0; i < num_pages * 512; i += 16) {
1637 const unsigned char * p = data+i;
1638 pout("%07x: %02x %02x %02x %02x %02x %02x %02x %02x "
1639 "%02x %02x %02x %02x %02x %02x %02x %02x ",
1640 (page * 512) + i,
1641 p[ 0], p[ 1], p[ 2], p[ 3], p[ 4], p[ 5], p[ 6], p[ 7],
1642 p[ 8], p[ 9], p[10], p[11], p[12], p[13], p[14], p[15]);
1643#define P(n) (' ' <= p[n] && p[n] <= '~' ? (int)p[n] : '.')
1644 pout("|%c%c%c%c%c%c%c%c"
1645 "%c%c%c%c%c%c%c%c|\n",
1646 P( 0), P( 1), P( 2), P( 3), P( 4), P( 5), P( 6), P( 7),
1647 P( 8), P( 9), P(10), P(11), P(12), P(13), P(14), P(15));
1648#undef P
1649 if ((i & 0x1ff) == 0x1f0)
1650 pout("\n");
1651 }
1652}
1653
1654///////////////////////////////////////////////////////////////////////
1655// Device statistics (Log 0x04)
1656
1657// Section A.5 of T13/2161-D (ACS-3) Revision 5, October 28, 2013
1658// Section 9.5 of T13/BSR INCITS 529 (ACS-4) Revision 20, October 26, 2017
1659
1661{
1662 short size; // #bytes of value, -1 for signed char
1663 const char * name;
1664};
1665
1667 { 2, "List of supported log pages" },
1668 { 0, 0 }
1669};
1670
1672 { 2, "General Statistics" },
1673 { 4, "Lifetime Power-On Resets" },
1674 { 4, "Power-on Hours" },
1675 { 6, "Logical Sectors Written" },
1676 { 6, "Number of Write Commands" },
1677 { 6, "Logical Sectors Read" },
1678 { 6, "Number of Read Commands" },
1679 { 6, "Date and Time TimeStamp" }, // ACS-3
1680 { 4, "Pending Error Count" }, // ACS-4
1681 { 2, "Workload Utilization" }, // ACS-4
1682 { 6, "Utilization Usage Rate" }, // ACS-4 (TODO: 47:40: Validity, 39:36 Basis, 7:0 Usage rate)
1683 { 7, "Resource Availability" }, // ACS-4 (TODO: 55:16 Resources, 15:0 Fraction)
1684 { 1, "Random Write Resources Used" }, // ACS-4
1685 { 0, 0 }
1686};
1687
1689 { 2, "Free-Fall Statistics" },
1690 { 4, "Number of Free-Fall Events Detected" },
1691 { 4, "Overlimit Shock Events" },
1692 { 0, 0 }
1693};
1694
1696 { 2, "Rotating Media Statistics" },
1697 { 4, "Spindle Motor Power-on Hours" },
1698 { 4, "Head Flying Hours" },
1699 { 4, "Head Load Events" },
1700 { 4, "Number of Reallocated Logical Sectors" },
1701 { 4, "Read Recovery Attempts" },
1702 { 4, "Number of Mechanical Start Failures" },
1703 { 4, "Number of Realloc. Candidate Logical Sectors" }, // ACS-3
1704 { 4, "Number of High Priority Unload Events" }, // ACS-3
1705 { 0, 0 }
1706};
1707
1709 { 2, "General Errors Statistics" },
1710 { 4, "Number of Reported Uncorrectable Errors" },
1711//{ 4, "Number of Resets Between Command Acceptance and Command Completion" },
1712 { 4, "Resets Between Cmd Acceptance and Completion" },
1713 { 4, "Physical Element Status Changed" }, // ACS-4
1714 { 0, 0 }
1715};
1716
1718 { 2, "Temperature Statistics" },
1719 { -1, "Current Temperature" },
1720 { -1, "Average Short Term Temperature" },
1721 { -1, "Average Long Term Temperature" },
1722 { -1, "Highest Temperature" },
1723 { -1, "Lowest Temperature" },
1724 { -1, "Highest Average Short Term Temperature" },
1725 { -1, "Lowest Average Short Term Temperature" },
1726 { -1, "Highest Average Long Term Temperature" },
1727 { -1, "Lowest Average Long Term Temperature" },
1728 { 4, "Time in Over-Temperature" },
1729 { -1, "Specified Maximum Operating Temperature" },
1730 { 4, "Time in Under-Temperature" },
1731 { -1, "Specified Minimum Operating Temperature" },
1732 { 0, 0 }
1733};
1734
1736 { 2, "Transport Statistics" },
1737 { 4, "Number of Hardware Resets" },
1738 { 4, "Number of ASR Events" },
1739 { 4, "Number of Interface CRC Errors" },
1740 { 0, 0 }
1741};
1742
1744 { 2, "Solid State Device Statistics" },
1745 { 1, "Percentage Used Endurance Indicator" },
1746 { 0, 0 }
1747};
1748
1758 // TODO: 0x08 Zoned Device Statistics (T13/f16136r7, January 2017)
1759 // TODO: 0x09 Command Duration Limits Statistics (ACS-5 Revision 10, March 2021)
1760 // TODO: 0x0a Command Duration Limits Statistics 2..3 (ACS-6 Revision 3, March 2023)
1761};
1762
1763const int num_devstat_infos = sizeof(devstat_infos)/sizeof(devstat_infos[0]);
1764
1765static const char * get_device_statistics_page_name(int page)
1766{
1767 if (page < num_devstat_infos)
1768 return devstat_infos[page][0].name;
1769 if (page == 0xff)
1770 return "Vendor Specific Statistics"; // ACS-4
1771 return "Unknown Statistics";
1772}
1773
1774static void set_json_globals_from_device_statistics(int page, int offset, int64_t val)
1775{
1776 switch (page) {
1777 case 1:
1778 switch (offset) {
1779 case 0x008: jglb["power_cycle_count"] = val; break; // ~= Lifetime Power-On Resets
1780 case 0x010: jglb["power_on_time"]["hours"]= val; break;
1781 }
1782 break;
1783 case 5:
1784 switch (offset) {
1785 case 0x008: jglb["temperature"]["current"] = val; break;
1786 case 0x020: jglb["temperature"]["lifetime_max"] = val; break;
1787 case 0x028: jglb["temperature"]["lifetime_min"] = val; break;
1788 case 0x050: jglb["temperature"]["lifetime_over_limit_minutes"] = val; break;
1789 case 0x058: jglb["temperature"]["op_limit_max"] = val; break;
1790 case 0x060: jglb["temperature"]["lifetime_under_limit_minutes"] = val; break;
1791 case 0x068: jglb["temperature"]["op_limit_min"] = val; break;
1792 }
1793 break;
1794 }
1795}
1796
1797static void print_device_statistics_page(const json::ref & jref, const unsigned char * data, int page)
1798{
1799 const devstat_entry_info * info = (page < num_devstat_infos ? devstat_infos[page] : 0);
1800 const char * name = get_device_statistics_page_name(page);
1801
1802 // Check page number in header
1803 static const char line[] = " ===== = = === == ";
1804 if (!data[2]) {
1805 pout("0x%02x%s%s (empty) ==\n", page, line, name);
1806 return;
1807 }
1808 if (data[2] != page) {
1809 pout("0x%02x%s%s (invalid page 0x%02x in header) ==\n", page, line, name, data[2]);
1810 return;
1811 }
1812
1813 int rev = data[0] | (data[1] << 8);
1814 jout("0x%02x%s%s (rev %d) ==\n", page, line, name, rev);
1815 jref["number"] = page;
1816 jref["name"] = name;
1817 jref["revision"] = rev;
1818
1819 // Print entries
1820 int ji = 0;
1821 for (int i = 1, offset = 8; offset < 512-7; i++, offset+=8) {
1822 // Check for last known entry
1823 if (info && !info[i].size)
1824 info = 0;
1825
1826 // Skip unsupported entries
1827 unsigned char flags = data[offset+7];
1828 if (!(flags & 0x80))
1829 continue;
1830
1831 // Stop if unknown entries contain garbage data due to buggy firmware
1832 if (!info && (data[offset+5] || data[offset+6])) {
1833 pout("0x%02x 0x%03x - - [Trailing garbage ignored]\n", page, offset);
1834 break;
1835 }
1836
1837 // Get value name
1838 const char * valname = (info ? info[i].name :
1839 (page == 0xff) ? "Vendor Specific" // ACS-4
1840 : "Unknown" );
1841
1842 // Get value size, default to max if unknown
1843 int size = (info ? info[i].size : 7);
1844
1845 // Get flags (supported flag already checked above)
1846 bool valid = !!(flags & 0x40);
1847 bool normalized = !!(flags & 0x20);
1848 bool supports_dsn = !!(flags & 0x10); // ACS-3
1849 bool monitored_condition_met = !!(flags & 0x08); // ACS-3
1850 // TODO: 0x04: READ THEN INITIALIZE SUPPORTED (ACS-5)
1851 unsigned char reserved_flags = (flags & 0x07);
1852
1853 // Format value
1854 int64_t val = 0;
1855 char valstr[32];
1856 if (valid) {
1857 // Get value
1858 if (size < 0) {
1859 val = (signed char)data[offset];
1860 }
1861 else {
1862 for (int j = 0; j < size; j++)
1863 val |= (int64_t)data[offset+j] << (j*8);
1864 }
1865 snprintf(valstr, sizeof(valstr), "%" PRId64, val);
1866 }
1867 else {
1868 // Value not known (yet)
1869 valstr[0] = '-'; valstr[1] = 0;
1870 }
1871
1872 char flagstr[] = {
1873 (valid ? 'V' : '-'), // JSON only
1874 (normalized ? 'N' : '-'),
1875 (supports_dsn ? 'D' : '-'),
1876 (monitored_condition_met ? 'C' : '-'),
1877 (reserved_flags ? '+' : ' '),
1878 0
1879 };
1880
1881 jout("0x%02x 0x%03x %d %15s %s %s\n",
1882 page, offset, abs(size), valstr, flagstr+1, valname);
1883
1884 if (!jglb.is_enabled())
1885 continue;
1886
1887 json::ref jrefi = jref["table"][ji++];
1888 jrefi["offset"] = offset;
1889 jrefi["name"] = valname;
1890 jrefi["size"] = abs(size);
1891 if (valid)
1892 jrefi["value"] = val; // TODO: May be unsafe JSON int if size > 6
1893
1894 json::ref jreff = jrefi["flags"];
1895 jreff["value"] = flags;
1896 jreff["string"] = flagstr;
1897 jreff["valid"] = valid;
1898 jreff["normalized"] = normalized;
1899 jreff["supports_dsn"] = supports_dsn;
1900 jreff["monitored_condition_met"] = monitored_condition_met;
1901 if (reserved_flags)
1902 jreff["other"] = reserved_flags;
1903
1904 if (valid)
1905 set_json_globals_from_device_statistics(page, offset, val);
1906 }
1907}
1908
1909static bool print_device_statistics(ata_device * device, unsigned nsectors,
1910 const std::vector<int> & single_pages, bool all_pages, bool ssd_page,
1911 bool use_gplog)
1912{
1913 // Read list of supported pages from page 0
1914 unsigned char page_0[512] = {0, };
1915 int rc;
1916
1917 if (use_gplog)
1918 rc = ataReadLogExt(device, 0x04, 0, 0, page_0, 1);
1919 else
1920 rc = ataReadSmartLog(device, 0x04, page_0, 1);
1921 if (!rc) {
1922 jerr("Read Device Statistics page 0x00 failed\n\n");
1923 return false;
1924 }
1925
1926 unsigned char nentries = page_0[8];
1927 if (!(page_0[2] == 0 && nentries > 0)) {
1928 jerr("Device Statistics page 0x00 is invalid (page=0x%02x, nentries=%d)\n\n", page_0[2], nentries);
1929 return false;
1930 }
1931
1932 // Prepare list of pages to print
1933 std::vector<int> pages;
1934 unsigned i;
1935 if (all_pages) {
1936 // Add all supported pages
1937 for (i = 0; i < nentries; i++) {
1938 int page = page_0[8+1+i];
1939 if (page)
1940 pages.push_back(page);
1941 }
1942 ssd_page = false;
1943 }
1944 // Add manually specified pages
1945 bool print_page_0 = false;
1946 for (i = 0; i < single_pages.size() || ssd_page; i++) {
1947 int page = (i < single_pages.size() ? single_pages[i] : 0x07);
1948 if (!page)
1949 print_page_0 = true;
1950 else if (page >= (int)nsectors)
1951 pout("Device Statistics Log has only 0x%02x pages\n", nsectors);
1952 else
1953 pages.push_back(page);
1954 if (page == 0x07)
1955 ssd_page = false;
1956 }
1957
1958 json::ref jref = jglb["ata_device_statistics"];
1959
1960 // Print list of supported pages if requested
1961 if (print_page_0) {
1962 pout("Device Statistics (%s Log 0x04) supported pages\n",
1963 use_gplog ? "GP" : "SMART");
1964 jout("Page Description\n");
1965 for (i = 0; i < nentries; i++) {
1966 int page = page_0[8+1+i];
1967 const char * name = get_device_statistics_page_name(page);
1968 jout("0x%02x %s\n", page, name);
1969 jref["supported_pages"][i]["number"] = page;
1970 jref["supported_pages"][i]["name"] = name;
1971 }
1972 jout("\n");
1973 }
1974
1975 // Read & print pages
1976 if (!pages.empty()) {
1977 pout("Device Statistics (%s Log 0x04)\n",
1978 use_gplog ? "GP" : "SMART");
1979 jout("Page Offset Size Value Flags Description\n");
1980 int max_page = 0;
1981
1982 if (!use_gplog)
1983 for (i = 0; i < pages.size(); i++) {
1984 int page = pages[i];
1985 if (max_page < page && page < 0xff)
1986 max_page = page;
1987 }
1988
1989 raw_buffer pages_buf((max_page+1) * 512);
1990
1991 if (!use_gplog && !ataReadSmartLog(device, 0x04, pages_buf.data(), max_page+1)) {
1992 jerr("Read Device Statistics pages 0x00-0x%02x failed\n\n", max_page);
1993 return false;
1994 }
1995
1996 int ji = 0;
1997 for (i = 0; i < pages.size(); i++) {
1998 int page = pages[i];
1999 if (use_gplog) {
2000 if (!ataReadLogExt(device, 0x04, 0, page, pages_buf.data(), 1)) {
2001 jerr("Read Device Statistics page 0x%02x failed\n\n", page);
2002 return false;
2003 }
2004 }
2005 else if (page > max_page)
2006 continue;
2007
2008 int offset = (use_gplog ? 0 : page * 512);
2009 print_device_statistics_page(jref["pages"][ji++], pages_buf.data() + offset, page);
2010 }
2011
2012 jout("%32s|||_ C monitored condition met\n", "");
2013 jout("%32s||__ D supports DSN\n", "");
2014 jout("%32s|___ N normalized value\n\n", "");
2015 }
2016
2017 return true;
2018}
2019
2020
2021///////////////////////////////////////////////////////////////////////
2022// Pending Defects log (Log 0x0c)
2023
2024// Section 9.26 of T13/BSR INCITS 529 (ACS-4) Revision 20, October 26, 2017
2025
2026static bool print_pending_defects_log(ata_device * device, unsigned nsectors,
2027 unsigned max_entries)
2028{
2029 // Read #entries from page 0
2030 unsigned char page_buf[512] = {0, };
2031 if (!ataReadLogExt(device, 0x0c, 0, 0, page_buf, 1)) {
2032 pout("Read Pending Defects log page 0x00 failed\n\n");
2033 return false;
2034 }
2035
2036 jout("Pending Defects log (GP Log 0x0c)\n");
2037 unsigned nentries = sg_get_unaligned_le32(page_buf);
2038 json::ref jref = jglb["ata_pending_defects_log"];
2039 jref["size"] = nsectors * 32 - 1;
2040 jref["count"] = nentries;
2041 if (!nentries) {
2042 jout("No Defects Logged\n\n");
2043 return true;
2044 }
2045
2046 // Print entries
2047 jout("Index LBA Hours\n");
2048 for (unsigned i = 0, pi = 1, page = 0; i < nentries && i < max_entries; i++, pi++) {
2049 // Read new page if required
2050 if (pi >= 32) {
2051 if (++page >= nsectors) {
2052 pout("Pending Defects count %u exceeds log size (#pages=%u)\n\n",
2053 nentries, nsectors);
2054 return false;
2055 }
2056 if (!ataReadLogExt(device, 0x0c, 0, page, page_buf, 1)) {
2057 pout("Read Pending Defects log page 0x%02x failed\n\n", page);
2058 return false;
2059 }
2060 pi = 0;
2061 }
2062
2063 const unsigned char * entry = page_buf + 16 * pi;
2064 unsigned hours = sg_get_unaligned_le32(entry);
2065 char hourstr[32];
2066 if (hours != 0xffffffffU)
2067 snprintf(hourstr, sizeof(hourstr), "%u", hours);
2068 else
2069 hourstr[0] = '-', hourstr[1] = 0;
2070 uint64_t lba = sg_get_unaligned_le64(entry + 8);
2071 jout("%5u %18" PRIu64 " %8s\n", i, lba, hourstr);
2072
2073 json::ref jrefi = jref["table"][i];
2074 jrefi["lba"].set_unsafe_uint64(lba);
2075 if (hours != 0xffffffffU)
2076 jrefi["power_on_hours"] = hours;
2077 }
2078
2079 if (nentries > max_entries)
2080 pout("... (%u entries not shown)\n", nentries - max_entries);
2081 jout("\n");
2082 return true;
2083}
2084
2085
2086///////////////////////////////////////////////////////////////////////
2087
2088// Print log 0x11
2089static void PrintSataPhyEventCounters(const unsigned char * data, bool reset)
2090{
2091 if (checksum(data))
2092 checksumwarning("SATA Phy Event Counters");
2093 jout("SATA Phy Event Counters (GP Log 0x11)\n");
2094 if (data[0] || data[1] || data[2] || data[3])
2095 pout("[Reserved: 0x%02x 0x%02x 0x%02x 0x%02x]\n",
2096 data[0], data[1], data[2], data[3]);
2097 jout("ID Size Value Description\n");
2098
2099 for (unsigned i = 4, ji = 0; ; ) {
2100 // Get counter id and size (bits 14:12)
2101 unsigned id = data[i] | (data[i+1] << 8);
2102 unsigned size = ((id >> 12) & 0x7) << 1;
2103 id &= 0x8fff;
2104
2105 // End of counter table ?
2106 if (!id)
2107 break;
2108 i += 2;
2109
2110 if (!(2 <= size && size <= 8 && i + size < 512)) {
2111 pout("0x%04x %u: Invalid entry\n", id, size);
2112 break;
2113 }
2114
2115 // Get value
2116 uint64_t val = 0, max_val = 0;
2117 for (unsigned j = 0; j < size; j+=2) {
2118 val |= (uint64_t)(data[i+j] | (data[i+j+1] << 8)) << (j*8);
2119 max_val |= (uint64_t)0xffffU << (j*8);
2120 }
2121 i += size;
2122
2123 // Get name
2124 const char * name;
2125 switch (id) {
2126 case 0x001: name = "Command failed due to ICRC error"; break; // Mandatory
2127 case 0x002: name = "R_ERR response for data FIS"; break;
2128 case 0x003: name = "R_ERR response for device-to-host data FIS"; break;
2129 case 0x004: name = "R_ERR response for host-to-device data FIS"; break;
2130 case 0x005: name = "R_ERR response for non-data FIS"; break;
2131 case 0x006: name = "R_ERR response for device-to-host non-data FIS"; break;
2132 case 0x007: name = "R_ERR response for host-to-device non-data FIS"; break;
2133 case 0x008: name = "Device-to-host non-data FIS retries"; break;
2134 case 0x009: name = "Transition from drive PhyRdy to drive PhyNRdy"; break;
2135 case 0x00A: name = "Device-to-host register FISes sent due to a COMRESET"; break; // Mandatory
2136 case 0x00B: name = "CRC errors within host-to-device FIS"; break;
2137 case 0x00D: name = "Non-CRC errors within host-to-device FIS"; break;
2138 case 0x00F: name = "R_ERR response for host-to-device data FIS, CRC"; break;
2139 case 0x010: name = "R_ERR response for host-to-device data FIS, non-CRC"; break;
2140 case 0x012: name = "R_ERR response for host-to-device non-data FIS, CRC"; break;
2141 case 0x013: name = "R_ERR response for host-to-device non-data FIS, non-CRC"; break;
2142 default: name = ((id & 0x8000) ? "Vendor specific" : "Unknown"); break;
2143 }
2144
2145 // Counters stop at max value, add '+' in this case
2146 jout("0x%04x %u %12" PRIu64 "%c %s\n", id, size, val,
2147 (val == max_val ? '+' : ' '), name);
2148
2149 json::ref jref = jglb["sata_phy_event_counters"]["table"][ji++];
2150 jref["id"] = id;
2151 jref["name"] = name;
2152 jref["size"] = size;
2153 jref["value"] = val;
2154 jref["overflow"] = (val == max_val);
2155 }
2156 if (reset)
2157 jout("All counters reset\n");
2158 jout("\n");
2159 jglb["sata_phy_event_counters"]["reset"] = reset;
2160}
2161
2162// Format milliseconds from error log entry as "DAYS+H:M:S.MSEC"
2163static std::string format_milliseconds(unsigned msec)
2164{
2165 unsigned days = msec / 86400000U;
2166 msec -= days * 86400000U;
2167 unsigned hours = msec / 3600000U;
2168 msec -= hours * 3600000U;
2169 unsigned min = msec / 60000U;
2170 msec -= min * 60000U;
2171 unsigned sec = msec / 1000U;
2172 msec -= sec * 1000U;
2173
2174 std::string str;
2175 if (days)
2176 str = strprintf("%2ud+", days);
2177 str += strprintf("%02u:%02u:%02u.%03u", hours, min, sec, msec);
2178 return str;
2179}
2180
2181// Get description for 'state' value from SMART Error Logs
2182static const char * get_error_log_state_desc(unsigned state)
2183{
2184 state &= 0x0f;
2185 switch (state){
2186 case 0x0: return "in an unknown state";
2187 case 0x1: return "sleeping";
2188 case 0x2: return "in standby mode";
2189 case 0x3: return "active or idle";
2190 case 0x4: return "doing SMART Offline or Self-test";
2191 default:
2192 return (state < 0xb ? "in a reserved state"
2193 : "in a vendor specific state");
2194 }
2195}
2196
2197// returns number of errors
2199 firmwarebug_defs firmwarebugs)
2200{
2201 json::ref jref = jglb["ata_smart_error_log"]["summary"];
2202 jout("SMART Error Log Version: %d\n", (int)data->revnumber);
2203 jref["revision"] = data->revnumber;
2204
2205 // Check consistency of error count and log index (pointer).
2206 // Starting with ATA/ATAPI 6, the index shall be zero if there are no log entries.
2207 if ( !( !data->ata_error_count == !data->error_log_pointer
2208 && !((data->ata_error_count - data->error_log_pointer) % 5))
2209 && !firmwarebugs.is_set(BUG_SAMSUNG2) )
2210 pout("Warning: ATA error count %d inconsistent with error log index %d\n",
2211 data->ata_error_count, data->error_log_pointer);
2212
2213 // if no errors logged, return
2214 if (!(data->ata_error_count && data->error_log_pointer)) {
2215 jout("No Errors Logged\n\n");
2216 jref["count"] = 0;
2217 return 0;
2218 }
2219 print_on();
2220 // If log pointer out of range, return
2221 if (data->error_log_pointer>5){
2222 pout("Invalid Error Log index = 0x%02x (valid range is from 1 to 5)\n",
2223 data->error_log_pointer);
2224 pout("ATA Error Count: %d (possibly also invalid)\n\n", data->ata_error_count);
2225 return 0;
2226 }
2227
2228 // starting printing error log info
2229 if (data->ata_error_count<=5)
2230 jout( "ATA Error Count: %d\n", (int)data->ata_error_count);
2231 else
2232 jout( "ATA Error Count: %d (device log contains only the most recent five errors)\n",
2233 (int)data->ata_error_count);
2234 jref["count"] = data->ata_error_count;
2235 jref["logged_count"] = (data->ata_error_count <= 5 ? data->ata_error_count : 5);
2236
2237 print_off();
2238 jout("\tCR = Command Register [HEX]\n"
2239 "\tFR = Features Register [HEX]\n"
2240 "\tSC = Sector Count Register [HEX]\n"
2241 "\tSN = Sector Number Register [HEX]\n"
2242 "\tCL = Cylinder Low Register [HEX]\n"
2243 "\tCH = Cylinder High Register [HEX]\n"
2244 "\tDH = Device/Head Register [HEX]\n"
2245 "\tDC = Device Command Register [HEX]\n"
2246 "\tER = Error register [HEX]\n"
2247 "\tST = Status register [HEX]\n"
2248 "Powered_Up_Time is measured from power on, and printed as\n"
2249 "DDd+hh:mm:SS.sss where DD=days, hh=hours, mm=minutes,\n"
2250 "SS=sec, and sss=millisec. It \"wraps\" after 49.710 days.\n\n");
2251
2252 // now step through the five error log data structures (table 39 of spec)
2253 for (int k = 4, ji = 0; k >= 0; k--) {
2254
2255 // The error log data structure entries are a circular buffer
2256 int i = (data->error_log_pointer + k) % 5;
2257 const ata_smart_errorlog_struct * elog = data->errorlog_struct+i;
2258 const ata_smart_errorlog_error_struct * summary = &(elog->error_struct);
2259
2260 // Spec says: unused error log structures shall be zero filled
2261 if (nonempty(elog, sizeof(*elog))){
2262 // Table 57 of T13/1532D Volume 1 Revision 3
2263 const char *msgstate = get_error_log_state_desc(summary->state);
2264 int days = (int)summary->timestamp/24;
2265
2266 // See table 42 of ATA5 spec
2267 print_on();
2268 jout("Error %d occurred at disk power-on lifetime: %d hours (%d days + %d hours)\n",
2269 (int)(data->ata_error_count+k-4), (int)summary->timestamp, days, (int)(summary->timestamp-24*days));
2270 print_off();
2271
2272 json::ref jrefi = jref["table"][ji++];
2273 jrefi["error_number"] = data->ata_error_count + k - 4;
2274 jrefi["lifetime_hours"] = summary->timestamp;
2275
2276 jout(" When the command that caused the error occurred, the device was %s.\n\n", msgstate);
2277 jout(" After command completion occurred, registers were:\n"
2278 " ER ST SC SN CL CH DH\n"
2279 " -- -- -- -- -- -- --\n"
2280 " %02x %02x %02x %02x %02x %02x %02x",
2281 (int)summary->error_register,
2282 (int)summary->status,
2283 (int)summary->sector_count,
2284 (int)summary->sector_number,
2285 (int)summary->cylinder_low,
2286 (int)summary->cylinder_high,
2287 (int)summary->drive_head);
2288
2289 {
2290 json::ref jrefir = jrefi["completion_registers"];
2291 jrefir["error"] = summary->error_register;
2292 jrefir["status"] = summary->status;
2293 jrefir["count"] = summary->sector_count;
2294 jrefir["lba"] = (summary->sector_number )
2295 | (summary->cylinder_low << 8)
2296 | (summary->cylinder_high << 16);
2297 jrefir["device"] = summary->drive_head;
2298 }
2299
2300 // Add a description of the contents of the status and error registers
2301 // if possible
2302 std::string st_er_desc = format_st_er_desc(elog);
2303 if (!st_er_desc.empty()) {
2304 jout(" %s", st_er_desc.c_str());
2305 jrefi["error_description"] = st_er_desc;
2306 }
2307 jout("\n\n");
2308 jout(" Commands leading to the command that caused the error were:\n"
2309 " CR FR SC SN CL CH DH DC Powered_Up_Time Command/Feature_Name\n"
2310 " -- -- -- -- -- -- -- -- ---------------- --------------------\n");
2311 for (int j = 4, jj = 0; j >= 0; j--) {
2312 const ata_smart_errorlog_command_struct * thiscommand = elog->commands+j;
2313
2314 // Spec says: unused data command structures shall be zero filled
2315 if (nonempty(thiscommand, sizeof(*thiscommand))) {
2316 const char * atacmd = look_up_ata_command(thiscommand->commandreg, thiscommand->featuresreg);
2317 jout(" %02x %02x %02x %02x %02x %02x %02x %02x %16s %s\n",
2318 (int)thiscommand->commandreg,
2319 (int)thiscommand->featuresreg,
2320 (int)thiscommand->sector_count,
2321 (int)thiscommand->sector_number,
2322 (int)thiscommand->cylinder_low,
2323 (int)thiscommand->cylinder_high,
2324 (int)thiscommand->drive_head,
2325 (int)thiscommand->devicecontrolreg,
2326 format_milliseconds(thiscommand->timestamp).c_str(),
2327 atacmd);
2328
2329 json::ref jrefic = jrefi["previous_commands"][jj++];
2330 json::ref jreficr = jrefic["registers"];
2331 jreficr["command"] = thiscommand->commandreg;
2332 jreficr["features"] = thiscommand->featuresreg,
2333 jreficr["count"] = thiscommand->sector_count;
2334 jreficr["lba"] = (thiscommand->sector_number )
2335 | (thiscommand->cylinder_low << 8)
2336 | (thiscommand->cylinder_high << 16);
2337 jreficr["device"] = thiscommand->drive_head;
2338 jreficr["device_control"] = thiscommand->devicecontrolreg;
2339 jrefic["powerup_milliseconds"] = thiscommand->timestamp;
2340 jrefic["command_name"] = atacmd;
2341 }
2342 }
2343 jout("\n");
2344 }
2345 }
2346 print_on();
2348 pout("\n");
2349 print_off();
2350 return data->ata_error_count;
2351}
2352
2353// Print SMART Extended Comprehensive Error Log (GP Log 0x03)
2355 const firmwarebug_defs & firmwarebugs,
2356 const ata_smart_exterrlog * log,
2357 unsigned nsectors, unsigned max_errors)
2358{
2359 json::ref jref = jglb["ata_smart_error_log"]["extended"];
2360 jout("SMART Extended Comprehensive Error Log Version: %u (%u sectors)\n",
2361 log->version, nsectors);
2362 jref["revision"] = log->version;
2363 jref["sectors"] = nsectors;
2364
2365 if (!log->device_error_count) {
2366 jout("No Errors Logged\n\n");
2367 jref["count"] = 0;
2368 return 0;
2369 }
2370 print_on();
2371
2372 // Check index
2373 unsigned nentries = nsectors * 4;
2374 unsigned erridx = log->error_log_index;
2375 if (!(1 <= erridx && erridx <= nentries)){
2376 // Some Samsung disks (at least SP1614C/SW100-25, HD300LJ/ZT100-12) use the
2377 // former index from Summary Error Log (byte 1, now reserved) and set byte 2-3
2378 // to 0.
2379 if (!(erridx == 0 && 1 <= log->reserved1 && log->reserved1 <= nentries)) {
2380 pout("Invalid Error Log index = 0x%04x (reserved = 0x%02x)\n", erridx, log->reserved1);
2381 pout("Device Error Count: %d (possibly also invalid)\n\n", log->device_error_count);
2382 return 0;
2383 }
2384 pout("Invalid Error Log index = 0x%04x, trying reserved byte (0x%02x) instead\n", erridx, log->reserved1);
2385 erridx = log->reserved1;
2386 }
2387
2388 // Index base is not clearly specified by ATA8-ACS (T13/1699-D Revision 6a),
2389 // it is 1-based in practice.
2390 erridx--;
2391
2392 // Calculate #errors to print
2393 unsigned errcnt = log->device_error_count;
2394
2395 if (errcnt <= nentries)
2396 jout("Device Error Count: %u\n", log->device_error_count);
2397 else {
2398 errcnt = nentries;
2399 jout("Device Error Count: %u (device log contains only the most recent %u errors)\n",
2400 log->device_error_count, errcnt);
2401 }
2402 jref["count"] = log->device_error_count;
2403 jref["logged_count"] = errcnt;
2404
2405 if (max_errors < errcnt)
2406 errcnt = max_errors;
2407
2408 print_off();
2409 jout("\tCR = Command Register\n"
2410 "\tFEATR = Features Register\n"
2411 "\tCOUNT = Count (was: Sector Count) Register\n"
2412 "\tLBA_48 = Upper bytes of LBA High/Mid/Low Registers ] ATA-8\n"
2413 "\tLH = LBA High (was: Cylinder High) Register ] LBA\n"
2414 "\tLM = LBA Mid (was: Cylinder Low) Register ] Register\n"
2415 "\tLL = LBA Low (was: Sector Number) Register ]\n"
2416 "\tDV = Device (was: Device/Head) Register\n"
2417 "\tDC = Device Control Register\n"
2418 "\tER = Error register\n"
2419 "\tST = Status register\n"
2420 "Powered_Up_Time is measured from power on, and printed as\n"
2421 "DDd+hh:mm:SS.sss where DD=days, hh=hours, mm=minutes,\n"
2422 "SS=sec, and sss=millisec. It \"wraps\" after 49.710 days.\n\n");
2423
2424 // Recently read log page
2425 ata_smart_exterrlog log_buf;
2426 unsigned log_buf_page = ~0;
2427
2428 // Iterate through circular buffer in reverse direction
2429 for (unsigned i = 0, errnum = log->device_error_count;
2430 i < errcnt; i++, errnum--, erridx = (erridx > 0 ? erridx - 1 : nentries - 1)) {
2431
2432 // Read log page if needed
2433 const ata_smart_exterrlog * log_p;
2434 unsigned page = erridx / 4;
2435 if (page == 0)
2436 log_p = log;
2437 else {
2438 if (page != log_buf_page) {
2439 memset(&log_buf, 0, sizeof(log_buf));
2440 if (!ataReadExtErrorLog(device, &log_buf, page, 1, firmwarebugs))
2441 break;
2442 log_buf_page = page;
2443 }
2444 log_p = &log_buf;
2445 }
2446
2447 const ata_smart_exterrlog_error_log & entry = log_p->error_logs[erridx % 4];
2448
2449 json::ref jrefi = jref["table"][i];
2450 jrefi["error_number"] = errnum;
2451 jrefi["log_index"] = erridx;
2452
2453 // Skip unused entries
2454 if (!nonempty(&entry, sizeof(entry))) {
2455 jout("Error %u [%u] log entry is empty\n", errnum, erridx);
2456 continue;
2457 }
2458
2459 // Print error information
2460 print_on();
2461 const ata_smart_exterrlog_error & err = entry.error;
2462 jout("Error %u [%u] occurred at disk power-on lifetime: %u hours (%u days + %u hours)\n",
2463 errnum, erridx, err.timestamp, err.timestamp / 24, err.timestamp % 24);
2464 print_off();
2465 jrefi["lifetime_hours"] = err.timestamp;
2466
2467 const char * msgstate = get_error_log_state_desc(err.state);
2468 jout(" When the command that caused the error occurred, the device was %s.\n\n", msgstate);
2469 jrefi["device_state"]["value"] = err.state;
2470 jrefi["device_state"]["string"] = msgstate;
2471
2472 // Print registers
2473 jout(" After command completion occurred, registers were:\n"
2474 " ER -- ST COUNT LBA_48 LH LM LL DV DC\n"
2475 " -- -- -- == -- == == == -- -- -- -- --\n"
2476 " %02x -- %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x",
2477 err.error_register,
2478 err.status_register,
2480 err.count_register,
2485 err.lba_mid_register,
2486 err.lba_low_register,
2487 err.device_register,
2489
2490 {
2491 json::ref jrefir = jrefi["completion_registers"];
2492 jrefir["error"] = err.error_register;
2493 jrefir["status"] = err.status_register,
2494 jrefir["count"] = (err.count_register_hi << 8) | err.count_register;
2495 jrefir["lba"] = ((uint64_t)err.lba_high_register_hi << 40)
2496 | ((uint64_t)err.lba_mid_register_hi << 32)
2497 | ((uint64_t)err.lba_low_register_hi << 24)
2498 | ((unsigned)err.lba_high_register << 16)
2499 | ((unsigned)err.lba_mid_register << 8)
2500 | ((unsigned)err.lba_low_register );
2501 jrefir["device"] = err.device_register;
2502 jrefir["device_control"] = err.device_control_register;
2503 }
2504
2505 // Add a description of the contents of the status and error registers
2506 // if possible
2507 std::string st_er_desc = format_st_er_desc(&entry);
2508 if (!st_er_desc.empty()) {
2509 jout(" %s", st_er_desc.c_str());
2510 jrefi["error_description"] = st_er_desc;
2511 }
2512 jout("\n\n");
2513
2514 // Print command history
2515 jout(" Commands leading to the command that caused the error were:\n"
2516 " CR FEATR COUNT LBA_48 LH LM LL DV DC Powered_Up_Time Command/Feature_Name\n"
2517 " -- == -- == -- == == == -- -- -- -- -- --------------- --------------------\n");
2518 for (int ci = 4, cji = 0; ci >= 0; ci--) {
2519 const ata_smart_exterrlog_command & cmd = entry.commands[ci];
2520
2521 // Skip unused entries
2522 if (!nonempty(&cmd, sizeof(cmd)))
2523 continue;
2524
2525 // Print registers, timestamp and ATA command name
2526 const char * atacmd = look_up_ata_command(cmd.command_register, cmd.features_register);
2527 jout(" %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %16s %s\n",
2528 cmd.command_register,
2529 cmd.features_register_hi,
2530 cmd.features_register,
2531 cmd.count_register_hi,
2532 cmd.count_register,
2533 cmd.lba_high_register_hi,
2534 cmd.lba_mid_register_hi,
2535 cmd.lba_low_register_hi,
2536 cmd.lba_high_register,
2537 cmd.lba_mid_register,
2538 cmd.lba_low_register,
2539 cmd.device_register,
2540 cmd.device_control_register,
2541 format_milliseconds(cmd.timestamp).c_str(),
2542 atacmd);
2543
2544 json::ref jrefic = jrefi["previous_commands"][cji++];
2545 json::ref jreficr = jrefic["registers"];
2546 jreficr["command"] = cmd.command_register;
2547 jreficr["features"] = (cmd.features_register_hi << 8) | cmd.features_register;
2548 jreficr["count"] = (cmd.count_register_hi << 8) | cmd.count_register;
2549 jreficr["lba"] = ((uint64_t)cmd.lba_high_register_hi << 40)
2550 | ((uint64_t)cmd.lba_mid_register_hi << 32)
2551 | ((uint64_t)cmd.lba_low_register_hi << 24)
2552 | ((unsigned)cmd.lba_high_register << 16)
2553 | ((unsigned)cmd.lba_mid_register << 8)
2554 | ((unsigned)cmd.lba_low_register );
2555 jreficr["device"] = cmd.device_register;
2556 jreficr["device_control"] = cmd.device_control_register;
2557 jrefic["powerup_milliseconds"] = cmd.timestamp;
2558 jrefic["command_name"] = atacmd;
2559 }
2560 jout("\n");
2561 }
2562
2563 print_on();
2565 pout("\n");
2566 print_off();
2567 return log->device_error_count;
2568}
2569
2570// Print one self-test log entry.
2571// Returns:
2572// -1: self-test failed
2573// 1: extended self-test completed without error
2574// 0: otherwise
2576 unsigned testnum, unsigned char test_type,
2577 unsigned char test_status,
2578 unsigned short timestamp,
2579 uint64_t failing_lba,
2580 bool print_error_only, bool & print_header)
2581{
2582 // Check status and type for return value
2583 int retval = 0;
2584 switch (test_status >> 4) {
2585 case 0x0:
2586 if ((test_type & 0x7f) == 0x02)
2587 retval = 1; // extended self-test completed without error
2588 break;
2589 case 0x3: case 0x4:
2590 case 0x5: case 0x6:
2591 case 0x7: case 0x8:
2592 retval = -1; // self-test failed
2593 break;
2594 }
2595
2596 if (retval >= 0 && print_error_only)
2597 return retval;
2598
2599 std::string msgtest;
2600 switch (test_type) {
2601 case 0x00: msgtest = "Offline"; break;
2602 case 0x01: msgtest = "Short offline"; break;
2603 case 0x02: msgtest = "Extended offline"; break;
2604 case 0x03: msgtest = "Conveyance offline"; break;
2605 case 0x04: msgtest = "Selective offline"; break;
2606 case 0x7f: msgtest = "Abort offline test"; break;
2607 case 0x81: msgtest = "Short captive"; break;
2608 case 0x82: msgtest = "Extended captive"; break;
2609 case 0x83: msgtest = "Conveyance captive"; break;
2610 case 0x84: msgtest = "Selective captive"; break;
2611 default:
2612 if ((0x40 <= test_type && test_type <= 0x7e) || 0x90 <= test_type)
2613 msgtest = strprintf("Vendor (0x%02x)", test_type);
2614 else
2615 msgtest = strprintf("Reserved (0x%02x)", test_type);
2616 }
2617
2618 std::string msgstat;
2619 switch (test_status >> 4) {
2620 case 0x0: msgstat = "Completed without error"; break;
2621 case 0x1: msgstat = "Aborted by host"; break;
2622 case 0x2: msgstat = "Interrupted (host reset)"; break;
2623 case 0x3: msgstat = "Fatal or unknown error"; break;
2624 case 0x4: msgstat = "Completed: unknown failure"; break;
2625 case 0x5: msgstat = "Completed: electrical failure"; break;
2626 case 0x6: msgstat = "Completed: servo/seek failure"; break;
2627 case 0x7: msgstat = "Completed: read failure"; break;
2628 case 0x8: msgstat = "Completed: handling damage??"; break;
2629 case 0xf: msgstat = "Self-test routine in progress"; break;
2630 default: msgstat = strprintf("Unknown status (0x%x)", test_status >> 4);
2631 }
2632
2633 // Print header once
2634 if (print_header) {
2635 print_header = false;
2636 jout("Num Test_Description Status Remaining LifeTime(hours) LBA_of_first_error\n");
2637 }
2638
2639 char msglba[32];
2640 if (retval < 0 && failing_lba < 0xffffffffffffULL)
2641 snprintf(msglba, sizeof(msglba), "%" PRIu64, failing_lba);
2642 else {
2643 msglba[0] = '-'; msglba[1] = 0;
2644 }
2645
2646 jout("#%2u %-19s %-29s %1d0%% %8u %s\n", testnum,
2647 msgtest.c_str(), msgstat.c_str(), test_status & 0x0f, timestamp, msglba);
2648
2649 jref["type"]["value"] = test_type;
2650 jref["type"]["string"] = msgtest;
2651
2652 jref["status"]["value"] = test_status;
2653 jref["status"]["string"] = msgstat;
2654 if (test_status & 0x0f)
2655 jref["status"]["remaining_percent"] = (test_status & 0x0f) * 10;
2656 switch (test_status >> 4) {
2657 case 0x1: case 0x2: case 0x3: break; // aborted -> unknown
2658 default: jref["status"]["passed"] = (retval >= 0);
2659 }
2660
2661 jref["lifetime_hours"] = timestamp;
2662
2663 if (retval < 0 && failing_lba < 0xffffffffffffULL)
2664 jref["lba"] = failing_lba;
2665
2666 return retval;
2667}
2668
2669// Print SMART Self-test log, return error count
2670static int ataPrintSmartSelfTestlog(const ata_smart_selftestlog * log, bool allentries,
2671 firmwarebug_defs firmwarebugs)
2672{
2673 json::ref jref = jglb["ata_smart_self_test_log"]["standard"];
2674
2675 if (allentries)
2676 jout("SMART Self-test log structure revision number %d\n", log->revnumber);
2677 jref["revision"] = log->revnumber;
2678 if (log->revnumber != 0x0001 && allentries && !firmwarebugs.is_set(BUG_SAMSUNG))
2679 pout("Warning: ATA Specification requires self-test log structure revision number = 1\n");
2680 if (!log->mostrecenttest){
2681 if (allentries)
2682 jout("No self-tests have been logged. [To run self-tests, use: smartctl -t]\n");
2683 jref["count"] = 0;
2684 return 0;
2685 }
2686
2687 bool noheaderprinted = true;
2688 int errcnt = 0, igncnt = 0;
2689 int testnum = 1, ext_ok_testnum = -1;
2690
2691 // Iterate through circular buffer in reverse direction
2692 for (int i = 20, ji = 0; i >= 0; i--) {
2693 int j = (i + log->mostrecenttest) % 21;
2695
2696 // Skip unused entries
2697 if (!nonempty(&entry, sizeof(entry)))
2698 continue;
2699
2700 // Get LBA if valid
2701 uint64_t lba48 = (entry.lbafirstfailure < 0xffffffff ?
2702 entry.lbafirstfailure : 0xffffffffffffULL);
2703
2704 // Print entry
2705 int state = ataPrintSmartSelfTestEntry(jref["table"][ji++],
2706 testnum, entry.selftestnumber, entry.selfteststatus,
2707 entry.timestamp, lba48, !allentries, noheaderprinted);
2708
2709 if (state < 0) {
2710 // Self-test showed an error
2711 if (ext_ok_testnum < 0)
2712 errcnt++;
2713 else
2714 // Newer successful extended self-test exits
2715 igncnt++;
2716 }
2717 else if (state > 0 && ext_ok_testnum < 0) {
2718 // Latest successful extended self-test
2719 ext_ok_testnum = testnum;
2720 }
2721 testnum++;
2722 }
2723
2724 if (igncnt)
2725 jout("%d of %d failed self-tests are outdated by newer successful extended offline self-test #%2d\n",
2726 igncnt, igncnt+errcnt, ext_ok_testnum);
2727 jref["count"] = testnum - 1;
2728 jref["error_count_total"] = igncnt + errcnt;
2729 jref["error_count_outdated"] = igncnt;
2730
2731 if (!allentries && !noheaderprinted)
2732 jout("\n");
2733
2734 return errcnt;
2735}
2736
2737// Print SMART Extended Self-test Log (GP Log 0x07)
2739 unsigned nsectors, unsigned max_entries)
2740{
2741 json::ref jref = jglb["ata_smart_self_test_log"]["extended"];
2742
2743 jout("SMART Extended Self-test Log Version: %u (%u sectors)\n",
2744 log->version, nsectors);
2745 jref["revision"] = log->version;
2746 jref["sectors"] = nsectors;
2747
2748 if (!log->log_desc_index){
2749 jout("No self-tests have been logged. [To run self-tests, use: smartctl -t]\n\n");
2750 jref["count"] = 0;
2751 return 0;
2752 }
2753
2754 // Check index
2755 unsigned nentries = nsectors * 19;
2756 unsigned logidx = log->log_desc_index;
2757 if (logidx > nentries) {
2758 pout("Invalid Self-test Log index = 0x%04x (reserved = 0x%02x)\n", logidx, log->reserved1);
2759 return 0;
2760 }
2761
2762 // Index base is not clearly specified by ATA8-ACS (T13/1699-D Revision 6a),
2763 // it is 1-based in practice.
2764 logidx--;
2765
2766 bool print_header = true;
2767 int errcnt = 0, igncnt = 0;
2768 int ext_ok_testnum = -1;
2769 unsigned testnum = 1;
2770
2771 // Iterate through circular buffer in reverse direction
2772 for (unsigned i = 0, ji = 0; i < nentries && testnum <= max_entries;
2773 i++, logidx = (logidx > 0 ? logidx - 1 : nentries - 1)) {
2774
2775 const ata_smart_extselftestlog_desc & entry = log[logidx / 19].log_descs[logidx % 19];
2776
2777 // Skip unused entries
2778 if (!nonempty(&entry, sizeof(entry)))
2779 continue;
2780
2781 // Get LBA
2782 const unsigned char * b = entry.failing_lba;
2783 uint64_t lba48 = b[0]
2784 | ( b[1] << 8)
2785 | ( b[2] << 16)
2786 | ((uint64_t)b[3] << 24)
2787 | ((uint64_t)b[4] << 32)
2788 | ((uint64_t)b[5] << 40);
2789
2790 // Print entry
2791 int state = ataPrintSmartSelfTestEntry(jref["table"][ji++],
2792 testnum, entry.self_test_type,
2793 entry.self_test_status, entry.timestamp, lba48,
2794 false /*!print_error_only*/, print_header);
2795
2796 if (state < 0) {
2797 // Self-test showed an error
2798 if (ext_ok_testnum < 0)
2799 errcnt++;
2800 else
2801 // Newer successful extended self-test exits
2802 igncnt++;
2803 }
2804 else if (state > 0 && ext_ok_testnum < 0) {
2805 // Latest successful extended self-test
2806 ext_ok_testnum = testnum;
2807 }
2808 testnum++;
2809 }
2810
2811 if (igncnt)
2812 jout("%d of %d failed self-tests are outdated by newer successful extended offline self-test #%2d\n",
2813 igncnt, igncnt+errcnt, ext_ok_testnum);
2814 jref["count"] = testnum - 1;
2815 jref["error_count_total"] = igncnt + errcnt;
2816 jref["error_count_outdated"] = igncnt;
2817
2818 jout("\n");
2819 return errcnt;
2820}
2821
2823{
2824 json::ref jref = jglb["ata_smart_selective_self_test_log"];
2825
2826 // print data structure revision number
2827 jout("SMART Selective self-test log data structure revision number %d\n", log->logversion);
2828 jref["revision"] = log->logversion;
2829 if (1 != log->logversion)
2830 pout("Note: revision number not 1 implies that no selective self-test has ever been run\n");
2831
2832 const char *msg;
2833 switch((sv->self_test_exec_status)>>4){
2834 case 0:msg="Completed";
2835 break;
2836 case 1:msg="Aborted_by_host";
2837 break;
2838 case 2:msg="Interrupted";
2839 break;
2840 case 3:msg="Fatal_error";
2841 break;
2842 case 4:msg="Completed_unknown_failure";
2843 break;
2844 case 5:msg="Completed_electrical_failure";
2845 break;
2846 case 6:msg="Completed_servo/seek_failure";
2847 break;
2848 case 7:msg="Completed_read_failure";
2849 break;
2850 case 8:msg="Completed_handling_damage??";
2851 break;
2852 case 15:msg="Self_test_in_progress";
2853 break;
2854 default:msg="Unknown_status ";
2855 break;
2856 }
2857
2858 // find the number of columns needed for printing. If in use, the
2859 // start/end of span being read-scanned...
2860 uint64_t maxl = 0, maxr = 0;
2861 uint64_t current = log->currentlba;
2862 uint64_t currentend = current + 0xffff;
2863 if (log->currentspan>5) {
2864 maxl=current;
2865 maxr=currentend;
2866 }
2867 for (int i = 0; i < 5; i++) {
2868 uint64_t start=log->span[i].start;
2869 uint64_t end =log->span[i].end;
2870 // ... plus max start/end of each of the five test spans.
2871 if (start>maxl)
2872 maxl=start;
2873 if (end > maxr)
2874 maxr=end;
2875 }
2876
2877 // we need at least 7 characters wide fields to accommodate the
2878 // labels
2879 int field1,field2;
2880 char tmp[64];
2881 if ((field1=snprintf(tmp,64, "%" PRIu64, maxl))<7)
2882 field1=7;
2883 if ((field2=snprintf(tmp,64, "%" PRIu64, maxr))<7)
2884 field2=7;
2885
2886 // now print the five test spans
2887 jout(" SPAN %*s %*s CURRENT_TEST_STATUS\n", field1, "MIN_LBA", field2, "MAX_LBA");
2888
2889 for (int i = 0; i < 5; i++) {
2890 uint64_t start=log->span[i].start;
2891 uint64_t end=log->span[i].end;
2892 bool active = (i + 1 == log->currentspan);
2893
2894 if (active)
2895 // this span is currently under test
2896 jout(" %d %*" PRIu64 " %*" PRIu64 " %s [%01d0%% left] (%" PRIu64 "-%" PRIu64 ")\n",
2897 i + 1, field1, start, field2, end, msg,
2898 (sv->self_test_exec_status & 0xf), current, currentend);
2899 else
2900 // this span is not currently under test
2901 jout(" %d %*" PRIu64 " %*" PRIu64 " Not_testing\n",
2902 i + 1, field1, start, field2, end);
2903
2904 json::ref jrefi = jref["table"][i];
2905 jrefi["lba_min"] = start;
2906 jrefi["lba_max"] = end;
2907 jrefi["status"]["value"] = sv->self_test_exec_status;
2908 jrefi["status"]["string"] = (active ? msg : "Not_testing");
2909 if (active) {
2910 jrefi["status"]["remaining_percent"] = sv->self_test_exec_status & 0xf;
2911 jrefi["current_lba_min"] = current;
2912 jrefi["current_lba_max"] = currentend;
2913 }
2914 }
2915
2916 // if we are currently read-scanning, print LBAs and the status of
2917 // the read scan
2918 if (log->currentspan > 5) {
2920 jout("%5d %*" PRIu64 " %*" PRIu64 " Read_scanning %s\n",
2921 log->currentspan, field1, current, field2, currentend, ost);
2922 json::ref jrefc = jref["current_read_scan"];
2923 jrefc["lba_min"] = current;
2924 jrefc["lba_max"] = currentend;
2925 jrefc["status"]["value"] = sv->offline_data_collection_status;
2926 jrefc["status"]["string"] = ost;
2927 }
2928
2929 /* Print selective self-test flags. Possible flag combinations are
2930 (numbering bits from 0-15):
2931 Bit-1 Bit-3 Bit-4
2932 Scan Pending Active
2933 0 * * Don't scan
2934 1 0 0 Will carry out scan after selective test
2935 1 1 0 Waiting to carry out scan after powerup
2936 1 0 1 Currently scanning
2937 1 1 1 Currently scanning
2938 */
2939
2940 jout("Selective self-test flags (0x%x):\n", (unsigned)log->flags);
2941 json::ref jreff = jref["flags"];
2942 jreff["value"] = log->flags;
2943 jreff["remainder_scan_enabled"] = !!(log->flags & SELECTIVE_FLAG_DOSCAN);
2944 if (log->flags & SELECTIVE_FLAG_DOSCAN) {
2945 if (log->flags & SELECTIVE_FLAG_ACTIVE)
2946 jout(" Currently read-scanning the remainder of the disk.\n");
2947 else if (log->flags & SELECTIVE_FLAG_PENDING)
2948 jout(" Read-scan of remainder of disk interrupted; will resume %d min after power-up.\n",
2949 log->pendingtime);
2950 else
2951 jout(" After scanning selected spans, read-scan remainder of disk.\n");
2952 jreff["remainder_scan_active"] = !!(log->flags & SELECTIVE_FLAG_ACTIVE);
2953 jreff["power_up_scan_pending"] = !!(log->flags & SELECTIVE_FLAG_PENDING);
2954 }
2955 else
2956 jout(" After scanning selected spans, do NOT read-scan remainder of disk.\n");
2957
2958 // print pending time
2959 jout("If Selective self-test is pending on power-up, resume after %d minute delay.\n",
2960 log->pendingtime);
2961 jref["power_up_scan_resume_minutes"] = log->pendingtime;
2962}
2963
2964// Format SCT Temperature value
2965static const char * sct_ptemp(signed char x, char (& buf)[20])
2966{
2967 if (x == -128 /*0x80 = unknown*/)
2968 return " ?";
2969 snprintf(buf, sizeof(buf), "%2d", x);
2970 return buf;
2971}
2972
2973static void sct_jtemp2(const json::ref & jref, const char * name, signed char x)
2974{
2975 if (x == -128 /*0x80 = unknown*/)
2976 return;
2977 jglb["temperature"][name] = x;
2978 jref["temperature"][name] = x;
2979}
2980
2981static const char * sct_pbar(int x, char (& buf)[64])
2982{
2983 if (x <= 19)
2984 x = 0;
2985 else
2986 x -= 19;
2987 bool ov = false;
2988 if (x > 40) {
2989 x = 40; ov = true;
2990 }
2991 if (x > 0) {
2992 memset(buf, '*', x);
2993 if (ov)
2994 buf[x-1] = '+';
2995 buf[x] = 0;
2996 }
2997 else {
2998 buf[0] = '-'; buf[1] = 0;
2999 }
3000 return buf;
3001}
3002
3003static const char * sct_device_state_msg(unsigned char state)
3004{
3005 switch (state) {
3006 case 0: return "Active";
3007 case 1: return "Stand-by";
3008 case 2: return "Sleep";
3009 case 3: return "DST executing in background";
3010 case 4: return "SMART Off-line Data Collection executing in background";
3011 case 5: return "SCT command executing in background";
3012 default:return "Unknown";
3013 }
3014}
3015
3016// Print SCT Status
3018{
3019 json::ref jref = jglb["ata_sct_status"];
3020
3021 jout("SCT Status Version: %u\n", sts->format_version);
3022 jref["format_version"] = sts->format_version;
3023 jout("SCT Version (vendor specific): %u (0x%04x)\n", sts->sct_version, sts->sct_version);
3024 jref["sct_version"] = sts->sct_version;
3025 // SCT Support Level (1) from original SCT draft was later declared obsolete in ATA-8 ACS.
3026 // Drives typically return 0 or 1. Print only if unknown value is returned.
3027 if (sts->sct_spec > 1)
3028 pout("SCT Support Level: %u\n", sts->sct_spec);
3029 const char * statestr = sct_device_state_msg(sts->device_state);
3030 jout("Device State: %s (%u)\n", statestr, sts->device_state);
3031 jref["device_state"]["value"] = sts->device_state;
3032 jref["device_state"]["string"] = statestr;
3033
3034 // If "Reserved" fields not set, assume "old" format version 2:
3035 // Table 11 of T13/1701DT-N (SMART Command Transport) Revision 5, February 2005
3036 // Table 54 of T13/1699-D (ATA8-ACS) Revision 3e, July 2006
3037 // ... else assume "new" format version 2 or version 3:
3038 // T13/e06152r0-3 (Additional SCT Temperature Statistics), August - October 2006
3039 // Table 60 of T13/1699-D (ATA8-ACS) Revision 3f, December 2006 (format version 2)
3040 // Table 80 of T13/1699-D (ATA8-ACS) Revision 6a, September 2008 (format version 3)
3041 // Table 194 of T13/BSR INCITS 529 (ACS-4) Revision 20, October 26, 2017
3042 // (max_op_limit, smart_status, min_erc_time)
3043 bool old_format_2 = ( !sts->min_temp && !sts->life_min_temp
3044 && !sts->under_limit_count && !sts->over_limit_count);
3045
3046 char buf1[20], buf2[20];
3047 jout("Current Temperature: %s Celsius\n",
3048 sct_ptemp(sts->hda_temp, buf1));
3049 sct_jtemp2(jref, "current", sts->hda_temp);
3050 jout("Power Cycle Min/Max Temperature: %s/%s Celsius\n",
3051 (!old_format_2 ? sct_ptemp(sts->min_temp, buf1) : "--"),
3052 sct_ptemp(sts->max_temp, buf2));
3053 if (!old_format_2)
3054 sct_jtemp2(jref, "power_cycle_min", sts->min_temp);
3055 sct_jtemp2(jref, "power_cycle_max", sts->max_temp);
3056 jout("Lifetime Min/Max Temperature: %s/%s Celsius\n",
3057 (!old_format_2 ? sct_ptemp(sts->life_min_temp, buf1) : "--"),
3058 sct_ptemp(sts->life_max_temp, buf2));
3059 if (!old_format_2)
3060 sct_jtemp2(jref, "lifetime_min", sts->life_min_temp);
3061 sct_jtemp2(jref, "lifetime_max", sts->life_max_temp);
3062 if (old_format_2)
3063 return 0;
3064
3065 if (sts->max_op_limit > 0) { // e06152r0-2: "Average Temperature"
3066 jout("Specified Max Operating Temperature: %3d Celsius\n", sts->max_op_limit);
3067 sct_jtemp2(jref, "op_limit_max", sts->max_op_limit);
3068 }
3069 jout("Under/Over Temperature Limit Count: %2u/%u\n",
3071 jref["temperature"]["under_limit_count"] = sts->under_limit_count;
3072 jref["temperature"]["over_limit_count"] = sts->over_limit_count;
3073
3074 if (sts->smart_status) { // ACS-4
3075 int passed = (sts->smart_status == 0x2cf4 ? 0 :
3076 sts->smart_status == 0xc24f ? 1 : -1);
3077 jout("SMART Status: 0x%04x (%s)\n", sts->smart_status,
3078 (passed == 0 ? "FAILED" : passed > 0 ? "PASSED" : "Reserved"));
3079 if (passed >= 0) {
3080 jref["smart_status"]["passed"] = !!passed;
3081 jglb["smart_status"]["passed"] = !!passed;
3082 }
3083 else
3084 jref["smart_status"]["reserved_value"] = sts->smart_status;
3085 }
3086
3087 if (sts->min_erc_time) // ACS-4
3088 pout("Minimum supported ERC Time Limit: %d (%0.1f seconds)\n",
3089 sts->min_erc_time, sts->min_erc_time/10.0);
3090
3091 if (nonempty(sts->vendor_specific, sizeof(sts->vendor_specific))) {
3092 jout("Vendor specific:\n");
3093 for (unsigned i = 0; i < sizeof(sts->vendor_specific); i++) {
3094 jout("%02x%c", sts->vendor_specific[i], ((i & 0xf) != 0xf ? ' ' : '\n'));
3095 jref["vendor_specific"][i] = sts->vendor_specific[i];
3096 }
3097 }
3098 return 0;
3099}
3100
3101// Print SCT Temperature History Table
3103{
3104 json::ref jref = jglb["ata_sct_temperature_history"];
3105
3106 char buf1[20], buf2[20], buf3[64];
3107 jout("SCT Temperature History Version: %u%s\n", tmh->format_version,
3108 (tmh->format_version != 2 ? " (Unknown, should be 2)" : ""));
3109 jref["version"] = tmh->format_version;
3110 jout("Temperature Sampling Period: %u minute%s\n",
3111 tmh->sampling_period, (tmh->sampling_period==1?"":"s"));
3112 jref["sampling_period_minutes"] = tmh->sampling_period;
3113 jout("Temperature Logging Interval: %u minute%s\n",
3114 tmh->interval, (tmh->interval==1?"":"s"));
3115 jref["logging_interval_minutes"] = tmh->interval;
3116
3117 jout("Min/Max recommended Temperature: %s/%s Celsius\n",
3118 sct_ptemp(tmh->min_op_limit, buf1), sct_ptemp(tmh->max_op_limit, buf2));
3119 sct_jtemp2(jref, "op_limit_min", tmh->min_op_limit);
3120 sct_jtemp2(jref, "op_limit_max", tmh->max_op_limit);
3121 jout("Min/Max Temperature Limit: %s/%s Celsius\n",
3122 sct_ptemp(tmh->under_limit, buf1), sct_ptemp(tmh->over_limit, buf2));
3123 sct_jtemp2(jref, "limit_min", tmh->under_limit);
3124 sct_jtemp2(jref, "limit_max", tmh->over_limit);
3125 jout("Temperature History Size (Index): %u (%u)\n", tmh->cb_size, tmh->cb_index);
3126 jref["size"] = tmh->cb_size;
3127 jref["index"] = tmh->cb_index;
3128
3129 if (!(0 < tmh->cb_size && tmh->cb_size <= sizeof(tmh->cb) && tmh->cb_index < tmh->cb_size)) {
3130 if (!tmh->cb_size)
3131 pout("Temperature History is empty\n");
3132 else
3133 pout("Invalid Temperature History Size or Index\n");
3134 return 0;
3135 }
3136
3137 // Print table
3138 jout("\nIndex Estimated Time Temperature Celsius\n");
3139 unsigned n = 0, i = (tmh->cb_index+1) % tmh->cb_size;
3140 unsigned interval = (tmh->interval > 0 ? tmh->interval : 1);
3141 time_t t = time(0) - (time_t)(tmh->cb_size-1) * interval * 60;
3142 t -= t % (interval * 60);
3143 while (n < tmh->cb_size) {
3144 // Find range of identical temperatures
3145 unsigned n1 = n, n2 = n+1, i2 = (i+1) % tmh->cb_size;
3146 while (n2 < tmh->cb_size && tmh->cb[i2] == tmh->cb[i]) {
3147 n2++; i2 = (i2+1) % tmh->cb_size;
3148 }
3149 // Print range
3150 while (n < n2) {
3151 if (n == n1 || n == n2-1 || n2 <= n1+3) {
3152 // TODO: Don't print times < boot time
3153 char date[32] = "";
3154 struct tm tmbuf;
3155 strftime(date, sizeof(date), "%Y-%m-%d %H:%M", time_to_tm_local(&tmbuf, t));
3156 jout(" %3u %s %s %s\n", i, date,
3157 sct_ptemp(tmh->cb[i], buf1), sct_pbar(tmh->cb[i], buf3));
3158 }
3159 else if (n == n1+1) {
3160 jout(" ... ..(%3u skipped). .. %s\n",
3161 n2-n1-2, sct_pbar(tmh->cb[i], buf3));
3162 }
3163 if (tmh->cb[i] != -128)
3164 jref["table"][n] = tmh->cb[i];
3165 t += interval * 60; i = (i+1) % tmh->cb_size; n++;
3166 }
3167 }
3168 //assert(n == tmh->cb_size && i == (tmh->cb_index+1) % tmh->cb_size);
3169
3170 return 0;
3171}
3172
3173// Print SCT Error Recovery Control timers
3174static void ataPrintSCTErrorRecoveryControl(bool set, unsigned short read_timer, unsigned short write_timer, bool power_on, bool mfg_default = false)
3175{
3176 const char* power_on_str = (power_on ? "Power-on " : "");
3177 json::ref jref = jglb["ata_sct_erc"];
3178 jout("SCT Error Recovery Control%s:%s\n", (set ? " set to" : ""), (mfg_default ? " default values." : ""));
3179
3180 if (!mfg_default) {
3181 jref["read"]["enabled"] = !!read_timer;
3182 if (!read_timer)
3183 jout(" %sRead: Disabled\n", power_on_str);
3184 else {
3185 jout(" %sRead: %6d (%0.1f seconds)\n", power_on_str, read_timer, read_timer/10.0);
3186 jref["read"]["deciseconds"] = read_timer;
3187 }
3188
3189 jref["write"]["enabled"] = !!write_timer;
3190 if (!write_timer)
3191 jout(" %sWrite: Disabled\n", power_on_str);
3192 else {
3193 jout(" %sWrite: %6d (%0.1f seconds)\n", power_on_str, write_timer, write_timer/10.0);
3194 jref["write"]["deciseconds"] = write_timer;
3195 }
3196 }
3197}
3198
3199static void print_aam_level(const char * msg, int level, int recommended = -1)
3200{
3201 // Table 56 of T13/1699-D (ATA8-ACS) Revision 6a, September 6, 2008
3202 // Obsolete since T13/2015-D (ACS-2) Revision 4a, December 9, 2010
3203 const char * s;
3204 if (level == 0)
3205 s = "vendor specific";
3206 else if (level < 128)
3207 s = "unknown/retired";
3208 else if (level == 128)
3209 s = "quiet";
3210 else if (level < 254)
3211 s = "intermediate";
3212 else if (level == 254)
3213 s = "maximum performance";
3214 else
3215 s = "reserved";
3216
3217 if (recommended >= 0)
3218 jout("%s%d (%s), recommended: %d\n", msg, level, s, recommended);
3219 else
3220 jout("%s%d (%s)\n", msg, level, s);
3221
3222 json::ref jref = jglb["ata_aam"];
3223 jref["enabled"] = true;
3224 jref["level"] = level;
3225 jref["string"] = s;
3226 if (recommended >= 0)
3227 jref["recommended_level"] = recommended;
3228}
3229
3230static void print_apm_level(const char * msg, int level)
3231{
3232 // Table 120 of T13/2015-D (ACS-2) Revision 7, June 22, 2011
3233 const char * s;
3234 if (!(1 <= level && level <= 254))
3235 s = "reserved";
3236 else if (level == 1)
3237 s = "minimum power consumption with standby";
3238 else if (level < 128)
3239 s = "intermediate level with standby";
3240 else if (level == 128)
3241 s = "minimum power consumption without standby";
3242 else if (level < 254)
3243 s = "intermediate level without standby";
3244 else
3245 s = "maximum performance";
3246
3247 jout("%s%d (%s)\n", msg, level, s);
3248
3249 json::ref jref = jglb["ata_apm"];
3250 jref["enabled"] = true;
3251 jref["level"] = level;
3252 jref["string"] = s;
3253 if (1 <= level && level <= 254) {
3254 jref["max_performance"] = (level == 254);
3255 jref["min_power"] = (level == 1 || level == 128);
3256 jref["with_standby"] = (level < 128);
3257 }
3258}
3259
3260static void print_ata_security_status(const char * msg, unsigned short state, unsigned short master_password_id)
3261{
3262 // Table 6 of T13/2015-D (ACS-2) Revision 7, June 22, 2011
3263 if (!(state & 0x0001)) {
3264 pout("%sUnavailable\n", msg);
3265 return;
3266 }
3267
3268 const char * s1, * s2 = "", * s3 = "", * s4 = "";
3269 bool enabled = false, locked = false;
3270 if (!(state & 0x0002)) {
3271 s1 = "Disabled, ";
3272 if (!(state & 0x0008))
3273 s2 = "NOT FROZEN [SEC1]";
3274 else
3275 s2 = "frozen [SEC2]";
3276 }
3277 else {
3278 enabled = true;
3279 s1 = "ENABLED, PW level ";
3280 if (!(state & 0x0100))
3281 s2 = "HIGH";
3282 else
3283 s2 = "MAX";
3284
3285 if (!(state & 0x0004)) {
3286 s3 = ", not locked, ";
3287 if (!(state & 0x0008))
3288 s4 = "not frozen [SEC5]";
3289 else
3290 s4 = "frozen [SEC6]";
3291 }
3292 else {
3293 locked = true;
3294 s3 = ", **LOCKED** [SEC4]";
3295 if (state & 0x0010)
3296 s4 = ", PW ATTEMPTS EXCEEDED";
3297 }
3298 }
3299
3300 // Print Master Password ID if set to non-default value
3301 // (0x0000, 0xffff: unsupported, 0xfffe: default)
3302 char s5[32] = "";
3303 if (0x0000 < master_password_id && master_password_id < 0xfffe)
3304 snprintf(s5, sizeof(s5), ", Master PW ID: 0x%04x", master_password_id);
3305
3306 jout("%s%s%s%s%s%s\n", msg, s1, s2, s3, s4, s5);
3307
3308 json::ref jref = jglb["ata_security"];
3309 jref["state"] = state;
3310 jref["string"] = strprintf("%s%s%s%s", s1, s2, s3, s4);
3311 jref["enabled"] = enabled;
3312 if (!enabled || !locked)
3313 jref["frozen"] = !!(state & 0x0008);
3314 if (enabled) {
3315 jref["pw_level_max"] = !!(state & 0x0100);
3316 jref["locked"] = locked;
3317 if (locked)
3318 jref["pw_attempts_exceeded"] = !!(state & 0x0010);
3319 }
3320 jref["master_password_id"] = master_password_id;
3321}
3322
3323static void print_standby_timer(const char * msg, int timer, const ata_identify_device & drive)
3324{
3325 const char * s1 = 0;
3326 int hours = 0, minutes = 0 , seconds = 0;
3327
3328 // Table 63 of T13/2015-D (ACS-2) Revision 7, June 22, 2011
3329 if (timer == 0)
3330 s1 = "disabled";
3331 else if (timer <= 240)
3332 seconds = timer * 5, minutes = seconds / 60, seconds %= 60;
3333 else if (timer <= 251)
3334 minutes = (timer - 240) * 30, hours = minutes / 60, minutes %= 60;
3335 else if (timer == 252)
3336 minutes = 21;
3337 else if (timer == 253)
3338 s1 = "between 8 hours and 12 hours";
3339 else if (timer == 255)
3340 minutes = 21, seconds = 15;
3341 else
3342 s1 = "reserved";
3343
3344 const char * s2 = "", * s3 = "";
3345 if (!(drive.words047_079[49-47] & 0x2000))
3346 s2 = " or vendor-specific";
3347 if (timer > 0 && (drive.words047_079[50-47] & 0xc001) == 0x4001)
3348 s3 = ", a vendor-specific minimum applies";
3349
3350 if (s1)
3351 pout("%s%d (%s%s%s)\n", msg, timer, s1, s2, s3);
3352 else
3353 pout("%s%d (%02d:%02d:%02d%s%s)\n", msg, timer, hours, minutes, seconds, s2, s3);
3354}
3355
3356
3357int ataPrintMain (ata_device * device, const ata_print_options & options)
3358{
3359 // If requested, check power mode first
3360 const char * powername = 0;
3361 bool powerchg = false;
3362 if (options.powermode) {
3363 unsigned char powerlimit = 0xff;
3364 int powermode = ataCheckPowerMode(device);
3365 // TODO: Move to new function used by smartctl and smartd.
3366 switch (powermode) {
3367 case -1:
3368 if (device->is_syscall_unsup()) {
3369 if (options.powerexit_unsup >= 0) {
3370 jinf("CHECK POWER MODE not implemented, exit(%d)\n", options.powerexit_unsup);
3371 return options.powerexit_unsup;
3372 }
3373 jinf("CHECK POWER MODE not implemented, ignoring -n option\n"); break;
3374 }
3375 powername = "SLEEP"; powerlimit = 2;
3376 break;
3377 // Table 215 of T13/2015-D (ACS-2) Revision 7, June 22, 2011
3378 // Table 293 of T13/BSR INCITS 529 (ACS-4) Revision 12, February 18, 2016
3379 case 0x00: // PM2:Standby, EPC unavailable or Standby_z power condition
3380 powername = "STANDBY"; powerlimit = 3; break;
3381 case 0x01: // PM2:Standby, Standby_y power condition
3382 powername = "STANDBY_Y"; powerlimit = 3; break;
3383 case 0x80: // PM1:Idle, EPC unavailable
3384 powername = "IDLE"; powerlimit = 4; break;
3385 case 0x81: // PM1:Idle, Idle_a power condition
3386 powername = "IDLE_A"; powerlimit = 4; break;
3387 case 0x82: // PM1:Idle, Idle_b power condition
3388 powername = "IDLE_B"; powerlimit = 4; break;
3389 case 0x83: // PM1:Idle, Idle_c power condition
3390 powername = "IDLE_C"; powerlimit = 4; break;
3391 // 0x40/41 were declared obsolete in ACS-3 Revision 1
3392 case 0x40: // PM0:Active, NV Cache power mode enabled, spun down
3393 powername = "ACTIVE_NV_DOWN"; break;
3394 case 0x41: // PM0:Active, NV Cache power mode enabled, spun up
3395 powername = "ACTIVE_NV_UP" ; break;
3396 case 0xff: // PM0:Active or PM1:Idle
3397 powername = "ACTIVE or IDLE"; break;
3398
3399 default:
3400 if (options.powerexit_unsup >= 0) {
3401 jinf("CHECK POWER MODE returned unknown value 0x%02x, exit(%d)\n", powermode,
3402 options.powerexit_unsup);
3403 return options.powerexit_unsup;
3404 }
3405 jinf("CHECK POWER MODE returned unknown value 0x%02x, ignoring -n option\n", powermode);
3406 break;
3407 }
3408 if (powername) {
3409 if (options.powermode >= powerlimit) {
3410 jinf("Device is in %s mode, exit(%d)\n", powername, options.powerexit);
3411 return options.powerexit;
3412 }
3413 powerchg = (powermode != 0xff); // SMART tests will spin up drives
3414 }
3415 }
3416
3417 // SMART values needed ?
3418 bool need_smart_val = (
3419 options.smart_check_status
3420 || options.smart_general_values
3421 || options.smart_vendor_attrib
3422 || options.smart_error_log
3423 || options.smart_selftest_log
3425 || options.smart_ext_error_log
3426 || options.smart_ext_selftest_log
3427 || options.smart_auto_offl_enable
3428 || options.smart_auto_offl_disable
3429 || options.smart_selftest_type != -1
3430 );
3431
3432 // SMART must be enabled ?
3433 bool need_smart_enabled = (
3434 need_smart_val
3435 || options.smart_auto_save_enable
3436 || options.smart_auto_save_disable
3437 );
3438
3439 // SMART feature set needed ?
3440 bool need_smart_support = (
3441 need_smart_enabled
3442 || options.smart_enable
3443 || options.smart_disable
3444 );
3445
3446 // SMART and GP log directories needed ?
3447 bool need_smart_logdir = (
3448 options.smart_logdir
3449 || options.devstat_all_pages // devstat fallback to smartlog if needed
3450 || options.devstat_ssd_page
3451 || !options.devstat_pages.empty()
3452 );
3453
3454 bool need_gp_logdir = (
3455 options.gp_logdir
3456 || options.smart_ext_error_log
3457 || options.smart_ext_selftest_log
3458 || options.devstat_all_pages
3459 || options.devstat_ssd_page
3460 || !options.devstat_pages.empty()
3461 || options.pending_defects_log
3462 || options.farm_log
3463 );
3464
3465 unsigned i;
3466 for (i = 0; i < options.log_requests.size(); i++) {
3467 if (options.log_requests[i].gpl)
3468 need_gp_logdir = true;
3469 else
3470 need_smart_logdir = true;
3471 }
3472
3473 // SCT commands needed ?
3474 bool need_sct_support = (
3475 options.sct_temp_sts
3476 || options.sct_temp_hist
3477 || options.sct_temp_int
3478 || options.sct_erc_get
3479 || options.sct_erc_set
3480 || options.sct_wcache_reorder_get
3481 || options.sct_wcache_reorder_set
3482 || options.sct_wcache_sct_get
3483 || options.sct_wcache_sct_set
3484 );
3485
3486 // Print any newer info not included in '-a' ?
3487 // Also used below to suppress suggestion of '-x'
3488 bool not_part_of_a_option = (
3489 need_smart_logdir
3490 || need_gp_logdir
3491 || need_sct_support
3492 || options.sataphy
3493 || options.farm_log
3494 || options.identify_word_level >= 0
3495 || options.get_set_used
3496 );
3497
3498 // Exit if no further options specified
3499 if (!( options.drive_info
3500 || options.show_presets
3501 || need_smart_support
3502 || not_part_of_a_option)) {
3503 if (powername)
3504 pout("Device is in %s mode\n", powername);
3505 else
3506 pout("ATA device successfully opened\n\n"
3507 "Use 'smartctl -a' (or '-x') to print SMART (and more) information\n\n");
3508 return 0;
3509 }
3510
3511 // Start by getting Drive ID information. We need this, to know if SMART is supported.
3512 int returnval = 0;
3513 ata_identify_device drive; memset(&drive, 0, sizeof(drive));
3514 unsigned char raw_drive[sizeof(drive)]; memset(&raw_drive, 0, sizeof(raw_drive));
3515
3516 device->clear_err();
3517 int retid = ata_read_identity(device, &drive, options.fix_swapped_id, raw_drive);
3518 if (retid < 0) {
3519 pout("Read Device Identity failed: %s\n\n",
3520 (device->get_errno() ? device->get_errmsg() : "Unknown error"));
3521 pout("If this is a USB connected device, look at the various "
3522 "--device=TYPE variants\n");
3523 failuretest(MANDATORY_CMD, returnval|=FAILID);
3524 }
3525 else if (!nonempty(&drive, sizeof(drive))) {
3526 pout("Read Device Identity failed: empty IDENTIFY data\n\n");
3527 failuretest(MANDATORY_CMD, returnval|=FAILID);
3528 }
3529
3530 // If requested, show which presets would be used for this drive and exit.
3531 if (options.show_presets) {
3532 show_presets(&drive);
3533 return 0;
3534 }
3535
3536 // Use preset vendor attribute options unless user has requested otherwise.
3537 ata_vendor_attr_defs attribute_defs = options.attribute_defs;
3538 firmwarebug_defs firmwarebugs = options.firmwarebugs;
3539 std::string dbversion;
3540 const drive_settings * dbentry = 0;
3541 if (!options.ignore_presets) {
3542 dbentry = lookup_drive_apply_presets(&drive, attribute_defs,
3543 firmwarebugs, dbversion);
3544 if (!dbversion.empty())
3545 jglb["smartctl"]["drive_database_version"]["string"] = dbversion;
3546 }
3547
3548 // Get capacity, sector sizes and rotation rate
3549 ata_size_info sizes;
3550 ata_get_size_info(&drive, sizes);
3551 int rpm = ata_get_rotation_rate(&drive);
3552
3553 // Print ATA IDENTIFY info if requested
3554 if (options.identify_word_level >= 0) {
3555 pout("=== ATA IDENTIFY DATA ===\n");
3556 // Pass raw data without endianness adjustments
3557 ata_print_identify_data(raw_drive, (options.identify_word_level > 0), options.identify_bit_level);
3558 }
3559
3560 // Print most drive identity information if requested
3561 if (options.drive_info) {
3562 pout("=== START OF INFORMATION SECTION ===\n");
3563 print_drive_info(&drive, sizes, rpm, dbentry, dbversion.c_str());
3564 }
3565
3566 // Check and print SMART support and state
3567 int smart_supported = -1, smart_enabled = -1;
3568 if (need_smart_support || options.drive_info) {
3569
3570 // Packet device ?
3571 if (retid > 0) {
3572 pout("SMART support is: Unavailable - Packet Interface Devices [this device: %s] don't support ATA SMART\n",
3573 packetdevicetype(retid-1));
3574 }
3575 else {
3576 // Disk device: SMART supported and enabled ?
3577 smart_supported = ataSmartSupport(&drive);
3578 smart_enabled = ataIsSmartEnabled(&drive);
3579
3580 if (smart_supported < 0)
3581 pout("SMART support is: Ambiguous - ATA IDENTIFY DEVICE words 82-83 don't show if SMART supported.\n");
3582 if (smart_supported && smart_enabled < 0) {
3583 pout("SMART support is: Ambiguous - ATA IDENTIFY DEVICE words 85-87 don't show if SMART is enabled.\n");
3584 if (need_smart_support) {
3585 failuretest(MANDATORY_CMD, returnval|=FAILSMART);
3586 // check SMART support by trying a command
3587 pout(" Checking to be sure by trying SMART RETURN STATUS command.\n");
3588 if (ataDoesSmartWork(device))
3589 smart_supported = smart_enabled = 1;
3590 }
3591 }
3592 else if (smart_supported < 0 && (smart_enabled > 0 || dbentry))
3593 // Assume supported if enabled or in drive database
3594 smart_supported = 1;
3595
3596 if (smart_supported < 0)
3597 pout("SMART support is: Unknown - Try option -s with argument 'on' to enable it.");
3598 else if (!smart_supported)
3599 jout("SMART support is: Unavailable - device lacks SMART capability.\n");
3600 else {
3601 if (options.drive_info)
3602 jout("SMART support is: Available - device has SMART capability.\n");
3603 if (smart_enabled >= 0) {
3604 if (device->ata_identify_is_cached()) {
3605 if (options.drive_info)
3606 pout(" %sabled status cached by OS, trying SMART RETURN STATUS cmd.\n",
3607 (smart_enabled?"En":"Dis"));
3608 smart_enabled = ataDoesSmartWork(device);
3609 }
3610 if (options.drive_info)
3611 jout("SMART support is: %s\n",
3612 (smart_enabled ? "Enabled" : "Disabled"));
3613 }
3614 }
3615 }
3616
3617 if (options.drive_info || smart_supported <= 0) {
3618 jglb["smart_support"]["available"] = (smart_supported > 0);
3619 if (smart_supported > 0)
3620 jglb["smart_support"]["enabled"] = (smart_enabled > 0);
3621 }
3622 }
3623
3624 // Print AAM status
3625 if (options.get_aam) {
3626 if ((drive.command_set_2 & 0xc200) != 0x4200) // word083
3627 pout("AAM feature is: Unavailable\n");
3628 else if (!(drive.word086 & 0x0200)) {
3629 jout("AAM feature is: Disabled\n");
3630 jglb["ata_aam"]["enabled"] = false;
3631 }
3632 else
3633 print_aam_level("AAM level is: ", drive.words088_255[94-88] & 0xff,
3634 drive.words088_255[94-88] >> 8);
3635 }
3636
3637 // Print APM status
3638 if (options.get_apm) {
3639 if ((drive.command_set_2 & 0xc008) != 0x4008) // word083
3640 pout("APM feature is: Unavailable\n");
3641 else if (!(drive.word086 & 0x0008)) {
3642 jout("APM feature is: Disabled\n");
3643 jglb["ata_apm"]["enabled"] = false;
3644 }
3645 else
3646 print_apm_level("APM level is: ", drive.words088_255[91-88] & 0xff);
3647 }
3648
3649 // Print read look-ahead status
3650 if (options.get_lookahead) {
3651 if ( (drive.command_set_2 & 0xc000) != 0x4000 // word083
3652 || !(drive.command_set_1 & 0x0040) ) // word082
3653 pout("Rd look-ahead is: Unavailable\n");
3654 else {
3655 bool enabled = !!(drive.cfs_enable_1 & 0x0040); // word085
3656 jout("Rd look-ahead is: %sabled\n", (enabled ? "En" : "Dis"));
3657 jglb["read_lookahead"]["enabled"] = enabled;
3658 }
3659 }
3660
3661 // Print write cache status
3662 if (options.get_wcache) {
3663 if ( (drive.command_set_2 & 0xc000) != 0x4000 // word083
3664 || !(drive.command_set_1 & 0x0020) ) // word082
3665 pout("Write cache is: Unavailable\n");
3666 else {
3667 bool enabled = !!(drive.cfs_enable_1 & 0x0020); // word085
3668 jout("Write cache is: %sabled\n", (enabled ? "En" : "Dis"));
3669 jglb["write_cache"]["enabled"] = enabled;
3670 }
3671 }
3672
3673 // Print DSN status
3674 unsigned short word120 = drive.words088_255[120-88];
3675 unsigned short word119 = drive.words088_255[119-88];
3676 if (options.get_dsn) {
3677 if (!(drive.word086 & 0x8000) // word086
3678 || ((word119 & 0xc200) != 0x4200) // word119
3679 || ((word120 & 0xc000) != 0x4000)) // word120
3680 pout("DSN feature is: Unavailable\n");
3681 else {
3682 bool enabled = !!(word120 & 0x200);
3683 jout("DSN feature is: %sabled\n", (enabled ? "En" : "Dis"));
3684 jglb["ata_dsn"]["enabled"] = enabled;
3685 }
3686 }
3687
3688 // Check for ATA Security LOCK
3689 unsigned short word128 = drive.words088_255[128-88];
3690 bool locked = ((word128 & 0x0007) == 0x0007); // LOCKED|ENABLED|SUPPORTED
3691
3692 // Print ATA Security status
3693 if (options.get_security)
3694 print_ata_security_status("ATA Security is: ", word128, drive.words088_255[92-88]);
3695
3696 // Print write cache reordering status
3697 if (options.sct_wcache_reorder_get) {
3698 if (!isSCTFeatureControlCapable(&drive))
3699 pout("Wt Cache Reorder: Unavailable\n");
3700 else if (locked)
3701 pout("Wt Cache Reorder: Unknown (SCT not supported if ATA Security is LOCKED)\n");
3702 else {
3703 int wcache_reorder = ataGetSetSCTWriteCacheReordering(device,
3704 false /*enable*/, false /*persistent*/, false /*set*/);
3705
3706 if (-1 <= wcache_reorder && wcache_reorder <= 2)
3707 pout("Wt Cache Reorder: %s\n",
3708 (wcache_reorder == -1 ? "Unknown (SCT Feature Control command failed)" :
3709 wcache_reorder == 0 ? "Unknown" : // not defined in standard but returned on some drives if not set
3710 wcache_reorder == 1 ? "Enabled" : "Disabled"));
3711 else
3712 pout("Wt Cache Reorder: Unknown (0x%02x)\n", wcache_reorder);
3713 }
3714 }
3715
3716 const char * sct_write_cache_state_desc[4] = {
3717 "Unknown", // 0: not defined in standard but returned on some drives if not set
3718 "Controlled by ATA", // 1: controlled ATA Set Features command
3719 "Force Enabled", // 2
3720 "Force Disabled" // 3
3721 };
3722
3723 // Print SCT feature control of write cache
3724 if (options.sct_wcache_sct_get) {
3725 if (!isSCTFeatureControlCapable(&drive))
3726 pout("SCT Write Cache Control: Unavailable\n");
3727 else if (locked)
3728 pout("SCT Write Cache Control: Unknown (SCT not supported if ATA Security is LOCKED)\n");
3729 else {
3730 int state = ataGetSetSCTWriteCache(device, 1, false /*persistent*/, false /*set*/);
3731 if (-1 <= state && state <= 3)
3732 pout("SCT Write Cache Control: %s\n",
3733 (state == -1 ? "Unknown (SCT Feature Control command failed)" :
3734 sct_write_cache_state_desc[state]));
3735 else
3736 pout("SCT Write Cache Control: Unknown (0x%02x)\n", state);
3737 }
3738 }
3739
3740
3741 // Print remaining drive info
3742 if (options.drive_info) {
3743 // Print the (now possibly changed) power mode if available
3744 if (powername)
3745 pout("Power mode %s %s\n", (powerchg?"was:":"is: "), powername);
3746 pout("\n");
3747 }
3748
3749 // Exit if SMART is not supported but must be available to proceed
3750 if (smart_supported <= 0 && need_smart_support)
3751 failuretest(MANDATORY_CMD, returnval|=FAILSMART);
3752
3753 // START OF THE ENABLE/DISABLE SECTION OF THE CODE
3754 if ( options.smart_disable || options.smart_enable
3757 || options.set_aam || options.set_apm || options.set_lookahead
3758 || options.set_wcache || options.set_security_freeze || options.set_standby
3759 || options.sct_wcache_reorder_set || options.sct_wcache_sct_set || options.set_dsn)
3760 pout("=== START OF ENABLE/DISABLE COMMANDS SECTION ===\n");
3761
3762 // Enable/Disable AAM
3763 if (options.set_aam) {
3764 if (options.set_aam > 0) {
3765 if (!ata_set_features(device, ATA_ENABLE_AAM, options.set_aam-1)) {
3766 pout("AAM enable failed: %s\n", device->get_errmsg());
3767 returnval |= FAILSMART;
3768 }
3769 else
3770 print_aam_level("AAM set to level ", options.set_aam-1);
3771 }
3772 else {
3773 if (!ata_set_features(device, ATA_DISABLE_AAM)) {
3774 pout("AAM disable failed: %s\n", device->get_errmsg());
3775 returnval |= FAILSMART;
3776 }
3777 else
3778 pout("AAM disabled\n");
3779 }
3780 }
3781
3782 // Enable/Disable APM
3783 if (options.set_apm) {
3784 if (options.set_apm > 0) {
3785 if (!ata_set_features(device, ATA_ENABLE_APM, options.set_apm-1)) {
3786 pout("APM enable failed: %s\n", device->get_errmsg());
3787 returnval |= FAILSMART;
3788 }
3789 else
3790 print_apm_level("APM set to level ", options.set_apm-1);
3791 }
3792 else {
3793 if (!ata_set_features(device, ATA_DISABLE_APM)) {
3794 pout("APM disable failed: %s\n", device->get_errmsg());
3795 returnval |= FAILSMART;
3796 }
3797 else
3798 pout("APM disabled\n");
3799 }
3800 }
3801
3802 // Enable/Disable read look-ahead
3803 if (options.set_lookahead) {
3804 bool enable = (options.set_lookahead > 0);
3806 pout("Read look-ahead %sable failed: %s\n", (enable ? "en" : "dis"), device->get_errmsg());
3807 returnval |= FAILSMART;
3808 }
3809 else
3810 pout("Read look-ahead %sabled\n", (enable ? "en" : "dis"));
3811 }
3812
3813 // Enable/Disable write cache
3814 if (options.set_wcache) {
3815 bool enable = (options.set_wcache > 0);
3817 pout("Write cache %sable failed: %s\n", (enable ? "en" : "dis"), device->get_errmsg());
3818 returnval |= FAILSMART;
3819 }
3820 else
3821 pout("Write cache %sabled\n", (enable ? "en" : "dis"));
3822 }
3823
3824 // Enable/Disable DSN
3825 if (options.set_dsn) {
3826 bool enable = (options.set_dsn > 0);
3827 if (!ata_set_features(device, ATA_ENABLE_DISABLE_DSN, (enable ? 0x1 : 0x2))) {
3828 pout("DSN %sable failed: %s\n", (enable ? "en" : "dis"), device->get_errmsg());
3829 returnval |= FAILSMART;
3830 }
3831 else
3832 pout("DSN %sabled\n", (enable ? "en" : "dis"));
3833 }
3834
3835 // Enable/Disable write cache reordering
3836 if (options.sct_wcache_reorder_set) {
3837 bool enable = (options.sct_wcache_reorder_set > 0);
3838 if (!isSCTFeatureControlCapable(&drive))
3839 pout("Write cache reordering %sable failed: SCT Feature Control command not supported\n",
3840 (enable ? "en" : "dis"));
3841 else if (locked)
3842 pout("Write cache reordering %sable failed: SCT not supported if ATA Security is LOCKED\n",
3843 (enable ? "en" : "dis"));
3844 else if (ataGetSetSCTWriteCacheReordering(device,
3845 enable, options.sct_wcache_reorder_set_pers, true /*set*/) < 0) {
3846 pout("Write cache reordering %sable failed: %s\n", (enable ? "en" : "dis"), device->get_errmsg());
3847 returnval |= FAILSMART;
3848 }
3849 else
3850 pout("Write cache reordering %sabled (%s)\n", (enable ? "en" : "dis"),
3851 (options.sct_wcache_reorder_set_pers ? "persistent" : "volatile"));
3852 }
3853
3854 // Enable/Disable write cache in SCT
3855 if (options.sct_wcache_sct_set) {
3856 if (!isSCTFeatureControlCapable(&drive))
3857 pout("SCT Feature Control of write cache failed: SCT Feature Control command not supported\n");
3858 else if (locked)
3859 pout("SCT Feature Control of write cache failed: SCT not supported if ATA Security is LOCKED\n");
3860 else if (ataGetSetSCTWriteCache(device,
3861 options.sct_wcache_sct_set, options.sct_wcache_sct_set_pers, true /*set*/) < 0) {
3862 pout("SCT Feature Control of write cache failed: %s\n", device->get_errmsg());
3863 returnval |= FAILSMART;
3864 }
3865 else
3866 pout("Write cache SCT Feature Control is set to: %s (%s)\n",
3867 sct_write_cache_state_desc[options.sct_wcache_sct_set],
3868 (options.sct_wcache_sct_set_pers ? "persistent" : "volatile"));
3869 }
3870
3871 // Freeze ATA security
3872 if (options.set_security_freeze) {
3874 pout("ATA SECURITY FREEZE LOCK failed: %s\n", device->get_errmsg());
3875 returnval |= FAILSMART;
3876 }
3877 else
3878 pout("ATA Security set to frozen mode\n");
3879 }
3880
3881 // Set standby timer unless immediate standby is also requested
3882 if (options.set_standby && !options.set_standby_now) {
3883 if (!ata_nodata_command(device, ATA_IDLE, options.set_standby-1)) {
3884 pout("ATA IDLE command failed: %s\n", device->get_errmsg());
3885 returnval |= FAILSMART;
3886 }
3887 else
3888 print_standby_timer("Standby timer set to ", options.set_standby-1, drive);
3889 }
3890
3891 // Enable/Disable SMART commands
3892 if (options.smart_enable) {
3893 if (ataEnableSmart(device)) {
3894 pout("SMART Enable failed: %s\n\n", device->get_errmsg());
3895 failuretest(MANDATORY_CMD, returnval|=FAILSMART);
3896 }
3897 else {
3898 pout("SMART Enabled.\n");
3899 smart_enabled = 1;
3900 }
3901 }
3902
3903 // Turn off SMART on device
3904 if (options.smart_disable) {
3905 if (ataDisableSmart(device)) {
3906 pout("SMART Disable failed: %s\n\n", device->get_errmsg());
3908 }
3909 }
3910
3911 // Exit if SMART is disabled but must be enabled to proceed
3912 if (options.smart_disable || (smart_enabled <= 0 && need_smart_enabled && !is_permissive())) {
3913 pout("SMART Disabled. Use option -s with argument 'on' to enable it.\n");
3914 if (!options.smart_disable)
3915 pout("(override with '-T permissive' option)\n");
3916 return returnval;
3917 }
3918
3919 // Enable/Disable Auto-save attributes
3920 if (options.smart_auto_save_enable) {
3921 if (ataEnableAutoSave(device)){
3922 pout("SMART Enable Attribute Autosave failed: %s\n\n", device->get_errmsg());
3923 failuretest(MANDATORY_CMD, returnval|=FAILSMART);
3924 }
3925 else
3926 pout("SMART Attribute Autosave Enabled.\n");
3927 }
3928
3929 if (options.smart_auto_save_disable) {
3930 if (ataDisableAutoSave(device)){
3931 pout("SMART Disable Attribute Autosave failed: %s\n\n", device->get_errmsg());
3932 failuretest(MANDATORY_CMD, returnval|=FAILSMART);
3933 }
3934 else
3935 pout("SMART Attribute Autosave Disabled.\n");
3936 }
3937
3938 // Read SMART values and thresholds if necessary
3939 ata_smart_values smartval; memset(&smartval, 0, sizeof(smartval));
3940 ata_smart_thresholds_pvt smartthres; memset(&smartthres, 0, sizeof(smartthres));
3941 bool smart_val_ok = false, smart_thres_ok = false;
3942
3943 if (need_smart_val) {
3944 if (ataReadSmartValues(device, &smartval)) {
3945 pout("Read SMART Data failed: %s\n\n", device->get_errmsg());
3946 failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
3947 }
3948 else {
3949 smart_val_ok = true;
3950
3951 if (options.smart_check_status || options.smart_vendor_attrib) {
3952 if (ataReadSmartThresholds(device, &smartthres)){
3953 pout("Read SMART Thresholds failed: %s\n\n", device->get_errmsg());
3954 failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
3955 }
3956 else
3957 smart_thres_ok = true;
3958 }
3959 }
3960 }
3961
3962 // Enable/Disable Off-line testing
3963 bool needupdate = false;
3964 if (options.smart_auto_offl_enable) {
3965 if (!isSupportAutomaticTimer(&smartval)){
3966 pout("SMART Automatic Timers not supported\n\n");
3967 failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
3968 }
3969 needupdate = smart_val_ok;
3970 if (ataEnableAutoOffline(device)){
3971 pout("SMART Enable Automatic Offline failed: %s\n\n", device->get_errmsg());
3972 failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
3973 }
3974 else
3975 pout("SMART Automatic Offline Testing Enabled every four hours.\n");
3976 }
3977
3978 if (options.smart_auto_offl_disable) {
3979 if (!isSupportAutomaticTimer(&smartval)){
3980 pout("SMART Automatic Timers not supported\n\n");
3981 failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
3982 }
3983 needupdate = smart_val_ok;
3984 if (ataDisableAutoOffline(device)){
3985 pout("SMART Disable Automatic Offline failed: %s\n\n", device->get_errmsg());
3986 failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
3987 }
3988 else
3989 pout("SMART Automatic Offline Testing Disabled.\n");
3990 }
3991
3992 if (needupdate && ataReadSmartValues(device, &smartval)){
3993 pout("Read SMART Data failed: %s\n\n", device->get_errmsg());
3994 failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
3995 smart_val_ok = false;
3996 }
3997
3998 // all this for a newline!
3999 if ( options.smart_disable || options.smart_enable
4002 || options.set_aam || options.set_apm || options.set_lookahead
4003 || options.set_wcache || options.set_security_freeze || options.set_standby
4004 || options.sct_wcache_reorder_set || options.set_dsn)
4005 pout("\n");
4006
4007 // START OF READ-ONLY OPTIONS APART FROM -V and -i
4008 if ( options.smart_check_status || options.smart_general_values
4009 || options.smart_vendor_attrib || options.smart_error_log
4011 || options.smart_ext_error_log || options.smart_ext_selftest_log
4012 || options.sct_temp_sts || options.sct_temp_hist )
4013 pout("=== START OF READ SMART DATA SECTION ===\n");
4014
4015 // Check SMART status
4016 if (options.smart_check_status) {
4017
4018 switch (ataSmartStatus2(device)) {
4019
4020 case 0:
4021 // The case where the disk health is OK
4022 jout("SMART overall-health self-assessment test result: PASSED\n");
4023 jglb["smart_status"]["passed"] = true;
4024 if (smart_thres_ok && find_failed_attr(&smartval, &smartthres, attribute_defs, 0)) {
4025 if (options.smart_vendor_attrib)
4026 pout("See vendor-specific Attribute list for marginal Attributes.\n\n");
4027 else {
4028 print_on();
4029 pout("Please note the following marginal Attributes:\n");
4030 PrintSmartAttribWithThres(&smartval, &smartthres, attribute_defs, rpm, 2, options.output_format);
4031 }
4032 returnval|=FAILAGE;
4033 }
4034 else
4035 pout("\n");
4036 break;
4037
4038 case 1:
4039 // The case where the disk health is NOT OK
4040 print_on();
4041 jout("SMART overall-health self-assessment test result: FAILED!\n"
4042 "Drive failure expected in less than 24 hours. SAVE ALL DATA.\n");
4043 jglb["smart_status"]["passed"] = false;
4044 print_off();
4045 if (smart_thres_ok && find_failed_attr(&smartval, &smartthres, attribute_defs, 1)) {
4046 returnval|=FAILATTR;
4047 if (options.smart_vendor_attrib)
4048 pout("See vendor-specific Attribute list for failed Attributes.\n\n");
4049 else {
4050 print_on();
4051 pout("Failed Attributes:\n");
4052 PrintSmartAttribWithThres(&smartval, &smartthres, attribute_defs, rpm, 1, options.output_format);
4053 }
4054 }
4055 else
4056 pout("No failed Attributes found.\n\n");
4057 returnval|=FAILSTATUS;
4058 print_off();
4059 break;
4060
4061 case -1:
4062 default:
4063 // Something went wrong with the SMART STATUS command.
4064 // The ATA SMART RETURN STATUS command provides the result in the ATA output
4065 // registers. Buggy ATA/SATA drivers and SAT Layers often do not properly
4066 // return the registers values.
4067 pout("SMART Status %s: %s\n",
4068 (device->is_syscall_unsup() ? "not supported" : "command failed"),
4069 device->get_errmsg());
4070 failuretest(OPTIONAL_CMD, returnval | FAILSMART);
4071 if (!(device->is_syscall_unsup() && smart_val_ok && smart_thres_ok))
4072 returnval |= FAILSMART; // Unknown error or attribute check not possible
4073
4074 if (!(smart_val_ok && smart_thres_ok)) {
4075 print_on();
4076 pout("SMART overall-health self-assessment test result: UNKNOWN!\n"
4077 "SMART Status, Attributes and Thresholds cannot be read.\n\n");
4078 }
4079 else if (find_failed_attr(&smartval, &smartthres, attribute_defs, 1)) {
4080 print_on();
4081 jout("SMART overall-health self-assessment test result: FAILED!\n"
4082 "Drive failure expected in less than 24 hours. SAVE ALL DATA.\n");
4083 jwrn("Warning: This result is based on an Attribute check.\n");
4084 jglb["smart_status"]["passed"] = false;
4085 print_off();
4086 returnval|=FAILATTR;
4087 returnval|=FAILSTATUS;
4088 if (options.smart_vendor_attrib)
4089 pout("See vendor-specific Attribute list for failed Attributes.\n\n");
4090 else {
4091 print_on();
4092 pout("Failed Attributes:\n");
4093 PrintSmartAttribWithThres(&smartval, &smartthres, attribute_defs, rpm, 1, options.output_format);
4094 }
4095 }
4096 else {
4097 jout("SMART overall-health self-assessment test result: PASSED\n");
4098 jwrn("Warning: This result is based on an Attribute check.\n");
4099 jglb["smart_status"]["passed"] = true;
4100 if (find_failed_attr(&smartval, &smartthres, attribute_defs, 0)) {
4101 if (options.smart_vendor_attrib)
4102 pout("See vendor-specific Attribute list for marginal Attributes.\n\n");
4103 else {
4104 print_on();
4105 pout("Please note the following marginal Attributes:\n");
4106 PrintSmartAttribWithThres(&smartval, &smartthres, attribute_defs, rpm, 2, options.output_format);
4107 }
4108 returnval|=FAILAGE;
4109 }
4110 else
4111 pout("\n");
4112 }
4113 print_off();
4114 break;
4115 } // end of switch statement
4116
4117 print_off();
4118 } // end of checking SMART Status
4119
4120 // Print general SMART values
4121 if (smart_val_ok && options.smart_general_values)
4122 PrintGeneralSmartValues(&smartval, &drive, firmwarebugs);
4123
4124 // Print vendor-specific attributes
4125 if (smart_val_ok && options.smart_vendor_attrib) {
4126 print_on();
4127 PrintSmartAttribWithThres(&smartval, &smartthres, attribute_defs, rpm,
4128 (printing_is_switchable ? 2 : 0), options.output_format);
4129 print_off();
4130 }
4131
4132 // If GP Log is supported use smart log directory for
4133 // error and selftest log support check.
4134 bool gp_log_supported = isGeneralPurposeLoggingCapable(&drive);
4135 if ( gp_log_supported
4136 && ( options.smart_error_log || options.smart_selftest_log
4137 || options.retry_error_log || options.retry_selftest_log))
4138 need_smart_logdir = true;
4139
4140 ata_smart_log_directory smartlogdir_buf, gplogdir_buf;
4141 const ata_smart_log_directory * smartlogdir = 0, * gplogdir = 0;
4142
4143 // Read SMART Log directory
4144 if (need_smart_logdir) {
4145 if (firmwarebugs.is_set(BUG_NOLOGDIR))
4146 smartlogdir = fake_logdir(&smartlogdir_buf, options);
4147 else if (ataReadLogDirectory(device, &smartlogdir_buf, false)) {
4148 pout("Read SMART Log Directory failed: %s\n\n", device->get_errmsg());
4149 failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
4150 }
4151 else
4152 smartlogdir = &smartlogdir_buf;
4153 }
4154
4155 // Read GP Log directory
4156 if (need_gp_logdir) {
4157 if (firmwarebugs.is_set(BUG_NOLOGDIR))
4158 gplogdir = fake_logdir(&gplogdir_buf, options);
4159 else if (!gp_log_supported && !is_permissive()) {
4160 if (options.gp_logdir)
4161 pout("General Purpose Log Directory not supported\n\n");
4162 }
4163 else if (ataReadLogDirectory(device, &gplogdir_buf, true)) {
4164 pout("Read GP Log Directory failed\n\n");
4165 failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
4166 }
4167 else
4168 gplogdir = &gplogdir_buf;
4169 }
4170
4171 // Print log directories
4172 if ((options.gp_logdir && gplogdir) || (options.smart_logdir && smartlogdir)) {
4173 if (firmwarebugs.is_set(BUG_NOLOGDIR))
4174 pout("Log Directories not read due to '-F nologdir' option\n\n");
4175 else
4176 PrintLogDirectories(gplogdir, smartlogdir);
4177 }
4178
4179 // Print log pages
4180 for (i = 0; i < options.log_requests.size(); i++) {
4181 const ata_log_request & req = options.log_requests[i];
4182
4183 const char * type;
4184 unsigned max_nsectors;
4185 if (req.gpl) {
4186 type = "General Purpose";
4187 max_nsectors = GetNumLogSectors(gplogdir, req.logaddr, true);
4188 }
4189 else {
4190 type = "SMART";
4191 max_nsectors = GetNumLogSectors(smartlogdir, req.logaddr, false);
4192 }
4193
4194 if (!max_nsectors) {
4195 if (!is_permissive()) {
4196 pout("%s Log 0x%02x does not exist (override with '-T permissive' option)\n", type, req.logaddr);
4197 continue;
4198 }
4199 max_nsectors = req.page+1;
4200 }
4201 if (max_nsectors <= req.page) {
4202 pout("%s Log 0x%02x has only %u sectors, output skipped\n", type, req.logaddr, max_nsectors);
4203 continue;
4204 }
4205
4206 unsigned ns = req.nsectors;
4207 if (ns > max_nsectors - req.page) {
4208 if (req.nsectors != ~0U) // "FIRST-max"
4209 pout("%s Log 0x%02x has only %u sectors, output truncated\n", type, req.logaddr, max_nsectors);
4210 ns = max_nsectors - req.page;
4211 }
4212
4213 // SMART log don't support sector offset, start with first sector
4214 unsigned offs = (req.gpl ? 0 : req.page);
4215
4216 raw_buffer log_buf((offs + ns) * 512);
4217 bool ok;
4218 if (req.gpl)
4219 ok = ataReadLogExt(device, req.logaddr, 0x00, req.page, log_buf.data(), ns);
4220 else
4221 ok = ataReadSmartLog(device, req.logaddr, log_buf.data(), offs + ns);
4222 if (!ok)
4223 failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
4224 else
4225 PrintLogPages(type, log_buf.data() + offs*512, req.logaddr, req.page, ns, max_nsectors);
4226 }
4227
4228 // Print SMART Extendend Comprehensive Error Log
4229 bool do_smart_error_log = options.smart_error_log;
4230 if (options.smart_ext_error_log) {
4231 bool ok = false;
4232 unsigned nsectors = GetNumLogSectors(gplogdir, 0x03, true);
4233 if (!nsectors)
4234 pout("SMART Extended Comprehensive Error Log (GP Log 0x03) not supported\n\n");
4235 else {
4236 // Read only first sector to get error count and index
4237 // Print function will read more sectors as needed
4238 ata_smart_exterrlog log_03; memset(&log_03, 0, sizeof(log_03));
4239 if (!ataReadExtErrorLog(device, &log_03, 0, 1, firmwarebugs)) {
4240 pout("Read SMART Extended Comprehensive Error Log failed\n\n");
4241 failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
4242 }
4243 else {
4244 if (PrintSmartExtErrorLog(device, firmwarebugs, &log_03, nsectors, options.smart_ext_error_log))
4245 returnval |= FAILERR;
4246 ok = true;
4247 }
4248 }
4249
4250 if (!ok) {
4251 if (options.retry_error_log)
4252 do_smart_error_log = true;
4253 else if (!do_smart_error_log)
4254 pout("Try '-l [xerror,]error' to read traditional SMART Error Log\n");
4255 }
4256 }
4257
4258 // Print SMART error log
4259 if (do_smart_error_log) {
4260 if (!( GetNumLogSectors(smartlogdir, 0x01, false)
4261 || ( !(smartlogdir && gp_log_supported)
4262 && isSmartErrorLogCapable(&smartval, &drive))
4263 || is_permissive() )) {
4264 pout("SMART Error Log not supported\n\n");
4265 }
4266 else {
4267 ata_smart_errorlog smarterror; memset(&smarterror, 0, sizeof(smarterror));
4268 if (ataReadErrorLog(device, &smarterror, firmwarebugs)) {
4269 pout("Read SMART Error Log failed: %s\n\n", device->get_errmsg());
4270 failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
4271 }
4272 else {
4273 // quiet mode is turned on inside PrintSmartErrorLog()
4274 if (PrintSmartErrorlog(&smarterror, firmwarebugs))
4275 returnval|=FAILERR;
4276 print_off();
4277 }
4278 }
4279 }
4280
4281 // Print SMART Extendend Self-test Log
4282 bool do_smart_selftest_log = options.smart_selftest_log;
4283 if (options.smart_ext_selftest_log) {
4284 bool ok = false;
4285 unsigned nsectors = GetNumLogSectors(gplogdir, 0x07, true);
4286 if (!nsectors)
4287 pout("SMART Extended Self-test Log (GP Log 0x07) not supported\n\n");
4288 else if (nsectors >= 256)
4289 pout("SMART Extended Self-test Log size %u not supported\n\n", nsectors);
4290 else {
4291 raw_buffer log_07_buf(nsectors * 512);
4292 ata_smart_extselftestlog * log_07 = reinterpret_cast<ata_smart_extselftestlog *>(log_07_buf.data());
4293 if (!ataReadExtSelfTestLog(device, log_07, nsectors)) {
4294 pout("Read SMART Extended Self-test Log failed\n\n");
4295 failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
4296 }
4297 else {
4298 if (PrintSmartExtSelfTestLog(log_07, nsectors, options.smart_ext_selftest_log))
4299 returnval |= FAILLOG;
4300 ok = true;
4301 }
4302 }
4303
4304 if (!ok) {
4305 if (options.retry_selftest_log)
4306 do_smart_selftest_log = true;
4307 else if (!do_smart_selftest_log)
4308 pout("Try '-l [xselftest,]selftest' to read traditional SMART Self Test Log\n");
4309 }
4310 }
4311
4312 // Print SMART self-test log
4313 if (do_smart_selftest_log) {
4314 if (!( GetNumLogSectors(smartlogdir, 0x06, false)
4315 || ( !(smartlogdir && gp_log_supported)
4316 && isSmartTestLogCapable(&smartval, &drive))
4317 || is_permissive() )) {
4318 pout("SMART Self-test Log not supported\n\n");
4319 }
4320 else {
4321 ata_smart_selftestlog smartselftest; memset(&smartselftest, 0, sizeof(smartselftest));
4322 if (ataReadSelfTestLog(device, &smartselftest, firmwarebugs)) {
4323 pout("Read SMART Self-test Log failed: %s\n\n", device->get_errmsg());
4324 failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
4325 }
4326 else {
4327 print_on();
4328 if (ataPrintSmartSelfTestlog(&smartselftest, !printing_is_switchable, firmwarebugs))
4329 returnval |= FAILLOG;
4330 print_off();
4331 pout("\n");
4332 }
4333 }
4334 }
4335
4336 // Print SMART selective self-test log
4337 if (options.smart_selective_selftest_log) {
4339
4340 if (!isSupportSelectiveSelfTest(&smartval))
4341 pout("Selective Self-tests/Logging not supported\n\n");
4342 else if(ataReadSelectiveSelfTestLog(device, &log)) {
4343 pout("Read SMART Selective Self-test Log failed: %s\n\n", device->get_errmsg());
4344 failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
4345 }
4346 else {
4347 print_on();
4348 // If any errors were found, they are logged in the SMART Self-test log.
4349 // So there is no need to print the Selective Self Test log in silent
4350 // mode.
4352 ataPrintSelectiveSelfTestLog(&log, &smartval);
4353 print_off();
4354 pout("\n");
4355 }
4356 }
4357
4358 // Check if SCT commands available
4359 bool sct_ok = isSCTCapable(&drive);
4360 if ( options.sct_temp_sts || options.sct_temp_hist || options.sct_temp_int
4361 || options.sct_erc_get || options.sct_erc_set ) {
4362 if (!sct_ok)
4363 pout("SCT Commands not supported\n\n");
4364 else if (locked) {
4365 pout("SCT Commands not supported if ATA Security is LOCKED\n\n");
4366 sct_ok = false;
4367 }
4368 }
4369
4370 // Print SCT status and temperature history table
4371 if (sct_ok && (options.sct_temp_sts || options.sct_temp_hist || options.sct_temp_int)) {
4372 for (;;) {
4373 bool sct_temp_hist_ok = isSCTDataTableCapable(&drive);
4375
4376 if (options.sct_temp_sts || (options.sct_temp_hist && sct_temp_hist_ok)) {
4377 // Read SCT status
4378 if (ataReadSCTStatus(device, &sts)) {
4379 pout("\n");
4380 failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
4381 break;
4382 }
4383 if (options.sct_temp_sts) {
4384 ataPrintSCTStatus(&sts);
4385 pout("\n");
4386 }
4387 }
4388
4389 if (!sct_temp_hist_ok && (options.sct_temp_hist || options.sct_temp_int)) {
4390 pout("SCT Data Table command not supported\n\n");
4391 failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
4392 break;
4393 }
4394
4395 if (options.sct_temp_hist) {
4396 // Read SCT temperature history,
4397 // requires initial SCT status from above
4399 if (ataReadSCTTempHist(device, &tmh, &sts)) {
4400 pout("Read SCT Temperature History failed\n\n");
4401 failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
4402 break;
4403 }
4404 ataPrintSCTTempHist(&tmh);
4405 pout("\n");
4406 }
4407
4408 if (options.sct_temp_int) {
4409 // Set new temperature logging interval
4410 if (!isSCTFeatureControlCapable(&drive)) {
4411 pout("SCT Feature Control command not supported\n\n");
4412 failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
4413 break;
4414 }
4415 if (ataSetSCTTempInterval(device, options.sct_temp_int, options.sct_temp_int_pers)) {
4416 pout("Write Temperature Logging Interval failed\n\n");
4417 failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
4418 break;
4419 }
4420 pout("Temperature Logging Interval set to %u minute%s (%s)\n",
4421 options.sct_temp_int, (options.sct_temp_int == 1 ? "" : "s"),
4422 (options.sct_temp_int_pers ? "persistent" : "volatile"));
4423 }
4424 break;
4425 }
4426 }
4427
4428 // SCT Error Recovery Control
4429 if (sct_ok && (options.sct_erc_get || options.sct_erc_set)) {
4430 if (!isSCTErrorRecoveryControlCapable(&drive)) {
4431 pout("SCT Error Recovery Control command not supported\n\n");
4432 if (options.sct_erc_set)
4433 failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
4434 }
4435 else {
4436 int sct_erc_get = options.sct_erc_get;
4437 if (options.sct_erc_set) {
4438 // Set SCT Error Recovery Control
4439 bool set_power_on = (options.sct_erc_set == 2), mfg_default = (options.sct_erc_set == 3);
4440 if ( ataSetSCTErrorRecoveryControltime(device, 1, options.sct_erc_readtime, set_power_on, mfg_default)
4441 || ataSetSCTErrorRecoveryControltime(device, 2, options.sct_erc_writetime, set_power_on, mfg_default)) {
4442 pout("SCT (Set) Error Recovery Control command failed\n");
4443 if (!( (options.sct_erc_readtime == 70 && options.sct_erc_writetime == 70)
4444 || (options.sct_erc_readtime == 0 && options.sct_erc_writetime == 0)))
4445 pout("Retry with: 'scterc,70,70' to enable ERC or 'scterc,0,0' to disable\n");
4446 failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
4447 sct_erc_get = 0;
4448 }
4449 else if (!sct_erc_get)
4451 options.sct_erc_writetime, set_power_on, mfg_default);
4452 }
4453
4454 if (sct_erc_get) {
4455 // Print SCT Error Recovery Control
4456 bool get_power_on = (sct_erc_get == 2);
4457 unsigned short read_timer, write_timer;
4458 if ( ataGetSCTErrorRecoveryControltime(device, 1, read_timer, get_power_on)
4459 || ataGetSCTErrorRecoveryControltime(device, 2, write_timer, get_power_on)) {
4460 pout("SCT (Get) Error Recovery Control command failed\n");
4461 if (options.sct_erc_set == sct_erc_get) {
4462 pout("The previous SCT (Set) Error Recovery Control command succeeded\n");
4464 options.sct_erc_writetime, get_power_on);
4465 }
4466 failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
4467 }
4468 else
4469 ataPrintSCTErrorRecoveryControl(false, read_timer, write_timer, get_power_on);
4470 }
4471 pout("\n");
4472 }
4473 }
4474
4475 // Print Device Statistics
4476 if (options.devstat_all_pages || options.devstat_ssd_page || !options.devstat_pages.empty()) {
4477 bool use_gplog = true;
4478 unsigned nsectors = 0;
4479 if (gplogdir)
4480 nsectors = GetNumLogSectors(gplogdir, 0x04, true);
4481 else if (smartlogdir){ // for systems without ATA_READ_LOG_EXT
4482 nsectors = GetNumLogSectors(smartlogdir, 0x04, false);
4483 use_gplog = false;
4484 }
4485 if (!nsectors)
4486 pout("Device Statistics (GP/SMART Log 0x04) not supported\n\n");
4487 else if (!print_device_statistics(device, nsectors, options.devstat_pages,
4488 options.devstat_all_pages, options.devstat_ssd_page, use_gplog))
4489 failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
4490 }
4491
4492 // Print Pending Defects log
4493 if (options.pending_defects_log) {
4494 unsigned nsectors = GetNumLogSectors(gplogdir, 0x0c, true);
4495 if (!nsectors)
4496 pout("Pending Defects log (GP Log 0x0c) not supported\n\n");
4497 else if (!print_pending_defects_log(device, nsectors, options.pending_defects_log))
4498 failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
4499 }
4500
4501 // Print SATA Phy Event Counters
4502 if (options.sataphy) {
4503 unsigned nsectors = GetNumLogSectors(gplogdir, 0x11, true);
4504 // Packet interface devices do not provide a log directory, check support bit
4505 if (!nsectors && (drive.words047_079[76-47] & 0x0401) == 0x0400)
4506 nsectors = 1;
4507 if (!nsectors)
4508 pout("SATA Phy Event Counters (GP Log 0x11) not supported\n\n");
4509 else if (nsectors != 1)
4510 pout("SATA Phy Event Counters with %u sectors not supported\n\n", nsectors);
4511 else {
4512 unsigned char log_11[512] = {0, };
4513 unsigned char features = (options.sataphy_reset ? 0x01 : 0x00);
4514 if (!ataReadLogExt(device, 0x11, features, 0, log_11, 1)) {
4515 pout("Read SATA Phy Event Counters failed\n\n");
4516 failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
4517 }
4518 else
4520 }
4521 }
4522
4523 // Print ATA FARM log for Seagate ATA drive
4524 if (options.farm_log || options.farm_log_suggest) {
4525 bool farm_supported = true;
4526 // Check if drive is a Seagate drive
4527 if (ataIsSeagate(drive, dbentry)) {
4528 unsigned nsectors = GetNumLogSectors(gplogdir, 0xA6, true);
4529 // Check if the Seagate drive is one that supports FARM
4530 if (!nsectors) {
4531 if (options.farm_log) {
4532 jout("FARM log (GP Log 0xa6) not supported\n\n");
4533 }
4534 farm_supported = false;
4535 } else {
4536 // If -x/-xall or -a/-all is run without explicit -l farm, suggests FARM log
4537 if (options.farm_log_suggest && !options.farm_log) {
4538 jout("Seagate FARM log (GP Log 0xa6) supported [try: -l farm]\n\n");
4539 // Otherwise, actually pull the FARM log
4540 } else {
4541 ataFarmLog farmLog;
4542 if (!ataReadFarmLog(device, farmLog, nsectors)) {
4543 pout("Read FARM log (GP Log 0xa6) failed\n\n");
4544 farm_supported = false;
4545 } else {
4546 ataPrintFarmLog(farmLog);
4547 jout("\n");
4548 }
4549 }
4550 }
4551 } else {
4552 if (options.farm_log) {
4553 jout("FARM log (GP Log 0xa6) not supported for non-Seagate drives\n\n");
4554 }
4555 farm_supported = false;
4556 }
4557 jglb["seagate_farm_log"]["supported"] = farm_supported;
4558 }
4559
4560 // Suggest '-x' if '-a' is specified without any advanced option
4561 if (options.a_option && !not_part_of_a_option)
4562 pout("The above only provides legacy SMART information - try 'smartctl -x' for more\n\n");
4563
4564 // Set to standby (spindown) mode and set standby timer if not done above
4565 // (Above commands may spinup drive)
4566 if (options.set_standby_now) {
4567 if (options.set_standby) {
4568 if (!ata_nodata_command(device, ATA_STANDBY, options.set_standby-1)) {
4569 pout("ATA STANDBY command failed: %s\n", device->get_errmsg());
4570 returnval |= FAILSMART;
4571 }
4572 else {
4573 print_standby_timer("Standby timer set to ", options.set_standby-1, drive);
4574 pout("Device placed in STANDBY mode\n");
4575 }
4576 }
4577 else {
4579 pout("ATA STANDBY IMMEDIATE command failed: %s\n", device->get_errmsg());
4580 returnval |= FAILSMART;
4581 }
4582 else
4583 pout("Device placed in STANDBY mode\n");
4584 }
4585 }
4586
4587 // START OF THE TESTING SECTION OF THE CODE. IF NO TESTING, RETURN
4588 if (!smart_val_ok || options.smart_selftest_type == -1)
4589 return returnval;
4590
4591 pout("=== START OF OFFLINE IMMEDIATE AND SELF-TEST SECTION ===\n");
4592 // if doing a self-test, be sure it's supported by the hardware
4593 switch (options.smart_selftest_type) {
4594 case OFFLINE_FULL_SCAN:
4595 if (!isSupportExecuteOfflineImmediate(&smartval)){
4596 pout("Execute Offline Immediate function not supported\n\n");
4597 failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
4598 }
4599 break;
4600 case ABORT_SELF_TEST:
4601 case SHORT_SELF_TEST:
4602 case EXTEND_SELF_TEST:
4605 if (!isSupportSelfTest(&smartval)){
4606 pout("Self-test functions not supported\n\n");
4607 failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
4608 }
4609 break;
4612 if (!isSupportConveyanceSelfTest(&smartval)){
4613 pout("Conveyance Self-test functions not supported\n\n");
4614 failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
4615 }
4616 break;
4619 if (!isSupportSelectiveSelfTest(&smartval)){
4620 pout("Selective Self-test functions not supported\n\n");
4621 failuretest(MANDATORY_CMD, returnval|=FAILSMART);
4622 }
4623 break;
4624 default:
4625 break; // Vendor specific type
4626 }
4627
4628 // Now do the test. Note ataSmartTest prints its own error/success
4629 // messages
4630 if (ataSmartTest(device, options.smart_selftest_type, options.smart_selftest_force,
4631 options.smart_selective_args, &smartval, sizes.sectors ))
4632 failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
4633 else {
4634 // Tell user how long test will take to complete. This is tricky
4635 // because in the case of an Offline Full Scan, the completion
4636 // timer is volatile, and needs to be read AFTER the command is
4637 // given. If this will interrupt the Offline Full Scan, we don't
4638 // do it, just warn user.
4639 if (options.smart_selftest_type == OFFLINE_FULL_SCAN) {
4640 if (isSupportOfflineAbort(&smartval))
4641 pout("Note: giving further SMART commands will abort Offline testing\n");
4642 else if (ataReadSmartValues(device, &smartval)){
4643 pout("Read SMART Data failed: %s\n\n", device->get_errmsg());
4644 failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
4645 }
4646 }
4647
4648 // Now say how long the test will take to complete
4649 int timewait = TestTime(&smartval, options.smart_selftest_type);
4650 if (timewait) {
4651 time_t t=time(NULL);
4652 if (options.smart_selftest_type == OFFLINE_FULL_SCAN) {
4653 t+=timewait;
4654 pout("Please wait %d seconds for test to complete.\n", (int)timewait);
4655 } else {
4656 t+=timewait*60;
4657 pout("Please wait %d minutes for test to complete.\n", (int)timewait);
4658 }
4659 char comptime[DATEANDEPOCHLEN];
4660 dateandtimezoneepoch(comptime, t);
4661 pout("Test will complete after %s\n", comptime);
4662
4667 pout("Use smartctl -X to abort test.\n");
4668 }
4669 }
4670
4671 return returnval;
4672}
const char * look_up_ata_command(unsigned char c_code, unsigned char f_reg)
bool ata_nodata_command(ata_device *device, unsigned char command, int sector_count)
Definition: atacmds.cpp:787
int ataDisableAutoOffline(ata_device *device)
Definition: atacmds.cpp:1581
unsigned char ata_return_temperature_value(const ata_smart_values *data, const ata_vendor_attr_defs &defs)
Definition: atacmds.cpp:2159
bool isSmartErrorLogCapable(const ata_smart_values *data, const ata_identify_device *identity)
Definition: atacmds.cpp:1731
int ataGetSCTErrorRecoveryControltime(ata_device *device, unsigned type, unsigned short &time_limit, bool power_on)
Definition: atacmds.cpp:2510
bool ataReadSmartLog(ata_device *device, unsigned char logaddr, void *data, unsigned nsectors)
Definition: atacmds.cpp:1143
int ata_get_wwn(const ata_identify_device *id, unsigned &oui, uint64_t &unique_id)
Definition: atacmds.cpp:900
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:1611
int ataEnableAutoOffline(ata_device *device)
Definition: atacmds.cpp:1570
int ataSmartStatus2(ata_device *device)
Definition: atacmds.cpp:1604
int ataSmartSupport(const ata_identify_device *drive)
Definition: atacmds.cpp:936
int ataDisableAutoSave(ata_device *device)
Definition: atacmds.cpp:1558
int ata_get_rotation_rate(const ata_identify_device *id)
Definition: atacmds.cpp:920
bool ataReadLogExt(ata_device *device, unsigned char logaddr, unsigned char features, unsigned page, void *data, unsigned nsectors)
Definition: atacmds.cpp:1111
int ataEnableAutoSave(ata_device *device)
Definition: atacmds.cpp:1551
int ataReadSelfTestLog(ata_device *device, ata_smart_selftestlog *data, firmwarebug_defs firmwarebugs)
Definition: atacmds.cpp:1013
std::string ata_format_attr_raw_value(const ata_smart_attribute &attr, const ata_vendor_attr_defs &defs)
Definition: atacmds.cpp:1920
int ataReadSCTTempHist(ata_device *device, ata_sct_temperature_history_table *tmh, ata_sct_status_response *sts)
Definition: atacmds.cpp:2220
int ataReadErrorLog(ata_device *device, ata_smart_errorlog *data, firmwarebug_defs firmwarebugs)
Definition: atacmds.cpp:1424
void ata_get_size_info(const ata_identify_device *id, ata_size_info &sizes)
Definition: atacmds.cpp:658
int ata_read_identity(ata_device *device, ata_identify_device *buf, bool fix_swapped_id, unsigned char *raw_buf)
Definition: atacmds.cpp:817
int TestTime(const ata_smart_values *data, int testtype)
Definition: atacmds.cpp:1700
int ataEnableSmart(ata_device *device)
Definition: atacmds.cpp:1536
bool isGeneralPurposeLoggingCapable(const ata_identify_device *identity)
Definition: atacmds.cpp:1769
int ataCheckPowerMode(ata_device *device)
Definition: atacmds.cpp:777
int ataGetSetSCTWriteCacheReordering(ata_device *device, bool enable, bool persistent, bool set)
Definition: atacmds.cpp:2349
unsigned char checksum(const void *data)
Definition: atacmds.cpp:716
bool ataReadExtSelfTestLog(ata_device *device, ata_smart_extselftestlog *log, unsigned nsectors)
Definition: atacmds.cpp:1061
int ataReadSelectiveSelfTestLog(ata_device *device, struct ata_selective_self_test_log *data)
Definition: atacmds.cpp:1184
bool isSmartTestLogCapable(const ata_smart_values *data, const ata_identify_device *identity)
Definition: atacmds.cpp:1750
int ataReadSmartValues(ata_device *device, struct ata_smart_values *data)
Definition: atacmds.cpp:967
int ataSetSCTErrorRecoveryControltime(ata_device *device, unsigned type, unsigned short time_limit, bool power_on, bool mfg_default)
Definition: atacmds.cpp:2516
int ataDoesSmartWork(ata_device *device)
Definition: atacmds.cpp:1593
uint64_t ata_get_attr_raw_value(const ata_smart_attribute &attr, const ata_vendor_attr_defs &defs)
Definition: atacmds.cpp:1846
bool dont_print_serial_number
Definition: atacmds.cpp:37
int ataReadSCTStatus(ata_device *device, ata_sct_status_response *sts)
Definition: atacmds.cpp:2188
bool ataReadExtErrorLog(ata_device *device, ata_smart_exterrlog *log, unsigned page, unsigned nsectors, firmwarebug_defs firmwarebugs)
Definition: atacmds.cpp:1491
int ataDisableSmart(ata_device *device)
Definition: atacmds.cpp:1543
int ataSetSCTTempInterval(ata_device *device, unsigned interval, bool persistent)
Definition: atacmds.cpp:2363
std::string ata_get_smart_attr_name(unsigned char id, const ata_vendor_attr_defs &defs, int rpm)
Definition: atacmds.cpp:2127
int ataGetSetSCTWriteCache(ata_device *device, unsigned short state, bool persistent, bool set)
Definition: atacmds.cpp:2356
int ataReadSmartThresholds(ata_device *device, struct ata_smart_thresholds_pvt *data)
Definition: atacmds.cpp:1518
int ataIsSmartEnabled(const ata_identify_device *drive)
Definition: atacmds.cpp:951
void ata_format_id_string(char *out, const unsigned char *in, int n)
Definition: atacmds.cpp:762
int ataReadLogDirectory(ata_device *device, ata_smart_log_directory *data, bool gpl)
Definition: atacmds.cpp:1164
bool ata_set_features(ata_device *device, unsigned char features, int sector_count)
Definition: atacmds.cpp:799
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:1796
#define ATA_ENABLE_READ_LOOK_AHEAD
Definition: atacmds.h:72
#define ATTRIBUTE_FLAGS_OTHER(x)
Definition: atacmds.h:192
#define SELECTIVE_FLAG_PENDING
Definition: atacmds.h:500
#define ATA_DISABLE_WRITE_CACHE
Definition: atacmds.h:67
#define ATTRIBUTE_FLAGS_SELFPRESERVING(x)
Definition: atacmds.h:189
bool isSupportSelfTest(const ata_smart_values *data)
Definition: atacmds.h:877
#define ATA_STANDBY
Definition: atacmds.h:61
#define SELECTIVE_SELF_TEST
Definition: atacmds.h:101
bool isSCTErrorRecoveryControlCapable(const ata_identify_device *drive)
Definition: atacmds.h:889
#define ATA_ENABLE_APM
Definition: atacmds.h:70
#define ATA_STANDBY_IMMEDIATE
Definition: atacmds.h:62
bool isSupportOfflineSurfaceScan(const ata_smart_values *data)
Definition: atacmds.h:874
#define ATA_DISABLE_AAM
Definition: atacmds.h:65
#define OFFLINE_FULL_SCAN
Definition: atacmds.h:97
#define SHORT_SELF_TEST
Definition: atacmds.h:98
#define SELECTIVE_FLAG_DOSCAN
Definition: atacmds.h:499
bool isSupportConveyanceSelfTest(const ata_smart_values *data)
Definition: atacmds.h:880
#define ATA_ENABLE_DISABLE_DSN
Definition: atacmds.h:73
#define ATA_IDLE
Definition: atacmds.h:55
void checksumwarning(const char *string)
Definition: smartctl.cpp:1485
@ RAWFMT_MIN2HOUR
Definition: atacmds.h:665
@ RAWFMT_RAW16_OPT_RAW16
Definition: atacmds.h:659
@ RAWFMT_RAW24_OPT_RAW8
Definition: atacmds.h:661
@ RAWFMT_MSEC24_HOUR32
Definition: atacmds.h:667
@ RAWFMT_RAW64
Definition: atacmds.h:657
@ RAWFMT_RAW48
Definition: atacmds.h:653
@ RAWFMT_DEFAULT
Definition: atacmds.h:650
@ RAWFMT_HALFMIN2HOUR
Definition: atacmds.h:666
@ RAWFMT_SEC2HOUR
Definition: atacmds.h:664
#define ATTRIBUTE_FLAGS_EVENTCOUNT(x)
Definition: atacmds.h:186
#define ATTRIBUTE_FLAGS_PERFORMANCE(x)
Definition: atacmds.h:180
bool isSupportAutomaticTimer(const ata_smart_values *data)
Definition: atacmds.h:868
@ ATTRFLAG_NO_WORSTVAL
Definition: atacmds.h:676
#define EXTEND_SELF_TEST
Definition: atacmds.h:99
#define ATA_ENABLE_WRITE_CACHE
Definition: atacmds.h:71
bool isSupportSelectiveSelfTest(const ata_smart_values *data)
Definition: atacmds.h:883
bool isSCTDataTableCapable(const ata_identify_device *drive)
Definition: atacmds.h:895
#define ATA_DISABLE_READ_LOOK_AHEAD
Definition: atacmds.h:68
#define ATTRIBUTE_FLAGS_PREFAILURE(x)
Definition: atacmds.h:164
#define ATA_ENABLE_AAM
Definition: atacmds.h:69
bool isSupportExecuteOfflineImmediate(const ata_smart_values *data)
Definition: atacmds.h:862
bool isSupportOfflineAbort(const ata_smart_values *data)
Definition: atacmds.h:871
#define ABORT_SELF_TEST
Definition: atacmds.h:102
#define SELECTIVE_FLAG_ACTIVE
Definition: atacmds.h:501
#define ATTRIBUTE_FLAGS_ERRORRATE(x)
Definition: atacmds.h:183
#define EXTEND_CAPTIVE_SELF_TEST
Definition: atacmds.h:104
#define CONVEYANCE_CAPTIVE_SELF_TEST
Definition: atacmds.h:105
#define CONVEYANCE_SELF_TEST
Definition: atacmds.h:100
@ BUG_SAMSUNG3
Definition: atacmds.h:717
@ BUG_NOLOGDIR
Definition: atacmds.h:714
@ BUG_SAMSUNG
Definition: atacmds.h:715
@ BUG_SAMSUNG2
Definition: atacmds.h:716
#define ATA_SECURITY_FREEZE_LOCK
Definition: atacmds.h:57
#define SHORT_CAPTIVE_SELF_TEST
Definition: atacmds.h:103
#define ATA_DISABLE_APM
Definition: atacmds.h:66
#define NUMBER_ATA_SMART_ATTRIBUTES
Definition: atacmds.h:110
#define SELECTIVE_CAPTIVE_SELF_TEST
Definition: atacmds.h:106
#define ATTRIBUTE_FLAGS_ONLINE(x)
Definition: atacmds.h:174
bool isSCTFeatureControlCapable(const ata_identify_device *drive)
Definition: atacmds.h:892
bool isSCTCapable(const ata_identify_device *drive)
Definition: atacmds.h:886
ata_attr_state
Definition: atacmds.h:902
@ ATTRSTATE_FAILED_NOW
Definition: atacmds.h:908
@ ATTRSTATE_NON_EXISTING
Definition: atacmds.h:903
@ ATTRSTATE_NO_THRESHOLD
Definition: atacmds.h:905
@ ATTRSTATE_FAILED_PAST
Definition: atacmds.h:907
@ ATTRSTATE_NO_NORMVAL
Definition: atacmds.h:904
void ata_print_identify_data(const void *id, bool all_words, int bit_level)
static void print_standby_timer(const char *msg, int timer, const ata_identify_device &drive)
Definition: ataprint.cpp:3323
static const char * sct_ptemp(signed char x, char(&buf)[20])
Definition: ataprint.cpp:2965
static void ataPrintSCTErrorRecoveryControl(bool set, unsigned short read_timer, unsigned short write_timer, bool power_on, bool mfg_default=false)
Definition: ataprint.cpp:3174
static void PrintSmartCapability(const ata_smart_values *data)
Definition: ataprint.cpp:1047
static const char * infofound(const char *output)
Definition: ataprint.cpp:40
const char * ataprint_cpp_cvsid
Definition: ataprint.cpp:36
static void ataPrintSCTCapability(const ata_identify_device *drive)
Definition: ataprint.cpp:1354
const devstat_entry_info devstat_info_0x04[]
Definition: ataprint.cpp:1708
static void PrintSmartTotalTimeCompleteOffline(const ata_smart_values *data)
Definition: ataprint.cpp:987
static void print_aam_level(const char *msg, int level, int recommended=-1)
Definition: ataprint.cpp:3199
const devstat_entry_info devstat_info_0x01[]
Definition: ataprint.cpp:1671
static void set_json_globals_from_device_statistics(int page, int offset, int64_t val)
Definition: ataprint.cpp:1774
static void print_sata_version_and_speed(unsigned short word222, unsigned short word076, unsigned short word077)
Definition: ataprint.cpp:621
static void print_ata_security_status(const char *msg, unsigned short state, unsigned short master_password_id)
Definition: ataprint.cpp:3260
static void PrintSmartOfflineCollectCap(const ata_smart_values *data)
Definition: ataprint.cpp:997
int ataPrintMain(ata_device *device, const ata_print_options &options)
Definition: ataprint.cpp:3357
static void PrintSmartOfflineStatus(const ata_smart_values *data)
Definition: ataprint.cpp:862
static void print_drive_info(const ata_identify_device *drive, const ata_size_info &sizes, int rpm, const drive_settings *dbentry, const char *dbversion)
Definition: ataprint.cpp:644
static void PrintSmartSelfExecStatus(const ata_smart_values *data, firmwarebug_defs firmwarebugs)
Definition: ataprint.cpp:890
const int num_devstat_infos
Definition: ataprint.cpp:1763
static const char * get_sata_version(unsigned short word222)
Definition: ataprint.cpp:559
const devstat_entry_info devstat_info_0x03[]
Definition: ataprint.cpp:1695
static void PrintSmartConveyanceSelfTestPollingTime(const ata_smart_values *data)
Definition: ataprint.cpp:1106
static bool is_permissive()
Definition: ataprint.cpp:46
const devstat_entry_info devstat_info_0x02[]
Definition: ataprint.cpp:1688
static int ataPrintSmartSelfTestlog(const ata_smart_selftestlog *log, bool allentries, firmwarebug_defs firmwarebugs)
Definition: ataprint.cpp:2670
static int PrintSmartErrorlog(const ata_smart_errorlog *data, firmwarebug_defs firmwarebugs)
Definition: ataprint.cpp:2198
static const char * get_ata_major_version(const ata_identify_device *drive)
Definition: ataprint.cpp:436
static const char * sct_device_state_msg(unsigned char state)
Definition: ataprint.cpp:3003
static const char * sct_pbar(int x, char(&buf)[64])
Definition: ataprint.cpp:2981
static std::string format_st_er_desc(unsigned char CR, unsigned char FR, unsigned char ST, unsigned char ER, unsigned short SC, const ata_smart_errorlog_error_struct *lba28_regs, const ata_smart_exterrlog_error *lba48_regs)
Definition: ataprint.cpp:67
static void ataPrintSelectiveSelfTestLog(const ata_selective_self_test_log *log, const ata_smart_values *sv)
Definition: ataprint.cpp:2822
static const char * get_pata_version(unsigned short word222, char(&buf)[32])
Definition: ataprint.cpp:546
static bool print_pending_defects_log(ata_device *device, unsigned nsectors, unsigned max_entries)
Definition: ataprint.cpp:2026
static void PrintSmartAttribWithThres(const ata_smart_values *data, const ata_smart_thresholds_pvt *thresholds, const ata_vendor_attr_defs &defs, int rpm, int onlyfailed, unsigned char format)
Definition: ataprint.cpp:1197
static void PrintSmartExtendedSelfTestPollingTime(const ata_smart_values *data)
Definition: ataprint.cpp:1093
#define P(n)
static void print_device_statistics_page(const json::ref &jref, const unsigned char *data, int page)
Definition: ataprint.cpp:1797
static bool print_device_statistics(ata_device *device, unsigned nsectors, const std::vector< int > &single_pages, bool all_pages, bool ssd_page, bool use_gplog)
Definition: ataprint.cpp:1909
static void PrintSataPhyEventCounters(const unsigned char *data, bool reset)
Definition: ataprint.cpp:2089
static void PrintSmartErrorLogCapability(const ata_smart_values *data, const ata_identify_device *identity)
Definition: ataprint.cpp:1072
static void PrintSmartShortSelfTestPollingTime(const ata_smart_values *data)
Definition: ataprint.cpp:1080
static const char * OfflineDataCollectionStatus(unsigned char status_byte)
Definition: ataprint.cpp:832
static int find_msb(unsigned short word)
Definition: ataprint.cpp:428
static std::string format_milliseconds(unsigned msec)
Definition: ataprint.cpp:2163
static void set_json_globals_from_smart_attrib(int id, const char *name, const ata_vendor_attr_defs &defs, uint64_t rawval)
Definition: ataprint.cpp:1143
static void PrintGeneralSmartValues(const ata_smart_values *data, const ata_identify_device *drive, firmwarebug_defs firmwarebugs)
Definition: ataprint.cpp:1374
static void PrintLogPages(const char *type, const unsigned char *data, unsigned char logaddr, unsigned page, unsigned num_pages, unsigned max_pages)
Definition: ataprint.cpp:1630
static void sct_jtemp2(const json::ref &jref, const char *name, signed char x)
Definition: ataprint.cpp:2973
static unsigned GetNumLogSectors(const ata_smart_log_directory *logdir, unsigned logaddr, bool gpl)
Definition: ataprint.cpp:1410
const ata_smart_log_directory * fake_logdir(ata_smart_log_directory *logdir, const ata_print_options &options)
Definition: ataprint.cpp:1525
static void print_apm_level(const char *msg, int level)
Definition: ataprint.cpp:3230
const devstat_entry_info devstat_info_0x07[]
Definition: ataprint.cpp:1743
static const char * get_error_log_state_desc(unsigned state)
Definition: ataprint.cpp:2182
static int ataPrintSCTTempHist(const ata_sct_temperature_history_table *tmh)
Definition: ataprint.cpp:3102
const devstat_entry_info devstat_info_0x00[]
Definition: ataprint.cpp:1666
static const char * get_log_rw(unsigned logaddr)
Definition: ataprint.cpp:1496
static const char * GetLogName(unsigned logaddr)
Definition: ataprint.cpp:1426
const devstat_entry_info devstat_info_0x05[]
Definition: ataprint.cpp:1717
static int PrintSmartExtSelfTestLog(const ata_smart_extselftestlog *log, unsigned nsectors, unsigned max_entries)
Definition: ataprint.cpp:2738
static void jset_sata_speed(const char *key, int value, int speed, const char *str)
Definition: ataprint.cpp:602
static const char * get_sata_speed(int speed)
Definition: ataprint.cpp:583
static int find_failed_attr(const ata_smart_values *data, const ata_smart_thresholds_pvt *thresholds, const ata_vendor_attr_defs &defs, int onlyfailed)
Definition: ataprint.cpp:1122
static int ataPrintSCTStatus(const ata_sct_status_response *sts)
Definition: ataprint.cpp:3017
static const char * get_device_statistics_page_name(int page)
Definition: ataprint.cpp:1765
const devstat_entry_info devstat_info_0x06[]
Definition: ataprint.cpp:1735
static const char * get_ata_minor_version(const ata_identify_device *drive)
Definition: ataprint.cpp:462
static int ataPrintSmartSelfTestEntry(const json::ref &jref, 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: ataprint.cpp:2575
static int PrintSmartExtErrorLog(ata_device *device, const firmwarebug_defs &firmwarebugs, const ata_smart_exterrlog *log, unsigned nsectors, unsigned max_errors)
Definition: ataprint.cpp:2354
static void PrintLogDirectories(const ata_smart_log_directory *gplogdir, const ata_smart_log_directory *smartlogdir)
Definition: ataprint.cpp:1541
const devstat_entry_info * devstat_infos[]
Definition: ataprint.cpp:1749
static const char * get_form_factor(unsigned short word168)
Definition: ataprint.cpp:408
#define ATAPRINT_H_CVSID
Definition: ataprint.h:16
ATA device access.
virtual bool ata_identify_is_cached() const
Return true if OS caches ATA identify sector.
bool is_set(firmwarebug_t bug) const
Definition: atacmds.h:728
Reference to a JSON element.
Definition: json.h:105
void set_unsafe_uint64(uint64_t value)
Definition: json.cpp:193
bool is_enabled() const
Return true if enabled.
Definition: json.h:187
unsigned char * data()
Definition: utility.h:148
int get_errno() const
Get last error number.
const char * get_errmsg() const
Get last error message.
virtual bool is_syscall_unsup() const
Return true if last error indicates an unsupported system call.
void clear_err()
Clear last error info.
bool ataIsSeagate(const ata_identify_device &drive, const drive_settings *dbentry)
Definition: farmcmds.cpp:33
bool ataReadFarmLog(ata_device *device, ataFarmLog &farmLog, unsigned nsectors)
Definition: farmcmds.cpp:56
void ataPrintFarmLog(const ataFarmLog &farmLog)
Definition: farmprint.cpp:150
const drive_settings * lookup_drive_apply_presets(const ata_identify_device *drive, ata_vendor_attr_defs &defs, firmwarebug_defs &firmwarebugs, std::string &dbversion)
void show_presets(const ata_identify_device *drive)
u8 cmd
Definition: megaraid.h:1
u16 flags
Definition: megaraid.h:14
u32 count
Definition: megaraid.h:1
u8 b[12]
Definition: megaraid.h:17
u16 s[6]
Definition: megaraid.h:18
ptr_t data
Definition: megaraid.h:15
u32 size
Definition: megaraid.h:0
uint8_t id
union @43 entry
unsigned char failuretest_permissive
Definition: smartctl.cpp:1457
static uint64_t sg_get_unaligned_le64(const void *p)
Definition: sg_unaligned.h:303
static uint32_t sg_get_unaligned_le32(const void *p)
Definition: sg_unaligned.h:297
void jout_startup_datetime(const char *prefix)
Definition: smartctl.cpp:1450
json jglb
Definition: smartctl.cpp:53
void failuretest(failure_type type, int returnvalue)
Definition: smartctl.cpp:1462
bool printing_is_switchable
Definition: smartctl.cpp:49
#define FAILATTR
Definition: smartctl.h:39
#define FAILERR
Definition: smartctl.h:46
void void jinf(const char *fmt,...) __attribute_format_printf(1
#define FAILID
Definition: smartctl.h:30
#define FAILSTATUS
Definition: smartctl.h:36
#define FAILAGE
Definition: smartctl.h:43
void print_off()
Definition: smartctl.h:79
#define FAILSMART
Definition: smartctl.h:33
void void void jwrn(const char *fmt,...) __attribute_format_printf(1
void void void void jerr(const char *fmt,...) __attribute_format_printf(1
void jout(const char *fmt,...) __attribute_format_printf(1
@ OPTIONAL_CMD
Definition: smartctl.h:57
@ MANDATORY_CMD
Definition: smartctl.h:58
void print_on()
Definition: smartctl.h:74
#define FAILLOG
Definition: smartctl.h:49
void pout(const char *fmt,...)
Definition: smartd.cpp:1347
unsigned char model[40]
Definition: atacmds.h:120
unsigned short minor_rev_num
Definition: atacmds.h:123
unsigned short major_rev_num
Definition: atacmds.h:122
unsigned short words047_079[33]
Definition: atacmds.h:121
unsigned short cfs_enable_1
Definition: atacmds.h:127
unsigned short words088_255[168]
Definition: atacmds.h:130
unsigned short command_set_2
Definition: atacmds.h:125
unsigned short word086
Definition: atacmds.h:128
unsigned char fw_rev[8]
Definition: atacmds.h:119
unsigned short command_set_1
Definition: atacmds.h:124
unsigned char serial_no[20]
Definition: atacmds.h:117
unsigned page
Definition: ataprint.h:25
unsigned char logaddr
Definition: ataprint.h:24
unsigned nsectors
Definition: ataprint.h:26
bool sct_wcache_sct_get
Definition: ataprint.h:101
bool sct_temp_hist
Definition: ataprint.h:54
bool smart_auto_offl_disable
Definition: ataprint.h:61
bool sct_wcache_reorder_get
Definition: ataprint.h:98
bool smart_auto_save_enable
Definition: ataprint.h:62
bool smart_general_values
Definition: ataprint.h:36
unsigned sct_erc_writetime
Definition: ataprint.h:57
bool devstat_all_pages
Definition: ataprint.h:49
bool set_security_freeze
Definition: ataprint.h:95
unsigned pending_defects_log
Definition: ataprint.h:52
bool set_standby_now
Definition: ataprint.h:93
int identify_word_level
Definition: ataprint.h:34
int smart_selftest_type
Definition: ataprint.h:64
bool smart_selftest_log
Definition: ataprint.h:39
int identify_bit_level
Definition: ataprint.h:34
bool smart_disable
Definition: ataprint.h:60
ata_selective_selftest_args smart_selective_args
Definition: ataprint.h:66
unsigned char powerexit
Definition: ataprint.h:82
std::vector< int > devstat_pages
Definition: ataprint.h:50
bool smart_check_status
Definition: ataprint.h:35
bool farm_log_suggest
Definition: ataprint.h:108
unsigned smart_ext_error_log
Definition: ataprint.h:43
bool fix_swapped_id
Definition: ataprint.h:75
unsigned smart_ext_selftest_log
Definition: ataprint.h:44
firmwarebug_defs firmwarebugs
Definition: ataprint.h:74
bool ignore_presets
Definition: ataprint.h:79
unsigned char powermode
Definition: ataprint.h:81
bool get_lookahead
Definition: ataprint.h:90
bool sataphy_reset
Definition: ataprint.h:58
unsigned char output_format
Definition: ataprint.h:72
int sct_wcache_reorder_set
Definition: ataprint.h:99
bool sct_temp_int_pers
Definition: ataprint.h:69
bool smart_selftest_force
Definition: ataprint.h:65
bool smart_selective_selftest_log
Definition: ataprint.h:40
bool devstat_ssd_page
Definition: ataprint.h:49
ata_vendor_attr_defs attribute_defs
Definition: ataprint.h:77
unsigned sct_temp_int
Definition: ataprint.h:68
unsigned sct_erc_readtime
Definition: ataprint.h:57
bool smart_vendor_attrib
Definition: ataprint.h:37
std::vector< ata_log_request > log_requests
Definition: ataprint.h:47
bool sct_wcache_sct_set_pers
Definition: ataprint.h:103
bool retry_error_log
Definition: ataprint.h:45
bool sct_wcache_reorder_set_pers
Definition: ataprint.h:100
bool smart_auto_offl_enable
Definition: ataprint.h:61
bool retry_selftest_log
Definition: ataprint.h:45
bool smart_error_log
Definition: ataprint.h:38
bool smart_auto_save_disable
Definition: ataprint.h:62
int sct_wcache_sct_set
Definition: ataprint.h:102
unsigned int over_limit_count
Definition: atacmds.h:532
unsigned short min_erc_time
Definition: atacmds.h:535
unsigned short sct_version
Definition: atacmds.h:515
unsigned short sct_spec
Definition: atacmds.h:516
unsigned short format_version
Definition: atacmds.h:514
signed char life_max_temp
Definition: atacmds.h:530
unsigned char vendor_specific[32]
Definition: atacmds.h:537
signed char max_temp
Definition: atacmds.h:528
unsigned char device_state
Definition: atacmds.h:518
signed char max_op_limit
Definition: atacmds.h:531
signed char min_temp
Definition: atacmds.h:527
signed char hda_temp
Definition: atacmds.h:526
unsigned int under_limit_count
Definition: atacmds.h:533
signed char life_min_temp
Definition: atacmds.h:529
unsigned short smart_status
Definition: atacmds.h:534
unsigned short sampling_period
Definition: atacmds.h:590
unsigned short flags
Definition: atacmds.h:490
struct test_span span[5]
Definition: atacmds.h:485
unsigned short pendingtime
Definition: atacmds.h:492
unsigned short logversion
Definition: atacmds.h:484
unsigned short currentspan
Definition: atacmds.h:489
unsigned phy_sector_size
Definition: atacmds.h:988
uint64_t capacity
Definition: atacmds.h:986
uint64_t sectors
Definition: atacmds.h:985
unsigned log_sector_offset
Definition: atacmds.h:989
unsigned log_sector_size
Definition: atacmds.h:987
unsigned char id
Definition: atacmds.h:138
unsigned char current
Definition: atacmds.h:142
unsigned short flags
Definition: atacmds.h:141
unsigned char worst
Definition: atacmds.h:143
unsigned char error_register
Definition: atacmds.h:256
struct ata_smart_errorlog_command_struct commands[5]
Definition: atacmds.h:290
struct ata_smart_errorlog_error_struct error_struct
Definition: atacmds.h:291
unsigned char state
Definition: atacmds.h:359
unsigned char device_control_register
Definition: atacmds.h:345
unsigned char lba_low_register_hi
Definition: atacmds.h:350
unsigned char lba_low_register
Definition: atacmds.h:349
unsigned char count_register
Definition: atacmds.h:347
unsigned char error_register
Definition: atacmds.h:346
unsigned char count_register_hi
Definition: atacmds.h:348
unsigned char lba_high_register_hi
Definition: atacmds.h:354
unsigned char device_register
Definition: atacmds.h:355
unsigned char status_register
Definition: atacmds.h:356
unsigned char lba_mid_register
Definition: atacmds.h:351
unsigned char lba_mid_register_hi
Definition: atacmds.h:352
unsigned short timestamp
Definition: atacmds.h:360
unsigned char lba_high_register
Definition: atacmds.h:353
unsigned short error_log_index
Definition: atacmds.h:383
unsigned char reserved1
Definition: atacmds.h:382
ata_smart_exterrlog_error_log error_logs[4]
Definition: atacmds.h:384
unsigned short device_error_count
Definition: atacmds.h:385
unsigned char version
Definition: atacmds.h:381
struct ata_smart_extselftestlog_desc log_descs[19]
Definition: atacmds.h:447
unsigned char version
Definition: atacmds.h:444
unsigned short log_desc_index
Definition: atacmds.h:446
unsigned char reserved1
Definition: atacmds.h:445
struct ata_smart_log_entry entry[255]
Definition: atacmds.h:467
unsigned short int logversion
Definition: atacmds.h:466
unsigned char reserved
Definition: atacmds.h:459
unsigned char numsectors
Definition: atacmds.h:458
unsigned char mostrecenttest
Definition: atacmds.h:412
struct ata_smart_selftestlog_struct selftest_struct[21]
Definition: atacmds.h:410
unsigned short int revnumber
Definition: atacmds.h:409
struct ata_smart_threshold_entry thres_entries[NUMBER_ATA_SMART_ATTRIBUTES]
Definition: atacmds.h:244
unsigned char self_test_exec_status
Definition: atacmds.h:202
unsigned char offline_data_collection_status
Definition: atacmds.h:201
Definition: ataprint.cpp:1661
const char * name
Definition: ataprint.cpp:1663
short size
Definition: ataprint.cpp:1662
const char * modelfamily
Definition: knowndrives.h:19
const char * warningmsg
Definition: knowndrives.h:22
uint64_t start
Definition: atacmds.h:476
uint64_t end
Definition: atacmds.h:477
void dateandtimezoneepoch(char(&buffer)[DATEANDEPOCHLEN], time_t tval)
Definition: utility.cpp:349
const char * format_capacity(char *str, int strsize, uint64_t val, const char *decimal_point)
Definition: utility.cpp:748
const char * format_with_thousands_sep(char *str, int strsize, uint64_t val, const char *thousands_sep)
Definition: utility.cpp:716
std::string strprintf(const char *fmt,...)
Definition: utility.cpp:799
bool nonempty(const void *data, int size)
Definition: utility.cpp:682
const char * packetdevicetype(int type)
Definition: utility.cpp:315
struct tm * time_to_tm_local(struct tm *tp, time_t t)
Definition: utility.cpp:326
#define DATEANDEPOCHLEN
Definition: utility.h:64
bool str_starts_with(const char *str, const char *prefix)
Definition: utility.h:52