diff options
author | Douglas Gilbert <dgilbert@interlog.com> | 2008-02-18 04:20:32 +0000 |
---|---|---|
committer | Douglas Gilbert <dgilbert@interlog.com> | 2008-02-18 04:20:32 +0000 |
commit | 7f650dbfa7e4bab6cf5bf03674effa193049f343 (patch) | |
tree | 86b1872411b2fca7cfeb8eff5ef57f3d6d8d4424 /lib | |
parent | 5f3f44b9a68939ceb2097e630cf6026a927569a0 (diff) | |
download | sg3_utils-7f650dbfa7e4bab6cf5bf03674effa193049f343.tar.gz |
move sg_io_linux.c from the src/ to the lib/ directory
git-svn-id: https://svn.bingwo.ca/repos/sg3_utils/trunk@151 6180dd3e-e324-4e3e-922d-17de1ae2f315
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Makefile.am | 8 | ||||
-rw-r--r-- | lib/Makefile.in | 19 | ||||
-rw-r--r-- | lib/sg_io_linux.c | 252 |
3 files changed, 272 insertions, 7 deletions
diff --git a/lib/Makefile.am b/lib/Makefile.am index 7f730470..b5e7c136 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -7,7 +7,8 @@ libsgutils_la_SOURCES = \ sg_lib_data.c \ sg_cmds_basic.c \ sg_cmds_extra.c \ - sg_pt_linux.c + sg_pt_linux.c \ + sg_io_linux.c EXTRA_libsgutils_la_SOURCES = \ sg_pt_freebsd.c \ @@ -30,6 +31,7 @@ libsgutils_la_SOURCES = \ EXTRA_libsgutils_la_SOURCES = \ sg_pt_linux.c \ + sg_io_linux.c \ sg_pt_freebsd.c \ sg_pt_osf1.c \ sg_pt_solaris.c \ @@ -49,6 +51,7 @@ libsgutils_la_SOURCES = \ EXTRA_libsgutils_la_SOURCES = \ sg_pt_linux.c \ + sg_io_linux.c \ sg_pt_freebsd.c \ sg_pt_osf1.c \ sg_pt_solaris.c \ @@ -68,6 +71,7 @@ libsgutils_la_SOURCES = \ EXTRA_libsgutils_la_SOURCES = \ sg_pt_linux.c \ + sg_io_linux.c \ sg_linux_inc.h \ sg_pt_osf1.c \ sg_pt_solaris.c \ @@ -88,6 +92,7 @@ libsgutils_la_SOURCES = \ EXTRA_libsgutils_la_SOURCES = \ sg_pt_linux.c \ + sg_io_linux.c \ sg_linux_inc.h \ sg_pt_freebsd.c \ sg_pt_osf1.c \ @@ -108,6 +113,7 @@ libsgutils_la_SOURCES = \ EXTRA_libsgutils_la_SOURCES = \ sg_pt_linux.c \ + sg_io_linux.c \ sg_pt_freebsd.c \ sg_pt_solaris.c \ sg_pt_win32.c \ diff --git a/lib/Makefile.in b/lib/Makefile.in index 4bae8444..b255c900 100644 --- a/lib/Makefile.in +++ b/lib/Makefile.in @@ -52,7 +52,7 @@ libLTLIBRARIES_INSTALL = $(INSTALL) LTLIBRARIES = $(lib_LTLIBRARIES) am__libsgutils_la_SOURCES_DIST = sg_lib.c sg_lib_data.c \ sg_cmds_basic.c sg_cmds_extra.c sg_pt_freebsd.c sg_pt_linux.c \ - sg_pt_osf1.c sg_pt_solaris.c sg_pt_win32.c + sg_io_linux.c sg_pt_osf1.c sg_pt_solaris.c sg_pt_win32.c @OS_FREEBSD_FALSE@@OS_LINUX_FALSE@@OS_OSF_FALSE@@OS_SOLARIS_FALSE@@OS_WIN32_CYGWIN_FALSE@@OS_WIN32_MINGW_TRUE@am_libsgutils_la_OBJECTS = sg_lib.lo \ @OS_FREEBSD_FALSE@@OS_LINUX_FALSE@@OS_OSF_FALSE@@OS_SOLARIS_FALSE@@OS_WIN32_CYGWIN_FALSE@@OS_WIN32_MINGW_TRUE@ sg_lib_data.lo \ @OS_FREEBSD_FALSE@@OS_LINUX_FALSE@@OS_OSF_FALSE@@OS_SOLARIS_FALSE@@OS_WIN32_CYGWIN_FALSE@@OS_WIN32_MINGW_TRUE@ sg_cmds_basic.lo \ @@ -78,13 +78,13 @@ am__libsgutils_la_SOURCES_DIST = sg_lib.c sg_lib_data.c \ @OS_FREEBSD_FALSE@@OS_LINUX_TRUE@ sg_lib_data.lo \ @OS_FREEBSD_FALSE@@OS_LINUX_TRUE@ sg_cmds_basic.lo \ @OS_FREEBSD_FALSE@@OS_LINUX_TRUE@ sg_cmds_extra.lo \ -@OS_FREEBSD_FALSE@@OS_LINUX_TRUE@ sg_pt_linux.lo +@OS_FREEBSD_FALSE@@OS_LINUX_TRUE@ sg_pt_linux.lo sg_io_linux.lo @OS_FREEBSD_TRUE@am_libsgutils_la_OBJECTS = sg_lib.lo sg_lib_data.lo \ @OS_FREEBSD_TRUE@ sg_cmds_basic.lo sg_cmds_extra.lo \ @OS_FREEBSD_TRUE@ sg_pt_freebsd.lo -am__EXTRA_libsgutils_la_SOURCES_DIST = sg_pt_linux.c sg_linux_inc.h \ - sg_pt_osf1.c sg_pt_solaris.c sg_pt_win32.c getopt_long.c \ - sg_pt_freebsd.c +am__EXTRA_libsgutils_la_SOURCES_DIST = sg_pt_linux.c sg_io_linux.c \ + sg_linux_inc.h sg_pt_osf1.c sg_pt_solaris.c sg_pt_win32.c \ + getopt_long.c sg_pt_freebsd.c libsgutils_la_OBJECTS = $(am_libsgutils_la_OBJECTS) libsgutils_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ @@ -227,7 +227,8 @@ top_srcdir = @top_srcdir@ @OS_LINUX_TRUE@ sg_lib_data.c \ @OS_LINUX_TRUE@ sg_cmds_basic.c \ @OS_LINUX_TRUE@ sg_cmds_extra.c \ -@OS_LINUX_TRUE@ sg_pt_linux.c +@OS_LINUX_TRUE@ sg_pt_linux.c \ +@OS_LINUX_TRUE@ sg_io_linux.c @OS_OSF_TRUE@libsgutils_la_SOURCES = \ @OS_OSF_TRUE@ sg_lib.c \ @@ -259,6 +260,7 @@ top_srcdir = @top_srcdir@ @OS_FREEBSD_TRUE@EXTRA_libsgutils_la_SOURCES = \ @OS_FREEBSD_TRUE@ sg_pt_linux.c \ +@OS_FREEBSD_TRUE@ sg_io_linux.c \ @OS_FREEBSD_TRUE@ sg_linux_inc.h \ @OS_FREEBSD_TRUE@ sg_pt_osf1.c \ @OS_FREEBSD_TRUE@ sg_pt_solaris.c \ @@ -274,6 +276,7 @@ top_srcdir = @top_srcdir@ @OS_OSF_TRUE@EXTRA_libsgutils_la_SOURCES = \ @OS_OSF_TRUE@ sg_pt_linux.c \ +@OS_OSF_TRUE@ sg_io_linux.c \ @OS_OSF_TRUE@ sg_pt_freebsd.c \ @OS_OSF_TRUE@ sg_pt_solaris.c \ @OS_OSF_TRUE@ sg_pt_win32.c \ @@ -281,6 +284,7 @@ top_srcdir = @top_srcdir@ @OS_SOLARIS_TRUE@EXTRA_libsgutils_la_SOURCES = \ @OS_SOLARIS_TRUE@ sg_pt_linux.c \ +@OS_SOLARIS_TRUE@ sg_io_linux.c \ @OS_SOLARIS_TRUE@ sg_linux_inc.h \ @OS_SOLARIS_TRUE@ sg_pt_freebsd.c \ @OS_SOLARIS_TRUE@ sg_pt_osf1.c \ @@ -289,6 +293,7 @@ top_srcdir = @top_srcdir@ @OS_WIN32_CYGWIN_TRUE@EXTRA_libsgutils_la_SOURCES = \ @OS_WIN32_CYGWIN_TRUE@ sg_pt_linux.c \ +@OS_WIN32_CYGWIN_TRUE@ sg_io_linux.c \ @OS_WIN32_CYGWIN_TRUE@ sg_pt_freebsd.c \ @OS_WIN32_CYGWIN_TRUE@ sg_pt_osf1.c \ @OS_WIN32_CYGWIN_TRUE@ sg_pt_solaris.c \ @@ -296,6 +301,7 @@ top_srcdir = @top_srcdir@ @OS_WIN32_MINGW_TRUE@EXTRA_libsgutils_la_SOURCES = \ @OS_WIN32_MINGW_TRUE@ sg_pt_linux.c \ +@OS_WIN32_MINGW_TRUE@ sg_io_linux.c \ @OS_WIN32_MINGW_TRUE@ sg_pt_freebsd.c \ @OS_WIN32_MINGW_TRUE@ sg_pt_osf1.c \ @OS_WIN32_MINGW_TRUE@ sg_pt_solaris.c \ @@ -379,6 +385,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getopt_long.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sg_cmds_basic.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sg_cmds_extra.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sg_io_linux.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sg_lib.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sg_lib_data.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sg_pt_freebsd.Plo@am__quote@ diff --git a/lib/sg_io_linux.c b/lib/sg_io_linux.c new file mode 100644 index 00000000..cb8ad6e7 --- /dev/null +++ b/lib/sg_io_linux.c @@ -0,0 +1,252 @@ +/* + * Copyright (c) 1999-2007 Douglas Gilbert. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <ctype.h> + +// need to include the file in the build when sg_scan is built for Win32. +// Hence the following guard ... +// +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif +#ifdef SG3_UTILS_LINUX + +#include "sg_io_linux.h" + + +/* Version 1.02 20060714 */ + + +void sg_print_masked_status(int masked_status) +{ + int scsi_status = (masked_status << 1) & 0x7e; + + sg_print_scsi_status(scsi_status); +} + +static const char * linux_host_bytes[] = { + "DID_OK", "DID_NO_CONNECT", "DID_BUS_BUSY", "DID_TIME_OUT", + "DID_BAD_TARGET", "DID_ABORT", "DID_PARITY", "DID_ERROR", + "DID_RESET", "DID_BAD_INTR", "DID_PASSTHROUGH", "DID_SOFT_ERROR", + "DID_IMM_RETRY", "DID_REQUEUE" +}; + +#define LINUX_HOST_BYTES_SZ \ + (int)(sizeof(linux_host_bytes) / sizeof(linux_host_bytes[0])) + +void sg_print_host_status(int host_status) +{ + if (NULL == sg_warnings_strm) + sg_warnings_strm = stderr; + fprintf(sg_warnings_strm, "Host_status=0x%02x ", host_status); + if ((host_status < 0) || (host_status >= LINUX_HOST_BYTES_SZ)) + fprintf(sg_warnings_strm, "is invalid "); + else + fprintf(sg_warnings_strm, "[%s] ", linux_host_bytes[host_status]); +} + +static const char * linux_driver_bytes[] = { + "DRIVER_OK", "DRIVER_BUSY", "DRIVER_SOFT", "DRIVER_MEDIA", + "DRIVER_ERROR", "DRIVER_INVALID", "DRIVER_TIMEOUT", "DRIVER_HARD", + "DRIVER_SENSE" +}; + +#define LINUX_DRIVER_BYTES_SZ \ + (int)(sizeof(linux_driver_bytes) / sizeof(linux_driver_bytes[0])) + +static const char * linux_driver_suggests[] = { + "SUGGEST_OK", "SUGGEST_RETRY", "SUGGEST_ABORT", "SUGGEST_REMAP", + "SUGGEST_DIE", "UNKNOWN","UNKNOWN","UNKNOWN", + "SUGGEST_SENSE" +}; + +#define LINUX_DRIVER_SUGGESTS_SZ \ + (int)(sizeof(linux_driver_suggests) / sizeof(linux_driver_suggests[0])) + + +void sg_print_driver_status(int driver_status) +{ + int driv, sugg; + const char * driv_cp = "invalid"; + const char * sugg_cp = "invalid"; + + driv = driver_status & SG_LIB_DRIVER_MASK; + if (driv < LINUX_DRIVER_BYTES_SZ) + driv_cp = linux_driver_bytes[driv]; + sugg = (driver_status & SG_LIB_SUGGEST_MASK) >> 4; + if (sugg < LINUX_DRIVER_SUGGESTS_SZ) + sugg_cp = linux_driver_suggests[sugg]; + if (NULL == sg_warnings_strm) + sg_warnings_strm = stderr; + fprintf(sg_warnings_strm, "Driver_status=0x%02x", driver_status); + fprintf(sg_warnings_strm, " [%s, %s] ", driv_cp, sugg_cp); +} + +/* Returns 1 if no errors found and thus nothing printed; otherwise + prints error/warning (prefix by 'leadin') and returns 0. */ +static int sg_linux_sense_print(const char * leadin, int scsi_status, + int host_status, int driver_status, + const unsigned char * sense_buffer, + int sb_len, int raw_sinfo) +{ + int done_leadin = 0; + int done_sense = 0; + + if (NULL == sg_warnings_strm) + sg_warnings_strm = stderr; + scsi_status &= 0x7e; /*sanity */ + if ((0 == scsi_status) && (0 == host_status) && (0 == driver_status)) + return 1; /* No problems */ + if (0 != scsi_status) { + if (leadin) + fprintf(sg_warnings_strm, "%s: ", leadin); + done_leadin = 1; + fprintf(sg_warnings_strm, "SCSI status: "); + sg_print_scsi_status(scsi_status); + fprintf(sg_warnings_strm, "\n"); + if (sense_buffer && ((scsi_status == SAM_STAT_CHECK_CONDITION) || + (scsi_status == SAM_STAT_COMMAND_TERMINATED))) { + /* SAM_STAT_COMMAND_TERMINATED is obsolete */ + sg_print_sense(0, sense_buffer, sb_len, raw_sinfo); + done_sense = 1; + } + } + if (0 != host_status) { + if (leadin && (! done_leadin)) + fprintf(sg_warnings_strm, "%s: ", leadin); + if (done_leadin) + fprintf(sg_warnings_strm, "plus...: "); + else + done_leadin = 1; + sg_print_host_status(host_status); + fprintf(sg_warnings_strm, "\n"); + } + if (0 != driver_status) { + if (done_sense && + (SG_LIB_DRIVER_SENSE == (SG_LIB_DRIVER_MASK & driver_status))) + return 0; + if (leadin && (! done_leadin)) + fprintf(sg_warnings_strm, "%s: ", leadin); + if (done_leadin) + fprintf(sg_warnings_strm, "plus...: "); + else + done_leadin = 1; + sg_print_driver_status(driver_status); + fprintf(sg_warnings_strm, "\n"); + if (sense_buffer && (! done_sense) && + (SG_LIB_DRIVER_SENSE == (SG_LIB_DRIVER_MASK & driver_status))) + sg_print_sense(0, sense_buffer, sb_len, raw_sinfo); + } + return 0; +} + +#ifdef SG_IO + +int sg_normalize_sense(const struct sg_io_hdr * hp, + struct sg_scsi_sense_hdr * sshp) +{ + if ((NULL == hp) || (0 == hp->sb_len_wr)) { + if (sshp) + memset(sshp, 0, sizeof(struct sg_scsi_sense_hdr)); + return 0; + } + return sg_scsi_normalize_sense(hp->sbp, hp->sb_len_wr, sshp); +} + +/* Returns 1 if no errors found and thus nothing printed; otherwise + returns 0. */ +int sg_chk_n_print3(const char * leadin, struct sg_io_hdr * hp, + int raw_sinfo) +{ + return sg_linux_sense_print(leadin, hp->status, hp->host_status, + hp->driver_status, hp->sbp, hp->sb_len_wr, + raw_sinfo); +} +#endif + +/* Returns 1 if no errors found and thus nothing printed; otherwise + returns 0. */ +int sg_chk_n_print(const char * leadin, int masked_status, + int host_status, int driver_status, + const unsigned char * sense_buffer, int sb_len, + int raw_sinfo) +{ + int scsi_status = (masked_status << 1) & 0x7e; + + return sg_linux_sense_print(leadin, scsi_status, host_status, + driver_status, sense_buffer, sb_len, + raw_sinfo); +} + +#ifdef SG_IO +int sg_err_category3(struct sg_io_hdr * hp) +{ + return sg_err_category_new(hp->status, hp->host_status, + hp->driver_status, hp->sbp, hp->sb_len_wr); +} +#endif + +int sg_err_category(int masked_status, int host_status, + int driver_status, const unsigned char * sense_buffer, + int sb_len) +{ + int scsi_status = (masked_status << 1) & 0x7e; + + return sg_err_category_new(scsi_status, host_status, driver_status, + sense_buffer, sb_len); +} + +int sg_err_category_new(int scsi_status, int host_status, int driver_status, + const unsigned char * sense_buffer, int sb_len) +{ + int masked_driver_status = (SG_LIB_DRIVER_MASK & driver_status); + + scsi_status &= 0x7e; + if ((0 == scsi_status) && (0 == host_status) && + (0 == masked_driver_status)) + return SG_LIB_CAT_CLEAN; + if ((SAM_STAT_CHECK_CONDITION == scsi_status) || + (SAM_STAT_COMMAND_TERMINATED == scsi_status) || + (SG_LIB_DRIVER_SENSE == masked_driver_status)) + return sg_err_category_sense(sense_buffer, sb_len); + if (0 != host_status) { + if ((SG_LIB_DID_NO_CONNECT == host_status) || + (SG_LIB_DID_BUS_BUSY == host_status) || + (SG_LIB_DID_TIME_OUT == host_status)) + return SG_LIB_CAT_TIMEOUT; + } + if (SG_LIB_DRIVER_TIMEOUT == masked_driver_status) + return SG_LIB_CAT_TIMEOUT; + return SG_LIB_CAT_OTHER; +} + +#endif |