aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDouglas Gilbert <dgilbert@interlog.com>2010-12-06 02:27:23 +0000
committerDouglas Gilbert <dgilbert@interlog.com>2010-12-06 02:27:23 +0000
commit3c60a8b8991001fe80ffdd95ca77bcce40b035eb (patch)
treec853891eab503ca2a6187d4623602f19b8a935be /src
parent02f2be1ee0e44a84cbdfa510ea11db9bcb4275ce (diff)
downloadsg3_utils-3c60a8b8991001fe80ffdd95ca77bcce40b035eb.tar.gz
add forwarded sense descriptor; new sg_decode_sense utility
git-svn-id: https://svn.bingwo.ca/repos/sg3_utils/trunk@365 6180dd3e-e324-4e3e-922d-17de1ae2f315
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am19
-rw-r--r--src/Makefile.in58
-rw-r--r--src/sg_decode_sense.c356
-rw-r--r--src/sg_format.c19
-rw-r--r--src/sg_inq.c2
-rw-r--r--src/sg_inq_data.c16
-rw-r--r--src/sg_turs.c14
7 files changed, 430 insertions, 54 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index 433133da..b45ff5e1 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -8,9 +8,9 @@ if OS_LINUX
# sg_scan is shared by Linux and Win32
bin_PROGRAMS = \
- sg_dd sg_emc_trespass sg_format sg_get_config sg_get_lba_status \
- sg_ident sginfo sg_inq sg_logs sg_luns sg_map26 sg_map \
- sgm_dd sg_modes sg_opcodes sgp_dd sg_persist sg_prevent \
+ sg_dd sg_decode_sense sg_emc_trespass sg_format sg_get_config \
+ sg_get_lba_status sg_ident sginfo sg_inq sg_logs sg_luns sg_map26 \
+ sg_map sgm_dd sg_modes sg_opcodes sgp_dd sg_persist sg_prevent \
sg_raw sg_rbuf sg_rdac sg_read sg_readcap sg_read_block_limits \
sg_read_buffer sg_read_long sg_reassign sg_referrals \
sg_requests sg_reset sg_rmsn sg_rtpg sg_safte sg_sat_identify \
@@ -30,7 +30,7 @@ endif
if OS_WIN32_MINGW
bin_PROGRAMS = \
- sg_format sg_get_config sg_get_lba_status sg_ident \
+ sg_decode_sense sg_format sg_get_config sg_get_lba_status sg_ident \
sg_inq sg_logs sg_luns sg_modes sg_opcodes sg_persist \
sg_prevent sg_raw sg_rdac sg_readcap sg_read_block_limits \
sg_read_buffer sg_read_long sg_reassign sg_referrals sg_requests \
@@ -51,7 +51,7 @@ endif
if OS_WIN32_CYGWIN
bin_PROGRAMS = \
- sg_format sg_get_config sg_get_lba_status sg_ident \
+ sg_decode_sense sg_format sg_get_config sg_get_lba_status sg_ident \
sg_inq sg_logs sg_luns sg_modes sg_opcodes sg_persist \
sg_prevent sg_raw sg_rdac sg_readcap sg_read_block_limits \
sg_read_buffer sg_read_long sg_reassign sg_referrals sg_requests \
@@ -72,7 +72,7 @@ endif
if OS_FREEBSD
bin_PROGRAMS = \
- sg_format sg_get_config sg_get_lba_status sg_ident \
+ sg_decode_sense sg_format sg_get_config sg_get_lba_status sg_ident \
sg_inq sg_logs sg_luns sg_modes sg_opcodes sg_persist \
sg_prevent sg_raw sg_rdac sg_readcap sg_read_block_limits \
sg_read_buffer sg_read_long sg_reassign sg_referrals sg_requests \
@@ -87,7 +87,7 @@ endif
if OS_SOLARIS
bin_PROGRAMS = \
- sg_format sg_get_config sg_get_lba_status sg_ident \
+ sg_decode_sense sg_format sg_get_config sg_get_lba_status sg_ident \
sg_inq sg_logs sg_luns sg_modes sg_opcodes sg_persist \
sg_prevent sg_raw sg_rdac sg_readcap sg_read_block_limits \
sg_read_buffer sg_read_long sg_reassign sg_referrals sg_requests \
@@ -102,7 +102,7 @@ endif
if OS_OSF
bin_PROGRAMS = \
- sg_format sg_get_config sg_get_lba_status sg_ident \
+ sg_decode_sense sg_format sg_get_config sg_get_lba_status sg_ident \
sg_inq sg_logs sg_luns sg_modes sg_opcodes sg_persist \
sg_prevent sg_raw sg_rdac sg_readcap sg_read_block_limits \
sg_read_buffer sg_read_long sg_reassign sg_referrals sg_requests \
@@ -120,6 +120,9 @@ AM_CFLAGS = -I ../include -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -Wall -W
sg_dd_SOURCES = sg_dd.c
sg_dd_LDADD = ../lib/libsgutils2.la @os_libs@
+sg_decode_sense_SOURCES = sg_decode_sense.c
+sg_decode_sense_LDADD = ../lib/libsgutils2.la @os_libs@
+
sg_emc_trespass_SOURCES = sg_emc_trespass.c
sg_emc_trespass_LDADD = ../lib/libsgutils2.la @os_libs@
diff --git a/src/Makefile.in b/src/Makefile.in
index d3bf315d..8bd80843 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -34,7 +34,8 @@ PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
-@OS_FREEBSD_FALSE@@OS_LINUX_FALSE@@OS_OSF_FALSE@@OS_SOLARIS_FALSE@@OS_WIN32_CYGWIN_FALSE@@OS_WIN32_MINGW_TRUE@bin_PROGRAMS = sg_format$(EXEEXT) \
+@OS_FREEBSD_FALSE@@OS_LINUX_FALSE@@OS_OSF_FALSE@@OS_SOLARIS_FALSE@@OS_WIN32_CYGWIN_FALSE@@OS_WIN32_MINGW_TRUE@bin_PROGRAMS = sg_decode_sense$(EXEEXT) \
+@OS_FREEBSD_FALSE@@OS_LINUX_FALSE@@OS_OSF_FALSE@@OS_SOLARIS_FALSE@@OS_WIN32_CYGWIN_FALSE@@OS_WIN32_MINGW_TRUE@ sg_format$(EXEEXT) \
@OS_FREEBSD_FALSE@@OS_LINUX_FALSE@@OS_OSF_FALSE@@OS_SOLARIS_FALSE@@OS_WIN32_CYGWIN_FALSE@@OS_WIN32_MINGW_TRUE@ sg_get_config$(EXEEXT) \
@OS_FREEBSD_FALSE@@OS_LINUX_FALSE@@OS_OSF_FALSE@@OS_SOLARIS_FALSE@@OS_WIN32_CYGWIN_FALSE@@OS_WIN32_MINGW_TRUE@ sg_get_lba_status$(EXEEXT) \
@OS_FREEBSD_FALSE@@OS_LINUX_FALSE@@OS_OSF_FALSE@@OS_SOLARIS_FALSE@@OS_WIN32_CYGWIN_FALSE@@OS_WIN32_MINGW_TRUE@ sg_ident$(EXEEXT) \
@@ -74,7 +75,8 @@ host_triplet = @host@
@OS_FREEBSD_FALSE@@OS_LINUX_FALSE@@OS_OSF_FALSE@@OS_SOLARIS_FALSE@@OS_WIN32_CYGWIN_FALSE@@OS_WIN32_MINGW_TRUE@ sg_write_long$(EXEEXT) \
@OS_FREEBSD_FALSE@@OS_LINUX_FALSE@@OS_OSF_FALSE@@OS_SOLARIS_FALSE@@OS_WIN32_CYGWIN_FALSE@@OS_WIN32_MINGW_TRUE@ sg_write_same$(EXEEXT) \
@OS_FREEBSD_FALSE@@OS_LINUX_FALSE@@OS_OSF_FALSE@@OS_SOLARIS_FALSE@@OS_WIN32_CYGWIN_FALSE@@OS_WIN32_MINGW_TRUE@ sg_wr_mode$(EXEEXT)
-@OS_FREEBSD_FALSE@@OS_LINUX_FALSE@@OS_OSF_FALSE@@OS_SOLARIS_FALSE@@OS_WIN32_CYGWIN_TRUE@bin_PROGRAMS = sg_format$(EXEEXT) \
+@OS_FREEBSD_FALSE@@OS_LINUX_FALSE@@OS_OSF_FALSE@@OS_SOLARIS_FALSE@@OS_WIN32_CYGWIN_TRUE@bin_PROGRAMS = sg_decode_sense$(EXEEXT) \
+@OS_FREEBSD_FALSE@@OS_LINUX_FALSE@@OS_OSF_FALSE@@OS_SOLARIS_FALSE@@OS_WIN32_CYGWIN_TRUE@ sg_format$(EXEEXT) \
@OS_FREEBSD_FALSE@@OS_LINUX_FALSE@@OS_OSF_FALSE@@OS_SOLARIS_FALSE@@OS_WIN32_CYGWIN_TRUE@ sg_get_config$(EXEEXT) \
@OS_FREEBSD_FALSE@@OS_LINUX_FALSE@@OS_OSF_FALSE@@OS_SOLARIS_FALSE@@OS_WIN32_CYGWIN_TRUE@ sg_get_lba_status$(EXEEXT) \
@OS_FREEBSD_FALSE@@OS_LINUX_FALSE@@OS_OSF_FALSE@@OS_SOLARIS_FALSE@@OS_WIN32_CYGWIN_TRUE@ sg_ident$(EXEEXT) \
@@ -114,7 +116,8 @@ host_triplet = @host@
@OS_FREEBSD_FALSE@@OS_LINUX_FALSE@@OS_OSF_FALSE@@OS_SOLARIS_FALSE@@OS_WIN32_CYGWIN_TRUE@ sg_write_long$(EXEEXT) \
@OS_FREEBSD_FALSE@@OS_LINUX_FALSE@@OS_OSF_FALSE@@OS_SOLARIS_FALSE@@OS_WIN32_CYGWIN_TRUE@ sg_write_same$(EXEEXT) \
@OS_FREEBSD_FALSE@@OS_LINUX_FALSE@@OS_OSF_FALSE@@OS_SOLARIS_FALSE@@OS_WIN32_CYGWIN_TRUE@ sg_wr_mode$(EXEEXT)
-@OS_FREEBSD_FALSE@@OS_LINUX_FALSE@@OS_OSF_FALSE@@OS_SOLARIS_TRUE@bin_PROGRAMS = sg_format$(EXEEXT) \
+@OS_FREEBSD_FALSE@@OS_LINUX_FALSE@@OS_OSF_FALSE@@OS_SOLARIS_TRUE@bin_PROGRAMS = sg_decode_sense$(EXEEXT) \
+@OS_FREEBSD_FALSE@@OS_LINUX_FALSE@@OS_OSF_FALSE@@OS_SOLARIS_TRUE@ sg_format$(EXEEXT) \
@OS_FREEBSD_FALSE@@OS_LINUX_FALSE@@OS_OSF_FALSE@@OS_SOLARIS_TRUE@ sg_get_config$(EXEEXT) \
@OS_FREEBSD_FALSE@@OS_LINUX_FALSE@@OS_OSF_FALSE@@OS_SOLARIS_TRUE@ sg_get_lba_status$(EXEEXT) \
@OS_FREEBSD_FALSE@@OS_LINUX_FALSE@@OS_OSF_FALSE@@OS_SOLARIS_TRUE@ sg_ident$(EXEEXT) \
@@ -153,7 +156,8 @@ host_triplet = @host@
@OS_FREEBSD_FALSE@@OS_LINUX_FALSE@@OS_OSF_FALSE@@OS_SOLARIS_TRUE@ sg_write_long$(EXEEXT) \
@OS_FREEBSD_FALSE@@OS_LINUX_FALSE@@OS_OSF_FALSE@@OS_SOLARIS_TRUE@ sg_write_same$(EXEEXT) \
@OS_FREEBSD_FALSE@@OS_LINUX_FALSE@@OS_OSF_FALSE@@OS_SOLARIS_TRUE@ sg_wr_mode$(EXEEXT)
-@OS_FREEBSD_FALSE@@OS_LINUX_FALSE@@OS_OSF_TRUE@bin_PROGRAMS = sg_format$(EXEEXT) \
+@OS_FREEBSD_FALSE@@OS_LINUX_FALSE@@OS_OSF_TRUE@bin_PROGRAMS = sg_decode_sense$(EXEEXT) \
+@OS_FREEBSD_FALSE@@OS_LINUX_FALSE@@OS_OSF_TRUE@ sg_format$(EXEEXT) \
@OS_FREEBSD_FALSE@@OS_LINUX_FALSE@@OS_OSF_TRUE@ sg_get_config$(EXEEXT) \
@OS_FREEBSD_FALSE@@OS_LINUX_FALSE@@OS_OSF_TRUE@ sg_get_lba_status$(EXEEXT) \
@OS_FREEBSD_FALSE@@OS_LINUX_FALSE@@OS_OSF_TRUE@ sg_ident$(EXEEXT) \
@@ -193,6 +197,7 @@ host_triplet = @host@
@OS_FREEBSD_FALSE@@OS_LINUX_FALSE@@OS_OSF_TRUE@ sg_write_same$(EXEEXT) \
@OS_FREEBSD_FALSE@@OS_LINUX_FALSE@@OS_OSF_TRUE@ sg_wr_mode$(EXEEXT)
@OS_FREEBSD_FALSE@@OS_LINUX_TRUE@bin_PROGRAMS = sg_dd$(EXEEXT) \
+@OS_FREEBSD_FALSE@@OS_LINUX_TRUE@ sg_decode_sense$(EXEEXT) \
@OS_FREEBSD_FALSE@@OS_LINUX_TRUE@ sg_emc_trespass$(EXEEXT) \
@OS_FREEBSD_FALSE@@OS_LINUX_TRUE@ sg_format$(EXEEXT) \
@OS_FREEBSD_FALSE@@OS_LINUX_TRUE@ sg_get_config$(EXEEXT) \
@@ -243,8 +248,8 @@ host_triplet = @host@
@OS_FREEBSD_FALSE@@OS_LINUX_TRUE@ sg_write_long$(EXEEXT) \
@OS_FREEBSD_FALSE@@OS_LINUX_TRUE@ sg_write_same$(EXEEXT) \
@OS_FREEBSD_FALSE@@OS_LINUX_TRUE@ sg_wr_mode$(EXEEXT)
-@OS_FREEBSD_TRUE@bin_PROGRAMS = sg_format$(EXEEXT) \
-@OS_FREEBSD_TRUE@ sg_get_config$(EXEEXT) \
+@OS_FREEBSD_TRUE@bin_PROGRAMS = sg_decode_sense$(EXEEXT) \
+@OS_FREEBSD_TRUE@ sg_format$(EXEEXT) sg_get_config$(EXEEXT) \
@OS_FREEBSD_TRUE@ sg_get_lba_status$(EXEEXT) sg_ident$(EXEEXT) \
@OS_FREEBSD_TRUE@ sg_inq$(EXEEXT) sg_logs$(EXEEXT) \
@OS_FREEBSD_TRUE@ sg_luns$(EXEEXT) sg_modes$(EXEEXT) \
@@ -281,6 +286,9 @@ PROGRAMS = $(bin_PROGRAMS)
am_sg_dd_OBJECTS = sg_dd.$(OBJEXT)
sg_dd_OBJECTS = $(am_sg_dd_OBJECTS)
sg_dd_DEPENDENCIES = ../lib/libsgutils2.la
+am_sg_decode_sense_OBJECTS = sg_decode_sense.$(OBJEXT)
+sg_decode_sense_OBJECTS = $(am_sg_decode_sense_OBJECTS)
+sg_decode_sense_DEPENDENCIES = ../lib/libsgutils2.la
am_sg_emc_trespass_OBJECTS = sg_emc_trespass.$(OBJEXT)
sg_emc_trespass_OBJECTS = $(am_sg_emc_trespass_OBJECTS)
sg_emc_trespass_DEPENDENCIES = ../lib/libsgutils2.la
@@ -444,14 +452,14 @@ CCLD = $(CC)
LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
--mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
$(LDFLAGS) -o $@
-SOURCES = $(sg_dd_SOURCES) $(sg_emc_trespass_SOURCES) \
- $(sg_format_SOURCES) $(sg_get_config_SOURCES) \
- $(sg_get_lba_status_SOURCES) $(sg_ident_SOURCES) \
- $(sg_inq_SOURCES) $(sg_logs_SOURCES) $(sg_luns_SOURCES) \
- $(sg_map_SOURCES) $(sg_map26_SOURCES) $(sg_modes_SOURCES) \
- $(sg_opcodes_SOURCES) $(sg_persist_SOURCES) \
- $(sg_prevent_SOURCES) $(sg_raw_SOURCES) $(sg_rbuf_SOURCES) \
- $(sg_rdac_SOURCES) $(sg_read_SOURCES) \
+SOURCES = $(sg_dd_SOURCES) $(sg_decode_sense_SOURCES) \
+ $(sg_emc_trespass_SOURCES) $(sg_format_SOURCES) \
+ $(sg_get_config_SOURCES) $(sg_get_lba_status_SOURCES) \
+ $(sg_ident_SOURCES) $(sg_inq_SOURCES) $(sg_logs_SOURCES) \
+ $(sg_luns_SOURCES) $(sg_map_SOURCES) $(sg_map26_SOURCES) \
+ $(sg_modes_SOURCES) $(sg_opcodes_SOURCES) \
+ $(sg_persist_SOURCES) $(sg_prevent_SOURCES) $(sg_raw_SOURCES) \
+ $(sg_rbuf_SOURCES) $(sg_rdac_SOURCES) $(sg_read_SOURCES) \
$(sg_read_block_limits_SOURCES) $(sg_read_buffer_SOURCES) \
$(sg_read_long_SOURCES) $(sg_readcap_SOURCES) \
$(sg_reassign_SOURCES) $(sg_referrals_SOURCES) \
@@ -466,14 +474,14 @@ SOURCES = $(sg_dd_SOURCES) $(sg_emc_trespass_SOURCES) \
$(sg_write_buffer_SOURCES) $(sg_write_long_SOURCES) \
$(sg_write_same_SOURCES) $(sginfo_SOURCES) $(sgm_dd_SOURCES) \
$(sgp_dd_SOURCES)
-DIST_SOURCES = $(sg_dd_SOURCES) $(sg_emc_trespass_SOURCES) \
- $(sg_format_SOURCES) $(sg_get_config_SOURCES) \
- $(sg_get_lba_status_SOURCES) $(sg_ident_SOURCES) \
- $(sg_inq_SOURCES) $(sg_logs_SOURCES) $(sg_luns_SOURCES) \
- $(sg_map_SOURCES) $(sg_map26_SOURCES) $(sg_modes_SOURCES) \
- $(sg_opcodes_SOURCES) $(sg_persist_SOURCES) \
- $(sg_prevent_SOURCES) $(sg_raw_SOURCES) $(sg_rbuf_SOURCES) \
- $(sg_rdac_SOURCES) $(sg_read_SOURCES) \
+DIST_SOURCES = $(sg_dd_SOURCES) $(sg_decode_sense_SOURCES) \
+ $(sg_emc_trespass_SOURCES) $(sg_format_SOURCES) \
+ $(sg_get_config_SOURCES) $(sg_get_lba_status_SOURCES) \
+ $(sg_ident_SOURCES) $(sg_inq_SOURCES) $(sg_logs_SOURCES) \
+ $(sg_luns_SOURCES) $(sg_map_SOURCES) $(sg_map26_SOURCES) \
+ $(sg_modes_SOURCES) $(sg_opcodes_SOURCES) \
+ $(sg_persist_SOURCES) $(sg_prevent_SOURCES) $(sg_raw_SOURCES) \
+ $(sg_rbuf_SOURCES) $(sg_rdac_SOURCES) $(sg_read_SOURCES) \
$(sg_read_block_limits_SOURCES) $(sg_read_buffer_SOURCES) \
$(sg_read_long_SOURCES) $(sg_readcap_SOURCES) \
$(sg_reassign_SOURCES) $(sg_referrals_SOURCES) \
@@ -609,6 +617,8 @@ AM_CFLAGS = -I ../include -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -Wall -W
# AM_CFLAGS = -I ../include -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -Wall -W -pedantic -std=c99
sg_dd_SOURCES = sg_dd.c
sg_dd_LDADD = ../lib/libsgutils2.la @os_libs@
+sg_decode_sense_SOURCES = sg_decode_sense.c
+sg_decode_sense_LDADD = ../lib/libsgutils2.la @os_libs@
sg_emc_trespass_SOURCES = sg_emc_trespass.c
sg_emc_trespass_LDADD = ../lib/libsgutils2.la @os_libs@
sg_format_SOURCES = sg_format.c
@@ -789,6 +799,9 @@ clean-binPROGRAMS:
sg_dd$(EXEEXT): $(sg_dd_OBJECTS) $(sg_dd_DEPENDENCIES)
@rm -f sg_dd$(EXEEXT)
$(LINK) $(sg_dd_OBJECTS) $(sg_dd_LDADD) $(LIBS)
+sg_decode_sense$(EXEEXT): $(sg_decode_sense_OBJECTS) $(sg_decode_sense_DEPENDENCIES)
+ @rm -f sg_decode_sense$(EXEEXT)
+ $(LINK) $(sg_decode_sense_OBJECTS) $(sg_decode_sense_LDADD) $(LIBS)
sg_emc_trespass$(EXEEXT): $(sg_emc_trespass_OBJECTS) $(sg_emc_trespass_DEPENDENCIES)
@rm -f sg_emc_trespass$(EXEEXT)
$(LINK) $(sg_emc_trespass_OBJECTS) $(sg_emc_trespass_LDADD) $(LIBS)
@@ -947,6 +960,7 @@ distclean-compile:
-rm -f *.tab.c
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sg_dd.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sg_decode_sense.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sg_emc_trespass.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sg_format.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sg_get_config.Po@am__quote@
diff --git a/src/sg_decode_sense.c b/src/sg_decode_sense.c
new file mode 100644
index 00000000..b068418f
--- /dev/null
+++ b/src/sg_decode_sense.c
@@ -0,0 +1,356 @@
+/*
+ * Copyright (c) 2010-2011 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.
+ */
+
+#include <unistd.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <limits.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <getopt.h>
+#define __STDC_FORMAT_MACROS 1
+#include <inttypes.h>
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include "sg_lib.h"
+
+
+static char * version_str = "1.00 20101204";
+
+#define MAX_SENSE_LEN (256 + 8) /* max descriptor format currently */
+
+static struct option long_options[] = {
+ {"binary", required_argument, 0, 'b'},
+ {"help", no_argument, 0, 'h'},
+ {"hex", required_argument, 0, 'H'},
+ {"status", required_argument, 0, 's'},
+ {"verbose", no_argument, 0, 'v'},
+ {"version", no_argument, 0, 'V'},
+ {"write", required_argument, 0, 'w'},
+ {0, 0, 0, 0},
+};
+
+struct opts_t {
+ int do_binary;
+ const char * fname;
+ int do_help;
+ int do_hex;
+ int do_status;
+ int sstatus;
+ int do_verbose;
+ int do_version;
+ const char * wfname;
+ unsigned char sense[MAX_SENSE_LEN + 4];
+ int sense_len;
+};
+
+
+static void
+usage()
+{
+ fprintf(stderr, "Usage: "
+ "sg_decode_sense [--binary=FN] [--help] [--hex=FN] [--status=SS]\n"
+ " [--verbose] [--version] [--write=WFN] "
+ "H1 H2 H3 ...\n"
+ " where:\n"
+ " --binary=FN|-b FN FN is a file name to read sense "
+ "data in\n"
+ " binary from. If FN is '-' then read "
+ "from stdin\n"
+ " --help|-h print out usage message\n"
+ " --hex=FN|-H FN FN is a file name from which to read "
+ "sense data\n"
+ " in ASCII hexadecimal. Interpret '-' "
+ "as stdin\n"
+ " --status=SS |-s SS SCSI status value in hex\n"
+ " --verbose|-v increase verbosity\n"
+ " --version|-V print version string then exit\n"
+ " --write=WFN |-w WFN write sense data in binary to WFN, "
+ "create if\n"
+ " required else truncate prior to "
+ "writing\n\n"
+ "Decodes SCSI sense data given on the command line as a sequence "
+ "of\nhexadecimal bytes (H1 H2 H3 ...) . Alternatively the sense "
+ "data can\nbe in a binary file or in a file containing ASCII "
+ "hexadecimal.\n"
+ );
+}
+
+static int
+process_cl(struct opts_t *optsp, int argc, char *argv[])
+{
+ int c;
+ unsigned int ul;
+ char * opt;
+ char *endptr;
+ long val;
+
+ while (1) {
+ c = getopt_long(argc, argv, "b:hH:s:vVw:", long_options, NULL);
+ if (c == -1)
+ break;
+
+ switch (c) {
+ case 'b':
+ if (optsp->fname) {
+ fprintf(stderr, "expect only one '--binary=FN' or "
+ "'--hex=FN' option\n");
+ return SG_LIB_SYNTAX_ERROR;
+ }
+ ++optsp->do_binary;
+ optsp->fname = optarg;
+ break;
+ case 'h':
+ case '?':
+ optsp->do_help = 1;
+ return 0;
+ case 'H':
+ if (optsp->fname) {
+ fprintf(stderr, "expect only one '--binary=FN' or "
+ "'--hex=FN' option\n");
+ return SG_LIB_SYNTAX_ERROR;
+ }
+ ++optsp->do_hex;
+ optsp->fname = optarg;
+ break;
+ case 's':
+ if (1 != sscanf(optarg, "%x", &ul)) {
+ fprintf(stderr, "'--status=SS' expects a byte value\n");
+ return SG_LIB_SYNTAX_ERROR;
+ }
+ if (ul > 0xff) {
+ fprintf(stderr, "'--status=SS' byte value exceeds FF\n");
+ return SG_LIB_SYNTAX_ERROR;
+ }
+ ++optsp->do_status;
+ optsp->sstatus = ul;
+ break;
+ case 'v':
+ ++optsp->do_verbose;
+ break;
+ case 'V':
+ optsp->do_version = 1;
+ return 0;
+ case 'w':
+ optsp->wfname = optarg;
+ break;
+ default:
+ return SG_LIB_SYNTAX_ERROR;
+ }
+ }
+
+ while (optind < argc) {
+ opt = argv[optind++];
+ val = strtol(opt, &endptr, 16);
+ if (*opt == '\0' || *endptr != '\0' || val < 0x00 || val > 0xff) {
+ fprintf(stderr, "Invalid byte '%s'\n", opt);
+ return SG_LIB_SYNTAX_ERROR;
+ }
+
+ if (optsp->sense_len > MAX_SENSE_LEN) {
+ fprintf(stderr, "sense data too long (max. %d bytes)\n",
+ MAX_SENSE_LEN);
+ return SG_LIB_SYNTAX_ERROR;
+ }
+ optsp->sense[optsp->sense_len++] = (unsigned char)val;
+ }
+ return 0;
+}
+
+/* Read hex numbers from file ('-' taken as stdin).
+ * There should be either one entry per line, a comma separated list or
+ * space separated list. Everything from and including a '#' on a line
+ * is ignored. Returns 0 if ok, or 1 if error. */
+static int file2hex_arr(const char * fname, unsigned char * mp_arr,
+ int * mp_arr_len, int max_arr_len)
+{
+ int fn_len, in_len, k, j, m;
+ unsigned int h;
+ const char * lcp;
+ FILE * fp;
+ char line[512];
+ int off = 0;
+
+ if ((NULL == fname) || (NULL == mp_arr) || (NULL == mp_arr_len))
+ return 1;
+ fn_len = strlen(fname);
+ if (0 == fn_len)
+ return 1;
+ if ((1 == in_len) && ('-' == fname[0])) /* read from stdin */
+ fp = stdin;
+ else {
+ fp = fopen(fname, "r");
+ if (NULL == fp) {
+ fprintf(stderr, "Unable to open %s for reading\n", fname);
+ return 1;
+ }
+ }
+
+ for (j = 0; j < 512; ++j) {
+ if (NULL == fgets(line, sizeof(line), fp))
+ break;
+ in_len = strlen(line);
+ if (in_len > 0) {
+ if ('\n' == line[in_len - 1]) {
+ --in_len;
+ line[in_len] = '\0';
+ }
+ }
+ if (0 == in_len)
+ continue;
+ lcp = line;
+ m = strspn(lcp, " \t");
+ if (m == in_len)
+ continue;
+ lcp += m;
+ in_len -= m;
+ if ('#' == *lcp)
+ continue;
+ k = strspn(lcp, "0123456789aAbBcCdDeEfF ,\t");
+ if ((k < in_len) && ('#' != lcp[k])) {
+ fprintf(stderr, "build_mode_page: syntax error at "
+ "line %d, pos %d\n", j + 1, m + k + 1);
+ goto bad;
+ }
+ for (k = 0; k < 1024; ++k) {
+ if (1 == sscanf(lcp, "%x", &h)) {
+ if (h > 0xff) {
+ fprintf(stderr, "build_mode_page: hex number "
+ "larger than 0xff in line %d, pos %d\n",
+ j + 1, (int)(lcp - line + 1));
+ goto bad;
+ }
+ if ((off + k) >= max_arr_len) {
+ fprintf(stderr, "build_mode_page: array length "
+ "exceeded\n");
+ goto bad;
+ }
+ mp_arr[off + k] = h;
+ lcp = strpbrk(lcp, " ,\t");
+ if (NULL == lcp)
+ break;
+ lcp += strspn(lcp, " ,\t");
+ if ('\0' == *lcp)
+ break;
+ } else {
+ if ('#' == *lcp) {
+ --k;
+ break;
+ }
+ fprintf(stderr, "build_mode_page: error in "
+ "line %d, at pos %d\n", j + 1,
+ (int)(lcp - line + 1));
+ goto bad;
+ }
+ }
+ off += (k + 1);
+ }
+ *mp_arr_len = off;
+ fclose(fp);
+ return 0;
+bad:
+ fclose(fp);
+ return 1;
+}
+
+
+int
+main(int argc, char *argv[])
+{
+ int ret = 0;
+ size_t s;
+ struct opts_t opts;
+ char b[2048];
+ FILE * fp = NULL;
+
+ memset(&opts, 0, sizeof(opts));
+ memset(b, 0, sizeof(b));
+ ret = process_cl(&opts, argc, argv);
+ if (ret != 0) {
+ usage();
+ return ret;
+ } else if (opts.do_help) {
+ usage();
+ return 0;
+ } else if (opts.do_version) {
+ fprintf(stderr, "version: %s\n", version_str);
+ return 0;
+ }
+
+
+ if (opts.do_status) {
+ sg_get_scsi_status_str(opts.sstatus, sizeof(b) - 1, b);
+ printf("SCSI status: %s\n", b);
+ }
+
+ if ((0 == opts.sense_len) && (! opts.do_binary) && (! opts.do_hex)) {
+ if (opts.do_status)
+ return 0;
+ fprintf(stderr, ">> Need sense data on the command line or in a "
+ "file\n\n");
+ usage();
+ return SG_LIB_SYNTAX_ERROR;
+ }
+ if (opts.sense_len && (opts.do_binary || opts.do_hex)) {
+ fprintf(stderr, ">> Need sense data on command line or in a file, "
+ "not both\n\n");
+ return SG_LIB_SYNTAX_ERROR;
+ }
+ if (opts.do_binary && opts.do_hex) {
+ fprintf(stderr, ">> Either a binary file or a ASCII hexadecimal, "
+ "file not both\n\n");
+ return SG_LIB_SYNTAX_ERROR;
+ }
+
+ if (opts.do_binary) {
+ fp = fopen(opts.fname, "r");
+ if (NULL == fp) {
+ fprintf(stderr, "unable to open file: %s\n", opts.fname);
+ return SG_LIB_SYNTAX_ERROR;
+ }
+ s = fread(opts.sense, 1, MAX_SENSE_LEN, fp);
+ fclose(fp);
+ if (0 == s) {
+ fprintf(stderr, "read nothing from file: %s\n", opts.fname);
+ return SG_LIB_SYNTAX_ERROR;
+ }
+ opts.sense_len = s;
+ } else if (opts.do_hex) {
+ ret = file2hex_arr(opts.fname, opts.sense, &opts.sense_len,
+ MAX_SENSE_LEN);
+ if (ret) {
+ fprintf(stderr, "unable to decode ASCII hex from file: %s\n",
+ opts.fname);
+ return SG_LIB_SYNTAX_ERROR;
+ }
+ }
+
+ if (opts.sense_len) {
+ if (opts.wfname) {
+ if ((fp = fopen(opts.wfname, "w"))) {
+ s = fwrite(opts.sense, 1, opts.sense_len, fp);
+ if ((int)s != opts.sense_len)
+ fprintf(stderr, "only able to write %d of %d bytes to "
+ "%s\n", s, opts.sense_len, opts.wfname);
+ fclose(fp);
+ } else {
+ perror("open");
+ fprintf(stderr, "trying to write to %s\n", opts.wfname);
+ }
+ }
+ sg_get_sense_str(NULL, opts.sense, opts.sense_len, opts.do_verbose,
+ sizeof(b) - 1, b);
+ printf("%s\n", b);
+ }
+
+ return 0;
+}
diff --git a/src/sg_format.c b/src/sg_format.c
index d92d4b60..be41a468 100644
--- a/src/sg_format.c
+++ b/src/sg_format.c
@@ -45,7 +45,7 @@
#include "sg_cmds_basic.h"
#include "sg_cmds_extra.h"
-static char * version_str = "1.18 20101030";
+static char * version_str = "1.19 20101203";
#define RW_ERROR_RECOVERY_PAGE 1 /* every disk should have one */
#define FORMAT_DEV_PAGE 3 /* Format Device Mode Page [now obsolete] */
@@ -54,9 +54,10 @@ static char * version_str = "1.18 20101030";
#define THIS_MPAGE_EXISTS RW_ERROR_RECOVERY_PAGE
#define SHORT_TIMEOUT 20 /* 20 seconds unless immed=0 ... */
-#define FORMAT_TIMEOUT (4 * 3600) /* 4 hours ! */
+#define FORMAT_TIMEOUT (15 * 3600) /* 15 hours ! */
+ /* Seagate ST32000444SS 2TB disk takes 9.5 hours */
-#define POLL_DURATION_SECS 30
+#define POLL_DURATION_SECS 60
#if defined(MSC_VER) || defined(__MINGW32__)
#define HAVE_MS_SLEEP
@@ -168,7 +169,7 @@ static int
scsi_format(int fd, int fmtpinfo, int cmplst, int pf_usage, int immed,
int dcrt, int pie, int si, int early, int verbose)
{
- int res, need_hdr, progress, verb, fmt_pl_sz, longlist, off;
+ int res, need_hdr, progress, pr, rem, verb, fmt_pl_sz, longlist, off;
const int SH_FORMAT_HEADER_SZ = 4;
const int LO_FORMAT_HEADER_SZ = 8;
const char INIT_PATTERN_DESC_SZ = 4;
@@ -241,10 +242,12 @@ scsi_format(int fd, int fmtpinfo, int cmplst, int pf_usage, int immed,
progress = -1;
res = sg_ll_test_unit_ready_progress(fd, 0, &progress, 0,
verb);
- if (progress >= 0)
- printf("Format in progress, %d%% done\n",
- (progress * 100) / 65536);
- else
+ if (progress >= 0) {
+ pr = (progress * 100) / 65536;
+ rem = ((progress * 100) % 65536) / 655;
+ printf("Format in progress, %d.%02d%% done\n",
+ pr, rem);
+ } else
break;
}
printf("FORMAT Complete\n");
diff --git a/src/sg_inq.c b/src/sg_inq.c
index 619534b6..2ed2c9c9 100644
--- a/src/sg_inq.c
+++ b/src/sg_inq.c
@@ -66,7 +66,7 @@
* information [MAINTENANCE IN, service action = 0xc]; see sg_opcodes.
*/
-static char * version_str = "0.94 20101030"; /* SPC-4 rev 27 */
+static char * version_str = "0.95 20101116"; /* SPC-4 rev 28 */
#define VPD_SUPPORTED_VPDS 0x0
diff --git a/src/sg_inq_data.c b/src/sg_inq_data.c
index 113a901d..1e925fc5 100644
--- a/src/sg_inq_data.c
+++ b/src/sg_inq_data.c
@@ -23,9 +23,9 @@
const char * sg_ansi_version_arr[] =
{
"no conformance claimed",
- "SCSI-1", /* obsolete */
- "SCSI-2", /* obsolete */
- "SPC", /* withdrawn */
+ "SCSI-1", /* obsolete */
+ "SCSI-2", /* obsolete */
+ "SPC", /* withdrawn */
"SPC-2",
"SPC-3",
"SPC-4",
@@ -39,7 +39,7 @@ struct sg_version_descriptor {
const char * name;
};
-/* table from SPC-4 revision 27 [sorted numerically (from Annex D.8)] */
+/* table from SPC-4 revision 28 [sorted numerically (from Annex D.8)] */
/* Can also be obtained from : http://www.t10.org/lists/stds.txt */
struct sg_version_descriptor sg_version_descriptor_arr[] = {
{0x0, "Version Descriptor not supported or No standard identified"},
@@ -184,6 +184,7 @@ struct sg_version_descriptor sg_version_descriptor_arr[] = {
{0x4e3, "MMC-6 T10/1836-D revision 2b"},
{0x4e5, "MMC-6 T10/1836-D revision 02g"},
{0x500, "ADC-3 (no version claimed)"},
+ {0x502, "ADC-3 T10/1895-D revision 04"},
{0x520, "SSC-4 (no version claimed)"},
{0x560, "OSD-3 (no version claimed)"},
{0x580, "SES-3 (no version claimed)"},
@@ -215,11 +216,7 @@ struct sg_version_descriptor sg_version_descriptor_arr[] = {
{0x917, "FCP-2 ANSI INCITS 350-2003"},
{0x918, "FCP-2 T10/1144-D revision 8"},
{0x920, "SST (no version claimed)"},
- {0x935, "SST T10/1380-D revision 8b"},
- {0x940, "SRP (no version claimed)"},
- {0x954, "SRP T10/1415-D revision 10"},
- {0x955, "SRP T10/1415-D revision 16a"},
- {0x95c, "SRP ANSI INCITS 365-2002"},
+ {0x935, "SST T10/1380-D revision 8b"}, {0x940, "SRP (no version claimed)"}, {0x954, "SRP T10/1415-D revision 10"}, {0x955, "SRP T10/1415-D revision 16a"}, {0x95c, "SRP ANSI INCITS 365-2002"},
{0x960, "iSCSI (no version claimed)"},
{0x980, "SBP-3 (no version claimed)"},
{0x982, "SBP-3 T10/1467-D revision 1f"},
@@ -243,6 +240,7 @@ struct sg_version_descriptor sg_version_descriptor_arr[] = {
{0xa27, "ADT-2 T10/1742-D revision 08"},
{0xa40, "FCP-4 (no version claimed)"},
{0xa42, "FCP-4 T10/1828-D revision 01"},
+ {0xa44, "FCP-4 T10/1828-D revision 02"},
{0xaa0, "SPI (no version claimed)"},
{0xab9, "SPI T10/0855-D revision 15a"},
{0xaba, "SPI ANSI INCITS 253-1995"},
diff --git a/src/sg_turs.c b/src/sg_turs.c
index 933fb66f..f3611702 100644
--- a/src/sg_turs.c
+++ b/src/sg_turs.c
@@ -21,7 +21,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-2009 D. Gilbert
+ * Copyright (C) 2000-2010 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 @@
*/
-static char * version_str = "3.27 20090422";
+static char * version_str = "3.28 20101203";
#if defined(MSC_VER) || defined(__MINGW32__)
#define HAVE_MS_SLEEP
@@ -265,7 +265,7 @@ static int process_cl(struct opts_t * optsp, int argc, char * argv[])
int main(int argc, char * argv[])
{
- int sg_fd, k, res, progress;
+ int sg_fd, k, res, progress, pr, rem;
int num_errs = 0;
int reported = 0;
int ret = 0;
@@ -310,9 +310,11 @@ int main(int argc, char * argv[])
if (progress < 0) {
ret = res;
break;
- } else
- printf("Progress indication: %d%% done\n",
- (progress * 100) / 65536);
+ } else {
+ pr = (progress * 100) / 65536;
+ rem = ((progress * 100) % 65536) / 655;
+ printf("Progress indication: %d.%02d%% done\n", pr, rem);
+ }
}
if (opts.do_number > 1)
printf("Completed %d Test Unit Ready commands\n",