aboutsummaryrefslogtreecommitdiff
path: root/src/sg_vpd.c
diff options
context:
space:
mode:
authorDouglas Gilbert <dgilbert@interlog.com>2020-11-17 02:16:17 +0000
committerDouglas Gilbert <dgilbert@interlog.com>2020-11-17 02:16:17 +0000
commitf277836fbdf1af79ef905fa357609f0e45db99dc (patch)
treec0de5bba8314d1b9ab969e96fcca1804776e8d1b /src/sg_vpd.c
parent6276daf9b89e1d27b91438ff1e92482a1d2e7179 (diff)
downloadsg3_utils-f277836fbdf1af79ef905fa357609f0e45db99dc.tar.gz
sg_vpd: add Format presets and Concurrent positioning ranges pages; sg_inq+sg_vpd: add hot-pluggable field in standard Inquiry
git-svn-id: https://svn.bingwo.ca/repos/sg3_utils/trunk@867 6180dd3e-e324-4e3e-922d-17de1ae2f315
Diffstat (limited to 'src/sg_vpd.c')
-rw-r--r--src/sg_vpd.c150
1 files changed, 146 insertions, 4 deletions
diff --git a/src/sg_vpd.c b/src/sg_vpd.c
index f088330c..69919dec 100644
--- a/src/sg_vpd.c
+++ b/src/sg_vpd.c
@@ -40,7 +40,7 @@
*/
-static const char * version_str = "1.60 20200501"; /* spc6r01 + sbc4r20a */
+static const char * version_str = "1.61 20201114"; /* spc6r02 + sbc4r22 */
/* standard VPD pages, in ascending page number order */
#define VPD_SUPPORTED_VPDS 0x0
@@ -79,6 +79,7 @@ static const char * version_str = "1.60 20200501"; /* spc6r01 + sbc4r20a */
#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 /* 20-089r2 */
#define VPD_NOPE_WANT_STD_INQ -2 /* request for standard inquiry */
/* Device identification VPD page associations */
@@ -198,6 +199,7 @@ static struct svpd_values_name_t standard_vpd_pg[] = {
{VPD_BLOCK_DEV_C_EXTENS, 0, 0, "bdce", "Block device characteristics "
"extension (SBC)"},
{VPD_CFA_PROFILE_INFO, 0, 0, "cfa", "CFA profile information"},
+ {VPD_CON_POS_RANGE, 0, 0, "cpr", "Concurrent positioning ranges"},
{VPD_DEVICE_CONSTITUENTS, 0, -1, "dc", "Device constituents"},
{VPD_DEVICE_ID, 0, -1, "di", "Device identification"},
{VPD_DEVICE_ID, VPD_DI_SEL_AS_IS, -1, "di_asis", "Like 'di' "
@@ -500,9 +502,9 @@ std_inq_decode(uint8_t * b, int len, int verbose)
printf(" [PQ indicates LU not accessible via this port]\n");
else
printf(" [reserved or vendor specific qualifier [%d]]\n", pqual);
- printf(" PQual=%d Device_type=%d RMB=%d LU_CONG=%d version=0x%02x ",
- pqual, b[0] & 0x1f, !!(b[1] & 0x80), !!(b[1] & 0x40),
- (unsigned int)b[2]);
+ printf(" PQual=%d PDT=%d RMB=%d LU_CONG=%d hot_pluggable=%d "
+ "version=0x%02x ", pqual, b[0] & 0x1f, !!(b[1] & 0x80),
+ !!(b[1] & 0x40), (b[1] >> 4) & 0x3, (unsigned int)b[2]);
printf(" [%s]\n", sg_ansi_version_arr[b[2] & 0xf]);
printf(" [AERC=%d] [TrmTsk=%d] NormACA=%d HiSUP=%d "
" Resp_data_format=%d\n",
@@ -2646,6 +2648,84 @@ decode_b7_vpd(uint8_t * buff, int len, int do_hex, int pdt)
}
}
+/* VPD_FORMAT_PRESETS 0xb8 (added sbc4r18) */
+static void
+decode_format_presets_vpd(uint8_t * buff, int len, bool do_hex)
+{
+ int k;
+ unsigned int sch_type;
+ uint8_t * bp;
+
+ if (do_hex) {
+ hex2stdout(buff, len, (1 == do_hex) ? 0 : -1);
+ return;
+ }
+ if (len < 4) {
+ pr2serr("Format presets VPD page length too short=%d\n", len);
+ return;
+ }
+ len -= 4;
+ bp = buff + 4;
+ for (k = 0; k < len; k += 64, bp += 64) {
+ printf(" Preset identifier: 0x%x\n", sg_get_unaligned_be32(bp));
+ sch_type = bp[4];
+ printf(" schema type: %u\n", sch_type);
+ printf(" logical blocks per physical block exponent type: %u\n",
+ 0xf & bp[7]);
+ printf(" logical block length: %u\n",
+ sg_get_unaligned_be32(bp + 8));
+ printf(" designed last LBA: 0x%" PRIx64 "\n",
+ sg_get_unaligned_be64(bp + 16));
+ printf(" FMPT_INFO: %u\n", (bp[38] >> 6) & 0x3);
+ printf(" protection field usage: %u\n", bp[38] & 0x7);
+ printf(" protection interval exponent: %u\n", bp[39] & 0xf);
+ if (2 == sch_type)
+ printf(" Defines zones for host aware device:\n");
+ else if (3 == sch_type)
+ printf(" Defines zones for host managed device:\n");
+ if ((2 == sch_type) || (3 == sch_type)) {
+ unsigned int u = bp[40 + 0];
+
+ printf(" low LBA conventional zones percentage: "
+ "%u.%u %%\n", u / 10, u % 10);
+ u = bp[40 + 1];
+ printf(" high LBA conventional zones percentage: "
+ "%u.%u %%\n", u / 10, u % 10);
+ printf(" logical blocks per zone: %u\n",
+ sg_get_unaligned_be32(bp + 40 + 12));
+ }
+ }
+}
+
+/* VPD_CON_POS_RANGE 0xb9 (added 20-089r2) */
+static void
+decode_con_pos_range_vpd(uint8_t * buff, int len, bool do_hex)
+{
+ int k;
+ uint64_t u;
+ uint8_t * bp;
+
+ if (do_hex) {
+ hex2stdout(buff, len, (1 == do_hex) ? 0 : -1);
+ return;
+ }
+ if (len < 64) {
+ pr2serr("Concurrent position ranges VPD page length too short=%d\n",
+ len);
+ return;
+ }
+ len -= 64;
+ bp = buff + 64;
+ for (k = 0; k < len; k += 32, bp += 32) {
+ printf(" LBA range number: %u\n", bp[0]);
+ printf(" number of storage elements: %u\n", bp[1]);
+ printf(" starting LBA: 0x%" PRIx64 "\n",
+ sg_get_unaligned_be64(bp + 8));
+ u = sg_get_unaligned_be64(bp + 16);
+ printf(" number of LBAs: 0x%" PRIx64 " [%" PRIu64 "]\n", u, u);
+ }
+}
+
/* Returns 0 if successful */
static int
svpd_unable_to_decode(int sg_fd, struct opts_t * op, int subvalue, int off)
@@ -3431,6 +3511,68 @@ svpd_decode_t10(int sg_fd, struct opts_t * op, int subvalue, int off,
(0 == op->examine))
printf("%sVPD page=0xb7\n", pre);
break;
+ case 0xb8: /* VPD_FORMAT_PRESETS */
+ res = vpd_fetch_page(sg_fd, rp, pn, op->maxlen, qt, vb, &len);
+ if (0 == res) {
+ pdt = rp[0] & 0x1f;
+ switch (pdt) {
+ case PDT_DISK: case PDT_WO: case PDT_OPTICAL: case PDT_ZBC:
+ np = "Format presets VPD page (SBC):";
+ break;
+ default:
+ np = NULL;
+ break;
+ }
+ if (NULL == np)
+ printf("VPD page=0x%x, pdt=0x%x:\n", pn, pdt);
+ else if (allow_name || allow_if_found)
+ printf("%s%s\n", pre, np);
+ if (op->do_raw)
+ dStrRaw(rp, len);
+ else {
+ pdt = rp[0] & 0x1f;
+ if (vb || long_notquiet)
+ printf(" [PQual=%d Peripheral device type: %s]\n",
+ (rp[0] & 0xe0) >> 5,
+ sg_get_pdt_str(pdt, sizeof(b), b));
+ decode_format_presets_vpd(rp, len, op->do_hex);
+ }
+ return 0;
+ } else if ((! op->do_raw) && (! op->do_quiet) && (op->do_hex < 3) &&
+ (0 == op->examine))
+ printf("%sVPD page=0xb7\n", pre);
+ break;
+ case 0xb9: /* VPD_CON_POS_RANGE */
+ res = vpd_fetch_page(sg_fd, rp, pn, op->maxlen, qt, vb, &len);
+ if (0 == res) {
+ pdt = rp[0] & 0x1f;
+ switch (pdt) {
+ case PDT_DISK: case PDT_WO: case PDT_OPTICAL: case PDT_ZBC:
+ np = "Concurrent positioning ranges VPD page (SBC):";
+ break;
+ default:
+ np = NULL;
+ break;
+ }
+ if (NULL == np)
+ printf("VPD page=0x%x, pdt=0x%x:\n", pn, pdt);
+ else if (allow_name || allow_if_found)
+ printf("%s%s\n", pre, np);
+ if (op->do_raw)
+ dStrRaw(rp, len);
+ else {
+ pdt = rp[0] & 0x1f;
+ if (vb || long_notquiet)
+ printf(" [PQual=%d Peripheral device type: %s]\n",
+ (rp[0] & 0xe0) >> 5,
+ sg_get_pdt_str(pdt, sizeof(b), b));
+ decode_con_pos_range_vpd(rp, len, op->do_hex);
+ }
+ return 0;
+ } else if ((! op->do_raw) && (! op->do_quiet) && (op->do_hex < 3) &&
+ (0 == op->examine))
+ printf("%sVPD page=0xb7\n", pre);
+ break;
default:
return SG_LIB_CAT_OTHER;
}