Imported upstream version 5.38~cvs20071118

This commit is contained in:
Guido Guenther 2007-11-19 13:17:31 +01:00
parent 9ebc753d41
commit a37e71455d
69 changed files with 11792 additions and 17597 deletions

46
.cvsignore Normal file
View File

@ -0,0 +1,46 @@
*.gz
*.o
*.rpm
*.tar.gz
*.tar.gz.asc
*~
.deps
.gdb_history
Makefile
Makefile.in
VERSION
aclocal.m4
add
autom4te.cache
autotools.diff
build
config.guess
config.h
config.h.in
config.log
config.status
config.sub
configure
core
cvs-script
depcomp
install-sh
missing
mkinstalldirs
smartctl
smartctl.8
smartctl.1m
smartctl.exe
smartd
smartd.8
smartd.1m
smartd.conf.5
smartd.conf.4
smartd.conf.sample
smartd.initd
smartd.exe
stamp-h
stamp-h.in
stamp-h1
writelog.c
SMART

11
AUTHORS
View File

@ -1,4 +1,4 @@
$Id: AUTHORS,v 1.17 2006/12/20 12:24:34 guidog Exp $
$Id: AUTHORS,v 1.18 2007/11/13 14:53:27 jhering Exp $
This code was originally developed as a Senior Thesis by Michael
Cornwell at the Concurrent Systems Laboratory (now part of the Storage
@ -11,19 +11,19 @@ ucsc-smartsuite and smartsuite packages, and is derived from that code.
Maintainers / Developers:
Bruce Allen <smartmontools-support@lists.sourceforge.net>
Erik Inge Bolsø <knan@mo.himolde.no>
Erik Inge Bols<EFBFBD> <knan@mo.himolde.no>
Stanislav Brabec <sbrabec@suse.cz>
Peter Cassidy <pcassidy@mac.com>
Casper Dik <casper@holland.sun.com>
Christian Franke <franke@computer.org>
Guilhem Frézou <guilhem.frezou@catii.fr>
Guilhem Fr<EFBFBD>zou <guilhem.frezou@catii.fr>
Douglas Gilbert <dougg@torque.net>
Guido Guenther <agx@sigxcpu.org>
Geoff Keating <geoffk@geoffk.org>
Dr. David Kirkby <drkirkby@ntlworld.com>
Kai Mäkisara <kai.makisara@kolumbus.fi>
Kai M<EFBFBD>kisara <kai.makisara@kolumbus.fi>
Eduard Martinescu <martines@rochester.rr.com>
Frédéric L. W. Meunier <http://www.pervalidus.net/contact.html>
Fr<EFBFBD>d<EFBFBD>ric L. W. Meunier <http://www.pervalidus.net/contact.html>
Keiji Sawada <card_captor@users.sourceforge.net>
David Snyder <dasnyderx@yahoo.com>
Sergey Svishchev <svs@ropnet.ru>
@ -32,3 +32,4 @@ Richard Zybert <richard.zybert@zybert.co.uk>
Yuri Dario <mc6530@mclink.it>
Shengfeng Zhou <linux@highpoint-tech.com>
Praveen Chidambaram <bunchofmails@gmail.com>
Joerg Hering <hering.ruegen@gmx.de>

163
CHANGELOG
View File

@ -1,26 +1,27 @@
CHANGELOG for smartmontools
$Id: CHANGELOG,v 1.592 2006/12/20 20:39:25 chrfranke Exp $
$Id: CHANGELOG,v 1.637 2007/11/13 14:53:27 jhering Exp $
The most recent version of this file is:
http://smartmontools.cvs.sourceforge.net/smartmontools/sm5/CHANGELOG?view=markup
Maintainers / Developers Key:
[BA] Bruce Allen
[EB] Erik Inge Bolsø
[EB] Erik Inge Bols<EFBFBD>
[SB] Stanislav Brabec
[PC] Peter Cassidy
[YD] Yuri Dario
[CD] Casper Dik
[CF] Christian Franke
[GF] Guilhem Frézou
[GF] Guilhem Fr<EFBFBD>zou
[DG] Douglas Gilbert
[GG] Guido Guenther
[GK] Geoff Keating
[DK] Dr. David Kirkby
[KM] Kai Mäkisara
[JH] Joerg Hering
[KM] Kai M<>kisara
[EM] Eduard Martinescu
[FM] Frédéric L. W. Meunier
[FM] Fr<EFBFBD>d<EFBFBD>ric L. W. Meunier
[KS] Keiji Sawada
[DS] David Snyder
[SS] Sergey Svishchev
@ -32,6 +33,156 @@ Maintainers / Developers Key:
NOTES FOR FUTURE RELEASES: see TODO file.
<DEVELOPERS: ADDITIONS TO THE CHANGE LOG GO JUST BELOW HERE, PLEASE>
[JH] initial porting to QNX Neutrino 6.3.2
need at this time a prerelease devb-eide driver and libcam.so.2
only tested for X86 Target, but devb-eide and lobcam.so.2 available for X86/ARM
the officional driver coming soon with the next QNX release
create two new source files os_qnxnto.[c..h]
[CF] smartd: Added option '-n, --no-fork' so that smartd works
better with modern init methods. Thanks to Enrico Scholz
for the patch from 2005-12-24.
[CF] Windows: Improved ATA/SCSI device type detection and
DEVICESCAN. This also fixes a regression in 3ware DEVICESCAN.
[CF] smartd: Don't start self tests in first pass to avoid
performance problems during boot.
https://bugzilla.novell.com/show_bug.cgi?id=192591
[CF] Fixed regression in SMART STATUS command on Win9x/ME.
[BA] Fixed 3ware issue with new controllers. Documentation said
that one could address up to 24 disks on a single controller,
but in fact one was limited to 16 disks. This is now fixed:
up to 32 disks can be addressed. Thanks to Adam Radford.
NOTE1: I have patched the Linux and FreeBSD code but not
modified the Win32 code (it already supports up to 32 disks).
NOTE2: NOT TESTED ON LINUX. Do not use this on a production box!
I will remove this NOTE2 as soon as some positive test
reports are recieved.
NOTE3: NOT TESTED ON FREEBSD. Do not use this on a production box!
I will remove this NOTE3 as soon as some positive test
reports are recieved.
[CF] Windows installer: Added explorer drive menu, CMD window,
UBCD4Win plugin, smartd service update and other minor
improvements.
[CF] Windows: Modified drive letter handling for explorer drive
context menu: try SCSI if type is unknown, allow 'X:\.' syntax.
[CF] Windows: Added automatic ATA/SCSI device type detection and
SCSI device scanning. The device names '/dev/sdX' and
'/dev/pd<n>' now work for both ATA and SCSI disks.
[CF] smartctl: Added ability to parse '-r ataioctl,2' output from
stdin ('-') and simulate the ATA commands for testing purposes.
[BA] SMART Attributes: added 187, 189, more accurate name for 190.
[CF] Windows: Added drive letters 'X:' as alternate disk device names.
[CF] smartctl: Added '-F swapid' to fix ATA identify string byte
ordering. Added '-q noserial' to suppress serial number output.
[CF] Windows: Added '/dev/n?st<n>' as alternate device names for SCSI
tapes. These names are also used by Cygwin's /dev emulation layer.
Thanks to Corinna Vinschen (Cygwin project lead) for pointing this
out.
[CF] Windows: Added IOCTL_SCSI_MINIPORT_*SMART* for commands not handled
properly by SMART_IOCTL in disk class driver. This allows to use
READ_LOG, WRITE_LOG and ABORT_SELFTEST even if the driver does not
support ATA_PASS_THROUGH.
[CF] Added ATA-8 revision 4, fixed WRITE LOG '-r ioctl' output.
[BA] Updated smartctl and smartd so that they can be used with the latest
3ware controllers which have 24 ports. Also updated docs.
Thanks to Tim Bell at CERN.
[GG] bit 4 in smartctl's return code might be set even when the dist check
didn't return "DISK OK"
[CF] Drive database: added '-F samsung3' for Samsung P80 firmware
BH100-35.
[SS] Applied patch from Dean Bennett to fix scheduled tests on
Highpoint RAID controllers.
[BA] Added patch from Tejun Heo http://thread.gmane.org/gmane.linux.ide/13222/focus=13235
to fix broken auto-offline and auto-save via libata. Very clean fix: does it
"the right way". Thanks Tejun!
[CF] Added message text for ATA-7 self-test execution status 8
("... handling damage").
[GG] cciss: support more than 16 disks (patch taken from
http://cciss.sourceforge.net/smartmontools_cciss_more_than_16_drives.patch
and adjusted for smartd)
[DG] Solaris: [SCSI] add USCSI_RQENABLE flag to uscsi pass-through so
sense buffer is made available. Expand reporting at this level.
[GK] Darwin: Improve handling of powered-down drives.
[SS] CCISS physical drive enumeration method changed (incompatibly).
[CF] Fixed smartd crash on missing '-s' directive argument.
[SS] Support CCISS on FreeBSD (kernel source is required).
[DG] SCSI/TAPE: some IBM tape drives don't react properly to a LOG
SENSE with an allocation length of 4; work around for that case.
[CF] Applied Guido's patch to fix CCISS LUN array bounds check
(openSUSE bug #239956) and remove trailing spaces in
os_linux.cpp.
[CF] Fixed 64-bit compilation issue in SCT status struct.
[DG] SAT/SCSI: make real SCSI disks visible to DEVICESCAN in
smartd again.
[CF] Fixed check of SCT temperature table size.
[CF] Added ATA-8 draft revisions, added SCT status format 3.
[CF] Drive database: added Samsung T166 series.
[CF] ATA: Added ',p' option for '-t scttempint,N' to make
setting persistent.
[CF] ATA: Added '-t scttempint,N' option to set SCT temperature
logging interval.
[CF] ATA: Added '-l scttemp[sts,hist]' options to print disk
temperature information and history table provided by
SMART Command Transport (SCT) Feature Set.
[CF] ATA: Added '-t selective,{redo,next,cont}' commands to
perform tests based on the last ranges still stored on
disk. Added 'N+SIZE' and 'N-max' format for LBA range
specification.
[CF] Added Min/Max Temperature format used in attribute 190 of
recent Maxtor disks (DiamondMax 20).
[CF] Linux: Added check for <linux/cciss_ioctl.h> to allow build
(without CCISS support) also when this file is missing.
[CF] Added -F samsung3 option to correct firmware bug reporting
completed self-tests as still in progress. Thanks to Manfred
Schwarb for the patch.
[CF] Added missing const specifiers (undetected by gcc 3.4 and 4.X)
to fix compilation with gcc 2.X.
[CF] Linux: compile fix for SuSE, config.h must be included first.
smartmontools 5.37 Experimental Release
@ -121,7 +272,7 @@ smartmontools 5.37 Experimental Release
and T series.
[GG] Add CCISS (Compaq Smart Array Controller) support with contributions
from Praveen Chidambaram, Douglas Gilbert, Guido Guenther and Frédéric
from Praveen Chidambaram, Douglas Gilbert, Guido Guenther and Fr<EFBFBD>d<EFBFBD>ric
BOITEUX
[PW] Drive database: added Hitachi Deskstar T7K250 and Hitachi

View File

@ -1,7 +1,7 @@
Smartmontools installation instructions
=======================================
$Id: INSTALL,v 1.72 2006/11/15 22:48:04 chrfranke Exp $
$Id: INSTALL,v 1.73 2007/04/27 08:50:00 geoffk1 Exp $
Please also see the smartmontools home page:
http://smartmontools.sourceforge.net/
@ -350,7 +350,7 @@ SuSE:
If you'd like to build the i386 version on a powerpc machine, you can
use
CC='gcc -isysroot /Developer/SDKs/MacOSX10.4u.sdk -arch i386' \
CXX='g++ -isysroot /Developer/SDKs/MacOSX10.4u.sdk -arch i386' \
./configure --host=i386-apple-darwin \
--with-initscriptdir=/Library/StartupItems

View File

@ -1,6 +1,6 @@
## Process this file with automake to produce Makefile.in
#
# $Id: Makefile.am,v 1.80 2006/10/21 18:34:31 chrfranke Exp $
# $Id: Makefile.am,v 1.81 2007/04/01 16:49:44 shattered Exp $
#
@SET_MAKE@
@ -53,7 +53,9 @@ EXTRA_smartd_SOURCES = os_darwin.cpp \
os_solaris_ata.s \
os_win32.cpp \
os_generic.cpp \
os_generic.h
os_generic.h \
cciss.cpp \
cciss.h
if OS_WIN32_MINGW
@ -113,7 +115,9 @@ EXTRA_smartctl_SOURCES = os_linux.cpp \
os_solaris.h \
os_win32.cpp \
os_generic.cpp \
os_generic.h
os_generic.h \
cciss.cpp \
cciss.h
if OS_WIN32_MINGW

File diff suppressed because it is too large Load Diff

31
TODO
View File

@ -1,6 +1,6 @@
TODO list for smartmontools:
$Id: TODO,v 1.62 2006/10/27 21:49:42 chrfranke Exp $
$Id: TODO,v 1.64 2007/09/03 19:36:58 chrfranke Exp $
SATA devices under Linux
------------------------
@ -30,21 +30,6 @@ Since this looks like this patch will become standard, we need to add something
to smartmontools to automatically recognize the libata, and add the '-d ata'
automatically.
SATA devices
------------
The ATA PASS THROUGH SCSI command (12 and 16 byte cdb) as defined in
SAT: http://www.t10.org/ftp/t10/drafts/sat/sat-r07.pdf (section 12.2)
provides a general way to pass ATA SMART commands through to SATA
devices.
Doug Gilbert will in the future add a '-d sat' type (note, this is not
a typo, we do not mean '-d sata') which will instruct the generic
smartmontools code to assume an ATA device but use those ATA PASS
THROUGH commands.
This should provide additional support for SATA devices under most or
all operating systems.
USB devices under Linux
-----------------------
Some USB devices can hang smartctl or smartd. This is because these
@ -106,11 +91,6 @@ executable/script in the background rather than in the foreground.
But let's wait for someone to request this. At that point we should
probably use fork/exec rather than system().
Perhaps change smartd to look in /proc/ide and /proc/scsi to see what
exists? If something doesn't exit then don't try to open it? This
should probably be the default option if there is no configuration
file.
Add ability to monitor "worst" value from attributes (sometimes it
gets larger!) and to monitor the threshold value (sometimes it
changes!).
@ -119,15 +99,6 @@ Add command line option that scans devices then WRITES
/etc/smartd.conf, perhaps as /etc/smartd.conf.output, just for devices
that can be monitored.
FreeBSD
-------
Add support for 3ware 9000 series SATA controllers.
Cygwin and Windows
------------------
Support DEVICESCAN for SPT (IOCTL_SCSI_PASS_THROUGH).
Packaging
---------
Under freebsd and solaris, the following are wrong:

912
aclocal.m4 vendored
View File

@ -1,912 +0,0 @@
# generated automatically by aclocal 1.9.6 -*- Autoconf -*-
# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
# 2005 Free Software Foundation, Inc.
# This file 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.
# Copyright (C) 2002, 2003, 2005 Free Software Foundation, Inc.
#
# This file 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.
# AM_AUTOMAKE_VERSION(VERSION)
# ----------------------------
# Automake X.Y traces this macro to ensure aclocal.m4 has been
# generated from the m4 files accompanying Automake X.Y.
AC_DEFUN([AM_AUTOMAKE_VERSION], [am__api_version="1.9"])
# AM_SET_CURRENT_AUTOMAKE_VERSION
# -------------------------------
# Call AM_AUTOMAKE_VERSION so it can be traced.
# This function is AC_REQUIREd by AC_INIT_AUTOMAKE.
AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
[AM_AUTOMAKE_VERSION([1.9.6])])
# Figure out how to run the assembler. -*- Autoconf -*-
# Copyright (C) 2001, 2003, 2004, 2005 Free Software Foundation, Inc.
#
# This file 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.
# serial 4
# AM_PROG_AS
# ----------
AC_DEFUN([AM_PROG_AS],
[# By default we simply use the C compiler to build assembly code.
AC_REQUIRE([AC_PROG_CC])
test "${CCAS+set}" = set || CCAS=$CC
test "${CCASFLAGS+set}" = set || CCASFLAGS=$CFLAGS
AC_ARG_VAR([CCAS], [assembler compiler command (defaults to CC)])
AC_ARG_VAR([CCASFLAGS], [assembler compiler flags (defaults to CFLAGS)])
])
# AM_AUX_DIR_EXPAND -*- Autoconf -*-
# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc.
#
# This file 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.
# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets
# $ac_aux_dir to `$srcdir/foo'. In other projects, it is set to
# `$srcdir', `$srcdir/..', or `$srcdir/../..'.
#
# Of course, Automake must honor this variable whenever it calls a
# tool from the auxiliary directory. The problem is that $srcdir (and
# therefore $ac_aux_dir as well) can be either absolute or relative,
# depending on how configure is run. This is pretty annoying, since
# it makes $ac_aux_dir quite unusable in subdirectories: in the top
# source directory, any form will work fine, but in subdirectories a
# relative path needs to be adjusted first.
#
# $ac_aux_dir/missing
# fails when called from a subdirectory if $ac_aux_dir is relative
# $top_srcdir/$ac_aux_dir/missing
# fails if $ac_aux_dir is absolute,
# fails when called from a subdirectory in a VPATH build with
# a relative $ac_aux_dir
#
# The reason of the latter failure is that $top_srcdir and $ac_aux_dir
# are both prefixed by $srcdir. In an in-source build this is usually
# harmless because $srcdir is `.', but things will broke when you
# start a VPATH build or use an absolute $srcdir.
#
# So we could use something similar to $top_srcdir/$ac_aux_dir/missing,
# iff we strip the leading $srcdir from $ac_aux_dir. That would be:
# am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"`
# and then we would define $MISSING as
# MISSING="\${SHELL} $am_aux_dir/missing"
# This will work as long as MISSING is not called from configure, because
# unfortunately $(top_srcdir) has no meaning in configure.
# However there are other variables, like CC, which are often used in
# configure, and could therefore not use this "fixed" $ac_aux_dir.
#
# Another solution, used here, is to always expand $ac_aux_dir to an
# absolute PATH. The drawback is that using absolute paths prevent a
# configured tree to be moved without reconfiguration.
AC_DEFUN([AM_AUX_DIR_EXPAND],
[dnl Rely on autoconf to set up CDPATH properly.
AC_PREREQ([2.50])dnl
# expand $ac_aux_dir to an absolute path
am_aux_dir=`cd $ac_aux_dir && pwd`
])
# AM_CONDITIONAL -*- Autoconf -*-
# Copyright (C) 1997, 2000, 2001, 2003, 2004, 2005
# Free Software Foundation, Inc.
#
# This file 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.
# serial 7
# AM_CONDITIONAL(NAME, SHELL-CONDITION)
# -------------------------------------
# Define a conditional.
AC_DEFUN([AM_CONDITIONAL],
[AC_PREREQ(2.52)dnl
ifelse([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])],
[$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl
AC_SUBST([$1_TRUE])
AC_SUBST([$1_FALSE])
if $2; then
$1_TRUE=
$1_FALSE='#'
else
$1_TRUE='#'
$1_FALSE=
fi
AC_CONFIG_COMMANDS_PRE(
[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then
AC_MSG_ERROR([[conditional "$1" was never defined.
Usually this means the macro was only invoked conditionally.]])
fi])])
# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
# Free Software Foundation, Inc.
#
# This file 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.
# serial 8
# There are a few dirty hacks below to avoid letting `AC_PROG_CC' be
# written in clear, in which case automake, when reading aclocal.m4,
# will think it sees a *use*, and therefore will trigger all it's
# C support machinery. Also note that it means that autoscan, seeing
# CC etc. in the Makefile, will ask for an AC_PROG_CC use...
# _AM_DEPENDENCIES(NAME)
# ----------------------
# See how the compiler implements dependency checking.
# NAME is "CC", "CXX", "GCJ", or "OBJC".
# We try a few techniques and use that to set a single cache variable.
#
# We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was
# modified to invoke _AM_DEPENDENCIES(CC); we would have a circular
# dependency, and given that the user is not expected to run this macro,
# just rely on AC_PROG_CC.
AC_DEFUN([_AM_DEPENDENCIES],
[AC_REQUIRE([AM_SET_DEPDIR])dnl
AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl
AC_REQUIRE([AM_MAKE_INCLUDE])dnl
AC_REQUIRE([AM_DEP_TRACK])dnl
ifelse([$1], CC, [depcc="$CC" am_compiler_list=],
[$1], CXX, [depcc="$CXX" am_compiler_list=],
[$1], OBJC, [depcc="$OBJC" am_compiler_list='gcc3 gcc'],
[$1], GCJ, [depcc="$GCJ" am_compiler_list='gcc3 gcc'],
[depcc="$$1" am_compiler_list=])
AC_CACHE_CHECK([dependency style of $depcc],
[am_cv_$1_dependencies_compiler_type],
[if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then
# We make a subdir and do the tests there. Otherwise we can end up
# making bogus files that we don't know about and never remove. For
# instance it was reported that on HP-UX the gcc test will end up
# making a dummy file named `D' -- because `-MD' means `put the output
# in D'.
mkdir conftest.dir
# Copy depcomp to subdir because otherwise we won't find it if we're
# using a relative directory.
cp "$am_depcomp" conftest.dir
cd conftest.dir
# We will build objects and dependencies in a subdirectory because
# it helps to detect inapplicable dependency modes. For instance
# both Tru64's cc and ICC support -MD to output dependencies as a
# side effect of compilation, but ICC will put the dependencies in
# the current directory while Tru64 will put them in the object
# directory.
mkdir sub
am_cv_$1_dependencies_compiler_type=none
if test "$am_compiler_list" = ""; then
am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp`
fi
for depmode in $am_compiler_list; do
# Setup a source with many dependencies, because some compilers
# like to wrap large dependency lists on column 80 (with \), and
# we should not choose a depcomp mode which is confused by this.
#
# We need to recreate these files for each test, as the compiler may
# overwrite some of them when testing with obscure command lines.
# This happens at least with the AIX C compiler.
: > sub/conftest.c
for i in 1 2 3 4 5 6; do
echo '#include "conftst'$i'.h"' >> sub/conftest.c
# Using `: > sub/conftst$i.h' creates only sub/conftst1.h with
# Solaris 8's {/usr,}/bin/sh.
touch sub/conftst$i.h
done
echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf
case $depmode in
nosideeffect)
# after this tag, mechanisms are not by side-effect, so they'll
# only be used when explicitly requested
if test "x$enable_dependency_tracking" = xyes; then
continue
else
break
fi
;;
none) break ;;
esac
# We check with `-c' and `-o' for the sake of the "dashmstdout"
# mode. It turns out that the SunPro C++ compiler does not properly
# handle `-M -o', and we need to detect this.
if depmode=$depmode \
source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \
depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \
$SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} sub/conftest.c \
>/dev/null 2>conftest.err &&
grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 &&
grep sub/conftest.${OBJEXT-o} sub/conftest.Po > /dev/null 2>&1 &&
${MAKE-make} -s -f confmf > /dev/null 2>&1; then
# icc doesn't choke on unknown options, it will just issue warnings
# or remarks (even with -Werror). So we grep stderr for any message
# that says an option was ignored or not supported.
# When given -MP, icc 7.0 and 7.1 complain thusly:
# icc: Command line warning: ignoring option '-M'; no argument required
# The diagnosis changed in icc 8.0:
# icc: Command line remark: option '-MP' not supported
if (grep 'ignoring option' conftest.err ||
grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else
am_cv_$1_dependencies_compiler_type=$depmode
break
fi
fi
done
cd ..
rm -rf conftest.dir
else
am_cv_$1_dependencies_compiler_type=none
fi
])
AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type])
AM_CONDITIONAL([am__fastdep$1], [
test "x$enable_dependency_tracking" != xno \
&& test "$am_cv_$1_dependencies_compiler_type" = gcc3])
])
# AM_SET_DEPDIR
# -------------
# Choose a directory name for dependency files.
# This macro is AC_REQUIREd in _AM_DEPENDENCIES
AC_DEFUN([AM_SET_DEPDIR],
[AC_REQUIRE([AM_SET_LEADING_DOT])dnl
AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl
])
# AM_DEP_TRACK
# ------------
AC_DEFUN([AM_DEP_TRACK],
[AC_ARG_ENABLE(dependency-tracking,
[ --disable-dependency-tracking speeds up one-time build
--enable-dependency-tracking do not reject slow dependency extractors])
if test "x$enable_dependency_tracking" != xno; then
am_depcomp="$ac_aux_dir/depcomp"
AMDEPBACKSLASH='\'
fi
AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno])
AC_SUBST([AMDEPBACKSLASH])
])
# Generate code to set up dependency tracking. -*- Autoconf -*-
# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
# Free Software Foundation, Inc.
#
# This file 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.
#serial 3
# _AM_OUTPUT_DEPENDENCY_COMMANDS
# ------------------------------
AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS],
[for mf in $CONFIG_FILES; do
# Strip MF so we end up with the name of the file.
mf=`echo "$mf" | sed -e 's/:.*$//'`
# Check whether this is an Automake generated Makefile or not.
# We used to match only the files named `Makefile.in', but
# some people rename them; so instead we look at the file content.
# Grep'ing the first line is not enough: some people post-process
# each Makefile.in and add a new line on top of each file to say so.
# So let's grep whole file.
if grep '^#.*generated by automake' $mf > /dev/null 2>&1; then
dirpart=`AS_DIRNAME("$mf")`
else
continue
fi
# Extract the definition of DEPDIR, am__include, and am__quote
# from the Makefile without running `make'.
DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"`
test -z "$DEPDIR" && continue
am__include=`sed -n 's/^am__include = //p' < "$mf"`
test -z "am__include" && continue
am__quote=`sed -n 's/^am__quote = //p' < "$mf"`
# When using ansi2knr, U may be empty or an underscore; expand it
U=`sed -n 's/^U = //p' < "$mf"`
# Find all dependency output files, they are included files with
# $(DEPDIR) in their names. We invoke sed twice because it is the
# simplest approach to changing $(DEPDIR) to its actual value in the
# expansion.
for file in `sed -n "
s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \
sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do
# Make sure the directory exists.
test -f "$dirpart/$file" && continue
fdir=`AS_DIRNAME(["$file"])`
AS_MKDIR_P([$dirpart/$fdir])
# echo "creating $dirpart/$file"
echo '# dummy' > "$dirpart/$file"
done
done
])# _AM_OUTPUT_DEPENDENCY_COMMANDS
# AM_OUTPUT_DEPENDENCY_COMMANDS
# -----------------------------
# This macro should only be invoked once -- use via AC_REQUIRE.
#
# This code is only required when automatic dependency tracking
# is enabled. FIXME. This creates each `.P' file that we will
# need in order to bootstrap the dependency handling code.
AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS],
[AC_CONFIG_COMMANDS([depfiles],
[test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS],
[AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"])
])
# Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005
# Free Software Foundation, Inc.
#
# This file 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.
# serial 8
# AM_CONFIG_HEADER is obsolete. It has been replaced by AC_CONFIG_HEADERS.
AU_DEFUN([AM_CONFIG_HEADER], [AC_CONFIG_HEADERS($@)])
# Do all the work for Automake. -*- Autoconf -*-
# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
# Free Software Foundation, Inc.
#
# This file 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.
# serial 12
# This macro actually does too much. Some checks are only needed if
# your package does certain things. But this isn't really a big deal.
# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE])
# AM_INIT_AUTOMAKE([OPTIONS])
# -----------------------------------------------
# The call with PACKAGE and VERSION arguments is the old style
# call (pre autoconf-2.50), which is being phased out. PACKAGE
# and VERSION should now be passed to AC_INIT and removed from
# the call to AM_INIT_AUTOMAKE.
# We support both call styles for the transition. After
# the next Automake release, Autoconf can make the AC_INIT
# arguments mandatory, and then we can depend on a new Autoconf
# release and drop the old call support.
AC_DEFUN([AM_INIT_AUTOMAKE],
[AC_PREREQ([2.58])dnl
dnl Autoconf wants to disallow AM_ names. We explicitly allow
dnl the ones we care about.
m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl
AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl
AC_REQUIRE([AC_PROG_INSTALL])dnl
# test to see if srcdir already configured
if test "`cd $srcdir && pwd`" != "`pwd`" &&
test -f $srcdir/config.status; then
AC_MSG_ERROR([source directory already configured; run "make distclean" there first])
fi
# test whether we have cygpath
if test -z "$CYGPATH_W"; then
if (cygpath --version) >/dev/null 2>/dev/null; then
CYGPATH_W='cygpath -w'
else
CYGPATH_W=echo
fi
fi
AC_SUBST([CYGPATH_W])
# Define the identity of the package.
dnl Distinguish between old-style and new-style calls.
m4_ifval([$2],
[m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl
AC_SUBST([PACKAGE], [$1])dnl
AC_SUBST([VERSION], [$2])],
[_AM_SET_OPTIONS([$1])dnl
AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl
AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl
_AM_IF_OPTION([no-define],,
[AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package])
AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])])dnl
# Some tools Automake needs.
AC_REQUIRE([AM_SANITY_CHECK])dnl
AC_REQUIRE([AC_ARG_PROGRAM])dnl
AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version})
AM_MISSING_PROG(AUTOCONF, autoconf)
AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version})
AM_MISSING_PROG(AUTOHEADER, autoheader)
AM_MISSING_PROG(MAKEINFO, makeinfo)
AM_PROG_INSTALL_SH
AM_PROG_INSTALL_STRIP
AC_REQUIRE([AM_PROG_MKDIR_P])dnl
# We need awk for the "check" target. The system "awk" is bad on
# some platforms.
AC_REQUIRE([AC_PROG_AWK])dnl
AC_REQUIRE([AC_PROG_MAKE_SET])dnl
AC_REQUIRE([AM_SET_LEADING_DOT])dnl
_AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])],
[_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])],
[_AM_PROG_TAR([v7])])])
_AM_IF_OPTION([no-dependencies],,
[AC_PROVIDE_IFELSE([AC_PROG_CC],
[_AM_DEPENDENCIES(CC)],
[define([AC_PROG_CC],
defn([AC_PROG_CC])[_AM_DEPENDENCIES(CC)])])dnl
AC_PROVIDE_IFELSE([AC_PROG_CXX],
[_AM_DEPENDENCIES(CXX)],
[define([AC_PROG_CXX],
defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl
])
])
# When config.status generates a header, we must update the stamp-h file.
# This file resides in the same directory as the config header
# that is generated. The stamp files are numbered to have different names.
# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the
# loop where config.status creates the headers, so we can generate
# our stamp files there.
AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK],
[# Compute $1's index in $config_headers.
_am_stamp_count=1
for _am_header in $config_headers :; do
case $_am_header in
$1 | $1:* )
break ;;
* )
_am_stamp_count=`expr $_am_stamp_count + 1` ;;
esac
done
echo "timestamp for $1" >`AS_DIRNAME([$1])`/stamp-h[]$_am_stamp_count])
# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc.
#
# This file 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.
# AM_PROG_INSTALL_SH
# ------------------
# Define $install_sh.
AC_DEFUN([AM_PROG_INSTALL_SH],
[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
install_sh=${install_sh-"$am_aux_dir/install-sh"}
AC_SUBST(install_sh)])
# Copyright (C) 2003, 2005 Free Software Foundation, Inc.
#
# This file 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.
# serial 2
# Check whether the underlying file-system supports filenames
# with a leading dot. For instance MS-DOS doesn't.
AC_DEFUN([AM_SET_LEADING_DOT],
[rm -rf .tst 2>/dev/null
mkdir .tst 2>/dev/null
if test -d .tst; then
am__leading_dot=.
else
am__leading_dot=_
fi
rmdir .tst 2>/dev/null
AC_SUBST([am__leading_dot])])
# Add --enable-maintainer-mode option to configure. -*- Autoconf -*-
# From Jim Meyering
# Copyright (C) 1996, 1998, 2000, 2001, 2002, 2003, 2004, 2005
# Free Software Foundation, Inc.
#
# This file 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.
# serial 4
AC_DEFUN([AM_MAINTAINER_MODE],
[AC_MSG_CHECKING([whether to enable maintainer-specific portions of Makefiles])
dnl maintainer-mode is disabled by default
AC_ARG_ENABLE(maintainer-mode,
[ --enable-maintainer-mode enable make rules and dependencies not useful
(and sometimes confusing) to the casual installer],
USE_MAINTAINER_MODE=$enableval,
USE_MAINTAINER_MODE=no)
AC_MSG_RESULT([$USE_MAINTAINER_MODE])
AM_CONDITIONAL(MAINTAINER_MODE, [test $USE_MAINTAINER_MODE = yes])
MAINT=$MAINTAINER_MODE_TRUE
AC_SUBST(MAINT)dnl
]
)
AU_DEFUN([jm_MAINTAINER_MODE], [AM_MAINTAINER_MODE])
# Check to see how 'make' treats includes. -*- Autoconf -*-
# Copyright (C) 2001, 2002, 2003, 2005 Free Software Foundation, Inc.
#
# This file 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.
# serial 3
# AM_MAKE_INCLUDE()
# -----------------
# Check to see how make treats includes.
AC_DEFUN([AM_MAKE_INCLUDE],
[am_make=${MAKE-make}
cat > confinc << 'END'
am__doit:
@echo done
.PHONY: am__doit
END
# If we don't find an include directive, just comment out the code.
AC_MSG_CHECKING([for style of include used by $am_make])
am__include="#"
am__quote=
_am_result=none
# First try GNU make style include.
echo "include confinc" > confmf
# We grep out `Entering directory' and `Leaving directory'
# messages which can occur if `w' ends up in MAKEFLAGS.
# In particular we don't look at `^make:' because GNU make might
# be invoked under some other name (usually "gmake"), in which
# case it prints its new name instead of `make'.
if test "`$am_make -s -f confmf 2> /dev/null | grep -v 'ing directory'`" = "done"; then
am__include=include
am__quote=
_am_result=GNU
fi
# Now try BSD make style include.
if test "$am__include" = "#"; then
echo '.include "confinc"' > confmf
if test "`$am_make -s -f confmf 2> /dev/null`" = "done"; then
am__include=.include
am__quote="\""
_am_result=BSD
fi
fi
AC_SUBST([am__include])
AC_SUBST([am__quote])
AC_MSG_RESULT([$_am_result])
rm -f confinc confmf
])
# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*-
# Copyright (C) 1997, 1999, 2000, 2001, 2003, 2005
# Free Software Foundation, Inc.
#
# This file 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.
# serial 4
# AM_MISSING_PROG(NAME, PROGRAM)
# ------------------------------
AC_DEFUN([AM_MISSING_PROG],
[AC_REQUIRE([AM_MISSING_HAS_RUN])
$1=${$1-"${am_missing_run}$2"}
AC_SUBST($1)])
# AM_MISSING_HAS_RUN
# ------------------
# Define MISSING if not defined so far and test if it supports --run.
# If it does, set am_missing_run to use it, otherwise, to nothing.
AC_DEFUN([AM_MISSING_HAS_RUN],
[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
test x"${MISSING+set}" = xset || MISSING="\${SHELL} $am_aux_dir/missing"
# Use eval to expand $SHELL
if eval "$MISSING --run true"; then
am_missing_run="$MISSING --run "
else
am_missing_run=
AC_MSG_WARN([`missing' script is too old or missing])
fi
])
# Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc.
#
# This file 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.
# AM_PROG_MKDIR_P
# ---------------
# Check whether `mkdir -p' is supported, fallback to mkinstalldirs otherwise.
#
# Automake 1.8 used `mkdir -m 0755 -p --' to ensure that directories
# created by `make install' are always world readable, even if the
# installer happens to have an overly restrictive umask (e.g. 077).
# This was a mistake. There are at least two reasons why we must not
# use `-m 0755':
# - it causes special bits like SGID to be ignored,
# - it may be too restrictive (some setups expect 775 directories).
#
# Do not use -m 0755 and let people choose whatever they expect by
# setting umask.
#
# We cannot accept any implementation of `mkdir' that recognizes `-p'.
# Some implementations (such as Solaris 8's) are not thread-safe: if a
# parallel make tries to run `mkdir -p a/b' and `mkdir -p a/c'
# concurrently, both version can detect that a/ is missing, but only
# one can create it and the other will error out. Consequently we
# restrict ourselves to GNU make (using the --version option ensures
# this.)
AC_DEFUN([AM_PROG_MKDIR_P],
[if mkdir -p --version . >/dev/null 2>&1 && test ! -d ./--version; then
# We used to keeping the `.' as first argument, in order to
# allow $(mkdir_p) to be used without argument. As in
# $(mkdir_p) $(somedir)
# where $(somedir) is conditionally defined. However this is wrong
# for two reasons:
# 1. if the package is installed by a user who cannot write `.'
# make install will fail,
# 2. the above comment should most certainly read
# $(mkdir_p) $(DESTDIR)$(somedir)
# so it does not work when $(somedir) is undefined and
# $(DESTDIR) is not.
# To support the latter case, we have to write
# test -z "$(somedir)" || $(mkdir_p) $(DESTDIR)$(somedir),
# so the `.' trick is pointless.
mkdir_p='mkdir -p --'
else
# On NextStep and OpenStep, the `mkdir' command does not
# recognize any option. It will interpret all options as
# directories to create, and then abort because `.' already
# exists.
for d in ./-p ./--version;
do
test -d $d && rmdir $d
done
# $(mkinstalldirs) is defined by Automake if mkinstalldirs exists.
if test -f "$ac_aux_dir/mkinstalldirs"; then
mkdir_p='$(mkinstalldirs)'
else
mkdir_p='$(install_sh) -d'
fi
fi
AC_SUBST([mkdir_p])])
# Helper functions for option handling. -*- Autoconf -*-
# Copyright (C) 2001, 2002, 2003, 2005 Free Software Foundation, Inc.
#
# This file 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.
# serial 3
# _AM_MANGLE_OPTION(NAME)
# -----------------------
AC_DEFUN([_AM_MANGLE_OPTION],
[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])])
# _AM_SET_OPTION(NAME)
# ------------------------------
# Set option NAME. Presently that only means defining a flag for this option.
AC_DEFUN([_AM_SET_OPTION],
[m4_define(_AM_MANGLE_OPTION([$1]), 1)])
# _AM_SET_OPTIONS(OPTIONS)
# ----------------------------------
# OPTIONS is a space-separated list of Automake options.
AC_DEFUN([_AM_SET_OPTIONS],
[AC_FOREACH([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])])
# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET])
# -------------------------------------------
# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise.
AC_DEFUN([_AM_IF_OPTION],
[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])])
# Check to make sure that the build environment is sane. -*- Autoconf -*-
# Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005
# Free Software Foundation, Inc.
#
# This file 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.
# serial 4
# AM_SANITY_CHECK
# ---------------
AC_DEFUN([AM_SANITY_CHECK],
[AC_MSG_CHECKING([whether build environment is sane])
# Just in case
sleep 1
echo timestamp > conftest.file
# Do `set' in a subshell so we don't clobber the current shell's
# arguments. Must try -L first in case configure is actually a
# symlink; some systems play weird games with the mod time of symlinks
# (eg FreeBSD returns the mod time of the symlink's containing
# directory).
if (
set X `ls -Lt $srcdir/configure conftest.file 2> /dev/null`
if test "$[*]" = "X"; then
# -L didn't work.
set X `ls -t $srcdir/configure conftest.file`
fi
rm -f conftest.file
if test "$[*]" != "X $srcdir/configure conftest.file" \
&& test "$[*]" != "X conftest.file $srcdir/configure"; then
# If neither matched, then we have a broken ls. This can happen
# if, for instance, CONFIG_SHELL is bash and it inherits a
# broken ls alias from the environment. This has actually
# happened. Such a system could not be considered "sane".
AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken
alias in your environment])
fi
test "$[2]" = conftest.file
)
then
# Ok.
:
else
AC_MSG_ERROR([newly created file is older than distributed files!
Check your system clock])
fi
AC_MSG_RESULT(yes)])
# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc.
#
# This file 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.
# AM_PROG_INSTALL_STRIP
# ---------------------
# One issue with vendor `install' (even GNU) is that you can't
# specify the program used to strip binaries. This is especially
# annoying in cross-compiling environments, where the build's strip
# is unlikely to handle the host's binaries.
# Fortunately install-sh will honor a STRIPPROG variable, so we
# always use install-sh in `make install-strip', and initialize
# STRIPPROG with the value of the STRIP variable (set by the user).
AC_DEFUN([AM_PROG_INSTALL_STRIP],
[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl
# Installed binaries are usually stripped using `strip' when the user
# run `make install-strip'. However `strip' might not be the right
# tool to use in cross-compilation environments, therefore Automake
# will honor the `STRIP' environment variable to overrule this program.
dnl Don't test for $cross_compiling = yes, because it might be `maybe'.
if test "$cross_compiling" != no; then
AC_CHECK_TOOL([STRIP], [strip], :)
fi
INSTALL_STRIP_PROGRAM="\${SHELL} \$(install_sh) -c -s"
AC_SUBST([INSTALL_STRIP_PROGRAM])])
# Check how to create a tarball. -*- Autoconf -*-
# Copyright (C) 2004, 2005 Free Software Foundation, Inc.
#
# This file 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.
# serial 2
# _AM_PROG_TAR(FORMAT)
# --------------------
# Check how to create a tarball in format FORMAT.
# FORMAT should be one of `v7', `ustar', or `pax'.
#
# Substitute a variable $(am__tar) that is a command
# writing to stdout a FORMAT-tarball containing the directory
# $tardir.
# tardir=directory && $(am__tar) > result.tar
#
# Substitute a variable $(am__untar) that extract such
# a tarball read from stdin.
# $(am__untar) < result.tar
AC_DEFUN([_AM_PROG_TAR],
[# Always define AMTAR for backward compatibility.
AM_MISSING_PROG([AMTAR], [tar])
m4_if([$1], [v7],
[am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -'],
[m4_case([$1], [ustar],, [pax],,
[m4_fatal([Unknown tar format])])
AC_MSG_CHECKING([how to create a $1 tar archive])
# Loop over all known methods to create a tar archive until one works.
_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none'
_am_tools=${am_cv_prog_tar_$1-$_am_tools}
# Do not fold the above two line into one, because Tru64 sh and
# Solaris sh will not grok spaces in the rhs of `-'.
for _am_tool in $_am_tools
do
case $_am_tool in
gnutar)
for _am_tar in tar gnutar gtar;
do
AM_RUN_LOG([$_am_tar --version]) && break
done
am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"'
am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"'
am__untar="$_am_tar -xf -"
;;
plaintar)
# Must skip GNU tar: if it does not support --format= it doesn't create
# ustar tarball either.
(tar --version) >/dev/null 2>&1 && continue
am__tar='tar chf - "$$tardir"'
am__tar_='tar chf - "$tardir"'
am__untar='tar xf -'
;;
pax)
am__tar='pax -L -x $1 -w "$$tardir"'
am__tar_='pax -L -x $1 -w "$tardir"'
am__untar='pax -r'
;;
cpio)
am__tar='find "$$tardir" -print | cpio -o -H $1 -L'
am__tar_='find "$tardir" -print | cpio -o -H $1 -L'
am__untar='cpio -i -H $1 -d'
;;
none)
am__tar=false
am__tar_=false
am__untar=false
;;
esac
# If the value was cached, stop now. We just wanted to have am__tar
# and am__untar set.
test -n "${am_cv_prog_tar_$1}" && break
# tar/untar a dummy directory, and stop if the command works
rm -rf conftest.dir
mkdir conftest.dir
echo GrepMe > conftest.dir/file
AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar])
rm -rf conftest.dir
if test -s conftest.tar; then
AM_RUN_LOG([$am__untar <conftest.tar])
grep GrepMe conftest.dir/file >/dev/null 2>&1 && break
fi
done
rm -rf conftest.dir
AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool])
AC_MSG_RESULT([$am_cv_prog_tar_$1])])
AC_SUBST([am__tar])
AC_SUBST([am__untar])
]) # _AM_PROG_TAR

View File

@ -3,7 +3,7 @@
*
* Home page of code is: http://smartmontools.sourceforge.net
*
* Copyright (C) 2002-6 Bruce Allen <smartmontools-support@lists.sourceforge.net>
* Copyright (C) 2002-7 Bruce Allen <smartmontools-support@lists.sourceforge.net>
* Copyright (C) 1999-2000 Michael Cornwell <cornwell@acm.org>
* Copyright (C) 2000 Andre Hedrick <andre@linux-ide.org>
*
@ -36,7 +36,7 @@
#include "extern.h"
#include "utility.h"
const char *atacmds_c_cvsid="$Id: atacmds.cpp,v 1.177 2006/10/27 21:30:02 chrfranke Exp $"
const char *atacmds_c_cvsid="$Id: atacmds.cpp,v 1.188 2007/07/26 20:58:50 chrfranke Exp $"
ATACMDS_H_CVSID CONFIG_H_CVSID EXTERN_H_CVSID INT64_H_CVSID SCSIATA_H_CVSID UTILITY_H_CVSID;
// to hold onto exit code for atexit routine
@ -514,6 +514,25 @@ void swap8(char *location){
return;
}
// Invalidate serial number and adjust checksum in IDENTIFY data
static void invalidate_serno(ata_identify_device * id){
unsigned char sum = 0;
for (unsigned i = 0; i < sizeof(id->serial_no); i++) {
sum += id->serial_no[i]; sum -= id->serial_no[i] = 'X';
}
#ifndef __NetBSD__
bool must_swap = !!isbigendian();
if (must_swap)
swapx(id->words088_255+255-88);
#endif
if ((id->words088_255[255-88] & 0x00ff) == 0x00a5)
id->words088_255[255-88] += sum << 8;
#ifndef __NetBSD__
if (must_swap)
swapx(id->words088_255+255-88);
#endif
}
static char *commandstrings[]={
"SMART ENABLE",
"SMART DISABLE",
@ -532,18 +551,20 @@ static char *commandstrings[]={
"WARNING (UNDEFINED COMMAND -- CONTACT DEVELOPERS AT " PACKAGE_BUGREPORT ")\n"
};
void prettyprint(unsigned char *stuff, char *name){
int i,j;
static void prettyprint(const unsigned char *p, const char *name){
pout("\n===== [%s] DATA START (BASE-16) =====\n", name);
for (i=0; i<32; i++){
pout("%03d-%03d: ", 16*i, 16*(i+1)-1);
for (j=0; j<15; j++)
pout("%02x ",*stuff++);
pout("%02x\n",*stuff++);
}
for (int i=0; i<512; i+=16, p+=16)
// print complete line to avoid slow tty output and extra lines in syslog.
pout("%03d-%03d: %02x %02x %02x %02x %02x %02x %02x %02x "
"%02x %02x %02x %02x %02x %02x %02x %02x\n",
i, i+16-1,
p[ 0], p[ 1], p[ 2], p[ 3], p[ 4], p[ 5], p[ 6], p[ 7],
p[ 8], p[ 9], p[10], p[11], p[12], p[13], p[14], p[15]);
pout("===== [%s] DATA END (512 Bytes) =====\n\n", name);
}
static int parsedev_command_interface(int fd, smart_command_set command, int select, char * data);
// This function provides the pretty-print reporting for SMART
// commands: it implements the various -r "reporting" options for ATA
// ioctls.
@ -592,13 +613,9 @@ int smartcommandhandler(int device, smart_command_set command, int select, char
}
// If reporting is enabled, say what input was sent to the command
if (con->reportataioctl && sendsdata){
pout("REPORT-IOCTL: DeviceFD=%d Command=%s", device, commandstrings[command]);
// if requested, pretty-print the output data structure
if (con->reportataioctl>1)
prettyprint((unsigned char *)data, commandstrings[command]);
}
// if requested, pretty-print the input data structure
if (con->reportataioctl>1 && sendsdata)
prettyprint((unsigned char *)data, commandstrings[command]);
// In case the command produces an error, we'll want to know what it is:
errno=0;
@ -621,10 +638,17 @@ int smartcommandhandler(int device, smart_command_set command, int select, char
case CONTROLLER_HPT:
retval=highpoint_command_interface(device, command, select, data);
break;
case CONTROLLER_PARSEDEV:
retval=parsedev_command_interface(device, command, select, data);
break;
default:
retval=ata_command_interface(device, command, select, data);
}
// If requested, invalidate serial number before any printing is done
if ((command == IDENTIFY || command == PIDENTIFY) && !retval && con->dont_print_serial)
invalidate_serno((ata_identify_device *)data);
// If reporting is enabled, say what output was produced by the command
if (con->reportataioctl){
if (errno)
@ -700,7 +724,7 @@ int ataReadHDIdentity (int device, struct ata_identify_device *buf){
#ifndef __NetBSD__
// if machine is big-endian, swap byte order as needed
// (the NetBSD kernel does deliver the results in host byte order)
// NetBSD kernel delivers IDENTIFY data in host byte order
if (isbigendian()){
int i;
@ -772,6 +796,23 @@ int ataVersionInfo (const char** description, struct ata_identify_device *drive,
}
}
// Try new ATA-8 minor revision numbers (Table 30 of T13/1699-D Revision 4b)
// (not in actual_ver/minor_str to avoid large sparse tables)
const char *desc;
switch (*minor) {
case 0x0027: desc = "ATA-8-ACS revision 3c"; break;
case 0x0029: desc = "ATA-8-ACS revision 4"; break;
case 0x0033: desc = "ATA-8-ACS revision 3e"; break;
case 0x0042: desc = "ATA-8-ACS revision 3f"; break;
case 0x0052: desc = "ATA-8-ACS revision 3b"; break;
case 0x0107: desc = "ATA-8-ACS revision 2d"; break;
default: desc = 0; break;
}
if (desc) {
*description = desc;
return 8;
}
// HDPARM has a very complicated algorithm from here on. Since SMART only
// exists on ATA-3 and later standards, let's punt on this. If you don't
// like it, please fix it. The code's in CVS.
@ -827,7 +868,7 @@ int ataReadSmartValues(int device, struct ata_smart_values *data){
if (checksum((unsigned char *)data))
checksumwarning("SMART Attribute Data Structure");
// byte swap if needed
// swap endian order if needed
if (isbigendian()){
int i;
swap2((char *)&(data->revnumber));
@ -879,7 +920,7 @@ int ataReadSelfTestLog (int device, struct ata_smart_selftestlog *data){
if (con->fixfirmwarebug == FIX_SAMSUNG)
fixsamsungselftestlog(data);
// fix endian order, if needed
// swap endian order if needed
if (isbigendian()){
int i;
swap2((char*)&(data->revnumber));
@ -945,13 +986,17 @@ int ataReadSelectiveSelfTestLog(int device, struct ata_selective_self_test_log *
}
// Writes the selective self-test log (log #9)
int ataWriteSelectiveSelfTestLog(int device, struct ata_smart_values *sv){
int i;
struct ata_selective_self_test_log sstlog, *data=&sstlog;
unsigned char cksum=0;
unsigned char *ptr=(unsigned char *)data;
int ataWriteSelectiveSelfTestLog(int device, struct ata_smart_values *sv, uint64_t num_sectors){
// Disk size must be known
if (!num_sectors) {
pout("Disk size is unknown, unable to check selective self-test spans\n");
return -1;
}
// Read log
struct ata_selective_self_test_log sstlog, *data=&sstlog;
unsigned char *ptr=(unsigned char *)data;
if (ataReadSelectiveSelfTestLog(device, data)) {
pout("Since Read failed, will not attempt to WRITE Selective Self-test Log\n");
return -1;
@ -978,6 +1023,80 @@ int ataWriteSelectiveSelfTestLog(int device, struct ata_smart_values *sv){
return -4;
}
// Set start/end values based on old spans for special -t select,... options
int i;
for (i=0; i<con->smartselectivenumspans; i++) {
char mode = con->smartselectivemode[i];
uint64_t start = con->smartselectivespan[i][0];
uint64_t end = con->smartselectivespan[i][1];
if (mode == SEL_CONT) {// redo or next dependig on last test status
switch (sv->self_test_exec_status >> 4) {
case 1: case 2: // Aborted/Interrupted by host
pout("Continue Selective Self-Test: Redo last span\n");
mode = SEL_REDO;
break;
default: // All others
pout("Continue Selective Self-Test: Start next span\n");
mode = SEL_NEXT;
break;
}
}
switch (mode) {
case SEL_RANGE: // -t select,START-END
break;
case SEL_REDO: // -t select,redo... => Redo current
start = data->span[i].start;
if (end > 0) { // -t select,redo+SIZE
end--; end += start; // [oldstart, oldstart+SIZE)
}
else // -t select,redo
end = data->span[i].end; // [oldstart, oldend]
break;
case SEL_NEXT: // -t select,next... => Do next
if (data->span[i].end == 0) {
start = end = 0; break; // skip empty spans
}
start = data->span[i].end + 1;
if (start >= num_sectors)
start = 0; // wrap around
if (end > 0) { // -t select,next+SIZE
end--; end += start; // (oldend, oldend+SIZE]
}
else { // -t select,next
uint64_t oldsize = data->span[i].end - data->span[i].start + 1;
end = start + oldsize - 1; // (oldend, oldend+oldsize]
if (end >= num_sectors) {
// Adjust size to allow round-robin testing without future size decrease
uint64_t spans = (num_sectors + oldsize-1) / oldsize;
uint64_t newsize = (num_sectors + spans-1) / spans;
uint64_t newstart = num_sectors - newsize, newend = num_sectors - 1;
pout("Span %d changed from %"PRIu64"-%"PRIu64" (%"PRIu64" sectors)\n"
" to %"PRIu64"-%"PRIu64" (%"PRIu64" sectors) (%"PRIu64" spans)\n",
i, start, end, oldsize, newstart, newend, newsize, spans);
start = newstart; end = newend;
}
}
break;
default:
pout("ataWriteSelectiveSelfTestLog: Invalid mode %d\n", mode);
return -1;
}
// Range check
if (start < num_sectors && num_sectors <= end) {
if (end != ~(uint64_t)0) // -t select,N-max
pout("Size of self-test span %d decreased according to disk size\n", i);
end = num_sectors - 1;
}
if (!(start <= end && end < num_sectors)) {
pout("Invalid selective self-test span %d: %"PRIu64"-%"PRIu64" (%"PRIu64" sectors)\n",
i, start, end, num_sectors);
return -1;
}
// Write back to allow ataSmartTest() to print the actual values
con->smartselectivespan[i][0] = start;
con->smartselectivespan[i][1] = end;
}
// Clear spans
for (i=0; i<5; i++)
memset(data->span+i, 0, sizeof(struct test_span));
@ -1010,17 +1129,17 @@ int ataWriteSelectiveSelfTestLog(int device, struct ata_smart_values *sv){
// Set checksum to zero, then compute checksum
data->checksum=0;
unsigned char cksum=0;
for (i=0; i<512; i++)
cksum+=ptr[i];
cksum=~cksum;
cksum+=1;
data->checksum=cksum;
// swap endian order if needed
// swap endian order if needed
if (isbigendian()){
int i;
swap2((char *)&(data->logversion));
for (i=0;i<5;i++){
for (int i=0;i<5;i++){
swap8((char *)&(data->span[i].start));
swap8((char *)&(data->span[i].end));
}
@ -1092,7 +1211,7 @@ int ataReadErrorLog (int device, struct ata_smart_errorlog *data){
else if (con->fixfirmwarebug == FIX_SAMSUNG2)
fixsamsungerrorlog2(data);
// Correct endian order if necessary
// swap endian order if needed
if (isbigendian()){
int i,j;
@ -1125,7 +1244,7 @@ int ataReadSmartThresholds (int device, struct ata_smart_thresholds_pvt *data){
if (checksum((unsigned char *)data))
checksumwarning("SMART Attribute Thresholds Structure");
// byte swap if needed
// swap endian order if needed
if (isbigendian())
swap2((char *)&(data->revnumber));
@ -1212,7 +1331,8 @@ int ataSmartStatus2(int device){
// This is the way to execute ALL tests: offline, short self-test,
// extended self test, with and without captive mode, etc.
int ataSmartTest(int device, int testtype, struct ata_smart_values *sv) {
int ataSmartTest(int device, int testtype, struct ata_smart_values *sv, uint64_t num_sectors)
{
char cmdmsg[128],*type,*captive;
int errornum, cap, retval, select=0;
@ -1240,7 +1360,7 @@ int ataSmartTest(int device, int testtype, struct ata_smart_values *sv) {
// If doing a selective self-test, first use WRITE_LOG to write the
// selective self-test log.
if (select && (retval=ataWriteSelectiveSelfTestLog(device, sv))) {
if (select && (retval=ataWriteSelectiveSelfTestLog(device, sv, num_sectors))) {
if (retval==-4)
pout("Can't start selective self-test without aborting current test: use '-X' option to smartctl.\n");
return retval;
@ -1484,6 +1604,32 @@ int ataCheckAttribute(struct ata_smart_values *data,
}
// Print temperature value and Min/Max value if present
static void ataPrintTemperatureValue(char *out, const unsigned char *raw, const unsigned *word)
{
out+=sprintf(out, "%u", word[0]);
if (!word[1] && !word[2])
return; // No Min/Max
unsigned lo = ~0, hi = ~0;
if (!raw[3]) {
// 00 HH 00 LL 00 TT (IBM)
hi = word[2]; lo = word[1];
}
else if (!word[2]) {
// 00 00 HH LL 00 TT (Maxtor)
hi = raw[3]; lo = raw[2];
}
if (lo > hi) {
unsigned t = lo; lo = hi; hi = t;
}
if (lo <= word[0] && word[0] <= hi)
sprintf(out, " (Lifetime Min/Max %u/%u)", lo, hi);
else
sprintf(out, " (%u %u %u %u)", raw[5], raw[4], raw[3], raw[2]);
}
// This routine prints the raw value of an attribute as a text string
// into out. It also returns this 48-bit number as a long long. The
// array defs[] contains non-zero values if particular attributes have
@ -1579,6 +1725,10 @@ int64_t ataPrintSmartAttribRawValue(char *out,
// hours
out+=sprintf(out, "%"PRIu64, rawvalue); //stored in hours
break;
// Temperature
case 190:
ataPrintTemperatureValue(out, attribute->raw, word);
break;
// Load unload cycles
case 193:
if (select==1){
@ -1602,15 +1752,8 @@ int64_t ataPrintSmartAttribRawValue(char *out,
else if (select==2)
// unknown attribute
out+=sprintf(out, "%"PRIu64, rawvalue);
else {
out+=sprintf(out, "%d", word[0]);
if (!(rawvalue==word[0])) {
int min=word[1]<word[2]?word[1]:word[2];
int max=word[1]>word[2]?word[1]:word[2];
// The other bytes are in use. Try IBM's model
out+=sprintf(out, " (Lifetime Min/Max %d/%d)", min, max);
}
}
else
ataPrintTemperatureValue(out, attribute->raw, word);
break;
default:
out+=sprintf(out, "%"PRIu64, rawvalue);
@ -1692,6 +1835,12 @@ void ataPrintSmartAttribName(char *out, unsigned char id, unsigned char *definit
case 13:
name="Read_Soft_Error_Rate";
break;
case 187:
name="Reported_Uncorrect";
break;
case 189:
name="High_Fly_Writes";
break;
case 190:
// Western Digital uses this for temperature.
// It's identical to Attribute 194 except that it
@ -1700,7 +1849,7 @@ void ataPrintSmartAttribName(char *out, unsigned char id, unsigned char *definit
// is typically 55C. So if this attribute has failed
// in the past, it indicates that the drive temp exceeded
// 55C sometime in the past.
name="Temperature_Celsius";
name="Airflow_Temperature_Cel";
break;
case 191:
name="G-Sense_Error_Rate";
@ -1934,3 +2083,399 @@ unsigned char ATAReturnTemperatureValue(/*const*/ struct ata_smart_values *data,
// No valid attribute found
return 0;
}
// Read SCT Status
int ataReadSCTStatus(int device, ata_sct_status_response * sts)
{
// read SCT status via SMART log 0xe0
memset(sts, 0, sizeof(*sts));
if (smartcommandhandler(device, READ_LOG, 0xe0, (char *)sts)){
syserror("Error Read SCT Status failed");
return -1;
}
// swap endian order if needed
if (isbigendian()){
swapx(&sts->format_version);
swapx(&sts->sct_version);
swapx(&sts->sct_spec);
swapx(&sts->ext_status_code);
swapx(&sts->action_code);
swapx(&sts->function_code);
swapx(&sts->over_limit_count);
swapx(&sts->under_limit_count);
}
// Check format version
if (!(sts->format_version == 2 || sts->format_version == 3)) {
pout("Error unknown SCT Status format version %u, should be 2 or 3.\n", sts->format_version);
return -1;
}
return 0;
}
// Read SCT Temperature History Table and Status
int ataReadSCTTempHist(int device, ata_sct_temperature_history_table * tmh,
ata_sct_status_response * sts)
{
// Check initial status
if (ataReadSCTStatus(device, sts))
return -1;
// Do nothing if other SCT command is executing
if (sts->ext_status_code == 0xffff) {
pout("Another SCT command is executing, abort Read Data Table\n"
"(SCT ext_status_code 0x%04x, action_code=%u, function_code=%u)\n",
sts->ext_status_code, sts->action_code, sts->function_code);
return -1;
}
ata_sct_data_table_command cmd; memset(&cmd, 0, sizeof(cmd));
// CAUTION: DO NOT CHANGE THIS VALUE (SOME ACTION CODES MAY ERASE DISK)
cmd.action_code = 5; // Data table command
cmd.function_code = 1; // Read table
cmd.table_id = 2; // Temperature History Table
// write command via SMART log page 0xe0
if (smartcommandhandler(device, WRITE_LOG, 0xe0, (char *)&cmd)){
syserror("Error Write SCT Data Table command failed");
return -1;
}
// read SCT data via SMART log page 0xe1
memset(tmh, 0, sizeof(*tmh));
if (smartcommandhandler(device, READ_LOG, 0xe1, (char *)tmh)){
syserror("Error Read SCT Data Table failed");
return -1;
}
// re-read and check SCT status
if (ataReadSCTStatus(device, sts))
return -1;
if (!(sts->ext_status_code == 0 && sts->action_code == 5 && sts->function_code == 1)) {
pout("Error unexcepted SCT status 0x%04x (action_code=%u, function_code=%u)\n",
sts->ext_status_code, sts->action_code, sts->function_code);
return -1;
}
// swap endian order if needed
if (isbigendian()){
swapx(&tmh->format_version);
swapx(&tmh->sampling_period);
swapx(&tmh->interval);
}
// Check format version
if (tmh->format_version != 2) {
pout("Error unknown SCT Temperature History Format Version (%u), should be 2.\n", tmh->format_version);
return -1;
}
return 0;
}
// Set SCT Temperature Logging Interval
int ataSetSCTTempInterval(int device, unsigned interval, bool persistent)
{
// Check initial status
ata_sct_status_response sts;
if (ataReadSCTStatus(device, &sts))
return -1;
// Do nothing if other SCT command is executing
if (sts.ext_status_code == 0xffff) {
pout("Another SCT command is executing, abort Feature Control\n"
"(SCT ext_status_code 0x%04x, action_code=%u, function_code=%u)\n",
sts.ext_status_code, sts.action_code, sts.function_code);
return -1;
}
ata_sct_feature_control_command cmd; memset(&cmd, 0, sizeof(cmd));
// CAUTION: DO NOT CHANGE THIS VALUE (SOME ACTION CODES MAY ERASE DISK)
cmd.action_code = 4; // Feature Control command
cmd.function_code = 1; // Set state
cmd.feature_code = 3; // Temperature logging interval
cmd.state = interval;
cmd.option_flags = (persistent ? 0x01 : 0x00);
// write command via SMART log page 0xe0
if (smartcommandhandler(device, WRITE_LOG, 0xe0, (char *)&cmd)){
syserror("Error Write SCT Feature Control Command failed");
return -1;
}
// re-read and check SCT status
if (ataReadSCTStatus(device, &sts))
return -1;
if (!(sts.ext_status_code == 0 && sts.action_code == 4 && sts.function_code == 1)) {
pout("Error unexcepted SCT status 0x%04x (action_code=%u, function_code=%u)\n",
sts.ext_status_code, sts.action_code, sts.function_code);
return -1;
}
return 0;
}
/////////////////////////////////////////////////////////////////////////////
// Pseudo-device to parse "smartctl -r ataioctl,2 ..." output and simulate
// an ATA device with same behaviour
// Table of parsed commands, return value, data
struct parsed_ata_command
{
smart_command_set command;
int select;
int retval, errval;
char * data;
};
const int max_num_parsed_commands = 32;
static parsed_ata_command parsed_command_table[max_num_parsed_commands];
static int num_parsed_commands;
static int next_replay_command;
static bool replay_out_of_sync;
static const char * nextline(const char * s, int & lineno)
{
for (s += strcspn(s, "\r\n"); *s == '\r' || *s == '\n'; s++) {
if (*s == '\r' && s[1] == '\n')
s++;
lineno++;
}
return s;
}
static int name2command(const char * s)
{
for (int i = 0; i < (int)(sizeof(commandstrings)/sizeof(commandstrings[0])); i++) {
if (!strcmp(s, commandstrings[i]))
return i;
}
return -1;
}
static bool matchcpy(char * dest, size_t size, const char * src, const regmatch_t & srcmatch)
{
if (srcmatch.rm_so < 0)
return false;
size_t n = srcmatch.rm_eo - srcmatch.rm_so;
if (n >= size)
n = size-1;
memcpy(dest, src + srcmatch.rm_so, n);
dest[n] = 0;
return true;
}
static inline int matchtoi(const char * src, const regmatch_t & srcmatch, int defval)
{
if (srcmatch.rm_so < 0)
return defval;
return atoi(src + srcmatch.rm_so);
}
// Parse stdin and build command table
int parsedev_open(const char * pathname)
{
if (strcmp(pathname, "-")) {
errno = EINVAL; return -1;
}
pathname = "<stdin>";
// Fill buffer
char buffer[64*1024];
int size = 0;
while (size < (int)sizeof(buffer)) {
int nr = fread(buffer, 1, sizeof(buffer), stdin);
if (nr <= 0)
break;
size += nr;
}
if (size <= 0) {
pout("%s: Unexpected EOF\n", pathname);
errno = ENOENT; return -1;
}
if (size >= (int)sizeof(buffer)) {
pout("%s: Buffer overflow\n", pathname);
errno = EIO; return -1;
}
buffer[size] = 0;
// Regex to match output from "-r ataioctl,2"
static const char pattern[] = "^"
"(" // (1
"REPORT-IOCTL: DeviceFD=[0-9]+ Command=([A-Z ]*[A-Z])" // (2)
"(" // (3
"( InputParameter=([0-9]+))?" // (4 (5))
"|"
"( returned (-?[0-9]+)( errno=([0-9]+)[^\r\n]*)?)" // (6 (7) (8 (9)))
")" // )
"[\r\n]" // EOL match necessary to match optional parts above
"|"
"===== \\[([A-Z ]*[A-Z])\\] DATA START " // (10)
")"; // )
// Compile regex
regex_t rex;
if (compileregex(&rex, pattern, REG_EXTENDED)) {
errno = EIO; return -1;
}
// Parse buffer
const char * errmsg = 0;
int i = -1, state = 0, lineno = 1;
for (const char * line = buffer; *line; line = nextline(line, lineno)) {
// Match line
if (!(line[0] == 'R' || line[0] == '='))
continue;
const int nmatch = 1+10;
regmatch_t match[nmatch];
if (regexec(&rex, line, nmatch, match, 0))
continue;
char cmdname[40];
if (matchcpy(cmdname, sizeof(cmdname), line, match[2])) { // "REPORT-IOCTL:... Command=%s ..."
int nc = name2command(cmdname);
if (nc < 0) {
errmsg = "Unknown ATA command name"; break;
}
if (match[7].rm_so < 0) { // "returned %d"
// Start of command
if (!(state == 0 || state == 2)) {
errmsg = "Missing REPORT-IOCTL result"; break;
}
if (++i >= max_num_parsed_commands) {
errmsg = "Too many ATA commands"; break;
}
parsed_command_table[i].command = (smart_command_set)nc;
parsed_command_table[i].select = matchtoi(line, match[5], 0); // "InputParameter=%d"
state = 1;
}
else {
// End of command
if (!(state == 1 && (int)parsed_command_table[i].command == nc)) {
errmsg = "Missing REPORT-IOCTL start"; break;
}
parsed_command_table[i].retval = matchtoi(line, match[7], -1); // "returned %d"
parsed_command_table[i].errval = matchtoi(line, match[9], 0); // "errno=%d"
state = 2;
}
}
else if (matchcpy(cmdname, sizeof(cmdname), line, match[10])) { // "===== [%s] DATA START "
// Start of sector hexdump
int nc = name2command(cmdname);
if (!(state == (nc == WRITE_LOG ? 1 : 2) && (int)parsed_command_table[i].command == nc)) {
errmsg = "Unexpected DATA START"; break;
}
line = nextline(line, lineno);
char * data = (char *)malloc(512);
unsigned j;
for (j = 0; j < 32; j++) {
unsigned b[16];
unsigned u1, u2; int n1 = -1;
if (!(sscanf(line, "%3u-%3u: "
"%2x %2x %2x %2x %2x %2x %2x %2x "
"%2x %2x %2x %2x %2x %2x %2x %2x%n",
&u1, &u2,
b+ 0, b+ 1, b+ 2, b+ 3, b+ 4, b+ 5, b+ 6, b+ 7,
b+ 8, b+ 9, b+10, b+11, b+12, b+13, b+14, b+15, &n1) == 18
&& n1 >= 56 && u1 == j*16 && u2 == j*16+15))
break;
for (unsigned k = 0; k < 16; k++)
data[j*16+k] = b[k];
line = nextline(line, lineno);
}
if (j < 32) {
free(data);
errmsg = "Incomplete sector hex dump"; break;
}
parsed_command_table[i].data = data;
if (nc != WRITE_LOG)
state = 0;
}
}
if (!(state == 0 || state == 2))
errmsg = "Missing REPORT-IOCTL result";
if (!errmsg && i < 0)
errmsg = "No information found";
num_parsed_commands = i+1;
next_replay_command = 0;
replay_out_of_sync = false;
if (errmsg) {
pout("%s(%d): Syntax error: %s\n", pathname, lineno, errmsg);
errno = EIO;
parsedev_close(0);
return -1;
}
return 0;
}
// Report warnings and free command table
void parsedev_close(int /*fd*/)
{
if (replay_out_of_sync)
pout("REPLAY-IOCTL: Warning: commands replayed out of sync\n");
else if (next_replay_command != 0)
pout("REPLAY-IOCTL: Warning: %d command(s) not replayed\n", num_parsed_commands-next_replay_command);
for (int i = 0; i < num_parsed_commands; i++) {
if (parsed_command_table[i].data) {
free(parsed_command_table[i].data); parsed_command_table[i].data = 0;
}
}
num_parsed_commands = 0;
}
// Simulate ATA command from command table
static int parsedev_command_interface(int /*fd*/, smart_command_set command, int select, char * data)
{
// Find command, try round-robin of out of sync
int i = next_replay_command;
for (int j = 0; ; j++) {
if (j >= num_parsed_commands) {
pout("REPLAY-IOCTL: Warning: Command not found\n");
errno = ENOSYS;
return -1;
}
if (parsed_command_table[i].command == command && parsed_command_table[i].select == select)
break;
if (!replay_out_of_sync) {
replay_out_of_sync = true;
pout("REPLAY-IOCTL: Warning: Command #%d is out of sync\n", i+1);
}
if (++i >= num_parsed_commands)
i = 0;
}
next_replay_command = i;
if (++next_replay_command >= num_parsed_commands)
next_replay_command = 0;
// Return command data
switch (command) {
case IDENTIFY:
case PIDENTIFY:
case READ_VALUES:
case READ_THRESHOLDS:
case READ_LOG:
if (parsed_command_table[i].data)
memcpy(data, parsed_command_table[i].data, 512);
break;
case WRITE_LOG:
if (!(parsed_command_table[i].data && !memcmp(data, parsed_command_table[i].data, 512)))
pout("REPLAY-IOCTL: Warning: WRITE LOG data does not match\n");
break;
case CHECK_POWER_MODE:
data[0] = (char)0xff;
default:
break;
}
if (parsed_command_table[i].errval)
errno = parsed_command_table[i].errval;
return parsed_command_table[i].retval;
}

122
atacmds.h
View File

@ -3,7 +3,7 @@
*
* Home page of code is: http://smartmontools.sourceforge.net
*
* Copyright (C) 2002-6 Bruce Allen <smartmontools-support@lists.sourceforge.net>
* Copyright (C) 2002-7 Bruce Allen <smartmontools-support@lists.sourceforge.net>
* Copyright (C) 1999-2000 Michael Cornwell <cornwell@acm.org>
*
* This program is free software; you can redistribute it and/or modify
@ -25,7 +25,7 @@
#ifndef ATACMDS_H_
#define ATACMDS_H_
#define ATACMDS_H_CVSID "$Id: atacmds.h,v 1.83 2006/08/25 06:06:24 sxzzsf Exp $\n"
#define ATACMDS_H_CVSID "$Id: atacmds.h,v 1.89 2007/07/26 20:58:50 chrfranke Exp $\n"
// Macro to check expected size of struct at compile time using a
// dummy typedef. On size mismatch, compiler reports a negative array
@ -372,6 +372,92 @@ ASSERT_SIZEOF_STRUCT(ata_selective_self_test_log, 512);
#define SELECTIVE_FLAG_PENDING (0x0008)
#define SELECTIVE_FLAG_ACTIVE (0x0010)
// SCT (SMART Command Transport) data structures
// See Sections 8.2 and 8.3 of:
// AT Attachment 8 - ATA/ATAPI Command Set (ATA8-ACS)
// T13/1699-D Revision 3f (Working Draft), December 11, 2006.
// SCT Status response (read with SMART_READ_LOG page 0xe0)
// Table 60 of T13/1699-D Revision 3f
#pragma pack(1)
struct ata_sct_status_response
{
unsigned short format_version; // 0-1: Status response format version number (2, 3)
unsigned short sct_version; // 2-3: Vendor specific version number
unsigned short sct_spec; // 4-5: SCT level supported (1)
unsigned int status_flags; // 6-9: Status flags (Bit 0: Segment initialized, Bits 1-31: reserved)
unsigned char device_state; // 10: Device State (0-5)
unsigned char bytes011_013[3]; // 11-13: reserved
unsigned short ext_status_code; // 14-15: Status of last SCT command (0xffff if executing)
unsigned short action_code; // 16-17: Action code of last SCT command
unsigned short function_code; // 18-19: Function code of last SCT command
unsigned char bytes020_039[20]; // 20-39: reserved
uint64_t lba_current; // 40-47: LBA of SCT command executing in background
unsigned char bytes048_199[152]; // 48-199: reserved
signed char hda_temp; // 200: Current temperature in Celsius (0x80 = invalid)
signed char min_temp; // 201: Minimum temperature this power cycle
signed char max_temp; // 202: Maximum temperature this power cycle
signed char life_min_temp; // 203: Minimum lifetime temperature
signed char life_max_temp; // 204: Maximum lifetime temperature
unsigned char byte205; // 205: reserved (T13/e06152r0-2: Average lifetime temperature)
unsigned int over_limit_count; // 206-209: # intervals since last reset with temperature > Max Op Limit
unsigned int under_limit_count; // 210-213: # intervals since last reset with temperature < Min Op Limit
unsigned char bytes214_479[266]; // 214-479: reserved
unsigned char vendor_specific[32];// 480-511: vendor specific
} ATTR_PACKED;
#pragma pack()
ASSERT_SIZEOF_STRUCT(ata_sct_status_response, 512);
// SCT Feature Control command (send with SMART_WRITE_LOG page 0xe0)
// Table 72 of T13/1699-D Revision 3f
#pragma pack(1)
struct ata_sct_feature_control_command
{
unsigned short action_code; // 4 = Feature Control
unsigned short function_code; // 1 = Set, 2 = Return, 3 = Return options
unsigned short feature_code; // 3 = Temperature logging interval
unsigned short state; // Interval
unsigned short option_flags; // Bit 0: persistent, Bits 1-31: reserved
unsigned short words005_255[251]; // reserved
} ATTR_PACKED;
#pragma pack()
ASSERT_SIZEOF_STRUCT(ata_sct_feature_control_command, 512);
// SCT Data Table command (send with SMART_WRITE_LOG page 0xe0)
// Table 73 of T13/1699-D Revision 3f
#pragma pack(1)
struct ata_sct_data_table_command
{
unsigned short action_code; // 5 = Data Table
unsigned short function_code; // 1 = Read Table
unsigned short table_id; // 2 = Temperature History
unsigned short words003_255[253]; // reserved
} ATTR_PACKED;
#pragma pack()
ASSERT_SIZEOF_STRUCT(ata_sct_data_table_command, 512);
// SCT Temperature History Table (read with SMART_READ_LOG page 0xe1)
// Table 75 of T13/1699-D Revision 3f
#pragma pack(1)
struct ata_sct_temperature_history_table
{
unsigned short format_version; // 0-1: Data table format version number (2)
unsigned short sampling_period; // 2-3: Temperature sampling period in minutes
unsigned short interval; // 4-5: Timer interval between history entries
signed char max_op_limit; // 6: Maximum recommended continuous operating temperature
signed char over_limit; // 7: Maximum temperature limit
signed char min_op_limit; // 8: Minimum recommended continuous operating limit
signed char under_limit; // 9: Minimum temperature limit
unsigned char bytes010_029[20]; // 10-29: reserved
unsigned short cb_size; // 30-31: Number of history entries (range 128-478)
unsigned short cb_index; // 32-33: Index of last updated entry (zero-based)
signed char cb[478]; // 34-(34+cb_size-1): Circular buffer of temperature values
} ATTR_PACKED;
#pragma pack()
ASSERT_SIZEOF_STRUCT(ata_sct_temperature_history_table, 512);
// Get information from drive
int ataReadHDIdentity(int device, struct ata_identify_device *buf);
int ataCheckPowerMode(int device);
@ -386,6 +472,14 @@ int ataSmartStatus(int device);
int ataSetSmartThresholds(int device, struct ata_smart_thresholds_pvt *);
int ataReadLogDirectory(int device, struct ata_smart_log_directory *);
// Read SCT information
int ataReadSCTStatus(int device, ata_sct_status_response * sts);
int ataReadSCTTempHist(int device, ata_sct_temperature_history_table * tmh,
ata_sct_status_response * sts);
// Set SCT temperature logging interval
int ataSetSCTTempInterval(int device, unsigned interval, bool persistent);
/* Enable/Disable SMART on device */
int ataEnableSmart ( int device );
int ataDisableSmart (int device );
@ -455,7 +549,16 @@ int isSupportConveyanceSelfTest(struct ata_smart_values *data);
int isSupportSelectiveSelfTest(struct ata_smart_values *data);
int ataSmartTest(int device, int testtype, struct ata_smart_values *data);
inline bool isSCTCapable(const ata_identify_device *drive)
{ return !!(drive->words088_255[206-88] & 0x01); } // 0x01 = SCT support
inline bool isSCTFeatureControlCapable(const ata_identify_device *drive)
{ return ((drive->words088_255[206-88] & 0x11) == 0x11); } // 0x10 = SCT Feature Control support
inline bool isSCTDataTableCapable(const ata_identify_device *drive)
{ return ((drive->words088_255[206-88] & 0x21) == 0x21); } // 0x20 = SCT Data Table support
int ataSmartTest(int device, int testtype, struct ata_smart_values *data, uint64_t num_sectors);
int TestTime(struct ata_smart_values *data,int testtype);
@ -526,6 +629,11 @@ int ata_command_interface(int device, smart_command_set command, int select, cha
int escalade_command_interface(int fd, int escalade_port, int escalade_type, smart_command_set command, int select, char *data);
int marvell_command_interface(int device, smart_command_set command, int select, char *data);
int highpoint_command_interface(int device, smart_command_set command, int select, char *data);
// "smartctl -r ataioctl,2 ..." output parser pseudo-device
int parsedev_open(const char * name);
void parsedev_close(int fd);
// Optional functions of os_*.c
#ifdef HAVE_ATA_IDENTIFY_IS_CACHED
// Return true if OS caches the ATA identify sector
@ -539,4 +647,12 @@ int smartcommandhandler(int device, smart_command_set command, int select, char
void swap2(char *location);
void swap4(char *location);
void swap8(char *location);
// Typesafe variants using overloading
inline void swapx(unsigned short * p)
{ swap2((char*)p); }
inline void swapx(unsigned int * p)
{ swap4((char*)p); }
inline void swapx(uint64_t * p)
{ swap8((char*)p); }
#endif /* ATACMDS_H_ */

View File

@ -3,7 +3,7 @@
*
* Home page of code is: http://smartmontools.sourceforge.net
*
* Copyright (C) 2002-6 Bruce Allen <smartmontools-support@lists.sourceforge.net>
* Copyright (C) 2002-7 Bruce Allen <smartmontools-support@lists.sourceforge.net>
* Copyright (C) 1999-2000 Michael Cornwell <cornwell@acm.org>
*
* This program is free software; you can redistribute it and/or modify
@ -41,7 +41,7 @@
#include "utility.h"
#include "knowndrives.h"
const char *ataprint_c_cvsid="$Id: ataprint.cpp,v 1.171 2006/10/28 11:51:25 chrfranke Exp $"
const char *ataprint_c_cvsid="$Id: ataprint.cpp,v 1.183 2007/07/21 20:59:41 chrfranke Exp $"
ATACMDNAMES_H_CVSID ATACMDS_H_CVSID ATAPRINT_H_CVSID CONFIG_H_CVSID EXTERN_H_CVSID INT64_H_CVSID KNOWNDRIVES_H_CVSID SMARTCTL_H_CVSID UTILITY_H_CVSID;
// for passing global control variables
@ -91,28 +91,27 @@ void trim(char *out, const char *in)
}
// Convenience function for formatting strings from ata_identify_device
void formatdriveidstring(char *out, const char *in, int n)
void format_ata_string(char *out, const char *in, int n)
{
char tmp[65];
n = n > 64 ? 64 : n;
bool must_swap = !con->fixswappedid;
#ifndef __NetBSD__
swapbytes(tmp, in, n);
#else
/* NetBSD kernel delivers IDENTIFY data in host byte order (but all else is LE) */
if (isbigendian())
must_swap = !must_swap;
#endif
char tmp[65];
n = n > 64 ? 64 : n;
if (!must_swap)
strncpy(tmp, in, n);
else
swapbytes(tmp, in, n);
#endif
tmp[n] = '\0';
trim(out, tmp);
}
void infofound(char *output) {
if (*output)
pout("%s\n", output);
else
pout("[No Information Found]\n");
static const char * infofound(const char *output) {
return (*output ? output : "[No Information Found]");
}
@ -433,12 +432,12 @@ char *construct_st_er_desc(struct ata_smart_errorlog_struct *data) {
return s;
}
// This returns the capacity of a disk drive and also prints this into
// a string, using comma separators to make it easier to read. If the
// drive doesn't support LBA addressing or has no user writable
// sectors (eg, CDROM or DVD) then routine returns zero.
uint64_t determine_capacity(struct ata_identify_device *drive, char *pstring){
// Get number of sectors from IDENTIFY sector. If the drive doesn't
// support LBA addressing or has no user writable sectors
// (eg, CDROM or DVD) then routine returns zero.
static uint64_t get_num_sectors(const ata_identify_device *drive)
{
unsigned short command_set_2 = drive->command_set_2;
unsigned short capabilities_0 = drive->words047_079[49-47];
unsigned short sects_16 = drive->words047_079[60-47];
@ -447,46 +446,56 @@ uint64_t determine_capacity(struct ata_identify_device *drive, char *pstring){
unsigned short lba_32 = drive->words088_255[101-88];
unsigned short lba_48 = drive->words088_255[102-88];
unsigned short lba_64 = drive->words088_255[103-88];
uint64_t capacity_short=0, capacity=0, threedigits, power_of_ten;
int started=0,k=1000000000;
char *separator=",";
// LBA support?
if (!(capabilities_0 & 0x0200))
return 0; // No
// if drive supports LBA addressing, determine 32-bit LBA capacity
uint64_t lba32 = (unsigned int)sects_32 << 16 |
(unsigned int)sects_16 << 0 ;
uint64_t lba64 = 0;
// if drive supports 48-bit addressing, determine THAT capacity
if ((command_set_2 & 0xc000) == 0x4000 && (command_set_2 & 0x0400))
lba64 = (uint64_t)lba_64 << 48 |
(uint64_t)lba_48 << 32 |
(uint64_t)lba_32 << 16 |
(uint64_t)lba_16 << 0 ;
// return the larger of the two possible capacities
return (lba32 > lba64 ? lba32 : lba64);
}
// This returns the capacity of a disk drive and also prints this into
// a string, using comma separators to make it easier to read. If the
// drive doesn't support LBA addressing or has no user writable
// sectors (eg, CDROM or DVD) then routine returns zero.
uint64_t determine_capacity(struct ata_identify_device *drive, char *pstring){
// get correct character to use as thousands separator
char *separator=",";
#ifdef HAVE_LOCALE_H
struct lconv *currentlocale=NULL;
setlocale (LC_ALL, "");
currentlocale=localeconv();
if (*(currentlocale->thousands_sep))
separator=currentlocale->thousands_sep;
separator=(char *)currentlocale->thousands_sep;
#endif // #ifdef HAVE_LOCALE_H
// if drive supports LBA addressing, determine 32-bit LBA capacity
if (capabilities_0 & 0x0200) {
capacity_short = (unsigned int)sects_32 << 16 |
(unsigned int)sects_16 << 0 ;
// if drive supports 48-bit addressing, determine THAT capacity
if ((command_set_2 & 0xc000) == 0x4000 && (command_set_2 & 0x0400))
capacity = (uint64_t)lba_64 << 48 |
(uint64_t)lba_48 << 32 |
(uint64_t)lba_32 << 16 |
(uint64_t)lba_16 << 0 ;
// choose the larger of the two possible capacities
if (capacity_short>capacity)
capacity=capacity_short;
}
// turn sectors into bytes
capacity_short = (capacity *= 512);
// get #sectors and turn into bytes
uint64_t capacity = get_num_sectors(drive) * 512;
uint64_t retval = capacity;
// print with locale-specific separators (default is comma)
power_of_ten = k;
int started=0, k=1000000000;
uint64_t power_of_ten = k;
power_of_ten *= k;
for (k=0; k<7; k++) {
threedigits = capacity/power_of_ten;
capacity -= threedigits*power_of_ten;
uint64_t threedigits = capacity/power_of_ten;
capacity -= threedigits*power_of_ten;
if (started)
// we have already printed some digits
pstring += sprintf(pstring, "%s%03"PRIu64, separator, threedigits);
@ -499,7 +508,7 @@ uint64_t determine_capacity(struct ata_identify_device *drive, char *pstring){
power_of_ten /= 1000;
}
return capacity_short;
return retval;
}
int ataPrintDriveInfo (struct ata_identify_device *drive){
@ -510,9 +519,9 @@ int ataPrintDriveInfo (struct ata_identify_device *drive){
char model[64], serial[64], firm[64], capacity[64];
// format drive information (with byte swapping as needed)
formatdriveidstring(model, (char *)drive->model,40);
formatdriveidstring(serial, (char *)drive->serial_no,20);
formatdriveidstring(firm, (char *)drive->fw_rev,8);
format_ata_string(model, (char *)drive->model,40);
format_ata_string(serial, (char *)drive->serial_no,20);
format_ata_string(firm, (char *)drive->fw_rev,8);
// print out model, serial # and firmware versions (byte-swap ASCI strings)
drivetype=lookupdrive(model, firm);
@ -521,12 +530,10 @@ int ataPrintDriveInfo (struct ata_identify_device *drive){
if (drivetype>=0 && knowndrives[drivetype].modelfamily)
pout("Model Family: %s\n", knowndrives[drivetype].modelfamily);
pout("Device Model: ");
infofound(model);
pout("Serial Number: ");
infofound(serial);
pout("Firmware Version: ");
infofound(firm);
pout("Device Model: %s\n", infofound(model));
if (!con->dont_print_serial)
pout("Serial Number: %s\n", infofound(serial));
pout("Firmware Version: %s\n", infofound(firm));
if (determine_capacity(drive, capacity))
pout("User Capacity: %s bytes\n", capacity);
@ -676,11 +683,26 @@ void PrintSmartSelfExecStatus(struct ata_smart_values *data)
(int)data->self_test_exec_status);
pout("the read element of the test failed.\n");
break;
case 15:
pout("(%4d)\tSelf-test routine in progress...\n\t\t\t\t\t",
case 8:
pout("(%4d)\tThe previous self-test completed having\n\t\t\t\t\t",
(int)data->self_test_exec_status);
pout("%1d0%% of test remaining.\n",
pout("a test element that failed and the\n\t\t\t\t\t");
pout("device is suspected of having handling\n\t\t\t\t\t");
pout("damage.\n");
break;
case 15:
if (con->fixfirmwarebug == FIX_SAMSUNG3 && data->self_test_exec_status == 0xf0) {
pout("(%4d)\tThe previous self-test routine completed\n\t\t\t\t\t",
(int)data->self_test_exec_status);
pout("with unknown result or self-test in\n\t\t\t\t\t");
pout("progress with less than 10%% remaining.\n");
}
else {
pout("(%4d)\tSelf-test routine in progress...\n\t\t\t\t\t",
(int)data->self_test_exec_status);
pout("%1d0%% of test remaining.\n",
(int)(data->self_test_exec_status & 0x0f));
}
break;
default:
pout("(%4d)\tReserved.\n",
@ -887,6 +909,20 @@ void PrintSmartAttribWithThres (struct ata_smart_values *data,
if (!needheader) pout("\n");
}
// Print SMART related SCT capabilities
static void ataPrintSCTCapability(const ata_identify_device *drive)
{
unsigned short sctcaps = drive->words088_255[206-88];
if (!(sctcaps & 0x01))
return;
pout("SCT capabilities: \t (0x%04x)\tSCT Status supported.\n", sctcaps);
if (sctcaps & 0x10)
pout("\t\t\t\t\tSCT Feature Control supported.\n");
if (sctcaps & 0x20)
pout("\t\t\t\t\tSCT Data Table supported.\n");
}
void ataPrintGeneralSmartValues(struct ata_smart_values *data, struct ata_identify_device *drive){
pout("General SMART Values:\n");
@ -913,6 +949,8 @@ void ataPrintGeneralSmartValues(struct ata_smart_values *data, struct ata_identi
if (isSupportConveyanceSelfTest(data))
PrintSmartConveyanceSelfTestPollingTime (data);
ataPrintSCTCapability(drive);
pout("\n");
}
@ -1358,6 +1396,144 @@ void ataPseudoCheckSmart ( struct ata_smart_values *data,
}
// Format SCT Temperature value
static const char * sct_ptemp(signed char x, char * buf)
{
if (x == -128 /*0x80 = unknown*/)
strcpy(buf, " ?");
else
sprintf(buf, "%2d", x);
return buf;
}
static const char * sct_pbar(int x, char * buf)
{
if (x <= 19)
x = 0;
else
x -= 19;
bool ov = false;
if (x > 40) {
x = 40; ov = true;
}
if (x > 0) {
memset(buf, '*', x);
if (ov)
buf[x-1] = '+';
buf[x] = 0;
}
else {
buf[0] = '-'; buf[1] = 0;
}
return buf;
}
static const char * sct_device_state_msg(unsigned char state)
{
switch (state) {
case 0: return "Active";
case 1: return "Stand-by";
case 2: return "Sleep";
case 3: return "DST executing in background";
case 4: return "SMART Off-line Data Collection executing in background";
case 5: return "SCT command executing in background";
default:return "Unknown";
}
}
// Print SCT Status
static int ataPrintSCTStatus(const ata_sct_status_response * sts)
{
pout("SCT Status Version: %u\n", sts->format_version);
pout("SCT Version (vendor specific): %u (0x%04x)\n", sts->sct_version, sts->sct_version);
pout("SCT Support Level: %u\n", sts->sct_spec);
pout("Device State: %s (%u)\n",
sct_device_state_msg(sts->device_state), sts->device_state);
char buf1[20], buf2[20];
if ( !sts->min_temp && !sts->life_min_temp && !sts->byte205
&& !sts->under_limit_count && !sts->over_limit_count ) {
// "Reserved" fields not set, assume "old" format version 2
// Table 11 of T13/1701DT Revision 5
// Table 54 of T13/1699-D Revision 3e
pout("Current Temperature: %s Celsius\n",
sct_ptemp(sts->hda_temp, buf1));
pout("Power Cycle Max Temperature: %s Celsius\n",
sct_ptemp(sts->max_temp, buf2));
pout("Lifetime Max Temperature: %s Celsius\n",
sct_ptemp(sts->life_max_temp, buf2));
}
else {
// Assume "new" format version 2 or version 3
// T13/e06152r0-3 (Additional SCT Temperature Statistics)
// Table 60 of T13/1699-D Revision 3f
pout("Current Temperature: %s Celsius\n",
sct_ptemp(sts->hda_temp, buf1));
pout("Power Cycle Min/Max Temperature: %s/%s Celsius\n",
sct_ptemp(sts->min_temp, buf1), sct_ptemp(sts->max_temp, buf2));
pout("Lifetime Min/Max Temperature: %s/%s Celsius\n",
sct_ptemp(sts->life_min_temp, buf1), sct_ptemp(sts->life_max_temp, buf2));
if (sts->byte205) // e06152r0-2, removed in e06152r3
pout("Lifetime Average Temperature: %s Celsius\n",
sct_ptemp((signed char)sts->byte205, buf1));
pout("Under/Over Temperature Limit Count: %2u/%u\n",
sts->under_limit_count, sts->over_limit_count);
}
return 0;
}
// Print SCT Temperature History Table
static int ataPrintSCTTempHist(const ata_sct_temperature_history_table * tmh)
{
char buf1[20], buf2[80];
pout("SCT Temperature History Version: %u\n", tmh->format_version);
pout("Temperature Sampling Period: %u minute%s\n",
tmh->sampling_period, (tmh->sampling_period==1?"":"s"));
pout("Temperature Logging Interval: %u minute%s\n",
tmh->interval, (tmh->interval==1?"":"s"));
pout("Min/Max recommended Temperature: %s/%s Celsius\n",
sct_ptemp(tmh->min_op_limit, buf1), sct_ptemp(tmh->max_op_limit, buf2));
pout("Min/Max Temperature Limit: %s/%s Celsius\n",
sct_ptemp(tmh->under_limit, buf1), sct_ptemp(tmh->over_limit, buf2));
pout("Temperature History Size (Index): %u (%u)\n", tmh->cb_size, tmh->cb_index);
if (!(0 < tmh->cb_size && tmh->cb_size <= sizeof(tmh->cb) && tmh->cb_index < tmh->cb_size)) {
pout("Error invalid Temperature History Size or Index\n");
return 0;
}
// Print table
pout("\nIndex Estimated Time Temperature Celsius\n");
unsigned n = 0, i = (tmh->cb_index+1) % tmh->cb_size;
unsigned interval = (tmh->interval > 0 ? tmh->interval : 1);
time_t t = time(0) - (tmh->cb_size-1) * interval * 60;
t -= t % (interval * 60);
while (n < tmh->cb_size) {
// Find range of identical temperatures
unsigned n1 = n, n2 = n+1, i2 = (i+1) % tmh->cb_size;
while (n2 < tmh->cb_size && tmh->cb[i2] == tmh->cb[i]) {
n2++; i2 = (i2+1) % tmh->cb_size;
}
// Print range
while (n < n2) {
if (n == n1 || n == n2-1 || n2 <= n1+3) {
char date[30];
// TODO: Don't print times < boot time
strftime(date, sizeof(date), "%Y-%m-%d %H:%M", localtime(&t));
pout(" %3u %s %s %s\n", i, date,
sct_ptemp(tmh->cb[i], buf1), sct_pbar(tmh->cb[i], buf2));
}
else if (n == n1+1) {
pout(" ... ..(%3u skipped). .. %s\n",
n2-n1-2, sct_pbar(tmh->cb[i], buf2));
}
t += interval * 60; i = (i+1) % tmh->cb_size; n++;
}
}
//assert(n == tmh->cb_size && i == (tmh->cb_index+1) % tmh->cb_size);
return 0;
}
// Compares failure type to policy in effect, and either exits or
// simply returns to the calling routine.
void failuretest(int type, int returnvalue){
@ -1643,7 +1819,8 @@ int ataPrintMain (int fd){
pout("\n");
// START OF READ-ONLY OPTIONS APART FROM -V and -i
if (con->checksmart || con->generalsmartvalues || con->smartvendorattrib || con->smarterrorlog || con->smartselftestlog)
if ( con->checksmart || con->generalsmartvalues || con->smartvendorattrib || con->smarterrorlog
|| con->smartselftestlog || con->selectivetestlog || con->scttempsts || con->scttemphist )
pout("=== START OF READ SMART DATA SECTION ===\n");
// Check SMART status (use previously returned value)
@ -1816,6 +1993,60 @@ int ataPrintMain (int fd){
}
}
// Print SMART SCT status and temperature history table
if (con->scttempsts || con->scttemphist || con->scttempint) {
for (;;) {
if (!isSCTCapable(&drive)) {
pout("Warning: device does not support SCT Commands\n");
failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
break;
}
if (con->scttempsts || con->scttemphist) {
ata_sct_status_response sts;
ata_sct_temperature_history_table tmh;
if (!con->scttemphist) {
// Read SCT status only
if (ataReadSCTStatus(fd, &sts)) {
failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
break;
}
}
else {
if (!isSCTDataTableCapable(&drive)) {
pout("Warning: device does not support SCT Data Table command\n");
failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
break;
}
// Read SCT status and temperature history
if (ataReadSCTTempHist(fd, &tmh, &sts)) {
failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
break;
}
}
if (con->scttempsts)
ataPrintSCTStatus(&sts);
if (con->scttemphist)
ataPrintSCTTempHist(&tmh);
pout("\n");
}
if (con->scttempint) {
// Set new temperature logging interval
if (!isSCTFeatureControlCapable(&drive)) {
pout("Warning: device does not support SCT Feature Control command\n");
failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
break;
}
if (ataSetSCTTempInterval(fd, con->scttempint, !!con->scttempintp)) {
failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
break;
}
pout("Temperature Logging Interval set to %u minute%s (%s)\n",
con->scttempint, (con->scttempint==1?"":"s"), (con->scttempintp?"persistent":"volatile"));
}
break;
}
}
// START OF THE TESTING SECTION OF THE CODE. IF NO TESTING, RETURN
if (con->testcase==-1)
return returnval;
@ -1861,7 +2092,7 @@ int ataPrintMain (int fd){
// Now do the test. Note ataSmartTest prints its own error/success
// messages
if (ataSmartTest(fd, con->testcase, &smartval))
if (ataSmartTest(fd, con->testcase, &smartval, get_num_sectors(&drive)))
failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
else {
// Tell user how long test will take to complete. This is tricky

View File

@ -25,7 +25,7 @@
#ifndef ATAPRINT_H_
#define ATAPRINT_H_
#define ATAPRINT_H_CVSID "$Id: ataprint.h,v 1.29 2006/09/17 10:12:51 shattered Exp $\n"
#define ATAPRINT_H_CVSID "$Id: ataprint.h,v 1.30 2007/04/05 18:23:29 shattered Exp $\n"
#include <stdio.h>
#include <stdlib.h>
@ -54,7 +54,7 @@ int ataPrintSmartSelfTestlog(struct ata_smart_selftestlog *, int allentries);
void ataPseudoCheckSmart(struct ata_smart_values *, struct ata_smart_thresholds_pvt *);
// Convenience function for formatting strings from ata_identify_device.
void formatdriveidstring(char *out, const char *in, int n);
void format_ata_string(char *out, const char *in, int n);
int ataPrintMain(int fd);

View File

@ -1,9 +1,9 @@
#!/bin/sh
# $Id: autogen.sh,v 1.13 2005/09/19 09:28:11 chrfranke Exp $
# $Id: autogen.sh,v 1.14 2007/01/29 21:24:18 chrfranke Exp $
#
# Generate ./configure from config.in and Makefile.in from Makefile.am.
# This also adds files like missing,depcomp,install-sh to the source
# direcory. To update these files at a later date use:
# directory. To update these files at a later date use:
# autoreconf -f -i -v
@ -36,7 +36,8 @@ typep()
return 1
}
test -x "$AUTOMAKE" || AUTOMAKE=`typep automake-1.9` || AUTOMAKE=`typep automake-1.8` || AUTOMAKE=`typep automake-1.7` || AUTOMAKE=`typep automake17` ||
test -x "$AUTOMAKE" || AUTOMAKE=`typep automake-1.10` || AUTOMAKE=`typep automake-1.9` ||
AUTOMAKE=`typep automake-1.8` || AUTOMAKE=`typep automake-1.7` || AUTOMAKE=`typep automake17` ||
{
echo
echo "You must have at least GNU Automake 1.7 (up to 1.9.x) installed"
@ -70,7 +71,7 @@ case "$AUTOMAKE" in
ver="`$AUTOMAKE --version | head -1 | sed -n 's,^.*\([12]\.[.0-9]*[-pl0-9]*\).*$,\1,p'`"
ver="${ver:-?.?.?}"
case "$ver" in
1.[78]*|1.9.[1-6]) ver= ;;
1.[78]*|1.9.[1-6]|1.10) ver= ;;
esac ;;
esac

237
cciss.cpp Normal file
View File

@ -0,0 +1,237 @@
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include "config.h"
#if defined(linux)
# include <sys/ioctl.h>
# ifdef HAVE_LINUX_COMPILER_H
# include <linux/compiler.h>
# endif
# if defined(HAVE_LINUX_CCISS_IOCTL_H)
# include <linux/cciss_ioctl.h>
# define _HAVE_CCISS
# endif
# include <asm/byteorder.h>
# define be32toh __be32_to_cpu
#elif defined(__FreeBSD__) && defined(HAVE_DEV_CISS_CISSIO_H)
# include <sys/endian.h>
# include <dev/ciss/cissio.h>
# define _HAVE_CCISS
#endif
#ifdef _HAVE_CCISS
#include "int64.h"
#include "scsicmds.h"
#include "utility.h"
typedef struct _ReportLUNdata_struct
{
uint32_t LUNListLength; /* always big-endian */
uint32_t reserved;
uint8_t LUN[CISS_MAX_LUN][8];
} ReportLunData_struct;
/* Structure/defines of Report Physical LUNS of drive */
#ifndef CISS_MAX_LUN
#define CISS_MAX_LUN 16
#endif
#define CISS_MAX_PHYS_LUN 1024
#define CISS_REPORT_PHYS 0xc3
#define LSCSI_DRIVER_SENSE 0x8 /* alternate CHECK CONDITION indication */
#define SEND_IOCTL_RESP_SENSE_LEN 16 /* ioctl limitation */
static int cciss_getlun(int device, int target, unsigned char *physlun, int report);
static int cciss_sendpassthru(unsigned int cmdtype, unsigned char *CDB,
unsigned int CDBlen, char *buff,
unsigned int size, unsigned int LunID,
unsigned char *scsi3addr, int fd);
/*
This is an interface that uses the cciss passthrough to talk to the SMART controller on
the HP system. The cciss driver provides a way to send SCSI cmds through the CCISS passthrough.
*/
int cciss_io_interface(int device, int target, struct scsi_cmnd_io * iop, int report)
{
unsigned char pBuf[512] = {0};
unsigned char phylun[8] = {0};
int iBufLen = 512;
int status = -1;
int len = 0; // used later in the code.
status = cciss_getlun(device, target, phylun, report);
if (report > 0)
printf(" cciss_getlun(%d, %d) = 0x%x; scsi3addr: %02x %02x %02x %02x %02x %02x %02x %02x\n",
device, target, status,
phylun[0], phylun[1], phylun[2], phylun[3], phylun[4], phylun[5], phylun[6], phylun[7]);
if (status) {
return -ENXIO; /* give up, assume no device there */
}
status = cciss_sendpassthru( 2, iop->cmnd, iop->cmnd_len, (char*) pBuf, iBufLen, 1, phylun, device);
if (0 == status)
{
if (report > 0)
printf(" status=0\n");
if (DXFER_FROM_DEVICE == iop->dxfer_dir)
{
memcpy(iop->dxferp, pBuf, iop->dxfer_len);
if (report > 1)
{
int trunc = (iop->dxfer_len > 256) ? 1 : 0;
printf(" Incoming data, len=%d%s:\n", (int)iop->dxfer_len,
(trunc ? " [only first 256 bytes shown]" : ""));
dStrHex((const char*)iop->dxferp, (trunc ? 256 : iop->dxfer_len) , 1);
}
}
return 0;
}
iop->scsi_status = status & 0x7e; /* bits 0 and 7 used to be for vendors */
if (LSCSI_DRIVER_SENSE == ((status >> 24) & 0xf))
iop->scsi_status = SCSI_STATUS_CHECK_CONDITION;
len = (SEND_IOCTL_RESP_SENSE_LEN < iop->max_sense_len) ?
SEND_IOCTL_RESP_SENSE_LEN : iop->max_sense_len;
if ((SCSI_STATUS_CHECK_CONDITION == iop->scsi_status) &&
iop->sensep && (len > 0))
{
memcpy(iop->sensep, pBuf, len);
iop->resp_sense_len = iBufLen;
if (report > 1)
{
printf(" >>> Sense buffer, len=%d:\n", (int)len);
dStrHex((const char *)pBuf, len , 1);
}
}
if (report)
{
if (SCSI_STATUS_CHECK_CONDITION == iop->scsi_status) {
printf(" status=%x: sense_key=%x asc=%x ascq=%x\n", status & 0xff,
pBuf[2] & 0xf, pBuf[12], pBuf[13]);
}
else
printf(" status=0x%x\n", status);
}
if (iop->scsi_status > 0)
return 0;
else
{
if (report > 0)
printf(" ioctl status=0x%x but scsi status=0, fail with ENXIO\n", status);
return -ENXIO; /* give up, assume no device there */
}
}
static int cciss_sendpassthru(unsigned int cmdtype, unsigned char *CDB,
unsigned int CDBlen, char *buff,
unsigned int size, unsigned int LunID,
unsigned char *scsi3addr, int fd)
{
int err ;
IOCTL_Command_struct iocommand;
memset(&iocommand, 0, sizeof(iocommand));
if (cmdtype == 0)
{
// To controller; nothing to do
}
else if (cmdtype == 1)
{
iocommand.LUN_info.LogDev.VolId = LunID;
iocommand.LUN_info.LogDev.Mode = 1;
}
else if (cmdtype == 2)
{
memcpy(&iocommand.LUN_info.LunAddrBytes,scsi3addr,8);
iocommand.LUN_info.LogDev.Mode = 0;
}
else
{
fprintf(stderr, "cciss_sendpassthru: bad cmdtype\n");
return 1;
}
memcpy(&iocommand.Request.CDB[0], CDB, CDBlen);
iocommand.Request.CDBLen = CDBlen;
iocommand.Request.Type.Type = TYPE_CMD;
iocommand.Request.Type.Attribute = ATTR_SIMPLE;
iocommand.Request.Type.Direction = XFER_READ;
iocommand.Request.Timeout = 0;
iocommand.buf_size = size;
iocommand.buf = (unsigned char *)buff;
if ((err = ioctl(fd, CCISS_PASSTHRU, &iocommand)))
{
fprintf(stderr, "CCISS ioctl error %d (fd %d CDBLen %d buf_size %d)\n",
fd, err, CDBlen, size);
}
return err;
}
static int cciss_getlun(int device, int target, unsigned char *physlun, int report)
{
unsigned char CDB[16]= {0};
ReportLunData_struct *luns;
int reportlunsize = sizeof(*luns) + CISS_MAX_PHYS_LUN * 8;
int i;
int ret;
luns = (ReportLunData_struct *)malloc(reportlunsize);
memset(luns, 0, reportlunsize);
/* Get Physical LUN Info (for physical device) */
CDB[0] = CISS_REPORT_PHYS;
CDB[6] = (reportlunsize >> 24) & 0xFF; /* MSB */
CDB[7] = (reportlunsize >> 16) & 0xFF;
CDB[8] = (reportlunsize >> 8) & 0xFF;
CDB[9] = reportlunsize & 0xFF;
if ((ret = cciss_sendpassthru(0, CDB, 12, (char *)luns, reportlunsize, 0, NULL, device)))
{
free(luns);
return ret;
}
if (report > 1)
{
unsigned int i,j;
unsigned char *stuff = (unsigned char *)luns;
pout("\n===== [%s] DATA START (BASE-16) =====\n", "LUN DATA");
for (i=0; i<(sizeof(_ReportLUNdata_struct)+15)/16; i++){
pout("%03d-%03d: ", 16*i, 16*(i+1)-1);
for (j=0; j<15; j++)
pout("%02x ",*stuff++);
pout("%02x\n",*stuff++);
}
pout("===== [%s] DATA END (%d Bytes) =====\n\n", "LUN DATA", sizeof(_ReportLUNdata_struct));
}
#if 0
for (i=0; i<CISS_MAX_LUN; i++)
{
if (luns->LUN[i][6] == target)
{
memcpy(physlun, luns->LUN[i], 8);
free(luns);
return 0;
}
}
#else
if (target >= 0 && target < (int) be32toh(luns->LUNListLength) / 8)
{
memcpy(physlun, luns->LUN[target], 8);
free(luns);
return 0;
}
#endif
free(luns);
return 1;
}
#endif

9
cciss.h Normal file
View File

@ -0,0 +1,9 @@
#ifndef CCISS_H_
#define CCISS_H_
#define CCISS_H_CVSID "$Id: cciss.h,v 1.1 2007/04/01 16:49:46 shattered Exp $\n"
int cciss_io_interface(int device, int target,
struct scsi_cmnd_io * iop, int report);
#endif /* CCISS_H_ */

1463
config.guess vendored

File diff suppressed because it is too large Load Diff

View File

@ -42,9 +42,6 @@
/* Define to 1 if you have the <inttypes.h> header file. */
#undef HAVE_INTTYPES_H
/* Define to 1 if you have the <linux/compiler.h> header file. */
#undef HAVE_LINUX_COMPILER_H
/* Define to 1 if you have the <locale.h> header file. */
#undef HAVE_LOCALE_H

1579
config.sub vendored

File diff suppressed because it is too large Load Diff

9971
configure vendored

File diff suppressed because it is too large Load Diff

View File

@ -1,13 +1,13 @@
#
# $Id: configure.in,v 1.122 2006/12/20 20:39:25 chrfranke Exp $
# $Id: configure.in,v 1.127 2007/11/13 14:53:27 jhering Exp $
#
dnl Process this file with autoconf to produce a configure script.
AC_PREREQ(2.50)
AC_INIT(smartmontools, 5.37, smartmontools-support@lists.sourceforge.net)
AC_INIT(smartmontools, 5.38, smartmontools-support@lists.sourceforge.net)
AC_CONFIG_SRCDIR(smartctl.cpp)
smartmontools_configure_date=`date -u +"%Y/%m/%d %T %Z"`
smartmontools_cvs_tag=`echo '$Id: configure.in,v 1.122 2006/12/20 20:39:25 chrfranke Exp $'`
smartmontools_cvs_tag=`echo '$Id: configure.in,v 1.127 2007/11/13 14:53:27 jhering Exp $'`
smartmontools_release_date=2006/12/20
smartmontools_release_time="20:37:59 UTC"
@ -37,6 +37,10 @@ case "${host}" in
CPPFLAGS="$CPPFLAGS -mno-cygwin"
LDFLAGS="$LDFLAGS -mno-cygwin"
CPPFLAGS="$CPPFLAGS -idirafter ${srcdir}/posix -idirafter ${srcdir}/os_win32"
;;
*-*-freebsd*)
CPPFLAGS="$CPPFLAGS -I/usr/src/sys"
;;
esac
dnl Checks for libraries.needed for gethostbyname (Solaris needs
@ -59,6 +63,10 @@ AC_CHECK_HEADERS([sys/tweio.h])
AC_CHECK_HEADERS([sys/twereg.h])
dnl Check for FreeBSD twa include files...
AC_CHECK_HEADERS([sys/tw_osl_ioctl.h])
dnl Check for FreeBSD ciss include files...
AC_CHECK_HEADERS([dev/ciss/cissio.h])
dnl Check for Linux CCISS include file
AC_CHECK_HEADERS([linux/cciss_ioctl.h])
dnl This header file needed at least for SuSE LINUX
AC_CHECK_HEADERS([linux/compiler.h])
@ -129,14 +137,11 @@ AC_SUBST(smartmontools_release_time)
dnl if OS not recognized, then use the os_generic modules
case "${host}" in
*-*-linux-gnu*)
AC_SUBST([os_deps], ['os_linux.o'])
AC_SUBST([os_libs], ['']) ;;
*-*-linux*)
AC_SUBST([os_deps], ['os_linux.o'])
AC_SUBST([os_deps], ['os_linux.o cciss.o'])
AC_SUBST([os_libs], ['']) ;;
*-*-freebsd*)
AC_SUBST([os_deps], ['os_freebsd.o'])
AC_SUBST([os_deps], ['os_freebsd.o cciss.o'])
AC_SUBST([os_libs], ['-lcam']);;
sparc-*-solaris*)
AC_DEFINE_UNQUOTED(DEFAULT_MAILER, "mailx", [use mailx as default mailer])
@ -162,6 +167,10 @@ case "${host}" in
*-*-darwin*)
AC_SUBST([os_deps], ['os_darwin.o'])
AC_SUBST([os_libs], ['-framework CoreFoundation -framework IOKit']) ;;
*-*-nto-qnx*)
AC_SUBST([os_deps], ['os_qnxnto.o'])
AC_SUBST([os_libs], ['']) ;;
*)
AC_SUBST([os_deps], ['os_generic.o'])
AC_SUBST([os_libs], ['']) ;;

530
depcomp
View File

@ -1,530 +0,0 @@
#! /bin/sh
# depcomp - compile a program generating dependencies as side-effects
scriptversion=2005-07-09.11
# Copyright (C) 1999, 2000, 2003, 2004, 2005 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, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
# 02110-1301, USA.
# 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 <oliva@dcc.unicamp.br>.
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 outputing dependencies.
libtool Whether libtool is used (yes/no).
Report bugs to <bug-automake@gnu.org>.
EOF
exit $?
;;
-v | --v*)
echo "depcomp $scriptversion"
exit $?
;;
esac
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"
# 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
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.
"$@" -MT "$object" -MD -MP -MF "$tmpdepfile"
stat=$?
if test $stat -eq 0; then :
else
rm -f "$tmpdepfile"
exit $stat
fi
mv "$tmpdepfile" "$depfile"
;;
gcc)
## 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).
## - 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 -eq 0; then :
else
rm -f "$tmpdepfile"
exit $stat
fi
rm -f "$depfile"
echo "$object : \\" > "$depfile"
alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
## 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.
tr ' ' '
' < "$tmpdepfile" |
## 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.
## Some versions of the HPUX 10.20 sed can't process this invocation
## correctly. Breaking it into two sed invocations is a workaround.
sed -e 's/^\\$//' -e '/^$/d' -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 -eq 0; then :
else
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 ' ' '
' < "$tmpdepfile" \
| sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \
tr '
' ' ' >> $depfile
echo >> $depfile
# The second pass generates a dummy entry for each header file.
tr ' ' '
' < "$tmpdepfile" \
| sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \
>> $depfile
else
# The sourcefile does not contain any dependencies, so just
# store a dummy comment line, to avoid errors with the Makefile
# "include basename.Plo" scheme.
echo "#dummy" > "$depfile"
fi
rm -f "$tmpdepfile"
;;
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.
stripped=`echo "$object" | sed 's/\(.*\)\..*$/\1/'`
tmpdepfile="$stripped.u"
if test "$libtool" = yes; then
"$@" -Wc,-M
else
"$@" -M
fi
stat=$?
if test -f "$tmpdepfile"; then :
else
stripped=`echo "$stripped" | sed 's,^.*/,,'`
tmpdepfile="$stripped.u"
fi
if test $stat -eq 0; then :
else
rm -f "$tmpdepfile"
exit $stat
fi
if test -f "$tmpdepfile"; then
outname="$stripped.o"
# Each line is of the form `foo.o: dependent.h'.
# Do two passes, one to just change these to
# `$object: dependent.h' and one to simply `dependent.h:'.
sed -e "s,^$outname:,$object :," < "$tmpdepfile" > "$depfile"
sed -e "s,^$outname: \(.*\)$,\1:," < "$tmpdepfile" >> "$depfile"
else
# The sourcefile does not contain any dependencies, so just
# store a dummy comment line, to avoid errors with the Makefile
# "include basename.Plo" scheme.
echo "#dummy" > "$depfile"
fi
rm -f "$tmpdepfile"
;;
icc)
# Intel's C compiler understands `-MD -MF file'. However on
# icc -MD -MF foo.d -c -o sub/foo.o sub/foo.c
# ICC 7.0 will fill foo.d with something like
# foo.o: sub/foo.c
# foo.o: sub/foo.h
# which is wrong. We want:
# sub/foo.o: sub/foo.c
# sub/foo.o: sub/foo.h
# sub/foo.c:
# sub/foo.h:
# ICC 7.1 will output
# foo.o: sub/foo.c sub/foo.h
# and will wrap long lines using \ :
# foo.o: sub/foo.c ... \
# sub/foo.h ... \
# ...
"$@" -MD -MF "$tmpdepfile"
stat=$?
if test $stat -eq 0; then :
else
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"
;;
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.
dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
test "x$dir" = "x$object" && dir=
base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
if test "$libtool" = yes; then
# With Tru64 cc, shared objects can also be used to make a
# static library. This mecanism is used in libtool 1.4 series to
# handle both shared and static libraries in a single compilation.
# With libtool 1.4, dependencies were output in $dir.libs/$base.lo.d.
#
# With libtool 1.5 this exception was removed, and libtool now
# generates 2 separate objects for the 2 libraries. These two
# compilations output dependencies in 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.libs/$base.lo.d # libtool 1.4
tmpdepfile2=$dir$base.o.d # libtool 1.5
tmpdepfile3=$dir.libs/$base.o.d # libtool 1.5
tmpdepfile4=$dir.libs/$base.d # Compaq CCC V6.2-504
"$@" -Wc,-MD
else
tmpdepfile1=$dir$base.o.d
tmpdepfile2=$dir$base.d
tmpdepfile3=$dir$base.d
tmpdepfile4=$dir$base.d
"$@" -MD
fi
stat=$?
if test $stat -eq 0; then :
else
rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4"
exit $stat
fi
for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4"
do
test -f "$tmpdepfile" && break
done
if test -f "$tmpdepfile"; then
sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile"
# That's a tab and a space in the [].
sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile"
else
echo "#dummy" > "$depfile"
fi
rm -f "$tmpdepfile"
;;
#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 $1 != '--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:^[ ]*[^: ][^:][^:]*\:[ ]*:'"$object"'\: :' > "$tmpdepfile"
rm -f "$depfile"
cat < "$tmpdepfile" > "$depfile"
tr ' ' '
' < "$tmpdepfile" | \
## Some versions of the HPUX 10.20 sed can't process this invocation
## correctly. Breaking it into two sed invocations is a workaround.
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 $1 != '--mode=compile'; do
shift
done
shift
fi
# X makedepend
shift
cleared=no
for arg in "$@"; do
case $cleared in
no)
set ""; shift
cleared=yes ;;
esac
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.
-*|$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"
cat < "$tmpdepfile" > "$depfile"
sed '1,2d' "$tmpdepfile" | tr ' ' '
' | \
## Some versions of the HPUX 10.20 sed can't process this invocation
## correctly. Breaking it into two sed invocations is a workaround.
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 $1 != '--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, regardless of -o,
# because we must use -o when running libtool.
"$@" || exit $?
IFS=" "
for arg
do
case "$arg" in
"-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI")
set fnord "$@"
shift
shift
;;
*)
set fnord "$@" "$arg"
shift
shift
;;
esac
done
"$@" -E |
sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::echo "`cygpath -u \\"\1\\"`":p' | sort | uniq > "$tmpdepfile"
rm -f "$depfile"
echo "$object : \\" > "$depfile"
. "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s:: \1 \\:p' >> "$depfile"
echo " " >> "$depfile"
. "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s::\1\::p' >> "$depfile"
rm -f "$tmpdepfile"
;;
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-end: "$"
# End:

98
do_release Executable file
View File

@ -0,0 +1,98 @@
#!/bin/bash -ev
#
# do a smartmontools release
# (C) 2003-6 Bruce Allen <ballen4705@users.sourceforge.net>,
# Guido Guenther <agx@sigxcpu.org>
# $Id: do_release,v 1.40 2006/12/19 19:25:42 chrfranke Exp $
# Notes on generating releases:
# (1) update NEWS
# (2) update CHANGELOG -- put in release number
# (3) update release number in configure.in and smartmontools.spec
# (4) update internal changelog in smartmontools.spec
# (5) to test, set USECVS below to 0
# (6) when satisfied, set USECVS below to 1
USECVS=1
KEYID=0x841ABAE8
setup_cvs()
{
CVS_SERVER=fakevalue
unset CVS_SERVER || echo "can't unset CVS_SERVER=$CVS_SERVER"
CVS_RSH=ssh
CVSROOT=:ext:ballen4705@smartmontools.cvs.sourceforge.net:/cvsroot/smartmontools
}
get_release()
{
VERSION=`grep 'AC_INIT' configure.in | awk '{ print $2 }' | sed s/,//g`
RELEASE="RELEASE_${VERSION//\./_}"
echo "Version: $VERSION"
echo "Release: $RELEASE"
}
inc_release()
{
MINOR=`echo $VERSION | cut -d. -f2`
MAJOR=`echo $VERSION | cut -d. -f1`
PERL_OLD=$MAJOR\\.$MINOR
((MINOR++))
NEW_VERSION=$MAJOR.$MINOR
PERL_NEW=$MAJOR\\.$MINOR
NEW_RELEASE="RELEASE_${NEW_VERSION//\./_}"
echo "New Version: $NEW_VERSION"
echo "New Release: $NEW_RELEASE"
}
# run automake/autoconf
if [ -f Makefile ] ; then
make distcheck || exit 1
make clean
make distclean
rm -f Makefile configure
fi
smartmontools_release_date=`date -u +"%Y/%m/%d"`
smartmontools_release_time=`date -u +"%T %Z"`
cat configure.in | sed "s|smartmontools_release_date=.*|smartmontools_release_date=${smartmontools_release_date}|" > configure.tmp
cat configure.tmp | sed "s|smartmontools_release_time=.*|smartmontools_release_time=\"${smartmontools_release_time}\"|" > configure.in
rm -f configure.tmp
./autogen.sh
get_release
# tag CVS version
if [ $USECVS -ne 0 ] ; then
setup_cvs
cvs commit -m "Release $VERSION $RELEASE"
cvs tag -d $RELEASE
cvs tag $RELEASE
fi
# build .tar.gz
rm -rf build
mkdir build
cd build
../configure
make distcheck || exit 1
cd ..
# increase release number:
inc_release
if [ $USECVS -ne 0 ] ; then
perl -p -i.bak -e "s/$PERL_OLD/$PERL_NEW/" configure.in
perl -p -i.bak -e "s/Version:\t$PERL_OLD/Version:\t$PERL_NEW/" smartmontools.spec
fi
cp -f build/smartmontools-$VERSION.tar.gz .
if [ "$KEYID" ]; then
gpg --default-key $KEYID --armor --detach-sign ./smartmontools-$VERSION.tar.gz
fi
# cleanup
rm -rf autom4te.cache build/ config.h.in Makefile.in examplescripts/Makefile.in \
depcomp mkinstalldirs install-sh configure config.guess config.sub \
aclocal.m4 missing *.bak

View File

@ -0,0 +1,2 @@
Makefile
Makefile.in

View File

@ -37,7 +37,6 @@ PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
LIBOBJDIR =
subdir = examplescripts
DIST_COMMON = README $(srcdir)/Makefile.am $(srcdir)/Makefile.in
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4

View File

@ -3,7 +3,7 @@
*
* Home page of code is: http://smartmontools.sourceforge.net
*
* Copyright (C) 2002-6 Bruce Allen <smartmontools-support@lists.sourceforge.net>
* Copyright (C) 2002-7 Bruce Allen <smartmontools-support@lists.sourceforge.net>
* Copyright (C) 1999-2000 Michael Cornwell <cornwell@acm.org>
*
* This program is free software; you can redistribute it and/or modify
@ -25,14 +25,15 @@
#ifndef EXTERN_H_
#define EXTERN_H_
#define EXTERN_H_CVSID "$Id: extern.h,v 1.47 2006/09/15 08:03:52 sxzzsf Exp $\n"
#define EXTERN_H_CVSID "$Id: extern.h,v 1.53 2007/07/21 20:59:41 chrfranke Exp $\n"
// Possible values for fixfirmwarebug. If use has NOT specified -F at
// Possible values for fixfirmwarebug. If user has NOT specified -F at
// all, then value is 0.
#define FIX_NOTSPECIFIED 0
#define FIX_NONE 1
#define FIX_SAMSUNG 2
#define FIX_SAMSUNG2 3
#define FIX_SAMSUNG3 4
// Block used for global control/communications. If you need more
// global variables, this should be the only place that you need to
@ -40,9 +41,12 @@
typedef struct smartmonctrl_s {
// spans for selective self-test
uint64_t smartselectivespan[5][2];
// mode for each span, see SEL_* in utility.h
char smartselectivemode[5];
// number of spans
int smartselectivenumspans;
int testcase;
unsigned scttempint;
// one plus time in minutes to wait after powerup before restarting
// interrupted offline scan after selective self-test.
int pendingtime;
@ -61,6 +65,9 @@ typedef struct smartmonctrl_s {
unsigned char selectivetestlog;
unsigned char smarterrorlog;
unsigned char smartbackgroundlog;
unsigned char scttempsts;
unsigned char scttemphist;
unsigned char scttempintp;
unsigned char smartdisable;
unsigned char smartenable;
unsigned char smartstatus;
@ -80,6 +87,7 @@ typedef struct smartmonctrl_s {
unsigned char smartautosavedisable;
unsigned char printing_switchable;
unsigned char dont_print;
unsigned char dont_print_serial;
unsigned char permissive;
unsigned char conservative;
unsigned char checksumfail;
@ -87,6 +95,7 @@ typedef struct smartmonctrl_s {
unsigned char reportataioctl;
unsigned char reportscsiioctl;
unsigned char fixfirmwarebug;
unsigned char fixswappedid;
unsigned char satpassthrulen;
// Controller type (device type) has been specified explicitly
unsigned char controller_explicit;

View File

@ -1,323 +0,0 @@
#!/bin/sh
# install - install a program, script, or datafile
scriptversion=2005-05-14.22
# 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. It can only install one file at a time, a restriction
# shared with many OS's install programs.
# set DOITPROG to echo to test this script
# Don't use :- since 4.3BSD and earlier shells don't like it.
doit="${DOITPROG-}"
# put in absolute paths if you don't have them in your path; or use env. vars.
mvprog="${MVPROG-mv}"
cpprog="${CPPROG-cp}"
chmodprog="${CHMODPROG-chmod}"
chownprog="${CHOWNPROG-chown}"
chgrpprog="${CHGRPPROG-chgrp}"
stripprog="${STRIPPROG-strip}"
rmprog="${RMPROG-rm}"
mkdirprog="${MKDIRPROG-mkdir}"
chmodcmd="$chmodprog 0755"
chowncmd=
chgrpcmd=
stripcmd=
rmcmd="$rmprog -f"
mvcmd="$mvprog"
src=
dst=
dir_arg=
dstarg=
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:
-c (ignored)
-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.
--help display this help and exit.
--version display version info and exit.
Environment variables override the default commands:
CHGRPPROG CHMODPROG CHOWNPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG
"
while test -n "$1"; do
case $1 in
-c) shift
continue;;
-d) dir_arg=true
shift
continue;;
-g) chgrpcmd="$chgrpprog $2"
shift
shift
continue;;
--help) echo "$usage"; exit $?;;
-m) chmodcmd="$chmodprog $2"
shift
shift
continue;;
-o) chowncmd="$chownprog $2"
shift
shift
continue;;
-s) stripcmd=$stripprog
shift
continue;;
-t) dstarg=$2
shift
shift
continue;;
-T) no_target_directory=true
shift
continue;;
--version) echo "$0 $scriptversion"; exit $?;;
*) # When -d is used, all remaining arguments are directories to create.
# When -t is used, the destination is already specified.
test -n "$dir_arg$dstarg" && break
# Otherwise, the last argument is the destination. Remove it from $@.
for arg
do
if test -n "$dstarg"; then
# $@ is not empty: it contains at least $arg.
set fnord "$@" "$dstarg"
shift # fnord
fi
shift # arg
dstarg=$arg
done
break;;
esac
done
if test -z "$1"; 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
for src
do
# Protect names starting with `-'.
case $src in
-*) src=./$src ;;
esac
if test -n "$dir_arg"; then
dst=$src
src=
if test -d "$dst"; then
mkdircmd=:
chmodcmd=
else
mkdircmd=$mkdirprog
fi
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 "$dstarg"; then
echo "$0: no destination specified." >&2
exit 1
fi
dst=$dstarg
# Protect names starting with `-'.
case $dst in
-*) dst=./$dst ;;
esac
# 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: $dstarg: Is a directory" >&2
exit 1
fi
dst=$dst/`basename "$src"`
fi
fi
# This sed command emulates the dirname command.
dstdir=`echo "$dst" | sed -e 's,/*$,,;s,[^/]*$,,;s,/*$,,;s,^$,.,'`
# Make sure that the destination directory exists.
# Skip lots of stat calls in the usual case.
if test ! -d "$dstdir"; then
defaultIFS='
'
IFS="${IFS-$defaultIFS}"
oIFS=$IFS
# Some sh's can't handle IFS=/ for some reason.
IFS='%'
set x `echo "$dstdir" | sed -e 's@/@%@g' -e 's@^%@/@'`
shift
IFS=$oIFS
pathcomp=
while test $# -ne 0 ; do
pathcomp=$pathcomp$1
shift
if test ! -d "$pathcomp"; then
$mkdirprog "$pathcomp"
# mkdir can fail with a `File exist' error in case several
# install-sh are creating the directory concurrently. This
# is OK.
test -d "$pathcomp" || exit
fi
pathcomp=$pathcomp/
done
fi
if test -n "$dir_arg"; then
$doit $mkdircmd "$dst" \
&& { test -z "$chowncmd" || $doit $chowncmd "$dst"; } \
&& { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } \
&& { test -z "$stripcmd" || $doit $stripcmd "$dst"; } \
&& { test -z "$chmodcmd" || $doit $chmodcmd "$dst"; }
else
dstfile=`basename "$dst"`
# 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
trap '(exit $?); exit' 1 2 13 15
# Copy the file name to the temp name.
$doit $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 "$dsttmp"; } &&
# Now rename the file to the real destination.
{ $doit $mvcmd -f "$dsttmp" "$dstdir/$dstfile" 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.
{
if test -f "$dstdir/$dstfile"; then
$doit $rmcmd -f "$dstdir/$dstfile" 2>/dev/null \
|| $doit $mvcmd -f "$dstdir/$dstfile" "$rmtmp" 2>/dev/null \
|| {
echo "$0: cannot unlink or rename $dstdir/$dstfile" >&2
(exit 1); exit 1
}
else
:
fi
} &&
# Now rename the file to the real destination.
$doit $mvcmd "$dsttmp" "$dstdir/$dstfile"
}
}
fi || { (exit 1); exit 1; }
done
# The final little trick to "correctly" pass the exit status to the exit trap.
{
(exit 0); exit 0
}
# Local variables:
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-end: "$"
# End:

View File

@ -4,7 +4,7 @@
* Home page of code is: http://smartmontools.sourceforge.net
* Address of support mailing list: smartmontools-support@lists.sourceforge.net
*
* Copyright (C) 2003-6 Philip Williams, Bruce Allen
* Copyright (C) 2003-7 Philip Williams, Bruce Allen
*
* 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
@ -26,7 +26,7 @@
#include "knowndrives.h"
#include "utility.h" // includes <regex.h>
const char *knowndrives_c_cvsid="$Id: knowndrives.cpp,v 1.156 2006/10/30 22:35:28 pjwilliams Exp $"
const char *knowndrives_c_cvsid="$Id: knowndrives.cpp,v 1.162 2007/11/05 00:29:11 geoffk1 Exp $"
ATACMDS_H_CVSID ATAPRINT_H_CVSID CONFIG_H_CVSID EXTERN_H_CVSID INT64_H_CVSID KNOWNDRIVES_H_CVSID UTILITY_H_CVSID;
#define MODEL_STRING_LENGTH 40
@ -111,11 +111,13 @@ const unsigned char vendoropts_Hitachi_DK23XX[][2] = {
const char same_as_minus_F[]="Fixes byte order in some SMART data (same as -F samsung)";
const char same_as_minus_F2[]="Fixes byte order in some SMART data (same as -F samsung2)";
const char same_as_minus_F3[]="Fixes completed self-test reported as in progress (same as -F samsung3)";
const char may_need_minus_F_disabled[] ="May need -F samsung disabled; see manual for details.";
const char may_need_minus_F2_disabled[]="May need -F samsung2 disabled; see manual for details.";
const char may_need_minus_F2_enabled[] ="May need -F samsung2 enabled; see manual for details.";
const char may_need_minus_F_enabled[] ="May need -F samsung or -F samsung2 enabled; see manual for details.";
const char may_need_minus_F3_enabled[] ="May need -F samsung3 enabled; see manual for details.";
/* Special-purpose functions for use in knowndrives[]. */
void specialpurpose_reverse_samsung(smartmonctrl *con)
@ -128,6 +130,11 @@ void specialpurpose_reverse_samsung2(smartmonctrl *con)
if (con->fixfirmwarebug==FIX_NOTSPECIFIED)
con->fixfirmwarebug = FIX_SAMSUNG2;
}
void specialpurpose_fix_samsung3(smartmonctrl *con)
{
if (con->fixfirmwarebug==FIX_NOTSPECIFIED)
con->fixfirmwarebug = FIX_SAMSUNG3;
}
/* Table of settings for known drives terminated by an element containing all
* zeros. The drivesettings structure is described in knowndrives.h. Note
@ -357,19 +364,45 @@ const drivesettings knowndrives[] = {
".*",
NULL, NULL, NULL, NULL
},
{ "SAMSUNG SpinPoint P120 series", // tested with SP2504C/VT100-33
"^SAMSUNG SP(16[01]3|2[05][01]4)[CN]$",
{ "SAMSUNG SpinPoint T166 series", // tested with HD501LJ/CR100-10
"^SAMSUNG HD(080G|160H|32[01]K|403L|50[01]L)J$",
".*",
NULL, NULL, NULL, NULL
},
{ "SAMSUNG SpinPoint P120 series", // VF100-37 firmware, tested with SP2514N/VF100-37
"^SAMSUNG SP(16[01]3|2[05][01]4)[CN]$",
"^VF100-37$",
NULL, NULL,
specialpurpose_fix_samsung3,
same_as_minus_F3
},
{ "SAMSUNG SpinPoint P120 series", // other firmware, tested with SP2504C/VT100-33
"^SAMSUNG SP(16[01]3|2[05][01]4)[CN]$",
".*",
may_need_minus_F3_enabled,
NULL, NULL, NULL
},
{ "SAMSUNG SpinPoint P80 SD series", // tested with HD160JJ/ZM100-33
"^SAMSUNG HD(080H|120I|160J)J$",
".*",
NULL, NULL, NULL, NULL
},
{ "SAMSUNG SpinPoint P80 series", // firmware *-26 or later, tested with SP1614C/SW100-34
{ "SAMSUNG SpinPoint P80 series", // BH100-35 firmware, tested with SP0842N/BH100-35
"^SAMSUNG SP(0451|08[0124]2|12[0145]3|16[0145]4)[CN]$",
".*-(2[6789]|3[0-9])$",
"^BH100-35$",
NULL, NULL,
specialpurpose_fix_samsung3,
same_as_minus_F3
},
{ "SAMSUNG SpinPoint P80 series", // firmware *-35 or later
"^SAMSUNG SP(0451|08[0124]2|12[0145]3|16[0145]4)[CN]$",
".*-3[5-9]$",
may_need_minus_F3_enabled,
NULL, NULL, NULL
},
{ "SAMSUNG SpinPoint P80 series", // firmware *-26...34, tested with SP1614C/SW100-34
"^SAMSUNG SP(0451|08[0124]2|12[0145]3|16[0145]4)[CN]$",
".*-(2[6789]|3[0-4])$",
NULL,
vendoropts_9_halfminutes,
NULL, NULL
@ -739,6 +772,11 @@ const drivesettings knowndrives[] = {
".*",
NULL, NULL, NULL, NULL
},
{ "Hitachi Travelstar 5K160 series",
"^(Hitachi )?HTS5416([468]0|1[26])J9(AT|SA)00$",
".*",
NULL, NULL, NULL, NULL
},
{ "Hitachi Travelstar 7K60",
"^HTS726060M9AT00$",
".*",
@ -1308,8 +1346,8 @@ void showpresets(const struct ata_identify_device *drive){
char model[MODEL_STRING_LENGTH+1], firmware[FIRMWARE_STRING_LENGTH+1];
// get the drive's model/firmware strings
formatdriveidstring(model, (char *)drive->model, MODEL_STRING_LENGTH);
formatdriveidstring(firmware, (char *)drive->fw_rev, FIRMWARE_STRING_LENGTH);
format_ata_string(model, (char *)drive->model, MODEL_STRING_LENGTH);
format_ata_string(firmware, (char *)drive->fw_rev, FIRMWARE_STRING_LENGTH);
// and search to see if they match values in the table
if ((i = lookupdrive(model, firmware)) < 0) {
@ -1355,8 +1393,8 @@ int applypresets(const struct ata_identify_device *drive, unsigned char **optspt
opts=*optsptr;
// get the drive's model/firmware strings
formatdriveidstring(model, (char *)drive->model, MODEL_STRING_LENGTH);
formatdriveidstring(firmware, (char *)drive->fw_rev, FIRMWARE_STRING_LENGTH);
format_ata_string(model, (char *)drive->model, MODEL_STRING_LENGTH);
format_ata_string(firmware, (char *)drive->fw_rev, FIRMWARE_STRING_LENGTH);
// Look up the drive in knowndrives[].
if ((i = lookupdrive(model, firmware)) >= 0) {

360
missing
View File

@ -1,360 +0,0 @@
#! /bin/sh
# Common stub for a few missing GNU programs while installing.
scriptversion=2005-06-08.21
# Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005
# Free Software Foundation, Inc.
# Originally by Fran,cois Pinard <pinard@iro.umontreal.ca>, 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, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
# 02110-1301, USA.
# 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
run=:
# In the cases where this matters, `missing' is being run in the
# srcdir already.
if test -f configure.ac; then
configure_ac=configure.ac
else
configure_ac=configure.in
fi
msg="missing on your system"
case "$1" in
--run)
# Try to run requested program, and just exit if it succeeds.
run=
shift
"$@" && exit 0
# Exit code 63 means version mismatch. This often happens
# when the user try to use an ancient version of a tool on
# a file that requires a minimum version. In this case we
# we should proceed has if the program had been absent, or
# if --run hadn't been passed.
if test $? = 63; then
run=:
msg="probably too old"
fi
;;
-h|--h|--he|--hel|--help)
echo "\
$0 [OPTION]... PROGRAM [ARGUMENT]...
Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an
error status if there is no known handling for PROGRAM.
Options:
-h, --help display this help and exit
-v, --version output version information and exit
--run try to run the given command, and emulate it if it fails
Supported PROGRAM values:
aclocal touch file \`aclocal.m4'
autoconf touch file \`configure'
autoheader touch file \`config.h.in'
automake touch all \`Makefile.in' files
bison create \`y.tab.[ch]', if possible, from existing .[ch]
flex create \`lex.yy.c', if possible, from existing .c
help2man touch the output file
lex create \`lex.yy.c', if possible, from existing .c
makeinfo touch the output file
tar try tar, gnutar, gtar, then tar without non-portable flags
yacc create \`y.tab.[ch]', if possible, from existing .[ch]
Send bug reports to <bug-automake@gnu.org>."
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
# Now exit if we have it, but it failed. Also exit now if we
# don't have it and --version was passed (most likely to detect
# the program).
case "$1" in
lex|yacc)
# Not GNU programs, they don't have --version.
;;
tar)
if test -n "$run"; then
echo 1>&2 "ERROR: \`tar' requires --run"
exit 1
elif test "x$2" = "x--version" || test "x$2" = "x--help"; then
exit 1
fi
;;
*)
if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
# We have it, but it failed.
exit 1
elif test "x$2" = "x--version" || test "x$2" = "x--help"; then
# Could not run --version or --help. This is probably someone
# running `$TOOL --version' or `$TOOL --help' to check whether
# $TOOL exists and not knowing $TOOL uses missing.
exit 1
fi
;;
esac
# If it does not exist, or fails to run (possibly an outdated version),
# try to emulate it.
case "$1" in
aclocal*)
echo 1>&2 "\
WARNING: \`$1' is $msg. You should only need it if
you modified \`acinclude.m4' or \`${configure_ac}'. You might want
to install the \`Automake' and \`Perl' packages. Grab them from
any GNU archive site."
touch aclocal.m4
;;
autoconf)
echo 1>&2 "\
WARNING: \`$1' is $msg. You should only need it if
you modified \`${configure_ac}'. You might want to install the
\`Autoconf' and \`GNU m4' packages. Grab them from any GNU
archive site."
touch configure
;;
autoheader)
echo 1>&2 "\
WARNING: \`$1' is $msg. You should only need it if
you modified \`acconfig.h' or \`${configure_ac}'. You might want
to install the \`Autoconf' and \`GNU m4' packages. Grab them
from any GNU archive site."
files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}`
test -z "$files" && files="config.h"
touch_files=
for f in $files; do
case "$f" in
*:*) touch_files="$touch_files "`echo "$f" |
sed -e 's/^[^:]*://' -e 's/:.*//'`;;
*) touch_files="$touch_files $f.in";;
esac
done
touch $touch_files
;;
automake*)
echo 1>&2 "\
WARNING: \`$1' is $msg. You should only need it if
you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'.
You might want to install the \`Automake' and \`Perl' packages.
Grab them from any GNU archive site."
find . -type f -name Makefile.am -print |
sed 's/\.am$/.in/' |
while read f; do touch "$f"; done
;;
autom4te)
echo 1>&2 "\
WARNING: \`$1' is needed, but is $msg.
You might have modified some files without having the
proper tools for further handling them.
You can get \`$1' as part of \`Autoconf' from any GNU
archive site."
file=`echo "$*" | sed -n 's/.*--output[ =]*\([^ ]*\).*/\1/p'`
test -z "$file" && file=`echo "$*" | sed -n 's/.*-o[ ]*\([^ ]*\).*/\1/p'`
if test -f "$file"; then
touch $file
else
test -z "$file" || exec >$file
echo "#! /bin/sh"
echo "# Created by GNU Automake missing as a replacement of"
echo "# $ $@"
echo "exit 0"
chmod +x $file
exit 1
fi
;;
bison|yacc)
echo 1>&2 "\
WARNING: \`$1' $msg. You should only need it if
you modified a \`.y' file. You may need the \`Bison' package
in order for those modifications to take effect. You can get
\`Bison' from any GNU archive site."
rm -f y.tab.c y.tab.h
if [ $# -ne 1 ]; then
eval LASTARG="\${$#}"
case "$LASTARG" in
*.y)
SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'`
if [ -f "$SRCFILE" ]; then
cp "$SRCFILE" y.tab.c
fi
SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'`
if [ -f "$SRCFILE" ]; then
cp "$SRCFILE" y.tab.h
fi
;;
esac
fi
if [ ! -f y.tab.h ]; then
echo >y.tab.h
fi
if [ ! -f y.tab.c ]; then
echo 'main() { return 0; }' >y.tab.c
fi
;;
lex|flex)
echo 1>&2 "\
WARNING: \`$1' is $msg. You should only need it if
you modified a \`.l' file. You may need the \`Flex' package
in order for those modifications to take effect. You can get
\`Flex' from any GNU archive site."
rm -f lex.yy.c
if [ $# -ne 1 ]; then
eval LASTARG="\${$#}"
case "$LASTARG" in
*.l)
SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'`
if [ -f "$SRCFILE" ]; then
cp "$SRCFILE" lex.yy.c
fi
;;
esac
fi
if [ ! -f lex.yy.c ]; then
echo 'main() { return 0; }' >lex.yy.c
fi
;;
help2man)
echo 1>&2 "\
WARNING: \`$1' is $msg. You should only need it if
you modified a dependency of a manual page. You may need the
\`Help2man' package in order for those modifications to take
effect. You can get \`Help2man' from any GNU archive site."
file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'`
if test -z "$file"; then
file=`echo "$*" | sed -n 's/.*--output=\([^ ]*\).*/\1/p'`
fi
if [ -f "$file" ]; then
touch $file
else
test -z "$file" || exec >$file
echo ".ab help2man is required to generate this page"
exit 1
fi
;;
makeinfo)
echo 1>&2 "\
WARNING: \`$1' is $msg. You should only need it if
you modified a \`.texi' or \`.texinfo' file, or any other file
indirectly affecting the aspect of the manual. The spurious
call might also be the consequence of using a buggy \`make' (AIX,
DU, IRIX). You might want to install the \`Texinfo' package or
the \`GNU make' package. Grab either from any GNU archive site."
# The file to touch is that specified with -o ...
file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'`
if test -z "$file"; then
# ... or it is the one specified with @setfilename ...
infile=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'`
file=`sed -n '/^@setfilename/ { s/.* \([^ ]*\) *$/\1/; p; q; }' $infile`
# ... or it is derived from the source name (dir/f.texi becomes f.info)
test -z "$file" && file=`echo "$infile" | sed 's,.*/,,;s,.[^.]*$,,'`.info
fi
# If the file does not exist, the user really needs makeinfo;
# let's fail without touching anything.
test -f $file || exit 1
touch $file
;;
tar)
shift
# We have already tried tar in the generic part.
# Look for gnutar/gtar before invocation to avoid ugly error
# messages.
if (gnutar --version > /dev/null 2>&1); then
gnutar "$@" && exit 0
fi
if (gtar --version > /dev/null 2>&1); then
gtar "$@" && exit 0
fi
firstarg="$1"
if shift; then
case "$firstarg" in
*o*)
firstarg=`echo "$firstarg" | sed s/o//`
tar "$firstarg" "$@" && exit 0
;;
esac
case "$firstarg" in
*h*)
firstarg=`echo "$firstarg" | sed s/h//`
tar "$firstarg" "$@" && exit 0
;;
esac
fi
echo 1>&2 "\
WARNING: I can't seem to be able to run \`tar' with the given arguments.
You may want to install GNU tar or Free paxutils, or check the
command line arguments."
exit 1
;;
*)
echo 1>&2 "\
WARNING: \`$1' is needed, and is $msg.
You might have modified some files without having the
proper tools for further handling them. Check the \`README' file,
it often tells you about the needed prerequisites for installing
this package. You may also peek at any GNU archive site, in case
some other package would contain this missing \`$1' program."
exit 1
;;
esac
exit 0
# Local variables:
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-end: "$"
# End:

View File

@ -3,7 +3,7 @@
*
* Home page of code is: http://smartmontools.sourceforge.net
*
* Copyright (C) 2004-6 Geoffrey Keating <geoffk@geoffk.org>
* Copyright (C) 2004-7 Geoffrey Keating <geoffk@geoffk.org>
*
* 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
@ -17,6 +17,7 @@
#include <stdbool.h>
#include <errno.h>
#include <unistd.h>
#include <mach/mach.h>
#include <mach/mach_error.h>
#include <mach/mach_init.h>
@ -43,7 +44,7 @@
#include "os_darwin.h"
// Needed by '-V' option (CVS versioning) of smartd/smartctl
const char *os_XXXX_c_cvsid="$Id: os_darwin.cpp,v 1.18 2006/09/20 16:17:31 shattered Exp $" \
const char *os_XXXX_c_cvsid="$Id: os_darwin.cpp,v 1.19 2007/04/27 08:52:44 geoffk1 Exp $" \
ATACMDS_H_CVSID CONFIG_H_CVSID INT64_H_CVSID OS_DARWIN_H_CVSID SCSICMDS_H_CVSID UTILITY_H_CVSID;
// Print examples for smartctl.
@ -333,7 +334,7 @@ ata_command_interface(int fd, smart_command_set command,
IOATASMARTInterface **ifp = devices[fd].smartIf;
IOATASMARTInterface *smartIf;
IOReturn err;
int timeoutCount = 2;
int timeoutCount = 5;
if (! ifp)
return -1;
@ -385,8 +386,9 @@ ata_command_interface(int fd, smart_command_set command,
{
UInt32 dummy;
err = smartIf->GetATAIdentifyData (ifp, data, 512, &dummy);
if (err != kIOReturnSuccess)
printf ("identify failed: %d\n", (int) err);
if (err != kIOReturnSuccess && err != kIOReturnTimeout
&& err != kIOReturnNotResponding)
printf ("identify failed: %#x\n", (unsigned) err);
if (err == kIOReturnSuccess && isbigendian())
{
int i;
@ -409,7 +411,10 @@ ata_command_interface(int fd, smart_command_set command,
you get a timeout, you have to try again to get the actual
command run, but the drive is already powering up so you can't
use this for CHECK_POWER_MODE. */
} while (err == kIOReturnTimeout && timeoutCount-- > 0);
if (err == kIOReturnTimeout || err == kIOReturnNotResponding)
sleep (1);
} while ((err == kIOReturnTimeout || err == kIOReturnNotResponding)
&& timeoutCount-- > 0);
if (err == kIOReturnExclusiveAccess)
errno = EBUSY;
return err == kIOReturnSuccess ? 0 : -1;

View File

@ -24,8 +24,12 @@
#ifndef OS_DARWIN_H_
#define OS_DARWIN_H_
#define OS_DARWIN_H_CVSID "$Id: os_darwin.h,v 1.5 2006/04/12 14:54:28 ballen4705 Exp $\n"
#define OS_DARWIN_H_CVSID "$Id: os_darwin.h,v 1.6 2007/04/16 17:49:02 shattered Exp $\n"
// There isn't actually any content here yet.
// Isn't in 10.3.9?
#ifndef kIOPropertySMARTCapableKey
#define kIOPropertySMARTCapableKey "SMART Capable"
#endif
#endif /* OS_DARWIN_H_ */

0
os_darwin/SMART.in Executable file → Normal file
View File

View File

@ -35,17 +35,21 @@
#include "int64.h"
#include "atacmds.h"
#include "scsicmds.h"
#include "cciss.h"
#include "utility.h"
#include "extern.h"
#include "os_freebsd.h"
static const char *filenameandversion="$Id: os_freebsd.cpp,v 1.51 2006/09/17 03:17:53 dpgilbert Exp $";
static const char *filenameandversion="$Id: os_freebsd.cpp,v 1.54 2007/09/06 08:48:55 ballen4705 Exp $";
const char *os_XXXX_c_cvsid="$Id: os_freebsd.cpp,v 1.51 2006/09/17 03:17:53 dpgilbert Exp $" \
const char *os_XXXX_c_cvsid="$Id: os_freebsd.cpp,v 1.54 2007/09/06 08:48:55 ballen4705 Exp $" \
ATACMDS_H_CVSID CONFIG_H_CVSID INT64_H_CVSID OS_FREEBSD_H_CVSID SCSICMDS_H_CVSID UTILITY_H_CVSID;
// to hold onto exit code for atexit routine
extern int exitstatus;
extern smartmonctrl * con;
// Private table of open devices: guaranteed zero on startup since
// part of static data.
struct freebsd_dev_channel *devicetable[FREEBSD_MAXDEV];
@ -85,7 +89,7 @@ void print_smartctl_examples(){
}
// Like open(). Return positive integer handle, used by functions below only. mode=="ATA" or "SCSI".
int deviceopen (const char* dev, char* mode __unused) {
int deviceopen (const char* dev, __unused char* mode) {
struct freebsd_dev_channel *fdchan;
int parse_ok, i;
@ -157,6 +161,15 @@ int deviceopen (const char* dev, char* mode __unused) {
}
}
if (parse_ok == CONTROLLER_CCISS) {
if ((fdchan->device = open(dev,O_RDWR))<0) {
int myerror = errno; // preserver across free call
free(fdchan);
errno=myerror;
return -1;
}
}
if (parse_ok == CONTROLLER_SCSI) {
// this is really a NO-OP, as the parse takes care
// of filling in correct details
@ -248,13 +261,13 @@ void printwarning(int msgNo, const char* extra) {
return;
}
// Interface to ATA devices. See os_linux.c
int marvell_command_interface(int fd __unused, smart_command_set command __unused, int select __unused, char *data __unused) {
return -1;
int marvell_command_interface(__unused int fd, __unused smart_command_set command, __unused int select, __unused char *data) {
return -1;
}
int highpoint_command_interface(int fd __unused, smart_command_set command __unused, int select __unused, char *data __unused)
int highpoint_command_interface(__unused int fd, __unused smart_command_set command, __unused int select, __unused char *data) {
{
return -1;
}
@ -439,7 +452,7 @@ int ata_command_interface(int fd, smart_command_set command, int select, char *d
// Interface to SCSI devices. See os_linux.c
int do_scsi_cmnd_io(int fd, struct scsi_cmnd_io * iop, int report)
int do_normal_scsi_cmnd_io(int fd, struct scsi_cmnd_io * iop, int report)
{
struct freebsd_dev_channel* con = NULL;
struct cam_device* cam_dev = NULL;
@ -540,6 +553,40 @@ int do_scsi_cmnd_io(int fd, struct scsi_cmnd_io * iop, int report)
return 0;
}
/* Check and call the right interface. Maybe when the do_generic_scsi_cmd_io interface is better
we can take off this crude way of calling the right interface */
int do_scsi_cmnd_io(int dev_fd, struct scsi_cmnd_io * iop, int report)
{
struct freebsd_dev_channel *fdchan;
switch(con->controller_type)
{
case CONTROLLER_CCISS:
// check that "file descriptor" is valid
if (isnotopen(&dev_fd,&fdchan))
return -ENOTTY;
#ifdef HAVE_DEV_CISS_CISSIO_H
return cciss_io_interface(fdchan->device, con->controller_port-1, iop, report);
#else
{
static int warned = 0;
if (!warned) {
pout("CCISS support is not available in this build of smartmontools,\n"
"/usr/src/sys/dev/ciss/cissio.h was not available at build time.\n\n");
warned = 1;
}
}
errno = ENOSYS;
return -1;
#endif
// not reached
break;
default:
return do_normal_scsi_cmnd_io(dev_fd, iop, report);
// not reached
break;
}
}
// Interface to ATA devices behind 3ware escalade RAID controller cards. See os_linux.c
#define BUFFER_LEN_678K_CHAR ( sizeof(struct twe_usercommand) ) // 520
@ -589,8 +636,7 @@ int escalade_command_interface(int fd, int disknum, int escalade_type, smart_com
// Same for (almost) all commands - but some reset below
ata->request_id = 0xFF;
ata->unit = disknum;
ata->host_id = 0;
ata->unit = disknum;
ata->status = 0;
ata->flags = 0x1;
ata->drive_head = 0x0;
@ -878,6 +924,7 @@ static const char * fbsd_dev_scsi_tape2 = "nsa";
static const char * fbsd_dev_scsi_tape3 = "esa";
static const char * fbsd_dev_twe_ctrl = "twe";
static const char * fbsd_dev_twa_ctrl = "twa";
static const char * fbsd_dev_cciss = "ciss";
static int parse_ata_chan_dev(const char * dev_name, struct freebsd_dev_channel *chan) {
int len;
@ -953,6 +1000,10 @@ static int parse_ata_chan_dev(const char * dev_name, struct freebsd_dev_channel
}
return CONTROLLER_3WARE_678K_CHAR;
}
// form /dev/ciss*
if (!strncmp(fbsd_dev_cciss, dev_name,
strlen(fbsd_dev_cciss)))
return CONTROLLER_CCISS;
// we failed to recognize any of the forms
return CONTROLLER_UNKNOWN;
@ -1005,10 +1056,10 @@ int get_dev_names(char*** names, const char* prefix) {
// Use glob to look for any directory entries matching the patterns
// first call inits with first pattern match, second call appends
// to first list. Turn on NOCHECK for second call. This results in no
// error if no more matches found, however it does append the actual
// pattern to the list of paths....
if ((retglob=glob(pattern1, GLOB_ERR, NULL, &globbuf)) ||
// to first list. GLOB_NOCHECK results in no error if no more matches
// found, however it does append the actual pattern to the list of
// paths....
if ((retglob=glob(pattern1, GLOB_ERR|GLOB_NOCHECK, NULL, &globbuf)) ||
(retglob=glob(pattern2, GLOB_ERR|GLOB_APPEND|GLOB_NOCHECK,NULL,&globbuf))) {
int retval = -1;
// glob failed
@ -1033,7 +1084,6 @@ int get_dev_names(char*** names, const char* prefix) {
return retval;
}
// did we find too many paths?
// did we find too many paths?
lim = globbuf.gl_pathc < MAX_NUM_DEV ? globbuf.gl_pathc : MAX_NUM_DEV;
if (lim < globbuf.gl_pathc)
@ -1050,7 +1100,7 @@ int get_dev_names(char*** names, const char* prefix) {
// now step through the list returned by glob. No link checking needed
// in FreeBSD
for (i=0; i<globbuf.gl_pathc; i++){
// becuase of the NO_CHECK on second call to glob,
// because of the NO_CHECK in calls to glob,
// the pattern itself will be added to path list..
// so ignore any paths that have the ']' from pattern
if (strchr(globbuf.gl_pathv[i],']') == NULL)

View File

@ -82,7 +82,7 @@
#ifndef OS_FREEBSD_H_
#define OS_FREEBSD_H_
#define OS_FREEBSD_H_CVSID "$Id: os_freebsd.h,v 1.20 2006/04/12 14:54:28 ballen4705 Exp $\n"
#define OS_FREEBSD_H_CVSID "$Id: os_freebsd.h,v 1.21 2007/09/06 08:48:55 ballen4705 Exp $\n"
struct freebsd_dev_channel {
int channel; // the ATA channel to work with
@ -234,8 +234,7 @@ typedef struct
u_int8_t sgl_offset:3;
u_int8_t size;
u_int8_t request_id;
u_int8_t unit:4;
u_int8_t host_id:4;
u_int8_t unit;
u_int8_t status;
u_int8_t flags;
u_int16_t param;

View File

@ -3,8 +3,8 @@
*
* Home page of code is: http://smartmontools.sourceforge.net
*
* Copyright (C) 2003-6 Bruce Allen <smartmontools-support@lists.sourceforge.net>
* Copyright (C) 2003-6 Doug Gilbert <dougg@torque.net>
* Copyright (C) 2003-7 Bruce Allen <smartmontools-support@lists.sourceforge.net>
* Copyright (C) 2003-7 Doug Gilbert <dougg@torque.net>
*
* Parts of this file are derived from code that was
*
@ -44,14 +44,12 @@
// one for SCSI devices, and one for ATA devices behind escalade
// controllers.
#include "config.h"
#include <errno.h>
#include <fcntl.h>
#include <glob.h>
#ifdef HAVE_LINUX_COMPILER_H
#include <linux/compiler.h>
#endif
#include <scsi/scsi_ioctl.h>
#include <scsi/sg.h>
#include <stdlib.h>
@ -63,7 +61,6 @@
#include <sys/sysmacros.h>
#endif
#include "config.h"
#include "int64.h"
#include "atacmds.h"
#include "extern.h"
@ -72,9 +69,7 @@ extern smartmonctrl * con;
#include "scsicmds.h"
#include "utility.h"
#include "extern.h"
#include <linux/cciss_ioctl.h>
#include "cciss.h"
#ifndef ENOTSUP
#define ENOTSUP ENOSYS
@ -84,9 +79,9 @@ typedef unsigned long long u8;
#define ARGUSED(x) ((void)(x))
static const char *filenameandversion="$Id: os_linux.cpp,v 1.88 2006/10/25 17:01:42 ballen4705 Exp $";
static const char *filenameandversion="$Id: os_linux.cpp,v 1.97 2007/09/06 08:48:55 ballen4705 Exp $";
const char *os_XXXX_c_cvsid="$Id: os_linux.cpp,v 1.88 2006/10/25 17:01:42 ballen4705 Exp $" \
const char *os_XXXX_c_cvsid="$Id: os_linux.cpp,v 1.97 2007/09/06 08:48:55 ballen4705 Exp $" \
ATACMDS_H_CVSID CONFIG_H_CVSID INT64_H_CVSID OS_LINUX_H_CVSID SCSICMDS_H_CVSID UTILITY_H_CVSID;
// to hold onto exit code for atexit routine
@ -98,22 +93,6 @@ extern long long bytes;
/* for passing global control variables */
extern smartmonctrl *con;
static int cciss_io_interface(int device, int target,
struct scsi_cmnd_io * iop, int report);
typedef struct _ReportLUNdata_struct
{
BYTE LUNListLength[4];
DWORD reserved;
BYTE LUN[CISS_MAX_LUN][8];
} ReportLunData_struct;
/* Structure/defines of Report Physical LUNS of drive */
#define CISS_MAX_LUN 16
#define CISS_MAX_PHYS_LUN 1024
#define CISS_REPORT_PHYS 0xc3
/* This function will setup and fix device nodes for a 3ware controller. */
#define MAJOR_STRING_LENGTH 3
#define DEVICE_STRING_LENGTH 32
@ -423,14 +402,10 @@ int make_device_names (char*** devlist, const char* name) {
// 1 if the command succeeded and disk SMART status is "FAILING"
// huge value of buffer size needed because HDIO_DRIVE_CMD assumes
// that buff[3] is the data size. Since the ATA_SMART_AUTOSAVE and
// ATA_SMART_AUTO_OFFLINE use values of 0xf1 and 0xf8 we need the space.
// Otherwise a 4+512 byte buffer would be enough.
#define STRANGE_BUFFER_LENGTH (4+512*0xf8)
#define BUFFER_LENGTH (4+512)
int ata_command_interface(int device, smart_command_set command, int select, char *data){
unsigned char buff[STRANGE_BUFFER_LENGTH];
unsigned char buff[BUFFER_LENGTH];
// positive: bytes to write to caller. negative: bytes to READ from
// caller. zero: non-data command
int copydata=0;
@ -447,7 +422,7 @@ int ata_command_interface(int device, smart_command_set command, int select, cha
// buff[2] contains the ATA SECTOR COUNT REGISTER
// clear out buff. Large enough for HDIO_DRIVE_CMD (4+512 bytes)
memset(buff, 0, STRANGE_BUFFER_LENGTH);
memset(buff, 0, BUFFER_LENGTH);
buff[0]=ATA_SMART_CMD;
switch (command){
@ -497,12 +472,14 @@ int ata_command_interface(int device, smart_command_set command, int select, cha
buff[2]=ATA_SMART_STATUS;
break;
case AUTO_OFFLINE:
buff[2]=ATA_SMART_AUTO_OFFLINE;
buff[3]=select; // YET NOTE - THIS IS A NON-DATA COMMAND!!
// NSECT is 241 for enable but no data transfer. Use TASK ioctl.
buff[1]=ATA_SMART_AUTO_OFFLINE;
buff[2]=select;
break;
case AUTOSAVE:
buff[2]=ATA_SMART_AUTOSAVE;
buff[3]=select; // YET NOTE - THIS IS A NON-DATA COMMAND!!
// NSECT is 248 for enable but no data transfer. Use TASK ioctl.
buff[1]=ATA_SMART_AUTOSAVE;
buff[2]=select;
break;
case IMMEDIATE_OFFLINE:
buff[2]=ATA_SMART_IMMEDIATE_OFFLINE;
@ -557,7 +534,7 @@ int ata_command_interface(int device, smart_command_set command, int select, cha
// There are two different types of ioctls(). The HDIO_DRIVE_TASK
// one is this:
if (command==STATUS_CHECK){
if (command==STATUS_CHECK || command==AUTOSAVE || command==AUTO_OFFLINE){
int retval;
// NOT DOCUMENTED in /usr/src/linux/include/linux/hdreg.h. You
@ -597,8 +574,8 @@ int ata_command_interface(int device, smart_command_set command, int select, cha
syserror("Error SMART Status command failed");
pout("Please get assistance from " PACKAGE_HOMEPAGE "\n");
pout("Register values returned from SMART Status command are:\n");
pout("CMD=0x%02x\n",(int)buff[0]);
pout("FR =0x%02x\n",(int)buff[1]);
pout("ST =0x%02x\n",(int)buff[0]);
pout("ERR=0x%02x\n",(int)buff[1]);
pout("NS =0x%02x\n",(int)buff[2]);
pout("SC =0x%02x\n",(int)buff[3]);
pout("CL =0x%02x\n",(int)buff[4]);
@ -650,94 +627,6 @@ int ata_command_interface(int device, smart_command_set command, int select, cha
return 0;
}
// CCISS Smart Array Controller
static int cciss_sendpassthru(unsigned int cmdtype, unsigned char *CDB,
unsigned int CDBlen, char *buff,
unsigned int size, unsigned int LunID,
unsigned char *scsi3addr, int fd)
{
int err ;
IOCTL_Command_struct iocommand;
memset(&iocommand, 0, sizeof(iocommand));
if (cmdtype == 0)
{
// To controller; nothing to do
}
else if (cmdtype == 1)
{
iocommand.LUN_info.LogDev.VolId = LunID;
iocommand.LUN_info.LogDev.Mode = 1;
}
else if (cmdtype == 2)
{
memcpy(&iocommand.LUN_info.LunAddrBytes,scsi3addr,8);
iocommand.LUN_info.LogDev.Mode = 0;
}
else
{
fprintf(stderr, "cciss_sendpassthru: bad cmdtype\n");
return 1;
}
memcpy(&iocommand.Request.CDB[0], CDB, CDBlen);
iocommand.Request.CDBLen = CDBlen;
iocommand.Request.Type.Type = TYPE_CMD;
iocommand.Request.Type.Attribute = ATTR_SIMPLE;
iocommand.Request.Type.Direction = XFER_READ;
iocommand.Request.Timeout = 0;
iocommand.buf_size = size;
iocommand.buf = (unsigned char *)buff;
if ((err = ioctl(fd, CCISS_PASSTHRU, &iocommand)))
{
fprintf(stderr, "CCISS ioctl error %d\n", err);
}
return err;
}
static int cciss_getlun(int device, int target, unsigned char *physlun)
{
unsigned char CDB[16]= {0};
ReportLunData_struct *luns;
int reportlunsize = sizeof(*luns) + CISS_MAX_PHYS_LUN * 8;
int i;
int ret;
luns = (ReportLunData_struct *)malloc(reportlunsize);
memset(luns, 0, reportlunsize);
/* Get Physical LUN Info (for physical device) */
CDB[0] = CISS_REPORT_PHYS;
CDB[6] = (reportlunsize >> 24) & 0xFF; /* MSB */
CDB[7] = (reportlunsize >> 16) & 0xFF;
CDB[8] = (reportlunsize >> 8) & 0xFF;
CDB[9] = reportlunsize & 0xFF;
if ((ret = cciss_sendpassthru(0, CDB, 12, (char *)luns, reportlunsize, 0, NULL, device)))
{
free(luns);
return ret;
}
for (i=0; i<CISS_MAX_LUN+1; i++)
{
if (luns->LUN[i][6] == target)
{
memcpy(physlun, luns->LUN[i], 8);
free(luns);
return 0;
}
}
free(luns);
return ret;
}
// end CCISS Smart Array Controller
// >>>>>> Start of general SCSI specific linux code
/* Linux specific code.
@ -849,24 +738,29 @@ static int sg_io_cmnd_io(int dev_fd, struct scsi_cmnd_io * iop, int report,
strerror(errno));
return -errno;
}
iop->resid = io_hdr.resid;
iop->scsi_status = io_hdr.status;
if (report > 0) {
pout(" scsi_status=0x%x, host_status=0x%x, driver_status=0x%x\n"
" info=0x%x duration=%d milliseconds\n", io_hdr.status,
" info=0x%x duration=%d milliseconds resid=%d\n", io_hdr.status,
io_hdr.host_status, io_hdr.driver_status, io_hdr.info,
io_hdr.duration);
io_hdr.duration, io_hdr.resid);
if (report > 1) {
if (DXFER_FROM_DEVICE == iop->dxfer_dir) {
int trunc = (iop->dxfer_len > 256) ? 1 : 0;
int trunc, len;
pout(" Incoming data, len=%d%s:\n", (int)iop->dxfer_len,
(trunc ? " [only first 256 bytes shown]" : ""));
dStrHex((const char*)iop->dxferp,
(trunc ? 256 : iop->dxfer_len) , 1);
len = iop->dxfer_len - iop->resid;
trunc = (len > 256) ? 1 : 0;
if (len > 0) {
pout(" Incoming data, len=%d%s:\n", len,
(trunc ? " [only first 256 bytes shown]" : ""));
dStrHex((const char*)iop->dxferp, (trunc ? 256 : len),
1);
} else
pout(" Incoming data trimmed to nothing by resid\n");
}
}
}
iop->resid = io_hdr.resid;
iop->scsi_status = io_hdr.status;
if (io_hdr.info | SG_INFO_CHECK) { /* error or warning */
int masked_driver_status = (LSCSI_DRIVER_MASK & io_hdr.driver_status);
@ -1084,7 +978,20 @@ static int do_normal_scsi_cmnd_io(int dev_fd, struct scsi_cmnd_io * iop,
switch(con->controller_type)
{
case CONTROLLER_CCISS:
#ifdef HAVE_LINUX_CCISS_IOCTL_H
return cciss_io_interface(dev_fd, con->controller_port-1, iop, report);
#else
{
static int warned = 0;
if (!warned) {
pout("CCISS support is not available in this build of smartmontools,\n"
"<linux/cciss_ioctl.h> was not available at build time.\n\n");
warned = 1;
}
}
errno = ENOSYS;
return -1;
#endif
// not reached
break;
default:
@ -1096,76 +1003,6 @@ static int do_normal_scsi_cmnd_io(int dev_fd, struct scsi_cmnd_io * iop,
// >>>>>> End of general SCSI specific linux code
/* cciss >> CCSISS I/O passthrough
This is an interface that uses the cciss passthrough to talk to the SMART controller on
the HP system. The cciss driver provides a way to send SCSI cmds through the CCISS passthrough
essentially the methods above and below pertain to SCSI, except for the SG driver which is not
involved. The CCISS driver does not engage the scsi subsystem. */
static int cciss_io_interface(int device, int target, struct scsi_cmnd_io * iop, int report)
{
unsigned char pBuf[512] = {0};
unsigned char phylun[1024] = {0};
int iBufLen = 512;
int status = -1;
int len = 0; // used later in the code.
report = 0;
cciss_getlun(device, target, phylun);
status = cciss_sendpassthru( 2, iop->cmnd, iop->cmnd_len, (char*) pBuf, iBufLen, 1, phylun, device);
if (0 == status)
{
if (report > 0)
printf(" status=0\n");
if (DXFER_FROM_DEVICE == iop->dxfer_dir)
{
memcpy(iop->dxferp, pBuf, iop->dxfer_len);
if (report > 1)
{
int trunc = (iop->dxfer_len > 256) ? 1 : 0;
printf(" Incoming data, len=%d%s:\n", (int)iop->dxfer_len,
(trunc ? " [only first 256 bytes shown]" : ""));
dStrHex((const char*)iop->dxferp, (trunc ? 256 : iop->dxfer_len) , 1);
}
}
return 0;
}
iop->scsi_status = status & 0x7e; /* bits 0 and 7 used to be for vendors */
if (LSCSI_DRIVER_SENSE == ((status >> 24) & 0xf))
iop->scsi_status = SCSI_STATUS_CHECK_CONDITION;
len = (SEND_IOCTL_RESP_SENSE_LEN < iop->max_sense_len) ?
SEND_IOCTL_RESP_SENSE_LEN : iop->max_sense_len;
if ((SCSI_STATUS_CHECK_CONDITION == iop->scsi_status) &&
iop->sensep && (len > 0))
{
memcpy(iop->sensep, pBuf, len);
iop->resp_sense_len = iBufLen;
if (report > 1)
{
printf(" >>> Sense buffer, len=%d:\n", (int)len);
dStrHex((const char *)pBuf, len , 1);
}
}
if (report)
{
if (SCSI_STATUS_CHECK_CONDITION == iop->scsi_status) {
printf(" status=%x: sense_key=%x asc=%x ascq=%x\n", status & 0xff,
pBuf[2] & 0xf, pBuf[12], pBuf[13]);
}
else
printf(" status=0x%x\n", status);
}
if (iop->scsi_status > 0)
return 0;
else
{
if (report > 0)
printf(" ioctl status=0x%x but scsi status=0, fail with EIO\n", status);
return -EIO; /* give up, assume no device there */
}
}
// prototype
void printwarning(smart_command_set command);
@ -1250,8 +1087,7 @@ int escalade_command_interface(int fd, int disknum, int escalade_type, smart_com
// Same for (almost) all commands - but some reset below
passthru->byte0.opcode = TW_OP_ATA_PASSTHRU;
passthru->request_id = 0xFF;
passthru->byte3.aport = disknum;
passthru->byte3.host_id = 0;
passthru->unit = disknum;
passthru->status = 0;
passthru->flags = 0x1;
passthru->drive_head = 0x0;
@ -1636,8 +1472,12 @@ int marvell_command_interface(int device,
// if no pmport device, set to 1 or leave blank
// 5: data [ void * ( var leangth ) ]
//
#define STRANGE_BUFFER_LENGTH (4+512*0xf8)
int highpoint_command_interface(int device, smart_command_set command,
int select, char *data)
{
unsigned char hpt_buff[4*sizeof(int) + STRANGE_BUFFER_LENGTH];
unsigned int *hpt = (unsigned int *)hpt_buff;

View File

@ -38,7 +38,7 @@
#ifndef OS_LINUX_H_
#define OS_LINUX_H_
#define OS_LINUX_H_CVSID "$Id: os_linux.h,v 1.25 2006/08/25 06:06:25 sxzzsf Exp $\n"
#define OS_LINUX_H_CVSID "$Id: os_linux.h,v 1.26 2007/09/06 08:48:55 ballen4705 Exp $\n"
/*
The following definitions/macros/prototypes are used for three
@ -76,10 +76,7 @@ typedef struct TAG_TW_Passthru {
} byte0;
unsigned char size;
unsigned char request_id;
struct {
unsigned char aport:4;
unsigned char host_id:4;
} byte3;
unsigned char unit;
unsigned char status; // On return, contains 3ware STATUS register
unsigned char flags;
unsigned short param;

View File

@ -25,7 +25,7 @@
#include "utility.h"
#include "os_openbsd.h"
const char *os_XXXX_c_cvsid = "$Id: os_openbsd.cpp,v 1.13 2006/09/20 16:17:31 shattered Exp $" \
const char *os_XXXX_c_cvsid = "$Id: os_openbsd.cpp,v 1.14 2007/04/05 16:39:21 shattered Exp $" \
ATACMDS_H_CVSID CONFIG_H_CVSID INT64_H_CVSID OS_OPENBSD_H_CVSID SCSICMDS_H_CVSID UTILITY_H_CVSID;
/* global variable holding byte count of allocated memory */
@ -105,7 +105,7 @@ get_dev_names(char ***names, const char *prefix)
pout("Failed to get value of sysctl `hw.disknames'\n");
return -1;
}
if (!(disknames = (char*)malloc(sysctl_len))) {
if (!(disknames = (char *)malloc(sysctl_len))) {
pout("Out of memory constructing scan device list\n");
return -1;
}
@ -121,7 +121,7 @@ get_dev_names(char ***names, const char *prefix)
if (strncmp(p, prefix, strlen(prefix))) {
continue;
}
mp[n] = (char*)malloc(strlen(net_dev_prefix) + strlen(p) + 2);
mp[n] = (char *)malloc(strlen(net_dev_prefix) + strlen(p) + 2);
if (!mp[n]) {
pout("Out of memory constructing scan device list\n");
return -1;
@ -131,7 +131,7 @@ get_dev_names(char ***names, const char *prefix)
n++;
}
mp = (char**)realloc(mp, n * (sizeof(char *)));
mp = (char **)realloc(mp, n * (sizeof(char *)));
bytes += (n) * (sizeof(char *));
*names = mp;
return n;
@ -390,12 +390,12 @@ do_scsi_cmnd_io(int fd, struct scsi_cmnd_io * iop, int report)
memset(&sc, 0, sizeof(sc));
memcpy(sc.cmd, iop->cmnd, iop->cmnd_len);
sc.cmdlen = iop->cmnd_len;
sc.databuf = (char*)iop->dxferp;
sc.databuf = (char *)iop->dxferp;
sc.datalen = iop->dxfer_len;
sc.senselen = iop->max_sense_len;
sc.timeout = iop->timeout == 0 ? 60000 : iop->timeout; /* XXX */
sc.flags =
(iop->dxfer_dir == DXFER_NONE ? SCCMD_READ : /* XXX */
(iop->dxfer_dir == DXFER_NONE ? SCCMD_READ :
(iop->dxfer_dir == DXFER_FROM_DEVICE ? SCCMD_READ : SCCMD_WRITE));
if (ioctl(fd, SCIOCCOMMAND, &sc) < 0) {

550
os_os2.cpp Normal file
View File

@ -0,0 +1,550 @@
/*
* os_os2.c
*
* Home page of code is: http://smartmontools.sourceforge.net
*
* Copyright (C) 2004-6 Yuri Dario <smartmontools-support@lists.sourceforge.net>
*
* 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.
*
* You should have received a copy of the GNU General Public License
* (for example COPYING); if not, write to the Free
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/*
*
* Thanks to Daniela Engert for providing sample code for SMART ioctl access.
*
*/
// These are needed to define prototypes for the functions defined below
#include <errno.h>
#include "atacmds.h"
#include "scsicmds.h"
#include "utility.h"
// This is to include whatever prototypes you define in os_generic.h
#include "os_os2.h"
// Needed by '-V' option (CVS versioning) of smartd/smartctl
const char *os_XXXX_c_cvsid="$Id: os_os2.cpp,v 1.7 2006/09/20 16:17:31 shattered Exp $" \
ATACMDS_H_CVSID OS_XXXX_H_CVSID SCSICMDS_H_CVSID UTILITY_H_CVSID;
// global handle to device driver
static HFILE hDevice;
// Please eliminate the following block: both the two #includes and
// the 'unsupported()' function. They are only here to warn
// unsuspecting users that their Operating System is not supported! If
// you wish, you can use a similar warning mechanism for any of the
// functions in this file that you can not (or choose not to)
// implement.
#include "config.h"
typedef struct _IDEREGS {
UCHAR bFeaturesReg;
UCHAR bSectorCountReg;
UCHAR bSectorNumberReg;
UCHAR bCylLowReg;
UCHAR bCylHighReg;
UCHAR bDriveHeadReg;
UCHAR bCommandReg;
UCHAR bReserved;
} IDEREGS, *PIDEREGS, *LPIDEREGS;
static void unsupported(int which){
static int warninggiven[4];
if (which<0 || which>3)
return;
if (!warninggiven[which]) {
char msg;
debugmode=1;
warninggiven[which]=1;
switch (which) {
case 0:
msg="generate a list of devices";
break;
case 1:
msg="interface to Marvell-based SATA controllers";
break;
case 2:
msg="interface to 3ware-based RAID controllers";
break;
case 3:
msg="interface to SCSI devices";
break;
}
pout("Under OS/2, smartmontools can not %s\n");
}
return;
}
// print examples for smartctl. You should modify this function so
// that the device paths are sensible for your OS, and to eliminate
// unsupported commands (eg, 3ware controllers).
void print_smartctl_examples(){
printf("=================================================== SMARTCTL EXAMPLES =====\n\n");
#ifdef HAVE_GETOPT_LONG
printf(
" smartctl -a /dev/hda (Prints all SMART information)\n\n"
" smartctl --smart=on --offlineauto=on --saveauto=on /dev/hda\n"
" (Enables SMART on first disk)\n\n"
" smartctl -t long /dev/hda (Executes extended disk self-test)\n\n"
" smartctl --attributes --log=selftest --quietmode=errorsonly /dev/hda\n"
" (Prints Self-Test & Attribute errors)\n"
" smartctl -a --device=3ware,2 /dev/sda\n"
" (Prints all SMART info for 3rd ATA disk on 3ware RAID controller)\n"
);
#else
printf(
" smartctl -a /dev/hda (Prints all SMART information)\n"
" smartctl -s on -o on -S on /dev/hda (Enables SMART on first disk)\n"
" smartctl -t long /dev/hda (Executes extended disk self-test)\n"
" smartctl -A -l selftest -q errorsonly /dev/hda\n"
" (Prints Self-Test & Attribute errors)\n"
" smartctl -a -d 3ware,2 /dev/sda\n"
" (Prints all SMART info for 3rd ATA disk on 3ware RAID controller)\n"
);
#endif
return;
}
static const char * skipdev(const char * s)
{
return (!strncmp(s, "/dev/", 5) ? s + 5 : s);
}
// tries to guess device type given the name (a path). See utility.h
// for return values.
int guess_device_type (const char* dev_name) {
//printf( "dev_name %s\n", dev_name);
dev_name = skipdev(dev_name);
if (!strncmp(dev_name, "hd", 2))
return CONTROLLER_ATA;
if (!strncmp(dev_name, "scsi", 4))
return CONTROLLER_SCSI;
return CONTROLLER_UNKNOWN;
}
// makes a list of ATA or SCSI devices for the DEVICESCAN directive of
// smartd. Returns number N of devices, or -1 if out of
// memory. Allocates N+1 arrays: one of N pointers (devlist); the
// other N arrays each contain null-terminated character strings. In
// the case N==0, no arrays are allocated because the array of 0
// pointers has zero length, equivalent to calling malloc(0).
int make_device_names (char*** devlist, const char* name) {
unsupported(0);
return 0;
}
// Like open(). Return non-negative integer handle, only used by the
// functions below. type=="ATA" or "SCSI". If you need to store
// extra information about your devices, create a private internal
// array within this file (see os_freebsd.cpp for an example). If you
// can not open the device (permission denied, does not exist, etc)
// set errno as open() does and return <0.
int deviceopen(const char *pathname, char *type){
int fd;
APIRET rc;
ULONG ActionTaken;
//printf( "deviceopen pathname %s\n", pathname);
rc = DosOpen ("\\DEV\\IBMS506$", &hDevice, &ActionTaken, 0, FILE_SYSTEM,
OPEN_ACTION_OPEN_IF_EXISTS, OPEN_SHARE_DENYNONE |
OPEN_FLAGS_NOINHERIT | OPEN_ACCESS_READONLY, NULL);
if (rc) {
char errmsg[256];
snprintf(errmsg,256,"Smartctl open driver IBMS506$ failed (%d)", rc);
errmsg[255]='\0';
syserror(errmsg);
return -1;
}
pathname = skipdev(pathname);
fd = tolower(pathname[2]) - 'a';
return fd;
}
// Like close(). Acts only on integer handles returned by
// deviceopen() above.
int deviceclose(int fd){
DosClose( hDevice);
hDevice = NULL;
return 0;
}
static void print_ide_regs(const IDEREGS * r, int out)
{
pout("%s=0x%02x,%s=0x%02x, SC=0x%02x, NS=0x%02x, CL=0x%02x, CH=0x%02x, SEL=0x%02x\n",
(out?"STS":"CMD"), r->bCommandReg, (out?"ERR":" FR"), r->bFeaturesReg,
r->bSectorCountReg, r->bSectorNumberReg, r->bCylLowReg, r->bCylHighReg, r->bDriveHeadReg);
}
//
// OS/2 direct ioctl interface to IBMS506$
//
int dani_ioctl( int device, int request, void* arg)
{
unsigned char* buff = (unsigned char*) arg;
APIRET rc;
DSKSP_CommandParameters Parms;
ULONG PLen = 1;
ULONG DLen = 512; //sizeof (*buf);
UCHAR temp;
ULONG value = 0;
IDEREGS regs;
//printf( "device %d, request 0x%x, arg[0] 0x%x, arg[2] 0x%x\n", device, request, buff[0], buff[2]);
Parms.byPhysicalUnit = device;
switch( buff[0]) {
case WIN_IDENTIFY:
rc = DosDevIOCtl (hDevice, DSKSP_CAT_GENERIC, DSKSP_GET_INQUIRY_DATA,
(PVOID)&Parms, PLen, &PLen, (PVOID)arg+4, DLen, &DLen);
if (rc != 0)
{
printf ("DANIS506 ATA GET HD Failed (%d,0x%x)\n", rc, rc);
return -1;
}
break;
case WIN_SMART:
switch( buff[2]) {
case SMART_STATUS:
DLen = sizeof(value);
// OS/2 already checks CL/CH in IBM1S506 code!! see s506rte.c (ddk)
// value: -1=not supported, 0=ok, 1=failing
rc = DosDevIOCtl (hDevice, DSKSP_CAT_SMART, DSKSP_SMART_GETSTATUS,
(PVOID)&Parms, PLen, &PLen, (PVOID)&value, DLen, &DLen);
if (rc)
{
printf ("DANIS506 ATA GET SMART_STATUS failed (%d,0x%x)\n", rc, rc);
return -1;
}
buff[4] = (unsigned char)value;
break;
case SMART_READ_VALUES:
rc = DosDevIOCtl (hDevice, DSKSP_CAT_SMART, DSKSP_SMART_GET_ATTRIBUTES,
(PVOID)&Parms, PLen, &PLen, (PVOID)arg+4, DLen, &DLen);
if (rc)
{
printf ("DANIS506 ATA GET DSKSP_SMART_GET_ATTRIBUTES failed (%d,0x%x)\n", rc, rc);
return -1;
}
break;
case SMART_READ_THRESHOLDS:
rc = DosDevIOCtl (hDevice, DSKSP_CAT_SMART, DSKSP_SMART_GET_THRESHOLDS,
(PVOID)&Parms, PLen, &PLen, (PVOID)arg+4, DLen, &DLen);
if (rc)
{
printf ("DANIS506 ATA GET DSKSP_SMART_GET_THRESHOLDS failed (%d,0x%x)\n", rc, rc);
return -1;
}
break;
case SMART_READ_LOG_SECTOR:
buff[4] = buff[1]; // copy select field
rc = DosDevIOCtl (hDevice, DSKSP_CAT_SMART, DSKSP_SMART_READ_LOG,
(PVOID)&Parms, PLen, &PLen, (PVOID)arg+4, DLen, &DLen);
if (rc)
{
printf ("DANIS506 ATA GET DSKSP_SMART_READ_LOG failed (%d,0x%x)\n", rc, rc);
return -1;
}
break;
case SMART_ENABLE:
buff[0] = 1; // enable
DLen = 1;
rc = DosDevIOCtl (hDevice, DSKSP_CAT_SMART, DSKSP_SMART_ONOFF,
(PVOID)&Parms, PLen, &PLen, (PVOID)buff, DLen, &DLen);
if (rc) {
printf ("DANIS506 ATA GET DSKSP_SMART_ONOFF failed (%d,0x%x)\n", rc, rc);
return -1;
}
break;
case SMART_DISABLE:
buff[0] = 0; // disable
DLen = 1;
rc = DosDevIOCtl (hDevice, DSKSP_CAT_SMART, DSKSP_SMART_ONOFF,
(PVOID)&Parms, PLen, &PLen, (PVOID)buff, DLen, &DLen);
if (rc) {
printf ("DANIS506 ATA GET DSKSP_SMART_ONOFF failed (%d,0x%x)\n", rc, rc);
return -1;
}
break;
#if 0
case SMART_AUTO_OFFLINE:
buff[0] = buff[3]; // select field
DLen = 1;
rc = DosDevIOCtl (hDevice, DSKSP_CAT_SMART, DSKSP_SMART_AUTO_OFFLINE,
(PVOID)&Parms, PLen, &PLen, (PVOID)buff, DLen, &DLen);
if (rc) {
printf ("DANIS506 ATA GET DSKSP_SMART_ONOFF failed (%d,0x%x)\n", rc, rc);
return -1;
}
break;
#endif
case SMART_AUTOSAVE:
buff[0] = buff[3]; // select field
DLen = 1;
rc = DosDevIOCtl (hDevice, DSKSP_CAT_SMART, DSKSP_SMART_AUTOSAVE_ONOFF,
(PVOID)&Parms, PLen, &PLen, (PVOID)buff, DLen, &DLen);
if (rc) {
printf ("DANIS506 ATA DSKSP_SMART_AUTOSAVE_ONOFF failed (%d,0x%x)\n", rc, rc);
return -1;
}
break;
case SMART_IMMEDIATE_OFFLINE:
buff[0] = buff[1]; // select field
DLen = 1;
rc = DosDevIOCtl (hDevice, DSKSP_CAT_SMART, DSKSP_SMART_EOLI,
(PVOID)&Parms, PLen, &PLen, (PVOID)buff, DLen, &DLen);
if (rc) {
printf ("DANIS506 ATA GET DSKSP_SMART_EXEC_OFFLINE failed (%d,0x%x)\n", rc, rc);
return -1;
}
break;
default:
fprintf( stderr, "device %d, request 0x%x, arg[0] 0x%x, arg[2] 0x%x\n", device, request, buff[0], buff[2]);
fprintf( stderr, "unknown ioctl\n");
return -1;
break;
}
break;
//case WIN_PIDENTIFY:
// break;
default:
fprintf( stderr, "unknown ioctl\n");
return -1;
break;
}
// ok
return 0;
}
// Interface to ATA devices. See os_linux.cpp for the cannonical example.
// DETAILED DESCRIPTION OF ARGUMENTS
// device: is the integer handle provided by deviceopen()
// command: defines the different operations, see atacmds.h
// select: additional input data IF NEEDED (which log, which type of
// self-test).
// data: location to write output data, IF NEEDED (1 or 512 bytes).
// Note: not all commands use all arguments.
// RETURN VALUES (for all commands BUT command==STATUS_CHECK)
// -1 if the command failed
// 0 if the command succeeded,
// RETURN VALUES if command==STATUS_CHECK
// -1 if the command failed OR the disk SMART status can't be determined
// 0 if the command succeeded and disk SMART status is "OK"
// 1 if the command succeeded and disk SMART status is "FAILING"
// huge value of buffer size needed because HDIO_DRIVE_CMD assumes
// that buff[3] is the data size. Since the ATA_SMART_AUTOSAVE and
// ATA_SMART_AUTO_OFFLINE use values of 0xf1 and 0xf8 we need the space.
// Otherwise a 4+512 byte buffer would be enough.
#define STRANGE_BUFFER_LENGTH (4+512*0xf8)
int ata_command_interface(int device, smart_command_set command, int select, char *data){
unsigned char buff[STRANGE_BUFFER_LENGTH];
// positive: bytes to write to caller. negative: bytes to READ from
// caller. zero: non-data command
int copydata=0;
const int HDIO_DRIVE_CMD_OFFSET = 4;
// See struct hd_drive_cmd_hdr in hdreg.h. Before calling ioctl()
// buff[0]: ATA COMMAND CODE REGISTER
// buff[1]: ATA SECTOR NUMBER REGISTER == LBA LOW REGISTER
// buff[2]: ATA FEATURES REGISTER
// buff[3]: ATA SECTOR COUNT REGISTER
// Note that on return:
// buff[2] contains the ATA SECTOR COUNT REGISTER
// clear out buff. Large enough for HDIO_DRIVE_CMD (4+512 bytes)
memset(buff, 0, STRANGE_BUFFER_LENGTH);
//printf( "command, select %d,%d\n", command, select);
buff[0]=ATA_SMART_CMD;
switch (command){
case CHECK_POWER_MODE:
buff[0]=ATA_CHECK_POWER_MODE;
copydata=1;
break;
case READ_VALUES:
buff[2]=ATA_SMART_READ_VALUES;
buff[3]=1;
copydata=512;
break;
case READ_THRESHOLDS:
buff[2]=ATA_SMART_READ_THRESHOLDS;
buff[1]=buff[3]=1;
copydata=512;
break;
case READ_LOG:
buff[2]=ATA_SMART_READ_LOG_SECTOR;
buff[1]=select;
buff[3]=1;
copydata=512;
break;
case WRITE_LOG:
break;
case IDENTIFY:
buff[0]=ATA_IDENTIFY_DEVICE;
buff[3]=1;
copydata=512;
break;
case PIDENTIFY:
buff[0]=ATA_IDENTIFY_PACKET_DEVICE;
buff[3]=1;
copydata=512;
break;
case ENABLE:
buff[2]=ATA_SMART_ENABLE;
buff[1]=1;
break;
case DISABLE:
buff[2]=ATA_SMART_DISABLE;
buff[1]=1;
break;
case STATUS:
case STATUS_CHECK:
// this command only says if SMART is working. It could be
// replaced with STATUS_CHECK below.
buff[2]=ATA_SMART_STATUS;
buff[4]=0;
break;
case AUTO_OFFLINE:
buff[2]=ATA_SMART_AUTO_OFFLINE;
buff[3]=select; // YET NOTE - THIS IS A NON-DATA COMMAND!!
break;
case AUTOSAVE:
buff[2]=ATA_SMART_AUTOSAVE;
buff[3]=select; // YET NOTE - THIS IS A NON-DATA COMMAND!!
break;
case IMMEDIATE_OFFLINE:
buff[2]=ATA_SMART_IMMEDIATE_OFFLINE;
buff[1]=select;
break;
//case STATUS_CHECK:
// // This command uses HDIO_DRIVE_TASK and has different syntax than
// // the other commands.
// buff[1]=ATA_SMART_STATUS;
// break;
default:
pout("Unrecognized command %d in linux_ata_command_interface()\n"
"Please contact " PACKAGE_BUGREPORT "\n", command);
errno=ENOSYS;
return -1;
}
#if 0
// This command uses the HDIO_DRIVE_TASKFILE ioctl(). This is the
// only ioctl() that can be used to WRITE data to the disk.
if (command==WRITE_LOG) {
unsigned char task[sizeof(ide_task_request_t)+512];
ide_task_request_t *reqtask=(ide_task_request_t *) task;
task_struct_t *taskfile=(task_struct_t *) reqtask->io_ports;
int retval;
memset(task, 0, sizeof(task));
taskfile->data = 0;
taskfile->feature = ATA_SMART_WRITE_LOG_SECTOR;
taskfile->sector_count = 1;
taskfile->sector_number = select;
taskfile->low_cylinder = 0x4f;
taskfile->high_cylinder = 0xc2;
taskfile->device_head = 0;
taskfile->command = ATA_SMART_CMD;
reqtask->data_phase = TASKFILE_OUT;
reqtask->req_cmd = IDE_DRIVE_TASK_OUT;
reqtask->out_size = 512;
reqtask->in_size = 0;
// copy user data into the task request structure
memcpy(task+sizeof(ide_task_request_t), data, 512);
if ((retval=dani_ioctl(device, HDIO_DRIVE_TASKFILE, task))) {
if (retval==-EINVAL)
pout("Kernel lacks HDIO_DRIVE_TASKFILE support; compile kernel with CONFIG_IDE_TASKFILE_IO set\n");
return -1;
}
return 0;
}
#endif // 0
// We are now doing the HDIO_DRIVE_CMD type ioctl.
if ((dani_ioctl(device, HDIO_DRIVE_CMD, buff)))
return -1;
// There are two different types of ioctls(). The HDIO_DRIVE_TASK
// one is this:
if (command==STATUS_CHECK){
int retval;
// Cyl low and Cyl high unchanged means "Good SMART status"
if (buff[4]==0)
return 0;
// These values mean "Bad SMART status"
if (buff[4]==1)
return 1;
// We haven't gotten output that makes sense; print out some debugging info
syserror("Error SMART Status command failed");
pout("Please get assistance from " PACKAGE_HOMEPAGE "\n");
return -1;
}
// CHECK POWER MODE command returns information in the Sector Count
// register (buff[3]). Copy to return data buffer.
if (command==CHECK_POWER_MODE)
buff[HDIO_DRIVE_CMD_OFFSET]=buff[2];
// if the command returns data then copy it back
if (copydata)
memcpy(data, buff+HDIO_DRIVE_CMD_OFFSET, copydata);
return 0;
}
int marvell_command_interface(int fd, smart_command_set command, int select, char *data){
unsupported(1);
return -1;
}
int highpoint_command_interface(int fd, smart_command_set command, int select, char *data)
{
unsupported(1);
return -1;
}
// Interface to ATA devices behind 3ware escalade RAID controller
// cards. Same description as ata_command_interface() above except
// that 0 <= disknum <= 15 specifies the ATA disk attached to the
// controller.
int escalade_command_interface(int fd, int disknum, int escalade_type, smart_command_set command, int select, char *data){
unsupported(2);
return -1;
}
// Interface to SCSI devices. See os_linux.c
int do_scsi_cmnd_io(int fd, struct scsi_cmnd_io * iop, int report) {
unsupported(3);
return -ENOSYS;
}

70
os_os2.h Normal file
View File

@ -0,0 +1,70 @@
/*
* os_os2.c
*
* Home page of code is: http://smartmontools.sourceforge.net
*
* Copyright (C) 2004-6 Yuri Dario <smartmontools-support@lists.sourceforge.net>
*
* 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.
*
* You should have received a copy of the GNU General Public License
* (for example COPYING); if not, write to the Free
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef OS_OS2_H_
#define OS_OS2_H_
#define OS_XXXX_H_CVSID "$Id: os_os2.h,v 1.4 2006/04/12 14:54:28 ballen4705 Exp $\n"
// Additional material should start here. Note: to keep the '-V' CVS
// reporting option working as intended, you should only #include
// system include files <something.h>. Local #include files
// <"something.h"> should be #included in os_generic.c
#define INCL_DOS
#include <os2.h>
#include "os_os2\hdreg.h"
#include "os_linux.h"
#pragma pack(1)
#define DSKSP_CAT_SMART 0x80 /* SMART IOCTL category */
#define DSKSP_SMART_ONOFF 0x20 /* turn SMART on or off */
#define DSKSP_SMART_AUTOSAVE_ONOFF 0x21 /* turn SMART autosave on or off */
#define DSKSP_SMART_SAVE 0x22 /* force save of SMART data */
#define DSKSP_SMART_GETSTATUS 0x23 /* get SMART status (pass/fail) */
#define DSKSP_SMART_GET_ATTRIBUTES 0x24 /* get SMART attributes table */
#define DSKSP_SMART_GET_THRESHOLDS 0x25 /* get SMART thresholds table */
#define DSKSP_SMART_READ_LOG 0x26
#define DSKSP_SMART_WRITE_LOG 0x27
#define DSKSP_SMART_READ_LOG_EXT 0x28
#define DSKSP_SMART_WRITE_LOG_EXT 0x29
#define DSKSP_SMART_EOLI 0x30 /* EXECUTE OFF-LINE IMMEDIATE */
#define SMART_CMD_ON 1 /* on value for related SMART functions */
#define SMART_CMD_OFF 0 /* off value for related SMART functions */
#define DSKSP_CAT_GENERIC 0x90 /* generic IOCTL category */
#define DSKSP_GET_INQUIRY_DATA 0x42 /* get ATA/ATAPI inquiry data */
typedef struct _DSKSP_CommandParameters {
BYTE byPhysicalUnit; /* physical unit number 0-n */
/* 0 = 1st disk, 1 = 2nd disk, ...*/
/* 0x80 = Pri/Mas, 0x81=Pri/Sla, 0x82=Sec/Mas,*/
} DSKSP_CommandParameters, *PDSKSP_CommandParameters;
struct SMART_ParamExt {
UCHAR byPhysicalUnit; // 0=Pri/Mas, 1=Pri/Sla, 2=Sec/Mas, etc.
ULONG LogAddress; // valid values 0-255. See ATA/ATPI standard
// for details
ULONG SectorCount; // valid values 0-255 See ATA/ATPI standard
// for details
ULONG reserved; // reserved. must be set to 0
};
#endif /* OS_GENERIC_H_ */

9
os_os2/configure.os2 Normal file
View File

@ -0,0 +1,9 @@
#! /bin/sh
CFLAGS="-s -Zomf -O3 -march=pentium -mcpu=pentium3" \
CXXFLAGS="-s -Zomf -O3 -march=pentium -mcpu=pentium3" \
LDFLAGS="-s -Zmap -Zhigh-mem -Zomf -Zexe -Zstack 0x100" \
LIBS=" -lsyslog -lsocket" \
LN_CP_F="cp.exe" \
RANLIB="echo" \
AR="emxomfar" \
./configure --prefix=/usr/local/smartmontools

333
os_os2/hdreg.h Normal file
View File

@ -0,0 +1,333 @@
#ifndef _LINUX_HDREG_H
#define _LINUX_HDREG_H
/*
* This file contains some defines for the AT-hd-controller.
* Various sources.
*/
#define HD_IRQ 14 /* the standard disk interrupt */
/* ide.c has its own port definitions in "ide.h" */
/* Hd controller regs. Ref: IBM AT Bios-listing */
#define HD_DATA 0x1f0 /* _CTL when writing */
#define HD_ERROR 0x1f1 /* see err-bits */
#define HD_NSECTOR 0x1f2 /* nr of sectors to read/write */
#define HD_SECTOR 0x1f3 /* starting sector */
#define HD_LCYL 0x1f4 /* starting cylinder */
#define HD_HCYL 0x1f5 /* high byte of starting cyl */
#define HD_CURRENT 0x1f6 /* 101dhhhh , d=drive, hhhh=head */
#define HD_STATUS 0x1f7 /* see status-bits */
#define HD_FEATURE HD_ERROR /* same io address, read=error, write=feature */
#define HD_PRECOMP HD_FEATURE /* obsolete use of this port - predates IDE */
#define HD_COMMAND HD_STATUS /* same io address, read=status, write=cmd */
#define HD_CMD 0x3f6 /* used for resets */
#define HD_ALTSTATUS 0x3f6 /* same as HD_STATUS but doesn't clear irq */
/* remainder is shared between hd.c, ide.c, ide-cd.c, and the hdparm utility */
/* Bits of HD_STATUS */
#define ERR_STAT 0x01
#define INDEX_STAT 0x02
#define ECC_STAT 0x04 /* Corrected error */
#define DRQ_STAT 0x08
#define SEEK_STAT 0x10
#define WRERR_STAT 0x20
#define READY_STAT 0x40
#define BUSY_STAT 0x80
/* Values for HD_COMMAND */
#define WIN_RESTORE 0x10
#define WIN_READ 0x20
#define WIN_WRITE 0x30
#define WIN_WRITE_VERIFY 0x3C
#define WIN_VERIFY 0x40
#define WIN_FORMAT 0x50
#define WIN_INIT 0x60
#define WIN_SEEK 0x70
#define WIN_DIAGNOSE 0x90
#define WIN_SPECIFY 0x91 /* set drive geometry translation */
#define WIN_IDLEIMMEDIATE 0xE1 /* force drive to become "ready" */
#define WIN_SETIDLE1 0xE3
#define WIN_SETIDLE2 0x97
#define WIN_STANDBYNOW1 0xE0
#define WIN_STANDBYNOW2 0x94
#define WIN_SLEEPNOW1 0xE6
#define WIN_SLEEPNOW2 0x99
#define WIN_CHECKPOWERMODE1 0xE5
#define WIN_CHECKPOWERMODE2 0x98
#define WIN_DOORLOCK 0xDE /* lock door on removable drives */
#define WIN_DOORUNLOCK 0xDF /* unlock door on removable drives */
#define WIN_MULTREAD 0xC4 /* read sectors using multiple mode */
#define WIN_MULTWRITE 0xC5 /* write sectors using multiple mode */
#define WIN_SETMULT 0xC6 /* enable/disable multiple mode */
#define WIN_IDENTIFY 0xEC /* ask drive to identify itself */
#define WIN_IDENTIFY_DMA 0xEE /* same as WIN_IDENTIFY, but DMA */
#define WIN_SETFEATURES 0xEF /* set special drive features */
#define WIN_READDMA 0xC8 /* read sectors using DMA transfers */
#define WIN_WRITEDMA 0xCA /* write sectors using DMA transfers */
#define WIN_QUEUED_SERVICE 0xA2 /* */
#define WIN_READDMA_QUEUED 0xC7 /* read sectors using Queued DMA transfers */
#define WIN_WRITEDMA_QUEUED 0xCC /* write sectors using Queued DMA transfers */
#define WIN_READ_BUFFER 0xE4 /* force read only 1 sector */
#define WIN_WRITE_BUFFER 0xE8 /* force write only 1 sector */
#define WIN_SMART 0xB0 /* self-monitoring and reporting */
/* Additional drive command codes used by ATAPI devices. */
#define WIN_PIDENTIFY 0xA1 /* identify ATAPI device */
#define WIN_SRST 0x08 /* ATAPI soft reset command */
#define WIN_PACKETCMD 0xA0 /* Send a packet command. */
#define DISABLE_SEAGATE 0xFB
#define EXABYTE_ENABLE_NEST 0xF0
/* WIN_SMART sub-commands */
#define SMART_READ_VALUES 0xd0
#define SMART_READ_THRESHOLDS 0xd1
#define SMART_AUTOSAVE 0xd2
#define SMART_SAVE 0xd3
#define SMART_IMMEDIATE_OFFLINE 0xd4
#define SMART_READ_LOG_SECTOR 0xd5
#define SMART_WRITE_LOG_SECTOR 0xd6
#define SMART_ENABLE 0xd8
#define SMART_DISABLE 0xd9
#define SMART_STATUS 0xda
#define SMART_AUTO_OFFLINE 0xdb
/* WIN_SETFEATURES sub-commands */
#define SETFEATURES_EN_WCACHE 0x02 /* Enable write cache */
#define SETFEATURES_XFER 0x03 /* Set transfer mode */
# define XFER_UDMA_7 0x47 /* 0100|0111 */
# define XFER_UDMA_6 0x46 /* 0100|0110 */
# define XFER_UDMA_5 0x45 /* 0100|0101 */
# define XFER_UDMA_4 0x44 /* 0100|0100 */
# define XFER_UDMA_3 0x43 /* 0100|0011 */
# define XFER_UDMA_2 0x42 /* 0100|0010 */
# define XFER_UDMA_1 0x41 /* 0100|0001 */
# define XFER_UDMA_0 0x40 /* 0100|0000 */
# define XFER_MW_DMA_2 0x22 /* 0010|0010 */
# define XFER_MW_DMA_1 0x21 /* 0010|0001 */
# define XFER_MW_DMA_0 0x20 /* 0010|0000 */
# define XFER_SW_DMA_2 0x12 /* 0001|0010 */
# define XFER_SW_DMA_1 0x11 /* 0001|0001 */
# define XFER_SW_DMA_0 0x10 /* 0001|0000 */
# define XFER_PIO_4 0x0C /* 0000|1100 */
# define XFER_PIO_3 0x0B /* 0000|1011 */
# define XFER_PIO_2 0x0A /* 0000|1010 */
# define XFER_PIO_1 0x09 /* 0000|1001 */
# define XFER_PIO_0 0x08 /* 0000|1000 */
# define XFER_PIO_SLOW 0x00 /* 0000|0000 */
#define SETFEATURES_DIS_DEFECT 0x04 /* Disable Defect Management */
#define SETFEATURES_EN_APM 0x05 /* Enable advanced power management */
#define SETFEATURES_DIS_MSN 0x31 /* Disable Media Status Notification */
#define SETFEATURES_DIS_RLA 0x55 /* Disable read look-ahead feature */
#define SETFEATURES_EN_RI 0x5D /* Enable release interrupt */
#define SETFEATURES_EN_SI 0x5E /* Enable SERVICE interrupt */
#define SETFEATURES_DIS_RPOD 0x66 /* Disable reverting to power on defaults */
#define SETFEATURES_DIS_WCACHE 0x82 /* Disable write cache */
#define SETFEATURES_EN_DEFECT 0x84 /* Enable Defect Management */
#define SETFEATURES_DIS_APM 0x85 /* Disable advanced power management */
#define SETFEATURES_EN_MSN 0x95 /* Enable Media Status Notification */
#define SETFEATURES_EN_RLA 0xAA /* Enable read look-ahead feature */
#define SETFEATURES_PREFETCH 0xAB /* Sets drive prefetch value */
#define SETFEATURES_EN_RPOD 0xCC /* Enable reverting to power on defaults */
#define SETFEATURES_DIS_RI 0xDD /* Disable release interrupt */
#define SETFEATURES_DIS_SI 0xDE /* Disable SERVICE interrupt */
/* WIN_SECURITY sub-commands */
#define SECURITY_SET_PASSWORD 0xBA /* 0xF1 */
#define SECURITY_UNLOCK 0xBB /* 0xF2 */
#define SECURITY_ERASE_PREPARE 0xBC /* 0xF3 */
#define SECURITY_ERASE_UNIT 0xBD /* 0xF4 */
#define SECURITY_FREEZE_LOCK 0xBE /* 0xF5 */
#define SECURITY_DISABLE_PASSWORD 0xBF /* 0xF6 */
/* Bits for HD_ERROR */
#define MARK_ERR 0x01 /* Bad address mark */
#define TRK0_ERR 0x02 /* couldn't find track 0 */
#define ABRT_ERR 0x04 /* Command aborted */
#define MCR_ERR 0x08 /* media change request */
#define ID_ERR 0x10 /* ID field not found */
#define ECC_ERR 0x40 /* Uncorrectable ECC error */
#define BBD_ERR 0x80 /* pre-EIDE meaning: block marked bad */
#define ICRC_ERR 0x80 /* new meaning: CRC error during transfer */
struct hd_geometry {
unsigned char heads;
unsigned char sectors;
unsigned short cylinders;
unsigned long start;
};
/* hd/ide ctl's that pass (arg) ptrs to user space are numbered 0x030n/0x031n */
#define HDIO_GETGEO 0x0301 /* get device geometry */
#define HDIO_GET_UNMASKINTR 0x0302 /* get current unmask setting */
#define HDIO_GET_MULTCOUNT 0x0304 /* get current IDE blockmode setting */
#define HDIO_OBSOLETE_IDENTITY 0x0307 /* OBSOLETE, DO NOT USE: returns 142 bytes */
#define HDIO_GET_KEEPSETTINGS 0x0308 /* get keep-settings-on-reset flag */
#define HDIO_GET_32BIT 0x0309 /* get current io_32bit setting */
#define HDIO_GET_NOWERR 0x030a /* get ignore-write-error flag */
#define HDIO_GET_DMA 0x030b /* get use-dma flag */
#define HDIO_GET_NICE 0x030c /* get nice flags */
#define HDIO_GET_IDENTITY 0x030d /* get IDE identification info */
#define HDIO_DRIVE_RESET 0x031c /* execute a device reset */
#define HDIO_TRISTATE_HWIF 0x031d /* execute a channel tristate */
#ifndef __EMX__
#define HDIO_DRIVE_TASK 0x031e /* execute task and special drive command */
#endif
#define HDIO_DRIVE_CMD 0x031f /* execute a special drive command */
#define HDIO_DRIVE_CMD_AEB HDIO_DRIVE_TASK
/* hd/ide ctl's that pass (arg) non-ptr values are numbered 0x032n/0x033n */
#define HDIO_SET_MULTCOUNT 0x0321 /* change IDE blockmode */
#define HDIO_SET_UNMASKINTR 0x0322 /* permit other irqs during I/O */
#define HDIO_SET_KEEPSETTINGS 0x0323 /* keep ioctl settings on reset */
#define HDIO_SET_32BIT 0x0324 /* change io_32bit flags */
#define HDIO_SET_NOWERR 0x0325 /* change ignore-write-error flag */
#define HDIO_SET_DMA 0x0326 /* change use-dma flag */
#define HDIO_SET_PIO_MODE 0x0327 /* reconfig interface to new speed */
#define HDIO_SCAN_HWIF 0x0328 /* register and (re)scan interface */
#define HDIO_SET_NICE 0x0329 /* set nice flags */
#define HDIO_UNREGISTER_HWIF 0x032a /* unregister interface */
/* BIG GEOMETRY */
struct hd_big_geometry {
unsigned char heads;
unsigned char sectors;
unsigned int cylinders;
unsigned long start;
};
/* hd/ide ctl's that pass (arg) ptrs to user space are numbered 0x033n/0x033n */
#define HDIO_GETGEO_BIG 0x0330 /* */
#define HDIO_GETGEO_BIG_RAW 0x0331 /* */
#define __NEW_HD_DRIVE_ID
/* structure returned by HDIO_GET_IDENTITY, as per ANSI ATA2 rev.2f spec */
struct hd_driveid {
unsigned short config; /* lots of obsolete bit flags */
unsigned short cyls; /* "physical" cyls */
unsigned short reserved2; /* reserved (word 2) */
unsigned short heads; /* "physical" heads */
unsigned short track_bytes; /* unformatted bytes per track */
unsigned short sector_bytes; /* unformatted bytes per sector */
unsigned short sectors; /* "physical" sectors per track */
unsigned short vendor0; /* vendor unique */
unsigned short vendor1; /* vendor unique */
unsigned short vendor2; /* vendor unique */
unsigned char serial_no[20]; /* 0 = not_specified */
unsigned short buf_type;
unsigned short buf_size; /* 512 byte increments; 0 = not_specified */
unsigned short ecc_bytes; /* for r/w long cmds; 0 = not_specified */
unsigned char fw_rev[8]; /* 0 = not_specified */
unsigned char model[40]; /* 0 = not_specified */
unsigned char max_multsect; /* 0=not_implemented */
unsigned char vendor3; /* vendor unique */
unsigned short dword_io; /* 0=not_implemented; 1=implemented */
unsigned char vendor4; /* vendor unique */
unsigned char capability; /* bits 0:DMA 1:LBA 2:IORDYsw 3:IORDYsup*/
unsigned short reserved50; /* reserved (word 50) */
unsigned char vendor5; /* vendor unique */
unsigned char tPIO; /* 0=slow, 1=medium, 2=fast */
unsigned char vendor6; /* vendor unique */
unsigned char tDMA; /* 0=slow, 1=medium, 2=fast */
unsigned short field_valid; /* bits 0:cur_ok 1:eide_ok */
unsigned short cur_cyls; /* logical cylinders */
unsigned short cur_heads; /* logical heads */
unsigned short cur_sectors; /* logical sectors per track */
unsigned short cur_capacity0; /* logical total sectors on drive */
unsigned short cur_capacity1; /* (2 words, misaligned int) */
unsigned char multsect; /* current multiple sector count */
unsigned char multsect_valid; /* when (bit0==1) multsect is ok */
unsigned int lba_capacity; /* total number of sectors */
unsigned short dma_1word; /* single-word dma info */
unsigned short dma_mword; /* multiple-word dma info */
unsigned short eide_pio_modes; /* bits 0:mode3 1:mode4 */
unsigned short eide_dma_min; /* min mword dma cycle time (ns) */
unsigned short eide_dma_time; /* recommended mword dma cycle time (ns) */
unsigned short eide_pio; /* min cycle time (ns), no IORDY */
unsigned short eide_pio_iordy; /* min cycle time (ns), with IORDY */
unsigned short words69_70[2]; /* reserved words 69-70 */
/* HDIO_GET_IDENTITY currently returns only words 0 through 70 */
unsigned short words71_74[4]; /* reserved words 71-74 */
unsigned short queue_depth; /* */
unsigned short words76_79[4]; /* reserved words 76-79 */
unsigned short major_rev_num; /* */
unsigned short minor_rev_num; /* */
unsigned short command_set_1; /* bits 0:Smart 1:Security 2:Removable 3:PM */
unsigned short command_set_2; /* bits 14:Smart Enabled 13:0 zero */
unsigned short cfsse; /* command set-feature supported extensions */
unsigned short cfs_enable_1; /* command set-feature enabled */
unsigned short cfs_enable_2; /* command set-feature enabled */
unsigned short csf_default; /* command set-feature default */
unsigned short dma_ultra; /* */
unsigned short word89; /* reserved (word 89) */
unsigned short word90; /* reserved (word 90) */
unsigned short CurAPMvalues; /* current APM values */
unsigned short word92; /* reserved (word 92) */
unsigned short hw_config; /* hardware config */
unsigned short words94_125[32];/* reserved words 94-125 */
unsigned short last_lun; /* reserved (word 126) */
unsigned short word127; /* reserved (word 127) */
unsigned short dlf; /* device lock function
* 15:9 reserved
* 8 security level 1:max 0:high
* 7:6 reserved
* 5 enhanced erase
* 4 expire
* 3 frozen
* 2 locked
* 1 en/disabled
* 0 capability
*/
unsigned short csfo; /* current set features options
* 15:4 reserved
* 3 auto reassign
* 2 reverting
* 1 read-look-ahead
* 0 write cache
*/
unsigned short words130_155[26];/* reserved vendor words 130-155 */
unsigned short word156;
unsigned short words157_159[3];/* reserved vendor words 157-159 */
unsigned short words160_255[95];/* reserved words 160-255 */
};
/*
* IDE "nice" flags. These are used on a per drive basis to determine
* when to be nice and give more bandwidth to the other devices which
* share the same IDE bus.
*/
#define IDE_NICE_DSC_OVERLAP (0) /* per the DSC overlap protocol */
#define IDE_NICE_ATAPI_OVERLAP (1) /* not supported yet */
#define IDE_NICE_0 (2) /* when sure that it won't affect us */
#define IDE_NICE_1 (3) /* when probably won't affect us much */
#define IDE_NICE_2 (4) /* when we know it's on our expense */
#ifdef __KERNEL__
/*
* These routines are used for kernel command line parameters from main.c:
*/
#include <linux/config.h>
#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE)
int ide_register(int io_port, int ctl_port, int irq);
void ide_unregister(unsigned int);
#endif /* CONFIG_BLK_DEV_IDE || CONFIG_BLK_DEV_IDE_MODULE */
#endif /* __KERNEL__ */
#endif /* _LINUX_HDREG_H */

627
os_qnxnto.cpp Normal file
View File

@ -0,0 +1,627 @@
// This is needed for the various HAVE_* macros and PROJECT_* macros.
#include "config.h"
// These are needed to define prototypes and structures for the
// functions defined below
#include "int64.h"
#include "atacmds.h"
#include "scsicmds.h"
#include "utility.h"
// This is to include whatever structures and prototypes you define in
// os_generic.h
#include "os_qnxnto.h"
// Needed by '-V' option (CVS versioning) of smartd/smartctl. You
// should have one *_H_CVSID macro appearing below for each file
// appearing with #include "*.h" above. Please list these (below) in
// alphabetic/dictionary order.
const char *os_XXXX_c_cvsid="$Id: os_qnxnto.cpp,v 1.1 2007/11/13 14:53:27 jhering Exp $" \
ATACMDS_H_CVSID CONFIG_H_CVSID INT64_H_CVSID OS_QNXNTO_H_CVSID SCSICMDS_H_CVSID UTILITY_H_CVSID;
// This is here to prevent compiler warnings for unused arguments of
// functions.
#define ARGUSED(x) ((void)(x))
// Please eliminate the following block: both the #include and
// the 'unsupported()' function. They are only here to warn
// unsuspecting users that their Operating System is not supported! If
// you wish, you can use a similar warning mechanism for any of the
// functions in this file that you can not (or choose not to)
// implement.
#ifdef HAVE_UNAME
#include <sys/utsname.h>
#endif
//----------------------------------------------------------------------------------------------
// private Functions
static int ata_sense_data(void *sdata,int *error,int *key,int *asc,int *ascq);
static int ata_interpret_sense(struct cam_pass_thru *cpt,void *sense,int *status,int rcount);
static int ata_pass_thru(int fd,struct cam_pass_thru *pcpt);
//----------------------------------------------------------------------------------------------
static void unsupported(){
static int warninggiven;
if (!warninggiven) {
char *osname;
extern unsigned char debugmode;
unsigned char savedebugmode=debugmode;
#ifdef HAVE_UNAME
struct utsname ostype;
uname(&ostype);
osname=ostype.sysname;
#else
osname="host's";
#endif
debugmode=1;
pout("\n"
"############################################################################\n"
"WARNING: smartmontools has not been ported to the %s Operating System.\n"
"Please see the files os_generic.cpp and os_generic.h for porting instructions.\n"
"############################################################################\n\n",
osname);
debugmode=savedebugmode;
warninggiven=1;
}
return;
}
// End of the 'unsupported()' block that you should eliminate.
// print examples for smartctl. You should modify this function so
// that the device paths are sensible for your OS, and to eliminate
// unsupported commands (eg, 3ware controllers).
void print_smartctl_examples(){
printf("=================================================== SMARTCTL EXAMPLES =====\n\n");
#ifdef HAVE_GETOPT_LONG
printf(
" smartctl -a /dev/hd0 (Prints all SMART information)\n\n"
" smartctl --smart=on --offlineauto=on --saveauto=on /dev/hd0\n"
" (Enables SMART on first disk)\n\n"
" smartctl -t long /dev/hd0 (Executes extended disk self-test)\n\n"
" smartctl --attributes --log=selftest --quietmode=errorsonly /dev/hd0\n"
" (Prints Self-Test & Attribute errors)\n"
" smartctl -a --device=3ware,2 /dev/sda\n"
" (Prints all SMART info for 3rd ATA disk on 3ware RAID controller)\n"
);
#else
printf(
" smartctl -a /dev/hd0 (Prints all SMART information)\n"
" smartctl -s on -o on -S on /dev/hd0 (Enables SMART on first disk)\n"
" smartctl -t long /dev/hd0 (Executes extended disk self-test)\n"
" smartctl -A -l selftest -q errorsonly /dev/hd0\n"
" (Prints Self-Test & Attribute errors)\n"
" smartctl -a -d 3ware,2 /dev/sda\n"
" (Prints all SMART info for 3rd ATA disk on 3ware RAID controller)\n"
);
#endif
return;
}
// tries to guess device type given the name (a path). See utility.h
// for return values.
static const char *net_dev_prefix = "/dev/";
static const char *net_dev_ata_disk = "hd";
int guess_device_type (const char* dev_name)
{
int len,dev_prefix_len;
dev_prefix_len=strlen(net_dev_prefix);
if(!dev_name||!(len=strlen(dev_name)))
return(CONTROLLER_UNKNOWN);
if (!strncmp(net_dev_prefix,dev_name,dev_prefix_len))
{
if(len<=dev_prefix_len)
return(CONTROLLER_UNKNOWN);
else
dev_name += dev_prefix_len;
}
if(!strncmp(net_dev_ata_disk,dev_name,strlen(net_dev_ata_disk)))
return(CONTROLLER_ATA);
return(CONTROLLER_UNKNOWN);
}
// makes a list of ATA or SCSI devices for the DEVICESCAN directive of
// smartd. Returns number N of devices, or -1 if out of
// memory. Allocates N+1 arrays: one of N pointers (devlist); the
// other N arrays each contain null-terminated character strings. In
// the case N==0, no arrays are allocated because the array of 0
// pointers has zero length, equivalent to calling malloc(0).
int make_device_names (char*** devlist, const char* name) {
ARGUSED(devlist);
ARGUSED(name);
unsupported();
return 0;
}
// Like open(). Return non-negative integer handle, only used by the
// functions below. type=="ATA" or "SCSI". If you need to store
// extra information about your devices, create a private internal
// array within this file (see os_freebsd.cpp for an example). If you
// can not open the device (permission denied, does not exist, etc)
// set errno as open() does and return <0.
int deviceopen(const char *pathname, char *type)
{
if(!strcmp(type, "ATA"))
return(open(pathname,O_RDWR|O_NONBLOCK));
else
return(-1);
}
// Like close(). Acts only on integer handles returned by
// deviceopen() above.
int deviceclose(int fd)
{
return(close(fd));
}
//----------------------------------------------------------------------------------------------
// Interface to ATA devices. See os_linux.cpp for the cannonical example.
// DETAILED DESCRIPTION OF ARGUMENTS
// device: is the integer handle provided by deviceopen()
// command: defines the different operations, see atacmds.h
// select: additional input data IF NEEDED (which log, which type of
// self-test).
// data: location to write output data, IF NEEDED (1 or 512 bytes).
// Note: not all commands use all arguments.
// RETURN VALUES (for all commands BUT command==STATUS_CHECK)
// -1 if the command failed
// 0 if the command succeeded,
// RETURN VALUES if command==STATUS_CHECK
// -1 if the command failed OR the disk SMART status can't be determined
// 0 if the command succeeded and disk SMART status is "OK"
// 1 if the command succeeded and disk SMART status is "FAILING"
int ata_command_interface(int fd,smart_command_set command,int select,char *data)
{
struct cam_pass_thru cpt;
ATA_SENSE sense;
CDB *cdb;
int status,rc;
memset(&cpt,0x00,sizeof(struct cam_pass_thru));
cdb=(CDB *)cpt.cam_cdb;
rc=-1;
switch(command)
{
case READ_VALUES:
cpt.cam_flags = CAM_DIR_IN;
cpt.cam_cdb_len = 16;
cpt.cam_dxfer_len = 512;
cpt.cam_data_ptr = (uint32_t)data;
cpt.cam_sense_len = sizeof(sense);
cpt.cam_sense_ptr = (uint32_t)&sense;
cdb->ata_pass_thru.opcode = SC_ATA_PT16;
cdb->ata_pass_thru.protocol = ATA_PROTO_PIO_DATA_IN;
cdb->ata_pass_thru.flags = ATA_FLG_T_DIR|ATA_FLG_TLEN_STPSIU;
cdb->ata_pass_thru.command = ATA_SMART_CMD;
cdb->ata_pass_thru.features = ATA_SMART_READ_VALUES;
cdb->ata_pass_thru.lba_mid = ATA_SMART_LBA_MID_SIG;
cdb->ata_pass_thru.lba_high = ATA_SMART_LBA_HI_SIG;
break;
case READ_THRESHOLDS:
cpt.cam_flags = CAM_DIR_IN;
cpt.cam_cdb_len = 16;
cpt.cam_dxfer_len = 512;
cpt.cam_data_ptr = (uint32_t)data;
cpt.cam_sense_len = sizeof(sense);
cpt.cam_sense_ptr = (uint32_t)&sense;
cdb->ata_pass_thru.opcode = SC_ATA_PT16;
cdb->ata_pass_thru.protocol = ATA_PROTO_PIO_DATA_IN;
cdb->ata_pass_thru.flags = ATA_FLG_T_DIR|ATA_FLG_TLEN_STPSIU;
cdb->ata_pass_thru.command = ATA_SMART_CMD;
cdb->ata_pass_thru.features = ATA_SMART_READ_THRESHOLDS;
cdb->ata_pass_thru.lba_mid = ATA_SMART_LBA_MID_SIG;
cdb->ata_pass_thru.lba_high = ATA_SMART_LBA_HI_SIG;
break;
case READ_LOG:
cpt.cam_flags = CAM_DIR_IN;
cpt.cam_cdb_len = 16;
cpt.cam_dxfer_len = 512;
cpt.cam_data_ptr = (uint32_t)data;
cpt.cam_sense_len = sizeof(sense);
cpt.cam_sense_ptr = (uint32_t)&sense;
cdb->ata_pass_thru.opcode = SC_ATA_PT16;
cdb->ata_pass_thru.protocol = ATA_PROTO_PIO_DATA_IN;
cdb->ata_pass_thru.flags = ATA_FLG_T_DIR | ATA_FLG_TLEN_STPSIU;
cdb->ata_pass_thru.command = ATA_SMART_CMD;
cdb->ata_pass_thru.features = ATA_SMART_READ_LOG_SECTOR;
cdb->ata_pass_thru.sector_count= 1;
cdb->ata_pass_thru.lba_low = select;
cdb->ata_pass_thru.lba_mid = ATA_SMART_LBA_MID_SIG;
cdb->ata_pass_thru.lba_high = ATA_SMART_LBA_HI_SIG;
break;
case WRITE_LOG:
return(-1);
break;
case IDENTIFY:
cpt.cam_flags = CAM_DIR_IN;
cpt.cam_cdb_len = 16;
cpt.cam_dxfer_len = 512;
cpt.cam_data_ptr = (uint32_t)data;
cpt.cam_sense_len = sizeof(sense);
cpt.cam_sense_ptr = (uint32_t)&sense;
cdb->ata_pass_thru.opcode = SC_ATA_PT16;
cdb->ata_pass_thru.protocol = ATA_PROTO_PIO_DATA_IN;
cdb->ata_pass_thru.flags = ATA_FLG_T_DIR|ATA_FLG_TLEN_STPSIU;
cdb->ata_pass_thru.command = ATA_IDENTIFY_DEVICE;
break;
case PIDENTIFY:
cpt.cam_flags = CAM_DIR_IN;
cpt.cam_cdb_len = 16;
cpt.cam_dxfer_len = 512;
cpt.cam_data_ptr = (uint32_t)data;
cpt.cam_sense_len = sizeof(sense);
cpt.cam_sense_ptr = (uint32_t)&sense;
cdb->ata_pass_thru.opcode = SC_ATA_PT16;
cdb->ata_pass_thru.protocol = ATA_PROTO_PIO_DATA_IN;
cdb->ata_pass_thru.flags = ATA_FLG_T_DIR|ATA_FLG_TLEN_STPSIU;
cdb->ata_pass_thru.command = ATA_IDENTIFY_PACKET_DEVICE;
break;
case ENABLE:
cpt.cam_flags = CAM_DIR_NONE;
cpt.cam_cdb_len = 16;
cpt.cam_sense_len = sizeof(sense);
cpt.cam_sense_ptr = (uint32_t)&sense;
cdb->ata_pass_thru.opcode = SC_ATA_PT16;
cdb->ata_pass_thru.protocol = ATA_PROTO_DATA_NONE;
cdb->ata_pass_thru.command = ATA_SMART_CMD;
cdb->ata_pass_thru.features = ATA_SMART_ENABLE;
cdb->ata_pass_thru.lba_mid = ATA_SMART_LBA_MID_SIG;
cdb->ata_pass_thru.lba_high = ATA_SMART_LBA_HI_SIG;
break;
case DISABLE:
cpt.cam_flags = CAM_DIR_NONE;
cpt.cam_cdb_len = 16;
cpt.cam_sense_len = sizeof(sense);
cpt.cam_sense_ptr = (uint32_t)&sense;
cdb->ata_pass_thru.opcode = SC_ATA_PT16;
cdb->ata_pass_thru.protocol = ATA_PROTO_DATA_NONE;
cdb->ata_pass_thru.command = ATA_SMART_CMD;
cdb->ata_pass_thru.features = ATA_SMART_DISABLE;
cdb->ata_pass_thru.lba_mid = ATA_SMART_LBA_MID_SIG;
cdb->ata_pass_thru.lba_high = ATA_SMART_LBA_HI_SIG;
break;
case AUTO_OFFLINE:
// NOTE: According to ATAPI 4 and UP, this command is obsolete
cpt.cam_flags = CAM_DIR_NONE;
cpt.cam_cdb_len = 16;
cpt.cam_sense_len = sizeof(sense);
cpt.cam_sense_ptr = (uint32_t)&sense;
cdb->ata_pass_thru.opcode = SC_ATA_PT16;
cdb->ata_pass_thru.protocol = ATA_PROTO_DATA_NONE;
cdb->ata_pass_thru.command = ATA_SMART_CMD;
cdb->ata_pass_thru.features = ATA_SMART_AUTO_OFFLINE;
cdb->ata_pass_thru.lba_low = select;
cdb->ata_pass_thru.lba_mid = ATA_SMART_LBA_MID_SIG;
cdb->ata_pass_thru.lba_high = ATA_SMART_LBA_HI_SIG;
break;
case AUTOSAVE:
cpt.cam_flags = CAM_DIR_NONE;
cpt.cam_cdb_len = 16;
cpt.cam_sense_len = sizeof(sense);
cpt.cam_sense_ptr = (uint32_t)&sense;
cdb->ata_pass_thru.opcode = SC_ATA_PT16;
cdb->ata_pass_thru.protocol = ATA_PROTO_DATA_NONE;
cdb->ata_pass_thru.command = ATA_SMART_CMD;
cdb->ata_pass_thru.features = ATA_SMART_AUTOSAVE;
cdb->ata_pass_thru.sector_count= select;
cdb->ata_pass_thru.lba_mid = ATA_SMART_LBA_MID_SIG;
cdb->ata_pass_thru.lba_high = ATA_SMART_LBA_HI_SIG;
break;
case IMMEDIATE_OFFLINE:
// NOTE: According to ATAPI 4 and UP, this command is obsolete
cpt.cam_flags = CAM_DIR_NONE;
cpt.cam_cdb_len = 16;
cpt.cam_sense_len = sizeof(sense);
cpt.cam_sense_ptr = (uint32_t)&sense;
cdb->ata_pass_thru.opcode = SC_ATA_PT16;
cdb->ata_pass_thru.protocol = ATA_PROTO_DATA_NONE;
cdb->ata_pass_thru.command = ATA_SMART_CMD;
cdb->ata_pass_thru.features = ATA_SMART_IMMEDIATE_OFFLINE;
cdb->ata_pass_thru.lba_low = select;
cdb->ata_pass_thru.lba_mid = ATA_SMART_LBA_MID_SIG;
cdb->ata_pass_thru.lba_high = ATA_SMART_LBA_HI_SIG;
break;
case STATUS_CHECK:
// same command, no HDIO in NetBSD
case STATUS:
cpt.cam_flags = CAM_DIR_NONE;
cpt.cam_cdb_len = 16;
cpt.cam_sense_len = sizeof(sense);
cpt.cam_sense_ptr = (uint32_t)&sense;
cdb->ata_pass_thru.opcode = SC_ATA_PT16;
cdb->ata_pass_thru.protocol = ATA_PROTO_DATA_NONE;
cdb->ata_pass_thru.flags = ATA_FLG_CK_COND;
cdb->ata_pass_thru.command = ATA_SMART_CMD;
cdb->ata_pass_thru.features = ATA_SMART_STATUS;
cdb->ata_pass_thru.lba_mid = ATA_SMART_LBA_MID_SIG;
cdb->ata_pass_thru.lba_high = ATA_SMART_LBA_HI_SIG;
break;
case CHECK_POWER_MODE:
cpt.cam_flags = CAM_DIR_NONE;
cpt.cam_cdb_len = 16;
cpt.cam_sense_len = sizeof(sense);
cpt.cam_sense_ptr = (uint32_t)&sense;
cdb->ata_pass_thru.opcode = SC_ATA_PT16;
cdb->ata_pass_thru.protocol = ATA_PROTO_DATA_NONE;
cdb->ata_pass_thru.flags = ATA_FLG_CK_COND;
cdb->ata_pass_thru.command = ATA_CHECK_POWER_MODE;
break;
default:
pout("Unrecognized command %d in ata_command_interface()\n", command);
errno=ENOSYS;
return(-1);
}
// execute now
if((status=ata_pass_thru(fd,&cpt))==EOK)
if(cpt.cam_status!=CAM_REQ_CMP)
ata_interpret_sense(&cpt,&sense,&status,0);
rc=status==EOK?0:1;
if((command==STATUS||command==STATUS_CHECK)&&status==EOK)
rc=((sense.desc.lba_high<<8)|sense.desc.lba_mid)==ATA_SMART_SIG?0:1;
if(command==CHECK_POWER_MODE)
data[0]=cdb->ata_pass_thru.sector_count;
// finish
return(rc);
}
//----------------------------------------------------------------------------------------------
int marvell_command_interface(int fd, smart_command_set command, int select, char *data)
{
ARGUSED(fd);
ARGUSED(command);
ARGUSED(select);
ARGUSED(data);
unsupported();
return -1;
}
//----------------------------------------------------------------------------------------------
int highpoint_command_interface(int fd, smart_command_set command, int select, char *data)
{
ARGUSED(fd);
ARGUSED(command);
ARGUSED(select);
ARGUSED(data);
unsupported();
return -1;
}
//----------------------------------------------------------------------------------------------
// Interface to ATA devices behind 3ware escalade/apache RAID
// controller cards. Same description as ata_command_interface()
// above except that 0 <= disknum <= 15 specifies the ATA disk
// attached to the controller, and controller_type specifies the
// precise type of 3ware controller. See os_linux.c
int escalade_command_interface(int fd,int disknum,int controller_type,smart_command_set command,int select,char *data)
{
ARGUSED(fd);
ARGUSED(disknum);
ARGUSED(controller_type);
ARGUSED(command);
ARGUSED(select);
ARGUSED(data);
unsupported();
return -1;
}
//----------------------------------------------------------------------------------------------
#include <errno.h>
// Interface to SCSI devices. See os_linux.c
int do_scsi_cmnd_io(int fd,struct scsi_cmnd_io * iop,int report)
{
ARGUSED(fd);
ARGUSED(iop);
ARGUSED(report);
unsupported();
return -ENOSYS;
}
//----------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------
static int ata_sense_data(void *sdata,int *error,int *key,int *asc,int *ascq)
{
SCSI_SENSE *sf;
SCSI_SENSE_DESCRIPTOR *sd;
sf=(SCSI_SENSE *)sdata;
sd=(SCSI_SENSE_DESCRIPTOR *)sdata;
*error=sf->error;
if(*error & SENSE_DATA_FMT_DESCRIPTOR)
{
*key=sd->sense & SK_MSK;
*asc=sd->asc;
*ascq=sd->ascq;
}
else
{
*key=sf->sense & SK_MSK;
*asc=sf->asc;
*ascq=sf->ascq;
}
return(CAM_SUCCESS);
}
//----------------------------------------------------------------------------------------------
static int ata_interpret_sense(struct cam_pass_thru *cpt,void *sense,int *status,int rcount)
{
int retry;
int key;
int asc;
int ascq;
int error;
*status=EIO;
retry=CAM_TRUE;
if(cpt->cam_status&CAM_AUTOSNS_VALID)
{
ata_sense_data(sense,&error,&key,&asc,&ascq);
switch(key)
{
case SK_NO_SENSE: // No sense data (no error)
retry=CAM_FALSE;
*status=EOK;
break;
case SK_RECOVERED: // Recovered error
switch(asc)
{
case ASC_ATA_PASS_THRU:
switch(ascq)
{
case ASCQ_ATA_PASS_THRU_INFO_AVAIL:
break;
default:
break;
}
break;
default:
break;
}
retry=CAM_FALSE;
*status=EOK;
break;
case SK_NOT_RDY: // Device not ready
*status=EAGAIN;
switch(asc)
{
case ASC_NOT_READY:
switch(ascq)
{
case ASCQ_BECOMING_READY:
case ASCQ_CAUSE_NOT_REPORTABLE:
default:
retry=CAM_FALSE;
break;
}
break;
case ASC_MEDIA_NOT_PRESENT:
*status=ENXIO;
retry=CAM_FALSE;
break;
}
break;
case SK_MEDIUM: // Medium error
case SK_HARDWARE: // Hardware error
retry=CAM_FALSE;
*status=EIO;
break;
case SK_ILLEGAL: // Illegal Request (bad command)
retry=CAM_FALSE;
*status=EINVAL;
break;
case SK_UNIT_ATN: // Unit Attention
switch(asc)
{
case ASC_MEDIUM_CHANGED:
*status=ESTALE;
retry=CAM_FALSE;
break;
case ASC_BUS_RESET:
break;
}
break;
case SK_DATA_PROT: // Data Protect
retry=CAM_FALSE;
*status=EROFS;
break;
case SK_VENDOR: // Vendor Specific
case SK_CPY_ABORT: // Copy Aborted
retry=CAM_FALSE;
*status=EIO;
break;
case SK_CMD_ABORT: // Aborted Command
retry=CAM_FALSE;
*status=ECANCELED;
break;
case SK_EQUAL: // Equal
case SK_VOL_OFL: // Volume Overflow
case SK_MISCMP: // Miscompare
case SK_RESERVED: // Reserved
break;
}
if(*status==EOK)
{
switch(cpt->cam_status&CAM_STATUS_MASK)
{
case CAM_REQ_CMP_ERR: // CCB request completed with an err
retry=CAM_FALSE;
*status=EIO;
break;
case CAM_BUSY: // CAM subsystem is busy
*status=EAGAIN;
break;
case CAM_REQ_INVALID: // CCB request is invalid
case CAM_PATH_INVALID: // Path ID supplied is invalid
case CAM_DEV_NOT_THERE: // SCSI device not installed/there
case CAM_SEL_TIMEOUT: // Target selection timeout
case CAM_LUN_INVALID: // LUN supplied is invalid
case CAM_TID_INVALID: // Target ID supplied is invalid
retry=CAM_FALSE;
*status=ENXIO;
break;
case CAM_CMD_TIMEOUT: // Command timeout
*status=rcount?EAGAIN:EIO;
break;
case CAM_MSG_REJECT_REC: // Message reject received
case CAM_SCSI_BUS_RESET: // SCSI bus reset sent/received
case CAM_UNCOR_PARITY: // Uncorrectable parity err occurred
case CAM_AUTOSENSE_FAIL: // Autosense: Request sense cmd fail
case CAM_NO_HBA: // No HBA detected Error
case CAM_DATA_RUN_ERR: // Data overrun/underrun error
retry=CAM_FALSE;
*status=EIO;
break;
case CAM_UNEXP_BUSFREE: // Unexpected BUS free
case CAM_SEQUENCE_FAIL: // Target bus phase sequence failure
*status=EIO;
break;
case CAM_PROVIDE_FAIL: // Unable to provide requ. capability
retry=CAM_FALSE;
*status=ENOTTY;
break;
case CAM_CCB_LEN_ERR: // CCB length supplied is inadequate
case CAM_BDR_SENT: // A SCSI BDR msg was sent to target
case CAM_REQ_TERMIO: // CCB request terminated by the host
case CAM_FUNC_NOTAVAIL: // The requ. func is not available
case CAM_NO_NEXUS: // Nexus is not established
case CAM_IID_INVALID: // The initiator ID is invalid
case CAM_CDB_RECVD: // The SCSI CDB has been received
retry=CAM_FALSE;
*status=EIO;
break;
case CAM_SCSI_BUSY: // SCSI bus busy
*status=EAGAIN;
break;
}
}
}
return(retry);
}
//----------------------------------------------------------------------------------------------
static int ata_pass_thru(int fd,struct cam_pass_thru *pcpt)
{
int icnt;
int status;
iov_t iov[3];
struct cam_pass_thru cpt;
cpt=*pcpt;
icnt=1;
SETIOV(&iov[0],&cpt,sizeof(cpt));
cpt.cam_timeout=cpt.cam_timeout?cpt.cam_timeout:CAM_TIME_DEFAULT;
if(cpt.cam_sense_len)
{
SETIOV(&iov[1],cpt.cam_sense_ptr,cpt.cam_sense_len);
cpt.cam_sense_ptr=sizeof(cpt);
icnt++;
}
if(cpt.cam_dxfer_len)
{
SETIOV(&iov[2],(void *)cpt.cam_data_ptr,cpt.cam_dxfer_len);
cpt.cam_data_ptr=(paddr_t)sizeof(cpt)+cpt.cam_sense_len;
icnt++;
}
if((status=devctlv(fd,DCMD_CAM_PASS_THRU,icnt,icnt,iov,iov,NULL)))
pout("ata_pass_thru devctl: %s\n",strerror(status));
pcpt->cam_status=cpt.cam_status;
pcpt->cam_scsi_status=cpt.cam_scsi_status;
return(status);
}
//----------------------------------------------------------------------------------------------

896
os_qnxnto.h Normal file
View File

@ -0,0 +1,896 @@
/*
* os_generic.h
*
* Home page of code is: http://smartmontools.sourceforge.net
*
* Copyright (C) Joerg Hering <smartmontools-support@lists.sourceforge.net>
* Copyright (C) 2003-6 Bruce Allen <smartmontools-support@lists.sourceforge.net>
*
* 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.
*
* You should have received a copy of the GNU General Public License
* (for example COPYING); if not, write to the Free
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* This code was originally developed as a Senior Thesis by Michael Cornwell
* at the Concurrent Systems Laboratory (now part of the Storage Systems
* Research Center), Jack Baskin School of Engineering, University of
* California, Santa Cruz. http://ssrc.soe.ucsc.edu/
*
*/
#ifndef OS_QNXNTO_H_
#define OS_QNXNTO_H_
#define OS_QNXNTO_H_CVSID "$Id: os_qnxnto.h,v 1.1 2007/11/13 14:53:27 jhering Exp $\n"
// Additional material should start here. Note: to keep the '-V' CVS
// reporting option working as intended, you should only #include
// system include files <something.h>. Local #include files
// <"something.h"> should be #included in os_generic.c
#include <sys/cpt.h>
#ifndef __TYPES_H_INCLUDED
#include <sys/types.h>
#endif
#include <stdio.h>
#include <fcntl.h>
#include <gulliver.h>
#include <sys/cpt.h>
#include <sys/dcmd_cam.h>
#include <sys/cam_device.h>
#include "atacmds.h"
//----------------------------------------------------------------------------------------------------------
typedef struct _ata_pass_thru ATA_PASS_THRU;
typedef struct _eide_identify EIDE_IDENTIFY;
typedef struct _ata_sense ATA_SENSE;
typedef void CCB;
struct _sim_hba;
struct _resmgr_context;
typedef struct _drive_attribute
{
int id;
int threshold;
char *name;
}DRIVE_ATTRIBUTE;
//----------------------------------------------------------------------------------------------------------
/* UNIVOS OSD defines and data structures. */
#define INQLEN 36 /* Inquiry string length to store. */
#define CAM_SUCCESS 0 /* For signaling general success */
#define CAM_FAILURE 1 /* For signaling general failure */
#define CAM_FALSE 0 /* General purpose flag value */
#define CAM_TRUE 1 /* General purpose flag value */
//----------------------------------------------------------------------------------------------------------
// Group 3 and 4, command codes 60H-9FH are reserved
#define SC_ATA_PT16 0x85 // ATA Pass-through
//----------------------------------------------------------------------------------------------------------
#define ATA_SMART_LBA_MID_SIG 0x4f
#define ATA_SMART_LBA_HI_SIG 0xc2
#define ATA_SMART_SIG 0xc24f
//----------------------------------------------------------------------------------------------------------
struct _ata_pass_thru {
uchar_t opcode;
#define ATA_PROTO_MSK 0x1e
#define ATA_PROTO_RESPONSE (15 << 1)
#define ATA_PROTO_FPDMA (12 << 1)
#define ATA_PROTO_UDMA_DATA_OUT (11 << 1)
#define ATA_PROTO_UDMA_DATA_IN (10 << 1)
#define ATA_PROTO_DEVICE_RESET (9 << 1)
#define ATA_PROTO_DEVICE_DIAGNOSTIC (8 << 1)
#define ATA_PROTO_DMA_QUEUED (7 << 1)
#define ATA_PROTO_DMA (6 << 1)
#define ATA_PROTO_PIO_DATA_OUT (5 << 1)
#define ATA_PROTO_PIO_DATA_IN (4 << 1)
#define ATA_PROTO_DATA_NONE (3 << 1)
#define ATA_PROTO_SRST (1 << 1)
#define ATA_PROTO_HRST (0 << 1)
#define ATA_PROTO_EXTEND 0x01
uchar_t protocol; // multiple count, protocol
#define ATA_MCOUNT_MSK 0xe0
#define ATA_FLG_CK_COND 0x20
#define ATA_FLG_T_DIR 0x08 // data from device
#define ATA_FLG_BYT_BLOK 0x04
#define ATA_FLG_TLEN_STPSIU 0x03
#define ATA_FLG_TLEN_SECTOR_COUNT 0x02
#define ATA_FLG_TLEN_FEATURE 0x01
uchar_t flags;
uchar_t efeatures;
uchar_t features;
uchar_t esector_count;
uchar_t sector_count;
uchar_t elba_low;
uchar_t lba_low;
uchar_t elba_mid;
uchar_t lba_mid;
uchar_t elba_high;
uchar_t lba_high;
uchar_t device;
uchar_t command;
uchar_t control;
} ata_pass_thru_;
//----------------------------------------------------------------------------------------------------------
#define SENSE_DATA_FMT_DESCRIPTOR 0x02
// Fixed Format Sense Data Structure
// Note: The field "error" has the following format:
// bit 7 - Address valid bit
// bits 6-4 - Error class
// bits 3-0 - Error code
//
// Error classes 0-6 are vendor unique and also indicate that the
// sense data is in _nonextended_ format. (i.e. not usually used)
// struct _scsi_nonextended_sense {
// uchar_t sd_err;
// ulong_t sd_block_address;
// };
//
// An error class of 7 and an error code of 0 (70H) indicate SCSI-1
// extended sense data format (or SCSI-2 sense data format).
//
// An error class of 7 and an error code of 1 (71H) indicate SCSI-2
// deferred errors.
//
// Error codes 74H to 7EH are reserved and error code 7FH indicates
// a vendor-specific sense data format.
typedef struct _scsi_sense {
uchar_t error; // Error Code
uchar_t segment; // Segment number
uchar_t sense; // Sense key/flags
uchar_t info[4]; // Information (32bit big-endian value)
uchar_t asl; // Additional Sense Length
uchar_t csinfo[4]; // Command-Specific Information
uchar_t asc; // Additional Sense Code
uchar_t ascq; // Additional Sense Code Qualifier
uchar_t fruc; // Field Replaceable Unit Code
uchar_t sks; // Sense Key Specific
ushort_t sks_data; // Sense Key Specific Data (16bit big-endian)
ushort_t asb; // Additional Sense uchar_ts (Max 256-18)
} SCSI_SENSE;
// Descriptor Format Sense Data Structure
// error code of 72 current, 73 deferred
// extended sense data format (or SCSI-2 sense data format).
typedef struct _scsi_sense_descriptor {
uchar_t error; // Error Code
uchar_t sense; // Sense key/flags
uchar_t asc; // Additional Sense Code
uchar_t ascq; // Additional Sense Code Qualifier
uchar_t rsvd[3];
uchar_t asl; // Additional Sense Length
} SCSI_SENSE_DESCRIPTOR;
typedef struct _scsi_sense_desriptor_header {
uchar_t descriptor_type;
uchar_t descriptor_len;
} SCSI_SENSE_DESCRIPTOR_HEADER;
#define SENSE_DTYPE_INFORMATION 0x00
#define SENSE_DTYPE_CSI 0x01 // Command Specific Information
#define SENSE_DTYPE_SKS 0x02 // Sense Key Specific
#define SENSE_DTYPE_FRU 0x03 // Field Replaceable Unit
#define SENSE_DTYPE_STREAM 0x04
#define SENSE_DTYPE_BLOCK 0x05
#define SENSE_DTYPE_OSD_OBJ_IDENT 0x06 // OSD Object Identification
#define SENSE_DTYPE_OSD_INTEGRITY 0x07 // OSD Response Integrity Check Value
#define SENSE_DTYPE_OSD_ATR_IDENT 0x08 // OSD Attribute Identification
#define SENSE_DTYPE_ATA 0x09
typedef struct _ata_status_descriptor {
uchar_t descriptor_type;
#define ATA_SD_DLEN 0x0c
uchar_t descriptor_len; /* 0xc */
#define ATA_SD_FLG_EXTEND 0x01
uchar_t flags;
uchar_t error;
uchar_t esector_count; /* (15:8) */
uchar_t sector_count; /* (7:0) */
uchar_t elba_low; /* (15:8) */
uchar_t lba_low; /* (7:0) */
uchar_t elba_mid; /* (15:8) */
uchar_t lba_mid; /* (7:0) */
uchar_t elba_high; /* (15:8) */
uchar_t lba_high; /* (7:0) */
uchar_t device;
uchar_t status;
} ATA_STATUS_DESCRIPTOR;
//----------------------------------------------------------------------------------------------------------
// Sense Keys
#define SK_MSK 0x0F // mask to sd_sense field for key
#define SK_NO_SENSE 0 // No sense data (no error)
#define ASCQ_FILEMARK_DETECTED 0x01
#define ASCQ_EOPM_DETECTED 0x02 // End of Partition/Medium Detected
#define ASCQ_SETMARK_DETECTED 0x03
#define ASCQ_BOPM_DETECTED 0x04 // Beginning of Partition/Medium Detected
#define SK_RECOVERED 1 // Recovered error
#define ASC_ATA_PASS_THRU 0x00
#define ASCQ_ATA_PASS_THRU_INFO_AVAIL 0x1d
#define SK_NOT_RDY 2 // Device not ready
#define ASC_NO_SEEK_COMPLETE 0x02
#define ASC_NOT_READY 0x04
#define ASCQ_CAUSE_NOT_REPORTABLE 0x00
#define ASCQ_BECOMING_READY 0x01
#define ASCQ_INIT_COMMAND_REQUIRED 0x02
#define ASCQ_MANUAL_INTERVENTION_REQUIRED 0x03
#define ASCQ_FORMAT_IN_PROGRESS 0x04
#define ASCQ_UNKNOWN_CHANGED 0xff // NTO extension for fdc's
#define ASC_MEDIA_FORMAT 0x30 // bad format
#define ASC_MEDIA_NOT_PRESENT 0x3a
#define ASC_NOT_CONFIGURED 0x3e
#define SK_MEDIUM 3 // Medium error
#define ASC_UNRECOVERABLE_READ_ERROR 0x11
#define ASC_RECORD_NOT_FOUND 0x14
#define ASCQ_RECORD_NOT_FOUND 0x01
#define ASC_UNABLE_TO_RECOVER_TOC 0x57
#define ASC_INCOMPATIBLE_MEDIUM 0x64
#define SK_HARDWARE 4 // Hardware error
#define ASC_INTERNAL_TARGET_FAILURE 0x44
#define ASC_MEDIA_LOAD_EJECT_FAILURE 0x53
#define ASCQ_UNRECOVERABLE_CIRC 0x06
#define SK_ILLEGAL 5 // Illegal Request (bad command)
#define ASC_INVALID_COMMAND 0x20
#define ASC_INVALID_FIELD 0x24
#define ASC_INVALID_FIELD_PARAMETER 0x26
#define ASC_COMMAND_SEQUENCE_ERROR 0x2c
#define ASCQ_READ_SCRAMBLED 0x03
#define ASC_ILLEGAL_MODE 0x64
#define ASC_COPY_PROTECTION 0x6f
#define SK_UNIT_ATN 6 // Unit Attention
#define ASC_MEDIUM_CHANGED 0x28
#define ASC_BUS_RESET 0x29
#define ASC_INSUFFICIENT_TIME_FOR_OPERATION 0x2e
#define ASC_OPERATOR_REQUEST 0x5a
#define ASCQ_OPERATOR_MEDIUM_REMOVAL 0x01
#define SK_DATA_PROT 7 // Data Protect
#define ASC_WRITE_PROTECTED 0x27
#define SK_BLNK_CHK 8 // Blank Check
#define SK_VENDOR 9 // Vendor Specific
#define SK_CPY_ABORT 10 // Copy Aborted
#define SK_CMD_ABORT 11 // Aborted Command
#define SK_EQUAL 12 // Equal
#define SK_VOL_OFL 13 // Volume Overflow
#define SK_MISCMP 14 // Miscompare
#define SK_RESERVED 15 // Reserved
//----------------------------------------------------------------------------------------------------------
// Command Descriptor Block structure definitions
// CDB Flags
#define CF_LINK 0x01 // Linked-command indication
#define CF_FLAG 0x02 // Linked-command with flag bit
#define CF_VENDOR0 0x40 // Vendor unique bits
#define CF_VENDOR1 0x80
#define CF_FUA 0x08
#define CF_DPO 0x10
typedef union _cdb {
// generic 6 byte command descriptor block
struct {
uchar_t opcode;
uchar_t lun_opt;
uchar_t lba_byte1;
uchar_t lba_byte0; // LSB
uchar_t transfer_len;
uchar_t control;
} gen6;
// generic 10 byte command descriptor block
struct {
uchar_t opcode;
uchar_t lun_opt;
uchar_t lba_byte3;
uchar_t lba_byte4;
uchar_t lba_byte1;
uchar_t lba_byte0;
uchar_t rsvd;
uchar_t transfer_len[2];
uchar_t control;
} gen10;
// generic 12 byte command descriptor block
struct {
uchar_t opcode;
uchar_t lun_opt;
uchar_t lba_byte3;
uchar_t lba_byte4;
uchar_t lba_byte1;
uchar_t lba_byte0;
uchar_t transfer_len[4];
uchar_t rsvd10;
uchar_t control;
} gen12;
struct _format_unit {
uchar_t op_code;
#define FU_RSVD0 0xc0 // reserved bits
#define FU_FMTDAT 0x10
#define FU_CMPLIST 0x08
uchar_t defect_list_fmt;
uchar_t track_num;
ushort_t interleave;
uchar_t rsvd1[7];
} format_unit;
struct _format_unit_old {
uchar_t op_code;
uchar_t rsvd0;
uchar_t medium_type_code;
uchar_t rsvd1;
uchar_t interleave;
uchar_t rsvd2;
#define FMT_RSVD3 0x80
#define FMT_SECT_SIZE_CD 0x70
#define FMT_IMMED 0x08
#define FMT_HEAD 0x04
#define FMT_ST 0x02
#define FMT_CERT 0x01
uchar_t cert;
uchar_t track_addr;
uchar_t rsvd4[4];
} format_unit_old;
#define RW_OPT_RELADR 0x01
#define RW_OPT_CORRCT 0x02 // Disable Corrections
#define RW_OPT_FUA 0x08 // Force Unit Access
#define RW_OPT_DPO 0x10 // Disable Page Out
struct {
uchar_t opcode;
uchar_t lun_lba;
uchar_t lba[2];
uchar_t transfer_len;
uchar_t control;
} read_write6;
struct {
uchar_t opcode;
uchar_t lun_opt;
uchar_t lba[4];
uchar_t rsvd2;
uchar_t transfer_len[2];
uchar_t control;
} read_write10;
struct {
uchar_t opcode;
uchar_t lun_opt;
uchar_t lba[4];
uchar_t transfer_len[4];
uchar_t rsvd2;
uchar_t control;
} read_write12;
#define MSEL_OPT_PF 0x10 // Page Format
#define MSEL_OPT_SP 0x01 // Save Page
struct {
uchar_t opcode;
uchar_t lun_opt;
uchar_t rsvd2;
uchar_t rsvd3;
uchar_t param_length;
uchar_t control;
} mode_select;
struct {
uchar_t opcode;
uchar_t lun_opt;
uchar_t rsvd2;
uchar_t rsvd3;
uchar_t rsvd4;
uchar_t rsvd5;
uchar_t rsvd6;
uchar_t param_length[2];
uchar_t control;
} mode_select10;
struct {
uchar_t opcode;
#define LS_OPT_SP 0x01 // Save Parameters
#define LS_OPT_PCR 0x02 // Parameter Code Reset
uchar_t lun_opt;
#define LS_PC_CUR_THRESHOLD 0x00
#define LS_PC_CUR_CUMULATIVE 0x01
#define LS_PC_DFLT_THRESHOLD 0x02
#define LS_PC_DFLT_CUMULATIVE 0x03
uchar_t pc; // Page Control
uchar_t rsvd3;
uchar_t rsvd4;
uchar_t rsvd5;
uchar_t rsvd6;
uchar_t param_length[2];
uchar_t control;
} log_select;
struct {
uchar_t opcode;
#define MSNS_OPT_DBD 0x08 // Disable Block Descriptors
uchar_t lun_opt;
#define PC_CURRENT 0x00
#define PC_CHANGEABLE 0x40
#define PC_DEFAULT 0x80
#define PC_SAVED 0xC0
#define PC_MSK 0xC0
uchar_t pc_page;
uchar_t subpage;
uchar_t allocation_length;
uchar_t control;
} mode_sense;
struct _mode_sense10 {
uchar_t opcode;
uchar_t lun_opt;
uchar_t pc_page;
uchar_t subpage;
uchar_t rsvd4;
uchar_t rsvd5;
uchar_t rsvd6;
uchar_t allocation_length[2];
uchar_t control;
} mode_sense10;
struct {
uchar_t opcode;
uchar_t lun_opt;
uchar_t pc_page;
uchar_t rsvd3;
uchar_t rsvd4;
uchar_t parameter_pointer[2];
uchar_t allocation_length[2];
uchar_t control;
} log_sense;
struct {
uchar_t opcode;
uchar_t lun_opt;
uchar_t rsvd2;
uchar_t rsvd3;
uchar_t prevent;
uchar_t control;
} removal;
struct {
uchar_t opcode;
#define LD_OPT_IMMED 0x01
uchar_t lun_opt;
uchar_t rsvd2;
uchar_t rsvd3;
#define LD_CMD_START 0x01
#define LD_CMD_LOEJ 0x02
#define LD_CMD_STOP 0x00
#define LD_CMD_EJECT 0x02
#define LD_CMD_LOAD 0x03
// Sequential-Access
#define LD_CMD_SA_HOLD 0x08
#define LD_CMD_SA_EOT 0x04
#define LD_CMD_SA_RT 0x02 // re-tension
#define LD_CMD_SA_LOEJ 0x01
// Block
#define LD_CMD_PC_MSK 0xf0
#define LD_CMD_PC_NC 0
#define LD_CMD_PC_ACTIVE 1
#define LD_CMD_PC_IDLE 2
#define LD_CMD_PC_STANDBY 3
#define LD_CMD_PC_SLEEP 5
uchar_t cmd;
uchar_t control;
} load;
struct {
uchar_t opcode;
uchar_t lun_opt;
#define SC_OPT_RELADR 0x01
#define SC_OPT_IMMED 0x02
uchar_t lba[4];
uchar_t num_blocks[2];
uchar_t control;
} synchronize_cache;
// cdrom commands
struct {
uchar_t opcode;
uchar_t rsvd1;
uchar_t rsvd2;
uchar_t rsvd3;
uchar_t rsvd4;
uchar_t rsvd5;
uchar_t rsvd6;
uchar_t allocation_length[2];
uchar_t control;
} read_disc_information;
struct {
uchar_t opcode;
uchar_t lun_opt;
uchar_t rsvd2;
uchar_t rsvd3;
uchar_t rsvd4;
uchar_t rsvd5;
uchar_t rsvd6;
uchar_t rsvd7;
uchar_t resume;
uchar_t control;
} pause_resume;
struct {
uchar_t opcode;
uchar_t lun_opt;
uchar_t rsvd2;
uchar_t start_minute;
uchar_t start_second;
uchar_t start_frame;
uchar_t end_minute;
uchar_t end_second;
uchar_t end_frame;
uchar_t control;
} play_audio_msf;
struct {
uchar_t opcode;
uchar_t lun_opt;
uchar_t rsvd2;
uchar_t rsvd3;
uchar_t start_track;
uchar_t start_index;
uchar_t rsvd6;
uchar_t end_track;
uchar_t end_index;
uchar_t control;
} play_audio_ti;
struct {
uchar_t opcode;
#define CD_SCAN_DIR_FORWARD 0x00
#define CD_SCAN_DIR_REVERSE 0x10
uchar_t opt;
uchar_t start_address[4];
#define CD_SCAN_TYPE_LBA 0x00
#define CD_SCAN_TYPE_MSF 0x40
#define CD_SCAN_TYPE_TRK 0x80
#define CD_SCAN_TYPE_MSK 0xc0
uchar_t rsvd6;
uchar_t rsvd7;
uchar_t rsvd8;
uchar_t type;
uchar_t rsvd10;
uchar_t rsvd11;
} cd_scan;
struct {
uchar_t opcode;
#define RTOC_OPT_MSF 0x02
uchar_t lun_opt;
#define RTOC_FMT_TOC 0x0
#define RTOC_FMT_SESSION 0x1
#define RTOC_FMT_QSUBCODE 0x2
#define RTOC_FMT_QSUBCHNL 0x3
#define RTOC_FMT_ATIP 0x4
#define RTOC_FMT_CDTEXT 0x5
uchar_t format;
uchar_t rsvd3;
uchar_t rsvd4;
uchar_t rsvd5;
uchar_t start_track;
uchar_t allocation_length[2];
#define RTOC_CNTL_FMT_SESSION 0x40
uchar_t control_format;
} read_toc;
struct {
uchar_t opcode;
uchar_t lun_opt;
uchar_t rsvd2[6];
uchar_t allocation_length[2];
uchar_t rsvd3[2];
} mechanism_status;
struct {
uchar_t opcode;
#define EXCHANGE_OPT_IMMED 0x01
uchar_t lun_opt;
uchar_t rsvd2;
uchar_t rsvd3;
#define EXCHANGE_CMD_START 0x01
#define EXCHANGE_CMD_LOEJ 0x02
uchar_t cmd;
uchar_t rsvd5;
uchar_t rsvd6;
uchar_t rsvd7;
uchar_t slot;
uchar_t rsvd9;
uchar_t rsvd10;
uchar_t rsvd11;
} exchange;
struct {
uchar_t opcode;
uchar_t rt;
uchar_t feature_number[2];
uchar_t rsvd4;
uchar_t rsvd5;
uchar_t rsvd6;
uchar_t allocation_length[2];
uchar_t control;
} get_configuration;
struct {
uchar_t opcode;
#define GE_OPT_POLLED 0x01
uchar_t opt;
uchar_t rsvd2;
uchar_t rsvd3;
#define NCR_OPERATIONAL_CHANGE 0x02
#define NCR_POWER_MANAGEMENT 0x04
#define NCR_EXTERNAL_REQUEST 0x08
#define NCR_MEDIA 0x10
#define NCR_MULTI_INITIATOR 0x20
#define NCR_DEVICE_BUSY 0x40
uchar_t ncr; // notification class request
uchar_t rsvd5;
uchar_t rsvd6;
uchar_t allocation_length[2];
uchar_t control;
} get_event;
struct {
uchar_t opcode;
uchar_t lun_opt;
uchar_t rsvd2;
uchar_t rsvd3;
uchar_t rsvd4;
uchar_t rsvd5;
uchar_t rsvd6;
uchar_t allocation_length[2];
uchar_t control;
} read_formated_capacities;
struct {
uchar_t opcode;
uchar_t lun_opt;
uchar_t read_speed[2];
uchar_t write_speed[2];
uchar_t rsvd2[6];
} cd_speed;
struct {
uchar_t opcode;
#define RSCHNL_OPT_MSF 0x02
uchar_t lun_opt;
#define RSCHNL_DATA_SUBQ 0x40
uchar_t data;
uchar_t data_format;
uchar_t rsvd4;
uchar_t rsvd5;
uchar_t track;
uchar_t allocation_length[2];
uchar_t control;
} read_subchannel;
#define CD_FRAME_SYNC_SIZE 12
#define CD_FRAME_HDR_SIZE 4
#define CD_FRAME_SUB_HDR_SIZE 8
#define CD_FRAME_EDC_SIZE 4
#define CD_FRAME_ECC_SIZE 276
#define CD_FRAME_AUX_SIZE 8
#define CD_FRAME_ZERO_SIZE 8
#define CD_FRAME_SPARE_SIZE 4
#define CD_FRAME_C2_ERR_SIZE 294
#define CD_FRAME_BLOCK_ERR_SIZE 2
struct {
uchar_t opcode;
uchar_t lun_stype;
// expected sector type
#define RDCD_EST_ANY_SECTOR (0 << 2)
#define RDCD_EST_CDDA_SECTOR (1 << 2)
#define RDCD_EST_YELLOW_MODE1_SECTOR (2 << 2)
#define RDCD_EST_YELLOW_MODE2_SECTOR (3 << 2)
#define RDCD_EST_XA_SECTOR (4 << 2)
#define RDCD_EST_XA_FORM2_SECTOR (5 << 2)
#define RDCD_EST_MSK (7 << 2)
uchar_t lba[4];
uchar_t transfer_len[3];
uchar_t flags;
#define RDCD_FLG_SYNC 0x80
#define RDCD_FLG_UDATA 0x10
#define RDCD_FLG_ECC 0x08
#define RDCD_FLG_CD_ERR 0x02
#define RDCD_FLG_CD_BLOCK_ERR 0x04
#define RDCD_FLG_HC_NONE ( 0x00 << 5 )
#define RDCD_FLG_HC_HDR ( 0x01 << 5 )
#define RDCD_FLG_HC_SUBHEADER ( 0x02 << 5 )
#define RDCD_FLG_HC_ALL_HEADERS ( 0x03 << 5 )
uchar_t subch_selection;
uchar_t rsvd3;
} read_cd;
struct {
uchar_t opcode;
uchar_t lun_stype;
uchar_t rsvd2;
uchar_t start_minute;
uchar_t start_second;
uchar_t start_frame;
uchar_t end_minute;
uchar_t end_second;
uchar_t end_frame;
uchar_t flags;
uchar_t subch_selection;
uchar_t rsvd11;
} read_cd_msf;
struct _ata_pass_thru {
uchar_t opcode;
#define ATA_PROTO_MSK 0x1e
#define ATA_PROTO_RESPONSE (15 << 1)
#define ATA_PROTO_FPDMA (12 << 1)
#define ATA_PROTO_UDMA_DATA_OUT (11 << 1)
#define ATA_PROTO_UDMA_DATA_IN (10 << 1)
#define ATA_PROTO_DEVICE_RESET (9 << 1)
#define ATA_PROTO_DEVICE_DIAGNOSTIC (8 << 1)
#define ATA_PROTO_DMA_QUEUED (7 << 1)
#define ATA_PROTO_DMA (6 << 1)
#define ATA_PROTO_PIO_DATA_OUT (5 << 1)
#define ATA_PROTO_PIO_DATA_IN (4 << 1)
#define ATA_PROTO_DATA_NONE (3 << 1)
#define ATA_PROTO_SRST (1 << 1)
#define ATA_PROTO_HRST (0 << 1)
#define ATA_PROTO_EXTEND 0x01
uchar_t protocol; // multiple count, protocol
#define ATA_MCOUNT_MSK 0xe0
#define ATA_FLG_CK_COND 0x20
#define ATA_FLG_T_DIR 0x08 // data from device
#define ATA_FLG_BYT_BLOK 0x04
#define ATA_FLG_TLEN_STPSIU 0x03
#define ATA_FLG_TLEN_SECTOR_COUNT 0x02
#define ATA_FLG_TLEN_FEATURE 0x01
uchar_t flags;
uchar_t efeatures;
uchar_t features;
uchar_t esector_count;
uchar_t sector_count;
uchar_t elba_low;
uchar_t lba_low;
uchar_t elba_mid;
uchar_t lba_mid;
uchar_t elba_high;
uchar_t lba_high;
uchar_t device;
uchar_t command;
uchar_t control;
} ata_pass_thru;
// sequential access commands
struct {
uchar_t opcode;
#define ERASE_OPT_LONG 0x01
uchar_t opt;
uchar_t rsvd[3];
uchar_t control;
} erase;
struct {
uchar_t opcode;
#define LOCATE_OPT_CP 0x2
#define LOCATE_OPT_BT 0x4
uchar_t opt;
uchar_t rsvd2;
uchar_t ba[4]; // block address
uchar_t rsvd7;
uchar_t partition;
uchar_t control;
} locate;
struct {
uchar_t opcode;
uchar_t opt;
uchar_t rsvd2[3];
uchar_t control;
} read_block_limits;
#define RP_OPT_BT 0x01 // block address type
#define RP_OPT_LNG 0x02 // long format
#define RP_OPT_TCLP 0x04 // total current logical position
struct {
uchar_t opcode;
uchar_t lun_opt;
uchar_t rsvd2[7];
uchar_t control;
} read_position;
#define SRW_OPT_FIXED 0x01
#define SRW_OPT_SILI 0x02
struct {
uchar_t opcode;
uchar_t opt;
uchar_t transfer_len[3];
uchar_t control;
} sa_read_write;
struct {
uchar_t opcode;
uchar_t opt;
uchar_t rsvd[3];
uchar_t control;
} rewind;
struct {
uchar_t opcode;
#define SPACE_CODE_BLOCKS 0x00
#define SPACE_CODE_FMRKS 0x01
#define SPACE_CODE_SEQ_FMRKS 0x02
#define SPACE_CODE_EOD 0x03
#define SPACE_CODE_SMRKS 0x04
#define SPACE_CODE_SEQ_SMRKS 0x05
uchar_t lun_code;
uchar_t count[3];
uchar_t control;
} space;
struct {
uchar_t opcode;
#define WF_OPT_IMMED 0x01
#define WF_OPT_WSMK 0x02
uchar_t opt;
uchar_t transfer_length[3];
uchar_t control;
} write_filemarks;
struct {
uchar_t opcode;
#define RD_OPT_MEDIA 0x01
uchar_t opt;
uchar_t rsvd[5];
uchar_t allocation_length[2];
uchar_t control;
} report_density;
struct {
uchar_t opcode;
#define FM_OPT_IMMED 0x01
#define FM_OPT_VERIFY 0x02
uchar_t opt;
#define FM_FMT_DFLT 0x00
#define FM_FMT_PARTITION 0x01
#define FM_FMT_FORMAT_PARTITION 0x02
uchar_t format;
uchar_t transfer_length[2];
uchar_t control;
} format_media;
} CDB;
//----------------------------------------------------------------------------------------------------------
struct _ata_sense
{
SCSI_SENSE_DESCRIPTOR sense;
ATA_STATUS_DESCRIPTOR desc;
};
//----------------------------------------------------------------------------------------------------------
#endif /* OS_QNXNTO_H_ */

View File

@ -39,9 +39,9 @@
extern long long bytes;
static const char *filenameandversion="$Id: os_solaris.cpp,v 1.28 2006/08/25 06:06:25 sxzzsf Exp $";
static const char *filenameandversion="$Id: os_solaris.cpp,v 1.29 2007/05/09 19:01:32 dpgilbert Exp $";
const char *os_XXXX_c_cvsid="$Id: os_solaris.cpp,v 1.28 2006/08/25 06:06:25 sxzzsf Exp $" \
const char *os_XXXX_c_cvsid="$Id: os_solaris.cpp,v 1.29 2007/05/09 19:01:32 dpgilbert Exp $" \
ATACMDS_H_CVSID CONFIG_H_CVSID INT64_H_CVSID OS_SOLARIS_H_CVSID SCSICMDS_H_CVSID UTILITY_H_CVSID;
// The printwarning() function warns about unimplemented functions
@ -369,37 +369,35 @@ int escalade_command_interface(int fd, int disknum, int escalade_type, smart_com
#include <sys/scsi/impl/uscsi.h>
// Interface to SCSI devices. See os_linux.c
int do_scsi_cmnd_io(int fd, struct scsi_cmnd_io * iop, int report) {
int do_scsi_cmnd_io(int fd, struct scsi_cmnd_io * iop, int report)
{
struct uscsi_cmd uscsi;
if (report > 0) {
int k;
const unsigned char * ucp = iop->cmnd;
const char * np;
if (report > 0) {
int k;
const unsigned char * ucp = iop->cmnd;
const char * np;
np = scsi_get_opcode_name(ucp[0]);
pout(" [%s: ", np ? np : "<unknown opcode>");
for (k = 0; k < (int)iop->cmnd_len; ++k)
pout("%02x ", ucp[k]);
if ((report > 1) &&
(DXFER_TO_DEVICE == iop->dxfer_dir) && (iop->dxferp)) {
int trunc = (iop->dxfer_len > 256) ? 1 : 0;
np = scsi_get_opcode_name(ucp[0]);
pout(" [%s: ", np ? np : "<unknown opcode>");
for (k = 0; k < (int)iop->cmnd_len; ++k)
pout("%02x ", ucp[k]);
pout("]\n");
if ((report > 1) &&
(DXFER_TO_DEVICE == iop->dxfer_dir) && (iop->dxferp)) {
int trunc = (iop->dxfer_len > 256) ? 1 : 0;
pout("]\n Outgoing data, len=%d%s:\n", (int)iop->dxfer_len,
(trunc ? " [only first 256 bytes shown]" : ""));
dStrHex((char *)iop->dxferp, (trunc ? 256 : iop->dxfer_len) , 1);
}
else
pout("]");
pout(" Outgoing data, len=%d%s:\n", (int)iop->dxfer_len,
(trunc ? " [only first 256 bytes shown]" : ""));
dStrHex((char *)iop->dxferp, (trunc ? 256 : iop->dxfer_len) , 1);
}
}
memset(&uscsi, 0, sizeof (uscsi));
uscsi.uscsi_cdb = reinterpret_cast<char*>(iop->cmnd);
uscsi.uscsi_cdblen = iop->cmnd_len;
if (iop->timeout == 0)
uscsi.uscsi_timeout = 60; /* XXX */
uscsi.uscsi_timeout = 60; /* 60 seconds */
else
uscsi.uscsi_timeout = iop->timeout;
uscsi.uscsi_bufaddr = reinterpret_cast<char*>(iop->dxferp);
@ -418,23 +416,46 @@ int do_scsi_cmnd_io(int fd, struct scsi_cmnd_io * iop, int report) {
default:
return -EINVAL;
}
uscsi.uscsi_flags |= USCSI_ISOLATE;
uscsi.uscsi_flags |= (USCSI_ISOLATE | USCSI_RQENABLE);
if (ioctl(fd, USCSICMD, &uscsi))
return -errno;
if (ioctl(fd, USCSICMD, &uscsi)) {
int err = errno;
if (! ((EIO == err) && uscsi.uscsi_status))
return -err;
/* errno is set to EIO when a non-zero SCSI completion status given */
}
iop->scsi_status = uscsi.uscsi_status;
iop->resid = uscsi.uscsi_resid;
iop->resp_sense_len = iop->max_sense_len - uscsi.uscsi_rqresid;
if (report > 0) {
int trunc = (iop->dxfer_len > 256) ? 1 : 0;
pout(" status=0\n");
int trunc;
int len = iop->resp_sense_len;
pout(" Incoming data, len=%d%s:\n", (int)iop->dxfer_len,
(trunc ? " [only first 256 bytes shown]" : ""));
dStrHex((char *)iop->dxferp, (trunc ? 256 : iop->dxfer_len) , 1);
if ((SCSI_STATUS_CHECK_CONDITION == iop->scsi_status) &&
iop->sensep && (len > 3)) {
pout(" status=0x%x: sense_key=0x%x asc=0x%x ascq=0x%x\n",
iop->scsi_status, iop->sensep[2] & 0xf,
iop->sensep[12], iop->sensep[13]);
if (report > 1) {
pout(" >>> Sense buffer, len=%d:\n", len);
dStrHex((const char *)iop->sensep, ((len > 252) ? 252 : len) , 1);
}
} else if (iop->scsi_status)
pout(" status=%x\n", iop->scsi_status);
if (iop->resid)
pout(" dxfer_len=%d, resid=%d\n", iop->dxfer_len, iop->resid);
if (report > 1) {
len = iop->dxfer_len - iop->resid;
if (len > 0) {
trunc = (len > 256) ? 1 : 0;
pout(" Incoming data, len=%d%s:\n", len,
(trunc ? " [only first 256 bytes shown]" : ""));
dStrHex((char *)iop->dxferp, (trunc ? 256 : len) , 1);
}
}
}
return (0);
return 0;
}

File diff suppressed because it is too large Load Diff

17
os_win32/.cvsignore Normal file
View File

@ -0,0 +1,17 @@
config.h
config_vc6.h
smartctl.d
smartctl.r
smartctl.exe
smartctl_vc6.plg
smartd.d
smartd.r
smartd.exe
smartd_vc6.plg
smartmontools_vc6.ncb
smartmontools_vc6.opt
syslogevt.d
syslogevt.r
syslogevt.exe
syslogevt.h
syslogevt_vc6.plg

View File

@ -1,14 +1,14 @@
;
; installer.nsi - NSIS install script for smartmontools
;
; Copyright (C) 2006 Christian Franke <smartmontools-support@lists.sourceforge.net>
; Copyright (C) 2006-7 Christian Franke <smartmontools-support@lists.sourceforge.net>
;
; Project home page is: http://smartmontools.sourceforge.net
;
; Download and install NSIS from: http://nsis.sourceforge.net/Download
; Process with makensis to create installer (tested with NSIS 2.17).
; Process with makensis to create installer (tested with NSIS 2.29)
;
; $Id: installer.nsi,v 1.2 2006/07/17 20:51:22 chrfranke Exp $
; $Id: installer.nsi,v 1.3 2007/08/19 14:57:05 chrfranke Exp $
;
@ -37,6 +37,7 @@ InstallColors /windows
InstallDir "$PROGRAMFILES\smartmontools"
InstallDirRegKey HKLM "Software\smartmontools" "Install_Dir"
Var UBCDDIR
LicenseData "${INPDIR}\doc\COPYING.txt"
@ -45,7 +46,12 @@ LicenseData "${INPDIR}\doc\COPYING.txt"
Page license
Page components
Page directory
Page directory SkipProgPath "" ""
PageEx directory
PageCallbacks SkipUBCDPath "" ""
DirText "Setup will install the UBCD4Win plugin in the following folder."
DirVar $UBCDDIR
PageExEnd
Page instfiles
UninstPage uninstConfirm
@ -53,14 +59,16 @@ UninstPage instfiles
InstType "Full"
InstType "Extract files only"
InstType "Drive menu"
InstType "UBCD4Win plugin"
;--------------------------------------------------------------------
; Sections
SectionGroup "Program files"
SectionGroup "!Program files"
Section "smartctl"
Section "smartctl" SMARTCTL_SECTION
SectionIn 1 2
@ -69,11 +77,19 @@ SectionGroup "Program files"
SectionEnd
Section "smartd"
Section "smartd" SMARTD_SECTION
SectionIn 1 2
SetOutPath "$INSTDIR\bin"
; Stop service ?
StrCpy $1 ""
IfFileExists "$INSTDIR\bin\smartd.exe" 0 nosrv
ReadRegStr $0 HKLM "System\CurrentControlSet\Services\smartd" "ImagePath"
StrCmp $0 "" nosrv
ExecWait "net stop smartd" $1
nosrv:
File "${INPDIR}\bin\smartd.exe"
IfFileExists "$INSTDIR\bin\smartd.conf" 0 +2
@ -83,11 +99,16 @@ SectionGroup "Program files"
IfFileExists "$WINDIR\system32\cmd.exe" 0 +2
File /nonfatal "${INPDIR}\bin\syslogevt.exe"
; Restart service ?
StrCmp $1 "0" 0 +3
MessageBox MB_YESNO|MB_ICONQUESTION|MB_DEFBUTTON2 "Restart smartd service ?" IDYES 0 IDNO +2
ExecWait "net start smartd"
SectionEnd
SectionGroupEnd
Section "Documentation"
Section "!Documentation" DOC_SECTION
SectionIn 1 2
@ -110,7 +131,7 @@ Section "Documentation"
SectionEnd
Section "Uninstaller"
Section "Uninstaller" UNINST_SECTION
SectionIn 1
AddSize 35
@ -122,14 +143,19 @@ Section "Uninstaller"
; Write uninstall keys and program
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\smartmontools" "DisplayName" "smartmontools"
;WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\smartmontools" "Publisher" "smartmontools"
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\smartmontools" "UninstallString" '"$INSTDIR\uninst-smartmontools.exe"'
;WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\smartmontools" "URLInfoAbout" "http://smartmontools.sourceforge.net/"
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\smartmontools" "HelpLink" "http://smartmontools.sourceforge.net/"
;WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\smartmontools" "URLUpdateInfo" "http://sourceforge.net/project/showfiles.php?group_id=64297"
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\smartmontools" "URLUpdateInfo" "http://smartmontools-win32.dyndns.org/"
WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\smartmontools" "NoModify" 1
WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\smartmontools" "NoRepair" 1
WriteUninstaller "uninst-smartmontools.exe"
SectionEnd
Section "Start Menu Shortcuts"
Section "Start Menu Shortcuts" MENU_SECTION
SectionIn 1
@ -139,26 +165,27 @@ Section "Start Menu Shortcuts"
IfFileExists "$INSTDIR\bin\smartctl.exe" 0 noctl
SetOutPath "$INSTDIR\bin"
DetailPrint "Create file: $INSTDIR\bin\smartctl-run.bat"
FileOpen $0 "$INSTDIR\bin\smartctl-run.bat" "w"
FileWrite $0 "@echo off$\r$\necho smartctl %1 %2 %3 %4 %5$\r$\nsmartctl %1 %2 %3 %4 %5$\r$\npause$\r$\n"
FileClose $0
Push "$INSTDIR\bin\smartctl-run.bat"
Call CreateSmartctlBat
IfFileExists "$WINDIR\system32\cmd.exe" 0 +2
CreateShortCut "$SMPROGRAMS\smartmontools\smartctl (CMD).lnk" "cmd.exe" "/k smartctl-run.bat"
CreateDirectory "$SMPROGRAMS\smartmontools\smartctl Examples"
FileOpen $0 "$SMPROGRAMS\smartmontools\smartctl Examples\!Read this first!.txt" "w"
FileWrite $0 "All the example commands in this directory$\r$\napply to the first IDE/ATA/SATA drive (hda).$\r$\n"
FileWrite $0 "All the example commands in this directory$\r$\napply to the first drive (sda).$\r$\n"
FileClose $0
CreateShortCut "$SMPROGRAMS\smartmontools\smartctl Examples\All info (-a).lnk" "$INSTDIR\bin\smartctl-run.bat" "-a hda"
CreateShortCut "$SMPROGRAMS\smartmontools\smartctl Examples\Identify drive (-i).lnk" "$INSTDIR\bin\smartctl-run.bat" "-i hda"
CreateShortCut "$SMPROGRAMS\smartmontools\smartctl Examples\SMART attributes (-A).lnk" "$INSTDIR\bin\smartctl-run.bat" "-A hda"
CreateShortCut "$SMPROGRAMS\smartmontools\smartctl Examples\SMART capabilities (-c).lnk" "$INSTDIR\bin\smartctl-run.bat" "-c hda"
CreateShortCut "$SMPROGRAMS\smartmontools\smartctl Examples\SMART health status (-H).lnk" "$INSTDIR\bin\smartctl-run.bat" "-H hda"
CreateShortCut "$SMPROGRAMS\smartmontools\smartctl Examples\SMART error log (-l error).lnk" "$INSTDIR\bin\smartctl-run.bat" "-l error hda"
CreateShortCut "$SMPROGRAMS\smartmontools\smartctl Examples\SMART selftest log (-l selftest).lnk" "$INSTDIR\bin\smartctl-run.bat" "-l selftest hda"
CreateShortCut "$SMPROGRAMS\smartmontools\smartctl Examples\Start long selftest (-t long).lnk" "$INSTDIR\bin\smartctl-run.bat" "-t long hda"
CreateShortCut "$SMPROGRAMS\smartmontools\smartctl Examples\Start offline test (-t offline).lnk" "$INSTDIR\bin\smartctl-run.bat" "-t offline hda"
CreateShortCut "$SMPROGRAMS\smartmontools\smartctl Examples\Start short selftest (-t short).lnk" "$INSTDIR\bin\smartctl-run.bat" "-t short hda"
CreateShortCut "$SMPROGRAMS\smartmontools\smartctl Examples\Stop(Abort) selftest (-X).lnk" "$INSTDIR\bin\smartctl-run.bat" "-X hda"
CreateShortCut "$SMPROGRAMS\smartmontools\smartctl Examples\Turn SMART off (-s off).lnk" "$INSTDIR\bin\smartctl-run.bat" "-s off hda"
CreateShortCut "$SMPROGRAMS\smartmontools\smartctl Examples\Turn SMART on (-s on).lnk" "$INSTDIR\bin\smartctl-run.bat" "-s on hda"
CreateShortCut "$SMPROGRAMS\smartmontools\smartctl Examples\All info (-a).lnk" "$INSTDIR\bin\smartctl-run.bat" "-a sda"
CreateShortCut "$SMPROGRAMS\smartmontools\smartctl Examples\Identify drive (-i).lnk" "$INSTDIR\bin\smartctl-run.bat" "-i sda"
CreateShortCut "$SMPROGRAMS\smartmontools\smartctl Examples\SMART attributes (-A).lnk" "$INSTDIR\bin\smartctl-run.bat" "-A sda"
CreateShortCut "$SMPROGRAMS\smartmontools\smartctl Examples\SMART capabilities (-c).lnk" "$INSTDIR\bin\smartctl-run.bat" "-c sda"
CreateShortCut "$SMPROGRAMS\smartmontools\smartctl Examples\SMART health status (-H).lnk" "$INSTDIR\bin\smartctl-run.bat" "-H sda"
CreateShortCut "$SMPROGRAMS\smartmontools\smartctl Examples\SMART error log (-l error).lnk" "$INSTDIR\bin\smartctl-run.bat" "-l error sda"
CreateShortCut "$SMPROGRAMS\smartmontools\smartctl Examples\SMART selftest log (-l selftest).lnk" "$INSTDIR\bin\smartctl-run.bat" "-l selftest sda"
CreateShortCut "$SMPROGRAMS\smartmontools\smartctl Examples\Start long selftest (-t long).lnk" "$INSTDIR\bin\smartctl-run.bat" "-t long sda"
CreateShortCut "$SMPROGRAMS\smartmontools\smartctl Examples\Start offline test (-t offline).lnk" "$INSTDIR\bin\smartctl-run.bat" "-t offline sda"
CreateShortCut "$SMPROGRAMS\smartmontools\smartctl Examples\Start short selftest (-t short).lnk" "$INSTDIR\bin\smartctl-run.bat" "-t short sda"
CreateShortCut "$SMPROGRAMS\smartmontools\smartctl Examples\Stop(Abort) selftest (-X).lnk" "$INSTDIR\bin\smartctl-run.bat" "-X sda"
CreateShortCut "$SMPROGRAMS\smartmontools\smartctl Examples\Turn SMART off (-s off).lnk" "$INSTDIR\bin\smartctl-run.bat" "-s off sda"
CreateShortCut "$SMPROGRAMS\smartmontools\smartctl Examples\Turn SMART on (-s on).lnk" "$INSTDIR\bin\smartctl-run.bat" "-s on sda"
noctl:
; smartd
@ -169,9 +196,9 @@ Section "Start Menu Shortcuts"
FileWrite $0 "@echo off$\r$\necho smartd %1 %2 %3 %4 %5$\r$\nsmartd %1 %2 %3 %4 %5$\r$\npause$\r$\n"
FileClose $0
CreateDirectory "$SMPROGRAMS\smartmontools\smartd Examples"
CreateShortCut "$SMPROGRAMS\smartmontools\smartd Examples\Daemon start, log to smartd.log.lnk" "$INSTDIR\bin\smartd-run.bat" "-l local0"
CreateShortCut "$SMPROGRAMS\smartmontools\smartd Examples\Daemon start, smartd.log.lnk" "$INSTDIR\bin\smartd-run.bat" "-l local0"
IfFileExists "$WINDIR\system32\cmd.exe" 0 +2
CreateShortCut "$SMPROGRAMS\smartmontools\smartd Examples\Daemon start, log to eventlog.lnk" "$INSTDIR\bin\smartd-run.bat" ""
CreateShortCut "$SMPROGRAMS\smartmontools\smartd Examples\Daemon start, eventlog.lnk" "$INSTDIR\bin\smartd-run.bat" ""
CreateShortCut "$SMPROGRAMS\smartmontools\smartd Examples\Daemon stop.lnk" "$INSTDIR\bin\smartd-run.bat" "stop"
CreateShortCut "$SMPROGRAMS\smartmontools\smartd Examples\Do all tests once (-q onecheck).lnk" "$INSTDIR\bin\smartd-run.bat" "-q onecheck"
CreateShortCut "$SMPROGRAMS\smartmontools\smartd Examples\Debug mode (-d).lnk" "$INSTDIR\bin\smartd-run.bat" "-d"
@ -182,8 +209,9 @@ Section "Start Menu Shortcuts"
; smartd service (not on 9x/ME)
IfFileExists "$WINDIR\system32\cmd.exe" 0 nosvc
CreateShortCut "$SMPROGRAMS\smartmontools\smartd Examples\Service install, log to eventlog.lnk" "$INSTDIR\bin\smartd-run.bat" "install"
CreateShortCut "$SMPROGRAMS\smartmontools\smartd Examples\Service install, log to smartd.log.lnk" "$INSTDIR\bin\smartd-run.bat" "install -l local0"
CreateShortCut "$SMPROGRAMS\smartmontools\smartd Examples\Service install, eventlog, 30min.lnk" "$INSTDIR\bin\smartd-run.bat" "install"
CreateShortCut "$SMPROGRAMS\smartmontools\smartd Examples\Service install, smartd.log, 10min.lnk" "$INSTDIR\bin\smartd-run.bat" "install -l local0 -i 600"
CreateShortCut "$SMPROGRAMS\smartmontools\smartd Examples\Service install, smartd.log, 30min.lnk" "$INSTDIR\bin\smartd-run.bat" "install -l local0"
CreateShortCut "$SMPROGRAMS\smartmontools\smartd Examples\Service remove.lnk" "$INSTDIR\bin\smartd-run.bat" "remove"
DetailPrint "Create file: $INSTDIR\bin\net-run.bat"
FileOpen $0 "$INSTDIR\bin\net-run.bat" "w"
@ -214,6 +242,7 @@ Section "Start Menu Shortcuts"
CreateShortCut "$SMPROGRAMS\smartmontools\Documentation\README.lnk" "$INSTDIR\doc\README.txt"
CreateShortCut "$SMPROGRAMS\smartmontools\Documentation\TODO.lnk" "$INSTDIR\doc\TODO.txt"
CreateShortCut "$SMPROGRAMS\smartmontools\Documentation\WARNINGS.lnk" "$INSTDIR\doc\WARNINGS.txt"
CreateShortCut "$SMPROGRAMS\smartmontools\Documentation\Windows version download page.lnk" "http://smartmontools-win32.dyndns.org/smartmontools/"
nodoc:
; Homepage
@ -225,7 +254,7 @@ Section "Start Menu Shortcuts"
SectionEnd
Section "Add install dir to PATH" PATH_IDX
Section "Add install dir to PATH" PATH_SECTION
SectionIn 1
@ -235,14 +264,105 @@ Section "Add install dir to PATH" PATH_IDX
SectionEnd
SectionGroup "Add smartctl to drive menu"
!macro DriveMenuRemove
DetailPrint "Remove drive menu entries"
DeleteRegKey HKCR "Drive\shell\smartctl0"
DeleteRegKey HKCR "Drive\shell\smartctl1"
DeleteRegKey HKCR "Drive\shell\smartctl2"
DeleteRegKey HKCR "Drive\shell\smartctl3"
DeleteRegKey HKCR "Drive\shell\smartctl4"
DeleteRegKey HKCR "Drive\shell\smartctl5"
!macroend
Section "Remove existing entries first"
SectionIn 3
!insertmacro DriveMenuRemove
SectionEnd
!macro DriveSection id name args
Section 'smartctl ${args} ...' DRIVE_${id}_SECTION
SectionIn 3
DetailPrint 'Add drive menu entry "${name}": smartctl ${args} ...'
WriteRegStr HKCR "Drive\shell\smartctl${id}" "" "${name}"
WriteRegStr HKCR "Drive\shell\smartctl${id}\command" "" '"$INSTDIR\bin\smartctl-run.bat" ${args} %L'
SectionEnd
!macroend
!insertmacro DriveSection 0 "SMART all info" "-a"
!insertmacro DriveSection 1 "SMART status" "-Hc"
!insertmacro DriveSection 2 "SMART attributes" "-A"
!insertmacro DriveSection 3 "SMART short selftest" "-t short"
!insertmacro DriveSection 4 "SMART long selftest" "-t long"
!insertmacro DriveSection 5 "SMART continue selective selftest" '-t "selective,cont"'
SectionGroupEnd
Section "UBCD4Win Plugin" UBCD_SECTION
SectionIn 4
SetOutPath "$UBCDDIR"
DetailPrint "Create file: smartmontools.inf"
FileOpen $0 "$UBCDDIR\smartmontools.inf" "w"
FileWrite $0 '; smartmontools.inf$\r$\n; PE Builder v3 plug-in INF file$\r$\n'
FileWrite $0 '; Created by smartmontools installer$\r$\n'
FileWrite $0 '; http://smartmontools.sourceforge.net/$\r$\n$\r$\n'
FileWrite $0 '[Version]$\r$\nSignature= "$$Windows NT$$"$\r$\n$\r$\n'
FileWrite $0 '[PEBuilder]$\r$\nName="Disk -Diagnostic: smartmontools"$\r$\n'
FileWrite $0 'Enable=1$\r$\nHelp="files\smartctl.8.html"$\r$\n$\r$\n'
FileWrite $0 '[WinntDirectories]$\r$\na=Programs\smartmontools,2$\r$\n$\r$\n'
FileWrite $0 '[SourceDisksFolders]$\r$\nfiles=a,,1$\r$\n$\r$\n'
FileWrite $0 '[Append]$\r$\nnu2menu.xml, smartmontools_nu2menu.xml$\r$\n'
FileClose $0
DetailPrint "Create file: smartmontools_nu2menu.xml"
FileOpen $0 "$UBCDDIR\smartmontools_nu2menu.xml" "w"
FileWrite $0 '<!-- Nu2Menu entry for smartmontools -->$\r$\n<NU2MENU>$\r$\n'
FileWrite $0 '$\t<MENU ID="Programs">$\r$\n$\t$\t<MITEM TYPE="POPUP" MENUID="Disk Tools">'
FileWrite $0 'Disk Tools</MITEM>$\r$\n$\t</MENU>$\r$\n$\t<MENU ID="Disk Tools">$\r$\n'
FileWrite $0 '$\t$\t<MITEM TYPE="POPUP" MENUID="Diagnostic">Diagnostic</MITEM>$\r$\n$\t</MENU>'
FileWrite $0 '$\r$\n$\t<MENU ID="Diagnostic">$\r$\n$\t$\t<MITEM TYPE="ITEM" DISABLED="'
FileWrite $0 '@Not(@FileExists(@GetProgramDrive()\Programs\smartmontools\smartctl.exe))" '
FileWrite $0 'CMD="RUN" FUNC="cmd.exe /k cd /d @GetProgramDrive()\Programs\smartmontools&'
FileWrite $0 'set PATH=@GetProgramDrive()\Programs\smartmontools;%PATH%&smartctl-run.bat ">'
FileWrite $0 'smartctl</MITEM>$\r$\n$\t</MENU>$\r$\n</NU2MENU>$\r$\n'
FileClose $0
SetOutPath "$UBCDDIR\files"
DetailPrint "Create file: smartctl-run.bat"
Push "$UBCDDIR\files\smartctl-run.bat"
Call CreateSmartctlBat
File "${INPDIR}\bin\smartctl.exe"
File "${INPDIR}\bin\smartd.exe"
File "${INPDIR}\doc\smartctl.8.html"
File "${INPDIR}\doc\smartctl.8.txt"
File "${INPDIR}\doc\smartd.8.html"
File "${INPDIR}\doc\smartd.8.txt"
File "${INPDIR}\doc\smartd.conf"
SectionEnd
;--------------------------------------------------------------------
Section "Uninstall"
; Remove registry keys
; Stop & remove service
IfFileExists "$INSTDIR\bin\smartd.exe" 0 nosrv
ReadRegStr $0 HKLM "System\CurrentControlSet\Services\smartd" "ImagePath"
StrCmp $0 "" nosrv
ExecWait "net stop smartd"
MessageBox MB_YESNO|MB_ICONQUESTION|MB_DEFBUTTON2 "Remove smartd service ?" IDYES 0 IDNO nosrv
ExecWait "$INSTDIR\bin\smartd.exe remove"
nosrv:
; Remove installer registry keys
DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\smartmontools"
DeleteRegKey HKLM "Software\smartmontools"
; Remove conf and log file
IfFileExists "$INSTDIR\bin\smartd.conf" 0 noconf
; Assume unchanged if timestamp is equal to sample file
GetFileTime "$INSTDIR\bin\smartd.conf" $0 $1
@ -288,8 +408,8 @@ Section "Uninstall"
; Remove folders
RMDir "$SMPROGRAMS\smartmontools\Documentation"
RMDir "$SMPROGRAMS\smartmontools\smartctl Examples\"
RMDir "$SMPROGRAMS\smartmontools\smartd Examples\"
RMDir "$SMPROGRAMS\smartmontools\smartctl Examples"
RMDir "$SMPROGRAMS\smartmontools\smartd Examples"
RMDir "$SMPROGRAMS\smartmontools"
RMDir "$INSTDIR\bin"
RMDir "$INSTDIR\doc"
@ -300,28 +420,98 @@ Section "Uninstall"
Push "$INSTDIR\bin"
Call un.RemoveFromPath
; Check for still existing files
; Remove drive menu registry entries
!insertmacro DriveMenuRemove
; Check for still existing entries
IfFileExists "$INSTDIR\bin\smartd.exe" 0 +3
MessageBox MB_OK|MB_ICONEXCLAMATION "$INSTDIR\bin\smartd.exe could not be removed.$\nsmartd is possibly still running."
Goto +3
IfFileExists "$INSTDIR" 0 +2
MessageBox MB_OK "Note: $INSTDIR could not be removed."
IfFileExists "$SMPROGRAMS\smartmontools" 0 +2
MessageBox MB_OK "Note: $SMPROGRAMS\smartmontools could not be removed."
SectionEnd
;--------------------------------------------------------------------
; Functions
Function .onInit
; Get UBCD4Win install location
ReadRegStr $0 HKLM "Software\UBCD4Win" "InstallPath"
StrCmp $0 "" 0 +2
StrCpy $0 "C:\UBCD4Win"
StrCpy $UBCDDIR "$0\plugin\Disk\Diagnostic\smartmontools"
; Hide "Add install dir to PATH" on 9x/ME
IfFileExists "$WINDIR\system32\cmd.exe" +2 0
SectionSetText ${PATH_IDX} ""
SectionSetText ${PATH_SECTION} ""
FunctionEnd
; Directory page callbacks
!macro CheckSection section
SectionGetFlags ${section} $0
IntOp $0 $0 & 1
IntCmp $0 1 done
!macroend
Function SkipProgPath
!insertmacro CheckSection ${SMARTCTL_SECTION}
!insertmacro CheckSection ${SMARTD_SECTION}
!insertmacro CheckSection ${DOC_SECTION}
!insertmacro CheckSection ${MENU_SECTION}
!insertmacro CheckSection ${PATH_SECTION}
!insertmacro CheckSection ${DRIVE_0_SECTION}
!insertmacro CheckSection ${DRIVE_1_SECTION}
!insertmacro CheckSection ${DRIVE_2_SECTION}
!insertmacro CheckSection ${DRIVE_3_SECTION}
!insertmacro CheckSection ${DRIVE_4_SECTION}
!insertmacro CheckSection ${DRIVE_5_SECTION}
Abort
done:
FunctionEnd
Function SkipUBCDPath
!insertmacro CheckSection ${UBCD_SECTION}
Abort
done:
FunctionEnd
; Create smartctl-run.bat
Function CreateSmartctlBat
Exch $0
FileOpen $0 $0 "w"
FileWrite $0 '@echo off$\r$\nif not "%1" == "" goto run$\r$\n'
FileWrite $0 'echo Examples (for first drive):$\r$\n'
FileWrite $0 'echo smartctl -i sda Show identify information$\r$\n'
FileWrite $0 'echo smartctl -H sda Show SMART health status$\r$\n'
FileWrite $0 'echo smartctl -c sda Show SMART capabilities$\r$\n'
FileWrite $0 'echo smartctl -A sda Show SMART attributes$\r$\n'
FileWrite $0 'echo smartctl -l error sda Show error log$\r$\n'
FileWrite $0 'echo smartctl -l selftest sda Show self-test log$\r$\n'
FileWrite $0 'echo smartctl -a sda Show all of the above$\r$\n'
FileWrite $0 'echo smartctl -t short sda Start short self test$\r$\n'
FileWrite $0 'echo smartctl -t long sda Start long self test$\r$\n'
FileWrite $0 'echo Use "sdb", "sdc", ... for second, third, ... drive.$\r$\n'
FileWrite $0 'echo See man page (smartctl.8.*) for further info.$\r$\n'
FileWrite $0 'goto end$\r$\n:run$\r$\n'
FileWrite $0 'echo smartctl %1 %2 %3 %4 %5$\r$\n'
FileWrite $0 'smartctl %1 %2 %3 %4 %5$\r$\n'
FileWrite $0 'pause$\r$\n:end$\r$\n'
FileClose $0
Pop $0
FunctionEnd
;--------------------------------------------------------------------
; Utility functions
; Path functions
;
; Based on example from:
; http://nsis.sourceforge.net/Path_Manipulation
@ -355,12 +545,12 @@ Function AddToPath
Push "$0;"
Call StrStr
Pop $2
StrCmp $2 "" "" done
StrCmp $2 "" 0 done
Push "$1;"
Push "$0\;"
Call StrStr
Pop $2
StrCmp $2 "" "" done
StrCmp $2 "" 0 done
DetailPrint "Add to PATH: $0"
StrCpy $2 $1 1 -1

244
os_win32/smartctl_vc6.dsp Normal file
View File

@ -0,0 +1,244 @@
# Microsoft Developer Studio Project File - Name="smartctl_vc6" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** NICHT BEARBEITEN **
# TARGTYPE "Win32 (x86) Console Application" 0x0103
CFG=smartctl_vc6 - Win32 Debug
!MESSAGE Dies ist kein gültiges Makefile. Zum Erstellen dieses Projekts mit NMAKE
!MESSAGE verwenden Sie den Befehl "Makefile exportieren" und führen Sie den Befehl
!MESSAGE
!MESSAGE NMAKE /f "smartctl_vc6.mak".
!MESSAGE
!MESSAGE Sie können beim Ausführen von NMAKE eine Konfiguration angeben
!MESSAGE durch Definieren des Makros CFG in der Befehlszeile. Zum Beispiel:
!MESSAGE
!MESSAGE NMAKE /f "smartctl_vc6.mak" CFG="smartctl_vc6 - Win32 Debug"
!MESSAGE
!MESSAGE Für die Konfiguration stehen zur Auswahl:
!MESSAGE
!MESSAGE "smartctl_vc6 - Win32 Release" (basierend auf "Win32 (x86) Console Application")
!MESSAGE "smartctl_vc6 - Win32 Debug" (basierend auf "Win32 (x86) Console Application")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
CPP=cl.exe
RSC=rc.exe
!IF "$(CFG)" == "smartctl_vc6 - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release"
# PROP BASE Intermediate_Dir "Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "smartctl.r"
# PROP Intermediate_Dir "smartctl.r"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
# ADD CPP /nologo /W3 /GX /O1 /I "." /I ".." /I "..\posix" /D "NDEBUG" /D "HAVE_CONFIG_H" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
# ADD BASE RSC /l 0x407 /d "NDEBUG"
# ADD RSC /l 0x407 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"smartctl.exe"
!ELSEIF "$(CFG)" == "smartctl_vc6 - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Debug"
# PROP BASE Intermediate_Dir "Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "smartctl.d"
# PROP Intermediate_Dir "smartctl.d"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "." /I ".." /I "..\posix" /D "_DEBUG" /D "HAVE_CONFIG_H" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
# ADD BASE RSC /l 0x407 /d "_DEBUG"
# ADD RSC /l 0x407 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
!ENDIF
# Begin Target
# Name "smartctl_vc6 - Win32 Release"
# Name "smartctl_vc6 - Win32 Debug"
# Begin Group "posix"
# PROP Default_Filter ""
# Begin Source File
SOURCE=..\posix\getopt.c
# End Source File
# Begin Source File
SOURCE=..\posix\getopt.h
# End Source File
# Begin Source File
SOURCE=..\posix\getopt1.c
# End Source File
# Begin Source File
SOURCE=..\posix\regcomp.c
# PROP Exclude_From_Build 1
# End Source File
# Begin Source File
SOURCE=..\posix\regex.c
# ADD CPP /w /W0
# End Source File
# Begin Source File
SOURCE=..\posix\regex.h
# End Source File
# Begin Source File
SOURCE=..\posix\regex_internal.c
# PROP Exclude_From_Build 1
# End Source File
# Begin Source File
SOURCE=..\posix\regex_internal.h
# End Source File
# Begin Source File
SOURCE=..\posix\regexec.c
# PROP Exclude_From_Build 1
# End Source File
# End Group
# Begin Source File
SOURCE=..\atacmdnames.cpp
# End Source File
# Begin Source File
SOURCE=..\atacmdnames.h
# End Source File
# Begin Source File
SOURCE=..\atacmds.cpp
# End Source File
# Begin Source File
SOURCE=..\atacmds.h
# End Source File
# Begin Source File
SOURCE=..\ataprint.cpp
# End Source File
# Begin Source File
SOURCE=..\ataprint.h
# End Source File
# Begin Source File
SOURCE=.\config_vc6.h
!IF "$(CFG)" == "smartctl_vc6 - Win32 Release"
# Begin Custom Build - Copy $(InputPath) config.h
InputPath=.\config_vc6.h
"config.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
copy $(InputPath) config.h
# End Custom Build
!ELSEIF "$(CFG)" == "smartctl_vc6 - Win32 Debug"
# Begin Custom Build - Copy $(InputPath) config.h
InputPath=.\config_vc6.h
"config.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
copy $(InputPath) config.h
# End Custom Build
!ENDIF
# End Source File
# Begin Source File
SOURCE=..\extern.h
# End Source File
# Begin Source File
SOURCE=..\int64.h
# End Source File
# Begin Source File
SOURCE=..\knowndrives.cpp
# End Source File
# Begin Source File
SOURCE=..\knowndrives.h
# End Source File
# Begin Source File
SOURCE=..\os_win32.cpp
# End Source File
# Begin Source File
SOURCE=..\scsiata.cpp
# End Source File
# Begin Source File
SOURCE=..\scsiata.h
# End Source File
# Begin Source File
SOURCE=..\scsicmds.cpp
# End Source File
# Begin Source File
SOURCE=..\scsicmds.h
# End Source File
# Begin Source File
SOURCE=..\scsiprint.cpp
# End Source File
# Begin Source File
SOURCE=..\scsiprint.h
# End Source File
# Begin Source File
SOURCE=..\smartctl.cpp
# End Source File
# Begin Source File
SOURCE=..\smartctl.h
# End Source File
# Begin Source File
SOURCE=.\syslog.h
# End Source File
# Begin Source File
SOURCE=..\utility.cpp
# End Source File
# Begin Source File
SOURCE=..\utility.h
# End Source File
# End Target
# End Project

268
os_win32/smartd_vc6.dsp Normal file
View File

@ -0,0 +1,268 @@
# Microsoft Developer Studio Project File - Name="smartd_vc6" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** NICHT BEARBEITEN **
# TARGTYPE "Win32 (x86) Console Application" 0x0103
CFG=smartd_vc6 - Win32 Debug
!MESSAGE Dies ist kein gültiges Makefile. Zum Erstellen dieses Projekts mit NMAKE
!MESSAGE verwenden Sie den Befehl "Makefile exportieren" und führen Sie den Befehl
!MESSAGE
!MESSAGE NMAKE /f "smartd_vc6.mak".
!MESSAGE
!MESSAGE Sie können beim Ausführen von NMAKE eine Konfiguration angeben
!MESSAGE durch Definieren des Makros CFG in der Befehlszeile. Zum Beispiel:
!MESSAGE
!MESSAGE NMAKE /f "smartd_vc6.mak" CFG="smartd_vc6 - Win32 Debug"
!MESSAGE
!MESSAGE Für die Konfiguration stehen zur Auswahl:
!MESSAGE
!MESSAGE "smartd_vc6 - Win32 Release" (basierend auf "Win32 (x86) Console Application")
!MESSAGE "smartd_vc6 - Win32 Debug" (basierend auf "Win32 (x86) Console Application")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
CPP=cl.exe
RSC=rc.exe
!IF "$(CFG)" == "smartd_vc6 - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release"
# PROP BASE Intermediate_Dir "Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "smartd.r"
# PROP Intermediate_Dir "smartd.r"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
# ADD CPP /nologo /W3 /GX /O1 /I "." /I ".." /I "..\posix" /D "NDEBUG" /D "HAVE_CONFIG_H" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
# ADD BASE RSC /l 0x407 /d "NDEBUG"
# ADD RSC /l 0x407 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"smartd.exe"
!ELSEIF "$(CFG)" == "smartd_vc6 - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Debug"
# PROP BASE Intermediate_Dir "Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "smartd.d"
# PROP Intermediate_Dir "smartd.d"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "." /I ".." /I "..\posix" /D "_DEBUG" /D "HAVE_CONFIG_H" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
# ADD BASE RSC /l 0x407 /d "_DEBUG"
# ADD RSC /l 0x407 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
!ENDIF
# Begin Target
# Name "smartd_vc6 - Win32 Release"
# Name "smartd_vc6 - Win32 Debug"
# Begin Group "posix"
# PROP Default_Filter ""
# Begin Source File
SOURCE=..\posix\getopt.c
# End Source File
# Begin Source File
SOURCE=..\posix\getopt.h
# End Source File
# Begin Source File
SOURCE=..\posix\getopt1.c
# End Source File
# Begin Source File
SOURCE=..\posix\regcomp.c
# PROP Exclude_From_Build 1
# End Source File
# Begin Source File
SOURCE=..\posix\regex.c
# ADD CPP /w /W0
# End Source File
# Begin Source File
SOURCE=..\posix\regex.h
# End Source File
# Begin Source File
SOURCE=..\posix\regex_internal.c
# PROP Exclude_From_Build 1
# End Source File
# Begin Source File
SOURCE=..\posix\regex_internal.h
# End Source File
# Begin Source File
SOURCE=..\posix\regexec.c
# PROP Exclude_From_Build 1
# End Source File
# End Group
# Begin Source File
SOURCE=..\atacmdnames.cpp
# End Source File
# Begin Source File
SOURCE=..\atacmdnames.h
# End Source File
# Begin Source File
SOURCE=..\atacmds.cpp
# End Source File
# Begin Source File
SOURCE=..\atacmds.h
# End Source File
# Begin Source File
SOURCE=..\ataprint.cpp
# End Source File
# Begin Source File
SOURCE=..\ataprint.h
# End Source File
# Begin Source File
SOURCE=.\config_vc6.h
!IF "$(CFG)" == "smartd_vc6 - Win32 Release"
# Begin Custom Build - Copy $(InputPath) config.h
InputPath=.\config_vc6.h
"config.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
copy $(InputPath) config.h
# End Custom Build
!ELSEIF "$(CFG)" == "smartd_vc6 - Win32 Debug"
# Begin Custom Build - Copy $(InputPath) config.h
InputPath=.\config_vc6.h
"config.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
copy $(InputPath) config.h
# End Custom Build
!ENDIF
# End Source File
# Begin Source File
SOURCE=.\daemon_win32.cpp
# End Source File
# Begin Source File
SOURCE=.\daemon_win32.h
# End Source File
# Begin Source File
SOURCE=..\extern.h
# End Source File
# Begin Source File
SOURCE=.\hostname_win32.cpp
# End Source File
# Begin Source File
SOURCE=.\hostname_win32.h
# End Source File
# Begin Source File
SOURCE=..\int64.h
# End Source File
# Begin Source File
SOURCE=..\knowndrives.cpp
# End Source File
# Begin Source File
SOURCE=..\knowndrives.h
# End Source File
# Begin Source File
SOURCE=..\os_win32.cpp
# End Source File
# Begin Source File
SOURCE=..\scsiata.cpp
# End Source File
# Begin Source File
SOURCE=..\scsiata.h
# End Source File
# Begin Source File
SOURCE=..\scsicmds.cpp
# End Source File
# Begin Source File
SOURCE=..\scsicmds.h
# End Source File
# Begin Source File
SOURCE=..\scsiprint.cpp
# End Source File
# Begin Source File
SOURCE=..\scsiprint.h
# End Source File
# Begin Source File
SOURCE=..\smartctl.h
# End Source File
# Begin Source File
SOURCE=..\smartd.cpp
# End Source File
# Begin Source File
SOURCE=..\smartd.h
# End Source File
# Begin Source File
SOURCE=.\syslog.h
# End Source File
# Begin Source File
SOURCE=.\syslog_win32.cpp
# End Source File
# Begin Source File
SOURCE=..\utility.cpp
# End Source File
# Begin Source File
SOURCE=..\utility.h
# End Source File
# End Target
# End Project

View File

@ -0,0 +1,53 @@
Microsoft Developer Studio Workspace File, Format Version 6.00
# WARNUNG: DIESE ARBEITSBEREICHSDATEI DARF NICHT BEARBEITET ODER GELÖSCHT WERDEN!
###############################################################################
Project: "smartctl_vc6"=.\smartctl_vc6.dsp - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
}}}
###############################################################################
Project: "smartd_vc6"=.\smartd_vc6.dsp - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
}}}
###############################################################################
Project: "syslogevt_vc6"=.\syslogevt_vc6.dsp - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
}}}
###############################################################################
Global:
Package=<5>
{{{
}}}
Package=<3>
{{{
}}}
###############################################################################

156
os_win32/syslogevt.c Normal file
View File

@ -0,0 +1,156 @@
/*
* os_win32/syslogevt.c
*
* Home page of code is: http://smartmontools.sourceforge.net
*
* Copyright (C) 2004-6 Christian Franke <smartmontools-support@lists.sourceforge.net>
*
* 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.
*
* You should have received a copy of the GNU General Public License
* (for example COPYING); if not, write to the Free
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
static char rcsid[] = "$Id: syslogevt.c,v 1.4 2006/04/12 14:54:29 ballen4705 Exp $";
#include <stdio.h>
#include <string.h>
#include <process.h>
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#ifdef _DEBUG
#include "syslogevt.h"
#endif
static int usage()
{
puts(
"syslogevt $Revision: 1.4 $ Copyright (C) 2004-6 Christian Franke\n"
"Home page is http://smartmontools.sourceforge.net/\n"
"\n"
"Usage: syslogevt [-ru] name [ident ...]\n"
"\n"
"Creates registry files \"name-r.reg\" and \"name-u.reg\" to (un)register\n"
"this program as an event message file for message source(s) \"ident\".\n"
"If \"ident\" is ommited, \"name\" is used. Options:\n"
"\n"
" -r run \"regedit name-r.reg\" after creating files\n"
" -u run \"regedit name-u.reg\" after creating files\n"
"\n"
"Examples:\n"
"\n"
"syslogevt smartd (Create smartd-r.reg and smartd-u.reg)\n"
"regedit smartd-r.reg (Register syslogevt.exe for smartd messages)\n"
"\n"
"syslogevt -r smartd (Same as above in one step)\n"
"\n"
"regedit smartd-u.reg (Undo the registration)\n"
"\n"
"CAUTION: A registry entry of an existing event source with the same \"ident\"\n"
" will be overwritten by regedit without notice."
);
return 1;
}
main(int argc, char ** argv)
{
int regedit, a1, ai;
char name1[30+1], name2[30+1], mypath[MAX_PATH+1];
const char * ident;
FILE * f1, * f2;
#ifdef _DEBUG
if (!(MSG_SYSLOG == 0 && MSG_SYSLOG_01 == 1 && MSG_SYSLOG_10 == 10)) {
puts("Internal error: MSG_SYSLOG_n != n"); return 1;
}
#endif
if (argc < 2)
return usage();
a1 = 1;
regedit = 0;
if (!strcmp(argv[a1], "-r")) {
regedit = 1; a1++;
}
else if (!strcmp(argv[a1], "-u")) {
regedit = -1; a1++;
}
for (ai = a1; ai < argc; ai++) {
ident = argv[ai];
if (!(ident[0] && strlen(ident) < sizeof(name1)-10
&& strcspn(ident, "-.:/\\") == strlen(ident) )) {
return usage();
}
}
if (!GetModuleFileName(NULL, mypath, sizeof(mypath)-1)) {
fputs("GetModuleFileName failed\n", stderr);
return 1;
}
ident = argv[a1];
strcpy(name1, ident); strcat(name1, "-r.reg");
strcpy(name2, ident); strcat(name2, "-u.reg");
if (!(f1 = fopen(name1, "w"))) {
perror(name1); return 1;
}
if (!(f2 = fopen(name2, "w"))) {
perror(name2); unlink(name1); return 1;
}
fputs("REGEDIT4\n\n", f1);
fputs("REGEDIT4\n\n", f2);
for (ai = (argc > a1+1 ? a1+1 : a1); ai < argc; ai++) {
int i;
ident = argv[ai];
fputs("[HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services\\Eventlog\\Application\\", f1);
fputs(ident, f1); fputs("]\n\"EventMessageFile\"=\"", f1);
for (i = 0; mypath[i]; i++) {
if (mypath[i] == '\\')
fputc('\\', f1);
fputc(mypath[i], f1);
}
fputs("\"\n\"TypesSupported\"=dword:00000007\n\n", f1);
fputs("[-HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services\\Eventlog\\Application\\", f2);
fputs(ident, f2); fputs("]\n\n", f2);
}
fclose(f1);
fclose(f2);
if (GetVersion() & 0x80000000) {
puts("Warning: Event log not supported on Win9x/ME\n");
if (regedit)
return 1;
}
if (regedit) {
if (spawnlp(P_WAIT, "regedit", "regedit", (regedit > 0 ? name1 : name2), (const char *)0) == -1) {
fputs("regedit: cannot execute\n", stderr);
return 1;
}
}
else {
fputs("Files generated. Use\n\n regedit ", stdout);
puts(name1);
fputs("\nto register event message file, and\n\n regedit ", stdout);
puts(name2);
fputs("\nto remove registration later.\n\n"
"Do not remove this program when registered.\n", stdout);
}
return 0;
}

161
os_win32/syslogevt.mc Normal file
View File

@ -0,0 +1,161 @@
;/*
; * os_win32/syslogevt.mc
; *
; * Home page of code is: http://smartmontools.sourceforge.net
; *
; * Copyright (C) 2004-6 Christian Franke <smartmontools-support@lists.sourceforge.net>
; *
; * 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.
; *
; * You should have received a copy of the GNU General Public License
; * (for example COPYING); if not, write to the Free
; * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
; *
; */
;
;// $Id: syslogevt.mc,v 1.4 2006/04/12 14:54:29 ballen4705 Exp $
;
;// Use message compiler "mc" to generate
;// syslogevt.rc, syslogevt.h, msg00001.bin
;// from this file.
;// MSG_SYSLOG in syslogmsg.h must be zero
;// MSG_SYSLOG_nn must be == nn
;
;
MessageId=0x0
Severity=Success
Facility=Application
SymbolicName=MSG_SYSLOG
Language=English
%1
.
;// 1-10 Line SYSLOG Messages
;// %1=Ident, %2=PID, %3=Severity, %[4-13]=Line 1-10
MessageId=0x1
Severity=Success
Facility=Application
SymbolicName=MSG_SYSLOG_01
Language=English
%1[%2]:%3: %4
.
MessageId=0x2
Severity=Success
Facility=Application
SymbolicName=MSG_SYSLOG_02
Language=English
%1[%2]:%3%n
%4%n
%5
.
MessageId=0x3
Severity=Success
Facility=Application
SymbolicName=MSG_SYSLOG_03
Language=English
%1[%2]:%3%n
%4%n
%5%n
%6
.
MessageId=0x4
Severity=Success
Facility=Application
SymbolicName=MSG_SYSLOG_04
Language=English
%1[%2]:%3%n
%4%n
%5%n
%6%n
%7
.
MessageId=0x5
Severity=Success
Facility=Application
SymbolicName=MSG_SYSLOG_05
Language=English
%1[%2]:%3%n
%4%n
%5%n
%6%n
%7%n
%8
.
MessageId=0x6
Severity=Success
Facility=Application
SymbolicName=MSG_SYSLOG_06
Language=English
%1[%2]:%3%n
%4%n
%5%n
%6%n
%7%n
%8%n
%9
.
MessageId=0x7
Severity=Success
Facility=Application
SymbolicName=MSG_SYSLOG_07
Language=English
%1[%2]:%3%n
%4%n
%5%n
%6%n
%7%n
%8%n
%9%n
%10
.
MessageId=0x8
Severity=Success
Facility=Application
SymbolicName=MSG_SYSLOG_08
Language=English
%1[%2]:%3%n
%4%n
%5%n
%6%n
%7%n
%8%n
%9%n
%10%n
%11
.
MessageId=0x9
Severity=Success
Facility=Application
SymbolicName=MSG_SYSLOG_09
Language=English
%1[%2]:%3%n
%4%n
%5%n
%6%n
%7%n
%8%n
%9%n
%10%n
%11%n
%12
.
MessageId=0xa
Severity=Success
Facility=Application
SymbolicName=MSG_SYSLOG_10
Language=English
%1[%2]:%3%n
%4%n
%5%n
%6%n
%7%n
%8%n
%9%n
%10%n
%11%n
%12%n
%13
.

148
os_win32/syslogevt_vc6.dsp Normal file
View File

@ -0,0 +1,148 @@
# Microsoft Developer Studio Project File - Name="syslogevt_vc6" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** NICHT BEARBEITEN **
# TARGTYPE "Win32 (x86) Console Application" 0x0103
CFG=syslogevt_vc6 - Win32 Debug
!MESSAGE Dies ist kein gültiges Makefile. Zum Erstellen dieses Projekts mit NMAKE
!MESSAGE verwenden Sie den Befehl "Makefile exportieren" und führen Sie den Befehl
!MESSAGE
!MESSAGE NMAKE /f "syslogevt_vc6.mak".
!MESSAGE
!MESSAGE Sie können beim Ausführen von NMAKE eine Konfiguration angeben
!MESSAGE durch Definieren des Makros CFG in der Befehlszeile. Zum Beispiel:
!MESSAGE
!MESSAGE NMAKE /f "syslogevt_vc6.mak" CFG="syslogevt_vc6 - Win32 Debug"
!MESSAGE
!MESSAGE Für die Konfiguration stehen zur Auswahl:
!MESSAGE
!MESSAGE "syslogevt_vc6 - Win32 Release" (basierend auf "Win32 (x86) Console Application")
!MESSAGE "syslogevt_vc6 - Win32 Debug" (basierend auf "Win32 (x86) Console Application")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
CPP=cl.exe
RSC=rc.exe
!IF "$(CFG)" == "syslogevt_vc6 - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release"
# PROP BASE Intermediate_Dir "Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "syslogevt.r"
# PROP Intermediate_Dir "syslogevt.r"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
# ADD CPP /nologo /MD /W3 /GX /O1 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
# ADD BASE RSC /l 0x407 /d "NDEBUG"
# ADD RSC /l 0x407 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
# ADD LINK32 $(IntDir)\syslogevt.res kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"syslogevt.exe"
# SUBTRACT LINK32 /pdb:none
# Begin Special Build Tool
IntDir=.\syslogevt.r
SOURCE="$(InputPath)"
PreLink_Desc=Compiling Resources
PreLink_Cmds=rc $(IntDir)\syslogevt.rc
# End Special Build Tool
!ELSEIF "$(CFG)" == "syslogevt_vc6 - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Debug"
# PROP BASE Intermediate_Dir "Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "syslogevt.d"
# PROP Intermediate_Dir "syslogevt.d"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
# ADD BASE RSC /l 0x407 /d "_DEBUG"
# ADD RSC /l 0x407 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
# ADD LINK32 $(IntDir)\syslogevt.res kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
# Begin Special Build Tool
IntDir=.\syslogevt.d
SOURCE="$(InputPath)"
PreLink_Desc=Compiling Resources
PreLink_Cmds=rc $(IntDir)\syslogevt.rc
# End Special Build Tool
!ENDIF
# Begin Target
# Name "syslogevt_vc6 - Win32 Release"
# Name "syslogevt_vc6 - Win32 Debug"
# Begin Source File
SOURCE=.\syslogevt.c
# End Source File
# Begin Source File
SOURCE=.\syslogevt.mc
!IF "$(CFG)" == "syslogevt_vc6 - Win32 Release"
# Begin Custom Build - Compiling Messages
IntDir=.\syslogevt.r
InputPath=.\syslogevt.mc
BuildCmds= \
mc -r $(IntDir) syslogevt.mc
"$(IntDir)\syslogevt.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
$(BuildCmds)
"$(IntDir)\msg00001.bin" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
$(BuildCmds)
"syslogevt.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
$(BuildCmds)
# End Custom Build
!ELSEIF "$(CFG)" == "syslogevt_vc6 - Win32 Debug"
# Begin Custom Build - Compiling Messages
IntDir=.\syslogevt.d
InputPath=.\syslogevt.mc
BuildCmds= \
mc -r $(IntDir) syslogevt.mc
"$(IntDir)\syslogevt.rc" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
$(BuildCmds)
"$(IntDir)\msg00001.bin" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
$(BuildCmds)
"syslogevt.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
$(BuildCmds)
# End Custom Build
!ENDIF
# End Source File
# End Target
# End Project

1277
posix/getopt.c Normal file

File diff suppressed because it is too large Load Diff

181
posix/getopt.h Normal file
View File

@ -0,0 +1,181 @@
/* Declarations for getopt.
Copyright (C) 1989-1994, 1996-1999, 2001 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
#ifndef _GETOPT_H
#ifndef __need_getopt
# define _GETOPT_H 1
#endif
/* If __GNU_LIBRARY__ is not already defined, either we are being used
standalone, or this is the first header included in the source file.
If we are being used with glibc, we need to include <features.h>, but
that does not exist if we are standalone. So: if __GNU_LIBRARY__ is
not defined, include <ctype.h>, which will pull in <features.h> for us
if it's from glibc. (Why ctype.h? It's guaranteed to exist and it
doesn't flood the namespace with stuff the way some other headers do.) */
#if !defined __GNU_LIBRARY__
# include <ctype.h>
#endif
#ifdef __cplusplus
extern "C" {
#endif
/* For communication from `getopt' to the caller.
When `getopt' finds an option that takes an argument,
the argument value is returned here.
Also, when `ordering' is RETURN_IN_ORDER,
each non-option ARGV-element is returned here. */
extern char *optarg;
/* Index in ARGV of the next element to be scanned.
This is used for communication to and from the caller
and for communication between successive calls to `getopt'.
On entry to `getopt', zero means this is the first call; initialize.
When `getopt' returns -1, this is the index of the first of the
non-option elements that the caller should itself scan.
Otherwise, `optind' communicates from one call to the next
how much of ARGV has been scanned so far. */
extern int optind;
/* Callers store zero here to inhibit the error message `getopt' prints
for unrecognized options. */
extern int opterr;
/* Set to an option character which was unrecognized. */
extern int optopt;
#ifndef __need_getopt
/* Describe the long-named options requested by the application.
The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector
of `struct option' terminated by an element containing a name which is
zero.
The field `has_arg' is:
no_argument (or 0) if the option does not take an argument,
required_argument (or 1) if the option requires an argument,
optional_argument (or 2) if the option takes an optional argument.
If the field `flag' is not NULL, it points to a variable that is set
to the value given in the field `val' when the option is found, but
left unchanged if the option is not found.
To have a long-named option do something other than set an `int' to
a compiled-in constant, such as set a value from `optarg', set the
option's `flag' field to zero and its `val' field to a nonzero
value (the equivalent single-letter option character, if there is
one). For long options that have a zero `flag' field, `getopt'
returns the contents of the `val' field. */
struct option
{
# if (defined __STDC__ && __STDC__) || defined __cplusplus
const char *name;
# else
char *name;
# endif
/* has_arg can't be an enum because some compilers complain about
type mismatches in all the code that assumes it is an int. */
int has_arg;
int *flag;
int val;
};
/* Names for the values of the `has_arg' field of `struct option'. */
# define no_argument 0
# define required_argument 1
# define optional_argument 2
#endif /* need getopt */
/* Get definitions and prototypes for functions to process the
arguments in ARGV (ARGC of them, minus the program name) for
options given in OPTS.
Return the option character from OPTS just read. Return -1 when
there are no more options. For unrecognized options, or options
missing arguments, `optopt' is set to the option letter, and '?' is
returned.
The OPTS string is a list of characters which are recognized option
letters, optionally followed by colons, specifying that that letter
takes an argument, to be placed in `optarg'.
If a letter in OPTS is followed by two colons, its argument is
optional. This behavior is specific to the GNU `getopt'.
The argument `--' causes premature termination of argument
scanning, explicitly telling `getopt' that there are no more
options.
If OPTS begins with `--', then non-option arguments are treated as
arguments to the option '\0'. This behavior is specific to the GNU
`getopt'. */
#if (defined __STDC__ && __STDC__) || defined __cplusplus
# ifdef __GNU_LIBRARY__
/* Many other libraries have conflicting prototypes for getopt, with
differences in the consts, in stdlib.h. To avoid compilation
errors, only prototype getopt for the GNU C library. */
extern int getopt (int ___argc, char *const *___argv, const char *__shortopts);
# else /* not __GNU_LIBRARY__ */
extern int getopt ();
# endif /* __GNU_LIBRARY__ */
# ifndef __need_getopt
extern int getopt_long (int ___argc, char *const *___argv,
const char *__shortopts,
const struct option *__longopts, int *__longind);
extern int getopt_long_only (int ___argc, char *const *___argv,
const char *__shortopts,
const struct option *__longopts, int *__longind);
/* Internal only. Users should not call this directly. */
extern int _getopt_internal (int ___argc, char *const *___argv,
const char *__shortopts,
const struct option *__longopts, int *__longind,
int __long_only);
# endif
#else /* not __STDC__ */
extern int getopt ();
# ifndef __need_getopt
extern int getopt_long ();
extern int getopt_long_only ();
extern int _getopt_internal ();
# endif
#endif /* __STDC__ */
#ifdef __cplusplus
}
#endif
/* Make sure we later can get all the definitions and declarations. */
#undef __need_getopt
#endif /* getopt.h */

196
posix/getopt1.c Normal file
View File

@ -0,0 +1,196 @@
/* getopt_long and getopt_long_only entry points for GNU getopt.
Copyright (C) 1987,88,89,90,91,92,93,94,96,97,98
Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#ifdef _LIBC
# include <getopt.h>
#else
# include "getopt.h"
#endif
#if !defined __STDC__ || !__STDC__
/* This is a separate conditional since some stdc systems
reject `defined (const)'. */
#ifndef const
#define const
#endif
#endif
#include <stdio.h>
/* Comment out all this code if we are using the GNU C Library, and are not
actually compiling the library itself. This code is part of the GNU C
Library, but also included in many other GNU distributions. Compiling
and linking in this code is a waste when using the GNU C library
(especially if it is a shared library). Rather than having every GNU
program understand `configure --with-gnu-libc' and omit the object files,
it is simpler to just do this in the source for each such file. */
#define GETOPT_INTERFACE_VERSION 2
#if !defined _LIBC && defined __GLIBC__ && __GLIBC__ >= 2
#include <gnu-versions.h>
#if _GNU_GETOPT_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION
#define ELIDE_CODE
#endif
#endif
#ifndef ELIDE_CODE
/* This needs to come after some library #include
to get __GNU_LIBRARY__ defined. */
#ifdef __GNU_LIBRARY__
#include <stdlib.h>
#endif
#ifndef NULL
#define NULL 0
#endif
int
getopt_long (argc, argv, options, long_options, opt_index)
int argc;
char *const *argv;
const char *options;
const struct option *long_options;
int *opt_index;
{
return _getopt_internal (argc, argv, options, long_options, opt_index, 0);
}
/* Like getopt_long, but '-' as well as '--' can indicate a long option.
If an option that starts with '-' (not '--') doesn't match a long option,
but does match a short option, it is parsed as a short option
instead. */
int
getopt_long_only (argc, argv, options, long_options, opt_index)
int argc;
char *const *argv;
const char *options;
const struct option *long_options;
int *opt_index;
{
return _getopt_internal (argc, argv, options, long_options, opt_index, 1);
}
# ifdef _LIBC
libc_hidden_def (getopt_long)
libc_hidden_def (getopt_long_only)
# endif
#endif /* Not ELIDE_CODE. */
#ifdef TEST
#include <stdio.h>
int
main (argc, argv)
int argc;
char **argv;
{
int c;
int digit_optind = 0;
while (1)
{
int this_option_optind = optind ? optind : 1;
int option_index = 0;
static struct option long_options[] =
{
{"add", 1, 0, 0},
{"append", 0, 0, 0},
{"delete", 1, 0, 0},
{"verbose", 0, 0, 0},
{"create", 0, 0, 0},
{"file", 1, 0, 0},
{0, 0, 0, 0}
};
c = getopt_long (argc, argv, "abc:d:0123456789",
long_options, &option_index);
if (c == -1)
break;
switch (c)
{
case 0:
printf ("option %s", long_options[option_index].name);
if (optarg)
printf (" with arg %s", optarg);
printf ("\n");
break;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
if (digit_optind != 0 && digit_optind != this_option_optind)
printf ("digits occur in two different argv-elements.\n");
digit_optind = this_option_optind;
printf ("option %c\n", c);
break;
case 'a':
printf ("option a\n");
break;
case 'b':
printf ("option b\n");
break;
case 'c':
printf ("option c with value `%s'\n", optarg);
break;
case 'd':
printf ("option d with value `%s'\n", optarg);
break;
case '?':
break;
default:
printf ("?? getopt returned character code 0%o ??\n", c);
}
}
if (optind < argc)
{
printf ("non-option ARGV-elements: ");
while (optind < argc)
printf ("%s ", argv[optind++]);
printf ("\n");
}
exit (0);
}
#endif /* TEST */

View File

@ -47,7 +47,7 @@
#include "scsicmds.h"
#include "utility.h"
const char *scsicmds_c_cvsid="$Id: scsicmds.cpp,v 1.92 2006/11/12 04:45:54 dpgilbert Exp $"
const char *scsicmds_c_cvsid="$Id: scsicmds.cpp,v 1.94 2007/03/23 03:47:28 dpgilbert Exp $"
CONFIG_H_CVSID EXTERN_H_CVSID INT64_H_CVSID SCSICMDS_H_CVSID UTILITY_H_CVSID;
/* for passing global control variables */
@ -116,8 +116,8 @@ static struct scsi_opcode_name opcode_name_arr[] = {
{TEST_UNIT_READY, "test unit ready"}, /* 0x00 */
{REQUEST_SENSE, "request sense"}, /* 0x03 */
{INQUIRY, "inquiry"}, /* 0x12 */
{MODE_SELECT, "mode select"}, /* 0x15 */
{MODE_SENSE, "mode sense"}, /* 0x1a */
{MODE_SELECT, "mode select(6)"}, /* 0x15 */
{MODE_SENSE, "mode sense(6)"}, /* 0x1a */
{RECEIVE_DIAGNOSTIC, "receive diagnostic"}, /* 0x1c */
{SEND_DIAGNOSTIC, "send diagnostic"}, /* 0x1d */
{READ_DEFECT_10, "read defect list(10)"}, /* 0x37 */
@ -171,6 +171,9 @@ void scsi_do_sense_disect(const struct scsi_cmnd_io * io_buf,
int scsiSimpleSenseFilter(const struct scsi_sense_disect * sinfo)
{
switch (sinfo->sense_key) {
case SCSI_SK_NO_SENSE:
case SCSI_SK_RECOVERED_ERR:
return SIMPLE_NO_ERROR;
case SCSI_SK_NOT_READY:
if (SCSI_ASC_NO_MEDIUM == sinfo->asc)
return SIMPLE_ERR_NO_MEDIUM;
@ -195,8 +198,10 @@ int scsiSimpleSenseFilter(const struct scsi_sense_disect * sinfo)
return SIMPLE_ERR_BAD_PARAM; /* all other illegal request */
case SCSI_SK_UNIT_ATTENTION:
return SIMPLE_ERR_TRY_AGAIN;
case SCSI_SK_ABORTED_COMMAND:
return SIMPLE_ERR_ABORTED_COMMAND;
default:
return SIMPLE_NO_ERROR;
return SIMPLE_ERR_UNKNOWN;
}
}
@ -225,6 +230,10 @@ const char * scsiErrString(int scsiErr)
return "unit attention reported, try again";
case SIMPLE_ERR_MEDIUM_HARDWARE:
return "medium or hardware error (serious)";
case SIMPLE_ERR_UNKNOWN:
return "unknown error (unexpected sense key)";
case SIMPLE_ERR_ABORTED_COMMAND:
return "aborted command (transport problem?)";
default:
return "unknown error";
}
@ -290,6 +299,8 @@ int scsiLogSense(int device, int pagenum, int subpagenum, UINT8 *pBuf,
if (0 == ((pBuf[2] << 8) + pBuf[3]))
return SIMPLE_ERR_BAD_RESP;
pageLen = (pBuf[2] << 8) + pBuf[3] + 4;
if (4 == pageLen) /* why define a lpage with no payload? */
pageLen = 252; /* some IBM tape drives don't like double fetch */
/* some SCSI HBA don't like "odd" length transfers */
if (pageLen % 2)
pageLen += 1;

View File

@ -32,7 +32,7 @@
#ifndef SCSICMDS_H_
#define SCSICMDS_H_
#define SCSICMDS_H_CVSID "$Id: scsicmds.h,v 1.63 2006/11/12 04:46:32 dpgilbert Exp $\n"
#define SCSICMDS_H_CVSID "$Id: scsicmds.h,v 1.65 2007/03/23 03:45:34 dpgilbert Exp $\n"
#include <stdio.h>
#include <stdlib.h>
@ -85,7 +85,7 @@
#endif
typedef unsigned char UINT8;
typedef char INT8;
typedef signed char INT8;
typedef unsigned int UINT32;
typedef int INT32;
@ -230,6 +230,7 @@ Documentation, see http://www.storage.ibm.com/techsup/hddtech/prodspecs.htm */
#define SCSI_SK_HARDWARE_ERROR 0x4
#define SCSI_SK_ILLEGAL_REQUEST 0x5
#define SCSI_SK_UNIT_ATTENTION 0x6
#define SCSI_SK_ABORTED_COMMAND 0xb
/* defines for useful Additional Sense Codes (ASCs) */
#define SCSI_ASC_NOT_READY 0x4 /* more info in ASCQ code */
@ -253,6 +254,8 @@ Documentation, see http://www.storage.ibm.com/techsup/hddtech/prodspecs.htm */
#define SIMPLE_ERR_BECOMING_READY 7 /* device will be ready soon */
#define SIMPLE_ERR_TRY_AGAIN 8 /* some warning, try again */
#define SIMPLE_ERR_MEDIUM_HARDWARE 9 /* medium or hardware error */
#define SIMPLE_ERR_UNKNOWN 10 /* unknown sense value */
#define SIMPLE_ERR_ABORTED_COMMAND 11 /* most likely transport error */
/* defines for functioncode parameter in SENDDIAGNOSTIC function */

View File

@ -3,11 +3,11 @@
*
* Home page of code is: http://smartmontools.sourceforge.net
*
* Copyright (C) 2002-6 Bruce Allen <smartmontools-support@lists.sourceforge.net>
* Copyright (C) 2002-7 Bruce Allen <smartmontools-support@lists.sourceforge.net>
* Copyright (C) 2000 Michael Cornwell <cornwell@acm.org>
*
* Additional SCSI work:
* Copyright (C) 2003-6 Douglas Gilbert <dougg@torque.net>
* Copyright (C) 2003-7 Douglas Gilbert <dougg@torque.net>
*
* 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
@ -42,7 +42,7 @@
#define GBUF_SIZE 65535
const char* scsiprint_c_cvsid="$Id: scsiprint.cpp,v 1.119 2006/11/12 04:47:23 dpgilbert Exp $"
const char* scsiprint_c_cvsid="$Id: scsiprint.cpp,v 1.120 2007/07/21 20:59:41 chrfranke Exp $"
CONFIG_H_CVSID EXTERN_H_CVSID INT64_H_CVSID SCSICMDS_H_CVSID SCSIPRINT_H_CVSID SMARTCTL_H_CVSID UTILITY_H_CVSID;
// control block which points to external global control variables
@ -1069,20 +1069,22 @@ static int scsiGetDriveInfo(int device, UINT8 * peripheral_type, int all)
} else
modese_len = iec.modese_len;
if (0 == (err = scsiInquiryVpd(device, 0x80, gBuf, 64))) {
/* should use VPD page 0x83 and fall back to this page (0x80)
* if 0x83 not supported. NAA requires a lot of decoding code */
len = gBuf[3];
gBuf[4 + len] = '\0';
pout("Serial number: %s\n", &gBuf[4]);
}
else if (con->reportscsiioctl > 0) {
PRINT_ON(con);
if (SIMPLE_ERR_BAD_RESP == err)
pout("Vital Product Data (VPD) bit ignored in INQUIRY\n");
else
pout("Vital Product Data (VPD) INQUIRY failed [%d]\n", err);
PRINT_OFF(con);
if (!con->dont_print_serial) {
if (0 == (err = scsiInquiryVpd(device, 0x80, gBuf, 64))) {
/* should use VPD page 0x83 and fall back to this page (0x80)
* if 0x83 not supported. NAA requires a lot of decoding code */
len = gBuf[3];
gBuf[4 + len] = '\0';
pout("Serial number: %s\n", &gBuf[4]);
}
else if (con->reportscsiioctl > 0) {
PRINT_ON(con);
if (SIMPLE_ERR_BAD_RESP == err)
pout("Vital Product Data (VPD) bit ignored in INQUIRY\n");
else
pout("Vital Product Data (VPD) INQUIRY failed [%d]\n", err);
PRINT_OFF(con);
}
}
// print SCSI peripheral device type

View File

@ -1,7 +1,7 @@
.ig
Copyright (C) 2002-6 Bruce Allen <smartmontools-support@lists.sourceforge.net>
Copyright (C) 2002-7 Bruce Allen <smartmontools-support@lists.sourceforge.net>
$Id: smartctl.8.in,v 1.90 2006/12/20 07:30:43 sxzzsf Exp $
$Id: smartctl.8.in,v 1.103 2007/09/06 08:48:55 ballen4705 Exp $
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
@ -82,34 +82,44 @@ your architecture.
.IP \fBSOLARIS\fP: 9
Use the forms \fB"/dev/rdsk/c?t?d?s?"\fP for IDE/ATA and SCSI disk
devices, and \fB"/dev/rmt/*"\fP for SCSI tape devices.
.IP \fBWINDOWS\fP: 9
Use the form \fB"/dev/hd[a\-j]"\fP for IDE/ATA
devices "\\\\.\\PhysicalDrive[0\-9]" on WinNT4/2000/XP/2003. For IDE/ATA
devices on Win95/98/98SE/ME, use \fB"/dev/hd[a\-d]"\fP for standard devices
.IP \fBWINDOWS\ 9x/ME\fP: 9
Use the forms \fB"/dev/hd[a\-d]"\fP for standard IDE/ATA devices
accessed via SMARTVSD.VXD, and \fB"/dev/hd[e\-h]"\fP for additional devices
accessed via a patched SMARTVSE.VXD (see INSTALL file for details).
Use the form \fB"/dev/scsi[0\-9][0\-f]"\fP for SCSI devices via an aspi dll
on ASPI adapter 0\-9, ID 0\-15. Alternatively use \fB"/dev/sd[a\-z]"\fP for
SCSI disks "\\\\.\\PhysicalDrive[0\-25]" on WinNT4/2000/XP/2003 (where "a"
maps to "0"). SCSI disks can also be referred to as \fB"/dev/pd[0\-255]"\fP
for "\\\\.\\PhysicalDrive[0\-255]" on WinNT4/2000/XP/2003. Use the
form \fB"/dev/tape[0\-255]"\fP for SCSI tape drives "\\\\.\\Tape[0\-255]"
on WinNT4/2000/XP/2003.
For disks behind 3ware 9000 controllers use \fB"/dev/hd[a\-j],N"\fP where
on ASPI adapter 0\-9, ID 0\-15. The prefix \fB"/dev/"\fP is optional.
.IP \fBWINDOWS\ NT4/2000/XP/2003/Vista\fP: 9
Use the forms \fB"/dev/sd[a\-z]"\fP for IDE/(S)ATA and SCSI disks
"\\\\.\\PhysicalDrive[0\-25]" (where "a" maps to "0").
These disks can also be referred to as \fB"/dev/pd[0\-255]"\fP for
"\\\\.\\PhysicalDrive[0\-255]".
ATA disks can also be referred to as \fB"/dev/hd[a\-z]"\fP for
"\\\\.\\PhysicalDrive[0\-25]".
Use one the forms \fB"/dev/tape[0\-255]"\fP, \fB"/dev/st[0\-255]"\fP,
or \fB"/dev/nst[0\-255]"\fP for SCSI tape drives "\\\\.\\Tape[0\-255]".
Alternatively, drive letters \fB"X:"\fP or \fB"X:\\"\fP may be used to
specify the physical drive behind a mounted partition.
For disks behind 3ware 9000 controllers use \fB"/dev/sd[a\-z],N"\fP where
N specifies the disk number (3ware \'port\') behind the controller
providing the logical drive (\'unit\') specified by \fB"/dev/hd[a\-j]"\fP.
providing the logical drive (\'unit\') specified by \fB"/dev/sd[a\-z]"\fP.
Alternatively, use \fB"/dev/tw_cli/cx/py"\fP for controller x, port y
to run the \'tw_cli\' tool and parse the output. This provides limited
monitoring (\'-i\', \'-c\', \'-A\' below) if SMART support is missing
monitoring (\'\-i\', \'\-c\', \'\-A\' below) if SMART support is missing
in the driver. Use \fB"/dev/tw_cli/stdin"\fP or \fB"/dev/tw_cli/clip"\fP
to parse CLI or 3DM output from standard input or clipboard.
The option \'-d 3ware,N\' is not necessary on Windows.
The option \'\-d 3ware,N\' is not necessary on Windows.
The prefix \fB"/dev/"\fP is optional.
.IP \fBCYGWIN\fP: 9
See "WINDOWS" above.
See "WINDOWS NT4/2000/XP/2003/Vista" above.
.IP \fBOS/2,eComStation\fP: 9
Use the form \fB"/dev/hd[a\-z]"\fP for IDE/ATA devices.
.PP
if \'\-\' is specified as the device path, \fBsmartctl\fP reads and
interprets it's own debug output from standard input.
See \'\-r ataioctl\' below for details.
.PP
Based on the device path, \fBsmartctl\fP will guess the device type
(ATA or SCSI). If necessary, the \'\-d\' option can be used to over\-ride
this guess
@ -165,7 +175,7 @@ Prints all SMART information about the disk, or TapeAlert information
about the tape drive or changer. For ATA devices this is equivalent
to
.nf
\'\-H \-i \-c \-A \-l error \-l selftest -l selective\'
\'\-H \-i \-c \-A \-l error \-l selftest \-l selective\'
.fi
and for SCSI, this is equivalent to
.nf
@ -193,6 +203,10 @@ which failed either now or in the past.
.I silent
\- print no output. The only way to learn about what was found is to
use the exit status of \fBsmartctl\fP (see RETURN VALUES below).
.I noserial
\- Do not print the serial number of the device.
.TP
.B \-d TYPE, \-\-device=TYPE
Specifies the type of the device. The valid arguments to this option
@ -210,7 +224,7 @@ overridden with either \'\-d sat,12\' or \'\-d sat,16\'.
Under Linux, to look at SATA disks behind Marvell SATA controllers
(using Marvell's \'linuxIAL\' driver rather than libata driver) use \'\-d marvell\'. Such
controllers show up as Marvell Technology Group Ltd. SATA I or II controllers
using lspci, or using lspci -n show a vendor ID 0x11ab and a device ID of
using lspci, or using lspci \-n show a vendor ID 0x11ab and a device ID of
either 0x5040, 0x5041, 0x5080, 0x5081, 0x6041 or 0x6081. The \'linuxIAL\' driver
seems not (yet?) available in the Linux kernel source tree, but should be available
from system vendors (ftp://ftp.aslab.com/ is known to provide a patch with the driver).
@ -228,21 +242,21 @@ use syntax such as:
.fi
where in the argument \fI3ware,N\fP, the integer N is the disk number
(3ware \'port\') within the 3ware ATA RAID controller. The allowed
values of N are from 0 to 15 inclusive. The first two forms, which
refer to devices /dev/sda-z and /dev/twe0-15, may be used with 3ware
series 6000, 7000, and 8000 series controllers that use the 3x-xxxx
driver. \fBNote that the /dev/sda-z form is deprecated\fP starting
values of N are from 0 to 31 inclusive. The first two forms, which
refer to devices /dev/sda\-z and /dev/twe0\-15, may be used with 3ware
series 6000, 7000, and 8000 series controllers that use the 3x\-xxxx
driver. \fBNote that the /dev/sda\-z form is deprecated\fP starting
with the Linux 2.6 kernel series and may not be supported by the Linux
kernel in the near future. The final form, which refers to devices
/dev/twa0-15, must be used with 3ware 9000 series controllers, which
use the 3w-9xxx driver.
/dev/twa0\-15, must be used with 3ware 9000 series controllers, which
use the 3w\-9xxx driver.
Note that if the special character device nodes /dev/twa? and
/dev/twe? do not exist, or exist with the incorrect major or minor
numbers, smartctl will recreate them on the fly. Typically /dev/twa0
refers to the first 9000-series controller, /dev/twa1 refers to the
refers to the first 9000\-series controller, /dev/twa1 refers to the
second 9000 series controller, and so on. Likewise /dev/twe0 refers to
the first 6/7/8000-series controller, /dev/twa1 refers to the second
the first 6/7/8000\-series controller, /dev/twa1 refers to the second
6/7/8000 series controller, and so on.
Note that for the 6/7/8000 controllers, \fBany\fP of the physical
@ -274,7 +288,7 @@ messages instead: "\fB3w\-xxxx: tw_ioctl(): Passthru size (123392) too
big\fP". This can be fixed by upgrading to version 1.02.00.037 or
later of the 3w\-xxxx driver, or by applying a patch to older
versions. See \fBhttp://smartmontools.sourceforge.net/\fP for
instructions. Alternatively, use the character device /dev/twe0-15 interface.
instructions. Alternatively, use the character device /dev/twe0\-15 interface.
The selective self\-test functions (\'\-t select,A\-B\') are only supported
using the character device interface /dev/twa0\-15 and /dev/twe0\-15.
@ -296,7 +310,7 @@ where in the argument \fIhpt,L/M\fP or \fIhpt,L/M/N\fP, the integer L is the
controller id, the integer M is the channel number, and the integer N is the
PMPort number if it is available. The allowed values of L are from 1 to 4
inclusive, M are from 1 to 8 inclusive and N from 1 to 4 if PMPort available.
Note that the /dev/sda-z form should be the device node which stands for
Note that the /dev/sda\-z form should be the device node which stands for
the disks derived from the HighPoint RocketRAID controllers. And also
these values are limited by the model of the HighPoint RocketRAID controller.
@ -394,6 +408,13 @@ the integer with no spaces. For example,
The default
level is 1, so \'\-r ataioctl,1\' and \'\-r ataioctl\' are equivalent.
For testing purposes, the output of \'\-r ataioctl,2\' can later be parsed
by \fBsmartctl\fP itself if \'\-\' is used as device path argument.
The ATA command input parameters, sector data and return values are
reconstructed from the debug report read from stdin.
Then \fBsmartctl\fP internally simulates an ATA device with the same
behaviour. This is does not work for SCSI devices yet.
.TP
.B \-n POWERMODE, \-\-nocheck=POWERMODE
Specifieds if \fBsmartctl\fP should exit before performing any checks
@ -647,7 +668,7 @@ ATA/ATAPI\-5 disks seem to respect their meaning, so we have retained
the option of printing the Attribute values.
For SCSI devices the "attributes" are obtained from the temperature
and start-stop cycle counter log pages. Certain vendor specific
and start\-stop cycle counter log pages. Certain vendor specific
attributes are listed if recognised. The attributes are output in a
relatively free format (compared with ATA disk attributes).
.TP
@ -816,6 +837,19 @@ typically be either recovered or unrecoverable errors. That latter group
may need some attention. There is a description of the background scan
mechansim in section 4.18 of SBC\-3 revision 6 (see www.t10.org ).
.I scttemp, scttempsts, scttemphist [ATA]
\- [NEW EXPERIMENTAL SMARTCTL FEATURE] prints the disk temperature
information provided by the SMART Command Transport (SCT) commands.
The option \'scttempsts\' prints current temperature and temperature
ranges returned by the SCT Status command, \'scttemphist\' prints
temperature limits and the temperature history table returned by
the SCT Data Table command, and \'scttemp\' prints both.
The temperature values are preserved across power cycles.
The default temperature logging interval is 1 minute and can be
configured with the \'\-t scttempint,N[,p]\' option, see below.
The SCT commands are specified in the proposed ATA\-8 Command Set
(ACS), and are already implemented in some recent ATA\-7 disks.
.TP
.B \-v N,OPTION, \-\-vendorattribute=N,OPTION
Sets a vendor\-specific display OPTION for Attribute N. This option
@ -910,9 +944,9 @@ value for Attribute 123 in this form.
.TP
.B \-F TYPE, \-\-firmwarebug=TYPE
Modifies the behavior of \fBsmartctl\fP to compensate for some known
and understood device firmware bug. The arguments to this option are
exclusive, so that only the final option given is used. The valid
values are:
and understood device firmware or driver bug. Except \'swapid\',
the arguments to this option are exclusive, so that only the final
option given is used. The valid values are:
.I none
\- Assume that the device firmware obeys the ATA specifications. This
@ -934,15 +968,25 @@ are (1) no self\-test log printed, even though you have run self\-tests;
the number of ATA errors reported is byte swapped. Enabling this
option tells \fBsmartctl\fP to evaluate this quantity in
byte\-reversed order. An indication that your Samsung disk needs this
option is that the self-test log is printed correctly, but there are a
option is that the self\-test log is printed correctly, but there are a
very large number of errors in the SMART error log. This is because
the error count is byte swapped. Thus a disk with five errors
(0x0005) will appear to have 20480 errors (0x5000).
.I samsung3
\- Some Samsung disks (at least SP2514N with Firmware VF100\-37) report
a self\-test still in progress with 0% remaining when the test was already
completed. Enabling this option modifies the output of the self\-test
execution status (see options \'\-c\' or \'\-a\' above) accordingly.
Note that an explicit \'\-F\' option on the command line will
over\-ride any preset values for \'\-F\' (see the \'\-P\' option
below).
.I swapid
\- Fixes byte swapped ATA identify strings (device name, serial number,
firmware version) returned by some buggy device drivers.
.TP
.B \-P TYPE, \-\-presets=TYPE
Specifies whether \fBsmartctl\fP should use any preset options that
@ -1068,18 +1112,27 @@ order of minutes to complete. Note that this command can be given
during normal system operation (unless run in captive mode \- see the
\'\-C\' option below).
.I select,N\-M
\- [ATA ONLY] [NEW EXPERIMENTAL SMARTCTL FEATURE] runs a SMART
.I select,N\-M, select,N+SIZE
\- [ATA ONLY] [EXPERIMENTAL SMARTCTL FEATURE] runs a SMART
Selective Self Test, to test a \fBrange\fP of disk Logical Block
Addresses (LBAs), rather than the entire disk. Each range of LBAs
that is checked is called a "span" and is specified by a starting LBA
(N) and an ending LBA (M) with N less than or equal to M. For example
the command:
(N) and an ending LBA (M) with N less than or equal to M. The range
can also be specified as N+SIZE. A span at the end of a disk can
be specified by N\-\fBmax\fP.
For example the commands:
.nf
smartctl \-t select,10\-20 /dev/hda
smartctl \-t select,10+11 /dev/hda
.fi
runs a self test on one span consisting of LBAs ten to twenty
(inclusive). The \'\-t\' option can be given up to five times, to test
both runs a self test on one span consisting of LBAs ten to twenty
(inclusive). The command:
.nf
smartctl \-t select,100000000\-max /dev/hda
.fi
run a self test from LBA 100000000 up to the end of the disk.
The \'\-t\' option can be given up to five times, to test
up to five spans. For example the command:
.nf
smartctl \-t select,0\-100 \-t select,1000\-2000 /dev/hda
@ -1104,11 +1157,60 @@ Logical Block Addresses (LBAs).
Selective self\-tests can be run during normal system operation (unless
done in captive mode \- see the \'\-C\' option below).
[Note: this new experimental smartmontools feature is currently only
available under Linux. The Linux kernel must be compiled with the
configuration option CONFIG_IDE_TASKFILE_IO enabled. Please report
unusual or incorrect behavior to the smartmontools\-support mailing
list.]
[Note: To use this feature on Linux, the kernel must be compiled with
the configuration option CONFIG_IDE_TASKFILE_IO enabled. Please report
unusual or incorrect behavior to the smartmontools\-support mailing list.]
The following variants of the selective self\-test command use spans based
on the ranges from past tests already stored on the disk:
.I select,redo[+SIZE]
\- [ATA ONLY] [NEW EXPERIMENTAL SMARTCTL FEATURE] redo the last SMART
Selective Self Test using the same LBA range. The starting LBA is identical
to the LBA used by last test, same for ending LBA unless a new span size
is specified by optional +SIZE argument.
For example the commands:
.nf
smartctl \-t select,10\-20 /dev/hda
smartctl \-t select,redo /dev/hda
smartctl \-t select,redo+20 /dev/hda
.fi
have the same effect as:
.nf
smartctl \-t select,10\-20 /dev/hda
smartctl \-t select,10\-20 /dev/hda
smartctl \-t select,10\-29 /dev/hda
.fi
.I select,next[+SIZE]
\- [ATA ONLY] [NEW EXPERIMENTAL SMARTCTL FEATURE] runs a SMART Selective
Self Test on the LBA range which follows the range of the last test. The
starting LBA is set to (ending LBA +1) of the last test. A new span size
may be specified by the optional +SIZE argument.
For example the commands:
.nf
smartctl \-t select,0\-999 /dev/hda
smartctl \-t select,next /dev/hda
smartctl \-t select,next+2000 /dev/hda
.fi
have the same effect as:
.nf
smartctl \-t select,0\-999 /dev/hda
smartctl \-t select,1000\-1999 /dev/hda
smartctl \-t select,2000\-3999 /dev/hda
.fi
If the last test ended at the last LBA of the disk, the new range starts
at LBA 0. The span size of the last span of a disk is adjusted such that
the total number of spans to check the full disk will not be changed
by future uses of \'\-t select,next\'.
.I select,cont[+SIZE]
\- [ATA ONLY] [NEW EXPERIMENTAL SMARTCTL FEATURE] performs a \'redo\'
(above) if the self test status reports that the last test was aborted
by the host. Otherwise it run the \'next\' (above) test.
.I afterselect,on
\- [ATA ONLY] perform an offline read scan after a Selective Self\-test
@ -1136,6 +1238,15 @@ option must be use together with one or more of the \fIselect,N\-M\fP
options above. The value of this option is preserved between selective
self\-tests.
.I scttempint,N[,p]
\- [ATA ONLY] [NEW EXPERIMENTAL SMARTCTL FEATURE] set the time interval
for SCT temperature logging to N minutes. If \',p\' is specified, the
setting is preserved across power cycles. Otherwise, the setting is
volatile and will be reverted to default (1 minute), or last
non-volatile setting by the next hard reset. This command also clears
the temperature history table. See \'\-l scttemp\' above for more
information about SCT temperature logging.
.TP
.B \-C, \-\-captive
Runs self\-tests in captive mode. This has no effect with \'\-t
@ -1284,7 +1395,7 @@ in a SMART data structure (see \'\-b\' option above).
SMART status check returned "DISK FAILING".
.TP
.B Bit 4:
SMART status check returned "DISK OK" but we found prefail Attributes <= threshold.
We found prefail Attributes <= threshold.
.TP
.B Bit 5:
SMART status check returned "DISK OK" but we found that some (usage
@ -1366,12 +1477,12 @@ REFERENCES FOR SMART
.fi
An introductory article about smartmontools is \fIMonitoring Hard
Disks with SMART\fP, by Bruce Allen, Linux Journal, January 2004,
pages 74-77. This is \fBhttp://www.linuxjournal.com/article.php?sid=6983\fP
pages 74\-77. This is \fBhttp://www.linuxjournal.com/article.php?sid=6983\fP
online.
If you would like to understand better how SMART works, and what it
does, a good place to start is with Sections 4.8 and 6.54 of the first
volume of the \'AT Attachment with Packet Interface-7\' (ATA/ATAPI-7)
volume of the \'AT Attachment with Packet Interface\-7\' (ATA/ATAPI\-7)
specification. This documents the SMART functionality which the
\fBsmartmontools\fP utilities provide access to. You can find
Revision 4b of this document at
@ -1389,7 +1500,7 @@ these documents may be found in the References section of the
.SH
CVS ID OF THIS PAGE:
$Id: smartctl.8.in,v 1.90 2006/12/20 07:30:43 sxzzsf Exp $
$Id: smartctl.8.in,v 1.103 2007/09/06 08:48:55 ballen4705 Exp $
.\" Local Variables:
.\" mode: nroff
.\" End:

1358
smartctl.8.in.orig Normal file

File diff suppressed because it is too large Load Diff

View File

@ -3,7 +3,7 @@
*
* Home page of code is: http://smartmontools.sourceforge.net
*
* Copyright (C) 2002-6 Bruce Allen <smartmontools-support@lists.sourceforge.net>
* Copyright (C) 2002-7 Bruce Allen <smartmontools-support@lists.sourceforge.net>
* Copyright (C) 2000 Michael Cornwell <cornwell@acm.org>
*
* This program is free software; you can redistribute it and/or modify
@ -36,6 +36,11 @@
#include <unistd.h>
#endif
#if defined(__QNXNTO__)
#include <unistd.h>
#endif
#include "int64.h"
#include "atacmds.h"
#include "ataprint.h"
@ -50,7 +55,7 @@
extern const char *os_solaris_ata_s_cvsid;
#endif
extern const char *atacmdnames_c_cvsid, *atacmds_c_cvsid, *ataprint_c_cvsid, *knowndrives_c_cvsid, *os_XXXX_c_cvsid, *scsicmds_c_cvsid, *scsiprint_c_cvsid, *utility_c_cvsid;
const char* smartctl_c_cvsid="$Id: smartctl.cpp,v 1.156 2006/10/09 11:45:12 guidog Exp $"
const char* smartctl_c_cvsid="$Id: smartctl.cpp,v 1.168 2007/11/13 14:53:27 jhering Exp $"
ATACMDS_H_CVSID ATAPRINT_H_CVSID CONFIG_H_CVSID EXTERN_H_CVSID INT64_H_CVSID KNOWNDRIVES_H_CVSID SCSICMDS_H_CVSID SCSIPRINT_H_CVSID SMARTCTL_H_CVSID UTILITY_H_CVSID;
// This is a block containing all the "control variables". We declare
@ -69,7 +74,7 @@ void printslogan(){
#else
const char * ver = SMARTMONTOOLS_BUILD_HOST;
#endif
pout("smartctl version %s [%s] Copyright (C) 2002-6 Bruce Allen\n", PACKAGE_VERSION, ver);
pout("smartctl version %s [%s] Copyright (C) 2002-7 Bruce Allen\n", PACKAGE_VERSION, ver);
pout("Home page is " PACKAGE_HOMEPAGE "\n\n");
return;
}
@ -82,7 +87,7 @@ void PrintOneCVS(const char *a_cvs_id){
}
void printcopy(){
char *configargs=strlen(SMARTMONTOOLS_CONFIGURE_ARGS)?SMARTMONTOOLS_CONFIGURE_ARGS:"[no arguments given]";
const char *configargs=strlen(SMARTMONTOOLS_CONFIGURE_ARGS)?SMARTMONTOOLS_CONFIGURE_ARGS:"[no arguments given]";
pout("smartctl comes with ABSOLUTELY NO WARRANTY. This\n");
pout("is free software, and you are welcome to redistribute it\n");
@ -141,7 +146,7 @@ void Usage (void){
#ifdef HAVE_GETOPT_LONG
printf(
" -q TYPE, --quietmode=TYPE (ATA)\n"
" Set smartctl quiet mode to one of: errorsonly, silent\n\n"
" Set smartctl quiet mode to one of: errorsonly, silent, noserial\n\n"
" -d TYPE, --device=TYPE\n"
" Specify device type to one of: ata, scsi, marvell, sat, 3ware,N\n\n"
" -T TYPE, --tolerance=TYPE (ATA)\n"
@ -155,9 +160,10 @@ void Usage (void){
);
#else
printf(
" -q TYPE Set smartctl quiet mode to one of: errorsonly, silent (ATA)\n"
" -q TYPE Set smartctl quiet mode to one of: errorsonly, silent, (ATA)\n"
" noserial\n"
" -d TYPE Specify device type to one of: ata, scsi, 3ware,N\n"
" -T TYPE Tolerance: normal, conservative,permissive,verypermissive (ATA\n"
" -T TYPE Tolerance: normal, conservative,permissive,verypermissive (ATA)\n"
" -b TYPE Set action on bad checksum to one of: warn, exit, ignore (ATA)\n"
" -r TYPE Report transactions (see man page)\n"
" -n MODE No check if: never, sleep, standby, idle (see man page) (ATA)\n\n"
@ -191,11 +197,12 @@ void Usage (void){
" Show device SMART vendor-specific Attributes and values\n\n"
" -l TYPE, --log=TYPE\n"
" Show device log. TYPE: error, selftest, selective, directory,\n"
" background\n\n"
" background, scttemp[sts,hist]\n\n"
" -v N,OPTION , --vendorattribute=N,OPTION (ATA)\n"
" Set display OPTION for vendor Attribute N (see man page)\n\n"
" -F TYPE, --firmwarebug=TYPE (ATA)\n"
" Use firmware bug workaround: none, samsung, samsung2\n\n"
" Use firmware bug workaround: none, samsung, samsung2,\n"
" samsung3, swapid\n\n"
" -P TYPE, --presets=TYPE (ATA)\n"
" Drive-specific presets: use, ignore, show, showall\n\n"
);
@ -205,9 +212,10 @@ void Usage (void){
" -c Show device SMART capabilities (ATA)\n"
" -A Show device SMART vendor-specific Attributes and values (ATA)\n"
" -l TYPE Show device log. TYPE: error, selftest, selective, directory,\n"
" background\n"
" background, scttemp[sts,hist]\n"
" -v N,OPT Set display OPTion for vendor Attribute N (see man page) (ATA)\n"
" -F TYPE Use firmware bug workaround: none, samsung, samsung2 (ATA)\n"
" -F TYPE Use firmware bug workaround: none, samsung, samsung2, (ATA)\n"
" samsung3, swapid\n"
" -P TYPE Drive-specific presets: use, ignore, show, showall (ATA)\n\n"
);
#endif
@ -215,7 +223,8 @@ void Usage (void){
#ifdef HAVE_GETOPT_LONG
printf(
" -t TEST, --test=TEST\n"
" Run test. TEST is: offline short long conveyance select,M-N pending,N afterselect,on afterselect,off\n\n"
" Run test. TEST: offline short long conveyance select,M-N\n"
" pending,N afterselect,[on|off] scttempint,N[,p]\n\n"
" -C, --captive\n"
" Do test in captive mode (along with -t)\n\n"
" -X, --abort\n"
@ -223,7 +232,8 @@ void Usage (void){
);
#else
printf(
" -t TEST Run test. TEST is: offline short long conveyance select,M-N pending,N afterselect,on afterselect,off\n"
" -t TEST Run test. TEST: offline short long conveyance select,M-N\n"
" pending,N afterselect,[on|off] scttempint,N[,p]\n"
" -C Do test in captive mode (along with -t)\n"
" -X Abort any non-captive test\n\n"
);
@ -237,7 +247,7 @@ void Usage (void){
const char *getvalidarglist(char opt) {
switch (opt) {
case 'q':
return "errorsonly, silent";
return "errorsonly, silent, noserial";
case 'd':
return "ata, scsi, marvell, sat, 3ware,N, hpt,L/M/N cciss,N";
case 'T':
@ -251,13 +261,13 @@ const char *getvalidarglist(char opt) {
case 'S':
return "on, off";
case 'l':
return "error, selftest, selective, directory, background";
return "error, selftest, selective, directory, background, scttemp[sts|hist]";
case 'P':
return "use, ignore, show, showall";
case 't':
return "offline, short, long, conveyance, select,M-N, pending,N, afterselect,on, afterselect,off";
return "offline, short, long, conveyance, select,M-N, pending,N, afterselect,[on|off], scttempint,N[,p]";
case 'F':
return "none, samsung, samsung2";
return "none, samsung, samsung2, samsung3, swapid";
case 'n':
return "never, sleep, standby, idle";
case 'v':
@ -368,6 +378,8 @@ void ParseOpts (int argc, char** argv){
} else if (!strcmp(optarg,"silent")) {
con->printing_switchable = FALSE;
con->dont_print = TRUE;
} else if (!strcmp(optarg,"noserial")) {
con->dont_print_serial = TRUE;
} else {
badarg = TRUE;
}
@ -463,8 +475,8 @@ void ParseOpts (int argc, char** argv){
if (split_report_arg2(s, &i)) {
sprintf(extraerror, "Option -d 3ware,N requires N to be a non-negative integer\n");
badarg = TRUE;
} else if (i<0 || i>15) {
sprintf(extraerror, "Option -d 3ware,N (N=%d) must have 0 <= N <= 15\n", i);
} else if (i<0 || i>31) {
sprintf(extraerror, "Option -d 3ware,N (N=%d) must have 0 <= N <= 31\n", i);
badarg = TRUE;
} else {
// NOTE: controller_port == disk number + 1
@ -476,8 +488,8 @@ void ParseOpts (int argc, char** argv){
if (split_report_arg2(s, &i)) {
sprintf(extraerror, "Option -d cciss,N requires N to be a non-negative integer\n");
badarg = TRUE;
} else if (i<0 || i>15) {
sprintf(extraerror, "Option -d cciss,N (N=%d) must have 0 <= N <= 15\n", i);
} else if (i<0 || i>127) {
sprintf(extraerror, "Option -d cciss,N (N=%d) must have 0 <= N <= 127\n", i);
badarg = TRUE;
} else {
// NOTE: controller_port == drive number
@ -588,6 +600,10 @@ void ParseOpts (int argc, char** argv){
con->fixfirmwarebug = FIX_SAMSUNG;
} else if (!strcmp(optarg,"samsung2")) {
con->fixfirmwarebug = FIX_SAMSUNG2;
} else if (!strcmp(optarg,"samsung3")) {
con->fixfirmwarebug = FIX_SAMSUNG3;
} else if (!strcmp(optarg,"swapid")) {
con->fixswappedid = TRUE;
} else {
badarg = TRUE;
}
@ -604,11 +620,17 @@ void ParseOpts (int argc, char** argv){
} else if (!strcmp(optarg,"selftest")) {
con->smartselftestlog = TRUE;
} else if (!strcmp(optarg, "selective")) {
con->selectivetestlog = TRUE;
con->selectivetestlog = TRUE;
} else if (!strcmp(optarg,"directory")) {
con->smartlogdirectory = TRUE;
} else if (!strcmp(optarg,"background")) {
con->smartbackgroundlog = TRUE;
} else if (!strcmp(optarg,"scttemp")) {
con->scttempsts = con->scttemphist = TRUE;
} else if (!strcmp(optarg,"scttempsts")) {
con->scttempsts = TRUE;
} else if (!strcmp(optarg,"scttemphist")) {
con->scttemphist = TRUE;
} else {
badarg = TRUE;
}
@ -702,10 +724,9 @@ void ParseOpts (int argc, char** argv){
con->pendingtime=i+1;
}
} else if (!strncmp(optarg,"select",strlen("select"))) {
// parse range of LBAs to test
uint64_t start, stop;
if (split_selective_arg(optarg, &start, &stop)) {
// parse range of LBAs to test
uint64_t start, stop; int mode;
if (split_selective_arg(optarg, &start, &stop, &mode)) {
sprintf(extraerror, "Option -t select,M-N must have non-negative integer M and N\n");
badarg = TRUE;
} else {
@ -721,9 +742,19 @@ void ParseOpts (int argc, char** argv){
}
con->smartselectivespan[con->smartselectivenumspans][0] = start;
con->smartselectivespan[con->smartselectivenumspans][1] = stop;
con->smartselectivemode[con->smartselectivenumspans] = mode;
con->smartselectivenumspans++;
con->testcase = SELECTIVE_SELF_TEST;
}
} else if (!strncmp(optarg, "scttempint,", sizeof("scstempint,")-1)) {
unsigned interval = 0; int n1 = -1, n2 = -1, len = strlen(optarg);
if (!( sscanf(optarg,"scttempint,%u%n,p%n", &interval, &n1, &n2) == 1
&& 0 < interval && interval <= 0xffff && (n1 == len || n2 == len))) {
strcpy(extraerror, "Option -t scttempint,N[,p] must have positive integer N\n");
badarg = TRUE;
}
con->scttempint = interval;
con->scttempintp = (n2 == len);
} else {
badarg = TRUE;
}
@ -934,6 +965,16 @@ int main (int argc, char **argv){
device = argv[argc-1];
// Device name "-": Parse "smartctl -r ataioctl,2 ..." output
if (!strcmp(device,"-")) {
if (con->controller_type != CONTROLLER_UNKNOWN) {
pout("Smartctl: -d option is not allowed in conjunction with device name \"-\".\n");
UsageSummary();
return FAILCMD;
}
con->controller_type = CONTROLLER_PARSEDEV;
}
// If use has specified 3ware controller, determine which interface
if (con->controller_type == CONTROLLER_3WARE) {
con->controller_type=guess_device_type(device);
@ -976,7 +1017,10 @@ int main (int argc, char **argv){
// present (e.g. with st). Opening is retried O_RDONLY if read-only
// media prevents opening O_RDWR (it cannot happen for scsi generic
// devices, but it can for the others).
fd = deviceopen(device, mode);
if (con->controller_type != CONTROLLER_PARSEDEV)
fd = deviceopen(device, mode);
else
fd = parsedev_open(device);
if (fd<0) {
char errmsg[256];
snprintf(errmsg,256,"Smartctl open device: %s failed",argv[argc-1]);
@ -1008,5 +1052,10 @@ int main (int argc, char **argv){
break;
}
if (con->controller_type != CONTROLLER_PARSEDEV)
deviceclose(fd);
else
parsedev_close(fd);
return retval;
}

View File

@ -1,7 +1,7 @@
.ig
Copyright (C) 2002-6 Bruce Allen <smartmontools-support@lists.sourceforge.net>
Copyright (C) 2002-7 Bruce Allen <smartmontools-support@lists.sourceforge.net>
$Id: smartd.8.in,v 1.113 2006/12/20 07:30:43 sxzzsf Exp $
$Id: smartd.8.in,v 1.120 2007/11/01 20:53:29 chrfranke Exp $
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
@ -101,26 +101,21 @@ Examine all entries \fB"/dev/rdsk/c?t?d?s?"\fP for IDE/ATA and SCSI disk
devices, and entries \fB"/dev/rmt/*"\fP for SCSI tape devices.
.IP \fBDARWIN:\fP 9
The IOService plane is scanned for ATA block storage devices.
.IP \fBWINDOWS:\fP 9
Examine all entries \fB"/dev/hd[a-j]"\fP ("\\\\.\\PhysicalDrive[0-9]")
for IDE/ATA devices on WinNT4/2000/XP, \fB"/dev/hd[a-d]"\fP
(bitmask from "\\\\.\\SMARTVSD") for IDE/ATA devices on Win95/98/98SE/ME.
Examines all entries \fB"/dev/scsi[0\-9][0\-f]"\fP for SCSI devices
.IP \fBWINDOWS\ 9x/ME\fP: 9
Examine all entries \fB"/dev/hd[a-d]"\fP (bitmask
from "\\\\.\\SMARTVSD") for IDE/ATA devices.
Examine all entries \fB"/dev/scsi[0\-9][0\-f]"\fP for SCSI devices
on ASPI adapter 0\-9, ID 0\-15.
If a 3ware 9000 controller is installed, examine all entries
\fB"/dev/hdX,N"\fP for the first logical drive (\'unit\'
\fB"/dev/hdX"\fP) and all physical disks (\'ports\' \fB",N"\fP)
detected behind this controller. Same for a second controller if present.
.IP \fBWINDOWS\ NT4/2000/XP/2003/Vista\fP: 9
Examine all entries \fB"/dev/sd[a-j]"\fP ("\\\\.\\PhysicalDrive[0-9]")
for IDE/(S)ATA and SCSI disk devices
The following forms are not scanned for but can be given explicitly in the
configuration file and only apply to WinNT4/2000/XP/2003. The
form \fB"/dev/sd[a\-z]"\fP can be given for SCSI
disks "\\\\.\\PhysicalDrive[0\-25]" (where "a" maps to "0"). Additionally
the form \fB"/dev/pd[0\-255]"\fP can be given for SCSI
disks "\\\\.\\PhysicalDrive[0\-255]". The form \fB"/dev/tape[0\-255]"\fP
can be given for SCSI tape drives "\\\\.\\Tape[0\-255]".
If a 3ware 9000 controller is installed, examine all entries
\fB"/dev/sdX,N"\fP for the first logical drive (\'unit\'
\fB"/dev/sdX"\fP) and all physical disks (\'ports\' \fB",N"\fP)
detected behind this controller. Same for a second controller if present.
.IP \fBCYGWIN\fP: 9
See "WINDOWS" above.
See "WINDOWS NT4/2000/XP/2003/Vista" above.
.IP \fBOS/2,eComStation\fP: 9
Use the form \fB"/dev/hd[a\-z]"\fP for IDE/ATA devices.
.PP
@ -256,6 +251,16 @@ messages from the event viewer. Use \'\fBsyslogevt -r smartd\fP\'
to register, \'\fBsyslogevt -u smartd\fP\' to unregister and
\'\fBsyslogevt\fP\' for more help.
.TP
.B \-n, \-\-no\-fork
Do not fork into background; this is useful when executed from modern
init methods like initng, minit or supervise.
On Cygwin, this allows running \fBsmartd\fP as service via cygrunsrv,
see NOTES below.
On Windows, this option is not available, use \'\-\-service\' instead.
.TP
.B \-p NAME, \-\-pidfile=NAME
Writes pidfile \fINAME\fP containing the \fBsmartd\fP Process ID
@ -352,8 +357,8 @@ equivalent.
.B \-\-service
Cygwin and Windows only: Enables \fBsmartd\fP to run as a Windows service.
On Cygwin, this option simply prevents forking into background mode to
allow running \fBsmartd\fP as service via cygrunsrv, see NOTES below.
On Cygwin, this option is kept for backward compatibility only.
It has the same effect as \'\-n, \-\-no\-fork\', see above.
On Windows, this option enables the buildin service support.
The option must be specified in the service command line as the first
@ -671,10 +676,10 @@ controllers (using the Marvell rather than libata driver).
.I 3ware,N
\- the device consists of one or more ATA disks connected to a 3ware
RAID controller. The non-negative integer N (in the range from 0 to 15
RAID controller. The non-negative integer N (in the range from 0 to 31
inclusive) denotes which disk on the controller is monitored. In log
files and email messages this disk will be identified as 3ware_disk_XX
with XX in the range from 00 to 15 inclusive.
with XX in the range from 00 to 31 inclusive.
This Directive may at first appear confusing, because the 3ware
controller is a SCSI device (such as /dev/sda) and should be listed as
@ -944,6 +949,10 @@ interrupted to begin another test.
\fBsmartd\fP will not attempt to run \fBany\fP type of test if another
test was already started or run in the same hour.
To avoid performance problems during system boot, \fBsmartd\fP will
not attempt to run any scheduled tests following the very first
device polling (unless \'\-q onecheck\' is specified).
Each time a test is run, \fBsmartd\fP will log an entry to SYSLOG.
You can use these or the '-q showtests' command-line option to verify
that you constructed \fBREGEXP\fP correctly. The matching order
@ -1102,7 +1111,7 @@ is set to the argument of \-M exec, if present or else to \'mail\'
is set to the device path (examples: /dev/hda, /dev/sdb).
.IP \fBSMARTD_DEVICETYPE\fP 4
is set to the device type (possible values: ata, scsi, 3ware,N, hpt,L/M/N).
Here N=0,...,15 denotes the ATA disk behind a 3ware RAID controller and
Here N=0,...,23 denotes the ATA disk behind a 3ware RAID controller and
L/M/N denotes the SATA disk behind a HighPoint RocketRAID controller.
.IP \fBSMARTD_DEVICESTRING\fP 4
is set to the device description. For SMARTD_DEVICETYPE of ata or
@ -1411,6 +1420,12 @@ are (1) no self-test log printed, even though you have run self-tests;
number of ATA errors reported is byte swapped. Enabling this option
tells \fBsmartd\fP to evaluate this quantity in byte-reversed order.
.I samsung3
\- Some Samsung disks (at least SP2514N with Firmware VF100\-37) report
a self\-test still in progress with 0% remaining when the test was already
completed. If this directive is specified, \fBsmartd\fP will not skip the
next scheduled self\-test (see Directive \'\-s\' above) in this case.
Note that an explicit \'\-F\' Directive will over-ride any preset
values for \'\-F\' (see the \'\-P\' option below).
@ -1950,4 +1965,4 @@ smartmontools home page at \fBhttp://smartmontools.sourceforge.net/#references\f
.SH
CVS ID OF THIS PAGE:
$Id: smartd.8.in,v 1.113 2006/12/20 07:30:43 sxzzsf Exp $
$Id: smartd.8.in,v 1.120 2007/11/01 20:53:29 chrfranke Exp $

1932
smartd.8.in.orig Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +1,7 @@
.ig
Copyright (C) 2002-6 Bruce Allen <smartmontools-support@lists.sourceforge.net>
Copyright (C) 2002-7 Bruce Allen <smartmontools-support@lists.sourceforge.net>
$Id: smartd.conf.5.in,v 1.82 2006/12/20 07:30:43 sxzzsf Exp $
$Id: smartd.conf.5.in,v 1.86 2007/10/20 13:02:50 chrfranke Exp $
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
@ -298,10 +298,10 @@ controllers (using the Marvell rather than libata driver).
.I 3ware,N
\- the device consists of one or more ATA disks connected to a 3ware
RAID controller. The non-negative integer N (in the range from 0 to 15
RAID controller. The non-negative integer N (in the range from 0 to 31
inclusive) denotes which disk on the controller is monitored. In log
files and email messages this disk will be identified as 3ware_disk_XX
with XX in the range from 00 to 15 inclusive.
with XX in the range from 00 to 31 inclusive.
This Directive may at first appear confusing, because the 3ware
controller is a SCSI device (such as /dev/sda) and should be listed as
@ -571,6 +571,10 @@ interrupted to begin another test.
\fBsmartd\fP will not attempt to run \fBany\fP type of test if another
test was already started or run in the same hour.
To avoid performance problems during system boot, \fBsmartd\fP will
not attempt to run any scheduled tests following the very first
device polling (unless \'\-q onecheck\' is specified).
Each time a test is run, \fBsmartd\fP will log an entry to SYSLOG.
You can use these or the '-q showtests' command-line option to verify
that you constructed \fBREGEXP\fP correctly. The matching order
@ -729,7 +733,7 @@ is set to the argument of \-M exec, if present or else to \'mail\'
is set to the device path (examples: /dev/hda, /dev/sdb).
.IP \fBSMARTD_DEVICETYPE\fP 4
is set to the device type (possible values: ata, scsi, 3ware,N, hpt,L/M/N).
Here N=0,...,15 denotes the ATA disk behind a 3ware RAID controller and
Here N=0,...,23 denotes the ATA disk behind a 3ware RAID controller and
L/M/N denotes the SATA disk behind a HighPoint RocketRAID controller.
.IP \fBSMARTD_DEVICESTRING\fP 4
is set to the device description. For SMARTD_DEVICETYPE of ata or
@ -1038,6 +1042,12 @@ are (1) no self-test log printed, even though you have run self-tests;
number of ATA errors reported is byte swapped. Enabling this option
tells \fBsmartd\fP to evaluate this quantity in byte-reversed order.
.I samsung3
\- Some Samsung disks (at least SP2514N with Firmware VF100\-37) report
a self\-test still in progress with 0% remaining when the test was already
completed. If this directive is specified, \fBsmartd\fP will not skip the
next scheduled self\-test (see Directive \'\-s\' above) in this case.
Note that an explicit \'\-F\' Directive will over-ride any preset
values for \'\-F\' (see the \'\-P\' option below).
@ -1347,4 +1357,4 @@ SEE ALSO:
.SH
CVS ID OF THIS PAGE:
$Id: smartd.conf.5.in,v 1.82 2006/12/20 07:30:43 sxzzsf Exp $
$Id: smartd.conf.5.in,v 1.86 2007/10/20 13:02:50 chrfranke Exp $

View File

@ -1,7 +1,7 @@
/*
* Home page of code is: http://smartmontools.sourceforge.net
*
* Copyright (C) 2002-6 Bruce Allen <smartmontools-support@lists.sourceforge.net>
* Copyright (C) 2002-7 Bruce Allen <smartmontools-support@lists.sourceforge.net>
* Copyright (C) 2000 Michael Cornwell <cornwell@acm.org>
*
* This program is free software; you can redistribute it and/or modify
@ -119,14 +119,14 @@ extern "C" int getdomainname(char *, int); // no declaration in header files!
extern const char *atacmdnames_c_cvsid, *atacmds_c_cvsid, *ataprint_c_cvsid, *escalade_c_cvsid,
*knowndrives_c_cvsid, *os_XXXX_c_cvsid, *scsicmds_c_cvsid, *utility_c_cvsid;
static const char *filenameandversion="$Id: smartd.cpp,v 1.384 2006/11/12 04:49:09 dpgilbert Exp $";
static const char *filenameandversion="$Id: smartd.cpp,v 1.394 2007/11/01 20:53:30 chrfranke Exp $";
#ifdef NEED_SOLARIS_ATA_CODE
extern const char *os_solaris_ata_s_cvsid;
#endif
#ifdef _WIN32
extern const char *daemon_win32_c_cvsid, *hostname_win32_c_cvsid, *syslog_win32_c_cvsid;
#endif
const char *smartd_c_cvsid="$Id: smartd.cpp,v 1.384 2006/11/12 04:49:09 dpgilbert Exp $"
const char *smartd_c_cvsid="$Id: smartd.cpp,v 1.394 2007/11/01 20:53:30 chrfranke Exp $"
ATACMDS_H_CVSID ATAPRINT_H_CVSID CONFIG_H_CVSID
#ifdef DAEMON_WIN32_H_CVSID
DAEMON_WIN32_H_CVSID
@ -174,9 +174,9 @@ static int quit=0;
// command-line; this is the default syslog(3) log facility to use.
static int facility=LOG_DAEMON;
#ifdef __CYGWIN__
// command-line: running as service, so don't fork()
static int is_service=0;
#ifndef _WIN32
// command-line: fork into background?
static bool do_fork=true;
#endif
// used for control of printing, passing arguments to atacmds.c
@ -310,7 +310,7 @@ void PrintOneCVS(const char *a_cvs_id){
// prints CVS identity information for the executable
void PrintCVS(void){
char *configargs=strlen(SMARTMONTOOLS_CONFIGURE_ARGS)?SMARTMONTOOLS_CONFIGURE_ARGS:"[no arguments given]";
const char *configargs=strlen(SMARTMONTOOLS_CONFIGURE_ARGS)?SMARTMONTOOLS_CONFIGURE_ARGS:"[no arguments given]";
PrintOut(LOG_INFO,(char *)copyleftstring);
PrintOut(LOG_INFO,"CVS version IDs of files used to build this code are:\n");
@ -1002,29 +1002,31 @@ void DaemonInit(){
// streams since both parent and child get copies of the buffers.
fflush(NULL);
if ((pid=fork()) < 0) {
// unable to fork!
PrintOut(LOG_CRIT,"smartd unable to fork daemon process!\n");
EXIT(EXIT_STARTUP);
if (do_fork) {
if ((pid=fork()) < 0) {
// unable to fork!
PrintOut(LOG_CRIT,"smartd unable to fork daemon process!\n");
EXIT(EXIT_STARTUP);
}
else if (pid)
// we are the parent process -- exit cleanly
EXIT(0);
// from here on, we are the child process.
setsid();
// Fork one more time to avoid any possibility of having terminals
if ((pid=fork()) < 0) {
// unable to fork!
PrintOut(LOG_CRIT,"smartd unable to fork daemon process!\n");
EXIT(EXIT_STARTUP);
}
else if (pid)
// we are the parent process -- exit cleanly
EXIT(0);
// Now we are the child's child...
}
else if (pid)
// we are the parent process -- exit cleanly
EXIT(0);
// from here on, we are the child process.
setsid();
// Fork one more time to avoid any possibility of having terminals
if ((pid=fork()) < 0) {
// unable to fork!
PrintOut(LOG_CRIT,"smartd unable to fork daemon process!\n");
EXIT(EXIT_STARTUP);
}
else if (pid)
// we are the parent process -- exit cleanly
EXIT(0);
// Now we are the child's child...
// close any open file descriptors
for (i=getdtablesize();i>=0;--i)
@ -1044,7 +1046,8 @@ void DaemonInit(){
umask(0);
chdir("/");
PrintOut(LOG_INFO, "smartd has fork()ed into background mode. New PID=%d.\n", (int)getpid());
if (do_fork)
PrintOut(LOG_INFO, "smartd has fork()ed into background mode. New PID=%d.\n", (int)getpid());
#else // _WIN32
@ -1100,7 +1103,7 @@ void PrintHead(){
#else
const char * ver = SMARTMONTOOLS_BUILD_HOST;
#endif
PrintOut(LOG_INFO,"smartd version %s [%s] Copyright (C) 2002-6 Bruce Allen\n", PACKAGE_VERSION, ver);
PrintOut(LOG_INFO,"smartd version %s [%s] Copyright (C) 2002-7 Bruce Allen\n", PACKAGE_VERSION, ver);
PrintOut(LOG_INFO,"Home page is " PACKAGE_HOMEPAGE "\n\n");
return;
}
@ -1133,7 +1136,7 @@ void Directives() {
" -v N,ST Modifies labeling of Attribute N (see man page) \n"
" -P TYPE Drive-specific presets: use, ignore, show, showall\n"
" -a Default: -H -f -t -l error -l selftest -C 197 -U 198\n"
" -F TYPE Firmware bug workaround: none, samsung, samsung2\n"
" -F TYPE Firmware bug workaround: none, samsung, samsung2, samsung3\n"
" # Comment: text after a hash sign is ignored\n"
" \\ Line continuation character\n"
"Attribute ID is a decimal integer 1 <= ID <= 255\n"
@ -1186,24 +1189,23 @@ void Usage (void){
#else
PrintOut(LOG_INFO," Log to \"./smartd.log\", stdout, stderr [default is event log]\n\n");
#endif
#ifndef _WIN32
PrintOut(LOG_INFO," -n, --no-fork\n");
PrintOut(LOG_INFO," Do not fork into background\n\n");
#endif // _WIN32
PrintOut(LOG_INFO," -p NAME, --pidfile=NAME\n");
PrintOut(LOG_INFO," Write PID file NAME\n\n");
PrintOut(LOG_INFO," -q WHEN, --quit=WHEN\n");
PrintOut(LOG_INFO," Quit on one of: %s\n\n", GetValidArgList('q'));
PrintOut(LOG_INFO," -r, --report=TYPE\n");
PrintOut(LOG_INFO," Report transactions for one of: %s\n\n", GetValidArgList('r'));
#if defined(_WIN32) || defined(__CYGWIN__)
#ifdef _WIN32
PrintOut(LOG_INFO," --service\n");
PrintOut(LOG_INFO," Running as windows service (see man page), install with:\n");
#ifdef _WIN32
PrintOut(LOG_INFO," smartd install [options]\n");
PrintOut(LOG_INFO," Remove service with:\n");
PrintOut(LOG_INFO," smartd remove\n\n");
#else
PrintOut(LOG_INFO," /etc/rc.d/init.d/smartd install [options]\n");
PrintOut(LOG_INFO," Remove service with:\n");
PrintOut(LOG_INFO," /etc/rc.d/init.d/smartd remove\n\n");
#endif
#endif // _WIN32 || __CYGWIN__
PrintOut(LOG_INFO," -V, --version, --license, --copyright\n");
PrintOut(LOG_INFO," Print License, Copyright, and version information\n");
@ -1214,6 +1216,7 @@ void Usage (void){
PrintOut(LOG_INFO," -h Display this help and exit\n");
PrintOut(LOG_INFO," -i N Set interval between disk checks to N seconds, where N >= 10\n");
PrintOut(LOG_INFO," -l local? Use syslog facility local0 - local7, or daemon\n");
PrintOut(LOG_INFO," -n Do not fork into background\n");
PrintOut(LOG_INFO," -p NAME Write PID file NAME\n");
PrintOut(LOG_INFO," -q WHEN Quit on one of: %s\n", GetValidArgList('q'));
PrintOut(LOG_INFO," -r TYPE Report transactions for one of: %s\n", GetValidArgList('r'));
@ -2041,7 +2044,7 @@ void PrintTestSchedule(cfgfile **atadevices, cfgfile **scsidevices){
// FixGlibcTimeZoneBug(); // done in PrintOut()
now=time(NULL);
dateandtimezoneepoch(datenow, now);
for (seconds=0; seconds<3600L*24*90; seconds+=checktime) {
for (seconds=checktime; seconds<3600L*24*90; seconds+=checktime) {
// Check for each device whether a test will be run
time_t testtime = now + seconds;
for (i=0; i<numdev; i++) {
@ -2187,9 +2190,14 @@ int DoATASelfTest(int fd, cfgfile *cfg, char testtype) {
// If currently running a self-test, do not interrupt it to start another.
if (15==(data.self_test_exec_status >> 4)) {
PrintOut(LOG_INFO, "Device: %s, skip scheduled %sTest; %1d0%% remaining of current Self-Test.\n",
name, testname, (int)(data.self_test_exec_status & 0x0f));
return 1;
if (cfg->fixfirmwarebug == FIX_SAMSUNG3 && data.self_test_exec_status == 0xf0) {
PrintOut(LOG_INFO, "Device: %s, will not skip scheduled %sTest "
"despite unclear Self-Test byte (SAMSUNG Firmware bug).\n", name, testname);
} else {
PrintOut(LOG_INFO, "Device: %s, skip scheduled %sTest; %1d0%% remaining of current Self-Test.\n",
name, testname, (int)(data.self_test_exec_status & 0x0f));
return 1;
}
}
// else execute the test, and return status
@ -2253,7 +2261,7 @@ static void CheckTemperature(cfgfile * cfg, unsigned char currtemp, unsigned cha
}
}
int ATACheckDevice(cfgfile *cfg){
int ATACheckDevice(cfgfile *cfg, bool allow_selftests){
int fd,i;
char *name=cfg->name;
char *mode="ATA";
@ -2264,6 +2272,10 @@ int ATACheckDevice(cfgfile *cfg){
con->controller_port=cfg->controller_port;
con->controller_type=cfg->controller_type;
con->controller_explicit=cfg->controller_explicit;
// Highpoint-specific data
con->hpt_data[0]=cfg->hpt_data[0];
con->hpt_data[1]=cfg->hpt_data[1];
con->hpt_data[2]=cfg->hpt_data[2];
// If user has asked, test the email warning system
if (cfg->mailwarn && cfg->mailwarn->emailtest)
@ -2288,7 +2300,7 @@ int ATACheckDevice(cfgfile *cfg){
// sure) check whether a self test should be done now.
// This check is done before powermode check to avoid missing self
// tests on idle or sleeping disks.
if (cfg->testdata) {
if (allow_selftests && cfg->testdata) {
// long test
if (!cfg->testdata->not_cap_long && DoTestNow(cfg, 'L', 0)>0)
testtype = 'L';
@ -2537,7 +2549,7 @@ int ATACheckDevice(cfgfile *cfg){
return 0;
}
int SCSICheckDevice(cfgfile *cfg)
int SCSICheckDevice(cfgfile *cfg, bool allow_selftests)
{
UINT8 asc, ascq;
UINT8 currenttemp;
@ -2607,7 +2619,7 @@ int SCSICheckDevice(cfgfile *cfg)
if (cfg->selftest)
CheckSelfTestLogs(cfg, scsiCountFailedSelfTests(fd, 0));
if (cfg->testdata) {
if (allow_selftests && cfg->testdata) {
// long (extended) background test
if (!cfg->testdata->not_cap_long && DoTestNow(cfg, 'L', 0)>0)
DoSCSISelfTest(fd, cfg, 'L');
@ -2620,14 +2632,14 @@ int SCSICheckDevice(cfgfile *cfg)
}
// Checks the SMART status of all ATA and SCSI devices
void CheckDevicesOnce(cfgfile **atadevices, cfgfile **scsidevices){
void CheckDevicesOnce(cfgfile **atadevices, cfgfile **scsidevices, bool allow_selftests){
int i;
for (i=0; i<numdevata; i++)
ATACheckDevice(atadevices[i]);
ATACheckDevice(atadevices[i], allow_selftests);
for (i=0; i<numdevscsi; i++)
SCSICheckDevice(scsidevices[i]);
SCSICheckDevice(scsidevices[i], allow_selftests);
return;
}
@ -2788,7 +2800,7 @@ void printoutvaliddirectiveargs(int priority, char d) {
PrintOut(priority, "use, ignore, show, showall");
break;
case 'F':
PrintOut(priority, "none, samsung, samsung2");
PrintOut(priority, "none, samsung, samsung2, samsung3");
break;
}
}
@ -3038,8 +3050,8 @@ int ParseToken(char *token,cfgfile *cfg){
PrintOut(LOG_CRIT, "File %s line %d (drive %s): Directive -d 3ware,N requires N integer\n",
configfile, lineno, name);
badarg=1;
} else if ( i<0 || i>15) {
PrintOut(LOG_CRIT, "File %s line %d (drive %s): Directive -d 3ware,N (N=%d) must have 0 <= N <= 15\n",
} else if ( i<0 || i>31) {
PrintOut(LOG_CRIT, "File %s line %d (drive %s): Directive -d 3ware,N (N=%d) must have 0 <= N <= 31\n",
configfile, lineno, name, i);
badarg=1;
} else {
@ -3056,8 +3068,8 @@ int ParseToken(char *token,cfgfile *cfg){
PrintOut(LOG_CRIT, "File %s line %d (drive %s): Directive -d cciss,N requires N integer\n",
configfile, lineno, name);
badarg=1;
} else if ( i<0 || i>15) {
PrintOut(LOG_CRIT, "File %s line %d (drive %s): Directive -d cciss,N (N=%d) must have 0 <= N <= 15\n",
} else if ( i<0 || i>127) {
PrintOut(LOG_CRIT, "File %s line %d (drive %s): Directive -d cciss,N (N=%d) must have 0 <= N <= 127\n",
configfile, lineno, name, i);
badarg=1;
} else {
@ -3081,6 +3093,8 @@ int ParseToken(char *token,cfgfile *cfg){
cfg->fixfirmwarebug = FIX_SAMSUNG;
} else if (!strcmp(arg, "samsung2")) {
cfg->fixfirmwarebug = FIX_SAMSUNG2;
} else if (!strcmp(arg, "samsung3")) {
cfg->fixfirmwarebug = FIX_SAMSUNG3;
} else {
badarg = 1;
}
@ -3198,7 +3212,7 @@ int ParseToken(char *token,cfgfile *cfg){
// Do a bit of sanity checking and warn user if we think that
// their regexp is "strange". User probably confused about shell
// glob(3) syntax versus regular expression syntax regexp(7).
if ((int)strlen(arg) != (val=strspn(arg,"0123456789/.-+*|()?^$[]SLCO")))
else if ((int)strlen(arg) != (val=strspn(arg,"0123456789/.-+*|()?^$[]SLCO")))
PrintOut(LOG_INFO, "File %s line %d (drive %s): warning, character %d (%c) looks odd in extended regular expression %s\n",
configfile, lineno, name, val+1, arg[val], arg);
break;
@ -3781,7 +3795,7 @@ void ParseOpts(int argc, char **argv){
char *tailptr;
long lchecktime;
// Please update GetValidArgList() if you edit shortopts
const char *shortopts = "c:l:q:dDi:p:r:Vh?";
const char *shortopts = "c:l:q:dDni:p:r:Vh?";
#ifdef HAVE_GETOPT_LONG
char *arg;
// Please update GetValidArgList() if you edit longopts
@ -3792,10 +3806,13 @@ void ParseOpts(int argc, char **argv){
{ "debug", no_argument, 0, 'd' },
{ "showdirectives", no_argument, 0, 'D' },
{ "interval", required_argument, 0, 'i' },
#ifndef _WIN32
{ "no-fork", no_argument, 0, 'n' },
#endif
{ "pidfile", required_argument, 0, 'p' },
{ "report", required_argument, 0, 'r' },
#if defined(_WIN32) || defined(__CYGWIN__)
{ "service", no_argument, 0, 'S' },
{ "service", no_argument, 0, 'n' },
#endif
{ "version", no_argument, 0, 'V' },
{ "license", no_argument, 0, 'V' },
@ -3867,6 +3884,12 @@ void ParseOpts(int argc, char **argv){
// enable debug mode
debugmode = TRUE;
break;
case 'n':
// don't fork()
#ifndef _WIN32 // On Windows, --service is already handled by daemon_main()
do_fork = false;
#endif
break;
case 'D':
// print summary of all valid directives
debugmode = TRUE;
@ -3931,14 +3954,6 @@ void ParseOpts(int argc, char **argv){
// output file with PID number
pid_file=CustomStrDup(optarg, 1, __LINE__,filenameandversion);
break;
#if defined(_WIN32) || defined(__CYGWIN__)
case 'S':
// running as service
#ifdef __CYGWIN__ // On Windows, option is already handled by daemon_main(), so ignore it
is_service = 1;
#endif
break;
#endif // _WIN32 || __CYGWIN__
case 'V':
// print version and CVS info
PrintCopyleft();
@ -4148,7 +4163,14 @@ int ReadOrMakeConfigEntries(int *scanning){
} else if (first->controller_type==CONTROLLER_SAT) {
doata = 0;
doscsi = 0;
}
} else
dosat = 0;
// The code in this block has been neutered by D. Gilbert
// on 20070226. smartd can't cope ATA disk behind a SAT
// transport seamlessly _without_ a bigger restructuring
// of smartd than this code tried. It made ATA disks
// behind a SAT interface automatically detected only by
// killing support for real SCSI disks. Sorry, no.
*scanning=1;
@ -4391,8 +4413,9 @@ static int smartd_main(int argc, char **argv)
caughtsigHUP=0;
}
// check all devices once
CheckDevicesOnce(atadevlist, scsidevlist);
// check all devices once,
// self tests are not started in first pass unless '-q onecheck' is specified
CheckDevicesOnce(atadevlist, scsidevlist, (!firstpass || quit==3));
// user has asked us to exit after first check
if (quit==3) {
@ -4403,9 +4426,6 @@ static int smartd_main(int argc, char **argv)
// fork into background if needed
if (firstpass && !debugmode) {
#ifdef __CYGWIN__
if (!is_service) // don't fork() if running as service via cygrunsrv
#endif
DaemonInit();
}

View File

@ -1,8 +1,8 @@
#! /bin/sh
# smartmontools init file for smartd
# Copyright (C) 2002-6 Bruce Allen <smartmontools-support@lists.sourceforge.net>
# $Id: smartd.initd.in,v 1.35 2006/10/24 13:29:24 sbrabec Exp $
# Copyright (C) 2002-7 Bruce Allen <smartmontools-support@lists.sourceforge.net>
# $Id: smartd.initd.in,v 1.36 2007/11/01 20:53:30 chrfranke Exp $
# For RedHat and cousins:
# chkconfig: 2345 40 40
@ -446,7 +446,7 @@ http://smartmontools.sourceforge.net/"
fi
echo "Installing service ${smartd_svcname}${smartd_opts+ with options '$smartd_opts'}:"
cygrunsrv -I "$smartd_svcname" -d "$smartd_svcdisp" -f "$smartd_svcdesc" $dep \
-e CYGWIN="$CYGWIN" -p $SMARTD_BIN -a "--service -p ${PID_FILE}${smartd_opts+ }$smartd_opts"
-e CYGWIN="$CYGWIN" -p $SMARTD_BIN -a "-n -p ${PID_FILE}${smartd_opts+ }$smartd_opts"
RETVAL=$?
;;
remove)

View File

@ -8,7 +8,7 @@ Summary(pt): smartmontools - para monitorar discos e dispositivos S.M.A.R.T.
Summary(it): smartmontools - per monitare dischi e dispositivi S.M.A.R.T.
Summary(pl): Monitorowanie i kontrola dysków u¿ywaj±æ S.M.A.R.T.
Name: smartmontools
Version: 5.37
Version: 5.38
License: GPL
Group: Applications/System
Group(de): Applikationen/System
@ -38,7 +38,7 @@ Packager: Bruce Allen <smartmontools-support@lists.sourceforge.net>
# http://ftp1.sourceforge.net/smartmontools/smartmontools-%{version}-%{release}.tar.gz
# CVS ID of this file is:
# $Id: smartmontools.spec,v 1.170 2006/12/20 20:39:25 chrfranke Exp $
# $Id: smartmontools.spec,v 1.171 2006/12/20 21:59:04 chrfranke Exp $
# Copyright (C) 2002-6 Bruce Allen <smartmontools-support@lists.sourceforge.net>
# Home page: http://smartmontools.sourceforge.net/

View File

@ -3,7 +3,7 @@
*
* Home page of code is: http://smartmontools.sourceforge.net
*
* Copyright (C) 2002-6 Bruce Allen <smartmontools-support@lists.sourceforge.net>
* Copyright (C) 2002-7 Bruce Allen <smartmontools-support@lists.sourceforge.net>
* Copyright (C) 2000 Michael Cornwell <cornwell@acm.org>
*
* This program is free software; you can redistribute it and/or modify
@ -44,7 +44,7 @@
#include "utility.h"
// Any local header files should be represented by a CVSIDX just below.
const char* utility_c_cvsid="$Id: utility.cpp,v 1.62 2006/08/09 20:40:20 chrfranke Exp $"
const char* utility_c_cvsid="$Id: utility.cpp,v 1.64 2007/02/03 15:14:14 chrfranke Exp $"
CONFIG_H_CVSID INT64_H_CVSID UTILITY_H_CVSID;
const char * packet_types[] = {
@ -517,25 +517,51 @@ static uint64_t strtoull(const char * p, char * * endp, int base)
// are allowed). The first long long int is assigned to *start and the second
// to *stop. Returns zero if successful and non-zero otherwise.
int split_selective_arg(char *s, uint64_t *start,
uint64_t *stop)
uint64_t *stop, int *mode)
{
char *tailptr;
if (!(s = strchr(s, ',')))
return 1;
if (!isdigit((int)(*++s)))
return 1;
errno = 0;
// Last argument to strtoull (the base) is 0 meaning that decimal is assumed
// unless prefixes of "0" (for octal) or "0x"/"0X" (for hex) are used.
*start = strtoull(s, &tailptr, 0);
s = tailptr;
if (errno || *s++ != '-')
return 1;
*stop = strtoull(s, &tailptr, 0);
bool add = false;
if (!isdigit((int)(*++s))) {
*start = *stop = 0;
if (!strncmp(s, "redo", 4))
*mode = SEL_REDO;
else if (!strncmp(s, "next", 4))
*mode = SEL_NEXT;
else if (!strncmp(s, "cont", 4))
*mode = SEL_CONT;
else
return 1;
s += 4;
if (!*s)
return 0;
if (*s != '+')
return 1;
}
else {
*mode = SEL_RANGE;
errno = 0;
// Last argument to strtoull (the base) is 0 meaning that decimal is assumed
// unless prefixes of "0" (for octal) or "0x"/"0X" (for hex) are used.
*start = strtoull(s, &tailptr, 0);
s = tailptr;
add = (*s == '+');
if (!(!errno && (add || *s == '-')))
return 1;
if (!strcmp(s, "-max")) {
*stop = ~(uint64_t)0; // replaced by max LBA later
return 0;
}
}
*stop = strtoull(s+1, &tailptr, 0);
if (errno || *tailptr != '\0')
return 1;
if (add) {
if (*stop > 0)
(*stop)--;
*stop += *start; // -t select,N+M => -t select,N,(N+M-1)
}
return 0;
}
@ -580,7 +606,7 @@ void *Calloc(size_t nmemb, size_t size) {
// A custom version of strdup() that keeps track of how much memory is
// being allocated. If mustexist is set, it also throws an error if we
// try to duplicate a NULL string.
char *CustomStrDup(char *ptr, int mustexist, int whatline, const char* file){
char *CustomStrDup(const char *ptr, int mustexist, int whatline, const char* file){
char *tmp;
// report error if ptr is NULL and mustexist is set

View File

@ -3,7 +3,7 @@
*
* Home page of code is: http://smartmontools.sourceforge.net
*
* Copyright (C) 2002-6 Bruce Allen <smartmontools-support@lists.sourceforge.net>
* Copyright (C) 2002-7 Bruce Allen <smartmontools-support@lists.sourceforge.net>
* Copyright (C) 2000 Michael Cornwell <cornwell@acm.org>
*
* This program is free software; you can redistribute it and/or modify
@ -25,7 +25,7 @@
#ifndef UTILITY_H_
#define UTILITY_H_
#define UTILITY_H_CVSID "$Id: utility.h,v 1.47 2006/10/09 11:45:12 guidog Exp $\n"
#define UTILITY_H_CVSID "$Id: utility.h,v 1.50 2007/07/26 20:58:50 chrfranke Exp $\n"
#include <time.h>
#include <sys/types.h> // for regex.h (according to POSIX)
@ -76,8 +76,14 @@ int compileregex(regex_t *compiled, const char *pattern, int cflags);
int split_report_arg(char *s, int *i);
// Function for processing -c option in smartctl and smartd
int split_report_arg2(char *s, int *i);
// Possible values for smartselectivemode
#define SEL_RANGE 0 // MIN-MAX
#define SEL_REDO 1 // redo this
#define SEL_NEXT 2 // do next range
#define SEL_CONT 3 // redo or next depending of last test status
// Function for processing -t selective... option in smartctl
int split_selective_arg(char *s, uint64_t *start, uint64_t *stop);
int split_selective_arg(char *s, uint64_t *start, uint64_t *stop, int *mode);
// Guess device type (ata or scsi) based on device name
@ -106,7 +112,7 @@ inline T * FreeNonZero(T * address, int size, int whatline, const char* file)
// A custom version of strdup() that keeps track of how much memory is
// being allocated. If mustexist is set, it also throws an error if we
// try to duplicate a NULL string.
char *CustomStrDup(char *ptr, int mustexist, int whatline, const char* file);
char *CustomStrDup(const char *ptr, int mustexist, int whatline, const char* file);
// To help with memory checking. Use when it is known that address is
// NOT null.
@ -187,5 +193,6 @@ void MsecToText(unsigned int msec, char *txt);
#define CONTROLLER_SAT 0x08 // SATA device behind a SCSI ATA Translation (SAT) layer
#define CONTROLLER_HPT 0x09 // SATA drives behind HighPoint Raid controllers
#define CONTROLLER_CCISS 0x10 // CCISS controller
#define CONTROLLER_PARSEDEV 0x11 // "smartctl -r ataioctl,2 ..." output parser pseudo-device
#endif