diff options
author | Douglas Gilbert <dgilbert@interlog.com> | 2021-11-20 17:13:42 +0000 |
---|---|---|
committer | Douglas Gilbert <dgilbert@interlog.com> | 2021-11-20 17:13:42 +0000 |
commit | 20315aa4fae1340e5d4b1faae15b90ee34b9ea50 (patch) | |
tree | eb935ed0b6aed4abf787556adcfe9e3cb99c297d /src | |
parent | 26be8550ae1aad5db9bcf9b0cfe1fdecccd210df (diff) | |
download | sg3_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.am | 4 | ||||
-rw-r--r-- | src/Makefile.in | 25 | ||||
-rw-r--r-- | src/sg_bg_ctl.c | 4 | ||||
-rw-r--r-- | src/sg_compare_and_write.c | 4 | ||||
-rw-r--r-- | src/sg_dd.c | 8 | ||||
-rw-r--r-- | src/sg_decode_sense.c | 111 | ||||
-rw-r--r-- | src/sg_format.c | 8 | ||||
-rw-r--r-- | src/sg_get_elem_status.c | 4 | ||||
-rw-r--r-- | src/sg_map26.c | 6 | ||||
-rw-r--r-- | src/sg_opcodes.c | 6 | ||||
-rw-r--r-- | src/sg_read.c | 6 | ||||
-rw-r--r-- | src/sg_read_attr.c | 4 | ||||
-rw-r--r-- | src/sg_read_buffer.c | 6 | ||||
-rw-r--r-- | src/sg_rep_pip.c | 4 | ||||
-rw-r--r-- | src/sg_rep_zones.c | 33 | ||||
-rw-r--r-- | src/sg_requests.c | 4 | ||||
-rw-r--r-- | src/sg_reset_wp.c | 4 | ||||
-rw-r--r-- | src/sg_sanitize.c | 4 | ||||
-rw-r--r-- | src/sg_stream_ctl.c | 6 | ||||
-rw-r--r-- | src/sg_sync.c | 4 | ||||
-rw-r--r-- | src/sg_timestamp.c | 4 | ||||
-rw-r--r-- | src/sg_vpd.c | 4 | ||||
-rw-r--r-- | src/sg_write_same.c | 7 | ||||
-rw-r--r-- | src/sg_write_verify.c | 4 | ||||
-rw-r--r-- | src/sg_write_x.c | 4 | ||||
-rw-r--r-- | src/sg_xcopy.c | 2 | ||||
-rw-r--r-- | src/sg_z_act_query.c | 642 | ||||
-rw-r--r-- | src/sg_zone.c | 4 | ||||
-rw-r--r-- | src/sginfo.c | 10 | ||||
-rw-r--r-- | src/sgm_dd.c | 8 | ||||
-rw-r--r-- | src/sgp_dd.c | 2 |
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 |