15#define __STDC_FORMAT_MACROS 1
34#define GBUF_SIZE 65532
39#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
42#define LOG_RESP_LEN 252
43#define LOG_RESP_LONG_LEN ((62 * 256) + 252)
44#define LOG_RESP_TAPE_ALERT_LEN 0x144
47#define SCSI_SUPP_LOG_PAGES_MAX_COUNT (252 + (62 * 128) + 126)
87#define SCSI_VERSION_SPC_4 0x6
88#define SCSI_VERSION_SPC_5 0x7
89#define SCSI_VERSION_SPC_6 0xd
90#define SCSI_VERSION_HIGHEST SCSI_VERSION_SPC_6
95#define T10_VENDOR_SEAGATE "SEAGATE"
96#define T10_VENDOR_HITACHI_1 "HITACHI"
97#define T10_VENDOR_HITACHI_2 "HL-DT-ST"
98#define T10_VENDOR_HITACHI_3 "HGST"
102static const char *
gsap_s =
"General statistics and performance";
103static const char *
ssm_s =
"Solid state media";
104static const char *
zbds_s =
"Zoned block device statistics";
105static const char *
lp_s =
"log page";
124 if ((
nullptr == bp) || (b_len <= 0))
126 for (--b_len; b_len >= 0; --b_len) {
127 if (0xff != bp[b_len])
134static std::string
rtrim(
const std::string&
s,
const char* t =
" \t\n\r\f\v")
138 r.erase(r.find_last_not_of(t) + 1);
145 bool got_subpages =
false;
146 int k, err, resp_len, num_unreported, num_unreported_spg;
147 int supp_lpg_and_spg_count = 0;
154 memset(supp_lpg_and_spg, 0,
sizeof(supp_lpg_and_spg));
158 pout(
"%s: RSOC says %s not supported\n", __func__,
logSenStr);
172 pout(
"%s for supported pages failed (second attempt) [%s]\n",
182 for (k = 0; k < resp_len; k += 1) {
184 supp_lpg_and_spg[supp_lpg_and_spg_count++] = {
page_code, 0};
202 pout(
"%s for supported pages and subpages failed [%s]\n",
208 pout(
"%s: %s ignored subpage field, bad\n",
210 }
else if (! ((0x40 &
gBuf[0]) &&
213 pout(
"%s supported subpages is bad SPF=%u SUBPG=%u\n",
224 for (k = 0; k < resp_len; k += 2) {
233 num_unreported_spg = 0;
234 for (k = 0; k < supp_lpg_and_spg_count; k += 1) {
243 pout(
"%s: Strange Log page number: 0x0,0x%x\n",
271 ++num_unreported_spg;
284 ++num_unreported_spg;
310 ++num_unreported_spg;
350 ++num_unreported_spg;
359 ++num_unreported_spg;
365 pout(
"%s: number of unreported (standard) %ss: %d (sub-pages: %d)\n",
366 __func__,
lp_s, num_unreported, num_unreported_spg);
376 uint8_t currenttemp = 255;
377 uint8_t triptemp = 255;
384 ¤ttemp, &triptemp)) {
394 jout(
"SMART Health Status: %s [asc=%x, ascq=%x]\n", cp, asc, ascq);
396 jglb[
"smart_status"][
"passed"] =
false;
397 jglb[
"smart_status"][
"scsi"][
"asc"] = asc;
398 jglb[
"smart_status"][
"scsi"][
"ascq"] = ascq;
399 jglb[
"smart_status"][
"scsi"][
"ie_string"] = cp;
402 jout(
"SMART Health Status: OK\n");
403 jglb[
"smart_status"][
"passed"] =
true;
407 if (255 == currenttemp)
408 pout(
"Current Drive Temperature: <not available>\n");
410 jout(
"Current Drive Temperature: %d C\n", currenttemp);
411 jglb[
"temperature"][
"current"] = currenttemp;
414 pout(
"Drive Trip Temperature: <not available>\n");
416 jout(
"Drive Trip Temperature: %d C\n", triptemp);
417 jglb[
"temperature"][
"drive_trip"] = triptemp;
433 unsigned short pagelength;
434 unsigned short parametercode;
439 const char * pad = from_health ?
"" :
" ";
440 static const char *
const tapealert_s =
"scsi_tapealert";
450 if (
gBuf[0] != 0x2e) {
459 for (i = 4, m = 0; i < pagelength; i += 5, ++k, ++m) {
468 jout(
"%sTapeAlert Errors (C=Critical, W=Warning, "
469 "I=Informational):\n", pad);
470 jout(
"%s[0x%02x] %s\n", pad, parametercode, ts);
471 jref[j][
"descriptor_idx"] = m + 1;
472 jref[j][
"parameter_code"] = parametercode;
473 jref[j][
"string"] = ts;
483 jout(
"%sTapeAlert: OK\n", pad);
484 jglb[tapealert_s][
"status"] =
"Good";
493 int err, len, k, extra;
498 static const char * jname =
"scsi_start_stop_cycle_counter";
515 for (k = len; k > 0; k -= extra, ucp += extra) {
525 bool is_all_ffs = (extra > 7) ?
all_ffs(ucp + 4, 4) :
false;
529 jout(
"Manufactured in week %.2s of year %.4s\n", ucp + 8,
531 snprintf(
b,
sizeof(
b),
"%.4s", ucp + 4);
532 jglb[jname][
"year_of_manufacture"] =
b;
533 snprintf(
b,
sizeof(
b),
"%.2s", ucp + 8);
534 jglb[jname][
"week_of_manufacture"] =
b;
541 if ((extra > 7) && (! is_all_ffs)) {
542 q =
"Specified cycle count over device lifetime";
543 jout(
"%s: %u\n", q, u);
548 if ((extra > 7) && (! is_all_ffs)) {
549 q =
"Accumulated start-stop cycles";
550 jout(
"%s: %u\n", q, u);
555 if ((extra > 7) && (! is_all_ffs)) {
556 q =
"Specified load-unload count over device lifetime";
557 jout(
"%s: %u\n", q, u);
562 if ((extra > 7) && (! is_all_ffs)) {
563 q =
"Accumulated load-unload cycles";
564 jout(
"%s: %u\n", q, u);
578 static const char * pDefStr =
"Pending Defects";
579 static const char * jname =
"scsi_pending_defects";
604 const uint8_t * bp =
gBuf + 4;
613 jout(
" Pending defect count:");
614 if ((pl < 8) || (num < 8)) {
616 pout(
"%s truncated descriptor\n", pDefStr);
623 jout(
"0 %s\n", pDefStr);
625 jout(
"1 Pending Defect, LBA and accumulated_power_on_hours "
628 jout(
"%u %s: index, LBA and accumulated_power_on_hours "
629 "follow\n",
count, pDefStr);
632 if ((pl < 16) || (num < 16)) {
634 pout(
"%s truncated descriptor\n", pDefStr);
640 jout(
" %4d: 0x%-16" PRIx64
", %5u\n", pc, lba, poh);
645 jref[
"accum_power_on_hours"] = poh;
659 unsigned int dl_len, div;
660 static const char * hname =
"Read defect list";
667 got_rd12 = (0 == err);
693 }
else if (101 == err)
711 pout(
"%s (12): generation=%d\n", hname, generation);
717 if (0x8 != (
gBuf[1] & 0x18)) {
719 pout(
"%s: asked for grown list but didn't get it\n", hname);
724 dl_format = (
gBuf[1] & 0x7);
743 pout(
"defect list format %d unknown\n", dl_format);
748 jout(
"Elements in grown defect list: 0\n\n");
749 jglb[
"scsi_grown_defect_list"] = 0;
753 pout(
"Grown defect list length=%u bytes [unknown "
754 "number of elements]\n\n", dl_len);
756 jout(
"Elements in grown defect list: %u\n\n", dl_len / div);
757 jglb[
"scsi_grown_defect_list"] = dl_len / div;
765 static const size_t sz_u64 = (int)
sizeof(uint64_t);
766 unsigned int u = ucp[3];
767 const unsigned char * xp = ucp + 4;
779 int num, pl, pc, err, len;
781 static const char * seaCacStr =
"Seagate Cache";
808 case 0:
case 1:
case 2:
case 3:
case 4:
813 pout(
"Vendor (%s) lpage has unexpected parameter, skip\n",
822 pout(
"Vendor (%s) information\n", seaCacStr);
829 case 0:
pout(
" Blocks sent to initiator");
break;
830 case 1:
pout(
" Blocks received from initiator");
break;
831 case 2:
pout(
" Blocks read from cache and sent to initiator");
break;
832 case 3:
pout(
" Number of read and write commands whose size "
833 "<= segment size");
break;
834 case 4:
pout(
" Number of read and write commands whose size "
835 "> segment size");
break;
836 default:
pout(
" Unknown Seagate parameter code [0x%x]", pc);
break;
848 int num, pl, pc, len, err, good, bad;
888 if ((good < 2) || (bad > 4)) {
891 pout(
"\nVendor (Seagate/Hitachi) factory lpage has too many "
892 "unexpected parameters, skip\n");
897 pout(
"Vendor (Seagate/Hitachi) factory information\n");
905 case 0:
jout(
" number of hours powered up");
908 case 8:
pout(
" number of minutes until next internal SMART test");
914 pout(
"Vendor (Seagate/Hitachi) factory lpage: "
915 "unknown parameter code [0x%x]\n", pc);
923 jout(
" = %.2f\n", ull / 60.0 );
924 jglb[
"power_on_time"][
"hours"] = ull / 60;
925 jglb[
"power_on_time"][
"minutes"] = ull % 60;
928 pout(
" = %" PRIu64
"\n", ull);
941 int found[3] = {0, 0, 0};
956 ecp = &errCounterArr[2];
957 for (
int k = 0; k < 7; ++k) {
964 if (found[0] || found[1] || found[2]) {
965 pout(
"Error counter log:\n");
966 pout(
" Errors Corrected by Total "
967 "Correction Gigabytes Total\n");
968 pout(
" ECC rereads/ errors "
969 "algorithm processed uncorrected\n");
970 pout(
" fast | delayed rewrites corrected "
971 "invocations [10^9 bytes] errors\n");
974 for (
int k = 0; k < 3; ++k) {
977 ecp = &errCounterArr[k];
978 static const char *
const pageNames[3] =
979 {
"read: ",
"write: ",
"verify: "};
980 static const char * jpageNames[3] =
981 {
"read",
"write",
"verify"};
982 jout(
"%s%8" PRIu64
" %8" PRIu64
" %8" PRIu64
" %8" PRIu64
983 " %8" PRIu64, pageNames[k], ecp->
counter[0],
986 double processed_gb = ecp->
counter[5] / 1000000000.0;
987 jout(
" %12.3f %8" PRIu64
"\n", processed_gb,
990 jref[jpageNames[k]][
"errors_corrected_by_eccfast"] = ecp->
counter[0];
991 jref[jpageNames[k]][
"errors_corrected_by_eccdelayed"] = ecp->
counter[1];
992 jref[jpageNames[k]][
"errors_corrected_by_rereads_rewrites"] = ecp->
counter[2];
993 jref[jpageNames[k]][
"total_errors_corrected"] = ecp->
counter[3];
994 jref[jpageNames[k]][
"correction_algorithm_invocations"] = ecp->
counter[4];
995 jref[jpageNames[k]][
"gigabytes_processed"] =
strprintf(
"%.3f", processed_gb);
996 jref[jpageNames[k]][
"total_uncorrected_errors"] = ecp->
counter[6];
1000 pout(
"Error Counter logging not supported\n");
1006 pout(
"\nNon-medium error count: %8" PRIu64
"\n", nme.
counterPC0);
1008 pout(
"Track following error count [Hitachi]: %8" PRIu64
"\n",
1011 pout(
"Positioning error count [Hitachi]: %8" PRIu64
"\n",
1021 unsigned char * ucp =
gBuf + 4;
1024 pout(
"\nNo error events logged\n");
1026 pout(
"\nLast n error events %s\n",
lp_s);
1027 for (
int k = num, pl; k > 0; k -= pl, ucp += pl) {
1029 pout(
" <<short Last n error events %s>>\n",
lp_s);
1035 if ((ucp[2] & 0x1) && (ucp[2] & 0x2)) {
1036 pout(
" Error event %d:\n", pc);
1037 pout(
" [binary]:\n");
1038 dStrHex((
const uint8_t *)ucp + 4, pl - 4, 1);
1039 }
else if (ucp[2] & 0x1) {
1040 pout(
" Error event %d:\n", pc);
1041 pout(
" %.*s\n", pl - 4, (
const char *)(ucp + 4));
1044 pout(
" Error event %d:\n", pc);
1045 pout(
" [data counter??]:\n");
1046 dStrHex((
const uint8_t *)ucp + 4, pl - 4, 1);
1052 pout(
" >>>> log truncated, fetched %d of %d available "
1072 "Aborted (by user command)",
1073 "Aborted (device reset ?) ",
1074 "Unknown error, incomplete",
1075 "Completed, segment failed",
1076 "Failed in first segment ",
1077 "Failed in second segment ",
1078 "Failed in segment",
1086 "Self test in progress ..."
1096 bool noheader =
true;
1097 int num, k, err, durationSec;
1101 static const char * hname =
"Self-test";
1102 static const char * fixup_stres7 =
" --> ";
1106 (sense_info.
asc == 0x04 && sense_info.
ascq == 0x09 &&
1108 pout(
"%s execution status:\t\t%d%% of test remaining\n", hname,
1109 100 - ((sense_info.
progress * 100) / 65535));
1130 pout(
"%s %s length is 0x%x not 0x190 bytes\n", hname,
logSenStr, num);
1135 for (k = 0, ucp =
gBuf + 4; k < 20; ++k, ucp += 20 ) {
1141 snprintf(st,
sizeof(st),
"scsi_self_test_%d", k);
1144 if ((0 == poh) && (0 == ucp[4]))
1149 jout(
"SMART %s log\n", hname);
1150 jout(
"Num Test Status segment "
1151 "LifeTime LBA_first_err [SK ASC ASQ]\n");
1152 jout(
" Description number "
1158 u = (ucp[4] >> 5) & 0x7;
1160 jglb[st][
"code"][
"value"] = u;
1197 jglb[st][
"result"][
"value"] = tr;
1209 jglb[st][
"failed_segment"][
"value"] = u;
1210 jglb[st][
"failed_segment"][
"aka"] =
"self_test_number";
1215 if (poh==0 && tr==0xf) {
1218 jglb[st][
"self_test_in_progress"] =
true;
1221 jglb[st][
"power_on_time"][
"hours"] = poh;
1222 jglb[st][
"power_on_time"][
"aka"] =
"accumulated_power_on_hours";
1227 bool is_all_ffs =
all_ffs(ucp + 8, 8);
1229 if ((! is_all_ffs) && (tr > 0) && (tr < 0xf)) {
1233 snprintf(buff,
sizeof(buff),
"%" PRIu64, ull);
1236 jglb[st][
"lba_first_failure"][
"value"] = ull;
1237 jglb[st][
"lba_first_failure"][
"aka"] =
"address_of_first_failure";
1243 if (ucp[16] & 0xf) {
1246 jout(
" [0x%x 0x%x 0x%x]\n", ucp[16] & 0xf, ucp[17], ucp[18]);
1248 jglb[st][
"sense_key"][
"value"] = u;
1249 jglb[st][
"sense_key"][
"string"] =
1251 jglb[st][
"asc"] = ucp[17];
1252 jglb[st][
"ascq"] = ucp[18];
1253 jglb[st][
"vendor_specific"] = ucp[19];
1260 jout(
"No %ss have been logged\n", hname);
1263 if (durationSec > 14400)
1264 jout(
"\nLong (extended) %s duration: %d seconds "
1265 "[%.1f hours]\n", hname, durationSec, durationSec / 3600.0);
1267 jout(
"\nLong (extended) %s duration: %d seconds "
1268 "[%.1f minutes]\n", hname, durationSec, durationSec / 60.0);
1269 jglb[
"scsi_extended_self_test_seconds"] = durationSec;
1278 "pre-scan is active",
1279 "halted due to fatal error",
1280 "halted due to a vendor specific pattern of error",
1281 "halted due to medium formatted without P-List",
1282 "halted - vendor specific cause",
1283 "halted due to temperature out of range",
1284 "waiting until BMS interval timer expires",
1289 "Require Write or Reassign Blocks command",
1290 "Successfully reassigned",
1292 "Reassignment by disk failed",
1293 "Recovered via rewrite in-place",
1294 "Reassigned by app, has valid data",
1295 "Reassigned by app, has no valid data",
1296 "Unsuccessfully reassigned by app",
1308 bool noheader =
true;
1309 bool firstresult =
true;
1310 int num, j, m, err, truncated;
1317 static const char * hname =
"Background scan results";
1318 static const char * jname =
"scsi_background_scan";
1336 if (! only_pow_time) {
1338 pout(
"%s %s length is %d, no scan status\n", hname,
logSenStr,
1352 int pl = ucp[3] + 4;
1357 if (! only_pow_time)
1358 jout(
"%s log\n", hname);
1360 if (! only_pow_time)
1362 if ((pl < 16) || (num < 16)) {
1363 if (! only_pow_time)
1368 if (! only_pow_time) {
1371 jglb[jname][
"status"][
"value"] = j;
1374 jout(
"unknown [0x%x] background scan status value\n", j);
1375 jglb[jname][
"status"][
"value"] = j;
1379 jout(
"%sAccumulated power on time, hours:minutes %d:%02d",
1380 (only_pow_time ?
"" :
" "), (j / 60), (j % 60));
1384 jout(
" [%d minutes]\n", j);
1385 jglb[
"power_on_time"][
"hours"] = j / 60;
1386 jglb[
"power_on_time"][
"minutes"] = j % 60;
1390 jout(
" Number of background scans performed: %u, ", u);
1391 jglb[jname][
"status"][
"number_scans_performed"] = u;
1393 snprintf(
b,
sizeof(
b),
"%.2f%%", (
double)u * 100.0 / 65536.0);
1394 jout(
"scan progress: %s\n",
b);
1395 jglb[jname][
"status"][
"scan_progress"] =
b;
1397 jout(
" Number of background medium scans performed: %d\n", u);
1398 jglb[jname][
"status"][
"number_medium_scans_performed"] = u;
1403 if (! only_pow_time)
1404 jout(
"\n%s log\n", hname);
1410 jout(
"\n # when lba(hex) [sk,asc,ascq] "
1411 "reassign_status\n");
1413 snprintf(res_s,
sizeof(res_s),
"result_%d", pc);
1415 jglb[jname][res_s][
"parameter_code"] = pc;
1416 if ((pl < 24) || (num < 24)) {
1418 jout(
"parameter length >= 24 expected, got %d\n", pl);
1422 jout(
"%4u:%02u ", (u / 60), (u % 60));
1423 jglb[jname][res_s][
"accumulated_power_on"][
"minutes"] = u;
1424 for (m = 0; m < 8; ++m)
1425 jout(
"%02x", ucp[16 + m]);
1427 jglb[jname][res_s][
"lba"] = lba;
1429 jout(
" [%x,%x,%x] ", u, ucp[9], ucp[10]);
1430 jglb[jname][res_s][
"sense_key"][
"value"] = u;
1431 jglb[jname][res_s][
"sense_key"][
"string"] =
1433 jglb[jname][res_s][
"asc"] = ucp[9];
1434 jglb[jname][res_s][
"ascq"] = ucp[10];
1435 u = (ucp[8] >> 4) & 0xf;
1438 jglb[jname][res_s][
"reassign_status"][
"value"] = u;
1439 jglb[jname][res_s][
"reassign_status"][
"string"] =
1442 jout(
"Reassign status: reserved [0x%x]\n", u);
1443 jglb[jname][res_s][
"reassign_status"][
"value"] = u;
1450 if (truncated && (! only_pow_time))
1451 jout(
" >>>> log truncated, fetched %d of %d available "
1454 if (! only_pow_time)
1463 uint16_t loop_pc, pl;
1464 uint32_t a_exp, a_int, casc;
1471 if (loop_pc == ti_pc) {
1475 pout(
"%s Time interval log parameter too short (pl=%d)\n",
1508 int64_t timeUnitInNS)
1510 if ((intervals > 0) && (timeUnitInNS > 0)) {
1511 intervals *= timeUnitInNS;
1512 intervals /= 1000000;
1513 jout(
"%*cin seconds: %" PRIu64
".%03" PRIu64
"\n",
1514 leadin_spaces,
' ', intervals / 1000, intervals % 1000);
1515 if (intervals > 3600000) {
1517 jout(
"%*cin hours: %" PRIu64
".%03" PRIu64
"\n",
1518 leadin_spaces,
' ', intervals / 1000, intervals % 1000);
1528 int num, err, truncated;
1530 int64_t timeUnitInNS;
1535 json::ref jref =
jglb[
"scsi_general_statistics_and_performance_log"];
1536 json::ref jref1 = jref[
"general_access"];
1538 json::ref jref3 = jref[
"time_interval"];
1540 static const char * p1name =
"General access statistics and performance";
1541 static const char * p2name =
"Idle time";
1542 static const char * p3name =
"Time interval";
1543 static const char * p4name =
"Force Unit Access statistics and "
1574 if (timeUnitInNS < 0) {
1577 pout(
"%s unable to decode time unit [%d]\n",
gsap_s,
1587 int pl = ucp[3] + 4;
1591 if (pl < 0x40 + 4) {
1593 pout(
"%s %s log parameter too short (pl=%d)\n",
gsap_s,
1598 jout(
" %s:\n", p1name);
1599 ccp =
"Number of read commands";
1601 jout(
" %s: %" PRIu64
"\n", ccp, ull);
1603 ccp =
"Number of write commands";
1605 jout(
" %s: %" PRIu64
"\n", ccp, ull);
1607 ccp =
"number of logical blocks received";
1609 jout(
" %s: %" PRIu64
"\n", ccp, ull);
1611 ccp =
"number of logical blocks transmitted";
1613 jout(
" %s: %" PRIu64
"\n", ccp, ull);
1615 ccp =
"read command processing intervals";
1617 jout(
" %s: %" PRIu64
"\n", ccp, ull);
1620 ccp =
"write command processing intervals";
1622 jout(
" %s: %" PRIu64
"\n", ccp, ull);
1625 ccp =
"weighted number of read commands plus write commands";
1627 jout(
" %s: %" PRIu64
"\n", ccp, ull);
1629 ccp =
"weighted read command processing plus write command "
1633 jout(
" %s: %" PRIu64
"\n", ccp, ull);
1639 pout(
"%s %s log parameter too short (pl=%d)\n",
gsap_s,
1644 jout(
" %s:\n", p2name);
1645 ccp =
"Idle time intervals";
1647 jout(
" %s: %" PRIu64
"\n", ccp, ull);
1655 pout(
"%s %s log parameter too short (pl=%d)\n",
gsap_s,
1668 if (pl < 0x40 + 4) {
1670 pout(
"%s %s log parameter too short (pl=%d)\n",
gsap_s,
1675 jout(
" %s:\n", p4name);
1676 ccp =
"Number of read FUA commands";
1678 jout(
" %s: %" PRIu64
"\n", ccp, ull);
1680 ccp =
"Number of write FUA commands";
1682 jout(
" %s: %" PRIu64
"\n", ccp, ull);
1684 ccp =
"Number of read FUA_NV commands";
1686 jout(
" %s: %" PRIu64
"\n", ccp, ull);
1688 ccp =
"Number of write FUA_NV commands";
1690 jout(
" %s: %" PRIu64
"\n", ccp, ull);
1692 ccp =
"Number of read FUA intervals";
1694 jout(
" %s: %" PRIu64
"\n", ccp, ull);
1697 ccp =
"Number of write FUA intervals";
1699 jout(
" %s: %" PRIu64
"\n", ccp, ull);
1701 ccp =
"Number of read FUA_NV intervals";
1703 jout(
" %s: %" PRIu64
"\n", ccp, ull);
1706 ccp =
"Number of write FUA_NV intervals";
1708 jout(
" %s: %" PRIu64
"\n", ccp, ull);
1729 int num, err, truncated;
1763 int pl = ucp[3] + 4;
1768 pout(
"%s Percentage used endurance indicator parameter "
1769 "too short (pl=%d)\n",
ssm_s, pl);
1773 q =
"Percentage used endurance indicator";
1774 jout(
"%s: %d%%\n", q, ucp[7]);
1788 int num, err, truncated;
1793 static const char * jname =
"scsi_zoned_block_device_statistics";
1826 int pl = ucp[3] + 4;
1832 q =
"Maximum open zones";
1834 jout(
" %s: %u\n", q, u);
1838 q =
"Maximum explicitly open zones";
1840 jout(
" %s: %u\n", q, u);
1844 q =
"Maximum implicitly open zones";
1846 jout(
" %s: %u\n", q, u);
1850 q =
"Minimum empty zones";
1852 jout(
" %s: %u\n", q, u);
1856 q =
"Maximum nonseq zones";
1858 jout(
" %s: %u\n", q, u);
1862 q =
"Zones emptied";
1864 jout(
" %s: %u\n", q, u);
1868 q =
"Suboptimal write commands";
1870 jout(
" %s: %u\n", q, u);
1874 q =
"Commands exceeding optinmal limit";
1876 jout(
" %s: %u\n", q, u);
1880 q =
"Failed explicit opens";
1882 jout(
" %s: %u\n", q, u);
1886 q =
"Read rule violations";
1888 jout(
" %s: %u\n", q, u);
1892 q =
"Write rule violations";
1894 jout(
" %s: %u\n", q, u);
1898 q =
"Maximum implicitly open sequential or before required zones";
1900 jout(
" %s: %u\n", q, u);
1916 int num, err, truncated;
1922 static const char * hname =
"Device statistics (SSC, tape)";
1923 static const char * jname =
"scsi_device_statistics";
1944 pout(
"%s %s length is %d, too short\n", hname,
logSenStr, num);
1956 int pl = ucp[3] + 4;
1961 q =
"Lifetime volume loads";
1963 jout(
" %s: %" PRIu64
"\n", q, ull);
1967 q =
"Lifetime cleaning operations";
1969 jout(
" %s: %" PRIu64
"\n", q, ull);
1973 q =
"Lifetime power on hours";
1975 jout(
" %s: %" PRIu64
"\n", q, ull);
1979 q =
"Lifetime medium motion hours";
1981 jout(
" %s: %" PRIu64
"\n", q, ull);
1985 q =
"Lifetime meters of tape processed";
1987 jout(
" %s: %" PRIu64
"\n", q, ull);
1991 q =
"Lifetime medium motion hours at last incompatible volume "
1994 jout(
" %s: %" PRIu64
"\n", q, ull);
1998 q =
"Lifetime power on hours at last temperature condition "
2001 jout(
" %s: %" PRIu64
"\n", q, ull);
2005 q =
"Lifetime power on hours at last power consumption condition "
2008 jout(
" %s: %" PRIu64
"\n", q, ull);
2012 q =
"Medium motion hours since last successful cleaning "
2015 jout(
" %s: %" PRIu64
"\n", q, ull);
2019 q =
"Medium motion hours since second to last successful "
2020 "cleaning operation";
2022 jout(
" %s: %" PRIu64
"\n", q, ull);
2026 q =
"Medium motion hours since third to last successful "
2027 "cleaning operation";
2029 jout(
" %s: %" PRIu64
"\n", q, ull);
2033 q =
"Lifetime power on hours at last operator initiated forced "
2034 "reset and/or emergency eject occurrence";
2036 jout(
" %s: %" PRIu64
"\n", q, ull);
2040 q =
"Lifetime power cycles";
2042 jout(
" %s: %" PRIu64
"\n", q, ull);
2046 q =
"Volume loads since last parameter reset";
2048 jout(
" %s: %" PRIu64
"\n", q, ull);
2052 q =
"Hard write errors";
2054 jout(
" %s: %" PRIu64
"\n", q, ull);
2058 q =
"Hard read errors";
2060 jout(
" %s: %" PRIu64
"\n", q, ull);
2064 q =
"Duty cycle sample time";
2066 jout(
" %s: %" PRIu64
"\n", q, ull);
2070 q =
"Read duty cycle";
2072 jout(
" %s: %" PRIu64
"\n", q, ull);
2076 q =
"Write duty cycle";
2078 jout(
" %s: %" PRIu64
"\n", q, ull);
2082 q =
"Activity duty cycle";
2084 jout(
" %s: %" PRIu64
"\n", q, ull);
2088 q =
"Volume not present duty cycle";
2090 jout(
" %s: %" PRIu64
"\n", q, ull);
2094 q =
"Ready duty cycle";
2096 jout(
" %s: %" PRIu64
"\n", q, ull);
2100 q =
"Megabytes transferred from application client in duty cycle"
2103 jout(
" %s: %" PRIu64
"\n", q, ull);
2107 q =
"Megabytes transferred to application client in duty cycle"
2110 jout(
" %s: %" PRIu64
"\n", q, ull);
2115 std::string v((
const char *)(ucp + 4), ucp[3]);
2116 q =
"Drive manufacturer's serial number";
2117 jout(
" %s: %s\n", q, v.c_str());
2123 std::string v((
const char *)(ucp + 4), ucp[3]);
2124 q =
"Drive serial number";
2125 jout(
" %s: %s\n", q, v.c_str());
2131 std::string v((
const char *)(ucp + 4), ucp[3]);
2132 q =
"Manufacturing date year,month,day";
2133 jout(
" %s: %s\n", q, v.c_str());
2139 std::string v((
const char *)(ucp + 4), ucp[3]);
2140 q =
"Manufacturing date year,week";
2141 jout(
" %s: %s\n", q, v.c_str());
2147 std::string v((
const char *)(ucp + 4), ucp[3]);
2148 q =
"Manufacturing date year,week";
2149 jout(
" %s: %s\n", q, v.c_str());
2154 q =
"Medium removal prevented";
2156 jout(
" %s: %" PRIu64
"\n", q, ull);
2160 q =
"Maximum recommended mechanism temperature exceeded";
2162 jout(
" %s: %" PRIu64
"\n", q, ull);
2166 q =
"Medium motion hours for each medium type";
2169 jout(
" %s, number of element: %u\n", q, n);
2170 for (k = 0; k < n; ++k, ucp += 8) {
2172 jout(
" [%d] density code: %u, density code: %u, hours: "
2173 "%u\n", k + 1, ucp[6], ucp[7], u);
2174 jglb[jname][
s][k][
"density_code"] = ucp[6];
2175 jglb[jname][
s][k][
"medium_type"] = ucp[7];
2176 jglb[jname][
s][k][
"medium_motion_hours"] = u;
2191 int num, err, truncated;
2195 static const char * hname =
"Format Status";
2196 static const char * jname =
"scsi_format_status";
2215 jout(
"%s %s length is %d, too short\n", hname,
logSenStr, num);
2227 int pl = ucp[3] + 4;
2229 bool is_count =
true;
2230 const char * jout_str =
"";
2231 const char * jglb_str =
"x";
2236 jout(
"Format data out: <empty>\n");
2239 jout(
"Format data out: <not available>\n");
2241 jout(
"Format data out:\n");
2242 dStrHex((
const uint8_t *)ucp + 4, pl - 4, 0);
2249 jout_str =
"Grown defects during certification";
2250 jglb_str =
"grown_defects_during_cert";
2253 jout_str =
"Total blocks reassigned during format";
2254 jglb_str =
"blocks_reassigned_during_format";
2257 jout_str =
"Total new blocks reassigned";
2258 jglb_str =
"total_new_block_since_format";
2261 jout_str =
"Power on minutes since format";
2262 jglb_str =
"power_on_minutes_since_format";
2266 pout(
" Unknown Format parameter code = 0x%x\n", pc);
2267 dStrHex((
const uint8_t *)ucp, pl, 0);
2273 if (
all_ffs(ucp + 4, ucp[3])) {
2274 pout(
"%s <not available>\n", jout_str);
2277 jout(
"%s = %" PRIu64
"\n", jout_str, ull);
2278 jglb[jname][jglb_str] = ull;
2290 unsigned thresh_val)
2294 static const char * pvd_th =
"Peak value detector threshold";
2295 static const char * pvd_th_j =
"pvd_threshold";
2299 jout(
" No event\n");
2302 q =
"Invalid dword count";
2303 jout(
" %s: %u\n", q, val);
2304 jref[std::string(q) +
"_2"] = val;
2307 q =
"Running disparity error count";
2308 jout(
" %s: %u\n", q, val);
2309 jref[std::string(q) +
"_2"] = val;
2312 q =
"Loss of dword synchronization count";
2313 jout(
" %s: %u\n", q, val);
2314 jref[std::string(q) +
"_2"] = val;
2317 q =
"Phy reset problem count";
2318 jout(
" %s: %u\n", q, val);
2319 jref[std::string(q) +
"_2"] = val;
2322 q =
"Elasticity buffer overflow count";
2323 jout(
" %s: %u\n", q, val);
2327 q =
"Received ERROR count";
2328 jout(
" %s: %u\n", q, val);
2332 q =
"Received address frame error count";
2333 jout(
" %s: %u\n", q, val);
2337 q =
"Transmitted abandon-class OPEN_REJECT count";
2338 jout(
" %s: %u\n", q, val);
2342 q =
"Received abandon-class OPEN_REJECT count";
2343 jout(
" %s: %u\n", q, val);
2347 q =
"Transmitted retry-class OPEN_REJECT count";
2348 jout(
" %s: %u\n", q, val);
2352 q =
"Received retry-class OPEN_REJECT count";
2353 jout(
" %s: %u\n", q, val);
2357 q =
"Received AIP (WAITING ON PARTIAL) count";
2358 jout(
" %s: %u\n", q, val);
2362 q =
"Received AIP (WAITING ON CONNECTION) count";
2363 jout(
" %s: %u\n", q, val);
2367 q =
"Transmitted BREAK count";
2368 jout(
" %s: %u\n", q, val);
2372 q =
"Received BREAK count";
2373 jout(
" %s: %u\n", q, val);
2377 q =
"Break timeout count";
2378 jout(
" %s: %u\n", q, val);
2382 q =
"Connection count";
2383 jout(
" %s: %u\n", q, val);
2387 q =
"Peak transmitted pathway blocked";
2388 jout(
" %s count: %u\n", q, val & 0xff);
2389 jout(
" %s: %u\n", pvd_th, thresh_val & 0xff);
2390 jref[q][
"count"] = val & 0xff;
2391 jref[q][pvd_th_j] = thresh_val & 0xff;
2394 q =
"Peak transmitted arbitration wait time";
2397 jout(
" %s (us): %u\n", q, u);
2398 jref[std::string(q) +
"_us"][
"event"] = u;
2400 jout(
" %s (ms): %u\n", q, 33 + (u - 0x8000));
2401 jref[std::string(q) +
"_ms"][
"event"] = 33 + (u - 0x8000);
2403 u = thresh_val & 0xffff;
2405 jout(
" %s (us): %u\n", pvd_th, u);
2406 jref[std::string(q) +
"_us"][pvd_th_j] = u;
2408 jout(
" %s (ms): %u\n", pvd_th, 33 + (u - 0x8000));
2409 jref[std::string(q) +
"_ms"][pvd_th_j] = 33 + (u - 0x8000);
2413 q =
"Peak arbitration time";
2414 jout(
" %s (us): %u\n", q, val);
2415 jref[std::string(q) +
"_us"][
"event"] = val;
2416 jout(
" %s: %u\n", pvd_th, thresh_val);
2417 jref[std::string(q) +
"_us"][pvd_th_j] = thresh_val;
2420 q =
"Peak connection time";
2421 jout(
" %s (us): %u\n", q, val);
2422 jref[std::string(q) +
"_us"][
"event"] = val;
2423 jout(
" %s: %u\n", pvd_th, thresh_val);
2424 jref[std::string(q) +
"_us"][pvd_th_j] = thresh_val;
2427 q =
"Transmitted SSP frame count";
2428 jout(
" %s: %u\n", q, val);
2432 q =
"Received SSP frame count";
2433 jout(
" %s: %u\n", q, val);
2437 q =
"Transmitted SSP frame error count";
2438 jout(
" %s: %u\n", q, val);
2442 q =
"Received SSP frame error count";
2443 jout(
" %s: %u\n", q, val);
2447 q =
"Transmitted CREDIT_BLOCKED count";
2448 jout(
" %s: %u\n", q, val);
2452 q =
"Received CREDIT_BLOCKED count";
2453 jout(
" %s: %u\n", q, val);
2457 q =
"Transmitted SATA frame count";
2458 jout(
" %s: %u\n", q, val);
2462 q =
"Received SATA frame count";
2463 jout(
" %s: %u\n", q, val);
2467 q =
"SATA flow control buffer overflow count";
2468 jout(
" %s: %u\n", q, val);
2472 q =
"Transmitted SMP frame count";
2473 jout(
" %s: %u\n", q, val);
2477 q =
"Received SMP frame count";
2478 jout(
" %s: %u\n", q, val);
2482 q =
"Received SMP frame error count";
2483 jout(
" %s: %u\n", q, val);
2494 int k, j, m, nphys, t, sz, spld_len;
2496 unsigned char * vcp;
2500 snprintf(pn,
sizeof(pn),
"scsi_sas_port_%d", port_num);
2504 jout(
"relative target port id = %d\n", t);
2505 jglb[pn][
"relative_target_port_id"] = t;
2506 jout(
" generation code = %d\n", ucp[6]);
2507 jglb[pn][
"generation_code"] = ucp[6];
2509 jout(
" number of phys = %d\n", nphys);
2510 jglb[pn][
"number_of_phys"] = nphys;
2512 for (j = 0, k = 0, vcp = ucp + 8; j < (param_len - 8);
2513 vcp += spld_len, j += spld_len, ++k) {
2516 snprintf(yn,
sizeof(yn),
"phy_%d", k);
2518 jout(
" phy identifier = %d\n", vcp[1]);
2519 jref[
"identifier"] = vcp[1];
2525 t = ((0x70 & vcp[4]) >> 4);
2527 case 0: snprintf(
s, sz,
"no device attached");
break;
2528 case 1: snprintf(
s, sz,
"SAS or SATA device");
break;
2529 case 2: snprintf(
s, sz,
"expander device");
break;
2530 case 3: snprintf(
s, sz,
"expander device (fanout)");
break;
2531 default: snprintf(
s, sz,
"reserved [%d]", t);
break;
2533 q =
"attached device type";
2534 jout(
" %s: %s\n", q,
s);
2538 case 0: snprintf(
s, sz,
"unknown");
break;
2539 case 1: snprintf(
s, sz,
"power on");
break;
2540 case 2: snprintf(
s, sz,
"hard reset");
break;
2541 case 3: snprintf(
s, sz,
"SMP phy control function");
break;
2542 case 4: snprintf(
s, sz,
"loss of dword synchronization");
break;
2543 case 5: snprintf(
s, sz,
"mux mix up");
break;
2544 case 6: snprintf(
s, sz,
"I_T nexus loss timeout for STP/SATA");
2546 case 7: snprintf(
s, sz,
"break timeout timer expired");
break;
2547 case 8: snprintf(
s, sz,
"phy test function stopped");
break;
2548 case 9: snprintf(
s, sz,
"expander device reduced functionality");
2550 default: snprintf(
s, sz,
"reserved [0x%x]", t);
break;
2552 q =
"attached reason";
2553 jout(
" %s: %s\n", q,
s);
2555 t = (vcp[5] & 0xf0) >> 4;
2557 case 0: snprintf(
s, sz,
"unknown");
break;
2558 case 1: snprintf(
s, sz,
"power on");
break;
2559 case 2: snprintf(
s, sz,
"hard reset");
break;
2560 case 3: snprintf(
s, sz,
"SMP phy control function");
break;
2561 case 4: snprintf(
s, sz,
"loss of dword synchronization");
break;
2562 case 5: snprintf(
s, sz,
"mux mix up");
break;
2563 case 6: snprintf(
s, sz,
"I_T nexus loss timeout for STP/SATA");
2565 case 7: snprintf(
s, sz,
"break timeout timer expired");
break;
2566 case 8: snprintf(
s, sz,
"phy test function stopped");
break;
2567 case 9: snprintf(
s, sz,
"expander device reduced functionality");
2569 default: snprintf(
s, sz,
"reserved [0x%x]", t);
break;
2572 jout(
" %s: %s\n", q,
s);
2576 case 0: snprintf(
s, sz,
"phy enabled; unknown");
2578 case 1: snprintf(
s, sz,
"phy disabled");
break;
2579 case 2: snprintf(
s, sz,
"phy enabled; speed negotiation failed");
2581 case 3: snprintf(
s, sz,
"phy enabled; SATA spinup hold state");
2583 case 4: snprintf(
s, sz,
"phy enabled; port selector");
2585 case 5: snprintf(
s, sz,
"phy enabled; reset in progress");
2587 case 6: snprintf(
s, sz,
"phy enabled; unsupported phy attached");
2589 case 8: snprintf(
s, sz,
"phy enabled; 1.5 Gbps");
break;
2590 case 9: snprintf(
s, sz,
"phy enabled; 3 Gbps");
break;
2591 case 0xa: snprintf(
s, sz,
"phy enabled; 6 Gbps");
break;
2592 case 0xb: snprintf(
s, sz,
"phy enabled; 12 Gbps");
break;
2593 default: snprintf(
s, sz,
"reserved [%d]", t);
break;
2595 q =
"negotiated logical link rate";
2596 jout(
" %s: %s\n", q,
s);
2598 q =
"attached initiator port";
2599 jout(
" %s: ssp=%d stp=%d smp=%d\n", q,
2600 !! (vcp[6] & 8), !! (vcp[6] & 4), !! (vcp[6] & 2));
2601 snprintf(
s, sz,
"%03d", ((vcp[6] & 8) ? 100 : 0) +
2602 ((vcp[6] & 4) ? 10 : 0) + ((vcp[6] & 2) ? 1 : 0));
2603 jref[q][
"ssp_stp_smp"] =
s;
2604 q =
"attached target port";
2605 jout(
" %s: ssp=%d stp=%d smp=%d\n", q,
2606 !! (vcp[7] & 8), !! (vcp[7] & 4), !! (vcp[7] & 2));
2607 snprintf(
s, sz,
"%03d", ((vcp[7] & 8) ? 100 : 0) +
2608 ((vcp[7] & 4) ? 10 : 0) + ((vcp[7] & 2) ? 1 : 0));
2609 jref[q][
"ssp_stp_smp"] =
s;
2614 snprintf(
b,
sizeof(
b),
"0x%" PRIx64, ull);
2616 jout(
" %s = %s\n", q,
b);
2619 snprintf(
b,
sizeof(
b),
"0x%" PRIx64, ull);
2620 q =
"attached SAS address";
2621 jout(
" %s = %s\n", q,
b);
2624 q =
"attached phy identifier";
2625 jout(
" %s = %d\n", q, vcp[24]);
2629 q =
"Invalid DWORD count";
2630 jout(
" %s = %u\n", q, ui);
2633 q =
"Running disparity error count";
2634 jout(
" %s = %u\n", q, ui);
2637 q =
"Loss of DWORD synchronization count";
2638 jout(
" %s = %u\n", q, ui);
2641 q =
"Phy reset problem count";
2642 jout(
" %s = %u\n", q, ui);
2644 if (spld_len > 51) {
2645 bool header_given =
false;
2648 unsigned char * xcp;
2652 for (m = 0; m < (num_ped * 12); m += 12, xcp += 12) {
2659 if (allow_dupl || (peis > 0x4)) {
2660 if (! header_given) {
2661 header_given =
true;
2662 jout(
" Phy event descriptors:\n");
2676 unsigned char * ucp;
2679 for (k = 0, j = 0, ucp = resp + 4; k < num; ++j) {
2680 int param_len = ucp[3] + 4;
2684 jout(
"\nProtocol Specific port %s for SAS SSP\n",
lp_s);
2700 static const char * hname =
"Protocol specific port";
2720 pout(
"Only support %s %s on SAS devices\n\n", hname,
lp_s);
2728 pout(
"%s Log Select (reset) Failed [%s]\n\n", __func__,
2754 "optical card reader",
2756 "object based storage",
2757 "automation/driver interface",
2758 "security manager device",
2759 "host managed zoned block device",
2769 "well known logical unit",
2770 "unknown or no device type",
2775 "Fibre channel (FCP-4)",
2776 "Parallel SCSI (SPI-4)",
2778 "IEEE 1394 (SBP-3)",
2796 bool & have_zbc,
bool all)
2799 bool is_tape =
false;
2800 int err, iec_err, len, req_len, avail_len;
2803 int form_factor = 0;
2809 memset(
gBuf, 0, 96);
2815 pout(
"Retrying with a 64 byte Standard Inquiry\n");
2821 pout(
"Standard Inquiry (64 bytes) failed [%s]\n",
2827 avail_len =
gBuf[4] + 5;
2828 len = (avail_len < req_len) ? avail_len : req_len;
2829 peri_dt =
gBuf[0] & 0x1f;
2830 *peripheral_type = peri_dt;
2839 pout(
"Short INQUIRY response, skip product id\n");
2847 if (all && (0 != strncmp((
char *)&
gBuf[8],
"ATA", 3))) {
2848 char product[16+1], revision[4+1];
2853 pout(
"=== START OF INFORMATION SECTION ===\n");
2856 jout(
"Product: %.16s\n", product);
2857 jglb[
"scsi_product"] = product;
2860 if (
gBuf[32] >=
' ') {
2861 jout(
"Revision: %.4s\n", revision);
2863 jglb[
"scsi_revision"] = revision;
2868 snprintf(sv_arr,
sizeof(sv_arr),
"SPC-%d",
scsi_version - 2);
2869 jout(
"Compliance: %s\n", sv_arr);
2870 jglb[
"scsi_version"] = sv_arr;
2875 (0 == strncmp((
char *)&
gBuf[8],
"ATA", 3))) {
2876 pout(
"\nProbable ATA device behind a SAT layer\n"
2877 "Try an additional '-d ata' or '-d sat' argument.\n");
2883 protect =
gBuf[5] & 0x1;
2889 unsigned char lb_prov_resp[8];
2892 static const char * lb_prov_j =
"scsi_lb_provisioning";
2895 char cap_str[64], si_str[64];
2898 jout(
"User Capacity: %s bytes [%s]\n", cap_str, si_str);
2900 jglb[
"user_capacity"][
"blocks"].set_unsafe_uint64(capacity /
2902 jglb[
"user_capacity"][
"bytes"].set_unsafe_uint64(capacity);
2903 jout(
"Logical block size: %u bytes\n", srr.
lb_size);
2908 jout(
"Physical block size: %u bytes\n", pb_size);
2909 jglb[
"physical_block_size"] = pb_size;
2916 pout(
"Formatted with type 1 protection\n");
2919 pout(
"Formatted with type 2 protection\n");
2922 pout(
"Formatted with type 3 protection\n");
2925 pout(
"Formatted with unknown protection type [%d]\n",
2930 unsigned p_i_per_lb = (1 << srr.
p_i_exp);
2931 const unsigned pi_sz = 8;
2934 if (p_i_per_lb > 1) {
2935 jout(
"%d protection information intervals per "
2936 "logical block\n", p_i_per_lb);
2939 jout(
"%d bytes of protection information per logical "
2940 "block\n", pi_sz * p_i_per_lb);
2941 jglb[
"scsi_protection_interval_bytes_per_lb"] =
2953 lb_prov_resp,
sizeof(lb_prov_resp))) {
2954 int prov_type = lb_prov_resp[6] & 0x7;
2955 int vpd_lbprz = ((lb_prov_resp[5] >> 2) & 0x7);
2959 else if ((0 == vpd_lbprz) && (1 ==
lbprz))
2963 switch (prov_type) {
2966 jout(
"LU is fully provisioned");
2967 jglb[lb_prov_j][
"name"] =
"fully provisioned";
2973 jout(
"LB provisioning type: not reported [LBPME=1, "
2974 "LBPRZ=%d]\n",
lbprz);
2975 jglb[lb_prov_j][
"name"] =
"not reported";
2979 jout(
"LU is resource provisioned, LBPRZ=%d\n",
lbprz);
2980 jglb[lb_prov_j][
"name"] =
"resource provisioned";
2983 jout(
"LU is thin provisioned, LBPRZ=%d\n",
lbprz);
2984 jglb[lb_prov_j][
"name"] =
"thin provisioned";
2987 jout(
"LU provisioning type reserved [%d], LBPRZ=%d\n",
2989 jglb[lb_prov_j][
"name"] =
"reserved";
2992 jglb[lb_prov_j][
"value"] = prov_type;
2993 jglb[lb_prov_j][
"management_enabled"][
"name"] =
"LBPME";
2994 jglb[lb_prov_j][
"management_enabled"][
"value"] =
lbpme;
2995 jglb[lb_prov_j][
"read_zeros"][
"name"] =
"LBPRZ";
2996 jglb[lb_prov_j][
"read_zeros"][
"value"] =
lbprz;
2997 }
else if (1 ==
lbpme) {
2999 jout(
"rcap_16 sets LBPME but no LB provisioning VPD page\n");
3000 jout(
"Logical block provisioning enabled, LBPRZ=%d\n",
lbprz);
3008 jout(
"Rotation Rate: Solid State Device\n");
3009 else if ((rpm <= 0x400) || (0xffff == rpm))
3012 jout(
"Rotation Rate: %d rpm\n", rpm);
3013 jglb[
"rotation_rate"] = (rpm == 1 ? 0 : rpm);
3015 if (form_factor > 0) {
3016 const char * cp =
nullptr;
3018 switch (form_factor) {
3035 jglb[
"form_factor"][
"scsi_value"] = form_factor;
3037 jout(
"Form Factor: %s inches\n", cp);
3043 q =
"Host aware zoned block capable";
3046 }
else if (haw_zbc == 2) {
3048 q =
"Device managed zoned block capable";
3067 pout(
">> Terminate command early due to bad response to IEC "
3083 if (strlen(
s) > 0) {
3084 jout(
"Logical Unit id: %s\n",
s);
3085 jglb[
"logical_unit_id"] =
s;
3090 pout(
"Vital Product Data (VPD) bit ignored in INQUIRY\n");
3092 pout(
"Vital Product Data (VPD) INQUIRY failed [%d]\n", err);
3100 gBuf[4 + len] =
'\0';
3102 jout(
"Serial number: %s\n", serial);
3103 jglb[
"serial_number"] = serial;
3107 pout(
"Vital Product Data (VPD) bit ignored in INQUIRY\n");
3109 pout(
"Vital Product Data (VPD) INQUIRY failed [%d]\n", err);
3115 jglb[
"device_type"][
"scsi_terminology"] =
"Peripheral Device Type [PDT]";
3116 jglb[
"device_type"][
"scsi_value"] = peri_dt;
3122 jout(
"Device type: <%d>\n", peri_dt);
3127 if ((transport >= 0) && (transport <= 0xf)) {
3130 jglb[
"scsi_transport_protocol"][
"value"] = transport;
3140 pout(
"device is NOT READY (e.g. spun down, busy)\n");
3142 pout(
"device is NOT READY (e.g. no tape)\n");
3147 pout(
"NO tape present in drive\n");
3149 pout(
"NO MEDIUM present in device\n");
3153 pout(
"device becoming ready (wait)\n");
3169 jout(
"SMART support is: Unavailable - device lacks SMART "
3171 jglb[
"smart_support"][
"available"] =
false;
3182 jout(
"SMART support is: Available - device has SMART capability.\n"
3183 "SMART support is: %s\n", ok ?
"Enabled" :
"Disabled");
3184 jglb[
"smart_support"][
"available"] =
true;
3185 jglb[
"smart_support"][
"enabled"] = ok;
3188 jout(
"Temperature Warning: %s\n",
3189 ok ?
"Enabled" :
"Disabled or Not Supported");
3190 jglb[
"temperature_warning"][
"enabled"] = ok;
3202 pout(
"unable to fetch IEC (SMART) mode page [%s]\n",
3211 pout(
"unable to enable Exception control and warning [%s]\n",
3218 pout(
"unable to fetch IEC (SMART) mode page [%s]\n",
3224 pout(
"Informational Exceptions (SMART) %s\n",
3226 pout(
"Temperature warning %s\n",
3239 pout(
"unable to fetch IEC (SMART) mode page [%s]\n",
3248 pout(
"unable to disable Exception control and warning [%s]\n",
3255 pout(
"unable to fetch IEC (SMART) mode page [%s]\n",
3261 pout(
"Informational Exceptions (SMART) %s\n",
3263 pout(
"Temperature warning %s\n",
3278 pout(
"Current Drive Temperature: <not available>\n");
3280 jout(
"Current Drive Temperature: %d C\n", temp);
3281 jglb[
"temperature"][
"current"] = temp;
3284 pout(
"Drive Trip Temperature: <not available>\n");
3286 jout(
"Drive Trip Temperature: %d C\n", trip);
3287 jglb[
"temperature"][
"drive_trip"] = trip;
3298 unsigned char * ucp;
3300 static const char * hname =
"Environmental Reports";
3301 static const char * jname =
"scsi_environmental_reports";
3302 static const char * rh_n =
"relative humidity";
3303 static const char * temp_n =
"temperature";
3304 static const char * sop_n =
"since power on";
3305 static const char * unkn_n =
"unknown";
3321 if (! (
gBuf[0] & 0x40)) {
3324 pout(
"Another flaky device that doesn't set the SPF bit\n");
3334 int pl = ucp[3] + 4;
3338 if ((pc < 0x100) && (pl == 12)) {
3339 snprintf(pc_s,
sizeof(pc_s),
"temperature_%d", ++temp_num);
3341 int temp = (int)(int8_t)ucp[5];
3343 jglb[jname][pc_s][
"parameter_code"] = pc;
3346 if (ucp[5] == 0x80) {
3347 jout(
"%s %s = %s\n", q, temp_n, unkn_n);
3348 jglb[jname][pc_s][
s] = unkn_n;
3350 jout(
"%s %s = %d\n", q, temp_n, temp);
3351 jglb[jname][pc_s][
s] = temp;
3353 temp = (int)(int8_t)ucp[6];
3354 q =
"Lifetime maximum";
3356 if (ucp[6] == 0x80) {
3357 jout(
"%s %s = %s\n", q, temp_n, unkn_n);
3358 jglb[jname][pc_s][
s] = unkn_n;
3360 jout(
"%s %s = %d\n", q, temp_n, temp);
3361 jglb[jname][pc_s][
s] = temp;
3363 temp = (int)(int8_t)ucp[7];
3364 q =
"Lifetime minimum";
3366 if (ucp[7] == 0x80) {
3367 jout(
"%s %s = %s\n", q, temp_n, unkn_n);
3368 jglb[jname][pc_s][
s] = unkn_n;
3370 jout(
"%s %s = %d\n", q, temp_n, temp);
3371 jglb[jname][pc_s][
s] = temp;
3373 temp = (int)(int8_t)ucp[8];
3374 q =
"Maximum since power on";
3376 if (ucp[8] == 0x80) {
3377 jout(
"Maximum %s %s = %s\n", temp_n, sop_n, unkn_n);
3378 jglb[jname][pc_s][
s] = unkn_n;
3380 jout(
"Maximum %s %s = %d\n", temp_n, sop_n, temp);
3381 jglb[jname][pc_s][
s] = temp;
3383 temp = (int)(int8_t)ucp[9];
3384 q =
"Minimum since power on";
3386 if (ucp[9] == 0x80) {
3387 jout(
"Minimum %s %s = %s\n", temp_n, sop_n, unkn_n);
3388 jglb[jname][pc_s][
s] = unkn_n;
3390 jout(
"Minimum %s %s = %d\n", temp_n, sop_n, temp);
3391 jglb[jname][pc_s][
s] = temp;
3393 if ((ucp[4] & 0x3) == 1) {
3394 temp = (int)(int8_t)ucp[10];
3395 q =
"Maximum other";
3397 if (ucp[10] == 0x80) {
3398 jout(
"%s %s = %s\n", q, temp_n, unkn_n);
3399 jglb[jname][pc_s][
s] = unkn_n;
3401 jout(
"%s %s = %d\n", q, temp_n, temp);
3402 jglb[jname][pc_s][
s] = temp;
3404 temp = (int)(int8_t)ucp[11];
3405 q =
"Minimum other";
3407 if (ucp[11] == 0x80) {
3408 jout(
"%s %s = %s\n", q, temp_n, unkn_n);
3409 jglb[jname][pc_s][
s] = unkn_n;
3411 jout(
"%s %s = %d\n", q, temp_n, temp);
3412 jglb[jname][pc_s][
s] = temp;
3415 }
else if ((pc < 0x200) && (pl == 12)) {
3416 snprintf(pc_s,
sizeof(pc_s),
"relative_humidity_%d", ++humid_num);
3417 jglb[jname][pc_s][
"parameter_code"] = pc;
3418 jout(
"Relative humidity = %u\n", ucp[5]);
3419 jglb[jname][pc_s][
"current"] = ucp[5];
3420 q =
"Lifetime maximum";
3422 jout(
"%s %s = %d\n", q, rh_n, ucp[6]);
3423 jglb[jname][pc_s][
s] = ucp[6];
3424 q =
"Lifetime minimum";
3426 jout(
"%s %s = %d\n", q, rh_n, ucp[7]);
3427 jglb[jname][pc_s][
s] = ucp[7];
3428 jout(
"Maximum %s %s = %d\n", rh_n, sop_n, ucp[8]);
3429 jglb[jname][pc_s][
"maximum_since_power_on"] = ucp[8];
3430 jout(
"Minimum %s %s = %d\n", rh_n, sop_n, ucp[9]);
3431 jglb[jname][pc_s][
"minimum_since_power_on"] = ucp[9];
3432 if ((ucp[4] & 0x3) == 1) {
3433 q =
"Maximum other";
3435 jout(
"%s %s = %d\n", q, rh_n, ucp[10]);
3436 jglb[jname][pc_s][
s] = ucp[10];
3437 q =
"Minimum other";
3439 jout(
"%s %s = %d\n", q, rh_n, ucp[11]);
3440 jglb[jname][pc_s][
s] = ucp[11];
3445 if ((pc < 0x200) && (pl != 12))
3446 pout(
"%s sub-lpage unexpected parameter length [%d], skip\n",
3449 pout(
"%s sub-lpage has unexpected parameter [0x%x], skip\n",
3465 bool envRepDone =
false;
3466 uint8_t peripheral_type = 0;
3468 int res, durationSec;
3476 const char * powername =
nullptr;
3477 bool powerchg =
false;
3481 if (sense_info.
asc == 0x5E) {
3482 unsigned char powerlimit = 0xff;
3483 int powermode = sense_info.
ascq ;
3502 switch (powermode) {
3505 pout(
"CHECK POWER MODE not implemented, ignoring -n option\n");
break;
3507 powername =
"SLEEP"; powerlimit = 2;
3511 powername =
"LOW POWER"; powerlimit = 2;
break;
3513 powername =
"IDLE BY TIMER"; powerlimit = 4;
break;
3515 powername =
"STANDBY BY TIMER"; powerlimit = 2;
break;
3517 powername =
"IDLE BY COMMAND"; powerlimit = 4;
break;
3519 powername =
"STANDBY BY COMMAND"; powerlimit = 2;
break;
3521 powername =
"IDLE BY TIMER"; powerlimit = 4;
break;
3523 powername =
"IDLE_ BY COMMAND"; powerlimit = 4;
break;
3525 powername =
"IDLE_C BY TIMER"; powerlimit = 4;
break;
3527 powername =
"IDLE_C BY COMMAND"; powerlimit = 4;
break;
3529 powername =
"STANDBY_Y BY TIMER"; powerlimit = 2;
break;
3531 powername =
"STANDBY_Y BY COMMAND"; powerlimit = 2;
break;
3534 pout(
"CHECK POWER MODE returned unknown value 0x%02x, "
3535 "ignoring -n option\n", powermode);
3540 jinf(
"Device is in %s mode, exit(%d)\n", powername, options.
powerexit);
3543 powerchg = (powermode != 0xff);
3546 powername =
"ACTIVE";
3569 pout(
"%s: query_cmd_support() failed\n", __func__);
3573 short int wce = -1, rcd = -1;
3579 pout(
"Read Cache is: %s\n",
3580 res ?
"Unavailable" :
3581 rcd ?
"Disabled" :
"Enabled");
3583 pout(
"Writeback Cache is: %s\n",
3584 res ?
"Unavailable" :
3585 !wce ?
"Disabled" :
"Enabled");
3592 pout(
"Power mode %s %s\n", (powerchg?
"was:":
"is: "), powername);
3599 pout(
"=== START OF ENABLE/DISABLE COMMANDS SECTION ===\n");
3615 pout(
"Enable autosave (clear GLTSD bit) failed\n");
3618 pout(
"Autosave enabled (GLTSD bit cleared).\n");
3623 if (options.
set_wce && is_disk) {
3624 short int enable = wce = (options.
set_wce > 0);
3628 pout(
"Write cache %sable failed: %s\n", (enable ?
"en" :
"dis"),
3632 pout(
"Write cache %sabled\n", (enable ?
"en" :
"dis"));
3637 if (options.
set_rcd && is_disk) {
3638 short int enable = (options.
set_rcd > 0);
3643 pout(
"Read cache %sable failed: %s\n", (enable ?
"en" :
"dis"),
3647 pout(
"Read cache %sabled\n", (enable ?
"en" :
"dis"));
3653 pout(
"Disable autosave (set GLTSD bit) failed\n");
3656 pout(
"Autosave disabled (GLTSD bit set).\n");
3668 pout(
"=== START OF READ SMART DATA SECTION ===\n");
3679 jout(
"TapeAlert Supported\n");
3680 jglb[
"tapealert"][
"supported"] =
true;
3687 jout(
"TapeAlert Not Supported\n");
3688 jglb[
"tapealert"][
"supported"] =
false;
3751 bool farm_supported =
true;
3756 jout(
"Seagate FARM log supported [try: -l farm]\n\n");
3761 jout(
"\nRead FARM log (GP Log 0xA6) failed\n\n");
3762 farm_supported =
false;
3769 jout(
"\nFARM log (SCSI log page 0x3D, sub-page 0x3) not supported\n\n");
3771 farm_supported =
false;
3773 jglb[
"seagate_farm_log"][
"supported"] = farm_supported;
3786 pout(
"\n[GLTSD (Global Logging Target Save Disable) set. "
3787 "Enable Save with '-S on']\n");
3797 pout(
"Device does not support Self Test logging\n");
3810 pout(
"Device does not support Background scan results logging\n");
3822 pout(
"Device does not support %s logging\n",
zbds_s);
3834 pout(
"Device does not support %s logging\n",
gsap_s);
3848 pout(
"Device does not support (tape) device characteristics "
3861 pout(
"Device does not support TapeAlert logging\n");
3867 pout(
"TapeAlerts only printed if active, so none printed is good\n");
3874 pout(
"Default Self Test Successful\n");
3880 pout(
"Short Foreground Self Test Successful\n");
3886 (sense_info.
asc == 0x04 && sense_info.
ascq == 0x09)) {
3888 pout(
"Can't start self-test without aborting current test");
3890 pout(
" (%d%% remaining)",
3891 100 - sense_info.
progress * 100 / 65535);
3892 pout(
",\nadd '-t force' option to override, or run "
3893 "'smartctl -X' to abort test.\n");
3902 pout(
"Short Background Self Test has begun\n");
3903 pout(
"Use smartctl -X to abort test\n");
3909 pout(
"Extended Background Self Test has begun\n");
3912 time_t t = time(
nullptr);
3915 pout(
"Please wait %d minutes for test to complete.\n",
3919 pout(
"Estimated completion time: %s\n", comptime);
3921 pout(
"Use smartctl -X to abort test\n");
3927 pout(
"Extended Foreground Self Test Successful\n");
3932 pout(
"Self Test returned without error\n");
3951 pout(
"SCSI SSU(ACTIVE) command failed: %s\n",
3955 pout(
"Device placed in ACTIVE mode\n");
3957 pout(
"SCSI SSU(STANDBY) with timeout not supported yet\n");
3964 pout(
"Device placed in STANDBY mode\n");
3967 if (!any_output && powername)
3968 pout(
"Device is in %s mode\n", powername);
3971 pout(
"SCSI device successfully opened\n\nUse 'smartctl -a' (or '-x') "
3972 "to print SMART (and more) information\n\n");
bool dont_print_serial_number
Reference to a JSON element.
static std::string str2key(const char *str)
Replace space and non-alphanumerics with '_', upper to lower case.
bool is_spc4_or_higher() const
bool checked_cmd_support() const
enum scsi_cmd_support cmd_support_level(uint8_t opcode, bool sa_valid, uint16_t sa, bool for_lsense_spc=false) const
const char * get_req_type() const
Get type requested by user, empty if none.
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.
bool is_supported(int vpd_page_num) const
bool scsiReadFarmLog(scsi_device *device, scsiFarmLog &farmLog)
bool scsiIsSeagate(char *scsi_vendor)
void scsiPrintFarmLog(const scsiFarmLog &farmLog)
unsigned char failuretest_permissive
int scsiSetPowerCondition(scsi_device *device, int power_cond, int pcond_modifier)
int scsiReadDefect12(scsi_device *device, int req_plist, int req_glist, int dl_format, int addrDescIndex, uint8_t *pBuf, int bufLen)
int scsiFetchExtendedSelfTestTime(scsi_device *device, int *durationSec, int modese_len)
void scsiDecodeErrCounterPage(unsigned char *resp, struct scsiErrorCounter *ecp, int allocLen)
int scsiSetExceptionControlAndWarning(scsi_device *device, int enabled, const struct scsi_iec_mode_page *iecp)
int scsiSmartExtendCapSelfTest(scsi_device *device)
int scsiFetchIECmpage(scsi_device *device, struct scsi_iec_mode_page *iecp, int modese_len)
int scsiGetTemp(scsi_device *device, uint8_t *currenttemp, uint8_t *triptemp)
int scsiSmartShortCapSelfTest(scsi_device *device)
int scsiSmartSelfTestAbort(scsi_device *device)
char * scsi_get_sense_key_str(int sense_key, int buff_len, char *buff)
const char * scsiTapeAlertsTapeDevice(unsigned short code)
int scsiFetchTransportProtocol(scsi_device *device, int modese_len)
int scsi_decode_lu_dev_id(const unsigned char *b, int blen, char *s, int slen, int *transport)
int scsiTestUnitReady(scsi_device *device)
int scsiInquiryVpd(scsi_device *device, int vpd_page, uint8_t *pBuf, int bufLen)
int scsiSmartExtendSelfTest(scsi_device *device)
void scsiDecodeNonMediumErrPage(unsigned char *resp, struct scsiNonMediumError *nmep, int allocLen)
int scsiRequestSense(scsi_device *device, struct scsi_sense_disect *sense_info)
int scsiCheckIE(scsi_device *device, int hasIELogPage, int hasTempLogPage, uint8_t *asc, uint8_t *ascq, uint8_t *currenttemp, uint8_t *triptemp)
uint64_t scsiGetSize(scsi_device *device, bool avoid_rcap16, struct scsi_readcap_resp *srrp)
char * scsiGetIEString(uint8_t asc, uint8_t ascq, char *b, int blen)
int scsiGetSetCache(scsi_device *device, int modese_len, short int *wcep, short int *rcdp)
supported_vpd_pages * supported_vpd_pages_p
int scsiGetRPM(scsi_device *device, int modese_len, int *form_factorp, int *haw_zbcp)
void scsi_format_id_string(char *out, const uint8_t *in, int n)
int scsiStdInquiry(scsi_device *device, uint8_t *pBuf, int bufLen)
int scsiSmartDefaultSelfTest(scsi_device *device)
void dStrHex(const uint8_t *up, int len, int no_ascii)
const char * scsiErrString(int scsiErr)
const char * scsiTapeAlertsChangerDevice(unsigned short code)
int scsiFetchControlGLTSD(scsi_device *device, int modese_len, int current)
int scsi_IsWarningEnabled(const struct scsi_iec_mode_page *iecp)
int scsiSetControlGLTSD(scsi_device *device, int enabled, int modese_len)
int scsi_IsExceptionControlEnabled(const struct scsi_iec_mode_page *iecp)
int scsiSmartShortSelfTest(scsi_device *device)
int scsiLogSense(scsi_device *device, int pagenum, int subpagenum, uint8_t *pBuf, int bufLen, int known_resp_len)
unsigned char scsi_debugmode
int scsiLogSelect(scsi_device *device, int pcr, int sp, int pc, int pagenum, int subpagenum, uint8_t *pBuf, int bufLen)
int scsiReadDefect10(scsi_device *device, int req_plist, int req_glist, int dl_format, uint8_t *pBuf, int bufLen)
#define ENVIRO_LIMITS_L_SPAGE
#define SIMPLE_ERR_BECOMING_READY
#define SIMPLE_ERR_NOT_READY
#define LAST_N_ERROR_EVENTS_LPAGE
#define SCSI_VPD_DEVICE_IDENTIFICATION
#define PEND_DEFECTS_L_SPAGE
#define LPS_MISALIGN_L_SPAGE
#define SEAGATE_FARM_LPAGE
#define SCSI_VPD_LOGICAL_BLOCK_PROVISIONING
#define SCSI_VPD_ZONED_BLOCK_DEV_CHAR
#define TAPE_ALERTS_LPAGE
#define SIMPLE_ERR_NO_MEDIUM
#define SELFTEST_RESULTS_LPAGE
#define SCSI_POW_COND_ACTIVE
#define SCSI_POW_COND_STANDBY
#define VERIFY_ERROR_COUNTER_LPAGE
#define SCSI_PT_MEDIUM_CHANGER
#define NON_MEDIUM_ERROR_LPAGE
#define SCSI_VPD_UNIT_SERIAL_NUMBER
#define UTILIZATION_L_SPAGE
#define SCSI_PT_SEQUENTIAL_ACCESS
#define ENVIRO_REP_L_SPAGE
#define NO_SUBPAGE_L_SPAGE
#define SCSI_PT_HOST_MANAGED
#define ZB_DEV_STATS_L_SPAGE
#define FORMAT_STATUS_LPAGE
#define SUPP_SPAGE_L_SPAGE
#define LOG_RESP_SELF_TEST_LEN
#define BACKGROUND_RESULTS_LPAGE
#define PROTOCOL_SPECIFIC_LPAGE
#define TEMPERATURE_LPAGE
#define WRITE_ERROR_COUNTER_LPAGE
#define SIMPLE_ERR_BAD_RESP
#define SCSI_PT_DIRECT_ACCESS
#define READ_ERROR_COUNTER_LPAGE
#define SEAGATE_FACTORY_LPAGE
#define BACKGROUND_OP_L_SPAGE
#define SEAGATE_FARM_CURRENT_L_SPAGE
#define GEN_STATS_PERF_LPAGE
#define DEVICE_STATS_LPAGE
#define STARTSTOP_CYCLE_COUNTER_LPAGE
#define SEAGATE_CACHE_LPAGE
static bool gFormatStatusLPage
static bool gSeagateFactoryLPage
static bool gEnviroLimitsLPage
static void scsiPrintTemp(scsi_device *device)
static int scsiPrintActiveTapeAlerts(scsi_device *device, int peripheral_type, bool from_health)
static void scsiPrintSeagateCacheLPage(scsi_device *device)
static void scsiGetSupportedLogPages(scsi_device *device)
static void show_sas_phy_event_info(const json::ref &jref, int peis, unsigned int val, unsigned thresh_val)
static std::string rtrim(const std::string &s, const char *t=" \t\n\r\f\v")
static int scsiGetDriveInfo(scsi_device *device, uint8_t *peripheral_type, bool &have_zbc, bool all)
static bool gBackgroundResultsLPage
#define T10_VENDOR_HITACHI_2
static bool gPendDefectsLPage
static int scsiPrintBackgroundResults(scsi_device *device, bool only_pow_time)
const char * scsiprint_c_cvsid
static const char * bms_status[]
static const char * zbds_s
#define SCSI_VERSION_HIGHEST
#define T10_VENDOR_HITACHI_3
static int scsiPrintSelfTest(scsi_device *device)
static bool gLPSMisalignLPage
#define LOG_RESP_TAPE_ALERT_LEN
static char scsi_vendor[8+1]
#define T10_VENDOR_SEAGATE
static const char * self_test_result[]
#define LOG_RESP_LONG_LEN
static bool gSSMediaLPage
static const char * reassign_status[]
static int scsiPrintFormatStatus(scsi_device *device)
static bool gTapeDeviceStatsLPage
static bool gGenStatsAndPerfLPage
static int show_protocol_specific_port_page(unsigned char *resp, int len)
static bool gStartStopLPage
static void scsiPrintErrorCounterLog(scsi_device *device)
static const char * logSenRspStr
static void scsiPrintPendingDefectsLPage(scsi_device *device)
static bool gUtilizationLPage
static bool gSeagateCacheLPage
static bool gTapeAlertsLPage
static int scsiPrintGStatsPerf(scsi_device *device)
static bool gSelfTestLPage
static void scsiPrintGrownDefectListLen(scsi_device *device, bool prefer12)
static bool gSeagateFarmLPage
static uint64_t variableLengthIntegerParam(const unsigned char *ucp)
static int scsiGetSmartData(scsi_device *device, bool attribs)
static const char * peripheral_dt_arr[32]
static bool gZBDeviceStatsLPage
static void show_sas_port_param(int port_num, unsigned char *ucp, int param_len)
static int scsiSmartEnable(scsi_device *device)
static bool gReadECounterLPage
static const char * transport_proto_arr[]
static void scsiPrintSeagateFactoryLPage(scsi_device *device)
static bool gEnviroReportingLPage
#define SCSI_VERSION_SPC_4
static const char *const severities
static void scsiPrintEnviroReporting(scsi_device *device)
#define T10_VENDOR_HITACHI_1
static int scsiPrintTapeDeviceStats(scsi_device *device)
static bool gProtocolSpecificLPage
#define SCSI_SUPP_LOG_PAGES_MAX_COUNT
static const char * logSenStr
static const char * ssm_s
static bool gBackgroundOpLPage
static const char * gsap_s
static int scsiPrintSSMedia(scsi_device *device)
static int scsiPrintSasPhy(scsi_device *device, int reset)
static bool gVerifyECounterLPage
static int64_t scsiGetTimeUnitInNano(const uint8_t *ucp, int num, uint16_t ti_pc)
static const char * self_test_code[]
static bool gNonMediumELPage
static int scsiSmartDisable(scsi_device *device)
static bool all_ffs(const uint8_t *bp, int b_len)
static void scsiGetStartStopData(scsi_device *device)
static bool gLastNErrorEvLPage
static bool gWriteECounterLPage
int scsiPrintMain(scsi_device *device, const scsi_print_options &options)
static bool seagate_or_hitachi(void)
static void scsiPrintTimeUnitInNano(int leadin_spaces, uint64_t intervals, int64_t timeUnitInNS)
static int scsiPrintZBDeviceStats(scsi_device *device)
#define SCSIPRINT_H_CVSID
static uint64_t sg_get_unaligned_be64(const void *p)
static uint64_t sg_get_unaligned_be(int num_bytes, const void *p)
static uint16_t sg_get_unaligned_be16(const void *p)
static uint32_t sg_get_unaligned_be32(const void *p)
void jout_startup_datetime(const char *prefix)
void failuretest(failure_type type, int returnvalue)
void void jinf(const char *fmt,...) __attribute_format_printf(1
void jout(const char *fmt,...) __attribute_format_printf(1
void pout(const char *fmt,...)
bool smart_background_log
bool smart_selftest_abort
bool smart_auto_save_disable
bool smart_selftest_force
bool smart_default_selftest
bool smart_short_cap_selftest
bool smart_short_selftest
bool smart_extend_cap_selftest
bool smart_extend_selftest
bool smart_auto_save_enable
bool scsi_pending_defects
bool general_stats_and_perf
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,...)