14#define __STDC_FORMAT_MACROS 1
41 return (*output ? output :
"[No Information Found]");
68 unsigned char CR,
unsigned char FR,
69 unsigned char ST,
unsigned char ER,
75 const char *error_flag[8];
76 int i, print_lba=0, print_sector=0;
80 const char *abrt =
"ABRT";
81 const char *amnf =
"AMNF";
82 const char *ccto =
"CCTO";
83 const char *eom =
"EOM";
84 const char *icrc =
"ICRC";
85 const char *idnf =
"IDNF";
86 const char *ili =
"ILI";
87 const char *mc =
"MC";
88 const char *mcr =
"MCR";
89 const char *nm =
"NM";
90 const char *obs =
"obs";
91 const char *tk0nf =
"TK0NF";
92 const char *unc =
"UNC";
93 const char *wp =
"WP";
99 int uses_device_fault = 1;
102 for (i = 0; i < 8; i++)
103 error_flag[i] = NULL;
109 error_flag[2] = abrt;
110 error_flag[1] = tk0nf;
119 error_flag[4] = idnf;
121 error_flag[2] = abrt;
123 error_flag[0] = amnf;
128 error_flag[4] = idnf;
129 error_flag[2] = abrt;
130 error_flag[0] = amnf;
136 error_flag[7] = icrc;
139 error_flag[4] = idnf;
141 error_flag[2] = abrt;
143 error_flag[0] = ccto;
150 error_flag[7] = icrc;
153 error_flag[4] = idnf;
155 error_flag[2] = abrt;
157 error_flag[0] = ccto;
167 error_flag[7] = icrc;
170 error_flag[4] = idnf;
172 error_flag[2] = abrt;
174 error_flag[0] = amnf;
176 if (CR==0x25 || CR==0xC8)
187 error_flag[4] = idnf;
189 error_flag[2] = abrt;
195 error_flag[4] = idnf;
196 error_flag[2] = abrt;
201 error_flag[4] = idnf;
202 error_flag[2] = abrt;
203 error_flag[0] = amnf;
211 error_flag[4] = idnf;
213 error_flag[2] = abrt;
215 error_flag[0] = amnf;
224 error_flag[7] =
"Sense key (bit 3)",
225 error_flag[6] =
"Sense key (bit 2)",
226 error_flag[5] =
"Sense key (bit 1)",
227 error_flag[4] =
"Sense key (bit 0)",
228 error_flag[2] = abrt;
236 error_flag[2] = abrt;
240 error_flag[4] = idnf;
241 error_flag[2] = abrt;
245 error_flag[4] = idnf;
246 error_flag[2] = abrt;
255 error_flag[4] = idnf;
256 error_flag[2] = abrt;
260 error_flag[4] = idnf;
261 error_flag[2] = abrt;
270 error_flag[2] = abrt;
273 error_flag[4] = idnf;
274 error_flag[2] = abrt;
284 error_flag[2] = abrt;
299 error_flag[7] = icrc;
302 error_flag[4] = idnf;
304 error_flag[2] = abrt;
306 error_flag[0] = amnf;
313 error_flag[2] = abrt;
321 if (uses_device_fault && (ST & (1 << 5))) {
322 str =
"Device Fault";
330 for (i = 7; i >= 0; i--)
331 if ((ER & (1 << i)) && (error_flag[i])) {
334 str += error_flag[i];
343 str +=
strprintf(
" %d sectors", print_sector);
358 str +=
strprintf(
" at LBA = 0x%08x = %u", lba, lba);
360 else if (lba48_regs) {
376 str +=
strprintf(
" at LBA = 0x%08" PRIx64
" = %" PRIu64, lba48, lba48);
387 data->commands[4].commandreg,
388 data->commands[4].featuresreg,
389 data->error_struct.status,
390 data->error_struct.error_register,
391 data->error_struct.sector_count,
399 data->commands[4].command_register,
400 data->commands[4].features_register,
401 data->error.status_register,
402 data->error.error_register,
403 data->error.count_register_hi << 8 |
data->error.count_register,
414 switch (word168 & 0xF) {
415 case 0x1:
return "5.25 inches";
416 case 0x2:
return "3.5 inches";
417 case 0x3:
return "2.5 inches";
418 case 0x4:
return "1.8 inches";
419 case 0x5:
return "< 1.8 inches";
420 case 0x6:
return "mSATA";
421 case 0x7:
return "M.2";
422 case 0x8:
return "MicroSSD";
423 case 0x9:
return "CFast";
430 for (
int bit = 15; bit >= 0; bit--)
431 if (word & (1 << bit))
443 case 15:
return "ACS >5 (15)";
444 case 14:
return "ACS >5 (14)";
445 case 13:
return "ACS >5 (13)";
446 case 12:
return "ACS-5";
447 case 11:
return "ACS-4";
448 case 10:
return "ACS-3";
449 case 9:
return "ACS-2";
450 case 8:
return "ATA8-ACS";
451 case 7:
return "ATA/ATAPI-7";
452 case 6:
return "ATA/ATAPI-6";
453 case 5:
return "ATA/ATAPI-5";
454 case 4:
return "ATA/ATAPI-4";
455 case 3:
return "ATA-3";
456 case 2:
return "ATA-2";
457 case 1:
return "ATA-1";
473 case 0x0001:
return "ATA-1 X3T9.2/781D prior to revision 4";
474 case 0x0002:
return "ATA-1 published, ANSI X3.221-1994";
475 case 0x0003:
return "ATA-1 X3T9.2/781D revision 4";
476 case 0x0004:
return "ATA-2 published, ANSI X3.279-1996";
477 case 0x0005:
return "ATA-2 X3T10/948D prior to revision 2k";
478 case 0x0006:
return "ATA-3 X3T10/2008D revision 1";
479 case 0x0007:
return "ATA-2 X3T10/948D revision 2k";
480 case 0x0008:
return "ATA-3 X3T10/2008D revision 0";
481 case 0x0009:
return "ATA-2 X3T10/948D revision 3";
482 case 0x000a:
return "ATA-3 published, ANSI X3.298-1997";
483 case 0x000b:
return "ATA-3 X3T10/2008D revision 6";
484 case 0x000c:
return "ATA-3 X3T13/2008D revision 7 and 7a";
485 case 0x000d:
return "ATA/ATAPI-4 X3T13/1153D revision 6";
486 case 0x000e:
return "ATA/ATAPI-4 T13/1153D revision 13";
487 case 0x000f:
return "ATA/ATAPI-4 X3T13/1153D revision 7";
488 case 0x0010:
return "ATA/ATAPI-4 T13/1153D revision 18";
489 case 0x0011:
return "ATA/ATAPI-4 T13/1153D revision 15";
490 case 0x0012:
return "ATA/ATAPI-4 published, ANSI NCITS 317-1998";
491 case 0x0013:
return "ATA/ATAPI-5 T13/1321D revision 3";
492 case 0x0014:
return "ATA/ATAPI-4 T13/1153D revision 14";
493 case 0x0015:
return "ATA/ATAPI-5 T13/1321D revision 1";
494 case 0x0016:
return "ATA/ATAPI-5 published, ANSI NCITS 340-2000";
495 case 0x0017:
return "ATA/ATAPI-4 T13/1153D revision 17";
496 case 0x0018:
return "ATA/ATAPI-6 T13/1410D revision 0";
497 case 0x0019:
return "ATA/ATAPI-6 T13/1410D revision 3a";
498 case 0x001a:
return "ATA/ATAPI-7 T13/1532D revision 1";
499 case 0x001b:
return "ATA/ATAPI-6 T13/1410D revision 2";
500 case 0x001c:
return "ATA/ATAPI-6 T13/1410D revision 1";
501 case 0x001d:
return "ATA/ATAPI-7 published, ANSI INCITS 397-2005";
502 case 0x001e:
return "ATA/ATAPI-7 T13/1532D revision 0";
503 case 0x001f:
return "ACS-3 T13/2161-D revision 3b";
505 case 0x0021:
return "ATA/ATAPI-7 T13/1532D revision 4a";
506 case 0x0022:
return "ATA/ATAPI-6 published, ANSI INCITS 361-2002";
508 case 0x0030:
return "ACS-5 T13/BSR INCITS 558 revision 10";
510 case 0x0027:
return "ATA8-ACS T13/1699-D revision 3c";
511 case 0x0028:
return "ATA8-ACS T13/1699-D revision 6";
512 case 0x0029:
return "ATA8-ACS T13/1699-D revision 4";
514 case 0x0031:
return "ACS-2 T13/2015-D revision 2";
516 case 0x0033:
return "ATA8-ACS T13/1699-D revision 3e";
518 case 0x0039:
return "ATA8-ACS T13/1699-D revision 4c";
520 case 0x0042:
return "ATA8-ACS T13/1699-D revision 3f";
522 case 0x0052:
return "ATA8-ACS T13/1699-D revision 3b";
524 case 0x005e:
return "ACS-4 T13/BSR INCITS 529 revision 5";
526 case 0x006d:
return "ACS-3 T13/2161-D revision 5";
528 case 0x0073:
return "ACS-6 T13/BSR INCITS 558 revision 2";
530 case 0x0082:
return "ACS-2 published, ANSI INCITS 482-2012";
532 case 0x009c:
return "ACS-4 published, ANSI INCITS 529-2018";
534 case 0x0107:
return "ATA8-ACS T13/1699-D revision 2d";
536 case 0x010a:
return "ACS-3 published, ANSI INCITS 522-2014";
538 case 0x0110:
return "ACS-2 T13/2015-D revision 3";
540 case 0x011b:
return "ACS-3 T13/2161-D revision 4";
550 switch (word222 & 0x0fff) {
551 default: snprintf(buf,
sizeof(buf),
552 "Unknown (0x%03x)", word222 & 0x0fff);
return buf;
554 case 0x003:
return "ATA8-APT";
555 case 0x002:
return "ATA/ATAPI-7";
566 switch (
find_msb(word222 & 0x0fff)) {
567 case 11:
return "SATA >3.5 (11)";
568 case 10:
return "SATA 3.5";
569 case 9:
return "SATA 3.4";
570 case 8:
return "SATA 3.3";
571 case 7:
return "SATA 3.2";
572 case 6:
return "SATA 3.1";
573 case 5:
return "SATA 3.0";
574 case 4:
return "SATA 2.6";
575 case 3:
return "SATA 2.5";
576 case 2:
return "SATA II Ext";
577 case 1:
return "SATA 1.0a";
578 case 0:
return "ATA8-AST";
592 default:
return ">6.0 Gb/s (7)";
593 case 6:
return ">6.0 Gb/s (6)";
594 case 5:
return ">6.0 Gb/s (5)";
595 case 4:
return ">6.0 Gb/s (4)";
596 case 3:
return "6.0 Gb/s";
597 case 2:
return "3.0 Gb/s";
598 case 1:
return "1.5 Gb/s";
607 jref[
"sata_value"] = value;
609 jref[
"string"] = str;
612 case 3: ups = 60;
break;
613 case 2: ups = 30;
break;
614 case 1: ups = 15;
break;
617 jref[
"units_per_second"] = ups;
618 jref[
"bits_per_unit"] = 100000000;
622 unsigned short word076,
623 unsigned short word077)
625 int allspeeds = (!(word076 & 0x0001) ? (word076 & 0x00fe) : 0);
626 int maxspeed = (allspeeds ?
find_msb(allspeeds) : 0);
627 int curspeed = (!(word077 & 0x0001) ? ((word077 >> 1) & 0x7) : 0);
632 jout(
"SATA Version is: %s%s%s%s%s%s\n",
633 (verstr ? verstr :
"Unknown"),
634 (maxstr ?
", " :
""), (maxstr ? maxstr :
""),
635 (curstr ?
" (current: " :
""), (curstr ? curstr :
""),
636 (curstr ?
")" :
""));
638 jglb[
"sata_version"][
"string"] = verstr;
639 jglb[
"sata_version"][
"value"] = word222 & 0x0fff;
649 char model[40+1], serial[20+1], firmware[8+1];
661 jglb[
"model_name"] = model;
665 jglb[
"serial_number"] = serial;
667 unsigned oui = 0; uint64_t unique_id = 0;
670 jout(
"LU WWN Device Id: %x %06x %09" PRIx64
"\n", naa, oui, unique_id);
671 jglb[
"wwn"][
"naa"] = naa;
672 jglb[
"wwn"][
"oui"] = oui;
673 jglb[
"wwn"][
"id"] = unique_id;
683 jout(
"Add. Product Id: %s\n", add);
684 jglb[
"ata_additional_product_id"] = add;
689 jglb[
"firmware_version"] = firmware;
693 char num[64], cap[32];
694 jout(
"User Capacity: %s bytes [%s]\n",
697 jglb[
"user_capacity"][
"blocks"].set_unsafe_uint64(sizes.
sectors);
698 jglb[
"user_capacity"][
"bytes"].set_unsafe_uint64(sizes.
capacity);
704 jout(
"Sector Sizes: %u bytes logical, %u bytes physical",
717 jout(
"Rotation Rate: Solid State Device\n");
719 jout(
"Rotation Rate: %d rpm\n", rpm);
721 pout(
"Rotation Rate: Unknown (0x%04x)\n", -rpm);
723 jglb[
"rotation_rate"] = (rpm == 1 ? 0 : rpm);
731 jout(
"Form Factor: %s\n", form_factor);
733 jout(
"Form Factor: Unknown (0x%04x)\n", word168);
734 jglb[
"form_factor"][
"ata_value"] = word168;
736 jglb[
"form_factor"][
"name"] = form_factor;
740 bool trim_sup = !!(drive->
words088_255[169-88] & 0x0001);
742 bool trim_det = !!(word069 & 0x4000), trim_zeroed = !!(word069 & 0x0020);
743 if (trim_sup || rpm == 1)
744 jout(
"TRIM Command: %s%s%s\n",
745 (!trim_sup ?
"Unavailable" :
"Available"),
746 (!(trim_sup && trim_det) ?
"" :
", deterministic"),
747 (!(trim_sup && trim_zeroed) ?
"" :
", zeroed") );
748 jglb[
"trim"][
"supported"] = trim_sup;
750 jglb[
"trim"][
"deterministic"] = trim_det;
751 jglb[
"trim"][
"zeroed"] = trim_zeroed;
756 unsigned short zoned_caps = word069 & 0x3;
758 jout(
"Zoned Device: %s\n",
759 (zoned_caps == 0x1 ?
"Host Aware Zones" :
760 zoned_caps == 0x2 ?
"Device managed zones" :
"Unknown (0x3)"));
761 if (zoned_caps < 0x3)
762 jglb[
"zoned_device"][
"capabilities"] = (zoned_caps == 0x1 ?
"host_aware" :
"device_managed");
766 jout(
"Device is: %s%s%s\n",
767 (dbentry ?
"In smartctl database" :
"Not in smartctl database"),
768 (*dbversion ?
" " :
""), (*dbversion ? dbversion :
""));
769 jglb[
"in_smartctl_database"] = !!dbentry;
793 ataver +=
" (minor revision not indicated)";
797 if (!ataver.empty()) {
798 jglb[
"ata_version"][
"string"] = ataver;
805 if (word222 != 0x0000 && word222 != 0xffff)
switch (word222 >> 12) {
818 pout(
"Transport Type: PCIe (0x%03x)\n", word222 & 0x0fff);
821 pout(
"Transport Type: Unknown (0x%04x)\n", word222);
834 unsigned char stat=status_byte & 0x7f;
838 return "was never started";
840 return "was completed without error";
842 if (status_byte == 0x03)
843 return "is in progress";
845 return "is in a Reserved state";
847 return "was suspended by an interrupting command from host";
849 return "was aborted by an interrupting command from host";
851 return "was aborted by the device with a fatal error";
854 return "is in a Vendor Specific state";
856 return "is in a Reserved state";
864 json::ref jref =
jglb[
"ata_smart_data"][
"offline_data_collection"][
"status"];
866 jout(
"Offline data collection status: (0x%02x)\t",
867 (
int)
data->offline_data_collection_status);
868 jref[
"value"] =
data->offline_data_collection_status;
872 jout(
"Offline data collection activity\n"
875 switch (
data->offline_data_collection_status & 0x7f) {
876 case 0x02: jref[
"passed"] =
true;
break;
877 case 0x06: jref[
"passed"] =
false;
break;
882 if (
data->offline_data_collection_status & 0x80)
883 pout(
"\t\t\t\t\tAuto Offline Data Collection: Enabled.\n");
885 pout(
"\t\t\t\t\tAuto Offline Data Collection: Disabled.\n");
893 unsigned char status =
data->self_test_exec_status;
894 jout(
"Self-test execution status: ");
896 switch (
data->self_test_exec_status >> 4) {
898 jout(
"(%4d)\tThe previous self-test routine completed\n\t\t\t\t\t", status);
899 jout(
"without error or no self-test has ever \n\t\t\t\t\tbeen run.\n");
902 jout(
"(%4d)\tThe self-test routine was aborted by\n\t\t\t\t\t", status);
906 jout(
"(%4d)\tThe self-test routine was interrupted\n\t\t\t\t\t", status);
907 jout(
"by the host with a hard or soft reset.\n");
910 jout(
"(%4d)\tA fatal error or unknown test error\n\t\t\t\t\t", status);
911 jout(
"occurred while the device was executing\n\t\t\t\t\t");
912 jout(
"its self-test routine and the device \n\t\t\t\t\t");
913 jout(
"was unable to complete the self-test \n\t\t\t\t\t");
917 jout(
"(%4d)\tThe previous self-test completed having\n\t\t\t\t\t", status);
918 jout(
"a test element that failed and the test\n\t\t\t\t\t");
919 jout(
"element that failed is not known.\n");
922 jout(
"(%4d)\tThe previous self-test completed having\n\t\t\t\t\t", status);
923 jout(
"the electrical element of the test\n\t\t\t\t\t");
927 jout(
"(%4d)\tThe previous self-test completed having\n\t\t\t\t\t", status);
928 jout(
"the servo (and/or seek) element of the \n\t\t\t\t\t");
929 jout(
"test failed.\n");
932 jout(
"(%4d)\tThe previous self-test completed having\n\t\t\t\t\t", status);
933 jout(
"the read element of the test failed.\n");
936 jout(
"(%4d)\tThe previous self-test completed having\n\t\t\t\t\t", status);
937 jout(
"a test element that failed and the\n\t\t\t\t\t");
938 jout(
"device is suspected of having handling\n\t\t\t\t\t");
943 pout(
"(%4d)\tThe previous self-test routine completed\n\t\t\t\t\t", status);
944 pout(
"with unknown result or self-test in\n\t\t\t\t\t");
945 pout(
"progress with less than 10%% remaining.\n");
948 jout(
"(%4d)\tSelf-test routine in progress...\n\t\t\t\t\t", status);
949 jout(
"%1d0%% of test remaining.\n", status & 0x0f);
953 jout(
"(%4d)\tReserved.\n", status);
957 json::ref jref =
jglb[
"ata_smart_data"][
"self_test"][
"status"];
959 jref[
"value"] = status;
962 switch (status >> 4) {
963 case 0x0: msg =
"completed without error";
break;
964 case 0x1: msg =
"was aborted by the host";
break;
965 case 0x2: msg =
"was interrupted by the host with a reset";
break;
966 case 0x3: msg =
"could not complete due to a fatal or unknown error";
break;
967 case 0x4: msg =
"completed with error (unknown test element)";
break;
968 case 0x5: msg =
"completed with error (electrical test element)";
break;
969 case 0x6: msg =
"completed with error (servo/seek test element)";
break;
970 case 0x7: msg =
"completed with error (read test element)";
break;
971 case 0x8: msg =
"completed with error (handling damage?)";
break;
975 jref[
"string"] = msg;
976 switch (status >> 4) {
977 case 0x1:
case 0x2:
case 0x3:
break;
978 default: jref[
"passed"] = ((status >> 4) == 0x0);
981 else if ((status >> 4) == 0xf) {
982 jref[
"string"] =
strprintf(
"in progress, %u0%% remaining", status & 0xf);
983 jref[
"remaining_percent"] = (status & 0xf) * 10;
989 jout(
"Total time to complete Offline \n");
990 jout(
"data collection: \t\t(%5d) seconds.\n",
991 (
int)
data->total_time_to_complete_off_line);
993 jglb[
"ata_smart_data"][
"offline_data_collection"][
"completion_seconds"] =
994 data->total_time_to_complete_off_line;
1001 jout(
"Offline data collection\n");
1002 jout(
"capabilities: \t\t\t (0x%02x) ",
1003 (
int)
data->offline_data_collection_capability);
1004 jref[
"values"][0] =
data->offline_data_collection_capability;
1006 if (
data->offline_data_collection_capability == 0x00){
1007 jout(
"\tOffline data collection not supported.\n");
1011 "SMART execute Offline immediate." :
1012 "No SMART execute Offline immediate.");
1017 "Auto Offline data collection on/off support.":
1018 "No Auto Offline data collection support.");
1021 "Abort Offline collection upon new\n\t\t\t\t\tcommand.":
1022 "Suspend Offline collection upon new\n\t\t\t\t\tcommand.");
1026 "Offline surface scan supported.":
1027 "No Offline surface scan supported.");
1031 "Self-test supported.":
1032 "No Self-test supported.");
1036 "Conveyance Self-test supported.":
1037 "No Conveyance Self-test supported.");
1041 "Selective Self-test supported.":
1042 "No Selective Self-test supported.");
1051 jout(
"SMART capabilities: ");
1052 jout(
"(0x%04x)\t", (
int)
data->smart_capability);
1053 jref[
"values"][1] =
data->smart_capability;
1055 if (
data->smart_capability == 0x00)
1056 jout(
"Automatic saving of SMART data\t\t\t\t\tis not implemented.\n");
1058 jout(
"%s\n", (
data->smart_capability & 0x01)?
1059 "Saves SMART data before entering\n\t\t\t\t\tpower-saving mode.":
1060 "Does not save SMART data before\n\t\t\t\t\tentering power-saving mode.");
1061 jref[
"attribute_autosave_enabled"] = !!(
data->smart_capability & 0x01);
1067 if (
data->smart_capability & 0x02)
1068 pout(
"\t\t\t\t\tSupports SMART auto save timer.\n");
1075 jout(
"Error logging capability: (0x%02x)\tError logging %ssupported.\n",
1076 data->errorlog_capability, (capable ?
"" :
"NOT "));
1077 jglb[
"ata_smart_data"][
"capabilities"][
"error_logging_supported"] = capable;
1082 jout(
"Short self-test routine \n");
1084 jout(
"recommended polling time: \t (%4d) minutes.\n",
1085 (
int)
data->short_test_completion_time);
1086 jglb[
"ata_smart_data"][
"self_test"][
"polling_minutes"][
"short"] =
1087 data->short_test_completion_time;
1090 jout(
"recommended polling time: \t Not Supported.\n");
1095 jout(
"Extended self-test routine\n");
1097 jout(
"recommended polling time: \t (%4d) minutes.\n",
1099 jglb[
"ata_smart_data"][
"self_test"][
"polling_minutes"][
"extended"] =
1103 jout(
"recommended polling time: \t Not Supported.\n");
1108 jout(
"Conveyance self-test routine\n");
1110 jout(
"recommended polling time: \t (%4d) minutes.\n",
1111 (
int)
data->conveyance_test_completion_time);
1112 jglb[
"ata_smart_data"][
"self_test"][
"polling_minutes"][
"conveyance"] =
1113 data->conveyance_test_completion_time;
1116 jout(
"recommended polling time: \t Not Supported.\n");
1153 switch (defs[
id].raw_format) {
1156 case RAWFMT_SEC2HOUR: minutes = (rawval / 60) % 60; rawval /= 60*60;
break;
1160 rawval &= 0xffffffffULL;
1163 minutes = (int)(rawval >> 32) / (1000*60);
1166 rawval &= 0xffffffffULL;
1170 if (rawval > 0x00ffffffULL)
1172 jglb[
"power_on_time"][
"hours"] = rawval;
1174 jglb[
"power_on_time"][
"minutes"] = minutes;
1178 if (strcmp(name,
"Power_Cycle_Count"))
1180 switch (defs[
id].raw_format) {
1185 if (rawval > 0x00ffffffULL)
1187 jglb[
"power_cycle_count"] = rawval;
1200 int onlyfailed,
unsigned char format)
1205 bool needheader =
true;
1212 unsigned char threshold = 0;
1227 jout(
"SMART Attributes Data Structure revision number: %d\n",(
int)
data->revnumber);
1228 jglb[
"ata_smart_attributes"][
"revision"] =
data->revnumber;
1229 jout(
"Vendor Specific SMART Attributes with Thresholds:\n");
1232 jout(
"ID#%s ATTRIBUTE_NAME FLAG VALUE WORST THRESH TYPE UPDATED WHEN_FAILED RAW_VALUE\n",
1233 (!hexid ?
"" :
" "));
1235 jout(
"ID#%s ATTRIBUTE_NAME FLAGS VALUE WORST THRESH FAIL RAW_VALUE\n",
1236 (!hexid ?
"" :
" "));
1241 std::string valstr, worstr, threstr;
1246 valstr = (!hexval ?
"---" :
"----");
1251 worstr = (!hexval ?
"---" :
"----");
1253 threstr = (!hexval ?
strprintf(
"%.3d", threshold)
1256 threstr = (!hexval ?
"---" :
"----");
1259 std::string idstr = (!hexid ?
strprintf(
"%3d", attr.
id)
1276 jout(
"%s %-24s0x%04x %-4s %-4s %-4s %-10s%-9s%-12s%s\n",
1277 idstr.c_str(), attrname.c_str(), attr.
flags,
1278 valstr.c_str(), worstr.c_str(), threstr.c_str(),
1286 jout(
"%s %-24s%s %-4s %-4s %-4s %-5s%s\n",
1287 idstr.c_str(), attrname.c_str(), flagstr,
1288 valstr.c_str(), worstr.c_str(), threstr.c_str(),
1297 json::ref jref =
jglb[
"ata_smart_attributes"][
"table"][ji++];
1298 jref[
"id"] = attr.
id;
1299 jref[
"name"] = attrname;
1303 jref[
"worst"] = attr.
worst;
1305 jref[
"thresh"] = threshold;
1312 jreff[
"value"] = attr.
flags;
1313 jreff[
"string"] = flagstr;
1324 jref[
"raw"][
"value"] = rawval;
1325 jref[
"raw"][
"string"] = rawstr;
1331 if (!onlyfailed && brief) {
1332 int n = (!hexid ? 28 : 29);
1333 jout(
"%*s||||||_ K auto-keep\n"
1334 "%*s|||||__ C event count\n"
1335 "%*s||||___ R error rate\n"
1336 "%*s|||____ S speed/performance\n"
1337 "%*s||_____ O updated online\n"
1338 "%*s|______ P prefailure warning\n",
1339 n,
"", n,
"", n,
"", n,
"", n,
"", n,
"");
1350 jglb[
"temperature"][
"current"] = t;
1357 if (!(sctcaps & 0x01))
1360 jout(
"SCT capabilities: \t (0x%04x)\tSCT Status supported.\n", sctcaps);
1361 jref[
"value"] = sctcaps;
1363 jout(
"\t\t\t\t\tSCT Error Recovery Control supported.\n");
1364 jref[
"error_recovery_control_supported"] = !!(sctcaps & 0x08);
1366 jout(
"\t\t\t\t\tSCT Feature Control supported.\n");
1367 jref[
"feature_control_supported"] = !!(sctcaps & 0x10);
1369 jout(
"\t\t\t\t\tSCT Data Table supported.\n");
1370 jref[
"data_table_supported"] = !!(sctcaps & 0x20);
1377 jout(
"General SMART Values:\n");
1392 "General Purpose Logging supported.":
1393 "No General Purpose Logging support.");
1394 jglb[
"ata_smart_data"][
"capabilities"][
"gp_logging_supported"] =
1435 case 0x00:
return "Log Directory";
1436 case 0x01:
return "Summary SMART error log";
1437 case 0x02:
return "Comprehensive SMART error log";
1438 case 0x03:
return "Ext. Comprehensive SMART error log";
1439 case 0x04:
return "Device Statistics log";
1440 case 0x05:
return "Reserved for CFA";
1441 case 0x06:
return "SMART self-test log";
1442 case 0x07:
return "Extended self-test log";
1443 case 0x08:
return "Power Conditions log";
1444 case 0x09:
return "Selective self-test log";
1445 case 0x0a:
return "Device Statistics Notification";
1446 case 0x0b:
return "Reserved for CFA";
1447 case 0x0c:
return "Pending Defects log";
1448 case 0x0d:
return "LPS Mis-alignment log";
1449 case 0x0e:
return "Reserved for ZAC-2";
1450 case 0x0f:
return "Sense Data for Successful NCQ Cmds log";
1451 case 0x10:
return "NCQ Command Error log";
1452 case 0x11:
return "SATA Phy Event Counters log";
1454 case 0x12:
return "SATA NCQ Non-Data log";
1455 case 0x13:
return "SATA NCQ Send and Receive log";
1456 case 0x14:
return "Hybrid Information log";
1457 case 0x15:
return "Rebuild Assist log";
1458 case 0x16:
return "Out Of Band Management Control log";
1459 case 0x17:
return "Reserved for Serial ATA";
1460 case 0x18:
return "Command Duration Limits log";
1461 case 0x19:
return "LBA Status log";
1463 case 0x20:
return "Streaming performance log";
1464 case 0x21:
return "Write stream error log";
1465 case 0x22:
return "Read stream error log";
1466 case 0x23:
return "Delayed sector log";
1467 case 0x24:
return "Current Device Internal Status Data log";
1468 case 0x25:
return "Saved Device Internal Status Data log";
1470 case 0x2f:
return "Set Sector Configuration";
1471 case 0x30:
return "IDENTIFY DEVICE data log";
1473 case 0x42:
return "Mutate Configurations log";
1475 case 0x47:
return "Concurrent Positioning Ranges log";
1477 case 0x53:
return "Sense Data log";
1479 case 0x59:
return "Power Consumption Control log";
1481 case 0x61:
return "Capacity/Model Number Mapping log";
1483 case 0xe0:
return "SCT Command/Status";
1484 case 0xe1:
return "SCT Data Transfer";
1486 if (0xa0 <= logaddr && logaddr <= 0xdf)
1487 return "Device vendor specific log";
1488 if (0x80 <= logaddr && logaddr <= 0x9f)
1489 return "Host vendor specific log";
1498 if ( ( logaddr <= 0x08)
1499 || (0x0c <= logaddr && logaddr <= 0x0d)
1500 || (0x0f <= logaddr && logaddr <= 0x14)
1501 || (0x19 == logaddr)
1502 || (0x20 <= logaddr && logaddr <= 0x25)
1503 || (0x2f <= logaddr && logaddr <= 0x30)
1504 || (0x42 == logaddr)
1505 || (0x47 == logaddr)
1506 || (0x53 == logaddr)
1507 || (0x59 == logaddr)
1508 || (0x61 == logaddr))
1511 if ( ( logaddr <= 0x0a)
1512 || (0x15 <= logaddr && logaddr <= 0x16)
1513 || (0x18 == logaddr)
1514 || (0x80 <= logaddr && logaddr <= 0x9f)
1515 || (0xe0 <= logaddr && logaddr <= 0xe1))
1518 if (0xa0 <= logaddr && logaddr <= 0xdf)
1528 memset(logdir, 0,
sizeof(*logdir));
1546 jout(
"General Purpose Log Directory Version %u\n", gplogdir->
logversion);
1547 jref[
"gp_dir_version"] = gplogdir->
logversion;
1550 jout(
"SMART %sLog Directory Version %u%s\n",
1551 (gplogdir ?
" " :
""), smartlogdir->
logversion,
1552 (smartlogdir->
logversion==1 ?
" [multi-sector log support]" :
""));
1553 jref[
"smart_dir_version"] = smartlogdir->
logversion;
1554 jref[
"smart_dir_multi_sector"] = (smartlogdir->
logversion == 1);
1557 jout(
"Address Access R/W Size Description\n");
1559 for (
unsigned i = 0, ji = 0; i <= 0xff; i++) {
1564 if (!(smart_numsect || gp_numsect))
1567 const char * acc;
unsigned size;
1568 if (smart_numsect == gp_numsect) {
1569 acc =
"GPL,SL";
size = gp_numsect;
1571 else if (!smart_numsect) {
1572 acc =
"GPL";
size = gp_numsect;
1574 else if (!gp_numsect) {
1575 acc =
" SL";
size = smart_numsect;
1582 if (acc && ((0x80 <= i && i < 0x9f) || (0xa0 <= i && i < 0xdf))) {
1584 unsigned imax = (i < 0x9f ? 0x9f : 0xdf);
1585 for (
unsigned j = i+1; j <= imax; j++) {
1589 if (!(sn == smart_numsect && gn == gp_numsect))
1599 jout(
"0x%02x-0x%02x %-6s %-3s %5u %s\n", i, i2, acc, rw,
size, name);
1601 jout(
"0x%02x %-6s %-3s %5u %s\n", i, acc, rw,
size, name);
1604 jout(
"0x%02x %-6s %-3s %5u %s\n", i,
"GPL", rw, gp_numsect, name);
1605 jout(
"0x%02x %-6s %-3s %5u %s\n", i,
"SL", rw, smart_numsect, name);
1610 jrefi[
"address"] = i;
1611 jrefi[
"name"] = name;
1612 if (rw[0] ==
'R' && rw[1] && rw[2]) {
1613 jrefi[
"read"] =
true;
1614 jrefi[
"write"] = (rw[2] ==
'W');
1617 jrefi[
"gp_sectors"] = gp_numsect;
1619 jrefi[
"smart_sectors"] = smart_numsect;
1631 unsigned char logaddr,
unsigned page,
1632 unsigned num_pages,
unsigned max_pages)
1634 pout(
"%s Log 0x%02x [%s], Page %u-%u (of %u)\n",
1635 type, logaddr,
GetLogName(logaddr), page, page+num_pages-1, max_pages);
1636 for (
unsigned i = 0; i < num_pages * 512; i += 16) {
1637 const unsigned char * p =
data+i;
1638 pout(
"%07x: %02x %02x %02x %02x %02x %02x %02x %02x "
1639 "%02x %02x %02x %02x %02x %02x %02x %02x ",
1641 p[ 0], p[ 1], p[ 2], p[ 3], p[ 4], p[ 5], p[ 6], p[ 7],
1642 p[ 8], p[ 9], p[10], p[11], p[12], p[13], p[14], p[15]);
1643#define P(n) (' ' <= p[n] && p[n] <= '~' ? (int)p[n] : '.')
1644 pout(
"|%c%c%c%c%c%c%c%c"
1645 "%c%c%c%c%c%c%c%c|\n",
1646 P( 0),
P( 1),
P( 2),
P( 3),
P( 4),
P( 5),
P( 6),
P( 7),
1647 P( 8),
P( 9),
P(10),
P(11),
P(12),
P(13),
P(14),
P(15));
1649 if ((i & 0x1ff) == 0x1f0)
1667 { 2,
"List of supported log pages" },
1672 { 2,
"General Statistics" },
1673 { 4,
"Lifetime Power-On Resets" },
1674 { 4,
"Power-on Hours" },
1675 { 6,
"Logical Sectors Written" },
1676 { 6,
"Number of Write Commands" },
1677 { 6,
"Logical Sectors Read" },
1678 { 6,
"Number of Read Commands" },
1679 { 6,
"Date and Time TimeStamp" },
1680 { 4,
"Pending Error Count" },
1681 { 2,
"Workload Utilization" },
1682 { 6,
"Utilization Usage Rate" },
1683 { 7,
"Resource Availability" },
1684 { 1,
"Random Write Resources Used" },
1689 { 2,
"Free-Fall Statistics" },
1690 { 4,
"Number of Free-Fall Events Detected" },
1691 { 4,
"Overlimit Shock Events" },
1696 { 2,
"Rotating Media Statistics" },
1697 { 4,
"Spindle Motor Power-on Hours" },
1698 { 4,
"Head Flying Hours" },
1699 { 4,
"Head Load Events" },
1700 { 4,
"Number of Reallocated Logical Sectors" },
1701 { 4,
"Read Recovery Attempts" },
1702 { 4,
"Number of Mechanical Start Failures" },
1703 { 4,
"Number of Realloc. Candidate Logical Sectors" },
1704 { 4,
"Number of High Priority Unload Events" },
1709 { 2,
"General Errors Statistics" },
1710 { 4,
"Number of Reported Uncorrectable Errors" },
1712 { 4,
"Resets Between Cmd Acceptance and Completion" },
1713 { 4,
"Physical Element Status Changed" },
1718 { 2,
"Temperature Statistics" },
1719 { -1,
"Current Temperature" },
1720 { -1,
"Average Short Term Temperature" },
1721 { -1,
"Average Long Term Temperature" },
1722 { -1,
"Highest Temperature" },
1723 { -1,
"Lowest Temperature" },
1724 { -1,
"Highest Average Short Term Temperature" },
1725 { -1,
"Lowest Average Short Term Temperature" },
1726 { -1,
"Highest Average Long Term Temperature" },
1727 { -1,
"Lowest Average Long Term Temperature" },
1728 { 4,
"Time in Over-Temperature" },
1729 { -1,
"Specified Maximum Operating Temperature" },
1730 { 4,
"Time in Under-Temperature" },
1731 { -1,
"Specified Minimum Operating Temperature" },
1736 { 2,
"Transport Statistics" },
1737 { 4,
"Number of Hardware Resets" },
1738 { 4,
"Number of ASR Events" },
1739 { 4,
"Number of Interface CRC Errors" },
1744 { 2,
"Solid State Device Statistics" },
1745 { 1,
"Percentage Used Endurance Indicator" },
1770 return "Vendor Specific Statistics";
1771 return "Unknown Statistics";
1779 case 0x008:
jglb[
"power_cycle_count"] = val;
break;
1780 case 0x010:
jglb[
"power_on_time"][
"hours"]= val;
break;
1785 case 0x008:
jglb[
"temperature"][
"current"] = val;
break;
1786 case 0x020:
jglb[
"temperature"][
"lifetime_max"] = val;
break;
1787 case 0x028:
jglb[
"temperature"][
"lifetime_min"] = val;
break;
1788 case 0x050:
jglb[
"temperature"][
"lifetime_over_limit_minutes"] = val;
break;
1789 case 0x058:
jglb[
"temperature"][
"op_limit_max"] = val;
break;
1790 case 0x060:
jglb[
"temperature"][
"lifetime_under_limit_minutes"] = val;
break;
1791 case 0x068:
jglb[
"temperature"][
"op_limit_min"] = val;
break;
1803 static const char line[] =
" ===== = = === == ";
1805 pout(
"0x%02x%s%s (empty) ==\n", page, line, name);
1808 if (
data[2] != page) {
1809 pout(
"0x%02x%s%s (invalid page 0x%02x in header) ==\n", page, line, name,
data[2]);
1813 int rev =
data[0] | (
data[1] << 8);
1814 jout(
"0x%02x%s%s (rev %d) ==\n", page, line, name, rev);
1815 jref[
"number"] = page;
1816 jref[
"name"] = name;
1817 jref[
"revision"] = rev;
1821 for (
int i = 1, offset = 8; offset < 512-7; i++, offset+=8) {
1823 if (info && !info[i].
size)
1828 if (!(
flags & 0x80))
1832 if (!info && (
data[offset+5] ||
data[offset+6])) {
1833 pout(
"0x%02x 0x%03x - - [Trailing garbage ignored]\n", page, offset);
1838 const char * valname = (info ? info[i].
name :
1839 (page == 0xff) ?
"Vendor Specific"
1843 int size = (info ? info[i].
size : 7);
1846 bool valid = !!(
flags & 0x40);
1847 bool normalized = !!(
flags & 0x20);
1848 bool supports_dsn = !!(
flags & 0x10);
1849 bool monitored_condition_met = !!(
flags & 0x08);
1851 unsigned char reserved_flags = (
flags & 0x07);
1859 val = (
signed char)
data[offset];
1862 for (
int j = 0; j <
size; j++)
1863 val |= (int64_t)
data[offset+j] << (j*8);
1865 snprintf(valstr,
sizeof(valstr),
"%" PRId64, val);
1869 valstr[0] =
'-'; valstr[1] = 0;
1873 (valid ?
'V' :
'-'),
1874 (normalized ?
'N' :
'-'),
1875 (supports_dsn ?
'D' :
'-'),
1876 (monitored_condition_met ?
'C' :
'-'),
1877 (reserved_flags ?
'+' :
' '),
1881 jout(
"0x%02x 0x%03x %d %15s %s %s\n",
1882 page, offset, abs(
size), valstr, flagstr+1, valname);
1888 jrefi[
"offset"] = offset;
1889 jrefi[
"name"] = valname;
1890 jrefi[
"size"] = abs(
size);
1892 jrefi[
"value"] = val;
1895 jreff[
"value"] =
flags;
1896 jreff[
"string"] = flagstr;
1897 jreff[
"valid"] = valid;
1898 jreff[
"normalized"] = normalized;
1899 jreff[
"supports_dsn"] = supports_dsn;
1900 jreff[
"monitored_condition_met"] = monitored_condition_met;
1902 jreff[
"other"] = reserved_flags;
1910 const std::vector<int> & single_pages,
bool all_pages,
bool ssd_page,
1914 unsigned char page_0[512] = {0, };
1922 jerr(
"Read Device Statistics page 0x00 failed\n\n");
1926 unsigned char nentries = page_0[8];
1927 if (!(page_0[2] == 0 && nentries > 0)) {
1928 jerr(
"Device Statistics page 0x00 is invalid (page=0x%02x, nentries=%d)\n\n", page_0[2], nentries);
1933 std::vector<int> pages;
1937 for (i = 0; i < nentries; i++) {
1938 int page = page_0[8+1+i];
1940 pages.push_back(page);
1945 bool print_page_0 =
false;
1946 for (i = 0; i < single_pages.size() || ssd_page; i++) {
1947 int page = (i < single_pages.size() ? single_pages[i] : 0x07);
1949 print_page_0 =
true;
1950 else if (page >= (
int)nsectors)
1951 pout(
"Device Statistics Log has only 0x%02x pages\n", nsectors);
1953 pages.push_back(page);
1962 pout(
"Device Statistics (%s Log 0x04) supported pages\n",
1963 use_gplog ?
"GP" :
"SMART");
1964 jout(
"Page Description\n");
1965 for (i = 0; i < nentries; i++) {
1966 int page = page_0[8+1+i];
1968 jout(
"0x%02x %s\n", page, name);
1969 jref[
"supported_pages"][i][
"number"] = page;
1970 jref[
"supported_pages"][i][
"name"] = name;
1976 if (!pages.empty()) {
1977 pout(
"Device Statistics (%s Log 0x04)\n",
1978 use_gplog ?
"GP" :
"SMART");
1979 jout(
"Page Offset Size Value Flags Description\n");
1983 for (i = 0; i < pages.size(); i++) {
1984 int page = pages[i];
1985 if (max_page < page && page < 0xff)
1992 jerr(
"Read Device Statistics pages 0x00-0x%02x failed\n\n", max_page);
1997 for (i = 0; i < pages.size(); i++) {
1998 int page = pages[i];
2001 jerr(
"Read Device Statistics page 0x%02x failed\n\n", page);
2005 else if (page > max_page)
2008 int offset = (use_gplog ? 0 : page * 512);
2012 jout(
"%32s|||_ C monitored condition met\n",
"");
2013 jout(
"%32s||__ D supports DSN\n",
"");
2014 jout(
"%32s|___ N normalized value\n\n",
"");
2027 unsigned max_entries)
2030 unsigned char page_buf[512] = {0, };
2032 pout(
"Read Pending Defects log page 0x00 failed\n\n");
2036 jout(
"Pending Defects log (GP Log 0x0c)\n");
2039 jref[
"size"] = nsectors * 32 - 1;
2040 jref[
"count"] = nentries;
2042 jout(
"No Defects Logged\n\n");
2047 jout(
"Index LBA Hours\n");
2048 for (
unsigned i = 0, pi = 1, page = 0; i < nentries && i < max_entries; i++, pi++) {
2051 if (++page >= nsectors) {
2052 pout(
"Pending Defects count %u exceeds log size (#pages=%u)\n\n",
2053 nentries, nsectors);
2057 pout(
"Read Pending Defects log page 0x%02x failed\n\n", page);
2063 const unsigned char *
entry = page_buf + 16 * pi;
2066 if (hours != 0xffffffffU)
2067 snprintf(hourstr,
sizeof(hourstr),
"%u", hours);
2069 hourstr[0] =
'-', hourstr[1] = 0;
2071 jout(
"%5u %18" PRIu64
" %8s\n", i, lba, hourstr);
2075 if (hours != 0xffffffffU)
2076 jrefi[
"power_on_hours"] = hours;
2079 if (nentries > max_entries)
2080 pout(
"... (%u entries not shown)\n", nentries - max_entries);
2093 jout(
"SATA Phy Event Counters (GP Log 0x11)\n");
2095 pout(
"[Reserved: 0x%02x 0x%02x 0x%02x 0x%02x]\n",
2097 jout(
"ID Size Value Description\n");
2099 for (
unsigned i = 4, ji = 0; ; ) {
2101 unsigned id =
data[i] | (
data[i+1] << 8);
2102 unsigned size = ((
id >> 12) & 0x7) << 1;
2111 pout(
"0x%04x %u: Invalid entry\n",
id,
size);
2116 uint64_t val = 0, max_val = 0;
2117 for (
unsigned j = 0; j <
size; j+=2) {
2118 val |= (uint64_t)(
data[i+j] | (
data[i+j+1] << 8)) << (j*8);
2119 max_val |= (uint64_t)0xffffU << (j*8);
2126 case 0x001: name =
"Command failed due to ICRC error";
break;
2127 case 0x002: name =
"R_ERR response for data FIS";
break;
2128 case 0x003: name =
"R_ERR response for device-to-host data FIS";
break;
2129 case 0x004: name =
"R_ERR response for host-to-device data FIS";
break;
2130 case 0x005: name =
"R_ERR response for non-data FIS";
break;
2131 case 0x006: name =
"R_ERR response for device-to-host non-data FIS";
break;
2132 case 0x007: name =
"R_ERR response for host-to-device non-data FIS";
break;
2133 case 0x008: name =
"Device-to-host non-data FIS retries";
break;
2134 case 0x009: name =
"Transition from drive PhyRdy to drive PhyNRdy";
break;
2135 case 0x00A: name =
"Device-to-host register FISes sent due to a COMRESET";
break;
2136 case 0x00B: name =
"CRC errors within host-to-device FIS";
break;
2137 case 0x00D: name =
"Non-CRC errors within host-to-device FIS";
break;
2138 case 0x00F: name =
"R_ERR response for host-to-device data FIS, CRC";
break;
2139 case 0x010: name =
"R_ERR response for host-to-device data FIS, non-CRC";
break;
2140 case 0x012: name =
"R_ERR response for host-to-device non-data FIS, CRC";
break;
2141 case 0x013: name =
"R_ERR response for host-to-device non-data FIS, non-CRC";
break;
2142 default: name = ((
id & 0x8000) ?
"Vendor specific" :
"Unknown");
break;
2146 jout(
"0x%04x %u %12" PRIu64
"%c %s\n",
id,
size, val,
2147 (val == max_val ?
'+' :
' '), name);
2149 json::ref jref =
jglb[
"sata_phy_event_counters"][
"table"][ji++];
2151 jref[
"name"] = name;
2152 jref[
"size"] =
size;
2153 jref[
"value"] = val;
2154 jref[
"overflow"] = (val == max_val);
2157 jout(
"All counters reset\n");
2159 jglb[
"sata_phy_event_counters"][
"reset"] = reset;
2165 unsigned days = msec / 86400000U;
2166 msec -= days * 86400000U;
2167 unsigned hours = msec / 3600000U;
2168 msec -= hours * 3600000U;
2169 unsigned min = msec / 60000U;
2170 msec -= min * 60000U;
2171 unsigned sec = msec / 1000U;
2172 msec -= sec * 1000U;
2177 str +=
strprintf(
"%02u:%02u:%02u.%03u", hours, min, sec, msec);
2186 case 0x0:
return "in an unknown state";
2187 case 0x1:
return "sleeping";
2188 case 0x2:
return "in standby mode";
2189 case 0x3:
return "active or idle";
2190 case 0x4:
return "doing SMART Offline or Self-test";
2192 return (state < 0xb ?
"in a reserved state"
2193 :
"in a vendor specific state");
2202 jout(
"SMART Error Log Version: %d\n", (
int)
data->revnumber);
2203 jref[
"revision"] =
data->revnumber;
2207 if ( !( !
data->ata_error_count == !
data->error_log_pointer
2208 && !((
data->ata_error_count -
data->error_log_pointer) % 5))
2210 pout(
"Warning: ATA error count %d inconsistent with error log index %d\n",
2211 data->ata_error_count,
data->error_log_pointer);
2214 if (!(
data->ata_error_count &&
data->error_log_pointer)) {
2215 jout(
"No Errors Logged\n\n");
2221 if (
data->error_log_pointer>5){
2222 pout(
"Invalid Error Log index = 0x%02x (valid range is from 1 to 5)\n",
2223 data->error_log_pointer);
2224 pout(
"ATA Error Count: %d (possibly also invalid)\n\n",
data->ata_error_count);
2229 if (
data->ata_error_count<=5)
2230 jout(
"ATA Error Count: %d\n", (
int)
data->ata_error_count);
2232 jout(
"ATA Error Count: %d (device log contains only the most recent five errors)\n",
2233 (
int)
data->ata_error_count);
2234 jref[
"count"] =
data->ata_error_count;
2235 jref[
"logged_count"] = (
data->ata_error_count <= 5 ?
data->ata_error_count : 5);
2238 jout(
"\tCR = Command Register [HEX]\n"
2239 "\tFR = Features Register [HEX]\n"
2240 "\tSC = Sector Count Register [HEX]\n"
2241 "\tSN = Sector Number Register [HEX]\n"
2242 "\tCL = Cylinder Low Register [HEX]\n"
2243 "\tCH = Cylinder High Register [HEX]\n"
2244 "\tDH = Device/Head Register [HEX]\n"
2245 "\tDC = Device Command Register [HEX]\n"
2246 "\tER = Error register [HEX]\n"
2247 "\tST = Status register [HEX]\n"
2248 "Powered_Up_Time is measured from power on, and printed as\n"
2249 "DDd+hh:mm:SS.sss where DD=days, hh=hours, mm=minutes,\n"
2250 "SS=sec, and sss=millisec. It \"wraps\" after 49.710 days.\n\n");
2253 for (
int k = 4, ji = 0; k >= 0; k--) {
2256 int i = (
data->error_log_pointer + k) % 5;
2261 if (
nonempty(elog,
sizeof(*elog))){
2268 jout(
"Error %d occurred at disk power-on lifetime: %d hours (%d days + %d hours)\n",
2273 jrefi[
"error_number"] =
data->ata_error_count + k - 4;
2274 jrefi[
"lifetime_hours"] = summary->
timestamp;
2276 jout(
" When the command that caused the error occurred, the device was %s.\n\n", msgstate);
2277 jout(
" After command completion occurred, registers were:\n"
2278 " ER ST SC SN CL CH DH\n"
2279 " -- -- -- -- -- -- --\n"
2280 " %02x %02x %02x %02x %02x %02x %02x",
2290 json::ref jrefir = jrefi[
"completion_registers"];
2292 jrefir[
"status"] = summary->
status;
2303 if (!st_er_desc.empty()) {
2304 jout(
" %s", st_er_desc.c_str());
2305 jrefi[
"error_description"] = st_er_desc;
2308 jout(
" Commands leading to the command that caused the error were:\n"
2309 " CR FR SC SN CL CH DH DC Powered_Up_Time Command/Feature_Name\n"
2310 " -- -- -- -- -- -- -- -- ---------------- --------------------\n");
2311 for (
int j = 4, jj = 0; j >= 0; j--) {
2315 if (
nonempty(thiscommand,
sizeof(*thiscommand))) {
2317 jout(
" %02x %02x %02x %02x %02x %02x %02x %02x %16s %s\n",
2329 json::ref jrefic = jrefi[
"previous_commands"][jj++];
2330 json::ref jreficr = jrefic[
"registers"];
2331 jreficr[
"command"] = thiscommand->
commandreg;
2339 jrefic[
"powerup_milliseconds"] = thiscommand->
timestamp;
2340 jrefic[
"command_name"] = atacmd;
2350 return data->ata_error_count;
2357 unsigned nsectors,
unsigned max_errors)
2360 jout(
"SMART Extended Comprehensive Error Log Version: %u (%u sectors)\n",
2362 jref[
"revision"] = log->
version;
2363 jref[
"sectors"] = nsectors;
2366 jout(
"No Errors Logged\n\n");
2373 unsigned nentries = nsectors * 4;
2375 if (!(1 <= erridx && erridx <= nentries)){
2380 pout(
"Invalid Error Log index = 0x%04x (reserved = 0x%02x)\n", erridx, log->
reserved1);
2384 pout(
"Invalid Error Log index = 0x%04x, trying reserved byte (0x%02x) instead\n", erridx, log->
reserved1);
2395 if (errcnt <= nentries)
2399 jout(
"Device Error Count: %u (device log contains only the most recent %u errors)\n",
2403 jref[
"logged_count"] = errcnt;
2405 if (max_errors < errcnt)
2406 errcnt = max_errors;
2409 jout(
"\tCR = Command Register\n"
2410 "\tFEATR = Features Register\n"
2411 "\tCOUNT = Count (was: Sector Count) Register\n"
2412 "\tLBA_48 = Upper bytes of LBA High/Mid/Low Registers ] ATA-8\n"
2413 "\tLH = LBA High (was: Cylinder High) Register ] LBA\n"
2414 "\tLM = LBA Mid (was: Cylinder Low) Register ] Register\n"
2415 "\tLL = LBA Low (was: Sector Number) Register ]\n"
2416 "\tDV = Device (was: Device/Head) Register\n"
2417 "\tDC = Device Control Register\n"
2418 "\tER = Error register\n"
2419 "\tST = Status register\n"
2420 "Powered_Up_Time is measured from power on, and printed as\n"
2421 "DDd+hh:mm:SS.sss where DD=days, hh=hours, mm=minutes,\n"
2422 "SS=sec, and sss=millisec. It \"wraps\" after 49.710 days.\n\n");
2426 unsigned log_buf_page = ~0;
2430 i < errcnt; i++, errnum--, erridx = (erridx > 0 ? erridx - 1 : nentries - 1)) {
2434 unsigned page = erridx / 4;
2438 if (page != log_buf_page) {
2439 memset(&log_buf, 0,
sizeof(log_buf));
2442 log_buf_page = page;
2450 jrefi[
"error_number"] = errnum;
2451 jrefi[
"log_index"] = erridx;
2455 jout(
"Error %u [%u] log entry is empty\n", errnum, erridx);
2462 jout(
"Error %u [%u] occurred at disk power-on lifetime: %u hours (%u days + %u hours)\n",
2465 jrefi[
"lifetime_hours"] = err.
timestamp;
2468 jout(
" When the command that caused the error occurred, the device was %s.\n\n", msgstate);
2469 jrefi[
"device_state"][
"value"] = err.
state;
2470 jrefi[
"device_state"][
"string"] = msgstate;
2473 jout(
" After command completion occurred, registers were:\n"
2474 " ER -- ST COUNT LBA_48 LH LM LL DV DC\n"
2475 " -- -- -- == -- == == == -- -- -- -- --\n"
2476 " %02x -- %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x",
2491 json::ref jrefir = jrefi[
"completion_registers"];
2508 if (!st_er_desc.empty()) {
2509 jout(
" %s", st_er_desc.c_str());
2510 jrefi[
"error_description"] = st_er_desc;
2515 jout(
" Commands leading to the command that caused the error were:\n"
2516 " CR FEATR COUNT LBA_48 LH LM LL DV DC Powered_Up_Time Command/Feature_Name\n"
2517 " -- == -- == -- == == == -- -- -- -- -- --------------- --------------------\n");
2518 for (
int ci = 4, cji = 0; ci >= 0; ci--) {
2527 jout(
" %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %16s %s\n",
2528 cmd.command_register,
2529 cmd.features_register_hi,
2530 cmd.features_register,
2531 cmd.count_register_hi,
2533 cmd.lba_high_register_hi,
2534 cmd.lba_mid_register_hi,
2535 cmd.lba_low_register_hi,
2536 cmd.lba_high_register,
2537 cmd.lba_mid_register,
2538 cmd.lba_low_register,
2539 cmd.device_register,
2540 cmd.device_control_register,
2544 json::ref jrefic = jrefi[
"previous_commands"][cji++];
2545 json::ref jreficr = jrefic[
"registers"];
2546 jreficr[
"command"] =
cmd.command_register;
2547 jreficr[
"features"] = (
cmd.features_register_hi << 8) |
cmd.features_register;
2548 jreficr[
"count"] = (
cmd.count_register_hi << 8) |
cmd.count_register;
2549 jreficr[
"lba"] = ((uint64_t)
cmd.lba_high_register_hi << 40)
2550 | ((uint64_t)
cmd.lba_mid_register_hi << 32)
2551 | ((uint64_t)
cmd.lba_low_register_hi << 24)
2552 | ((unsigned)
cmd.lba_high_register << 16)
2553 | ((unsigned)
cmd.lba_mid_register << 8)
2554 | ((unsigned)
cmd.lba_low_register );
2555 jreficr[
"device"] =
cmd.device_register;
2556 jreficr[
"device_control"] =
cmd.device_control_register;
2557 jrefic[
"powerup_milliseconds"] =
cmd.timestamp;
2558 jrefic[
"command_name"] = atacmd;
2576 unsigned testnum,
unsigned char test_type,
2577 unsigned char test_status,
2578 unsigned short timestamp,
2579 uint64_t failing_lba,
2580 bool print_error_only,
bool & print_header)
2584 switch (test_status >> 4) {
2586 if ((test_type & 0x7f) == 0x02)
2596 if (retval >= 0 && print_error_only)
2599 std::string msgtest;
2600 switch (test_type) {
2601 case 0x00: msgtest =
"Offline";
break;
2602 case 0x01: msgtest =
"Short offline";
break;
2603 case 0x02: msgtest =
"Extended offline";
break;
2604 case 0x03: msgtest =
"Conveyance offline";
break;
2605 case 0x04: msgtest =
"Selective offline";
break;
2606 case 0x7f: msgtest =
"Abort offline test";
break;
2607 case 0x81: msgtest =
"Short captive";
break;
2608 case 0x82: msgtest =
"Extended captive";
break;
2609 case 0x83: msgtest =
"Conveyance captive";
break;
2610 case 0x84: msgtest =
"Selective captive";
break;
2612 if ((0x40 <= test_type && test_type <= 0x7e) || 0x90 <= test_type)
2613 msgtest =
strprintf(
"Vendor (0x%02x)", test_type);
2615 msgtest =
strprintf(
"Reserved (0x%02x)", test_type);
2618 std::string msgstat;
2619 switch (test_status >> 4) {
2620 case 0x0: msgstat =
"Completed without error";
break;
2621 case 0x1: msgstat =
"Aborted by host";
break;
2622 case 0x2: msgstat =
"Interrupted (host reset)";
break;
2623 case 0x3: msgstat =
"Fatal or unknown error";
break;
2624 case 0x4: msgstat =
"Completed: unknown failure";
break;
2625 case 0x5: msgstat =
"Completed: electrical failure";
break;
2626 case 0x6: msgstat =
"Completed: servo/seek failure";
break;
2627 case 0x7: msgstat =
"Completed: read failure";
break;
2628 case 0x8: msgstat =
"Completed: handling damage??";
break;
2629 case 0xf: msgstat =
"Self-test routine in progress";
break;
2630 default: msgstat =
strprintf(
"Unknown status (0x%x)", test_status >> 4);
2635 print_header =
false;
2636 jout(
"Num Test_Description Status Remaining LifeTime(hours) LBA_of_first_error\n");
2640 if (retval < 0 && failing_lba < 0xffffffffffffULL)
2641 snprintf(msglba,
sizeof(msglba),
"%" PRIu64, failing_lba);
2643 msglba[0] =
'-'; msglba[1] = 0;
2646 jout(
"#%2u %-19s %-29s %1d0%% %8u %s\n", testnum,
2647 msgtest.c_str(), msgstat.c_str(), test_status & 0x0f, timestamp, msglba);
2649 jref[
"type"][
"value"] = test_type;
2650 jref[
"type"][
"string"] = msgtest;
2652 jref[
"status"][
"value"] = test_status;
2653 jref[
"status"][
"string"] = msgstat;
2654 if (test_status & 0x0f)
2655 jref[
"status"][
"remaining_percent"] = (test_status & 0x0f) * 10;
2656 switch (test_status >> 4) {
2657 case 0x1:
case 0x2:
case 0x3:
break;
2658 default: jref[
"status"][
"passed"] = (retval >= 0);
2661 jref[
"lifetime_hours"] = timestamp;
2663 if (retval < 0 && failing_lba < 0xffffffffffffULL)
2664 jref[
"lba"] = failing_lba;
2673 json::ref jref =
jglb[
"ata_smart_self_test_log"][
"standard"];
2676 jout(
"SMART Self-test log structure revision number %d\n", log->
revnumber);
2679 pout(
"Warning: ATA Specification requires self-test log structure revision number = 1\n");
2682 jout(
"No self-tests have been logged. [To run self-tests, use: smartctl -t]\n");
2687 bool noheaderprinted =
true;
2688 int errcnt = 0, igncnt = 0;
2689 int testnum = 1, ext_ok_testnum = -1;
2692 for (
int i = 20, ji = 0; i >= 0; i--) {
2701 uint64_t lba48 = (
entry.lbafirstfailure < 0xffffffff ?
2702 entry.lbafirstfailure : 0xffffffffffffULL);
2706 testnum,
entry.selftestnumber,
entry.selfteststatus,
2707 entry.timestamp, lba48, !allentries, noheaderprinted);
2711 if (ext_ok_testnum < 0)
2717 else if (state > 0 && ext_ok_testnum < 0) {
2719 ext_ok_testnum = testnum;
2725 jout(
"%d of %d failed self-tests are outdated by newer successful extended offline self-test #%2d\n",
2726 igncnt, igncnt+errcnt, ext_ok_testnum);
2727 jref[
"count"] = testnum - 1;
2728 jref[
"error_count_total"] = igncnt + errcnt;
2729 jref[
"error_count_outdated"] = igncnt;
2731 if (!allentries && !noheaderprinted)
2739 unsigned nsectors,
unsigned max_entries)
2741 json::ref jref =
jglb[
"ata_smart_self_test_log"][
"extended"];
2743 jout(
"SMART Extended Self-test Log Version: %u (%u sectors)\n",
2745 jref[
"revision"] = log->
version;
2746 jref[
"sectors"] = nsectors;
2749 jout(
"No self-tests have been logged. [To run self-tests, use: smartctl -t]\n\n");
2755 unsigned nentries = nsectors * 19;
2757 if (logidx > nentries) {
2758 pout(
"Invalid Self-test Log index = 0x%04x (reserved = 0x%02x)\n", logidx, log->
reserved1);
2766 bool print_header =
true;
2767 int errcnt = 0, igncnt = 0;
2768 int ext_ok_testnum = -1;
2769 unsigned testnum = 1;
2772 for (
unsigned i = 0, ji = 0; i < nentries && testnum <= max_entries;
2773 i++, logidx = (logidx > 0 ? logidx - 1 : nentries - 1)) {
2782 const unsigned char *
b =
entry.failing_lba;
2783 uint64_t lba48 =
b[0]
2786 | ((uint64_t)
b[3] << 24)
2787 | ((uint64_t)
b[4] << 32)
2788 | ((uint64_t)
b[5] << 40);
2792 testnum,
entry.self_test_type,
2793 entry.self_test_status,
entry.timestamp, lba48,
2794 false , print_header);
2798 if (ext_ok_testnum < 0)
2804 else if (state > 0 && ext_ok_testnum < 0) {
2806 ext_ok_testnum = testnum;
2812 jout(
"%d of %d failed self-tests are outdated by newer successful extended offline self-test #%2d\n",
2813 igncnt, igncnt+errcnt, ext_ok_testnum);
2814 jref[
"count"] = testnum - 1;
2815 jref[
"error_count_total"] = igncnt + errcnt;
2816 jref[
"error_count_outdated"] = igncnt;
2827 jout(
"SMART Selective self-test log data structure revision number %d\n", log->
logversion);
2830 pout(
"Note: revision number not 1 implies that no selective self-test has ever been run\n");
2834 case 0:msg=
"Completed";
2836 case 1:msg=
"Aborted_by_host";
2838 case 2:msg=
"Interrupted";
2840 case 3:msg=
"Fatal_error";
2842 case 4:msg=
"Completed_unknown_failure";
2844 case 5:msg=
"Completed_electrical_failure";
2846 case 6:msg=
"Completed_servo/seek_failure";
2848 case 7:msg=
"Completed_read_failure";
2850 case 8:msg=
"Completed_handling_damage??";
2852 case 15:msg=
"Self_test_in_progress";
2854 default:msg=
"Unknown_status ";
2860 uint64_t maxl = 0, maxr = 0;
2862 uint64_t currentend = current + 0xffff;
2867 for (
int i = 0; i < 5; i++) {
2869 uint64_t end =log->
span[i].
end;
2881 if ((field1=snprintf(tmp,64,
"%" PRIu64, maxl))<7)
2883 if ((field2=snprintf(tmp,64,
"%" PRIu64, maxr))<7)
2887 jout(
" SPAN %*s %*s CURRENT_TEST_STATUS\n", field1,
"MIN_LBA", field2,
"MAX_LBA");
2889 for (
int i = 0; i < 5; i++) {
2891 uint64_t end=log->
span[i].
end;
2896 jout(
" %d %*" PRIu64
" %*" PRIu64
" %s [%01d0%% left] (%" PRIu64
"-%" PRIu64
")\n",
2897 i + 1, field1, start, field2, end, msg,
2901 jout(
" %d %*" PRIu64
" %*" PRIu64
" Not_testing\n",
2902 i + 1, field1, start, field2, end);
2905 jrefi[
"lba_min"] = start;
2906 jrefi[
"lba_max"] = end;
2908 jrefi[
"status"][
"string"] = (active ? msg :
"Not_testing");
2911 jrefi[
"current_lba_min"] = current;
2912 jrefi[
"current_lba_max"] = currentend;
2920 jout(
"%5d %*" PRIu64
" %*" PRIu64
" Read_scanning %s\n",
2921 log->
currentspan, field1, current, field2, currentend, ost);
2922 json::ref jrefc = jref[
"current_read_scan"];
2923 jrefc[
"lba_min"] = current;
2924 jrefc[
"lba_max"] = currentend;
2926 jrefc[
"status"][
"string"] = ost;
2940 jout(
"Selective self-test flags (0x%x):\n", (
unsigned)log->
flags);
2942 jreff[
"value"] = log->
flags;
2946 jout(
" Currently read-scanning the remainder of the disk.\n");
2948 jout(
" Read-scan of remainder of disk interrupted; will resume %d min after power-up.\n",
2951 jout(
" After scanning selected spans, read-scan remainder of disk.\n");
2956 jout(
" After scanning selected spans, do NOT read-scan remainder of disk.\n");
2959 jout(
"If Selective self-test is pending on power-up, resume after %d minute delay.\n",
2961 jref[
"power_up_scan_resume_minutes"] = log->
pendingtime;
2965static const char *
sct_ptemp(
signed char x,
char (& buf)[20])
2969 snprintf(buf,
sizeof(buf),
"%2d", x);
2977 jglb[
"temperature"][name] = x;
2978 jref[
"temperature"][name] = x;
2992 memset(buf,
'*', x);
2998 buf[0] =
'-'; buf[1] = 0;
3006 case 0:
return "Active";
3007 case 1:
return "Stand-by";
3008 case 2:
return "Sleep";
3009 case 3:
return "DST executing in background";
3010 case 4:
return "SMART Off-line Data Collection executing in background";
3011 case 5:
return "SCT command executing in background";
3012 default:
return "Unknown";
3032 jref[
"device_state"][
"string"] = statestr;
3046 char buf1[20], buf2[20];
3047 jout(
"Current Temperature: %s Celsius\n",
3050 jout(
"Power Cycle Min/Max Temperature: %s/%s Celsius\n",
3056 jout(
"Lifetime Min/Max Temperature: %s/%s Celsius\n",
3066 jout(
"Specified Max Operating Temperature: %3d Celsius\n", sts->
max_op_limit);
3069 jout(
"Under/Over Temperature Limit Count: %2u/%u\n",
3078 (passed == 0 ?
"FAILED" : passed > 0 ?
"PASSED" :
"Reserved"));
3080 jref[
"smart_status"][
"passed"] = !!passed;
3081 jglb[
"smart_status"][
"passed"] = !!passed;
3084 jref[
"smart_status"][
"reserved_value"] = sts->
smart_status;
3088 pout(
"Minimum supported ERC Time Limit: %d (%0.1f seconds)\n",
3092 jout(
"Vendor specific:\n");
3106 char buf1[20], buf2[20], buf3[64];
3110 jout(
"Temperature Sampling Period: %u minute%s\n",
3113 jout(
"Temperature Logging Interval: %u minute%s\n",
3115 jref[
"logging_interval_minutes"] = tmh->
interval;
3117 jout(
"Min/Max recommended Temperature: %s/%s Celsius\n",
3121 jout(
"Min/Max Temperature Limit: %s/%s Celsius\n",
3131 pout(
"Temperature History is empty\n");
3133 pout(
"Invalid Temperature History Size or Index\n");
3138 jout(
"\nIndex Estimated Time Temperature Celsius\n");
3141 time_t t = time(0) - (time_t)(tmh->
cb_size-1) * interval * 60;
3142 t -= t % (interval * 60);
3143 while (n < tmh->cb_size) {
3145 unsigned n1 = n, n2 = n+1, i2 = (i+1) % tmh->
cb_size;
3146 while (n2 < tmh->cb_size && tmh->
cb[i2] == tmh->
cb[i]) {
3147 n2++; i2 = (i2+1) % tmh->
cb_size;
3151 if (n == n1 || n == n2-1 || n2 <= n1+3) {
3155 strftime(date,
sizeof(date),
"%Y-%m-%d %H:%M",
time_to_tm_local(&tmbuf, t));
3156 jout(
" %3u %s %s %s\n", i, date,
3159 else if (n == n1+1) {
3160 jout(
" ... ..(%3u skipped). .. %s\n",
3163 if (tmh->
cb[i] != -128)
3164 jref[
"table"][n] = tmh->
cb[i];
3165 t += interval * 60; i = (i+1) % tmh->
cb_size; n++;
3176 const char* power_on_str = (power_on ?
"Power-on " :
"");
3178 jout(
"SCT Error Recovery Control%s:%s\n", (set ?
" set to" :
""), (mfg_default ?
" default values." :
""));
3181 jref[
"read"][
"enabled"] = !!read_timer;
3183 jout(
" %sRead: Disabled\n", power_on_str);
3185 jout(
" %sRead: %6d (%0.1f seconds)\n", power_on_str, read_timer, read_timer/10.0);
3186 jref[
"read"][
"deciseconds"] = read_timer;
3189 jref[
"write"][
"enabled"] = !!write_timer;
3191 jout(
" %sWrite: Disabled\n", power_on_str);
3193 jout(
" %sWrite: %6d (%0.1f seconds)\n", power_on_str, write_timer, write_timer/10.0);
3194 jref[
"write"][
"deciseconds"] = write_timer;
3205 s =
"vendor specific";
3206 else if (level < 128)
3207 s =
"unknown/retired";
3208 else if (level == 128)
3210 else if (level < 254)
3212 else if (level == 254)
3213 s =
"maximum performance";
3217 if (recommended >= 0)
3218 jout(
"%s%d (%s), recommended: %d\n", msg, level,
s, recommended);
3220 jout(
"%s%d (%s)\n", msg, level,
s);
3223 jref[
"enabled"] =
true;
3224 jref[
"level"] = level;
3226 if (recommended >= 0)
3227 jref[
"recommended_level"] = recommended;
3234 if (!(1 <= level && level <= 254))
3236 else if (level == 1)
3237 s =
"minimum power consumption with standby";
3238 else if (level < 128)
3239 s =
"intermediate level with standby";
3240 else if (level == 128)
3241 s =
"minimum power consumption without standby";
3242 else if (level < 254)
3243 s =
"intermediate level without standby";
3245 s =
"maximum performance";
3247 jout(
"%s%d (%s)\n", msg, level,
s);
3250 jref[
"enabled"] =
true;
3251 jref[
"level"] = level;
3253 if (1 <= level && level <= 254) {
3254 jref[
"max_performance"] = (level == 254);
3255 jref[
"min_power"] = (level == 1 || level == 128);
3256 jref[
"with_standby"] = (level < 128);
3263 if (!(state & 0x0001)) {
3264 pout(
"%sUnavailable\n", msg);
3268 const char * s1, * s2 =
"", * s3 =
"", * s4 =
"";
3269 bool enabled =
false, locked =
false;
3270 if (!(state & 0x0002)) {
3272 if (!(state & 0x0008))
3273 s2 =
"NOT FROZEN [SEC1]";
3275 s2 =
"frozen [SEC2]";
3279 s1 =
"ENABLED, PW level ";
3280 if (!(state & 0x0100))
3285 if (!(state & 0x0004)) {
3286 s3 =
", not locked, ";
3287 if (!(state & 0x0008))
3288 s4 =
"not frozen [SEC5]";
3290 s4 =
"frozen [SEC6]";
3294 s3 =
", **LOCKED** [SEC4]";
3296 s4 =
", PW ATTEMPTS EXCEEDED";
3303 if (0x0000 < master_password_id && master_password_id < 0xfffe)
3304 snprintf(s5,
sizeof(s5),
", Master PW ID: 0x%04x", master_password_id);
3306 jout(
"%s%s%s%s%s%s\n", msg, s1, s2, s3, s4, s5);
3309 jref[
"state"] = state;
3310 jref[
"string"] =
strprintf(
"%s%s%s%s", s1, s2, s3, s4);
3311 jref[
"enabled"] = enabled;
3312 if (!enabled || !locked)
3313 jref[
"frozen"] = !!(state & 0x0008);
3315 jref[
"pw_level_max"] = !!(state & 0x0100);
3316 jref[
"locked"] = locked;
3318 jref[
"pw_attempts_exceeded"] = !!(state & 0x0010);
3320 jref[
"master_password_id"] = master_password_id;
3325 const char * s1 = 0;
3326 int hours = 0, minutes = 0 , seconds = 0;
3331 else if (timer <= 240)
3332 seconds = timer * 5, minutes = seconds / 60, seconds %= 60;
3333 else if (timer <= 251)
3334 minutes = (timer - 240) * 30, hours = minutes / 60, minutes %= 60;
3335 else if (timer == 252)
3337 else if (timer == 253)
3338 s1 =
"between 8 hours and 12 hours";
3339 else if (timer == 255)
3340 minutes = 21, seconds = 15;
3344 const char * s2 =
"", * s3 =
"";
3346 s2 =
" or vendor-specific";
3347 if (timer > 0 && (drive.
words047_079[50-47] & 0xc001) == 0x4001)
3348 s3 =
", a vendor-specific minimum applies";
3351 pout(
"%s%d (%s%s%s)\n", msg, timer, s1, s2, s3);
3353 pout(
"%s%d (%02d:%02d:%02d%s%s)\n", msg, timer, hours, minutes, seconds, s2, s3);
3360 const char * powername = 0;
3361 bool powerchg =
false;
3363 unsigned char powerlimit = 0xff;
3366 switch (powermode) {
3373 jinf(
"CHECK POWER MODE not implemented, ignoring -n option\n");
break;
3375 powername =
"SLEEP"; powerlimit = 2;
3380 powername =
"STANDBY"; powerlimit = 3;
break;
3382 powername =
"STANDBY_Y"; powerlimit = 3;
break;
3384 powername =
"IDLE"; powerlimit = 4;
break;
3386 powername =
"IDLE_A"; powerlimit = 4;
break;
3388 powername =
"IDLE_B"; powerlimit = 4;
break;
3390 powername =
"IDLE_C"; powerlimit = 4;
break;
3393 powername =
"ACTIVE_NV_DOWN";
break;
3395 powername =
"ACTIVE_NV_UP" ;
break;
3397 powername =
"ACTIVE or IDLE";
break;
3401 jinf(
"CHECK POWER MODE returned unknown value 0x%02x, exit(%d)\n", powermode,
3405 jinf(
"CHECK POWER MODE returned unknown value 0x%02x, ignoring -n option\n", powermode);
3410 jinf(
"Device is in %s mode, exit(%d)\n", powername, options.
powerexit);
3413 powerchg = (powermode != 0xff);
3418 bool need_smart_val = (
3433 bool need_smart_enabled = (
3440 bool need_smart_support = (
3447 bool need_smart_logdir = (
3454 bool need_gp_logdir = (
3468 need_gp_logdir =
true;
3470 need_smart_logdir =
true;
3474 bool need_sct_support = (
3488 bool not_part_of_a_option = (
3501 || need_smart_support
3502 || not_part_of_a_option)) {
3504 pout(
"Device is in %s mode\n", powername);
3506 pout(
"ATA device successfully opened\n\n"
3507 "Use 'smartctl -a' (or '-x') to print SMART (and more) information\n\n");
3514 unsigned char raw_drive[
sizeof(drive)]; memset(&raw_drive, 0,
sizeof(raw_drive));
3519 pout(
"Read Device Identity failed: %s\n\n",
3521 pout(
"If this is a USB connected device, look at the various "
3522 "--device=TYPE variants\n");
3525 else if (!
nonempty(&drive,
sizeof(drive))) {
3526 pout(
"Read Device Identity failed: empty IDENTIFY data\n\n");
3539 std::string dbversion;
3543 firmwarebugs, dbversion);
3544 if (!dbversion.empty())
3545 jglb[
"smartctl"][
"drive_database_version"][
"string"] = dbversion;
3555 pout(
"=== ATA IDENTIFY DATA ===\n");
3562 pout(
"=== START OF INFORMATION SECTION ===\n");
3567 int smart_supported = -1, smart_enabled = -1;
3568 if (need_smart_support || options.
drive_info) {
3572 pout(
"SMART support is: Unavailable - Packet Interface Devices [this device: %s] don't support ATA SMART\n",
3580 if (smart_supported < 0)
3581 pout(
"SMART support is: Ambiguous - ATA IDENTIFY DEVICE words 82-83 don't show if SMART supported.\n");
3582 if (smart_supported && smart_enabled < 0) {
3583 pout(
"SMART support is: Ambiguous - ATA IDENTIFY DEVICE words 85-87 don't show if SMART is enabled.\n");
3584 if (need_smart_support) {
3587 pout(
" Checking to be sure by trying SMART RETURN STATUS command.\n");
3589 smart_supported = smart_enabled = 1;
3592 else if (smart_supported < 0 && (smart_enabled > 0 || dbentry))
3594 smart_supported = 1;
3596 if (smart_supported < 0)
3597 pout(
"SMART support is: Unknown - Try option -s with argument 'on' to enable it.");
3598 else if (!smart_supported)
3599 jout(
"SMART support is: Unavailable - device lacks SMART capability.\n");
3602 jout(
"SMART support is: Available - device has SMART capability.\n");
3603 if (smart_enabled >= 0) {
3606 pout(
" %sabled status cached by OS, trying SMART RETURN STATUS cmd.\n",
3607 (smart_enabled?
"En":
"Dis"));
3611 jout(
"SMART support is: %s\n",
3612 (smart_enabled ?
"Enabled" :
"Disabled"));
3617 if (options.
drive_info || smart_supported <= 0) {
3618 jglb[
"smart_support"][
"available"] = (smart_supported > 0);
3619 if (smart_supported > 0)
3620 jglb[
"smart_support"][
"enabled"] = (smart_enabled > 0);
3627 pout(
"AAM feature is: Unavailable\n");
3628 else if (!(drive.
word086 & 0x0200)) {
3629 jout(
"AAM feature is: Disabled\n");
3630 jglb[
"ata_aam"][
"enabled"] =
false;
3640 pout(
"APM feature is: Unavailable\n");
3641 else if (!(drive.
word086 & 0x0008)) {
3642 jout(
"APM feature is: Disabled\n");
3643 jglb[
"ata_apm"][
"enabled"] =
false;
3653 pout(
"Rd look-ahead is: Unavailable\n");
3656 jout(
"Rd look-ahead is: %sabled\n", (enabled ?
"En" :
"Dis"));
3657 jglb[
"read_lookahead"][
"enabled"] = enabled;
3665 pout(
"Write cache is: Unavailable\n");
3668 jout(
"Write cache is: %sabled\n", (enabled ?
"En" :
"Dis"));
3669 jglb[
"write_cache"][
"enabled"] = enabled;
3678 || ((word119 & 0xc200) != 0x4200)
3679 || ((word120 & 0xc000) != 0x4000))
3680 pout(
"DSN feature is: Unavailable\n");
3682 bool enabled = !!(word120 & 0x200);
3683 jout(
"DSN feature is: %sabled\n", (enabled ?
"En" :
"Dis"));
3684 jglb[
"ata_dsn"][
"enabled"] = enabled;
3690 bool locked = ((word128 & 0x0007) == 0x0007);
3699 pout(
"Wt Cache Reorder: Unavailable\n");
3701 pout(
"Wt Cache Reorder: Unknown (SCT not supported if ATA Security is LOCKED)\n");
3704 false ,
false ,
false );
3706 if (-1 <= wcache_reorder && wcache_reorder <= 2)
3707 pout(
"Wt Cache Reorder: %s\n",
3708 (wcache_reorder == -1 ?
"Unknown (SCT Feature Control command failed)" :
3709 wcache_reorder == 0 ?
"Unknown" :
3710 wcache_reorder == 1 ?
"Enabled" :
"Disabled"));
3712 pout(
"Wt Cache Reorder: Unknown (0x%02x)\n", wcache_reorder);
3716 const char * sct_write_cache_state_desc[4] = {
3718 "Controlled by ATA",
3726 pout(
"SCT Write Cache Control: Unavailable\n");
3728 pout(
"SCT Write Cache Control: Unknown (SCT not supported if ATA Security is LOCKED)\n");
3731 if (-1 <= state && state <= 3)
3732 pout(
"SCT Write Cache Control: %s\n",
3733 (state == -1 ?
"Unknown (SCT Feature Control command failed)" :
3734 sct_write_cache_state_desc[state]));
3736 pout(
"SCT Write Cache Control: Unknown (0x%02x)\n", state);
3745 pout(
"Power mode %s %s\n", (powerchg?
"was:":
"is: "), powername);
3750 if (smart_supported <= 0 && need_smart_support)
3760 pout(
"=== START OF ENABLE/DISABLE COMMANDS SECTION ===\n");
3778 pout(
"AAM disabled\n");
3798 pout(
"APM disabled\n");
3806 pout(
"Read look-ahead %sable failed: %s\n", (enable ?
"en" :
"dis"), device->
get_errmsg());
3810 pout(
"Read look-ahead %sabled\n", (enable ?
"en" :
"dis"));
3817 pout(
"Write cache %sable failed: %s\n", (enable ?
"en" :
"dis"), device->
get_errmsg());
3821 pout(
"Write cache %sabled\n", (enable ?
"en" :
"dis"));
3826 bool enable = (options.
set_dsn > 0);
3828 pout(
"DSN %sable failed: %s\n", (enable ?
"en" :
"dis"), device->
get_errmsg());
3832 pout(
"DSN %sabled\n", (enable ?
"en" :
"dis"));
3839 pout(
"Write cache reordering %sable failed: SCT Feature Control command not supported\n",
3840 (enable ?
"en" :
"dis"));
3842 pout(
"Write cache reordering %sable failed: SCT not supported if ATA Security is LOCKED\n",
3843 (enable ?
"en" :
"dis"));
3846 pout(
"Write cache reordering %sable failed: %s\n", (enable ?
"en" :
"dis"), device->
get_errmsg());
3850 pout(
"Write cache reordering %sabled (%s)\n", (enable ?
"en" :
"dis"),
3857 pout(
"SCT Feature Control of write cache failed: SCT Feature Control command not supported\n");
3859 pout(
"SCT Feature Control of write cache failed: SCT not supported if ATA Security is LOCKED\n");
3862 pout(
"SCT Feature Control of write cache failed: %s\n", device->
get_errmsg());
3866 pout(
"Write cache SCT Feature Control is set to: %s (%s)\n",
3874 pout(
"ATA SECURITY FREEZE LOCK failed: %s\n", device->
get_errmsg());
3878 pout(
"ATA Security set to frozen mode\n");
3898 pout(
"SMART Enabled.\n");
3913 pout(
"SMART Disabled. Use option -s with argument 'on' to enable it.\n");
3915 pout(
"(override with '-T permissive' option)\n");
3922 pout(
"SMART Enable Attribute Autosave failed: %s\n\n", device->
get_errmsg());
3926 pout(
"SMART Attribute Autosave Enabled.\n");
3931 pout(
"SMART Disable Attribute Autosave failed: %s\n\n", device->
get_errmsg());
3935 pout(
"SMART Attribute Autosave Disabled.\n");
3941 bool smart_val_ok =
false, smart_thres_ok =
false;
3943 if (need_smart_val) {
3949 smart_val_ok =
true;
3953 pout(
"Read SMART Thresholds failed: %s\n\n", device->
get_errmsg());
3957 smart_thres_ok =
true;
3963 bool needupdate =
false;
3966 pout(
"SMART Automatic Timers not supported\n\n");
3969 needupdate = smart_val_ok;
3971 pout(
"SMART Enable Automatic Offline failed: %s\n\n", device->
get_errmsg());
3975 pout(
"SMART Automatic Offline Testing Enabled every four hours.\n");
3980 pout(
"SMART Automatic Timers not supported\n\n");
3983 needupdate = smart_val_ok;
3985 pout(
"SMART Disable Automatic Offline failed: %s\n\n", device->
get_errmsg());
3989 pout(
"SMART Automatic Offline Testing Disabled.\n");
3995 smart_val_ok =
false;
4013 pout(
"=== START OF READ SMART DATA SECTION ===\n");
4022 jout(
"SMART overall-health self-assessment test result: PASSED\n");
4023 jglb[
"smart_status"][
"passed"] =
true;
4024 if (smart_thres_ok &&
find_failed_attr(&smartval, &smartthres, attribute_defs, 0)) {
4026 pout(
"See vendor-specific Attribute list for marginal Attributes.\n\n");
4029 pout(
"Please note the following marginal Attributes:\n");
4041 jout(
"SMART overall-health self-assessment test result: FAILED!\n"
4042 "Drive failure expected in less than 24 hours. SAVE ALL DATA.\n");
4043 jglb[
"smart_status"][
"passed"] =
false;
4045 if (smart_thres_ok &&
find_failed_attr(&smartval, &smartthres, attribute_defs, 1)) {
4048 pout(
"See vendor-specific Attribute list for failed Attributes.\n\n");
4051 pout(
"Failed Attributes:\n");
4056 pout(
"No failed Attributes found.\n\n");
4067 pout(
"SMART Status %s: %s\n",
4074 if (!(smart_val_ok && smart_thres_ok)) {
4076 pout(
"SMART overall-health self-assessment test result: UNKNOWN!\n"
4077 "SMART Status, Attributes and Thresholds cannot be read.\n\n");
4081 jout(
"SMART overall-health self-assessment test result: FAILED!\n"
4082 "Drive failure expected in less than 24 hours. SAVE ALL DATA.\n");
4083 jwrn(
"Warning: This result is based on an Attribute check.\n");
4084 jglb[
"smart_status"][
"passed"] =
false;
4089 pout(
"See vendor-specific Attribute list for failed Attributes.\n\n");
4092 pout(
"Failed Attributes:\n");
4097 jout(
"SMART overall-health self-assessment test result: PASSED\n");
4098 jwrn(
"Warning: This result is based on an Attribute check.\n");
4099 jglb[
"smart_status"][
"passed"] =
true;
4102 pout(
"See vendor-specific Attribute list for marginal Attributes.\n\n");
4105 pout(
"Please note the following marginal Attributes:\n");
4135 if ( gp_log_supported
4138 need_smart_logdir =
true;
4144 if (need_smart_logdir) {
4146 smartlogdir =
fake_logdir(&smartlogdir_buf, options);
4148 pout(
"Read SMART Log Directory failed: %s\n\n", device->
get_errmsg());
4152 smartlogdir = &smartlogdir_buf;
4156 if (need_gp_logdir) {
4161 pout(
"General Purpose Log Directory not supported\n\n");
4164 pout(
"Read GP Log Directory failed\n\n");
4168 gplogdir = &gplogdir_buf;
4174 pout(
"Log Directories not read due to '-F nologdir' option\n\n");
4184 unsigned max_nsectors;
4186 type =
"General Purpose";
4194 if (!max_nsectors) {
4196 pout(
"%s Log 0x%02x does not exist (override with '-T permissive' option)\n", type, req.
logaddr);
4199 max_nsectors = req.
page+1;
4201 if (max_nsectors <= req.
page) {
4202 pout(
"%s Log 0x%02x has only %u sectors, output skipped\n", type, req.
logaddr, max_nsectors);
4207 if (ns > max_nsectors - req.
page) {
4209 pout(
"%s Log 0x%02x has only %u sectors, output truncated\n", type, req.
logaddr, max_nsectors);
4210 ns = max_nsectors - req.
page;
4214 unsigned offs = (req.
gpl ? 0 : req.
page);
4234 pout(
"SMART Extended Comprehensive Error Log (GP Log 0x03) not supported\n\n");
4240 pout(
"Read SMART Extended Comprehensive Error Log failed\n\n");
4252 do_smart_error_log =
true;
4253 else if (!do_smart_error_log)
4254 pout(
"Try '-l [xerror,]error' to read traditional SMART Error Log\n");
4259 if (do_smart_error_log) {
4261 || ( !(smartlogdir && gp_log_supported)
4264 pout(
"SMART Error Log not supported\n\n");
4269 pout(
"Read SMART Error Log failed: %s\n\n", device->
get_errmsg());
4287 pout(
"SMART Extended Self-test Log (GP Log 0x07) not supported\n\n");
4288 else if (nsectors >= 256)
4289 pout(
"SMART Extended Self-test Log size %u not supported\n\n", nsectors);
4294 pout(
"Read SMART Extended Self-test Log failed\n\n");
4306 do_smart_selftest_log =
true;
4307 else if (!do_smart_selftest_log)
4308 pout(
"Try '-l [xselftest,]selftest' to read traditional SMART Self Test Log\n");
4313 if (do_smart_selftest_log) {
4315 || ( !(smartlogdir && gp_log_supported)
4318 pout(
"SMART Self-test Log not supported\n\n");
4323 pout(
"Read SMART Self-test Log failed: %s\n\n", device->
get_errmsg());
4341 pout(
"Selective Self-tests/Logging not supported\n\n");
4343 pout(
"Read SMART Selective Self-test Log failed: %s\n\n", device->
get_errmsg());
4363 pout(
"SCT Commands not supported\n\n");
4365 pout(
"SCT Commands not supported if ATA Security is LOCKED\n\n");
4390 pout(
"SCT Data Table command not supported\n\n");
4400 pout(
"Read SCT Temperature History failed\n\n");
4411 pout(
"SCT Feature Control command not supported\n\n");
4416 pout(
"Write Temperature Logging Interval failed\n\n");
4420 pout(
"Temperature Logging Interval set to %u minute%s (%s)\n",
4431 pout(
"SCT Error Recovery Control command not supported\n\n");
4442 pout(
"SCT (Set) Error Recovery Control command failed\n");
4445 pout(
"Retry with: 'scterc,70,70' to enable ERC or 'scterc,0,0' to disable\n");
4449 else if (!sct_erc_get)
4456 bool get_power_on = (sct_erc_get == 2);
4457 unsigned short read_timer, write_timer;
4460 pout(
"SCT (Get) Error Recovery Control command failed\n");
4462 pout(
"The previous SCT (Set) Error Recovery Control command succeeded\n");
4477 bool use_gplog =
true;
4478 unsigned nsectors = 0;
4481 else if (smartlogdir){
4486 pout(
"Device Statistics (GP/SMART Log 0x04) not supported\n\n");
4496 pout(
"Pending Defects log (GP Log 0x0c) not supported\n\n");
4505 if (!nsectors && (drive.
words047_079[76-47] & 0x0401) == 0x0400)
4508 pout(
"SATA Phy Event Counters (GP Log 0x11) not supported\n\n");
4509 else if (nsectors != 1)
4510 pout(
"SATA Phy Event Counters with %u sectors not supported\n\n", nsectors);
4512 unsigned char log_11[512] = {0, };
4513 unsigned char features = (options.
sataphy_reset ? 0x01 : 0x00);
4515 pout(
"Read SATA Phy Event Counters failed\n\n");
4525 bool farm_supported =
true;
4532 jout(
"FARM log (GP Log 0xa6) not supported\n\n");
4534 farm_supported =
false;
4538 jout(
"Seagate FARM log (GP Log 0xa6) supported [try: -l farm]\n\n");
4543 pout(
"Read FARM log (GP Log 0xa6) failed\n\n");
4544 farm_supported =
false;
4553 jout(
"FARM log (GP Log 0xa6) not supported for non-Seagate drives\n\n");
4555 farm_supported =
false;
4557 jglb[
"seagate_farm_log"][
"supported"] = farm_supported;
4561 if (options.
a_option && !not_part_of_a_option)
4562 pout(
"The above only provides legacy SMART information - try 'smartctl -x' for more\n\n");
4574 pout(
"Device placed in STANDBY mode\n");
4579 pout(
"ATA STANDBY IMMEDIATE command failed: %s\n", device->
get_errmsg());
4583 pout(
"Device placed in STANDBY mode\n");
4591 pout(
"=== START OF OFFLINE IMMEDIATE AND SELF-TEST SECTION ===\n");
4596 pout(
"Execute Offline Immediate function not supported\n\n");
4606 pout(
"Self-test functions not supported\n\n");
4613 pout(
"Conveyance Self-test functions not supported\n\n");
4620 pout(
"Selective Self-test functions not supported\n\n");
4641 pout(
"Note: giving further SMART commands will abort Offline testing\n");
4651 time_t t=time(NULL);
4654 pout(
"Please wait %d seconds for test to complete.\n", (
int)timewait);
4657 pout(
"Please wait %d minutes for test to complete.\n", (
int)timewait);
4661 pout(
"Test will complete after %s\n", comptime);
4667 pout(
"Use smartctl -X to abort test.\n");
const char * look_up_ata_command(unsigned char c_code, unsigned char f_reg)
bool ata_nodata_command(ata_device *device, unsigned char command, int sector_count)
int ataDisableAutoOffline(ata_device *device)
unsigned char ata_return_temperature_value(const ata_smart_values *data, const ata_vendor_attr_defs &defs)
bool isSmartErrorLogCapable(const ata_smart_values *data, const ata_identify_device *identity)
int ataGetSCTErrorRecoveryControltime(ata_device *device, unsigned type, unsigned short &time_limit, bool power_on)
bool ataReadSmartLog(ata_device *device, unsigned char logaddr, void *data, unsigned nsectors)
int ata_get_wwn(const ata_identify_device *id, unsigned &oui, uint64_t &unique_id)
int ataSmartTest(ata_device *device, int testtype, bool force, const ata_selective_selftest_args &selargs, const ata_smart_values *sv, uint64_t num_sectors)
int ataEnableAutoOffline(ata_device *device)
int ataSmartStatus2(ata_device *device)
int ataSmartSupport(const ata_identify_device *drive)
int ataDisableAutoSave(ata_device *device)
int ata_get_rotation_rate(const ata_identify_device *id)
bool ataReadLogExt(ata_device *device, unsigned char logaddr, unsigned char features, unsigned page, void *data, unsigned nsectors)
int ataEnableAutoSave(ata_device *device)
int ataReadSelfTestLog(ata_device *device, ata_smart_selftestlog *data, firmwarebug_defs firmwarebugs)
std::string ata_format_attr_raw_value(const ata_smart_attribute &attr, const ata_vendor_attr_defs &defs)
int ataReadSCTTempHist(ata_device *device, ata_sct_temperature_history_table *tmh, ata_sct_status_response *sts)
int ataReadErrorLog(ata_device *device, ata_smart_errorlog *data, firmwarebug_defs firmwarebugs)
void ata_get_size_info(const ata_identify_device *id, ata_size_info &sizes)
int ata_read_identity(ata_device *device, ata_identify_device *buf, bool fix_swapped_id, unsigned char *raw_buf)
int TestTime(const ata_smart_values *data, int testtype)
int ataEnableSmart(ata_device *device)
bool isGeneralPurposeLoggingCapable(const ata_identify_device *identity)
int ataCheckPowerMode(ata_device *device)
int ataGetSetSCTWriteCacheReordering(ata_device *device, bool enable, bool persistent, bool set)
unsigned char checksum(const void *data)
bool ataReadExtSelfTestLog(ata_device *device, ata_smart_extselftestlog *log, unsigned nsectors)
int ataReadSelectiveSelfTestLog(ata_device *device, struct ata_selective_self_test_log *data)
bool isSmartTestLogCapable(const ata_smart_values *data, const ata_identify_device *identity)
int ataReadSmartValues(ata_device *device, struct ata_smart_values *data)
int ataSetSCTErrorRecoveryControltime(ata_device *device, unsigned type, unsigned short time_limit, bool power_on, bool mfg_default)
int ataDoesSmartWork(ata_device *device)
uint64_t ata_get_attr_raw_value(const ata_smart_attribute &attr, const ata_vendor_attr_defs &defs)
bool dont_print_serial_number
int ataReadSCTStatus(ata_device *device, ata_sct_status_response *sts)
bool ataReadExtErrorLog(ata_device *device, ata_smart_exterrlog *log, unsigned page, unsigned nsectors, firmwarebug_defs firmwarebugs)
int ataDisableSmart(ata_device *device)
int ataSetSCTTempInterval(ata_device *device, unsigned interval, bool persistent)
std::string ata_get_smart_attr_name(unsigned char id, const ata_vendor_attr_defs &defs, int rpm)
int ataGetSetSCTWriteCache(ata_device *device, unsigned short state, bool persistent, bool set)
int ataReadSmartThresholds(ata_device *device, struct ata_smart_thresholds_pvt *data)
int ataIsSmartEnabled(const ata_identify_device *drive)
void ata_format_id_string(char *out, const unsigned char *in, int n)
int ataReadLogDirectory(ata_device *device, ata_smart_log_directory *data, bool gpl)
bool ata_set_features(ata_device *device, unsigned char features, int sector_count)
ata_attr_state ata_get_attr_state(const ata_smart_attribute &attr, int attridx, const ata_smart_threshold_entry *thresholds, const ata_vendor_attr_defs &defs, unsigned char *threshval)
#define ATA_ENABLE_READ_LOOK_AHEAD
#define ATTRIBUTE_FLAGS_OTHER(x)
#define SELECTIVE_FLAG_PENDING
#define ATA_DISABLE_WRITE_CACHE
#define ATTRIBUTE_FLAGS_SELFPRESERVING(x)
bool isSupportSelfTest(const ata_smart_values *data)
#define SELECTIVE_SELF_TEST
bool isSCTErrorRecoveryControlCapable(const ata_identify_device *drive)
#define ATA_STANDBY_IMMEDIATE
bool isSupportOfflineSurfaceScan(const ata_smart_values *data)
#define OFFLINE_FULL_SCAN
#define SELECTIVE_FLAG_DOSCAN
bool isSupportConveyanceSelfTest(const ata_smart_values *data)
#define ATA_ENABLE_DISABLE_DSN
void checksumwarning(const char *string)
#define ATTRIBUTE_FLAGS_EVENTCOUNT(x)
#define ATTRIBUTE_FLAGS_PERFORMANCE(x)
bool isSupportAutomaticTimer(const ata_smart_values *data)
#define ATA_ENABLE_WRITE_CACHE
bool isSupportSelectiveSelfTest(const ata_smart_values *data)
bool isSCTDataTableCapable(const ata_identify_device *drive)
#define ATA_DISABLE_READ_LOOK_AHEAD
#define ATTRIBUTE_FLAGS_PREFAILURE(x)
bool isSupportExecuteOfflineImmediate(const ata_smart_values *data)
bool isSupportOfflineAbort(const ata_smart_values *data)
#define SELECTIVE_FLAG_ACTIVE
#define ATTRIBUTE_FLAGS_ERRORRATE(x)
#define EXTEND_CAPTIVE_SELF_TEST
#define CONVEYANCE_CAPTIVE_SELF_TEST
#define CONVEYANCE_SELF_TEST
#define ATA_SECURITY_FREEZE_LOCK
#define SHORT_CAPTIVE_SELF_TEST
#define NUMBER_ATA_SMART_ATTRIBUTES
#define SELECTIVE_CAPTIVE_SELF_TEST
#define ATTRIBUTE_FLAGS_ONLINE(x)
bool isSCTFeatureControlCapable(const ata_identify_device *drive)
bool isSCTCapable(const ata_identify_device *drive)
void ata_print_identify_data(const void *id, bool all_words, int bit_level)
static void print_standby_timer(const char *msg, int timer, const ata_identify_device &drive)
static const char * sct_ptemp(signed char x, char(&buf)[20])
static void ataPrintSCTErrorRecoveryControl(bool set, unsigned short read_timer, unsigned short write_timer, bool power_on, bool mfg_default=false)
static void PrintSmartCapability(const ata_smart_values *data)
static const char * infofound(const char *output)
const char * ataprint_cpp_cvsid
static void ataPrintSCTCapability(const ata_identify_device *drive)
const devstat_entry_info devstat_info_0x04[]
static void PrintSmartTotalTimeCompleteOffline(const ata_smart_values *data)
static void print_aam_level(const char *msg, int level, int recommended=-1)
const devstat_entry_info devstat_info_0x01[]
static void set_json_globals_from_device_statistics(int page, int offset, int64_t val)
static void print_sata_version_and_speed(unsigned short word222, unsigned short word076, unsigned short word077)
static void print_ata_security_status(const char *msg, unsigned short state, unsigned short master_password_id)
static void PrintSmartOfflineCollectCap(const ata_smart_values *data)
int ataPrintMain(ata_device *device, const ata_print_options &options)
static void PrintSmartOfflineStatus(const ata_smart_values *data)
static void print_drive_info(const ata_identify_device *drive, const ata_size_info &sizes, int rpm, const drive_settings *dbentry, const char *dbversion)
static void PrintSmartSelfExecStatus(const ata_smart_values *data, firmwarebug_defs firmwarebugs)
const int num_devstat_infos
static const char * get_sata_version(unsigned short word222)
const devstat_entry_info devstat_info_0x03[]
static void PrintSmartConveyanceSelfTestPollingTime(const ata_smart_values *data)
static bool is_permissive()
const devstat_entry_info devstat_info_0x02[]
static int ataPrintSmartSelfTestlog(const ata_smart_selftestlog *log, bool allentries, firmwarebug_defs firmwarebugs)
static int PrintSmartErrorlog(const ata_smart_errorlog *data, firmwarebug_defs firmwarebugs)
static const char * get_ata_major_version(const ata_identify_device *drive)
static const char * sct_device_state_msg(unsigned char state)
static const char * sct_pbar(int x, char(&buf)[64])
static std::string format_st_er_desc(unsigned char CR, unsigned char FR, unsigned char ST, unsigned char ER, unsigned short SC, const ata_smart_errorlog_error_struct *lba28_regs, const ata_smart_exterrlog_error *lba48_regs)
static void ataPrintSelectiveSelfTestLog(const ata_selective_self_test_log *log, const ata_smart_values *sv)
static const char * get_pata_version(unsigned short word222, char(&buf)[32])
static bool print_pending_defects_log(ata_device *device, unsigned nsectors, unsigned max_entries)
static void PrintSmartAttribWithThres(const ata_smart_values *data, const ata_smart_thresholds_pvt *thresholds, const ata_vendor_attr_defs &defs, int rpm, int onlyfailed, unsigned char format)
static void PrintSmartExtendedSelfTestPollingTime(const ata_smart_values *data)
static void print_device_statistics_page(const json::ref &jref, const unsigned char *data, int page)
static bool print_device_statistics(ata_device *device, unsigned nsectors, const std::vector< int > &single_pages, bool all_pages, bool ssd_page, bool use_gplog)
static void PrintSataPhyEventCounters(const unsigned char *data, bool reset)
static void PrintSmartErrorLogCapability(const ata_smart_values *data, const ata_identify_device *identity)
static void PrintSmartShortSelfTestPollingTime(const ata_smart_values *data)
static const char * OfflineDataCollectionStatus(unsigned char status_byte)
static int find_msb(unsigned short word)
static std::string format_milliseconds(unsigned msec)
static void set_json_globals_from_smart_attrib(int id, const char *name, const ata_vendor_attr_defs &defs, uint64_t rawval)
static void PrintGeneralSmartValues(const ata_smart_values *data, const ata_identify_device *drive, firmwarebug_defs firmwarebugs)
static void PrintLogPages(const char *type, const unsigned char *data, unsigned char logaddr, unsigned page, unsigned num_pages, unsigned max_pages)
static void sct_jtemp2(const json::ref &jref, const char *name, signed char x)
static unsigned GetNumLogSectors(const ata_smart_log_directory *logdir, unsigned logaddr, bool gpl)
const ata_smart_log_directory * fake_logdir(ata_smart_log_directory *logdir, const ata_print_options &options)
static void print_apm_level(const char *msg, int level)
const devstat_entry_info devstat_info_0x07[]
static const char * get_error_log_state_desc(unsigned state)
static int ataPrintSCTTempHist(const ata_sct_temperature_history_table *tmh)
const devstat_entry_info devstat_info_0x00[]
static const char * get_log_rw(unsigned logaddr)
static const char * GetLogName(unsigned logaddr)
const devstat_entry_info devstat_info_0x05[]
static int PrintSmartExtSelfTestLog(const ata_smart_extselftestlog *log, unsigned nsectors, unsigned max_entries)
static void jset_sata_speed(const char *key, int value, int speed, const char *str)
static const char * get_sata_speed(int speed)
static int find_failed_attr(const ata_smart_values *data, const ata_smart_thresholds_pvt *thresholds, const ata_vendor_attr_defs &defs, int onlyfailed)
static int ataPrintSCTStatus(const ata_sct_status_response *sts)
static const char * get_device_statistics_page_name(int page)
const devstat_entry_info devstat_info_0x06[]
static const char * get_ata_minor_version(const ata_identify_device *drive)
static int ataPrintSmartSelfTestEntry(const json::ref &jref, unsigned testnum, unsigned char test_type, unsigned char test_status, unsigned short timestamp, uint64_t failing_lba, bool print_error_only, bool &print_header)
static int PrintSmartExtErrorLog(ata_device *device, const firmwarebug_defs &firmwarebugs, const ata_smart_exterrlog *log, unsigned nsectors, unsigned max_errors)
static void PrintLogDirectories(const ata_smart_log_directory *gplogdir, const ata_smart_log_directory *smartlogdir)
const devstat_entry_info * devstat_infos[]
static const char * get_form_factor(unsigned short word168)
virtual bool ata_identify_is_cached() const
Return true if OS caches ATA identify sector.
bool is_set(firmwarebug_t bug) const
Reference to a JSON element.
void set_unsafe_uint64(uint64_t value)
bool is_enabled() const
Return true if enabled.
int get_errno() const
Get last error number.
const char * get_errmsg() const
Get last error message.
virtual bool is_syscall_unsup() const
Return true if last error indicates an unsupported system call.
void clear_err()
Clear last error info.
bool ataIsSeagate(const ata_identify_device &drive, const drive_settings *dbentry)
bool ataReadFarmLog(ata_device *device, ataFarmLog &farmLog, unsigned nsectors)
void ataPrintFarmLog(const ataFarmLog &farmLog)
const drive_settings * lookup_drive_apply_presets(const ata_identify_device *drive, ata_vendor_attr_defs &defs, firmwarebug_defs &firmwarebugs, std::string &dbversion)
void show_presets(const ata_identify_device *drive)
unsigned char failuretest_permissive
static uint64_t sg_get_unaligned_le64(const void *p)
static uint32_t sg_get_unaligned_le32(const void *p)
void jout_startup_datetime(const char *prefix)
void failuretest(failure_type type, int returnvalue)
bool printing_is_switchable
void void jinf(const char *fmt,...) __attribute_format_printf(1
void void void jwrn(const char *fmt,...) __attribute_format_printf(1
void void void void jerr(const char *fmt,...) __attribute_format_printf(1
void jout(const char *fmt,...) __attribute_format_printf(1
void pout(const char *fmt,...)
unsigned short minor_rev_num
unsigned short major_rev_num
unsigned short words047_079[33]
unsigned short cfs_enable_1
unsigned short words088_255[168]
unsigned short command_set_2
unsigned short command_set_1
unsigned char serial_no[20]
bool smart_auto_offl_disable
bool sct_wcache_reorder_get
bool smart_auto_save_enable
bool smart_general_values
unsigned sct_erc_writetime
unsigned pending_defects_log
ata_selective_selftest_args smart_selective_args
std::vector< int > devstat_pages
unsigned smart_ext_error_log
unsigned smart_ext_selftest_log
firmwarebug_defs firmwarebugs
unsigned char output_format
int sct_wcache_reorder_set
bool smart_selftest_force
bool smart_selective_selftest_log
ata_vendor_attr_defs attribute_defs
unsigned sct_erc_readtime
std::vector< ata_log_request > log_requests
bool sct_wcache_sct_set_pers
bool sct_wcache_reorder_set_pers
bool smart_auto_offl_enable
bool smart_auto_save_disable
unsigned int over_limit_count
unsigned short min_erc_time
unsigned short sct_version
unsigned short format_version
signed char life_max_temp
unsigned char vendor_specific[32]
unsigned char device_state
unsigned int under_limit_count
signed char life_min_temp
unsigned short smart_status
unsigned short sampling_period
unsigned short format_version
unsigned short pendingtime
unsigned short logversion
unsigned short currentspan
unsigned log_sector_offset
unsigned char devicecontrolreg
unsigned char cylinder_high
unsigned char cylinder_low
unsigned char featuresreg
unsigned char sector_count
unsigned char sector_number
unsigned char cylinder_low
unsigned char sector_count
unsigned char sector_number
unsigned char cylinder_high
unsigned char error_register
struct ata_smart_errorlog_command_struct commands[5]
struct ata_smart_errorlog_error_struct error_struct
unsigned char device_control_register
unsigned char lba_low_register_hi
unsigned char lba_low_register
unsigned char count_register
unsigned char error_register
unsigned char count_register_hi
unsigned char lba_high_register_hi
unsigned char device_register
unsigned char status_register
unsigned char lba_mid_register
unsigned char lba_mid_register_hi
unsigned char lba_high_register
unsigned short error_log_index
ata_smart_exterrlog_error_log error_logs[4]
unsigned short device_error_count
struct ata_smart_extselftestlog_desc log_descs[19]
unsigned short log_desc_index
struct ata_smart_log_entry entry[255]
unsigned short int logversion
unsigned char mostrecenttest
struct ata_smart_selftestlog_struct selftest_struct[21]
unsigned short int revnumber
struct ata_smart_threshold_entry thres_entries[NUMBER_ATA_SMART_ATTRIBUTES]
unsigned char self_test_exec_status
unsigned char offline_data_collection_status
void dateandtimezoneepoch(char(&buffer)[DATEANDEPOCHLEN], time_t tval)
const char * format_capacity(char *str, int strsize, uint64_t val, const char *decimal_point)
const char * format_with_thousands_sep(char *str, int strsize, uint64_t val, const char *thousands_sep)
std::string strprintf(const char *fmt,...)
bool nonempty(const void *data, int size)
const char * packetdevicetype(int type)
struct tm * time_to_tm_local(struct tm *tp, time_t t)
bool str_starts_with(const char *str, const char *prefix)