aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDouglas Gilbert <dgilbert@interlog.com>2022-09-18 02:14:13 +0000
committerDouglas Gilbert <dgilbert@interlog.com>2022-09-18 02:14:13 +0000
commitccefa8190c1f38cb71384bcdd786599db7de570a (patch)
treea4f0c0db16e15ce55ed98460635040b755a26cf3
parenteda37108f2a83c7944b1c0f63162647eddc9960d (diff)
downloadsg3_utils-ccefa8190c1f38cb71384bcdd786599db7de570a.tar.gz
sg_inq+sg_vpd: ongoing JSON updates
Probably at the end of the JSON work for sg_inq since it only has four vendor specific VPD pages. sg_vpd has a lot more vendor specific VPD pages which are yet to be 'jsonified'. git-svn-id: https://svn.bingwo.ca/repos/sg3_utils/trunk@971 6180dd3e-e324-4e3e-922d-17de1ae2f315
-rw-r--r--ChangeLog2
-rw-r--r--src/Makefile.am2
-rw-r--r--src/Makefile.in4
-rw-r--r--src/sg_inq.c218
-rw-r--r--src/sg_sat_read_gplog.c4
-rw-r--r--src/sg_vpd.c23
-rw-r--r--src/sg_vpd_common.c512
-rw-r--r--src/sg_vpd_common.h12
-rw-r--r--src/sg_vpd_vendor.c227
-rw-r--r--testing/sg_mrq_dd.cpp8
-rw-r--r--testing/sgh_dd.cpp10
-rw-r--r--utils/Makefile2
12 files changed, 589 insertions, 435 deletions
diff --git a/ChangeLog b/ChangeLog
index c22493a6..00fb98d1 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -2,7 +2,7 @@ Each utility has its own version number, date of last change and
some description at the top of its ".c" file. All utilities in the main
directory have their own "man" pages. There is also a sg3_utils man page.
-Changelog for pre-release sg3_utils-1.48 [20220904] [svn: r970]
+Changelog for pre-release sg3_utils-1.48 [20220917] [svn: r971]
- some utilities: add experimental --json[=JO] option
- sg_z_act_query: new utility for sending either a
Zone activate or Zone query command
diff --git a/src/Makefile.am b/src/Makefile.am
index f75bc7cb..95144625 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -93,7 +93,7 @@ sg_ident_LDADD = ../lib/libsgutils2.la
sginfo_LDADD = ../lib/libsgutils2.la
-sg_inq_SOURCES = sg_inq.c sg_inq_data.c sg_vpd_vendor.c sg_vpd_common.c
+sg_inq_SOURCES = sg_inq.c sg_inq_data.c sg_vpd_common.c
sg_inq_LDADD = ../lib/libsgutils2.la
sg_logs_LDADD = ../lib/libsgutils2.la
diff --git a/src/Makefile.in b/src/Makefile.in
index c5217b1e..96880766 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -188,7 +188,7 @@ sg_ident_SOURCES = sg_ident.c
sg_ident_OBJECTS = sg_ident.$(OBJEXT)
sg_ident_DEPENDENCIES = ../lib/libsgutils2.la
am_sg_inq_OBJECTS = sg_inq.$(OBJEXT) sg_inq_data.$(OBJEXT) \
- sg_vpd_vendor.$(OBJEXT) sg_vpd_common.$(OBJEXT)
+ sg_vpd_common.$(OBJEXT)
sg_inq_OBJECTS = $(am_sg_inq_OBJECTS)
sg_inq_DEPENDENCIES = ../lib/libsgutils2.la
sg_logs_SOURCES = sg_logs.c
@@ -682,7 +682,7 @@ sg_get_elem_status_LDADD = ../lib/libsgutils2.la
sg_get_lba_status_LDADD = ../lib/libsgutils2.la
sg_ident_LDADD = ../lib/libsgutils2.la
sginfo_LDADD = ../lib/libsgutils2.la
-sg_inq_SOURCES = sg_inq.c sg_inq_data.c sg_vpd_vendor.c sg_vpd_common.c
+sg_inq_SOURCES = sg_inq.c sg_inq_data.c sg_vpd_common.c
sg_inq_LDADD = ../lib/libsgutils2.la
sg_logs_LDADD = ../lib/libsgutils2.la
sg_luns_LDADD = ../lib/libsgutils2.la
diff --git a/src/sg_inq.c b/src/sg_inq.c
index edd571c7..8a9b43e2 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.30 20220904"; /* spc6r06, sbc5r03 */
+static const char * version_str = "2.31 20220915"; /* spc6r06, sbc5r03 */
#define MY_NAME "sg_inq"
@@ -1122,17 +1122,6 @@ svpd_inhex_decode_all(struct opts_t * op, sgj_opaque_p jop)
return res;
}
-static int
-no_ascii_4hex(const struct opts_t * op)
-{
- if (op->do_hex < 2)
- return 1;
- else if (2 == op->do_hex)
- return 0;
- else
- return -1;
-}
-
static void
decode_supported_vpd_4inq(uint8_t * buff, int len, struct opts_t * op,
sgj_opaque_p jap)
@@ -2089,185 +2078,7 @@ decode_b3_vpd(uint8_t * buff, int len, struct opts_t * op, sgj_opaque_p jop)
}
}
-static const char * lun_state_arr[] =
-{
- "LUN not bound or LUN_Z report",
- "LUN bound, but not owned by this SP",
- "LUN bound and owned by this SP",
-};
-
-static const char * ip_mgmt_arr[] =
-{
- "No IP access",
- "Reserved (undefined)",
- "via IPv4",
- "via IPv6",
-};
-
-static const char * sp_arr[] =
-{
- "SP A",
- "SP B",
-};
-
-static const char * lun_op_arr[] =
-{
- "Normal operations",
- "I/O Operations being rejected, SP reboot or NDU in progress",
-};
-
-static const char * failover_mode_arr[] =
-{
- "Legacy mode 0",
- "Unknown mode (1)",
- "Unknown mode (2)",
- "Unknown mode (3)",
- "Active/Passive (PNR) mode 1",
- "Unknown mode (5)",
- "Active/Active (ALUA) mode 4",
- "Unknown mode (7)",
- "Legacy mode 2",
- "Unknown mode (9)",
- "Unknown mode (10)",
- "Unknown mode (11)",
- "Unknown mode (12)",
- "Unknown mode (13)",
- "AIX Active/Passive (PAR) mode 3",
- "Unknown mode (15)",
-};
-
-static void
-decode_upr_vpd_c0_emc(uint8_t * buff, int len, struct opts_t * op,
- sgj_opaque_p jop)
-{
- uint8_t uc;
- int k, n, ip_mgmt, vpp80, lun_z;
- sgj_state * jsp = &op->json_st;
- const char * cp;
- char b[256];
- static const int blen = sizeof(b);
-
- if (len < 3) {
- pr2serr("EMC upr VPD page [0xc0]: length too short=%d\n", len);
- return;
- }
- if (op->do_hex) {
- hex2stdout(buff, len, no_ascii_4hex(op));
- return;
- }
- if (buff[9] != 0x00) {
- pr2serr("Unsupported page revision %d, decoding not possible.\n",
- buff[9]);
- return;
- }
- for (k = 0, n = 0; k < 16; ++k)
- n += sg_scnpr(b + n, blen - n, "%02x", buff[10 + k]);
- sgj_haj_vs(jsp, jop, 2, "LUN WWN", SGJ_SEP_COLON_1_SPACE, b);
- snprintf(b, blen, "%.*s", buff[49], buff + 50);
- sgj_haj_vs(jsp, jop, 2, "Array Serial Number", SGJ_SEP_COLON_1_SPACE, b);
-
- if (buff[4] > 0x02)
- snprintf(b, blen, "Unknown (%x)", buff[4]);
- else
- snprintf(b, blen, "%s", lun_state_arr[buff[4]]);
- sgj_haj_vistr(jsp, jop, 2, "LUN State", SGJ_SEP_COLON_1_SPACE,
- buff[4], true, b);
-
- uc = buff[8];
- n = 0;
- if (uc > 0x01)
- n += sg_scnpr(b + n, blen - n, "Unknown SP (%x)", uc);
- else
- n += sg_scnpr(b + n, blen - n, "%s", sp_arr[uc]);
- sgj_js_nv_ihexstr(jsp, jop, "path_connects_to", uc, NULL, b);
- n += sg_scnpr(b + n, blen - n, ", Port Number: %u", buff[7]);
- sgj_pr_hr(jsp, " This path connects to: %s\n", b);
- sgj_js_nv_ihex(jsp, jop, "port_number", buff[7]);
-
- if (buff[5] > 0x01)
- snprintf(b, blen, "Unknown (%x)\n", buff[5]);
- else
- snprintf(b, blen, "%s\n", sp_arr[buff[5]]);
- sgj_haj_vistr(jsp, jop, 2, "Default owner", SGJ_SEP_COLON_1_SPACE,
- buff[5], true, b);
-
- cp = (buff[6] & 0x40) ? "supported" : "not supported";
- sgj_pr_hr(jsp, " NO_ATF: %s, Access Logix: %s\n",
- buff[6] & 0x80 ? "set" : "not set", cp);
- sgj_js_nv_i(jsp, jop, "no_atf", !! (buff[6] & 0x80));
- sgj_js_nv_istr(jsp, jop, "access_logix", !! (buff[6] & 0x40),
- NULL, cp);
-
- ip_mgmt = (buff[6] >> 4) & 0x3;
- cp = ip_mgmt_arr[ip_mgmt];
- sgj_pr_hr(jsp, " SP IP Management Mode: %s\n", cp);
- sgj_js_nv_istr(jsp, jop, "sp_ip_management_mode", !! ip_mgmt,
- NULL, cp);
- if (ip_mgmt == 2) {
- snprintf(b, blen, "%u.%u.%u.%u", buff[44], buff[45], buff[46],
- buff[47]);
- sgj_pr_hr(jsp, " SP IPv4 address: %s\n", b);
- sgj_js_nv_s(jsp, jop, "sp_ipv4_address", b);
- } else if (ip_mgmt == 3) {
- printf(" SP IPv6 address: ");
- n = 0;
- for (k = 0; k < 16; ++k)
- n += sg_scnpr(b + n, blen - n, "%02x", buff[32 + k]);
- sgj_pr_hr(jsp, " SP IPv6 address: %s\n", b);
- sgj_js_nv_hex_bytes(jsp, jop, "sp_ipv6_address", buff + 32, 16);
- }
-
-// yyyyyyy more conversion work needed below this point
- vpp80 = buff[30] & 0x08;
- lun_z = buff[30] & 0x04;
-
- printf(" System Type: %x, Failover mode: %s\n",
- buff[27], failover_mode_arr[buff[28] & 0x0f]);
-
- printf(" Inquiry VPP 0x80 returns: %s, Arraycommpath: %s\n",
- vpp80 ? "array serial#" : "LUN serial#",
- lun_z ? "Set to 1" : "Unknown");
-
- printf(" Lun operations: %s\n",
- buff[48] > 1 ? "undefined" : lun_op_arr[buff[48]]);
-
- return;
-}
-
-static void
-decode_rdac_vpd_c2(uint8_t * buff, int len, struct opts_t * op)
-{
- if (len < 3) {
- pr2serr("Software Version VPD page length too short=%d\n", len);
- return;
- }
- if (op->do_hex) {
- hex2stdout(buff, len, no_ascii_4hex(op));
- return;
- }
- if (buff[4] != 's' && buff[5] != 'w' && buff[6] != 'r') {
- pr2serr("Invalid page identifier %c%c%c%c, decoding "
- "not possible.\n" , buff[4], buff[5], buff[6], buff[7]);
- return;
- }
- printf(" Software Version: %02x.%02x.%02x\n", buff[8], buff[9], buff[10]);
- printf(" Software Date: %02d/%02d/%02d\n", buff[11], buff[12], buff[13]);
- printf(" Features:");
- if (buff[14] & 0x01)
- printf(" Dual Active,");
- if (buff[14] & 0x02)
- printf(" Series 3,");
- if (buff[14] & 0x04)
- printf(" Multiple Sub-enclosures,");
- if (buff[14] & 0x08)
- printf(" DCE/DRM/DSS/DVE,");
- if (buff[14] & 0x10)
- printf(" Asymmetric Logical Unit Access,");
- printf("\n");
- printf(" Max. #of LUNS: %d\n", buff[15]);
- return;
-}
-
+#if 0
static void
decode_rdac_vpd_c9_rtpg_data(uint8_t aas, uint8_t vendor)
{
@@ -2440,6 +2251,7 @@ decode_rdac_vpd_c9(uint8_t * buff, int len, struct opts_t * op)
return;
}
+#endif
extern const char * sg_ansi_version_arr[];
@@ -3840,7 +3652,7 @@ vpd_decode(int sg_fd, struct opts_t * op, sgj_opaque_p jop, int off)
break;
/* Vendor specific VPD pages (>= 0xc0) */
case VPD_UPR_EMC: /* 0xc0 */
- np = "Block device characteristics VPD page";
+ np = "Unit path report VPD page";
ep = "(EMC)";
if (!op->do_raw && (op->do_hex < 3))
sgj_pr_hr(jsp, "VPD INQUIRY: %s %s\n", np, ep);
@@ -3856,26 +3668,36 @@ vpd_decode(int sg_fd, struct opts_t * op, sgj_opaque_p jop, int off)
}
break;
case VPD_RDAC_VERS: /* 0xc2 */
+ np = "Software Version VPD page";
+ ep = "(RDAC)";
if (!op->do_raw && (op->do_hex < 3))
- printf("VPD INQUIRY: Software Version (RDAC)\n");
+ sgj_pr_hr(jsp, "VPD INQUIRY: %s %s\n", np, ep);
res = vpd_fetch_page(sg_fd, rp, pn, -1, qt, vb, &len);
if (res)
break;
if (op->do_raw)
dStrRaw((const char *)rp, len);
- else
- decode_rdac_vpd_c2(rp, len, op);
+ else {
+ if (as_json)
+ jo2p = sg_vpd_js_hdr(jsp, jop, np, rp);
+ decode_rdac_vpd_c2(rp, len, op, jo2p);
+ }
break;
case VPD_RDAC_VAC: /* 0xc9 */
+ np = "Volume access control VPD page";
+ ep = "(RDAC)";
if (!op->do_raw && (op->do_hex < 3))
- printf("VPD INQUIRY: Volume Access Control (RDAC)\n");
+ sgj_pr_hr(jsp, "VPD INQUIRY: %s %s\n", np, ep);
res = vpd_fetch_page(sg_fd, rp, pn, -1, qt, vb, &len);
if (res)
break;
if (op->do_raw)
dStrRaw((const char *)rp, len);
- else
- decode_rdac_vpd_c9(rp, len, op);
+ else {
+ if (as_json)
+ jo2p = sg_vpd_js_hdr(jsp, jop, np, rp);
+ decode_rdac_vpd_c9(rp, len, op, jo2p);
+ }
break;
case SG_NVME_VPD_NICR: /* 0xde */
np = "NVMe Identify Controller Response VPD page";
diff --git a/src/sg_sat_read_gplog.c b/src/sg_sat_read_gplog.c
index a1afc828..55c164eb 100644
--- a/src/sg_sat_read_gplog.c
+++ b/src/sg_sat_read_gplog.c
@@ -54,7 +54,7 @@
#define DEF_TIMEOUT 20
-static const char * version_str = "1.22 20220425";
+static const char * version_str = "1.23 20220917";
struct opts_t {
bool ck_cond;
@@ -124,7 +124,7 @@ usage()
}
static int
-do_read_gplog(int sg_fd, int ata_cmd, uint8_t *inbuff,
+do_read_gplog(int sg_fd, int ata_cmd, uint8_t * inbuff,
const struct opts_t * op)
{
const bool extend = true;
diff --git a/src/sg_vpd.c b/src/sg_vpd.c
index 707d3e12..35de6ca4 100644
--- a/src/sg_vpd.c
+++ b/src/sg_vpd.c
@@ -42,7 +42,7 @@
*/
-static const char * version_str = "1.82 20220826"; /* spc6r06 + sbc5r03 */
+static const char * version_str = "1.83 20220915"; /* spc6r06 + sbc5r03 */
#define MY_NAME "sg_vpd"
@@ -444,17 +444,6 @@ device_id_vpd_variants(uint8_t * buff, int len, int subvalue,
}
}
-static int
-no_ascii_4hex(const struct opts_t * op)
-{
- if (op->do_hex < 2)
- return 1;
- else if (2 == op->do_hex)
- return 0;
- else
- return -1;
-}
-
static void /* VPD_SUPPORTED_VPDS ["sv"] */
decode_supported_vpd_4vpd(uint8_t * buff, int len, struct opts_t * op,
sgj_opaque_p jap)
@@ -1100,16 +1089,6 @@ svpd_unable_to_decode(int sg_fd, struct opts_t * op, int subvalue, int off)
}
} else
hex2stdout(rp, len, no_ascii_4hex(op));
-#if 0
- if (op->do_hex > 1)
- hex2stdout(rp, len, -1);
- else if (VPD_ASCII_OP_DEF == op->vpd_pn)
- hex2stdout(rp, len, 0);
- else if (1 == op->do_hex)
- hex2stdout(rp, len, (op->do_long ? 0 : 1));
- else
- hex2stdout(rp, len, 0);
-#endif
}
} else if ((! op->do_quiet) && (! op->examine_given)) {
if (op->vpd_pn >= 0)
diff --git a/src/sg_vpd_common.c b/src/sg_vpd_common.c
index dcc7727b..31c74ea0 100644
--- a/src/sg_vpd_common.c
+++ b/src/sg_vpd_common.c
@@ -132,6 +132,17 @@ struct svpd_values_name_t vendor_vpd_pg[] = {
int
+no_ascii_4hex(const struct opts_t * op)
+{
+ if (op->do_hex < 2)
+ return 1;
+ else if (2 == op->do_hex)
+ return 0;
+ else
+ return -1;
+}
+
+int
svpd_find_vp_num_by_acron(const char * vp_ap)
{
size_t len;
@@ -696,9 +707,9 @@ decode_mode_policy_vpd(const uint8_t * buff, int len, struct opts_t * op,
n = 0;
ppc = (bp[0] & 0x3f);
pspc = bp[1];
- n = snprintf(b + n, blen - n, " Policy page code: 0x%x", ppc);
+ n = sg_scnpr(b + n, blen - n, " Policy page code: 0x%x", ppc);
if (pspc)
- n += snprintf(b + n, blen - n, ", subpage code: 0x%x", pspc);
+ n += sg_scnpr(b + n, blen - n, ", subpage code: 0x%x", pspc);
sgj_pr_hr(jsp, "%s\n", b);
if ((0 == k) && (0x3f == (0x3f & bp[0])) && (0xff == bp[1]))
sgj_pr_hr(jsp, " therefore the policy applies to all modes "
@@ -839,7 +850,7 @@ decode_ata_info_vpd(const uint8_t * buff, int len, struct opts_t * op,
ata_transp);
cc = buff[56]; /* 0xec for IDENTIFY DEVICE and 0xa1 for IDENTIFY
* PACKET DEVICE (obsolete) */
- n = snprintf(b, blen, " Command code: 0x%x\n", cc);
+ n = sg_scnpr(b, blen, " Command code: 0x%x\n", cc);
if (len < 60)
return;
if (0xec == cc)
@@ -2993,3 +3004,498 @@ decode_tapealert_supported_vpd(const uint8_t * buff, int len,
}
sgj_pr_hr(jsp, "%s\n", b);
}
+
+/*
+ * Some of the vendor specific VPD pages are common as well. So place them here
+ * to save on code duplication.
+ */
+
+static const char * lun_state_arr[] =
+{
+ "LUN not bound or LUN_Z report",
+ "LUN bound, but not owned by this SP",
+ "LUN bound and owned by this SP",
+};
+
+static const char * ip_mgmt_arr[] =
+{
+ "No IP access",
+ "Reserved (undefined)",
+ "via IPv4",
+ "via IPv6",
+};
+
+static const char * sp_arr[] =
+{
+ "SP A",
+ "SP B",
+};
+
+static const char * lun_op_arr[] =
+{
+ "Normal operations",
+ "I/O Operations being rejected, SP reboot or NDU in progress",
+};
+
+static const char * failover_mode_arr[] =
+{
+ "Legacy mode 0",
+ "Unknown mode (1)",
+ "Unknown mode (2)",
+ "Unknown mode (3)",
+ "Active/Passive (PNR) mode 1",
+ "Unknown mode (5)",
+ "Active/Active (ALUA) mode 4",
+ "Unknown mode (7)",
+ "Legacy mode 2",
+ "Unknown mode (9)",
+ "Unknown mode (10)",
+ "Unknown mode (11)",
+ "Unknown mode (12)",
+ "Unknown mode (13)",
+ "AIX Active/Passive (PAR) mode 3",
+ "Unknown mode (15)",
+};
+
+/* VPD_UPR_EMC,VPD_V_UPR_EMC 0xc0 ["upr","upr"] */
+void
+decode_upr_vpd_c0_emc(uint8_t * buff, int len, struct opts_t * op,
+ sgj_opaque_p jop)
+{
+ uint8_t uc;
+ int k, n, ip_mgmt, vpp80, lun_z;
+ sgj_state * jsp = &op->json_st;
+ const char * cp;
+ const char * c2p;
+ char b[256];
+ static const int blen = sizeof(b);
+
+ if (len < 3) {
+ pr2serr("EMC upr VPD page [0xc0]: length too short=%d\n", len);
+ return;
+ }
+ if (op->do_hex) {
+ hex2stdout(buff, len, no_ascii_4hex(op));
+ return;
+ }
+ if (buff[9] != 0x00) {
+ pr2serr("Unsupported page revision %d, decoding not possible.\n",
+ buff[9]);
+ return;
+ }
+ for (k = 0, n = 0; k < 16; ++k)
+ n += sg_scnpr(b + n, blen - n, "%02x", buff[10 + k]);
+ sgj_haj_vs(jsp, jop, 2, "LUN WWN", SGJ_SEP_COLON_1_SPACE, b);
+ snprintf(b, blen, "%.*s", buff[49], buff + 50);
+ sgj_haj_vs(jsp, jop, 2, "Array Serial Number", SGJ_SEP_COLON_1_SPACE, b);
+
+ if (buff[4] > 0x02)
+ snprintf(b, blen, "Unknown (%x)", buff[4]);
+ else
+ snprintf(b, blen, "%s", lun_state_arr[buff[4]]);
+ sgj_haj_vistr(jsp, jop, 2, "LUN State", SGJ_SEP_COLON_1_SPACE,
+ buff[4], true, b);
+
+ uc = buff[8];
+ n = 0;
+ if (uc > 0x01)
+ n += sg_scnpr(b + n, blen - n, "Unknown SP (%x)", uc);
+ else
+ n += sg_scnpr(b + n, blen - n, "%s", sp_arr[uc]);
+ sgj_js_nv_ihexstr(jsp, jop, "path_connects_to", uc, NULL, b);
+ n += sg_scnpr(b + n, blen - n, ", Port Number: %u", buff[7]);
+ sgj_pr_hr(jsp, " This path connects to: %s\n", b);
+ sgj_js_nv_ihex(jsp, jop, "port_number", buff[7]);
+
+ if (buff[5] > 0x01)
+ snprintf(b, blen, "Unknown (%x)\n", buff[5]);
+ else
+ snprintf(b, blen, "%s\n", sp_arr[buff[5]]);
+ sgj_haj_vistr(jsp, jop, 2, "Default owner", SGJ_SEP_COLON_1_SPACE,
+ buff[5], true, b);
+
+ cp = (buff[6] & 0x40) ? "supported" : "not supported";
+ sgj_pr_hr(jsp, " NO_ATF: %s, Access Logix: %s\n",
+ buff[6] & 0x80 ? "set" : "not set", cp);
+ sgj_js_nv_i(jsp, jop, "no_atf", !! (buff[6] & 0x80));
+ sgj_js_nv_istr(jsp, jop, "access_logix", !! (buff[6] & 0x40),
+ NULL, cp);
+
+ ip_mgmt = (buff[6] >> 4) & 0x3;
+ cp = ip_mgmt_arr[ip_mgmt];
+ sgj_pr_hr(jsp, " SP IP Management Mode: %s\n", cp);
+ sgj_js_nv_istr(jsp, jop, "sp_ip_management_mode", !! ip_mgmt,
+ NULL, cp);
+ if (ip_mgmt == 2) {
+ snprintf(b, blen, "%u.%u.%u.%u", buff[44], buff[45], buff[46],
+ buff[47]);
+ sgj_pr_hr(jsp, " SP IPv4 address: %s\n", b);
+ sgj_js_nv_s(jsp, jop, "sp_ipv4_address", b);
+ } else if (ip_mgmt == 3) {
+ printf(" SP IPv6 address: ");
+ n = 0;
+ for (k = 0; k < 16; ++k)
+ n += sg_scnpr(b + n, blen - n, "%02x", buff[32 + k]);
+ sgj_pr_hr(jsp, " SP IPv6 address: %s\n", b);
+ sgj_js_nv_hex_bytes(jsp, jop, "sp_ipv6_address", buff + 32, 16);
+ }
+
+ k = buff[28] & 0x0f;
+ sgj_pr_hr(jsp, " System Type: %x, Failover mode: %s\n",
+ buff[27], failover_mode_arr[k]);
+ sgj_js_nv_ihex(jsp, jop, "system_type", buff[27]);
+ sgj_js_nv_ihexstr(jsp, jop, "failover_mode", k, NULL,
+ failover_mode_arr[k]);
+
+ vpp80 = buff[30] & 0x08;
+ lun_z = buff[30] & 0x04;
+ cp = vpp80 ? "array serial#" : "LUN serial#";
+ c2p = lun_z ? "Set to 1" : "Unknown";
+ sgj_pr_hr(jsp, " Inquiry VPP 0x80 returns: %s, Arraycommpath: %s\n",
+ cp, c2p);
+ sgj_js_nv_istr(jsp, jop, "inquiry_vpp_0x80_returns", !! vpp80, NULL, cp);
+ sgj_js_nv_istr(jsp, jop, "arraycommpath", !! lun_z, NULL, c2p);
+
+ cp = buff[48] > 1 ? "undefined" : lun_op_arr[buff[48]];
+ sgj_pr_hr(jsp, " Lun operations: %s\n", cp);
+ sgj_js_nv_istr(jsp, jop, "lun_operations", 0x1 & buff[48], NULL, cp);
+
+ return;
+}
+
+/* VPD_RDAC_VERS,VPD_V_SVER_RDAC 0xc2 ["rdac_vers", "swr4"] */
+void
+decode_rdac_vpd_c2(uint8_t * buff, int len, struct opts_t * op,
+ sgj_opaque_p jop)
+{
+ int i, n, v, r, m, p, d, y, num_part;
+ sgj_state * jsp = &op->json_st;
+ sgj_opaque_p jo2p = NULL;
+ sgj_opaque_p jap = NULL;
+ // const char * cp;
+ // const char * c2p;
+ char b[256];
+ static const int blen = sizeof(b);
+ char part[5];
+
+ if (len < 3) {
+ pr2serr("Software Version VPD page length too short=%d\n", len);
+ return;
+ }
+ if (op->do_hex) {
+ hex2stdout(buff, len, no_ascii_4hex(op));
+ return;
+ }
+ if (buff[4] != 's' && buff[5] != 'w' && buff[6] != 'r') {
+ pr2serr("Invalid page identifier %c%c%c%c, decoding not possible.\n",
+ buff[4], buff[5], buff[6], buff[7]);
+ return;
+ }
+ snprintf(b, blen, "%02x.%02x.%02x", buff[8], buff[9], buff[10]);
+ sgj_haj_vs(jsp, jop, 2, "Software Version", SGJ_SEP_COLON_1_SPACE, b);
+ snprintf(b, blen, "%02d/%02d/%02d\n", buff[11], buff[12], buff[13]);
+ sgj_haj_vs(jsp, jop, 2, "Software Date", SGJ_SEP_COLON_1_SPACE, b);
+ n = 0;
+ n += sg_scnpr(b + n, blen - n, " Features:");
+ if (buff[14] & 0x01)
+ n += sg_scnpr(b + n, blen - n, " Dual Active,");
+ if (buff[14] & 0x02)
+ n += sg_scnpr(b + n, blen - n, " Series 3,");
+ if (buff[14] & 0x04)
+ n += sg_scnpr(b + n, blen - n, " Multiple Sub-enclosures,");
+ if (buff[14] & 0x08)
+ n += sg_scnpr(b + n, blen - n, " DCE/DRM/DSS/DVE,");
+ if (buff[14] & 0x10)
+ n += sg_scnpr(b + n, blen - n, " Asymmetric Logical Unit Access,");
+ sgj_pr_hr(jsp, "%s\n", b);
+ if (jsp->pr_as_json) {
+ jo2p = sgj_snake_named_subobject_r(jsp, jop, "features");
+ sgj_js_nv_i(jsp, jo2p, "dual_active", !! (buff[14] & 0x01));
+ sgj_js_nv_i(jsp, jo2p, "series_3", !! (buff[14] & 0x02));
+ sgj_js_nv_i(jsp, jo2p, "multiple_sub_enclosures",
+ !! (buff[14] & 0x04));
+ sgj_js_nv_i(jsp, jo2p, "dcm_drm_dss_dve", !! (buff[14] & 0x08));
+ sgj_js_nv_i(jsp, jo2p, "asymmetric_logical_unit_access",
+ !! (buff[14] & 0x10));
+ }
+ sgj_haj_vi(jsp, jop, 2, "Maximum number of LUNS",
+ SGJ_SEP_COLON_1_SPACE, buff[15], true);
+
+ num_part = (len - 12) / 16;
+ n = 16;
+ printf(" Partitions: %d\n", num_part);
+ sgj_haj_vi(jsp, jop, 2, "Partitions", SGJ_SEP_COLON_1_SPACE, num_part,
+ true);
+ if (num_part > 0)
+ jap = sgj_named_subarray_r(jsp, jop, "partition_list");
+ for (i = 0; i < num_part; i++) {
+ memset(part,0, 5);
+ memcpy(part, &buff[n], 4);
+ sgj_pr_hr(jsp, " Name: %s\n", part);
+ if (jsp->pr_as_json) {
+ jo2p = sgj_new_unattached_object_r(jsp);
+ sgj_js_nv_s(jsp, jo2p, "name", part);
+ }
+ n += 4;
+ v = buff[n++];
+ r = buff[n++];
+ m = buff[n++];
+ p = buff[n++];
+ snprintf(b, blen, "%d.%d.%d.%d", v, r, m, p);
+ sgj_pr_hr(jsp, " Version: %s\n", b);
+ if (jsp->pr_as_json)
+ sgj_js_nv_s(jsp, jo2p, "version", b);
+ m = buff[n++];
+ d = buff[n++];
+ y = buff[n++];
+ snprintf(b, blen, "%d/%d/%d\n", m, d, y);
+ sgj_pr_hr(jsp, " Date: %s\n", b);
+ if (jsp->pr_as_json) {
+ sgj_js_nv_s(jsp, jo2p, "date", b);
+ sgj_js_nv_o(jsp, jap, NULL /* name */, jo2p);
+ }
+
+ n += 5;
+ }
+ return;
+}
+
+static char *
+decode_rdac_vpd_c9_aas_s(uint8_t aas, char * b, int blen)
+{
+ // snprintf(" Asymmetric Access State:");
+ switch(aas & 0x0F) {
+ case 0x0:
+ snprintf(b, blen, "Active/Optimized");
+ break;
+ case 0x1:
+ snprintf(b, blen, "Active/Non-Optimized");
+ break;
+ case 0x2:
+ snprintf(b, blen, "Standby");
+ break;
+ case 0x3:
+ snprintf(b, blen, "Unavailable");
+ break;
+ case 0xE:
+ snprintf(b, blen, "Offline");
+ break;
+ case 0xF:
+ snprintf(b, blen, "Transitioning");
+ break;
+ default:
+ snprintf(b, blen, "(unknown)");
+ break;
+ }
+ return b;
+}
+
+static char *
+decode_rdac_vpd_c9_vs_s(uint8_t vendor, char * b, int blen)
+{
+ // printf(" Vendor Specific Field:");
+ switch(vendor) {
+ case 0x01:
+ snprintf(b, blen, "Operating normally");
+ break;
+ case 0x02:
+ snprintf(b, blen, "Non-responsive to queries");
+ break;
+ case 0x03:
+ snprintf(b, blen, "Controller being held in reset");
+ break;
+ case 0x04:
+ snprintf(b, blen, "Performing controller firmware download (1st "
+ "controller)");
+ break;
+ case 0x05:
+ snprintf(b, blen, "Performing controller firmware download (2nd "
+ "controller)");
+ break;
+ case 0x06:
+ snprintf(b, blen,
+ "Quiesced as a result of an administrative request");
+ break;
+ case 0x07:
+ snprintf(b, blen,
+ "Service mode as a result of an administrative request");
+ break;
+ case 0xFF:
+ snprintf(b, blen, "Details are not available");
+ break;
+ default:
+ snprintf(b, blen, "(unknown)");
+ break;
+ }
+ return b;
+}
+
+/* VPD_RDAC_VAC,VPD_V_VAC_RDAC 0xc9 ["rdac_vac", "vac1"] */
+void
+decode_rdac_vpd_c9(uint8_t * buff, int len, struct opts_t * op,
+ sgj_opaque_p jop)
+{
+ bool vav;
+ int n, n_hold;
+ sgj_state * jsp = &op->json_st;
+ char b[196];
+ static const int blen = sizeof(b);
+
+ if (len < 3) {
+ pr2serr("Volume Access Control VPD page length too short=%d\n", len);
+ return;
+ }
+ if (op->do_hex) {
+ hex2stdout(buff, len, no_ascii_4hex(op));
+ return;
+ }
+ if (buff[4] != 'v' && buff[5] != 'a' && buff[6] != 'c') {
+ pr2serr("Invalid page identifier %c%c%c%c, decoding "
+ "not possible.\n" , buff[4], buff[5], buff[6], buff[7]);
+ return;
+ }
+ if (buff[7] != '1') {
+ pr2serr("Invalid page version '%c' (should be 1)\n", buff[7]);
+ }
+ n = ((buff[8] & 0xE0) == 0xE0 );
+ if (n) {
+ sgj_pr_hr(jsp, " IOShipping (ALUA): Enabled\n");
+ sgj_js_nv_ihexstr_nex(jsp, jop, "ioshipping", n, true, NULL,
+ "Enabled",
+ "a.k.a. ALUA (Asymmetric Logical Unit Access)");
+ } else {
+ n = 0;
+ n = snprintf(b, blen, " AVT:");
+ n_hold = n;
+ if (buff[8] & 0x80) {
+ n += sg_scnpr(b + n, blen - n, " Enabled");
+ if (buff[8] & 0x40)
+ n += sg_scnpr(b + n, blen - n, " (Allow reads on sector 0)");
+ sgj_pr_hr(jsp, "%s\n", b);
+ sgj_js_nv_ihexstr(jsp, jop, "avt", buff[8], NULL, b + n_hold);
+
+ } else {
+ sgj_pr_hr(jsp, "%s: Disabled\n", b);
+ sgj_js_nv_ihexstr(jsp, jop, "avt", buff[8], NULL, "Disabled");
+ }
+ }
+ vav = !! (0x1 & buff[8]);
+ sgj_haj_vistr(jsp, jop, 2, "Volume access via", SGJ_SEP_COLON_1_SPACE,
+ (int)vav, false,
+ (vav ? "primary controller" : "alternate controller"));
+
+ if (buff[8] & 0x08) {
+ n = buff[15] & 0xf;
+ // printf(" Path priority: %d ", n);
+ switch (n) {
+ case 0x1:
+ snprintf(b, blen, "(preferred path)");
+ break;
+ case 0x2:
+ snprintf(b, blen, "(secondary path)");
+ break;
+ default:
+ snprintf(b, blen, "(unknown)");
+ break;
+ }
+ sgj_haj_vistr(jsp, jop, 2, "Path priority", SGJ_SEP_COLON_1_SPACE, n,
+ true, b);
+
+ // printf(" Preferred Path Auto Changeable:");
+ n = buff[14] & 0x3C;
+ switch (n) {
+ case 0x14:
+ snprintf(b, blen, "No (User Disabled and Host Type Restricted)");
+ break;
+ case 0x18:
+ snprintf(b, blen, "No (User Disabled)");
+ break;
+ case 0x24:
+ snprintf(b, blen, "No (Host Type Restricted)");
+ break;
+ case 0x28:
+ snprintf(b, blen, "Yes");
+ break;
+ default:
+ snprintf(b, blen, "(Unknown)");
+ break;
+ }
+ sgj_haj_vistr(jsp, jop, 2, "Preferred path auto changeable",
+ SGJ_SEP_COLON_1_SPACE, n, true, b);
+
+ n = buff[14] & 0x03;
+ // printf(" Implicit Failback:");
+ switch (n) {
+ case 0x1:
+ snprintf(b, blen, "Disabled");
+ break;
+ case 0x2:
+ snprintf(b, blen, "Enabled");
+ break;
+ default:
+ snprintf(b, blen, "(Unknown)");
+ break;
+ }
+ sgj_haj_vistr(jsp, jop, 2, "Implicit failback",
+ SGJ_SEP_COLON_1_SPACE, n, false, b);
+ } else {
+ n = buff[9] & 0xf;
+ // printf(" Path priority: %d ", buff[9] & 0xf);
+ switch (n) {
+ case 0x1:
+ snprintf(b, blen, "(preferred path)");
+ break;
+ case 0x2:
+ snprintf(b, blen, "(secondary path)");
+ break;
+ default:
+ snprintf(b, blen, "(unknown)");
+ break;
+ }
+ sgj_haj_vistr(jsp, jop, 2, "Path priority",
+ SGJ_SEP_COLON_1_SPACE, n, false, b);
+ }
+
+ n = !! (buff[8] & 0x80);
+ sgj_haj_vi(jsp, jop, 2, "Target port group present",
+ SGJ_SEP_COLON_1_SPACE, n, false);
+ if (n) {
+ sgj_opaque_p jo2p = NULL;
+ sgj_opaque_p jo3p = NULL;
+ static const char * tpg_s = "Target port group data";
+ static const char * aas_s = "Asymmetric access state";
+ static const char * vs_s = "Vendor specific field";
+ char d1[80];
+ char d2[80];
+
+ sgj_pr_hr(jsp, " Target Port Group Data (This controller):\n");
+ decode_rdac_vpd_c9_aas_s(buff[10], d1, sizeof(d1));
+ decode_rdac_vpd_c9_vs_s(buff[11], d2, sizeof(d2));
+ sgj_pr_hr(jsp, " %s: %s\n", aas_s, d1);
+ sgj_pr_hr(jsp, " %s: %s\n", vs_s, d2);
+ if (jsp->pr_as_json) {
+ jo2p = sgj_snake_named_subobject_r(jsp, jop, tpg_s);
+ jo3p = sgj_snake_named_subobject_r(jsp, jo2p, "this_controller");
+ sgj_convert_to_snake_name(aas_s, b, blen);
+ sgj_js_nv_ihexstr(jsp, jo3p, b, buff[10], NULL, d1);
+ sgj_convert_to_snake_name(vs_s, b, blen);
+ sgj_js_nv_ihexstr(jsp, jo3p, b, buff[11], NULL, d2);
+ }
+ sgj_pr_hr(jsp, " Target Port Group Data (Alternate controller):\n");
+ // decode_rdac_vpd_c9_rtpg_data(buff[12], buff[13]);
+
+ decode_rdac_vpd_c9_aas_s(buff[12], d1, sizeof(d1));
+ decode_rdac_vpd_c9_vs_s(buff[13], d2, sizeof(d2));
+ sgj_pr_hr(jsp, " %s: %s\n", aas_s, d1);
+ sgj_pr_hr(jsp, " %s: %s\n", vs_s, d2);
+ if (jsp->pr_as_json) {
+ jo2p = sgj_snake_named_subobject_r(jsp, jop, tpg_s);
+ jo3p = sgj_snake_named_subobject_r(jsp, jo2p,
+ "alternate_controller");
+ sgj_convert_to_snake_name(aas_s, b, blen);
+ sgj_js_nv_ihexstr(jsp, jo3p, b, buff[12], NULL, d1);
+ sgj_convert_to_snake_name(vs_s, b, blen);
+ sgj_js_nv_ihexstr(jsp, jo3p, b, buff[13], NULL, d2);
+ }
+ }
+}
diff --git a/src/sg_vpd_common.h b/src/sg_vpd_common.h
index 50cdb48a..13134336 100644
--- a/src/sg_vpd_common.h
+++ b/src/sg_vpd_common.h
@@ -250,7 +250,19 @@ decode_lb_protection_vpd(const uint8_t * buff, int len, struct opts_t * op,
void
decode_tapealert_supported_vpd(const uint8_t * buff, int len,
struct opts_t * op, sgj_opaque_p jop);
+/* Share some vendor specific VPD pages as well */
+void
+decode_upr_vpd_c0_emc(uint8_t * buff, int len, struct opts_t * op,
+ sgj_opaque_p jop);
+void
+decode_rdac_vpd_c2(uint8_t * buff, int len, struct opts_t * op,
+ sgj_opaque_p jop);
+void
+decode_rdac_vpd_c9(uint8_t * buff, int len, struct opts_t * op,
+ sgj_opaque_p jop);
+
const char * pqual_str(int pqual);
+int no_ascii_4hex(const struct opts_t * op);
void svpd_enumerate_vendor(int vend_prod_num);
int svpd_count_vendor_vpds(int vpd_pn, int vend_prod_num);
diff --git a/src/sg_vpd_vendor.c b/src/sg_vpd_vendor.c
index 5cfc7ee3..156dd83b 100644
--- a/src/sg_vpd_vendor.c
+++ b/src/sg_vpd_vendor.c
@@ -111,17 +111,6 @@ dup_sanity_chk(int sz_opts_t, int sz_values_name_t)
sz_values_name_t);
}
-static int
-no_ascii_4hex(const struct opts_t * op)
-{
- if (op->do_hex < 2)
- return 1;
- else if (2 == op->do_hex)
- return 0;
- else
- return -1;
-}
-
static bool
is_like_pdt(int actual_pdt, const struct svpd_values_name_t * vnp)
{
@@ -350,127 +339,6 @@ decode_dev_beh_vpd_c3_sea(uint8_t * buff, int len)
printf(" Default number of cache segments: %d\n", buff[24]);
}
-static const char * lun_state_arr[] =
-{
- "LUN not bound or LUN_Z report",
- "LUN bound, but not owned by this SP",
- "LUN bound and owned by this SP",
-};
-
-static const char * ip_mgmt_arr[] =
-{
- "No IP access",
- "Reserved (undefined)",
- "via IPv4",
- "via IPv6",
-};
-
-static const char * sp_arr[] =
-{
- "SP A",
- "SP B",
-};
-
-static const char * lun_op_arr[] =
-{
- "Normal operations",
- "I/O Operations being rejected, SP reboot or NDU in progress",
-};
-
-static const char * failover_mode_arr[] =
-{
- "Legacy mode 0",
- "Unknown mode (1)",
- "Unknown mode (2)",
- "Unknown mode (3)",
- "Active/Passive (PNR) mode 1",
- "Unknown mode (5)",
- "Active/Active (ALUA) mode 4",
- "Unknown mode (7)",
- "Legacy mode 2",
- "Unknown mode (9)",
- "Unknown mode (10)",
- "Unknown mode (11)",
- "Unknown mode (12)",
- "Unknown mode (13)",
- "AIX Active/Passive (PAR) mode 3",
- "Unknown mode (15)",
-};
-
-static void
-decode_upr_vpd_c0_emc(uint8_t * buff, int len)
-{
- int k, ip_mgmt, vpp80, lun_z;
-
- if (len < 3) {
- pr2serr("EMC upr VPD page [0xc0]: length too short=%d\n", len);
- return;
- }
- if (buff[9] != 0x00) {
- pr2serr("Unsupported page revision %d, decoding not possible.\n",
- buff[9]);
- return;
- }
- printf(" LUN WWN: ");
- for (k = 0; k < 16; ++k)
- printf("%02x", buff[10 + k]);
- printf("\n");
- printf(" Array Serial Number: ");
- dStrRaw(&buff[50], buff[49]);
- printf("\n");
-
- printf(" LUN State: ");
- if (buff[4] > 0x02)
- printf("Unknown (%x)\n", buff[4]);
- else
- printf("%s\n", lun_state_arr[buff[4]]);
-
- printf(" This path connects to: ");
- if (buff[8] > 0x01)
- printf("Unknown SP (%x)", buff[8]);
- else
- printf("%s", sp_arr[buff[8]]);
- printf(", Port Number: %u\n", buff[7]);
-
- printf(" Default Owner: ");
- if (buff[5] > 0x01)
- printf("Unknown (%x)\n", buff[5]);
- else
- printf("%s\n", sp_arr[buff[5]]);
-
- printf(" NO_ATF: %s, Access Logix: %s\n",
- buff[6] & 0x80 ? "set" : "not set",
- buff[6] & 0x40 ? "supported" : "not supported");
-
- ip_mgmt = (buff[6] >> 4) & 0x3;
-
- printf(" SP IP Management Mode: %s\n", ip_mgmt_arr[ip_mgmt]);
- if (ip_mgmt == 2)
- printf(" SP IPv4 address: %u.%u.%u.%u\n",
- buff[44], buff[45], buff[46], buff[47]);
- else {
- printf(" SP IPv6 address: ");
- for (k = 0; k < 16; ++k)
- printf("%02x", buff[32 + k]);
- printf("\n");
- }
-
- vpp80 = buff[30] & 0x08;
- lun_z = buff[30] & 0x04;
-
- printf(" System Type: %x, Failover mode: %s\n",
- buff[27], failover_mode_arr[buff[28] & 0x0f]);
-
- printf(" Inquiry VPP 0x80 returns: %s, Arraycommpath: %s\n",
- vpp80 ? "array serial#" : "LUN serial#",
- lun_z ? "Set to 1" : "Unknown");
-
- printf(" Lun operations: %s\n",
- buff[48] > 1 ? "undefined" : lun_op_arr[buff[48]]);
-
- return;
-}
-
static void
decode_rdac_vpd_c0(uint8_t * buff, int len)
{
@@ -560,61 +428,6 @@ decode_rdac_vpd_c1(uint8_t * buff, int len)
}
static void
-decode_rdac_vpd_c2(uint8_t * buff, int len)
-{
- int i, n, v, r, m, p, d, y, num_part;
- char part[5];
-
- if (len < 3) {
- pr2serr("Software Version VPD page length too short=%d\n", len);
- return;
- }
- if (buff[4] != 's' && buff[5] != 'w' && buff[6] != 'r') {
- pr2serr("Invalid page identifier %c%c%c%c, decoding not possible.\n",
- buff[4], buff[5], buff[6], buff[7]);
- return;
- }
- printf(" Software Version: %02x.%02x.%02x\n", buff[8], buff[9], buff[10]);
- printf(" Software Date: %02d/%02d/%02d\n", buff[11], buff[12], buff[13]);
- printf(" Features:");
- if (buff[14] & 0x01)
- printf(" Dual Active,");
- if (buff[14] & 0x02)
- printf(" Series 3,");
- if (buff[14] & 0x04)
- printf(" Multiple Sub-enclosures,");
- if (buff[14] & 0x08)
- printf(" DCE/DRM/DSS/DVE,");
- if (buff[14] & 0x10)
- printf(" Asymmetric Logical Unit Access,");
- printf("\n");
- printf(" Max. #of LUNS: %d\n", buff[15]);
-
- num_part = (len - 12) / 16;
- n = 16;
- printf(" Partitions: %d\n", num_part);
- for (i = 0; i < num_part; i++) {
- memset(part,0, 5);
- memcpy(part, &buff[n], 4);
- printf(" Name: %s\n", part);
- n += 4;
- v = buff[n++];
- r = buff[n++];
- m = buff[n++];
- p = buff[n++];
- printf(" Version: %d.%d.%d.%d\n", v, r, m, p);
- m = buff[n++];
- d = buff[n++];
- y = buff[n++];
- printf(" Date: %d/%d/%d\n", m, d, y);
-
- n += 5;
- }
-
- return;
-}
-
-static void
decode_rdac_vpd_c3(uint8_t * buff, int len)
{
if (len < 0x2c) {
@@ -827,6 +640,7 @@ decode_rdac_vpd_c8(uint8_t * buff, int len)
return;
}
+#if 0
static void
decode_rdac_vpd_c9_rtpg_data(uint8_t aas, uint8_t vendor)
{
@@ -992,6 +806,7 @@ decode_rdac_vpd_c9(uint8_t * buff, int len)
decode_rdac_vpd_c9_rtpg_data(buff[12], buff[13]);
}
}
+#endif
static void
decode_rdac_vpd_ca(uint8_t * buff, int len)
@@ -1237,15 +1052,17 @@ int
svpd_decode_vendor(int sg_fd, struct opts_t * op, sgj_opaque_p jop, int off)
{
bool hex0 = (0 == op->do_hex);
+ bool as_json;
int len, pdt, plen, pn;
int alloc_len = op->maxlen;
int res = 0;
const struct svpd_values_name_t * vnp;
sgj_state * jsp = &op->json_st;
- sgj_opaque_p jo2p;
+ sgj_opaque_p jo2p = NULL;
uint8_t * rp;
char name[80];
+ as_json = jsp->pr_as_json;
pn = op->vpd_pn;
switch (pn) { /* VPD codes that we support vendor pages for */
case 0x3:
@@ -1300,9 +1117,12 @@ svpd_decode_vendor(int sg_fd, struct opts_t * op, sgj_opaque_p jop, int off)
hex2stdout(rp, len, no_ascii_4hex(op));
else if (VPD_VP_SEAGATE == op->vend_prod_num)
decode_firm_vpd_c0_sea(rp, len);
- else if (VPD_VP_EMC == op->vend_prod_num)
- decode_upr_vpd_c0_emc(rp, len);
- else if (VPD_VP_HP3PAR == op->vend_prod_num)
+ else if (VPD_VP_EMC == op->vend_prod_num) {
+ if (as_json)
+ jo2p = sg_vpd_js_hdr(jsp, jop,
+ "Unit serial number VPD page", rp);
+ decode_upr_vpd_c0_emc(rp, len, op, jo2p);
+ } else if (VPD_VP_HP3PAR == op->vend_prod_num)
decode_vpd_c0_hp3par(rp, len);
else if (VPD_VP_RDAC == op->vend_prod_num)
decode_rdac_vpd_c0(rp, len);
@@ -1332,9 +1152,12 @@ svpd_decode_vendor(int sg_fd, struct opts_t * op, sgj_opaque_p jop, int off)
case 0xc2:
if (! hex0)
hex2stdout(rp, len, no_ascii_4hex(op));
- else if (VPD_VP_RDAC == op->vend_prod_num)
- decode_rdac_vpd_c2(rp, len);
- else if (VPD_VP_HP_LTO == op->vend_prod_num)
+ else if (VPD_VP_RDAC == op->vend_prod_num) {
+ if (as_json)
+ jo2p = sg_vpd_js_hdr(jsp, jop,
+ "Software version VPD page", rp);
+ decode_rdac_vpd_c2(rp, len, op, jo2p);
+ } else if (VPD_VP_HP_LTO == op->vend_prod_num)
decode_hp_lto_vpd_cx(rp, len, pn);
else
res = SG_LIB_CAT_OTHER;
@@ -1380,9 +1203,12 @@ svpd_decode_vendor(int sg_fd, struct opts_t * op, sgj_opaque_p jop, int off)
case 0xc9:
if (! hex0)
hex2stdout(rp, len, no_ascii_4hex(op));
- else if (VPD_VP_RDAC == op->vend_prod_num)
- decode_rdac_vpd_c9(rp, len);
- else
+ else if (VPD_VP_RDAC == op->vend_prod_num) {
+ if (as_json)
+ jo2p = sg_vpd_js_hdr(jsp, jop,
+ "Volume access control VPD page", rp);
+ decode_rdac_vpd_c9(rp, len, op, jo2p);
+ } else
res = SG_LIB_CAT_OTHER;
break;
case 0xca:
@@ -1438,16 +1264,21 @@ svpd_decode_vendor(int sg_fd, struct opts_t * op, sgj_opaque_p jop, int off)
break;
} else {
int n = len - 16;
+ const char * np = "NVMe Identify Controller Response VPD page";
+ /* NVMe: Identify Controller data structure (CNS 01h) */
+ const char * ep = "(sg3_utils)";
if (n > 4096) {
pr2serr("NVMe Identify response expected to be "
"<= 4096 bytes (got: %d)\n", n);
break;
}
+ if (op->do_hex < 3)
+ sgj_pr_hr(jsp, "VPD INQUIRY: %s %s\n", np, ep);
if (op->do_hex)
hex2stdout(rp, len, no_ascii_4hex(op));
else if (jsp->pr_as_json) {
- jo2p = sg_vpd_js_hdr(jsp, jop, name, rp);
+ jo2p = sg_vpd_js_hdr(jsp, jop, np, rp);
sgj_js_nv_hex_bytes(jsp, jo2p, "response_bytes",
rp + 16, n);
} else
diff --git a/testing/sg_mrq_dd.cpp b/testing/sg_mrq_dd.cpp
index 959a6848..821f2555 100644
--- a/testing/sg_mrq_dd.cpp
+++ b/testing/sg_mrq_dd.cpp
@@ -30,7 +30,7 @@
*
*/
-static const char * version_str = "1.42 20220615";
+static const char * version_str = "1.43 20220910";
#define _XOPEN_SOURCE 600
#ifndef _GNU_SOURCE
@@ -826,7 +826,7 @@ sg_flags_str(int flags, int b_len, char * b)
goto fini;
}
if (SGV4_FLAG_NO_DXFER & flags) { /* 0x10000 */
- n += sg_scnpr(b + n, b_len - n, "NDXFER|");
+ n += sg_scnpr(b + n, b_len - n, "NOXFER|");
if (n >= b_len)
goto fini;
}
@@ -1507,7 +1507,9 @@ sig_listen_thread(struct global_collection * clp)
} else
pr2serr_lk("%s: subsequent stall at pack_id=%d\n",
__func__, pack_id);
- system_wrapper("/usr/bin/dmesg\n");
+ // following command assumes linux bash or similar shell
+ system_wrapper("cat /proc/scsi/sg/debug >> /dev/stderr\n");
+ // system_wrapper("/usr/bin/dmesg\n");
} else
prev_pack_id = pack_id;
} else if (EAGAIN != err)
diff --git a/testing/sgh_dd.cpp b/testing/sgh_dd.cpp
index 83b4e5bc..dd72ffa9 100644
--- a/testing/sgh_dd.cpp
+++ b/testing/sgh_dd.cpp
@@ -36,7 +36,7 @@
* renamed [20181221]
*/
-static const char * version_str = "2.20 20220616";
+static const char * version_str = "2.21 20220911";
#define _XOPEN_SOURCE 600
#ifndef _GNU_SOURCE
@@ -823,7 +823,7 @@ sg_flags_str(int flags, int b_len, char * b)
goto fini;
}
if (SGV4_FLAG_NO_DXFER & flags) { /* 0x10000 */
- n += sg_scnpr(b + n, b_len - n, "NDXFER|");
+ n += sg_scnpr(b + n, b_len - n, "NOXFER|");
if (n >= b_len)
goto fini;
}
@@ -1093,7 +1093,7 @@ tsafe_strerror(int code, char * ebp)
strncpy(ebp, cp, STRERR_BUFF_LEN);
pthread_mutex_unlock(&strerr_mut);
- ebp[strlen(ebp) - 1] = '\0';
+ ebp[strlen(ebp)] = '\0';
return ebp;
}
@@ -1259,7 +1259,9 @@ sig_listen_thread(void * v_clp)
} else
pr2serr_lk("%s: subsequent stall at pack_id=%d\n",
__func__, pack_id);
- system_wrapper("/usr/bin/dmesg\n");
+ // following command assumes linux bash or similar shell
+ system_wrapper("cat /proc/scsi/sg/debug >> /dev/stderr\n");
+ // system_wrapper("/usr/bin/dmesg\n");
} else
prev_pack_id = pack_id;
} else if (EAGAIN != err)
diff --git a/utils/Makefile b/utils/Makefile
index 985c2c63..9558f9eb 100644
--- a/utils/Makefile
+++ b/utils/Makefile
@@ -1,6 +1,6 @@
SHELL = /bin/sh
-PREFIX=/usr
+PREFIX=/usr/local
INSTDIR=$(DESTDIR)/$(PREFIX)/bin
MANDIR=$(DESTDIR)/$(PREFIX)/share/man