aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDouglas Gilbert <dgilbert@interlog.com>2021-11-20 17:13:42 +0000
committerDouglas Gilbert <dgilbert@interlog.com>2021-11-20 17:13:42 +0000
commit20315aa4fae1340e5d4b1faae15b90ee34b9ea50 (patch)
treeeb935ed0b6aed4abf787556adcfe9e3cb99c297d /src
parent26be8550ae1aad5db9bcf9b0cfe1fdecccd210df (diff)
downloadsg3_utils-20315aa4fae1340e5d4b1faae15b90ee34b9ea50.tar.gz
sg_z_act_query: new utility for sending either a Zone activate or Zone query command; sg_rep_zones: add Report zone starting LBA granularity field in REPORT ZONES response [zbc2r12]; sg_decode_sense: add --nodecode option; initialize all sense buffers to 0; rework main README file
git-svn-id: https://svn.bingwo.ca/repos/sg3_utils/trunk@923 6180dd3e-e324-4e3e-922d-17de1ae2f315
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am4
-rw-r--r--src/Makefile.in25
-rw-r--r--src/sg_bg_ctl.c4
-rw-r--r--src/sg_compare_and_write.c4
-rw-r--r--src/sg_dd.c8
-rw-r--r--src/sg_decode_sense.c111
-rw-r--r--src/sg_format.c8
-rw-r--r--src/sg_get_elem_status.c4
-rw-r--r--src/sg_map26.c6
-rw-r--r--src/sg_opcodes.c6
-rw-r--r--src/sg_read.c6
-rw-r--r--src/sg_read_attr.c4
-rw-r--r--src/sg_read_buffer.c6
-rw-r--r--src/sg_rep_pip.c4
-rw-r--r--src/sg_rep_zones.c33
-rw-r--r--src/sg_requests.c4
-rw-r--r--src/sg_reset_wp.c4
-rw-r--r--src/sg_sanitize.c4
-rw-r--r--src/sg_stream_ctl.c6
-rw-r--r--src/sg_sync.c4
-rw-r--r--src/sg_timestamp.c4
-rw-r--r--src/sg_vpd.c4
-rw-r--r--src/sg_write_same.c7
-rw-r--r--src/sg_write_verify.c4
-rw-r--r--src/sg_write_x.c4
-rw-r--r--src/sg_xcopy.c2
-rw-r--r--src/sg_z_act_query.c642
-rw-r--r--src/sg_zone.c4
-rw-r--r--src/sginfo.c10
-rw-r--r--src/sgm_dd.c8
-rw-r--r--src/sgp_dd.c2
31 files changed, 820 insertions, 126 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index 9007642f..cd9d8b9d 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -10,7 +10,7 @@ bin_PROGRAMS = \
sg_sat_set_features sg_seek sg_senddiag sg_ses sg_ses_microcode \
sg_start sg_stpg sg_stream_ctl sg_sync sg_timestamp sg_turs sg_unmap \
sg_verify sg_vpd sg_wr_mode sg_write_buffer sg_write_long \
- sg_write_same sg_write_verify sg_write_x sg_zone
+ sg_write_same sg_write_verify sg_write_x sg_zone sg_z_act_query
sg_scan_SOURCES =
@@ -203,3 +203,5 @@ sg_write_x_LDADD = ../lib/libsgutils2.la
sg_xcopy_LDADD = ../lib/libsgutils2.la
sg_zone_LDADD = ../lib/libsgutils2.la
+
+sg_z_act_query_LDADD = ../lib/libsgutils2.la
diff --git a/src/Makefile.in b/src/Makefile.in
index 5ae4625e..39648d8c 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -110,7 +110,8 @@ bin_PROGRAMS = sg_bg_ctl$(EXEEXT) sg_compare_and_write$(EXEEXT) \
sg_vpd$(EXEEXT) sg_wr_mode$(EXEEXT) sg_write_buffer$(EXEEXT) \
sg_write_long$(EXEEXT) sg_write_same$(EXEEXT) \
sg_write_verify$(EXEEXT) sg_write_x$(EXEEXT) sg_zone$(EXEEXT) \
- $(am__EXEEXT_1) $(am__EXEEXT_2) $(am__EXEEXT_3)
+ sg_z_act_query$(EXEEXT) $(am__EXEEXT_1) $(am__EXEEXT_2) \
+ $(am__EXEEXT_3)
@OS_LINUX_TRUE@@PT_DUMMY_FALSE@am__append_1 = \
@OS_LINUX_TRUE@@PT_DUMMY_FALSE@ sg_copy_results sg_dd sg_emc_trespass sg_map sg_map26 sg_rbuf \
@OS_LINUX_TRUE@@PT_DUMMY_FALSE@ sg_read sg_reset sg_scan sg_test_rwbuf sg_xcopy sginfo sgm_dd sgp_dd
@@ -356,6 +357,9 @@ sg_write_x_DEPENDENCIES = ../lib/libsgutils2.la
sg_xcopy_SOURCES = sg_xcopy.c
sg_xcopy_OBJECTS = sg_xcopy.$(OBJEXT)
sg_xcopy_DEPENDENCIES = ../lib/libsgutils2.la
+sg_z_act_query_SOURCES = sg_z_act_query.c
+sg_z_act_query_OBJECTS = sg_z_act_query.$(OBJEXT)
+sg_z_act_query_DEPENDENCIES = ../lib/libsgutils2.la
sg_zone_SOURCES = sg_zone.c
sg_zone_OBJECTS = sg_zone.$(OBJEXT)
sg_zone_DEPENDENCIES = ../lib/libsgutils2.la
@@ -421,8 +425,9 @@ am__depfiles_remade = ./$(DEPDIR)/sg_bg_ctl.Po \
./$(DEPDIR)/sg_write_buffer.Po ./$(DEPDIR)/sg_write_long.Po \
./$(DEPDIR)/sg_write_same.Po ./$(DEPDIR)/sg_write_verify.Po \
./$(DEPDIR)/sg_write_x.Po ./$(DEPDIR)/sg_xcopy.Po \
- ./$(DEPDIR)/sg_zone.Po ./$(DEPDIR)/sginfo.Po \
- ./$(DEPDIR)/sgm_dd.Po ./$(DEPDIR)/sgp_dd.Po
+ ./$(DEPDIR)/sg_z_act_query.Po ./$(DEPDIR)/sg_zone.Po \
+ ./$(DEPDIR)/sginfo.Po ./$(DEPDIR)/sgm_dd.Po \
+ ./$(DEPDIR)/sgp_dd.Po
am__mv = mv -f
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
@@ -458,7 +463,8 @@ SOURCES = sg_bg_ctl.c sg_compare_and_write.c sg_copy_results.c sg_dd.c \
sg_sync.c sg_test_rwbuf.c sg_timestamp.c sg_turs.c sg_unmap.c \
sg_verify.c $(sg_vpd_SOURCES) sg_wr_mode.c sg_write_buffer.c \
sg_write_long.c sg_write_same.c sg_write_verify.c sg_write_x.c \
- sg_xcopy.c sg_zone.c sginfo.c sgm_dd.c sgp_dd.c
+ sg_xcopy.c sg_z_act_query.c sg_zone.c sginfo.c sgm_dd.c \
+ sgp_dd.c
DIST_SOURCES = sg_bg_ctl.c sg_compare_and_write.c sg_copy_results.c \
sg_dd.c sg_decode_sense.c sg_emc_trespass.c sg_format.c \
sg_get_config.c sg_get_elem_status.c sg_get_lba_status.c \
@@ -475,7 +481,8 @@ DIST_SOURCES = sg_bg_ctl.c sg_compare_and_write.c sg_copy_results.c \
sg_sync.c sg_test_rwbuf.c sg_timestamp.c sg_turs.c sg_unmap.c \
sg_verify.c $(sg_vpd_SOURCES) sg_wr_mode.c sg_write_buffer.c \
sg_write_long.c sg_write_same.c sg_write_verify.c sg_write_x.c \
- sg_xcopy.c sg_zone.c sginfo.c sgm_dd.c sgp_dd.c
+ sg_xcopy.c sg_z_act_query.c sg_zone.c sginfo.c sgm_dd.c \
+ sgp_dd.c
am__can_run_installinfo = \
case $$AM_UPDATE_INFO_DIR in \
n|no|NO) false;; \
@@ -719,6 +726,7 @@ sg_write_verify_LDADD = ../lib/libsgutils2.la
sg_write_x_LDADD = ../lib/libsgutils2.la
sg_xcopy_LDADD = ../lib/libsgutils2.la
sg_zone_LDADD = ../lib/libsgutils2.la
+sg_z_act_query_LDADD = ../lib/libsgutils2.la
all: all-am
.SUFFIXES:
@@ -1066,6 +1074,10 @@ sg_xcopy$(EXEEXT): $(sg_xcopy_OBJECTS) $(sg_xcopy_DEPENDENCIES) $(EXTRA_sg_xcopy
@rm -f sg_xcopy$(EXEEXT)
$(AM_V_CCLD)$(LINK) $(sg_xcopy_OBJECTS) $(sg_xcopy_LDADD) $(LIBS)
+sg_z_act_query$(EXEEXT): $(sg_z_act_query_OBJECTS) $(sg_z_act_query_DEPENDENCIES) $(EXTRA_sg_z_act_query_DEPENDENCIES)
+ @rm -f sg_z_act_query$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(sg_z_act_query_OBJECTS) $(sg_z_act_query_LDADD) $(LIBS)
+
sg_zone$(EXEEXT): $(sg_zone_OBJECTS) $(sg_zone_DEPENDENCIES) $(EXTRA_sg_zone_DEPENDENCIES)
@rm -f sg_zone$(EXEEXT)
$(AM_V_CCLD)$(LINK) $(sg_zone_OBJECTS) $(sg_zone_LDADD) $(LIBS)
@@ -1157,6 +1169,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sg_write_verify.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sg_write_x.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sg_xcopy.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sg_z_act_query.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sg_zone.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sginfo.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sgm_dd.Po@am__quote@ # am--include-marker
@@ -1390,6 +1403,7 @@ distclean: distclean-am
-rm -f ./$(DEPDIR)/sg_write_verify.Po
-rm -f ./$(DEPDIR)/sg_write_x.Po
-rm -f ./$(DEPDIR)/sg_xcopy.Po
+ -rm -f ./$(DEPDIR)/sg_z_act_query.Po
-rm -f ./$(DEPDIR)/sg_zone.Po
-rm -f ./$(DEPDIR)/sginfo.Po
-rm -f ./$(DEPDIR)/sgm_dd.Po
@@ -1508,6 +1522,7 @@ maintainer-clean: maintainer-clean-am
-rm -f ./$(DEPDIR)/sg_write_verify.Po
-rm -f ./$(DEPDIR)/sg_write_x.Po
-rm -f ./$(DEPDIR)/sg_xcopy.Po
+ -rm -f ./$(DEPDIR)/sg_z_act_query.Po
-rm -f ./$(DEPDIR)/sg_zone.Po
-rm -f ./$(DEPDIR)/sginfo.Po
-rm -f ./$(DEPDIR)/sgm_dd.Po
diff --git a/src/sg_bg_ctl.c b/src/sg_bg_ctl.c
index a1ca3f23..0e61d38e 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.12 20210830";
+static const char * version_str = "1.13 20211114";
#define BACKGROUND_CONTROL_SA 0x15
@@ -93,7 +93,7 @@ sg_ll_background_control(int sg_fd, unsigned int bo_ctl, unsigned int bo_time,
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};
- uint8_t sense_b[SENSE_BUFF_LEN];
+ uint8_t sense_b[SENSE_BUFF_LEN] = {0};
struct sg_pt_base * ptvp;
if (bo_ctl)
diff --git a/src/sg_compare_and_write.c b/src/sg_compare_and_write.c
index e3762021..0a307003 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.30 20210830";
+static const char * version_str = "1.31 20211114";
#define DEF_BLOCK_SIZE 512
#define DEF_NUM_BLOCKS (1)
@@ -355,7 +355,7 @@ sg_ll_compare_and_write(int sg_fd, uint8_t * buff, int blocks,
uint64_t ull = 0;
struct sg_pt_base * ptvp;
uint8_t cawCmd[COMPARE_AND_WRITE_CDB_SIZE];
- uint8_t sense_b[SENSE_BUFF_LEN];
+ uint8_t sense_b[SENSE_BUFF_LEN] = {0};
if (sg_build_scsi_cdb(cawCmd, blocks, lba, flags)) {
pr2serr(ME "bad cdb build, lba=0x%" PRIx64 ", blocks=%d\n",
diff --git a/src/sg_dd.c b/src/sg_dd.c
index 75430dda..2fa37500 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, 3, 4 and 5 series.
+ * This version is designed for the Linux kernel 2, 3, 4 and 5 series.
*/
#define _XOPEN_SOURCE 600
@@ -70,7 +70,7 @@
#include "sg_unaligned.h"
#include "sg_pr2serr.h"
-static const char * version_str = "6.31 20211115";
+static const char * version_str = "6.31 20211114";
#define ME "sg_dd: "
@@ -715,7 +715,7 @@ sg_read_low(int sg_fd, uint8_t * buff, int blocks, int64_t from_block,
int res, slen;
const uint8_t * sbp;
uint8_t rdCmd[MAX_SCSI_CDBSZ];
- uint8_t senseBuff[SENSE_BUFF_LEN];
+ uint8_t senseBuff[SENSE_BUFF_LEN] = {0};
struct sg_io_hdr io_hdr;
if (sg_build_scsi_cdb(rdCmd, ifp->cdbsz, blocks, from_block, do_verify,
@@ -1124,7 +1124,7 @@ sg_write(int sg_fd, uint8_t * buff, int blocks, int64_t to_block,
uint64_t io_addr = 0;
const char * op_str = do_verify ? "verifying" : "writing";
uint8_t wrCmd[MAX_SCSI_CDBSZ];
- uint8_t senseBuff[SENSE_BUFF_LEN];
+ uint8_t senseBuff[SENSE_BUFF_LEN] = {0};
struct sg_io_hdr io_hdr;
if (sg_build_scsi_cdb(wrCmd, ofp->cdbsz, blocks, to_block, do_verify,
diff --git a/src/sg_decode_sense.c b/src/sg_decode_sense.c
index a21ceb47..76e5f6f9 100644
--- a/src/sg_decode_sense.c
+++ b/src/sg_decode_sense.c
@@ -30,9 +30,9 @@
#include "sg_unaligned.h"
-static const char * version_str = "1.24 20211104";
+static const char * version_str = "1.25 20211119";
-#define MAX_SENSE_LEN 1024 /* max descriptor format actually: 255+8 */
+#define MAX_SENSE_LEN 4096 /* max descriptor format actually: 255+8 */
static struct option long_options[] = {
{"binary", required_argument, 0, 'b'},
@@ -45,6 +45,7 @@ static struct option long_options[] = {
{"hex", no_argument, 0, 'H'},
{"in", required_argument, 0, 'i'}, /* don't advertise */
{"inhex", required_argument, 0, 'i'}, /* same as --file */
+ {"nodecode", no_argument, 0, 'N'},
{"nospace", no_argument, 0, 'n'},
{"status", required_argument, 0, 's'},
{"verbose", no_argument, 0, 'v'},
@@ -57,7 +58,7 @@ struct opts_t {
bool do_binary;
bool do_cdb;
bool do_help;
- bool do_hex;
+ bool no_decode;
bool no_space;
bool do_status;
bool verbose_given;
@@ -66,6 +67,7 @@ struct opts_t {
bool file_given;
const char * fname;
int es_val;
+ int hex_count;
int sense_len;
int sstatus;
int verbose;
@@ -82,10 +84,11 @@ usage()
{
pr2serr("Usage: sg_decode_sense [--binary=BFN] [--cdb] [--err=ES] "
"[--file=HFN]\n"
- " [--help] [--hex] [--inhex=HFN] [--nospace] "
- "[--status=SS]\n"
- " [--verbose] [--version] [--write=WFN] H1 "
- "H2 H3 ...\n"
+ " [--help] [--hex] [--inhex=HFN] "
+ "[--nodecode]\n"
+ " [--nospace] [--status=SS] [--verbose] "
+ "[--version]\n"
+ " [--write=WFN] H1 H2 H3 ...\n"
" where:\n"
" --binary=BFN|-b BFN BFN is a file name to read sense "
"data in\n"
@@ -105,6 +108,8 @@ usage()
" C language style ASCII hex (instead "
"of binary)\n"
" --inhex=HFN|-i HFN same as action as --file=HFN\n"
+ " --nodecode|-N do not decode, may be neither sense "
+ "nor cdb\n"
" --nospace|-n no spaces or other separators between "
"pairs of\n"
" hex digits (e.g. '3132330A')\n"
@@ -133,7 +138,8 @@ parse_cmd_line(struct opts_t *op, int argc, char *argv[])
char *endptr;
while (1) {
- c = getopt_long(argc, argv, "b:ce:f:hHi:ns:vVw:", long_options, NULL);
+ c = getopt_long(argc, argv, "b:ce:f:hHi:nNs:vVw:", long_options,
+ NULL);
if (c == -1)
break;
@@ -182,11 +188,14 @@ parse_cmd_line(struct opts_t *op, int argc, char *argv[])
op->fname = optarg;
break;
case 'H':
- op->do_hex = true;
+ op->hex_count++;
break;
case 'n':
op->no_space = true;
break;
+ case 'N':
+ op->no_decode = true;
+ break;
case 's':
if (1 != sscanf(optarg, "%x", &ui)) {
pr2serr("'--status=SS' expects a byte value\n");
@@ -257,6 +266,7 @@ the_end:
return 0;
}
+/* Keep this format (e.g. 0xff,0x12,...) for backward compatibility */
static void
write2wfn(FILE * fp, struct opts_t * op)
{
@@ -264,30 +274,23 @@ write2wfn(FILE * fp, struct opts_t * op)
size_t s;
char b[128];
- if (op->do_hex) {
- for (k = 0, n = 0; k < op->sense_len; ++k) {
- n += sprintf(b + n, "0x%02x,", op->sense[k]);
- if (15 == (k % 16)) {
- b[n] = '\n';
- s = fwrite(b, 1, n + 1, fp);
- if ((int)s != (n + 1))
- pr2serr("only able to write %d of %d bytes to %s\n",
- (int)s, n + 1, op->wfname);
- n = 0;
- }
- }
- if (n > 0) {
+ for (k = 0, n = 0; k < op->sense_len; ++k) {
+ n += sprintf(b + n, "0x%02x,", op->sense[k]);
+ if (15 == (k % 16)) {
b[n] = '\n';
s = fwrite(b, 1, n + 1, fp);
if ((int)s != (n + 1))
- pr2serr("only able to write %d of %d bytes to %s\n", (int)s,
- n + 1, op->wfname);
+ pr2serr("only able to write %d of %d bytes to %s\n",
+ (int)s, n + 1, op->wfname);
+ n = 0;
}
- } else {
- s = fwrite(op->sense, 1, op->sense_len, fp);
- if ((int)s != op->sense_len)
+ }
+ if (n > 0) {
+ b[n] = '\n';
+ s = fwrite(b, 1, n + 1, fp);
+ if ((int)s != (n + 1))
pr2serr("only able to write %d of %d bytes to %s\n", (int)s,
- op->sense_len, op->wfname);
+ n + 1, op->wfname);
}
}
@@ -374,7 +377,8 @@ main(int argc, char *argv[])
if ((0 == op->sense_len) && (! op->do_binary) && (! op->file_given)) {
if (op->do_status)
return 0;
- pr2serr(">> Need sense data on the command line or in a file\n\n");
+ pr2serr(">> Need sense/cdb/arbitrary data on the command line or "
+ "in a file\n\n");
usage();
return SG_LIB_SYNTAX_ERROR;
}
@@ -413,19 +417,40 @@ main(int argc, char *argv[])
}
}
- if (op->sense_len) {
- if (op->wfname) {
- if ((fp = fopen(op->wfname, "w"))) {
+ if (op->sense_len > 0) {
+ if (op->wfname || op->hex_count) {
+ if (op->wfname) {
+ if (NULL == ((fp = fopen(op->wfname, "w")))) {
+ err =errno;
+ perror("open");
+ pr2serr("trying to write to %s\n", op->wfname);
+ ret = sg_convert_errno(err);
+ goto fini;
+ }
+ } else
+ fp = stdout;
+
+ if (op->wfname && (1 == op->hex_count))
write2wfn(fp, op);
- fclose(fp);
- } else {
- err =errno;
- perror("open");
- pr2serr("trying to write to %s\n", op->wfname);
- ret = sg_convert_errno(err);
+ else if (op->hex_count && (2 != op->hex_count))
+ dStrHexFp((const char *)op->sense, op->sense_len,
+ ((1 == op->hex_count) ? 1 : -1), fp);
+ else if (op->hex_count)
+ dStrHexFp((const char *)op->sense, op->sense_len, 0, fp);
+ else {
+ size_t s = fwrite(op->sense, 1, op->sense_len, fp);
+
+ if ((int)s != op->sense_len)
+ pr2serr("only able to write %d of %d bytes to %s\n",
+ (int)s, op->sense_len, op->wfname);
}
- }
- if (op->do_cdb) {
+ if (op->wfname)
+ fclose(fp);
+ } else if (op->no_decode) {
+ if (op->verbose > 1)
+ pr2serr("Not decoding as %s because --nodecode given\n",
+ (op->do_cdb ? "cdb" : "sense"));
+ } else if (op->do_cdb) {
int sa, opcode;
opcode = op->sense[0];
@@ -436,10 +461,12 @@ main(int argc, char *argv[])
else
sa = 0;
sg_get_opcode_sa_name(opcode, sa, 0, blen, b);
- } else
+ printf("%s\n", b);
+ } else {
sg_get_sense_str(NULL, op->sense, op->sense_len,
op->verbose, blen, b);
- printf("%s\n", b);
+ printf("%s\n", b);
+ }
}
fini:
return ret;
diff --git a/src/sg_format.c b/src/sg_format.c
index 0d9b3185..b6620ab2 100644
--- a/src/sg_format.c
+++ b/src/sg_format.c
@@ -6,7 +6,7 @@
*
* Copyright (C) 2003 Grant Grundler grundler at parisc-linux dot org
* Copyright (C) 2003 James Bottomley jejb at parisc-linux dot org
- * Copyright (C) 2005-2020 Douglas Gilbert dgilbert at interlog dot com
+ * Copyright (C) 2005-2021 Douglas Gilbert dgilbert at interlog dot com
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -40,7 +40,7 @@
#include "sg_pr2serr.h"
#include "sg_pt.h"
-static const char * version_str = "1.63 20210830";
+static const char * version_str = "1.64 20211114";
#define RW_ERROR_RECOVERY_PAGE 1 /* can give alternate with --mode=MP */
@@ -278,7 +278,7 @@ sg_ll_format_medium(int sg_fd, bool verify, bool immed, int format,
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];
+ uint8_t sense_b[SENSE_BUFF_LEN] = {0};
struct sg_pt_base * ptvp;
if (verify)
@@ -343,7 +343,7 @@ sg_ll_format_with_preset(int sg_fd, bool immed, bool fmtmaxlba,
int ret, res, sense_cat;
uint8_t fwp_cdb[SG_FORMAT_WITH_PRESET_CMDLEN] =
{SG_FORMAT_WITH_PRESET_CMD, 0, 0, 0, 0, 0, 0, 0, 0, 0};
- uint8_t sense_b[SENSE_BUFF_LEN];
+ uint8_t sense_b[SENSE_BUFF_LEN] = {0};
struct sg_pt_base * ptvp;
if (immed)
diff --git a/src/sg_get_elem_status.c b/src/sg_get_elem_status.c
index c60d984e..ea5b7d0c 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.07 20211104"; /* sbc5r01 */
+static const char * version_str = "1.08 20211114"; /* sbc5r01 */
#ifndef UINT32_MAX
@@ -144,7 +144,7 @@ sg_ll_get_phy_elem_status(int sg_fd, uint32_t starting_elem, uint8_t filter,
uint8_t gpesCmd[16] = {SG_SERVICE_ACTION_IN_16,
GET_PHY_ELEM_STATUS_SA, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
- uint8_t sense_b[SENSE_BUFF_LEN];
+ uint8_t sense_b[SENSE_BUFF_LEN] = {0};
struct sg_pt_base * ptvp;
static const char * const cmd_name = "Get physical element status";
diff --git a/src/sg_map26.c b/src/sg_map26.c
index ddee5c47..3fca0190 100644
--- a/src/sg_map26.c
+++ b/src/sg_map26.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005-2020 Douglas Gilbert.
+ * Copyright (c) 2005-2021 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.
@@ -11,7 +11,7 @@
*
*
* This program maps a primary SCSI device node name to the corresponding
- * SCSI generic device node name (or vice versa). Targets linux
+ * SCSI generic device node name (or vice versa). Targets Linux
* kernel 2.6, 3 and 4 series. Sysfs device names can also be mapped.
*/
@@ -47,7 +47,7 @@
#endif
#include "sg_lib.h"
-static const char * version_str = "1.17 20200501";
+static const char * version_str = "1.18 20211118";
#define ME "sg_map26: "
diff --git a/src/sg_opcodes.c b/src/sg_opcodes.c
index ffa7823c..9d908248 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.71 20210830"; /* spc6r05 */
+static const char * version_str = "0.72 20211114"; /* spc6r05 */
#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 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];
+ uint8_t sense_b[SENSE_BUFF_LEN] = {0};
if (rctd)
rsoc_cdb[2] |= 0x80;
@@ -259,7 +259,7 @@ do_rstmf(struct sg_pt_base * ptvp, bool repd, void * resp, int mx_resp_len,
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];
+ uint8_t sense_b[SENSE_BUFF_LEN] = {0};
if (repd)
rstmf_cdb[2] = 0x80;
diff --git a/src/sg_read.c b/src/sg_read.c
index cd10c2ea..628e0d88 100644
--- a/src/sg_read.c
+++ b/src/sg_read.c
@@ -1,6 +1,6 @@
/*
* A utility program for the Linux OS SCSI generic ("sg") device driver.
- * Copyright (C) 2001 - 2019 D. Gilbert
+ * Copyright (C) 2001 - 2021 D. Gilbert
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
@@ -58,7 +58,7 @@
#include "sg_pr2serr.h"
-static const char * version_str = "1.36 20191220";
+static const char * version_str = "1.37 20211114";
#define DEF_BLOCK_SIZE 512
#define DEF_BLOCKS_PER_TRANSFER 128
@@ -296,7 +296,7 @@ sg_bread(int sg_fd, uint8_t * buff, int blocks, int64_t from_block, int bs,
bool no_dxfer)
{
uint8_t rdCmd[MAX_SCSI_CDBSZ];
- uint8_t senseBuff[SENSE_BUFF_LEN];
+ uint8_t senseBuff[SENSE_BUFF_LEN] = {0};
struct sg_io_hdr io_hdr;
if (sg_build_scsi_cdb(rdCmd, cdbsz, blocks, from_block, false, fua,
diff --git a/src/sg_read_attr.c b/src/sg_read_attr.c
index 87124d3c..b0bcedb0 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.15 20210830";
+static const char * version_str = "1.16 20211114";
#define MAX_RATTR_BUFF_LEN (1024 * 1024)
#define DEF_RATTR_BUFF_LEN (1024 * 8)
@@ -249,7 +249,7 @@ sg_ll_read_attr(int sg_fd, void * resp, int * residp, bool noisy,
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};
- uint8_t sense_b[SENSE_BUFF_LEN];
+ uint8_t sense_b[SENSE_BUFF_LEN] = {0};
struct sg_pt_base * ptvp;
ra_cdb[1] = 0x1f & op->sa;
diff --git a/src/sg_read_buffer.c b/src/sg_read_buffer.c
index e3dae423..93c32a58 100644
--- a/src/sg_read_buffer.c
+++ b/src/sg_read_buffer.c
@@ -39,7 +39,7 @@
* device.
*/
-static const char * version_str = "1.32 20210830"; /* spc6r05 */
+static const char * version_str = "1.33 20211114"; /* spc6r05 */
#ifndef SG_READ_BUFFER_10_CMD
@@ -166,7 +166,7 @@ sg_ll_read_buffer_10(int sg_fd, int rb_mode, int rb_mode_sp, int rb_id,
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];
+ uint8_t sense_b[SENSE_BUFF_LEN] = {0};
struct sg_pt_base * ptvp;
rb10_cb[1] = (uint8_t)(rb_mode & 0x1f);
@@ -234,7 +234,7 @@ sg_ll_read_buffer_16(int sg_fd, int rb_mode, int rb_mode_sp, int rb_id,
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};
- uint8_t sense_b[SENSE_BUFF_LEN];
+ uint8_t sense_b[SENSE_BUFF_LEN] = {0};
struct sg_pt_base * ptvp;
rb16_cb[1] = (uint8_t)(rb_mode & 0x1f);
diff --git a/src/sg_rep_pip.c b/src/sg_rep_pip.c
index f800d81a..2f6127e1 100644
--- a/src/sg_rep_pip.c
+++ b/src/sg_rep_pip.c
@@ -39,7 +39,7 @@
* sbc4r21.pdf
*/
-static const char * version_str = "1.02 20210830";
+static const char * version_str = "1.03 20211114";
#define MAX_RPIP_BUFF_LEN (1024 * 1024)
#define DEF_RPIP_BUFF_LEN 512
@@ -102,7 +102,7 @@ sg_ll_report_pip(int sg_fd, void * resp, int mx_resp_len, int * residp,
uint8_t rz_cdb[SG_MAINT_IN_CMDLEN] =
{SG_MAINTENANCE_IN, REPORT_PROVISIONING_INITIALIZATION_PATTERN_SA,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
- uint8_t sense_b[SENSE_BUFF_LEN];
+ uint8_t sense_b[SENSE_BUFF_LEN] = {0};
struct sg_pt_base * ptvp;
sg_put_unaligned_be32((uint32_t)mx_resp_len, rz_cdb + 6);
diff --git a/src/sg_rep_zones.c b/src/sg_rep_zones.c
index 7453ee22..2e719e75 100644
--- a/src/sg_rep_zones.c
+++ b/src/sg_rep_zones.c
@@ -39,7 +39,7 @@
* Based on zbc2r10.pdf
*/
-static const char * version_str = "1.28 20210922";
+static const char * version_str = "1.29 20211117";
#define MAX_RZONES_BUFF_LEN (1024 * 1024)
#define DEF_RZONES_BUFF_LEN (1024 * 8)
@@ -105,7 +105,8 @@ usage(int h)
{
if (h > 1) goto h_twoormore;
pr2serr("Usage: "
- "sg_rep_zones [--domain] [--help] [--hex] [--inhex=FN]\n"
+ "sg_rep_zones [--domain] [--force] [--help] [--hex] "
+ "[--inhex=FN]\n"
" [--locator=LBA] [--maxlen=LEN] "
"[--partial] [--raw]\n"
" [--readonly] [--realm] [--report=OPT] "
@@ -113,6 +114,8 @@ usage(int h)
" [--verbose] [--version] DEVICE\n");
pr2serr(" where:\n"
" --domain|-d sends a REPORT ZONE DOMAINS command\n"
+ " --force|-f bypass some sanity checks when decoding "
+ "response\n"
" --help|-h print out usage message, use twice for "
"more help\n"
" --hex|-H output response in hexadecimal; used "
@@ -140,7 +143,7 @@ usage(int h)
" --version|-V print version string and exit\n"
" --wp|-w output write pointer only\n\n"
"Sends a SCSI REPORT ZONES, REPORT ZONE DOMAINS or REPORT REALMS "
- "command.\n By default sends a REPORT ZONES command. Give help "
+ "command.\nBy default sends a REPORT ZONES command. Give help "
"option twice\n(e.g. '-hh') to see reporting options "
"enumerated.\n");
return;
@@ -191,7 +194,7 @@ sg_ll_report_zzz(int sg_fd, int serv_act, uint64_t zs_lba, bool partial,
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};
- uint8_t sense_b[SENSE_BUFF_LEN];
+ uint8_t sense_b[SENSE_BUFF_LEN] = {0};
struct sg_pt_base * ptvp;
rz_cdb[1] = serv_act;
@@ -313,13 +316,13 @@ decode_rep_zones(const uint8_t * rzBuff, int act_len, uint32_t decod_len,
const struct opts_t * op)
{
uint8_t zt;
- int k, same, zc, zones;
+ int k, same, zc, num_zd;
uint64_t wp;
const uint8_t * bp;
char b[80];
if ((uint32_t)act_len < decod_len) {
- zones = (act_len - 64) / 64;
+ num_zd = (act_len >= 64) ? ((act_len - 64) / 64): 0;
if (act_len == op->maxlen) {
if (op->maxlen_given)
pr2serr("decode length [%u bytes] may be constrained by "
@@ -329,21 +332,23 @@ decode_rep_zones(const uint8_t * rzBuff, int act_len, uint32_t decod_len,
} else if (op->in_fn)
pr2serr("perhaps %s has been truncated\n", op->in_fn);
} else
- zones = (decod_len - 64) / 64;
+ num_zd = (decod_len - 64) / 64;
same = rzBuff[4] & 0xf;
if (! op->wp_only) {
printf(" Same=%d: %s\n", same, same_desc_arr[same]);
printf(" Maximum LBA: 0x%" PRIx64 "\n\n",
sg_get_unaligned_be64(rzBuff + 8));
+ printf(" Reported zone starting LBA granularity: 0x%" PRIx64 "\n\n",
+ sg_get_unaligned_be64(rzBuff + 16)); /* zbc2r12 */
}
if (op->do_num > 0)
- zones = (zones > op->do_num) ? op->do_num : zones;
- if (((uint32_t)act_len < decod_len) && ((zones * 64) + 64 > act_len)) {
+ num_zd = (num_zd > op->do_num) ? op->do_num : num_zd;
+ if (((uint32_t)act_len < decod_len) && ((num_zd * 64) + 64 > act_len)) {
pr2serr("Skip due to truncated response, try using --num= to a "
- "value less than %d\n", zones);
+ "value less than %d\n", num_zd);
return SG_LIB_CAT_MALFORMED;
}
- for (k = 0, bp = rzBuff + 64; k < zones; ++k, bp += 64) {
+ for (k = 0, bp = rzBuff + 64; k < num_zd; ++k, bp += 64) {
if (! op->wp_only)
printf(" Zone descriptor: %d\n", k);
if (op->do_hex) {
@@ -374,7 +379,7 @@ decode_rep_zones(const uint8_t * rzBuff, int act_len, uint32_t decod_len,
printf(" Write pointer LBA: 0x%" PRIx64 "\n", wp);
}
if ((op->do_num == 0) && (! op->wp_only)) {
- if ((64 + (64 * (uint32_t)zones)) < decod_len)
+ if ((64 + (64 * (uint32_t)num_zd)) < decod_len)
printf("\n>>> Beware: Zone list truncated, may need another "
"call\n");
}
@@ -589,6 +594,10 @@ main(int argc, char * argv[])
break;
case 's':
case 'l': /* --locator= and --start= are interchangeable */
+ if ((2 == strlen(optarg)) && (0 == memcmp("-1", optarg, 2))) {
+ op->st_lba = UINT64_MAX;
+ break;
+ }
ll = sg_get_llnum(optarg);
if (-1 == ll) {
pr2serr("bad argument to '--start=LBA' or '--locator=LBA\n");
diff --git a/src/sg_requests.c b/src/sg_requests.c
index a0afd365..ee0c0388 100644
--- a/src/sg_requests.c
+++ b/src/sg_requests.c
@@ -34,7 +34,7 @@
* This program issues the SCSI command REQUEST SENSE to the given SCSI device.
*/
-static const char * version_str = "1.38 20211001";
+static const char * version_str = "1.39 20211114";
#define MAX_REQS_RESP_LEN 255
#define DEF_REQS_RESP_LEN 252
@@ -152,7 +152,7 @@ main(int argc, char * argv[])
char b[256];
uint8_t rs_cdb[REQUEST_SENSE_CMDLEN] =
{REQUEST_SENSE_CMD, 0, 0, 0, 0, 0};
- uint8_t sense_b[SENSE_BUFF_LEN];
+ uint8_t sense_b[SENSE_BUFF_LEN] = {0};
#ifndef SG_LIB_MINGW
bool do_time = false;
struct timeval start_tm, end_tm;
diff --git a/src/sg_reset_wp.c b/src/sg_reset_wp.c
index 3a99a722..f3e76b3b 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.15 20210830";
+static const char * version_str = "1.16 20211114";
#define SG_ZONING_OUT_CMDLEN 16
#define RESET_WRITE_POINTER_SA 0x4
@@ -88,7 +88,7 @@ sg_ll_reset_write_pointer(int sg_fd, uint64_t zid, uint16_t zc, bool all,
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];
+ uint8_t sense_b[SENSE_BUFF_LEN] = {0};
struct sg_pt_base * ptvp;
sg_put_unaligned_be64(zid, rwp_cdb + 2);
diff --git a/src/sg_sanitize.c b/src/sg_sanitize.c
index 6865e463..ade9be71 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.16 20210830";
+static const char * version_str = "1.17 20211114";
/* Not all environments support the Unix sleep() */
#if defined(MSC_VER) || defined(__MINGW32__)
@@ -185,7 +185,7 @@ do_sanitize(int sg_fd, const struct opts_t * op, const void * param_lstp,
bool immed;
int ret, res, sense_cat, timeout;
uint8_t san_cdb[SANITIZE_OP_LEN];
- uint8_t sense_b[SENSE_BUFF_LEN];
+ uint8_t sense_b[SENSE_BUFF_LEN] = {0};
struct sg_pt_base * ptvp;
if (op->early || op->wait)
diff --git a/src/sg_stream_ctl.c b/src/sg_stream_ctl.c
index 3f1ff844..eede6e8f 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.10 20210830";
+static const char * version_str = "1.11 20211114";
#define STREAM_CONTROL_SA 0x14
#define GET_STREAM_STATUS_SA 0x16
@@ -116,7 +116,7 @@ sg_ll_get_stream_status(int sg_fd, uint16_t s_str_id, uint8_t * resp,
int k, ret, res, sense_cat;
uint8_t gssCdb[16] = {SG_SERVICE_ACTION_IN_16,
GET_STREAM_STATUS_SA, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
- uint8_t sense_b[SENSE_BUFF_LEN];
+ uint8_t sense_b[SENSE_BUFF_LEN] = {0};
struct sg_pt_base * ptvp;
static const char * const cmd_name = "Get stream status";
@@ -184,7 +184,7 @@ sg_ll_stream_control(int sg_fd, uint32_t str_ctl, uint16_t str_id,
int k, ret, res, sense_cat;
uint8_t scCdb[16] = {SG_SERVICE_ACTION_IN_16,
STREAM_CONTROL_SA, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
- uint8_t sense_b[SENSE_BUFF_LEN];
+ uint8_t sense_b[SENSE_BUFF_LEN] = {0};
struct sg_pt_base * ptvp;
static const char * const cmd_name = "Stream control";
diff --git a/src/sg_sync.c b/src/sg_sync.c
index 751b25c8..1a8eebfb 100644
--- a/src/sg_sync.c
+++ b/src/sg_sync.c
@@ -37,7 +37,7 @@
* (e.g. disks).
*/
-static const char * version_str = "1.26 20210830";
+static const char * version_str = "1.27 20211114";
#define SYNCHRONIZE_CACHE16_CMD 0x91
#define SYNCHRONIZE_CACHE16_CMDLEN 16
@@ -101,7 +101,7 @@ sg_ll_sync_cache_16(int sg_fd, bool sync_nv, bool immed, int group,
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};
- uint8_t sense_b[SENSE_BUFF_LEN];
+ uint8_t sense_b[SENSE_BUFF_LEN] = {0};
struct sg_pt_base * ptvp;
if (sync_nv)
diff --git a/src/sg_timestamp.c b/src/sg_timestamp.c
index 58f12975..b9da385c 100644
--- a/src/sg_timestamp.c
+++ b/src/sg_timestamp.c
@@ -197,7 +197,7 @@ sg_ll_rep_timestamp(int sg_fd, void * resp, int mx_resp_len, int * residp,
int k, ret, res, sense_cat;
uint8_t rt_cdb[REP_TIMESTAMP_CMDLEN] =
{SG_MAINTENANCE_IN, REP_TIMESTAMP_SA, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
- uint8_t sense_b[SENSE_BUFF_LEN];
+ uint8_t sense_b[SENSE_BUFF_LEN] = {0};
struct sg_pt_base * ptvp;
sg_put_unaligned_be32((uint32_t)mx_resp_len, rt_cdb + 6);
@@ -260,7 +260,7 @@ sg_ll_set_timestamp(int sg_fd, void * paramp, int param_len, bool noisy,
uint8_t st_cdb[SET_TIMESTAMP_CMDLEN] =
{SG_MAINTENANCE_OUT, SET_TIMESTAMP_SA, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0};
- uint8_t sense_b[SENSE_BUFF_LEN];
+ uint8_t sense_b[SENSE_BUFF_LEN] = {0};
struct sg_pt_base * ptvp;
sg_put_unaligned_be32(param_len, st_cdb + 6);
diff --git a/src/sg_vpd.c b/src/sg_vpd.c
index 82924da5..cbd2876b 100644
--- a/src/sg_vpd.c
+++ b/src/sg_vpd.c
@@ -40,7 +40,7 @@
*/
-static const char * version_str = "1.66 20210923"; /* spc6r05 + sbc5r01 */
+static const char * version_str = "1.67 20211112"; /* spc6r05 + sbc5r01 */
/* standard VPD pages, in ascending page number order */
#define VPD_SUPPORTED_VPDS 0x0
@@ -2599,7 +2599,7 @@ decode_zbdch_vpd(uint8_t * b, int len, int do_hex)
printf("no limit\n");
else
printf("%" PRIu32 "\n", u);
- printf(" Zone alignment mode: "); /* zbc2r11 */
+ printf(" Zone alignment method: "); /* zbc2r11,zbc2r12 */
switch (b[23] & 0xf) {
case 0:
printf("not reported [0]\n");
diff --git a/src/sg_write_same.c b/src/sg_write_same.c
index bfbfdca7..e2213fba 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.33 20210830";
+static const char * version_str = "1.33 20211114";
#define ME "sg_write_same: "
@@ -169,8 +169,8 @@ do_write_same(int sg_fd, const struct opts_t * op, const void * dataoutp,
{
int ret, res, sense_cat, cdb_len;
uint64_t llba;
- uint8_t ws_cdb[WRITE_SAME32_LEN];
- uint8_t sense_b[SENSE_BUFF_LEN];
+ uint8_t ws_cdb[WRITE_SAME32_LEN] = {0};
+ uint8_t sense_b[SENSE_BUFF_LEN] = {0};
struct sg_pt_base * ptvp;
cdb_len = op->pref_cdb_size;
@@ -194,7 +194,6 @@ do_write_same(int sg_fd, const struct opts_t * op, const void * dataoutp,
}
if (act_cdb_lenp)
*act_cdb_lenp = cdb_len;
- memset(ws_cdb, 0, sizeof(ws_cdb));
switch (cdb_len) {
case WRITE_SAME10_LEN:
ws_cdb[0] = WRITE_SAME10_OP;
diff --git a/src/sg_write_verify.c b/src/sg_write_verify.c
index 13030206..384899b2 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.19 20210830";
+static const char * version_str = "1.20 20211114";
#define ME "sg_write_verify: "
@@ -129,7 +129,7 @@ run_scsi_transaction(int sg_fd, const uint8_t *cdbp, int cdb_len,
{
int res, sense_cat, ret;
struct sg_pt_base * ptvp;
- uint8_t sense_b[SENSE_BUFF_LEN];
+ uint8_t sense_b[SENSE_BUFF_LEN] = {0};
char b[32];
snprintf(b, sizeof(b), "Write and verify(%d)", cdb_len);
diff --git a/src/sg_write_x.c b/src/sg_write_x.c
index 504fe26f..18d1e7ec 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.28 20210923";
+static const char * version_str = "1.29 20211114";
/* Protection Information refers to 8 bytes of extra information usually
* associated with each logical block and is often abbreviated to PI while
@@ -1053,7 +1053,7 @@ do_write_x(int sg_fd, const void * dataoutp, int dout_len,
{
int k, ret, res, sense_cat, cdb_len, vb, err;
uint8_t x_cdb[WRITE_X_32_LEN]; /* use for both lengths */
- uint8_t sense_b[SENSE_BUFF_LEN];
+ uint8_t sense_b[SENSE_BUFF_LEN] = {0};
struct sg_pt_base * ptvp;
memset(x_cdb, 0, sizeof(x_cdb));
diff --git a/src/sg_xcopy.c b/src/sg_xcopy.c
index 1fb09c49..4307668b 100644
--- a/src/sg_xcopy.c
+++ b/src/sg_xcopy.c
@@ -27,7 +27,7 @@
* in this case) is transferred to or from the sg device in a single SCSI
* command.
*
- * This version is designed for the linux kernel 2.4, 2.6, 3, 4 and 5 series.
+ * This version is designed for the Linux kernel 2.4, 2.6, 3, 4 and 5 series.
*/
#define _XOPEN_SOURCE 600
diff --git a/src/sg_z_act_query.c b/src/sg_z_act_query.c
new file mode 100644
index 00000000..5958f94a
--- /dev/null
+++ b/src/sg_z_act_query.c
@@ -0,0 +1,642 @@
+/*
+ * Copyright (c) 2014-2021 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.
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#include <unistd.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <stdbool.h>
+#include <string.h>
+#include <ctype.h>
+#include <errno.h>
+#include <getopt.h>
+#define __STDC_FORMAT_MACROS 1
+#include <inttypes.h>
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "sg_lib.h"
+#include "sg_lib_data.h"
+#include "sg_pt.h"
+#include "sg_cmds_basic.h"
+#include "sg_unaligned.h"
+#include "sg_pr2serr.h"
+
+/* A utility program originally written for the Linux OS SCSI subsystem.
+ *
+ *
+ * This program issues either a SCSI ZONE ACTIVATE command or a ZONE QUERY
+ * command to the given SCSI device. Based on zbc2r12.pdf .
+ */
+
+static const char * version_str = "1.01 20211117";
+
+#define SG_ZBC_IN_CMDLEN 16
+#define Z_ACTIVATE_SA 0x8
+#define Z_QUERY_SA 0x9
+
+#define SENSE_BUFF_LEN 64 /* Arbitrary, could be larger */
+#define DEF_PT_TIMEOUT 60 /* 60 seconds */
+#define DEF_ALLOC_LEN 8192
+#define Z_ACT_DESC_LEN 32
+#define MAX_ACT_QUERY_BUFF_LEN (16 * 1024 * 1024)
+
+struct opts_t {
+ bool do_all;
+ bool do_activate;
+ bool do_force;
+ bool do_query;
+ bool do_raw;
+ bool maxlen_given;
+ uint8_t other_zdid;
+ uint16_t max_alloc;
+ uint16_t num_zones;
+ int hex_count;
+ int vb;
+ uint64_t st_lba; /* Zone ID */
+ const char * device_name;
+ const char * inhex_fn;
+};
+
+static struct option long_options[] = {
+ {"activate", no_argument, 0, 'A'},
+ {"all", no_argument, 0, 'a'},
+ {"force", no_argument, 0, 'f'},
+ {"help", no_argument, 0, 'h'},
+ {"hex", no_argument, 0, 'H'},
+ {"in", required_argument, 0, 'i'}, /* silent, same as --inhex= */
+ {"inhex", required_argument, 0, 'i'},
+ {"maxlen", required_argument, 0, 'm'},
+ {"num", required_argument, 0, 'n'},
+ {"other", required_argument, 0, 'o'},
+ {"query", no_argument, 0, 'q'},
+ {"raw", no_argument, 0, 'r'},
+ {"verbose", no_argument, 0, 'v'},
+ {"version", no_argument, 0, 'V'},
+ {"zone", required_argument, 0, 'z'},
+ {0, 0, 0, 0},
+};
+
+
+static void
+usage()
+{
+ pr2serr("Usage: "
+ "sg_z_act_query [--activate] [--all] [--force] [--help] "
+ "[--hex]\n"
+ " [--inhex=FN] [--maxlen=LEN] [--num=ZS] "
+ "[--other=ZDID]\n"
+ " [--query] [--raw] [--verbose] "
+ "[--version]\n"
+ " [--zone=ID] DEVICE\n");
+ pr2serr(" where:\n"
+ " --activate|-A do ZONE ACTIVATE command (def: ZONE "
+ "QUERY)\n"
+ " --all|-a sets the ALL flag in the cdb\n"
+ " --force|-f bypass some sanity checks\n"
+ " --help|-h print out usage message\n"
+ " --hex|-H print out response in hexadecimal\n"
+ " --inhex=FN|-i FN decode contents of FN, ignore DEVICE\n"
+ " --maxlen=LEN|-m LEN LEN place in cdb's allocation "
+ "length field\n"
+ " (def: 8192 (bytes))\n"
+ " --num=ZS|-n ZS ZS is the number of zones and is placed "
+ "in the cdb;\n"
+ " default value is 1, ignored if --all "
+ "given\n"
+ " --other=ZDID|-o ZDID ZDID is placed in Other zone domain "
+ "ID field\n"
+ " --query|-q do ZONE QUERY command (def: ZONE "
+ "QUERY)\n"
+ " --raw|-r output response in binary, or if "
+ "--inhex=FN is\n"
+ " given, then FN's contents are binary\n"
+ " --verbose|-v increase verbosity\n"
+ " --version|-V print version string and exit\n"
+ " --zone=ID|-z ID ID is the starting LBA of the zone "
+ "(def: 0)\n\n"
+ "Performs either a SCSI ZONE ACTIVATE command, or a ZONE QUERY "
+ "command.\nArguments to options are decimal by default, for hex "
+ "use a leading '0x'\nor a trailing 'h'. The default action is to "
+ "send a ZONE QUERY command.\n");
+}
+
+/* Invokes a ZBC IN command (with either a ZONE ACTIVATE or a ZONE QUERY
+ * service action). Return of 0 -> success, various SG_LIB_CAT_* positive
+ * values or -1 -> other errors */
+static int
+sg_ll_zone_act_query(int sg_fd, const struct opts_t * op, void * resp,
+ int * residp)
+{
+ uint8_t sa = op->do_activate ? Z_ACTIVATE_SA : Z_QUERY_SA;
+ int ret, res, sense_cat;
+ struct sg_pt_base * ptvp;
+ uint8_t zi_cdb[SG_ZBC_IN_CMDLEN] =
+ {SG_ZBC_IN, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+ uint8_t sense_b[SENSE_BUFF_LEN] = {0};
+ char b[64];
+
+ zi_cdb[1] = 0x1f & sa;
+ if (op->do_all)
+ zi_cdb[1] |= 0x80;
+
+ sg_put_unaligned_be64(op->st_lba, zi_cdb + 2);
+ sg_put_unaligned_be16(op->num_zones, zi_cdb + 10);
+ sg_put_unaligned_be16(op->max_alloc, zi_cdb + 12);
+ zi_cdb[14] = op->other_zdid;
+ sg_get_opcode_sa_name(zi_cdb[0], sa, -1, sizeof(b), b);
+ if (op->vb) {
+ char d[128];
+
+ pr2serr(" %s cdb: %s\n", b,
+ sg_get_command_str(zi_cdb, SG_ZBC_IN_CMDLEN, false,
+ sizeof(d), d));
+ }
+ ptvp = construct_scsi_pt_obj();
+ if (NULL == ptvp) {
+ pr2serr("%s: out of memory\n", b);
+ return -1;
+ }
+ set_scsi_pt_cdb(ptvp, zi_cdb, sizeof(zi_cdb));
+ set_scsi_pt_sense(ptvp, sense_b, sizeof(sense_b));
+ set_scsi_pt_data_in(ptvp, (uint8_t *)resp, op->max_alloc);
+ res = do_scsi_pt(ptvp, sg_fd, DEF_PT_TIMEOUT, op->vb);
+ ret = sg_cmds_process_resp(ptvp, b, res, true /* noisy */,
+ op->vb, &sense_cat);
+ if (-1 == ret) {
+ if (get_scsi_pt_transport_err(ptvp))
+ ret = SG_LIB_TRANSPORT_ERROR;
+ else
+ ret = sg_convert_errno(get_scsi_pt_os_err(ptvp));
+ } else if (-2 == ret) {
+ switch (sense_cat) {
+ case SG_LIB_CAT_RECOVERED:
+ case SG_LIB_CAT_NO_SENSE:
+ ret = 0;
+ break;
+ default:
+ ret = sense_cat;
+ break;
+ }
+ } else
+ ret = 0;
+ if (residp)
+ *residp = get_scsi_pt_resid(ptvp);
+ destruct_scsi_pt_obj(ptvp);
+ return ret;
+}
+
+static const char *
+zone_condition_str(int zc, char * b, int blen, int vb)
+{
+ const char * cp;
+
+ if (NULL == b)
+ return "zone_condition_str: NULL ptr)";
+ switch (zc) {
+ case 0:
+ cp = "Not write pointer";
+ break;
+ case 1:
+ cp = "Empty";
+ break;
+ case 2:
+ cp = "Implicitly opened";
+ break;
+ case 3:
+ cp = "Explicitly opened";
+ break;
+ case 4:
+ cp = "Closed";
+ break;
+ case 5:
+ cp = "Inactive";
+ break;
+ case 0xd:
+ cp = "Read only";
+ break;
+ case 0xe:
+ cp = "Full";
+ break;
+ case 0xf:
+ cp = "Offline";
+ break;
+ default:
+ cp = NULL;
+ break;
+ }
+ if (cp) {
+ if (vb)
+ snprintf(b, blen, "%s [0x%x]", cp, zc);
+ else
+ snprintf(b, blen, "%s", cp);
+ } else
+ snprintf(b, blen, "Reserved [0x%x]", zc);
+ return b;
+}
+
+/* The allocation length field in each cdb cannot be less than 64 but the
+ * transport could still trim the response. */
+static int
+decode_z_act_query(const uint8_t * ziBuff, int act_len, uint32_t zar_len,
+ const struct opts_t * op)
+{
+ uint8_t zt;
+ int k, zc, num_desc;
+ const uint8_t * bp;
+ char b[80];
+
+ if ((uint32_t)act_len < zar_len) {
+ num_desc = (act_len >= 64) ? ((act_len - 64) / Z_ACT_DESC_LEN) : 0;
+ if (act_len == op->max_alloc) {
+ if (op->maxlen_given)
+ pr2serr("response length [%u bytes] may be constrained by "
+ "given --maxlen value, try increasing\n", zar_len);
+ else
+ pr2serr("perhaps --maxlen=%u needs to be used\n", zar_len);
+ } else if (op->inhex_fn)
+ pr2serr("perhaps %s has been truncated\n", op->inhex_fn);
+ } else
+ num_desc = (zar_len - 64) / Z_ACT_DESC_LEN;
+ if (act_len <= 8)
+ return 0;
+ if (0x80 & ziBuff[8]) {
+ printf(" Nz_valid=1\n");
+ if (act_len > 19)
+ printf(" Number of zones: %u\n",
+ sg_get_unaligned_be32(ziBuff + 16));
+ } else
+ printf(" Nz_valid=0\n");
+ if (0x40 & ziBuff[8]) {
+ printf(" Ziwup_valid=1\n");
+ if (act_len > 31)
+ printf(" Zone ID with unmet prerequisite: 0x%" PRIx64 "\n",
+ sg_get_unaligned_be64(ziBuff + 24));
+ } else
+ printf(" Ziwup_valid=0\n");
+ printf(" Activated=%d\n", (0x1 & ziBuff[8]));
+ if (act_len <= 9)
+ return 0;
+ printf(" Unmet prerequisites:\n");
+ if (0 == ziBuff[9])
+ printf(" none\n");
+ else {
+ if (0x40 & ziBuff[9])
+ printf(" security\n");
+ if (0x20 & ziBuff[9])
+ printf(" mult domn\n");
+ if (0x10 & ziBuff[9])
+ printf(" rlm rstct\n");
+ if (0x8 & ziBuff[9])
+ printf(" mult ztyp\n");
+ if (0x4 & ziBuff[9])
+ printf(" rlm align\n");
+ if (0x2 & ziBuff[9])
+ printf(" not empty\n");
+ if (0x1 & ziBuff[9])
+ printf(" not inact\n");
+ }
+ if (act_len <= 10)
+ return 0;
+ printf(" Other zone domain ID: %u\n", ziBuff[10]);
+ if (act_len <= 11)
+ return 0;
+ printf(" All: %d\n", (0x1 & ziBuff[11]));
+
+ if (((uint32_t)act_len < zar_len) &&
+ ((num_desc * Z_ACT_DESC_LEN) + 64 > act_len)) {
+ pr2serr("Skip due to truncated response, try using --num= to a "
+ "value less than %d\n", num_desc);
+ return SG_LIB_CAT_MALFORMED;
+ }
+ for (k = 0, bp = ziBuff + 64; k < num_desc; ++k, bp += Z_ACT_DESC_LEN) {
+ printf(" Zone activation descriptor: %d\n", k);
+ if (op->hex_count) {
+ hex2stdout(bp, Z_ACT_DESC_LEN, -1);
+ continue;
+ }
+ zt = bp[0] & 0xf;
+ zc = (bp[1] >> 4) & 0xf;
+ printf(" Zone type: %s\n", sg_get_zone_type_str(zt, sizeof(b),
+ b));
+ printf(" Zone condition: %s\n", zone_condition_str(zc, b,
+ sizeof(b), op->vb));
+ printf(" Zone domain ID: %u\n", bp[2]);
+ printf(" Zone range size: %" PRIu64 "\n",
+ sg_get_unaligned_be64(bp + 8));
+ printf(" Starting zone locator: 0x%" PRIx64 "\n",
+ sg_get_unaligned_be64(bp + 16));
+ }
+ return 0;
+}
+
+static void
+dStrRaw(const uint8_t * str, int len)
+{
+ int k;
+
+ for (k = 0; k < len; ++k)
+ printf("%c", str[k]);
+}
+
+
+int
+main(int argc, char * argv[])
+{
+ bool no_final_msg = false;
+ bool version_given = false;
+ int res, c, n, in_len, rlen, act_len;
+ int sg_fd = -1;
+ int resid = 0;
+ int verbose = 0;
+ int ret = 0;
+ uint32_t zar_len, zarr_len;
+ int64_t ll;
+ uint8_t * ziBuff = NULL;
+ uint8_t * free_zibp = NULL;
+ const char * sa_name;
+ char b[80];
+ struct opts_t opts;
+ struct opts_t * op = &opts;
+
+ memset(&opts, 0, sizeof(opts));
+ while (1) {
+ int option_index = 0;
+
+ c = getopt_long(argc, argv, "aAfhHi:m:n:o:qrvVz:", long_options,
+ &option_index);
+ if (c == -1)
+ break;
+
+ switch (c) {
+ case 'a':
+ op->do_all = true;
+ break;
+ case 'A':
+ op->do_activate = true;
+ break;
+ case 'f':
+ op->do_force = true;
+ break;
+ case 'h':
+ case '?':
+ usage();
+ return 0;
+ case 'H':
+ ++op->hex_count;
+ break;
+ case 'i':
+ op->inhex_fn = optarg;
+ break;
+ case 'm':
+ n = sg_get_num(optarg);
+ if ((n < 0) || (n > 0xffff)) {
+ pr2serr("--maxlen= expects an argument between 0 and 0xffff "
+ "inclusive\n");
+ return SG_LIB_SYNTAX_ERROR;
+ }
+ op->maxlen_given = true;
+ op->max_alloc = (uint16_t)n;
+ break;
+ case 'n':
+ n = sg_get_num(optarg);
+ if ((n < 0) || (n > 0xffff)) {
+ pr2serr("--num=ZS expects an argument between 0 and 0xffff "
+ "inclusive\n");
+ return SG_LIB_SYNTAX_ERROR;
+ }
+ op->num_zones = (uint16_t)n;
+ break;
+ case 'o':
+ n = sg_get_num(optarg);
+ if ((n < 0) || (n > 0xff)) {
+ pr2serr("--other=ZDID expects an argument between 0 and 0xff "
+ "inclusive\n");
+ return SG_LIB_SYNTAX_ERROR;
+ }
+ op->other_zdid = (uint8_t)n;
+ break;
+ case 'q':
+ op->do_query = true;
+ break;
+ case 'r':
+ op->do_raw = true;
+ break;
+ case 'v':
+ ++op->vb;
+ break;
+ case 'V':
+ version_given = true;
+ break;
+ case 'z':
+ if ((2 == strlen(optarg)) && (0 == memcmp("-1", optarg, 2))) {
+ op->st_lba = UINT64_MAX;
+ break;
+ }
+ ll = sg_get_llnum(optarg);
+ if (-1 == ll) {
+ pr2serr("bad argument to '--zone=ID'\n");
+ return SG_LIB_SYNTAX_ERROR;
+ }
+ op->st_lba = (uint64_t)ll; /* Zone ID is starting LBA */
+ break;
+ default:
+ pr2serr("unrecognised option code 0x%x ??\n\n", c);
+ usage();
+ return SG_LIB_SYNTAX_ERROR;
+ }
+ }
+ if (optind < argc) {
+ if (NULL == op->device_name) {
+ op->device_name = argv[optind];
+ ++optind;
+ }
+ if (optind < argc) {
+ for (; optind < argc; ++optind)
+ pr2serr("Unexpected extra argument: %s\n",
+ argv[optind]);
+ usage();
+ return SG_LIB_SYNTAX_ERROR;
+ }
+ }
+
+ if (version_given) {
+ pr2serr("version: %s\n", version_str);
+ return 0;
+ }
+
+ if ((! op->do_all) && (0 == op->num_zones))
+ op->num_zones = 1;
+ if (op->do_activate && op->do_query){
+ pr2serr("only one of these options: --activate and --query may be "
+ "given\n\n");
+ usage();
+ return SG_LIB_CONTRADICT;
+ }
+ sa_name = op->do_activate ? "Zone activate" : "Zone query";
+ if (op->device_name && op->inhex_fn) {
+ pr2serr("ignoring DEVICE, best to give DEVICE or --inhex=FN, but "
+ "not both\n");
+ op->device_name = NULL;
+ }
+ if (op->max_alloc < 4) {
+ if (op->max_alloc > 0)
+ pr2serr("Won't accept --maxlen= of 1, 2 or 3, using %d "
+ "instead\n", DEF_ALLOC_LEN);
+ op->max_alloc = DEF_ALLOC_LEN;
+ }
+ ziBuff = (uint8_t *)sg_memalign(op->max_alloc, 0, &free_zibp, op->vb > 3);
+ if (NULL == ziBuff) {
+ pr2serr("unable to sg_memalign %d bytes\n", op->max_alloc);
+ return sg_convert_errno(ENOMEM);
+ }
+
+ if (NULL == op->device_name) {
+ if (op->inhex_fn) {
+ if ((ret = sg_f2hex_arr(op->inhex_fn, op->do_raw, false, ziBuff,
+ &in_len, op->max_alloc))) {
+ if (SG_LIB_LBA_OUT_OF_RANGE == ret) {
+ no_final_msg = true;
+ pr2serr("... decode what we have, --maxlen=%d needs to "
+ "be increased\n", op->max_alloc);
+ } else
+ goto the_end;
+ }
+ if (verbose > 2)
+ pr2serr("Read %d [0x%x] bytes of user supplied data\n",
+ in_len, in_len);
+ if (op->do_raw)
+ op->do_raw = false; /* can interfere on decode */
+ if (in_len < 4) {
+ pr2serr("--inhex=%s only decoded %d bytes (needs 4 at "
+ "least)\n", op->inhex_fn, in_len);
+ ret = SG_LIB_SYNTAX_ERROR;
+ goto the_end;
+ }
+ res = 0;
+ goto start_response;
+ } else {
+ pr2serr("missing device name!\n\n");
+ usage(1);
+ ret = SG_LIB_FILE_ERROR;
+ no_final_msg = true;
+ goto the_end;
+ }
+ } else
+ in_len = 0;
+
+ if (op->do_raw) {
+ if (sg_set_binary_mode(STDOUT_FILENO) < 0) {
+ perror("sg_set_binary_mode");
+ return SG_LIB_FILE_ERROR;
+ }
+ }
+
+ sg_fd = sg_cmds_open_device(op->device_name, false /* rw */, verbose);
+ if (sg_fd < 0) {
+ int err = -sg_fd;
+ if (verbose)
+ pr2serr("open error: %s: %s\n", op->device_name,
+ safe_strerror(err));
+ ret = sg_convert_errno(err);
+ goto the_end;
+ }
+
+ res = sg_ll_zone_act_query(sg_fd, op, ziBuff, &resid);
+ ret = res;
+ if (res) {
+ if (SG_LIB_CAT_INVALID_OP == res)
+ pr2serr("%s command not supported\n", sa_name);
+ else {
+ char b[80];
+
+ sg_get_category_sense_str(res, sizeof(b), b, verbose);
+ pr2serr("%s command: %s\n", sa_name, b);
+ }
+ }
+
+start_response:
+ if (0 == res) {
+ if ((resid < 0) || (resid > op->max_alloc)) {
+ pr2serr("Unexpected resid=%d\n", resid);
+ ret = SG_LIB_CAT_MALFORMED;
+ goto the_end;
+ }
+ rlen = op->inhex_fn ? in_len : (op->max_alloc - resid);
+ if (rlen < 4) {
+ pr2serr("Decoded response length (%d) too short\n", rlen);
+ ret = SG_LIB_CAT_MALFORMED;
+ goto the_end;
+ }
+ zar_len = sg_get_unaligned_be32(ziBuff + 0) + 64;
+ zarr_len = sg_get_unaligned_be32(ziBuff + 4) + 64;
+ if ((zar_len > MAX_ACT_QUERY_BUFF_LEN) ||
+ (zarr_len > MAX_ACT_QUERY_BUFF_LEN) || (zarr_len > zar_len)) {
+ if (! op->do_force) {
+ pr2serr("zar or zarr length [%u/%u bytes] seems wild, use "
+ "--force override\n", zar_len, zarr_len);
+ return SG_LIB_CAT_MALFORMED;
+ }
+ }
+ if (zarr_len > (uint32_t)rlen) {
+ pr2serr("zarr response length is %u bytes, but system "
+ "reports %d bytes received??\n", zarr_len, rlen);
+ if (op->do_force)
+ act_len = rlen;
+ else {
+ pr2serr("Exiting, use --force to override\n");
+ ret = SG_LIB_CAT_MALFORMED;
+ goto the_end;
+ }
+ } else
+ act_len = zarr_len;
+ if (op->do_raw) {
+ dStrRaw(ziBuff, act_len);
+ goto the_end;
+ }
+ if (op->hex_count && (2 != op->hex_count)) {
+ hex2stdout(ziBuff, act_len, ((1 == op->hex_count) ? 1 : -1));
+ goto the_end;
+ }
+ printf("%s response:\n", sa_name);
+ if (act_len < 64) {
+ pr2serr("Zone length [%d] too short (perhaps after truncation\n)",
+ act_len);
+ ret = SG_LIB_CAT_MALFORMED;
+ goto the_end;
+ }
+ ret = decode_z_act_query(ziBuff, act_len, zar_len, op);
+ } else if (SG_LIB_CAT_INVALID_OP == res)
+ pr2serr("%s command not supported\n", sa_name);
+ else {
+ sg_get_category_sense_str(res, sizeof(b), b, op->vb);
+ pr2serr("%s command: %s\n", sa_name, b);
+ }
+
+the_end:
+ if (sg_fd >= 0) {
+ res = sg_cmds_close_device(sg_fd);
+ if (res < 0) {
+ pr2serr("close error: %s\n", safe_strerror(-res));
+ if (0 == ret)
+ ret = sg_convert_errno(-res);
+ }
+ }
+ if (free_zibp)
+ free(free_zibp);
+ if ((0 == verbose) && (! no_final_msg)) {
+ if (! sg_if_can2stderr("sg_z_act_query failed: ", ret))
+ pr2serr("Some error occurred, try again with '-v' "
+ "or '-vv' for more information\n");
+ }
+ return (ret >= 0) ? ret : SG_LIB_CAT_OTHER;
+}
diff --git a/src/sg_zone.c b/src/sg_zone.c
index f47e6f65..ff4dc366 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.16 20210830";
+static const char * version_str = "1.17 20211114";
#define SG_ZONING_OUT_CMDLEN 16
#define CLOSE_ZONE_SA 0x1
@@ -133,7 +133,7 @@ sg_ll_zone_out(int sg_fd, int sa, uint64_t zid, uint16_t zc, bool all,
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};
- uint8_t sense_b[SENSE_BUFF_LEN];
+ uint8_t sense_b[SENSE_BUFF_LEN] = {0};
char b[64];
zo_cdb[1] = 0x1f & sa;
diff --git a/src/sginfo.c b/src/sginfo.c
index ba094dc6..51a312af 100644
--- a/src/sginfo.c
+++ b/src/sginfo.c
@@ -124,7 +124,7 @@
#define _GNU_SOURCE 1
#endif
-static const char * version_str = "2.43 [20190913]";
+static const char * version_str = "2.44 [20211114]";
#include <stdio.h>
#include <string.h>
@@ -393,7 +393,7 @@ struct scsi_cmnd_io
static int
do_scsi_io(struct scsi_cmnd_io * sio)
{
- uint8_t sense_b[SENSE_BUFF_LEN];
+ uint8_t sense_b[SENSE_BUFF_LEN] = {0};
struct sg_io_hdr io_hdr;
struct sg_scsi_sense_hdr ssh;
int res;
@@ -1758,7 +1758,7 @@ trytenbyte:
}
else if (!sorthead) printf("|");
}
- break;
+ break;
case 5: /* physical sector */
while (len > 0) {
snprintf((char *)cbuffer1, 40, "%6d:%2u:%5d",
@@ -1777,7 +1777,7 @@ trytenbyte:
}
else if (!sorthead) printf("|");
}
- break;
+ break;
case 0: /* lba (32 bit) */
while (len > 0) {
printf("%10d", getnbyte(df, 4));
@@ -1791,7 +1791,7 @@ trytenbyte:
else
printf("|");
}
- break;
+ break;
case 3: /* lba (64 bit) */
while (len > 0) {
printf("%15" PRId64 , getnbyte_ll(df, 8));
diff --git a/src/sgm_dd.c b/src/sgm_dd.c
index 4909c821..e95fca9e 100644
--- a/src/sgm_dd.c
+++ b/src/sgm_dd.c
@@ -27,7 +27,7 @@
then only the read side will be mmap-ed, while the write side will
use normal IO.
- This version is designed for the linux kernel 2.4, 2.6, 3, 4 and 5 series.
+ This version is designed for the Linux kernel 2.4, 2.6, 3, 4 and 5 series.
*/
#define _XOPEN_SOURCE 600
@@ -69,7 +69,7 @@
#include "sg_pr2serr.h"
-static const char * version_str = "1.17 20211024";
+static const char * version_str = "1.18 20211114";
#define DEF_BLOCK_SIZE 512
#define DEF_BLOCKS_PER_TRANSFER 128
@@ -471,7 +471,7 @@ sg_read(int sg_fd, uint8_t * buff, int blocks, int64_t from_block,
bool print_cdb_after = false;
int res;
uint8_t rdCmd[MAX_SCSI_CDBSZ];
- uint8_t senseBuff[SENSE_BUFF_LEN];
+ uint8_t senseBuff[SENSE_BUFF_LEN] = {0};
struct sg_io_hdr io_hdr;
if (sg_build_scsi_cdb(rdCmd, cdbsz, blocks, from_block, false, fua,
@@ -568,7 +568,7 @@ sg_write(int sg_fd, uint8_t * buff, int blocks, int64_t to_block,
bool print_cdb_after = false;
int res;
uint8_t wrCmd[MAX_SCSI_CDBSZ];
- uint8_t senseBuff[SENSE_BUFF_LEN];
+ uint8_t senseBuff[SENSE_BUFF_LEN] = {0};
struct sg_io_hdr io_hdr;
if (sg_build_scsi_cdb(wrCmd, cdbsz, blocks, to_block, true, fua, dpo)) {
diff --git a/src/sgp_dd.c b/src/sgp_dd.c
index 2b2d4e5c..b71bf7b4 100644
--- a/src/sgp_dd.c
+++ b/src/sgp_dd.c
@@ -22,7 +22,7 @@
* in this case) are transferred to or from the sg device in a single SCSI
* command.
*
- * This version is designed for the linux kernel 2.4, 2.6, 3, 4 and 5 series.
+ * This version is designed for the Linux kernel 2.4, 2.6, 3, 4 and 5 series.
*
* sgp_dd is a Posix threads specialization of the sg_dd utility. Both
* sgp_dd and sg_dd only perform special tasks when one or both of the given