diff options
author | Douglas Gilbert <dgilbert@interlog.com> | 2022-07-19 04:02:56 +0000 |
---|---|---|
committer | Douglas Gilbert <dgilbert@interlog.com> | 2022-07-19 04:02:56 +0000 |
commit | 270cd7304dd379ee490df57120d281641c292398 (patch) | |
tree | 460d315db53c3b8214402650ad5b94bcba4c56dc /src | |
parent | f1c4468bc5353fa361029e790b3ab370d22d5101 (diff) | |
download | sg3_utils-270cd7304dd379ee490df57120d281641c292398.tar.gz |
another round of sgj_* function renaming; sg_inq+sg_vpd: add new Block Limits VPD page code
git-svn-id: https://svn.bingwo.ca/repos/sg3_utils/trunk@961 6180dd3e-e324-4e3e-922d-17de1ae2f315
Diffstat (limited to 'src')
-rw-r--r-- | src/sg_decode_sense.c | 38 | ||||
-rw-r--r-- | src/sg_get_elem_status.c | 41 | ||||
-rw-r--r-- | src/sg_get_lba_status.c | 52 | ||||
-rw-r--r-- | src/sg_inq.c | 264 | ||||
-rw-r--r-- | src/sg_opcodes.c | 96 | ||||
-rw-r--r-- | src/sg_rep_zones.c | 144 | ||||
-rw-r--r-- | src/sg_vpd.c | 233 | ||||
-rw-r--r-- | src/sg_vpd_common.c | 760 | ||||
-rw-r--r-- | src/sg_vpd_common.h | 7 |
9 files changed, 914 insertions, 721 deletions
diff --git a/src/sg_decode_sense.c b/src/sg_decode_sense.c index 8950cdbd..63e2ab26 100644 --- a/src/sg_decode_sense.c +++ b/src/sg_decode_sense.c @@ -30,7 +30,7 @@ #include "sg_unaligned.h" -static const char * version_str = "1.29 20220711"; +static const char * version_str = "1.30 20220717"; #define MY_NAME "sg_decode_sense" @@ -118,7 +118,7 @@ usage() " --inhex=HFN|-i HFN same as action as --file=HFN\n" " --json[=JO]|-j[JO] output in JSON instead of human " "readable text.\n" - " Use --json=? for JSON help\n" + " Use --json=? for JSON help\n" " --nodecode|-N do not decode, may be neither sense " "nor cdb\n" " --nospace|-n no spaces or other separators between " @@ -372,7 +372,7 @@ main(int argc, char *argv[]) as_json = op->json_st.pr_as_json; jsp = &op->json_st; if (as_json) - jop = sgj_start(MY_NAME, version_str, argc, argv, jsp); + jop = sgj_start_r(MY_NAME, version_str, argc, argv, jsp); if (op->err_given) { char d[128]; @@ -504,11 +504,11 @@ main(int argc, char *argv[]) printf("%s\n", b); } else { if (as_json) { - sgj_pr_js_sense(jsp, jop, op->sense, op->sense_len); + sgj_js_sense(jsp, jop, op->sense, op->sense_len); if (jsp->pr_out_hr) { sg_get_sense_str(NULL, op->sense, op->sense_len, op->verbose, blen, b); - sgj_pr_str_out_hr(jsp, b, strlen(b)); + sgj_js_str_out(jsp, b, strlen(b)); } } else { sg_get_sense_str(NULL, op->sense, op->sense_len, @@ -519,34 +519,8 @@ main(int argc, char *argv[]) } fini: if (as_json) { - -#if 0 -// <<<< testing -{ - sgj_opaque_p jo2p; - -// uint8_t dd[] = {0x1, 0x0, 0x0, 0x6, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66}; - -// uint8_t dd[] = {0x01, 0x00, 0x00, 0x16, 0x11, 0x22, 0x33, 0x44 , 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, -// 0xdd, 0xee, 0xff, 0xed, 0xcb, 0xa9, 0x87, 0x65 , 0x43, 0x21}; - -// uint8_t dd[] = {0x2, 0x1, 0x0, 0x14, -// 0x41, 0x42, 0x43, 0x20, 0x20, 0x20, 0x20, 0x20, -// 0x58, 0x59, 0x5a, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39}; - -// uint8_t dd[] = {0x01, 0x03, 0x00, 0x08, 0x51, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88}; -// uint8_t dd[] = {0x01, 0x03, 0x00, 0x10, 0x61, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, 0xee, 0xdd}; - -uint8_t dd[] = {0x01, 0x14, 0x00, 0x04, 0x0, 0x0, 0x0, 0x2, }; - -jo2p = sgj_new_named_object(jsp, jop, "designation_descriptor"); -sgj_get_designation_descriptor(jsp, jo2p, dd, sizeof(dd)); -} -// <<<< end of testing -#endif - if (0 == op->hex_count) - sgj_pr2file(&op->json_st, NULL, ret, stdout); + sgj_js2file(&op->json_st, NULL, ret, stdout); sgj_finish(jsp); } return ret; diff --git a/src/sg_get_elem_status.c b/src/sg_get_elem_status.c index 4501a935..f7f06a1f 100644 --- a/src/sg_get_elem_status.c +++ b/src/sg_get_elem_status.c @@ -37,7 +37,7 @@ * given SCSI device. */ -static const char * version_str = "1.12 20220626"; /* sbc5r01 */ +static const char * version_str = "1.13 20220717"; /* sbc5r02 */ #define MY_NAME "sg_get_elem_status" @@ -435,7 +435,7 @@ main(int argc, char * argv[]) return 0; } if (jsp->pr_as_json) - jop = sgj_start(MY_NAME, version_str, argc, argv, jsp); + jop = sgj_start_r(MY_NAME, version_str, argc, argv, jsp); if (maxlen > DEF_GPES_BUFF_LEN) { gpesBuffp = (uint8_t *)sg_memalign(maxlen, 0, &free_gpesBuffp, @@ -556,12 +556,12 @@ start_response: goto fini; } - sgj_pr_hr_js_vi(jsp, jop, 0, "Number of descriptors", - SGJ_SEP_COLON_1_SPACE, num_desc); - sgj_pr_hr_js_vi(jsp, jop, 0, "Number of descriptors returned", - SGJ_SEP_COLON_1_SPACE, num_desc_ret); - sgj_pr_hr_js_vi(jsp, jop, 0, "Identifier of element being depopulated", - SGJ_SEP_COLON_1_SPACE, id_elem_depop); + sgj_hr_js_vi(jsp, jop, 0, "Number of descriptors", + SGJ_SEP_COLON_1_SPACE, num_desc, true); + sgj_hr_js_vi(jsp, jop, 0, "Number of descriptors returned", + SGJ_SEP_COLON_1_SPACE, num_desc_ret, true); + sgj_hr_js_vi(jsp, jop, 0, "Identifier of element being depopulated", + SGJ_SEP_COLON_1_SPACE, id_elem_depop, true); if (rlen < 64) { sgj_pr_hr(jsp, "No complete physical element status descriptors " "available\n"); @@ -573,27 +573,26 @@ start_response: } if (jsp->pr_as_json) - jap = sgj_new_named_array(jsp, jop, - "physical_element_status_descriptor"); + jap = sgj_named_subarray_r(jsp, jop, + "physical_element_status_descriptor"); for (bp = gpesBuffp + GPES_DESC_OFFSET, k = 0; k < (int)num_desc_ret; bp += GPES_DESC_LEN, ++k) { if ((0 == k) && (do_brief < 2)) sgj_pr_hr(jsp, "Element descriptors:\n"); decode_elem_status_desc(bp, &a_ped); if (jsp->pr_as_json) { - jo2p = sgj_new_unattached_object(jsp); - sgj_add_nv_ihex(jsp, jo2p, "element_identifier", - (int64_t)a_ped.elem_id); + jo2p = sgj_new_unattached_object_r(jsp); + sgj_js_nv_ihex(jsp, jo2p, "element_identifier", + (int64_t)a_ped.elem_id); cp = (1 == a_ped.phys_elem_type) ? "storage" : "reserved"; - sgj_add_nv_istr(jsp, jo2p, "physical_element_type", - a_ped.phys_elem_type, "meaning", cp); + sgj_js_nv_istr(jsp, jo2p, "physical_element_type", + a_ped.phys_elem_type, "meaning", cp); j = a_ped.phys_elem_health; fetch_health_str(j, b, blen); - sgj_add_nv_istr(jsp, jo2p, "physical_element_health", j, - "meaning", b); - sgj_add_nv_ihex(jsp, jo2p, "associated_capacity", - (int64_t)a_ped.assoc_cap); - sgj_add_nv_o(jsp, jap, NULL /* name */, jo2p); + sgj_js_nv_istr(jsp, jo2p, "physical_element_health", j, NULL, b); + sgj_js_nv_ihex(jsp, jo2p, "associated_capacity", + (int64_t)a_ped.assoc_cap); + sgj_js_nv_o(jsp, jap, NULL /* name */, jo2p); } else if (do_brief) { sgj_pr_hr(jsp, "%u: %u,%u\n", a_ped.elem_id, a_ped.phys_elem_type, a_ped.phys_elem_health); @@ -655,7 +654,7 @@ fini: ret = (ret >= 0) ? ret : SG_LIB_CAT_OTHER; if (jsp->pr_as_json) { if (0 == do_hex) - sgj_pr2file(jsp, NULL, ret, stdout); + sgj_js2file(jsp, NULL, ret, stdout); sgj_finish(jsp); } return ret; diff --git a/src/sg_get_lba_status.c b/src/sg_get_lba_status.c index d85c5231..4ed45c81 100644 --- a/src/sg_get_lba_status.c +++ b/src/sg_get_lba_status.c @@ -35,7 +35,7 @@ * device. */ -static const char * version_str = "1.28 20220626"; /* sbc5r01 */ +static const char * version_str = "1.29 20220717"; /* sbc5r01 */ #define MY_NAME "sg_get_lba_status" @@ -198,7 +198,7 @@ get_prov_status_str(int ps, char * b, int blen) } static char * -get_add_status_str(int as, char * b, int blen) +get_pr_status_str(int as, char * b, int blen) { switch (as) { case 0: @@ -402,7 +402,7 @@ main(int argc, char * argv[]) return 0; } if (jsp->pr_as_json) - jop = sgj_start(MY_NAME, version_str, argc, argv, jsp); + jop = sgj_start_r(MY_NAME, version_str, argc, argv, jsp); if (maxlen > DEF_GLBAS_BUFF_LEN) { glbasBuffp = (uint8_t *)sg_memalign(maxlen, 0, &free_glbasBuffp, @@ -550,8 +550,8 @@ start_response: sgj_pr_hr(jsp,"p_status: %d add_status: 0x%x\n", res, (unsigned int)add_status); if (jsp->pr_as_json) { - sgj_add_nv_i(jsp, jop, prov_stat_s, res); - sgj_add_nv_i(jsp, jop, add_stat_s, add_status); + sgj_js_nv_i(jsp, jop, prov_stat_s, res); + sgj_js_nv_i(jsp, jop, add_stat_s, add_status); } goto fini; } @@ -563,8 +563,8 @@ start_response: num_descs = (rlen - 8) / 16; completion_cond = (*(glbasBuffp + 7) >> 1) & 7; /* added sbc4r14 */ if (do_brief) - sgj_pr_hr_js_vi(jsp, jop, 0, compl_cond_s, - SGJ_SEP_EQUAL_NO_SPACE, completion_cond); + sgj_hr_js_vi(jsp, jop, 0, compl_cond_s, SGJ_SEP_EQUAL_NO_SPACE, + completion_cond, true); else { switch (completion_cond) { case 0: @@ -587,15 +587,15 @@ start_response: break; } sgj_pr_hr(jsp, "%s\n", b); - sgj_add_nv_istr(jsp, jop, compl_cond_s, completion_cond, - NULL /* "meaning" */, b); + sgj_js_nv_istr(jsp, jop, compl_cond_s, completion_cond, + NULL /* "meaning" */, b); } - sgj_pr_hr_js_vi(jsp, jop, 0, "RTP", SGJ_SEP_EQUAL_NO_SPACE, - *(glbasBuffp + 7) & 0x1); /* added sbc4r12 */ + sgj_hr_js_vi(jsp, jop, 0, "RTP", SGJ_SEP_EQUAL_NO_SPACE, + *(glbasBuffp + 7) & 0x1, true); /* added sbc4r12 */ if (verbose) pr2serr("%d complete LBA status descriptors found\n", num_descs); if (jsp->pr_as_json) - jap = sgj_new_named_array(jsp, jop, "lba_status_descriptor"); + jap = sgj_named_subarray_r(jsp, jop, "lba_status_descriptor"); for (bp = glbasBuffp + 8, k = 0; k < num_descs; bp += 16, ++k) { res = decode_lba_status_desc(bp, &d_lba, &d_blocks, &add_status); @@ -603,7 +603,7 @@ start_response: pr2serr("descriptor %d: bad LBA status descriptor returned " "%d\n", k + 1, res); if (jsp->pr_as_json) - jo2p = sgj_new_unattached_object(jsp); + jo2p = sgj_new_unattached_object_r(jsp); if (do_brief) { n = 0; n += sg_scnpr(b + n, blen - n, "0x"); @@ -616,18 +616,18 @@ start_response: n += sg_scnpr(b + n, blen - n, " %u %d %d", (unsigned int)d_blocks, res, add_status); sgj_pr_hr(jsp, "%s\n", b); - sgj_add_nv_ihex(jsp, jo2p, "lba", d_lba); - sgj_add_nv_ihex(jsp, jo2p, "blocks", d_blocks); - sgj_add_nv_i(jsp, jo2p, prov_stat_s, res); - sgj_add_nv_i(jsp, jo2p, add_stat_s, add_status); + sgj_js_nv_ihex(jsp, jo2p, "lba", d_lba); + sgj_js_nv_ihex(jsp, jo2p, "blocks", d_blocks); + sgj_js_nv_i(jsp, jo2p, prov_stat_s, res); + sgj_js_nv_i(jsp, jo2p, add_stat_s, add_status); } else { if (jsp->pr_as_json) { - sgj_add_nv_ihex(jsp, jo2p, "lba", d_lba); - sgj_add_nv_ihex(jsp, jo2p, "blocks", d_blocks); - sgj_add_nv_istr(jsp, jo2p, prov_stat_s, res, NULL, - get_prov_status_str(res, b, blen)); - sgj_add_nv_istr(jsp, jo2p, add_stat_s, add_status, NULL, - get_add_status_str(add_status, b, blen)); + sgj_js_nv_ihex(jsp, jo2p, "lba", d_lba); + sgj_js_nv_ihex(jsp, jo2p, "blocks", d_blocks); + sgj_js_nv_istr(jsp, jo2p, prov_stat_s, res, NULL, + get_prov_status_str(res, b, blen)); + sgj_js_nv_istr(jsp, jo2p, add_stat_s, add_status, NULL, + get_pr_status_str(add_status, b, blen)); } else { char c[64]; @@ -644,14 +644,14 @@ start_response: (unsigned int)d_blocks); get_prov_status_str(res, c, sizeof(c)); n += sg_scnpr(b + n, blen - n, " %s", c); - get_add_status_str(add_status, c, sizeof(c)); + get_pr_status_str(add_status, c, sizeof(c)); if (strlen(c) > 0) n += sg_scnpr(b + n, blen - n, " [%s]", c); sgj_pr_hr(jsp, "%s\n", b); } } if (jsp->pr_as_json) - sgj_add_nv_o(jsp, jap, NULL /* name */, jo2p); + sgj_js_nv_o(jsp, jap, NULL /* name */, jo2p); } if ((num_descs * 16) + 8 < rlen) pr2serr("incomplete trailing LBA status descriptors found\n"); @@ -688,7 +688,7 @@ fini: ret = (ret >= 0) ? ret : SG_LIB_CAT_OTHER; if (jsp->pr_as_json) { if (0 == do_hex) - sgj_pr2file(jsp, NULL, ret, stdout); + sgj_js2file(jsp, NULL, ret, stdout); sgj_finish(jsp); } return ret; diff --git a/src/sg_inq.c b/src/sg_inq.c index 98f505d6..cf7c4064 100644 --- a/src/sg_inq.c +++ b/src/sg_inq.c @@ -53,7 +53,7 @@ #include "sg_vpd_common.h" /* for shared VPD page processing with sg_vpd */ -static const char * version_str = "2.21 20220714"; /* spc6r06 */ +static const char * version_str = "2.22 20220718"; /* spc6r06 */ #define MY_NAME "sg_inq" @@ -128,14 +128,15 @@ static void decode_dev_ids(const char * leadin, uint8_t * buff, int len, static int vpd_decode(int sg_fd, struct opts_t * op, sgj_opaque_p jop, int off); -// Testing <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< -#undef SG_SCSI_STRINGS +// Test define that will only work for Linux +// #define HDIO_GET_IDENTITY 1 #if defined(SG_LIB_LINUX) && defined(SG_SCSI_STRINGS) && \ defined(HDIO_GET_IDENTITY) +#include <sys/ioctl.h> + static int try_ata_identify(int ata_fd, int do_hex, int do_raw, int verbose); -struct opts_t; static void prepare_ata_identify(const struct opts_t * op, int inhex_len); #endif @@ -1102,12 +1103,12 @@ decode_supported_vpd(uint8_t * buff, int len, struct opts_t * op, snprintf(b, sizeof(b), "0x%x", vpd); vnp = get_vpd_page_info(vpd, pdt); if (jsp->pr_as_json && jap) { - jo2p = sgj_new_unattached_object(jsp); - sgj_add_nv_i(jsp, jo2p, "i", vpd); - sgj_add_nv_s(jsp, jo2p, "hex", b + 2); - sgj_add_nv_s(jsp, jo2p, "name", vnp ? vnp->name : "unknown"); - sgj_add_nv_s(jsp, jo2p, "acronym", vnp ? vnp->acron : "unknown"); - sgj_add_nv_o(jsp, jap, NULL /* name */, jo2p); + jo2p = sgj_new_unattached_object_r(jsp); + sgj_js_nv_i(jsp, jo2p, "i", vpd); + sgj_js_nv_s(jsp, jo2p, "hex", b + 2); + sgj_js_nv_s(jsp, jo2p, "name", vnp ? vnp->name : "unknown"); + sgj_js_nv_s(jsp, jo2p, "acronym", vnp ? vnp->acron : "unknown"); + sgj_js_nv_o(jsp, jap, NULL /* name */, jo2p); } if (vnp) sgj_pr_hr(jsp, " %s\t%s\n", b, vnp->name); @@ -1216,16 +1217,16 @@ decode_scsi_ports_vpd(uint8_t * buff, int len, struct opts_t * op, len -= 4; bp = buff + 4; for (k = 0; k < len; k += bump, bp += bump) { - jo2p = sgj_new_unattached_object(jsp); + jo2p = sgj_new_unattached_object_r(jsp); rel_port = sg_get_unaligned_be16(bp + 2); sgj_pr_hr(jsp, "Relative port=%d\n", rel_port); - sgj_add_nv_i(jsp, jo2p, "relative_port", rel_port); + sgj_js_nv_i(jsp, jo2p, "relative_port", rel_port); ip_tid_len = sg_get_unaligned_be16(bp + 6); bump = 8 + ip_tid_len; if ((k + bump) > len) { pr2serr("SCSI Ports VPD page, short descriptor " "length=%d, left=%d\n", bump, (len - k)); - sgj_add_nv_o(jsp, jap, NULL /* name */, jo2p); + sgj_js_nv_o(jsp, jap, NULL /* name */, jo2p); return; } if (ip_tid_len > 0) { @@ -1239,7 +1240,7 @@ decode_scsi_ports_vpd(uint8_t * buff, int len, struct opts_t * op, sg_decode_transportid_str(" ", bp + 8, ip_tid_len, true, sizeof(b), b); if (jsp->pr_as_json) - sgj_add_nv_s(jsp, jo2p, "initiator_port_transport_id", b); + sgj_js_nv_s(jsp, jo2p, "initiator_port_transport_id", b); sgj_pr_hr(jsp, "%s", sg_decode_transportid_str(" ", bp + 8, ip_tid_len, true, sizeof(b), b)); @@ -1249,7 +1250,7 @@ decode_scsi_ports_vpd(uint8_t * buff, int len, struct opts_t * op, if ((k + bump + tpd_len + 4) > len) { pr2serr("SCSI Ports VPD page, short descriptor(tgt) " "length=%d, left=%d\n", bump, (len - k)); - sgj_add_nv_o(jsp, jap, NULL /* name */, jo2p); + sgj_js_nv_o(jsp, jap, NULL /* name */, jo2p); return; } if (tpd_len > 0) { @@ -1258,7 +1259,7 @@ decode_scsi_ports_vpd(uint8_t * buff, int len, struct opts_t * op, hex2stdout(bp + bump + 4, tpd_len, (1 == op->do_hex) ? 1 : -1); else { - sgj_opaque_p ja2p = sgj_new_named_array(jsp, jo2p, + sgj_opaque_p ja2p = sgj_named_subarray_r(jsp, jo2p, "target_port_descriptor_list"); decode_dev_ids("SCSI Ports", bp + bump + 4, tpd_len, @@ -1266,7 +1267,7 @@ decode_scsi_ports_vpd(uint8_t * buff, int len, struct opts_t * op, } } bump += tpd_len + 4; - sgj_add_nv_o(jsp, jap, NULL /* name */, jo2p); + sgj_js_nv_o(jsp, jap, NULL /* name */, jo2p); } } @@ -1563,7 +1564,7 @@ decode_dev_ids(const char * leadin, uint8_t * buff, int len, } sgj_pr_hr(jsp, " MD5 logical unit identifier:\n"); if (jsp->pr_out_hr) - sgj_pr_str_out_hr(jsp, (const char *)ip, i_len); + sgj_js_str_out(jsp, (const char *)ip, i_len); else hex2stdout(ip, i_len, -1); break; @@ -1944,9 +1945,6 @@ static void decode_b0_vpd(uint8_t * buff, int len, int do_hex) { int pdt; - unsigned int u; - uint64_t ull; - bool ugavalid; if (do_hex) { hex2stdout(buff, len, (1 == do_hex) ? 0 : -1); @@ -1955,118 +1953,7 @@ decode_b0_vpd(uint8_t * buff, int len, int do_hex) pdt = PDT_MASK & buff[0]; switch (pdt) { case PDT_DISK: case PDT_WO: case PDT_OPTICAL: case PDT_ZBC: - if (len < 16) { - pr2serr("Block limits VPD page length too short=%d\n", len); - return; - } - u = buff[5]; - printf(" Maximum compare and write length: "); - if (0 == u) - printf("0 blocks [Command not implemented]\n"); - else - printf("%u blocks\n", buff[5]); - u = sg_get_unaligned_be16(buff + 6); - printf(" Optimal transfer length granularity: "); - if (0 == u) - printf("0 blocks [not reported]\n"); - else - printf("%u blocks\n", u); - u = sg_get_unaligned_be32(buff + 8); - printf(" Maximum transfer length: "); - if (0 == u) - printf("0 blocks [not reported]\n"); - else - printf("%u blocks\n", u); - u = sg_get_unaligned_be32(buff + 12); - printf(" Optimal transfer length: "); - if (0 == u) - printf("0 blocks [not reported]\n"); - else - printf("%u blocks\n", u); - if (len > 19) { /* added in sbc3r09 */ - u = sg_get_unaligned_be32(buff + 16); - printf(" Maximum prefetch transfer length: "); - if (0 == u) - printf("0 blocks [ignored]\n"); - else - printf("%u blocks\n", u); - } - if (len > 27) { /* added in sbc3r18 */ - u = sg_get_unaligned_be32(buff + 20); - printf(" Maximum unmap LBA count: "); - if (0 == u) - printf("0 [Unmap command not implemented]\n"); - else if (SG_LIB_UNBOUNDED_32BIT == u) - printf("-1 [unbounded]\n"); - else - printf("%u\n", u); - u = sg_get_unaligned_be32(buff + 24); - printf(" Maximum unmap block descriptor count: "); - if (0 == u) - printf("0 [Unmap command not implemented]\n"); - else if (SG_LIB_UNBOUNDED_32BIT == u) - printf("-1 [unbounded]\n"); - else - printf("%u\n", u); - } - if (len > 35) { /* added in sbc3r19 */ - u = sg_get_unaligned_be32(buff + 28); - printf(" Optimal unmap granularity: "); - if (0 == u) - printf("0 blocks [not reported]\n"); - else - printf("%u blocks\n", u); - - ugavalid = !!(buff[32] & 0x80); - printf(" Unmap granularity alignment valid: %s\n", - ugavalid ? "true" : "false"); - u = 0x7fffffff & sg_get_unaligned_be32(buff + 32); - printf(" Unmap granularity alignment: %u%s\n", u, - ugavalid ? "" : " [invalid]"); - } - if (len > 43) { /* added in sbc3r26 */ - ull = sg_get_unaligned_be64(buff + 36); - printf(" Maximum write same length: "); - if (0 == ull) - printf("0 blocks [not reported]\n"); - else - printf("0x%" PRIx64 " blocks\n", ull); - } - if (len > 44) { /* added in sbc4r02 */ - u = sg_get_unaligned_be32(buff + 44); - printf(" Maximum atomic transfer length: "); - if (0 == u) - printf("0 blocks [not reported]\n"); - else - printf("%u blocks\n", u); - u = sg_get_unaligned_be32(buff + 48); - printf(" Atomic alignment: "); - if (0 == u) - printf("0 [unaligned atomic writes permitted]\n"); - else - printf("%u\n", u); - u = sg_get_unaligned_be32(buff + 52); - printf(" Atomic transfer length granularity: "); - if (0 == u) - printf("0 [no granularity requirement\n"); - else - printf("%u\n", u); - } - if (len > 56) { - u = sg_get_unaligned_be32(buff + 56); - printf(" Maximum atomic transfer length with atomic " - "boundary: "); - if (0 == u) - printf("0 blocks [not reported]\n"); - else - printf("%u blocks\n", u); - u = sg_get_unaligned_be32(buff + 60); - printf(" Maximum atomic boundary size: "); - if (0 == u) - printf("0 blocks [can only write atomic 1 block]\n"); - else - printf("%u blocks\n", u); - } + /* done by decode_block_limits_vpd() */ break; case PDT_TAPE: case PDT_MCHANGER: printf(" WORM=%d\n", !!(buff[4] & 0x1)); @@ -2727,7 +2614,7 @@ std_inq_decode(struct opts_t * op, sgj_opaque_p jop, int off) if ((0 == op->maxlen) && usn_buff[0]) sgj_pr_hr(jsp, " Unit serial number: %s\n", usn_buff); if (op->do_descriptors) { - sgj_opaque_p jap = sgj_new_named_array(jsp, jo2p, + sgj_opaque_p jap = sgj_named_subarray_r(jsp, jo2p, "version_descriptor_list"); if (0 == vdesc_arr[0]) { sgj_pr_hr(jsp, "\n"); @@ -2736,7 +2623,7 @@ std_inq_decode(struct opts_t * op, sgj_opaque_p jop, int off) sgj_pr_hr(jsp, "\n"); sgj_pr_hr(jsp, " Version descriptors:\n"); for (k = 0; k < 8; ++k) { - sgj_opaque_p jo3p = sgj_new_unattached_object(jsp); + sgj_opaque_p jo3p = sgj_new_unattached_object_r(jsp); int vdv = vdesc_arr[k]; if (0 == vdv) @@ -2747,9 +2634,9 @@ std_inq_decode(struct opts_t * op, sgj_opaque_p jop, int off) else sgj_pr_hr(jsp, " [unrecognised version descriptor " "code: 0x%x]\n", vdv); - sgj_add_nv_ihexstr(jsp, jo3p, "version_descriptor", vdv, - NULL, cp ? cp : "unknown"); - sgj_add_nv_o(jsp, jap, NULL /* name */, jo3p); + sgj_js_nv_ihexstr(jsp, jo3p, "version_descriptor", vdv, + NULL, cp ? cp : "unknown"); + sgj_js_nv_o(jsp, jap, NULL /* name */, jo3p); } } } @@ -3208,7 +3095,7 @@ vpd_decode(int sg_fd, struct opts_t * op, sgj_opaque_p jop, int off) else { if (as_json) { jo2p = sg_vpd_js_hdr(jsp, jop, np, rp); - jap = sgj_new_named_array(jsp, jo2p, + jap = sgj_named_subarray_r(jsp, jo2p, "supported_vpd_page_list"); } decode_supported_vpd(rp, len, op, jap); @@ -3256,7 +3143,7 @@ vpd_decode(int sg_fd, struct opts_t * op, sgj_opaque_p jop, int off) k = encode_unicode((uint8_t *)obuff, len); if (k > 0) { sgj_pr_hr(jsp, " Unit serial number: %s\n", obuff); - sgj_add_nv_s(jsp, jo2p, "unit_serial_number", obuff); + sgj_js_nv_s(jsp, jo2p, "unit_serial_number", obuff); } } } @@ -3277,7 +3164,7 @@ vpd_decode(int sg_fd, struct opts_t * op, sgj_opaque_p jop, int off) else { if (as_json) { jo2p = sg_vpd_js_hdr(jsp, jop, np, rp); - jap = sgj_new_named_array(jsp, jo2p, + jap = sgj_named_subarray_r(jsp, jo2p, "designation_descriptor_list"); } decode_id_vpd(rp, len, op, jap); @@ -3295,7 +3182,7 @@ vpd_decode(int sg_fd, struct opts_t * op, sgj_opaque_p jop, int off) else { if (as_json) { jo2p = sg_vpd_js_hdr(jsp, jop, np, rp); - jap = sgj_new_named_array(jsp, jo2p, + jap = sgj_named_subarray_r(jsp, jo2p, "software_interface_identifier_list"); } decode_softw_inf_id(rp, len, op, jap); @@ -3316,7 +3203,7 @@ vpd_decode(int sg_fd, struct opts_t * op, sgj_opaque_p jop, int off) // pqual = (rp[0] & 0xe0) >> 5; if (as_json) { jo2p = sg_vpd_js_hdr(jsp, jop, np, rp); - jap = sgj_new_named_array(jsp, jo2p, + jap = sgj_named_subarray_r(jsp, jo2p, "network_services_descriptor_list"); } decode_net_man_vpd(rp, len, op, jap); @@ -3349,7 +3236,7 @@ vpd_decode(int sg_fd, struct opts_t * op, sgj_opaque_p jop, int off) else { if (as_json) { jo2p = sg_vpd_js_hdr(jsp, jop, np, rp); - jap = sgj_new_named_array(jsp, jo2p, + jap = sgj_named_subarray_r(jsp, jo2p, "mode_page_policy_descriptor_list"); } decode_mode_policy_vpd(rp, len, op, jap); @@ -3367,7 +3254,7 @@ vpd_decode(int sg_fd, struct opts_t * op, sgj_opaque_p jop, int off) else { if (as_json) { jo2p = sg_vpd_js_hdr(jsp, jop, np, rp); - jap = sgj_new_named_array(jsp, jo2p, + jap = sgj_named_subarray_r(jsp, jo2p, "scsi_ports_descriptor_list"); } decode_scsi_ports_vpd(rp, len, op, jap); @@ -3395,7 +3282,7 @@ vpd_decode(int sg_fd, struct opts_t * op, sgj_opaque_p jop, int off) } break; case VPD_POWER_CONDITION: /* 0x8a ["pc"] */ - np = "Power condition page VPD page"; + np = "Power condition VPD page"; if (!op->do_raw && (op->do_hex < 2)) sgj_pr_hr(jsp, "VPD INQUIRY: %s\n", np); res = vpd_fetch_page_from_dev(sg_fd, rp, pn, op->maxlen, vb, &len); @@ -3409,6 +3296,24 @@ vpd_decode(int sg_fd, struct opts_t * op, sgj_opaque_p jop, int off) decode_power_condition(rp, len, op, jo2p); } break; + case VPD_POWER_CONSUMPTION: /* 0x8d ["psm"] */ + np = "Power consumption VPD page"; + if (!op->do_raw && (op->do_hex < 2)) + sgj_pr_hr(jsp, "VPD INQUIRY: %s\n", np); + res = vpd_fetch_page_from_dev(sg_fd, rp, pn, op->maxlen, vb, &len); + if (res) + break; + if (op->do_raw) + dStrRaw((const char *)rp, len); + else { + if (as_json) { + jo2p = sg_vpd_js_hdr(jsp, jop, np, rp); + jap = sgj_named_subarray_r(jsp, jo2p, + "power_consumption_descriptor_list"); + } + decode_power_consumption(rp, len, jop, jap); + } + break; case VPD_DEVICE_CONSTITUENTS: /* 0x8b ["dc"] */ np = "Device constituents page VPD page"; if (!op->do_raw && (op->do_hex < 2)) @@ -3421,7 +3326,7 @@ vpd_decode(int sg_fd, struct opts_t * op, sgj_opaque_p jop, int off) else { if (as_json) { jo2p = sg_vpd_js_hdr(jsp, jop, np, rp); - jap = sgj_new_named_array(jsp, jo2p, + jap = sgj_named_subarray_r(jsp, jo2p, "constituent_descriptor_list"); } decode_dev_constit_vpd(rp, len, op, jap, recurse_vpd_decode); @@ -3439,36 +3344,57 @@ vpd_decode(int sg_fd, struct opts_t * op, sgj_opaque_p jop, int off) else { if (as_json) { jo2p = sg_vpd_js_hdr(jsp, jop, np, rp); - jap = sgj_new_named_array(jsp, jo2p, + jap = sgj_named_subarray_r(jsp, jo2p, "feature_set_code_list"); } decode_feature_sets_vpd(rp, len, op, jap); } break; case 0xb0: /* VPD pages in B0h to BFh range depend on pdt */ + np = NULL; res = vpd_fetch_page_from_dev(sg_fd, rp, pn, op->maxlen, vb, &len); if (0 == res) { + bool bl = false; + bool sad = false; + bool oi = false; + const char * ep = ""; + + if (op->do_raw) { + dStrRaw((const char *)rp, len); + break; + } pdt = rp[0] & PDT_MASK; - if (! op->do_raw && (op->do_hex < 2)) { - switch (pdt) { - case PDT_DISK: case PDT_WO: case PDT_OPTICAL: case PDT_ZBC: - printf("VPD INQUIRY: Block limits page (SBC)\n"); - break; - case PDT_TAPE: case PDT_MCHANGER: - printf("VPD INQUIRY: Sequential access device " - "capabilities (SSC)\n"); - break; - case PDT_OSD: - printf("VPD INQUIRY: OSD information (OSD)\n"); - break; - default: - printf("VPD INQUIRY: page=0x%x, pdt=0x%x\n", 0xb0, pdt); - break; - } + switch (pdt) { + case PDT_DISK: case PDT_WO: case PDT_OPTICAL: case PDT_ZBC: + np = "Block limits VPD page"; + ep = "(SBC)"; + bl = true; + break; + case PDT_TAPE: case PDT_MCHANGER: + np = "Sequential-access device capabilities VPD page"; + ep = "(SSC)"; + sad = true; + break; + case PDT_OSD: + np = "OSD information VPD page"; + ep = "(OSD)"; + oi = true; + break; + default: + np = NULL; + break; } - if (op->do_raw) - dStrRaw((const char *)rp, len); - else + if (op->do_hex < 2) { + if (NULL == np) + sgj_pr_hr(jsp, "VPD page=0x%x, pdt=0x%x:\n", pn, pdt); + else + sgj_pr_hr(jsp, "VPD INQUIRY: %s %s\n", np, ep); + } + if (as_json) + jo2p = sg_vpd_js_hdr(jsp, jop, np, rp); + if (bl) + decode_block_limits_vpd(rp, len, op, jo2p); + else if (sad || oi) // more work here <<<<<<<<<< decode_b0_vpd(rp, len, op->do_hex); } else if (! op->do_raw) pr2serr("VPD INQUIRY: page=0xb0\n"); @@ -4108,7 +4034,7 @@ main(int argc, char * argv[]) jsp = &op->json_st; as_json = jsp->pr_as_json; if (as_json) - jop = sgj_start(MY_NAME, version_str, argc, argv, jsp); + jop = sgj_start_r(MY_NAME, version_str, argc, argv, jsp); rsp_buff = sg_memalign(rsp_buff_sz, 0 /* page align */, &free_rsp_buff, false); @@ -4397,7 +4323,7 @@ err_out: ret = (ret >= 0) ? ret : SG_LIB_CAT_OTHER; if (as_json) { if (0 == op->do_hex) - sgj_pr2file(jsp, NULL, ret, stdout); + sgj_js2file(jsp, NULL, ret, stdout); sgj_finish(jsp); } return ret; diff --git a/src/sg_opcodes.c b/src/sg_opcodes.c index 4d8fe0c7..bb092065 100644 --- a/src/sg_opcodes.c +++ b/src/sg_opcodes.c @@ -33,7 +33,7 @@ #include "sg_pt.h" -static const char * version_str = "0.84 20220626"; /* spc6r06 */ +static const char * version_str = "0.85 20220717"; /* spc6r06 */ #define MY_NAME "sg_opcodes" @@ -785,9 +785,9 @@ list_all_codes(uint8_t * rsoc_buff, int rsoc_len, struct opts_t * op, (op->do_alpha ? opcode_alpha_compare : opcode_num_compare)); } - jap = sgj_new_named_array(jsp, jsp->basep, "all_command_descriptor"); + jap = sgj_named_subarray_r(jsp, jsp->basep, "all_command_descriptor"); for (k = 0, j = 0; k < cd_len; ++j, k += len) { - jop = sgj_new_unattached_object(jsp); + jop = sgj_new_unattached_object_r(jsp); bp = op->do_unsorted ? (rsoc_buff + 4 + k) : sort_arr[j]; byt5 = bp[5]; @@ -858,22 +858,22 @@ list_all_codes(uint8_t * rsoc_buff, int rsoc_len, struct opts_t * op, } if (jsp->pr_as_json) { snprintf(b, blen, "0x%x", opcode); - sgj_add_nv_s(jsp, jop, "operation_code", b); + sgj_js_nv_s(jsp, jop, "operation_code", b); if (sa_v) { snprintf(b, blen, "0x%x", serv_act); - sgj_add_nv_s(jsp, jop, "service_action", b); + sgj_js_nv_s(jsp, jop, "service_action", b); } if (name_buff[0]) - sgj_add_nv_s(jsp, jop, "name", name_buff); - sgj_add_nv_i(jsp, jop, "rwcdlp", (byt5 >> 6) & 0x1); - sgj_add_nv_i(jsp, jop, "mlu", (byt5 >> 4) & 0x3); - sgj_add_nv_i(jsp, jop, "cdlp", (byt5 >> 2) & 0x3); - sgj_add_nv_i(jsp, jop, "ctdp", (byt5 >> 1) & 0x1); - sgj_add_nv_i(jsp, jop, "servactv", byt5 & 0x1); - sgj_add_nv_i(jsp, jop, "cdb_length", - sg_get_unaligned_be16(bp + 6)); - - sgj_add_nv_o(jsp, jap, NULL /* implies an array add */, jop); + sgj_js_nv_s(jsp, jop, "name", name_buff); + sgj_js_nv_i(jsp, jop, "rwcdlp", (byt5 >> 6) & 0x1); + sgj_js_nv_i(jsp, jop, "mlu", (byt5 >> 4) & 0x3); + sgj_js_nv_i(jsp, jop, "cdlp", (byt5 >> 2) & 0x3); + sgj_js_nv_i(jsp, jop, "ctdp", (byt5 >> 1) & 0x1); + sgj_js_nv_i(jsp, jop, "servactv", byt5 & 0x1); + sgj_js_nv_i(jsp, jop, "cdb_length", + sg_get_unaligned_be16(bp + 6)); + + sgj_js_nv_o(jsp, jap, NULL /* implies an array add */, jop); } if (op->do_mask && ptvp) { @@ -903,14 +903,14 @@ list_all_codes(uint8_t * rsoc_buff, int rsoc_len, struct opts_t * op, if (jsp->pr_as_json) { int l; char *b2p = b + nn; - sgj_opaque_p jo2p = sgj_new_named_object(jsp, jop, + sgj_opaque_p jo2p = sgj_named_subobject_r(jsp, jop, "one_command_descriptor"); l = strlen(b2p); if ((l > 0) && (' ' == b2p[l - 1])) b2p[l - 1] = '\0'; - sgj_add_nv_i(jsp, jo2p, "cdb_size", cdb_sz); - sgj_add_nv_s(jsp, jo2p, "cdb_usage_data", b2p); + sgj_js_nv_i(jsp, jo2p, "cdb_size", cdb_sz); + sgj_js_nv_s(jsp, jo2p, "cdb_usage_data", b2p); } } } else @@ -948,9 +948,9 @@ decode_cmd_timeout_desc(uint8_t * dp, int max_b_len, char * b, else snprintf(b, max_b_len, "nominal timeout: %u secs, ", timeout); if (jsp->pr_as_json) { - sgj_add_nv_i(jsp, jsp->userp, "command_specific", dp[3]); - sgj_add_nv_i(jsp, jsp->userp, "nominal_command_processing_timeout", - timeout); + sgj_js_nv_i(jsp, jsp->userp, "command_specific", dp[3]); + sgj_js_nv_i(jsp, jsp->userp, "nominal_command_processing_timeout", + timeout); } len = strlen(b); max_b_len -= len; @@ -961,7 +961,7 @@ decode_cmd_timeout_desc(uint8_t * dp, int max_b_len, char * b, else snprintf(b, max_b_len, "recommended timeout: %u secs", timeout); if (jsp->pr_as_json) - sgj_add_nv_i(jsp, jsp->userp, "recommended_command_timeout", timeout); + sgj_js_nv_i(jsp, jsp->userp, "recommended_command_timeout", timeout); return; } @@ -986,7 +986,7 @@ list_one(uint8_t * rsoc_buff, int cd_len, int rep_opts, const int blen = sizeof(b); - jop = sgj_new_named_object(jsp, jsp->basep, "one_command_descriptor"); + jop = sgj_named_subobject_r(jsp, jsp->basep, "one_command_descriptor"); n += sg_scnpr(b + n, blen - n, "\n Opcode=0x%.2x", op->opcode); if (rep_opts > 1) n += sg_scnpr(b + n, blen - n, " Service_action=0x%.4x", op->servact); @@ -1077,29 +1077,29 @@ list_one(uint8_t * rsoc_buff, int cd_len, int rep_opts, int l; snprintf(b, blen, "0x%x", op->opcode); - sgj_add_nv_s(jsp, jop, "operation_code", b); + sgj_js_nv_s(jsp, jop, "operation_code", b); if (rep_opts > 1) { snprintf(b, blen, "0x%x", op->servact); - sgj_add_nv_s(jsp, jop, "service_action", b); + sgj_js_nv_s(jsp, jop, "service_action", b); } - sgj_add_nv_i(jsp, jop, "rwcdlp", rwcdlp); - sgj_add_nv_i(jsp, jop, "ctdp", ctdp); - sgj_add_nv_i(jsp, jop, "mlu", mlu); - sgj_add_nv_i(jsp, jop, "cdlp", cdlp); - sgj_add_nv_i(jsp, jop, "support", support); - sgj_add_nv_s(jsp, jop, "support_str", cp); - sgj_add_nv_i(jsp, jop, "cdb_size", cd_len); + sgj_js_nv_i(jsp, jop, "rwcdlp", rwcdlp); + sgj_js_nv_i(jsp, jop, "ctdp", ctdp); + sgj_js_nv_i(jsp, jop, "mlu", mlu); + sgj_js_nv_i(jsp, jop, "cdlp", cdlp); + sgj_js_nv_i(jsp, jop, "support", support); + sgj_js_nv_s(jsp, jop, "support_str", cp); + sgj_js_nv_i(jsp, jop, "cdb_size", cd_len); n = 0; for (k = 0; k < cd_len; ++k) n += sg_scnpr(b + n, blen - n, "%.2x ", rsoc_buff[k + 4]); l = strlen(b); if ((l > 0) && (' ' == b[l - 1])) b[l - 1] = '\0'; - sgj_add_nv_s(jsp, jop, "cdb_usage_data", b); + sgj_js_nv_s(jsp, jop, "cdb_usage_data", b); } if (ctdp) { - jsp->userp = sgj_new_named_object(jsp, jsp->basep, - "command_timeouts_descriptor"); + jsp->userp = sgj_named_subobject_r(jsp, jsp->basep, + "command_timeouts_descriptor"); bp = rsoc_buff + 4 + cd_len; decode_cmd_timeout_desc(bp, NAME_BUFF_SZ, name_buff, op); sgj_pr_hr(jsp, " %s\n", name_buff); @@ -1144,7 +1144,7 @@ main(int argc, char * argv[]) jsp = &op->json_st; as_json = jsp->pr_as_json; if (as_json) { - jop = sgj_start(MY_NAME, version_str, argc, argv, jsp); + jop = sgj_start_r(MY_NAME, version_str, argc, argv, jsp); } #ifdef DEBUG pr2serr("In DEBUG mode, "); @@ -1375,17 +1375,17 @@ start_response: goto fini; } if (jsp->pr_as_json) { - sgj_add_nv_b(jsp, jop, "ats", rsoc_buff[0] & 0x80); - sgj_add_nv_b(jsp, jop, "atss", rsoc_buff[0] & 0x40); - sgj_add_nv_b(jsp, jop, "cacas", rsoc_buff[0] & 0x20); - sgj_add_nv_b(jsp, jop, "ctss", rsoc_buff[0] & 0x10); - sgj_add_nv_b(jsp, jop, "lurs", rsoc_buff[0] & 0x8); - sgj_add_nv_b(jsp, jop, "qts", rsoc_buff[0] & 0x4); - sgj_add_nv_b(jsp, jop, "trs", rsoc_buff[0] & 0x2); - sgj_add_nv_b(jsp, jop, "ws", rsoc_buff[0] & 0x1); - sgj_add_nv_b(jsp, jop, "qaes", rsoc_buff[1] & 0x4); - sgj_add_nv_b(jsp, jop, "qtss", rsoc_buff[1] & 0x2); - sgj_add_nv_b(jsp, jop, "itnrs", rsoc_buff[1] & 0x1); + sgj_js_nv_b(jsp, jop, "ats", rsoc_buff[0] & 0x80); + sgj_js_nv_b(jsp, jop, "atss", rsoc_buff[0] & 0x40); + sgj_js_nv_b(jsp, jop, "cacas", rsoc_buff[0] & 0x20); + sgj_js_nv_b(jsp, jop, "ctss", rsoc_buff[0] & 0x10); + sgj_js_nv_b(jsp, jop, "lurs", rsoc_buff[0] & 0x8); + sgj_js_nv_b(jsp, jop, "qts", rsoc_buff[0] & 0x4); + sgj_js_nv_b(jsp, jop, "trs", rsoc_buff[0] & 0x2); + sgj_js_nv_b(jsp, jop, "ws", rsoc_buff[0] & 0x1); + sgj_js_nv_b(jsp, jop, "qaes", rsoc_buff[1] & 0x4); + sgj_js_nv_b(jsp, jop, "qtss", rsoc_buff[1] & 0x2); + sgj_js_nv_b(jsp, jop, "itnrs", rsoc_buff[1] & 0x1); if (! jsp->pr_out_hr) goto fini; } @@ -1493,7 +1493,7 @@ err_out: res = (res >= 0) ? res : SG_LIB_CAT_OTHER; if (as_json) { if (0 == op->do_hex) - sgj_pr2file(jsp, NULL, res, stdout); + sgj_js2file(jsp, NULL, res, stdout); sgj_finish(jsp); } return res; diff --git a/src/sg_rep_zones.c b/src/sg_rep_zones.c index 8fc733ff..d6c03e7c 100644 --- a/src/sg_rep_zones.c +++ b/src/sg_rep_zones.c @@ -40,7 +40,7 @@ * Based on zbc2r12.pdf */ -static const char * version_str = "1.40 20220625"; +static const char * version_str = "1.41 20220717"; #define MY_NAME "sg_rep_zones" @@ -394,28 +394,28 @@ prt_a_zn_desc(const uint8_t *bp, const struct opts_t * op, zc = (bp[1] >> 4) & 0xf; sg_get_zone_type_str(zt, sizeof(b), b); sgj_pr_hr(jsp, " Zone type: %s\n", b); - sgj_add_nv_istr(jsp, jop, "zone_type", zt, meaning_s, b); + sgj_js_nv_istr(jsp, jop, "zone_type", zt, meaning_s, b); zone_condition_str(zc, b, sizeof(b), op->vb); sgj_pr_hr(jsp, " Zone condition: %s\n", b); - sgj_add_nv_istr(jsp, jop, "zone_condition", zc, meaning_s, b); - sgj_pr_hr_js_vi(jsp, jop, 3, "PUEP", SGJ_SEP_COLON_1_SPACE, - !!(bp[1] & 0x4)); - sgj_pr_hr_js_vi(jsp, jop, 3, "NON_SEQ", SGJ_SEP_COLON_1_SPACE, - !!(bp[1] & 0x2)); - sgj_pr_hr_js_vi(jsp, jop, 3, "RESET", SGJ_SEP_COLON_1_SPACE, - !!(bp[1] & 0x1)); + sgj_js_nv_istr(jsp, jop, "zone_condition", zc, meaning_s, b); + sgj_hr_js_vi(jsp, jop, 3, "PUEP", SGJ_SEP_COLON_1_SPACE, + !!(bp[1] & 0x4), false); + sgj_hr_js_vi(jsp, jop, 3, "NON_SEQ", SGJ_SEP_COLON_1_SPACE, + !!(bp[1] & 0x2), false); + sgj_hr_js_vi(jsp, jop, 3, "RESET", SGJ_SEP_COLON_1_SPACE, + !!(bp[1] & 0x1), false); len = sg_get_unaligned_be64(bp + 8); sgj_pr_hr(jsp, " Zone Length: 0x%" PRIx64 "\n", len); - sgj_add_nv_ihex(jsp, jop, "zone_length", (int64_t)len); + sgj_js_nv_ihex(jsp, jop, "zone_length", (int64_t)len); lba = sg_get_unaligned_be64(bp + 16); sgj_pr_hr(jsp, " Zone start LBA: 0x%" PRIx64 "\n", lba); - sgj_add_nv_ihex(jsp, jop, "zone_start_lba", (int64_t)lba); + sgj_js_nv_ihex(jsp, jop, "zone_start_lba", (int64_t)lba); wp = sg_get_unaligned_be64(bp + 24); if (sg_all_ffs((const uint8_t *)&wp, sizeof(wp))) sgj_pr_hr(jsp, " Write pointer LBA: -1\n"); else sgj_pr_hr(jsp, " Write pointer LBA: 0x%" PRIx64 "\n", wp); - sgj_add_nv_ihex(jsp, jop, "write_pointer_lba", (int64_t)wp); + sgj_js_nv_ihex(jsp, jop, "write_pointer_lba", (int64_t)wp); return lba + len; } @@ -456,12 +456,12 @@ decode_rep_zones(const uint8_t * rzBuff, int act_len, uint32_t decod_len, "granularity"; sgj_pr_hr(jsp, " Same=%d: %s\n", same, same_desc_arr[same]); - sgj_add_nv_istr(jsp, jop, "same", same, meaning_s, - same_desc_arr[same]); + sgj_js_nv_istr(jsp, jop, "same", same, meaning_s, + same_desc_arr[same]); sgj_pr_hr(jsp, " Maximum LBA: 0x%" PRIx64 "\n\n", mx_lba); - sgj_add_nv_ihex(jsp, jop, "maximum_lba", mx_lba); + sgj_js_nv_ihex(jsp, jop, "maximum_lba", mx_lba); sgj_pr_hr(jsp, " %s: 0x%" PRIx64 "\n\n", rzslbag_s, rzslbag); - sgj_add_nv_ihex(jsp, jop, rzslbag_s, rzslbag); + sgj_js_nv_ihex(jsp, jop, rzslbag_s, rzslbag); } if (op->do_num > 0) num_zd = (num_zd > op->do_num) ? op->do_num : num_zd; @@ -482,7 +482,7 @@ decode_rep_zones(const uint8_t * rzBuff, int act_len, uint32_t decod_len, } sgj_pr_hr(jsp, "From last descriptor in this response:\n"); sgj_pr_hr(jsp, " %s%d\n", zn_dnum_s, num_zd - 1); - sgj_add_nv_i(jsp, jop, "zone_descriptor_index", num_zd - 1); + sgj_js_nv_i(jsp, jop, "zone_descriptor_index", num_zd - 1); ul = prt_a_zn_desc(bp, op, jsp, jop); if (ul > mx_lba) sgj_pr_hr(jsp, " >> This zone seems to be the last one\n"); @@ -492,7 +492,7 @@ decode_rep_zones(const uint8_t * rzBuff, int act_len, uint32_t decod_len, return 0; } if (as_json) - jap = sgj_new_named_array(jsp, NULL, "zone_descriptors_list"); + jap = sgj_named_subarray_r(jsp, NULL, "zone_descriptors_list"); for (k = 0, bp = rzBuff + 64; k < num_zd; ++k, bp += REPORT_ZONES_DESC_LEN) { sgj_opaque_p jo2p; @@ -512,15 +512,15 @@ decode_rep_zones(const uint8_t * rzBuff, int act_len, uint32_t decod_len, sgj_pr_hr(jsp, "-1\n"); else sgj_pr_hr(jsp, "0x%" PRIx64 "\n", wp); - jo2p = sgj_new_unattached_object(jsp); - sgj_add_nv_ihex(jsp, jo2p, "write_pointer_lba", (int64_t)wp); - sgj_add_nv_o(jsp, jap, NULL /* name */, jo2p); + jo2p = sgj_new_unattached_object_r(jsp); + sgj_js_nv_ihex(jsp, jo2p, "write_pointer_lba", (int64_t)wp); + sgj_js_nv_o(jsp, jap, NULL /* name */, jo2p); } continue; } - jo2p = sgj_new_unattached_object(jsp); + jo2p = sgj_new_unattached_object_r(jsp); prt_a_zn_desc(bp, op, jsp, jo2p); - sgj_add_nv_o(jsp, jap, NULL /* name */, jo2p); + sgj_js_nv_o(jsp, jap, NULL /* name */, jo2p); } if ((op->do_num == 0) && (! op->wp_only) && (! op->do_hex)) { if ((64 + (REPORT_ZONES_DESC_LEN * (uint32_t)num_zd)) < decod_len) @@ -552,12 +552,12 @@ decode_rep_realms(const uint8_t * rzBuff, int act_len, nr_locator = sg_get_unaligned_be64(rzBuff + 12); else nr_locator = 0; - sgj_pr_hr_js_vi(jsp, jop, 0, "Realms_count", SGJ_SEP_EQUAL_NO_SPACE, - realms_count); - sgj_pr_hr_js_vi(jsp, jop, 0, "Realms_descriptor_length", - SGJ_SEP_EQUAL_NO_SPACE, r_desc_len); + sgj_hr_js_vi(jsp, jop, 0, "Realms_count", SGJ_SEP_EQUAL_NO_SPACE, + realms_count, true); + sgj_hr_js_vi(jsp, jop, 0, "Realms_descriptor_length", + SGJ_SEP_EQUAL_NO_SPACE, r_desc_len, true); sgj_pr_hr(jsp, "Next_realm_locator=0x%" PRIx64 "\n", nr_locator); - sgj_add_nv_ihex(jsp, jop, "Next_realm_locator", nr_locator); + sgj_js_nv_ihex(jsp, jop, "Next_realm_locator", nr_locator); if ((realms_count < 1) || (act_len < (64 + 16)) || (r_desc_len < 16)) { if (op->vb) { pr2serr("%s: exiting early because ", __func__); @@ -587,7 +587,7 @@ decode_rep_realms(const uint8_t * rzBuff, int act_len, if (op->do_num > 0) realms_count = (realms_count > (uint32_t)op->do_num) ? (uint32_t)op->do_num : realms_count; - jap = sgj_new_named_array(jsp, jop, "realm_descriptors_list"); + jap = sgj_named_subarray_r(jsp, jop, "realm_descriptors_list"); for (k = 0, bp = rzBuff + 64; k < realms_count; ++k, bp += r_desc_len) { uint32_t j; @@ -595,37 +595,37 @@ decode_rep_realms(const uint8_t * rzBuff, int act_len, const uint8_t * zp; sgj_opaque_p jo2p; - jo2p = sgj_new_unattached_object(jsp); - sgj_pr_hr_js_vi(jsp, jo2p, 1, "Realms_id", SGJ_SEP_EQUAL_NO_SPACE, - sg_get_unaligned_be32(bp + 0)); + jo2p = sgj_new_unattached_object_r(jsp); + sgj_hr_js_vi(jsp, jo2p, 1, "Realms_id", SGJ_SEP_EQUAL_NO_SPACE, + sg_get_unaligned_be32(bp + 0), true); if (op->do_hex) { hex2stdout(bp, r_desc_len, -1); continue; } restrictions = sg_get_unaligned_be16(bp + 4); sgj_pr_hr(jsp, " realm_restrictions=0x%hu\n", restrictions); - sgj_add_nv_ihex(jsp, jo2p, "realm_restrictions", restrictions); - sgj_pr_hr_js_vi(jsp, jo2p, 3, "active_zone_domain_id", - SGJ_SEP_EQUAL_NO_SPACE, bp[7]); + sgj_js_nv_ihex(jsp, jo2p, "realm_restrictions", restrictions); + sgj_hr_js_vi(jsp, jo2p, 3, "active_zone_domain_id", + SGJ_SEP_EQUAL_NO_SPACE, bp[7], true); - ja2p = sgj_new_named_array(jsp, jo2p, - "realm_start_end_descriptors_list"); + ja2p = sgj_named_subarray_r(jsp, jo2p, + "realm_start_end_descriptors_list"); for (j = 0, zp = bp + 16; j < zdomains_count; ++j, zp += 16) { uint64_t lba; sgj_opaque_p jo3p; - jo3p = sgj_new_unattached_object(jsp); + jo3p = sgj_new_unattached_object_r(jsp); sgj_pr_hr(jsp, " zone_domain=%u\n", j); - sgj_add_nv_i(jsp, jo3p, "corresponding_zone_domain_id", j); + sgj_js_nv_i(jsp, jo3p, "corresponding_zone_domain_id", j); lba = sg_get_unaligned_be64(zp + 0); sgj_pr_hr(jsp, " starting_lba=0x%" PRIx64 "\n", lba); - sgj_add_nv_ihex(jsp, jo3p, "realm_starting_lba", (int64_t)lba); + sgj_js_nv_ihex(jsp, jo3p, "realm_starting_lba", (int64_t)lba); lba = sg_get_unaligned_be64(zp + 8); sgj_pr_hr(jsp, " ending_lba=0x%" PRIx64 "\n", lba); - sgj_add_nv_ihex(jsp, jo3p, "realm_ending_lba", (int64_t)lba); - sgj_add_nv_o(jsp, ja2p, NULL /* name */, jo3p); + sgj_js_nv_ihex(jsp, jo3p, "realm_ending_lba", (int64_t)lba); + sgj_js_nv_o(jsp, ja2p, NULL /* name */, jo3p); } - sgj_add_nv_o(jsp, jap, NULL /* name */, jo2p); + sgj_js_nv_o(jsp, jap, NULL /* name */, jo2p); } return 0; } @@ -654,46 +654,46 @@ decode_rep_zdomains(const uint8_t * rzBuff, int act_len, zd_locator = sg_get_unaligned_be64(rzBuff + 16); else zd_locator = 0; - sgj_pr_hr_js_vi(jsp, jop, 0, "Zone_domains_returned_list_length=", - SGJ_SEP_EQUAL_NO_SPACE, zd_ret_len); - sgj_pr_hr_js_vi(jsp, jop, 0, "Zone_domains_supported", - SGJ_SEP_EQUAL_NO_SPACE, zdoms_sup); - sgj_pr_hr_js_vi(jsp, jop, 0, "Zone_domains_reported", - SGJ_SEP_EQUAL_NO_SPACE, zdoms_rep); + sgj_hr_js_vi(jsp, jop, 0, "Zone_domains_returned_list_length=", + SGJ_SEP_EQUAL_NO_SPACE, zd_ret_len, true); + sgj_hr_js_vi(jsp, jop, 0, "Zone_domains_supported", + SGJ_SEP_EQUAL_NO_SPACE, zdoms_sup, true); + sgj_hr_js_vi(jsp, jop, 0, "Zone_domains_reported", + SGJ_SEP_EQUAL_NO_SPACE, zdoms_rep, true); sgj_pr_hr(jsp, "Reporting_options=0x%x\n", zd_rep_opts); - sgj_add_nv_ihex(jsp, jop, "Reporting_options", zd_rep_opts); + sgj_js_nv_ihex(jsp, jop, "Reporting_options", zd_rep_opts); sgj_pr_hr(jsp, "Zone_domain_locator=0x%" PRIx64 "\n", zd_locator); - sgj_add_nv_ihex(jsp, jop, "Zone_domain_locator", zd_locator); + sgj_js_nv_ihex(jsp, jop, "Zone_domain_locator", zd_locator); der_zdoms = zd_len / 96; if (op->vb > 1) pr2serr("Derived zdomains=%u\n", der_zdoms); num = ((der_zdoms < zdoms_rep) ? der_zdoms : zdoms_rep) * 96; - jap = sgj_new_named_array(jsp, jop, "zone_domain_descriptors_list"); + jap = sgj_named_subarray_r(jsp, jop, "zone_domain_descriptors_list"); for (k = 0, bp = rzBuff + 64; k < num; k += 96, bp += 96) { uint64_t lba; sgj_opaque_p jo2p; - jo2p = sgj_new_unattached_object(jsp); - sgj_pr_hr_js_vi(jsp, jo2p, 3, "zone_domain", - SGJ_SEP_EQUAL_NO_SPACE, bp[0]); + jo2p = sgj_new_unattached_object_r(jsp); + sgj_hr_js_vi(jsp, jo2p, 3, "zone_domain", + SGJ_SEP_EQUAL_NO_SPACE, bp[0], true); lba = sg_get_unaligned_be64(bp + 16); sgj_pr_hr(jsp, " zone_count=%" PRIu64 "\n", lba); - sgj_add_nv_ihex(jsp, jo2p, "zone_count", lba); + sgj_js_nv_ihex(jsp, jo2p, "zone_count", lba); lba = sg_get_unaligned_be64(bp + 24); sgj_pr_hr(jsp, " starting_lba=0x%" PRIx64 "\n", lba); - sgj_add_nv_ihex(jsp, jo2p, "starting_lba", lba); + sgj_js_nv_ihex(jsp, jo2p, "starting_lba", lba); lba = sg_get_unaligned_be64(bp + 32); sgj_pr_hr(jsp, " ending_lba=0x%" PRIx64 "\n", lba); - sgj_add_nv_ihex(jsp, jo2p, "ending_lba", lba); + sgj_js_nv_ihex(jsp, jo2p, "ending_lba", lba); sgj_pr_hr(jsp, " zone_domain_zone_type=0x%x\n", bp[40]); - sgj_add_nv_ihex(jsp, jo2p, "zone_domain_zone_type", bp[40]); - sgj_pr_hr_js_vi(jsp, jo2p, 5, "VZDZT", SGJ_SEP_EQUAL_NO_SPACE, - !!(0x2 & bp[42])); - sgj_pr_hr_js_vi(jsp, jo2p, 5, "SRB", SGJ_SEP_EQUAL_NO_SPACE, - !!(0x1 & bp[42])); - sgj_add_nv_o(jsp, jap, NULL /* name */, jo2p); + sgj_js_nv_ihex(jsp, jo2p, "zone_domain_zone_type", bp[40]); + sgj_hr_js_vi(jsp, jo2p, 5, "VZDZT", SGJ_SEP_EQUAL_NO_SPACE, + !!(0x2 & bp[42]), false); + sgj_hr_js_vi(jsp, jo2p, 5, "SRB", SGJ_SEP_EQUAL_NO_SPACE, + !!(0x1 & bp[42]), false); + sgj_js_nv_o(jsp, jap, NULL /* name */, jo2p); } return 0; } @@ -760,7 +760,7 @@ find_report_zones(int sg_fd, uint8_t * rzBuff, const char * cmd_name, } /* end of outer for loop */ if (res == 0) { sgj_opaque_p jo2p = as_json ? - sgj_new_named_object(jsp, NULL, "find_condition") : NULL; + sgj_named_subobject_r(jsp, NULL, "find_condition") : NULL; if (found) { if (op->do_hex) { @@ -770,8 +770,8 @@ find_report_zones(int sg_fd, uint8_t * rzBuff, const char * cmd_name, } else { sgj_pr_hr(jsp, "Condition met at:\n"); sgj_pr_hr(jsp, " %s: %d\n", zn_dnum_s, zn_dnum); - sgj_add_nv_b(jsp, jo2p, "met", true); - sgj_add_nv_i(jsp, jo2p, "zone_descriptor_index", zn_dnum); + sgj_js_nv_b(jsp, jo2p, "met", true); + sgj_js_nv_i(jsp, jo2p, "zone_descriptor_index", zn_dnum); prt_a_zn_desc(bp, op, jsp, jo2p); } } else { @@ -779,8 +779,8 @@ find_report_zones(int sg_fd, uint8_t * rzBuff, const char * cmd_name, memset(b, 0xff, 64); hex2stdout((const uint8_t *)b, 64, -1); } else { - sgj_add_nv_b(jsp, jo2p, "met", false); - sgj_add_nv_i(jsp, jo2p, "zone_descriptor_index", zn_dnum); + sgj_js_nv_b(jsp, jo2p, "met", false); + sgj_js_nv_i(jsp, jo2p, "zone_descriptor_index", zn_dnum); if (num_rem < 1) sgj_pr_hr(jsp, "Condition NOT met, checked %d zones; " "next %s%u\n", op->do_num, zn_dnum_s, zn_dnum); @@ -1333,7 +1333,7 @@ main(int argc, char * argv[]) as_json = op->json_st.pr_as_json; jsp = &op->json_st; if (as_json) - jop = sgj_start(MY_NAME, version_str, argc, argv, jsp); + jop = sgj_start_r(MY_NAME, version_str, argc, argv, jsp); if (op->do_zdomains && op->do_realms) { pr2serr("Can't have both --domain and --realm\n"); @@ -1343,7 +1343,7 @@ main(int argc, char * argv[]) else if (op->do_realms) cmd_name = "Report realms"; if (as_json) - sgj_add_nv_s(jsp, jop, "scsi_command_name", cmd_name); + sgj_js_nv_s(jsp, jop, "scsi_command_name", cmd_name); if ((op->serv_act != REPORT_ZONES_SA) && op->do_partial) { pr2serr("Can only use --partial with REPORT ZONES\n"); return SG_LIB_SYNTAX_ERROR; @@ -1518,7 +1518,7 @@ the_end: ret = (ret >= 0) ? ret : SG_LIB_CAT_OTHER; if (as_json) { if (0 == op->do_hex) - sgj_pr2file(jsp, NULL, ret, stdout); + sgj_js2file(jsp, NULL, ret, stdout); sgj_finish(jsp); } return ret; diff --git a/src/sg_vpd.c b/src/sg_vpd.c index 206fe91d..8cb231d7 100644 --- a/src/sg_vpd.c +++ b/src/sg_vpd.c @@ -42,7 +42,7 @@ */ -static const char * version_str = "1.75 20220714"; /* spc6r06 + sbc5r01 */ +static const char * version_str = "1.76 20220717"; /* spc6r06 + sbc5r01 */ #define MY_NAME "sg_vpd" @@ -99,6 +99,8 @@ static struct option long_options[] = { {"page", required_argument, 0, 'p'}, {"quiet", no_argument, 0, 'q'}, {"raw", no_argument, 0, 'r'}, + {"sinq_inraw", required_argument, 0, 'Q'}, + {"sinq-inraw", required_argument, 0, 'Q'}, {"vendor", required_argument, 0, 'M'}, {"verbose", no_argument, 0, 'v'}, {"version", no_argument, 0, 'V'}, @@ -177,9 +179,9 @@ usage() "[--help] [--hex]\n" " [--ident] [--inhex=FN] [--long] [--maxlen=LEN] " "[--page=PG]\n" - " [--quiet] [--raw] [--vendor=VP] [--verbose] " - "[--version]\n" - " DEVICE\n"); + " [--quiet] [--raw] [--sinq_inraw=RFN] " + "[--vendor=VP] [--verbose] " + " [--version] DEVICE\n"); pr2serr(" where:\n" " --all|-a output all pages listed in the supported " "pages VPD\n" @@ -218,6 +220,9 @@ usage() "also\n" " given, FN is in binary (else FN is in " "hex)\n" + " --sinq_inraw=RFN|-Q RFN read raw (binary) standard " + "INQUIRY\n" + " response from the RFN filename\n" " --vendor=VP|-M VP vendor/product abbreviation [or " "number]\n" " --verbose|-v increase verbosity\n" @@ -540,8 +545,8 @@ decode_scsi_ports_vpd(uint8_t * buff, int len, struct opts_t * op, for (k = 0; k < len; k += bump, bp += bump) { rel_port = sg_get_unaligned_be16(bp + 2); sgj_pr_hr(jsp, " Relative port=%d\n", rel_port); - jo2p = sgj_new_unattached_object(jsp); - sgj_add_nv_i(jsp, jo2p, "relative_port", rel_port); + jo2p = sgj_new_unattached_object_r(jsp); + sgj_js_nv_i(jsp, jo2p, "relative_port", rel_port); ip_tid_len = sg_get_unaligned_be16(bp + 6); bump = 8 + ip_tid_len; if ((k + bump) > len) { @@ -559,7 +564,7 @@ decode_scsi_ports_vpd(uint8_t * buff, int len, struct opts_t * op, sg_decode_transportid_str(" ", bp + 8, ip_tid_len, true, sizeof(b), b); if (jsp->pr_as_json) - sgj_add_nv_s(jsp, jo2p, "initiator_port_transport_id", b); + sgj_js_nv_s(jsp, jo2p, "initiator_port_transport_id", b); sgj_pr_hr(jsp, "%s", sg_decode_transportid_str(" ", bp + 8, ip_tid_len, true, sizeof(b), b)); @@ -579,18 +584,18 @@ decode_scsi_ports_vpd(uint8_t * buff, int len, struct opts_t * op, if ((0 == op->do_quiet) || (ip_tid_len > 0)) sgj_pr_hr(jsp, " Target port descriptor(s):\n"); if (jsp->pr_as_json) { - sgj_opaque_p jo3p = sgj_new_named_object(jsp, jo2p, - "target_port"); + sgj_opaque_p jo3p = sgj_named_subobject_r(jsp, jo2p, + "target_port"); - ja2p = sgj_new_named_array(jsp, jo3p, - "designation_descriptor_list"); + ja2p = sgj_named_subarray_r(jsp, jo3p, + "designation_descriptor_list"); } filter_dev_ids("", 2 /* leading spaces */, bp + bump + 4, tpd_len, VPD_ASSOC_TPORT, op, ja2p); } } bump += tpd_len + 4; - sgj_add_nv_o(jsp, jap, NULL, jo2p); + sgj_js_nv_o(jsp, jap, NULL, jo2p); } } @@ -843,7 +848,7 @@ filter_dev_ids(const char * print_if_found, int num_leading, uint8_t * buff, if (strlen(print_if_found) > 0) { snprintf(b, blen, " %s:", print_if_found); if (sgj_out_hr) - sgj_pr_str_out_hr(jsp, b, strlen(b)); + sgj_js_str_out(jsp, b, strlen(b)); else printf("%s\n", b); } @@ -851,14 +856,14 @@ filter_dev_ids(const char * print_if_found, int num_leading, uint8_t * buff, if (NULL == print_if_found) { snprintf(b, blen, " %s%s:", sp, sg_get_desig_assoc_str(assoc)); if (sgj_out_hr) - sgj_pr_str_out_hr(jsp, b, strlen(b)); + sgj_js_str_out(jsp, b, strlen(b)); else printf("%s\n", b); } sg_get_designation_descriptor_str(sp, bp, i_len + 4, false, op->do_long, blen, b); if (sgj_out_hr) - sgj_pr_str_out_hr(jsp, b, strlen(b)); + sgj_js_str_out(jsp, b, strlen(b)); else printf("%s", b); } @@ -869,60 +874,6 @@ filter_dev_ids(const char * print_if_found, int num_leading, uint8_t * buff, return 0; } -static const char * power_unit_arr[] = -{ - "Gigawatts", - "Megawatts", - "Kilowatts", - "Watts", - "Milliwatts", - "Microwatts", - "Unit reserved", - "Unit reserved", -}; - -/* VPD_POWER_CONSUMPTION */ -static void -decode_power_consumption_vpd(uint8_t * buff, int len, int do_hex) -{ - int k, bump; - uint8_t * bp; - unsigned int value; - static const char * pcp = "Power consumption VPD page"; - - if ((1 == do_hex) || (do_hex > 2)) { - hex2stdout(buff, len, (1 == do_hex) ? 1 : -1); - return; - } - if (len < 4) { - pr2serr("%s length too short=%d\n", pcp,len); - return; - } - len -= 4; - bp = buff + 4; - for (k = 0; k < len; k += bump, bp += bump) { - bump = 4; - if ((k + bump) > len) { - pr2serr("%s, short descriptor length=%d, left=%d\n", pcp, bump, - (len - k)); - return; - } - if (do_hex > 1) - hex2stdout(bp, 4, 1); - else { - value = sg_get_unaligned_be16(bp + 2); - printf(" Power consumption identifier: 0x%x", bp[0]); - if (value >= 1000 && (bp[1] & 0x7) > 0) - printf(" Maximum power consumption: %d.%03d %s\n", - value / 1000, value % 1000, - power_unit_arr[(bp[1] & 0x7) - 1]); - else - printf(" Maximum power consumption: %u %s\n", - value, power_unit_arr[bp[1] & 0x7]); - } - } -} - /* This is xcopy(LID4) related: "ROD" == Representation Of Data * Used by VPD_3PARTY_COPY */ static void @@ -1946,10 +1897,10 @@ decode_b3_vpd(uint8_t * b, int len, int pdt, struct opts_t * op, sgj_pr_hr(jsp, "%s0 [per sense descriptor]\n", d); else sgj_pr_hr(jsp, "%s%u\n", d, u); - sgj_add_nv_ihex(jsp, jop, "user_data_segment_size", u); + sgj_js_nv_ihex(jsp, jop, "user_data_segment_size", u); u = sg_get_unaligned_be32(b + 12); - sgj_pr_hr_js_vi(jsp, jop, 2, "User data segment multiplier", - SGJ_SEP_COLON_1_SPACE, u); + sgj_hr_js_vi(jsp, jop, 2, "User data segment multiplier", + SGJ_SEP_COLON_1_SPACE, u, true); break; case PDT_TAPE: case PDT_MCHANGER: memset(obuff, 0, sizeof(obuff)); @@ -2320,6 +2271,7 @@ svpd_decode_t10(int sg_fd, struct opts_t * op, sgj_opaque_p jop, sgj_opaque_p jap = NULL; sgj_opaque_p jo2p = NULL; const char * np; + const char * ep; const char * pre = (prefix ? prefix : "");; const char * pdt_str; bool as_json = jsp->pr_as_json; @@ -2426,8 +2378,8 @@ svpd_decode_t10(int sg_fd, struct opts_t * op, sgj_opaque_p jop, num = (len - 4); if (as_json) { jo2p = sg_vpd_js_hdr(jsp, jop, np, rp); - jap = sgj_new_named_array(jsp, jo2p, - "supported_vpd_page_list"); + jap = sgj_named_subarray_r(jsp, jo2p, + "supported_vpd_page_list"); } for (k = 0; k < num; ++k) { pn = rp[4 + k]; @@ -2454,17 +2406,17 @@ svpd_decode_t10(int sg_fd, struct opts_t * op, sgj_opaque_p jop, } else sgj_pr_hr(jsp, " %s\n", b); if (as_json) { - jo2p = sgj_new_unattached_object(jsp); - sgj_add_nv_i(jsp, jo2p, "i", pn); - sgj_add_nv_s(jsp, jo2p, "hex", b + 2); + jo2p = sgj_new_unattached_object_r(jsp); + sgj_js_nv_i(jsp, jo2p, "i", pn); + sgj_js_nv_s(jsp, jo2p, "hex", b + 2); if (vnp) { - sgj_add_nv_s(jsp, jo2p, "name", vnp->name); - sgj_add_nv_s(jsp, jo2p, "acronym", vnp->acron); + sgj_js_nv_s(jsp, jo2p, "name", vnp->name); + sgj_js_nv_s(jsp, jo2p, "acronym", vnp->acron); } else { - sgj_add_nv_s(jsp, jo2p, "name", "unknown"); - sgj_add_nv_s(jsp, jo2p, "acronym", "unknown"); + sgj_js_nv_s(jsp, jo2p, "name", "unknown"); + sgj_js_nv_s(jsp, jo2p, "acronym", "unknown"); } - sgj_add_nv_o(jsp, jap, NULL /* name */, jo2p); + sgj_js_nv_o(jsp, jap, NULL /* name */, jo2p); } } } @@ -2493,8 +2445,7 @@ svpd_decode_t10(int sg_fd, struct opts_t * op, sgj_opaque_p jop, len = sizeof(obuff) - 1; memcpy(obuff, rp + 4, len); jo2p = sg_vpd_js_hdr(jsp, jop, np, rp); - sgj_pr_hr_js_vs(jsp, jo2p, 2, np, SGJ_SEP_COLON_1_SPACE, - obuff); + sgj_hr_js_vs(jsp, jo2p, 2, np, SGJ_SEP_COLON_1_SPACE, obuff); } return 0; } @@ -2517,8 +2468,8 @@ svpd_decode_t10(int sg_fd, struct opts_t * op, sgj_opaque_p jop, "%s]\n", pqual, pdt_str); if (as_json) { jo2p = sg_vpd_js_hdr(jsp, jop, np, rp); - jap = sgj_new_named_array(jsp, jo2p, - "designation_descriptor_list"); + jap = sgj_named_subarray_r(jsp, jo2p, + "designation_descriptor_list"); } device_id_vpd_variants(rp, len, subvalue, op, jap); } @@ -2541,7 +2492,7 @@ svpd_decode_t10(int sg_fd, struct opts_t * op, sgj_opaque_p jop, "%s]\n", pqual, pdt_str); if (as_json) { jo2p = sg_vpd_js_hdr(jsp, jop, np, rp); - jap = sgj_new_named_array(jsp, jo2p, + jap = sgj_named_subarray_r(jsp, jo2p, "software_interface_identifier_list"); } decode_softw_inf_id(rp, len, op, jap); @@ -2562,7 +2513,7 @@ svpd_decode_t10(int sg_fd, struct opts_t * op, sgj_opaque_p jop, else { if (as_json) { jo2p = sg_vpd_js_hdr(jsp, jop, np, rp); - jap = sgj_new_named_array(jsp, jo2p, + jap = sgj_named_subarray_r(jsp, jo2p, "network_services_descriptor_list"); } decode_net_man_vpd(rp, len, op, jap); @@ -2619,7 +2570,7 @@ svpd_decode_t10(int sg_fd, struct opts_t * op, sgj_opaque_p jop, "%s]\n", pqual, pdt_str); if (as_json) { jo2p = sg_vpd_js_hdr(jsp, jop, np, rp); - jap = sgj_new_named_array(jsp, jo2p, + jap = sgj_named_subarray_r(jsp, jo2p, "mode_page_policy_descriptor_list"); } decode_mode_policy_vpd(rp, len, op, jap); @@ -2643,8 +2594,8 @@ svpd_decode_t10(int sg_fd, struct opts_t * op, sgj_opaque_p jop, "%s]\n", pqual, pdt_str); if (as_json) { jo2p = sg_vpd_js_hdr(jsp, jop, np, rp); - jap = sgj_new_named_array(jsp, jo2p, - "scsi_ports_descriptor_list"); + jap = sgj_named_subarray_r(jsp, jo2p, + "scsi_ports_descriptor_list"); } decode_scsi_ports_vpd(rp, len, op, jap); } @@ -2718,29 +2669,34 @@ svpd_decode_t10(int sg_fd, struct opts_t * op, sgj_opaque_p jop, "%s]\n", pqual, pdt_str); if (as_json) { jo2p = sg_vpd_js_hdr(jsp, jop, np, rp); - jap = sgj_new_named_array(jsp, jo2p, - "constituent_descriptor_list"); + jap = sgj_named_subarray_r(jsp, jo2p, + "constituent_descriptor_list"); } decode_dev_constit_vpd(rp, len, op, jap, recurse_vpd_decode); } return 0; } break; - case VPD_POWER_CONSUMPTION: /* 0x8d */ - np = "Power consumption VPD page:"; + case VPD_POWER_CONSUMPTION: /* 0x8d ["psm"] */ + np = "Power consumption VPD page"; if (allow_name) - printf("%s%s\n", pre, np); + sgj_pr_hr(jsp, "%s%s:\n", pre, np); res = vpd_fetch_page(sg_fd, rp, pn, op->maxlen, qt, vb, &len); if (0 == res) { if (! allow_name && allow_if_found) - printf("%s%s\n", pre, np); + sgj_pr_hr(jsp, "%s%s\n", pre, np); if (op->do_raw) dStrRaw(rp, len); else { if (vb || long_notquiet) - printf(" [PQual=%d Peripheral device type: %s]\n", - pqual, pdt_str); - decode_power_consumption_vpd(rp, len, op->do_hex); + sgj_pr_hr(jsp, " [PQual=%d Peripheral device type: " + "%s]\n", pqual, pdt_str); + if (as_json) { + jo2p = sg_vpd_js_hdr(jsp, jop, np, rp); + jap = sgj_named_subarray_r(jsp, jo2p, + "power_consumption_descriptor_list"); + } + decode_power_consumption(rp, len, op, jap); } return 0; } @@ -2820,7 +2776,7 @@ svpd_decode_t10(int sg_fd, struct opts_t * op, sgj_opaque_p jop, "%s]\n", pqual, pdt_str); if (as_json) { jo2p = sg_vpd_js_hdr(jsp, jop, np, rp); - jap = sgj_new_named_array(jsp, jo2p, + jap = sgj_named_subarray_r(jsp, jo2p, "feature_set_code_list"); } decode_feature_sets_vpd(rp, len, op, jap); @@ -2831,31 +2787,51 @@ svpd_decode_t10(int sg_fd, struct opts_t * op, sgj_opaque_p jop, case 0xb0: /* depends on pdt */ res = vpd_fetch_page(sg_fd, rp, pn, op->maxlen, qt, vb, &len); if (0 == res) { + bool bl = false; + bool sad = false; + bool oi = false; + switch (pdt) { case PDT_DISK: case PDT_WO: case PDT_OPTICAL: case PDT_ZBC: - np = "Block limits VPD page (SBC):"; + np = "Block limits VPD page"; + ep = "(SBC)"; + bl = true; break; case PDT_TAPE: case PDT_MCHANGER: - np = "Sequential-access device capabilities VPD page (SSC):"; + np = "Sequential-access device capabilities VPD page"; + ep = "(SSC)"; + sad = true; break; case PDT_OSD: - np = "OSD information VPD page (OSD):"; + np = "OSD information VPD page"; + ep = "(OSD)"; + oi = true; break; default: np = NULL; break; } if (NULL == np) - printf("VPD page=0x%x, pdt=0x%x:\n", pn, pdt); + sgj_pr_hr(jsp, "VPD page=0x%x, pdt=0x%x:\n", pn, pdt); else if (allow_name || allow_if_found) - printf("%s%s\n", pre, np); + sgj_pr_hr(jsp, "%s%s %s\n", pre, np, ep ? ep : ""); if (op->do_raw) dStrRaw(rp, len); else { if (vb || long_notquiet) - printf(" [PQual=%d Peripheral device type: %s]\n", - pqual, pdt_str); - decode_b0_vpd(rp, len, op->do_hex, pdt); + sgj_pr_hr(jsp, " [PQual=%d Peripheral device type: " + "%s]\n", pqual, pdt_str); + if (as_json) + jo2p = sg_vpd_js_hdr(jsp, jop, np, rp); + if (bl) + decode_block_limits_vpd(rp, len, op, jo2p); + else if (sad) { + decode_b0_vpd(rp, len, op->do_hex, pdt); + } else if (oi) { + decode_b0_vpd(rp, len, op->do_hex, pdt); + } else { + + } } return 0; } else if ((! op->do_raw) && (! op->do_quiet) && (op->do_hex < 3) && @@ -3313,6 +3289,7 @@ main(int argc, char * argv[]) int c, res, matches; int sg_fd = -1; int inhex_len = 0; + int inraw_len = 0; int ret = 0; int subvalue = 0; const char * cp; @@ -3328,7 +3305,7 @@ main(int argc, char * argv[]) while (1) { int option_index = 0; - c = getopt_long(argc, argv, "aeEfhHiI:j::lm:M:p:qrvV", long_options, + c = getopt_long(argc, argv, "aeEfhHiI:j::lm:M:p:qQ:rvV", long_options, &option_index); if (c == -1) break; @@ -3414,6 +3391,9 @@ main(int argc, char * argv[]) case 'q': op->do_quiet = true; break; + case 'Q': + op->sinq_inraw_fn = optarg; + break; case 'r': ++op->do_raw; break; @@ -3519,7 +3499,7 @@ main(int argc, char * argv[]) jsp = &op->json_st; as_json = jsp->pr_as_json; if (as_json) - jop = sgj_start(MY_NAME, version_str, argc, argv, jsp); + jop = sgj_start_r(MY_NAME, version_str, argc, argv, jsp); if (op->page_str) { if ('-' == op->page_str[0]) @@ -3611,6 +3591,20 @@ main(int argc, char * argv[]) ret = sg_convert_errno(ENOMEM); goto fini; } + if (op->sinq_inraw_fn) { + if ((ret = sg_f2hex_arr(op->sinq_inraw_fn, true, false, rsp_buff, + &inraw_len, rsp_buff_sz))) { + goto err_out; + } + if (inraw_len < 36) { + pr2serr("Unable to read 36 or more bytes from %s\n", + op->sinq_inraw_fn); + ret = SG_LIB_FILE_ERROR; + goto err_out; + } + memcpy(op->std_inq_a, rsp_buff, 36); + op->std_inq_a_valid = true; + } if (op->inhex_fn) { if (op->device_name) { pr2serr("Cannot have both a DEVICE and --inhex= option\n"); @@ -3652,7 +3646,7 @@ main(int argc, char * argv[]) } } } - } else if (NULL == op->device_name) { + } else if ((NULL == op->device_name) && (! op->std_inq_a_valid)) { pr2serr("No DEVICE argument given\n\n"); usage(); ret = SG_LIB_SYNTAX_ERROR; @@ -3696,6 +3690,19 @@ main(int argc, char * argv[]) } ret = res; goto err_out; + } else if (op->std_inq_a_valid && (NULL == op->device_name)) { + /* nothing else to do ... */ + /* --sinq_inraw=RFN contents still in rsp_buff */ + if (op->do_raw) + dStrRaw(rsp_buff, inraw_len); + else if (op->do_hex) { + if (! op->do_quiet && (op->do_hex < 3)) + sgj_pr_hr(jsp, "Standard Inquiry data format:\n"); + hex2stdout(rsp_buff, inraw_len, (1 == op->do_hex) ? 0 : -1); + } else + std_inq_decode(rsp_buff, inraw_len, op, jop); + ret = 0; + goto fini; } if ((sg_fd = sg_cmds_open_device(op->device_name, true /* ro */, @@ -3753,7 +3760,7 @@ fini: ret = (ret >= 0) ? ret : SG_LIB_CAT_OTHER; if (as_json) { if (0 == op->do_hex) - sgj_pr2file(jsp, NULL, ret, stdout); + sgj_js2file(jsp, NULL, ret, stdout); sgj_finish(jsp); } return ret; diff --git a/src/sg_vpd_common.c b/src/sg_vpd_common.c index 7f168c5b..111185a1 100644 --- a/src/sg_vpd_common.c +++ b/src/sg_vpd_common.c @@ -51,15 +51,15 @@ sg_vpd_js_hdr(sgj_state * jsp, sgj_opaque_p jop, const char * name, int pqual = (vpd_hdrp[0] & 0xe0) >> 5; int pn = vpd_hdrp[1]; const char * pdt_str; - sgj_opaque_p jo2p = sgj_new_snake_named_object(jsp, jop, name); + sgj_opaque_p jo2p = sgj_snake_named_subobject_r(jsp, jop, name); char d[64]; pdt_str = sg_get_pdt_str(pdt, sizeof(d), d); - sgj_add_nv_ihexstr(jsp, jo2p, "peripheral_qualifier", - pqual, NULL, pqual_str(pqual)); - sgj_add_nv_ihexstr(jsp, jo2p, "peripheral_device_type", - pdt, NULL, pdt_str); - sgj_add_nv_ihex(jsp, jo2p, "page_code", pn); + sgj_js_nv_ihexstr(jsp, jo2p, "peripheral_qualifier", + pqual, NULL, pqual_str(pqual)); + sgj_js_nv_ihexstr(jsp, jo2p, "peripheral_device_type", + pdt, NULL, pdt_str); + sgj_js_nv_ihex(jsp, jo2p, "page_code", pn); return jo2p; } @@ -128,14 +128,14 @@ decode_net_man_vpd(uint8_t * buff, int len, struct opts_t * op, sgj_pr_hr(jsp, " %s, Service type: %s\n", assoc_str, nst_str); na_len = sg_get_unaligned_be16(bp + 2); if (jsp->pr_as_json) { - jo2p = sgj_new_unattached_object(jsp); - sgj_add_nv_ihexstr(jsp, jo2p, "association", assoc, NULL, - assoc_str); - sgj_add_nv_ihexstr(jsp, jo2p, "service_type", nst, NULL, - nst_str); - sgj_add_nv_s_len(jsp, jo2p, "network_address", - (const char *)(bp + 4), na_len); - sgj_add_nv_o(jsp, jap, NULL /* name */, jo2p); + jo2p = sgj_new_unattached_object_r(jsp); + sgj_js_nv_ihexstr(jsp, jo2p, "association", assoc, NULL, + assoc_str); + sgj_js_nv_ihexstr(jsp, jo2p, "service_type", nst, NULL, + nst_str); + sgj_js_nv_s_len(jsp, jo2p, "network_address", + (const char *)(bp + 4), na_len); + sgj_js_nv_o(jsp, jap, NULL /* name */, jo2p); } if (na_len > 0) { if (op->do_hex > 1) { @@ -189,7 +189,7 @@ decode_x_inq_vpd(uint8_t * b, int len, bool protect, struct opts_t * op, if (cp[0]) snprintf(d, dlen, " [%s]", cp); sgj_pr_hr(jsp, " ACTIVATE_MICROCODE=%d%s\n", n, d); - sgj_add_nv_ihexstr(jsp, jop, "activate_microcode", n, NULL, cp); + sgj_js_nv_ihexstr(jsp, jop, "activate_microcode", n, NULL, cp); n = (b[4] >> 3) & 0x7; if (protect) { switch (n) @@ -227,46 +227,50 @@ decode_x_inq_vpd(uint8_t * b, int len, bool protect, struct opts_t * op, if (cp[0]) snprintf(d, dlen, " [%s]", cp); sgj_pr_hr(jsp, " SPT=%d%s\n", n, d); - sgj_add_nv_ihexstr_nex(jsp, jop, "spt", n, false, NULL, - cp, "Supported Protection Type"); - sgj_pr_hr_js_vi_nex(jsp, jop, 2, "GRD_CHK", SGJ_SEP_EQUAL_NO_SPACE, - !!(b[4] & 0x4), "guard check"); - sgj_pr_hr_js_vi_nex(jsp, jop, 2, "APP_CHK", SGJ_SEP_EQUAL_NO_SPACE, - !!(b[4] & 0x2), "application tag check"); - sgj_pr_hr_js_vi_nex(jsp, jop, 2, "REF_CHK", SGJ_SEP_EQUAL_NO_SPACE, - !!(b[4] & 0x1), "reference tag check"); - sgj_pr_hr_js_vi_nex(jsp, jop, 2, "UASK_SUP", SGJ_SEP_EQUAL_NO_SPACE, - !!(b[5] & 0x20), "Unit Attention condition Sense " - "Key specific data Supported"); - sgj_pr_hr_js_vi_nex(jsp, jop, 2, "GROUP_SUP", SGJ_SEP_EQUAL_NO_SPACE, - !!(b[5] & 0x10), "grouping function supported"); - sgj_pr_hr_js_vi_nex(jsp, jop, 2, "PRIOR_SUP", SGJ_SEP_EQUAL_NO_SPACE, - !!(b[5] & 0x8), "priority supported"); - sgj_pr_hr_js_vi_nex(jsp, jop, 2, "HEADSUP", SGJ_SEP_EQUAL_NO_SPACE, - !!(b[5] & 0x4), "head of queue supported"); - sgj_pr_hr_js_vi_nex(jsp, jop, 2, "ORDSUP", SGJ_SEP_EQUAL_NO_SPACE, - !!(b[5] & 0x2), "ordered (task attribute) " - "supported"); - sgj_pr_hr_js_vi_nex(jsp, jop, 2, "SIMPSUP", SGJ_SEP_EQUAL_NO_SPACE, - !!(b[5] & 0x1), "simple (task attribute) " - "supported"); - sgj_pr_hr_js_vi_nex(jsp, jop, 2, "WU_SUP", SGJ_SEP_EQUAL_NO_SPACE, - !!(b[6] & 0x8), "Write uncorrectable supported"); - sgj_pr_hr_js_vi_nex(jsp, jop, 2, "CRD_SUP", SGJ_SEP_EQUAL_NO_SPACE, - !!(b[6] & 0x4), "Correction disable supported " - "(obsolete SPC-5)"); - sgj_pr_hr_js_vi_nex(jsp, jop, 2, "NV_SUP", SGJ_SEP_EQUAL_NO_SPACE, - !!(b[6] & 0x2), "Nonvolatile cache supported"); - sgj_pr_hr_js_vi_nex(jsp, jop, 2, "V_SUP", SGJ_SEP_EQUAL_NO_SPACE, - !!(b[6] & 0x1), "Volatile cache supported"); - sgj_pr_hr_js_vi_nex(jsp, jop, 2, "NO_PI_CHK", SGJ_SEP_EQUAL_NO_SPACE, - !!(b[7] & 0x20), "No protection information " - "checking"); /* spc5r02 */ - sgj_pr_hr_js_vi_nex(jsp, jop, 2, "P_I_I_SUP", SGJ_SEP_EQUAL_NO_SPACE, - !!(b[7] & 0x10), "Protection information " - "interval supported"); - sgj_pr_hr_js_vi_nex(jsp, jop, 2, "LUICLR", SGJ_SEP_EQUAL_NO_SPACE, - !!(b[7] & 0x1), "Logical unit I_T nexus clear"); + sgj_js_nv_ihexstr_nex(jsp, jop, "spt", n, false, NULL, + cp, "Supported Protection Type"); + sgj_hr_js_vi_nex(jsp, jop, 2, "GRD_CHK", SGJ_SEP_EQUAL_NO_SPACE, + !!(b[4] & 0x4), false, "guard check"); + sgj_hr_js_vi_nex(jsp, jop, 2, "APP_CHK", SGJ_SEP_EQUAL_NO_SPACE, + !!(b[4] & 0x2), false, "application tag check"); + sgj_hr_js_vi_nex(jsp, jop, 2, "REF_CHK", SGJ_SEP_EQUAL_NO_SPACE, + !!(b[4] & 0x1), false, "reference tag check"); + sgj_hr_js_vi_nex(jsp, jop, 2, "UASK_SUP", SGJ_SEP_EQUAL_NO_SPACE, + !!(b[5] & 0x20), false, "Unit Attention " + "condition Sense Key specific data Supported"); + sgj_hr_js_vi_nex(jsp, jop, 2, "GROUP_SUP", SGJ_SEP_EQUAL_NO_SPACE, + !!(b[5] & 0x10), false, "grouping function " + "supported"); + sgj_hr_js_vi_nex(jsp, jop, 2, "PRIOR_SUP", SGJ_SEP_EQUAL_NO_SPACE, + !!(b[5] & 0x8), false, "priority supported"); + sgj_hr_js_vi_nex(jsp, jop, 2, "HEADSUP", SGJ_SEP_EQUAL_NO_SPACE, + !!(b[5] & 0x4), false, "head of queue supported"); + sgj_hr_js_vi_nex(jsp, jop, 2, "ORDSUP", SGJ_SEP_EQUAL_NO_SPACE, + !!(b[5] & 0x2), false, "ordered (task attribute) " + "supported"); + sgj_hr_js_vi_nex(jsp, jop, 2, "SIMPSUP", SGJ_SEP_EQUAL_NO_SPACE, + !!(b[5] & 0x1), false, "simple (task attribute) " + "supported"); + sgj_hr_js_vi_nex(jsp, jop, 2, "WU_SUP", SGJ_SEP_EQUAL_NO_SPACE, + !!(b[6] & 0x8), false, "Write uncorrectable " + "supported"); + sgj_hr_js_vi_nex(jsp, jop, 2, "CRD_SUP", SGJ_SEP_EQUAL_NO_SPACE, + !!(b[6] & 0x4), false, "Correction disable " + "supported (obsolete SPC-5)"); + sgj_hr_js_vi_nex(jsp, jop, 2, "NV_SUP", SGJ_SEP_EQUAL_NO_SPACE, + !!(b[6] & 0x2), false, "Nonvolatile cache " + "supported"); + sgj_hr_js_vi_nex(jsp, jop, 2, "V_SUP", SGJ_SEP_EQUAL_NO_SPACE, + !!(b[6] & 0x1), false, "Volatile cache supported"); + sgj_hr_js_vi_nex(jsp, jop, 2, "NO_PI_CHK", SGJ_SEP_EQUAL_NO_SPACE, + !!(b[7] & 0x20), false, "No protection " + "information checking"); /* spc5r02 */ + sgj_hr_js_vi_nex(jsp, jop, 2, "P_I_I_SUP", SGJ_SEP_EQUAL_NO_SPACE, + !!(b[7] & 0x10), false, "Protection information " + "interval supported"); + sgj_hr_js_vi_nex(jsp, jop, 2, "LUICLR", SGJ_SEP_EQUAL_NO_SPACE, + !!(b[7] & 0x1), false, "Logical unit I_T nexus " + "clear"); np = "LU_COLL_TYPE"; n = (b[8] >> 5) & 0x7; nex_p = "Logical unit collection type"; @@ -285,85 +289,87 @@ decode_x_inq_vpd(uint8_t * b, int len, bool protect, struct opts_t * op, cp = "reserved"; break; } - jo2p = sgj_pr_hr_js_subo(jsp, jop, 2, np, SGJ_SEP_EQUAL_NO_SPACE, - n); - sgj_add_nv_s(jsp, jo2p, "meaning", cp); + jo2p = sgj_hr_js_subo_r(jsp, jop, 2, np, SGJ_SEP_EQUAL_NO_SPACE, + n); + sgj_js_nv_s(jsp, jo2p, "meaning", cp); if (jsp->pr_name_ex) - sgj_add_nv_s(jsp, jo2p, "abbreviated_name_expansion", nex_p); + sgj_js_nv_s(jsp, jo2p, "abbreviated_name_expansion", nex_p); } else - sgj_pr_hr_js_vi_nex(jsp, jop, 2, np, SGJ_SEP_EQUAL_NO_SPACE, n, - nex_p); - - sgj_pr_hr_js_vi_nex(jsp, jop, 2, "R_SUP", SGJ_SEP_EQUAL_NO_SPACE, - !!(b[8] & 0x10), "Referrals supported"); - sgj_pr_hr_js_vi_nex(jsp, jop, 2, "RTD_SUP", SGJ_SEP_EQUAL_NO_SPACE, - !!(b[8] & 0x8), "Revert to defaults supported"); - sgj_pr_hr_js_vi_nex(jsp, jop, 2, "HSSRELEF", SGJ_SEP_EQUAL_NO_SPACE, - !!(b[8] & 0x2), - "History snapshots release effects"); - sgj_pr_hr_js_vi_nex(jsp, jop, 2, "CBCS", SGJ_SEP_EQUAL_NO_SPACE, - !!(b[8] & 0x1), "Capability-based command " - "security (obsolete SPC-5)"); - sgj_pr_hr_js_vi(jsp, jop, 2, "Multi I_T nexus microcode download", - SGJ_SEP_EQUAL_NO_SPACE, b[9] & 0xf); - sgj_pr_hr_js_vi(jsp, jop, 2, "Extended self-test completion minutes", - SGJ_SEP_EQUAL_NO_SPACE, - sg_get_unaligned_be16(b + 10)); - sgj_pr_hr_js_vi_nex(jsp, jop, 2, "POA_SUP", SGJ_SEP_EQUAL_NO_SPACE, - !!(b[12] & 0x80), - "Power on activation supported"); - sgj_pr_hr_js_vi_nex(jsp, jop, 2, "HRA_SUP", SGJ_SEP_EQUAL_NO_SPACE, - !!(b[12] & 0x40), - "Hard reset activation supported"); - sgj_pr_hr_js_vi_nex(jsp, jop, 2, "VSA_SUP", SGJ_SEP_EQUAL_NO_SPACE, - !!(b[12] & 0x20), - "Vendor specific activation supported"); - sgj_pr_hr_js_vi_nex(jsp, jop, 2, "DMS_VALID", SGJ_SEP_EQUAL_NO_SPACE, - !!(b[12] & 0x10), - "Download microcode support byte valid"); - sgj_pr_hr_js_vi(jsp, jop, 2, "Maximum supported sense data length", - SGJ_SEP_EQUAL_NO_SPACE, b[13]); - sgj_pr_hr_js_vi_nex(jsp, jop, 2, "IBS", SGJ_SEP_EQUAL_NO_SPACE, - !!(b[14] & 0x80), "Implicit bind supported"); - sgj_pr_hr_js_vi_nex(jsp, jop, 2, "IAS", SGJ_SEP_EQUAL_NO_SPACE, - !!(b[14] & 0x40), - "Implicit affiliation supported"); - sgj_pr_hr_js_vi_nex(jsp, jop, 2, "SAC", SGJ_SEP_EQUAL_NO_SPACE, - !!(b[14] & 0x4), - "Set affiliation command supported"); - sgj_pr_hr_js_vi_nex(jsp, jop, 2, "NRD1", SGJ_SEP_EQUAL_NO_SPACE, - !!(b[14] & 0x2), - "No redirect one supported (BIND)"); - sgj_pr_hr_js_vi_nex(jsp, jop, 2, "NRD0", SGJ_SEP_EQUAL_NO_SPACE, - !!(b[14] & 0x1), - "No redirect zero supported (BIND)"); - sgj_pr_hr_js_vi(jsp, jop, 2, "Maximum inquiry change logs", - SGJ_SEP_EQUAL_NO_SPACE, - sg_get_unaligned_be16(b + 15)); - sgj_pr_hr_js_vi(jsp, jop, 2, "Maximum mode page change logs", - SGJ_SEP_EQUAL_NO_SPACE, - sg_get_unaligned_be16(b + 17)); - sgj_pr_hr_js_vi_nex(jsp, jop, 2, "DM_MD_4", SGJ_SEP_EQUAL_NO_SPACE, - !!(b[19] & 0x80), - "Download microcode mode 4 supported"); - sgj_pr_hr_js_vi_nex(jsp, jop, 2, "DM_MD_5", SGJ_SEP_EQUAL_NO_SPACE, - !!(b[19] & 0x40), - "Download microcode mode 5 supported"); - sgj_pr_hr_js_vi_nex(jsp, jop, 2, "DM_MD_6", SGJ_SEP_EQUAL_NO_SPACE, - !!(b[19] & 0x20), - "Download microcode mode 6 supported"); - sgj_pr_hr_js_vi_nex(jsp, jop, 2, "DM_MD_7", SGJ_SEP_EQUAL_NO_SPACE, - !!(b[19] & 0x10), - "Download microcode mode 7 supported"); - sgj_pr_hr_js_vi_nex(jsp, jop, 2, "DM_MD_D", SGJ_SEP_EQUAL_NO_SPACE, - !!(b[19] & 0x8), - "Download microcode mode 0xd supported"); - sgj_pr_hr_js_vi_nex(jsp, jop, 2, "DM_MD_E", SGJ_SEP_EQUAL_NO_SPACE, - !!(b[19] & 0x4), - "Download microcode mode 0xe supported"); - sgj_pr_hr_js_vi_nex(jsp, jop, 2, "DM_MD_F", SGJ_SEP_EQUAL_NO_SPACE, - !!(b[19] & 0x2), - "Download microcode mode 0xf supported"); + sgj_hr_js_vi_nex(jsp, jop, 2, np, SGJ_SEP_EQUAL_NO_SPACE, n, + true, nex_p); + + sgj_hr_js_vi_nex(jsp, jop, 2, "R_SUP", SGJ_SEP_EQUAL_NO_SPACE, + !!(b[8] & 0x10), false, "Referrals supported"); + sgj_hr_js_vi_nex(jsp, jop, 2, "RTD_SUP", SGJ_SEP_EQUAL_NO_SPACE, + !!(b[8] & 0x8), false, + "Revert to defaults supported"); + sgj_hr_js_vi_nex(jsp, jop, 2, "HSSRELEF", SGJ_SEP_EQUAL_NO_SPACE, + !!(b[8] & 0x2), false, + "History snapshots release effects"); + sgj_hr_js_vi_nex(jsp, jop, 2, "CBCS", SGJ_SEP_EQUAL_NO_SPACE, + !!(b[8] & 0x1), false, "Capability-based command " + "security (obsolete SPC-5)"); + sgj_hr_js_vi(jsp, jop, 2, "Multi I_T nexus microcode download", + SGJ_SEP_EQUAL_NO_SPACE, b[9] & 0xf, true); + sgj_hr_js_vi(jsp, jop, 2, "Extended self-test completion minutes", + SGJ_SEP_EQUAL_NO_SPACE, + sg_get_unaligned_be16(b + 10), true); + sgj_hr_js_vi_nex(jsp, jop, 2, "POA_SUP", SGJ_SEP_EQUAL_NO_SPACE, + !!(b[12] & 0x80), false, + "Power on activation supported"); + sgj_hr_js_vi_nex(jsp, jop, 2, "HRA_SUP", SGJ_SEP_EQUAL_NO_SPACE, + !!(b[12] & 0x40), false, + "Hard reset activation supported"); + sgj_hr_js_vi_nex(jsp, jop, 2, "VSA_SUP", SGJ_SEP_EQUAL_NO_SPACE, + !!(b[12] & 0x20), false, + "Vendor specific activation supported"); + sgj_hr_js_vi_nex(jsp, jop, 2, "DMS_VALID", SGJ_SEP_EQUAL_NO_SPACE, + !!(b[12] & 0x10), false, + "Download microcode support byte valid"); + sgj_hr_js_vi(jsp, jop, 2, "Maximum supported sense data length", + SGJ_SEP_EQUAL_NO_SPACE, b[13], true); + sgj_hr_js_vi_nex(jsp, jop, 2, "IBS", SGJ_SEP_EQUAL_NO_SPACE, + !!(b[14] & 0x80), false, + "Implicit bind supported"); + sgj_hr_js_vi_nex(jsp, jop, 2, "IAS", SGJ_SEP_EQUAL_NO_SPACE, + !!(b[14] & 0x40), false, + "Implicit affiliation supported"); + sgj_hr_js_vi_nex(jsp, jop, 2, "SAC", SGJ_SEP_EQUAL_NO_SPACE, + !!(b[14] & 0x4), false, + "Set affiliation command supported"); + sgj_hr_js_vi_nex(jsp, jop, 2, "NRD1", SGJ_SEP_EQUAL_NO_SPACE, + !!(b[14] & 0x2), false, + "No redirect one supported (BIND)"); + sgj_hr_js_vi_nex(jsp, jop, 2, "NRD0", SGJ_SEP_EQUAL_NO_SPACE, + !!(b[14] & 0x1), false, + "No redirect zero supported (BIND)"); + sgj_hr_js_vi(jsp, jop, 2, "Maximum inquiry change logs", + SGJ_SEP_EQUAL_NO_SPACE, + sg_get_unaligned_be16(b + 15), true); + sgj_hr_js_vi(jsp, jop, 2, "Maximum mode page change logs", + SGJ_SEP_EQUAL_NO_SPACE, + sg_get_unaligned_be16(b + 17), true); + sgj_hr_js_vi_nex(jsp, jop, 2, "DM_MD_4", SGJ_SEP_EQUAL_NO_SPACE, + !!(b[19] & 0x80), false, + "Download microcode mode 4 supported"); + sgj_hr_js_vi_nex(jsp, jop, 2, "DM_MD_5", SGJ_SEP_EQUAL_NO_SPACE, + !!(b[19] & 0x40), false, + "Download microcode mode 5 supported"); + sgj_hr_js_vi_nex(jsp, jop, 2, "DM_MD_6", SGJ_SEP_EQUAL_NO_SPACE, + !!(b[19] & 0x20), false, + "Download microcode mode 6 supported"); + sgj_hr_js_vi_nex(jsp, jop, 2, "DM_MD_7", SGJ_SEP_EQUAL_NO_SPACE, + !!(b[19] & 0x10), false, + "Download microcode mode 7 supported"); + sgj_hr_js_vi_nex(jsp, jop, 2, "DM_MD_D", SGJ_SEP_EQUAL_NO_SPACE, + !!(b[19] & 0x8), false, + "Download microcode mode 0xd supported"); + sgj_hr_js_vi_nex(jsp, jop, 2, "DM_MD_E", SGJ_SEP_EQUAL_NO_SPACE, + !!(b[19] & 0x4), false, + "Download microcode mode 0xe supported"); + sgj_hr_js_vi_nex(jsp, jop, 2, "DM_MD_F", SGJ_SEP_EQUAL_NO_SPACE, + !!(b[19] & 0x2), false, + "Download microcode mode 0xf supported"); if (do_long_nq || (! jsp->pr_out_hr)) return; } @@ -423,9 +429,9 @@ decode_softw_inf_id(uint8_t * buff, int len, struct opts_t * op, ieee_id = sg_get_unaligned_be48(buff + 0); sgj_pr_hr(jsp, " IEEE identifier: 0x%" PRIx64 "\n", ieee_id); if (jsp->pr_as_json) { - jop = sgj_new_unattached_object(jsp); - sgj_add_nv_ihex(jsp, jop, "ieee_identifier", ieee_id); - sgj_add_nv_o(jsp, jap, NULL /* name */, jop); + jop = sgj_new_unattached_object_r(jsp); + sgj_js_nv_ihex(jsp, jop, "ieee_identifier", ieee_id); + sgj_js_nv_o(jsp, jap, NULL /* name */, jop); } } } @@ -483,14 +489,14 @@ decode_mode_policy_vpd(uint8_t * buff, int len, struct opts_t * op, sgj_pr_hr(jsp, " MLUS=%d, Policy: %s\n", !!(bp[2] & 0x80), mode_page_policy_arr[bp[2] & 0x3]); if (jsp->pr_as_json) { - jo2p = sgj_new_unattached_object(jsp); - sgj_add_nv_ihex(jsp, jo2p, "policy_page_code", ppc); - sgj_add_nv_ihex(jsp, jo2p, "policy_subpage_code", pspc); - sgj_add_nv_ihex_nex(jsp, jo2p, "mlus", !!(bp[2] & 0x80), false, - "Multiple logical units share"); - sgj_add_nv_ihexstr(jsp, jo2p, "mode_page_policy", bp[2] & 0x3, - NULL, mode_page_policy_arr[bp[2] & 0x3]); - sgj_add_nv_o(jsp, jap, NULL /* name */, jo2p); + jo2p = sgj_new_unattached_object_r(jsp); + sgj_js_nv_ihex(jsp, jo2p, "policy_page_code", ppc); + sgj_js_nv_ihex(jsp, jo2p, "policy_subpage_code", pspc); + sgj_js_nv_ihex_nex(jsp, jo2p, "mlus", !!(bp[2] & 0x80), false, + "Multiple logical units share"); + sgj_js_nv_ihexstr(jsp, jo2p, "mode_page_policy", bp[2] & 0x3, + NULL, mode_page_policy_arr[bp[2] & 0x3]); + sgj_js_nv_o(jsp, jap, NULL /* name */, jo2p); } } } @@ -515,24 +521,30 @@ decode_power_condition(uint8_t * buff, int len, struct opts_t * op, "Idle_a=%d\n", !!(buff[4] & 0x2), !!(buff[4] & 0x1), !!(buff[5] & 0x4), !!(buff[5] & 0x2), !!(buff[5] & 0x1)); if (jsp->pr_as_json) { - sgj_add_nv_ihex(jsp, jop, "standby_y", !!(buff[4] & 0x2)); - sgj_add_nv_ihex(jsp, jop, "standby_z", !!(buff[4] & 0x1)); - sgj_add_nv_ihex(jsp, jop, "idle_c", !!(buff[5] & 0x4)); - sgj_add_nv_ihex(jsp, jop, "idle_b", !!(buff[5] & 0x2)); - sgj_add_nv_ihex(jsp, jop, "idle_a", !!(buff[5] & 0x1)); - } - sgj_pr_hr_js_vi(jsp, jop, 2, "Stopped condition recovery time (ms)", - SGJ_SEP_SPACE_1, sg_get_unaligned_be16(buff + 6)); - sgj_pr_hr_js_vi(jsp, jop, 2, "Standby_z condition recovery time (ms)", - SGJ_SEP_SPACE_1, sg_get_unaligned_be16(buff + 8)); - sgj_pr_hr_js_vi(jsp, jop, 2, "Standby_y condition recovery time (ms)", - SGJ_SEP_SPACE_1, sg_get_unaligned_be16(buff + 10)); - sgj_pr_hr_js_vi(jsp, jop, 2, "Idle_a condition recovery time (ms)", - SGJ_SEP_SPACE_1, sg_get_unaligned_be16(buff + 12)); - sgj_pr_hr_js_vi(jsp, jop, 2, "Idle_b condition recovery time (ms)", - SGJ_SEP_SPACE_1, sg_get_unaligned_be16(buff + 14)); - sgj_pr_hr_js_vi(jsp, jop, 2, "Idle_c condition recovery time (ms)", - SGJ_SEP_SPACE_1, sg_get_unaligned_be16(buff + 16)); + sgj_js_nv_ihex(jsp, jop, "standby_y", !!(buff[4] & 0x2)); + sgj_js_nv_ihex(jsp, jop, "standby_z", !!(buff[4] & 0x1)); + sgj_js_nv_ihex(jsp, jop, "idle_c", !!(buff[5] & 0x4)); + sgj_js_nv_ihex(jsp, jop, "idle_b", !!(buff[5] & 0x2)); + sgj_js_nv_ihex(jsp, jop, "idle_a", !!(buff[5] & 0x1)); + } + sgj_hr_js_vi_nex(jsp, jop, 2, "Stopped condition recovery time", + SGJ_SEP_SPACE_1, sg_get_unaligned_be16(buff + 6), + true, "unit: millisecond"); + sgj_hr_js_vi_nex(jsp, jop, 2, "Standby_z condition recovery time", + SGJ_SEP_SPACE_1, sg_get_unaligned_be16(buff + 8), + true, "unit: millisecond"); + sgj_hr_js_vi_nex(jsp, jop, 2, "Standby_y condition recovery time", + SGJ_SEP_SPACE_1, sg_get_unaligned_be16(buff + 10), + true, "unit: millisecond"); + sgj_hr_js_vi_nex(jsp, jop, 2, "Idle_a condition recovery time", + SGJ_SEP_SPACE_1, sg_get_unaligned_be16(buff + 12), + true, "unit: millisecond"); + sgj_hr_js_vi_nex(jsp, jop, 2, "Idle_b condition recovery time", + SGJ_SEP_SPACE_1, sg_get_unaligned_be16(buff + 14), + true, "unit: millisecond"); + sgj_hr_js_vi_nex(jsp, jop, 2, "Idle_c condition recovery time", + SGJ_SEP_SPACE_1, sg_get_unaligned_be16(buff + 16), + true, "unit: millisecond"); } int @@ -553,9 +565,9 @@ filter_json_dev_ids(uint8_t * buff, int len, int m_assoc, struct opts_t * op, " remaining response length=%d\n", (len - off)); return SG_LIB_CAT_MALFORMED; } - jo2p = sgj_new_unattached_object(jsp); - sgj_pr_js_designation_descriptor(jsp, jo2p, bp, i_len + 4); - sgj_add_nv_o(jsp, jap, NULL /* name */, jo2p); + jo2p = sgj_new_unattached_object_r(jsp); + sgj_js_designation_descriptor(jsp, jo2p, bp, i_len + 4); + sgj_js_nv_o(jsp, jap, NULL /* name */, jo2p); } if (-2 == u) { pr2serr("VPD page error: short designator around offset %d\n", off); @@ -564,7 +576,7 @@ filter_json_dev_ids(uint8_t * buff, int len, int m_assoc, struct opts_t * op, return 0; } -/* VPD_ATA_INFO 0x89 ['ai"] */ +/* VPD_ATA_INFO 0x89 ["ai"] */ void decode_ata_info_vpd(const uint8_t * buff, int len, struct opts_t * op, sgj_opaque_p jop) @@ -644,15 +656,15 @@ decode_ata_info_vpd(const uint8_t * buff, int len, struct opts_t * op, (unsigned int)cc); if (jsp->pr_as_json) { sgj_convert_to_snake_name(sat_vip, d, dlen); - sgj_add_nv_s_len(jsp, jop, d, (const char *)(buff + 8), 8); + sgj_js_nv_s_len(jsp, jop, d, (const char *)(buff + 8), 8); sgj_convert_to_snake_name(sat_pip, d, dlen); - sgj_add_nv_s_len(jsp, jop, d, (const char *)(buff + 16), 16); + sgj_js_nv_s_len(jsp, jop, d, (const char *)(buff + 16), 16); sgj_convert_to_snake_name(sat_prlp, d, dlen); - sgj_add_nv_s_len(jsp, jop, d, (const char *)(buff + 32), 4); - sgj_add_nv_hex_bytes(jsp, jop, "ata_device_signature", buff + 36, 20); - sgj_add_nv_ihex(jsp, jop, "command_code", buff[56]); - sgj_add_nv_s(jsp, jop, "ata_identify_device_data_example", - "sg_vpd -p ai -HHH /dev/sdc | hdparm --Istdin"); + sgj_js_nv_s_len(jsp, jop, d, (const char *)(buff + 32), 4); + sgj_js_nv_hex_bytes(jsp, jop, "ata_device_signature", buff + 36, 20); + sgj_js_nv_ihex(jsp, jop, "command_code", buff[56]); + sgj_js_nv_s(jsp, jop, "ata_identify_device_data_example", + "sg_vpd -p ai -HHH /dev/sdc | hdparm --Istdin"); } if (len < 572) return; @@ -687,7 +699,7 @@ decode_feature_sets_vpd(uint8_t * buff, int len, struct opts_t * op, len -= 8; bp = buff + 8; for (k = 0; k < len; k += bump, bp += bump) { - jo2p = sgj_new_unattached_object(jsp); + jo2p = sgj_new_unattached_object_r(jsp); sf_code = sg_get_unaligned_be16(bp); bump = 2; if ((k + bump) > len) { @@ -710,12 +722,12 @@ decode_feature_sets_vpd(uint8_t * buff, int len, struct opts_t * op, (unsigned int)sf_code, found ? "true" : "false"); else sgj_pr_hr(jsp, "%s\n", b); - sgj_add_nv_ihexstr(jsp, jo2p, "feature_set_code", sf_code, NULL, - d); + sgj_js_nv_ihexstr(jsp, jo2p, "feature_set_code", sf_code, NULL, + d); if (jsp->verbose) - sgj_add_nv_b(jsp, jo2p, "meaning_is_match", found); + sgj_js_nv_b(jsp, jo2p, "meaning_is_match", found); } - sgj_add_nv_o(jsp, jap, NULL, jo2p); + sgj_js_nv_o(jsp, jap, NULL, jo2p); } } @@ -752,13 +764,13 @@ decode_dev_constit_vpd(const uint8_t * buff, int len, struct opts_t * op, len -= 4; bp = buff + 4; for (k = 0, j = 0; k < len; k += bump, bp += bump, ++j) { - jo2p = sgj_new_unattached_object(jsp); + jo2p = sgj_new_unattached_object_r(jsp); if (j > 0) sgj_pr_hr(jsp, "\n"); sgj_pr_hr(jsp, " Constituent descriptor %d:\n", j + 1); if ((k + 36) > len) { pr2serr("short descriptor length=36, left=%d\n", (len - k)); - sgj_add_nv_o(jsp, jap, NULL, jo2p); + sgj_js_nv_o(jsp, jap, NULL, jo2p); return; } constit_type = sg_get_unaligned_be16(bp + 0); @@ -778,18 +790,18 @@ decode_dev_constit_vpd(const uint8_t * buff, int len, struct opts_t * op, sg_get_pdt_str(PDT_MASK & bp[2], dlen, d), bp[2]); snprintf(b, blen, "%.8s", bp + 4); sgj_pr_hr(jsp, " %s: %s\n", t10_vendor_id_hr, b); - sgj_add_nv_s(jsp, jo2p, t10_vendor_id_js, b); + sgj_js_nv_s(jsp, jo2p, t10_vendor_id_js, b); snprintf(b, blen, "%.16s", bp + 12); sgj_pr_hr(jsp, " %s: %s\n", product_id_hr, b); - sgj_add_nv_s(jsp, jo2p, product_id_js, b); + sgj_js_nv_s(jsp, jo2p, product_id_js, b); snprintf(b, blen, "%.4s", bp + 28); sgj_pr_hr(jsp, " %s: %s\n", product_rev_lev_hr, b); - sgj_add_nv_s(jsp, jo2p, product_rev_lev_js, b); + sgj_js_nv_s(jsp, jo2p, product_rev_lev_js, b); csd_len = sg_get_unaligned_be16(bp + 34); bump = 36 + csd_len; if ((k + bump) > len) { pr2serr("short descriptor length=%d, left=%d\n", bump, (len - k)); - sgj_add_nv_o(jsp, jap, NULL, jo2p); + sgj_js_nv_o(jsp, jap, NULL, jo2p); return; } if (csd_len > 0) { @@ -799,16 +811,16 @@ decode_dev_constit_vpd(const uint8_t * buff, int len, struct opts_t * op, const uint8_t * cs_bp; sgj_pr_hr(jsp, " Constituent specific descriptors:\n"); - ja2p = sgj_new_named_array(jsp, jo2p, + ja2p = sgj_named_subarray_r(jsp, jo2p, "constituent_specific_descriptor_list"); for (m = 0, q = 0, cs_bp = bp + 36; m < csd_len; m += cs_bump, ++q, cs_bp += cs_bump) { - jo3p = sgj_new_unattached_object(jsp); + jo3p = sgj_new_unattached_object_r(jsp); cs_type = cs_bp[0]; cs_len = sg_get_unaligned_be16(cs_bp + 2); cs_bump = cs_len + 4; - sgj_add_nv_ihex(jsp, jo3p, "constituent_specific_type", - cs_type); + sgj_js_nv_ihex(jsp, jo3p, "constituent_specific_type", + cs_type); if (1 == cs_type) { /* VPD page */ int off = cs_bp + 4 - buff; @@ -828,16 +840,16 @@ decode_dev_constit_vpd(const uint8_t * buff, int len, struct opts_t * op, sgj_pr_hr(jsp, " Reserved [0x%x] specific " "data (in hex):\n", cs_type); if (jsp->pr_as_json) - sgj_add_nv_hex_bytes(jsp, jo3p, - "constituent_specific_data_hex", - cs_bp + 4, cs_len); + sgj_js_nv_hex_bytes(jsp, jo3p, + "constituent_specific_data_hex", + cs_bp + 4, cs_len); else hex2stdout(cs_bp + 4, cs_len, 0 /* plus ASCII */); } - sgj_add_nv_o(jsp, ja2p, NULL, jo3p); + sgj_js_nv_o(jsp, ja2p, NULL, jo3p); } /* end of Constituent specific descriptor loop */ } - sgj_add_nv_o(jsp, jap, NULL, jo2p); + sgj_js_nv_o(jsp, jap, NULL, jo2p); } /* end Constituent descriptor loop */ } @@ -907,66 +919,334 @@ std_inq_decode_js(const uint8_t * b, int len, struct opts_t * op, char c[256]; static const int clen = sizeof(c); - jo2p = sgj_new_named_object(jsp, jop, "standard_inquiry_data_format"); - sgj_add_nv_ihexstr(jsp, jo2p, "peripheral_qualifier", pqual, NULL, - pqual_str(pqual)); - sgj_add_nv_ihexstr(jsp, jo2p, "peripheral_device_type", pdt, NULL, - sg_get_pdt_str(pdt, clen, c)); - sgj_add_nv_ihex_nex(jsp, jo2p, "rmb", !!(b[1] & 0x80), false, - "Removable Medium Bit"); - sgj_add_nv_ihex_nex(jsp, jo2p, "lu_cong", !!(b[1] & 0x40), false, - "Logical Unit Conglomerate"); - sgj_add_nv_ihexstr(jsp, jo2p, "hot_pluggable", hp, NULL, - hot_pluggable_str(hp)); + jo2p = sgj_named_subobject_r(jsp, jop, "standard_inquiry_data_format"); + sgj_js_nv_ihexstr(jsp, jo2p, "peripheral_qualifier", pqual, NULL, + pqual_str(pqual)); + sgj_js_nv_ihexstr(jsp, jo2p, "peripheral_device_type", pdt, NULL, + sg_get_pdt_str(pdt, clen, c)); + sgj_js_nv_ihex_nex(jsp, jo2p, "rmb", !!(b[1] & 0x80), false, + "Removable Medium Bit"); + sgj_js_nv_ihex_nex(jsp, jo2p, "lu_cong", !!(b[1] & 0x40), false, + "Logical Unit Conglomerate"); + sgj_js_nv_ihexstr(jsp, jo2p, "hot_pluggable", hp, NULL, + hot_pluggable_str(hp)); snprintf(c, clen, "%s", (ver > 0xf) ? "old or reserved version code" : sg_ansi_version_arr[ver]); - sgj_add_nv_ihexstr(jsp, jo2p, "version", ver, NULL, c); - sgj_add_nv_ihex_nex(jsp, jo2p, "aerc", !!(b[3] & 0x80), false, - "Asynchronous Event Reporting Capability (obsolete " - "SPC-3)"); - sgj_add_nv_ihex_nex(jsp, jo2p, "trmtsk", !!(b[3] & 0x40), false, - "Terminate Task (obsolete SPC-2)"); - sgj_add_nv_ihex_nex(jsp, jo2p, "normaca", !!(b[3] & 0x20), false, - "Normal ACA (Auto Contingent Allegiance)"); - sgj_add_nv_ihex_nex(jsp, jo2p, "hisup", !!(b[3] & 0x10), false, - "Hierarchial Support"); - sgj_add_nv_ihex(jsp, jo2p, "response_data_format", b[3] & 0xf); - sgj_add_nv_ihex_nex(jsp, jo2p, "sccs", !!(b[5] & 0x80), false, - "SCC (SCSI Storage Commands) Supported"); - sgj_add_nv_ihex_nex(jsp, jo2p, "acc", !!(b[5] & 0x40), false, - "Access Commands Coordinator (obsolete SPC-5)"); + sgj_js_nv_ihexstr(jsp, jo2p, "version", ver, NULL, c); + sgj_js_nv_ihex_nex(jsp, jo2p, "aerc", !!(b[3] & 0x80), false, + "Asynchronous Event Reporting Capability (obsolete " + "SPC-3)"); + sgj_js_nv_ihex_nex(jsp, jo2p, "trmtsk", !!(b[3] & 0x40), false, + "Terminate Task (obsolete SPC-2)"); + sgj_js_nv_ihex_nex(jsp, jo2p, "normaca", !!(b[3] & 0x20), false, + "Normal ACA (Auto Contingent Allegiance)"); + sgj_js_nv_ihex_nex(jsp, jo2p, "hisup", !!(b[3] & 0x10), false, + "Hierarchial Support"); + sgj_js_nv_ihex(jsp, jo2p, "response_data_format", b[3] & 0xf); + sgj_js_nv_ihex_nex(jsp, jo2p, "sccs", !!(b[5] & 0x80), false, + "SCC (SCSI Storage Commands) Supported"); + sgj_js_nv_ihex_nex(jsp, jo2p, "acc", !!(b[5] & 0x40), false, + "Access Commands Coordinator (obsolete SPC-5)"); tpgs = (b[5] >> 4) & 0x3; - sgj_add_nv_ihexstr_nex(jsp, jo2p, "tpgs", tpgs, false, NULL, - tpgs_str(tpgs), "Target Port Group Support"); - sgj_add_nv_ihex_nex(jsp, jo2p, "3pc", !!(b[5] & 0x8), false, - "Third Party Copy"); - sgj_add_nv_ihex(jsp, jo2p, "protect", !!(b[5] & 0x1)); + sgj_js_nv_ihexstr_nex(jsp, jo2p, "tpgs", tpgs, false, NULL, + tpgs_str(tpgs), "Target Port Group Support"); + sgj_js_nv_ihex_nex(jsp, jo2p, "3pc", !!(b[5] & 0x8), false, + "Third Party Copy"); + sgj_js_nv_ihex(jsp, jo2p, "protect", !!(b[5] & 0x1)); /* Skip SPI specific flags which have been obsolete for a while) */ - sgj_add_nv_ihex_nex(jsp, jo2p, "bque", !!(b[6] & 0x80), false, - "Basic task management model (obsolete SPC-4)"); - sgj_add_nv_ihex_nex(jsp, jo2p, "encserv", !!(b[6] & 0x40), false, - "Enclousure Services supported"); - sgj_add_nv_ihex_nex(jsp, jo2p, "multip", !!(b[6] & 0x10), false, - "Multiple SCSI port"); - sgj_add_nv_ihex_nex(jsp, jo2p, "mchngr", !!(b[6] & 0x8), false, - "Medium changer (obsolete SPC-4)"); - sgj_add_nv_ihex_nex(jsp, jo2p, "reladr", !!(b[7] & 0x80), false, - "Relative Addressing (obsolete in SPC-4)"); - sgj_add_nv_ihex_nex(jsp, jo2p, "linked", !!(b[7] & 0x8), false, - "Linked Commands (obsolete in SPC-4)"); - sgj_add_nv_ihex_nex(jsp, jo2p, "cmdque", !!(b[7] & 0x2), false, - "Command Management Model (command queuing)"); + sgj_js_nv_ihex_nex(jsp, jo2p, "bque", !!(b[6] & 0x80), false, + "Basic task management model (obsolete SPC-4)"); + sgj_js_nv_ihex_nex(jsp, jo2p, "encserv", !!(b[6] & 0x40), false, + "Enclousure Services supported"); + sgj_js_nv_ihex_nex(jsp, jo2p, "multip", !!(b[6] & 0x10), false, + "Multiple SCSI port"); + sgj_js_nv_ihex_nex(jsp, jo2p, "mchngr", !!(b[6] & 0x8), false, + "Medium changer (obsolete SPC-4)"); + sgj_js_nv_ihex_nex(jsp, jo2p, "reladr", !!(b[7] & 0x80), false, + "Relative Addressing (obsolete in SPC-4)"); + sgj_js_nv_ihex_nex(jsp, jo2p, "linked", !!(b[7] & 0x8), false, + "Linked Commands (obsolete in SPC-4)"); + sgj_js_nv_ihex_nex(jsp, jo2p, "cmdque", !!(b[7] & 0x2), false, + "Command Management Model (command queuing)"); if (len < 16) return jo2p; snprintf(c, clen, "%.8s", b + 8); - sgj_add_nv_s(jsp, jo2p, t10_vendor_id_js, c); + sgj_js_nv_s(jsp, jo2p, t10_vendor_id_js, c); if (len < 32) return jo2p; snprintf(c, clen, "%.16s", b + 16); - sgj_add_nv_s(jsp, jo2p, product_id_js, c); + sgj_js_nv_s(jsp, jo2p, product_id_js, c); if (len < 36) return jo2p; snprintf(c, clen, "%.4s", b + 32); - sgj_add_nv_s(jsp, jo2p, product_rev_lev_js, c); + sgj_js_nv_s(jsp, jo2p, product_rev_lev_js, c); return jo2p; } + +static const char * power_unit_arr[] = +{ + "Gigawatts", + "Megawatts", + "Kilowatts", + "Watts", + "Milliwatts", + "Microwatts", + "Unit reserved", + "Unit reserved", +}; + +/* VPD_POWER_CONSUMPTION 0x8d ["psm"] */ +void +decode_power_consumption(uint8_t * buff, int len, struct opts_t * op, + sgj_opaque_p jap) +{ + int k, bump, pcmp_id, pcmp_unit; + unsigned int pcmp_val; + sgj_state * jsp = &op->json_st; + sgj_opaque_p jo2p; + uint8_t * bp; + char b[128]; + static const int blen = sizeof(b); + static const char * pcmp = "power_consumption"; + static const char * pci = "Power consumption identifier"; + static const char * mpc = "Maximum power consumption"; + + if ((1 == op->do_hex) || (op->do_hex > 2)) { + hex2stdout(buff, len, (1 == op->do_hex) ? 1 : -1); + return; + } + if (len < 4) { + pr2serr("length too short=%d\n", len); + return; + } + len -= 4; + bp = buff + 4; + for (k = 0; k < len; k += bump, bp += bump) { + bump = 4; + if ((k + bump) > len) { + pr2serr("short descriptor length=%d, left=%d\n", bump, + (len - k)); + return; + } + if (op->do_hex > 1) + hex2stdout(bp, 4, 1); + else { + jo2p = sgj_new_unattached_object_r(jsp); + pcmp_id = bp[0]; + pcmp_unit = 0x7 & bp[1]; + pcmp_val = sg_get_unaligned_be16(bp + 2); + if (jsp->pr_as_json) { + sgj_convert_to_snake_name(pci, b, blen); + sgj_js_nv_ihex(jsp, jo2p, b, pcmp_id); + snprintf(b, blen, "%s_units", pcmp); + sgj_js_nv_ihexstr(jsp, jo2p, b, pcmp_unit, NULL, + power_unit_arr[pcmp_unit]); + snprintf(b, blen, "%s_value", pcmp); + sgj_js_nv_ihex(jsp, jo2p, b, pcmp_val); + } + snprintf(b, blen, " %s: 0x%x", pci, pcmp_id); + if (pcmp_val >= 1000 && pcmp_unit > 0) + sgj_pr_hr(jsp, "%s %s: %d.%03d %s\n", b, mpc, + pcmp_val / 1000, pcmp_val % 1000, + power_unit_arr[pcmp_unit - 1]); /* up one unit */ + else + sgj_pr_hr(jsp, "%s %s: %u %s\n", b, mpc, pcmp_val, + power_unit_arr[pcmp_unit]); + sgj_js_nv_o(jsp, jap, NULL /* name */, jo2p); + } + } +} + +/* VPD_BLOCK_LIMITS 0xb0 ["bl"] */ +void +decode_block_limits_vpd(const uint8_t * buff, int len, struct opts_t * op, + sgj_opaque_p jop) +{ + int wsnz, ugavalid; + uint32_t u; + uint64_t ull; + sgj_state * jsp = &op->json_st; + char b[144]; + static const int blen = sizeof(b); + static const char * mcawl = "Maximum compare and write length"; + static const char * otlg = "Optimal transfer length granularity"; + static const char * cni = "command not implemented"; + static const char * nr = "not reported"; + static const char * ul = "unlimited"; + static const char * mtl = "Maximum transfer length"; + static const char * otl = "Optimal transfer length"; + static const char * mpl = "Maximum prefetch length"; + static const char * mulc = "Maximum unmap LBA count"; + static const char * mubdc = "Maximum unmap block descriptor count"; + static const char * oug = "Optimal unmap granularity"; + static const char * ugav = "Unmap granularity alignment valid"; + static const char * uga = "Unmap granularity alignment"; + static const char * mwsl = "Maximum write same length"; + static const char * matl = "Maximum atomic transfer length"; + static const char * aa = "Atomic alignment"; + static const char * atlg = "Atomic transfer length granularity"; + static const char * matlwab = "Maximum atomic transfer length with " + "atomic boundary"; + static const char * mabs = "Maximum atomic boundary size"; + + if (len < 16) { + pr2serr("page length too short=%d\n", len); + return; + } + wsnz = !!(buff[4] & 0x1); + sgj_pr_hr(jsp, " Write same non-zero (WSNZ): %d\n", wsnz); + sgj_js_nv_ihex_nex(jsp, jop, "wsnz", wsnz, false, + "Write Same Non-Zero (number of LBs must be > 0)"); + u = buff[5]; + if (0 == u) { + sgj_pr_hr(jsp, " %s: 0 blocks [%s]\n", mcawl, cni); + sgj_convert_to_snake_name(mcawl, b, blen); + sgj_js_nv_ihexstr(jsp, jop, b, u, NULL, cni); + } else + sgj_hr_js_vi_nex(jsp, jop, 2, mcawl, SGJ_SEP_COLON_1_SPACE, u, + true, "unit: LB"); + + u = sg_get_unaligned_be16(buff + 6); + if (0 == u) { + sgj_pr_hr(jsp, " %s: 0 blocks [%s]\n", otlg, nr); + sgj_convert_to_snake_name(otlg, b, blen); + sgj_js_nv_ihexstr(jsp, jop, b, u, NULL, nr); + } else + sgj_hr_js_vi_nex(jsp, jop, 2, otlg, SGJ_SEP_COLON_1_SPACE, u, + true, "unit: LB"); + + u = sg_get_unaligned_be32(buff + 8); + if (0 == u) { + sgj_pr_hr(jsp, " %s: 0 blocks [%s]\n", mtl, nr); + sgj_convert_to_snake_name(mtl, b, blen); + sgj_js_nv_ihexstr(jsp, jop, b, u, NULL, nr); + } else + sgj_hr_js_vi_nex(jsp, jop, 2, mtl, SGJ_SEP_COLON_1_SPACE, u, + true, "unit: LB"); + + u = sg_get_unaligned_be32(buff + 12); + if (0 == u) { + sgj_pr_hr(jsp, " %s: 0 blocks [%s]\n", otl, nr); + sgj_convert_to_snake_name(otl, b, blen); + sgj_js_nv_ihexstr(jsp, jop, b, u, NULL, nr); + } else + sgj_hr_js_vi_nex(jsp, jop, 2, otl, SGJ_SEP_COLON_1_SPACE, u, + true, "unit: LB"); + if (len > 19) { /* added in sbc3r09 */ + u = sg_get_unaligned_be32(buff + 16); + if (0 == u) { + sgj_pr_hr(jsp, " %s: 0 blocks [%s]\n", mpl, nr); + sgj_convert_to_snake_name(mpl, b, blen); + sgj_js_nv_ihexstr(jsp, jop, b, u, NULL, nr); + } else + sgj_hr_js_vi_nex(jsp, jop, 2, mpl, SGJ_SEP_COLON_1_SPACE, u, + true, "unit: LB"); + } + if (len > 27) { /* added in sbc3r18 */ + u = sg_get_unaligned_be32(buff + 20); + sgj_convert_to_snake_name(mulc, b, blen); + if (0 == u) { + sgj_pr_hr(jsp, " %s: 0 blocks [%s]\n", mulc, cni); + sgj_js_nv_ihexstr(jsp, jop, b, u, NULL, cni); + } else if (0xffffffff == u) { + sgj_pr_hr(jsp, " %s: %s blocks\n", ul, mulc); + sgj_js_nv_ihexstr(jsp, jop, b, u, NULL, ul); + } else + sgj_hr_js_vi_nex(jsp, jop, 2, mulc, SGJ_SEP_COLON_1_SPACE, u, + true, "unit: LB"); + + u = sg_get_unaligned_be32(buff + 24); + sgj_convert_to_snake_name(mulc, b, blen); + if (0 == u) { + sgj_pr_hr(jsp, " %s: 0 block descriptors [%s]\n", mubdc, cni); + sgj_js_nv_ihexstr(jsp, jop, b, u, NULL, cni); + } else if (0xffffffff == u) { + sgj_pr_hr(jsp, " %s: %s block descriptors\n", ul, mubdc); + sgj_js_nv_ihexstr(jsp, jop, b, u, NULL, ul); + } else + sgj_hr_js_vi(jsp, jop, 2, mubdc, SGJ_SEP_COLON_1_SPACE, + u, true); + } + if (len > 35) { /* added in sbc3r19 */ + u = sg_get_unaligned_be32(buff + 28); + if (0 == u) { + sgj_pr_hr(jsp, " %s: 0 blocks [%s]\n", oug, nr); + sgj_convert_to_snake_name(oug, b, blen); + sgj_js_nv_ihexstr(jsp, jop, b, u, NULL, nr); + } else + sgj_hr_js_vi_nex(jsp, jop, 2, oug, SGJ_SEP_COLON_1_SPACE, u, + true, "unit: LB"); + + ugavalid = !!(buff[32] & 0x80); + sgj_pr_hr(jsp, " %s: %s\n", ugav, ugavalid ? "true" : "false"); + sgj_js_nv_i(jsp, jop, ugav, ugavalid); + if (ugavalid) { + u = 0x7fffffff & sg_get_unaligned_be32(buff + 32); + sgj_hr_js_vi_nex(jsp, jop, 2, uga, SGJ_SEP_COLON_1_SPACE, u, + true, "unit: LB"); + } + } + if (len > 43) { /* added in sbc3r26 */ + ull = sg_get_unaligned_be64(buff + 36); + if (0 == ull) { + sgj_pr_hr(jsp, " %s: 0 blocks [%s]\n", mwsl, nr); + sgj_convert_to_snake_name(mwsl, b, blen); + sgj_js_nv_ihexstr(jsp, jop, b, ull, NULL, nr); + } else + sgj_hr_js_vi_nex(jsp, jop, 2, mwsl, SGJ_SEP_COLON_1_SPACE, + ull, true, "unit: LB"); + } + if (len > 47) { /* added in sbc4r02 */ + u = sg_get_unaligned_be32(buff + 44); + if (0 == u) { + sgj_pr_hr(jsp, " %s: 0 blocks [%s]\n", matl, nr); + sgj_convert_to_snake_name(matl, b, blen); + sgj_js_nv_ihexstr(jsp, jop, b, u, NULL, nr); + } else + sgj_hr_js_vi_nex(jsp, jop, 2, matl, SGJ_SEP_COLON_1_SPACE, + u, true, "unit: LB"); + + u = sg_get_unaligned_be32(buff + 48); + if (0 == u) { + static const char * uawp = "unaligned atomic writes permitted"; + + sgj_pr_hr(jsp, " %s: 0 blocks [%s]\n", aa, uawp); + sgj_convert_to_snake_name(aa, b, blen); + sgj_js_nv_ihexstr(jsp, jop, b, u, NULL, uawp); + } else + sgj_hr_js_vi_nex(jsp, jop, 2, aa, SGJ_SEP_COLON_1_SPACE, + u, true, "unit: LB"); + + u = sg_get_unaligned_be32(buff + 52); + if (0 == u) { + static const char * ngr = "no granularity requirement"; + + sgj_pr_hr(jsp, " %s: 0 blocks [%s]\n", atlg, ngr); + sgj_convert_to_snake_name(atlg, b, blen); + sgj_js_nv_ihexstr(jsp, jop, b, u, NULL, ngr); + } else + sgj_hr_js_vi_nex(jsp, jop, 2, aa, SGJ_SEP_COLON_1_SPACE, + u, true, "unit: LB"); + } + if (len > 56) { + u = sg_get_unaligned_be32(buff + 56); + if (0 == u) { + sgj_pr_hr(jsp, " %s: 0 blocks [%s]\n", matlwab, nr); + sgj_convert_to_snake_name(matlwab, b, blen); + sgj_js_nv_ihexstr(jsp, jop, b, u, NULL, nr); + } else + sgj_hr_js_vi_nex(jsp, jop, 2, matlwab, SGJ_SEP_COLON_1_SPACE, + u, true, "unit: LB"); + + u = sg_get_unaligned_be32(buff + 60); + if (0 == u) { + static const char * cowa1b = "can only write atomic 1 block"; + + sgj_pr_hr(jsp, " %s: 0 blocks [%s]\n", mabs, cowa1b); + sgj_convert_to_snake_name(mabs, b, blen); + sgj_js_nv_ihexstr(jsp, jop, b, u, NULL, cowa1b); + } else + sgj_hr_js_vi_nex(jsp, jop, 2, mabs, SGJ_SEP_COLON_1_SPACE, + u, true, "unit: LB"); + } +} diff --git a/src/sg_vpd_common.h b/src/sg_vpd_common.h index 7cb56293..3f182664 100644 --- a/src/sg_vpd_common.h +++ b/src/sg_vpd_common.h @@ -87,6 +87,7 @@ struct opts_t { bool verbose_given; /* sg_inq + sg_vpd */ bool version_given; /* sg_inq + sg_vpd */ bool do_vpd; /* sg_inq */ + bool std_inq_a_valid; /* sg_inq + sg_vpd */ #ifdef SG_SCSI_STRINGS bool opt_new; /* sg_inq */ #endif @@ -108,8 +109,10 @@ struct opts_t { const char * device_name; /* sg_inq + sg_vpd */ const char * page_str; /* sg_inq + sg_vpd */ const char * inhex_fn; /* sg_inq + sg_vpd */ + const char * sinq_inraw_fn; /* sg_inq + sg_vpd */ const char * vend_prod; /* sg_vpd */ sgj_state json_st; + uint8_t std_inq_a[36]; }; struct svpd_values_name_t { @@ -147,6 +150,10 @@ void decode_dev_constit_vpd(const uint8_t * buff, int len, recurse_vpd_decodep fp); sgj_opaque_p std_inq_decode_js(const uint8_t * b, int len, struct opts_t * op, sgj_opaque_p jop); +void decode_power_consumption(uint8_t * buff, int len, + struct opts_t * op, sgj_opaque_p jap); +void decode_block_limits_vpd(const uint8_t * buff, int len, + struct opts_t * op, sgj_opaque_p jop); const char * pqual_str(int pqual); void svpd_enumerate_vendor(int vend_prod_num); |