aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDouglas Gilbert <dgilbert@interlog.com>2007-07-11 09:35:30 +0000
committerDouglas Gilbert <dgilbert@interlog.com>2007-07-11 09:35:30 +0000
commitf979e5aaba7d5ea7d1a8066bbdcd6e3c0a9f6879 (patch)
treee55584c8da2afc823047433647924d923b2a1387
parent4e835e1d74d63fcb2f92aa5a3bce525b67c1e44e (diff)
downloadsg3_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--CHANGELOG3
-rw-r--r--README2
-rw-r--r--no_lib/sg3_utils.spec2
-rw-r--r--sg3_utils.spec2
-rw-r--r--sg_inq.82
-rw-r--r--sg_vpd.c108
6 files changed, 110 insertions, 9 deletions
diff --git a/CHANGELOG b/CHANGELOG
index 997eff9b..0ec4eaac 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -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]
diff --git a/README b/README
index 6f0591c0..c317703d 100644
--- a/README
+++ b/README
@@ -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
diff --git a/sg_inq.8 b/sg_inq.8
index d8de6571..443da2ca 100644
--- a/sg_inq.8
+++ b/sg_inq.8
@@ -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 .
diff --git a/sg_vpd.c b/sg_vpd.c
index 1385b400..8a8fa857 100644
--- a/sg_vpd.c
+++ b/sg_vpd.c
@@ -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");