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");
1145 uint8_t normval, uint8_t threshold,
1154 switch (defs[
id].raw_format) {
1157 case RAWFMT_SEC2HOUR: minutes = (rawval / 60) % 60; rawval /= 60*60;
break;
1161 rawval &= 0xffffffffULL;
1164 minutes = (int)(rawval >> 32) / (1000*60);
1167 rawval &= 0xffffffffULL;
1171 if (rawval > 0x00ffffffULL)
1173 jglb[
"power_on_time"][
"hours"] = rawval;
1175 jglb[
"power_on_time"][
"minutes"] = minutes;
1179 if (strcmp(name,
"Power_Cycle_Count"))
1181 switch (defs[
id].raw_format) {
1186 if (rawval > 0x00ffffffULL)
1188 jglb[
"power_cycle_count"] = rawval;
1197 "Reallocated_Sector_C.*|Retired_Block_C.*|"
1198 "(Remain.*_)?Spare_Blocks(_(Avail|Remain).*)?"
1200 if ((
id == 5 ||
id == 17 ||
id >= 100) && spare_regex.
full_match(name)) {
1201 jglb[
"spare_available"][
"current_percent"] = (normval <= 100 ? normval : 100);
1202 if (0 < threshold && threshold < 50)
1203 jglb[
"spare_available"][
"threshold_percent"] = threshold;
1208 "SSD_Life_Left.*|Wear_Leveling.*"
1210 if (
id >= 100 && endurance_regex.
full_match(name)) {
1212 jglb[
"endurance_used"][
"current_percent"] = (normval <= 100 ? 100 - normval : 0);
1223 int onlyfailed,
unsigned char format)
1228 bool needheader =
true;
1235 unsigned char threshold = 0;
1250 jout(
"SMART Attributes Data Structure revision number: %d\n",(
int)
data->revnumber);
1251 jglb[
"ata_smart_attributes"][
"revision"] =
data->revnumber;
1252 jout(
"Vendor Specific SMART Attributes with Thresholds:\n");
1255 jout(
"ID#%s ATTRIBUTE_NAME FLAG VALUE WORST THRESH TYPE UPDATED WHEN_FAILED RAW_VALUE\n",
1256 (!hexid ?
"" :
" "));
1258 jout(
"ID#%s ATTRIBUTE_NAME FLAGS VALUE WORST THRESH FAIL RAW_VALUE\n",
1259 (!hexid ?
"" :
" "));
1264 std::string valstr, worstr, threstr;
1269 valstr = (!hexval ?
"---" :
"----");
1274 worstr = (!hexval ?
"---" :
"----");
1276 threstr = (!hexval ?
strprintf(
"%.3d", threshold)
1279 threstr = (!hexval ?
"---" :
"----");
1282 std::string idstr = (!hexid ?
strprintf(
"%3d", attr.
id)
1299 jout(
"%s %-24s0x%04x %-4s %-4s %-4s %-10s%-9s%-12s%s\n",
1300 idstr.c_str(), attrname.c_str(), attr.
flags,
1301 valstr.c_str(), worstr.c_str(), threstr.c_str(),
1309 jout(
"%s %-24s%s %-4s %-4s %-4s %-5s%s\n",
1310 idstr.c_str(), attrname.c_str(), flagstr,
1311 valstr.c_str(), worstr.c_str(), threstr.c_str(),
1320 json::ref jref =
jglb[
"ata_smart_attributes"][
"table"][ji++];
1321 jref[
"id"] = attr.
id;
1322 jref[
"name"] = attrname;
1326 jref[
"worst"] = attr.
worst;
1328 jref[
"thresh"] = threshold;
1335 jreff[
"value"] = attr.
flags;
1336 jreff[
"string"] = flagstr;
1347 jref[
"raw"][
"value"] = rawval;
1348 jref[
"raw"][
"string"] = rawstr;
1351 attr.
current, threshold, rawval);
1355 if (!onlyfailed && brief) {
1356 int n = (!hexid ? 28 : 29);
1357 jout(
"%*s||||||_ K auto-keep\n"
1358 "%*s|||||__ C event count\n"
1359 "%*s||||___ R error rate\n"
1360 "%*s|||____ S speed/performance\n"
1361 "%*s||_____ O updated online\n"
1362 "%*s|______ P prefailure warning\n",
1363 n,
"", n,
"", n,
"", n,
"", n,
"", n,
"");
1374 jglb[
"temperature"][
"current"] = t;
1381 if (!(sctcaps & 0x01))
1384 jout(
"SCT capabilities: \t (0x%04x)\tSCT Status supported.\n", sctcaps);
1385 jref[
"value"] = sctcaps;
1387 jout(
"\t\t\t\t\tSCT Error Recovery Control supported.\n");
1388 jref[
"error_recovery_control_supported"] = !!(sctcaps & 0x08);
1390 jout(
"\t\t\t\t\tSCT Feature Control supported.\n");
1391 jref[
"feature_control_supported"] = !!(sctcaps & 0x10);
1393 jout(
"\t\t\t\t\tSCT Data Table supported.\n");
1394 jref[
"data_table_supported"] = !!(sctcaps & 0x20);
1401 jout(
"General SMART Values:\n");
1416 "General Purpose Logging supported.":
1417 "No General Purpose Logging support.");
1418 jglb[
"ata_smart_data"][
"capabilities"][
"gp_logging_supported"] =
1459 case 0x00:
return "Log Directory";
1460 case 0x01:
return "Summary SMART error log";
1461 case 0x02:
return "Comprehensive SMART error log";
1462 case 0x03:
return "Ext. Comprehensive SMART error log";
1463 case 0x04:
return "Device Statistics log";
1464 case 0x05:
return "Reserved for CFA";
1465 case 0x06:
return "SMART self-test log";
1466 case 0x07:
return "Extended self-test log";
1467 case 0x08:
return "Power Conditions log";
1468 case 0x09:
return "Selective self-test log";
1469 case 0x0a:
return "Device Statistics Notification";
1470 case 0x0b:
return "Reserved for CFA";
1471 case 0x0c:
return "Pending Defects log";
1472 case 0x0d:
return "LPS Mis-alignment log";
1473 case 0x0e:
return "Reserved for ZAC-2";
1474 case 0x0f:
return "Sense Data for Successful NCQ Cmds log";
1475 case 0x10:
return "NCQ Command Error log";
1476 case 0x11:
return "SATA Phy Event Counters log";
1478 case 0x12:
return "SATA NCQ Non-Data log";
1479 case 0x13:
return "SATA NCQ Send and Receive log";
1480 case 0x14:
return "Hybrid Information log";
1481 case 0x15:
return "Rebuild Assist log";
1482 case 0x16:
return "Out Of Band Management Control log";
1483 case 0x17:
return "Reserved for Serial ATA";
1484 case 0x18:
return "Command Duration Limits log";
1485 case 0x19:
return "LBA Status log";
1487 case 0x20:
return "Streaming performance log";
1488 case 0x21:
return "Write stream error log";
1489 case 0x22:
return "Read stream error log";
1490 case 0x23:
return "Delayed sector log";
1491 case 0x24:
return "Current Device Internal Status Data log";
1492 case 0x25:
return "Saved Device Internal Status Data log";
1494 case 0x2f:
return "Set Sector Configuration";
1495 case 0x30:
return "IDENTIFY DEVICE data log";
1497 case 0x42:
return "Mutate Configurations log";
1499 case 0x47:
return "Concurrent Positioning Ranges log";
1501 case 0x53:
return "Sense Data log";
1503 case 0x59:
return "Power Consumption Control log";
1505 case 0x61:
return "Capacity/Model Number Mapping log";
1507 case 0xe0:
return "SCT Command/Status";
1508 case 0xe1:
return "SCT Data Transfer";
1510 if (0xa0 <= logaddr && logaddr <= 0xdf)
1511 return "Device vendor specific log";
1512 if (0x80 <= logaddr && logaddr <= 0x9f)
1513 return "Host vendor specific log";
1522 if ( ( logaddr <= 0x08)
1523 || (0x0c <= logaddr && logaddr <= 0x0d)
1524 || (0x0f <= logaddr && logaddr <= 0x14)
1525 || (0x19 == logaddr)
1526 || (0x20 <= logaddr && logaddr <= 0x25)
1527 || (0x2f <= logaddr && logaddr <= 0x30)
1528 || (0x42 == logaddr)
1529 || (0x47 == logaddr)
1530 || (0x53 == logaddr)
1531 || (0x59 == logaddr)
1532 || (0x61 == logaddr))
1535 if ( ( logaddr <= 0x0a)
1536 || (0x15 <= logaddr && logaddr <= 0x16)
1537 || (0x18 == logaddr)
1538 || (0x80 <= logaddr && logaddr <= 0x9f)
1539 || (0xe0 <= logaddr && logaddr <= 0xe1))
1542 if (0xa0 <= logaddr && logaddr <= 0xdf)
1552 memset(logdir, 0,
sizeof(*logdir));
1570 jout(
"General Purpose Log Directory Version %u\n", gplogdir->
logversion);
1571 jref[
"gp_dir_version"] = gplogdir->
logversion;
1574 jout(
"SMART %sLog Directory Version %u%s\n",
1575 (gplogdir ?
" " :
""), smartlogdir->
logversion,
1576 (smartlogdir->
logversion==1 ?
" [multi-sector log support]" :
""));
1577 jref[
"smart_dir_version"] = smartlogdir->
logversion;
1578 jref[
"smart_dir_multi_sector"] = (smartlogdir->
logversion == 1);
1581 jout(
"Address Access R/W Size Description\n");
1583 for (
unsigned i = 0, ji = 0; i <= 0xff; i++) {
1588 if (!(smart_numsect || gp_numsect))
1591 const char * acc;
unsigned size;
1592 if (smart_numsect == gp_numsect) {
1593 acc =
"GPL,SL";
size = gp_numsect;
1595 else if (!smart_numsect) {
1596 acc =
"GPL";
size = gp_numsect;
1598 else if (!gp_numsect) {
1599 acc =
" SL";
size = smart_numsect;
1606 if (acc && ((0x80 <= i && i < 0x9f) || (0xa0 <= i && i < 0xdf))) {
1608 unsigned imax = (i < 0x9f ? 0x9f : 0xdf);
1609 for (
unsigned j = i+1; j <= imax; j++) {
1613 if (!(sn == smart_numsect && gn == gp_numsect))
1623 jout(
"0x%02x-0x%02x %-6s %-3s %5u %s\n", i, i2, acc, rw,
size, name);
1625 jout(
"0x%02x %-6s %-3s %5u %s\n", i, acc, rw,
size, name);
1628 jout(
"0x%02x %-6s %-3s %5u %s\n", i,
"GPL", rw, gp_numsect, name);
1629 jout(
"0x%02x %-6s %-3s %5u %s\n", i,
"SL", rw, smart_numsect, name);
1634 jrefi[
"address"] = i;
1635 jrefi[
"name"] = name;
1636 if (rw[0] ==
'R' && rw[1] && rw[2]) {
1637 jrefi[
"read"] =
true;
1638 jrefi[
"write"] = (rw[2] ==
'W');
1641 jrefi[
"gp_sectors"] = gp_numsect;
1643 jrefi[
"smart_sectors"] = smart_numsect;
1655 unsigned char logaddr,
unsigned page,
1656 unsigned num_pages,
unsigned max_pages)
1658 pout(
"%s Log 0x%02x [%s], Page %u-%u (of %u)\n",
1659 type, logaddr,
GetLogName(logaddr), page, page+num_pages-1, max_pages);
1660 for (
unsigned i = 0; i < num_pages * 512; i += 16) {
1661 const unsigned char * p =
data+i;
1662 pout(
"%07x: %02x %02x %02x %02x %02x %02x %02x %02x "
1663 "%02x %02x %02x %02x %02x %02x %02x %02x ",
1665 p[ 0], p[ 1], p[ 2], p[ 3], p[ 4], p[ 5], p[ 6], p[ 7],
1666 p[ 8], p[ 9], p[10], p[11], p[12], p[13], p[14], p[15]);
1667#define P(n) (' ' <= p[n] && p[n] <= '~' ? (int)p[n] : '.')
1668 pout(
"|%c%c%c%c%c%c%c%c"
1669 "%c%c%c%c%c%c%c%c|\n",
1670 P( 0),
P( 1),
P( 2),
P( 3),
P( 4),
P( 5),
P( 6),
P( 7),
1671 P( 8),
P( 9),
P(10),
P(11),
P(12),
P(13),
P(14),
P(15));
1673 if ((i & 0x1ff) == 0x1f0)
1691 { 2,
"List of supported log pages" },
1696 { 2,
"General Statistics" },
1697 { 4,
"Lifetime Power-On Resets" },
1698 { 4,
"Power-on Hours" },
1699 { 6,
"Logical Sectors Written" },
1700 { 6,
"Number of Write Commands" },
1701 { 6,
"Logical Sectors Read" },
1702 { 6,
"Number of Read Commands" },
1703 { 6,
"Date and Time TimeStamp" },
1704 { 4,
"Pending Error Count" },
1705 { 2,
"Workload Utilization" },
1706 { 6,
"Utilization Usage Rate" },
1707 { 7,
"Resource Availability" },
1708 { 1,
"Random Write Resources Used" },
1713 { 2,
"Free-Fall Statistics" },
1714 { 4,
"Number of Free-Fall Events Detected" },
1715 { 4,
"Overlimit Shock Events" },
1720 { 2,
"Rotating Media Statistics" },
1721 { 4,
"Spindle Motor Power-on Hours" },
1722 { 4,
"Head Flying Hours" },
1723 { 4,
"Head Load Events" },
1724 { 4,
"Number of Reallocated Logical Sectors" },
1725 { 4,
"Read Recovery Attempts" },
1726 { 4,
"Number of Mechanical Start Failures" },
1727 { 4,
"Number of Realloc. Candidate Logical Sectors" },
1728 { 4,
"Number of High Priority Unload Events" },
1733 { 2,
"General Errors Statistics" },
1734 { 4,
"Number of Reported Uncorrectable Errors" },
1736 { 4,
"Resets Between Cmd Acceptance and Completion" },
1737 { 4,
"Physical Element Status Changed" },
1742 { 2,
"Temperature Statistics" },
1743 { -1,
"Current Temperature" },
1744 { -1,
"Average Short Term Temperature" },
1745 { -1,
"Average Long Term Temperature" },
1746 { -1,
"Highest Temperature" },
1747 { -1,
"Lowest Temperature" },
1748 { -1,
"Highest Average Short Term Temperature" },
1749 { -1,
"Lowest Average Short Term Temperature" },
1750 { -1,
"Highest Average Long Term Temperature" },
1751 { -1,
"Lowest Average Long Term Temperature" },
1752 { 4,
"Time in Over-Temperature" },
1753 { -1,
"Specified Maximum Operating Temperature" },
1754 { 4,
"Time in Under-Temperature" },
1755 { -1,
"Specified Minimum Operating Temperature" },
1760 { 2,
"Transport Statistics" },
1761 { 4,
"Number of Hardware Resets" },
1762 { 4,
"Number of ASR Events" },
1763 { 4,
"Number of Interface CRC Errors" },
1768 { 2,
"Solid State Device Statistics" },
1769 { 1,
"Percentage Used Endurance Indicator" },
1794 return "Vendor Specific Statistics";
1795 return "Unknown Statistics";
1803 case 0x008:
jglb[
"power_cycle_count"] = val;
break;
1804 case 0x010:
jglb[
"power_on_time"][
"hours"]= val;
break;
1809 case 0x008:
jglb[
"temperature"][
"current"] = val;
break;
1810 case 0x020:
jglb[
"temperature"][
"lifetime_max"] = val;
break;
1811 case 0x028:
jglb[
"temperature"][
"lifetime_min"] = val;
break;
1812 case 0x050:
jglb[
"temperature"][
"lifetime_over_limit_minutes"] = val;
break;
1813 case 0x058:
jglb[
"temperature"][
"op_limit_max"] = val;
break;
1814 case 0x060:
jglb[
"temperature"][
"lifetime_under_limit_minutes"] = val;
break;
1815 case 0x068:
jglb[
"temperature"][
"op_limit_min"] = val;
break;
1820 case 0x008:
jglb[
"endurance_used"][
"current_percent"] = val;
break;
1832 static const char line[] =
" ===== = = === == ";
1834 pout(
"0x%02x%s%s (empty) ==\n", page, line, name);
1837 if (
data[2] != page) {
1838 pout(
"0x%02x%s%s (invalid page 0x%02x in header) ==\n", page, line, name,
data[2]);
1842 int rev =
data[0] | (
data[1] << 8);
1843 jout(
"0x%02x%s%s (rev %d) ==\n", page, line, name, rev);
1844 jref[
"number"] = page;
1845 jref[
"name"] = name;
1846 jref[
"revision"] = rev;
1850 for (
int i = 1, offset = 8; offset < 512-7; i++, offset+=8) {
1852 if (info && !info[i].
size)
1857 if (!(
flags & 0x80))
1861 if (!info && (
data[offset+5] ||
data[offset+6])) {
1862 pout(
"0x%02x 0x%03x - - [Trailing garbage ignored]\n", page, offset);
1867 const char * valname = (info ? info[i].
name :
1868 (page == 0xff) ?
"Vendor Specific"
1872 int size = (info ? info[i].
size : 7);
1875 bool valid = !!(
flags & 0x40);
1876 bool normalized = !!(
flags & 0x20);
1877 bool supports_dsn = !!(
flags & 0x10);
1878 bool monitored_condition_met = !!(
flags & 0x08);
1880 unsigned char reserved_flags = (
flags & 0x07);
1888 val = (
signed char)
data[offset];
1891 for (
int j = 0; j <
size; j++)
1892 val |= (int64_t)
data[offset+j] << (j*8);
1894 snprintf(valstr,
sizeof(valstr),
"%" PRId64, val);
1898 valstr[0] =
'-'; valstr[1] = 0;
1902 (valid ?
'V' :
'-'),
1903 (normalized ?
'N' :
'-'),
1904 (supports_dsn ?
'D' :
'-'),
1905 (monitored_condition_met ?
'C' :
'-'),
1906 (reserved_flags ?
'+' :
' '),
1910 jout(
"0x%02x 0x%03x %d %15s %s %s\n",
1911 page, offset, abs(
size), valstr, flagstr+1, valname);
1917 jrefi[
"offset"] = offset;
1918 jrefi[
"name"] = valname;
1919 jrefi[
"size"] = abs(
size);
1921 jrefi[
"value"] = val;
1924 jreff[
"value"] =
flags;
1925 jreff[
"string"] = flagstr;
1926 jreff[
"valid"] = valid;
1927 jreff[
"normalized"] = normalized;
1928 jreff[
"supports_dsn"] = supports_dsn;
1929 jreff[
"monitored_condition_met"] = monitored_condition_met;
1931 jreff[
"other"] = reserved_flags;
1939 const std::vector<int> & single_pages,
bool all_pages,
bool ssd_page,
1943 unsigned char page_0[512] = {0, };
1951 jerr(
"Read Device Statistics page 0x00 failed\n\n");
1955 unsigned char nentries = page_0[8];
1956 if (!(page_0[2] == 0 && nentries > 0)) {
1957 jerr(
"Device Statistics page 0x00 is invalid (page=0x%02x, nentries=%d)\n\n", page_0[2], nentries);
1962 std::vector<int> pages;
1966 for (i = 0; i < nentries; i++) {
1967 int page = page_0[8+1+i];
1969 pages.push_back(page);
1974 bool print_page_0 =
false;
1975 for (i = 0; i < single_pages.size() || ssd_page; i++) {
1976 int page = (i < single_pages.size() ? single_pages[i] : 0x07);
1978 print_page_0 =
true;
1979 else if (page >= (
int)nsectors)
1980 pout(
"Device Statistics Log has only 0x%02x pages\n", nsectors);
1982 pages.push_back(page);
1991 pout(
"Device Statistics (%s Log 0x04) supported pages\n",
1992 use_gplog ?
"GP" :
"SMART");
1993 jout(
"Page Description\n");
1994 for (i = 0; i < nentries; i++) {
1995 int page = page_0[8+1+i];
1997 jout(
"0x%02x %s\n", page, name);
1998 jref[
"supported_pages"][i][
"number"] = page;
1999 jref[
"supported_pages"][i][
"name"] = name;
2005 if (!pages.empty()) {
2006 pout(
"Device Statistics (%s Log 0x04)\n",
2007 use_gplog ?
"GP" :
"SMART");
2008 jout(
"Page Offset Size Value Flags Description\n");
2012 for (i = 0; i < pages.size(); i++) {
2013 int page = pages[i];
2014 if (max_page < page && page < 0xff)
2021 jerr(
"Read Device Statistics pages 0x00-0x%02x failed\n\n", max_page);
2026 for (i = 0; i < pages.size(); i++) {
2027 int page = pages[i];
2030 jerr(
"Read Device Statistics page 0x%02x failed\n\n", page);
2034 else if (page > max_page)
2037 int offset = (use_gplog ? 0 : page * 512);
2041 jout(
"%32s|||_ C monitored condition met\n",
"");
2042 jout(
"%32s||__ D supports DSN\n",
"");
2043 jout(
"%32s|___ N normalized value\n\n",
"");
2056 unsigned max_entries)
2059 unsigned char page_buf[512] = {0, };
2061 pout(
"Read Pending Defects log page 0x00 failed\n\n");
2065 jout(
"Pending Defects log (GP Log 0x0c)\n");
2068 jref[
"size"] = nsectors * 32 - 1;
2069 jref[
"count"] = nentries;
2071 jout(
"No Defects Logged\n\n");
2076 jout(
"Index LBA Hours\n");
2077 for (
unsigned i = 0, pi = 1, page = 0; i < nentries && i < max_entries; i++, pi++) {
2080 if (++page >= nsectors) {
2081 pout(
"Pending Defects count %u exceeds log size (#pages=%u)\n\n",
2082 nentries, nsectors);
2086 pout(
"Read Pending Defects log page 0x%02x failed\n\n", page);
2092 const unsigned char *
entry = page_buf + 16 * pi;
2095 if (hours != 0xffffffffU)
2096 snprintf(hourstr,
sizeof(hourstr),
"%u", hours);
2098 hourstr[0] =
'-', hourstr[1] = 0;
2100 jout(
"%5u %18" PRIu64
" %8s\n", i, lba, hourstr);
2104 if (hours != 0xffffffffU)
2105 jrefi[
"power_on_hours"] = hours;
2108 if (nentries > max_entries)
2109 pout(
"... (%u entries not shown)\n", nentries - max_entries);
2122 jout(
"SATA Phy Event Counters (GP Log 0x11)\n");
2124 pout(
"[Reserved: 0x%02x 0x%02x 0x%02x 0x%02x]\n",
2126 jout(
"ID Size Value Description\n");
2128 for (
unsigned i = 4, ji = 0; ; ) {
2130 unsigned id =
data[i] | (
data[i+1] << 8);
2131 unsigned size = ((
id >> 12) & 0x7) << 1;
2140 pout(
"0x%04x %u: Invalid entry\n",
id,
size);
2145 uint64_t val = 0, max_val = 0;
2146 for (
unsigned j = 0; j <
size; j+=2) {
2147 val |= (uint64_t)(
data[i+j] | (
data[i+j+1] << 8)) << (j*8);
2148 max_val |= (uint64_t)0xffffU << (j*8);
2155 case 0x001: name =
"Command failed due to ICRC error";
break;
2156 case 0x002: name =
"R_ERR response for data FIS";
break;
2157 case 0x003: name =
"R_ERR response for device-to-host data FIS";
break;
2158 case 0x004: name =
"R_ERR response for host-to-device data FIS";
break;
2159 case 0x005: name =
"R_ERR response for non-data FIS";
break;
2160 case 0x006: name =
"R_ERR response for device-to-host non-data FIS";
break;
2161 case 0x007: name =
"R_ERR response for host-to-device non-data FIS";
break;
2162 case 0x008: name =
"Device-to-host non-data FIS retries";
break;
2163 case 0x009: name =
"Transition from drive PhyRdy to drive PhyNRdy";
break;
2164 case 0x00A: name =
"Device-to-host register FISes sent due to a COMRESET";
break;
2165 case 0x00B: name =
"CRC errors within host-to-device FIS";
break;
2166 case 0x00D: name =
"Non-CRC errors within host-to-device FIS";
break;
2167 case 0x00F: name =
"R_ERR response for host-to-device data FIS, CRC";
break;
2168 case 0x010: name =
"R_ERR response for host-to-device data FIS, non-CRC";
break;
2169 case 0x012: name =
"R_ERR response for host-to-device non-data FIS, CRC";
break;
2170 case 0x013: name =
"R_ERR response for host-to-device non-data FIS, non-CRC";
break;
2171 default: name = ((
id & 0x8000) ?
"Vendor specific" :
"Unknown");
break;
2175 jout(
"0x%04x %u %12" PRIu64
"%c %s\n",
id,
size, val,
2176 (val == max_val ?
'+' :
' '), name);
2178 json::ref jref =
jglb[
"sata_phy_event_counters"][
"table"][ji++];
2180 jref[
"name"] = name;
2181 jref[
"size"] =
size;
2182 jref[
"value"] = val;
2183 jref[
"overflow"] = (val == max_val);
2186 jout(
"All counters reset\n");
2188 jglb[
"sata_phy_event_counters"][
"reset"] = reset;
2194 unsigned days = msec / 86400000U;
2195 msec -= days * 86400000U;
2196 unsigned hours = msec / 3600000U;
2197 msec -= hours * 3600000U;
2198 unsigned min = msec / 60000U;
2199 msec -= min * 60000U;
2200 unsigned sec = msec / 1000U;
2201 msec -= sec * 1000U;
2206 str +=
strprintf(
"%02u:%02u:%02u.%03u", hours, min, sec, msec);
2215 case 0x0:
return "in an unknown state";
2216 case 0x1:
return "sleeping";
2217 case 0x2:
return "in standby mode";
2218 case 0x3:
return "active or idle";
2219 case 0x4:
return "doing SMART Offline or Self-test";
2221 return (state < 0xb ?
"in a reserved state"
2222 :
"in a vendor specific state");
2231 jout(
"SMART Error Log Version: %d\n", (
int)
data->revnumber);
2232 jref[
"revision"] =
data->revnumber;
2236 if ( !( !
data->ata_error_count == !
data->error_log_pointer
2237 && !((
data->ata_error_count -
data->error_log_pointer) % 5))
2239 pout(
"Warning: ATA error count %d inconsistent with error log index %d\n",
2240 data->ata_error_count,
data->error_log_pointer);
2243 if (!(
data->ata_error_count &&
data->error_log_pointer)) {
2244 jout(
"No Errors Logged\n\n");
2250 if (
data->error_log_pointer>5){
2251 pout(
"Invalid Error Log index = 0x%02x (valid range is from 1 to 5)\n",
2252 data->error_log_pointer);
2253 pout(
"ATA Error Count: %d (possibly also invalid)\n\n",
data->ata_error_count);
2258 if (
data->ata_error_count<=5)
2259 jout(
"ATA Error Count: %d\n", (
int)
data->ata_error_count);
2261 jout(
"ATA Error Count: %d (device log contains only the most recent five errors)\n",
2262 (
int)
data->ata_error_count);
2263 jref[
"count"] =
data->ata_error_count;
2264 jref[
"logged_count"] = (
data->ata_error_count <= 5 ?
data->ata_error_count : 5);
2267 jout(
"\tCR = Command Register [HEX]\n"
2268 "\tFR = Features Register [HEX]\n"
2269 "\tSC = Sector Count Register [HEX]\n"
2270 "\tSN = Sector Number Register [HEX]\n"
2271 "\tCL = Cylinder Low Register [HEX]\n"
2272 "\tCH = Cylinder High Register [HEX]\n"
2273 "\tDH = Device/Head Register [HEX]\n"
2274 "\tDC = Device Command Register [HEX]\n"
2275 "\tER = Error register [HEX]\n"
2276 "\tST = Status register [HEX]\n"
2277 "Powered_Up_Time is measured from power on, and printed as\n"
2278 "DDd+hh:mm:SS.sss where DD=days, hh=hours, mm=minutes,\n"
2279 "SS=sec, and sss=millisec. It \"wraps\" after 49.710 days.\n\n");
2282 for (
int k = 4, ji = 0; k >= 0; k--) {
2285 int i = (
data->error_log_pointer + k) % 5;
2290 if (
nonempty(elog,
sizeof(*elog))){
2297 jout(
"Error %d occurred at disk power-on lifetime: %d hours (%d days + %d hours)\n",
2302 jrefi[
"error_number"] =
data->ata_error_count + k - 4;
2303 jrefi[
"lifetime_hours"] = summary->
timestamp;
2305 jout(
" When the command that caused the error occurred, the device was %s.\n\n", msgstate);
2306 jout(
" After command completion occurred, registers were:\n"
2307 " ER ST SC SN CL CH DH\n"
2308 " -- -- -- -- -- -- --\n"
2309 " %02x %02x %02x %02x %02x %02x %02x",
2319 json::ref jrefir = jrefi[
"completion_registers"];
2321 jrefir[
"status"] = summary->
status;
2332 if (!st_er_desc.empty()) {
2333 jout(
" %s", st_er_desc.c_str());
2334 jrefi[
"error_description"] = st_er_desc;
2337 jout(
" Commands leading to the command that caused the error were:\n"
2338 " CR FR SC SN CL CH DH DC Powered_Up_Time Command/Feature_Name\n"
2339 " -- -- -- -- -- -- -- -- ---------------- --------------------\n");
2340 for (
int j = 4, jj = 0; j >= 0; j--) {
2344 if (
nonempty(thiscommand,
sizeof(*thiscommand))) {
2346 jout(
" %02x %02x %02x %02x %02x %02x %02x %02x %16s %s\n",
2358 json::ref jrefic = jrefi[
"previous_commands"][jj++];
2359 json::ref jreficr = jrefic[
"registers"];
2360 jreficr[
"command"] = thiscommand->
commandreg;
2368 jrefic[
"powerup_milliseconds"] = thiscommand->
timestamp;
2369 jrefic[
"command_name"] = atacmd;
2379 return data->ata_error_count;
2386 unsigned nsectors,
unsigned max_errors)
2389 jout(
"SMART Extended Comprehensive Error Log Version: %u (%u sectors)\n",
2391 jref[
"revision"] = log->
version;
2392 jref[
"sectors"] = nsectors;
2395 jout(
"No Errors Logged\n\n");
2402 unsigned nentries = nsectors * 4;
2404 if (!(1 <= erridx && erridx <= nentries)){
2409 pout(
"Invalid Error Log index = 0x%04x (reserved = 0x%02x)\n", erridx, log->
reserved1);
2413 pout(
"Invalid Error Log index = 0x%04x, trying reserved byte (0x%02x) instead\n", erridx, log->
reserved1);
2424 if (errcnt <= nentries)
2428 jout(
"Device Error Count: %u (device log contains only the most recent %u errors)\n",
2432 jref[
"logged_count"] = errcnt;
2434 if (max_errors < errcnt)
2435 errcnt = max_errors;
2438 jout(
"\tCR = Command Register\n"
2439 "\tFEATR = Features Register\n"
2440 "\tCOUNT = Count (was: Sector Count) Register\n"
2441 "\tLBA_48 = Upper bytes of LBA High/Mid/Low Registers ] ATA-8\n"
2442 "\tLH = LBA High (was: Cylinder High) Register ] LBA\n"
2443 "\tLM = LBA Mid (was: Cylinder Low) Register ] Register\n"
2444 "\tLL = LBA Low (was: Sector Number) Register ]\n"
2445 "\tDV = Device (was: Device/Head) Register\n"
2446 "\tDC = Device Control Register\n"
2447 "\tER = Error register\n"
2448 "\tST = Status register\n"
2449 "Powered_Up_Time is measured from power on, and printed as\n"
2450 "DDd+hh:mm:SS.sss where DD=days, hh=hours, mm=minutes,\n"
2451 "SS=sec, and sss=millisec. It \"wraps\" after 49.710 days.\n\n");
2455 unsigned log_buf_page = ~0;
2459 i < errcnt; i++, errnum--, erridx = (erridx > 0 ? erridx - 1 : nentries - 1)) {
2463 unsigned page = erridx / 4;
2467 if (page != log_buf_page) {
2468 memset(&log_buf, 0,
sizeof(log_buf));
2471 log_buf_page = page;
2479 jrefi[
"error_number"] = errnum;
2480 jrefi[
"log_index"] = erridx;
2484 jout(
"Error %u [%u] log entry is empty\n", errnum, erridx);
2491 jout(
"Error %u [%u] occurred at disk power-on lifetime: %u hours (%u days + %u hours)\n",
2494 jrefi[
"lifetime_hours"] = err.
timestamp;
2497 jout(
" When the command that caused the error occurred, the device was %s.\n\n", msgstate);
2498 jrefi[
"device_state"][
"value"] = err.
state;
2499 jrefi[
"device_state"][
"string"] = msgstate;
2502 jout(
" After command completion occurred, registers were:\n"
2503 " ER -- ST COUNT LBA_48 LH LM LL DV DC\n"
2504 " -- -- -- == -- == == == -- -- -- -- --\n"
2505 " %02x -- %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x",
2520 json::ref jrefir = jrefi[
"completion_registers"];
2537 if (!st_er_desc.empty()) {
2538 jout(
" %s", st_er_desc.c_str());
2539 jrefi[
"error_description"] = st_er_desc;
2544 jout(
" Commands leading to the command that caused the error were:\n"
2545 " CR FEATR COUNT LBA_48 LH LM LL DV DC Powered_Up_Time Command/Feature_Name\n"
2546 " -- == -- == -- == == == -- -- -- -- -- --------------- --------------------\n");
2547 for (
int ci = 4, cji = 0; ci >= 0; ci--) {
2556 jout(
" %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %16s %s\n",
2557 cmd.command_register,
2558 cmd.features_register_hi,
2559 cmd.features_register,
2560 cmd.count_register_hi,
2562 cmd.lba_high_register_hi,
2563 cmd.lba_mid_register_hi,
2564 cmd.lba_low_register_hi,
2565 cmd.lba_high_register,
2566 cmd.lba_mid_register,
2567 cmd.lba_low_register,
2568 cmd.device_register,
2569 cmd.device_control_register,
2573 json::ref jrefic = jrefi[
"previous_commands"][cji++];
2574 json::ref jreficr = jrefic[
"registers"];
2575 jreficr[
"command"] =
cmd.command_register;
2576 jreficr[
"features"] = (
cmd.features_register_hi << 8) |
cmd.features_register;
2577 jreficr[
"count"] = (
cmd.count_register_hi << 8) |
cmd.count_register;
2578 jreficr[
"lba"] = ((uint64_t)
cmd.lba_high_register_hi << 40)
2579 | ((uint64_t)
cmd.lba_mid_register_hi << 32)
2580 | ((uint64_t)
cmd.lba_low_register_hi << 24)
2581 | ((unsigned)
cmd.lba_high_register << 16)
2582 | ((unsigned)
cmd.lba_mid_register << 8)
2583 | ((unsigned)
cmd.lba_low_register );
2584 jreficr[
"device"] =
cmd.device_register;
2585 jreficr[
"device_control"] =
cmd.device_control_register;
2586 jrefic[
"powerup_milliseconds"] =
cmd.timestamp;
2587 jrefic[
"command_name"] = atacmd;
2605 unsigned testnum,
unsigned char test_type,
2606 unsigned char test_status,
2607 unsigned short timestamp,
2608 uint64_t failing_lba,
2609 bool print_error_only,
bool & print_header)
2613 switch (test_status >> 4) {
2615 if ((test_type & 0x7f) == 0x02)
2625 if (retval >= 0 && print_error_only)
2628 std::string msgtest;
2629 switch (test_type) {
2630 case 0x00: msgtest =
"Offline";
break;
2631 case 0x01: msgtest =
"Short offline";
break;
2632 case 0x02: msgtest =
"Extended offline";
break;
2633 case 0x03: msgtest =
"Conveyance offline";
break;
2634 case 0x04: msgtest =
"Selective offline";
break;
2635 case 0x7f: msgtest =
"Abort offline test";
break;
2636 case 0x81: msgtest =
"Short captive";
break;
2637 case 0x82: msgtest =
"Extended captive";
break;
2638 case 0x83: msgtest =
"Conveyance captive";
break;
2639 case 0x84: msgtest =
"Selective captive";
break;
2641 if ((0x40 <= test_type && test_type <= 0x7e) || 0x90 <= test_type)
2642 msgtest =
strprintf(
"Vendor (0x%02x)", test_type);
2644 msgtest =
strprintf(
"Reserved (0x%02x)", test_type);
2647 std::string msgstat;
2648 switch (test_status >> 4) {
2649 case 0x0: msgstat =
"Completed without error";
break;
2650 case 0x1: msgstat =
"Aborted by host";
break;
2651 case 0x2: msgstat =
"Interrupted (host reset)";
break;
2652 case 0x3: msgstat =
"Fatal or unknown error";
break;
2653 case 0x4: msgstat =
"Completed: unknown failure";
break;
2654 case 0x5: msgstat =
"Completed: electrical failure";
break;
2655 case 0x6: msgstat =
"Completed: servo/seek failure";
break;
2656 case 0x7: msgstat =
"Completed: read failure";
break;
2657 case 0x8: msgstat =
"Completed: handling damage??";
break;
2658 case 0xf: msgstat =
"Self-test routine in progress";
break;
2659 default: msgstat =
strprintf(
"Unknown status (0x%x)", test_status >> 4);
2664 print_header =
false;
2665 jout(
"Num Test_Description Status Remaining LifeTime(hours) LBA_of_first_error\n");
2669 if (retval < 0 && failing_lba < 0xffffffffffffULL)
2670 snprintf(msglba,
sizeof(msglba),
"%" PRIu64, failing_lba);
2672 msglba[0] =
'-'; msglba[1] = 0;
2675 jout(
"#%2u %-19s %-29s %1d0%% %8u %s\n", testnum,
2676 msgtest.c_str(), msgstat.c_str(), test_status & 0x0f, timestamp, msglba);
2678 jref[
"type"][
"value"] = test_type;
2679 jref[
"type"][
"string"] = msgtest;
2681 jref[
"status"][
"value"] = test_status;
2682 jref[
"status"][
"string"] = msgstat;
2683 if (test_status & 0x0f)
2684 jref[
"status"][
"remaining_percent"] = (test_status & 0x0f) * 10;
2685 switch (test_status >> 4) {
2686 case 0x1:
case 0x2:
case 0x3:
break;
2687 default: jref[
"status"][
"passed"] = (retval >= 0);
2690 jref[
"lifetime_hours"] = timestamp;
2692 if (retval < 0 && failing_lba < 0xffffffffffffULL)
2693 jref[
"lba"] = failing_lba;
2702 json::ref jref =
jglb[
"ata_smart_self_test_log"][
"standard"];
2705 jout(
"SMART Self-test log structure revision number %d\n", log->
revnumber);
2708 pout(
"Warning: ATA Specification requires self-test log structure revision number = 1\n");
2711 jout(
"No self-tests have been logged. [To run self-tests, use: smartctl -t]\n");
2716 bool noheaderprinted =
true;
2717 int errcnt = 0, igncnt = 0;
2718 int testnum = 1, ext_ok_testnum = -1;
2721 for (
int i = 20, ji = 0; i >= 0; i--) {
2730 uint64_t lba48 = (
entry.lbafirstfailure < 0xffffffff ?
2731 entry.lbafirstfailure : 0xffffffffffffULL);
2735 testnum,
entry.selftestnumber,
entry.selfteststatus,
2736 entry.timestamp, lba48, !allentries, noheaderprinted);
2740 if (ext_ok_testnum < 0)
2746 else if (state > 0 && ext_ok_testnum < 0) {
2748 ext_ok_testnum = testnum;
2754 jout(
"%d of %d failed self-tests are outdated by newer successful extended offline self-test #%2d\n",
2755 igncnt, igncnt+errcnt, ext_ok_testnum);
2756 jref[
"count"] = testnum - 1;
2757 jref[
"error_count_total"] = igncnt + errcnt;
2758 jref[
"error_count_outdated"] = igncnt;
2760 if (!allentries && !noheaderprinted)
2768 unsigned nsectors,
unsigned max_entries)
2770 json::ref jref =
jglb[
"ata_smart_self_test_log"][
"extended"];
2772 jout(
"SMART Extended Self-test Log Version: %u (%u sectors)\n",
2774 jref[
"revision"] = log->
version;
2775 jref[
"sectors"] = nsectors;
2778 jout(
"No self-tests have been logged. [To run self-tests, use: smartctl -t]\n\n");
2784 unsigned nentries = nsectors * 19;
2786 if (logidx > nentries) {
2787 pout(
"Invalid Self-test Log index = 0x%04x (reserved = 0x%02x)\n", logidx, log->
reserved1);
2795 bool print_header =
true;
2796 int errcnt = 0, igncnt = 0;
2797 int ext_ok_testnum = -1;
2798 unsigned testnum = 1;
2801 for (
unsigned i = 0, ji = 0; i < nentries && testnum <= max_entries;
2802 i++, logidx = (logidx > 0 ? logidx - 1 : nentries - 1)) {
2811 const unsigned char *
b =
entry.failing_lba;
2812 uint64_t lba48 =
b[0]
2815 | ((uint64_t)
b[3] << 24)
2816 | ((uint64_t)
b[4] << 32)
2817 | ((uint64_t)
b[5] << 40);
2821 testnum,
entry.self_test_type,
2822 entry.self_test_status,
entry.timestamp, lba48,
2823 false , print_header);
2827 if (ext_ok_testnum < 0)
2833 else if (state > 0 && ext_ok_testnum < 0) {
2835 ext_ok_testnum = testnum;
2841 jout(
"%d of %d failed self-tests are outdated by newer successful extended offline self-test #%2d\n",
2842 igncnt, igncnt+errcnt, ext_ok_testnum);
2843 jref[
"count"] = testnum - 1;
2844 jref[
"error_count_total"] = igncnt + errcnt;
2845 jref[
"error_count_outdated"] = igncnt;
2856 jout(
"SMART Selective self-test log data structure revision number %d\n", log->
logversion);
2859 pout(
"Note: revision number not 1 implies that no selective self-test has ever been run\n");
2863 case 0:msg=
"Completed";
2865 case 1:msg=
"Aborted_by_host";
2867 case 2:msg=
"Interrupted";
2869 case 3:msg=
"Fatal_error";
2871 case 4:msg=
"Completed_unknown_failure";
2873 case 5:msg=
"Completed_electrical_failure";
2875 case 6:msg=
"Completed_servo/seek_failure";
2877 case 7:msg=
"Completed_read_failure";
2879 case 8:msg=
"Completed_handling_damage??";
2881 case 15:msg=
"Self_test_in_progress";
2883 default:msg=
"Unknown_status ";
2889 uint64_t maxl = 0, maxr = 0;
2891 uint64_t currentend = current + 0xffff;
2896 for (
int i = 0; i < 5; i++) {
2898 uint64_t end =log->
span[i].
end;
2910 if ((field1=snprintf(tmp,64,
"%" PRIu64, maxl))<7)
2912 if ((field2=snprintf(tmp,64,
"%" PRIu64, maxr))<7)
2916 jout(
" SPAN %*s %*s CURRENT_TEST_STATUS\n", field1,
"MIN_LBA", field2,
"MAX_LBA");
2918 for (
int i = 0; i < 5; i++) {
2920 uint64_t end=log->
span[i].
end;
2925 jout(
" %d %*" PRIu64
" %*" PRIu64
" %s [%01d0%% left] (%" PRIu64
"-%" PRIu64
")\n",
2926 i + 1, field1, start, field2, end, msg,
2930 jout(
" %d %*" PRIu64
" %*" PRIu64
" Not_testing\n",
2931 i + 1, field1, start, field2, end);
2934 jrefi[
"lba_min"] = start;
2935 jrefi[
"lba_max"] = end;
2937 jrefi[
"status"][
"string"] = (active ? msg :
"Not_testing");
2940 jrefi[
"current_lba_min"] = current;
2941 jrefi[
"current_lba_max"] = currentend;
2949 jout(
"%5d %*" PRIu64
" %*" PRIu64
" Read_scanning %s\n",
2950 log->
currentspan, field1, current, field2, currentend, ost);
2951 json::ref jrefc = jref[
"current_read_scan"];
2952 jrefc[
"lba_min"] = current;
2953 jrefc[
"lba_max"] = currentend;
2955 jrefc[
"status"][
"string"] = ost;
2969 jout(
"Selective self-test flags (0x%x):\n", (
unsigned)log->
flags);
2971 jreff[
"value"] = log->
flags;
2975 jout(
" Currently read-scanning the remainder of the disk.\n");
2977 jout(
" Read-scan of remainder of disk interrupted; will resume %d min after power-up.\n",
2980 jout(
" After scanning selected spans, read-scan remainder of disk.\n");
2985 jout(
" After scanning selected spans, do NOT read-scan remainder of disk.\n");
2988 jout(
"If Selective self-test is pending on power-up, resume after %d minute delay.\n",
2990 jref[
"power_up_scan_resume_minutes"] = log->
pendingtime;
2994static const char *
sct_ptemp(
signed char x,
char (& buf)[20])
2998 snprintf(buf,
sizeof(buf),
"%2d", x);
3006 jglb[
"temperature"][name] = x;
3007 jref[
"temperature"][name] = x;
3021 memset(buf,
'*', x);
3027 buf[0] =
'-'; buf[1] = 0;
3035 case 0:
return "Active";
3036 case 1:
return "Stand-by";
3037 case 2:
return "Sleep";
3038 case 3:
return "DST executing in background";
3039 case 4:
return "SMART Off-line Data Collection executing in background";
3040 case 5:
return "SCT command executing in background";
3041 default:
return "Unknown";
3061 jref[
"device_state"][
"string"] = statestr;
3075 char buf1[20], buf2[20];
3076 jout(
"Current Temperature: %s Celsius\n",
3079 jout(
"Power Cycle Min/Max Temperature: %s/%s Celsius\n",
3085 jout(
"Lifetime Min/Max Temperature: %s/%s Celsius\n",
3095 jout(
"Specified Max Operating Temperature: %3d Celsius\n", sts->
max_op_limit);
3098 jout(
"Under/Over Temperature Limit Count: %2u/%u\n",
3107 (passed == 0 ?
"FAILED" : passed > 0 ?
"PASSED" :
"Reserved"));
3109 jref[
"smart_status"][
"passed"] = !!passed;
3110 jglb[
"smart_status"][
"passed"] = !!passed;
3113 jref[
"smart_status"][
"reserved_value"] = sts->
smart_status;
3117 pout(
"Minimum supported ERC Time Limit: %d (%0.1f seconds)\n",
3121 jout(
"Vendor specific:\n");
3135 char buf1[20], buf2[20], buf3[64];
3139 jout(
"Temperature Sampling Period: %u minute%s\n",
3142 jout(
"Temperature Logging Interval: %u minute%s\n",
3144 jref[
"logging_interval_minutes"] = tmh->
interval;
3146 jout(
"Min/Max recommended Temperature: %s/%s Celsius\n",
3150 jout(
"Min/Max Temperature Limit: %s/%s Celsius\n",
3160 pout(
"Temperature History is empty\n");
3162 pout(
"Invalid Temperature History Size or Index\n");
3167 jout(
"\nIndex Estimated Time Temperature Celsius\n");
3170 time_t t = time(0) - (time_t)(tmh->
cb_size-1) * interval * 60;
3171 t -= t % (interval * 60);
3172 while (n < tmh->cb_size) {
3174 unsigned n1 = n, n2 = n+1, i2 = (i+1) % tmh->
cb_size;
3175 while (n2 < tmh->cb_size && tmh->
cb[i2] == tmh->
cb[i]) {
3176 n2++; i2 = (i2+1) % tmh->
cb_size;
3180 if (n == n1 || n == n2-1 || n2 <= n1+3) {
3184 strftime(date,
sizeof(date),
"%Y-%m-%d %H:%M",
time_to_tm_local(&tmbuf, t));
3185 jout(
" %3u %s %s %s\n", i, date,
3188 else if (n == n1+1) {
3189 jout(
" ... ..(%3u skipped). .. %s\n",
3192 if (tmh->
cb[i] != -128)
3193 jref[
"table"][n] = tmh->
cb[i];
3194 t += interval * 60; i = (i+1) % tmh->
cb_size; n++;
3205 const char* power_on_str = (power_on ?
"Power-on " :
"");
3207 jout(
"SCT Error Recovery Control%s:%s\n", (set ?
" set to" :
""), (mfg_default ?
" default values." :
""));
3210 jref[
"read"][
"enabled"] = !!read_timer;
3212 jout(
" %sRead: Disabled\n", power_on_str);
3214 jout(
" %sRead: %6d (%0.1f seconds)\n", power_on_str, read_timer, read_timer/10.0);
3215 jref[
"read"][
"deciseconds"] = read_timer;
3218 jref[
"write"][
"enabled"] = !!write_timer;
3220 jout(
" %sWrite: Disabled\n", power_on_str);
3222 jout(
" %sWrite: %6d (%0.1f seconds)\n", power_on_str, write_timer, write_timer/10.0);
3223 jref[
"write"][
"deciseconds"] = write_timer;
3234 s =
"vendor specific";
3235 else if (level < 128)
3236 s =
"unknown/retired";
3237 else if (level == 128)
3239 else if (level < 254)
3241 else if (level == 254)
3242 s =
"maximum performance";
3246 if (recommended >= 0)
3247 jout(
"%s%d (%s), recommended: %d\n", msg, level,
s, recommended);
3249 jout(
"%s%d (%s)\n", msg, level,
s);
3252 jref[
"enabled"] =
true;
3253 jref[
"level"] = level;
3255 if (recommended >= 0)
3256 jref[
"recommended_level"] = recommended;
3263 if (!(1 <= level && level <= 254))
3265 else if (level == 1)
3266 s =
"minimum power consumption with standby";
3267 else if (level < 128)
3268 s =
"intermediate level with standby";
3269 else if (level == 128)
3270 s =
"minimum power consumption without standby";
3271 else if (level < 254)
3272 s =
"intermediate level without standby";
3274 s =
"maximum performance";
3276 jout(
"%s%d (%s)\n", msg, level,
s);
3279 jref[
"enabled"] =
true;
3280 jref[
"level"] = level;
3282 if (1 <= level && level <= 254) {
3283 jref[
"max_performance"] = (level == 254);
3284 jref[
"min_power"] = (level == 1 || level == 128);
3285 jref[
"with_standby"] = (level < 128);
3292 if (!(state & 0x0001)) {
3293 pout(
"%sUnavailable\n", msg);
3297 const char * s1, * s2 =
"", * s3 =
"", * s4 =
"";
3298 bool enabled =
false, locked =
false;
3299 if (!(state & 0x0002)) {
3301 if (!(state & 0x0008))
3302 s2 =
"NOT FROZEN [SEC1]";
3304 s2 =
"frozen [SEC2]";
3308 s1 =
"ENABLED, PW level ";
3309 if (!(state & 0x0100))
3314 if (!(state & 0x0004)) {
3315 s3 =
", not locked, ";
3316 if (!(state & 0x0008))
3317 s4 =
"not frozen [SEC5]";
3319 s4 =
"frozen [SEC6]";
3323 s3 =
", **LOCKED** [SEC4]";
3325 s4 =
", PW ATTEMPTS EXCEEDED";
3332 if (0x0000 < master_password_id && master_password_id < 0xfffe)
3333 snprintf(s5,
sizeof(s5),
", Master PW ID: 0x%04x", master_password_id);
3335 jout(
"%s%s%s%s%s%s\n", msg, s1, s2, s3, s4, s5);
3338 jref[
"state"] = state;
3339 jref[
"string"] =
strprintf(
"%s%s%s%s", s1, s2, s3, s4);
3340 jref[
"enabled"] = enabled;
3341 if (!enabled || !locked)
3342 jref[
"frozen"] = !!(state & 0x0008);
3344 jref[
"pw_level_max"] = !!(state & 0x0100);
3345 jref[
"locked"] = locked;
3347 jref[
"pw_attempts_exceeded"] = !!(state & 0x0010);
3349 jref[
"master_password_id"] = master_password_id;
3354 const char * s1 = 0;
3355 int hours = 0, minutes = 0 , seconds = 0;
3360 else if (timer <= 240)
3361 seconds = timer * 5, minutes = seconds / 60, seconds %= 60;
3362 else if (timer <= 251)
3363 minutes = (timer - 240) * 30, hours = minutes / 60, minutes %= 60;
3364 else if (timer == 252)
3366 else if (timer == 253)
3367 s1 =
"between 8 hours and 12 hours";
3368 else if (timer == 255)
3369 minutes = 21, seconds = 15;
3373 const char * s2 =
"", * s3 =
"";
3375 s2 =
" or vendor-specific";
3376 if (timer > 0 && (drive.
words047_079[50-47] & 0xc001) == 0x4001)
3377 s3 =
", a vendor-specific minimum applies";
3380 pout(
"%s%d (%s%s%s)\n", msg, timer, s1, s2, s3);
3382 pout(
"%s%d (%02d:%02d:%02d%s%s)\n", msg, timer, hours, minutes, seconds, s2, s3);
3389 const char * powername = 0;
3390 bool powerchg =
false;
3392 unsigned char powerlimit = 0xff;
3395 switch (powermode) {
3402 jinf(
"CHECK POWER MODE not implemented, ignoring -n option\n");
break;
3404 powername =
"SLEEP"; powerlimit = 2;
3409 powername =
"STANDBY"; powerlimit = 3;
break;
3411 powername =
"STANDBY_Y"; powerlimit = 3;
break;
3413 powername =
"IDLE"; powerlimit = 4;
break;
3415 powername =
"IDLE_A"; powerlimit = 4;
break;
3417 powername =
"IDLE_B"; powerlimit = 4;
break;
3419 powername =
"IDLE_C"; powerlimit = 4;
break;
3422 powername =
"ACTIVE_NV_DOWN";
break;
3424 powername =
"ACTIVE_NV_UP" ;
break;
3426 powername =
"ACTIVE or IDLE";
break;
3430 jinf(
"CHECK POWER MODE returned unknown value 0x%02x, exit(%d)\n", powermode,
3434 jinf(
"CHECK POWER MODE returned unknown value 0x%02x, ignoring -n option\n", powermode);
3439 jinf(
"Device is in %s mode, exit(%d)\n", powername, options.
powerexit);
3442 powerchg = (powermode != 0xff);
3447 bool need_smart_val = (
3462 bool need_smart_enabled = (
3469 bool need_smart_support = (
3476 bool need_smart_logdir = (
3483 bool need_gp_logdir = (
3497 need_gp_logdir =
true;
3499 need_smart_logdir =
true;
3503 bool need_sct_support = (
3517 bool not_part_of_a_option = (
3530 || need_smart_support
3531 || not_part_of_a_option)) {
3533 pout(
"Device is in %s mode\n", powername);
3535 pout(
"ATA device successfully opened\n\n"
3536 "Use 'smartctl -a' (or '-x') to print SMART (and more) information\n\n");
3543 unsigned char raw_drive[
sizeof(drive)]; memset(&raw_drive, 0,
sizeof(raw_drive));
3548 pout(
"Read Device Identity failed: %s\n\n",
3550 pout(
"If this is a USB connected device, look at the various "
3551 "--device=TYPE variants\n");
3554 else if (!
nonempty(&drive,
sizeof(drive))) {
3555 pout(
"Read Device Identity failed: empty IDENTIFY data\n\n");
3568 std::string dbversion;
3572 firmwarebugs, dbversion);
3573 if (!dbversion.empty())
3574 jglb[
"smartctl"][
"drive_database_version"][
"string"] = dbversion;
3584 pout(
"=== ATA IDENTIFY DATA ===\n");
3591 pout(
"=== START OF INFORMATION SECTION ===\n");
3596 int smart_supported = -1, smart_enabled = -1;
3597 if (need_smart_support || options.
drive_info) {
3601 pout(
"SMART support is: Unavailable - Packet Interface Devices [this device: %s] don't support ATA SMART\n",
3609 if (smart_supported < 0)
3610 pout(
"SMART support is: Ambiguous - ATA IDENTIFY DEVICE words 82-83 don't show if SMART supported.\n");
3611 if (smart_supported && smart_enabled < 0) {
3612 pout(
"SMART support is: Ambiguous - ATA IDENTIFY DEVICE words 85-87 don't show if SMART is enabled.\n");
3613 if (need_smart_support) {
3616 pout(
" Checking to be sure by trying SMART RETURN STATUS command.\n");
3618 smart_supported = smart_enabled = 1;
3621 else if (smart_supported < 0 && (smart_enabled > 0 || dbentry))
3623 smart_supported = 1;
3625 if (smart_supported < 0)
3626 pout(
"SMART support is: Unknown - Try option -s with argument 'on' to enable it.");
3627 else if (!smart_supported)
3628 jout(
"SMART support is: Unavailable - device lacks SMART capability.\n");
3631 jout(
"SMART support is: Available - device has SMART capability.\n");
3632 if (smart_enabled >= 0) {
3635 pout(
" %sabled status cached by OS, trying SMART RETURN STATUS cmd.\n",
3636 (smart_enabled?
"En":
"Dis"));
3640 jout(
"SMART support is: %s\n",
3641 (smart_enabled ?
"Enabled" :
"Disabled"));
3646 if (options.
drive_info || smart_supported <= 0) {
3647 jglb[
"smart_support"][
"available"] = (smart_supported > 0);
3648 if (smart_supported > 0)
3649 jglb[
"smart_support"][
"enabled"] = (smart_enabled > 0);
3656 pout(
"AAM feature is: Unavailable\n");
3657 else if (!(drive.
word086 & 0x0200)) {
3658 jout(
"AAM feature is: Disabled\n");
3659 jglb[
"ata_aam"][
"enabled"] =
false;
3669 pout(
"APM feature is: Unavailable\n");
3670 else if (!(drive.
word086 & 0x0008)) {
3671 jout(
"APM feature is: Disabled\n");
3672 jglb[
"ata_apm"][
"enabled"] =
false;
3682 pout(
"Rd look-ahead is: Unavailable\n");
3685 jout(
"Rd look-ahead is: %sabled\n", (enabled ?
"En" :
"Dis"));
3686 jglb[
"read_lookahead"][
"enabled"] = enabled;
3694 pout(
"Write cache is: Unavailable\n");
3697 jout(
"Write cache is: %sabled\n", (enabled ?
"En" :
"Dis"));
3698 jglb[
"write_cache"][
"enabled"] = enabled;
3707 || ((word119 & 0xc200) != 0x4200)
3708 || ((word120 & 0xc000) != 0x4000))
3709 pout(
"DSN feature is: Unavailable\n");
3711 bool enabled = !!(word120 & 0x200);
3712 jout(
"DSN feature is: %sabled\n", (enabled ?
"En" :
"Dis"));
3713 jglb[
"ata_dsn"][
"enabled"] = enabled;
3719 bool locked = ((word128 & 0x0007) == 0x0007);
3728 pout(
"Wt Cache Reorder: Unavailable\n");
3730 pout(
"Wt Cache Reorder: Unknown (SCT not supported if ATA Security is LOCKED)\n");
3733 false ,
false ,
false );
3735 if (-1 <= wcache_reorder && wcache_reorder <= 2)
3736 pout(
"Wt Cache Reorder: %s\n",
3737 (wcache_reorder == -1 ?
"Unknown (SCT Feature Control command failed)" :
3738 wcache_reorder == 0 ?
"Unknown" :
3739 wcache_reorder == 1 ?
"Enabled" :
"Disabled"));
3741 pout(
"Wt Cache Reorder: Unknown (0x%02x)\n", wcache_reorder);
3745 const char * sct_write_cache_state_desc[4] = {
3747 "Controlled by ATA",
3755 pout(
"SCT Write Cache Control: Unavailable\n");
3757 pout(
"SCT Write Cache Control: Unknown (SCT not supported if ATA Security is LOCKED)\n");
3760 if (-1 <= state && state <= 3)
3761 pout(
"SCT Write Cache Control: %s\n",
3762 (state == -1 ?
"Unknown (SCT Feature Control command failed)" :
3763 sct_write_cache_state_desc[state]));
3765 pout(
"SCT Write Cache Control: Unknown (0x%02x)\n", state);
3774 pout(
"Power mode %s %s\n", (powerchg?
"was:":
"is: "), powername);
3779 if (smart_supported <= 0 && need_smart_support)
3789 pout(
"=== START OF ENABLE/DISABLE COMMANDS SECTION ===\n");
3807 pout(
"AAM disabled\n");
3827 pout(
"APM disabled\n");
3835 pout(
"Read look-ahead %sable failed: %s\n", (enable ?
"en" :
"dis"), device->
get_errmsg());
3839 pout(
"Read look-ahead %sabled\n", (enable ?
"en" :
"dis"));
3846 pout(
"Write cache %sable failed: %s\n", (enable ?
"en" :
"dis"), device->
get_errmsg());
3850 pout(
"Write cache %sabled\n", (enable ?
"en" :
"dis"));
3855 bool enable = (options.
set_dsn > 0);
3857 pout(
"DSN %sable failed: %s\n", (enable ?
"en" :
"dis"), device->
get_errmsg());
3861 pout(
"DSN %sabled\n", (enable ?
"en" :
"dis"));
3868 pout(
"Write cache reordering %sable failed: SCT Feature Control command not supported\n",
3869 (enable ?
"en" :
"dis"));
3871 pout(
"Write cache reordering %sable failed: SCT not supported if ATA Security is LOCKED\n",
3872 (enable ?
"en" :
"dis"));
3875 pout(
"Write cache reordering %sable failed: %s\n", (enable ?
"en" :
"dis"), device->
get_errmsg());
3879 pout(
"Write cache reordering %sabled (%s)\n", (enable ?
"en" :
"dis"),
3886 pout(
"SCT Feature Control of write cache failed: SCT Feature Control command not supported\n");
3888 pout(
"SCT Feature Control of write cache failed: SCT not supported if ATA Security is LOCKED\n");
3891 pout(
"SCT Feature Control of write cache failed: %s\n", device->
get_errmsg());
3895 pout(
"Write cache SCT Feature Control is set to: %s (%s)\n",
3903 pout(
"ATA SECURITY FREEZE LOCK failed: %s\n", device->
get_errmsg());
3907 pout(
"ATA Security set to frozen mode\n");
3927 pout(
"SMART Enabled.\n");
3942 pout(
"SMART Disabled. Use option -s with argument 'on' to enable it.\n");
3944 pout(
"(override with '-T permissive' option)\n");
3951 pout(
"SMART Enable Attribute Autosave failed: %s\n\n", device->
get_errmsg());
3955 pout(
"SMART Attribute Autosave Enabled.\n");
3960 pout(
"SMART Disable Attribute Autosave failed: %s\n\n", device->
get_errmsg());
3964 pout(
"SMART Attribute Autosave Disabled.\n");
3970 bool smart_val_ok =
false, smart_thres_ok =
false;
3972 if (need_smart_val) {
3978 smart_val_ok =
true;
3982 pout(
"Read SMART Thresholds failed: %s\n\n", device->
get_errmsg());
3986 smart_thres_ok =
true;
3992 bool needupdate =
false;
3995 pout(
"SMART Automatic Timers not supported\n\n");
3998 needupdate = smart_val_ok;
4000 pout(
"SMART Enable Automatic Offline failed: %s\n\n", device->
get_errmsg());
4004 pout(
"SMART Automatic Offline Testing Enabled every four hours.\n");
4009 pout(
"SMART Automatic Timers not supported\n\n");
4012 needupdate = smart_val_ok;
4014 pout(
"SMART Disable Automatic Offline failed: %s\n\n", device->
get_errmsg());
4018 pout(
"SMART Automatic Offline Testing Disabled.\n");
4024 smart_val_ok =
false;
4042 pout(
"=== START OF READ SMART DATA SECTION ===\n");
4051 jout(
"SMART overall-health self-assessment test result: PASSED\n");
4052 jglb[
"smart_status"][
"passed"] =
true;
4053 if (smart_thres_ok &&
find_failed_attr(&smartval, &smartthres, attribute_defs, 0)) {
4055 pout(
"See vendor-specific Attribute list for marginal Attributes.\n\n");
4058 pout(
"Please note the following marginal Attributes:\n");
4070 jout(
"SMART overall-health self-assessment test result: FAILED!\n"
4071 "Drive failure expected in less than 24 hours. SAVE ALL DATA.\n");
4072 jglb[
"smart_status"][
"passed"] =
false;
4074 if (smart_thres_ok &&
find_failed_attr(&smartval, &smartthres, attribute_defs, 1)) {
4077 pout(
"See vendor-specific Attribute list for failed Attributes.\n\n");
4080 pout(
"Failed Attributes:\n");
4085 pout(
"No failed Attributes found.\n\n");
4096 pout(
"SMART Status %s: %s\n",
4103 if (!(smart_val_ok && smart_thres_ok)) {
4105 pout(
"SMART overall-health self-assessment test result: UNKNOWN!\n"
4106 "SMART Status, Attributes and Thresholds cannot be read.\n\n");
4110 jout(
"SMART overall-health self-assessment test result: FAILED!\n"
4111 "Drive failure expected in less than 24 hours. SAVE ALL DATA.\n");
4112 jwrn(
"Warning: This result is based on an Attribute check.\n");
4113 jglb[
"smart_status"][
"passed"] =
false;
4118 pout(
"See vendor-specific Attribute list for failed Attributes.\n\n");
4121 pout(
"Failed Attributes:\n");
4126 jout(
"SMART overall-health self-assessment test result: PASSED\n");
4127 jwrn(
"Warning: This result is based on an Attribute check.\n");
4128 jglb[
"smart_status"][
"passed"] =
true;
4131 pout(
"See vendor-specific Attribute list for marginal Attributes.\n\n");
4134 pout(
"Please note the following marginal Attributes:\n");
4164 if ( gp_log_supported
4167 need_smart_logdir =
true;
4173 if (need_smart_logdir) {
4175 smartlogdir =
fake_logdir(&smartlogdir_buf, options);
4177 pout(
"Read SMART Log Directory failed: %s\n\n", device->
get_errmsg());
4181 smartlogdir = &smartlogdir_buf;
4185 if (need_gp_logdir) {
4190 pout(
"General Purpose Log Directory not supported\n\n");
4193 pout(
"Read GP Log Directory failed\n\n");
4197 gplogdir = &gplogdir_buf;
4203 pout(
"Log Directories not read due to '-F nologdir' option\n\n");
4213 unsigned max_nsectors;
4215 type =
"General Purpose";
4223 if (!max_nsectors) {
4225 pout(
"%s Log 0x%02x does not exist (override with '-T permissive' option)\n", type, req.
logaddr);
4228 max_nsectors = req.
page+1;
4230 if (max_nsectors <= req.
page) {
4231 pout(
"%s Log 0x%02x has only %u sectors, output skipped\n", type, req.
logaddr, max_nsectors);
4236 if (ns > max_nsectors - req.
page) {
4238 pout(
"%s Log 0x%02x has only %u sectors, output truncated\n", type, req.
logaddr, max_nsectors);
4239 ns = max_nsectors - req.
page;
4243 unsigned offs = (req.
gpl ? 0 : req.
page);
4263 pout(
"SMART Extended Comprehensive Error Log (GP Log 0x03) not supported\n\n");
4269 pout(
"Read SMART Extended Comprehensive Error Log failed\n\n");
4281 do_smart_error_log =
true;
4282 else if (!do_smart_error_log)
4283 pout(
"Try '-l [xerror,]error' to read traditional SMART Error Log\n");
4288 if (do_smart_error_log) {
4290 || ( !(smartlogdir && gp_log_supported)
4293 pout(
"SMART Error Log not supported\n\n");
4298 pout(
"Read SMART Error Log failed: %s\n\n", device->
get_errmsg());
4316 pout(
"SMART Extended Self-test Log (GP Log 0x07) not supported\n\n");
4317 else if (nsectors >= 256)
4318 pout(
"SMART Extended Self-test Log size %u not supported\n\n", nsectors);
4323 pout(
"Read SMART Extended Self-test Log failed\n\n");
4335 do_smart_selftest_log =
true;
4336 else if (!do_smart_selftest_log)
4337 pout(
"Try '-l [xselftest,]selftest' to read traditional SMART Self Test Log\n");
4342 if (do_smart_selftest_log) {
4344 || ( !(smartlogdir && gp_log_supported)
4347 pout(
"SMART Self-test Log not supported\n\n");
4352 pout(
"Read SMART Self-test Log failed: %s\n\n", device->
get_errmsg());
4370 pout(
"Selective Self-tests/Logging not supported\n\n");
4372 pout(
"Read SMART Selective Self-test Log failed: %s\n\n", device->
get_errmsg());
4392 pout(
"SCT Commands not supported\n\n");
4394 pout(
"SCT Commands not supported if ATA Security is LOCKED\n\n");
4419 pout(
"SCT Data Table command not supported\n\n");
4429 pout(
"Read SCT Temperature History failed\n\n");
4440 pout(
"SCT Feature Control command not supported\n\n");
4445 pout(
"Write Temperature Logging Interval failed\n\n");
4449 pout(
"Temperature Logging Interval set to %u minute%s (%s)\n",
4460 pout(
"SCT Error Recovery Control command not supported\n\n");
4471 pout(
"SCT (Set) Error Recovery Control command failed\n");
4474 pout(
"Retry with: 'scterc,70,70' to enable ERC or 'scterc,0,0' to disable\n");
4478 else if (!sct_erc_get)
4485 bool get_power_on = (sct_erc_get == 2);
4486 unsigned short read_timer, write_timer;
4489 pout(
"SCT (Get) Error Recovery Control command failed\n");
4491 pout(
"The previous SCT (Set) Error Recovery Control command succeeded\n");
4506 bool use_gplog =
true;
4507 unsigned nsectors = 0;
4510 else if (smartlogdir){
4515 pout(
"Device Statistics (GP/SMART Log 0x04) not supported\n\n");
4525 pout(
"Pending Defects log (GP Log 0x0c) not supported\n\n");
4534 if (!nsectors && (drive.
words047_079[76-47] & 0x0401) == 0x0400)
4537 pout(
"SATA Phy Event Counters (GP Log 0x11) not supported\n\n");
4538 else if (nsectors != 1)
4539 pout(
"SATA Phy Event Counters with %u sectors not supported\n\n", nsectors);
4541 unsigned char log_11[512] = {0, };
4542 unsigned char features = (options.
sataphy_reset ? 0x01 : 0x00);
4544 pout(
"Read SATA Phy Event Counters failed\n\n");
4554 bool farm_supported =
true;
4561 jout(
"FARM log (GP Log 0xa6) not supported\n\n");
4563 farm_supported =
false;
4567 jout(
"Seagate FARM log (GP Log 0xa6) supported [try: -l farm]\n\n");
4572 pout(
"Read FARM log (GP Log 0xa6) failed\n\n");
4573 farm_supported =
false;
4582 jout(
"FARM log (GP Log 0xa6) not supported for non-Seagate drives\n\n");
4584 farm_supported =
false;
4586 jglb[
"seagate_farm_log"][
"supported"] = farm_supported;
4590 if (options.
a_option && !not_part_of_a_option)
4591 pout(
"The above only provides legacy SMART information - try 'smartctl -x' for more\n\n");
4603 pout(
"Device placed in STANDBY mode\n");
4608 pout(
"ATA STANDBY IMMEDIATE command failed: %s\n", device->
get_errmsg());
4612 pout(
"Device placed in STANDBY mode\n");
4620 pout(
"=== START OF OFFLINE IMMEDIATE AND SELF-TEST SECTION ===\n");
4625 pout(
"Execute Offline Immediate function not supported\n\n");
4635 pout(
"Self-test functions not supported\n\n");
4642 pout(
"Conveyance Self-test functions not supported\n\n");
4649 pout(
"Selective Self-test functions not supported\n\n");
4670 pout(
"Note: giving further SMART commands will abort Offline testing\n");
4680 time_t t=time(NULL);
4683 pout(
"Please wait %d seconds for test to complete.\n", (
int)timewait);
4686 pout(
"Please wait %d minutes for test to complete.\n", (
int)timewait);
4690 pout(
"Test will complete after %s\n", comptime);
4696 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 set_json_globals_from_smart_attrib(int id, const char *name, const ata_vendor_attr_defs &defs, uint8_t normval, uint8_t threshold, uint64_t rawval)
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 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.
Wrapper class for POSIX regex(3) or std::regex Supports copy & assignment and is compatible with STL ...
bool full_match(const char *str) const
Return true if full string matches pattern.
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)