aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog10
-rw-r--r--doc/sg_dd.820
-rw-r--r--doc/sg_verify.836
-rw-r--r--doc/sg_write_same.828
-rw-r--r--include/sg_lib.h12
-rw-r--r--lib/sg_cmds_basic.c47
-rw-r--r--lib/sg_cmds_basic2.c121
-rw-r--r--lib/sg_cmds_extra.c334
-rw-r--r--lib/sg_lib.c77
-rw-r--r--lib/sg_lib_data.c4
-rw-r--r--src/sg_bg_ctl.c13
-rw-r--r--src/sg_compare_and_write.c13
-rw-r--r--src/sg_dd.c120
-rw-r--r--src/sg_format.c13
-rw-r--r--src/sg_get_elem_status.c15
-rw-r--r--src/sg_opcodes.c24
-rw-r--r--src/sg_raw.c15
-rw-r--r--src/sg_rbuf.c26
-rw-r--r--src/sg_read.c11
-rw-r--r--src/sg_read_attr.c13
-rw-r--r--src/sg_read_buffer.c24
-rw-r--r--src/sg_rep_zones.c14
-rw-r--r--src/sg_reset_wp.c13
-rw-r--r--src/sg_sanitize.c13
-rw-r--r--src/sg_stream_ctl.c20
-rw-r--r--src/sg_sync.c13
-rw-r--r--src/sg_test_rwbuf.c35
-rw-r--r--src/sg_timestamp.c22
-rw-r--r--src/sg_verify.c62
-rw-r--r--src/sg_write_same.c37
-rw-r--r--src/sg_write_verify.c14
-rw-r--r--src/sg_write_x.c10
-rw-r--r--src/sg_zone.c13
-rw-r--r--src/sgm_dd.c22
-rw-r--r--testing/sgh_dd.cpp263
35 files changed, 914 insertions, 613 deletions
diff --git a/ChangeLog b/ChangeLog
index 336ce088..4762214b 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.45 [20191206] [svn: r836]
+Changelog for sg3_utils-1.45 [20191227] [svn: r837]
- sg_get_elem_status: new utility [sbc4r16]
- sg_ses: bug: --page= being overridden when --control
and --data= also given; fix
@@ -41,9 +41,16 @@ Changelog for sg3_utils-1.45 [20191206] [svn: r836]
- sg_reassign: for defect list format 6 (vendor
specfic) don't try to decode
- sg_rep_zones: expand some fields per zbc2r04
+ - sg_verify: correct so issues VERIFY(16)
+ - add --0 and --ff options and implement
+ bytchk=3 properly
+ - sg_write_same: add --ff for 0xff fill
+ - sg_dd: add --verify support
- inhex directory: new, contains ASCII hex files
that can be used with the '--inhex=' option
- sg_lib: add sg_t10_uuid_desig2str()
+ - add sg_get_command_str and sg_print_command_len()
+ - speed up sg_print_command()
- sg_scsi_normalize_sense(): populate byte4,5,6
- tweak sg_pt interface to better handle bidi
- sg_cmds_process_resp(): two arguments removed
@@ -67,6 +74,7 @@ Changelog for sg3_utils-1.45 [20191206] [svn: r836]
- testing/sg_tst_ioctl: for sg 4.0 driver
- testing/sg_tst_bidi: for sg 4.0 driver
- testing/sgh_dd: test request sharing, mreqs...
+ - add --verify support
- testing/sgs_dd: back from archive, for testing
- testing/sg_chk_asc: allow LF and CR/LF in asc-num.txt
- testing: 'make' now builds both C and C++ programs
diff --git a/doc/sg_dd.8 b/doc/sg_dd.8
index 872c43cf..d8fcd487 100644
--- a/doc/sg_dd.8
+++ b/doc/sg_dd.8
@@ -1,4 +1,4 @@
-.TH SG_DD "8" "February 2019" "sg3_utils\-1.45" SG3_UTILS
+.TH SG_DD "8" "December 2019" "sg3_utils\-1.45" SG3_UTILS
.SH NAME
sg_dd \- copy data to and from files and devices, especially SCSI
devices
@@ -13,6 +13,7 @@ devices
[\fIcoe=\fR{0|1|2|3}] [\fIcoe_limit=CL\fR] [\fIdio=\fR{0|1}]
[\fIodir=\fR{0|1}] [\fIof2=OFILE2\fR] [\fIretries=RETR\fR] [\fIsync=\fR{0|1}]
[\fItime=\fR{0|1}] [\fIverbose=VERB\fR] [\fI\-\-dry\-run\fR] [\fI\-V\fR]
+[\fI\-\-verify\fR]
.SH DESCRIPTION
.\" Add any additional description here
.PP
@@ -28,6 +29,15 @@ The first group in the synopsis above are "standard" Unix
operands. The second group are extra options added by this utility.
Both groups are defined below.
.PP
+When the \fI\-\-verify\fR option is given, then the read side is the
+same but the on the write side, the WRITE SCSI command is replaced by
+the VERIFY SCSI command. If any VERIFY commands yields a sense key of
+MISCOMPARE then the verify operation will stop. The \fI\-\-verify\fR
+option can only be used when \fIOFILE\fR is either a sg device or
+a block device with oflag=sgio also given. When the \fI\-\-verify\fR
+option is used, this utility works in a similar fashion to the Unix
+cmp(1) command.
+.PP
This utility is only supported on Linux whereas most other utilities in the
sg3_utils package have been ported to other operating systems. A utility
called "ddpt" has similar syntax and functionality to sg_dd. ddpt drops some
@@ -208,6 +218,12 @@ outputs usage message and exits.
when used once, this is equivalent to \fIverbose=1\fR. When used
twice (e.g. "\-vv") this is equivalent to \fIverbose=2\fR, etc.
.TP
+\fB\-x\fR, \fB\-\-verify\fR
+do a verify operation (like Unix command cmp(1)) rather than a copy.
+Cannot be used with "oflag=sparse". \fIof=OFILE\fR must be given and
+\fIOFILE\fR must be an sg device or a block device with "oflag=sgio"
+alsoe given.
+.TP
\fB\-V\fR, \fB\-\-version\fR
outputs version number information and exits.
.SH CONVERSIONS
@@ -496,6 +512,8 @@ Copyright \(co 2000\-2019 Douglas Gilbert
This software is distributed under the GPL version 2. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
.SH "SEE ALSO"
+cmp(1)
+.PP
There is a web page discussing sg_dd at http://sg.danny.cz/sg/sg_dd.html
.PP
A POSIX threads version of this utility called
diff --git a/doc/sg_verify.8 b/doc/sg_verify.8
index 51c8f880..425af3bb 100644
--- a/doc/sg_verify.8
+++ b/doc/sg_verify.8
@@ -1,19 +1,19 @@
-.TH SG_VERIFY "8" "January 2018" "sg3_utils\-1.43" SG3_UTILS
+.TH SG_VERIFY "8" "December 2019" "sg3_utils\-1.45" 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\-\-count=COUNT\fR] [\fI\-\-dpo\fR]
-[\fI\-\-ebytchk=BCH\fR] [\fI\-\-group=GN\fR] [\fI\-\-help\fR]
-[\fI\-\-in=IF\fR] [\fI\-\-lba=LBA\fR] [\fI\-\-ndo=NDO\fR] [\fI\-\-quiet\fR]
-[\fI\-\-readonly\fR] [\fI\-\-verbose\fR] [\fI\-\-version\fR]
-[\fI\-\-vrprotect=VRP\fR] \fIDEVICE\fR
+[\fI\-\-0\fR] [\fI\-\-16\fR] [\fI\-\-bpc=BPC\fR] [\fI\-\-count=COUNT\fR]
+[\fI\-\-dpo\fR] [\fI\-\-ff\fR] [\fI\-\-ebytchk=BCH\fR] [\fI\-\-group=GN\fR]
+[\fI\-\-help\fR] [\fI\-\-in=IF\fR] [\fI\-\-lba=LBA\fR] [\fI\-\-ndo=NDO\fR]
+[\fI\-\-quiet\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 (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.
+commands are defined in the SBC\-2 and SBC\-3 standards at http://www.t10.org
+and SBC\-4 drafts.
.PP
When \fI\-\-ndo=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
@@ -45,6 +45,12 @@ 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\-0\fR, \fB\-\-0\fR
+a buffer \fINDO\fR bytes long full of zeros is sent as the data\-out
+part of a VERIFY command. So stdin is not read and if \fI\-\-in=IF\fR
+is given, an error is generated. Useful when \fIBCH\fR is 3 to check
+if some or all of \fIDEVICE\fR (e.g. a disk) is zero filled blocks.
+.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
@@ -80,11 +86,17 @@ other commands are more likely to remain in the device's cache.
sets the BYTCHK field to \fIBCH\fR overriding the value (1) set by the
\fI\-\-ndo=NDO\fR option. Values of 1, 2 or 3 are accepted for \fIBCH\fR
however sbc3r34 reserves the value 2. If this option is given then
-\fI\-\-ndo=NDO\fR must also be given. If \fIBCH\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 information if \fIVRP\fR is greater
+\fI\-\-ndo=NDO\fR must also be given. If \fIBCH\fR is 3 then \fINDO\fR
+should be the size of one logical block (plus the size of some or all
+of the protection information if \fIVRP\fR is greater
than 0).
.TP
+\fB\-f\fR, \fB\-\-ff\fR
+a buffer \fINDO\fR bytes long full of 0xff bytes is sent as the data\-out
+part of a VERIFY command. So stdin is not read and if \fI\-\-in=IF\fR
+is given, an error is generated. Useful when \fIBCH\fR is 3 to check
+if some or all of \fIDEVICE\fR (e.g. a disk) is 0xff byte filled blocks.
+.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. It can be from 0 to 63 inclusive. The default value for
@@ -198,7 +210,7 @@ Written by Douglas Gilbert.
.SH "REPORTING BUGS"
Report bugs to <dgilbert at interlog dot com>.
.SH COPYRIGHT
-Copyright \(co 2004\-2018 Douglas Gilbert
+Copyright \(co 2004\-2019 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_write_same.8 b/doc/sg_write_same.8
index 55e739d9..55dcfec9 100644
--- a/doc/sg_write_same.8
+++ b/doc/sg_write_same.8
@@ -1,13 +1,14 @@
-.TH SG_WRITE_SAME "8" "November 2017" "sg3_utils\-1.43" SG3_UTILS
+.TH SG_WRITE_SAME "8" "December 2019" "sg3_utils\-1.45" SG3_UTILS
.SH NAME
sg_write_same \- send SCSI WRITE SAME command
.SH SYNOPSIS
.B sg_write_same
[\fI\-\-10\fR] [\fI\-\-16\fR] [\fI\-\-32\fR] [\fI\-\-anchor\fR]
-[\fI\-\-grpnum=GN\fR] [\fI\-\-help\fR] [\fI\-\-in=IF\fR] [\fI\-\-lba=LBA\fR]
-[\fI\-\-lbdata\fR] [\fI\-\-num=NUM\fR] [\fI\-\-ndob\fR] [\fI\-\-pbdata\fR]
-[\fI\-\-timeout=TO\fR] [\fI\-\-unmap\fR] [\fI\-\-verbose\fR]
-[\fI\-\-version\fR] [\fI\-\-wrprotect=WPR\fR] [\fI\-\-xferlen=LEN\fR]
+[\fI\-\-ff\fR] [\fI\-\-grpnum=GN\fR] [\fI\-\-help\fR] [\fI\-\-in=IF\fR]
+[\fI\-\-lba=LBA\fR] [\fI\-\-lbdata\fR] [\fI\-\-num=NUM\fR]
+[\fI\-\-ndob\fR] [\fI\-\-pbdata\fR] [\fI\-\-timeout=TO\fR]
+[\fI\-\-unmap\fR] [\fI\-\-verbose\fR] [\fI\-\-version\fR]
+[\fI\-\-wrprotect=WPR\fR] [\fI\-\-xferlen=LEN\fR]
\fIDEVICE\fR
.SH DESCRIPTION
.\" Add any additional description here
@@ -86,6 +87,10 @@ send a SCSI WRITE SAME (32) command to \fIDEVICE\fR.
sets the ANCHOR bit in the cdb. Introduced in SBC\-3 revision 22.
That draft requires the \fI\-\-unmap\fR option to also be specified.
.TP
+\fB\-f\fR, \fB\-\-ff\fR
+the data\-out buffer sent with this command is initialized with 0xff bytes
+when this option is given.
+.TP
\fB\-g\fR, \fB\-\-grpnum\fR=\fIGN\fR
sets the 'Group number' field to \fIGN\fR. Defaults to a value of zero.
\fIGN\fR should be a value between 0 and 63.
@@ -97,11 +102,12 @@ output the usage message then exit.
read data (binary) from file named \fIIF\fR and use it as the data\-out
buffer for the SCSI WRITE SAME command. The length of the data\-out buffer
is \fI\-\-xferlen=LEN\fR or, if that is not given, the length of the \fIIF\fR
-file. If \fIIF\fR is "\-" then stdin is read. If this option is not given
-then 0x00 bytes are used as fill with the length of the data\-out buffer
-obtained from \fI\-\-xferlen=LEN\fR or by calling READ CAPACITY(16 or 10).
-If the response to READ CAPACITY(16) has the PROT_EN bit set then data\-
-out buffer size is modified accordingly with the last 8 bytes set to 0xff.
+file. If \fIIF\fR is "\-" then stdin is read. If this option and the
+\fI\-\-ff\fR are not given then 0x00 bytes are used as fill with the length
+of the data\-out buffer obtained from \fI\-\-xferlen=LEN\fR or by calling
+READ CAPACITY(16 or 10). If the response to READ CAPACITY(16) has the
+PROT_EN bit set then data\- out buffer size is modified accordingly with
+the last 8 bytes set to 0xff.
.TP
\fB\-l\fR, \fB\-\-lba\fR=\fILBA\fR
where \fILBA\fR is the logical block address to start the WRITE SAME command.
@@ -316,7 +322,7 @@ Written by Douglas Gilbert.
.SH "REPORTING BUGS"
Report bugs to <dgilbert at interlog dot com>.
.SH COPYRIGHT
-Copyright \(co 2009\-2017 Douglas Gilbert
+Copyright \(co 2009\-2019 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/include/sg_lib.h b/include/sg_lib.h
index 169b0ea5..0b722069 100644
--- a/include/sg_lib.h
+++ b/include/sg_lib.h
@@ -378,9 +378,21 @@ extern FILE * sg_warnings_strm;
void sg_set_warnings_strm(FILE * warnings_strm);
+/* Given a SCSI command pointed to by cmdp of sz bytes this function forms a
+ * SCSI command in ASCII hex surrounded by square brackets in 'b'. 'b' is at
+ * least blen bytes long. If cmd_name is true then the command is prefixed
+ * by its SCSI command name (e.g. "VERIFY(10) [2f ...]". The command is
+ * shown as spaced separated pairs of hexadecimal digits (i.e. 0-9, a-f).
+ * Each pair repesents byte. The leftmost pair of digits is cmdp[0] . If
+ * sz <= 0 then this function tries to guess the length of the command. */
+char *
+sg_get_command_str(const uint8_t * cmdp, int sz, bool cmd_name, int blen,
+ char * b);
+
/* The following "print" functions send ASCII to 'sg_warnings_strm' file
* descriptor (default value is stderr). 'leadin' is string prepended to
* each line printed out, NULL treated as "". */
+void sg_print_command_len(const uint8_t * command, int len);
void sg_print_command(const uint8_t * command);
void sg_print_scsi_status(int scsi_status);
diff --git a/lib/sg_cmds_basic.c b/lib/sg_cmds_basic.c
index 470c2f1c..c119c51f 100644
--- a/lib/sg_cmds_basic.c
+++ b/lib/sg_cmds_basic.c
@@ -42,7 +42,7 @@
#endif
-static const char * const version_str = "1.94 20190913";
+static const char * const version_str = "1.95 20191219";
#define SENSE_BUFF_LEN 64 /* Arbitrary, could be larger */
@@ -371,7 +371,7 @@ sg_ll_inquiry_com(struct sg_pt_base * ptvp, bool cmddt, bool evpd, int pg_op,
void * resp, int mx_resp_len, int timeout_secs,
int * residp, bool noisy, int verbose)
{
- int res, ret, k, sense_cat, resid;
+ int res, ret, sense_cat, resid;
uint8_t inq_cdb[INQUIRY_CMDLEN] = {INQUIRY_CMD, 0, 0, 0, 0, 0};
uint8_t sense_b[SENSE_BUFF_LEN];
uint8_t * up;
@@ -389,10 +389,11 @@ sg_ll_inquiry_com(struct sg_pt_base * ptvp, bool cmddt, bool evpd, int pg_op,
/* 16 bit allocation length (was 8, increased in spc3r09, 200209) */
sg_put_unaligned_be16((uint16_t)mx_resp_len, inq_cdb + 3);
if (verbose) {
- pr2ws(" %s cdb: ", inquiry_s);
- for (k = 0; k < INQUIRY_CMDLEN; ++k)
- pr2ws("%02x ", inq_cdb[k]);
- pr2ws("\n");
+ char b[128];
+
+ pr2ws(" %s cdb: %s\n", inquiry_s,
+ sg_get_command_str(inq_cdb, INQUIRY_CMDLEN, false, sizeof(b),
+ b));
}
if (resp && (mx_resp_len > 0)) {
up = (uint8_t *)resp;
@@ -598,15 +599,15 @@ sg_ll_test_unit_ready_progress_pt(struct sg_pt_base * ptvp, int pack_id,
int * progress, bool noisy, int verbose)
{
static const char * const tur_s = "test unit ready";
- int res, ret, k, sense_cat;
+ int res, ret, sense_cat;
uint8_t tur_cdb[TUR_CMDLEN] = {TUR_CMD, 0, 0, 0, 0, 0};
uint8_t sense_b[SENSE_BUFF_LEN];
if (verbose) {
- pr2ws(" %s cdb: ", tur_s);
- for (k = 0; k < TUR_CMDLEN; ++k)
- pr2ws("%02x ", tur_cdb[k]);
- pr2ws("\n");
+ char b[128];
+
+ pr2ws(" %s cdb: %s\n", tur_s,
+ sg_get_command_str(tur_cdb, TUR_CMDLEN, false, sizeof(b), b));
}
clear_scsi_pt_obj(ptvp);
@@ -688,7 +689,7 @@ sg_ll_request_sense_com(struct sg_pt_base * ptvp, int sg_fd, bool desc,
void * resp, int mx_resp_len, bool noisy, int verbose)
{
bool ptvp_given = false;
- int k, ret, res, sense_cat;
+ int ret, res, sense_cat;
static const char * const rq_s = "request sense";
uint8_t rs_cdb[REQUEST_SENSE_CMDLEN] =
{REQUEST_SENSE_CMD, 0, 0, 0, 0, 0};
@@ -702,12 +703,12 @@ sg_ll_request_sense_com(struct sg_pt_base * ptvp, int sg_fd, bool desc,
}
rs_cdb[4] = mx_resp_len & 0xff;
if (verbose) {
- pr2ws(" %s cmd: ", rq_s);
- for (k = 0; k < REQUEST_SENSE_CMDLEN; ++k)
- pr2ws("%02x ", rs_cdb[k]);
- pr2ws("\n");
- }
+ char b[128];
+ pr2ws(" %s cdb: %s\n", rq_s,
+ sg_get_command_str(rs_cdb, REQUEST_SENSE_CMDLEN, false,
+ sizeof(b), b));
+ }
if (ptvp)
ptvp_given = true;
else {
@@ -771,7 +772,7 @@ sg_ll_report_luns_com(struct sg_pt_base * ptvp, int sg_fd, int select_report,
{
static const char * const report_luns_s = "report luns";
bool ptvp_given = false;
- int k, ret, res, sense_cat;
+ int ret, res, sense_cat;
uint8_t rl_cdb[REPORT_LUNS_CMDLEN] =
{REPORT_LUNS_CMD, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
uint8_t sense_b[SENSE_BUFF_LEN];
@@ -779,12 +780,12 @@ sg_ll_report_luns_com(struct sg_pt_base * ptvp, int sg_fd, int select_report,
rl_cdb[2] = select_report & 0xff;
sg_put_unaligned_be32((uint32_t)mx_resp_len, rl_cdb + 6);
if (verbose) {
- pr2ws(" %s cdb: ", report_luns_s);
- for (k = 0; k < REPORT_LUNS_CMDLEN; ++k)
- pr2ws("%02x ", rl_cdb[k]);
- pr2ws("\n");
- }
+ char b[128];
+ pr2ws(" %s cdb: %s\n", report_luns_s,
+ sg_get_command_str(rl_cdb, REPORT_LUNS_CMDLEN, false,
+ sizeof(b), b));
+ }
if (ptvp)
ptvp_given = true;
else if (NULL == ((ptvp = create_pt_obj(report_luns_s))))
diff --git a/lib/sg_cmds_basic2.c b/lib/sg_cmds_basic2.c
index e8536385..c6c8c0bf 100644
--- a/lib/sg_cmds_basic2.c
+++ b/lib/sg_cmds_basic2.c
@@ -90,7 +90,7 @@ sg_ll_sync_cache_10(int sg_fd, bool sync_nv, bool immed, int group,
int verbose)
{
static const char * const cdb_s = "synchronize cache(10)";
- int res, ret, k, sense_cat;
+ int res, ret, sense_cat;
uint8_t sc_cdb[SYNCHRONIZE_CACHE_CMDLEN] =
{SYNCHRONIZE_CACHE_CMD, 0, 0, 0, 0, 0, 0, 0, 0, 0};
uint8_t sense_b[SENSE_BUFF_LEN];
@@ -109,10 +109,11 @@ sg_ll_sync_cache_10(int sg_fd, bool sync_nv, bool immed, int group,
sg_put_unaligned_be16((int16_t)count, sc_cdb + 7);
if (verbose) {
- pr2ws(" %s cdb: ", cdb_s);
- for (k = 0; k < SYNCHRONIZE_CACHE_CMDLEN; ++k)
- pr2ws("%02x ", sc_cdb[k]);
- pr2ws("\n");
+ char b[128];
+
+ pr2ws(" %s cdb: %s\n", cdb_s,
+ sg_get_command_str(sc_cdb, SYNCHRONIZE_CACHE_CMDLEN, false,
+ sizeof(b), b));
}
if (NULL == ((ptvp = create_pt_obj(cdb_s))))
return -1;
@@ -146,7 +147,7 @@ sg_ll_readcap_16(int sg_fd, bool pmi, uint64_t llba, void * resp,
int mx_resp_len, bool noisy, int verbose)
{
static const char * const cdb_s = "read capacity(16)";
- int k, ret, res, sense_cat;
+ int ret, res, sense_cat;
uint8_t rc_cdb[SERVICE_ACTION_IN_16_CMDLEN] =
{SERVICE_ACTION_IN_16_CMD, READ_CAPACITY_16_SA,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
@@ -160,10 +161,11 @@ sg_ll_readcap_16(int sg_fd, bool pmi, uint64_t llba, void * resp,
/* Allocation length, no guidance in SBC-2 rev 15b */
sg_put_unaligned_be32((uint32_t)mx_resp_len, rc_cdb + 10);
if (verbose) {
- pr2ws(" %s cdb: ", cdb_s);
- for (k = 0; k < SERVICE_ACTION_IN_16_CMDLEN; ++k)
- pr2ws("%02x ", rc_cdb[k]);
- pr2ws("\n");
+ char b[128];
+
+ pr2ws(" %s cdb: %s\n", cdb_s,
+ sg_get_command_str(rc_cdb, SERVICE_ACTION_IN_16_CMDLEN, false,
+ sizeof(b), b));
}
if (NULL == ((ptvp = create_pt_obj(cdb_s))))
return -1;
@@ -198,7 +200,7 @@ sg_ll_readcap_10(int sg_fd, bool pmi, unsigned int lba, void * resp,
int mx_resp_len, bool noisy, int verbose)
{
static const char * const cdb_s = "read capacity(10)";
- int k, ret, res, sense_cat;
+ int ret, res, sense_cat;
uint8_t rc_cdb[READ_CAPACITY_10_CMDLEN] =
{READ_CAPACITY_10_CMD, 0, 0, 0, 0, 0, 0, 0, 0, 0};
uint8_t sense_b[SENSE_BUFF_LEN];
@@ -209,10 +211,11 @@ sg_ll_readcap_10(int sg_fd, bool pmi, unsigned int lba, void * resp,
sg_put_unaligned_be32((uint32_t)lba, rc_cdb + 2);
}
if (verbose) {
- pr2ws(" %s cdb: ", cdb_s);
- for (k = 0; k < READ_CAPACITY_10_CMDLEN; ++k)
- pr2ws("%02x ", rc_cdb[k]);
- pr2ws("\n");
+ char b[128];
+
+ pr2ws(" %s cdb: %s\n", cdb_s,
+ sg_get_command_str(rc_cdb, READ_CAPACITY_10_CMDLEN, false,
+ sizeof(b), b));
}
if (NULL == ((ptvp = create_pt_obj(cdb_s))))
return -1;
@@ -247,7 +250,7 @@ sg_ll_mode_sense6(int sg_fd, bool dbd, int pc, int pg_code, int sub_pg_code,
void * resp, int mx_resp_len, bool noisy, int verbose)
{
static const char * const cdb_s = "mode sense(6)";
- int res, ret, k, sense_cat, resid;
+ int res, ret, sense_cat, resid;
uint8_t modes_cdb[MODE_SENSE6_CMDLEN] =
{MODE_SENSE6_CMD, 0, 0, 0, 0, 0};
uint8_t sense_b[SENSE_BUFF_LEN];
@@ -262,10 +265,11 @@ sg_ll_mode_sense6(int sg_fd, bool dbd, int pc, int pg_code, int sub_pg_code,
return -1;
}
if (verbose) {
- pr2ws(" %s cdb: ", cdb_s);
- for (k = 0; k < MODE_SENSE6_CMDLEN; ++k)
- pr2ws("%02x ", modes_cdb[k]);
- pr2ws("\n");
+ char b[128];
+
+ pr2ws(" %s cdb: %s\n", cdb_s,
+ sg_get_command_str(modes_cdb, MODE_SENSE6_CMDLEN, false,
+ sizeof(b), b));
}
if (NULL == ((ptvp = create_pt_obj(cdb_s))))
return -1;
@@ -340,7 +344,7 @@ sg_ll_mode_sense10_v2(int sg_fd, bool llbaa, bool dbd, int pc, int pg_code,
int sub_pg_code, void * resp, int mx_resp_len,
int timeout_secs, int * residp, bool noisy, int verbose)
{
- int res, ret, k, sense_cat, resid;
+ int res, ret, sense_cat, resid;
static const char * const cdb_s = "mode sense(10)";
struct sg_pt_base * ptvp;
uint8_t modes_cdb[MODE_SENSE10_CMDLEN] =
@@ -356,10 +360,11 @@ sg_ll_mode_sense10_v2(int sg_fd, bool llbaa, bool dbd, int pc, int pg_code,
goto gen_err;
}
if (verbose) {
- pr2ws(" %s cdb: ", cdb_s);
- for (k = 0; k < MODE_SENSE10_CMDLEN; ++k)
- pr2ws("%02x ", modes_cdb[k]);
- pr2ws("\n");
+ char b[128];
+
+ pr2ws(" %s cdb: %s\n", cdb_s,
+ sg_get_command_str(modes_cdb, MODE_SENSE10_CMDLEN, false,
+ sizeof(b), b));
}
if (timeout_secs <= 0)
timeout_secs = DEF_PT_TIMEOUT;
@@ -425,7 +430,7 @@ sg_ll_mode_select6_v2(int sg_fd, bool pf, bool rtd, bool sp, void * paramp,
int param_len, bool noisy, int verbose)
{
static const char * const cdb_s = "mode select(6)";
- int res, ret, k, sense_cat;
+ int res, ret, sense_cat;
uint8_t modes_cdb[MODE_SELECT6_CMDLEN] =
{MODE_SELECT6_CMD, 0, 0, 0, 0, 0};
uint8_t sense_b[SENSE_BUFF_LEN];
@@ -440,10 +445,11 @@ sg_ll_mode_select6_v2(int sg_fd, bool pf, bool rtd, bool sp, void * paramp,
return -1;
}
if (verbose) {
- pr2ws(" %s cdb: ", cdb_s);
- for (k = 0; k < MODE_SELECT6_CMDLEN; ++k)
- pr2ws("%02x ", modes_cdb[k]);
- pr2ws("\n");
+ char b[128];
+
+ pr2ws(" %s cdb: %s\n", cdb_s,
+ sg_get_command_str(modes_cdb, MODE_SELECT6_CMDLEN, false,
+ sizeof(b), b));
}
if (verbose > 1) {
pr2ws(" %s parameter list\n", cdb_s);
@@ -492,7 +498,7 @@ sg_ll_mode_select10_v2(int sg_fd, bool pf, bool rtd, bool sp, void * paramp,
int param_len, bool noisy, int verbose)
{
static const char * const cdb_s = "mode select(10)";
- int res, ret, k, sense_cat;
+ int res, ret, sense_cat;
uint8_t modes_cdb[MODE_SELECT10_CMDLEN] =
{MODE_SELECT10_CMD, 0, 0, 0, 0, 0, 0, 0, 0, 0};
uint8_t sense_b[SENSE_BUFF_LEN];
@@ -507,10 +513,11 @@ sg_ll_mode_select10_v2(int sg_fd, bool pf, bool rtd, bool sp, void * paramp,
return -1;
}
if (verbose) {
- pr2ws(" %s cdb: ", cdb_s);
- for (k = 0; k < MODE_SELECT10_CMDLEN; ++k)
- pr2ws("%02x ", modes_cdb[k]);
- pr2ws("\n");
+ char b[128];
+
+ pr2ws(" %s cdb: %s\n", cdb_s,
+ sg_get_command_str(modes_cdb, MODE_SELECT10_CMDLEN, false,
+ sizeof(b), b));
}
if (verbose > 1) {
pr2ws(" %s parameter list\n", cdb_s);
@@ -787,7 +794,7 @@ sg_ll_log_sense_v2(int sg_fd, bool ppc, bool sp, int pc, int pg_code,
bool noisy, int verbose)
{
static const char * const cdb_s = "log sense";
- int res, ret, k, sense_cat, resid;
+ int res, ret, sense_cat, resid;
uint8_t logs_cdb[LOG_SENSE_CMDLEN] =
{LOG_SENSE_CMD, 0, 0, 0, 0, 0, 0, 0, 0, 0};
uint8_t sense_b[SENSE_BUFF_LEN];
@@ -803,10 +810,11 @@ sg_ll_log_sense_v2(int sg_fd, bool ppc, bool sp, int pc, int pg_code,
sg_put_unaligned_be16((int16_t)paramp, logs_cdb + 5);
sg_put_unaligned_be16((int16_t)mx_resp_len, logs_cdb + 7);
if (verbose) {
- pr2ws(" %s cdb: ", cdb_s);
- for (k = 0; k < LOG_SENSE_CMDLEN; ++k)
- pr2ws("%02x ", logs_cdb[k]);
- pr2ws("\n");
+ char b[128];
+
+ pr2ws(" %s cdb: %s\n", cdb_s,
+ sg_get_command_str(logs_cdb, LOG_SENSE_CMDLEN, false,
+ sizeof(b), b));
}
if (timeout_secs <= 0)
timeout_secs = DEF_PT_TIMEOUT;
@@ -867,7 +875,7 @@ sg_ll_log_select(int sg_fd, bool pcr, bool sp, int pc, int pg_code,
bool noisy, int verbose)
{
static const char * const cdb_s = "log select";
- int res, ret, k, sense_cat;
+ int res, ret, sense_cat;
uint8_t logs_cdb[LOG_SELECT_CMDLEN] =
{LOG_SELECT_CMD, 0, 0, 0, 0, 0, 0, 0, 0, 0};
uint8_t sense_b[SENSE_BUFF_LEN];
@@ -882,10 +890,11 @@ sg_ll_log_select(int sg_fd, bool pcr, bool sp, int pc, int pg_code,
logs_cdb[3] = (uint8_t)(subpg_code & 0xff);
sg_put_unaligned_be16((int16_t)param_len, logs_cdb + 7);
if (verbose) {
- pr2ws(" %s cdb: ", cdb_s);
- for (k = 0; k < LOG_SELECT_CMDLEN; ++k)
- pr2ws("%02x ", logs_cdb[k]);
- pr2ws("\n");
+ char b[128];
+
+ pr2ws(" %s cdb: %s\n", cdb_s,
+ sg_get_command_str(logs_cdb, LOG_SELECT_CMDLEN, false,
+ sizeof(b), b));
}
if ((verbose > 1) && (param_len > 0)) {
pr2ws(" %s parameter list\n", cdb_s);
@@ -949,7 +958,7 @@ sg_ll_start_stop_unit_pt(struct sg_pt_base * ptvp, bool immed,
bool loej, bool start, bool noisy, int verbose)
{
static const char * const cdb_s = "start stop unit";
- int k, res, ret, sense_cat;
+ int res, ret, sense_cat;
uint8_t ssuBlk[START_STOP_CMDLEN] = {START_STOP_CMD, 0, 0, 0, 0, 0};
uint8_t sense_b[SENSE_BUFF_LEN];
@@ -964,10 +973,11 @@ sg_ll_start_stop_unit_pt(struct sg_pt_base * ptvp, bool immed,
if (start)
ssuBlk[4] |= 0x1;
if (verbose) {
- pr2ws(" %s command:", cdb_s);
- for (k = 0; k < (int)sizeof(ssuBlk); ++k)
- pr2ws(" %02x", ssuBlk[k]);
- pr2ws("\n");
+ char b[128];
+
+ pr2ws(" %s cdb: %s\n", cdb_s,
+ sg_get_command_str(ssuBlk, sizeof(ssuBlk), false,
+ sizeof(b), b));
}
clear_scsi_pt_obj(ptvp);
@@ -1001,7 +1011,7 @@ int
sg_ll_prevent_allow(int sg_fd, int prevent, bool noisy, int verbose)
{
static const char * const cdb_s = "prevent allow medium removal";
- int k, res, ret, sense_cat;
+ int res, ret, sense_cat;
uint8_t p_cdb[PREVENT_ALLOW_CMDLEN] =
{PREVENT_ALLOW_CMD, 0, 0, 0, 0, 0};
uint8_t sense_b[SENSE_BUFF_LEN];
@@ -1013,10 +1023,11 @@ sg_ll_prevent_allow(int sg_fd, int prevent, bool noisy, int verbose)
}
p_cdb[4] |= (prevent & 0x3);
if (verbose) {
- pr2ws(" %s cdb: ", cdb_s);
- for (k = 0; k < PREVENT_ALLOW_CMDLEN; ++k)
- pr2ws("%02x ", p_cdb[k]);
- pr2ws("\n");
+ char b[128];
+
+ pr2ws(" %s cdb: %s\n", cdb_s,
+ sg_get_command_str(p_cdb, PREVENT_ALLOW_CMDLEN, false,
+ sizeof(b), b));
}
if (NULL == ((ptvp = create_pt_obj(cdb_s))))
diff --git a/lib/sg_cmds_extra.c b/lib/sg_cmds_extra.c
index 96558883..71af0358 100644
--- a/lib/sg_cmds_extra.c
+++ b/lib/sg_cmds_extra.c
@@ -123,7 +123,7 @@ sg_ll_get_lba_status16(int sg_fd, uint64_t start_llba, uint8_t rt,
void * resp, int alloc_len, bool noisy, int vb)
{
static const char * const cdb_s = "Get LBA status(16)";
- int k, res, s_cat, ret;
+ int res, s_cat, ret;
uint8_t getLbaStatCmd[SERVICE_ACTION_IN_16_CMDLEN];
uint8_t sense_b[SENSE_BUFF_LEN];
struct sg_pt_base * ptvp;
@@ -136,10 +136,11 @@ sg_ll_get_lba_status16(int sg_fd, uint64_t start_llba, uint8_t rt,
sg_put_unaligned_be32((uint32_t)alloc_len, getLbaStatCmd + 10);
getLbaStatCmd[14] = rt;
if (vb) {
- pr2ws(" %s cdb: ", cdb_s);
- for (k = 0; k < SERVICE_ACTION_IN_16_CMDLEN; ++k)
- pr2ws("%02x ", getLbaStatCmd[k]);
- pr2ws("\n");
+ char b[128];
+
+ pr2ws(" %s cdb: %s\n", cdb_s,
+ sg_get_command_str(getLbaStatCmd, SERVICE_ACTION_IN_16_CMDLEN,
+ false, sizeof(b), b));
}
if (NULL == ((ptvp = create_pt_obj(cdb_s))))
@@ -196,7 +197,7 @@ sg_ll_get_lba_status32(int sg_fd, uint64_t start_llba, uint32_t scan_len,
int vb)
{
static const char * const cdb_s = "Get LBA status(32)";
- int k, res, s_cat, ret;
+ int res, s_cat, ret;
uint8_t gls32_cmd[GLS32_CMD_LEN];
uint8_t sense_b[SENSE_BUFF_LEN];
struct sg_pt_base * ptvp;
@@ -211,10 +212,11 @@ sg_ll_get_lba_status32(int sg_fd, uint64_t start_llba, uint32_t scan_len,
sg_put_unaligned_be32(element_id, gls32_cmd + 24);
sg_put_unaligned_be32((uint32_t)alloc_len, gls32_cmd + 28);
if (vb) {
- pr2ws(" %s cdb: ", cdb_s);
- for (k = 0; k < GLS32_CMD_LEN; ++k)
- pr2ws("%02x ", gls32_cmd[k]);
- pr2ws("\n");
+ char b[128];
+
+ pr2ws(" %s cdb: %s\n", cdb_s,
+ sg_get_command_str(gls32_cmd, GLS32_CMD_LEN, false, sizeof(b),
+ b));
}
if (NULL == ((ptvp = create_pt_obj(cdb_s))))
@@ -269,7 +271,7 @@ sg_ll_report_tgt_prt_grp2(int sg_fd, void * resp, int mx_resp_len,
bool extended, bool noisy, int vb)
{
static const char * const cdb_s = "Report target port groups";
- int k, res, ret, s_cat;
+ int res, ret, s_cat;
uint8_t rtpg_cdb[MAINTENANCE_IN_CMDLEN] =
{MAINTENANCE_IN_CMD, REPORT_TGT_PRT_GRP_SA,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
@@ -280,10 +282,11 @@ sg_ll_report_tgt_prt_grp2(int sg_fd, void * resp, int mx_resp_len,
rtpg_cdb[1] |= 0x20;
sg_put_unaligned_be32((uint32_t)mx_resp_len, rtpg_cdb + 6);
if (vb) {
- pr2ws(" %s cdb: ", cdb_s);
- for (k = 0; k < MAINTENANCE_IN_CMDLEN; ++k)
- pr2ws("%02x ", rtpg_cdb[k]);
- pr2ws("\n");
+ char b[128];
+
+ pr2ws(" %s cdb: %s\n", cdb_s,
+ sg_get_command_str(rtpg_cdb, MAINTENANCE_IN_CMDLEN,
+ false, sizeof(b), b));
}
if (NULL == ((ptvp = create_pt_obj(cdb_s))))
@@ -330,7 +333,7 @@ sg_ll_set_tgt_prt_grp(int sg_fd, void * paramp, int param_len, bool noisy,
int vb)
{
static const char * const cdb_s = "Set target port groups";
- int k, res, ret, s_cat;
+ int res, ret, s_cat;
uint8_t stpg_cdb[MAINTENANCE_OUT_CMDLEN] =
{MAINTENANCE_OUT_CMD, SET_TGT_PRT_GRP_SA,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
@@ -339,10 +342,11 @@ sg_ll_set_tgt_prt_grp(int sg_fd, void * paramp, int param_len, bool noisy,
sg_put_unaligned_be32((uint32_t)param_len, stpg_cdb + 6);
if (vb) {
- pr2ws(" %s cdb: ", cdb_s);
- for (k = 0; k < MAINTENANCE_OUT_CMDLEN; ++k)
- pr2ws("%02x ", stpg_cdb[k]);
- pr2ws("\n");
+ char b[128];
+
+ pr2ws(" %s cdb: %s\n", cdb_s,
+ sg_get_command_str(stpg_cdb, MAINTENANCE_OUT_CMDLEN,
+ false, sizeof(b), b));
if ((vb > 1) && paramp && param_len) {
pr2ws(" %s parameter list:\n", cdb_s);
hex2stderr((const uint8_t *)paramp, param_len, -1);
@@ -382,7 +386,7 @@ sg_ll_report_referrals(int sg_fd, uint64_t start_llba, bool one_seg,
int vb)
{
static const char * const cdb_s = "Report referrals";
- int k, res, ret, s_cat;
+ int res, ret, s_cat;
uint8_t repRef_cdb[SERVICE_ACTION_IN_16_CMDLEN] =
{SERVICE_ACTION_IN_16_CMD, REPORT_REFERRALS_SA,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
@@ -394,10 +398,11 @@ sg_ll_report_referrals(int sg_fd, uint64_t start_llba, bool one_seg,
if (one_seg)
repRef_cdb[14] = 0x1;
if (vb) {
- pr2ws(" %s cdb: ", cdb_s);
- for (k = 0; k < SERVICE_ACTION_IN_16_CMDLEN; ++k)
- pr2ws("%02x ", repRef_cdb[k]);
- pr2ws("\n");
+ char b[128];
+
+ pr2ws(" %s cdb: %s\n", cdb_s,
+ sg_get_command_str(repRef_cdb, SERVICE_ACTION_IN_16_CMDLEN,
+ false, sizeof(b), b));
}
if (NULL == ((ptvp = create_pt_obj(cdb_s))))
@@ -449,7 +454,7 @@ sg_ll_send_diag_pt(struct sg_pt_base * ptvp, int st_code, bool pf_bit,
bool noisy, int vb)
{
static const char * const cdb_s = "Send diagnostic";
- int k, res, ret, s_cat, tmout;
+ int res, ret, s_cat, tmout;
uint8_t senddiag_cdb[SEND_DIAGNOSTIC_CMDLEN] =
{SEND_DIAGNOSTIC_CMD, 0, 0, 0, 0, 0};
uint8_t sense_b[SENSE_BUFF_LEN];
@@ -470,10 +475,11 @@ sg_ll_send_diag_pt(struct sg_pt_base * ptvp, int st_code, bool pf_bit,
tmout = long_duration ? LONG_PT_TIMEOUT : DEF_PT_TIMEOUT;
if (vb) {
- pr2ws(" %s cdb: ", cdb_s);
- for (k = 0; k < SEND_DIAGNOSTIC_CMDLEN; ++k)
- pr2ws("%02x ", senddiag_cdb[k]);
- pr2ws("\n");
+ char b[128];
+
+ pr2ws(" %s cdb: %s\n", cdb_s,
+ sg_get_command_str(senddiag_cdb, SEND_DIAGNOSTIC_CMDLEN,
+ false, sizeof(b), b));
if (vb > 1) {
if (paramp && param_len) {
pr2ws(" %s parameter list:\n", cdb_s);
@@ -532,7 +538,7 @@ sg_ll_receive_diag_pt(struct sg_pt_base * ptvp, bool pcv, int pg_code,
int * residp, bool noisy, int vb)
{
int resid = 0;
- int k, res, ret, s_cat;
+ int res, ret, s_cat;
static const char * const cdb_s = "Receive diagnostic results";
uint8_t rcvdiag_cdb[RECEIVE_DIAGNOSTICS_CMDLEN] =
{RECEIVE_DIAGNOSTICS_CMD, 0, 0, 0, 0, 0};
@@ -544,10 +550,11 @@ sg_ll_receive_diag_pt(struct sg_pt_base * ptvp, bool pcv, int pg_code,
sg_put_unaligned_be16((uint16_t)mx_resp_len, rcvdiag_cdb + 3);
if (vb) {
- pr2ws(" %s cdb: ", cdb_s);
- for (k = 0; k < RECEIVE_DIAGNOSTICS_CMDLEN; ++k)
- pr2ws("%02x ", rcvdiag_cdb[k]);
- pr2ws("\n");
+ char b[128];
+
+ pr2ws(" %s cdb: %s\n", cdb_s,
+ sg_get_command_str(rcvdiag_cdb, RECEIVE_DIAGNOSTICS_CMDLEN,
+ false, sizeof(b), b));
}
if (timeout_secs <= 0)
timeout_secs = DEF_PT_TIMEOUT;
@@ -632,7 +639,7 @@ sg_ll_read_defect10(int sg_fd, bool req_plist, bool req_glist, int dl_format,
void * resp, int mx_resp_len, bool noisy, int vb)
{
static const char * const cdb_s = "Read defect(10)";
- int res, k, ret, s_cat;
+ int res, ret, s_cat;
uint8_t rdef_cdb[READ_DEFECT10_CMDLEN] =
{READ_DEFECT10_CMD, 0, 0, 0, 0, 0, 0, 0, 0, 0};
uint8_t sense_b[SENSE_BUFF_LEN];
@@ -649,10 +656,11 @@ sg_ll_read_defect10(int sg_fd, bool req_plist, bool req_glist, int dl_format,
return -1;
}
if (vb) {
- pr2ws(" %s cdb: ", cdb_s);
- for (k = 0; k < READ_DEFECT10_CMDLEN; ++k)
- pr2ws("%02x ", rdef_cdb[k]);
- pr2ws("\n");
+ char b[128];
+
+ pr2ws(" %s cdb: %s\n", cdb_s,
+ sg_get_command_str(rdef_cdb, READ_DEFECT10_CMDLEN,
+ false, sizeof(b), b));
}
if (NULL == ((ptvp = create_pt_obj(cdb_s))))
@@ -699,7 +707,7 @@ sg_ll_read_media_serial_num(int sg_fd, void * resp, int mx_resp_len,
bool noisy, int vb)
{
static const char * const cdb_s = "Read media serial number";
- int k, res, ret, s_cat;
+ int res, ret, s_cat;
uint8_t rmsn_cdb[SERVICE_ACTION_IN_12_CMDLEN] =
{SERVICE_ACTION_IN_12_CMD, READ_MEDIA_SERIAL_NUM_SA,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
@@ -708,10 +716,11 @@ sg_ll_read_media_serial_num(int sg_fd, void * resp, int mx_resp_len,
sg_put_unaligned_be32((uint32_t)mx_resp_len, rmsn_cdb + 6);
if (vb) {
- pr2ws(" %s cdb: ", cdb_s);
- for (k = 0; k < SERVICE_ACTION_IN_12_CMDLEN; ++k)
- pr2ws("%02x ", rmsn_cdb[k]);
- pr2ws("\n");
+ char b[128];
+
+ pr2ws(" %s cdb: %s\n", cdb_s,
+ sg_get_command_str(rmsn_cdb, SERVICE_ACTION_IN_12_CMDLEN,
+ false, sizeof(b), b));
}
if (NULL == ((ptvp = create_pt_obj(cdb_s))))
@@ -759,7 +768,7 @@ sg_ll_report_id_info(int sg_fd, int itype, void * resp, int max_resp_len,
bool noisy, int vb)
{
static const char * const cdb_s = "Report identifying information";
- int k, res, ret, s_cat;
+ int res, ret, s_cat;
uint8_t rii_cdb[MAINTENANCE_IN_CMDLEN] = {MAINTENANCE_IN_CMD,
REPORT_IDENTIFYING_INFORMATION_SA,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
@@ -770,10 +779,11 @@ sg_ll_report_id_info(int sg_fd, int itype, void * resp, int max_resp_len,
rii_cdb[10] |= (itype << 1) & 0xfe;
if (vb) {
- pr2ws(" %s cdb: ", cdb_s);
- for (k = 0; k < MAINTENANCE_IN_CMDLEN; ++k)
- pr2ws("%02x ", rii_cdb[k]);
- pr2ws("\n");
+ char b[128];
+
+ pr2ws(" %s cdb: %s\n", cdb_s,
+ sg_get_command_str(rii_cdb, MAINTENANCE_IN_CMDLEN,
+ false, sizeof(b), b));
}
if (NULL == ((ptvp = create_pt_obj(cdb_s))))
@@ -821,7 +831,7 @@ sg_ll_set_id_info(int sg_fd, int itype, void * paramp, int param_len,
bool noisy, int vb)
{
static const char * const cdb_s = "Set identifying information";
- int k, res, ret, s_cat;
+ int res, ret, s_cat;
uint8_t sii_cdb[MAINTENANCE_OUT_CMDLEN] = {MAINTENANCE_OUT_CMD,
SET_IDENTIFYING_INFORMATION_SA,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
@@ -831,10 +841,11 @@ sg_ll_set_id_info(int sg_fd, int itype, void * paramp, int param_len,
sg_put_unaligned_be32((uint32_t)param_len, sii_cdb + 6);
sii_cdb[10] |= (itype << 1) & 0xfe;
if (vb) {
- pr2ws(" %s cdb: ", cdb_s);
- for (k = 0; k < MAINTENANCE_OUT_CMDLEN; ++k)
- pr2ws("%02x ", sii_cdb[k]);
- pr2ws("\n");
+ char b[128];
+
+ pr2ws(" %s cdb: %s\n", cdb_s,
+ sg_get_command_str(sii_cdb, MAINTENANCE_OUT_CMDLEN,
+ false, sizeof(b), b));
if ((vb > 1) && paramp && param_len) {
pr2ws(" %s parameter list:\n", cdb_s);
hex2stderr((const uint8_t *)paramp, param_len, -1);
@@ -901,7 +912,7 @@ sg_ll_format_unit_v2(int sg_fd, int fmtpinfo, bool longlist, bool fmtdata,
bool noisy, int vb)
{
static const char * const cdb_s = "Format unit";
- int k, res, ret, s_cat, tmout;
+ int res, ret, s_cat, tmout;
uint8_t fu_cdb[FORMAT_UNIT_CMDLEN] =
{FORMAT_UNIT_CMD, 0, 0, 0, 0, 0};
uint8_t sense_b[SENSE_BUFF_LEN];
@@ -921,10 +932,10 @@ sg_ll_format_unit_v2(int sg_fd, int fmtpinfo, bool longlist, bool fmtdata,
fu_cdb[4] |= (ffmt & 0x3);
tmout = (timeout_secs > 0) ? timeout_secs : DEF_PT_TIMEOUT;
if (vb) {
- pr2ws(" %s cdb: ", cdb_s);
- for (k = 0; k < 6; ++k)
- pr2ws("%02x ", fu_cdb[k]);
- pr2ws("\n");
+ char b[128];
+
+ pr2ws(" %s cdb: %s\n", cdb_s,
+ sg_get_command_str(fu_cdb, 6, false, sizeof(b), b));
if (vb > 1) {
if (param_len > 0) {
pr2ws(" %s parameter list:\n", cdb_s);
@@ -967,7 +978,7 @@ sg_ll_reassign_blocks(int sg_fd, bool longlba, bool longlist, void * paramp,
int param_len, bool noisy, int vb)
{
static const char * const cdb_s = "Reassign blocks";
- int res, k, ret, s_cat;
+ int res, ret, s_cat;
uint8_t reass_cdb[REASSIGN_BLKS_CMDLEN] =
{REASSIGN_BLKS_CMD, 0, 0, 0, 0, 0};
uint8_t sense_b[SENSE_BUFF_LEN];
@@ -978,10 +989,11 @@ sg_ll_reassign_blocks(int sg_fd, bool longlba, bool longlist, void * paramp,
if (longlist)
reass_cdb[1] |= 0x1;
if (vb) {
- pr2ws(" %s cdb: ", cdb_s);
- for (k = 0; k < REASSIGN_BLKS_CMDLEN; ++k)
- pr2ws("%02x ", reass_cdb[k]);
- pr2ws("\n");
+ char b[128];
+
+ pr2ws(" %s cdb: %s\n", cdb_s,
+ sg_get_command_str(reass_cdb, REASSIGN_BLKS_CMDLEN, false,
+ sizeof(b), b));
}
if (vb > 1) {
pr2ws(" %s parameter list\n", cdb_s);
@@ -1022,7 +1034,7 @@ sg_ll_persistent_reserve_in(int sg_fd, int rq_servact, void * resp,
int mx_resp_len, bool noisy, int vb)
{
static const char * const cdb_s = "Persistent reservation in";
- int res, k, ret, s_cat;
+ int res, ret, s_cat;
uint8_t prin_cdb[PERSISTENT_RESERVE_IN_CMDLEN] =
{PERSISTENT_RESERVE_IN_CMD, 0, 0, 0, 0, 0, 0, 0, 0, 0};
uint8_t sense_b[SENSE_BUFF_LEN];
@@ -1033,10 +1045,11 @@ sg_ll_persistent_reserve_in(int sg_fd, int rq_servact, void * resp,
sg_put_unaligned_be16((uint16_t)mx_resp_len, prin_cdb + 7);
if (vb) {
- pr2ws(" %s cdb: ", cdb_s);
- for (k = 0; k < PERSISTENT_RESERVE_IN_CMDLEN; ++k)
- pr2ws("%02x ", prin_cdb[k]);
- pr2ws("\n");
+ char b[128];
+
+ pr2ws(" %s cdb: %s\n", cdb_s,
+ sg_get_command_str(prin_cdb, PERSISTENT_RESERVE_IN_CMDLEN,
+ false, sizeof(b), b));
}
if (NULL == ((ptvp = create_pt_obj(cdb_s))))
@@ -1085,7 +1098,7 @@ sg_ll_persistent_reserve_out(int sg_fd, int rq_servact, int rq_scope,
int param_len, bool noisy, int vb)
{
static const char * const cdb_s = "Persistent reservation out";
- int res, k, ret, s_cat;
+ int res, ret, s_cat;
uint8_t prout_cdb[PERSISTENT_RESERVE_OUT_CMDLEN] =
{PERSISTENT_RESERVE_OUT_CMD, 0, 0, 0, 0, 0, 0, 0, 0, 0};
uint8_t sense_b[SENSE_BUFF_LEN];
@@ -1097,10 +1110,11 @@ sg_ll_persistent_reserve_out(int sg_fd, int rq_servact, int rq_scope,
sg_put_unaligned_be16((uint16_t)param_len, prout_cdb + 7);
if (vb) {
- pr2ws(" %s cdb: ", cdb_s);
- for (k = 0; k < PERSISTENT_RESERVE_OUT_CMDLEN; ++k)
- pr2ws("%02x ", prout_cdb[k]);
- pr2ws("\n");
+ char b[128];
+
+ pr2ws(" %s cdb: %s\n", cdb_s,
+ sg_get_command_str(prout_cdb, PERSISTENT_RESERVE_OUT_CMDLEN,
+ false, sizeof(b), b));
if (vb > 1) {
pr2ws(" %s parameters:\n", cdb_s);
hex2stderr((const uint8_t *)paramp, param_len, 0);
@@ -1160,7 +1174,7 @@ sg_ll_read_long10(int sg_fd, bool pblock, bool correct, unsigned int lba,
int vb)
{
static const char * const cdb_s = "read long(10)";
- int k, res, s_cat, ret;
+ int res, s_cat, ret;
uint8_t readLong_cdb[READ_LONG10_CMDLEN];
uint8_t sense_b[SENSE_BUFF_LEN];
struct sg_pt_base * ptvp;
@@ -1175,10 +1189,11 @@ sg_ll_read_long10(int sg_fd, bool pblock, bool correct, unsigned int lba,
sg_put_unaligned_be32((uint32_t)lba, readLong_cdb + 2);
sg_put_unaligned_be16((uint16_t)xfer_len, readLong_cdb + 7);
if (vb) {
- pr2ws(" %s cdb: ", cdb_s);
- for (k = 0; k < READ_LONG10_CMDLEN; ++k)
- pr2ws("%02x ", readLong_cdb[k]);
- pr2ws("\n");
+ char b[128];
+
+ pr2ws(" %s cdb: %s\n", cdb_s,
+ sg_get_command_str(readLong_cdb, READ_LONG10_CMDLEN,
+ false, sizeof(b), b));
}
if (NULL == ((ptvp = create_pt_obj(cdb_s))))
@@ -1248,7 +1263,7 @@ sg_ll_read_long16(int sg_fd, bool pblock, bool correct, uint64_t llba,
int vb)
{
static const char * const cdb_s = "read long(16)";
- int k, res, s_cat, ret;
+ int res, s_cat, ret;
uint8_t readLong_cdb[SERVICE_ACTION_IN_16_CMDLEN];
uint8_t sense_b[SENSE_BUFF_LEN];
struct sg_pt_base * ptvp;
@@ -1264,10 +1279,11 @@ sg_ll_read_long16(int sg_fd, bool pblock, bool correct, uint64_t llba,
sg_put_unaligned_be64(llba, readLong_cdb + 2);
sg_put_unaligned_be16((uint16_t)xfer_len, readLong_cdb + 12);
if (vb) {
- pr2ws(" %s cdb: ", cdb_s);
- for (k = 0; k < SERVICE_ACTION_IN_16_CMDLEN; ++k)
- pr2ws("%02x ", readLong_cdb[k]);
- pr2ws("\n");
+ char b[128];
+
+ pr2ws(" %s cdb: %s\n", cdb_s,
+ sg_get_command_str(readLong_cdb, SERVICE_ACTION_IN_16_CMDLEN,
+ false, sizeof(b), b));
}
if (NULL == ((ptvp = create_pt_obj(cdb_s))))
@@ -1337,7 +1353,7 @@ sg_ll_write_long10(int sg_fd, bool cor_dis, bool wr_uncor, bool pblock,
int * offsetp, bool noisy, int vb)
{
static const char * const cdb_s = "write long(10)";
- int k, res, s_cat, ret;
+ int res, s_cat, ret;
uint8_t writeLong_cdb[WRITE_LONG10_CMDLEN];
uint8_t sense_b[SENSE_BUFF_LEN];
struct sg_pt_base * ptvp;
@@ -1354,10 +1370,11 @@ sg_ll_write_long10(int sg_fd, bool cor_dis, bool wr_uncor, bool pblock,
sg_put_unaligned_be32((uint32_t)lba, writeLong_cdb + 2);
sg_put_unaligned_be16((uint16_t)xfer_len, writeLong_cdb + 7);
if (vb) {
- pr2ws(" %s cdb: ", cdb_s);
- for (k = 0; k < (int)sizeof(writeLong_cdb); ++k)
- pr2ws("%02x ", writeLong_cdb[k]);
- pr2ws("\n");
+ char b[128];
+
+ pr2ws(" %s cdb: %s\n", cdb_s,
+ sg_get_command_str(writeLong_cdb, (int)sizeof(writeLong_cdb),
+ false, sizeof(b), b));
}
if (NULL == ((ptvp = create_pt_obj(cdb_s))))
@@ -1415,7 +1432,7 @@ sg_ll_write_long16(int sg_fd, bool cor_dis, bool wr_uncor, bool pblock,
int * offsetp, bool noisy, int vb)
{
static const char * const cdb_s = "write long(16)";
- int k, res, s_cat, ret;
+ int res, s_cat, ret;
uint8_t writeLong_cdb[SERVICE_ACTION_OUT_16_CMDLEN];
uint8_t sense_b[SENSE_BUFF_LEN];
struct sg_pt_base * ptvp;
@@ -1433,10 +1450,11 @@ sg_ll_write_long16(int sg_fd, bool cor_dis, bool wr_uncor, bool pblock,
sg_put_unaligned_be64(llba, writeLong_cdb + 2);
sg_put_unaligned_be16((uint16_t)xfer_len, writeLong_cdb + 12);
if (vb) {
- pr2ws(" %s cdb: ", cdb_s);
- for (k = 0; k < SERVICE_ACTION_OUT_16_CMDLEN; ++k)
- pr2ws("%02x ", writeLong_cdb[k]);
- pr2ws("\n");
+ char b[128];
+
+ pr2ws(" %s cdb: %s\n", cdb_s,
+ sg_get_command_str(writeLong_cdb, SERVICE_ACTION_OUT_16_CMDLEN,
+ false, sizeof(b), b));
}
if (NULL == ((ptvp = create_pt_obj(cdb_s))))
@@ -1510,10 +1528,11 @@ sg_ll_verify10(int sg_fd, int vrprotect, bool dpo, int bytchk,
sg_put_unaligned_be32((uint32_t)lba, v_cdb + 2);
sg_put_unaligned_be16((uint16_t)veri_len, v_cdb + 7);
if (vb > 1) {
- pr2ws(" %s cdb: ", cdb_s);
- for (k = 0; k < VERIFY10_CMDLEN; ++k)
- pr2ws("%02x ", v_cdb[k]);
- pr2ws("\n");
+ char b[128];
+
+ pr2ws(" %s cdb: %s\n", cdb_s,
+ sg_get_command_str(v_cdb, VERIFY10_CMDLEN,
+ false, sizeof(b), b));
if ((vb > 3) && bytchk && data_out && (data_out_len > 0)) {
k = data_out_len > 4104 ? 4104 : data_out_len;
pr2ws(" data_out buffer%s\n",
@@ -1587,10 +1606,11 @@ sg_ll_verify16(int sg_fd, int vrprotect, bool dpo, int bytchk, uint64_t llba,
sg_put_unaligned_be32((uint32_t)veri_len, v_cdb + 10);
v_cdb[14] = group_num & 0x1f;
if (vb > 1) {
- pr2ws(" %s cdb: ", cdb_s);
- for (k = 0; k < VERIFY16_CMDLEN; ++k)
- pr2ws("%02x ", v_cdb[k]);
- pr2ws("\n");
+ char b[128];
+
+ pr2ws(" %s cdb: %s\n", cdb_s,
+ sg_get_command_str(v_cdb, VERIFY16_CMDLEN,
+ false, sizeof(b), b));
if ((vb > 3) && bytchk && data_out && (data_out_len > 0)) {
k = data_out_len > 4104 ? 4104 : data_out_len;
pr2ws(" data_out buffer%s\n",
@@ -1716,13 +1736,13 @@ sg_ll_ata_pt(int sg_fd, const uint8_t * cdbp, int cdb_len,
slen = sizeof(sense_b);
}
if (vb) {
- pr2ws(" %s cdb: ", cnamep);
if (cdb_len < 32) {
- for (k = 0; k < cdb_len; ++k)
- pr2ws("%02x ", apt_cdb[k]);
- pr2ws("\n");
+ char d[128];
+
+ pr2ws(" %s cdb: %s\n", cnamep,
+ sg_get_command_str(apt_cdb, cdb_len, false, sizeof(d), d));
} else {
- pr2ws("\n");
+ pr2ws(" %s cdb:\n", cnamep);
hex2stderr(apt_cdb, cdb_len, -1);
}
}
@@ -1821,7 +1841,7 @@ sg_ll_read_buffer(int sg_fd, int mode, int buffer_id, int buffer_offset,
void * resp, int mx_resp_len, bool noisy, int vb)
{
static const char * const cdb_s = "read buffer(10)";
- int res, k, ret, s_cat;
+ int res, ret, s_cat;
uint8_t rbuf_cdb[READ_BUFFER_CMDLEN] =
{READ_BUFFER_CMD, 0, 0, 0, 0, 0, 0, 0, 0, 0};
uint8_t sense_b[SENSE_BUFF_LEN];
@@ -1832,10 +1852,11 @@ sg_ll_read_buffer(int sg_fd, int mode, int buffer_id, int buffer_offset,
sg_put_unaligned_be24((uint32_t)buffer_offset, rbuf_cdb + 3);
sg_put_unaligned_be24((uint32_t)mx_resp_len, rbuf_cdb + 6);
if (vb) {
- pr2ws(" %s cdb: ", cdb_s);
- for (k = 0; k < READ_BUFFER_CMDLEN; ++k)
- pr2ws("%02x ", rbuf_cdb[k]);
- pr2ws("\n");
+ char b[128];
+
+ pr2ws(" %s cdb: %s\n", cdb_s,
+ sg_get_command_str(rbuf_cdb, READ_BUFFER_CMDLEN,
+ false, sizeof(b), b));
}
if (NULL == ((ptvp = create_pt_obj(cdb_s))))
@@ -1882,7 +1903,7 @@ sg_ll_write_buffer(int sg_fd, int mode, int buffer_id, int buffer_offset,
void * paramp, int param_len, bool noisy, int vb)
{
static const char * const cdb_s = "write buffer";
- int k, res, ret, s_cat;
+ int res, ret, s_cat;
uint8_t wbuf_cdb[WRITE_BUFFER_CMDLEN] =
{WRITE_BUFFER_CMD, 0, 0, 0, 0, 0, 0, 0, 0, 0};
uint8_t sense_b[SENSE_BUFF_LEN];
@@ -1893,10 +1914,11 @@ sg_ll_write_buffer(int sg_fd, int mode, int buffer_id, int buffer_offset,
sg_put_unaligned_be24((uint32_t)buffer_offset, wbuf_cdb + 3);
sg_put_unaligned_be24((uint32_t)param_len, wbuf_cdb + 6);
if (vb) {
- pr2ws(" %s cdb: ", cdb_s);
- for (k = 0; k < WRITE_BUFFER_CMDLEN; ++k)
- pr2ws("%02x ", wbuf_cdb[k]);
- pr2ws("\n");
+ char b[128];
+
+ pr2ws(" %s cdb: %s\n", cdb_s,
+ sg_get_command_str(wbuf_cdb, WRITE_BUFFER_CMDLEN,
+ false, sizeof(b), b));
if ((vb > 1) && paramp && param_len) {
pr2ws(" %s parameter list", cdb_s);
if (2 == vb) {
@@ -1949,7 +1971,7 @@ sg_ll_write_buffer_v2(int sg_fd, int mode, int m_specific, int buffer_id,
uint32_t param_len, int timeout_secs, bool noisy,
int vb)
{
- int k, res, ret, s_cat;
+ int res, ret, s_cat;
uint8_t wbuf_cdb[WRITE_BUFFER_CMDLEN] =
{WRITE_BUFFER_CMD, 0, 0, 0, 0, 0, 0, 0, 0, 0};
uint8_t sense_b[SENSE_BUFF_LEN];
@@ -1969,10 +1991,11 @@ sg_ll_write_buffer_v2(int sg_fd, int mode, int m_specific, int buffer_id,
sg_put_unaligned_be24(buffer_offset, wbuf_cdb + 3);
sg_put_unaligned_be24(param_len, wbuf_cdb + 6);
if (vb) {
- pr2ws(" Write buffer cdb: ");
- for (k = 0; k < WRITE_BUFFER_CMDLEN; ++k)
- pr2ws("%02x ", wbuf_cdb[k]);
- pr2ws("\n");
+ char b[128];
+
+ pr2ws(" Write buffer cdb: %s\n",
+ sg_get_command_str(wbuf_cdb, WRITE_BUFFER_CMDLEN,
+ false, sizeof(b), b));
if ((vb > 1) && paramp && param_len) {
pr2ws(" Write buffer parameter list%s:\n",
((param_len > 256) ? " (first 256 bytes)" : ""));
@@ -2029,7 +2052,7 @@ sg_ll_unmap_v2(int sg_fd, bool anchor, int group_num, int timeout_secs,
void * paramp, int param_len, bool noisy, int vb)
{
static const char * const cdb_s = "unmap";
- int k, res, ret, s_cat, tmout;
+ int res, ret, s_cat, tmout;
uint8_t u_cdb[UNMAP_CMDLEN] =
{UNMAP_CMD, 0, 0, 0, 0, 0, 0, 0, 0, 0};
uint8_t sense_b[SENSE_BUFF_LEN];
@@ -2041,10 +2064,11 @@ sg_ll_unmap_v2(int sg_fd, bool anchor, int group_num, int timeout_secs,
u_cdb[6] = group_num & 0x1f;
sg_put_unaligned_be16((uint16_t)param_len, u_cdb + 7);
if (vb) {
- pr2ws(" %s cdb: ", cdb_s);
- for (k = 0; k < UNMAP_CMDLEN; ++k)
- pr2ws("%02x ", u_cdb[k]);
- pr2ws("\n");
+ char b[128];
+
+ pr2ws(" %s cdb: %s\n", cdb_s,
+ sg_get_command_str(u_cdb, UNMAP_CMDLEN,
+ false, sizeof(b), b));
if ((vb > 1) && paramp && param_len) {
pr2ws(" %s parameter list:\n", cdb_s);
hex2stderr((const uint8_t *)paramp, param_len, -1);
@@ -2083,17 +2107,18 @@ sg_ll_read_block_limits(int sg_fd, void * resp, int mx_resp_len,
bool noisy, int vb)
{
static const char * const cdb_s = "read block limits";
- int k, ret, res, s_cat;
+ int ret, res, s_cat;
uint8_t rl_cdb[READ_BLOCK_LIMITS_CMDLEN] =
{READ_BLOCK_LIMITS_CMD, 0, 0, 0, 0, 0};
uint8_t sense_b[SENSE_BUFF_LEN];
struct sg_pt_base * ptvp;
if (vb) {
- pr2ws(" %s cdb: ", cdb_s);
- for (k = 0; k < READ_BLOCK_LIMITS_CMDLEN; ++k)
- pr2ws("%02x ", rl_cdb[k]);
- pr2ws("\n");
+ char b[128];
+
+ pr2ws(" %s cdb: %s\n", cdb_s,
+ sg_get_command_str(rl_cdb, READ_BLOCK_LIMITS_CMDLEN,
+ false, sizeof(b), b));
}
if (NULL == ((ptvp = create_pt_obj(cdb_s))))
@@ -2140,7 +2165,7 @@ int
sg_ll_receive_copy_results(int sg_fd, int sa, int list_id, void * resp,
int mx_resp_len, bool noisy, int vb)
{
- int k, res, ret, s_cat;
+ int res, ret, s_cat;
uint8_t rcvcopyres_cdb[THIRD_PARTY_COPY_IN_CMDLEN] =
{THIRD_PARTY_COPY_IN_CMD, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
uint8_t sense_b[SENSE_BUFF_LEN];
@@ -2156,10 +2181,11 @@ sg_ll_receive_copy_results(int sg_fd, int sa, int list_id, void * resp,
sg_put_unaligned_be32((uint32_t)mx_resp_len, rcvcopyres_cdb + 10);
if (vb) {
- pr2ws(" %s cdb: ", b);
- for (k = 0; k < THIRD_PARTY_COPY_IN_CMDLEN; ++k)
- pr2ws("%02x ", rcvcopyres_cdb[k]);
- pr2ws("\n");
+ char d[128];
+
+ pr2ws(" %s cdb: %s\n", b,
+ sg_get_command_str(rcvcopyres_cdb, THIRD_PARTY_COPY_IN_CMDLEN,
+ false, sizeof(d), d));
}
if (NULL == ((ptvp = create_pt_obj(b))))
@@ -2199,7 +2225,7 @@ int
sg_ll_extended_copy(int sg_fd, void * paramp, int param_len, bool noisy,
int vb)
{
- int k, res, ret, s_cat;
+ int res, ret, s_cat;
uint8_t xcopy_cdb[THIRD_PARTY_COPY_OUT_CMDLEN] =
{THIRD_PARTY_COPY_OUT_CMD, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
uint8_t sense_b[SENSE_BUFF_LEN];
@@ -2210,10 +2236,11 @@ sg_ll_extended_copy(int sg_fd, void * paramp, int param_len, bool noisy,
sg_put_unaligned_be32((uint32_t)param_len, xcopy_cdb + 10);
if (vb) {
- pr2ws(" %s cdb: ", cdb_s);
- for (k = 0; k < THIRD_PARTY_COPY_OUT_CMDLEN; ++k)
- pr2ws("%02x ", xcopy_cdb[k]);
- pr2ws("\n");
+ char b[128];
+
+ pr2ws(" %s cdb: %s\n", cdb_s,
+ sg_get_command_str(xcopy_cdb, THIRD_PARTY_COPY_OUT_CMDLEN,
+ false, sizeof(b), b));
if ((vb > 1) && paramp && param_len) {
pr2ws(" %s parameter list:\n", cdb_s);
hex2stderr((const uint8_t *)paramp, param_len, -1);
@@ -2255,7 +2282,7 @@ sg_ll_3party_copy_out(int sg_fd, int sa, unsigned int list_id, int group_num,
int timeout_secs, void * paramp, int param_len,
bool noisy, int vb)
{
- int k, res, ret, s_cat, tmout;
+ int res, ret, s_cat, tmout;
uint8_t xcopy_cdb[THIRD_PARTY_COPY_OUT_CMDLEN] =
{THIRD_PARTY_COPY_OUT_CMD, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
uint8_t sense_b[SENSE_BUFF_LEN];
@@ -2286,10 +2313,11 @@ sg_ll_3party_copy_out(int sg_fd, int sa, unsigned int list_id, int group_num,
tmout = (timeout_secs > 0) ? timeout_secs : DEF_PT_TIMEOUT;
if (vb) {
- pr2ws(" %s cdb: ", cname);
- for (k = 0; k < THIRD_PARTY_COPY_OUT_CMDLEN; ++k)
- pr2ws("%02x ", xcopy_cdb[k]);
- pr2ws("\n");
+ char b[128];
+
+ pr2ws(" %s cdb: %s\n", cname,
+ sg_get_command_str(xcopy_cdb, THIRD_PARTY_COPY_OUT_CMDLEN,
+ false, sizeof(b), b));
if ((vb > 1) && paramp && param_len) {
pr2ws(" %s parameter list:\n", cname);
hex2stderr((const uint8_t *)paramp, param_len, -1);
@@ -2338,7 +2366,7 @@ sg_ll_pre_fetch_x(int sg_fd, bool do_seek10, bool cdb16, bool immed,
static const char * const cdb10_name_s = "Pre-fetch(10)";
static const char * const cdb16_name_s = "Pre-fetch(16)";
static const char * const cdb_seek_name_s = "Seek(10)";
- int k, res, s_cat, ret, cdb_len, tmout;
+ int res, s_cat, ret, cdb_len, tmout;
const char *cdb_s;
uint8_t preFetchCdb[PRE_FETCH16_CMDLEN]; /* all use longest cdb */
uint8_t sense_b[SENSE_BUFF_LEN];
@@ -2386,10 +2414,10 @@ sg_ll_pre_fetch_x(int sg_fd, bool do_seek10, bool cdb16, bool immed,
}
tmout = (timeout_secs > 0) ? timeout_secs : DEF_PT_TIMEOUT;
if (vb) {
- pr2ws(" %s cdb: ", cdb_s);
- for (k = 0; k < cdb_len; ++k)
- pr2ws("%02x ", preFetchCdb[k]);
- pr2ws("\n");
+ char b[128];
+
+ pr2ws(" %s cdb: %s\n", cdb_s,
+ sg_get_command_str(preFetchCdb, cdb_len, false, sizeof(b), b));
}
if (NULL == ((ptvp = create_pt_obj(cdb_s))))
return -1;
diff --git a/lib/sg_lib.c b/lib/sg_lib.c
index 2516f450..d688f6eb 100644
--- a/lib/sg_lib.c
+++ b/lib/sg_lib.c
@@ -157,25 +157,78 @@ sg_set_warnings_strm(FILE * warnings_strm)
sg_warnings_strm = warnings_strm;
}
+/* Take care to minimize printf() parsing delays when printing commands */
+static char bin2hexascii[] = {'0', '1', '2', '3', '4', '5', '6', '7',
+ '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
+
+
+/* Given a SCSI command pointed to by cmdp of sz bytes this function forms
+ * a SCSI command in ASCII surrounded by square brackets in 'b'. 'b' is at
+ * least blen bytes long. If cmd_name is true then the command is prefixed
+ * by its SCSI command name (e.g. "VERIFY(10) [2f ...]". The command is
+ * shown as spaced separated pairs of hexadecimal digits (i.e. 0-9, a-f).
+ * Each pair repesents byte. The leftmost pair of digits is cmdp[0] . If
+ * sz <= 0 then this function tries to guess the length of the command. */
+char *
+sg_get_command_str(const uint8_t * cmdp, int sz, bool cmd_name, int blen,
+ char * b)
+{
+ int k, j, jj;
+
+ if ((cmdp == NULL) || (b == NULL) || (blen < 1))
+ return b;
+ if (cmd_name && (blen > 16)) {
+ sg_get_command_name(cmdp, 0, blen, b);
+ j = (int)strlen(b);
+ if (j < (blen - 1))
+ b[j++] = ' ';
+ } else
+ j = 0;
+ if (j >= blen)
+ goto fini;
+ b[j++] = '[';
+ if (j >= blen)
+ goto fini;
+ if (sz <= 0) {
+ if (SG_VARIABLE_LENGTH_CMD == cmdp[0])
+ sz = cmdp[7] + 8;
+ else
+ sz = sg_get_command_size(cmdp[0]);
+ }
+ jj = j;
+ for (k = 0; (k < sz) && (j < (blen - 3)); ++k, j += 3, ++cmdp) {
+ b[j] = bin2hexascii[(*cmdp >> 4) & 0xf];
+ b[j + 1] = bin2hexascii[*cmdp & 0xf];
+ b[j + 2] = ' ';
+ }
+ if (j > jj)
+ --j; /* don't want trailing space before ']' */
+ if (j >= blen)
+ goto fini;
+ b[j++] = ']';
+fini:
+ if (j >= blen)
+ b[blen - 1] = '\0'; /* truncated string */
+ else
+ b[j] = '\0';
+ return b;
+}
+
#define CMD_NAME_LEN 128
void
-sg_print_command(const uint8_t * command)
+sg_print_command_len(const uint8_t * cmdp, int sz)
{
- int k, sz;
char buff[CMD_NAME_LEN];
- sg_get_command_name(command, 0, CMD_NAME_LEN, buff);
- buff[CMD_NAME_LEN - 1] = '\0';
+ sg_get_command_str(cmdp, sz, true, sizeof(buff), buff);
+ pr2ws("%s\n", buff);
+}
- pr2ws("%s [", buff);
- if (SG_VARIABLE_LENGTH_CMD == command[0])
- sz = command[7] + 8;
- else
- sz = sg_get_command_size(command[0]);
- for (k = 0; k < sz; ++k)
- pr2ws("%02x ", command[k]);
- pr2ws("]\n");
+void
+sg_print_command(const uint8_t * cmdp)
+{
+ sg_print_command_len(cmdp, 0);
}
/* SCSI Status values */
diff --git a/lib/sg_lib_data.c b/lib/sg_lib_data.c
index 14c009f7..7bec0678 100644
--- a/lib/sg_lib_data.c
+++ b/lib/sg_lib_data.c
@@ -19,7 +19,7 @@
#include "sg_lib_data.h"
-const char * sg_lib_version_str = "2.69 20191204";
+const char * sg_lib_version_str = "2.70 20191226";
/* spc5r22, sbc4r17, zbc2r04 */
@@ -1506,7 +1506,7 @@ const char * sg_lib_pdt_strs[32] = { /* should have 2**5 elements */
const char * sg_lib_transport_proto_strs[] =
{
- "Fibre Channel Protocol for SCSI (FCP-4)",
+ "Fibre Channel Protocol for SCSI (FCP-5)", /* now at fcp5r01 */
"SCSI Parallel Interface (SPI-5)", /* obsolete in spc5r01 */
"Serial Storage Architecture SCSI-3 Protocol (SSA-S3P)",
"Serial Bus Protocol for IEEE 1394 (SBP-3)",
diff --git a/src/sg_bg_ctl.c b/src/sg_bg_ctl.c
index 0f2128af..d7df6587 100644
--- a/src/sg_bg_ctl.c
+++ b/src/sg_bg_ctl.c
@@ -35,7 +35,7 @@
* device. Based on sbc4r10.pdf .
*/
-static const char * version_str = "1.10 20190113";
+static const char * version_str = "1.11 20191220";
#define BACKGROUND_CONTROL_SA 0x15
@@ -89,7 +89,7 @@ static int
sg_ll_background_control(int sg_fd, unsigned int bo_ctl, unsigned int bo_time,
bool noisy, int verbose)
{
- int k, ret, res, sense_cat;
+ int ret, res, sense_cat;
uint8_t bcCDB[16] = {SG_SERVICE_ACTION_IN_16,
BACKGROUND_CONTROL_SA, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0};
@@ -101,10 +101,11 @@ sg_ll_background_control(int sg_fd, unsigned int bo_ctl, unsigned int bo_time,
if (bo_time)
bcCDB[3] = bo_time;
if (verbose) {
- pr2serr(" %s cdb: ", cmd_name);
- for (k = 0; k < (int)sizeof(bcCDB); ++k)
- pr2serr("%02x ", bcCDB[k]);
- pr2serr("\n");
+ char b[128];
+
+ pr2serr(" %s cdb: %s\n", cmd_name,
+ sg_get_command_str(bcCDB, (int)sizeof(bcCDB), false,
+ sizeof(b), b));
}
ptvp = construct_scsi_pt_obj();
diff --git a/src/sg_compare_and_write.c b/src/sg_compare_and_write.c
index 784907e4..d1905899 100644
--- a/src/sg_compare_and_write.c
+++ b/src/sg_compare_and_write.c
@@ -56,7 +56,7 @@
#include "sg_unaligned.h"
#include "sg_pr2serr.h"
-static const char * version_str = "1.26 20190113";
+static const char * version_str = "1.27 20191220";
#define DEF_BLOCK_SIZE 512
#define DEF_NUM_BLOCKS (1)
@@ -349,7 +349,7 @@ sg_ll_compare_and_write(int sg_fd, uint8_t * buff, int blocks,
bool noisy, int verbose)
{
bool valid;
- int k, sense_cat, slen, res, ret;
+ int sense_cat, slen, res, ret;
uint64_t ull = 0;
struct sg_pt_base * ptvp;
uint8_t cawCmd[COMPARE_AND_WRITE_CDB_SIZE];
@@ -370,10 +370,11 @@ sg_ll_compare_and_write(int sg_fd, uint8_t * buff, int blocks,
set_scsi_pt_sense(ptvp, sense_b, sizeof(sense_b));
set_scsi_pt_data_out(ptvp, buff, xfer_len);
if (verbose > 1) {
- pr2serr(" Compare and write cdb: ");
- for (k = 0; k < COMPARE_AND_WRITE_CDB_SIZE; ++k)
- pr2serr("%02x ", cawCmd[k]);
- pr2serr("\n");
+ char b[128];
+
+ pr2serr(" Compare and write cdb: %s\n",
+ sg_get_command_str(cawCmd, COMPARE_AND_WRITE_CDB_SIZE, false,
+ sizeof(b), b));
}
if ((verbose > 2) && (xfer_len > 0)) {
pr2serr(" Data-out buffer contents:\n");
diff --git a/src/sg_dd.c b/src/sg_dd.c
index 06d96610..97513b76 100644
--- a/src/sg_dd.c
+++ b/src/sg_dd.c
@@ -24,7 +24,7 @@
* command. The actual size of the SCSI READ or WRITE command block can be
* selected with the "cdbsz" argument.
*
- * This version is designed for the linux kernel 2.4, 2.6, 3 and 4 series.
+ * This version is designed for the linux kernel 2, 3, 4 and 5 series.
*/
#define _XOPEN_SOURCE 600
@@ -66,7 +66,7 @@
#include "sg_unaligned.h"
#include "sg_pr2serr.h"
-static const char * version_str = "6.07 20190618";
+static const char * version_str = "6.08 20191220";
#define ME "sg_dd: "
@@ -142,6 +142,7 @@ static int dry_run = 0;
static bool do_time = false;
static bool start_tm_valid = false;
+static bool do_verify = false; /* when false: do copy */
static int verbose = 0;
static int blk_sz = 0;
static int max_uas = MAX_UNIT_ATTENTIONS;
@@ -203,8 +204,8 @@ print_stats(const char * str)
pr2serr(" remaining block count=%" PRId64 "\n", dd_count);
pr2serr("%s%" PRId64 "+%d records in\n", str, in_full - in_partial,
in_partial);
- pr2serr("%s%" PRId64 "+%d records out\n", str, out_full - out_partial,
- out_partial);
+ pr2serr("%s%" PRId64 "+%d records %s\n", str, out_full - out_partial,
+ out_partial, (do_verify ? "verified" : "out"));
if (oflag.sparse)
pr2serr("%s%" PRId64 " bypassed records out\n", str, out_sparse_num);
if (recovered_errs > 0)
@@ -411,12 +412,17 @@ usage()
" verbose 0->quiet(def), 1->some noise, 2->more noise, "
"etc\n"
" --dry-run do preparation but bypass copy (or read)\n"
- " --help print out this usage message then exit\n"
- " --verbose same as 'verbose=1', can be used multiple "
+ " --help|-h print out this usage message then exit\n"
+ " --verbose|-v same as 'verbose=1', can be used multiple "
"times\n"
- " --version print version information then exit\n\n"
- "copy from IFILE to OFILE, similar to dd command; "
- "specialized for SCSI devices\n");
+ " --verify|-x do verify/compare rather than copy "
+ "(OFILE must\n"
+ " be a sg device)\n"
+ " --version|-V print version information then exit\n\n"
+ "Copy from IFILE to OFILE, similar to dd command; "
+ "specialized for SCSI devices.\nIf the --verify option is given "
+ " then IFILE is read and that data is used to\ncompare with "
+ "OFILE using the VERIFY(n) SCSI command (with BYTCHK=1).\n");
}
@@ -508,10 +514,12 @@ read_blkdev_capacity(int sg_fd, int64_t * num_sect, int * sect_sz)
static int
sg_build_scsi_cdb(uint8_t * cdbp, int cdb_sz, unsigned int blocks,
- int64_t start_block, bool write_true, bool fua, bool dpo)
+ int64_t start_block, bool is_verify, bool write_true,
+ bool fua, bool dpo)
{
int sz_ind;
int rd_opcode[] = {0x8, 0x28, 0xa8, 0x88};
+ int ve_opcode[] = {0xff /* no VERIFY(6) */, 0x2f, 0xaf, 0x8f};
int wr_opcode[] = {0xa, 0x2a, 0xaa, 0x8a};
memset(cdbp, 0, cdb_sz);
@@ -522,6 +530,10 @@ sg_build_scsi_cdb(uint8_t * cdbp, int cdb_sz, unsigned int blocks,
switch (cdb_sz) {
case 6:
sz_ind = 0;
+ if (is_verify && write_true) {
+ pr2serr(ME "there is no VERIFY(6), choose a larger cdbsz\n");
+ return 1;
+ }
cdbp[0] = (uint8_t)(write_true ? wr_opcode[sz_ind] :
rd_opcode[sz_ind]);
sg_put_unaligned_be24(0x1fffff & start_block, cdbp + 1);
@@ -544,8 +556,11 @@ sg_build_scsi_cdb(uint8_t * cdbp, int cdb_sz, unsigned int blocks,
break;
case 10:
sz_ind = 1;
- cdbp[0] = (uint8_t)(write_true ? wr_opcode[sz_ind] :
- rd_opcode[sz_ind]);
+ if (is_verify && write_true)
+ cdbp[0] = ve_opcode[sz_ind];
+ else
+ cdbp[0] = (uint8_t)(write_true ? wr_opcode[sz_ind] :
+ rd_opcode[sz_ind]);
sg_put_unaligned_be32(start_block, cdbp + 2);
sg_put_unaligned_be16(blocks, cdbp + 7);
if (blocks & (~0xffff)) {
@@ -556,15 +571,21 @@ sg_build_scsi_cdb(uint8_t * cdbp, int cdb_sz, unsigned int blocks,
break;
case 12:
sz_ind = 2;
- cdbp[0] = (uint8_t)(write_true ? wr_opcode[sz_ind] :
- rd_opcode[sz_ind]);
+ if (is_verify && write_true)
+ cdbp[0] = ve_opcode[sz_ind];
+ else
+ cdbp[0] = (uint8_t)(write_true ? wr_opcode[sz_ind] :
+ rd_opcode[sz_ind]);
sg_put_unaligned_be32(start_block, cdbp + 2);
sg_put_unaligned_be32(blocks, cdbp + 6);
break;
case 16:
sz_ind = 3;
- cdbp[0] = (uint8_t)(write_true ? wr_opcode[sz_ind] :
- rd_opcode[sz_ind]);
+ if (is_verify && write_true)
+ cdbp[0] = ve_opcode[sz_ind];
+ else
+ cdbp[0] = (uint8_t)(write_true ? wr_opcode[sz_ind] :
+ rd_opcode[sz_ind]);
sg_put_unaligned_be64(start_block, cdbp + 2);
sg_put_unaligned_be32(blocks, cdbp + 10);
break;
@@ -590,14 +611,14 @@ sg_read_low(int sg_fd, uint8_t * buff, int blocks, int64_t from_block,
uint64_t * io_addrp)
{
bool info_valid;
- int res, k, slen;
+ int res, slen;
const uint8_t * sbp;
uint8_t rdCmd[MAX_SCSI_CDBSZ];
uint8_t senseBuff[SENSE_BUFF_LEN];
struct sg_io_hdr io_hdr;
- if (sg_build_scsi_cdb(rdCmd, ifp->cdbsz, blocks, from_block, false,
- ifp->fua, ifp->dpo)) {
+ if (sg_build_scsi_cdb(rdCmd, ifp->cdbsz, blocks, from_block, do_verify,
+ false, ifp->fua, ifp->dpo)) {
pr2serr(ME "bad rd cdb build, from_block=%" PRId64 ", blocks=%d\n",
from_block, blocks);
return SG_LIB_SYNTAX_ERROR;
@@ -617,12 +638,9 @@ sg_read_low(int sg_fd, uint8_t * buff, int blocks, int64_t from_block,
if (diop && *diop)
io_hdr.flags |= SG_FLAG_DIRECT_IO;
- if (verbose > 2) {
- pr2serr(" read cdb: ");
- for (k = 0; k < ifp->cdbsz; ++k)
- pr2serr("%02x ", rdCmd[k]);
- pr2serr("\n");
- }
+ if (verbose > 2)
+ sg_print_command_len(rdCmd, ifp->cdbsz);
+
while (((res = ioctl(sg_fd, SG_IO, &io_hdr)) < 0) &&
((EINTR == errno) || (EAGAIN == errno)))
;
@@ -987,22 +1005,23 @@ err_out:
/* 0 -> successful, SG_LIB_SYNTAX_ERROR -> unable to build cdb,
- SG_LIB_CAT_NOT_READY, SG_LIB_CAT_UNIT_ATTENTION, SG_LIB_CAT_MEDIUM_HARD,
- SG_LIB_CAT_ABORTED_COMMAND, -2 -> recoverable (ENOMEM),
- -1 -> unrecoverable error + others */
+ * SG_LIB_CAT_NOT_READY, SG_LIB_CAT_UNIT_ATTENTION, SG_LIB_CAT_MEDIUM_HARD,
+ * SG_LIB_CAT_ABORTED_COMMAND, -2 -> recoverable (ENOMEM),
+ * -1 -> unrecoverable error + others. Note: if do_verify is true then does
+ * a VERIFY rather tahn a WRITE command. */
static int
sg_write(int sg_fd, uint8_t * buff, int blocks, int64_t to_block,
int bs, const struct flags_t * ofp, bool * diop)
{
bool info_valid;
- int res, k;
+ int res;
uint64_t io_addr = 0;
uint8_t wrCmd[MAX_SCSI_CDBSZ];
uint8_t senseBuff[SENSE_BUFF_LEN];
struct sg_io_hdr io_hdr;
- if (sg_build_scsi_cdb(wrCmd, ofp->cdbsz, blocks, to_block, true, ofp->fua,
- ofp->dpo)) {
+ if (sg_build_scsi_cdb(wrCmd, ofp->cdbsz, blocks, to_block, do_verify,
+ true, ofp->fua, ofp->dpo)) {
pr2serr(ME "bad wr cdb build, to_block=%" PRId64 ", blocks=%d\n",
to_block, blocks);
return SG_LIB_SYNTAX_ERROR;
@@ -1022,12 +1041,9 @@ sg_write(int sg_fd, uint8_t * buff, int blocks, int64_t to_block,
if (diop && *diop)
io_hdr.flags |= SG_FLAG_DIRECT_IO;
- if (verbose > 2) {
- pr2serr(" write cdb: ");
- for (k = 0; k < ofp->cdbsz; ++k)
- pr2serr("%02x ", wrCmd[k]);
- pr2serr("\n");
- }
+ if (verbose > 2)
+ sg_print_command_len(wrCmd, ofp->cdbsz);
+
while (((res = ioctl(sg_fd, SG_IO, &io_hdr)) < 0) &&
((EINTR == errno) || (EAGAIN == errno)))
;
@@ -1699,6 +1715,10 @@ main(int argc, char * argv[])
if (n > 0)
version_given = true;
res += n;
+ n = num_chs_in_str(key + 1, keylen - 1, 'x');
+ if (n > 0)
+ do_verify = true;
+ res += n;
if (res < (keylen - 1)) {
pr2serr("Unrecognised short option in '%s', try '--help'\n",
key);
@@ -1714,7 +1734,9 @@ main(int argc, char * argv[])
} else if (0 == strncmp(key, "--verb", 6)) {
verbose_given = true;
++verbose;
- } else if (0 == strncmp(key, "--vers", 6))
+ } else if (0 == strncmp(key, "--veri", 6))
+ do_verify = true;
+ else if (0 == strncmp(key, "--vers", 6))
version_given = true;
else {
pr2serr("Unrecognized option '%s'\n", key);
@@ -1801,7 +1823,19 @@ main(int argc, char * argv[])
if (outfd < -1)
return -outfd;
}
-
+ if (do_verify) {
+ if (! (FT_SG & out_type)) {
+ pr2serr("--verify only supported when OFILE is a sg device or "
+ "oflag=sgio\n");
+ ret = SG_LIB_CONTRADICT;
+ goto bypass_copy;
+ }
+ if (oflag.sparse) {
+ pr2serr("--verify cannot be used with oflag=sparse\n");
+ ret = SG_LIB_CONTRADICT;
+ goto bypass_copy;
+ }
+ }
if (out2f[0]) {
out2_type = dd_filetype(out2f);
if ((out2fd = open(out2f, O_WRONLY | O_CREAT, 0666)) < 0) {
@@ -2124,8 +2158,8 @@ main(int argc, char * argv[])
blocks_per = (buf_sz + blk_sz - 1) / blk_sz;
if (blocks_per < blocks) {
blocks = blocks_per;
- pr2serr("Reducing write to %d blocks per loop\n",
- blocks);
+ pr2serr("Reducing %s to %d blocks per loop\n",
+ (do_verify ? "verify" : "write"), blocks);
} else
break;
} else if ((SG_LIB_CAT_UNIT_ATTENTION == ret) && first) {
@@ -2145,8 +2179,8 @@ main(int argc, char * argv[])
} else if (ret < 0)
break;
else if (retries_tmp > 0) {
- pr2serr(">>> retrying a sgio write, lba=0x%" PRIx64 "\n",
- (uint64_t)seek);
+ pr2serr(">>> retrying a sgio %s, lba=0x%" PRIx64 "\n",
+ (do_verify ? "verify" : "write"), (uint64_t)seek);
--retries_tmp;
++num_retries;
if (unrecovered_errs > 0)
diff --git a/src/sg_format.c b/src/sg_format.c
index 9b29caf9..f30a4e6d 100644
--- a/src/sg_format.c
+++ b/src/sg_format.c
@@ -40,7 +40,7 @@
#include "sg_pr2serr.h"
#include "sg_pt.h"
-static const char * version_str = "1.59 20190913";
+static const char * version_str = "1.60 20191220";
#define RW_ERROR_RECOVERY_PAGE 1 /* can give alternate with --mode=MP */
@@ -251,7 +251,7 @@ sg_ll_format_medium(int sg_fd, bool verify, bool immed, int format,
void * paramp, int transfer_len, int timeout, bool noisy,
int verbose)
{
- int k, ret, res, sense_cat;
+ int ret, res, sense_cat;
uint8_t fm_cdb[SG_FORMAT_MEDIUM_CMDLEN] =
{SG_FORMAT_MEDIUM_CMD, 0, 0, 0, 0, 0};
uint8_t sense_b[SENSE_BUFF_LEN];
@@ -266,10 +266,11 @@ sg_ll_format_medium(int sg_fd, bool verify, bool immed, int format,
if (transfer_len > 0)
sg_put_unaligned_be16(transfer_len, fm_cdb + 3);
if (verbose) {
- pr2serr(" Format medium cdb: ");
- for (k = 0; k < SG_FORMAT_MEDIUM_CMDLEN; ++k)
- pr2serr("%02x ", fm_cdb[k]);
- pr2serr("\n");
+ char b[128];
+
+ pr2serr(" Format medium cdb: %s\n",
+ sg_get_command_str(fm_cdb, SG_FORMAT_MEDIUM_CMDLEN,
+ false, sizeof(b), b));
}
ptvp = construct_scsi_pt_obj();
diff --git a/src/sg_get_elem_status.c b/src/sg_get_elem_status.c
index 3e1473f9..96841f68 100644
--- a/src/sg_get_elem_status.c
+++ b/src/sg_get_elem_status.c
@@ -37,7 +37,7 @@
* given SCSI device.
*/
-static const char * version_str = "1.00 20190827"; /* sbc4r15,17 */
+static const char * version_str = "1.01 20191220"; /* sbc4r15,17 */
#ifndef UINT32_MAX
@@ -155,10 +155,11 @@ sg_ll_get_phy_elem_status(int sg_fd, uint32_t starting_elem, uint8_t filter,
if (report_type)
gpesCmd[14] |= (0xf & report_type);
if (verbose) {
- pr2serr(" %s cdb: ", cmd_name);
- for (k = 0; k < (int)sizeof(gpesCmd); ++k)
- pr2serr("%02x ", gpesCmd[k]);
- pr2serr("\n");
+ char b[128];
+
+ pr2serr(" %s cdb: %s\n", cmd_name,
+ sg_get_command_str(gpesCmd, (int)sizeof(gpesCmd), false,
+ sizeof(b), b));
}
ptvp = construct_scsi_pt_obj_with_fd(sg_fd, verbose);
@@ -548,8 +549,8 @@ start_response:
printf("depopulation operations in progress");
else if (0xff == j)
printf("depopulation completed, no errors");
- if (a_ped.restore_allowed)
- printf(" [restore allowed]");
+ if (a_ped.restore_allowed)
+ printf(" [restore allowed]");
printf("\n");
}
}
diff --git a/src/sg_opcodes.c b/src/sg_opcodes.c
index f80b79da..7c892c0f 100644
--- a/src/sg_opcodes.c
+++ b/src/sg_opcodes.c
@@ -33,7 +33,7 @@
#include "sg_pt.h"
-static const char * version_str = "0.66 20190113"; /* spc5r20 */
+static const char * version_str = "0.67 20191220"; /* spc5r20 */
#define SENSE_BUFF_LEN 64 /* Arbitrary, could be larger */
@@ -195,7 +195,7 @@ do_rsoc(struct sg_pt_base * ptvp, bool rctd, int rep_opts, int rq_opcode,
int rq_servact, void * resp, int mx_resp_len, int * act_resp_lenp,
bool noisy, int verbose)
{
- int k, ret, res, sense_cat;
+ int ret, res, sense_cat;
uint8_t rsoc_cdb[RSOC_CMD_LEN] = {SG_MAINTENANCE_IN, RSOC_SA, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0};
uint8_t sense_b[SENSE_BUFF_LEN];
@@ -213,10 +213,11 @@ do_rsoc(struct sg_pt_base * ptvp, bool rctd, int rep_opts, int rq_opcode,
sg_put_unaligned_be32((uint32_t)mx_resp_len, rsoc_cdb + 6);
if (verbose) {
- pr2serr(" %s cdb: ", rsoc_s);
- for (k = 0; k < RSOC_CMD_LEN; ++k)
- pr2serr("%02x ", rsoc_cdb[k]);
- pr2serr("\n");
+ char b[128];
+
+ pr2serr(" %s cdb: %s\n", rsoc_s,
+ sg_get_command_str(rsoc_cdb, RSOC_CMD_LEN, false,
+ sizeof(b), b));
}
clear_scsi_pt_obj(ptvp);
set_scsi_pt_cdb(ptvp, rsoc_cdb, sizeof(rsoc_cdb));
@@ -255,7 +256,7 @@ static int
do_rstmf(struct sg_pt_base * ptvp, bool repd, void * resp, int mx_resp_len,
int * act_resp_lenp, bool noisy, int verbose)
{
- int k, ret, res, sense_cat;
+ int ret, res, sense_cat;
uint8_t rstmf_cdb[RSTMF_CMD_LEN] = {SG_MAINTENANCE_IN, RSTMF_SA,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
uint8_t sense_b[SENSE_BUFF_LEN];
@@ -267,10 +268,11 @@ do_rstmf(struct sg_pt_base * ptvp, bool repd, void * resp, int mx_resp_len,
sg_put_unaligned_be32((uint32_t)mx_resp_len, rstmf_cdb + 6);
if (verbose) {
- pr2serr(" %s: ", rstmf_s);
- for (k = 0; k < RSTMF_CMD_LEN; ++k)
- pr2serr("%02x ", rstmf_cdb[k]);
- pr2serr("\n");
+ char b[128];
+
+ pr2serr(" %s cdb: %s\n", rstmf_s,
+ sg_get_command_str(rstmf_cdb, RSTMF_CMD_LEN, false,
+ sizeof(b), b));
}
clear_scsi_pt_obj(ptvp);
set_scsi_pt_cdb(ptvp, rstmf_cdb, sizeof(rstmf_cdb));
diff --git a/src/sg_raw.c b/src/sg_raw.c
index f9deaa9f..07e40bfb 100644
--- a/src/sg_raw.c
+++ b/src/sg_raw.c
@@ -39,7 +39,7 @@
#include "sg_pr2serr.h"
#include "sg_unaligned.h"
-#define SG_RAW_VERSION "0.4.30 (2019-05-16)"
+#define SG_RAW_VERSION "0.4.32 (2019-12-26)"
#define DEFAULT_TIMEOUT 20
#define MIN_SCSI_CDBSZ 6
@@ -577,16 +577,13 @@ main(int argc, char *argv[])
}
}
if (op->verbose) {
+ char d[128];
+
pr2serr(" %s to send: ", is_scsi_cdb ? "cdb" : "cmd");
if (is_scsi_cdb) {
- for (k = 0; k < op->cdb_length; ++k)
- pr2serr("%02x ", op->cdb[k]);
- pr2serr("\n");
- if (op->verbose > 1) {
- sg_get_command_name(op->cdb, 0, b_len - 1, b);
- b[b_len - 1] = '\0';
- pr2serr(" Command name: %s\n", b);
- }
+ pr2serr("%s\n", sg_get_command_str(op->cdb, op->cdb_length,
+ op->verbose > 1,
+ sizeof(d), d));
} else { /* If not SCSI cdb then treat as NVMe command */
pr2serr("\n");
hex2stderr(op->cdb, op->cdb_length, -1);
diff --git a/src/sg_rbuf.c b/src/sg_rbuf.c
index 2f5229f0..760129d8 100644
--- a/src/sg_rbuf.c
+++ b/src/sg_rbuf.c
@@ -57,7 +57,7 @@
#endif
-static const char * version_str = "5.06 20190913";
+static const char * version_str = "5.07 20191226";
static struct option long_options[] = {
{"buffer", required_argument, 0, 'b'},
@@ -359,7 +359,7 @@ main(int argc, char * argv[])
bool clear = true;
#endif
bool dio_incomplete = false;
- int sg_fd, res, j, err;
+ int sg_fd, res, err;
int buf_capacity = 0;
int buf_size = 0;
size_t psz;
@@ -451,11 +451,11 @@ main(int argc, char * argv[])
io_hdr.sbp = sense_buffer;
io_hdr.timeout = 60000; /* 60000 millisecs == 60 seconds */
if (op->verbose) {
- pr2serr(" Read buffer (%sdescriptor) cdb: ",
- (op->do_echo ? "echo " : ""));
- for (k = 0; k < RB_CMD_LEN; ++k)
- pr2serr("%02x ", rb_cdb[k]);
- pr2serr("\n");
+ char b[128];
+
+ pr2serr(" Read buffer (%sdescriptor) cdb: %s\n",
+ (op->do_echo ? "echo " : ""),
+ sg_get_command_str(rb_cdb, RB_CMD_LEN, false, sizeof(b), b));
}
/* do normal IO to find RB size (not dio or mmap-ed at this stage) */
@@ -587,13 +587,13 @@ main(int argc, char * argv[])
else if (op->do_quick)
io_hdr.flags |= SG_FLAG_NO_DXFER;
if (op->verbose > 1) {
- pr2serr(" Read buffer (%sdata) cdb: ",
- (op->do_echo ? "echo " : ""));
- for (j = 0; j < RB_CMD_LEN; ++j)
- pr2serr("%02x ", rb_cdb[j]);
- pr2serr("\n");
- }
+ char b[128];
+ pr2serr(" Read buffer (%sdata) cdb: %s\n",
+ (op->do_echo ? "echo " : ""),
+ sg_get_command_str(rb_cdb, RB_CMD_LEN, false,
+ sizeof(b), b));
+ }
if (ioctl(sg_fd, SG_IO, &io_hdr) < 0) {
if (ENOMEM == errno) {
pr2serr("SG_IO data: out of memory, try a smaller buffer "
diff --git a/src/sg_read.c b/src/sg_read.c
index 0c6b9825..4122e620 100644
--- a/src/sg_read.c
+++ b/src/sg_read.c
@@ -58,7 +58,7 @@
#include "sg_pr2serr.h"
-static const char * version_str = "1.35 20190501";
+static const char * version_str = "1.36 20191220";
#define DEF_BLOCK_SIZE 512
#define DEF_BLOCKS_PER_TRANSFER 128
@@ -295,7 +295,6 @@ sg_bread(int sg_fd, uint8_t * buff, int blocks, int64_t from_block, int bs,
int cdbsz, bool fua, bool dpo, bool * diop, bool do_mmap,
bool no_dxfer)
{
- int k;
uint8_t rdCmd[MAX_SCSI_CDBSZ];
uint8_t senseBuff[SENSE_BUFF_LEN];
struct sg_io_hdr io_hdr;
@@ -329,10 +328,10 @@ sg_bread(int sg_fd, uint8_t * buff, int blocks, int64_t from_block, int bs,
io_hdr.timeout = DEF_TIMEOUT;
io_hdr.pack_id = pack_id_count++;
if (verbose > 1) {
- pr2serr( " read cdb: ");
- for (k = 0; k < cdbsz; ++k)
- pr2serr( "%02x ", rdCmd[k]);
- pr2serr( "\n");
+ char b[128];
+
+ pr2serr(" READ cdb: %s\n",
+ sg_get_command_str(rdCmd, cdbsz, false, sizeof(b), b));
}
if (ioctl(sg_fd, SG_IO, &io_hdr) < 0) {
diff --git a/src/sg_read_attr.c b/src/sg_read_attr.c
index 0b664596..bf27da1e 100644
--- a/src/sg_read_attr.c
+++ b/src/sg_read_attr.c
@@ -39,7 +39,7 @@
* and decodes the response. Based on spc5r08.pdf
*/
-static const char * version_str = "1.12 20190113";
+static const char * version_str = "1.13 20191220";
#define MAX_RATTR_BUFF_LEN (1024 * 1024)
#define DEF_RATTR_BUFF_LEN (1024 * 8)
@@ -245,7 +245,7 @@ static int
sg_ll_read_attr(int sg_fd, void * resp, int * residp, bool noisy,
const struct opts_t * op)
{
- int k, ret, res, sense_cat;
+ int ret, res, sense_cat;
uint8_t ra_cdb[SG_READ_ATTRIBUTE_CMDLEN] =
{SG_READ_ATTRIBUTE_CMD, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0};
@@ -265,10 +265,11 @@ sg_ll_read_attr(int sg_fd, void * resp, int * residp, bool noisy,
if (op->cache)
ra_cdb[14] |= 0x1;
if (op->verbose) {
- pr2serr(" Read attribute cdb: ");
- for (k = 0; k < SG_READ_ATTRIBUTE_CMDLEN; ++k)
- pr2serr("%02x ", ra_cdb[k]);
- pr2serr("\n");
+ char b[128];
+
+ pr2serr(" Read attribute cdb: %s\n",
+ sg_get_command_str(ra_cdb, SG_READ_ATTRIBUTE_CMDLEN, false,
+ sizeof(b), b));
}
ptvp = construct_scsi_pt_obj();
diff --git a/src/sg_read_buffer.c b/src/sg_read_buffer.c
index 2dabefb2..4eb5da4a 100644
--- a/src/sg_read_buffer.c
+++ b/src/sg_read_buffer.c
@@ -39,7 +39,7 @@
* device.
*/
-static const char * version_str = "1.29 20190516"; /* spc5r22 */
+static const char * version_str = "1.30 20191220"; /* spc5r22 */
#ifndef SG_READ_BUFFER_10_CMD
@@ -163,7 +163,7 @@ sg_ll_read_buffer_10(int sg_fd, int rb_mode, int rb_mode_sp, int rb_id,
uint32_t rb_offset, void * resp, int mx_resp_len,
int * residp, bool noisy, int verbose)
{
- int k, ret, res, sense_cat;
+ int ret, res, sense_cat;
uint8_t rb10_cb[SG_READ_BUFFER_10_CMDLEN] =
{SG_READ_BUFFER_10_CMD, 0, 0, 0, 0, 0, 0, 0, 0, 0};
uint8_t sense_b[SENSE_BUFF_LEN];
@@ -176,10 +176,11 @@ sg_ll_read_buffer_10(int sg_fd, int rb_mode, int rb_mode_sp, int rb_id,
sg_put_unaligned_be24(rb_offset, rb10_cb + 3);
sg_put_unaligned_be24(mx_resp_len, rb10_cb + 6);
if (verbose) {
- pr2serr(" Read buffer(10) cdb: ");
- for (k = 0; k < SG_READ_BUFFER_10_CMDLEN; ++k)
- pr2serr("%02x ", rb10_cb[k]);
- pr2serr("\n");
+ char b[128];
+
+ pr2serr(" Read buffer(10) cdb: %s\n",
+ sg_get_command_str(rb10_cb, SG_READ_BUFFER_10_CMDLEN, false,
+ sizeof(b), b));
}
ptvp = construct_scsi_pt_obj();
@@ -226,7 +227,7 @@ sg_ll_read_buffer_16(int sg_fd, int rb_mode, int rb_mode_sp, int rb_id,
uint64_t rb_offset, void * resp, int mx_resp_len,
int * residp, bool noisy, int verbose)
{
- int k, ret, res, sense_cat;
+ int ret, res, sense_cat;
uint8_t rb16_cb[SG_READ_BUFFER_16_CMDLEN] =
{SG_READ_BUFFER_16_CMD, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0};
@@ -240,10 +241,11 @@ sg_ll_read_buffer_16(int sg_fd, int rb_mode, int rb_mode_sp, int rb_id,
sg_put_unaligned_be24(mx_resp_len, rb16_cb + 11);
rb16_cb[14] = (uint8_t)rb_id;
if (verbose) {
- pr2serr(" Read buffer(16) cdb: ");
- for (k = 0; k < SG_READ_BUFFER_16_CMDLEN; ++k)
- pr2serr("%02x ", rb16_cb[k]);
- pr2serr("\n");
+ char b[128];
+
+ pr2serr(" Read buffer(16) cdb: %s\n",
+ sg_get_command_str(rb16_cb, SG_READ_BUFFER_16_CMDLEN, false,
+ sizeof(b), b));
}
ptvp = construct_scsi_pt_obj();
diff --git a/src/sg_rep_zones.c b/src/sg_rep_zones.c
index c5b048f1..3be9f5f0 100644
--- a/src/sg_rep_zones.c
+++ b/src/sg_rep_zones.c
@@ -38,7 +38,7 @@
* and decodes the response. Based on zbc-r02.pdf
*/
-static const char * version_str = "1.18 20191204";
+static const char * version_str = "1.19 20191226";
#define MAX_RZONES_BUFF_LEN (1024 * 1024)
#define DEF_RZONES_BUFF_LEN (1024 * 8)
@@ -127,7 +127,7 @@ sg_ll_report_zones(int sg_fd, uint64_t zs_lba, bool partial, int report_opts,
void * resp, int mx_resp_len, int * residp, bool noisy,
int verbose)
{
- int k, ret, res, sense_cat;
+ int ret, res, sense_cat;
uint8_t rz_cdb[SG_ZONING_IN_CMDLEN] =
{SG_ZONING_IN, REPORT_ZONES_SA, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0};
@@ -140,12 +140,12 @@ sg_ll_report_zones(int sg_fd, uint64_t zs_lba, bool partial, int report_opts,
if (partial)
rz_cdb[14] |= 0x80;
if (verbose) {
- pr2serr(" Report zones cdb: ");
- for (k = 0; k < SG_ZONING_IN_CMDLEN; ++k)
- pr2serr("%02x ", rz_cdb[k]);
- pr2serr("\n");
- }
+ char b[128];
+ pr2serr(" Report zones cdb: %s\n",
+ sg_get_command_str(rz_cdb, SG_ZONING_IN_CMDLEN, false,
+ sizeof(b), b));
+ }
ptvp = construct_scsi_pt_obj();
if (NULL == ptvp) {
pr2serr("%s: out of memory\n", __func__);
diff --git a/src/sg_reset_wp.c b/src/sg_reset_wp.c
index 40a2ffdb..7f265490 100644
--- a/src/sg_reset_wp.c
+++ b/src/sg_reset_wp.c
@@ -37,7 +37,7 @@
* device. Based on zbc-r04c.pdf .
*/
-static const char * version_str = "1.13 20190113";
+static const char * version_str = "1.14 20191220";
#define SG_ZONING_OUT_CMDLEN 16
#define RESET_WRITE_POINTER_SA 0x4
@@ -85,7 +85,7 @@ static int
sg_ll_reset_write_pointer(int sg_fd, uint64_t zid, uint16_t zc, bool all,
bool noisy, int verbose)
{
- int k, ret, res, sense_cat;
+ int ret, res, sense_cat;
uint8_t rwp_cdb[SG_ZONING_OUT_CMDLEN] = {SG_ZONING_OUT,
RESET_WRITE_POINTER_SA, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
uint8_t sense_b[SENSE_BUFF_LEN];
@@ -96,10 +96,11 @@ sg_ll_reset_write_pointer(int sg_fd, uint64_t zid, uint16_t zc, bool all,
if (all)
rwp_cdb[14] = 0x1;
if (verbose) {
- pr2serr(" Reset write pointer cdb: ");
- for (k = 0; k < SG_ZONING_OUT_CMDLEN; ++k)
- pr2serr("%02x ", rwp_cdb[k]);
- pr2serr("\n");
+ char b[128];
+
+ pr2serr(" Reset write pointer cdb: %s\n",
+ sg_get_command_str(rwp_cdb, SG_ZONING_OUT_CMDLEN, false,
+ sizeof(b), b));
}
ptvp = construct_scsi_pt_obj();
diff --git a/src/sg_sanitize.c b/src/sg_sanitize.c
index b4a10682..00d6b59d 100644
--- a/src/sg_sanitize.c
+++ b/src/sg_sanitize.c
@@ -33,7 +33,7 @@
#include "sg_unaligned.h"
#include "sg_pr2serr.h"
-static const char * version_str = "1.13 20190913";
+static const char * version_str = "1.14 20191220";
/* Not all environments support the Unix sleep() */
#if defined(MSC_VER) || defined(__MINGW32__)
@@ -183,7 +183,7 @@ do_sanitize(int sg_fd, const struct opts_t * op, const void * param_lstp,
int param_lst_len)
{
bool immed;
- int k, ret, res, sense_cat, timeout;
+ int ret, res, sense_cat, timeout;
uint8_t san_cdb[SANITIZE_OP_LEN];
uint8_t sense_b[SENSE_BUFF_LEN];
struct sg_pt_base * ptvp;
@@ -217,10 +217,11 @@ do_sanitize(int sg_fd, const struct opts_t * op, const void * param_lstp,
sg_put_unaligned_be16((uint16_t)param_lst_len, san_cdb + 7);
if (op->verbose > 1) {
- pr2serr(" Sanitize cdb: ");
- for (k = 0; k < SANITIZE_OP_LEN; ++k)
- pr2serr("%02x ", san_cdb[k]);
- pr2serr("\n");
+ char b[128];
+
+ pr2serr(" Sanitize cdb: %s\n",
+ sg_get_command_str(san_cdb, SANITIZE_OP_LEN, false,
+ sizeof(b), b));
if (op->verbose > 2) {
if (param_lst_len > 0) {
pr2serr(" Parameter list contents:\n");
diff --git a/src/sg_stream_ctl.c b/src/sg_stream_ctl.c
index cf6ff5f4..4179aa7f 100644
--- a/src/sg_stream_ctl.c
+++ b/src/sg_stream_ctl.c
@@ -35,7 +35,7 @@
* to the given SCSI device. Based on sbc4r15.pdf .
*/
-static const char * version_str = "1.07 20190113";
+static const char * version_str = "1.08 20191220";
#define STREAM_CONTROL_SA 0x14
#define GET_STREAM_STATUS_SA 0x16
@@ -124,10 +124,11 @@ sg_ll_get_stream_status(int sg_fd, uint16_t s_str_id, uint8_t * resp,
sg_put_unaligned_be16(s_str_id, gssCdb + 4);
sg_put_unaligned_be32(alloc_len, gssCdb + 10);
if (verbose) {
- pr2serr(" %s cdb: ", cmd_name);
- for (k = 0; k < (int)sizeof(gssCdb); ++k)
- pr2serr("%02x ", gssCdb[k]);
- pr2serr("\n");
+ char b[128];
+
+ pr2serr(" %s cdb: %s\n", cmd_name,
+ sg_get_command_str(gssCdb, (int)sizeof(gssCdb), false,
+ sizeof(b), b));
}
ptvp = construct_scsi_pt_obj_with_fd(sg_fd, verbose);
@@ -190,10 +191,11 @@ sg_ll_stream_control(int sg_fd, uint32_t str_ctl, uint16_t str_id,
sg_put_unaligned_be16(str_id, scCdb + 4);
sg_put_unaligned_be32(alloc_len, scCdb + 10);
if (verbose) {
- pr2serr(" %s cdb: ", cmd_name);
- for (k = 0; k < (int)sizeof(scCdb); ++k)
- pr2serr("%02x ", scCdb[k]);
- pr2serr("\n");
+ char b[128];
+
+ pr2serr(" %s cdb: %s\n", cmd_name,
+ sg_get_command_str(scCdb, (int)sizeof(scCdb), false,
+ sizeof(b), b));
}
ptvp = construct_scsi_pt_obj_with_fd(sg_fd, verbose);
diff --git a/src/sg_sync.c b/src/sg_sync.c
index fd81686a..a40c1970 100644
--- a/src/sg_sync.c
+++ b/src/sg_sync.c
@@ -37,7 +37,7 @@
* (e.g. disks).
*/
-static const char * version_str = "1.24 20190113";
+static const char * version_str = "1.25 20191220";
#define SYNCHRONIZE_CACHE16_CMD 0x91
#define SYNCHRONIZE_CACHE16_CMDLEN 16
@@ -97,7 +97,7 @@ sg_ll_sync_cache_16(int sg_fd, bool sync_nv, bool immed, int group,
uint64_t lba, unsigned int num_lb, int to_secs,
bool noisy, int verbose)
{
- int res, ret, k, sense_cat;
+ int res, ret, sense_cat;
uint8_t sc_cdb[SYNCHRONIZE_CACHE16_CMDLEN] =
{SYNCHRONIZE_CACHE16_CMD, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0};
@@ -113,10 +113,11 @@ sg_ll_sync_cache_16(int sg_fd, bool sync_nv, bool immed, int group,
sg_put_unaligned_be32((uint32_t)num_lb, sc_cdb + 10);
if (verbose) {
- pr2serr(" synchronize cache(16) cdb: ");
- for (k = 0; k < SYNCHRONIZE_CACHE16_CMDLEN; ++k)
- pr2serr("%02x ", sc_cdb[k]);
- pr2serr("\n");
+ char b[128];
+
+ pr2serr(" Synchronize cache(16) cdb: %s\n",
+ sg_get_command_str(sc_cdb, SYNCHRONIZE_CACHE16_CMDLEN, false,
+ sizeof(b), b));
}
ptvp = construct_scsi_pt_obj();
if (NULL == ptvp) {
diff --git a/src/sg_test_rwbuf.c b/src/sg_test_rwbuf.c
index 86d85ca1..84ef2072 100644
--- a/src/sg_test_rwbuf.c
+++ b/src/sg_test_rwbuf.c
@@ -47,7 +47,7 @@
#include "sg_pr2serr.h"
-static const char * version_str = "1.19 20190913";
+static const char * version_str = "1.20 20191220";
#define BPI (signed)(sizeof(int))
@@ -96,7 +96,7 @@ find_out_about_buffer(int sg_fd)
uint8_t rbBuff[RB_DESC_LEN];
uint8_t sense_buffer[32];
struct sg_io_hdr io_hdr;
- int k, res;
+ int res;
rb_cdb[1] = RB_MODE_DESC;
rb_cdb[8] = RB_DESC_LEN;
@@ -112,10 +112,11 @@ find_out_about_buffer(int sg_fd)
io_hdr.timeout = 60000; /* 60000 millisecs == 60 seconds */
if (verbose) {
- pr2serr(" read buffer [mode desc] cdb: ");
- for (k = 0; k < (int)sizeof(rb_cdb); ++k)
- pr2serr("%02x ", rb_cdb[k]);
- pr2serr("\n");
+ char b[128];
+
+ pr2serr(" read buffer [mode desc] cdb: %s\n",
+ sg_get_command_str(rb_cdb, (int)sizeof(rb_cdb), false,
+ sizeof(b), b));
}
if (ioctl(sg_fd, SG_IO, &io_hdr) < 0) {
perror(ME "SG_IO READ BUFFER descriptor error");
@@ -230,7 +231,7 @@ void do_fill_buffer (int *buf, int len)
int read_buffer (int sg_fd, unsigned ssize)
{
- int res, k;
+ int res;
uint8_t rb_cdb[] = {READ_BUFFER, 0, 0, 0, 0, 0, 0, 0, 0, 0};
int bufSize = ssize + addread;
uint8_t * free_rbBuff = NULL;
@@ -255,10 +256,11 @@ int read_buffer (int sg_fd, unsigned ssize)
io_hdr.pack_id = 2;
io_hdr.timeout = 60000; /* 60000 millisecs == 60 seconds */
if (verbose) {
- pr2serr(" read buffer [mode data] cdb: ");
- for (k = 0; k < (int)sizeof(rb_cdb); ++k)
- pr2serr("%02x ", rb_cdb[k]);
- pr2serr("\n");
+ char b[128];
+
+ pr2serr(" read buffer [mode data] cdb: %s\n",
+ sg_get_command_str(rb_cdb, (int)sizeof(rb_cdb), false,
+ sizeof(b), b));
}
if (ioctl(sg_fd, SG_IO, &io_hdr) < 0) {
@@ -300,7 +302,7 @@ int write_buffer (int sg_fd, unsigned ssize)
false);
uint8_t sense_buffer[32];
struct sg_io_hdr io_hdr;
- int k, res;
+ int res;
if (NULL == wbBuff)
return -1;
@@ -320,10 +322,11 @@ int write_buffer (int sg_fd, unsigned ssize)
io_hdr.pack_id = 1;
io_hdr.timeout = 60000; /* 60000 millisecs == 60 seconds */
if (verbose) {
- pr2serr(" write buffer [mode data] cdb: ");
- for (k = 0; k < (int)sizeof(wb_cdb); ++k)
- pr2serr("%02x ", wb_cdb[k]);
- pr2serr("\n");
+ char b[128];
+
+ pr2serr(" write buffer [mode data] cdb: %s\n",
+ sg_get_command_str(wb_cdb, (int)sizeof(wb_cdb), false,
+ sizeof(b), b));
}
if (ioctl(sg_fd, SG_IO, &io_hdr) < 0) {
diff --git a/src/sg_timestamp.c b/src/sg_timestamp.c
index ea1e1dd8..cc3d054b 100644
--- a/src/sg_timestamp.c
+++ b/src/sg_timestamp.c
@@ -37,7 +37,7 @@
* to the given SCSI device. Based on spc5r07.pdf .
*/
-static const char * version_str = "1.13 20180113";
+static const char * version_str = "1.14 20191220";
#define REP_TIMESTAMP_CMDLEN 12
#define SET_TIMESTAMP_CMDLEN 12
@@ -202,10 +202,11 @@ sg_ll_rep_timestamp(int sg_fd, void * resp, int mx_resp_len, int * residp,
sg_put_unaligned_be32((uint32_t)mx_resp_len, rt_cdb + 6);
if (verbose) {
- pr2serr(" Report timestamp cdb: ");
- for (k = 0; k < REP_TIMESTAMP_CMDLEN; ++k)
- pr2serr("%02x ", rt_cdb[k]);
- pr2serr("\n");
+ char b[128];
+
+ pr2serr(" Report timestamp cdb: %s\n",
+ sg_get_command_str(rt_cdb, REP_TIMESTAMP_CMDLEN, false,
+ sizeof(b), b));
}
ptvp = construct_scsi_pt_obj();
@@ -252,7 +253,7 @@ static int
sg_ll_set_timestamp(int sg_fd, void * paramp, int param_len, bool noisy,
int verbose)
{
- int k, ret, res, sense_cat;
+ int ret, res, sense_cat;
uint8_t st_cdb[SET_TIMESTAMP_CMDLEN] =
{SG_MAINTENANCE_OUT, SET_TIMESTAMP_SA, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0};
@@ -261,10 +262,11 @@ sg_ll_set_timestamp(int sg_fd, void * paramp, int param_len, bool noisy,
sg_put_unaligned_be32(param_len, st_cdb + 6);
if (verbose) {
- pr2serr(" Set timestamp cdb: ");
- for (k = 0; k < SET_TIMESTAMP_CMDLEN; ++k)
- pr2serr("%02x ", st_cdb[k]);
- pr2serr("\n");
+ char b[128];
+
+ pr2serr(" Set timestamp cdb: %s\n",
+ sg_get_command_str(st_cdb, SET_TIMESTAMP_CMDLEN, false,
+ sizeof(b), b));
if ((verbose > 1) && paramp && param_len) {
pr2serr(" set timestamp parameter list:\n");
hex2stderr((const uint8_t *)paramp, param_len, -1);
diff --git a/src/sg_verify.c b/src/sg_verify.c
index ad0057b8..642d10ae 100644
--- a/src/sg_verify.c
+++ b/src/sg_verify.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2004-2018 Douglas Gilbert.
+ * Copyright (c) 2004-2019 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.
@@ -39,7 +39,7 @@
* the possibility of protection data (DIF).
*/
-static const char * version_str = "1.25 20180628"; /* sbc4r15 */
+static const char * version_str = "1.26 20191216"; /* sbc4r17 */
#define ME "sg_verify: "
@@ -47,6 +47,7 @@ static const char * version_str = "1.25 20180628"; /* sbc4r15 */
static struct option long_options[] = {
+ {"0", no_argument, 0, '0'},
{"16", no_argument, 0, 'S'},
{"bpc", required_argument, 0, 'b'},
{"bytchk", required_argument, 0, 'B'}, /* 4 backward compatibility */
@@ -70,22 +71,23 @@ static struct option long_options[] = {
static void
usage()
{
- pr2serr("Usage: sg_verify [--16] [--bpc=BPC] [--count=COUNT] [--dpo] "
- "[--ebytchk=BCH]\n"
- " [--group=GN] [--help] [--in=IF] "
- "[--lba=LBA] [--ndo=NDO]\n"
- " [--quiet] [--readonly] [--verbose] "
- "[--version]\n"
- " [--vrprotect=VRP] DEVICE\n"
+ pr2serr("Usage: sg_verify [--0] [--16] [--bpc=BPC] [--count=COUNT] "
+ "[--dpo]\n"
+ " [--ebytchk=BCH] [--ff] [--group=GN] [--help] "
+ "[--in=IF]\n"
+ " [--lba=LBA] [--ndo=NDO] [--quiet] "
+ "[--readonly]\n"
+ " [--verbose] [--version] [--vrprotect=VRP] "
+ "DEVICE\n"
" where:\n"
+ " --0|-0 fill buffer with zeros (don't read "
+ "stdin)\n"
" --16|-S use VERIFY(16) (def: use "
"VERIFY(10) )\n"
" --bpc=BPC|-b BPC max blocks per verify command "
"(def: 128)\n"
" --count=COUNT|-c COUNT count of blocks to verify "
"(def: 1).\n"
- " If BCH=3 then COUNT must "
- "be 1 .\n"
" --dpo|-d disable page out (cache retention "
"priority)\n"
" --ebytchk=BCH|-E BCH sets BYTCHK value, either 1, 2 "
@@ -96,6 +98,8 @@ usage()
"size\n"
" (plus protection size if DIF "
"active)\n"
+ " --ff|-f fill buffer with 0xff bytes (don't read "
+ "stdin)\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: "
@@ -130,12 +134,14 @@ main(int argc, char * argv[])
{
bool bpc_given = false;
bool dpo = false;
+ bool ff_given = false;
bool got_stdin = false;
bool quiet = false;
bool readonly = false;
bool verbose_given = false;
bool verify16 = false;
bool version_given = false;
+ bool zero_given = false;
int res, c, num, nread, infd;
int sg_fd = -1;
int bpc = 128;
@@ -162,12 +168,15 @@ main(int argc, char * argv[])
while (1) {
int option_index = 0;
- c = getopt_long(argc, argv, "b:B:c:dE:g:hi:l:n:P:qrSvV", long_options,
- &option_index);
+ c = getopt_long(argc, argv, "0b:B:c:dE:fg:hi:l:n:P:qrSvV",
+ long_options, &option_index);
if (c == -1)
break;
switch (c) {
+ case '0':
+ zero_given = true;
+ break;
case 'b':
bpc = sg_get_num(optarg);
if (bpc < 1) {
@@ -188,11 +197,14 @@ main(int argc, char * argv[])
break;
case 'E':
bytchk = sg_get_num(optarg);
- if ((bytchk < 1) || (bytchk > 3)) {
+ if ((bytchk < 0) || (bytchk > 3)) {
pr2serr("bad argument to '--ebytchk'\n");
return SG_LIB_SYNTAX_ERROR;
}
break;
+ case 'f':
+ ff_given = true;
+ break;
case 'g':
group = sg_get_num(optarg);
if ((group < 0) || (group > 63)) {
@@ -242,7 +254,7 @@ main(int argc, char * argv[])
readonly = true;
break;
case 'S':
- verify16 = false;
+ verify16 = true;
break;
case 'v':
verbose_given = true;
@@ -300,16 +312,23 @@ main(int argc, char * argv[])
pr2serr("count exceed 31 bits, way too large\n");
return SG_LIB_SYNTAX_ERROR;
}
+#if 0
if ((3 == bytchk) && (1 != count)) {
pr2serr("count must be 1 when bytchk=3\n");
return SG_LIB_SYNTAX_ERROR;
}
- bpc = (int)count;
+ // bpc = (int)count;
+#endif
} else if (bytchk > 0) {
- pr2serr("when the 'ebytchk=BCH' option is given, then '--bytchk=NDO' "
+ pr2serr("when the 'ebytchk=BCH' option is given, then '--ndo=NDO' "
"must also be given\n");
return SG_LIB_CONTRADICT;
}
+ if ((zero_given || ff_given) && file_name) {
+ pr2serr("giving --0 or --ff is not compatible with --if=%s\n",
+ file_name);
+ return SG_LIB_CONTRADICT;
+ }
if ((bpc > 0xffff) && (! verify16)) {
pr2serr("'%s' exceeds 65535, so use VERIFY(16)\n",
@@ -334,6 +353,10 @@ main(int argc, char * argv[])
ret = sg_convert_errno(ENOMEM);
goto err_out;
}
+ if (ff_given)
+ memset(ref_data, 0xff, ndo);
+ if (zero_given || ff_given)
+ goto skip;
if ((NULL == file_name) || (0 == strcmp(file_name, "-"))) {
got_stdin = true;
infd = STDIN_FILENO;
@@ -363,7 +386,7 @@ main(int argc, char * argv[])
if (! got_stdin)
close(infd);
}
-
+skip:
if (NULL == device_name) {
pr2serr("missing device name!\n");
usage();
@@ -413,7 +436,8 @@ main(int argc, char * argv[])
break;
case SG_LIB_CAT_MISCOMPARE:
if ((0 == quiet) || verbose)
- pr2serr("%s reported MISCOMPARE\n", vc);
+ pr2serr("%s MISCOMPARE: started at LBA 0x%" PRIx64 "\n",
+ vc, lba);
break;
default:
sg_get_category_sense_str(res, sizeof(b), b, verbose);
diff --git a/src/sg_write_same.c b/src/sg_write_same.c
index f50647db..9ba8c3a6 100644
--- a/src/sg_write_same.c
+++ b/src/sg_write_same.c
@@ -33,7 +33,7 @@
#include "sg_unaligned.h"
#include "sg_pr2serr.h"
-static const char * version_str = "1.28 20190124";
+static const char * version_str = "1.30 20191220";
#define ME "sg_write_same: "
@@ -64,6 +64,7 @@ static struct option long_options[] = {
{"16", no_argument, 0, 'S'},
{"32", no_argument, 0, 'T'},
{"anchor", no_argument, 0, 'a'},
+ {"ff", no_argument, 0, 'f'},
{"grpnum", required_argument, 0, 'g'},
{"help", no_argument, 0, 'h'},
{"in", required_argument, 0, 'i'},
@@ -83,6 +84,7 @@ static struct option long_options[] = {
struct opts_t {
bool anchor;
+ bool ff;
bool ndob;
bool lbdata;
bool pbdata;
@@ -106,12 +108,12 @@ static void
usage()
{
pr2serr("Usage: sg_write_same [--10] [--16] [--32] [--anchor] "
- "[--grpnum=GN] [--help]\n"
- " [--in=IF] [--lba=LBA] [--lbdata] "
- "[--ndob] [--num=NUM]\n"
- " [--pbdata] [--timeout=TO] [--unmap] "
- "[--verbose]\n"
- " [--version] [--wrprotect=WRP] "
+ "[-ff] [--grpnum=GN]\n"
+ " [--help] [--in=IF] [--lba=LBA] [--lbdata] "
+ "[--ndob]\n"
+ " [--num=NUM] [--pbdata] [--timeout=TO] "
+ "[--unmap]\n"
+ " [--verbose] [--version] [--wrprotect=WRP] "
"[xferlen=LEN]\n"
" DEVICE\n"
" where:\n"
@@ -123,6 +125,8 @@ usage()
"then def 16)\n"
" --32|-T send WRITE SAME(32) (def: 10 or 16)\n"
" --anchor|-a set ANCHOR field in cdb\n"
+ " --ff|-f use buffer of 0xff bytes for fill "
+ "(def: 0x0 bytes)\n"
" --grpnum=GN|-g GN GN is group number field (def: 0)\n"
" --help|-h print out usage message\n"
" --in=IF|-i IF IF is file to fetch one block of data "
@@ -163,7 +167,7 @@ static int
do_write_same(int sg_fd, const struct opts_t * op, const void * dataoutp,
int * act_cdb_lenp)
{
- int k, ret, res, sense_cat, cdb_len;
+ int ret, res, sense_cat, cdb_len;
uint64_t llba;
uint8_t ws_cdb[WRITE_SAME32_LEN];
uint8_t sense_b[SENSE_BUFF_LEN];
@@ -251,11 +255,11 @@ do_write_same(int sg_fd, const struct opts_t * op, const void * dataoutp,
}
if (op->verbose > 1) {
- pr2serr(" Write same(%d) cdb: ", cdb_len);
- for (k = 0; k < cdb_len; ++k)
- pr2serr("%02x ", ws_cdb[k]);
- pr2serr("\n Data-out buffer length=%d\n",
- op->xfer_len);
+ char b[128];
+
+ pr2serr(" Write same(%d) cdb: %s\n", cdb_len,
+ sg_get_command_str(ws_cdb, cdb_len, false, sizeof(b), b));
+ pr2serr(" Data-out buffer length=%d\n", op->xfer_len);
}
if ((op->verbose > 3) && (op->xfer_len > 0)) {
pr2serr(" Data-out buffer contents:\n");
@@ -337,7 +341,7 @@ main(int argc, char * argv[])
while (1) {
int option_index = 0;
- c = getopt_long(argc, argv, "ag:hi:l:Ln:NPRSt:TUvVw:x:",
+ c = getopt_long(argc, argv, "afg:hi:l:Ln:NPRSt:TUvVw:x:",
long_options, &option_index);
if (c == -1)
break;
@@ -346,6 +350,9 @@ main(int argc, char * argv[])
case 'a':
op->anchor = true;
break;
+ case 'f':
+ op->ff = true;
+ break;
case 'g':
op->grpnum = sg_get_num(optarg);
if ((op->grpnum < 0) || (op->grpnum > 63)) {
@@ -591,6 +598,8 @@ main(int argc, char * argv[])
ret = sg_convert_errno(ENOMEM);
goto err_out;
}
+ if (op->ff)
+ memset(wBuff, 0xff, op->xfer_len);
if (op->ifilename[0]) {
if (got_stdin) {
infd = STDIN_FILENO;
diff --git a/src/sg_write_verify.c b/src/sg_write_verify.c
index ab19607c..4a8ea248 100644
--- a/src/sg_write_verify.c
+++ b/src/sg_write_verify.c
@@ -40,7 +40,7 @@
#include "sg_unaligned.h"
#include "sg_pr2serr.h"
-static const char * version_str = "1.16 20190113";
+static const char * version_str = "1.17 20191220";
#define ME "sg_write_verify: "
@@ -127,18 +127,18 @@ run_scsi_transaction(int sg_fd, const uint8_t *cdbp, int cdb_len,
uint8_t *dop, int do_len, int timeout,
bool noisy, int verbose)
{
- int res, k, sense_cat, ret;
+ int res, sense_cat, ret;
struct sg_pt_base * ptvp;
uint8_t sense_b[SENSE_BUFF_LEN];
char b[32];
snprintf(b, sizeof(b), "Write and verify(%d)", cdb_len);
if (verbose) {
- pr2serr(" %s cdb: ", b);
- for (k = 0; k < cdb_len; ++k)
- pr2serr("%02x ", cdbp[k]);
- pr2serr("\n");
- if ((verbose > 2) && dop && do_len) {
+ char d[128];
+
+ pr2serr(" %s cdb: %s\n", b,
+ sg_get_command_str(cdbp, cdb_len, false, sizeof(d), d));
+ if ((verbose > 2) && dop && do_len) {
pr2serr(" Data out buffer [%d bytes]:\n", do_len);
hex2stderr(dop, do_len, -1);
}
diff --git a/src/sg_write_x.c b/src/sg_write_x.c
index fca94377..0bc28c27 100644
--- a/src/sg_write_x.c
+++ b/src/sg_write_x.c
@@ -38,7 +38,7 @@
#include "sg_unaligned.h"
#include "sg_pr2serr.h"
-static const char * version_str = "1.21 20190913";
+static const char * version_str = "1.22 20191220";
/* Protection Information refers to 8 bytes of extra information usually
* associated with each logical block and is often abbreviated to PI while
@@ -1237,10 +1237,10 @@ do_write_x(int sg_fd, const void * dataoutp, int dout_len,
}
if (vb > 1) {
- pr2serr(" %s cdb: ", op->cdb_name);
- for (k = 0; k < cdb_len; ++k)
- pr2serr("%02x ", x_cdb[k]);
- pr2serr("\n");
+ char b[128];
+
+ pr2serr(" %s cdb: %s\n", op->cdb_name,
+ sg_get_command_str(x_cdb, cdb_len, false, sizeof(b), b));
}
if (op->do_scattered && (vb > 2) && (dout_len > 31)) {
uint32_t sod_off = op->bs_pi_do * op->scat_lbdof;
diff --git a/src/sg_zone.c b/src/sg_zone.c
index e4b2bccf..14fa0885 100644
--- a/src/sg_zone.c
+++ b/src/sg_zone.c
@@ -37,7 +37,7 @@
* to the given SCSI device. Based on zbc-r04c.pdf .
*/
-static const char * version_str = "1.13 20190113";
+static const char * version_str = "1.14 20191220";
#define SG_ZONING_OUT_CMDLEN 16
#define CLOSE_ZONE_SA 0x1
@@ -114,7 +114,7 @@ static int
sg_ll_zone_out(int sg_fd, int sa, uint64_t zid, uint16_t zc, bool all,
bool noisy, int verbose)
{
- int k, ret, res, sense_cat;
+ int ret, res, sense_cat;
struct sg_pt_base * ptvp;
uint8_t zo_cdb[SG_ZONING_OUT_CMDLEN] =
{SG_ZONING_OUT, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
@@ -128,10 +128,11 @@ sg_ll_zone_out(int sg_fd, int sa, uint64_t zid, uint16_t zc, bool all,
zo_cdb[14] = 0x1;
sg_get_opcode_sa_name(zo_cdb[0], sa, -1, sizeof(b), b);
if (verbose) {
- pr2serr(" %s cdb: ", b);
- for (k = 0; k < SG_ZONING_OUT_CMDLEN; ++k)
- pr2serr("%02x ", zo_cdb[k]);
- pr2serr("\n");
+ char d[128];
+
+ pr2serr(" %s cdb: %s\n", b,
+ sg_get_command_str(zo_cdb, SG_ZONING_OUT_CMDLEN,
+ false, sizeof(d), d));
}
ptvp = construct_scsi_pt_obj();
diff --git a/src/sgm_dd.c b/src/sgm_dd.c
index 0883def1..d40f7859 100644
--- a/src/sgm_dd.c
+++ b/src/sgm_dd.c
@@ -69,7 +69,7 @@
#include "sg_pr2serr.h"
-static const char * version_str = "1.63 20190618";
+static const char * version_str = "1.64 20191226";
#define DEF_BLOCK_SIZE 512
#define DEF_BLOCKS_PER_TRANSFER 128
@@ -467,7 +467,7 @@ static int
sg_read(int sg_fd, uint8_t * buff, int blocks, int64_t from_block,
int bs, int cdbsz, bool fua, bool dpo, bool do_mmap)
{
- int k, res;
+ int res;
uint8_t rdCmd[MAX_SCSI_CDBSZ];
uint8_t senseBuff[SENSE_BUFF_LEN];
struct sg_io_hdr io_hdr;
@@ -493,10 +493,10 @@ sg_read(int sg_fd, uint8_t * buff, int blocks, int64_t from_block,
if (do_mmap)
io_hdr.flags |= SG_FLAG_MMAP_IO;
if (verbose > 2) {
- pr2serr(" read cdb: ");
- for (k = 0; k < cdbsz; ++k)
- pr2serr("%02x ", rdCmd[k]);
- pr2serr("\n");
+ char b[128];
+
+ pr2serr(" Read cdb: %s\n",
+ sg_get_command_str(rdCmd, cdbsz, false, sizeof(b), b));
}
#if 1
@@ -558,7 +558,7 @@ static int
sg_write(int sg_fd, uint8_t * buff, int blocks, int64_t to_block,
int bs, int cdbsz, bool fua, bool dpo, bool do_mmap, bool * diop)
{
- int k, res;
+ int res;
uint8_t wrCmd[MAX_SCSI_CDBSZ];
uint8_t senseBuff[SENSE_BUFF_LEN];
struct sg_io_hdr io_hdr;
@@ -586,10 +586,10 @@ sg_write(int sg_fd, uint8_t * buff, int blocks, int64_t to_block,
else if (diop && *diop)
io_hdr.flags |= SG_FLAG_DIRECT_IO;
if (verbose > 2) {
- pr2serr(" write cdb: ");
- for (k = 0; k < cdbsz; ++k)
- pr2serr("%02x ", wrCmd[k]);
- pr2serr("\n");
+ char b[128];
+
+ pr2serr(" Write cdb: %s\n",
+ sg_get_command_str(wrCmd, cdbsz, false, sizeof(b), b));
}
#if 1
diff --git a/testing/sgh_dd.cpp b/testing/sgh_dd.cpp
index d512aac1..73a2e677 100644
--- a/testing/sgh_dd.cpp
+++ b/testing/sgh_dd.cpp
@@ -108,7 +108,7 @@
using namespace std;
-static const char * version_str = "1.55 20191201";
+static const char * version_str = "1.61 20191226";
#ifdef __GNUC__
#ifndef __clang__
@@ -138,6 +138,7 @@ static const char * version_str = "1.55 20191201";
#define DEF_TIMEOUT 60000 /* 60,000 millisecs == 60 seconds */
#define SGP_READ10 0x28
+#define SGP_VERIFY10 0x2f
#define SGP_WRITE10 0x2a
#define DEF_NUM_THREADS 4
#define MAX_NUM_THREADS 1024 /* was SG_MAX_QUEUE with v3 driver */
@@ -244,6 +245,7 @@ typedef struct global_collection
bool mrq_cmds; /* mrq=<NRQS>,C given */
bool mrq_async; /* either mrq_immed or no_waitq flags given */
bool unbalanced_mrq; /* so _not_ sg->sg request sharing sync mrq */
+ bool verify; /* don't copy, verify like Unix: cmp */
const char * infp;
const char * outfp;
const char * out2fp;
@@ -435,11 +437,15 @@ pr_errno_lk(int e_no, const char * fmt, ...)
#endif
static void
-lk_print_command(uint8_t * cmdp)
+lk_print_command_len(const char *prefix, uint8_t * cmdp, int len, bool lock)
{
- pthread_mutex_lock(&strerr_mut);
- sg_print_command(cmdp);
- pthread_mutex_unlock(&strerr_mut);
+ if (lock)
+ pthread_mutex_lock(&strerr_mut);
+ if (prefix && *prefix)
+ fputs(prefix, stderr);
+ sg_print_command_len(cmdp, len);
+ if (lock)
+ pthread_mutex_unlock(&strerr_mut);
}
static void
@@ -667,8 +673,9 @@ print_stats(const char * str)
infull - gcoll.in_partial.load(), gcoll.in_partial.load());
outfull = dd_count - gcoll.out_rem_count.load();
- pr2serr("%s%" PRId64 "+%d records out\n", str,
- outfull - gcoll.out_partial.load(), gcoll.out_partial.load());
+ pr2serr("%s%" PRId64 "+%d records %s\n", str,
+ outfull - gcoll.out_partial.load(), gcoll.out_partial.load(),
+ (gcoll.verify ? "verified" : "out"));
}
static void
@@ -807,7 +814,8 @@ usage(int pg_num)
" [mrq=[IO,]NRQS[,C]] [of2=OFILE2] [ofreg=OFREG] "
"[sync=0|1]\n"
" [thr=THR] [time=0|1] [verbose=VERB] [--dry-run] "
- "[--verbose]\n\n"
+ "[--verbose]\n"
+ " [--verify] [--version]\n\n"
" where the main options (shown in first group above) are:\n"
" bs must be device logical block size (default "
"512)\n"
@@ -830,13 +838,16 @@ usage(int pg_num)
" seek block position to start writing to OFILE\n"
" skip block position to start reading from IFILE\n"
" --help|-h output this usage message then exit\n"
+ " --verify|-x do a verify (compare) operation [def: do a "
+ "copy]\n"
" --version|-V output version string then exit\n\n"
"Copy IFILE to OFILE, similar to dd command. This utility is "
"specialized for\nSCSI devices and uses multiple POSIX threads. "
- "It expects one or both IFILE\nand OFILE to be sg devices. It "
- "is Linux specific and uses the v4 sg driver\n'share' capability "
- "if available. Use '-hh', '-hhh' or '-hhhh' for more\n"
- "information.\n"
+ "It expects one or both IFILE\nand OFILE to be sg devices. With "
+ "--verify option does a verify/compare\noperation instead of a "
+ "copy. This utility is Linux specific and uses the\nv4 sg "
+ "driver 'share' capability if available. Use '-hh', '-hhh' or "
+ "'-hhhh'\nfor more information.\n"
#ifdef SGH_DD_READ_COMPLET_AFTER
"\nIn this version oflag=swait does read completion _after_ "
"write completion\n"
@@ -846,17 +857,18 @@ usage(int pg_num)
page2:
pr2serr("Syntax: sgh_dd [operands] [options]\n\n"
" where: operands have the form name=value and are pecular to "
- "'dd'\n style commands, and options start with one or "
- "two hyphens\n\n"
- " where the less used options (not shown on first help page) "
- "are:\n"
+ "'dd'\n"
+ " style commands, and options start with one or "
+ "two hyphens;\n"
+ " the lesser used operands and option are:\n\n"
" ae AEN: abort every n commands (def: 0 --> don't "
"abort any)\n"
" MAEN: abort every n mrq commands (def: 0 --> "
"don't)\n"
" [requires commands with > 1 ms duration]\n"
" bpt is blocks_per_transfer (default is 128)\n"
- " cdbsz size of SCSI READ or WRITE cdb (default is 10)\n"
+ " cdbsz size of SCSI READ, WRITE or VERIFY cdb_s "
+ "(default is 10)\n"
" coe continue on error, 0->exit (def), "
"1->zero + continue\n"
" deb for debug, 0->none (def), > 0->varying degrees "
@@ -887,7 +899,8 @@ page2:
return;
page3:
pr2serr("Syntax: sgh_dd [operands] [options]\n\n"
- " where: iflag=' and 'oflag=' arguments are listed below:\n"
+ " where: 'iflag=<arg>' and 'oflag=<arg>' arguments are listed "
+ "below:\n\n"
" append append output to OFILE (assumes OFILE is "
"regular file)\n"
" coe continue of error (reading, fills with zeros)\n"
@@ -949,7 +962,8 @@ page4:
"devices, then the READ in\neach read-write pair is issued an "
"even pack_id and its WRITE pair is\ngiven the pack_id one "
"higher (i.e. an odd number). This enables a\n'cat '"
- "/proc/scsi/sg/debug' user to see associated commands.\n\n");
+ "/proc/scsi/sg/debug' user to see that progress is being "
+ "made.\n\n");
pr2serr("Debugging:\n"
"Apart from using one or more '--verbose' options which gets a "
"bit noisy\n'cat /proc/scsi/sg/debug' can give a good overview "
@@ -968,7 +982,8 @@ page4:
"output)\nis entered during request setup and completion. It "
"is intended to be\na temporary state. It should not block "
"but does sometimes (e.g. in\nblock_get_request()). Even so "
- "that block should be short and\nif not there is a problem.\n");
+ "that blockage should be short and if not\nthere is a "
+ "problem.\n");
return;
}
@@ -1245,6 +1260,7 @@ read_write_thread(void * v_tip)
int64_t my_index;
volatile bool stop_after_write = false;
bool own_infd = false;
+ bool in_is_sg, in_mmap, out_is_sg, out_mmap;
bool own_outfd = false;
bool own_out2fd = false;
bool share_and_ofreg;
@@ -1254,13 +1270,17 @@ read_write_thread(void * v_tip)
clp = tip->gcp;
vb = clp->debug;
sz = clp->bpt * clp->bs;
+ in_is_sg = (FT_SG == clp->in_type);
+ in_mmap = (in_is_sg && clp->in_flags.mmap);
+ out_is_sg = (FT_SG == clp->out_type);
+ out_mmap = (out_is_sg && clp->out_flags.mmap);
memset(rep, 0, sizeof(Rq_elem));
/* Following clp members are constant during lifetime of thread */
rep->clp = clp;
rep->id = tip->id;
if (vb > 2)
pr2serr_lk("%d <-- Starting worker thread\n", rep->id);
- if (! clp->in_flags.mmap) {
+ if (! in_mmap) {
int n = sz;
if (clp->unbalanced_mrq)
@@ -1279,13 +1299,13 @@ read_write_thread(void * v_tip)
rep->mrq_index = clp->nmrqs - 1;
if (rep->infd == rep->outfd) {
- if (FT_SG == clp->in_type)
+ if (in_is_sg)
rep->same_sg = true;
- } else if ((FT_SG == clp->in_type) && (FT_SG == clp->out_type))
+ } else if (in_is_sg && out_is_sg)
rep->both_sg = true;
- else if (FT_SG == clp->in_type)
+ else if (in_is_sg)
rep->only_in_sg = true;
- else if (FT_SG == clp->out_type)
+ else if (out_is_sg)
rep->only_out_sg = true;
if (clp->in_flags.same_fds || clp->out_flags.same_fds) {
@@ -1297,10 +1317,9 @@ read_write_thread(void * v_tip)
} else {
int fd;
- if ((FT_SG == clp->in_type) && clp->infp) {
- fd = sg_in_open(clp, clp->infp,
- (clp->in_flags.mmap ? &rep->buffp : NULL),
- (clp->in_flags.mmap ? &rep->mmap_len : NULL));
+ if (in_is_sg && clp->infp) {
+ fd = sg_in_open(clp, clp->infp, (in_mmap ? &rep->buffp : NULL),
+ (in_mmap ? &rep->mmap_len : NULL));
if (fd < 0)
goto fini;
rep->infd = fd;
@@ -1309,10 +1328,9 @@ read_write_thread(void * v_tip)
if (vb > 2)
pr2serr_lk("thread=%d: opened local sg IFILE\n", rep->id);
}
- if ((FT_SG == clp->out_type) && clp->outfp) {
- fd = sg_out_open(clp, clp->outfp,
- (clp->out_flags.mmap ? &rep->buffp : NULL),
- (clp->out_flags.mmap ? &rep->mmap_len : NULL));
+ if (out_is_sg && clp->outfp) {
+ fd = sg_out_open(clp, clp->outfp, (out_mmap ? &rep->buffp : NULL),
+ (out_mmap ? &rep->mmap_len : NULL));
if (fd < 0)
goto fini;
rep->outfd = fd;
@@ -1323,8 +1341,8 @@ read_write_thread(void * v_tip)
}
if ((FT_SG == clp->out2_type) && clp->out2fp) {
fd = sg_out_open(clp, clp->out2fp,
- (clp->out_flags.mmap ? &rep->buffp : NULL),
- (clp->out_flags.mmap ? &rep->mmap_len : NULL));
+ (out_mmap ? &rep->buffp : NULL),
+ (out_mmap ? &rep->mmap_len : NULL));
if (fd < 0)
goto fini;
rep->out2fd = fd;
@@ -1341,10 +1359,10 @@ read_write_thread(void * v_tip)
}
}
if (vb > 2) {
- if ((FT_SG == clp->in_type) && (! own_infd))
+ if (in_is_sg && (! own_infd))
pr2serr_lk("thread=%d: using global sg IFILE, fd=%d\n", rep->id,
rep->infd);
- if ((FT_SG == clp-> out_type) && (! own_outfd))
+ if (out_is_sg && (! own_outfd))
pr2serr_lk("thread=%d: using global sg OFILE, fd=%d\n", rep->id,
rep->outfd);
if ((FT_SG == clp->out2_type) && (! own_out2fd))
@@ -1361,8 +1379,7 @@ read_write_thread(void * v_tip)
else if (vb > 4)
pr2serr_lk("thread=%d: Skipping IFILE share with OFILE due to "
"mrq>0\n", rep->id);
- } else if (sg_version_ge_40030 && (FT_SG == clp->in_type) &&
- (FT_SG == clp->out_type))
+ } else if (sg_version_ge_40030 && in_is_sg && out_is_sg)
rep->has_share = sg_share_prepare(rep->outfd, rep->infd, rep->id,
vb > 9);
if (vb > 9)
@@ -1406,7 +1423,7 @@ read_write_thread(void * v_tip)
// clp->in_count -= blocks;
pthread_cleanup_push(cleanup_in, (void *)clp);
- if (FT_SG == clp->in_type) {
+ if (in_is_sg) {
if (rep->swait)
sg_in_out_interleave(clp, rep, deferred_arr);
else /* unlocks in_mutex mid op */
@@ -1425,8 +1442,7 @@ read_write_thread(void * v_tip)
if (0 != status) err_exit(status, "lock out_mutex");
/* Make sure the OFILE (+ OFREG) are in same sequence as IFILE */
- if ((rep->outregfd < 0) && (FT_SG == clp->in_type) &&
- (FT_SG == clp->out_type))
+ if ((rep->outregfd < 0) && in_is_sg && out_is_sg)
goto skip_force_out_sequence;
if (share_and_ofreg || (FT_DEV_NULL != clp->out_type)) {
while ((! clp->out_stop.load()) &&
@@ -1468,7 +1484,7 @@ skip_force_out_sequence:
}
/* Output to OFILE */
wr_blks = rep->num_blks;
- if (FT_SG == clp->out_type) {
+ if (out_is_sg) {
if (rep->swait) { /* done already in sg_in_out_interleave() */
status = pthread_mutex_unlock(&clp->out_mutex);
if (0 != status) err_exit(status, "unlock out_mutex");
@@ -1543,12 +1559,12 @@ fini:
if ((clp->nmrqs > 0) &&
(! (clp->in_flags.no_unshare || clp->out_flags.no_unshare)))
sg_unshare(rep->infd, rep->id, vb > 9);
- } else if ((FT_SG == clp->in_type) && (FT_SG == clp->out_type))
+ } else if (in_is_sg && out_is_sg)
if (! (clp->in_flags.no_unshare || clp->out_flags.no_unshare))
sg_unshare(rep->infd, rep->id, vb > 9);
}
if (own_infd && (rep->infd >= 0)) {
- if (vb && (FT_SG == clp->in_type)) {
+ if (vb && in_is_sg) {
++num_waiting_calls;
if (ioctl(rep->infd, SG_GET_NUM_WAITING, &n) >= 0) {
if (n > 0)
@@ -1563,7 +1579,7 @@ fini:
close(rep->infd);
}
if (own_outfd && (rep->outfd >= 0)) {
- if (vb && (FT_SG == clp->out_type)) {
+ if (vb && out_is_sg) {
++num_waiting_calls;
if (ioctl(rep->outfd, SG_GET_NUM_WAITING, &n) >= 0) {
if (n > 0)
@@ -1606,14 +1622,14 @@ normal_in_rd(Rq_elem * rep, int blocks)
}
}
/* enters holding in_mutex */
- while (((res = read(clp->infd, get_buffp(rep), blocks * clp->bs)) < 0) &&
+ while (((res = read(clp->infd, rep->buffp, blocks * clp->bs)) < 0) &&
((EINTR == errno) || (EAGAIN == errno)))
std::this_thread::yield();/* another thread may be able to progress */
if (res < 0) {
if (clp->in_flags.coe) {
- memset(get_buffp(rep), 0, rep->num_blks * clp->bs);
+ memset(rep->buffp, 0, rep->num_blks * clp->bs);
pr2serr_lk("tid=%d: >> substituted zeros for in blk=%" PRId64
- " for %d bytes, %s\n", rep->id, rep->iblk,
+ " for %d bytes, %s\n", rep->id, rep->iblk,
rep->num_blks * clp->bs,
tsafe_strerror(errno, strerr_buff));
res = rep->num_blks * clp->bs;
@@ -1656,7 +1672,7 @@ normal_out_wr(Rq_elem * rep, int blocks)
if (clp->debug > 4)
pr2serr_lk("%s: tid=%d: oblk=%" PRIu64 ", blocks=%d\n", __func__,
rep->id, rep->oblk, blocks);
- while (((res = write(clp->outfd, get_buffp(rep), rep->num_blks * clp->bs))
+ while (((res = write(clp->outfd, rep->buffp, rep->num_blks * clp->bs))
< 0) && ((EINTR == errno) || (EAGAIN == errno)))
std::this_thread::yield();/* another thread may be able to progress */
if (res < 0) {
@@ -1687,13 +1703,25 @@ normal_out_wr(Rq_elem * rep, int blocks)
static int
sg_build_scsi_cdb(uint8_t * cdbp, int cdb_sz, unsigned int blocks,
- int64_t start_block, bool write_true, bool fua, bool dpo)
+ int64_t start_block, bool ver_true, bool write_true,
+ bool fua, bool dpo)
{
int rd_opcode[] = {0x8, 0x28, 0xa8, 0x88};
+ int ve_opcode[] = {0xff /* no VER(6) */, 0x2f, 0xaf, 0x8f};
int wr_opcode[] = {0xa, 0x2a, 0xaa, 0x8a};
int sz_ind;
memset(cdbp, 0, cdb_sz);
+ if (ver_true) { /* only support VERIFY(10) */
+ if (cdb_sz < 10) {
+ pr2serr_lk("%s only support VERIFY(10)\n", my_name);
+ return 1;
+ }
+ cdb_sz = 10;
+ fua = false;
+ cdbp[1] |= 0x2; /* BYTCHK=1 --> sending dout for comparison */
+ cdbp[0] = ve_opcode[1];
+ }
if (dpo)
cdbp[1] |= 0x10;
if (fua)
@@ -1702,7 +1730,7 @@ sg_build_scsi_cdb(uint8_t * cdbp, int cdb_sz, unsigned int blocks,
case 6:
sz_ind = 0;
cdbp[0] = (uint8_t)(write_true ? wr_opcode[sz_ind] :
- rd_opcode[sz_ind]);
+ rd_opcode[sz_ind]);
sg_put_unaligned_be24(0x1fffff & start_block, cdbp + 1);
cdbp[4] = (256 == blocks) ? 0 : (uint8_t)blocks;
if (blocks > 256) {
@@ -1722,9 +1750,11 @@ sg_build_scsi_cdb(uint8_t * cdbp, int cdb_sz, unsigned int blocks,
}
break;
case 10:
- sz_ind = 1;
- cdbp[0] = (uint8_t)(write_true ? wr_opcode[sz_ind] :
- rd_opcode[sz_ind]);
+ if (! ver_true) {
+ sz_ind = 1;
+ cdbp[0] = (uint8_t)(write_true ? wr_opcode[sz_ind] :
+ rd_opcode[sz_ind]);
+ }
sg_put_unaligned_be32((uint32_t)start_block, cdbp + 2);
sg_put_unaligned_be16((uint16_t)blocks, cdbp + 7);
if (blocks & (~0xffff)) {
@@ -1736,14 +1766,14 @@ sg_build_scsi_cdb(uint8_t * cdbp, int cdb_sz, unsigned int blocks,
case 12:
sz_ind = 2;
cdbp[0] = (uint8_t)(write_true ? wr_opcode[sz_ind] :
- rd_opcode[sz_ind]);
+ rd_opcode[sz_ind]);
sg_put_unaligned_be32((uint32_t)start_block, cdbp + 2);
sg_put_unaligned_be32((uint32_t)blocks, cdbp + 6);
break;
case 16:
sz_ind = 3;
cdbp[0] = (uint8_t)(write_true ? wr_opcode[sz_ind] :
- rd_opcode[sz_ind]);
+ rd_opcode[sz_ind]);
sg_put_unaligned_be64((uint64_t)start_block, cdbp + 2);
sg_put_unaligned_be32((uint32_t)blocks, cdbp + 10);
break;
@@ -1919,7 +1949,8 @@ sg_out_wr_cmd(Rq_elem * rep, mrq_arr_t & def_arr, bool is_wr2)
break; /* loops around */
case SG_LIB_CAT_MEDIUM_HARD:
if (0 == clp->out_flags.coe) {
- pr2serr_lk("error finishing sg out command (medium)\n");
+ pr2serr_lk("error finishing sg %s command (medium)\n",
+ (clp->verify ? "verify" : "out"));
if (exit_status <= 0)
exit_status = res;
stop_both(clp);
@@ -1947,7 +1978,8 @@ sg_out_wr_cmd(Rq_elem * rep, mrq_arr_t & def_arr, bool is_wr2)
}
goto fini;
default:
- pr2serr_lk("error finishing sg out command (%d)\n", res);
+ pr2serr_lk("error finishing sg %s command (%d)\n",
+ (clp->verify ? "verify" : "out"), res);
if (exit_status <= 0)
exit_status = res;
stop_both(clp);
@@ -2082,16 +2114,16 @@ sgh_do_async_mrq(Rq_elem * rep, mrq_arr_t & def_arr, int fd,
ctlop->flags = SGV4_FLAG_MULTIPLE_REQS;
if (clp->in_flags.no_waitq || clp->out_flags.no_waitq) {
ctlop->flags |= SGV4_FLAG_NO_WAITQ; /* waitless non-blocking */
- if (!after1 && (clp->debug > 1)) {
- after1 = true;
- pr2serr_lk("%s: %s\n", __func__, mrq_nw_nb_s);
- }
+ if (!after1 && (clp->debug > 1)) {
+ after1 = true;
+ pr2serr_lk("%s: %s\n", __func__, mrq_nw_nb_s);
+ }
} else {
ctlop->flags |= SGV4_FLAG_IMMED; /* submit non-blocking */
- if (!after1 && (clp->debug > 1)) {
- after1 = true;
- pr2serr_lk("%s: %s\n", __func__, mrq_s_nb_s);
- }
+ if (!after1 && (clp->debug > 1)) {
+ after1 = true;
+ pr2serr_lk("%s: %s\n", __func__, mrq_s_nb_s);
+ }
}
if (clp->debug > 4) {
pr2serr_lk("%s: Controlling object _before_ ioctl(SG_IOSUBMIT):\n",
@@ -2462,34 +2494,34 @@ sgh_do_deferred_mrq(Rq_elem * rep, mrq_arr_t & def_arr)
}
if (clp->unbalanced_mrq) {
- if (!after1 && (clp->debug > 1)) {
- after1 = true;
- pr2serr_lk("%s: unbalanced %s\n", __func__, mrq_vb_s);
- }
+ if (!after1 && (clp->debug > 1)) {
+ after1 = true;
+ pr2serr_lk("%s: unbalanced %s\n", __func__, mrq_vb_s);
+ }
res = ioctl(fd, SG_IOSUBMIT, &ctl_v4);
} else {
if (clp->mrq_async) {
iosub_str = "SUBMIT(variable_blocking)";
- if (!after1 && (clp->debug > 1)) {
- after1 = true;
- pr2serr_lk("%s: %s\n", __func__, mrq_vb_s);
- }
+ if (!after1 && (clp->debug > 1)) {
+ after1 = true;
+ pr2serr_lk("%s: %s\n", __func__, mrq_vb_s);
+ }
res = ioctl(fd, SG_IOSUBMIT, &ctl_v4);
} else if (clp->in_flags.mrq_svb || clp->in_flags.mrq_svb) {
ctl_v4.flags |= SGV4_FLAG_SHARE;
iosub_str = "SUBMIT(shared_variable_blocking)";
- if (!after1 && (clp->debug > 1)) {
- after1 = true;
- pr2serr_lk("%s: %s\n", __func__, mrq_svb_s);
- }
+ if (!after1 && (clp->debug > 1)) {
+ after1 = true;
+ pr2serr_lk("%s: %s\n", __func__, mrq_svb_s);
+ }
// v4hdr_out_lk("cop: shared_variable_blocking", &ctl_v4, id);
res = ioctl(fd, SG_IOSUBMIT, &ctl_v4);
} else {
iosub_str = "SG_IO(ordered_blocking)";
- if (!after1 && (clp->debug > 1)) {
- after1 = true;
- pr2serr_lk("%s: %s\n", __func__, mrq_blk_s);
- }
+ if (!after1 && (clp->debug > 1)) {
+ after1 = true;
+ pr2serr_lk("%s: %s\n", __func__, mrq_blk_s);
+ }
res = ioctl(fd, SG_IO, &ctl_v4);
}
}
@@ -2592,8 +2624,8 @@ sg_start_io(Rq_elem * rep, mrq_arr_t & def_arr, int & pack_id,
}
if (qhead)
qtail = false; /* qhead takes precedence */
- if (sg_build_scsi_cdb(rep->cmd, cdbsz, rep->num_blks, blk, wr, fua,
- dpo)) {
+ if (sg_build_scsi_cdb(rep->cmd, cdbsz, rep->num_blks, blk,
+ wr ? clp->verify : false, wr, fua, dpo)) {
pr2serr_lk("%sbad cdb build, start_blk=%" PRId64 ", blocks=%d\n",
my_name, blk, rep->num_blks);
return -1;
@@ -2629,10 +2661,20 @@ sg_start_io(Rq_elem * rep, mrq_arr_t & def_arr, int & pack_id,
pack_id = atomic_fetch_add(&mono_pack_id, 1); /* fetch before */
rep->rq_id = pack_id;
if (clp->debug > 3) {
- pr2serr_lk("%s tid,rq_id=%d,%d: SCSI %s%s %s, blk=%" PRId64
- " num_blks=%d\n", __func__, rep->id, pack_id, crwp, cp,
- sg_flags_str(flags, b_len, b), blk, rep->num_blks);
- lk_print_command(rep->cmd);
+ bool lock = true;
+ char prefix[128];
+
+ if (4 == clp->debug) {
+ snprintf(prefix, sizeof(prefix), "tid,rq_id=%d,%d: ", rep->id,
+ pack_id);
+ lock = false;
+ } else {
+ prefix[0] = '\0';
+ pr2serr_lk("%s tid,rq_id=%d,%d: SCSI %s%s %s, blk=%" PRId64
+ " num_blks=%d\n", __func__, rep->id, pack_id, crwp, cp,
+ sg_flags_str(flags, b_len, b), blk, rep->num_blks);
+ }
+ lk_print_command_len(prefix, rep->cmd, cdbsz, lock);
}
if (v4)
goto do_v4;
@@ -2804,6 +2846,8 @@ sg_finish_io(bool wr, Rq_elem * rep, int pack_id, bool is_wr2)
if (wr) {
fd = is_wr2 ? rep->out2fd : rep->outfd;
cp = is_wr2 ? "writing2" : "writing";
+ if (clp->verify)
+ cp = is_wr2 ? "verifying2" : "verifying";
} else {
fd = rep->infd;
cp = "reading";
@@ -2949,7 +2993,7 @@ do_v4:
else
rep->dio_incomplete_count = 0;
rep->resid = h4p->din_resid;
- if (clp->debug > 3) {
+ if (clp->debug > 4) {
pr2serr_lk("%s: tid,rq_id=%d,%d: completed %s\n", __func__, rep->id,
pack_id, cp);
if ((clp->debug > 4) && h4p->info)
@@ -3107,7 +3151,7 @@ write_complet:
if (0 != status) err_exit(status, "unlock out_mutex");
#ifdef SGH_DD_READ_COMPLET_AFTER
- goto read_complet;
+ goto read_complet;
#endif
return;
default:
@@ -3385,8 +3429,8 @@ sg_out_open(Gbl_coll *clp, const char *outf, uint8_t **mmpp, int * mmap_lenp)
if ((fd = open(outf, flags)) < 0) {
err = errno;
- snprintf(ebuff, EBUFF_SZ, "%s: could not open %s for sg writing",
- __func__, outf);
+ snprintf(ebuff, EBUFF_SZ, "%s: could not open %s for sg %s",
+ __func__, outf, (clp->verify ? "verifying" : "writing"));
perror(ebuff);
return -sg_convert_errno(err);
}
@@ -3410,6 +3454,7 @@ parse_cmdline_sanity(int argc, char * argv[], Gbl_coll * clp, char * inf,
{
bool verbose_given = false;
bool version_given = false;
+ bool verify_given = false;
bool bpt_given = false;
int ibs = 0;
int obs = 0;
@@ -3609,6 +3654,10 @@ parse_cmdline_sanity(int argc, char * argv[], Gbl_coll * clp, char * inf,
if (n > 0)
version_given = true;
res += n;
+ n = num_chs_in_str(key + 1, keylen - 1, 'x');
+ if (n > 0)
+ verify_given = true;
+ res += n;
if (res < (keylen - 1)) {
pr2serr("Unrecognised short option in '%s', try '--help'\n",
@@ -3624,7 +3673,9 @@ parse_cmdline_sanity(int argc, char * argv[], Gbl_coll * clp, char * inf,
else if (0 == strncmp(key, "--verb", 6)) {
verbose_given = true;
++clp->debug; /* --verbose */
- } else if (0 == strncmp(key, "--vers", 6))
+ } else if (0 == strncmp(key, "--veri", 6))
+ verify_given = true;
+ else if (0 == strncmp(key, "--vers", 6))
version_given = true;
else {
pr2serr("Unrecognized option '%s'\n", key);
@@ -3662,6 +3713,10 @@ parse_cmdline_sanity(int argc, char * argv[], Gbl_coll * clp, char * inf,
pr2serr("Assume default 'bs' ((logical) block size) of %d bytes\n",
clp->bs);
}
+ if (verify_given) {
+ pr2serr("Doing verify/cmp rather than copy\n");
+ clp->verify = true;
+ }
if ((ibs && (ibs != clp->bs)) || (obs && (obs != clp->bs))) {
pr2serr("If 'ibs' or 'obs' given must be same as 'bs'\n");
usage(0);
@@ -3671,9 +3726,15 @@ parse_cmdline_sanity(int argc, char * argv[], Gbl_coll * clp, char * inf,
pr2serr("skip and seek cannot be negative\n");
return SG_LIB_SYNTAX_ERROR;
}
- if (clp->out_flags.append && (clp->seek > 0)) {
- pr2serr("Can't use both append and seek switches\n");
- return SG_LIB_SYNTAX_ERROR;
+ if (clp->out_flags.append) {
+ if (clp->seek > 0) {
+ pr2serr("Can't use both append and seek switches\n");
+ return SG_LIB_SYNTAX_ERROR;
+ }
+ if (verify_given) {
+ pr2serr("Can't use both append and verify switches\n");
+ return SG_LIB_SYNTAX_ERROR;
+ }
}
if (clp->bpt < 1) {
pr2serr("bpt must be greater than 0\n");
@@ -3719,6 +3780,7 @@ parse_cmdline_sanity(int argc, char * argv[], Gbl_coll * clp, char * inf,
clp->out_flags.swait = true;
}
clp->unit_nanosec = (do_time > 1) || !!getenv("SG3_UTILS_LINUX_NANO");
+#if 0
if (clp->debug) {
pr2serr("%sif=%s skip=%" PRId64 " of=%s seek=%" PRId64 " count=%"
PRId64, my_name, inf, clp->skip, outf, clp->seek, dd_count);
@@ -3727,6 +3789,7 @@ parse_cmdline_sanity(int argc, char * argv[], Gbl_coll * clp, char * inf,
else
pr2serr("\n");
}
+#endif
return 0;
}
@@ -3847,6 +3910,10 @@ main(int argc, char * argv[])
if (outf[0] && ('-' != outf[0])) {
clp->out_type = dd_filetype(outf);
+ if ((FT_SG != clp->out_type) && clp->verify) {
+ pr2serr("%s --verify only supported by sg OFILEs\n", my_name);
+ return SG_LIB_FILE_ERROR;
+ }
if (FT_ST == clp->out_type) {
pr2serr("%sunable to use scsi tape device %s\n", my_name, outf);
return SG_LIB_FILE_ERROR;
@@ -4311,5 +4378,7 @@ fini:
pr2serr("Number of SG_GET_NUM_WAITING calls=%ld\n",
num_waiting_calls.load());
}
+ if (clp->verify && (SG_LIB_CAT_MISCOMPARE == res))
+ pr2serr("Verify/compare failed due to miscompare\n");
return (res >= 0) ? res : SG_LIB_CAT_OTHER;
}