diff options
author | Douglas Gilbert <dgilbert@interlog.com> | 2010-12-06 02:27:23 +0000 |
---|---|---|
committer | Douglas Gilbert <dgilbert@interlog.com> | 2010-12-06 02:27:23 +0000 |
commit | 3c60a8b8991001fe80ffdd95ca77bcce40b035eb (patch) | |
tree | c853891eab503ca2a6187d4623602f19b8a935be /src | |
parent | 02f2be1ee0e44a84cbdfa510ea11db9bcb4275ce (diff) | |
download | sg3_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.am | 19 | ||||
-rw-r--r-- | src/Makefile.in | 58 | ||||
-rw-r--r-- | src/sg_decode_sense.c | 356 | ||||
-rw-r--r-- | src/sg_format.c | 19 | ||||
-rw-r--r-- | src/sg_inq.c | 2 | ||||
-rw-r--r-- | src/sg_inq_data.c | 16 | ||||
-rw-r--r-- | src/sg_turs.c | 14 |
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", |