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;
497 static const char * jname =
"scsi_start_stop_cycle_counter";
514 for (k = len; k > 0; k -= extra, ucp += extra) {
524 bool is_all_ffs = (extra > 7) ?
all_ffs(ucp + 4, 4) :
false;
528 jout(
"Manufactured in week %.2s of year %.4s\n", ucp + 8,
530 snprintf(
b,
sizeof(
b),
"%.4s", ucp + 4);
531 jglb[jname][
"year_of_manufacture"] =
b;
532 snprintf(
b,
sizeof(
b),
"%.2s", ucp + 8);
533 jglb[jname][
"week_of_manufacture"] =
b;
540 if ((extra > 7) && (! is_all_ffs)) {
541 q =
"Specified cycle count over device lifetime";
542 jout(
"%s: %u\n", q, u);
547 if ((extra > 7) && (! is_all_ffs)) {
548 q =
"Accumulated start-stop cycles";
549 jout(
"%s: %u\n", q, u);
554 if ((extra > 7) && (! is_all_ffs)) {
555 q =
"Specified load-unload count over device lifetime";
556 jout(
"%s: %u\n", q, u);
561 if ((extra > 7) && (! is_all_ffs)) {
562 q =
"Accumulated load-unload cycles";
563 jout(
"%s: %u\n", q, u);
577 static const char * pDefStr =
"Pending Defects";
578 static const char * jname =
"scsi_pending_defects";
603 const uint8_t * bp =
gBuf + 4;
612 jout(
" Pending defect count:");
613 if ((pl < 8) || (num < 8)) {
615 pout(
"%s truncated descriptor\n", pDefStr);
622 jout(
"0 %s\n", pDefStr);
624 jout(
"1 Pending Defect, LBA and accumulated_power_on_hours "
627 jout(
"%u %s: index, LBA and accumulated_power_on_hours "
628 "follow\n",
count, pDefStr);
631 if ((pl < 16) || (num < 16)) {
633 pout(
"%s truncated descriptor\n", pDefStr);
639 jout(
" %4d: 0x%-16" PRIx64
", %5u\n", pc, lba, poh);
644 jref[
"accum_power_on_hours"] = poh;
658 unsigned int dl_len, div;
659 static const char * hname =
"Read defect list";
666 got_rd12 = (0 == err);
689 }
else if (101 == err)
707 pout(
"%s (12): generation=%d\n", hname, generation);
713 if (0x8 != (
gBuf[1] & 0x18)) {
715 pout(
"%s: asked for grown list but didn't get it\n", hname);
720 dl_format = (
gBuf[1] & 0x7);
739 pout(
"defect list format %d unknown\n", dl_format);
744 jout(
"Elements in grown defect list: 0\n\n");
745 jglb[
"scsi_grown_defect_list"] = 0;
749 pout(
"Grown defect list length=%u bytes [unknown "
750 "number of elements]\n\n", dl_len);
752 jout(
"Elements in grown defect list: %u\n\n", dl_len / div);
753 jglb[
"scsi_grown_defect_list"] = dl_len / div;
761 static const size_t sz_u64 = (int)
sizeof(uint64_t);
762 unsigned int u = ucp[3];
763 const unsigned char * xp = ucp + 4;
775 int num, pl, pc, err, len;
777 static const char * seaCacStr =
"Seagate Cache";
804 case 0:
case 1:
case 2:
case 3:
case 4:
809 pout(
"Vendor (%s) lpage has unexpected parameter, skip\n",
818 pout(
"Vendor (%s) information\n", seaCacStr);
825 case 0:
pout(
" Blocks sent to initiator");
break;
826 case 1:
pout(
" Blocks received from initiator");
break;
827 case 2:
pout(
" Blocks read from cache and sent to initiator");
break;
828 case 3:
pout(
" Number of read and write commands whose size "
829 "<= segment size");
break;
830 case 4:
pout(
" Number of read and write commands whose size "
831 "> segment size");
break;
832 default:
pout(
" Unknown Seagate parameter code [0x%x]", pc);
break;
844 int num, pl, pc, len, err, good, bad;
884 if ((good < 2) || (bad > 4)) {
887 pout(
"\nVendor (Seagate/Hitachi) factory lpage has too many "
888 "unexpected parameters, skip\n");
893 pout(
"Vendor (Seagate/Hitachi) factory information\n");
901 case 0:
jout(
" number of hours powered up");
904 case 8:
pout(
" number of minutes until next internal SMART test");
910 pout(
"Vendor (Seagate/Hitachi) factory lpage: "
911 "unknown parameter code [0x%x]\n", pc);
919 jout(
" = %.2f\n", ull / 60.0 );
920 jglb[
"power_on_time"][
"hours"] = ull / 60;
921 jglb[
"power_on_time"][
"minutes"] = ull % 60;
924 pout(
" = %" PRIu64
"\n", ull);
937 int found[3] = {0, 0, 0};
952 ecp = &errCounterArr[2];
953 for (
int k = 0; k < 7; ++k) {
960 if (found[0] || found[1] || found[2]) {
961 pout(
"Error counter log:\n");
962 pout(
" Errors Corrected by Total "
963 "Correction Gigabytes Total\n");
964 pout(
" ECC rereads/ errors "
965 "algorithm processed uncorrected\n");
966 pout(
" fast | delayed rewrites corrected "
967 "invocations [10^9 bytes] errors\n");
970 for (
int k = 0; k < 3; ++k) {
973 ecp = &errCounterArr[k];
974 static const char *
const pageNames[3] =
975 {
"read: ",
"write: ",
"verify: "};
976 static const char * jpageNames[3] =
977 {
"read",
"write",
"verify"};
978 jout(
"%s%8" PRIu64
" %8" PRIu64
" %8" PRIu64
" %8" PRIu64
979 " %8" PRIu64, pageNames[k], ecp->
counter[0],
982 double processed_gb = ecp->
counter[5] / 1000000000.0;
983 jout(
" %12.3f %8" PRIu64
"\n", processed_gb,
986 jref[jpageNames[k]][
"errors_corrected_by_eccfast"] = ecp->
counter[0];
987 jref[jpageNames[k]][
"errors_corrected_by_eccdelayed"] = ecp->
counter[1];
988 jref[jpageNames[k]][
"errors_corrected_by_rereads_rewrites"] = ecp->
counter[2];
989 jref[jpageNames[k]][
"total_errors_corrected"] = ecp->
counter[3];
990 jref[jpageNames[k]][
"correction_algorithm_invocations"] = ecp->
counter[4];
991 jref[jpageNames[k]][
"gigabytes_processed"] =
strprintf(
"%.3f", processed_gb);
992 jref[jpageNames[k]][
"total_uncorrected_errors"] = ecp->
counter[6];
996 pout(
"Error Counter logging not supported\n");
1002 pout(
"\nNon-medium error count: %8" PRIu64
"\n", nme.
counterPC0);
1004 pout(
"Track following error count [Hitachi]: %8" PRIu64
"\n",
1007 pout(
"Positioning error count [Hitachi]: %8" PRIu64
"\n",
1017 unsigned char * ucp =
gBuf + 4;
1020 pout(
"\nNo error events logged\n");
1022 pout(
"\nLast n error events %s\n",
lp_s);
1023 for (
int k = num, pl; k > 0; k -= pl, ucp += pl) {
1025 pout(
" <<short Last n error events %s>>\n",
lp_s);
1031 if ((ucp[2] & 0x1) && (ucp[2] & 0x2)) {
1032 pout(
" Error event %d:\n", pc);
1033 pout(
" [binary]:\n");
1034 dStrHex((
const uint8_t *)ucp + 4, pl - 4, 1);
1035 }
else if (ucp[2] & 0x1) {
1036 pout(
" Error event %d:\n", pc);
1037 pout(
" %.*s\n", pl - 4, (
const char *)(ucp + 4));
1040 pout(
" Error event %d:\n", pc);
1041 pout(
" [data counter??]:\n");
1042 dStrHex((
const uint8_t *)ucp + 4, pl - 4, 1);
1048 pout(
" >>>> log truncated, fetched %d of %d available "
1068 "Aborted (by user command)",
1069 "Aborted (device reset ?) ",
1070 "Unknown error, incomplete",
1071 "Completed, segment failed",
1072 "Failed in first segment ",
1073 "Failed in second segment ",
1074 "Failed in segment",
1082 "Self test in progress ..."
1092 bool noheader =
true;
1093 int num, k, err, durationSec;
1097 static const char * hname =
"Self-test";
1098 static const char * fixup_stres7 =
" --> ";
1102 (sense_info.
asc == 0x04 && sense_info.
ascq == 0x09 &&
1104 pout(
"%s execution status:\t\t%d%% of test remaining\n", hname,
1105 100 - ((sense_info.
progress * 100) / 65535));
1126 pout(
"%s %s length is 0x%x not 0x190 bytes\n", hname,
logSenStr, num);
1131 for (k = 0, ucp =
gBuf + 4; k < 20; ++k, ucp += 20 ) {
1137 snprintf(st,
sizeof(st),
"scsi_self_test_%d", k);
1140 if ((0 == poh) && (0 == ucp[4]))
1145 jout(
"SMART %s log\n", hname);
1146 jout(
"Num Test Status segment "
1147 "LifeTime LBA_first_err [SK ASC ASQ]\n");
1148 jout(
" Description number "
1154 u = (ucp[4] >> 5) & 0x7;
1156 jglb[st][
"code"][
"value"] = u;
1193 jglb[st][
"result"][
"value"] = tr;
1205 jglb[st][
"failed_segment"][
"value"] = u;
1206 jglb[st][
"failed_segment"][
"aka"] =
"self_test_number";
1211 if (poh==0 && tr==0xf) {
1214 jglb[st][
"self_test_in_progress"] =
true;
1217 jglb[st][
"power_on_time"][
"hours"] = poh;
1218 jglb[st][
"power_on_time"][
"aka"] =
"accumulated_power_on_hours";
1223 bool is_all_ffs =
all_ffs(ucp + 8, 8);
1225 if ((! is_all_ffs) && (tr > 0) && (tr < 0xf)) {
1229 snprintf(buff,
sizeof(buff),
"%" PRIu64, ull);
1232 jglb[st][
"lba_first_failure"][
"value"] = ull;
1233 jglb[st][
"lba_first_failure"][
"aka"] =
"address_of_first_failure";
1239 if (ucp[16] & 0xf) {
1242 jout(
" [0x%x 0x%x 0x%x]\n", ucp[16] & 0xf, ucp[17], ucp[18]);
1244 jglb[st][
"sense_key"][
"value"] = u;
1245 jglb[st][
"sense_key"][
"string"] =
1247 jglb[st][
"asc"] = ucp[17];
1248 jglb[st][
"ascq"] = ucp[18];
1249 jglb[st][
"vendor_specific"] = ucp[19];
1256 jout(
"No %ss have been logged\n", hname);
1259 if (durationSec > 14400)
1260 jout(
"\nLong (extended) %s duration: %d seconds "
1261 "[%.1f hours]\n", hname, durationSec, durationSec / 3600.0);
1263 jout(
"\nLong (extended) %s duration: %d seconds "
1264 "[%.1f minutes]\n", hname, durationSec, durationSec / 60.0);
1265 jglb[
"scsi_extended_self_test_seconds"] = durationSec;
1274 "pre-scan is active",
1275 "halted due to fatal error",
1276 "halted due to a vendor specific pattern of error",
1277 "halted due to medium formatted without P-List",
1278 "halted - vendor specific cause",
1279 "halted due to temperature out of range",
1280 "waiting until BMS interval timer expires",
1285 "Require Write or Reassign Blocks command",
1286 "Successfully reassigned",
1288 "Reassignment by disk failed",
1289 "Recovered via rewrite in-place",
1290 "Reassigned by app, has valid data",
1291 "Reassigned by app, has no valid data",
1292 "Unsuccessfully reassigned by app",
1304 bool noheader =
true;
1305 bool firstresult =
true;
1306 int num, j, m, err, truncated;
1313 static const char * hname =
"Background scan results";
1314 static const char * jname =
"scsi_background_scan";
1332 if (! only_pow_time) {
1334 pout(
"%s %s length is %d, no scan status\n", hname,
logSenStr,
1348 int pl = ucp[3] + 4;
1353 if (! only_pow_time)
1354 jout(
"%s log\n", hname);
1356 if (! only_pow_time)
1358 if ((pl < 16) || (num < 16)) {
1359 if (! only_pow_time)
1364 if (! only_pow_time) {
1367 jglb[jname][
"status"][
"value"] = j;
1370 jout(
"unknown [0x%x] background scan status value\n", j);
1371 jglb[jname][
"status"][
"value"] = j;
1375 jout(
"%sAccumulated power on time, hours:minutes %d:%02d",
1376 (only_pow_time ?
"" :
" "), (j / 60), (j % 60));
1380 jout(
" [%d minutes]\n", j);
1381 jglb[
"power_on_time"][
"hours"] = j / 60;
1382 jglb[
"power_on_time"][
"minutes"] = j % 60;
1386 jout(
" Number of background scans performed: %u, ", u);
1387 jglb[jname][
"status"][
"number_scans_performed"] = u;
1389 snprintf(
b,
sizeof(
b),
"%.2f%%", (
double)u * 100.0 / 65536.0);
1390 jout(
"scan progress: %s\n",
b);
1391 jglb[jname][
"status"][
"scan_progress"] =
b;
1393 jout(
" Number of background medium scans performed: %d\n", u);
1394 jglb[jname][
"status"][
"number_medium_scans_performed"] = u;
1399 if (! only_pow_time)
1400 jout(
"\n%s log\n", hname);
1406 jout(
"\n # when lba(hex) [sk,asc,ascq] "
1407 "reassign_status\n");
1409 snprintf(res_s,
sizeof(res_s),
"result_%d", pc);
1411 jglb[jname][res_s][
"parameter_code"] = pc;
1412 if ((pl < 24) || (num < 24)) {
1414 jout(
"parameter length >= 24 expected, got %d\n", pl);
1418 jout(
"%4u:%02u ", (u / 60), (u % 60));
1419 jglb[jname][res_s][
"accumulated_power_on"][
"minutes"] = u;
1420 for (m = 0; m < 8; ++m)
1421 jout(
"%02x", ucp[16 + m]);
1423 jglb[jname][res_s][
"lba"] = lba;
1425 jout(
" [%x,%x,%x] ", u, ucp[9], ucp[10]);
1426 jglb[jname][res_s][
"sense_key"][
"value"] = u;
1427 jglb[jname][res_s][
"sense_key"][
"string"] =
1429 jglb[jname][res_s][
"asc"] = ucp[9];
1430 jglb[jname][res_s][
"ascq"] = ucp[10];
1431 u = (ucp[8] >> 4) & 0xf;
1434 jglb[jname][res_s][
"reassign_status"][
"value"] = u;
1435 jglb[jname][res_s][
"reassign_status"][
"string"] =
1438 jout(
"Reassign status: reserved [0x%x]\n", u);
1439 jglb[jname][res_s][
"reassign_status"][
"value"] = u;
1446 if (truncated && (! only_pow_time))
1447 jout(
" >>>> log truncated, fetched %d of %d available "
1450 if (! only_pow_time)
1459 uint16_t loop_pc, pl;
1460 uint32_t a_exp, a_int, casc;
1467 if (loop_pc == ti_pc) {
1471 pout(
"%s Time interval log parameter too short (pl=%d)\n",
1504 int64_t timeUnitInNS)
1506 if ((intervals > 0) && (timeUnitInNS > 0)) {
1507 intervals *= timeUnitInNS;
1508 intervals /= 1000000;
1509 jout(
"%*cin seconds: %" PRIu64
".%03" PRIu64
"\n",
1510 leadin_spaces,
' ', intervals / 1000, intervals % 1000);
1511 if (intervals > 3600000) {
1513 jout(
"%*cin hours: %" PRIu64
".%03" PRIu64
"\n",
1514 leadin_spaces,
' ', intervals / 1000, intervals % 1000);
1524 int num, err, truncated;
1526 int64_t timeUnitInNS;
1531 json::ref jref =
jglb[
"scsi_general_statistics_and_performance_log"];
1532 json::ref jref1 = jref[
"general_access"];
1534 json::ref jref3 = jref[
"time_interval"];
1536 static const char * p1name =
"General access statistics and performance";
1537 static const char * p2name =
"Idle time";
1538 static const char * p3name =
"Time interval";
1539 static const char * p4name =
"Force Unit Access statistics and "
1570 if (timeUnitInNS < 0) {
1573 pout(
"%s unable to decode time unit [%d]\n",
gsap_s,
1583 int pl = ucp[3] + 4;
1587 if (pl < 0x40 + 4) {
1589 pout(
"%s %s log parameter too short (pl=%d)\n",
gsap_s,
1594 jout(
" %s:\n", p1name);
1595 ccp =
"Number of read commands";
1597 jout(
" %s: %" PRIu64
"\n", ccp, ull);
1599 ccp =
"Number of write commands";
1601 jout(
" %s: %" PRIu64
"\n", ccp, ull);
1603 ccp =
"number of logical blocks received";
1605 jout(
" %s: %" PRIu64
"\n", ccp, ull);
1607 ccp =
"number of logical blocks transmitted";
1609 jout(
" %s: %" PRIu64
"\n", ccp, ull);
1611 ccp =
"read command processing intervals";
1613 jout(
" %s: %" PRIu64
"\n", ccp, ull);
1616 ccp =
"write command processing intervals";
1618 jout(
" %s: %" PRIu64
"\n", ccp, ull);
1621 ccp =
"weighted number of read commands plus write commands";
1623 jout(
" %s: %" PRIu64
"\n", ccp, ull);
1625 ccp =
"weighted read command processing plus write command "
1629 jout(
" %s: %" PRIu64
"\n", ccp, ull);
1635 pout(
"%s %s log parameter too short (pl=%d)\n",
gsap_s,
1640 jout(
" %s:\n", p2name);
1641 ccp =
"Idle time intervals";
1643 jout(
" %s: %" PRIu64
"\n", ccp, ull);
1651 pout(
"%s %s log parameter too short (pl=%d)\n",
gsap_s,
1664 if (pl < 0x40 + 4) {
1666 pout(
"%s %s log parameter too short (pl=%d)\n",
gsap_s,
1671 jout(
" %s:\n", p4name);
1672 ccp =
"Number of read FUA commands";
1674 jout(
" %s: %" PRIu64
"\n", ccp, ull);
1676 ccp =
"Number of write FUA commands";
1678 jout(
" %s: %" PRIu64
"\n", ccp, ull);
1680 ccp =
"Number of read FUA_NV commands";
1682 jout(
" %s: %" PRIu64
"\n", ccp, ull);
1684 ccp =
"Number of write FUA_NV commands";
1686 jout(
" %s: %" PRIu64
"\n", ccp, ull);
1688 ccp =
"Number of read FUA intervals";
1690 jout(
" %s: %" PRIu64
"\n", ccp, ull);
1693 ccp =
"Number of write FUA intervals";
1695 jout(
" %s: %" PRIu64
"\n", ccp, ull);
1697 ccp =
"Number of read FUA_NV intervals";
1699 jout(
" %s: %" PRIu64
"\n", ccp, ull);
1702 ccp =
"Number of write FUA_NV intervals";
1704 jout(
" %s: %" PRIu64
"\n", ccp, ull);
1725 int num, err, truncated;
1759 int pl = ucp[3] + 4;
1764 pout(
"%s Percentage used endurance indicator parameter "
1765 "too short (pl=%d)\n",
ssm_s, pl);
1769 q =
"Percentage used endurance indicator";
1770 jout(
"%s: %d%%\n", q, ucp[7]);
1772 jglb[
"endurance_used"][
"current_percent"] = ucp[7];
1785 int num, err, truncated;
1790 static const char * jname =
"scsi_zoned_block_device_statistics";
1823 int pl = ucp[3] + 4;
1829 q =
"Maximum open zones";
1831 jout(
" %s: %u\n", q, u);
1835 q =
"Maximum explicitly open zones";
1837 jout(
" %s: %u\n", q, u);
1841 q =
"Maximum implicitly open zones";
1843 jout(
" %s: %u\n", q, u);
1847 q =
"Minimum empty zones";
1849 jout(
" %s: %u\n", q, u);
1853 q =
"Maximum nonseq zones";
1855 jout(
" %s: %u\n", q, u);
1859 q =
"Zones emptied";
1861 jout(
" %s: %u\n", q, u);
1865 q =
"Suboptimal write commands";
1867 jout(
" %s: %u\n", q, u);
1871 q =
"Commands exceeding optinmal limit";
1873 jout(
" %s: %u\n", q, u);
1877 q =
"Failed explicit opens";
1879 jout(
" %s: %u\n", q, u);
1883 q =
"Read rule violations";
1885 jout(
" %s: %u\n", q, u);
1889 q =
"Write rule violations";
1891 jout(
" %s: %u\n", q, u);
1895 q =
"Maximum implicitly open sequential or before required zones";
1897 jout(
" %s: %u\n", q, u);
1913 int num, err, truncated;
1919 static const char * hname =
"Device statistics (SSC, tape)";
1920 static const char * jname =
"scsi_device_statistics";
1941 pout(
"%s %s length is %d, too short\n", hname,
logSenStr, num);
1953 int pl = ucp[3] + 4;
1958 q =
"Lifetime volume loads";
1960 jout(
" %s: %" PRIu64
"\n", q, ull);
1964 q =
"Lifetime cleaning operations";
1966 jout(
" %s: %" PRIu64
"\n", q, ull);
1970 q =
"Lifetime power on hours";
1972 jout(
" %s: %" PRIu64
"\n", q, ull);
1976 q =
"Lifetime medium motion hours";
1978 jout(
" %s: %" PRIu64
"\n", q, ull);
1982 q =
"Lifetime meters of tape processed";
1984 jout(
" %s: %" PRIu64
"\n", q, ull);
1988 q =
"Lifetime medium motion hours at last incompatible volume "
1991 jout(
" %s: %" PRIu64
"\n", q, ull);
1995 q =
"Lifetime power on hours at last temperature condition "
1998 jout(
" %s: %" PRIu64
"\n", q, ull);
2002 q =
"Lifetime power on hours at last power consumption condition "
2005 jout(
" %s: %" PRIu64
"\n", q, ull);
2009 q =
"Medium motion hours since last successful cleaning "
2012 jout(
" %s: %" PRIu64
"\n", q, ull);
2016 q =
"Medium motion hours since second to last successful "
2017 "cleaning operation";
2019 jout(
" %s: %" PRIu64
"\n", q, ull);
2023 q =
"Medium motion hours since third to last successful "
2024 "cleaning operation";
2026 jout(
" %s: %" PRIu64
"\n", q, ull);
2030 q =
"Lifetime power on hours at last operator initiated forced "
2031 "reset and/or emergency eject occurrence";
2033 jout(
" %s: %" PRIu64
"\n", q, ull);
2037 q =
"Lifetime power cycles";
2039 jout(
" %s: %" PRIu64
"\n", q, ull);
2043 q =
"Volume loads since last parameter reset";
2045 jout(
" %s: %" PRIu64
"\n", q, ull);
2049 q =
"Hard write errors";
2051 jout(
" %s: %" PRIu64
"\n", q, ull);
2055 q =
"Hard read errors";
2057 jout(
" %s: %" PRIu64
"\n", q, ull);
2061 q =
"Duty cycle sample time";
2063 jout(
" %s: %" PRIu64
"\n", q, ull);
2067 q =
"Read duty cycle";
2069 jout(
" %s: %" PRIu64
"\n", q, ull);
2073 q =
"Write duty cycle";
2075 jout(
" %s: %" PRIu64
"\n", q, ull);
2079 q =
"Activity duty cycle";
2081 jout(
" %s: %" PRIu64
"\n", q, ull);
2085 q =
"Volume not present duty cycle";
2087 jout(
" %s: %" PRIu64
"\n", q, ull);
2091 q =
"Ready duty cycle";
2093 jout(
" %s: %" PRIu64
"\n", q, ull);
2097 q =
"Megabytes transferred from application client in duty cycle"
2100 jout(
" %s: %" PRIu64
"\n", q, ull);
2104 q =
"Megabytes transferred to application client in duty cycle"
2107 jout(
" %s: %" PRIu64
"\n", q, ull);
2112 std::string v((
const char *)(ucp + 4), ucp[3]);
2113 q =
"Drive manufacturer's serial number";
2114 jout(
" %s: %s\n", q, v.c_str());
2120 std::string v((
const char *)(ucp + 4), ucp[3]);
2121 q =
"Drive serial number";
2122 jout(
" %s: %s\n", q, v.c_str());
2128 std::string v((
const char *)(ucp + 4), ucp[3]);
2129 q =
"Manufacturing date year,month,day";
2130 jout(
" %s: %s\n", q, v.c_str());
2136 std::string v((
const char *)(ucp + 4), ucp[3]);
2137 q =
"Manufacturing date year,week";
2138 jout(
" %s: %s\n", q, v.c_str());
2144 std::string v((
const char *)(ucp + 4), ucp[3]);
2145 q =
"Manufacturing date year,week";
2146 jout(
" %s: %s\n", q, v.c_str());
2151 q =
"Medium removal prevented";
2153 jout(
" %s: %" PRIu64
"\n", q, ull);
2157 q =
"Maximum recommended mechanism temperature exceeded";
2159 jout(
" %s: %" PRIu64
"\n", q, ull);
2163 q =
"Medium motion hours for each medium type";
2166 jout(
" %s, number of element: %u\n", q, n);
2167 for (k = 0; k < n; ++k, ucp += 8) {
2169 jout(
" [%d] density code: %u, density code: %u, hours: "
2170 "%u\n", k + 1, ucp[6], ucp[7], u);
2171 jglb[jname][
s][k][
"density_code"] = ucp[6];
2172 jglb[jname][
s][k][
"medium_type"] = ucp[7];
2173 jglb[jname][
s][k][
"medium_motion_hours"] = u;
2188 bool all_not_avail =
false;
2189 int num, num_hold, err, truncated;
2193 static const char * hname =
"Format Status";
2194 static const char * jname =
"scsi_format_status";
2213 jout(
"%s %s length is %d, too short\n", hname,
logSenStr, num);
2225 all_not_avail =
true;
2228 int pl = ucp[3] + 4;
2237 if (!
all_ffs(ucp + 4, ucp[3]))
2238 all_not_avail =
false;
2243 if (! all_not_avail)
2248 if (all_not_avail) {
2249 jout(
"Format status indicates no format since manufacture\n");
2259 int pl = ucp[3] + 4;
2261 bool is_count =
true;
2262 const char * jout_str =
"";
2263 const char * jglb_str =
"x";
2268 jout(
"Format data out: <empty>\n");
2271 jout(
"Format data out: <not available>\n");
2273 jout(
"Format data out:\n");
2274 dStrHex((
const uint8_t *)ucp + 4, pl - 4, 0);
2281 jout_str =
"Grown defects during certification";
2282 jglb_str =
"grown_defects_during_cert";
2285 jout_str =
"Total blocks reassigned during format";
2286 jglb_str =
"blocks_reassigned_during_format";
2289 jout_str =
"Total new blocks reassigned";
2290 jglb_str =
"total_new_block_since_format";
2293 jout_str =
"Power on minutes since format";
2294 jglb_str =
"power_on_minutes_since_format";
2298 pout(
" Unknown Format parameter code = 0x%x\n", pc);
2299 dStrHex((
const uint8_t *)ucp, pl, 0);
2305 if (
all_ffs(ucp + 4, ucp[3])) {
2306 pout(
"%s <not available>\n", jout_str);
2309 jout(
"%s = %" PRIu64
"\n", jout_str, ull);
2310 jglb[jname][jglb_str] = ull;
2322 unsigned thresh_val)
2326 static const char * pvd_th =
"Peak value detector threshold";
2327 static const char * pvd_th_j =
"pvd_threshold";
2331 jout(
" No event\n");
2334 q =
"Invalid dword count";
2335 jout(
" %s: %u\n", q, val);
2336 jref[std::string(q) +
"_2"] = val;
2339 q =
"Running disparity error count";
2340 jout(
" %s: %u\n", q, val);
2341 jref[std::string(q) +
"_2"] = val;
2344 q =
"Loss of dword synchronization count";
2345 jout(
" %s: %u\n", q, val);
2346 jref[std::string(q) +
"_2"] = val;
2349 q =
"Phy reset problem count";
2350 jout(
" %s: %u\n", q, val);
2351 jref[std::string(q) +
"_2"] = val;
2354 q =
"Elasticity buffer overflow count";
2355 jout(
" %s: %u\n", q, val);
2359 q =
"Received ERROR count";
2360 jout(
" %s: %u\n", q, val);
2364 q =
"Received address frame error count";
2365 jout(
" %s: %u\n", q, val);
2369 q =
"Transmitted abandon-class OPEN_REJECT count";
2370 jout(
" %s: %u\n", q, val);
2374 q =
"Received abandon-class OPEN_REJECT count";
2375 jout(
" %s: %u\n", q, val);
2379 q =
"Transmitted retry-class OPEN_REJECT count";
2380 jout(
" %s: %u\n", q, val);
2384 q =
"Received retry-class OPEN_REJECT count";
2385 jout(
" %s: %u\n", q, val);
2389 q =
"Received AIP (WAITING ON PARTIAL) count";
2390 jout(
" %s: %u\n", q, val);
2394 q =
"Received AIP (WAITING ON CONNECTION) count";
2395 jout(
" %s: %u\n", q, val);
2399 q =
"Transmitted BREAK count";
2400 jout(
" %s: %u\n", q, val);
2404 q =
"Received BREAK count";
2405 jout(
" %s: %u\n", q, val);
2409 q =
"Break timeout count";
2410 jout(
" %s: %u\n", q, val);
2414 q =
"Connection count";
2415 jout(
" %s: %u\n", q, val);
2419 q =
"Peak transmitted pathway blocked";
2420 jout(
" %s count: %u\n", q, val & 0xff);
2421 jout(
" %s: %u\n", pvd_th, thresh_val & 0xff);
2422 jref[q][
"count"] = val & 0xff;
2423 jref[q][pvd_th_j] = thresh_val & 0xff;
2426 q =
"Peak transmitted arbitration wait time";
2429 jout(
" %s (us): %u\n", q, u);
2430 jref[std::string(q) +
"_us"][
"event"] = u;
2432 jout(
" %s (ms): %u\n", q, 33 + (u - 0x8000));
2433 jref[std::string(q) +
"_ms"][
"event"] = 33 + (u - 0x8000);
2435 u = thresh_val & 0xffff;
2437 jout(
" %s (us): %u\n", pvd_th, u);
2438 jref[std::string(q) +
"_us"][pvd_th_j] = u;
2440 jout(
" %s (ms): %u\n", pvd_th, 33 + (u - 0x8000));
2441 jref[std::string(q) +
"_ms"][pvd_th_j] = 33 + (u - 0x8000);
2445 q =
"Peak arbitration time";
2446 jout(
" %s (us): %u\n", q, val);
2447 jref[std::string(q) +
"_us"][
"event"] = val;
2448 jout(
" %s: %u\n", pvd_th, thresh_val);
2449 jref[std::string(q) +
"_us"][pvd_th_j] = thresh_val;
2452 q =
"Peak connection time";
2453 jout(
" %s (us): %u\n", q, val);
2454 jref[std::string(q) +
"_us"][
"event"] = val;
2455 jout(
" %s: %u\n", pvd_th, thresh_val);
2456 jref[std::string(q) +
"_us"][pvd_th_j] = thresh_val;
2459 q =
"Transmitted SSP frame count";
2460 jout(
" %s: %u\n", q, val);
2464 q =
"Received SSP frame count";
2465 jout(
" %s: %u\n", q, val);
2469 q =
"Transmitted SSP frame error count";
2470 jout(
" %s: %u\n", q, val);
2474 q =
"Received SSP frame error count";
2475 jout(
" %s: %u\n", q, val);
2479 q =
"Transmitted CREDIT_BLOCKED count";
2480 jout(
" %s: %u\n", q, val);
2484 q =
"Received CREDIT_BLOCKED count";
2485 jout(
" %s: %u\n", q, val);
2489 q =
"Transmitted SATA frame count";
2490 jout(
" %s: %u\n", q, val);
2494 q =
"Received SATA frame count";
2495 jout(
" %s: %u\n", q, val);
2499 q =
"SATA flow control buffer overflow count";
2500 jout(
" %s: %u\n", q, val);
2504 q =
"Transmitted SMP frame count";
2505 jout(
" %s: %u\n", q, val);
2509 q =
"Received SMP frame count";
2510 jout(
" %s: %u\n", q, val);
2514 q =
"Received SMP frame error count";
2515 jout(
" %s: %u\n", q, val);
2526 int k, j, m, nphys, t, sz, spld_len;
2528 unsigned char * vcp;
2532 snprintf(pn,
sizeof(pn),
"scsi_sas_port_%d", port_num);
2536 jout(
"relative target port id = %d\n", t);
2537 jglb[pn][
"relative_target_port_id"] = t;
2538 jout(
" generation code = %d\n", ucp[6]);
2539 jglb[pn][
"generation_code"] = ucp[6];
2541 jout(
" number of phys = %d\n", nphys);
2542 jglb[pn][
"number_of_phys"] = nphys;
2544 for (j = 0, k = 0, vcp = ucp + 8; j < (param_len - 8);
2545 vcp += spld_len, j += spld_len, ++k) {
2548 snprintf(yn,
sizeof(yn),
"phy_%d", k);
2550 jout(
" phy identifier = %d\n", vcp[1]);
2551 jref[
"identifier"] = vcp[1];
2557 t = ((0x70 & vcp[4]) >> 4);
2559 case 0: snprintf(
s, sz,
"no device attached");
break;
2560 case 1: snprintf(
s, sz,
"SAS or SATA device");
break;
2561 case 2: snprintf(
s, sz,
"expander device");
break;
2562 case 3: snprintf(
s, sz,
"expander device (fanout)");
break;
2563 default: snprintf(
s, sz,
"reserved [%d]", t);
break;
2565 q =
"attached device type";
2566 jout(
" %s: %s\n", q,
s);
2570 case 0: snprintf(
s, sz,
"unknown");
break;
2571 case 1: snprintf(
s, sz,
"power on");
break;
2572 case 2: snprintf(
s, sz,
"hard reset");
break;
2573 case 3: snprintf(
s, sz,
"SMP phy control function");
break;
2574 case 4: snprintf(
s, sz,
"loss of dword synchronization");
break;
2575 case 5: snprintf(
s, sz,
"mux mix up");
break;
2576 case 6: snprintf(
s, sz,
"I_T nexus loss timeout for STP/SATA");
2578 case 7: snprintf(
s, sz,
"break timeout timer expired");
break;
2579 case 8: snprintf(
s, sz,
"phy test function stopped");
break;
2580 case 9: snprintf(
s, sz,
"expander device reduced functionality");
2582 default: snprintf(
s, sz,
"reserved [0x%x]", t);
break;
2584 q =
"attached reason";
2585 jout(
" %s: %s\n", q,
s);
2587 t = (vcp[5] & 0xf0) >> 4;
2589 case 0: snprintf(
s, sz,
"unknown");
break;
2590 case 1: snprintf(
s, sz,
"power on");
break;
2591 case 2: snprintf(
s, sz,
"hard reset");
break;
2592 case 3: snprintf(
s, sz,
"SMP phy control function");
break;
2593 case 4: snprintf(
s, sz,
"loss of dword synchronization");
break;
2594 case 5: snprintf(
s, sz,
"mux mix up");
break;
2595 case 6: snprintf(
s, sz,
"I_T nexus loss timeout for STP/SATA");
2597 case 7: snprintf(
s, sz,
"break timeout timer expired");
break;
2598 case 8: snprintf(
s, sz,
"phy test function stopped");
break;
2599 case 9: snprintf(
s, sz,
"expander device reduced functionality");
2601 default: snprintf(
s, sz,
"reserved [0x%x]", t);
break;
2604 jout(
" %s: %s\n", q,
s);
2608 case 0: snprintf(
s, sz,
"phy enabled; unknown");
2610 case 1: snprintf(
s, sz,
"phy disabled");
break;
2611 case 2: snprintf(
s, sz,
"phy enabled; speed negotiation failed");
2613 case 3: snprintf(
s, sz,
"phy enabled; SATA spinup hold state");
2615 case 4: snprintf(
s, sz,
"phy enabled; port selector");
2617 case 5: snprintf(
s, sz,
"phy enabled; reset in progress");
2619 case 6: snprintf(
s, sz,
"phy enabled; unsupported phy attached");
2621 case 8: snprintf(
s, sz,
"phy enabled; 1.5 Gbps");
break;
2622 case 9: snprintf(
s, sz,
"phy enabled; 3 Gbps");
break;
2623 case 0xa: snprintf(
s, sz,
"phy enabled; 6 Gbps");
break;
2624 case 0xb: snprintf(
s, sz,
"phy enabled; 12 Gbps");
break;
2625 default: snprintf(
s, sz,
"reserved [%d]", t);
break;
2627 q =
"negotiated logical link rate";
2628 jout(
" %s: %s\n", q,
s);
2630 q =
"attached initiator port";
2631 jout(
" %s: ssp=%d stp=%d smp=%d\n", q,
2632 !! (vcp[6] & 8), !! (vcp[6] & 4), !! (vcp[6] & 2));
2633 snprintf(
s, sz,
"%03d", ((vcp[6] & 8) ? 100 : 0) +
2634 ((vcp[6] & 4) ? 10 : 0) + ((vcp[6] & 2) ? 1 : 0));
2635 jref[q][
"ssp_stp_smp"] =
s;
2636 q =
"attached target port";
2637 jout(
" %s: ssp=%d stp=%d smp=%d\n", q,
2638 !! (vcp[7] & 8), !! (vcp[7] & 4), !! (vcp[7] & 2));
2639 snprintf(
s, sz,
"%03d", ((vcp[7] & 8) ? 100 : 0) +
2640 ((vcp[7] & 4) ? 10 : 0) + ((vcp[7] & 2) ? 1 : 0));
2641 jref[q][
"ssp_stp_smp"] =
s;
2646 snprintf(
b,
sizeof(
b),
"0x%" PRIx64, ull);
2648 jout(
" %s = %s\n", q,
b);
2651 snprintf(
b,
sizeof(
b),
"0x%" PRIx64, ull);
2652 q =
"attached SAS address";
2653 jout(
" %s = %s\n", q,
b);
2656 q =
"attached phy identifier";
2657 jout(
" %s = %d\n", q, vcp[24]);
2661 q =
"Invalid DWORD count";
2662 jout(
" %s = %u\n", q, ui);
2665 q =
"Running disparity error count";
2666 jout(
" %s = %u\n", q, ui);
2669 q =
"Loss of DWORD synchronization count";
2670 jout(
" %s = %u\n", q, ui);
2673 q =
"Phy reset problem count";
2674 jout(
" %s = %u\n", q, ui);
2676 if (spld_len > 51) {
2677 bool header_given =
false;
2680 unsigned char * xcp;
2684 for (m = 0; m < (num_ped * 12); m += 12, xcp += 12) {
2691 if (allow_dupl || (peis > 0x4)) {
2692 if (! header_given) {
2693 header_given =
true;
2694 jout(
" Phy event descriptors:\n");
2708 unsigned char * ucp;
2711 for (k = 0, j = 0, ucp = resp + 4; k < num; ++j) {
2712 int param_len = ucp[3] + 4;
2716 jout(
"\nProtocol Specific port %s for SAS SSP\n",
lp_s);
2732 static const char * hname =
"Protocol specific port";
2752 pout(
"Only support %s %s on SAS devices\n\n", hname,
lp_s);
2760 pout(
"%s Log Select (reset) Failed [%s]\n\n", __func__,
2786 "optical card reader",
2788 "object based storage",
2789 "automation/driver interface",
2790 "security manager device",
2791 "host managed zoned block device",
2801 "well known logical unit",
2802 "unknown or no device type",
2807 "Fibre channel (FCP-4)",
2808 "Parallel SCSI (SPI-4)",
2810 "IEEE 1394 (SBP-3)",
2828 bool & have_zbc,
bool all)
2831 bool is_tape =
false;
2832 int err, iec_err, len, req_len, avail_len;
2835 int form_factor = 0;
2841 memset(
gBuf, 0, 96);
2847 pout(
"Retrying with a 64 byte Standard Inquiry\n");
2853 pout(
"Standard Inquiry (64 bytes) failed [%s]\n",
2859 avail_len =
gBuf[4] + 5;
2860 len = (avail_len < req_len) ? avail_len : req_len;
2861 peri_dt =
gBuf[0] & 0x1f;
2862 *peripheral_type = peri_dt;
2871 pout(
"Short INQUIRY response, skip product id\n");
2879 if (all && (0 != strncmp((
char *)&
gBuf[8],
"ATA", 3))) {
2880 char product[16+1], revision[4+1];
2884 char model_name[
sizeof(
scsi_vendor) +
sizeof(product)];
2885 snprintf(model_name,
sizeof(model_name),
"%s%s%s",
2888 pout(
"=== START OF INFORMATION SECTION ===\n");
2891 jout(
"Product: %.16s\n", product);
2892 jglb[
"scsi_product"] = product;
2893 jglb[
"model_name"] = model_name;
2894 jglb[
"scsi_model_name"] = model_name;
2895 if (
gBuf[32] >=
' ') {
2896 jout(
"Revision: %.4s\n", revision);
2898 jglb[
"scsi_revision"] = revision;
2903 snprintf(sv_arr,
sizeof(sv_arr),
"SPC-%d",
scsi_version - 2);
2904 jout(
"Compliance: %s\n", sv_arr);
2905 jglb[
"scsi_version"] = sv_arr;
2910 (0 == strncmp((
char *)&
gBuf[8],
"ATA", 3))) {
2911 pout(
"\nProbable ATA device behind a SAT layer\n"
2912 "Try an additional '-d ata' or '-d sat' argument.\n");
2918 protect =
gBuf[5] & 0x1;
2924 unsigned char lb_prov_resp[8];
2927 static const char * lb_prov_j =
"scsi_lb_provisioning";
2930 char cap_str[64], si_str[64];
2933 jout(
"User Capacity: %s bytes [%s]\n", cap_str, si_str);
2935 jglb[
"user_capacity"][
"blocks"].set_unsafe_uint64(capacity /
2937 jglb[
"user_capacity"][
"bytes"].set_unsafe_uint64(capacity);
2938 jout(
"Logical block size: %u bytes\n", srr.
lb_size);
2943 jout(
"Physical block size: %u bytes\n", pb_size);
2944 jglb[
"physical_block_size"] = pb_size;
2951 pout(
"Formatted with type 1 protection\n");
2954 pout(
"Formatted with type 2 protection\n");
2957 pout(
"Formatted with type 3 protection\n");
2960 pout(
"Formatted with unknown protection type [%d]\n",
2965 unsigned p_i_per_lb = (1 << srr.
p_i_exp);
2966 const unsigned pi_sz = 8;
2969 if (p_i_per_lb > 1) {
2970 jout(
"%d protection information intervals per "
2971 "logical block\n", p_i_per_lb);
2974 jout(
"%d bytes of protection information per logical "
2975 "block\n", pi_sz * p_i_per_lb);
2976 jglb[
"scsi_protection_interval_bytes_per_lb"] =
2988 lb_prov_resp,
sizeof(lb_prov_resp))) {
2989 int prov_type = lb_prov_resp[6] & 0x7;
2990 int vpd_lbprz = ((lb_prov_resp[5] >> 2) & 0x7);
2994 else if ((0 == vpd_lbprz) && (1 ==
lbprz))
2998 switch (prov_type) {
3001 jout(
"LU is fully provisioned");
3002 jglb[lb_prov_j][
"name"] =
"fully provisioned";
3008 jout(
"LB provisioning type: not reported [LBPME=1, "
3009 "LBPRZ=%d]\n",
lbprz);
3010 jglb[lb_prov_j][
"name"] =
"not reported";
3014 jout(
"LU is resource provisioned, LBPRZ=%d\n",
lbprz);
3015 jglb[lb_prov_j][
"name"] =
"resource provisioned";
3018 jout(
"LU is thin provisioned, LBPRZ=%d\n",
lbprz);
3019 jglb[lb_prov_j][
"name"] =
"thin provisioned";
3022 jout(
"LU provisioning type reserved [%d], LBPRZ=%d\n",
3024 jglb[lb_prov_j][
"name"] =
"reserved";
3027 jglb[lb_prov_j][
"value"] = prov_type;
3028 jglb[lb_prov_j][
"management_enabled"][
"name"] =
"LBPME";
3029 jglb[lb_prov_j][
"management_enabled"][
"value"] =
lbpme;
3030 jglb[lb_prov_j][
"read_zeros"][
"name"] =
"LBPRZ";
3031 jglb[lb_prov_j][
"read_zeros"][
"value"] =
lbprz;
3032 }
else if (1 ==
lbpme) {
3034 jout(
"rcap_16 sets LBPME but no LB provisioning VPD page\n");
3035 jout(
"Logical block provisioning enabled, LBPRZ=%d\n",
lbprz);
3043 jout(
"Rotation Rate: Solid State Device\n");
3044 else if ((rpm <= 0x400) || (0xffff == rpm))
3047 jout(
"Rotation Rate: %d rpm\n", rpm);
3048 jglb[
"rotation_rate"] = (rpm == 1 ? 0 : rpm);
3050 if (form_factor > 0) {
3051 const char * cp =
nullptr;
3053 switch (form_factor) {
3070 jglb[
"form_factor"][
"scsi_value"] = form_factor;
3072 jout(
"Form Factor: %s inches\n", cp);
3078 q =
"Host aware zoned block capable";
3081 }
else if (haw_zbc == 2) {
3083 q =
"Device managed zoned block capable";
3102 pout(
">> Terminate command early due to bad response to IEC "
3118 if (strlen(
s) > 0) {
3119 jout(
"Logical Unit id: %s\n",
s);
3120 jglb[
"logical_unit_id"] =
s;
3125 pout(
"Vital Product Data (VPD) bit ignored in INQUIRY\n");
3127 pout(
"Vital Product Data (VPD) INQUIRY failed [%d]\n", err);
3135 gBuf[4 + len] =
'\0';
3137 jout(
"Serial number: %s\n", serial);
3138 jglb[
"serial_number"] = serial;
3142 pout(
"Vital Product Data (VPD) bit ignored in INQUIRY\n");
3144 pout(
"Vital Product Data (VPD) INQUIRY failed [%d]\n", err);
3150 jglb[
"device_type"][
"scsi_terminology"] =
"Peripheral Device Type [PDT]";
3151 jglb[
"device_type"][
"scsi_value"] = peri_dt;
3157 jout(
"Device type: <%d>\n", peri_dt);
3162 if ((transport >= 0) && (transport <= 0xf)) {
3165 jglb[
"scsi_transport_protocol"][
"value"] = transport;
3175 pout(
"device is NOT READY (e.g. spun down, busy)\n");
3177 pout(
"device is NOT READY (e.g. no tape)\n");
3182 pout(
"NO tape present in drive\n");
3184 pout(
"NO MEDIUM present in device\n");
3188 pout(
"device becoming ready (wait)\n");
3204 jout(
"SMART support is: Unavailable - device lacks SMART "
3206 jglb[
"smart_support"][
"available"] =
false;
3217 jout(
"SMART support is: Available - device has SMART capability.\n"
3218 "SMART support is: %s\n", ok ?
"Enabled" :
"Disabled");
3219 jglb[
"smart_support"][
"available"] =
true;
3220 jglb[
"smart_support"][
"enabled"] = ok;
3223 jout(
"Temperature Warning: %s\n",
3224 ok ?
"Enabled" :
"Disabled or Not Supported");
3225 jglb[
"temperature_warning"][
"enabled"] = ok;
3237 pout(
"unable to fetch IEC (SMART) mode page [%s]\n",
3246 pout(
"unable to enable Exception control and warning [%s]\n",
3253 pout(
"unable to fetch IEC (SMART) mode page [%s]\n",
3259 pout(
"Informational Exceptions (SMART) %s\n",
3261 pout(
"Temperature warning %s\n",
3274 pout(
"unable to fetch IEC (SMART) mode page [%s]\n",
3283 pout(
"unable to disable Exception control and warning [%s]\n",
3290 pout(
"unable to fetch IEC (SMART) mode page [%s]\n",
3296 pout(
"Informational Exceptions (SMART) %s\n",
3298 pout(
"Temperature warning %s\n",
3313 pout(
"Current Drive Temperature: <not available>\n");
3315 jout(
"Current Drive Temperature: %d C\n", temp);
3316 jglb[
"temperature"][
"current"] = temp;
3319 pout(
"Drive Trip Temperature: <not available>\n");
3321 jout(
"Drive Trip Temperature: %d C\n", trip);
3322 jglb[
"temperature"][
"drive_trip"] = trip;
3333 unsigned char * ucp;
3335 static const char * hname =
"Environmental Reports";
3336 static const char * jname =
"scsi_environmental_reports";
3337 static const char * rh_n =
"relative humidity";
3338 static const char * temp_n =
"temperature";
3339 static const char * sop_n =
"since power on";
3340 static const char * unkn_n =
"unknown";
3356 if (! (
gBuf[0] & 0x40)) {
3359 pout(
"Another flaky device that doesn't set the SPF bit\n");
3369 int pl = ucp[3] + 4;
3373 if ((pc < 0x100) && (pl == 12)) {
3374 snprintf(pc_s,
sizeof(pc_s),
"temperature_%d", ++temp_num);
3376 int temp = (int)(int8_t)ucp[5];
3378 jglb[jname][pc_s][
"parameter_code"] = pc;
3381 if (ucp[5] == 0x80) {
3382 jout(
"%s %s = %s\n", q, temp_n, unkn_n);
3383 jglb[jname][pc_s][
s] = unkn_n;
3385 jout(
"%s %s = %d\n", q, temp_n, temp);
3386 jglb[jname][pc_s][
s] = temp;
3388 temp = (int)(int8_t)ucp[6];
3389 q =
"Lifetime maximum";
3391 if (ucp[6] == 0x80) {
3392 jout(
"%s %s = %s\n", q, temp_n, unkn_n);
3393 jglb[jname][pc_s][
s] = unkn_n;
3395 jout(
"%s %s = %d\n", q, temp_n, temp);
3396 jglb[jname][pc_s][
s] = temp;
3398 temp = (int)(int8_t)ucp[7];
3399 q =
"Lifetime minimum";
3401 if (ucp[7] == 0x80) {
3402 jout(
"%s %s = %s\n", q, temp_n, unkn_n);
3403 jglb[jname][pc_s][
s] = unkn_n;
3405 jout(
"%s %s = %d\n", q, temp_n, temp);
3406 jglb[jname][pc_s][
s] = temp;
3408 temp = (int)(int8_t)ucp[8];
3409 q =
"Maximum since power on";
3411 if (ucp[8] == 0x80) {
3412 jout(
"Maximum %s %s = %s\n", temp_n, sop_n, unkn_n);
3413 jglb[jname][pc_s][
s] = unkn_n;
3415 jout(
"Maximum %s %s = %d\n", temp_n, sop_n, temp);
3416 jglb[jname][pc_s][
s] = temp;
3418 temp = (int)(int8_t)ucp[9];
3419 q =
"Minimum since power on";
3421 if (ucp[9] == 0x80) {
3422 jout(
"Minimum %s %s = %s\n", temp_n, sop_n, unkn_n);
3423 jglb[jname][pc_s][
s] = unkn_n;
3425 jout(
"Minimum %s %s = %d\n", temp_n, sop_n, temp);
3426 jglb[jname][pc_s][
s] = temp;
3428 if ((ucp[4] & 0x3) == 1) {
3429 temp = (int)(int8_t)ucp[10];
3430 q =
"Maximum other";
3432 if (ucp[10] == 0x80) {
3433 jout(
"%s %s = %s\n", q, temp_n, unkn_n);
3434 jglb[jname][pc_s][
s] = unkn_n;
3436 jout(
"%s %s = %d\n", q, temp_n, temp);
3437 jglb[jname][pc_s][
s] = temp;
3439 temp = (int)(int8_t)ucp[11];
3440 q =
"Minimum other";
3442 if (ucp[11] == 0x80) {
3443 jout(
"%s %s = %s\n", q, temp_n, unkn_n);
3444 jglb[jname][pc_s][
s] = unkn_n;
3446 jout(
"%s %s = %d\n", q, temp_n, temp);
3447 jglb[jname][pc_s][
s] = temp;
3450 }
else if ((pc < 0x200) && (pl == 12)) {
3451 snprintf(pc_s,
sizeof(pc_s),
"relative_humidity_%d", ++humid_num);
3452 jglb[jname][pc_s][
"parameter_code"] = pc;
3453 jout(
"Relative humidity = %u\n", ucp[5]);
3454 jglb[jname][pc_s][
"current"] = ucp[5];
3455 q =
"Lifetime maximum";
3457 jout(
"%s %s = %d\n", q, rh_n, ucp[6]);
3458 jglb[jname][pc_s][
s] = ucp[6];
3459 q =
"Lifetime minimum";
3461 jout(
"%s %s = %d\n", q, rh_n, ucp[7]);
3462 jglb[jname][pc_s][
s] = ucp[7];
3463 jout(
"Maximum %s %s = %d\n", rh_n, sop_n, ucp[8]);
3464 jglb[jname][pc_s][
"maximum_since_power_on"] = ucp[8];
3465 jout(
"Minimum %s %s = %d\n", rh_n, sop_n, ucp[9]);
3466 jglb[jname][pc_s][
"minimum_since_power_on"] = ucp[9];
3467 if ((ucp[4] & 0x3) == 1) {
3468 q =
"Maximum other";
3470 jout(
"%s %s = %d\n", q, rh_n, ucp[10]);
3471 jglb[jname][pc_s][
s] = ucp[10];
3472 q =
"Minimum other";
3474 jout(
"%s %s = %d\n", q, rh_n, ucp[11]);
3475 jglb[jname][pc_s][
s] = ucp[11];
3480 if ((pc < 0x200) && (pl != 12))
3481 pout(
"%s sub-lpage unexpected parameter length [%d], skip\n",
3484 pout(
"%s sub-lpage has unexpected parameter [0x%x], skip\n",
3500 bool envRepDone =
false;
3501 uint8_t peripheral_type = 0;
3503 int res, durationSec;
3511 const char * powername =
nullptr;
3512 bool powerchg =
false;
3516 if (sense_info.
asc == 0x5E) {
3517 unsigned char powerlimit = 0xff;
3518 int powermode = sense_info.
ascq ;
3537 switch (powermode) {
3540 pout(
"CHECK POWER MODE not implemented, ignoring -n option\n");
break;
3542 powername =
"SLEEP"; powerlimit = 2;
3546 powername =
"LOW POWER"; powerlimit = 2;
break;
3548 powername =
"IDLE BY TIMER"; powerlimit = 4;
break;
3550 powername =
"STANDBY BY TIMER"; powerlimit = 2;
break;
3552 powername =
"IDLE BY COMMAND"; powerlimit = 4;
break;
3554 powername =
"STANDBY BY COMMAND"; powerlimit = 2;
break;
3556 powername =
"IDLE BY TIMER"; powerlimit = 4;
break;
3558 powername =
"IDLE_ BY COMMAND"; powerlimit = 4;
break;
3560 powername =
"IDLE_C BY TIMER"; powerlimit = 4;
break;
3562 powername =
"IDLE_C BY COMMAND"; powerlimit = 4;
break;
3564 powername =
"STANDBY_Y BY TIMER"; powerlimit = 2;
break;
3566 powername =
"STANDBY_Y BY COMMAND"; powerlimit = 2;
break;
3569 pout(
"CHECK POWER MODE returned unknown value 0x%02x, "
3570 "ignoring -n option\n", powermode);
3575 jinf(
"Device is in %s mode, exit(%d)\n", powername, options.
powerexit);
3578 powerchg = (powermode != 0xff);
3581 powername =
"ACTIVE";
3604 pout(
"%s: query_cmd_support() failed\n", __func__);
3608 short int wce = -1, rcd = -1;
3614 pout(
"Read Cache is: %s\n",
3615 res ?
"Unavailable" :
3616 rcd ?
"Disabled" :
"Enabled");
3618 pout(
"Writeback Cache is: %s\n",
3619 res ?
"Unavailable" :
3620 !wce ?
"Disabled" :
"Enabled");
3627 pout(
"Power mode %s %s\n", (powerchg?
"was:":
"is: "), powername);
3634 pout(
"=== START OF ENABLE/DISABLE COMMANDS SECTION ===\n");
3650 pout(
"Enable autosave (clear GLTSD bit) failed\n");
3653 pout(
"Autosave enabled (GLTSD bit cleared).\n");
3658 if (options.
set_wce && is_disk) {
3659 short int enable = wce = (options.
set_wce > 0);
3663 pout(
"Write cache %sable failed: %s\n", (enable ?
"en" :
"dis"),
3667 pout(
"Write cache %sabled\n", (enable ?
"en" :
"dis"));
3672 if (options.
set_rcd && is_disk) {
3673 short int enable = (options.
set_rcd > 0);
3678 pout(
"Read cache %sable failed: %s\n", (enable ?
"en" :
"dis"),
3682 pout(
"Read cache %sabled\n", (enable ?
"en" :
"dis"));
3688 pout(
"Disable autosave (set GLTSD bit) failed\n");
3691 pout(
"Autosave disabled (GLTSD bit set).\n");
3703 pout(
"=== START OF READ SMART DATA SECTION ===\n");
3714 jout(
"TapeAlert Supported\n");
3715 jglb[
"tapealert"][
"supported"] =
true;
3722 jout(
"TapeAlert Not Supported\n");
3723 jglb[
"tapealert"][
"supported"] =
false;
3786 bool farm_supported =
true;
3791 jout(
"Seagate FARM log supported [try: -l farm]\n\n");
3796 pout(
"\nRead FARM log (SCSI Log page 0x3d, sub-page 0x3) failed\n\n");
3797 farm_supported =
false;
3804 jout(
"\nFARM log (SCSI Log page 0x3d, sub-page 0x3) not supported\n\n");
3806 farm_supported =
false;
3808 jglb[
"seagate_farm_log"][
"supported"] = farm_supported;
3821 pout(
"\n[GLTSD (Global Logging Target Save Disable) set. "
3822 "Enable Save with '-S on']\n");
3832 pout(
"Device does not support Self Test logging\n");
3845 pout(
"Device does not support Background scan results logging\n");
3857 pout(
"Device does not support %s logging\n",
zbds_s);
3869 pout(
"Device does not support %s logging\n",
gsap_s);
3883 pout(
"Device does not support (tape) device characteristics "
3896 pout(
"Device does not support TapeAlert logging\n");
3902 pout(
"TapeAlerts only printed if active, so none printed is good\n");
3909 pout(
"Default Self Test Successful\n");
3915 pout(
"Short Foreground Self Test Successful\n");
3921 (sense_info.
asc == 0x04 && sense_info.
ascq == 0x09)) {
3923 pout(
"Can't start self-test without aborting current test");
3925 pout(
" (%d%% remaining)",
3926 100 - sense_info.
progress * 100 / 65535);
3927 pout(
",\nadd '-t force' option to override, or run "
3928 "'smartctl -X' to abort test.\n");
3937 pout(
"Short Background Self Test has begun\n");
3938 pout(
"Use smartctl -X to abort test\n");
3944 pout(
"Extended Background Self Test has begun\n");
3947 time_t t = time(
nullptr);
3950 pout(
"Please wait %d minutes for test to complete.\n",
3954 pout(
"Estimated completion time: %s\n", comptime);
3956 pout(
"Use smartctl -X to abort test\n");
3962 pout(
"Extended Foreground Self Test Successful\n");
3967 pout(
"Self Test returned without error\n");
3986 pout(
"SCSI SSU(ACTIVE) command failed: %s\n",
3990 pout(
"Device placed in ACTIVE mode\n");
3992 pout(
"SCSI SSU(STANDBY) with timeout not supported yet\n");
3999 pout(
"Device placed in STANDBY mode\n");
4002 if (!any_output && powername)
4003 pout(
"Device is in %s mode\n", powername);
4006 pout(
"SCSI device successfully opened\n\nUse 'smartctl -a' (or '-x') "
4007 "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,...)