]> git.proxmox.com Git - mirror_smartmontools-debian.git/blob - ataprint.cpp
Imported Upstream version 5.42+svn3561
[mirror_smartmontools-debian.git] / ataprint.cpp
1 /*
2 * ataprint.cpp
3 *
4 * Home page of code is: http://smartmontools.sourceforge.net
5 *
6 * Copyright (C) 2002-11 Bruce Allen <smartmontools-support@lists.sourceforge.net>
7 * Copyright (C) 2008-12 Christian Franke <smartmontools-support@lists.sourceforge.net>
8 * Copyright (C) 1999-2000 Michael Cornwell <cornwell@acm.org>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2, or (at your option)
13 * any later version.
14 *
15 * You should have received a copy of the GNU General Public License
16 * (for example COPYING); if not, write to the Free
17 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 *
19 * This code was originally developed as a Senior Thesis by Michael Cornwell
20 * at the Concurrent Systems Laboratory (now part of the Storage Systems
21 * Research Center), Jack Baskin School of Engineering, University of
22 * California, Santa Cruz. http://ssrc.soe.ucsc.edu/
23 *
24 */
25
26 #include "config.h"
27
28 #include <ctype.h>
29 #include <errno.h>
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include <string.h>
33
34 #include "int64.h"
35 #include "atacmdnames.h"
36 #include "atacmds.h"
37 #include "dev_interface.h"
38 #include "ataprint.h"
39 #include "smartctl.h"
40 #include "utility.h"
41 #include "knowndrives.h"
42
43 const char * ataprint_cpp_cvsid = "$Id: ataprint.cpp 3554 2012-06-01 20:11:46Z chrfranke $"
44 ATAPRINT_H_CVSID;
45
46
47 static const char * infofound(const char *output) {
48 return (*output ? output : "[No Information Found]");
49 }
50
51 // Return true if '-T permissive' is specified,
52 // used to ignore missing capabilities
53 static bool is_permissive()
54 {
55 if (!failuretest_permissive)
56 return false;
57 failuretest_permissive--;
58 return true;
59 }
60
61 /* For the given Command Register (CR) and Features Register (FR), attempts
62 * to construct a string that describes the contents of the Status
63 * Register (ST) and Error Register (ER). The caller passes the string
64 * buffer and the return value is a pointer to this string. If the
65 * meanings of the flags of the error register are not known for the given
66 * command then it returns NULL.
67 *
68 * The meanings of the flags of the error register for all commands are
69 * described in the ATA spec and could all be supported here in theory.
70 * Currently, only a few commands are supported (those that have been seen
71 * to produce errors). If many more are to be added then this function
72 * should probably be redesigned.
73 */
74
75 static const char * construct_st_er_desc(
76 char * s,
77 unsigned char CR, unsigned char FR,
78 unsigned char ST, unsigned char ER,
79 unsigned short SC,
80 const ata_smart_errorlog_error_struct * lba28_regs,
81 const ata_smart_exterrlog_error * lba48_regs
82 )
83 {
84 const char *error_flag[8];
85 int i, print_lba=0, print_sector=0;
86
87 // Set of character strings corresponding to different error codes.
88 // Please keep in alphabetic order if you add more.
89 const char *abrt = "ABRT"; // ABORTED
90 const char *amnf = "AMNF"; // ADDRESS MARK NOT FOUND
91 const char *ccto = "CCTO"; // COMMAND COMPLETION TIMED OUT
92 const char *eom = "EOM"; // END OF MEDIA
93 const char *icrc = "ICRC"; // INTERFACE CRC ERROR
94 const char *idnf = "IDNF"; // ID NOT FOUND
95 const char *ili = "ILI"; // MEANING OF THIS BIT IS COMMAND-SET SPECIFIC
96 const char *mc = "MC"; // MEDIA CHANGED
97 const char *mcr = "MCR"; // MEDIA CHANGE REQUEST
98 const char *nm = "NM"; // NO MEDIA
99 const char *obs = "obs"; // OBSOLETE
100 const char *tk0nf = "TK0NF"; // TRACK 0 NOT FOUND
101 const char *unc = "UNC"; // UNCORRECTABLE
102 const char *wp = "WP"; // WRITE PROTECTED
103
104 /* If for any command the Device Fault flag of the status register is
105 * not used then used_device_fault should be set to 0 (in the CR switch
106 * below)
107 */
108 int uses_device_fault = 1;
109
110 /* A value of NULL means that the error flag isn't used */
111 for (i = 0; i < 8; i++)
112 error_flag[i] = NULL;
113
114 switch (CR) {
115 case 0x10: // RECALIBRATE
116 error_flag[2] = abrt;
117 error_flag[1] = tk0nf;
118 break;
119 case 0x20: /* READ SECTOR(S) */
120 case 0x21: // READ SECTOR(S)
121 case 0x24: // READ SECTOR(S) EXT
122 case 0xC4: /* READ MULTIPLE */
123 case 0x29: // READ MULTIPLE EXT
124 error_flag[6] = unc;
125 error_flag[5] = mc;
126 error_flag[4] = idnf;
127 error_flag[3] = mcr;
128 error_flag[2] = abrt;
129 error_flag[1] = nm;
130 error_flag[0] = amnf;
131 print_lba=1;
132 break;
133 case 0x22: // READ LONG (with retries)
134 case 0x23: // READ LONG (without retries)
135 error_flag[4] = idnf;
136 error_flag[2] = abrt;
137 error_flag[0] = amnf;
138 print_lba=1;
139 break;
140 case 0x2a: // READ STREAM DMA
141 case 0x2b: // READ STREAM PIO
142 if (CR==0x2a)
143 error_flag[7] = icrc;
144 error_flag[6] = unc;
145 error_flag[5] = mc;
146 error_flag[4] = idnf;
147 error_flag[3] = mcr;
148 error_flag[2] = abrt;
149 error_flag[1] = nm;
150 error_flag[0] = ccto;
151 print_lba=1;
152 print_sector=SC;
153 break;
154 case 0x3A: // WRITE STREAM DMA
155 case 0x3B: // WRITE STREAM PIO
156 if (CR==0x3A)
157 error_flag[7] = icrc;
158 error_flag[6] = wp;
159 error_flag[5] = mc;
160 error_flag[4] = idnf;
161 error_flag[3] = mcr;
162 error_flag[2] = abrt;
163 error_flag[1] = nm;
164 error_flag[0] = ccto;
165 print_lba=1;
166 print_sector=SC;
167 break;
168 case 0x25: // READ DMA EXT
169 case 0x26: // READ DMA QUEUED EXT
170 case 0xC7: // READ DMA QUEUED
171 case 0xC8: // READ DMA (with retries)
172 case 0xC9: // READ DMA (without retries, obsolete since ATA-5)
173 case 0x60: // READ FPDMA QUEUED (NCQ)
174 error_flag[7] = icrc;
175 error_flag[6] = unc;
176 error_flag[5] = mc;
177 error_flag[4] = idnf;
178 error_flag[3] = mcr;
179 error_flag[2] = abrt;
180 error_flag[1] = nm;
181 error_flag[0] = amnf;
182 print_lba=1;
183 if (CR==0x25 || CR==0xC8)
184 print_sector=SC;
185 break;
186 case 0x30: /* WRITE SECTOR(S) */
187 case 0x31: // WRITE SECTOR(S)
188 case 0x34: // WRITE SECTOR(S) EXT
189 case 0xC5: /* WRITE MULTIPLE */
190 case 0x39: // WRITE MULTIPLE EXT
191 case 0xCE: // WRITE MULTIPLE FUA EXT
192 error_flag[6] = wp;
193 error_flag[5] = mc;
194 error_flag[4] = idnf;
195 error_flag[3] = mcr;
196 error_flag[2] = abrt;
197 error_flag[1] = nm;
198 print_lba=1;
199 break;
200 case 0x32: // WRITE LONG (with retries)
201 case 0x33: // WRITE LONG (without retries)
202 error_flag[4] = idnf;
203 error_flag[2] = abrt;
204 print_lba=1;
205 break;
206 case 0x3C: // WRITE VERIFY
207 error_flag[6] = unc;
208 error_flag[4] = idnf;
209 error_flag[2] = abrt;
210 error_flag[0] = amnf;
211 print_lba=1;
212 break;
213 case 0x40: // READ VERIFY SECTOR(S) with retries
214 case 0x41: // READ VERIFY SECTOR(S) without retries
215 case 0x42: // READ VERIFY SECTOR(S) EXT
216 error_flag[6] = unc;
217 error_flag[5] = mc;
218 error_flag[4] = idnf;
219 error_flag[3] = mcr;
220 error_flag[2] = abrt;
221 error_flag[1] = nm;
222 error_flag[0] = amnf;
223 print_lba=1;
224 break;
225 case 0xA0: /* PACKET */
226 /* Bits 4-7 are all used for sense key (a 'command packet set specific error
227 * indication' according to the ATA/ATAPI-7 standard), so "Sense key" will
228 * be repeated in the error description string if more than one of those
229 * bits is set.
230 */
231 error_flag[7] = "Sense key (bit 3)",
232 error_flag[6] = "Sense key (bit 2)",
233 error_flag[5] = "Sense key (bit 1)",
234 error_flag[4] = "Sense key (bit 0)",
235 error_flag[2] = abrt;
236 error_flag[1] = eom;
237 error_flag[0] = ili;
238 break;
239 case 0xA1: /* IDENTIFY PACKET DEVICE */
240 case 0xEF: /* SET FEATURES */
241 case 0x00: /* NOP */
242 case 0xC6: /* SET MULTIPLE MODE */
243 error_flag[2] = abrt;
244 break;
245 case 0x2F: // READ LOG EXT
246 error_flag[6] = unc;
247 error_flag[4] = idnf;
248 error_flag[2] = abrt;
249 error_flag[0] = obs;
250 break;
251 case 0x3F: // WRITE LOG EXT
252 error_flag[4] = idnf;
253 error_flag[2] = abrt;
254 error_flag[0] = obs;
255 break;
256 case 0xB0: /* SMART */
257 switch(FR) {
258 case 0xD0: // SMART READ DATA
259 case 0xD1: // SMART READ ATTRIBUTE THRESHOLDS
260 case 0xD5: /* SMART READ LOG */
261 error_flag[6] = unc;
262 error_flag[4] = idnf;
263 error_flag[2] = abrt;
264 error_flag[0] = obs;
265 break;
266 case 0xD6: /* SMART WRITE LOG */
267 error_flag[4] = idnf;
268 error_flag[2] = abrt;
269 error_flag[0] = obs;
270 break;
271 case 0xD2: // Enable/Disable Attribute Autosave
272 case 0xD3: // SMART SAVE ATTRIBUTE VALUES (ATA-3)
273 case 0xD8: // SMART ENABLE OPERATIONS
274 case 0xD9: /* SMART DISABLE OPERATIONS */
275 case 0xDA: /* SMART RETURN STATUS */
276 case 0xDB: // Enable/Disable Auto Offline (SFF)
277 error_flag[2] = abrt;
278 break;
279 case 0xD4: // SMART EXECUTE IMMEDIATE OFFLINE
280 error_flag[4] = idnf;
281 error_flag[2] = abrt;
282 break;
283 default:
284 return NULL;
285 break;
286 }
287 break;
288 case 0xB1: /* DEVICE CONFIGURATION */
289 switch (FR) {
290 case 0xC0: /* DEVICE CONFIGURATION RESTORE */
291 error_flag[2] = abrt;
292 break;
293 default:
294 return NULL;
295 break;
296 }
297 break;
298 case 0xCA: // WRITE DMA (with retries)
299 case 0xCB: // WRITE DMA (without retries, obsolete since ATA-5)
300 case 0x35: // WRITE DMA EXT
301 case 0x3D: // WRITE DMA FUA EXT
302 case 0xCC: // WRITE DMA QUEUED
303 case 0x36: // WRITE DMA QUEUED EXT
304 case 0x3E: // WRITE DMA QUEUED FUA EXT
305 case 0x61: // WRITE FPDMA QUEUED (NCQ)
306 error_flag[7] = icrc;
307 error_flag[6] = wp;
308 error_flag[5] = mc;
309 error_flag[4] = idnf;
310 error_flag[3] = mcr;
311 error_flag[2] = abrt;
312 error_flag[1] = nm;
313 error_flag[0] = amnf;
314 print_lba=1;
315 if (CR==0x35)
316 print_sector=SC;
317 break;
318 case 0xE4: // READ BUFFER
319 case 0xE8: // WRITE BUFFER
320 error_flag[2] = abrt;
321 break;
322 default:
323 return NULL;
324 }
325
326 s[0] = '\0';
327
328 /* We ignore any status flags other than Device Fault and Error */
329
330 if (uses_device_fault && (ST & (1 << 5))) {
331 strcat(s, "Device Fault");
332 if (ST & 1) // Error flag
333 strcat(s, "; ");
334 }
335 if (ST & 1) { // Error flag
336 int count = 0;
337
338 strcat(s, "Error: ");
339 for (i = 7; i >= 0; i--)
340 if ((ER & (1 << i)) && (error_flag[i])) {
341 if (count++ > 0)
342 strcat(s, ", ");
343 strcat(s, error_flag[i]);
344 }
345 }
346
347 // If the error was a READ or WRITE error, print the Logical Block
348 // Address (LBA) at which the read or write failed.
349 if (print_lba) {
350 char tmp[128];
351 // print number of sectors, if known, and append to print string
352 if (print_sector) {
353 snprintf(tmp, 128, " %d sectors", print_sector);
354 strcat(s, tmp);
355 }
356
357 if (lba28_regs) {
358 unsigned lba;
359 // bits 24-27: bits 0-3 of DH
360 lba = 0xf & lba28_regs->drive_head;
361 lba <<= 8;
362 // bits 16-23: CH
363 lba |= lba28_regs->cylinder_high;
364 lba <<= 8;
365 // bits 8-15: CL
366 lba |= lba28_regs->cylinder_low;
367 lba <<= 8;
368 // bits 0-7: SN
369 lba |= lba28_regs->sector_number;
370 snprintf(tmp, 128, " at LBA = 0x%08x = %u", lba, lba);
371 strcat(s, tmp);
372 }
373 else if (lba48_regs) {
374 // This assumes that upper LBA registers are 0 for 28-bit commands
375 // (TODO: detect 48-bit commands above)
376 uint64_t lba48;
377 lba48 = lba48_regs->lba_high_register_hi;
378 lba48 <<= 8;
379 lba48 |= lba48_regs->lba_mid_register_hi;
380 lba48 <<= 8;
381 lba48 |= lba48_regs->lba_low_register_hi;
382 lba48 |= lba48_regs->device_register & 0xf;
383 lba48 <<= 8;
384 lba48 |= lba48_regs->lba_high_register;
385 lba48 <<= 8;
386 lba48 |= lba48_regs->lba_mid_register;
387 lba48 <<= 8;
388 lba48 |= lba48_regs->lba_low_register;
389 snprintf(tmp, 128, " at LBA = 0x%08"PRIx64" = %"PRIu64, lba48, lba48);
390 strcat(s, tmp);
391 }
392 }
393
394 return s;
395 }
396
397 static inline const char * construct_st_er_desc(char * s,
398 const ata_smart_errorlog_struct * data)
399 {
400 return construct_st_er_desc(s,
401 data->commands[4].commandreg,
402 data->commands[4].featuresreg,
403 data->error_struct.status,
404 data->error_struct.error_register,
405 data->error_struct.sector_count,
406 &data->error_struct, (const ata_smart_exterrlog_error *)0);
407 }
408
409 static inline const char * construct_st_er_desc(char * s,
410 const ata_smart_exterrlog_error_log * data)
411 {
412 return construct_st_er_desc(s,
413 data->commands[4].command_register,
414 data->commands[4].features_register,
415 data->error.status_register,
416 data->error.error_register,
417 data->error.count_register_hi << 8 | data->error.count_register,
418 (const ata_smart_errorlog_error_struct *)0, &data->error);
419 }
420
421 static void print_drive_info(const ata_identify_device * drive,
422 const ata_size_info & sizes,
423 const drive_settings * dbentry)
424 {
425 // format drive information (with byte swapping as needed)
426 char model[40+1], serial[20+1], firmware[8+1];
427 ata_format_id_string(model, drive->model, sizeof(model)-1);
428 ata_format_id_string(serial, drive->serial_no, sizeof(serial)-1);
429 ata_format_id_string(firmware, drive->fw_rev, sizeof(firmware)-1);
430
431 // Print model family if known
432 if (dbentry && *dbentry->modelfamily)
433 pout("Model Family: %s\n", dbentry->modelfamily);
434
435 pout("Device Model: %s\n", infofound(model));
436 if (!dont_print_serial_number) {
437 pout("Serial Number: %s\n", infofound(serial));
438
439 unsigned oui = 0; uint64_t unique_id = 0;
440 int naa = ata_get_wwn(drive, oui, unique_id);
441 if (naa >= 0)
442 pout("LU WWN Device Id: %x %06x %09"PRIx64"\n", naa, oui, unique_id);
443 }
444 pout("Firmware Version: %s\n", infofound(firmware));
445
446 if (sizes.capacity) {
447 // Print capacity
448 char num[64], cap[32];
449 pout("User Capacity: %s bytes [%s]\n",
450 format_with_thousands_sep(num, sizeof(num), sizes.capacity),
451 format_capacity(cap, sizeof(cap), sizes.capacity));
452
453 // Print sector sizes.
454 if (sizes.phy_sector_size == sizes.log_sector_size)
455 pout("Sector Size: %u bytes logical/physical\n", sizes.log_sector_size);
456 else {
457 pout("Sector Sizes: %u bytes logical, %u bytes physical",
458 sizes.log_sector_size, sizes.phy_sector_size);
459 if (sizes.log_sector_offset)
460 pout(" (offset %u bytes)", sizes.log_sector_offset);
461 pout("\n");
462 }
463 }
464
465 // See if drive is recognized
466 pout("Device is: %s\n", !dbentry ?
467 "Not in smartctl database [for details use: -P showall]":
468 "In smartctl database [for details use: -P show]");
469
470 // now get ATA version info
471 const char *description; unsigned short minorrev;
472 int version = ataVersionInfo(&description, drive, &minorrev);
473
474 // SMART Support was first added into the ATA/ATAPI-3 Standard with
475 // Revision 3 of the document, July 25, 1995. Look at the "Document
476 // Status" revision commands at the beginning of
477 // http://www.t13.org/Documents/UploadedDocuments/project/d2008r7b-ATA-3.pdf
478 // to see this. So it's not enough to check if we are ATA-3.
479 // Version=-3 indicates ATA-3 BEFORE Revision 3.
480 // Version=0 indicates that no info is found. This may happen if
481 // the OS provides only part of the IDENTIFY data.
482
483 std::string majorstr, minorstr;
484 if (version) {
485 if (version <= 8) {
486 majorstr = strprintf("%d", abs(version));
487 if (description)
488 minorstr = description;
489 else if (!minorrev)
490 minorstr = "Exact ATA specification draft version not indicated";
491 else
492 minorstr = strprintf("Not recognized. Minor revision code: 0x%04x", minorrev);
493 }
494 else {
495 // Bit 9 in word 80 of ATA IDENTIFY data does not mean "ATA-9" but "ACS-2"
496 // TODO: handle this in ataVersionInfo()
497 majorstr = "8";
498 if (description)
499 minorstr = description;
500 else if (!minorrev)
501 minorstr = strprintf("ACS-%d (revision not indicated)", version-9+2);
502 else
503 minorstr = strprintf("ACS-%d (unknown minor revision code: 0x%04x)", version-9+2, minorrev);
504 }
505 }
506
507 pout("ATA Version is: %s\n", infofound(majorstr.c_str()));
508 pout("ATA Standard is: %s\n", infofound(minorstr.c_str()));
509
510 // print current time and date and timezone
511 char timedatetz[DATEANDEPOCHLEN]; dateandtimezone(timedatetz);
512 pout("Local Time is: %s\n", timedatetz);
513
514 // Print warning message, if there is one
515 if (dbentry && *dbentry->warningmsg)
516 pout("\n==> WARNING: %s\n\n", dbentry->warningmsg);
517
518 if (!version || version >= 3)
519 return;
520
521 pout("SMART is only available in ATA Version 3 Revision 3 or greater.\n");
522 pout("We will try to proceed in spite of this.\n");
523 }
524
525 static const char *OfflineDataCollectionStatus(unsigned char status_byte)
526 {
527 unsigned char stat=status_byte & 0x7f;
528
529 switch(stat){
530 case 0x00:
531 return "was never started";
532 case 0x02:
533 return "was completed without error";
534 case 0x03:
535 if (status_byte == 0x03)
536 return "is in progress";
537 else
538 return "is in a Reserved state";
539 case 0x04:
540 return "was suspended by an interrupting command from host";
541 case 0x05:
542 return "was aborted by an interrupting command from host";
543 case 0x06:
544 return "was aborted by the device with a fatal error";
545 default:
546 if (stat >= 0x40)
547 return "is in a Vendor Specific state";
548 else
549 return "is in a Reserved state";
550 }
551 }
552
553
554 // prints verbose value Off-line data collection status byte
555 static void PrintSmartOfflineStatus(const ata_smart_values * data)
556 {
557 pout("Offline data collection status: (0x%02x)\t",
558 (int)data->offline_data_collection_status);
559
560 // Off-line data collection status byte is not a reserved
561 // or vendor specific value
562 pout("Offline data collection activity\n"
563 "\t\t\t\t\t%s.\n", OfflineDataCollectionStatus(data->offline_data_collection_status));
564
565 // Report on Automatic Data Collection Status. Only IBM documents
566 // this bit. See SFF 8035i Revision 2 for details.
567 if (data->offline_data_collection_status & 0x80)
568 pout("\t\t\t\t\tAuto Offline Data Collection: Enabled.\n");
569 else
570 pout("\t\t\t\t\tAuto Offline Data Collection: Disabled.\n");
571
572 return;
573 }
574
575 static void PrintSmartSelfExecStatus(const ata_smart_values * data,
576 unsigned char fix_firmwarebug)
577 {
578 pout("Self-test execution status: ");
579
580 switch (data->self_test_exec_status >> 4)
581 {
582 case 0:
583 pout("(%4d)\tThe previous self-test routine completed\n\t\t\t\t\t",
584 (int)data->self_test_exec_status);
585 pout("without error or no self-test has ever \n\t\t\t\t\tbeen run.\n");
586 break;
587 case 1:
588 pout("(%4d)\tThe self-test routine was aborted by\n\t\t\t\t\t",
589 (int)data->self_test_exec_status);
590 pout("the host.\n");
591 break;
592 case 2:
593 pout("(%4d)\tThe self-test routine was interrupted\n\t\t\t\t\t",
594 (int)data->self_test_exec_status);
595 pout("by the host with a hard or soft reset.\n");
596 break;
597 case 3:
598 pout("(%4d)\tA fatal error or unknown test error\n\t\t\t\t\t",
599 (int)data->self_test_exec_status);
600 pout("occurred while the device was executing\n\t\t\t\t\t");
601 pout("its self-test routine and the device \n\t\t\t\t\t");
602 pout("was unable to complete the self-test \n\t\t\t\t\t");
603 pout("routine.\n");
604 break;
605 case 4:
606 pout("(%4d)\tThe previous self-test completed having\n\t\t\t\t\t",
607 (int)data->self_test_exec_status);
608 pout("a test element that failed and the test\n\t\t\t\t\t");
609 pout("element that failed is not known.\n");
610 break;
611 case 5:
612 pout("(%4d)\tThe previous self-test completed having\n\t\t\t\t\t",
613 (int)data->self_test_exec_status);
614 pout("the electrical element of the test\n\t\t\t\t\t");
615 pout("failed.\n");
616 break;
617 case 6:
618 pout("(%4d)\tThe previous self-test completed having\n\t\t\t\t\t",
619 (int)data->self_test_exec_status);
620 pout("the servo (and/or seek) element of the \n\t\t\t\t\t");
621 pout("test failed.\n");
622 break;
623 case 7:
624 pout("(%4d)\tThe previous self-test completed having\n\t\t\t\t\t",
625 (int)data->self_test_exec_status);
626 pout("the read element of the test failed.\n");
627 break;
628 case 8:
629 pout("(%4d)\tThe previous self-test completed having\n\t\t\t\t\t",
630 (int)data->self_test_exec_status);
631 pout("a test element that failed and the\n\t\t\t\t\t");
632 pout("device is suspected of having handling\n\t\t\t\t\t");
633 pout("damage.\n");
634 break;
635 case 15:
636 if (fix_firmwarebug == FIX_SAMSUNG3 && data->self_test_exec_status == 0xf0) {
637 pout("(%4d)\tThe previous self-test routine completed\n\t\t\t\t\t",
638 (int)data->self_test_exec_status);
639 pout("with unknown result or self-test in\n\t\t\t\t\t");
640 pout("progress with less than 10%% remaining.\n");
641 }
642 else {
643 pout("(%4d)\tSelf-test routine in progress...\n\t\t\t\t\t",
644 (int)data->self_test_exec_status);
645 pout("%1d0%% of test remaining.\n",
646 (int)(data->self_test_exec_status & 0x0f));
647 }
648 break;
649 default:
650 pout("(%4d)\tReserved.\n",
651 (int)data->self_test_exec_status);
652 break;
653 }
654
655 }
656
657 static void PrintSmartTotalTimeCompleteOffline (const ata_smart_values * data)
658 {
659 pout("Total time to complete Offline \n");
660 pout("data collection: \t\t(%5d) seconds.\n",
661 (int)data->total_time_to_complete_off_line);
662 }
663
664 static void PrintSmartOfflineCollectCap(const ata_smart_values *data)
665 {
666 pout("Offline data collection\n");
667 pout("capabilities: \t\t\t (0x%02x) ",
668 (int)data->offline_data_collection_capability);
669
670 if (data->offline_data_collection_capability == 0x00){
671 pout("\tOffline data collection not supported.\n");
672 }
673 else {
674 pout( "%s\n", isSupportExecuteOfflineImmediate(data)?
675 "SMART execute Offline immediate." :
676 "No SMART execute Offline immediate.");
677
678 pout( "\t\t\t\t\t%s\n", isSupportAutomaticTimer(data)?
679 "Auto Offline data collection on/off support.":
680 "No Auto Offline data collection support.");
681
682 pout( "\t\t\t\t\t%s\n", isSupportOfflineAbort(data)?
683 "Abort Offline collection upon new\n\t\t\t\t\tcommand.":
684 "Suspend Offline collection upon new\n\t\t\t\t\tcommand.");
685
686 pout( "\t\t\t\t\t%s\n", isSupportOfflineSurfaceScan(data)?
687 "Offline surface scan supported.":
688 "No Offline surface scan supported.");
689
690 pout( "\t\t\t\t\t%s\n", isSupportSelfTest(data)?
691 "Self-test supported.":
692 "No Self-test supported.");
693
694 pout( "\t\t\t\t\t%s\n", isSupportConveyanceSelfTest(data)?
695 "Conveyance Self-test supported.":
696 "No Conveyance Self-test supported.");
697
698 pout( "\t\t\t\t\t%s\n", isSupportSelectiveSelfTest(data)?
699 "Selective Self-test supported.":
700 "No Selective Self-test supported.");
701 }
702 }
703
704 static void PrintSmartCapability(const ata_smart_values *data)
705 {
706 pout("SMART capabilities: ");
707 pout("(0x%04x)\t", (int)data->smart_capability);
708
709 if (data->smart_capability == 0x00)
710 {
711 pout("Automatic saving of SMART data\t\t\t\t\tis not implemented.\n");
712 }
713 else
714 {
715
716 pout( "%s\n", (data->smart_capability & 0x01)?
717 "Saves SMART data before entering\n\t\t\t\t\tpower-saving mode.":
718 "Does not save SMART data before\n\t\t\t\t\tentering power-saving mode.");
719
720 if ( data->smart_capability & 0x02 )
721 {
722 pout("\t\t\t\t\tSupports SMART auto save timer.\n");
723 }
724 }
725 }
726
727 static void PrintSmartErrorLogCapability(const ata_smart_values * data, const ata_identify_device * identity)
728 {
729 pout("Error logging capability: ");
730
731 if ( isSmartErrorLogCapable(data, identity) )
732 {
733 pout(" (0x%02x)\tError logging supported.\n",
734 (int)data->errorlog_capability);
735 }
736 else {
737 pout(" (0x%02x)\tError logging NOT supported.\n",
738 (int)data->errorlog_capability);
739 }
740 }
741
742 static void PrintSmartShortSelfTestPollingTime(const ata_smart_values * data)
743 {
744 pout("Short self-test routine \n");
745 if (isSupportSelfTest(data))
746 pout("recommended polling time: \t (%4d) minutes.\n",
747 (int)data->short_test_completion_time);
748 else
749 pout("recommended polling time: \t Not Supported.\n");
750 }
751
752 static void PrintSmartExtendedSelfTestPollingTime(const ata_smart_values * data)
753 {
754 pout("Extended self-test routine\n");
755 if (isSupportSelfTest(data))
756 pout("recommended polling time: \t (%4d) minutes.\n",
757 TestTime(data, EXTEND_SELF_TEST));
758 else
759 pout("recommended polling time: \t Not Supported.\n");
760 }
761
762 static void PrintSmartConveyanceSelfTestPollingTime(const ata_smart_values * data)
763 {
764 pout("Conveyance self-test routine\n");
765 if (isSupportConveyanceSelfTest(data))
766 pout("recommended polling time: \t (%4d) minutes.\n",
767 (int)data->conveyance_test_completion_time);
768 else
769 pout("recommended polling time: \t Not Supported.\n");
770 }
771
772 // Check SMART attribute table for Threshold failure
773 // onlyfailed=0: are or were any age or prefailure attributes <= threshold
774 // onlyfailed=1: are any prefailure attributes <= threshold now
775 static int find_failed_attr(const ata_smart_values * data,
776 const ata_smart_thresholds_pvt * thresholds,
777 const ata_vendor_attr_defs & defs, int onlyfailed)
778 {
779 for (int i = 0; i < NUMBER_ATA_SMART_ATTRIBUTES; i++) {
780 const ata_smart_attribute & attr = data->vendor_attributes[i];
781
782 ata_attr_state state = ata_get_attr_state(attr, i, thresholds->thres_entries, defs);
783
784 if (!onlyfailed) {
785 if (state >= ATTRSTATE_FAILED_PAST)
786 return attr.id;
787 }
788 else {
789 if (state == ATTRSTATE_FAILED_NOW && ATTRIBUTE_FLAGS_PREFAILURE(attr.flags))
790 return attr.id;
791 }
792 }
793 return 0;
794 }
795
796 // onlyfailed=0 : print all attribute values
797 // onlyfailed=1: just ones that are currently failed and have prefailure bit set
798 // onlyfailed=2: ones that are failed, or have failed with or without prefailure bit set
799 static void PrintSmartAttribWithThres(const ata_smart_values * data,
800 const ata_smart_thresholds_pvt * thresholds,
801 const ata_vendor_attr_defs & defs,
802 int onlyfailed, unsigned char format)
803 {
804 bool brief = !!(format & ata_print_options::FMT_BRIEF);
805 bool hexid = !!(format & ata_print_options::FMT_HEX_ID);
806 bool hexval = !!(format & ata_print_options::FMT_HEX_VAL);
807 bool needheader = true;
808
809 // step through all vendor attributes
810 for (int i = 0; i < NUMBER_ATA_SMART_ATTRIBUTES; i++) {
811 const ata_smart_attribute & attr = data->vendor_attributes[i];
812
813 // Check attribute and threshold
814 unsigned char threshold = 0;
815 ata_attr_state state = ata_get_attr_state(attr, i, thresholds->thres_entries, defs, &threshold);
816 if (state == ATTRSTATE_NON_EXISTING)
817 continue;
818
819 // These break out of the loop if we are only printing certain entries...
820 if (onlyfailed == 1 && !(ATTRIBUTE_FLAGS_PREFAILURE(attr.flags) && state == ATTRSTATE_FAILED_NOW))
821 continue;
822
823 if (onlyfailed == 2 && state < ATTRSTATE_FAILED_PAST)
824 continue;
825
826 // print header only if needed
827 if (needheader) {
828 if (!onlyfailed) {
829 pout("SMART Attributes Data Structure revision number: %d\n",(int)data->revnumber);
830 pout("Vendor Specific SMART Attributes with Thresholds:\n");
831 }
832 if (!brief)
833 pout("ID#%s ATTRIBUTE_NAME FLAG VALUE WORST THRESH TYPE UPDATED WHEN_FAILED RAW_VALUE\n",
834 (!hexid ? "" : " "));
835 else
836 pout("ID#%s ATTRIBUTE_NAME FLAGS VALUE WORST THRESH FAIL RAW_VALUE\n",
837 (!hexid ? "" : " "));
838 needheader = false;
839 }
840
841 // Format value, worst, threshold
842 std::string valstr, worstr, threstr;
843 if (state > ATTRSTATE_NO_NORMVAL)
844 valstr = (!hexval ? strprintf("%.3d", attr.current)
845 : strprintf("0x%02x", attr.current));
846 else
847 valstr = (!hexval ? "---" : "----");
848 if (!(defs[attr.id].flags & ATTRFLAG_NO_WORSTVAL))
849 worstr = (!hexval ? strprintf("%.3d", attr.worst)
850 : strprintf("0x%02x", attr.worst));
851 else
852 worstr = (!hexval ? "---" : "----");
853 if (state > ATTRSTATE_NO_THRESHOLD)
854 threstr = (!hexval ? strprintf("%.3d", threshold)
855 : strprintf("0x%02x", threshold));
856 else
857 threstr = (!hexval ? "---" : "----");
858
859 // Print line for each valid attribute
860 std::string idstr = (!hexid ? strprintf("%3d", attr.id)
861 : strprintf("0x%02x", attr.id));
862 std::string attrname = ata_get_smart_attr_name(attr.id, defs);
863 std::string rawstr = ata_format_attr_raw_value(attr, defs);
864
865 if (!brief)
866 pout("%s %-24s0x%04x %-4s %-4s %-4s %-10s%-9s%-12s%s\n",
867 idstr.c_str(), attrname.c_str(), attr.flags,
868 valstr.c_str(), worstr.c_str(), threstr.c_str(),
869 (ATTRIBUTE_FLAGS_PREFAILURE(attr.flags) ? "Pre-fail" : "Old_age"),
870 (ATTRIBUTE_FLAGS_ONLINE(attr.flags) ? "Always" : "Offline"),
871 (state == ATTRSTATE_FAILED_NOW ? "FAILING_NOW" :
872 state == ATTRSTATE_FAILED_PAST ? "In_the_past"
873 : " -" ) ,
874 rawstr.c_str());
875 else
876 pout("%s %-24s%c%c%c%c%c%c%c %-4s %-4s %-4s %-5s%s\n",
877 idstr.c_str(), attrname.c_str(),
878 (ATTRIBUTE_FLAGS_PREFAILURE(attr.flags) ? 'P' : '-'),
879 (ATTRIBUTE_FLAGS_ONLINE(attr.flags) ? 'O' : '-'),
880 (ATTRIBUTE_FLAGS_PERFORMANCE(attr.flags) ? 'S' : '-'),
881 (ATTRIBUTE_FLAGS_ERRORRATE(attr.flags) ? 'R' : '-'),
882 (ATTRIBUTE_FLAGS_EVENTCOUNT(attr.flags) ? 'C' : '-'),
883 (ATTRIBUTE_FLAGS_SELFPRESERVING(attr.flags) ? 'K' : '-'),
884 (ATTRIBUTE_FLAGS_OTHER(attr.flags) ? '+' : ' '),
885 valstr.c_str(), worstr.c_str(), threstr.c_str(),
886 (state == ATTRSTATE_FAILED_NOW ? "NOW" :
887 state == ATTRSTATE_FAILED_PAST ? "Past"
888 : "-" ),
889 rawstr.c_str());
890
891 }
892
893 if (!needheader) {
894 if (!onlyfailed && brief) {
895 int n = (!hexid ? 28 : 29);
896 pout("%*s||||||_ K auto-keep\n"
897 "%*s|||||__ C event count\n"
898 "%*s||||___ R error rate\n"
899 "%*s|||____ S speed/performance\n"
900 "%*s||_____ O updated online\n"
901 "%*s|______ P prefailure warning\n",
902 n, "", n, "", n, "", n, "", n, "", n, "");
903 }
904 pout("\n");
905 }
906 }
907
908 // Print SMART related SCT capabilities
909 static void ataPrintSCTCapability(const ata_identify_device *drive)
910 {
911 unsigned short sctcaps = drive->words088_255[206-88];
912 if (!(sctcaps & 0x01))
913 return;
914 pout("SCT capabilities: \t (0x%04x)\tSCT Status supported.\n", sctcaps);
915 if (sctcaps & 0x08)
916 pout("\t\t\t\t\tSCT Error Recovery Control supported.\n");
917 if (sctcaps & 0x10)
918 pout("\t\t\t\t\tSCT Feature Control supported.\n");
919 if (sctcaps & 0x20)
920 pout("\t\t\t\t\tSCT Data Table supported.\n");
921 }
922
923
924 static void PrintGeneralSmartValues(const ata_smart_values *data, const ata_identify_device *drive,
925 unsigned char fix_firmwarebug)
926 {
927 pout("General SMART Values:\n");
928
929 PrintSmartOfflineStatus(data);
930
931 if (isSupportSelfTest(data)){
932 PrintSmartSelfExecStatus(data, fix_firmwarebug);
933 }
934
935 PrintSmartTotalTimeCompleteOffline(data);
936 PrintSmartOfflineCollectCap(data);
937 PrintSmartCapability(data);
938
939 PrintSmartErrorLogCapability(data, drive);
940
941 pout( "\t\t\t\t\t%s\n", isGeneralPurposeLoggingCapable(drive)?
942 "General Purpose Logging supported.":
943 "No General Purpose Logging support.");
944
945 if (isSupportSelfTest(data)){
946 PrintSmartShortSelfTestPollingTime (data);
947 PrintSmartExtendedSelfTestPollingTime (data);
948 }
949 if (isSupportConveyanceSelfTest(data))
950 PrintSmartConveyanceSelfTestPollingTime (data);
951
952 ataPrintSCTCapability(drive);
953
954 pout("\n");
955 }
956
957 // Get # sectors of a log addr, 0 if log does not exist.
958 static unsigned GetNumLogSectors(const ata_smart_log_directory * logdir, unsigned logaddr, bool gpl)
959 {
960 if (!logdir)
961 return 0;
962 if (logaddr > 0xff)
963 return 0;
964 if (logaddr == 0)
965 return 1;
966 unsigned n = logdir->entry[logaddr-1].numsectors;
967 if (gpl)
968 // GP logs may have >255 sectors
969 n |= logdir->entry[logaddr-1].reserved << 8;
970 return n;
971 }
972
973 // Get name of log.
974 // Table A.2 of T13/2161-D Revision 2 (ACS-3), February 21, 2012.
975 static const char * GetLogName(unsigned logaddr)
976 {
977 switch (logaddr) {
978 case 0x00: return "Log Directory";
979 case 0x01: return "Summary SMART error log";
980 case 0x02: return "Comprehensive SMART error log";
981 case 0x03: return "Ext. Comprehensive SMART error log";
982 case 0x04: return "Device Statistics log";
983 case 0x05: return "Reserved for the CFA"; // ACS-2
984 case 0x06: return "SMART self-test log";
985 case 0x07: return "Extended self-test log";
986 case 0x08: return "Power Conditions log"; // ACS-2
987 case 0x09: return "Selective self-test log";
988 case 0x0d: return "LPS Mis-alignment log"; // ACS-2
989 case 0x10: return "NCQ Command Error log";
990 case 0x11: return "SATA Phy Event Counters";
991 case 0x12: return "SATA NCQ Queue Management log"; // ACS-3
992 case 0x13: return "SATA NCQ Send and Receive log"; // ACS-3
993 case 0x14:
994 case 0x15:
995 case 0x16: return "Reserved for Serial ATA";
996 case 0x19: return "LBA Status log"; // ACS-3
997 case 0x20: return "Streaming performance log"; // Obsolete
998 case 0x21: return "Write stream error log";
999 case 0x22: return "Read stream error log";
1000 case 0x23: return "Delayed sector log"; // Obsolete
1001 case 0x24: return "Current Device Internal Status Data log"; // ACS-3
1002 case 0x25: return "Saved Device Internal Status Data log"; // ACS-3
1003 case 0x30: return "IDENTIFY DEVICE data log"; // ACS-3
1004 case 0xe0: return "SCT Command/Status";
1005 case 0xe1: return "SCT Data Transfer";
1006 default:
1007 if (0xa0 <= logaddr && logaddr <= 0xdf)
1008 return "Device vendor specific log";
1009 if (0x80 <= logaddr && logaddr <= 0x9f)
1010 return "Host vendor specific log";
1011 return "Reserved";
1012 }
1013 /*NOTREACHED*/
1014 }
1015
1016 // Print SMART and/or GP Log Directory
1017 static void PrintLogDirectories(const ata_smart_log_directory * gplogdir,
1018 const ata_smart_log_directory * smartlogdir)
1019 {
1020 if (gplogdir)
1021 pout("General Purpose Log Directory Version %u\n", gplogdir->logversion);
1022 if (smartlogdir)
1023 pout("SMART %sLog Directory Version %u%s\n",
1024 (gplogdir ? " " : ""), smartlogdir->logversion,
1025 (smartlogdir->logversion==1 ? " [multi-sector log support]" : ""));
1026
1027 for (unsigned i = 0; i <= 0xff; i++) {
1028 // Get number of sectors
1029 unsigned smart_numsect = GetNumLogSectors(smartlogdir, i, false);
1030 unsigned gp_numsect = GetNumLogSectors(gplogdir , i, true );
1031
1032 if (!(smart_numsect || gp_numsect))
1033 continue; // Log does not exist
1034
1035 const char * name = GetLogName(i);
1036
1037 // Print name and length of log.
1038 // If both SMART and GP exist, print separate entries if length differ.
1039 if (smart_numsect == gp_numsect)
1040 pout( "GP/S Log at address 0x%02x has %4d sectors [%s]\n", i, smart_numsect, name);
1041 else {
1042 if (gp_numsect)
1043 pout("GP %sLog at address 0x%02x has %4d sectors [%s]\n", (smartlogdir?" ":""),
1044 i, gp_numsect, name);
1045 if (smart_numsect)
1046 pout("SMART Log at address 0x%02x has %4d sectors [%s]\n", i, smart_numsect, name);
1047 }
1048 }
1049 pout("\n");
1050 }
1051
1052 // Print hexdump of log pages.
1053 // Format is compatible with 'xxd -r'.
1054 static void PrintLogPages(const char * type, const unsigned char * data,
1055 unsigned char logaddr, unsigned page,
1056 unsigned num_pages, unsigned max_pages)
1057 {
1058 pout("%s Log 0x%02x [%s], Page %u-%u (of %u)\n",
1059 type, logaddr, GetLogName(logaddr), page, page+num_pages-1, max_pages);
1060 for (unsigned i = 0; i < num_pages * 512; i += 16) {
1061 const unsigned char * p = data+i;
1062 pout("%07x: %02x %02x %02x %02x %02x %02x %02x %02x "
1063 "%02x %02x %02x %02x %02x %02x %02x %02x ",
1064 (page * 512) + i,
1065 p[ 0], p[ 1], p[ 2], p[ 3], p[ 4], p[ 5], p[ 6], p[ 7],
1066 p[ 8], p[ 9], p[10], p[11], p[12], p[13], p[14], p[15]);
1067 #define P(n) (' ' <= p[n] && p[n] <= '~' ? (int)p[n] : '.')
1068 pout("|%c%c%c%c%c%c%c%c"
1069 "%c%c%c%c%c%c%c%c|\n",
1070 P( 0), P( 1), P( 2), P( 3), P( 4), P( 5), P( 6), P( 7),
1071 P( 8), P( 9), P(10), P(11), P(12), P(13), P(14), P(15));
1072 #undef P
1073 if ((i & 0x1ff) == 0x1f0)
1074 pout("\n");
1075 }
1076 }
1077
1078 ///////////////////////////////////////////////////////////////////////
1079 // Device statistics (Log 0x04)
1080
1081 // See Section A.5 of
1082 // ATA/ATAPI Command Set - 3 (ACS-3)
1083 // T13/2161-D Revision 2, February 21, 2012.
1084
1085 struct devstat_entry_info
1086 {
1087 short size; // #bytes of value, -1 for signed char
1088 const char * name;
1089 };
1090
1091 const devstat_entry_info devstat_info_0x00[] = {
1092 { 2, "List of supported log pages" },
1093 { 0, 0 }
1094 };
1095
1096 const devstat_entry_info devstat_info_0x01[] = {
1097 { 2, "General Statistics" },
1098 { 4, "Lifetime Power-On Resets" },
1099 { 4, "Power-on Hours" }, // spec says no flags(?)
1100 { 6, "Logical Sectors Written" },
1101 { 6, "Number of Write Commands" },
1102 { 6, "Logical Sectors Read" },
1103 { 6, "Number of Read Commands" },
1104 { 6, "Date and Time TimeStamp" }, // ACS-3
1105 { 0, 0 }
1106 };
1107
1108 const devstat_entry_info devstat_info_0x02[] = {
1109 { 2, "Free-Fall Statistics" },
1110 { 4, "Number of Free-Fall Events Detected" },
1111 { 4, "Overlimit Shock Events" },
1112 { 0, 0 }
1113 };
1114
1115 const devstat_entry_info devstat_info_0x03[] = {
1116 { 2, "Rotating Media Statistics" },
1117 { 4, "Spindle Motor Power-on Hours" },
1118 { 4, "Head Flying Hours" },
1119 { 4, "Head Load Events" },
1120 { 4, "Number of Reallocated Logical Sectors" },
1121 { 4, "Read Recovery Attempts" },
1122 { 4, "Number of Mechanical Start Failures" },
1123 { 4, "Number of Realloc. Candidate Logical Sectors" }, // ACS-3
1124 { 0, 0 }
1125 };
1126
1127 const devstat_entry_info devstat_info_0x04[] = {
1128 { 2, "General Errors Statistics" },
1129 { 4, "Number of Reported Uncorrectable Errors" },
1130 //{ 4, "Number of Resets Between Command Acceptance and Command Completion" },
1131 { 4, "Resets Between Cmd Acceptance and Completion" },
1132 { 0, 0 }
1133 };
1134
1135 const devstat_entry_info devstat_info_0x05[] = {
1136 { 2, "Temperature Statistics" },
1137 { -1, "Current Temperature" },
1138 { -1, "Average Short Term Temperature" },
1139 { -1, "Average Long Term Temperature" },
1140 { -1, "Highest Temperature" },
1141 { -1, "Lowest Temperature" },
1142 { -1, "Highest Average Short Term Temperature" },
1143 { -1, "Lowest Average Short Term Temperature" },
1144 { -1, "Highest Average Long Term Temperature" },
1145 { -1, "Lowest Average Long Term Temperature" },
1146 { 4, "Time in Over-Temperature" },
1147 { -1, "Specified Maximum Operating Temperature" },
1148 { 4, "Time in Under-Temperature" },
1149 { -1, "Specified Minimum Operating Temperature" },
1150 { 0, 0 }
1151 };
1152
1153 const devstat_entry_info devstat_info_0x06[] = {
1154 { 2, "Transport Statistics" },
1155 { 4, "Number of Hardware Resets" },
1156 { 4, "Number of ASR Events" },
1157 { 4, "Number of Interface CRC Errors" },
1158 { 0, 0 }
1159 };
1160
1161 const devstat_entry_info devstat_info_0x07[] = {
1162 { 2, "Solid State Device Statistics" },
1163 { 1, "Percentage Used Endurance Indicator" },
1164 { 0, 0 }
1165 };
1166
1167 const devstat_entry_info * devstat_infos[] = {
1168 devstat_info_0x00,
1169 devstat_info_0x01,
1170 devstat_info_0x02,
1171 devstat_info_0x03,
1172 devstat_info_0x04,
1173 devstat_info_0x05,
1174 devstat_info_0x06,
1175 devstat_info_0x07
1176 };
1177
1178 const int num_devstat_infos = sizeof(devstat_infos)/sizeof(devstat_infos[0]);
1179
1180 static void print_device_statistics_page(const unsigned char * data, int page,
1181 bool & need_trailer)
1182 {
1183 const devstat_entry_info * info = (page < num_devstat_infos ? devstat_infos[page] : 0);
1184 const char * name = (info ? info[0].name : "Unknown Statistics");
1185
1186 // Check page number in header
1187 static const char line[] = " ===== = = == ";
1188 if (!data[2]) {
1189 pout("%3d%s%s (empty) ==\n", page, line, name);
1190 return;
1191 }
1192 if (data[2] != page) {
1193 pout("%3d%s%s (invalid page %d in header) ==\n", page, line, name, data[2]);
1194 return;
1195 }
1196
1197 pout("%3d%s%s (rev %d) ==\n", page, line, name, data[0]);
1198
1199 // Print entries
1200 for (int i = 1, offset = 8; offset < 512-7; i++, offset+=8) {
1201 // Check for last known entry
1202 if (info && !info[i].size)
1203 info = 0;
1204
1205 // Skip unsupported entries
1206 unsigned char flags = data[offset+7];
1207 if (!(flags & 0x80))
1208 continue;
1209
1210 // Get value size, default to max if unknown
1211 int size = (info ? info[i].size : 7);
1212
1213 // Format value
1214 char valstr[32];
1215 if (flags & 0x40) { // valid flag
1216 // Get value
1217 int64_t val;
1218 if (size < 0) {
1219 val = (signed char)data[offset];
1220 }
1221 else {
1222 val = 0;
1223 for (int j = 0; j < size; j++)
1224 val |= (int64_t)data[offset+j] << (j*8);
1225 }
1226 snprintf(valstr, sizeof(valstr), "%"PRId64, val);
1227 }
1228 else {
1229 // Value not known (yet)
1230 strcpy(valstr, "-");
1231 }
1232
1233 pout("%3d 0x%03x %d%c %15s%c %s\n",
1234 page, offset,
1235 abs(size),
1236 (flags & 0x1f ? '+' : ' '), // unknown flags
1237 valstr,
1238 (flags & 0x20 ? '~' : ' '), // normalized flag
1239 (info ? info[i].name : "Unknown"));
1240 if (flags & 0x20)
1241 need_trailer = true;
1242 }
1243 }
1244
1245 static bool print_device_statistics(ata_device * device, unsigned nsectors,
1246 const std::vector<int> & single_pages, bool all_pages, bool ssd_page)
1247 {
1248 // Read list of supported pages from page 0
1249 unsigned char page_0[512] = {0, };
1250 if (!ataReadLogExt(device, 0x04, 0, 0, page_0, 1))
1251 return false;
1252
1253 unsigned char nentries = page_0[8];
1254 if (!(page_0[2] == 0 && nentries > 0)) {
1255 pout("Device Statistics page 0 is invalid (page=%d, nentries=%d)\n", page_0[2], nentries);
1256 return false;
1257 }
1258
1259 // Prepare list of pages to print
1260 std::vector<int> pages;
1261 unsigned i;
1262 if (all_pages) {
1263 // Add all supported pages
1264 for (i = 0; i < nentries; i++) {
1265 int page = page_0[8+1+i];
1266 if (page)
1267 pages.push_back(page);
1268 }
1269 ssd_page = false;
1270 }
1271 // Add manually specified pages
1272 bool print_page_0 = false;
1273 for (i = 0; i < single_pages.size() || ssd_page; i++) {
1274 int page = (i < single_pages.size() ? single_pages[i] : 7);
1275 if (!page)
1276 print_page_0 = true;
1277 else if (page >= (int)nsectors)
1278 pout("Device Statistics Log has only %u pages\n", nsectors);
1279 else
1280 pages.push_back(page);
1281 if (page == 7)
1282 ssd_page = false;
1283 }
1284
1285 // Print list of supported pages if requested
1286 if (print_page_0) {
1287 pout("Device Statistics (GP Log 0x04) supported pages\n");
1288 pout("Page Description\n");
1289 for (i = 0; i < nentries; i++) {
1290 int page = page_0[8+1+i];
1291 pout("%3d %s\n", page,
1292 (page < num_devstat_infos ? devstat_infos[page][0].name : "Unknown Statistics"));
1293 }
1294 pout("\n");
1295 }
1296
1297 // Read & print pages
1298 if (!pages.empty()) {
1299 pout("Device Statistics (GP Log 0x04)\n");
1300 pout("Page Offset Size Value Description\n");
1301 bool need_trailer = false;
1302
1303 for (i = 0; i < pages.size(); i++) {
1304 int page = pages[i];
1305 unsigned char page_n[512] = {0, };
1306 if (!ataReadLogExt(device, 0x04, 0, page, page_n, 1))
1307 return false;
1308 print_device_statistics_page(page_n, page, need_trailer);
1309 }
1310
1311 if (need_trailer)
1312 pout("%30s|_ ~ normalized value\n", "");
1313 pout("\n");
1314 }
1315
1316 return true;
1317 }
1318
1319
1320 ///////////////////////////////////////////////////////////////////////
1321
1322 // Print log 0x11
1323 static void PrintSataPhyEventCounters(const unsigned char * data, bool reset)
1324 {
1325 if (checksum(data))
1326 checksumwarning("SATA Phy Event Counters");
1327 pout("SATA Phy Event Counters (GP Log 0x11)\n");
1328 if (data[0] || data[1] || data[2] || data[3])
1329 pout("[Reserved: 0x%02x 0x%02x 0x%02x 0x%02x]\n",
1330 data[0], data[1], data[2], data[3]);
1331 pout("ID Size Value Description\n");
1332
1333 for (unsigned i = 4; ; ) {
1334 // Get counter id and size (bits 14:12)
1335 unsigned id = data[i] | (data[i+1] << 8);
1336 unsigned size = ((id >> 12) & 0x7) << 1;
1337 id &= 0x8fff;
1338
1339 // End of counter table ?
1340 if (!id)
1341 break;
1342 i += 2;
1343
1344 if (!(2 <= size && size <= 8 && i + size < 512)) {
1345 pout("0x%04x %u: Invalid entry\n", id, size);
1346 break;
1347 }
1348
1349 // Get value
1350 uint64_t val = 0, max_val = 0;
1351 for (unsigned j = 0; j < size; j+=2) {
1352 val |= (uint64_t)(data[i+j] | (data[i+j+1] << 8)) << (j*8);
1353 max_val |= (uint64_t)0xffffU << (j*8);
1354 }
1355 i += size;
1356
1357 // Get name
1358 const char * name;
1359 switch (id) {
1360 case 0x001: name = "Command failed due to ICRC error"; break; // Mandatory
1361 case 0x002: name = "R_ERR response for data FIS"; break;
1362 case 0x003: name = "R_ERR response for device-to-host data FIS"; break;
1363 case 0x004: name = "R_ERR response for host-to-device data FIS"; break;
1364 case 0x005: name = "R_ERR response for non-data FIS"; break;
1365 case 0x006: name = "R_ERR response for device-to-host non-data FIS"; break;
1366 case 0x007: name = "R_ERR response for host-to-device non-data FIS"; break;
1367 case 0x008: name = "Device-to-host non-data FIS retries"; break;
1368 case 0x009: name = "Transition from drive PhyRdy to drive PhyNRdy"; break;
1369 case 0x00A: name = "Device-to-host register FISes sent due to a COMRESET"; break; // Mandatory
1370 case 0x00B: name = "CRC errors within host-to-device FIS"; break;
1371 case 0x00D: name = "Non-CRC errors within host-to-device FIS"; break;
1372 case 0x00F: name = "R_ERR response for host-to-device data FIS, CRC"; break;
1373 case 0x010: name = "R_ERR response for host-to-device data FIS, non-CRC"; break;
1374 case 0x012: name = "R_ERR response for host-to-device non-data FIS, CRC"; break;
1375 case 0x013: name = "R_ERR response for host-to-device non-data FIS, non-CRC"; break;
1376 default: name = (id & 0x8000 ? "Vendor specific" : "Unknown"); break;
1377 }
1378
1379 // Counters stop at max value, add '+' in this case
1380 pout("0x%04x %u %12"PRIu64"%c %s\n", id, size, val,
1381 (val == max_val ? '+' : ' '), name);
1382 }
1383 if (reset)
1384 pout("All counters reset\n");
1385 pout("\n");
1386 }
1387
1388 // Get description for 'state' value from SMART Error Logs
1389 static const char * get_error_log_state_desc(unsigned state)
1390 {
1391 state &= 0x0f;
1392 switch (state){
1393 case 0x0: return "in an unknown state";
1394 case 0x1: return "sleeping";
1395 case 0x2: return "in standby mode";
1396 case 0x3: return "active or idle";
1397 case 0x4: return "doing SMART Offline or Self-test";
1398 default:
1399 return (state < 0xb ? "in a reserved state"
1400 : "in a vendor specific state");
1401 }
1402 }
1403
1404 // returns number of errors
1405 static int PrintSmartErrorlog(const ata_smart_errorlog *data,
1406 unsigned char fix_firmwarebug)
1407 {
1408 pout("SMART Error Log Version: %d\n", (int)data->revnumber);
1409
1410 // if no errors logged, return
1411 if (!data->error_log_pointer){
1412 pout("No Errors Logged\n\n");
1413 return 0;
1414 }
1415 print_on();
1416 // If log pointer out of range, return
1417 if (data->error_log_pointer>5){
1418 pout("Invalid Error Log index = 0x%02x (T13/1321D rev 1c "
1419 "Section 8.41.6.8.2.2 gives valid range from 1 to 5)\n\n",
1420 (int)data->error_log_pointer);
1421 return 0;
1422 }
1423
1424 // Some internal consistency checking of the data structures
1425 if ((data->ata_error_count-data->error_log_pointer)%5 && fix_firmwarebug != FIX_SAMSUNG2) {
1426 pout("Warning: ATA error count %d inconsistent with error log pointer %d\n\n",
1427 data->ata_error_count,data->error_log_pointer);
1428 }
1429
1430 // starting printing error log info
1431 if (data->ata_error_count<=5)
1432 pout( "ATA Error Count: %d\n", (int)data->ata_error_count);
1433 else
1434 pout( "ATA Error Count: %d (device log contains only the most recent five errors)\n",
1435 (int)data->ata_error_count);
1436 print_off();
1437 pout("\tCR = Command Register [HEX]\n"
1438 "\tFR = Features Register [HEX]\n"
1439 "\tSC = Sector Count Register [HEX]\n"
1440 "\tSN = Sector Number Register [HEX]\n"
1441 "\tCL = Cylinder Low Register [HEX]\n"
1442 "\tCH = Cylinder High Register [HEX]\n"
1443 "\tDH = Device/Head Register [HEX]\n"
1444 "\tDC = Device Command Register [HEX]\n"
1445 "\tER = Error register [HEX]\n"
1446 "\tST = Status register [HEX]\n"
1447 "Powered_Up_Time is measured from power on, and printed as\n"
1448 "DDd+hh:mm:SS.sss where DD=days, hh=hours, mm=minutes,\n"
1449 "SS=sec, and sss=millisec. It \"wraps\" after 49.710 days.\n\n");
1450
1451 // now step through the five error log data structures (table 39 of spec)
1452 for (int k = 4; k >= 0; k-- ) {
1453
1454 // The error log data structure entries are a circular buffer
1455 int j, i=(data->error_log_pointer+k)%5;
1456 const ata_smart_errorlog_struct * elog = data->errorlog_struct+i;
1457 const ata_smart_errorlog_error_struct * summary = &(elog->error_struct);
1458
1459 // Spec says: unused error log structures shall be zero filled
1460 if (nonempty(elog, sizeof(*elog))){
1461 // Table 57 of T13/1532D Volume 1 Revision 3
1462 const char *msgstate = get_error_log_state_desc(summary->state);
1463 int days = (int)summary->timestamp/24;
1464
1465 // See table 42 of ATA5 spec
1466 print_on();
1467 pout("Error %d occurred at disk power-on lifetime: %d hours (%d days + %d hours)\n",
1468 (int)(data->ata_error_count+k-4), (int)summary->timestamp, days, (int)(summary->timestamp-24*days));
1469 print_off();
1470 pout(" When the command that caused the error occurred, the device was %s.\n\n",msgstate);
1471 pout(" After command completion occurred, registers were:\n"
1472 " ER ST SC SN CL CH DH\n"
1473 " -- -- -- -- -- -- --\n"
1474 " %02x %02x %02x %02x %02x %02x %02x",
1475 (int)summary->error_register,
1476 (int)summary->status,
1477 (int)summary->sector_count,
1478 (int)summary->sector_number,
1479 (int)summary->cylinder_low,
1480 (int)summary->cylinder_high,
1481 (int)summary->drive_head);
1482 // Add a description of the contents of the status and error registers
1483 // if possible
1484 char descbuf[256];
1485 const char * st_er_desc = construct_st_er_desc(descbuf, elog);
1486 if (st_er_desc)
1487 pout(" %s", st_er_desc);
1488 pout("\n\n");
1489 pout(" Commands leading to the command that caused the error were:\n"
1490 " CR FR SC SN CL CH DH DC Powered_Up_Time Command/Feature_Name\n"
1491 " -- -- -- -- -- -- -- -- ---------------- --------------------\n");
1492 for ( j = 4; j >= 0; j--){
1493 const ata_smart_errorlog_command_struct * thiscommand = elog->commands+j;
1494
1495 // Spec says: unused data command structures shall be zero filled
1496 if (nonempty(thiscommand, sizeof(*thiscommand))) {
1497 char timestring[32];
1498
1499 // Convert integer milliseconds to a text-format string
1500 MsecToText(thiscommand->timestamp, timestring);
1501
1502 pout(" %02x %02x %02x %02x %02x %02x %02x %02x %16s %s\n",
1503 (int)thiscommand->commandreg,
1504 (int)thiscommand->featuresreg,
1505 (int)thiscommand->sector_count,
1506 (int)thiscommand->sector_number,
1507 (int)thiscommand->cylinder_low,
1508 (int)thiscommand->cylinder_high,
1509 (int)thiscommand->drive_head,
1510 (int)thiscommand->devicecontrolreg,
1511 timestring,
1512 look_up_ata_command(thiscommand->commandreg, thiscommand->featuresreg));
1513 }
1514 }
1515 pout("\n");
1516 }
1517 }
1518 print_on();
1519 if (printing_is_switchable)
1520 pout("\n");
1521 print_off();
1522 return data->ata_error_count;
1523 }
1524
1525 // Print SMART Extended Comprehensive Error Log (GP Log 0x03)
1526 static int PrintSmartExtErrorLog(const ata_smart_exterrlog * log,
1527 unsigned nsectors, unsigned max_errors)
1528 {
1529 pout("SMART Extended Comprehensive Error Log Version: %u (%u sectors)\n",
1530 log->version, nsectors);
1531
1532 if (!log->device_error_count) {
1533 pout("No Errors Logged\n\n");
1534 return 0;
1535 }
1536 print_on();
1537
1538 // Check index
1539 unsigned nentries = nsectors * 4;
1540 unsigned erridx = log->error_log_index;
1541 if (!(1 <= erridx && erridx <= nentries)){
1542 // Some Samsung disks (at least SP1614C/SW100-25, HD300LJ/ZT100-12) use the
1543 // former index from Summary Error Log (byte 1, now reserved) and set byte 2-3
1544 // to 0.
1545 if (!(erridx == 0 && 1 <= log->reserved1 && log->reserved1 <= nentries)) {
1546 pout("Invalid Error Log index = 0x%04x (reserved = 0x%02x)\n", erridx, log->reserved1);
1547 return 0;
1548 }
1549 pout("Invalid Error Log index = 0x%04x, trying reserved byte (0x%02x) instead\n", erridx, log->reserved1);
1550 erridx = log->reserved1;
1551 }
1552
1553 // Index base is not clearly specified by ATA8-ACS (T13/1699-D Revision 6a),
1554 // it is 1-based in practice.
1555 erridx--;
1556
1557 // Calculate #errors to print
1558 unsigned errcnt = log->device_error_count;
1559
1560 if (errcnt <= nentries)
1561 pout("Device Error Count: %u\n", log->device_error_count);
1562 else {
1563 errcnt = nentries;
1564 pout("Device Error Count: %u (device log contains only the most recent %u errors)\n",
1565 log->device_error_count, errcnt);
1566 }
1567
1568 if (max_errors < errcnt)
1569 errcnt = max_errors;
1570
1571 print_off();
1572 pout("\tCR = Command Register\n"
1573 "\tFEATR = Features Register\n"
1574 "\tCOUNT = Count (was: Sector Count) Register\n"
1575 "\tLBA_48 = Upper bytes of LBA High/Mid/Low Registers ] ATA-8\n"
1576 "\tLH = LBA High (was: Cylinder High) Register ] LBA\n"
1577 "\tLM = LBA Mid (was: Cylinder Low) Register ] Register\n"
1578 "\tLL = LBA Low (was: Sector Number) Register ]\n"
1579 "\tDV = Device (was: Device/Head) Register\n"
1580 "\tDC = Device Control Register\n"
1581 "\tER = Error register\n"
1582 "\tST = Status register\n"
1583 "Powered_Up_Time is measured from power on, and printed as\n"
1584 "DDd+hh:mm:SS.sss where DD=days, hh=hours, mm=minutes,\n"
1585 "SS=sec, and sss=millisec. It \"wraps\" after 49.710 days.\n\n");
1586
1587 // Iterate through circular buffer in reverse direction
1588 for (unsigned i = 0, errnum = log->device_error_count;
1589 i < errcnt; i++, errnum--, erridx = (erridx > 0 ? erridx - 1 : nentries - 1)) {
1590
1591 const ata_smart_exterrlog_error_log & entry = log[erridx / 4].error_logs[erridx % 4];
1592
1593 // Skip unused entries
1594 if (!nonempty(&entry, sizeof(entry))) {
1595 pout("Error %u [%u] log entry is empty\n", errnum, erridx);
1596 continue;
1597 }
1598
1599 // Print error information
1600 print_on();
1601 const ata_smart_exterrlog_error & err = entry.error;
1602 pout("Error %u [%u] occurred at disk power-on lifetime: %u hours (%u days + %u hours)\n",
1603 errnum, erridx, err.timestamp, err.timestamp / 24, err.timestamp % 24);
1604 print_off();
1605
1606 pout(" When the command that caused the error occurred, the device was %s.\n\n",
1607 get_error_log_state_desc(err.state));
1608
1609 // Print registers
1610 pout(" After command completion occurred, registers were:\n"
1611 " ER -- ST COUNT LBA_48 LH LM LL DV DC\n"
1612 " -- -- -- == -- == == == -- -- -- -- --\n"
1613 " %02x -- %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x",
1614 err.error_register,
1615 err.status_register,
1616 err.count_register_hi,
1617 err.count_register,
1618 err.lba_high_register_hi,
1619 err.lba_mid_register_hi,
1620 err.lba_low_register_hi,
1621 err.lba_high_register,
1622 err.lba_mid_register,
1623 err.lba_low_register,
1624 err.device_register,
1625 err.device_control_register);
1626
1627 // Add a description of the contents of the status and error registers
1628 // if possible
1629 char descbuf[256];
1630 const char * st_er_desc = construct_st_er_desc(descbuf, &entry);
1631 if (st_er_desc)
1632 pout(" %s", st_er_desc);
1633 pout("\n\n");
1634
1635 // Print command history
1636 pout(" Commands leading to the command that caused the error were:\n"
1637 " CR FEATR COUNT LBA_48 LH LM LL DV DC Powered_Up_Time Command/Feature_Name\n"
1638 " -- == -- == -- == == == -- -- -- -- -- --------------- --------------------\n");
1639 for (int ci = 4; ci >= 0; ci--) {
1640 const ata_smart_exterrlog_command & cmd = entry.commands[ci];
1641
1642 // Skip unused entries
1643 if (!nonempty(&cmd, sizeof(cmd)))
1644 continue;
1645
1646 // Print registers, timestamp and ATA command name
1647 char timestring[32];
1648 MsecToText(cmd.timestamp, timestring);
1649
1650 pout(" %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %16s %s\n",
1651 cmd.command_register,
1652 cmd.features_register_hi,
1653 cmd.features_register,
1654 cmd.count_register_hi,
1655 cmd.count_register,
1656 cmd.lba_high_register_hi,
1657 cmd.lba_mid_register_hi,
1658 cmd.lba_low_register_hi,
1659 cmd.lba_high_register,
1660 cmd.lba_mid_register,
1661 cmd.lba_low_register,
1662 cmd.device_register,
1663 cmd.device_control_register,
1664 timestring,
1665 look_up_ata_command(cmd.command_register, cmd.features_register));
1666 }
1667 pout("\n");
1668 }
1669
1670 print_on();
1671 if (printing_is_switchable)
1672 pout("\n");
1673 print_off();
1674 return log->device_error_count;
1675 }
1676
1677 // Print SMART Extended Self-test Log (GP Log 0x07)
1678 static int PrintSmartExtSelfTestLog(const ata_smart_extselftestlog * log,
1679 unsigned nsectors, unsigned max_entries)
1680 {
1681 pout("SMART Extended Self-test Log Version: %u (%u sectors)\n",
1682 log->version, nsectors);
1683
1684 if (!log->log_desc_index){
1685 pout("No self-tests have been logged. [To run self-tests, use: smartctl -t]\n\n");
1686 return 0;
1687 }
1688
1689 // Check index
1690 unsigned nentries = nsectors * 19;
1691 unsigned logidx = log->log_desc_index;
1692 if (logidx > nentries) {
1693 pout("Invalid Self-test Log index = 0x%04x (reserved = 0x%02x)\n", logidx, log->reserved1);
1694 return 0;
1695 }
1696
1697 // Index base is not clearly specified by ATA8-ACS (T13/1699-D Revision 6a),
1698 // it is 1-based in practice.
1699 logidx--;
1700
1701 bool print_header = true;
1702 int errcnt = 0, igncnt = 0;
1703 int ext_ok_testnum = -1;
1704
1705 // Iterate through circular buffer in reverse direction
1706 for (unsigned i = 0, testnum = 1;
1707 i < nentries && testnum <= max_entries;
1708 i++, logidx = (logidx > 0 ? logidx - 1 : nentries - 1)) {
1709
1710 const ata_smart_extselftestlog_desc & entry = log[logidx / 19].log_descs[logidx % 19];
1711
1712 // Skip unused entries
1713 if (!nonempty(&entry, sizeof(entry)))
1714 continue;
1715
1716 // Get LBA
1717 const unsigned char * b = entry.failing_lba;
1718 uint64_t lba48 = b[0]
1719 | ( b[1] << 8)
1720 | ( b[2] << 16)
1721 | ((uint64_t)b[3] << 24)
1722 | ((uint64_t)b[4] << 32)
1723 | ((uint64_t)b[5] << 40);
1724
1725 // Print entry
1726 int state = ataPrintSmartSelfTestEntry(testnum, entry.self_test_type,
1727 entry.self_test_status, entry.timestamp, lba48,
1728 false /*!print_error_only*/, print_header);
1729
1730 if (state < 0) {
1731 // Self-test showed an error
1732 if (ext_ok_testnum < 0)
1733 errcnt++;
1734 else
1735 // Newer successful extended self-test exits
1736 igncnt++;
1737 }
1738 else if (state > 0 && ext_ok_testnum < 0) {
1739 // Latest successful extended self-test
1740 ext_ok_testnum = testnum;
1741 }
1742 testnum++;
1743 }
1744
1745 if (igncnt)
1746 pout("%d of %d failed self-tests are outdated by newer successful extended offline self-test #%2d\n",
1747 igncnt, igncnt+errcnt, ext_ok_testnum);
1748
1749 pout("\n");
1750 return errcnt;
1751 }
1752
1753 static void ataPrintSelectiveSelfTestLog(const ata_selective_self_test_log * log, const ata_smart_values * sv)
1754 {
1755 int i,field1,field2;
1756 const char *msg;
1757 char tmp[64];
1758 uint64_t maxl=0,maxr=0;
1759 uint64_t current=log->currentlba;
1760 uint64_t currentend=current+65535;
1761
1762 // print data structure revision number
1763 pout("SMART Selective self-test log data structure revision number %d\n",(int)log->logversion);
1764 if (1 != log->logversion)
1765 pout("Note: revision number not 1 implies that no selective self-test has ever been run\n");
1766
1767 switch((sv->self_test_exec_status)>>4){
1768 case 0:msg="Completed";
1769 break;
1770 case 1:msg="Aborted_by_host";
1771 break;
1772 case 2:msg="Interrupted";
1773 break;
1774 case 3:msg="Fatal_error";
1775 break;
1776 case 4:msg="Completed_unknown_failure";
1777 break;
1778 case 5:msg="Completed_electrical_failure";
1779 break;
1780 case 6:msg="Completed_servo/seek_failure";
1781 break;
1782 case 7:msg="Completed_read_failure";
1783 break;
1784 case 8:msg="Completed_handling_damage??";
1785 break;
1786 case 15:msg="Self_test_in_progress";
1787 break;
1788 default:msg="Unknown_status ";
1789 break;
1790 }
1791
1792 // find the number of columns needed for printing. If in use, the
1793 // start/end of span being read-scanned...
1794 if (log->currentspan>5) {
1795 maxl=current;
1796 maxr=currentend;
1797 }
1798 for (i=0; i<5; i++) {
1799 uint64_t start=log->span[i].start;
1800 uint64_t end =log->span[i].end;
1801 // ... plus max start/end of each of the five test spans.
1802 if (start>maxl)
1803 maxl=start;
1804 if (end > maxr)
1805 maxr=end;
1806 }
1807
1808 // we need at least 7 characters wide fields to accomodate the
1809 // labels
1810 if ((field1=snprintf(tmp,64, "%"PRIu64, maxl))<7)
1811 field1=7;
1812 if ((field2=snprintf(tmp,64, "%"PRIu64, maxr))<7)
1813 field2=7;
1814
1815 // now print the five test spans
1816 pout(" SPAN %*s %*s CURRENT_TEST_STATUS\n", field1, "MIN_LBA", field2, "MAX_LBA");
1817
1818 for (i=0; i<5; i++) {
1819 uint64_t start=log->span[i].start;
1820 uint64_t end=log->span[i].end;
1821
1822 if ((i+1)==(int)log->currentspan)
1823 // this span is currently under test
1824 pout(" %d %*"PRIu64" %*"PRIu64" %s [%01d0%% left] (%"PRIu64"-%"PRIu64")\n",
1825 i+1, field1, start, field2, end, msg,
1826 (int)(sv->self_test_exec_status & 0xf), current, currentend);
1827 else
1828 // this span is not currently under test
1829 pout(" %d %*"PRIu64" %*"PRIu64" Not_testing\n",
1830 i+1, field1, start, field2, end);
1831 }
1832
1833 // if we are currently read-scanning, print LBAs and the status of
1834 // the read scan
1835 if (log->currentspan>5)
1836 pout("%5d %*"PRIu64" %*"PRIu64" Read_scanning %s\n",
1837 (int)log->currentspan, field1, current, field2, currentend,
1838 OfflineDataCollectionStatus(sv->offline_data_collection_status));
1839
1840 /* Print selective self-test flags. Possible flag combinations are
1841 (numbering bits from 0-15):
1842 Bit-1 Bit-3 Bit-4
1843 Scan Pending Active
1844 0 * * Don't scan
1845 1 0 0 Will carry out scan after selective test
1846 1 1 0 Waiting to carry out scan after powerup
1847 1 0 1 Currently scanning
1848 1 1 1 Currently scanning
1849 */
1850
1851 pout("Selective self-test flags (0x%x):\n", (unsigned int)log->flags);
1852 if (log->flags & SELECTIVE_FLAG_DOSCAN) {
1853 if (log->flags & SELECTIVE_FLAG_ACTIVE)
1854 pout(" Currently read-scanning the remainder of the disk.\n");
1855 else if (log->flags & SELECTIVE_FLAG_PENDING)
1856 pout(" Read-scan of remainder of disk interrupted; will resume %d min after power-up.\n",
1857 (int)log->pendingtime);
1858 else
1859 pout(" After scanning selected spans, read-scan remainder of disk.\n");
1860 }
1861 else
1862 pout(" After scanning selected spans, do NOT read-scan remainder of disk.\n");
1863
1864 // print pending time
1865 pout("If Selective self-test is pending on power-up, resume after %d minute delay.\n",
1866 (int)log->pendingtime);
1867
1868 return;
1869 }
1870
1871 // Format SCT Temperature value
1872 static const char * sct_ptemp(signed char x, char * buf)
1873 {
1874 if (x == -128 /*0x80 = unknown*/)
1875 strcpy(buf, " ?");
1876 else
1877 sprintf(buf, "%2d", x);
1878 return buf;
1879 }
1880
1881 static const char * sct_pbar(int x, char * buf)
1882 {
1883 if (x <= 19)
1884 x = 0;
1885 else
1886 x -= 19;
1887 bool ov = false;
1888 if (x > 40) {
1889 x = 40; ov = true;
1890 }
1891 if (x > 0) {
1892 memset(buf, '*', x);
1893 if (ov)
1894 buf[x-1] = '+';
1895 buf[x] = 0;
1896 }
1897 else {
1898 buf[0] = '-'; buf[1] = 0;
1899 }
1900 return buf;
1901 }
1902
1903 static const char * sct_device_state_msg(unsigned char state)
1904 {
1905 switch (state) {
1906 case 0: return "Active";
1907 case 1: return "Stand-by";
1908 case 2: return "Sleep";
1909 case 3: return "DST executing in background";
1910 case 4: return "SMART Off-line Data Collection executing in background";
1911 case 5: return "SCT command executing in background";
1912 default:return "Unknown";
1913 }
1914 }
1915
1916 // Print SCT Status
1917 static int ataPrintSCTStatus(const ata_sct_status_response * sts)
1918 {
1919 pout("SCT Status Version: %u\n", sts->format_version);
1920 pout("SCT Version (vendor specific): %u (0x%04x)\n", sts->sct_version, sts->sct_version);
1921 pout("SCT Support Level: %u\n", sts->sct_spec);
1922 pout("Device State: %s (%u)\n",
1923 sct_device_state_msg(sts->device_state), sts->device_state);
1924 char buf1[20], buf2[20];
1925 if ( !sts->min_temp && !sts->life_min_temp
1926 && !sts->under_limit_count && !sts->over_limit_count) {
1927 // "Reserved" fields not set, assume "old" format version 2
1928 // Table 11 of T13/1701DT-N (SMART Command Transport) Revision 5, February 2005
1929 // Table 54 of T13/1699-D (ATA8-ACS) Revision 3e, July 2006
1930 pout("Current Temperature: %s Celsius\n",
1931 sct_ptemp(sts->hda_temp, buf1));
1932 pout("Power Cycle Max Temperature: %s Celsius\n",
1933 sct_ptemp(sts->max_temp, buf2));
1934 pout("Lifetime Max Temperature: %s Celsius\n",
1935 sct_ptemp(sts->life_max_temp, buf2));
1936 }
1937 else {
1938 // Assume "new" format version 2 or version 3
1939 // T13/e06152r0-3 (Additional SCT Temperature Statistics), August - October 2006
1940 // Table 60 of T13/1699-D (ATA8-ACS) Revision 3f, December 2006 (format version 2)
1941 // Table 80 of T13/1699-D (ATA8-ACS) Revision 6a, September 2008 (format version 3)
1942 pout("Current Temperature: %s Celsius\n",
1943 sct_ptemp(sts->hda_temp, buf1));
1944 pout("Power Cycle Min/Max Temperature: %s/%s Celsius\n",
1945 sct_ptemp(sts->min_temp, buf1), sct_ptemp(sts->max_temp, buf2));
1946 pout("Lifetime Min/Max Temperature: %s/%s Celsius\n",
1947 sct_ptemp(sts->life_min_temp, buf1), sct_ptemp(sts->life_max_temp, buf2));
1948 signed char avg = sts->byte205; // Average Temperature from e06152r0-2, removed in e06152r3
1949 if (0 < avg && sts->life_min_temp <= avg && avg <= sts->life_max_temp)
1950 pout("Lifetime Average Temperature: %2d Celsius\n", avg);
1951 pout("Under/Over Temperature Limit Count: %2u/%u\n",
1952 sts->under_limit_count, sts->over_limit_count);
1953 }
1954 return 0;
1955 }
1956
1957 // Print SCT Temperature History Table
1958 static int ataPrintSCTTempHist(const ata_sct_temperature_history_table * tmh)
1959 {
1960 char buf1[20], buf2[80];
1961 pout("SCT Temperature History Version: %u\n", tmh->format_version);
1962 pout("Temperature Sampling Period: %u minute%s\n",
1963 tmh->sampling_period, (tmh->sampling_period==1?"":"s"));
1964 pout("Temperature Logging Interval: %u minute%s\n",
1965 tmh->interval, (tmh->interval==1?"":"s"));
1966 pout("Min/Max recommended Temperature: %s/%s Celsius\n",
1967 sct_ptemp(tmh->min_op_limit, buf1), sct_ptemp(tmh->max_op_limit, buf2));
1968 pout("Min/Max Temperature Limit: %s/%s Celsius\n",
1969 sct_ptemp(tmh->under_limit, buf1), sct_ptemp(tmh->over_limit, buf2));
1970 pout("Temperature History Size (Index): %u (%u)\n", tmh->cb_size, tmh->cb_index);
1971 if (!(0 < tmh->cb_size && tmh->cb_size <= sizeof(tmh->cb) && tmh->cb_index < tmh->cb_size)) {
1972 pout("Error invalid Temperature History Size or Index\n");
1973 return 0;
1974 }
1975
1976 // Print table
1977 pout("\nIndex Estimated Time Temperature Celsius\n");
1978 unsigned n = 0, i = (tmh->cb_index+1) % tmh->cb_size;
1979 unsigned interval = (tmh->interval > 0 ? tmh->interval : 1);
1980 time_t t = time(0) - (tmh->cb_size-1) * interval * 60;
1981 t -= t % (interval * 60);
1982 while (n < tmh->cb_size) {
1983 // Find range of identical temperatures
1984 unsigned n1 = n, n2 = n+1, i2 = (i+1) % tmh->cb_size;
1985 while (n2 < tmh->cb_size && tmh->cb[i2] == tmh->cb[i]) {
1986 n2++; i2 = (i2+1) % tmh->cb_size;
1987 }
1988 // Print range
1989 while (n < n2) {
1990 if (n == n1 || n == n2-1 || n2 <= n1+3) {
1991 char date[30];
1992 // TODO: Don't print times < boot time
1993 strftime(date, sizeof(date), "%Y-%m-%d %H:%M", localtime(&t));
1994 pout(" %3u %s %s %s\n", i, date,
1995 sct_ptemp(tmh->cb[i], buf1), sct_pbar(tmh->cb[i], buf2));
1996 }
1997 else if (n == n1+1) {
1998 pout(" ... ..(%3u skipped). .. %s\n",
1999 n2-n1-2, sct_pbar(tmh->cb[i], buf2));
2000 }
2001 t += interval * 60; i = (i+1) % tmh->cb_size; n++;
2002 }
2003 }
2004 //assert(n == tmh->cb_size && i == (tmh->cb_index+1) % tmh->cb_size);
2005
2006 return 0;
2007 }
2008
2009 // Print SCT Error Recovery Control timers
2010 static void ataPrintSCTErrorRecoveryControl(bool set, unsigned short read_timer, unsigned short write_timer)
2011 {
2012 pout("SCT Error Recovery Control%s:\n", (set ? " set to" : ""));
2013 if (!read_timer)
2014 pout(" Read: Disabled\n");
2015 else
2016 pout(" Read: %6d (%0.1f seconds)\n", read_timer, read_timer/10.0);
2017 if (!write_timer)
2018 pout(" Write: Disabled\n");
2019 else
2020 pout(" Write: %6d (%0.1f seconds)\n", write_timer, write_timer/10.0);
2021 }
2022
2023 static void print_aam_level(const char * msg, int level, int recommended = -1)
2024 {
2025 // Table 56 of T13/1699-D (ATA8-ACS) Revision 6a, September 6, 2008
2026 // Obsolete since T13/2015-D (ACS-2) Revision 4a, December 9, 2010
2027 const char * s;
2028 if (level == 0)
2029 s = "vendor specific";
2030 else if (level < 128)
2031 s = "unknown/retired";
2032 else if (level == 128)
2033 s = "quiet";
2034 else if (level < 254)
2035 s = "intermediate";
2036 else if (level == 254)
2037 s = "maximum performance";
2038 else
2039 s = "reserved";
2040
2041 if (recommended >= 0)
2042 pout("%s%d (%s), recommended: %d\n", msg, level, s, recommended);
2043 else
2044 pout("%s%d (%s)\n", msg, level, s);
2045 }
2046
2047 static void print_apm_level(const char * msg, int level)
2048 {
2049 // Table 120 of T13/2015-D (ACS-2) Revision 7, June 22, 2011
2050 const char * s;
2051 if (!(1 <= level && level <= 254))
2052 s = "reserved";
2053 else if (level == 1)
2054 s = "minimum power consumption with standby";
2055 else if (level < 128)
2056 s = "intermediate level with standby";
2057 else if (level == 128)
2058 s = "minimum power consumption without standby";
2059 else if (level < 254)
2060 s = "intermediate level without standby";
2061 else
2062 s = "maximum performance";
2063
2064 pout("%s%d (%s)\n", msg, level, s);
2065 }
2066
2067 static void print_ata_security_status(const char * msg, unsigned short state)
2068 {
2069 const char * s1, * s2 = "", * s3 = "", * s4 = "";
2070
2071 // Table 6 of T13/2015-D (ACS-2) Revision 7, June 22, 2011
2072 if (!(state & 0x0001))
2073 s1 = "Unavailable";
2074 else if (!(state & 0x0002)) {
2075 s1 = "Disabled, ";
2076 if (!(state & 0x0008))
2077 s2 = "NOT FROZEN [SEC1]";
2078 else
2079 s2 = "frozen [SEC2]";
2080 }
2081 else {
2082 s1 = "ENABLED, PW level ";
2083 if (!(state & 0x0020))
2084 s2 = "HIGH";
2085 else
2086 s2 = "MAX";
2087
2088 if (!(state & 0x0004)) {
2089 s3 = ", not locked, ";
2090 if (!(state & 0x0008))
2091 s4 = "not frozen [SEC5]";
2092 else
2093 s4 = "frozen [SEC6]";
2094 }
2095 else {
2096 s3 = ", **LOCKED** [SEC4]";
2097 if (state & 0x0010)
2098 s4 = ", PW ATTEMPTS EXCEEDED";
2099 }
2100 }
2101
2102 pout("%s%s%s%s%s\n", msg, s1, s2, s3, s4);
2103 }
2104
2105 static void print_standby_timer(const char * msg, int timer, const ata_identify_device & drive)
2106 {
2107 const char * s1 = 0;
2108 int hours = 0, minutes = 0 , seconds = 0;
2109
2110 // Table 63 of T13/2015-D (ACS-2) Revision 7, June 22, 2011
2111 if (timer == 0)
2112 s1 = "disabled";
2113 else if (timer <= 240)
2114 seconds = timer * 5, minutes = seconds / 60, seconds %= 60;
2115 else if (timer <= 251)
2116 minutes = (timer - 240) * 30, hours = minutes / 60, minutes %= 60;
2117 else if (timer == 252)
2118 minutes = 21;
2119 else if (timer == 253)
2120 s1 = "between 8 hours and 12 hours";
2121 else if (timer == 255)
2122 minutes = 21, seconds = 15;
2123 else
2124 s1 = "reserved";
2125
2126 const char * s2 = "", * s3 = "";
2127 if (!(drive.words047_079[49-47] & 0x2000))
2128 s2 = " or vendor-specific";
2129 if (timer > 0 && (drive.words047_079[50-47] & 0xc001) == 0x4001)
2130 s3 = ", a vendor-specific minimum applies";
2131
2132 if (s1)
2133 pout("%s%d (%s%s%s)\n", msg, timer, s1, s2, s3);
2134 else
2135 pout("%s%d (%02d:%02d:%02d%s%s)\n", msg, timer, hours, minutes, seconds, s2, s3);
2136 }
2137
2138
2139 int ataPrintMain (ata_device * device, const ata_print_options & options)
2140 {
2141 // If requested, check power mode first
2142 const char * powername = 0;
2143 bool powerchg = false;
2144 if (options.powermode) {
2145 unsigned char powerlimit = 0xff;
2146 int powermode = ataCheckPowerMode(device);
2147 switch (powermode) {
2148 case -1:
2149 if (device->is_syscall_unsup()) {
2150 pout("CHECK POWER MODE not implemented, ignoring -n option\n"); break;
2151 }
2152 powername = "SLEEP"; powerlimit = 2;
2153 break;
2154 case 0:
2155 powername = "STANDBY"; powerlimit = 3; break;
2156 case 0x80:
2157 powername = "IDLE"; powerlimit = 4; break;
2158 case 0xff:
2159 powername = "ACTIVE or IDLE"; break;
2160 default:
2161 pout("CHECK POWER MODE returned unknown value 0x%02x, ignoring -n option\n", powermode);
2162 break;
2163 }
2164 if (powername) {
2165 if (options.powermode >= powerlimit) {
2166 pout("Device is in %s mode, exit(%d)\n", powername, FAILPOWER);
2167 return FAILPOWER;
2168 }
2169 powerchg = (powermode != 0xff); // SMART tests will spin up drives
2170 }
2171 }
2172
2173 // SMART values needed ?
2174 bool need_smart_val = (
2175 options.smart_check_status
2176 || options.smart_general_values
2177 || options.smart_vendor_attrib
2178 || options.smart_error_log
2179 || options.smart_selftest_log
2180 || options.smart_selective_selftest_log
2181 || options.smart_ext_error_log
2182 || options.smart_ext_selftest_log
2183 || options.smart_auto_offl_enable
2184 || options.smart_auto_offl_disable
2185 || options.smart_selftest_type != -1
2186 );
2187
2188 // SMART must be enabled ?
2189 bool need_smart_enabled = (
2190 need_smart_val
2191 || options.smart_auto_save_enable
2192 || options.smart_auto_save_disable
2193 );
2194
2195 // SMART feature set needed ?
2196 bool need_smart_support = (
2197 need_smart_enabled
2198 || options.smart_enable
2199 || options.smart_disable
2200 );
2201
2202 // SMART and GP log directories needed ?
2203 bool need_smart_logdir = options.smart_logdir;
2204
2205 bool need_gp_logdir = (
2206 options.gp_logdir
2207 || options.smart_ext_error_log
2208 || options.smart_ext_selftest_log
2209 || options.sataphy
2210 || options.devstat_all_pages
2211 || options.devstat_ssd_page
2212 || !options.devstat_pages.empty()
2213 );
2214
2215 unsigned i;
2216 for (i = 0; i < options.log_requests.size(); i++) {
2217 if (options.log_requests[i].gpl)
2218 need_gp_logdir = true;
2219 else
2220 need_smart_logdir = true;
2221 }
2222
2223 // SCT commands needed ?
2224 bool need_sct_support = (
2225 options.sct_temp_sts
2226 || options.sct_temp_hist
2227 || options.sct_temp_int
2228 || options.sct_erc_get
2229 || options.sct_erc_set
2230 );
2231
2232 // Exit if no further options specified
2233 if (!( options.drive_info || need_smart_support
2234 || need_smart_logdir || need_gp_logdir
2235 || need_sct_support || options.get_set_used)) {
2236 if (powername)
2237 pout("Device is in %s mode\n", powername);
2238 else
2239 pout("ATA device successfully opened\n\n"
2240 "Use 'smartctl -a' (or '-x') to print SMART (and more) information\n\n");
2241 return 0;
2242 }
2243
2244 // Start by getting Drive ID information. We need this, to know if SMART is supported.
2245 int returnval = 0;
2246 ata_identify_device drive; memset(&drive, 0, sizeof(drive));
2247 device->clear_err();
2248 int retid = ata_read_identity(device, &drive, options.fix_swapped_id);
2249 if (retid < 0) {
2250 pout("Smartctl: Device Read Identity Failed: %s\n\n",
2251 (device->get_errno() ? device->get_errmsg() : "Unknown error"));
2252 failuretest(MANDATORY_CMD, returnval|=FAILID);
2253 }
2254 else if (!nonempty(&drive, sizeof(drive))) {
2255 pout("Smartctl: Device Read Identity Failed: empty IDENTIFY data\n\n");
2256 failuretest(MANDATORY_CMD, returnval|=FAILID);
2257 }
2258
2259 // If requested, show which presets would be used for this drive and exit.
2260 if (options.show_presets) {
2261 show_presets(&drive);
2262 return 0;
2263 }
2264
2265 // Use preset vendor attribute options unless user has requested otherwise.
2266 ata_vendor_attr_defs attribute_defs = options.attribute_defs;
2267 unsigned char fix_firmwarebug = options.fix_firmwarebug;
2268 const drive_settings * dbentry = 0;
2269 if (!options.ignore_presets)
2270 dbentry = lookup_drive_apply_presets(&drive, attribute_defs,
2271 fix_firmwarebug);
2272
2273 // Get capacity and sector sizes
2274 ata_size_info sizes;
2275 ata_get_size_info(&drive, sizes);
2276
2277 // Print most drive identity information if requested
2278 if (options.drive_info) {
2279 pout("=== START OF INFORMATION SECTION ===\n");
2280 print_drive_info(&drive, sizes, dbentry);
2281 }
2282
2283 // Check and print SMART support and state
2284 int smart_supported = -1, smart_enabled = -1;
2285 if (need_smart_support || options.drive_info) {
2286
2287 // Packet device ?
2288 if (retid > 0) {
2289 pout("SMART support is: Unavailable - Packet Interface Devices [this device: %s] don't support ATA SMART\n",
2290 packetdevicetype(retid-1));
2291 }
2292 else {
2293 // Disk device: SMART supported and enabled ?
2294 smart_supported = ataSmartSupport(&drive);
2295 smart_enabled = ataIsSmartEnabled(&drive);
2296
2297 if (smart_supported < 0)
2298 pout("SMART support is: Ambiguous - ATA IDENTIFY DEVICE words 82-83 don't show if SMART supported.\n");
2299 if (smart_supported && smart_enabled < 0) {
2300 pout("SMART support is: Ambiguous - ATA IDENTIFY DEVICE words 85-87 don't show if SMART is enabled.\n");
2301 if (need_smart_support) {
2302 failuretest(MANDATORY_CMD, returnval|=FAILSMART);
2303 // check SMART support by trying a command
2304 pout(" Checking to be sure by trying SMART RETURN STATUS command.\n");
2305 if (ataDoesSmartWork(device))
2306 smart_supported = smart_enabled = 1;
2307 }
2308 }
2309 else if (smart_supported < 0 && (smart_enabled > 0 || dbentry))
2310 // Assume supported if enabled or in drive database
2311 smart_supported = 1;
2312
2313 if (smart_supported < 0)
2314 pout("SMART support is: Unknown - Try option -s with argument 'on' to enable it.");
2315 else if (!smart_supported)
2316 pout("SMART support is: Unavailable - device lacks SMART capability.\n");
2317 else {
2318 if (options.drive_info)
2319 pout("SMART support is: Available - device has SMART capability.\n");
2320 if (smart_enabled >= 0) {
2321 if (device->ata_identify_is_cached()) {
2322 if (options.drive_info)
2323 pout(" %sabled status cached by OS, trying SMART RETURN STATUS cmd.\n",
2324 (smart_enabled?"En":"Dis"));
2325 smart_enabled = ataDoesSmartWork(device);
2326 }
2327 if (options.drive_info)
2328 pout("SMART support is: %s\n",
2329 (smart_enabled ? "Enabled" : "Disabled"));
2330 }
2331 }
2332 }
2333 }
2334
2335 // Print AAM status
2336 if (options.get_aam) {
2337 if ((drive.command_set_2 & 0xc200) != 0x4200) // word083
2338 pout("AAM feature is: Unavailable\n");
2339 else if (!(drive.word086 & 0x0200))
2340 pout("AAM feature is: Disabled\n");
2341 else
2342 print_aam_level("AAM level is: ", drive.words088_255[94-88] & 0xff,
2343 drive.words088_255[94-88] >> 8);
2344 }
2345
2346 // Print APM status
2347 if (options.get_apm) {
2348 if ((drive.command_set_2 & 0xc008) != 0x4008) // word083
2349 pout("APM feature is: Unavailable\n");
2350 else if (!(drive.word086 & 0x0008))
2351 pout("APM feature is: Disabled\n");
2352 else
2353 print_apm_level("APM level is: ", drive.words088_255[91-88] & 0xff);
2354 }
2355
2356 // Print read look-ahead status
2357 if (options.get_lookahead) {
2358 pout("Rd look-ahead is: %s\n",
2359 ( (drive.command_set_2 & 0xc000) != 0x4000 // word083
2360 || !(drive.command_set_1 & 0x0040)) ? "Unavailable" : // word082
2361 !(drive.cfs_enable_1 & 0x0040) ? "Disabled" : "Enabled"); // word085
2362 }
2363
2364 // Print write cache status
2365 if (options.get_wcache) {
2366 pout("Write cache is: %s\n",
2367 ( (drive.command_set_2 & 0xc000) != 0x4000 // word083
2368 || !(drive.command_set_1 & 0x0020)) ? "Unavailable" : // word082
2369 !(drive.cfs_enable_1 & 0x0020) ? "Disabled" : "Enabled"); // word085
2370 }
2371
2372 // Print ATA security status
2373 if (options.get_security)
2374 print_ata_security_status("ATA Security is: ", drive.words088_255[128-88]);
2375
2376 // Print remaining drive info
2377 if (options.drive_info) {
2378 // Print the (now possibly changed) power mode if available
2379 if (powername)
2380 pout("Power mode %s %s\n", (powerchg?"was:":"is: "), powername);
2381 pout("\n");
2382 }
2383
2384 // Exit if SMART is not supported but must be available to proceed
2385 if (smart_supported <= 0 && need_smart_support)
2386 failuretest(MANDATORY_CMD, returnval|=FAILSMART);
2387
2388 // START OF THE ENABLE/DISABLE SECTION OF THE CODE
2389 if ( options.smart_disable || options.smart_enable
2390 || options.smart_auto_save_disable || options.smart_auto_save_enable
2391 || options.smart_auto_offl_disable || options.smart_auto_offl_enable)
2392 pout("=== START OF ENABLE/DISABLE COMMANDS SECTION ===\n");
2393
2394 // Enable/Disable AAM
2395 if (options.set_aam) {
2396 if (options.set_aam > 0) {
2397 if (!ata_set_features(device, ATA_ENABLE_AAM, options.set_aam-1)) {
2398 pout("AAM enable failed: %s\n", device->get_errmsg());
2399 returnval |= FAILSMART;
2400 }
2401 else
2402 print_aam_level("AAM set to level ", options.set_aam-1);
2403 }
2404 else {
2405 if (!ata_set_features(device, ATA_DISABLE_AAM)) {
2406 pout("AAM disable failed: %s\n", device->get_errmsg());
2407 returnval |= FAILSMART;
2408 }
2409 else
2410 pout("AAM disabled\n");
2411 }
2412 }
2413
2414 // Enable/Disable APM
2415 if (options.set_apm) {
2416 if (options.set_apm > 0) {
2417 if (!ata_set_features(device, ATA_ENABLE_APM, options.set_apm-1)) {
2418 pout("APM enable failed: %s\n", device->get_errmsg());
2419 returnval |= FAILSMART;
2420 }
2421 else
2422 print_apm_level("APM set to level ", options.set_apm-1);
2423 }
2424 else {
2425 if (!ata_set_features(device, ATA_DISABLE_APM)) {
2426 pout("APM disable failed: %s\n", device->get_errmsg());
2427 returnval |= FAILSMART;
2428 }
2429 else
2430 pout("APM disabled\n");
2431 }
2432 }
2433
2434 // Enable/Disable read look-ahead
2435 if (options.set_lookahead) {
2436 bool enable = (options.set_lookahead > 0);
2437 if (!ata_set_features(device, (enable ? ATA_ENABLE_READ_LOOK_AHEAD : ATA_DISABLE_READ_LOOK_AHEAD))) {
2438 pout("Read look-ahead %sable failed: %s\n", (enable ? "en" : "dis"), device->get_errmsg());
2439 returnval |= FAILSMART;
2440 }
2441 else
2442 pout("Read look-ahead %sabled\n", (enable ? "en" : "dis"));
2443 }
2444
2445 // Enable/Disable write cache
2446 if (options.set_wcache) {
2447 bool enable = (options.set_wcache > 0);
2448 if (!ata_set_features(device, (enable ? ATA_ENABLE_WRITE_CACHE : ATA_DISABLE_WRITE_CACHE))) {
2449 pout("Write cache %sable failed: %s\n", (enable ? "en" : "dis"), device->get_errmsg());
2450 returnval |= FAILSMART;
2451 }
2452 else
2453 pout("Write cache %sabled\n", (enable ? "en" : "dis"));
2454 }
2455
2456 // Freeze ATA security
2457 if (options.set_security_freeze) {
2458 if (!ata_nodata_command(device, ATA_SECURITY_FREEZE_LOCK)) {
2459 pout("ATA SECURITY FREEZE LOCK failed: %s\n", device->get_errmsg());
2460 returnval |= FAILSMART;
2461 }
2462 else
2463 pout("ATA Security set to frozen mode\n");
2464 }
2465
2466 // Set standby timer
2467 if (options.set_standby) {
2468 if (!ata_nodata_command(device, ATA_IDLE, options.set_standby-1)) {
2469 pout("ATA IDLE command failed: %s\n", device->get_errmsg());
2470 returnval |= FAILSMART;
2471 }
2472 else
2473 print_standby_timer("Standby timer set to ", options.set_standby-1, drive);
2474 }
2475
2476 // Enable/Disable SMART commands
2477 if (options.smart_enable) {
2478 if (ataEnableSmart(device)) {
2479 pout("Smartctl: SMART Enable Failed.\n\n");
2480 failuretest(MANDATORY_CMD, returnval|=FAILSMART);
2481 }
2482 else {
2483 pout("SMART Enabled.\n");
2484 smart_enabled = 1;
2485 }
2486 }
2487
2488 // Turn off SMART on device
2489 if (options.smart_disable) {
2490 if (ataDisableSmart(device)) {
2491 pout( "Smartctl: SMART Disable Failed.\n\n");
2492 failuretest(MANDATORY_CMD,returnval|=FAILSMART);
2493 }
2494 }
2495
2496 // Exit if SMART is disabled but must be enabled to proceed
2497 if (options.smart_disable || (smart_enabled <= 0 && need_smart_enabled)) {
2498 pout("SMART Disabled. Use option -s with argument 'on' to enable it.\n");
2499 return returnval;
2500 }
2501
2502 // Enable/Disable Auto-save attributes
2503 if (options.smart_auto_save_enable) {
2504 if (ataEnableAutoSave(device)){
2505 pout( "Smartctl: SMART Enable Attribute Autosave Failed.\n\n");
2506 failuretest(MANDATORY_CMD, returnval|=FAILSMART);
2507 }
2508 else
2509 pout("SMART Attribute Autosave Enabled.\n");
2510 }
2511
2512 if (options.smart_auto_save_disable) {
2513 if (ataDisableAutoSave(device)){
2514 pout( "Smartctl: SMART Disable Attribute Autosave Failed.\n\n");
2515 failuretest(MANDATORY_CMD, returnval|=FAILSMART);
2516 }
2517 else
2518 pout("SMART Attribute Autosave Disabled.\n");
2519 }
2520
2521 // Read SMART values and thresholds if necessary
2522 ata_smart_values smartval; memset(&smartval, 0, sizeof(smartval));
2523 ata_smart_thresholds_pvt smartthres; memset(&smartthres, 0, sizeof(smartthres));
2524 bool smart_val_ok = false, smart_thres_ok = false;
2525
2526 if (need_smart_val) {
2527 if (ataReadSmartValues(device, &smartval)) {
2528 pout("Smartctl: SMART Read Values failed.\n\n");
2529 failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
2530 }
2531 else {
2532 smart_val_ok = true;
2533
2534 if (options.smart_check_status || options.smart_vendor_attrib) {
2535 if (ataReadSmartThresholds(device, &smartthres)){
2536 pout("Smartctl: SMART Read Thresholds failed.\n\n");
2537 failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
2538 }
2539 else
2540 smart_thres_ok = true;
2541 }
2542 }
2543 }
2544
2545 // Enable/Disable Off-line testing
2546 bool needupdate = false;
2547 if (options.smart_auto_offl_enable) {
2548 if (!isSupportAutomaticTimer(&smartval)){
2549 pout("Warning: device does not support SMART Automatic Timers.\n\n");
2550 failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
2551 }
2552 needupdate = smart_val_ok;
2553 if (ataEnableAutoOffline(device)){
2554 pout( "Smartctl: SMART Enable Automatic Offline Failed.\n\n");
2555 failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
2556 }
2557 else
2558 pout("SMART Automatic Offline Testing Enabled every four hours.\n");
2559 }
2560
2561 if (options.smart_auto_offl_disable) {
2562 if (!isSupportAutomaticTimer(&smartval)){
2563 pout("Warning: device does not support SMART Automatic Timers.\n\n");
2564 failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
2565 }
2566 needupdate = smart_val_ok;
2567 if (ataDisableAutoOffline(device)){
2568 pout("Smartctl: SMART Disable Automatic Offline Failed.\n\n");
2569 failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
2570 }
2571 else
2572 pout("SMART Automatic Offline Testing Disabled.\n");
2573 }
2574
2575 if (needupdate && ataReadSmartValues(device, &smartval)){
2576 pout("Smartctl: SMART Read Values failed.\n\n");
2577 failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
2578 smart_val_ok = false;
2579 }
2580
2581 // all this for a newline!
2582 if ( options.smart_disable || options.smart_enable
2583 || options.smart_auto_save_disable || options.smart_auto_save_enable
2584 || options.smart_auto_offl_disable || options.smart_auto_offl_enable)
2585 pout("\n");
2586
2587 // START OF READ-ONLY OPTIONS APART FROM -V and -i
2588 if ( options.smart_check_status || options.smart_general_values
2589 || options.smart_vendor_attrib || options.smart_error_log
2590 || options.smart_selftest_log || options.smart_selective_selftest_log
2591 || options.smart_ext_error_log || options.smart_ext_selftest_log
2592 || options.sct_temp_sts || options.sct_temp_hist )
2593 pout("=== START OF READ SMART DATA SECTION ===\n");
2594
2595 // Check SMART status
2596 if (options.smart_check_status) {
2597
2598 switch (ataSmartStatus2(device)) {
2599
2600 case 0:
2601 // The case where the disk health is OK
2602 pout("SMART overall-health self-assessment test result: PASSED\n");
2603 if (smart_thres_ok && find_failed_attr(&smartval, &smartthres, attribute_defs, 0)) {
2604 if (options.smart_vendor_attrib)
2605 pout("See vendor-specific Attribute list for marginal Attributes.\n\n");
2606 else {
2607 print_on();
2608 pout("Please note the following marginal Attributes:\n");
2609 PrintSmartAttribWithThres(&smartval, &smartthres, attribute_defs, 2, options.output_format);
2610 }
2611 returnval|=FAILAGE;
2612 }
2613 else
2614 pout("\n");
2615 break;
2616
2617 case 1:
2618 // The case where the disk health is NOT OK
2619 print_on();
2620 pout("SMART overall-health self-assessment test result: FAILED!\n"
2621 "Drive failure expected in less than 24 hours. SAVE ALL DATA.\n");
2622 print_off();
2623 if (smart_thres_ok && find_failed_attr(&smartval, &smartthres, attribute_defs, 1)) {
2624 returnval|=FAILATTR;
2625 if (options.smart_vendor_attrib)
2626 pout("See vendor-specific Attribute list for failed Attributes.\n\n");
2627 else {
2628 print_on();
2629 pout("Failed Attributes:\n");
2630 PrintSmartAttribWithThres(&smartval, &smartthres, attribute_defs, 1, options.output_format);
2631 }
2632 }
2633 else
2634 pout("No failed Attributes found.\n\n");
2635 returnval|=FAILSTATUS;
2636 print_off();
2637 break;
2638
2639 case -1:
2640 default:
2641 // Something went wrong with the SMART STATUS command.
2642 // The ATA SMART RETURN STATUS command provides the result in the ATA output
2643 // registers. Buggy ATA/SATA drivers and SAT Layers often do not properly
2644 // return the registers values.
2645 failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
2646 if (!(smart_val_ok && smart_thres_ok)) {
2647 print_on();
2648 pout("SMART overall-health self-assessment test result: UNKNOWN!\n"
2649 "SMART Status, Attributes and Thresholds cannot be read.\n\n");
2650 }
2651 else if (find_failed_attr(&smartval, &smartthres, attribute_defs, 1)) {
2652 print_on();
2653 pout("SMART overall-health self-assessment test result: FAILED!\n"
2654 "Drive failure expected in less than 24 hours. SAVE ALL DATA.\n");
2655 print_off();
2656 returnval|=FAILATTR;
2657 returnval|=FAILSTATUS;
2658 if (options.smart_vendor_attrib)
2659 pout("See vendor-specific Attribute list for failed Attributes.\n\n");
2660 else {
2661 print_on();
2662 pout("Failed Attributes:\n");
2663 PrintSmartAttribWithThres(&smartval, &smartthres, attribute_defs, 1, options.output_format);
2664 }
2665 }
2666 else {
2667 pout("SMART overall-health self-assessment test result: PASSED\n");
2668 pout("Warning: This result is based on an Attribute check.\n");
2669 if (find_failed_attr(&smartval, &smartthres, attribute_defs, 0)) {
2670 if (options.smart_vendor_attrib)
2671 pout("See vendor-specific Attribute list for marginal Attributes.\n\n");
2672 else {
2673 print_on();
2674 pout("Please note the following marginal Attributes:\n");
2675 PrintSmartAttribWithThres(&smartval, &smartthres, attribute_defs, 2, options.output_format);
2676 }
2677 returnval|=FAILAGE;
2678 }
2679 else
2680 pout("\n");
2681 }
2682 print_off();
2683 break;
2684 } // end of switch statement
2685
2686 print_off();
2687 } // end of checking SMART Status
2688
2689 // Print general SMART values
2690 if (smart_val_ok && options.smart_general_values)
2691 PrintGeneralSmartValues(&smartval, &drive, fix_firmwarebug);
2692
2693 // Print vendor-specific attributes
2694 if (smart_val_ok && options.smart_vendor_attrib) {
2695 print_on();
2696 PrintSmartAttribWithThres(&smartval, &smartthres, attribute_defs,
2697 (printing_is_switchable ? 2 : 0), options.output_format);
2698 print_off();
2699 }
2700
2701 // If GP Log is supported use smart log directory for
2702 // error and selftest log support check.
2703 if ( isGeneralPurposeLoggingCapable(&drive)
2704 && ( options.smart_error_log || options.smart_selftest_log
2705 || options.retry_error_log || options.retry_selftest_log))
2706 need_smart_logdir = true;
2707
2708 ata_smart_log_directory smartlogdir_buf, gplogdir_buf;
2709 const ata_smart_log_directory * smartlogdir = 0, * gplogdir = 0;
2710
2711 // Read SMART Log directory
2712 if (need_smart_logdir) {
2713 if (ataReadLogDirectory(device, &smartlogdir_buf, false)) {
2714 pout("Read SMART Log Directory failed.\n\n");
2715 failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
2716 }
2717 else
2718 smartlogdir = &smartlogdir_buf;
2719 }
2720
2721 // Read GP Log directory
2722 if (need_gp_logdir) {
2723 if (ataReadLogDirectory(device, &gplogdir_buf, true)) {
2724 pout("Read GP Log Directory failed.\n\n");
2725 failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
2726 }
2727 else
2728 gplogdir = &gplogdir_buf;
2729 }
2730
2731 // Print log directories
2732 if ((options.gp_logdir && gplogdir) || (options.smart_logdir && smartlogdir))
2733 PrintLogDirectories(gplogdir, smartlogdir);
2734
2735 // Print log pages
2736 for (i = 0; i < options.log_requests.size(); i++) {
2737 const ata_log_request & req = options.log_requests[i];
2738
2739 const char * type;
2740 unsigned max_nsectors;
2741 if (req.gpl) {
2742 type = "General Purpose";
2743 max_nsectors = GetNumLogSectors(gplogdir, req.logaddr, true);
2744 }
2745 else {
2746 type = "SMART";
2747 max_nsectors = GetNumLogSectors(smartlogdir, req.logaddr, false);
2748 }
2749
2750 if (!max_nsectors) {
2751 if (!is_permissive()) {
2752 pout("%s Log 0x%02x does not exist (override with '-T permissive' option)\n", type, req.logaddr);
2753 continue;
2754 }
2755 max_nsectors = req.page+1;
2756 }
2757 if (max_nsectors <= req.page) {
2758 pout("%s Log 0x%02x has only %u sectors, output skipped\n", type, req.logaddr, max_nsectors);
2759 continue;
2760 }
2761
2762 unsigned ns = req.nsectors;
2763 if (ns > max_nsectors - req.page) {
2764 if (req.nsectors != ~0U) // "FIRST-max"
2765 pout("%s Log 0x%02x has only %u sectors, output truncated\n", type, req.logaddr, max_nsectors);
2766 ns = max_nsectors - req.page;
2767 }
2768
2769 // SMART log don't support sector offset, start with first sector
2770 unsigned offs = (req.gpl ? 0 : req.page);
2771
2772 raw_buffer log_buf((offs + ns) * 512);
2773 bool ok;
2774 if (req.gpl)
2775 ok = ataReadLogExt(device, req.logaddr, 0x00, req.page, log_buf.data(), ns);
2776 else
2777 ok = ataReadSmartLog(device, req.logaddr, log_buf.data(), offs + ns);
2778 if (!ok)
2779 failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
2780 else
2781 PrintLogPages(type, log_buf.data() + offs*512, req.logaddr, req.page, ns, max_nsectors);
2782 }
2783
2784 // Print SMART Extendend Comprehensive Error Log
2785 bool do_smart_error_log = options.smart_error_log;
2786 if (options.smart_ext_error_log) {
2787 bool ok = false;
2788 unsigned nsectors = GetNumLogSectors(gplogdir, 0x03, true);
2789 if (!nsectors)
2790 pout("SMART Extended Comprehensive Error Log (GP Log 0x03) not supported\n");
2791 else if (nsectors >= 256)
2792 pout("SMART Extended Comprehensive Error Log size %u not supported\n", nsectors);
2793 else {
2794 raw_buffer log_03_buf(nsectors * 512);
2795 ata_smart_exterrlog * log_03 = (ata_smart_exterrlog *)log_03_buf.data();
2796 if (!ataReadExtErrorLog(device, log_03, nsectors))
2797 failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
2798 else {
2799 if (PrintSmartExtErrorLog(log_03, nsectors, options.smart_ext_error_log))
2800 returnval |= FAILERR;
2801 ok = true;
2802 }
2803 }
2804
2805 if (!ok) {
2806 if (options.retry_error_log)
2807 do_smart_error_log = true;
2808 else if (!do_smart_error_log)
2809 pout("Try '-l [xerror,]error' to read traditional SMART Error Log\n");
2810 }
2811 }
2812
2813 // Print SMART error log
2814 if (do_smart_error_log) {
2815 if (!( ( smartlogdir && GetNumLogSectors(smartlogdir, 0x01, false))
2816 || (!smartlogdir && isSmartErrorLogCapable(&smartval, &drive) )
2817 || is_permissive() )) {
2818 pout("SMART Error Log not supported\n");
2819 }
2820 else {
2821 ata_smart_errorlog smarterror; memset(&smarterror, 0, sizeof(smarterror));
2822 if (ataReadErrorLog(device, &smarterror, fix_firmwarebug)) {
2823 pout("Smartctl: SMART Error Log Read Failed\n");
2824 failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
2825 }
2826 else {
2827 // quiet mode is turned on inside PrintSmartErrorLog()
2828 if (PrintSmartErrorlog(&smarterror, fix_firmwarebug))
2829 returnval|=FAILERR;
2830 print_off();
2831 }
2832 }
2833 }
2834
2835 // Print SMART Extendend Self-test Log
2836 bool do_smart_selftest_log = options.smart_selftest_log;
2837 if (options.smart_ext_selftest_log) {
2838 bool ok = false;
2839 unsigned nsectors = GetNumLogSectors(gplogdir, 0x07, true);
2840 if (!nsectors)
2841 pout("SMART Extended Self-test Log (GP Log 0x07) not supported\n");
2842 else if (nsectors >= 256)
2843 pout("SMART Extended Self-test Log size %u not supported\n", nsectors);
2844 else {
2845 raw_buffer log_07_buf(nsectors * 512);
2846 ata_smart_extselftestlog * log_07 = (ata_smart_extselftestlog *)log_07_buf.data();
2847 if (!ataReadExtSelfTestLog(device, log_07, nsectors))
2848 failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
2849 else {
2850 if (PrintSmartExtSelfTestLog(log_07, nsectors, options.smart_ext_selftest_log))
2851 returnval |= FAILLOG;
2852 ok = true;
2853 }
2854 }
2855
2856 if (!ok) {
2857 if (options.retry_selftest_log)
2858 do_smart_selftest_log = true;
2859 else if (!do_smart_selftest_log)
2860 pout("Try '-l [xselftest,]selftest' to read traditional SMART Self Test Log\n");
2861 }
2862 }
2863
2864 // Print SMART self-test log
2865 if (do_smart_selftest_log) {
2866 if (!( ( smartlogdir && GetNumLogSectors(smartlogdir, 0x06, false))
2867 || (!smartlogdir && isSmartTestLogCapable(&smartval, &drive) )
2868 || is_permissive() )) {
2869 pout("SMART Self-test Log not supported\n");
2870 }
2871 else {
2872 ata_smart_selftestlog smartselftest; memset(&smartselftest, 0, sizeof(smartselftest));
2873 if (ataReadSelfTestLog(device, &smartselftest, fix_firmwarebug)) {
2874 pout("Smartctl: SMART Self Test Log Read Failed\n");
2875 failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
2876 }
2877 else {
2878 print_on();
2879 if (ataPrintSmartSelfTestlog(&smartselftest, !printing_is_switchable, fix_firmwarebug))
2880 returnval |= FAILLOG;
2881 print_off();
2882 pout("\n");
2883 }
2884 }
2885 }
2886
2887 // Print SMART selective self-test log
2888 if (options.smart_selective_selftest_log) {
2889 ata_selective_self_test_log log;
2890
2891 if (!isSupportSelectiveSelfTest(&smartval))
2892 pout("Device does not support Selective Self Tests/Logging\n");
2893 else if(ataReadSelectiveSelfTestLog(device, &log)) {
2894 pout("Smartctl: SMART Selective Self Test Log Read Failed\n");
2895 failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
2896 }
2897 else {
2898 print_on();
2899 // If any errors were found, they are logged in the SMART Self-test log.
2900 // So there is no need to print the Selective Self Test log in silent
2901 // mode.
2902 if (!printing_is_switchable)
2903 ataPrintSelectiveSelfTestLog(&log, &smartval);
2904 print_off();
2905 pout("\n");
2906 }
2907 }
2908
2909 // SCT commands
2910 bool sct_ok = false;
2911 if (need_sct_support) {
2912 if (!isSCTCapable(&drive)) {
2913 pout("Warning: device does not support SCT Commands\n");
2914 failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
2915 }
2916 else
2917 sct_ok = true;
2918 }
2919
2920 // Print SCT status and temperature history table
2921 if (sct_ok && (options.sct_temp_sts || options.sct_temp_hist || options.sct_temp_int)) {
2922 for (;;) {
2923 if (options.sct_temp_sts || options.sct_temp_hist) {
2924 ata_sct_status_response sts;
2925 ata_sct_temperature_history_table tmh;
2926 if (!options.sct_temp_hist) {
2927 // Read SCT status only
2928 if (ataReadSCTStatus(device, &sts)) {
2929 failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
2930 break;
2931 }
2932 }
2933 else {
2934 if (!isSCTDataTableCapable(&drive)) {
2935 pout("Warning: device does not support SCT Data Table command\n");
2936 failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
2937 break;
2938 }
2939 // Read SCT status and temperature history
2940 if (ataReadSCTTempHist(device, &tmh, &sts)) {
2941 failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
2942 break;
2943 }
2944 }
2945 if (options.sct_temp_sts)
2946 ataPrintSCTStatus(&sts);
2947 if (options.sct_temp_hist)
2948 ataPrintSCTTempHist(&tmh);
2949 pout("\n");
2950 }
2951 if (options.sct_temp_int) {
2952 // Set new temperature logging interval
2953 if (!isSCTFeatureControlCapable(&drive)) {
2954 pout("Warning: device does not support SCT Feature Control command\n");
2955 failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
2956 break;
2957 }
2958 if (ataSetSCTTempInterval(device, options.sct_temp_int, options.sct_temp_int_pers)) {
2959 failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
2960 break;
2961 }
2962 pout("Temperature Logging Interval set to %u minute%s (%s)\n",
2963 options.sct_temp_int, (options.sct_temp_int == 1 ? "" : "s"),
2964 (options.sct_temp_int_pers ? "persistent" : "volatile"));
2965 }
2966 break;
2967 }
2968 }
2969
2970 // SCT Error Recovery Control
2971 if (sct_ok && (options.sct_erc_get || options.sct_erc_set)) {
2972 if (!isSCTErrorRecoveryControlCapable(&drive)) {
2973 pout("Warning: device does not support SCT Error Recovery Control command\n");
2974 failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
2975 }
2976 else {
2977 bool sct_erc_get = options.sct_erc_get;
2978 if (options.sct_erc_set) {
2979 // Set SCT Error Recovery Control
2980 if ( ataSetSCTErrorRecoveryControltime(device, 1, options.sct_erc_readtime )
2981 || ataSetSCTErrorRecoveryControltime(device, 2, options.sct_erc_writetime)) {
2982 pout("Warning: device does not support SCT (Set) Error Recovery Control command\n");
2983 if (!( (options.sct_erc_readtime == 70 && options.sct_erc_writetime == 70)
2984 || (options.sct_erc_readtime == 0 && options.sct_erc_writetime == 0)))
2985 pout("Retry with: 'scterc,70,70' to enable ERC or 'scterc,0,0' to disable\n");
2986 failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
2987 sct_erc_get = false;
2988 }
2989 else if (!sct_erc_get)
2990 ataPrintSCTErrorRecoveryControl(true, options.sct_erc_readtime,
2991 options.sct_erc_writetime);
2992 }
2993
2994 if (sct_erc_get) {
2995 // Print SCT Error Recovery Control
2996 unsigned short read_timer, write_timer;
2997 if ( ataGetSCTErrorRecoveryControltime(device, 1, read_timer )
2998 || ataGetSCTErrorRecoveryControltime(device, 2, write_timer)) {
2999 pout("Warning: device does not support SCT (Get) Error Recovery Control command\n");
3000 if (options.sct_erc_set) {
3001 pout("The previous SCT (Set) Error Recovery Control command succeeded\n");
3002 ataPrintSCTErrorRecoveryControl(true, options.sct_erc_readtime,
3003 options.sct_erc_writetime);
3004 }
3005 failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
3006 }
3007 else
3008 ataPrintSCTErrorRecoveryControl(false, read_timer, write_timer);
3009 }
3010 pout("\n");
3011 }
3012 }
3013
3014 // Print Device Statistics
3015 if (options.devstat_all_pages || options.devstat_ssd_page || !options.devstat_pages.empty()) {
3016 unsigned nsectors = GetNumLogSectors(gplogdir, 0x04, true);
3017 if (!nsectors)
3018 pout("Device Statistics (GP Log 0x04) not supported\n");
3019 else if (!print_device_statistics(device, nsectors, options.devstat_pages,
3020 options.devstat_all_pages, options.devstat_ssd_page))
3021 failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
3022 }
3023
3024 // Print SATA Phy Event Counters
3025 if (options.sataphy) {
3026 unsigned nsectors = GetNumLogSectors(gplogdir, 0x11, true);
3027 if (!nsectors)
3028 pout("SATA Phy Event Counters (GP Log 0x11) not supported\n");
3029 else if (nsectors != 1)
3030 pout("SATA Phy Event Counters with %u sectors not supported\n", nsectors);
3031 else {
3032 unsigned char log_11[512] = {0, };
3033 unsigned char features = (options.sataphy_reset ? 0x01 : 0x00);
3034 if (!ataReadLogExt(device, 0x11, features, 0, log_11, 1))
3035 failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
3036 else
3037 PrintSataPhyEventCounters(log_11, options.sataphy_reset);
3038 }
3039 }
3040
3041 // Set to standby (spindown) mode
3042 // (Above commands may spinup drive)
3043 if (options.set_standby_now) {
3044 if (!ata_nodata_command(device, ATA_STANDBY_IMMEDIATE)) {
3045 pout("ATA STANDBY IMMEDIATE command failed: %s\n", device->get_errmsg());
3046 returnval |= FAILSMART;
3047 }
3048 else
3049 pout("Device placed in STANDBY mode\n");
3050 }
3051
3052 // START OF THE TESTING SECTION OF THE CODE. IF NO TESTING, RETURN
3053 if (!smart_val_ok || options.smart_selftest_type == -1)
3054 return returnval;
3055
3056 pout("=== START OF OFFLINE IMMEDIATE AND SELF-TEST SECTION ===\n");
3057 // if doing a self-test, be sure it's supported by the hardware
3058 switch (options.smart_selftest_type) {
3059 case OFFLINE_FULL_SCAN:
3060 if (!isSupportExecuteOfflineImmediate(&smartval)){
3061 pout("Warning: device does not support Execute Offline Immediate function.\n\n");
3062 failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
3063 }
3064 break;
3065 case ABORT_SELF_TEST:
3066 case SHORT_SELF_TEST:
3067 case EXTEND_SELF_TEST:
3068 case SHORT_CAPTIVE_SELF_TEST:
3069 case EXTEND_CAPTIVE_SELF_TEST:
3070 if (!isSupportSelfTest(&smartval)){
3071 pout("Warning: device does not support Self-Test functions.\n\n");
3072 failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
3073 }
3074 break;
3075 case CONVEYANCE_SELF_TEST:
3076 case CONVEYANCE_CAPTIVE_SELF_TEST:
3077 if (!isSupportConveyanceSelfTest(&smartval)){
3078 pout("Warning: device does not support Conveyance Self-Test functions.\n\n");
3079 failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
3080 }
3081 break;
3082 case SELECTIVE_SELF_TEST:
3083 case SELECTIVE_CAPTIVE_SELF_TEST:
3084 if (!isSupportSelectiveSelfTest(&smartval)){
3085 pout("Warning: device does not support Selective Self-Test functions.\n\n");
3086 failuretest(MANDATORY_CMD, returnval|=FAILSMART);
3087 }
3088 break;
3089 default:
3090 break; // Vendor specific type
3091 }
3092
3093 // Now do the test. Note ataSmartTest prints its own error/success
3094 // messages
3095 if (ataSmartTest(device, options.smart_selftest_type, options.smart_selftest_force,
3096 options.smart_selective_args, &smartval, sizes.sectors ))
3097 failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
3098 else {
3099 // Tell user how long test will take to complete. This is tricky
3100 // because in the case of an Offline Full Scan, the completion
3101 // timer is volatile, and needs to be read AFTER the command is
3102 // given. If this will interrupt the Offline Full Scan, we don't
3103 // do it, just warn user.
3104 if (options.smart_selftest_type == OFFLINE_FULL_SCAN) {
3105 if (isSupportOfflineAbort(&smartval))
3106 pout("Note: giving further SMART commands will abort Offline testing\n");
3107 else if (ataReadSmartValues(device, &smartval)){
3108 pout("Smartctl: SMART Read Values failed.\n");
3109 failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
3110 }
3111 }
3112
3113 // Now say how long the test will take to complete
3114 int timewait = TestTime(&smartval, options.smart_selftest_type);
3115 if (timewait) {
3116 time_t t=time(NULL);
3117 if (options.smart_selftest_type == OFFLINE_FULL_SCAN) {
3118 t+=timewait;
3119 pout("Please wait %d seconds for test to complete.\n", (int)timewait);
3120 } else {
3121 t+=timewait*60;
3122 pout("Please wait %d minutes for test to complete.\n", (int)timewait);
3123 }
3124 pout("Test will complete after %s\n", ctime(&t));
3125
3126 if ( options.smart_selftest_type != SHORT_CAPTIVE_SELF_TEST
3127 && options.smart_selftest_type != EXTEND_CAPTIVE_SELF_TEST
3128 && options.smart_selftest_type != CONVEYANCE_CAPTIVE_SELF_TEST
3129 && options.smart_selftest_type != SELECTIVE_CAPTIVE_SELF_TEST )
3130 pout("Use smartctl -X to abort test.\n");
3131 }
3132 }
3133
3134 return returnval;
3135 }