aboutsummaryrefslogtreecommitdiff
path: root/src/sg_vpd.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/sg_vpd.c')
-rw-r--r--src/sg_vpd.c731
1 files changed, 179 insertions, 552 deletions
diff --git a/src/sg_vpd.c b/src/sg_vpd.c
index 89c982e4..122111d2 100644
--- a/src/sg_vpd.c
+++ b/src/sg_vpd.c
@@ -31,7 +31,7 @@
#include "sg_unaligned.h"
#include "sg_pr2serr.h"
-#include "sg_vpd.h"
+#include "sg_vpd_common.h" /* shared with sg_inq */
/* This utility program was originally written for the Linux OS SCSI subsystem.
@@ -42,49 +42,9 @@
*/
-static const char * version_str = "1.73 20220705"; /* spc6r06 + sbc5r01 */
-
-#define MY_NAME "sg_decode_sense"
-
-/* standard VPD pages, in ascending page number order */
-#define VPD_SUPPORTED_VPDS 0x0
-#define VPD_UNIT_SERIAL_NUM 0x80
-#define VPD_IMP_OP_DEF 0x81 /* obsolete in SPC-2 */
-#define VPD_ASCII_OP_DEF 0x82 /* obsolete in SPC-2 */
-#define VPD_DEVICE_ID 0x83
-#define VPD_SOFTW_INF_ID 0x84
-#define VPD_MAN_NET_ADDR 0x85
-#define VPD_EXT_INQ 0x86 /* Extended Inquiry */
-#define VPD_MODE_PG_POLICY 0x87
-#define VPD_SCSI_PORTS 0x88
-#define VPD_ATA_INFO 0x89
-#define VPD_POWER_CONDITION 0x8a
-#define VPD_DEVICE_CONSTITUENTS 0x8b
-#define VPD_CFA_PROFILE_INFO 0x8c
-#define VPD_POWER_CONSUMPTION 0x8d
-#define VPD_3PARTY_COPY 0x8f /* 3PC, XCOPY, SPC-4, SBC-3 */
-#define VPD_PROTO_LU 0x90
-#define VPD_PROTO_PORT 0x91
-#define VPD_SCSI_FEATURE_SETS 0x92 /* spc5r11 */
-#define VPD_BLOCK_LIMITS 0xb0 /* SBC-3 */
-#define VPD_SA_DEV_CAP 0xb0 /* SSC-3 */
-#define VPD_OSD_INFO 0xb0 /* OSD */
-#define VPD_BLOCK_DEV_CHARS 0xb1 /* SBC-3 */
-#define VPD_MAN_ASS_SN 0xb1 /* SSC-3, ADC-2 */
-#define VPD_SECURITY_TOKEN 0xb1 /* OSD */
-#define VPD_TA_SUPPORTED 0xb2 /* SSC-3 */
-#define VPD_LB_PROVISIONING 0xb2 /* SBC-3 */
-#define VPD_REFERRALS 0xb3 /* SBC-3 */
-#define VPD_AUTOMATION_DEV_SN 0xb3 /* SSC-3 */
-#define VPD_SUP_BLOCK_LENS 0xb4 /* sbc4r01 */
-#define VPD_DTDE_ADDRESS 0xb4 /* SSC-4 */
-#define VPD_BLOCK_DEV_C_EXTENS 0xb5 /* sbc4r02 */
-#define VPD_LB_PROTECTION 0xb5 /* SSC-5 */
-#define VPD_ZBC_DEV_CHARS 0xb6 /* zbc-r01b */
-#define VPD_BLOCK_LIMITS_EXT 0xb7 /* sbc4r08 */
-#define VPD_FORMAT_PRESETS 0xb8 /* sbc4r18 */
-#define VPD_CON_POS_RANGE 0xb9 /* sbc5r01 */
-#define VPD_NOPE_WANT_STD_INQ -2 /* request for standard inquiry */
+static const char * version_str = "1.74 20220711"; /* spc6r06 + sbc5r01 */
+
+#define MY_NAME "sg_vpd"
/* Device identification VPD page associations */
#define VPD_ASSOC_LU 0
@@ -118,7 +78,6 @@ static int svpd_unable_to_decode(int sg_fd, struct opts_t * op, int subvalue,
static int filter_dev_ids(const char * print_if_found, int num_leading,
uint8_t * buff, int len, int m_assoc,
- int m_desig_type, int m_code_set,
struct opts_t * op, sgj_opaque_p jop);
static const int rsp_buff_sz = MX_ALLOC_LEN + 2;
@@ -450,20 +409,7 @@ static const char * sg_ansi_version_arr[16] =
"reserved [Fh]",
};
-static const char *
-pqual_str(int pqual)
-{
- switch (pqual) {
- case 0:
- return "LU accessible";
- case 1:
- return "LU temporarily unavailable";
- case 3:
- return "LU not accessible via this port";
- default:
- return "value reserved by T10";
- }
-}
+static const char * vpd_p_s = "VPD page";
static const char *
hot_pluggable_str(int hp)
@@ -569,49 +515,49 @@ skip1:
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_ane(jsp, jo2p, "rmb", !!(b[1] & 0x80), false,
+ sgj_add_nv_ihex_nex(jsp, jo2p, "rmb", !!(b[1] & 0x80), false,
"Removable Medium Bit");
- sgj_add_nv_ihex_ane(jsp, jo2p, "lu_cong", !!(b[1] & 0x40), false,
+ 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));
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_ane(jsp, jo2p, "aerc", !!(b[3] & 0x80), false,
+ sgj_add_nv_ihex_nex(jsp, jo2p, "aerc", !!(b[3] & 0x80), false,
"Asynchronous Event Reporting Capability (obsolete "
"SPC-3)");
- sgj_add_nv_ihex_ane(jsp, jo2p, "trmtsk", !!(b[3] & 0x40), false,
+ sgj_add_nv_ihex_nex(jsp, jo2p, "trmtsk", !!(b[3] & 0x40), false,
"Terminate Task (obsolete SPC-2)");
- sgj_add_nv_ihex_ane(jsp, jo2p, "normaca", !!(b[3] & 0x20), false,
+ sgj_add_nv_ihex_nex(jsp, jo2p, "normaca", !!(b[3] & 0x20), false,
"Normal ACA (Auto Contingent Allegiance)");
- sgj_add_nv_ihex_ane(jsp, jo2p, "hisup", !!(b[3] & 0x10), false,
+ 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_ane(jsp, jo2p, "sccs", !!(b[5] & 0x80), false,
+ sgj_add_nv_ihex_nex(jsp, jo2p, "sccs", !!(b[5] & 0x80), false,
"SCC (SCSI Storage Commands) Supported");
- sgj_add_nv_ihex_ane(jsp, jo2p, "acc", !!(b[5] & 0x40), false,
+ sgj_add_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_ane(jsp, jo2p, "tpgs", tpgs, false, NULL,
+ sgj_add_nv_ihexstr_nex(jsp, jo2p, "tpgs", tpgs, false, NULL,
tpgs_str(tpgs), "Target Port Group Support");
- sgj_add_nv_ihex_ane(jsp, jo2p, "3pc", !!(b[5] & 0x8), false,
+ 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));
/* Skip SPI specific flags which have been obsolete for a while) */
- sgj_add_nv_ihex_ane(jsp, jo2p, "bque", !!(b[6] & 0x80), false,
+ sgj_add_nv_ihex_nex(jsp, jo2p, "bque", !!(b[6] & 0x80), false,
"Basic task management model (obsolete SPC-4)");
- sgj_add_nv_ihex_ane(jsp, jo2p, "encserv", !!(b[6] & 0x40), false,
+ sgj_add_nv_ihex_nex(jsp, jo2p, "encserv", !!(b[6] & 0x40), false,
"Enclousure Services supported");
- sgj_add_nv_ihex_ane(jsp, jo2p, "multip", !!(b[6] & 0x10), false,
+ sgj_add_nv_ihex_nex(jsp, jo2p, "multip", !!(b[6] & 0x10), false,
"Multiple SCSI port");
- sgj_add_nv_ihex_ane(jsp, jo2p, "mchngr", !!(b[6] & 0x8), false,
+ sgj_add_nv_ihex_nex(jsp, jo2p, "mchngr", !!(b[6] & 0x8), false,
"Medium changer (obsolete SPC-4)");
- sgj_add_nv_ihex_ane(jsp, jo2p, "reladr", !!(b[7] & 0x80), false,
+ sgj_add_nv_ihex_nex(jsp, jo2p, "reladr", !!(b[7] & 0x80), false,
"Relative Addressing (obsolete in SPC-4)");
- sgj_add_nv_ihex_ane(jsp, jo2p, "linked", !!(b[7] & 0x8), false,
+ sgj_add_nv_ihex_nex(jsp, jo2p, "linked", !!(b[7] & 0x8), false,
"Linked Commands (obsolete in SPC-4)");
- sgj_add_nv_ihex_ane(jsp, jo2p, "cmdque", !!(b[7] & 0x2), false,
+ sgj_add_nv_ihex_nex(jsp, jo2p, "cmdque", !!(b[7] & 0x2), false,
"Command Management Model (command queuing)");
if (len < 16)
return;
@@ -627,11 +573,12 @@ skip1:
sgj_add_nv_s(jsp, jo2p, "product_revision_level", c);
}
+/* VPD_DEVICE_ID 0x83 ["di, di_asis, di_lu, di_port, di_target"] */
static void
device_id_vpd_variants(uint8_t * buff, int len, int subvalue,
struct opts_t * op, sgj_opaque_p jap)
{
- int m_a, m_d, m_cs, blen;
+ int m_a, blen;
uint8_t * b;
if (len < 4) {
@@ -641,155 +588,29 @@ device_id_vpd_variants(uint8_t * buff, int len, int subvalue,
blen = len - 4;
b = buff + 4;
m_a = -1;
- m_d = -1;
- m_cs = -1;
if (0 == subvalue) {
filter_dev_ids(sg_get_desig_assoc_str(VPD_ASSOC_LU), 0, b, blen,
- VPD_ASSOC_LU, m_d, m_cs, op, jap);
+ VPD_ASSOC_LU, op, jap);
filter_dev_ids(sg_get_desig_assoc_str(VPD_ASSOC_TPORT), 0, b, blen,
- VPD_ASSOC_TPORT, m_d, m_cs, op, jap);
+ VPD_ASSOC_TPORT, op, jap);
filter_dev_ids(sg_get_desig_assoc_str(VPD_ASSOC_TDEVICE), 0, b, blen,
- VPD_ASSOC_TDEVICE, m_d, m_cs, op, jap);
+ VPD_ASSOC_TDEVICE, op, jap);
} else if (VPD_DI_SEL_AS_IS == subvalue)
- filter_dev_ids(NULL, 0, b, blen, m_a, m_d, m_cs, op, jap);
+ filter_dev_ids(NULL, 0, b, blen, m_a, op, jap);
else {
if (VPD_DI_SEL_LU & subvalue)
filter_dev_ids(sg_get_desig_assoc_str(VPD_ASSOC_LU), 0, b, blen,
- VPD_ASSOC_LU, m_d, m_cs, op, jap);
+ VPD_ASSOC_LU, op, jap);
if (VPD_DI_SEL_TPORT & subvalue)
filter_dev_ids(sg_get_desig_assoc_str(VPD_ASSOC_TPORT), 0, b,
- blen, VPD_ASSOC_TPORT, m_d, m_cs, op, jap);
+ blen, VPD_ASSOC_TPORT, op, jap);
if (VPD_DI_SEL_TARGET & subvalue)
filter_dev_ids(sg_get_desig_assoc_str(VPD_ASSOC_TDEVICE), 0,
- b, blen, VPD_ASSOC_TDEVICE, m_d, m_cs, op, jap);
+ b, blen, VPD_ASSOC_TDEVICE, op, jap);
}
}
-static const char * network_service_type_arr[] =
-{
- "unspecified",
- "storage configuration service",
- "diagnostics",
- "status",
- "logging",
- "code download",
- "copy service",
- "administrative configuration service",
- "reserved[0x8]", "reserved[0x9]",
- "reserved[0xa]", "reserved[0xb]", "reserved[0xc]", "reserved[0xd]",
- "reserved[0xe]", "reserved[0xf]", "reserved[0x10]", "reserved[0x11]",
- "reserved[0x12]", "reserved[0x13]", "reserved[0x14]", "reserved[0x15]",
- "reserved[0x16]", "reserved[0x17]", "reserved[0x18]", "reserved[0x19]",
- "reserved[0x1a]", "reserved[0x1b]", "reserved[0x1c]", "reserved[0x1d]",
- "reserved[0x1e]", "reserved[0x1f]",
-};
-
-/* VPD_MAN_NET_ADDR */
-static void
-decode_net_man_vpd(uint8_t * buff, int len, struct opts_t * op,
- sgj_opaque_p jap)
-{
- int k, bump, na_len, assoc, nst;
- sgj_state * jsp = &op->json_st;
- sgj_opaque_p jo2p;
- uint8_t * bp;
- const char * assoc_str;
- const char * nst_str;
-
- if ((1 == op->do_hex) || (op->do_hex > 2)) {
- hex2stdout(buff, len, (1 == op->do_hex) ? 0 : -1);
- return;
- }
- if (len < 4) {
- pr2serr("Management network addresses VPD page length too short=%d\n",
- len);
- return;
- }
- len -= 4;
- bp = buff + 4;
- for (k = 0; k < len; k += bump, bp += bump) {
- assoc = (bp[0] >> 5) & 0x3;
- assoc_str = sg_get_desig_assoc_str(assoc);
- nst = bp[0] & 0x1f;
- nst_str = network_service_type_arr[nst];
- 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);
- }
- if (na_len > 0) {
- if (op->do_hex > 1) {
- printf(" Network address:\n");
- hex2stdout((bp + 4), na_len, 0);
- } else
- sgj_pr_hr(jsp, " %s\n", bp + 4);
- }
- bump = 4 + na_len;
- if ((k + bump) > len) {
- pr2serr("Management network addresses VPD page, short "
- "descriptor length=%d, left=%d\n", bump, (len - k));
- return;
- }
- }
-}
-
-static const char * mode_page_policy_arr[] =
-{
- "shared",
- "per target port",
- "per initiator port",
- "per I_T nexus",
-};
-
-/* VPD_MODE_PG_POLICY */
-static void
-decode_mode_policy_vpd(uint8_t * buff, int len, int do_hex)
-{
- int k, bump;
- uint8_t * bp;
-
- if ((1 == do_hex) || (do_hex > 2)) {
- hex2stdout(buff, len, (1 == do_hex) ? 1 : -1);
- return;
- }
- if (len < 4) {
- pr2serr("Mode page policy VPD page 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("Mode page policy VPD page, short "
- "descriptor length=%d, left=%d\n", bump, (len - k));
- return;
- }
- if (do_hex > 1)
- hex2stdout(bp, 4, 1);
- else {
- printf(" Policy page code: 0x%x", (bp[0] & 0x3f));
- if (bp[1])
- printf(", subpage code: 0x%x\n", bp[1]);
- else
- printf("\n");
- if ((0 == k) && (0x3f == (0x3f & bp[0])) && (0xff == bp[1]))
- printf(" therefore the policy applies to all modes pages "
- "and subpages\n");
- printf(" MLUS=%d, Policy: %s\n", !!(bp[2] & 0x80),
- mode_page_policy_arr[bp[2] & 0x3]);
- }
- }
-}
-
-/* VPD_SCSI_PORTS */
+/* VPD_SCSI_PORTS 0x88 ["sp"] */
static void
decode_scsi_ports_vpd(uint8_t * buff, int len, struct opts_t * op,
sgj_opaque_p jap)
@@ -829,6 +650,10 @@ decode_scsi_ports_vpd(uint8_t * buff, int len, struct opts_t * op,
} else {
char b[1024];
+ 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_pr_hr(jsp, "%s",
sg_decode_transportid_str(" ", bp + 8,
ip_tid_len, true, sizeof(b), b));
@@ -855,7 +680,7 @@ decode_scsi_ports_vpd(uint8_t * buff, int len, struct opts_t * op,
"designation_descriptor_list");
}
filter_dev_ids("", 2 /* leading spaces */, bp + bump + 4,
- tpd_len, VPD_ASSOC_TPORT, -1, -1, op, ja2p);
+ tpd_len, VPD_ASSOC_TPORT, op, ja2p);
}
}
bump += tpd_len + 4;
@@ -864,10 +689,10 @@ decode_scsi_ports_vpd(uint8_t * buff, int len, struct opts_t * op,
}
/* Prints outs an abridged set of device identification designators
- selected by association, designator type and/or code set. */
+ selected by association, designator type and/or code set. Not used
+ for JSON output. */
static int
-filter_dev_ids_quiet(uint8_t * buff, int len, int m_assoc,
- int m_desig_type, int m_code_set)
+filter_dev_ids_quiet(uint8_t * buff, int len, int m_assoc)
{
int k, m, p_id, c_set, piv, desig_type, i_len, naa, off, u;
int assoc, is_sas, rtp;
@@ -889,8 +714,7 @@ filter_dev_ids_quiet(uint8_t * buff, int len, int m_assoc,
desig_type = 3;
i_len = 16;
} else {
- u = sg_vpd_dev_id_iter(buff, len, &off, m_assoc, m_desig_type,
- m_code_set);
+ u = sg_vpd_dev_id_iter(buff, len, &off, m_assoc, -1, -1);
if (0 != u)
break;
bp = buff + off;
@@ -1061,11 +885,10 @@ filter_dev_ids_quiet(uint8_t * buff, int len, int m_assoc,
}
/* Prints outs designation descriptors (dd_s) selected by association,
- designator type and/or code set. */
+ designator type and/or code set. VPD_DEVICE_ID and VPD_SCSI_PORTS */
static int
filter_dev_ids(const char * print_if_found, int num_leading, uint8_t * buff,
- int len, int m_assoc, int m_desig_type, int m_code_set,
- struct opts_t * op, sgj_opaque_p jap)
+ int len, int m_assoc, struct opts_t * op, sgj_opaque_p jap)
{
bool printed, sgj_out_hr;
int assoc, off, u, i_len;
@@ -1076,8 +899,15 @@ filter_dev_ids(const char * print_if_found, int num_leading, uint8_t * buff,
static const int blen = sizeof(b);
if (op->do_quiet && (! jsp->pr_as_json))
- return filter_dev_ids_quiet(buff, len, m_assoc, m_desig_type,
- m_code_set);
+ return filter_dev_ids_quiet(buff, len, m_assoc);
+ sgj_out_hr = false;
+ if (jsp->pr_as_json) {
+ int ret = filter_json_dev_ids(buff, len, m_assoc, op, jap);
+
+ if (ret || (! jsp->pr_out_hr))
+ return ret;
+ sgj_out_hr = true;
+ }
if (num_leading > (int)(sizeof(sp) - 2))
num_leading = sizeof(sp) - 2;
if (num_leading > 0)
@@ -1093,8 +923,7 @@ filter_dev_ids(const char * print_if_found, int num_leading, uint8_t * buff,
}
off = -1;
printed = false;
- while ((u = sg_vpd_dev_id_iter(buff, len, &off, m_assoc, m_desig_type,
- m_code_set)) == 0) {
+ while ((u = sg_vpd_dev_id_iter(buff, len, &off, m_assoc, -1, -1)) == 0) {
bp = buff + off;
i_len = bp[3];
if ((off + i_len + 4) > len) {
@@ -1102,18 +931,6 @@ filter_dev_ids(const char * print_if_found, int num_leading, uint8_t * buff,
" remaining response length=%d\n", (len - off));
return SG_LIB_CAT_MALFORMED;
}
- sgj_out_hr = false;
- if (jsp->pr_as_json) {
- sgj_opaque_p jo2p;
-
- jo2p = sgj_new_unattached_object(jsp);
- sgj_get_designation_descriptor(jsp, jo2p, bp, i_len + 4);
- sgj_add_nv_o(jsp, jap, NULL /* name */, jo2p);
- if (jsp->pr_out_hr)
- sgj_out_hr = true;
- else
- continue;
- }
assoc = ((bp[1] >> 4) & 0x3);
if (print_if_found && (! printed)) {
printed = true;
@@ -1146,210 +963,53 @@ filter_dev_ids(const char * print_if_found, int num_leading, uint8_t * buff,
return 0;
}
-/* VPD_EXT_INQ Extended Inquiry VPD */
+/* VPD_ATA_INFO 0x89 ['ai"] */
static void
-decode_x_inq_vpd(uint8_t * b, int len, int do_hex, bool do_long,
- bool protect)
-{
- int n;
-
- if (len < 7) {
- pr2serr("Extended INQUIRY data VPD page length too short=%d\n", len);
- return;
- }
- if (do_hex) {
- hex2stdout(b, len, (1 == do_hex) ? 0 : -1);
- return;
- }
- if (do_long) {
- n = (b[4] >> 6) & 0x3;
- printf(" ACTIVATE_MICROCODE=%d", n);
- if (1 == n)
- printf(" [before final WRITE BUFFER]\n");
- else if (2 == n)
- printf(" [after power on or hard reset]\n");
- else
- printf("\n");
- n = (b[4] >> 3) & 0x7;
- printf(" SPT=%d", n);
- if (protect) {
- switch (n)
- {
- case 0:
- printf(" [protection type 1 supported]\n");
- break;
- case 1:
- printf(" [protection types 1 and 2 supported]\n");
- break;
- case 2:
- printf(" [protection type 2 supported]\n");
- break;
- case 3:
- printf(" [protection types 1 and 3 supported]\n");
- break;
- case 4:
- printf(" [protection type 3 supported]\n");
- break;
- case 5:
- printf(" [protection types 2 and 3 supported]\n");
- break;
- case 6:
- printf(" [see Supported block lengths and protection types "
- "VPD page]\n");
- break;
- case 7:
- printf(" [protection types 1, 2 and 3 supported]\n");
- break;
- }
- } else
- printf("\n");
- printf(" GRD_CHK=%d\n", !!(b[4] & 0x4));
- printf(" APP_CHK=%d\n", !!(b[4] & 0x2));
- printf(" REF_CHK=%d\n", !!(b[4] & 0x1));
- printf(" UASK_SUP=%d\n", !!(b[5] & 0x20));
- printf(" GROUP_SUP=%d\n", !!(b[5] & 0x10));
- printf(" PRIOR_SUP=%d\n", !!(b[5] & 0x8));
- printf(" HEADSUP=%d\n", !!(b[5] & 0x4));
- printf(" ORDSUP=%d\n", !!(b[5] & 0x2));
- printf(" SIMPSUP=%d\n", !!(b[5] & 0x1));
- printf(" WU_SUP=%d\n", !!(b[6] & 0x8));
- printf(" CRD_SUP=%d\n", !!(b[6] & 0x4));
- printf(" NV_SUP=%d\n", !!(b[6] & 0x2));
- printf(" V_SUP=%d\n", !!(b[6] & 0x1));
- printf(" NO_PI_CHK=%d\n", !!(b[7] & 0x10)); /* spc5r02 */
- printf(" P_I_I_SUP=%d\n", !!(b[7] & 0x10));
- printf(" LUICLR=%d\n", !!(b[7] & 0x1));
- printf(" LU_COLL_TYPE=%d\n", (b[8] >> 5) & 0x7); /* spc5r09 */
- printf(" R_SUP=%d\n", !!(b[8] & 0x10));
- printf(" RTD_SUP=%d\n", !!(b[8] & 0x8)); /* spc5r11 */
- printf(" HSSRELEF=%d\n", !!(b[8] & 0x2)); /* spc5r02 */
- printf(" CBCS=%d\n", !!(b[8] & 0x1)); /* obsolete in spc5r01 */
- printf(" Multi I_T nexus microcode download=%d\n", b[9] & 0xf);
- printf(" Extended self-test completion minutes=%d\n",
- sg_get_unaligned_be16(b + 10));
- printf(" POA_SUP=%d\n", !!(b[12] & 0x80)); /* spc4r32 */
- printf(" HRA_SUP=%d\n", !!(b[12] & 0x40)); /* spc4r32 */
- printf(" VSA_SUP=%d\n", !!(b[12] & 0x20)); /* spc4r32 */
- printf(" DMS_VALID=%d\n", !!(b[12] & 0x10)); /* spc5r20 */
- printf(" Maximum supported sense data length=%d\n",
- b[13]); /* spc4r34 */
- printf(" IBS=%d\n", !!(b[14] & 0x80)); /* spc5r09 */
- printf(" IAS=%d\n", !!(b[14] & 0x40)); /* spc5r09 */
- printf(" SAC=%d\n", !!(b[14] & 0x4)); /* spc5r09 */
- printf(" NRD1=%d\n", !!(b[14] & 0x2)); /* spc5r09 */
- printf(" NRD0=%d\n", !!(b[14] & 0x1)); /* spc5r09 */
- printf(" Maximum inquiry change logs=%u\n",
- sg_get_unaligned_be16(b + 15)); /* spc5r17 */
- printf(" Maximum mode page change logs=%u\n",
- sg_get_unaligned_be16(b + 17)); /* spc5r17 */
- printf(" DM_MD_4=%d\n", !!(b[19] & 0x80)); /* spc5r20 */
- printf(" DM_MD_5=%d\n", !!(b[19] & 0x40)); /* spc5r20 */
- printf(" DM_MD_6=%d\n", !!(b[19] & 0x20)); /* spc5r20 */
- printf(" DM_MD_7=%d\n", !!(b[19] & 0x10)); /* spc5r20 */
- printf(" DM_MD_D=%d\n", !!(b[19] & 0x8)); /* spc5r20 */
- printf(" DM_MD_E=%d\n", !!(b[19] & 0x4)); /* spc5r20 */
- printf(" DM_MD_F=%d\n", !!(b[19] & 0x2)); /* spc5r20 */
- return;
- }
- printf(" ACTIVATE_MICROCODE=%d SPT=%d GRD_CHK=%d APP_CHK=%d "
- "REF_CHK=%d\n", ((b[4] >> 6) & 0x3), ((b[4] >> 3) & 0x7),
- !!(b[4] & 0x4), !!(b[4] & 0x2), !!(b[4] & 0x1));
- printf(" UASK_SUP=%d GROUP_SUP=%d PRIOR_SUP=%d HEADSUP=%d ORDSUP=%d "
- "SIMPSUP=%d\n", !!(b[5] & 0x20), !!(b[5] & 0x10), !!(b[5] & 0x8),
- !!(b[5] & 0x4), !!(b[5] & 0x2), !!(b[5] & 0x1));
- printf(" WU_SUP=%d [CRD_SUP=%d] NV_SUP=%d V_SUP=%d\n",
- !!(b[6] & 0x8), !!(b[6] & 0x4), !!(b[6] & 0x2), !!(b[6] & 0x1));
- printf(" NO_PI_CHK=%d P_I_I_SUP=%d LUICLR=%d\n", !!(b[7] & 0x20),
- !!(b[7] & 0x10), !!(b[7] & 0x1));
- /* RTD_SUP added in spc5r11, LU_COLL_TYPE added in spc5r09,
- * HSSRELEF added in spc5r02; CBCS obsolete in spc5r01 */
- printf(" LU_COLL_TYPE=%d R_SUP=%d RTD_SUP=%d HSSRELEF=%d [CBCS=%d]\n",
- (b[8] >> 5) & 0x7, !!(b[8] & 0x10), !!(b[8] & 0x8),
- !!(b[8] & 0x2), !!(b[8] & 0x1));
- printf(" Multi I_T nexus microcode download=%d\n", b[9] & 0xf);
- printf(" Extended self-test completion minutes=%d\n",
- sg_get_unaligned_be16(b + 10)); /* spc4r27 */
- printf(" POA_SUP=%d HRA_SUP=%d VSA_SUP=%d DMS_VALID=%d\n",
- !!(b[12] & 0x80), !!(b[12] & 0x40), !!(b[12] & 0x20),
- !!(b[12] & 0x10)); /* spc5r20 */
- printf(" Maximum supported sense data length=%d\n", b[13]); /* spc4r34 */
- printf(" IBS=%d IAS=%d SAC=%d NRD1=%d NRD0=%d\n", !!(b[14] & 0x80),
- !!(b[14] & 0x40), !!(b[14] & 0x4), !!(b[14] & 0x2),
- !!(b[14] & 0x1)); /* added in spc5r09 */
- printf(" Maximum inquiry change logs=%u\n",
- sg_get_unaligned_be16(b + 15)); /* spc5r17 */
- printf(" Maximum mode page change logs=%u\n",
- sg_get_unaligned_be16(b + 17)); /* spc5r17 */
- printf(" DM_MD_4=%d DM_MD_5=%d DM_MD_6=%d DM_MD_7=%d\n",
- !!(b[19] & 0x80), !!(b[19] & 0x40), !!(b[19] & 0x20),
- !!(b[19] & 0x10)); /* spc5r20 */
- printf(" DM_MD_D=%d DM_MD_E=%d DM_MD_F=%d\n",
- !!(b[19] & 0x8), !!(b[19] & 0x4), !!(b[19] & 0x2));
-}
-
-/* VPD_SOFTW_INF_ID */
-static void
-decode_softw_inf_id(uint8_t * buff, int len, struct opts_t * op,
- sgj_opaque_p jap)
+decode_ata_info_vpd(const uint8_t * buff, int len, struct opts_t * op,
+ sgj_opaque_p jop)
{
+ bool do_long_nq = op->do_long && (! op->do_quiet);
+ int num, is_be, cc, n;
sgj_state * jsp = &op->json_st;
- sgj_opaque_p jop;
- uint64_t ieee_id;
-
- if (op->do_hex) {
- hex2stdout(buff, len, (1 == op->do_hex) ? 0 : -1);
- return;
- }
- len -= 4;
- buff += 4;
- for ( ; len > 5; len -= 6, buff += 6) {
- 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);
- }
- }
-}
-
-/* VPD_ATA_INFO */
-static void
-decode_ata_info_vpd(uint8_t * buff, int len, int do_long, int do_hex)
-{
- char b[80];
- int num, is_be, cc;
const char * cp;
const char * ata_transp;
+ char b[144];
+ char d[80];
+ static const int blen = sizeof(b);
+ static const int dlen = sizeof(d);
+ static const char * sat_vip = "SAT Vendor identification";
+ static const char * sat_pip = "SAT Product identification";
+ static const char * sat_prlp = "SAT Product revision level";
if (len < 36) {
pr2serr("ATA information VPD page length too short=%d\n", len);
return;
}
- if (do_hex && (2 != do_hex)) {
- hex2stdout(buff, len, (1 == do_hex) ? 0 : -1);
+ if (op->do_hex && (2 != op->do_hex)) {
+ hex2stdout(buff, len, (1 == op->do_hex) ? 0 : -1);
return;
}
memcpy(b, buff + 8, 8);
b[8] = '\0';
- printf(" SAT Vendor identification: %s\n", b);
+ sgj_pr_hr(jsp, " %s: %s\n", sat_vip, b);
memcpy(b, buff + 16, 16);
b[16] = '\0';
- printf(" SAT Product identification: %s\n", b);
+ sgj_pr_hr(jsp, " %s: %s\n", sat_pip, b);
memcpy(b, buff + 32, 4);
b[4] = '\0';
- printf(" SAT Product revision level: %s\n", b);
+ sgj_pr_hr(jsp, " %s: %s\n", sat_prlp, b);
if (len < 56)
return;
ata_transp = (0x34 == buff[36]) ? "SATA" : "PATA";
- if (do_long) {
- printf(" Device signature [%s] (in hex):\n", ata_transp);
+ if (do_long_nq) {
+ sgj_pr_hr(jsp, " Device signature [%s] (in hex):\n", ata_transp);
hex2stdout(buff + 36, 20, 0);
} else
- printf(" Device signature indicates %s transport\n", ata_transp);
+ sgj_pr_hr(jsp, " Device signature indicates %s transport\n",
+ ata_transp);
cc = buff[56]; /* 0xec for IDENTIFY DEVICE and 0xa1 for IDENTIFY
* PACKET DEVICE (obsolete) */
- printf(" Command code: 0x%x\n", cc);
+ n = snprintf(b, blen, " Command code: 0x%x\n", cc);
if (len < 60)
return;
if (0xec == cc)
@@ -1360,62 +1020,47 @@ decode_ata_info_vpd(uint8_t * buff, int len, int do_long, int do_hex)
cp = NULL;
is_be = sg_is_big_endian();
if (cp) {
- printf(" ATA command IDENTIFY %sDEVICE response summary:\n", cp);
+ n += sg_scnpr(b + n, blen - n, " ATA command IDENTIFY %sDEVICE "
+ "response summary:\n", cp);
num = sg_ata_get_chars((const unsigned short *)(buff + 60), 27, 20,
- is_be, b);
- b[num] = '\0';
- printf(" model: %s\n", b);
+ is_be, d);
+ d[num] = '\0';
+ n += sg_scnpr(b + n, blen - n, " model: %s\n", d);
num = sg_ata_get_chars((const unsigned short *)(buff + 60), 10, 10,
- is_be, b);
- b[num] = '\0';
- printf(" serial number: %s\n", b);
+ is_be, d);
+ d[num] = '\0';
+ n += sg_scnpr(b + n, blen - n, " serial number: %s\n", d);
num = sg_ata_get_chars((const unsigned short *)(buff + 60), 23, 4,
- is_be, b);
- b[num] = '\0';
- printf(" firmware revision: %s\n", b);
- if (do_long)
- printf(" ATA command IDENTIFY %sDEVICE response in hex:\n", cp);
- } else if (do_long)
- printf(" ATA command 0x%x got following response:\n",
- (unsigned int)cc);
+ is_be, d);
+ d[num] = '\0';
+ n += sg_scnpr(b + n, blen - n, " firmware revision: %s\n", d);
+ sgj_pr_hr(jsp, "%s", b);
+ if (do_long_nq)
+ sgj_pr_hr(jsp, " ATA command IDENTIFY %sDEVICE response in "
+ "hex:\n", cp);
+ } else if (do_long_nq)
+ sgj_pr_hr(jsp, " ATA command 0x%x got following response:\n",
+ (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_convert_to_snake_name(sat_pip, d, dlen);
+ sgj_add_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");
+ }
if (len < 572)
return;
- if (2 == do_hex)
+ if (2 == op->do_hex)
hex2stdout((buff + 60), 512, 0);
- else if (do_long)
+ else if (do_long_nq)
dWordHex((const unsigned short *)(buff + 60), 256, 0, is_be);
}
-
-/* VPD_POWER_CONDITION 0x8a */
-static void
-decode_power_condition(uint8_t * buff, int len, int do_hex)
-{
- if (len < 18) {
- pr2serr("Power condition VPD page length too short=%d\n", len);
- return;
- }
- if (do_hex) {
- hex2stdout(buff, len, (1 == do_hex) ? 0 : -1);
- return;
- }
- printf(" Standby_y=%d Standby_z=%d Idle_c=%d Idle_b=%d Idle_a=%d\n",
- !!(buff[4] & 0x2), !!(buff[4] & 0x1),
- !!(buff[5] & 0x4), !!(buff[5] & 0x2), !!(buff[5] & 0x1));
- printf(" Stopped condition recovery time (ms) %d\n",
- sg_get_unaligned_be16(buff + 6));
- printf(" Standby_z condition recovery time (ms) %d\n",
- sg_get_unaligned_be16(buff + 8));
- printf(" Standby_y condition recovery time (ms) %d\n",
- sg_get_unaligned_be16(buff + 10));
- printf(" Idle_a condition recovery time (ms) %d\n",
- sg_get_unaligned_be16(buff + 12));
- printf(" Idle_b condition recovery time (ms) %d\n",
- sg_get_unaligned_be16(buff + 14));
- printf(" Idle_c condition recovery time (ms) %d\n",
- sg_get_unaligned_be16(buff + 16));
-}
-
static const char * constituent_type_arr[] = {
"Reserved",
"Virtual tape library",
@@ -3076,14 +2721,14 @@ svpd_decode_t10(int sg_fd, struct opts_t * op, sgj_opaque_p jop,
return 0;
}
break;
- case VPD_SUPPORTED_VPDS: /* 0x0 */
- np = "Supported VPD pages VPD page:";
+ case VPD_SUPPORTED_VPDS: /* 0x0 ["sv"] */
+ np = "Supported VPD pages";
if (allow_name)
- sgj_pr_hr(jsp, "%s%s\n", pre, np);
+ sgj_pr_hr(jsp, "%s%s %s:\n", pre, np, vpd_p_s);
res = vpd_fetch_page(sg_fd, rp, pn, op->maxlen, qt, vb, &len);
if (0 == res) {
if (! allow_name && allow_if_found)
- sgj_pr_hr(jsp, "%s%s\n", pre, np);
+ sgj_pr_hr(jsp, "%s%s %s:\n", pre, np, vpd_p_s);
if (op->do_raw)
dStrRaw(rp, len);
else if (op->do_hex)
@@ -3096,12 +2741,7 @@ svpd_decode_t10(int sg_fd, struct opts_t * op, sgj_opaque_p jop,
if (num > (len - 4))
num = (len - 4);
if (as_json) {
- jo2p = sgj_new_snake_named_object(jsp, jop, np);
- 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);
+ jo2p = sg_vpd_js_hdr(jsp, jop, np, rp);
jap = sgj_new_named_array(jsp, jo2p,
"supported_vpd_page_list");
}
@@ -3147,14 +2787,14 @@ svpd_decode_t10(int sg_fd, struct opts_t * op, sgj_opaque_p jop,
return 0;
}
break;
- case VPD_UNIT_SERIAL_NUM: /* 0x80 */
- np = "Unit serial number VPD page:";
+ case VPD_UNIT_SERIAL_NUM: /* 0x80 ["sn"] */
+ np = "Unit serial number";
if (allow_name && not_json)
- sgj_pr_hr(jsp, "%s%s\n", pre, np);
+ sgj_pr_hr(jsp, "%s%s VPD page:\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)
- sgj_pr_hr(jsp, "%s%s\n", pre, np);
+ sgj_pr_hr(jsp, "%s%s %s:\n", pre, np, vpd_p_s);
if (op->do_raw)
dStrRaw(rp, len);
else if (op->do_hex)
@@ -3168,26 +2808,21 @@ svpd_decode_t10(int sg_fd, struct opts_t * op, sgj_opaque_p jop,
if (len >= (int)sizeof(obuff))
len = sizeof(obuff) - 1;
memcpy(obuff, rp + 4, len);
- jo2p = sgj_new_snake_named_object(jsp, jop, np);
- 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_pr_hr_js_vs(jsp, jo2p, 2, "unit_serial_number",
- SGJ_SEP_COLON_1_SPACE, obuff);
+ jo2p = sg_vpd_js_hdr(jsp, jop, np, rp);
+ sgj_pr_hr_js_vs(jsp, jo2p, 2, np, SGJ_SEP_COLON_1_SPACE,
+ obuff);
}
return 0;
}
break;
- case VPD_DEVICE_ID: /* 0x83 */
- np = "Device Identification VPD page:";
+ case VPD_DEVICE_ID: /* 0x83 ["di, di_asis, di_lu, di_port, di_target"] */
+ np = "Device Identification";
if (allow_name)
- sgj_pr_hr(jsp, "%s%s\n", pre, np);
+ sgj_pr_hr(jsp, "%s%s %s:\n", pre, np, vpd_p_s);
res = vpd_fetch_page(sg_fd, rp, pn, op->maxlen, qt, vb, &len);
if (0 == res) {
if (! allow_name && allow_if_found)
- sgj_pr_hr(jsp, "%s%s\n", pre, np);
+ sgj_pr_hr(jsp, "%s%s %s:\n", pre, np, vpd_p_s);
if (op->do_raw)
dStrRaw(rp, len);
else if (op->do_hex)
@@ -3197,12 +2832,7 @@ svpd_decode_t10(int sg_fd, struct opts_t * op, sgj_opaque_p jop,
sgj_pr_hr(jsp, " [PQual=%d Peripheral device type: "
"%s]\n", pqual, pdt_str);
if (as_json) {
- jo2p = sgj_new_snake_named_object(jsp, jop, np);
- 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);
+ jo2p = sg_vpd_js_hdr(jsp, jop, np, rp);
jap = sgj_new_named_array(jsp, jo2p,
"designation_descriptor_list");
}
@@ -3211,14 +2841,14 @@ svpd_decode_t10(int sg_fd, struct opts_t * op, sgj_opaque_p jop,
return 0;
}
break;
- case VPD_SOFTW_INF_ID: /* 0x84 */
- np = "Software interface identification VPD page:";
+ case VPD_SOFTW_INF_ID: /* 0x84 ["sii"] */
+ np = "Software interface identification";
if (allow_name)
- sgj_pr_hr(jsp, "%s%s\n", pre, np);
+ sgj_pr_hr(jsp, "%s%s %s:\n", pre, np, vpd_p_s);
res = vpd_fetch_page(sg_fd, rp, pn, op->maxlen, qt, vb, &len);
if (0 == res) {
if (! allow_name && allow_if_found)
- sgj_pr_hr(jsp, "%s%s\n", pre, np);
+ sgj_pr_hr(jsp, "%s%s %s:\n", pre, np, vpd_p_s);
if (op->do_raw)
dStrRaw(rp, len);
else {
@@ -3226,12 +2856,7 @@ svpd_decode_t10(int sg_fd, struct opts_t * op, sgj_opaque_p jop,
sgj_pr_hr(jsp, " [PQual=%d Peripheral device type: "
"%s]\n", pqual, pdt_str);
if (as_json) {
- jo2p = sgj_new_snake_named_object(jsp, jop, np);
- 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);
+ jo2p = sg_vpd_js_hdr(jsp, jop, np, rp);
jap = sgj_new_named_array(jsp, jo2p,
"software_interface_identifier_list");
}
@@ -3240,24 +2865,19 @@ svpd_decode_t10(int sg_fd, struct opts_t * op, sgj_opaque_p jop,
return 0;
}
break;
- case VPD_MAN_NET_ADDR: /* 0x85 */
- np= "Management network addresses VPD page:";
+ case VPD_MAN_NET_ADDR: /* 0x85 ["mna"] */
+ np= "Management network addresses";
if (allow_name)
- sgj_pr_hr(jsp, "%s%s\n", pre, np);
+ sgj_pr_hr(jsp, "%s%s %s:\n", pre, np, vpd_p_s);
res = vpd_fetch_page(sg_fd, rp, pn, op->maxlen, qt, vb, &len);
if (0 == res) {
if (! allow_name && allow_if_found)
- sgj_pr_hr(jsp, "%s%s\n", pre, np);
+ sgj_pr_hr(jsp, "%s%s %s:\n", pre, np, vpd_p_s);
if (op->do_raw)
dStrRaw(rp, len);
else {
if (as_json) {
- jo2p = sgj_new_snake_named_object(jsp, jop, np);
- 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);
+ jo2p = sg_vpd_js_hdr(jsp, jop, np, rp);
jap = sgj_new_named_array(jsp, jo2p,
"network_services_descriptor_list");
}
@@ -3266,14 +2886,14 @@ svpd_decode_t10(int sg_fd, struct opts_t * op, sgj_opaque_p jop,
return 0;
}
break;
- case VPD_EXT_INQ: /* 0x86 */
- np = "extended INQUIRY data VPD page:";
+ case VPD_EXT_INQ: /* 0x86 ["ei"] */
+ np = "extended INQUIRY data";
if (allow_name)
- printf("%s%s\n", pre, np);
+ sgj_pr_hr(jsp, "%s%s %s:\n", pre, np, vpd_p_s);
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 %s:\n", pre, np, vpd_p_s);
if (op->do_raw)
dStrRaw(rp, len);
else {
@@ -3290,40 +2910,48 @@ svpd_decode_t10(int sg_fd, struct opts_t * op, sgj_opaque_p jop,
protect = !!(sir.byte_5 & 0x1); /* SPC-3 and later */
}
if (vb || long_notquiet)
- printf(" [PQual=%d Peripheral device type: %s]\n",
- pqual, pdt_str);
- decode_x_inq_vpd(rp, len, op->do_hex, long_notquiet, protect);
+ 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);
+ decode_x_inq_vpd(rp, len, protect, op, jo2p);
}
return 0;
}
break;
case VPD_MODE_PG_POLICY: /* 0x87 */
- np = "Mode page policy VPD page:";
+ np = "Mode page policy";
if (allow_name)
- printf("%s%s\n", pre, np);
+ sgj_pr_hr(jsp, "%s%s %s:\n", pre, np, vpd_p_s);
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", (prefix ? prefix : ""), np);
+ sgj_pr_hr(jsp, "%s%s %s:\n", (prefix ? prefix : ""), np,
+ vpd_p_s);
if (op->do_raw)
dStrRaw(rp, len);
else {
if (vb || long_notquiet)
- printf(" [PQual=%d Peripheral device type: %s]\n",
- pqual, pdt_str);
- decode_mode_policy_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_new_named_array(jsp, jo2p,
+ "mode_page_policy_descriptor_list");
+ }
+ decode_mode_policy_vpd(rp, len, op, jap);
}
return 0;
}
break;
- case VPD_SCSI_PORTS: /* 0x88 */
- np = "SCSI Ports VPD page:";
+ case VPD_SCSI_PORTS: /* 0x88 ["sp"] */
+ np = "SCSI Ports";
if (allow_name)
- sgj_pr_hr(jsp, "%s%s\n", pre, np);
+ sgj_pr_hr(jsp, "%s%s %s:\n", pre, np, vpd_p_s);
res = vpd_fetch_page(sg_fd, rp, pn, op->maxlen, qt, vb, &len);
if (0 == res) {
if (! allow_name && allow_if_found)
- sgj_pr_hr(jsp, "%s%s\n", pre, np);
+ sgj_pr_hr(jsp, "%s%s %s:\n", pre, np, vpd_p_s);
if (op->do_raw)
dStrRaw(rp, len);
else {
@@ -3331,29 +2959,25 @@ svpd_decode_t10(int sg_fd, struct opts_t * op, sgj_opaque_p jop,
sgj_pr_hr(jsp, " [PQual=%d Peripheral device type: "
"%s]\n", pqual, pdt_str);
if (as_json) {
- jo2p = sgj_new_snake_named_object(jsp, jop, np);
- 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);
+ jo2p = sg_vpd_js_hdr(jsp, jop, np, rp);
jap = sgj_new_named_array(jsp, jo2p,
- "scsi_port_descriptor_list");
+ "scsi_ports_descriptor_list");
}
decode_scsi_ports_vpd(rp, len, op, jap);
}
return 0;
}
break;
- case VPD_ATA_INFO: /* 0x89 */
- np = "ATA information VPD page:";
+ case VPD_ATA_INFO: /* 0x89 ['ai"] */
+ np = "ATA information";
if (allow_name)
- printf("%s%s\n", pre, np);
+ sgj_pr_hr(jsp, "%s%s %s:\n", pre, np, vpd_p_s);
alloc_len = op->maxlen ? op->maxlen : VPD_ATA_INFO_LEN;
res = vpd_fetch_page(sg_fd, rp, pn, alloc_len, qt, vb, &len);
if (0 == res) {
if (! allow_name && allow_if_found)
- printf("%s%s\n", (prefix ? prefix : ""), np);
+ sgj_pr_hr(jsp, "%s%s %s:\n", (prefix ? prefix : ""), np,
+ vpd_p_s);
if ((2 == op->do_raw) || (3 == op->do_hex)) { /* for hdparm */
if (len < (60 + 512))
pr2serr("ATA_INFO VPD page len (%d) less than expected "
@@ -3366,28 +2990,30 @@ svpd_decode_t10(int sg_fd, struct opts_t * op, sgj_opaque_p jop,
dStrRaw(rp, len);
else {
if (vb || long_notquiet)
- printf(" [PQual=%d Peripheral device type: %s]\n",
- pqual, pdt_str);
- decode_ata_info_vpd(rp, len, long_notquiet, 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);
+ decode_ata_info_vpd(rp, len, op, jo2p);
}
return 0;
}
break;
- case VPD_POWER_CONDITION: /* 0x8a */
+ case VPD_POWER_CONDITION: /* 0x8a ["pc"\ */
np = "Power condition 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_condition(rp, len, op->do_hex);
+ sgj_pr_hr(jsp, " [PQual=%d Peripheral device type: "
+ "%s]\n", pqual, pdt_str);
+ decode_power_condition(rp, len, op, jop);
}
return 0;
}
@@ -3996,6 +3622,7 @@ main(int argc, char * argv[])
struct opts_t opts = {0};
struct opts_t * op = &opts;
+ op->invoker = SG_VPD_INV_SG_VPD;
dup_sanity_chk((int)sizeof(opts), (int)sizeof(*vnp));
op->vend_prod_num = -1;
while (1) {
@@ -4189,8 +3816,8 @@ main(int argc, char * argv[])
return 0;
}
- as_json = op->json_st.pr_as_json;
jsp = &op->json_st;
+ as_json = jsp->pr_as_json;
if (as_json)
jop = sgj_start(MY_NAME, version_str, argc, argv, jsp);