diff options
author | Douglas Gilbert <dgilbert@interlog.com> | 2007-07-11 09:35:30 +0000 |
---|---|---|
committer | Douglas Gilbert <dgilbert@interlog.com> | 2007-07-11 09:35:30 +0000 |
commit | f979e5aaba7d5ea7d1a8066bbdcd6e3c0a9f6879 (patch) | |
tree | e55584c8da2afc823047433647924d923b2a1387 | |
parent | 4e835e1d74d63fcb2f92aa5a3bce525b67c1e44e (diff) | |
download | sg3_utils-f979e5aaba7d5ea7d1a8066bbdcd6e3c0a9f6879.tar.gz |
add block device characteristics VPD page
git-svn-id: https://svn.bingwo.ca/repos/sg3_utils/trunk@83 6180dd3e-e324-4e3e-922d-17de1ae2f315
-rw-r--r-- | CHANGELOG | 3 | ||||
-rw-r--r-- | README | 2 | ||||
-rw-r--r-- | no_lib/sg3_utils.spec | 2 | ||||
-rw-r--r-- | sg3_utils.spec | 2 | ||||
-rw-r--r-- | sg_inq.8 | 2 | ||||
-rw-r--r-- | sg_vpd.c | 108 |
6 files changed, 110 insertions, 9 deletions
@@ -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 sg3_utils-1.25 [20070710] +Changelog for sg3_utils-1.25 [20070711] - sg_dd: add oflag=sparse to step over bs*bpt number of zeros; - with oflag=sparse, write last bs*bpt segment at end or after error so file length of OFILE is appropriate @@ -10,6 +10,7 @@ Changelog for sg3_utils-1.25 [20070710] - when coe>1 then SCSI READ LONG logic remember extended block length of first encountered error - sg_ses: sync with ses2r17 + - sg_vpd: add block device characteristics VPD page - place source in subversion repository Changelog for sg3_utils-1.24 [20070507] @@ -325,4 +325,4 @@ See http://www.torque.net/sg/tools.html Doug Gilbert -10th July 2007 +11th July 2007 diff --git a/no_lib/sg3_utils.spec b/no_lib/sg3_utils.spec index fe1e80b2..58ceba0b 100644 --- a/no_lib/sg3_utils.spec +++ b/no_lib/sg3_utils.spec @@ -137,7 +137,7 @@ rm -rf $RPM_BUILD_ROOT %changelog -* Tue Jul 10 2007 - dgilbert at interlog dot com +* Wed Jul 11 2007 - dgilbert at interlog dot com - sg_dd oflag=sparse,null * sg3_utils-1.25 diff --git a/sg3_utils.spec b/sg3_utils.spec index 67205524..150b6b61 100644 --- a/sg3_utils.spec +++ b/sg3_utils.spec @@ -79,7 +79,7 @@ rm -rf $RPM_BUILD_ROOT %{_libdir}/*.la %changelog -* Tue Jul 10 2007 - dgilbert at interlog dot com +* Wed Jul 11 2007 - dgilbert at interlog dot com - sg_dd oflag=sparse,null * sg3_utils-1.25 @@ -43,7 +43,7 @@ and \fI\-\-hex\fR options can be used to manipulate the output. If the and the \fIDEVICE\fR is assumed to be ATA (or ATAPI). .PP The reference document used for interpreting an INQUIRY is T10/1713\-D -Revision 7a (SPC\-4, 7 October 2006) found at http://www.t10.org . +Revision 11 (SPC\-4, 14 May 2007) found at http://www.t10.org . Obsolete items in the standard INQUIRY response are displayed in brackets. The reference document for the ATA IDENTIFY (PACKET) DEVICE command is ATA8\-ACS found at http://www.t13.org . @@ -49,7 +49,7 @@ */ -static char * version_str = "0.19 20070419"; /* spc-4 rev 9 */ +static char * version_str = "0.20 20070711"; /* spc-4 rev 11 */ extern void svpd_enumerate_vendor(void); extern int svpd_decode_vendor(int sg_fd, int num_vpd, int subvalue, @@ -74,7 +74,8 @@ extern const struct svpd_values_name_t * #define VPD_BLOCK_LIMITS 0xb0 /* SBC-3 */ #define VPD_SA_DEV_CAP 0xb0 /* SSC-3 */ #define VPD_OSD_INFO 0xb0 /* OSD */ -#define VPD_MAN_ASS_SN 0xb1 /* SSC-3 */ +#define VPD_BLOCK_DEV_CHAR 0xb1 /* SBC-3 */ +#define VPD_MAN_ASS_SN 0xb1 /* SSC-3, ADC-2 */ #define VPD_SECURITY_TOKEN 0xb1 /* OSD */ #define VPD_TA_SUPPORTED 0xb2 /* SSC-3 */ @@ -136,6 +137,8 @@ static struct svpd_values_name_t standard_vpd_pg[] = { {VPD_ASCII_OP_DEF, 0, -1, 0, "aod", "ASCII implemented operating definition (obs)"}, {VPD_BLOCK_LIMITS, 0, 0, 0, "bl", "Block limits (SBC)"}, + {VPD_BLOCK_DEV_CHAR, 0, 0, 0, "bdc", "Block device characteristics " + "(SBC)"}, {VPD_DEVICE_ID, 0, -1, 0, "di", "Device identification"}, {VPD_DEVICE_ID, VPD_DI_SEL_AS_IS, -1, 0, "di_asis", "Like 'di' " "but designators ordered as found"}, @@ -150,6 +153,8 @@ static struct svpd_values_name_t standard_vpd_pg[] = { "Implemented operating definition (obs)"}, {VPD_MAN_ASS_SN, 0, 1, 0, "mas", "Manufacturer assigned serial number (SSC)"}, + {VPD_MAN_ASS_SN, 0, 0x12, 0, "masa", + "Manufacturer assigned serial number (ADC)"}, {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"}, @@ -1199,6 +1204,42 @@ static void decode_b0_vpd(unsigned char * buff, int len, int do_hex, int pdt) } } +static void decode_b1_vpd(unsigned char * buff, int len, int do_hex, int pdt) +{ + unsigned int u; + + if (do_hex) { + dStrHex((const char *)buff, len, 0); + return; + } + switch (pdt) { + case 0: case 4: case 7: + if (len < 64) { + fprintf(stderr, "Block device characteristics VPD page length " + "too short=%d\n", len); + return; + } + u = (buff[4] << 8) | buff[5]; + if (0 == u) + printf(" Medium rotation rate is not reported\n"); + else if (1 == u) + printf(" Non-rotating medium (e.g. solid state)\n"); + else if ((u < 0x401) || (0xffff == u)) + printf(" Reserved [0x%x]\n", u); + else + printf(" Nominal rotation rate: %d rpm\n", u); + break; + case 1: case 8: case 0x12: + printf(" Manufacturer-assigned serial number: %.*s\n", + len - 4, buff + 4); + break; + default: + printf(" Unable to decode pdt=0x%x, in hex:\n", pdt); + dStrHex((const char *)buff, len, 0); + break; + } +} + /* Returns 0 if successful */ static int svpd_unable_to_decode(int sg_fd, int num_vpd, int subvalue, int do_hex, int do_raw, int do_long, @@ -1559,7 +1600,7 @@ static int svpd_decode_standard(int sg_fd, int num_vpd, int subvalue, return 0; } break; - case 0xb0: /* could be BLOCK LIMITS but need to know pdt to find out */ + case 0xb0: /* depends on pdt */ res = sg_ll_inquiry(sg_fd, 0, 1, 0xb0, rsp_buff, DEF_ALLOC_LEN, 1, verbose); if (0 == res) { @@ -1574,7 +1615,7 @@ static int svpd_decode_standard(int sg_fd, int num_vpd, int subvalue, "(SSC):\n"); break; case 0x11: - printf("OSD information (OSD) VPD page:\n"); + printf("OSD information VPD page (OSD):\n"); break; default: printf("VPD page=0x%x, pdt=0x%x:\n", 0xb0, pdt); @@ -1614,6 +1655,65 @@ static int svpd_decode_standard(int sg_fd, int num_vpd, int subvalue, } else if (! do_raw) printf("VPD page=0xb0\n"); break; + case 0xb1: /* depends on pdt */ + res = sg_ll_inquiry(sg_fd, 0, 1, 0xb1, rsp_buff, + DEF_ALLOC_LEN, 1, verbose); + if (0 == res) { + pdt = rsp_buff[0] & 0x1f; + if ((! do_raw) && (! do_quiet)) { + switch (pdt) { + case 0: case 4: case 7: + printf("Block device characteristics VPD page (SBC):\n"); + break; + case 1: case 8: + printf("Manufactured assigned serial number VPD page " + "(SSC):\n"); + break; + case 0x11: + printf("Security token VPD page (OSD):\n"); + break; + case 0x12: + printf("Manufactured assigned serial number VPD page " + "(ADC):\n"); + break; + default: + printf("VPD page=0x%x, pdt=0x%x:\n", 0xb1, pdt); + break; + } + } + len = ((rsp_buff[2] << 8) + rsp_buff[3]) + 4; + if (0xb1 != 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, 0xb1, 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_b1_vpd(rsp_buff, len, do_hex, pdt); + } + return 0; + } 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"); |