ddpt-0.94/ 0000755 0001750 0001750 00000000000 12320426231 011370 5 ustar dougg dougg ddpt-0.94/INSTALL 0000644 0001750 0001750 00000022450 11130302611 012415 0 ustar dougg dougg Installation Instructions
*************************
Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005,
2006, 2007 Free Software Foundation, Inc.
This file is free documentation; the Free Software Foundation gives
unlimited permission to copy, distribute and modify it.
Basic Installation
==================
Briefly, the shell commands `./configure; make; make install' should
configure, build, and install this package. The following
more-detailed instructions are generic; see the `README' file for
instructions specific to this package.
The `configure' shell script attempts to guess correct values for
various system-dependent variables used during compilation. It uses
those values to create a `Makefile' in each directory of the package.
It may also create one or more `.h' files containing system-dependent
definitions. Finally, it creates a shell script `config.status' that
you can run in the future to recreate the current configuration, and a
file `config.log' containing compiler output (useful mainly for
debugging `configure').
It can also use an optional file (typically called `config.cache'
and enabled with `--cache-file=config.cache' or simply `-C') that saves
the results of its tests to speed up reconfiguring. Caching is
disabled by default to prevent problems with accidental use of stale
cache files.
If you need to do unusual things to compile the package, please try
to figure out how `configure' could check whether to do them, and mail
diffs or instructions to the address given in the `README' so they can
be considered for the next release. If you are using the cache, and at
some point `config.cache' contains results you don't want to keep, you
may remove or edit it.
The file `configure.ac' (or `configure.in') is used to create
`configure' by a program called `autoconf'. You need `configure.ac' if
you want to change it or regenerate `configure' using a newer version
of `autoconf'.
The simplest way to compile this package is:
1. `cd' to the directory containing the package's source code and type
`./configure' to configure the package for your system.
Running `configure' might take a while. While running, it prints
some messages telling which features it is checking for.
2. Type `make' to compile the package.
3. Optionally, type `make check' to run any self-tests that come with
the package.
4. Type `make install' to install the programs and any data files and
documentation.
5. You can remove the program binaries and object files from the
source code directory by typing `make clean'. To also remove the
files that `configure' created (so you can compile the package for
a different kind of computer), type `make distclean'. There is
also a `make maintainer-clean' target, but that is intended mainly
for the package's developers. If you use it, you may have to get
all sorts of other programs in order to regenerate files that came
with the distribution.
6. Often, you can also type `make uninstall' to remove the installed
files again.
Compilers and Options
=====================
Some systems require unusual options for compilation or linking that the
`configure' script does not know about. Run `./configure --help' for
details on some of the pertinent environment variables.
You can give `configure' initial values for configuration parameters
by setting variables in the command line or in the environment. Here
is an example:
./configure CC=c99 CFLAGS=-g LIBS=-lposix
*Note Defining Variables::, for more details.
Compiling For Multiple Architectures
====================================
You can compile the package for more than one kind of computer at the
same time, by placing the object files for each architecture in their
own directory. To do this, you can use GNU `make'. `cd' to the
directory where you want the object files and executables to go and run
the `configure' script. `configure' automatically checks for the
source code in the directory that `configure' is in and in `..'.
With a non-GNU `make', it is safer to compile the package for one
architecture at a time in the source code directory. After you have
installed the package for one architecture, use `make distclean' before
reconfiguring for another architecture.
Installation Names
==================
By default, `make install' installs the package's commands under
`/usr/local/bin', include files under `/usr/local/include', etc. You
can specify an installation prefix other than `/usr/local' by giving
`configure' the option `--prefix=PREFIX'.
You can specify separate installation prefixes for
architecture-specific files and architecture-independent files. If you
pass the option `--exec-prefix=PREFIX' to `configure', the package uses
PREFIX as the prefix for installing programs and libraries.
Documentation and other data files still use the regular prefix.
In addition, if you use an unusual directory layout you can give
options like `--bindir=DIR' to specify different values for particular
kinds of files. Run `configure --help' for a list of the directories
you can set and what kinds of files go in them.
If the package supports it, you can cause programs to be installed
with an extra prefix or suffix on their names by giving `configure' the
option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
Optional Features
=================
Some packages pay attention to `--enable-FEATURE' options to
`configure', where FEATURE indicates an optional part of the package.
They may also pay attention to `--with-PACKAGE' options, where PACKAGE
is something like `gnu-as' or `x' (for the X Window System). The
`README' should mention any `--enable-' and `--with-' options that the
package recognizes.
For packages that use the X Window System, `configure' can usually
find the X include and library files automatically, but if it doesn't,
you can use the `configure' options `--x-includes=DIR' and
`--x-libraries=DIR' to specify their locations.
Specifying the System Type
==========================
There may be some features `configure' cannot figure out automatically,
but needs to determine by the type of machine the package will run on.
Usually, assuming the package is built to be run on the _same_
architectures, `configure' can figure that out, but if it prints a
message saying it cannot guess the machine type, give it the
`--build=TYPE' option. TYPE can either be a short name for the system
type, such as `sun4', or a canonical name which has the form:
CPU-COMPANY-SYSTEM
where SYSTEM can have one of these forms:
OS KERNEL-OS
See the file `config.sub' for the possible values of each field. If
`config.sub' isn't included in this package, then this package doesn't
need to know the machine type.
If you are _building_ compiler tools for cross-compiling, you should
use the option `--target=TYPE' to select the type of system they will
produce code for.
If you want to _use_ a cross compiler, that generates code for a
platform different from the build platform, you should specify the
"host" platform (i.e., that on which the generated programs will
eventually be run) with `--host=TYPE'.
Sharing Defaults
================
If you want to set default values for `configure' scripts to share, you
can create a site shell script called `config.site' that gives default
values for variables like `CC', `cache_file', and `prefix'.
`configure' looks for `PREFIX/share/config.site' if it exists, then
`PREFIX/etc/config.site' if it exists. Or, you can set the
`CONFIG_SITE' environment variable to the location of the site script.
A warning: not all `configure' scripts look for a site script.
Defining Variables
==================
Variables not defined in a site shell script can be set in the
environment passed to `configure'. However, some packages may run
configure again during the build, and the customized values of these
variables may be lost. In order to avoid this problem, you should set
them in the `configure' command line, using `VAR=value'. For example:
./configure CC=/usr/local2/bin/gcc
causes the specified `gcc' to be used as the C compiler (unless it is
overridden in the site shell script).
Unfortunately, this technique does not work for `CONFIG_SHELL' due to
an Autoconf bug. Until the bug is fixed you can use this workaround:
CONFIG_SHELL=/bin/bash /bin/bash ./configure CONFIG_SHELL=/bin/bash
`configure' Invocation
======================
`configure' recognizes the following options to control how it operates.
`--help'
`-h'
Print a summary of the options to `configure', and exit.
`--version'
`-V'
Print the version of Autoconf used to generate the `configure'
script, and exit.
`--cache-file=FILE'
Enable the cache: use and save the results of the tests in FILE,
traditionally `config.cache'. FILE defaults to `/dev/null' to
disable caching.
`--config-cache'
`-C'
Alias for `--cache-file=config.cache'.
`--quiet'
`--silent'
`-q'
Do not print messages saying which checks are being made. To
suppress all normal output, redirect it to `/dev/null' (any error
messages will still be shown).
`--srcdir=DIR'
Look for the package's source code in directory DIR. Usually
`configure' can determine that directory automatically.
`configure' also accepts some other, not widely useful, options. Run
`configure --help' for more details.
ddpt-0.94/config.guess 0000755 0001750 0001750 00000130361 12234471250 013721 0 ustar dougg dougg #! /bin/sh
# Attempt to guess a canonical system name.
# Copyright 1992-2013 Free Software Foundation, Inc.
timestamp='2013-06-10'
# This file 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 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, see .
#
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that
# program. This Exception is an additional permission under section 7
# of the GNU General Public License, version 3 ("GPLv3").
#
# Originally written by Per Bothner.
#
# You can get the latest version of this script from:
# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
#
# Please send patches with a ChangeLog entry to config-patches@gnu.org.
me=`echo "$0" | sed -e 's,.*/,,'`
usage="\
Usage: $0 [OPTION]
Output the configuration name of the system \`$me' is run on.
Operation modes:
-h, --help print this help, then exit
-t, --time-stamp print date of last modification, then exit
-v, --version print version number, then exit
Report bugs and patches to ."
version="\
GNU config.guess ($timestamp)
Originally written by Per Bothner.
Copyright 1992-2013 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
help="
Try \`$me --help' for more information."
# Parse command line
while test $# -gt 0 ; do
case $1 in
--time-stamp | --time* | -t )
echo "$timestamp" ; exit ;;
--version | -v )
echo "$version" ; exit ;;
--help | --h* | -h )
echo "$usage"; exit ;;
-- ) # Stop option processing
shift; break ;;
- ) # Use stdin as input.
break ;;
-* )
echo "$me: invalid option $1$help" >&2
exit 1 ;;
* )
break ;;
esac
done
if test $# != 0; then
echo "$me: too many arguments$help" >&2
exit 1
fi
trap 'exit 1' 1 2 15
# CC_FOR_BUILD -- compiler used by this script. Note that the use of a
# compiler to aid in system detection is discouraged as it requires
# temporary files to be created and, as you can see below, it is a
# headache to deal with in a portable fashion.
# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still
# use `HOST_CC' if defined, but it is deprecated.
# Portable tmp directory creation inspired by the Autoconf team.
set_cc_for_build='
trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ;
trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ;
: ${TMPDIR=/tmp} ;
{ tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } ||
{ test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } ||
{ tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } ||
{ echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ;
dummy=$tmp/dummy ;
tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ;
case $CC_FOR_BUILD,$HOST_CC,$CC in
,,) echo "int x;" > $dummy.c ;
for c in cc gcc c89 c99 ; do
if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then
CC_FOR_BUILD="$c"; break ;
fi ;
done ;
if test x"$CC_FOR_BUILD" = x ; then
CC_FOR_BUILD=no_compiler_found ;
fi
;;
,,*) CC_FOR_BUILD=$CC ;;
,*,*) CC_FOR_BUILD=$HOST_CC ;;
esac ; set_cc_for_build= ;'
# This is needed to find uname on a Pyramid OSx when run in the BSD universe.
# (ghazi@noc.rutgers.edu 1994-08-24)
if (test -f /.attbin/uname) >/dev/null 2>&1 ; then
PATH=$PATH:/.attbin ; export PATH
fi
UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown
UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown
UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
case "${UNAME_SYSTEM}" in
Linux|GNU|GNU/*)
# If the system lacks a compiler, then just pick glibc.
# We could probably try harder.
LIBC=gnu
eval $set_cc_for_build
cat <<-EOF > $dummy.c
#include
#if defined(__UCLIBC__)
LIBC=uclibc
#elif defined(__dietlibc__)
LIBC=dietlibc
#else
LIBC=gnu
#endif
EOF
eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'`
;;
esac
# Note: order is significant - the case branches are not exclusive.
case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
*:NetBSD:*:*)
# NetBSD (nbsd) targets should (where applicable) match one or
# more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*,
# *-*-netbsdecoff* and *-*-netbsd*. For targets that recently
# switched to ELF, *-*-netbsd* would select the old
# object file format. This provides both forward
# compatibility and a consistent mechanism for selecting the
# object file format.
#
# Note: NetBSD doesn't particularly care about the vendor
# portion of the name. We always set it to "unknown".
sysctl="sysctl -n hw.machine_arch"
UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \
/usr/sbin/$sysctl 2>/dev/null || echo unknown)`
case "${UNAME_MACHINE_ARCH}" in
armeb) machine=armeb-unknown ;;
arm*) machine=arm-unknown ;;
sh3el) machine=shl-unknown ;;
sh3eb) machine=sh-unknown ;;
sh5el) machine=sh5le-unknown ;;
*) machine=${UNAME_MACHINE_ARCH}-unknown ;;
esac
# The Operating System including object format, if it has switched
# to ELF recently, or will in the future.
case "${UNAME_MACHINE_ARCH}" in
arm*|i386|m68k|ns32k|sh3*|sparc|vax)
eval $set_cc_for_build
if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
| grep -q __ELF__
then
# Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout).
# Return netbsd for either. FIX?
os=netbsd
else
os=netbsdelf
fi
;;
*)
os=netbsd
;;
esac
# The OS release
# Debian GNU/NetBSD machines have a different userland, and
# thus, need a distinct triplet. However, they do not need
# kernel version information, so it can be replaced with a
# suitable tag, in the style of linux-gnu.
case "${UNAME_VERSION}" in
Debian*)
release='-gnu'
;;
*)
release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
;;
esac
# Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:
# contains redundant information, the shorter form:
# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
echo "${machine}-${os}${release}"
exit ;;
*:Bitrig:*:*)
UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'`
echo ${UNAME_MACHINE_ARCH}-unknown-bitrig${UNAME_RELEASE}
exit ;;
*:OpenBSD:*:*)
UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'`
echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE}
exit ;;
*:ekkoBSD:*:*)
echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE}
exit ;;
*:SolidBSD:*:*)
echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE}
exit ;;
macppc:MirBSD:*:*)
echo powerpc-unknown-mirbsd${UNAME_RELEASE}
exit ;;
*:MirBSD:*:*)
echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE}
exit ;;
alpha:OSF1:*:*)
case $UNAME_RELEASE in
*4.0)
UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
;;
*5.*)
UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'`
;;
esac
# According to Compaq, /usr/sbin/psrinfo has been available on
# OSF/1 and Tru64 systems produced since 1995. I hope that
# covers most systems running today. This code pipes the CPU
# types through head -n 1, so we only detect the type of CPU 0.
ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1`
case "$ALPHA_CPU_TYPE" in
"EV4 (21064)")
UNAME_MACHINE="alpha" ;;
"EV4.5 (21064)")
UNAME_MACHINE="alpha" ;;
"LCA4 (21066/21068)")
UNAME_MACHINE="alpha" ;;
"EV5 (21164)")
UNAME_MACHINE="alphaev5" ;;
"EV5.6 (21164A)")
UNAME_MACHINE="alphaev56" ;;
"EV5.6 (21164PC)")
UNAME_MACHINE="alphapca56" ;;
"EV5.7 (21164PC)")
UNAME_MACHINE="alphapca57" ;;
"EV6 (21264)")
UNAME_MACHINE="alphaev6" ;;
"EV6.7 (21264A)")
UNAME_MACHINE="alphaev67" ;;
"EV6.8CB (21264C)")
UNAME_MACHINE="alphaev68" ;;
"EV6.8AL (21264B)")
UNAME_MACHINE="alphaev68" ;;
"EV6.8CX (21264D)")
UNAME_MACHINE="alphaev68" ;;
"EV6.9A (21264/EV69A)")
UNAME_MACHINE="alphaev69" ;;
"EV7 (21364)")
UNAME_MACHINE="alphaev7" ;;
"EV7.9 (21364A)")
UNAME_MACHINE="alphaev79" ;;
esac
# A Pn.n version is a patched version.
# A Vn.n version is a released version.
# A Tn.n version is a released field test version.
# A Xn.n version is an unreleased experimental baselevel.
# 1.2 uses "1.2" for uname -r.
echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
# Reset EXIT trap before exiting to avoid spurious non-zero exit code.
exitcode=$?
trap '' 0
exit $exitcode ;;
Alpha\ *:Windows_NT*:*)
# How do we know it's Interix rather than the generic POSIX subsystem?
# Should we change UNAME_MACHINE based on the output of uname instead
# of the specific Alpha model?
echo alpha-pc-interix
exit ;;
21064:Windows_NT:50:3)
echo alpha-dec-winnt3.5
exit ;;
Amiga*:UNIX_System_V:4.0:*)
echo m68k-unknown-sysv4
exit ;;
*:[Aa]miga[Oo][Ss]:*:*)
echo ${UNAME_MACHINE}-unknown-amigaos
exit ;;
*:[Mm]orph[Oo][Ss]:*:*)
echo ${UNAME_MACHINE}-unknown-morphos
exit ;;
*:OS/390:*:*)
echo i370-ibm-openedition
exit ;;
*:z/VM:*:*)
echo s390-ibm-zvmoe
exit ;;
*:OS400:*:*)
echo powerpc-ibm-os400
exit ;;
arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
echo arm-acorn-riscix${UNAME_RELEASE}
exit ;;
arm*:riscos:*:*|arm*:RISCOS:*:*)
echo arm-unknown-riscos
exit ;;
SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*)
echo hppa1.1-hitachi-hiuxmpp
exit ;;
Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*)
# akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE.
if test "`(/bin/universe) 2>/dev/null`" = att ; then
echo pyramid-pyramid-sysv3
else
echo pyramid-pyramid-bsd
fi
exit ;;
NILE*:*:*:dcosx)
echo pyramid-pyramid-svr4
exit ;;
DRS?6000:unix:4.0:6*)
echo sparc-icl-nx6
exit ;;
DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*)
case `/usr/bin/uname -p` in
sparc) echo sparc-icl-nx7; exit ;;
esac ;;
s390x:SunOS:*:*)
echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
exit ;;
sun4H:SunOS:5.*:*)
echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
exit ;;
sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
exit ;;
i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*)
echo i386-pc-auroraux${UNAME_RELEASE}
exit ;;
i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*)
eval $set_cc_for_build
SUN_ARCH="i386"
# If there is a compiler, see if it is configured for 64-bit objects.
# Note that the Sun cc does not turn __LP64__ into 1 like gcc does.
# This test works for both compilers.
if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \
(CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
grep IS_64BIT_ARCH >/dev/null
then
SUN_ARCH="x86_64"
fi
fi
echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
exit ;;
sun4*:SunOS:6*:*)
# According to config.sub, this is the proper way to canonicalize
# SunOS6. Hard to guess exactly what SunOS6 will be like, but
# it's likely to be more like Solaris than SunOS4.
echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
exit ;;
sun4*:SunOS:*:*)
case "`/usr/bin/arch -k`" in
Series*|S4*)
UNAME_RELEASE=`uname -v`
;;
esac
# Japanese Language versions have a version number like `4.1.3-JL'.
echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'`
exit ;;
sun3*:SunOS:*:*)
echo m68k-sun-sunos${UNAME_RELEASE}
exit ;;
sun*:*:4.2BSD:*)
UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3
case "`/bin/arch`" in
sun3)
echo m68k-sun-sunos${UNAME_RELEASE}
;;
sun4)
echo sparc-sun-sunos${UNAME_RELEASE}
;;
esac
exit ;;
aushp:SunOS:*:*)
echo sparc-auspex-sunos${UNAME_RELEASE}
exit ;;
# The situation for MiNT is a little confusing. The machine name
# can be virtually everything (everything which is not
# "atarist" or "atariste" at least should have a processor
# > m68000). The system name ranges from "MiNT" over "FreeMiNT"
# to the lowercase version "mint" (or "freemint"). Finally
# the system name "TOS" denotes a system which is actually not
# MiNT. But MiNT is downward compatible to TOS, so this should
# be no problem.
atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)
echo m68k-atari-mint${UNAME_RELEASE}
exit ;;
atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
echo m68k-atari-mint${UNAME_RELEASE}
exit ;;
*falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
echo m68k-atari-mint${UNAME_RELEASE}
exit ;;
milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
echo m68k-milan-mint${UNAME_RELEASE}
exit ;;
hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
echo m68k-hades-mint${UNAME_RELEASE}
exit ;;
*:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
echo m68k-unknown-mint${UNAME_RELEASE}
exit ;;
m68k:machten:*:*)
echo m68k-apple-machten${UNAME_RELEASE}
exit ;;
powerpc:machten:*:*)
echo powerpc-apple-machten${UNAME_RELEASE}
exit ;;
RISC*:Mach:*:*)
echo mips-dec-mach_bsd4.3
exit ;;
RISC*:ULTRIX:*:*)
echo mips-dec-ultrix${UNAME_RELEASE}
exit ;;
VAX*:ULTRIX*:*:*)
echo vax-dec-ultrix${UNAME_RELEASE}
exit ;;
2020:CLIX:*:* | 2430:CLIX:*:*)
echo clipper-intergraph-clix${UNAME_RELEASE}
exit ;;
mips:*:*:UMIPS | mips:*:*:RISCos)
eval $set_cc_for_build
sed 's/^ //' << EOF >$dummy.c
#ifdef __cplusplus
#include /* for printf() prototype */
int main (int argc, char *argv[]) {
#else
int main (argc, argv) int argc; char *argv[]; {
#endif
#if defined (host_mips) && defined (MIPSEB)
#if defined (SYSTYPE_SYSV)
printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0);
#endif
#if defined (SYSTYPE_SVR4)
printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0);
#endif
#if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD)
printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0);
#endif
#endif
exit (-1);
}
EOF
$CC_FOR_BUILD -o $dummy $dummy.c &&
dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` &&
SYSTEM_NAME=`$dummy $dummyarg` &&
{ echo "$SYSTEM_NAME"; exit; }
echo mips-mips-riscos${UNAME_RELEASE}
exit ;;
Motorola:PowerMAX_OS:*:*)
echo powerpc-motorola-powermax
exit ;;
Motorola:*:4.3:PL8-*)
echo powerpc-harris-powermax
exit ;;
Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*)
echo powerpc-harris-powermax
exit ;;
Night_Hawk:Power_UNIX:*:*)
echo powerpc-harris-powerunix
exit ;;
m88k:CX/UX:7*:*)
echo m88k-harris-cxux7
exit ;;
m88k:*:4*:R4*)
echo m88k-motorola-sysv4
exit ;;
m88k:*:3*:R3*)
echo m88k-motorola-sysv3
exit ;;
AViiON:dgux:*:*)
# DG/UX returns AViiON for all architectures
UNAME_PROCESSOR=`/usr/bin/uname -p`
if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ]
then
if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \
[ ${TARGET_BINARY_INTERFACE}x = x ]
then
echo m88k-dg-dgux${UNAME_RELEASE}
else
echo m88k-dg-dguxbcs${UNAME_RELEASE}
fi
else
echo i586-dg-dgux${UNAME_RELEASE}
fi
exit ;;
M88*:DolphinOS:*:*) # DolphinOS (SVR3)
echo m88k-dolphin-sysv3
exit ;;
M88*:*:R3*:*)
# Delta 88k system running SVR3
echo m88k-motorola-sysv3
exit ;;
XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3)
echo m88k-tektronix-sysv3
exit ;;
Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD)
echo m68k-tektronix-bsd
exit ;;
*:IRIX*:*:*)
echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'`
exit ;;
????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.
echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id
exit ;; # Note that: echo "'`uname -s`'" gives 'AIX '
i*86:AIX:*:*)
echo i386-ibm-aix
exit ;;
ia64:AIX:*:*)
if [ -x /usr/bin/oslevel ] ; then
IBM_REV=`/usr/bin/oslevel`
else
IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
fi
echo ${UNAME_MACHINE}-ibm-aix${IBM_REV}
exit ;;
*:AIX:2:3)
if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
eval $set_cc_for_build
sed 's/^ //' << EOF >$dummy.c
#include
main()
{
if (!__power_pc())
exit(1);
puts("powerpc-ibm-aix3.2.5");
exit(0);
}
EOF
if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy`
then
echo "$SYSTEM_NAME"
else
echo rs6000-ibm-aix3.2.5
fi
elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then
echo rs6000-ibm-aix3.2.4
else
echo rs6000-ibm-aix3.2
fi
exit ;;
*:AIX:*:[4567])
IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then
IBM_ARCH=rs6000
else
IBM_ARCH=powerpc
fi
if [ -x /usr/bin/oslevel ] ; then
IBM_REV=`/usr/bin/oslevel`
else
IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
fi
echo ${IBM_ARCH}-ibm-aix${IBM_REV}
exit ;;
*:AIX:*:*)
echo rs6000-ibm-aix
exit ;;
ibmrt:4.4BSD:*|romp-ibm:BSD:*)
echo romp-ibm-bsd4.4
exit ;;
ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and
echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to
exit ;; # report: romp-ibm BSD 4.3
*:BOSX:*:*)
echo rs6000-bull-bosx
exit ;;
DPX/2?00:B.O.S.:*:*)
echo m68k-bull-sysv3
exit ;;
9000/[34]??:4.3bsd:1.*:*)
echo m68k-hp-bsd
exit ;;
hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)
echo m68k-hp-bsd4.4
exit ;;
9000/[34678]??:HP-UX:*:*)
HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
case "${UNAME_MACHINE}" in
9000/31? ) HP_ARCH=m68000 ;;
9000/[34]?? ) HP_ARCH=m68k ;;
9000/[678][0-9][0-9])
if [ -x /usr/bin/getconf ]; then
sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
case "${sc_cpu_version}" in
523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1
532) # CPU_PA_RISC2_0
case "${sc_kernel_bits}" in
32) HP_ARCH="hppa2.0n" ;;
64) HP_ARCH="hppa2.0w" ;;
'') HP_ARCH="hppa2.0" ;; # HP-UX 10.20
esac ;;
esac
fi
if [ "${HP_ARCH}" = "" ]; then
eval $set_cc_for_build
sed 's/^ //' << EOF >$dummy.c
#define _HPUX_SOURCE
#include
#include
int main ()
{
#if defined(_SC_KERNEL_BITS)
long bits = sysconf(_SC_KERNEL_BITS);
#endif
long cpu = sysconf (_SC_CPU_VERSION);
switch (cpu)
{
case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
case CPU_PA_RISC2_0:
#if defined(_SC_KERNEL_BITS)
switch (bits)
{
case 64: puts ("hppa2.0w"); break;
case 32: puts ("hppa2.0n"); break;
default: puts ("hppa2.0"); break;
} break;
#else /* !defined(_SC_KERNEL_BITS) */
puts ("hppa2.0"); break;
#endif
default: puts ("hppa1.0"); break;
}
exit (0);
}
EOF
(CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy`
test -z "$HP_ARCH" && HP_ARCH=hppa
fi ;;
esac
if [ ${HP_ARCH} = "hppa2.0w" ]
then
eval $set_cc_for_build
# hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating
# 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler
# generating 64-bit code. GNU and HP use different nomenclature:
#
# $ CC_FOR_BUILD=cc ./config.guess
# => hppa2.0w-hp-hpux11.23
# $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess
# => hppa64-hp-hpux11.23
if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) |
grep -q __LP64__
then
HP_ARCH="hppa2.0w"
else
HP_ARCH="hppa64"
fi
fi
echo ${HP_ARCH}-hp-hpux${HPUX_REV}
exit ;;
ia64:HP-UX:*:*)
HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
echo ia64-hp-hpux${HPUX_REV}
exit ;;
3050*:HI-UX:*:*)
eval $set_cc_for_build
sed 's/^ //' << EOF >$dummy.c
#include
int
main ()
{
long cpu = sysconf (_SC_CPU_VERSION);
/* The order matters, because CPU_IS_HP_MC68K erroneously returns
true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct
results, however. */
if (CPU_IS_PA_RISC (cpu))
{
switch (cpu)
{
case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break;
case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break;
case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break;
default: puts ("hppa-hitachi-hiuxwe2"); break;
}
}
else if (CPU_IS_HP_MC68K (cpu))
puts ("m68k-hitachi-hiuxwe2");
else puts ("unknown-hitachi-hiuxwe2");
exit (0);
}
EOF
$CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` &&
{ echo "$SYSTEM_NAME"; exit; }
echo unknown-hitachi-hiuxwe2
exit ;;
9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* )
echo hppa1.1-hp-bsd
exit ;;
9000/8??:4.3bsd:*:*)
echo hppa1.0-hp-bsd
exit ;;
*9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*)
echo hppa1.0-hp-mpeix
exit ;;
hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* )
echo hppa1.1-hp-osf
exit ;;
hp8??:OSF1:*:*)
echo hppa1.0-hp-osf
exit ;;
i*86:OSF1:*:*)
if [ -x /usr/sbin/sysversion ] ; then
echo ${UNAME_MACHINE}-unknown-osf1mk
else
echo ${UNAME_MACHINE}-unknown-osf1
fi
exit ;;
parisc*:Lites*:*:*)
echo hppa1.1-hp-lites
exit ;;
C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
echo c1-convex-bsd
exit ;;
C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
if getsysinfo -f scalar_acc
then echo c32-convex-bsd
else echo c2-convex-bsd
fi
exit ;;
C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
echo c34-convex-bsd
exit ;;
C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
echo c38-convex-bsd
exit ;;
C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
echo c4-convex-bsd
exit ;;
CRAY*Y-MP:*:*:*)
echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
exit ;;
CRAY*[A-Z]90:*:*:*)
echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \
| sed -e 's/CRAY.*\([A-Z]90\)/\1/' \
-e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \
-e 's/\.[^.]*$/.X/'
exit ;;
CRAY*TS:*:*:*)
echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
exit ;;
CRAY*T3E:*:*:*)
echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
exit ;;
CRAY*SV1:*:*:*)
echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
exit ;;
*:UNICOS/mp:*:*)
echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
exit ;;
F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
exit ;;
5000:UNIX_System_V:4.*:*)
FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'`
echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
exit ;;
i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
exit ;;
sparc*:BSD/OS:*:*)
echo sparc-unknown-bsdi${UNAME_RELEASE}
exit ;;
*:BSD/OS:*:*)
echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
exit ;;
*:FreeBSD:*:*)
UNAME_PROCESSOR=`/usr/bin/uname -p`
case ${UNAME_PROCESSOR} in
amd64)
echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
*)
echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
esac
exit ;;
i*:CYGWIN*:*)
echo ${UNAME_MACHINE}-pc-cygwin
exit ;;
*:MINGW64*:*)
echo ${UNAME_MACHINE}-pc-mingw64
exit ;;
*:MINGW*:*)
echo ${UNAME_MACHINE}-pc-mingw32
exit ;;
i*:MSYS*:*)
echo ${UNAME_MACHINE}-pc-msys
exit ;;
i*:windows32*:*)
# uname -m includes "-pc" on this system.
echo ${UNAME_MACHINE}-mingw32
exit ;;
i*:PW*:*)
echo ${UNAME_MACHINE}-pc-pw32
exit ;;
*:Interix*:*)
case ${UNAME_MACHINE} in
x86)
echo i586-pc-interix${UNAME_RELEASE}
exit ;;
authenticamd | genuineintel | EM64T)
echo x86_64-unknown-interix${UNAME_RELEASE}
exit ;;
IA64)
echo ia64-unknown-interix${UNAME_RELEASE}
exit ;;
esac ;;
[345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*)
echo i${UNAME_MACHINE}-pc-mks
exit ;;
8664:Windows_NT:*)
echo x86_64-pc-mks
exit ;;
i*:Windows_NT*:* | Pentium*:Windows_NT*:*)
# How do we know it's Interix rather than the generic POSIX subsystem?
# It also conflicts with pre-2.0 versions of AT&T UWIN. Should we
# UNAME_MACHINE based on the output of uname instead of i386?
echo i586-pc-interix
exit ;;
i*:UWIN*:*)
echo ${UNAME_MACHINE}-pc-uwin
exit ;;
amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*)
echo x86_64-unknown-cygwin
exit ;;
p*:CYGWIN*:*)
echo powerpcle-unknown-cygwin
exit ;;
prep*:SunOS:5.*:*)
echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
exit ;;
*:GNU:*:*)
# the GNU system
echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-${LIBC}`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
exit ;;
*:GNU/*:*:*)
# other systems with GNU libc and userland
echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-${LIBC}
exit ;;
i*86:Minix:*:*)
echo ${UNAME_MACHINE}-pc-minix
exit ;;
aarch64:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
aarch64_be:Linux:*:*)
UNAME_MACHINE=aarch64_be
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
alpha:Linux:*:*)
case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
EV5) UNAME_MACHINE=alphaev5 ;;
EV56) UNAME_MACHINE=alphaev56 ;;
PCA56) UNAME_MACHINE=alphapca56 ;;
PCA57) UNAME_MACHINE=alphapca56 ;;
EV6) UNAME_MACHINE=alphaev6 ;;
EV67) UNAME_MACHINE=alphaev67 ;;
EV68*) UNAME_MACHINE=alphaev68 ;;
esac
objdump --private-headers /bin/sh | grep -q ld.so.1
if test "$?" = 0 ; then LIBC="gnulibc1" ; fi
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
arc:Linux:*:* | arceb:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
arm*:Linux:*:*)
eval $set_cc_for_build
if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \
| grep -q __ARM_EABI__
then
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
else
if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \
| grep -q __ARM_PCS_VFP
then
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabi
else
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabihf
fi
fi
exit ;;
avr32*:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
cris:Linux:*:*)
echo ${UNAME_MACHINE}-axis-linux-${LIBC}
exit ;;
crisv32:Linux:*:*)
echo ${UNAME_MACHINE}-axis-linux-${LIBC}
exit ;;
frv:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
hexagon:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
i*86:Linux:*:*)
echo ${UNAME_MACHINE}-pc-linux-${LIBC}
exit ;;
ia64:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
m32r*:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
m68*:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
mips:Linux:*:* | mips64:Linux:*:*)
eval $set_cc_for_build
sed 's/^ //' << EOF >$dummy.c
#undef CPU
#undef ${UNAME_MACHINE}
#undef ${UNAME_MACHINE}el
#if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
CPU=${UNAME_MACHINE}el
#else
#if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
CPU=${UNAME_MACHINE}
#else
CPU=
#endif
#endif
EOF
eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'`
test x"${CPU}" != x && { echo "${CPU}-unknown-linux-${LIBC}"; exit; }
;;
or1k:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
or32:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
padre:Linux:*:*)
echo sparc-unknown-linux-${LIBC}
exit ;;
parisc64:Linux:*:* | hppa64:Linux:*:*)
echo hppa64-unknown-linux-${LIBC}
exit ;;
parisc:Linux:*:* | hppa:Linux:*:*)
# Look for CPU level
case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in
PA7*) echo hppa1.1-unknown-linux-${LIBC} ;;
PA8*) echo hppa2.0-unknown-linux-${LIBC} ;;
*) echo hppa-unknown-linux-${LIBC} ;;
esac
exit ;;
ppc64:Linux:*:*)
echo powerpc64-unknown-linux-${LIBC}
exit ;;
ppc:Linux:*:*)
echo powerpc-unknown-linux-${LIBC}
exit ;;
ppc64le:Linux:*:*)
echo powerpc64le-unknown-linux-${LIBC}
exit ;;
ppcle:Linux:*:*)
echo powerpcle-unknown-linux-${LIBC}
exit ;;
s390:Linux:*:* | s390x:Linux:*:*)
echo ${UNAME_MACHINE}-ibm-linux-${LIBC}
exit ;;
sh64*:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
sh*:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
sparc:Linux:*:* | sparc64:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
tile*:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
vax:Linux:*:*)
echo ${UNAME_MACHINE}-dec-linux-${LIBC}
exit ;;
x86_64:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
xtensa*:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
i*86:DYNIX/ptx:4*:*)
# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
# earlier versions are messed up and put the nodename in both
# sysname and nodename.
echo i386-sequent-sysv4
exit ;;
i*86:UNIX_SV:4.2MP:2.*)
# Unixware is an offshoot of SVR4, but it has its own version
# number series starting with 2...
# I am not positive that other SVR4 systems won't match this,
# I just have to hope. -- rms.
# Use sysv4.2uw... so that sysv4* matches it.
echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
exit ;;
i*86:OS/2:*:*)
# If we were able to find `uname', then EMX Unix compatibility
# is probably installed.
echo ${UNAME_MACHINE}-pc-os2-emx
exit ;;
i*86:XTS-300:*:STOP)
echo ${UNAME_MACHINE}-unknown-stop
exit ;;
i*86:atheos:*:*)
echo ${UNAME_MACHINE}-unknown-atheos
exit ;;
i*86:syllable:*:*)
echo ${UNAME_MACHINE}-pc-syllable
exit ;;
i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*)
echo i386-unknown-lynxos${UNAME_RELEASE}
exit ;;
i*86:*DOS:*:*)
echo ${UNAME_MACHINE}-pc-msdosdjgpp
exit ;;
i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*)
UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'`
if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL}
else
echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL}
fi
exit ;;
i*86:*:5:[678]*)
# UnixWare 7.x, OpenUNIX and OpenServer 6.
case `/bin/uname -X | grep "^Machine"` in
*486*) UNAME_MACHINE=i486 ;;
*Pentium) UNAME_MACHINE=i586 ;;
*Pent*|*Celeron) UNAME_MACHINE=i686 ;;
esac
echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION}
exit ;;
i*86:*:3.2:*)
if test -f /usr/options/cb.name; then
UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then
UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')`
(/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486
(/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \
&& UNAME_MACHINE=i586
(/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \
&& UNAME_MACHINE=i686
(/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \
&& UNAME_MACHINE=i686
echo ${UNAME_MACHINE}-pc-sco$UNAME_REL
else
echo ${UNAME_MACHINE}-pc-sysv32
fi
exit ;;
pc:*:*:*)
# Left here for compatibility:
# uname -m prints for DJGPP always 'pc', but it prints nothing about
# the processor, so we play safe by assuming i586.
# Note: whatever this is, it MUST be the same as what config.sub
# prints for the "djgpp" host, or else GDB configury will decide that
# this is a cross-build.
echo i586-pc-msdosdjgpp
exit ;;
Intel:Mach:3*:*)
echo i386-pc-mach3
exit ;;
paragon:*:*:*)
echo i860-intel-osf1
exit ;;
i860:*:4.*:*) # i860-SVR4
if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then
echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4
else # Add other i860-SVR4 vendors below as they are discovered.
echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4
fi
exit ;;
mini*:CTIX:SYS*5:*)
# "miniframe"
echo m68010-convergent-sysv
exit ;;
mc68k:UNIX:SYSTEM5:3.51m)
echo m68k-convergent-sysv
exit ;;
M680?0:D-NIX:5.3:*)
echo m68k-diab-dnix
exit ;;
M68*:*:R3V[5678]*:*)
test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;;
3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0)
OS_REL=''
test -r /etc/.relid \
&& OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
&& { echo i486-ncr-sysv4.3${OS_REL}; exit; }
/bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
&& { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
&& { echo i486-ncr-sysv4; exit; } ;;
NCR*:*:4.2:* | MPRAS*:*:4.2:*)
OS_REL='.3'
test -r /etc/.relid \
&& OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
&& { echo i486-ncr-sysv4.3${OS_REL}; exit; }
/bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
&& { echo i586-ncr-sysv4.3${OS_REL}; exit; }
/bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \
&& { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*)
echo m68k-unknown-lynxos${UNAME_RELEASE}
exit ;;
mc68030:UNIX_System_V:4.*:*)
echo m68k-atari-sysv4
exit ;;
TSUNAMI:LynxOS:2.*:*)
echo sparc-unknown-lynxos${UNAME_RELEASE}
exit ;;
rs6000:LynxOS:2.*:*)
echo rs6000-unknown-lynxos${UNAME_RELEASE}
exit ;;
PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*)
echo powerpc-unknown-lynxos${UNAME_RELEASE}
exit ;;
SM[BE]S:UNIX_SV:*:*)
echo mips-dde-sysv${UNAME_RELEASE}
exit ;;
RM*:ReliantUNIX-*:*:*)
echo mips-sni-sysv4
exit ;;
RM*:SINIX-*:*:*)
echo mips-sni-sysv4
exit ;;
*:SINIX-*:*:*)
if uname -p 2>/dev/null >/dev/null ; then
UNAME_MACHINE=`(uname -p) 2>/dev/null`
echo ${UNAME_MACHINE}-sni-sysv4
else
echo ns32k-sni-sysv
fi
exit ;;
PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
# says
echo i586-unisys-sysv4
exit ;;
*:UNIX_System_V:4*:FTX*)
# From Gerald Hewes .
# How about differentiating between stratus architectures? -djm
echo hppa1.1-stratus-sysv4
exit ;;
*:*:*:FTX*)
# From seanf@swdc.stratus.com.
echo i860-stratus-sysv4
exit ;;
i*86:VOS:*:*)
# From Paul.Green@stratus.com.
echo ${UNAME_MACHINE}-stratus-vos
exit ;;
*:VOS:*:*)
# From Paul.Green@stratus.com.
echo hppa1.1-stratus-vos
exit ;;
mc68*:A/UX:*:*)
echo m68k-apple-aux${UNAME_RELEASE}
exit ;;
news*:NEWS-OS:6*:*)
echo mips-sony-newsos6
exit ;;
R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
if [ -d /usr/nec ]; then
echo mips-nec-sysv${UNAME_RELEASE}
else
echo mips-unknown-sysv${UNAME_RELEASE}
fi
exit ;;
BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only.
echo powerpc-be-beos
exit ;;
BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only.
echo powerpc-apple-beos
exit ;;
BePC:BeOS:*:*) # BeOS running on Intel PC compatible.
echo i586-pc-beos
exit ;;
BePC:Haiku:*:*) # Haiku running on Intel PC compatible.
echo i586-pc-haiku
exit ;;
x86_64:Haiku:*:*)
echo x86_64-unknown-haiku
exit ;;
SX-4:SUPER-UX:*:*)
echo sx4-nec-superux${UNAME_RELEASE}
exit ;;
SX-5:SUPER-UX:*:*)
echo sx5-nec-superux${UNAME_RELEASE}
exit ;;
SX-6:SUPER-UX:*:*)
echo sx6-nec-superux${UNAME_RELEASE}
exit ;;
SX-7:SUPER-UX:*:*)
echo sx7-nec-superux${UNAME_RELEASE}
exit ;;
SX-8:SUPER-UX:*:*)
echo sx8-nec-superux${UNAME_RELEASE}
exit ;;
SX-8R:SUPER-UX:*:*)
echo sx8r-nec-superux${UNAME_RELEASE}
exit ;;
Power*:Rhapsody:*:*)
echo powerpc-apple-rhapsody${UNAME_RELEASE}
exit ;;
*:Rhapsody:*:*)
echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE}
exit ;;
*:Darwin:*:*)
UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown
eval $set_cc_for_build
if test "$UNAME_PROCESSOR" = unknown ; then
UNAME_PROCESSOR=powerpc
fi
if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \
(CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
grep IS_64BIT_ARCH >/dev/null
then
case $UNAME_PROCESSOR in
i386) UNAME_PROCESSOR=x86_64 ;;
powerpc) UNAME_PROCESSOR=powerpc64 ;;
esac
fi
fi
echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE}
exit ;;
*:procnto*:*:* | *:QNX:[0123456789]*:*)
UNAME_PROCESSOR=`uname -p`
if test "$UNAME_PROCESSOR" = "x86"; then
UNAME_PROCESSOR=i386
UNAME_MACHINE=pc
fi
echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE}
exit ;;
*:QNX:*:4*)
echo i386-pc-qnx
exit ;;
NEO-?:NONSTOP_KERNEL:*:*)
echo neo-tandem-nsk${UNAME_RELEASE}
exit ;;
NSE-*:NONSTOP_KERNEL:*:*)
echo nse-tandem-nsk${UNAME_RELEASE}
exit ;;
NSR-?:NONSTOP_KERNEL:*:*)
echo nsr-tandem-nsk${UNAME_RELEASE}
exit ;;
*:NonStop-UX:*:*)
echo mips-compaq-nonstopux
exit ;;
BS2000:POSIX*:*:*)
echo bs2000-siemens-sysv
exit ;;
DS/*:UNIX_System_V:*:*)
echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE}
exit ;;
*:Plan9:*:*)
# "uname -m" is not consistent, so use $cputype instead. 386
# is converted to i386 for consistency with other x86
# operating systems.
if test "$cputype" = "386"; then
UNAME_MACHINE=i386
else
UNAME_MACHINE="$cputype"
fi
echo ${UNAME_MACHINE}-unknown-plan9
exit ;;
*:TOPS-10:*:*)
echo pdp10-unknown-tops10
exit ;;
*:TENEX:*:*)
echo pdp10-unknown-tenex
exit ;;
KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*)
echo pdp10-dec-tops20
exit ;;
XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*)
echo pdp10-xkl-tops20
exit ;;
*:TOPS-20:*:*)
echo pdp10-unknown-tops20
exit ;;
*:ITS:*:*)
echo pdp10-unknown-its
exit ;;
SEI:*:*:SEIUX)
echo mips-sei-seiux${UNAME_RELEASE}
exit ;;
*:DragonFly:*:*)
echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
exit ;;
*:*VMS:*:*)
UNAME_MACHINE=`(uname -p) 2>/dev/null`
case "${UNAME_MACHINE}" in
A*) echo alpha-dec-vms ; exit ;;
I*) echo ia64-dec-vms ; exit ;;
V*) echo vax-dec-vms ; exit ;;
esac ;;
*:XENIX:*:SysV)
echo i386-pc-xenix
exit ;;
i*86:skyos:*:*)
echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//'
exit ;;
i*86:rdos:*:*)
echo ${UNAME_MACHINE}-pc-rdos
exit ;;
i*86:AROS:*:*)
echo ${UNAME_MACHINE}-pc-aros
exit ;;
x86_64:VMkernel:*:*)
echo ${UNAME_MACHINE}-unknown-esx
exit ;;
esac
eval $set_cc_for_build
cat >$dummy.c <
# include
#endif
main ()
{
#if defined (sony)
#if defined (MIPSEB)
/* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed,
I don't know.... */
printf ("mips-sony-bsd\n"); exit (0);
#else
#include
printf ("m68k-sony-newsos%s\n",
#ifdef NEWSOS4
"4"
#else
""
#endif
); exit (0);
#endif
#endif
#if defined (__arm) && defined (__acorn) && defined (__unix)
printf ("arm-acorn-riscix\n"); exit (0);
#endif
#if defined (hp300) && !defined (hpux)
printf ("m68k-hp-bsd\n"); exit (0);
#endif
#if defined (NeXT)
#if !defined (__ARCHITECTURE__)
#define __ARCHITECTURE__ "m68k"
#endif
int version;
version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`;
if (version < 4)
printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version);
else
printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version);
exit (0);
#endif
#if defined (MULTIMAX) || defined (n16)
#if defined (UMAXV)
printf ("ns32k-encore-sysv\n"); exit (0);
#else
#if defined (CMU)
printf ("ns32k-encore-mach\n"); exit (0);
#else
printf ("ns32k-encore-bsd\n"); exit (0);
#endif
#endif
#endif
#if defined (__386BSD__)
printf ("i386-pc-bsd\n"); exit (0);
#endif
#if defined (sequent)
#if defined (i386)
printf ("i386-sequent-dynix\n"); exit (0);
#endif
#if defined (ns32000)
printf ("ns32k-sequent-dynix\n"); exit (0);
#endif
#endif
#if defined (_SEQUENT_)
struct utsname un;
uname(&un);
if (strncmp(un.version, "V2", 2) == 0) {
printf ("i386-sequent-ptx2\n"); exit (0);
}
if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */
printf ("i386-sequent-ptx1\n"); exit (0);
}
printf ("i386-sequent-ptx\n"); exit (0);
#endif
#if defined (vax)
# if !defined (ultrix)
# include
# if defined (BSD)
# if BSD == 43
printf ("vax-dec-bsd4.3\n"); exit (0);
# else
# if BSD == 199006
printf ("vax-dec-bsd4.3reno\n"); exit (0);
# else
printf ("vax-dec-bsd\n"); exit (0);
# endif
# endif
# else
printf ("vax-dec-bsd\n"); exit (0);
# endif
# else
printf ("vax-dec-ultrix\n"); exit (0);
# endif
#endif
#if defined (alliant) && defined (i860)
printf ("i860-alliant-bsd\n"); exit (0);
#endif
exit (1);
}
EOF
$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` &&
{ echo "$SYSTEM_NAME"; exit; }
# Apollos put the system type in the environment.
test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; }
# Convex versions that predate uname can use getsysinfo(1)
if [ -x /usr/convex/getsysinfo ]
then
case `getsysinfo -f cpu_type` in
c1*)
echo c1-convex-bsd
exit ;;
c2*)
if getsysinfo -f scalar_acc
then echo c32-convex-bsd
else echo c2-convex-bsd
fi
exit ;;
c34*)
echo c34-convex-bsd
exit ;;
c38*)
echo c38-convex-bsd
exit ;;
c4*)
echo c4-convex-bsd
exit ;;
esac
fi
cat >&2 < in order to provide the needed
information to handle your system.
config.guess timestamp = $timestamp
uname -m = `(uname -m) 2>/dev/null || echo unknown`
uname -r = `(uname -r) 2>/dev/null || echo unknown`
uname -s = `(uname -s) 2>/dev/null || echo unknown`
uname -v = `(uname -v) 2>/dev/null || echo unknown`
/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null`
/bin/uname -X = `(/bin/uname -X) 2>/dev/null`
hostinfo = `(hostinfo) 2>/dev/null`
/bin/universe = `(/bin/universe) 2>/dev/null`
/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null`
/bin/arch = `(/bin/arch) 2>/dev/null`
/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null`
/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null`
UNAME_MACHINE = ${UNAME_MACHINE}
UNAME_RELEASE = ${UNAME_RELEASE}
UNAME_SYSTEM = ${UNAME_SYSTEM}
UNAME_VERSION = ${UNAME_VERSION}
EOF
exit 1
# Local variables:
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "timestamp='"
# time-stamp-format: "%:y-%02m-%02d"
# time-stamp-end: "'"
# End:
ddpt-0.94/install-sh 0000755 0001750 0001750 00000033255 12234471250 013411 0 ustar dougg dougg #!/bin/sh
# install - install a program, script, or datafile
scriptversion=2011-11-20.07; # UTC
# This originates from X11R5 (mit/util/scripts/install.sh), which was
# later released in X11R6 (xc/config/util/install.sh) with the
# following copyright and license.
#
# Copyright (C) 1994 X Consortium
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to
# deal in the Software without restriction, including without limitation the
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
# sell copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
# Except as contained in this notice, the name of the X Consortium shall not
# be used in advertising or otherwise to promote the sale, use or other deal-
# ings in this Software without prior written authorization from the X Consor-
# tium.
#
#
# FSF changes to this file are in the public domain.
#
# Calling this script install-sh is preferred over install.sh, to prevent
# 'make' implicit rules from creating a file called install from it
# when there is no Makefile.
#
# This script is compatible with the BSD install script, but was written
# from scratch.
nl='
'
IFS=" "" $nl"
# set DOITPROG to echo to test this script
# Don't use :- since 4.3BSD and earlier shells don't like it.
doit=${DOITPROG-}
if test -z "$doit"; then
doit_exec=exec
else
doit_exec=$doit
fi
# Put in absolute file names if you don't have them in your path;
# or use environment vars.
chgrpprog=${CHGRPPROG-chgrp}
chmodprog=${CHMODPROG-chmod}
chownprog=${CHOWNPROG-chown}
cmpprog=${CMPPROG-cmp}
cpprog=${CPPROG-cp}
mkdirprog=${MKDIRPROG-mkdir}
mvprog=${MVPROG-mv}
rmprog=${RMPROG-rm}
stripprog=${STRIPPROG-strip}
posix_glob='?'
initialize_posix_glob='
test "$posix_glob" != "?" || {
if (set -f) 2>/dev/null; then
posix_glob=
else
posix_glob=:
fi
}
'
posix_mkdir=
# Desired mode of installed file.
mode=0755
chgrpcmd=
chmodcmd=$chmodprog
chowncmd=
mvcmd=$mvprog
rmcmd="$rmprog -f"
stripcmd=
src=
dst=
dir_arg=
dst_arg=
copy_on_change=false
no_target_directory=
usage="\
Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
or: $0 [OPTION]... SRCFILES... DIRECTORY
or: $0 [OPTION]... -t DIRECTORY SRCFILES...
or: $0 [OPTION]... -d DIRECTORIES...
In the 1st form, copy SRCFILE to DSTFILE.
In the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
In the 4th, create DIRECTORIES.
Options:
--help display this help and exit.
--version display version info and exit.
-c (ignored)
-C install only if different (preserve the last data modification time)
-d create directories instead of installing files.
-g GROUP $chgrpprog installed files to GROUP.
-m MODE $chmodprog installed files to MODE.
-o USER $chownprog installed files to USER.
-s $stripprog installed files.
-t DIRECTORY install into DIRECTORY.
-T report an error if DSTFILE is a directory.
Environment variables override the default commands:
CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
RMPROG STRIPPROG
"
while test $# -ne 0; do
case $1 in
-c) ;;
-C) copy_on_change=true;;
-d) dir_arg=true;;
-g) chgrpcmd="$chgrpprog $2"
shift;;
--help) echo "$usage"; exit $?;;
-m) mode=$2
case $mode in
*' '* | *' '* | *'
'* | *'*'* | *'?'* | *'['*)
echo "$0: invalid mode: $mode" >&2
exit 1;;
esac
shift;;
-o) chowncmd="$chownprog $2"
shift;;
-s) stripcmd=$stripprog;;
-t) dst_arg=$2
# Protect names problematic for 'test' and other utilities.
case $dst_arg in
-* | [=\(\)!]) dst_arg=./$dst_arg;;
esac
shift;;
-T) no_target_directory=true;;
--version) echo "$0 $scriptversion"; exit $?;;
--) shift
break;;
-*) echo "$0: invalid option: $1" >&2
exit 1;;
*) break;;
esac
shift
done
if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
# When -d is used, all remaining arguments are directories to create.
# When -t is used, the destination is already specified.
# Otherwise, the last argument is the destination. Remove it from $@.
for arg
do
if test -n "$dst_arg"; then
# $@ is not empty: it contains at least $arg.
set fnord "$@" "$dst_arg"
shift # fnord
fi
shift # arg
dst_arg=$arg
# Protect names problematic for 'test' and other utilities.
case $dst_arg in
-* | [=\(\)!]) dst_arg=./$dst_arg;;
esac
done
fi
if test $# -eq 0; then
if test -z "$dir_arg"; then
echo "$0: no input file specified." >&2
exit 1
fi
# It's OK to call 'install-sh -d' without argument.
# This can happen when creating conditional directories.
exit 0
fi
if test -z "$dir_arg"; then
do_exit='(exit $ret); exit $ret'
trap "ret=129; $do_exit" 1
trap "ret=130; $do_exit" 2
trap "ret=141; $do_exit" 13
trap "ret=143; $do_exit" 15
# Set umask so as not to create temps with too-generous modes.
# However, 'strip' requires both read and write access to temps.
case $mode in
# Optimize common cases.
*644) cp_umask=133;;
*755) cp_umask=22;;
*[0-7])
if test -z "$stripcmd"; then
u_plus_rw=
else
u_plus_rw='% 200'
fi
cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
*)
if test -z "$stripcmd"; then
u_plus_rw=
else
u_plus_rw=,u+rw
fi
cp_umask=$mode$u_plus_rw;;
esac
fi
for src
do
# Protect names problematic for 'test' and other utilities.
case $src in
-* | [=\(\)!]) src=./$src;;
esac
if test -n "$dir_arg"; then
dst=$src
dstdir=$dst
test -d "$dstdir"
dstdir_status=$?
else
# Waiting for this to be detected by the "$cpprog $src $dsttmp" command
# might cause directories to be created, which would be especially bad
# if $src (and thus $dsttmp) contains '*'.
if test ! -f "$src" && test ! -d "$src"; then
echo "$0: $src does not exist." >&2
exit 1
fi
if test -z "$dst_arg"; then
echo "$0: no destination specified." >&2
exit 1
fi
dst=$dst_arg
# If destination is a directory, append the input filename; won't work
# if double slashes aren't ignored.
if test -d "$dst"; then
if test -n "$no_target_directory"; then
echo "$0: $dst_arg: Is a directory" >&2
exit 1
fi
dstdir=$dst
dst=$dstdir/`basename "$src"`
dstdir_status=0
else
# Prefer dirname, but fall back on a substitute if dirname fails.
dstdir=`
(dirname "$dst") 2>/dev/null ||
expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
X"$dst" : 'X\(//\)[^/]' \| \
X"$dst" : 'X\(//\)$' \| \
X"$dst" : 'X\(/\)' \| . 2>/dev/null ||
echo X"$dst" |
sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
s//\1/
q
}
/^X\(\/\/\)[^/].*/{
s//\1/
q
}
/^X\(\/\/\)$/{
s//\1/
q
}
/^X\(\/\).*/{
s//\1/
q
}
s/.*/./; q'
`
test -d "$dstdir"
dstdir_status=$?
fi
fi
obsolete_mkdir_used=false
if test $dstdir_status != 0; then
case $posix_mkdir in
'')
# Create intermediate dirs using mode 755 as modified by the umask.
# This is like FreeBSD 'install' as of 1997-10-28.
umask=`umask`
case $stripcmd.$umask in
# Optimize common cases.
*[2367][2367]) mkdir_umask=$umask;;
.*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;
*[0-7])
mkdir_umask=`expr $umask + 22 \
- $umask % 100 % 40 + $umask % 20 \
- $umask % 10 % 4 + $umask % 2
`;;
*) mkdir_umask=$umask,go-w;;
esac
# With -d, create the new directory with the user-specified mode.
# Otherwise, rely on $mkdir_umask.
if test -n "$dir_arg"; then
mkdir_mode=-m$mode
else
mkdir_mode=
fi
posix_mkdir=false
case $umask in
*[123567][0-7][0-7])
# POSIX mkdir -p sets u+wx bits regardless of umask, which
# is incompatible with FreeBSD 'install' when (umask & 300) != 0.
;;
*)
tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0
if (umask $mkdir_umask &&
exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1
then
if test -z "$dir_arg" || {
# Check for POSIX incompatibilities with -m.
# HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
# other-writable bit of parent directory when it shouldn't.
# FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
ls_ld_tmpdir=`ls -ld "$tmpdir"`
case $ls_ld_tmpdir in
d????-?r-*) different_mode=700;;
d????-?--*) different_mode=755;;
*) false;;
esac &&
$mkdirprog -m$different_mode -p -- "$tmpdir" && {
ls_ld_tmpdir_1=`ls -ld "$tmpdir"`
test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
}
}
then posix_mkdir=:
fi
rmdir "$tmpdir/d" "$tmpdir"
else
# Remove any dirs left behind by ancient mkdir implementations.
rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null
fi
trap '' 0;;
esac;;
esac
if
$posix_mkdir && (
umask $mkdir_umask &&
$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
)
then :
else
# The umask is ridiculous, or mkdir does not conform to POSIX,
# or it failed possibly due to a race condition. Create the
# directory the slow way, step by step, checking for races as we go.
case $dstdir in
/*) prefix='/';;
[-=\(\)!]*) prefix='./';;
*) prefix='';;
esac
eval "$initialize_posix_glob"
oIFS=$IFS
IFS=/
$posix_glob set -f
set fnord $dstdir
shift
$posix_glob set +f
IFS=$oIFS
prefixes=
for d
do
test X"$d" = X && continue
prefix=$prefix$d
if test -d "$prefix"; then
prefixes=
else
if $posix_mkdir; then
(umask=$mkdir_umask &&
$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
# Don't fail if two instances are running concurrently.
test -d "$prefix" || exit 1
else
case $prefix in
*\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
*) qprefix=$prefix;;
esac
prefixes="$prefixes '$qprefix'"
fi
fi
prefix=$prefix/
done
if test -n "$prefixes"; then
# Don't fail if two instances are running concurrently.
(umask $mkdir_umask &&
eval "\$doit_exec \$mkdirprog $prefixes") ||
test -d "$dstdir" || exit 1
obsolete_mkdir_used=true
fi
fi
fi
if test -n "$dir_arg"; then
{ test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&
{ test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&
{ test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||
test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1
else
# Make a couple of temp file names in the proper directory.
dsttmp=$dstdir/_inst.$$_
rmtmp=$dstdir/_rm.$$_
# Trap to clean up those temp files at exit.
trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
# Copy the file name to the temp name.
(umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") &&
# and set any options; do chmod last to preserve setuid bits.
#
# If any of these fail, we abort the whole thing. If we want to
# ignore errors from any of these, just make sure not to ignore
# errors from the above "$doit $cpprog $src $dsttmp" command.
#
{ test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } &&
{ test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } &&
{ test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } &&
{ test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&
# If -C, don't bother to copy if it wouldn't change the file.
if $copy_on_change &&
old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` &&
new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` &&
eval "$initialize_posix_glob" &&
$posix_glob set -f &&
set X $old && old=:$2:$4:$5:$6 &&
set X $new && new=:$2:$4:$5:$6 &&
$posix_glob set +f &&
test "$old" = "$new" &&
$cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
then
rm -f "$dsttmp"
else
# Rename the file to the real destination.
$doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||
# The rename failed, perhaps because mv can't rename something else
# to itself, or perhaps because mv is so ancient that it does not
# support -f.
{
# Now remove or move aside any old file at destination location.
# We try this two ways since rm can't unlink itself on some
# systems and the destination file might be busy for other
# reasons. In this case, the final cleanup might fail but the new
# file should still install successfully.
{
test ! -f "$dst" ||
$doit $rmcmd -f "$dst" 2>/dev/null ||
{ $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
{ $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }
} ||
{ echo "$0: cannot unlink or rename $dst" >&2
(exit 1); exit 1
}
} &&
# Now rename the file to the real destination.
$doit $mvcmd "$dsttmp" "$dst"
}
fi || exit 1
trap '' 0
fi
done
# Local variables:
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-time-zone: "UTC"
# time-stamp-end: "; # UTC"
# End:
ddpt-0.94/missing 0000755 0001750 0001750 00000015331 12234471250 012777 0 ustar dougg dougg #! /bin/sh
# Common wrapper for a few potentially missing GNU programs.
scriptversion=2012-06-26.16; # UTC
# Copyright (C) 1996-2013 Free Software Foundation, Inc.
# Originally written by Fran,cois Pinard , 1996.
# 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 distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program. If not, see .
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program.
if test $# -eq 0; then
echo 1>&2 "Try '$0 --help' for more information"
exit 1
fi
case $1 in
--is-lightweight)
# Used by our autoconf macros to check whether the available missing
# script is modern enough.
exit 0
;;
--run)
# Back-compat with the calling convention used by older automake.
shift
;;
-h|--h|--he|--hel|--help)
echo "\
$0 [OPTION]... PROGRAM [ARGUMENT]...
Run 'PROGRAM [ARGUMENT]...', returning a proper advice when this fails due
to PROGRAM being missing or too old.
Options:
-h, --help display this help and exit
-v, --version output version information and exit
Supported PROGRAM values:
aclocal autoconf autoheader autom4te automake makeinfo
bison yacc flex lex help2man
Version suffixes to PROGRAM as well as the prefixes 'gnu-', 'gnu', and
'g' are ignored when checking the name.
Send bug reports to ."
exit $?
;;
-v|--v|--ve|--ver|--vers|--versi|--versio|--version)
echo "missing $scriptversion (GNU Automake)"
exit $?
;;
-*)
echo 1>&2 "$0: unknown '$1' option"
echo 1>&2 "Try '$0 --help' for more information"
exit 1
;;
esac
# Run the given program, remember its exit status.
"$@"; st=$?
# If it succeeded, we are done.
test $st -eq 0 && exit 0
# Also exit now if we it failed (or wasn't found), and '--version' was
# passed; such an option is passed most likely to detect whether the
# program is present and works.
case $2 in --version|--help) exit $st;; esac
# Exit code 63 means version mismatch. This often happens when the user
# tries to use an ancient version of a tool on a file that requires a
# minimum version.
if test $st -eq 63; then
msg="probably too old"
elif test $st -eq 127; then
# Program was missing.
msg="missing on your system"
else
# Program was found and executed, but failed. Give up.
exit $st
fi
perl_URL=http://www.perl.org/
flex_URL=http://flex.sourceforge.net/
gnu_software_URL=http://www.gnu.org/software
program_details ()
{
case $1 in
aclocal|automake)
echo "The '$1' program is part of the GNU Automake package:"
echo "<$gnu_software_URL/automake>"
echo "It also requires GNU Autoconf, GNU m4 and Perl in order to run:"
echo "<$gnu_software_URL/autoconf>"
echo "<$gnu_software_URL/m4/>"
echo "<$perl_URL>"
;;
autoconf|autom4te|autoheader)
echo "The '$1' program is part of the GNU Autoconf package:"
echo "<$gnu_software_URL/autoconf/>"
echo "It also requires GNU m4 and Perl in order to run:"
echo "<$gnu_software_URL/m4/>"
echo "<$perl_URL>"
;;
esac
}
give_advice ()
{
# Normalize program name to check for.
normalized_program=`echo "$1" | sed '
s/^gnu-//; t
s/^gnu//; t
s/^g//; t'`
printf '%s\n' "'$1' is $msg."
configure_deps="'configure.ac' or m4 files included by 'configure.ac'"
case $normalized_program in
autoconf*)
echo "You should only need it if you modified 'configure.ac',"
echo "or m4 files included by it."
program_details 'autoconf'
;;
autoheader*)
echo "You should only need it if you modified 'acconfig.h' or"
echo "$configure_deps."
program_details 'autoheader'
;;
automake*)
echo "You should only need it if you modified 'Makefile.am' or"
echo "$configure_deps."
program_details 'automake'
;;
aclocal*)
echo "You should only need it if you modified 'acinclude.m4' or"
echo "$configure_deps."
program_details 'aclocal'
;;
autom4te*)
echo "You might have modified some maintainer files that require"
echo "the 'automa4te' program to be rebuilt."
program_details 'autom4te'
;;
bison*|yacc*)
echo "You should only need it if you modified a '.y' file."
echo "You may want to install the GNU Bison package:"
echo "<$gnu_software_URL/bison/>"
;;
lex*|flex*)
echo "You should only need it if you modified a '.l' file."
echo "You may want to install the Fast Lexical Analyzer package:"
echo "<$flex_URL>"
;;
help2man*)
echo "You should only need it if you modified a dependency" \
"of a man page."
echo "You may want to install the GNU Help2man package:"
echo "<$gnu_software_URL/help2man/>"
;;
makeinfo*)
echo "You should only need it if you modified a '.texi' file, or"
echo "any other file indirectly affecting the aspect of the manual."
echo "You might want to install the Texinfo package:"
echo "<$gnu_software_URL/texinfo/>"
echo "The spurious makeinfo call might also be the consequence of"
echo "using a buggy 'make' (AIX, DU, IRIX), in which case you might"
echo "want to install GNU make:"
echo "<$gnu_software_URL/make/>"
;;
*)
echo "You might have modified some files without having the proper"
echo "tools for further handling them. Check the 'README' file, it"
echo "often tells you about the needed prerequisites for installing"
echo "this package. You may also peek at any GNU archive site, in"
echo "case some other package contains this missing '$1' program."
;;
esac
}
give_advice "$1" | sed -e '1s/^/WARNING: /' \
-e '2,$s/^/ /' >&2
# Propagate the correct exit status (expected to be 127 for a program
# not found, 63 for a program that failed due to version mismatch).
exit $st
# Local variables:
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-time-zone: "UTC"
# time-stamp-end: "; # UTC"
# End:
ddpt-0.94/lib/ 0000755 0001750 0001750 00000000000 12320426231 012136 5 ustar dougg dougg ddpt-0.94/lib/sg_pt_common.c 0000644 0001750 0001750 00000000622 12207377272 015004 0 ustar dougg dougg /*
* Copyright (c) 2009-2013 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
#include "sg_pt.h"
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
static const char * scsi_pt_version_str = "2.10 20130827";
const char *
scsi_pt_version()
{
return scsi_pt_version_str;
}
ddpt-0.94/lib/sg_cmds_mmc.c 0000644 0001750 0001750 00000030025 12176051475 014572 0 ustar dougg dougg /*
* Copyright (c) 2008-2013 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
#include
#include
#include
#define __STDC_FORMAT_MACROS 1
#include
#include "sg_lib.h"
#include "sg_cmds_basic.h"
#include "sg_cmds_mmc.h"
#include "sg_pt.h"
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#define SENSE_BUFF_LEN 64 /* Arbitrary, could be larger */
#define DEF_PT_TIMEOUT 60 /* 60 seconds */
#define GET_CONFIG_CMD 0x46
#define GET_CONFIG_CMD_LEN 10
#define GET_PERFORMANCE_CMD 0xac
#define GET_PERFORMANCE_CMD_LEN 12
#define SET_CD_SPEED_CMD 0xbb
#define SET_CD_SPEED_CMDLEN 12
#define SET_STREAMING_CMD 0xb6
#define SET_STREAMING_CMDLEN 12
/* Invokes a SCSI SET CD SPEED command (MMC).
* Return of 0 -> success, SG_LIB_CAT_INVALID_OP -> command not supported,
* SG_LIB_CAT_ILLEGAL_REQ -> bad field in cdb, SG_LIB_CAT_UNIT_ATTENTION,
* SG_LIB_CAT_NOT_READY -> device not ready, SG_LIB_CAT_ABORTED_COMMAND,
* -1 -> other failure */
int
sg_ll_set_cd_speed(int sg_fd, int rot_control, int drv_read_speed,
int drv_write_speed, int noisy, int verbose)
{
int res, ret, k, sense_cat;
unsigned char scsCmdBlk[SET_CD_SPEED_CMDLEN] = {SET_CD_SPEED_CMD, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0 ,0};
unsigned char sense_b[SENSE_BUFF_LEN];
struct sg_pt_base * ptvp;
if (NULL == sg_warnings_strm)
sg_warnings_strm = stderr;
scsCmdBlk[1] |= (rot_control & 0x3);
scsCmdBlk[2] = (drv_read_speed >> 8) & 0xff;
scsCmdBlk[3] = drv_read_speed & 0xff;
scsCmdBlk[4] = (drv_write_speed >> 8) & 0xff;
scsCmdBlk[5] = drv_write_speed & 0xff;
if (verbose) {
fprintf(sg_warnings_strm, " set cd speed cdb: ");
for (k = 0; k < SET_CD_SPEED_CMDLEN; ++k)
fprintf(sg_warnings_strm, "%02x ", scsCmdBlk[k]);
fprintf(sg_warnings_strm, "\n");
}
ptvp = construct_scsi_pt_obj();
if (NULL == ptvp) {
fprintf(sg_warnings_strm, "set cd speed: out of memory\n");
return -1;
}
set_scsi_pt_cdb(ptvp, scsCmdBlk, sizeof(scsCmdBlk));
set_scsi_pt_sense(ptvp, sense_b, sizeof(sense_b));
res = do_scsi_pt(ptvp, sg_fd, DEF_PT_TIMEOUT, verbose);
ret = sg_cmds_process_resp(ptvp, "set cd speed", res, 0,
sense_b, noisy, verbose, &sense_cat);
if (-1 == ret)
;
else if (-2 == ret) {
switch (sense_cat) {
case SG_LIB_CAT_NOT_READY:
case SG_LIB_CAT_UNIT_ATTENTION:
case SG_LIB_CAT_INVALID_OP:
case SG_LIB_CAT_ILLEGAL_REQ:
case SG_LIB_CAT_ABORTED_COMMAND:
ret = sense_cat;
break;
case SG_LIB_CAT_RECOVERED:
case SG_LIB_CAT_NO_SENSE:
ret = 0;
break;
default:
ret = -1;
break;
}
} else
ret = 0;
destruct_scsi_pt_obj(ptvp);
return ret;
}
/* Invokes a SCSI GET CONFIGURATION command (MMC-3,4,5).
* Returns 0 when successful, SG_LIB_CAT_INVALID_OP if command not
* supported, SG_LIB_CAT_ILLEGAL_REQ if field in cdb not supported,
* SG_LIB_CAT_UNIT_ATTENTION, SG_LIB_CAT_ABORTED_COMMAND, else -1 */
int
sg_ll_get_config(int sg_fd, int rt, int starting, void * resp,
int mx_resp_len, int noisy, int verbose)
{
int res, k, ret, sense_cat;
unsigned char gcCmdBlk[GET_CONFIG_CMD_LEN] = {GET_CONFIG_CMD, 0, 0, 0,
0, 0, 0, 0, 0, 0};
unsigned char sense_b[SENSE_BUFF_LEN];
struct sg_pt_base * ptvp;
if (NULL == sg_warnings_strm)
sg_warnings_strm = stderr;
if ((rt < 0) || (rt > 3)) {
fprintf(sg_warnings_strm, "Bad rt value: %d\n", rt);
return -1;
}
gcCmdBlk[1] = (rt & 0x3);
if ((starting < 0) || (starting > 0xffff)) {
fprintf(sg_warnings_strm, "Bad starting field number: 0x%x\n",
starting);
return -1;
}
gcCmdBlk[2] = (unsigned char)((starting >> 8) & 0xff);
gcCmdBlk[3] = (unsigned char)(starting & 0xff);
if ((mx_resp_len < 0) || (mx_resp_len > 0xffff)) {
fprintf(sg_warnings_strm, "Bad mx_resp_len: 0x%x\n", starting);
return -1;
}
gcCmdBlk[7] = (unsigned char)((mx_resp_len >> 8) & 0xff);
gcCmdBlk[8] = (unsigned char)(mx_resp_len & 0xff);
if (verbose) {
fprintf(sg_warnings_strm, " Get Configuration cdb: ");
for (k = 0; k < GET_CONFIG_CMD_LEN; ++k)
fprintf(sg_warnings_strm, "%02x ", gcCmdBlk[k]);
fprintf(sg_warnings_strm, "\n");
}
ptvp = construct_scsi_pt_obj();
if (NULL == ptvp) {
fprintf(sg_warnings_strm, "get configuration: out of memory\n");
return -1;
}
set_scsi_pt_cdb(ptvp, gcCmdBlk, sizeof(gcCmdBlk));
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, sg_fd, DEF_PT_TIMEOUT, verbose);
ret = sg_cmds_process_resp(ptvp, "get configuration", res, mx_resp_len,
sense_b, noisy, verbose, &sense_cat);
if (-1 == ret)
;
else if (-2 == ret) {
switch (sense_cat) {
case SG_LIB_CAT_INVALID_OP:
case SG_LIB_CAT_ILLEGAL_REQ:
case SG_LIB_CAT_UNIT_ATTENTION:
case SG_LIB_CAT_ABORTED_COMMAND:
ret = sense_cat;
break;
case SG_LIB_CAT_RECOVERED:
case SG_LIB_CAT_NO_SENSE:
ret = 0;
break;
default:
ret = -1;
break;
}
} else {
if ((verbose > 2) && (ret > 3)) {
unsigned char * ucp;
int len;
ucp = (unsigned char *)resp;
len = (ucp[0] << 24) + (ucp[1] << 16) + (ucp[2] << 8) + ucp[3] +
4;
if (len < 0)
len = 0;
len = (ret < len) ? ret : len;
fprintf(sg_warnings_strm, " get configuration: response%s\n",
(len > 256 ? ", first 256 bytes" : ""));
dStrHexErr((const char *)resp, (len > 256 ? 256 : len), -1);
}
ret = 0;
}
destruct_scsi_pt_obj(ptvp);
return ret;
}
/* Invokes a SCSI GET PERFORMANCE command (MMC-3...6).
* Returns 0 when successful, SG_LIB_CAT_INVALID_OP if command not
* supported, SG_LIB_CAT_ILLEGAL_REQ if field in cdb not supported,
* SG_LIB_CAT_UNIT_ATTENTION, SG_LIB_CAT_ABORTED_COMMAND, else -1 */
int
sg_ll_get_performance(int sg_fd, int data_type, unsigned int starting_lba,
int max_num_desc, int ttype, void * resp,
int mx_resp_len, int noisy, int verbose)
{
int res, k, ret, sense_cat;
unsigned char gpCmdBlk[GET_PERFORMANCE_CMD_LEN] = {GET_PERFORMANCE_CMD, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
unsigned char sense_b[SENSE_BUFF_LEN];
struct sg_pt_base * ptvp;
if (NULL == sg_warnings_strm)
sg_warnings_strm = stderr;
if ((data_type < 0) || (data_type > 0x1f)) {
fprintf(sg_warnings_strm, "Bad data_type value: %d\n", data_type);
return -1;
}
gpCmdBlk[1] = (data_type & 0x1f);
gpCmdBlk[2] = (unsigned char)((starting_lba >> 24) & 0xff);
gpCmdBlk[3] = (unsigned char)((starting_lba >> 16) & 0xff);
gpCmdBlk[4] = (unsigned char)((starting_lba >> 8) & 0xff);
gpCmdBlk[3] = (unsigned char)(starting_lba & 0xff);
if ((max_num_desc < 0) || (max_num_desc > 0xffff)) {
fprintf(sg_warnings_strm, "Bad max_num_desc: 0x%x\n", max_num_desc);
return -1;
}
gpCmdBlk[8] = (unsigned char)((max_num_desc >> 8) & 0xff);
gpCmdBlk[9] = (unsigned char)(max_num_desc & 0xff);
if ((ttype < 0) || (ttype > 0xff)) {
fprintf(sg_warnings_strm, "Bad type: 0x%x\n", ttype);
return -1;
}
gpCmdBlk[10] = (unsigned char)ttype;
if (verbose) {
fprintf(sg_warnings_strm, " Get Performance cdb: ");
for (k = 0; k < GET_PERFORMANCE_CMD_LEN; ++k)
fprintf(sg_warnings_strm, "%02x ", gpCmdBlk[k]);
fprintf(sg_warnings_strm, "\n");
}
ptvp = construct_scsi_pt_obj();
if (NULL == ptvp) {
fprintf(sg_warnings_strm, "get performance: out of memory\n");
return -1;
}
set_scsi_pt_cdb(ptvp, gpCmdBlk, sizeof(gpCmdBlk));
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, sg_fd, DEF_PT_TIMEOUT, verbose);
ret = sg_cmds_process_resp(ptvp, "get performance", res, mx_resp_len,
sense_b, noisy, verbose, &sense_cat);
if (-1 == ret)
;
else if (-2 == ret) {
switch (sense_cat) {
case SG_LIB_CAT_INVALID_OP:
case SG_LIB_CAT_ILLEGAL_REQ:
case SG_LIB_CAT_UNIT_ATTENTION:
case SG_LIB_CAT_ABORTED_COMMAND:
ret = sense_cat;
break;
case SG_LIB_CAT_RECOVERED:
case SG_LIB_CAT_NO_SENSE:
ret = 0;
break;
default:
ret = -1;
break;
}
} else {
if ((verbose > 2) && (ret > 3)) {
unsigned char * ucp;
int len;
ucp = (unsigned char *)resp;
len = (ucp[0] << 24) + (ucp[1] << 16) + (ucp[2] << 8) + ucp[3] +
4;
if (len < 0)
len = 0;
len = (ret < len) ? ret : len;
fprintf(sg_warnings_strm, " get performance:: response%s\n",
(len > 256 ? ", first 256 bytes" : ""));
dStrHexErr((const char *)resp, (len > 256 ? 256 : len), -1);
}
ret = 0;
}
destruct_scsi_pt_obj(ptvp);
return ret;
}
/* Invokes a SCSI SET STREAMING command (MMC). Return of 0 -> success,
* SG_LIB_CAT_INVALID_OP -> Set Streaming not supported,
* SG_LIB_CAT_ILLEGAL_REQ -> bad field in cdb, SG_LIB_CAT_ABORTED_COMMAND,
* SG_LIB_CAT_UNIT_ATTENTION, SG_LIB_CAT_NOT_READY -> device not ready,
* -1 -> other failure */
int
sg_ll_set_streaming(int sg_fd, int type, void * paramp, int param_len,
int noisy, int verbose)
{
int k, res, ret, sense_cat;
unsigned char ssCmdBlk[SET_STREAMING_CMDLEN] =
{SET_STREAMING_CMD, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
unsigned char sense_b[SENSE_BUFF_LEN];
struct sg_pt_base * ptvp;
ssCmdBlk[8] = type;
ssCmdBlk[9] = (param_len >> 8) & 0xff;
ssCmdBlk[10] = param_len & 0xff;
if (NULL == sg_warnings_strm)
sg_warnings_strm = stderr;
if (verbose) {
fprintf(sg_warnings_strm, " set streaming cdb: ");
for (k = 0; k < SET_STREAMING_CMDLEN; ++k)
fprintf(sg_warnings_strm, "%02x ", ssCmdBlk[k]);
fprintf(sg_warnings_strm, "\n");
if ((verbose > 1) && paramp && param_len) {
fprintf(sg_warnings_strm, " set streaming "
"parameter list:\n");
dStrHexErr((const char *)paramp, param_len, -1);
}
}
ptvp = construct_scsi_pt_obj();
if (NULL == ptvp) {
fprintf(sg_warnings_strm, "set streaming: out of memory\n");
return -1;
}
set_scsi_pt_cdb(ptvp, ssCmdBlk, sizeof(ssCmdBlk));
set_scsi_pt_sense(ptvp, sense_b, sizeof(sense_b));
set_scsi_pt_data_out(ptvp, (unsigned char *)paramp, param_len);
res = do_scsi_pt(ptvp, sg_fd, DEF_PT_TIMEOUT, verbose);
ret = sg_cmds_process_resp(ptvp, "set streaming", res, 0,
sense_b, noisy, verbose, &sense_cat);
if (-1 == ret)
;
else if (-2 == ret) {
switch (sense_cat) {
case SG_LIB_CAT_NOT_READY:
case SG_LIB_CAT_INVALID_OP:
case SG_LIB_CAT_ILLEGAL_REQ:
case SG_LIB_CAT_UNIT_ATTENTION:
case SG_LIB_CAT_ABORTED_COMMAND:
ret = sense_cat;
break;
case SG_LIB_CAT_RECOVERED:
case SG_LIB_CAT_NO_SENSE:
ret = 0;
break;
default:
ret = -1;
break;
}
} else
ret = 0;
destruct_scsi_pt_obj(ptvp);
return ret;
}
ddpt-0.94/lib/sg_lib.c 0000644 0001750 0001750 00000206736 12316660506 013571 0 ustar dougg dougg /*
* Copyright (c) 1999-2014 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.
*/
/* NOTICE:
* On 5th October 2004 (v1.00) this file name was changed from sg_err.c
* to sg_lib.c and the previous GPL was changed to a FreeBSD license.
* The intention is to maintain this file and the related sg_lib.h file
* as open source and encourage their unencumbered use.
*
* CONTRIBUTIONS:
* This file started out as a copy of SCSI opcodes, sense keys and
* additional sense codes (ASC/ASCQ) kept in the Linux SCSI subsystem
* in the kernel source file: drivers/scsi/constant.c . That file
* bore this notice: "Copyright (C) 1993, 1994, 1995 Eric Youngdale"
* and a GPL notice.
*
* Much of the data in this file is derived from SCSI draft standards
* found at http://www.t10.org with the "SCSI Primary Commands-4" (SPC-4)
* being the central point of reference.
*
* Contributions:
* sense key specific field decoding [Trent Piepho 20031116]
*
*/
#include
#include
#include
#include
#include
#define __STDC_FORMAT_MACROS 1
#include
#include "sg_lib.h"
#include "sg_lib_data.h"
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
/* sg_lib_version_str (and datestamp) defined in sg_lib_data.c file */
#define ASCQ_ATA_PT_INFO_AVAILABLE 0x1d /* corresponding ASC is 0 */
FILE * sg_warnings_strm = NULL; /* would like to default to stderr */
/* Want safe, 'n += snprintf(b + n, blen - n, ...)' style sequence of
* functions. Returns number number of chars placed in cp excluding the
* trailing null char. So for cp_max_len > 0 the return value is always
* < cp_max_len; for cp_max_len <= 1 the return value is 0 and no chars
* are written to cp. Note this means that when cp_max_len = 1, this
* function assumes that cp[0] is the null character and does nothing
* (and returns 0). */
static int
my_snprintf(char * cp, int cp_max_len, const char * fmt, ...)
{
va_list args;
int n;
if (cp_max_len < 2)
return 0;
va_start(args, fmt);
n = vsnprintf(cp, cp_max_len, fmt, args);
va_end(args);
return (n < cp_max_len) ? n : (cp_max_len - 1);
}
/* Searches 'arr' for match on 'value' then 'peri_type'. If matches
'value' but not 'peri_type' then yields first 'value' match entry.
Last element of 'arr' has NULL 'name'. If no match returns NULL. */
static const struct sg_lib_value_name_t *
get_value_name(const struct sg_lib_value_name_t * arr, int value,
int peri_type)
{
const struct sg_lib_value_name_t * vp = arr;
const struct sg_lib_value_name_t * holdp;
for (; vp->name; ++vp) {
if (value == vp->value) {
if (peri_type == vp->peri_dev_type)
return vp;
holdp = vp;
while ((vp + 1)->name && (value == (vp + 1)->value)) {
++vp;
if (peri_type == vp->peri_dev_type)
return vp;
}
return holdp;
}
}
return NULL;
}
void
sg_set_warnings_strm(FILE * warnings_strm)
{
sg_warnings_strm = warnings_strm;
}
#define CMD_NAME_LEN 128
void
sg_print_command(const unsigned char * command)
{
int k, sz;
char buff[CMD_NAME_LEN];
sg_get_command_name(command, 0, CMD_NAME_LEN, buff);
buff[CMD_NAME_LEN - 1] = '\0';
if (NULL == sg_warnings_strm)
sg_warnings_strm = stderr;
fprintf(sg_warnings_strm, "%s [", buff);
if (SG_VARIABLE_LENGTH_CMD == command[0])
sz = command[7] + 8;
else
sz = sg_get_command_size(command[0]);
for (k = 0; k < sz; ++k)
fprintf(sg_warnings_strm, "%02x ", command[k]);
fprintf(sg_warnings_strm, "]\n");
}
void
sg_get_scsi_status_str(int scsi_status, int buff_len, char * buff)
{
const char * ccp;
if ((NULL == buff) || (buff_len < 1))
return;
else if (1 == buff_len) {
buff[0] = '\0';
return;
}
scsi_status &= 0x7e; /* sanitize as much as possible */
switch (scsi_status) {
case 0: ccp = "Good"; break;
case 0x2: ccp = "Check Condition"; break;
case 0x4: ccp = "Condition Met"; break;
case 0x8: ccp = "Busy"; break;
case 0x10: ccp = "Intermediate (obsolete)"; break;
case 0x14: ccp = "Intermediate-Condition Met (obs)"; break;
case 0x18: ccp = "Reservation Conflict"; break;
case 0x22: ccp = "Command Terminated (obsolete)"; break;
case 0x28: ccp = "Task set Full"; break;
case 0x30: ccp = "ACA Active"; break;
case 0x40: ccp = "Task Aborted"; break;
default: ccp = "Unknown status"; break;
}
my_snprintf(buff, buff_len, "%s", ccp);
}
void
sg_print_scsi_status(int scsi_status)
{
char buff[128];
sg_get_scsi_status_str(scsi_status, sizeof(buff) - 1, buff);
buff[sizeof(buff) - 1] = '\0';
if (NULL == sg_warnings_strm)
sg_warnings_strm = stderr;
fprintf(sg_warnings_strm, "%s ", buff);
}
int
sg_get_sense_key(const unsigned char * sensep, int sense_len)
{
if ((NULL == sensep) || (sense_len < 2))
return -1;
switch (sensep[0] & 0x7f) {
case 0x70:
case 0x71:
return (sense_len < 3) ? -1 : (sensep[2] & 0xf);
case 0x72:
case 0x73:
return sensep[1] & 0xf;
default:
return -1;
}
}
char *
sg_get_sense_key_str(int sense_key, int buff_len, char * buff)
{
if (1 == buff_len) {
buff[0] = '\0';
return buff;
}
if ((sense_key >= 0) && (sense_key < 16))
my_snprintf(buff, buff_len, "%s", sg_lib_sense_key_desc[sense_key]);
else
my_snprintf(buff, buff_len, "invalid value: 0x%x", sense_key);
return buff;
}
char *
sg_get_asc_ascq_str(int asc, int ascq, int buff_len, char * buff)
{
int k, num, rlen;
int found = 0;
struct sg_lib_asc_ascq_t * eip;
struct sg_lib_asc_ascq_range_t * ei2p;
if (1 == buff_len) {
buff[0] = '\0';
return buff;
}
for (k = 0; sg_lib_asc_ascq_range[k].text; ++k) {
ei2p = &sg_lib_asc_ascq_range[k];
if ((ei2p->asc == asc) &&
(ascq >= ei2p->ascq_min) &&
(ascq <= ei2p->ascq_max)) {
found = 1;
num = my_snprintf(buff, buff_len, "Additional sense: ");
rlen = buff_len - num;
num += my_snprintf(buff + num, ((rlen > 0) ? rlen : 0),
ei2p->text, ascq);
}
}
if (found)
return buff;
for (k = 0; sg_lib_asc_ascq[k].text; ++k) {
eip = &sg_lib_asc_ascq[k];
if (eip->asc == asc &&
eip->ascq == ascq) {
found = 1;
my_snprintf(buff, buff_len, "Additional sense: %s", eip->text);
}
}
if (! found) {
if (asc >= 0x80)
my_snprintf(buff, buff_len, "vendor specific ASC=%02x, "
"ASCQ=%02x (hex)", asc, ascq);
else if (ascq >= 0x80)
my_snprintf(buff, buff_len, "ASC=%02x, vendor specific "
"qualification ASCQ=%02x (hex)", asc, ascq);
else
my_snprintf(buff, buff_len, "ASC=%02x, ASCQ=%02x (hex)", asc,
ascq);
}
return buff;
}
const unsigned char *
sg_scsi_sense_desc_find(const unsigned char * sensep, int sense_len,
int desc_type)
{
int add_sb_len, add_d_len, desc_len, k;
const unsigned char * descp;
if ((sense_len < 8) || (0 == (add_sb_len = sensep[7])))
return NULL;
if ((sensep[0] < 0x72) || (sensep[0] > 0x73))
return NULL;
add_sb_len = (add_sb_len < (sense_len - 8)) ?
add_sb_len : (sense_len - 8);
descp = &sensep[8];
for (desc_len = 0, k = 0; k < add_sb_len; k += desc_len) {
descp += desc_len;
add_d_len = (k < (add_sb_len - 1)) ? descp[1]: -1;
desc_len = add_d_len + 2;
if (descp[0] == desc_type)
return descp;
if (add_d_len < 0) /* short descriptor ?? */
break;
}
return NULL;
}
int
sg_get_sense_info_fld(const unsigned char * sensep, int sb_len,
uint64_t * info_outp)
{
int j;
const unsigned char * ucp;
uint64_t ull;
if (info_outp)
*info_outp = 0;
if (sb_len < 7)
return 0;
switch (sensep[0] & 0x7f) {
case 0x70:
case 0x71:
if (info_outp)
*info_outp = ((unsigned int)sensep[3] << 24) + (sensep[4] << 16) +
(sensep[5] << 8) + sensep[6];
return (sensep[0] & 0x80) ? 1 : 0;
case 0x72:
case 0x73:
ucp = sg_scsi_sense_desc_find(sensep, sb_len, 0 /* info desc */);
if (ucp && (0xa == ucp[1])) {
ull = 0;
for (j = 0; j < 8; ++j) {
if (j > 0)
ull <<= 8;
ull |= ucp[4 + j];
}
if (info_outp)
*info_outp = ull;
return !!(ucp[2] & 0x80); /* since spc3r23 should be set */
} else
return 0;
default:
return 0;
}
}
int
sg_get_sense_filemark_eom_ili(const unsigned char * sensep, int sb_len,
int * filemark_p, int * eom_p, int * ili_p)
{
const unsigned char * ucp;
if (sb_len < 7)
return 0;
switch (sensep[0] & 0x7f) {
case 0x70:
case 0x71:
if (sensep[2] & 0xe0) {
if (filemark_p)
*filemark_p = !!(sensep[2] & 0x80);
if (eom_p)
*eom_p = !!(sensep[2] & 0x40);
if (ili_p)
*ili_p = !!(sensep[2] & 0x20);
return 1;
} else
return 0;
case 0x72:
case 0x73:
/* Look for stream commands sense data descriptor */
ucp = sg_scsi_sense_desc_find(sensep, sb_len, 4);
if (ucp && (ucp[1] >= 2)) {
if (ucp[3] & 0xe0) {
if (filemark_p)
*filemark_p = !!(ucp[3] & 0x80);
if (eom_p)
*eom_p = !!(ucp[3] & 0x40);
if (ili_p)
*ili_p = !!(ucp[3] & 0x20);
return 1;
}
}
return 0;
default:
return 0;
}
}
/* Returns 1 if SKSV is set and sense key is NO_SENSE or NOT_READY. Also
* returns 1 if progress indication sense data descriptor found. Places
* progress field from sense data where progress_outp points. If progress
* field is not available returns 0 and *progress_outp is unaltered. Handles
* both fixed and descriptor sense formats.
* Hint: if 1 is returned *progress_outp may be multiplied by 100 then
* divided by 65536 to get the percentage completion. */
int
sg_get_sense_progress_fld(const unsigned char * sensep, int sb_len,
int * progress_outp)
{
const unsigned char * ucp;
int sk, sk_pr;
if (sb_len < 7)
return 0;
switch (sensep[0] & 0x7f) {
case 0x70:
case 0x71:
sk = (sensep[2] & 0xf);
if ((sb_len < 18) ||
((SPC_SK_NO_SENSE != sk) && (SPC_SK_NOT_READY != sk)))
return 0;
if (sensep[15] & 0x80) { /* SKSV bit set */
if (progress_outp)
*progress_outp = (sensep[16] << 8) + sensep[17];
return 1;
} else
return 0;
case 0x72:
case 0x73:
/* sense key specific progress (0x2) or progress descriptor (0xa) */
sk = (sensep[1] & 0xf);
sk_pr = (SPC_SK_NO_SENSE == sk) || (SPC_SK_NOT_READY == sk);
if (sk_pr && ((ucp = sg_scsi_sense_desc_find(sensep, sb_len, 2))) &&
(0x6 == ucp[1]) && (0x80 & ucp[4])) {
if (progress_outp)
*progress_outp = (ucp[5] << 8) + ucp[6];
return 1;
} else if (((ucp = sg_scsi_sense_desc_find(sensep, sb_len, 0xa))) &&
((0x6 == ucp[1]))) {
if (progress_outp)
*progress_outp = (ucp[6] << 8) + ucp[7];
return 1;
} else
return 0;
default:
return 0;
}
}
char *
sg_get_pdt_str(int pdt, int buff_len, char * buff)
{
if ((pdt < 0) || (pdt > 31))
my_snprintf(buff, buff_len, "bad pdt");
else
my_snprintf(buff, buff_len, "%s", sg_lib_pdt_strs[pdt]);
return buff;
}
char *
sg_get_trans_proto_str(int tpi, int buff_len, char * buff)
{
if ((tpi < 0) || (tpi > 15))
my_snprintf(buff, buff_len, "bad tpi");
else
my_snprintf(buff, buff_len, "%s", sg_lib_transport_proto_strs[tpi]);
return buff;
}
#define TPGS_STATE_OPTIMIZED 0x0
#define TPGS_STATE_NONOPTIMIZED 0x1
#define TPGS_STATE_STANDBY 0x2
#define TPGS_STATE_UNAVAILABLE 0x3
#define TPGS_STATE_OFFLINE 0xe
#define TPGS_STATE_TRANSITIONING 0xf
static int
decode_tpgs_state(int st, char * b, int blen)
{
switch (st) {
case TPGS_STATE_OPTIMIZED:
return my_snprintf(b, blen, "active/optimized");
case TPGS_STATE_NONOPTIMIZED:
return my_snprintf(b, blen, "active/non optimized");
case TPGS_STATE_STANDBY:
return my_snprintf(b, blen, "standby");
case TPGS_STATE_UNAVAILABLE:
return my_snprintf(b, blen, "unavailable");
case TPGS_STATE_OFFLINE:
return my_snprintf(b, blen, "offline");
case TPGS_STATE_TRANSITIONING:
return my_snprintf(b, blen, "transitioning between states");
default:
return my_snprintf(b, blen, "unknown: 0x%x", st);
}
}
static int
uds_referral_descriptor_str(char * b, int blen, const unsigned char * dp,
int alen)
{
int n = 0;
int dlen = alen - 2;
int k, j, g, f, tpgd;
const unsigned char * tp;
uint64_t ull;
char c[40];
n += my_snprintf(b + n, blen - n, " Not all referrals: %d\n",
!!(dp[2] & 0x1));
dp += 4;
for (k = 0, f = 1; (k + 4) < dlen; k += g, dp += g, ++f) {
tpgd = dp[3];
g = (tpgd * 4) + 20;
n += my_snprintf(b + n, blen - n, " Descriptor %d\n", f);
if ((k + g) > dlen) {
n += my_snprintf(b + n, blen - n, " truncated descriptor, "
"stop\n");
return n;
}
ull = 0;
for (j = 0; j < 8; ++j) {
if (j > 0)
ull <<= 8;
ull |= dp[4 + j];
}
n += my_snprintf(b + n, blen - n, " first uds LBA: 0x%" PRIx64
"\n", ull);
ull = 0;
for (j = 0; j < 8; ++j) {
if (j > 0)
ull <<= 8;
ull |= dp[12 + j];
}
n += my_snprintf(b + n, blen - n, " last uds LBA: 0x%" PRIx64
"\n", ull);
for (j = 0; j < tpgd; ++j) {
tp = dp + 20 + (j * 4);
decode_tpgs_state(tp[0] & 0xf, c, sizeof(c));
n += my_snprintf(b + n, blen - n, " tpg: %d state: %s\n",
(tp[2] << 8) + tp[3], c);
}
}
return n;
}
static const char * sdata_src[] = {
"unknown",
"Extended Copy command source device",
"Extended Copy command destination device",
};
/* Decode descriptor format sense descriptors (assumes sense buffer is
* in descriptor format) */
static void
sg_get_sense_descriptors_str(const unsigned char * sense_buffer, int sb_len,
int blen, char * b)
{
int add_sb_len, add_d_len, desc_len, k, j, sense_key, processed;
int n, progress, pr, rem;
const unsigned char * descp;
const char * dtsp = " >> descriptor too short";
if ((NULL == b) || (blen <= 0))
return;
b[0] = '\0';
if ((sb_len < 8) || (0 == (add_sb_len = sense_buffer[7])))
return;
add_sb_len = (add_sb_len < (sb_len - 8)) ? add_sb_len : (sb_len - 8);
sense_key = (sense_buffer[1] & 0xf);
for (descp = (sense_buffer + 8), k = 0, n = 0;
(k < add_sb_len) && (n < blen);
k += desc_len, descp += desc_len) {
add_d_len = (k < (add_sb_len - 1)) ? descp[1] : -1;
if ((k + add_d_len + 2) > add_sb_len)
add_d_len = add_sb_len - k - 2;
desc_len = add_d_len + 2;
n += my_snprintf(b + n, blen - n, " Descriptor type: ");
processed = 1;
switch (descp[0]) {
case 0:
n += my_snprintf(b + n, blen - n, "Information\n");
if ((add_d_len >= 10) && (0x80 & descp[2])) {
n += my_snprintf(b + n, blen - n, " 0x");
for (j = 0; j < 8; ++j)
n += my_snprintf(b + n, blen - n, "%02x", descp[4 + j]);
n += my_snprintf(b + n, blen - n, "\n");
} else {
n += my_snprintf(b + n, blen - n, "%s\n", dtsp);
processed = 0;
}
break;
case 1:
n += my_snprintf(b + n, blen - n, "Command specific\n");
if (add_d_len >= 10) {
n += my_snprintf(b + n, blen - n, " 0x");
for (j = 0; j < 8; ++j)
n += my_snprintf(b + n, blen - n, "%02x", descp[4 + j]);
n += my_snprintf(b + n, blen - n, "\n");
} else {
n += my_snprintf(b + n, blen - n, "%s\n", dtsp);
processed = 0;
}
break;
case 2:
n += my_snprintf(b + n, blen - n, "Sense key specific:");
switch (sense_key) {
case SPC_SK_ILLEGAL_REQUEST:
n += my_snprintf(b + n, blen - n, " Field pointer\n");
if (add_d_len < 6) {
n += my_snprintf(b + n, blen - n, "%s\n", dtsp);
processed = 0;
break;
}
n += my_snprintf(b + n, blen - n, " Error in %s byte %d",
(descp[4] & 0x40) ? "Command" : "Data",
(descp[5] << 8) | descp[6]);
if (descp[4] & 0x08) {
n += my_snprintf(b + n, blen - n, " bit %d\n",
descp[4] & 0x07);
} else
n += my_snprintf(b + n, blen - n, "\n");
break;
case SPC_SK_HARDWARE_ERROR:
case SPC_SK_MEDIUM_ERROR:
case SPC_SK_RECOVERED_ERROR:
n += my_snprintf(b + n, blen - n, " Actual retry count\n");
if (add_d_len < 6) {
n += my_snprintf(b + n, blen - n, "%s\n", dtsp);
processed = 0;
break;
}
n += my_snprintf(b + n, blen - n," 0x%02x%02x\n", descp[5],
descp[6]);
break;
case SPC_SK_NO_SENSE:
case SPC_SK_NOT_READY:
n += my_snprintf(b + n, blen - n, " Progress indication: ");
if (add_d_len < 6) {
n += my_snprintf(b + n, blen - n, "%s\n", dtsp);
processed = 0;
break;
}
progress = (descp[5] << 8) + descp[6];
pr = (progress * 100) / 65536;
rem = ((progress * 100) % 65536) / 656;
n += my_snprintf(b + n, blen - n, "%d.%02d%%\n", pr, rem);
break;
case SPC_SK_COPY_ABORTED:
n += my_snprintf(b + n, blen - n, " Segment pointer\n");
if (add_d_len < 6) {
n += my_snprintf(b + n, blen - n, "%s\n", dtsp);
processed = 0;
break;
}
n += my_snprintf(b + n, blen - n, " Relative to start of %s, "
"byte %d",
(descp[4] & 0x20) ? "segment descriptor" :
"parameter list",
(descp[5] << 8) | descp[6]);
if (descp[4] & 0x08)
n += my_snprintf(b + n, blen - n, " bit %d\n",
descp[4] & 0x07);
else
n += my_snprintf(b + n, blen - n, "\n");
break;
case SPC_SK_UNIT_ATTENTION:
n += my_snprintf(b + n, blen - n, " Unit attention condition "
"queue: ");
n += my_snprintf(b + n, blen - n, "overflow flag is %d\n",
!!(descp[4] & 0x1));
break;
default:
n += my_snprintf(b + n, blen - n, " Sense_key: 0x%x "
"unexpected\n", sense_key);
processed = 0;
break;
}
break;
case 3:
n += my_snprintf(b + n, blen - n, "Field replaceable unit\n");
if (add_d_len >= 2)
n += my_snprintf(b + n, blen - n, " code=0x%x\n",
descp[3]);
else {
n += my_snprintf(b + n, blen - n, "%s\n", dtsp);
processed = 0;
}
break;
case 4:
n += my_snprintf(b + n, blen - n, "Stream commands\n");
if (add_d_len >= 2) {
if (descp[3] & 0x80)
n += my_snprintf(b + n, blen - n, " FILEMARK");
if (descp[3] & 0x40)
n += my_snprintf(b + n, blen - n, " End Of Medium "
"(EOM)");
if (descp[3] & 0x20)
n += my_snprintf(b + n, blen - n, " Incorrect Length "
"Indicator (ILI)");
n += my_snprintf(b + n, blen - n, "\n");
} else {
n += my_snprintf(b + n, blen - n, "%s\n", dtsp);
processed = 0;
}
break;
case 5:
n += my_snprintf(b + n, blen - n, "Block commands\n");
if (add_d_len >= 2)
n += my_snprintf(b + n, blen - n, " Incorrect Length "
"Indicator (ILI) %s\n",
(descp[3] & 0x20) ? "set" : "clear");
else {
n += my_snprintf(b + n, blen - n, "%s\n", dtsp);
processed = 0;
}
break;
case 6:
n += my_snprintf(b + n, blen - n, "OSD object identification\n");
processed = 0;
break;
case 7:
n += my_snprintf(b + n, blen - n, "OSD response integrity check "
"value\n");
processed = 0;
break;
case 8:
n += my_snprintf(b + n, blen - n, "OSD attribute "
"identification\n");
processed = 0;
break;
case 9: /* this is defined in SAT (and SAT-2) */
n += my_snprintf(b + n, blen - n, "ATA Status Return\n");
if (add_d_len >= 12) {
int extend, sector_count;
extend = descp[2] & 1;
sector_count = descp[5] + (extend ? (descp[4] << 8) : 0);
n += my_snprintf(b + n, blen - n, " extend=%d error=0x%x "
" sector_count=0x%x\n", extend, descp[3],
sector_count);
if (extend)
n += my_snprintf(b + n, blen - n, " "
"lba=0x%02x%02x%02x%02x%02x%02x\n",
descp[10], descp[8], descp[6],
descp[11], descp[9], descp[7]);
else
n += my_snprintf(b + n, blen - n, " "
"lba=0x%02x%02x%02x\n",
descp[11], descp[9], descp[7]);
n += my_snprintf(b + n, blen - n, " device=0x%x "
"status=0x%x\n", descp[12], descp[13]);
} else {
n += my_snprintf(b + n, blen - n, "%s\n", dtsp);
processed = 0;
}
break;
case 0xa:
/* Added in SPC-4 rev 17, became 'Another ...' in rev 34 */
n += my_snprintf(b + n, blen - n, "Another progress "
"indication\n");
if (add_d_len < 6) {
n += my_snprintf(b + n, blen - n, "%s\n", dtsp);
processed = 0;
break;
}
progress = (descp[6] << 8) + descp[7];
pr = (progress * 100) / 65536;
rem = ((progress * 100) % 65536) / 656;
n += my_snprintf(b + n, blen - n, " %d.02%d%%", pr, rem);
n += my_snprintf(b + n, blen - n, " [sense_key=0x%x "
"asc,ascq=0x%x,0x%x]\n",
descp[2], descp[3], descp[4]);
break;
case 0xb: /* Added in SPC-4 rev 23, defined in SBC-3 rev 22 */
n += my_snprintf(b + n, blen - n, "User data segment referral\n");
if (add_d_len < 2) {
n += my_snprintf(b + n, blen - n, "%s\n", dtsp);
processed = 0;
break;
}
n += uds_referral_descriptor_str(b + n, blen - n, descp,
add_d_len);
break;
case 0xc: /* Added in SPC-4 rev 28 */
n += my_snprintf(b + n, blen - n, "Forwarded sense data\n");
if (add_d_len < 2) {
n += my_snprintf(b + n, blen - n, "%s\n", dtsp);
processed = 0;
break;
}
n += my_snprintf(b + n, blen - n, " FSDT: %s\n",
(descp[2] & 0x80) ? "set" : "clear");
j = descp[2] & 0xf;
if (j < 3)
n += my_snprintf(b + n, blen - n, " Sense data source: "
"%s\n", sdata_src[j]);
else
n += my_snprintf(b + n, blen - n, " Sense data source: "
"reserved [%d]\n", j);
{
char c[200];
sg_get_scsi_status_str(descp[3], sizeof(c) - 1, c);
c[sizeof(c) - 1] = '\0';
n += my_snprintf(b + n, blen - n, " Forwarded status: "
"%s\n", c);
if (add_d_len > 2) {
/* recursing; hope not to get carried away */
n += my_snprintf(b + n, blen - n, " vvvvvvvvvvvvvvvv\n");
sg_get_sense_str(NULL, descp + 4, add_d_len - 2, 0,
sizeof(c), c);
n += my_snprintf(b + n, blen - n, "%s", c);
n += my_snprintf(b + n, blen - n, " ^^^^^^^^^^^^^^^^\n");
}
}
break;
default:
if (descp[0] >= 0x80)
n += my_snprintf(b + n, blen - n, "Vendor specific [0x%x]\n",
descp[0]);
else
n += my_snprintf(b + n, blen - n, "Unknown [0x%x]\n",
descp[0]);
processed = 0;
break;
}
if (! processed) {
if (add_d_len > 0) {
n += my_snprintf(b + n, blen - n, " ");
for (j = 0; j < add_d_len; ++j) {
if ((j > 0) && (0 == (j % 24)))
n += my_snprintf(b + n, blen - n, "\n ");
n += my_snprintf(b + n, blen - n, "%02x ", descp[j + 2]);
}
n += my_snprintf(b + n, blen - n, "\n");
}
}
if (add_d_len < 0)
n += my_snprintf(b + n, blen - n, " short descriptor\n");
}
}
/* Decode SAT ATA PASS-THROUGH fixed format sense */
static void
sg_get_sense_sat_pt_fixed_str(const unsigned char * sp, int slen, int blen,
char * b)
{
int n = 0;
if (slen) { ; } /* unused, suppress warning */
if (blen < 1)
return;
if (SPC_SK_RECOVERED_ERROR != (0xf & sp[2]))
n += my_snprintf(b + n, blen - n, " >> expected Sense key: "
"Recovered Error ??\n");
n += my_snprintf(b + n, blen - n, " error=0x%x, status=0x%x, "
"device=0x%x, sector_count(7:0)=0x%x%c\n", sp[3], sp[4],
sp[5], sp[6], ((0x40 & sp[8]) ? '+' : ' '));
n += my_snprintf(b + n, blen - n, " extend=%d, log_index=0x%x, "
"lba_high,mid,low(7:0)=0x%x,0x%x,0x%x%c\n",
(!!(0x80 & sp[8])), (0xf & sp[8]), sp[9], sp[10], sp[11],
((0x20 & sp[8]) ? '+' : ' '));
}
/* Fetch sense information */
void
sg_get_sense_str(const char * leadin, const unsigned char * sense_buffer,
int sb_len, int raw_sinfo, int buff_len, char * buff)
{
int len, valid, progress, n, r, pr, rem, blen;
unsigned int info;
int descriptor_format = 0;
int sdat_ovfl = 0;
const char * ebp = NULL;
char error_buff[64];
char b[256];
struct sg_scsi_sense_hdr ssh;
if ((NULL == buff) || (buff_len <= 0))
return;
else if (1 == buff_len) {
buff[0] = '\0';
return;
}
blen = sizeof(b);
n = 0;
if (sb_len < 1) {
my_snprintf(buff, buff_len, "sense buffer empty\n");
return;
}
if (leadin)
n += my_snprintf(buff + n, buff_len - n, "%s: ", leadin);
len = sb_len;
if (sg_scsi_normalize_sense(sense_buffer, sb_len, &ssh)) {
switch (ssh.response_code) {
case 0x70: /* fixed, current */
ebp = "Fixed format, current";
len = (sb_len > 7) ? (sense_buffer[7] + 8) : sb_len;
len = (len > sb_len) ? sb_len : len;
sdat_ovfl = (len > 2) ? !!(sense_buffer[2] & 0x10) : 0;
break;
case 0x71: /* fixed, deferred */
/* error related to a previous command */
ebp = "Fixed format, <<>>";
len = (sb_len > 7) ? (sense_buffer[7] + 8) : sb_len;
len = (len > sb_len) ? sb_len : len;
sdat_ovfl = (len > 2) ? !!(sense_buffer[2] & 0x10) : 0;
break;
case 0x72: /* descriptor, current */
descriptor_format = 1;
ebp = "Descriptor format, current";
sdat_ovfl = (sb_len > 4) ? !!(sense_buffer[4] & 0x80) : 0;
break;
case 0x73: /* descriptor, deferred */
descriptor_format = 1;
ebp = "Descriptor format, <<>>";
sdat_ovfl = (sb_len > 4) ? !!(sense_buffer[4] & 0x80) : 0;
break;
case 0x0:
ebp = "Response code: 0x0 (?)";
break;
default:
my_snprintf(error_buff, sizeof(error_buff),
"Unknown response code: 0x%x", ssh.response_code);
ebp = error_buff;
break;
}
n += my_snprintf(buff + n, buff_len - n, " %s; Sense key: %s\n ",
ebp, sg_lib_sense_key_desc[ssh.sense_key]);
if (sdat_ovfl)
n += my_snprintf(buff + n, buff_len - n, "<<>>\n");
if (descriptor_format) {
n += my_snprintf(buff + n, buff_len - n, "%s\n",
sg_get_asc_ascq_str(ssh.asc, ssh.ascq,
sizeof(b), b));
sg_get_sense_descriptors_str(sense_buffer, len, buff_len - n,
buff + n);
n = strlen(buff);
} else if ((len > 12) && (0 == ssh.asc) &&
(ASCQ_ATA_PT_INFO_AVAILABLE == ssh.ascq)) {
/* SAT ATA PASS-THROUGH fixed format */
n += my_snprintf(buff + n, buff_len - n, "%s\n",
sg_get_asc_ascq_str(ssh.asc, ssh.ascq,
sizeof(b), b));
sg_get_sense_sat_pt_fixed_str(sense_buffer, len, buff_len - n,
buff + n);
n = strlen(buff);
} else if (len > 2) { /* fixed format */
if (len > 12)
n += my_snprintf(buff + n, buff_len - n, "%s\n",
sg_get_asc_ascq_str(ssh.asc, ssh.ascq,
sizeof(b), b));
r = 0;
valid = sense_buffer[0] & 0x80;
if (len > 6) {
info = (unsigned int)((sense_buffer[3] << 24) |
(sense_buffer[4] << 16) | (sense_buffer[5] << 8) |
sense_buffer[6]);
if (valid)
r += my_snprintf(b + r, blen - r, " Info fld=0x%x [%u] ",
info, info);
else if (info > 0)
r += my_snprintf(b + r, blen - r, " Valid=0, Info "
"fld=0x%x [%u] ", info, info);
} else
info = 0;
if (sense_buffer[2] & 0xe0) {
if (sense_buffer[2] & 0x80)
r += my_snprintf(b + r, blen - r, " FMK");
/* current command has read a filemark */
if (sense_buffer[2] & 0x40)
r += my_snprintf(b + r, blen - r, " EOM");
/* end-of-medium condition exists */
if (sense_buffer[2] & 0x20)
r += my_snprintf(b + r, blen - r, " ILI");
/* incorrect block length requested */
r += my_snprintf(b + r, blen - r, "\n");
} else if (valid || (info > 0))
r += my_snprintf(b + r, blen - r, "\n");
if ((len >= 14) && sense_buffer[14])
r += my_snprintf(b + r, blen - r, " Field replaceable unit "
"code: %d\n", sense_buffer[14]);
if ((len >= 18) && (sense_buffer[15] & 0x80)) {
/* sense key specific decoding */
switch (ssh.sense_key) {
case SPC_SK_ILLEGAL_REQUEST:
r += my_snprintf(b + r, blen - r, " Sense Key Specific: "
"Error in %s byte %d",
((sense_buffer[15] & 0x40) ? "Command" : "Data"),
(sense_buffer[16] << 8) | sense_buffer[17]);
if (sense_buffer[15] & 0x08)
r += my_snprintf(b + r, blen - r, " bit %d\n",
sense_buffer[15] & 0x07);
else
r += my_snprintf(b + r, blen - r, "\n");
break;
case SPC_SK_NO_SENSE:
case SPC_SK_NOT_READY:
progress = (sense_buffer[16] << 8) + sense_buffer[17];
pr = (progress * 100) / 65536;
rem = ((progress * 100) % 65536) / 656;
r += my_snprintf(b + r, blen - r, " Progress "
"indication: %d.%02d%%\n", pr, rem);
break;
case SPC_SK_HARDWARE_ERROR:
case SPC_SK_MEDIUM_ERROR:
case SPC_SK_RECOVERED_ERROR:
r += my_snprintf(b + r, blen - r, " Actual retry count: "
"0x%02x%02x\n", sense_buffer[16],
sense_buffer[17]);
break;
case SPC_SK_COPY_ABORTED:
r += my_snprintf(b + r, blen - r, " Segment pointer: ");
r += my_snprintf(b + r, blen - r, "Relative to start of "
"%s, byte %d",
((sense_buffer[15] & 0x20) ?
"segment descriptor" : "parameter list"),
((sense_buffer[16] << 8) +
sense_buffer[17]));
if (sense_buffer[15] & 0x08)
r += my_snprintf(b + r, blen - r, " bit %d\n",
sense_buffer[15] & 0x07);
else
r += my_snprintf(b + r, blen - r, "\n");
break;
case SPC_SK_UNIT_ATTENTION:
r += my_snprintf(b + r, blen - r, " Unit attention "
"condition queue: ");
r += my_snprintf(b + r, blen - r, "overflow flag is %d\n",
!!(sense_buffer[15] & 0x1));
break;
default:
r += my_snprintf(b + r, blen - r, " Sense_key: 0x%x "
"unexpected\n", ssh.sense_key);
break;
}
}
if (r > 0)
n += my_snprintf(buff + n, buff_len - n, "%s", b);
} else
n += my_snprintf(buff + n, buff_len - n, " fixed descriptor "
"length too short, len=%d\n", len);
} else { /* non-extended SCSI-1 sense data ?? */
if (sb_len < 4) {
n += my_snprintf(buff + n, buff_len - n, "sense buffer too short "
"(4 byte minimum)\n");
return;
}
r = 0;
r += my_snprintf(b + r, blen - r, "Probably uninitialized data.\n "
"Try to view as SCSI-1 non-extended sense:\n");
r += my_snprintf(b + r, blen - r, " AdValid=%d Error class=%d "
"Error code=%d\n", !!(sense_buffer[0] & 0x80),
((sense_buffer[0] >> 4) & 0x7),
(sense_buffer[0] & 0xf));
if (sense_buffer[0] & 0x80)
r += my_snprintf(b + r, blen - r, " lba=0x%x\n",
((sense_buffer[1] & 0x1f) << 16) +
(sense_buffer[2] << 8) + sense_buffer[3]);
n += my_snprintf(buff + n, buff_len - n, "%s\n", b);
len = sb_len;
if (len > 32)
len = 32; /* trim in case there is a lot of rubbish */
}
if (raw_sinfo) {
n += my_snprintf(buff + n, buff_len - n, " Raw sense data (in hex):"
"\n");
if (n >= (buff_len - 1))
return;
dStrHexStr((const char *)sense_buffer, len, " ", 0,
buff_len - n, buff + n);
}
}
/* Print sense information */
void
sg_print_sense(const char * leadin, const unsigned char * sense_buffer,
int sb_len, int raw_sinfo)
{
char b[2048];
sg_get_sense_str(leadin, sense_buffer, sb_len, raw_sinfo, sizeof(b), b);
if (NULL == sg_warnings_strm)
sg_warnings_strm = stderr;
fprintf(sg_warnings_strm, "%s", b);
}
/* See description in sg_lib.h header file */
int
sg_scsi_normalize_sense(const unsigned char * sensep, int sb_len,
struct sg_scsi_sense_hdr * sshp)
{
if (sshp)
memset(sshp, 0, sizeof(struct sg_scsi_sense_hdr));
if ((NULL == sensep) || (0 == sb_len) || (0x70 != (0x70 & sensep[0])))
return 0;
if (sshp) {
sshp->response_code = (0x7f & sensep[0]);
if (sshp->response_code >= 0x72) { /* descriptor format */
if (sb_len > 1)
sshp->sense_key = (0xf & sensep[1]);
if (sb_len > 2)
sshp->asc = sensep[2];
if (sb_len > 3)
sshp->ascq = sensep[3];
if (sb_len > 7)
sshp->additional_length = sensep[7];
} else { /* fixed format */
if (sb_len > 2)
sshp->sense_key = (0xf & sensep[2]);
if (sb_len > 7) {
sb_len = (sb_len < (sensep[7] + 8)) ? sb_len :
(sensep[7] + 8);
if (sb_len > 12)
sshp->asc = sensep[12];
if (sb_len > 13)
sshp->ascq = sensep[13];
}
}
}
return 1;
}
/* Returns a SG_LIB_CAT_* value. If cannot decode sense_buffer or a less
* common sense key then return SG_LIB_CAT_SENSE .*/
int
sg_err_category_sense(const unsigned char * sense_buffer, int sb_len)
{
struct sg_scsi_sense_hdr ssh;
if ((sense_buffer && (sb_len > 2)) &&
(sg_scsi_normalize_sense(sense_buffer, sb_len, &ssh))) {
switch (ssh.sense_key) { /* 0 to 0x1f */
case SPC_SK_NO_SENSE:
return SG_LIB_CAT_NO_SENSE;
case SPC_SK_RECOVERED_ERROR:
return SG_LIB_CAT_RECOVERED;
case SPC_SK_NOT_READY:
return SG_LIB_CAT_NOT_READY;
case SPC_SK_MEDIUM_ERROR:
case SPC_SK_HARDWARE_ERROR:
case SPC_SK_BLANK_CHECK:
return SG_LIB_CAT_MEDIUM_HARD;
case SPC_SK_UNIT_ATTENTION:
return SG_LIB_CAT_UNIT_ATTENTION;
/* used to return SG_LIB_CAT_MEDIA_CHANGED when ssh.asc==0x28 */
case SPC_SK_ILLEGAL_REQUEST:
if ((0x20 == ssh.asc) && (0x0 == ssh.ascq))
return SG_LIB_CAT_INVALID_OP;
else
return SG_LIB_CAT_ILLEGAL_REQ;
break;
case SPC_SK_ABORTED_COMMAND:
return SG_LIB_CAT_ABORTED_COMMAND;
case SPC_SK_MISCOMPARE:
return SG_LIB_CAT_MISCOMPARE;
case SPC_SK_DATA_PROTECT:
case SPC_SK_COMPLETED:
case SPC_SK_COPY_ABORTED:
case SPC_SK_VOLUME_OVERFLOW:
return SG_LIB_CAT_SENSE;
default:
; /* reserved and vendor specific sense keys fall through */
}
}
return SG_LIB_CAT_SENSE;
}
/* Beware: gives wrong answer for variable length command (opcode=0x7f) */
int
sg_get_command_size(unsigned char opcode)
{
switch ((opcode >> 5) & 0x7) {
case 0:
return 6;
case 1: case 2: case 6: case 7:
return 10;
case 3: case 5:
return 12;
break;
case 4:
return 16;
default:
return 10;
}
}
void
sg_get_command_name(const unsigned char * cmdp, int peri_type, int buff_len,
char * buff)
{
int service_action;
if ((NULL == buff) || (buff_len < 1))
return;
else if (1 == buff_len) {
buff[0] = '\0';
return;
}
if (NULL == cmdp) {
my_snprintf(buff, buff_len, "%s", " command pointer");
return;
}
service_action = (SG_VARIABLE_LENGTH_CMD == cmdp[0]) ?
((cmdp[8] << 8) | cmdp[9]) : (cmdp[1] & 0x1f);
sg_get_opcode_sa_name(cmdp[0], service_action, peri_type, buff_len, buff);
}
void
sg_get_opcode_sa_name(unsigned char cmd_byte0, int service_action,
int peri_type, int buff_len, char * buff)
{
const struct sg_lib_value_name_t * vnp;
if ((NULL == buff) || (buff_len < 1))
return;
else if (1 == buff_len) {
buff[0] = '\0';
return;
}
switch ((int)cmd_byte0) {
case SG_VARIABLE_LENGTH_CMD:
vnp = get_value_name(sg_lib_variable_length_arr, service_action,
peri_type);
if (vnp)
my_snprintf(buff, buff_len, "%s", vnp->name);
else
my_snprintf(buff, buff_len, "Variable length service action=0x%x",
service_action);
break;
case SG_MAINTENANCE_IN:
vnp = get_value_name(sg_lib_maint_in_arr, service_action, peri_type);
if (vnp)
my_snprintf(buff, buff_len, "%s", vnp->name);
else
my_snprintf(buff, buff_len, "Maintenance in service action=0x%x",
service_action);
break;
case SG_MAINTENANCE_OUT:
vnp = get_value_name(sg_lib_maint_out_arr, service_action, peri_type);
if (vnp)
my_snprintf(buff, buff_len, "%s", vnp->name);
else
my_snprintf(buff, buff_len, "Maintenance out service action=0x%x",
service_action);
break;
case SG_SERVICE_ACTION_IN_12:
vnp = get_value_name(sg_lib_serv_in12_arr, service_action, peri_type);
if (vnp)
my_snprintf(buff, buff_len, "%s", vnp->name);
else
my_snprintf(buff, buff_len, "Service action in(12)=0x%x",
service_action);
break;
case SG_SERVICE_ACTION_OUT_12:
vnp = get_value_name(sg_lib_serv_out12_arr, service_action, peri_type);
if (vnp)
my_snprintf(buff, buff_len, "%s", vnp->name);
else
my_snprintf(buff, buff_len, "Service action out(12)=0x%x",
service_action);
break;
case SG_SERVICE_ACTION_IN_16:
vnp = get_value_name(sg_lib_serv_in16_arr, service_action, peri_type);
if (vnp)
my_snprintf(buff, buff_len, "%s", vnp->name);
else
my_snprintf(buff, buff_len, "Service action in(16)=0x%x",
service_action);
break;
case SG_SERVICE_ACTION_OUT_16:
vnp = get_value_name(sg_lib_serv_out16_arr, service_action, peri_type);
if (vnp)
my_snprintf(buff, buff_len, "%s", vnp->name);
else
my_snprintf(buff, buff_len, "Service action out(16)=0x%x",
service_action);
break;
case SG_PERSISTENT_RESERVE_IN:
vnp = get_value_name(sg_lib_pr_in_arr, service_action, peri_type);
if (vnp)
my_snprintf(buff, buff_len, "%s", vnp->name);
else
my_snprintf(buff, buff_len, "Persistent reserve in, service "
"action=0x%x", service_action);
break;
case SG_PERSISTENT_RESERVE_OUT:
vnp = get_value_name(sg_lib_pr_out_arr, service_action, peri_type);
if (vnp)
my_snprintf(buff, buff_len, "%s", vnp->name);
else
my_snprintf(buff, buff_len, "Persistent reserve out, service "
"action=0x%x", service_action);
break;
case SG_EXTENDED_COPY:
/* 'Extended copy' was renamed 'Third party copy out' in spc4r34 */
vnp = get_value_name(sg_lib_xcopy_sa_arr, service_action, peri_type);
if (vnp)
my_snprintf(buff, buff_len, "%s", vnp->name);
else
my_snprintf(buff, buff_len, "Third party copy out, service "
"action=0x%x", service_action);
break;
case SG_RECEIVE_COPY:
/* 'Receive copy results' was renamed 'Third party copy in' in
* spc4r34 */
vnp = get_value_name(sg_lib_rec_copy_sa_arr, service_action,
peri_type);
if (vnp)
my_snprintf(buff, buff_len, "%s", vnp->name);
else
my_snprintf(buff, buff_len, "Third party copy in, service "
"action=0x%x", service_action);
break;
case SG_READ_BUFFER:
/* spc4r34 requested treating mode as service action */
vnp = get_value_name(sg_lib_read_buff_arr, service_action,
peri_type);
if (vnp)
my_snprintf(buff, buff_len, "Read buffer (%s)\n", vnp->name);
else
my_snprintf(buff, buff_len, "Read buffer, mode=0x%x",
service_action);
break;
case SG_WRITE_BUFFER:
/* spc4r34 requested treating mode as service action */
vnp = get_value_name(sg_lib_write_buff_arr, service_action,
peri_type);
if (vnp)
my_snprintf(buff, buff_len, "Write buffer (%s)\n", vnp->name);
else
my_snprintf(buff, buff_len, "Write buffer, mode=0x%x",
service_action);
break;
default:
sg_get_opcode_name(cmd_byte0, peri_type, buff_len, buff);
break;
}
}
void
sg_get_opcode_name(unsigned char cmd_byte0, int peri_type, int buff_len,
char * buff)
{
const struct sg_lib_value_name_t * vnp;
int grp;
if ((NULL == buff) || (buff_len < 1))
return;
else if (1 == buff_len) {
buff[0] = '\0';
return;
}
if (SG_VARIABLE_LENGTH_CMD == cmd_byte0) {
my_snprintf(buff, buff_len, "%s", "Variable length");
return;
}
grp = (cmd_byte0 >> 5) & 0x7;
switch (grp) {
case 0:
case 1:
case 2:
case 4:
case 5:
vnp = get_value_name(sg_lib_normal_opcodes, cmd_byte0, peri_type);
if (vnp)
my_snprintf(buff, buff_len, "%s", vnp->name);
else
my_snprintf(buff, buff_len, "Opcode=0x%x", (int)cmd_byte0);
break;
case 3:
my_snprintf(buff, buff_len, "Reserved [0x%x]", (int)cmd_byte0);
break;
case 6:
case 7:
my_snprintf(buff, buff_len, "Vendor specific [0x%x]", (int)cmd_byte0);
break;
default:
my_snprintf(buff, buff_len, "Opcode=0x%x", (int)cmd_byte0);
break;
}
}
/* Iterates to next designation descriptor in the device identification
* VPD page. The 'initial_desig_desc' should point to start of first
* descriptor with 'page_len' being the number of valid bytes in that
* and following descriptors. To start, 'off' should point to a negative
* value, thereafter it should point to the value yielded by the previous
* call. If 0 returned then 'initial_desig_desc + *off' should be a valid
* descriptor; returns -1 if normal end condition and -2 for an abnormal
* termination. Matches association, designator_type and/or code_set when
* any of those values are greater than or equal to zero. */
int
sg_vpd_dev_id_iter(const unsigned char * initial_desig_desc, int page_len,
int * off, int m_assoc, int m_desig_type, int m_code_set)
{
const unsigned char * ucp;
int k, c_set, assoc, desig_type;
for (k = *off, ucp = initial_desig_desc ; (k + 3) < page_len; ) {
k = (k < 0) ? 0 : (k + ucp[k + 3] + 4);
if ((k + 4) > page_len)
break;
c_set = (ucp[k] & 0xf);
if ((m_code_set >= 0) && (m_code_set != c_set))
continue;
assoc = ((ucp[k + 1] >> 4) & 0x3);
if ((m_assoc >= 0) && (m_assoc != assoc))
continue;
desig_type = (ucp[k + 1] & 0xf);
if ((m_desig_type >= 0) && (m_desig_type != desig_type))
continue;
*off = k;
return 0;
}
return (k == page_len) ? -1 : -2;
}
/* safe_strerror() contributed by Clayton Weaver
* Allows for situation in which strerror() is given a wild value (or the
* C library is incomplete) and returns NULL. Still not thread safe.
*/
static char safe_errbuf[64] = {'u', 'n', 'k', 'n', 'o', 'w', 'n', ' ',
'e', 'r', 'r', 'n', 'o', ':', ' ', 0};
char *
safe_strerror(int errnum)
{
size_t len;
char * errstr;
if (errnum < 0)
errnum = -errnum;
errstr = strerror(errnum);
if (NULL == errstr) {
len = strlen(safe_errbuf);
my_snprintf(safe_errbuf + len, sizeof(safe_errbuf) - len, "%i",
errnum);
return safe_errbuf;
}
return errstr;
}
/* Note the ASCII-hex output goes to stdout. [Most other output from functions
* in this file go to sg_warnings_strm (default stderr).]
* 'no_ascii' allows for 3 output types:
* > 0 each line has address then up to 16 ASCII-hex bytes
* = 0 in addition, the bytes are listed in ASCII to the right
* < 0 only the ASCII-hex bytes are listed (i.e. without address) */
static void
dStrHexFp(const char* str, int len, int no_ascii, FILE * fp)
{
const char * p = str;
const char * formatstr;
unsigned char c;
char buff[82];
int a = 0;
int bpstart = 5;
const int cpstart = 60;
int cpos = cpstart;
int bpos = bpstart;
int i, k, blen;
if (len <= 0)
return;
blen = (int)sizeof(buff);
formatstr = (0 == no_ascii) ? "%.76s\n" : "%.48s\n";
memset(buff, ' ', 80);
buff[80] = '\0';
if (no_ascii < 0) {
bpstart = 0;
bpos = bpstart;
for (k = 0; k < len; k++) {
c = *p++;
if (0 != (k % 16))
bpos += 3;
if (bpos == (bpstart + (8 * 3)))
bpos++;
my_snprintf(&buff[bpos], blen - bpos, "%.2x",
(int)(unsigned char)c);
buff[bpos + 2] = ' ';
if ((k > 0) && (0 == ((k + 1) % 16))) {
fprintf(fp, formatstr, buff);
bpos = bpstart;
memset(buff, ' ', 80);
}
}
if (bpos > bpstart) {
buff[bpos + 2] = '\0';
fprintf(fp, "%s\n", buff);
}
return;
}
/* no_ascii>=0, start each line with address (offset) */
k = my_snprintf(buff + 1, blen - 1, "%.2x", a);
buff[k + 1] = ' ';
for (i = 0; i < len; i++) {
c = *p++;
bpos += 3;
if (bpos == (bpstart + (9 * 3)))
bpos++;
my_snprintf(&buff[bpos], blen - bpos, "%.2x", (int)(unsigned char)c);
buff[bpos + 2] = ' ';
if (no_ascii)
buff[cpos++] = ' ';
else {
if ((c < ' ') || (c >= 0x7f))
c = '.';
buff[cpos++] = c;
}
if (cpos > (cpstart + 15)) {
fprintf(fp, formatstr, buff);
bpos = bpstart;
cpos = cpstart;
a += 16;
memset(buff, ' ', 80);
k = my_snprintf(buff + 1, blen - 1, "%.2x", a);
buff[k + 1] = ' ';
}
}
if (cpos > cpstart) {
buff[cpos] = '\0';
fprintf(fp, "%s\n", buff);
}
}
void
dStrHex(const char* str, int len, int no_ascii)
{
dStrHexFp(str, len, no_ascii, stdout);
}
void
dStrHexErr(const char* str, int len, int no_ascii)
{
dStrHexFp(str, len, no_ascii,
(sg_warnings_strm ? sg_warnings_strm : stderr));
}
/* Read 'len' bytes from 'str' and output as ASCII-Hex bytes (space
* separated) to 'b' not to exceed 'b_len' characters. Each line
* starts with 'leadin' (NULL for no leadin) and there are 16 bytes
* per line with an extra space between the 8th and 9th bytes. 'format'
* is unused (currently), set to 0 . */
void
dStrHexStr(const char* str, int len, const char * leadin, int format,
int b_len, char * b)
{
const char * p = str;
unsigned char c;
char buff[122];
int bpstart, bpos, k, n;
if (len <= 0)
return;
if (0 != format) {
; /* do nothing different for now */
}
if (leadin) {
bpstart = strlen(leadin);
/* Cap leadin at 60 characters */
if (bpstart > 60)
bpstart = 60;
} else
bpstart = 0;
bpos = bpstart;
n = 0;
memset(buff, ' ', 120);
buff[120] = '\0';
if (bpstart > 0)
memcpy(buff, leadin, bpstart);
for (k = 0; k < len; k++) {
c = *p++;
if (bpos == (bpstart + (8 * 3)))
bpos++;
my_snprintf(&buff[bpos], (int)sizeof(buff) - bpos, "%.2x",
(int)(unsigned char)c);
buff[bpos + 2] = ' ';
if ((k > 0) && (0 == ((k + 1) % 16))) {
n += my_snprintf(b + n, b_len - n, "%.*s\n", bpstart + 48, buff);
if (n >= (b_len - 1))
return;
bpos = bpstart;
memset(buff, ' ', 120);
if (bpstart > 0)
memcpy(buff, leadin, bpstart);
} else
bpos += 3;
}
if (bpos > bpstart)
n += my_snprintf(b + n, b_len - n, "%.*s\n", bpstart + 48, buff);
return;
}
/* Returns 1 when executed on big endian machine; else returns 0.
* Useful for displaying ATA identify words (which need swapping on a
* big endian machine). */
int
sg_is_big_endian()
{
union u_t {
unsigned short s;
unsigned char c[sizeof(unsigned short)];
} u;
u.s = 0x0102;
return (u.c[0] == 0x01); /* The lowest address contains
the most significant byte */
}
static unsigned short
swapb_ushort(unsigned short u)
{
unsigned short r;
r = (u >> 8) & 0xff;
r |= ((u & 0xff) << 8);
return r;
}
/* Note the ASCII-hex output goes to stdout. [Most other output from functions
* in this file go to sg_warnings_strm (default stderr).]
* 'no_ascii' allows for 3 output types:
* > 0 each line has address then up to 8 ASCII-hex 16 bit words
* = 0 in addition, the ASCI bytes pairs are listed to the right
* = -1 only the ASCII-hex words are listed (i.e. without address)
* = -2 only the ASCII-hex words, formatted for "hdparm --Istdin"
* < -2 same as -1
* If 'swapb' non-zero then bytes in each word swapped. Needs to be set
* for ATA IDENTIFY DEVICE response on big-endian machines. */
void
dWordHex(const unsigned short* words, int num, int no_ascii, int swapb)
{
const unsigned short * p = words;
unsigned short c;
char buff[82];
unsigned char upp, low;
int a = 0;
const int bpstart = 3;
const int cpstart = 52;
int cpos = cpstart;
int bpos = bpstart;
int i, k, blen;
if (num <= 0)
return;
blen = (int)sizeof(buff);
memset(buff, ' ', 80);
buff[80] = '\0';
if (no_ascii < 0) {
for (k = 0; k < num; k++) {
c = *p++;
if (swapb)
c = swapb_ushort(c);
bpos += 5;
my_snprintf(&buff[bpos], blen - bpos, "%.4x", (unsigned int)c);
buff[bpos + 4] = ' ';
if ((k > 0) && (0 == ((k + 1) % 8))) {
if (-2 == no_ascii)
printf("%.39s\n", buff +8);
else
printf("%.47s\n", buff);
bpos = bpstart;
memset(buff, ' ', 80);
}
}
if (bpos > bpstart) {
if (-2 == no_ascii)
printf("%.39s\n", buff +8);
else
printf("%.47s\n", buff);
}
return;
}
/* no_ascii>=0, start each line with address (offset) */
k = my_snprintf(buff + 1, blen - 1, "%.2x", a);
buff[k + 1] = ' ';
for (i = 0; i < num; i++) {
c = *p++;
if (swapb)
c = swapb_ushort(c);
bpos += 5;
my_snprintf(&buff[bpos], blen - bpos, "%.4x", (unsigned int)c);
buff[bpos + 4] = ' ';
if (no_ascii) {
buff[cpos++] = ' ';
buff[cpos++] = ' ';
buff[cpos++] = ' ';
} else {
upp = (c >> 8) & 0xff;
low = c & 0xff;
if ((upp < 0x20) || (upp >= 0x7f))
upp = '.';
buff[cpos++] = upp;
if ((low < 0x20) || (low >= 0x7f))
low = '.';
buff[cpos++] = low;
buff[cpos++] = ' ';
}
if (cpos > (cpstart + 23)) {
printf("%.76s\n", buff);
bpos = bpstart;
cpos = cpstart;
a += 8;
memset(buff, ' ', 80);
k = my_snprintf(buff + 1, blen - 1, "%.2x", a);
buff[k + 1] = ' ';
}
}
if (cpos > cpstart)
printf("%.76s\n", buff);
}
/* If the number in 'buf' can be decoded or the multiplier is unknown
* then -1 is returned. Accepts a hex prefix (0x or 0X) or a decimal
* multiplier suffix (as per GNU's dd (since 2002: SI and IEC 60027-2)).
* Main (SI) multipliers supported: K, M, G. Ignore leading spaces and
* tabs; accept comma, space, tab and hash as terminator. */
int
sg_get_num(const char * buf)
{
int res, num, n, len;
unsigned int unum;
char * cp;
const char * b;
char c = 'c';
char c2, c3;
char lb[16];
if ((NULL == buf) || ('\0' == buf[0]))
return -1;
len = strlen(buf);
n = strspn(buf, " \t");
if (n > 0) {
if (n == len)
return -1;
buf += n;
len -=n;
}
/* following hack to keep C++ happy */
cp = strpbrk((char *)buf, " \t,#");
if (cp) {
len = cp - buf;
n = (int)sizeof(lb) - 1;
len = (len < n) ? len : n;
memcpy(lb, buf, len);
lb[len] = '\0';
b = lb;
} else
b = buf;
if (('0' == b[0]) && (('x' == b[1]) || ('X' == b[1]))) {
res = sscanf(b + 2, "%x", &unum);
num = unum;
} else if ('H' == toupper((int)b[len - 1])) {
res = sscanf(b, "%x", &unum);
num = unum;
} else
res = sscanf(b, "%d%c%c%c", &num, &c, &c2, &c3);
if (res < 1)
return -1LL;
else if (1 == res)
return num;
else {
if (res > 2)
c2 = toupper((int)c2);
if (res > 3)
c3 = toupper((int)c3);
switch (toupper((int)c)) {
case 'C':
return num;
case 'W':
return num * 2;
case 'B':
return num * 512;
case 'K':
if (2 == res)
return num * 1024;
if (('B' == c2) || ('D' == c2))
return num * 1000;
if (('I' == c2) && (4 == res) && ('B' == c3))
return num * 1024;
return -1;
case 'M':
if (2 == res)
return num * 1048576;
if (('B' == c2) || ('D' == c2))
return num * 1000000;
if (('I' == c2) && (4 == res) && ('B' == c3))
return num * 1048576;
return -1;
case 'G':
if (2 == res)
return num * 1073741824;
if (('B' == c2) || ('D' == c2))
return num * 1000000000;
if (('I' == c2) && (4 == res) && ('B' == c3))
return num * 1073741824;
return -1;
case 'X':
cp = (char *)strchr(b, 'x');
if (NULL == cp)
cp = (char *)strchr(b, 'X');
if (cp) {
n = sg_get_num(cp + 1);
if (-1 != n)
return num * n;
}
return -1;
default:
if (NULL == sg_warnings_strm)
sg_warnings_strm = stderr;
fprintf(sg_warnings_strm, "unrecognized multiplier\n");
return -1;
}
}
}
/* If the number in 'buf' can not be decoded then -1 is returned. Accepts a
* hex prefix (0x or 0X) or a 'h' (or 'H') suffix; otherwise decimal is
* assumed. Does not accept multipliers. Accept a comma (","), a whitespace
* or newline as terminator. */
int
sg_get_num_nomult(const char * buf)
{
int res, len, num;
unsigned int unum;
char * commap;
if ((NULL == buf) || ('\0' == buf[0]))
return -1;
len = strlen(buf);
commap = (char *)strchr(buf + 1, ',');
if (('0' == buf[0]) && (('x' == buf[1]) || ('X' == buf[1]))) {
res = sscanf(buf + 2, "%x", &unum);
num = unum;
} else if (commap && ('H' == toupper((int)*(commap - 1)))) {
res = sscanf(buf, "%x", &unum);
num = unum;
} else if ((NULL == commap) && ('H' == toupper((int)buf[len - 1]))) {
res = sscanf(buf, "%x", &unum);
num = unum;
} else
res = sscanf(buf, "%d", &num);
if (1 == res)
return num;
else
return -1;
}
/* If the number in 'buf' can be decoded or the multiplier is unknown
* then -1LL is returned. Accepts a hex prefix (0x or 0X) or a decimal
* multiplier suffix (as per GNU's dd (since 2002: SI and IEC 60027-2)).
* Main (SI) multipliers supported: K, M, G, T, P. Ignore leading spaces
* and tabs; accept comma, space, tab and hash as terminator. */
int64_t
sg_get_llnum(const char * buf)
{
int res, len, n;
int64_t num, ll;
uint64_t unum;
char * cp;
const char * b;
char c = 'c';
char c2, c3;
char lb[32];
if ((NULL == buf) || ('\0' == buf[0]))
return -1LL;
len = strlen(buf);
n = strspn(buf, " \t");
if (n > 0) {
if (n == len)
return -1LL;
buf += n;
len -=n;
}
/* following hack to keep C++ happy */
cp = strpbrk((char *)buf, " \t,#");
if (cp) {
len = cp - buf;
n = (int)sizeof(lb) - 1;
len = (len < n) ? len : n;
memcpy(lb, buf, len);
lb[len] = '\0';
b = lb;
} else
b = buf;
if (('0' == b[0]) && (('x' == b[1]) || ('X' == b[1]))) {
res = sscanf(b + 2, "%" SCNx64 "", &unum);
num = unum;
} else if ('H' == toupper((int)b[len - 1])) {
res = sscanf(b, "%" SCNx64 "", &unum);
num = unum;
} else
res = sscanf(b, "%" SCNd64 "%c%c%c", &num, &c, &c2, &c3);
if (res < 1)
return -1LL;
else if (1 == res)
return num;
else {
if (res > 2)
c2 = toupper((int)c2);
if (res > 3)
c3 = toupper((int)c3);
switch (toupper((int)c)) {
case 'C':
return num;
case 'W':
return num * 2;
case 'B':
return num * 512;
case 'K':
if (2 == res)
return num * 1024;
if (('B' == c2) || ('D' == c2))
return num * 1000;
if (('I' == c2) && (4 == res) && ('B' == c3))
return num * 1024;
return -1LL;
case 'M':
if (2 == res)
return num * 1048576;
if (('B' == c2) || ('D' == c2))
return num * 1000000;
if (('I' == c2) && (4 == res) && ('B' == c3))
return num * 1048576;
return -1LL;
case 'G':
if (2 == res)
return num * 1073741824;
if (('B' == c2) || ('D' == c2))
return num * 1000000000;
if (('I' == c2) && (4 == res) && ('B' == c3))
return num * 1073741824;
return -1LL;
case 'T':
if (2 == res)
return num * 1099511627776LL;
if (('B' == c2) || ('D' == c2))
return num * 1000000000000LL;
if (('I' == c2) && (4 == res) && ('B' == c3))
return num * 1099511627776LL;
return -1LL;
case 'P':
if (2 == res)
return num * 1099511627776LL * 1024;
if (('B' == c2) || ('D' == c2))
return num * 1000000000000LL * 1000;
if (('I' == c2) && (4 == res) && ('B' == c3))
return num * 1099511627776LL * 1024;
return -1LL;
case 'X':
cp = (char *)strchr(b, 'x');
if (NULL == cp)
cp = (char *)strchr(b, 'X');
if (cp) {
ll = sg_get_llnum(cp + 1);
if (-1LL != ll)
return num * ll;
}
return -1LL;
default:
if (NULL == sg_warnings_strm)
sg_warnings_strm = stderr;
fprintf(sg_warnings_strm, "unrecognized multiplier\n");
return -1LL;
}
}
}
/* Extract character sequence from ATA words as in the model string
* in a IDENTIFY DEVICE response. Returns number of characters
* written to 'ochars' before 0 character is found or 'num' words
* are processed. */
int
sg_ata_get_chars(const unsigned short * word_arr, int start_word,
int num_words, int is_big_endian, char * ochars)
{
int k;
unsigned short s;
char a, b;
char * op = ochars;
for (k = start_word; k < (start_word + num_words); ++k) {
s = word_arr[k];
if (is_big_endian) {
a = s & 0xff;
b = (s >> 8) & 0xff;
} else {
a = (s >> 8) & 0xff;
b = s & 0xff;
}
if (a == 0)
break;
*op++ = a;
if (b == 0)
break;
*op++ = b;
}
return op - ochars;
}
const char *
sg_lib_version()
{
return sg_lib_version_str;
}
#ifdef SG_LIB_MINGW
/* Non Unix OSes distinguish between text and binary files.
Set text mode on fd. Does nothing in Unix. Returns negative number on
failure. */
#include
#include
int
sg_set_text_mode(int fd)
{
return setmode(fd, O_TEXT);
}
/* Set binary mode on fd. Does nothing in Unix. Returns negative number on
failure. */
int
sg_set_binary_mode(int fd)
{
return setmode(fd, O_BINARY);
}
#else
/* For Unix the following functions are dummies. */
int
sg_set_text_mode(int fd)
{
return fd; /* fd should be >= 0 */
}
int
sg_set_binary_mode(int fd)
{
return fd;
}
#endif
ddpt-0.94/lib/Makefile.am 0000644 0001750 0001750 00000002212 12254763724 014210 0 ustar dougg dougg libsgutils2_la_SOURCES = \
sg_lib.c \
sg_lib_data.c \
sg_cmds_basic.c \
sg_cmds_basic2.c \
sg_cmds_extra.c \
sg_cmds_mmc.c \
sg_pt_common.c
if OS_LINUX
libsgutils2_la_SOURCES += \
sg_pt_linux.c \
sg_io_linux.c
endif
if OS_WIN32_MINGW
libsgutils2_la_SOURCES += sg_pt_win32.c
endif
if OS_WIN32_CYGWIN
libsgutils2_la_SOURCES += sg_pt_win32.c
endif
if OS_FREEBSD
libsgutils2_la_SOURCES += sg_pt_freebsd.c
endif
if OS_SOLARIS
libsgutils2_la_SOURCES += sg_pt_solaris.c
endif
if OS_OSF
libsgutils2_la_SOURCES += sg_pt_osf1.c
endif
# For C++/clang testing
## CC = g++
## CC = g++
## CC = clang
## CC = clang++
# -std= can be c99, c11, gnu11, etc. Default is gnu89 (gnu90 is the same)
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=c11
# AM_CFLAGS = -I ../include -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -Wall -W -pedantic -std=c++11
lib_LTLIBRARIES = libsgutils2.la
libsgutils2_la_LDFLAGS = -version-info 2:0:0
libsgutils2_la_LIBADD = @GETOPT_O_FILES@ @os_libs@
libsgutils2_la_DEPENDENCIES = @GETOPT_O_FILES@
ddpt-0.94/lib/sg_cmds_basic.c 0000644 0001750 0001750 00000050103 12305171513 015064 0 ustar dougg dougg /*
* Copyright (c) 1999-2014 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.
*/
/*
* CONTENTS
* Some SCSI commands are executed in many contexts and hence began
* to appear in several sg3_utils utilities. This files centralizes
* some of the low level command execution code. In most cases the
* interpretation of the command response is left to the each
* utility.
*/
#include
#include
#include
#include
#include "sg_lib.h"
#include "sg_cmds_basic.h"
#include "sg_pt.h"
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
static const char * version_str = "1.66 20140222";
#define SENSE_BUFF_LEN 64 /* Arbitrary, could be larger */
#define EBUFF_SZ 256
#define DEF_PT_TIMEOUT 60 /* 60 seconds */
#define START_PT_TIMEOUT 120 /* 120 seconds == 2 minutes */
#define LONG_PT_TIMEOUT 7200 /* 7,200 seconds == 120 minutes */
#define INQUIRY_CMD 0x12
#define INQUIRY_CMDLEN 6
#define REQUEST_SENSE_CMD 0x3
#define REQUEST_SENSE_CMDLEN 6
#define REPORT_LUNS_CMD 0xa0
#define REPORT_LUNS_CMDLEN 12
#define TUR_CMD 0x0
#define TUR_CMDLEN 6
#define INQUIRY_RESP_INITIAL_LEN 36
const char *
sg_cmds_version()
{
return version_str;
}
/* Returns file descriptor >= 0 if successful. If error in Unix returns
negated errno. */
int
sg_cmds_open_device(const char * device_name, int read_only, int verbose)
{
return scsi_pt_open_device(device_name, read_only, verbose);
}
/* Returns file descriptor >= 0 if successful. If error in Unix returns
negated errno. */
int
sg_cmds_open_flags(const char * device_name, int flags, int verbose)
{
return scsi_pt_open_flags(device_name, flags, verbose);
}
/* Returns 0 if successful. If error in Unix returns negated errno. */
int
sg_cmds_close_device(int device_fd)
{
return scsi_pt_close_device(device_fd);
}
static int
sg_cmds_process_helper(const char * leadin, int mx_di_len, int resid,
const unsigned char * sbp, int slen, int noisy,
int verbose, int * o_sense_cat)
{
int scat, got;
int n = 0;
int check_data_in = 0;
char b[512];
scat = sg_err_category_sense(sbp, slen);
switch (scat) {
case SG_LIB_CAT_NOT_READY:
case SG_LIB_CAT_INVALID_OP:
case SG_LIB_CAT_ILLEGAL_REQ:
case SG_LIB_CAT_ABORTED_COMMAND:
case SG_LIB_CAT_NO_SENSE:
n = 0;
break;
case SG_LIB_CAT_RECOVERED:
case SG_LIB_CAT_MEDIUM_HARD:
++check_data_in;
/* drop through */
case SG_LIB_CAT_UNIT_ATTENTION:
default:
n = noisy;
break;
}
if (verbose || n) {
sg_get_sense_str(leadin, sbp, slen, (verbose > 1),
sizeof(b), b);
fprintf(sg_warnings_strm, "%s", b);
if ((mx_di_len > 0) && (resid > 0)) {
got = mx_di_len - resid;
if ((verbose > 2) || check_data_in || (got > 0))
fprintf(sg_warnings_strm, " pass-through requested %d "
"bytes (data-in) but got %d bytes\n", mx_di_len, got);
}
}
if (o_sense_cat)
*o_sense_cat = scat;
return -2;
}
/* This is a helper function used by sg_cmds_* implementations after the
* call to the pass-through. pt_res is returned from do_scsi_pt(). If valid
* sense data is found it is decoded and output to sg_warnings_strm (def:
* stderr); depending on the 'noisy' and 'verbose' settings. Returns -2 for
* sense data (may not be fatal), -1 for failed, 0, or a positive number. If
* 'mx_di_len > 0' then asks pass-through for resid and returns
* (mx_di_len - resid); otherwise returns 0. So for data-in it should return
* the actual number of bytes received. For data-out (to device) or no data
* call with 'mx_di_len' set to 0 or less. If -2 returned then sense category
* output via 'o_sense_cat' pointer (if not NULL). Note that several sense
* categories also have data in bytes received; -2 is still returned. */
int
sg_cmds_process_resp(struct sg_pt_base * ptvp, const char * leadin,
int pt_res, int mx_di_len, const unsigned char * sbp,
int noisy, int verbose, int * o_sense_cat)
{
int got, cat, duration, slen, resid, resp_code;
char b[1024];
if (NULL == sg_warnings_strm)
sg_warnings_strm = stderr;
if (NULL == leadin)
leadin = "";
if (pt_res < 0) {
if (noisy || verbose)
fprintf(sg_warnings_strm, "%s: pass through os error: %s\n",
leadin, safe_strerror(-pt_res));
return -1;
} else if (SCSI_PT_DO_BAD_PARAMS == pt_res) {
fprintf(sg_warnings_strm, "%s: bad pass through setup\n", leadin);
return -1;
} else if (SCSI_PT_DO_TIMEOUT == pt_res) {
fprintf(sg_warnings_strm, "%s: pass through timeout\n", leadin);
return -1;
}
if ((verbose > 2) && ((duration = get_scsi_pt_duration_ms(ptvp)) >= 0))
fprintf(sg_warnings_strm, " duration=%d ms\n", duration);
resid = (mx_di_len > 0) ? get_scsi_pt_resid(ptvp) : 0;
slen = get_scsi_pt_sense_len(ptvp);
switch ((cat = get_scsi_pt_result_category(ptvp))) {
case SCSI_PT_RESULT_GOOD:
if (slen > 7) {
resp_code = sbp[0] & 0x7f;
/* SBC referrals can have status=GOOD and sense_key=COMPLETED */
if (resp_code >= 0x70) {
if (resp_code < 0x72) {
if (SPC_SK_NO_SENSE != (0xf & sbp[2]))
sg_err_category_sense(sbp, slen);
} else if (resp_code < 0x74) {
if (SPC_SK_NO_SENSE != (0xf & sbp[1]))
sg_err_category_sense(sbp, slen);
}
}
}
if (mx_di_len > 0) {
got = mx_di_len - resid;
if ((verbose > 1) && (resid > 0))
fprintf(sg_warnings_strm, " %s: pass-through requested "
"%d bytes (data-in) but got %d bytes\n", leadin,
mx_di_len, got);
return got;
} else
return 0;
case SCSI_PT_RESULT_STATUS: /* other than GOOD and CHECK CONDITION */
if (verbose || noisy) {
sg_get_scsi_status_str(get_scsi_pt_status_response(ptvp),
sizeof(b), b);
fprintf(sg_warnings_strm, "%s: scsi status: %s\n", leadin, b);
}
return -1;
case SCSI_PT_RESULT_SENSE:
return sg_cmds_process_helper(leadin, mx_di_len, resid, sbp, slen,
noisy, verbose, o_sense_cat);
case SCSI_PT_RESULT_TRANSPORT_ERR:
if (verbose || noisy) {
get_scsi_pt_transport_err_str(ptvp, sizeof(b), b);
fprintf(sg_warnings_strm, "%s: transport: %s\n", leadin, b);
}
if ((SAM_STAT_CHECK_CONDITION == get_scsi_pt_status_response(ptvp))
&& (slen > 0))
return sg_cmds_process_helper(leadin, mx_di_len, resid, sbp,
slen, noisy, verbose, o_sense_cat);
else
return -1;
case SCSI_PT_RESULT_OS_ERR:
if (verbose || noisy) {
get_scsi_pt_os_err_str(ptvp, sizeof(b), b);
fprintf(sg_warnings_strm, "%s: os: %s\n", leadin, b);
}
return -1;
default:
fprintf(sg_warnings_strm, "%s: unknown pass through result "
"category (%d)\n", leadin, cat);
return -1;
}
}
/* Invokes a SCSI INQUIRY command and yields the response
* Returns 0 when successful, SG_LIB_CAT_INVALID_OP -> not supported,
* SG_LIB_CAT_ILLEGAL_REQ -> bad field in cdb, SG_LIB_CAT_ABORTED_COMMAND,
* SG_LIB_CAT_MALFORMED -> bad response, -1 -> other errors */
int
sg_ll_inquiry(int sg_fd, int cmddt, int evpd, int pg_op, void * resp,
int mx_resp_len, int noisy, int verbose)
{
int res, ret, k, sense_cat;
unsigned char inqCmdBlk[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 (cmddt)
inqCmdBlk[1] |= 2;
if (evpd)
inqCmdBlk[1] |= 1;
inqCmdBlk[2] = (unsigned char)pg_op;
/* 16 bit allocation length (was 8) is a recent SPC-3 addition */
inqCmdBlk[3] = (unsigned char)((mx_resp_len >> 8) & 0xff);
inqCmdBlk[4] = (unsigned char)(mx_resp_len & 0xff);
if (NULL == sg_warnings_strm)
sg_warnings_strm = stderr;
if (verbose) {
fprintf(sg_warnings_strm, " inquiry cdb: ");
for (k = 0; k < INQUIRY_CMDLEN; ++k)
fprintf(sg_warnings_strm, "%02x ", inqCmdBlk[k]);
fprintf(sg_warnings_strm, "\n");
}
if (resp && (mx_resp_len > 0)) {
up = (unsigned char *)resp;
up[0] = 0x7f; /* defensive prefill */
if (mx_resp_len > 4)
up[4] = 0;
}
ptvp = construct_scsi_pt_obj();
if (NULL == ptvp) {
fprintf(sg_warnings_strm, "inquiry: out of memory\n");
return -1;
}
set_scsi_pt_cdb(ptvp, inqCmdBlk, sizeof(inqCmdBlk));
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, sg_fd, DEF_PT_TIMEOUT, verbose);
ret = sg_cmds_process_resp(ptvp, "inquiry", res, mx_resp_len, sense_b,
noisy, verbose, &sense_cat);
destruct_scsi_pt_obj(ptvp);
if (-1 == ret)
;
else if (-2 == ret) {
switch (sense_cat) {
case SG_LIB_CAT_INVALID_OP:
case SG_LIB_CAT_ILLEGAL_REQ:
case SG_LIB_CAT_ABORTED_COMMAND:
ret = sense_cat;
break;
case SG_LIB_CAT_RECOVERED:
case SG_LIB_CAT_NO_SENSE:
ret = 0;
break;
default:
ret = -1;
break;
}
} else if (ret < 4) {
if (verbose)
fprintf(sg_warnings_strm, "inquiry: got too few "
"bytes (%d)\n", ret);
ret = SG_LIB_CAT_MALFORMED;
} else
ret = 0;
return ret;
}
/* Yields most of first 36 bytes of a standard INQUIRY (evpd==0) response.
* Returns 0 when successful, SG_LIB_CAT_INVALID_OP -> not supported,
* SG_LIB_CAT_ILLEGAL_REQ -> bad field in cdb, SG_LIB_CAT_ABORTED_COMMAND,
* SG_LIB_CAT_MALFORMED -> bad response, -1 -> other errors */
int
sg_simple_inquiry(int sg_fd, struct sg_simple_inquiry_resp * inq_data,
int noisy, int verbose)
{
int res, ret, k, sense_cat;
unsigned char inqCmdBlk[INQUIRY_CMDLEN] = {INQUIRY_CMD, 0, 0, 0, 0, 0};
unsigned char sense_b[SENSE_BUFF_LEN];
unsigned char inq_resp[INQUIRY_RESP_INITIAL_LEN];
struct sg_pt_base * ptvp;
if (inq_data) {
memset(inq_data, 0, sizeof(* inq_data));
inq_data->peripheral_qualifier = 0x3;
inq_data->peripheral_type = 0x1f;
}
inqCmdBlk[4] = (unsigned char)sizeof(inq_resp);
if (NULL == sg_warnings_strm)
sg_warnings_strm = stderr;
if (verbose) {
fprintf(sg_warnings_strm, " inquiry cdb: ");
for (k = 0; k < INQUIRY_CMDLEN; ++k)
fprintf(sg_warnings_strm, "%02x ", inqCmdBlk[k]);
fprintf(sg_warnings_strm, "\n");
}
memset(inq_resp, 0, sizeof(inq_resp));
inq_resp[0] = 0x7f; /* defensive prefill */
ptvp = construct_scsi_pt_obj();
if (NULL == ptvp) {
fprintf(sg_warnings_strm, "inquiry: out of memory\n");
return -1;
}
set_scsi_pt_cdb(ptvp, inqCmdBlk, sizeof(inqCmdBlk));
set_scsi_pt_sense(ptvp, sense_b, sizeof(sense_b));
set_scsi_pt_data_in(ptvp, inq_resp, sizeof(inq_resp));
res = do_scsi_pt(ptvp, sg_fd, DEF_PT_TIMEOUT, verbose);
ret = sg_cmds_process_resp(ptvp, "inquiry", res, sizeof(inq_resp),
sense_b, noisy, verbose, &sense_cat);
if (-1 == ret)
;
else if (-2 == ret) {
switch (sense_cat) {
case SG_LIB_CAT_INVALID_OP:
case SG_LIB_CAT_ILLEGAL_REQ:
case SG_LIB_CAT_ABORTED_COMMAND:
ret = sense_cat;
break;
case SG_LIB_CAT_RECOVERED:
case SG_LIB_CAT_NO_SENSE:
ret = 0;
break;
default:
ret = -1;
break;
}
} else if (ret < 4) {
if (verbose)
fprintf(sg_warnings_strm, "inquiry: got too few "
"bytes (%d)\n", ret);
ret = SG_LIB_CAT_MALFORMED;
} else
ret = 0;
if (0 == ret) {
inq_data->peripheral_qualifier = (inq_resp[0] >> 5) & 0x7;
inq_data->peripheral_type = inq_resp[0] & 0x1f;
inq_data->rmb = (inq_resp[1] & 0x80) ? 1 : 0;
inq_data->version = inq_resp[2];
inq_data->byte_3 = inq_resp[3];
inq_data->byte_5 = inq_resp[5];
inq_data->byte_6 = inq_resp[6];
inq_data->byte_7 = inq_resp[7];
memcpy(inq_data->vendor, inq_resp + 8, 8);
memcpy(inq_data->product, inq_resp + 16, 16);
memcpy(inq_data->revision, inq_resp + 32, 4);
}
destruct_scsi_pt_obj(ptvp);
return ret;
}
/* Invokes a SCSI TEST UNIT READY command.
* 'pack_id' is just for diagnostics, safe to set to 0.
* Looks for progress indicator if 'progress' non-NULL;
* if found writes value [0..65535] else write -1.
* Return of 0 -> success, SG_LIB_CAT_UNIT_ATTENTION,
* SG_LIB_CAT_ABORTED_COMMAND, SG_LIB_CAT_NOT_READY ->
* device not ready, -1 -> other failure */
int
sg_ll_test_unit_ready_progress(int sg_fd, int pack_id, int * progress,
int noisy, int verbose)
{
int res, ret, k, sense_cat;
unsigned char turCmdBlk[TUR_CMDLEN] = {TUR_CMD, 0, 0, 0, 0, 0};
unsigned char sense_b[SENSE_BUFF_LEN];
struct sg_pt_base * ptvp;
if (NULL == sg_warnings_strm)
sg_warnings_strm = stderr;
if (verbose) {
fprintf(sg_warnings_strm, " test unit ready cdb: ");
for (k = 0; k < TUR_CMDLEN; ++k)
fprintf(sg_warnings_strm, "%02x ", turCmdBlk[k]);
fprintf(sg_warnings_strm, "\n");
}
ptvp = construct_scsi_pt_obj();
if (NULL == ptvp) {
fprintf(sg_warnings_strm, "test unit ready: out of memory\n");
return -1;
}
set_scsi_pt_cdb(ptvp, turCmdBlk, sizeof(turCmdBlk));
set_scsi_pt_sense(ptvp, sense_b, sizeof(sense_b));
set_scsi_pt_packet_id(ptvp, pack_id);
res = do_scsi_pt(ptvp, sg_fd, DEF_PT_TIMEOUT, verbose);
ret = sg_cmds_process_resp(ptvp, "test unit ready", res, 0, sense_b,
noisy, verbose, &sense_cat);
if (-1 == ret)
;
else if (-2 == ret) {
if (progress) {
int slen = get_scsi_pt_sense_len(ptvp);
if (! sg_get_sense_progress_fld(sense_b, slen, progress))
*progress = -1;
}
switch (sense_cat) {
case SG_LIB_CAT_UNIT_ATTENTION:
case SG_LIB_CAT_NOT_READY:
case SG_LIB_CAT_ABORTED_COMMAND:
ret = sense_cat;
break;
case SG_LIB_CAT_RECOVERED:
case SG_LIB_CAT_NO_SENSE:
ret = 0;
break;
case SG_LIB_CAT_INVALID_OP:
case SG_LIB_CAT_ILLEGAL_REQ:
default:
ret = -1;
break;
}
} else
ret = 0;
destruct_scsi_pt_obj(ptvp);
return ret;
}
/* Invokes a SCSI TEST UNIT READY command.
* 'pack_id' is just for diagnostics, safe to set to 0.
* Return of 0 -> success, SG_LIB_CAT_UNIT_ATTENTION,
* SG_LIB_CAT_ABORTED_COMMAND, SG_LIB_CAT_NOT_READY ->
* device not ready, -1 -> other failure */
int
sg_ll_test_unit_ready(int sg_fd, int pack_id, int noisy, int verbose)
{
return sg_ll_test_unit_ready_progress(sg_fd, pack_id, NULL, noisy,
verbose);
}
/* Invokes a SCSI REQUEST SENSE command. Return of 0 -> success,
* SG_LIB_CAT_INVALID_OP -> Request Sense not supported??,
* SG_LIB_CAT_ILLEGAL_REQ -> bad field in cdb,
* SG_LIB_CAT_ABORTED_COMMAND, -1 -> other failure */
int
sg_ll_request_sense(int sg_fd, int desc, void * resp, int mx_resp_len,
int noisy, int verbose)
{
int k, ret, res, sense_cat;
unsigned char rsCmdBlk[REQUEST_SENSE_CMDLEN] =
{REQUEST_SENSE_CMD, 0, 0, 0, 0, 0};
unsigned char sense_b[SENSE_BUFF_LEN];
struct sg_pt_base * ptvp;
if (desc)
rsCmdBlk[1] |= 0x1;
if (NULL == sg_warnings_strm)
sg_warnings_strm = stderr;
if (mx_resp_len > 0xff) {
fprintf(sg_warnings_strm, "mx_resp_len cannot exceed 255\n");
return -1;
}
rsCmdBlk[4] = mx_resp_len & 0xff;
if (verbose) {
fprintf(sg_warnings_strm, " Request Sense cmd: ");
for (k = 0; k < REQUEST_SENSE_CMDLEN; ++k)
fprintf(sg_warnings_strm, "%02x ", rsCmdBlk[k]);
fprintf(sg_warnings_strm, "\n");
}
ptvp = construct_scsi_pt_obj();
if (NULL == ptvp) {
fprintf(sg_warnings_strm, "request sense: out of memory\n");
return -1;
}
set_scsi_pt_cdb(ptvp, rsCmdBlk, sizeof(rsCmdBlk));
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, sg_fd, DEF_PT_TIMEOUT, verbose);
ret = sg_cmds_process_resp(ptvp, "request sense", res, mx_resp_len,
sense_b, noisy, verbose, &sense_cat);
if (-1 == ret)
;
else if (-2 == ret) {
switch (sense_cat) {
case SG_LIB_CAT_INVALID_OP:
case SG_LIB_CAT_ILLEGAL_REQ:
case SG_LIB_CAT_ABORTED_COMMAND:
ret = sense_cat;
break;
case SG_LIB_CAT_RECOVERED:
case SG_LIB_CAT_NO_SENSE:
ret = 0;
break;
case SG_LIB_CAT_NOT_READY: /* shouldn't happen ?? */
default:
ret = -1;
break;
}
} else {
if ((mx_resp_len >= 8) && (ret < 8)) {
if (verbose)
fprintf(sg_warnings_strm, " request sense: got %d "
"bytes in response, too short\n", ret);
ret = -1;
} else
ret = 0;
}
destruct_scsi_pt_obj(ptvp);
return ret;
}
/* Invokes a SCSI REPORT LUNS command. Return of 0 -> success,
* SG_LIB_CAT_INVALID_OP -> Report Luns not supported,
* SG_LIB_CAT_ILLEGAL_REQ -> bad field in cdb,
* SG_LIB_CAT_ABORTED_COMMAND,
* SG_LIB_NOT_READY (shouldn't happen), -1 -> other failure */
int
sg_ll_report_luns(int sg_fd, int select_report, void * resp, int mx_resp_len,
int noisy, int verbose)
{
int k, ret, res, sense_cat;
unsigned char rlCmdBlk[REPORT_LUNS_CMDLEN] =
{REPORT_LUNS_CMD, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
unsigned char sense_b[SENSE_BUFF_LEN];
struct sg_pt_base * ptvp;
rlCmdBlk[2] = select_report & 0xff;
rlCmdBlk[6] = (mx_resp_len >> 24) & 0xff;
rlCmdBlk[7] = (mx_resp_len >> 16) & 0xff;
rlCmdBlk[8] = (mx_resp_len >> 8) & 0xff;
rlCmdBlk[9] = mx_resp_len & 0xff;
if (NULL == sg_warnings_strm)
sg_warnings_strm = stderr;
if (verbose) {
fprintf(sg_warnings_strm, " report luns cdb: ");
for (k = 0; k < REPORT_LUNS_CMDLEN; ++k)
fprintf(sg_warnings_strm, "%02x ", rlCmdBlk[k]);
fprintf(sg_warnings_strm, "\n");
}
ptvp = construct_scsi_pt_obj();
if (NULL == ptvp) {
fprintf(sg_warnings_strm, "report luns: out of memory\n");
return -1;
}
set_scsi_pt_cdb(ptvp, rlCmdBlk, sizeof(rlCmdBlk));
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, sg_fd, DEF_PT_TIMEOUT, verbose);
ret = sg_cmds_process_resp(ptvp, "report luns", res, mx_resp_len,
sense_b, noisy, verbose, &sense_cat);
if (-1 == ret)
;
else if (-2 == ret) {
switch (sense_cat) {
case SG_LIB_CAT_INVALID_OP:
case SG_LIB_CAT_ILLEGAL_REQ:
case SG_LIB_CAT_ABORTED_COMMAND:
case SG_LIB_CAT_NOT_READY: /* shouldn't happen ?? */
ret = sense_cat;
break;
case SG_LIB_CAT_RECOVERED:
case SG_LIB_CAT_NO_SENSE:
ret = 0;
break;
default:
ret = -1;
break;
}
} else
ret = 0;
destruct_scsi_pt_obj(ptvp);
return ret;
}
ddpt-0.94/lib/Makefile.in 0000644 0001750 0001750 00000053675 12253616765 014245 0 ustar dougg dougg # Makefile.in generated by automake 1.13.3 from Makefile.am.
# @configure_input@
# Copyright (C) 1994-2013 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
@SET_MAKE@
VPATH = @srcdir@
am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
am__make_running_with_option = \
case $${target_option-} in \
?) ;; \
*) echo "am__make_running_with_option: internal error: invalid" \
"target option '$${target_option-}' specified" >&2; \
exit 1;; \
esac; \
has_opt=no; \
sane_makeflags=$$MAKEFLAGS; \
if $(am__is_gnu_make); then \
sane_makeflags=$$MFLAGS; \
else \
case $$MAKEFLAGS in \
*\\[\ \ ]*) \
bs=\\; \
sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
| sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
esac; \
fi; \
skip_next=no; \
strip_trailopt () \
{ \
flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
}; \
for flg in $$sane_makeflags; do \
test $$skip_next = yes && { skip_next=no; continue; }; \
case $$flg in \
*=*|--*) continue;; \
-*I) strip_trailopt 'I'; skip_next=yes;; \
-*I?*) strip_trailopt 'I';; \
-*O) strip_trailopt 'O'; skip_next=yes;; \
-*O?*) strip_trailopt 'O';; \
-*l) strip_trailopt 'l'; skip_next=yes;; \
-*l?*) strip_trailopt 'l';; \
-[dEDm]) skip_next=yes;; \
-[JT]) skip_next=yes;; \
esac; \
case $$flg in \
*$$target_option*) has_opt=yes; break;; \
esac; \
done; \
test $$has_opt = yes
am__make_dryrun = (target_option=n; $(am__make_running_with_option))
am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
pkgdatadir = $(datadir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkglibexecdir = $(libexecdir)/@PACKAGE@
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
@OS_LINUX_TRUE@am__append_1 = \
@OS_LINUX_TRUE@ sg_pt_linux.c \
@OS_LINUX_TRUE@ sg_io_linux.c
@OS_WIN32_MINGW_TRUE@am__append_2 = sg_pt_win32.c
@OS_WIN32_CYGWIN_TRUE@am__append_3 = sg_pt_win32.c
@OS_FREEBSD_TRUE@am__append_4 = sg_pt_freebsd.c
@OS_SOLARIS_TRUE@am__append_5 = sg_pt_solaris.c
@OS_OSF_TRUE@am__append_6 = sg_pt_osf1.c
subdir = lib
DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
$(top_srcdir)/depcomp
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(install_sh) -d
CONFIG_HEADER = $(top_builddir)/config.h
CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
am__vpath_adj = case $$p in \
$(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
*) f=$$p;; \
esac;
am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
am__install_max = 40
am__nobase_strip_setup = \
srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
am__nobase_strip = \
for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
am__nobase_list = $(am__nobase_strip_setup); \
for p in $$list; do echo "$$p $$p"; done | \
sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
$(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
if (++n[$$2] == $(am__install_max)) \
{ print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
END { for (dir in files) print dir, files[dir] }'
am__base_list = \
sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
am__uninstall_files_from_dir = { \
test -z "$$files" \
|| { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
|| { echo " ( cd '$$dir' && rm -f" $$files ")"; \
$(am__cd) "$$dir" && rm -f $$files; }; \
}
am__installdirs = "$(DESTDIR)$(libdir)"
LTLIBRARIES = $(lib_LTLIBRARIES)
am__libsgutils2_la_SOURCES_DIST = sg_lib.c sg_lib_data.c \
sg_cmds_basic.c sg_cmds_basic2.c sg_cmds_extra.c sg_cmds_mmc.c \
sg_pt_common.c sg_pt_linux.c sg_io_linux.c sg_pt_win32.c \
sg_pt_freebsd.c sg_pt_solaris.c sg_pt_osf1.c
@OS_LINUX_TRUE@am__objects_1 = sg_pt_linux.lo sg_io_linux.lo
@OS_WIN32_MINGW_TRUE@am__objects_2 = sg_pt_win32.lo
@OS_WIN32_CYGWIN_TRUE@am__objects_3 = sg_pt_win32.lo
@OS_FREEBSD_TRUE@am__objects_4 = sg_pt_freebsd.lo
@OS_SOLARIS_TRUE@am__objects_5 = sg_pt_solaris.lo
@OS_OSF_TRUE@am__objects_6 = sg_pt_osf1.lo
am_libsgutils2_la_OBJECTS = sg_lib.lo sg_lib_data.lo sg_cmds_basic.lo \
sg_cmds_basic2.lo sg_cmds_extra.lo sg_cmds_mmc.lo \
sg_pt_common.lo $(am__objects_1) $(am__objects_2) \
$(am__objects_3) $(am__objects_4) $(am__objects_5) \
$(am__objects_6)
libsgutils2_la_OBJECTS = $(am_libsgutils2_la_OBJECTS)
AM_V_lt = $(am__v_lt_@AM_V@)
am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
am__v_lt_0 = --silent
am__v_lt_1 =
libsgutils2_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
$(AM_CFLAGS) $(CFLAGS) $(libsgutils2_la_LDFLAGS) $(LDFLAGS) -o \
$@
AM_V_P = $(am__v_P_@AM_V@)
am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
am__v_P_0 = false
am__v_P_1 = :
AM_V_GEN = $(am__v_GEN_@AM_V@)
am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
am__v_GEN_0 = @echo " GEN " $@;
am__v_GEN_1 =
AM_V_at = $(am__v_at_@AM_V@)
am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
am__v_at_0 = @
am__v_at_1 =
DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
depcomp = $(SHELL) $(top_srcdir)/depcomp
am__depfiles_maybe = depfiles
am__mv = mv -f
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
$(AM_CFLAGS) $(CFLAGS)
AM_V_CC = $(am__v_CC_@AM_V@)
am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
am__v_CC_0 = @echo " CC " $@;
am__v_CC_1 =
CCLD = $(CC)
LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
$(AM_LDFLAGS) $(LDFLAGS) -o $@
AM_V_CCLD = $(am__v_CCLD_@AM_V@)
am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
am__v_CCLD_0 = @echo " CCLD " $@;
am__v_CCLD_1 =
SOURCES = $(libsgutils2_la_SOURCES)
DIST_SOURCES = $(am__libsgutils2_la_SOURCES_DIST)
am__can_run_installinfo = \
case $$AM_UPDATE_INFO_DIR in \
n|no|NO) false;; \
*) (install-info --version) >/dev/null 2>&1;; \
esac
am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
# Read a list of newline-separated strings from the standard input,
# and print each of them once, without duplicates. Input order is
# *not* preserved.
am__uniquify_input = $(AWK) '\
BEGIN { nonempty = 0; } \
{ items[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in items) print i; }; } \
'
# Make sure the list of sources is unique. This is necessary because,
# e.g., the same source file might be shared among _SOURCES variables
# for different programs/libraries.
am__define_uniq_tagged_files = \
list='$(am__tagged_files)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | $(am__uniquify_input)`
ETAGS = etags
CTAGS = ctags
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
AMTAR = @AMTAR@
AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
AR = @AR@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
DLLTOOL = @DLLTOOL@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
GETOPT_O_FILES = @GETOPT_O_FILES@
GREP = @GREP@
INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
LD = @LD@
LDFLAGS = @LDFLAGS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LIPO = @LIPO@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
MAINT = @MAINT@
MAKEINFO = @MAKEINFO@
MANIFEST_TOOL = @MANIFEST_TOOL@
MKDIR_P = @MKDIR_P@
NM = @NM@
NMEDIT = @NMEDIT@
OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
OTOOL = @OTOOL@
OTOOL64 = @OTOOL64@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_URL = @PACKAGE_URL@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
RANLIB = @RANLIB@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRIP = @STRIP@
VERSION = @VERSION@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
ac_ct_AR = @ac_ct_AR@
ac_ct_CC = @ac_ct_CC@
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
datadir = @datadir@
datarootdir = @datarootdir@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
localedir = @localedir@
localstatedir = @localstatedir@
mandir = @mandir@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
os_libs = @os_libs@
pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
libsgutils2_la_SOURCES = sg_lib.c sg_lib_data.c sg_cmds_basic.c \
sg_cmds_basic2.c sg_cmds_extra.c sg_cmds_mmc.c sg_pt_common.c \
$(am__append_1) $(am__append_2) $(am__append_3) \
$(am__append_4) $(am__append_5) $(am__append_6)
# For C++/clang testing
# -std= can be c99, c11, gnu11, etc. Default is gnu89 (gnu90 is the same)
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=c11
# AM_CFLAGS = -I ../include -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -Wall -W -pedantic -std=c++11
lib_LTLIBRARIES = libsgutils2.la
libsgutils2_la_LDFLAGS = -version-info 2:0:0
libsgutils2_la_LIBADD = @GETOPT_O_FILES@ @os_libs@
libsgutils2_la_DEPENDENCIES = @GETOPT_O_FILES@
all: all-am
.SUFFIXES:
.SUFFIXES: .c .lo .o .obj
$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
&& { if test -f $@; then exit 0; else break; fi; }; \
exit 1;; \
esac; \
done; \
echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu lib/Makefile'; \
$(am__cd) $(top_srcdir) && \
$(AUTOMAKE) --gnu lib/Makefile
.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
*) \
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
esac;
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(am__aclocal_m4_deps):
install-libLTLIBRARIES: $(lib_LTLIBRARIES)
@$(NORMAL_INSTALL)
@list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
list2=; for p in $$list; do \
if test -f $$p; then \
list2="$$list2 $$p"; \
else :; fi; \
done; \
test -z "$$list2" || { \
echo " $(MKDIR_P) '$(DESTDIR)$(libdir)'"; \
$(MKDIR_P) "$(DESTDIR)$(libdir)" || exit 1; \
echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \
$(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \
}
uninstall-libLTLIBRARIES:
@$(NORMAL_UNINSTALL)
@list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
for p in $$list; do \
$(am__strip_dir) \
echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \
$(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \
done
clean-libLTLIBRARIES:
-test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES)
@list='$(lib_LTLIBRARIES)'; \
locs=`for p in $$list; do echo $$p; done | \
sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
sort -u`; \
test -z "$$locs" || { \
echo rm -f $${locs}; \
rm -f $${locs}; \
}
libsgutils2.la: $(libsgutils2_la_OBJECTS) $(libsgutils2_la_DEPENDENCIES) $(EXTRA_libsgutils2_la_DEPENDENCIES)
$(AM_V_CCLD)$(libsgutils2_la_LINK) -rpath $(libdir) $(libsgutils2_la_OBJECTS) $(libsgutils2_la_LIBADD) $(LIBS)
mostlyclean-compile:
-rm -f *.$(OBJEXT)
distclean-compile:
-rm -f *.tab.c
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sg_cmds_basic.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sg_cmds_basic2.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sg_cmds_extra.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sg_cmds_mmc.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_common.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sg_pt_freebsd.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sg_pt_linux.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sg_pt_osf1.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sg_pt_solaris.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sg_pt_win32.Plo@am__quote@
.c.o:
@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c $<
.c.obj:
@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'`
.c.lo:
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
mostlyclean-libtool:
-rm -f *.lo
clean-libtool:
-rm -rf .libs _libs
ID: $(am__tagged_files)
$(am__define_uniq_tagged_files); mkid -fID $$unique
tags: tags-am
TAGS: tags
tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
set x; \
here=`pwd`; \
$(am__define_uniq_tagged_files); \
shift; \
if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
test -n "$$unique" || unique=$$empty_fix; \
if test $$# -gt 0; then \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
"$$@" $$unique; \
else \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
$$unique; \
fi; \
fi
ctags: ctags-am
CTAGS: ctags
ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
$(am__define_uniq_tagged_files); \
test -z "$(CTAGS_ARGS)$$unique" \
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
$$unique
GTAGS:
here=`$(am__cd) $(top_builddir) && pwd` \
&& $(am__cd) $(top_srcdir) \
&& gtags -i $(GTAGS_ARGS) "$$here"
cscopelist: cscopelist-am
cscopelist-am: $(am__tagged_files)
list='$(am__tagged_files)'; \
case "$(srcdir)" in \
[\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
*) sdir=$(subdir)/$(srcdir) ;; \
esac; \
for i in $$list; do \
if test -f "$$i"; then \
echo "$(subdir)/$$i"; \
else \
echo "$$sdir/$$i"; \
fi; \
done >> $(top_builddir)/cscope.files
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
distdir: $(DISTFILES)
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
list='$(DISTFILES)'; \
dist_files=`for file in $$list; do echo $$file; done | \
sed -e "s|^$$srcdirstrip/||;t" \
-e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
case $$dist_files in \
*/*) $(MKDIR_P) `echo "$$dist_files" | \
sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
sort -u` ;; \
esac; \
for file in $$dist_files; do \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
if test -d $$d/$$file; then \
dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
if test -d "$(distdir)/$$file"; then \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
else \
test -f "$(distdir)/$$file" \
|| cp -p $$d/$$file "$(distdir)/$$file" \
|| exit 1; \
fi; \
done
check-am: all-am
check: check-am
all-am: Makefile $(LTLIBRARIES)
installdirs:
for dir in "$(DESTDIR)$(libdir)"; do \
test -z "$$dir" || $(MKDIR_P) "$$dir"; \
done
install: install-am
install-exec: install-exec-am
install-data: install-data-am
uninstall: uninstall-am
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-am
install-strip:
if test -z '$(STRIP)'; then \
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
install; \
else \
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
"INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
fi
mostlyclean-generic:
clean-generic:
distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
clean: clean-am
clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \
mostlyclean-am
distclean: distclean-am
-rm -rf ./$(DEPDIR)
-rm -f Makefile
distclean-am: clean-am distclean-compile distclean-generic \
distclean-tags
dvi: dvi-am
dvi-am:
html: html-am
html-am:
info: info-am
info-am:
install-data-am:
install-dvi: install-dvi-am
install-dvi-am:
install-exec-am: install-libLTLIBRARIES
install-html: install-html-am
install-html-am:
install-info: install-info-am
install-info-am:
install-man:
install-pdf: install-pdf-am
install-pdf-am:
install-ps: install-ps-am
install-ps-am:
installcheck-am:
maintainer-clean: maintainer-clean-am
-rm -rf ./$(DEPDIR)
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-am
mostlyclean-am: mostlyclean-compile mostlyclean-generic \
mostlyclean-libtool
pdf: pdf-am
pdf-am:
ps: ps-am
ps-am:
uninstall-am: uninstall-libLTLIBRARIES
.MAKE: install-am install-strip
.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \
clean-libLTLIBRARIES clean-libtool cscopelist-am ctags \
ctags-am distclean distclean-compile distclean-generic \
distclean-libtool distclean-tags distdir dvi dvi-am html \
html-am info info-am install install-am install-data \
install-data-am install-dvi install-dvi-am install-exec \
install-exec-am install-html install-html-am install-info \
install-info-am install-libLTLIBRARIES install-man install-pdf \
install-pdf-am install-ps install-ps-am install-strip \
installcheck installcheck-am installdirs maintainer-clean \
maintainer-clean-generic mostlyclean mostlyclean-compile \
mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
tags tags-am uninstall uninstall-am uninstall-libLTLIBRARIES
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:
ddpt-0.94/lib/sg_io_linux.c 0000644 0001750 0001750 00000016721 12024633456 014642 0 ustar dougg dougg /*
* Copyright (c) 1999-2012 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
#include
#include
#include
// 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 SG_LIB_LINUX
#include "sg_io_linux.h"
/* Version 1.04 20120914 */
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", "DID_TRANSPORT_DISRUPTED",
"DID_TRANSPORT_FAILFAST", "DID_TARGET_FAILURE", "DID_NEXUS_FAILURE",
};
#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
ddpt-0.94/lib/sg_lib_data.c 0000644 0001750 0001750 00000166177 12316660506 014566 0 ustar dougg dougg /*
* Copyright (c) 2007-2014 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
#include "sg_lib.h"
#include "sg_lib_data.h"
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
const char * sg_lib_version_str = "1.96 20140401"; /* spc4r36s, sbc4r01 */
#ifdef SG_SCSI_STRINGS
struct sg_lib_value_name_t sg_lib_normal_opcodes[] = {
{0, 0, "Test Unit Ready"},
{0x1, 0, "Rezero Unit"},
{0x1, PDT_TAPE, "Rewind"},
{0x3, 0, "Request Sense"},
{0x4, 0, "Format Unit"},
{0x4, PDT_TAPE, "Format medium"},
{0x4, PDT_PRINTER, "Format"},
{0x5, 0, "Read Block Limits"},
{0x7, 0, "Reassign Blocks"},
{0x7, PDT_MCHANGER, "Initialize element status"},
{0x8, 0, "Read(6)"}, /* obsolete in sbc3r30 */
{0x8, PDT_PROCESSOR, "Receive"},
{0xa, 0, "Write(6)"}, /* obsolete in sbc3r30 */
{0xa, PDT_PRINTER, "Print"},
{0xa, PDT_PROCESSOR, "Send"},
{0xb, 0, "Seek(6)"},
{0xb, PDT_TAPE, "Set capacity"},
{0xb, PDT_PRINTER, "Slew and print"},
{0xf, 0, "Read reverse(6)"},
{0x10, 0, "Write filemarks(6)"},
{0x10, PDT_PRINTER, "Synchronize buffer"},
{0x11, 0, "Space(6)"},
{0x12, 0, "Inquiry"},
{0x13, 0, "Verify(6)"}, /* SSC */
{0x14, 0, "Recover buffered data"},
{0x15, 0, "Mode select(6)"}, /* SBC-3 r31 recommends Mode select(10) */
{0x16, 0, "Reserve(6)"}, /* obsolete in SPC-4 r11 */
{0x16, PDT_MCHANGER, "Reserve element(6)"},
{0x17, 0, "Release(6)"}, /* obsolete in SPC-4 r11 */
{0x17, PDT_MCHANGER, "Release element(6)"},
{0x18, 0, "Copy"}, /* obsolete in SPC-4 r11 */
{0x19, 0, "Erase(6)"},
{0x1a, 0, "Mode sense(6)"}, /* SBC-3 r31 recommends Mode sense(10) */
{0x1b, 0, "Start stop unit"},
{0x1b, PDT_TAPE, "Load unload"},
{0x1b, PDT_ADC, "Load unload"},
{0x1b, PDT_PRINTER, "Stop print"},
{0x1c, 0, "Receive diagnostic results"},
{0x1d, 0, "Send diagnostic"},
{0x1e, 0, "Prevent allow medium removal"},
{0x23, 0, "Read Format capacities"},
{0x24, 0, "Set window"},
{0x25, 0, "Read capacity(10)"},
/* SBC-3 r31 recommends Read capacity(16) */
{0x25, PDT_OCRW, "Read card capacity"},
{0x28, 0, "Read(10)"}, /* SBC-3 r31 recommends Read(16) */
{0x29, 0, "Read generation"},
{0x2a, 0, "Write(10)"}, /* SBC-3 r31 recommends Write(16) */
{0x2b, 0, "Seek(10)"},
{0x2b, PDT_TAPE, "Locate(10)"},
{0x2b, PDT_MCHANGER, "Position to element"},
{0x2c, 0, "Erase(10)"},
{0x2d, 0, "Read updated block"},
{0x2e, 0, "Write and verify(10)"},
/* SBC-3 r31 recommends Write and verify(16) */
{0x2f, 0, "Verify(10)"}, /* SBC-3 r31 recommends Verify(16) */
{0x30, 0, "Search data high(10)"},
{0x31, 0, "Search data equal(10)"},
{0x32, 0, "Search data low(10)"},
{0x33, 0, "Set limits(10)"},
{0x34, 0, "Pre-fetch(10)"}, /* SBC-3 r31 recommends Pre-fetch(16) */
{0x34, PDT_TAPE, "Read position"},
{0x35, 0, "Synchronize cache(10)"},
/* SBC-3 r31 recommends Synchronize cache(16) */
{0x36, 0, "Lock unlock cache(10)"},
{0x37, 0, "Read defect data(10)"},
/* SBC-3 r31 recommends Read defect data(12) */
{0x37, PDT_MCHANGER, "Initialize element status with range"},
{0x38, 0, "Medium scan"},
{0x39, 0, "Compare"}, /* obsolete in SPC-4 r11 */
{0x3a, 0, "Copy and verify"}, /* obsolete in SPC-4 r11 */
{0x3b, 0, "Write buffer"},
{0x3c, 0, "Read buffer"},
{0x3d, 0, "Update block"},
{0x3e, 0, "Read long(10)"}, /* SBC-3 r31 recommends Read long(16) */
{0x3f, 0, "Write long(10)"}, /* SBC-3 r31 recommends Write long(16) */
{0x40, 0, "Change definition"}, /* obsolete in SPC-4 r11 */
{0x41, 0, "Write same(10)"}, /* SBC-3 r31 recommends Write same(16) */
{0x42, 0, "Unmap"}, /* added SPC-4 rev 18 */
{0x42, PDT_MMC, "Read sub-channel"},
{0x43, PDT_MMC, "Read TOC/PMA/ATIP"},
{0x44, 0, "Report density support"},
{0x45, PDT_MMC, "Play audio(10)"},
{0x46, PDT_MMC, "Get configuration"},
{0x47, PDT_MMC, "Play audio msf"},
{0x48, 0, "Sanitize"},
{0x4a, PDT_MMC, "Get event status notification"},
{0x4b, PDT_MMC, "Pause/resume"},
{0x4c, 0, "Log select"},
{0x4d, 0, "Log sense"},
{0x4e, 0, "Stop play/scan"},
{0x50, 0, "Xdwrite(10)"}, /* obsolete in SBC-3 r31 */
{0x51, 0, "Xpwrite(10)"},
{0x51, PDT_MMC, "Read disk information"},
{0x52, 0, "Xdread(10)"}, /* obsolete in SBC-3 r31 */
{0x52, PDT_MMC, "Read track information"},
{0x53, 0, "Reserve track"},
{0x54, 0, "Send OPC information"},
{0x55, 0, "Mode select(10)"},
{0x56, 0, "Reserve(10)"}, /* obsolete in SPC-4 r11 */
{0x56, PDT_MCHANGER, "Reserve element(10)"},
{0x57, 0, "Release(10)"}, /* obsolete in SPC-4 r11 */
{0x57, PDT_MCHANGER, "Release element(10)"},
{0x58, 0, "Repair track"},
{0x5a, 0, "Mode sense(10)"},
{0x5b, 0, "Close track/session"},
{0x5c, 0, "Read buffer capacity"},
{0x5d, 0, "Send cue sheet"},
{0x5e, 0, "Persistent reserve in"},
{0x5f, 0, "Persistent reserve out"},
{0x7e, 0, "Extended cdb (XCBD)"}, /* added in SPC-4 r12 */
{0x80, 0, "Xdwrite extended(16)"},
{0x80, PDT_TAPE, "Write filemarks(16)"},
{0x81, 0, "Rebuild(16)"},
{0x81, PDT_TAPE, "Read reverse(16)"},
{0x82, 0, "Regenerate(16)"},
{0x83, 0, "Third party copy out"}, /* Extended copy, before spc4r34 */
/* Following was "Receive copy results", before spc4r34 */
{0x84, 0, "Third party copy in"},
{0x85, 0, "ATA pass-through(16)"}, /* was 0x98 in spc3 rev21c */
{0x86, 0, "Access control in"},
{0x87, 0, "Access control out"},
{0x88, 0, "Read(16)"},
{0x89, 0, "Compare and write"},
{0x8a, 0, "Write(16)"},
{0x8b, 0, "Orwrite(16)"},
{0x8c, 0, "Read attribute"},
{0x8d, 0, "Write attribute"},
{0x8e, 0, "Write and verify(16)"},
{0x8f, 0, "Verify(16)"},
{0x90, 0, "Pre-fetch(16)"},
{0x91, 0, "Synchronize cache(16)"},
{0x91, PDT_TAPE, "Space(16)"},
{0x92, 0, "Lock unlock cache(16)"},
{0x92, PDT_TAPE, "Locate(16)"},
{0x93, 0, "Write same(16)"},
{0x93, PDT_TAPE, "Erase(16)"},
{0x9d, 0, "Service action bidirectional"}, /* added spc4r35 */
{0x9e, 0, "Service action in(16)"},
{0x9f, 0, "Service action out(16)"},
{0xa0, 0, "Report luns"},
{0xa1, 0, "ATA pass-through(12)"},
{0xa1, PDT_MMC, "Blank"},
{0xa2, 0, "Security protocol in"},
{0xa3, 0, "Maintenance in"},
{0xa3, PDT_MMC, "Send key"},
{0xa4, 0, "Maintenance out"},
{0xa4, PDT_MMC, "Report key"},
{0xa5, 0, "Move medium"},
{0xa5, PDT_MMC, "Play audio(12)"},
{0xa6, 0, "Exchange medium"},
{0xa6, PDT_MMC, "Load/unload medium"},
{0xa7, 0, "Move medium attached"},
{0xa7, PDT_MMC, "Set read ahead"},
{0xa8, 0, "Read(12)"}, /* SBC-3 r31 recommends Read(16) */
{0xa9, 0, "Service action out(12)"},
{0xaa, 0, "Write(12)"}, /* SBC-3 r31 recommends Write(16) */
{0xab, 0, "Service action in(12)"},
{0xac, 0, "erase(12)"},
{0xac, PDT_MMC, "Get performance"},
{0xad, PDT_MMC, "Read DVD/BD structure"},
{0xae, 0, "Write and verify(12)"},
/* SBC-3 r31 recommends Write and verify(16) */
{0xaf, 0, "Verify(12)"}, /* SBC-3 r31 recommends Verify(16) */
{0xb0, 0, "Search data high(12)"},
{0xb1, 0, "Search data equal(12)"},
{0xb1, PDT_MCHANGER, "Open/close import/export element"},
{0xb2, 0, "Search data low(12)"},
{0xb3, 0, "Set limits(12)"},
{0xb4, 0, "Read element status attached"},
{0xb5, 0, "Security protocol out"},
{0xb5, PDT_MCHANGER, "Request volume element address"},
{0xb6, 0, "Send volume tag"},
{0xb6, PDT_MMC, "Set streaming"},
{0xb7, 0, "Read defect data(12)"},
{0xb8, 0, "Read element status"},
{0xb9, 0, "Read CD msf"},
{0xba, 0, "Redundancy group in"},
{0xba, PDT_MMC, "Scan"},
{0xbb, 0, "Redundancy group out"},
{0xbb, PDT_MMC, "Set CD speed"},
{0xbc, 0, "Spare in"},
{0xbd, 0, "Spare out"},
{0xbd, PDT_MMC, "Mechanism status"},
{0xbe, 0, "Volume set in"},
{0xbe, PDT_MMC, "Read CD"},
{0xbf, 0, "Volume set out"},
{0xbf, PDT_MMC, "Send DVD/BD structure"},
{0xffff, 0, NULL},
};
struct sg_lib_value_name_t sg_lib_read_buff_arr[] = { /* opcode 0x3c */
{0x0, 0, "combined header and data [or multiple modes]"},
{0x2, 0, "data"},
{0x3, 0, "descriptor"},
{0xa, 0, "read data from echo buffer"},
{0xb, 0, "echo buffer descriptor"},
{0x1a, 0, "enable expander comms protocol and echo buffer"},
{0x1c, 0, "error history"},
{0xffff, 0, NULL},
};
struct sg_lib_value_name_t sg_lib_write_buff_arr[] = { /* opcode 0x3b */
{0x0, 0, "combined header and data [or multiple modes]"},
{0x2, 0, "data"},
{0x4, 0, "download microcode and activate"},
{0x5, 0, "download microcode, save, and activate"},
{0x6, 0, "download microcode with offsets and activate"},
{0x7, 0, "download microcode with offsets, save, and activate"},
{0xa, 0, "write data to echo buffer"},
{0xd, 0, "download microcode with offsets, select activation events, "
" save and defer activate"},
{0xe, 0, "download microcode with offsets, save and defer activate"},
{0xf, 0, "activate deferred microcode"},
{0x1a, 0, "enable expander comms protocol and echo buffer"},
{0x1b, 0, "disable expander comms protocol"},
{0x1c, 0, "download application client error history"},
{0xffff, 0, NULL},
};
struct sg_lib_value_name_t sg_lib_maint_in_arr[] = { /* opcode 0xa3 */
{0x5, 0, "Report identifying information"},
/* was "Report device identifier" prior to spc4r07 */
{0xa, 0, "Report target port groups"},
{0xb, 0, "Report aliases"},
{0xc, 0, "Report supported operation codes"},
{0xd, 0, "Report supported task management functions"},
{0xe, 0, "Report priority"},
{0xf, 0, "Report timestamp"},
{0x10, 0, "Management protocol in"},
{0xffff, 0, NULL},
};
struct sg_lib_value_name_t sg_lib_maint_out_arr[] = { /* opcode 0xa4 */
{0x6, 0, "Set identifying information"},
/* was "Set device identifier" prior to spc4r07 */
{0xa, 0, "Set target port groups"},
{0xb, 0, "Change aliases"},
{0xc, 0, "Remove I_T nexus"},
{0xe, 0, "Set priority"},
{0xf, 0, "Set timestamp"},
{0x10, 0, "Management protocol out"},
{0xffff, 0, NULL},
};
struct sg_lib_value_name_t sg_lib_serv_in12_arr[] = { /* opcode 0xab */
{0x1, 0, "Read media serial number"},
{0xffff, 0, NULL},
};
struct sg_lib_value_name_t sg_lib_serv_out12_arr[] = { /* opcode 0xa9 */
{0xff, 0, "Impossible command name"},
{0xffff, 0, NULL},
};
struct sg_lib_value_name_t sg_lib_serv_in16_arr[] = { /* opcode 0x9e */
{0x10, 0, "Read capacity(16)"},
{0x11, 0, "Read long(16)"},
{0x12, 0, "Get LBA status"},
{0x13, 0, "Report referrals"},
{0xffff, 0, NULL},
};
struct sg_lib_value_name_t sg_lib_serv_out16_arr[] = { /* opcode 0x9f */
{0x11, 0, "Write long(16)"},
{0x1f, PDT_ADC, "Notify data transfer device(16)"},
{0xffff, 0, NULL},
};
struct sg_lib_value_name_t sg_lib_serv_bidi_arr[] = { /* opcode 0x9d */
{0xffff, 0, NULL},
};
struct sg_lib_value_name_t sg_lib_pr_in_arr[] = { /* opcode 0x5e */
{0x0, 0, "Persistent reserve in, read keys"},
{0x1, 0, "Persistent reserve in, read reservation"},
{0x2, 0, "Persistent reserve in, report capabilities"},
{0x3, 0, "Persistent reserve in, read full status"},
{0xffff, 0, NULL},
};
struct sg_lib_value_name_t sg_lib_pr_out_arr[] = { /* opcode 0x5f */
{0x0, 0, "Persistent reserve out, register"},
{0x1, 0, "Persistent reserve out, reserve"},
{0x2, 0, "Persistent reserve out, release"},
{0x3, 0, "Persistent reserve out, clear"},
{0x4, 0, "Persistent reserve out, preempt"},
{0x5, 0, "Persistent reserve out, preempt and abort"},
{0x6, 0, "Persistent reserve out, register and ignore existing key"},
{0x7, 0, "Persistent reserve out, register and move"},
{0x8, 0, "Persistent reserve out, replace lost reservation"},
{0xffff, 0, NULL},
};
/* 'Extended copy' was renamed 'Third party copy in' in spc4r34 */
/* LID1 is an abbreviation of List Identifier length of 1 byte */
struct sg_lib_value_name_t sg_lib_xcopy_sa_arr[] = { /* opcode 0x83 */
{0x0, 0, "Extended copy(LID1)"},
{0x1, 0, "Extended copy(LID4)"},
{0x10, 0, "Populate token"},
{0x11, 0, "Write using token"},
{0x1c, 0, "Copy operation abort"},
{0xffff, 0, NULL},
};
/* 'Receive copy results' was renamed 'Third party copy out' in spc4r34 */
/* LID4 is an abbreviation of List Identifier length of 4 bytes */
struct sg_lib_value_name_t sg_lib_rec_copy_sa_arr[] = { /* opcode 0x84 */
{0x0, 0, "Receive copy status(LID1)"},
{0x1, 0, "Receive copy data(LID1)"},
{0x3, 0, "Receive copy operating parameters"},
{0x4, 0, "Receive copy failure details(LID1)"},
{0x5, 0, "Receive copy status(LID4)"},
{0x6, 0, "Receive copy data(LID4)"},
{0x7, 0, "Receive ROD token information"},
{0x8, 0, "Report all ROD tokens"},
{0xffff, 0, NULL},
};
struct sg_lib_value_name_t sg_lib_variable_length_arr[] = {
{0x1, 0, "Rebuild(32)"},
{0x2, 0, "Regenerate(32)"},
{0x3, 0, "Xdread(32)"}, /* obsolete in SBC-3 r31 */
{0x4, 0, "Xdwrite(32)"}, /* obsolete in SBC-3 r31 */
{0x5, 0, "Xdwrite extended(32)"},
{0x6, 0, "Xpwrite(32)"},
{0x7, 0, "Xdwriteread(32)"},
{0x8, 0, "Xdwrite extended(64)"},
{0x9, 0, "Read(32)"},
{0xa, 0, "Verify(32)"},
{0xb, 0, "Write(32)"},
{0xc, 0, "Write an verify(32)"},
{0xd, 0, "Write same(32)"},
{0xe, 0, "Orwrite(32)"}, /* added sbc3r25 */
{0x1800, 0, "Receive credential"},
{0x8801, 0, "Format OSD (osd)"},
{0x8802, 0, "Create (osd)"},
{0x8803, 0, "List (osd)"},
{0x8805, 0, "Read (osd)"},
{0x8806, 0, "Write (osd)"},
{0x8807, 0, "Append (osd)"},
{0x8808, 0, "Flush (osd)"},
{0x880a, 0, "Remove (osd)"},
{0x880b, 0, "Create partition (osd)"},
{0x880c, 0, "Remove partition (osd)"},
{0x880e, 0, "Get attributes (osd)"},
{0x880f, 0, "Set attributes (osd)"},
{0x8812, 0, "Create and write (osd)"},
{0x8815, 0, "Create collection (osd)"},
{0x8816, 0, "Remove collection (osd)"},
{0x8817, 0, "List collection (osd)"},
{0x8818, 0, "Set key (osd)"},
{0x8819, 0, "Set master key (osd)"},
{0x881a, 0, "Flush collection (osd)"},
{0x881b, 0, "Flush partition (osd)"},
{0x881c, 0, "Flush OSD (osd)"},
{0x8880, 0, "Object structure check (osd-2)"},
{0x8881, 0, "Format OSD (osd-2)"},
{0x8882, 0, "Create (osd-2)"},
{0x8883, 0, "List (osd-2)"},
{0x8884, 0, "Punch (osd-2)"},
{0x8885, 0, "Read (osd-2)"},
{0x8886, 0, "Write (osd-2)"},
{0x8887, 0, "Append (osd-2)"},
{0x8888, 0, "Flush (osd-2)"},
{0x8889, 0, "Clear (osd-2)"},
{0x888a, 0, "Remove (osd-2)"},
{0x888b, 0, "Create partition (osd-2)"},
{0x888c, 0, "Remove partition (osd-2)"},
{0x888e, 0, "Get attributes (osd-2)"},
{0x888f, 0, "Set attributes (osd-2)"},
{0x8892, 0, "Create and write (osd-2)"},
{0x8895, 0, "Create collection (osd-2)"},
{0x8896, 0, "Remove collection (osd-2)"},
{0x8897, 0, "List collection (osd-2)"},
{0x8898, 0, "Set key (osd-2)"},
{0x8899, 0, "Set master key (osd-2)"},
{0x889a, 0, "Flush collection (osd-2)"},
{0x889b, 0, "Flush partition (osd-2)"},
{0x889c, 0, "Flush OSD (osd-2)"},
{0x88a0, 0, "Query (osd-2)"},
{0x88a1, 0, "Remove member objects (osd-2)"},
{0x88a2, 0, "Get member attributes (osd-2)"},
{0x88a3, 0, "Set member attributes (osd-2)"},
{0x88b1, 0, "Read map (osd-2)"},
{0x8f7c, 0, "Perform SCSI command (osd-2)"},
{0x8f7d, 0, "Perform task management function (osd-2)"},
{0x8f7e, 0, "Perform SCSI command (osd)"},
{0x8f7f, 0, "Perform task management function (osd)"},
{0xffff, 0, NULL},
};
#else
struct sg_lib_value_name_t sg_lib_normal_opcodes[] = {
{0xffff, 0, NULL},
};
struct sg_lib_value_name_t sg_lib_read_buff_arr[] = { /* opcode 0x3c */
{0xffff, 0, NULL},
};
struct sg_lib_value_name_t sg_lib_write_buff_arr[] = { /* opcode 0x3b */
{0xffff, 0, NULL},
};
struct sg_lib_value_name_t sg_lib_maint_in_arr[] = { /* opcode 0xa3 */
{0xffff, 0, NULL},
};
struct sg_lib_value_name_t sg_lib_maint_out_arr[] = { /* opcode 0xa4 */
{0xffff, 0, NULL},
};
struct sg_lib_value_name_t sg_lib_serv_in12_arr[] = { /* opcode 0xab */
{0xffff, 0, NULL},
};
struct sg_lib_value_name_t sg_lib_serv_out12_arr[] = { /* opcode 0xa9 */
{0xffff, 0, NULL},
};
struct sg_lib_value_name_t sg_lib_serv_in16_arr[] = { /* opcode 0x9e */
{0xffff, 0, NULL},
};
struct sg_lib_value_name_t sg_lib_serv_out16_arr[] = { /* opcode 0x9f */
{0xffff, 0, NULL},
};
struct sg_lib_value_name_t sg_lib_serv_bidi_arr[] = { /* opcode 0x9d */
{0xffff, 0, NULL},
};
struct sg_lib_value_name_t sg_lib_pr_in_arr[] = { /* opcode 0x5e */
{0xffff, 0, NULL},
};
struct sg_lib_value_name_t sg_lib_pr_out_arr[] = { /* opcode 0x5f */
{0xffff, 0, NULL},
};
struct sg_lib_value_name_t sg_lib_xcopy_sa_arr[] = { /* opcode 0x83 */
{0xffff, 0, NULL},
};
struct sg_lib_value_name_t sg_lib_rec_copy_sa_arr[] = { /* opcode 0x84 */
{0xffff, 0, NULL},
};
struct sg_lib_value_name_t sg_lib_variable_length_arr[] = {
{0xffff, 0, NULL},
};
#endif
/* A conveniently formatted list of SCSI ASC/ASCQ codes and their
* corresponding text can be found at: www.t10.org/lists/asc-num.txt
* The following should match asc-num.txt dated 20140320 */
#ifdef SG_SCSI_STRINGS
struct sg_lib_asc_ascq_range_t sg_lib_asc_ascq_range[] =
{
{0x40,0x01,0x7f,"Ram failure [0x%x]"},
{0x40,0x80,0xff,"Diagnostic failure on component [0x%x]"},
{0x41,0x01,0xff,"Data path failure [0x%x]"},
{0x42,0x01,0xff,"Power-on or self-test failure [0x%x]"},
{0x4d,0x00,0xff,"Tagged overlapped commands [0x%x]"},
{0x70,0x00,0xff,"Decompression exception short algorithm id of 0x%x"},
{0, 0, 0, NULL}
};
struct sg_lib_asc_ascq_t sg_lib_asc_ascq[] =
{
{0x00,0x00,"No additional sense information"},
{0x00,0x01,"Filemark detected"},
{0x00,0x02,"End-of-partition/medium detected"},
{0x00,0x03,"Setmark detected"},
{0x00,0x04,"Beginning-of-partition/medium detected"},
{0x00,0x05,"End-of-data detected"},
{0x00,0x06,"I/O process terminated"},
{0x00,0x07,"Programmable early warning detected"},
{0x00,0x11,"Audio play operation in progress"},
{0x00,0x12,"Audio play operation paused"},
{0x00,0x13,"Audio play operation successfully completed"},
{0x00,0x14,"Audio play operation stopped due to error"},
{0x00,0x15,"No current audio status to return"},
{0x00,0x16,"operation in progress"},
{0x00,0x17,"Cleaning requested"},
{0x00,0x18,"Erase operation in progress"},
{0x00,0x19,"Locate operation in progress"},
{0x00,0x1a,"Rewind operation in progress"},
{0x00,0x1b,"Set capacity operation in progress"},
{0x00,0x1c,"Verify operation in progress"},
{0x00,0x1d,"ATA pass through information available"},
{0x00,0x1e,"Conflicting SA creation request"},
{0x00,0x1f,"Logical unit transitioning to another power condition"},
{0x00,0x20,"Extended copy information available"},
{0x01,0x00,"No index/sector signal"},
{0x02,0x00,"No seek complete"},
{0x03,0x00,"Peripheral device write fault"},
{0x03,0x01,"No write current"},
{0x03,0x02,"Excessive write errors"},
{0x04,0x00,"Logical unit not ready, cause not reportable"},
{0x04,0x01,"Logical unit is in process of becoming ready"},
{0x04,0x02,"Logical unit not ready, "
"initializing command required"},
{0x04,0x03,"Logical unit not ready, "
"manual intervention required"},
{0x04,0x04,"Logical unit not ready, format in progress"},
{0x04,0x05,"Logical unit not ready, rebuild in progress"},
{0x04,0x06,"Logical unit not ready, recalculation in progress"},
{0x04,0x07,"Logical unit not ready, operation in progress"},
{0x04,0x08,"Logical unit not ready, long write in progress"},
{0x04,0x09,"Logical unit not ready, self-test in progress"},
{0x04,0x0a,"Logical unit "
"not accessible, asymmetric access state transition"},
{0x04,0x0b,"Logical unit "
"not accessible, target port in standby state"},
{0x04,0x0c,"Logical unit "
"not accessible, target port in unavailable state"},
{0x04,0x0d,"Logical unit not ready, structure check required"},
{0x04,0x10,"Logical unit not ready, "
"auxiliary memory not accessible"},
{0x04,0x11,"Logical unit not ready, "
"notify (enable spinup) required"},
{0x04,0x12,"Logical unit not ready, offline"},
{0x04,0x13,"Logical unit not ready, SA creation in progress"},
{0x04,0x14,"Logical unit not ready, space allocation in progress"},
{0x04,0x15,"Logical unit not ready, robotics disabled"},
{0x04,0x16,"Logical unit not ready, configuration required"},
{0x04,0x17,"Logical unit not ready, calibration required"},
{0x04,0x18,"Logical unit not ready, a door is open"},
{0x04,0x19,"Logical unit not ready, operating in sequential mode"},
{0x04,0x1a,"Logical unit not ready, start stop unit command in progress"},
{0x04,0x1b,"Logical unit not ready, sanitize in progress"},
{0x04,0x1c,"Logical unit not ready, additional power use not yet "
"granted"},
{0x04,0x1d,"Logical unit not ready, configuration in progress"},
{0x04,0x1e,"Logical unit not ready, microcode activation required"},
{0x04,0x1f,"Logical unit not ready, microcode download required"},
{0x04,0x20,"Logical unit not ready, logical unit reset required"},
{0x04,0x21,"Logical unit not ready, hard reset required"},
{0x04,0x22,"Logical unit not ready, power cycle required"},
{0x05,0x00,"Logical unit does not respond to selection"},
{0x06,0x00,"No reference position found"},
{0x07,0x00,"Multiple peripheral devices selected"},
{0x08,0x00,"Logical unit communication failure"},
{0x08,0x01,"Logical unit communication time-out"},
{0x08,0x02,"Logical unit communication parity error"},
{0x08,0x03,"Logical unit communication CRC error (Ultra-DMA/32)"},
{0x08,0x04,"Unreachable copy target"},
{0x09,0x00,"Track following error"},
{0x09,0x01,"Tracking servo failure"},
{0x09,0x02,"Focus servo failure"},
{0x09,0x03,"Spindle servo failure"},
{0x09,0x04,"Head select fault"},
{0x0A,0x00,"Error log overflow"},
{0x0B,0x00,"Warning"},
{0x0B,0x01,"Warning - specified temperature exceeded"},
{0x0B,0x02,"Warning - enclosure degraded"},
{0x0B,0x03,"Warning - background self-test failed"},
{0x0B,0x04,"Warning - background pre-scan detected medium error"},
{0x0B,0x05,"Warning - background medium scan detected medium error"},
{0x0B,0x06,"Warning - non-volatile cache now volatile"},
{0x0B,0x07,"Warning - degraded power to non-volatile cache"},
{0x0B,0x08,"Warning - power loss expected"},
{0x0B,0x09,"Warning - device statistics notification active"},
{0x0C,0x00,"Write error"},
{0x0C,0x01,"Write error - recovered with auto reallocation"},
{0x0C,0x02,"Write error - auto reallocation failed"},
{0x0C,0x03,"Write error - recommend reassignment"},
{0x0C,0x04,"Compression check miscompare error"},
{0x0C,0x05,"Data expansion occurred during compression"},
{0x0C,0x06,"Block not compressible"},
{0x0C,0x07,"Write error - recovery needed"},
{0x0C,0x08,"Write error - recovery failed"},
{0x0C,0x09,"Write error - loss of streaming"},
{0x0C,0x0A,"Write error - padding blocks added"},
{0x0C,0x0B,"Auxiliary memory write error"},
{0x0C,0x0C,"Write error - unexpected unsolicited data"},
{0x0C,0x0D,"Write error - not enough unsolicited data"},
{0x0C,0x0E,"Multiple write errors"},
{0x0C,0x0F,"Defects in error window"},
{0x0D,0x00,"Error detected by third party temporary initiator"},
{0x0D,0x01,"Third party device failure"},
{0x0D,0x02,"Copy target device not reachable"},
{0x0D,0x03,"Incorrect copy target device type"},
{0x0D,0x04,"Copy target device data underrun"},
{0x0D,0x05,"Copy target device data overrun"},
{0x0E,0x00,"Invalid information unit"},
{0x0E,0x01,"Information unit too short"},
{0x0E,0x02,"Information unit too long"},
{0x0E,0x03,"Invalid field in command information unit"},
{0x10,0x00,"Id CRC or ECC error"},
{0x10,0x01,"Logical block guard check failed"},
{0x10,0x02,"Logical block application tag check failed"},
{0x10,0x03,"Logical block reference tag check failed"},
{0x10,0x04,"Logical block protection error on recover buffered data"},
{0x10,0x05,"Logical block protection method error"},
{0x11,0x00,"Unrecovered read error"},
{0x11,0x01,"Read retries exhausted"},
{0x11,0x02,"Error too long to correct"},
{0x11,0x03,"Multiple read errors"},
{0x11,0x04,"Unrecovered read error - auto reallocate failed"},
{0x11,0x05,"L-EC uncorrectable error"},
{0x11,0x06,"CIRC unrecovered error"},
{0x11,0x07,"Data re-synchronization error"},
{0x11,0x08,"Incomplete block read"},
{0x11,0x09,"No gap found"},
{0x11,0x0A,"Miscorrected error"},
{0x11,0x0B,"Unrecovered read error - recommend reassignment"},
{0x11,0x0C,"Unrecovered read error - recommend rewrite the data"},
{0x11,0x0D,"De-compression CRC error"},
{0x11,0x0E,"Cannot decompress using declared algorithm"},
{0x11,0x0F,"Error reading UPC/EAN number"},
{0x11,0x10,"Error reading ISRC number"},
{0x11,0x11,"Read error - loss of streaming"},
{0x11,0x12,"Auxiliary memory read error"},
{0x11,0x13,"Read error - failed retransmission request"},
{0x11,0x14,"Read error - LBA marked bad by application client"},
{0x11,0x15,"Write after sanitize required"},
{0x12,0x00,"Address mark not found for id field"},
{0x13,0x00,"Address mark not found for data field"},
{0x14,0x00,"Recorded entity not found"},
{0x14,0x01,"Record not found"},
{0x14,0x02,"Filemark or setmark not found"},
{0x14,0x03,"End-of-data not found"},
{0x14,0x04,"Block sequence error"},
{0x14,0x05,"Record not found - recommend reassignment"},
{0x14,0x06,"Record not found - data auto-reallocated"},
{0x14,0x07,"Locate operation failure"},
{0x15,0x00,"Random positioning error"},
{0x15,0x01,"Mechanical positioning error"},
{0x15,0x02,"Positioning error detected by read of medium"},
{0x16,0x00,"Data synchronization mark error"},
{0x16,0x01,"Data sync error - data rewritten"},
{0x16,0x02,"Data sync error - recommend rewrite"},
{0x16,0x03,"Data sync error - data auto-reallocated"},
{0x16,0x04,"Data sync error - recommend reassignment"},
{0x17,0x00,"Recovered data with no error correction applied"},
{0x17,0x01,"Recovered data with retries"},
{0x17,0x02,"Recovered data with positive head offset"},
{0x17,0x03,"Recovered data with negative head offset"},
{0x17,0x04,"Recovered data with retries and/or circ applied"},
{0x17,0x05,"Recovered data using previous sector id"},
{0x17,0x06,"Recovered data without ECC - data auto-reallocated"},
{0x17,0x07,"Recovered data without ECC - recommend reassignment"},
{0x17,0x08,"Recovered data without ECC - recommend rewrite"},
{0x17,0x09,"Recovered data without ECC - data rewritten"},
{0x18,0x00,"Recovered data with error correction applied"},
{0x18,0x01,"Recovered data with error corr. & retries applied"},
{0x18,0x02,"Recovered data - data auto-reallocated"},
{0x18,0x03,"Recovered data with CIRC"},
{0x18,0x04,"Recovered data with L-EC"},
{0x18,0x05,"Recovered data - recommend reassignment"},
{0x18,0x06,"Recovered data - recommend rewrite"},
{0x18,0x07,"Recovered data with ECC - data rewritten"},
{0x18,0x08,"Recovered data with linking"},
{0x19,0x00,"Defect list error"},
{0x19,0x01,"Defect list not available"},
{0x19,0x02,"Defect list error in primary list"},
{0x19,0x03,"Defect list error in grown list"},
{0x1A,0x00,"Parameter list length error"},
{0x1B,0x00,"Synchronous data transfer error"},
{0x1C,0x00,"Defect list not found"},
{0x1C,0x01,"Primary defect list not found"},
{0x1C,0x02,"Grown defect list not found"},
{0x1D,0x00,"Miscompare during verify operation"},
{0x1D,0x01,"Miscompare verify of unmapped lba"},
{0x1E,0x00,"Recovered id with ECC correction"},
{0x1F,0x00,"Partial defect list transfer"},
{0x20,0x00,"Invalid command operation code"},
{0x20,0x01,"Access denied - initiator pending-enrolled"},
{0x20,0x02,"Access denied - no access rights"},
{0x20,0x03,"Access denied - invalid mgmt id key"},
{0x20,0x04,"Illegal command while in write capable state"},
{0x20,0x05,"Write type operation while in read capable state (obs)"},
{0x20,0x06,"Illegal command while in explicit address mode"},
{0x20,0x07,"Illegal command while in implicit address mode"},
{0x20,0x08,"Access denied - enrollment conflict"},
{0x20,0x09,"Access denied - invalid LU identifier"},
{0x20,0x0A,"Access denied - invalid proxy token"},
{0x20,0x0B,"Access denied - ACL LUN conflict"},
{0x20,0x0C,"Illegal command when not in append-only mode"},
{0x21,0x00,"Logical block address out of range"},
{0x21,0x01,"Invalid element address"},
{0x21,0x02,"Invalid address for write"},
{0x21,0x03,"Invalid write crossing layer jump"},
{0x22,0x00,"Illegal function (use 20 00, 24 00, or 26 00)"},
{0x23,0x00,"Invalid token operation, cause not reportable"},
{0x23,0x01,"Invalid token operation, unsupported token type"},
{0x23,0x02,"Invalid token operation, remote token usage not supported"},
{0x23,0x03,"invalid token operation, remote rod token creation not "
"supported"},
{0x23,0x04,"Invalid token operation, token unknown"},
{0x23,0x05,"Invalid token operation, token corrupt"},
{0x23,0x06,"Invalid token operation, token revoked"},
{0x23,0x07,"Invalid token operation, token expired"},
{0x23,0x08,"Invalid token operation, token cancelled"},
{0x23,0x09,"Invalid token operation, token deleted"},
{0x23,0x0a,"Invalid token operation, invalid token length"},
{0x24,0x00,"Invalid field in cdb"},
{0x24,0x01,"CDB decryption error"},
{0x24,0x02,"Invalid cdb field while in explicit block model (obs)"},
{0x24,0x03,"Invalid cdb field while in implicit block model (obs)"},
{0x24,0x04,"Security audit value frozen"},
{0x24,0x05,"Security working key frozen"},
{0x24,0x06,"Nonce not unique"},
{0x24,0x07,"Nonce timestamp out of range"},
{0x24,0x08,"Invalid xcdb"},
{0x25,0x00,"Logical unit not supported"},
{0x26,0x00,"Invalid field in parameter list"},
{0x26,0x01,"Parameter not supported"},
{0x26,0x02,"Parameter value invalid"},
{0x26,0x03,"Threshold parameters not supported"},
{0x26,0x04,"Invalid release of persistent reservation"},
{0x26,0x05,"Data decryption error"},
{0x26,0x06,"Too many target descriptors"},
{0x26,0x07,"Unsupported target descriptor type code"},
{0x26,0x08,"Too many segment descriptors"},
{0x26,0x09,"Unsupported segment descriptor type code"},
{0x26,0x0A,"Unexpected inexact segment"},
{0x26,0x0B,"Inline data length exceeded"},
{0x26,0x0C,"Invalid operation for copy source or destination"},
{0x26,0x0D,"Copy segment granularity violation"},
{0x26,0x0E,"Invalid parameter while port is enabled"},
{0x26,0x0F,"Invalid data-out buffer integrity check value"},
{0x26,0x10,"Data decryption key fail limit reached"},
{0x26,0x11,"Incomplete key-associated data set"},
{0x26,0x12,"Vendor specific key reference not found"},
{0x27,0x00,"Write protected"},
{0x27,0x01,"Hardware write protected"},
{0x27,0x02,"Logical unit software write protected"},
{0x27,0x03,"Associated write protect"},
{0x27,0x04,"Persistent write protect"},
{0x27,0x05,"Permanent write protect"},
{0x27,0x06,"Conditional write protect"},
{0x27,0x07,"Space allocation failed write protect"},
{0x28,0x00,"Not ready to ready change, medium may have changed"},
{0x28,0x01,"Import or export element accessed"},
{0x28,0x02,"Format-layer may have changed"},
{0x28,0x03,"Import/export element accessed, medium changed"},
{0x29,0x00,"Power on, reset, or bus device reset occurred"},
{0x29,0x01,"Power on occurred"},
{0x29,0x02,"SCSI bus reset occurred"},
{0x29,0x03,"Bus device reset function occurred"},
{0x29,0x04,"Device internal reset"},
{0x29,0x05,"Transceiver mode changed to single-ended"},
{0x29,0x06,"Transceiver mode changed to lvd"},
{0x29,0x07,"I_T nexus loss occurred"},
{0x2A,0x00,"Parameters changed"},
{0x2A,0x01,"Mode parameters changed"},
{0x2A,0x02,"Log parameters changed"},
{0x2A,0x03,"Reservations preempted"},
{0x2A,0x04,"Reservations released"},
{0x2A,0x05,"Registrations preempted"},
{0x2A,0x06,"Asymmetric access state changed"},
{0x2A,0x07,"Implicit asymmetric access state transition failed"},
{0x2A,0x08,"Priority changed"},
{0x2A,0x09,"Capacity data has changed"},
{0x2A,0x0c, "Error recovery attributes have changed"},
{0x2A,0x0d, "Data encryption capabilities changed"},
{0x2A,0x10,"Timestamp changed"},
{0x2A,0x11,"Data encryption parameters changed by another i_t nexus"},
{0x2A,0x12,"Data encryption parameters changed by vendor specific event"},
{0x2A,0x13,"Data encryption key instance counter has changed"},
{0x2A,0x0a,"Error history i_t nexus cleared"},
{0x2A,0x0b,"Error history snapshot released"},
{0x2A,0x14,"SA creation capabilities data has changed"},
{0x2A,0x15,"Medium removal prevention preempted"},
{0x2B,0x00,"Copy cannot execute since host cannot disconnect"},
{0x2C,0x00,"Command sequence error"},
{0x2C,0x01,"Too many windows specified"},
{0x2C,0x02,"Invalid combination of windows specified"},
{0x2C,0x03,"Current program area is not empty"},
{0x2C,0x04,"Current program area is empty"},
{0x2C,0x05,"Illegal power condition request"},
{0x2C,0x06,"Persistent prevent conflict"},
{0x2C,0x07,"Previous busy status"},
{0x2C,0x08,"Previous task set full status"},
{0x2C,0x09,"Previous reservation conflict status"},
{0x2C,0x0A,"Partition or collection contains user objects"},
{0x2C,0x0B,"Not reserved"},
{0x2C,0x0C,"ORWRITE generation does not match"},
{0x2D,0x00,"Overwrite error on update in place"},
{0x2E,0x00,"Insufficient time for operation"},
{0x2E,0x01,"Command timeout before processing"},
{0x2E,0x02,"Command timeout during processing"},
{0x2E,0x03,"Command timeout during processing due to error recovery"},
{0x2F,0x00,"Commands cleared by another initiator"},
{0x2F,0x01,"Commands cleared by power loss notification"},
{0x2F,0x02,"Commands cleared by device server"},
{0x2F,0x03,"Some commands cleared by queuing layer event"},
{0x30,0x00,"Incompatible medium installed"},
{0x30,0x01,"Cannot read medium - unknown format"},
{0x30,0x02,"Cannot read medium - incompatible format"},
{0x30,0x03,"Cleaning cartridge installed"},
{0x30,0x04,"Cannot write medium - unknown format"},
{0x30,0x05,"Cannot write medium - incompatible format"},
{0x30,0x06,"Cannot format medium - incompatible medium"},
{0x30,0x07,"Cleaning failure"},
{0x30,0x08,"Cannot write - application code mismatch"},
{0x30,0x09,"Current session not fixated for append"},
{0x30,0x0A,"Cleaning request rejected"},
{0x30,0x0B,"Cleaning tape expired"},
{0x30,0x0C,"WORM medium - overwrite attempted"},
{0x30,0x0D,"WORM medium - integrity check"},
{0x30,0x10,"Medium not formatted"},
{0x30,0x11,"Incompatible volume type"},
{0x30,0x12,"Incompatible volume qualifier"},
{0x30,0x13,"Cleaning volume expired"},
{0x31,0x00,"Medium format corrupted"},
{0x31,0x01,"Format command failed"},
{0x31,0x02,"Zoned formatting failed due to spare linking"},
{0x31,0x03,"Sanitize command failed"},
{0x32,0x00,"No defect spare location available"},
{0x32,0x01,"Defect list update failure"},
{0x33,0x00,"Tape length error"},
{0x34,0x00,"Enclosure failure"},
{0x35,0x00,"Enclosure services failure"},
{0x35,0x01,"Unsupported enclosure function"},
{0x35,0x02,"Enclosure services unavailable"},
{0x35,0x03,"Enclosure services transfer failure"},
{0x35,0x04,"Enclosure services transfer refused"},
{0x35,0x05,"Enclosure services checksum error"},
{0x36,0x00,"Ribbon, ink, or toner failure"},
{0x37,0x00,"Rounded parameter"},
{0x38,0x00,"Event status notification"},
{0x38,0x02,"Esn - power management class event"},
{0x38,0x04,"Esn - media class event"},
{0x38,0x06,"Esn - device busy class event"},
{0x38,0x07,"Thin provisioning soft threshold reached"},
{0x39,0x00,"Saving parameters not supported"},
{0x3A,0x00,"Medium not present"},
{0x3A,0x01,"Medium not present - tray closed"},
{0x3A,0x02,"Medium not present - tray open"},
{0x3A,0x03,"Medium not present - loadable"},
{0x3A,0x04,"Medium not present - medium auxiliary memory accessible"},
{0x3B,0x00,"Sequential positioning error"},
{0x3B,0x01,"Tape position error at beginning-of-medium"},
{0x3B,0x02,"Tape position error at end-of-medium"},
{0x3B,0x03,"Tape or electronic vertical forms unit not ready"},
{0x3B,0x04,"Slew failure"},
{0x3B,0x05,"Paper jam"},
{0x3B,0x06,"Failed to sense top-of-form"},
{0x3B,0x07,"Failed to sense bottom-of-form"},
{0x3B,0x08,"Reposition error"},
{0x3B,0x09,"Read past end of medium"},
{0x3B,0x0A,"Read past beginning of medium"},
{0x3B,0x0B,"Position past end of medium"},
{0x3B,0x0C,"Position past beginning of medium"},
{0x3B,0x0D,"Medium destination element full"},
{0x3B,0x0E,"Medium source element empty"},
{0x3B,0x0F,"End of medium reached"},
{0x3B,0x11,"Medium magazine not accessible"},
{0x3B,0x12,"Medium magazine removed"},
{0x3B,0x13,"Medium magazine inserted"},
{0x3B,0x14,"Medium magazine locked"},
{0x3B,0x15,"Medium magazine unlocked"},
{0x3B,0x16,"Mechanical positioning or changer error"},
{0x3B,0x17,"Read past end of user object"},
{0x3B,0x18,"Element disabled"},
{0x3B,0x19,"Element enabled"},
{0x3B,0x1a,"Data transfer device removed"},
{0x3B,0x1b,"Data transfer device inserted"},
{0x3B,0x1c,"Too many logical objects on partition to support operation"},
{0x3D,0x00,"Invalid bits in identify message"},
{0x3E,0x00,"Logical unit has not self-configured yet"},
{0x3E,0x01,"Logical unit failure"},
{0x3E,0x02,"Timeout on logical unit"},
{0x3E,0x03,"Logical unit failed self-test"},
{0x3E,0x04,"Logical unit unable to update self-test log"},
{0x3F,0x00,"Target operating conditions have changed"},
{0x3F,0x01,"Microcode has been changed"},
{0x3F,0x02,"Changed operating definition"},
{0x3F,0x03,"Inquiry data has changed"},
{0x3F,0x04,"Component device attached"},
{0x3F,0x05,"Device identifier changed"},
{0x3F,0x06,"Redundancy group created or modified"},
{0x3F,0x07,"Redundancy group deleted"},
{0x3F,0x08,"Spare created or modified"},
{0x3F,0x09,"Spare deleted"},
{0x3F,0x0A,"Volume set created or modified"},
{0x3F,0x0B,"Volume set deleted"},
{0x3F,0x0C,"Volume set deassigned"},
{0x3F,0x0D,"Volume set reassigned"},
{0x3F,0x0E,"Reported luns data has changed"},
{0x3F,0x0F,"Echo buffer overwritten"},
{0x3F,0x10,"Medium loadable"},
{0x3F,0x11,"Medium auxiliary memory accessible"},
{0x3F,0x12,"iSCSI IP address added"},
{0x3F,0x13,"iSCSI IP address removed"},
{0x3F,0x14,"iSCSI IP address changed"},
{0x3F,0x15,"Inspect referrals sense descriptors"},
{0x3F,0x16,"Microcode has been changed without reset"},
/*
* ASC 0x40, 0x41 and 0x42 overridden by "additional2" array entries
* for ascq > 1. Preferred error message for this group is
* "Diagnostic failure on component nn (80h-ffh)".
*/
{0x40,0x00,"Ram failure (should use 40 nn)"},
{0x41,0x00,"Data path failure (should use 40 nn)"},
{0x42,0x00,"Power-on or self-test failure (should use 40 nn)"},
{0x43,0x00,"Message error"},
{0x44,0x00,"Internal target failure"},
{0x44,0x01,"Persistent reservation information lost"},
{0x44,0x71,"ATA device failed Set Features"},
{0x45,0x00,"Select or reselect failure"},
{0x46,0x00,"Unsuccessful soft reset"},
{0x47,0x00,"SCSI parity error"},
{0x47,0x01,"Data phase CRC error detected"},
{0x47,0x02,"SCSI parity error detected during st data phase"},
{0x47,0x03,"Information unit iuCRC error detected"},
{0x47,0x04,"Asynchronous information protection error detected"},
{0x47,0x05,"Protocol service CRC error"},
{0x47,0x06,"Phy test function in progress"},
{0x47,0x7F,"Some commands cleared by iSCSI protocol event"},
{0x48,0x00,"Initiator detected error message received"},
{0x49,0x00,"Invalid message error"},
{0x4A,0x00,"Command phase error"},
{0x4B,0x00,"Data phase error"},
{0x4B,0x01,"Invalid target port transfer tag received"},
{0x4B,0x02,"Too much write data"},
{0x4B,0x03,"Ack/nak timeout"},
{0x4B,0x04,"Nak received"},
{0x4B,0x05,"Data offset error"},
{0x4B,0x06,"Initiator response timeout"},
{0x4B,0x07,"Connection lost"},
{0x4B,0x08,"Data-in buffer overflow - data buffer size"},
{0x4B,0x09,"Data-in buffer overflow - data buffer descriptor area"},
{0x4B,0x0A,"Data-in buffer error"},
{0x4B,0x0B,"Data-out buffer overflow - data buffer size"},
{0x4B,0x0C,"Data-out buffer overflow - data buffer descriptor area"},
{0x4B,0x0D,"Data-out buffer error"},
{0x4B,0x0E,"PCIe fabric error"},
{0x4B,0x0f,"PCIe completion timeout"},
{0x4B,0x10,"PCIe completer abort"},
{0x4B,0x11,"PCIe poisoned tlp received"},
{0x4B,0x12,"PCIe ecrc check failed"},
{0x4B,0x13,"PCIe unsupported request"},
{0x4B,0x14,"PCIe acs violation"},
{0x4B,0x15,"PCIe tlp prefix blocked"},
{0x4C,0x00,"Logical unit failed self-configuration"},
/*
* ASC 0x4D overridden by an "additional2" array entry
* so there is no need to have them here.
*/
/* {0x4D,0x00,"Tagged overlapped commands (nn = queue tag)"}, */
{0x4E,0x00,"Overlapped commands attempted"},
{0x50,0x00,"Write append error"},
{0x50,0x01,"Write append position error"},
{0x50,0x02,"Position error related to timing"},
{0x51,0x00,"Erase failure"},
{0x51,0x01,"Erase failure - incomplete erase operation detected"},
{0x52,0x00,"Cartridge fault"},
{0x53,0x00,"Media load or eject failed"},
{0x53,0x01,"Unload tape failure"},
{0x53,0x02,"Medium removal prevented"},
{0x53,0x03,"Medium removal prevented by data transfer element"},
{0x53,0x04,"Medium thread or unthread failure"},
{0x53,0x05,"Volume identifier invalid"},
{0x53,0x06,"Volume identifier missing"},
{0x53,0x07,"Duplicate volume identifier"},
{0x53,0x08,"Element status unknown"},
{0x53,0x09,"Data transfer device error - load failed"},
{0x53,0x0A,"Data transfer device error - unload failed"},
{0x53,0x0B,"Data transfer device error - unload missing"},
{0x53,0x0C,"Data transfer device error - eject failed"},
{0x53,0x0D,"Data transfer device error - library communication failed"},
{0x54,0x00,"SCSI to host system interface failure"},
{0x55,0x00,"System resource failure"},
{0x55,0x01,"System buffer full"},
{0x55,0x02,"Insufficient reservation resources"},
{0x55,0x03,"Insufficient resources"},
{0x55,0x04,"Insufficient registration resources"},
{0x55,0x05,"Insufficient access control resources"},
{0x55,0x06,"Auxiliary memory out of space"},
{0x55,0x07,"Quota error"},
{0x55,0x08,"Maximum number of supplemental decryption keys exceeded"},
{0x55,0x09,"Medium auxiliary memory not accessible"},
{0x55,0x0a,"Data currently unavailable"},
{0x55,0x0b,"Insufficient power for operation"},
{0x55,0x0c,"Insufficient resources to create rod"},
{0x55,0x0d,"Insufficient resources to create rod token"},
{0x57,0x00,"Unable to recover table-of-contents"},
{0x58,0x00,"Generation does not exist"},
{0x59,0x00,"Updated block read"},
{0x5A,0x00,"Operator request or state change input"},
{0x5A,0x01,"Operator medium removal request"},
{0x5A,0x02,"Operator selected write protect"},
{0x5A,0x03,"Operator selected write permit"},
{0x5B,0x00,"Log exception"},
{0x5B,0x01,"Threshold condition met"},
{0x5B,0x02,"Log counter at maximum"},
{0x5B,0x03,"Log list codes exhausted"},
{0x5C,0x00,"Rpl status change"},
{0x5C,0x01,"Spindles synchronized"},
{0x5C,0x02,"Spindles not synchronized"},
{0x5D,0x00,"Failure prediction threshold exceeded"},
{0x5D,0x01,"Media failure prediction threshold exceeded"},
{0x5D,0x02,"Logical unit failure prediction threshold exceeded"},
{0x5D,0x03,"spare area exhaustion prediction threshold exceeded"},
{0x5D,0x10,"Hardware impending failure general hard drive failure"},
{0x5D,0x11,"Hardware impending failure drive error rate too high" },
{0x5D,0x12,"Hardware impending failure data error rate too high" },
{0x5D,0x13,"Hardware impending failure seek error rate too high" },
{0x5D,0x14,"Hardware impending failure too many block reassigns"},
{0x5D,0x15,"Hardware impending failure access times too high" },
{0x5D,0x16,"Hardware impending failure start unit times too high" },
{0x5D,0x17,"Hardware impending failure channel parametrics"},
{0x5D,0x18,"Hardware impending failure controller detected"},
{0x5D,0x19,"Hardware impending failure throughput performance"},
{0x5D,0x1A,"Hardware impending failure seek time performance"},
{0x5D,0x1B,"Hardware impending failure spin-up retry count"},
{0x5D,0x1C,"Hardware impending failure drive calibration retry count"},
{0x5D,0x20,"Controller impending failure general hard drive failure"},
{0x5D,0x21,"Controller impending failure drive error rate too high" },
{0x5D,0x22,"Controller impending failure data error rate too high" },
{0x5D,0x23,"Controller impending failure seek error rate too high" },
{0x5D,0x24,"Controller impending failure too many block reassigns"},
{0x5D,0x25,"Controller impending failure access times too high" },
{0x5D,0x26,"Controller impending failure start unit times too high" },
{0x5D,0x27,"Controller impending failure channel parametrics"},
{0x5D,0x28,"Controller impending failure controller detected"},
{0x5D,0x29,"Controller impending failure throughput performance"},
{0x5D,0x2A,"Controller impending failure seek time performance"},
{0x5D,0x2B,"Controller impending failure spin-up retry count"},
{0x5D,0x2C,"Controller impending failure drive calibration retry count"},
{0x5D,0x30,"Data channel impending failure general hard drive failure"},
{0x5D,0x31,"Data channel impending failure drive error rate too high" },
{0x5D,0x32,"Data channel impending failure data error rate too high" },
{0x5D,0x33,"Data channel impending failure seek error rate too high" },
{0x5D,0x34,"Data channel impending failure too many block reassigns"},
{0x5D,0x35,"Data channel impending failure access times too high" },
{0x5D,0x36,"Data channel impending failure start unit times too high" },
{0x5D,0x37,"Data channel impending failure channel parametrics"},
{0x5D,0x38,"Data channel impending failure controller detected"},
{0x5D,0x39,"Data channel impending failure throughput performance"},
{0x5D,0x3A,"Data channel impending failure seek time performance"},
{0x5D,0x3B,"Data channel impending failure spin-up retry count"},
{0x5D,0x3C,"Data channel impending failure drive calibration retry count"},
{0x5D,0x40,"Servo impending failure general hard drive failure"},
{0x5D,0x41,"Servo impending failure drive error rate too high" },
{0x5D,0x42,"Servo impending failure data error rate too high" },
{0x5D,0x43,"Servo impending failure seek error rate too high" },
{0x5D,0x44,"Servo impending failure too many block reassigns"},
{0x5D,0x45,"Servo impending failure access times too high" },
{0x5D,0x46,"Servo impending failure start unit times too high" },
{0x5D,0x47,"Servo impending failure channel parametrics"},
{0x5D,0x48,"Servo impending failure controller detected"},
{0x5D,0x49,"Servo impending failure throughput performance"},
{0x5D,0x4A,"Servo impending failure seek time performance"},
{0x5D,0x4B,"Servo impending failure spin-up retry count"},
{0x5D,0x4C,"Servo impending failure drive calibration retry count"},
{0x5D,0x50,"Spindle impending failure general hard drive failure"},
{0x5D,0x51,"Spindle impending failure drive error rate too high" },
{0x5D,0x52,"Spindle impending failure data error rate too high" },
{0x5D,0x53,"Spindle impending failure seek error rate too high" },
{0x5D,0x54,"Spindle impending failure too many block reassigns"},
{0x5D,0x55,"Spindle impending failure access times too high" },
{0x5D,0x56,"Spindle impending failure start unit times too high" },
{0x5D,0x57,"Spindle impending failure channel parametrics"},
{0x5D,0x58,"Spindle impending failure controller detected"},
{0x5D,0x59,"Spindle impending failure throughput performance"},
{0x5D,0x5A,"Spindle impending failure seek time performance"},
{0x5D,0x5B,"Spindle impending failure spin-up retry count"},
{0x5D,0x5C,"Spindle impending failure drive calibration retry count"},
{0x5D,0x60,"Firmware impending failure general hard drive failure"},
{0x5D,0x61,"Firmware impending failure drive error rate too high" },
{0x5D,0x62,"Firmware impending failure data error rate too high" },
{0x5D,0x63,"Firmware impending failure seek error rate too high" },
{0x5D,0x64,"Firmware impending failure too many block reassigns"},
{0x5D,0x65,"Firmware impending failure access times too high" },
{0x5D,0x66,"Firmware impending failure start unit times too high" },
{0x5D,0x67,"Firmware impending failure channel parametrics"},
{0x5D,0x68,"Firmware impending failure controller detected"},
{0x5D,0x69,"Firmware impending failure throughput performance"},
{0x5D,0x6A,"Firmware impending failure seek time performance"},
{0x5D,0x6B,"Firmware impending failure spin-up retry count"},
{0x5D,0x6C,"Firmware impending failure drive calibration retry count"},
{0x5D,0xFF,"Failure prediction threshold exceeded (false)"},
{0x5E,0x00,"Low power condition on"},
{0x5E,0x01,"Idle condition activated by timer"},
{0x5E,0x02,"Standby condition activated by timer"},
{0x5E,0x03,"Idle condition activated by command"},
{0x5E,0x04,"Standby condition activated by command"},
{0x5E,0x05,"Idle_b condition activated by timer"},
{0x5E,0x06,"Idle_b condition activated by command"},
{0x5E,0x07,"Idle_c condition activated by timer"},
{0x5E,0x08,"Idle_c condition activated by command"},
{0x5E,0x09,"Standby_y condition activated by timer"},
{0x5E,0x0a,"Standby_y condition activated by command"},
{0x5E,0x41,"Power state change to active"},
{0x5E,0x42,"Power state change to idle"},
{0x5E,0x43,"Power state change to standby"},
{0x5E,0x45,"Power state change to sleep"},
{0x5E,0x47,"Power state change to device control"},
{0x60,0x00,"Lamp failure"},
{0x61,0x00,"Video acquisition error"},
{0x61,0x01,"Unable to acquire video"},
{0x61,0x02,"Out of focus"},
{0x62,0x00,"Scan head positioning error"},
{0x63,0x00,"End of user area encountered on this track"},
{0x63,0x01,"Packet does not fit in available space"},
{0x64,0x00,"Illegal mode for this track"},
{0x64,0x01,"Invalid packet size"},
{0x65,0x00,"Voltage fault"},
{0x66,0x00,"Automatic document feeder cover up"},
{0x66,0x01,"Automatic document feeder lift up"},
{0x66,0x02,"Document jam in automatic document feeder"},
{0x66,0x03,"Document miss feed automatic in document feeder"},
{0x67,0x00,"Configuration failure"},
{0x67,0x01,"Configuration of incapable logical units failed"},
{0x67,0x02,"Add logical unit failed"},
{0x67,0x03,"Modification of logical unit failed"},
{0x67,0x04,"Exchange of logical unit failed"},
{0x67,0x05,"Remove of logical unit failed"},
{0x67,0x06,"Attachment of logical unit failed"},
{0x67,0x07,"Creation of logical unit failed"},
{0x67,0x08,"Assign failure occurred"},
{0x67,0x09,"Multiply assigned logical unit"},
{0x67,0x0A,"Set target port groups command failed"},
{0x67,0x0B,"ATA device feature not enabled"},
{0x68,0x00,"Logical unit not configured"},
{0x68,0x01,"Subsidiary logical unit not configured"},
{0x69,0x00,"Data loss on logical unit"},
{0x69,0x01,"Multiple logical unit failures"},
{0x69,0x02,"Parity/data mismatch"},
{0x6A,0x00,"Informational, refer to log"},
{0x6B,0x00,"State change has occurred"},
{0x6B,0x01,"Redundancy level got better"},
{0x6B,0x02,"Redundancy level got worse"},
{0x6C,0x00,"Rebuild failure occurred"},
{0x6D,0x00,"Recalculate failure occurred"},
{0x6E,0x00,"Command to logical unit failed"},
{0x6F,0x00,"Copy protection key exchange failure - authentication "
"failure"},
{0x6F,0x01,"Copy protection key exchange failure - key not present"},
{0x6F,0x02,"Copy protection key exchange failure - key not established"},
{0x6F,0x03,"Read of scrambled sector without authentication"},
{0x6F,0x04,"Media region code is mismatched to logical unit region"},
{0x6F,0x05,"Drive region must be permanent/region reset count error"},
{0x6F,0x06,"Insufficient block count for binding nonce recording"},
{0x6F,0x07,"Conflict in binding nonce recording"},
/*
* ASC 0x70 overridden by an "additional2" array entry
* so there is no need to have them here.
*/
/* {0x70,0x00,"Decompression exception short algorithm id of nn"}, */
{0x71,0x00,"Decompression exception long algorithm id"},
{0x72,0x00,"Session fixation error"},
{0x72,0x01,"Session fixation error writing lead-in"},
{0x72,0x02,"Session fixation error writing lead-out"},
{0x72,0x03,"Session fixation error - incomplete track in session"},
{0x72,0x04,"Empty or partially written reserved track"},
{0x72,0x05,"No more track reservations allowed"},
{0x72,0x06,"RMZ extension is not allowed"},
{0x72,0x07,"No more test zone extensions are allowed"},
{0x73,0x00,"CD control error"},
{0x73,0x01,"Power calibration area almost full"},
{0x73,0x02,"Power calibration area is full"},
{0x73,0x03,"Power calibration area error"},
{0x73,0x04,"Program memory area update failure"},
{0x73,0x05,"Program memory area is full"},
{0x73,0x06,"RMA/PMA is almost full"},
{0x73,0x10,"Current power calibration area almost full"},
{0x73,0x11,"Current power calibration area is full"},
{0x73,0x17,"RDZ is full"},
{0x74,0x00,"Security error"},
{0x74,0x01,"Unable to decrypt data"},
{0x74,0x02,"Unencrypted data encountered while decrypting"},
{0x74,0x03,"Incorrect data encryption key"},
{0x74,0x04,"Cryptographic integrity validation failed"},
{0x74,0x05,"Error decrypting data"},
{0x74,0x06,"Unknown signature verification key"},
{0x74,0x07,"Encryption parameters not useable"},
{0x74,0x08,"Digital signature validation failure"},
{0x74,0x09,"Encryption mode mismatch on read"},
{0x74,0x0a,"Encrypted block not raw read enabled"},
{0x74,0x0b,"Incorrect Encryption parameters"},
{0x74,0x0c,"Unable to decrypt parameter list"},
{0x74,0x0d,"Encryption algorithm disabled"},
{0x74,0x10,"SA creation parameter value invalid"},
{0x74,0x11,"SA creation parameter value rejected"},
{0x74,0x12,"Invalid SA usage"},
{0x74,0x21,"Data encryption configuration prevented"},
{0x74,0x30,"SA creation parameter not supported"},
{0x74,0x40,"Authentication failed"},
{0x74,0x61,"External data encryption key manager access error"},
{0x74,0x62,"External data encryption key manager error"},
{0x74,0x63,"External data encryption key not found"},
{0x74,0x64,"External data encryption request not authorized"},
{0x74,0x6e,"External data encryption control timeout"},
{0x74,0x6f,"External data encryption control error"},
{0x74,0x71,"Logical unit access not authorized"},
{0x74,0x79,"Security conflict in translated device"},
{0, 0, NULL}
};
#else
struct sg_lib_asc_ascq_range_t sg_lib_asc_ascq_range[] =
{
{0, 0, 0, NULL}
};
struct sg_lib_asc_ascq_t sg_lib_asc_ascq[] =
{
{0, 0, NULL}
};
#endif /* SG_SCSI_STRINGS */
const char * sg_lib_sense_key_desc[] = {
"No Sense", /* Filemark, ILI and/or EOM; progress
indication (during FORMAT); power
condition sensing (REQUEST SENSE) */
"Recovered Error", /* The last command completed successfully
but used error correction */
"Not Ready", /* The addressed target is not ready */
"Medium Error", /* Data error detected on the medium */
"Hardware Error", /* Controller or device failure */
"Illegal Request",
"Unit Attention", /* Removable medium was changed, or
the target has been reset */
"Data Protect", /* Access to the data is blocked */
"Blank Check", /* Reached unexpected written or unwritten
region of the medium */
"Vendor specific(9)", /* Vendor specific */
"Copy Aborted", /* COPY or COMPARE was aborted */
"Aborted Command", /* The target aborted the command */
"Equal", /* SEARCH DATA found data equal (obsolete) */
"Volume Overflow", /* Medium full with data to be written */
"Miscompare", /* Source data and data on the medium
do not agree */
"Completed" /* may occur for successful cmd (spc4r23) */
};
const char * sg_lib_pdt_strs[] = {
/* 0 */ "disk",
"tape",
"printer",
"processor", /* often SAF-TE device, copy manager */
"write once optical disk",
/* 5 */ "cd/dvd",
"scanner", /* obsolete */
"optical memory device",
"medium changer",
"communications", /* obsolete */
/* 0xa */ "graphics [0xa]", /* obsolete */
"graphics [0xb]", /* obsolete */
"storage array controller",
"enclosure services device",
"simplified direct access device",
"optical card reader/writer device",
/* 0x10 */ "bridge controller commands",
"object based storage",
"automation/driver interface",
"security manager device",
"zoned block commands",
"0x15", "0x16", "0x17", "0x18",
"0x19", "0x1a", "0x1b", "0x1c", "0x1d",
"well known logical unit",
"no physical device on this lu",
};
const char * sg_lib_transport_proto_strs[] =
{
"Fibre Channel Protocol for SCSI (FCP-4)",
"SCSI Parallel Interface (SPI-5)",
"Serial Storage Architecture SCSI-3 Protocol (SSA-S3P)",
"Serial Bus Protocol for IEEE 1394 (SBP-3)",
"SCSI RDMA Protocol (SRP)",
"Internet SCSI (iSCSI)",
"Serial Attached SCSI Protocol (SPL-3)",
"Automation/Drive Interface Transport (ADT-2)",
"AT Attachment Interface (ACS-2)", /* 0x8 */
"USB Attached SCSI (UAS-2)",
"SCSI over PCI Express (SOP)",
"Oxb", "Oxc", "Oxd", "Oxe",
"No specific protocol"
};
ddpt-0.94/lib/sg_pt_freebsd.c 0000644 0001750 0001750 00000033077 12227056727 015141 0 ustar dougg dougg /*
* Copyright (c) 2005-2013 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.
*/
/* sg_pt_freebsd version 1.12 20130919 */
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
// #include
#include
#include
#include
#include
#include
#include
#include "sg_pt.h"
#include "sg_lib.h"
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#define FREEBSD_MAXDEV 64
#define FREEBSD_FDOFFSET 16;
struct freebsd_dev_channel {
char* devname; // the SCSI device name
int unitnum; // the SCSI unit number
struct cam_device* cam_dev;
};
// Private table of open devices: guaranteed zero on startup since
// part of static data.
static struct freebsd_dev_channel *devicetable[FREEBSD_MAXDEV];
#define DEF_TIMEOUT 60000 /* 60,000 milliseconds (60 seconds) */
struct sg_pt_freebsd_scsi {
struct cam_device* cam_dev; // copy held for error processing
union ccb *ccb;
unsigned char * cdb;
int cdb_len;
unsigned char * sense;
int sense_len;
unsigned char * dxferp;
int dxfer_len;
int dxfer_dir;
int scsi_status;
int resid;
int sense_resid;
int in_err;
int os_err;
int transport_err;
};
struct sg_pt_base {
struct sg_pt_freebsd_scsi impl;
};
/* Returns >= 0 if successful. If error in Unix returns negated errno. */
int
scsi_pt_open_device(const char * device_name, int read_only, int verbose)
{
int oflags = 0 /* O_NONBLOCK*/ ;
oflags |= (read_only ? O_RDONLY : O_RDWR);
return scsi_pt_open_flags(device_name, oflags, verbose);
}
/* Similar to scsi_pt_open_device() but takes Unix style open flags OR-ed
* together. The 'flags' argument is ignored in FreeBSD.
* Returns >= 0 if successful, otherwise returns negated errno. */
int
scsi_pt_open_flags(const char * device_name,
int flags __attribute__ ((unused)), int verbose)
{
struct freebsd_dev_channel *fdchan;
struct cam_device* cam_dev;
int k;
if (NULL == sg_warnings_strm)
sg_warnings_strm = stderr;
// Search table for a free entry
for (k = 0; k < FREEBSD_MAXDEV; k++)
if (! devicetable[k])
break;
// If no free entry found, return error. We have max allowed number
// of "file descriptors" already allocated.
if (k == FREEBSD_MAXDEV) {
if (verbose)
fprintf(sg_warnings_strm, "too many open file descriptors "
"(%d)\n", FREEBSD_MAXDEV);
errno = EMFILE;
return -1;
}
fdchan = (struct freebsd_dev_channel *)
calloc(1,sizeof(struct freebsd_dev_channel));
if (fdchan == NULL) {
// errno already set by call to calloc()
return -1;
}
if (! (fdchan->devname = (char *)calloc(1, DEV_IDLEN+1)))
return -1;
if (cam_get_device(device_name, fdchan->devname, DEV_IDLEN,
&(fdchan->unitnum)) == -1) {
if (verbose)
fprintf(sg_warnings_strm, "bad device name structure\n");
errno = EINVAL;
return -1;
}
if (! (cam_dev = cam_open_spec_device(fdchan->devname,
fdchan->unitnum, O_RDWR, NULL))) {
if (verbose)
fprintf(sg_warnings_strm, "cam_open_spec_device: %s\n",
cam_errbuf);
errno = EPERM; /* permissions or no CAM */
return -1;
}
fdchan->cam_dev = cam_dev;
// return pointer to "file descriptor" table entry, properly offset.
devicetable[k] = fdchan;
return k + FREEBSD_FDOFFSET;
}
/* Returns 0 if successful. If error in Unix returns negated errno. */
int
scsi_pt_close_device(int device_fd)
{
struct freebsd_dev_channel *fdchan;
int fd = device_fd - FREEBSD_FDOFFSET;
if ((fd < 0) || (fd >= FREEBSD_MAXDEV)) {
errno = ENODEV;
return -1;
}
fdchan = devicetable[fd];
if (NULL == fdchan) {
errno = ENODEV;
return -1;
}
if (fdchan->devname)
free(fdchan->devname);
if (fdchan->cam_dev)
cam_close_device(fdchan->cam_dev);
free(fdchan);
devicetable[fd] = NULL;
return 0;
}
struct sg_pt_base *
construct_scsi_pt_obj()
{
struct sg_pt_freebsd_scsi * ptp;
ptp = (struct sg_pt_freebsd_scsi *)
calloc(1, sizeof(struct sg_pt_freebsd_scsi));
if (ptp) {
memset(ptp, 0, sizeof(struct sg_pt_freebsd_scsi));
ptp->dxfer_dir = CAM_DIR_NONE;
}
return (struct sg_pt_base *)ptp;
}
void
destruct_scsi_pt_obj(struct sg_pt_base * vp)
{
struct sg_pt_freebsd_scsi * ptp = &vp->impl;
if (ptp) {
if (ptp->ccb)
cam_freeccb(ptp->ccb);
free(ptp);
}
}
void
clear_scsi_pt_obj(struct sg_pt_base * vp)
{
struct sg_pt_freebsd_scsi * ptp = &vp->impl;
if (ptp) {
if (ptp->ccb)
cam_freeccb(ptp->ccb);
memset(ptp, 0, sizeof(struct sg_pt_freebsd_scsi));
ptp->dxfer_dir = CAM_DIR_NONE;
}
}
void
set_scsi_pt_cdb(struct sg_pt_base * vp, const unsigned char * cdb, int cdb_len)
{
struct sg_pt_freebsd_scsi * ptp = &vp->impl;
if (ptp->cdb)
++ptp->in_err;
ptp->cdb = (unsigned char *)cdb;
ptp->cdb_len = cdb_len;
}
void
set_scsi_pt_sense(struct sg_pt_base * vp, unsigned char * sense,
int max_sense_len)
{
struct sg_pt_freebsd_scsi * ptp = &vp->impl;
if (ptp->sense)
++ptp->in_err;
memset(sense, 0, max_sense_len);
ptp->sense = sense;
ptp->sense_len = max_sense_len;
}
/* Setup for data transfer from device */
void
set_scsi_pt_data_in(struct sg_pt_base * vp, unsigned char * dxferp,
int dxfer_len)
{
struct sg_pt_freebsd_scsi * ptp = &vp->impl;
if (ptp->dxferp)
++ptp->in_err;
if (dxfer_len > 0) {
ptp->dxferp = dxferp;
ptp->dxfer_len = dxfer_len;
ptp->dxfer_dir = CAM_DIR_IN;
}
}
/* Setup for data transfer toward device */
void
set_scsi_pt_data_out(struct sg_pt_base * vp, const unsigned char * dxferp,
int dxfer_len)
{
struct sg_pt_freebsd_scsi * ptp = &vp->impl;
if (ptp->dxferp)
++ptp->in_err;
if (dxfer_len > 0) {
ptp->dxferp = (unsigned char *)dxferp;
ptp->dxfer_len = dxfer_len;
ptp->dxfer_dir = CAM_DIR_OUT;
}
}
void
set_scsi_pt_packet_id(struct sg_pt_base * vp __attribute__ ((unused)),
int pack_id __attribute__ ((unused)))
{
}
void
set_scsi_pt_tag(struct sg_pt_base * vp, uint64_t tag __attribute__ ((unused)))
{
struct sg_pt_freebsd_scsi * ptp = &vp->impl;
++ptp->in_err;
}
void
set_scsi_pt_task_management(struct sg_pt_base * vp,
int tmf_code __attribute__ ((unused)))
{
struct sg_pt_freebsd_scsi * ptp = &vp->impl;
++ptp->in_err;
}
void
set_scsi_pt_task_attr(struct sg_pt_base * vp,
int attrib __attribute__ ((unused)),
int priority __attribute__ ((unused)))
{
struct sg_pt_freebsd_scsi * ptp = &vp->impl;
++ptp->in_err;
}
void
set_scsi_pt_flags(struct sg_pt_base * objp, int flags)
{
if (objp) { ; } /* unused, suppress warning */
if (flags) { ; } /* unused, suppress warning */
}
/* Executes SCSI command (or at least forwards it to lower layers).
* Clears os_err field prior to active call (whose result may set it
* again). */
int
do_scsi_pt(struct sg_pt_base * vp, int device_fd, int time_secs, int verbose)
{
int fd = device_fd - FREEBSD_FDOFFSET;
struct sg_pt_freebsd_scsi * ptp = &vp->impl;
struct freebsd_dev_channel *fdchan;
union ccb *ccb;
int len, timout_ms;
if (NULL == sg_warnings_strm)
sg_warnings_strm = stderr;
ptp->os_err = 0;
if (ptp->in_err) {
if (verbose)
fprintf(sg_warnings_strm, "Replicated or unused set_scsi_pt...\n");
return SCSI_PT_DO_BAD_PARAMS;
}
if (NULL == ptp->cdb) {
if (verbose)
fprintf(sg_warnings_strm, "No command (cdb) given\n");
return SCSI_PT_DO_BAD_PARAMS;
}
if ((fd < 0) || (fd >= FREEBSD_MAXDEV)) {
if (verbose)
fprintf(sg_warnings_strm, "Bad file descriptor\n");
ptp->os_err = ENODEV;
return -ptp->os_err;
}
fdchan = devicetable[fd];
if (NULL == fdchan) {
if (verbose)
fprintf(sg_warnings_strm, "File descriptor closed??\n");
ptp->os_err = ENODEV;
return -ptp->os_err;
}
if (NULL == fdchan->cam_dev) {
if (verbose)
fprintf(sg_warnings_strm, "No open CAM device\n");
return SCSI_PT_DO_BAD_PARAMS;
}
if (NULL == ptp->ccb) { /* re-use if we have one already */
if (! (ccb = cam_getccb(fdchan->cam_dev))) {
if (verbose)
fprintf(sg_warnings_strm, "cam_getccb: failed\n");
ptp->os_err = ENOMEM;
return -ptp->os_err;
}
ptp->ccb = ccb;
} else
ccb = ptp->ccb;
// clear out structure, except for header that was filled in for us
bzero(&(&ccb->ccb_h)[1],
sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
timout_ms = (time_secs > 0) ? (time_secs * 1000) : DEF_TIMEOUT;
cam_fill_csio(&ccb->csio,
/* retries */ 1,
/* cbfcnp */ NULL,
/* flags */ ptp->dxfer_dir,
/* tagaction */ MSG_SIMPLE_Q_TAG,
/* dataptr */ ptp->dxferp,
/* datalen */ ptp->dxfer_len,
/* senselen */ ptp->sense_len,
/* cdblen */ ptp->cdb_len,
/* timeout (millisecs) */ timout_ms);
memcpy(ccb->csio.cdb_io.cdb_bytes, ptp->cdb, ptp->cdb_len);
if (cam_send_ccb(fdchan->cam_dev, ccb) < 0) {
if (verbose) {
warn("error sending SCSI ccb");
#if __FreeBSD_version > 500000
cam_error_print(fdchan->cam_dev, ccb, CAM_ESF_ALL,
CAM_EPF_ALL, stderr);
#endif
}
cam_freeccb(ptp->ccb);
ptp->ccb = NULL;
ptp->os_err = EIO;
return -ptp->os_err;
}
if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) ||
((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_SCSI_STATUS_ERROR)) {
ptp->scsi_status = ccb->csio.scsi_status;
ptp->resid = ccb->csio.resid;
ptp->sense_resid = ccb->csio.sense_resid;
if ((SAM_STAT_CHECK_CONDITION == ptp->scsi_status) ||
(SAM_STAT_COMMAND_TERMINATED == ptp->scsi_status)) {
if (ptp->sense_resid > ptp->sense_len)
len = ptp->sense_len; /* crazy; ignore sense_resid */
else
len = ptp->sense_len - ptp->sense_resid;
if (len > 0)
memcpy(ptp->sense, &(ccb->csio.sense_data), len);
}
} else
ptp->transport_err = 1;
ptp->cam_dev = fdchan->cam_dev; // for error processing
return 0;
}
int
get_scsi_pt_result_category(const struct sg_pt_base * vp)
{
const struct sg_pt_freebsd_scsi * ptp = &vp->impl;
if (ptp->os_err)
return SCSI_PT_RESULT_OS_ERR;
else if (ptp->transport_err)
return SCSI_PT_RESULT_TRANSPORT_ERR;
else if ((SAM_STAT_CHECK_CONDITION == ptp->scsi_status) ||
(SAM_STAT_COMMAND_TERMINATED == ptp->scsi_status))
return SCSI_PT_RESULT_SENSE;
else if (ptp->scsi_status)
return SCSI_PT_RESULT_STATUS;
else
return SCSI_PT_RESULT_GOOD;
}
int
get_scsi_pt_resid(const struct sg_pt_base * vp)
{
const struct sg_pt_freebsd_scsi * ptp = &vp->impl;
return ptp->resid;
}
int
get_scsi_pt_status_response(const struct sg_pt_base * vp)
{
const struct sg_pt_freebsd_scsi * ptp = &vp->impl;
return ptp->scsi_status;
}
int
get_scsi_pt_sense_len(const struct sg_pt_base * vp)
{
const struct sg_pt_freebsd_scsi * ptp = &vp->impl;
if (ptp->sense_resid > ptp->sense_len)
return ptp->sense_len; /* strange; ignore ptp->sense_resid */
else
return ptp->sense_len - ptp->sense_resid;
}
int
get_scsi_pt_duration_ms(const struct sg_pt_base * vp __attribute__ ((unused)))
{
// const struct sg_pt_freebsd_scsi * ptp = &vp->impl;
return -1;
}
int
get_scsi_pt_transport_err(const struct sg_pt_base * vp)
{
const struct sg_pt_freebsd_scsi * ptp = &vp->impl;
return ptp->transport_err;
}
int
get_scsi_pt_os_err(const struct sg_pt_base * vp)
{
const struct sg_pt_freebsd_scsi * ptp = &vp->impl;
return ptp->os_err;
}
char *
get_scsi_pt_transport_err_str(const struct sg_pt_base * vp, int max_b_len,
char * b)
{
const struct sg_pt_freebsd_scsi * ptp = &vp->impl;
if (0 == ptp->transport_err) {
strncpy(b, "no transport error available", max_b_len);
b[max_b_len - 1] = '\0';
return b;
}
#if __FreeBSD_version > 500000
if (ptp->cam_dev)
cam_error_string(ptp->cam_dev, ptp->ccb, b, max_b_len, CAM_ESF_ALL,
CAM_EPF_ALL);
else {
strncpy(b, "no transport error available", max_b_len);
b[max_b_len - 1] = '\0';
}
#else
strncpy(b, "no transport error available", max_b_len);
b[max_b_len - 1] = '\0';
#endif
return b;
}
char *
get_scsi_pt_os_err_str(const struct sg_pt_base * vp, int max_b_len, char * b)
{
const struct sg_pt_freebsd_scsi * ptp = &vp->impl;
const char * cp;
cp = safe_strerror(ptp->os_err);
strncpy(b, cp, max_b_len);
if ((int)strlen(cp) >= max_b_len)
b[max_b_len - 1] = '\0';
return b;
}
ddpt-0.94/lib/sg_pt_linux.c 0000644 0001750 0001750 00000067426 12227056727 014673 0 ustar dougg dougg /*
* Copyright (c) 2005-2013 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.
*/
/* sg_pt_linux version 1.20 20131014 */
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "sg_pt.h"
#include "sg_lib.h"
#include "sg_linux_inc.h"
#define DEF_TIMEOUT 60000 /* 60,000 millisecs (60 seconds) */
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" /* 0xd */,
"DID_TRANSPORT_DISRUPTED", "DID_TRANSPORT_FAILFAST",
"DID_TARGET_FAILURE" /* 0x10 */,
"DID_NEXUS_FAILURE (reservation conflict)",
};
#define LINUX_HOST_BYTES_SZ \
(int)(sizeof(linux_host_bytes) / sizeof(linux_host_bytes[0]))
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]))
/*
* These defines are for constants that should be visible in the
* /usr/include/scsi directory (brought in by sg_linux_inc.h).
* Redefined and aliased here to decouple this code from
* sg_io_linux.h
*/
#ifndef DRIVER_MASK
#define DRIVER_MASK 0x0f
#endif
#ifndef SUGGEST_MASK
#define SUGGEST_MASK 0xf0
#endif
#ifndef DRIVER_SENSE
#define DRIVER_SENSE 0x08
#endif
#define SG_LIB_DRIVER_MASK DRIVER_MASK
#define SG_LIB_SUGGEST_MASK SUGGEST_MASK
#define SG_LIB_DRIVER_SENSE DRIVER_SENSE
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
#if defined(IGNORE_LINUX_BSG) || ! defined(HAVE_LINUX_BSG_H)
/*
* sg(v3) via SG_IO ioctl on a sg node or other node that accepts that ioctl.
* Decision has been made at compile time because either:
* a) no /usr/include/linux/bsg.h header file was found, or
* b) the builder gave the '--enable-no-linux-bsg' option to ./configure
*/
struct sg_pt_linux_scsi {
struct sg_io_hdr io_hdr;
int in_err;
int os_err;
};
struct sg_pt_base {
struct sg_pt_linux_scsi impl;
};
/* Returns >= 0 if successful. If error in Unix returns negated errno. */
int
scsi_pt_open_device(const char * device_name, int read_only, int verbose)
{
int oflags = O_NONBLOCK;
oflags |= (read_only ? O_RDONLY : O_RDWR);
return scsi_pt_open_flags(device_name, oflags, verbose);
}
/* Similar to scsi_pt_open_device() but takes Unix style open flags OR-ed */
/* together. The 'flags' argument is advisory and may be ignored. */
/* Returns >= 0 if successful, otherwise returns negated errno. */
int
scsi_pt_open_flags(const char * device_name, int flags, int verbose)
{
int fd;
if (verbose > 1) {
if (NULL == sg_warnings_strm)
sg_warnings_strm = stderr;
fprintf(sg_warnings_strm, "open %s with flags=0x%x\n", device_name,
flags);
}
fd = open(device_name, flags);
if (fd < 0)
fd = -errno;
return fd;
}
/* Returns 0 if successful. If error in Unix returns negated errno. */
int
scsi_pt_close_device(int device_fd)
{
int res;
res = close(device_fd);
if (res < 0)
res = -errno;
return res;
}
struct sg_pt_base *
construct_scsi_pt_obj()
{
struct sg_pt_linux_scsi * ptp;
ptp = (struct sg_pt_linux_scsi *)
calloc(1, sizeof(struct sg_pt_linux_scsi));
if (ptp) {
ptp->io_hdr.interface_id = 'S';
ptp->io_hdr.dxfer_direction = SG_DXFER_NONE;
}
return (struct sg_pt_base *)ptp;
}
void
destruct_scsi_pt_obj(struct sg_pt_base * vp)
{
struct sg_pt_linux_scsi * ptp = &vp->impl;
if (ptp)
free(ptp);
}
void
clear_scsi_pt_obj(struct sg_pt_base * vp)
{
struct sg_pt_linux_scsi * ptp = &vp->impl;
if (ptp) {
memset(ptp, 0, sizeof(struct sg_pt_linux_scsi));
ptp->io_hdr.interface_id = 'S';
ptp->io_hdr.dxfer_direction = SG_DXFER_NONE;
}
}
void
set_scsi_pt_cdb(struct sg_pt_base * vp, const unsigned char * cdb,
int cdb_len)
{
struct sg_pt_linux_scsi * ptp = &vp->impl;
if (ptp->io_hdr.cmdp)
++ptp->in_err;
ptp->io_hdr.cmdp = (unsigned char *)cdb;
ptp->io_hdr.cmd_len = cdb_len;
}
void
set_scsi_pt_sense(struct sg_pt_base * vp, unsigned char * sense,
int max_sense_len)
{
struct sg_pt_linux_scsi * ptp = &vp->impl;
if (ptp->io_hdr.sbp)
++ptp->in_err;
memset(sense, 0, max_sense_len);
ptp->io_hdr.sbp = sense;
ptp->io_hdr.mx_sb_len = max_sense_len;
}
/* Setup for data transfer from device */
void
set_scsi_pt_data_in(struct sg_pt_base * vp, unsigned char * dxferp,
int dxfer_len)
{
struct sg_pt_linux_scsi * ptp = &vp->impl;
if (ptp->io_hdr.dxferp)
++ptp->in_err;
if (dxfer_len > 0) {
ptp->io_hdr.dxferp = dxferp;
ptp->io_hdr.dxfer_len = dxfer_len;
ptp->io_hdr.dxfer_direction = SG_DXFER_FROM_DEV;
}
}
/* Setup for data transfer toward device */
void
set_scsi_pt_data_out(struct sg_pt_base * vp, const unsigned char * dxferp,
int dxfer_len)
{
struct sg_pt_linux_scsi * ptp = &vp->impl;
if (ptp->io_hdr.dxferp)
++ptp->in_err;
if (dxfer_len > 0) {
ptp->io_hdr.dxferp = (unsigned char *)dxferp;
ptp->io_hdr.dxfer_len = dxfer_len;
ptp->io_hdr.dxfer_direction = SG_DXFER_TO_DEV;
}
}
void
set_scsi_pt_packet_id(struct sg_pt_base * vp, int pack_id)
{
struct sg_pt_linux_scsi * ptp = &vp->impl;
ptp->io_hdr.pack_id = pack_id;
}
void
set_scsi_pt_tag(struct sg_pt_base * vp, uint64_t tag)
{
struct sg_pt_linux_scsi * ptp = &vp->impl;
++ptp->in_err;
if (tag) { ; } /* unused, suppress warning */
}
/* Note that task management function codes are transport specific */
void
set_scsi_pt_task_management(struct sg_pt_base * vp, int tmf_code)
{
struct sg_pt_linux_scsi * ptp = &vp->impl;
++ptp->in_err;
if (tmf_code) { ; } /* unused, suppress warning */
}
void
set_scsi_pt_task_attr(struct sg_pt_base * vp, int attribute, int priority)
{
struct sg_pt_linux_scsi * ptp = &vp->impl;
++ptp->in_err;
if (attribute) { ; } /* unused, suppress warning */
if (priority) { ; } /* unused, suppress warning */
}
#ifndef SG_FLAG_Q_AT_TAIL
#define SG_FLAG_Q_AT_TAIL 0x10
#endif
#ifndef SG_FLAG_Q_AT_HEAD
#define SG_FLAG_Q_AT_HEAD 0x20
#endif
void
set_scsi_pt_flags(struct sg_pt_base * vp, int flags)
{
struct sg_pt_linux_scsi * ptp = &vp->impl;
/* default action of SG (v3) is QUEUE_AT_HEAD */
/* default action of block layer SG_IO ioctl is QUEUE_AT_TAIL */
if (SCSI_PT_FLAGS_QUEUE_AT_TAIL & flags) {
ptp->io_hdr.flags |= SG_FLAG_Q_AT_TAIL;
ptp->io_hdr.flags &= ~SG_FLAG_Q_AT_HEAD;
}
if (SCSI_PT_FLAGS_QUEUE_AT_HEAD & flags) {
ptp->io_hdr.flags |= SG_FLAG_Q_AT_HEAD;
ptp->io_hdr.flags &= ~SG_FLAG_Q_AT_TAIL;
}
}
/* Executes SCSI command (or at least forwards it to lower layers).
* Clears os_err field prior to active call (whose result may set it
* again). */
int
do_scsi_pt(struct sg_pt_base * vp, int fd, int time_secs, int verbose)
{
struct sg_pt_linux_scsi * ptp = &vp->impl;
if (NULL == sg_warnings_strm)
sg_warnings_strm = stderr;
ptp->os_err = 0;
if (ptp->in_err) {
if (verbose)
fprintf(sg_warnings_strm, "Replicated or unused set_scsi_pt... "
"functions\n");
return SCSI_PT_DO_BAD_PARAMS;
}
if (NULL == ptp->io_hdr.cmdp) {
if (verbose)
fprintf(sg_warnings_strm, "No SCSI command (cdb) given\n");
return SCSI_PT_DO_BAD_PARAMS;
}
/* io_hdr.timeout is in milliseconds */
ptp->io_hdr.timeout = ((time_secs > 0) ? (time_secs * 1000) :
DEF_TIMEOUT);
if (ptp->io_hdr.sbp && (ptp->io_hdr.mx_sb_len > 0))
memset(ptp->io_hdr.sbp, 0, ptp->io_hdr.mx_sb_len);
if (ioctl(fd, SG_IO, &ptp->io_hdr) < 0) {
ptp->os_err = errno;
if (verbose > 1)
fprintf(sg_warnings_strm, "ioctl(SG_IO) failed: %s (errno=%d)\n",
strerror(ptp->os_err), ptp->os_err);
return -ptp->os_err;
}
return 0;
}
int
get_scsi_pt_result_category(const struct sg_pt_base * vp)
{
const struct sg_pt_linux_scsi * ptp = &vp->impl;
int dr_st = ptp->io_hdr.driver_status & SG_LIB_DRIVER_MASK;
int scsi_st = ptp->io_hdr.status & 0x7e;
if (ptp->os_err)
return SCSI_PT_RESULT_OS_ERR;
else if (ptp->io_hdr.host_status)
return SCSI_PT_RESULT_TRANSPORT_ERR;
else if (dr_st && (SG_LIB_DRIVER_SENSE != dr_st))
return SCSI_PT_RESULT_TRANSPORT_ERR;
else if ((SG_LIB_DRIVER_SENSE == dr_st) ||
(SAM_STAT_CHECK_CONDITION == scsi_st) ||
(SAM_STAT_COMMAND_TERMINATED == scsi_st))
return SCSI_PT_RESULT_SENSE;
else if (scsi_st)
return SCSI_PT_RESULT_STATUS;
else
return SCSI_PT_RESULT_GOOD;
}
int
get_scsi_pt_resid(const struct sg_pt_base * vp)
{
const struct sg_pt_linux_scsi * ptp = &vp->impl;
return ptp->io_hdr.resid;
}
int
get_scsi_pt_status_response(const struct sg_pt_base * vp)
{
const struct sg_pt_linux_scsi * ptp = &vp->impl;
return ptp->io_hdr.status;
}
int
get_scsi_pt_sense_len(const struct sg_pt_base * vp)
{
const struct sg_pt_linux_scsi * ptp = &vp->impl;
return ptp->io_hdr.sb_len_wr;
}
int
get_scsi_pt_duration_ms(const struct sg_pt_base * vp)
{
const struct sg_pt_linux_scsi * ptp = &vp->impl;
return ptp->io_hdr.duration;
}
int
get_scsi_pt_transport_err(const struct sg_pt_base * vp)
{
const struct sg_pt_linux_scsi * ptp = &vp->impl;
return (ptp->io_hdr.host_status << 8) + ptp->io_hdr.driver_status;
}
int
get_scsi_pt_os_err(const struct sg_pt_base * vp)
{
const struct sg_pt_linux_scsi * ptp = &vp->impl;
return ptp->os_err;
}
/* Returns b which will contain a null char terminated string (if
* max_b_len > 0). That string should decode Linux driver and host
* status values. */
char *
get_scsi_pt_transport_err_str(const struct sg_pt_base * vp, int max_b_len,
char * b)
{
const struct sg_pt_linux_scsi * ptp = &vp->impl;
int ds = ptp->io_hdr.driver_status;
int hs = ptp->io_hdr.host_status;
int n, m;
char * cp = b;
int driv, sugg;
const char * driv_cp = "unknown";
const char * sugg_cp = "unknown";
if (max_b_len < 1)
return b;
m = max_b_len;
n = 0;
if (hs) {
if ((hs < 0) || (hs >= LINUX_HOST_BYTES_SZ))
n = snprintf(cp, m, "Host_status=0x%02x is unknown\n", hs);
else
n = snprintf(cp, m, "Host_status=0x%02x [%s]\n", hs,
linux_host_bytes[hs]);
}
m -= n;
if (m < 1) {
b[max_b_len - 1] = '\0';
return b;
}
cp += n;
driv = ds & SG_LIB_DRIVER_MASK;
if (driv < LINUX_DRIVER_BYTES_SZ)
driv_cp = linux_driver_bytes[driv];
sugg = (ds & SG_LIB_SUGGEST_MASK) >> 4;
if (sugg < LINUX_DRIVER_SUGGESTS_SZ)
sugg_cp = linux_driver_suggests[sugg];
n = snprintf(cp, m, "Driver_status=0x%02x [%s, %s]\n", ds, driv_cp,
sugg_cp);
m -= n;
if (m < 1)
b[max_b_len - 1] = '\0';
return b;
}
char *
get_scsi_pt_os_err_str(const struct sg_pt_base * vp, int max_b_len, char * b)
{
const struct sg_pt_linux_scsi * ptp = &vp->impl;
const char * cp;
cp = safe_strerror(ptp->os_err);
strncpy(b, cp, max_b_len);
if ((int)strlen(cp) >= max_b_len)
b[max_b_len - 1] = '\0';
return b;
}
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
#else /* allow for runtime selection of sg v3 or v4 (via bsg) */
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
/*
* So bsg is an option. Thus we make a runtime decision. If all the following
* are true we use sg v4 which is only currently supported on bsg device
* nodes:
* a) there is a bsg entry in the /proc/devices file
* b) the device node given to scsi_pt_open() is a char device
* c) the char major number of the device node given to scsi_pt_open()
* matches the char major number of the bsg entry in /proc/devices
* Otherwise the sg v3 interface is used.
*
* Note that in either case we prepare the data in a sg v4 structure. If
* the runtime tests indicate that the v3 interface is needed then
* do_scsi_pt_v3() transfers the input data into a v3 structure and
* then the output data is transferred back into a sg v4 structure.
* That implementation detail could change in the future.
*
* [20120806] Only use MAJOR() macro in kdev_t.h if that header file is
* available and major() macro [N.B. lower case] is not available.
*/
#include
#include
#ifdef major
#define SG_DEV_MAJOR major
#else
#ifdef HAVE_LINUX_KDEV_T_H
#include
#endif
#define SG_DEV_MAJOR MAJOR /* MAJOR() macro faulty if > 255 minors */
#endif
struct sg_pt_linux_scsi {
struct sg_io_v4 io_hdr; /* use v4 header as it is more general */
int in_err;
int os_err;
unsigned char tmf_request[4];
};
struct sg_pt_base {
struct sg_pt_linux_scsi impl;
};
static int bsg_major_checked = 0;
static int bsg_major = 0;
static void
find_bsg_major(int verbose)
{
const char * proc_devices = "/proc/devices";
FILE *fp;
char a[128];
char b[128];
char * cp;
int n;
if (NULL == (fp = fopen(proc_devices, "r"))) {
if (NULL == sg_warnings_strm)
sg_warnings_strm = stderr;
if (verbose)
fprintf(sg_warnings_strm, "fopen %s failed: %s\n", proc_devices,
strerror(errno));
return;
}
while ((cp = fgets(b, sizeof(b), fp))) {
if ((1 == sscanf(b, "%s", a)) &&
(0 == memcmp(a, "Character", 9)))
break;
}
while (cp && (cp = fgets(b, sizeof(b), fp))) {
if (2 == sscanf(b, "%d %s", &n, a)) {
if (0 == strcmp("bsg", a)) {
bsg_major = n;
break;
}
} else
break;
}
if (verbose > 3) {
if (NULL == sg_warnings_strm)
sg_warnings_strm = stderr;
if (cp)
fprintf(sg_warnings_strm, "found bsg_major=%d\n", bsg_major);
else
fprintf(sg_warnings_strm, "found no bsg char device in %s\n",
proc_devices);
}
fclose(fp);
}
/* Returns >= 0 if successful. If error in Unix returns negated errno. */
int
scsi_pt_open_device(const char * device_name, int read_only, int verbose)
{
int oflags = O_NONBLOCK;
oflags |= (read_only ? O_RDONLY : O_RDWR);
return scsi_pt_open_flags(device_name, oflags, verbose);
}
/* Similar to scsi_pt_open_device() but takes Unix style open flags OR-ed */
/* together. The 'flags' argument is advisory and may be ignored. */
/* Returns >= 0 if successful, otherwise returns negated errno. */
int
scsi_pt_open_flags(const char * device_name, int flags, int verbose)
{
int fd;
if (! bsg_major_checked) {
bsg_major_checked = 1;
find_bsg_major(verbose);
}
if (verbose > 1) {
if (NULL == sg_warnings_strm)
sg_warnings_strm = stderr;
fprintf(sg_warnings_strm, "open %s with flags=0x%x\n", device_name,
flags);
}
fd = open(device_name, flags);
if (fd < 0)
fd = -errno;
return fd;
}
/* Returns 0 if successful. If error in Unix returns negated errno. */
int
scsi_pt_close_device(int device_fd)
{
int res;
res = close(device_fd);
if (res < 0)
res = -errno;
return res;
}
struct sg_pt_base *
construct_scsi_pt_obj()
{
struct sg_pt_linux_scsi * ptp;
ptp = (struct sg_pt_linux_scsi *)
calloc(1, sizeof(struct sg_pt_linux_scsi));
if (ptp) {
ptp->io_hdr.guard = 'Q';
#ifdef BSG_PROTOCOL_SCSI
ptp->io_hdr.protocol = BSG_PROTOCOL_SCSI;
#endif
#ifdef BSG_SUB_PROTOCOL_SCSI_CMD
ptp->io_hdr.subprotocol = BSG_SUB_PROTOCOL_SCSI_CMD;
#endif
}
return (struct sg_pt_base *)ptp;
}
void
destruct_scsi_pt_obj(struct sg_pt_base * vp)
{
struct sg_pt_linux_scsi * ptp = &vp->impl;
if (ptp)
free(ptp);
}
void
clear_scsi_pt_obj(struct sg_pt_base * vp)
{
struct sg_pt_linux_scsi * ptp = &vp->impl;
if (ptp) {
memset(ptp, 0, sizeof(struct sg_pt_linux_scsi));
ptp->io_hdr.guard = 'Q';
#ifdef BSG_PROTOCOL_SCSI
ptp->io_hdr.protocol = BSG_PROTOCOL_SCSI;
#endif
#ifdef BSG_SUB_PROTOCOL_SCSI_CMD
ptp->io_hdr.subprotocol = BSG_SUB_PROTOCOL_SCSI_CMD;
#endif
}
}
void
set_scsi_pt_cdb(struct sg_pt_base * vp, const unsigned char * cdb,
int cdb_len)
{
struct sg_pt_linux_scsi * ptp = &vp->impl;
if (ptp->io_hdr.request)
++ptp->in_err;
/* C99 has intptr_t instead of long */
ptp->io_hdr.request = (__u64)(long)cdb;
ptp->io_hdr.request_len = cdb_len;
}
void
set_scsi_pt_sense(struct sg_pt_base * vp, unsigned char * sense,
int max_sense_len)
{
struct sg_pt_linux_scsi * ptp = &vp->impl;
if (ptp->io_hdr.response)
++ptp->in_err;
memset(sense, 0, max_sense_len);
ptp->io_hdr.response = (__u64)(long)sense;
ptp->io_hdr.max_response_len = max_sense_len;
}
/* Setup for data transfer from device */
void
set_scsi_pt_data_in(struct sg_pt_base * vp, unsigned char * dxferp,
int dxfer_len)
{
struct sg_pt_linux_scsi * ptp = &vp->impl;
if (ptp->io_hdr.din_xferp)
++ptp->in_err;
if (dxfer_len > 0) {
ptp->io_hdr.din_xferp = (__u64)(long)dxferp;
ptp->io_hdr.din_xfer_len = dxfer_len;
}
}
/* Setup for data transfer toward device */
void
set_scsi_pt_data_out(struct sg_pt_base * vp, const unsigned char * dxferp,
int dxfer_len)
{
struct sg_pt_linux_scsi * ptp = &vp->impl;
if (ptp->io_hdr.dout_xferp)
++ptp->in_err;
if (dxfer_len > 0) {
ptp->io_hdr.dout_xferp = (__u64)(long)dxferp;
ptp->io_hdr.dout_xfer_len = dxfer_len;
}
}
void
set_scsi_pt_packet_id(struct sg_pt_base * vp, int pack_id)
{
struct sg_pt_linux_scsi * ptp = &vp->impl;
ptp->io_hdr.spare_in = pack_id;
}
void
set_scsi_pt_tag(struct sg_pt_base * vp, uint64_t tag)
{
struct sg_pt_linux_scsi * ptp = &vp->impl;
ptp->io_hdr.request_tag = tag;
}
/* Note that task management function codes are transport specific */
void
set_scsi_pt_task_management(struct sg_pt_base * vp, int tmf_code)
{
struct sg_pt_linux_scsi * ptp = &vp->impl;
ptp->io_hdr.subprotocol = 1; /* SCSI task management function */
ptp->tmf_request[0] = (unsigned char)tmf_code; /* assume it fits */
ptp->io_hdr.request = (__u64)(long)(&(ptp->tmf_request[0]));
ptp->io_hdr.request_len = 1;
}
void
set_scsi_pt_task_attr(struct sg_pt_base * vp, int attribute, int priority)
{
struct sg_pt_linux_scsi * ptp = &vp->impl;
ptp->io_hdr.request_attr = attribute;
ptp->io_hdr.request_priority = priority;
}
#ifndef BSG_FLAG_Q_AT_TAIL
#define BSG_FLAG_Q_AT_TAIL 0x10
#endif
void
set_scsi_pt_flags(struct sg_pt_base * vp, int flags)
{
struct sg_pt_linux_scsi * ptp = &vp->impl;
/* default action of bsg (sg v4) is QUEUE_AT_HEAD */
if (SCSI_PT_FLAGS_QUEUE_AT_TAIL & flags)
ptp->io_hdr.flags |= BSG_FLAG_Q_AT_TAIL;
if (SCSI_PT_FLAGS_QUEUE_AT_HEAD & flags)
ptp->io_hdr.flags &= ~BSG_FLAG_Q_AT_TAIL;
}
/* N.B. Returns din_resid and ignores dout_resid */
int
get_scsi_pt_resid(const struct sg_pt_base * vp)
{
const struct sg_pt_linux_scsi * ptp = &vp->impl;
return ptp->io_hdr.din_resid;
}
int
get_scsi_pt_status_response(const struct sg_pt_base * vp)
{
const struct sg_pt_linux_scsi * ptp = &vp->impl;
return ptp->io_hdr.device_status;
}
int
get_scsi_pt_sense_len(const struct sg_pt_base * vp)
{
const struct sg_pt_linux_scsi * ptp = &vp->impl;
return ptp->io_hdr.response_len;
}
int
get_scsi_pt_duration_ms(const struct sg_pt_base * vp)
{
const struct sg_pt_linux_scsi * ptp = &vp->impl;
return ptp->io_hdr.duration;
}
int
get_scsi_pt_transport_err(const struct sg_pt_base * vp)
{
const struct sg_pt_linux_scsi * ptp = &vp->impl;
return ptp->io_hdr.transport_status;
}
/* Returns b which will contain a null char terminated string (if
* max_b_len > 0). Combined driver and transport (called "host" in Linux
* kernel) statuses */
char *
get_scsi_pt_transport_err_str(const struct sg_pt_base * vp, int max_b_len,
char * b)
{
const struct sg_pt_linux_scsi * ptp = &vp->impl;
int ds = ptp->io_hdr.driver_status;
int hs = ptp->io_hdr.transport_status;
int n, m;
char * cp = b;
int driv, sugg;
const char * driv_cp = "invalid";
const char * sugg_cp = "invalid";
if (max_b_len < 1)
return b;
m = max_b_len;
n = 0;
if (hs) {
if ((hs < 0) || (hs >= LINUX_HOST_BYTES_SZ))
n = snprintf(cp, m, "Host_status=0x%02x is invalid\n", hs);
else
n = snprintf(cp, m, "Host_status=0x%02x [%s]\n", hs,
linux_host_bytes[hs]);
}
m -= n;
if (m < 1) {
b[max_b_len - 1] = '\0';
return b;
}
cp += n;
driv = ds & SG_LIB_DRIVER_MASK;
if (driv < LINUX_DRIVER_BYTES_SZ)
driv_cp = linux_driver_bytes[driv];
sugg = (ds & SG_LIB_SUGGEST_MASK) >> 4;
if (sugg < LINUX_DRIVER_SUGGESTS_SZ)
sugg_cp = linux_driver_suggests[sugg];
n = snprintf(cp, m, "Driver_status=0x%02x [%s, %s]\n", ds, driv_cp,
sugg_cp);
m -= n;
if (m < 1)
b[max_b_len - 1] = '\0';
return b;
}
int
get_scsi_pt_result_category(const struct sg_pt_base * vp)
{
const struct sg_pt_linux_scsi * ptp = &vp->impl;
int dr_st = ptp->io_hdr.driver_status & SG_LIB_DRIVER_MASK;
int scsi_st = ptp->io_hdr.device_status & 0x7e;
if (ptp->os_err)
return SCSI_PT_RESULT_OS_ERR;
else if (ptp->io_hdr.transport_status)
return SCSI_PT_RESULT_TRANSPORT_ERR;
else if (dr_st && (SG_LIB_DRIVER_SENSE != dr_st))
return SCSI_PT_RESULT_TRANSPORT_ERR;
else if ((SG_LIB_DRIVER_SENSE == dr_st) ||
(SAM_STAT_CHECK_CONDITION == scsi_st) ||
(SAM_STAT_COMMAND_TERMINATED == scsi_st))
return SCSI_PT_RESULT_SENSE;
else if (scsi_st)
return SCSI_PT_RESULT_STATUS;
else
return SCSI_PT_RESULT_GOOD;
}
int
get_scsi_pt_os_err(const struct sg_pt_base * vp)
{
const struct sg_pt_linux_scsi * ptp = &vp->impl;
return ptp->os_err;
}
char *
get_scsi_pt_os_err_str(const struct sg_pt_base * vp, int max_b_len, char * b)
{
const struct sg_pt_linux_scsi * ptp = &vp->impl;
const char * cp;
cp = safe_strerror(ptp->os_err);
strncpy(b, cp, max_b_len);
if ((int)strlen(cp) >= max_b_len)
b[max_b_len - 1] = '\0';
return b;
}
/* Executes SCSI command using sg v3 interface */
static int
do_scsi_pt_v3(struct sg_pt_linux_scsi * ptp, int fd, int time_secs,
int verbose)
{
struct sg_io_hdr v3_hdr;
memset(&v3_hdr, 0, sizeof(v3_hdr));
/* convert v4 to v3 header */
v3_hdr.interface_id = 'S';
v3_hdr.dxfer_direction = SG_DXFER_NONE;
v3_hdr.cmdp = (unsigned char *)(long)ptp->io_hdr.request;
v3_hdr.cmd_len = (unsigned char)ptp->io_hdr.request_len;
if (ptp->io_hdr.din_xfer_len > 0) {
if (ptp->io_hdr.dout_xfer_len > 0) {
if (verbose)
fprintf(sg_warnings_strm, "sgv3 doesn't support bidi\n");
return SCSI_PT_DO_BAD_PARAMS;
}
v3_hdr.dxferp = (void *)(long)ptp->io_hdr.din_xferp;
v3_hdr.dxfer_len = (unsigned int)ptp->io_hdr.din_xfer_len;
v3_hdr.dxfer_direction = SG_DXFER_FROM_DEV;
} else if (ptp->io_hdr.dout_xfer_len > 0) {
v3_hdr.dxferp = (void *)(long)ptp->io_hdr.dout_xferp;
v3_hdr.dxfer_len = (unsigned int)ptp->io_hdr.dout_xfer_len;
v3_hdr.dxfer_direction = SG_DXFER_TO_DEV;
}
if (ptp->io_hdr.response && (ptp->io_hdr.max_response_len > 0)) {
v3_hdr.sbp = (unsigned char *)(long)ptp->io_hdr.response;
v3_hdr.mx_sb_len = (unsigned char)ptp->io_hdr.max_response_len;
}
v3_hdr.pack_id = (int)ptp->io_hdr.spare_in;
if (NULL == v3_hdr.cmdp) {
if (verbose)
fprintf(sg_warnings_strm, "No SCSI command (cdb) given\n");
return SCSI_PT_DO_BAD_PARAMS;
}
/* io_hdr.timeout is in milliseconds, if greater than zero */
v3_hdr.timeout = ((time_secs > 0) ? (time_secs * 1000) : DEF_TIMEOUT);
/* Finally do the v3 SG_IO ioctl */
if (ioctl(fd, SG_IO, &v3_hdr) < 0) {
ptp->os_err = errno;
if (verbose > 1)
fprintf(sg_warnings_strm, "ioctl(SG_IO v3) failed: %s "
"(errno=%d)\n", strerror(ptp->os_err), ptp->os_err);
return -ptp->os_err;
}
ptp->io_hdr.device_status = (__u32)v3_hdr.status;
ptp->io_hdr.driver_status = (__u32)v3_hdr.driver_status;
ptp->io_hdr.transport_status = (__u32)v3_hdr.host_status;
ptp->io_hdr.response_len = (__u32)v3_hdr.sb_len_wr;
ptp->io_hdr.duration = (__u32)v3_hdr.duration;
ptp->io_hdr.din_resid = (__s32)v3_hdr.resid;
/* v3_hdr.info not passed back since no mapping defined (yet) */
return 0;
}
/* Executes SCSI command (or at least forwards it to lower layers).
* Clears os_err field prior to active call (whose result may set it
* again). */
int
do_scsi_pt(struct sg_pt_base * vp, int fd, int time_secs, int verbose)
{
struct sg_pt_linux_scsi * ptp = &vp->impl;
if (! bsg_major_checked) {
bsg_major_checked = 1;
find_bsg_major(verbose);
}
if (NULL == sg_warnings_strm)
sg_warnings_strm = stderr;
ptp->os_err = 0;
if (ptp->in_err) {
if (verbose)
fprintf(sg_warnings_strm, "Replicated or unused set_scsi_pt... "
"functions\n");
return SCSI_PT_DO_BAD_PARAMS;
}
if (bsg_major <= 0)
return do_scsi_pt_v3(ptp, fd, time_secs, verbose);
else {
struct stat a_stat;
if (fstat(fd, &a_stat) < 0) {
ptp->os_err = errno;
if (verbose > 1)
fprintf(sg_warnings_strm, "fstat() failed: %s (errno=%d)\n",
strerror(ptp->os_err), ptp->os_err);
return -ptp->os_err;
}
if (! S_ISCHR(a_stat.st_mode) ||
(bsg_major != (int)SG_DEV_MAJOR(a_stat.st_rdev)))
return do_scsi_pt_v3(ptp, fd, time_secs, verbose);
}
if (! ptp->io_hdr.request) {
if (verbose)
fprintf(sg_warnings_strm, "No SCSI command (cdb) given (v4)\n");
return SCSI_PT_DO_BAD_PARAMS;
}
/* io_hdr.timeout is in milliseconds */
ptp->io_hdr.timeout = ((time_secs > 0) ? (time_secs * 1000) :
DEF_TIMEOUT);
#if 0
/* sense buffer already zeroed */
if (ptp->io_hdr.response && (ptp->io_hdr.max_response_len > 0)) {
void * p;
p = (void *)(long)ptp->io_hdr.response;
memset(p, 0, ptp->io_hdr.max_response_len);
}
#endif
if (ioctl(fd, SG_IO, &ptp->io_hdr) < 0) {
ptp->os_err = errno;
if (verbose > 1)
fprintf(sg_warnings_strm, "ioctl(SG_IO v4) failed: %s "
"(errno=%d)\n", strerror(ptp->os_err), ptp->os_err);
return -ptp->os_err;
}
return 0;
}
#endif
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
ddpt-0.94/lib/sg_pt_solaris.c 0000644 0001750 0001750 00000021465 11351460102 015160 0 ustar dougg dougg /*
* Copyright (c) 2007-2010 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.
*/
/* sg_pt_solaris version 1.03 20100321 */
#include
#include
#include
#include
#include
#include
#include
#include
/* Solaris headers */
#include
#include
#include
#include
#include "sg_pt.h"
#include "sg_lib.h"
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#define DEF_TIMEOUT 60 /* 60 seconds */
struct sg_pt_solaris_scsi {
struct uscsi_cmd uscsi;
int max_sense_len;
int in_err;
int os_err;
};
struct sg_pt_base {
struct sg_pt_solaris_scsi impl;
};
/* Returns >= 0 if successful. If error in Unix returns negated errno. */
int
scsi_pt_open_device(const char * device_name, int read_only, int verbose)
{
int oflags = 0 /* O_NONBLOCK*/ ;
oflags |= (read_only ? O_RDONLY : O_RDWR);
return scsi_pt_open_flags(device_name, oflags, verbose);
}
/* Similar to scsi_pt_open_device() but takes Unix style open flags OR-ed
* together. The 'flags' argument is ignored in Solaris.
* Returns >= 0 if successful, otherwise returns negated errno. */
int
scsi_pt_open_flags(const char * device_name, int flags_arg, int verbose)
{
int oflags = O_NONBLOCK | O_RDWR;
int fd;
flags_arg = flags_arg; /* ignore flags argument, suppress warning */
if (verbose > 1) {
fprintf(stderr, "open %s with flags=0x%x\n", device_name, oflags);
}
fd = open(device_name, oflags);
if (fd < 0)
fd = -errno;
return fd;
}
/* Returns 0 if successful. If error in Unix returns negated errno. */
int
scsi_pt_close_device(int device_fd)
{
int res;
res = close(device_fd);
if (res < 0)
res = -errno;
return res;
}
struct sg_pt_base *
construct_scsi_pt_obj()
{
struct sg_pt_solaris_scsi * ptp;
ptp = (struct sg_pt_solaris_scsi *)
calloc(1, sizeof(struct sg_pt_solaris_scsi));
if (ptp) {
ptp->uscsi.uscsi_timeout = DEF_TIMEOUT;
ptp->uscsi.uscsi_flags = USCSI_READ | USCSI_ISOLATE | USCSI_RQENABLE;
ptp->uscsi.uscsi_timeout = DEF_TIMEOUT;
}
return (struct sg_pt_base *)ptp;
}
void
destruct_scsi_pt_obj(struct sg_pt_base * vp)
{
struct sg_pt_solaris_scsi * ptp = &vp->impl;
if (ptp)
free(ptp);
}
void
clear_scsi_pt_obj(struct sg_pt_base * vp)
{
struct sg_pt_solaris_scsi * ptp = &vp->impl;
if (ptp) {
memset(ptp, 0, sizeof(struct sg_pt_solaris_scsi));
ptp->uscsi.uscsi_timeout = DEF_TIMEOUT;
ptp->uscsi.uscsi_flags = USCSI_READ | USCSI_ISOLATE | USCSI_RQENABLE;
ptp->uscsi.uscsi_timeout = DEF_TIMEOUT;
}
}
void
set_scsi_pt_cdb(struct sg_pt_base * vp, const unsigned char * cdb,
int cdb_len)
{
struct sg_pt_solaris_scsi * ptp = &vp->impl;
if (ptp->uscsi.uscsi_cdb)
++ptp->in_err;
ptp->uscsi.uscsi_cdb = (char *)cdb;
ptp->uscsi.uscsi_cdblen = cdb_len;
}
void
set_scsi_pt_sense(struct sg_pt_base * vp, unsigned char * sense,
int max_sense_len)
{
struct sg_pt_solaris_scsi * ptp = &vp->impl;
if (ptp->uscsi.uscsi_rqbuf)
++ptp->in_err;
memset(sense, 0, max_sense_len);
ptp->uscsi.uscsi_rqbuf = (char *)sense;
ptp->uscsi.uscsi_rqlen = max_sense_len;
ptp->max_sense_len = max_sense_len;
}
/* from device */
void
set_scsi_pt_data_in(struct sg_pt_base * vp, unsigned char * dxferp,
int dxfer_len)
{
struct sg_pt_solaris_scsi * ptp = &vp->impl;
if (ptp->uscsi.uscsi_bufaddr)
++ptp->in_err;
if (dxfer_len > 0) {
ptp->uscsi.uscsi_bufaddr = (char *)dxferp;
ptp->uscsi.uscsi_buflen = dxfer_len;
ptp->uscsi.uscsi_flags = USCSI_READ | USCSI_ISOLATE | USCSI_RQENABLE;
}
}
/* to device */
void
set_scsi_pt_data_out(struct sg_pt_base * vp, const unsigned char * dxferp,
int dxfer_len)
{
struct sg_pt_solaris_scsi * ptp = &vp->impl;
if (ptp->uscsi.uscsi_bufaddr)
++ptp->in_err;
if (dxfer_len > 0) {
ptp->uscsi.uscsi_bufaddr = (char *)dxferp;
ptp->uscsi.uscsi_buflen = dxfer_len;
ptp->uscsi.uscsi_flags = USCSI_WRITE | USCSI_ISOLATE | USCSI_RQENABLE;
}
}
void
set_scsi_pt_packet_id(struct sg_pt_base * vp, int pack_id)
{
// struct sg_pt_solaris_scsi * ptp = &vp->impl;
vp = vp; /* ignore and suppress warning */
pack_id = pack_id; /* ignore and suppress warning */
}
void
set_scsi_pt_tag(struct sg_pt_base * vp, uint64_t tag)
{
// struct sg_pt_solaris_scsi * ptp = &vp->impl;
vp = vp; /* ignore and suppress warning */
tag = tag; /* ignore and suppress warning */
}
/* Note that task management function codes are transport specific */
void
set_scsi_pt_task_management(struct sg_pt_base * vp, int tmf_code)
{
struct sg_pt_solaris_scsi * ptp = &vp->impl;
++ptp->in_err;
tmf_code = tmf_code; /* dummy to silence compiler */
}
void
set_scsi_pt_task_attr(struct sg_pt_base * vp, int attribute, int priority)
{
struct sg_pt_solaris_scsi * ptp = &vp->impl;
++ptp->in_err;
attribute = attribute; /* dummy to silence compiler */
priority = priority; /* dummy to silence compiler */
}
void
set_scsi_pt_flags(struct sg_pt_base * objp, int flags)
{
/* do nothing, suppress warnings */
objp = objp;
flags = flags;
}
/* Executes SCSI command (or at least forwards it to lower layers).
* Clears os_err field prior to active call (whose result may set it
* again). */
int
do_scsi_pt(struct sg_pt_base * vp, int fd, int time_secs, int verbose)
{
struct sg_pt_solaris_scsi * ptp = &vp->impl;
ptp->os_err = 0;
if (ptp->in_err) {
if (verbose)
fprintf(stderr, "Replicated or unused set_scsi_pt... "
"functions\n");
return SCSI_PT_DO_BAD_PARAMS;
}
if (NULL == ptp->uscsi.uscsi_cdb) {
if (verbose)
fprintf(stderr, "No SCSI command (cdb) given\n");
return SCSI_PT_DO_BAD_PARAMS;
}
if (time_secs > 0)
ptp->uscsi.uscsi_timeout = time_secs;
if (ioctl(fd, USCSICMD, &ptp->uscsi)) {
ptp->os_err = errno;
if ((EIO == ptp->os_err) && ptp->uscsi.uscsi_status) {
ptp->os_err = 0;
return 0;
}
if (verbose)
fprintf(stderr, "ioctl(USCSICMD) failed with os_err "
"(errno) = %d\n", ptp->os_err);
return -ptp->os_err;
}
return 0;
}
int
get_scsi_pt_result_category(const struct sg_pt_base * vp)
{
const struct sg_pt_solaris_scsi * ptp = &vp->impl;
int scsi_st = ptp->uscsi.uscsi_status;
if (ptp->os_err)
return SCSI_PT_RESULT_OS_ERR;
else if ((SAM_STAT_CHECK_CONDITION == scsi_st) ||
(SAM_STAT_COMMAND_TERMINATED == scsi_st))
return SCSI_PT_RESULT_SENSE;
else if (scsi_st)
return SCSI_PT_RESULT_STATUS;
else
return SCSI_PT_RESULT_GOOD;
}
int
get_scsi_pt_resid(const struct sg_pt_base * vp)
{
const struct sg_pt_solaris_scsi * ptp = &vp->impl;
return ptp->uscsi.uscsi_resid;
}
int
get_scsi_pt_status_response(const struct sg_pt_base * vp)
{
const struct sg_pt_solaris_scsi * ptp = &vp->impl;
return ptp->uscsi.uscsi_status;
}
int
get_scsi_pt_sense_len(const struct sg_pt_base * vp)
{
const struct sg_pt_solaris_scsi * ptp = &vp->impl;
int res;
if (ptp->max_sense_len > 0) {
res = ptp->max_sense_len - ptp->uscsi.uscsi_rqresid;
return (res > 0) ? res : 0;
}
return 0;
}
int
get_scsi_pt_duration_ms(const struct sg_pt_base * vp)
{
// const struct sg_pt_solaris_scsi * ptp = &vp->impl;
vp = vp; /* ignore and suppress warning */
return -1; /* not available */
}
int
get_scsi_pt_transport_err(const struct sg_pt_base * vp)
{
// const struct sg_pt_solaris_scsi * ptp = &vp->impl;
vp = vp; /* ignore and suppress warning */
return 0;
}
int
get_scsi_pt_os_err(const struct sg_pt_base * vp)
{
const struct sg_pt_solaris_scsi * ptp = &vp->impl;
return ptp->os_err;
}
char *
get_scsi_pt_transport_err_str(const struct sg_pt_base * vp, int max_b_len,
char * b)
{
// const struct sg_pt_solaris_scsi * ptp = &vp->impl;
vp = vp; /* ignore and suppress warning */
if (max_b_len > 0)
b[0] = '\0';
return b;
}
char *
get_scsi_pt_os_err_str(const struct sg_pt_base * vp, int max_b_len, char * b)
{
const struct sg_pt_solaris_scsi * ptp = &vp->impl;
const char * cp;
cp = safe_strerror(ptp->os_err);
strncpy(b, cp, max_b_len);
if ((int)strlen(cp) >= max_b_len)
b[max_b_len - 1] = '\0';
return b;
}
ddpt-0.94/lib/sg_pt_osf1.c 0000644 0001750 0001750 00000030334 12061626602 014357 0 ustar dougg dougg /*
* Copyright (c) 2005-2010 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
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include "sg_pt.h"
#include "sg_lib.h"
/* Changed to use struct sg_pt_base 20070403 */
#define OSF1_MAXDEV 64
struct osf1_dev_channel {
int bus;
int tgt;
int lun;
};
// Private table of open devices: guaranteed zero on startup since
// part of static data.
static struct osf1_dev_channel *devicetable[OSF1_MAXDEV] = {0};
static char *cam_dev = "/dev/cam";
static int camfd;
static int camopened = 0;
struct sg_pt_osf1_scsi {
unsigned char * cdb;
int cdb_len;
unsigned char * sense;
int sense_len;
unsigned char * dxferp;
int dxfer_len;
int dxfer_dir;
int scsi_status;
int resid;
int sense_resid;
int in_err;
int os_err;
int transport_err;
};
struct sg_pt_base {
struct sg_pt_osf1_scsi impl;
};
/* Returns >= 0 if successful. If error in Unix returns negated errno. */
int
scsi_pt_open_device(const char * device_name, int read_only, int verbose)
{
int oflags = 0 /* O_NONBLOCK*/ ;
oflags |= (read_only ? O_RDONLY : O_RDWR);
return scsi_pt_open_flags(device_name, oflags, verbose);
}
/* Similar to scsi_pt_open_device() but takes Unix style open flags OR-ed
* together. The 'flags' argument is ignored in OSF-1.
* Returns >= 0 if successful, otherwise returns negated errno. */
int
scsi_pt_open_flags(const char * device_name, int flags, int verbose)
{
struct osf1_dev_channel *fdchan;
int fd, k;
if (NULL == sg_warnings_strm)
sg_warnings_strm = stderr;
if (!camopened) {
camfd = open(cam_dev, O_RDWR, 0);
if (camfd < 0)
return -1;
camopened++;
}
// Search table for a free entry
for (k = 0; k < OSF1_MAXDEV; k++)
if (! devicetable[k])
break;
if (k == OSF1_MAXDEV) {
if (verbose)
fprintf(sg_warnings_strm, "too many open devices "
"(%d)\n", OSF1_MAXDEV);
errno=EMFILE;
return -1;
}
fdchan = (struct osf1_dev_channel *)calloc(1,
sizeof(struct osf1_dev_channel));
if (fdchan == NULL) {
// errno already set by call to malloc()
return -1;
}
fd = open(device_name, O_RDONLY|O_NONBLOCK);
if (fd > 0) {
device_info_t devinfo;
bzero(&devinfo, sizeof(devinfo));
if (ioctl(fd, DEVGETINFO, &devinfo) == 0) {
fdchan->bus = devinfo.v1.businfo.bus.scsi.bus_num;
fdchan->tgt = devinfo.v1.businfo.bus.scsi.tgt_id;
fdchan->lun = devinfo.v1.businfo.bus.scsi.lun;
}
close (fd);
} else {
free(fdchan);
return -1;
}
devicetable[k] = fdchan;
return k;
}
/* Returns 0 if successful. If error in Unix returns negated errno. */
int
scsi_pt_close_device(int device_fd)
{
struct osf1_dev_channel *fdchan;
int i;
if ((device_fd < 0) || (device_fd >= OSF1_MAXDEV)) {
errno = ENODEV;
return -1;
}
fdchan = devicetable[device_fd];
if (NULL == fdchan) {
errno = ENODEV;
return -1;
}
free(fdchan);
devicetable[device_fd] = NULL;
for (i = 0; i < OSF1_MAXDEV; i++) {
if (devicetable[i])
break;
}
if (i == OSF1_MAXDEV) {
close(camfd);
camopened = 0;
}
return 0;
}
struct sg_pt_base *
construct_scsi_pt_obj()
{
struct sg_pt_osf1_scsi * ptp;
ptp = (struct sg_pt_osf1_scsi *)malloc(sizeof(struct sg_pt_osf1_scsi));
if (ptp) {
bzero(ptp, sizeof(struct sg_pt_osf1_scsi));
ptp->dxfer_dir = CAM_DIR_NONE;
}
return (struct sg_pt_base *)ptp;
}
void
destruct_scsi_pt_obj(struct sg_pt_base * vp)
{
struct sg_pt_osf1_scsi * ptp = &vp->impl;
if (ptp)
free(ptp);
}
void
clear_scsi_pt_obj(struct sg_pt_base * vp)
{
struct sg_pt_osf1_scsi * ptp = &vp->impl;
if (ptp) {
bzero(ptp, sizeof(struct sg_pt_osf1_scsi));
ptp->dxfer_dir = CAM_DIR_NONE;
}
}
void
set_scsi_pt_cdb(struct sg_pt_base * vp, const unsigned char * cdb,
int cdb_len)
{
struct sg_pt_osf1_scsi * ptp = &vp->impl;
if (ptp->cdb)
++ptp->in_err;
ptp->cdb = (unsigned char *)cdb;
ptp->cdb_len = cdb_len;
}
void
set_scsi_pt_sense(struct sg_pt_base * vp, unsigned char * sense,
int max_sense_len)
{
struct sg_pt_osf1_scsi * ptp = &vp->impl;
if (ptp->sense)
++ptp->in_err;
bzero(sense, max_sense_len);
ptp->sense = sense;
ptp->sense_len = max_sense_len;
}
/* from device */
void
set_scsi_pt_data_in(struct sg_pt_base * vp, unsigned char * dxferp,
int dxfer_len)
{
struct sg_pt_osf1_scsi * ptp = &vp->impl;
if (ptp->dxferp)
++ptp->in_err;
if (dxfer_len > 0) {
ptp->dxferp = dxferp;
ptp->dxfer_len = dxfer_len;
ptp->dxfer_dir = CAM_DIR_IN;
}
}
/* to device */
void
set_scsi_pt_data_out(struct sg_pt_base * vp, const unsigned char * dxferp,
int dxfer_len)
{
struct sg_pt_osf1_scsi * ptp = &vp->impl;
if (ptp->dxferp)
++ptp->in_err;
if (dxfer_len > 0) {
ptp->dxferp = (unsigned char *)dxferp;
ptp->dxfer_len = dxfer_len;
ptp->dxfer_dir = CAM_DIR_OUT;
}
}
void
set_scsi_pt_packet_id(struct sg_pt_base * vp, int pack_id)
{
}
void
set_scsi_pt_tag(struct sg_pt_base * vp, uint64_t tag)
{
struct sg_pt_osf1_scsi * ptp = &vp->impl;
++ptp->in_err;
}
void
set_scsi_pt_task_management(struct sg_pt_base * vp, int tmf_code)
{
struct sg_pt_osf1_scsi * ptp = &vp->impl;
++ptp->in_err;
}
void
set_scsi_pt_task_attr(struct sg_pt_base * vp, int attrib, int priority)
{
struct sg_pt_osf1_scsi * ptp = &vp->impl;
++ptp->in_err;
}
void
set_scsi_pt_flags(struct sg_pt_base * objp, int flags)
{
/* do nothing, suppress warnings */
objp = objp;
flags = flags;
}
static int
release_sim(struct sg_pt_base *vp, int device_fd, int verbose) {
struct sg_pt_osf1_scsi * ptp = &vp->impl;
struct osf1_dev_channel *fdchan = devicetable[device_fd];
UAGT_CAM_CCB uagt;
CCB_RELSIM relsim;
int retval;
if (NULL == sg_warnings_strm)
sg_warnings_strm = stderr;
bzero(&uagt, sizeof(uagt));
bzero(&relsim, sizeof(relsim));
uagt.uagt_ccb = (CCB_HEADER *) &relsim;
uagt.uagt_ccblen = sizeof(relsim);
relsim.cam_ch.cam_ccb_len = sizeof(relsim);
relsim.cam_ch.cam_func_code = XPT_REL_SIMQ;
relsim.cam_ch.cam_flags = CAM_DIR_IN | CAM_DIS_CALLBACK;
relsim.cam_ch.cam_path_id = fdchan->bus;
relsim.cam_ch.cam_target_id = fdchan->tgt;
relsim.cam_ch.cam_target_lun = fdchan->lun;
retval = ioctl(camfd, UAGT_CAM_IO, &uagt);
if (retval < 0) {
if (verbose)
fprintf(sg_warnings_strm, "CAM ioctl error (Release SIM Queue)\n");
}
return retval;
}
int
do_scsi_pt(struct sg_pt_base * vp, int device_fd, int time_secs, int verbose)
{
struct sg_pt_osf1_scsi * ptp = &vp->impl;
struct osf1_dev_channel *fdchan;
int len, retval;
CCB_SCSIIO ccb;
UAGT_CAM_CCB uagt;
unsigned char sensep[ADDL_SENSE_LENGTH];
if (NULL == sg_warnings_strm)
sg_warnings_strm = stderr;
ptp->os_err = 0;
if (ptp->in_err) {
if (verbose)
fprintf(sg_warnings_strm, "Replicated or unused set_scsi_pt...\n");
return SCSI_PT_DO_BAD_PARAMS;
}
if (NULL == ptp->cdb) {
if (verbose)
fprintf(sg_warnings_strm, "No command (cdb) given\n");
return SCSI_PT_DO_BAD_PARAMS;
}
if ((device_fd < 0) || (device_fd >= OSF1_MAXDEV)) {
if (verbose)
fprintf(sg_warnings_strm, "Bad file descriptor\n");
ptp->os_err = ENODEV;
return -ptp->os_err;
}
fdchan = devicetable[device_fd];
if (NULL == fdchan) {
if (verbose)
fprintf(sg_warnings_strm, "File descriptor closed??\n");
ptp->os_err = ENODEV;
return -ptp->os_err;
}
if (0 == camopened) {
if (verbose)
fprintf(sg_warnings_strm, "No open CAM device\n");
return SCSI_PT_DO_BAD_PARAMS;
}
bzero(&uagt, sizeof(uagt));
bzero(&ccb, sizeof(ccb));
uagt.uagt_ccb = (CCB_HEADER *) &ccb;
uagt.uagt_ccblen = sizeof(ccb);
uagt.uagt_snsbuf = ccb.cam_sense_ptr = ptp->sense ? ptp->sense : sensep;
uagt.uagt_snslen = ccb.cam_sense_len = ptp->sense ? ptp->sense_len :
sizeof sensep;
uagt.uagt_buffer = ccb.cam_data_ptr = ptp->dxferp;
uagt.uagt_buflen = ccb.cam_dxfer_len = ptp->dxfer_len;
ccb.cam_timeout = time_secs;
ccb.cam_ch.my_addr = (CCB_HEADER *) &ccb;
ccb.cam_ch.cam_ccb_len = sizeof(ccb);
ccb.cam_ch.cam_func_code = XPT_SCSI_IO;
ccb.cam_ch.cam_flags = ptp->dxfer_dir;
ccb.cam_cdb_len = ptp->cdb_len;
memcpy(ccb.cam_cdb_io.cam_cdb_bytes, ptp->cdb, ptp->cdb_len);
ccb.cam_ch.cam_path_id = fdchan->bus;
ccb.cam_ch.cam_target_id = fdchan->tgt;
ccb.cam_ch.cam_target_lun = fdchan->lun;
if (ioctl(camfd, UAGT_CAM_IO, &uagt) < 0) {
if (verbose)
fprintf(sg_warnings_strm, "CAN I/O Error\n");
ptp->os_err = EIO;
return -ptp->os_err;
}
if (((ccb.cam_ch.cam_status & CAM_STATUS_MASK) == CAM_REQ_CMP) ||
((ccb.cam_ch.cam_status & CAM_STATUS_MASK) == CAM_REQ_CMP_ERR)) {
ptp->scsi_status = ccb.cam_scsi_status;
ptp->resid = ccb.cam_resid;
if (ptp->sense)
ptp->sense_resid = ccb.cam_sense_resid;
} else {
ptp->transport_err = 1;
}
/* If the SIM queue is frozen, release SIM queue. */
if (ccb.cam_ch.cam_status & CAM_SIM_QFRZN)
release_sim(vp, device_fd, verbose);
return 0;
}
int
get_scsi_pt_result_category(const struct sg_pt_base * vp)
{
const struct sg_pt_osf1_scsi * ptp = &vp->impl;
if (ptp->os_err)
return SCSI_PT_RESULT_OS_ERR;
else if (ptp->transport_err)
return SCSI_PT_RESULT_TRANSPORT_ERR;
else if ((SAM_STAT_CHECK_CONDITION == ptp->scsi_status) ||
(SAM_STAT_COMMAND_TERMINATED == ptp->scsi_status))
return SCSI_PT_RESULT_SENSE;
else if (ptp->scsi_status)
return SCSI_PT_RESULT_STATUS;
else
return SCSI_PT_RESULT_GOOD;
}
int
get_scsi_pt_resid(const struct sg_pt_base * vp)
{
const struct sg_pt_osf1_scsi * ptp = &vp->impl;
return ptp->resid;
}
int
get_scsi_pt_status_response(const struct sg_pt_base * vp)
{
const struct sg_pt_osf1_scsi * ptp = &vp->impl;
return ptp->scsi_status;
}
int
get_scsi_pt_sense_len(const struct sg_pt_base * vp)
{
const struct sg_pt_osf1_scsi * ptp = &vp->impl;
int len;
len = ptp->sense_len - ptp->sense_resid;
return (len > 0) ? len : 0;
}
int
get_scsi_pt_duration_ms(const struct sg_pt_base * vp)
{
// const struct sg_pt_osf1_scsi * ptp = &vp->impl;
return -1;
}
int
get_scsi_pt_transport_err(const struct sg_pt_base * vp)
{
const struct sg_pt_osf1_scsi * ptp = &vp->impl;
return ptp->transport_err;
}
int
get_scsi_pt_os_err(const struct sg_pt_base * vp)
{
const struct sg_pt_osf1_scsi * ptp = &vp->impl;
return ptp->os_err;
}
char *
get_scsi_pt_transport_err_str(const struct sg_pt_base * vp, int max_b_len,
char * b)
{
const struct sg_pt_osf1_scsi * ptp = &vp->impl;
if (0 == ptp->transport_err) {
strncpy(b, "no transport error available", max_b_len);
b[max_b_len - 1] = '\0';
return b;
}
strncpy(b, "no transport error available", max_b_len);
b[max_b_len - 1] = '\0';
return b;
}
char *
get_scsi_pt_os_err_str(const struct sg_pt_base * vp, int max_b_len, char * b)
{
const struct sg_pt_osf1_scsi * ptp = &vp->impl;
const char * cp;
cp = safe_strerror(ptp->os_err);
strncpy(b, cp, max_b_len);
if ((int)strlen(cp) >= max_b_len)
b[max_b_len - 1] = '\0';
return b;
}
ddpt-0.94/lib/BSD_LICENSE 0000644 0001750 0001750 00000002752 11346470114 013647 0 ustar dougg dougg /*
* Copyright (c) 1999-2010 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.
*/
ddpt-0.94/lib/sg_cmds_basic2.c 0000644 0001750 0001750 00000110610 12176051475 015160 0 ustar dougg dougg /*
* Copyright (c) 1999-2013 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.
*/
/*
* CONTENTS
* Some SCSI commands are executed in many contexts and hence began
* to appear in several sg3_utils utilities. This files centralizes
* some of the low level command execution code. In most cases the
* interpretation of the command response is left to the each
* utility.
*/
#include
#include
#include
#include
#include "sg_lib.h"
#include "sg_cmds_basic.h"
#include "sg_pt.h"
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#define SENSE_BUFF_LEN 64 /* Arbitrary, could be larger */
#define EBUFF_SZ 256
#define DEF_PT_TIMEOUT 60 /* 60 seconds */
#define START_PT_TIMEOUT 120 /* 120 seconds == 2 minutes */
#define LONG_PT_TIMEOUT 7200 /* 7,200 seconds == 120 minutes */
#define SYNCHRONIZE_CACHE_CMD 0x35
#define SYNCHRONIZE_CACHE_CMDLEN 10
#define SERVICE_ACTION_IN_16_CMD 0x9e
#define SERVICE_ACTION_IN_16_CMDLEN 16
#define READ_CAPACITY_16_SA 0x10
#define READ_CAPACITY_10_CMD 0x25
#define READ_CAPACITY_10_CMDLEN 10
#define MODE_SENSE6_CMD 0x1a
#define MODE_SENSE6_CMDLEN 6
#define MODE_SENSE10_CMD 0x5a
#define MODE_SENSE10_CMDLEN 10
#define MODE_SELECT6_CMD 0x15
#define MODE_SELECT6_CMDLEN 6
#define MODE_SELECT10_CMD 0x55
#define MODE_SELECT10_CMDLEN 10
#define LOG_SENSE_CMD 0x4d
#define LOG_SENSE_CMDLEN 10
#define LOG_SELECT_CMD 0x4c
#define LOG_SELECT_CMDLEN 10
#define START_STOP_CMD 0x1b
#define START_STOP_CMDLEN 6
#define PREVENT_ALLOW_CMD 0x1e
#define PREVENT_ALLOW_CMDLEN 6
#define MODE6_RESP_HDR_LEN 4
#define MODE10_RESP_HDR_LEN 8
#define MODE_RESP_ARB_LEN 1024
#define INQUIRY_RESP_INITIAL_LEN 36
/* Invokes a SCSI SYNCHRONIZE CACHE (10) command. Return of 0 -> success,
* SG_LIB_CAT_UNIT_ATTENTION -> repeat,
* SG_LIB_CAT_INVALID_OP -> cdb not supported,
* SG_LIB_CAT_ILLEGAL_REQ -> bad field in cdb, SG_LIB_CAT_ABORTED_COMMAND,
* SG_LIB_CAT_NOT_READY -> device not ready, -1 -> other failure */
int
sg_ll_sync_cache_10(int sg_fd, int sync_nv, int immed, int group,
unsigned int lba, unsigned int count, int noisy,
int verbose)
{
int res, ret, k, sense_cat;
unsigned char scCmdBlk[SYNCHRONIZE_CACHE_CMDLEN] =
{SYNCHRONIZE_CACHE_CMD, 0, 0, 0, 0, 0, 0, 0, 0, 0};
unsigned char sense_b[SENSE_BUFF_LEN];
struct sg_pt_base * ptvp;
if (sync_nv)
scCmdBlk[1] |= 4;
if (immed)
scCmdBlk[1] |= 2;
scCmdBlk[2] = (lba >> 24) & 0xff;
scCmdBlk[3] = (lba >> 16) & 0xff;
scCmdBlk[4] = (lba >> 8) & 0xff;
scCmdBlk[5] = lba & 0xff;
scCmdBlk[6] = group & 0x1f;
if (NULL == sg_warnings_strm)
sg_warnings_strm = stderr;
if (count > 0xffff) {
fprintf(sg_warnings_strm, "count too big\n");
return -1;
}
scCmdBlk[7] = (count >> 8) & 0xff;
scCmdBlk[8] = count & 0xff;
if (verbose) {
fprintf(sg_warnings_strm, " synchronize cache(10) cdb: ");
for (k = 0; k < SYNCHRONIZE_CACHE_CMDLEN; ++k)
fprintf(sg_warnings_strm, "%02x ", scCmdBlk[k]);
fprintf(sg_warnings_strm, "\n");
}
ptvp = construct_scsi_pt_obj();
if (NULL == ptvp) {
fprintf(sg_warnings_strm, "synchronize cache(10): out of memory\n");
return -1;
}
set_scsi_pt_cdb(ptvp, scCmdBlk, sizeof(scCmdBlk));
set_scsi_pt_sense(ptvp, sense_b, sizeof(sense_b));
res = do_scsi_pt(ptvp, sg_fd, DEF_PT_TIMEOUT, verbose);
ret = sg_cmds_process_resp(ptvp, "synchronize cache(10)", res, 0,
sense_b, noisy, verbose, &sense_cat);
if (-1 == ret)
;
else if (-2 == ret) {
switch (sense_cat) {
case SG_LIB_CAT_NOT_READY:
case SG_LIB_CAT_UNIT_ATTENTION:
case SG_LIB_CAT_INVALID_OP:
case SG_LIB_CAT_ILLEGAL_REQ:
case SG_LIB_CAT_ABORTED_COMMAND:
ret = sense_cat;
break;
case SG_LIB_CAT_RECOVERED:
case SG_LIB_CAT_NO_SENSE:
ret = 0;
break;
default:
ret = -1;
break;
}
} else
ret = 0;
destruct_scsi_pt_obj(ptvp);
return ret;
}
/* Invokes a SCSI READ CAPACITY (16) command. Returns 0 -> success,
* SG_LIB_CAT_UNIT_ATTENTION -> media changed??, SG_LIB_CAT_INVALID_OP
* -> cdb not supported, SG_LIB_CAT_IlLEGAL_REQ -> bad field in cdb,
* SG_LIB_CAT_ABORTED_COMMAND, SG_LIB_CAT_NOT_READY -> device not ready,
* -1 -> other failure */
int
sg_ll_readcap_16(int sg_fd, int pmi, uint64_t llba, void * resp,
int mx_resp_len, int noisy, int verbose)
{
int k, ret, res, sense_cat;
unsigned char rcCmdBlk[SERVICE_ACTION_IN_16_CMDLEN] =
{SERVICE_ACTION_IN_16_CMD, READ_CAPACITY_16_SA,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
unsigned char sense_b[SENSE_BUFF_LEN];
struct sg_pt_base * ptvp;
if (pmi) { /* lbs only valid when pmi set */
rcCmdBlk[14] |= 1;
rcCmdBlk[2] = (llba >> 56) & 0xff;
rcCmdBlk[3] = (llba >> 48) & 0xff;
rcCmdBlk[4] = (llba >> 40) & 0xff;
rcCmdBlk[5] = (llba >> 32) & 0xff;
rcCmdBlk[6] = (llba >> 24) & 0xff;
rcCmdBlk[7] = (llba >> 16) & 0xff;
rcCmdBlk[8] = (llba >> 8) & 0xff;
rcCmdBlk[9] = llba & 0xff;
}
/* Allocation length, no guidance in SBC-2 rev 15b */
rcCmdBlk[10] = (mx_resp_len >> 24) & 0xff;
rcCmdBlk[11] = (mx_resp_len >> 16) & 0xff;
rcCmdBlk[12] = (mx_resp_len >> 8) & 0xff;
rcCmdBlk[13] = mx_resp_len & 0xff;
if (NULL == sg_warnings_strm)
sg_warnings_strm = stderr;
if (verbose) {
fprintf(sg_warnings_strm, " read capacity (16) cdb: ");
for (k = 0; k < SERVICE_ACTION_IN_16_CMDLEN; ++k)
fprintf(sg_warnings_strm, "%02x ", rcCmdBlk[k]);
fprintf(sg_warnings_strm, "\n");
}
ptvp = construct_scsi_pt_obj();
if (NULL == ptvp) {
fprintf(sg_warnings_strm, "read capacity (16): out of memory\n");
return -1;
}
set_scsi_pt_cdb(ptvp, rcCmdBlk, sizeof(rcCmdBlk));
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, sg_fd, DEF_PT_TIMEOUT, verbose);
ret = sg_cmds_process_resp(ptvp, "read capacity (16)", res, mx_resp_len,
sense_b, noisy, verbose, &sense_cat);
if (-1 == ret)
;
else if (-2 == ret) {
switch (sense_cat) {
case SG_LIB_CAT_NOT_READY:
case SG_LIB_CAT_UNIT_ATTENTION:
case SG_LIB_CAT_INVALID_OP:
case SG_LIB_CAT_ILLEGAL_REQ:
case SG_LIB_CAT_ABORTED_COMMAND:
ret = sense_cat;
break;
case SG_LIB_CAT_RECOVERED:
case SG_LIB_CAT_NO_SENSE:
ret = 0;
break;
default:
ret = -1;
break;
}
} else
ret = 0;
destruct_scsi_pt_obj(ptvp);
return ret;
}
/* Invokes a SCSI READ CAPACITY (10) command. Returns 0 -> success,
* SG_LIB_CAT_UNIT_ATTENTION -> media changed??, SG_LIB_CAT_INVALID_OP
* -> cdb not supported, SG_LIB_CAT_IlLEGAL_REQ -> bad field in cdb,
* SG_LIB_CAT_ABORTED_COMMAND, SG_LIB_CAT_NOT_READY -> device not ready,
* -1 -> other failure */
int
sg_ll_readcap_10(int sg_fd, int pmi, unsigned int lba, void * resp,
int mx_resp_len, int noisy, int verbose)
{
int k, ret, res, sense_cat;
unsigned char rcCmdBlk[READ_CAPACITY_10_CMDLEN] =
{READ_CAPACITY_10_CMD, 0, 0, 0, 0, 0, 0, 0, 0, 0};
unsigned char sense_b[SENSE_BUFF_LEN];
struct sg_pt_base * ptvp;
if (pmi) { /* lbs only valid when pmi set */
rcCmdBlk[8] |= 1;
rcCmdBlk[2] = (lba >> 24) & 0xff;
rcCmdBlk[3] = (lba >> 16) & 0xff;
rcCmdBlk[4] = (lba >> 8) & 0xff;
rcCmdBlk[5] = lba & 0xff;
}
if (NULL == sg_warnings_strm)
sg_warnings_strm = stderr;
if (verbose) {
fprintf(sg_warnings_strm, " read capacity (10) cdb: ");
for (k = 0; k < READ_CAPACITY_10_CMDLEN; ++k)
fprintf(sg_warnings_strm, "%02x ", rcCmdBlk[k]);
fprintf(sg_warnings_strm, "\n");
}
ptvp = construct_scsi_pt_obj();
if (NULL == ptvp) {
fprintf(sg_warnings_strm, "read capacity (10): out of memory\n");
return -1;
}
set_scsi_pt_cdb(ptvp, rcCmdBlk, sizeof(rcCmdBlk));
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, sg_fd, DEF_PT_TIMEOUT, verbose);
ret = sg_cmds_process_resp(ptvp, "read capacity (10)", res, mx_resp_len,
sense_b, noisy, verbose, &sense_cat);
if (-1 == ret)
;
else if (-2 == ret) {
switch (sense_cat) {
case SG_LIB_CAT_NOT_READY:
case SG_LIB_CAT_UNIT_ATTENTION:
case SG_LIB_CAT_INVALID_OP:
case SG_LIB_CAT_ILLEGAL_REQ:
case SG_LIB_CAT_ABORTED_COMMAND:
ret = sense_cat;
break;
case SG_LIB_CAT_RECOVERED:
case SG_LIB_CAT_NO_SENSE:
ret = 0;
break;
default:
ret = -1;
break;
}
} else
ret = 0;
destruct_scsi_pt_obj(ptvp);
return ret;
}
/* Invokes a SCSI MODE SENSE (6) command. Return of 0 -> success,
* SG_LIB_CAT_INVALID_OP -> invalid opcode, SG_LIB_CAT_ILLEGAL_REQ ->
* bad field in cdb, * SG_LIB_CAT_NOT_READY -> device not ready,
* SG_LIB_CAT_ABORTED_COMMAND, SG_LIB_CAT_UNIT_ATTENTION,
* -1 -> other failure */
int
sg_ll_mode_sense6(int sg_fd, int dbd, int pc, int pg_code, int sub_pg_code,
void * resp, int mx_resp_len, int noisy, int verbose)
{
int res, ret, k, sense_cat;
unsigned char modesCmdBlk[MODE_SENSE6_CMDLEN] =
{MODE_SENSE6_CMD, 0, 0, 0, 0, 0};
unsigned char sense_b[SENSE_BUFF_LEN];
struct sg_pt_base * ptvp;
modesCmdBlk[1] = (unsigned char)(dbd ? 0x8 : 0);
modesCmdBlk[2] = (unsigned char)(((pc << 6) & 0xc0) | (pg_code & 0x3f));
modesCmdBlk[3] = (unsigned char)(sub_pg_code & 0xff);
modesCmdBlk[4] = (unsigned char)(mx_resp_len & 0xff);
if (NULL == sg_warnings_strm)
sg_warnings_strm = stderr;
if (mx_resp_len > 0xff) {
fprintf(sg_warnings_strm, "mx_resp_len too big\n");
return -1;
}
if (verbose) {
fprintf(sg_warnings_strm, " mode sense (6) cdb: ");
for (k = 0; k < MODE_SENSE6_CMDLEN; ++k)
fprintf(sg_warnings_strm, "%02x ", modesCmdBlk[k]);
fprintf(sg_warnings_strm, "\n");
}
ptvp = construct_scsi_pt_obj();
if (NULL == ptvp) {
fprintf(sg_warnings_strm, "mode sense (6): out of memory\n");
return -1;
}
set_scsi_pt_cdb(ptvp, modesCmdBlk, sizeof(modesCmdBlk));
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, sg_fd, DEF_PT_TIMEOUT, verbose);
ret = sg_cmds_process_resp(ptvp, "mode sense (6)", res, mx_resp_len,
sense_b, noisy, verbose, &sense_cat);
if (-1 == ret)
;
else if (-2 == ret) {
switch (sense_cat) {
case SG_LIB_CAT_NOT_READY:
case SG_LIB_CAT_INVALID_OP:
case SG_LIB_CAT_ILLEGAL_REQ:
case SG_LIB_CAT_UNIT_ATTENTION:
case SG_LIB_CAT_ABORTED_COMMAND:
ret = sense_cat;
break;
case SG_LIB_CAT_RECOVERED:
case SG_LIB_CAT_NO_SENSE:
ret = 0;
break;
default:
ret = -1;
break;
}
} else {
if ((verbose > 2) && (ret > 0)) {
fprintf(sg_warnings_strm, " mode sense (6): response%s\n",
(ret > 256 ? ", first 256 bytes" : ""));
dStrHexErr((const char *)resp, (ret > 256 ? 256 : ret), -1);
}
ret = 0;
}
destruct_scsi_pt_obj(ptvp);
return ret;
}
/* Invokes a SCSI MODE SENSE (10) command. Return of 0 -> success,
* SG_LIB_CAT_INVALID_OP -> invalid opcode, SG_LIB_CAT_ILLEGAL_REQ ->
* bad field in cdb, * SG_LIB_CAT_NOT_READY -> device not ready,
* SG_LIB_CAT_ABORTED_COMMAND, SG_LIB_CAT_UNIT_ATTENTION,
* -1 -> other failure */
int
sg_ll_mode_sense10(int sg_fd, int llbaa, int dbd, int pc, int pg_code,
int sub_pg_code, void * resp, int mx_resp_len,
int noisy, int verbose)
{
int res, ret, k, sense_cat;
unsigned char modesCmdBlk[MODE_SENSE10_CMDLEN] =
{MODE_SENSE10_CMD, 0, 0, 0, 0, 0, 0, 0, 0, 0};
unsigned char sense_b[SENSE_BUFF_LEN];
struct sg_pt_base * ptvp;
modesCmdBlk[1] = (unsigned char)((dbd ? 0x8 : 0) | (llbaa ? 0x10 : 0));
modesCmdBlk[2] = (unsigned char)(((pc << 6) & 0xc0) | (pg_code & 0x3f));
modesCmdBlk[3] = (unsigned char)(sub_pg_code & 0xff);
modesCmdBlk[7] = (unsigned char)((mx_resp_len >> 8) & 0xff);
modesCmdBlk[8] = (unsigned char)(mx_resp_len & 0xff);
if (NULL == sg_warnings_strm)
sg_warnings_strm = stderr;
if (mx_resp_len > 0xffff) {
fprintf(sg_warnings_strm, "mx_resp_len too big\n");
return -1;
}
if (verbose) {
fprintf(sg_warnings_strm, " mode sense (10) cdb: ");
for (k = 0; k < MODE_SENSE10_CMDLEN; ++k)
fprintf(sg_warnings_strm, "%02x ", modesCmdBlk[k]);
fprintf(sg_warnings_strm, "\n");
}
ptvp = construct_scsi_pt_obj();
if (NULL == ptvp) {
fprintf(sg_warnings_strm, "mode sense (10): out of memory\n");
return -1;
}
set_scsi_pt_cdb(ptvp, modesCmdBlk, sizeof(modesCmdBlk));
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, sg_fd, DEF_PT_TIMEOUT, verbose);
ret = sg_cmds_process_resp(ptvp, "mode sense (10)", res, mx_resp_len,
sense_b, noisy, verbose, &sense_cat);
if (-1 == ret)
;
else if (-2 == ret) {
switch (sense_cat) {
case SG_LIB_CAT_NOT_READY:
case SG_LIB_CAT_INVALID_OP:
case SG_LIB_CAT_ILLEGAL_REQ:
case SG_LIB_CAT_UNIT_ATTENTION:
case SG_LIB_CAT_ABORTED_COMMAND:
ret = sense_cat;
break;
case SG_LIB_CAT_RECOVERED:
case SG_LIB_CAT_NO_SENSE:
ret = 0;
break;
default:
ret = -1;
break;
}
} else {
if ((verbose > 2) && (ret > 0)) {
fprintf(sg_warnings_strm, " mode sense (10): response%s\n",
(ret > 256 ? ", first 256 bytes" : ""));
dStrHexErr((const char *)resp, (ret > 256 ? 256 : ret), -1);
}
ret = 0;
}
destruct_scsi_pt_obj(ptvp);
return ret;
}
/* Invokes a SCSI MODE SELECT (6) command. Return of 0 -> success,
* SG_LIB_CAT_INVALID_OP -> invalid opcode, SG_LIB_CAT_ILLEGAL_REQ ->
* bad field in cdb, * SG_LIB_CAT_NOT_READY -> device not ready,
* SG_LIB_CAT_ABORTED_COMMAND, SG_LIB_CAT_UNIT_ATTENTION,
* -1 -> other failure */
int
sg_ll_mode_select6(int sg_fd, int pf, int sp, void * paramp, int param_len,
int noisy, int verbose)
{
int res, ret, k, sense_cat;
unsigned char modesCmdBlk[MODE_SELECT6_CMDLEN] =
{MODE_SELECT6_CMD, 0, 0, 0, 0, 0};
unsigned char sense_b[SENSE_BUFF_LEN];
struct sg_pt_base * ptvp;
modesCmdBlk[1] = (unsigned char)(((pf << 4) & 0x10) | (sp & 0x1));
modesCmdBlk[4] = (unsigned char)(param_len & 0xff);
if (NULL == sg_warnings_strm)
sg_warnings_strm = stderr;
if (param_len > 0xff) {
fprintf(sg_warnings_strm, "mode select (6): param_len too big\n");
return -1;
}
if (verbose) {
fprintf(sg_warnings_strm, " mode select (6) cdb: ");
for (k = 0; k < MODE_SELECT6_CMDLEN; ++k)
fprintf(sg_warnings_strm, "%02x ", modesCmdBlk[k]);
fprintf(sg_warnings_strm, "\n");
}
if (verbose > 1) {
fprintf(sg_warnings_strm, " mode select (6) parameter list\n");
dStrHexErr((const char *)paramp, param_len, -1);
}
ptvp = construct_scsi_pt_obj();
if (NULL == ptvp) {
fprintf(sg_warnings_strm, "mode select (6): out of memory\n");
return -1;
}
set_scsi_pt_cdb(ptvp, modesCmdBlk, sizeof(modesCmdBlk));
set_scsi_pt_sense(ptvp, sense_b, sizeof(sense_b));
set_scsi_pt_data_out(ptvp, (unsigned char *)paramp, param_len);
res = do_scsi_pt(ptvp, sg_fd, DEF_PT_TIMEOUT, verbose);
ret = sg_cmds_process_resp(ptvp, "mode select (6)", res, 0, sense_b,
noisy, verbose, &sense_cat);
if (-1 == ret)
;
else if (-2 == ret) {
switch (sense_cat) {
case SG_LIB_CAT_NOT_READY:
case SG_LIB_CAT_INVALID_OP:
case SG_LIB_CAT_ILLEGAL_REQ:
case SG_LIB_CAT_UNIT_ATTENTION:
case SG_LIB_CAT_ABORTED_COMMAND:
ret = sense_cat;
break;
case SG_LIB_CAT_RECOVERED:
case SG_LIB_CAT_NO_SENSE:
ret = 0;
break;
default:
ret = -1;
break;
}
} else
ret = 0;
destruct_scsi_pt_obj(ptvp);
return ret;
}
/* Invokes a SCSI MODE SELECT (10) command. Return of 0 -> success,
* SG_LIB_CAT_INVALID_OP -> invalid opcode, SG_LIB_CAT_ILLEGAL_REQ ->
* bad field in cdb, * SG_LIB_CAT_NOT_READY -> device not ready,
* SG_LIB_CAT_ABORTED_COMMAND, SG_LIB_CAT_UNIT_ATTENTION,
* -1 -> other failure */
int
sg_ll_mode_select10(int sg_fd, int pf, int sp, void * paramp, int param_len,
int noisy, int verbose)
{
int res, ret, k, sense_cat;
unsigned char modesCmdBlk[MODE_SELECT10_CMDLEN] =
{MODE_SELECT10_CMD, 0, 0, 0, 0, 0, 0, 0, 0, 0};
unsigned char sense_b[SENSE_BUFF_LEN];
struct sg_pt_base * ptvp;
modesCmdBlk[1] = (unsigned char)(((pf << 4) & 0x10) | (sp & 0x1));
modesCmdBlk[7] = (unsigned char)((param_len >> 8) & 0xff);
modesCmdBlk[8] = (unsigned char)(param_len & 0xff);
if (NULL == sg_warnings_strm)
sg_warnings_strm = stderr;
if (param_len > 0xffff) {
fprintf(sg_warnings_strm, "mode select (10): param_len too big\n");
return -1;
}
if (verbose) {
fprintf(sg_warnings_strm, " mode select (10) cdb: ");
for (k = 0; k < MODE_SELECT10_CMDLEN; ++k)
fprintf(sg_warnings_strm, "%02x ", modesCmdBlk[k]);
fprintf(sg_warnings_strm, "\n");
}
if (verbose > 1) {
fprintf(sg_warnings_strm, " mode select (10) parameter list\n");
dStrHexErr((const char *)paramp, param_len, -1);
}
ptvp = construct_scsi_pt_obj();
if (NULL == ptvp) {
fprintf(sg_warnings_strm, "mode select (10): out of memory\n");
return -1;
}
set_scsi_pt_cdb(ptvp, modesCmdBlk, sizeof(modesCmdBlk));
set_scsi_pt_sense(ptvp, sense_b, sizeof(sense_b));
set_scsi_pt_data_out(ptvp, (unsigned char *)paramp, param_len);
res = do_scsi_pt(ptvp, sg_fd, DEF_PT_TIMEOUT, verbose);
ret = sg_cmds_process_resp(ptvp, "mode select (10)", res, 0, sense_b,
noisy, verbose, &sense_cat);
if (-1 == ret)
;
else if (-2 == ret) {
switch (sense_cat) {
case SG_LIB_CAT_NOT_READY:
case SG_LIB_CAT_INVALID_OP:
case SG_LIB_CAT_ILLEGAL_REQ:
case SG_LIB_CAT_UNIT_ATTENTION:
case SG_LIB_CAT_ABORTED_COMMAND:
ret = sense_cat;
break;
case SG_LIB_CAT_RECOVERED:
case SG_LIB_CAT_NO_SENSE:
ret = 0;
break;
default:
ret = -1;
break;
}
} else
ret = 0;
destruct_scsi_pt_obj(ptvp);
return ret;
}
/* MODE SENSE commands yield a response that has block descriptors followed
* by mode pages. In most cases users are interested in the first mode page.
* This function returns the (byte) offset of the start of the first mode
* page. Set mode_sense_6 to 1 for MODE SENSE (6) and 0 for MODE SENSE (10).
* Returns >= 0 is successful or -1 if failure. If there is a failure
* a message is written to err_buff. */
int
sg_mode_page_offset(const unsigned char * resp, int resp_len,
int mode_sense_6, char * err_buff, int err_buff_len)
{
int bd_len;
int calc_len;
int offset;
if ((NULL == resp) || (resp_len < 4) ||
((! mode_sense_6) && (resp_len < 8))) {
if (err_buff_len > 0)
snprintf(err_buff, err_buff_len, "given response length too "
"short: %d\n", resp_len);
return -1;
}
if (mode_sense_6) {
calc_len = resp[0] + 1;
bd_len = resp[3];
offset = bd_len + MODE6_RESP_HDR_LEN;
} else {
calc_len = (resp[0] << 8) + resp[1] + 2;
bd_len = (resp[6] << 8) + resp[7];
/* LongLBA doesn't change this calculation */
offset = bd_len + MODE10_RESP_HDR_LEN;
}
if ((offset + 2) > resp_len) {
if (err_buff_len > 0)
snprintf(err_buff, err_buff_len, "given response length "
"too small, offset=%d given_len=%d bd_len=%d\n",
offset, resp_len, bd_len);
offset = -1;
} else if ((offset + 2) > calc_len) {
if (err_buff_len > 0)
snprintf(err_buff, err_buff_len, "calculated response "
"length too small, offset=%d calc_len=%d bd_len=%d\n",
offset, calc_len, bd_len);
offset = -1;
}
return offset;
}
/* Fetches current, changeable, default and/or saveable modes pages as
* indicated by pcontrol_arr for given pg_code and sub_pg_code. If
* mode6==0 then use MODE SENSE (10) else use MODE SENSE (6). If
* flexible set and mode data length seems wrong then try and
* fix (compensating hack for bad device or driver). pcontrol_arr
* should have 4 elements for output of current, changeable, default
* and saved values respectively. Each element should be NULL or
* at least mx_mpage_len bytes long.
* Return of 0 -> overall success, SG_LIB_CAT_INVALID_OP -> invalid opcode,
* SG_LIB_CAT_ILLEGAL_REQ -> bad field in cdb, SG_LIB_CAT_UNIT_ATTENTION,
* SG_LIB_CAT_NOT_READY -> device not ready,
* SG_LIB_CAT_MALFORMED -> bad response, -1 -> other failure.
* If success_mask pointer is not NULL then first zeros it. Then set bits
* 0, 1, 2 and/or 3 if the current, changeable, default and saved values
* respectively have been fetched. If error on current page
* then stops and returns that error; otherwise continues if an error is
* detected but returns the first error encountered. */
int
sg_get_mode_page_controls(int sg_fd, int mode6, int pg_code, int sub_pg_code,
int dbd, int flexible, int mx_mpage_len,
int * success_mask, void * pcontrol_arr[],
int * reported_len, int verbose)
{
int k, n, res, offset, calc_len, xfer_len, resp_mode6;
unsigned char buff[MODE_RESP_ARB_LEN];
char ebuff[EBUFF_SZ];
int first_err = 0;
if (success_mask)
*success_mask = 0;
if (reported_len)
*reported_len = 0;
if (mx_mpage_len < 4)
return 0;
if (NULL == sg_warnings_strm)
sg_warnings_strm = stderr;
memset(ebuff, 0, sizeof(ebuff));
/* first try to find length of current page response */
memset(buff, 0, MODE10_RESP_HDR_LEN);
if (mode6) /* want first 8 bytes just in case */
res = sg_ll_mode_sense6(sg_fd, dbd, 0 /* pc */, pg_code,
sub_pg_code, buff, MODE10_RESP_HDR_LEN, 1,
verbose);
else
res = sg_ll_mode_sense10(sg_fd, 0 /* llbaa */, dbd,
0 /* pc */, pg_code, sub_pg_code, buff,
MODE10_RESP_HDR_LEN, 1, verbose);
if (0 != res)
return res;
n = buff[0];
if (reported_len)
*reported_len = mode6 ? (n + 1) : ((n << 8) + buff[1] + 2);
resp_mode6 = mode6;
if (flexible) {
if (mode6 && (n < 3)) {
resp_mode6 = 0;
if (verbose)
fprintf(sg_warnings_strm, ">>> msense(6) but resp[0]=%d so "
"try msense(10) response processing\n", n);
}
if ((0 == mode6) && (n > 5)) {
if ((n > 11) && (0 == (n % 2)) && (0 == buff[4]) &&
(0 == buff[5]) && (0 == buff[6])) {
buff[1] = n;
buff[0] = 0;
if (verbose)
fprintf(sg_warnings_strm, ">>> msense(10) but resp[0]=%d "
"and not msense(6) response so fix length\n", n);
} else
resp_mode6 = 1;
}
}
if (verbose && (resp_mode6 != mode6))
fprintf(sg_warnings_strm, ">>> msense(%d) but resp[0]=%d "
"so switch response processing\n", (mode6 ? 6 : 10),
buff[0]);
calc_len = resp_mode6 ? (buff[0] + 1) : ((buff[0] << 8) + buff[1] + 2);
if (calc_len > MODE_RESP_ARB_LEN)
calc_len = MODE_RESP_ARB_LEN;
offset = sg_mode_page_offset(buff, calc_len, resp_mode6,
ebuff, EBUFF_SZ);
if (offset < 0) {
if (('\0' != ebuff[0]) && (verbose > 0))
fprintf(sg_warnings_strm, "sg_get_mode_page_controls: %s\n",
ebuff);
return SG_LIB_CAT_MALFORMED;
}
xfer_len = calc_len - offset;
if (xfer_len > mx_mpage_len)
xfer_len = mx_mpage_len;
for (k = 0; k < 4; ++k) {
if (NULL == pcontrol_arr[k])
continue;
memset(pcontrol_arr[k], 0, mx_mpage_len);
if (mode6)
res = sg_ll_mode_sense6(sg_fd, dbd, k /* pc */,
pg_code, sub_pg_code, buff,
calc_len, 1, verbose);
else
res = sg_ll_mode_sense10(sg_fd, 0 /* llbaa */, dbd,
k /* pc */, pg_code, sub_pg_code,
buff, calc_len, 1, verbose);
if (0 != res) {
if (0 == first_err)
first_err = res;
if (0 == k)
break; /* if problem on current page, it won't improve */
else
continue;
}
if (xfer_len > 0)
memcpy(pcontrol_arr[k], buff + offset, xfer_len);
if (success_mask)
*success_mask |= (1 << k);
}
return first_err;
}
/* Invokes a SCSI LOG SENSE command. Return of 0 -> success,
* SG_LIB_CAT_INVALID_OP -> Log Sense not supported,
* SG_LIB_CAT_ILLEGAL_REQ -> bad field in cdb, SG_LIB_CAT_UNIT_ATTENTION,
* SG_LIB_CAT_NOT_READY -> device not ready, SG_LIB_CAT_ABORTED_COMMAND,
* -1 -> other failure */
int
sg_ll_log_sense(int sg_fd, int ppc, int sp, int pc, int pg_code,
int subpg_code, int paramp, unsigned char * resp,
int mx_resp_len, int noisy, int verbose)
{
int res, ret, k, sense_cat;
unsigned char logsCmdBlk[LOG_SENSE_CMDLEN] =
{LOG_SENSE_CMD, 0, 0, 0, 0, 0, 0, 0, 0, 0};
unsigned char sense_b[SENSE_BUFF_LEN];
struct sg_pt_base * ptvp;
if (NULL == sg_warnings_strm)
sg_warnings_strm = stderr;
if (mx_resp_len > 0xffff) {
fprintf(sg_warnings_strm, "mx_resp_len too big\n");
return -1;
}
logsCmdBlk[1] = (unsigned char)((ppc ? 2 : 0) | (sp ? 1 : 0));
logsCmdBlk[2] = (unsigned char)(((pc << 6) & 0xc0) | (pg_code & 0x3f));
logsCmdBlk[3] = (unsigned char)(subpg_code & 0xff);
logsCmdBlk[5] = (unsigned char)((paramp >> 8) & 0xff);
logsCmdBlk[6] = (unsigned char)(paramp & 0xff);
logsCmdBlk[7] = (unsigned char)((mx_resp_len >> 8) & 0xff);
logsCmdBlk[8] = (unsigned char)(mx_resp_len & 0xff);
if (verbose) {
fprintf(sg_warnings_strm, " log sense cdb: ");
for (k = 0; k < LOG_SENSE_CMDLEN; ++k)
fprintf(sg_warnings_strm, "%02x ", logsCmdBlk[k]);
fprintf(sg_warnings_strm, "\n");
}
ptvp = construct_scsi_pt_obj();
if (NULL == ptvp) {
fprintf(sg_warnings_strm, "log sense: out of memory\n");
return -1;
}
set_scsi_pt_cdb(ptvp, logsCmdBlk, sizeof(logsCmdBlk));
set_scsi_pt_sense(ptvp, sense_b, sizeof(sense_b));
set_scsi_pt_data_in(ptvp, resp, mx_resp_len);
res = do_scsi_pt(ptvp, sg_fd, DEF_PT_TIMEOUT, verbose);
ret = sg_cmds_process_resp(ptvp, "log sense", res, mx_resp_len,
sense_b, noisy, verbose, &sense_cat);
if (-1 == ret)
;
else if (-2 == ret) {
switch (sense_cat) {
case SG_LIB_CAT_NOT_READY:
case SG_LIB_CAT_INVALID_OP:
case SG_LIB_CAT_ILLEGAL_REQ:
case SG_LIB_CAT_UNIT_ATTENTION:
case SG_LIB_CAT_ABORTED_COMMAND:
ret = sense_cat;
break;
case SG_LIB_CAT_RECOVERED:
case SG_LIB_CAT_NO_SENSE:
ret = 0;
break;
default:
ret = -1;
break;
}
} else {
if ((mx_resp_len > 3) && (ret < 4)) {
/* resid indicates LOG SENSE response length bad, so zero it */
resp[2] = 0;
resp[3] = 0;
}
ret = 0;
}
destruct_scsi_pt_obj(ptvp);
return ret;
}
/* Invokes a SCSI LOG SELECT command. Return of 0 -> success,
* SG_LIB_CAT_INVALID_OP -> Log Select not supported,
* SG_LIB_CAT_ILLEGAL_REQ -> bad field in cdb, SG_LIB_CAT_UNIT_ATTENTION,
* SG_LIB_CAT_NOT_READY -> device not ready, SG_LIB_CAT_ABORTED_COMMAND,
* -1 -> other failure */
int
sg_ll_log_select(int sg_fd, int pcr, int sp, int pc, int pg_code,
int subpg_code, unsigned char * paramp, int param_len,
int noisy, int verbose)
{
int res, ret, k, sense_cat;
unsigned char logsCmdBlk[LOG_SELECT_CMDLEN] =
{LOG_SELECT_CMD, 0, 0, 0, 0, 0, 0, 0, 0, 0};
unsigned char sense_b[SENSE_BUFF_LEN];
struct sg_pt_base * ptvp;
if (NULL == sg_warnings_strm)
sg_warnings_strm = stderr;
if (param_len > 0xffff) {
fprintf(sg_warnings_strm, "log select: param_len too big\n");
return -1;
}
logsCmdBlk[1] = (unsigned char)((pcr ? 2 : 0) | (sp ? 1 : 0));
logsCmdBlk[2] = (unsigned char)(((pc << 6) & 0xc0) | (pg_code & 0x3f));
logsCmdBlk[3] = (unsigned char)(subpg_code & 0xff);
logsCmdBlk[7] = (unsigned char)((param_len >> 8) & 0xff);
logsCmdBlk[8] = (unsigned char)(param_len & 0xff);
if (verbose) {
fprintf(sg_warnings_strm, " log select cdb: ");
for (k = 0; k < LOG_SELECT_CMDLEN; ++k)
fprintf(sg_warnings_strm, "%02x ", logsCmdBlk[k]);
fprintf(sg_warnings_strm, "\n");
}
if ((verbose > 1) && (param_len > 0)) {
fprintf(sg_warnings_strm, " log select parameter list\n");
dStrHexErr((const char *)paramp, param_len, -1);
}
ptvp = construct_scsi_pt_obj();
if (NULL == ptvp) {
fprintf(sg_warnings_strm, "log select: out of memory\n");
return -1;
}
set_scsi_pt_cdb(ptvp, logsCmdBlk, sizeof(logsCmdBlk));
set_scsi_pt_sense(ptvp, sense_b, sizeof(sense_b));
set_scsi_pt_data_out(ptvp, paramp, param_len);
res = do_scsi_pt(ptvp, sg_fd, DEF_PT_TIMEOUT, verbose);
ret = sg_cmds_process_resp(ptvp, "log select", res, 0, sense_b,
noisy, verbose, &sense_cat);
if (-1 == ret)
;
else if (-2 == ret) {
switch (sense_cat) {
case SG_LIB_CAT_NOT_READY:
case SG_LIB_CAT_INVALID_OP:
case SG_LIB_CAT_ILLEGAL_REQ:
case SG_LIB_CAT_UNIT_ATTENTION:
case SG_LIB_CAT_ABORTED_COMMAND:
ret = sense_cat;
break;
case SG_LIB_CAT_RECOVERED:
case SG_LIB_CAT_NO_SENSE:
ret = 0;
break;
default:
ret = -1;
break;
}
} else
ret = 0;
destruct_scsi_pt_obj(ptvp);
return ret;
}
/* Invokes a SCSI START STOP UNIT command (SBC + MMC).
* Return of 0 -> success,
* SG_LIB_CAT_INVALID_OP -> Start stop unit not supported,
* SG_LIB_CAT_ILLEGAL_REQ -> bad field in cdb, SG_LIB_CAT_UNIT_ATTENTION,
* SG_LIB_CAT_NOT_READY -> device not ready, SG_LIB_CAT_ABORTED_COMMAND,
* -1 -> other failure
* SBC-3 and MMC partially overlap on the power_condition_modifier(sbc) and
* format_layer_number(mmc) fields. They also overlap on the noflush(sbc)
* and fl(mmc) one bit field. This is the cause of the awkardly named
* pc_mod__fl_num and noflush__fl arguments to this function.
* */
int
sg_ll_start_stop_unit(int sg_fd, int immed, int pc_mod__fl_num,
int power_cond, int noflush__fl, int loej, int start,
int noisy, int verbose)
{
unsigned char ssuBlk[START_STOP_CMDLEN] = {START_STOP_CMD, 0, 0, 0, 0, 0};
unsigned char sense_b[SENSE_BUFF_LEN];
int k, res, ret, sense_cat;
struct sg_pt_base * ptvp;
ssuBlk[1] = immed & 1;
ssuBlk[3] = pc_mod__fl_num & 0xf; /* bits 2 and 3 are reserved in MMC */
ssuBlk[4] = ((power_cond & 0xf) << 4) | (noflush__fl ? 0x4 : 0) |
(loej ? 0x2 : 0) | (start ? 0x1 : 0);
if (NULL == sg_warnings_strm)
sg_warnings_strm = stderr;
if (verbose) {
fprintf(sg_warnings_strm, " Start stop unit command:");
for (k = 0; k < (int)sizeof(ssuBlk); ++k)
fprintf (sg_warnings_strm, " %02x", ssuBlk[k]);
fprintf(sg_warnings_strm, "\n");
}
ptvp = construct_scsi_pt_obj();
if (NULL == ptvp) {
fprintf(sg_warnings_strm, "start stop unit: out of memory\n");
return -1;
}
set_scsi_pt_cdb(ptvp, ssuBlk, sizeof(ssuBlk));
set_scsi_pt_sense(ptvp, sense_b, sizeof(sense_b));
res = do_scsi_pt(ptvp, sg_fd, START_PT_TIMEOUT, verbose);
ret = sg_cmds_process_resp(ptvp, "start stop unit", res, 0,
sense_b, noisy, verbose, &sense_cat);
if (-1 == ret)
;
else if (-2 == ret) {
switch (sense_cat) {
case SG_LIB_CAT_NOT_READY:
case SG_LIB_CAT_INVALID_OP:
case SG_LIB_CAT_ILLEGAL_REQ:
case SG_LIB_CAT_UNIT_ATTENTION:
case SG_LIB_CAT_ABORTED_COMMAND:
ret = sense_cat;
break;
case SG_LIB_CAT_RECOVERED:
case SG_LIB_CAT_NO_SENSE:
ret = 0;
break;
default:
ret = -1;
break;
}
} else
ret = 0;
destruct_scsi_pt_obj(ptvp);
return ret;
}
/* Invokes a SCSI PREVENT ALLOW MEDIUM REMOVAL command
* [was in SPC-3 but displaced from SPC-4 into SBC-3, MMC-5, SSC-3]
* prevent==0 allows removal, prevent==1 prevents removal ...
* Return of 0 -> success,
* SG_LIB_CAT_INVALID_OP -> command not supported
* SG_LIB_CAT_ILLEGAL_REQ -> bad field in cdb, SG_LIB_CAT_UNIT_ATTENTION,
* SG_LIB_CAT_NOT_READY -> device not ready, SG_LIB_CAT_ABORTED_COMMAND,
* -1 -> other failure */
int
sg_ll_prevent_allow(int sg_fd, int prevent, int noisy, int verbose)
{
int k, res, ret, sense_cat;
unsigned char pCmdBlk[PREVENT_ALLOW_CMDLEN] =
{PREVENT_ALLOW_CMD, 0, 0, 0, 0, 0};
unsigned char sense_b[SENSE_BUFF_LEN];
struct sg_pt_base * ptvp;
if (NULL == sg_warnings_strm)
sg_warnings_strm = stderr;
if ((prevent < 0) || (prevent > 3)) {
fprintf(sg_warnings_strm, "prevent argument should be 0, 1, 2 or 3\n");
return -1;
}
pCmdBlk[4] |= (prevent & 0x3);
if (verbose) {
fprintf(sg_warnings_strm, " Prevent allow medium removal cdb: ");
for (k = 0; k < PREVENT_ALLOW_CMDLEN; ++k)
fprintf(sg_warnings_strm, "%02x ", pCmdBlk[k]);
fprintf(sg_warnings_strm, "\n");
}
ptvp = construct_scsi_pt_obj();
if (NULL == ptvp) {
fprintf(sg_warnings_strm, "prevent allow medium removal: out of "
"memory\n");
return -1;
}
set_scsi_pt_cdb(ptvp, pCmdBlk, sizeof(pCmdBlk));
set_scsi_pt_sense(ptvp, sense_b, sizeof(sense_b));
res = do_scsi_pt(ptvp, sg_fd, DEF_PT_TIMEOUT, verbose);
ret = sg_cmds_process_resp(ptvp, "prevent allow medium removal", res, 0,
sense_b, noisy, verbose, &sense_cat);
if (-1 == ret)
;
else if (-2 == ret) {
switch (sense_cat) {
case SG_LIB_CAT_NOT_READY:
case SG_LIB_CAT_INVALID_OP:
case SG_LIB_CAT_ILLEGAL_REQ:
case SG_LIB_CAT_UNIT_ATTENTION:
case SG_LIB_CAT_ABORTED_COMMAND:
ret = sense_cat;
break;
case SG_LIB_CAT_RECOVERED:
case SG_LIB_CAT_NO_SENSE:
ret = 0;
break;
default:
ret = -1;
break;
}
} else
ret = 0;
destruct_scsi_pt_obj(ptvp);
return ret;
}
ddpt-0.94/lib/sg_pt_win32.c 0000644 0001750 0001750 00000057473 12207377272 014476 0 ustar dougg dougg /*
* Copyright (c) 2006-2012 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.
*/
/* sg_pt_win32 version 1.14 20121026 */
#include
#include
#include
#include
#include
#include
#include
#include "sg_pt.h"
#include "sg_lib.h"
#include "sg_pt_win32.h"
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#ifndef O_EXCL
// #define O_EXCL 0x80 // cygwin ??
// #define O_EXCL 0x80 // Linux
#define O_EXCL 0x400 // mingw
#warning "O_EXCL not defined"
#endif
/* Use the Microsoft SCSI Pass Through (SPT) interface. It has two
* variants: "SPT" where data is double buffered; and "SPTD" where data
* pointers to the user space are passed to the OS. Only Windows
* 2000 and later (i.e. not 95,98 or ME).
* There is no ASPI interface which relies on a dll from adaptec.
* This code uses cygwin facilities and is built in a cygwin
* shell. It can be run in a normal DOS shell if the cygwin1.dll
* file is put in an appropriate place.
* This code can build in a MinGW environment.
*
* N.B. MSDN says that the "SPT" interface (i.e. double buffered)
* should be used for small amounts of data (it says "< 16 KB").
* The direct variant (i.e. IOCTL_SCSI_PASS_THROUGH_DIRECT) should
* be used for larger amounts of data but the buffer needs to be
* "cache aligned". Is that 16 byte alignment or greater?
*
* This code will default to indirect (i.e. double buffered) access
* unless the WIN32_SPT_DIRECT preprocessor constant is defined in
* config.h . In version 1.12 runtime selection of direct and indirect
* access was added; the default is still determined by the
* WIN32_SPT_DIRECT preprocessor constant.
*/
#define DEF_TIMEOUT 60 /* 60 seconds */
#define MAX_OPEN_SIMULT 8
#define WIN32_FDOFFSET 32
struct sg_pt_handle {
int in_use;
HANDLE fh;
char adapter[32];
int bus;
int target;
int lun;
};
struct sg_pt_handle handle_arr[MAX_OPEN_SIMULT];
struct sg_pt_win32_scsi {
unsigned char * dxferp;
int dxfer_len;
unsigned char * sensep;
int sense_len;
int scsi_status;
int resid;
int sense_resid;
int in_err;
int os_err; /* pseudo unix error */
int transport_err; /* windows error number */
union {
SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER swb_d;
/* Last entry in structure so data buffer can be extended */
SCSI_PASS_THROUGH_WITH_BUFFERS swb_i;
};
};
/* embed pointer so can change on fly if (non-direct) data buffer
* is not big enough */
struct sg_pt_base {
struct sg_pt_win32_scsi * implp;
};
#ifdef WIN32_SPT_DIRECT
static int spt_direct = 1;
#else
static int spt_direct = 0;
#endif
/* Request SPT direct interface when state_direct is 1, state_direct set
* to 0 for the SPT indirect interface. */
void
scsi_pt_win32_direct(int state_direct)
{
spt_direct = state_direct;
}
/* Returns current SPT interface state, 1 for direct, 0 for indirect */
int
scsi_pt_win32_spt_state(void)
{
return spt_direct;
}
/* Returns >= 0 if successful. If error in Unix returns negated errno. */
int
scsi_pt_open_device(const char * device_name, int read_only, int verbose)
{
int oflags = 0 /* O_NONBLOCK*/ ;
oflags |= (read_only ? 0 : 0); /* was ... ? O_RDONLY : O_RDWR) */
return scsi_pt_open_flags(device_name, oflags, verbose);
}
/*
* Similar to scsi_pt_open_device() but takes Unix style open flags OR-ed
* together. The 'flags' argument is ignored in Windows.
* Returns >= 0 if successful, otherwise returns negated errno.
* Optionally accept leading "\\.\". If given something of the form
* "SCSI:,," where the values in angle brackets
* are integers, then will attempt to open "\\.\SCSI:" and save the
* other three values for the DeviceIoControl call. The trailing "."
* is optionally and if not given 0 is assumed. Since "PhysicalDrive"
* is a lot of keystrokes, "PD" is accepted and converted to the longer
* form.
*/
int
scsi_pt_open_flags(const char * device_name, int flags, int verbose)
{
int len, k, adapter_num, bus, target, lun, off, got_scsi_name;
int index, num, got_pd_name, pd_num, share_mode;
struct sg_pt_handle * shp;
char buff[8];
if (NULL == sg_warnings_strm)
sg_warnings_strm = stderr;
share_mode = (O_EXCL & flags) ? 0 : (FILE_SHARE_READ | FILE_SHARE_WRITE);
/* lock */
for (k = 0; k < MAX_OPEN_SIMULT; k++)
if (0 == handle_arr[k].in_use)
break;
if (k == MAX_OPEN_SIMULT) {
if (verbose)
fprintf(sg_warnings_strm, "too many open handles "
"(%d)\n", MAX_OPEN_SIMULT);
return -EMFILE;
} else
handle_arr[k].in_use = 1;
/* unlock */
index = k;
shp = handle_arr + index;
adapter_num = 0;
bus = 0; /* also known as 'PathId' in MS docs */
target = 0;
lun = 0;
got_pd_name = 0;
got_scsi_name = 0;
len = strlen(device_name);
if ((len > 4) && (0 == strncmp("\\\\.\\", device_name, 4)))
off = 4;
else
off = 0;
if (len > (off + 2)) {
buff[0] = toupper((int)device_name[off + 0]);
buff[1] = toupper((int)device_name[off + 1]);
if (0 == strncmp("PD", buff, 2)) {
num = sscanf(device_name + off + 2, "%d", &pd_num);
if (1 == num)
got_pd_name = 1;
}
if (0 == got_pd_name) {
buff[2] = toupper((int)device_name[off + 2]);
buff[3] = toupper((int)device_name[off + 3]);
if (0 == strncmp("SCSI", buff, 4)) {
num = sscanf(device_name + off + 4, "%d:%d,%d,%d",
&adapter_num, &bus, &target, &lun);
if (num < 3) {
if (verbose)
fprintf(sg_warnings_strm, "expected format like: "
"'SCSI:.[.]'\n");
shp->in_use = 0;
return -EINVAL;
}
got_scsi_name = 1;
}
}
}
shp->bus = bus;
shp->target = target;
shp->lun = lun;
memset(shp->adapter, 0, sizeof(shp->adapter));
strncpy(shp->adapter, "\\\\.\\", 4);
if (got_pd_name)
snprintf(shp->adapter + 4, sizeof(shp->adapter) - 5,
"PhysicalDrive%d", pd_num);
else if (got_scsi_name)
snprintf(shp->adapter + 4, sizeof(shp->adapter) - 5, "SCSI%d:",
adapter_num);
else
snprintf(shp->adapter + 4, sizeof(shp->adapter) - 5, "%s",
device_name + off);
shp->fh = CreateFile(shp->adapter, GENERIC_READ | GENERIC_WRITE,
share_mode, NULL, OPEN_EXISTING, 0, NULL);
if (shp->fh == INVALID_HANDLE_VALUE) {
if (verbose)
fprintf(sg_warnings_strm, "Windows CreateFile error=%ld\n",
GetLastError());
shp->in_use = 0;
return -ENODEV;
}
return index + WIN32_FDOFFSET;
}
/* Returns 0 if successful. If error in Unix returns negated errno. */
int
scsi_pt_close_device(int device_fd)
{
struct sg_pt_handle * shp;
int index;
index = device_fd - WIN32_FDOFFSET;
if ((index < 0) || (index >= WIN32_FDOFFSET))
return -ENODEV;
shp = handle_arr + index;
CloseHandle(shp->fh);
shp->bus = 0;
shp->target = 0;
shp->lun = 0;
memset(shp->adapter, 0, sizeof(shp->adapter));
shp->in_use = 0;
return 0;
}
struct sg_pt_base *
construct_scsi_pt_obj()
{
struct sg_pt_win32_scsi * psp;
struct sg_pt_base * vp = NULL;
psp = (struct sg_pt_win32_scsi *)calloc(sizeof(struct sg_pt_win32_scsi),
1);
if (psp) {
if (spt_direct) {
psp->swb_d.spt.DataIn = SCSI_IOCTL_DATA_UNSPECIFIED;
psp->swb_d.spt.SenseInfoLength = SCSI_MAX_SENSE_LEN;
psp->swb_d.spt.SenseInfoOffset =
offsetof(SCSI_PASS_THROUGH_WITH_BUFFERS, ucSenseBuf);
psp->swb_d.spt.TimeOutValue = DEF_TIMEOUT;
} else {
psp->swb_i.spt.DataIn = SCSI_IOCTL_DATA_UNSPECIFIED;
psp->swb_i.spt.SenseInfoLength = SCSI_MAX_SENSE_LEN;
psp->swb_i.spt.SenseInfoOffset =
offsetof(SCSI_PASS_THROUGH_WITH_BUFFERS, ucSenseBuf);
psp->swb_i.spt.TimeOutValue = DEF_TIMEOUT;
}
vp = malloc(sizeof(struct sg_pt_win32_scsi *)); // yes a pointer
if (vp)
vp->implp = psp;
else
free(psp);
}
return vp;
}
void
destruct_scsi_pt_obj(struct sg_pt_base * vp)
{
if (vp) {
struct sg_pt_win32_scsi * psp = vp->implp;
if (psp) {
free(psp);
}
free(vp);
}
}
void
clear_scsi_pt_obj(struct sg_pt_base * vp)
{
struct sg_pt_win32_scsi * psp = vp->implp;
if (psp) {
memset(psp, 0, sizeof(struct sg_pt_win32_scsi));
if (spt_direct) {
psp->swb_d.spt.DataIn = SCSI_IOCTL_DATA_UNSPECIFIED;
psp->swb_d.spt.SenseInfoLength = SCSI_MAX_SENSE_LEN;
psp->swb_d.spt.SenseInfoOffset =
offsetof(SCSI_PASS_THROUGH_WITH_BUFFERS, ucSenseBuf);
psp->swb_d.spt.TimeOutValue = DEF_TIMEOUT;
} else {
psp->swb_i.spt.DataIn = SCSI_IOCTL_DATA_UNSPECIFIED;
psp->swb_i.spt.SenseInfoLength = SCSI_MAX_SENSE_LEN;
psp->swb_i.spt.SenseInfoOffset =
offsetof(SCSI_PASS_THROUGH_WITH_BUFFERS, ucSenseBuf);
psp->swb_i.spt.TimeOutValue = DEF_TIMEOUT;
}
}
}
void
set_scsi_pt_cdb(struct sg_pt_base * vp, const unsigned char * cdb,
int cdb_len)
{
struct sg_pt_win32_scsi * psp = vp->implp;
if (spt_direct) {
if (psp->swb_d.spt.CdbLength > 0)
++psp->in_err;
if (cdb_len > (int)sizeof(psp->swb_d.spt.Cdb)) {
++psp->in_err;
return;
}
memcpy(psp->swb_d.spt.Cdb, cdb, cdb_len);
psp->swb_d.spt.CdbLength = cdb_len;
} else {
if (psp->swb_i.spt.CdbLength > 0)
++psp->in_err;
if (cdb_len > (int)sizeof(psp->swb_i.spt.Cdb)) {
++psp->in_err;
return;
}
memcpy(psp->swb_i.spt.Cdb, cdb, cdb_len);
psp->swb_i.spt.CdbLength = cdb_len;
}
}
void
set_scsi_pt_sense(struct sg_pt_base * vp, unsigned char * sense,
int sense_len)
{
struct sg_pt_win32_scsi * psp = vp->implp;
if (psp->sensep)
++psp->in_err;
memset(sense, 0, sense_len);
psp->sensep = sense;
psp->sense_len = sense_len;
}
/* from device */
void
set_scsi_pt_data_in(struct sg_pt_base * vp, unsigned char * dxferp,
int dxfer_len)
{
struct sg_pt_win32_scsi * psp = vp->implp;
if (psp->dxferp)
++psp->in_err;
if (dxfer_len > 0) {
psp->dxferp = dxferp;
psp->dxfer_len = dxfer_len;
if (spt_direct)
psp->swb_d.spt.DataIn = SCSI_IOCTL_DATA_IN;
else
psp->swb_i.spt.DataIn = SCSI_IOCTL_DATA_IN;
}
}
/* to device */
void
set_scsi_pt_data_out(struct sg_pt_base * vp, const unsigned char * dxferp,
int dxfer_len)
{
struct sg_pt_win32_scsi * psp = vp->implp;
if (psp->dxferp)
++psp->in_err;
if (dxfer_len > 0) {
psp->dxferp = (unsigned char *)dxferp;
psp->dxfer_len = dxfer_len;
if (spt_direct)
psp->swb_d.spt.DataIn = SCSI_IOCTL_DATA_OUT;
else
psp->swb_i.spt.DataIn = SCSI_IOCTL_DATA_OUT;
}
}
void
set_scsi_pt_packet_id(struct sg_pt_base * vp __attribute__ ((unused)),
int pack_id __attribute__ ((unused)))
{
}
void
set_scsi_pt_tag(struct sg_pt_base * vp, uint64_t tag __attribute__ ((unused)))
{
struct sg_pt_win32_scsi * psp = vp->implp;
++psp->in_err;
}
void
set_scsi_pt_task_management(struct sg_pt_base * vp,
int tmf_code __attribute__ ((unused)))
{
struct sg_pt_win32_scsi * psp = vp->implp;
++psp->in_err;
}
void
set_scsi_pt_task_attr(struct sg_pt_base * vp,
int attrib __attribute__ ((unused)),
int priority __attribute__ ((unused)))
{
struct sg_pt_win32_scsi * psp = vp->implp;
++psp->in_err;
}
void
set_scsi_pt_flags(struct sg_pt_base * objp, int flags)
{
/* do nothing, suppress warnings */
objp = objp;
flags = flags;
}
/* Executes SCSI command (or at least forwards it to lower layers)
* using direct interface. Clears os_err field prior to active call (whose
* result may set it again). */
int
do_scsi_pt_direct(struct sg_pt_base * vp, int device_fd, int time_secs,
int verbose)
{
int index = device_fd - WIN32_FDOFFSET;
struct sg_pt_win32_scsi * psp = vp->implp;
struct sg_pt_handle * shp;
BOOL status;
ULONG returned;
if (NULL == sg_warnings_strm)
sg_warnings_strm = stderr;
psp->os_err = 0;
if (psp->in_err) {
if (verbose)
fprintf(sg_warnings_strm, "Replicated or unused set_scsi_pt...\n");
return SCSI_PT_DO_BAD_PARAMS;
}
if (0 == psp->swb_d.spt.CdbLength) {
if (verbose)
fprintf(sg_warnings_strm, "No command (cdb) given\n");
return SCSI_PT_DO_BAD_PARAMS;
}
index = device_fd - WIN32_FDOFFSET;
if ((index < 0) || (index >= WIN32_FDOFFSET)) {
if (verbose)
fprintf(sg_warnings_strm, "Bad file descriptor\n");
psp->os_err = ENODEV;
return -psp->os_err;
}
shp = handle_arr + index;
if (0 == shp->in_use) {
if (verbose)
fprintf(sg_warnings_strm, "File descriptor closed??\n");
psp->os_err = ENODEV;
return -psp->os_err;
}
psp->swb_d.spt.Length = sizeof (SCSI_PASS_THROUGH_DIRECT);
psp->swb_d.spt.PathId = shp->bus;
psp->swb_d.spt.TargetId = shp->target;
psp->swb_d.spt.Lun = shp->lun;
psp->swb_d.spt.TimeOutValue = time_secs;
psp->swb_d.spt.DataTransferLength = psp->dxfer_len;
if (verbose > 4) {
fprintf(stderr, " spt_direct, adapter: %s Length=%d ScsiStatus=%d "
"PathId=%d TargetId=%d Lun=%d\n", shp->adapter,
(int)psp->swb_d.spt.Length,
(int)psp->swb_d.spt.ScsiStatus, (int)psp->swb_d.spt.PathId,
(int)psp->swb_d.spt.TargetId, (int)psp->swb_d.spt.Lun);
fprintf(stderr, " CdbLength=%d SenseInfoLength=%d DataIn=%d "
"DataTransferLength=%lu\n",
(int)psp->swb_d.spt.CdbLength,
(int)psp->swb_d.spt.SenseInfoLength,
(int)psp->swb_d.spt.DataIn,
psp->swb_d.spt.DataTransferLength);
fprintf(stderr, " TimeOutValue=%lu SenseInfoOffset=%lu\n",
psp->swb_d.spt.TimeOutValue, psp->swb_d.spt.SenseInfoOffset);
}
psp->swb_d.spt.DataBuffer = psp->dxferp;
status = DeviceIoControl(shp->fh, IOCTL_SCSI_PASS_THROUGH_DIRECT,
&psp->swb_d,
sizeof(psp->swb_d),
&psp->swb_d,
sizeof(psp->swb_d),
&returned,
NULL);
if (! status) {
psp->transport_err = GetLastError();
if (verbose)
fprintf(sg_warnings_strm, "Windows DeviceIoControl error=%d\n",
psp->transport_err);
psp->os_err = EIO;
return 0; /* let app find transport error */
}
psp->scsi_status = psp->swb_d.spt.ScsiStatus;
if ((SAM_STAT_CHECK_CONDITION == psp->scsi_status) ||
(SAM_STAT_COMMAND_TERMINATED == psp->scsi_status))
memcpy(psp->sensep, psp->swb_d.ucSenseBuf, psp->sense_len);
else
psp->sense_len = 0;
psp->sense_resid = 0;
if ((psp->dxfer_len > 0) && (psp->swb_d.spt.DataTransferLength > 0))
psp->resid = psp->dxfer_len - psp->swb_d.spt.DataTransferLength;
else
psp->resid = 0;
return 0;
}
/* Executes SCSI command (or at least forwards it to lower layers) using
* indirect interface. Clears os_err field prior to active call (whose
* result may set it again). */
static int
do_scsi_pt_indirect(struct sg_pt_base * vp, int device_fd, int time_secs,
int verbose)
{
int index = device_fd - WIN32_FDOFFSET;
struct sg_pt_win32_scsi * psp = vp->implp;
struct sg_pt_handle * shp;
BOOL status;
ULONG returned;
if (NULL == sg_warnings_strm)
sg_warnings_strm = stderr;
psp->os_err = 0;
if (psp->in_err) {
if (verbose)
fprintf(sg_warnings_strm, "Replicated or unused "
"set_scsi_pt...\n");
return SCSI_PT_DO_BAD_PARAMS;
}
if (0 == psp->swb_i.spt.CdbLength) {
if (verbose)
fprintf(sg_warnings_strm, "No command (cdb) given\n");
return SCSI_PT_DO_BAD_PARAMS;
}
index = device_fd - WIN32_FDOFFSET;
if ((index < 0) || (index >= WIN32_FDOFFSET)) {
if (verbose)
fprintf(sg_warnings_strm, "Bad file descriptor\n");
psp->os_err = ENODEV;
return -psp->os_err;
}
shp = handle_arr + index;
if (0 == shp->in_use) {
if (verbose)
fprintf(sg_warnings_strm, "File descriptor closed??\n");
psp->os_err = ENODEV;
return -psp->os_err;
}
if (psp->dxfer_len > (int)sizeof(psp->swb_i.ucDataBuf)) {
int extra = psp->dxfer_len - (int)sizeof(psp->swb_i.ucDataBuf);
struct sg_pt_win32_scsi * epsp;
if (verbose > 4)
fprintf(sg_warnings_strm, "spt_indirect: dxfer_len (%d) too "
"large for initial data\n buffer (%d bytes), try "
"enlarging\n", psp->dxfer_len,
sizeof(psp->swb_i.ucDataBuf));
epsp = (struct sg_pt_win32_scsi *)
calloc(sizeof(struct sg_pt_win32_scsi) + extra, 1);
if (NULL == epsp) {
fprintf(sg_warnings_strm, "do_scsi_pt: failed to enlarge data "
"buffer to %d bytes\n", psp->dxfer_len);
psp->os_err = ENOMEM;
return -psp->os_err;
}
memcpy(epsp, psp, sizeof(struct sg_pt_win32_scsi));
free(psp);
vp->implp = epsp;
psp = epsp;
}
psp->swb_i.spt.Length = sizeof (SCSI_PASS_THROUGH);
psp->swb_i.spt.DataBufferOffset =
offsetof(SCSI_PASS_THROUGH_WITH_BUFFERS, ucDataBuf);
psp->swb_i.spt.PathId = shp->bus;
psp->swb_i.spt.TargetId = shp->target;
psp->swb_i.spt.Lun = shp->lun;
psp->swb_i.spt.TimeOutValue = time_secs;
psp->swb_i.spt.DataTransferLength = psp->dxfer_len;
if (verbose > 4) {
fprintf(stderr, " spt_indirect, adapter: %s Length=%d ScsiStatus=%d "
"PathId=%d TargetId=%d Lun=%d\n", shp->adapter,
(int)psp->swb_i.spt.Length,
(int)psp->swb_i.spt.ScsiStatus, (int)psp->swb_i.spt.PathId,
(int)psp->swb_i.spt.TargetId, (int)psp->swb_i.spt.Lun);
fprintf(stderr, " CdbLength=%d SenseInfoLength=%d DataIn=%d "
"DataTransferLength=%lu\n",
(int)psp->swb_i.spt.CdbLength,
(int)psp->swb_i.spt.SenseInfoLength,
(int)psp->swb_i.spt.DataIn,
psp->swb_i.spt.DataTransferLength);
fprintf(stderr, " TimeOutValue=%lu DataBufferOffset=%lu "
"SenseInfoOffset=%lu\n", psp->swb_i.spt.TimeOutValue,
psp->swb_i.spt.DataBufferOffset,
psp->swb_i.spt.SenseInfoOffset);
}
if ((psp->dxfer_len > 0) &&
(SCSI_IOCTL_DATA_OUT == psp->swb_i.spt.DataIn))
memcpy(psp->swb_i.ucDataBuf, psp->dxferp, psp->dxfer_len);
status = DeviceIoControl(shp->fh, IOCTL_SCSI_PASS_THROUGH,
&psp->swb_i,
sizeof(psp->swb_i),
&psp->swb_i,
sizeof(psp->swb_i),
&returned,
NULL);
if (! status) {
psp->transport_err = GetLastError();
if (verbose)
fprintf(sg_warnings_strm, "Windows DeviceIoControl error=%d\n",
psp->transport_err);
psp->os_err = EIO;
return 0; /* let app find transport error */
}
if ((psp->dxfer_len > 0) && (SCSI_IOCTL_DATA_IN == psp->swb_i.spt.DataIn))
memcpy(psp->dxferp, psp->swb_i.ucDataBuf, psp->dxfer_len);
psp->scsi_status = psp->swb_i.spt.ScsiStatus;
if ((SAM_STAT_CHECK_CONDITION == psp->scsi_status) ||
(SAM_STAT_COMMAND_TERMINATED == psp->scsi_status))
memcpy(psp->sensep, psp->swb_i.ucSenseBuf, psp->sense_len);
else
psp->sense_len = 0;
psp->sense_resid = 0;
if ((psp->dxfer_len > 0) && (psp->swb_i.spt.DataTransferLength > 0))
psp->resid = psp->dxfer_len - psp->swb_i.spt.DataTransferLength;
else
psp->resid = 0;
return 0;
}
/* Executes SCSI command (or at least forwards it to lower layers).
* Clears os_err field prior to active call (whose result may set it
* again). */
int
do_scsi_pt(struct sg_pt_base * vp, int device_fd, int time_secs, int verbose)
{
if (spt_direct)
return do_scsi_pt_direct(vp, device_fd, time_secs, verbose);
else
return do_scsi_pt_indirect(vp, device_fd, time_secs, verbose);
}
int
get_scsi_pt_result_category(const struct sg_pt_base * vp)
{
const struct sg_pt_win32_scsi * psp = vp->implp;
if (psp->transport_err) /* give transport error highest priority */
return SCSI_PT_RESULT_TRANSPORT_ERR;
else if (psp->os_err)
return SCSI_PT_RESULT_OS_ERR;
else if ((SAM_STAT_CHECK_CONDITION == psp->scsi_status) ||
(SAM_STAT_COMMAND_TERMINATED == psp->scsi_status))
return SCSI_PT_RESULT_SENSE;
else if (psp->scsi_status)
return SCSI_PT_RESULT_STATUS;
else
return SCSI_PT_RESULT_GOOD;
}
int
get_scsi_pt_resid(const struct sg_pt_base * vp)
{
const struct sg_pt_win32_scsi * psp = vp->implp;
return psp->resid;
}
int
get_scsi_pt_status_response(const struct sg_pt_base * vp)
{
const struct sg_pt_win32_scsi * psp = vp->implp;
return psp->scsi_status;
}
int
get_scsi_pt_sense_len(const struct sg_pt_base * vp)
{
const struct sg_pt_win32_scsi * psp = vp->implp;
int len;
len = psp->sense_len - psp->sense_resid;
return (len > 0) ? len : 0;
}
int
get_scsi_pt_duration_ms(const struct sg_pt_base * vp __attribute__ ((unused)))
{
// const struct sg_pt_freebsd_scsi * psp = vp->implp;
return -1;
}
int
get_scsi_pt_transport_err(const struct sg_pt_base * vp)
{
const struct sg_pt_win32_scsi * psp = vp->implp;
return psp->transport_err;
}
int
get_scsi_pt_os_err(const struct sg_pt_base * vp)
{
const struct sg_pt_win32_scsi * psp = vp->implp;
return psp->os_err;
}
char *
get_scsi_pt_transport_err_str(const struct sg_pt_base * vp, int max_b_len,
char * b)
{
struct sg_pt_win32_scsi * psp = (struct sg_pt_win32_scsi *)vp->implp;
LPVOID lpMsgBuf;
int k, num, ch;
if (max_b_len < 2) {
if (1 == max_b_len)
b[0] = '\0';
return b;
}
memset(b, 0, max_b_len);
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM,
NULL,
psp->transport_err,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR) &lpMsgBuf,
0, NULL );
num = lstrlen((LPCTSTR)lpMsgBuf);
if (num < 1)
return b;
num = (num < max_b_len) ? num : (max_b_len - 1);
for (k = 0; k < num; ++k) {
ch = *((LPCTSTR)lpMsgBuf + k);
if ((ch >= 0x0) && (ch < 0x7f))
b[k] = ch & 0x7f;
else
b[k] = '?';
}
return b;
}
char *
get_scsi_pt_os_err_str(const struct sg_pt_base * vp, int max_b_len, char * b)
{
const struct sg_pt_win32_scsi * psp = vp->implp;
const char * cp;
cp = safe_strerror(psp->os_err);
strncpy(b, cp, max_b_len);
if ((int)strlen(cp) >= max_b_len)
b[max_b_len - 1] = '\0';
return b;
}
ddpt-0.94/lib/sg_cmds_extra.c 0000644 0001750 0001750 00000262740 12270322342 015141 0 ustar dougg dougg /*
* Copyright (c) 1999-2013 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
#include
#include
#include
#define __STDC_FORMAT_MACROS 1
#include
#include "sg_lib.h"
#include "sg_lib_data.h"
#include "sg_cmds_basic.h"
#include "sg_cmds_extra.h"
#include "sg_pt.h"
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#define SENSE_BUFF_LEN 64 /* Arbitrary, could be larger */
#define DEF_PT_TIMEOUT 60 /* 60 seconds */
#define LONG_PT_TIMEOUT 7200 /* 7,200 seconds == 120 minutes */
#define SERVICE_ACTION_IN_16_CMD 0x9e
#define SERVICE_ACTION_IN_16_CMDLEN 16
#define SERVICE_ACTION_OUT_16_CMD 0x9f
#define SERVICE_ACTION_OUT_16_CMDLEN 16
#define MAINTENANCE_IN_CMD 0xa3
#define MAINTENANCE_IN_CMDLEN 12
#define MAINTENANCE_OUT_CMD 0xa4
#define MAINTENANCE_OUT_CMDLEN 12
#define ATA_PT_12_CMD 0xa1
#define ATA_PT_12_CMDLEN 12
#define ATA_PT_16_CMD 0x85
#define ATA_PT_16_CMDLEN 16
#define FORMAT_UNIT_CMD 0x4
#define FORMAT_UNIT_CMDLEN 6
#define PERSISTENT_RESERVE_IN_CMD 0x5e
#define PERSISTENT_RESERVE_IN_CMDLEN 10
#define PERSISTENT_RESERVE_OUT_CMD 0x5f
#define PERSISTENT_RESERVE_OUT_CMDLEN 10
#define READ_BLOCK_LIMITS_CMD 0x5
#define READ_BLOCK_LIMITS_CMDLEN 6
#define READ_BUFFER_CMD 0x3c
#define READ_BUFFER_CMDLEN 10
#define READ_DEFECT10_CMD 0x37
#define READ_DEFECT10_CMDLEN 10
#define REASSIGN_BLKS_CMD 0x7
#define REASSIGN_BLKS_CMDLEN 6
#define RECEIVE_DIAGNOSTICS_CMD 0x1c
#define RECEIVE_DIAGNOSTICS_CMDLEN 6
#define THIRD_PARTY_COPY_OUT_CMD 0x83 /* was EXTENDED_COPY_CMD */
#define THIRD_PARTY_COPY_OUT_CMDLEN 16
#define THIRD_PARTY_COPY_IN_CMD 0x84 /* was RECEIVE_COPY_RESULTS_CMD */
#define THIRD_PARTY_COPY_IN_CMDLEN 16
#define SEND_DIAGNOSTIC_CMD 0x1d
#define SEND_DIAGNOSTIC_CMDLEN 6
#define SERVICE_ACTION_IN_12_CMD 0xab
#define SERVICE_ACTION_IN_12_CMDLEN 12
#define READ_LONG10_CMD 0x3e
#define READ_LONG10_CMDLEN 10
#define UNMAP_CMD 0x42
#define UNMAP_CMDLEN 10
#define VERIFY10_CMD 0x2f
#define VERIFY10_CMDLEN 10
#define VERIFY16_CMD 0x8f
#define VERIFY16_CMDLEN 16
#define WRITE_LONG10_CMD 0x3f
#define WRITE_LONG10_CMDLEN 10
#define WRITE_BUFFER_CMD 0x3b
#define WRITE_BUFFER_CMDLEN 10
#define GET_LBA_STATUS_SA 0x12
#define READ_LONG_16_SA 0x11
#define READ_MEDIA_SERIAL_NUM_SA 0x1
#define REPORT_IDENTIFYING_INFORMATION_SA 0x5
#define REPORT_TGT_PRT_GRP_SA 0xa
#define SET_IDENTIFYING_INFORMATION_SA 0x6
#define SET_TGT_PRT_GRP_SA 0xa
#define WRITE_LONG_16_SA 0x11
#define REPORT_REFERRALS_SA 0x13
#define EXTENDED_COPY_LID1_SA 0x0
/* Invokes a SCSI GET LBA STATUS command (SBC). Returns 0 -> success,
* SG_LIB_CAT_INVALID_OP -> GET LBA STATUS not supported,
* SG_LIB_CAT_ILLEGAL_REQ -> bad field in cdb, SG_LIB_CAT_ABORTED_COMMAND,
* SG_LIB_CAT_NOT_READY -> device not ready, -1 -> other failure */
int
sg_ll_get_lba_status(int sg_fd, uint64_t start_llba, void * resp,
int alloc_len, int noisy, int verbose)
{
int k, res, sense_cat, ret;
unsigned char getLbaStatCmd[SERVICE_ACTION_IN_16_CMDLEN];
unsigned char sense_b[SENSE_BUFF_LEN];
struct sg_pt_base * ptvp;
memset(getLbaStatCmd, 0, sizeof(getLbaStatCmd));
getLbaStatCmd[0] = SERVICE_ACTION_IN_16_CMD;
getLbaStatCmd[1] = GET_LBA_STATUS_SA;
getLbaStatCmd[2] = (start_llba >> 56) & 0xff;
getLbaStatCmd[3] = (start_llba >> 48) & 0xff;
getLbaStatCmd[4] = (start_llba >> 40) & 0xff;
getLbaStatCmd[5] = (start_llba >> 32) & 0xff;
getLbaStatCmd[6] = (start_llba >> 24) & 0xff;
getLbaStatCmd[7] = (start_llba >> 16) & 0xff;
getLbaStatCmd[8] = (start_llba >> 8) & 0xff;
getLbaStatCmd[9] = start_llba & 0xff;
getLbaStatCmd[10] = (alloc_len >> 24) & 0xff;
getLbaStatCmd[11] = (alloc_len >> 16) & 0xff;
getLbaStatCmd[12] = (alloc_len >> 8) & 0xff;
getLbaStatCmd[13] = alloc_len & 0xff;
if (NULL == sg_warnings_strm)
sg_warnings_strm = stderr;
if (verbose) {
fprintf(sg_warnings_strm, " Get LBA status cmd: ");
for (k = 0; k < SERVICE_ACTION_IN_16_CMDLEN; ++k)
fprintf(sg_warnings_strm, "%02x ", getLbaStatCmd[k]);
fprintf(sg_warnings_strm, "\n");
}
ptvp = construct_scsi_pt_obj();
if (NULL == ptvp) {
fprintf(sg_warnings_strm, "get LBA status: out of memory\n");
return -1;
}
set_scsi_pt_cdb(ptvp, getLbaStatCmd, sizeof(getLbaStatCmd));
set_scsi_pt_sense(ptvp, sense_b, sizeof(sense_b));
set_scsi_pt_data_in(ptvp, (unsigned char *)resp, alloc_len);
res = do_scsi_pt(ptvp, sg_fd, DEF_PT_TIMEOUT, verbose);
ret = sg_cmds_process_resp(ptvp, "get LBA status", res, alloc_len,
sense_b, noisy, verbose, &sense_cat);
if (-1 == ret)
;
else if (-2 == ret) {
switch (sense_cat) {
case SG_LIB_CAT_NOT_READY:
case SG_LIB_CAT_ILLEGAL_REQ:
case SG_LIB_CAT_INVALID_OP:
case SG_LIB_CAT_UNIT_ATTENTION:
case SG_LIB_CAT_ABORTED_COMMAND:
ret = sense_cat;
break;
case SG_LIB_CAT_RECOVERED:
case SG_LIB_CAT_NO_SENSE:
ret = 0;
break;
default:
ret = -1;
break;
}
} else {
if ((verbose > 2) && (ret > 0)) {
fprintf(sg_warnings_strm, " get LBA status: response%s\n",
(ret > 256 ? ", first 256 bytes" : ""));
dStrHexErr((const char *)resp, (ret > 256 ? 256 : ret), -1);
}
ret = 0;
}
destruct_scsi_pt_obj(ptvp);
return ret;
}
int
sg_ll_report_tgt_prt_grp(int sg_fd, void * resp, int mx_resp_len,
int noisy, int verbose)
{
return sg_ll_report_tgt_prt_grp2(sg_fd, resp, mx_resp_len, 0, noisy,
verbose);
}
/* Invokes a SCSI REPORT TARGET PORT GROUPS command. Return of 0 -> success,
* SG_LIB_CAT_INVALID_OP -> Report Target Port Groups not supported,
* SG_LIB_CAT_ILLEGAL_REQ -> bad field in cdb, SG_LIB_CAT_ABORTED_COMMAND,
* SG_LIB_CAT_UNIT_ATTENTION, -1 -> other failure */
int
sg_ll_report_tgt_prt_grp2(int sg_fd, void * resp, int mx_resp_len,
int extended, int noisy, int verbose)
{
int k, res, ret, sense_cat;
unsigned char rtpgCmdBlk[MAINTENANCE_IN_CMDLEN] =
{MAINTENANCE_IN_CMD, REPORT_TGT_PRT_GRP_SA,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
unsigned char sense_b[SENSE_BUFF_LEN];
struct sg_pt_base * ptvp;
if (extended) {
rtpgCmdBlk[1] |= 0x20;
}
rtpgCmdBlk[6] = (mx_resp_len >> 24) & 0xff;
rtpgCmdBlk[7] = (mx_resp_len >> 16) & 0xff;
rtpgCmdBlk[8] = (mx_resp_len >> 8) & 0xff;
rtpgCmdBlk[9] = mx_resp_len & 0xff;
if (NULL == sg_warnings_strm)
sg_warnings_strm = stderr;
if (verbose) {
fprintf(sg_warnings_strm, " report target port groups cdb: ");
for (k = 0; k < MAINTENANCE_IN_CMDLEN; ++k)
fprintf(sg_warnings_strm, "%02x ", rtpgCmdBlk[k]);
fprintf(sg_warnings_strm, "\n");
}
ptvp = construct_scsi_pt_obj();
if (NULL == ptvp) {
fprintf(sg_warnings_strm, "report target port groups: out of "
"memory\n");
return -1;
}
set_scsi_pt_cdb(ptvp, rtpgCmdBlk, sizeof(rtpgCmdBlk));
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, sg_fd, DEF_PT_TIMEOUT, verbose);
ret = sg_cmds_process_resp(ptvp, "report target port group", res,
mx_resp_len, sense_b, noisy, verbose,
&sense_cat);
if (-1 == ret)
;
else if (-2 == ret) {
switch (sense_cat) {
case SG_LIB_CAT_INVALID_OP:
case SG_LIB_CAT_ILLEGAL_REQ:
case SG_LIB_CAT_UNIT_ATTENTION:
case SG_LIB_CAT_ABORTED_COMMAND:
ret = sense_cat;
break;
case SG_LIB_CAT_RECOVERED:
case SG_LIB_CAT_NO_SENSE:
ret = 0;
break;
default:
ret = -1;
break;
}
} else {
if ((verbose > 2) && (ret > 0)) {
fprintf(sg_warnings_strm, " report target port group: "
"response%s\n", (ret > 256 ? ", first 256 bytes" : ""));
dStrHexErr((const char *)resp, (ret > 256 ? 256 : ret), -1);
}
ret = 0;
}
destruct_scsi_pt_obj(ptvp);
return ret;
}
/* Invokes a SCSI SET TARGET PORT GROUPS command. Return of 0 -> success,
* SG_LIB_CAT_INVALID_OP -> Set Target Port Groups not supported,
* SG_LIB_CAT_ILLEGAL_REQ -> bad field in cdb, SG_LIB_CAT_ABORTED_COMMAND,
* SG_LIB_CAT_UNIT_ATTENTION, -1 -> other failure */
int
sg_ll_set_tgt_prt_grp(int sg_fd, void * paramp, int param_len, int noisy,
int verbose)
{
int k, res, ret, sense_cat;
unsigned char stpgCmdBlk[MAINTENANCE_OUT_CMDLEN] =
{MAINTENANCE_OUT_CMD, SET_TGT_PRT_GRP_SA,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
unsigned char sense_b[SENSE_BUFF_LEN];
struct sg_pt_base * ptvp;
stpgCmdBlk[6] = (param_len >> 24) & 0xff;
stpgCmdBlk[7] = (param_len >> 16) & 0xff;
stpgCmdBlk[8] = (param_len >> 8) & 0xff;
stpgCmdBlk[9] = param_len & 0xff;
if (NULL == sg_warnings_strm)
sg_warnings_strm = stderr;
if (verbose) {
fprintf(sg_warnings_strm, " set target port groups cdb: ");
for (k = 0; k < MAINTENANCE_OUT_CMDLEN; ++k)
fprintf(sg_warnings_strm, "%02x ", stpgCmdBlk[k]);
fprintf(sg_warnings_strm, "\n");
if ((verbose > 1) && paramp && param_len) {
fprintf(sg_warnings_strm, " set target port groups "
"parameter list:\n");
dStrHexErr((const char *)paramp, param_len, -1);
}
}
ptvp = construct_scsi_pt_obj();
if (NULL == ptvp) {
fprintf(sg_warnings_strm, "set target port groups: out of "
"memory\n");
return -1;
}
set_scsi_pt_cdb(ptvp, stpgCmdBlk, sizeof(stpgCmdBlk));
set_scsi_pt_sense(ptvp, sense_b, sizeof(sense_b));
set_scsi_pt_data_out(ptvp, (unsigned char *)paramp, param_len);
res = do_scsi_pt(ptvp, sg_fd, DEF_PT_TIMEOUT, verbose);
ret = sg_cmds_process_resp(ptvp, "set target port group", res, 0,
sense_b, noisy, verbose, &sense_cat);
if (-1 == ret)
;
else if (-2 == ret) {
switch (sense_cat) {
case SG_LIB_CAT_INVALID_OP:
case SG_LIB_CAT_ILLEGAL_REQ:
case SG_LIB_CAT_UNIT_ATTENTION:
case SG_LIB_CAT_ABORTED_COMMAND:
ret = sense_cat;
break;
case SG_LIB_CAT_RECOVERED:
case SG_LIB_CAT_NO_SENSE:
ret = 0;
break;
default:
ret = -1;
break;
}
} else
ret = 0;
destruct_scsi_pt_obj(ptvp);
return ret;
}
/* Invokes a SCSI REPORT REFERRALS command. Return of 0 -> success,
* SG_LIB_CAT_INVALID_OP -> Report Referrals not supported,
* SG_LIB_CAT_ILLEGAL_REQ -> bad field in cdb, SG_LIB_CAT_ABORTED_COMMAND,
* SG_LIB_CAT_UNIT_ATTENTION, -1 -> other failure */
int
sg_ll_report_referrals(int sg_fd, uint64_t start_llba, int one_seg,
void * resp, int mx_resp_len, int noisy,
int verbose)
{
int k, res, ret, sense_cat;
unsigned char repRefCmdBlk[SERVICE_ACTION_IN_16_CMDLEN] =
{SERVICE_ACTION_IN_16_CMD, REPORT_REFERRALS_SA,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
unsigned char sense_b[SENSE_BUFF_LEN];
struct sg_pt_base * ptvp;
repRefCmdBlk[2] = (start_llba >> 56) & 0xff;
repRefCmdBlk[3] = (start_llba >> 48) & 0xff;
repRefCmdBlk[4] = (start_llba >> 40) & 0xff;
repRefCmdBlk[5] = (start_llba >> 32) & 0xff;
repRefCmdBlk[6] = (start_llba >> 24) & 0xff;
repRefCmdBlk[7] = (start_llba >> 16) & 0xff;
repRefCmdBlk[8] = (start_llba >> 8) & 0xff;
repRefCmdBlk[9] = start_llba & 0xff;
repRefCmdBlk[10] = (mx_resp_len >> 24) & 0xff;
repRefCmdBlk[11] = (mx_resp_len >> 16) & 0xff;
repRefCmdBlk[12] = (mx_resp_len >> 8) & 0xff;
repRefCmdBlk[13] = mx_resp_len & 0xff;
repRefCmdBlk[14] = one_seg & 0x1;
if (NULL == sg_warnings_strm)
sg_warnings_strm = stderr;
if (verbose) {
fprintf(sg_warnings_strm, " report referrals cdb: ");
for (k = 0; k < SERVICE_ACTION_IN_16_CMDLEN; ++k)
fprintf(sg_warnings_strm, "%02x ", repRefCmdBlk[k]);
fprintf(sg_warnings_strm, "\n");
}
ptvp = construct_scsi_pt_obj();
if (NULL == ptvp) {
fprintf(sg_warnings_strm, "report target port groups: out of "
"memory\n");
return -1;
}
set_scsi_pt_cdb(ptvp, repRefCmdBlk, sizeof(repRefCmdBlk));
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, sg_fd, DEF_PT_TIMEOUT, verbose);
ret = sg_cmds_process_resp(ptvp, "report referrals", res,
mx_resp_len, sense_b, noisy, verbose,
&sense_cat);
if (-1 == ret)
;
else if (-2 == ret) {
switch (sense_cat) {
case SG_LIB_CAT_INVALID_OP:
case SG_LIB_CAT_ILLEGAL_REQ:
case SG_LIB_CAT_UNIT_ATTENTION:
case SG_LIB_CAT_ABORTED_COMMAND:
ret = sense_cat;
break;
case SG_LIB_CAT_RECOVERED:
case SG_LIB_CAT_NO_SENSE:
ret = 0;
break;
default:
ret = -1;
break;
}
} else {
if ((verbose > 2) && (ret > 0)) {
fprintf(sg_warnings_strm, " report referrals: response%s\n",
(ret > 256 ? ", first 256 bytes" : ""));
dStrHexErr((const char *)resp, (ret > 256 ? 256 : ret), -1);
}
ret = 0;
}
destruct_scsi_pt_obj(ptvp);
return ret;
}
/* Invokes a SCSI SEND DIAGNOSTIC command. Foreground, extended self tests can
* take a long time, if so set long_duration flag in which case the timout
* is set to 7200 seconds; if the value of long_duration is > 7200 then that
* value is taken as the timeout value in seconds. Return of 0 -> success,
* SG_LIB_CAT_INVALID_OP -> Send diagnostic not supported,
* SG_LIB_CAT_ILLEGAL_REQ -> bad field in cdb, SG_LIB_CAT_UNIT_ATTENTION,
* SG_LIB_CAT_NOT_READY -> device not ready, SG_LIB_CAT_ABORTED_COMMAND,
* -1 -> other failure */
int
sg_ll_send_diag(int sg_fd, int sf_code, int pf_bit, int sf_bit, int devofl_bit,
int unitofl_bit, int long_duration, void * paramp,
int param_len, int noisy, int verbose)
{
int k, res, ret, sense_cat, tmout;
unsigned char senddiagCmdBlk[SEND_DIAGNOSTIC_CMDLEN] =
{SEND_DIAGNOSTIC_CMD, 0, 0, 0, 0, 0};
unsigned char sense_b[SENSE_BUFF_LEN];
struct sg_pt_base * ptvp;
senddiagCmdBlk[1] = (unsigned char)((sf_code << 5) | (pf_bit << 4) |
(sf_bit << 2) | (devofl_bit << 1) | unitofl_bit);
senddiagCmdBlk[3] = (unsigned char)((param_len >> 8) & 0xff);
senddiagCmdBlk[4] = (unsigned char)(param_len & 0xff);
if (NULL == sg_warnings_strm)
sg_warnings_strm = stderr;
if (verbose) {
fprintf(sg_warnings_strm, " Send diagnostic cmd: ");
for (k = 0; k < SEND_DIAGNOSTIC_CMDLEN; ++k)
fprintf(sg_warnings_strm, "%02x ", senddiagCmdBlk[k]);
fprintf(sg_warnings_strm, "\n");
if ((verbose > 1) && paramp && param_len) {
fprintf(sg_warnings_strm, " Send diagnostic parameter "
"list:\n");
dStrHexErr((const char *)paramp, param_len, -1);
}
}
if (long_duration > LONG_PT_TIMEOUT)
tmout = long_duration;
else
tmout = long_duration ? LONG_PT_TIMEOUT : DEF_PT_TIMEOUT;
ptvp = construct_scsi_pt_obj();
if (NULL == ptvp) {
fprintf(sg_warnings_strm, "send diagnostic: out of memory\n");
return -1;
}
set_scsi_pt_cdb(ptvp, senddiagCmdBlk, sizeof(senddiagCmdBlk));
set_scsi_pt_sense(ptvp, sense_b, sizeof(sense_b));
set_scsi_pt_data_out(ptvp, (unsigned char *)paramp, param_len);
res = do_scsi_pt(ptvp, sg_fd, tmout, verbose);
ret = sg_cmds_process_resp(ptvp, "send diagnostic", res, 0, sense_b,
noisy, verbose, &sense_cat);
if (-1 == ret)
;
else if (-2 == ret) {
switch (sense_cat) {
case SG_LIB_CAT_NOT_READY:
case SG_LIB_CAT_INVALID_OP:
case SG_LIB_CAT_ILLEGAL_REQ:
case SG_LIB_CAT_UNIT_ATTENTION:
case SG_LIB_CAT_ABORTED_COMMAND:
ret = sense_cat;
break;
case SG_LIB_CAT_RECOVERED:
case SG_LIB_CAT_NO_SENSE:
ret = 0;
break;
default:
ret = -1;
break;
}
} else
ret = 0;
destruct_scsi_pt_obj(ptvp);
return ret;
}
/* Invokes a SCSI RECEIVE DIAGNOSTIC RESULTS command. Return of 0 -> success,
* SG_LIB_CAT_INVALID_OP -> Receive diagnostic results not supported,
* SG_LIB_CAT_ILLEGAL_REQ -> bad field in cdb, SG_LIB_CAT_UNIT_ATTENTION,
* SG_LIB_CAT_NOT_READY -> device not ready, SG_LIB_CAT_ABORTED_COMMAND,
* -1 -> other failure */
int
sg_ll_receive_diag(int sg_fd, int pcv, int pg_code, void * resp,
int mx_resp_len, int noisy, int verbose)
{
int k, res, ret, sense_cat;
unsigned char rcvdiagCmdBlk[RECEIVE_DIAGNOSTICS_CMDLEN] =
{RECEIVE_DIAGNOSTICS_CMD, 0, 0, 0, 0, 0};
unsigned char sense_b[SENSE_BUFF_LEN];
struct sg_pt_base * ptvp;
rcvdiagCmdBlk[1] = (unsigned char)(pcv ? 0x1 : 0);
rcvdiagCmdBlk[2] = (unsigned char)(pg_code);
rcvdiagCmdBlk[3] = (unsigned char)((mx_resp_len >> 8) & 0xff);
rcvdiagCmdBlk[4] = (unsigned char)(mx_resp_len & 0xff);
if (NULL == sg_warnings_strm)
sg_warnings_strm = stderr;
if (verbose) {
fprintf(sg_warnings_strm, " Receive diagnostic results cmd: ");
for (k = 0; k < RECEIVE_DIAGNOSTICS_CMDLEN; ++k)
fprintf(sg_warnings_strm, "%02x ", rcvdiagCmdBlk[k]);
fprintf(sg_warnings_strm, "\n");
}
ptvp = construct_scsi_pt_obj();
if (NULL == ptvp) {
fprintf(sg_warnings_strm, "receive diagnostic results: out of "
"memory\n");
return -1;
}
set_scsi_pt_cdb(ptvp, rcvdiagCmdBlk, sizeof(rcvdiagCmdBlk));
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, sg_fd, DEF_PT_TIMEOUT, verbose);
ret = sg_cmds_process_resp(ptvp, "receive diagnostic results", res,
mx_resp_len, sense_b, noisy, verbose,
&sense_cat);
if (-1 == ret)
;
else if (-2 == ret) {
switch (sense_cat) {
case SG_LIB_CAT_NOT_READY:
case SG_LIB_CAT_INVALID_OP:
case SG_LIB_CAT_ILLEGAL_REQ:
case SG_LIB_CAT_UNIT_ATTENTION:
case SG_LIB_CAT_ABORTED_COMMAND:
ret = sense_cat;
break;
case SG_LIB_CAT_RECOVERED:
case SG_LIB_CAT_NO_SENSE:
ret = 0;
break;
default:
ret = -1;
break;
}
} else {
if ((verbose > 2) && (ret > 0)) {
fprintf(sg_warnings_strm, " receive diagnostic results: "
"response%s\n", (ret > 256 ? ", first 256 bytes" : ""));
dStrHexErr((const char *)resp, (ret > 256 ? 256 : ret), -1);
}
ret = 0;
}
destruct_scsi_pt_obj(ptvp);
return ret;
}
/* Invokes a SCSI READ DEFECT DATA (10) command (SBC). Return of 0 ->
* success, SG_LIB_CAT_INVALID_OP -> invalid opcode,
* SG_LIB_CAT_ILLEGAL_REQ -> bad field in cdb, SG_LIB_CAT_UNIT_ATTENTION,
* SG_LIB_CAT_NOT_READY -> device not ready, SG_LIB_CAT_ABORTED_COMMAND,
* -1 -> other failure */
int
sg_ll_read_defect10(int sg_fd, int req_plist, int req_glist, int dl_format,
void * resp, int mx_resp_len, int noisy, int verbose)
{
int res, k, ret, sense_cat;
unsigned char rdefCmdBlk[READ_DEFECT10_CMDLEN] =
{READ_DEFECT10_CMD, 0, 0, 0, 0, 0, 0, 0, 0, 0};
unsigned char sense_b[SENSE_BUFF_LEN];
struct sg_pt_base * ptvp;
rdefCmdBlk[2] = (unsigned char)(((req_plist << 4) & 0x10) |
((req_glist << 3) & 0x8) | (dl_format & 0x7));
rdefCmdBlk[7] = (unsigned char)((mx_resp_len >> 8) & 0xff);
rdefCmdBlk[8] = (unsigned char)(mx_resp_len & 0xff);
if (NULL == sg_warnings_strm)
sg_warnings_strm = stderr;
if (mx_resp_len > 0xffff) {
fprintf(sg_warnings_strm, "mx_resp_len too big\n");
return -1;
}
if (verbose) {
fprintf(sg_warnings_strm, " read defect (10) cdb: ");
for (k = 0; k < READ_DEFECT10_CMDLEN; ++k)
fprintf(sg_warnings_strm, "%02x ", rdefCmdBlk[k]);
fprintf(sg_warnings_strm, "\n");
}
ptvp = construct_scsi_pt_obj();
if (NULL == ptvp) {
fprintf(sg_warnings_strm, "read defect (10): out of memory\n");
return -1;
}
set_scsi_pt_cdb(ptvp, rdefCmdBlk, sizeof(rdefCmdBlk));
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, sg_fd, DEF_PT_TIMEOUT, verbose);
ret = sg_cmds_process_resp(ptvp, "read defect (10)", res, mx_resp_len,
sense_b, noisy, verbose, &sense_cat);
if (-1 == ret)
;
else if (-2 == ret) {
switch (sense_cat) {
case SG_LIB_CAT_NOT_READY:
case SG_LIB_CAT_INVALID_OP:
case SG_LIB_CAT_ILLEGAL_REQ:
case SG_LIB_CAT_UNIT_ATTENTION:
case SG_LIB_CAT_ABORTED_COMMAND:
ret = sense_cat;
break;
case SG_LIB_CAT_RECOVERED:
case SG_LIB_CAT_NO_SENSE:
ret = 0;
break;
default:
ret = -1;
break;
}
} else {
if ((verbose > 2) && (ret > 0)) {
fprintf(sg_warnings_strm, " read defect (10): response%s\n",
(ret > 256 ? ", first 256 bytes" : ""));
dStrHexErr((const char *)resp, (ret > 256 ? 256 : ret), -1);
}
ret = 0;
}
destruct_scsi_pt_obj(ptvp);
return ret;
}
/* Invokes a SCSI READ MEDIA SERIAL NUMBER command. Return of 0 -> success,
* SG_LIB_CAT_INVALID_OP -> Read media serial number not supported,
* SG_LIB_CAT_ILLEGAL_REQ -> bad field in cdb, SG_LIB_CAT_UNIT_ATTENTION,
* SG_LIB_CAT_NOT_READY -> device not ready, SG_LIB_CAT_ABORTED_COMMAND,
* -1 -> other failure */
int
sg_ll_read_media_serial_num(int sg_fd, void * resp, int mx_resp_len,
int noisy, int verbose)
{
int k, res, ret, sense_cat;
unsigned char rmsnCmdBlk[SERVICE_ACTION_IN_12_CMDLEN] =
{SERVICE_ACTION_IN_12_CMD, READ_MEDIA_SERIAL_NUM_SA,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
unsigned char sense_b[SENSE_BUFF_LEN];
struct sg_pt_base * ptvp;
rmsnCmdBlk[6] = (mx_resp_len >> 24) & 0xff;
rmsnCmdBlk[7] = (mx_resp_len >> 16) & 0xff;
rmsnCmdBlk[8] = (mx_resp_len >> 8) & 0xff;
rmsnCmdBlk[9] = mx_resp_len & 0xff;
if (NULL == sg_warnings_strm)
sg_warnings_strm = stderr;
if (verbose) {
fprintf(sg_warnings_strm, " read media serial number cdb: ");
for (k = 0; k < SERVICE_ACTION_IN_12_CMDLEN; ++k)
fprintf(sg_warnings_strm, "%02x ", rmsnCmdBlk[k]);
fprintf(sg_warnings_strm, "\n");
}
ptvp = construct_scsi_pt_obj();
if (NULL == ptvp) {
fprintf(sg_warnings_strm, "read media serial number: out of "
"memory\n");
return -1;
}
set_scsi_pt_cdb(ptvp, rmsnCmdBlk, sizeof(rmsnCmdBlk));
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, sg_fd, DEF_PT_TIMEOUT, verbose);
ret = sg_cmds_process_resp(ptvp, "read media serial number", res,
mx_resp_len, sense_b, noisy, verbose,
&sense_cat);
if (-1 == ret)
;
else if (-2 == ret) {
switch (sense_cat) {
case SG_LIB_CAT_NOT_READY:
case SG_LIB_CAT_INVALID_OP:
case SG_LIB_CAT_ILLEGAL_REQ:
case SG_LIB_CAT_UNIT_ATTENTION:
case SG_LIB_CAT_ABORTED_COMMAND:
ret = sense_cat;
break;
case SG_LIB_CAT_RECOVERED:
case SG_LIB_CAT_NO_SENSE:
ret = 0;
break;
default:
ret = -1;
break;
}
} else {
if ((verbose > 2) && (ret > 0)) {
fprintf(sg_warnings_strm, " read media serial number: respon"
"se%s\n", (ret > 256 ? ", first 256 bytes" : ""));
dStrHexErr((const char *)resp, (ret > 256 ? 256 : ret), -1);
}
ret = 0;
}
destruct_scsi_pt_obj(ptvp);
return ret;
}
/* Invokes a SCSI REPORT IDENTIFYING INFORMATION command. This command was
* called REPORT DEVICE IDENTIFIER prior to spc4r07. Return of 0 -> success,
* SG_LIB_CAT_INVALID_OP -> Report identifying information not supported,
* SG_LIB_CAT_ILLEGAL_REQ -> bad field in cdb, SG_LIB_CAT_UNIT_ATTENTION,
* SG_LIB_CAT_NOT_READY -> device not ready, SG_LIB_CAT_ABORTED_COMMAND,
* -1 -> other failure */
int
sg_ll_report_id_info(int sg_fd, int itype, void * resp, int max_resp_len,
int noisy, int verbose)
{
int k, res, ret, sense_cat;
unsigned char riiCmdBlk[MAINTENANCE_IN_CMDLEN] = {MAINTENANCE_IN_CMD,
REPORT_IDENTIFYING_INFORMATION_SA,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
unsigned char sense_b[SENSE_BUFF_LEN];
struct sg_pt_base * ptvp;
riiCmdBlk[6] = (max_resp_len >> 24) & 0xff;
riiCmdBlk[7] = (max_resp_len >> 16) & 0xff;
riiCmdBlk[8] = (max_resp_len >> 8) & 0xff;
riiCmdBlk[9] = max_resp_len & 0xff;
riiCmdBlk[10] |= (itype << 1) & 0xfe;
if (NULL == sg_warnings_strm)
sg_warnings_strm = stderr;
if (verbose) {
fprintf(sg_warnings_strm, " Report identifying information cdb: ");
for (k = 0; k < MAINTENANCE_IN_CMDLEN; ++k)
fprintf(sg_warnings_strm, "%02x ", riiCmdBlk[k]);
fprintf(sg_warnings_strm, "\n");
}
ptvp = construct_scsi_pt_obj();
if (NULL == ptvp) {
fprintf(sg_warnings_strm, "report identifying information: out of "
"memory\n");
return -1;
}
set_scsi_pt_cdb(ptvp, riiCmdBlk, sizeof(riiCmdBlk));
set_scsi_pt_sense(ptvp, sense_b, sizeof(sense_b));
set_scsi_pt_data_in(ptvp, (unsigned char *)resp, max_resp_len);
res = do_scsi_pt(ptvp, sg_fd, DEF_PT_TIMEOUT, verbose);
ret = sg_cmds_process_resp(ptvp, "report identifying information", res,
max_resp_len, sense_b, noisy, verbose,
&sense_cat);
if (-1 == ret)
;
else if (-2 == ret) {
switch (sense_cat) {
case SG_LIB_CAT_NOT_READY:
case SG_LIB_CAT_INVALID_OP:
case SG_LIB_CAT_ILLEGAL_REQ:
case SG_LIB_CAT_UNIT_ATTENTION:
case SG_LIB_CAT_ABORTED_COMMAND:
ret = sense_cat;
break;
case SG_LIB_CAT_RECOVERED:
case SG_LIB_CAT_NO_SENSE:
ret = 0;
break;
default:
ret = -1;
break;
}
} else {
if ((verbose > 2) && (ret > 0)) {
fprintf(sg_warnings_strm, " report identifying information: "
"response%s\n", (ret > 256 ? ", first 256 bytes" : ""));
dStrHexErr((const char *)resp, (ret > 256 ? 256 : ret), -1);
}
ret = 0;
}
destruct_scsi_pt_obj(ptvp);
return ret;
}
/* Invokes a SCSI SET IDENTIFYING INFORMATION command. This command was
* called SET DEVICE IDENTIFIER prior to spc4r07. Return of 0 -> success,
* SG_LIB_CAT_INVALID_OP -> Set identifying information not supported,
* SG_LIB_CAT_ILLEGAL_REQ -> bad field in cdb, SG_LIB_CAT_UNIT_ATTENTION,
* SG_LIB_CAT_NOT_READY -> device not ready, SG_LIB_CAT_ABORTED_COMMAND,
* -1 -> other failure */
int
sg_ll_set_id_info(int sg_fd, int itype, void * paramp, int param_len,
int noisy, int verbose)
{
int k, res, ret, sense_cat;
unsigned char siiCmdBlk[MAINTENANCE_OUT_CMDLEN] = {MAINTENANCE_OUT_CMD,
SET_IDENTIFYING_INFORMATION_SA,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
unsigned char sense_b[SENSE_BUFF_LEN];
struct sg_pt_base * ptvp;
siiCmdBlk[6] = (param_len >> 24) & 0xff;
siiCmdBlk[7] = (param_len >> 16) & 0xff;
siiCmdBlk[8] = (param_len >> 8) & 0xff;
siiCmdBlk[9] = param_len & 0xff;
siiCmdBlk[10] |= (itype << 1) & 0xfe;
if (NULL == sg_warnings_strm)
sg_warnings_strm = stderr;
if (verbose) {
fprintf(sg_warnings_strm, " Set identifying information cdb: ");
for (k = 0; k < MAINTENANCE_OUT_CMDLEN; ++k)
fprintf(sg_warnings_strm, "%02x ", siiCmdBlk[k]);
fprintf(sg_warnings_strm, "\n");
if ((verbose > 1) && paramp && param_len) {
fprintf(sg_warnings_strm, " Set identifying information "
"parameter list:\n");
dStrHexErr((const char *)paramp, param_len, -1);
}
}
ptvp = construct_scsi_pt_obj();
if (NULL == ptvp) {
fprintf(sg_warnings_strm, "Set identifying information: out of "
"memory\n");
return -1;
}
set_scsi_pt_cdb(ptvp, siiCmdBlk, sizeof(siiCmdBlk));
set_scsi_pt_sense(ptvp, sense_b, sizeof(sense_b));
set_scsi_pt_data_out(ptvp, (unsigned char *)paramp, param_len);
res = do_scsi_pt(ptvp, sg_fd, DEF_PT_TIMEOUT, verbose);
ret = sg_cmds_process_resp(ptvp, "set identifying information", res, 0,
sense_b, noisy, verbose, &sense_cat);
if (-1 == ret)
;
else if (-2 == ret) {
switch (sense_cat) {
case SG_LIB_CAT_NOT_READY:
case SG_LIB_CAT_INVALID_OP:
case SG_LIB_CAT_ILLEGAL_REQ:
case SG_LIB_CAT_UNIT_ATTENTION:
case SG_LIB_CAT_ABORTED_COMMAND:
ret = sense_cat;
break;
case SG_LIB_CAT_RECOVERED:
case SG_LIB_CAT_NO_SENSE:
ret = 0;
break;
default:
ret = -1;
break;
}
} else
ret = 0;
destruct_scsi_pt_obj(ptvp);
return ret;
}
/* Invokes a FORMAT UNIT (SBC-3) command. Return of 0 -> success,
* SG_LIB_CAT_INVALID_OP -> Format unit not supported,
* SG_LIB_CAT_ILLEGAL_REQ -> bad field in cdb, SG_LIB_CAT_UNIT_ATTENTION,
* SG_LIB_CAT_NOT_READY -> device not ready, SG_LIB_CAT_ABORTED_COMMAND,
* -1 -> other failure */
int
sg_ll_format_unit(int sg_fd, int fmtpinfo, int longlist, int fmtdata,
int cmplst, int dlist_format, int timeout_secs,
void * paramp, int param_len, int noisy, int verbose)
{
int k, res, ret, sense_cat, tmout;
unsigned char fuCmdBlk[FORMAT_UNIT_CMDLEN] =
{FORMAT_UNIT_CMD, 0, 0, 0, 0, 0};
unsigned char sense_b[SENSE_BUFF_LEN];
struct sg_pt_base * ptvp;
if (fmtpinfo)
fuCmdBlk[1] |= (fmtpinfo << 6);
if (longlist)
fuCmdBlk[1] |= 0x20;
if (fmtdata)
fuCmdBlk[1] |= 0x10;
if (cmplst)
fuCmdBlk[1] |= 0x8;
if (dlist_format)
fuCmdBlk[1] |= (dlist_format & 0x7);
if (NULL == sg_warnings_strm)
sg_warnings_strm = stderr;
tmout = (timeout_secs > 0) ? timeout_secs : DEF_PT_TIMEOUT;
if (verbose) {
fprintf(sg_warnings_strm, " format cdb: ");
for (k = 0; k < 6; ++k)
fprintf(sg_warnings_strm, "%02x ", fuCmdBlk[k]);
fprintf(sg_warnings_strm, "\n");
}
if ((verbose > 1) && (param_len > 0)) {
fprintf(sg_warnings_strm, " format parameter list:\n");
dStrHexErr((const char *)paramp, param_len, -1);
}
ptvp = construct_scsi_pt_obj();
if (NULL == ptvp) {
fprintf(sg_warnings_strm, "format unit: out of memory\n");
return -1;
}
set_scsi_pt_cdb(ptvp, fuCmdBlk, sizeof(fuCmdBlk));
set_scsi_pt_sense(ptvp, sense_b, sizeof(sense_b));
set_scsi_pt_data_out(ptvp, (unsigned char *)paramp, param_len);
res = do_scsi_pt(ptvp, sg_fd, tmout, verbose);
ret = sg_cmds_process_resp(ptvp, "format unit", res, 0, sense_b,
noisy, verbose, &sense_cat);
if (-1 == ret)
;
else if (-2 == ret) {
switch (sense_cat) {
case SG_LIB_CAT_NOT_READY:
case SG_LIB_CAT_INVALID_OP:
case SG_LIB_CAT_ILLEGAL_REQ:
case SG_LIB_CAT_UNIT_ATTENTION:
case SG_LIB_CAT_ABORTED_COMMAND:
ret = sense_cat;
break;
case SG_LIB_CAT_RECOVERED:
case SG_LIB_CAT_NO_SENSE:
ret = 0;
break;
default:
ret = -1;
break;
}
} else
ret = 0;
destruct_scsi_pt_obj(ptvp);
return ret;
}
/* Invokes a SCSI REASSIGN BLOCKS command. Return of 0 -> success,
* SG_LIB_CAT_INVALID_OP -> invalid opcode, SG_LIB_CAT_UNIT_ATTENTION,
* SG_LIB_CAT_ILLEGAL_REQ -> bad field in cdb, SG_LIB_CAT_ABORTED_COMMAND,
* SG_LIB_CAT_NOT_READY -> device not ready, -1 -> other failure */
int
sg_ll_reassign_blocks(int sg_fd, int longlba, int longlist, void * paramp,
int param_len, int noisy, int verbose)
{
int res, k, ret, sense_cat;
unsigned char reassCmdBlk[REASSIGN_BLKS_CMDLEN] =
{REASSIGN_BLKS_CMD, 0, 0, 0, 0, 0};
unsigned char sense_b[SENSE_BUFF_LEN];
struct sg_pt_base * ptvp;
reassCmdBlk[1] = (unsigned char)(((longlba << 1) & 0x2) |
(longlist & 0x1));
if (NULL == sg_warnings_strm)
sg_warnings_strm = stderr;
if (verbose) {
fprintf(sg_warnings_strm, " reassign blocks cdb: ");
for (k = 0; k < REASSIGN_BLKS_CMDLEN; ++k)
fprintf(sg_warnings_strm, "%02x ", reassCmdBlk[k]);
fprintf(sg_warnings_strm, "\n");
}
if (verbose > 1) {
fprintf(sg_warnings_strm, " reassign blocks parameter list\n");
dStrHexErr((const char *)paramp, param_len, -1);
}
ptvp = construct_scsi_pt_obj();
if (NULL == ptvp) {
fprintf(sg_warnings_strm, "reassign blocks: out of memory\n");
return -1;
}
set_scsi_pt_cdb(ptvp, reassCmdBlk, sizeof(reassCmdBlk));
set_scsi_pt_sense(ptvp, sense_b, sizeof(sense_b));
set_scsi_pt_data_out(ptvp, (unsigned char *)paramp, param_len);
res = do_scsi_pt(ptvp, sg_fd, DEF_PT_TIMEOUT, verbose);
ret = sg_cmds_process_resp(ptvp, "reassign blocks", res, 0, sense_b,
noisy, verbose, &sense_cat);
if (-1 == ret)
;
else if (-2 == ret) {
switch (sense_cat) {
case SG_LIB_CAT_NOT_READY:
case SG_LIB_CAT_INVALID_OP:
case SG_LIB_CAT_ILLEGAL_REQ:
case SG_LIB_CAT_UNIT_ATTENTION:
case SG_LIB_CAT_ABORTED_COMMAND:
ret = sense_cat;
break;
case SG_LIB_CAT_RECOVERED:
case SG_LIB_CAT_NO_SENSE:
ret = 0;
break;
default:
ret = -1;
break;
}
} else
ret = 0;
destruct_scsi_pt_obj(ptvp);
return ret;
}
/* Invokes a SCSI PERSISTENT RESERVE IN command (SPC). Returns 0
* when successful, SG_LIB_CAT_INVALID_OP if command not supported,
* SG_LIB_CAT_ILLEGAL_REQ if field in cdb not supported,
* SG_LIB_CAT_UNIT_ATTENTION, SG_LIB_CAT_ABORTED_COMMAND, else -1 */
int
sg_ll_persistent_reserve_in(int sg_fd, int rq_servact, void * resp,
int mx_resp_len, int noisy, int verbose)
{
int res, k, ret, sense_cat;
unsigned char prinCmdBlk[PERSISTENT_RESERVE_IN_CMDLEN] =
{PERSISTENT_RESERVE_IN_CMD, 0, 0, 0, 0, 0, 0, 0, 0, 0};
unsigned char sense_b[SENSE_BUFF_LEN];
struct sg_pt_base * ptvp;
if (rq_servact > 0)
prinCmdBlk[1] = (unsigned char)(rq_servact & 0x1f);
prinCmdBlk[7] = (unsigned char)((mx_resp_len >> 8) & 0xff);
prinCmdBlk[8] = (unsigned char)(mx_resp_len & 0xff);
if (NULL == sg_warnings_strm)
sg_warnings_strm = stderr;
if (verbose) {
fprintf(sg_warnings_strm, " Persistent Reservation In cmd: ");
for (k = 0; k < PERSISTENT_RESERVE_IN_CMDLEN; ++k)
fprintf(sg_warnings_strm, "%02x ", prinCmdBlk[k]);
fprintf(sg_warnings_strm, "\n");
}
ptvp = construct_scsi_pt_obj();
if (NULL == ptvp) {
fprintf(sg_warnings_strm, "persistent reservation in: out of "
"memory\n");
return -1;
}
set_scsi_pt_cdb(ptvp, prinCmdBlk, sizeof(prinCmdBlk));
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, sg_fd, DEF_PT_TIMEOUT, verbose);
ret = sg_cmds_process_resp(ptvp, "persistent reservation in", res,
mx_resp_len, sense_b, noisy, verbose,
&sense_cat);
if (-1 == ret)
;
else if (-2 == ret) {
switch (sense_cat) {
case SG_LIB_CAT_INVALID_OP:
case SG_LIB_CAT_ILLEGAL_REQ:
case SG_LIB_CAT_UNIT_ATTENTION:
case SG_LIB_CAT_ABORTED_COMMAND:
ret = sense_cat;
break;
case SG_LIB_CAT_RECOVERED:
case SG_LIB_CAT_NO_SENSE:
ret = 0;
break;
default:
ret = -1;
break;
}
} else {
if ((verbose > 2) && (ret > 0)) {
fprintf(sg_warnings_strm, " persistent reserve in: "
"response%s\n", (ret > 256 ? ", first 256 bytes" : ""));
dStrHexErr((const char *)resp, (ret > 256 ? 256 : ret), -1);
}
ret = 0;
}
destruct_scsi_pt_obj(ptvp);
return ret;
}
/* Invokes a SCSI PERSISTENT RESERVE OUT command (SPC). Returns 0
* when successful, SG_LIB_CAT_INVALID_OP if command not supported,
* SG_LIB_CAT_ILLEGAL_REQ if field in cdb not supported,
* SG_LIB_CAT_UNIT_ATTENTION, SG_LIB_CAT_ABORTED_COMMAND, else -1 */
int
sg_ll_persistent_reserve_out(int sg_fd, int rq_servact, int rq_scope,
unsigned int rq_type, void * paramp,
int param_len, int noisy, int verbose)
{
int res, k, ret, sense_cat;
unsigned char proutCmdBlk[PERSISTENT_RESERVE_OUT_CMDLEN] =
{PERSISTENT_RESERVE_OUT_CMD, 0, 0, 0, 0, 0, 0, 0, 0, 0};
unsigned char sense_b[SENSE_BUFF_LEN];
struct sg_pt_base * ptvp;
if (rq_servact > 0)
proutCmdBlk[1] = (unsigned char)(rq_servact & 0x1f);
proutCmdBlk[2] = (((rq_scope & 0xf) << 4) | (rq_type & 0xf));
proutCmdBlk[7] = (unsigned char)((param_len >> 8) & 0xff);
proutCmdBlk[8] = (unsigned char)(param_len & 0xff);
if (NULL == sg_warnings_strm)
sg_warnings_strm = stderr;
if (verbose) {
fprintf(sg_warnings_strm, " Persistent Reservation Out cmd: ");
for (k = 0; k < PERSISTENT_RESERVE_OUT_CMDLEN; ++k)
fprintf(sg_warnings_strm, "%02x ", proutCmdBlk[k]);
fprintf(sg_warnings_strm, "\n");
if (verbose > 1) {
fprintf(sg_warnings_strm, " Persistent Reservation Out "
"parameters:\n");
dStrHexErr((const char *)paramp, param_len, 0);
}
}
ptvp = construct_scsi_pt_obj();
if (NULL == ptvp) {
fprintf(sg_warnings_strm, "persistent reserve out: out of memory\n");
return -1;
}
set_scsi_pt_cdb(ptvp, proutCmdBlk, sizeof(proutCmdBlk));
set_scsi_pt_sense(ptvp, sense_b, sizeof(sense_b));
set_scsi_pt_data_out(ptvp, (unsigned char *)paramp, param_len);
res = do_scsi_pt(ptvp, sg_fd, DEF_PT_TIMEOUT, verbose);
ret = sg_cmds_process_resp(ptvp, "persistent reserve out", res, 0,
sense_b, noisy, verbose, &sense_cat);
if (-1 == ret)
;
else if (-2 == ret) {
switch (sense_cat) {
case SG_LIB_CAT_INVALID_OP:
case SG_LIB_CAT_ILLEGAL_REQ:
case SG_LIB_CAT_UNIT_ATTENTION:
case SG_LIB_CAT_ABORTED_COMMAND:
ret = sense_cat;
break;
case SG_LIB_CAT_RECOVERED:
case SG_LIB_CAT_NO_SENSE:
ret = 0;
break;
default:
ret = -1;
break;
}
} else
ret = 0;
destruct_scsi_pt_obj(ptvp);
return ret;
}
static int
has_blk_ili(unsigned char * sensep, int sb_len)
{
int resp_code;
const unsigned char * cup;
if (sb_len < 8)
return 0;
resp_code = (0x7f & sensep[0]);
if (resp_code >= 0x72) { /* descriptor format */
/* find block command descriptor */
if ((cup = sg_scsi_sense_desc_find(sensep, sb_len, 0x5)))
return ((cup[3] & 0x20) ? 1 : 0);
} else /* fixed */
return ((sensep[2] & 0x20) ? 1 : 0);
return 0;
}
/* Invokes a SCSI READ LONG (10) command (SBC). Note that 'xfer_len'
* is in bytes. Returns 0 -> success,
* SG_LIB_CAT_INVALID_OP -> READ LONG(10) not supported,
* SG_LIB_CAT_ILLEGAL_REQ -> bad field in cdb,
* SG_LIB_CAT_ILLEGAL_REQ_WITH_INFO -> bad field in cdb, with info
* field written to 'offsetp', SG_LIB_CAT_ABORTED_COMMAND,
* SG_LIB_CAT_NOT_READY -> device not ready, -1 -> other failure */
int
sg_ll_read_long10(int sg_fd, int pblock, int correct, unsigned int lba,
void * resp, int xfer_len, int * offsetp, int noisy,
int verbose)
{
int k, res, sense_cat, ret;
unsigned char readLongCmdBlk[READ_LONG10_CMDLEN];
unsigned char sense_b[SENSE_BUFF_LEN];
struct sg_pt_base * ptvp;
memset(readLongCmdBlk, 0, READ_LONG10_CMDLEN);
readLongCmdBlk[0] = READ_LONG10_CMD;
if (pblock)
readLongCmdBlk[1] |= 0x4;
if (correct)
readLongCmdBlk[1] |= 0x2;
readLongCmdBlk[2] = (lba >> 24) & 0xff;
readLongCmdBlk[3] = (lba >> 16) & 0xff;
readLongCmdBlk[4] = (lba >> 8) & 0xff;
readLongCmdBlk[5] = lba & 0xff;
readLongCmdBlk[7] = (xfer_len >> 8) & 0xff;
readLongCmdBlk[8] = xfer_len & 0xff;
if (NULL == sg_warnings_strm)
sg_warnings_strm = stderr;
if (verbose) {
fprintf(sg_warnings_strm, " Read Long (10) cmd: ");
for (k = 0; k < READ_LONG10_CMDLEN; ++k)
fprintf(sg_warnings_strm, "%02x ", readLongCmdBlk[k]);
fprintf(sg_warnings_strm, "\n");
}
ptvp = construct_scsi_pt_obj();
if (NULL == ptvp) {
fprintf(sg_warnings_strm, "read long (10): out of memory\n");
return -1;
}
set_scsi_pt_cdb(ptvp, readLongCmdBlk, sizeof(readLongCmdBlk));
set_scsi_pt_sense(ptvp, sense_b, sizeof(sense_b));
set_scsi_pt_data_in(ptvp, (unsigned char *)resp, xfer_len);
res = do_scsi_pt(ptvp, sg_fd, DEF_PT_TIMEOUT, verbose);
ret = sg_cmds_process_resp(ptvp, "read long (10)", res, xfer_len,
sense_b, noisy, verbose, &sense_cat);
if (-1 == ret)
;
else if (-2 == ret) {
switch (sense_cat) {
case SG_LIB_CAT_NOT_READY:
case SG_LIB_CAT_INVALID_OP:
case SG_LIB_CAT_UNIT_ATTENTION:
case SG_LIB_CAT_ABORTED_COMMAND:
ret = sense_cat;
break;
case SG_LIB_CAT_RECOVERED:
case SG_LIB_CAT_NO_SENSE:
ret = 0;
break;
case SG_LIB_CAT_ILLEGAL_REQ:
{
int valid, slen, ili;
uint64_t ull = 0;
slen = get_scsi_pt_sense_len(ptvp);
valid = sg_get_sense_info_fld(sense_b, slen, &ull);
ili = has_blk_ili(sense_b, slen);
if (valid && ili) {
if (offsetp)
*offsetp = (int)(int64_t)ull;
ret = SG_LIB_CAT_ILLEGAL_REQ_WITH_INFO;
} else {
if (verbose > 1)
fprintf(sg_warnings_strm, " info field: 0x%" PRIx64
", valid: %d, ili: %d\n", ull, valid, ili);
ret = SG_LIB_CAT_ILLEGAL_REQ;
}
}
break;
default:
ret = -1;
break;
}
} else {
if ((verbose > 2) && (ret > 0)) {
fprintf(sg_warnings_strm, " read long(10): response%s\n",
(ret > 256 ? ", first 256 bytes" : ""));
dStrHexErr((const char *)resp, (ret > 256 ? 256 : ret), -1);
}
ret = 0;
}
destruct_scsi_pt_obj(ptvp);
return ret;
}
/* Invokes a SCSI READ LONG (16) command (SBC). Note that 'xfer_len'
* is in bytes. Returns 0 -> success,
* SG_LIB_CAT_INVALID_OP -> READ LONG(16) not supported,
* SG_LIB_CAT_ILLEGAL_REQ -> bad field in cdb,
* SG_LIB_CAT_ILLEGAL_REQ_WITH_INFO -> bad field in cdb, with info
* field written to 'offsetp', SG_LIB_CAT_ABORTED_COMMAND,
* SG_LIB_CAT_NOT_READY -> device not ready, -1 -> other failure */
int
sg_ll_read_long16(int sg_fd, int pblock, int correct, uint64_t llba,
void * resp, int xfer_len, int * offsetp, int noisy,
int verbose)
{
int k, res, sense_cat, ret;
unsigned char readLongCmdBlk[SERVICE_ACTION_IN_16_CMDLEN];
unsigned char sense_b[SENSE_BUFF_LEN];
struct sg_pt_base * ptvp;
memset(readLongCmdBlk, 0, sizeof(readLongCmdBlk));
readLongCmdBlk[0] = SERVICE_ACTION_IN_16_CMD;
readLongCmdBlk[1] = READ_LONG_16_SA;
if (pblock)
readLongCmdBlk[14] |= 0x2;
if (correct)
readLongCmdBlk[14] |= 0x1;
readLongCmdBlk[2] = (llba >> 56) & 0xff;
readLongCmdBlk[3] = (llba >> 48) & 0xff;
readLongCmdBlk[4] = (llba >> 40) & 0xff;
readLongCmdBlk[5] = (llba >> 32) & 0xff;
readLongCmdBlk[6] = (llba >> 24) & 0xff;
readLongCmdBlk[7] = (llba >> 16) & 0xff;
readLongCmdBlk[8] = (llba >> 8) & 0xff;
readLongCmdBlk[9] = llba & 0xff;
readLongCmdBlk[12] = (xfer_len >> 8) & 0xff;
readLongCmdBlk[13] = xfer_len & 0xff;
if (NULL == sg_warnings_strm)
sg_warnings_strm = stderr;
if (verbose) {
fprintf(sg_warnings_strm, " Read Long (16) cmd: ");
for (k = 0; k < SERVICE_ACTION_IN_16_CMDLEN; ++k)
fprintf(sg_warnings_strm, "%02x ", readLongCmdBlk[k]);
fprintf(sg_warnings_strm, "\n");
}
ptvp = construct_scsi_pt_obj();
if (NULL == ptvp) {
fprintf(sg_warnings_strm, "read long (16): out of memory\n");
return -1;
}
set_scsi_pt_cdb(ptvp, readLongCmdBlk, sizeof(readLongCmdBlk));
set_scsi_pt_sense(ptvp, sense_b, sizeof(sense_b));
set_scsi_pt_data_in(ptvp, (unsigned char *)resp, xfer_len);
res = do_scsi_pt(ptvp, sg_fd, DEF_PT_TIMEOUT, verbose);
ret = sg_cmds_process_resp(ptvp, "read long (16)", res, xfer_len,
sense_b, noisy, verbose, &sense_cat);
if (-1 == ret)
;
else if (-2 == ret) {
switch (sense_cat) {
case SG_LIB_CAT_NOT_READY:
case SG_LIB_CAT_INVALID_OP:
case SG_LIB_CAT_UNIT_ATTENTION:
case SG_LIB_CAT_ABORTED_COMMAND:
ret = sense_cat;
break;
case SG_LIB_CAT_RECOVERED:
case SG_LIB_CAT_NO_SENSE:
ret = 0;
break;
case SG_LIB_CAT_ILLEGAL_REQ:
{
int valid, slen, ili;
uint64_t ull = 0;
slen = get_scsi_pt_sense_len(ptvp);
valid = sg_get_sense_info_fld(sense_b, slen, &ull);
ili = has_blk_ili(sense_b, slen);
if (valid && ili) {
if (offsetp)
*offsetp = (int)(int64_t)ull;
ret = SG_LIB_CAT_ILLEGAL_REQ_WITH_INFO;
} else {
if (verbose > 1)
fprintf(sg_warnings_strm, " info field: 0x%" PRIx64
", valid: %d, ili: %d\n", ull, valid, ili);
ret = SG_LIB_CAT_ILLEGAL_REQ;
}
}
break;
default:
ret = -1;
break;
}
} else {
if ((verbose > 2) && (ret > 0)) {
fprintf(sg_warnings_strm, " read long(16): response%s\n",
(ret > 256 ? ", first 256 bytes" : ""));
dStrHexErr((const char *)resp, (ret > 256 ? 256 : ret), -1);
}
ret = 0;
}
destruct_scsi_pt_obj(ptvp);
return ret;
}
/* Invokes a SCSI WRITE LONG (10) command (SBC). Note that 'xfer_len'
* is in bytes. Returns 0 -> success,
* SG_LIB_CAT_INVALID_OP -> WRITE LONG(10) not supported,
* SG_LIB_CAT_ILLEGAL_REQ -> bad field in cdb,
* SG_LIB_CAT_ILLEGAL_REQ_WITH_INFO -> bad field in cdb, with info
* field written to 'offsetp', SG_LIB_CAT_UNIT_ATTENTION,
* SG_LIB_CAT_NOT_READY -> device not ready,
* SG_LIB_CAT_ABORTED_COMMAND, -1 -> other failure */
int
sg_ll_write_long10(int sg_fd, int cor_dis, int wr_uncor, int pblock,
unsigned int lba, void * data_out, int xfer_len,
int * offsetp, int noisy, int verbose)
{
int k, res, sense_cat, ret;
unsigned char writeLongCmdBlk[WRITE_LONG10_CMDLEN];
unsigned char sense_b[SENSE_BUFF_LEN];
struct sg_pt_base * ptvp;
memset(writeLongCmdBlk, 0, WRITE_LONG10_CMDLEN);
writeLongCmdBlk[0] = WRITE_LONG10_CMD;
if (cor_dis)
writeLongCmdBlk[1] |= 0x80;
if (wr_uncor)
writeLongCmdBlk[1] |= 0x40;
if (pblock)
writeLongCmdBlk[1] |= 0x20;
writeLongCmdBlk[2] = (lba >> 24) & 0xff;
writeLongCmdBlk[3] = (lba >> 16) & 0xff;
writeLongCmdBlk[4] = (lba >> 8) & 0xff;
writeLongCmdBlk[5] = lba & 0xff;
writeLongCmdBlk[7] = (xfer_len >> 8) & 0xff;
writeLongCmdBlk[8] = xfer_len & 0xff;
if (NULL == sg_warnings_strm)
sg_warnings_strm = stderr;
if (verbose) {
fprintf(sg_warnings_strm, " Write Long (10) cmd: ");
for (k = 0; k < (int)sizeof(writeLongCmdBlk); ++k)
fprintf(sg_warnings_strm, "%02x ", writeLongCmdBlk[k]);
fprintf(sg_warnings_strm, "\n");
}
ptvp = construct_scsi_pt_obj();
if (NULL == ptvp) {
fprintf(sg_warnings_strm, "write long(10): out of memory\n");
return -1;
}
set_scsi_pt_cdb(ptvp, writeLongCmdBlk, sizeof(writeLongCmdBlk));
set_scsi_pt_sense(ptvp, sense_b, sizeof(sense_b));
set_scsi_pt_data_out(ptvp, (unsigned char *)data_out, xfer_len);
res = do_scsi_pt(ptvp, sg_fd, DEF_PT_TIMEOUT, verbose);
ret = sg_cmds_process_resp(ptvp, "write long(10)", res, 0, sense_b,
noisy, verbose, &sense_cat);
if (-1 == ret)
;
else if (-2 == ret) {
switch (sense_cat) {
case SG_LIB_CAT_NOT_READY:
case SG_LIB_CAT_UNIT_ATTENTION:
case SG_LIB_CAT_INVALID_OP:
case SG_LIB_CAT_ABORTED_COMMAND:
ret = sense_cat;
break;
case SG_LIB_CAT_RECOVERED:
case SG_LIB_CAT_NO_SENSE:
ret = 0;
break;
case SG_LIB_CAT_ILLEGAL_REQ:
{
int valid, slen, ili;
uint64_t ull = 0;
slen = get_scsi_pt_sense_len(ptvp);
valid = sg_get_sense_info_fld(sense_b, slen, &ull);
ili = has_blk_ili(sense_b, slen);
if (valid && ili) {
if (offsetp)
*offsetp = (int)(int64_t)ull;
ret = SG_LIB_CAT_ILLEGAL_REQ_WITH_INFO;
} else {
if (verbose > 1)
fprintf(sg_warnings_strm, " info field: 0x%" PRIx64
", valid: %d, ili: %d\n", ull, valid, ili);
ret = SG_LIB_CAT_ILLEGAL_REQ;
}
}
break;
default:
ret = -1;
break;
}
} else
ret = 0;
destruct_scsi_pt_obj(ptvp);
return ret;
}
/* Invokes a SCSI WRITE LONG (16) command (SBC). Note that 'xfer_len'
* is in bytes. Returns 0 -> success,
* SG_LIB_CAT_INVALID_OP -> WRITE LONG(16) not supported,
* SG_LIB_CAT_ILLEGAL_REQ -> bad field in cdb,
* SG_LIB_CAT_ILLEGAL_REQ_WITH_INFO -> bad field in cdb, with info
* field written to 'offsetp', SG_LIB_CAT_UNIT_ATTENTION,
* SG_LIB_CAT_NOT_READY -> device not ready,
* SG_LIB_CAT_ABORTED_COMMAND, -1 -> other failure */
int
sg_ll_write_long16(int sg_fd, int cor_dis, int wr_uncor, int pblock,
uint64_t llba, void * data_out, int xfer_len,
int * offsetp, int noisy, int verbose)
{
int k, res, sense_cat, ret;
unsigned char writeLongCmdBlk[SERVICE_ACTION_OUT_16_CMDLEN];
unsigned char sense_b[SENSE_BUFF_LEN];
struct sg_pt_base * ptvp;
memset(writeLongCmdBlk, 0, sizeof(writeLongCmdBlk));
writeLongCmdBlk[0] = SERVICE_ACTION_OUT_16_CMD;
writeLongCmdBlk[1] = WRITE_LONG_16_SA;
if (cor_dis)
writeLongCmdBlk[1] |= 0x80;
if (wr_uncor)
writeLongCmdBlk[1] |= 0x40;
if (pblock)
writeLongCmdBlk[1] |= 0x20;
writeLongCmdBlk[2] = (llba >> 56) & 0xff;
writeLongCmdBlk[3] = (llba >> 48) & 0xff;
writeLongCmdBlk[4] = (llba >> 40) & 0xff;
writeLongCmdBlk[5] = (llba >> 32) & 0xff;
writeLongCmdBlk[6] = (llba >> 24) & 0xff;
writeLongCmdBlk[7] = (llba >> 16) & 0xff;
writeLongCmdBlk[8] = (llba >> 8) & 0xff;
writeLongCmdBlk[9] = llba & 0xff;
writeLongCmdBlk[12] = (xfer_len >> 8) & 0xff;
writeLongCmdBlk[13] = xfer_len & 0xff;
if (NULL == sg_warnings_strm)
sg_warnings_strm = stderr;
if (verbose) {
fprintf(sg_warnings_strm, " Write Long (16) cmd: ");
for (k = 0; k < SERVICE_ACTION_OUT_16_CMDLEN; ++k)
fprintf(sg_warnings_strm, "%02x ", writeLongCmdBlk[k]);
fprintf(sg_warnings_strm, "\n");
}
ptvp = construct_scsi_pt_obj();
if (NULL == ptvp) {
fprintf(sg_warnings_strm, "write long(16): out of memory\n");
return -1;
}
set_scsi_pt_cdb(ptvp, writeLongCmdBlk, sizeof(writeLongCmdBlk));
set_scsi_pt_sense(ptvp, sense_b, sizeof(sense_b));
set_scsi_pt_data_out(ptvp, (unsigned char *)data_out, xfer_len);
res = do_scsi_pt(ptvp, sg_fd, DEF_PT_TIMEOUT, verbose);
ret = sg_cmds_process_resp(ptvp, "write long(16)", res, 0, sense_b,
noisy, verbose, &sense_cat);
if (-1 == ret)
;
else if (-2 == ret) {
switch (sense_cat) {
case SG_LIB_CAT_NOT_READY:
case SG_LIB_CAT_UNIT_ATTENTION:
case SG_LIB_CAT_INVALID_OP:
case SG_LIB_CAT_ABORTED_COMMAND:
ret = sense_cat;
break;
case SG_LIB_CAT_RECOVERED:
case SG_LIB_CAT_NO_SENSE:
ret = 0;
break;
case SG_LIB_CAT_ILLEGAL_REQ:
{
int valid, slen, ili;
uint64_t ull = 0;
slen = get_scsi_pt_sense_len(ptvp);
valid = sg_get_sense_info_fld(sense_b, slen, &ull);
ili = has_blk_ili(sense_b, slen);
if (valid && ili) {
if (offsetp)
*offsetp = (int)(int64_t)ull;
ret = SG_LIB_CAT_ILLEGAL_REQ_WITH_INFO;
} else {
if (verbose > 1)
fprintf(sg_warnings_strm, " info field: 0x%" PRIx64
", valid: %d, ili: %d\n", ull, valid, ili);
ret = SG_LIB_CAT_ILLEGAL_REQ;
}
}
break;
default:
ret = -1;
break;
}
} else
ret = 0;
destruct_scsi_pt_obj(ptvp);
return ret;
}
/* Invokes a SCSI VERIFY (10) command (SBC and MMC).
* Note that 'veri_len' is in blocks while 'data_out_len' is in bytes.
* Returns of 0 -> success,
* SG_LIB_CAT_INVALID_OP -> Verify(10) not supported,
* SG_LIB_CAT_ILLEGAL_REQ -> bad field in cdb, SG_LIB_CAT_UNIT_ATTENTION,
* SG_LIB_CAT_MEDIUM_HARD -> medium or hardware error, no valid info,
* SG_LIB_CAT_MEDIUM_HARD_WITH_INFO -> as previous, with valid info,
* SG_LIB_CAT_NOT_READY -> device not ready, SG_LIB_CAT_ABORTED_COMMAND,
* SG_LIB_CAT_MISCOMPARE, -1 -> other failure */
int
sg_ll_verify10(int sg_fd, int vrprotect, int dpo, int bytchk,
unsigned int lba, int veri_len, void * data_out,
int data_out_len, unsigned int * infop, int noisy,
int verbose)
{
int k, res, ret, sense_cat, slen;
unsigned char vCmdBlk[VERIFY10_CMDLEN] =
{VERIFY10_CMD, 0, 0, 0, 0, 0, 0, 0, 0, 0};
unsigned char sense_b[SENSE_BUFF_LEN];
struct sg_pt_base * ptvp;
/* N.B. BYTCHK field expanded to 2 bits sbc3r34 */
vCmdBlk[1] = ((vrprotect & 0x7) << 5) | ((dpo & 0x1) << 4) |
((bytchk & 0x3) << 1) ;
vCmdBlk[2] = (unsigned char)((lba >> 24) & 0xff);
vCmdBlk[3] = (unsigned char)((lba >> 16) & 0xff);
vCmdBlk[4] = (unsigned char)((lba >> 8) & 0xff);
vCmdBlk[5] = (unsigned char)(lba & 0xff);
vCmdBlk[7] = (unsigned char)((veri_len >> 8) & 0xff);
vCmdBlk[8] = (unsigned char)(veri_len & 0xff);
if (NULL == sg_warnings_strm)
sg_warnings_strm = stderr;
if (verbose > 1) {
fprintf(sg_warnings_strm, " Verify(10) cdb: ");
for (k = 0; k < VERIFY10_CMDLEN; ++k)
fprintf(sg_warnings_strm, "%02x ", vCmdBlk[k]);
fprintf(sg_warnings_strm, "\n");
if ((verbose > 3) && bytchk && data_out && (data_out_len > 0)) {
k = data_out_len > 4104 ? 4104 : data_out_len;
fprintf(sg_warnings_strm, " data_out buffer%s\n",
(data_out_len > 4104 ? ", first 4104 bytes" : ""));
dStrHexErr((const char *)data_out, k, verbose < 5);
}
}
ptvp = construct_scsi_pt_obj();
if (NULL == ptvp) {
fprintf(sg_warnings_strm, "verify (10): out of memory\n");
return -1;
}
set_scsi_pt_cdb(ptvp, vCmdBlk, sizeof(vCmdBlk));
set_scsi_pt_sense(ptvp, sense_b, sizeof(sense_b));
if (data_out_len > 0)
set_scsi_pt_data_out(ptvp, (unsigned char *)data_out, data_out_len);
res = do_scsi_pt(ptvp, sg_fd, DEF_PT_TIMEOUT, verbose);
ret = sg_cmds_process_resp(ptvp, "verify (10)", res, 0, sense_b,
noisy, verbose, &sense_cat);
if (-1 == ret)
;
else if (-2 == ret) {
switch (sense_cat) {
case SG_LIB_CAT_NOT_READY:
case SG_LIB_CAT_INVALID_OP:
case SG_LIB_CAT_ILLEGAL_REQ:
case SG_LIB_CAT_UNIT_ATTENTION:
case SG_LIB_CAT_ABORTED_COMMAND:
case SG_LIB_CAT_MISCOMPARE:
ret = sense_cat;
break;
case SG_LIB_CAT_RECOVERED:
case SG_LIB_CAT_NO_SENSE:
ret = 0;
break;
case SG_LIB_CAT_MEDIUM_HARD:
{
int valid;
uint64_t ull = 0;
slen = get_scsi_pt_sense_len(ptvp);
valid = sg_get_sense_info_fld(sense_b, slen, &ull);
if (valid) {
if (infop)
*infop = (unsigned int)ull;
ret = SG_LIB_CAT_MEDIUM_HARD_WITH_INFO;
} else
ret = SG_LIB_CAT_MEDIUM_HARD;
}
break;
default:
ret = -1;
break;
}
} else
ret = 0;
destruct_scsi_pt_obj(ptvp);
return ret;
}
/* Invokes a SCSI VERIFY (16) command (SBC and MMC).
* Note that 'veri_len' is in blocks while 'data_out_len' is in bytes.
* Returns of 0 -> success,
* SG_LIB_CAT_INVALID_OP -> Verify(16) not supported,
* SG_LIB_CAT_ILLEGAL_REQ -> bad field in cdb, SG_LIB_CAT_UNIT_ATTENTION,
* SG_LIB_CAT_MEDIUM_HARD -> medium or hardware error, no valid info,
* SG_LIB_CAT_MEDIUM_HARD_WITH_INFO -> as previous, with valid info,
* SG_LIB_CAT_NOT_READY -> device not ready, SG_LIB_CAT_ABORTED_COMMAND,
* SG_LIB_CAT_MISCOMPARE, -1 -> other failure */
int
sg_ll_verify16(int sg_fd, int vrprotect, int dpo, int bytchk, uint64_t llba,
int veri_len, int group_num, void * data_out,
int data_out_len, uint64_t * infop, int noisy, int verbose)
{
int k, res, ret, sense_cat, slen;
unsigned char vCmdBlk[VERIFY16_CMDLEN] =
{VERIFY16_CMD, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
unsigned char sense_b[SENSE_BUFF_LEN];
struct sg_pt_base * ptvp;
/* N.B. BYTCHK field expanded to 2 bits sbc3r34 */
vCmdBlk[1] = ((vrprotect & 0x7) << 5) | ((dpo & 0x1) << 4) |
((bytchk & 0x3) << 1) ;
vCmdBlk[2] = (llba >> 56) & 0xff;
vCmdBlk[3] = (llba >> 48) & 0xff;
vCmdBlk[4] = (llba >> 40) & 0xff;
vCmdBlk[5] = (llba >> 32) & 0xff;
vCmdBlk[6] = (llba >> 24) & 0xff;
vCmdBlk[7] = (llba >> 16) & 0xff;
vCmdBlk[8] = (llba >> 8) & 0xff;
vCmdBlk[9] = llba & 0xff;
vCmdBlk[10] = (veri_len >> 24) & 0xff;
vCmdBlk[11] = (veri_len >> 16) & 0xff;
vCmdBlk[12] = (veri_len >> 8) & 0xff;
vCmdBlk[13] = veri_len & 0xff;
vCmdBlk[14] = group_num & 0x1f;
if (NULL == sg_warnings_strm)
sg_warnings_strm = stderr;
if (verbose > 1) {
fprintf(sg_warnings_strm, " Verify(16) cdb: ");
for (k = 0; k < VERIFY16_CMDLEN; ++k)
fprintf(sg_warnings_strm, "%02x ", vCmdBlk[k]);
fprintf(sg_warnings_strm, "\n");
if ((verbose > 3) && bytchk && data_out && (data_out_len > 0)) {
k = data_out_len > 4104 ? 4104 : data_out_len;
fprintf(sg_warnings_strm, " data_out buffer%s\n",
(data_out_len > 4104 ? ", first 4104 bytes" : ""));
dStrHexErr((const char *)data_out, k, verbose < 5);
}
}
ptvp = construct_scsi_pt_obj();
if (NULL == ptvp) {
fprintf(sg_warnings_strm, "verify (16): out of memory\n");
return -1;
}
set_scsi_pt_cdb(ptvp, vCmdBlk, sizeof(vCmdBlk));
set_scsi_pt_sense(ptvp, sense_b, sizeof(sense_b));
if (data_out_len > 0)
set_scsi_pt_data_out(ptvp, (unsigned char *)data_out, data_out_len);
res = do_scsi_pt(ptvp, sg_fd, DEF_PT_TIMEOUT, verbose);
ret = sg_cmds_process_resp(ptvp, "verify (16)", res, 0, sense_b,
noisy, verbose, &sense_cat);
if (-1 == ret)
;
else if (-2 == ret) {
switch (sense_cat) {
case SG_LIB_CAT_NOT_READY:
case SG_LIB_CAT_INVALID_OP:
case SG_LIB_CAT_ILLEGAL_REQ:
case SG_LIB_CAT_UNIT_ATTENTION:
case SG_LIB_CAT_ABORTED_COMMAND:
case SG_LIB_CAT_MISCOMPARE:
ret = sense_cat;
break;
case SG_LIB_CAT_RECOVERED:
case SG_LIB_CAT_NO_SENSE:
ret = 0;
break;
case SG_LIB_CAT_MEDIUM_HARD:
{
int valid;
uint64_t ull = 0;
slen = get_scsi_pt_sense_len(ptvp);
valid = sg_get_sense_info_fld(sense_b, slen, &ull);
if (valid) {
if (infop)
*infop = ull;
ret = SG_LIB_CAT_MEDIUM_HARD_WITH_INFO;
} else
ret = SG_LIB_CAT_MEDIUM_HARD;
}
break;
default:
ret = -1;
break;
}
} else
ret = 0;
destruct_scsi_pt_obj(ptvp);
return ret;
}
/* Invokes a ATA PASS-THROUGH (12 or 16) SCSI command (SAT). If cdb_len
* is 12 then a ATA PASS-THROUGH (12) command is called. If cdb_len is 16
* then a ATA PASS-THROUGH (16) command is called. If cdb_len is any other
* value -1 is returned. After copying from cdbp to an internal buffer,
* the first byte (i.e. offset 0) is set to 0xa1 if cdb_len is 12; or is
* set to 0x85 if cdb_len is 16. The last byte (offset 11 or offset 15) is
* set to 0x0 in the internal buffer. If timeout_secs <= 0 then the timeout
* is set to 60 seconds. For data in or out transfers set dinp or doutp,
* and dlen to the number of bytes to transfer. If dlen is zero then no data
* transfer is assumed. If sense buffer obtained then it is written to
* sensep, else sensep[0] is set to 0x0. If ATA return descriptor is obtained
* then written to ata_return_dp, else ata_return_dp[0] is set to 0x0. Either
* sensep or ata_return_dp (or both) may be NULL pointers. Returns SCSI
* status value (>= 0) or -1 if other error. Users are expected to check the
* sense buffer themselves. If available the data in resid is written to
* residp. Note in SAT-2 and later, fixed format sense data may be placed in
* *sensep in which case sensep[0]==0x70 .
*/
int
sg_ll_ata_pt(int sg_fd, const unsigned char * cdbp, int cdb_len,
int timeout_secs, void * dinp, void * doutp, int dlen,
unsigned char * sensep, int max_sense_len,
unsigned char * ata_return_dp, int max_ata_return_len,
int * residp, int verbose)
{
int k, res, slen, duration;
unsigned char aptCmdBlk[ATA_PT_16_CMDLEN] =
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
unsigned char sense_b[SENSE_BUFF_LEN];
unsigned char * sp;
const unsigned char * ucp;
struct sg_pt_base * ptvp;
const char * cnamep;
char b[256];
int ret = -1;
b[0] = '\0';
if (NULL == sg_warnings_strm)
sg_warnings_strm = stderr;
cnamep = (12 == cdb_len) ?
"ATA pass through (12)" : "ATA pass through (16)";
if ((NULL == cdbp) || ((12 != cdb_len) && (16 != cdb_len))) {
if (verbose) {
if (NULL == cdbp)
fprintf(sg_warnings_strm, "%s NULL cdb pointer\n", cnamep);
else
fprintf(sg_warnings_strm, "cdb_len must be 12 or 16\n");
}
return -1;
}
aptCmdBlk[0] = (12 == cdb_len) ? ATA_PT_12_CMD : ATA_PT_16_CMD;
if (sensep && (max_sense_len >= (int)sizeof(sense_b))) {
sp = sensep;
slen = max_sense_len;
} else {
sp = sense_b;
slen = sizeof(sense_b);
}
if (12 == cdb_len)
memcpy(aptCmdBlk + 1, cdbp + 1, ((cdb_len > 11) ? 10 : (cdb_len - 1)));
else
memcpy(aptCmdBlk + 1, cdbp + 1, ((cdb_len > 15) ? 14 : (cdb_len - 1)));
if (verbose) {
fprintf(sg_warnings_strm, " %s cdb: ", cnamep);
for (k = 0; k < cdb_len; ++k)
fprintf(sg_warnings_strm, "%02x ", aptCmdBlk[k]);
fprintf(sg_warnings_strm, "\n");
}
ptvp = construct_scsi_pt_obj();
if (NULL == ptvp) {
fprintf(sg_warnings_strm, "%s: out of memory\n", cnamep);
return -1;
}
set_scsi_pt_cdb(ptvp, aptCmdBlk, cdb_len);
set_scsi_pt_sense(ptvp, sp, slen);
if (dlen > 0) {
if (dinp)
set_scsi_pt_data_in(ptvp, (unsigned char *)dinp, dlen);
else if (doutp)
set_scsi_pt_data_out(ptvp, (unsigned char *)doutp, dlen);
}
res = do_scsi_pt(ptvp, sg_fd,
((timeout_secs > 0) ? timeout_secs : DEF_PT_TIMEOUT),
verbose);
if (SCSI_PT_DO_BAD_PARAMS == res) {
if (verbose)
fprintf(sg_warnings_strm, "%s: bad parameters\n", cnamep);
goto out;
} else if (SCSI_PT_DO_TIMEOUT == res) {
if (verbose)
fprintf(sg_warnings_strm, "%s: timeout\n", cnamep);
goto out;
} else if (res > 2) {
if (verbose)
fprintf(sg_warnings_strm, "%s: do_scsi_pt: errno=%d\n",
cnamep, -res);
}
if ((verbose > 2) && ((duration = get_scsi_pt_duration_ms(ptvp)) >= 0))
fprintf(sg_warnings_strm, " duration=%d ms\n", duration);
switch (get_scsi_pt_result_category(ptvp)) {
case SCSI_PT_RESULT_GOOD:
if ((sensep) && (max_sense_len > 0))
*sensep = 0;
if ((ata_return_dp) && (max_ata_return_len > 0))
*ata_return_dp = 0;
if (residp && (dlen > 0))
*residp = get_scsi_pt_resid(ptvp);
ret = 0;
break;
case SCSI_PT_RESULT_STATUS: /* other than GOOD + CHECK CONDITION */
if ((sensep) && (max_sense_len > 0))
*sensep = 0;
if ((ata_return_dp) && (max_ata_return_len > 0))
*ata_return_dp = 0;
ret = get_scsi_pt_status_response(ptvp);
break;
case SCSI_PT_RESULT_SENSE:
if (sensep && (sp != sensep)) {
k = get_scsi_pt_sense_len(ptvp);
k = (k > max_sense_len) ? max_sense_len : k;
memcpy(sensep, sp, k);
}
if (ata_return_dp && (max_ata_return_len > 0)) {
/* search for ATA return descriptor */
ucp = sg_scsi_sense_desc_find(sp, slen, 0x9);
if (ucp) {
k = ucp[1] + 2;
k = (k > max_ata_return_len) ? max_ata_return_len : k;
memcpy(ata_return_dp, ucp, k);
} else
ata_return_dp[0] = 0x0;
}
if (residp && (dlen > 0))
*residp = get_scsi_pt_resid(ptvp);
ret = get_scsi_pt_status_response(ptvp);
break;
case SCSI_PT_RESULT_TRANSPORT_ERR:
if (verbose)
fprintf(sg_warnings_strm, "%s: transport error: %s\n",
cnamep, get_scsi_pt_transport_err_str(ptvp, sizeof(b) ,
b));
break;
case SCSI_PT_RESULT_OS_ERR:
if (verbose)
fprintf(sg_warnings_strm, "%s: os error: %s\n",
cnamep, get_scsi_pt_os_err_str(ptvp, sizeof(b) , b));
break;
default:
if (verbose)
fprintf(sg_warnings_strm, "%s: unknown pt_result_category=%d\n",
cnamep, get_scsi_pt_result_category(ptvp));
break;
}
out:
destruct_scsi_pt_obj(ptvp);
return ret;
}
/* Invokes a SCSI READ BUFFER command (SPC). Return of 0 ->
* success, SG_LIB_CAT_INVALID_OP -> invalid opcode,
* SG_LIB_CAT_ILLEGAL_REQ -> bad field in cdb, SG_LIB_CAT_UNIT_ATTENTION,
* SG_LIB_CAT_NOT_READY -> device not ready, SG_LIB_CAT_ABORTED_COMMAND,
* -1 -> other failure */
int
sg_ll_read_buffer(int sg_fd, int mode, int buffer_id, int buffer_offset,
void * resp, int mx_resp_len, int noisy, int verbose)
{
int res, k, ret, sense_cat;
unsigned char rbufCmdBlk[READ_BUFFER_CMDLEN] =
{READ_BUFFER_CMD, 0, 0, 0, 0, 0, 0, 0, 0, 0};
unsigned char sense_b[SENSE_BUFF_LEN];
struct sg_pt_base * ptvp;
rbufCmdBlk[1] = (unsigned char)(mode & 0x1f);
rbufCmdBlk[2] = (unsigned char)(buffer_id & 0xff);
rbufCmdBlk[3] = (unsigned char)((buffer_offset >> 16) & 0xff);
rbufCmdBlk[4] = (unsigned char)((buffer_offset >> 8) & 0xff);
rbufCmdBlk[5] = (unsigned char)(buffer_offset & 0xff);
rbufCmdBlk[6] = (unsigned char)((mx_resp_len >> 16) & 0xff);
rbufCmdBlk[7] = (unsigned char)((mx_resp_len >> 8) & 0xff);
rbufCmdBlk[8] = (unsigned char)(mx_resp_len & 0xff);
if (NULL == sg_warnings_strm)
sg_warnings_strm = stderr;
if (verbose) {
fprintf(sg_warnings_strm, " read buffer cdb: ");
for (k = 0; k < READ_BUFFER_CMDLEN; ++k)
fprintf(sg_warnings_strm, "%02x ", rbufCmdBlk[k]);
fprintf(sg_warnings_strm, "\n");
}
ptvp = construct_scsi_pt_obj();
if (NULL == ptvp) {
fprintf(sg_warnings_strm, "read buffer: out of memory\n");
return -1;
}
set_scsi_pt_cdb(ptvp, rbufCmdBlk, sizeof(rbufCmdBlk));
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, sg_fd, DEF_PT_TIMEOUT, verbose);
ret = sg_cmds_process_resp(ptvp, "read buffer", res, mx_resp_len,
sense_b, noisy, verbose, &sense_cat);
if (-1 == ret)
;
else if (-2 == ret) {
switch (sense_cat) {
case SG_LIB_CAT_NOT_READY:
case SG_LIB_CAT_INVALID_OP:
case SG_LIB_CAT_ILLEGAL_REQ:
case SG_LIB_CAT_UNIT_ATTENTION:
case SG_LIB_CAT_ABORTED_COMMAND:
ret = sense_cat;
break;
case SG_LIB_CAT_RECOVERED:
case SG_LIB_CAT_NO_SENSE:
ret = 0;
break;
default:
ret = -1;
break;
}
} else {
if ((verbose > 2) && (ret > 0)) {
fprintf(sg_warnings_strm, " read buffer: response%s\n",
(ret > 256 ? ", first 256 bytes" : ""));
dStrHexErr((const char *)resp, (ret > 256 ? 256 : ret), -1);
}
ret = 0;
}
destruct_scsi_pt_obj(ptvp);
return ret;
}
/* Invokes a SCSI WRITE BUFFER command (SPC). Return of 0 ->
* success, SG_LIB_CAT_INVALID_OP -> invalid opcode,
* SG_LIB_CAT_ILLEGAL_REQ -> bad field in cdb, SG_LIB_CAT_UNIT_ATTENTION,
* SG_LIB_CAT_NOT_READY -> device not ready, SG_LIB_CAT_ABORTED_COMMAND,
* -1 -> other failure */
int
sg_ll_write_buffer(int sg_fd, int mode, int buffer_id, int buffer_offset,
void * paramp, int param_len, int noisy, int verbose)
{
int k, res, ret, sense_cat;
unsigned char wbufCmdBlk[WRITE_BUFFER_CMDLEN] =
{WRITE_BUFFER_CMD, 0, 0, 0, 0, 0, 0, 0, 0, 0};
unsigned char sense_b[SENSE_BUFF_LEN];
struct sg_pt_base * ptvp;
wbufCmdBlk[1] = (unsigned char)(mode & 0x1f);
wbufCmdBlk[2] = (unsigned char)(buffer_id & 0xff);
wbufCmdBlk[3] = (unsigned char)((buffer_offset >> 16) & 0xff);
wbufCmdBlk[4] = (unsigned char)((buffer_offset >> 8) & 0xff);
wbufCmdBlk[5] = (unsigned char)(buffer_offset & 0xff);
wbufCmdBlk[6] = (unsigned char)((param_len >> 16) & 0xff);
wbufCmdBlk[7] = (unsigned char)((param_len >> 8) & 0xff);
wbufCmdBlk[8] = (unsigned char)(param_len & 0xff);
if (NULL == sg_warnings_strm)
sg_warnings_strm = stderr;
if (verbose) {
fprintf(sg_warnings_strm, " Write buffer cmd: ");
for (k = 0; k < WRITE_BUFFER_CMDLEN; ++k)
fprintf(sg_warnings_strm, "%02x ", wbufCmdBlk[k]);
fprintf(sg_warnings_strm, "\n");
if ((verbose > 1) && paramp && param_len) {
fprintf(sg_warnings_strm, " Write buffer parameter list%s:\n",
((param_len > 256) ? " (first 256 bytes)" : ""));
dStrHexErr((const char *)paramp,
((param_len > 256) ? 256 : param_len), -1);
}
}
ptvp = construct_scsi_pt_obj();
if (NULL == ptvp) {
fprintf(sg_warnings_strm, "write buffer: out of memory\n");
return -1;
}
set_scsi_pt_cdb(ptvp, wbufCmdBlk, sizeof(wbufCmdBlk));
set_scsi_pt_sense(ptvp, sense_b, sizeof(sense_b));
set_scsi_pt_data_out(ptvp, (unsigned char *)paramp, param_len);
res = do_scsi_pt(ptvp, sg_fd, DEF_PT_TIMEOUT, verbose);
ret = sg_cmds_process_resp(ptvp, "write buffer", res, 0, sense_b,
noisy, verbose, &sense_cat);
if (-1 == ret)
;
else if (-2 == ret) {
switch (sense_cat) {
case SG_LIB_CAT_NOT_READY:
case SG_LIB_CAT_INVALID_OP:
case SG_LIB_CAT_ILLEGAL_REQ:
case SG_LIB_CAT_UNIT_ATTENTION:
case SG_LIB_CAT_ABORTED_COMMAND:
ret = sense_cat;
break;
case SG_LIB_CAT_RECOVERED:
case SG_LIB_CAT_NO_SENSE:
ret = 0;
break;
default:
ret = -1;
break;
}
} else
ret = 0;
destruct_scsi_pt_obj(ptvp);
return ret;
}
/* Invokes a SCSI UNMAP command. Return of 0 -> success,
* SG_LIB_CAT_INVALID_OP -> command not supported,
* SG_LIB_CAT_ILLEGAL_REQ -> bad field in cdb, SG_LIB_CAT_ABORTED_COMMAND,
* SG_LIB_CAT_UNIT_ATTENTION, -1 -> other failure */
int
sg_ll_unmap(int sg_fd, int group_num, int timeout_secs, void * paramp,
int param_len, int noisy, int verbose)
{
return sg_ll_unmap_v2(sg_fd, 0, group_num, timeout_secs, paramp,
param_len, noisy, verbose);
}
/* Invokes a SCSI UNMAP (SBC-3) command. Version 2 adds anchor field
* (sbc3r22). Otherwise same as sg_ll_unmap() . */
int
sg_ll_unmap_v2(int sg_fd, int anchor, int group_num, int timeout_secs,
void * paramp, int param_len, int noisy, int verbose)
{
int k, res, ret, sense_cat, tmout;
unsigned char uCmdBlk[UNMAP_CMDLEN] =
{UNMAP_CMD, 0, 0, 0, 0, 0, 0, 0, 0, 0};
unsigned char sense_b[SENSE_BUFF_LEN];
struct sg_pt_base * ptvp;
if (anchor)
uCmdBlk[1] |= 0x1;
tmout = (timeout_secs > 0) ? timeout_secs : DEF_PT_TIMEOUT;
uCmdBlk[7] = group_num & 0x1f;
uCmdBlk[7] = (param_len >> 8) & 0xff;
uCmdBlk[8] = param_len & 0xff;
if (NULL == sg_warnings_strm)
sg_warnings_strm = stderr;
if (verbose) {
fprintf(sg_warnings_strm, " unmap cdb: ");
for (k = 0; k < UNMAP_CMDLEN; ++k)
fprintf(sg_warnings_strm, "%02x ", uCmdBlk[k]);
fprintf(sg_warnings_strm, "\n");
if ((verbose > 1) && paramp && param_len) {
fprintf(sg_warnings_strm, " unmap parameter list:\n");
dStrHexErr((const char *)paramp, param_len, -1);
}
}
ptvp = construct_scsi_pt_obj();
if (NULL == ptvp) {
fprintf(sg_warnings_strm, "unmap: out of memory\n");
return -1;
}
set_scsi_pt_cdb(ptvp, uCmdBlk, sizeof(uCmdBlk));
set_scsi_pt_sense(ptvp, sense_b, sizeof(sense_b));
set_scsi_pt_data_out(ptvp, (unsigned char *)paramp, param_len);
res = do_scsi_pt(ptvp, sg_fd, tmout, verbose);
ret = sg_cmds_process_resp(ptvp, "unmap", res, 0,
sense_b, noisy, verbose, &sense_cat);
if (-1 == ret)
;
else if (-2 == ret) {
switch (sense_cat) {
case SG_LIB_CAT_INVALID_OP:
case SG_LIB_CAT_ILLEGAL_REQ:
case SG_LIB_CAT_UNIT_ATTENTION:
case SG_LIB_CAT_ABORTED_COMMAND:
ret = sense_cat;
break;
case SG_LIB_CAT_RECOVERED:
case SG_LIB_CAT_NO_SENSE:
ret = 0;
break;
default:
ret = -1;
break;
}
} else
ret = 0;
destruct_scsi_pt_obj(ptvp);
return ret;
}
/* Invokes a SCSI READ BLOCK LIMITS command. Return of 0 -> success,
* SG_LIB_CAT_INVALID_OP -> Read block limits not supported,
* SG_LIB_CAT_ILLEGAL_REQ -> bad field in cdb,
* SG_LIB_CAT_ABORTED_COMMAND,
* SG_LIB_NOT_READY (shouldn't happen), -1 -> other failure */
int
sg_ll_read_block_limits(int sg_fd, void * resp, int mx_resp_len,
int noisy, int verbose)
{
int k, ret, res, sense_cat;
unsigned char rlCmdBlk[READ_BLOCK_LIMITS_CMDLEN] =
{READ_BLOCK_LIMITS_CMD, 0, 0, 0, 0, 0};
unsigned char sense_b[SENSE_BUFF_LEN];
struct sg_pt_base * ptvp;
if (NULL == sg_warnings_strm)
sg_warnings_strm = stderr;
if (verbose) {
fprintf(sg_warnings_strm, " read block limits cdb: ");
for (k = 0; k < READ_BLOCK_LIMITS_CMDLEN; ++k)
fprintf(sg_warnings_strm, "%02x ", rlCmdBlk[k]);
fprintf(sg_warnings_strm, "\n");
}
ptvp = construct_scsi_pt_obj();
if (NULL == ptvp) {
fprintf(sg_warnings_strm, "read block limits: out of memory\n");
return -1;
}
set_scsi_pt_cdb(ptvp, rlCmdBlk, sizeof(rlCmdBlk));
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, sg_fd, DEF_PT_TIMEOUT, verbose);
ret = sg_cmds_process_resp(ptvp, "read block limits", res, mx_resp_len,
sense_b, noisy, verbose, &sense_cat);
if (-1 == ret)
;
else if (-2 == ret) {
switch (sense_cat) {
case SG_LIB_CAT_INVALID_OP:
case SG_LIB_CAT_ILLEGAL_REQ:
case SG_LIB_CAT_ABORTED_COMMAND:
case SG_LIB_CAT_NOT_READY: /* shouldn't happen ?? */
ret = sense_cat;
break;
case SG_LIB_CAT_RECOVERED:
case SG_LIB_CAT_NO_SENSE:
ret = 0;
break;
default:
ret = -1;
break;
}
} else {
if ((verbose > 2) && (ret > 0)) {
fprintf(sg_warnings_strm, " read block limits: response%s\n",
(ret > 256 ? ", first 256 bytes" : ""));
dStrHexErr((const char *)resp, (ret > 256 ? 256 : ret), -1);
}
ret = 0;
}
destruct_scsi_pt_obj(ptvp);
return ret;
}
/* Invokes a SCSI RECEIVE COPY RESULTS command. Actually cover all current
* uses of opcode 0x84 (Third-party copy IN). Return of 0 -> success,
* SG_LIB_CAT_INVALID_OP -> Receive copy results not supported,
* SG_LIB_CAT_ILLEGAL_REQ -> bad field in cdb, SG_LIB_CAT_UNIT_ATTENTION,
* SG_LIB_CAT_NOT_READY -> device not ready, SG_LIB_CAT_ABORTED_COMMAND,
* -1 -> other failure */
int
sg_ll_receive_copy_results(int sg_fd, int sa, int list_id, void * resp,
int mx_resp_len, int noisy, int verbose)
{
int k, res, ret, sense_cat;
unsigned char rcvcopyresCmdBlk[THIRD_PARTY_COPY_IN_CMDLEN] =
{THIRD_PARTY_COPY_IN_CMD, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
unsigned char sense_b[SENSE_BUFF_LEN];
struct sg_pt_base * ptvp;
char b[64];
sg_get_opcode_sa_name(THIRD_PARTY_COPY_IN_CMD, sa, 0, (int)sizeof(b), b);
rcvcopyresCmdBlk[1] = (unsigned char)(sa & 0x1f);
if (sa <= 4) /* LID1 variants */
rcvcopyresCmdBlk[2] = (unsigned char)(list_id);
else if ((sa >= 5) && (sa <= 7)) { /* LID4 variants */
rcvcopyresCmdBlk[2] = (unsigned char)((list_id >> 24) & 0xff);
rcvcopyresCmdBlk[3] = (unsigned char)((list_id >> 16) & 0xff);
rcvcopyresCmdBlk[4] = (unsigned char)((list_id >> 8) & 0xff);
rcvcopyresCmdBlk[5] = (unsigned char)(list_id & 0xff);
}
rcvcopyresCmdBlk[10] = (unsigned char)((mx_resp_len >> 24) & 0xff);
rcvcopyresCmdBlk[11] = (unsigned char)((mx_resp_len >> 16) & 0xff);
rcvcopyresCmdBlk[12] = (unsigned char)((mx_resp_len >> 8) & 0xff);
rcvcopyresCmdBlk[13] = (unsigned char)(mx_resp_len & 0xff);
if (NULL == sg_warnings_strm)
sg_warnings_strm = stderr;
if (verbose) {
fprintf(sg_warnings_strm, " %s cmd: ", b);
for (k = 0; k < THIRD_PARTY_COPY_IN_CMDLEN; ++k)
fprintf(sg_warnings_strm, "%02x ", rcvcopyresCmdBlk[k]);
fprintf(sg_warnings_strm, "\n");
}
ptvp = construct_scsi_pt_obj();
if (NULL == ptvp) {
fprintf(sg_warnings_strm, "%s: out of memory\n", b);
return -1;
}
set_scsi_pt_cdb(ptvp, rcvcopyresCmdBlk, sizeof(rcvcopyresCmdBlk));
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, sg_fd, DEF_PT_TIMEOUT, verbose);
ret = sg_cmds_process_resp(ptvp, b, res, mx_resp_len, sense_b, noisy,
verbose, &sense_cat);
if (-1 == ret)
;
else if (-2 == ret) {
switch (sense_cat) {
case SG_LIB_CAT_NOT_READY:
case SG_LIB_CAT_INVALID_OP:
case SG_LIB_CAT_ILLEGAL_REQ:
case SG_LIB_CAT_UNIT_ATTENTION:
case SG_LIB_CAT_ABORTED_COMMAND:
ret = sense_cat;
break;
case SG_LIB_CAT_RECOVERED:
case SG_LIB_CAT_NO_SENSE:
ret = 0;
break;
default:
ret = -1;
break;
}
} else
ret = 0;
destruct_scsi_pt_obj(ptvp);
return ret;
}
/* SPC-4 rev 35 and later calls this opcode (0x83) "Third-party copy OUT"
* The original EXTENDED COPY command (now called EXTENDED COPY (LID1))
* is the only one supported by sg_ll_extended_copy(). See function
* sg_ll_3party_copy_out() for the other service actions ( > 0 ). */
/* Invokes a SCSI EXTENDED COPY (LID1) command. Return of 0 -> success,
* SG_LIB_CAT_INVALID_OP -> Receive copy results not supported,
* SG_LIB_CAT_ILLEGAL_REQ -> bad field in cdb, SG_LIB_CAT_UNIT_ATTENTION,
* SG_LIB_CAT_NOT_READY -> device not ready, SG_LIB_CAT_ABORTED_COMMAND,
* -1 -> other failure */
int
sg_ll_extended_copy(int sg_fd, void * paramp, int param_len, int noisy,
int verbose)
{
int k, res, ret, sense_cat;
unsigned char xcopyCmdBlk[THIRD_PARTY_COPY_OUT_CMDLEN] =
{THIRD_PARTY_COPY_OUT_CMD, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
unsigned char sense_b[SENSE_BUFF_LEN];
struct sg_pt_base * ptvp;
const char * opcode_name = "Extended copy (LID1)";
xcopyCmdBlk[1] = (unsigned char)(EXTENDED_COPY_LID1_SA & 0x1f);
xcopyCmdBlk[10] = (unsigned char)((param_len >> 24) & 0xff);
xcopyCmdBlk[11] = (unsigned char)((param_len >> 16) & 0xff);
xcopyCmdBlk[12] = (unsigned char)((param_len >> 8) & 0xff);
xcopyCmdBlk[13] = (unsigned char)(param_len & 0xff);
if (NULL == sg_warnings_strm)
sg_warnings_strm = stderr;
if (verbose) {
fprintf(sg_warnings_strm, " %s cmd: ", opcode_name);
for (k = 0; k < THIRD_PARTY_COPY_OUT_CMDLEN; ++k)
fprintf(sg_warnings_strm, "%02x ", xcopyCmdBlk[k]);
fprintf(sg_warnings_strm, "\n");
if ((verbose > 1) && paramp && param_len) {
fprintf(sg_warnings_strm, " %s parameter list:\n",
opcode_name);
dStrHexErr((const char *)paramp, param_len, -1);
}
}
ptvp = construct_scsi_pt_obj();
if (NULL == ptvp) {
fprintf(sg_warnings_strm, "%s: out of memory\n", opcode_name);
return -1;
}
set_scsi_pt_cdb(ptvp, xcopyCmdBlk, sizeof(xcopyCmdBlk));
set_scsi_pt_sense(ptvp, sense_b, sizeof(sense_b));
set_scsi_pt_data_out(ptvp, (unsigned char *)paramp, param_len);
res = do_scsi_pt(ptvp, sg_fd, DEF_PT_TIMEOUT, verbose);
ret = sg_cmds_process_resp(ptvp, opcode_name, res, 0, sense_b,
noisy, verbose, &sense_cat);
if (-1 == ret)
;
else if (-2 == ret) {
switch (sense_cat) {
case SG_LIB_CAT_NOT_READY:
case SG_LIB_CAT_INVALID_OP:
case SG_LIB_CAT_ILLEGAL_REQ:
case SG_LIB_CAT_UNIT_ATTENTION:
case SG_LIB_CAT_ABORTED_COMMAND:
ret = sense_cat;
break;
case SG_LIB_CAT_RECOVERED:
case SG_LIB_CAT_NO_SENSE:
ret = 0;
break;
default:
ret = -1;
break;
}
} else
ret = 0;
destruct_scsi_pt_obj(ptvp);
return ret;
}
/* Handles various service actions associated with opcode 0x83 which is
* called THIRD PARTY COPY OUT. These include the EXTENDED COPY(LID1 and
* LID4), POPULATE TOKEN and WRITE USING TOKEN commands.
* Return of 0 -> success,
* SG_LIB_CAT_INVALID_OP -> opcode 0x83 not supported,
* SG_LIB_CAT_ILLEGAL_REQ -> bad field in cdb, SG_LIB_CAT_UNIT_ATTENTION,
* SG_LIB_CAT_NOT_READY -> device not ready, SG_LIB_CAT_ABORTED_COMMAND,
* -1 -> other failure */
int
sg_ll_3party_copy_out(int sg_fd, int sa, unsigned int list_id, int group_num,
int timeout_secs, void * paramp, int param_len,
int noisy, int verbose)
{
int k, res, ret, sense_cat, tmout;
unsigned char xcopyCmdBlk[THIRD_PARTY_COPY_OUT_CMDLEN] =
{THIRD_PARTY_COPY_OUT_CMD, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
unsigned char sense_b[SENSE_BUFF_LEN];
struct sg_pt_base * ptvp;
char cname[80];
if (NULL == sg_warnings_strm)
sg_warnings_strm = stderr;
sg_get_opcode_sa_name(THIRD_PARTY_COPY_OUT_CMD, sa, 0, sizeof(cname),
cname);
xcopyCmdBlk[1] = (unsigned char)(sa & 0x1f);
switch (sa) {
case 0x0: /* XCOPY(LID1) */
case 0x1: /* XCOPY(LID4) */
xcopyCmdBlk[10] = (unsigned char)((param_len >> 24) & 0xff);
xcopyCmdBlk[11] = (unsigned char)((param_len >> 16) & 0xff);
xcopyCmdBlk[12] = (unsigned char)((param_len >> 8) & 0xff);
xcopyCmdBlk[13] = (unsigned char)(param_len & 0xff);
break;
case 0x10: /* POPULATE TOKEN (SBC-3) */
case 0x11: /* WRITE USING TOKEN (SBC-3) */
xcopyCmdBlk[6] = (unsigned char)((list_id >> 24) & 0xff);
xcopyCmdBlk[7] = (unsigned char)((list_id >> 16) & 0xff);
xcopyCmdBlk[8] = (unsigned char)((list_id >> 8) & 0xff);
xcopyCmdBlk[9] = (unsigned char)(list_id & 0xff);
xcopyCmdBlk[10] = (unsigned char)((param_len >> 24) & 0xff);
xcopyCmdBlk[11] = (unsigned char)((param_len >> 16) & 0xff);
xcopyCmdBlk[12] = (unsigned char)((param_len >> 8) & 0xff);
xcopyCmdBlk[13] = (unsigned char)(param_len & 0xff);
xcopyCmdBlk[14] = (unsigned char)(group_num & 0x1f);
break;
case 0x1c: /* COPY OPERATION ABORT */
xcopyCmdBlk[2] = (unsigned char)((list_id >> 24) & 0xff);
xcopyCmdBlk[3] = (unsigned char)((list_id >> 16) & 0xff);
xcopyCmdBlk[4] = (unsigned char)((list_id >> 8) & 0xff);
xcopyCmdBlk[5] = (unsigned char)(list_id & 0xff);
break;
default:
fprintf(sg_warnings_strm, "sg_ll_3party_copy_out: unknown service "
"action 0x%x\n", sa);
return -1;
}
tmout = (timeout_secs > 0) ? timeout_secs : DEF_PT_TIMEOUT;
if (verbose) {
fprintf(sg_warnings_strm, " %s cmd: ", cname);
for (k = 0; k < THIRD_PARTY_COPY_OUT_CMDLEN; ++k)
fprintf(sg_warnings_strm, "%02x ", xcopyCmdBlk[k]);
fprintf(sg_warnings_strm, "\n");
if ((verbose > 1) && paramp && param_len) {
fprintf(sg_warnings_strm, " %s parameter list:\n", cname);
dStrHexErr((const char *)paramp, param_len, -1);
}
}
ptvp = construct_scsi_pt_obj();
if (NULL == ptvp) {
fprintf(sg_warnings_strm, "%s: out of memory\n", cname);
return -1;
}
set_scsi_pt_cdb(ptvp, xcopyCmdBlk, sizeof(xcopyCmdBlk));
set_scsi_pt_sense(ptvp, sense_b, sizeof(sense_b));
set_scsi_pt_data_out(ptvp, (unsigned char *)paramp, param_len);
res = do_scsi_pt(ptvp, sg_fd, tmout, verbose);
ret = sg_cmds_process_resp(ptvp, cname, res, 0, sense_b, noisy, verbose,
&sense_cat);
if (-1 == ret)
;
else if (-2 == ret) {
switch (sense_cat) {
case SG_LIB_CAT_NOT_READY:
case SG_LIB_CAT_INVALID_OP:
case SG_LIB_CAT_ILLEGAL_REQ:
case SG_LIB_CAT_UNIT_ATTENTION:
case SG_LIB_CAT_ABORTED_COMMAND:
ret = sense_cat;
break;
case SG_LIB_CAT_RECOVERED:
case SG_LIB_CAT_NO_SENSE:
ret = 0;
break;
default:
ret = -1;
break;
}
} else
ret = 0;
destruct_scsi_pt_obj(ptvp);
return ret;
}
ddpt-0.94/TODO 0000644 0001750 0001750 00000000364 11440271346 012072 0 ustar dougg dougg Some suggestions:
- look into supporting the SCSI EXTENDED COPY command. Syntax should be
interesting [20090320]
- cope with MEDIUM/HARDWARE ERROR when no valid INFO field given and
bpt>1 . Broken devices are out there [20100903]
ddpt-0.94/ChangeLog 0000644 0001750 0001750 00000013230 12320426132 013141 0 ustar dougg dougg The version number is hard-coded into src/ddpt.c (in a C string);
the rpm spec file: ddpt.spec ; the debian/changelog file;
and the configure.ac file (in the AC_INIT item).
Changelog for ddpt-0.94 [20140407] [svn: r277]
- xcopy: change default to send xcopy command to dst
- add XCOPY_TO_SRC and XCOPY_TO_DST environment
variables to guide where to send xcopy command
- odx: add new offloaded copy technique, also known
as "xcopy v2, lite", that exposes ROD Tokens
- ddpt supports 4 odx variants: full copy, zero
output blocks, read to tokens and write from
tokens. Latter two facilitate network copies
- add scatter-gather list capability to seek=,
skip= to read from command line, file or stdin
- ddptctl: add odx helper utility
- can issue individual PT, WUT, RRTI, Report All
Rod Tokens, and Copy Operation Abort commands
- can decode T10 defined info in Rod Token
- improve CL handling of short options (e.g. '-vv')
- point svn:externals to rev 563 of sg3_utils
- configure: add --disable-libsgutils option so
build bypasses that library if present
Changelog for ddpt-0.93 [20131113] [svn: r242]
- add xcopy support, new flags: xcopy, cat, dc;
new options: id_usage=, list_id=, prio=
- add intio=0|1 ; rework signal handling
- allow tape device in non-pt mode
- fix fifo read when bs is large
- add delay=MS,W_MS for bandwidth limiting
- add oflag=ignoreew,pad,nofm,nopad for tape
- add iseek= option, synonym for skip=
- add oseek= option, synonym for seek=
- add protect=RDP,WRP option
- add cdbsz=32 option for READ(32) and WRITE(32)
- add rarc flag for scsi read cdbs
- add block flag for pt (non blocking by default)
- fix overflow on OFILE when input fifo
- ./configure options:
- change --enable-no-linux-bsg to --disable-linuxbsg
- add --disable-scsistrings to reduce utility size
with non-libsgutils build
- reduce ddpt.c size by adding ddpt_pt.c
- win32: fixes for cygwin version 1.7.17 headers
- translate O_EXCL to no sharing
- point svn:externals to rev 522 of sg3_utils
- upgrade automake to version 1.13.3
Changelog for ddpt-0.92 [20110217] [svn: r157]
- when pt used on block device and discrepancy between size
of block device and read capacity size, require force flag
- add coe support for input block devices and regular files
- support conv=fdatasync, conv=fsync, oflag=fdatasync and
oflag=fsync; called at end of copy
- allow partial writes of trailing bytes when output is
regular file or fifo (stdout), ignore if block or pt device
- fix stdin, stdout and fifo handling problems
- if iflag=sparse and of=/dev/null (or not given) warn but
set oflag=sparse and continue
- treat unrecovered errors as partial (as dd does)
- win32: add '--wscan' option to scan for devices and volumes
- select SPT direct pt interface
- add estimate of remaining time in progress signal handler
- accept but ignore cbs= option
- error reporting clean up
- add AM_MAINTAINER_MODE to configure.ac to lessen build issues
Changelog for ddpt-0.91 [20100920] [svn: r121]
- rework copy loop.
- extend bpt=BPT to bpt=BPR[,OBPC] spare+sparse granularity
- change BPT default to vary from 8192 to 1 depending on IBS
- add oflag=resume logic
- change oflag=sparse to extend regular OFILE with a final
block write, if required
- add oflag=strunc to also do sparse writes but to extend
regular OFILE with ftruncate, if required
- change 'bs=' option to set IBS and OBS; 'ibs=' and 'obs='
can coexist but not with 'bs='. [Closer to dd semantics]
- conv=noerror,null,resume,sparing,sparse,sync now permitted
- add oflag=trunc and conv=trunc (default: overwrite)
- quietly ignored if resume, needed due to sequence
- add oflag=trim for TRIM/UNMAP on pt OFILEs
- add iflag=self or oflag=self for self-trim
- add oflag=nowrite to bypass writes+truncates (does trims)
- add iflag=errblk to write bad LBAs to file
- if sense data deficient, write a LBA range to file
- add iflag=norcap or oflag=norcap to bypass the SCSI READ
CAPACITY command on pt devices
- discrepancies between ibs or obs and READ CAPACITY supplied
block lengths abort the copy. This can be overridden by
iflag=force or oflag=force on pt devices
- optical memory devices (pdt=7) added to cd/dvd readers (pdt=5)
that don't need sense valid=1 to accept info field (when > 0)
- rework short read logic for block and regular files
- treat linux bsg devices as implicit pt devices
Changelog for ddpt-0.90 [20100508] [svn: r85]
- copied from sg_dd utility in sg3_utils package
- change name from sgdd to ddpt (package and utility name)
- ibs and obs can differ when ((ibs * bpt) % obs) == 0)
- change 'sg_io' flag to 'pt' (for pass-through)
- change 'dsync' flag to 'sync'; 'ssync' flag for SCSI
SYNCHRONIZE CACHE command; add 'nocache' flag
- 'if=IFILE' must be given, to read from stdin use 'if=-'
- 'of=OFILE' changed to default to /dev/null (was stdout)
- if 'nocache' flag call posix_fadvise(SEQUENTIAL) on
input fd and posix_fadvise(DONTNEED) during copy
- add 'fua_nv' flag
- when multiple unrecovered errors report lowest and
highest LBA
- call sg_set_binary_mode() on fds (for windows)
- resubmit pass-through reads and writes if interrupted
- drop Linux raw file support
- drop READ LONG logic (coe=2 and coe=3)
- add write sparing support (oflag=sparing)
- add linux bsg support
- sg_pt_win32: define WIN32_SPT_DIRECT via config.h
- calculate COUNT for regular files when required
- accept 'count=-1' to mean calculate COUNT
- accept '-V' as synonym for '--version'
- point svn:externals to rev 334 of sg3_utils
ddpt-0.94/Makefile.am 0000644 0001750 0001750 00000000123 11100510330 013405 0 ustar dougg dougg SUBDIRS = src doc
EXTRA_DIST=autogen.sh
distclean-local:
rm -rf autom4te.cache
ddpt-0.94/depcomp 0000755 0001750 0001750 00000056016 12234471250 012762 0 ustar dougg dougg #! /bin/sh
# depcomp - compile a program generating dependencies as side-effects
scriptversion=2013-05-30.07; # UTC
# Copyright (C) 1999-2013 Free Software Foundation, Inc.
# 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 distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program. If not, see .
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program.
# Originally written by Alexandre Oliva .
case $1 in
'')
echo "$0: No command. Try '$0 --help' for more information." 1>&2
exit 1;
;;
-h | --h*)
cat <<\EOF
Usage: depcomp [--help] [--version] PROGRAM [ARGS]
Run PROGRAMS ARGS to compile a file, generating dependencies
as side-effects.
Environment variables:
depmode Dependency tracking mode.
source Source file read by 'PROGRAMS ARGS'.
object Object file output by 'PROGRAMS ARGS'.
DEPDIR directory where to store dependencies.
depfile Dependency file to output.
tmpdepfile Temporary file to use when outputting dependencies.
libtool Whether libtool is used (yes/no).
Report bugs to .
EOF
exit $?
;;
-v | --v*)
echo "depcomp $scriptversion"
exit $?
;;
esac
# Get the directory component of the given path, and save it in the
# global variables '$dir'. Note that this directory component will
# be either empty or ending with a '/' character. This is deliberate.
set_dir_from ()
{
case $1 in
*/*) dir=`echo "$1" | sed -e 's|/[^/]*$|/|'`;;
*) dir=;;
esac
}
# Get the suffix-stripped basename of the given path, and save it the
# global variable '$base'.
set_base_from ()
{
base=`echo "$1" | sed -e 's|^.*/||' -e 's/\.[^.]*$//'`
}
# If no dependency file was actually created by the compiler invocation,
# we still have to create a dummy depfile, to avoid errors with the
# Makefile "include basename.Plo" scheme.
make_dummy_depfile ()
{
echo "#dummy" > "$depfile"
}
# Factor out some common post-processing of the generated depfile.
# Requires the auxiliary global variable '$tmpdepfile' to be set.
aix_post_process_depfile ()
{
# If the compiler actually managed to produce a dependency file,
# post-process it.
if test -f "$tmpdepfile"; then
# Each line is of the form 'foo.o: dependency.h'.
# Do two passes, one to just change these to
# $object: dependency.h
# and one to simply output
# dependency.h:
# which is needed to avoid the deleted-header problem.
{ sed -e "s,^.*\.[$lower]*:,$object:," < "$tmpdepfile"
sed -e "s,^.*\.[$lower]*:[$tab ]*,," -e 's,$,:,' < "$tmpdepfile"
} > "$depfile"
rm -f "$tmpdepfile"
else
make_dummy_depfile
fi
}
# A tabulation character.
tab=' '
# A newline character.
nl='
'
# Character ranges might be problematic outside the C locale.
# These definitions help.
upper=ABCDEFGHIJKLMNOPQRSTUVWXYZ
lower=abcdefghijklmnopqrstuvwxyz
digits=0123456789
alpha=${upper}${lower}
if test -z "$depmode" || test -z "$source" || test -z "$object"; then
echo "depcomp: Variables source, object and depmode must be set" 1>&2
exit 1
fi
# Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po.
depfile=${depfile-`echo "$object" |
sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`}
tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`}
rm -f "$tmpdepfile"
# Avoid interferences from the environment.
gccflag= dashmflag=
# Some modes work just like other modes, but use different flags. We
# parameterize here, but still list the modes in the big case below,
# to make depend.m4 easier to write. Note that we *cannot* use a case
# here, because this file can only contain one case statement.
if test "$depmode" = hp; then
# HP compiler uses -M and no extra arg.
gccflag=-M
depmode=gcc
fi
if test "$depmode" = dashXmstdout; then
# This is just like dashmstdout with a different argument.
dashmflag=-xM
depmode=dashmstdout
fi
cygpath_u="cygpath -u -f -"
if test "$depmode" = msvcmsys; then
# This is just like msvisualcpp but w/o cygpath translation.
# Just convert the backslash-escaped backslashes to single forward
# slashes to satisfy depend.m4
cygpath_u='sed s,\\\\,/,g'
depmode=msvisualcpp
fi
if test "$depmode" = msvc7msys; then
# This is just like msvc7 but w/o cygpath translation.
# Just convert the backslash-escaped backslashes to single forward
# slashes to satisfy depend.m4
cygpath_u='sed s,\\\\,/,g'
depmode=msvc7
fi
if test "$depmode" = xlc; then
# IBM C/C++ Compilers xlc/xlC can output gcc-like dependency information.
gccflag=-qmakedep=gcc,-MF
depmode=gcc
fi
case "$depmode" in
gcc3)
## gcc 3 implements dependency tracking that does exactly what
## we want. Yay! Note: for some reason libtool 1.4 doesn't like
## it if -MD -MP comes after the -MF stuff. Hmm.
## Unfortunately, FreeBSD c89 acceptance of flags depends upon
## the command line argument order; so add the flags where they
## appear in depend2.am. Note that the slowdown incurred here
## affects only configure: in makefiles, %FASTDEP% shortcuts this.
for arg
do
case $arg in
-c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;;
*) set fnord "$@" "$arg" ;;
esac
shift # fnord
shift # $arg
done
"$@"
stat=$?
if test $stat -ne 0; then
rm -f "$tmpdepfile"
exit $stat
fi
mv "$tmpdepfile" "$depfile"
;;
gcc)
## Note that this doesn't just cater to obsosete pre-3.x GCC compilers.
## but also to in-use compilers like IMB xlc/xlC and the HP C compiler.
## (see the conditional assignment to $gccflag above).
## There are various ways to get dependency output from gcc. Here's
## why we pick this rather obscure method:
## - Don't want to use -MD because we'd like the dependencies to end
## up in a subdir. Having to rename by hand is ugly.
## (We might end up doing this anyway to support other compilers.)
## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like
## -MM, not -M (despite what the docs say). Also, it might not be
## supported by the other compilers which use the 'gcc' depmode.
## - Using -M directly means running the compiler twice (even worse
## than renaming).
if test -z "$gccflag"; then
gccflag=-MD,
fi
"$@" -Wp,"$gccflag$tmpdepfile"
stat=$?
if test $stat -ne 0; then
rm -f "$tmpdepfile"
exit $stat
fi
rm -f "$depfile"
echo "$object : \\" > "$depfile"
# The second -e expression handles DOS-style file names with drive
# letters.
sed -e 's/^[^:]*: / /' \
-e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile"
## This next piece of magic avoids the "deleted header file" problem.
## The problem is that when a header file which appears in a .P file
## is deleted, the dependency causes make to die (because there is
## typically no way to rebuild the header). We avoid this by adding
## dummy dependencies for each header file. Too bad gcc doesn't do
## this for us directly.
## Some versions of gcc put a space before the ':'. On the theory
## that the space means something, we add a space to the output as
## well. hp depmode also adds that space, but also prefixes the VPATH
## to the object. Take care to not repeat it in the output.
## Some versions of the HPUX 10.20 sed can't process this invocation
## correctly. Breaking it into two sed invocations is a workaround.
tr ' ' "$nl" < "$tmpdepfile" \
| sed -e 's/^\\$//' -e '/^$/d' -e "s|.*$object$||" -e '/:$/d' \
| sed -e 's/$/ :/' >> "$depfile"
rm -f "$tmpdepfile"
;;
hp)
# This case exists only to let depend.m4 do its work. It works by
# looking at the text of this script. This case will never be run,
# since it is checked for above.
exit 1
;;
sgi)
if test "$libtool" = yes; then
"$@" "-Wp,-MDupdate,$tmpdepfile"
else
"$@" -MDupdate "$tmpdepfile"
fi
stat=$?
if test $stat -ne 0; then
rm -f "$tmpdepfile"
exit $stat
fi
rm -f "$depfile"
if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files
echo "$object : \\" > "$depfile"
# Clip off the initial element (the dependent). Don't try to be
# clever and replace this with sed code, as IRIX sed won't handle
# lines with more than a fixed number of characters (4096 in
# IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines;
# the IRIX cc adds comments like '#:fec' to the end of the
# dependency line.
tr ' ' "$nl" < "$tmpdepfile" \
| sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' \
| tr "$nl" ' ' >> "$depfile"
echo >> "$depfile"
# The second pass generates a dummy entry for each header file.
tr ' ' "$nl" < "$tmpdepfile" \
| sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \
>> "$depfile"
else
make_dummy_depfile
fi
rm -f "$tmpdepfile"
;;
xlc)
# This case exists only to let depend.m4 do its work. It works by
# looking at the text of this script. This case will never be run,
# since it is checked for above.
exit 1
;;
aix)
# The C for AIX Compiler uses -M and outputs the dependencies
# in a .u file. In older versions, this file always lives in the
# current directory. Also, the AIX compiler puts '$object:' at the
# start of each line; $object doesn't have directory information.
# Version 6 uses the directory in both cases.
set_dir_from "$object"
set_base_from "$object"
if test "$libtool" = yes; then
tmpdepfile1=$dir$base.u
tmpdepfile2=$base.u
tmpdepfile3=$dir.libs/$base.u
"$@" -Wc,-M
else
tmpdepfile1=$dir$base.u
tmpdepfile2=$dir$base.u
tmpdepfile3=$dir$base.u
"$@" -M
fi
stat=$?
if test $stat -ne 0; then
rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
exit $stat
fi
for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
do
test -f "$tmpdepfile" && break
done
aix_post_process_depfile
;;
tcc)
# tcc (Tiny C Compiler) understand '-MD -MF file' since version 0.9.26
# FIXME: That version still under development at the moment of writing.
# Make that this statement remains true also for stable, released
# versions.
# It will wrap lines (doesn't matter whether long or short) with a
# trailing '\', as in:
#
# foo.o : \
# foo.c \
# foo.h \
#
# It will put a trailing '\' even on the last line, and will use leading
# spaces rather than leading tabs (at least since its commit 0394caf7
# "Emit spaces for -MD").
"$@" -MD -MF "$tmpdepfile"
stat=$?
if test $stat -ne 0; then
rm -f "$tmpdepfile"
exit $stat
fi
rm -f "$depfile"
# Each non-empty line is of the form 'foo.o : \' or ' dep.h \'.
# We have to change lines of the first kind to '$object: \'.
sed -e "s|.*:|$object :|" < "$tmpdepfile" > "$depfile"
# And for each line of the second kind, we have to emit a 'dep.h:'
# dummy dependency, to avoid the deleted-header problem.
sed -n -e 's|^ *\(.*\) *\\$|\1:|p' < "$tmpdepfile" >> "$depfile"
rm -f "$tmpdepfile"
;;
## The order of this option in the case statement is important, since the
## shell code in configure will try each of these formats in the order
## listed in this file. A plain '-MD' option would be understood by many
## compilers, so we must ensure this comes after the gcc and icc options.
pgcc)
# Portland's C compiler understands '-MD'.
# Will always output deps to 'file.d' where file is the root name of the
# source file under compilation, even if file resides in a subdirectory.
# The object file name does not affect the name of the '.d' file.
# pgcc 10.2 will output
# foo.o: sub/foo.c sub/foo.h
# and will wrap long lines using '\' :
# foo.o: sub/foo.c ... \
# sub/foo.h ... \
# ...
set_dir_from "$object"
# Use the source, not the object, to determine the base name, since
# that's sadly what pgcc will do too.
set_base_from "$source"
tmpdepfile=$base.d
# For projects that build the same source file twice into different object
# files, the pgcc approach of using the *source* file root name can cause
# problems in parallel builds. Use a locking strategy to avoid stomping on
# the same $tmpdepfile.
lockdir=$base.d-lock
trap "
echo '$0: caught signal, cleaning up...' >&2
rmdir '$lockdir'
exit 1
" 1 2 13 15
numtries=100
i=$numtries
while test $i -gt 0; do
# mkdir is a portable test-and-set.
if mkdir "$lockdir" 2>/dev/null; then
# This process acquired the lock.
"$@" -MD
stat=$?
# Release the lock.
rmdir "$lockdir"
break
else
# If the lock is being held by a different process, wait
# until the winning process is done or we timeout.
while test -d "$lockdir" && test $i -gt 0; do
sleep 1
i=`expr $i - 1`
done
fi
i=`expr $i - 1`
done
trap - 1 2 13 15
if test $i -le 0; then
echo "$0: failed to acquire lock after $numtries attempts" >&2
echo "$0: check lockdir '$lockdir'" >&2
exit 1
fi
if test $stat -ne 0; then
rm -f "$tmpdepfile"
exit $stat
fi
rm -f "$depfile"
# Each line is of the form `foo.o: dependent.h',
# or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'.
# Do two passes, one to just change these to
# `$object: dependent.h' and one to simply `dependent.h:'.
sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile"
# Some versions of the HPUX 10.20 sed can't process this invocation
# correctly. Breaking it into two sed invocations is a workaround.
sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" \
| sed -e 's/$/ :/' >> "$depfile"
rm -f "$tmpdepfile"
;;
hp2)
# The "hp" stanza above does not work with aCC (C++) and HP's ia64
# compilers, which have integrated preprocessors. The correct option
# to use with these is +Maked; it writes dependencies to a file named
# 'foo.d', which lands next to the object file, wherever that
# happens to be.
# Much of this is similar to the tru64 case; see comments there.
set_dir_from "$object"
set_base_from "$object"
if test "$libtool" = yes; then
tmpdepfile1=$dir$base.d
tmpdepfile2=$dir.libs/$base.d
"$@" -Wc,+Maked
else
tmpdepfile1=$dir$base.d
tmpdepfile2=$dir$base.d
"$@" +Maked
fi
stat=$?
if test $stat -ne 0; then
rm -f "$tmpdepfile1" "$tmpdepfile2"
exit $stat
fi
for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2"
do
test -f "$tmpdepfile" && break
done
if test -f "$tmpdepfile"; then
sed -e "s,^.*\.[$lower]*:,$object:," "$tmpdepfile" > "$depfile"
# Add 'dependent.h:' lines.
sed -ne '2,${
s/^ *//
s/ \\*$//
s/$/:/
p
}' "$tmpdepfile" >> "$depfile"
else
make_dummy_depfile
fi
rm -f "$tmpdepfile" "$tmpdepfile2"
;;
tru64)
# The Tru64 compiler uses -MD to generate dependencies as a side
# effect. 'cc -MD -o foo.o ...' puts the dependencies into 'foo.o.d'.
# At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put
# dependencies in 'foo.d' instead, so we check for that too.
# Subdirectories are respected.
set_dir_from "$object"
set_base_from "$object"
if test "$libtool" = yes; then
# Libtool generates 2 separate objects for the 2 libraries. These
# two compilations output dependencies in $dir.libs/$base.o.d and
# in $dir$base.o.d. We have to check for both files, because
# one of the two compilations can be disabled. We should prefer
# $dir$base.o.d over $dir.libs/$base.o.d because the latter is
# automatically cleaned when .libs/ is deleted, while ignoring
# the former would cause a distcleancheck panic.
tmpdepfile1=$dir$base.o.d # libtool 1.5
tmpdepfile2=$dir.libs/$base.o.d # Likewise.
tmpdepfile3=$dir.libs/$base.d # Compaq CCC V6.2-504
"$@" -Wc,-MD
else
tmpdepfile1=$dir$base.d
tmpdepfile2=$dir$base.d
tmpdepfile3=$dir$base.d
"$@" -MD
fi
stat=$?
if test $stat -ne 0; then
rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
exit $stat
fi
for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
do
test -f "$tmpdepfile" && break
done
# Same post-processing that is required for AIX mode.
aix_post_process_depfile
;;
msvc7)
if test "$libtool" = yes; then
showIncludes=-Wc,-showIncludes
else
showIncludes=-showIncludes
fi
"$@" $showIncludes > "$tmpdepfile"
stat=$?
grep -v '^Note: including file: ' "$tmpdepfile"
if test $stat -ne 0; then
rm -f "$tmpdepfile"
exit $stat
fi
rm -f "$depfile"
echo "$object : \\" > "$depfile"
# The first sed program below extracts the file names and escapes
# backslashes for cygpath. The second sed program outputs the file
# name when reading, but also accumulates all include files in the
# hold buffer in order to output them again at the end. This only
# works with sed implementations that can handle large buffers.
sed < "$tmpdepfile" -n '
/^Note: including file: *\(.*\)/ {
s//\1/
s/\\/\\\\/g
p
}' | $cygpath_u | sort -u | sed -n '
s/ /\\ /g
s/\(.*\)/'"$tab"'\1 \\/p
s/.\(.*\) \\/\1:/
H
$ {
s/.*/'"$tab"'/
G
p
}' >> "$depfile"
echo >> "$depfile" # make sure the fragment doesn't end with a backslash
rm -f "$tmpdepfile"
;;
msvc7msys)
# This case exists only to let depend.m4 do its work. It works by
# looking at the text of this script. This case will never be run,
# since it is checked for above.
exit 1
;;
#nosideeffect)
# This comment above is used by automake to tell side-effect
# dependency tracking mechanisms from slower ones.
dashmstdout)
# Important note: in order to support this mode, a compiler *must*
# always write the preprocessed file to stdout, regardless of -o.
"$@" || exit $?
# Remove the call to Libtool.
if test "$libtool" = yes; then
while test "X$1" != 'X--mode=compile'; do
shift
done
shift
fi
# Remove '-o $object'.
IFS=" "
for arg
do
case $arg in
-o)
shift
;;
$object)
shift
;;
*)
set fnord "$@" "$arg"
shift # fnord
shift # $arg
;;
esac
done
test -z "$dashmflag" && dashmflag=-M
# Require at least two characters before searching for ':'
# in the target name. This is to cope with DOS-style filenames:
# a dependency such as 'c:/foo/bar' could be seen as target 'c' otherwise.
"$@" $dashmflag |
sed "s|^[$tab ]*[^:$tab ][^:][^:]*:[$tab ]*|$object: |" > "$tmpdepfile"
rm -f "$depfile"
cat < "$tmpdepfile" > "$depfile"
# Some versions of the HPUX 10.20 sed can't process this sed invocation
# correctly. Breaking it into two sed invocations is a workaround.
tr ' ' "$nl" < "$tmpdepfile" \
| sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \
| sed -e 's/$/ :/' >> "$depfile"
rm -f "$tmpdepfile"
;;
dashXmstdout)
# This case only exists to satisfy depend.m4. It is never actually
# run, as this mode is specially recognized in the preamble.
exit 1
;;
makedepend)
"$@" || exit $?
# Remove any Libtool call
if test "$libtool" = yes; then
while test "X$1" != 'X--mode=compile'; do
shift
done
shift
fi
# X makedepend
shift
cleared=no eat=no
for arg
do
case $cleared in
no)
set ""; shift
cleared=yes ;;
esac
if test $eat = yes; then
eat=no
continue
fi
case "$arg" in
-D*|-I*)
set fnord "$@" "$arg"; shift ;;
# Strip any option that makedepend may not understand. Remove
# the object too, otherwise makedepend will parse it as a source file.
-arch)
eat=yes ;;
-*|$object)
;;
*)
set fnord "$@" "$arg"; shift ;;
esac
done
obj_suffix=`echo "$object" | sed 's/^.*\././'`
touch "$tmpdepfile"
${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@"
rm -f "$depfile"
# makedepend may prepend the VPATH from the source file name to the object.
# No need to regex-escape $object, excess matching of '.' is harmless.
sed "s|^.*\($object *:\)|\1|" "$tmpdepfile" > "$depfile"
# Some versions of the HPUX 10.20 sed can't process the last invocation
# correctly. Breaking it into two sed invocations is a workaround.
sed '1,2d' "$tmpdepfile" \
| tr ' ' "$nl" \
| sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \
| sed -e 's/$/ :/' >> "$depfile"
rm -f "$tmpdepfile" "$tmpdepfile".bak
;;
cpp)
# Important note: in order to support this mode, a compiler *must*
# always write the preprocessed file to stdout.
"$@" || exit $?
# Remove the call to Libtool.
if test "$libtool" = yes; then
while test "X$1" != 'X--mode=compile'; do
shift
done
shift
fi
# Remove '-o $object'.
IFS=" "
for arg
do
case $arg in
-o)
shift
;;
$object)
shift
;;
*)
set fnord "$@" "$arg"
shift # fnord
shift # $arg
;;
esac
done
"$@" -E \
| sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \
-e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \
| sed '$ s: \\$::' > "$tmpdepfile"
rm -f "$depfile"
echo "$object : \\" > "$depfile"
cat < "$tmpdepfile" >> "$depfile"
sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile"
rm -f "$tmpdepfile"
;;
msvisualcpp)
# Important note: in order to support this mode, a compiler *must*
# always write the preprocessed file to stdout.
"$@" || exit $?
# Remove the call to Libtool.
if test "$libtool" = yes; then
while test "X$1" != 'X--mode=compile'; do
shift
done
shift
fi
IFS=" "
for arg
do
case "$arg" in
-o)
shift
;;
$object)
shift
;;
"-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI")
set fnord "$@"
shift
shift
;;
*)
set fnord "$@" "$arg"
shift
shift
;;
esac
done
"$@" -E 2>/dev/null |
sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u > "$tmpdepfile"
rm -f "$depfile"
echo "$object : \\" > "$depfile"
sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::'"$tab"'\1 \\:p' >> "$depfile"
echo "$tab" >> "$depfile"
sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile"
rm -f "$tmpdepfile"
;;
msvcmsys)
# This case exists only to let depend.m4 do its work. It works by
# looking at the text of this script. This case will never be run,
# since it is checked for above.
exit 1
;;
none)
exec "$@"
;;
*)
echo "Unknown depmode $depmode" 1>&2
exit 1
;;
esac
exit 0
# Local Variables:
# mode: shell-script
# sh-indentation: 2
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-time-zone: "UTC"
# time-stamp-end: "; # UTC"
# End:
ddpt-0.94/config.sub 0000755 0001750 0001750 00000105354 12234471250 013370 0 ustar dougg dougg #! /bin/sh
# Configuration validation subroutine script.
# Copyright 1992-2013 Free Software Foundation, Inc.
timestamp='2013-08-10'
# This file 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 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, see .
#
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that
# program. This Exception is an additional permission under section 7
# of the GNU General Public License, version 3 ("GPLv3").
# Please send patches with a ChangeLog entry to config-patches@gnu.org.
#
# Configuration subroutine to validate and canonicalize a configuration type.
# Supply the specified configuration type as an argument.
# If it is invalid, we print an error message on stderr and exit with code 1.
# Otherwise, we print the canonical config type on stdout and succeed.
# You can get the latest version of this script from:
# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD
# This file is supposed to be the same for all GNU packages
# and recognize all the CPU types, system types and aliases
# that are meaningful with *any* GNU software.
# Each package is responsible for reporting which valid configurations
# it does not support. The user should be able to distinguish
# a failure to support a valid configuration from a meaningless
# configuration.
# The goal of this file is to map all the various variations of a given
# machine specification into a single specification in the form:
# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
# or in some cases, the newer four-part form:
# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
# It is wrong to echo any other type of specification.
me=`echo "$0" | sed -e 's,.*/,,'`
usage="\
Usage: $0 [OPTION] CPU-MFR-OPSYS
$0 [OPTION] ALIAS
Canonicalize a configuration name.
Operation modes:
-h, --help print this help, then exit
-t, --time-stamp print date of last modification, then exit
-v, --version print version number, then exit
Report bugs and patches to ."
version="\
GNU config.sub ($timestamp)
Copyright 1992-2013 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
help="
Try \`$me --help' for more information."
# Parse command line
while test $# -gt 0 ; do
case $1 in
--time-stamp | --time* | -t )
echo "$timestamp" ; exit ;;
--version | -v )
echo "$version" ; exit ;;
--help | --h* | -h )
echo "$usage"; exit ;;
-- ) # Stop option processing
shift; break ;;
- ) # Use stdin as input.
break ;;
-* )
echo "$me: invalid option $1$help"
exit 1 ;;
*local*)
# First pass through any local machine types.
echo $1
exit ;;
* )
break ;;
esac
done
case $# in
0) echo "$me: missing argument$help" >&2
exit 1;;
1) ;;
*) echo "$me: too many arguments$help" >&2
exit 1;;
esac
# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
# Here we must recognize all the valid KERNEL-OS combinations.
maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
case $maybe_os in
nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \
linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \
knetbsd*-gnu* | netbsd*-gnu* | \
kopensolaris*-gnu* | \
storm-chaos* | os2-emx* | rtmk-nova*)
os=-$maybe_os
basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
;;
android-linux)
os=-linux-android
basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown
;;
*)
basic_machine=`echo $1 | sed 's/-[^-]*$//'`
if [ $basic_machine != $1 ]
then os=`echo $1 | sed 's/.*-/-/'`
else os=; fi
;;
esac
### Let's recognize common machines as not being operating systems so
### that things like config.sub decstation-3100 work. We also
### recognize some manufacturers as not being operating systems, so we
### can provide default operating systems below.
case $os in
-sun*os*)
# Prevent following clause from handling this invalid input.
;;
-dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \
-att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \
-unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \
-convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
-c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
-harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
-apple | -axis | -knuth | -cray | -microblaze*)
os=
basic_machine=$1
;;
-bluegene*)
os=-cnk
;;
-sim | -cisco | -oki | -wec | -winbond)
os=
basic_machine=$1
;;
-scout)
;;
-wrs)
os=-vxworks
basic_machine=$1
;;
-chorusos*)
os=-chorusos
basic_machine=$1
;;
-chorusrdb)
os=-chorusrdb
basic_machine=$1
;;
-hiux*)
os=-hiuxwe2
;;
-sco6)
os=-sco5v6
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
;;
-sco5)
os=-sco3.2v5
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
;;
-sco4)
os=-sco3.2v4
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
;;
-sco3.2.[4-9]*)
os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
;;
-sco3.2v[4-9]*)
# Don't forget version if it is 3.2v4 or newer.
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
;;
-sco5v6*)
# Don't forget version if it is 3.2v4 or newer.
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
;;
-sco*)
os=-sco3.2v2
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
;;
-udk*)
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
;;
-isc)
os=-isc2.2
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
;;
-clix*)
basic_machine=clipper-intergraph
;;
-isc*)
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
;;
-lynx*178)
os=-lynxos178
;;
-lynx*5)
os=-lynxos5
;;
-lynx*)
os=-lynxos
;;
-ptx*)
basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'`
;;
-windowsnt*)
os=`echo $os | sed -e 's/windowsnt/winnt/'`
;;
-psos*)
os=-psos
;;
-mint | -mint[0-9]*)
basic_machine=m68k-atari
os=-mint
;;
esac
# Decode aliases for certain CPU-COMPANY combinations.
case $basic_machine in
# Recognize the basic CPU types without company name.
# Some are omitted here because they have special meanings below.
1750a | 580 \
| a29k \
| aarch64 | aarch64_be \
| alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
| alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
| am33_2.0 \
| arc | arceb \
| arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \
| avr | avr32 \
| be32 | be64 \
| bfin \
| c4x | c8051 | clipper \
| d10v | d30v | dlx | dsp16xx \
| epiphany \
| fido | fr30 | frv \
| h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
| hexagon \
| i370 | i860 | i960 | ia64 \
| ip2k | iq2000 \
| le32 | le64 \
| lm32 \
| m32c | m32r | m32rle | m68000 | m68k | m88k \
| maxq | mb | microblaze | microblazeel | mcore | mep | metag \
| mips | mipsbe | mipseb | mipsel | mipsle \
| mips16 \
| mips64 | mips64el \
| mips64octeon | mips64octeonel \
| mips64orion | mips64orionel \
| mips64r5900 | mips64r5900el \
| mips64vr | mips64vrel \
| mips64vr4100 | mips64vr4100el \
| mips64vr4300 | mips64vr4300el \
| mips64vr5000 | mips64vr5000el \
| mips64vr5900 | mips64vr5900el \
| mipsisa32 | mipsisa32el \
| mipsisa32r2 | mipsisa32r2el \
| mipsisa64 | mipsisa64el \
| mipsisa64r2 | mipsisa64r2el \
| mipsisa64sb1 | mipsisa64sb1el \
| mipsisa64sr71k | mipsisa64sr71kel \
| mipsr5900 | mipsr5900el \
| mipstx39 | mipstx39el \
| mn10200 | mn10300 \
| moxie \
| mt \
| msp430 \
| nds32 | nds32le | nds32be \
| nios | nios2 | nios2eb | nios2el \
| ns16k | ns32k \
| open8 \
| or1k | or32 \
| pdp10 | pdp11 | pj | pjl \
| powerpc | powerpc64 | powerpc64le | powerpcle \
| pyramid \
| rl78 | rx \
| score \
| sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
| sh64 | sh64le \
| sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \
| sparcv8 | sparcv9 | sparcv9b | sparcv9v \
| spu \
| tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \
| ubicom32 \
| v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \
| we32k \
| x86 | xc16x | xstormy16 | xtensa \
| z8k | z80)
basic_machine=$basic_machine-unknown
;;
c54x)
basic_machine=tic54x-unknown
;;
c55x)
basic_machine=tic55x-unknown
;;
c6x)
basic_machine=tic6x-unknown
;;
m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | picochip)
basic_machine=$basic_machine-unknown
os=-none
;;
m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k)
;;
ms1)
basic_machine=mt-unknown
;;
strongarm | thumb | xscale)
basic_machine=arm-unknown
;;
xgate)
basic_machine=$basic_machine-unknown
os=-none
;;
xscaleeb)
basic_machine=armeb-unknown
;;
xscaleel)
basic_machine=armel-unknown
;;
# We use `pc' rather than `unknown'
# because (1) that's what they normally are, and
# (2) the word "unknown" tends to confuse beginning users.
i*86 | x86_64)
basic_machine=$basic_machine-pc
;;
# Object if more than one company name word.
*-*-*)
echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
exit 1
;;
# Recognize the basic CPU types with company name.
580-* \
| a29k-* \
| aarch64-* | aarch64_be-* \
| alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
| alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
| alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \
| arm-* | armbe-* | armle-* | armeb-* | armv*-* \
| avr-* | avr32-* \
| be32-* | be64-* \
| bfin-* | bs2000-* \
| c[123]* | c30-* | [cjt]90-* | c4x-* \
| c8051-* | clipper-* | craynv-* | cydra-* \
| d10v-* | d30v-* | dlx-* \
| elxsi-* \
| f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \
| h8300-* | h8500-* \
| hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
| hexagon-* \
| i*86-* | i860-* | i960-* | ia64-* \
| ip2k-* | iq2000-* \
| le32-* | le64-* \
| lm32-* \
| m32c-* | m32r-* | m32rle-* \
| m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
| m88110-* | m88k-* | maxq-* | mcore-* | metag-* \
| microblaze-* | microblazeel-* \
| mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
| mips16-* \
| mips64-* | mips64el-* \
| mips64octeon-* | mips64octeonel-* \
| mips64orion-* | mips64orionel-* \
| mips64r5900-* | mips64r5900el-* \
| mips64vr-* | mips64vrel-* \
| mips64vr4100-* | mips64vr4100el-* \
| mips64vr4300-* | mips64vr4300el-* \
| mips64vr5000-* | mips64vr5000el-* \
| mips64vr5900-* | mips64vr5900el-* \
| mipsisa32-* | mipsisa32el-* \
| mipsisa32r2-* | mipsisa32r2el-* \
| mipsisa64-* | mipsisa64el-* \
| mipsisa64r2-* | mipsisa64r2el-* \
| mipsisa64sb1-* | mipsisa64sb1el-* \
| mipsisa64sr71k-* | mipsisa64sr71kel-* \
| mipsr5900-* | mipsr5900el-* \
| mipstx39-* | mipstx39el-* \
| mmix-* \
| mt-* \
| msp430-* \
| nds32-* | nds32le-* | nds32be-* \
| nios-* | nios2-* | nios2eb-* | nios2el-* \
| none-* | np1-* | ns16k-* | ns32k-* \
| open8-* \
| orion-* \
| pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \
| pyramid-* \
| rl78-* | romp-* | rs6000-* | rx-* \
| sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \
| shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
| sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \
| sparclite-* \
| sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx?-* \
| tahoe-* \
| tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
| tile*-* \
| tron-* \
| ubicom32-* \
| v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \
| vax-* \
| we32k-* \
| x86-* | x86_64-* | xc16x-* | xps100-* \
| xstormy16-* | xtensa*-* \
| ymp-* \
| z8k-* | z80-*)
;;
# Recognize the basic CPU types without company name, with glob match.
xtensa*)
basic_machine=$basic_machine-unknown
;;
# Recognize the various machine names and aliases which stand
# for a CPU type and a company and sometimes even an OS.
386bsd)
basic_machine=i386-unknown
os=-bsd
;;
3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
basic_machine=m68000-att
;;
3b*)
basic_machine=we32k-att
;;
a29khif)
basic_machine=a29k-amd
os=-udi
;;
abacus)
basic_machine=abacus-unknown
;;
adobe68k)
basic_machine=m68010-adobe
os=-scout
;;
alliant | fx80)
basic_machine=fx80-alliant
;;
altos | altos3068)
basic_machine=m68k-altos
;;
am29k)
basic_machine=a29k-none
os=-bsd
;;
amd64)
basic_machine=x86_64-pc
;;
amd64-*)
basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
amdahl)
basic_machine=580-amdahl
os=-sysv
;;
amiga | amiga-*)
basic_machine=m68k-unknown
;;
amigaos | amigados)
basic_machine=m68k-unknown
os=-amigaos
;;
amigaunix | amix)
basic_machine=m68k-unknown
os=-sysv4
;;
apollo68)
basic_machine=m68k-apollo
os=-sysv
;;
apollo68bsd)
basic_machine=m68k-apollo
os=-bsd
;;
aros)
basic_machine=i386-pc
os=-aros
;;
aux)
basic_machine=m68k-apple
os=-aux
;;
balance)
basic_machine=ns32k-sequent
os=-dynix
;;
blackfin)
basic_machine=bfin-unknown
os=-linux
;;
blackfin-*)
basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'`
os=-linux
;;
bluegene*)
basic_machine=powerpc-ibm
os=-cnk
;;
c54x-*)
basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
c55x-*)
basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
c6x-*)
basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
c90)
basic_machine=c90-cray
os=-unicos
;;
cegcc)
basic_machine=arm-unknown
os=-cegcc
;;
convex-c1)
basic_machine=c1-convex
os=-bsd
;;
convex-c2)
basic_machine=c2-convex
os=-bsd
;;
convex-c32)
basic_machine=c32-convex
os=-bsd
;;
convex-c34)
basic_machine=c34-convex
os=-bsd
;;
convex-c38)
basic_machine=c38-convex
os=-bsd
;;
cray | j90)
basic_machine=j90-cray
os=-unicos
;;
craynv)
basic_machine=craynv-cray
os=-unicosmp
;;
cr16 | cr16-*)
basic_machine=cr16-unknown
os=-elf
;;
crds | unos)
basic_machine=m68k-crds
;;
crisv32 | crisv32-* | etraxfs*)
basic_machine=crisv32-axis
;;
cris | cris-* | etrax*)
basic_machine=cris-axis
;;
crx)
basic_machine=crx-unknown
os=-elf
;;
da30 | da30-*)
basic_machine=m68k-da30
;;
decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn)
basic_machine=mips-dec
;;
decsystem10* | dec10*)
basic_machine=pdp10-dec
os=-tops10
;;
decsystem20* | dec20*)
basic_machine=pdp10-dec
os=-tops20
;;
delta | 3300 | motorola-3300 | motorola-delta \
| 3300-motorola | delta-motorola)
basic_machine=m68k-motorola
;;
delta88)
basic_machine=m88k-motorola
os=-sysv3
;;
dicos)
basic_machine=i686-pc
os=-dicos
;;
djgpp)
basic_machine=i586-pc
os=-msdosdjgpp
;;
dpx20 | dpx20-*)
basic_machine=rs6000-bull
os=-bosx
;;
dpx2* | dpx2*-bull)
basic_machine=m68k-bull
os=-sysv3
;;
ebmon29k)
basic_machine=a29k-amd
os=-ebmon
;;
elxsi)
basic_machine=elxsi-elxsi
os=-bsd
;;
encore | umax | mmax)
basic_machine=ns32k-encore
;;
es1800 | OSE68k | ose68k | ose | OSE)
basic_machine=m68k-ericsson
os=-ose
;;
fx2800)
basic_machine=i860-alliant
;;
genix)
basic_machine=ns32k-ns
;;
gmicro)
basic_machine=tron-gmicro
os=-sysv
;;
go32)
basic_machine=i386-pc
os=-go32
;;
h3050r* | hiux*)
basic_machine=hppa1.1-hitachi
os=-hiuxwe2
;;
h8300hms)
basic_machine=h8300-hitachi
os=-hms
;;
h8300xray)
basic_machine=h8300-hitachi
os=-xray
;;
h8500hms)
basic_machine=h8500-hitachi
os=-hms
;;
harris)
basic_machine=m88k-harris
os=-sysv3
;;
hp300-*)
basic_machine=m68k-hp
;;
hp300bsd)
basic_machine=m68k-hp
os=-bsd
;;
hp300hpux)
basic_machine=m68k-hp
os=-hpux
;;
hp3k9[0-9][0-9] | hp9[0-9][0-9])
basic_machine=hppa1.0-hp
;;
hp9k2[0-9][0-9] | hp9k31[0-9])
basic_machine=m68000-hp
;;
hp9k3[2-9][0-9])
basic_machine=m68k-hp
;;
hp9k6[0-9][0-9] | hp6[0-9][0-9])
basic_machine=hppa1.0-hp
;;
hp9k7[0-79][0-9] | hp7[0-79][0-9])
basic_machine=hppa1.1-hp
;;
hp9k78[0-9] | hp78[0-9])
# FIXME: really hppa2.0-hp
basic_machine=hppa1.1-hp
;;
hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893)
# FIXME: really hppa2.0-hp
basic_machine=hppa1.1-hp
;;
hp9k8[0-9][13679] | hp8[0-9][13679])
basic_machine=hppa1.1-hp
;;
hp9k8[0-9][0-9] | hp8[0-9][0-9])
basic_machine=hppa1.0-hp
;;
hppa-next)
os=-nextstep3
;;
hppaosf)
basic_machine=hppa1.1-hp
os=-osf
;;
hppro)
basic_machine=hppa1.1-hp
os=-proelf
;;
i370-ibm* | ibm*)
basic_machine=i370-ibm
;;
i*86v32)
basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
os=-sysv32
;;
i*86v4*)
basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
os=-sysv4
;;
i*86v)
basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
os=-sysv
;;
i*86sol2)
basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
os=-solaris2
;;
i386mach)
basic_machine=i386-mach
os=-mach
;;
i386-vsta | vsta)
basic_machine=i386-unknown
os=-vsta
;;
iris | iris4d)
basic_machine=mips-sgi
case $os in
-irix*)
;;
*)
os=-irix4
;;
esac
;;
isi68 | isi)
basic_machine=m68k-isi
os=-sysv
;;
m68knommu)
basic_machine=m68k-unknown
os=-linux
;;
m68knommu-*)
basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'`
os=-linux
;;
m88k-omron*)
basic_machine=m88k-omron
;;
magnum | m3230)
basic_machine=mips-mips
os=-sysv
;;
merlin)
basic_machine=ns32k-utek
os=-sysv
;;
microblaze*)
basic_machine=microblaze-xilinx
;;
mingw64)
basic_machine=x86_64-pc
os=-mingw64
;;
mingw32)
basic_machine=i686-pc
os=-mingw32
;;
mingw32ce)
basic_machine=arm-unknown
os=-mingw32ce
;;
miniframe)
basic_machine=m68000-convergent
;;
*mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*)
basic_machine=m68k-atari
os=-mint
;;
mips3*-*)
basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
;;
mips3*)
basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
;;
monitor)
basic_machine=m68k-rom68k
os=-coff
;;
morphos)
basic_machine=powerpc-unknown
os=-morphos
;;
msdos)
basic_machine=i386-pc
os=-msdos
;;
ms1-*)
basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'`
;;
msys)
basic_machine=i686-pc
os=-msys
;;
mvs)
basic_machine=i370-ibm
os=-mvs
;;
nacl)
basic_machine=le32-unknown
os=-nacl
;;
ncr3000)
basic_machine=i486-ncr
os=-sysv4
;;
netbsd386)
basic_machine=i386-unknown
os=-netbsd
;;
netwinder)
basic_machine=armv4l-rebel
os=-linux
;;
news | news700 | news800 | news900)
basic_machine=m68k-sony
os=-newsos
;;
news1000)
basic_machine=m68030-sony
os=-newsos
;;
news-3600 | risc-news)
basic_machine=mips-sony
os=-newsos
;;
necv70)
basic_machine=v70-nec
os=-sysv
;;
next | m*-next )
basic_machine=m68k-next
case $os in
-nextstep* )
;;
-ns2*)
os=-nextstep2
;;
*)
os=-nextstep3
;;
esac
;;
nh3000)
basic_machine=m68k-harris
os=-cxux
;;
nh[45]000)
basic_machine=m88k-harris
os=-cxux
;;
nindy960)
basic_machine=i960-intel
os=-nindy
;;
mon960)
basic_machine=i960-intel
os=-mon960
;;
nonstopux)
basic_machine=mips-compaq
os=-nonstopux
;;
np1)
basic_machine=np1-gould
;;
neo-tandem)
basic_machine=neo-tandem
;;
nse-tandem)
basic_machine=nse-tandem
;;
nsr-tandem)
basic_machine=nsr-tandem
;;
op50n-* | op60c-*)
basic_machine=hppa1.1-oki
os=-proelf
;;
openrisc | openrisc-*)
basic_machine=or32-unknown
;;
os400)
basic_machine=powerpc-ibm
os=-os400
;;
OSE68000 | ose68000)
basic_machine=m68000-ericsson
os=-ose
;;
os68k)
basic_machine=m68k-none
os=-os68k
;;
pa-hitachi)
basic_machine=hppa1.1-hitachi
os=-hiuxwe2
;;
paragon)
basic_machine=i860-intel
os=-osf
;;
parisc)
basic_machine=hppa-unknown
os=-linux
;;
parisc-*)
basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'`
os=-linux
;;
pbd)
basic_machine=sparc-tti
;;
pbb)
basic_machine=m68k-tti
;;
pc532 | pc532-*)
basic_machine=ns32k-pc532
;;
pc98)
basic_machine=i386-pc
;;
pc98-*)
basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
pentium | p5 | k5 | k6 | nexgen | viac3)
basic_machine=i586-pc
;;
pentiumpro | p6 | 6x86 | athlon | athlon_*)
basic_machine=i686-pc
;;
pentiumii | pentium2 | pentiumiii | pentium3)
basic_machine=i686-pc
;;
pentium4)
basic_machine=i786-pc
;;
pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
pentiumpro-* | p6-* | 6x86-* | athlon-*)
basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*)
basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
pentium4-*)
basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
pn)
basic_machine=pn-gould
;;
power) basic_machine=power-ibm
;;
ppc | ppcbe) basic_machine=powerpc-unknown
;;
ppc-* | ppcbe-*)
basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
ppcle | powerpclittle | ppc-le | powerpc-little)
basic_machine=powerpcle-unknown
;;
ppcle-* | powerpclittle-*)
basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
ppc64) basic_machine=powerpc64-unknown
;;
ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
ppc64le | powerpc64little | ppc64-le | powerpc64-little)
basic_machine=powerpc64le-unknown
;;
ppc64le-* | powerpc64little-*)
basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
ps2)
basic_machine=i386-ibm
;;
pw32)
basic_machine=i586-unknown
os=-pw32
;;
rdos | rdos64)
basic_machine=x86_64-pc
os=-rdos
;;
rdos32)
basic_machine=i386-pc
os=-rdos
;;
rom68k)
basic_machine=m68k-rom68k
os=-coff
;;
rm[46]00)
basic_machine=mips-siemens
;;
rtpc | rtpc-*)
basic_machine=romp-ibm
;;
s390 | s390-*)
basic_machine=s390-ibm
;;
s390x | s390x-*)
basic_machine=s390x-ibm
;;
sa29200)
basic_machine=a29k-amd
os=-udi
;;
sb1)
basic_machine=mipsisa64sb1-unknown
;;
sb1el)
basic_machine=mipsisa64sb1el-unknown
;;
sde)
basic_machine=mipsisa32-sde
os=-elf
;;
sei)
basic_machine=mips-sei
os=-seiux
;;
sequent)
basic_machine=i386-sequent
;;
sh)
basic_machine=sh-hitachi
os=-hms
;;
sh5el)
basic_machine=sh5le-unknown
;;
sh64)
basic_machine=sh64-unknown
;;
sparclite-wrs | simso-wrs)
basic_machine=sparclite-wrs
os=-vxworks
;;
sps7)
basic_machine=m68k-bull
os=-sysv2
;;
spur)
basic_machine=spur-unknown
;;
st2000)
basic_machine=m68k-tandem
;;
stratus)
basic_machine=i860-stratus
os=-sysv4
;;
strongarm-* | thumb-*)
basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
sun2)
basic_machine=m68000-sun
;;
sun2os3)
basic_machine=m68000-sun
os=-sunos3
;;
sun2os4)
basic_machine=m68000-sun
os=-sunos4
;;
sun3os3)
basic_machine=m68k-sun
os=-sunos3
;;
sun3os4)
basic_machine=m68k-sun
os=-sunos4
;;
sun4os3)
basic_machine=sparc-sun
os=-sunos3
;;
sun4os4)
basic_machine=sparc-sun
os=-sunos4
;;
sun4sol2)
basic_machine=sparc-sun
os=-solaris2
;;
sun3 | sun3-*)
basic_machine=m68k-sun
;;
sun4)
basic_machine=sparc-sun
;;
sun386 | sun386i | roadrunner)
basic_machine=i386-sun
;;
sv1)
basic_machine=sv1-cray
os=-unicos
;;
symmetry)
basic_machine=i386-sequent
os=-dynix
;;
t3e)
basic_machine=alphaev5-cray
os=-unicos
;;
t90)
basic_machine=t90-cray
os=-unicos
;;
tile*)
basic_machine=$basic_machine-unknown
os=-linux-gnu
;;
tx39)
basic_machine=mipstx39-unknown
;;
tx39el)
basic_machine=mipstx39el-unknown
;;
toad1)
basic_machine=pdp10-xkl
os=-tops20
;;
tower | tower-32)
basic_machine=m68k-ncr
;;
tpf)
basic_machine=s390x-ibm
os=-tpf
;;
udi29k)
basic_machine=a29k-amd
os=-udi
;;
ultra3)
basic_machine=a29k-nyu
os=-sym1
;;
v810 | necv810)
basic_machine=v810-nec
os=-none
;;
vaxv)
basic_machine=vax-dec
os=-sysv
;;
vms)
basic_machine=vax-dec
os=-vms
;;
vpp*|vx|vx-*)
basic_machine=f301-fujitsu
;;
vxworks960)
basic_machine=i960-wrs
os=-vxworks
;;
vxworks68)
basic_machine=m68k-wrs
os=-vxworks
;;
vxworks29k)
basic_machine=a29k-wrs
os=-vxworks
;;
w65*)
basic_machine=w65-wdc
os=-none
;;
w89k-*)
basic_machine=hppa1.1-winbond
os=-proelf
;;
xbox)
basic_machine=i686-pc
os=-mingw32
;;
xps | xps100)
basic_machine=xps100-honeywell
;;
xscale-* | xscalee[bl]-*)
basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'`
;;
ymp)
basic_machine=ymp-cray
os=-unicos
;;
z8k-*-coff)
basic_machine=z8k-unknown
os=-sim
;;
z80-*-coff)
basic_machine=z80-unknown
os=-sim
;;
none)
basic_machine=none-none
os=-none
;;
# Here we handle the default manufacturer of certain CPU types. It is in
# some cases the only manufacturer, in others, it is the most popular.
w89k)
basic_machine=hppa1.1-winbond
;;
op50n)
basic_machine=hppa1.1-oki
;;
op60c)
basic_machine=hppa1.1-oki
;;
romp)
basic_machine=romp-ibm
;;
mmix)
basic_machine=mmix-knuth
;;
rs6000)
basic_machine=rs6000-ibm
;;
vax)
basic_machine=vax-dec
;;
pdp10)
# there are many clones, so DEC is not a safe bet
basic_machine=pdp10-unknown
;;
pdp11)
basic_machine=pdp11-dec
;;
we32k)
basic_machine=we32k-att
;;
sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele)
basic_machine=sh-unknown
;;
sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v)
basic_machine=sparc-sun
;;
cydra)
basic_machine=cydra-cydrome
;;
orion)
basic_machine=orion-highlevel
;;
orion105)
basic_machine=clipper-highlevel
;;
mac | mpw | mac-mpw)
basic_machine=m68k-apple
;;
pmac | pmac-mpw)
basic_machine=powerpc-apple
;;
*-unknown)
# Make sure to match an already-canonicalized machine name.
;;
*)
echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
exit 1
;;
esac
# Here we canonicalize certain aliases for manufacturers.
case $basic_machine in
*-digital*)
basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'`
;;
*-commodore*)
basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'`
;;
*)
;;
esac
# Decode manufacturer-specific aliases for certain operating systems.
if [ x"$os" != x"" ]
then
case $os in
# First match some system type aliases
# that might get confused with valid system types.
# -solaris* is a basic system type, with this one exception.
-auroraux)
os=-auroraux
;;
-solaris1 | -solaris1.*)
os=`echo $os | sed -e 's|solaris1|sunos4|'`
;;
-solaris)
os=-solaris2
;;
-svr4*)
os=-sysv4
;;
-unixware*)
os=-sysv4.2uw
;;
-gnu/linux*)
os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
;;
# First accept the basic system types.
# The portable systems comes first.
# Each alternative MUST END IN A *, to match a version number.
# -sysv* is not here because it comes later, after sysvr4.
-gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
| -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\
| -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \
| -sym* | -kopensolaris* | -plan9* \
| -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
| -aos* | -aros* \
| -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
| -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
| -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \
| -bitrig* | -openbsd* | -solidbsd* \
| -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
| -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
| -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
| -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
| -chorusos* | -chorusrdb* | -cegcc* \
| -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
| -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \
| -linux-newlib* | -linux-musl* | -linux-uclibc* \
| -uxpv* | -beos* | -mpeix* | -udk* \
| -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
| -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
| -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
| -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
| -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
| -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
| -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es*)
# Remember, each alternative MUST END IN *, to match a version number.
;;
-qnx*)
case $basic_machine in
x86-* | i*86-*)
;;
*)
os=-nto$os
;;
esac
;;
-nto-qnx*)
;;
-nto*)
os=`echo $os | sed -e 's|nto|nto-qnx|'`
;;
-sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \
| -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \
| -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*)
;;
-mac*)
os=`echo $os | sed -e 's|mac|macos|'`
;;
-linux-dietlibc)
os=-linux-dietlibc
;;
-linux*)
os=`echo $os | sed -e 's|linux|linux-gnu|'`
;;
-sunos5*)
os=`echo $os | sed -e 's|sunos5|solaris2|'`
;;
-sunos6*)
os=`echo $os | sed -e 's|sunos6|solaris3|'`
;;
-opened*)
os=-openedition
;;
-os400*)
os=-os400
;;
-wince*)
os=-wince
;;
-osfrose*)
os=-osfrose
;;
-osf*)
os=-osf
;;
-utek*)
os=-bsd
;;
-dynix*)
os=-bsd
;;
-acis*)
os=-aos
;;
-atheos*)
os=-atheos
;;
-syllable*)
os=-syllable
;;
-386bsd)
os=-bsd
;;
-ctix* | -uts*)
os=-sysv
;;
-nova*)
os=-rtmk-nova
;;
-ns2 )
os=-nextstep2
;;
-nsk*)
os=-nsk
;;
# Preserve the version number of sinix5.
-sinix5.*)
os=`echo $os | sed -e 's|sinix|sysv|'`
;;
-sinix*)
os=-sysv4
;;
-tpf*)
os=-tpf
;;
-triton*)
os=-sysv3
;;
-oss*)
os=-sysv3
;;
-svr4)
os=-sysv4
;;
-svr3)
os=-sysv3
;;
-sysvr4)
os=-sysv4
;;
# This must come after -sysvr4.
-sysv*)
;;
-ose*)
os=-ose
;;
-es1800*)
os=-ose
;;
-xenix)
os=-xenix
;;
-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
os=-mint
;;
-aros*)
os=-aros
;;
-zvmoe)
os=-zvmoe
;;
-dicos*)
os=-dicos
;;
-nacl*)
;;
-none)
;;
*)
# Get rid of the `-' at the beginning of $os.
os=`echo $os | sed 's/[^-]*-//'`
echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2
exit 1
;;
esac
else
# Here we handle the default operating systems that come with various machines.
# The value should be what the vendor currently ships out the door with their
# machine or put another way, the most popular os provided with the machine.
# Note that if you're going to try to match "-MANUFACTURER" here (say,
# "-sun"), then you have to tell the case statement up towards the top
# that MANUFACTURER isn't an operating system. Otherwise, code above
# will signal an error saying that MANUFACTURER isn't an operating
# system, and we'll never get to this point.
case $basic_machine in
score-*)
os=-elf
;;
spu-*)
os=-elf
;;
*-acorn)
os=-riscix1.2
;;
arm*-rebel)
os=-linux
;;
arm*-semi)
os=-aout
;;
c4x-* | tic4x-*)
os=-coff
;;
c8051-*)
os=-elf
;;
hexagon-*)
os=-elf
;;
tic54x-*)
os=-coff
;;
tic55x-*)
os=-coff
;;
tic6x-*)
os=-coff
;;
# This must come before the *-dec entry.
pdp10-*)
os=-tops20
;;
pdp11-*)
os=-none
;;
*-dec | vax-*)
os=-ultrix4.2
;;
m68*-apollo)
os=-domain
;;
i386-sun)
os=-sunos4.0.2
;;
m68000-sun)
os=-sunos3
;;
m68*-cisco)
os=-aout
;;
mep-*)
os=-elf
;;
mips*-cisco)
os=-elf
;;
mips*-*)
os=-elf
;;
or1k-*)
os=-elf
;;
or32-*)
os=-coff
;;
*-tti) # must be before sparc entry or we get the wrong os.
os=-sysv3
;;
sparc-* | *-sun)
os=-sunos4.1.1
;;
*-be)
os=-beos
;;
*-haiku)
os=-haiku
;;
*-ibm)
os=-aix
;;
*-knuth)
os=-mmixware
;;
*-wec)
os=-proelf
;;
*-winbond)
os=-proelf
;;
*-oki)
os=-proelf
;;
*-hp)
os=-hpux
;;
*-hitachi)
os=-hiux
;;
i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent)
os=-sysv
;;
*-cbm)
os=-amigaos
;;
*-dg)
os=-dgux
;;
*-dolphin)
os=-sysv3
;;
m68k-ccur)
os=-rtu
;;
m88k-omron*)
os=-luna
;;
*-next )
os=-nextstep
;;
*-sequent)
os=-ptx
;;
*-crds)
os=-unos
;;
*-ns)
os=-genix
;;
i370-*)
os=-mvs
;;
*-next)
os=-nextstep3
;;
*-gould)
os=-sysv
;;
*-highlevel)
os=-bsd
;;
*-encore)
os=-bsd
;;
*-sgi)
os=-irix
;;
*-siemens)
os=-sysv4
;;
*-masscomp)
os=-rtu
;;
f30[01]-fujitsu | f700-fujitsu)
os=-uxpv
;;
*-rom68k)
os=-coff
;;
*-*bug)
os=-coff
;;
*-apple)
os=-macos
;;
*-atari*)
os=-mint
;;
*)
os=-none
;;
esac
fi
# Here we handle the case where we know the os, and the CPU type, but not the
# manufacturer. We pick the logical manufacturer.
vendor=unknown
case $basic_machine in
*-unknown)
case $os in
-riscix*)
vendor=acorn
;;
-sunos*)
vendor=sun
;;
-cnk*|-aix*)
vendor=ibm
;;
-beos*)
vendor=be
;;
-hpux*)
vendor=hp
;;
-mpeix*)
vendor=hp
;;
-hiux*)
vendor=hitachi
;;
-unos*)
vendor=crds
;;
-dgux*)
vendor=dg
;;
-luna*)
vendor=omron
;;
-genix*)
vendor=ns
;;
-mvs* | -opened*)
vendor=ibm
;;
-os400*)
vendor=ibm
;;
-ptx*)
vendor=sequent
;;
-tpf*)
vendor=ibm
;;
-vxsim* | -vxworks* | -windiss*)
vendor=wrs
;;
-aux*)
vendor=apple
;;
-hms*)
vendor=hitachi
;;
-mpw* | -macos*)
vendor=apple
;;
-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
vendor=atari
;;
-vos*)
vendor=stratus
;;
esac
basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
;;
esac
echo $basic_machine$os
exit
# Local variables:
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "timestamp='"
# time-stamp-format: "%:y-%02m-%02d"
# time-stamp-end: "'"
# End:
ddpt-0.94/autogen.sh 0000755 0001750 0001750 00000130141 11173672404 013403 0 ustar dougg dougg #!/bin/sh
# a u t o g e n . s h
#
# Copyright (c) 2005-2007 United States Government as represented by
# the U.S. Army Research Laboratory.
#
# 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 ``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 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.
#
###
#
# Script for automatically preparing the sources for compilation by
# performing the myrid of necessary steps. The script attempts to
# detect proper version support, and outputs warnings about particular
# systems that have autotool peculiarities.
#
# Basically, if everything is set up and installed correctly, the
# script will validate that minimum versions of the GNU Build System
# tools are installed, account for several common configuration
# issues, and then simply run autoreconf for you.
#
# If autoreconf fails, which can happen for many valid configurations,
# this script proceeds to run manual preparation steps effectively
# providing a POSIX shell script (mostly complete) reimplementation of
# autoreconf.
#
# The AUTORECONF, AUTOCONF, AUTOMAKE, LIBTOOLIZE, ACLOCAL, AUTOHEADER
# environment variables and corresponding _OPTIONS variables (e.g.
# AUTORECONF_OPTIONS) may be used to override the default automatic
# detection behaviors. Similarly the _VERSION variables will override
# the minimum required version numbers.
#
# Examples:
#
# To obtain help on usage:
# ./autogen.sh --help
#
# To obtain verbose output:
# ./autogen.sh --verbose
#
# To skip autoreconf and prepare manually:
# AUTORECONF=false ./autogen.sh
#
# To verbosely try running with an older (unsupported) autoconf:
# AUTOCONF_VERSION=2.50 ./autogen.sh --verbose
#
# Author: Christopher Sean Morrison
#
######################################################################
# set to minimum acceptible version of autoconf
if [ "x$AUTOCONF_VERSION" = "x" ] ; then
AUTOCONF_VERSION=2.52
fi
# set to minimum acceptible version of automake
if [ "x$AUTOMAKE_VERSION" = "x" ] ; then
AUTOMAKE_VERSION=1.6.0
fi
# set to minimum acceptible version of libtool
if [ "x$LIBTOOL_VERSION" = "x" ] ; then
LIBTOOL_VERSION=1.4.2
fi
##################
# ident function #
##################
ident ( ) {
# extract copyright from header
__copyright="`grep Copyright $AUTOGEN_SH | head -${HEAD_N}1 | awk '{print $4}'`"
if [ "x$__copyright" = "x" ] ; then
__copyright="`date +%Y`"
fi
# extract version from CVS Id string
__id="$Id: autogen.sh,v 14.97 2007/06/18 22:25:02 brlcad Exp $"
__version="`echo $__id | sed 's/.*\([0-9][0-9][0-9][0-9]\)[-\/]\([0-9][0-9]\)[-\/]\([0-9][0-9]\).*/\1\2\3/'`"
if [ "x$__version" = "x" ] ; then
__version=""
fi
echo "autogen.sh build preparation script by Christopher Sean Morrison"
echo "revised 3-clause BSD-style license, copyright (c) $__copyright"
echo "script version $__version, ISO/IEC 9945 POSIX shell script"
}
##################
# USAGE FUNCTION #
##################
usage ( ) {
echo "Usage: $AUTOGEN_SH [-h|--help] [-v|--verbose] [-q|--quiet] [--version]"
echo " --help Help on $NAME_OF_AUTOGEN usage"
echo " --verbose Verbose progress output"
echo " --quiet Quiet suppressed progress output"
echo " --version Only perform GNU Build System version checks"
echo
echo "Description: This script will validate that minimum versions of the"
echo "GNU Build System tools are installed and then run autoreconf for you."
echo "Should autoreconf fail, manual preparation steps will be run"
echo "potentially accounting for several common preparation issues. The"
echo "AUTORECONF, AUTOCONF, AUTOMAKE, LIBTOOLIZE, ACLOCAL, AUTOHEADER,"
echo "PROJECT, & CONFIGURE environment variables and corresponding _OPTIONS"
echo "variables (e.g. AUTORECONF_OPTIONS) may be used to override the"
echo "default automatic detection behavior."
echo
ident
return 0
}
##########################
# VERSION_ERROR FUNCTION #
##########################
version_error ( ) {
if [ "x$1" = "x" ] ; then
echo "INTERNAL ERROR: version_error was not provided a version"
exit 1
fi
if [ "x$2" = "x" ] ; then
echo "INTERNAL ERROR: version_error was not provided an application name"
exit 1
fi
$ECHO
$ECHO "ERROR: To prepare the ${PROJECT} build system from scratch,"
$ECHO " at least version $1 of $2 must be installed."
$ECHO
$ECHO "$NAME_OF_AUTOGEN does not need to be run on the same machine that will"
$ECHO "run configure or make. Either the GNU Autotools will need to be installed"
$ECHO "or upgraded on this system, or $NAME_OF_AUTOGEN must be run on the source"
$ECHO "code on another system and then transferred to here. -- Cheers!"
$ECHO
}
##########################
# VERSION_CHECK FUNCTION #
##########################
version_check ( ) {
if [ "x$1" = "x" ] ; then
echo "INTERNAL ERROR: version_check was not provided a minimum version"
exit 1
fi
_min="$1"
if [ "x$2" = "x" ] ; then
echo "INTERNAL ERROR: version check was not provided a comparison version"
exit 1
fi
_cur="$2"
# needed to handle versions like 1.10 and 1.4-p6
_min="`echo ${_min}. | sed 's/[^0-9]/./g' | sed 's/\.\././g'`"
_cur="`echo ${_cur}. | sed 's/[^0-9]/./g' | sed 's/\.\././g'`"
_min_major="`echo $_min | cut -d. -f1`"
_min_minor="`echo $_min | cut -d. -f2`"
_min_patch="`echo $_min | cut -d. -f3`"
_cur_major="`echo $_cur | cut -d. -f1`"
_cur_minor="`echo $_cur | cut -d. -f2`"
_cur_patch="`echo $_cur | cut -d. -f3`"
if [ "x$_min_major" = "x" ] ; then
_min_major=0
fi
if [ "x$_min_minor" = "x" ] ; then
_min_minor=0
fi
if [ "x$_min_patch" = "x" ] ; then
_min_patch=0
fi
if [ "x$_cur_minor" = "x" ] ; then
_cur_major=0
fi
if [ "x$_cur_minor" = "x" ] ; then
_cur_minor=0
fi
if [ "x$_cur_patch" = "x" ] ; then
_cur_patch=0
fi
$VERBOSE_ECHO "Checking if ${_cur_major}.${_cur_minor}.${_cur_patch} is greater than ${_min_major}.${_min_minor}.${_min_patch}"
if [ $_min_major -lt $_cur_major ] ; then
return 0
elif [ $_min_major -eq $_cur_major ] ; then
if [ $_min_minor -lt $_cur_minor ] ; then
return 0
elif [ $_min_minor -eq $_cur_minor ] ; then
if [ $_min_patch -lt $_cur_patch ] ; then
return 0
elif [ $_min_patch -eq $_cur_patch ] ; then
return 0
fi
fi
fi
return 1
}
######################################
# LOCATE_CONFIGURE_TEMPLATE FUNCTION #
######################################
locate_configure_template ( ) {
_pwd="`pwd`"
if test -f "./configure.ac" ; then
echo "./configure.ac"
elif test -f "./configure.in" ; then
echo "./configure.in"
elif test -f "$_pwd/configure.ac" ; then
echo "$_pwd/configure.ac"
elif test -f "$_pwd/configure.in" ; then
echo "$_pwd/configure.in"
elif test -f "$PATH_TO_AUTOGEN/configure.ac" ; then
echo "$PATH_TO_AUTOGEN/configure.ac"
elif test -f "$PATH_TO_AUTOGEN/configure.in" ; then
echo "$PATH_TO_AUTOGEN/configure.in"
fi
}
##################
# argument check #
##################
ARGS="$*"
PATH_TO_AUTOGEN="`dirname $0`"
NAME_OF_AUTOGEN="`basename $0`"
AUTOGEN_SH="$PATH_TO_AUTOGEN/$NAME_OF_AUTOGEN"
LIBTOOL_M4="${PATH_TO_AUTOGEN}/misc/libtool.m4"
if [ "x$HELP" = "x" ] ; then
HELP=no
fi
if [ "x$QUIET" = "x" ] ; then
QUIET=no
fi
if [ "x$VERBOSE" = "x" ] ; then
VERBOSE=no
fi
if [ "x$VERSION_ONLY" = "x" ] ; then
VERSION_ONLY=no
fi
if [ "x$AUTORECONF_OPTIONS" = "x" ] ; then
AUTORECONF_OPTIONS="-i -f"
fi
if [ "x$AUTOCONF_OPTIONS" = "x" ] ; then
AUTOCONF_OPTIONS="-f"
fi
if [ "x$AUTOMAKE_OPTIONS" = "x" ] ; then
AUTOMAKE_OPTIONS="-a -c -f"
fi
ALT_AUTOMAKE_OPTIONS="-a -c"
if [ "x$LIBTOOLIZE_OPTIONS" = "x" ] ; then
LIBTOOLIZE_OPTIONS="--automake -c -f"
fi
ALT_LIBTOOLIZE_OPTIONS="--automake --copy --force"
if [ "x$ACLOCAL_OPTIONS" = "x" ] ; then
ACLOCAL_OPTIONS=""
fi
if [ "x$AUTOHEADER_OPTIONS" = "x" ] ; then
AUTOHEADER_OPTIONS=""
fi
for arg in $ARGS ; do
case "x$arg" in
x--help) HELP=yes ;;
x-[hH]) HELP=yes ;;
x--quiet) QUIET=yes ;;
x-[qQ]) QUIET=yes ;;
x--verbose) VERBOSE=yes ;;
x-[vV]) VERBOSE=yes ;;
x--version) VERSION_ONLY=yes ;;
*)
echo "Unknown option: $arg"
echo
usage
exit 1
;;
esac
done
#####################
# environment check #
#####################
# sanity check before recursions potentially begin
if [ ! -f "$AUTOGEN_SH" ] ; then
echo "INTERNAL ERROR: $AUTOGEN_SH does not exist"
if [ ! "x$0" = "x$AUTOGEN_SH" ] ; then
echo "INTERNAL ERROR: dirname/basename inconsistency: $0 != $AUTOGEN_SH"
fi
exit 1
fi
# force locale setting to C so things like date output as expected
LC_ALL=C
# commands that this script expects
for __cmd in echo head tail pwd ; do
echo "test" | $__cmd > /dev/null 2>&1
if [ $? != 0 ] ; then
echo "INTERNAL ERROR: '${__cmd}' command is required"
exit 2
fi
done
echo "test" | grep "test" > /dev/null 2>&1
if test ! x$? = x0 ; then
echo "INTERNAL ERROR: grep command is required"
exit 1
fi
echo "test" | sed "s/test/test/" > /dev/null 2>&1
if test ! x$? = x0 ; then
echo "INTERNAL ERROR: sed command is required"
exit 1
fi
# determine the behavior of echo
case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in
*c*,-n*) ECHO_N= ECHO_C='
' ECHO_T=' ' ;;
*c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;;
*) ECHO_N= ECHO_C='\c' ECHO_T= ;;
esac
# determine the behavior of head
case "x`echo 'head' | head -n 1 2>&1`" in
*xhead*) HEAD_N="n " ;;
*) HEAD_N="" ;;
esac
# determine the behavior of tail
case "x`echo 'tail' | tail -n 1 2>&1`" in
*xtail*) TAIL_N="n " ;;
*) TAIL_N="" ;;
esac
VERBOSE_ECHO=:
ECHO=:
if [ "x$QUIET" = "xyes" ] ; then
if [ "x$VERBOSE" = "xyes" ] ; then
echo "Verbose output quelled by quiet option. Further output disabled."
fi
else
ECHO=echo
if [ "x$VERBOSE" = "xyes" ] ; then
echo "Verbose output enabled"
VERBOSE_ECHO=echo
fi
fi
# allow a recursive run to disable further recursions
if [ "x$RUN_RECURSIVE" = "x" ] ; then
RUN_RECURSIVE=yes
fi
################################################
# check for help arg and bypass version checks #
################################################
if [ "x`echo $ARGS | sed 's/.*[hH][eE][lL][pP].*/help/'`" = "xhelp" ] ; then
HELP=yes
fi
if [ "x$HELP" = "xyes" ] ; then
usage
$ECHO "---"
$ECHO "Help was requested. No preparation or configuration will be performed."
exit 0
fi
#######################
# set up signal traps #
#######################
untrap_abnormal ( ) {
for sig in 1 2 13 15; do
trap - $sig
done
}
# do this cleanup whenever we exit.
trap '
# start from the root
if test -d "$START_PATH" ; then
cd "$START_PATH"
fi
# restore/delete backup files
if test "x$PFC_INIT" = "x1" ; then
recursive_restore
fi
' 0
# trap SIGHUP (1), SIGINT (2), SIGPIPE (13), SIGTERM (15)
for sig in 1 2 13 15; do
trap '
$ECHO ""
$ECHO "Aborting $NAME_OF_AUTOGEN: caught signal '$sig'"
# start from the root
if test -d "$START_PATH" ; then
cd "$START_PATH"
fi
# clean up on abnormal exit
$VERBOSE_ECHO "rm -rf autom4te.cache"
rm -rf autom4te.cache
if test -f "acinclude.m4.$$.backup" ; then
$VERBOSE_ECHO "cat acinclude.m4.$$.backup > acinclude.m4"
chmod u+w acinclude.m4
cat acinclude.m4.$$.backup > acinclude.m4
$VERBOSE_ECHO "rm -f acinclude.m4.$$.backup"
rm -f acinclude.m4.$$.backup
fi
{ (exit 1); exit 1; }
' $sig
done
#############################
# look for a configure file #
#############################
if [ "x$CONFIGURE" = "x" ] ; then
CONFIGURE="`locate_configure_template`"
if [ ! "x$CONFIGURE" = "x" ] ; then
$VERBOSE_ECHO "Found a configure template: $CONFIGURE"
fi
else
$ECHO "Using CONFIGURE environment variable override: $CONFIGURE"
fi
if [ "x$CONFIGURE" = "x" ] ; then
if [ "x$VERSION_ONLY" = "xyes" ] ; then
CONFIGURE=/dev/null
else
$ECHO
$ECHO "A configure.ac or configure.in file could not be located implying"
$ECHO "that the GNU Build System is at least not used in this directory. In"
$ECHO "any case, there is nothing to do here without one of those files."
$ECHO
$ECHO "ERROR: No configure.in or configure.ac file found in `pwd`"
exit 1
fi
fi
####################
# get project name #
####################
if [ "x$PROJECT" = "x" ] ; then
PROJECT="`grep AC_INIT $CONFIGURE | grep -v '.*#.*AC_INIT' | tail -${TAIL_N}1 | sed 's/^[ ]*AC_INIT(\([^,)]*\).*/\1/' | sed 's/.*\[\(.*\)\].*/\1/'`"
if [ "x$PROJECT" = "xAC_INIT" ] ; then
# projects might be using the older/deprecated arg-less AC_INIT .. look for AM_INIT_AUTOMAKE instead
PROJECT="`grep AM_INIT_AUTOMAKE $CONFIGURE | grep -v '.*#.*AM_INIT_AUTOMAKE' | tail -${TAIL_N}1 | sed 's/^[ ]*AM_INIT_AUTOMAKE(\([^,)]*\).*/\1/' | sed 's/.*\[\(.*\)\].*/\1/'`"
fi
if [ "x$PROJECT" = "xAM_INIT_AUTOMAKE" ] ; then
PROJECT="project"
fi
if [ "x$PROJECT" = "x" ] ; then
PROJECT="project"
fi
else
$ECHO "Using PROJECT environment variable override: $PROJECT"
fi
$ECHO "Preparing the $PROJECT build system...please wait"
$ECHO
########################
# check for autoreconf #
########################
HAVE_AUTORECONF=no
if [ "x$AUTORECONF" = "x" ] ; then
for AUTORECONF in autoreconf ; do
$VERBOSE_ECHO "Checking autoreconf version: $AUTORECONF --version"
$AUTORECONF --version > /dev/null 2>&1
if [ $? = 0 ] ; then
HAVE_AUTORECONF=yes
break
fi
done
else
HAVE_AUTORECONF=yes
$ECHO "Using AUTORECONF environment variable override: $AUTORECONF"
fi
##########################
# autoconf version check #
##########################
_acfound=no
if [ "x$AUTOCONF" = "x" ] ; then
for AUTOCONF in autoconf ; do
$VERBOSE_ECHO "Checking autoconf version: $AUTOCONF --version"
$AUTOCONF --version > /dev/null 2>&1
if [ $? = 0 ] ; then
_acfound=yes
break
fi
done
else
_acfound=yes
$ECHO "Using AUTOCONF environment variable override: $AUTOCONF"
fi
_report_error=no
if [ ! "x$_acfound" = "xyes" ] ; then
$ECHO "ERROR: Unable to locate GNU Autoconf."
_report_error=yes
else
_version="`$AUTOCONF --version | head -${HEAD_N}1 | sed 's/[^0-9]*\([0-9\.][0-9\.]*\)/\1/'`"
if [ "x$_version" = "x" ] ; then
_version="0.0.0"
fi
$ECHO "Found GNU Autoconf version $_version"
version_check "$AUTOCONF_VERSION" "$_version"
if [ $? -ne 0 ] ; then
_report_error=yes
fi
fi
if [ "x$_report_error" = "xyes" ] ; then
version_error "$AUTOCONF_VERSION" "GNU Autoconf"
exit 1
fi
##########################
# automake version check #
##########################
_amfound=no
if [ "x$AUTOMAKE" = "x" ] ; then
for AUTOMAKE in automake ; do
$VERBOSE_ECHO "Checking automake version: $AUTOMAKE --version"
$AUTOMAKE --version > /dev/null 2>&1
if [ $? = 0 ] ; then
_amfound=yes
break
fi
done
else
_amfound=yes
$ECHO "Using AUTOMAKE environment variable override: $AUTOMAKE"
fi
_report_error=no
if [ ! "x$_amfound" = "xyes" ] ; then
$ECHO
$ECHO "ERROR: Unable to locate GNU Automake."
_report_error=yes
else
_version="`$AUTOMAKE --version | head -${HEAD_N}1 | sed 's/[^0-9]*\([0-9\.][0-9\.]*\)/\1/'`"
if [ "x$_version" = "x" ] ; then
_version="0.0.0"
fi
$ECHO "Found GNU Automake version $_version"
version_check "$AUTOMAKE_VERSION" "$_version"
if [ $? -ne 0 ] ; then
_report_error=yes
fi
fi
if [ "x$_report_error" = "xyes" ] ; then
version_error "$AUTOMAKE_VERSION" "GNU Automake"
exit 1
fi
########################
# check for libtoolize #
########################
HAVE_LIBTOOLIZE=yes
HAVE_ALT_LIBTOOLIZE=no
_ltfound=no
if [ "x$LIBTOOLIZE" = "x" ] ; then
LIBTOOLIZE=libtoolize
$VERBOSE_ECHO "Checking libtoolize version: $LIBTOOLIZE --version"
$LIBTOOLIZE --version > /dev/null 2>&1
if [ ! $? = 0 ] ; then
HAVE_LIBTOOLIZE=no
$ECHO
if [ "x$HAVE_AUTORECONF" = "xno" ] ; then
$ECHO "Warning: libtoolize does not appear to be available."
else
$ECHO "Warning: libtoolize does not appear to be available. This means that"
$ECHO "the automatic build preparation via autoreconf will probably not work."
$ECHO "Preparing the build by running each step individually, however, should"
$ECHO "work and will be done automatically for you if autoreconf fails."
fi
# look for some alternates
for tool in glibtoolize libtoolize15 libtoolize14 libtoolize13 ; do
$VERBOSE_ECHO "Checking libtoolize alternate: $tool --version"
_glibtoolize="`$tool --version > /dev/null 2>&1`"
if [ $? = 0 ] ; then
$VERBOSE_ECHO "Found $tool --version"
_glti="`which $tool`"
if [ "x$_glti" = "x" ] ; then
$VERBOSE_ECHO "Cannot find $tool with which"
continue;
fi
if test ! -f "$_glti" ; then
$VERBOSE_ECHO "Cannot use $tool, $_glti is not a file"
continue;
fi
_gltidir="`dirname $_glti`"
if [ "x$_gltidir" = "x" ] ; then
$VERBOSE_ECHO "Cannot find $tool path with dirname of $_glti"
continue;
fi
if test ! -d "$_gltidir" ; then
$VERBOSE_ECHO "Cannot use $tool, $_gltidir is not a directory"
continue;
fi
HAVE_ALT_LIBTOOLIZE=yes
LIBTOOLIZE="$tool"
$ECHO
$ECHO "Fortunately, $tool was found which means that your system may simply"
$ECHO "have a non-standard or incomplete GNU Autotools install. If you have"
$ECHO "sufficient system access, it may be possible to quell this warning by"
$ECHO "running:"
$ECHO
sudo -V > /dev/null 2>&1
if [ $? = 0 ] ; then
$ECHO " sudo ln -s $_glti $_gltidir/libtoolize"
$ECHO
else
$ECHO " ln -s $_glti $_gltidir/libtoolize"
$ECHO
$ECHO "Run that as root or with proper permissions to the $_gltidir directory"
$ECHO
fi
_ltfound=yes
break
fi
done
else
_ltfound=yes
fi
else
_ltfound=yes
$ECHO "Using LIBTOOLIZE environment variable override: $LIBTOOLIZE"
fi
############################
# libtoolize version check #
############################
_report_error=no
if [ ! "x$_ltfound" = "xyes" ] ; then
$ECHO
$ECHO "ERROR: Unable to locate GNU Libtool."
_report_error=yes
else
_version="`$LIBTOOLIZE --version | head -${HEAD_N}1 | sed 's/[^0-9]*\([0-9\.][0-9\.]*\)/\1/'`"
if [ "x$_version" = "x" ] ; then
_version="0.0.0"
fi
$ECHO "Found GNU Libtool version $_version"
version_check "$LIBTOOL_VERSION" "$_version"
if [ $? -ne 0 ] ; then
_report_error=yes
fi
fi
if [ "x$_report_error" = "xyes" ] ; then
version_error "$LIBTOOL_VERSION" "GNU Libtool"
exit 1
fi
#####################
# check for aclocal #
#####################
if [ "x$ACLOCAL" = "x" ] ; then
for ACLOCAL in aclocal ; do
$VERBOSE_ECHO "Checking aclocal version: $ACLOCAL --version"
$ACLOCAL --version > /dev/null 2>&1
if [ $? = 0 ] ; then
break
fi
done
else
$ECHO "Using ACLOCAL environment variable override: $ACLOCAL"
fi
########################
# check for autoheader #
########################
if [ "x$AUTOHEADER" = "x" ] ; then
for AUTOHEADER in autoheader ; do
$VERBOSE_ECHO "Checking autoheader version: $AUTOHEADER --version"
$AUTOHEADER --version > /dev/null 2>&1
if [ $? = 0 ] ; then
break
fi
done
else
$ECHO "Using AUTOHEADER environment variable override: $AUTOHEADER"
fi
#########################
# check if version only #
#########################
$VERBOSE_ECHO "Checking whether to only output version information"
if [ "x$VERSION_ONLY" = "xyes" ] ; then
$ECHO
ident
$ECHO "---"
$ECHO "Version requested. No preparation or configuration will be performed."
exit 0
fi
#################################
# PROTECT_FROM_CLOBBER FUNCTION #
#################################
protect_from_clobber ( ) {
PFC_INIT=1
# protect COPYING & INSTALL from overwrite by automake. the
# automake force option will (inappropriately) ignore the existing
# contents of a COPYING and/or INSTALL files (depending on the
# version) instead of just forcing *missing* files like it does
# for AUTHORS, NEWS, and README. this is broken but extremely
# prevalent behavior, so we protect against it by keeping a backup
# of the file that can later be restored.
if test -f COPYING ; then
if test -f COPYING.$$.protect_from_automake.backup ; then
$VERBOSE_ECHO "Already backed up COPYING in `pwd`"
else
$VERBOSE_ECHO "Backing up COPYING in `pwd`"
$VERBOSE_ECHO "cp -p COPYING COPYING.$$.protect_from_automake.backup"
cp -p COPYING COPYING.$$.protect_from_automake.backup
fi
fi
if test -f INSTALL ; then
if test -f INSTALL.$$.protect_from_automake.backup ; then
$VERBOSE_ECHO "Already backed up INSTALL in `pwd`"
else
$VERBOSE_ECHO "Backing up INSTALL in `pwd`"
$VERBOSE_ECHO "cp -p INSTALL INSTALL.$$.protect_from_automake.backup"
cp -p INSTALL INSTALL.$$.protect_from_automake.backup
fi
fi
}
##############################
# RECURSIVE_PROTECT FUNCTION #
##############################
recursive_protect ( ) {
# for projects using recursive configure, run the build
# preparation steps for the subdirectories. this function assumes
# START_PATH was set to pwd before recursion begins so that
# relative paths work.
# git 'r done, protect COPYING and INSTALL from being clobbered
protect_from_clobber
if test -d autom4te.cache ; then
$VERBOSE_ECHO "Found an autom4te.cache directory, deleting it"
$VERBOSE_ECHO "rm -rf autom4te.cache"
rm -rf autom4te.cache
fi
# find configure template
_configure="`locate_configure_template`"
if [ "x$_configure" = "x" ] ; then
return
fi
# $VERBOSE_ECHO "Looking for configure template found `pwd`/$_configure"
# look for subdirs
# $VERBOSE_ECHO "Looking for subdirs in `pwd`"
_det_config_subdirs="`grep AC_CONFIG_SUBDIRS $_configure | grep -v '.*#.*AC_CONFIG_SUBDIRS' | sed 's/^[ ]*AC_CONFIG_SUBDIRS(\(.*\)).*/\1/' | sed 's/.*\[\(.*\)\].*/\1/'`"
CHECK_DIRS=""
for dir in $_det_config_subdirs ; do
if test -d "`pwd`/$dir" ; then
CHECK_DIRS="$CHECK_DIRS \"`pwd`/$dir\""
fi
done
# process subdirs
if [ ! "x$CHECK_DIRS" = "x" ] ; then
$VERBOSE_ECHO "Recursively scanning the following directories:"
$VERBOSE_ECHO " $CHECK_DIRS"
for dir in $CHECK_DIRS ; do
$VERBOSE_ECHO "Protecting files from automake in $dir"
cd "$START_PATH"
eval "cd $dir"
# recursively git 'r done
recursive_protect
done
fi
} # end of recursive_protect
#############################
# RESTORE_CLOBBERED FUNCION #
#############################
restore_clobbered ( ) {
# The automake (and autoreconf by extension) -f/--force-missing
# option may overwrite COPYING and INSTALL even if they do exist.
# Here we restore the files if necessary.
spacer=no
# COPYING
if test -f COPYING.$$.protect_from_automake.backup ; then
if test -f COPYING ; then
# compare entire content, restore if needed
if test "x`cat COPYING`" != "x`cat COPYING.$$.protect_from_automake.backup`" ; then
if test "x$spacer" = "xno" ; then
$VERBOSE_ECHO
spacer=yes
fi
# restore the backup
$VERBOSE_ECHO "Restoring COPYING from backup (automake -f likely clobbered it)"
$VERBOSE_ECHO "rm -f COPYING"
rm -f COPYING
$VERBOSE_ECHO "mv COPYING.$$.protect_from_automake.backup COPYING"
mv COPYING.$$.protect_from_automake.backup COPYING
fi # check contents
elif test -f COPYING.$$.protect_from_automake.backup ; then
$VERBOSE_ECHO "mv COPYING.$$.protect_from_automake.backup COPYING"
mv COPYING.$$.protect_from_automake.backup COPYING
fi # -f COPYING
# just in case
$VERBOSE_ECHO "rm -f COPYING.$$.protect_from_automake.backup"
rm -f COPYING.$$.protect_from_automake.backup
fi # -f COPYING.$$.protect_from_automake.backup
# INSTALL
if test -f INSTALL.$$.protect_from_automake.backup ; then
if test -f INSTALL ; then
# compare entire content, restore if needed
if test "x`cat INSTALL`" != "x`cat INSTALL.$$.protect_from_automake.backup`" ; then
if test "x$spacer" = "xno" ; then
$VERBOSE_ECHO
spacer=yes
fi
# restore the backup
$VERBOSE_ECHO "Restoring INSTALL from backup (automake -f likely clobbered it)"
$VERBOSE_ECHO "rm -f INSTALL"
rm -f INSTALL
$VERBOSE_ECHO "mv INSTALL.$$.protect_from_automake.backup INSTALL"
mv INSTALL.$$.protect_from_automake.backup INSTALL
fi # check contents
elif test -f INSTALL.$$.protect_from_automake.backup ; then
$VERBOSE_ECHO "mv INSTALL.$$.protect_from_automake.backup INSTALL"
mv INSTALL.$$.protect_from_automake.backup INSTALL
fi # -f INSTALL
# just in case
$VERBOSE_ECHO "rm -f INSTALL.$$.protect_from_automake.backup"
rm -f INSTALL.$$.protect_from_automake.backup
fi # -f INSTALL.$$.protect_from_automake.backup
CONFIGURE="`locate_configure_template`"
if [ "x$CONFIGURE" = "x" ] ; then
return
fi
_aux_dir="`grep AC_CONFIG_AUX_DIR $CONFIGURE | grep -v '.*#.*AC_CONFIG_AUX_DIR' | tail -${TAIL_N}1 | sed 's/^[ ]*AC_CONFIG_AUX_DIR(\(.*\)).*/\1/' | sed 's/.*\[\(.*\)\].*/\1/'`"
if test ! -d "$_aux_dir" ; then
_aux_dir=.
fi
for file in config.guess config.sub ltmain.sh ; do
if test -f "${_aux_dir}/${file}" ; then
$VERBOSE_ECHO "rm -f \"${_aux_dir}/${file}.backup\""
rm -f "${_aux_dir}/${file}.backup"
fi
done
} # end of restore_clobbered
##############################
# RECURSIVE_RESTORE FUNCTION #
##############################
recursive_restore ( ) {
# restore COPYING and INSTALL from backup if they were clobbered
# for each directory recursively.
# git 'r undone
restore_clobbered
# find configure template
_configure="`locate_configure_template`"
if [ "x$_configure" = "x" ] ; then
return
fi
# look for subdirs
_det_config_subdirs="`grep AC_CONFIG_SUBDIRS $_configure | grep -v '.*#.*AC_CONFIG_SUBDIRS' | sed 's/^[ ]*AC_CONFIG_SUBDIRS(\(.*\)).*/\1/' | sed 's/.*\[\(.*\)\].*/\1/'`"
CHECK_DIRS=""
for dir in $_det_config_subdirs ; do
if test -d "`pwd`/$dir" ; then
CHECK_DIRS="$CHECK_DIRS \"`pwd`/$dir\""
fi
done
# process subdirs
if [ ! "x$CHECK_DIRS" = "x" ] ; then
$VERBOSE_ECHO "Recursively scanning the following directories:"
$VERBOSE_ECHO " $CHECK_DIRS"
for dir in $CHECK_DIRS ; do
$VERBOSE_ECHO "Checking files for automake damage in $dir"
cd "$START_PATH"
eval "cd $dir"
# recursively git 'r undone
recursive_restore
done
fi
} # end of recursive_restore
#######################
# INITIALIZE FUNCTION #
#######################
initialize ( ) {
# this routine performs a variety of directory-specific
# initializations. some are sanity checks, some are preventive,
# and some are necessary setup detection.
#
# this function sets:
# CONFIGURE
# SEARCH_DIRS
# CONFIG_SUBDIRS
##################################
# check for a configure template #
##################################
CONFIGURE="`locate_configure_template`"
if [ "x$CONFIGURE" = "x" ] ; then
$ECHO
$ECHO "A configure.ac or configure.in file could not be located implying"
$ECHO "that the GNU Build System is at least not used in this directory. In"
$ECHO "any case, there is nothing to do here without one of those files."
$ECHO
$ECHO "ERROR: No configure.in or configure.ac file found in `pwd`"
exit 1
fi
#####################
# detect an aux dir #
#####################
_aux_dir="`grep AC_CONFIG_AUX_DIR $CONFIGURE | grep -v '.*#.*AC_CONFIG_AUX_DIR' | tail -${TAIL_N}1 | sed 's/^[ ]*AC_CONFIG_AUX_DIR(\(.*\)).*/\1/' | sed 's/.*\[\(.*\)\].*/\1/'`"
if test ! -d "$_aux_dir" ; then
_aux_dir=.
else
$VERBOSE_ECHO "Detected auxillary directory: $_aux_dir"
fi
################################
# detect a recursive configure #
################################
CONFIG_SUBDIRS=""
_det_config_subdirs="`grep AC_CONFIG_SUBDIRS $CONFIGURE | grep -v '.*#.*AC_CONFIG_SUBDIRS' | sed 's/^[ ]*AC_CONFIG_SUBDIRS(\(.*\)).*/\1/' | sed 's/.*\[\(.*\)\].*/\1/'`"
for dir in $_det_config_subdirs ; do
if test -d "`pwd`/$dir" ; then
$VERBOSE_ECHO "Detected recursive configure directory: `pwd`/$dir"
CONFIG_SUBDIRS="$CONFIG_SUBDIRS `pwd`/$dir"
fi
done
##########################################
# make sure certain required files exist #
##########################################
for file in AUTHORS COPYING ChangeLog INSTALL NEWS README ; do
if test ! -f $file ; then
$VERBOSE_ECHO "Touching ${file} since it does not exist"
touch $file
fi
done
##################################################
# make sure certain generated files do not exist #
##################################################
for file in config.guess config.sub ltmain.sh ; do
if test -f "${_aux_dir}/${file}" ; then
$VERBOSE_ECHO "mv -f \"${_aux_dir}/${file}\" \"${_aux_dir}/${file}.backup\""
mv -f "${_aux_dir}/${file}" "${_aux_dir}/${file}.backup"
fi
done
############################
# search alternate m4 dirs #
############################
SEARCH_DIRS=""
for dir in m4 ; do
if [ -d $dir ] ; then
$VERBOSE_ECHO "Found extra aclocal search directory: $dir"
SEARCH_DIRS="$SEARCH_DIRS -I $dir"
fi
done
######################################
# remove any previous build products #
######################################
if test -d autom4te.cache ; then
$VERBOSE_ECHO "Found an autom4te.cache directory, deleting it"
$VERBOSE_ECHO "rm -rf autom4te.cache"
rm -rf autom4te.cache
fi
# tcl/tk (and probably others) have a customized aclocal.m4, so can't delete it
# if test -f aclocal.m4 ; then
# $VERBOSE_ECHO "Found an aclocal.m4 file, deleting it"
# $VERBOSE_ECHO "rm -f aclocal.m4"
# rm -f aclocal.m4
# fi
} # end of initialize()
##############
# initialize #
##############
# stash path
START_PATH="`pwd`"
# Before running autoreconf or manual steps, some prep detection work
# is necessary or useful. Only needs to occur once per directory, but
# does need to traverse the entire subconfigure hierarchy to protect
# files from being clobbered even by autoreconf.
recursive_protect
# start from where we started
cd "$START_PATH"
# get ready to process
initialize
############################################
# prepare build via autoreconf or manually #
############################################
reconfigure_manually=no
if [ "x$HAVE_AUTORECONF" = "xyes" ] ; then
$ECHO
$ECHO $ECHO_N "Automatically preparing build ... $ECHO_C"
$VERBOSE_ECHO "$AUTORECONF $SEARCH_DIRS $AUTORECONF_OPTIONS"
autoreconf_output="`$AUTORECONF $SEARCH_DIRS $AUTORECONF_OPTIONS 2>&1`"
ret=$?
$VERBOSE_ECHO "$autoreconf_output"
if [ ! $ret = 0 ] ; then
if [ "x$HAVE_ALT_LIBTOOLIZE" = "xyes" ] ; then
if [ ! "x`echo \"$autoreconf_output\" | grep libtoolize | grep \"No such file or directory\"`" = "x" ] ; then
$ECHO
$ECHO "Warning: autoreconf failed but due to what is usually a common libtool"
$ECHO "misconfiguration issue. This problem is encountered on systems that"
$ECHO "have installed libtoolize under a different name without providing a"
$ECHO "symbolic link or without setting the LIBTOOLIZE environment variable."
$ECHO
$ECHO "Restarting the preparation steps with LIBTOOLIZE set to $LIBTOOLIZE"
export LIBTOOLIZE
RUN_RECURSIVE=no
export RUN_RECURSIVE
untrap_abnormal
$VERBOSE_ECHO sh $AUTOGEN_SH "$1" "$2" "$3" "$4" "$5" "$6" "$7" "$8" "$9"
sh "$AUTOGEN_SH" "$1" "$2" "$3" "$4" "$5" "$6" "$7" "$8" "$9"
exit $?
fi
fi
$ECHO "Warning: $AUTORECONF failed"
if test -f ltmain.sh ; then
$ECHO "libtoolize being run by autoreconf is not creating ltmain.sh in the auxillary directory like it should"
fi
$ECHO "Attempting to run the preparation steps individually"
reconfigure_manually=yes
fi
else
reconfigure_manually=yes
fi
############################
# LIBTOOL_FAILURE FUNCTION #
############################
libtool_failure ( ) {
# libtool is rather error-prone in comparison to the other
# autotools and this routine attempts to compensate for some
# common failures. the output after a libtoolize failure is
# parsed for an error related to AC_PROG_LIBTOOL and if found, we
# attempt to inject a project-provided libtool.m4 file.
_autoconf_output="$1"
if [ "x$RUN_RECURSIVE" = "xno" ] ; then
# we already tried the libtool.m4, don't try again
return 1
fi
if test -f "$LIBTOOL_M4" ; then
found_libtool="`$ECHO $_autoconf_output | grep AC_PROG_LIBTOOL`"
if test ! "x$found_libtool" = "x" ; then
if test -f acinclude.m4 ; then
rm -f acinclude.m4.$$.backup
$VERBOSE_ECHO "cat acinclude.m4 > acinclude.m4.$$.backup"
cat acinclude.m4 > acinclude.m4.$$.backup
fi
$VERBOSE_ECHO "cat \"$LIBTOOL_M4\" >> acinclude.m4"
chmod u+w acinclude.m4
cat "$LIBTOOL_M4" >> acinclude.m4
# don't keep doing this
RUN_RECURSIVE=no
export RUN_RECURSIVE
untrap_abnormal
$ECHO
$ECHO "Restarting the preparation steps with libtool macros in acinclude.m4"
$VERBOSE_ECHO sh $AUTOGEN_SH "$1" "$2" "$3" "$4" "$5" "$6" "$7" "$8" "$9"
sh "$AUTOGEN_SH" "$1" "$2" "$3" "$4" "$5" "$6" "$7" "$8" "$9"
exit $?
fi
fi
}
###########################
# MANUAL_AUTOGEN FUNCTION #
###########################
manual_autogen ( ) {
##################################################
# Manual preparation steps taken are as follows: #
# aclocal [-I m4] #
# libtoolize --automake -c -f #
# aclocal [-I m4] #
# autoconf -f #
# autoheader #
# automake -a -c -f #
##################################################
###########
# aclocal #
###########
$VERBOSE_ECHO "$ACLOCAL $SEARCH_DIRS $ACLOCAL_OPTIONS"
aclocal_output="`$ACLOCAL $SEARCH_DIRS $ACLOCAL_OPTIONS 2>&1`"
ret=$?
$VERBOSE_ECHO "$aclocal_output"
if [ ! $ret = 0 ] ; then $ECHO "ERROR: $ACLOCAL failed" && exit 2 ; fi
##############
# libtoolize #
##############
need_libtoolize=no
for feature in AC_PROG_LIBTOOL LT_INIT ; do
$VERBOSE_ECHO "Searching for $feature in $CONFIGURE"
found="`grep \"^$feature.*\" $CONFIGURE`"
if [ ! "x$found" = "x" ] ; then
need_libtoolize=yes
break
fi
done
if [ "x$need_libtoolize" = "xyes" ] ; then
if [ "x$HAVE_LIBTOOLIZE" = "xyes" ] ; then
$VERBOSE_ECHO "$LIBTOOLIZE $LIBTOOLIZE_OPTIONS"
libtoolize_output="`$LIBTOOLIZE $LIBTOOLIZE_OPTIONS 2>&1`"
ret=$?
$VERBOSE_ECHO "$libtoolize_output"
if [ ! $ret = 0 ] ; then $ECHO "ERROR: $LIBTOOLIZE failed" && exit 2 ; fi
else
if [ "x$HAVE_ALT_LIBTOOLIZE" = "xyes" ] ; then
$VERBOSE_ECHO "$LIBTOOLIZE $ALT_LIBTOOLIZE_OPTIONS"
libtoolize_output="`$LIBTOOLIZE $ALT_LIBTOOLIZE_OPTIONS 2>&1`"
ret=$?
$VERBOSE_ECHO "$libtoolize_output"
if [ ! $ret = 0 ] ; then $ECHO "ERROR: $LIBTOOLIZE failed" && exit 2 ; fi
fi
fi
###########
# aclocal #
###########
# re-run again as instructed by libtoolize
$VERBOSE_ECHO "$ACLOCAL $SEARCH_DIRS $ACLOCAL_OPTIONS"
aclocal_output="`$ACLOCAL $SEARCH_DIRS $ACLOCAL_OPTIONS 2>&1`"
ret=$?
$VERBOSE_ECHO "$aclocal_output"
# libtoolize might put ltmain.sh in the wrong place
if test -f ltmain.sh ; then
if test ! -f "${_aux_dir}/ltmain.sh" ; then
$ECHO
$ECHO "Warning: $LIBTOOLIZE is creating ltmain.sh in the wrong directory"
$ECHO
$ECHO "Fortunately, the problem can be worked around by simply copying the"
$ECHO "file to the appropriate location (${_aux_dir}/). This has been done for you."
$ECHO
$VERBOSE_ECHO "cp -p ltmain.sh \"${_aux_dir}/ltmain.sh\""
cp -p ltmain.sh "${_aux_dir}/ltmain.sh"
$ECHO $ECHO_N "Continuing build preparation ... $ECHO_C"
fi
fi # ltmain.sh
fi # need_libtoolize
############
# autoconf #
############
$VERBOSE_ECHO
$VERBOSE_ECHO "$AUTOCONF $AUTOCONF_OPTIONS"
autoconf_output="`$AUTOCONF $AUTOCONF_OPTIONS 2>&1`"
ret=$?
$VERBOSE_ECHO "$autoconf_output"
if [ ! $ret = 0 ] ; then
# retry without the -f and check for usage of macros that are too new
ac2_59_macros="AC_C_RESTRICT AC_INCLUDES_DEFAULT AC_LANG_ASSERT AC_LANG_WERROR AS_SET_CATFILE"
ac2_55_macros="AC_COMPILER_IFELSE AC_FUNC_MBRTOWC AC_HEADER_STDBOOL AC_LANG_CONFTEST AC_LANG_SOURCE AC_LANG_PROGRAM AC_LANG_CALL AC_LANG_FUNC_TRY_LINK AC_MSG_FAILURE AC_PREPROC_IFELSE"
ac2_54_macros="AC_C_BACKSLASH_A AC_CONFIG_LIBOBJ_DIR AC_GNU_SOURCE AC_PROG_EGREP AC_PROG_FGREP AC_REPLACE_FNMATCH AC_FUNC_FNMATCH_GNU AC_FUNC_REALLOC AC_TYPE_MBSTATE_T"
macros_to_search=""
ac_major="`echo ${AUTOCONF_VERSION}. | cut -d. -f1 | sed 's/[^0-9]//g'`"
ac_minor="`echo ${AUTOCONF_VERSION}. | cut -d. -f2 | sed 's/[^0-9]//g'`"
if [ $ac_major -lt 2 ] ; then
macros_to_search="$ac2_59_macros $ac2_55_macros $ac2_54_macros"
else
if [ $ac_minor -lt 54 ] ; then
macros_to_search="$ac2_59_macros $ac2_55_macros $ac2_54_macros"
elif [ $ac_minor -lt 55 ] ; then
macros_to_search="$ac2_59_macros $ac2_55_macros"
elif [ $ac_minor -lt 59 ] ; then
macros_to_search="$ac2_59_macros"
fi
fi
configure_ac_macros=__none__
for feature in $macros_to_search ; do
$VERBOSE_ECHO "Searching for $feature in $CONFIGURE"
found="`grep \"^$feature.*\" $CONFIGURE`"
if [ ! "x$found" = "x" ] ; then
if [ "x$configure_ac_macros" = "x__none__" ] ; then
configure_ac_macros="$feature"
else
configure_ac_macros="$feature $configure_ac_macros"
fi
fi
done
if [ ! "x$configure_ac_macros" = "x__none__" ] ; then
$ECHO
$ECHO "Warning: Unsupported macros were found in $CONFIGURE"
$ECHO
$ECHO "The `echo $CONFIGURE | basename` file was scanned in order to determine if any"
$ECHO "unsupported macros are used that exceed the minimum version"
$ECHO "settings specified within this file. As such, the following macros"
$ECHO "should be removed from configure.ac or the version numbers in this"
$ECHO "file should be increased:"
$ECHO
$ECHO "$configure_ac_macros"
$ECHO
$ECHO $ECHO_N "Ignorantly continuing build preparation ... $ECHO_C"
fi
###################
# autoconf, retry #
###################
$VERBOSE_ECHO
$VERBOSE_ECHO "$AUTOCONF"
autoconf_output="`$AUTOCONF 2>&1`"
ret=$?
$VERBOSE_ECHO "$autoconf_output"
if [ ! $ret = 0 ] ; then
# test if libtool is busted
libtool_failure "$autoconf_output"
# let the user know what went wrong
cat <