+static int
+scsiPrintFormatStatus(scsi_device * device)
+{
+ bool is_count;
+ int k, num, err, truncated;
+ int retval = 0;
+ uint64_t ull;
+ uint8_t * ucp;
+ uint8_t * xp;
+ const char * jout_str;
+ const char * jglb_str;
+ static const char * hname = "Format Status";
+ static const char * jname = "format_status";
+
+ if ((err = scsiLogSense(device, FORMAT_STATUS_LPAGE, 0, gBuf,
+ LOG_RESP_LONG_LEN, 0))) {
+ print_on();
+ jout("%s: Failed [%s]\n", __func__, scsiErrString(err));
+ print_off();
+ return FAILSMART;
+ }
+ if ((gBuf[0] & 0x3f) != FORMAT_STATUS_LPAGE) {
+ print_on();
+ jout("%s %s, page mismatch\n", hname, logSenRspStr);
+ print_off();
+ return FAILSMART;
+ }
+ // compute page length
+ num = sg_get_unaligned_be16(gBuf + 2) + 4;
+ if (num < 12) {
+ print_on();
+ jout("%s %s length is %d, too short\n", hname, logSenStr, num);
+ print_off();
+ return FAILSMART;
+ }
+ truncated = (num > LOG_RESP_LONG_LEN) ? num : 0;
+ if (truncated)
+ num = LOG_RESP_LONG_LEN;
+ ucp = gBuf + 4;
+ num -= 4;
+ while (num > 3) {
+ int pc = sg_get_unaligned_be16(ucp + 0);
+ // pcb = ucp[2];
+ int pl = ucp[3] + 4;
+
+ is_count = true;
+ jout_str = "";
+ jglb_str = "x";
+ switch (pc) {
+ case 0:
+ if (scsi_debugmode > 1) {
+ if (pl < 5)
+ jout("Format data out: <empty>\n");
+ else {
+ if (all_ffs(ucp + 4, pl - 4))
+ jout("Format data out: <not available>\n");
+ else {
+ jout("Format data out:\n");
+ dStrHex((const uint8_t *)ucp + 4, pl - 4, 0);
+ }
+ }
+ }
+ is_count = false;
+ break;
+ case 1:
+ jout_str = "Grown defects during certification";
+ jglb_str = "grown_defects_during_cert";
+ break;
+ case 2:
+ jout_str = "Total blocks reassigned during format";
+ jglb_str = "blocks_reassigned_during_format";
+ break;
+ case 3:
+ jout_str = "Total new blocks reassigned";
+ jglb_str = "total_new_block_since_format";
+ break;
+ case 4:
+ jout_str = "Power on minutes since format";
+ jglb_str = "power_on_minutes_since_format";
+ break;
+ default:
+ if (scsi_debugmode > 3) {
+ pout(" Unknown Format parameter code = 0x%x\n", pc);
+ dStrHex((const uint8_t *)ucp, pl, 0);
+ }
+ is_count = false;
+ break;
+ }
+ if (is_count) {
+ k = pl - 4;
+ xp = ucp + 4;
+ if (all_ffs(xp, k)) {
+ pout("%s <not available>\n", jout_str);
+ } else {
+ if (k > (int)sizeof(ull)) {
+ xp += (k - sizeof(ull));
+ k = sizeof(ull);
+ }
+ ull = sg_get_unaligned_be(k, xp);
+ jout("%s = %" PRIu64 "\n", jout_str, ull);
+ jglb[jname][jglb_str] = ull;
+ }
+ } else
+ num -= pl;
+ ucp += pl;
+ }
+ return retval;
+
+}
+