aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDouglas Gilbert <dgilbert@interlog.com>2012-02-18 03:05:34 +0000
committerDouglas Gilbert <dgilbert@interlog.com>2012-02-18 03:05:34 +0000
commitd02d2889c502cdccd3ec326bec8cc6651fc257be (patch)
tree49bf64b8fb0523bf6ecb5e3e029296a4c0768ece
parentdd92db0e9896e4577f2309209920a58c109c1366 (diff)
downloadsg3_utils-d02d2889c502cdccd3ec326bec8cc6651fc257be.tar.gz
sg_verify, 16 byte cdb, bytchk and group number support
git-svn-id: https://svn.bingwo.ca/repos/sg3_utils/trunk@439 6180dd3e-e324-4e3e-922d-17de1ae2f315
-rw-r--r--COVERAGE3
-rw-r--r--ChangeLog4
-rw-r--r--README2
-rw-r--r--debian/changelog2
-rw-r--r--doc/sg_sync.810
-rw-r--r--doc/sg_verify.8108
-rw-r--r--lib/sg_cmds_basic.c4
-rw-r--r--lib/sg_cmds_extra.c22
-rw-r--r--sg3_utils.spec2
-rw-r--r--src/sg_ses.c2
-rw-r--r--src/sg_sync.c8
-rw-r--r--src/sg_verify.c190
12 files changed, 272 insertions, 85 deletions
diff --git a/COVERAGE b/COVERAGE
index 75cc014a..d7291284 100644
--- a/COVERAGE
+++ b/COVERAGE
@@ -62,6 +62,7 @@ SYNCHRONIZE CACHE(10) sg_sync, sg_dd, sgm_dd, sgp_dd, ++
TEST UNIT READY sg_turs, sg_format, ++
UNMAP sg_unmap, ++
VERIFY(10) sg_verify, ++
+VERIFY(16) sg_verify, ++
WRITE(6) sg_dd, sgm_dd, sgp_dd
WRITE(10) sg_dd, sgm_dd, sgp_dd
WRITE(12) sg_dd, sgm_dd, sgp_dd
@@ -96,4 +97,4 @@ SMART READ DATA examples/sg_sat_smart_rd_data
Douglas Gilbert
-21st June 2011
+17th February 2012
diff --git a/ChangeLog b/ChangeLog
index a65b4125..6f49ffe1 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -2,7 +2,9 @@ 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.34 [20120210] [svn: r438]
+Changelog for sg3_utils-1.34 [20120217] [svn: r439]
+ - sg_verify: add 16 byte cdb, bytchk (data-out buffer)
+ and group number support
- sg_pt_linux: expand DID_ (host_byte) codes
Changelog for sg3_utils-1.33 [20120118] [svn: r435]
diff --git a/README b/README
index 046cb6a7..c584c8fc 100644
--- a/README
+++ b/README
@@ -370,4 +370,4 @@ See http://sg.danny.cz/sg/tools.html
Douglas Gilbert
-19th January 2012
+17th February 2012
diff --git a/debian/changelog b/debian/changelog
index e5040962..31cc2a89 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -2,7 +2,7 @@ sg3-utils (1.34-0.1) unstable; urgency=low
* New upstream version
- -- Douglas Gilbert <dgilbert@interlog.com> Thu, 19 Jan 2012 18:00:00 -0500
+ -- Douglas Gilbert <dgilbert@interlog.com> Fri, 17 Feb 2012 22:00:00 -0500
sg3-utils (1.33-0.1) unstable; urgency=low
diff --git a/doc/sg_sync.8 b/doc/sg_sync.8
index 33c57e6f..ffceb4bf 100644
--- a/doc/sg_sync.8
+++ b/doc/sg_sync.8
@@ -1,9 +1,9 @@
-.TH SG_SYNC "8" "March 2009" "sg3_utils\-1.27" SG3_UTILS
+.TH SG_SYNC "8" "February 2012" "sg3_utils\-1.34" SG3_UTILS
.SH NAME
sg_sync \- send the scsi command synchronize cache
.SH SYNOPSIS
.B sg_sync
-[\fI\-\-count=COUNT\fR] [\fI\-\-group=GROUP\fR] [\fI\-\-help\fR]
+[\fI\-\-count=COUNT\fR] [\fI\-\-group=GN\fR] [\fI\-\-help\fR]
[\fI\-\-immed\fR] [\fI\-\-lba=LBA\fR] [\fI\-\-sync\-nv\fR]
[\fI\-\-verbose\fR] [\fI\-\-version\fR] \fIDEVICE\fR
.SH DESCRIPTION
@@ -33,8 +33,8 @@ where \fICOUNT\fR is the number of blocks to synchronize from and including
from and including \fILBA\fR argument to the highest block address are
synchronized.
.TP
-\fB\-g\fR, \fB\-\-group\fR=\fIGROUP\fR
-where \fIGROUP\fR is the group number which can be between 0 and 31 inclusive.
+\fB\-g\fR, \fB\-\-group\fR=\fIGN\fR
+where \fIGN\fR is the group number which can be between 0 and 31 inclusive.
The default value is 0 . Group numbers are used to segregate data collected
within the device. This is a new feature in SBC\-2 and can probably be
ignored for the time being.
@@ -76,7 +76,7 @@ Written by Douglas Gilbert.
.SH "REPORTING BUGS"
Report bugs to <dgilbert at interlog dot com>.
.SH COPYRIGHT
-Copyright \(co 2004\-2009 Douglas Gilbert
+Copyright \(co 2004\-2012 Douglas Gilbert
.br
This software is distributed under a FreeBSD license. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
diff --git a/doc/sg_verify.8 b/doc/sg_verify.8
index 7ff38488..9cd5e51b 100644
--- a/doc/sg_verify.8
+++ b/doc/sg_verify.8
@@ -1,39 +1,66 @@
-.TH SG_VERIFY "8" "February 2011" "sg3_utils\-1.31" SG3_UTILS
+.TH SG_VERIFY "8" "February 2012" "sg3_utils\-1.33" SG3_UTILS
.SH NAME
sg_verify \- invoke SCSI VERIFY command(s) on a block device
.SH SYNOPSIS
.B sg_verify
-[\fI\-\-bpc=BPC\fR] [\fI\-\-count=COUNT\fR] [\fI\-\-dpo\fR] [\fI\-\-help\fR]
-[\fI\-\-lba=LBA\fR] [\fI\-\-readonly\fR] [\fI\-\-verbose\fR]
-[\fI\-\-version\fR] [\fI\-\-vrprotect=VRP\fR] \fIDEVICE\fR
+[\fI\-\-16\fR] [\fI\-\-bpc=BPC\fR] [\fI\-\-bytchk=N\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]
+\fIDEVICE\fR
.SH DESCRIPTION
.\" Add any additional description here
.PP
-Sends one or more SCSI VERIFY commands to \fIDEVICE\fR. It is the 10 byte
-VERIFY command defined for block devices (see SBC\-2 at http://www.t10.org).
-Verify starts at the logical block address given by the \fI\-\-lba=LBA\fR
+Sends one or more SCSI VERIFY (10 or 16) commands to \fIDEVICE\fR. These SCSI
+commands are defined in the SBC\-2 (draft) standard at http://www.t10.org and
+SBC\-3 drafts.
+.PP
+When \fI\-\-bytchk=N\fR is not given (or \fIN\fR is 0 or less) 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).
+.PP
+When \fI\-\-bytchk=N\fR is given (and \fIN\fR is greater than 0) then the
+\fI\-\-bpc=BPC\fR option is ignored. A single verify command is issued and
+it starts at the logical block address given by the \fI\-\-lba=LBA\fR
+option and continues for \fI\-\-count=COUNT\fR blocks. The verify command
+has an associated data\-out buffer that is \fIN\fR bytes long. The contents
+of the data\-out buffer are obtained from the \fIFN\fR file (if
+\fI\-\-in=FN\fR is given) or from stdin.
.SH OPTIONS
Arguments to long options are mandatory for short options as well.
The options are arranged in alphabetical order based on the long
option name.
.TP
+\fB\-S\fR, \fB\-\-16\fR
+uses a VERIFY(16) command (default VERIFY(10)). Even without this option,
+using an \fI\-\-lba=LBA\fR which is too large, will cause the utility
+to issue a VERIFY(16) command.
+.TP
\fB\-b\fR, \fB\-\-bpc\fR=\fIBPC\fR
-where \fIBPC\fR specifies the maximum number of blocks that will be verified
-by a single SCSI VERIFY command. The default value is 128 blocks which
-equates to 64 KB for a disk with 512 byte blocks. If \fIBPC\fR is less than
-\fICOUNT\fR then multiple SCSI VERIFY commands are sent to the device. For
-recent block devices (disks) this value may be constrained by the maximum
-transfer length field in the block limits VPD page.
+this option is ignored if \fI\-\-bytchk=N\fR (with \fIN\fR greater than 0)
+is given. Otherwise \fIBPC\fR specifies the maximum number of blocks that
+will be verified by a single SCSI VERIFY command. The default value is 128
+blocks which equates to 64 KB for a disk with 512 byte blocks. If \fIBPC\fR
+is less than \fICOUNT\fR then multiple SCSI VERIFY commands are sent to the
+device. For recent block devices (disks) this value may be constrained b
+the maximum transfer length field in the block limits VPD page.
+.TP
+\fB\-B\fR, \fB\-\-bytchk\fR=\fIN\fR
+sets the BYTCHK bit in the VERIFY command (if \fIN\fR is greater than 0).
+\fIN\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.
.TP
\fB\-c\fR, \fB\-\-count\fR=\fICOUNT\fR
where \fICOUNT\fR specifies the number of blocks to verify. The default value
is 1 . If \fICOUNT\fR is greater than \fIBPC\fR (or its default value of 128)
-then multiple SCSI VERIFY commands are sent to the device. The
+and \fIN\fR is not given, 0 or less then multiple SCSI VERIFY commands are
+sent to the device. Otherwise \fICOUNT\fR becomes the contents of the
+verification length field of the SCSI VERIFY command issued. The
.B sg_readcap
utility can be used to find the maximum number of blocks that a block
device (e.g. a disk) has.
@@ -43,9 +70,21 @@ 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\-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
+option is ignored for the SCSI VERIFY(10) command.
+.TP
\fB\-h\fR, \fB\-\-help\fR
output the usage message then exit.
.TP
+\fB\-i\fR, \fB\-\-in\fR=\fIIF\fR
+where \fIIF\fR is the name of a file from which \fIN\fR bytes will be read
+and placed in the data\-out buffer. This is only done when the
+\fI\-\-bytchk=N\fR option is given and \fIN\fR is greater than 0. If this
+option is not given then stdin is read. If \fIIF\fR is "\-" then stdin is
+also used.
+.TP
\fB\-l\fR, \fB\-\-lba\fR=\fILBA\fR
where \fILBA\fR specifies the logical block address of the first block to
start the verify operation. \fILBA\fR is assumed to be decimal unless prefixed
@@ -66,20 +105,39 @@ print the version string and then exit.
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=N\fR option (with \fIN\fR greater than 0) sets the
+BYTCHK field and \fIN\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).
+.PP
+The calculation of \fIN\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).
+.PP
+When the BYTCHK field is 0 then the verification process done by the
+device (disk) is vendor specific. It typically involves checking each
+block on the disk against its error correction codes (ECC) which is
+additional data also held on the disk.
.SH NOTES
Various numeric arguments (e.g. \fILBA\fR) may include multiplicative
suffixes or be given in hexadecimal. See the "NUMERIC ARGUMENTS" section
in the sg3_utils(8) man page.
.PP
-The amount of error correction and the number of retries attempted
-before a block is considered defective are controlled in part by the
-Verify Error Recovery mode page. A note in the SBC\-2 (draft)
-standard advises that to minimize the number of checks (and hence
-have the most "sensitive" verify check) do the following in that
-mode page. Set the EER bit to 0, the PER bit to 1, the DTE bit to 1,
-the DCR bit to 1, the verify retry count to 0 and the verify error
-recovery timeout to 0. Mode pages can be modified with the
-.B sginfo
+The amount of error correction and the number of retries attempted before a
+block is considered defective are controlled in part by the Verify Error
+Recovery mode page. A note in the SBC\-3 draft (rev 29 section 6.4.9 on the
+Verify Error Recovery mode page) advises that to minimize the number of
+checks (and hence have the most "sensitive" verify check) do the following
+in that mode page: set the EER bit to 0, the PER bit to 1, the DTE bit to 1,
+the DCR bit to 1, the verify retry count to 0 and the verify recovery time
+limit to 0. Mode pages can be modified with the
+.B sdparm
utility.
.SH EXIT STATUS
The exit status of sg_verify is 0 when it is successful. Otherwise see
@@ -89,10 +147,10 @@ Written by Douglas Gilbert.
.SH "REPORTING BUGS"
Report bugs to <dgilbert at interlog dot com>.
.SH COPYRIGHT
-Copyright \(co 2004\-2011 Douglas Gilbert
+Copyright \(co 2004\-2012 Douglas Gilbert
.br
This software is distributed under a FreeBSD license. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
.SH "SEE ALSO"
-.B sginfo(sg3_utils), sg_modes(sg3_utils), sg_readcap(sg3_utils),
+.B sdparm(sdparm), sg_modes(sg3_utils), sg_readcap(sg3_utils),
.B sg_inq(sg3_utils)
diff --git a/lib/sg_cmds_basic.c b/lib/sg_cmds_basic.c
index 79dbd2b3..06f0f992 100644
--- a/lib/sg_cmds_basic.c
+++ b/lib/sg_cmds_basic.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999-2011 Douglas Gilbert.
+ * Copyright (c) 1999-2012 Douglas Gilbert.
* All rights reserved.
* Use of this source code is governed by a BSD-style
* license that can be found in the BSD_LICENSE file.
@@ -27,7 +27,7 @@
#endif
-static char * version_str = "1.55 20110730";
+static char * version_str = "1.56 20120217";
#define SENSE_BUFF_LEN 64 /* Arbitrary, could be larger */
diff --git a/lib/sg_cmds_extra.c b/lib/sg_cmds_extra.c
index d7233924..647fb81a 100644
--- a/lib/sg_cmds_extra.c
+++ b/lib/sg_cmds_extra.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999-2011 Douglas Gilbert.
+ * Copyright (c) 1999-2012 Douglas Gilbert.
* All rights reserved.
* Use of this source code is governed by a BSD-style
* license that can be found in the BSD_LICENSE file.
@@ -1545,7 +1545,7 @@ sg_ll_write_long16(int sg_fd, int cor_dis, int wr_uncor, int pblock,
* SG_LIB_CAT_NOT_READY -> device not ready, SG_LIB_CAT_ABORTED_COMMAND,
* -1 -> other failure */
int
-sg_ll_verify10(int sg_fd, int vrprotect, int dpo, int bytechk,
+sg_ll_verify10(int sg_fd, int vrprotect, int dpo, int bytchk,
unsigned int lba, int veri_len, void * data_out,
int data_out_len, unsigned int * infop, int noisy,
int verbose)
@@ -1557,7 +1557,7 @@ sg_ll_verify10(int sg_fd, int vrprotect, int dpo, int bytechk,
struct sg_pt_base * ptvp;
vCmdBlk[1] = ((vrprotect & 0x7) << 5) | ((dpo & 0x1) << 4) |
- ((bytechk & 0x1) << 1) ;
+ ((bytchk & 0x1) << 1) ;
vCmdBlk[2] = (unsigned char)((lba >> 24) & 0xff);
vCmdBlk[3] = (unsigned char)((lba >> 16) & 0xff);
vCmdBlk[4] = (unsigned char)((lba >> 8) & 0xff);
@@ -1571,6 +1571,12 @@ sg_ll_verify10(int sg_fd, int vrprotect, int dpo, int bytechk,
for (k = 0; k < VERIFY10_CMDLEN; ++k)
fprintf(sg_warnings_strm, "%02x ", vCmdBlk[k]);
fprintf(sg_warnings_strm, "\n");
+ if ((verbose > 3) && bytchk && data_out && (data_out_len > 0)) {
+ k = data_out_len > 4104 ? 4104 : data_out_len;
+ fprintf(sg_warnings_strm, " data_out buffer%s\n",
+ (data_out_len > 4104 ? ", first 4104 bytes" : ""));
+ dStrHex((const char *)data_out, k, verbose < 5);
+ }
}
ptvp = construct_scsi_pt_obj();
if (NULL == ptvp) {
@@ -1635,7 +1641,7 @@ sg_ll_verify10(int sg_fd, int vrprotect, int dpo, int bytechk,
* SG_LIB_CAT_NOT_READY -> device not ready, SG_LIB_CAT_ABORTED_COMMAND,
* -1 -> other failure */
int
-sg_ll_verify16(int sg_fd, int vrprotect, int dpo, int bytechk, uint64_t llba,
+sg_ll_verify16(int sg_fd, int vrprotect, int dpo, int bytchk, uint64_t llba,
int veri_len, int group_num, void * data_out,
int data_out_len, uint64_t * infop, int noisy, int verbose)
{
@@ -1646,7 +1652,7 @@ sg_ll_verify16(int sg_fd, int vrprotect, int dpo, int bytechk, uint64_t llba,
struct sg_pt_base * ptvp;
vCmdBlk[1] = ((vrprotect & 0x7) << 5) | ((dpo & 0x1) << 4) |
- ((bytechk & 0x1) << 1) ;
+ ((bytchk & 0x1) << 1) ;
vCmdBlk[2] = (llba >> 56) & 0xff;
vCmdBlk[3] = (llba >> 48) & 0xff;
vCmdBlk[4] = (llba >> 40) & 0xff;
@@ -1667,6 +1673,12 @@ sg_ll_verify16(int sg_fd, int vrprotect, int dpo, int bytechk, uint64_t llba,
for (k = 0; k < VERIFY16_CMDLEN; ++k)
fprintf(sg_warnings_strm, "%02x ", vCmdBlk[k]);
fprintf(sg_warnings_strm, "\n");
+ if ((verbose > 3) && bytchk && data_out && (data_out_len > 0)) {
+ k = data_out_len > 4104 ? 4104 : data_out_len;
+ fprintf(sg_warnings_strm, " data_out buffer%s\n",
+ (data_out_len > 4104 ? ", first 4104 bytes" : ""));
+ dStrHex((const char *)data_out, k, verbose < 5);
+ }
}
ptvp = construct_scsi_pt_obj();
if (NULL == ptvp) {
diff --git a/sg3_utils.spec b/sg3_utils.spec
index a3c21308..e85553cd 100644
--- a/sg3_utils.spec
+++ b/sg3_utils.spec
@@ -79,7 +79,7 @@ fi
%{_libdir}/*.la
%changelog
-* Thu Jan 19 2012 - dgilbert at interlog dot com
+* Fri Feb 17 2012 - dgilbert at interlog dot com
- track t10 changes
* sg3_utils-1.34
diff --git a/src/sg_ses.c b/src/sg_ses.c
index b52fc14d..9e76c390 100644
--- a/src/sg_ses.c
+++ b/src/sg_ses.c
@@ -27,7 +27,7 @@
* commands tailored for SES (enclosure) devices.
*/
-static char * version_str = "1.64 20120118"; /* ses3r03 */
+static char * version_str = "1.65 20120214"; /* ses3r04 */
#define MX_ALLOC_LEN 4096
#define MX_ELEM_HDR 1024
diff --git a/src/sg_sync.c b/src/sg_sync.c
index b616c590..e6692c9d 100644
--- a/src/sg_sync.c
+++ b/src/sg_sync.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2004-2010 Douglas Gilbert.
+ * Copyright (c) 2004-2012 Douglas Gilbert.
* All rights reserved.
* Use of this source code is governed by a BSD-style
* license that can be found in the BSD_LICENSE file.
@@ -23,7 +23,7 @@
* (e.g. disks).
*/
-static char * version_str = "1.08 20100312";
+static char * version_str = "1.09 20120217";
static struct option long_options[] = {
@@ -41,14 +41,14 @@ static struct option long_options[] = {
static void usage()
{
fprintf(stderr, "Usage: "
- "sg_sync [--count=COUNT] [--group=GROUP] [--help] [--immed]\n"
+ "sg_sync [--count=COUNT] [--group=GN] [--help] [--immed]\n"
" [--lba=LBA] [--sync-nv] [--verbose] [--version] "
"DEVICE\n"
" where:\n"
" --count=COUNT|-c COUNT number of blocks to sync (def: 0 "
"which implies\n"
" rest of device)\n"
- " --group=GROUP|-g GROUP set group number (def: 0)\n"
+ " --group=GN|-g GN set group number field to GN (def: 0)\n"
" --help|-h print out usage message\n"
" --immed|-i command returns immediately when set "
"else wait\n"
diff --git a/src/sg_verify.c b/src/sg_verify.c
index fae9e859..c33e9add 100644
--- a/src/sg_verify.c
+++ b/src/sg_verify.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2004-2011 Douglas Gilbert.
+ * Copyright (c) 2004-2012 Douglas Gilbert.
* All rights reserved.
* Use of this source code is governed by a BSD-style
* license that can be found in the BSD_LICENSE file.
@@ -23,19 +23,26 @@
/* A utility program for the Linux OS SCSI subsystem.
*
- * This program issues the SCSI VERIFY command to the given SCSI block device.
+ * This program issues the SCSI VERIFY(10) or VERIFY(16) command to the given
+ * SCSI block device.
*/
-static char * version_str = "1.15 20110206";
+static char * version_str = "1.16 20120217";
#define ME "sg_verify: "
+#define EBUFF_SZ 256
+
static struct option long_options[] = {
+ {"16", 0, 0, 'S'},
{"bpc", 1, 0, 'b'},
+ {"bytchk", 1, 0, 'B'},
{"count", 1, 0, 'c'},
{"dpo", 0, 0, 'd'},
+ {"group", 1, 0, 'g'},
{"help", 0, 0, 'h'},
+ {"in", 1, 0, 'i'},
{"lba", 1, 0, 'l'},
{"readonly", 0, 0, 'r'},
{"verbose", 0, 0, 'v'},
@@ -48,19 +55,32 @@ static void
usage()
{
fprintf(stderr, "Usage: "
- "sg_verify [--bpc=BPC] [--count=COUNT] [--dpo] [--help] "
- "[--lba=LBA]\n"
- " [--readonly] [--verbose] [--version] "
- "[--vrprotect=VRP]\n"
- " DEVICE\n"
+ "sg_verify [--16] [--bpc=BPC] [--bytchk=N] [--count=COUNT] "
+ "[--dpo]\n"
+ " [--group=GN] [--help] [--in=IF] [--lba=LBA] "
+ "[--readonly]\n"
+ " [--verbose] [--version] [--vrprotect=VRP] "
+ "DEVICE\n"
" where:\n"
+ " --16|-S use VERIFY(16) (default: use "
+ "VERIFY(10) )\n"
" --bpc=BPC|-b BPC max blocks per verify command "
"(def 128)\n"
+ " --bytchk=N|-B set BYTCHK (byte check) bit, N is "
+ "number of\n"
+ " bytes fetched from IF (or stdin) "
+ "to verify the\n"
+ " device data against. Forces "
+ "--bpc=COUNT\n"
" --count=COUNT|-c COUNT count of blocks to verify "
"(def 1)\n"
" --dpo|-d disable page out (cache retention "
"priority)\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 (default: "
+ "stdin)\n"
+ " only active if --bytchk=N given\n"
" --lba=LBA|-l LBA logical block address to start "
"verify (def 0)\n"
" --readonly|-r open DEVICE read-only (def: open it "
@@ -69,33 +89,43 @@ usage()
" --version|-V print version string and exit\n"
" --vrprotect=VRP|-P VRP set vrprotect field to VRP "
"(def 0)\n"
- "Performs a SCSI VERIFY(10) command\n"
+ "Performs one or more SCSI VERIFY(10) or SCSI VERIFY(16) "
+ "commands\n"
);
}
int
main(int argc, char * argv[])
{
- int sg_fd, res, c, num;
+ int sg_fd, res, c, num, nread, infd;
int64_t ll;
int dpo = 0;
- int bytechk = 0;
+ int bytchk = -1;
+ char *ref_data = NULL;
int vrprotect = 0;
int64_t count = 1;
int64_t orig_count;
int bpc = 128;
+ int bpc_given = 0;
+ int got_stdin = 0;
+ int group = 0;
uint64_t lba = 0;
uint64_t orig_lba;
int readonly = 0;
int verbose = 0;
+ int verify16 = 0;
const char * device_name = NULL;
+ const char * file_name = NULL;
+ const char * vc;
int ret = 0;
unsigned int info = 0;
+ uint64_t info64 = 0;
+ char ebuff[EBUFF_SZ];
while (1) {
int option_index = 0;
- c = getopt_long(argc, argv, "b:c:dhl:P:rvV", long_options,
+ c = getopt_long(argc, argv, "b:B:c:dg:hi:l:P:rSvV", long_options,
&option_index);
if (c == -1)
break;
@@ -107,6 +137,14 @@ main(int argc, char * argv[])
fprintf(stderr, "bad argument to '--bpc'\n");
return SG_LIB_SYNTAX_ERROR;
}
+ ++bpc_given;
+ break;
+ case 'B':
+ bytchk = sg_get_num(optarg);
+ if (-1 == bytchk) {
+ fprintf(stderr, "bad argument to '--bytchk'\n");
+ return SG_LIB_SYNTAX_ERROR;
+ }
break;
case 'c':
count = sg_get_llnum(optarg);
@@ -118,10 +156,20 @@ main(int argc, char * argv[])
case 'd':
dpo = 1;
break;
+ case 'g':
+ group = sg_get_num(optarg);
+ if ((group < 0) || (group > 31)) {
+ fprintf(stderr, "bad argument to '--group'\n");
+ return SG_LIB_SYNTAX_ERROR;
+ }
+ break;
case 'h':
case '?':
usage();
return 0;
+ case 'i':
+ file_name = optarg;
+ break;
case 'l':
ll = sg_get_llnum(optarg);
if (-1 == ll) {
@@ -145,6 +193,9 @@ main(int argc, char * argv[])
case 'r':
++readonly;
break;
+ case 'S':
+ ++verify16;
+ break;
case 'v':
++verbose;
break;
@@ -170,66 +221,125 @@ main(int argc, char * argv[])
return SG_LIB_SYNTAX_ERROR;
}
}
- if (bpc > 0xffff) {
- fprintf(stderr, "'bpc' cannot exceed 65535\n");
- usage();
- return SG_LIB_SYNTAX_ERROR;
+ if (bytchk > 0) {
+ if (bpc_given && (bpc != count))
+ fprintf(stderr, "'bpc' argument ignored, using --bpc=COUNT\n");
+ if (count > 0x7fffffffLL) {
+ fprintf(stderr, "count exceed 31 bits, way too large\n");
+ return SG_LIB_SYNTAX_ERROR;
+ }
+ bpc = (int)count;
}
- if (lba > 0xffffffffLLU) {
- fprintf(stderr, "'lba' cannot exceed 32 bits\n");
- usage();
- return SG_LIB_SYNTAX_ERROR;
+ if ((bpc > 0xffff) && (0 == verify16)) {
+ fprintf(stderr, "'%s' exceeds 65535, so use VERIFY(16)\n",
+ (bytchk > 0) ? "count" : "bpc");
+ ++verify16;
+ }
+ if ((lba > 0xffffffffLLU) && (0 == verify16)) {
+ fprintf(stderr, "'lba' exceed 32 bits, so use VERIFY(16)\n");
+ ++verify16;
}
+ if ((group > 0) && (0 == verify16))
+ fprintf(stderr, "group number ignored with VERIFY(10) command, "
+ "use the --16 option\n");
+
orig_count = count;
orig_lba = lba;
+ if (bytchk > 0) {
+ ref_data = malloc(bytchk);
+ if (NULL == ref_data) {
+ fprintf(stderr, "failed to allocate %d byte buffer\n", bytchk);
+ return SG_LIB_FILE_ERROR;
+ }
+ if ((NULL == file_name) || (0 == strcmp(file_name, "-"))) {
+ ++got_stdin;
+ infd = STDIN_FILENO;
+ if (sg_set_binary_mode(STDIN_FILENO) < 0)
+ perror("sg_set_binary_mode");
+ } else {
+ if ((infd = open(file_name, O_RDONLY)) < 0) {
+ snprintf(ebuff, EBUFF_SZ,
+ ME "could not open %s for reading", file_name);
+ perror(ebuff);
+ ret = SG_LIB_FILE_ERROR;
+ goto err_out;
+ } else if (sg_set_binary_mode(infd) < 0)
+ perror("sg_set_binary_mode");
+ }
+ for (nread = 0; nread < bytchk; nread += res) {
+ res = read(infd, ref_data + nread, bytchk - nread);
+ if (res <= 0) {
+ fprintf(stderr, "reading from %s failed at file offset=%d\n",
+ (got_stdin ? "stdin" : file_name), nread);
+ ret = SG_LIB_FILE_ERROR;
+ goto err_out;
+ }
+ }
+ if (! got_stdin)
+ close(infd);
+ } else
+ bytchk = 0;
+
if (NULL == device_name) {
fprintf(stderr, "missing device name!\n");
usage();
- return SG_LIB_SYNTAX_ERROR;
+ ret = SG_LIB_SYNTAX_ERROR;
+ goto err_out;
}
sg_fd = sg_cmds_open_device(device_name, readonly, verbose);
if (sg_fd < 0) {
fprintf(stderr, ME "open error: %s: %s\n", device_name,
safe_strerror(-sg_fd));
- return SG_LIB_FILE_ERROR;
+ ret = SG_LIB_FILE_ERROR;
+ goto err_out;
}
+ vc = verify16 ? "VERIFY(16)" : "VERIFY(10)";
for (; count > 0; count -= bpc, lba +=bpc) {
num = (count > bpc) ? bpc : count;
- res = sg_ll_verify10(sg_fd, vrprotect, dpo, bytechk,
- (unsigned int)lba, num, NULL, 0,
- &info, 1, verbose);
+ if (verify16)
+ res = sg_ll_verify16(sg_fd, vrprotect, dpo, bytchk >= 0,
+ lba, num, group, ref_data,
+ bytchk, &info64, 1, verbose);
+ else
+ res = sg_ll_verify10(sg_fd, vrprotect, dpo, bytchk >= 0,
+ (unsigned int)lba, num, ref_data,
+ bytchk, &info, 1, verbose);
if (0 != res) {
ret = res;
switch (res) {
case SG_LIB_CAT_NOT_READY:
- fprintf(stderr, "Verify(10) failed, device not ready\n");
+ fprintf(stderr, "%s failed, device not ready\n", vc);
break;
case SG_LIB_CAT_UNIT_ATTENTION:
- fprintf(stderr, "Verify(10), unit attention\n");
+ fprintf(stderr, "%s, unit attention\n", vc);
break;
case SG_LIB_CAT_ABORTED_COMMAND:
- fprintf(stderr, "Verify(10), aborted command\n");
+ fprintf(stderr, "%s, aborted command\n", vc);
break;
case SG_LIB_CAT_INVALID_OP:
- fprintf(stderr, "Verify(10) command not supported\n");
+ fprintf(stderr, "%s command not supported\n", vc);
break;
case SG_LIB_CAT_ILLEGAL_REQ:
- fprintf(stderr, "bad field in Verify(10) cdb, near "
- "lba=0x%" PRIx64 "\n", lba);
+ fprintf(stderr, "bad field in %s cdb, near lba=0x%" PRIx64
+ "\n", vc, lba);
break;
case SG_LIB_CAT_MEDIUM_HARD:
- fprintf(stderr, "medium or hardware error near "
- "lba=0x%" PRIx64 "\n", lba);
+ fprintf(stderr, "%s medium or hardware error near "
+ "lba=0x%" PRIx64 "\n", vc, lba);
break;
case SG_LIB_CAT_MEDIUM_HARD_WITH_INFO:
- fprintf(stderr, "medium or hardware error, reported "
- "lba=0x%x\n", info);
+ if (verify16)
+ fprintf(stderr, "%s medium or hardware error, reported "
+ "lba=0x%" PRIx64 "\n", vc, info64);
+ else
+ fprintf(stderr, "%s medium or hardware error, reported "
+ "lba=0x%x\n", vc, info);
break;
default:
- fprintf(stderr, "Verify(10) failed near lba=%" PRIu64
- " [0x%" PRIx64 "]\n", lba, lba);
+ fprintf(stderr, "%s failed near lba=%" PRIu64 " [0x%" PRIx64
+ "]\n", vc, lba, lba);
break;
}
break;
@@ -245,7 +355,11 @@ main(int argc, char * argv[])
if (res < 0) {
fprintf(stderr, "close error: %s\n", safe_strerror(-res));
if (0 == ret)
- return SG_LIB_FILE_ERROR;
+ ret = SG_LIB_FILE_ERROR;
}
+
+ err_out:
+ if (ref_data)
+ free(ref_data);
return (ret >= 0) ? ret : SG_LIB_CAT_OTHER;
}