aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog5
-rwxr-xr-xconfigure3
-rw-r--r--configure.ac3
-rw-r--r--debian/changelog2
-rw-r--r--examples/Makefile12
-rw-r--r--examples/Makefile.freebsd45
-rw-r--r--include/sg_lib.h17
-rw-r--r--include/sg_pt.h13
-rw-r--r--include/sg_pt_linux.h3
-rw-r--r--include/sg_pt_nvme.h8
-rw-r--r--lib/Makefile.am1
-rw-r--r--lib/Makefile.in1
-rw-r--r--lib/sg_cmds_basic.c6
-rw-r--r--lib/sg_cmds_basic2.c14
-rw-r--r--lib/sg_cmds_extra.c84
-rw-r--r--lib/sg_cmds_mmc.c10
-rw-r--r--lib/sg_lib.c117
-rw-r--r--lib/sg_lib_data.c2
-rw-r--r--lib/sg_pt_common.c2
-rw-r--r--lib/sg_pt_freebsd.c122
-rw-r--r--lib/sg_pt_linux.c15
-rw-r--r--lib/sg_pt_linux_nvme.c157
-rw-r--r--sg3_utils.spec2
-rw-r--r--src/Makefile.am1
-rw-r--r--src/Makefile.in1
-rw-r--r--src/sg_bg_ctl.c4
-rw-r--r--src/sg_compare_and_write.c2
-rw-r--r--src/sg_copy_results.c8
-rw-r--r--src/sg_dd.c74
-rw-r--r--src/sg_format.c9
-rw-r--r--src/sg_get_config.c10
-rw-r--r--src/sg_get_lba_status.c8
-rw-r--r--src/sg_ident.c6
-rw-r--r--src/sg_inq.c421
-rw-r--r--src/sg_logs.c242
-rw-r--r--src/sg_luns.c13
-rw-r--r--src/sg_modes.c22
-rw-r--r--src/sg_opcodes.c24
-rw-r--r--src/sg_persist.c17
-rw-r--r--src/sg_raw.c6
-rw-r--r--src/sg_read_attr.c29
-rw-r--r--src/sg_read_block_limits.c11
-rw-r--r--src/sg_read_buffer.c21
-rw-r--r--src/sg_read_long.c29
-rw-r--r--src/sg_readcap.c44
-rw-r--r--src/sg_reassign.c7
-rw-r--r--src/sg_referrals.c13
-rw-r--r--src/sg_rep_zones.c15
-rw-r--r--src/sg_requests.c26
-rw-r--r--src/sg_rmsn.c7
-rw-r--r--src/sg_rtpg.c13
-rw-r--r--src/sg_safte.c34
-rw-r--r--src/sg_sanitize.c10
-rw-r--r--src/sg_sat_identify.c12
-rw-r--r--src/sg_sat_phy_event.c10
-rw-r--r--src/sg_sat_read_gplog.c9
-rw-r--r--src/sg_scan_win32.c6
-rw-r--r--src/sg_senddiag.c13
-rw-r--r--src/sg_ses.c63
-rw-r--r--src/sg_ses_microcode.c2
-rw-r--r--src/sg_stpg.c16
-rw-r--r--src/sg_test_rwbuf.c16
-rw-r--r--src/sg_timestamp.c15
-rw-r--r--src/sg_turs.c16
-rw-r--r--src/sg_vpd.c217
-rw-r--r--src/sg_vpd_vendor.c49
-rw-r--r--src/sg_wr_mode.c11
-rw-r--r--src/sg_write_same.c11
-rw-r--r--src/sg_write_verify.c6
-rw-r--r--src/sg_write_x.c14
-rw-r--r--src/sg_xcopy.c64
-rw-r--r--testing/Makefile19
-rw-r--r--testing/Makefile.freebsd96
-rw-r--r--testing/sg_iovec_tst.c3
-rw-r--r--testing/sg_tst_nvme.c731
75 files changed, 2097 insertions, 1073 deletions
diff --git a/ChangeLog b/ChangeLog
index 28a8b043..817f545e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -2,7 +2,7 @@ Each utility has its own version number, date of last change and
some description at the top of its ".c" file. All utilities in the main
directory have their own "man" pages. There is also a sg3_utils man page.
-Changelog for sg3_utils-1.43 [20180112] [svn: r744]
+Changelog for sg3_utils-1.43 [20180119] [svn: r745]
- sg_bg_ctl: new Background control command (sbc4r08)
- sg_write_x: where x can be normal, atomic, orwrite,
same, scattered, or stream writes with 16 or 32 byte
@@ -116,6 +116,7 @@ Changelog for sg3_utils-1.43 [20180112] [svn: r744]
- add sg_get_nvme_cmd_status_str()
- add sg_nvme_status2scsi()
- add sg_memalign() and sg_get_page_size()
+ - add hex2stdout(), hex2stderr() and hex2str()
- implement 'format' argument in dStrHexStr()
- add read buffer(16) command mode names
- add Microcode activation sense descriptor spc5r10
@@ -142,6 +143,8 @@ Changelog for sg3_utils-1.43 [20180112] [svn: r744]
- move some testing utilities out of the
'examples' and 'utils' directories into the new
'testing' directory
+ - add testing/sg_tst_nvme utility
+ - clean Makefile.freebsd in examples/ and testing/
- gcc 7.2 cleanups (sysmacros.h etc)
- clang --analyze static checker clean ups
- shellcheck cleanup on scripts
diff --git a/configure b/configure
index 1ddb0cd3..0cd29887 100755
--- a/configure
+++ b/configure
@@ -12530,7 +12530,8 @@ _ACEOF
cat >>confdefs.h <<_ACEOF
#define SG_LIB_MINGW 1
_ACEOF
-;;
+
+ CFLAGS="$CFLAGS -D__USE_MINGW_ANSI_STDIO";;
*-*-linux-gnu* | *-*-linux* | *)
cat >>confdefs.h <<_ACEOF
diff --git a/configure.ac b/configure.ac
index b1d1f4fd..02d76a45 100644
--- a/configure.ac
+++ b/configure.ac
@@ -66,7 +66,8 @@ case "${host}" in
CFLAGS="$CFLAGS -Wno-char-subscripts";;
*-*-mingw*)
AC_DEFINE_UNQUOTED(SG_LIB_WIN32, 1, [sg3_utils on Win32])
- AC_DEFINE_UNQUOTED(SG_LIB_MINGW, 1, [also MinGW environment]);;
+ AC_DEFINE_UNQUOTED(SG_LIB_MINGW, 1, [also MinGW environment])
+ CFLAGS="$CFLAGS -D__USE_MINGW_ANSI_STDIO";;
*-*-linux-gnu* | *-*-linux* | *)
AC_DEFINE_UNQUOTED(SG_LIB_LINUX, 1, [sg3_utils on linux])
check_for_linux_nvme_headers;;
diff --git a/debian/changelog b/debian/changelog
index da81096c..fd57db84 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -2,7 +2,7 @@ sg3-utils (1.43-0.1) unstable; urgency=low
* New upstream version
- -- Douglas Gilbert <dgilbert@interlog.com> Sat, 13 Jan 2018 01:00:00 -0500
+ -- Douglas Gilbert <dgilbert@interlog.com> Thu, 18 Jan 2018 14:00:00 -0500
sg3-utils (1.42-0.1) unstable; urgency=low
diff --git a/examples/Makefile b/examples/Makefile
index cd8920d8..1501850f 100644
--- a/examples/Makefile
+++ b/examples/Makefile
@@ -4,8 +4,15 @@ PREFIX=/usr/local
INSTDIR=$(DESTDIR)/$(PREFIX)/bin
MANDIR=$(DESTDIR)/$(PREFIX)/man
+# In Linux the default C compiler is GCC while in FreeBSD (since release 10 ?)
+# the default C compiler is clang. Swap the comment marks (lines starting
+# with '#') on the next 4 (non-blank) lines.
CC = gcc
+# CC = clang
+
LD = gcc
+# LD = clang
+
EXECS = sg_simple1 sg_simple2 sg_simple3 sg_simple4 sg_simple16 \
scsi_inquiry sg_excl sg_simple5 sg__sat_identify \
@@ -107,6 +114,11 @@ uninstall:
rm -f $(MANDIR)/$(MAN_PREF)/$$mp.gz; \
done
+# Linux uses GNU make and FreeBSD uses Berkely make. The following lines
+# only work in Linux. Possible solutions in FreeBSD:
+# a) use 'gmake'; b) comment out the next 3 lines, starting with 'ifeq'
+# c) build with 'make -f Makefile.freebsd'
+# In Linux one can install bmake (but that won't help here).
ifeq (.depend,$(wildcard .depend))
include .depend
endif
diff --git a/examples/Makefile.freebsd b/examples/Makefile.freebsd
index 7b90aa97..86d48cc7 100644
--- a/examples/Makefile.freebsd
+++ b/examples/Makefile.freebsd
@@ -4,51 +4,62 @@ PREFIX=/usr/local
INSTDIR=$(DESTDIR)/$(PREFIX)/bin
MANDIR=$(DESTDIR)/$(PREFIX)/man
-CC = gcc
-LD = gcc
+# In Linux the default C compiler is GCC while in FreeBSD (since release 10 ?)
+# the default C compiler is clang. Swap the comment marks (lines starting
+# with '#') on the next 4 (non-blank) lines.
+# CC = gcc
+CC = clang
+
+# LD = gcc
+LD = clang
+
EXECS = sg_simple5
-MAN_PGS =
+# EXTRAS = sgq_dd
+
+MAN_PGS =
MAN_PREF = man8
OS_FLAGS = -DSG_LIB_FREEBSD
EXTRA_FLAGS = $(OS_FLAGS)
-# CFLAGS = -O2 -Wall -W $(EXTRA_FLAGS)
-CFLAGS = -g -O2 -Wall -W $(EXTRA_FLAGS)
-# CFLAGS = -g -O2 -Wall -W -pedantic -std=c99 $(EXTRA_FLAGS)
+# CFLAGS = -O2 -Wall -W $(EXTRA_FLAGS) -I ../include
+CFLAGS = -g -O2 -Wall -W $(EXTRA_FLAGS) -I ../include
+# CFLAGS = -g -O2 -Wall -W -pedantic -std=c99 $(EXTRA_FLAGS) -I ../include
CFLAGS_PTHREADS = -D_REENTRANT
# there is no rule to make the following in the parent directory,
# it is assumed they are already built.
-D_FILES = ../lib/sg_lib.o ../lib/sg_lib_data.o ../lib/sg_pt_freebsd.o
+D_FILES = ../lib/sg_lib.o ../lib/sg_lib_data.o ../lib/sg_cmds_basic.o ../lib/sg_pt_common.o ../lib/sg_pt_freebsd.o
LDFLAGS = -lcam
-# LDFLAGS = -v -lm
all: $(EXECS)
+extras: $(EXTRAS)
+
+
depend dep:
for i in *.c; do $(CC) $(INCLUDES) $(CFLAGS) -M $$i; \
done > .depend
clean:
- /bin/rm -f *.o $(EXECS) core* .depend *.a *.la *.lo
- /bin/rm -rf .libs
+ /bin/rm -f *.o $(EXECS) $(EXTRAS) core .depend
sg_simple5: sg_simple5.o $(D_FILES)
$(LD) -o $@ $(LDFLAGS) $@.o $(D_FILES)
+
install: $(EXECS)
install -d $(INSTDIR)
- for name in $(EXECS); \
- do install -s -m 755 $$name $(INSTDIR); \
+ for name in $^; \
+ do install -s -o root -g root -m 755 $$name $(INSTDIR); \
done
install -d $(MANDIR)/$(MAN_PREF)
for mp in $(MAN_PGS); \
- do install -m 644 $$mp $(MANDIR)/$(MAN_PREF); \
+ do install -o root -g root -m 644 $$mp $(MANDIR)/$(MAN_PREF); \
gzip -9f $(MANDIR)/$(MAN_PREF)/$$mp; \
done
@@ -61,3 +72,11 @@ uninstall:
rm -f $(MANDIR)/$(MAN_PREF)/$$mp.gz; \
done
+# Linux uses GNU make and FreeBSD uses Berkely make. The following lines
+# only work in Linux. Possible solutions in FreeBSD:
+# a) use 'gmake'; b) comment out the next 3 lines, starting with 'ifeq'
+# c) build with 'make -f Makefile.freebsd'
+# In Linux one can install bmake (but that won't help here).
+# ifeq (.depend,$(wildcard .depend))
+# include .depend
+# endif
diff --git a/include/sg_lib.h b/include/sg_lib.h
index 28a5feb7..0f12b107 100644
--- a/include/sg_lib.h
+++ b/include/sg_lib.h
@@ -2,7 +2,7 @@
#define SG_LIB_H
/*
- * Copyright (c) 2004-2017 Douglas Gilbert.
+ * Copyright (c) 2004-2018 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.
@@ -335,9 +335,9 @@ bool sg_is_scsi_cdb(const uint8_t * cdbp, int clen);
* Returns 'buff'. Does nothing if buff_len<=0 or if buff is NULL.*/
char * sg_get_nvme_cmd_status_str(uint16_t sct_sc, int buff_len, char * buff);
-/* Attempts to map NVMe status value (SCT and SC) to SCSI status, sense_key,
- * asc and ascq tuple. If successful returns true and writes to non-NULL
- * pointer arguments; otherwise returns false. */
+/* Attempts to map NVMe status value ((SCT << 8) | SC) n sct_sc to a SCSI
+ * status, sense_key, asc and ascq tuple. If successful returns true and
+ * writes to non-NULL pointer arguments; otherwise returns false. */
bool sg_nvme_status2scsi(uint16_t sct_sc, uint8_t * status_p, uint8_t * sk_p,
uint8_t * asc_p, uint8_t * ascq_p);
@@ -483,6 +483,15 @@ void dStrHexErr(const char * str, int len, int no_ascii);
int dStrHexStr(const char * str, int len, const char * leadin, int format,
int b_len, char * b);
+/* The following 3 functions are equivalent to dStrHex(), dStrHexErr() and
+ * dStrHexStr() respectively. The difference is the type of the first of
+ * argument: uint8_t instead of char. The name of the argument is changed
+ * to b_str to stress it is a pointer to the start of a binary string. */
+void hex2stdout(const uint8_t * b_str, int len, int no_ascii);
+void hex2stderr(const uint8_t * b_str, int len, int no_ascii);
+int hex2str(const uint8_t * b_str, int len, const char * leadin, int format,
+ int b_len, char * b);
+
/* Returns true when executed on big endian machine; else returns false.
* Useful for displaying ATA identify words (which need swapping on a
* big endian machine).
diff --git a/include/sg_pt.h b/include/sg_pt.h
index d11bae26..b3f669f6 100644
--- a/include/sg_pt.h
+++ b/include/sg_pt.h
@@ -2,7 +2,7 @@
#define SG_PT_H
/*
- * Copyright (c) 2005-2017 Douglas Gilbert.
+ * Copyright (c) 2005-2018 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.
@@ -121,6 +121,7 @@ void set_scsi_pt_flags(struct sg_pt_base * objp, int flags);
#define SCSI_PT_DO_START_OK 0
#define SCSI_PT_DO_BAD_PARAMS 1
#define SCSI_PT_DO_TIMEOUT 2
+#define SCSI_PT_DO_NVME_STATUS 48 /* == SG_LIB_NVME_STATUS */
/* If OS error prior to or during command submission then returns negated
* error value (e.g. Unix '-errno'). This includes interrupted system calls
* (e.g. by a signal) in which case -EINTR would be returned. Note that
@@ -145,12 +146,14 @@ int get_scsi_pt_result_category(const struct sg_pt_base * objp);
* the device is 'dxfer_ilen - get_scsi_pt_len()' bytes. */
int get_scsi_pt_resid(const struct sg_pt_base * objp);
-/* Returns SCSI status value (from device that received the
- command). */
+/* Returns SCSI status value (from device that received the command). If an
+ * NVMe command was issued directly (i.e. through do_scsi_pt() then return
+ * NVMe status (i.e. ((SCT << 8) | SC)) */
int get_scsi_pt_status_response(const struct sg_pt_base * objp);
-/* Returns SCSI status value or NVMe result (from device that received the
- command). */
+/* Returns SCSI status value or, if NVMe command given to do_scsi_pt(),
+ * then returns NVMe result (i.e. DWord(0) from completion queue). If
+ * 'objp' is NULL then returns 0xffffffff. */
uint32_t get_pt_result(const struct sg_pt_base * objp);
/* Actual sense length returned. If sense data is present but
diff --git a/include/sg_pt_linux.h b/include/sg_pt_linux.h
index c7447726..0ad38d81 100644
--- a/include/sg_pt_linux.h
+++ b/include/sg_pt_linux.h
@@ -96,7 +96,8 @@ struct sg_pt_linux_scsi {
/* Leave io_hdr in first place of this structure */
bool is_sg;
bool is_bsg;
- bool is_nvme;
+ bool is_nvme; /* OS device type, if false ignore nvme_direct */
+ bool nvme_direct; /* false: our SNTL; true: received NVMe command */
bool mdxfer_out; /* direction of metadata xfer, true->data-out */
bool scsi_dsense; /* SCSI descriptor sense active when true */
int dev_fd; /* -1 if not given (yet) */
diff --git a/include/sg_pt_nvme.h b/include/sg_pt_nvme.h
index 9de39f43..fc365343 100644
--- a/include/sg_pt_nvme.h
+++ b/include/sg_pt_nvme.h
@@ -2,7 +2,7 @@
#define SG_PT_NVME_H
/*
- * Copyright (c) 2017 Douglas Gilbert.
+ * Copyright (c) 2017-2018 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.
@@ -104,7 +104,7 @@ struct sg_nvme_passthru_cmd
uint32_t cdw15;
#ifdef SG_LIB_LINUX
uint32_t timeout_ms;
- uint32_t result; /* DWord(0) of completion queue entry */
+ uint32_t result; /* out: DWord(0) from completion queue */
#endif
}
#ifdef SG_LIB_FREEBSD
@@ -141,6 +141,10 @@ __packed;
#define SG_NVME_PT_RESULT 68 /* length: 4 bytes */
#endif
+/* Byte offset of Result and Status (plus phase bit) in CQ */
+#define SG_NVME_PT_CQ_RESULT 0 /* CDW0, length: 4 bytes */
+#define SG_NVME_PT_CQ_STATUS_P 14 /* CDW3 31:16, length: 2 bytes */
+
/* Valid namespace IDs (nsid_s) range from 1 to 0xfffffffe, leaving: */
#define SG_NVME_BROADCAST_NSID 0xffffffff /* all namespaces */
diff --git a/lib/Makefile.am b/lib/Makefile.am
index b8be482a..31004776 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -44,6 +44,7 @@ endif
# -Wall is no longer all warnings. Add -W (since renamed to -Wextra) for more
AM_CPPFLAGS = -iquote ${top_srcdir}/include -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64
AM_CFLAGS = -Wall -W
+# AM_CFLAGS = -Wall -W -Wextra -Wmisleading-indentation -Wduplicated-cond -Wduplicated-branches -Wlogical-op -Wnull-dereference -Wshadow -Wjump-misses-init
# AM_CFLAGS = -Wall -W -pedantic -std=c11
# AM_CFLAGS = -Wall -W -pedantic -std=c11 --analyze
# AM_CFLAGS = -Wall -W -pedantic -std=c++14
diff --git a/lib/Makefile.in b/lib/Makefile.in
index 36465e79..13f243e0 100644
--- a/lib/Makefile.in
+++ b/lib/Makefile.in
@@ -354,6 +354,7 @@ libsgutils2_la_SOURCES = sg_lib.c sg_lib_data.c sg_cmds_basic.c \
# -Wall is no longer all warnings. Add -W (since renamed to -Wextra) for more
AM_CPPFLAGS = -iquote ${top_srcdir}/include -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64
AM_CFLAGS = -Wall -W
+# AM_CFLAGS = -Wall -W -Wextra -Wmisleading-indentation -Wduplicated-cond -Wduplicated-branches -Wlogical-op -Wnull-dereference -Wshadow -Wjump-misses-init
# AM_CFLAGS = -Wall -W -pedantic -std=c11
# AM_CFLAGS = -Wall -W -pedantic -std=c11 --analyze
# AM_CFLAGS = -Wall -W -pedantic -std=c++14
diff --git a/lib/sg_cmds_basic.c b/lib/sg_cmds_basic.c
index 2f0cbac0..cf5dfbc2 100644
--- a/lib/sg_cmds_basic.c
+++ b/lib/sg_cmds_basic.c
@@ -36,7 +36,7 @@
#endif
-static const char * const version_str = "1.79 20180112";
+static const char * const version_str = "1.80 20180117";
#define SENSE_BUFF_LEN 64 /* Arbitrary, could be larger */
@@ -351,7 +351,7 @@ sg_ll_inquiry(int sg_fd, bool cmddt, bool evpd, int pg_op, void * resp,
if (evpd)
inq_cdb[1] |= 1;
inq_cdb[2] = (unsigned char)pg_op;
- /* 16 bit allocation length (was 8) is a recent SPC-3 addition */
+ /* 16 bit allocation length (was 8, increased in spc3r09, September 2002) */
sg_put_unaligned_be16((uint16_t)mx_resp_len, inq_cdb + 3);
if (verbose) {
pr2ws(" %s cdb: ", inquiry_s);
@@ -502,7 +502,7 @@ sg_ll_inquiry_v2(int sg_fd, bool evpd, int pg_op, void * resp,
if (evpd)
inq_cdb[1] |= 1;
inq_cdb[2] = (unsigned char)pg_op;
- /* 16 bit allocation length (was 8) is a recent SPC-3 addition */
+ /* 16 bit allocation length (was 8, increased in spc3r09, September 2002) */
sg_put_unaligned_be16((uint16_t)mx_resp_len, inq_cdb + 3);
if (verbose) {
pr2ws(" inquiry cdb: ");
diff --git a/lib/sg_cmds_basic2.c b/lib/sg_cmds_basic2.c
index f3cd379a..cf7b1240 100644
--- a/lib/sg_cmds_basic2.c
+++ b/lib/sg_cmds_basic2.c
@@ -313,10 +313,10 @@ sg_ll_mode_sense6(int sg_fd, bool dbd, int pc, int pg_code, int sub_pg_code,
pr2ws(" %s: response", cdb_name_s);
if (3 == verbose) {
pr2ws("%s:\n", (ret > 256 ? ", first 256 bytes" : ""));
- dStrHexErr((const char *)resp, (ret > 256 ? 256 : ret), -1);
+ hex2stderr(resp, (ret > 256 ? 256 : ret), -1);
} else {
pr2ws(":\n");
- dStrHexErr((const char *)resp, ret, 0);
+ hex2stderr(resp, ret, 0);
}
}
ret = 0;
@@ -412,10 +412,10 @@ sg_ll_mode_sense10_v2(int sg_fd, bool llbaa, bool dbd, int pc, int pg_code,
pr2ws(" %s: response", cdb_name_s);
if (3 == verbose) {
pr2ws("%s:\n", (ret > 256 ? ", first 256 bytes" : ""));
- dStrHexErr((const char *)resp, (ret > 256 ? 256 : ret), -1);
+ hex2stderr(resp, (ret > 256 ? 256 : ret), -1);
} else {
pr2ws(":\n");
- dStrHexErr((const char *)resp, ret, 0);
+ hex2stderr(resp, ret, 0);
}
}
ret = 0;
@@ -464,7 +464,7 @@ sg_ll_mode_select6(int sg_fd, bool pf, bool sp, void * paramp, int param_len,
}
if (verbose > 1) {
pr2ws(" %s parameter list\n", cdb_name_s);
- dStrHexErr((const char *)paramp, param_len, -1);
+ hex2stderr(paramp, param_len, -1);
}
if (NULL == ((ptvp = create_pt_obj(cdb_name_s))))
@@ -521,7 +521,7 @@ sg_ll_mode_select10(int sg_fd, bool pf, bool sp, void * paramp, int param_len,
}
if (verbose > 1) {
pr2ws(" %s parameter list\n", cdb_name_s);
- dStrHexErr((const char *)paramp, param_len, -1);
+ hex2stderr(paramp, param_len, -1);
}
if (NULL == ((ptvp = create_pt_obj(cdb_name_s))))
@@ -890,7 +890,7 @@ sg_ll_log_select(int sg_fd, bool pcr, bool sp, int pc, int pg_code,
}
if ((verbose > 1) && (param_len > 0)) {
pr2ws(" %s parameter list\n", cdb_name_s);
- dStrHexErr((const char *)paramp, param_len, -1);
+ hex2stderr(paramp, param_len, -1);
}
if (NULL == ((ptvp = create_pt_obj(cdb_name_s))))
diff --git a/lib/sg_cmds_extra.c b/lib/sg_cmds_extra.c
index a6072c95..9b3a3eff 100644
--- a/lib/sg_cmds_extra.c
+++ b/lib/sg_cmds_extra.c
@@ -175,10 +175,10 @@ sg_ll_get_lba_status16(int sg_fd, uint64_t start_llba, uint8_t rt,
pr2ws(" %s: response\n", cdb_name_s);
if (3 == verbose) {
pr2ws("%s:\n", (ret > 256 ? ", first 256 bytes" : ""));
- dStrHexErr((const char *)resp, (ret > 256 ? 256 : ret), -1);
+ hex2stderr(resp, (ret > 256 ? 256 : ret), -1);
} else {
pr2ws(":\n");
- dStrHexErr((const char *)resp, ret, 0);
+ hex2stderr(resp, ret, 0);
}
}
ret = 0;
@@ -250,10 +250,10 @@ sg_ll_get_lba_status32(int sg_fd, uint64_t start_llba, uint32_t scan_len,
pr2ws(" %s: response\n", cdb_name_s);
if (3 == verbose) {
pr2ws("%s:\n", (ret > 256 ? ", first 256 bytes" : ""));
- dStrHexErr((const char *)resp, (ret > 256 ? 256 : ret), -1);
+ hex2stderr(resp, (ret > 256 ? 256 : ret), -1);
} else {
pr2ws(":\n");
- dStrHexErr((const char *)resp, ret, 0);
+ hex2stderr(resp, ret, 0);
}
}
ret = 0;
@@ -319,10 +319,10 @@ sg_ll_report_tgt_prt_grp2(int sg_fd, void * resp, int mx_resp_len,
pr2ws(" %s: response", cdb_name_s);
if (3 == verbose) {
pr2ws("%s:\n", (ret > 256 ? ", first 256 bytes" : ""));
- dStrHexErr((const char *)resp, (ret > 256 ? 256 : ret), -1);
+ hex2stderr(resp, (ret > 256 ? 256 : ret), -1);
} else {
pr2ws(":\n");
- dStrHexErr((const char *)resp, ret, 0);
+ hex2stderr(resp, ret, 0);
}
}
ret = 0;
@@ -353,7 +353,7 @@ sg_ll_set_tgt_prt_grp(int sg_fd, void * paramp, int param_len, bool noisy,
pr2ws("\n");
if ((verbose > 1) && paramp && param_len) {
pr2ws(" %s parameter list:\n", cdb_name_s);
- dStrHexErr((const char *)paramp, param_len, -1);
+ hex2stderr(paramp, param_len, -1);
}
}
@@ -434,10 +434,10 @@ sg_ll_report_referrals(int sg_fd, uint64_t start_llba, bool one_seg,
pr2ws(" %s: response", cdb_name_s);
if (3 == verbose) {
pr2ws("%s:\n", (ret > 256 ? ", first 256 bytes" : ""));
- dStrHexErr((const char *)resp, (ret > 256 ? 256 : ret), -1);
+ hex2stderr(resp, (ret > 256 ? 256 : ret), -1);
} else {
pr2ws(":\n");
- dStrHexErr((const char *)resp, ret, 0);
+ hex2stderr(resp, ret, 0);
}
}
ret = 0;
@@ -486,7 +486,7 @@ sg_ll_send_diag(int sg_fd, int st_code, bool pf_bit, bool st_bit,
if (verbose > 1) {
if (paramp && param_len) {
pr2ws(" %s parameter list:\n", cdb_name_s);
- dStrHexErr((const char *)paramp, param_len, -1);
+ hex2stderr(paramp, param_len, -1);
}
pr2ws(" %s timeout: %d seconds\n", cdb_name_s, tmout);
}
@@ -589,10 +589,10 @@ sg_ll_receive_diag_v2(int sg_fd, bool pcv, int pg_code, void * resp,
pr2ws(" %s: response", cdb_name_s);
if (3 == verbose) {
pr2ws("%s:\n", (ret > 256 ? ", first 256 bytes" : ""));
- dStrHexErr((const char *)resp, (ret > 256 ? 256 : ret), -1);
+ hex2stderr(resp, (ret > 256 ? 256 : ret), -1);
} else {
pr2ws(":\n");
- dStrHexErr((const char *)resp, ret, 0);
+ hex2stderr(resp, ret, 0);
}
}
ret = 0;
@@ -656,10 +656,10 @@ sg_ll_read_defect10(int sg_fd, bool req_plist, bool req_glist, int dl_format,
pr2ws(" %s: response\n", cdb_name_s);
if (3 == verbose) {
pr2ws("%s:\n", (ret > 256 ? ", first 256 bytes" : ""));
- dStrHexErr((const char *)resp, (ret > 256 ? 256 : ret), -1);
+ hex2stderr(resp, (ret > 256 ? 256 : ret), -1);
} else {
pr2ws(":\n");
- dStrHexErr((const char *)resp, ret, 0);
+ hex2stderr(resp, ret, 0);
}
}
ret = 0;
@@ -715,10 +715,10 @@ sg_ll_read_media_serial_num(int sg_fd, void * resp, int mx_resp_len,
pr2ws(" %s: response", cdb_name_s);
if (3 == verbose) {
pr2ws("%s:\n", (ret > 256 ? ", first 256 bytes" : ""));
- dStrHexErr((const char *)resp, (ret > 256 ? 256 : ret), -1);
+ hex2stderr(resp, (ret > 256 ? 256 : ret), -1);
} else {
pr2ws(":\n");
- dStrHexErr((const char *)resp, ret, 0);
+ hex2stderr(resp, ret, 0);
}
}
ret = 0;
@@ -777,10 +777,10 @@ sg_ll_report_id_info(int sg_fd, int itype, void * resp, int max_resp_len,
pr2ws(" %s: response", cdb_name_s);
if (3 == verbose) {
pr2ws("%s:\n", (ret > 256 ? ", first 256 bytes" : ""));
- dStrHexErr((const char *)resp, (ret > 256 ? 256 : ret), -1);
+ hex2stderr(resp, (ret > 256 ? 256 : ret), -1);
} else {
pr2ws(":\n");
- dStrHexErr((const char *)resp, ret, 0);
+ hex2stderr(resp, ret, 0);
}
}
ret = 0;
@@ -813,7 +813,7 @@ sg_ll_set_id_info(int sg_fd, int itype, void * paramp, int param_len,
pr2ws("\n");
if ((verbose > 1) && paramp && param_len) {
pr2ws(" %s parameter list:\n", cdb_name_s);
- dStrHexErr((const char *)paramp, param_len, -1);
+ hex2stderr(paramp, param_len, -1);
}
}
@@ -905,7 +905,7 @@ sg_ll_format_unit_v2(int sg_fd, int fmtpinfo, bool longlist, bool fmtdata,
if (verbose > 1) {
if (param_len > 0) {
pr2ws(" %s parameter list:\n", cdb_name_s);
- dStrHexErr((const char *)paramp, param_len, -1);
+ hex2stderr(paramp, param_len, -1);
}
pr2ws(" %s timeout: %d seconds\n", cdb_name_s, tmout);
}
@@ -963,7 +963,7 @@ sg_ll_reassign_blocks(int sg_fd, bool longlba, bool longlist, void * paramp,
}
if (verbose > 1) {
pr2ws(" %s parameter list\n", cdb_name_s);
- dStrHexErr((const char *)paramp, param_len, -1);
+ hex2stderr(paramp, param_len, -1);
}
if (NULL == ((ptvp = create_pt_obj(cdb_name_s))))
@@ -1043,10 +1043,10 @@ sg_ll_persistent_reserve_in(int sg_fd, int rq_servact, void * resp,
pr2ws(" %s: response", cdb_name_s);
if (3 == verbose) {
pr2ws("%s:\n", (ret > 256 ? ", first 256 bytes" : ""));
- dStrHexErr((const char *)resp, (ret > 256 ? 256 : ret), -1);
+ hex2stderr(resp, (ret > 256 ? 256 : ret), -1);
} else {
pr2ws(":\n");
- dStrHexErr((const char *)resp, ret, 0);
+ hex2stderr(resp, ret, 0);
}
}
ret = 0;
@@ -1082,7 +1082,7 @@ sg_ll_persistent_reserve_out(int sg_fd, int rq_servact, int rq_scope,
pr2ws("\n");
if (verbose > 1) {
pr2ws(" %s parameters:\n", cdb_name_s);
- dStrHexErr((const char *)paramp, param_len, 0);
+ hex2stderr(paramp, param_len, 0);
}
}
@@ -1207,10 +1207,10 @@ sg_ll_read_long10(int sg_fd, bool pblock, bool correct, unsigned int lba,
pr2ws(" %s: response", cdb_name_s);
if (3 == verbose) {
pr2ws("%s:\n", (ret > 256 ? ", first 256 bytes" : ""));
- dStrHexErr((const char *)resp, (ret > 256 ? 256 : ret), -1);
+ hex2stderr(resp, (ret > 256 ? 256 : ret), -1);
} else {
pr2ws(":\n");
- dStrHexErr((const char *)resp, ret, 0);
+ hex2stderr(resp, ret, 0);
}
}
ret = 0;
@@ -1296,10 +1296,10 @@ sg_ll_read_long16(int sg_fd, bool pblock, bool correct, uint64_t llba,
pr2ws(" %s: response", cdb_name_s);
if (3 == verbose) {
pr2ws("%s:\n", (ret > 256 ? ", first 256 bytes" : ""));
- dStrHexErr((const char *)resp, (ret > 256 ? 256 : ret), -1);
+ hex2stderr(resp, (ret > 256 ? 256 : ret), -1);
} else {
pr2ws(":\n");
- dStrHexErr((const char *)resp, ret, 0);
+ hex2stderr(resp, ret, 0);
}
}
ret = 0;
@@ -1500,7 +1500,7 @@ sg_ll_verify10(int sg_fd, int vrprotect, bool dpo, int bytchk,
k = data_out_len > 4104 ? 4104 : data_out_len;
pr2ws(" data_out buffer%s\n",
(data_out_len > 4104 ? ", first 4104 bytes" : ""));
- dStrHexErr((const char *)data_out, k, verbose < 5);
+ hex2stderr(data_out, k, verbose < 5);
}
}
if (NULL == ((ptvp = create_pt_obj(cdb_name_s))))
@@ -1578,7 +1578,7 @@ sg_ll_verify16(int sg_fd, int vrprotect, bool dpo, int bytchk, uint64_t llba,
k = data_out_len > 4104 ? 4104 : data_out_len;
pr2ws(" data_out buffer%s\n",
(data_out_len > 4104 ? ", first 4104 bytes" : ""));
- dStrHexErr((const char *)data_out, k, verbose < 5);
+ hex2stderr(data_out, k, verbose < 5);
}
}
if (NULL == ((ptvp = create_pt_obj(cdb_name_s))))
@@ -1707,7 +1707,7 @@ sg_ll_ata_pt(int sg_fd, const unsigned char * cdbp, int cdb_len,
pr2ws("\n");
} else {
pr2ws("\n");
- dStrHexErr((const char *)apt_cdb, cdb_len, -1);
+ hex2stderr(apt_cdb, cdb_len, -1);
}
}
if (NULL == ((ptvp = create_pt_obj(cnamep))))
@@ -1847,10 +1847,10 @@ sg_ll_read_buffer(int sg_fd, int mode, int buffer_id, int buffer_offset,
pr2ws(" %s: response", cdb_name_s);
if (3 == verbose) {
pr2ws("%s:\n", (ret > 256 ? ", first 256 bytes" : ""));
- dStrHexErr((const char *)resp, (ret > 256 ? 256 : ret), -1);
+ hex2stderr(resp, (ret > 256 ? 256 : ret), -1);
} else {
pr2ws(":\n");
- dStrHexErr((const char *)resp, ret, 0);
+ hex2stderr(resp, ret, 0);
}
}
ret = 0;
@@ -1885,11 +1885,10 @@ sg_ll_write_buffer(int sg_fd, int mode, int buffer_id, int buffer_offset,
pr2ws(" %s parameter list", cdb_name_s);
if (2 == verbose) {
pr2ws("%s:\n", (param_len > 256 ? ", first 256 bytes" : ""));
- dStrHexErr((const char *)paramp,
- (param_len > 256 ? 256 : param_len), -1);
+ hex2stderr(paramp, (param_len > 256 ? 256 : param_len), -1);
} else {
pr2ws(":\n");
- dStrHexErr((const char *)paramp, param_len, 0);
+ hex2stderr(paramp, param_len, 0);
}
}
}
@@ -1961,8 +1960,7 @@ sg_ll_write_buffer_v2(int sg_fd, int mode, int m_specific, int buffer_id,
if ((verbose > 1) && paramp && param_len) {
pr2ws(" Write buffer parameter list%s:\n",
((param_len > 256) ? " (first 256 bytes)" : ""));
- dStrHexErr((const char *)paramp,
- ((param_len > 256) ? 256 : param_len), -1);
+ hex2stderr(paramp, ((param_len > 256) ? 256 : param_len), -1);
}
}
if (timeout_secs <= 0)
@@ -2033,7 +2031,7 @@ sg_ll_unmap_v2(int sg_fd, bool anchor, int group_num, int timeout_secs,
pr2ws("\n");
if ((verbose > 1) && paramp && param_len) {
pr2ws(" %s parameter list:\n", cdb_name_s);
- dStrHexErr((const char *)paramp, param_len, -1);
+ hex2stderr(paramp, param_len, -1);
}
}
@@ -2108,10 +2106,10 @@ sg_ll_read_block_limits(int sg_fd, void * resp, int mx_resp_len,
pr2ws(" %s: response", cdb_name_s);
if (3 == verbose) {
pr2ws("%s:\n", (ret > 256 ? ", first 256 bytes" : ""));
- dStrHexErr((const char *)resp, (ret > 256 ? 256 : ret), -1);
+ hex2stderr(resp, (ret > 256 ? 256 : ret), -1);
} else {
pr2ws(":\n");
- dStrHexErr((const char *)resp, ret, 0);
+ hex2stderr(resp, ret, 0);
}
}
ret = 0;
@@ -2204,7 +2202,7 @@ sg_ll_extended_copy(int sg_fd, void * paramp, int param_len, bool noisy,
pr2ws("\n");
if ((verbose > 1) && paramp && param_len) {
pr2ws(" %s parameter list:\n", opcode_name);
- dStrHexErr((const char *)paramp, param_len, -1);
+ hex2stderr(paramp, param_len, -1);
}
}
@@ -2281,7 +2279,7 @@ sg_ll_3party_copy_out(int sg_fd, int sa, unsigned int list_id, int group_num,
pr2ws("\n");
if ((verbose > 1) && paramp && param_len) {
pr2ws(" %s parameter list:\n", cname);
- dStrHexErr((const char *)paramp, param_len, -1);
+ hex2stderr(paramp, param_len, -1);
}
}
diff --git a/lib/sg_cmds_mmc.c b/lib/sg_cmds_mmc.c
index 8df15be2..b9bd9ff7 100644
--- a/lib/sg_cmds_mmc.c
+++ b/lib/sg_cmds_mmc.c
@@ -202,10 +202,10 @@ sg_ll_get_config(int sg_fd, int rt, int starting, void * resp,
pr2ws(" %s: response:\n", cdb_name_s);
if (3 == verbose) {
pr2ws("%s:\n", (len > 256 ? ", first 256 bytes" : ""));
- dStrHexErr((const char *)resp, (len > 256 ? 256 : len), -1);
+ hex2stderr(resp, (len > 256 ? 256 : len), -1);
} else {
pr2ws(":\n");
- dStrHexErr((const char *)resp, len, 0);
+ hex2stderr(resp, len, 0);
}
}
ret = 0;
@@ -293,10 +293,10 @@ sg_ll_get_performance(int sg_fd, int data_type, unsigned int starting_lba,
pr2ws(" %s: response", cdb_name_s);
if (3 == verbose) {
pr2ws("%s:\n", (len > 256 ? ", first 256 bytes" : ""));
- dStrHexErr((const char *)resp, (len > 256 ? 256 : len), -1);
+ hex2stderr(resp, (len > 256 ? 256 : len), -1);
} else {
pr2ws(":\n");
- dStrHexErr((const char *)resp, len, 0);
+ hex2stderr(resp, len, 0);
}
}
ret = 0;
@@ -330,7 +330,7 @@ sg_ll_set_streaming(int sg_fd, int type, void * paramp, int param_len,
pr2ws("\n");
if ((verbose > 1) && paramp && param_len) {
pr2ws(" %s parameter list:\n", cdb_name_s);
- dStrHexErr((const char *)paramp, param_len, -1);
+ hex2stderr(paramp, param_len, -1);
}
}
diff --git a/lib/sg_lib.c b/lib/sg_lib.c
index 314a5508..e2685499 100644
--- a/lib/sg_lib.c
+++ b/lib/sg_lib.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999-2017 Douglas Gilbert.
+ * Copyright (c) 1999-2018 Douglas Gilbert.
* All rights reserved.
* Use of this source code is governed by a BSD-style
* license that can be found in the BSD_LICENSE file.
@@ -27,7 +27,7 @@
*
*/
-#define _POSIX_C_SOURCE 200809L /* for posix_memalign() */
+#define _POSIX_C_SOURCE 200809L /* for posix_memalign() */
#define __STDC_FORMAT_MACROS 1
#include <stdio.h>
#include <stdlib.h>
@@ -553,8 +553,7 @@ sg_decode_transportid_str(const char * lip, unsigned char * bp, int bplen,
if (0 != tpid_format)
n += scnpr(b + n, blen - n, "%s [Unexpected TPID format: "
"%d]\n", lip, tpid_format);
- n += dStrHexStr((const char *)bp +8, 8, lip, 1, blen - n,
- b + n);
+ n += hex2str(bp + 8, 8, lip, 1, blen - n, b + n);
bump = TRANSPORT_ID_MIN_LEN;
break;
case TPROTO_SPI: /* Scsi Parallel Interface, obsolete */
@@ -573,8 +572,7 @@ sg_decode_transportid_str(const char * lip, unsigned char * bp, int bplen,
"defined):\n", lip);
n += scnpr(b + n, blen - n, "%s TPID format: %d\n", lip,
tpid_format);
- n += dStrHexStr((const char *)bp, normal_len, lip, 1, blen - n,
- b + n);
+ n += hex2str(bp, normal_len, lip, 1, blen - n, b + n);
bump = TRANSPORT_ID_MIN_LEN;
break;
case TPROTO_1394: /* IEEE 1394 */
@@ -582,8 +580,7 @@ sg_decode_transportid_str(const char * lip, unsigned char * bp, int bplen,
if (0 != tpid_format)
n += scnpr(b + n, blen - n, "%s [Unexpected TPID format: "
"%d]\n", lip, tpid_format);
- n += dStrHexStr((const char *)&bp[8], 8, lip, 1, blen - n,
- b + n);
+ n += hex2str(&bp[8], 8, lip, 1, blen - n, b + n);
bump = TRANSPORT_ID_MIN_LEN;
break;
case TPROTO_SRP: /* SCSI over RDMA */
@@ -592,8 +589,7 @@ sg_decode_transportid_str(const char * lip, unsigned char * bp, int bplen,
if (0 != tpid_format)
n += scnpr(b + n, blen - n, "%s [Unexpected TPID format: "
"%d]\n", lip, tpid_format);
- n += dStrHexStr((const char *)&bp[8], 16, lip, 1, blen - n,
- b + n);
+ n += hex2str(bp + 8, 16, lip, 1, blen - n, b + n);
bump = TRANSPORT_ID_MIN_LEN;
break;
case TPROTO_ISCSI:
@@ -607,8 +603,7 @@ sg_decode_transportid_str(const char * lip, unsigned char * bp, int bplen,
else {
n += scnpr(b + n, blen - n, " [Unexpected TPID format: "
"%d]\n", tpid_format);
- n += dStrHexStr((const char *)bp, num + 4, lip, 0,
- blen - n, b + n);
+ n += hex2str(bp, num + 4, lip, 0, blen - n, b + n);
}
bump = (((num + 4) < TRANSPORT_ID_MIN_LEN) ?
TRANSPORT_ID_MIN_LEN : num + 4);
@@ -626,24 +621,21 @@ sg_decode_transportid_str(const char * lip, unsigned char * bp, int bplen,
n += scnpr(b + n, blen - n, "%s ADT:\n", lip);
n += scnpr(b + n, blen - n, "%s TPID format: %d\n", lip,
tpid_format);
- n += dStrHexStr((const char *)bp, normal_len, lip, 1, blen - n,
- b + n);
+ n += hex2str(bp, normal_len, lip, 1, blen - n, b + n);
bump = TRANSPORT_ID_MIN_LEN;
break;
case TPROTO_ATA: /* no TransportID defined by T10 yet */
n += scnpr(b + n, blen - n, "%s ATAPI:\n", lip);
n += scnpr(b + n, blen - n, "%s TPID format: %d\n", lip,
tpid_format);
- n += dStrHexStr((const char *)bp, normal_len, lip, 1, blen - n,
- b + n);
+ n += hex2str(bp, normal_len, lip, 1, blen - n, b + n);
bump = TRANSPORT_ID_MIN_LEN;
break;
case TPROTO_UAS: /* no TransportID defined by T10 yet */
n += scnpr(b + n, blen - n, "%s UAS:\n", lip);
n += scnpr(b + n, blen - n, "%s TPID format: %d\n", lip,
tpid_format);
- n += dStrHexStr((const char *)bp, normal_len, lip, 1, blen - n,
- b + n);
+ n += hex2str(bp, normal_len, lip, 1, blen - n, b + n);
bump = TRANSPORT_ID_MIN_LEN;
break;
case TPROTO_SOP:
@@ -654,8 +646,7 @@ sg_decode_transportid_str(const char * lip, unsigned char * bp, int bplen,
else {
n += scnpr(b + n, blen - n, " [Unexpected TPID format: "
"%d]\n", tpid_format);
- n += dStrHexStr((const char *)bp, normal_len, lip, 1,
- blen - n, b + n);
+ n += hex2str(bp, normal_len, lip, 1, blen - n, b + n);
}
bump = TRANSPORT_ID_MIN_LEN;
break;
@@ -663,21 +654,19 @@ sg_decode_transportid_str(const char * lip, unsigned char * bp, int bplen,
n += scnpr(b + n, blen - n, "%s PCIE:\n", lip);
n += scnpr(b + n, blen - n, "%s TPID format: %d\n", lip,
tpid_format);
- n += dStrHexStr((const char *)bp, normal_len, lip, 1, blen - n,
- b + n);
+ n += hex2str(bp, normal_len, lip, 1, blen - n, b + n);
bump = TRANSPORT_ID_MIN_LEN;
break;
case TPROTO_NONE: /* no TransportID defined by T10 */
n += scnpr(b + n, blen - n, "%s No specified protocol\n", lip);
- /* n += dStrHexStr((const char *)bp, ((bplen > 24) ? 24 : bplen),
+ /* n += hex2str(bp, ((bplen > 24) ? 24 : bplen),
* lip, 0, blen - n, b + n); */
bump = TRANSPORT_ID_MIN_LEN;
break;
default:
n += scnpr(b + n, blen - n, "%s unknown protocol id=0x%x "
"TPID format=%d\n", lip, proto_id, tpid_format);
- n += dStrHexStr((const char *)bp, normal_len, lip, 1, blen - n,
- b + n);
+ n += hex2str(bp, normal_len, lip, 1, blen - n, b + n);
bump = TRANSPORT_ID_MIN_LEN;
break;
}
@@ -811,7 +800,7 @@ sg_get_designation_descriptor_str(const char * lip, const unsigned char * ddp,
lip, dlen, ip);
else {
n += scnpr(b + n, blen - n, "%s vendor specific:\n", lip);
- n += dStrHexStr((const char *)ip, dlen, lip, 0, blen - n, b + n);
+ n += hex2str(ip, dlen, lip, 0, blen - n, b + n);
}
break;
case 1: /* T10 vendor identification */
@@ -834,8 +823,7 @@ sg_get_designation_descriptor_str(const char * lip, const unsigned char * ddp,
if ((8 != dlen) && (12 != dlen) && (16 != dlen)) {
n += scnpr(b + n, blen - n, "%s << expect 8, 12 and 16 "
"byte EUI, got %d >>\n", lip, dlen);
- n += dStrHexStr((const char *)ip, dlen, lip, 1, blen - n,
- b + n);
+ n += hex2str(ip, dlen, lip, 1, blen - n, b + n);
break;
}
n += scnpr(b + n, blen - n, "%s 0x", lip);
@@ -849,7 +837,7 @@ sg_get_designation_descriptor_str(const char * lip, const unsigned char * ddp,
if (1 != c_set) {
n += scnpr(b + n, blen - n, "%s << expected binary code_set "
"(1) >>\n", lip);
- n += dStrHexStr((const char *)ip, dlen, lip, 1, blen - n, b + n);
+ n += hex2str(ip, dlen, lip, 1, blen - n, b + n);
break;
}
ci_off = 0;
@@ -861,7 +849,7 @@ sg_get_designation_descriptor_str(const char * lip, const unsigned char * ddp,
} else if ((8 != dlen) && (12 != dlen)) {
n += scnpr(b + n, blen - n, "%s << can only decode 8, 12 "
"and 16 byte ids >>\n", lip);
- n += dStrHexStr((const char *)ip, dlen, lip, 1, blen - n, b + n);
+ n += hex2str(ip, dlen, lip, 1, blen - n, b + n);
break;
}
c_id = sg_get_unaligned_be24(ip + ci_off);
@@ -885,7 +873,7 @@ sg_get_designation_descriptor_str(const char * lip, const unsigned char * ddp,
if (1 != c_set) {
n += scnpr(b + n, blen - n, "%s << unexpected code set %d "
"for NAA >>\n", lip, c_set);
- n += dStrHexStr((const char *)ip, dlen, lip, 1, blen - n, b + n);
+ n += hex2str(ip, dlen, lip, 1, blen - n, b + n);
break;
}
naa = (ip[0] >> 4) & 0xff;
@@ -894,8 +882,7 @@ sg_get_designation_descriptor_str(const char * lip, const unsigned char * ddp,
if (8 != dlen) {
n += scnpr(b + n, blen - n, "%s << unexpected NAA 2 "
"identifier length: 0x%x >>\n", lip, dlen);
- n += dStrHexStr((const char *)ip, dlen, lip, 1, blen - n,
- b + n);
+ n += hex2str(ip, dlen, lip, 1, blen - n, b + n);
break;
}
d_id = (((ip[0] & 0xf) << 8) | ip[1]);
@@ -922,8 +909,7 @@ sg_get_designation_descriptor_str(const char * lip, const unsigned char * ddp,
if (8 != dlen) {
n += scnpr(b + n, blen - n, "%s << unexpected NAA 3 "
"identifier length: 0x%x >>\n", lip, dlen);
- n += dStrHexStr((const char *)ip, dlen, lip, 1, blen - n,
- b + n);
+ n += hex2str(ip, dlen, lip, 1, blen - n, b + n);
break;
}
if (do_long)
@@ -938,8 +924,7 @@ sg_get_designation_descriptor_str(const char * lip, const unsigned char * ddp,
if (8 != dlen) {
n += scnpr(b + n, blen - n, "%s << unexpected NAA 5 "
"identifier length: 0x%x >>\n", lip, dlen);
- n += dStrHexStr((const char *)ip, dlen, lip, 1, blen - n,
- b + n);
+ n += hex2str(ip, dlen, lip, 1, blen - n, b + n);
break;
}
c_id = (((ip[0] & 0xf) << 20) | (ip[1] << 12) |
@@ -969,8 +954,7 @@ sg_get_designation_descriptor_str(const char * lip, const unsigned char * ddp,
if (16 != dlen) {
n += scnpr(b + n, blen - n, "%s << unexpected NAA 6 "
"identifier length: 0x%x >>\n", lip, dlen);
- n += dStrHexStr((const char *)ip, dlen, lip, 1, blen - n,
- b + n);
+ n += hex2str(ip, dlen, lip, 1, blen - n, b + n);
break;
}
c_id = (((ip[0] & 0xf) << 20) | (ip[1] << 12) |
@@ -1003,7 +987,7 @@ sg_get_designation_descriptor_str(const char * lip, const unsigned char * ddp,
default:
n += scnpr(b + n, blen - n, "%s << unexpected NAA [0x%x] "
">>\n", lip, naa);
- n += dStrHexStr((const char *)ip, dlen, lip, 1, blen - n, b + n);
+ n += hex2str(ip, dlen, lip, 1, blen - n, b + n);
break;
}
break;
@@ -1012,7 +996,7 @@ sg_get_designation_descriptor_str(const char * lip, const unsigned char * ddp,
n += scnpr(b + n, blen - n, "%s << expected binary "
"code_set, target port association, length 4 >>\n",
lip);
- n += dStrHexStr((const char *)ip, dlen, "", 1, blen - n, b + n);
+ n += hex2str(ip, dlen, "", 1, blen - n, b + n);
break;
}
d_id = sg_get_unaligned_be16(ip + 2);
@@ -1024,7 +1008,7 @@ sg_get_designation_descriptor_str(const char * lip, const unsigned char * ddp,
n += scnpr(b + n, blen - n, "%s << expected binary "
"code_set, target port association, length 4 >>\n",
lip);
- n += dStrHexStr((const char *)ip, dlen, lip, 1, blen - n, b + n);
+ n += hex2str(ip, dlen, lip, 1, blen - n, b + n);
break;
}
d_id = sg_get_unaligned_be16(ip + 2);
@@ -1036,7 +1020,7 @@ sg_get_designation_descriptor_str(const char * lip, const unsigned char * ddp,
n += scnpr(b + n, blen - n, "%s << expected binary "
"code_set, logical unit association, length 4 >>\n",
lip);
- n += dStrHexStr((const char *)ip, dlen, lip, 1, blen - n, b + n);
+ n += hex2str(ip, dlen, lip, 1, blen - n, b + n);
break;
}
d_id = sg_get_unaligned_be16(ip + 2);
@@ -1047,12 +1031,12 @@ sg_get_designation_descriptor_str(const char * lip, const unsigned char * ddp,
if ((1 != c_set) || (0 != assoc)) {
n += scnpr(b + n, blen - n, "%s << expected binary "
"code_set, logical unit association >>\n", lip);
- n += dStrHexStr((const char *)ip, dlen, "", 1, blen - n, b + n);
+ n += hex2str(ip, dlen, "", 1, blen - n, b + n);
break;
}
n += scnpr(b + n, blen - n, "%s MD5 logical unit identifier:\n",
lip);
- n += dStrHexStr((const char *)ip, dlen, lip, 1, blen - n, b + n);
+ n += hex2str(ip, dlen, lip, 1, blen - n, b + n);
break;
case 8: /* SCSI name string */
if (3 != c_set) { /* accept ASCII as subset of UTF-8 */
@@ -1063,8 +1047,7 @@ sg_get_designation_descriptor_str(const char * lip, const unsigned char * ddp,
} else {
n += scnpr(b + n, blen - n, "%s << expected UTF-8 "
"code_set >>\n", lip);
- n += dStrHexStr((const char *)ip, dlen, lip, 0, blen - n,
- b + n);
+ n += hex2str(ip, dlen, lip, 0, blen - n, b + n);
break;
}
}
@@ -1107,13 +1090,13 @@ sg_get_designation_descriptor_str(const char * lip, const unsigned char * ddp,
if (1 != c_set) {
n += scnpr(b + n, blen - n, "%s << expected binary "
"code_set >>\n", lip);
- n += dStrHexStr((const char *)ip, dlen, lip, 0, blen - n, b + n);
+ n += hex2str(ip, dlen, lip, 0, blen - n, b + n);
break;
}
if ((1 != ((ip[0] >> 4) & 0xf)) || (18 != dlen)) {
n += scnpr(b + n, blen - n, "%s << expected locally "
"assigned UUID, 16 bytes long >>\n", lip);
- n += dStrHexStr((const char *)ip, dlen, lip, 0, blen - n, b + n);
+ n += hex2str(ip, dlen, lip, 0, blen - n, b + n);
break;
}
n += scnpr(b + n, blen - n, "%s Locally assigned UUID: ", lip);
@@ -1133,7 +1116,7 @@ sg_get_designation_descriptor_str(const char * lip, const unsigned char * ddp,
default: /* reserved */
n += scnpr(b + n, blen - n, "%s reserved designator=0x%x\n", lip,
desig_type);
- n += dStrHexStr((const char *)ip, dlen, lip, 1, blen - n, b + n);
+ n += hex2str(ip, dlen, lip, 1, blen - n, b + n);
break;
}
return n;
@@ -1825,8 +1808,7 @@ sg_get_sense_str(const char * lip, const unsigned char * sbp, int sb_len,
if (n >= (buff_len - 1))
return n;
scnpr(z, sizeof(z), "%.50s ", lip);
- n += dStrHexStr((const char *)sbp, len, z, 1, buff_len - n,
- buff + n);
+ n += hex2str(sbp, len, z, 1, buff_len - n, buff + n);
}
return n;
}
@@ -2480,9 +2462,9 @@ sg_get_nvme_cmd_status_str(uint16_t sct_sc, int b_len, char * b)
return b;
}
-/* Attempts to map NVMe status value (SCT and SC) to SCSI status, sense_key,
- * asc and ascq tuple. If successful returns true and writes to non-NULL
- * pointer arguments; otherwise returns false. */
+/* Attempts to map NVMe status value ((SCT << 8) | SC) to SCSI status,
+ * sense_key, asc and ascq tuple. If successful returns true and writes to
+ * non-NULL pointer arguments; otherwise returns false. */
bool
sg_nvme_status2scsi(uint16_t sct_sc, uint8_t * status_p, uint8_t * sk_p,
uint8_t * asc_p, uint8_t * ascq_p)
@@ -2589,10 +2571,8 @@ dStrHexFp(const char* str, int len, int no_ascii, FILE * fp)
blen = (int)sizeof(buff);
if (0 == no_ascii) /* address at left and ASCII at right */
formatstr = "%.76s\n";
- else if (no_ascii > 0)
- formatstr = "%s\n"; /* was: "%.58s\n" */
- else /* negative: no address at left and no ASCII at right */
- formatstr = "%s\n"; /* was: "%.48s\n"; */
+ else /* previously when > 0 str was "%.58s\n" */
+ formatstr = "%s\n"; /* when < 0 str was: "%.48s\n" */
memset(buff, ' ', 80);
buff[80] = '\0';
if (no_ascii < 0) {
@@ -2754,6 +2734,25 @@ dStrHexStr(const char * str, int len, const char * leadin, int format,
return n;
}
+void
+hex2stdout(const uint8_t * b_str, int len, int no_ascii)
+{
+ dStrHex((const char *)b_str, len, no_ascii);
+}
+
+void
+hex2stderr(const uint8_t * b_str, int len, int no_ascii)
+{
+ dStrHexErr((const char *)b_str, len, no_ascii);
+}
+
+int
+hex2str(const uint8_t * b_str, int len, const char * leadin, int format,
+ int b_len, char * b)
+{
+ return dStrHexStr((const char *)b_str, len, leadin, format, b_len, b);
+}
+
/* Returns true when executed on big endian machine; else returns false.
* Useful for displaying ATA identify words (which need swapping on a
* big endian machine). */
diff --git a/lib/sg_lib_data.c b/lib/sg_lib_data.c
index 5ac4a9bb..9e34e075 100644
--- a/lib/sg_lib_data.c
+++ b/lib/sg_lib_data.c
@@ -17,7 +17,7 @@
#include "sg_lib_data.h"
-const char * sg_lib_version_str = "2.37 20180109";/* spc5r17, sbc4r15 */
+const char * sg_lib_version_str = "2.38 20180118";/* spc5r17, sbc4r15 */
/* indexed by pdt; those that map to own index do not decay */
diff --git a/lib/sg_pt_common.c b/lib/sg_pt_common.c
index ca053aa7..85bc1917 100644
--- a/lib/sg_pt_common.c
+++ b/lib/sg_pt_common.c
@@ -24,7 +24,7 @@
#include "sg_pt_nvme.h"
-static const char * scsi_pt_version_str = "3.02 20180104";
+static const char * scsi_pt_version_str = "3.03 20180115";
static const char * nvme_scsi_vendor_str = "NVMe ";
diff --git a/lib/sg_pt_freebsd.c b/lib/sg_pt_freebsd.c
index efad6d12..b764738c 100644
--- a/lib/sg_pt_freebsd.c
+++ b/lib/sg_pt_freebsd.c
@@ -5,7 +5,7 @@
* license that can be found in the BSD_LICENSE file.
*/
-/* sg_pt_freebsd version 1.22 20180112 */
+/* sg_pt_freebsd version 1.23 20180115 */
#include <stdio.h>
#include <stdlib.h>
@@ -54,7 +54,8 @@
struct freebsd_dev_channel {
int unitnum; // the SCSI unit number
- bool is_nvme;
+ bool is_nvme; /* OS device type, if false ignore nvme_direct */
+ bool nvme_direct; /* false: our SNTL; true: received NVMe command */
bool is_char;
uint32_t nsid;
uint32_t nv_ctrlid;
@@ -65,6 +66,7 @@ struct freebsd_dev_channel {
struct cam_device* cam_dev;
uint8_t * nvme_id_ctlp;
uint8_t * free_nvme_id_ctlp;
+ uint8_t cq_dw0_3[16];
};
// Private table of open devices: guaranteed zero on startup since
@@ -102,6 +104,7 @@ struct sg_pt_freebsd_scsi {
// (dev_han - FREEBSD_FDOFFSET) is the
// index into devicetable[]
bool is_nvme; // copy of same field in fdc object
+ bool nvme_direct; // copy of same field in fdc object
};
struct sg_pt_base {
@@ -248,6 +251,7 @@ scsi_pt_open_flags(const char * device_name, int oflags, int verbose)
goto scsi_ata_try;
}
fdc_p->is_nvme = true;
+ fdc_p->nvme_direct = false;
fdc_p->is_char = is_char;
fdc_p->nsid = (broadcast_nsid == nsid) ? 0 : nsid;
fdc_p->nv_ctrlid = nv_ctrlid;
@@ -732,7 +736,7 @@ get_scsi_pt_resid(const struct sg_pt_base * vp)
{
const struct sg_pt_freebsd_scsi * ptp = &vp->impl;
- return ptp->is_nvme ? 0 : ptp->resid;
+ return ptp->nvme_direct ? 0 : ptp->resid;
}
int
@@ -741,7 +745,7 @@ get_scsi_pt_status_response(const struct sg_pt_base * vp)
const struct sg_pt_freebsd_scsi * ptp = &vp->impl;
if (ptp) {
- if (ptp->is_nvme) {
+ if (ptp->nvme_direct) {
const struct freebsd_dev_channel *fdc_p;
fdc_p = get_fdc_cp(ptp);
@@ -754,14 +758,14 @@ get_scsi_pt_status_response(const struct sg_pt_base * vp)
return -1;
}
-/* For NVMe, CDW0 from completion (32 bits), for SCSI the status */
+/* For NVMe command: CDW0 from completion (32 bits); for SCSI: the status */
uint32_t
get_pt_result(const struct sg_pt_base * vp)
{
const struct sg_pt_freebsd_scsi * ptp = &vp->impl;
if (ptp) {
- if (ptp->is_nvme) {
+ if (ptp->nvme_direct) {
const struct freebsd_dev_channel *fdc_p;
fdc_p = get_fdc_cp(ptp);
@@ -771,7 +775,7 @@ get_pt_result(const struct sg_pt_base * vp)
} else
return (uint32_t)ptp->scsi_status;
}
- return -1;
+ return 0xffffffff;
}
int
@@ -1052,12 +1056,14 @@ mk_sense_invalid_fld(struct sg_pt_freebsd_scsi * ptp, bool in_cdb,
}
/* Does actual ioctl(NVME_PASSTHROUGH_CMD). Returns 0 on success; negative
- * values are Unix negated errno values; positive values are NVMe status. */
+ * values are Unix negated errno values; positive values are NVMe status
+ * (i.e. ((SCT << 8) | SC) ). */
static int
nvme_pt_low(struct freebsd_dev_channel *fdc_p, void * dxferp, uint32_t len,
bool is_read, struct nvme_pt_command * npcp, int vb)
{
- int err, status;
+ int err;
+ uint16_t sct_sc;
uint8_t opcode;
char b[80];
@@ -1074,11 +1080,20 @@ nvme_pt_low(struct freebsd_dev_channel *fdc_p, void * dxferp, uint32_t len,
err = ioctl(fdc_p->dev_fd, NVME_PASSTHROUGH_CMD, npcp);
if (err < 0)
return -errno; /* Assume Unix error in normal place */
- status = ((npcp->cpl.status.sct << 8) | npcp->cpl.status.sc);
- if (status && vb)
+ sct_sc = ((npcp->cpl.status.sct << 8) | npcp->cpl.status.sc);
+ fdc_p->nvme_result = npcp->cpl.cdw0;
+ sg_put_unaligned_le32(npcp->cpl.cdw0,
+ fdc_p->cq_dw0_3 + SG_NVME_PT_CQ_RESULT);
+ sg_put_unaligned_le32(npcp->cpl.rsvd1, fdc_p->cq_dw0_3 + 4);
+ sg_put_unaligned_le16(npcp->cpl.sqhd, fdc_p->cq_dw0_3 + 8);
+ sg_put_unaligned_le16(npcp->cpl.sqid, fdc_p->cq_dw0_3 + 10);
+ sg_put_unaligned_le16(npcp->cpl.cid, fdc_p->cq_dw0_3 + 12);
+ sg_put_unaligned_le16(*((const uint16_t *)&(npcp->cpl.status)),
+ fdc_p->cq_dw0_3 + SG_NVME_PT_CQ_STATUS_P);
+ if (sct_sc && (vb > 1))
pr2ws("%s: opcode=0x%x, status: %s\n", __func__, opcode,
- sg_get_nvme_cmd_status_str(status, sizeof(b), b));
- return status;
+ sg_get_nvme_cmd_status_str(sct_sc, sizeof(b), b));
+ return sct_sc;
}
static int
@@ -1125,6 +1140,7 @@ static int
sntl_inq(struct sg_pt_freebsd_scsi * ptp, const uint8_t * cdbp, int vb)
{
bool evpd;
+ bool cp_id_ctl = false;
int res;
uint16_t n, alloc_len, pg_cd;
uint32_t pg_sz = sg_get_page_size();
@@ -1136,7 +1152,7 @@ sntl_inq(struct sg_pt_freebsd_scsi * ptp, const uint8_t * cdbp, int vb)
if (vb > 3)
pr2ws("%s: starting\n", __func__);
- if (0x2 & cdbp[1]) {
+ if (0x2 & cdbp[1]) { /* Reject CmdDt=1 */
mk_sense_invalid_fld(ptp, true, 1, 1, vb);
return 0;
}
@@ -1150,7 +1166,7 @@ sntl_inq(struct sg_pt_freebsd_scsi * ptp, const uint8_t * cdbp, int vb)
if (SG_LIB_NVME_STATUS == res) {
mk_sense_from_nvme_status(ptp, fdc_p->nvme_status, vb);
return 0;
- } else if (res)
+ } else if (res) /* should be negative errno */
return res;
}
memset(inq_dout, 0, sizeof(inq_dout));
@@ -1162,11 +1178,12 @@ sntl_inq(struct sg_pt_freebsd_scsi * ptp, const uint8_t * cdbp, int vb)
case 0: /* Supported VPD pages VPD page */
/* inq_dout[0] = (PQ=0)<<5 | (PDT=0); prefer pdt=0xd --> SES */
inq_dout[1] = pg_cd;
- sg_put_unaligned_be16(3, inq_dout + 2);
+ n = 8;
+ sg_put_unaligned_be16(n - 4, inq_dout + 2);
inq_dout[4] = 0x0;
inq_dout[5] = 0x80;
inq_dout[6] = 0x83;
- n = 7;
+ inq_dout[n - 1] = 0xde;
break;
case 0x80: /* Serial number VPD page */
/* inq_dout[0] = (PQ=0)<<5 | (PDT=0); prefer pdt=0xd --> SES */
@@ -1212,6 +1229,12 @@ sntl_inq(struct sg_pt_freebsd_scsi * ptp, const uint8_t * cdbp, int vb)
nvme_id_ns = NULL;
}
break;
+ case 0xde:
+ inq_dout[1] = pg_cd;
+ sg_put_unaligned_be16((16 + 4096) - 4, inq_dout + 2);
+ n = 16;
+ cp_id_ctl = true;
+ break;
default: /* Point to page_code field in cdb */
mk_sense_invalid_fld(ptp, true, 2, 7, vb);
return 0;
@@ -1219,8 +1242,17 @@ sntl_inq(struct sg_pt_freebsd_scsi * ptp, const uint8_t * cdbp, int vb)
if (alloc_len > 0) {
n = (alloc_len < n) ? alloc_len : n;
n = (n < ptp->dxfer_len) ? n : ptp->dxfer_len;
- if (n > 0)
- memcpy((uint8_t *)ptp->dxferp, inq_dout, n);
+ ptp->resid = ptp->dxfer_len - n;
+ if (n > 0) {
+ if (cp_id_ctl) {
+ memcpy((uint8_t *)ptp->dxferp, inq_dout,
+ (n < 16 ? n : 16));
+ if (n > 16)
+ memcpy((uint8_t *)ptp->dxferp + 16,
+ fdc_p->nvme_id_ctlp, n - 16);
+ } else
+ memcpy((uint8_t *)ptp->dxferp, inq_dout, n);
+ }
}
} else { /* Standard INQUIRY response */
/* inq_dout[0] = (PQ=0)<<5 | (PDT=0); pdt=0 --> SBC; 0xd --> SES */
@@ -1667,15 +1699,17 @@ sntl_recvdiag(struct sg_pt_freebsd_scsi * ptp, const uint8_t * cdbp, int vb)
static int
sg_do_nvme_pt(struct sg_pt_base * vp, int fd, int vb)
{
- bool scsi_cmd, in_xfer;
+ bool scsi_cdb, in_xfer;
int n, err, len, io_len;
- struct nvme_pt_command npc;
+ uint16_t sct_sc;
uint8_t * dxferp;
- uint8_t * npc_up = (uint8_t *)&npc;
+ uint8_t * npc_up;
struct freebsd_dev_channel * fdc_p;
struct sg_pt_freebsd_scsi * ptp = &vp->impl;
const uint8_t * cdbp;
+ struct nvme_pt_command npc;
+ npc_up = (uint8_t *)&npc;
if (vb > 3)
pr2ws("%s: fd=%d\n", __func__, fd);
if (! ptp->cdb) {
@@ -1716,8 +1750,11 @@ sg_do_nvme_pt(struct sg_pt_base * vp, int fd, int vb)
cdbp = (const uint8_t *)ptp->cdb;
if (vb > 3)
pr2ws("%s: opcode=0x%x, fd=%d\n", __func__, cdbp[0], fd);
- scsi_cmd = sg_is_scsi_cdb(cdbp, n);
- if (scsi_cmd) {
+ scsi_cdb = sg_is_scsi_cdb(cdbp, n);
+ /* nvme_direct is true when NVMe command (64 byte) has been given */
+ ptp->nvme_direct = ! scsi_cdb;
+ fdc_p->nvme_direct = ptp->nvme_direct;
+ if (scsi_cdb) {
switch (cdbp[0]) {
case SCSI_INQUIRY_OPC:
return sntl_inq(ptp, cdbp, vb);
@@ -1732,11 +1769,19 @@ sg_do_nvme_pt(struct sg_pt_base * vp, int fd, int vb)
case SCSI_RECEIVE_DIAGNOSTIC_OPC:
return sntl_recvdiag(ptp, cdbp, vb);
default:
+ if (vb > 2) {
+ char b[64];
+
+ sg_get_command_name(cdbp, -1, sizeof(b), b);
+ pr2ws("%s: no translation to NVMe for SCSI %s command\n",
+ __func__, b);
+ }
mk_sense_asc_ascq(ptp, SPC_SK_ILLEGAL_REQUEST, INVALID_OPCODE,
0, vb);
return 0;
}
}
+ /* NVMe command given to pass-through */
len = (int)sizeof(npc.cmd);
n = (n < len) ? n : len;
if (n < 64) {
@@ -1767,21 +1812,28 @@ sg_do_nvme_pt(struct sg_pt_base * vp, int fd, int vb)
npc_up + SG_NVME_PT_ADDR);
}
err = nvme_pt_low(fdc_p, dxferp, io_len, in_xfer, &npc, vb);
- if (err) {
- if (err < 0) {
- if (vb > 1)
- pr2ws("%s: do_nvme_pt() failed: %s (errno=%d)\n",
- __func__, strerror(-err), -err);
- return err;
- } else {
- fdc_p->nvme_status = err;
- mk_sense_from_nvme_status(ptp, err, vb);
- return 0;
+ if (err < 0) {
+ if (vb > 1)
+ pr2ws("%s: do_nvme_pt() failed: %s (errno=%d)\n",
+ __func__, strerror(-err), -err);
+ return err;
+ }
+ sct_sc = err; /* ((SCT << 8) | SC) which may be 0 */
+ fdc_p->nvme_status = sct_sc;
+ if (ptp->sense && (ptp->sense_len > 0)) {
+ uint32_t k = sizeof(fdc_p->cq_dw0_3);
+
+ if ((int)k < ptp->sense_len)
+ ptp->sense_resid = ptp->sense_len - (int)k;
+ else {
+ k = ptp->sense_len;
+ ptp->sense_resid = 0;
}
+ memcpy(ptp->sense, fdc_p->cq_dw0_3, k);
}
if (in_xfer)
ptp->resid = 0; /* Just hoping ... */
- return 0;
+ return sct_sc ? SG_LIB_NVME_STATUS : 0;
}
#else /* if not(HAVE_NVME && (! IGNORE_NVME)) */
diff --git a/lib/sg_pt_linux.c b/lib/sg_pt_linux.c
index 51526eca..d3a91199 100644
--- a/lib/sg_pt_linux.c
+++ b/lib/sg_pt_linux.c
@@ -5,7 +5,7 @@
* license that can be found in the BSD_LICENSE file.
*/
-/* sg_pt_linux version 1.34 20180104 */
+/* sg_pt_linux version 1.35 20180115 */
#include <stdio.h>
@@ -468,6 +468,7 @@ clear_scsi_pt_obj(struct sg_pt_base * vp)
ptp->is_sg = is_sg;
ptp->is_bsg = is_bsg;
ptp->is_nvme = is_nvme;
+ ptp->nvme_direct = false;
ptp->nvme_nsid = nvme_nsid;
}
}
@@ -495,6 +496,7 @@ set_pt_file_handle(struct sg_pt_base * vp, int dev_fd, int verbose)
ptp->is_sg = false;
ptp->is_bsg = false;
ptp->is_nvme = false;
+ ptp->nvme_direct = false;
ptp->nvme_nsid = 0;
ptp->os_err = 0;
}
@@ -655,7 +657,7 @@ get_scsi_pt_resid(const struct sg_pt_base * vp)
if (NULL == ptp)
return 0;
- return ptp->is_nvme ? 0 : ptp->io_hdr.din_resid;
+ return ptp->nvme_direct ? 0 : ptp->io_hdr.din_resid;
}
int
@@ -665,9 +667,8 @@ get_scsi_pt_status_response(const struct sg_pt_base * vp)
if (NULL == ptp)
return 0;
- return (int)(ptp->is_nvme ? ptp->nvme_status :
- ptp->io_hdr.device_status);
- return ptp->io_hdr.device_status;
+ return (int)(ptp->nvme_direct ? ptp->nvme_status :
+ ptp->io_hdr.device_status);
}
uint32_t
@@ -677,8 +678,8 @@ get_pt_result(const struct sg_pt_base * vp)
if (NULL == ptp)
return 0;
- return ptp->is_nvme ? ptp->nvme_status :
- ptp->io_hdr.device_status;
+ return ptp->nvme_direct ? ptp->nvme_result :
+ ptp->io_hdr.device_status;
}
int
diff --git a/lib/sg_pt_linux_nvme.c b/lib/sg_pt_linux_nvme.c
index f62366f7..1b4fa735 100644
--- a/lib/sg_pt_linux_nvme.c
+++ b/lib/sg_pt_linux_nvme.c
@@ -39,7 +39,7 @@
* MA 02110-1301, USA.
*/
-/* sg_pt_linux_nvme version 1.03 20171219 */
+/* sg_pt_linux_nvme version 1.04 20180115 */
#include <stdio.h>
@@ -288,21 +288,24 @@ mk_sense_invalid_fld(struct sg_pt_linux_scsi * ptp, bool in_cdb, int in_byte,
* ptp->nvme_status. If Unix error from ioctl then return negated value
* (equivalent -errno from basic Unix system functions like open()).
* CDW0 from the completion queue is placed in ptp->nvme_result in the
- * absence of a Unix error. */
+ * absence of a Unix error. If time_secs is negative it is treated as
+ * a timeout in milliseconds (of abs(time_secs) ). */
static int
do_nvme_admin_cmd(struct sg_pt_linux_scsi * ptp,
- struct sg_nvme_passthru_cmd *cmdp, const void * dp,
- bool is_read, int time_secs, int vb)
+ struct sg_nvme_passthru_cmd *cmdp, void * dp, bool is_read,
+ int time_secs, int vb)
{
const uint32_t cmd_len = sizeof(struct sg_nvme_passthru_cmd);
int res;
uint32_t n;
+ uint16_t sct_sc;
const uint8_t * up = ((const uint8_t *)cmdp) + SG_NVME_PT_OPCODE;
- cmdp->timeout_ms = (time_secs < 0) ? 0 : (1000 * time_secs);
+ cmdp->timeout_ms = (time_secs < 0) ? (-time_secs) : (1000 * time_secs);
+ ptp->os_err = 0;
if (vb > 2) {
pr2ws("NVMe command:\n");
- dStrHexErr((const char *)cmdp, cmd_len, 1);
+ hex2stderr(cmdp, cmd_len, 1);
if ((vb > 3) && (! is_read) && dp) {
uint32_t len = sg_get_unaligned_le32(up + SG_NVME_PT_DATA_LEN);
@@ -314,50 +317,64 @@ do_nvme_admin_cmd(struct sg_pt_linux_scsi * ptp,
pr2ws("\nData-out buffer (first 512 of %u bytes):\n", n);
n = 512;
}
- dStrHexErr((const char *)dp, n, 0);
+ hex2stderr(dp, n, 0);
}
}
}
res = ioctl(ptp->dev_fd, NVME_IOCTL_ADMIN_CMD, cmdp);
- if (0 != res) {
- if (res < 0) { /* OS error (errno negated) */
- ptp->os_err = -res;
- if (vb > 3) {
- pr2ws("%s: ioctl opcode=0x%x failed: %s "
- "(errno=%d)\n", __func__, *up, strerror(-res), -res);
- }
- return res;
- } else { /* NVMe errors are positive return values */
- res &= 0x3ff; /* clear DNR and More bits */
- ptp->nvme_status = res;
- if (vb > 2) {
- char b[80];
-
- pr2ws("%s: ioctl opcode=0x%x failed: NVMe status: %s "
- "[0x%x]\n", __func__, *up,
- sg_get_nvme_cmd_status_str(res, sizeof(b), b), res);
- }
- return SG_LIB_NVME_STATUS;
+ if (res < 0) { /* OS error (errno negated) */
+ ptp->os_err = -res;
+ if (vb > 1) {
+ pr2ws("%s: ioctl opcode=0x%x failed: %s "
+ "(errno=%d)\n", __func__, *up, strerror(-res), -res);
}
- } else {
- ptp->os_err = 0;
- ptp->nvme_status = 0;
- if ((vb > 3) && is_read && dp) {
- uint32_t len = sg_get_unaligned_le32(up + SG_NVME_PT_DATA_LEN);
+ return res;
+ }
- if (len > 0) {
- n = len;
- if ((len < 1024) || (vb > 5))
- pr2ws("\nData-in buffer (%u bytes):\n", n);
- else {
- pr2ws("\nData-in buffer (first 1024 of %u bytes):\n", n);
- n = 1024;
- }
- dStrHexErr((const char *)dp, n, 0);
+ /* Now res contains NVMe completion queue CDW3 31:17 (15 bits) */
+ ptp->nvme_result = cmdp->result;
+ if (ptp->nvme_direct && ptp->io_hdr.response &&
+ (ptp->io_hdr.max_response_len > 3)) {
+ /* build 16 byte "sense" buffer */
+ uint8_t * sbp = (uint8_t *)ptp->io_hdr.response;
+ uint16_t st = (uint16_t)res;
+
+ n = ptp->io_hdr.max_response_len;
+ n = (n < 16) ? n : 16;
+ memset(sbp, 0 , n);
+ ptp->io_hdr.response_len = n;
+ sg_put_unaligned_le32(cmdp->result,
+ sbp + SG_NVME_PT_CQ_RESULT);
+ if (n > 15) /* LSBit will be 0 (Phase bit) after (st << 1) */
+ sg_put_unaligned_le16(st << 1, sbp + SG_NVME_PT_CQ_STATUS_P);
+ }
+ /* clear upper bits (DNR and More) leaving ((SCT << 8) | SC) */
+ sct_sc = 0x3ff & res;
+ ptp->nvme_status = sct_sc;
+ if (sct_sc) { /* when non-zero, treat as command error */
+ if (vb > 1) {
+ char b[80];
+
+ pr2ws("%s: ioctl opcode=0x%x failed: NVMe status: %s [0x%x]\n",
+ __func__, *up,
+ sg_get_nvme_cmd_status_str(sct_sc, sizeof(b), b), sct_sc);
+ }
+ return SG_LIB_NVME_STATUS; /* == SCSI_PT_DO_NVME_STATUS */
+ }
+ if ((vb > 3) && is_read && dp) {
+ uint32_t len = sg_get_unaligned_le32(up + SG_NVME_PT_DATA_LEN);
+
+ if (len > 0) {
+ n = len;
+ if ((len < 1024) || (vb > 5))
+ pr2ws("\nData-in buffer (%u bytes):\n", n);
+ else {
+ pr2ws("\nData-in buffer (first 1024 of %u bytes):\n", n);
+ n = 1024;
}
+ hex2stderr(dp, n, 0);
}
}
- ptp->nvme_result = cmdp->result;
return 0;
}
@@ -391,6 +408,7 @@ sntl_inq(struct sg_pt_linux_scsi * ptp, const uint8_t * cdbp, int time_secs,
int vb)
{
bool evpd;
+ bool cp_id_ctl = false;
int res;
uint16_t n, alloc_len, pg_cd;
uint32_t pg_sz = sg_get_page_size();
@@ -401,7 +419,7 @@ sntl_inq(struct sg_pt_linux_scsi * ptp, const uint8_t * cdbp, int time_secs,
if (vb > 3)
pr2ws("%s: time_secs=%d\n", __func__, time_secs);
- if (0x2 & cdbp[1]) {
+ if (0x2 & cdbp[1]) { /* Reject CmdDt=1 */
mk_sense_invalid_fld(ptp, true, 1, 1, vb);
return 0;
}
@@ -410,7 +428,7 @@ sntl_inq(struct sg_pt_linux_scsi * ptp, const uint8_t * cdbp, int time_secs,
if (SG_LIB_NVME_STATUS == res) {
mk_sense_from_nvme_status(ptp, vb);
return 0;
- } else if (res)
+ } else if (res) /* should be negative errno */
return res;
}
memset(inq_dout, 0, sizeof(inq_dout));
@@ -422,11 +440,12 @@ sntl_inq(struct sg_pt_linux_scsi * ptp, const uint8_t * cdbp, int time_secs,
case 0:
/* inq_dout[0] = (PQ=0)<<5 | (PDT=0); prefer pdt=0xd --> SES */
inq_dout[1] = pg_cd;
- sg_put_unaligned_be16(3, inq_dout + 2);
+ n = 8;
+ sg_put_unaligned_be16(n - 4, inq_dout + 2);
inq_dout[4] = 0x0;
inq_dout[5] = 0x80;
inq_dout[6] = 0x83;
- n = 7;
+ inq_dout[n - 1] = 0xde; /* last VPD number */
break;
case 0x80:
/* inq_dout[0] = (PQ=0)<<5 | (PDT=0); prefer pdt=0xd --> SES */
@@ -469,6 +488,12 @@ sntl_inq(struct sg_pt_linux_scsi * ptp, const uint8_t * cdbp, int time_secs,
nvme_id_ns = NULL;
}
break;
+ case 0xde:
+ inq_dout[1] = pg_cd;
+ sg_put_unaligned_be16((16 + 4096) - 4, inq_dout + 2);
+ n = 16 + 4096;
+ cp_id_ctl = true;
+ break;
default: /* Point to page_code field in cdb */
mk_sense_invalid_fld(ptp, true, 2, 7, vb);
return 0;
@@ -476,8 +501,17 @@ sntl_inq(struct sg_pt_linux_scsi * ptp, const uint8_t * cdbp, int time_secs,
if (alloc_len > 0) {
n = (alloc_len < n) ? alloc_len : n;
n = (n < ptp->io_hdr.din_xfer_len) ? n : ptp->io_hdr.din_xfer_len;
- if (n > 0)
- memcpy((uint8_t *)ptp->io_hdr.din_xferp, inq_dout, n);
+ ptp->io_hdr.din_resid = ptp->io_hdr.din_xfer_len - n;
+ if (n > 0) {
+ if (cp_id_ctl) {
+ memcpy((uint8_t *)ptp->io_hdr.din_xferp, inq_dout,
+ (n < 16 ? n : 16));
+ if (n > 16)
+ memcpy((uint8_t *)ptp->io_hdr.din_xferp + 16,
+ ptp->nvme_id_ctlp, n - 16);
+ } else
+ memcpy((uint8_t *)ptp->io_hdr.din_xferp, inq_dout, n);
+ }
}
} else { /* Standard INQUIRY response */
/* inq_dout[0] = (PQ=0)<<5 | (PDT=0); pdt=0 --> SBC; 0xd --> SES */
@@ -492,6 +526,7 @@ sntl_inq(struct sg_pt_linux_scsi * ptp, const uint8_t * cdbp, int time_secs,
if (alloc_len > 0) {
n = (alloc_len < inq_resp_len) ? alloc_len : inq_resp_len;
n = (n < ptp->io_hdr.din_xfer_len) ? n : ptp->io_hdr.din_xfer_len;
+ ptp->io_hdr.din_resid = ptp->io_hdr.din_xfer_len - n;
if (n > 0)
memcpy((uint8_t *)ptp->io_hdr.din_xferp, inq_dout, n);
}
@@ -556,10 +591,9 @@ sntl_rluns(struct sg_pt_linux_scsi * ptp, const uint8_t * cdbp, int time_secs,
if (alloc_len > 0) {
n = (alloc_len < n) ? alloc_len : n;
n = (n < ptp->io_hdr.din_xfer_len) ? n : ptp->io_hdr.din_xfer_len;
- if (n > 0) {
+ ptp->io_hdr.din_resid = ptp->io_hdr.din_xfer_len - n;
+ if (n > 0)
memcpy((uint8_t *)ptp->io_hdr.din_xferp, rl_doutp, n);
- ptp->io_hdr.din_resid = ptp->io_hdr.din_xfer_len - n;
- }
}
res = 0;
free(rl_doutp);
@@ -683,7 +717,7 @@ sntl_senddiag(struct sg_pt_linux_scsi * ptp, const uint8_t * cdbp,
uint8_t st_cd, dpg_cd;
uint32_t alloc_len, n, dout_len, dpg_len, nvme_dst;
uint32_t pg_sz = sg_get_page_size();
- const uint8_t * dop;
+ uint8_t * dop;
struct sg_nvme_passthru_cmd cmd;
uint8_t * cmd_up = (uint8_t *)&cmd;
@@ -757,7 +791,7 @@ sntl_senddiag(struct sg_pt_linux_scsi * ptp, const uint8_t * cdbp,
}
n = dout_len;
n = (n < alloc_len) ? n : alloc_len;
- dop = (const uint8_t *)ptp->io_hdr.dout_xferp;
+ dop = (uint8_t *)ptp->io_hdr.dout_xferp;
if (! is_aligned(dop, pg_sz)) { /* caller best use sg_memalign(,pg_sz) */
if (vb)
pr2ws("%s: dout [0x%" PRIx64 "] not page aligned\n", __func__,
@@ -804,7 +838,7 @@ sntl_recvdiag(struct sg_pt_linux_scsi * ptp, const uint8_t * cdbp,
uint8_t dpg_cd;
uint32_t alloc_len, n, din_len;
uint32_t pg_sz = sg_get_page_size();
- const uint8_t * dip;
+ uint8_t * dip;
struct sg_nvme_passthru_cmd cmd;
pcv = !! (0x1 & cdbp[1]);
@@ -816,7 +850,7 @@ sntl_recvdiag(struct sg_pt_linux_scsi * ptp, const uint8_t * cdbp,
din_len = ptp->io_hdr.din_xfer_len;
n = din_len;
n = (n < alloc_len) ? n : alloc_len;
- dip = (const uint8_t *)ptp->io_hdr.din_xferp;
+ dip = (uint8_t *)ptp->io_hdr.din_xferp;
if (! is_aligned(dip, pg_sz)) { /* caller best use sg_memalign(,pg_sz) */
if (vb)
pr2ws("%s: din [0x%" PRIx64 "] not page aligned\n", __func__,
@@ -856,7 +890,7 @@ sntl_recvdiag(struct sg_pt_linux_scsi * ptp, const uint8_t * cdbp,
int
sg_do_nvme_pt(struct sg_pt_base * vp, int fd, int time_secs, int vb)
{
- bool scsi_cmd;
+ bool scsi_cdb;
bool is_read = false;
int n, len;
struct sg_pt_linux_scsi * ptp = &vp->impl;
@@ -887,8 +921,10 @@ sg_do_nvme_pt(struct sg_pt_base * vp, int fd, int time_secs, int vb)
if (vb > 3)
pr2ws("%s: opcode=0x%x, fd=%d, time_secs=%d\n", __func__, cdbp[0],
fd, time_secs);
- scsi_cmd = sg_is_scsi_cdb(cdbp, n);
- if (scsi_cmd) {
+ scsi_cdb = sg_is_scsi_cdb(cdbp, n);
+ /* direct NVMe command (i.e. 64 bytes long) or SNTL */
+ ptp->nvme_direct = ! scsi_cdb;
+ if (scsi_cdb) {
switch (cdbp[0]) {
case SCSI_INQUIRY_OPC:
return sntl_inq(ptp, cdbp, time_secs, vb);
@@ -903,6 +939,13 @@ sg_do_nvme_pt(struct sg_pt_base * vp, int fd, int time_secs, int vb)
case SCSI_RECEIVE_DIAGNOSTIC_OPC:
return sntl_recvdiag(ptp, cdbp, time_secs, vb);
default:
+ if (vb > 2) {
+ char b[64];
+
+ sg_get_command_name(cdbp, -1, sizeof(b), b);
+ pr2ws("%s: no translation to NVMe for SCSI %s command\n",
+ __func__, b);
+ }
mk_sense_asc_ascq(ptp, SPC_SK_ILLEGAL_REQUEST, INVALID_OPCODE,
0, vb);
return 0;
diff --git a/sg3_utils.spec b/sg3_utils.spec
index 05a33b70..4a94807b 100644
--- a/sg3_utils.spec
+++ b/sg3_utils.spec
@@ -79,7 +79,7 @@ fi
%{_libdir}/*.la
%changelog
-* Sat Jan 13 2018 - dgilbert at interlog dot com
+* Thu Jan 18 2018 - dgilbert at interlog dot com
- track t10 changes
* sg3_utils-1.43
diff --git a/src/Makefile.am b/src/Makefile.am
index 7d76caf1..6ee7d0ac 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -43,6 +43,7 @@ endif
# -Wall is no longer all warnings. Add -W (since renamed to -Wextra) for more
AM_CPPFLAGS = -iquote ${top_srcdir}/include -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64
AM_CFLAGS = -Wall -W
+# AM_CFLAGS = -Wall -W -Wextra -Wmisleading-indentation -Wduplicated-cond -Wduplicated-branches -Wlogical-op -Wnull-dereference -Wshadow -Wjump-misses-init
# AM_CFLAGS = -Wall -W -pedantic -std=c11
# AM_CFLAGS = -Wall -W -pedantic -std=c11 --analyze
# AM_CFLAGS = -Wall -W -pedantic -std=c++14
diff --git a/src/Makefile.in b/src/Makefile.in
index 58b81399..2b79f871 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -567,6 +567,7 @@ sg_scan_SOURCES = $(am__append_2) $(am__append_4) $(am__append_6)
# -Wall is no longer all warnings. Add -W (since renamed to -Wextra) for more
AM_CPPFLAGS = -iquote ${top_srcdir}/include -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64
AM_CFLAGS = -Wall -W
+# AM_CFLAGS = -Wall -W -Wextra -Wmisleading-indentation -Wduplicated-cond -Wduplicated-branches -Wlogical-op -Wnull-dereference -Wshadow -Wjump-misses-init
# AM_CFLAGS = -Wall -W -pedantic -std=c11
# AM_CFLAGS = -Wall -W -pedantic -std=c11 --analyze
# AM_CFLAGS = -Wall -W -pedantic -std=c++14
diff --git a/src/sg_bg_ctl.c b/src/sg_bg_ctl.c
index 708a5808..ef9e6d5f 100644
--- a/src/sg_bg_ctl.c
+++ b/src/sg_bg_ctl.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-2017 Douglas Gilbert.
+ * Copyright (c) 2016-2018 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.
@@ -33,7 +33,7 @@
* device. Based on sbc4r10.pdf .
*/
-static const char * version_str = "1.02 20171008";
+static const char * version_str = "1.03 20180118";
#define BACKGROUND_CONTROL_SA 0x15
diff --git a/src/sg_compare_and_write.c b/src/sg_compare_and_write.c
index 4549c362..c2b16a47 100644
--- a/src/sg_compare_and_write.c
+++ b/src/sg_compare_and_write.c
@@ -366,7 +366,7 @@ sg_ll_compare_and_write(int sg_fd, unsigned char * buff, int blocks,
}
if ((verbose > 2) && (xfer_len > 0)) {
pr2serr(" Data-out buffer contents:\n");
- dStrHexErr((const char *)buff, xfer_len, 1);
+ hex2stderr(buff, xfer_len, 1);
}
res = do_scsi_pt(ptvp, sg_fd, DEF_TIMEOUT_SECS, verbose);
ret = sg_cmds_process_resp(ptvp, "COMPARE AND WRITE", res,
diff --git a/src/sg_copy_results.c b/src/sg_copy_results.c
index 0785afd6..2d67ec6d 100644
--- a/src/sg_copy_results.c
+++ b/src/sg_copy_results.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011-2017 Hannes Reinecke, SUSE Labs
+ * Copyright (c) 2011-2018 Hannes Reinecke, SUSE Labs
* All rights reserved.
* Use of this source code is governed by a BSD-style
* license that can be found in the BSD_LICENSE file.
@@ -38,7 +38,7 @@
and the optional list identifier passed as the list_id argument.
*/
-static const char * version_str = "1.16 20171010";
+static const char * version_str = "1.17 20180118";
#define MAX_XFER_LEN 10000
@@ -434,7 +434,7 @@ main(int argc, char * argv[])
goto finish;
}
if (do_hex) {
- dStrHex((const char *)cpResultBuff, xfer_len, 1);
+ hex2stdout(cpResultBuff, xfer_len, 1);
goto finish;
}
switch (sa) {
@@ -448,7 +448,7 @@ main(int argc, char * argv[])
scsi_copy_status(cpResultBuff, xfer_len);
break;
default:
- dStrHex((const char *)cpResultBuff, xfer_len, 1);
+ hex2stdout(cpResultBuff, xfer_len, 1);
break;
}
diff --git a/src/sg_dd.c b/src/sg_dd.c
index 74b0547e..7a2c8415 100644
--- a/src/sg_dd.c
+++ b/src/sg_dd.c
@@ -1,29 +1,29 @@
/* A utility program for copying files. Specialised for "files" that
* represent devices that understand the SCSI command set.
*
- * Copyright (C) 1999 - 2017 D. Gilbert and P. Allworth
+ * Copyright (C) 1999 - 2018 D. Gilbert and P. Allworth
* 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)
* any later version.
-
- This program is a specialisation of the Unix "dd" command in which
- either the input or the output file is a scsi generic device, raw
- device, a block device or a normal file. The block size ('bs') is
- assumed to be 512 if not given. This program complains if 'ibs' or
- 'obs' are given with a value that differs from 'bs' (or the default 512).
- If 'if' is not given or 'if=-' then stdin is assumed. If 'of' is
- not given or 'of=-' then stdout assumed.
-
- A non-standard argument "bpt" (blocks per transfer) is added to control
- the maximum number of blocks in each transfer. The default value is 128.
- For example if "bs=512" and "bpt=32" then a maximum of 32 blocks (16 KiB
- in this case) is transferred to or from the sg device in a single SCSI
- command. The actual size of the SCSI READ or WRITE command block can be
- selected with the "cdbsz" argument.
-
- This version is designed for the linux kernel 2.4, 2.6 and 3 series.
-*/
+ *
+ * This program is a specialisation of the Unix "dd" command in which
+ * either the input or the output file is a scsi generic device, raw
+ * device, a block device or a normal file. The block size ('bs') is
+ * assumed to be 512 if not given. This program complains if 'ibs' or
+ * 'obs' are given with a value that differs from 'bs' (or the default 512).
+ * If 'if' is not given or 'if=-' then stdin is assumed. If 'of' is
+ * not given or 'of=-' then stdout assumed.
+ *
+ * A non-standard argument "bpt" (blocks per transfer) is added to control
+ * the maximum number of blocks in each transfer. The default value is 128.
+ * For example if "bs=512" and "bpt=32" then a maximum of 32 blocks (16 KiB
+ * in this case) is transferred to or from the sg device in a single SCSI
+ * command. The actual size of the SCSI READ or WRITE command block can be
+ * selected with the "cdbsz" argument.
+ *
+ * This version is designed for the linux kernel 2.4, 2.6 and 3 series.
+ */
#define _XOPEN_SOURCE 600
#ifndef _GNU_SOURCE
@@ -62,7 +62,7 @@
#include "sg_unaligned.h"
#include "sg_pr2serr.h"
-static const char * version_str = "5.93 20171206";
+static const char * version_str = "5.94 20180116";
#define ME "sg_dd: "
@@ -1215,15 +1215,14 @@ process_conv(const char * arg, struct flags_t * ifp, struct flags_t * ofp)
*/
static int
open_if(const char * inf, int64_t skip, int bpt, struct flags_t * ifp,
- int * in_typep, int verbose)
+ int * in_typep, int vb)
{
- int infd, flags, fl, t, verb, res;
+ int infd, flags, fl, t, res;
char ebuff[EBUFF_SZ];
struct sg_simple_inquiry_resp sir;
- verb = (verbose ? verbose - 1: 0);
*in_typep = dd_filetype(inf);
- if (verbose)
+ if (vb)
pr2serr(" >> Input file type: %s\n",
dd_filetype_str(*in_typep, ebuff));
if (FT_ERROR & *in_typep) {
@@ -1253,14 +1252,14 @@ open_if(const char * inf, int64_t skip, int bpt, struct flags_t * ifp,
goto file_err;
}
}
- if (verbose)
+ if (vb)
pr2serr(" open input(sg_io), flags=0x%x\n", fl | flags);
- if (sg_simple_inquiry(infd, &sir, 0, verb)) {
+ if (sg_simple_inquiry(infd, &sir, 0, (vb ? (vb - 1) : 0))) {
pr2serr("INQUIRY failed on %s\n", inf);
goto other_err;
}
ifp->pdt = sir.peripheral_type;
- if (verbose)
+ if (vb)
pr2serr(" %s: %.8s %.16s %.4s [pdt=%d]\n", inf, sir.vendor,
sir.product, sir.revision, ifp->pdt);
if (! (FT_BLOCK & *in_typep)) {
@@ -1292,7 +1291,7 @@ open_if(const char * inf, int64_t skip, int bpt, struct flags_t * ifp,
perror(ebuff);
goto file_err;
} else {
- if (verbose)
+ if (vb)
pr2serr(" open input, flags=0x%x\n", flags);
if (skip > 0) {
off64_t offset = skip;
@@ -1304,7 +1303,7 @@ open_if(const char * inf, int64_t skip, int bpt, struct flags_t * ifp,
perror(ebuff);
goto file_err;
}
- if (verbose)
+ if (vb)
pr2serr(" >> skip: lseek64 SEEK_SET, byte offset=0x%"
PRIx64 "\n", (uint64_t)offset);
}
@@ -1344,15 +1343,14 @@ other_err:
*/
static int
open_of(const char * outf, int64_t seek, int bpt, struct flags_t * ofp,
- int * out_typep, int verbose)
+ int * out_typep, int vb)
{
- int outfd, flags, t, verb, res;
+ int outfd, flags, t, res;
char ebuff[EBUFF_SZ];
struct sg_simple_inquiry_resp sir;
- verb = (verbose ? verbose - 1: 0);
*out_typep = dd_filetype(outf);
- if (verbose)
+ if (vb)
pr2serr(" >> Output file type: %s\n",
dd_filetype_str(*out_typep, ebuff));
@@ -1376,14 +1374,14 @@ open_of(const char * outf, int64_t seek, int bpt, struct flags_t * ofp,
perror(ebuff);
goto file_err;
}
- if (verbose)
+ if (vb)
pr2serr(" open output(sg_io), flags=0x%x\n", flags);
- if (sg_simple_inquiry(outfd, &sir, 0, verb)) {
+ if (sg_simple_inquiry(outfd, &sir, 0, (vb ? (vb - 1) : 0))) {
pr2serr("INQUIRY failed on %s\n", outf);
goto other_err;
}
ofp->pdt = sir.peripheral_type;
- if (verbose)
+ if (vb)
pr2serr(" %s: %.8s %.16s %.4s [pdt=%d]\n", outf, sir.vendor,
sir.product, sir.revision, ofp->pdt);
if (! (FT_BLOCK & *out_typep)) {
@@ -1431,7 +1429,7 @@ open_of(const char * outf, int64_t seek, int bpt, struct flags_t * ofp,
goto file_err;
}
}
- if (verbose)
+ if (vb)
pr2serr(" %s output, flags=0x%x\n",
((O_CREAT & flags) ? "create" : "open"), flags);
if (seek > 0) {
@@ -1444,7 +1442,7 @@ open_of(const char * outf, int64_t seek, int bpt, struct flags_t * ofp,
perror(ebuff);
goto file_err;
}
- if (verbose)
+ if (vb)
pr2serr(" >> seek: lseek64 SEEK_SET, byte offset=0x%" PRIx64
"\n", (uint64_t)offset);
}
diff --git a/src/sg_format.c b/src/sg_format.c
index 4da7923b..afe21c58 100644
--- a/src/sg_format.c
+++ b/src/sg_format.c
@@ -376,8 +376,7 @@ scsi_format_unit(int fd, const struct opts_t * op)
resp_len = reqSense[7] + 8;
if (verb) {
pr2serr("Parameter data in hex:\n");
- dStrHexErr((const char *)reqSense, resp_len,
- 1);
+ hex2stderr(reqSense, resp_len, 1);
}
progress = -1;
sg_get_sense_progress_fld(reqSense, resp_len,
@@ -409,8 +408,7 @@ scsi_format_unit(int fd, const struct opts_t * op)
resp_len = requestSenseBuff[7] + 8;
if (op->verbose > 1) {
pr2serr("Parameter data in hex\n");
- dStrHexErr((const char *)requestSenseBuff, resp_len,
- 1);
+ hex2stderr(requestSenseBuff, resp_len, 1);
}
progress = -1;
sg_get_sense_progress_fld(requestSenseBuff, resp_len,
@@ -495,8 +493,7 @@ scsi_format_medium(int fd, const struct opts_t * op)
resp_len = reqSense[7] + 8;
if (verb) {
pr2serr("Parameter data in hex:\n");
- dStrHexErr((const char *)reqSense, resp_len,
- 1);
+ hex2stderr(reqSense, resp_len, 1);
}
progress = -1;
sg_get_sense_progress_fld(reqSense, resp_len,
diff --git a/src/sg_get_config.c b/src/sg_get_config.c
index 86f6e324..9fdd3827 100644
--- a/src/sg_get_config.c
+++ b/src/sg_get_config.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2004-2017 Douglas Gilbert.
+ * Copyright (c) 2004-2018 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.
@@ -238,7 +238,7 @@ dStrRaw(const char * str, int len)
{
int k;
- for (k = 0 ; k < len; ++k)
+ for (k = 0; k < len; ++k)
printf("%c", str[k]);
}
@@ -876,7 +876,7 @@ decode_feature(int feature, unsigned char * bp, int len)
pr2serr(" Unknown feature [0x%x], version=%d persist=%d, "
"current=%d\n", feature, ((bp[2] >> 2) & 0xf),
!!(bp[2] & 0x2), !!(bp[2] & 0x1));
- dStrHexErr((const char *)bp, len, 1);
+ hex2stderr(bp, len, 1);
break;
}
}
@@ -913,7 +913,7 @@ decode_config(unsigned char * resp, int max_resp_len, int len, bool brief,
if (brief)
continue;
if (inner_hex) {
- dStrHex((const char *)bp, extra_len, 1);
+ hex2stdout(bp, extra_len, 1);
continue;
}
if (0 != (extra_len % 4))
@@ -1090,7 +1090,7 @@ main(int argc, char * argv[])
if (do_hex) {
if (len > (int)sizeof(resp_buffer))
len = sizeof(resp_buffer);
- dStrHex((const char *)resp_buffer, len, 0);
+ hex2stdout(resp_buffer, len, 0);
} else if (do_raw)
dStrRaw((const char *)resp_buffer, len);
else
diff --git a/src/sg_get_lba_status.c b/src/sg_get_lba_status.c
index 7fb6c723..3a4f2020 100644
--- a/src/sg_get_lba_status.c
+++ b/src/sg_get_lba_status.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2009-2017 Douglas Gilbert.
+ * Copyright (c) 2009-2018 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.
@@ -114,11 +114,11 @@ usage()
}
static void
-dStrRaw(const char* str, int len)
+dStrRaw(const char * str, int len)
{
int k;
- for (k = 0 ; k < len; ++k)
+ for (k = 0; k < len; ++k)
printf("%c", str[k]);
}
@@ -327,7 +327,7 @@ main(int argc, char * argv[])
goto the_end;
}
if (do_hex) {
- dStrHex((const char *)glbasBuffp, k, 1);
+ hex2stdout(glbasBuffp, k, 1);
goto the_end;
}
if (maxlen < 4) {
diff --git a/src/sg_ident.c b/src/sg_ident.c
index 9ef06289..0ca94bf6 100644
--- a/src/sg_ident.c
+++ b/src/sg_ident.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005-2017 Douglas Gilbert.
+ * Copyright (c) 2005-2018 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.
@@ -31,7 +31,7 @@
* DEVICE IDENTIFIER and SET DEVICE IDENTIFIER prior to spc4r07.
*/
-static const char * version_str = "1.17 20171008";
+static const char * version_str = "1.18 20180118";
#define ME "sg_ident: "
@@ -83,7 +83,7 @@ decode_ii(const unsigned char * iip, int ii_len, int itype, bool ascii,
if (ascii)
printf("%.*s\n", ii_len, (const char *)iip);
else
- dStrHex((const char *)iip, ii_len, 0);
+ hex2stdout(iip, ii_len, 0);
}
}
}
diff --git a/src/sg_inq.c b/src/sg_inq.c
index ca0d4c51..c15539b7 100644
--- a/src/sg_inq.c
+++ b/src/sg_inq.c
@@ -1,19 +1,19 @@
/* A utility program originally written for the Linux OS SCSI subsystem.
-* Copyright (C) 2000-2018 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)
-* any later version.
-
- This program outputs information provided by a SCSI INQUIRY command.
- It is mainly based on the SCSI SPC-5 document at http://www.t10.org .
-
- Acknowledgment:
- - Martin Schwenke <martin at meltin dot net> added the raw switch and
- other improvements [20020814]
- - Lars Marowsky-Bree <lmb at suse dot de> contributed Unit Path Report
- VPD page decoding for EMC CLARiiON devices [20041016]
-*/
+ * Copyright (C) 2000-2018 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)
+ * any later version.
+ *
+ * This program outputs information provided by a SCSI INQUIRY command.
+ * It is mainly based on the SCSI SPC-5 document at http://www.t10.org .
+ *
+ * Acknowledgment:
+ * - Martin Schwenke <martin at meltin dot net> added the raw switch and
+ * other improvements [20020814]
+ * - Lars Marowsky-Bree <lmb at suse dot de> contributed Unit Path Report
+ * VPD page decoding for EMC CLARiiON devices [20041016]
+ */
#include <unistd.h>
#include <fcntl.h>
@@ -46,7 +46,7 @@
#include "sg_pt_nvme.h"
#endif
-static const char * version_str = "1.83 20180112"; /* SPC-5 rev 18 */
+static const char * version_str = "1.84 20180118"; /* SPC-5 rev 18 */
/* INQUIRY notes:
* It is recommended that the initial allocation length given to a
@@ -1002,11 +1002,11 @@ enumerate_vpds()
}
static void
-dStrRaw(const char* str, int len)
+dStrRaw(const char * str, int len)
{
int k;
- for (k = 0 ; k < len; ++k)
+ for (k = 0; k < len; ++k)
printf("%c", str[k]);
}
@@ -1205,7 +1205,7 @@ decode_supported_vpd(unsigned char * buff, int len, int do_hex)
const char * cp;
if (do_hex) {
- dStrHex((const char *)buff, len, (1 == do_hex) ? 0 : -1);
+ hex2stdout(buff, len, (1 == do_hex) ? 0 : -1);
return;
}
if (len < 4) {
@@ -1267,7 +1267,7 @@ decode_ascii_inf(unsigned char * buff, int len, int do_hex)
unsigned char * p;
if (do_hex) {
- dStrHex((const char *)buff, len, (1 == do_hex) ? 0 : -1);
+ hex2stdout(buff, len, (1 == do_hex) ? 0 : -1);
return;
}
if (len < 4) {
@@ -1291,7 +1291,7 @@ decode_ascii_inf(unsigned char * buff, int len, int do_hex)
bp = buff + 5 + al;
if (bp < (buff + len)) {
printf("Vendor specific information in hex:\n");
- dStrHex((const char *)bp, len - (al + 5), 0);
+ hex2stdout(bp, len - (al + 5), 0);
}
}
@@ -1344,7 +1344,7 @@ decode_net_man_vpd(unsigned char * buff, int len, int do_hex)
return;
}
if (do_hex > 2) {
- dStrHex((const char *)buff, len, -1);
+ hex2stdout(buff, len, -1);
return;
}
len -= 4;
@@ -1363,7 +1363,7 @@ decode_net_man_vpd(unsigned char * buff, int len, int do_hex)
if (na_len > 0) {
if (do_hex) {
printf(" Network address:\n");
- dStrHex((const char *)(bp + 4), na_len, 0);
+ hex2stdout(bp + 4, na_len, 0);
} else
printf(" %s\n", bp + 4);
}
@@ -1390,7 +1390,7 @@ decode_mode_policy_vpd(unsigned char * buff, int len, int do_hex)
return;
}
if (do_hex > 2) {
- dStrHex((const char *)buff, len, -1);
+ hex2stdout(buff, len, -1);
return;
}
len -= 4;
@@ -1403,7 +1403,7 @@ decode_mode_policy_vpd(unsigned char * buff, int len, int do_hex)
return;
}
if (do_hex)
- dStrHex((const char *)bp, 4, (1 == do_hex) ? 1 : -1);
+ hex2stdout(bp, 4, (1 == do_hex) ? 1 : -1);
else {
printf(" Policy page code: 0x%x", (bp[0] & 0x3f));
if (bp[1])
@@ -1428,7 +1428,7 @@ decode_scsi_ports_vpd(unsigned char * buff, int len, int do_hex, int verbose)
return;
}
if (do_hex > 2) {
- dStrHex((const char *)buff, len, -1);
+ hex2stdout(buff, len, -1);
return;
}
len -= 4;
@@ -1446,8 +1446,7 @@ decode_scsi_ports_vpd(unsigned char * buff, int len, int do_hex, int verbose)
if (ip_tid_len > 0) {
if (do_hex) {
printf(" Initiator port transport id:\n");
- dStrHex((const char *)(bp + 8), ip_tid_len,
- (1 == do_hex) ? 1 : -1);
+ hex2stdout((bp + 8), ip_tid_len, (1 == do_hex) ? 1 : -1);
} else {
char b[1024];
@@ -1464,8 +1463,7 @@ decode_scsi_ports_vpd(unsigned char * buff, int len, int do_hex, int verbose)
if (tpd_len > 0) {
printf(" Target port descriptor(s):\n");
if (do_hex)
- dStrHex((const char *)(bp + bump + 4), tpd_len,
- (1 == do_hex) ? 1 : -1);
+ hex2stdout(bp + bump + 4, tpd_len, (1 == do_hex) ? 1 : -1);
else
decode_dev_ids("SCSI Ports", bp + bump + 4, tpd_len,
do_hex, verbose);
@@ -1546,7 +1544,7 @@ decode_dev_ids(const char * leadin, unsigned char * buff, int len, int do_hex,
printf(" designator header(hex): %.2x %.2x %.2x %.2x\n",
bp[0], bp[1], bp[2], bp[3]);
printf(" designator:\n");
- dStrHex((const char *)ip, i_len, 0);
+ hex2stdout(ip, i_len, 0);
continue;
}
switch (desig_type) {
@@ -1562,7 +1560,7 @@ decode_dev_ids(const char * leadin, unsigned char * buff, int len, int do_hex,
printf(" vendor specific: %.*s\n", i_len, ip);
else {
printf(" vendor specific:\n");
- dStrHex((const char *)ip, i_len, -1);
+ hex2stdout(ip, i_len, -1);
}
break;
case 1: /* T10 vendor identification */
@@ -1582,7 +1580,7 @@ decode_dev_ids(const char * leadin, unsigned char * buff, int len, int do_hex,
printf(" EUI-64 based %d byte identifier\n", i_len);
if (1 != c_set) {
pr2serr(" << expected binary code_set (1)>>\n");
- dStrHexErr((const char *)ip, i_len, -1);
+ hex2stderr(ip, i_len, -1);
break;
}
ci_off = 0;
@@ -1593,7 +1591,7 @@ decode_dev_ids(const char * leadin, unsigned char * buff, int len, int do_hex,
} else if ((8 != i_len) && (12 != i_len)) {
pr2serr(" << can only decode 8, 12 and 16 "
"byte ids>>\n");
- dStrHexErr((const char *)ip, i_len, -1);
+ hex2stderr(ip, i_len, -1);
break;
}
c_id = sg_get_unaligned_be24(ip + ci_off);
@@ -1615,7 +1613,7 @@ decode_dev_ids(const char * leadin, unsigned char * buff, int len, int do_hex,
if (1 != c_set) {
pr2serr(" << expected binary code_set (1), got %d for "
"NAA=%d>>\n", c_set, naa);
- dStrHexErr((const char *)ip, i_len, -1);
+ hex2stderr(ip, i_len, -1);
break;
}
switch (naa) {
@@ -1623,7 +1621,7 @@ decode_dev_ids(const char * leadin, unsigned char * buff, int len, int do_hex,
if (8 != i_len) {
pr2serr(" << unexpected NAA 2 identifier "
"length: 0x%x>>\n", i_len);
- dStrHexErr((const char *)ip, i_len, -1);
+ hex2stderr(ip, i_len, -1);
break;
}
d_id = (((ip[0] & 0xf) << 8) | ip[1]);
@@ -1642,7 +1640,7 @@ decode_dev_ids(const char * leadin, unsigned char * buff, int len, int do_hex,
if (8 != i_len) {
pr2serr(" << unexpected NAA 3 identifier "
"length: 0x%x>>\n", i_len);
- dStrHexErr((const char *)ip, i_len, -1);
+ hex2stderr(ip, i_len, -1);
break;
}
printf(" NAA 3, Locally assigned:\n");
@@ -1655,7 +1653,7 @@ decode_dev_ids(const char * leadin, unsigned char * buff, int len, int do_hex,
if (8 != i_len) {
pr2serr(" << unexpected NAA 5 identifier "
"length: 0x%x>>\n", i_len);
- dStrHexErr((const char *)ip, i_len, -1);
+ hex2stderr(ip, i_len, -1);
break;
}
c_id = (((ip[0] & 0xf) << 20) | (ip[1] << 12) |
@@ -1677,7 +1675,7 @@ decode_dev_ids(const char * leadin, unsigned char * buff, int len, int do_hex,
if (16 != i_len) {
pr2serr(" << unexpected NAA 6 identifier "
"length: 0x%x>>\n", i_len);
- dStrHexErr((const char *)ip, i_len, 0);
+ hex2stderr(ip, i_len, 0);
break;
}
c_id = (((ip[0] & 0xf) << 20) | (ip[1] << 12) |
@@ -1701,7 +1699,7 @@ decode_dev_ids(const char * leadin, unsigned char * buff, int len, int do_hex,
default:
pr2serr(" << bad NAA nibble , expect 2, 3, 5 or 6, "
"got %d>>\n", naa);
- dStrHexErr((const char *)ip, i_len, -1);
+ hex2stderr(ip, i_len, -1);
break;
}
break;
@@ -1709,7 +1707,7 @@ decode_dev_ids(const char * leadin, unsigned char * buff, int len, int do_hex,
if ((1 != c_set) || (1 != assoc) || (4 != i_len)) {
pr2serr(" << expected binary code_set, target "
"port association, length 4>>\n");
- dStrHexErr((const char *)ip, i_len, -1);
+ hex2stderr(ip, i_len, -1);
break;
}
d_id = sg_get_unaligned_be16(ip + 2);
@@ -1719,7 +1717,7 @@ decode_dev_ids(const char * leadin, unsigned char * buff, int len, int do_hex,
if ((1 != c_set) || (1 != assoc) || (4 != i_len)) {
pr2serr(" << expected binary code_set, target "
"port association, length 4>>\n");
- dStrHexErr((const char *)ip, i_len, -1);
+ hex2stderr(ip, i_len, -1);
break;
}
d_id = sg_get_unaligned_be16(ip + 2);
@@ -1729,7 +1727,7 @@ decode_dev_ids(const char * leadin, unsigned char * buff, int len, int do_hex,
if ((1 != c_set) || (0 != assoc) || (4 != i_len)) {
pr2serr(" << expected binary code_set, logical "
"unit association, length 4>>\n");
- dStrHexErr((const char *)ip, i_len, -1);
+ hex2stderr(ip, i_len, -1);
break;
}
d_id = sg_get_unaligned_be16(ip + 2);
@@ -1739,11 +1737,11 @@ decode_dev_ids(const char * leadin, unsigned char * buff, int len, int do_hex,
if ((1 != c_set) || (0 != assoc)) {
pr2serr(" << expected binary code_set, logical "
"unit association>>\n");
- dStrHexErr((const char *)ip, i_len, -1);
+ hex2stderr(ip, i_len, -1);
break;
}
printf(" MD5 logical unit identifier:\n");
- dStrHex((const char *)ip, i_len, -1);
+ hex2stdout(ip, i_len, -1);
break;
case 8: /* SCSI name string */
if (3 != c_set) {
@@ -1752,7 +1750,7 @@ decode_dev_ids(const char * leadin, unsigned char * buff, int len, int do_hex,
pr2serr(" << expected UTF-8, use ASCII>>\n");
} else {
pr2serr(" << expected UTF-8 code_set>>\n");
- dStrHexErr((const char *)ip, i_len, -1);
+ hex2stderr(ip, i_len, -1);
break;
}
}
@@ -1787,13 +1785,13 @@ decode_dev_ids(const char * leadin, unsigned char * buff, int len, int do_hex,
case 0xa: /* UUID identifier [spc5r08] RFC 4122 */
if (1 != c_set) {
pr2serr(" << expected binary code_set >>\n");
- dStrHexErr((const char *)ip, i_len, 0);
+ hex2stderr(ip, i_len, 0);
break;
}
if ((1 != ((ip[0] >> 4) & 0xf)) || (18 != i_len)) {
pr2serr(" << expected locally assigned UUID, 16 bytes "
"long >>\n");
- dStrHexErr((const char *)ip, i_len, 0);
+ hex2stderr(ip, i_len, 0);
break;
}
printf(" Locally assigned UUID: ");
@@ -1806,7 +1804,7 @@ decode_dev_ids(const char * leadin, unsigned char * buff, int len, int do_hex,
break;
default: /* reserved */
pr2serr(" reserved designator=0x%x\n", desig_type);
- dStrHexErr((const char *)ip, i_len, -1);
+ hex2stderr(ip, i_len, -1);
break;
}
}
@@ -1929,7 +1927,7 @@ export_dev_ids(unsigned char * buff, int len, int verbose)
if (1 != c_set) {
if (verbose) {
pr2serr(" << expected binary code_set (1)>>\n");
- dStrHexErr((const char *)ip, i_len, 0);
+ hex2stderr(ip, i_len, 0);
}
break;
}
@@ -1942,7 +1940,7 @@ export_dev_ids(unsigned char * buff, int len, int verbose)
if (1 != c_set) {
if (verbose) {
pr2serr(" << expected binary code_set (1)>>\n");
- dStrHexErr((const char *)ip, i_len, 0);
+ hex2stderr(ip, i_len, 0);
}
break;
}
@@ -1977,7 +1975,7 @@ export_dev_ids(unsigned char * buff, int len, int verbose)
if (verbose) {
pr2serr(" << expected binary code_set, target "
"port association, length 4>>\n");
- dStrHexErr((const char *)ip, i_len, 0);
+ hex2stderr(ip, i_len, 0);
}
break;
}
@@ -1989,7 +1987,7 @@ export_dev_ids(unsigned char * buff, int len, int verbose)
if (verbose) {
pr2serr(" << expected binary code_set, target "
"port association, length 4>>\n");
- dStrHexErr((const char *)ip, i_len, 0);
+ hex2stderr(ip, i_len, 0);
}
break;
}
@@ -2001,7 +1999,7 @@ export_dev_ids(unsigned char * buff, int len, int verbose)
if (verbose) {
pr2serr(" << expected binary code_set, logical "
"unit association, length 4>>\n");
- dStrHexErr((const char *)ip, i_len, 0);
+ hex2stderr(ip, i_len, 0);
}
break;
}
@@ -2013,18 +2011,18 @@ export_dev_ids(unsigned char * buff, int len, int verbose)
if (verbose) {
pr2serr(" << expected binary code_set, logical "
"unit association>>\n");
- dStrHexErr((const char *)ip, i_len, 0);
+ hex2stderr(ip, i_len, 0);
}
break;
}
printf("SCSI_IDENT_%s_MD5=", assoc_str);
- dStrHex((const char *)ip, i_len, -1);
+ hex2stdout(ip, i_len, -1);
break;
case 8: /* SCSI name string */
if (3 != c_set) {
if (verbose) {
pr2serr(" << expected UTF-8 code_set>>\n");
- dStrHexErr((const char *)ip, i_len, -1);
+ hex2stderr(ip, i_len, -1);
}
break;
}
@@ -2035,7 +2033,7 @@ export_dev_ids(unsigned char * buff, int len, int verbose)
strncmp((const char *)ip, "iqn.", 4))) {
if (verbose) {
pr2serr(" << expected name string prefix>>\n");
- dStrHexErr((const char *)ip, i_len, -1);
+ hex2stderr(ip, i_len, -1);
}
break;
}
@@ -2049,7 +2047,7 @@ export_dev_ids(unsigned char * buff, int len, int verbose)
if (verbose) {
pr2serr(" << UAS (USB) expected target "
"port association>>\n");
- dStrHexErr((const char *)ip, i_len, 0);
+ hex2stderr(ip, i_len, 0);
}
break;
}
@@ -2062,7 +2060,7 @@ export_dev_ids(unsigned char * buff, int len, int verbose)
if (verbose) {
pr2serr(" << SOP (PCIe) descriptor "
"length=%d >>\n", i_len);
- dStrHexErr((const char *)ip, i_len, 0);
+ hex2stderr(ip, i_len, 0);
}
break;
}
@@ -2077,7 +2075,7 @@ export_dev_ids(unsigned char * buff, int len, int verbose)
if (1 != c_set) {
if (verbose) {
pr2serr(" << expected binary code_set (1)>>\n");
- dStrHexErr((const char *)ip, i_len, 0);
+ hex2stderr(ip, i_len, 0);
}
break;
}
@@ -2085,7 +2083,7 @@ export_dev_ids(unsigned char * buff, int len, int verbose)
if (verbose) {
pr2serr(" << short UUID field expected 18 or more, "
"got %d >>\n", i_len);
- dStrHexErr((const char *)ip, i_len, 0);
+ hex2stderr(ip, i_len, 0);
}
break;
}
@@ -2101,7 +2099,7 @@ export_dev_ids(unsigned char * buff, int len, int verbose)
default: /* reserved */
if (verbose) {
pr2serr(" reserved designator=0x%x\n", desig_type);
- dStrHexErr((const char *)ip, i_len, -1);
+ hex2stderr(ip, i_len, -1);
}
break;
}
@@ -2120,7 +2118,7 @@ decode_x_inq_vpd(unsigned char * buff, int len, int do_hex)
return;
}
if (do_hex) {
- dStrHex((const char *)buff, len, (1 == do_hex) ? 0 : -1);
+ hex2stdout(buff, len, (1 == do_hex) ? 0 : -1);
return;
}
printf(" ACTIVATE_MICROCODE=%d SPT=%d GRD_CHK=%d APP_CHK=%d "
@@ -2164,7 +2162,7 @@ static void
decode_softw_inf_id(unsigned char * buff, int len, int do_hex)
{
if (do_hex) {
- dStrHex((const char *)buff, len, (1 == do_hex) ? 0 : -1);
+ hex2stdout(buff, len, (1 == do_hex) ? 0 : -1);
return;
}
len -= 4;
@@ -2187,7 +2185,7 @@ decode_ata_info_vpd(unsigned char * buff, int len, int do_hex)
return;
}
if (do_hex && (2 != do_hex)) {
- dStrHex((const char *)buff, len, (3 == do_hex) ? 0 : -1);
+ hex2stdout(buff, len, (3 == do_hex) ? 0 : -1);
return;
}
memcpy(b, buff + 8, 8);
@@ -2202,7 +2200,7 @@ decode_ata_info_vpd(unsigned char * buff, int len, int do_hex)
if (len < 56)
return;
printf(" Signature (Device to host FIS):\n");
- dStrHex((const char *)buff + 36, 20, 1);
+ hex2stdout(buff + 36, 20, 1);
if (len < 60)
return;
is_be = sg_is_big_endian();
@@ -2228,7 +2226,7 @@ decode_ata_info_vpd(unsigned char * buff, int len, int do_hex)
if (len < 572)
return;
if (2 == do_hex)
- dStrHex((const char *)(buff + 60), 512, 0);
+ hex2stdout(buff + 60, 512, 0);
else
dWordHex((const unsigned short *)(buff + 60), 256, 0,
sg_is_big_endian());
@@ -2243,7 +2241,7 @@ decode_power_condition(unsigned char * buff, int len, int do_hex)
return;
}
if (do_hex) {
- dStrHex((const char *)buff, len, (1 == do_hex) ? 0 : -1);
+ hex2stdout(buff, len, (1 == do_hex) ? 0 : -1);
return;
}
printf(" Standby_y=%d Standby_z=%d Idle_c=%d Idle_b=%d Idle_a=%d\n",
@@ -2275,7 +2273,7 @@ decode_feature_sets_vpd(unsigned char * buff, int len,
char b[64];
if ((1 == op->do_hex) || (op->do_hex > 2)) {
- dStrHex((const char *)buff, len, (1 == op->do_hex) ? 1 : -1);
+ hex2stdout(buff, len, (1 == op->do_hex) ? 1 : -1);
return;
}
if (len < 4) {
@@ -2293,9 +2291,9 @@ decode_feature_sets_vpd(unsigned char * buff, int len,
return;
}
if (2 == op->do_hex)
- dStrHex((const char *)bp + 8, 2, 1);
+ hex2stdout(bp + 8, 2, 1);
else if (op->do_hex > 2)
- dStrHex((const char *)bp, 2, 1);
+ hex2stdout(bp, 2, 1);
else {
printf(" %s", sg_get_sfs_str(sf_code, -2, sizeof(b), b,
&found, op->do_verbose));
@@ -2322,7 +2320,7 @@ decode_b0_vpd(unsigned char * buff, int len, int do_hex)
bool ugavalid;
if (do_hex) {
- dStrHex((const char *)buff, len, (1 == do_hex) ? 0 : -1);
+ hex2stdout(buff, len, (1 == do_hex) ? 0 : -1);
return;
}
pdt = 0x1f & buff[0];
@@ -2447,7 +2445,7 @@ decode_b0_vpd(unsigned char * buff, int len, int do_hex)
case PDT_OSD:
default:
printf(" Unable to decode pdt=0x%x, in hex:\n", pdt);
- dStrHex((const char *)buff, len, 0);
+ hex2stdout(buff, len, 0);
break;
}
}
@@ -2462,7 +2460,7 @@ decode_b1_vpd(unsigned char * buff, int len, int do_hex)
unsigned int u;
if (do_hex) {
- dStrHex((const char *)buff, len, (1 == do_hex) ? 0 : -1);
+ hex2stdout(buff, len, (1 == do_hex) ? 0 : -1);
return;
}
pdt = 0x1f & buff[0];
@@ -2524,7 +2522,7 @@ decode_b1_vpd(unsigned char * buff, int len, int do_hex)
/* fall through */
default:
printf(" Unable to decode pdt=0x%x, in hex:\n", pdt);
- dStrHex((const char *)buff, len, 0);
+ hex2stdout(buff, len, 0);
break;
}
}
@@ -2537,7 +2535,7 @@ decode_b3_vpd(unsigned char * buff, int len, int do_hex)
unsigned int s, m;
if (do_hex) {
- dStrHex((const char *)buff, len, (1 == do_hex) ? 0 : -1);
+ hex2stdout(buff, len, (1 == do_hex) ? 0 : -1);
return;
}
pdt = 0x1f & buff[0];
@@ -2559,7 +2557,7 @@ decode_b3_vpd(unsigned char * buff, int len, int do_hex)
break;
default:
printf(" Unable to decode pdt=0x%x, in hex:\n", pdt);
- dStrHex((const char *)buff, len, 0);
+ hex2stdout(buff, len, 0);
break;
}
}
@@ -2621,7 +2619,7 @@ decode_upr_vpd_c0_emc(unsigned char * buff, int len, int do_hex)
return;
}
if (do_hex) {
- dStrHex((const char *)buff, len, (1 == do_hex) ? 1 : -1);
+ hex2stdout(buff, len, (1 == do_hex) ? 1 : -1);
return;
}
if (buff[9] != 0x00) {
@@ -2697,7 +2695,7 @@ decode_rdac_vpd_c2(unsigned char * buff, int len, int do_hex)
return;
}
if (do_hex) {
- dStrHex((const char *)buff, len, (1 == do_hex) ? 1 : -1);
+ hex2stdout(buff, len, (1 == do_hex) ? 1 : -1);
return;
}
if (buff[4] != 's' && buff[5] != 'w' && buff[6] != 'r') {
@@ -2795,7 +2793,7 @@ decode_rdac_vpd_c9(unsigned char * buff, int len, int do_hex)
return;
}
if (do_hex) {
- dStrHex((const char *)buff, len, (1 == do_hex) ? 1 : -1);
+ hex2stdout(buff, len, (1 == do_hex) ? 1 : -1);
return;
}
if (buff[4] != 'v' && buff[5] != 'a' && buff[6] != 'c') {
@@ -2923,7 +2921,7 @@ std_inq_response(const struct opts_t * op, int act_len)
return 0;
} else if (op->do_hex) {
/* with -H, print with address, -HH without */
- dStrHex((const char *)rp, act_len, ((1 == op->do_hex) ? 0 : -1));
+ hex2stdout(rp, act_len, ((1 == op->do_hex) ? 0 : -1));
return 0;
}
pqual = (rp[0] & 0xe0) >> 5;
@@ -3234,7 +3232,7 @@ std_inq_process(int sg_fd, const struct opts_t * op, int inhex_len)
if (0 == res) {
if ((verb > 4) && ((rlen - resid) > 0)) {
pr2serr("Safe (36 byte) Inquiry response:\n");
- dStrHex((const char *)rsp_buff, rlen - resid, 0);
+ hex2stdout(rsp_buff, rlen - resid, 0);
}
len = rsp_buff[4] + 5;
if ((len > SAFE_STD_INQ_RESP_LEN) && (len < 256) &&
@@ -3356,8 +3354,7 @@ cmddt_process(int sg_fd, const struct opts_t * op)
len = rsp_buff[5] + 6;
reserved_cmddt = rsp_buff[4];
if (op->do_hex)
- dStrHex((const char *)rsp_buff, len,
- (1 == op->do_hex) ? 0 : -1);
+ hex2stdout(rsp_buff, len, (1 == op->do_hex) ? 0 : -1);
else if (op->do_raw)
dStrRaw((const char *)rsp_buff, len);
else {
@@ -3459,7 +3456,7 @@ vpd_mainly_hex(int sg_fd, const struct opts_t * op, int inhex_len)
printf(" [PQual=%d Peripheral device type: %s]\n",
(rp[0] & 0xe0) >> 5, cp);
}
- dStrHex((const char *)rp, len, ((1 == op->do_hex) ? 0 : -1));
+ hex2stdout(rp, len, ((1 == op->do_hex) ? 0 : -1));
}
}
} else {
@@ -3509,8 +3506,7 @@ vpd_decode(int sg_fd, const struct opts_t * op, int inhex_len)
if (op->do_raw)
dStrRaw((const char *)rp, len);
else if (op->do_hex)
- dStrHex((const char *)rp, len,
- (1 == op->do_hex) ? 0 : -1);
+ hex2stdout(rp, len, (1 == op->do_hex) ? 0 : -1);
else
decode_supported_vpd(rp, len, 0x1f & rp[0]);
break;
@@ -3523,8 +3519,7 @@ vpd_decode(int sg_fd, const struct opts_t * op, int inhex_len)
if (op->do_raw)
dStrRaw((const char *)rp, len);
else if (op->do_hex)
- dStrHex((const char *)rp, len,
- (1 == op->do_hex) ? 0 : -1);
+ hex2stdout(rp, len, (1 == op->do_hex) ? 0 : -1);
else {
char obuff[DEF_ALLOC_LEN];
int k, m;
@@ -3566,7 +3561,7 @@ vpd_decode(int sg_fd, const struct opts_t * op, int inhex_len)
if (op->do_raw)
dStrRaw((const char *)rp, len);
else if (op->do_hex > 2)
- dStrHex((const char *)rp, len, -1);
+ hex2stdout(rp, len, -1);
else if (op->do_export)
export_dev_ids(rp + 4, len - 4, op->do_verbose);
else
@@ -3828,58 +3823,37 @@ nvme_hex_raw(const unsigned char * b, int b_len, const struct opts_t * op)
else if (op->do_hex) {
if (op->do_hex < 3) {
printf("data_in buffer:\n");
- dStrHex((const char *)b, b_len, (2 == op->do_hex));
+ hex2stdout(b, b_len, (2 == op->do_hex));
} else
- dStrHex((const char *)b, b_len, -1);
+ hex2stdout(b, b_len, -1);
}
}
-const char * rperf[] = {"Best", "Better", "Good", "Degraded"};
+static const char * rperf[] = {"Best", "Better", "Good", "Degraded"};
-/* Send Identify(CNS=0, nsid) and decode the Identify namespace response */
-static int
-nvme_id_namespace(struct sg_pt_base * ptvp, uint32_t nsid,
- struct sg_nvme_passthru_cmd * id_cmdp, uint8_t * id_dinp,
- int id_din_len, const struct opts_t * op)
+static void
+show_nvme_id_ns(const uint8_t * dinp, int do_long)
{
bool got_eui_128 = false;
- int ret = 0;
- int vb = op->do_verbose;
uint32_t u, k, off, num_lbaf, flbas, flba_info, md_size, lb_size;
uint64_t ns_sz, eui_64;
- struct sg_nvme_passthru_cmd cmd_back;
- clear_scsi_pt_obj(ptvp);
- id_cmdp->nsid = nsid;
- id_cmdp->cdw10 = 0x0; /* CNS=0x0 Identify NS */
- set_scsi_pt_data_in(ptvp, id_dinp, id_din_len);
- set_scsi_pt_sense(ptvp, (unsigned char *)&cmd_back, sizeof(cmd_back));
- set_scsi_pt_cdb(ptvp, (const uint8_t *)id_cmdp, sizeof(*id_cmdp));
- ret = do_scsi_pt(ptvp, -1, 0 /* timeout (def: 1 min) */, vb);
- if (vb > 2)
- pr2serr("%s: do_scsi_pt() result is %d\n", __func__, ret);
- if (ret)
- return ret;
- num_lbaf = id_dinp[25] + 1; /* spec says this is "0's based value" */
- flbas = id_dinp[26] & 0xf; /* index of active LBA format (for this ns) */
- if (op->do_hex || op->do_raw) {
- nvme_hex_raw(id_dinp, id_din_len, op);
- return 0;
- }
- ns_sz = sg_get_unaligned_le64(id_dinp + 0);
- eui_64 = sg_get_unaligned_be64(id_dinp + 120); /* N.B. big endian */
- if (! sg_all_zeros(id_dinp + 104, 16))
+ num_lbaf = dinp[25] + 1; /* spec says this is "0's based value" */
+ flbas = dinp[26] & 0xf; /* index of active LBA format (for this ns) */
+ ns_sz = sg_get_unaligned_le64(dinp + 0);
+ eui_64 = sg_get_unaligned_be64(dinp + 120); /* N.B. big endian */
+ if (! sg_all_zeros(dinp + 104, 16))
got_eui_128 = true;
printf(" Namespace size/capacity: %" PRIu64 "/%" PRIu64
- " blocks\n", ns_sz, sg_get_unaligned_le64(id_dinp + 8));
+ " blocks\n", ns_sz, sg_get_unaligned_le64(dinp + 8));
printf(" Namespace utilization: %" PRIu64 " blocks\n",
- sg_get_unaligned_le64(id_dinp + 16));
+ sg_get_unaligned_le64(dinp + 16));
if (got_eui_128) { /* N.B. big endian */
- printf(" NGUID: 0x%02x", id_dinp[104]);
+ printf(" NGUID: 0x%02x", dinp[104]);
for (k = 1; k < 16; ++k)
- printf("%02x", id_dinp[104 + k]);
+ printf("%02x", dinp[104 + k]);
printf("\n");
- } else if (op->do_long)
+ } else if (do_long)
printf(" NGUID: 0x0\n");
if (eui_64)
printf(" EUI-64: 0x%" PRIx64 "\n", eui_64); /* N.B. big endian */
@@ -3891,7 +3865,7 @@ nvme_id_namespace(struct sg_pt_base * ptvp, uint32_t nsid,
printf(" <-- active\n");
else
printf("\n");
- flba_info = sg_get_unaligned_le32(id_dinp + off);
+ flba_info = sg_get_unaligned_le32(dinp + off);
md_size = flba_info & 0xffff;
lb_size = flba_info >> 16 & 0xff;
if (lb_size > 31) {
@@ -3913,75 +3887,53 @@ nvme_id_namespace(struct sg_pt_base * ptvp, uint32_t nsid,
printf(" Metadata size: %u bytes\n", md_size);
printf(" Relative performance: %s [0x%x]\n", rperf[u], u);
}
- return ret;
}
-/* Send a NVMe Identify(CNS=1, nsid=0) and decode Controller info. If the
- * device name includes a namespace indication (e.g. /dev/nvme0ns1) then
- * an Identify namespace command is sent to that namespace (e.g. 1). If the
- * device name does not contain a namespace indication (e.g. /dev/nvme0)
- * and --only is not given then nvme_id_namespace() is sent for each
- * namespace in the controller. Namespaces number sequentially starting at
- * 1 . The CNS (Controller or Namespace Structure) field is CDW10 7:0, was
- * only bit 0 in NVMe 1.0 and bits 1:0 in NVMe 1.1, thereafter 8 bits. */
+/* Send Identify(CNS=0, nsid) and decode the Identify namespace response */
static int
-do_nvme_identify(int pt_fd, const struct opts_t * op)
+nvme_id_namespace(struct sg_pt_base * ptvp, uint32_t nsid,
+ struct sg_nvme_passthru_cmd * id_cmdp, uint8_t * id_dinp,
+ int id_din_len, const struct opts_t * op)
{
- bool got_fguid;
int ret = 0;
int vb = op->do_verbose;
- uint8_t ver_min, ver_ter, mtds;
- uint16_t ver_maj, oacs, oncs;
- uint32_t k, ver, nsid, max_nsid, npss, j, n, m;
- uint64_t sz1, sz2;
- uint8_t * up;
- struct sg_pt_base * ptvp;
- struct sg_nvme_passthru_cmd identify_cmd;
- struct sg_nvme_passthru_cmd cmd_back;
- struct sg_nvme_passthru_cmd * id_cmdp = &identify_cmd;
- uint8_t * id_dinp = NULL;
- uint8_t * free_id_dinp = NULL;
- const uint32_t pg_sz = sg_get_page_size();
+ uint8_t resp[16];
- if (op->do_raw) {
- if (sg_set_binary_mode(STDOUT_FILENO) < 0) {
- perror("sg_set_binary_mode");
- return SG_LIB_FILE_ERROR;
- }
- }
- ptvp = construct_scsi_pt_obj_with_fd(pt_fd, vb);
- if (NULL == ptvp) {
- pr2serr("%s: memory problem\n", __func__);
- return SG_LIB_CAT_OTHER;
- }
- memset(id_cmdp, 0, sizeof(*id_cmdp));
- id_cmdp->opcode = 0x6;
- nsid = get_pt_nvme_nsid(ptvp);
- /* leave id_cmdp->nsid at 0 */
- id_cmdp->cdw10 = 0x1; /* CNS=0x1 Identify controller */
- id_dinp = sg_memalign(pg_sz, pg_sz, &free_id_dinp, vb > 3);
- set_scsi_pt_data_in(ptvp, id_dinp, pg_sz);
+ clear_scsi_pt_obj(ptvp);
+ id_cmdp->nsid = nsid;
+ id_cmdp->cdw10 = 0x0; /* CNS=0x0 Identify NS */
+ set_scsi_pt_data_in(ptvp, id_dinp, id_din_len);
+ set_scsi_pt_sense(ptvp, resp, sizeof(resp));
set_scsi_pt_cdb(ptvp, (const uint8_t *)id_cmdp, sizeof(*id_cmdp));
- set_scsi_pt_sense(ptvp, (unsigned char *)&cmd_back, sizeof(cmd_back));
ret = do_scsi_pt(ptvp, -1, 0 /* timeout (def: 1 min) */, vb);
if (vb > 2)
- pr2serr("%s: do_scsi_pt result is %d\n", __func__, ret);
+ pr2serr("%s: do_scsi_pt() result is %d\n", __func__, ret);
if (ret)
- goto err_out;
- max_nsid = sg_get_unaligned_le32(id_dinp + 516); /* NN */
- if (op->do_raw || op->do_hex) {
- if (op->do_only || (SG_NVME_CTL_NSID == nsid ) ||
- (SG_NVME_BROADCAST_NSID == nsid)) {
- nvme_hex_raw(id_dinp, pg_sz, op);
- goto fini;
- }
- goto skip1;
+ return ret;
+ if (op->do_hex || op->do_raw) {
+ nvme_hex_raw(id_dinp, id_din_len, op);
+ return 0;
}
- printf("Identify controller for %s:\n", op->device_name);
- printf(" Model number: %.40s\n", (const char *)(id_dinp + 24));
- printf(" Serial number: %.20s\n", (const char *)(id_dinp + 4));
- printf(" Firmware revision: %.8s\n", (const char *)(id_dinp + 64));
- ver = sg_get_unaligned_le32(id_dinp + 80);
+ show_nvme_id_ns(id_dinp, op->do_long);
+ return 0;
+}
+
+static void
+show_nvme_id_ctl(const uint8_t *dinp, const char *dev_name, int do_long)
+{
+ bool got_fguid;
+ uint8_t ver_min, ver_ter, mtds;
+ uint16_t ver_maj, oacs, oncs;
+ uint32_t k, ver, max_nsid, npss, j, n, m;
+ uint64_t sz1, sz2;
+ const uint8_t * up;
+
+ max_nsid = sg_get_unaligned_le32(dinp + 516); /* NN */
+ printf("Identify controller for %s:\n", dev_name);
+ printf(" Model number: %.40s\n", (const char *)(dinp + 24));
+ printf(" Serial number: %.20s\n", (const char *)(dinp + 4));
+ printf(" Firmware revision: %.8s\n", (const char *)(dinp + 64));
+ ver = sg_get_unaligned_le32(dinp + 80);
ver_maj = (ver >> 16);
ver_min = (ver >> 8) & 0xff;
ver_ter = (ver & 0xff);
@@ -3991,7 +3943,7 @@ do_nvme_identify(int pt_fd, const struct opts_t * op)
printf(".%u\n", ver_ter);
else
printf("\n");
- oacs = sg_get_unaligned_le16(id_dinp + 256);
+ oacs = sg_get_unaligned_le16(dinp + 256);
if (0x1ff & oacs) {
printf(" Optional admin command support:\n");
if (0x100 & oacs)
@@ -4014,7 +3966,7 @@ do_nvme_identify(int pt_fd, const struct opts_t * op)
printf(" Security send and receive\n");
} else
printf(" No optional admin command support\n");
- oncs = sg_get_unaligned_le16(id_dinp + 256);
+ oncs = sg_get_unaligned_le16(dinp + 256);
if (0x7f & oncs) {
printf(" Optional NVM command support:\n");
if (0x40 & oncs)
@@ -4034,47 +3986,47 @@ do_nvme_identify(int pt_fd, const struct opts_t * op)
} else
printf(" No optional NVM command support\n");
printf(" PCI vendor ID VID/SSVID: 0x%x/0x%x\n",
- sg_get_unaligned_le16(id_dinp + 0),
- sg_get_unaligned_le16(id_dinp + 2));
+ sg_get_unaligned_le16(dinp + 0),
+ sg_get_unaligned_le16(dinp + 2));
printf(" IEEE OUI Identifier: 0x%x\n",
- sg_get_unaligned_le24(id_dinp + 73));
- got_fguid = ! sg_all_zeros(id_dinp + 112, 16);
+ sg_get_unaligned_le24(dinp + 73));
+ got_fguid = ! sg_all_zeros(dinp + 112, 16);
if (got_fguid) {
- printf(" FGUID: 0x%02x", id_dinp[112]);
+ printf(" FGUID: 0x%02x", dinp[112]);
for (k = 1; k < 16; ++k)
- printf("%02x", id_dinp[112 + k]);
+ printf("%02x", dinp[112 + k]);
printf("\n");
- } else if (op->do_long)
+ } else if (do_long)
printf(" FGUID: 0x0\n");
- printf(" Controller ID: 0x%x\n", sg_get_unaligned_le16(id_dinp + 78));
- if (op->do_long) {
+ printf(" Controller ID: 0x%x\n", sg_get_unaligned_le16(dinp + 78));
+ if (do_long) {
printf(" Management endpoint capabilities, over a PCIe port: %d\n",
- !! (0x2 & id_dinp[255]));
+ !! (0x2 & dinp[255]));
printf(" Management endpoint capabilities, over a SMBus/I2C port: "
- "%d\n", !! (0x1 & id_dinp[255]));
+ "%d\n", !! (0x1 & dinp[255]));
}
printf(" Number of namespaces: %u\n", max_nsid);
- sz1 = sg_get_unaligned_le64(id_dinp + 280); /* lower 64 bits */
- sz2 = sg_get_unaligned_le64(id_dinp + 288); /* upper 64 bits */
+ sz1 = sg_get_unaligned_le64(dinp + 280); /* lower 64 bits */
+ sz2 = sg_get_unaligned_le64(dinp + 288); /* upper 64 bits */
if (sz2)
printf(" Total NVM capacity: huge ...\n");
else if (sz1)
printf(" Total NVM capacity: %" PRIu64 " bytes\n", sz1);
- mtds = id_dinp[77];
+ mtds = dinp[77];
printf(" Maximum data transfer size: ");
if (mtds)
printf("%u pages\n", 1U << mtds);
else
printf("<unlimited>\n");
- if (op->do_long) {
+ if (do_long) {
const char * const non_op = "does not process I/O";
const char * const operat = "processes I/O";
const char * cp;
printf(" Total NVM capacity: 0 bytes\n");
- npss = id_dinp[263] + 1;
- up = id_dinp + 2048;
+ npss = dinp[263] + 1;
+ up = dinp + 2048;
for (k = 0; k < npss; ++k, up += 32) {
n = sg_get_unaligned_le16(up + 0);
n *= (0x1 & up[3]) ? 1 : 100; /* unit: 100 microWatts */
@@ -4109,6 +4061,65 @@ do_nvme_identify(int pt_fd, const struct opts_t * op)
printf("RWL=%u\n", n);
}
}
+}
+
+/* Send a NVMe Identify(CNS=1, nsid=0) and decode Controller info. If the
+ * device name includes a namespace indication (e.g. /dev/nvme0ns1) then
+ * an Identify namespace command is sent to that namespace (e.g. 1). If the
+ * device name does not contain a namespace indication (e.g. /dev/nvme0)
+ * and --only is not given then nvme_id_namespace() is sent for each
+ * namespace in the controller. Namespaces number sequentially starting at
+ * 1 . The CNS (Controller or Namespace Structure) field is CDW10 7:0, was
+ * only bit 0 in NVMe 1.0 and bits 1:0 in NVMe 1.1, thereafter 8 bits. */
+static int
+do_nvme_identify(int pt_fd, const struct opts_t * op)
+{
+ int ret = 0;
+ int vb = op->do_verbose;
+ uint32_t k, nsid, max_nsid;
+ struct sg_pt_base * ptvp;
+ struct sg_nvme_passthru_cmd identify_cmd;
+ struct sg_nvme_passthru_cmd * id_cmdp = &identify_cmd;
+ uint8_t * id_dinp = NULL;
+ uint8_t * free_id_dinp = NULL;
+ const uint32_t pg_sz = sg_get_page_size();
+ uint8_t resp[16];
+
+ if (op->do_raw) {
+ if (sg_set_binary_mode(STDOUT_FILENO) < 0) {
+ perror("sg_set_binary_mode");
+ return SG_LIB_FILE_ERROR;
+ }
+ }
+ ptvp = construct_scsi_pt_obj_with_fd(pt_fd, vb);
+ if (NULL == ptvp) {
+ pr2serr("%s: memory problem\n", __func__);
+ return SG_LIB_CAT_OTHER;
+ }
+ memset(id_cmdp, 0, sizeof(*id_cmdp));
+ id_cmdp->opcode = 0x6;
+ nsid = get_pt_nvme_nsid(ptvp);
+ /* leave id_cmdp->nsid at 0 */
+ id_cmdp->cdw10 = 0x1; /* CNS=0x1 Identify controller */
+ id_dinp = sg_memalign(pg_sz, pg_sz, &free_id_dinp, vb > 3);
+ set_scsi_pt_data_in(ptvp, id_dinp, pg_sz);
+ set_scsi_pt_cdb(ptvp, (const uint8_t *)id_cmdp, sizeof(*id_cmdp));
+ set_scsi_pt_sense(ptvp, resp, sizeof(resp));
+ ret = do_scsi_pt(ptvp, -1, 0 /* timeout (def: 1 min) */, vb);
+ if (vb > 2)
+ pr2serr("%s: do_scsi_pt result is %d\n", __func__, ret);
+ if (ret)
+ goto err_out;
+ max_nsid = sg_get_unaligned_le32(id_dinp + 516); /* NN */
+ if (op->do_raw || op->do_hex) {
+ if (op->do_only || (SG_NVME_CTL_NSID == nsid ) ||
+ (SG_NVME_BROADCAST_NSID == nsid)) {
+ nvme_hex_raw(id_dinp, pg_sz, op);
+ goto fini;
+ }
+ goto skip1;
+ }
+ show_nvme_id_ctl(id_dinp, op->device_name, op->do_long);
skip1:
if (op->do_only)
goto fini;
@@ -4668,7 +4679,7 @@ try_ata_identify(int ata_fd, int do_hex, int do_raw, int verbose)
printf("ATA IDENTIFY DEVICE response ");
if (do_hex > 1) {
printf("(512 bytes):\n");
- dStrHex((const char *)&ata_ident, 512, 0);
+ hex2stdout((const uint8_t *)&ata_ident, 512, 0);
} else {
printf("(256 words):\n");
dWordHex((const unsigned short *)&ata_ident, 256, 0,
diff --git a/src/sg_logs.c b/src/sg_logs.c
index 94c3b504..7c5ccda6 100644
--- a/src/sg_logs.c
+++ b/src/sg_logs.c
@@ -28,11 +28,13 @@
#endif
#include "sg_lib.h"
#include "sg_cmds_basic.h"
+#ifdef SG_LIB_WIN32
#include "sg_pt.h" /* needed for scsi_pt_win32_direct() */
+#endif
#include "sg_unaligned.h"
#include "sg_pr2serr.h"
-static const char * version_str = "1.59 20180102"; /* spc5r17 + sbc4r11 */
+static const char * version_str = "1.60 20180119"; /* spc5r17 + sbc4r11 */
#define MX_ALLOC_LEN (0xfffc)
#define SHORT_RESP_LEN 128
@@ -1311,11 +1313,11 @@ process_cl(struct opts_t * op, int argc, char * argv[])
}
static void
-dStrRaw(const char* str, int len)
+dStrRaw(const char * str, int len)
{
int k;
- for (k = 0 ; k < len; ++k)
+ for (k = 0; k < len; ++k)
printf("%c", str[k]);
}
@@ -1569,7 +1571,7 @@ do_logs(int sg_fd, uint8_t * resp, int mx_resp_len,
calc_len = sg_get_unaligned_be16(resp + 2) + 4;
if ((! op->do_raw) && (vb > 1)) {
pr2serr(" Log sense (find length) response:\n");
- dStrHexErr((const char *)resp, LOG_SENSE_PROBE_ALLOC_LEN, 1);
+ hex2stderr(resp, LOG_SENSE_PROBE_ALLOC_LEN, 1);
pr2serr(" hence calculated response length=%d\n", calc_len);
}
if (op->pg_code != (0x3f & resp[0])) {
@@ -1607,7 +1609,7 @@ do_logs(int sg_fd, uint8_t * resp, int mx_resp_len,
}
if ((! op->do_raw) && (vb > 1)) {
pr2serr(" Log sense response:\n");
- dStrHexErr((const char *)resp, request_len, 1);
+ hex2stderr(resp, request_len, 1);
}
return 0;
resid_err:
@@ -1616,7 +1618,7 @@ resid_err:
request_len -= resid;
if ((request_len > 0) && (! op->do_raw) && (vb > 1)) {
pr2serr(" Log sense (resid_err) response:\n");
- dStrHexErr((const char *)resp, request_len, 1);
+ hex2stderr(resp, request_len, 1);
}
return res;
}
@@ -1748,7 +1750,7 @@ show_buffer_over_under_run_page(const uint8_t * resp, int len,
dStrRaw((const char *)bp, pl);
break;
} else if (op->do_hex) {
- dStrHex((const char *)bp, pl, ((1 == op->do_hex) ? 1 : -1));
+ hex2stdout(bp, pl, ((1 == op->do_hex) ? 1 : -1));
break;
}
}
@@ -1889,7 +1891,7 @@ show_error_counter_page(const uint8_t * resp, int len,
dStrRaw((const char *)bp, pl);
break;
} else if (op->do_hex) {
- dStrHex((const char *)bp, pl, ((1 == op->do_hex) ? 1 : -1));
+ hex2stdout(bp, pl, ((1 == op->do_hex) ? 1 : -1));
break;
}
}
@@ -1941,7 +1943,7 @@ show_non_medium_error_page(const uint8_t * resp, int len,
dStrRaw((const char *)bp, pl);
break;
} else if (op->do_hex) {
- dStrHex((const char *)bp, pl, ((1 == op->do_hex) ? 1 : -1));
+ hex2stdout(bp, pl, ((1 == op->do_hex) ? 1 : -1));
break;
}
}
@@ -1992,7 +1994,7 @@ show_power_condition_transitions_page(const uint8_t * resp, int len,
dStrRaw((const char *)bp, pl);
break;
} else if (op->do_hex) {
- dStrHex((const char *)bp, pl, ((1 == op->do_hex) ? 1 : -1));
+ hex2stdout(bp, pl, ((1 == op->do_hex) ? 1 : -1));
break;
}
}
@@ -2080,7 +2082,7 @@ show_environmental_reporting_page(const uint8_t * resp, int len,
dStrRaw((const char *)bp, pl);
break;
} else if (op->do_hex) {
- dStrHex((const char *)bp, pl, ((1 == op->do_hex) ? 1 : -1));
+ hex2stdout(bp, pl, ((1 == op->do_hex) ? 1 : -1));
break;
}
}
@@ -2172,7 +2174,7 @@ show_environmental_limits_page(const uint8_t * resp, int len,
dStrRaw((const char *)bp, pl);
break;
} else if (op->do_hex) {
- dStrHex((const char *)bp, pl, ((1 == op->do_hex) ? 1 : -1));
+ hex2stdout(bp, pl, ((1 == op->do_hex) ? 1 : -1));
break;
}
}
@@ -2257,8 +2259,7 @@ show_tape_usage_page(const uint8_t * resp, int len, const struct opts_t * op)
dStrRaw((const char *)bp, extra);
break;
} else if (op->do_hex) {
- dStrHex((const char *)bp, extra,
- ((1 == op->do_hex) ? 1 : -1));
+ hex2stdout(bp, extra, ((1 == op->do_hex) ? 1 : -1));
break;
}
}
@@ -2322,7 +2323,7 @@ show_tape_usage_page(const uint8_t * resp, int len, const struct opts_t * op)
default:
printf(" unknown parameter code = 0x%x, contents in "
"hex:\n", pc);
- dStrHex((const char *)bp, extra, 1);
+ hex2stdout(bp, extra, 1);
break;
}
printf("\n");
@@ -2362,8 +2363,7 @@ show_tape_capacity_page(const uint8_t * resp, int len,
dStrRaw((const char *)bp, extra);
break;
} else if (op->do_hex) {
- dStrHex((const char *)bp, extra,
- ((1 == op->do_hex) ? 1 : -1));
+ hex2stdout(bp, extra, ((1 == op->do_hex) ? 1 : -1));
break;
}
}
@@ -2386,7 +2386,7 @@ show_tape_capacity_page(const uint8_t * resp, int len,
default:
printf(" unknown parameter code = 0x%x, contents in "
"hex:\n", pc);
- dStrHex((const char *)bp, extra, 1);
+ hex2stdout(bp, extra, 1);
break;
}
printf("\n");
@@ -2434,15 +2434,14 @@ show_data_compression_page(const uint8_t * resp, int len,
dStrRaw((const char *)bp, extra);
break;
} else if (op->do_hex) {
- dStrHex((const char *)bp, extra,
- ((1 == op->do_hex) ? 1 : -1));
+ hex2stdout(bp, extra, ((1 == op->do_hex) ? 1 : -1));
break;
}
}
if ((0 == pl) || (pl > 8)) {
printf("badly formed data compression log parameter\n");
printf(" parameter code = 0x%x, contents in hex:\n", pc);
- dStrHex((const char *)bp, extra, 1);
+ hex2stdout(bp, extra, 1);
goto skip_para;
}
/* variable length integer, max length 8 bytes */
@@ -2488,7 +2487,7 @@ show_data_compression_page(const uint8_t * resp, int len,
default:
printf(" unknown parameter code = 0x%x, contents in "
"hex:\n", pc);
- dStrHex((const char *)bp, extra, 1);
+ hex2stdout(bp, extra, 1);
break;
}
skip_para:
@@ -2532,7 +2531,7 @@ show_last_n_error_page(const uint8_t * resp, int len,
dStrRaw((const char *)bp, pl);
break;
} else if (op->do_hex) {
- dStrHex((const char *)bp, pl, ((1 == op->do_hex) ? 1 : -1));
+ hex2stdout(bp, pl, ((1 == op->do_hex) ? 1 : -1));
break;
}
}
@@ -2540,12 +2539,12 @@ show_last_n_error_page(const uint8_t * resp, int len,
if (pl > 4) {
if ((bp[2] & 0x1) && (bp[2] & 0x2)) {
printf(" [binary]:\n");
- dStrHex((const char *)bp + 4, pl - 4, 1);
+ hex2stdout(bp + 4, pl - 4, 1);
} else if (bp[2] & 0x1)
printf(" %.*s\n", pl - 4, (const char *)(bp + 4));
else {
printf(" [data counter?? (LP bit should be set)]:\n");
- dStrHex((const char *)bp + 4, pl - 4, 1);
+ hex2stdout(bp + 4, pl - 4, 1);
}
}
if (op->do_pcb)
@@ -2587,12 +2586,12 @@ show_last_n_deferred_error_page(const uint8_t * resp, int len,
dStrRaw((const char *)bp, pl);
break;
} else if (op->do_hex) {
- dStrHex((const char *)bp, pl, ((1 == op->do_hex) ? 1 : -1));
+ hex2stdout(bp, pl, ((1 == op->do_hex) ? 1 : -1));
break;
}
}
printf(" Deferred error %d:\n", pc);
- dStrHex((const char *)bp + 4, pl - 4, 1);
+ hex2stdout(bp + 4, pl - 4, 1);
if (op->do_pcb)
printf(" <%s>\n", get_pcb_str(bp[2], str, sizeof(str)));
if (op->filter_given)
@@ -2624,7 +2623,7 @@ show_last_n_inq_data_ch_page(const uint8_t * resp, int len,
dStrRaw((const char *)bp, pl);
break;
} else if (op->do_hex) {
- dStrHex((const char *)bp, pl, ((1 == op->do_hex) ? 1 : -1));
+ hex2stdout(bp, pl, ((1 == op->do_hex) ? 1 : -1));
break;
}
}
@@ -2683,7 +2682,7 @@ show_last_n_mode_pg_data_ch_page(const uint8_t * resp, int len,
dStrRaw((const char *)bp, pl);
break;
} else if (op->do_hex) {
- dStrHex((const char *)bp, pl, ((1 == op->do_hex) ? 1 : -1));
+ hex2stdout(bp, pl, ((1 == op->do_hex) ? 1 : -1));
break;
}
}
@@ -2767,7 +2766,7 @@ show_self_test_page(const uint8_t * resp, int len, const struct opts_t * op)
dStrRaw((const char *)bp, pl);
break;
} else if (op->do_hex) {
- dStrHex((const char *)bp, pl, ((1 == op->do_hex) ? 1 : -1));
+ hex2stdout(bp, pl, ((1 == op->do_hex) ? 1 : -1));
break;
}
}
@@ -2837,8 +2836,7 @@ show_temperature_page(const uint8_t * resp, int len, const struct opts_t * op)
dStrRaw((const char *)bp, extra);
break;
} else if (op->do_hex) {
- dStrHex((const char *)bp, extra,
- ((1 == op->do_hex) ? 1 : -1));
+ hex2stdout(bp, extra, ((1 == op->do_hex) ? 1 : -1));
break;
}
}
@@ -2865,7 +2863,7 @@ show_temperature_page(const uint8_t * resp, int len, const struct opts_t * op)
if (! op->do_temperature) {
printf(" unknown parameter code = 0x%x, contents in "
"hex:\n", pc);
- dStrHex((const char *)bp, extra, 1);
+ hex2stdout(bp, extra, 1);
} else
continue;
break;
@@ -2908,8 +2906,7 @@ show_start_stop_page(const uint8_t * resp, int len, const struct opts_t * op)
dStrRaw((const char *)bp, extra);
break;
} else if (op->do_hex) {
- dStrHex((const char *)bp, extra,
- ((1 == op->do_hex) ? 1 : -1));
+ hex2stdout(bp, extra, ((1 == op->do_hex) ? 1 : -1));
break;
}
}
@@ -2921,7 +2918,7 @@ show_start_stop_page(const uint8_t * resp, int len, const struct opts_t * op)
else if (op->verbose) {
pr2serr(" Date of manufacture parameter length strange: "
"%d\n", extra - 4);
- dStrHexErr((const char *)bp, extra, 1);
+ hex2stderr(bp, extra, 1);
}
break;
case 2:
@@ -2931,7 +2928,7 @@ show_start_stop_page(const uint8_t * resp, int len, const struct opts_t * op)
else if (op->verbose) {
pr2serr(" Accounting date parameter length strange: %d\n",
extra - 4);
- dStrHexErr((const char *)bp, extra, 1);
+ hex2stderr(bp, extra, 1);
}
break;
case 3:
@@ -2975,7 +2972,7 @@ show_start_stop_page(const uint8_t * resp, int len, const struct opts_t * op)
default:
printf(" unknown parameter code = 0x%x, contents in "
"hex:\n", pc);
- dStrHex((const char *)bp, extra, 1);
+ hex2stdout(bp, extra, 1);
break;
}
printf("\n");
@@ -3005,12 +3002,12 @@ show_app_client_page(const uint8_t * resp, int len, const struct opts_t * op)
printf("Application client page [0xf]\n");
if (0 == op->filter_given) {
if ((len > 128) && (0 == op->do_hex)) {
- dStrHex((const char *)resp, 64, 1);
+ hex2stdout(resp, 64, 1);
printf(" ..... [truncated after 64 of %d bytes (use '-H' to "
"see the rest)]\n", len);
}
else
- dStrHex((const char *)resp, len, 1);
+ hex2stdout(resp, len, 1);
return true;
}
/* only here if filter_given set */
@@ -3026,11 +3023,11 @@ show_app_client_page(const uint8_t * resp, int len, const struct opts_t * op)
if (op->do_raw)
dStrRaw((const char *)bp, extra);
else if (0 == op->do_hex)
- dStrHex((const char *)bp, extra, 0);
+ hex2stdout(bp, extra, 0);
else if (1 == op->do_hex)
- dStrHex((const char *)bp, extra, 1);
+ hex2stdout(bp, extra, 1);
else
- dStrHex((const char *)bp, extra, -1);
+ hex2stdout(bp, extra, -1);
printf("\n");
if (op->do_pcb)
printf(" <%s>\n", get_pcb_str(bp[2], str, sizeof(str)));
@@ -3078,8 +3075,7 @@ show_ie_page(const uint8_t * resp, int len, const struct opts_t * op)
dStrRaw((const char *)bp, extra);
break;
} else if (op->do_hex) {
- dStrHex((const char *)bp, extra,
- ((1 == op->do_hex) ? 1 : -1));
+ hex2stdout(bp, extra, ((1 == op->do_hex) ? 1 : -1));
break;
}
}
@@ -3190,7 +3186,7 @@ show_ie_page(const uint8_t * resp, int len, const struct opts_t * op)
/* decoded = true; */
} else if ((! decoded) && full) {
printf(" parameter code = 0x%x, contents in hex:\n", pc);
- dStrHex((const char *)bp, extra, 1);
+ hex2stdout(bp, extra, 1);
}
printf("\n");
if (op->do_pcb)
@@ -3557,7 +3553,7 @@ show_protocol_specific_page(const uint8_t * resp, int len,
dStrRaw((const char *)bp, pl);
break;
} else if (op->do_hex) {
- dStrHex((const char *)bp, pl, ((1 == op->do_hex) ? 1 : -1));
+ hex2stdout(bp, pl, ((1 == op->do_hex) ? 1 : -1));
break;
}
}
@@ -3630,8 +3626,7 @@ show_stats_perform_pages(const uint8_t * resp, int len,
dStrRaw((const char *)bp, extra);
break;
} else if (op->do_hex) {
- dStrHex((const char *)bp, extra,
- ((1 == op->do_hex) ? 1 : -1));
+ hex2stdout(bp, extra, ((1 == op->do_hex) ? 1 : -1));
break;
}
}
@@ -3750,7 +3745,7 @@ show_stats_perform_pages(const uint8_t * resp, int len,
pr2serr("show_performance... unknown parameter code "
"%d\n", param_code);
if (op->verbose)
- dStrHexErr((const char *)bp, extra, 1);
+ hex2stderr(bp, extra, 1);
break;
}
if ((op->do_pcb) && (! op->do_name))
@@ -3774,8 +3769,7 @@ show_stats_perform_pages(const uint8_t * resp, int len,
dStrRaw((const char *)bp, extra);
break;
} else if (op->do_hex) {
- dStrHex((const char *)bp, extra,
- ((1 == op->do_hex) ? 1 : -1));
+ hex2stdout(bp, extra, ((1 == op->do_hex) ? 1 : -1));
break;
}
}
@@ -3856,7 +3850,7 @@ show_stats_perform_pages(const uint8_t * resp, int len,
pr2serr("show_performance... unknown parameter code "
"%d\n", param_code);
if (op->verbose)
- dStrHexErr((const char *)bp, extra, 1);
+ hex2stderr(bp, extra, 1);
break;
}
if ((op->do_pcb) && (! op->do_name))
@@ -3918,8 +3912,7 @@ show_cache_stats_page(const uint8_t * resp, int len, const struct opts_t * op)
dStrRaw((const char *)bp, extra);
break;
} else if (op->do_hex) {
- dStrHex((const char *)bp, extra,
- ((1 == op->do_hex) ? 1 : -1));
+ hex2stdout(bp, extra, ((1 == op->do_hex) ? 1 : -1));
break;
}
}
@@ -3990,7 +3983,7 @@ show_cache_stats_page(const uint8_t * resp, int len, const struct opts_t * op)
pr2serr("show_performance... unknown parameter code %d\n",
pc);
if (op->verbose)
- dStrHexErr((const char *)bp, extra, 1);
+ hex2stderr(bp, extra, 1);
break;
}
if ((op->do_pcb) && (! op->do_name))
@@ -4027,7 +4020,7 @@ show_format_status_page(const uint8_t * resp, int len,
dStrRaw((const char *)bp, pl);
break;
} else if (op->do_hex) {
- dStrHex((const char *)bp, pl, ((1 == op->do_hex) ? 1 : -1));
+ hex2stdout(bp, pl, ((1 == op->do_hex) ? 1 : -1));
break;
}
}
@@ -4041,7 +4034,7 @@ show_format_status_page(const uint8_t * resp, int len,
printf(" Format data out: <not available>\n");
else {
printf(" Format data out:\n");
- dStrHex((const char *)bp + 4, pl - 4, 0);
+ hex2stdout(bp + 4, pl - 4, 0);
}
}
is_count = false;
@@ -4061,7 +4054,7 @@ show_format_status_page(const uint8_t * resp, int len,
default:
printf(" Unknown Format parameter code = 0x%x\n", pc);
is_count = false;
- dStrHex((const char *)bp, pl, 0);
+ hex2stdout(bp, pl, 0);
break;
}
if (is_count) {
@@ -4112,7 +4105,7 @@ show_non_volatile_cache_page(const uint8_t * resp, int len,
dStrRaw((const char *)bp, pl);
break;
} else if (op->do_hex) {
- dStrHex((const char *)bp, pl, ((1 == op->do_hex) ? 1 : -1));
+ hex2stdout(bp, pl, ((1 == op->do_hex) ? 1 : -1));
break;
}
}
@@ -4161,7 +4154,7 @@ show_non_volatile_cache_page(const uint8_t * resp, int len,
break;
default:
printf(" Unknown parameter code = 0x%x\n", pc);
- dStrHex((const char *)bp, pl, 0);
+ hex2stdout(bp, pl, 0);
break;
}
if (op->do_pcb)
@@ -4199,7 +4192,7 @@ show_lb_provisioning_page(const uint8_t * resp, int len,
dStrRaw((const char *)bp, pl);
break;
} else if (op->do_hex) {
- dStrHex((const char *)bp, pl, ((1 == op->do_hex) ? 1 : -1));
+ hex2stdout(bp, pl, ((1 == op->do_hex) ? 1 : -1));
break;
}
}
@@ -4252,10 +4245,10 @@ show_lb_provisioning_page(const uint8_t * resp, int len,
}
} else if ((pc >= 0xfff0) && (pc <= 0xffff)) {
printf(" Vendor specific [0x%x]:", pc);
- dStrHex((const char *)bp, ((pl < num) ? pl : num), 0);
+ hex2stdout(bp, ((pl < num) ? pl : num), 0);
} else {
printf(" Reserved [parameter_code=0x%x]:\n", pc);
- dStrHex((const char *)bp, ((pl < num) ? pl : num), 0);
+ hex2stdout(bp, ((pl < num) ? pl : num), 0);
}
if (op->do_pcb)
printf(" <%s>\n", get_pcb_str(bp[2], str, sizeof(str)));
@@ -4290,7 +4283,7 @@ show_utilization_page(const uint8_t * resp, int len, const struct opts_t * op)
dStrRaw((const char *)bp, pl);
break;
} else if (op->do_hex) {
- dStrHex((const char *)bp, pl, ((1 == op->do_hex) ? 1 : -1));
+ hex2stdout(bp, pl, ((1 == op->do_hex) ? 1 : -1));
break;
}
}
@@ -4324,7 +4317,7 @@ show_utilization_page(const uint8_t * resp, int len, const struct opts_t * op)
break;
default:
printf(" Reserved [parameter_code=0x%x]:\n", pc);
- dStrHex((const char *)bp, ((pl < num) ? pl : num), 0);
+ hex2stdout(bp, ((pl < num) ? pl : num), 0);
break;
}
if (op->do_pcb)
@@ -4361,7 +4354,7 @@ show_solid_state_media_page(const uint8_t * resp, int len,
dStrRaw((const char *)bp, pl);
break;
} else if (op->do_hex) {
- dStrHex((const char *)bp, pl, ((1 == op->do_hex) ? 1 : -1));
+ hex2stdout(bp, pl, ((1 == op->do_hex) ? 1 : -1));
break;
}
}
@@ -4381,7 +4374,7 @@ show_solid_state_media_page(const uint8_t * resp, int len,
break;
default:
printf(" Reserved [parameter_code=0x%x]:\n", pc);
- dStrHex((const char *)bp, ((pl < num) ? pl : num), 0);
+ hex2stdout(bp, ((pl < num) ? pl : num), 0);
break;
}
if (op->do_pcb)
@@ -4439,7 +4432,7 @@ show_dt_device_status_page(const uint8_t * resp, int len,
dStrRaw((const char *)bp, pl);
break;
} else if (op->do_hex) {
- dStrHex((const char *)bp, pl, ((1 == op->do_hex) ? 1 : -1));
+ hex2stdout(bp, pl, ((1 == op->do_hex) ? 1 : -1));
break;
}
}
@@ -4502,7 +4495,7 @@ show_dt_device_status_page(const uint8_t * resp, int len,
pl);
break;
}
- dStrHex((const char *)bp + 4, 8, 1);
+ hex2stdout(bp + 4, 8, 1);
break;
case 0x3:
printf(" Key management error data (hex only now):\n");
@@ -4515,7 +4508,7 @@ show_dt_device_status_page(const uint8_t * resp, int len,
pl);
break;
}
- dStrHex((const char *)bp + 4, 12, 1);
+ hex2stdout(bp + 4, 12, 1);
break;
default:
if ((pc >= 0x101) && (pc <= 0x1ff)) {
@@ -4532,15 +4525,14 @@ show_dt_device_status_page(const uint8_t * resp, int len,
sg_get_unaligned_be64(bp + 8));
} else {
printf(" non-SAS transport, in hex:\n");
- dStrHex((const char *)bp + 4,
- ((pl < num) ? pl : num) - 4, 0);
+ hex2stdout(bp + 4, ((pl < num) ? pl : num) - 4, 0);
}
} else if (pc >= 0x8000) {
printf(" Vendor specific [parameter_code=0x%x]:\n", pc);
- dStrHex((const char *)bp, ((pl < num) ? pl : num), 0);
+ hex2stdout(bp, ((pl < num) ? pl : num), 0);
} else {
printf(" Reserved [parameter_code=0x%x]:\n", pc);
- dStrHex((const char *)bp, ((pl < num) ? pl : num), 0);
+ hex2stdout(bp, ((pl < num) ? pl : num), 0);
}
break;
}
@@ -4578,7 +4570,7 @@ show_tapealert_response_page(const uint8_t * resp, int len,
dStrRaw((const char *)bp, pl);
break;
} else if (op->do_hex) {
- dStrHex((const char *)bp, pl, ((1 == op->do_hex) ? 1 : -1));
+ hex2stdout(bp, pl, ((1 == op->do_hex) ? 1 : -1));
break;
}
}
@@ -4603,10 +4595,10 @@ show_tapealert_response_page(const uint8_t * resp, int len,
default:
if (pc <= 0x8000) {
printf(" Reserved [parameter_code=0x%x]:\n", pc);
- dStrHex((const char *)bp, ((pl < num) ? pl : num), 0);
+ hex2stdout(bp, ((pl < num) ? pl : num), 0);
} else {
printf(" Vendor specific [parameter_code=0x%x]:\n", pc);
- dStrHex((const char *)bp, ((pl < num) ? pl : num), 0);
+ hex2stdout(bp, ((pl < num) ? pl : num), 0);
}
break;
}
@@ -4667,7 +4659,7 @@ show_requested_recovery_page(const uint8_t * resp, int len,
dStrRaw((const char *)bp, pl);
break;
} else if (op->do_hex) {
- dStrHex((const char *)bp, pl, ((1 == op->do_hex) ? 1 : -1));
+ hex2stdout(bp, pl, ((1 == op->do_hex) ? 1 : -1));
break;
}
}
@@ -4687,10 +4679,10 @@ show_requested_recovery_page(const uint8_t * resp, int len,
default:
if (pc <= 0x8000) {
printf(" Reserved [parameter_code=0x%x]:\n", pc);
- dStrHex((const char *)bp, ((pl < num) ? pl : num), 0);
+ hex2stdout(bp, ((pl < num) ? pl : num), 0);
} else {
printf(" Vendor specific [parameter_code=0x%x]:\n", pc);
- dStrHex((const char *)bp, ((pl < num) ? pl : num), 0);
+ hex2stdout(bp, ((pl < num) ? pl : num), 0);
}
break;
}
@@ -4729,7 +4721,7 @@ show_ata_pt_results_page(const uint8_t * resp, int len,
dStrRaw((const char *)bp, pl);
break;
} else if (op->do_hex) {
- dStrHex((const char *)bp, pl, ((1 == op->do_hex) ? 1 : -1));
+ hex2stdout(bp, pl, ((1 == op->do_hex) ? 1 : -1));
break;
}
}
@@ -4751,11 +4743,11 @@ show_ata_pt_results_page(const uint8_t * resp, int len,
printf(" device=0x%x status=0x%x\n", dp[12], dp[13]);
} else if (pl > 17) {
printf(" Reserved [parameter_code=0x%x]:\n", pc);
- dStrHex((const char *)bp, ((pl < num) ? pl : num), 0);
+ hex2stdout(bp, ((pl < num) ? pl : num), 0);
} else {
printf(" short parameter length: %d [parameter_code=0x%x]:\n",
pl, pc);
- dStrHex((const char *)bp, ((pl < num) ? pl : num), 0);
+ hex2stdout(bp, ((pl < num) ? pl : num), 0);
}
if (op->do_pcb)
printf(" <%s>\n", get_pcb_str(bp[2], str, sizeof(str)));
@@ -4818,7 +4810,7 @@ show_background_scan_results_page(const uint8_t * resp, int len,
dStrRaw((const char *)bp, pl);
break;
} else if (op->do_hex) {
- dStrHex((const char *)bp, pl, ((1 == op->do_hex) ? 1 : -1));
+ hex2stdout(bp, pl, ((1 == op->do_hex) ? 1 : -1));
break;
}
}
@@ -4869,7 +4861,7 @@ show_background_scan_results_page(const uint8_t * resp, int len,
else
printf(" Medium scan parameter # %d [0x%x], "
"reserved\n", pc, pc);
- dStrHex((const char *)bp, ((pl < num) ? pl : num), 0);
+ hex2stdout(bp, ((pl < num) ? pl : num), 0);
break;
} else
printf(" Medium scan parameter # %d [0x%x]\n", pc, pc);
@@ -4947,7 +4939,7 @@ show_zoned_block_dev_stats(const uint8_t * resp, int len,
dStrRaw((const char *)bp, pl);
break;
} else if (op->do_hex) {
- dStrHex((const char *)bp, pl, ((1 == op->do_hex) ? 1 : -1));
+ hex2stdout(bp, pl, ((1 == op->do_hex) ? 1 : -1));
break;
}
}
@@ -5097,7 +5089,7 @@ show_zoned_block_dev_stats(const uint8_t * resp, int len,
break;
default:
printf(" Reserved [parameter_code=0x%x]:\n", pc);
- dStrHex((const char *)bp, ((pl < num) ? pl : num), 0);
+ hex2stdout(bp, ((pl < num) ? pl : num), 0);
break;
}
if (op->do_pcb)
@@ -5135,7 +5127,7 @@ show_pending_defects_page(const uint8_t * resp, int len,
dStrRaw((const char *)bp, pl);
break;
} else if (op->do_hex) {
- dStrHex((const char *)bp, pl, ((1 == op->do_hex) ? 1 : -1));
+ hex2stdout(bp, pl, ((1 == op->do_hex) ? 1 : -1));
break;
}
}
@@ -5210,7 +5202,7 @@ show_background_op_page(const uint8_t * resp, int len,
dStrRaw((const char *)bp, pl);
break;
} else if (op->do_hex) {
- dStrHex((const char *)bp, pl, ((1 == op->do_hex) ? 1 : -1));
+ hex2stdout(bp, pl, ((1 == op->do_hex) ? 1 : -1));
break;
}
}
@@ -5230,7 +5222,7 @@ show_background_op_page(const uint8_t * resp, int len,
break;
default:
printf(" Reserved [parameter_code=0x%x]:\n", pc);
- dStrHex((const char *)bp, ((pl < num) ? pl : num), 0);
+ hex2stdout(bp, ((pl < num) ? pl : num), 0);
break;
}
if (op->do_pcb)
@@ -5268,7 +5260,7 @@ show_lps_misalignment_page(const uint8_t * resp, int len,
dStrRaw((const char *)bp, pl);
break;
} else if (op->do_hex) {
- dStrHex((const char *)bp, pl, ((1 == op->do_hex) ? 1 : -1));
+ hex2stdout(bp, pl, ((1 == op->do_hex) ? 1 : -1));
break;
}
}
@@ -5292,7 +5284,7 @@ show_lps_misalignment_page(const uint8_t * resp, int len,
pc, bp[4]);
} else {
printf("<unexpected pc=0x%x>\n", pc);
- dStrHex((const char *)bp, pl, 0);
+ hex2stdout(bp, pl, 0);
}
break;
}
@@ -5330,7 +5322,7 @@ show_service_buffer_info_page(const uint8_t * resp, int len,
dStrRaw((const char *)bp, pl);
break;
} else if (op->do_hex) {
- dStrHex((const char *)bp, pl, ((1 == op->do_hex) ? 1 : -1));
+ hex2stdout(bp, pl, ((1 == op->do_hex) ? 1 : -1));
break;
}
}
@@ -5345,11 +5337,11 @@ show_service_buffer_info_page(const uint8_t * resp, int len,
} else if (pc < 0x8000) {
printf(" parameter_code=0x%x, Reserved, parameter in hex:\n",
pc);
- dStrHex((const char *)bp + 4, pl - 4, 0);
+ hex2stdout(bp + 4, pl - 4, 0);
} else {
printf(" parameter_code=0x%x, Vendor-specific, parameter in "
"hex:\n", pc);
- dStrHex((const char *)bp + 4, pl - 4, 0);
+ hex2stdout(bp + 4, pl - 4, 0);
}
if (op->do_pcb)
printf(" <%s>\n", get_pcb_str(bp[2], str, sizeof(str)));
@@ -5387,7 +5379,7 @@ show_sequential_access_page(const uint8_t * resp, int len,
dStrRaw((const char *)bp, pl);
break;
} else if (op->do_hex) {
- dStrHex((const char *)bp, pl, ((1 == op->do_hex) ? 1 : -1));
+ hex2stdout(bp, pl, ((1 == op->do_hex) ? 1 : -1));
break;
}
}
@@ -5499,7 +5491,7 @@ show_device_stats_page(const uint8_t * resp, int len,
dStrRaw((const char *)bp, pl);
break;
} else if (op->do_hex) {
- dStrHex((const char *)bp, pl, ((1 == op->do_hex) ? 1 : -1));
+ hex2stdout(bp, pl, ((1 == op->do_hex) ? 1 : -1));
break;
}
}
@@ -5615,7 +5607,7 @@ show_device_stats_page(const uint8_t * resp, int len,
default:
vl_num = false;
printf(" Reserved parameter code [0x%x] data in hex:\n", pc);
- dStrHex((const char *)bp + 4, pl - 4, 0);
+ hex2stdout(bp + 4, pl - 4, 0);
break;
}
if (vl_num)
@@ -5640,7 +5632,7 @@ show_device_stats_page(const uint8_t * resp, int len,
"hex:\n", pc);
else
printf(" Reserved parameter [0x%x], dump in hex:\n", pc);
- dStrHex((const char *)bp + 4, pl - 4, 0);
+ hex2stdout(bp + 4, pl - 4, 0);
break;
}
}
@@ -5678,7 +5670,7 @@ show_media_stats_page(const uint8_t * resp, int len, const struct opts_t * op)
dStrRaw((const char *)bp, pl);
break;
} else if (op->do_hex) {
- dStrHex((const char *)bp, pl, ((1 == op->do_hex) ? 1 : -1));
+ hex2stdout(bp, pl, ((1 == op->do_hex) ? 1 : -1));
break;
}
}
@@ -5814,7 +5806,7 @@ show_element_stats_page(const uint8_t * resp, int len,
dStrRaw((const char *)bp, pl);
break;
} else if (op->do_hex) {
- dStrHex((const char *)bp, pl, ((1 == op->do_hex) ? 1 : -1));
+ hex2stdout(bp, pl, ((1 == op->do_hex) ? 1 : -1));
break;
}
}
@@ -5867,7 +5859,7 @@ show_tape_diag_data_page(const uint8_t * resp, int len,
dStrRaw((const char *)bp, pl);
break;
} else if (op->do_hex) {
- dStrHex((const char *)bp, pl, ((1 == op->do_hex) ? 1 : -1));
+ hex2stdout(bp, pl, ((1 == op->do_hex) ? 1 : -1));
break;
}
}
@@ -5903,7 +5895,7 @@ show_tape_diag_data_page(const uint8_t * resp, int len,
printf(" Medium id number is 32 bytes of zero\n");
else {
printf(" Medium id number (in hex):\n");
- dStrHex((const char *)(bp + 32), 32, 0);
+ hex2stdout(bp + 32, 32, 0);
}
printf(" Timestamp origin: 0x%x\n", bp[64] & 0xf);
// Check Timestamp for all zeros
@@ -5915,11 +5907,11 @@ show_tape_diag_data_page(const uint8_t * resp, int len,
printf(" Timestamp is all zeros:\n");
else {
printf(" Timestamp:\n");
- dStrHex((const char *)(bp + 66), 6, 1);
+ hex2stdout(bp + 66, 6, 1);
}
if (pl > 72) {
printf(" Vendor specific:\n");
- dStrHex((const char *)(bp + 72), pl - 72, 0);
+ hex2stdout(bp + 72, pl - 72, 0);
}
if (op->do_pcb)
printf(" <%s>\n", get_pcb_str(bp[2], str, sizeof(str)));
@@ -5957,7 +5949,7 @@ show_mchanger_diag_data_page(const uint8_t * resp, int len,
dStrRaw((const char *)bp, pl);
break;
} else if (op->do_hex) {
- dStrHex((const char *)bp, pl, ((1 == op->do_hex) ? 1 : -1));
+ hex2stdout(bp, pl, ((1 == op->do_hex) ? 1 : -1));
break;
}
}
@@ -6006,12 +5998,12 @@ show_mchanger_diag_data_page(const uint8_t * resp, int len,
printf(" Destination address: 0x%x\n", v);
if (pl > 91) {
printf(" Volume tag information:\n");
- dStrHex((const char *)(bp + 56), 36, 0);
+ hex2stdout((bp + 56), 36, 0);
}
if (pl > 99) {
printf(" Timestamp origin: 0x%x\n", bp[92] & 0xf);
printf(" Timestamp:\n");
- dStrHex((const char *)(bp + 94), 6, 1);
+ hex2stdout((bp + 94), 6, 1);
}
if (op->do_pcb)
printf(" <%s>\n", get_pcb_str(bp[2], str, sizeof(str)));
@@ -6129,7 +6121,7 @@ show_volume_stats_pages(const uint8_t * resp, int len,
dStrRaw((const char *)bp, pl);
break;
} else if (op->do_hex) {
- dStrHex((const char *)bp, pl, ((1 == op->do_hex) ? 1 : -1));
+ hex2stdout(bp, pl, ((1 == op->do_hex) ? 1 : -1));
break;
}
}
@@ -6307,7 +6299,7 @@ show_volume_stats_pages(const uint8_t * resp, int len,
else
printf(" Reserved parameter code (0x%x), payload in hex\n",
pc);
- dStrHex((const char *)(bp + 4), pl - 4, 0);
+ hex2stdout(bp + 4, pl - 4, 0);
break;
}
if (op->do_pcb)
@@ -6409,7 +6401,7 @@ show_tape_alert_ssc_page(const uint8_t * resp, int len,
dStrRaw((const char *)bp, pl);
break;
} else if (op->do_hex) {
- dStrHex((const char *)bp, pl, ((1 == op->do_hex) ? 1 : -1));
+ hex2stdout(bp, pl, ((1 == op->do_hex) ? 1 : -1));
break;
}
}
@@ -6458,7 +6450,7 @@ show_seagate_cache_page(const uint8_t * resp, int len,
dStrRaw((const char *)bp, pl);
break;
} else if (op->do_hex) {
- dStrHex((const char *)bp, pl, ((1 == op->do_hex) ? 1 : -1));
+ hex2stdout(bp, pl, ((1 == op->do_hex) ? 1 : -1));
break;
}
}
@@ -6515,7 +6507,7 @@ show_seagate_factory_page(const uint8_t * resp, int len,
dStrRaw((const char *)bp, pl);
break;
} else if (op->do_hex) {
- dStrHex((const char *)bp, pl, ((1 == op->do_hex) ? 1 : -1));
+ hex2stdout(bp, pl, ((1 == op->do_hex) ? 1 : -1));
break;
}
}
@@ -6580,12 +6572,12 @@ decode_page_contents(const uint8_t * resp, int len, const struct opts_t * op)
else
printf("Unable to decode page = 0x%x, here is hex:\n", pg_code);
if (len > 128) {
- dStrHex((const char *)resp, 64, 1);
+ hex2stdout(resp, 64, 1);
printf(" ..... [truncated after 64 of %d bytes (use '-H' to "
"see the rest)]\n", len);
}
else
- dStrHex((const char *)resp, len, 1);
+ hex2stdout(resp, len, 1);
}
}
@@ -6603,7 +6595,7 @@ fetchTemperature(int sg_fd, uint8_t * resp, int max_len, struct opts_t * op)
if (op->do_raw)
dStrRaw((const char *)resp, len);
else if (op->do_hex)
- dStrHex((const char *)resp, len, (1 == op->do_hex));
+ hex2stdout(resp, len, (1 == op->do_hex));
else
show_temperature_page(resp, len, op);
} else if (SG_LIB_CAT_NOT_READY == res)
@@ -6616,7 +6608,7 @@ fetchTemperature(int sg_fd, uint8_t * resp, int max_len, struct opts_t * op)
if (op->do_raw)
dStrRaw((const char *)resp, len);
else if (op->do_hex)
- dStrHex((const char *)resp, len, (1 == op->do_hex));
+ hex2stdout(resp, len, (1 == op->do_hex));
else
show_ie_page(resp, len, op);
} else
@@ -6951,15 +6943,13 @@ main(int argc, char * argv[])
if (0 == op->do_all) {
if (op->filter_given) {
if (op->do_hex > 2)
- dStrHex((const char *)rsp_buff, pg_len + 4,
- (op->do_hex < 4));
+ hex2stdout(rsp_buff, pg_len + 4, (op->do_hex < 4));
else
decode_page_contents(rsp_buff, pg_len + 4, op);
} else if (op->do_raw)
dStrRaw((const char *)rsp_buff, pg_len + 4);
else if (op->do_hex > 1)
- dStrHex((const char *)rsp_buff, pg_len + 4,
- (2 == op->do_hex) ? 0 : -1);
+ hex2stdout(rsp_buff, pg_len + 4, (2 == op->do_hex) ? 0 : -1);
else if (pg_len > 1) {
if (op->do_hex) {
if (rsp_buff[0] & 0x40)
@@ -6969,7 +6959,7 @@ main(int argc, char * argv[])
else
printf("Log page code=0x%x, DS=%d, SPF=0, page_len=0x%x\n",
rsp_buff[0] & 0x3f, !!(rsp_buff[0] & 0x80), pg_len);
- dStrHex((const char *)rsp_buff, pg_len + 4, 1);
+ hex2stdout(rsp_buff, pg_len + 4, 1);
}
else
decode_page_contents(rsp_buff, pg_len + 4, op);
@@ -7009,8 +6999,8 @@ main(int argc, char * argv[])
if (op->do_raw)
dStrRaw((const char *)rsp_buff, pg_len + 4);
else if (op->do_hex > 1)
- dStrHex((const char *)rsp_buff, pg_len + 4,
- (2 == op->do_hex) ? 0 : -1);
+ hex2stdout(rsp_buff, pg_len + 4,
+ (2 == op->do_hex) ? 0 : -1);
else if (op->do_hex) {
if (rsp_buff[0] & 0x40)
printf("Log page code=0x%x,0x%x, DS=%d, SPF=1, page_"
@@ -7020,7 +7010,7 @@ main(int argc, char * argv[])
printf("Log page code=0x%x, DS=%d, SPF=0, page_len="
"0x%x\n", rsp_buff[0] & 0x3f,
!!(rsp_buff[0] & 0x80), pg_len);
- dStrHex((const char *)rsp_buff, pg_len + 4, 1);
+ hex2stdout(rsp_buff, pg_len + 4, 1);
}
else
decode_page_contents(rsp_buff, pg_len + 4, op);
diff --git a/src/sg_luns.c b/src/sg_luns.c
index d2478ebb..721bde90 100644
--- a/src/sg_luns.c
+++ b/src/sg_luns.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2004-2017 Douglas Gilbert.
+ * Copyright (c) 2004-2018 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.
@@ -31,7 +31,7 @@
* and decodes the response.
*/
-static const char * version_str = "1.35 20171011";
+static const char * version_str = "1.36 20180118";
#define MAX_RLUNS_BUFF_LEN (1024 * 1024)
#define DEF_RLUNS_BUFF_LEN (1024 * 8)
@@ -344,11 +344,11 @@ t10_2linux_lun(const unsigned char t10_lun[])
static void
-dStrRaw(const char* str, int len)
+dStrRaw(const char * str, int len)
{
int k;
- for (k = 0 ; k < len; ++k)
+ for (k = 0; k < len; ++k)
printf("%c", str[k]);
}
@@ -613,7 +613,7 @@ main(int argc, char * argv[])
goto the_end;
}
if (1 == do_hex) {
- dStrHex((const char *)reportLunsBuff, len_cap, 1);
+ hex2stdout(reportLunsBuff, len_cap, 1);
goto the_end;
}
luns = (list_len / 8);
@@ -628,8 +628,7 @@ main(int argc, char * argv[])
}
if (verbose > 1) {
pr2serr("\nOutput response in hex\n");
- dStrHexErr((const char *)reportLunsBuff,
- (trunc ? maxlen : list_len + 8), 1);
+ hex2stderr(reportLunsBuff, (trunc ? maxlen : list_len + 8), 1);
}
for (k = 0, off = 8; k < luns; ++k, off += 8) {
if (! do_quiet) {
diff --git a/src/sg_modes.c b/src/sg_modes.c
index a60d431b..52ea25d0 100644
--- a/src/sg_modes.c
+++ b/src/sg_modes.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2000-2017 D. Gilbert
+ * Copyright (C) 2000-2018 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)
@@ -29,7 +29,7 @@
#include "sg_unaligned.h"
#include "sg_pr2serr.h"
-static const char * version_str = "1.54 20171030";
+static const char * version_str = "1.55 20180118";
#define DEF_ALLOC_LEN (1024 * 4)
#define DEF_6_ALLOC_LEN 252
@@ -504,11 +504,11 @@ process_cl(struct opts_t * op, int argc, char * argv[])
}
static void
-dStrRaw(const char* str, int len)
+dStrRaw(const char * str, int len)
{
int k;
- for (k = 0 ; k < len; ++k)
+ for (k = 0; k < len; ++k)
printf("%c", str[k]);
}
@@ -936,7 +936,7 @@ examine_pages(int sg_fd, int inq_pdt, bool encserv, bool mchngr,
continue;
}
if (op->do_hex > 2) {
- dStrHex((const char *)rbuf, len, -1);
+ hex2stdout(rbuf, len, -1);
continue;
}
if (! header_printed) {
@@ -949,7 +949,7 @@ examine_pages(int sg_fd, int inq_pdt, bool encserv, bool mchngr,
else
printf(" [0x%x]\n", k);
if (op->do_hex)
- dStrHex((const char *)rbuf, len, 1);
+ hex2stdout(rbuf, len, 1);
} else if (op->do_verbose) {
char b[80];
@@ -1241,14 +1241,14 @@ main(int argc, char * argv[])
for (k = 0; k < len; ++k)
printf("%02x\n", bp[k]);
} else
- dStrHex((const char *)rsp_buff, md_len, -1);
+ hex2stdout(rsp_buff, md_len, -1);
goto finish;
}
if (1 == op->do_hex) {
- dStrHex((const char *)rsp_buff, md_len, 1);
+ hex2stdout(rsp_buff, md_len, 1);
goto finish;
} else if (op->do_hex > 1)
- dStrHex((const char *)rsp_buff, headerlen, 1);
+ hex2stdout(rsp_buff, headerlen, 1);
if (0 == inq_pdt)
printf(" Mode data length=%d, medium type=0x%.2x, WP=%d,"
" DpoFua=%d, longlba=%d\n", md_len, medium_type,
@@ -1287,7 +1287,7 @@ main(int argc, char * argv[])
while (num > 0) {
printf(" Density code=0x%x\n",
*(bp + density_code_off));
- dStrHex((const char *)bp, len, 1);
+ hex2stdout(bp, len, 1);
bp += len;
num -= len;
}
@@ -1354,7 +1354,7 @@ main(int argc, char * argv[])
pr2serr(">>> page length (%d) > 256 bytes, unlikely trim\n"
" Try '-f' option\n", len);
}
- dStrHex((const char *)bp, num , 1);
+ hex2stdout(bp, num , 1);
bp += len;
md_len -= len;
}
diff --git a/src/sg_opcodes.c b/src/sg_opcodes.c
index ae9525be..a594870c 100644
--- a/src/sg_opcodes.c
+++ b/src/sg_opcodes.c
@@ -1,13 +1,13 @@
/* A utility program originally written for the Linux OS SCSI subsystem.
- * Copyright (C) 2004-2017 D. Gilbert
+ * Copyright (C) 2004-2018 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)
* any later version.
-
- This program outputs information provided by a SCSI REPORT SUPPORTED
- OPERATION CODES [0xa3/0xc] and REPORT SUPPORTED TASK MANAGEMENT
- FUNCTIONS [0xa3/0xd] commands.
+ *
+ * This program outputs information provided by a SCSI REPORT SUPPORTED
+ * OPERATION CODES [0xa3/0xc] and REPORT SUPPORTED TASK MANAGEMENT
+ * FUNCTIONS [0xa3/0xd] commands.
*/
#include <unistd.h>
@@ -236,7 +236,7 @@ do_rsoc(int sg_fd, bool rctd, int rep_opts, int rq_opcode, int rq_servact,
*act_resp_lenp = ret;
if ((verbose > 2) && (ret > 0)) {
pr2serr("%s response:\n", rsoc_s);
- dStrHexErr((const char *)resp, ret, 1);
+ hex2stderr(resp, ret, 1);
}
ret = 0;
}
@@ -298,7 +298,7 @@ do_rstmf(int sg_fd, bool repd, void * resp, int mx_resp_len,
*act_resp_lenp = ret;
if ((verbose > 2) && (ret > 0)) {
pr2serr("%s response:\n", rstmf_s);
- dStrHexErr((const char *)resp, ret, 1);
+ hex2stderr(resp, ret, 1);
}
ret = 0;
}
@@ -584,11 +584,11 @@ process_cl(struct opts_t * op, int argc, char * argv[])
}
static void
-dStrRaw(const char* str, int len)
+dStrRaw(const char * str, int len)
{
int k;
- for (k = 0 ; k < len; ++k)
+ for (k = 0; k < len; ++k)
printf("%c", str[k]);
}
@@ -1051,7 +1051,7 @@ main(int argc, char * argv[])
}
printf("\nTask Management Functions supported by device:\n");
if (op->do_hex) {
- dStrHex((const char *)rsoc_buff, act_len, 1);
+ hex2stdout(rsoc_buff, act_len, 1);
goto err_out;
}
if (rsoc_buff[0] & 0x80)
@@ -1107,7 +1107,7 @@ main(int argc, char * argv[])
goto err_out;
}
if (op->do_hex) {
- dStrHex((const char *)rsoc_buff, len, 1);
+ hex2stdout(rsoc_buff, len, 1);
goto err_out;
}
list_all_codes(rsoc_buff, len, op, sg_fd);
@@ -1121,7 +1121,7 @@ main(int argc, char * argv[])
goto err_out;
}
if (op->do_hex) {
- dStrHex((const char *)rsoc_buff, len, 1);
+ hex2stdout(rsoc_buff, len, 1);
goto err_out;
}
list_one(rsoc_buff, cd_len, rep_opts, op);
diff --git a/src/sg_persist.c b/src/sg_persist.c
index 2b044431..5997bc4d 100644
--- a/src/sg_persist.c
+++ b/src/sg_persist.c
@@ -1,5 +1,5 @@
/* A utility program originally written for the Linux OS SCSI subsystem.
- * Copyright (C) 2004-2017 D. Gilbert
+ * Copyright (C) 2004-2018 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)
@@ -24,13 +24,14 @@
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
+
#include "sg_lib.h"
#include "sg_cmds_basic.h"
#include "sg_cmds_extra.h"
#include "sg_unaligned.h"
#include "sg_pr2serr.h"
-static const char * version_str = "0.57 20171012";
+static const char * version_str = "0.58 20180118";
#define PRIN_RKEY_SA 0x0
@@ -275,11 +276,11 @@ prin_work(int sg_fd, const struct opts_t * op)
if (8 != pr_buff[1]) {
pr2serr("Unexpected response for PRIN Report Capabilities\n");
if (op->hex)
- dStrHex((const char *)pr_buff, pr_buff[1], 1);
+ hex2stdout(pr_buff, pr_buff[1], 1);
return SG_LIB_CAT_MALFORMED;
}
if (op->hex)
- dStrHex((const char *)pr_buff, 8, 1);
+ hex2stdout(pr_buff, 8, 1);
else {
printf("Report capabilities response:\n");
printf(" Compatible Reservation Handling(CRH): %d\n",
@@ -315,8 +316,7 @@ prin_work(int sg_fd, const struct opts_t * op)
add_len = sg_get_unaligned_be32(pr_buff + 4);
if (op->hex) {
if (op->hex > 1)
- dStrHex((const char *)pr_buff, add_len + 8,
- ((2 == op->hex) ? 1 : -1));
+ hex2stdout(pr_buff, add_len + 8, ((2 == op->hex) ? 1 : -1));
else {
printf(" PR generation=0x%x, ", pr_gen);
if (add_len <= 0)
@@ -324,11 +324,10 @@ prin_work(int sg_fd, const struct opts_t * op)
if (add_len > ((int)sizeof(pr_buff) - 8)) {
printf("Additional length too large=%d, truncate\n",
add_len);
- dStrHex((const char *)(pr_buff + 8), sizeof(pr_buff) - 8,
- 1);
+ hex2stdout((pr_buff + 8), sizeof(pr_buff) - 8, 1);
} else {
printf("Additional length=%d\n", add_len);
- dStrHex((const char *)(pr_buff + 8), add_len, 1);
+ hex2stdout((pr_buff + 8), add_len, 1);
}
}
} else if (PRIN_RKEY_SA == op->prin_sa) {
diff --git a/src/sg_raw.c b/src/sg_raw.c
index 9ea07065..a19dda36 100644
--- a/src/sg_raw.c
+++ b/src/sg_raw.c
@@ -1,7 +1,7 @@
/*
* A utility program originally written for the Linux OS SCSI subsystem.
*
- * Copyright (C) 2000-2017 Ingo van Lil <inguin@gmx.de>
+ * Copyright (C) 2000-2018 Ingo van Lil <inguin@gmx.de>
*
* 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
@@ -32,7 +32,7 @@
#include "sg_pr2serr.h"
#include "sg_unaligned.h"
-#define SG_RAW_VERSION "0.4.20 (2017-12-29)"
+#define SG_RAW_VERSION "0.4.21 (2018-01-18)"
#define DEFAULT_TIMEOUT 20
#define MIN_SCSI_CDBSZ 6
@@ -543,7 +543,7 @@ main(int argc, char *argv[])
} else {
if (op->datain_file == NULL && !op->datain_binary) {
pr2serr("Received %d bytes of data:\n", data_len);
- dStrHexErr((const char *)dxfer_buffer_in, data_len, 0);
+ hex2stderr(dxfer_buffer_in, data_len, 0);
} else {
const char * cp = "stdout";
diff --git a/src/sg_read_attr.c b/src/sg_read_attr.c
index 1efccac6..17b9cfa5 100644
--- a/src/sg_read_attr.c
+++ b/src/sg_read_attr.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-2017 Douglas Gilbert.
+ * Copyright (c) 2016-2018 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.
@@ -21,6 +21,7 @@
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
+
#include "sg_lib.h"
#include "sg_lib_data.h"
#include "sg_pt.h"
@@ -35,7 +36,7 @@
* and decodes the response. Based on spc5r08.pdf
*/
-static const char * version_str = "1.05 20171010";
+static const char * version_str = "1.06 20180118";
#define MAX_RATTR_BUFF_LEN (1024 * 1024)
#define DEF_RATTR_BUFF_LEN (1024 * 8)
@@ -297,11 +298,11 @@ sg_ll_read_attr(int sg_fd, void * resp, int * residp, bool noisy,
}
static void
-dStrRaw(const char* str, int len)
+dStrRaw(const char * str, int len)
{
int k;
- for (k = 0 ; k < len; ++k)
+ for (k = 0; k < len; ++k)
printf("%c", str[k]);
}
@@ -611,7 +612,7 @@ decode_attr_list(const unsigned char * alp, int len, bool supported,
else if (0 == op->quiet)
printf("%sttribute list:\n", leadin);
if (op->do_hex) {
- dStrHex((const char *)alp, len, 0);
+ hex2stdout(alp, len, 0);
return;
}
for ( ; len > 0; alp += 2, len -= 2) {
@@ -658,7 +659,7 @@ helper_full_attr(const unsigned char * alp, int len, int id,
printf("%" PRIx64, sg_get_unaligned_be(len - 5, alp + 5));
else {
printf("\n");
- dStrHex((const char *)(alp + 5), len - 5, 0);
+ hex2stdout((alp + 5), len - 5, 0);
}
}
break;
@@ -674,7 +675,7 @@ helper_full_attr(const unsigned char * alp, int len, int id,
printf("%" PRIx64, sg_get_unaligned_be(len - 5, alp + 5));
else {
printf("\n");
- dStrHex((const char *)(alp + 5), len - 5, 0);
+ hex2stdout(alp + 5, len - 5, 0);
}
}
break;
@@ -757,7 +758,7 @@ helper_full_attr(const unsigned char * alp, int len, int id,
default:
pr2serr("%s: unknown attribute id: 0x%x\n", __func__, id);
printf(" In hex:\n");
- dStrHex((const char *)alp, len, 0);
+ hex2stdout(alp, len, 0);
break;
}
}
@@ -778,7 +779,7 @@ decode_attr_vals(const unsigned char * alp, int len, const struct opts_t * op)
if (0 == op->quiet)
printf("Attribute values:\n");
if (op->do_hex) { /* only expect -HH to get through here */
- dStrHex((const char *)alp, len, 0);
+ hex2stdout(alp, len, 0);
return;
}
}
@@ -823,7 +824,7 @@ decode_attr_vals(const unsigned char * alp, int len, const struct opts_t * op)
helper_full_attr(alp, bump, id, anip, op);
else {
printf("\n");
- dStrHex((const char *)(alp + 5), alen, 0);
+ hex2stdout(alp + 5, alen, 0);
}
} else {
if (2 == anip->process)
@@ -843,7 +844,7 @@ decode_attr_vals(const unsigned char * alp, int len, const struct opts_t * op)
printf("Attribute id lookup failed, in hex:\n");
else
printf("\n");
- dStrHex((const char *)(alp + 5), alen, 0);
+ hex2stdout(alp + 5, alen, 0);
}
}
if (op->verbose && (len > 0) && (len <= 4))
@@ -855,7 +856,7 @@ static void
decode_all_sa_s(const unsigned char * rabp, int len, const struct opts_t * op)
{
if (op->do_hex && (2 != op->do_hex)) {
- dStrHex((const char *)rabp, len, ((1 == op->do_hex) ? 1 : -1));
+ hex2stdout(rabp, len, ((1 == op->do_hex) ? 1 : -1));
return;
}
switch (op->sa) {
@@ -889,7 +890,7 @@ decode_all_sa_s(const unsigned char * rabp, int len, const struct opts_t * op)
break;
case RA_SMC2_SA:
printf("Used by SMC-2, not information, output in hex:\n");
- dStrHex((const char *)rabp, len, 0);
+ hex2stdout(rabp, len, 0);
break;
case RA_SUP_ATTR_SA:
decode_attr_list(rabp + 4, len - 4, true, op);
@@ -897,7 +898,7 @@ decode_all_sa_s(const unsigned char * rabp, int len, const struct opts_t * op)
default:
printf("Unrecognized service action [0x%x], response in hex:\n",
op->sa);
- dStrHex((const char *)rabp, len, 0);
+ hex2stdout(rabp, len, 0);
break;
}
}
diff --git a/src/sg_read_block_limits.c b/src/sg_read_block_limits.c
index 48560c8a..63a0bba9 100644
--- a/src/sg_read_block_limits.c
+++ b/src/sg_read_block_limits.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2009-2017 Douglas Gilbert.
+ * Copyright (c) 2009-2018 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.
@@ -19,6 +19,7 @@
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
+
#include "sg_lib.h"
#include "sg_cmds_basic.h"
#include "sg_cmds_extra.h"
@@ -32,7 +33,7 @@
* SCSI device.
*/
-static const char * version_str = "1.06 20171006";
+static const char * version_str = "1.07 20180118";
#define MAX_READ_BLOCK_LIMITS_LEN 6
@@ -70,11 +71,11 @@ usage()
}
static void
-dStrRaw(const char* str, int len)
+dStrRaw(const char * str, int len)
{
int k;
- for (k = 0 ; k < len; ++k)
+ for (k = 0; k < len; ++k)
printf("%c", str[k]);
}
@@ -155,7 +156,7 @@ main(int argc, char * argv[])
ret = res;
if (0 == res) {
if (do_hex) {
- dStrHex((const char *)readBlkLmtBuff, sizeof(readBlkLmtBuff), 1);
+ hex2stdout(readBlkLmtBuff, sizeof(readBlkLmtBuff), 1);
goto the_end;
} else if (do_raw) {
dStrRaw((const char *)readBlkLmtBuff, sizeof(readBlkLmtBuff));
diff --git a/src/sg_read_buffer.c b/src/sg_read_buffer.c
index 13e1117a..cd16f954 100644
--- a/src/sg_read_buffer.c
+++ b/src/sg_read_buffer.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006-2017 Luben Tuikov and Douglas Gilbert.
+ * Copyright (c) 2006-2018 Luben Tuikov and 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.
@@ -20,10 +20,13 @@
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
+
#include "sg_lib.h"
#include "sg_cmds_basic.h"
#include "sg_cmds_extra.h"
+#ifdef SG_LIB_WIN32
#include "sg_pt.h" /* needed for scsi_pt_win32_direct() */
+#endif
#include "sg_unaligned.h"
#include "sg_pr2serr.h"
@@ -32,7 +35,7 @@
* device.
*/
-static const char * version_str = "1.20 20171103";
+static const char * version_str = "1.21 20180118";
#ifndef SG_READ_BUFFER_10_CMD
@@ -193,7 +196,7 @@ sg_ll_read_buffer_10(int sg_fd, int rb_mode, int rb_mode_sp, int rb_id,
if ((verbose > 2) && (ret > 0)) {
pr2serr(" Read buffer(10): response%s\n",
(ret > 256 ? ", first 256 bytes" : ""));
- dStrHexErr((const char *)resp, (ret > 256 ? 256 : ret), -1);
+ hex2stderr(resp, (ret > 256 ? 256 : ret), -1);
}
ret = 0;
}
@@ -257,7 +260,7 @@ sg_ll_read_buffer_16(int sg_fd, int rb_mode, int rb_mode_sp, int rb_id,
if ((verbose > 2) && (ret > 0)) {
pr2serr(" Read buffer(16): response%s\n",
(ret > 256 ? ", first 256 bytes" : ""));
- dStrHexErr((const char *)resp, (ret > 256 ? 256 : ret), -1);
+ hex2stderr(resp, (ret > 256 ? 256 : ret), -1);
}
ret = 0;
}
@@ -268,11 +271,11 @@ sg_ll_read_buffer_16(int sg_fd, int rb_mode, int rb_mode_sp, int rb_id,
}
static void
-dStrRaw(const char* str, int len)
+dStrRaw(const uint8_t * str, int len)
{
int k;
- for (k = 0 ; k < len; ++k)
+ for (k = 0; k < len; ++k)
printf("%c", str[k]);
}
@@ -479,9 +482,9 @@ main(int argc, char * argv[])
rb_len -= resid; /* got back less than requested */
if (rb_len > 0) {
if (do_raw)
- dStrRaw((const char *)resp, rb_len);
+ dStrRaw(resp, rb_len);
else if (do_hex || (rb_len < 4))
- dStrHex((const char *)resp, rb_len, ((do_hex > 1) ? 0 : 1));
+ hex2stdout(resp, rb_len, ((do_hex > 1) ? 0 : 1));
else {
switch (rb_mode) {
case MODE_DESCRIPTOR:
@@ -496,7 +499,7 @@ main(int argc, char * argv[])
printf("Echo buffer capacity: %d (0x%x)\n", k, k);
break;
default:
- dStrHex((const char *)resp, rb_len, (verbose > 1 ? 0 : 1));
+ hex2stdout(resp, rb_len, (verbose > 1 ? 0 : 1));
break;
}
}
diff --git a/src/sg_read_long.c b/src/sg_read_long.c
index 111c5b3c..86dcd659 100644
--- a/src/sg_read_long.c
+++ b/src/sg_read_long.c
@@ -1,16 +1,16 @@
/* A utility program for the Linux OS SCSI subsystem.
- * Copyright (C) 2004-2017 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)
- * any later version.
-
- This program issues the SCSI command READ LONG to a given SCSI device.
- It sends the command with the logical block address passed as the lba
- argument, and the transfer length set to the xfer_len argument. the
- buffer to be written to the device filled with 0xff, this buffer includes
- the sector data and the ECC bytes.
-*/
+ * Copyright (C) 2004-2018 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)
+ * any later version.
+ *
+ * This program issues the SCSI command READ LONG to a given SCSI device.
+ * It sends the command with the logical block address passed as the lba
+ * argument, and the transfer length set to the xfer_len argument. the
+ * buffer to be written to the device filled with 0xff, this buffer includes
+ * the sector data and the ECC bytes.
+ */
#include <unistd.h>
#include <fcntl.h>
@@ -27,12 +27,13 @@
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
+
#include "sg_lib.h"
#include "sg_cmds_basic.h"
#include "sg_cmds_extra.h"
#include "sg_pr2serr.h"
-static const char * version_str = "1.23 20171006";
+static const char * version_str = "1.24 20180118";
#define MAX_XFER_LEN 10000
@@ -241,7 +242,7 @@ main(int argc, char * argv[])
goto err_out;
if ('\0' == out_fname[0])
- dStrHex((const char *)rawp, xfer_len, 0);
+ hex2stdout(rawp, xfer_len, 0);
else {
got_stdout = (0 == strcmp(out_fname, "-"));
if (got_stdout)
diff --git a/src/sg_readcap.c b/src/sg_readcap.c
index 6d78d574..4c45b977 100644
--- a/src/sg_readcap.c
+++ b/src/sg_readcap.c
@@ -1,17 +1,16 @@
/* This code is does a SCSI READ CAPACITY command on the given device
- and outputs the result.
-
-* Copyright (C) 1999 - 2017 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)
-* any later version.
-
- This program was originally written with Linux 2.4 kernel series.
- It now builds for the Linux 2.6 and 3 kernel series and various other
- operating systems.
-
-*/
+ * and outputs the result.
+ *
+ * Copyright (C) 1999 - 2018 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)
+ * any later version.
+ *
+ * This program was originally written with Linux 2.4 kernel series.
+ * It now builds for the Linux 2.6, 3 and 4 kernel series and various other
+ * operating systems.
+ */
#include <stdio.h>
#include <stdlib.h>
@@ -27,13 +26,14 @@
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
+
#include "sg_lib.h"
#include "sg_cmds_basic.h"
#include "sg_unaligned.h"
#include "sg_pr2serr.h"
-static const char * version_str = "3.97 20171007";
+static const char * version_str = "3.98 20180118";
#define ME "sg_readcap: "
@@ -368,11 +368,11 @@ process_cl(struct opts_t * op, int argc, char * argv[])
}
static void
-dStrRaw(const char* str, int len)
+dStrRaw(const uint8_t * str, int len)
{
int k;
- for (k = 0 ; k < len; ++k)
+ for (k = 0; k < len; ++k)
printf("%c", str[k]);
}
@@ -463,11 +463,11 @@ main(int argc, char * argv[])
if (0 == res) {
if (op->do_hex || op->do_raw) {
if (op->do_raw)
- dStrRaw((const char *)resp_buff, RCAP_REPLY_LEN);
+ dStrRaw(resp_buff, RCAP_REPLY_LEN);
else if (op->do_hex > 2)
- dStrHex((const char *)resp_buff, RCAP_REPLY_LEN, -1);
+ hex2stdout(resp_buff, RCAP_REPLY_LEN, -1);
else
- dStrHex((const char *)resp_buff, RCAP_REPLY_LEN, 1);
+ hex2stdout(resp_buff, RCAP_REPLY_LEN, 1);
goto good;
}
last_blk_addr = sg_get_unaligned_be32(resp_buff + 0);
@@ -536,11 +536,11 @@ main(int argc, char * argv[])
if (0 == res) {
if (op->do_hex || op->do_raw) {
if (op->do_raw)
- dStrRaw((const char *)resp_buff, RCAP16_REPLY_LEN);
+ dStrRaw(resp_buff, RCAP16_REPLY_LEN);
else if (op->do_hex > 2)
- dStrHex((const char *)resp_buff, RCAP16_REPLY_LEN, -1);
+ hex2stdout(resp_buff, RCAP16_REPLY_LEN, -1);
else
- dStrHex((const char *)resp_buff, RCAP16_REPLY_LEN, 1);
+ hex2stdout(resp_buff, RCAP16_REPLY_LEN, 1);
goto good;
}
llast_blk_addr = sg_get_unaligned_be64(resp_buff + 0);
diff --git a/src/sg_reassign.c b/src/sg_reassign.c
index ea5cec7c..1438b099 100644
--- a/src/sg_reassign.c
+++ b/src/sg_reassign.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005-2017 Douglas Gilbert.
+ * Copyright (c) 2005-2018 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.
@@ -21,6 +21,7 @@
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
+
#include "sg_lib.h"
#include "sg_cmds_basic.h"
#include "sg_cmds_extra.h"
@@ -36,7 +37,7 @@
* vendor specific data is written.
*/
-static const char * version_str = "1.22 20171008";
+static const char * version_str = "1.23 20180118";
#define DEF_DEFECT_LIST_FORMAT 4 /* bytes from index */
@@ -404,7 +405,7 @@ main(int argc, char * argv[])
goto err_out;
}
if (do_hex) {
- dStrHex((const char *)param_arr, param_len, 1);
+ hex2stdout(param_arr, param_len, 1);
goto err_out; /* ret is zero */
}
got_grown = !!(param_arr[1] & 0x8);
diff --git a/src/sg_referrals.c b/src/sg_referrals.c
index a1a8278e..52ddfbf2 100644
--- a/src/sg_referrals.c
+++ b/src/sg_referrals.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010-2017 Hannes Reinecke.
+ * Copyright (c) 2010-2018 Hannes Reinecke.
* All rights reserved.
* Use of this source code is governed by a BSD-style
* license that can be found in the BSD_LICENSE file.
@@ -19,6 +19,7 @@
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
+
#include "sg_lib.h"
#include "sg_cmds_basic.h"
#include "sg_cmds_extra.h"
@@ -33,7 +34,7 @@
* SCSI device.
*/
-static const char * version_str = "1.08 20171006"; /* sbc4r10 */
+static const char * version_str = "1.09 20180118"; /* sbc4r10 */
#define MAX_REFER_BUFF_LEN (1024 * 1024)
#define DEF_REFER_BUFF_LEN 256
@@ -119,11 +120,11 @@ usage()
}
static void
-dStrRaw(const char* str, int len)
+dStrRaw(const uint8_t * str, int len)
{
int k;
- for (k = 0 ; k < len; ++k)
+ for (k = 0; k < len; ++k)
printf("%c", str[k]);
}
@@ -292,11 +293,11 @@ main(int argc, char * argv[])
rlen = maxlen;
k = (rlen > maxlen) ? maxlen : rlen;
if (do_raw) {
- dStrRaw((const char *)referralBuffp, k);
+ dStrRaw(referralBuffp, k);
goto the_end;
}
if (do_hex) {
- dStrHex((const char *)referralBuffp, k, 1);
+ hex2stdout(referralBuffp, k, 1);
goto the_end;
}
if (maxlen < 4) {
diff --git a/src/sg_rep_zones.c b/src/sg_rep_zones.c
index 3319fc25..7fc08d7f 100644
--- a/src/sg_rep_zones.c
+++ b/src/sg_rep_zones.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014-2017 Douglas Gilbert.
+ * Copyright (c) 2014-2018 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.
@@ -20,6 +20,7 @@
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
+
#include "sg_lib.h"
#include "sg_lib_data.h"
#include "sg_pt.h"
@@ -34,7 +35,7 @@
* and decodes the response. Based on zbc-r02.pdf
*/
-static const char * version_str = "1.12 20171103";
+static const char * version_str = "1.13 20180118";
#define MAX_RZONES_BUFF_LEN (1024 * 1024)
#define DEF_RZONES_BUFF_LEN (1024 * 8)
@@ -173,11 +174,11 @@ sg_ll_report_zones(int sg_fd, uint64_t zs_lba, bool partial, int report_opts,
}
static void
-dStrRaw(const char* str, int len)
+dStrRaw(const uint8_t * str, int len)
{
int k;
- for (k = 0 ; k < len; ++k)
+ for (k = 0; k < len; ++k)
printf("%c", str[k]);
}
@@ -414,11 +415,11 @@ main(int argc, char * argv[])
} else
len = zl_len;
if (do_raw) {
- dStrRaw((const char *)reportZonesBuff, len);
+ dStrRaw(reportZonesBuff, len);
goto the_end;
}
if (do_hex && (2 != do_hex)) {
- dStrHex((const char *)reportZonesBuff, len,
+ hex2stdout(reportZonesBuff, len,
((1 == do_hex) ? 1 : -1));
goto the_end;
}
@@ -437,7 +438,7 @@ main(int argc, char * argv[])
for (k = 0, bp = reportZonesBuff + 64; k < zones; ++k, bp += 64) {
printf(" Zone descriptor: %d\n", k);
if (do_hex) {
- dStrHex((const char *)bp, len, -1);
+ hex2stdout(bp, len, -1);
continue;
}
zt = bp[0] & 0xf;
diff --git a/src/sg_requests.c b/src/sg_requests.c
index e110b21e..d5107d20 100644
--- a/src/sg_requests.c
+++ b/src/sg_requests.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2004-2017 Douglas Gilbert.
+ * Copyright (c) 2004-2018 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.
@@ -98,11 +98,11 @@ usage()
}
static void
-dStrRaw(const char* str, int len)
+dStrRaw(const uint8_t * str, int len)
{
int k;
- for (k = 0 ; k < len; ++k)
+ for (k = 0; k < len; ++k)
printf("%c", str[k]);
}
@@ -244,7 +244,7 @@ main(int argc, char * argv[])
resp_len = requestSenseBuff[7] + 8;
if (verbose > 1) {
pr2serr("Parameter data in hex\n");
- dStrHexErr((const char *)requestSenseBuff, resp_len, 1);
+ hex2stderr(requestSenseBuff, resp_len, 1);
}
progress = -1;
sg_get_sense_progress_fld(requestSenseBuff, resp_len,
@@ -282,15 +282,15 @@ main(int argc, char * argv[])
if (0 == res) {
resp_len = requestSenseBuff[7] + 8;
if (do_raw)
- dStrRaw((const char *)requestSenseBuff, resp_len);
+ dStrRaw(requestSenseBuff, resp_len);
else if (do_hex)
- dStrHex((const char *)requestSenseBuff, resp_len, 1);
+ hex2stdout(requestSenseBuff, resp_len, 1);
else if (1 == num_rs) {
pr2serr("Decode parameter data as sense data:\n");
sg_print_sense(NULL, requestSenseBuff, resp_len, 0);
if (verbose > 1) {
pr2serr("\nParameter data in hex\n");
- dStrHexErr((const char *)requestSenseBuff, resp_len, 1);
+ hex2stderr(requestSenseBuff, resp_len, 1);
}
}
continue;
@@ -321,7 +321,7 @@ main(int argc, char * argv[])
#ifndef SG_LIB_MINGW
if (do_time && (start_tm.tv_sec || start_tm.tv_usec)) {
struct timeval res_tm;
- double a, b;
+ double den, num;
gettimeofday(&end_tm, NULL);
res_tm.tv_sec = end_tm.tv_sec - start_tm.tv_sec;
@@ -330,13 +330,13 @@ main(int argc, char * argv[])
--res_tm.tv_sec;
res_tm.tv_usec += 1000000;
}
- a = res_tm.tv_sec;
- a += (0.000001 * res_tm.tv_usec);
- b = (double)num_rs;
+ den = res_tm.tv_sec;
+ den += (0.000001 * res_tm.tv_usec);
+ num = (double)num_rs;
printf("time to perform commands was %d.%06d secs",
(int)res_tm.tv_sec, (int)res_tm.tv_usec);
- if (a > 0.00001)
- printf("; %.2f operations/sec\n", b / a);
+ if (den > 0.00001)
+ printf("; %.2f operations/sec\n", num / den);
else
printf("\n");
}
diff --git a/src/sg_rmsn.c b/src/sg_rmsn.c
index 4d87b0fe..740aea8f 100644
--- a/src/sg_rmsn.c
+++ b/src/sg_rmsn.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005-2017 Douglas Gilbert.
+ * Copyright (c) 2005-2018 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.
@@ -17,6 +17,7 @@
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
+
#include "sg_lib.h"
#include "sg_cmds_basic.h"
#include "sg_cmds_extra.h"
@@ -30,7 +31,7 @@
* to the given SCSI device.
*/
-static const char * version_str = "1.14 20171006";
+static const char * version_str = "1.15 20180118";
#define SERIAL_NUM_SANITY_LEN (16 * 1024)
@@ -168,7 +169,7 @@ int main(int argc, char * argv[])
} else {
printf("Serial number:\n");
if (sn_len > 0)
- dStrHex((const char *)bp + 4, sn_len, 0);
+ hex2stdout(bp + 4, sn_len, 0);
}
}
}
diff --git a/src/sg_rtpg.c b/src/sg_rtpg.c
index b193b2bd..36e2cd23 100644
--- a/src/sg_rtpg.c
+++ b/src/sg_rtpg.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2004-2017 Christophe Varoqui and Douglas Gilbert.
+ * Copyright (c) 2004-2018 Christophe Varoqui and 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.
@@ -17,6 +17,7 @@
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
+
#include "sg_lib.h"
#include "sg_cmds_basic.h"
#include "sg_cmds_extra.h"
@@ -30,7 +31,7 @@
* to the given SCSI device.
*/
-static const char * version_str = "1.23 20171010";
+static const char * version_str = "1.24 20180118";
#define REPORT_TGT_GRP_BUFF_LEN 1024
@@ -77,11 +78,11 @@ static void usage()
}
-static void dStrRaw(const char* str, int len)
+static void dStrRaw(const uint8_t * str, int len)
{
int k;
- for (k = 0 ; k < len; ++k)
+ for (k = 0; k < len; ++k)
printf("%c", str[k]);
}
@@ -236,7 +237,7 @@ int main(int argc, char * argv[])
report_len = (int)sizeof(reportTgtGrpBuff);
}
if (raw) {
- dStrRaw((const char *)reportTgtGrpBuff, report_len);
+ dStrRaw(reportTgtGrpBuff, report_len);
goto err_out;
}
if (verbose)
@@ -244,7 +245,7 @@ int main(int argc, char * argv[])
if (hex) {
if (verbose)
printf("\nOutput response in hex:\n");
- dStrHex((const char *)reportTgtGrpBuff, report_len, 1);
+ hex2stdout(reportTgtGrpBuff, report_len, 1);
goto err_out;
}
printf("Report target port groups:\n");
diff --git a/src/sg_safte.c b/src/sg_safte.c
index b25423c2..274d6b8d 100644
--- a/src/sg_safte.c
+++ b/src/sg_safte.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2004-2017 Hannes Reinecke and Douglas Gilbert.
+ * Copyright (c) 2004-2018 Hannes Reinecke and 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,6 +11,7 @@
#include <stdlib.h>
#include <stdarg.h>
#include <stdbool.h>
+#include <stdint.h>
#include <string.h>
#include <ctype.h>
#include <getopt.h>
@@ -18,6 +19,7 @@
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
+
#include "sg_lib.h"
#include "sg_cmds_basic.h"
#include "sg_cmds_extra.h"
@@ -30,7 +32,7 @@
* to the 'SCSI Accessed Fault-Tolerant Enclosures' (SAF-TE) spec.
*/
-static const char * version_str = "0.28 20171006";
+static const char * version_str = "0.30 20180118";
#define SENSE_BUFF_LEN 64 /* Arbitrary, could be larger */
@@ -61,11 +63,11 @@ struct safte_cfg_t safte_cfg;
static unsigned int buf_capacity = 64;
static void
-dStrRaw(const char* str, int len)
+dStrRaw(const uint8_t * str, int len)
{
int k;
- for (k = 0 ; k < len; ++k)
+ for (k = 0; k < len; ++k)
printf("%c", str[k]);
}
@@ -143,11 +145,11 @@ do_safte_encl_status(int sg_fd, int do_hex, int do_raw, int verbose)
return res;
if (do_raw > 1) {
- dStrRaw((const char *)rb_buff, buf_capacity);
+ dStrRaw(rb_buff, buf_capacity);
return 0;
}
if (do_hex > 1) {
- dStrHex((const char *)rb_buff, buf_capacity, 1);
+ hex2stdout(rb_buff, buf_capacity, 1);
return 0;
}
printf("Enclosure Status:\n");
@@ -292,11 +294,11 @@ do_safte_usage_statistics(int sg_fd, int do_hex, int do_raw, int verbose)
}
if (do_raw > 1) {
- dStrRaw((const char *)rb_buff, buf_capacity);
+ dStrRaw(rb_buff, buf_capacity);
return 0;
}
if (do_hex > 1) {
- dStrHex((const char *)rb_buff, buf_capacity, 1);
+ hex2stdout(rb_buff, buf_capacity, 1);
return 0;
}
printf("Usage Statistics:\n");
@@ -337,11 +339,11 @@ do_safte_slot_insertions(int sg_fd, int do_hex, int do_raw, int verbose)
}
if (do_raw > 1) {
- dStrRaw((const char *)rb_buff, buf_capacity);
+ dStrRaw(rb_buff, buf_capacity);
return 0;
}
if (do_hex > 1) {
- dStrHex((const char *)rb_buff, buf_capacity, 1);
+ hex2stdout(rb_buff, buf_capacity, 1);
return 0;
}
printf("Slot insertions:\n");
@@ -375,11 +377,11 @@ do_safte_slot_status(int sg_fd, int do_hex, int do_raw, int verbose)
}
if (do_raw > 1) {
- dStrRaw((const char *)rb_buff, buf_capacity);
+ dStrRaw(rb_buff, buf_capacity);
return 0;
}
if (do_hex > 1) {
- dStrHex((const char *)rb_buff, buf_capacity, 1);
+ hex2stdout(rb_buff, buf_capacity, 1);
return 0;
}
printf("Slot status:\n");
@@ -430,11 +432,11 @@ do_safte_global_flags(int sg_fd, int do_hex, int do_raw, int verbose)
}
if (do_raw > 1) {
- dStrRaw((const char *)rb_buff, buf_capacity);
+ dStrRaw(rb_buff, buf_capacity);
return 0;
}
if (do_hex > 1) {
- dStrHex((const char *)rb_buff, buf_capacity, 1);
+ hex2stdout(rb_buff, buf_capacity, 1);
return 0;
}
printf("Global Flags:\n");
@@ -647,11 +649,11 @@ main(int argc, char * argv[])
goto err_out;
}
if (1 == do_raw) {
- dStrRaw((const char *)rb_buff, buf_capacity);
+ dStrRaw(rb_buff, buf_capacity);
goto finish;
}
if (1 == do_hex) {
- dStrHex((const char *)rb_buff, buf_capacity, 1);
+ hex2stdout(rb_buff, buf_capacity, 1);
goto finish;
}
diff --git a/src/sg_sanitize.c b/src/sg_sanitize.c
index 8e6ac6f3..a346887d 100644
--- a/src/sg_sanitize.c
+++ b/src/sg_sanitize.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011-2017 Douglas Gilbert.
+ * Copyright (c) 2011-2018 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.
@@ -30,7 +30,7 @@
#include "sg_unaligned.h"
#include "sg_pr2serr.h"
-static const char * version_str = "1.04 20171008";
+static const char * version_str = "1.05 20180118";
/* Not all environments support the Unix sleep() */
#if defined(MSC_VER) || defined(__MINGW32__)
@@ -212,7 +212,7 @@ do_sanitize(int sg_fd, const struct opts_t * op, const void * param_lstp,
if (op->verbose > 2) {
if (param_lst_len > 0) {
pr2serr(" Parameter list contents:\n");
- dStrHexErr((const char *)param_lstp, param_lst_len, 1);
+ hex2stderr(param_lstp, param_lst_len, 1);
}
pr2serr(" Sanitize command timeout: %d seconds\n", timeout);
}
@@ -690,7 +690,7 @@ main(int argc, char * argv[])
}
if ((0 == ret) && (! op->early) && (! op->wait)) {
- for (k = 0 ;; ++k) {
+ for (k = 0; ;++k) { /* unbounded, exits via break */
sleep_for(POLL_DURATION_SECS);
memset(rsBuff, 0x0, sizeof(rsBuff));
res = sg_ll_request_sense(sg_fd, op->desc, rsBuff, sizeof(rsBuff),
@@ -720,7 +720,7 @@ main(int argc, char * argv[])
resp_len = rsBuff[7] + 8;
if (vb > 2) {
pr2serr("Parameter data in hex\n");
- dStrHexErr((const char *)rsBuff, resp_len, 1);
+ hex2stderr(rsBuff, resp_len, 1);
}
progress = -1;
sg_get_sense_progress_fld(rsBuff, resp_len, &progress);
diff --git a/src/sg_sat_identify.c b/src/sg_sat_identify.c
index ca6431ab..13c5306d 100644
--- a/src/sg_sat_identify.c
+++ b/src/sg_sat_identify.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006-2017 Douglas Gilbert.
+ * Copyright (c) 2006-2018 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.
@@ -99,11 +99,11 @@ static void usage()
"support the SCSI ATA\nPASS-THROUGH(32) command.\n");
}
-static void dStrRaw(const char* str, int len)
+static void dStrRaw(const uint8_t * str, int len)
{
int k;
- for (k = 0 ; k < len; ++k)
+ for (k = 0; k < len; ++k)
printf("%c", str[k]);
}
@@ -352,7 +352,7 @@ static int do_identify_dev(int sg_fd, bool do_packet, int cdb_len,
if (ok) { /* output result if it is available */
if (do_raw)
- dStrRaw((const char *)inBuff, 512);
+ dStrRaw(inBuff, 512);
else if (0 == do_hex) {
if (do_ident) {
usp = (const unsigned short *)inBuff;
@@ -370,7 +370,7 @@ static int do_identify_dev(int sg_fd, bool do_packet, int cdb_len,
sg_is_big_endian());
}
} else if (1 == do_hex)
- dStrHex((const char *)inBuff, 512, 0);
+ hex2stdout(inBuff, 512, 0);
else if (2 == do_hex)
dWordHex((const unsigned short *)inBuff, 256, 0,
sg_is_big_endian());
@@ -378,7 +378,7 @@ static int do_identify_dev(int sg_fd, bool do_packet, int cdb_len,
dWordHex((const unsigned short *)inBuff, 256, -2,
sg_is_big_endian());
else /* '-HHHH' hex bytes only */
- dStrHex((const char *)inBuff, 512, -1);
+ hex2stdout(inBuff, 512, -1);
}
return 0;
}
diff --git a/src/sg_sat_phy_event.c b/src/sg_sat_phy_event.c
index 720fc9db..d18f2e5d 100644
--- a/src/sg_sat_phy_event.c
+++ b/src/sg_sat_phy_event.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006-2017 Douglas Gilbert.
+ * Copyright (c) 2006-2018 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.
@@ -140,11 +140,11 @@ find_phy_desc(int id)
}
static void
-dStrRaw(const char* str, int len)
+dStrRaw(const uint8_t * str, int len)
{
int k;
- for (k = 0 ; k < len; ++k)
+ for (k =0; k < len; ++k)
printf("%c", str[k]);
}
@@ -347,9 +347,9 @@ do_read_log_ext(int sg_fd, int log_addr, bool page_in_log, int feature,
if (ok) { /* output result if ok and --hex or --raw given */
if (do_raw)
- dStrRaw((const char *)resp, mx_resp_len);
+ dStrRaw(resp, mx_resp_len);
else if (1 == do_hex)
- dStrHex((const char *)resp, mx_resp_len, 0);
+ hex2stdout(resp, mx_resp_len, 0);
else if (do_hex > 1)
dWordHex((const unsigned short *)resp, mx_resp_len / 2, 0,
sg_is_big_endian());
diff --git a/src/sg_sat_read_gplog.c b/src/sg_sat_read_gplog.c
index 7feadeb5..18fa4193 100644
--- a/src/sg_sat_read_gplog.c
+++ b/src/sg_sat_read_gplog.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014-2017 Hannes Reinecke, SUSE Linux GmbH.
+ * Copyright (c) 2014-2018 Hannes Reinecke, SUSE Linux GmbH.
* All rights reserved.
* Use of this source code is governed by a BSD-style
* license that can be found in the BSD_LICENSE file.
@@ -18,6 +18,7 @@
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
+
#include "sg_lib.h"
#include "sg_cmds_basic.h"
#include "sg_cmds_extra.h"
@@ -51,7 +52,7 @@
#define DEF_TIMEOUT 20
-static const char * version_str = "1.16 20171107";
+static const char * version_str = "1.17 20180119";
struct opts_t {
bool ck_cond;
@@ -212,12 +213,12 @@ do_read_gplog(int sg_fd, int ata_cmd, unsigned char *inbuff,
dWordHex((const unsigned short *)inbuff, op->count * 256, 0,
sg_is_big_endian());
else if (1 == op->hex)
- dStrHex((const char *)inbuff, 512, 0);
+ hex2stdout(inbuff, 512, 0);
else if (3 == op->hex) /* '-HHH' suitable for "hdparm --Istdin" */
dWordHex((const unsigned short *)inbuff, 256, -2,
sg_is_big_endian());
else /* '-HHHH' hex bytes only */
- dStrHex((const char *)inbuff, 512, -1);
+ hex2stdout(inbuff, 512, -1);
} else if ((res > 0) && (res & SAM_STAT_CHECK_CONDITION)) {
if (op->verbose > 1) {
pr2serr("ATA pass through:\n");
diff --git a/src/sg_scan_win32.c b/src/sg_scan_win32.c
index 7424efdf..1433a46f 100644
--- a/src/sg_scan_win32.c
+++ b/src/sg_scan_win32.c
@@ -40,7 +40,7 @@
#include "sg_pt_win32.h"
-static const char * version_str = "1.19 (win32) 20180104";
+static const char * version_str = "1.19 (win32) 20180118";
#define MAX_SCSI_ELEMS 2048
#define MAX_ADAPTER_NUM 128
@@ -693,12 +693,12 @@ sg_do_wscan(char letter, bool show_bt, int scsi_scan)
printf("%s", sp->qp_descriptor.raw + j);
printf("\n");
if (verbose > 2)
- dStrHexErr(sp->qp_descriptor.raw, 144, 0);
+ hex2stderr(sp->qp_descriptor.raw, 144, 0);
} else
printf("\n");
if ((verbose > 3) && sp->qp_uid_valid) {
printf(" UID valid, in hex:\n");
- dStrHexErr(sp->qp_uid.raw, sizeof(sp->qp_uid.raw), 1);
+ hex2stderr(sp->qp_uid.raw, sizeof(sp->qp_uid.raw), 1);
}
}
}
diff --git a/src/sg_senddiag.c b/src/sg_senddiag.c
index 54504bec..e49aedfd 100644
--- a/src/sg_senddiag.c
+++ b/src/sg_senddiag.c
@@ -1,5 +1,5 @@
/* A utility program originally written for the Linux OS SCSI subsystem
-* Copyright (C) 2003-2017 D. Gilbert
+* Copyright (C) 2003-2018 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)
@@ -20,15 +20,18 @@
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
+
#include "sg_lib.h"
#include "sg_cmds_basic.h"
#include "sg_cmds_extra.h"
+#if SG_LIB_WIN32
#include "sg_pt.h" /* needed for scsi_pt_win32_direct() */
+#endif
#include "sg_unaligned.h"
#include "sg_pr2serr.h"
-static const char * version_str = "0.55 20171208";
+static const char * version_str = "0.56 20180119";
#define ME "sg_senddiag: "
@@ -848,12 +851,12 @@ main(int argc, char * argv[])
rsp_len = sg_get_unaligned_be16(rsp_buff + 2) + 4;
rsp_len= (rsp_len < rsp_buff_size) ? rsp_len : rsp_buff_size;
if (op->do_hex > 1)
- dStrHex((const char *)rsp_buff, rsp_len,
+ hex2stdout(rsp_buff, rsp_len,
(2 == op->do_hex) ? 0 : -1);
else if (pg < 0x1) {
printf("Supported diagnostic pages response:\n");
if (op->do_hex)
- dStrHex((const char *)rsp_buff, rsp_len, 1);
+ hex2stdout(rsp_buff, rsp_len, 1);
else {
for (k = 0; k < (rsp_len - 4); ++k) {
cp = find_page_code_desc(rsp_buff[k + 4]);
@@ -868,7 +871,7 @@ main(int argc, char * argv[])
"hex:\n", cp, pg);
else
printf("diagnostic page 0x%x response in hex:\n", pg);
- dStrHex((const char *)rsp_buff, rsp_len, 1);
+ hex2stdout(rsp_buff, rsp_len, 1);
}
} else {
ret = res;
diff --git a/src/sg_ses.c b/src/sg_ses.c
index f14f495f..405d1195 100644
--- a/src/sg_ses.c
+++ b/src/sg_ses.c
@@ -13,6 +13,7 @@
#include <stdbool.h>
#include <string.h>
#include <ctype.h>
+#include <errno.h>
#include <getopt.h>
#define __STDC_FORMAT_MACROS 1
#include <inttypes.h>
@@ -20,11 +21,14 @@
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
+
#include "sg_lib.h"
#include "sg_cmds_basic.h"
#include "sg_cmds_extra.h"
#include "sg_unaligned.h"
+#ifdef SG_LIB_WIN32
#include "sg_pt.h" /* needed for scsi_pt_win32_direct() */
+#endif
#include "sg_pr2serr.h"
/*
@@ -32,7 +36,7 @@
* commands tailored for SES (enclosure) devices.
*/
-static const char * version_str = "2.29 20180111"; /* ses4r01 */
+static const char * version_str = "2.30 20180118"; /* ses4r01 */
#define MX_ALLOC_LEN ((64 * 1024) - 4) /* max allowable for big enclosures */
#define MX_ELEM_HDR 1024
@@ -1213,11 +1217,11 @@ parse_cmd_line(struct opts_t *op, int argc, char *argv[])
n = sg_get_num(optarg);
if ((n < 0) || (n > 65535)) {
pr2serr("bad argument to '--maxlen' (0 to 65535 inclusive "
- "expected)\n");
+ "expected)\n");
return SG_LIB_SYNTAX_ERROR;
}
if (0 == n)
- op->maxlen = MX_ALLOC_LEN;
+ op->maxlen = MX_ALLOC_LEN;
else if (n < 4)
pr2serr("Warning: --maxlen= less than 4 ignored\n");
else
@@ -1760,14 +1764,14 @@ do_rec_diag(int sg_fd, int page_code, uint8_t * rsp_buff,
if ((0x9 == rsp_buff[0]) && (1 & rsp_buff[1])) {
pr2serr("Enclosure busy, try again later\n");
if (op->do_hex)
- dStrHexErr((const char *)rsp_buff, rsp_len, 0);
+ hex2stderr(rsp_buff, rsp_len, 0);
} else if (0x8 == rsp_buff[0]) {
pr2serr("Enclosure only supports Short Enclosure Status: "
"0x%x\n", rsp_buff[1]);
} else {
pr2serr("Invalid response, wanted page code: 0x%x but got "
"0x%x\n", page_code, rsp_buff[0]);
- dStrHexErr((const char *)rsp_buff, rsp_len, 0);
+ hex2stderr(rsp_buff, rsp_len, 0);
}
return -2;
}
@@ -1784,15 +1788,36 @@ do_rec_diag(int sg_fd, int page_code, uint8_t * rsp_buff,
return res;
}
+#if 1
+
static void
-dStrRaw(const char* str, int len)
+dStrRaw(const uint8_t * str, int len)
{
int k;
- for (k = 0 ; k < len; ++k)
+ for (k = 0; k < len; ++k)
printf("%c", str[k]);
}
+#else
+
+static void
+dStrRaw(const uint8_t * str, int len)
+{
+ int res, err;
+
+ if (len > 0) {
+ res = write(fileno(stdout), str, len);
+ if (res < 0) {
+ err = errno;
+ pr2serr("%s: write to stdout failed: %s [%d]\n", __func__,
+ strerror(err), err);
+ }
+ }
+}
+
+#endif
+
/* CONFIGURATION_DPC [0x1]
* Display Configuration diagnostic page. */
static void
@@ -1840,8 +1865,7 @@ configuration_sdg(const uint8_t * resp, int resp_len)
char bb[1024];
printf(" vendor-specific data:\n");
- dStrHexStr((const char *)(bp + 40), el - 40, " ", 0,
- sizeof(bb), bb);
+ hex2str(bp + 40, el - 40, " ", 0, sizeof(bb), bb);
printf("%s\n", bb);
}
}
@@ -3290,7 +3314,7 @@ additional_elem_helper(const char * pad, const uint8_t * ae_bp,
printf("%sTransport protocol: PCIe subprotocol=0x%x not "
"decoded\n", pad, pcie_pt);
if (op->verbose)
- dStrHex((const char *)ae_bp, len, 0);
+ hex2stdout(ae_bp, len, 0);
break;
}
phys = ae_bp[4];
@@ -3327,7 +3351,7 @@ additional_elem_helper(const char * pad, const uint8_t * ae_bp,
printf("%sTransport protocol: %s not decoded\n", pad,
sg_get_trans_proto_str((0xf & ae_bp[0]), sizeof(b), b));
if (op->verbose)
- dStrHex((const char *)ae_bp, len, 0);
+ hex2stdout(ae_bp, len, 0);
break;
}
}
@@ -3518,8 +3542,7 @@ subenc_string_sdg(const uint8_t * resp, int resp_len)
if (el > 4) {
char bb[1024];
- dStrHexStr((const char *)(bp + 40), el - 40, " ", 0,
- sizeof(bb), bb);
+ hex2str(bp + 40, el - 40, " ", 0, sizeof(bb), bb);
printf("%s\n", bb);
} else
printf(" <empty>\n");
@@ -3812,7 +3835,7 @@ read_hex(const char * inp, uint8_t * arr, int * arr_len, int verb)
*arr_len = k + 1;
}
if (verb > 3)
- dStrHex((const char *)arr, *arr_len, 0);
+ hex2stdout(arr, *arr_len, 0);
if (fp && (fp != stdin))
fclose(fp);
return 0;
@@ -3854,22 +3877,22 @@ process_status_page(int sg_fd, struct opts_t * op)
goto fini;
if (op->do_raw) {
if (1 == op->do_raw)
- dStrHex((const char *)resp + 4, resp_len - 4, -1);
+ hex2stdout(resp + 4, resp_len - 4, -1);
else {
if (sg_set_binary_mode(STDOUT_FILENO) < 0)
perror("sg_set_binary_mode");
- dStrRaw((const char *)resp, resp_len);
+ dStrRaw(resp, resp_len);
}
} else if (op->do_hex) {
if (op->do_hex > 2)
- dStrHex((const char *)resp, resp_len, -1);
+ hex2stdout(resp, resp_len, -1);
else {
if (cp)
printf("Response in hex from diagnostic page: %s\n", cp);
else
printf("Response in hex from unknown diagnostic page "
"[0x%x]\n", op->page_code);
- dStrHex((const char *)resp, resp_len, (2 == op->do_hex));
+ hex2stdout(resp, resp_len, (2 == op->do_hex));
}
} else {
memset(&primary_info, 0, sizeof(primary_info));
@@ -3928,7 +3951,7 @@ process_status_page(int sg_fd, struct opts_t * op)
printf("String In diagnostic page (for primary "
"subenclosure):\n");
if (resp_len > 4)
- dStrHex((const char *)(resp + 4), resp_len - 4, 0);
+ hex2stdout(resp + 4, resp_len - 4, 0);
else
printf(" <empty>\n");
break;
@@ -4014,7 +4037,7 @@ process_status_page(int sg_fd, struct opts_t * op)
default:
printf("Cannot decode response from diagnostic "
"page: %s\n", (cp ? cp : "<unknown>"));
- dStrHex((const char *)resp, resp_len, 0);
+ hex2stdout(resp, resp_len, 0);
}
}
ret = 0;
diff --git a/src/sg_ses_microcode.c b/src/sg_ses_microcode.c
index 626a4297..656eb95d 100644
--- a/src/sg_ses_microcode.c
+++ b/src/sg_ses_microcode.c
@@ -40,7 +40,7 @@
* RESULTS commands in order to send microcode to the given SES device.
*/
-static const char * version_str = "1.10 20180112"; /* ses4r01 */
+static const char * version_str = "1.11 20180119"; /* ses4r01 */
#define ME "sg_ses_microcode: "
#define MAX_XFER_LEN (128 * 1024 * 1024)
diff --git a/src/sg_stpg.c b/src/sg_stpg.c
index a79cc8b2..eab39d50 100644
--- a/src/sg_stpg.c
+++ b/src/sg_stpg.c
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2004-2017 Hannes Reinecke, Christophe Varoqui, Douglas Gilbert
+* Copyright (c) 2004-2018 Hannes Reinecke, Christophe Varoqui, 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.
@@ -129,11 +129,11 @@ usage()
}
static void
-dStrRaw(const char* str, int len)
+dStrRaw(const uint8_t * str, int len)
{
int k;
- for (k = 0 ; k < len; ++k)
+ for (k = 0; k < len; ++k)
printf("%c", str[k]);
}
@@ -166,7 +166,7 @@ decode_target_port(unsigned char * buff, int len, int *d_id, int *d_tpg)
if ((1 != c_set) || (1 != assoc) || (4 != i_len)) {
pr2serr(" << expected binary code_set, target port "
"association, length 4>>\n");
- dStrHexErr((const char *)ip, i_len, 0);
+ hex2stderr(ip, i_len, 0);
break;
}
*d_id = sg_get_unaligned_be16(ip + 2);
@@ -175,7 +175,7 @@ decode_target_port(unsigned char * buff, int len, int *d_id, int *d_tpg)
if ((1 != c_set) || (1 != assoc) || (4 != i_len)) {
pr2serr(" << expected binary code_set, target port "
"association, length 4>>\n");
- dStrHexErr((const char *)ip, i_len, 0);
+ hex2stderr(ip, i_len, 0);
break;
}
*d_tpg = sg_get_unaligned_be16(ip + 2);
@@ -575,7 +575,7 @@ main(int argc, char * argv[])
"response\n");
if (verbose) {
pr2serr("First 32 bytes of bad response\n");
- dStrHexErr((const char *)rsp_buff, 32, 0);
+ hex2stderr(rsp_buff, 32, 0);
}
return SG_LIB_CAT_MALFORMED;
}
@@ -610,7 +610,7 @@ main(int argc, char * argv[])
report_len = (int)sizeof(reportTgtGrpBuff);
}
if (raw) {
- dStrRaw((const char *)reportTgtGrpBuff, report_len);
+ dStrRaw(reportTgtGrpBuff, report_len);
goto err_out;
}
if (verbose)
@@ -618,7 +618,7 @@ main(int argc, char * argv[])
if (hex) {
if (verbose)
printf("\nOutput response in hex:\n");
- dStrHex((const char *)reportTgtGrpBuff, report_len, 1);
+ hex2stdout(reportTgtGrpBuff, report_len, 1);
goto err_out;
}
memset(tgtGrpState, 0, sizeof(struct tgtgrp) * 256);
diff --git a/src/sg_test_rwbuf.c b/src/sg_test_rwbuf.c
index 0ab5c613..968a5e40 100644
--- a/src/sg_test_rwbuf.c
+++ b/src/sg_test_rwbuf.c
@@ -1,7 +1,7 @@
/*
* (c) 2000 Kurt Garloff <garloff at suse dot de>
* heavily based on Douglas Gilbert's sg_rbuf program.
- * (c) 1999-2017 Douglas Gilbert
+ * (c) 1999-2018 Douglas Gilbert
*
* Program to test the SCSI host adapter by issuing
* write and read operations on a device's buffer
@@ -43,7 +43,7 @@
#include "sg_pr2serr.h"
-static const char * version_str = "1.13 20171107";
+static const char * version_str = "1.14 20180116";
#define BPI (signed)(sizeof(int))
@@ -223,11 +223,11 @@ void do_fill_buffer (int *buf, int len)
}
-int read_buffer (int sg_fd, unsigned size)
+int read_buffer (int sg_fd, unsigned ssize)
{
int res, k;
unsigned char rb_cdb[] = {READ_BUFFER, 0, 0, 0, 0, 0, 0, 0, 0, 0};
- int bufSize = size + addread;
+ int bufSize = ssize + addread;
unsigned char * rbBuff = (unsigned char *)malloc(bufSize);
unsigned char sense_buffer[32];
struct sg_io_hdr io_hdr;
@@ -278,15 +278,15 @@ int read_buffer (int sg_fd, unsigned size)
return res;
}
- res = do_checksum((int*)rbBuff, size, false);
+ res = do_checksum((int*)rbBuff, ssize, false);
free(rbBuff);
return res;
}
-int write_buffer (int sg_fd, unsigned size)
+int write_buffer (int sg_fd, unsigned ssize)
{
unsigned char wb_cdb[] = {WRITE_BUFFER, 0, 0, 0, 0, 0, 0, 0, 0, 0};
- int bufSize = size + addwrite;
+ int bufSize = ssize + addwrite;
unsigned char * wbBuff = (unsigned char *)malloc(bufSize);
unsigned char sense_buffer[32];
struct sg_io_hdr io_hdr;
@@ -295,7 +295,7 @@ int write_buffer (int sg_fd, unsigned size)
if (NULL == wbBuff)
return -1;
memset(wbBuff, 0, bufSize);
- do_fill_buffer ((int*)wbBuff, size);
+ do_fill_buffer ((int*)wbBuff, ssize);
wb_cdb[1] = RWB_MODE_DATA;
sg_put_unaligned_be24((uint32_t)bufSize, wb_cdb + 6);
memset(&io_hdr, 0, sizeof(struct sg_io_hdr));
diff --git a/src/sg_timestamp.c b/src/sg_timestamp.c
index 3862ad8b..aa6dea6a 100644
--- a/src/sg_timestamp.c
+++ b/src/sg_timestamp.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2017 Douglas Gilbert.
+ * Copyright (c) 2015-2018 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.
@@ -34,7 +34,7 @@
* to the given SCSI device. Based on spc5r07.pdf .
*/
-static const char * version_str = "1.04 20171008";
+static const char * version_str = "1.05 20180118";
#define REP_TIMESTAMP_CMDLEN 12
#define SET_TIMESTAMP_CMDLEN 12
@@ -168,8 +168,7 @@ sg_ll_rep_timestamp(int sg_fd, void * resp, int mx_resp_len, int * residp,
*residp = k;
if ((verbose > 2) && ((mx_resp_len - k) > 0)) {
pr2serr("Parameter data returned:\n");
- dStrHexErr((const char *)resp, mx_resp_len - k,
- ((verbose > 3) ? -1 : 1));
+ hex2stderr(resp, mx_resp_len - k, ((verbose > 3) ? -1 : 1));
}
destruct_scsi_pt_obj(ptvp);
return ret;
@@ -197,7 +196,7 @@ sg_ll_set_timestamp(int sg_fd, void * paramp, int param_len, bool noisy,
pr2serr("\n");
if ((verbose > 1) && paramp && param_len) {
pr2serr(" set timestamp parameter list:\n");
- dStrHexErr((const char *)paramp, param_len, -1);
+ hex2stderr(paramp, param_len, -1);
}
}
@@ -231,11 +230,11 @@ sg_ll_set_timestamp(int sg_fd, void * paramp, int param_len, bool noisy,
}
static void
-dStrRaw(const char* str, int len)
+dStrRaw(const uint8_t * str, int len)
{
int k;
- for (k = 0 ; k < len; ++k)
+ for (k = 0; k < len; ++k)
printf("%c", str[k]);
}
@@ -357,7 +356,7 @@ main(int argc, char * argv[])
res = sg_ll_rep_timestamp(sg_fd, d_buff, 12, NULL, true, verbose);
if (0 == res) {
if (do_raw)
- dStrRaw((const char *)d_buff, 12);
+ dStrRaw(d_buff, 12);
else {
int len = sg_get_unaligned_be16(d_buff + 0);
if (len < 8)
diff --git a/src/sg_turs.c b/src/sg_turs.c
index f4ac2efa..2578378d 100644
--- a/src/sg_turs.c
+++ b/src/sg_turs.c
@@ -3,7 +3,7 @@
* data transfer (and no REQUEST SENSE command iff the unit is ready)
* then this can be used for timing per SCSI command overheads.
*
- * Copyright (C) 2000-2017 D. Gilbert
+ * Copyright (C) 2000-2018 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)
@@ -33,7 +33,7 @@
#include "sg_pr2serr.h"
-static const char * version_str = "3.36 20171011";
+static const char * version_str = "3.37 20180116";
#if defined(MSC_VER) || defined(__MINGW32__)
#define HAVE_MS_SLEEP
@@ -369,7 +369,7 @@ main(int argc, char * argv[])
#ifndef SG_LIB_MINGW
if ((op->do_time) && (start_tm.tv_sec || start_tm.tv_usec)) {
struct timeval res_tm;
- double a, b;
+ double den, num;
gettimeofday(&end_tm, NULL);
res_tm.tv_sec = end_tm.tv_sec - start_tm.tv_sec;
@@ -378,13 +378,13 @@ main(int argc, char * argv[])
--res_tm.tv_sec;
res_tm.tv_usec += 1000000;
}
- a = res_tm.tv_sec;
- a += (0.000001 * res_tm.tv_usec);
- b = (double)op->do_number;
+ den = res_tm.tv_sec;
+ den += (0.000001 * res_tm.tv_usec);
+ num = (double)op->do_number;
printf("time to perform commands was %d.%06d secs",
(int)res_tm.tv_sec, (int)res_tm.tv_usec);
- if (a > 0.00001)
- printf("; %.2f operations/sec\n", b / a);
+ if (den > 0.00001)
+ printf("; %.2f operations/sec\n", num / den);
else
printf("\n");
}
diff --git a/src/sg_vpd.c b/src/sg_vpd.c
index 5f2e89bf..010aca56 100644
--- a/src/sg_vpd.c
+++ b/src/sg_vpd.c
@@ -38,7 +38,7 @@
*/
-static const char * version_str = "1.33 20180105"; /* spc5r18 + sbc4r14 */
+static const char * version_str = "1.34 20180118"; /* spc5r18 + sbc4r14 */
/* standard VPD pages, in ascending page number order */
#define VPD_SUPPORTED_VPDS 0x0
@@ -517,7 +517,7 @@ vpd_fetch_page_from_dev(int sg_fd, unsigned char * rp, int page,
n = (rlen < 32) ? rlen : 32;
if (vb) {
pr2serr("First %d bytes of bad response\n", n);
- dStrHexErr((const char *)rp, n, 0);
+ hex2stderr(rp, n, 0);
}
return SG_LIB_CAT_MALFORMED;
} else if ((0x80 == page) && (0x2 == rp[2]) && (0x2 == rp[3])) {
@@ -632,11 +632,11 @@ count_standard_vpds(int vpd_pn)
}
static void
-dStrRaw(const char * str, int len)
+dStrRaw(const uint8_t * str, int len)
{
int k;
- for (k = 0 ; k < len; ++k)
+ for (k = 0; k < len; ++k)
printf("%c", str[k]);
}
@@ -780,7 +780,7 @@ decode_net_man_vpd(unsigned char * buff, int len, int do_hex)
unsigned char * bp;
if ((1 == do_hex) || (do_hex > 2)) {
- dStrHex((const char *)buff, len, (1 == do_hex) ? 0 : -1);
+ hex2stdout(buff, len, (1 == do_hex) ? 0 : -1);
return;
}
if (len < 4) {
@@ -804,7 +804,7 @@ decode_net_man_vpd(unsigned char * buff, int len, int do_hex)
if (na_len > 0) {
if (do_hex > 1) {
printf(" Network address:\n");
- dStrHex((const char *)(bp + 4), na_len, 0);
+ hex2stdout((bp + 4), na_len, 0);
} else
printf(" %s\n", bp + 4);
}
@@ -827,7 +827,7 @@ decode_mode_policy_vpd(unsigned char * buff, int len, int do_hex)
unsigned char * bp;
if ((1 == do_hex) || (do_hex > 2)) {
- dStrHex((const char *)buff, len, (1 == do_hex) ? 1 : -1);
+ hex2stdout(buff, len, (1 == do_hex) ? 1 : -1);
return;
}
if (len < 4) {
@@ -844,7 +844,7 @@ decode_mode_policy_vpd(unsigned char * buff, int len, int do_hex)
return;
}
if (do_hex > 1)
- dStrHex((const char *)bp, 4, 1);
+ hex2stdout(bp, 4, 1);
else {
printf(" Policy page code: 0x%x", (bp[0] & 0x3f));
if (bp[1])
@@ -865,7 +865,7 @@ decode_scsi_ports_vpd(unsigned char * buff, int len, const struct opts_t * op)
unsigned char * bp;
if ((1 == op->do_hex) || (op->do_hex > 2)) {
- dStrHex((const char *)buff, len, (1 == op->do_hex) ? 1 : -1);
+ hex2stdout(buff, len, (1 == op->do_hex) ? 1 : -1);
return;
}
if (len < 4) {
@@ -887,7 +887,7 @@ decode_scsi_ports_vpd(unsigned char * buff, int len, const struct opts_t * op)
if (ip_tid_len > 0) {
if (op->do_hex > 1) {
printf(" Initiator port transport id:\n");
- dStrHex((const char *)(bp + 8), ip_tid_len, 1);
+ hex2stdout((bp + 8), ip_tid_len, 1);
} else {
char b[1024];
@@ -904,7 +904,7 @@ decode_scsi_ports_vpd(unsigned char * buff, int len, const struct opts_t * op)
if (tpd_len > 0) {
if (op->do_hex > 1) {
printf(" Target port descriptor(s):\n");
- dStrHex((const char *)(bp + bump + 4), tpd_len, 1);
+ hex2stdout(bp + bump + 4, tpd_len, 1);
} else {
if ((0 == op->do_quiet) || (ip_tid_len > 0))
printf(" Target port descriptor(s):\n");
@@ -980,7 +980,7 @@ decode_dev_ids_quiet(unsigned char * buff, int len, int m_assoc,
if (1 != c_set) {
pr2serr(" << expected binary code_set (1), got %d for "
"NAA=%d>>\n", c_set, naa);
- dStrHexErr((const char *)ip, i_len, 0);
+ hex2stderr(ip, i_len, 0);
break;
}
switch (naa) {
@@ -988,7 +988,7 @@ decode_dev_ids_quiet(unsigned char * buff, int len, int m_assoc,
if (8 != i_len) {
pr2serr(" << unexpected NAA 2 identifier "
"length: 0x%x>>\n", i_len);
- dStrHexErr((const char *)ip, i_len, 0);
+ hex2stderr(ip, i_len, 0);
break;
}
printf(" 0x");
@@ -1001,7 +1001,7 @@ decode_dev_ids_quiet(unsigned char * buff, int len, int m_assoc,
if (8 != i_len) {
pr2serr(" << unexpected NAA 3 or 5 "
"identifier length: 0x%x>>\n", i_len);
- dStrHexErr((const char *)ip, i_len, 0);
+ hex2stderr(ip, i_len, 0);
break;
}
if ((0 == is_sas) || (1 != assoc)) {
@@ -1029,7 +1029,7 @@ decode_dev_ids_quiet(unsigned char * buff, int len, int m_assoc,
if (16 != i_len) {
pr2serr(" << unexpected NAA 6 identifier length: "
"0x%x>>\n", i_len);
- dStrHexErr((const char *)ip, i_len, 0);
+ hex2stderr(ip, i_len, 0);
break;
}
printf(" 0x");
@@ -1040,7 +1040,7 @@ decode_dev_ids_quiet(unsigned char * buff, int len, int m_assoc,
default:
pr2serr(" << bad NAA nibble, expected 2, 3, 5 or 6, got "
"%d>>\n", naa);
- dStrHexErr((const char *)ip, i_len, 0);
+ hex2stderr(ip, i_len, 0);
break;
}
break;
@@ -1066,7 +1066,7 @@ decode_dev_ids_quiet(unsigned char * buff, int len, int m_assoc,
case 8: /* SCSI name string */
if (c_set < 2) { /* quietly accept ASCII for UTF-8 */
pr2serr(" << expected UTF-8 code_set>>\n");
- dStrHexErr((const char *)ip, i_len, 0);
+ hex2stderr(ip, i_len, 0);
break;
}
if (! (strncmp((const char *)ip, "eui.", 4) ||
@@ -1075,7 +1075,7 @@ decode_dev_ids_quiet(unsigned char * buff, int len, int m_assoc,
strncmp((const char *)ip, "NAA.", 4) ||
strncmp((const char *)ip, "iqn.", 4))) {
pr2serr(" << expected name string prefix>>\n");
- dStrHexErr((const char *)ip, i_len, -1);
+ hex2stderr(ip, i_len, -1);
break;
}
/* does %s print out UTF-8 ok??
@@ -1176,7 +1176,7 @@ decode_x_inq_vpd(unsigned char * b, int len, int do_hex, bool do_long,
return;
}
if (do_hex) {
- dStrHex((const char *)b, len, (1 == do_hex) ? 0 : -1);
+ hex2stdout(b, len, (1 == do_hex) ? 0 : -1);
return;
}
if (do_long) {
@@ -1299,7 +1299,7 @@ static void
decode_softw_inf_id(unsigned char * buff, int len, int do_hex)
{
if (do_hex) {
- dStrHex((const char *)buff, len, (1 == do_hex) ? 0 : -1);
+ hex2stdout(buff, len, (1 == do_hex) ? 0 : -1);
return;
}
len -= 4;
@@ -1325,7 +1325,7 @@ decode_ata_info_vpd(unsigned char * buff, int len, int do_long, int do_hex)
return;
}
if (do_hex && (2 != do_hex)) {
- dStrHex((const char *)buff, len, (1 == do_hex) ? 0 : -1);
+ hex2stdout(buff, len, (1 == do_hex) ? 0 : -1);
return;
}
memcpy(b, buff + 8, 8);
@@ -1342,7 +1342,7 @@ decode_ata_info_vpd(unsigned char * buff, int len, int do_long, int do_hex)
ata_transp = (0x34 == buff[36]) ? "SATA" : "PATA";
if (do_long) {
printf(" Device signature [%s] (in hex):\n", ata_transp);
- dStrHex((const char *)buff + 36, 20, 0);
+ hex2stdout(buff + 36, 20, 0);
} else
printf(" Device signature indicates %s transport\n", ata_transp);
cc = buff[56]; /* 0xec for IDENTIFY DEVICE and 0xa1 for IDENTIFY
@@ -1379,7 +1379,7 @@ decode_ata_info_vpd(unsigned char * buff, int len, int do_long, int do_hex)
if (len < 572)
return;
if (2 == do_hex)
- dStrHex((const char *)(buff + 60), 512, 0);
+ hex2stdout((buff + 60), 512, 0);
else if (do_long)
dWordHex((const unsigned short *)(buff + 60), 256, 0, is_be);
}
@@ -1394,7 +1394,7 @@ decode_power_condition(unsigned char * buff, int len, int do_hex)
return;
}
if (do_hex) {
- dStrHex((const char *)buff, len, (1 == do_hex) ? 0 : -1);
+ hex2stdout(buff, len, (1 == do_hex) ? 0 : -1);
return;
}
printf(" Standby_y=%d Standby_z=%d Idle_c=%d Idle_b=%d Idle_a=%d\n",
@@ -1423,7 +1423,7 @@ decode_dev_const_vpd(unsigned char * buff, int len, int do_hex)
const char * dcp = "Device constituents VPD page";
if ((1 == do_hex) || (do_hex > 2)) {
- dStrHex((const char *)buff, len, (1 == do_hex) ? 0 : -1);
+ hex2stdout(buff, len, (1 == do_hex) ? 0 : -1);
return;
}
if (len < 4) {
@@ -1433,8 +1433,6 @@ decode_dev_const_vpd(unsigned char * buff, int len, int do_hex)
len -= 4;
bp = buff + 4;
for (k = 0, j = 0; k < len; k += bump, bp += bump, ++j) {
-
-
printf(" Constituent descriptor %d:\n", j + 1);
if ((k + 36) > len) {
pr2serr("%s, short descriptor length=36, left=%d\n", dcp,
@@ -1456,7 +1454,7 @@ decode_dev_const_vpd(unsigned char * buff, int len, int do_hex)
}
if (cd_len > 0) {
printf(" Constituent specific descriptor list (in hex):\n");
- dStrHex((const char *)(bp + 36), cd_len, 1);
+ hex2stdout(bp + 36, cd_len, 1);
}
}
}
@@ -1483,7 +1481,7 @@ decode_power_consumption_vpd(unsigned char * buff, int len, int do_hex)
const char * pcp = "Power consumption VPD page";
if ((1 == do_hex) || (do_hex > 2)) {
- dStrHex((const char *)buff, len, (1 == do_hex) ? 1 : -1);
+ hex2stdout(buff, len, (1 == do_hex) ? 1 : -1);
return;
}
if (len < 4) {
@@ -1500,7 +1498,7 @@ decode_power_consumption_vpd(unsigned char * buff, int len, int do_hex)
return;
}
if (do_hex > 1)
- dStrHex((const char *)bp, 4, 1);
+ hex2stdout(bp, 4, 1);
else {
value = sg_get_unaligned_be16(bp + 2);
printf(" Power consumption identifier: 0x%x", bp[0]);
@@ -1694,7 +1692,7 @@ decode_3party_copy_vpd(unsigned char * buff, int len, int do_hex, int pdt,
return;
}
if (3 == do_hex) {
- dStrHex((const char *)buff, len, -1);
+ hex2stdout(buff, len, -1);
return;
}
len -= 4;
@@ -1714,9 +1712,9 @@ decode_3party_copy_vpd(unsigned char * buff, int len, int do_hex, int pdt,
if (0 == desc_len)
continue;
if (2 == do_hex)
- dStrHex((const char *)bp + 4, desc_len, 1);
+ hex2stdout(bp + 4, desc_len, 1);
else if (do_hex > 2)
- dStrHex((const char *)bp, bump, 1);
+ hex2stdout(bp, bump, 1);
else {
int csll;
@@ -1872,7 +1870,7 @@ decode_3party_copy_vpd(unsigned char * buff, int len, int do_hex, int pdt,
break;
default:
pr2serr("Unexpected type=%d\n", desc_type);
- dStrHexErr((const char *)bp, bump, 1);
+ hex2stderr(bp, bump, 1);
break;
}
}
@@ -1887,7 +1885,7 @@ decode_proto_lu_vpd(unsigned char * buff, int len, int do_hex)
unsigned char * bp;
if ((1 == do_hex) || (do_hex > 2)) {
- dStrHex((const char *)buff, len, (1 == do_hex) ? 1 : -1);
+ hex2stdout(buff, len, (1 == do_hex) ? 1 : -1);
return;
}
if (len < 4) {
@@ -1911,9 +1909,9 @@ decode_proto_lu_vpd(unsigned char * buff, int len, int do_hex)
if (0 == desc_len)
continue;
if (2 == do_hex)
- dStrHex((const char *)bp + 8, desc_len, 1);
+ hex2stdout(bp + 8, desc_len, 1);
else if (do_hex > 2)
- dStrHex((const char *)bp, bump, 1);
+ hex2stdout(bp, bump, 1);
else {
switch (proto) {
case TPROTO_SAS:
@@ -1922,7 +1920,7 @@ decode_proto_lu_vpd(unsigned char * buff, int len, int do_hex)
break;
default:
pr2serr("Unexpected proto=%d\n", proto);
- dStrHexErr((const char *)bp, bump, 1);
+ hex2stderr(bp, bump, 1);
break;
}
}
@@ -1938,7 +1936,7 @@ decode_proto_port_vpd(unsigned char * buff, int len, int do_hex)
unsigned char * pidp;
if ((1 == do_hex) || (do_hex > 2)) {
- dStrHex((const char *)buff, len, (1 == do_hex) ? 1 : -1);
+ hex2stdout(buff, len, (1 == do_hex) ? 1 : -1);
return;
}
if (len < 4) {
@@ -1962,9 +1960,9 @@ decode_proto_port_vpd(unsigned char * buff, int len, int do_hex)
if (0 == desc_len)
continue;
if (2 == do_hex)
- dStrHex((const char *)bp + 8, desc_len, 1);
+ hex2stdout(bp + 8, desc_len, 1);
else if (do_hex > 2)
- dStrHex((const char *)bp, bump, 1);
+ hex2stdout(bp, bump, 1);
else {
switch (proto) {
case TPROTO_SAS: /* page added in spl3r02 */
@@ -1977,7 +1975,7 @@ decode_proto_port_vpd(unsigned char * buff, int len, int do_hex)
break;
default:
pr2serr("Unexpected proto=%d\n", proto);
- dStrHexErr((const char *)bp, bump, 1);
+ hex2stderr(bp, bump, 1);
break;
}
}
@@ -1996,7 +1994,7 @@ decode_feature_sets_vpd(unsigned char * buff, int len,
char b[64];
if ((1 == op->do_hex) || (op->do_hex > 2)) {
- dStrHex((const char *)buff, len, (1 == op->do_hex) ? 1 : -1);
+ hex2stdout(buff, len, (1 == op->do_hex) ? 1 : -1);
return;
}
if (len < 4) {
@@ -2014,9 +2012,9 @@ decode_feature_sets_vpd(unsigned char * buff, int len,
return;
}
if (2 == op->do_hex)
- dStrHex((const char *)bp + 8, 2, 1);
+ hex2stdout(bp + 8, 2, 1);
else if (op->do_hex > 2)
- dStrHex((const char *)bp, 2, 1);
+ hex2stdout(bp, 2, 1);
else {
printf(" %s", sg_get_sfs_str(sf_code, -2, sizeof(b), b,
&found, op->verbose));
@@ -2043,7 +2041,7 @@ decode_b0_vpd(unsigned char * buff, int len, int do_hex, int pdt)
bool ugavalid;
if (do_hex) {
- dStrHex((const char *)buff, len, (1 == do_hex) ? 0 : -1);
+ hex2stdout(buff, len, (1 == do_hex) ? 0 : -1);
return;
}
switch (pdt) {
@@ -2168,7 +2166,7 @@ decode_b0_vpd(unsigned char * buff, int len, int do_hex, int pdt)
case PDT_OSD:
default:
pr2serr(" Unable to decode pdt=0x%x, in hex:\n", pdt);
- dStrHexErr((const char *)buff, len, 0);
+ hex2stderr(buff, len, 0);
break;
}
}
@@ -2195,7 +2193,7 @@ decode_b1_vpd(unsigned char * buff, int len, int do_hex, int pdt)
unsigned int u, k;
if (do_hex) {
- dStrHex((const char *)buff, len, (1 == do_hex) ? 0 : -1);
+ hex2stdout(buff, len, (1 == do_hex) ? 0 : -1);
return;
}
switch (pdt) {
@@ -2279,7 +2277,7 @@ decode_b1_vpd(unsigned char * buff, int len, int do_hex, int pdt)
break;
default:
pr2serr(" Unable to decode pdt=0x%x, in hex:\n", pdt);
- dStrHexErr((const char *)buff, len, 0);
+ hex2stderr(buff, len, 0);
break;
}
}
@@ -2457,7 +2455,7 @@ decode_lb_protection_vpd(unsigned char * buff, int len, int do_hex)
unsigned char * bp;
if ((1 == do_hex) || (do_hex > 2)) {
- dStrHex((const char *)buff, len, (1 == do_hex) ? 0 : -1);
+ hex2stdout(buff, len, (1 == do_hex) ? 0 : -1);
return;
}
if (len < 8) {
@@ -2511,7 +2509,7 @@ decode_b2_vpd(unsigned char * buff, int len, int pdt,
const struct opts_t * op)
{
if (op->do_hex) {
- dStrHex((const char *)buff, len, (1 == op->do_hex) ? 0 : -1);
+ hex2stdout(buff, len, (1 == op->do_hex) ? 0 : -1);
return;
}
switch (pdt) {
@@ -2523,7 +2521,7 @@ decode_b2_vpd(unsigned char * buff, int len, int pdt,
break;
default:
pr2serr(" Unable to decode pdt=0x%x, in hex:\n", pdt);
- dStrHexErr((const char *)buff, len, 0);
+ hex2stderr(buff, len, 0);
break;
}
}
@@ -2537,7 +2535,7 @@ decode_b3_vpd(unsigned char * b, int len, int do_hex, int pdt)
unsigned int u;
if (do_hex) {
- dStrHex((const char *)b, len, (1 == do_hex) ? 0 : -1);
+ hex2stdout(b, len, (1 == do_hex) ? 0 : -1);
return;
}
switch (pdt) {
@@ -2565,7 +2563,7 @@ decode_b3_vpd(unsigned char * b, int len, int do_hex, int pdt)
break;
default:
pr2serr(" Unable to decode pdt=0x%x, in hex:\n", pdt);
- dStrHexErr((const char *)b, len, 0);
+ hex2stderr(b, len, 0);
break;
}
}
@@ -2578,7 +2576,7 @@ decode_b4_vpd(unsigned char * b, int len, int do_hex, int pdt)
int k;
if (do_hex) {
- dStrHex((const char *)b, len, (1 == do_hex) ? 0 : -1);
+ hex2stdout(b, len, (1 == do_hex) ? 0 : -1);
return;
}
switch (pdt) {
@@ -2593,7 +2591,7 @@ decode_b4_vpd(unsigned char * b, int len, int do_hex, int pdt)
break;
default:
pr2serr(" Unable to decode pdt=0x%x, in hex:\n", pdt);
- dStrHexErr((const char *)b, len, 0);
+ hex2stderr(b, len, 0);
break;
}
}
@@ -2603,7 +2601,7 @@ static void
decode_b5_vpd(unsigned char * b, int len, int do_hex, int pdt)
{
if (do_hex) {
- dStrHex((const char *)b, len, (1 == do_hex) ? 0 : -1);
+ hex2stdout(b, len, (1 == do_hex) ? 0 : -1);
return;
}
switch (pdt) {
@@ -2615,7 +2613,7 @@ decode_b5_vpd(unsigned char * b, int len, int do_hex, int pdt)
break;
default:
pr2serr(" Unable to decode pdt=0x%x, in hex:\n", pdt);
- dStrHexErr((const char *)b, len, 0);
+ hex2stderr(b, len, 0);
break;
}
}
@@ -2627,7 +2625,7 @@ decode_zbdc_vpd(unsigned char * b, int len, int do_hex)
uint32_t u;
if (do_hex) {
- dStrHex((const char *)b, len, (1 == do_hex) ? 0 : -1);
+ hex2stdout(b, len, (1 == do_hex) ? 0 : -1);
return;
}
if (len < 64) {
@@ -2664,7 +2662,7 @@ decode_b7_vpd(unsigned char * buff, int len, int do_hex, int pdt)
unsigned int u;
if (do_hex) {
- dStrHex((const char *)buff, len, (1 == do_hex) ? 0 : -1);
+ hex2stdout(buff, len, (1 == do_hex) ? 0 : -1);
return;
}
switch (pdt) {
@@ -2707,7 +2705,7 @@ decode_b7_vpd(unsigned char * buff, int len, int do_hex, int pdt)
break;
default:
pr2serr(" Unable to decode pdt=0x%x, in hex:\n", pdt);
- dStrHexErr((const char *)buff, len, 0);
+ hex2stderr(buff, len, 0);
break;
}
}
@@ -2736,14 +2734,16 @@ svpd_unable_to_decode(int sg_fd, struct opts_t * op, int subvalue, int off)
op->verbose, &len);
if (0 == res) {
if (op->do_raw)
- dStrRaw((const char *)rp, len);
+ dStrRaw(rp, len);
else {
- if (op->do_hex > 1)
- dStrHex((const char *)rp, len, -1);
+ if ((2 == op->do_hex) || (3 == op->do_hex))
+ hex2stdout(rp, len, -1);
else if (VPD_ASCII_OP_DEF == op->vpd_pn)
- dStrHex((const char *)rp, len, 0);
+ hex2stdout(rp, len, 0);
+ else if (1 == op->do_hex)
+ hex2stdout(rp, len, (op->do_long ? 0 : 1));
else
- dStrHex((const char *)rp, len, (op->do_long ? 0 : 1));
+ hex2stdout(rp, len, 0);
}
return 0;
} else {
@@ -2756,7 +2756,7 @@ svpd_unable_to_decode(int sg_fd, struct opts_t * op, int subvalue, int off)
}
/* Returns 0 if successful. If don't know how to decode, returns
- * SG_LIB_SYNTAX_ERROR else see sg_ll_inquiry(). */
+ * SG_LIB_CAT_OTHER else see sg_ll_inquiry(). */
static int
svpd_decode_t10(int sg_fd, struct opts_t * op, int subvalue, int off)
{
@@ -2817,12 +2817,11 @@ svpd_decode_t10(int sg_fd, struct opts_t * op, int subvalue, int off)
if (0 == res) {
alloc_len -= resid;
if (op->do_raw)
- dStrRaw((const char *)rp, alloc_len);
+ dStrRaw(rp, alloc_len);
else if (op->do_hex) {
if (! op->do_quiet && (op->do_hex < 3))
printf("Standard Inquiry reponse:\n");
- dStrHex((const char *)rp, alloc_len,
- (1 == op->do_hex) ? 0 : -1);
+ hex2stdout(rp, alloc_len, (1 == op->do_hex) ? 0 : -1);
} else
decode_std_inq(rp, alloc_len, vb);
return 0;
@@ -2834,9 +2833,9 @@ svpd_decode_t10(int sg_fd, struct opts_t * op, int subvalue, int off)
res = vpd_fetch_page_from_dev(sg_fd, rp, pn, op->maxlen, vb, &len);
if (0 == res) {
if (op->do_raw)
- dStrRaw((const char *)rp, len);
+ dStrRaw(rp, len);
else if (op->do_hex)
- dStrHex((const char *)rp, len, (1 == op->do_hex) ? 0 : -1);
+ hex2stdout(rp, len, (1 == op->do_hex) ? 0 : -1);
else {
pdt = rp[0] & 0x1f;
if (vb || long_notquiet)
@@ -2878,9 +2877,9 @@ svpd_decode_t10(int sg_fd, struct opts_t * op, int subvalue, int off)
res = vpd_fetch_page_from_dev(sg_fd, rp, pn, op->maxlen, vb, &len);
if (0 == res) {
if (op->do_raw)
- dStrRaw((const char *)rp, len);
+ dStrRaw(rp, len);
else if (op->do_hex)
- dStrHex((const char *)rp, len, (1 == op->do_hex) ? 0 : -1);
+ hex2stdout(rp, len, (1 == op->do_hex) ? 0 : -1);
else {
pdt = rp[0] & 0x1f;
if (vb || long_notquiet)
@@ -2903,9 +2902,9 @@ svpd_decode_t10(int sg_fd, struct opts_t * op, int subvalue, int off)
res = vpd_fetch_page_from_dev(sg_fd, rp, pn, op->maxlen, vb, &len);
if (0 == res) {
if (op->do_raw)
- dStrRaw((const char *)rp, len);
+ dStrRaw(rp, len);
else if (op->do_hex)
- dStrHex((const char *)rp, len, (1 == op->do_hex) ? 0 : -1);
+ hex2stdout(rp, len, (1 == op->do_hex) ? 0 : -1);
else {
pdt = rp[0] & 0x1f;
if (vb || long_notquiet)
@@ -2923,7 +2922,7 @@ svpd_decode_t10(int sg_fd, struct opts_t * op, int subvalue, int off)
res = vpd_fetch_page_from_dev(sg_fd, rp, pn, op->maxlen, vb, &len);
if (0 == res) {
if (op->do_raw)
- dStrRaw((const char *)rp, len);
+ dStrRaw(rp, len);
else {
pdt = rp[0] & 0x1f;
if (vb || long_notquiet)
@@ -2941,7 +2940,7 @@ svpd_decode_t10(int sg_fd, struct opts_t * op, int subvalue, int off)
res = vpd_fetch_page_from_dev(sg_fd, rp, pn, op->maxlen, vb, &len);
if (0 == res) {
if (op->do_raw)
- dStrRaw((const char *)rp, len);
+ dStrRaw(rp, len);
else
decode_net_man_vpd(rp, len, op->do_hex);
return 0;
@@ -2953,7 +2952,7 @@ svpd_decode_t10(int sg_fd, struct opts_t * op, int subvalue, int off)
res = vpd_fetch_page_from_dev(sg_fd, rp, pn, op->maxlen, vb, &len);
if (0 == res) {
if (op->do_raw)
- dStrRaw((const char *)rp, len);
+ dStrRaw(rp, len);
else {
bool protect = false;
struct sg_simple_inquiry_resp sir;
@@ -2983,7 +2982,7 @@ svpd_decode_t10(int sg_fd, struct opts_t * op, int subvalue, int off)
res = vpd_fetch_page_from_dev(sg_fd, rp, pn, op->maxlen, vb, &len);
if (0 == res) {
if (op->do_raw)
- dStrRaw((const char *)rp, len);
+ dStrRaw(rp, len);
else {
pdt = rp[0] & 0x1f;
if (vb || long_notquiet)
@@ -3001,7 +3000,7 @@ svpd_decode_t10(int sg_fd, struct opts_t * op, int subvalue, int off)
res = vpd_fetch_page_from_dev(sg_fd, rp, pn, op->maxlen, vb, &len);
if (0 == res) {
if (op->do_raw)
- dStrRaw((const char *)rp, len);
+ dStrRaw(rp, len);
else {
pdt = rp[0] & 0x1f;
if (vb || long_notquiet)
@@ -3028,7 +3027,7 @@ svpd_decode_t10(int sg_fd, struct opts_t * op, int subvalue, int off)
sg_is_big_endian());
}
else if (op->do_raw)
- dStrRaw((const char *)rp, len);
+ dStrRaw(rp, len);
else {
pdt = rp[0] & 0x1f;
if (vb || long_notquiet)
@@ -3046,7 +3045,7 @@ svpd_decode_t10(int sg_fd, struct opts_t * op, int subvalue, int off)
res = vpd_fetch_page_from_dev(sg_fd, rp, pn, op->maxlen, vb, &len);
if (0 == res) {
if (op->do_raw)
- dStrRaw((const char *)rp, len);
+ dStrRaw(rp, len);
else {
pdt = rp[0] & 0x1f;
if (vb || long_notquiet)
@@ -3064,7 +3063,7 @@ svpd_decode_t10(int sg_fd, struct opts_t * op, int subvalue, int off)
res = vpd_fetch_page_from_dev(sg_fd, rp, pn, op->maxlen, vb, &len);
if (0 == res) {
if (op->do_raw)
- dStrRaw((const char *)rp, len);
+ dStrRaw(rp, len);
else
decode_dev_const_vpd(rp, len, op->do_hex);
return 0;
@@ -3076,7 +3075,7 @@ svpd_decode_t10(int sg_fd, struct opts_t * op, int subvalue, int off)
res = vpd_fetch_page_from_dev(sg_fd, rp, pn, op->maxlen, vb, &len);
if (0 == res) {
if (op->do_raw)
- dStrRaw((const char *)rp, len);
+ dStrRaw(rp, len);
else {
pdt = rp[0] & 0x1f;
if (vb || long_notquiet)
@@ -3094,9 +3093,9 @@ svpd_decode_t10(int sg_fd, struct opts_t * op, int subvalue, int off)
res = vpd_fetch_page_from_dev(sg_fd, rp, pn, op->maxlen, vb, &len);
if (0 == res) {
if (op->do_raw)
- dStrRaw((const char *)rp, len);
+ dStrRaw(rp, len);
else if (1 == op->do_hex)
- dStrHex((const char *)rp, len, 0);
+ hex2stdout(rp, len, 0);
else {
pdt = rp[0] & 0x1f;
if (vb || long_notquiet)
@@ -3114,7 +3113,7 @@ svpd_decode_t10(int sg_fd, struct opts_t * op, int subvalue, int off)
res = vpd_fetch_page_from_dev(sg_fd, rp, pn, op->maxlen, vb, &len);
if (0 == res) {
if (op->do_raw)
- dStrRaw((const char *)rp, len);
+ dStrRaw(rp, len);
else {
pdt = rsp_buff[0] & 0x1f;
if (vb || long_notquiet)
@@ -3132,7 +3131,7 @@ svpd_decode_t10(int sg_fd, struct opts_t * op, int subvalue, int off)
res = vpd_fetch_page_from_dev(sg_fd, rp, pn, op->maxlen, vb, &len);
if (0 == res) {
if (op->do_raw)
- dStrRaw((const char *)rp, len);
+ dStrRaw(rp, len);
else {
pdt = rp[0] & 0x1f;
if (vb || long_notquiet)
@@ -3150,7 +3149,7 @@ svpd_decode_t10(int sg_fd, struct opts_t * op, int subvalue, int off)
res = vpd_fetch_page_from_dev(sg_fd, rp, pn, op->maxlen, vb, &len);
if (0 == res) {
if (op->do_raw)
- dStrRaw((const char *)rp, len);
+ dStrRaw(rp, len);
else {
pdt = rp[0] & 0x1f;
if (vb || long_notquiet)
@@ -3184,7 +3183,7 @@ svpd_decode_t10(int sg_fd, struct opts_t * op, int subvalue, int off)
}
}
if (op->do_raw)
- dStrRaw((const char *)rp, len);
+ dStrRaw(rp, len);
else {
pdt = rp[0] & 0x1f;
if (vb || long_notquiet)
@@ -3223,7 +3222,7 @@ svpd_decode_t10(int sg_fd, struct opts_t * op, int subvalue, int off)
}
}
if (op->do_raw)
- dStrRaw((const char *)rp, len);
+ dStrRaw(rp, len);
else {
if (vb || long_notquiet)
printf(" [PQual=%d Peripheral device type: %s]\n",
@@ -3253,7 +3252,7 @@ svpd_decode_t10(int sg_fd, struct opts_t * op, int subvalue, int off)
}
}
if (op->do_raw)
- dStrRaw((const char *)rp, len);
+ dStrRaw(rp, len);
else {
if (vb || long_notquiet)
printf(" [PQual=%d Peripheral device type: %s]\n",
@@ -3284,7 +3283,7 @@ svpd_decode_t10(int sg_fd, struct opts_t * op, int subvalue, int off)
}
}
if (op->do_raw)
- dStrRaw((const char *)rp, len);
+ dStrRaw(rp, len);
else {
if (vb || long_notquiet)
printf(" [PQual=%d Peripheral device type: %s]\n",
@@ -3315,7 +3314,7 @@ svpd_decode_t10(int sg_fd, struct opts_t * op, int subvalue, int off)
}
}
if (op->do_raw)
- dStrRaw((const char *)rp, len);
+ dStrRaw(rp, len);
else {
if (vb || long_notquiet)
printf(" [PQual=%d Peripheral device type: %s]\n",
@@ -3346,7 +3345,7 @@ svpd_decode_t10(int sg_fd, struct opts_t * op, int subvalue, int off)
}
}
if (op->do_raw)
- dStrRaw((const char *)rp, len);
+ dStrRaw(rp, len);
else {
if (vb || long_notquiet)
printf(" [PQual=%d Peripheral device type: %s]\n",
@@ -3374,7 +3373,7 @@ svpd_decode_t10(int sg_fd, struct opts_t * op, int subvalue, int off)
}
}
if (op->do_raw)
- dStrRaw((const char *)rp, len);
+ dStrRaw(rp, len);
else {
if (vb || long_notquiet)
printf(" [PQual=%d Peripheral device type: %s]\n",
@@ -3401,7 +3400,7 @@ svpd_decode_t10(int sg_fd, struct opts_t * op, int subvalue, int off)
}
}
if (op->do_raw)
- dStrRaw((const char *)rp, len);
+ dStrRaw(rp, len);
else {
pdt = rp[0] & 0x1f;
if (vb || long_notquiet)
@@ -3415,7 +3414,7 @@ svpd_decode_t10(int sg_fd, struct opts_t * op, int subvalue, int off)
printf("VPD page=0xb7\n");
break;
default:
- return SG_LIB_SYNTAX_ERROR;
+ return SG_LIB_CAT_OTHER;
}
return res;
}
@@ -3461,9 +3460,9 @@ svpd_decode_all(int sg_fd, struct opts_t * op)
printf("[0x%x] ", pn);
res = svpd_decode_t10(sg_fd, op, 0, 0);
- if (SG_LIB_SYNTAX_ERROR == res) {
+ if (SG_LIB_CAT_OTHER == res) {
res = svpd_decode_vendor(sg_fd, op, 0);
- if (SG_LIB_SYNTAX_ERROR == res)
+ if (SG_LIB_CAT_OTHER == res)
res = svpd_unable_to_decode(sg_fd, op, 0, 0);
}
if (SG_LIB_CAT_ABORTED_COMMAND == res)
@@ -3510,9 +3509,9 @@ svpd_decode_all(int sg_fd, struct opts_t * op)
printf("[0x%x] ", pn);
res = svpd_decode_t10(-1, op, 0, off);
- if (SG_LIB_SYNTAX_ERROR == res) {
+ if (SG_LIB_CAT_OTHER == res) {
res = svpd_decode_vendor(-1, op, off);
- if (SG_LIB_SYNTAX_ERROR == res)
+ if (SG_LIB_CAT_OTHER == res)
res = svpd_unable_to_decode(-1, op, 0, off);
}
}
@@ -3765,7 +3764,7 @@ main(int argc, char * argv[])
if (op->verbose > 2)
pr2serr("Read %d bytes of user supplied data\n", inhex_len);
if (op->verbose > 3)
- dStrHexErr((const char *)rsp_buff, inhex_len, 0);
+ hex2stderr(rsp_buff, inhex_len, 0);
op->do_raw = 0; /* don't want raw on output with --inhex= */
if ((NULL == op->page_str) && (! op->do_all)) {
/* may be able to deduce VPD page */
@@ -3825,9 +3824,9 @@ main(int argc, char * argv[])
res = svpd_decode_all(-1, op);
else {
res = svpd_decode_t10(-1, op, subvalue, 0);
- if (SG_LIB_SYNTAX_ERROR == res) {
+ if (SG_LIB_CAT_OTHER == res) {
res = svpd_decode_vendor(-1, op, 0);
- if (SG_LIB_SYNTAX_ERROR == res)
+ if (SG_LIB_CAT_OTHER == res)
res = svpd_unable_to_decode(-1, op, subvalue, 0);
}
}
@@ -3847,10 +3846,10 @@ main(int argc, char * argv[])
memset(rsp_buff, 0, sizeof(rsp_buff));
res = svpd_decode_t10(sg_fd, op, subvalue, 0);
- if (SG_LIB_SYNTAX_ERROR == res) {
+ if (SG_LIB_CAT_OTHER == res) {
res = svpd_decode_vendor(sg_fd, op, 0);
- if (SG_LIB_SYNTAX_ERROR == res)
- res = svpd_unable_to_decode(sg_fd, op, subvalue, 0);
+ if (SG_LIB_CAT_OTHER == res)
+ res = svpd_unable_to_decode(sg_fd, op, subvalue, 0);
}
if (SG_LIB_CAT_ABORTED_COMMAND == res)
pr2serr("fetching VPD page failed, aborted command\n");
diff --git a/src/sg_vpd_vendor.c b/src/sg_vpd_vendor.c
index 0752db77..e567d131 100644
--- a/src/sg_vpd_vendor.c
+++ b/src/sg_vpd_vendor.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006-2017 Douglas Gilbert.
+ * Copyright (c) 2006-2018 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.
@@ -150,21 +150,21 @@ static struct svpd_vp_name_t vp_arr[] = {
static struct svpd_values_name_t vendor_vpd_pg[] = {
{VPD_V_ACI_LTO, VPD_VP_HP_LTO, 1, "aci", "ACI revision level (HP LTO)"},
{VPD_V_DATC_SEA, VPD_VP_SEAGATE, 0, "datc", "Date code (Seagate)"},
- {VPD_V_DCRL_LTO, VPD_VP_IBM_LTO, 1, "dcrl" , "Drive component revision "
+ {VPD_V_DCRL_LTO, VPD_VP_IBM_LTO, 1, "dcrl", "Drive component revision "
"levels (IBM LTO)"},
{VPD_V_FVER_DDS, VPD_VP_DDS, 1, "ddsver", "Firmware revision (DDS)"},
{VPD_V_DEV_BEH_SEA, VPD_VP_SEAGATE, 0, "devb", "Device behavior "
"(Seagate)"},
- {VPD_V_DSN_LTO, VPD_VP_IBM_LTO, 1, "dsn" , "Drive serial numbers (IBM "
+ {VPD_V_DSN_LTO, VPD_VP_IBM_LTO, 1, "dsn", "Drive serial numbers (IBM "
"LTO)"},
- {VPD_V_DUCD_LTO, VPD_VP_IBM_LTO, 1, "ducd" , "Device unique "
+ {VPD_V_DUCD_LTO, VPD_VP_IBM_LTO, 1, "ducd", "Device unique "
"configuration data (IBM LTO)"},
{VPD_V_EDID_RDAC, VPD_VP_RDAC, 0, "edid", "Extended device "
"identification (RDAC)"},
{VPD_V_FEAT_RDAC, VPD_VP_RDAC, 0, "prm4", "Feature Parameters (RDAC)"},
{VPD_V_FIRM_SEA, VPD_VP_SEAGATE, 0, "firm", "Firmware numbers "
"(Seagate)"},
- {VPD_V_FVER_LTO, VPD_VP_HP_LTO, 0, "frl" , "Firmware revision level "
+ {VPD_V_FVER_LTO, VPD_VP_HP_LTO, 0, "frl", "Firmware revision level "
"(HP LTO)"},
{VPD_V_FVER_RDAC, VPD_VP_RDAC, 0, "fwr4", "Firmware version (RDAC)"},
{VPD_V_HEAD_LTO, VPD_VP_HP_LTO, 1, "head", "Head Assy revision level "
@@ -177,7 +177,7 @@ static struct svpd_values_name_t vendor_vpd_pg[] = {
{VPD_V_JUMP_SEA, VPD_VP_SEAGATE, 0, "jump", "Jump setting (Seagate)"},
{VPD_V_MECH_LTO, VPD_VP_HP_LTO, 1, "mech", "Mechanism revision level "
"(HP LTO)"},
- {VPD_V_MPDS_LTO, VPD_VP_IBM_LTO, 1, "mpds" , "Mode parameter default "
+ {VPD_V_MPDS_LTO, VPD_VP_IBM_LTO, 1, "mpds", "Mode parameter default "
"settings (IBM LTO)"},
{VPD_V_PCA_LTO, VPD_VP_HP_LTO, 1, "pca", "PCA revision level (HP LTO)"},
{VPD_V_RVSI_RDAC, VPD_VP_RDAC, 0, "rvsi", "Replicated volume source "
@@ -358,11 +358,11 @@ svpd_count_vendor_vpds(int vpd_pn, int vend_prod_num)
}
static void
-dStrRaw(const char* str, int len)
+dStrRaw(const uint8_t * str, int len)
{
int k;
- for (k = 0 ; k < len; ++k)
+ for (k = 0; k < len; ++k)
printf("%c", str[k]);
}
@@ -554,7 +554,7 @@ decode_upr_vpd_c0_emc(unsigned char * buff, int len)
printf("%02x", buff[10 + k]);
printf("\n");
printf(" Array Serial Number: ");
- dStrRaw((const char *)&buff[50], buff[49]);
+ dStrRaw(&buff[50], buff[49]);
printf("\n");
printf(" LUN State: ");
@@ -1297,7 +1297,7 @@ decode_ibm_lto_dsn(unsigned char * buff, int len)
printf(" Reported serial number: %.12s\n", buff + 16);
}
-/* Returns 0 if successful, see sg_ll_inquiry() plus SG_LIB_SYNTAX_ERROR for
+/* Returns 0 if successful, see sg_ll_inquiry() plus SG_LIB_CAT_OTHER for
unsupported page */
int
svpd_decode_vendor(int sg_fd, struct opts_t * op, int off)
@@ -1321,7 +1321,7 @@ svpd_decode_vendor(int sg_fd, struct opts_t * op, int off)
case 0xd0:
break;
default: /* not known so return prior to fetching page */
- return SG_LIB_SYNTAX_ERROR;
+ return SG_LIB_CAT_OTHER;
}
rp = rsp_buff + off;
if (sg_fd >= 0) {
@@ -1340,10 +1340,9 @@ svpd_decode_vendor(int sg_fd, struct opts_t * op, int off)
if ((! op->do_raw) && (! op->do_quiet) && (op->do_hex < 2))
printf("%s VPD Page:\n", name);
if (op->do_raw)
- dStrRaw((const char *)rp, len);
+ dStrRaw(rp, len);
else if (op->do_hex)
- dStrHex((const char *)rp, len,
- ((1 == op->do_hex) ? 0 : -1));
+ hex2stdout(rp, len, ((1 == op->do_hex) ? 0 : -1));
else {
switch(op->vpd_pn) {
case 0xc0:
@@ -1362,7 +1361,7 @@ svpd_decode_vendor(int sg_fd, struct opts_t * op, int off)
else if (VPD_VP_HP_LTO == op->vend_prod_num)
decode_hp_lto_vpd_cx(rp, len, op->vpd_pn);
else
- dStrHex((const char *)rp, len, 0);
+ hex2stdout(rp, len, 0);
break;
case 0xc1:
if (VPD_VP_SEAGATE == op->vend_prod_num)
@@ -1374,7 +1373,7 @@ svpd_decode_vendor(int sg_fd, struct opts_t * op, int off)
else if (VPD_VP_HP_LTO == op->vend_prod_num)
decode_hp_lto_vpd_cx(rp, len, op->vpd_pn);
else
- dStrHex((const char *)rp, len, 0);
+ hex2stdout(rp, len, 0);
break;
case 0xc2:
if (VPD_VP_RDAC == op->vend_prod_num)
@@ -1382,7 +1381,7 @@ svpd_decode_vendor(int sg_fd, struct opts_t * op, int off)
else if (VPD_VP_HP_LTO == op->vend_prod_num)
decode_hp_lto_vpd_cx(rp, len, op->vpd_pn);
else
- dStrHex((const char *)rp, len, 0);
+ hex2stdout(rp, len, 0);
break;
case 0xc3:
if (VPD_VP_SEAGATE == op->vend_prod_num)
@@ -1392,7 +1391,7 @@ svpd_decode_vendor(int sg_fd, struct opts_t * op, int off)
else if (VPD_VP_HP_LTO == op->vend_prod_num)
decode_hp_lto_vpd_cx(rp, len, op->vpd_pn);
else
- dStrHex((const char *)rp, len, 0);
+ hex2stdout(rp, len, 0);
break;
case 0xc4:
if (VPD_VP_RDAC == op->vend_prod_num)
@@ -1400,42 +1399,42 @@ svpd_decode_vendor(int sg_fd, struct opts_t * op, int off)
else if (VPD_VP_HP_LTO == op->vend_prod_num)
decode_hp_lto_vpd_cx(rp, len, op->vpd_pn);
else
- dStrHex((const char *)rp, len, 0);
+ hex2stdout(rp, len, 0);
break;
case 0xc5:
if (VPD_VP_HP_LTO == op->vend_prod_num)
decode_hp_lto_vpd_cx(rp, len, op->vpd_pn);
else
- dStrHex((const char *)rp, len, 0);
+ hex2stdout(rp, len, 0);
break;
case 0xc8:
if (VPD_VP_RDAC == op->vend_prod_num)
decode_rdac_vpd_c8(rp, len);
else
- dStrHex((const char *)rp, len, 0);
+ hex2stdout(rp, len, 0);
break;
case 0xc9:
if (VPD_VP_RDAC == op->vend_prod_num)
decode_rdac_vpd_c9(rp, len);
else
- dStrHex((const char *)rp, len, 0);
+ hex2stdout(rp, len, 0);
break;
case 0xca:
if (VPD_VP_RDAC == op->vend_prod_num)
decode_rdac_vpd_ca(rp, len);
else
- dStrHex((const char *)rp, len, 0);
+ hex2stdout(rp, len, 0);
break;
case 0xd0:
if (VPD_VP_RDAC == op->vend_prod_num)
decode_rdac_vpd_d0(rp, len);
else
- dStrHex((const char *)rp, len, 0);
+ hex2stdout(rp, len, 0);
break;
default:
pr2serr("%s: logic error, should know can't decode "
"pn=0x%x\n", __func__, op->vpd_pn);
- return SG_LIB_SYNTAX_ERROR;
+ return SG_LIB_CAT_OTHER;
}
return 0;
}
diff --git a/src/sg_wr_mode.c b/src/sg_wr_mode.c
index 6c8aea45..60ad453d 100644
--- a/src/sg_wr_mode.c
+++ b/src/sg_wr_mode.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2004-2017 Douglas Gilbert.
+ * Copyright (c) 2004-2018 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.
@@ -18,6 +18,7 @@
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
+
#include "sg_lib.h"
#include "sg_cmds_basic.h"
#include "sg_unaligned.h"
@@ -29,7 +30,7 @@
* mode page on the given device.
*/
-static const char * version_str = "1.20 20171030";
+static const char * version_str = "1.21 20180119";
#define ME "sg_wr_mode: "
@@ -555,14 +556,14 @@ int main(int argc, char * argv[])
} else {
printf(">>> No contents given, so show current mode page data:\n");
printf(" header:\n");
- dStrHex((const char *)ref_md, hdr_len, -1);
+ hex2stdout(ref_md, hdr_len, -1);
if (bd_len) {
printf(" block descriptor(s):\n");
- dStrHex((const char *)(ref_md + hdr_len), bd_len, -1);
+ hex2stdout(ref_md + hdr_len, bd_len, -1);
} else
printf(" << no block descriptors >>\n");
printf(" mode page:\n");
- dStrHex((const char *)(ref_md + off), md_len - off, -1);
+ hex2stdout(ref_md + off, md_len - off, -1);
}
err_out:
res = sg_cmds_close_device(sg_fd);
diff --git a/src/sg_write_same.c b/src/sg_write_same.c
index d382cb53..73bd4d9d 100644
--- a/src/sg_write_same.c
+++ b/src/sg_write_same.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2009-2017 Douglas Gilbert.
+ * Copyright (c) 2009-2018 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.
@@ -30,7 +30,7 @@
#include "sg_unaligned.h"
#include "sg_pr2serr.h"
-static const char * version_str = "1.18 20171025";
+static const char * version_str = "1.19 20180118";
#define ME "sg_write_same: "
@@ -253,7 +253,7 @@ do_write_same(int sg_fd, const struct opts_t * op, const void * dataoutp,
}
if ((op->verbose > 3) && (op->xfer_len > 0)) {
pr2serr(" Data-out buffer contents:\n");
- dStrHexErr((const char *)dataoutp, op->xfer_len, 1);
+ hex2stderr(dataoutp, op->xfer_len, 1);
}
ptvp = construct_scsi_pt_obj();
if (NULL == ptvp) {
@@ -507,7 +507,7 @@ main(int argc, char * argv[])
}
if (0 == res) {
if (vb > 3)
- dStrHexErr((const char *)resp_buff, RCAP16_RESP_LEN, 1);
+ hex2stderr(resp_buff, RCAP16_RESP_LEN, 1);
block_size = sg_get_unaligned_be32(resp_buff + 8);
prot_en = !!(resp_buff[12] & 0x1);
op->xfer_len = block_size;
@@ -523,8 +523,7 @@ main(int argc, char * argv[])
(vb ? (vb - 1): 0));
if (0 == res) {
if (vb > 3)
- dStrHexErr((const char *)resp_buff, RCAP10_RESP_LEN,
- 1);
+ hex2stderr(resp_buff, RCAP10_RESP_LEN, 1);
block_size = sg_get_unaligned_be32(resp_buff + 4);
op->xfer_len = block_size;
} else {
diff --git a/src/sg_write_verify.c b/src/sg_write_verify.c
index 8fb03326..64937d6b 100644
--- a/src/sg_write_verify.c
+++ b/src/sg_write_verify.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014-2017 Douglas Gilbert
+ * Copyright (c) 2014-2018 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.
@@ -37,7 +37,7 @@
#include "sg_unaligned.h"
#include "sg_pr2serr.h"
-static const char * version_str = "1.11 20171008";
+static const char * version_str = "1.11 20180118";
#define ME "sg_write_verify: "
@@ -137,7 +137,7 @@ run_scsi_transaction(int sg_fd, const unsigned char *cdbp, int cdb_len,
pr2serr("\n");
if ((verbose > 2) && dop && do_len) {
pr2serr(" Data out buffer [%d bytes]:\n", do_len);
- dStrHexErr((const char *)dop, do_len, -1);
+ hex2stderr(dop, do_len, -1);
}
}
ptvp = construct_scsi_pt_obj();
diff --git a/src/sg_write_x.c b/src/sg_write_x.c
index d5381d52..4c99a2c0 100644
--- a/src/sg_write_x.c
+++ b/src/sg_write_x.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017 Douglas Gilbert.
+ * Copyright (c) 2017-2018 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.
@@ -36,7 +36,7 @@
#include "sg_unaligned.h"
#include "sg_pr2serr.h"
-static const char * version_str = "1.10 20171229";
+static const char * version_str = "1.12 20180118";
/* Protection Information refers to 8 bytes of extra information usually
* associated with each logical block and is often abbreviated to PI while
@@ -1265,12 +1265,12 @@ do_write_x(int sg_fd, const void * dataoutp, int dout_len,
if ((dout_len > 1024) && (vb < 7)) {
pr2serr(" Data-out buffer contents (first 1024 of %u "
"bytes):\n", dout_len);
- dStrHexErr((const char *)dataoutp, 1024, 1);
+ hex2stdout(dataoutp, 1024, 1);
pr2serr(" Above: dout's first 1024 of %u bytes [%s]\n",
dout_len, op->cdb_name);
} else {
pr2serr(" Data-out buffer contents (length=%u):\n", dout_len);
- dStrHexErr((const char *)dataoutp, (int)dout_len, 1);
+ hex2stderr(dataoutp, (int)dout_len, 1);
}
}
if (op->dry_run) {
@@ -1389,7 +1389,7 @@ do_read_capacity(int sg_fd, struct opts_t *op)
if (vb > 3) {
pr2serr("Read capacity(16) response:\n");
- dStrHexErr((const char *)resp_buff, RCAP16_RESP_LEN, 1);
+ hex2stderr(resp_buff, RCAP16_RESP_LEN, 1);
}
op->bs = sg_get_unaligned_be32(resp_buff + 8);
op->tot_lbs = sg_get_unaligned_be64(resp_buff + 0) + 1;
@@ -1448,7 +1448,7 @@ do_read_capacity(int sg_fd, struct opts_t *op)
if (0 == res) {
if (vb > 3) {
pr2serr("Read capacity(10) response:\n");
- dStrHexErr((const char *)resp_buff, RCAP10_RESP_LEN, 1);
+ hex2stderr(resp_buff, RCAP10_RESP_LEN, 1);
}
op->tot_lbs = sg_get_unaligned_be32(resp_buff + 0) + 1;
op->bs = sg_get_unaligned_be32(resp_buff + 4);
@@ -2493,9 +2493,9 @@ main(int argc, char * argv[])
pr2serr("warning: %d LBA,number_of_blocks pairs found, only "
"taking first\n", addr_arr_len);
} else if (op->scat_filename && (! op->do_scat_raw)) {
- uint32_t sum_num = 0;
uint8_t upp[96];
+ sum_num = 0;
ret = build_t10_scat(op->scat_filename, op->do_16,
true /* parse one */, upp, &num_lbard,
&sum_num, sizeof(upp));
diff --git a/src/sg_xcopy.c b/src/sg_xcopy.c
index 238c38b1..473d8fce 100644
--- a/src/sg_xcopy.c
+++ b/src/sg_xcopy.c
@@ -1,7 +1,7 @@
/* A utility program for copying files. Similar to 'dd' but using
* the 'Extended Copy' command.
*
- * Copyright (c) 2011-2017 Hannes Reinecke, SUSE Labs
+ * Copyright (c) 2011-2018 Hannes Reinecke, SUSE Labs
*
* Largely taken from 'sg_dd', which has the
*
@@ -10,23 +10,23 @@
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
-
- This program is a specialisation of the Unix "dd" command in which
- either the input or the output file is a scsi generic device, raw
- device, a block device or a normal file. The block size ('bs') is
- assumed to be 512 if not given. This program complains if 'ibs' or
- 'obs' are given with a value that differs from 'bs' (or the default 512).
- If 'if' is not given or 'if=-' then stdin is assumed. If 'of' is
- not given or 'of=-' then stdout assumed.
-
- A non-standard argument "bpt" (blocks per transfer) is added to control
- the maximum number of blocks in each transfer. The default value is 128.
- For example if "bs=512" and "bpt=32" then a maximum of 32 blocks (16 KiB
- 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 and 3 series.
-*/
+ *
+ * This program is a specialisation of the Unix "dd" command in which
+ * either the input or the output file is a scsi generic device, raw
+ * device, a block device or a normal file. The block size ('bs') is
+ * assumed to be 512 if not given. This program complains if 'ibs' or
+ * 'obs' are given with a value that differs from 'bs' (or the default 512).
+ * If 'if' is not given or 'if=-' then stdin is assumed. If 'of' is
+ * not given or 'of=-' then stdout assumed.
+ *
+ * A non-standard argument "bpt" (blocks per transfer) is added to control
+ * the maximum number of blocks in each transfer. The default value is 128.
+ * For example if "bs=512" and "bpt=32" then a maximum of 32 blocks (16 KiB
+ * 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 and 4 series.
+ */
#define _XOPEN_SOURCE 600
#ifndef _GNU_SOURCE
@@ -67,7 +67,7 @@
#include "sg_unaligned.h"
#include "sg_pr2serr.h"
-static const char * version_str = "0.60 20171025";
+static const char * version_str = "0.61 20180116";
#define ME "sg_xcopy: "
@@ -298,7 +298,7 @@ find_bsg_major(void)
/* Returns a file descriptor on success (0 or greater), -1 for an open
* error, -2 for a standard INQUIRY problem. */
static int
-open_sg(struct xcopy_fp_t * fp, int verbose)
+open_sg(struct xcopy_fp_t * fp, int vb)
{
int devmajor, devminor, offset;
struct sg_simple_inquiry_resp sir;
@@ -330,7 +330,7 @@ open_sg(struct xcopy_fp_t * fp, int verbose)
} else {
snprintf(ebuff, EBUFF_SZ, "/dev/char/%d:%d", devmajor, devminor);
}
- fp->sg_fd = sg_cmds_open_device(ebuff, false /* rw mode */, verbose);
+ fp->sg_fd = sg_cmds_open_device(ebuff, false /* rw mode */, vb);
if (fp->sg_fd < 0) {
snprintf(ebuff, EBUFF_SZ,
ME "could not open %s device %d:%d for sg",
@@ -339,7 +339,7 @@ open_sg(struct xcopy_fp_t * fp, int verbose)
perror(ebuff);
return -1;
}
- if (sg_simple_inquiry(fp->sg_fd, &sir, 0, verbose)) {
+ if (sg_simple_inquiry(fp->sg_fd, &sir, 0, vb)) {
pr2serr("INQUIRY failed on %s\n", ebuff);
sg_cmds_close_device(fp->sg_fd);
fp->sg_fd = -1;
@@ -347,7 +347,7 @@ open_sg(struct xcopy_fp_t * fp, int verbose)
}
fp->pdt = sir.peripheral_type;
- if (verbose)
+ if (vb)
pr2serr(" %s: %.8s %.16s %.4s [pdt=%d, 3pc=%d]\n", fp->fname,
sir.vendor, sir.product, sir.revision, fp->pdt,
!! (0x8 & sir.byte_5));
@@ -726,7 +726,7 @@ scsi_operating_parameter(struct xcopy_fp_t *xfp, int is_target)
}
if (verbose > 2) {
pr2serr("\nOutput response in hex:\n");
- dStrHexErr((const char *)rcBuff, len, 1);
+ hex2stderr(rcBuff, len, 1);
}
snlid = rcBuff[4] & 0x1;
max_target_num = sg_get_unaligned_be16(rcBuff + 8);
@@ -1051,7 +1051,7 @@ desc_from_vpd_id(int sg_fd, unsigned char *desc, int desc_len,
}
if (verbose > 2) {
pr2serr("Output response in hex:\n");
- dStrHexErr((const char *)rcBuff, len, 1);
+ hex2stderr(rcBuff, len, 1);
}
while ((u = sg_vpd_dev_id_iter(rcBuff + 4, len - 4, &off, 0, -1, -1)) ==
@@ -1110,7 +1110,7 @@ desc_from_vpd_id(int sg_fd, unsigned char *desc, int desc_len,
sg_put_unaligned_be24((uint32_t)block_size, desc + 29);
if (verbose > 3) {
pr2serr("Descriptor in hex (bs %d):\n", block_size);
- dStrHexErr((const char *)desc, 32, 1);
+ hex2stderr(desc, 32, 1);
}
return 32;
}
@@ -1193,14 +1193,14 @@ process_flags(const char * arg, struct xcopy_fp_t * fp)
* (-SG_LIB_FILE_ERROR or -SG_LIB_CAT_OTHER) if error.
*/
static int
-open_if(struct xcopy_fp_t * ifp, int verbose)
+open_if(struct xcopy_fp_t * ifp, int vb)
{
int infd = -1, flags, fl, res;
char ebuff[EBUFF_SZ];
ifp->sg_type = dd_filetype(ifp);
- if (verbose)
+ if (vb)
pr2serr(" >> Input file type: %s, devno %d:%d\n",
dd_filetype_str(ifp->sg_type, ebuff),
major(ifp->devno), minor(ifp->devno));
@@ -1221,7 +1221,7 @@ open_if(struct xcopy_fp_t * ifp, int verbose)
return -SG_LIB_FILE_ERROR;
}
}
- if (verbose)
+ if (vb)
pr2serr(" open input(sg_io), flags=0x%x\n", fl | flags);
if (ifp->flock) {
@@ -1242,13 +1242,13 @@ open_if(struct xcopy_fp_t * ifp, int verbose)
* (-SG_LIB_FILE_ERROR or -SG_LIB_CAT_OTHER) if error.
*/
static int
-open_of(struct xcopy_fp_t * ofp, int verbose)
+open_of(struct xcopy_fp_t * ofp, int vb)
{
int outfd, flags, res;
char ebuff[EBUFF_SZ];
ofp->sg_type = dd_filetype(ofp);
- if (verbose)
+ if (vb)
pr2serr(" >> Output file type: %s, devno %d:%d\n",
dd_filetype_str(ofp->sg_type, ebuff),
major(ofp->devno), minor(ofp->devno));
@@ -1263,7 +1263,7 @@ open_of(struct xcopy_fp_t * ofp, int verbose)
perror(ebuff);
return -SG_LIB_FILE_ERROR;
}
- if (verbose)
+ if (vb)
pr2serr(" open output(sg_io), flags=0x%x\n", flags);
} else
outfd = -1; /* don't bother opening */
diff --git a/testing/Makefile b/testing/Makefile
index 2e4ef68a..9471292a 100644
--- a/testing/Makefile
+++ b/testing/Makefile
@@ -4,11 +4,17 @@ PREFIX=/usr/local
INSTDIR=$(DESTDIR)/$(PREFIX)/bin
MANDIR=$(DESTDIR)/$(PREFIX)/man
+# In Linux the default C compiler is GCC while in FreeBSD (since release 10 ?)
+# the default C compiler is clang. Swap the comment marks (lines starting
+# with '#') on the next 4 (non-blank) lines.
CC = gcc
+# CC = clang
+
LD = gcc
+# LD = clang
EXECS = sg_iovec_tst sg_sense_test sg_queue_tst bsg_queue_tst sg_chk_asc \
- tst_sg_lib
+ sg_tst_nvme tst_sg_lib
EXTRAS =
@@ -35,7 +41,8 @@ CFLAGS = -g -O2 -W -Wall -iquote ../include -D_REENTRANT $(LARGE_FILE_FLAGS)
LDFLAGS =
LIBFILESOLD = ../lib/sg_lib.o ../lib/sg_lib_data.o ../lib/sg_io_linux.o
-LIBFILESNEW = ../lib/sg_lib.o ../lib/sg_lib_data.o ../lib/sg_pt_linux.o
+LIBFILESNEW = ../lib/sg_lib.o ../lib/sg_lib_data.o ../lib/sg_pt_linux.o \
+ ../lib/sg_pt_common.o ../lib/sg_cmds_basic.o ../lib/sg_pt_linux_nvme.o
all: $(EXECS)
@@ -67,6 +74,9 @@ bsg_queue_tst: bsg_queue_tst.o $(LIBFILESOLD)
sg_chk_asc: sg_chk_asc.o ../lib/sg_lib.o ../lib/sg_lib_data.o
$(LD) -o $@ $(LDFLAGS) $^
+sg_tst_nvme: sg_tst_nvme.o $(LIBFILESNEW)
+ $(LD) -o $@ $(LDFLAGS) $^
+
tst_sg_lib: tst_sg_lib.o ../lib/sg_lib.o ../lib/sg_lib_data.o
$(LD) -o $@ $(LDFLAGS) $^
@@ -90,6 +100,11 @@ uninstall:
rm -f $(MANDIR)/$(MAN_PREF)/$$mp.gz; \
done
+# Linux uses GNU make and FreeBSD uses Berkely make. The following lines
+# only work in Linux. Possible solutions in FreeBSD:
+# a) use 'gmake'; b) comment out the next 3 lines, starting with 'ifeq'
+# c) build with 'make -f Makefile.freebsd'
+# In Linux one can install bmake (but that won't help here).
ifeq (.depend,$(wildcard .depend))
include .depend
endif
diff --git a/testing/Makefile.freebsd b/testing/Makefile.freebsd
new file mode 100644
index 00000000..557b1e93
--- /dev/null
+++ b/testing/Makefile.freebsd
@@ -0,0 +1,96 @@
+SHELL = /bin/sh
+
+PREFIX=/usr/local
+INSTDIR=$(DESTDIR)/$(PREFIX)/bin
+MANDIR=$(DESTDIR)/$(PREFIX)/man
+
+# In Linux the default C compiler is GCC while in FreeBSD (since release 10 ?)
+# the default C compiler is clang. Swap the comment marks (lines starting
+# with '#') on the next 4 (non-blank) lines.
+# CC = gcc
+CC = clang
+
+# LD = gcc
+LD = clang
+
+EXECS = sg_sense_test sg_chk_asc sg_tst_nvme tst_sg_lib
+
+EXTRAS =
+
+MAN_PGS =
+MAN_PREF = man8
+
+OS_FLAGS = -DSG_LIB_FREEBSD
+EXTRA_FLAGS = $(OS_FLAGS)
+
+# For C++/clang testing
+## CC = gcc
+## CC = g++
+## CC = clang
+## CC = clang++
+
+# CFLAGS = -O2 -Wall -W $(EXTRA_FLAGS) -I ../include
+CFLAGS = -g -O2 -Wall -W $(EXTRA_FLAGS) -I ../include
+# CFLAGS = -g -O2 -Wall -W -pedantic -std=c99 $(EXTRA_FLAGS) -I ../include
+
+CFLAGS_PTHREADS = -D_REENTRANT
+
+# there is no rule to make the following in the parent directory,
+# it is assumed they are already built.
+D_FILES = ../lib/sg_lib.o ../lib/sg_lib_data.o ../lib/sg_cmds_basic.o ../lib/sg_pt_common.o ../lib/sg_pt_freebsd.o
+
+LDFLAGS = -lcam
+
+all: $(EXECS)
+
+extras: $(EXTRAS)
+
+
+depend dep:
+ for i in *.c; do $(CC) $(INCLUDES) $(CFLAGS) -M $$i; \
+ done > .depend
+
+clean:
+ /bin/rm -f *.o $(EXECS) $(EXTRAS) core .depend
+
+sg_sense_test: sg_sense_test.o $(D_FILES)
+ $(LD) -o $@ $(LDFLAGS) $@.o $(D_FILES)
+
+# building sg_chk_asc depends on a prior successful make in ../lib
+sg_chk_asc: sg_chk_asc.o $(D_FILES)
+ $(LD) -o $@ $(LDFLAGS) $@.o $(D_FILES)
+
+sg_tst_nvme: sg_tst_nvme.o $(D_FILES)
+ $(LD) -o $@ $(LDFLAGS) $@.o $(D_FILES)
+
+tst_sg_lib: tst_sg_lib.o $(D_FILES)
+ $(LD) -o $@ $(LDFLAGS) $@.o $(D_FILES)
+
+install: $(EXECS)
+ install -d $(INSTDIR)
+ for name in $^; \
+ do install -s -o root -g root -m 755 $$name $(INSTDIR); \
+ done
+ install -d $(MANDIR)/$(MAN_PREF)
+ for mp in $(MAN_PGS); \
+ do install -o root -g root -m 644 $$mp $(MANDIR)/$(MAN_PREF); \
+ gzip -9f $(MANDIR)/$(MAN_PREF)/$$mp; \
+ done
+
+uninstall:
+ dists="$(EXECS)"; \
+ for name in $$dists; do \
+ rm -f $(INSTDIR)/$$name; \
+ done
+ for mp in $(MAN_PGS); do \
+ rm -f $(MANDIR)/$(MAN_PREF)/$$mp.gz; \
+ done
+
+# Linux uses GNU make and FreeBSD uses Berkely make. The following lines
+# only work in Linux. Possible solutions in FreeBSD:
+# a) use 'gmake'; b) comment out the next 3 lines, starting with 'ifeq'
+# c) build with 'make -f Makefile.freebsd'
+# In Linux one can install bmake (but that won't help here).
+# ifeq (.depend,$(wildcard .depend))
+# include .depend
+# endif
diff --git a/testing/sg_iovec_tst.c b/testing/sg_iovec_tst.c
index 3018ba45..3928be95 100644
--- a/testing/sg_iovec_tst.c
+++ b/testing/sg_iovec_tst.c
@@ -9,13 +9,14 @@
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
+
#include "sg_lib.h"
#include "sg_io_linux.h"
#include "sg_unaligned.h"
/* Test code for D. Gilbert's extensions to the Linux OS SCSI generic ("sg")
device driver.
-* Copyright (C) 2003-2017 D. Gilbert
+* Copyright (C) 2003-2018 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)
diff --git a/testing/sg_tst_nvme.c b/testing/sg_tst_nvme.c
new file mode 100644
index 00000000..1e1b502f
--- /dev/null
+++ b/testing/sg_tst_nvme.c
@@ -0,0 +1,731 @@
+/*
+ * Copyright (c) 2018 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.
+ *
+ * This program issues a NVMe Identify command (controller or namespace)
+ * or a Device self-test command via the "SCSI" pass-through interface of
+ * this packages sg_utils library. That interface is primarily shown in
+ * the ../include/sg_pt.h header file.
+ *
+ */
+
+#include <unistd.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <stdbool.h>
+#include <string.h>
+#include <errno.h>
+#include <limits.h>
+#include <getopt.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#define __STDC_FORMAT_MACROS 1
+#include <inttypes.h>
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "sg_lib.h"
+#include "sg_pt.h"
+#include "sg_pt_nvme.h"
+#include "sg_cmds_basic.h"
+#include "sg_unaligned.h"
+#include "sg_pr2serr.h"
+
+static const char * version_str = "1.00 20180118";
+
+
+#define ME "sg_tst_nvme: "
+
+#define SENSE_BUFF_LEN 32 /* Arbitrary, only need 16 bytes for NVME
+ * (and SCSI at least 18) currently */
+
+
+#define INQUIRY_CMD 0x12 /* SCSI command to get VPD page 0x83 */
+#define INQUIRY_CMDLEN 6
+
+#define VPD_DEVICE_ID 0x83
+
+#define DEF_TIMEOUT_SECS 60
+
+
+static struct option long_options[] = {
+ {"ctl", no_argument, 0, 'c'},
+ {"dev-id", no_argument, 0, 'd'},
+ {"dev_id", no_argument, 0, 'd'},
+ {"help", no_argument, 0, 'h'},
+ {"long", no_argument, 0, 'l'},
+ {"nsid", required_argument, 0, 'n'},
+ {"self-test", required_argument, 0, 's'},
+ {"self_test", required_argument, 0, 's'},
+ {"to-ms", required_argument, 0, 't'},
+ {"to_ms", required_argument, 0, 't'},
+ {"verbose", no_argument, 0, 'v'},
+ {"version", no_argument, 0, 'V'},
+ {0, 0, 0, 0},
+};
+
+
+static void
+usage()
+{
+ pr2serr("Usage: sg_tst_nvme [--ctl] [dev-id] [--help] [--long] "
+ "[--nsid=ID]\n"
+ " [--self-test=ST] [--to-ms=TO] [--verbose] "
+ "[--version]\n"
+ " DEVICE\n"
+ " where:\n"
+ " --ctl|-c do Identify controller command\n"
+ " --dev-id|-d do SCSI INQUIRY for device "
+ " identification\n"
+ " VPD page (0x83) via own SNTL\n"
+ " --help|-h print out usage message\n"
+ " --long|-l add more detail to decoded output\n"
+ " --nsid=ID| -n ID do Identify namespace with nsid set to "
+ "ID; if ID\n"
+ " is 0 then try to get nsid from "
+ "DEVICE.\n"
+ " Can also be used with self-test (def: "
+ "0)\n"
+ " --self-test=ST|-s ST do (or abort) device self-test, ST "
+ "can be:\n"
+ " 0: do nothing\n"
+ " 1: do short (background) "
+ "self-test\n"
+ " 2: do long self-test\n"
+ " 15: abort self-test in "
+ "progress\n"
+ " if nsid is 0 then test controller "
+ "only\n"
+ " if nsid is 0xffffffff then test "
+ "controller and\n"
+ " all namespaces\n"
+ " --to-ms=TO|-t TO command timeout in milliseconds (def: "
+ "60,000)\n"
+ " --verbose|-v increase verbosity\n"
+ " --version|-V print version string then exit\n\n"
+ "Performs a NVME Identify or Device self-test Admin command on "
+ "DEVICE.\nCan also simulate a SCSI device identification VPD "
+ "page [0x83] via\na local SNTL. --nsid= accepts '-1' for "
+ "0xffffffff .\n"
+ );
+}
+
+static void
+show_nvme_id_ctl(const uint8_t *dinp, const char *dev_name, int do_long)
+{
+ bool got_fguid;
+ uint8_t ver_min, ver_ter, mtds;
+ uint16_t ver_maj, oacs, oncs;
+ uint32_t k, ver, max_nsid, npss, j, n, m;
+ uint64_t sz1, sz2;
+ const uint8_t * up;
+
+ max_nsid = sg_get_unaligned_le32(dinp + 516); /* NN */
+ printf("Identify controller for %s:\n", dev_name);
+ printf(" Model number: %.40s\n", (const char *)(dinp + 24));
+ printf(" Serial number: %.20s\n", (const char *)(dinp + 4));
+ printf(" Firmware revision: %.8s\n", (const char *)(dinp + 64));
+ ver = sg_get_unaligned_le32(dinp + 80);
+ ver_maj = (ver >> 16);
+ ver_min = (ver >> 8) & 0xff;
+ ver_ter = (ver & 0xff);
+ printf(" Version: %u.%u", ver_maj, ver_min);
+ if ((ver_maj > 1) || ((1 == ver_maj) && (ver_min > 2)) ||
+ ((1 == ver_maj) && (2 == ver_min) && (ver_ter > 0)))
+ printf(".%u\n", ver_ter);
+ else
+ printf("\n");
+ oacs = sg_get_unaligned_le16(dinp + 256);
+ if (0x1ff & oacs) {
+ printf(" Optional admin command support:\n");
+ if (0x100 & oacs)
+ printf(" Doorbell buffer config\n");
+ if (0x80 & oacs)
+ printf(" Virtualization management\n");
+ if (0x40 & oacs)
+ printf(" NVMe-MI send and NVMe-MI receive\n");
+ if (0x20 & oacs)
+ printf(" Directive send and directive receive\n");
+ if (0x10 & oacs)
+ printf(" Device self-test\n");
+ if (0x8 & oacs)
+ printf(" Namespace management and attachment\n");
+ if (0x4 & oacs)
+ printf(" Firmware download and commit\n");
+ if (0x2 & oacs)
+ printf(" Format NVM\n");
+ if (0x1 & oacs)
+ printf(" Security send and receive\n");
+ } else
+ printf(" No optional admin command support\n");
+ oncs = sg_get_unaligned_le16(dinp + 256);
+ if (0x7f & oncs) {
+ printf(" Optional NVM command support:\n");
+ if (0x40 & oncs)
+ printf(" Timestamp feature\n");
+ if (0x20 & oncs)
+ printf(" Reservations\n");
+ if (0x10 & oncs)
+ printf(" Save and Select fields non-zero\n");
+ if (0x8 & oncs)
+ printf(" Write zeroes\n");
+ if (0x4 & oncs)
+ printf(" Dataset management\n");
+ if (0x2 & oncs)
+ printf(" Write uncorrectable\n");
+ if (0x1 & oncs)
+ printf(" Compare\n");
+ } else
+ printf(" No optional NVM command support\n");
+ printf(" PCI vendor ID VID/SSVID: 0x%x/0x%x\n",
+ sg_get_unaligned_le16(dinp + 0),
+ sg_get_unaligned_le16(dinp + 2));
+ printf(" IEEE OUI Identifier: 0x%x\n",
+ sg_get_unaligned_le24(dinp + 73));
+ got_fguid = ! sg_all_zeros(dinp + 112, 16);
+ if (got_fguid) {
+ printf(" FGUID: 0x%02x", dinp[112]);
+ for (k = 1; k < 16; ++k)
+ printf("%02x", dinp[112 + k]);
+ printf("\n");
+ } else if (do_long)
+ printf(" FGUID: 0x0\n");
+ printf(" Controller ID: 0x%x\n", sg_get_unaligned_le16(dinp + 78));
+ if (do_long) {
+ printf(" Management endpoint capabilities, over a PCIe port: %d\n",
+ !! (0x2 & dinp[255]));
+ printf(" Management endpoint capabilities, over a SMBus/I2C port: "
+ "%d\n", !! (0x1 & dinp[255]));
+ }
+ printf(" Number of namespaces: %u\n", max_nsid);
+ sz1 = sg_get_unaligned_le64(dinp + 280); /* lower 64 bits */
+ sz2 = sg_get_unaligned_le64(dinp + 288); /* upper 64 bits */
+ if (sz2)
+ printf(" Total NVM capacity: huge ...\n");
+ else if (sz1)
+ printf(" Total NVM capacity: %" PRIu64 " bytes\n", sz1);
+ mtds = dinp[77];
+ printf(" Maximum data transfer size: ");
+ if (mtds)
+ printf("%u pages\n", 1U << mtds);
+ else
+ printf("<unlimited>\n");
+
+ if (do_long) {
+ const char * const non_op = "does not process I/O";
+ const char * const operat = "processes I/O";
+ const char * cp;
+
+ printf(" Total NVM capacity: 0 bytes\n");
+ npss = dinp[263] + 1;
+ up = dinp + 2048;
+ for (k = 0; k < npss; ++k, up += 32) {
+ n = sg_get_unaligned_le16(up + 0);
+ n *= (0x1 & up[3]) ? 1 : 100; /* unit: 100 microWatts */
+ j = n / 10; /* unit: 1 milliWatts */
+ m = j % 1000;
+ j /= 1000;
+ cp = (0x2 & up[3]) ? non_op : operat;
+ printf(" Power state %u: Max power: ", k);
+ if (0 == j) {
+ m = n % 10;
+ n /= 10;
+ printf("%u.%u milliWatts, %s\n", n, m, cp);
+ } else
+ printf("%u.%03u Watts, %s\n", j, m, cp);
+ n = sg_get_unaligned_le32(up + 4);
+ if (0 == n)
+ printf(" [ENLAT], ");
+ else
+ printf(" ENLAT=%u, ", n);
+ n = sg_get_unaligned_le32(up + 8);
+ if (0 == n)
+ printf("[EXLAT], ");
+ else
+ printf("EXLAT=%u, ", n);
+ n = 0x1f & up[12];
+ printf("RRT=%u, ", n);
+ n = 0x1f & up[13];
+ printf("RRL=%u, ", n);
+ n = 0x1f & up[14];
+ printf("RWT=%u, ", n);
+ n = 0x1f & up[15];
+ printf("RWL=%u\n", n);
+ }
+ }
+}
+
+static const char * rperf[] = {"Best", "Better", "Good", "Degraded"};
+
+static void
+show_nvme_id_ns(const uint8_t * dinp, int do_long)
+{
+ bool got_eui_128 = false;
+ uint32_t u, k, off, num_lbaf, flbas, flba_info, md_size, lb_size;
+ uint64_t ns_sz, eui_64;
+
+ num_lbaf = dinp[25] + 1; /* spec says this is "0's based value" */
+ flbas = dinp[26] & 0xf; /* index of active LBA format (for this ns) */
+ ns_sz = sg_get_unaligned_le64(dinp + 0);
+ eui_64 = sg_get_unaligned_be64(dinp + 120); /* N.B. big endian */
+ if (! sg_all_zeros(dinp + 104, 16))
+ got_eui_128 = true;
+ printf(" Namespace size/capacity: %" PRIu64 "/%" PRIu64
+ " blocks\n", ns_sz, sg_get_unaligned_le64(dinp + 8));
+ printf(" Namespace utilization: %" PRIu64 " blocks\n",
+ sg_get_unaligned_le64(dinp + 16));
+ if (got_eui_128) { /* N.B. big endian */
+ printf(" NGUID: 0x%02x", dinp[104]);
+ for (k = 1; k < 16; ++k)
+ printf("%02x", dinp[104 + k]);
+ printf("\n");
+ } else if (do_long)
+ printf(" NGUID: 0x0\n");
+ if (eui_64)
+ printf(" EUI-64: 0x%" PRIx64 "\n", eui_64); /* N.B. big endian */
+ printf(" Number of LBA formats: %u\n", num_lbaf);
+ printf(" Index LBA size: %u\n", flbas);
+ for (k = 0, off = 128; k < num_lbaf; ++k, off += 4) {
+ printf(" LBA format %u support:", k);
+ if (k == flbas)
+ printf(" <-- active\n");
+ else
+ printf("\n");
+ flba_info = sg_get_unaligned_le32(dinp + off);
+ md_size = flba_info & 0xffff;
+ lb_size = flba_info >> 16 & 0xff;
+ if (lb_size > 31) {
+ pr2serr("%s: logical block size exponent of %u implies a LB "
+ "size larger than 4 billion bytes, ignore\n", __func__,
+ lb_size);
+ continue;
+ }
+ lb_size = 1U << lb_size;
+ ns_sz *= lb_size;
+ ns_sz /= 500*1000*1000;
+ if (ns_sz & 0x1)
+ ns_sz = (ns_sz / 2) + 1;
+ else
+ ns_sz = ns_sz / 2;
+ u = (flba_info >> 24) & 0x3;
+ printf(" Logical block size: %u bytes\n", lb_size);
+ printf(" Approximate namespace size: %" PRIu64 " GB\n", ns_sz);
+ printf(" Metadata size: %u bytes\n", md_size);
+ printf(" Relative performance: %s [0x%x]\n", rperf[u], u);
+ }
+}
+
+/* Invokes a NVMe Admin command via sg_utils library pass-through that will
+ * potentially fetch data from the device (din). Returns 0 -> success,
+ * various SG_LIB_* positive values or negated errno values.
+ * SG_LIB_NVME_STATUS is returned if the NVMe status is non-zero. */
+static int
+nvme_din_admin_cmd(int sg_fd, const uint8_t *cmdp, uint32_t cmd_len,
+ const char *cmd_str, bool internal_nsid, uint8_t *dip,
+ int di_len, int timeout_ms, uint16_t *sct_scp,
+ int verbose)
+{
+ int res, k;
+ uint16_t sct_sc;
+ uint32_t result, clen;
+ struct sg_pt_base * ptvp;
+ unsigned char sense_b[SENSE_BUFF_LEN];
+ uint8_t ucmd[128];
+ char b[32];
+
+ snprintf(b, sizeof(b), "%s", cmd_str);
+ clen = (cmd_len > sizeof(ucmd)) ? sizeof(ucmd) : cmd_len;
+ memcpy(ucmd, cmdp, clen);
+ ptvp = construct_scsi_pt_obj_with_fd(sg_fd, verbose);
+ if (NULL == ptvp) {
+ pr2serr("%s: out of memory\n", b);
+ return -ENOMEM;
+ }
+ if (internal_nsid)
+ sg_put_unaligned_le32(get_pt_nvme_nsid(ptvp), ucmd + SG_NVME_PT_NSID);
+ if (verbose > 1) {
+ pr2serr(" %s cdb:\n", b);
+ hex2stderr(ucmd, clen, -1);
+ }
+ set_scsi_pt_cdb(ptvp, ucmd, clen);
+ set_scsi_pt_sense(ptvp, sense_b, sizeof(sense_b));
+ if (dip && (di_len > 0))
+ set_scsi_pt_data_in(ptvp, dip, di_len);
+ res = do_scsi_pt(ptvp, -1, -timeout_ms, verbose);
+ if (res < 0)
+ goto err_out; /* OS error (Unix: negated errno) */
+
+ if ((verbose > 2) && dip && di_len) {
+ k = get_scsi_pt_resid(ptvp);
+ pr2serr(" Data in buffer [%d bytes]:\n", di_len - k);
+ if (di_len > k)
+ hex2stderr(dip, di_len - k, -1);
+ if (verbose > 3)
+ pr2serr(" do_scsi_pt(nvme): res=%d resid=%d\n", res, k);
+ }
+ sct_sc = get_scsi_pt_status_response(ptvp);
+ result = get_pt_result(ptvp);
+ k = get_scsi_pt_sense_len(ptvp);
+ if (verbose) {
+ pr2serr("Status: 0x%x [SCT<<8 + SC], Result: 0x%x, Completion Q:\n",
+ sct_sc, result);
+ if (k > 0)
+ hex2stderr(sense_b, k, -1);
+ }
+ if (sct_scp)
+ *sct_scp = sct_sc;
+err_out:
+ destruct_scsi_pt_obj(ptvp);
+ return res;
+}
+
+/* Invokes a SCSI INQUIRY command and yields the response. Returns 0 when
+ * successful, various SG_LIB_CAT_* positive values or -1 -> other errors.
+ * The CMDDT field is obsolete in the INQUIRY cdb (since spc3r16 in 2003) so
+ * an argument to set it has been removed (use the REPORT SUPPORTED OPERATION
+ * CODES command instead). Adds the ability to set the command abort timeout
+ * and the ability to report the residual count. If timeout_secs is zero
+ * the default command abort timeout (60 seconds) is used.
+ * If residp is non-NULL then the residual value is written where residp
+ * points. A residual value of 0 implies mx_resp_len bytes have be written
+ * where resp points. If the residual value equals mx_resp_len then no
+ * bytes have been written. */
+static int
+sg_scsi_inquiry(int sg_fd, bool evpd, int pg_op, void * resp,
+ int mx_resp_len, int timeout_secs, int * residp,
+ bool noisy, int verbose)
+{
+ int res, ret, k, sense_cat, resid;
+ unsigned char inq_cdb[INQUIRY_CMDLEN] = {INQUIRY_CMD, 0, 0, 0, 0, 0};
+ unsigned char sense_b[SENSE_BUFF_LEN];
+ unsigned char * up;
+ struct sg_pt_base * ptvp;
+
+ if (evpd)
+ inq_cdb[1] |= 1;
+ inq_cdb[2] = (unsigned char)pg_op;
+ sg_put_unaligned_be16((uint16_t)mx_resp_len, inq_cdb + 3);
+ if (verbose > 1) {
+ pr2serr(" INQUIRY cdb: ");
+ for (k = 0; k < INQUIRY_CMDLEN; ++k)
+ pr2serr("%02x ", inq_cdb[k]);
+ pr2serr("\n");
+ }
+ if (resp && (mx_resp_len > 0)) {
+ up = (unsigned char *)resp;
+ up[0] = 0x7f; /* defensive prefill */
+ if (mx_resp_len > 4)
+ up[4] = 0;
+ }
+ if (timeout_secs == 0)
+ timeout_secs = DEF_TIMEOUT_SECS;
+ ptvp = construct_scsi_pt_obj_with_fd(sg_fd, verbose);
+ if (NULL == ptvp) {
+ pr2serr("%s: out of memory\n", __func__);
+ if (residp)
+ *residp = 0;
+ return -1;
+ }
+ set_scsi_pt_cdb(ptvp, inq_cdb, sizeof(inq_cdb));
+ set_scsi_pt_sense(ptvp, sense_b, sizeof(sense_b));
+ set_scsi_pt_data_in(ptvp, (unsigned char *)resp, mx_resp_len);
+ res = do_scsi_pt(ptvp, -1, timeout_secs, verbose);
+ ret = sg_cmds_process_resp(ptvp, "inquiry", res, mx_resp_len, sense_b,
+ noisy, verbose, &sense_cat);
+ resid = get_scsi_pt_resid(ptvp);
+ if (residp)
+ *residp = resid;
+ destruct_scsi_pt_obj(ptvp);
+ if (-1 == ret)
+ ;
+ 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 if (ret < 4) {
+ if (verbose)
+ pr2serr("%s: got too few bytes (%d)\n", __func__, ret);
+ ret = SG_LIB_CAT_MALFORMED;
+ } else
+ ret = 0;
+
+ if (resid > 0) {
+ if (resid > mx_resp_len) {
+ pr2serr("INQUIRY resid (%d) should never exceed requested "
+ "len=%d\n", resid, mx_resp_len);
+ return ret ? ret : SG_LIB_CAT_MALFORMED;
+ }
+ /* zero unfilled section of response buffer */
+ memset((unsigned char *)resp + (mx_resp_len - resid), 0, resid);
+ }
+ return ret;
+}
+
+int
+main(int argc, char * argv[])
+{
+ bool do_dev_id_vpd = false;
+ bool do_id_ctl = false;
+ bool do_id_ns = false;
+ bool do_self_test = false;
+ bool flagged = false;
+ int sg_fd, res, c, n, resid, off, len, ln;
+ int do_long = 0;
+ int self_test = 0;
+ int ret = 1;
+ int timeout_ms = DEF_TIMEOUT_SECS * 1000;
+ int vb = 0;
+ uint32_t nsid = 0;
+ uint32_t pg_sz = sg_get_page_size();
+ int64_t ll;
+ uint8_t * al_buff = NULL;
+ uint8_t * free_al_buff = NULL;
+ uint8_t * bp;
+ const char * device_name = NULL;
+ const char * cp;
+ char cmd_name[32];
+ char b[2048];
+
+ while (1) {
+ int option_index = 0;
+
+ c = getopt_long(argc, argv, "cdhln:s:t:vV", long_options,
+ &option_index);
+ if (c == -1)
+ break;
+
+ switch (c) {
+ case 'c':
+ strcpy(cmd_name, "Identify(ctl)");
+ do_id_ctl = true;
+ break;
+ case 'd':
+ strcpy(cmd_name, "INQUIRY(vpd=0x83)");
+ do_dev_id_vpd = true;
+ break;
+ case 'h':
+ case '?':
+ usage();
+ return 0;
+ case 'l':
+ ++do_long;
+ break;
+ case 'n':
+ if ((2 == strlen(optarg)) && (0 == memcmp("-1", optarg, 2))) {
+ nsid = 0xffffffff; /* treat '-1' as (2**32 - 1) */
+ break;
+ }
+ ll = sg_get_llnum(optarg);
+ if ((ll < 0) || (ll > UINT32_MAX)) {
+ pr2serr("bad argument to '--nsid', accept 0 to 0xffffffff\n");
+ return SG_LIB_SYNTAX_ERROR;
+ }
+ strcpy(cmd_name, "Identify(ns)");
+ nsid = (uint32_t)ll;
+ do_id_ns = true;
+ break;
+ case 's':
+ self_test = sg_get_num(optarg);
+ if (self_test < 0) {
+ pr2serr("bad argument to '--self-test=', expect 0 or "
+ "higher\n");
+ return SG_LIB_SYNTAX_ERROR;
+ }
+ strcpy(cmd_name, "Device self-test");
+ do_self_test = true;
+ break;
+ case 't':
+ timeout_ms = sg_get_num(optarg);
+ if (timeout_ms < 0) {
+ pr2serr("bad argument to '--to-ms=', expect 0 or higher\n");
+ return SG_LIB_SYNTAX_ERROR;
+ }
+ break;
+ case 'v':
+ ++vb;
+ break;
+ case 'V':
+ pr2serr(ME "version: %s\n", version_str);
+ return 0;
+ default:
+ pr2serr("unrecognised option code 0x%x ??\n", c);
+ usage();
+ return SG_LIB_SYNTAX_ERROR;
+ }
+ }
+ if (optind < argc) {
+ if (NULL == device_name) {
+ 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 (NULL == device_name) {
+ pr2serr("missing device name!\n\n");
+ usage();
+ return SG_LIB_SYNTAX_ERROR;
+ }
+
+ if (do_self_test && do_id_ns)
+ do_id_ns = false; /* self-test with DW10 set to nsid */
+ n = (int)do_id_ctl + (int)do_id_ns + (int)do_dev_id_vpd +
+ (int)do_self_test;
+ if (n > 1) {
+ pr2serr("can only have one of --ctl, --dev-id, --nsid= and "
+ "--self-test=\n\n");
+ usage();
+ return SG_LIB_SYNTAX_ERROR;
+ } else if (0 == n)
+ do_id_ctl = true;
+
+
+ al_buff = sg_memalign(pg_sz, pg_sz, &free_al_buff, vb > 3);
+ if (NULL == al_buff) {
+ pr2serr("out of memory allocating page sized buffer\n");
+ return -ENOMEM;
+ }
+ sg_fd = sg_cmds_open_device(device_name, false /* rw */, vb);
+ if (sg_fd < 0) {
+ pr2serr(ME "open error: %s: %s\n", device_name, safe_strerror(-sg_fd));
+ ret = SG_LIB_FILE_ERROR;
+ flagged = true;
+ goto err_out;
+ }
+ n = check_pt_file_handle(sg_fd, device_name, vb);
+ if (n < 0) {
+ pr2serr("check_pt_file_handle error: %s: %s\n", device_name,
+ safe_strerror(-n));
+ flagged = true;
+ goto err_out;
+ }
+ cp = NULL;
+ switch (n) {
+ case 0:
+ cp = "Unidentified device (SATA disk ?)";
+ break;
+ case 1:
+ cp = "SCSI char device (e.g. in Linux: sg or bsg device)";
+ break;
+ case 2:
+ cp = "SCSI block device (e.g. in FreeBSD: /dev/da0)";
+ break;
+ case 3:
+ cp = "NVMe char device (e.g. in Linux: /dev/nvme0)";
+ break;
+ case 4:
+ cp = "NVMe block device (e.g. in FreeBSD: /dev/nvme0ns1)";
+ break;
+ default:
+ pr2serr("Strange value from check_pt_file_handle() --> %d\n", n);
+ break;
+ }
+ if (cp && (vb || (do_long > 0)))
+ pr2serr("%s\n", cp);
+
+ /* Ignore the above check and do what has been asked on command line */
+ resid = 0;
+ if (do_dev_id_vpd) {
+ ret = sg_scsi_inquiry(sg_fd, true /* evpd */, VPD_DEVICE_ID, al_buff,
+ pg_sz, timeout_ms / 1000, &resid, true, vb);
+ if (ret) {
+ pr2serr("SCSI INQUIRY to SNTL for device id vpage failed, "
+ "try again with -vv option added\n");
+ goto err_out;
+ }
+ len = pg_sz - resid;
+ if (len < 4) {
+ pr2serr("Something wrong with data-in, len=%d (resid=%d)\n",
+ len, resid);
+ goto err_out;
+ }
+ for (off = -1, bp = al_buff + 4, ln = len - 4;
+ 0 == sg_vpd_dev_id_iter(bp, ln, &off, -1, -1, -1); ) {
+ n = sg_get_designation_descriptor_str(" ", bp + off,
+ bp[off + 3] + 4, do_long > 0, do_long > 1, sizeof(b), b);
+ if (n > 0)
+ printf("%s", b);
+ }
+
+ } else { /* NVME Identify or Device self-test */
+ uint16_t sct_sc;
+ struct sg_nvme_passthru_cmd n_cmd;
+
+ memset(&n_cmd, 0, sizeof(n_cmd));
+ if (do_self_test) {
+ n_cmd.opcode = 0x14; /* Device self-test */
+ n_cmd.nsid = nsid;
+ n_cmd.cdw10 = self_test;
+ if (0 == nsid)
+ printf("Starting Device self-test for controller only\n");
+ else if (0xffffffff == nsid)
+ printf("Starting Device self-test for controller and all "
+ "namespaces\n");
+ else
+ printf("Starting Device self-test for controller and "
+ "namespace %u\n", nsid);
+ } else {
+ n_cmd.opcode = 0x6; /* Identify */
+ if (do_id_ctl)
+ n_cmd.cdw10 = 0x1; /* Controller */
+ else {
+ n_cmd.cdw10 = 0x0; /* Namespace */
+ n_cmd.nsid = nsid;
+ }
+ }
+ ret = nvme_din_admin_cmd(sg_fd, (const uint8_t *)&n_cmd,
+ sizeof(n_cmd), cmd_name, (0 == nsid),
+ al_buff, pg_sz, timeout_ms, &sct_sc, vb);
+ if (ret < 0)
+ goto err_out;
+ if (sct_sc > 0) {
+ sg_get_nvme_cmd_status_str(sct_sc, sizeof(b), b);
+ pr2serr("%s: %s\n", cmd_name, b);
+ flagged = true;
+ goto err_out;
+ }
+ if (do_id_ctl)
+ show_nvme_id_ctl(al_buff, device_name, do_long);
+ else if (do_id_ns)
+ show_nvme_id_ns(al_buff, do_long);
+ }
+ ret = 0;
+
+err_out:
+ if (free_al_buff)
+ free(free_al_buff);
+ res = sg_cmds_close_device(sg_fd);
+ if (res < 0) {
+ pr2serr("close error: %s\n", safe_strerror(-res));
+ if (0 == ret)
+ return SG_LIB_FILE_ERROR;
+ }
+ if (ret && (0 == vb) && (! flagged)) {
+ if (SG_LIB_CAT_INVALID_OP == ret)
+ pr2serr("%s command not supported\n", cmd_name);
+ else if (SG_LIB_NVME_STATUS == ret)
+ pr2serr("%s completed with a NVME non-zero status\n", cmd_name);
+ else if (ret > 0)
+ pr2serr("%s, exit status %d\n", cmd_name, ret);
+ else if (ret < 0)
+ pr2serr("Some error occurred\n");
+ }
+ return (ret >= 0) ? ret : SG_LIB_CAT_OTHER;
+}