aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDouglas Gilbert <dgilbert@interlog.com>2007-10-05 04:47:38 +0000
committerDouglas Gilbert <dgilbert@interlog.com>2007-10-05 04:47:38 +0000
commita1d15c35ce45754c109aed26595752c64ffef921 (patch)
treef3866e7ebc309363f53e93e64c8ecca944dd5b77 /src
parent86b71f28e0496ad7a4b44ba58af9c6c9ec8eed83 (diff)
downloadsg3_utils-a1d15c35ce45754c109aed26595752c64ffef921.tar.gz
add TPROTO_* to sg_lib.h; protocol-specific lu info VPD page
git-svn-id: https://svn.bingwo.ca/repos/sg3_utils/trunk@111 6180dd3e-e324-4e3e-922d-17de1ae2f315
Diffstat (limited to 'src')
-rw-r--r--src/sg_inq.c34
-rw-r--r--src/sg_modes.c10
-rw-r--r--src/sg_persist.c19
-rw-r--r--src/sg_ses.c6
-rw-r--r--src/sg_vpd.c306
-rw-r--r--src/sg_vpd_vendor.c2
6 files changed, 282 insertions, 95 deletions
diff --git a/src/sg_inq.c b/src/sg_inq.c
index 9bca6187..9d3770c3 100644
--- a/src/sg_inq.c
+++ b/src/sg_inq.c
@@ -78,6 +78,8 @@ static char * version_str = "0.70 20070919"; /* spc-4 rev 11 */
#define VPD_MODE_PG_POLICY 0x87
#define VPD_SCSI_PORTS 0x88
#define VPD_ATA_INFO 0x89
+#define VPD_PROTO_LU 0x90
+#define VPD_PROTO_PORT 0x91
#define VPD_BLOCK_LIMITS 0xb0
#define VPD_BLOCK_DEV_CHARS 0xb1
#define VPD_UPR_EMC 0xc0
@@ -118,7 +120,7 @@ struct svpd_values_name_t {
int subvalue;
int pdt; /* peripheral device type id, -1 is the default */
/* (all or not applicable) value */
- int ro_vendor; /* read-only or vendor flag */
+ int vendor; /* vendor flag */
const char * acron;
const char * name;
};
@@ -142,13 +144,16 @@ static struct svpd_values_name_t vpd_pg[] = {
{VPD_EXT_INQ, 0, -1, 0, "ei", "Extended inquiry data"},
{VPD_MAN_NET_ADDR, 0, -1, 0, "mna", "Management network addresses"},
{VPD_MODE_PG_POLICY, 0, -1, 0, "mpp", "Mode page policy"},
+ {VPD_PROTO_LU, 0, 0x0, 0, "pslu", "Protocol-specific logical unit "
+ "information"},
+ {VPD_PROTO_PORT, 0, 0x0, 0, "pspo", "Protocol-specific port information"},
{VPD_SOFTW_INF_ID, 0, -1, 0, "sii", "Software interface identification"},
{VPD_UNIT_SERIAL_NUM, 0, -1, 0, "sn", "Unit serial number"},
{VPD_SCSI_PORTS, 0, -1, 0, "sp", "SCSI ports"},
{VPD_SUPPORTED_VPDS, 0, -1, 0, "sv", "Supported VPD pages"},
- {VPD_UPR_EMC, 0, -1, 0, "upr", "Unit path report (EMC)"},
- {VPD_RDAC_VERS, 0, -1, 0, "rdac_vers", "RDAC software version (IBM)"},
- {VPD_RDAC_VAC, 0, -1, 0, "rdac_vac", "RDAC volume access control (IBM)"},
+ {VPD_RDAC_VAC, 0, -1, 1, "rdac_vac", "RDAC volume access control (IBM)"},
+ {VPD_RDAC_VERS, 0, -1, 1, "rdac_vers", "RDAC software version (IBM)"},
+ {VPD_UPR_EMC, 0, -1, 1, "upr", "Unit path report (EMC)"},
{0, 0, 0, 0, NULL, NULL},
};
@@ -592,7 +597,7 @@ static void enumerate_vpds()
const struct svpd_values_name_t * vnp;
for (vnp = vpd_pg; vnp->acron; ++vnp) {
- if (vnp->name && (0 == vnp->ro_vendor))
+ if (vnp->name)
printf(" %-10s 0x%02x %s\n", vnp->acron, vnp->value,
vnp->name);
}
@@ -1132,7 +1137,7 @@ static void decode_transport_id(const char * leadin, unsigned char * ucp,
format_code = ((ucp[0] >> 6) & 0x3);
proto_id = (ucp[0] & 0xf);
switch (proto_id) {
- case 0: /* Fibre channel */
+ case TPROTO_FCP:
printf("%s FCP-2 World Wide Name:\n", leadin);
if (0 != format_code)
printf("%s [Unexpected format code: %d]\n", leadin,
@@ -1140,7 +1145,7 @@ static void decode_transport_id(const char * leadin, unsigned char * ucp,
dStrHex((const char *)&ucp[8], 8, 0);
bump = 24;
break;
- case 1: /* Parallel SCSI */
+ case TPROTO_SPI:
printf("%s Parallel SCSI initiator SCSI address: 0x%x\n",
leadin, ((ucp[2] << 8) | ucp[3]));
if (0 != format_code)
@@ -1150,13 +1155,13 @@ static void decode_transport_id(const char * leadin, unsigned char * ucp,
"0x%x\n", leadin, ((ucp[6] << 8) | ucp[7]));
bump = 24;
break;
- case 2: /* SSA */
+ case TPROTO_SSA: /* SSA */
printf("%s SSA (transport id not defined):\n", leadin);
printf("%s format code: %d\n", leadin, format_code);
dStrHex((const char *)ucp, ((len > 24) ? 24 : len), 0);
bump = 24;
break;
- case 3: /* IEEE 1394 */
+ case TPROTO_1394:
printf("%s IEEE 1394 EUI-64 name:\n", leadin);
if (0 != format_code)
printf("%s [Unexpected format code: %d]\n", leadin,
@@ -1164,7 +1169,7 @@ static void decode_transport_id(const char * leadin, unsigned char * ucp,
dStrHex((const char *)&ucp[8], 8, 0);
bump = 24;
break;
- case 4: /* Remote Direct Memory Access (RDMA) */
+ case TPROTO_SRP:
printf("%s RDMA initiator port identifier:\n", leadin);
if (0 != format_code)
printf("%s [Unexpected format code: %d]\n", leadin,
@@ -1172,7 +1177,7 @@ static void decode_transport_id(const char * leadin, unsigned char * ucp,
dStrHex((const char *)&ucp[8], 16, 0);
bump = 24;
break;
- case 5: /* iSCSI */
+ case TPROTO_ISCSI:
printf("%s iSCSI ", leadin);
num = ((ucp[2] << 8) | ucp[3]);
if (0 == format_code)
@@ -1185,7 +1190,7 @@ static void decode_transport_id(const char * leadin, unsigned char * ucp,
}
bump = (((num + 4) < 24) ? 24 : num + 4);
break;
- case 6: /* SAS */
+ case TPROTO_SAS:
ull = 0;
for (j = 0; j < 8; ++j) {
if (j > 0)
@@ -1198,18 +1203,19 @@ static void decode_transport_id(const char * leadin, unsigned char * ucp,
format_code);
bump = 24;
break;
- case 7: /* Automation/Drive Interface Transport Protocol */
+ case TPROTO_ADT:
printf("%s ADT:\n", leadin);
printf("%s format code: %d\n", leadin, format_code);
dStrHex((const char *)ucp, ((len > 24) ? 24 : len), 0);
bump = 24;
break;
- case 8: /* ATAPI */
+ case TPROTO_ATA:
printf("%s ATAPI:\n", leadin);
printf("%s format code: %d\n", leadin, format_code);
dStrHex((const char *)ucp, ((len > 24) ? 24 : len), 0);
bump = 24;
break;
+ case TPROTO_NONE:
default:
fprintf(stderr, "%s unknown protocol id=0x%x "
"format_code=%d\n", leadin, proto_id, format_code);
diff --git a/src/sg_modes.c b/src/sg_modes.c
index 13aa888f..a46235b2 100644
--- a/src/sg_modes.c
+++ b/src/sg_modes.c
@@ -26,7 +26,7 @@
*/
-static char * version_str = "1.26 20070923";
+static char * version_str = "1.26 20071005";
#define MX_ALLOC_LEN (1024 * 4)
#define PG_CODE_ALL 0x3f
@@ -647,16 +647,16 @@ mode_page_transp_table(int t_proto, int * size)
{
switch (t_proto)
{
- case 0: /* Fibre channel */
+ case TPROTO_FCP:
*size = sizeof(pc_desc_t_fcp) / sizeof(pc_desc_t_fcp[0]);
return &pc_desc_t_fcp[0];
- case 1: /* SPI-4 */
+ case TPROTO_SPI:
*size = sizeof(pc_desc_t_spi4) / sizeof(pc_desc_t_spi4[0]);
return &pc_desc_t_spi4[0];
- case 6: /* SAS-1.1 */
+ case TPROTO_SAS:
*size = sizeof(pc_desc_t_sas) / sizeof(pc_desc_t_sas[0]);
return &pc_desc_t_sas[0];
- case 7: /* ADT/ADC */
+ case TPROTO_ADT:
*size = sizeof(pc_desc_t_adt) / sizeof(pc_desc_t_adt[0]);
return &pc_desc_t_adt[0];
}
diff --git a/src/sg_persist.c b/src/sg_persist.c
index 60092130..920b37b4 100644
--- a/src/sg_persist.c
+++ b/src/sg_persist.c
@@ -187,7 +187,7 @@ static void decode_transport_id(const char * leadin, unsigned char * ucp,
format_code = ((ucp[0] >> 6) & 0x3);
proto_id = (ucp[0] & 0xf);
switch (proto_id) {
- case 0: /* Fibre channel */
+ case TPROTO_FCP: /* Fibre channel */
printf("%s FCP-2 World Wide Name:\n", leadin);
if (0 != format_code)
printf("%s [Unexpected format code: %d]\n", leadin,
@@ -195,7 +195,7 @@ static void decode_transport_id(const char * leadin, unsigned char * ucp,
dStrHex((const char *)&ucp[8], 8, 0);
bump = 24;
break;
- case 1: /* Parallel SCSI */
+ case TPROTO_SPI: /* Parallel SCSI */
printf("%s Parallel SCSI initiator SCSI address: 0x%x\n",
leadin, ((ucp[2] << 8) | ucp[3]));
if (0 != format_code)
@@ -205,13 +205,13 @@ static void decode_transport_id(const char * leadin, unsigned char * ucp,
"0x%x\n", leadin, ((ucp[6] << 8) | ucp[7]));
bump = 24;
break;
- case 2: /* SSA */
+ case TPROTO_SSA:
printf("%s SSA (transport id not defined):\n", leadin);
printf("%s format code: %d\n", leadin, format_code);
dStrHex((const char *)ucp, ((len > 24) ? 24 : len), 0);
bump = 24;
break;
- case 3: /* IEEE 1394 */
+ case TPROTO_1394: /* IEEE 1394 */
printf("%s IEEE 1394 EUI-64 name:\n", leadin);
if (0 != format_code)
printf("%s [Unexpected format code: %d]\n", leadin,
@@ -219,7 +219,7 @@ static void decode_transport_id(const char * leadin, unsigned char * ucp,
dStrHex((const char *)&ucp[8], 8, 0);
bump = 24;
break;
- case 4: /* Remote Direct Memory Access (RDMA) */
+ case TPROTO_SRP:
printf("%s RDMA initiator port identifier:\n", leadin);
if (0 != format_code)
printf("%s [Unexpected format code: %d]\n", leadin,
@@ -227,7 +227,7 @@ static void decode_transport_id(const char * leadin, unsigned char * ucp,
dStrHex((const char *)&ucp[8], 16, 0);
bump = 24;
break;
- case 5: /* iSCSI */
+ case TPROTO_ISCSI:
printf("%s iSCSI ", leadin);
num = ((ucp[2] << 8) | ucp[3]);
if (0 == format_code)
@@ -240,7 +240,7 @@ static void decode_transport_id(const char * leadin, unsigned char * ucp,
}
bump = (((num + 4) < 24) ? 24 : num + 4);
break;
- case 6: /* SAS */
+ case TPROTO_SAS:
ull = 0;
for (j = 0; j < 8; ++j) {
if (j > 0)
@@ -253,18 +253,19 @@ static void decode_transport_id(const char * leadin, unsigned char * ucp,
format_code);
bump = 24;
break;
- case 7: /* Automation/Drive Interface */
+ case TPROTO_ADT:
printf("%s ADT:\n", leadin);
printf("%s format code: %d\n", leadin, format_code);
dStrHex((const char *)ucp, ((len > 24) ? 24 : len), 0);
bump = 24;
break;
- case 8: /* ATAPI */
+ case TPROTO_ATA:
printf("%s ATAPI:\n", leadin);
printf("%s format code: %d\n", leadin, format_code);
dStrHex((const char *)ucp, ((len > 24) ? 24 : len), 0);
bump = 24;
break;
+ case TPROTO_NONE:
default:
fprintf(stderr, "%s unknown protocol id=0x%x "
"format_code=%d\n", leadin, proto_id, format_code);
diff --git a/src/sg_ses.c b/src/sg_ses.c
index 23773573..ad64e1f5 100644
--- a/src/sg_ses.c
+++ b/src/sg_ses.c
@@ -46,7 +46,7 @@
* commands tailored for SES (enclosure) devices.
*/
-static char * version_str = "1.37 20070919"; /* ses2r18 */
+static char * version_str = "1.38 20071005"; /* ses2r18 */
#define MX_ALLOC_LEN 4096
#define MX_ELEM_HDR 1024
@@ -1117,7 +1117,7 @@ static void ses_additional_elem_each(const unsigned char * ucp, int len,
eip_offset = (0x10 & ucp[0]) ? 2 : 0;
switch (0xf & ucp[0]) {
- case 0: /* FCP */
+ case TPROTO_FCP:
ports = ucp[2 + eip_offset];
printf(" Transport protocol: FCP\n");
#if 0
@@ -1142,7 +1142,7 @@ static void ses_additional_elem_each(const unsigned char * ucp, int len,
printf("\n");
}
break;
- case 6: /* SAS */
+ case TPROTO_SAS:
desc_type = (ucp[3 + eip_offset] >> 6) & 0x3;
printf(" Transport protocol: SAS\n");
#if 0
diff --git a/src/sg_vpd.c b/src/sg_vpd.c
index f2e6e9d1..e144600c 100644
--- a/src/sg_vpd.c
+++ b/src/sg_vpd.c
@@ -52,7 +52,7 @@
*/
-static char * version_str = "0.22 20070923"; /* spc-4 rev 11 */
+static char * version_str = "0.23 20071004"; /* spc4r11 + 07-153r1 */
extern void svpd_enumerate_vendor(void);
extern int svpd_decode_vendor(int sg_fd, int num_vpd, int subvalue,
@@ -74,6 +74,8 @@ extern const struct svpd_values_name_t *
#define VPD_MODE_PG_POLICY 0x87
#define VPD_SCSI_PORTS 0x88
#define VPD_ATA_INFO 0x89
+#define VPD_PROTO_LU 0x90
+#define VPD_PROTO_PORT 0x91
#define VPD_BLOCK_LIMITS 0xb0 /* SBC-3 */
#define VPD_SA_DEV_CAP 0xb0 /* SSC-3 */
#define VPD_OSD_INFO 0xb0 /* OSD */
@@ -107,7 +109,7 @@ struct svpd_values_name_t {
int subvalue;
int pdt; /* peripheral device type id, -1 is the default */
/* (all or not applicable) value */
- int ro_vendor; /* read-only or vendor flag */
+ int vendor; /* vendor flag */
const char * acron;
const char * name;
};
@@ -135,6 +137,8 @@ static struct option long_options[] = {
{0, 0, 0, 0},
};
+
+/* arranged in alphabetical order by acronym */
static struct svpd_values_name_t standard_vpd_pg[] = {
{VPD_ATA_INFO, 0, -1, 0, "ai", "ATA information (SAT)"},
{VPD_ASCII_OP_DEF, 0, -1, 0, "aod",
@@ -161,6 +165,9 @@ static struct svpd_values_name_t standard_vpd_pg[] = {
{VPD_MAN_NET_ADDR, 0, -1, 0, "mna", "Management network addresses"},
{VPD_MODE_PG_POLICY, 0, -1, 0, "mpp", "Mode page policy"},
{VPD_OSD_INFO, 0, 0x11, 0, "oi", "OSD information"},
+ {VPD_PROTO_LU, 0, 0x0, 0, "pslu", "Protocol-specific logical unit "
+ "information"},
+ {VPD_PROTO_PORT, 0, 0x0, 0, "pspo", "Protocol-specific port information"},
{VPD_SA_DEV_CAP, 0, 1, 0, "sad",
"Sequential access device capabilities (SSC)"},
{VPD_SOFTW_INF_ID, 0, -1, 0, "sii", "Software interface identification"},
@@ -242,7 +249,7 @@ enumerate_vpds(int standard, int vendor)
if (standard) {
for (vnp = standard_vpd_pg; vnp->acron; ++vnp) {
- if (vnp->name && (0 == vnp->ro_vendor))
+ if (vnp->name && (0 == vnp->vendor))
printf(" %-10s 0x%02x %s\n", vnp->acron, vnp->value,
vnp->name);
}
@@ -955,7 +962,7 @@ decode_transport_id(const char * leadin, unsigned char * ucp, int len)
format_code = ((ucp[0] >> 6) & 0x3);
proto_id = (ucp[0] & 0xf);
switch (proto_id) {
- case 0: /* Fibre channel */
+ case TPROTO_FCP: /* Fibre channel */
printf("%s FCP-2 World Wide Name:\n", leadin);
if (0 != format_code)
printf("%s [Unexpected format code: %d]\n", leadin,
@@ -963,7 +970,7 @@ decode_transport_id(const char * leadin, unsigned char * ucp, int len)
dStrHex((const char *)&ucp[8], 8, 0);
bump = 24;
break;
- case 1: /* Parallel SCSI */
+ case TPROTO_SPI: /* Scsi Parallel Interface */
printf("%s Parallel SCSI initiator SCSI address: 0x%x\n",
leadin, ((ucp[2] << 8) | ucp[3]));
if (0 != format_code)
@@ -973,13 +980,13 @@ decode_transport_id(const char * leadin, unsigned char * ucp, int len)
"0x%x\n", leadin, ((ucp[6] << 8) | ucp[7]));
bump = 24;
break;
- case 2: /* SSA */
+ case TPROTO_SSA:
printf("%s SSA (transport id not defined):\n", leadin);
printf("%s format code: %d\n", leadin, format_code);
dStrHex((const char *)ucp, ((len > 24) ? 24 : len), 0);
bump = 24;
break;
- case 3: /* IEEE 1394 */
+ case TPROTO_1394: /* IEEE 1394 */
printf("%s IEEE 1394 EUI-64 name:\n", leadin);
if (0 != format_code)
printf("%s [Unexpected format code: %d]\n", leadin,
@@ -987,7 +994,7 @@ decode_transport_id(const char * leadin, unsigned char * ucp, int len)
dStrHex((const char *)&ucp[8], 8, 0);
bump = 24;
break;
- case 4: /* Remote Direct Memory Access (RDMA) */
+ case TPROTO_SRP:
printf("%s RDMA initiator port identifier:\n", leadin);
if (0 != format_code)
printf("%s [Unexpected format code: %d]\n", leadin,
@@ -995,7 +1002,7 @@ decode_transport_id(const char * leadin, unsigned char * ucp, int len)
dStrHex((const char *)&ucp[8], 16, 0);
bump = 24;
break;
- case 5: /* iSCSI */
+ case TPROTO_ISCSI:
printf("%s iSCSI ", leadin);
num = ((ucp[2] << 8) | ucp[3]);
if (0 == format_code)
@@ -1008,7 +1015,7 @@ decode_transport_id(const char * leadin, unsigned char * ucp, int len)
}
bump = (((num + 4) < 24) ? 24 : num + 4);
break;
- case 6: /* SAS */
+ case TPROTO_SAS:
ull = 0;
for (j = 0; j < 8; ++j) {
if (j > 0)
@@ -1021,18 +1028,19 @@ decode_transport_id(const char * leadin, unsigned char * ucp, int len)
format_code);
bump = 24;
break;
- case 7: /* Automation/Drive Interface Transport Protocol */
+ case TPROTO_ADT:
printf("%s ADT:\n", leadin);
printf("%s format code: %d\n", leadin, format_code);
dStrHex((const char *)ucp, ((len > 24) ? 24 : len), 0);
bump = 24;
break;
- case 8: /* ATAPI */
+ case TPROTO_ATA: /* ATA/ATAPI */
printf("%s ATAPI:\n", leadin);
printf("%s format code: %d\n", leadin, format_code);
dStrHex((const char *)ucp, ((len > 24) ? 24 : len), 0);
bump = 24;
break;
+ case TPROTO_NONE:
default:
fprintf(stderr, "%s unknown protocol id=0x%x "
"format_code=%d\n", leadin, proto_id, format_code);
@@ -1148,6 +1156,102 @@ decode_ata_info_vpd(unsigned char * buff, int len, int do_long, int do_hex)
}
static void
+decode_proto_lu_vpd(unsigned char * buff, int len, int do_hex)
+{
+ int k, bump, rel_port, desc_len, proto;
+ unsigned char * ucp;
+
+ if (1 == do_hex) {
+ dStrHex((const char *)buff, len, 0);
+ return;
+ }
+ if (len < 4) {
+ fprintf(stderr, "Protocol-specific logical unit information VPD "
+ "page length too short=%d\n", len);
+ return;
+ }
+ len -= 4;
+ ucp = buff + 4;
+ for (k = 0; k < len; k += bump, ucp += bump) {
+ rel_port = (ucp[0] << 8) + ucp[1];
+ printf("Relative port=%d\n", rel_port);
+ proto = ucp[2] & 0xf;
+ desc_len = (ucp[6] << 8) + ucp[7];
+ bump = 8 + desc_len;
+ if ((k + bump) > len) {
+ fprintf(stderr, "Protocol-specific logical unit information VPD "
+ "page, short descriptor length=%d, left=%d\n", bump,
+ (len - k));
+ return;
+ }
+ if (0 == desc_len)
+ continue;
+ if (2 == do_hex)
+ dStrHex((const char *)ucp + 8, desc_len, 1);
+ else if (do_hex > 2)
+ dStrHex((const char *)ucp, bump, 1);
+ else {
+ switch (proto) {
+ case TPROTO_SAS:
+ printf(" Protocol identifier: SAS\n");
+ printf(" TLR control supported: %d\n", !!(ucp[8] & 0x1));
+ break;
+ default:
+ fprintf(stderr, "Unexpected proto=%d\n", proto);
+ dStrHex((const char *)ucp, bump, 1);
+ break;
+ }
+ }
+ }
+}
+
+static void
+decode_proto_port_vpd(unsigned char * buff, int len, int do_hex)
+{
+ int k, bump, rel_port, desc_len, proto;
+ unsigned char * ucp;
+
+ if (1 == do_hex) {
+ dStrHex((const char *)buff, len, 0);
+ return;
+ }
+ if (len < 4) {
+ fprintf(stderr, "Protocol-specific port information VPD "
+ "page length too short=%d\n", len);
+ return;
+ }
+ len -= 4;
+ ucp = buff + 4;
+ for (k = 0; k < len; k += bump, ucp += bump) {
+ rel_port = (ucp[0] << 8) + ucp[1];
+ printf("Relative port=%d\n", rel_port);
+ proto = ucp[2] & 0xf;
+ desc_len = (ucp[6] << 8) + ucp[7];
+ bump = 8 + desc_len;
+ if ((k + bump) > len) {
+ fprintf(stderr, "Protocol-specific port VPD "
+ "page, short descriptor length=%d, left=%d\n", bump,
+ (len - k));
+ return;
+ }
+ if (0 == desc_len)
+ continue;
+ if (2 == do_hex)
+ dStrHex((const char *)ucp + 8, desc_len, 1);
+ else if (do_hex > 2)
+ dStrHex((const char *)ucp, bump, 1);
+ else {
+ switch (proto) {
+ default:
+ fprintf(stderr, "Unexpected proto=%d\n", proto);
+ dStrHex((const char *)ucp, bump, 1);
+ break;
+ }
+ }
+ }
+}
+
+static void
decode_b0_vpd(unsigned char * buff, int len, int do_hex, int pdt)
{
unsigned int u;
@@ -1292,7 +1396,7 @@ svpd_decode_standard(int sg_fd, int num_vpd, int subvalue, int do_hex,
int res = 0;
switch(num_vpd) {
- case VPD_SUPPORTED_VPDS:
+ case VPD_SUPPORTED_VPDS: /* 0x0 */
if ((! do_raw) && (! do_quiet))
printf("Supported VPD pages VPD page:\n");
res = sg_ll_inquiry(sg_fd, 0, 1, VPD_SUPPORTED_VPDS, rsp_buff,
@@ -1330,7 +1434,7 @@ svpd_decode_standard(int sg_fd, int num_vpd, int subvalue, int do_hex,
return 0;
}
break;
- case VPD_UNIT_SERIAL_NUM:
+ case VPD_UNIT_SERIAL_NUM: /* 0x80 */
if ((! do_raw) && (! do_quiet))
printf("Unit serial number VPD page:\n");
res = sg_ll_inquiry(sg_fd, 0, 1, VPD_UNIT_SERIAL_NUM, rsp_buff,
@@ -1368,7 +1472,7 @@ svpd_decode_standard(int sg_fd, int num_vpd, int subvalue, int do_hex,
return 0;
}
break;
- case VPD_DEVICE_ID:
+ case VPD_DEVICE_ID: /* 0x83 */
if ((! do_raw) && (! do_quiet))
printf("Device Identification VPD page:\n");
res = sg_ll_inquiry(sg_fd, 0, 1, VPD_DEVICE_ID, rsp_buff,
@@ -1408,7 +1512,7 @@ svpd_decode_standard(int sg_fd, int num_vpd, int subvalue, int do_hex,
return 0;
}
break;
- case VPD_SOFTW_INF_ID:
+ case VPD_SOFTW_INF_ID: /* 0x84 */
if ((! do_raw) && (! do_quiet))
printf("Software interface identification VPD page:\n");
res = sg_ll_inquiry(sg_fd, 0, 1, VPD_SOFTW_INF_ID, rsp_buff,
@@ -1437,7 +1541,7 @@ svpd_decode_standard(int sg_fd, int num_vpd, int subvalue, int do_hex,
return 0;
}
break;
- case VPD_MAN_NET_ADDR:
+ case VPD_MAN_NET_ADDR: /* 0x85 */
if ((! do_raw) && (! do_quiet))
printf("Management network addresses VPD page:\n");
res = sg_ll_inquiry(sg_fd, 0, 1, VPD_MAN_NET_ADDR, rsp_buff,
@@ -1469,7 +1573,45 @@ svpd_decode_standard(int sg_fd, int num_vpd, int subvalue, int do_hex,
return 0;
}
break;
- case VPD_MODE_PG_POLICY:
+ case VPD_EXT_INQ: /* 0x86 */
+ if ((! do_raw) && (! do_quiet))
+ printf("extended INQUIRY data VPD page:\n");
+ res = sg_ll_inquiry(sg_fd, 0, 1, VPD_EXT_INQ, rsp_buff,
+ DEF_ALLOC_LEN, 1, verbose);
+ if (0 == res) {
+ len = ((rsp_buff[2] << 8) + rsp_buff[3]) + 4;
+ if (VPD_EXT_INQ != rsp_buff[1]) {
+ fprintf(stderr, "invalid VPD response; probably a STANDARD "
+ "INQUIRY response\n");
+ if (verbose) {
+ fprintf(stderr, "First 32 bytes of bad response\n");
+ dStrHex((const char *)rsp_buff, 32, 0);
+ }
+ return SG_LIB_CAT_MALFORMED;
+ }
+ if (len > MX_ALLOC_LEN) {
+ fprintf(stderr, "response length too long: %d > %d\n", len,
+ MX_ALLOC_LEN);
+ return SG_LIB_CAT_MALFORMED;
+ } else if (len > DEF_ALLOC_LEN) {
+ if (sg_ll_inquiry(sg_fd, 0, 1, VPD_EXT_INQ, rsp_buff, len,
+ 1, verbose))
+ return SG_LIB_CAT_OTHER;
+ }
+ if (do_raw)
+ dStrRaw((const char *)rsp_buff, len);
+ else {
+ pdt = rsp_buff[0] & 0x1f;
+ if (verbose || do_long)
+ printf(" [PQual=%d Peripheral device type: %s]\n",
+ (rsp_buff[0] & 0xe0) >> 5,
+ sg_get_pdt_str(pdt, sizeof(buff), buff));
+ decode_x_inq_vpd(rsp_buff, len, do_hex);
+ }
+ return 0;
+ }
+ break;
+ case VPD_MODE_PG_POLICY: /* 0x87 */
if ((! do_raw) && (! do_quiet))
printf("Mode page VPD policy:\n");
res = sg_ll_inquiry(sg_fd, 0, 1, VPD_MODE_PG_POLICY, rsp_buff,
@@ -1507,14 +1649,14 @@ svpd_decode_standard(int sg_fd, int num_vpd, int subvalue, int do_hex,
return 0;
}
break;
- case VPD_EXT_INQ:
+ case VPD_SCSI_PORTS: /* 0x88 */
if ((! do_raw) && (! do_quiet))
- printf("extended INQUIRY data VPD page:\n");
- res = sg_ll_inquiry(sg_fd, 0, 1, VPD_EXT_INQ, rsp_buff,
+ printf("SCSI Ports VPD page:\n");
+ res = sg_ll_inquiry(sg_fd, 0, 1, VPD_SCSI_PORTS, rsp_buff,
DEF_ALLOC_LEN, 1, verbose);
if (0 == res) {
len = ((rsp_buff[2] << 8) + rsp_buff[3]) + 4;
- if (VPD_EXT_INQ != rsp_buff[1]) {
+ if (VPD_SCSI_PORTS != rsp_buff[1]) {
fprintf(stderr, "invalid VPD response; probably a STANDARD "
"INQUIRY response\n");
if (verbose) {
@@ -1528,7 +1670,7 @@ svpd_decode_standard(int sg_fd, int num_vpd, int subvalue, int do_hex,
MX_ALLOC_LEN);
return SG_LIB_CAT_MALFORMED;
} else if (len > DEF_ALLOC_LEN) {
- if (sg_ll_inquiry(sg_fd, 0, 1, VPD_EXT_INQ, rsp_buff, len,
+ if (sg_ll_inquiry(sg_fd, 0, 1, VPD_SCSI_PORTS, rsp_buff, len,
1, verbose))
return SG_LIB_CAT_OTHER;
}
@@ -1540,12 +1682,12 @@ svpd_decode_standard(int sg_fd, int num_vpd, int subvalue, int do_hex,
printf(" [PQual=%d Peripheral device type: %s]\n",
(rsp_buff[0] & 0xe0) >> 5,
sg_get_pdt_str(pdt, sizeof(buff), buff));
- decode_x_inq_vpd(rsp_buff, len, do_hex);
+ decode_scsi_ports_vpd(rsp_buff, len, do_hex, do_long, do_quiet);
}
return 0;
}
break;
- case VPD_ATA_INFO:
+ case VPD_ATA_INFO: /* 0x89 */
if ((! do_raw) && (3 != do_hex) && (! do_quiet))
printf("ATA information VPD page:\n");
res = sg_ll_inquiry(sg_fd, 0, 1, VPD_ATA_INFO, rsp_buff,
@@ -1586,6 +1728,82 @@ svpd_decode_standard(int sg_fd, int num_vpd, int subvalue, int do_hex,
return 0;
}
break;
+ case VPD_PROTO_LU: /* 0x90 */
+ if ((! do_raw) && (! do_quiet))
+ printf("Protocol-specific logical unit information:\n");
+ res = sg_ll_inquiry(sg_fd, 0, 1, VPD_PROTO_LU, rsp_buff,
+ DEF_ALLOC_LEN, 1, verbose);
+ if (0 == res) {
+ len = ((rsp_buff[2] << 8) + rsp_buff[3]) + 4;
+ if (VPD_PROTO_LU != rsp_buff[1]) {
+ fprintf(stderr, "invalid VPD response; probably a STANDARD "
+ "INQUIRY response\n");
+ if (verbose) {
+ fprintf(stderr, "First 32 bytes of bad response\n");
+ dStrHex((const char *)rsp_buff, 32, 0);
+ }
+ return SG_LIB_CAT_MALFORMED;
+ }
+ if (len > MX_ALLOC_LEN) {
+ fprintf(stderr, "response length too long: %d > %d\n", len,
+ MX_ALLOC_LEN);
+ return SG_LIB_CAT_MALFORMED;
+ } else if (len > DEF_ALLOC_LEN) {
+ if (sg_ll_inquiry(sg_fd, 0, 1, VPD_PROTO_LU, rsp_buff,
+ len, 1, verbose))
+ return SG_LIB_CAT_OTHER;
+ }
+ if (do_raw)
+ dStrRaw((const char *)rsp_buff, len);
+ else {
+ pdt = rsp_buff[0] & 0x1f;
+ if (verbose || do_long)
+ printf(" [PQual=%d Peripheral device type: %s]\n",
+ (rsp_buff[0] & 0xe0) >> 5,
+ sg_get_pdt_str(pdt, sizeof(buff), buff));
+ decode_proto_lu_vpd(rsp_buff, len, do_hex);
+ }
+ return 0;
+ }
+ break;
+ case VPD_PROTO_PORT: /* 0x91 */
+ if ((! do_raw) && (! do_quiet))
+ printf("Protocol-specific port information:\n");
+ res = sg_ll_inquiry(sg_fd, 0, 1, VPD_PROTO_PORT, rsp_buff,
+ DEF_ALLOC_LEN, 1, verbose);
+ if (0 == res) {
+ len = ((rsp_buff[2] << 8) + rsp_buff[3]) + 4;
+ if (VPD_PROTO_PORT != rsp_buff[1]) {
+ fprintf(stderr, "invalid VPD response; probably a STANDARD "
+ "INQUIRY response\n");
+ if (verbose) {
+ fprintf(stderr, "First 32 bytes of bad response\n");
+ dStrHex((const char *)rsp_buff, 32, 0);
+ }
+ return SG_LIB_CAT_MALFORMED;
+ }
+ if (len > MX_ALLOC_LEN) {
+ fprintf(stderr, "response length too long: %d > %d\n", len,
+ MX_ALLOC_LEN);
+ return SG_LIB_CAT_MALFORMED;
+ } else if (len > DEF_ALLOC_LEN) {
+ if (sg_ll_inquiry(sg_fd, 0, 1, VPD_PROTO_PORT, rsp_buff,
+ len, 1, verbose))
+ return SG_LIB_CAT_OTHER;
+ }
+ if (do_raw)
+ dStrRaw((const char *)rsp_buff, len);
+ else {
+ pdt = rsp_buff[0] & 0x1f;
+ if (verbose || do_long)
+ printf(" [PQual=%d Peripheral device type: %s]\n",
+ (rsp_buff[0] & 0xe0) >> 5,
+ sg_get_pdt_str(pdt, sizeof(buff), buff));
+ decode_proto_port_vpd(rsp_buff, len, do_hex);
+ }
+ return 0;
+ }
+ break;
case 0xb0: /* depends on pdt */
res = sg_ll_inquiry(sg_fd, 0, 1, 0xb0, rsp_buff,
DEF_ALLOC_LEN, 1, verbose);
@@ -1700,44 +1918,6 @@ svpd_decode_standard(int sg_fd, int num_vpd, int subvalue, int do_hex,
} else if (! do_raw)
printf("VPD page=0xb1\n");
break;
- case VPD_SCSI_PORTS:
- if ((! do_raw) && (! do_quiet))
- printf("SCSI Ports VPD page:\n");
- res = sg_ll_inquiry(sg_fd, 0, 1, VPD_SCSI_PORTS, rsp_buff,
- DEF_ALLOC_LEN, 1, verbose);
- if (0 == res) {
- len = ((rsp_buff[2] << 8) + rsp_buff[3]) + 4;
- if (VPD_SCSI_PORTS != rsp_buff[1]) {
- fprintf(stderr, "invalid VPD response; probably a STANDARD "
- "INQUIRY response\n");
- if (verbose) {
- fprintf(stderr, "First 32 bytes of bad response\n");
- dStrHex((const char *)rsp_buff, 32, 0);
- }
- return SG_LIB_CAT_MALFORMED;
- }
- if (len > MX_ALLOC_LEN) {
- fprintf(stderr, "response length too long: %d > %d\n", len,
- MX_ALLOC_LEN);
- return SG_LIB_CAT_MALFORMED;
- } else if (len > DEF_ALLOC_LEN) {
- if (sg_ll_inquiry(sg_fd, 0, 1, VPD_SCSI_PORTS, rsp_buff, len,
- 1, verbose))
- return SG_LIB_CAT_OTHER;
- }
- if (do_raw)
- dStrRaw((const char *)rsp_buff, len);
- else {
- pdt = rsp_buff[0] & 0x1f;
- if (verbose || do_long)
- printf(" [PQual=%d Peripheral device type: %s]\n",
- (rsp_buff[0] & 0xe0) >> 5,
- sg_get_pdt_str(pdt, sizeof(buff), buff));
- decode_scsi_ports_vpd(rsp_buff, len, do_hex, do_long, do_quiet);
- }
- return 0;
- }
- break;
default:
return SG_LIB_SYNTAX_ERROR;
}
diff --git a/src/sg_vpd_vendor.c b/src/sg_vpd_vendor.c
index 575012e4..e3820080 100644
--- a/src/sg_vpd_vendor.c
+++ b/src/sg_vpd_vendor.c
@@ -76,7 +76,7 @@ struct svpd_values_name_t {
int subvalue;
int pdt; /* peripheral device type id, -1 is the default */
/* (all or not applicable) value */
- int ro_vendor; /* read-only or vendor flag */
+ int vendor; /* vendor flag */
const char * acron;
const char * name;
};