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]);
1784 int num, err, truncated;
1789 static const char * jname =
"scsi_zoned_block_device_statistics";
1822 int pl = ucp[3] + 4;
1828 q =
"Maximum open zones";
1830 jout(
" %s: %u\n", q, u);
1834 q =
"Maximum explicitly open zones";
1836 jout(
" %s: %u\n", q, u);
1840 q =
"Maximum implicitly open zones";
1842 jout(
" %s: %u\n", q, u);
1846 q =
"Minimum empty zones";
1848 jout(
" %s: %u\n", q, u);
1852 q =
"Maximum nonseq zones";
1854 jout(
" %s: %u\n", q, u);
1858 q =
"Zones emptied";
1860 jout(
" %s: %u\n", q, u);
1864 q =
"Suboptimal write commands";
1866 jout(
" %s: %u\n", q, u);
1870 q =
"Commands exceeding optinmal limit";
1872 jout(
" %s: %u\n", q, u);
1876 q =
"Failed explicit opens";
1878 jout(
" %s: %u\n", q, u);
1882 q =
"Read rule violations";
1884 jout(
" %s: %u\n", q, u);
1888 q =
"Write rule violations";
1890 jout(
" %s: %u\n", q, u);
1894 q =
"Maximum implicitly open sequential or before required zones";
1896 jout(
" %s: %u\n", q, u);
1912 int num, err, truncated;
1918 static const char * hname =
"Device statistics (SSC, tape)";
1919 static const char * jname =
"scsi_device_statistics";
1940 pout(
"%s %s length is %d, too short\n", hname,
logSenStr, num);
1952 int pl = ucp[3] + 4;
1957 q =
"Lifetime volume loads";
1959 jout(
" %s: %" PRIu64
"\n", q, ull);
1963 q =
"Lifetime cleaning operations";
1965 jout(
" %s: %" PRIu64
"\n", q, ull);
1969 q =
"Lifetime power on hours";
1971 jout(
" %s: %" PRIu64
"\n", q, ull);
1975 q =
"Lifetime medium motion hours";
1977 jout(
" %s: %" PRIu64
"\n", q, ull);
1981 q =
"Lifetime meters of tape processed";
1983 jout(
" %s: %" PRIu64
"\n", q, ull);
1987 q =
"Lifetime medium motion hours at last incompatible volume "
1990 jout(
" %s: %" PRIu64
"\n", q, ull);
1994 q =
"Lifetime power on hours at last temperature condition "
1997 jout(
" %s: %" PRIu64
"\n", q, ull);
2001 q =
"Lifetime power on hours at last power consumption condition "
2004 jout(
" %s: %" PRIu64
"\n", q, ull);
2008 q =
"Medium motion hours since last successful cleaning "
2011 jout(
" %s: %" PRIu64
"\n", q, ull);
2015 q =
"Medium motion hours since second to last successful "
2016 "cleaning operation";
2018 jout(
" %s: %" PRIu64
"\n", q, ull);
2022 q =
"Medium motion hours since third to last successful "
2023 "cleaning operation";
2025 jout(
" %s: %" PRIu64
"\n", q, ull);
2029 q =
"Lifetime power on hours at last operator initiated forced "
2030 "reset and/or emergency eject occurrence";
2032 jout(
" %s: %" PRIu64
"\n", q, ull);
2036 q =
"Lifetime power cycles";
2038 jout(
" %s: %" PRIu64
"\n", q, ull);
2042 q =
"Volume loads since last parameter reset";
2044 jout(
" %s: %" PRIu64
"\n", q, ull);
2048 q =
"Hard write errors";
2050 jout(
" %s: %" PRIu64
"\n", q, ull);
2054 q =
"Hard read errors";
2056 jout(
" %s: %" PRIu64
"\n", q, ull);
2060 q =
"Duty cycle sample time";
2062 jout(
" %s: %" PRIu64
"\n", q, ull);
2066 q =
"Read duty cycle";
2068 jout(
" %s: %" PRIu64
"\n", q, ull);
2072 q =
"Write duty cycle";
2074 jout(
" %s: %" PRIu64
"\n", q, ull);
2078 q =
"Activity duty cycle";
2080 jout(
" %s: %" PRIu64
"\n", q, ull);
2084 q =
"Volume not present duty cycle";
2086 jout(
" %s: %" PRIu64
"\n", q, ull);
2090 q =
"Ready duty cycle";
2092 jout(
" %s: %" PRIu64
"\n", q, ull);
2096 q =
"Megabytes transferred from application client in duty cycle"
2099 jout(
" %s: %" PRIu64
"\n", q, ull);
2103 q =
"Megabytes transferred to application client in duty cycle"
2106 jout(
" %s: %" PRIu64
"\n", q, ull);
2111 std::string v((
const char *)(ucp + 4), ucp[3]);
2112 q =
"Drive manufacturer's serial number";
2113 jout(
" %s: %s\n", q, v.c_str());
2119 std::string v((
const char *)(ucp + 4), ucp[3]);
2120 q =
"Drive serial number";
2121 jout(
" %s: %s\n", q, v.c_str());
2127 std::string v((
const char *)(ucp + 4), ucp[3]);
2128 q =
"Manufacturing date year,month,day";
2129 jout(
" %s: %s\n", q, v.c_str());
2135 std::string v((
const char *)(ucp + 4), ucp[3]);
2136 q =
"Manufacturing date year,week";
2137 jout(
" %s: %s\n", q, v.c_str());
2143 std::string v((
const char *)(ucp + 4), ucp[3]);
2144 q =
"Manufacturing date year,week";
2145 jout(
" %s: %s\n", q, v.c_str());
2150 q =
"Medium removal prevented";
2152 jout(
" %s: %" PRIu64
"\n", q, ull);
2156 q =
"Maximum recommended mechanism temperature exceeded";
2158 jout(
" %s: %" PRIu64
"\n", q, ull);
2162 q =
"Medium motion hours for each medium type";
2165 jout(
" %s, number of element: %u\n", q, n);
2166 for (k = 0; k < n; ++k, ucp += 8) {
2168 jout(
" [%d] density code: %u, density code: %u, hours: "
2169 "%u\n", k + 1, ucp[6], ucp[7], u);
2170 jglb[jname][
s][k][
"density_code"] = ucp[6];
2171 jglb[jname][
s][k][
"medium_type"] = ucp[7];
2172 jglb[jname][
s][k][
"medium_motion_hours"] = u;
2187 bool all_not_avail =
false;
2188 int num, num_hold, err, truncated;
2192 static const char * hname =
"Format Status";
2193 static const char * jname =
"scsi_format_status";
2212 jout(
"%s %s length is %d, too short\n", hname,
logSenStr, num);
2224 all_not_avail =
true;
2227 int pl = ucp[3] + 4;
2236 if (!
all_ffs(ucp + 4, ucp[3]))
2237 all_not_avail =
false;
2242 if (! all_not_avail)
2247 if (all_not_avail) {
2248 jout(
"Format status indicates no format since manufacture\n");
2258 int pl = ucp[3] + 4;
2260 bool is_count =
true;
2261 const char * jout_str =
"";
2262 const char * jglb_str =
"x";
2267 jout(
"Format data out: <empty>\n");
2270 jout(
"Format data out: <not available>\n");
2272 jout(
"Format data out:\n");
2273 dStrHex((
const uint8_t *)ucp + 4, pl - 4, 0);
2280 jout_str =
"Grown defects during certification";
2281 jglb_str =
"grown_defects_during_cert";
2284 jout_str =
"Total blocks reassigned during format";
2285 jglb_str =
"blocks_reassigned_during_format";
2288 jout_str =
"Total new blocks reassigned";
2289 jglb_str =
"total_new_block_since_format";
2292 jout_str =
"Power on minutes since format";
2293 jglb_str =
"power_on_minutes_since_format";
2297 pout(
" Unknown Format parameter code = 0x%x\n", pc);
2298 dStrHex((
const uint8_t *)ucp, pl, 0);
2304 if (
all_ffs(ucp + 4, ucp[3])) {
2305 pout(
"%s <not available>\n", jout_str);
2308 jout(
"%s = %" PRIu64
"\n", jout_str, ull);
2309 jglb[jname][jglb_str] = ull;
2321 unsigned thresh_val)
2325 static const char * pvd_th =
"Peak value detector threshold";
2326 static const char * pvd_th_j =
"pvd_threshold";
2330 jout(
" No event\n");
2333 q =
"Invalid dword count";
2334 jout(
" %s: %u\n", q, val);
2335 jref[std::string(q) +
"_2"] = val;
2338 q =
"Running disparity error count";
2339 jout(
" %s: %u\n", q, val);
2340 jref[std::string(q) +
"_2"] = val;
2343 q =
"Loss of dword synchronization count";
2344 jout(
" %s: %u\n", q, val);
2345 jref[std::string(q) +
"_2"] = val;
2348 q =
"Phy reset problem count";
2349 jout(
" %s: %u\n", q, val);
2350 jref[std::string(q) +
"_2"] = val;
2353 q =
"Elasticity buffer overflow count";
2354 jout(
" %s: %u\n", q, val);
2358 q =
"Received ERROR count";
2359 jout(
" %s: %u\n", q, val);
2363 q =
"Received address frame error count";
2364 jout(
" %s: %u\n", q, val);
2368 q =
"Transmitted abandon-class OPEN_REJECT count";
2369 jout(
" %s: %u\n", q, val);
2373 q =
"Received abandon-class OPEN_REJECT count";
2374 jout(
" %s: %u\n", q, val);
2378 q =
"Transmitted retry-class OPEN_REJECT count";
2379 jout(
" %s: %u\n", q, val);
2383 q =
"Received retry-class OPEN_REJECT count";
2384 jout(
" %s: %u\n", q, val);
2388 q =
"Received AIP (WAITING ON PARTIAL) count";
2389 jout(
" %s: %u\n", q, val);
2393 q =
"Received AIP (WAITING ON CONNECTION) count";
2394 jout(
" %s: %u\n", q, val);
2398 q =
"Transmitted BREAK count";
2399 jout(
" %s: %u\n", q, val);
2403 q =
"Received BREAK count";
2404 jout(
" %s: %u\n", q, val);
2408 q =
"Break timeout count";
2409 jout(
" %s: %u\n", q, val);
2413 q =
"Connection count";
2414 jout(
" %s: %u\n", q, val);
2418 q =
"Peak transmitted pathway blocked";
2419 jout(
" %s count: %u\n", q, val & 0xff);
2420 jout(
" %s: %u\n", pvd_th, thresh_val & 0xff);
2421 jref[q][
"count"] = val & 0xff;
2422 jref[q][pvd_th_j] = thresh_val & 0xff;
2425 q =
"Peak transmitted arbitration wait time";
2428 jout(
" %s (us): %u\n", q, u);
2429 jref[std::string(q) +
"_us"][
"event"] = u;
2431 jout(
" %s (ms): %u\n", q, 33 + (u - 0x8000));
2432 jref[std::string(q) +
"_ms"][
"event"] = 33 + (u - 0x8000);
2434 u = thresh_val & 0xffff;
2436 jout(
" %s (us): %u\n", pvd_th, u);
2437 jref[std::string(q) +
"_us"][pvd_th_j] = u;
2439 jout(
" %s (ms): %u\n", pvd_th, 33 + (u - 0x8000));
2440 jref[std::string(q) +
"_ms"][pvd_th_j] = 33 + (u - 0x8000);
2444 q =
"Peak arbitration time";
2445 jout(
" %s (us): %u\n", q, val);
2446 jref[std::string(q) +
"_us"][
"event"] = val;
2447 jout(
" %s: %u\n", pvd_th, thresh_val);
2448 jref[std::string(q) +
"_us"][pvd_th_j] = thresh_val;
2451 q =
"Peak connection time";
2452 jout(
" %s (us): %u\n", q, val);
2453 jref[std::string(q) +
"_us"][
"event"] = val;
2454 jout(
" %s: %u\n", pvd_th, thresh_val);
2455 jref[std::string(q) +
"_us"][pvd_th_j] = thresh_val;
2458 q =
"Transmitted SSP frame count";
2459 jout(
" %s: %u\n", q, val);
2463 q =
"Received SSP frame count";
2464 jout(
" %s: %u\n", q, val);
2468 q =
"Transmitted SSP frame error count";
2469 jout(
" %s: %u\n", q, val);
2473 q =
"Received SSP frame error count";
2474 jout(
" %s: %u\n", q, val);
2478 q =
"Transmitted CREDIT_BLOCKED count";
2479 jout(
" %s: %u\n", q, val);
2483 q =
"Received CREDIT_BLOCKED count";
2484 jout(
" %s: %u\n", q, val);
2488 q =
"Transmitted SATA frame count";
2489 jout(
" %s: %u\n", q, val);
2493 q =
"Received SATA frame count";
2494 jout(
" %s: %u\n", q, val);
2498 q =
"SATA flow control buffer overflow count";
2499 jout(
" %s: %u\n", q, val);
2503 q =
"Transmitted SMP frame count";
2504 jout(
" %s: %u\n", q, val);
2508 q =
"Received SMP frame count";
2509 jout(
" %s: %u\n", q, val);
2513 q =
"Received SMP frame error count";
2514 jout(
" %s: %u\n", q, val);
2525 int k, j, m, nphys, t, sz, spld_len;
2527 unsigned char * vcp;
2531 snprintf(pn,
sizeof(pn),
"scsi_sas_port_%d", port_num);
2535 jout(
"relative target port id = %d\n", t);
2536 jglb[pn][
"relative_target_port_id"] = t;
2537 jout(
" generation code = %d\n", ucp[6]);
2538 jglb[pn][
"generation_code"] = ucp[6];
2540 jout(
" number of phys = %d\n", nphys);
2541 jglb[pn][
"number_of_phys"] = nphys;
2543 for (j = 0, k = 0, vcp = ucp + 8; j < (param_len - 8);
2544 vcp += spld_len, j += spld_len, ++k) {
2547 snprintf(yn,
sizeof(yn),
"phy_%d", k);
2549 jout(
" phy identifier = %d\n", vcp[1]);
2550 jref[
"identifier"] = vcp[1];
2556 t = ((0x70 & vcp[4]) >> 4);
2558 case 0: snprintf(
s, sz,
"no device attached");
break;
2559 case 1: snprintf(
s, sz,
"SAS or SATA device");
break;
2560 case 2: snprintf(
s, sz,
"expander device");
break;
2561 case 3: snprintf(
s, sz,
"expander device (fanout)");
break;
2562 default: snprintf(
s, sz,
"reserved [%d]", t);
break;
2564 q =
"attached device type";
2565 jout(
" %s: %s\n", q,
s);
2569 case 0: snprintf(
s, sz,
"unknown");
break;
2570 case 1: snprintf(
s, sz,
"power on");
break;
2571 case 2: snprintf(
s, sz,
"hard reset");
break;
2572 case 3: snprintf(
s, sz,
"SMP phy control function");
break;
2573 case 4: snprintf(
s, sz,
"loss of dword synchronization");
break;
2574 case 5: snprintf(
s, sz,
"mux mix up");
break;
2575 case 6: snprintf(
s, sz,
"I_T nexus loss timeout for STP/SATA");
2577 case 7: snprintf(
s, sz,
"break timeout timer expired");
break;
2578 case 8: snprintf(
s, sz,
"phy test function stopped");
break;
2579 case 9: snprintf(
s, sz,
"expander device reduced functionality");
2581 default: snprintf(
s, sz,
"reserved [0x%x]", t);
break;
2583 q =
"attached reason";
2584 jout(
" %s: %s\n", q,
s);
2586 t = (vcp[5] & 0xf0) >> 4;
2588 case 0: snprintf(
s, sz,
"unknown");
break;
2589 case 1: snprintf(
s, sz,
"power on");
break;
2590 case 2: snprintf(
s, sz,
"hard reset");
break;
2591 case 3: snprintf(
s, sz,
"SMP phy control function");
break;
2592 case 4: snprintf(
s, sz,
"loss of dword synchronization");
break;
2593 case 5: snprintf(
s, sz,
"mux mix up");
break;
2594 case 6: snprintf(
s, sz,
"I_T nexus loss timeout for STP/SATA");
2596 case 7: snprintf(
s, sz,
"break timeout timer expired");
break;
2597 case 8: snprintf(
s, sz,
"phy test function stopped");
break;
2598 case 9: snprintf(
s, sz,
"expander device reduced functionality");
2600 default: snprintf(
s, sz,
"reserved [0x%x]", t);
break;
2603 jout(
" %s: %s\n", q,
s);
2607 case 0: snprintf(
s, sz,
"phy enabled; unknown");
2609 case 1: snprintf(
s, sz,
"phy disabled");
break;
2610 case 2: snprintf(
s, sz,
"phy enabled; speed negotiation failed");
2612 case 3: snprintf(
s, sz,
"phy enabled; SATA spinup hold state");
2614 case 4: snprintf(
s, sz,
"phy enabled; port selector");
2616 case 5: snprintf(
s, sz,
"phy enabled; reset in progress");
2618 case 6: snprintf(
s, sz,
"phy enabled; unsupported phy attached");
2620 case 8: snprintf(
s, sz,
"phy enabled; 1.5 Gbps");
break;
2621 case 9: snprintf(
s, sz,
"phy enabled; 3 Gbps");
break;
2622 case 0xa: snprintf(
s, sz,
"phy enabled; 6 Gbps");
break;
2623 case 0xb: snprintf(
s, sz,
"phy enabled; 12 Gbps");
break;
2624 default: snprintf(
s, sz,
"reserved [%d]", t);
break;
2626 q =
"negotiated logical link rate";
2627 jout(
" %s: %s\n", q,
s);
2629 q =
"attached initiator port";
2630 jout(
" %s: ssp=%d stp=%d smp=%d\n", q,
2631 !! (vcp[6] & 8), !! (vcp[6] & 4), !! (vcp[6] & 2));
2632 snprintf(
s, sz,
"%03d", ((vcp[6] & 8) ? 100 : 0) +
2633 ((vcp[6] & 4) ? 10 : 0) + ((vcp[6] & 2) ? 1 : 0));
2634 jref[q][
"ssp_stp_smp"] =
s;
2635 q =
"attached target port";
2636 jout(
" %s: ssp=%d stp=%d smp=%d\n", q,
2637 !! (vcp[7] & 8), !! (vcp[7] & 4), !! (vcp[7] & 2));
2638 snprintf(
s, sz,
"%03d", ((vcp[7] & 8) ? 100 : 0) +
2639 ((vcp[7] & 4) ? 10 : 0) + ((vcp[7] & 2) ? 1 : 0));
2640 jref[q][
"ssp_stp_smp"] =
s;
2645 snprintf(
b,
sizeof(
b),
"0x%" PRIx64, ull);
2647 jout(
" %s = %s\n", q,
b);
2650 snprintf(
b,
sizeof(
b),
"0x%" PRIx64, ull);
2651 q =
"attached SAS address";
2652 jout(
" %s = %s\n", q,
b);
2655 q =
"attached phy identifier";
2656 jout(
" %s = %d\n", q, vcp[24]);
2660 q =
"Invalid DWORD count";
2661 jout(
" %s = %u\n", q, ui);
2664 q =
"Running disparity error count";
2665 jout(
" %s = %u\n", q, ui);
2668 q =
"Loss of DWORD synchronization count";
2669 jout(
" %s = %u\n", q, ui);
2672 q =
"Phy reset problem count";
2673 jout(
" %s = %u\n", q, ui);
2675 if (spld_len > 51) {
2676 bool header_given =
false;
2679 unsigned char * xcp;
2683 for (m = 0; m < (num_ped * 12); m += 12, xcp += 12) {
2690 if (allow_dupl || (peis > 0x4)) {
2691 if (! header_given) {
2692 header_given =
true;
2693 jout(
" Phy event descriptors:\n");
2707 unsigned char * ucp;
2710 for (k = 0, j = 0, ucp = resp + 4; k < num; ++j) {
2711 int param_len = ucp[3] + 4;
2715 jout(
"\nProtocol Specific port %s for SAS SSP\n",
lp_s);
2731 static const char * hname =
"Protocol specific port";
2751 pout(
"Only support %s %s on SAS devices\n\n", hname,
lp_s);
2759 pout(
"%s Log Select (reset) Failed [%s]\n\n", __func__,
2785 "optical card reader",
2787 "object based storage",
2788 "automation/driver interface",
2789 "security manager device",
2790 "host managed zoned block device",
2800 "well known logical unit",
2801 "unknown or no device type",
2806 "Fibre channel (FCP-4)",
2807 "Parallel SCSI (SPI-4)",
2809 "IEEE 1394 (SBP-3)",
2827 bool & have_zbc,
bool all)
2830 bool is_tape =
false;
2831 int err, iec_err, len, req_len, avail_len;
2834 int form_factor = 0;
2840 memset(
gBuf, 0, 96);
2846 pout(
"Retrying with a 64 byte Standard Inquiry\n");
2852 pout(
"Standard Inquiry (64 bytes) failed [%s]\n",
2858 avail_len =
gBuf[4] + 5;
2859 len = (avail_len < req_len) ? avail_len : req_len;
2860 peri_dt =
gBuf[0] & 0x1f;
2861 *peripheral_type = peri_dt;
2870 pout(
"Short INQUIRY response, skip product id\n");
2878 if (all && (0 != strncmp((
char *)&
gBuf[8],
"ATA", 3))) {
2879 char product[16+1], revision[4+1];
2884 pout(
"=== START OF INFORMATION SECTION ===\n");
2887 jout(
"Product: %.16s\n", product);
2888 jglb[
"scsi_product"] = product;
2891 if (
gBuf[32] >=
' ') {
2892 jout(
"Revision: %.4s\n", revision);
2894 jglb[
"scsi_revision"] = revision;
2899 snprintf(sv_arr,
sizeof(sv_arr),
"SPC-%d",
scsi_version - 2);
2900 jout(
"Compliance: %s\n", sv_arr);
2901 jglb[
"scsi_version"] = sv_arr;
2906 (0 == strncmp((
char *)&
gBuf[8],
"ATA", 3))) {
2907 pout(
"\nProbable ATA device behind a SAT layer\n"
2908 "Try an additional '-d ata' or '-d sat' argument.\n");
2914 protect =
gBuf[5] & 0x1;
2920 unsigned char lb_prov_resp[8];
2923 static const char * lb_prov_j =
"scsi_lb_provisioning";
2926 char cap_str[64], si_str[64];
2929 jout(
"User Capacity: %s bytes [%s]\n", cap_str, si_str);
2931 jglb[
"user_capacity"][
"blocks"].set_unsafe_uint64(capacity /
2933 jglb[
"user_capacity"][
"bytes"].set_unsafe_uint64(capacity);
2934 jout(
"Logical block size: %u bytes\n", srr.
lb_size);
2939 jout(
"Physical block size: %u bytes\n", pb_size);
2940 jglb[
"physical_block_size"] = pb_size;
2947 pout(
"Formatted with type 1 protection\n");
2950 pout(
"Formatted with type 2 protection\n");
2953 pout(
"Formatted with type 3 protection\n");
2956 pout(
"Formatted with unknown protection type [%d]\n",
2961 unsigned p_i_per_lb = (1 << srr.
p_i_exp);
2962 const unsigned pi_sz = 8;
2965 if (p_i_per_lb > 1) {
2966 jout(
"%d protection information intervals per "
2967 "logical block\n", p_i_per_lb);
2970 jout(
"%d bytes of protection information per logical "
2971 "block\n", pi_sz * p_i_per_lb);
2972 jglb[
"scsi_protection_interval_bytes_per_lb"] =
2984 lb_prov_resp,
sizeof(lb_prov_resp))) {
2985 int prov_type = lb_prov_resp[6] & 0x7;
2986 int vpd_lbprz = ((lb_prov_resp[5] >> 2) & 0x7);
2990 else if ((0 == vpd_lbprz) && (1 ==
lbprz))
2994 switch (prov_type) {
2997 jout(
"LU is fully provisioned");
2998 jglb[lb_prov_j][
"name"] =
"fully provisioned";
3004 jout(
"LB provisioning type: not reported [LBPME=1, "
3005 "LBPRZ=%d]\n",
lbprz);
3006 jglb[lb_prov_j][
"name"] =
"not reported";
3010 jout(
"LU is resource provisioned, LBPRZ=%d\n",
lbprz);
3011 jglb[lb_prov_j][
"name"] =
"resource provisioned";
3014 jout(
"LU is thin provisioned, LBPRZ=%d\n",
lbprz);
3015 jglb[lb_prov_j][
"name"] =
"thin provisioned";
3018 jout(
"LU provisioning type reserved [%d], LBPRZ=%d\n",
3020 jglb[lb_prov_j][
"name"] =
"reserved";
3023 jglb[lb_prov_j][
"value"] = prov_type;
3024 jglb[lb_prov_j][
"management_enabled"][
"name"] =
"LBPME";
3025 jglb[lb_prov_j][
"management_enabled"][
"value"] =
lbpme;
3026 jglb[lb_prov_j][
"read_zeros"][
"name"] =
"LBPRZ";
3027 jglb[lb_prov_j][
"read_zeros"][
"value"] =
lbprz;
3028 }
else if (1 ==
lbpme) {
3030 jout(
"rcap_16 sets LBPME but no LB provisioning VPD page\n");
3031 jout(
"Logical block provisioning enabled, LBPRZ=%d\n",
lbprz);
3039 jout(
"Rotation Rate: Solid State Device\n");
3040 else if ((rpm <= 0x400) || (0xffff == rpm))
3043 jout(
"Rotation Rate: %d rpm\n", rpm);
3044 jglb[
"rotation_rate"] = (rpm == 1 ? 0 : rpm);
3046 if (form_factor > 0) {
3047 const char * cp =
nullptr;
3049 switch (form_factor) {
3066 jglb[
"form_factor"][
"scsi_value"] = form_factor;
3068 jout(
"Form Factor: %s inches\n", cp);
3074 q =
"Host aware zoned block capable";
3077 }
else if (haw_zbc == 2) {
3079 q =
"Device managed zoned block capable";
3098 pout(
">> Terminate command early due to bad response to IEC "
3114 if (strlen(
s) > 0) {
3115 jout(
"Logical Unit id: %s\n",
s);
3116 jglb[
"logical_unit_id"] =
s;
3121 pout(
"Vital Product Data (VPD) bit ignored in INQUIRY\n");
3123 pout(
"Vital Product Data (VPD) INQUIRY failed [%d]\n", err);
3131 gBuf[4 + len] =
'\0';
3133 jout(
"Serial number: %s\n", serial);
3134 jglb[
"serial_number"] = serial;
3138 pout(
"Vital Product Data (VPD) bit ignored in INQUIRY\n");
3140 pout(
"Vital Product Data (VPD) INQUIRY failed [%d]\n", err);
3146 jglb[
"device_type"][
"scsi_terminology"] =
"Peripheral Device Type [PDT]";
3147 jglb[
"device_type"][
"scsi_value"] = peri_dt;
3153 jout(
"Device type: <%d>\n", peri_dt);
3158 if ((transport >= 0) && (transport <= 0xf)) {
3161 jglb[
"scsi_transport_protocol"][
"value"] = transport;
3171 pout(
"device is NOT READY (e.g. spun down, busy)\n");
3173 pout(
"device is NOT READY (e.g. no tape)\n");
3178 pout(
"NO tape present in drive\n");
3180 pout(
"NO MEDIUM present in device\n");
3184 pout(
"device becoming ready (wait)\n");
3200 jout(
"SMART support is: Unavailable - device lacks SMART "
3202 jglb[
"smart_support"][
"available"] =
false;
3213 jout(
"SMART support is: Available - device has SMART capability.\n"
3214 "SMART support is: %s\n", ok ?
"Enabled" :
"Disabled");
3215 jglb[
"smart_support"][
"available"] =
true;
3216 jglb[
"smart_support"][
"enabled"] = ok;
3219 jout(
"Temperature Warning: %s\n",
3220 ok ?
"Enabled" :
"Disabled or Not Supported");
3221 jglb[
"temperature_warning"][
"enabled"] = ok;
3233 pout(
"unable to fetch IEC (SMART) mode page [%s]\n",
3242 pout(
"unable to enable Exception control and warning [%s]\n",
3249 pout(
"unable to fetch IEC (SMART) mode page [%s]\n",
3255 pout(
"Informational Exceptions (SMART) %s\n",
3257 pout(
"Temperature warning %s\n",
3270 pout(
"unable to fetch IEC (SMART) mode page [%s]\n",
3279 pout(
"unable to disable Exception control and warning [%s]\n",
3286 pout(
"unable to fetch IEC (SMART) mode page [%s]\n",
3292 pout(
"Informational Exceptions (SMART) %s\n",
3294 pout(
"Temperature warning %s\n",
3309 pout(
"Current Drive Temperature: <not available>\n");
3311 jout(
"Current Drive Temperature: %d C\n", temp);
3312 jglb[
"temperature"][
"current"] = temp;
3315 pout(
"Drive Trip Temperature: <not available>\n");
3317 jout(
"Drive Trip Temperature: %d C\n", trip);
3318 jglb[
"temperature"][
"drive_trip"] = trip;
3329 unsigned char * ucp;
3331 static const char * hname =
"Environmental Reports";
3332 static const char * jname =
"scsi_environmental_reports";
3333 static const char * rh_n =
"relative humidity";
3334 static const char * temp_n =
"temperature";
3335 static const char * sop_n =
"since power on";
3336 static const char * unkn_n =
"unknown";
3352 if (! (
gBuf[0] & 0x40)) {
3355 pout(
"Another flaky device that doesn't set the SPF bit\n");
3365 int pl = ucp[3] + 4;
3369 if ((pc < 0x100) && (pl == 12)) {
3370 snprintf(pc_s,
sizeof(pc_s),
"temperature_%d", ++temp_num);
3372 int temp = (int)(int8_t)ucp[5];
3374 jglb[jname][pc_s][
"parameter_code"] = pc;
3377 if (ucp[5] == 0x80) {
3378 jout(
"%s %s = %s\n", q, temp_n, unkn_n);
3379 jglb[jname][pc_s][
s] = unkn_n;
3381 jout(
"%s %s = %d\n", q, temp_n, temp);
3382 jglb[jname][pc_s][
s] = temp;
3384 temp = (int)(int8_t)ucp[6];
3385 q =
"Lifetime maximum";
3387 if (ucp[6] == 0x80) {
3388 jout(
"%s %s = %s\n", q, temp_n, unkn_n);
3389 jglb[jname][pc_s][
s] = unkn_n;
3391 jout(
"%s %s = %d\n", q, temp_n, temp);
3392 jglb[jname][pc_s][
s] = temp;
3394 temp = (int)(int8_t)ucp[7];
3395 q =
"Lifetime minimum";
3397 if (ucp[7] == 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[8];
3405 q =
"Maximum since power on";
3407 if (ucp[8] == 0x80) {
3408 jout(
"Maximum %s %s = %s\n", temp_n, sop_n, unkn_n);
3409 jglb[jname][pc_s][
s] = unkn_n;
3411 jout(
"Maximum %s %s = %d\n", temp_n, sop_n, temp);
3412 jglb[jname][pc_s][
s] = temp;
3414 temp = (int)(int8_t)ucp[9];
3415 q =
"Minimum since power on";
3417 if (ucp[9] == 0x80) {
3418 jout(
"Minimum %s %s = %s\n", temp_n, sop_n, unkn_n);
3419 jglb[jname][pc_s][
s] = unkn_n;
3421 jout(
"Minimum %s %s = %d\n", temp_n, sop_n, temp);
3422 jglb[jname][pc_s][
s] = temp;
3424 if ((ucp[4] & 0x3) == 1) {
3425 temp = (int)(int8_t)ucp[10];
3426 q =
"Maximum other";
3428 if (ucp[10] == 0x80) {
3429 jout(
"%s %s = %s\n", q, temp_n, unkn_n);
3430 jglb[jname][pc_s][
s] = unkn_n;
3432 jout(
"%s %s = %d\n", q, temp_n, temp);
3433 jglb[jname][pc_s][
s] = temp;
3435 temp = (int)(int8_t)ucp[11];
3436 q =
"Minimum other";
3438 if (ucp[11] == 0x80) {
3439 jout(
"%s %s = %s\n", q, temp_n, unkn_n);
3440 jglb[jname][pc_s][
s] = unkn_n;
3442 jout(
"%s %s = %d\n", q, temp_n, temp);
3443 jglb[jname][pc_s][
s] = temp;
3446 }
else if ((pc < 0x200) && (pl == 12)) {
3447 snprintf(pc_s,
sizeof(pc_s),
"relative_humidity_%d", ++humid_num);
3448 jglb[jname][pc_s][
"parameter_code"] = pc;
3449 jout(
"Relative humidity = %u\n", ucp[5]);
3450 jglb[jname][pc_s][
"current"] = ucp[5];
3451 q =
"Lifetime maximum";
3453 jout(
"%s %s = %d\n", q, rh_n, ucp[6]);
3454 jglb[jname][pc_s][
s] = ucp[6];
3455 q =
"Lifetime minimum";
3457 jout(
"%s %s = %d\n", q, rh_n, ucp[7]);
3458 jglb[jname][pc_s][
s] = ucp[7];
3459 jout(
"Maximum %s %s = %d\n", rh_n, sop_n, ucp[8]);
3460 jglb[jname][pc_s][
"maximum_since_power_on"] = ucp[8];
3461 jout(
"Minimum %s %s = %d\n", rh_n, sop_n, ucp[9]);
3462 jglb[jname][pc_s][
"minimum_since_power_on"] = ucp[9];
3463 if ((ucp[4] & 0x3) == 1) {
3464 q =
"Maximum other";
3466 jout(
"%s %s = %d\n", q, rh_n, ucp[10]);
3467 jglb[jname][pc_s][
s] = ucp[10];
3468 q =
"Minimum other";
3470 jout(
"%s %s = %d\n", q, rh_n, ucp[11]);
3471 jglb[jname][pc_s][
s] = ucp[11];
3476 if ((pc < 0x200) && (pl != 12))
3477 pout(
"%s sub-lpage unexpected parameter length [%d], skip\n",
3480 pout(
"%s sub-lpage has unexpected parameter [0x%x], skip\n",
3496 bool envRepDone =
false;
3497 uint8_t peripheral_type = 0;
3499 int res, durationSec;
3507 const char * powername =
nullptr;
3508 bool powerchg =
false;
3512 if (sense_info.
asc == 0x5E) {
3513 unsigned char powerlimit = 0xff;
3514 int powermode = sense_info.
ascq ;
3533 switch (powermode) {
3536 pout(
"CHECK POWER MODE not implemented, ignoring -n option\n");
break;
3538 powername =
"SLEEP"; powerlimit = 2;
3542 powername =
"LOW POWER"; powerlimit = 2;
break;
3544 powername =
"IDLE BY TIMER"; powerlimit = 4;
break;
3546 powername =
"STANDBY BY TIMER"; powerlimit = 2;
break;
3548 powername =
"IDLE BY COMMAND"; powerlimit = 4;
break;
3550 powername =
"STANDBY BY COMMAND"; powerlimit = 2;
break;
3552 powername =
"IDLE BY TIMER"; powerlimit = 4;
break;
3554 powername =
"IDLE_ BY COMMAND"; powerlimit = 4;
break;
3556 powername =
"IDLE_C BY TIMER"; powerlimit = 4;
break;
3558 powername =
"IDLE_C BY COMMAND"; powerlimit = 4;
break;
3560 powername =
"STANDBY_Y BY TIMER"; powerlimit = 2;
break;
3562 powername =
"STANDBY_Y BY COMMAND"; powerlimit = 2;
break;
3565 pout(
"CHECK POWER MODE returned unknown value 0x%02x, "
3566 "ignoring -n option\n", powermode);
3571 jinf(
"Device is in %s mode, exit(%d)\n", powername, options.
powerexit);
3574 powerchg = (powermode != 0xff);
3577 powername =
"ACTIVE";
3600 pout(
"%s: query_cmd_support() failed\n", __func__);
3604 short int wce = -1, rcd = -1;
3610 pout(
"Read Cache is: %s\n",
3611 res ?
"Unavailable" :
3612 rcd ?
"Disabled" :
"Enabled");
3614 pout(
"Writeback Cache is: %s\n",
3615 res ?
"Unavailable" :
3616 !wce ?
"Disabled" :
"Enabled");
3623 pout(
"Power mode %s %s\n", (powerchg?
"was:":
"is: "), powername);
3630 pout(
"=== START OF ENABLE/DISABLE COMMANDS SECTION ===\n");
3646 pout(
"Enable autosave (clear GLTSD bit) failed\n");
3649 pout(
"Autosave enabled (GLTSD bit cleared).\n");
3654 if (options.
set_wce && is_disk) {
3655 short int enable = wce = (options.
set_wce > 0);
3659 pout(
"Write cache %sable failed: %s\n", (enable ?
"en" :
"dis"),
3663 pout(
"Write cache %sabled\n", (enable ?
"en" :
"dis"));
3668 if (options.
set_rcd && is_disk) {
3669 short int enable = (options.
set_rcd > 0);
3674 pout(
"Read cache %sable failed: %s\n", (enable ?
"en" :
"dis"),
3678 pout(
"Read cache %sabled\n", (enable ?
"en" :
"dis"));
3684 pout(
"Disable autosave (set GLTSD bit) failed\n");
3687 pout(
"Autosave disabled (GLTSD bit set).\n");
3699 pout(
"=== START OF READ SMART DATA SECTION ===\n");
3710 jout(
"TapeAlert Supported\n");
3711 jglb[
"tapealert"][
"supported"] =
true;
3718 jout(
"TapeAlert Not Supported\n");
3719 jglb[
"tapealert"][
"supported"] =
false;
3782 bool farm_supported =
true;
3787 jout(
"Seagate FARM log supported [try: -l farm]\n\n");
3792 pout(
"\nRead FARM log (SCSI Log page 0x3d, sub-page 0x3) failed\n\n");
3793 farm_supported =
false;
3800 jout(
"\nFARM log (SCSI Log page 0x3d, sub-page 0x3) not supported\n\n");
3802 farm_supported =
false;
3804 jglb[
"seagate_farm_log"][
"supported"] = farm_supported;
3817 pout(
"\n[GLTSD (Global Logging Target Save Disable) set. "
3818 "Enable Save with '-S on']\n");
3828 pout(
"Device does not support Self Test logging\n");
3841 pout(
"Device does not support Background scan results logging\n");
3853 pout(
"Device does not support %s logging\n",
zbds_s);
3865 pout(
"Device does not support %s logging\n",
gsap_s);
3879 pout(
"Device does not support (tape) device characteristics "
3892 pout(
"Device does not support TapeAlert logging\n");
3898 pout(
"TapeAlerts only printed if active, so none printed is good\n");
3905 pout(
"Default Self Test Successful\n");
3911 pout(
"Short Foreground Self Test Successful\n");
3917 (sense_info.
asc == 0x04 && sense_info.
ascq == 0x09)) {
3919 pout(
"Can't start self-test without aborting current test");
3921 pout(
" (%d%% remaining)",
3922 100 - sense_info.
progress * 100 / 65535);
3923 pout(
",\nadd '-t force' option to override, or run "
3924 "'smartctl -X' to abort test.\n");
3933 pout(
"Short Background Self Test has begun\n");
3934 pout(
"Use smartctl -X to abort test\n");
3940 pout(
"Extended Background Self Test has begun\n");
3943 time_t t = time(
nullptr);
3946 pout(
"Please wait %d minutes for test to complete.\n",
3950 pout(
"Estimated completion time: %s\n", comptime);
3952 pout(
"Use smartctl -X to abort test\n");
3958 pout(
"Extended Foreground Self Test Successful\n");
3963 pout(
"Self Test returned without error\n");
3982 pout(
"SCSI SSU(ACTIVE) command failed: %s\n",
3986 pout(
"Device placed in ACTIVE mode\n");
3988 pout(
"SCSI SSU(STANDBY) with timeout not supported yet\n");
3995 pout(
"Device placed in STANDBY mode\n");
3998 if (!any_output && powername)
3999 pout(
"Device is in %s mode\n", powername);
4002 pout(
"SCSI device successfully opened\n\nUse 'smartctl -a' (or '-x') "
4003 "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,...)