aboutsummaryrefslogtreecommitdiff
path: root/src/sg_inq.c
diff options
context:
space:
mode:
authorDouglas Gilbert <dgilbert@interlog.com>2022-08-12 02:12:48 +0000
committerDouglas Gilbert <dgilbert@interlog.com>2022-08-12 02:12:48 +0000
commit048bd1272b7256331117b0e7b1ab5d22cf308067 (patch)
tree3f86090e36f01551afc2aa8132ce3660d878d57a /src/sg_inq.c
parent4ea97e60c544ad44ee7396c815064d87f0d25874 (diff)
downloadsg3_utils-048bd1272b7256331117b0e7b1ab5d22cf308067.tar.gz
sg_inq+sg_vpd: more JSON work (add SG_C_CPP_ZERO_INIT)
git-svn-id: https://svn.bingwo.ca/repos/sg3_utils/trunk@966 6180dd3e-e324-4e3e-922d-17de1ae2f315
Diffstat (limited to 'src/sg_inq.c')
-rw-r--r--src/sg_inq.c326
1 files changed, 166 insertions, 160 deletions
diff --git a/src/sg_inq.c b/src/sg_inq.c
index 9745c0ec..681073fe 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.27 20220806"; /* spc6r06, sbc5r03 */
+static const char * version_str = "2.28 20220811"; /* spc6r06, sbc5r03 */
#define MY_NAME "sg_inq"
@@ -84,6 +84,9 @@ static const char * version_str = "2.27 20220806"; /* spc6r06, sbc5r03 */
* information [MAINTENANCE IN, service action = 0xc]; see sg_opcodes.
*/
+// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< TESTING
+// #undef SG_SCSI_STRINGS
+// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< TESTING
#ifndef SG_NVME_VPD_NICR
#define SG_NVME_VPD_NICR 0xde
@@ -168,6 +171,9 @@ static struct svpd_values_name_t t10_vpd_pg[] = {
{VPD_FORMAT_PRESETS, 0, 0, "fp", "Format presets"},
{VPD_LB_PROVISIONING, 0, 0, "lbpv", "Logical block provisioning "
"(SBC)"},
+ {VPD_MAN_ASS_SN, 0, 1, "mas", "Manufacturer assigned serial number (SSC)"},
+ {VPD_MAN_ASS_SN, 0, 0x12, "masa",
+ "Manufacturer assigned serial number (ADC)"},
{VPD_MAN_NET_ADDR, 0, -1, "mna", "Management network addresses"},
{VPD_MODE_PG_POLICY, 0, -1, "mpp", "Mode page policy"},
{VPD_POWER_CONDITION, 0, -1, "po", "Power condition"},
@@ -424,18 +430,18 @@ new_parse_cmd_line(struct opts_t * op, int argc, char * argv[])
#ifdef SG_LIB_LINUX
#ifdef SG_SCSI_STRINGS
- c = getopt_long(argc, argv, "aB:cdeEfhHiI:j::l:Lm:NoOp:Q:rsuvVx",
+ c = getopt_long(argc, argv, "aB:cdeEfhHiI:j::l:Lm:M:NoOp:Q:rsuvVx",
long_options, &option_index);
#else
- c = getopt_long(argc, argv, "B:cdeEfhHiI:j::l:Lm:op:Q:rsuvVx",
+ c = getopt_long(argc, argv, "B:cdeEfhHiI:j::l:Lm:M:op:Q:rsuvVx",
long_options, &option_index);
#endif /* SG_SCSI_STRINGS */
#else /* SG_LIB_LINUX */
#ifdef SG_SCSI_STRINGS
- c = getopt_long(argc, argv, "B:cdeEfhHiI:j::l:Lm:NoOp:Q:rsuvVx",
+ c = getopt_long(argc, argv, "B:cdeEfhHiI:j::l:Lm:M:NoOp:Q:rsuvVx",
long_options, &option_index);
#else
- c = getopt_long(argc, argv, "B:cdeEfhHiI:j::l:Lm:op:Q:rsuvVx",
+ c = getopt_long(argc, argv, "B:cdeEfhHiI:j::l:Lm:M:op:Q:rsuvVx",
long_options, &option_index);
#endif /* SG_SCSI_STRINGS */
#endif /* SG_LIB_LINUX */
@@ -531,6 +537,14 @@ new_parse_cmd_line(struct opts_t * op, int argc, char * argv[])
}
op->maxlen = n;
break;
+ case 'M':
+ if (op->vend_prod) {
+ pr2serr("only one '--vendor=' option permitted\n");
+ usage();
+ return SG_LIB_SYNTAX_ERROR;
+ } else
+ op->vend_prod = optarg;
+ break;
case 'L':
++op->do_long;
break;
@@ -1080,8 +1094,8 @@ svpd_inhex_decode_all(struct opts_t * op, sgj_opaque_p jop)
static void
-decode_supported_vpd(uint8_t * buff, int len, struct opts_t * op,
- sgj_opaque_p jap)
+decode_supported_vpd_4inq(uint8_t * buff, int len, struct opts_t * op,
+ sgj_opaque_p jap)
{
int vpd, k, rlen, pdt;
sgj_state * jsp = &op->json_st;
@@ -1149,12 +1163,6 @@ vpd_page_is_supported(uint8_t * vpd_pg0, int v0_len, int pg_num, int vb)
return false;
}
-static bool
-vpd_page_not_supported(uint8_t * vpd_pg0, int v0_len, int pg_num, int vb)
-{
- return ! vpd_page_is_supported(vpd_pg0, v0_len, pg_num, vb);
-}
-
/* ASCII Information VPD pages (page numbers: 0x1 to 0x7f) */
static void
decode_ascii_inf(uint8_t * buff, int len, int do_hex)
@@ -1205,8 +1213,8 @@ decode_id_vpd(uint8_t * buff, int len, struct opts_t * op, sgj_opaque_p jap)
/* VPD_SCSI_PORTS 0x88 ["sp"] */
static void
-decode_scsi_ports_vpd(uint8_t * buff, int len, struct opts_t * op,
- sgj_opaque_p jap)
+decode_scsi_ports_vpd_4inq(uint8_t * buff, int len, struct opts_t * op,
+ sgj_opaque_p jap)
{
int k, bump, rel_port, ip_tid_len, tpd_len;
uint8_t * bp;
@@ -1949,27 +1957,33 @@ export_dev_ids(uint8_t * buff, int len, int verbose)
/* Sequential access device characteristics, ssc+smc */
/* OSD information, osd */
static void
-decode_b0_vpd(uint8_t * buff, int len, int do_hex)
+decode_b0_vpd(uint8_t * buff, int len, struct opts_t * op, sgj_opaque_p jop)
{
- int pdt;
+ int pdt = PDT_MASK & buff[0];
+ sgj_state * jsp = &op->json_st;
- if (do_hex) {
- hex2stdout(buff, len, (1 == do_hex) ? 0 : -1);
+ if (op->do_hex) {
+ hex2stdout(buff, len, (1 == op->do_hex) ? 0 : -1);
return;
}
- pdt = PDT_MASK & buff[0];
switch (pdt) {
- case PDT_DISK: case PDT_WO: case PDT_OPTICAL: case PDT_ZBC:
- /* done by decode_block_limits_vpd() */
- break;
- case PDT_TAPE: case PDT_MCHANGER:
- printf(" WORM=%d\n", !!(buff[4] & 0x1));
- break;
- case PDT_OSD:
- default:
- printf(" Unable to decode pdt=0x%x, in hex:\n", pdt);
- hex2stdout(buff, len, 0);
- break;
+ case PDT_DISK: case PDT_WO: case PDT_OPTICAL: case PDT_ZBC:
+ /* done by decode_block_limits_vpd() */
+ break;
+ case PDT_TAPE: case PDT_MCHANGER:
+ sgj_haj_vi_nex(jsp, jop, 2, "TSMC", SGJ_SEP_EQUAL_NO_SPACE,
+ !!(buff[4] & 0x2), false, "Tape Stream Mirror "
+ "Capable");
+ sgj_haj_vi_nex(jsp, jop, 2, "WORM", SGJ_SEP_EQUAL_NO_SPACE,
+ !!(buff[4] & 0x1), false, "Write Once Read Multple "
+ "supported");
+
+ break;
+ case PDT_OSD:
+ default:
+ printf(" Unable to decode pdt=0x%x, in hex:\n", pdt);
+ hex2stdout(buff, len, 0);
+ break;
}
}
@@ -2581,82 +2595,6 @@ std_inq_decode(struct opts_t * op, sgj_opaque_p jop, int off)
}
}
-/* When sg_fd >= 0 fetch VPD page from device; mxlen is command line
- * --maxlen=LEN option (def: 0) or -1 for a VPD page with a short length
- * field (1 byte). When sg_fd < 0 then mxlen bytes have been read from
- * --inhex=FN file. Returns 0 for success. */
-static int
-vpd_fetch_page_from_dev(int sg_fd, uint8_t * rp, int page,
- int mxlen, int vb, int * rlenp)
-{
- int res, resid, rlen, len, n;
-
- if (sg_fd < 0) {
- len = sg_get_unaligned_be16(rp + 2) + 4;
- if (vb && (len > mxlen))
- pr2serr("warning: VPD page's length (%d) > bytes in --inhex=FN "
- "file (%d)\n", len , mxlen);
- if (rlenp)
- *rlenp = (len < mxlen) ? len : mxlen;
- return 0;
- }
- if (mxlen > MX_ALLOC_LEN) {
- pr2serr("--maxlen=LEN too long: %d > %d\n", mxlen, MX_ALLOC_LEN);
- return SG_LIB_SYNTAX_ERROR;
- }
- n = (mxlen > 0) ? mxlen : DEF_ALLOC_LEN;
- res = sg_ll_inquiry_v2(sg_fd, true, page, rp, n, DEF_PT_TIMEOUT, &resid,
- true, vb);
- if (res)
- return res;
- rlen = n - resid;
- if (rlen < 4) {
- pr2serr("VPD response too short (len=%d)\n", rlen);
- return SG_LIB_CAT_MALFORMED;
- }
- if (page != rp[1]) {
- pr2serr("invalid VPD response; probably a STANDARD INQUIRY "
- "response\n");
- return SG_LIB_CAT_MALFORMED;
- } else if ((0x80 == page) && (0x2 == rp[2]) && (0x2 == rp[3])) {
- /* could be a Unit Serial number VPD page with a very long
- * length of 4+514 bytes; more likely standard response for
- * SCSI-2, RMB=1 and a response_data_format of 0x2. */
- pr2serr("invalid Unit Serial Number VPD response; probably a "
- "STANDARD INQUIRY response\n");
- return SG_LIB_CAT_MALFORMED;
- }
- if (mxlen < 0)
- len = rp[3] + 4;
- else
- len = sg_get_unaligned_be16(rp + 2) + 4;
- if (len <= rlen) {
- if (rlenp)
- *rlenp = len;
- return 0;
- } else if (mxlen) {
- if (rlenp)
- *rlenp = rlen;
- return 0;
- }
- if (len > MX_ALLOC_LEN) {
- pr2serr("response length too long: %d > %d\n", len, MX_ALLOC_LEN);
- return SG_LIB_CAT_MALFORMED;
- } else {
- /* First response indicated that not enough bytes of response were
- * requested, so try again, this time requesting more. */
- res = sg_ll_inquiry_v2(sg_fd, true, page, rp, len, DEF_PT_TIMEOUT,
- &resid, true, vb);
- if (res)
- return res;
- rlen = len - resid;
- /* assume it is well behaved: hence page and len still same */
- if (rlenp)
- *rlenp = rlen;
- return 0;
- }
-}
-
/* Returns 0 if Unit Serial Number VPD page contents found, else see
* sg_ll_inquiry_v2() return values */
static int
@@ -2671,22 +2609,22 @@ fetch_unit_serial_num(int sg_fd, char * obuff, int obuff_len, int verbose)
pr2serr("%s: unable to allocate on heap\n", __func__);
return sg_convert_errno(ENOMEM);
}
- res = vpd_fetch_page_from_dev(sg_fd, b, VPD_SUPPORTED_VPDS,
- -1 /* 1 byte alloc_len */, verbose, &len);
+ res = vpd_fetch_page(sg_fd, b, VPD_SUPPORTED_VPDS,
+ -1 /* 1 byte alloc_len */, false, verbose, &len);
if (res) {
if (verbose > 2)
pr2serr("%s: no supported VPDs page\n", __func__);
res = SG_LIB_CAT_MALFORMED;
goto fini;
}
- if (vpd_page_not_supported(b, len, VPD_UNIT_SERIAL_NUM, verbose)) {
+ if (! vpd_page_is_supported(b, len, VPD_UNIT_SERIAL_NUM, verbose)) {
res = sg_convert_errno(EDOM); /* was SG_LIB_CAT_ILLEGAL_REQ */
goto fini;
}
memset(b, 0xff, 4); /* guard against empty response */
- res = vpd_fetch_page_from_dev(sg_fd, b, VPD_UNIT_SERIAL_NUM, -1, verbose,
- &len);
+ res = vpd_fetch_page(sg_fd, b, VPD_UNIT_SERIAL_NUM, -1, false, verbose,
+ &len);
if ((0 == res) && (len > 3)) {
len -= 4;
len = (len < (obuff_len - 1)) ? len : (obuff_len - 1);
@@ -2947,15 +2885,15 @@ vpd_mainly_hex(int sg_fd, struct opts_t * op, sgj_opaque_p jap, int off)
res = 0;
} else {
memset(rp, 0, DEF_ALLOC_LEN);
- res = vpd_fetch_page_from_dev(sg_fd, rp, op->vpd_pn, op->maxlen,
- op->verbose, &len);
+ res = vpd_fetch_page(sg_fd, rp, op->vpd_pn, op->maxlen,
+ op->do_quiet, op->verbose, &len);
}
if (0 == res) {
if (op->do_raw)
dStrRaw((const char *)rp, len);
else {
if (0 == op->vpd_pn)
- decode_supported_vpd(rp, len, op, jap);
+ decode_supported_vpd_4inq(rp, len, op, jap);
else {
if (op->verbose) {
cp = sg_get_pdt_str(rp[0] & PDT_MASK, sizeof(b), b);
@@ -2988,6 +2926,7 @@ static int
vpd_decode(int sg_fd, struct opts_t * op, sgj_opaque_p jop, int off)
{
bool bad = false;
+ bool qt = op->do_quiet;
int len, pdt, pn, vb /*, pqual */;
int res = 0;
sgj_state * jsp = &op->json_st;
@@ -3005,11 +2944,11 @@ vpd_decode(int sg_fd, struct opts_t * op, sgj_opaque_p jop, int off)
else
pn = op->vpd_pn;
if (sg_fd != -1 && !op->do_force && pn != VPD_SUPPORTED_VPDS) {
- res = vpd_fetch_page_from_dev(sg_fd, rp, VPD_SUPPORTED_VPDS,
- op->maxlen, vb, &len);
+ res = vpd_fetch_page(sg_fd, rp, VPD_SUPPORTED_VPDS, op->maxlen,
+ qt, vb, &len);
if (res)
goto out;
- if (vpd_page_not_supported(rp, len, pn, vb)) {
+ if (! vpd_page_is_supported(rp, len, pn, vb)) {
if (vb)
pr2serr("Given VPD page not in supported list, use --force "
"to override this check\n");
@@ -3022,7 +2961,7 @@ vpd_decode(int sg_fd, struct opts_t * op, sgj_opaque_p jop, int off)
np = "Supported VPD pages 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);
+ res = vpd_fetch_page(sg_fd, rp, pn, op->maxlen, qt, vb, &len);
if (res)
break;
if (op->do_raw)
@@ -3035,14 +2974,14 @@ vpd_decode(int sg_fd, struct opts_t * op, sgj_opaque_p jop, int off)
jap = sgj_named_subarray_r(jsp, jo2p,
"supported_vpd_page_list");
}
- decode_supported_vpd(rp, len, op, jap);
+ decode_supported_vpd_4inq(rp, len, op, jap);
}
break;
case VPD_UNIT_SERIAL_NUM: /* 0x80 ["sn"] */
np = "Unit serial number VPD page";
if (! op->do_raw && ! op->do_export && (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);
+ res = vpd_fetch_page(sg_fd, rp, pn, op->maxlen, qt, vb, &len);
if (res)
break;
if (op->do_raw)
@@ -3089,7 +3028,7 @@ vpd_decode(int sg_fd, struct opts_t * op, sgj_opaque_p jop, int off)
np = "Device Identification VPD page";
if (! op->do_raw && ! op->do_export && (op->do_hex < 3))
sgj_pr_hr(jsp, "VPD INQUIRY: %s\n", np);
- res = vpd_fetch_page_from_dev(sg_fd, rp, pn, op->maxlen, vb, &len);
+ res = vpd_fetch_page(sg_fd, rp, pn, op->maxlen, qt, vb, &len);
if (res)
break;
if (op->do_raw)
@@ -3111,7 +3050,7 @@ vpd_decode(int sg_fd, struct opts_t * op, sgj_opaque_p jop, int off)
np = "Software interface identification 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);
+ res = vpd_fetch_page(sg_fd, rp, pn, op->maxlen, qt, vb, &len);
if (res)
break;
if (op->do_raw)
@@ -3129,7 +3068,7 @@ vpd_decode(int sg_fd, struct opts_t * op, sgj_opaque_p jop, int off)
np = "Management network addresses 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);
+ res = vpd_fetch_page(sg_fd, rp, pn, op->maxlen, qt, vb, &len);
if (res)
break;
if (op->do_raw)
@@ -3150,7 +3089,7 @@ vpd_decode(int sg_fd, struct opts_t * op, sgj_opaque_p jop, int off)
np = "Extended INQUIRY data";
if (!op->do_raw && (op->do_hex < 2))
sgj_pr_hr(jsp, "VPD INQUIRY: %s page\n", np);
- res = vpd_fetch_page_from_dev(sg_fd, rp, pn, op->maxlen, vb, &len);
+ res = vpd_fetch_page(sg_fd, rp, pn, op->maxlen, qt, vb, &len);
if (res)
break;
if (op->do_raw)
@@ -3165,7 +3104,7 @@ vpd_decode(int sg_fd, struct opts_t * op, sgj_opaque_p jop, int off)
np = "Mode page policy";
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);
+ res = vpd_fetch_page(sg_fd, rp, pn, op->maxlen, qt, vb, &len);
if (res)
break;
if (op->do_raw)
@@ -3183,7 +3122,7 @@ vpd_decode(int sg_fd, struct opts_t * op, sgj_opaque_p jop, int off)
np = "SCSI Ports 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);
+ res = vpd_fetch_page(sg_fd, rp, pn, op->maxlen, qt, vb, &len);
if (res)
break;
if (op->do_raw)
@@ -3194,14 +3133,14 @@ vpd_decode(int sg_fd, struct opts_t * op, sgj_opaque_p jop, int off)
jap = sgj_named_subarray_r(jsp, jo2p,
"scsi_ports_descriptor_list");
}
- decode_scsi_ports_vpd(rp, len, op, jap);
+ decode_scsi_ports_vpd_4inq(rp, len, op, jap);
}
break;
case VPD_ATA_INFO: /* 0x89 ["ai"] */
np = "ATA information 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);
+ res = vpd_fetch_page(sg_fd, rp, pn, op->maxlen, qt, vb, &len);
if (res)
break;
/* format output for 'hdparm --Istdin' with '-rr' or '-HHH' */
@@ -3222,7 +3161,7 @@ vpd_decode(int sg_fd, struct opts_t * op, sgj_opaque_p jop, int off)
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);
+ res = vpd_fetch_page(sg_fd, rp, pn, op->maxlen, qt, vb, &len);
if (res)
break;
if (op->do_raw)
@@ -3237,7 +3176,7 @@ vpd_decode(int sg_fd, struct opts_t * op, sgj_opaque_p jop, int off)
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);
+ res = vpd_fetch_page(sg_fd, rp, pn, op->maxlen, qt, vb, &len);
if (res)
break;
if (op->do_raw)
@@ -3248,14 +3187,14 @@ vpd_decode(int sg_fd, struct opts_t * op, sgj_opaque_p jop, int off)
jap = sgj_named_subarray_r(jsp, jo2p,
"power_consumption_descriptor_list");
}
- decode_power_consumption(rp, len, jop, jap);
+ decode_power_consumption(rp, len, op, jap);
}
break;
case VPD_DEVICE_CONSTITUENTS: /* 0x8b ["dc"] */
np = "Device constituents page 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);
+ res = vpd_fetch_page(sg_fd, rp, pn, op->maxlen, qt, vb, &len);
if (res)
break;
if (op->do_raw)
@@ -3273,7 +3212,7 @@ vpd_decode(int sg_fd, struct opts_t * op, sgj_opaque_p jop, int off)
np = "Third party copy 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);
+ res = vpd_fetch_page(sg_fd, rp, pn, op->maxlen, qt, vb, &len);
if (res)
break;
if (op->do_raw)
@@ -3291,7 +3230,7 @@ vpd_decode(int sg_fd, struct opts_t * op, sgj_opaque_p jop, int off)
np = "Protocol specific logical unit information 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);
+ res = vpd_fetch_page(sg_fd, rp, pn, op->maxlen, qt, vb, &len);
if (res)
break;
if (op->do_raw)
@@ -3309,7 +3248,7 @@ vpd_decode(int sg_fd, struct opts_t * op, sgj_opaque_p jop, int off)
np = "Protocol specific port information 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);
+ res = vpd_fetch_page(sg_fd, rp, pn, op->maxlen, qt, vb, &len);
if (res)
break;
if (op->do_raw)
@@ -3327,7 +3266,7 @@ vpd_decode(int sg_fd, struct opts_t * op, sgj_opaque_p jop, int off)
np = "SCSI Feature sets 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);
+ res = vpd_fetch_page(sg_fd, rp, pn, op->maxlen, qt, vb, &len);
if (res)
break;
if (op->do_raw)
@@ -3343,7 +3282,7 @@ vpd_decode(int sg_fd, struct opts_t * op, sgj_opaque_p jop, int off)
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);
+ res = vpd_fetch_page(sg_fd, rp, pn, op->maxlen, qt, vb, &len);
if (0 == res) {
bool bl = false;
bool sad = false;
@@ -3385,13 +3324,13 @@ vpd_decode(int sg_fd, struct opts_t * op, sgj_opaque_p jop, int off)
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 (sad || oi)
+ decode_b0_vpd(rp, len, op, jop);
} else if (! op->do_raw)
pr2serr("VPD INQUIRY: page=0xb0\n");
break;
case 0xb1: /* VPD pages in B0h to BFh range depend on pdt */
- res = vpd_fetch_page_from_dev(sg_fd, rp, pn, op->maxlen, vb, &len);
+ res = vpd_fetch_page(sg_fd, rp, pn, op->maxlen, qt, vb, &len);
if (0 == res) {
bool bdc = false;
static const char * masn =
@@ -3441,7 +3380,7 @@ vpd_decode(int sg_fd, struct opts_t * op, sgj_opaque_p jop, int off)
pr2serr("VPD INQUIRY: page=0xb1\n");
break;
case 0xb2: /* VPD pages in B0h to BFh range depend on pdt */
- res = vpd_fetch_page_from_dev(sg_fd, rp, pn, op->maxlen, vb, &len);
+ res = vpd_fetch_page(sg_fd, rp, pn, op->maxlen, qt, vb, &len);
if (0 == res) {
bool lbpv = false;
@@ -3487,7 +3426,7 @@ xxxxx
return vpd_mainly_hex(sg_fd, op, NULL, off);
#endif
case 0xb3:
- res = vpd_fetch_page_from_dev(sg_fd, rp, pn, op->maxlen, vb, &len);
+ res = vpd_fetch_page(sg_fd, rp, pn, op->maxlen, qt, vb, &len);
if (0 == res) {
bool ref = false;
@@ -3523,7 +3462,7 @@ xxxxx
pr2serr("VPD INQUIRY: page=0xb3\n");
break;
case 0xb4:
- res = vpd_fetch_page_from_dev(sg_fd, rp, pn, op->maxlen, vb, &len);
+ res = vpd_fetch_page(sg_fd, rp, pn, op->maxlen, qt, vb, &len);
if (0 == res) {
bool sbl = false;
@@ -3562,7 +3501,7 @@ xxxxx
pr2serr("VPD INQUIRY: page=0xb4\n");
break;
case 0xb5:
- res = vpd_fetch_page_from_dev(sg_fd, rp, pn, op->maxlen, vb, &len);
+ res = vpd_fetch_page(sg_fd, rp, pn, op->maxlen, qt, vb, &len);
if (0 == res) {
bool bdce = false;
@@ -3598,7 +3537,7 @@ xxxxx
pr2serr("VPD INQUIRY: page=0xb5\n");
break;
case 0xb6:
- res = vpd_fetch_page_from_dev(sg_fd, rp, pn, op->maxlen, vb, &len);
+ res = vpd_fetch_page(sg_fd, rp, pn, op->maxlen, qt, vb, &len);
if (0 == res) {
bool zbdch = false;
@@ -3634,7 +3573,7 @@ xxxxx
pr2serr("VPD INQUIRY: page=0xb6\n");
break;
case 0xb7:
- res = vpd_fetch_page_from_dev(sg_fd, rp, pn, op->maxlen, vb, &len);
+ res = vpd_fetch_page(sg_fd, rp, pn, op->maxlen, qt, vb, &len);
if (0 == res) {
bool ble = false;
@@ -3670,7 +3609,7 @@ xxxxx
pr2serr("VPD INQUIRY: page=0xb7\n");
break;
case 0xb8:
- res = vpd_fetch_page_from_dev(sg_fd, rp, pn, op->maxlen, vb, &len);
+ res = vpd_fetch_page(sg_fd, rp, pn, op->maxlen, qt, vb, &len);
if (0 == res) {
bool fp = false;
@@ -3709,7 +3648,7 @@ xxxxx
pr2serr("VPD INQUIRY: page=0xb8\n");
break;
case 0xb9:
- res = vpd_fetch_page_from_dev(sg_fd, rp, pn, op->maxlen, vb, &len);
+ res = vpd_fetch_page(sg_fd, rp, pn, op->maxlen, qt, vb, &len);
if (0 == res) {
bool cpr = false;
@@ -3751,7 +3690,7 @@ xxxxx
case VPD_UPR_EMC: /* 0xc0 */
if (!op->do_raw && (op->do_hex < 2))
printf("VPD INQUIRY: Unit Path Report Page (EMC)\n");
- res = vpd_fetch_page_from_dev(sg_fd, rp, pn, -1, vb, &len);
+ res = vpd_fetch_page(sg_fd, rp, pn, -1, qt, vb, &len);
if (res)
break;
if (op->do_raw)
@@ -3762,7 +3701,7 @@ xxxxx
case VPD_RDAC_VERS: /* 0xc2 */
if (!op->do_raw && (op->do_hex < 2))
printf("VPD INQUIRY: Software Version (RDAC)\n");
- res = vpd_fetch_page_from_dev(sg_fd, rp, pn, -1, vb, &len);
+ res = vpd_fetch_page(sg_fd, rp, pn, -1, qt, vb, &len);
if (res)
break;
if (op->do_raw)
@@ -3773,7 +3712,7 @@ xxxxx
case VPD_RDAC_VAC: /* 0xc9 */
if (!op->do_raw && (op->do_hex < 2))
printf("VPD INQUIRY: Volume Access Control (RDAC)\n");
- res = vpd_fetch_page_from_dev(sg_fd, rp, pn, -1, vb, &len);
+ res = vpd_fetch_page(sg_fd, rp, pn, -1, qt, vb, &len);
if (res)
break;
if (op->do_raw)
@@ -3790,7 +3729,7 @@ xxxxx
if (!op->do_raw && (op->do_hex < 2))
printf("VPD INQUIRY: ASCII information page, FRU code=0x%x\n",
pn);
- res = vpd_fetch_page_from_dev(sg_fd, rp, pn, op->maxlen, vb, &len);
+ res = vpd_fetch_page(sg_fd, rp, pn, op->maxlen, qt, vb, &len);
if (0 == res) {
if (op->do_raw)
dStrRaw((const char *)rp, len);
@@ -4197,18 +4136,20 @@ main(int argc, char * argv[])
int res, n, err;
int sg_fd = -1;
int ret = 0;
+ int subvalue = 0;
int inhex_len = 0;
int inraw_len = 0;
+ const char * cp;
const struct svpd_values_name_t * vnp;
sgj_state * jsp;
sgj_opaque_p jop = NULL;
- struct opts_t opts;
+ struct opts_t opts SG_C_CPP_ZERO_INIT;
struct opts_t * op;
op = &opts;
- memset(op, 0, sizeof(opts));
op->invoker = SG_VPD_INV_SG_INQ;
op->vpd_pn = -1;
+ op->vend_prod_num = -1;
op->page_pdt = -1;
op->do_block = -1; /* use default for OS */
res = parse_cmd_line(op, argc, argv);
@@ -4243,13 +4184,17 @@ main(int argc, char * argv[])
pr2serr("Version string: %s\n", version_str);
return 0;
}
+ jsp = &op->json_st;
+ as_json = jsp->pr_as_json;
if (op->page_str) {
if (op->vpd_pn >= 0) {
pr2serr("Given '-p' option and another option that "
"implies a page\n");
return SG_LIB_CONTRADICT;
}
- if (isalpha((uint8_t)op->page_str[0])) {
+ if ('-' == op->page_str[0])
+ op->vpd_pn = VPD_NOPE_WANT_STD_INQ;
+ else if (isalpha((uint8_t)op->page_str[0])) {
vnp = sdp_find_vpd_by_acron(op->page_str);
if (NULL == vnp) {
#ifdef SG_SCSI_STRINGS
@@ -4270,9 +4215,58 @@ main(int argc, char * argv[])
if ((1 != op->do_hex) && (0 == op->do_raw))
op->do_decode = true;
op->vpd_pn = vnp->value;
+ subvalue = vnp->subvalue;
op->page_pdt = vnp->pdt;
- } else if ('-' == op->page_str[0])
- op->vpd_pn = VPD_NOPE_WANT_STD_INQ;
+ } else {
+ cp = strchr(op->page_str, ',');
+ if (cp && op->vend_prod) {
+ pr2serr("the --page=pg,vp and the --vendor=vp forms overlap, "
+ "choose one or the other\n");
+ ret = SG_LIB_SYNTAX_ERROR;
+ goto err_out;
+ }
+ op->vpd_pn = sg_get_num_nomult(op->page_str);
+ if ((op->vpd_pn < 0) || (op->vpd_pn > 255)) {
+ pr2serr("Bad page code value after '-p' option\n");
+ printf("Available standard VPD pages:\n");
+ enumerate_vpds(/* 1, 1 */);
+ ret = SG_LIB_SYNTAX_ERROR;
+ goto err_out;
+ }
+ if (cp) {
+ if (isdigit((uint8_t)*(cp + 1)))
+ op->vend_prod_num = sg_get_num_nomult(cp + 1);
+ else
+ op->vend_prod_num = svpd_find_vp_num_by_acron(cp + 1);
+ if ((op->vend_prod_num < 0) || (op->vend_prod_num > 255)) {
+ pr2serr("Bad vendor/product acronym after comma in '-p' "
+ "option\n");
+ if (op->vend_prod_num < 0)
+ svpd_enumerate_vendor(-1);
+ ret = SG_LIB_SYNTAX_ERROR;
+ goto err_out;
+ }
+ subvalue = op->vend_prod_num;
+ } else if (op->vend_prod) {
+ if (isdigit((uint8_t)op->vend_prod[0]))
+ op->vend_prod_num = sg_get_num_nomult(op->vend_prod);
+ else
+ op->vend_prod_num =
+ svpd_find_vp_num_by_acron(op->vend_prod);
+ if ((op->vend_prod_num < 0) || (op->vend_prod_num > 255)) {
+ pr2serr("Bad vendor/product acronym after '--vendor=' "
+ "option\n");
+ svpd_enumerate_vendor(-1);
+ ret = SG_LIB_SYNTAX_ERROR;
+ goto err_out;
+ }
+ subvalue = op->vend_prod_num;
+ }
+ }
+ if (op->verbose > 3)
+ pr2serr("'--page=' matched pn=%d [0x%x], subvalue=%d\n",
+ op->vpd_pn, op->vpd_pn, subvalue);
+#if 0
else {
#ifdef SG_SCSI_STRINGS
if (op->opt_new) {
@@ -4311,9 +4305,21 @@ main(int argc, char * argv[])
#endif /* SG_SCSI_STRINGS */
op->vpd_pn = n;
}
+#endif
+ } else if (op->vend_prod) {
+ if (isdigit((uint8_t)op->vend_prod[0]))
+ op->vend_prod_num = sg_get_num_nomult(op->vend_prod);
+ else
+ op->vend_prod_num = svpd_find_vp_num_by_acron(op->vend_prod);
+ if ((op->vend_prod_num < 0) || (op->vend_prod_num > 255)) {
+ pr2serr("Bad vendor/product acronym after '--vendor=' "
+ "option\n");
+ svpd_enumerate_vendor(-1);
+ ret = SG_LIB_SYNTAX_ERROR;
+ goto err_out;
+ }
+ subvalue = op->vend_prod_num;
}
- jsp = &op->json_st;
- as_json = jsp->pr_as_json;
if (as_json)
jop = sgj_start_r(MY_NAME, version_str, argc, argv, jsp);