aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDouglas Gilbert <dgilbert@interlog.com>2012-12-06 10:00:15 +0000
committerDouglas Gilbert <dgilbert@interlog.com>2012-12-06 10:00:15 +0000
commita455114c44be5eb5ef423bb2e39da233589cd0dd (patch)
treed38d551da90067b9cebafcba1a46ca0606ec6fe7
parent8243af5bed308cfc43c7f4ea613ebbbf2a240d6f (diff)
downloadsg3_utils-a455114c44be5eb5ef423bb2e39da233589cd0dd.tar.gz
sg_verify: BYTCHK expansion in sbc3r34; block device characteristics VPD page additions
git-svn-id: https://svn.bingwo.ca/repos/sg3_utils/trunk@468 6180dd3e-e324-4e3e-922d-17de1ae2f315
-rw-r--r--ChangeLog8
-rw-r--r--doc/sg_verify.855
-rw-r--r--lib/sg_cmds_basic.c2
-rw-r--r--lib/sg_cmds_extra.c6
-rw-r--r--src/sg_inq.c31
-rw-r--r--src/sg_verify.c87
-rw-r--r--src/sg_vpd.c6
7 files changed, 143 insertions, 52 deletions
diff --git a/ChangeLog b/ChangeLog
index b244bf2a..a3f9bdba 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -2,11 +2,15 @@ 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.35 [20121124] [svn: r467]
+Changelog for sg3_utils-1.35 [20121206] [svn: r468]
+ - sg_inq+sg_vpd: block device characteristics VPD page:
+ add product_type, WABEREQ, WACEREQ and VBULS fields
+ - sg_verify: add --ebytchk option for sbc3r34 changes
- sg_stpg: with --offline fix 'Invalid state 0xe'
- sg_ses: Door Lock element changed to Door element and
abbreviation changed frm 'dl' to 'do' (ses3r05)
- - sync to sbc3r33
+ - sync to sbc3r34
+ - sg_lib: sg_ll_verify10+16 expand BYTCHK two 2 bit field
- sg_pt_win32, sg_scan(win32): changes for cygwin 1.7.17
- clean up man page summary lines
diff --git a/doc/sg_verify.8 b/doc/sg_verify.8
index 4947eb50..15c1c942 100644
--- a/doc/sg_verify.8
+++ b/doc/sg_verify.8
@@ -1,12 +1,13 @@
-.TH SG_VERIFY "8" "September 2012" "sg3_utils\-1.34" SG3_UTILS
+.TH SG_VERIFY "8" "December 2012" "sg3_utils\-1.35" SG3_UTILS
.SH NAME
sg_verify \- invoke SCSI VERIFY command(s) on a block device
.SH SYNOPSIS
.B sg_verify
[\fI\-\-16\fR] [\fI\-\-bpc=BPC\fR] [\fI\-\-bytchk=NDO\fR]
-[\fI\-\-count=COUNT\fR] [\fI\-\-dpo\fR] [\fI\-\-group=GN\fR] [\fI\-\-help\fR]
-[\fI\-\-in=IF\fR] [\fI\-\-lba=LBA\fR] [\fI\-\-readonly\fR]
-[\fI\-\-verbose\fR] [\fI\-\-version\fR] [\fI\-\-vrprotect=VRP\fR]
+[\fI\-\-count=COUNT\fR] [\fI\-\-dpo\fR] [\fI\-\-ebytchk=BVAL\fR]
+[\fI\-\-group=GN\fR] [\fI\-\-help\fR] [\fI\-\-in=IF\fR]
+[\fI\-\-lba=LBA\fR] [\fI\-\-readonly\fR] [\fI\-\-verbose\fR]
+[\fI\-\-version\fR] [\fI\-\-vrprotect=VRP\fR]
\fIDEVICE\fR
.SH DESCRIPTION
.\" Add any additional description here
@@ -19,8 +20,8 @@ When \fI\-\-bytchk=NDO\fR is not given then the verify starts at the logical
block address given by the \fI\-\-lba=LBA\fR option and continues for
\fI\-\-count=COUNT\fR blocks. No more than \fI\-\-bpc=BPC\fR blocks are
verified by each VERIFY command so if necessary multiple VERIFY commands are
-sent. No news is good news (i.e. if there are no verify errors detected no
-messages are sent to stderr and the Unix return status is 0).
+sent. No news is good news (i.e. if there are no verify errors detected then
+no messages are sent to stderr and the Unix return status is 0).
.PP
When \fI\-\-bytchk=NDO\fR is given then the \fI\-\-bpc=BPC\fR option is
ignored. A single verify command is issued and it starts at the logical block
@@ -50,11 +51,12 @@ devices (disks) this value may be constrained by the maximum transfer length
field in the block limits VPD page.
.TP
\fB\-B\fR, \fB\-\-bytchk\fR=\fINDO\fR
-sets the BYTCHK bit in the VERIFY command. \fINDO\fR is the number of bytes
-to obtain from the \fIFN\fR file (if \fI\-\-in=FN\fR is given) or from stdin.
-Those bytes are placed in the data\-out buffer associated with the SCSI
-VERIFY command. The minimum value for \fINDO\fR is 1 and the maximum value
-is dependant on the OS.
+sets the BYTCHK field to one in the VERIFY command. \fINDO\fR is the number
+of bytes to obtain from the \fIFN\fR file (if \fI\-\-in=FN\fR is given) or
+from stdin. Those bytes are placed in the data\-out buffer associated with
+the SCSI VERIFY command. The minimum value for \fINDO\fR is 1 and the
+maximum value is dependant on the OS. The actual value in the BYTCHK field
+in the VERIFY command may be modified by a \fI\-\-ebytchk=BVAL\fR option.
.TP
\fB\-c\fR, \fB\-\-count\fR=\fICOUNT\fR
where \fICOUNT\fR specifies the number of blocks to verify. The default value
@@ -71,6 +73,15 @@ disable page out changes the cache retention priority of blocks read on
the device's cache to the lowest priority. This means that blocks read by
other commands are more likely to remain in the device's cache.
.TP
+\fB\-E\fR, \fB\-\-ebytchk\fR=\fIBVAL\fR
+sets the BYTCHK field to \fIBVAL\fR overriding the value (1) set by the
+\fI\-\-bytchk=NDO\fR option. Values of 1, 2 or 3 are accepted for \fIBVAL\fR
+however sbc3r34 reserves the value 2. If this option is given then
+\fI\-\-bytchk=NDO\fR must also be given. If \fIBVAL\fR is 3 then \fICOUNT\fR
+must be 1 and \fINDO\fR should be the size of one logical block (plus the
+size of some or all of the protection infomation if \fIVRP\fR is greater
+than 0).
+.TP
\fB\-g\fR, \fB\-\-group\fR=\fIGN\fR
where \fIGN\fR becomes the contents of the group number field in the SCSI
VERIFY(16) command. The default value for \fIGN\fR is 0. Note that this
@@ -106,18 +117,20 @@ where \fIVRP\fR is the value in the vrprotect field in the VERIFY command
cdb. It must be a value between 0 and 7 inclusive. The default value is
zero.
.SH BYTCHK
-BYTCHK is the name of a bit field in the VERIFY(10) and VERIFY(16) commands.
-When set it indicates that associated with the SCSI VERIFY command a
-data\-out buffer will be sent for the device (disk) to check. Using the
-\fI\-\-bytchk=NDO\fR option sets the BYTCHK field and \fINDO\fR is the number
-of bytes placed in the data\-out buffer. Those bytes are obtained from stdin
-or \fIIF\fR (from the \fI\-\-in=FN\fR option).
+BYTCHK is the name of a field (two bits wide) in the VERIFY(10) and
+VERIFY(16) commands. When set to 1 or 3 (sbc3r34 reserves the value 2) it
+indicates that associated with the SCSI VERIFY command, a data\-out buffer
+will be sent for the device (disk) to check. Using the \fI\-\-bytchk=NDO\fR
+option sets the BYTCHK field to 1 and \fINDO\fR is the number of bytes
+placed in the data\-out buffer. Those bytes are obtained from stdin or
+\fIIF\fR (from the \fI\-\-in=FN\fR option). The \fI\-\-ebytchk=BVAL\fR
+option may be used to override the BYTCHK field value of 1 with \fIBVAL\fR.
.PP
The calculation of \fINDO\fR is left up to the user. Its value depends
-on the logical block size (found with the sg_readcap utility), the
-\fICOUNT\fR and the \fIVRP\fR values. If the \fIVRP\fR is greater than 0
-then each logical block will contain an extra 8 bytes (of protection
-information).
+on the logical block size (which cab be found with the sg_readcap utility),
+the \fICOUNT\fR and the \fIVRP\fR values. If the \fIVRP\fR is greater than
+0 then each logical block will contain an extra 8 bytes (at least) of
+protection information.
.PP
When the BYTCHK field is 0 then the verification process done by the
device (disk) is vendor specific. It typically involves checking each
diff --git a/lib/sg_cmds_basic.c b/lib/sg_cmds_basic.c
index 4e0a3ed3..2ff71abb 100644
--- a/lib/sg_cmds_basic.c
+++ b/lib/sg_cmds_basic.c
@@ -27,7 +27,7 @@
#endif
-static char * version_str = "1.57 20120328";
+static char * version_str = "1.58 20121204";
#define SENSE_BUFF_LEN 64 /* Arbitrary, could be larger */
diff --git a/lib/sg_cmds_extra.c b/lib/sg_cmds_extra.c
index 791da154..48534b28 100644
--- a/lib/sg_cmds_extra.c
+++ b/lib/sg_cmds_extra.c
@@ -1575,8 +1575,9 @@ sg_ll_verify10(int sg_fd, int vrprotect, int dpo, int bytchk,
unsigned char sense_b[SENSE_BUFF_LEN];
struct sg_pt_base * ptvp;
+ /* N.B. BYTCHK field expanded to 2 bits sbc3r34 */
vCmdBlk[1] = ((vrprotect & 0x7) << 5) | ((dpo & 0x1) << 4) |
- ((bytchk & 0x1) << 1) ;
+ ((bytchk & 0x3) << 1) ;
vCmdBlk[2] = (unsigned char)((lba >> 24) & 0xff);
vCmdBlk[3] = (unsigned char)((lba >> 16) & 0xff);
vCmdBlk[4] = (unsigned char)((lba >> 8) & 0xff);
@@ -1670,8 +1671,9 @@ sg_ll_verify16(int sg_fd, int vrprotect, int dpo, int bytchk, uint64_t llba,
unsigned char sense_b[SENSE_BUFF_LEN];
struct sg_pt_base * ptvp;
+ /* N.B. BYTCHK field expanded to 2 bits sbc3r34 */
vCmdBlk[1] = ((vrprotect & 0x7) << 5) | ((dpo & 0x1) << 4) |
- ((bytchk & 0x1) << 1) ;
+ ((bytchk & 0x3) << 1) ;
vCmdBlk[2] = (llba >> 56) & 0xff;
vCmdBlk[3] = (llba >> 48) & 0xff;
vCmdBlk[4] = (llba >> 40) & 0xff;
diff --git a/src/sg_inq.c b/src/sg_inq.c
index 295fc2f4..231055d6 100644
--- a/src/sg_inq.c
+++ b/src/sg_inq.c
@@ -66,7 +66,7 @@
* information [MAINTENANCE IN, service action = 0xc]; see sg_opcodes.
*/
-static char * version_str = "1.08 20120927"; /* SPC-4 rev 36 */
+static char * version_str = "1.09 20121204"; /* SPC-4 rev 36 */
/* Following VPD pages are in ascending page number order */
@@ -1856,6 +1856,35 @@ decode_b1_vpd(unsigned char * buff, int len, int do_hex, int pdt)
printf(" Reserved [0x%x]\n", u);
else
printf(" Nominal rotation rate: %d rpm\n", u);
+ printf(" Product type=%d\n", buff[6]);
+ printf(" WABEREQ=%d\n", (buff[7] >> 6) & 0x3);
+ printf(" WACEREQ=%d\n", (buff[7] >> 4) & 0x3);
+ u = buff[7] & 0xf;
+ printf(" Nominal form factor ");
+ switch(u) {
+ case 0:
+ printf("is not reported\n");
+ break;
+ case 1:
+ printf("5.25 inches\n");
+ break;
+ case 2:
+ printf("3.5 inches\n");
+ break;
+ case 3:
+ printf("2.5 inches\n");
+ break;
+ case 4:
+ printf("1.8 inches\n");
+ break;
+ case 5:
+ printf("less then 1.8 inches\n");
+ break;
+ default:
+ printf("reserved [%u]\n", u);
+ break;
+ }
+ printf(" VBULS=%d\n", buff[8] & 0x1);
break;
case PDT_TAPE: case PDT_MCHANGER: case PDT_ADC:
printf(" Manufacturer-assigned serial number: %.*s\n",
diff --git a/src/sg_verify.c b/src/sg_verify.c
index fbb7871c..98719871 100644
--- a/src/sg_verify.c
+++ b/src/sg_verify.c
@@ -25,9 +25,15 @@
*
* This program issues the SCSI VERIFY(10) or VERIFY(16) command to the given
* SCSI block device.
+ *
+ * N.B. This utility should, but doesn't, check the logical block size with
+ * the SCSI READ CAPACITY command. It is up to the user to make sure that
+ * the count of blocks requested and the number of bytes transferred (when
+ * BYTCHK>0) are "in sync". That caclculation is somewhat complicated by
+ * the possibility of protection data (DIF).
*/
-static char * version_str = "1.18 20120927";
+static char * version_str = "1.19 20121204"; /* sbc3r34 */
#define ME "sg_verify: "
@@ -40,6 +46,7 @@ static struct option long_options[] = {
{"bytchk", 1, 0, 'B'},
{"count", 1, 0, 'c'},
{"dpo", 0, 0, 'd'},
+ {"ebytchk", 1, 0, 'E'},
{"group", 1, 0, 'g'},
{"help", 0, 0, 'h'},
{"in", 1, 0, 'i'},
@@ -57,27 +64,38 @@ usage()
fprintf(stderr, "Usage: "
"sg_verify [--16] [--bpc=BPC] [--bytchk=NDO] [--count=COUNT] "
"[--dpo]\n"
- " [--group=GN] [--help] [--in=IF] [--lba=LBA] "
- "[--readonly]\n"
- " [--verbose] [--version] [--vrprotect=VRP] "
- "DEVICE\n"
+ " [--ebytchk=BVAL] [--group=GN] [--help] "
+ "[--in=IF]\n"
+ " [--lba=LBA] [--readonly] [--verbose] "
+ "[--version]\n"
+ " [--vrprotect=VRP] DEVICE\n"
" where:\n"
" --16|-S use VERIFY(16) (def: use "
"VERIFY(10) )\n"
" --bpc=BPC|-b BPC max blocks per verify command "
"(def: 128)\n"
- " --bytchk=NDO|-B NDO set BYTCHK (byte check) bit, NDO is "
+ " --bytchk=NDO|-B NDO set BYTCHK (byte check) to 1, NDO is "
"number of\n"
" bytes placed in data-out buffer. "
"These are\n"
" fetched from IF (or stdin) and used "
"to verify\n"
" the device data against. Forces "
- "--bpc=COUNT\n"
+ "--bpc=COUNT.\n"
" --count=COUNT|-c COUNT count of blocks to verify "
- "(def: 1)\n"
+ "(def: 1).\n"
+ " If BVAL=3 then COUNT must "
+ "be 1 .\n"
" --dpo|-d disable page out (cache retention "
"priority)\n"
+ " --ebytchk=BVAL|-E BVAL extra BYTCHK value, either 1, 2 "
+ "or 3.\n"
+ " BVAL overrides BYTCHK=1 set by "
+ "'--bytchk='\n"
+ " If BVAL is 3 then NDO must be "
+ "the LBA\n"
+ " size (plus protection size if "
+ "DIF active)\n"
" --group=GN|-g GN set group number field to GN (def: 0)\n"
" --help|-h print out usage message\n"
" --in=IF|-i IF input from file called IF (def: "
@@ -92,7 +110,8 @@ usage()
" --vrprotect=VRP|-P VRP set vrprotect field to VRP "
"(def: 0)\n"
"Performs one or more SCSI VERIFY(10) or SCSI VERIFY(16) "
- "commands\n"
+ "commands. sbc3r34\nmade the BYTCHK field two bits wide "
+ "(it was a single bit).\n"
);
}
@@ -103,6 +122,7 @@ main(int argc, char * argv[])
int64_t ll;
int dpo = 0;
int bytchk = 0;
+ int ndo = 0;
char *ref_data = NULL;
int vrprotect = 0;
int64_t count = 1;
@@ -127,7 +147,7 @@ main(int argc, char * argv[])
while (1) {
int option_index = 0;
- c = getopt_long(argc, argv, "b:B:c:dg:hi:l:P:rSvV", long_options,
+ c = getopt_long(argc, argv, "b:B:c:dE:g:hi:l:P:rSvV", long_options,
&option_index);
if (c == -1)
break;
@@ -142,8 +162,8 @@ main(int argc, char * argv[])
++bpc_given;
break;
case 'B':
- bytchk = sg_get_num(optarg);
- if (bytchk < 1) {
+ ndo = sg_get_num(optarg);
+ if (ndo < 1) {
fprintf(stderr, "bad argument to '--bytchk'\n");
return SG_LIB_SYNTAX_ERROR;
}
@@ -158,6 +178,13 @@ main(int argc, char * argv[])
case 'd':
dpo = 1;
break;
+ case 'E':
+ bytchk = sg_get_num(optarg);
+ if ((bytchk < 1) || (bytchk > 3)) {
+ fprintf(stderr, "bad argument to '--ebytchk'\n");
+ return SG_LIB_SYNTAX_ERROR;
+ }
+ break;
case 'g':
group = sg_get_num(optarg);
if ((group < 0) || (group > 31)) {
@@ -223,18 +250,30 @@ main(int argc, char * argv[])
return SG_LIB_SYNTAX_ERROR;
}
}
- if (bytchk > 0) {
+ if (ndo > 0) {
+ if (0 == bytchk)
+ bytchk = 1;
if (bpc_given && (bpc != count))
- fprintf(stderr, "'bpc' argument ignored, using --bpc=COUNT\n");
+ fprintf(stderr, "'bpc' argument ignored, using --bpc=%"
+ PRIu64 "\n", count);
if (count > 0x7fffffffLL) {
fprintf(stderr, "count exceed 31 bits, way too large\n");
return SG_LIB_SYNTAX_ERROR;
}
+ if ((3 == bytchk) && (1 != count)) {
+ fprintf(stderr, "count must be 1 when bytchk=3\n");
+ return SG_LIB_SYNTAX_ERROR;
+ }
bpc = (int)count;
+ } else if (bytchk > 0) {
+ fprintf(stderr, "when the 'ebytchk=BVAL' option is given, "
+ "then '--bytchk=NDO' must also be given\n");
+ return SG_LIB_SYNTAX_ERROR;
}
+
if ((bpc > 0xffff) && (0 == verify16)) {
fprintf(stderr, "'%s' exceeds 65535, so use VERIFY(16)\n",
- (bytchk > 0) ? "count" : "bpc");
+ (ndo > 0) ? "count" : "bpc");
++verify16;
}
if (((lba + count - 1) > 0xffffffffLLU) && (0 == verify16)) {
@@ -248,10 +287,10 @@ main(int argc, char * argv[])
orig_count = count;
orig_lba = lba;
- if (bytchk > 0) {
- ref_data = malloc(bytchk);
+ if (ndo > 0) {
+ ref_data = malloc(ndo);
if (NULL == ref_data) {
- fprintf(stderr, "failed to allocate %d byte buffer\n", bytchk);
+ fprintf(stderr, "failed to allocate %d byte buffer\n", ndo);
return SG_LIB_FILE_ERROR;
}
if ((NULL == file_name) || (0 == strcmp(file_name, "-"))) {
@@ -271,8 +310,8 @@ main(int argc, char * argv[])
}
if (verbose && got_stdin)
fprintf(stderr, "about to wait on STDIN\n");
- for (nread = 0; nread < bytchk; nread += res) {
- res = read(infd, ref_data + nread, bytchk - nread);
+ for (nread = 0; nread < ndo; nread += res) {
+ res = read(infd, ref_data + nread, ndo - nread);
if (res <= 0) {
fprintf(stderr, "reading from %s failed at file offset=%d\n",
(got_stdin ? "stdin" : file_name), nread);
@@ -302,13 +341,13 @@ main(int argc, char * argv[])
for (; count > 0; count -= bpc, lba += bpc) {
num = (count > bpc) ? bpc : count;
if (verify16)
- res = sg_ll_verify16(sg_fd, vrprotect, dpo, bytchk > 0,
+ res = sg_ll_verify16(sg_fd, vrprotect, dpo, bytchk,
lba, num, group, ref_data,
- bytchk, &info64, 1, verbose);
+ ndo, &info64, 1, verbose);
else
- res = sg_ll_verify10(sg_fd, vrprotect, dpo, bytchk > 0,
+ res = sg_ll_verify10(sg_fd, vrprotect, dpo, bytchk,
(unsigned int)lba, num, ref_data,
- bytchk, &info, 1, verbose);
+ ndo, &info, 1, verbose);
if (0 != res) {
ret = res;
switch (res) {
diff --git a/src/sg_vpd.c b/src/sg_vpd.c
index c62056d6..d79a52f7 100644
--- a/src/sg_vpd.c
+++ b/src/sg_vpd.c
@@ -30,7 +30,7 @@
*/
-static char * version_str = "0.63 20121112"; /* spc4r36 + sbc3r33 */
+static char * version_str = "0.64 20121204"; /* spc4r36 + sbc3r34 */
extern void svpd_enumerate_vendor(void);
extern int svpd_decode_vendor(int sg_fd, int num_vpd, int subvalue,
@@ -1686,6 +1686,9 @@ decode_b1_vpd(unsigned char * buff, int len, int do_hex, int pdt)
printf(" Reserved [0x%x]\n", u);
else
printf(" Nominal rotation rate: %d rpm\n", u);
+ printf(" Product type=%d\n", buff[6]);
+ printf(" WABEREQ=%d\n", (buff[7] >> 6) & 0x3);
+ printf(" WACEREQ=%d\n", (buff[7] >> 4) & 0x3);
u = buff[7] & 0xf;
printf(" Nominal form factor");
switch (u) {
@@ -1711,6 +1714,7 @@ decode_b1_vpd(unsigned char * buff, int len, int do_hex, int pdt)
printf(": reserved\n");
break;
}
+ printf(" VBULS=%d\n", buff[8] & 0x1);
break;
case PDT_TAPE: case PDT_MCHANGER: case PDT_ADC:
printf(" Manufacturer-assigned serial number: %.*s\n",