diff options
author | Douglas Gilbert <dgilbert@interlog.com> | 2007-10-05 04:47:38 +0000 |
---|---|---|
committer | Douglas Gilbert <dgilbert@interlog.com> | 2007-10-05 04:47:38 +0000 |
commit | a1d15c35ce45754c109aed26595752c64ffef921 (patch) | |
tree | f3866e7ebc309363f53e93e64c8ecca944dd5b77 /src | |
parent | 86b71f28e0496ad7a4b44ba58af9c6c9ec8eed83 (diff) | |
download | sg3_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.c | 34 | ||||
-rw-r--r-- | src/sg_modes.c | 10 | ||||
-rw-r--r-- | src/sg_persist.c | 19 | ||||
-rw-r--r-- | src/sg_ses.c | 6 | ||||
-rw-r--r-- | src/sg_vpd.c | 306 | ||||
-rw-r--r-- | src/sg_vpd_vendor.c | 2 |
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; }; |