Imported smartmontools-5.27.cvs20061002

into Git repository
This commit is contained in:
Guido Guenther 2006-10-02 16:38:42 +02:00 committed by Guido Guenther
parent 832b75ede0
commit 4d59bff95e
75 changed files with 8910 additions and 16329 deletions

103
CHANGELOG
View File

@ -1,9 +1,9 @@
CHANGELOG for smartmontools
$Id: CHANGELOG,v 1.537 2006/04/12 16:11:44 ballen4705 Exp $
$Id: CHANGELOG,v 1.566 2006/09/27 21:42:03 chrfranke Exp $
The most recent version of this file is:
http://cvs.sourceforge.net/viewcvs.py/smartmontools/sm5/CHANGELOG?sortby=date&view=markup
http://smartmontools.cvs.sourceforge.net/smartmontools/sm5/CHANGELOG?view=markup
Maintainers / Developers Key:
[BA] Bruce Allen
@ -27,11 +27,110 @@ Maintainers / Developers Key:
[PW] Phil Williams
[LW] Leon Woestenberg
[RZ] Richard Zybert
[SZ] Sf Zhou
NOTES FOR FUTURE RELEASES: see TODO file.
<DEVELOPERS: ADDITIONS TO THE CHANGE LOG GO JUST BELOW HERE, PLEASE>
[CF] Windows: Added support for 3ware 9000 controllers using extended
SMART functionality in new 3ware driver. This includes DEVICESCAN
support for at most 2 controllers. Thanks to Greg de Valois from
AMCC/3ware for new driver features, development support and
hardware for testing.
[SZ] smartd: Support HighPoint RocketRAID controller under GNU/linux
[DG] [SCSI] First cut for '-l background' to show background scan
results log
[SZ] smartctl: Support HighPoint RocketRAID controller under GNU/linux
[KS] C++ compile fixes for Solaris with a few cleanups.
[BA] C++ compile fixes for Darwin (thanks to CF)
[CF] Removed old *.c files (now in CVS Attic).
[CF] Added changes for C++ to platform independent and Windows
related files.
[BA] Tagged last .c Version with PRE_MOVE_TO_CPP. Copied *.c,v
to *.cpp,v in CVS repository to preserve history of source
files. Removed sm5_Darwin repository.
[CF] smartctl: Added -n option to skip checks when disk is in
low-power mode.
[CF] Windows: Added alternate system call for power state check
because the PASS THROUGH calls may spin up the disk.
[CF] smartd: Modified power state logging to report state changes
instead of standby condition.
[CF] smartd: Ignore -n directive on scheduled self tests.
[DG] [SCSI] Make start stop cycle counter log page decoding
more robust
[DG] Modify smartctl (but not smartd) to detect probable ATA
devices behind a SAT layer. In the absence of an explicit
device type, change to device type 'sat'.
[DG] Add indication that controller (device) type has been
explicitly set. Preparation for automatic detection of
'sat' device type unless user specifies a device type.
[SS] NetBSD: Deliver strings from ata_identify_device properly
on little- and big-endian platforms.
[BA] Added published ANSI ATA-7 spec to list of recognized ATA
versions.
[BA] Code janitor: added missing header strings for '-V' option.
[DG] [SATA] Extend 'sat' device type to allow either 12 or 16 byte
variant of the SAT ATA PASS THROUGH SCSI command. Syntax is
'-d sat,<n>' where <n> can be 0, 12 or 16 . The ',<n>' part
is optional. Currently defaults to 16 byte variant but that
could be made platform or even device dependent.
[DG] [SATA] Add new 'sat' device type for SATA disks behind a
SCSI to ATA Translation (SAT) Layer (SATL). Uses the ATA
PASS THROUGH (16) SCSI command thence the generic SCSI
passthrough for each platform.
[CF] Windows: Added script and make targets to create installer
with NSIS (http://nsis.sourceforge.net/)
[CF] Updated hostname and links for new SourceForge CVS service.
[CF] smartd: Added '-W' directive to track temperature changes
and warn if temperature limits are reached.
[CF] Windows: Added IOCTL_ATA_PASS_THROUGH (Win2003, XP SP2)
for commands unsupported by SMART_IOCTL. Added device
specific options to select subset and ordering of the ATA
IOCTLs actually used. These options are specified as
modifiers of the device name (/dev/hd[a-j]:[saic]+)
[CF] Windows: Added support for drives 4-7 (/dev/hd[e-h]) via
SMARTVSE.VXD on Win9x/ME. Thanks to Dariusz Rzonca for
patch and testing.
[DG] [SCSI/SATA linux] from lk 2.6.17 SATA disk identification in
libata will change. Expand LibAta detection to see old
identifier and new variant (VPD page 0x83).
[BA] Identified Attribute 190 for Western Digital disks. This
stores temperature in Celsius, just like Attribute 194.
But it has a failure threshold set to correspond to the
maximum design operating temperature of the disk, which
is 55 Celsius on the WD800JD drives that I studied.
So if this Attribute has 'failed
in the past' this means that the maximum disk operating
temperature has been exceeded.
smartmontools 5.36 Stable Release
[BA] Linux: smartd/smartctl issue syntax hints to user if 3ware

77
INSTALL
View File

@ -1,7 +1,7 @@
Smartmontools installation instructions
=======================================
$Id: INSTALL,v 1.62 2005/10/22 17:11:39 chrfranke Exp $
$Id: INSTALL,v 1.68 2006/09/27 21:42:03 chrfranke Exp $
Please also see the smartmontools home page:
http://smartmontools.sourceforge.net/
@ -123,15 +123,24 @@ Table of contents:
to get loaded at Windows startup. The default location in a new
installation of some versions of Windows is the WINDOWS\SYSTEM folder.
In this case, move SMARTVSD.VXD to WINDOWS\SYSTEM\IOSUBSYS and reboot
(http://support.microsoft.com/default.aspx?scid=kb;en-us;265854).
(http://support.microsoft.com/kb/265854/en-us).
SMARTVSD.VXD may also be missing in a new installation
(http://support.microsoft.com/kb/199886/en-us).
SMARTVSD.VXD relies on the standard IDE port driver ESDI_506.PDR.
If the system uses a vendor specific driver, access of SMART data
is not possible on 9x/ME. This is the case if e.g. the optional
"IDE miniport driver" is installed on a system with VIA chipset.
On NT4/2000/XP, also other ATA or SATA devices are supported if
the device driver implements the SMART IOCTL.
Some ATA controllers (e.g. Promise) provided a custom SMARTVSD.VXD
for their Win9x/ME driver. To access SMART data from both the legacy
(/dev/h[a-d]) and this additional (/dev/hd[e-h]) controller, rename
this file to SMARTVSE.VXD. Open the file with a hex editor and replace
all occurrences of the string "SMARTVSD" with "SMARTVSE". Then reinstall
the original Windows SMARTVSD.VXD.
On NT4/2000/XP/2003, ATA or SATA devices are supported if the device
driver implements the SMART IOCTL.
The IDE/ATA read log command (smartctl -l, --log, -a, --all) is
not supported by the SMART IOCTL of NT4/2000/XP. Undocumented
@ -141,18 +150,28 @@ Table of contents:
SCSI devices are supported on all versions of Windows. An installed
ASPI interface (WNASPI32.DLL) is required to access SCSI devices.
The code was tested with Adaptec Windows ASPI drivers 4.71.2.
(http://www.adaptec.com/worldwide/support/drivers_by_product.jsp?cat=/Product/ASPI-4.70)
(http://www.adaptec.com/en-US/support/scsi_soft/ASPI/ASPI-4.70/)
Links to other ASPI drivers can be found at http://www.nu2.nu/aspi/.
3ware 9000 RAID controllers are supported using new features added
to the 3ware 9000 Windows driver. These features are not implemented
in the latest 'Released' driver (9.3.0.6) available at the time of
this writing. But an 'in Engineering Phase' driver v3.00.02.061 or
later can be used to access SMART functionality of each individual
drive. Older drivers provide SMART access only to the first drive
(port) of each unit. The commands READ LOG and ABORT SELFTEST are
still unsupported due to the limitations of SMART IOCTL (see above).
G) MacOS/Darwin
The code was tested on MacOS 10.3.4. It should work from 10.3
forwards. It doesn't support 10.2.
There's an important limitation (see WARNINGS); due to bugs in
the libraries used, you cannot run a short test or switch SMART
support off on a drive; if you try, you will just run an extended
test or switch SMART support on. So don't panic when your "short"
test seems to be taking hours.
It's important to know that on 10.3.x, some things don't work
(see WARNINGS): due to bugs in the libraries used, you cannot run
a short test or switch SMART support off on a drive; if you try,
you will just run an extended test or switch SMART support on. So
don't panic when your "short" test seems to be taking hours.
It's also not possible at present to control when the offline
routine runs. If your drive doesn't have it running automatically by
@ -174,17 +193,16 @@ Table of contents:
- checking the power mode [-n Directive of smartd] (this is not
completely impossible, but not by using a documented API)
* Are implemented, but don't work due to OS bugs:
* Work on 10.4 and later, but not on 10.3:
- switching off SMART (switching *on* works fine)
- switching off auto-save (but why would you want to?)
- running the short test (that leaves you with only the extended test)
The last set have been filed in Apple's bug tracking system and
hopefully will be fixed in the next major version of Mac OS.
However, some things do work well. For ATA devices, all the
informational output is available, unless you want something that only
an offline test updates.
an offline test updates. On many newer Mac OS systems, the
hard drive comes with the offline test switched on by default, so
even that works.
H) OS/2, eComStation
@ -197,8 +215,8 @@ Table of contents:
[2] Installing from CVS
=======================
Get the sources from the CVS repository:
cvs -d :pserver:anonymous@cvs.sourceforge.net:/cvsroot/smartmontools login
cvs -d :pserver:anonymous@cvs.sourceforge.net:/cvsroot/smartmontools co sm5
cvs -d :pserver:anonymous@smartmontools.cvs.sourceforge.net:/cvsroot/smartmontools login
cvs -d :pserver:anonymous@smartmontools.cvs.sourceforge.net:/cvsroot/smartmontools co sm5
(when prompted for a password, just press Enter)
Then type:
@ -331,6 +349,12 @@ SuSE:
=========================
./configure --with-initscriptdir=/Library/StartupItems
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' \
./configure --host=i386-apple-darwin \
--with-initscriptdir=/Library/StartupItems
[7] Guidelines for NetBSD/OpenBSD
=================================
@ -418,7 +442,7 @@ To compile the Windows release with MinGW, use the following on Cygwin:
To build the Windows binary distribution, use:
make dist-win32
This builds the distribution in directory
./smartmontools-VERSION.win32/
@ -427,6 +451,23 @@ To build the Windows binary distribution, use:
./smartmontools-VERSION.win32.zip
To create a Windows installer, use:
make installer-win32
This builds the distribution directory and packs it into the
self-extracting install program
./smartmontools-VERSION.win32-setup.exe
The installer is build using the command "makensis" from the NSIS
package. See http://nsis.sourceforge.net/ for documentation and
download location. The install script was tested with NSIS 2.17.
To both create and run the (interactive) installer, use:
make install-win32
Additional make targets are distdir-win32 to build the directory
only and cleandist-win32 for cleanup.

View File

@ -1,65 +1,72 @@
## Process this file with automake to produce Makefile.in
#
# $Id: Makefile.am,v 1.74 2005/11/29 18:22:51 chrfranke Exp $
# $Id: Makefile.am,v 1.79 2006/08/09 20:40:19 chrfranke Exp $
#
@SET_MAKE@
# Make sure .cpp takes precedence to avoid compiling old .c file
SUFFIXES = .cpp .c .s .o
AM_CPPFLAGS = -DSMARTMONTOOLS_SYSCONFDIR=\"$(sysconfdir)\"
sbin_PROGRAMS = smartd \
smartctl
smartd_SOURCES = smartd.c \
smartd.h \
atacmdnames.c \
atacmdnames.h \
atacmds.c \
atacmds.h \
ataprint.c \
ataprint.h \
extern.h \
int64.h \
knowndrives.c \
knowndrives.h \
scsicmds.c \
scsicmds.h \
scsiprint.c \
scsiprint.h \
utility.c \
smartd_SOURCES = smartd.cpp \
smartd.h \
atacmdnames.cpp \
atacmdnames.h \
atacmds.cpp \
atacmds.h \
ataprint.cpp \
ataprint.h \
extern.h \
int64.h \
knowndrives.cpp \
knowndrives.h \
scsicmds.cpp \
scsicmds.h \
scsiata.cpp \
scsiata.h \
scsiprint.cpp \
scsiprint.h \
utility.cpp \
utility.h
smartd_LDADD = @os_deps@ @os_libs@
smartd_DEPENDENCIES = @os_deps@
EXTRA_smartd_SOURCES = os_darwin.c \
os_darwin.h \
os_linux.c \
EXTRA_smartd_SOURCES = os_darwin.cpp \
os_darwin.h \
os_linux.cpp \
os_linux.h \
os_freebsd.c \
os_freebsd.h \
os_netbsd.c \
os_netbsd.h \
os_openbsd.c \
os_openbsd.h \
os_solaris.c \
os_solaris.h \
os_solaris_ata.s \
os_win32.c \
os_generic.c \
os_generic.h
os_freebsd.cpp \
os_freebsd.h \
os_netbsd.cpp \
os_netbsd.h \
os_openbsd.cpp \
os_openbsd.h \
os_solaris.cpp \
os_solaris.h \
os_solaris_ata.s \
os_win32.cpp \
os_generic.cpp \
os_generic.h
if OS_WIN32_MINGW
smartd_SOURCES += \
posix/regex.h \
posix/regex.c \
os_win32/daemon_win32.h \
os_win32/daemon_win32.c \
os_win32/hostname_win32.h \
os_win32/hostname_win32.c \
os_win32/syslog.h \
os_win32/syslog_win32.c
smartd_SOURCES += \
posix/regex.h \
posix/regex.c \
os_win32/daemon_win32.h \
os_win32/daemon_win32.cpp \
os_win32/hostname_win32.h \
os_win32/hostname_win32.cpp \
os_win32/syslog.h \
os_win32/syslog_win32.cpp
# Included by regex.c:
EXTRA_smartd_SOURCES += \
@ -70,40 +77,43 @@ EXTRA_smartd_SOURCES += \
endif
smartctl_SOURCES= smartctl.c \
smartctl.h \
atacmdnames.c \
atacmdnames.h \
atacmds.c \
atacmds.h \
ataprint.c \
ataprint.h \
extern.h \
int64.h \
knowndrives.c \
knowndrives.h \
scsicmds.c \
scsicmds.h \
scsiprint.c \
scsiprint.h \
utility.c \
smartctl_SOURCES= smartctl.cpp \
smartctl.h \
atacmdnames.cpp \
atacmdnames.h \
atacmds.cpp \
atacmds.h \
ataprint.cpp \
ataprint.h \
extern.h \
int64.h \
knowndrives.cpp \
knowndrives.h \
scsicmds.cpp \
scsicmds.h \
scsiata.cpp \
scsiata.h \
scsiprint.cpp \
scsiprint.h \
utility.cpp \
utility.h
smartctl_LDADD = @os_deps@ @os_libs@
smartctl_DEPENDENCIES = @os_deps@
EXTRA_smartctl_SOURCES = os_linux.c \
os_linux.h \
os_freebsd.c \
os_freebsd.h \
os_netbsd.c \
os_netbsd.h \
os_openbsd.c \
os_openbsd.h \
os_solaris.c \
os_solaris.h \
os_win32.c \
os_generic.c \
os_generic.h
EXTRA_smartctl_SOURCES = os_linux.cpp \
os_linux.h \
os_freebsd.cpp \
os_freebsd.h \
os_netbsd.cpp \
os_netbsd.h \
os_openbsd.cpp \
os_openbsd.h \
os_solaris.cpp \
os_solaris.h \
os_win32.cpp \
os_generic.cpp \
os_generic.h
if OS_WIN32_MINGW
@ -207,6 +217,7 @@ EXTRA_DIST = smartmontools.spec \
os_darwin/SMART.in \
os_darwin/StartupParameters.plist \
os_darwin/English_Localizable.strings \
os_win32/installer.nsi \
$(docs_DATA)
CLEANFILES = smartd.conf.5 \
@ -322,8 +333,9 @@ MAN2HTML = man2html
#MAN2HTML = groff -man -Thtml
MAN2TXT = groff -man -Tascii -P'-bcou'
# Fix links in man2html output
FIXHTML = sed 's,<A HREF="http://[-a-z/]*/man2html?\([1-8]\)+\(smart[cd][.a-z]*\)">,<A HREF="\2.\1.html">,g' \
# Remove HTTP header and fix links in man2html output
FIXHTML = sed '1s,^Content-type.*,,' \
| sed 's,<A HREF="http://[-a-z/]*/man2html?\([1-8]\)+\(smart[cd][.a-z]*\)">,<A HREF="\2.\1.html">,g' \
| sed 's,<A HREF="http://[-a-z/]*/man2html">,<A HREF=".">,g' \
| sed 's,<A HREF="http://[-a-z/]*/man2html?[^"]*">\([^<]*\)</A>,\1,g' \
| sed 's,<A HREF="mailto:[^s][^m][^a][^"]*">\([^<]*\)</A>,\1,g'
@ -334,11 +346,21 @@ htmlman: smartctl.8.html smartd.8.html smartd.conf.5.html
txtman: smartctl.8.txt smartd.8.txt smartd.conf.5.txt
if OS_WIN32_MINGW
%.5.html: %.5
$(DOS2UNIX) < $< | $(MAN2HTML) | $(FIXHTML) > $@
%.8.html: %.8
$(DOS2UNIX) < $< | $(MAN2HTML) | $(FIXHTML) > $@
else
%.5.html: %.5
$(MAN2HTML) $< | $(FIXHTML) > $@
%.8.html: %.8
$(MAN2HTML) $< | $(FIXHTML) > $@
endif
%.5.txt: %.5
$(MAN2TXT) $< > $@
@ -353,6 +375,7 @@ if OS_WIN32_MINGW
distdir_win32 = $(PACKAGE)-$(VERSION).win32
distzip_win32 = $(PACKAGE)-$(VERSION).win32.zip
distinst_win32= $(PACKAGE)-$(VERSION).win32-setup.exe
exedir_win32 = $(distdir_win32)/bin
docdir_win32 = $(distdir_win32)/doc
@ -379,17 +402,38 @@ CLEANFILES += $(FILES_WIN32) $(exedir_win32)/syslogevt.exe distdir.mkdir sysloge
# Textfile converter from cygutils
UNIX2DOS = unix2dos -D
DOS2UNIX = dos2unix -U
# Build Windows distribution
dist-win32: $(distzip_win32)
install-win32: $(distinst_win32)
./$(distinst_win32)
installer-win32: $(distinst_win32)
distdir-win32: distdir.mkdir $(FILES_WIN32) syslogevt.check
$(distzip_win32): distdir.mkdir $(FILES_WIN32) syslogevt.check
@rm -fv $(distzip_win32)
cd $(distdir_win32) && zip -9Dr ../$(distzip_win32) .
# Build NSIS installer, try to locate makensis in default location first
$(distinst_win32): $(srcdir)/os_win32/installer.nsi distdir.mkdir $(FILES_WIN32) syslogevt.check
@makensis="$(MAKENSIS)"; if [ -z "$$makensis" ]; then \
if [ ! -z "$$PROGRAMFILES" ] && "$$PROGRAMFILES/NSIS/makensis" /VERSION >/dev/null 2>&1; then \
makensis="$$PROGRAMFILES/NSIS/makensis"; \
elif makensis /VERSION >/dev/null 2>&1; then \
makensis=makensis; \
else \
echo 'makensis: command not found. Please download and install NSIS' 1>&2; \
echo 'from http://nsis.sourceforge.net/Download' 1>&2; exit 1; \
fi; \
fi; \
echo "$$makensis /V2 /NOCD /DINPDIR=$(distdir_win32) /DOUTFILE=$(distinst_win32) $(srcdir)/os_win32/installer.nsi"; \
"$$makensis" /V2 /NOCD /DINPDIR="$(distdir_win32)" /DOUTFILE="$(distinst_win32)" "$(srcdir)/os_win32/installer.nsi"
cleandist-win32:
rm -rf $(distdir_win32) distdir.mkdir syslogevt.check
@ -428,7 +472,7 @@ config-vc6: $(srcdir)/os_win32/config_vc6.h
$(srcdir)/os_win32/config_vc6.h: config.h
sed '1i/* config_vc6.h. Generated by Makefile. */' $< | \
sed 's,^#define HAVE_\(ATTR_PACKED\|INTTYPES_H\|STDINT_H\|STRTOULL\|U*INT64_T\|UNISTD_H\) 1$$,/* #undef HAVE_\1 */,' | \
sed 's,^#define HAVE_\(ATTR_PACKED\|INTTYPES_H\|STDINT_H\|STRINGS_H\|STRTOULL\|U*INT64_T\|UNISTD_H\) 1$$,/* #undef HAVE_\1 */,' | \
sed 's,i.86-pc-mingw32,i686-pc-win32vc6,' > $@
endif

File diff suppressed because it is too large Load Diff

6
NEWS
View File

@ -1,9 +1,9 @@
smartmontools NEWS
------------------
CVS ID: $Id: NEWS,v 1.29 2006/04/12 15:46:30 ballen4705 Exp $
CVS ID: $Id: NEWS,v 1.30 2006/05/19 16:33:33 chrfranke Exp $
The most up-to-date version of this file is:
http://cvs.sourceforge.net/viewcvs.py/smartmontools/sm5/NEWS?sortby=date&view=markup
http://smartmontools.cvs.sourceforge.net/smartmontools/sm5/NEWS?view=markup
Date 2006-04-12
Summary: smartmontools release 5.36 (STABLE)
@ -72,7 +72,7 @@ This is an stable release of smartmontools.
Note added 2004/7/7: users building a Solaris/Intel version of the code should
modify the 'configure' file, changing "pc-*-solaris*" on line 106
to read "*-pc-solaris*". Reference:
http://cvs.sourceforge.net/viewcvs.py/smartmontools/sm5/configure.in?r1=1.83&r2=1.84
http://smartmontools.cvs.sourceforge.net/smartmontools/sm5/configure.in?r1=1.83&r2=1.84
Date: 2004-5-4

10
README
View File

@ -3,7 +3,7 @@ smartmontools - S.M.A.R.T. utility toolset for Darwin/Mac
OSX, FreeBSD, Linux, NetBSD, OpenBSD, Solaris, and Windows.
==========================================================
$Id: README,v 1.55 2006/04/12 14:54:28 ballen4705 Exp $
$Id: README,v 1.56 2006/05/19 16:33:33 chrfranke Exp $
== HOME ==
The home for smartmontools is located at:
@ -74,14 +74,14 @@ http://sourceforge.net/project/showfiles.php?group_id=64297
CVS
---
cvs -d:pserver:anonymous@cvs.sourceforge.net:/cvsroot/smartmontools login (when prompted for a password, just press Enter)
cvs -d:pserver:anonymous@cvs.sourceforge.net:/cvsroot/smartmontools co sm5
cvs -d:pserver:anonymous@smartmontools.cvs.sourceforge.net:/cvsroot/smartmontools login (when prompted for a password, just press Enter)
cvs -d:pserver:anonymous@smartmontools.cvs.sourceforge.net:/cvsroot/smartmontools co sm5
This will create a subdirectory called sm5/ containing the code.
To instead get the 5.1-16 release:
cvs -d:pserver:anonymous@cvs.sourceforge.net:/cvsroot/smartmontools co -r RELEASE_5_1_16 sm5
cvs -d:pserver:anonymous@smartmontools.cvs.sourceforge.net:/cvsroot/smartmontools co -r RELEASE_5_1_16 sm5
To update your sources to the 5.1-18 release:
@ -94,7 +94,7 @@ cd sm5
cvs up -A
You can see what the different tags are by looking at
http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/smartmontools/sm5/ .
http://smartmontools.cvs.sourceforge.net/smartmontools/sm5/ .
You'll see the tag names in the little scroll window where it says "Show
only files with tag".

6
TODO
View File

@ -1,6 +1,6 @@
TODO list for smartmontools:
$Id: TODO,v 1.59 2005/12/11 18:40:35 ballen4705 Exp $
$Id: TODO,v 1.60 2006/06/05 17:36:03 chrfranke Exp $
SATA devices under Linux
------------------------
@ -131,10 +131,6 @@ Add IDE/ATA selective self test.
Access SCSI devices via IOCTL_SCSI_PASS_THROUGH on 2000/XP
to support systems with missing ASPI driver.
Windows
-------
Provide some installer.
Packaging
---------
Under freebsd and solaris, the following are wrong:

View File

@ -1,7 +1,7 @@
$Id: WARNINGS,v 1.32 2005/04/20 19:17:33 geoffk1 Exp $
$Id: WARNINGS,v 1.33 2006/05/19 16:33:33 chrfranke Exp $
The most recent version of this file can be found here:
http://cvs.sourceforge.net/viewcvs.py/smartmontools/sm5/WARNINGS?view=markup
http://smartmontools.cvs.sourceforge.net/smartmontools/sm5/WARNINGS?view=markup
The following are reports of serious problems (eg system lockup) which
were due to smartmontools. There are DARWIN, LINUX, FREEBSD, SOLARIS
@ -107,7 +107,7 @@ NOTE: The IOCTL call SMART_RCV_DRIVE_DATA does not support
ATA_SMART_READ_LOG_SECTOR on NT4/2000/XP. The Win32
implementation of smartctl/smartd uses undocumented
and possibly buggy system calls for this purpose:
NT4: IOCTL_SCSI_PASS_THROUGH.with undocumented pseudo SCSI
NT4: IOCTL_SCSI_PASS_THROUGH with undocumented pseudo SCSI
command SCSIOP_ATA_PASSTHROUGH (0xCC).
2000/XP: Undocumented IOCTL_IDE_PASS_THROUGH.

1116
aclocal.m4 vendored

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,5 @@
/*
* atacmdnames.c
* atacmdnames.cpp
*
* This module is based on the T13/1532D Volume 1 Revision 3 (ATA/ATAPI-7)
* specification, which is available from http://www.t13.org/#FTP_site
@ -26,7 +26,7 @@
#define COMMAND_TABLE_SIZE 256
const char *atacmdnames_c_cvsid="$Id: atacmdnames.c,v 1.13 2006/04/12 14:54:28 ballen4705 Exp $" ATACMDNAMES_H_CVSID;
const char *atacmdnames_c_cvsid="$Id: atacmdnames.cpp,v 1.14 2006/08/09 20:40:19 chrfranke Exp $" ATACMDNAMES_H_CVSID;
const char cmd_reserved[] = "[RESERVED]";
const char cmd_vendor_specific[] = "[VENDOR SPECIFIC]";

View File

@ -1,5 +1,5 @@
/*
* atacmds.c
* atacmds.cpp
*
* Home page of code is: http://smartmontools.sourceforge.net
*
@ -32,11 +32,12 @@
#include "config.h"
#include "int64.h"
#include "atacmds.h"
#include "scsiata.h"
#include "extern.h"
#include "utility.h"
const char *atacmds_c_cvsid="$Id: atacmds.c,v 1.168 2006/04/12 17:01:46 ballen4705 Exp $"
ATACMDS_H_CVSID CONFIG_H_CVSID EXTERN_H_CVSID INT64_H_CVSID UTILITY_H_CVSID;
const char *atacmds_c_cvsid="$Id: atacmds.cpp,v 1.176 2006/08/25 06:06:24 sxzzsf 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
extern int exitstatus;
@ -84,7 +85,7 @@ const char *minor_str[] = { /* word 81 value: */
"ATA/ATAPI-7 T13 1532D revision 1", /* 0x001a */
"ATA/ATAPI-6 T13 1410D revision 2", /* 0x001b */
"ATA/ATAPI-6 T13 1410D revision 1", /* 0x001c */
"reserved", /* 0x001d */
"ATA/ATAPI-7 published, ANSI INCITS 397-2005",/* 0x001d */
"ATA/ATAPI-7 T13 1532D revision 0", /* 0x001e */
"reserved", /* 0x001f */
"reserved", /* 0x0020 */
@ -129,7 +130,7 @@ const int actual_ver[] = {
7, /* 0x001a WARNING: */
6, /* 0x001b WARNING: */
6, /* 0x001c WARNING: */
0, /* 0x001d WARNING: */
7, /* 0x001d WARNING: */
7, /* 0x001e WARNING: */
0, /* 0x001f WARNING: */
0, /* 0x0020 WARNING: */
@ -555,7 +556,7 @@ int smartcommandhandler(int device, smart_command_set command, int select, char
command==READ_LOG ||
command==READ_THRESHOLDS ||
command==READ_VALUES ||
command==CHECK_POWER_MODE);
command==CHECK_POWER_MODE);
int sendsdata=(command==WRITE_LOG);
@ -614,6 +615,12 @@ int smartcommandhandler(int device, smart_command_set command, int select, char
case CONTROLLER_MARVELL_SATA:
retval=marvell_command_interface(device, command, select, data);
break;
case CONTROLLER_SAT:
retval=sat_command_interface(device, command, select, data);
break;
case CONTROLLER_HPT:
retval=highpoint_command_interface(device, command, select, data);
break;
default:
retval=ata_command_interface(device, command, select, data);
}
@ -1678,6 +1685,16 @@ void ataPrintSmartAttribName(char *out, unsigned char id, unsigned char *definit
case 13:
name="Read_Soft_Error_Rate";
break;
case 190:
// Western Digital uses this for temperature.
// It's identical to Attribute 194 except that it
// has a failure threshold set to correspond to the
// max allowed operating temperature of the drive, which
// 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";
break;
case 191:
name="G-Sense_Error_Rate";
break;
@ -1860,8 +1877,8 @@ int64_t ATAReturnAttributeRawValue(unsigned char id, struct ata_smart_values *da
// loop over Attributes to see if there is one with the desired ID
for (i=0; i<NUMBER_ATA_SMART_ATTRIBUTES; i++) {
struct ata_smart_attribute *this = data->vendor_attributes + i;
if (this->id == id) {
struct ata_smart_attribute *ap = data->vendor_attributes + i;
if (ap->id == id) {
// we've found the desired Attribute. Return its value
int64_t rawvalue=0;
int j;
@ -1872,7 +1889,7 @@ int64_t ATAReturnAttributeRawValue(unsigned char id, struct ata_smart_values *da
// the normal rules this will be promoted to the native type.
// On a 32 bit machine this might then overflow.
int64_t temp;
temp = this->raw[j];
temp = ap->raw[j];
temp <<= 8*j;
rawvalue |= temp;
} // loop over j
@ -1884,4 +1901,29 @@ int64_t ATAReturnAttributeRawValue(unsigned char id, struct ata_smart_values *da
return -1;
}
// Return Temperature Attribute raw value selected according to possible
// non-default interpretations. If the Attribute does not exist, return 0
unsigned char ATAReturnTemperatureValue(/*const*/ struct ata_smart_values *data, const unsigned char *defs){
int i;
for (i = 0; i < 3; i++) {
static const unsigned char ids[3] = {194, 9, 220};
unsigned char id = ids[i];
unsigned char select = (defs ? defs[id] : 0);
int64_t raw; unsigned temp;
if (!( (id == 194 && select <= 1) // ! -v 194,unknown
|| (id == 9 && select == 2) // -v 9,temp
|| (id == 220 && select == 1))) // -v 220,temp
continue;
raw = ATAReturnAttributeRawValue(id, data);
if (raw < 0)
continue;
temp = (unsigned short)raw; // ignore possible min/max values in high words
if (id == 194 && select == 1) // -v 194,10xCelsius
temp = (temp+5) / 10;
if (!(0 < temp && temp <= 255))
continue;
return temp;
}
// No valid attribute found
return 0;
}

View File

@ -25,7 +25,7 @@
#ifndef ATACMDS_H_
#define ATACMDS_H_
#define ATACMDS_H_CVSID "$Id: atacmds.h,v 1.81 2006/04/12 14:54:28 ballen4705 Exp $\n"
#define ATACMDS_H_CVSID "$Id: atacmds.h,v 1.83 2006/08/25 06:06:24 sxzzsf Exp $\n"
// Macro to check expected size of struct at compile time using a
// dummy typedef. On size mismatch, compiler reports a negative array
@ -490,6 +490,10 @@ void checksumwarning(const char *string);
// return -1.
int64_t ATAReturnAttributeRawValue(unsigned char id, struct ata_smart_values *data);
// Return Temperature Attribute raw value selected according to possible
// non-default interpretations. If the Attribute does not exist, return 0
unsigned char ATAReturnTemperatureValue(/*const*/ struct ata_smart_values *data, const unsigned char *defs);
// This are the meanings of the Self-test failure checkpoint byte.
// This is in the self-test log at offset 4 bytes into the self-test
@ -521,6 +525,7 @@ char *create_vendor_attribute_arg_list(void);
int ata_command_interface(int device, smart_command_set command, int select, char *data);
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);
// Optional functions of os_*.c
#ifdef HAVE_ATA_IDENTIFY_IS_CACHED
// Return true if OS caches the ATA identify sector

View File

@ -1,5 +1,5 @@
/*
* ataprint.c
* ataprint.cpp
*
* Home page of code is: http://smartmontools.sourceforge.net
*
@ -25,6 +25,7 @@
#include "config.h"
#include <ctype.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
#ifdef HAVE_LOCALE_H
@ -40,7 +41,7 @@
#include "utility.h"
#include "knowndrives.h"
const char *ataprint_c_cvsid="$Id: ataprint.c,v 1.164 2006/04/12 14:54:28 ballen4705 Exp $"
const char *ataprint_c_cvsid="$Id: ataprint.cpp,v 1.168 2006/09/17 09:34:29 shattered 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
@ -98,7 +99,10 @@ void formatdriveidstring(char *out, const char *in, int n)
#ifndef __NetBSD__
swapbytes(tmp, in, n);
#else
strncpy(tmp, in, n); /* NetBSD delivers host byte order strings */
if (isbigendian())
strncpy(tmp, in, n);
else
swapbytes(tmp, in, n);
#endif
tmp[n] = '\0';
trim(out, tmp);
@ -498,7 +502,7 @@ uint64_t determine_capacity(struct ata_identify_device *drive, char *pstring){
return capacity_short;
}
void ataPrintDriveInfo (struct ata_identify_device *drive){
int ataPrintDriveInfo (struct ata_identify_device *drive){
int version, drivetype;
const char *description;
char unknown[64], timedatetz[DATEANDEPOCHLEN];
@ -563,11 +567,11 @@ void ataPrintDriveInfo (struct ata_identify_device *drive){
pout("\n==> WARNING: %s\n\n", knowndrives[drivetype].warningmsg);
if (version>=3)
return;
return drivetype;
pout("SMART is only available in ATA Version 3 Revision 3 or greater.\n");
pout("We will try to proceed in spite of this.\n");
return;
return drivetype;
}
@ -822,7 +826,7 @@ void PrintSmartAttribWithThres (struct ata_smart_values *data,
// consider only valid attributes (allowing some screw-ups in the
// thresholds page data to slip by)
if (disk->id){
char *type, *update;
const char *type, *update;
int failednow,failedever;
char attributename[64];
@ -1404,7 +1408,38 @@ struct ata_smart_selftestlog smartselftest;
int ataPrintMain (int fd){
int timewait,code;
int returnval=0, retid=0, supported=0, needupdate=0;
int returnval=0, retid=0, supported=0, needupdate=0, known=0;
const char * powername = 0; char powerchg = 0;
// If requested, check power mode first
if (con->powermode) {
unsigned char powerlimit = 0xff;
int powermode = ataCheckPowerMode(fd);
switch (powermode) {
case -1:
if (errno == ENOSYS) {
pout("CHECK POWER STATUS not implemented, ignoring -n Option\n"); break;
}
powername = "SLEEP"; powerlimit = 2;
break;
case 0:
powername = "STANDBY"; powerlimit = 3; break;
case 0x80:
powername = "IDLE"; powerlimit = 4; break;
case 0xff:
powername = "ACTIVE or IDLE"; break;
default:
pout("CHECK POWER STATUS returned %d, not ATA compliant, ignoring -n Option\n", powermode);
break;
}
if (powername) {
if (con->powermode >= powerlimit) {
pout("Device is in %s mode, exit(%d)\n", powername, FAILPOWER);
return FAILPOWER;
}
powerchg = (powermode != 0xff); // SMART tests will spin up drives
}
}
// Start by getting Drive ID information. We need this, to know if SMART is supported.
if ((retid=ataReadHDIdentity(fd,&drive))<0){
@ -1432,7 +1467,7 @@ int ataPrintMain (int fd){
// Print most drive identity information if requested
if (con->driveinfo){
pout("=== START OF INFORMATION SECTION ===\n");
ataPrintDriveInfo(&drive);
known = ataPrintDriveInfo(&drive);
}
// Was this a packet device?
@ -1451,7 +1486,7 @@ int ataPrintMain (int fd){
}
else {
pout("SMART support is: Ambiguous - ATA IDENTIFY DEVICE words 82-83 don't show if SMART supported.\n");
failuretest(MANDATORY_CMD, returnval|=FAILSMART);
if (!known) failuretest(MANDATORY_CMD, returnval|=FAILSMART);
pout(" Checking for SMART support by trying SMART ENABLE command.\n");
}
@ -1497,6 +1532,9 @@ int ataPrintMain (int fd){
else
pout("SMART support is: Disabled\n");
}
// Print the (now possibly changed) power mode if available
if (powername)
pout("Power mode %s %s\n", (powerchg?"was:":"is: "), powername);
pout("\n");
}

View File

@ -25,13 +25,13 @@
#ifndef ATAPRINT_H_
#define ATAPRINT_H_
#define ATAPRINT_H_CVSID "$Id: ataprint.h,v 1.28 2006/04/12 14:54:28 ballen4705 Exp $\n"
#define ATAPRINT_H_CVSID "$Id: ataprint.h,v 1.29 2006/09/17 10:12:51 shattered Exp $\n"
#include <stdio.h>
#include <stdlib.h>
/* Prints ATA Drive Information and S.M.A.R.T. Capability */
void ataPrintDriveInfo(struct ata_identify_device *);
int ataPrintDriveInfo(struct ata_identify_device *);
void ataPrintGeneralSmartValues(struct ata_smart_values *, struct ata_identify_device *);

1450
config.guess vendored

File diff suppressed because it is too large Load Diff

View File

@ -1,148 +0,0 @@
/* config.h.in. Generated from configure.in by autoheader. */
/* smartmontools CVS Tag */
#undef CONFIG_H_CVSID
/* use mailx as default mailer */
#undef DEFAULT_MAILER
/* Define to 1 if you have the `ata_identify_is_cached' function in os_*.c. */
#undef HAVE_ATA_IDENTIFY_IS_CACHED
/* Define to 1 if C compiler supports __attribute__((packed)) */
#undef HAVE_ATTR_PACKED
/* Define to 1 if you have the <dev/ata/atavar.h> header file. */
#undef HAVE_DEV_ATA_ATAVAR_H
/* Define to 1 if you have the `getdomainname' function. */
#undef HAVE_GETDOMAINNAME
/* Define to 1 if you have the `gethostbyname' function. */
#undef HAVE_GETHOSTBYNAME
/* Define to 1 if you have the `gethostname' function. */
#undef HAVE_GETHOSTNAME
/* Define to 1 if you have the `getopt' function. */
#undef HAVE_GETOPT
/* Define to 1 if you have the <getopt.h> header file. */
#undef HAVE_GETOPT_H
/* Define to 1 if you have the `getopt_long' function. */
#undef HAVE_GETOPT_LONG
/* Define to 1 if you have the `get_os_version_str' function in os_*.c. */
#undef HAVE_GET_OS_VERSION_STR
/* Define to 1 if the system has the type `int64_t'. */
#undef HAVE_INT64_T
/* Define to 1 if you have the <inttypes.h> header file. */
#undef HAVE_INTTYPES_H
/* Define to 1 if you have the <locale.h> header file. */
#undef HAVE_LOCALE_H
/* Define to 1 if you have the <memory.h> header file. */
#undef HAVE_MEMORY_H
/* Define to 1 if you have the <netdb.h> header file. */
#undef HAVE_NETDB_H
/* Define to 1 if you have the `sigset' function. */
#undef HAVE_SIGSET
/* Define to 1 if you have the <stdint.h> header file. */
#undef HAVE_STDINT_H
/* Define to 1 if you have the <stdlib.h> header file. */
#undef HAVE_STDLIB_H
/* Define to 1 if you have the <strings.h> header file. */
#undef HAVE_STRINGS_H
/* Define to 1 if you have the <string.h> header file. */
#undef HAVE_STRING_H
/* Define to 1 if you have the `strtoull' function. */
#undef HAVE_STRTOULL
/* Define to 1 if you have the <sys/inttypes.h> header file. */
#undef HAVE_SYS_INTTYPES_H
/* Define to 1 if you have the <sys/int_types.h> header file. */
#undef HAVE_SYS_INT_TYPES_H
/* Define to 1 if you have the <sys/stat.h> header file. */
#undef HAVE_SYS_STAT_H
/* Define to 1 if you have the <sys/tweio.h> header file. */
#undef HAVE_SYS_TWEIO_H
/* Define to 1 if you have the <sys/twereg.h> header file. */
#undef HAVE_SYS_TWEREG_H
/* Define to 1 if you have the <sys/tw_osl_ioctl.h> header file. */
#undef HAVE_SYS_TW_OSL_IOCTL_H
/* Define to 1 if you have the <sys/types.h> header file. */
#undef HAVE_SYS_TYPES_H
/* Define to 1 if the system has the type `uint64_t'. */
#undef HAVE_UINT64_T
/* Define to 1 if you have the `uname' function. */
#undef HAVE_UNAME
/* Define to 1 if you have the <unistd.h> header file. */
#undef HAVE_UNISTD_H
/* Define to 1 if the `snprintf' function is sane */
#undef HAVE_WORKING_SNPRINTF
/* need assembly code os_solaris_ata.s */
#undef NEED_SOLARIS_ATA_CODE
/* Name of package */
#undef PACKAGE
/* Define to the address where bug reports for this package should be sent. */
#undef PACKAGE_BUGREPORT
/* smartmontools Home Page */
#undef PACKAGE_HOMEPAGE
/* Define to the full name of this package. */
#undef PACKAGE_NAME
/* Define to the full name and version of this package. */
#undef PACKAGE_STRING
/* Define to the one symbol short name of this package. */
#undef PACKAGE_TARNAME
/* Define to the version of this package. */
#undef PACKAGE_VERSION
/* smartmontools Build Host */
#undef SMARTMONTOOLS_BUILD_HOST
/* smartmontools Configure Arguments */
#undef SMARTMONTOOLS_CONFIGURE_ARGS
/* smartmontools Configure Date */
#undef SMARTMONTOOLS_CONFIGURE_DATE
/* smartmontools Release Date */
#undef SMARTMONTOOLS_RELEASE_DATE
/* smartmontools Release Time */
#undef SMARTMONTOOLS_RELEASE_TIME
/* Define to 1 if you have the ANSI C header files. */
#undef STDC_HEADERS
/* Version number of package */
#undef VERSION

1555
config.sub vendored

File diff suppressed because it is too large Load Diff

8268
configure vendored

File diff suppressed because it is too large Load Diff

View File

@ -1,13 +1,13 @@
#
# $Id: configure.in,v 1.114 2006/04/12 17:39:32 ballen4705 Exp $
# $Id: configure.in,v 1.118 2006/08/12 05:41:13 card_captor Exp $
#
dnl Process this file with autoconf to produce a configure script.
AC_PREREQ(2.50)
AC_INIT(smartmontools, 5.36, smartmontools-support@lists.sourceforge.net)
AC_CONFIG_SRCDIR(smartctl.c)
AC_INIT(smartmontools, 5.37, 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.114 2006/04/12 17:39:32 ballen4705 Exp $'`
smartmontools_cvs_tag=`echo '$Id: configure.in,v 1.118 2006/08/12 05:41:13 card_captor Exp $'`
smartmontools_release_date=2006/04/12
smartmontools_release_time="17:39:01 UTC"
@ -24,9 +24,9 @@ AM_INIT_AUTOMAKE
AM_MAINTAINER_MODE
AC_LANG_C
AC_LANG_CPLUSPLUS
dnl Checks for programs.
AC_PROG_CC
AC_PROG_CXX
AM_PROG_AS
AC_PROG_INSTALL
@ -78,7 +78,9 @@ AH_TEMPLATE(HAVE_WORKING_SNPRINTF, [Define to 1 if the `snprintf' function is sa
AC_MSG_CHECKING([for working snprintf])
AC_RUN_IFELSE([AC_LANG_PROGRAM([[#include <stdio.h>]], [[ char buf[]="ABCDEFGHI";
int i=snprintf(buf,8,"12345678"); return !(!buf[7] && i==8); ]])],
[libc_have_working_snprintf=yes], [libc_have_working_snprintf=no])
[libc_have_working_snprintf=yes],
[libc_have_working_snprintf=no],
[libc_have_working_snprintf=no])
AC_SUBST(libc_have_working_snprintf)
if test "$libc_have_working_snprintf" = "yes"; then
AC_DEFINE(HAVE_WORKING_SNPRINTF)
@ -86,8 +88,8 @@ fi
AC_MSG_RESULT([$libc_have_working_snprintf])
# check for __attribute__((packed))
AH_TEMPLATE(HAVE_ATTR_PACKED, [Define to 1 if C compiler supports __attribute__((packed))])
AC_MSG_CHECKING([whether C compiler supports __attribute__((packed))])
AH_TEMPLATE(HAVE_ATTR_PACKED, [Define to 1 if C++ compiler supports __attribute__((packed))])
AC_MSG_CHECKING([whether C++ compiler supports __attribute__((packed))])
AC_COMPILE_IFELSE([AC_LANG_PROGRAM(, [[struct a { int b; } __attribute__((packed));]])],
[gcc_have_attr_packed=yes], [gcc_have_attr_packed=no])
AC_SUBST(gcc_have_attr_packed)
@ -180,41 +182,42 @@ AM_CONDITIONAL(OS_WIN32_MINGW, [echo $host_os | grep '^mingw' > /dev/null])
dnl Add -Wall and -W if using gcc and its not already specified.
if test "x$GCC" = "xyes"; then
if test -z "`echo "$CFLAGS" | grep "\-Wall" 2> /dev/null`" ; then
CFLAGS="$CFLAGS -Wall"
if test -z "`echo "$CXXFLAGS" | grep "\-Wall" 2> /dev/null`" ; then
CXXFLAGS="$CXXFLAGS -Wall"
fi
# In the next line, do NOT delete the 2 spaces inside double quotes.
if test -z "`echo "$CFLAGS " | grep "\-W " 2> /dev/null`" ; then
CFLAGS="$CFLAGS -W"
if test -z "`echo "$CXXFLAGS " | grep "\-W " 2> /dev/null`" ; then
CXXFLAGS="$CXXFLAGS -W"
fi
case "${host}" in
*-*-mingw*)
# MinGW uses MSVCRT.DLL which uses printf format "%I64d" and not "%lld" for int64_t
CFLAGS="$CFLAGS -Wno-format";;
CXXFLAGS="$CXXFLAGS -Wno-format";;
esac
else
dnl We are NOT using gcc, so enable host-specific compiler flags
case "${host}" in
*-*-solaris*)
dnl set CFLAGS for Solaris C compiler
if test -z "`echo "$CFLAGS" | grep "\-xmemalign" 2> /dev/null`" ; then
dnl set CXXFLAGS for Solaris C++ compiler
if test -z "`echo "$CXXFLAGS" | grep "\-xmemalign" 2> /dev/null`" ; then
dnl we have to tell the compilers about packed ATA structures
CFLAGS="-xmemalign=1i $CFLAGS"
CXXFLAGS="-xmemalign=1i $CXXFLAGS"
fi
if test -z "`echo "$CFLAGS" | grep "\-xCC" 2> /dev/null`" ; then
dnl we have to tell the compiler to ignore C++ style comments
CFLAGS="-xCC $CFLAGS"
fi
if test -z "`echo "$CFLAGS" | grep "\-xO" 2> /dev/null`" ; then
if test -z "`echo "$CXXFLAGS" | grep "\-xO" 2> /dev/null`" ; then
dnl turn on optimization if user has not explicitly set its value
CFLAGS="-xO2 $CFLAGS"
CXXFLAGS="-xO2 $CXXFLAGS"
fi
if test -z "`echo "$CXXFLAGS" | grep "\-erroff" 2> /dev/null`" ; then
dnl suppress warnings on use of string literal (const char[]) as
dnl char*. TODO: Sun Studio 10 (Sun C++ 5.7) or above only?
CXXFLAGS="-erroff=%none,wbadinitl,wbadasgl,badargtypel2w $CXXFLAGS"
fi
esac
fi
AC_DEFINE_UNQUOTED(SMARTMONTOOLS_BUILD_HOST, "${host}", [smartmontools Build Host])
AC_SUBST(CFLAGS)
AC_SUBST(CXXFLAGS)
AC_OUTPUT(Makefile examplescripts/Makefile)
AC_PROG_MAKE_SET

522
depcomp
View File

@ -1,522 +0,0 @@
#! /bin/sh
# depcomp - compile a program generating dependencies as side-effects
scriptversion=2004-05-31.23
# Copyright (C) 1999, 2000, 2003, 2004 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., 59 Temple Place - Suite 330, Boston, MA
# 02111-1307, 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 0
;;
-v | --v*)
echo "depcomp $scriptversion"
exit 0
;;
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
# Dependencies are output in .lo.d with libtool 1.4.
# With libtool 1.5 they are output both in $dir.libs/$base.o.d
# and in $dir.libs/$base.o.d and $dir$base.o.d. We process the
# latter, because the former will be cleaned when $dir.libs is
# erased.
tmpdepfile1="$dir.libs/$base.lo.d"
tmpdepfile2="$dir$base.o.d"
tmpdepfile3="$dir.libs/$base.d"
"$@" -Wc,-MD
else
tmpdepfile1="$dir$base.o.d"
tmpdepfile2="$dir$base.d"
tmpdepfile3="$dir$base.d"
"$@" -MD
fi
stat=$?
if test $stat -eq 0; then :
else
rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
exit $stat
fi
if test -f "$tmpdepfile1"; then
tmpdepfile="$tmpdepfile1"
elif test -f "$tmpdepfile2"; then
tmpdepfile="$tmpdepfile2"
else
tmpdepfile="$tmpdepfile3"
fi
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 '/^# [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:

113
do_release Executable file
View File

@ -0,0 +1,113 @@
#!/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.39 2006/05/19 16:33:33 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
if [ -f /etc/redhat-release ]; then
RPM_BASE=/usr/src/redhat/
else
RPM_BASE=/usr/src/rpm/
fi
SOURCES=$RPM_BASE/SOURCES/
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 ..
cp build/smartmontools-$VERSION.tar.gz $SOURCES
# build rpm
rpmbuild -ba --sign smartmontools.spec
# remove source tarball
rm -f $SOURCES/smartmontools-$VERSION.tar.gz
# 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
mv -f $RPM_BASE/RPMS/i386/smartmontools-$VERSION-*.i386.rpm . || mv -f $RPM_BASE/RPMS/x86_64/smartmontools-$VERSION-*.x86_64.rpm .
mv -f $RPM_BASE/SRPMS/smartmontools-$VERSION-*.src.rpm .
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 aclocal.m4 missing *.bak

View File

@ -1,369 +0,0 @@
# Makefile.in generated by automake 1.9.3 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
# 2003, 2004 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
@SET_MAKE@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
pkgdatadir = $(datadir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
top_builddir = ..
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
INSTALL = @INSTALL@
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
subdir = examplescripts
DIST_COMMON = README $(srcdir)/Makefile.am $(srcdir)/Makefile.in
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/configure.in
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(install_sh) -d
CONFIG_HEADER = $(top_builddir)/config.h
CONFIG_CLEAN_FILES =
am__installdirs = "$(DESTDIR)$(examplesdir)" \
"$(DESTDIR)$(examplesdir)"
examplesSCRIPT_INSTALL = $(INSTALL_SCRIPT)
SCRIPTS = $(examples_SCRIPTS)
SOURCES =
DIST_SOURCES =
am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
am__vpath_adj = case $$p in \
$(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
*) f=$$p;; \
esac;
am__strip_dir = `echo $$p | sed -e 's|^.*/||'`;
examplesDATA_INSTALL = $(INSTALL_DATA)
DATA = $(examples_DATA)
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
AMDEP_FALSE = @AMDEP_FALSE@
AMDEP_TRUE = @AMDEP_TRUE@
AMTAR = @AMTAR@
ASFLAGS = @ASFLAGS@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
CC = @CC@
CCAS = @CCAS@
CCASFLAGS = @CCASFLAGS@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
LDFLAGS = @LDFLAGS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LTLIBOBJS = @LTLIBOBJS@
MAINT = @MAINT@
MAINTAINER_MODE_FALSE = @MAINTAINER_MODE_FALSE@
MAINTAINER_MODE_TRUE = @MAINTAINER_MODE_TRUE@
MAKEINFO = @MAKEINFO@
OBJEXT = @OBJEXT@
OS_DARWIN_FALSE = @OS_DARWIN_FALSE@
OS_DARWIN_TRUE = @OS_DARWIN_TRUE@
OS_SOLARIS_FALSE = @OS_SOLARIS_FALSE@
OS_SOLARIS_TRUE = @OS_SOLARIS_TRUE@
OS_WIN32_MINGW_FALSE = @OS_WIN32_MINGW_FALSE@
OS_WIN32_MINGW_TRUE = @OS_WIN32_MINGW_TRUE@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
SMARTD_SUFFIX_FALSE = @SMARTD_SUFFIX_FALSE@
SMARTD_SUFFIX_TRUE = @SMARTD_SUFFIX_TRUE@
STRIP = @STRIP@
VERSION = @VERSION@
ac_ct_CC = @ac_ct_CC@
ac_ct_STRIP = @ac_ct_STRIP@
am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
datadir = @datadir@
docdir = @docdir@
exampledir = @exampledir@
exec_prefix = @exec_prefix@
gcc_have_attr_packed = @gcc_have_attr_packed@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
includedir = @includedir@
infodir = @infodir@
initddir = @initddir@
install_sh = @install_sh@
libc_have_working_snprintf = @libc_have_working_snprintf@
libdir = @libdir@
libexecdir = @libexecdir@
localstatedir = @localstatedir@
mandir = @mandir@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
os_deps = @os_deps@
os_libs = @os_libs@
prefix = @prefix@
program_transform_name = @program_transform_name@
releaseversion = @releaseversion@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
smartd_suffix = @smartd_suffix@
smartmontools_release_date = @smartmontools_release_date@
smartmontools_release_time = @smartmontools_release_time@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
examplesdir = $(exampledir)
examples_DATA = README
examples_SCRIPTS = Example1 \
Example2 \
Example3
EXTRA_DIST = $(examples_SCRIPTS)
all: all-am
.SUFFIXES:
$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
&& exit 0; \
exit 1;; \
esac; \
done; \
echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign examplescripts/Makefile'; \
cd $(top_srcdir) && \
$(AUTOMAKE) --foreign examplescripts/Makefile
.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
*) \
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
esac;
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
install-examplesSCRIPTS: $(examples_SCRIPTS)
@$(NORMAL_INSTALL)
test -z "$(examplesdir)" || $(mkdir_p) "$(DESTDIR)$(examplesdir)"
@list='$(examples_SCRIPTS)'; for p in $$list; do \
if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
if test -f $$d$$p; then \
f=`echo "$$p" | sed 's|^.*/||;$(transform)'`; \
echo " $(examplesSCRIPT_INSTALL) '$$d$$p' '$(DESTDIR)$(examplesdir)/$$f'"; \
$(examplesSCRIPT_INSTALL) "$$d$$p" "$(DESTDIR)$(examplesdir)/$$f"; \
else :; fi; \
done
uninstall-examplesSCRIPTS:
@$(NORMAL_UNINSTALL)
@list='$(examples_SCRIPTS)'; for p in $$list; do \
f=`echo "$$p" | sed 's|^.*/||;$(transform)'`; \
echo " rm -f '$(DESTDIR)$(examplesdir)/$$f'"; \
rm -f "$(DESTDIR)$(examplesdir)/$$f"; \
done
uninstall-info-am:
install-examplesDATA: $(examples_DATA)
@$(NORMAL_INSTALL)
test -z "$(examplesdir)" || $(mkdir_p) "$(DESTDIR)$(examplesdir)"
@list='$(examples_DATA)'; for p in $$list; do \
if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
f=$(am__strip_dir) \
echo " $(examplesDATA_INSTALL) '$$d$$p' '$(DESTDIR)$(examplesdir)/$$f'"; \
$(examplesDATA_INSTALL) "$$d$$p" "$(DESTDIR)$(examplesdir)/$$f"; \
done
uninstall-examplesDATA:
@$(NORMAL_UNINSTALL)
@list='$(examples_DATA)'; for p in $$list; do \
f=$(am__strip_dir) \
echo " rm -f '$(DESTDIR)$(examplesdir)/$$f'"; \
rm -f "$(DESTDIR)$(examplesdir)/$$f"; \
done
tags: TAGS
TAGS:
ctags: CTAGS
CTAGS:
distdir: $(DISTFILES)
@srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
list='$(DISTFILES)'; for file in $$list; do \
case $$file in \
$(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
$(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
esac; \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
if test "$$dir" != "$$file" && test "$$dir" != "."; then \
dir="/$$dir"; \
$(mkdir_p) "$(distdir)$$dir"; \
else \
dir=''; \
fi; \
if test -d $$d/$$file; then \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
fi; \
cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
else \
test -f $(distdir)/$$file \
|| cp -p $$d/$$file $(distdir)/$$file \
|| exit 1; \
fi; \
done
check-am: all-am
check: check-am
all-am: Makefile $(SCRIPTS) $(DATA)
installdirs:
for dir in "$(DESTDIR)$(examplesdir)" "$(DESTDIR)$(examplesdir)"; do \
test -z "$$dir" || $(mkdir_p) "$$dir"; \
done
install: install-am
install-exec: install-exec-am
install-data: install-data-am
uninstall: uninstall-am
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-am
install-strip:
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
`test -z '$(STRIP)' || \
echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
mostlyclean-generic:
clean-generic:
distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
clean: clean-am
clean-am: clean-generic mostlyclean-am
distclean: distclean-am
-rm -f Makefile
distclean-am: clean-am distclean-generic
dvi: dvi-am
dvi-am:
html: html-am
info: info-am
info-am:
install-data-am: install-examplesDATA install-examplesSCRIPTS
install-exec-am:
install-info: install-info-am
install-man:
installcheck-am:
maintainer-clean: maintainer-clean-am
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-am
mostlyclean-am: mostlyclean-generic
pdf: pdf-am
pdf-am:
ps: ps-am
ps-am:
uninstall-am: uninstall-examplesDATA uninstall-examplesSCRIPTS \
uninstall-info-am
.PHONY: all all-am check check-am clean clean-generic distclean \
distclean-generic distdir dvi dvi-am html html-am info info-am \
install install-am install-data install-data-am \
install-examplesDATA install-examplesSCRIPTS install-exec \
install-exec-am install-info install-info-am install-man \
install-strip installcheck installcheck-am installdirs \
maintainer-clean maintainer-clean-generic mostlyclean \
mostlyclean-generic pdf pdf-am ps ps-am uninstall uninstall-am \
uninstall-examplesDATA uninstall-examplesSCRIPTS \
uninstall-info-am
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:

View File

@ -25,7 +25,7 @@
#ifndef EXTERN_H_
#define EXTERN_H_
#define EXTERN_H_CVSID "$Id: extern.h,v 1.41 2006/04/12 14:54:28 ballen4705 Exp $\n"
#define EXTERN_H_CVSID "$Id: extern.h,v 1.47 2006/09/15 08:03:52 sxzzsf Exp $\n"
// Possible values for fixfirmwarebug. If use has NOT specified -F at
// all, then value is 0.
@ -50,6 +50,8 @@ typedef struct smartmonctrl_s {
// turn off scan after selective self-test, 2: turn on scan after
// selective self-test.
unsigned char scanafterselect;
// skip check, if disk in idle or standby mode
unsigned char powermode;
unsigned char driveinfo;
unsigned char checksmart;
unsigned char smartvendorattrib;
@ -58,6 +60,7 @@ typedef struct smartmonctrl_s {
unsigned char smartselftestlog;
unsigned char selectivetestlog;
unsigned char smarterrorlog;
unsigned char smartbackgroundlog;
unsigned char smartdisable;
unsigned char smartenable;
unsigned char smartstatus;
@ -84,10 +87,15 @@ typedef struct smartmonctrl_s {
unsigned char reportataioctl;
unsigned char reportscsiioctl;
unsigned char fixfirmwarebug;
unsigned char satpassthrulen;
// Controller type (device type) has been specified explicitly
unsigned char controller_explicit;
// 3Ware controller type, but also extensible to other contoller types
unsigned char controller_type;
// For 3Ware controllers, nonzero value is 1 plus the disk number
unsigned char controller_port;
// combined controller/channle/pmport for highpoint rocketraid controller
unsigned char hpt_data[3];
unsigned char ignorepresets;
unsigned char showpresets;
// The i'th entry in this array will modify the printed meaning of

View File

@ -1,323 +0,0 @@
#!/bin/sh
# install - install a program, script, or datafile
scriptversion=2004-10-22.00
# 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 0;;
-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 0;;
*) # 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
}
else
:
fi
} &&
# Now rename the file to the real destination.
$doit $mvcmd "$dsttmp" "$dstdir/$dstfile"
}
}
fi || { (exit 1); exit; }
done
# The final little trick to "correctly" pass the exit status to the exit trap.
{
(exit 0); exit
}
# 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

@ -1,5 +1,5 @@
/*
* knowndrives.c
* knowndrives.cpp
*
* Home page of code is: http://smartmontools.sourceforge.net
* Address of support mailing list: smartmontools-support@lists.sourceforge.net
@ -26,14 +26,14 @@
#include "knowndrives.h"
#include "utility.h" // includes <regex.h>
const char *knowndrives_c_cvsid="$Id: knowndrives.c,v 1.139 2006/04/05 19:50:07 chrfranke Exp $"
const char *knowndrives_c_cvsid="$Id: knowndrives.cpp,v 1.144 2006/09/24 16:32:25 chrfranke 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
#define FIRMWARE_STRING_LENGTH 8
#define TABLEPRINTWIDTH 19
// See vendorattributeargs[] array in atacmds.c for definitions.
// See vendorattributeargs[] array in atacmds.cpp for definitions.
#define PRESET_9_MINUTES { 9, 1 }
#define PRESET_9_TEMP { 9, 2 }
#define PRESET_9_SECONDS { 9, 3 }
@ -180,50 +180,8 @@ const drivesettings knowndrives[] = {
vendoropts_9_seconds,
NULL, NULL
},
{ "Fujitsu MHG and MHH series",
"^FUJITSU MH(G2102|H20(64|48|32))AT$",
".*",
NULL,
vendoropts_9_seconds,
NULL, NULL
},
{ "Fujitsu MHJ and MHK series",
"^FUJITSU MH[JK]....ATU?$",
".*",
NULL,
vendoropts_9_seconds,
NULL, NULL
},
{ "Fujitsu MPB series",
"^FUJITSU MPB....ATU?$",
".*",
NULL,
vendoropts_9_seconds,
NULL, NULL
},
{ "Fujitsu MPD and MPE series",
"^FUJITSU MP[DE]....A[HTE]$",
".*",
NULL,
vendoropts_9_seconds,
NULL, NULL
},
{ "Fujitsu MPF series",
"^FUJITSU MPF3(102A[HT]|153A[HT]|204A[HT])$",
".*",
NULL,
vendoropts_9_seconds,
NULL, NULL
},
{ "Fujitsu MPG series",
"^FUJITSU MPG3(102A(H|T E)|153AH|204A(H|[HT] E)|307A(H E|T)|409A[HT] E)$",
".*",
NULL,
vendoropts_9_seconds,
NULL, NULL
},
{ "Fujitsu MPC series",
"^FUJITSU MPC3(032AT|043AT|045AH|064A[HT]|084AT|096AT|102AT)$",
{ "Fujitsu MHG..MHK, MHT, MHU series",
"^FUJITSU MH[GHJKTU]2...ATU?",
".*",
NULL,
vendoropts_9_seconds,
@ -265,15 +223,8 @@ const drivesettings knowndrives[] = {
vendoropts_9_seconds,
NULL, NULL
},
{ "Fujitsu MHT2xxxAT/MHU2100AT series",
"^FUJITSU MH(T20[23468]0AT( PL)?|U2100AT)$",
".*",
NULL,
vendoropts_9_seconds,
NULL, NULL
},
{ "Fujitsu MHTxxxxAH family",
"^FUJITSU MHT20[468]0AH$",
{ "Fujitsu MPA..MPG series",
"^FUJITSU MP[A-G]3...A[HTEV]U?",
".*",
NULL,
vendoropts_9_seconds,
@ -343,6 +294,14 @@ const drivesettings knowndrives[] = {
specialpurpose_reverse_samsung,
same_as_minus_F
},
{ "SAMSUNG SpinPoint T133 series", // tested with HD300LJ/ZT100-12, HD400LJ/ZZ100-14, HD401LJ/ZZ100-15
"^SAMSUNG HD[34][02][01]L[DJ]$",
".*",
NULL,
NULL,
NULL,
NULL
},
{
NULL, // Any other Samsung disk with *-23 *-24 firmware
// SAMSUNG SP1213N (TL100-23 firmware)
@ -758,7 +717,7 @@ const drivesettings knowndrives[] = {
NULL, NULL, NULL, NULL
},
{ "Seagate Momentus 5400.2 series",
"^ST9(100823|808211|60822|408114|308110)A$",
"^ST9(9808211|960822|808211|408114|308110|120821|10082[34]|98823|96812|94813|93811|60822)AS?$",
".*",
NULL, NULL, NULL, NULL
},

View File

@ -20,7 +20,7 @@
#ifndef KNOWNDRIVES_H_
#define KNOWNDRIVES_H_
#define KNOWNDRIVES_H_CVSID "$Id: knowndrives.h,v 1.16 2006/04/05 19:50:07 chrfranke Exp $\n"
#define KNOWNDRIVES_H_CVSID "$Id: knowndrives.h,v 1.17 2006/08/09 20:40:19 chrfranke Exp $\n"
/* Structure used to store settings for specific drives in knowndrives[]. The
* elements are used in the following ways:
@ -50,13 +50,13 @@
* make the output more informative.
*/
typedef struct drivesettings_s {
const char * const modelfamily;
const char * const modelregexp;
const char * const firmwareregexp;
const char * const warningmsg;
const unsigned char (* const vendoropts)[2];
void (* const specialpurpose)(smartmonctrl *);
const char * const functiondesc;
const char * modelfamily;
const char * modelregexp;
const char * firmwareregexp;
const char * warningmsg;
const unsigned char (* vendoropts)[2];
void (* specialpurpose)(smartmonctrl *);
const char * functiondesc;
} drivesettings;
/* Table of settings for known drives. Defined in knowndrives.c. */

353
missing
View File

@ -1,353 +0,0 @@
#! /bin/sh
# Common stub for a few missing GNU programs while installing.
scriptversion=2004-09-07.08
# Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004
# 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., 59 Temple Place - Suite 330, Boston, MA
# 02111-1307, 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 0
;;
-v|--v|--ve|--ver|--vers|--versi|--versio|--version)
echo "missing $scriptversion (GNU Automake)"
exit 0
;;
-*)
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."
file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'`
if test -z "$file"; then
file=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'`
file=`sed -n '/^@setfilename/ { s/.* \([^ ]*\) *$/\1/; p; q; }' $file`
fi
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

@ -24,10 +24,11 @@
#include <IOKit/IOKitLib.h>
#include <IOKit/IOReturn.h>
#include <IOKit/IOBSD.h>
#include <IOKit/storage/ata/IOATAStorageDefines.h>
#include <IOKit/storage/ata/ATASMARTLib.h>
#include <IOKit/storage/IOBlockStorageDevice.h>
#include <IOKit/storage/IOStorageDeviceCharacteristics.h>
#include <IOKit/storage/IOMedia.h>
#include <IOKit/storage/ata/IOATAStorageDefines.h>
#include <IOKit/storage/ata/ATASMARTLib.h>
#include <CoreFoundation/CoreFoundation.h>
// No, I don't know why there isn't a header for this.
@ -42,7 +43,7 @@
#include "os_darwin.h"
// Needed by '-V' option (CVS versioning) of smartd/smartctl
const char *os_XXXX_c_cvsid="$Id: os_darwin.c,v 1.13 2006/04/12 14:54:28 ballen4705 Exp $" \
const char *os_XXXX_c_cvsid="$Id: os_darwin.cpp,v 1.18 2006/09/20 16:17:31 shattered Exp $" \
ATACMDS_H_CVSID CONFIG_H_CVSID INT64_H_CVSID OS_DARWIN_H_CVSID SCSICMDS_H_CVSID UTILITY_H_CVSID;
// Print examples for smartctl.
@ -76,6 +77,46 @@ int guess_device_type (const char* dev_name) {
return CONTROLLER_ATA;
}
// Determine whether 'dev' is a SMART-capable device.
static bool is_smart_capable (io_object_t dev) {
CFTypeRef smartCapableKey;
CFDictionaryRef diskChars;
// If the device has kIOPropertySMARTCapableKey, then it's capable,
// no matter what it looks like.
smartCapableKey = IORegistryEntryCreateCFProperty
(dev, CFSTR (kIOPropertySMARTCapableKey),
kCFAllocatorDefault, 0);
if (smartCapableKey)
{
CFRelease (smartCapableKey);
return true;
}
// If it's an kIOATABlockStorageDeviceClass then we're successful
// only if its ATA features indicate it supports SMART.
if (IOObjectConformsTo (dev, kIOATABlockStorageDeviceClass)
&& (diskChars = (CFDictionaryRef)IORegistryEntryCreateCFProperty
(dev, CFSTR (kIOPropertyDeviceCharacteristicsKey),
kCFAllocatorDefault, kNilOptions)) != NULL)
{
CFNumberRef diskFeatures = NULL;
UInt32 ataFeatures = 0;
if (CFDictionaryGetValueIfPresent (diskChars, CFSTR ("ATA Features"),
(const void **)&diskFeatures))
CFNumberGetValue (diskFeatures, kCFNumberLongType,
&ataFeatures);
CFRelease (diskChars);
if (diskFeatures)
CFRelease (diskFeatures);
return (ataFeatures & kIOATAFeatureSMART) != 0;
}
return false;
}
// 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
@ -85,46 +126,52 @@ int guess_device_type (const char* dev_name) {
int make_device_names (char*** devlist, const char* name) {
IOReturn err;
io_iterator_t i;
io_object_t device;
io_object_t device = MACH_PORT_NULL;
int result;
int index;
const char * cls;
if (strcmp (name, "ATA") == 0)
cls = kIOATABlockStorageDeviceClass;
else // only ATA supported right now.
// We treat all devices as ATA so long as they support SMARTLib.
if (strcmp (name, "ATA") != 0)
return 0;
err = IOServiceGetMatchingServices (kIOMasterPortDefault,
IOServiceMatching (cls),
&i);
err = IOServiceGetMatchingServices
(kIOMasterPortDefault, IOServiceMatching (kIOBlockStorageDeviceClass), &i);
if (err != kIOReturnSuccess)
return -1;
// Count the devices.
for (result = 0; (device = IOIteratorNext (i)) != MACH_PORT_NULL; result++)
result = 0;
while ((device = IOIteratorNext (i)) != MACH_PORT_NULL) {
if (is_smart_capable (device))
result++;
IOObjectRelease (device);
}
// Create an array of service names.
IOIteratorReset (i);
*devlist = Calloc (result, sizeof (char *));
*devlist = (char**)Calloc (result, sizeof (char *));
if (! *devlist)
goto error;
for (index = 0; (device = IOIteratorNext (i)) != MACH_PORT_NULL; index++)
{
io_string_t devName;
IORegistryEntryGetPath(device, kIOServicePlane, devName);
IOObjectRelease (device);
index = 0;
while ((device = IOIteratorNext (i)) != MACH_PORT_NULL) {
if (is_smart_capable (device))
{
io_string_t devName;
IORegistryEntryGetPath(device, kIOServicePlane, devName);
(*devlist)[index] = CustomStrDup (devName, true, __LINE__, __FILE__);
if (! (*devlist)[index])
goto error;
index++;
}
IOObjectRelease (device);
}
(*devlist)[index] = CustomStrDup (devName, true, __LINE__, __FILE__);
if (! (*devlist)[index])
goto error;
}
IOObjectRelease (i);
return result;
error:
if (device != MACH_PORT_NULL)
IOObjectRelease (device);
IOObjectRelease (i);
if (*devlist)
{
@ -140,7 +187,6 @@ int make_device_names (char*** devlist, const char* name) {
static struct {
io_object_t ioob;
bool hassmart;
IOCFPlugInInterface **plugin;
IOATASMARTInterface **smartIf;
} devices[20];
@ -203,44 +249,24 @@ int deviceopen(const char *pathname, char *type){
return -1;
}
// Find the ATA block storage driver that is the parent of this device
while (! IOObjectConformsTo (disk, kIOATABlockStorageDeviceClass))
// Find a SMART-capable driver which is a parent of this device.
while (! is_smart_capable (disk))
{
IOReturn err;
io_object_t notdisk = disk;
io_object_t prevdisk = disk;
err = IORegistryEntryGetParentEntry (notdisk, kIOServicePlane, &disk);
// Find this device's parent and try again.
err = IORegistryEntryGetParentEntry (disk, kIOServicePlane, &disk);
if (err != kIOReturnSuccess || ! disk)
{
errno = ENODEV;
IOObjectRelease (notdisk);
IOObjectRelease (prevdisk);
return -1;
}
}
devices[devnum].ioob = disk;
{
CFDictionaryRef diskChars = NULL;
CFNumberRef diskFeatures = NULL;
UInt32 ataFeatures;
// Determine whether the drive actually supports SMART.
if ((diskChars = IORegistryEntryCreateCFProperty (disk,
CFSTR (kIOPropertyDeviceCharacteristicsKey),
kCFAllocatorDefault,
kNilOptions)) != NULL
&& CFDictionaryGetValueIfPresent (diskChars, CFSTR ("ATA Features"),
(const void **)&diskFeatures)
&& CFNumberGetValue (diskFeatures, kCFNumberLongType, &ataFeatures)
&& (ataFeatures & kIOATAFeatureSMART))
devices[devnum].hassmart = true;
else
devices[devnum].hassmart = false;
if (diskChars)
CFRelease (diskChars);
}
{
SInt32 dummy;
@ -248,16 +274,15 @@ int deviceopen(const char *pathname, char *type){
devices[devnum].smartIf = NULL;
// Create an interface to the ATA SMART library.
if (devices[devnum].hassmart
&& IOCreatePlugInInterfaceForService (disk,
kIOATASMARTUserClientTypeID,
kIOCFPlugInInterfaceID,
&devices[devnum].plugin,
&dummy) == kIOReturnSuccess)
if (IOCreatePlugInInterfaceForService (disk,
kIOATASMARTUserClientTypeID,
kIOCFPlugInInterfaceID,
&devices[devnum].plugin,
&dummy) == kIOReturnSuccess)
(*devices[devnum].plugin)->QueryInterface
(devices[devnum].plugin,
CFUUIDGetUUIDBytes ( kIOATASMARTInterfaceID),
(LPVOID) &devices[devnum].smartIf);
(void **)&devices[devnum].smartIf);
}
return devnum;
@ -275,7 +300,7 @@ int deviceclose(int fd){
return 0;
}
// Interface to ATA devices. See os_linux.c for the cannonical example.
// 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
@ -301,10 +326,6 @@ int deviceclose(int fd){
// have a buggy library that treats the boolean value in
// SMARTEnableDisableOperations, SMARTEnableDisableAutosave, and
// SMARTExecuteOffLineImmediate as always being true.
int marvell_command_interface(int fd, smart_command_set command,
int select, char *data)
{ return -1; }
int
ata_command_interface(int fd, smart_command_set command,
int select, char *data)
@ -312,72 +333,83 @@ ata_command_interface(int fd, smart_command_set command,
IOATASMARTInterface **ifp = devices[fd].smartIf;
IOATASMARTInterface *smartIf;
IOReturn err;
int timeoutCount = 2;
if (! ifp)
return -1;
smartIf = *ifp;
switch (command)
{
case STATUS:
return 0;
case STATUS_CHECK:
do {
switch (command)
{
Boolean is_failing;
err = smartIf->SMARTReturnStatus (ifp, &is_failing);
if (err == kIOReturnSuccess && is_failing)
return 1;
break;
}
case ENABLE:
case DISABLE:
err = smartIf->SMARTEnableDisableOperations (ifp, command == ENABLE);
break;
case AUTOSAVE:
err = smartIf->SMARTEnableDisableAutosave (ifp, select != 0);
break;
case IMMEDIATE_OFFLINE:
if (select != SHORT_SELF_TEST && select != EXTEND_SELF_TEST)
case STATUS:
return 0;
case STATUS_CHECK:
{
errno = EINVAL;
return -1;
Boolean is_failing;
err = smartIf->SMARTReturnStatus (ifp, &is_failing);
if (err == kIOReturnSuccess && is_failing)
return 1;
break;
}
err = smartIf->SMARTExecuteOffLineImmediate (ifp,
select == EXTEND_SELF_TEST);
break;
case READ_VALUES:
err = smartIf->SMARTReadData (ifp, (ATASMARTData *)data);
break;
case READ_THRESHOLDS:
err = smartIf->SMARTReadDataThresholds (ifp,
(ATASMARTDataThresholds *)data);
break;
case READ_LOG:
err = smartIf->SMARTReadLogAtAddress (ifp, select, data, 512);
break;
case WRITE_LOG:
err = smartIf->SMARTWriteLogAtAddress (ifp, select, data, 512);
break;
case IDENTIFY:
{
UInt32 dummy;
err = smartIf->GetATAIdentifyData (ifp, data, 512, &dummy);
if (err == kIOReturnSuccess && isbigendian())
case ENABLE:
case DISABLE:
err = smartIf->SMARTEnableDisableOperations (ifp, command == ENABLE);
break;
case AUTOSAVE:
err = smartIf->SMARTEnableDisableAutosave (ifp, select != 0);
break;
case IMMEDIATE_OFFLINE:
if (select != SHORT_SELF_TEST && select != EXTEND_SELF_TEST)
{
int i;
/* The system has already byte-swapped, undo it. */
for (i = 0; i < 256; i+=2)
swap2 (data + i);
errno = EINVAL;
return -1;
}
err = smartIf->SMARTExecuteOffLineImmediate (ifp,
select == EXTEND_SELF_TEST);
break;
case READ_VALUES:
err = smartIf->SMARTReadData (ifp, (ATASMARTData *)data);
break;
case READ_THRESHOLDS:
err = smartIf->SMARTReadDataThresholds (ifp,
(ATASMARTDataThresholds *)data);
break;
case READ_LOG:
err = smartIf->SMARTReadLogAtAddress (ifp, select, data, 512);
break;
case WRITE_LOG:
err = smartIf->SMARTWriteLogAtAddress (ifp, select, data, 512);
break;
case IDENTIFY:
{
UInt32 dummy;
err = smartIf->GetATAIdentifyData (ifp, data, 512, &dummy);
if (err != kIOReturnSuccess)
printf ("identify failed: %d\n", (int) err);
if (err == kIOReturnSuccess && isbigendian())
{
int i;
/* The system has already byte-swapped, undo it. */
for (i = 0; i < 256; i+=2)
swap2 (data + i);
}
}
break;
case CHECK_POWER_MODE:
// The information is right there in the device registry, but how
// to get to it portably?
default:
errno = ENOTSUP;
return -1;
}
break;
case CHECK_POWER_MODE:
// The information is right there in the device registry, but how
// to get to it portably?
default:
errno = ENOTSUP;
return -1;
}
/* This bit is a bit strange. Apparently, when the drive is spun
down, the intended behaviour of these calls is that they fail,
return kIOReturnTimeout and then power the drive up. So if
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 == kIOReturnExclusiveAccess)
errno = EBUSY;
return err == kIOReturnSuccess ? 0 : -1;
@ -398,7 +430,29 @@ int escalade_command_interface(int fd, int escalade_port, int escalade_type,
return -1;
}
int marvell_command_interface(int fd, smart_command_set command,
int select, char *data)
{
fd = fd;
command = command;
select = select;
data = data;
return -1;
}
int highpoint_command_interface(int fd, smart_command_set command, int select, char *data)
{
fd = fd;
command = command;
select = select;
data = data;
return -1;
}
// Interface to SCSI devices. See os_linux.c
int do_scsi_cmnd_io(int fd, struct scsi_cmnd_io * iop, int report) {
fd = fd;
iop = iop;
report = report;
return -ENOSYS;
}

View File

@ -38,9 +38,9 @@
#include "utility.h"
#include "os_freebsd.h"
static const char *filenameandversion="$Id: os_freebsd.c,v 1.49 2006/04/12 14:54:28 ballen4705 Exp $";
static const char *filenameandversion="$Id: os_freebsd.cpp,v 1.51 2006/09/17 03:17:53 dpgilbert Exp $";
const char *os_XXXX_c_cvsid="$Id: os_freebsd.c,v 1.49 2006/04/12 14:54:28 ballen4705 Exp $" \
const char *os_XXXX_c_cvsid="$Id: os_freebsd.cpp,v 1.51 2006/09/17 03:17:53 dpgilbert 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
@ -101,7 +101,7 @@ int deviceopen (const char* dev, char* mode __unused) {
return -1;
}
fdchan = calloc(1,sizeof(struct freebsd_dev_channel));
fdchan = (struct freebsd_dev_channel *)calloc(1,sizeof(struct freebsd_dev_channel));
if (fdchan == NULL) {
// errno already set by call to malloc()
return -1;
@ -254,6 +254,11 @@ int marvell_command_interface(int fd __unused, smart_command_set command __unuse
return -1;
}
int highpoint_command_interface(int fd __unused, smart_command_set command __unused, int select __unused, char *data __unused)
{
return -1;
}
int ata_command_interface(int fd, smart_command_set command, int select, char *data) {
#if !defined(ATAREQUEST) && !defined(IOCATAREQUEST)
// sorry, but without ATAng, we can't do anything here
@ -297,7 +302,7 @@ int ata_command_interface(int fd, smart_command_set command, int select, char *d
request.u.ata.feature=ATA_SMART_READ_VALUES;
request.u.ata.lba=0xc24f<<8;
request.flags=ATA_CMD_READ;
request.data=buff;
request.data=(char *)buff;
request.count=512;
copydata=1;
break;
@ -306,7 +311,7 @@ int ata_command_interface(int fd, smart_command_set command, int select, char *d
request.u.ata.count=1;
request.u.ata.lba=1|(0xc24f<<8);
request.flags=ATA_CMD_READ;
request.data=buff;
request.data=(char *)buff;
request.count=512;
copydata=1;
break;
@ -315,21 +320,21 @@ int ata_command_interface(int fd, smart_command_set command, int select, char *d
request.u.ata.lba=select|(0xc24f<<8);
request.u.ata.count=1;
request.flags=ATA_CMD_READ;
request.data=buff;
request.data=(char *)buff;
request.count=512;
copydata=1;
break;
case IDENTIFY:
request.u.ata.command=ATA_IDENTIFY_DEVICE;
request.flags=ATA_CMD_READ;
request.data=buff;
request.data=(char *)buff;
request.count=512;
copydata=1;
break;
case PIDENTIFY:
request.u.ata.command=ATA_IDENTIFY_PACKET_DEVICE;
request.flags=ATA_CMD_READ;
request.data=buff;
request.data=(char *)buff;
request.count=512;
copydata=1;
break;
@ -954,7 +959,7 @@ static int parse_ata_chan_dev(const char * dev_name, struct freebsd_dev_channel
handlescsi:
if (chan != NULL) {
if (!(chan->devname = calloc(1,DEV_IDLEN+1)))
if (!(chan->devname = (char *)calloc(1,DEV_IDLEN+1)))
return CONTROLLER_UNKNOWN;
if (cam_get_device(dev_name,chan->devname,DEV_IDLEN,&(chan->unitnum)) == -1)
@ -1053,7 +1058,7 @@ int get_dev_names(char*** names, const char* prefix) {
}
globfree(&globbuf);
mp = realloc(mp,n*(sizeof(char*))); // shrink to correct size
mp = (char **)realloc(mp,n*(sizeof(char*))); // shrink to correct size
bytes += (n)*(sizeof(char*)); // and set allocated byte count
*names=mp;
return n;

View File

@ -16,9 +16,18 @@
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* PORTING NOTES AND COMMENTS
To port smartmontools to the OS of your choice, please:
/*
NOTE: The code in this file is only called when smartmontools has
been compiled on an unrecognized/unsupported platform. This file
can then serve as a "template" to make os_myOS.cpp if you wish to
build support for that platform.
PORTING NOTES AND COMMENTS
--------------------------
To port smartmontools to the OS of your choice, please:
[0] Contact smartmontools-support@lists.sourceforge.net to check
that it's not already been done.
@ -70,7 +79,7 @@
// 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_generic.c,v 1.21 2006/04/12 14:54:28 ballen4705 Exp $" \
const char *os_XXXX_c_cvsid="$Id: os_generic.cpp,v 1.24 2006/09/20 16:17:31 shattered Exp $" \
ATACMDS_H_CVSID CONFIG_H_CVSID INT64_H_CVSID OS_GENERIC_H_CVSID SCSICMDS_H_CVSID UTILITY_H_CVSID;
@ -110,7 +119,7 @@ static void unsupported(){
pout("\n"
"############################################################################\n"
"WARNING: smartmontools has not been ported to the %s Operating System.\n"
"Please see the files os_generic.c and os_generic.h for porting instructions.\n"
"Please see the files os_generic.cpp and os_generic.h for porting instructions.\n"
"############################################################################\n\n",
osname);
debugmode=savedebugmode;
@ -176,7 +185,7 @@ int make_device_names (char*** devlist, const char* name) {
// 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.c for an example). If you
// 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){
@ -194,7 +203,7 @@ int deviceclose(int fd){
return 0;
}
// Interface to ATA devices. See os_linux.c for the cannonical example.
// 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
@ -227,6 +236,17 @@ int marvell_command_interface(int fd, smart_command_set command, int select, cha
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

View File

@ -61,6 +61,8 @@
#include "config.h"
#include "int64.h"
#include "atacmds.h"
#include "extern.h"
extern smartmonctrl * con;
#include "os_linux.h"
#include "scsicmds.h"
#include "utility.h"
@ -72,9 +74,9 @@ typedef unsigned long long u8;
#define ARGUSED(x) ((void)(x))
static const char *filenameandversion="$Id: os_linux.c,v 1.82 2006/04/12 16:28:56 ballen4705 Exp $";
static const char *filenameandversion="$Id: os_linux.cpp,v 1.86 2006/09/12 01:16:54 sxzzsf Exp $";
const char *os_XXXX_c_cvsid="$Id: os_linux.c,v 1.82 2006/04/12 16:28:56 ballen4705 Exp $" \
const char *os_XXXX_c_cvsid="$Id: os_linux.cpp,v 1.86 2006/09/12 01:16:54 sxzzsf 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
@ -125,34 +127,34 @@ int setup_3ware_nodes(char *nodename, char *driver_name) {
/* Now check if nodes are correct */
for (index=0; index<16; index++) {
sprintf(nodestring, "/dev/%s%d", nodename, index);
/* Try to stat the node */
if ((stat(nodestring, &stat_buf))) {
/* Create a new node if it doesn't exist */
if (mknod(nodestring, S_IFCHR|0600, makedev(tw_major, index))) {
pout("problem creating 3ware device nodes %s", nodestring);
syserror("mknod");
return 3;
pout("problem creating 3ware device nodes %s", nodestring);
syserror("mknod");
return 3;
}
}
/* See if nodes major and minor numbers are correct */
if ((tw_major != (int)(major(stat_buf.st_rdev))) ||
(index != (int)(minor(stat_buf.st_rdev))) ||
(!S_ISCHR(stat_buf.st_mode))) {
(index != (int)(minor(stat_buf.st_rdev))) ||
(!S_ISCHR(stat_buf.st_mode))) {
/* Delete the old node */
if (unlink(nodestring)) {
pout("problem unlinking stale 3ware device node %s", nodestring);
syserror("unlink");
return 4;
pout("problem unlinking stale 3ware device node %s", nodestring);
syserror("unlink");
return 4;
}
/* Make a new node */
if (mknod(nodestring, S_IFCHR|0600, makedev(tw_major, index))) {
pout("problem creating 3ware device nodes %s", nodestring);
syserror("mknod");
return 5;
pout("problem creating 3ware device nodes %s", nodestring);
syserror("mknod");
return 5;
}
}
}
@ -175,7 +177,7 @@ int deviceopen(const char *pathname, char *type){
// numbers and if not, create them
if (setup_3ware_nodes("twa", "3w-9xxx")) {
if (!errno)
errno=ENXIO;
errno=ENXIO;
return -1;
}
return open(pathname, O_RDONLY | O_NONBLOCK);
@ -186,7 +188,7 @@ int deviceopen(const char *pathname, char *type){
// numbers and if not, create them
if (setup_3ware_nodes("twe", "3w-xxxx")) {
if (!errno)
errno=ENXIO;
errno=ENXIO;
return -1;
}
return open(pathname, O_RDONLY | O_NONBLOCK);
@ -215,6 +217,9 @@ void print_smartctl_examples(){
" smartctl --all --device=3ware,2 /dev/twe0\n"
" smartctl --all --device=3ware,2 /dev/twa0\n"
" (Prints all SMART info for 3rd ATA disk on 3ware RAID controller)\n"
" smartctl --all --device=hpt,1/1/3 /dev/sda\n"
" (Prints all SMART info for the SATA disk attached to the 3rd PMPort\n"
" of the 1st channel on the 1st HighPoint RAID controller)\n"
);
#else
printf(
@ -227,6 +232,9 @@ void print_smartctl_examples(){
" smartctl -a -d 3ware,2 /dev/twa0\n"
" smartctl -a -d 3ware,2 /dev/twe0\n"
" (Prints all SMART info for 3rd ATA disk on 3ware RAID controller)\n"
" smartctl -a -d hpt,1/1/3 /dev/sda\n"
" (Prints all SMART info for the SATA disk attached to the 3rd PMPort\n"
" of the 1st channel on the 1st HighPoint RAID controller)\n"
);
#endif
return;
@ -315,7 +323,7 @@ int get_dev_names(char*** names, const char* pattern, const char* name, int max)
// this case, we check that the link to the directory is of
// the correct type, and then append "disc" to it.
char tmpname[1024]={0};
char *type=strcmp(name,"ATA")?"scsi":"ide";
const char * type = (strcmp(name,"ATA") ? "scsi" : "ide");
if (strstr(linkbuf, type)){
snprintf(tmpname, 1024, "%s/disc", globbuf.gl_pathv[i]);
mp[n++] = CustomStrDup(tmpname, 1, __LINE__, filenameandversion);
@ -326,7 +334,7 @@ int get_dev_names(char*** names, const char* pattern, const char* name, int max)
// free memory, track memory usage
globfree(&globbuf);
mp = realloc(mp,n*(sizeof(char*)));
mp = static_cast<char **>(realloc(mp,n*(sizeof(char*))));
bytes += n*(sizeof(char*));
// and set up return values
@ -509,7 +517,7 @@ int ata_command_interface(int device, smart_command_set command, int select, cha
if ((retval=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");
pout("Kernel lacks HDIO_DRIVE_TASKFILE support; compile kernel with CONFIG_IDE_TASKFILE_IO set\n");
return -1;
}
return 0;
@ -537,11 +545,11 @@ int ata_command_interface(int device, smart_command_set command, int select, cha
if ((retval=ioctl(device, HDIO_DRIVE_TASK, buff))) {
if (retval==-EINVAL) {
pout("Error SMART Status command via HDIO_DRIVE_TASK failed");
pout("Rebuild older linux 2.2 kernels with HDIO_DRIVE_TASK support added\n");
pout("Error SMART Status command via HDIO_DRIVE_TASK failed");
pout("Rebuild older linux 2.2 kernels with HDIO_DRIVE_TASK support added\n");
}
else
syserror("Error SMART Status command failed");
syserror("Error SMART Status command failed");
return -1;
}
@ -644,7 +652,7 @@ int ata_command_interface(int device, smart_command_set command, int select, cha
#define SG_IO_PRESENT_NO 2
static int sg_io_cmnd_io(int dev_fd, struct scsi_cmnd_io * iop, int report,
int unknown);
int unknown);
static int sisc_cmnd_io(int dev_fd, struct scsi_cmnd_io * iop, int report);
static int sg_io_state = SG_IO_PRESENT_UNKNOWN;
@ -654,7 +662,7 @@ static int sg_io_state = SG_IO_PRESENT_UNKNOWN;
* (various status values should still be checked). If the SCSI command
* cannot be issued then a negative errno value is returned. */
static int sg_io_cmnd_io(int dev_fd, struct scsi_cmnd_io * iop, int report,
int unknown)
int unknown)
{
#ifndef SG_IO
ARGUSED(dev_fd); ARGUSED(iop); ARGUSED(report);
@ -681,7 +689,7 @@ static int sg_io_cmnd_io(int dev_fd, struct scsi_cmnd_io * iop, int report,
"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);
(trunc ? 256 : iop->dxfer_len) , 1);
}
else
j += snprintf(&buff[j], (sz > j ? (sz - j) : 0), "]\n");
@ -718,14 +726,14 @@ static int sg_io_cmnd_io(int dev_fd, struct scsi_cmnd_io * iop, int report,
if (ioctl(dev_fd, SG_IO, &io_hdr) < 0) {
if (report && (! unknown))
pout(" SG_IO ioctl failed, errno=%d [%s]\n", errno,
strerror(errno));
strerror(errno));
return -errno;
}
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,
io_hdr.host_status, io_hdr.driver_status, io_hdr.info,
io_hdr.duration);
" info=0x%x duration=%d milliseconds\n", io_hdr.status,
io_hdr.host_status, io_hdr.driver_status, io_hdr.info,
io_hdr.duration);
if (report > 1) {
if (DXFER_FROM_DEVICE == iop->dxfer_dir) {
int trunc = (iop->dxfer_len > 256) ? 1 : 0;
@ -733,7 +741,7 @@ static int sg_io_cmnd_io(int dev_fd, struct scsi_cmnd_io * iop, int report,
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);
(trunc ? 256 : iop->dxfer_len) , 1);
}
}
}
@ -741,22 +749,22 @@ static int sg_io_cmnd_io(int dev_fd, struct scsi_cmnd_io * iop, int report,
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);
int masked_driver_status = (LSCSI_DRIVER_MASK & io_hdr.driver_status);
if (0 != io_hdr.host_status) {
if (0 != io_hdr.host_status) {
if ((LSCSI_DID_NO_CONNECT == io_hdr.host_status) ||
(LSCSI_DID_BUS_BUSY == io_hdr.host_status) ||
(LSCSI_DID_TIME_OUT == io_hdr.host_status))
return -ETIMEDOUT;
else
return -EIO; /* catch all */
else
return -EIO; /* catch all */
}
if (0 != masked_driver_status) {
if (LSCSI_DRIVER_TIMEOUT == masked_driver_status)
return -ETIMEDOUT;
else if (LSCSI_DRIVER_SENSE != masked_driver_status)
return -EIO;
}
else if (LSCSI_DRIVER_SENSE != masked_driver_status)
return -EIO;
}
if (LSCSI_DRIVER_SENSE == masked_driver_status)
iop->scsi_status = SCSI_STATUS_CHECK_CONDITION;
iop->resp_sense_len = io_hdr.sb_len_wr;
@ -764,15 +772,20 @@ static int sg_io_cmnd_io(int dev_fd, struct scsi_cmnd_io * iop, int report,
iop->sensep && (iop->resp_sense_len > 0)) {
if (report > 1) {
pout(" >>> Sense buffer, len=%d:\n",
(int)iop->resp_sense_len);
(int)iop->resp_sense_len);
dStrHex((const char *)iop->sensep, iop->resp_sense_len , 1);
}
}
if (report) {
if (SCSI_STATUS_CHECK_CONDITION == iop->scsi_status) {
pout(" status=%x: sense_key=%x asc=%x ascq=%x\n",
iop->scsi_status, iop->sensep[2] & 0xf, iop->sensep[12],
iop->sensep[13]);
if ((iop->sensep[0] & 0x7f) > 0x71)
pout(" status=%x: [desc] sense_key=%x asc=%x ascq=%x\n",
iop->scsi_status, iop->sensep[1] & 0xf,
iop->sensep[2], iop->sensep[3]);
else
pout(" status=%x: sense_key=%x asc=%x ascq=%x\n",
iop->scsi_status, iop->sensep[2] & 0xf,
iop->sensep[12], iop->sensep[13]);
}
else
pout(" status=0x%x\n", iop->scsi_status);
@ -820,7 +833,7 @@ static int sisc_cmnd_io(int dev_fd, struct scsi_cmnd_io * iop, int report)
"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);
(trunc ? 256 : iop->dxfer_len) , 1);
}
else
j += snprintf(&buff[j], (sz > j ? (sz - j) : 0), "]\n");
@ -869,7 +882,7 @@ static int sisc_cmnd_io(int dev_fd, struct scsi_cmnd_io * iop, int report)
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);
(trunc ? 256 : iop->dxfer_len) , 1);
}
}
return 0;
@ -925,21 +938,21 @@ int do_scsi_cmnd_io(int dev_fd, struct scsi_cmnd_io * iop, int report)
switch (sg_io_state) {
case SG_IO_PRESENT_UNKNOWN:
/* ignore report argument */
if (0 == (res = sg_io_cmnd_io(dev_fd, iop, report, 1))) {
sg_io_state = SG_IO_PRESENT_YES;
return 0;
} else if ((-ENODEV == res) || (-EACCES == res) || (-EPERM == res))
return res; /* wait until we see a device */
if (0 == (res = sg_io_cmnd_io(dev_fd, iop, report, 1))) {
sg_io_state = SG_IO_PRESENT_YES;
return 0;
} else if ((-ENODEV == res) || (-EACCES == res) || (-EPERM == res))
return res; /* wait until we see a device */
sg_io_state = SG_IO_PRESENT_NO;
/* drop through by design */
/* drop through by design */
case SG_IO_PRESENT_NO:
return sisc_cmnd_io(dev_fd, iop, report);
return sisc_cmnd_io(dev_fd, iop, report);
case SG_IO_PRESENT_YES:
return sg_io_cmnd_io(dev_fd, iop, report, 0);
return sg_io_cmnd_io(dev_fd, iop, report, 0);
default:
pout(">>>> do_scsi_cmnd_io: bad sg_io_state=%d\n", sg_io_state);
sg_io_state = SG_IO_PRESENT_UNKNOWN;
return -EIO; /* report error and reset state */
pout(">>>> do_scsi_cmnd_io: bad sg_io_state=%d\n", sg_io_state);
sg_io_state = SG_IO_PRESENT_UNKNOWN;
return -EIO; /* report error and reset state */
}
}
@ -1397,6 +1410,210 @@ int marvell_command_interface(int device,
return 0;
}
// this implementation is derived from ata_command_interface with a header
// packing for highpoint linux driver ioctl interface
//
// ioctl(fd,HPTIO_CTL,buff)
// ^^^^^^^^^
//
// structure of hpt_buff
// +----+----+----+----+--------------------.....---------------------+
// | 1 | 2 | 3 | 4 | 5 |
// +----+----+----+----+--------------------.....---------------------+
//
// 1: The target controller [ int ( 4 Bytes ) ]
// 2: The channel of the target controllee [ int ( 4 Bytes ) ]
// 3: HDIO_ ioctl call [ int ( 4 Bytes ) ]
// available from ${LINUX_KERNEL_SOURCE}/Documentation/ioctl/hdio
// 4: the pmport that disk attached, [ int ( 4 Bytes ) ]
// if no pmport device, set to 1 or leave blank
// 5: data [ void * ( var leangth ) ]
//
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;
unsigned char *buff = &hpt_buff[4*sizeof(int)];
int copydata = 0;
const int HDIO_DRIVE_CMD_OFFSET = 4;
memset(hpt_buff, 0, 4*sizeof(int) + STRANGE_BUFFER_LENGTH);
hpt[0] = con->hpt_data[0]; // controller id
hpt[1] = con->hpt_data[1]; // channel number
hpt[3] = con->hpt_data[2]; // pmport number
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:
buff[2]=ATA_SMART_STATUS;
break;
case AUTO_OFFLINE:
buff[2]=ATA_SMART_AUTO_OFFLINE;
buff[3]=select;
break;
case AUTOSAVE:
buff[2]=ATA_SMART_AUTOSAVE;
buff[3]=select;
break;
case IMMEDIATE_OFFLINE:
buff[2]=ATA_SMART_IMMEDIATE_OFFLINE;
buff[1]=select;
break;
case STATUS_CHECK:
buff[1]=ATA_SMART_STATUS;
break;
default:
pout("Unrecognized command %d in linux_highpoint_command_interface()\n"
"Please contact " PACKAGE_BUGREPORT "\n", command);
errno=ENOSYS;
return -1;
}
if (command==WRITE_LOG) {
unsigned char task[4*sizeof(int)+sizeof(ide_task_request_t)+512];
unsigned int *hpt = (unsigned int *)task;
ide_task_request_t *reqtask = (ide_task_request_t *)(&task[4*sizeof(int)]);
task_struct_t *taskfile = (task_struct_t *)reqtask->io_ports;
int retval;
memset(task, 0, sizeof(task));
hpt[0] = con->hpt_data[0]; // controller id
hpt[1] = con->hpt_data[1]; // channel number
hpt[3] = con->hpt_data[2]; // pmport number
hpt[2] = HDIO_DRIVE_TASKFILE; // real hd ioctl
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;
memcpy(task+sizeof(ide_task_request_t)+4*sizeof(int), data, 512);
if ((retval=ioctl(device, HPTIO_CTL, task))) {
if (retval==-EINVAL)
pout("Kernel lacks HDIO_DRIVE_TASKFILE support; compile kernel with CONFIG_IDE_TASKFILE_IO set\n");
return -1;
}
return 0;
}
if (command==STATUS_CHECK){
int retval;
unsigned const char normal_lo=0x4f, normal_hi=0xc2;
unsigned const char failed_lo=0xf4, failed_hi=0x2c;
buff[4]=normal_lo;
buff[5]=normal_hi;
hpt[2] = HDIO_DRIVE_TASK;
if ((retval=ioctl(device, HPTIO_CTL, hpt_buff))) {
if (retval==-EINVAL) {
pout("Error SMART Status command via HDIO_DRIVE_TASK failed");
pout("Rebuild older linux 2.2 kernels with HDIO_DRIVE_TASK support added\n");
}
else
syserror("Error SMART Status command failed");
return -1;
}
if (buff[4]==normal_lo && buff[5]==normal_hi)
return 0;
if (buff[4]==failed_lo && buff[5]==failed_hi)
return 1;
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("NS =0x%02x\n",(int)buff[2]);
pout("SC =0x%02x\n",(int)buff[3]);
pout("CL =0x%02x\n",(int)buff[4]);
pout("CH =0x%02x\n",(int)buff[5]);
pout("SEL=0x%02x\n",(int)buff[6]);
return -1;
}
#if 1
if (command==IDENTIFY || command==PIDENTIFY) {
unsigned char deviceid[4*sizeof(int)+512*sizeof(char)];
unsigned int *hpt = (unsigned int *)deviceid;
hpt[0] = con->hpt_data[0]; // controller id
hpt[1] = con->hpt_data[1]; // channel number
hpt[3] = con->hpt_data[2]; // pmport number
hpt[2] = HDIO_GET_IDENTITY;
if (!ioctl(device, HPTIO_CTL, deviceid) && (deviceid[4*sizeof(int)] & 0x8000))
buff[0]=(command==IDENTIFY)?ATA_IDENTIFY_PACKET_DEVICE:ATA_IDENTIFY_DEVICE;
}
#endif
hpt[2] = HDIO_DRIVE_CMD;
if ((ioctl(device, HPTIO_CTL, hpt_buff)))
return -1;
if (command==CHECK_POWER_MODE)
buff[HDIO_DRIVE_CMD_OFFSET]=buff[2];
if (copydata)
memcpy(data, buff+HDIO_DRIVE_CMD_OFFSET, copydata);
return 0;
}
// Utility function for printing warnings
void printwarning(smart_command_set command){

View File

@ -9,7 +9,7 @@
*
* Written By: Adam Radford <linux@3ware.com>
* Modifications By: Joel Jacobson <linux@3ware.com>
* Arnaldo Carvalho de Melo <acme@conectiva.com.br>
* Arnaldo Carvalho de Melo <acme@conectiva.com.br>
* Brad Strand <linux@3ware.com>
*
* Copyright (C) 1999-2003 3ware Inc.
@ -38,7 +38,7 @@
#ifndef OS_LINUX_H_
#define OS_LINUX_H_
#define OS_LINUX_H_CVSID "$Id: os_linux.h,v 1.24 2006/04/12 14:54:28 ballen4705 Exp $\n"
#define OS_LINUX_H_CVSID "$Id: os_linux.h,v 1.25 2006/08/25 06:06:25 sxzzsf Exp $\n"
/*
The following definitions/macros/prototypes are used for three
@ -387,4 +387,6 @@ typedef struct ide_task_request_s {
#define HDIO_DRIVE_TASKFILE 0x031d
#define HDIO_GET_IDENTITY 0x030d
#define HPTIO_CTL 0x03ff // ioctl interface for HighPoint raid device
#endif /* OS_LINUX_H_ */

View File

@ -1,5 +1,5 @@
/*
* os_netbsd.c
* os_netbsd.cpp
*
* Home page of code is: http://smartmontools.sourceforge.net
*
@ -24,7 +24,7 @@
#include "os_netbsd.h"
#include <unistd.h>
const char *os_XXXX_c_cvsid = "$Id: os_netbsd.c,v 1.15 2006/04/12 14:54:28 ballen4705 Exp $" \
const char *os_XXXX_c_cvsid = "$Id: os_netbsd.cpp,v 1.19 2006/09/20 16:17:31 shattered Exp $" \
ATACMDS_H_CVSID CONFIG_H_CVSID INT64_H_CVSID OS_NETBSD_H_CVSID SCSICMDS_H_CVSID UTILITY_H_CVSID;
/* global variable holding byte count of allocated memory */
@ -104,7 +104,7 @@ get_dev_names(char ***names, const char *prefix)
pout("Failed to get value of sysctl `hw.disknames'\n");
return -1;
}
if (!(disknames = malloc(sysctl_len))) {
if (!(disknames = (char *)malloc(sysctl_len))) {
pout("Out of memory constructing scan device list\n");
return -1;
}
@ -120,7 +120,7 @@ get_dev_names(char ***names, const char *prefix)
if (strncmp(p, prefix, strlen(prefix))) {
continue;
}
mp[n] = 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;
@ -130,7 +130,7 @@ get_dev_names(char ***names, const char *prefix)
n++;
}
mp = realloc(mp, n * (sizeof(char *)));
mp = (char **)realloc(mp, n * (sizeof(char *)));
bytes += (n) * (sizeof(char *));
*names = mp;
return n;
@ -171,6 +171,11 @@ int
marvell_command_interface(int fd, smart_command_set command, int select, char *data)
{ return -1; }
int highpoint_command_interface(int fd, smart_command_set command, int select, char *data)
{
return -1;
}
int
ata_command_interface(int fd, smart_command_set command, int select, char *data)
{
@ -186,7 +191,7 @@ ata_command_interface(int fd, smart_command_set command, int select, char *data)
req.flags = ATACMD_READ;
req.features = WDSM_RD_DATA;
req.command = WDCC_SMART;
req.databuf = inbuf;
req.databuf = (char *)inbuf;
req.datalen = sizeof(inbuf);
req.cylinder = WDSMART_CYL;
req.timeout = 1000;
@ -196,7 +201,7 @@ ata_command_interface(int fd, smart_command_set command, int select, char *data)
req.flags = ATACMD_READ;
req.features = WDSM_RD_THRESHOLDS;
req.command = WDCC_SMART;
req.databuf = inbuf;
req.databuf = (char *)inbuf;
req.datalen = sizeof(inbuf);
req.cylinder = WDSMART_CYL;
req.timeout = 1000;
@ -206,7 +211,7 @@ ata_command_interface(int fd, smart_command_set command, int select, char *data)
req.flags = ATACMD_READ;
req.features = ATA_SMART_READ_LOG_SECTOR; /* XXX missing from wdcreg.h */
req.command = WDCC_SMART;
req.databuf = inbuf;
req.databuf = (char *)inbuf;
req.datalen = sizeof(inbuf);
req.cylinder = WDSMART_CYL;
req.sec_num = select;
@ -219,7 +224,7 @@ ata_command_interface(int fd, smart_command_set command, int select, char *data)
req.flags = ATACMD_WRITE;
req.features = ATA_SMART_WRITE_LOG_SECTOR; /* XXX missing from wdcreg.h */
req.command = WDCC_SMART;
req.databuf = inbuf;
req.databuf = (char *)inbuf;
req.datalen = sizeof(inbuf);
req.cylinder = WDSMART_CYL;
req.sec_num = select;
@ -229,7 +234,7 @@ ata_command_interface(int fd, smart_command_set command, int select, char *data)
case IDENTIFY:
req.flags = ATACMD_READ;
req.command = WDCC_IDENTIFY;
req.databuf = (caddr_t) inbuf;
req.databuf = (char *)inbuf;
req.datalen = sizeof(inbuf);
req.timeout = 1000;
copydata = 1;
@ -237,7 +242,7 @@ ata_command_interface(int fd, smart_command_set command, int select, char *data)
case PIDENTIFY:
req.flags = ATACMD_READ;
req.command = ATAPI_IDENTIFY_DEVICE;
req.databuf = (caddr_t) inbuf;
req.databuf = (char *)inbuf;
req.datalen = sizeof(inbuf);
req.timeout = 1000;
copydata = 1;
@ -261,7 +266,7 @@ ata_command_interface(int fd, smart_command_set command, int select, char *data)
req.flags = ATACMD_READ;
req.features = ATA_SMART_AUTO_OFFLINE; /* XXX missing from wdcreg.h */
req.command = WDCC_SMART;
req.databuf = inbuf;
req.databuf = (char *)inbuf;
req.datalen = sizeof(inbuf);
req.cylinder = WDSMART_CYL;
req.sec_num = select;
@ -282,7 +287,7 @@ ata_command_interface(int fd, smart_command_set command, int select, char *data)
req.flags = ATACMD_READ;
req.features = ATA_SMART_IMMEDIATE_OFFLINE; /* XXX missing from wdcreg.h */
req.command = WDCC_SMART;
req.databuf = inbuf;
req.databuf = (char *)inbuf;
req.datalen = sizeof(inbuf);
req.cylinder = WDSMART_CYL;
req.sec_num = select;
@ -384,12 +389,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 = iop->dxferp;
sc.databuf = (char *)iop->dxferp;
sc.datalen = iop->dxfer_len;
sc.senselen = iop->max_sense_len;
sc.timeout = iop->timeout == 0 ? 60000 : (1000 * iop->timeout);
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) {

View File

@ -5,7 +5,7 @@
*
* Copyright (C) 2004-6 David Snyder <smartmontools-support@lists.sourceforge.net>
*
* Derived from os_netbsd.c by Sergey Svishchev <smartmontools-support@lists.sourceforge.net>, Copyright (C) 2003-6
* Derived from os_netbsd.cpp by Sergey Svishchev <smartmontools-support@lists.sourceforge.net>, Copyright (C) 2003-6
*
* 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
@ -25,7 +25,7 @@
#include "utility.h"
#include "os_openbsd.h"
const char *os_XXXX_c_cvsid = "$Id: os_openbsd.c,v 1.10 2006/04/12 14:54:28 ballen4705 Exp $" \
const char *os_XXXX_c_cvsid = "$Id: os_openbsd.cpp,v 1.13 2006/09/20 16:17:31 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 = 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] = 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 = realloc(mp, n * (sizeof(char *)));
mp = (char**)realloc(mp, n * (sizeof(char *)));
bytes += (n) * (sizeof(char *));
*names = mp;
return n;
@ -172,6 +172,11 @@ int
marvell_command_interface(int fd, smart_command_set command, int select, char *data)
{ return -1; }
int highpoint_command_interface(int fd, smart_command_set command, int select, char *data)
{
return -1;
}
int
ata_command_interface(int fd, smart_command_set command, int select, char *data)
{
@ -385,7 +390,7 @@ 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 = 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 */

View File

@ -26,7 +26,7 @@
#ifndef OS_OPENBSD_H_
#define OS_OPENBSD_H_
#define OS_OPENBSD_H_CVSID "$Id: os_openbsd.h,v 1.4 2006/04/12 14:54:28 ballen4705 Exp $\n"
#define OS_OPENBSD_H_CVSID "$Id: os_openbsd.h,v 1.5 2006/09/19 07:22:09 snyderx Exp $\n"
/* from NetBSD: atareg.h,v 1.17, by Manuel Bouyer */
/* Actually fits _perfectly_ into OBSDs wdcreg.h, but... */
@ -51,5 +51,6 @@
#include <err.h>
#include <fcntl.h>
#include <util.h>
#include <unistd.h>
#endif /* OS_OPENBSD_H_ */

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 */

View File

@ -39,9 +39,9 @@
extern long long bytes;
static const char *filenameandversion="$Id: os_solaris.c,v 1.26 2006/04/12 14:54:28 ballen4705 Exp $";
static const char *filenameandversion="$Id: os_solaris.cpp,v 1.28 2006/08/25 06:06:25 sxzzsf Exp $";
const char *os_XXXX_c_cvsid="$Id: os_solaris.c,v 1.26 2006/04/12 14:54:28 ballen4705 Exp $" \
const char *os_XXXX_c_cvsid="$Id: os_solaris.cpp,v 1.28 2006/08/25 06:06:25 sxzzsf 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
@ -163,7 +163,7 @@ addpath(const char *path, struct pathlist *res)
{
if (++res->nnames > res->maxnames) {
res->maxnames += 16;
res->names = realloc(res->names, res->maxnames * sizeof (char *));
res->names = static_cast<char**>(realloc(res->names, res->maxnames * sizeof (char *)));
if (res->names == NULL)
return -1;
bytes += 16*sizeof(char *);
@ -247,7 +247,7 @@ int make_device_names (char*** devlist, const char* name) {
}
// shrink array to min possible size
res.names = realloc(res.names, res.nnames * sizeof (char *));
res.names = static_cast<char**>(realloc(res.names, res.nnames * sizeof (char *)));
bytes -= sizeof(char *)*(res.maxnames-res.nnames);
// pass list back
@ -271,15 +271,18 @@ int deviceclose(int fd){
return close(fd);
}
#if defined(__sparc)
// swap each 2-byte pairs in a sector
static void swap_sector(void *p)
{
int i;
unsigned char t, *cp = p;
char t, *cp = static_cast<char*>(p);
for(i = 0; i < 256; i++) {
t = cp[0]; cp[0] = cp[1]; cp[1] = t;
cp += 2;
}
}
#endif
// Interface to ATA devices. See os_linux.c
int marvell_command_interface(int fd, smart_command_set command, int select, char *data){
@ -287,6 +290,12 @@ int marvell_command_interface(int fd, smart_command_set command, int select, cha
return -1;
}
int highpoint_command_interface(int fd, smart_command_set command, int select, char *data)
{
ARGUSED(fd); ARGUSED(command); ARGUSED(select); ARGUSED(data);
return -1;
}
int ata_command_interface(int fd, smart_command_set command, int select, char *data){
#if defined(__sparc)
int err;
@ -304,12 +313,12 @@ int ata_command_interface(int fd, smart_command_set command, int select, char *d
case IDENTIFY:
err = ata_identify(fd, data);
if(err) return err;
swap_sector(data);
swap_sector(static_cast<void*>(data));
return 0;
case PIDENTIFY:
err = ata_pidentify(fd, data);
if(err) return err;
swap_sector(data);
swap_sector(static_cast<void*>(data));
return 0;
case ENABLE:
return smart_enable(fd);
@ -331,9 +340,7 @@ int ata_command_interface(int fd, smart_command_set command, int select, char *d
break;
}
#else /* __sparc */
// avoid gcc warnings//
fd=command=select=0;
data=NULL;
ARGUSED(fd); ARGUSED(command); ARGUSED(select); ARGUSED(data);
/* Above smart_* routines uses undocumented ioctls of "dada"
* driver, which is specific to SPARC Solaris. See
@ -347,9 +354,8 @@ int ata_command_interface(int fd, smart_command_set command, int select, char *d
// Interface to ATA devices behind 3ware escalade RAID controller cards. See os_linux.c
int escalade_command_interface(int fd, int disknum, int escalade_type, smart_command_set command, int select, char *data){
// avoid gcc warnings//
fd=disknum=escalade_type=command=select=0;
data=NULL;
ARGUSED(fd); ARGUSED(disknum); ARGUSED(escalade_type);
ARGUSED(command); ARGUSED(select); ARGUSED(data);
if (printwarning(1))
return -1;
@ -390,15 +396,15 @@ int do_scsi_cmnd_io(int fd, struct scsi_cmnd_io * iop, int report) {
memset(&uscsi, 0, sizeof (uscsi));
uscsi.uscsi_cdb = (void *)iop->cmnd;
uscsi.uscsi_cdb = reinterpret_cast<char*>(iop->cmnd);
uscsi.uscsi_cdblen = iop->cmnd_len;
if (iop->timeout == 0)
uscsi.uscsi_timeout = 60; /* XXX */
else
uscsi.uscsi_timeout = iop->timeout;
uscsi.uscsi_bufaddr = (void *)iop->dxferp;
uscsi.uscsi_bufaddr = reinterpret_cast<char*>(iop->dxferp);
uscsi.uscsi_buflen = iop->dxfer_len;
uscsi.uscsi_rqbuf = (void *)iop->sensep;
uscsi.uscsi_rqbuf = reinterpret_cast<char*>(iop->sensep);
uscsi.uscsi_rqlen = iop->max_sense_len;
switch (iop->dxfer_dir) {

View File

@ -25,7 +25,7 @@
#ifndef OS_SOLARIS_H_
#define OS_SOLARIS_H_
#define OS_SOLARIS_H_CVSID "$Id: os_solaris.h,v 1.12 2006/04/12 14:54:28 ballen4705 Exp $\n"
#define OS_SOLARIS_H_CVSID "$Id: os_solaris.h,v 1.13 2006/08/12 05:41:13 card_captor Exp $\n"
// Additional material should start here. Note: to keep the '-V' CVS
// reporting option working as intended, you should only #include
@ -37,18 +37,20 @@
#include <fcntl.h>
// function prototypes for functions defined in os_solaris_ata.s
int smart_read_data(int fd, void *data);
int smart_read_thresholds(int fd, void *data);
int smart_read_log(int fd, int s, int count, void *data);
int ata_identify(int fd, void *data);
int ata_pidentify(int fd, void *data);
int smart_enable(int fd);
int smart_disable(int fd);
int smart_status(int fd);
int smart_auto_offline(int fd, int s);
int smart_auto_save(int fd, int s);
int smart_immediate_offline(int fd, int s);
int smart_status_check(int fd);
extern "C" {
int smart_read_data(int fd, void *data);
int smart_read_thresholds(int fd, void *data);
int smart_read_log(int fd, int s, int count, void *data);
int ata_identify(int fd, void *data);
int ata_pidentify(int fd, void *data);
int smart_enable(int fd);
int smart_disable(int fd);
int smart_status(int fd);
int smart_auto_offline(int fd, int s);
int smart_auto_save(int fd, int s);
int smart_immediate_offline(int fd, int s);
int smart_status_check(int fd);
}
// wrapper macros
#define smart_enable_auto_save(fd) smart_auto_save(fd, 0xf1)

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,5 @@
/*
* os_win32/daemon_win32.c
* os_win32/daemon_win32.cpp
*
* Home page of code is: http://smartmontools.sourceforge.net
*
@ -31,7 +31,7 @@
#include "daemon_win32.h"
const char *daemon_win32_c_cvsid = "$Id: daemon_win32.c,v 1.10 2006/04/12 14:54:28 ballen4705 Exp $"
const char *daemon_win32_c_cvsid = "$Id: daemon_win32.cpp,v 1.11 2006/08/09 20:40:20 chrfranke Exp $"
DAEMON_WIN32_H_CVSID;
@ -972,7 +972,7 @@ static void WINAPI service_main(DWORD argc, LPSTR * argv)
static int svcadm_setdesc(SC_HANDLE hs, const char * desc)
{
HANDLE hdll;
HINSTANCE hdll;
BOOL (WINAPI * ChangeServiceConfig2A_p)(SC_HANDLE, DWORD, LPVOID);
BOOL ret;
if (!(hdll = LoadLibraryA("ADVAPI32.DLL")))

View File

@ -1,5 +1,5 @@
/*
* os_win32/hostname_win32.c
* os_win32/hostname_win32.cpp
*
* Home page of code is: http://smartmontools.sourceforge.net
*
@ -18,7 +18,7 @@
#include "hostname_win32.h"
const char * hostname_win32_c_cvsid = "$Id: hostname_win32.c,v 1.4 2006/04/12 14:54:28 ballen4705 Exp $" HOSTNAME_WIN32_H_CVSID;
const char * hostname_win32_c_cvsid = "$Id: hostname_win32.cpp,v 1.5 2006/08/09 20:40:20 chrfranke Exp $" HOSTNAME_WIN32_H_CVSID;
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
@ -67,7 +67,7 @@ DWORD WINAPI GetNetworkParams(PFIXED_INFO info, PULONG size);
static BOOL CallGetComputerNameExA(int type, LPSTR name, LPDWORD size)
{
HANDLE hdll;
HINSTANCE hdll;
BOOL (WINAPI * GetComputerNameExA_p)(int/*enum COMPUTER_NAME_FORMAT*/, LPSTR, LPDWORD);
BOOL ret;
if (!(hdll = LoadLibraryA("KERNEL32.DLL")))
@ -85,7 +85,7 @@ static BOOL CallGetComputerNameExA(int type, LPSTR name, LPDWORD size)
static DWORD CallGetNetworkParams(PFIXED_INFO info, PULONG size)
{
HANDLE hdll;
HINSTANCE hdll;
DWORD (WINAPI * GetNetworkParams_p)(PFIXED_INFO, PULONG);
DWORD ret;
if (!(hdll = LoadLibraryA("IPHlpApi.dll")))
@ -111,11 +111,11 @@ static DWORD GetNamesFromRegistry(BOOL domain, char * name, int len)
0, KEY_READ, &hk) != ERROR_SUCCESS)
return 0;
size = len-1;
if (!(RegQueryValueExA(hk, (!domain?"HostName":"Domain"), 0, &type, name, &size) == ERROR_SUCCESS && type == REG_SZ))
if (!(RegQueryValueExA(hk, (!domain?"HostName":"Domain"), 0, &type, (unsigned char *)name, &size) == ERROR_SUCCESS && type == REG_SZ))
size = 0;
if (size == 0 && domain) {
size = len-1;
if (!(RegQueryValueExA(hk, "DhcpDomain", 0, &type, name, &size) == ERROR_SUCCESS && type == REG_SZ))
if (!(RegQueryValueExA(hk, "DhcpDomain", 0, &type, (unsigned char *)name, &size) == ERROR_SUCCESS && type == REG_SZ))
size = 0;
}
RegCloseKey(hk);

View File

@ -19,9 +19,17 @@
#ifndef HOSTNAME_WIN32_H
#define HOSTNAME_WIN32_H
#define HOSTNAME_WIN32_H_CVSID "$Id: hostname_win32.h,v 1.3 2006/04/12 14:54:28 ballen4705 Exp $\n"
#define HOSTNAME_WIN32_H_CVSID "$Id: hostname_win32.h,v 1.4 2006/08/09 20:40:20 chrfranke Exp $\n"
#ifdef __cplusplus
extern "C" {
#endif
int gethostname(char * name, int len);
int getdomainname(char * name, int len);
#ifdef __cplusplus
}
#endif
#endif // HOSTNAME_WIN32_H

466
os_win32/installer.nsi Normal file
View File

@ -0,0 +1,466 @@
;
; installer.nsi - NSIS install script for smartmontools
;
; Copyright (C) 2006 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).
;
; $Id: installer.nsi,v 1.2 2006/07/17 20:51:22 chrfranke Exp $
;
;--------------------------------------------------------------------
; Command line arguments:
; makensis /DINPDIR=<input-dir> /DOUTFILE=<output-file> installer.nsi
!ifndef INPDIR
!define INPDIR "."
!endif
!ifndef OUTFILE
!define OUTFILE "smartmontools.win32-setup.exe"
!endif
;--------------------------------------------------------------------
; General
Name "smartmontools"
OutFile "${OUTFILE}"
SetCompressor /solid lzma
XPStyle on
InstallColors /windows
InstallDir "$PROGRAMFILES\smartmontools"
InstallDirRegKey HKLM "Software\smartmontools" "Install_Dir"
LicenseData "${INPDIR}\doc\COPYING.txt"
;--------------------------------------------------------------------
; Pages
Page license
Page components
Page directory
Page instfiles
UninstPage uninstConfirm
UninstPage instfiles
InstType "Full"
InstType "Extract files only"
;--------------------------------------------------------------------
; Sections
SectionGroup "Program files"
Section "smartctl"
SectionIn 1 2
SetOutPath "$INSTDIR\bin"
File "${INPDIR}\bin\smartctl.exe"
SectionEnd
Section "smartd"
SectionIn 1 2
SetOutPath "$INSTDIR\bin"
File "${INPDIR}\bin\smartd.exe"
IfFileExists "$INSTDIR\bin\smartd.conf" 0 +2
MessageBox MB_YESNO|MB_ICONQUESTION|MB_DEFBUTTON2 "Replace existing configuration file$\n$INSTDIR\bin\smartd.conf ?" IDYES 0 IDNO +2
File "${INPDIR}\doc\smartd.conf"
IfFileExists "$WINDIR\system32\cmd.exe" 0 +2
File /nonfatal "${INPDIR}\bin\syslogevt.exe"
SectionEnd
SectionGroupEnd
Section "Documentation"
SectionIn 1 2
SetOutPath "$INSTDIR\doc"
File "${INPDIR}\doc\AUTHORS.txt"
File "${INPDIR}\doc\CHANGELOG.txt"
File "${INPDIR}\doc\COPYING.txt"
File "${INPDIR}\doc\INSTALL.txt"
File "${INPDIR}\doc\NEWS.txt"
File "${INPDIR}\doc\README.txt"
File "${INPDIR}\doc\TODO.txt"
File "${INPDIR}\doc\WARNINGS.txt"
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"
File "${INPDIR}\doc\smartd.conf.5.html"
File "${INPDIR}\doc\smartd.conf.5.txt"
SectionEnd
Section "Uninstaller"
SectionIn 1
AddSize 35
CreateDirectory "$INSTDIR"
; Save installation location
WriteRegStr HKLM "Software\smartmontools" "Install_Dir" "$INSTDIR"
; Write uninstall keys and program
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\smartmontools" "DisplayName" "smartmontools"
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\smartmontools" "UninstallString" '"$INSTDIR\uninst-smartmontools.exe"'
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"
SectionIn 1
CreateDirectory "$SMPROGRAMS\smartmontools"
; smartctl
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
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"
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"
noctl:
; smartd
IfFileExists "$INSTDIR\bin\smartd.exe" 0 nod
SetOutPath "$INSTDIR\bin"
DetailPrint "Create file: $INSTDIR\bin\smartd-run.bat"
FileOpen $0 "$INSTDIR\bin\smartd-run.bat" "w"
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"
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 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"
IfFileExists "$WINDIR\notepad.exe" 0 nopad
CreateShortCut "$SMPROGRAMS\smartmontools\smartd Examples\Edit smartd.conf.lnk" "$WINDIR\notepad.exe" "$INSTDIR\bin\smartd.conf"
CreateShortCut "$SMPROGRAMS\smartmontools\smartd Examples\View smartd.log.lnk" "$WINDIR\notepad.exe" "$INSTDIR\bin\smartd.log"
nopad:
; 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 remove.lnk" "$INSTDIR\bin\smartd-run.bat" "remove"
DetailPrint "Create file: $INSTDIR\bin\net-run.bat"
FileOpen $0 "$INSTDIR\bin\net-run.bat" "w"
FileWrite $0 "@echo off$\r$\necho net %1 %2 %3 %4 %5$\r$\nnet %1 %2 %3 %4 %5$\r$\npause$\r$\n"
FileClose $0
CreateShortCut "$SMPROGRAMS\smartmontools\smartd Examples\Service start.lnk" "$INSTDIR\bin\net-run.bat" "start smartd"
CreateShortCut "$SMPROGRAMS\smartmontools\smartd Examples\Service stop.lnk" "$INSTDIR\bin\net-run.bat" "stop smartd"
nosvc:
nod:
; Documentation
IfFileExists "$INSTDIR\doc\README.TXT" 0 nodoc
SetOutPath "$INSTDIR\doc"
CreateDirectory "$SMPROGRAMS\smartmontools\Documentation"
CreateShortCut "$SMPROGRAMS\smartmontools\Documentation\smartctl manual page (html).lnk" "$INSTDIR\doc\smartctl.8.html"
CreateShortCut "$SMPROGRAMS\smartmontools\Documentation\smartd manual page (html).lnk" "$INSTDIR\doc\smartd.8.html"
CreateShortCut "$SMPROGRAMS\smartmontools\Documentation\smartd.conf manual page (html).lnk" "$INSTDIR\doc\smartd.conf.5.html"
CreateShortCut "$SMPROGRAMS\smartmontools\Documentation\smartctl manual page (txt).lnk" "$INSTDIR\doc\smartctl.8.txt"
CreateShortCut "$SMPROGRAMS\smartmontools\Documentation\smartd manual page (txt).lnk" "$INSTDIR\doc\smartd.8.txt"
CreateShortCut "$SMPROGRAMS\smartmontools\Documentation\smartd.conf manual page (txt).lnk" "$INSTDIR\doc\smartd.conf.5.txt"
IfFileExists "$WINDIR\notepad.exe" 0 +2
CreateShortCut "$SMPROGRAMS\smartmontools\Documentation\smartd.conf sample.lnk" "$WINDIR\notepad.exe" "$INSTDIR\doc\smartd.conf"
CreateShortCut "$SMPROGRAMS\smartmontools\Documentation\AUTHORS.lnk" "$INSTDIR\doc\AUTHORS.txt"
CreateShortCut "$SMPROGRAMS\smartmontools\Documentation\CHANGELOG.lnk" "$INSTDIR\doc\CHANGELOG.txt"
CreateShortCut "$SMPROGRAMS\smartmontools\Documentation\COPYING.lnk" "$INSTDIR\doc\COPYING.txt"
CreateShortCut "$SMPROGRAMS\smartmontools\Documentation\INSTALL.lnk" "$INSTDIR\doc\INSTALL.txt"
CreateShortCut "$SMPROGRAMS\smartmontools\Documentation\NEWS.lnk" "$INSTDIR\doc\NEWS.txt"
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"
nodoc:
; Homepage
CreateShortCut "$SMPROGRAMS\smartmontools\smartmontools Home Page.lnk" "http://smartmontools.sourceforge.net/"
; Uninstall
IfFileExists "$INSTDIR\uninst-smartmontools.exe" 0 +2
CreateShortCut "$SMPROGRAMS\smartmontools\Uninstall smartmontools.lnk" "$INSTDIR\uninst-smartmontools.exe"
SectionEnd
Section "Add install dir to PATH" PATH_IDX
SectionIn 1
IfFileExists "$WINDIR\system32\cmd.exe" 0 +3
Push "$INSTDIR\bin"
Call AddToPath
SectionEnd
;--------------------------------------------------------------------
Section "Uninstall"
; Remove registry keys
DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\smartmontools"
DeleteRegKey HKLM "Software\smartmontools"
IfFileExists "$INSTDIR\bin\smartd.conf" 0 noconf
; Assume unchanged if timestamp is equal to sample file
GetFileTime "$INSTDIR\bin\smartd.conf" $0 $1
GetFileTime "$INSTDIR\doc\smartd.conf" $2 $3
StrCmp "$0:$1" "$2:$3" +2 0
MessageBox MB_YESNO|MB_ICONQUESTION|MB_DEFBUTTON2 "Delete configuration file$\n$INSTDIR\bin\smartd.conf ?" IDYES 0 IDNO noconf
Delete "$INSTDIR\bin\smartd.conf"
noconf:
IfFileExists "$INSTDIR\bin\smartd.log" 0 +3
MessageBox MB_YESNO|MB_ICONQUESTION|MB_DEFBUTTON2 "Delete log file$\n$INSTDIR\bin\smartd.log ?" IDYES 0 IDNO +2
Delete "$INSTDIR\bin\smartd.log"
; Remove files
Delete "$INSTDIR\bin\smartctl.exe"
Delete "$INSTDIR\bin\smartd.exe"
Delete "$INSTDIR\bin\syslogevt.exe"
Delete "$INSTDIR\bin\smartctl-run.bat"
Delete "$INSTDIR\bin\smartd-run.bat"
Delete "$INSTDIR\bin\net-run.bat"
Delete "$INSTDIR\doc\AUTHORS.txt"
Delete "$INSTDIR\doc\CHANGELOG.txt"
Delete "$INSTDIR\doc\COPYING.txt"
Delete "$INSTDIR\doc\INSTALL.txt"
Delete "$INSTDIR\doc\NEWS.txt"
Delete "$INSTDIR\doc\README.txt"
Delete "$INSTDIR\doc\TODO.txt"
Delete "$INSTDIR\doc\WARNINGS.txt"
Delete "$INSTDIR\doc\smartctl.8.html"
Delete "$INSTDIR\doc\smartctl.8.txt"
Delete "$INSTDIR\doc\smartd.8.html"
Delete "$INSTDIR\doc\smartd.8.txt"
Delete "$INSTDIR\doc\smartd.conf"
Delete "$INSTDIR\doc\smartd.conf.5.html"
Delete "$INSTDIR\doc\smartd.conf.5.txt"
Delete "$INSTDIR\uninst-smartmontools.exe"
; Remove shortcuts
Delete "$SMPROGRAMS\smartmontools\*.*"
Delete "$SMPROGRAMS\smartmontools\Documentation\*.*"
Delete "$SMPROGRAMS\smartmontools\smartctl Examples\*.*"
Delete "$SMPROGRAMS\smartmontools\smartd Examples\*.*"
; Remove folders
RMDir "$SMPROGRAMS\smartmontools\Documentation"
RMDir "$SMPROGRAMS\smartmontools\smartctl Examples\"
RMDir "$SMPROGRAMS\smartmontools\smartd Examples\"
RMDir "$SMPROGRAMS\smartmontools"
RMDir "$INSTDIR\bin"
RMDir "$INSTDIR\doc"
RMDir "$INSTDIR"
; Remove install dir from PATH
IfFileExists "$WINDIR\system32\cmd.exe" 0 +3
Push "$INSTDIR\bin"
Call un.RemoveFromPath
; Check for still existing files
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."
SectionEnd
;--------------------------------------------------------------------
Function .onInit
; Hide "Add install dir to PATH" on 9x/ME
IfFileExists "$WINDIR\system32\cmd.exe" +2 0
SectionSetText ${PATH_IDX} ""
FunctionEnd
;--------------------------------------------------------------------
; Utility functions
;
; Based on example from:
; http://nsis.sourceforge.net/Path_Manipulation
;
!include "WinMessages.nsh"
; Registry Entry for environment (NT4,2000,XP)
; All users:
;!define Environ 'HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"'
; Current user only:
!define Environ 'HKCU "Environment"'
; AddToPath - Appends dir to PATH
; (does not work on Win9x/ME)
;
; Usage:
; Push "dir"
; Call AddToPath
Function AddToPath
Exch $0
Push $1
Push $2
Push $3
ReadRegStr $1 ${Environ} "PATH"
Push "$1;"
Push "$0;"
Call StrStr
Pop $2
StrCmp $2 "" "" done
Push "$1;"
Push "$0\;"
Call StrStr
Pop $2
StrCmp $2 "" "" done
DetailPrint "Add to PATH: $0"
StrCpy $2 $1 1 -1
StrCmp $2 ";" 0 +2
StrCpy $1 $1 -1 ; remove trailing ';'
StrCmp $1 "" +2 ; no leading ';'
StrCpy $0 "$1;$0"
WriteRegExpandStr ${Environ} "PATH" $0
SendMessage ${HWND_BROADCAST} ${WM_WININICHANGE} 0 "STR:Environment" /TIMEOUT=5000
done:
Pop $3
Pop $2
Pop $1
Pop $0
FunctionEnd
; RemoveFromPath - Removes dir from PATH
;
; Usage:
; Push "dir"
; Call RemoveFromPath
Function un.RemoveFromPath
Exch $0
Push $1
Push $2
Push $3
Push $4
Push $5
Push $6
ReadRegStr $1 ${Environ} "PATH"
StrCpy $5 $1 1 -1
StrCmp $5 ";" +2
StrCpy $1 "$1;" ; ensure trailing ';'
Push $1
Push "$0;"
Call un.StrStr
Pop $2 ; pos of our dir
StrCmp $2 "" done
DetailPrint "Remove from PATH: $0"
StrLen $3 "$0;"
StrLen $4 $2
StrCpy $5 $1 -$4 ; $5 is now the part before the path to remove
StrCpy $6 $2 "" $3 ; $6 is now the part after the path to remove
StrCpy $3 "$5$6"
StrCpy $5 $3 1 -1
StrCmp $5 ";" 0 +2
StrCpy $3 $3 -1 ; remove trailing ';'
WriteRegExpandStr ${Environ} "PATH" $3
SendMessage ${HWND_BROADCAST} ${WM_WININICHANGE} 0 "STR:Environment" /TIMEOUT=5000
done:
Pop $6
Pop $5
Pop $4
Pop $3
Pop $2
Pop $1
Pop $0
FunctionEnd
; StrStr - find substring in a string
;
; Usage:
; Push "this is some string"
; Push "some"
; Call StrStr
; Pop $0 ; "some string"
!macro StrStr un
Function ${un}StrStr
Exch $R1 ; $R1=substring, stack=[old$R1,string,...]
Exch ; stack=[string,old$R1,...]
Exch $R2 ; $R2=string, stack=[old$R2,old$R1,...]
Push $R3
Push $R4
Push $R5
StrLen $R3 $R1
StrCpy $R4 0
; $R1=substring, $R2=string, $R3=strlen(substring)
; $R4=count, $R5=tmp
loop:
StrCpy $R5 $R2 $R3 $R4
StrCmp $R5 $R1 done
StrCmp $R5 "" done
IntOp $R4 $R4 + 1
Goto loop
done:
StrCpy $R1 $R2 "" $R4
Pop $R5
Pop $R4
Pop $R3
Pop $R2
Exch $R1 ; $R1=old$R1, stack=[result,...]
FunctionEnd
!macroend
!insertmacro StrStr ""
!insertmacro StrStr "un."

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>
{{{
}}}
###############################################################################

View File

@ -19,10 +19,14 @@
#ifndef SYSLOG_H
#define SYSLOG_H
#define SYSLOG_H_CVSID "$Id: syslog.h,v 1.4 2006/04/12 14:54:28 ballen4705 Exp $\n"
#define SYSLOG_H_CVSID "$Id: syslog.h,v 1.5 2006/08/09 20:40:20 chrfranke Exp $\n"
#include <stdarg.h>
#ifdef __cplusplus
extern "C" {
#endif
/* EVENTLOG_ERROR_TYPE: */
#define LOG_EMERG 0
#define LOG_ALERT 1
@ -59,4 +63,8 @@ void closelog(void);
void vsyslog(int priority, const char * message, va_list args);
#ifdef __cplusplus
}
#endif
#endif /* SYSLOG_H */

View File

@ -1,5 +1,5 @@
/*
* os_win32/syslog_win32.c
* os_win32/syslog_win32.cpp
*
* Home page of code is: http://smartmontools.sourceforge.net
*
@ -35,7 +35,7 @@
#define WIN32_LEAN_AND_MEAN
#include <windows.h> // RegisterEventSourceA(), ReportEventA(), ...
const char *syslog_win32_c_cvsid = "$Id: syslog_win32.c,v 1.6 2006/04/12 14:54:29 ballen4705 Exp $"
const char *syslog_win32_c_cvsid = "$Id: syslog_win32.cpp,v 1.7 2006/08/09 20:40:20 chrfranke Exp $"
SYSLOG_H_CVSID;
#ifdef _MSC_VER

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

@ -439,7 +439,7 @@ typedef struct
unfortunately clutters up the declarations a bit, but I think it's
worth it. */
#if __STDC__
#if defined(__STDC__) || defined(__cplusplus)
# define _RE_ARGS(args) args
@ -536,7 +536,7 @@ extern int re_exec _RE_ARGS ((const char *));
#endif
/* gcc 3.1 and up support the [restrict] syntax. */
#ifndef __restrict_arr
# if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1)
# if (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1)) && !defined(__WIN32__)
# define __restrict_arr __restrict
# else
# define __restrict_arr

451
scsiata.cpp Normal file
View File

@ -0,0 +1,451 @@
/*
* scsiata.cpp
*
* Home page of code is: http://smartmontools.sourceforge.net
*
* Copyright (C) 2006 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
* 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.
*
* The code in this file is based on the SCSI to ATA Translation (SAT)
* draft found at http://www.t10.org . The original draft used for this
* code is sat-r08.pdf which is not too far away from becoming a
* standard. The SAT commands of interest to smartmontools are the
* ATA PASS THROUGH SCSI (16) and ATA PASS THROUGH SCSI (12) defined in
* section 12 of that document.
*
* With more transports "hiding" SATA disks (and other S-ATAPI devices)
* behind a SCSI command set, accessing special features like SMART
* information becomes a challenge. The SAT standard offers ATA PASS
* THROUGH commands for special usages. Note that the SAT layer may
* be inside a generic OS layer (e.g. libata in linux), in a host
* adapter (HA or HBA) firmware, or somewhere on the interconnect
* between the host computer and the SATA devices (e.g. a RAID made
* of SATA disks and the RAID talks "SCSI" to the host computer).
* Note that in the latter case, this code does not solve the
* addressing issue (i.e. which SATA disk to address behind the logical
* SCSI (RAID) interface).
*
*/
#include <stdio.h>
#include <string.h>
#include "config.h"
#include "int64.h"
#include "extern.h"
#include "scsicmds.h"
#include "scsiata.h"
#include "utility.h"
const char *scsiata_c_cvsid="$Id: scsiata.cpp,v 1.7 2006/08/09 20:40:19 chrfranke Exp $"
CONFIG_H_CVSID EXTERN_H_CVSID INT64_H_CVSID SCSICMDS_H_CVSID SCSIATA_H_CVSID UTILITY_H_CVSID;
/* for passing global control variables */
extern smartmonctrl *con;
#define DEF_SAT_ATA_PASSTHRU_SIZE 16
// cdb[0]: ATA PASS THROUGH (16) SCSI command opcode byte (0x85)
// cdb[1]: multiple_count, protocol + extend
// cdb[2]: offline, ck_cond, t_dir, byte_block + t_length
// cdb[3]: features (15:8)
// cdb[4]: features (7:0)
// cdb[5]: sector_count (15:8)
// cdb[6]: sector_count (7:0)
// cdb[7]: lba_low (15:8)
// cdb[8]: lba_low (7:0)
// cdb[9]: lba_mid (15:8)
// cdb[10]: lba_mid (7:0)
// cdb[11]: lba_high (15:8)
// cdb[12]: lba_high (7:0)
// cdb[13]: device
// cdb[14]: (ata) command
// cdb[15]: control (SCSI, leave as zero)
//
// 24 bit lba (from MSB): cdb[12] cdb[10] cdb[8]
// 48 bit lba (from MSB): cdb[11] cdb[9] cdb[7] cdb[12] cdb[10] cdb[8]
//
//
// cdb[0]: ATA PASS THROUGH (12) SCSI command opcode byte (0xa1)
// cdb[1]: multiple_count, protocol + extend
// cdb[2]: offline, ck_cond, t_dir, byte_block + t_length
// cdb[3]: features (7:0)
// cdb[4]: sector_count (7:0)
// cdb[5]: lba_low (7:0)
// cdb[6]: lba_mid (7:0)
// cdb[7]: lba_high (7:0)
// cdb[8]: device
// cdb[9]: (ata) command
// cdb[10]: reserved
// cdb[11]: control (SCSI, leave as zero)
//
//
// ATA status return descriptor (component of descriptor sense data)
// des[0]: descriptor code (0x9)
// des[1]: additional descriptor length (0xc)
// des[2]: extend (bit 0)
// des[3]: error
// des[4]: sector_count (15:8)
// des[5]: sector_count (7:0)
// des[6]: lba_low (15:8)
// des[7]: lba_low (7:0)
// des[8]: lba_mid (15:8)
// des[9]: lba_mid (7:0)
// des[10]: lba_high (15:8)
// des[11]: lba_high (7:0)
// des[12]: device
// des[13]: status
// PURPOSE
// This interface routine takes ATA SMART commands and packages
// them in the SAT-defined ATA PASS THROUGH SCSI commands. There are
// two available SCSI commands: a 12 byte and 16 byte variant; the
// one used is chosen via con->satpassthrulen .
// DETAILED DESCRIPTION OF ARGUMENTS
// device: is the file descriptor provided by (a SCSI dvice type) open()
// command: defines the different ATA operations.
// select: additional input data if needed (which log, which type of
// self-test).
// data: location to write output data, if needed (512 bytes).
// Note: not all commands use all arguments.
// RETURN VALUES
// -1 if the command failed
// 0 if the command succeeded,
// STATUS_CHECK routine:
// -1 if the command failed
// 0 if the command succeeded and disk SMART status is "OK"
// 1 if the command succeeded and disk SMART status is "FAILING"
int sat_command_interface(int device, smart_command_set command, int select,
char *data)
{
struct scsi_cmnd_io io_hdr;
struct scsi_sense_disect sinfo;
struct sg_scsi_sense_hdr ssh;
unsigned char cdb[SAT_ATA_PASSTHROUGH_16LEN];
unsigned char sense[32];
const unsigned char * ucp;
int status, len;
int copydata = 0;
int outlen = 0;
int extend = 0;
int chk_cond = 0; /* set to 1 to read register(s) back */
int protocol = 3; /* non-data */
int t_dir = 1; /* 0 -> to device, 1 -> from device */
int byte_block = 1; /* 0 -> bytes, 1 -> 512 byte blocks */
int t_length = 0; /* 0 -> no data transferred */
int feature = 0;
int ata_command = 0;
int sector_count = 0;
int lba_low = 0;
int lba_mid = 0;
int lba_high = 0;
int passthru_size = DEF_SAT_ATA_PASSTHRU_SIZE;
memset(cdb, 0, sizeof(cdb));
memset(sense, 0, sizeof(sense));
ata_command = ATA_SMART_CMD;
switch (command) {
case CHECK_POWER_MODE:
ata_command = ATA_CHECK_POWER_MODE;
chk_cond = 1;
copydata = 1;
break;
case READ_VALUES: /* READ DATA */
feature = ATA_SMART_READ_VALUES;
sector_count = 1; /* one (512 byte) block */
protocol = 4; /* PIO data-in */
t_length = 2; /* sector count holds count */
copydata = 512;
break;
case READ_THRESHOLDS: /* obsolete */
feature = ATA_SMART_READ_THRESHOLDS;
sector_count = 1; /* one (512 byte) block */
lba_low = 1;
protocol = 4; /* PIO data-in */
t_length = 2; /* sector count holds count */
copydata=512;
break;
case READ_LOG:
feature = ATA_SMART_READ_LOG_SECTOR;
sector_count = 1; /* one (512 byte) block */
lba_low = select;
protocol = 4; /* PIO data-in */
t_length = 2; /* sector count holds count */
copydata = 512;
break;
case WRITE_LOG:
feature = ATA_SMART_WRITE_LOG_SECTOR;
sector_count = 1; /* one (512 byte) block */
lba_low = select;
protocol = 5; /* PIO data-out */
t_length = 2; /* sector count holds count */
t_dir = 0; /* to device */
outlen = 512;
break;
case IDENTIFY:
ata_command = ATA_IDENTIFY_DEVICE;
sector_count = 1; /* one (512 byte) block */
protocol = 4; /* PIO data-in */
t_length = 2; /* sector count holds count */
copydata = 512;
break;
case PIDENTIFY:
ata_command = ATA_IDENTIFY_PACKET_DEVICE;
sector_count = 1; /* one (512 byte) block */
protocol = 4; /* PIO data-in */
t_length = 2; /* sector count (7:0) holds count */
copydata = 512;
break;
case ENABLE:
feature = ATA_SMART_ENABLE;
lba_low = 1;
break;
case DISABLE:
feature = ATA_SMART_DISABLE;
lba_low = 1;
break;
case STATUS:
// this command only says if SMART is working. It could be
// replaced with STATUS_CHECK below.
feature = ATA_SMART_STATUS;
chk_cond = 1;
break;
case AUTO_OFFLINE:
feature = ATA_SMART_AUTO_OFFLINE;
sector_count = select; // YET NOTE - THIS IS A NON-DATA COMMAND!!
break;
case AUTOSAVE:
feature = ATA_SMART_AUTOSAVE;
sector_count = select; // YET NOTE - THIS IS A NON-DATA COMMAND!!
break;
case IMMEDIATE_OFFLINE:
feature = ATA_SMART_IMMEDIATE_OFFLINE;
lba_low = select;
break;
case STATUS_CHECK:
// This command uses HDIO_DRIVE_TASK and has different syntax than
// the other commands.
feature = ATA_SMART_STATUS; /* SMART RETURN STATUS */
chk_cond = 1;
break;
default:
pout("Unrecognized command %d in sat_command_interface()\n"
"Please contact " PACKAGE_BUGREPORT "\n", command);
errno=ENOSYS;
return -1;
}
if (ATA_SMART_CMD == ata_command) {
lba_mid = 0x4f;
lba_high = 0xc2;
}
if ((SAT_ATA_PASSTHROUGH_12LEN == con->satpassthrulen) ||
(SAT_ATA_PASSTHROUGH_16LEN == con->satpassthrulen))
passthru_size = con->satpassthrulen;
cdb[0] = (SAT_ATA_PASSTHROUGH_12LEN == passthru_size) ?
SAT_ATA_PASSTHROUGH_12 : SAT_ATA_PASSTHROUGH_16;
cdb[1] = (protocol << 1) | extend;
cdb[2] = (chk_cond << 5) | (t_dir << 3) |
(byte_block << 2) | t_length;
cdb[(SAT_ATA_PASSTHROUGH_12LEN == passthru_size) ? 3 : 4] = feature;
cdb[(SAT_ATA_PASSTHROUGH_12LEN == passthru_size) ? 4 : 6] = sector_count;
cdb[(SAT_ATA_PASSTHROUGH_12LEN == passthru_size) ? 5 : 8] = lba_low;
cdb[(SAT_ATA_PASSTHROUGH_12LEN == passthru_size) ? 6 : 10] = lba_mid;
cdb[(SAT_ATA_PASSTHROUGH_12LEN == passthru_size) ? 7 : 12] = lba_high;
cdb[(SAT_ATA_PASSTHROUGH_12LEN == passthru_size) ? 9 : 14] = ata_command;
memset(&io_hdr, 0, sizeof(io_hdr));
if (0 == t_length) {
io_hdr.dxfer_dir = DXFER_NONE;
io_hdr.dxfer_len = 0;
} else if (t_dir) { /* from device */
io_hdr.dxfer_dir = DXFER_FROM_DEVICE;
io_hdr.dxfer_len = copydata;
io_hdr.dxferp = (unsigned char *)data;
memset(data, 0, copydata); /* prefill with zeroes */
} else { /* to device */
io_hdr.dxfer_dir = DXFER_TO_DEVICE;
io_hdr.dxfer_len = outlen;
io_hdr.dxferp = (unsigned char *)data;
}
io_hdr.cmnd = cdb;
io_hdr.cmnd_len = passthru_size;
io_hdr.sensep = sense;
io_hdr.max_sense_len = sizeof(sense);
io_hdr.timeout = SCSI_TIMEOUT_DEFAULT;
status = do_scsi_cmnd_io(device, &io_hdr, con->reportscsiioctl);
if (0 != status) {
if (con->reportscsiioctl > 0)
pout("sat_command_interface: do_scsi_cmnd_io() failed, "
"status=%d\n", status);
return -1;
}
if (chk_cond) { /* expecting SAT specific sense data */
ucp = NULL;
if (sg_scsi_normalize_sense(io_hdr.sensep, io_hdr.resp_sense_len,
&ssh)) {
/* look for SAT extended ATA status return descriptor (9) */
ucp = sg_scsi_sense_desc_find(io_hdr.sensep,
io_hdr.resp_sense_len, 9);
if (ucp) {
len = ucp[1] + 2;
if (len < 12)
len = 12;
else if (len > 14)
len = 14;
if (con->reportscsiioctl > 1) {
pout("Values from ATA status return descriptor are:\n");
dStrHex((const char *)ucp, len, 1);
}
if (ATA_CHECK_POWER_MODE == cdb[14])
data[0] = ucp[5]; /* sector count (0:7) */
else if (STATUS_CHECK == command) {
if ((ucp[9] == 0x4f) && (ucp[11] == 0xc2))
return 0; /* GOOD smart status */
if ((ucp[9] == 0xf4) && (ucp[11] == 0x2c))
return 1; // smart predicting failure, "bad" status
// We haven't gotten output that makes sense so
// print out some debugging info
syserror("Error SMART Status command failed");
pout("Please get assistance from " PACKAGE_HOMEPAGE "\n");
pout("Values from ATA status return descriptor are:\n");
dStrHex((const char *)ucp, len, 1);
return -1;
}
}
}
if (ucp == NULL) {
chk_cond = 0; /* not the type of sense data expected */
if (t_dir && (t_length > 0))
data[0] = 0;
}
}
if (0 == chk_cond) {
ucp = NULL;
if (sg_scsi_normalize_sense(io_hdr.sensep, io_hdr.resp_sense_len,
&ssh)) {
if ((ssh.response_code >= 0x72) &&
((SCSI_SK_NO_SENSE == ssh.sense_key) ||
(SCSI_SK_RECOVERED_ERR == ssh.sense_key)) &&
(0 == ssh.asc) &&
(SCSI_ASCQ_ATA_PASS_THROUGH == ssh.ascq)) {
/* look for SAT extended ATA status return descriptor (9) */
ucp = sg_scsi_sense_desc_find(io_hdr.sensep,
io_hdr.resp_sense_len, 9);
if (ucp) {
if (con->reportscsiioctl > 0) {
pout("Values from ATA status return descriptor are:\n");
len = ucp[1] + 2;
if (len < 12)
len = 12;
else if (len > 14)
len = 14;
dStrHex((const char *)ucp, len, 1);
}
return -1;
}
}
scsi_do_sense_disect(&io_hdr, &sinfo);
status = scsiSimpleSenseFilter(&sinfo);
if (0 != status) {
if (con->reportscsiioctl > 0)
pout("sat_command_interface: scsi error: %s\n",
scsiErrString(status));
return -1;
}
}
}
return 0;
}
/* Attempt an IDENTIFY DEVICE ATA command via SATL when packet_interface
is 0 otherwise attempt IDENTIFY PACKET DEVICE. If successful
return 1, else 0 */
int has_sat_pass_through(int device, int packet_interface)
{
char data[512];
smart_command_set command;
command = packet_interface ? PIDENTIFY : IDENTIFY;
if (0 == sat_command_interface(device, command, 0, data))
return 1;
else
return 0;
}
/* Next two functions are borrowed from sg_lib.c in the sg3_utils
package. Same copyrght owner, same license as this file. */
int sg_scsi_normalize_sense(const unsigned char * sensep, int sb_len,
struct sg_scsi_sense_hdr * sshp)
{
if (sshp)
memset(sshp, 0, sizeof(struct sg_scsi_sense_hdr));
if ((NULL == sensep) || (0 == sb_len) || (0x70 != (0x70 & sensep[0])))
return 0;
if (sshp) {
sshp->response_code = (0x7f & sensep[0]);
if (sshp->response_code >= 0x72) { /* descriptor format */
if (sb_len > 1)
sshp->sense_key = (0xf & sensep[1]);
if (sb_len > 2)
sshp->asc = sensep[2];
if (sb_len > 3)
sshp->ascq = sensep[3];
if (sb_len > 7)
sshp->additional_length = sensep[7];
} else { /* fixed format */
if (sb_len > 2)
sshp->sense_key = (0xf & sensep[2]);
if (sb_len > 7) {
sb_len = (sb_len < (sensep[7] + 8)) ? sb_len :
(sensep[7] + 8);
if (sb_len > 12)
sshp->asc = sensep[12];
if (sb_len > 13)
sshp->ascq = sensep[13];
}
}
}
return 1;
}
const unsigned char * sg_scsi_sense_desc_find(const unsigned char * sensep,
int sense_len, int desc_type)
{
int add_sen_len, add_len, desc_len, k;
const unsigned char * descp;
if ((sense_len < 8) || (0 == (add_sen_len = sensep[7])))
return NULL;
if ((sensep[0] < 0x72) || (sensep[0] > 0x73))
return NULL;
add_sen_len = (add_sen_len < (sense_len - 8)) ?
add_sen_len : (sense_len - 8);
descp = &sensep[8];
for (desc_len = 0, k = 0; k < add_sen_len; k += desc_len) {
descp += desc_len;
add_len = (k < (add_sen_len - 1)) ? descp[1]: -1;
desc_len = add_len + 2;
if (descp[0] == desc_type)
return descp;
if (add_len < 0) /* short descriptor ?? */
break;
}
return NULL;
}

78
scsiata.h Normal file
View File

@ -0,0 +1,78 @@
/*
* scsiata.h
*
* Home page of code is: http://smartmontools.sourceforge.net
*
* Copyright (C) 2006 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
* 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 SCSIATA_H_
#define SCSIATA_H_
#define SCSIATA_H_CVSID "$Id: scsiata.h,v 1.2 2006/07/01 21:29:31 dpgilbert Exp $\n"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include "atacmds.h"
#define SAT_ATA_PASSTHROUGH_12LEN 12
#define SAT_ATA_PASSTHROUGH_16LEN 16
extern int sat_command_interface(int device, smart_command_set command,
int select, char *data);
/* Attempt an IDENTIFY DEVICE ATA command via SATL when packet_interface
is 0 otherwise attempt IDENTIFY PACKET DEVICE. If successful
return 1, else 0 */
extern int has_sat_pass_through(int device, int packet_interface);
/* This is a slightly stretched SCSI sense "descriptor" format header.
The addition is to allow the 0x70 and 0x71 response codes. The idea
is to place the salient data of both "fixed" and "descriptor" sense
format into one structure to ease application processing.
The original sense buffer should be kept around for those cases
in which more information is required (e.g. the LBA of a MEDIUM ERROR). */
struct sg_scsi_sense_hdr {
unsigned char response_code; /* permit: 0x0, 0x70, 0x71, 0x72, 0x73 */
unsigned char sense_key;
unsigned char asc;
unsigned char ascq;
unsigned char byte4;
unsigned char byte5;
unsigned char byte6;
unsigned char additional_length;
};
/* Maps the salient data from a sense buffer which is in either fixed or
descriptor format into a structure mimicking a descriptor format
header (i.e. the first 8 bytes of sense descriptor format).
If zero response code returns 0. Otherwise returns 1 and if 'sshp' is
non-NULL then zero all fields and then set the appropriate fields in
that structure. sshp::additional_length is always 0 for response
codes 0x70 and 0x71 (fixed format). */
extern int sg_scsi_normalize_sense(const unsigned char * sensep,
int sense_len,
struct sg_scsi_sense_hdr * sshp);
/* Attempt to find the first SCSI sense data descriptor that matches the
given 'desc_type'. If found return pointer to start of sense data
descriptor; otherwise (including fixed format sense data) returns NULL. */
extern const unsigned char * sg_scsi_sense_desc_find(
const unsigned char * sensep, int sense_len, int desc_type);
#endif

View File

@ -1,5 +1,5 @@
/*
* scsicmds.c
* scsicmds.cpp
*
* Home page of code is: http://smartmontools.sourceforge.net
*
@ -47,7 +47,7 @@
#include "scsicmds.h"
#include "utility.h"
const char *scsicmds_c_cvsid="$Id: scsicmds.c,v 1.85 2006/04/12 14:54:28 ballen4705 Exp $"
const char *scsicmds_c_cvsid="$Id: scsicmds.cpp,v 1.91 2006/09/12 00:25:44 dpgilbert Exp $"
CONFIG_H_CVSID EXTERN_H_CVSID INT64_H_CVSID SCSICMDS_H_CVSID UTILITY_H_CVSID;
/* for passing global control variables */
@ -124,6 +124,8 @@ static struct scsi_opcode_name opcode_name_arr[] = {
{LOG_SENSE, "log sense"}, /* 0x4d */
{MODE_SELECT_10, "mode select(10)"}, /* 0x55 */
{MODE_SENSE_10, "mode sense(10)"}, /* 0x5a */
{SAT_ATA_PASSTHROUGH_16, "ata pass-through(16)"}, /* 0x85 */
{SAT_ATA_PASSTHROUGH_12, "ata pass-through(12)"}, /* 0xa1 */
};
const char * scsi_get_opcode_name(UINT8 opcode)
@ -146,19 +148,27 @@ const char * scsi_get_opcode_name(UINT8 opcode)
void scsi_do_sense_disect(const struct scsi_cmnd_io * io_buf,
struct scsi_sense_disect * out)
{
int resp_code;
memset(out, 0, sizeof(struct scsi_sense_disect));
if ((SCSI_STATUS_CHECK_CONDITION == io_buf->scsi_status) &&
(io_buf->resp_sense_len > 7)) {
out->error_code = (io_buf->sensep[0] & 0x7f);
out->sense_key = (io_buf->sensep[2] & 0xf);
if (io_buf->resp_sense_len > 13) {
out->asc = io_buf->sensep[12];
out->ascq = io_buf->sensep[13];
if (SCSI_STATUS_CHECK_CONDITION == io_buf->scsi_status) {
resp_code = (io_buf->sensep[0] & 0x7f);
out->error_code = resp_code;
if (resp_code >= 0x72) {
out->sense_key = (io_buf->sensep[1] & 0xf);
out->asc = io_buf->sensep[2];
out->ascq = io_buf->sensep[3];
} else if (resp_code >= 0x70) {
out->sense_key = (io_buf->sensep[2] & 0xf);
if (io_buf->resp_sense_len > 13) {
out->asc = io_buf->sensep[12];
out->ascq = io_buf->sensep[13];
}
}
}
}
static int scsiSimpleSenseFilter(const struct scsi_sense_disect * sinfo)
int scsiSimpleSenseFilter(const struct scsi_sense_disect * sinfo)
{
switch (sinfo->sense_key) {
case SCSI_SK_NOT_READY:
@ -230,8 +240,8 @@ const char * scsiErrString(int scsiErr)
requesting the deduced response length. This protects certain fragile
HBAs. The twin fetch technique should not be used with the TapeAlert
log page since it clears its state flags after each fetch. */
int scsiLogSense(int device, int pagenum, UINT8 *pBuf, int bufLen,
int known_resp_len)
int scsiLogSense(int device, int pagenum, int subpagenum, UINT8 *pBuf,
int bufLen, int known_resp_len)
{
struct scsi_cmnd_io io_hdr;
struct scsi_sense_disect sinfo;
@ -259,6 +269,7 @@ int scsiLogSense(int device, int pagenum, UINT8 *pBuf, int bufLen,
io_hdr.dxferp = pBuf;
cdb[0] = LOG_SENSE;
cdb[2] = 0x40 | (pagenum & 0x3f); /* Page control (PC)==1 */
cdb[3] = subpagenum;
cdb[7] = (pageLen >> 8) & 0xff;
cdb[8] = pageLen & 0xff;
io_hdr.cmnd = cdb;
@ -320,7 +331,8 @@ int scsiLogSense(int device, int pagenum, UINT8 *pBuf, int bufLen,
* 2 if command not supported (then MODE SENSE(10) should be supported),
* 3 if field in command not supported or returns negated errno.
* SPC-3 sections 6.9 and 7.4 (rev 22a) [mode subpage==0] */
int scsiModeSense(int device, int pagenum, int pc, UINT8 *pBuf, int bufLen)
int scsiModeSense(int device, int pagenum, int subpagenum, int pc,
UINT8 *pBuf, int bufLen)
{
struct scsi_cmnd_io io_hdr;
struct scsi_sense_disect sinfo;
@ -337,6 +349,7 @@ int scsiModeSense(int device, int pagenum, int pc, UINT8 *pBuf, int bufLen)
io_hdr.dxferp = pBuf;
cdb[0] = MODE_SENSE;
cdb[2] = (pc << 6) | (pagenum & 0x3f);
cdb[3] = subpagenum;
cdb[4] = bufLen;
io_hdr.cmnd = cdb;
io_hdr.cmnd_len = sizeof(cdb);
@ -417,7 +430,8 @@ int scsiModeSelect(int device, int sp, UINT8 *pBuf, int bufLen)
* not supported (then MODE SENSE(6) might be supported), 3 if field in
* command not supported or returns negated errno.
* SPC-3 sections 6.10 and 7.4 (rev 22a) [mode subpage==0] */
int scsiModeSense10(int device, int pagenum, int pc, UINT8 *pBuf, int bufLen)
int scsiModeSense10(int device, int pagenum, int subpagenum, int pc,
UINT8 *pBuf, int bufLen)
{
struct scsi_cmnd_io io_hdr;
struct scsi_sense_disect sinfo;
@ -432,6 +446,7 @@ int scsiModeSense10(int device, int pagenum, int pc, UINT8 *pBuf, int bufLen)
io_hdr.dxferp = pBuf;
cdb[0] = MODE_SENSE_10;
cdb[2] = (pc << 6) | (pagenum & 0x3f);
cdb[3] = subpagenum;
cdb[7] = (bufLen >> 8) & 0xff;
cdb[8] = bufLen & 0xff;
io_hdr.cmnd = cdb;
@ -842,8 +857,8 @@ int scsiFetchIECmpage(int device, struct scsi_iec_mode_page *iecp, int modese_le
iecp->modese_len = modese_len;
iecp->requestedCurrent = 1;
if (iecp->modese_len <= 6) {
if ((err = scsiModeSense(device, INFORMATIONAL_EXCEPTIONS_CONTROL_PAGE,
MPAGE_CONTROL_CURRENT,
if ((err = scsiModeSense(device, INFORMATIONAL_EXCEPTIONS_CONTROL_PAGE,
0, MPAGE_CONTROL_CURRENT,
iecp->raw_curr, sizeof(iecp->raw_curr)))) {
if (SIMPLE_ERR_BAD_OPCODE == err)
iecp->modese_len = 10;
@ -856,7 +871,7 @@ int scsiFetchIECmpage(int device, struct scsi_iec_mode_page *iecp, int modese_le
}
if (10 == iecp->modese_len) {
err = scsiModeSense10(device, INFORMATIONAL_EXCEPTIONS_CONTROL_PAGE,
MPAGE_CONTROL_CURRENT,
0, MPAGE_CONTROL_CURRENT,
iecp->raw_curr, sizeof(iecp->raw_curr));
if (err) {
iecp->modese_len = 0;
@ -867,11 +882,11 @@ int scsiFetchIECmpage(int device, struct scsi_iec_mode_page *iecp, int modese_le
iecp->requestedChangeable = 1;
if (10 == iecp->modese_len)
err = scsiModeSense10(device, INFORMATIONAL_EXCEPTIONS_CONTROL_PAGE,
MPAGE_CONTROL_CHANGEABLE,
iecp->raw_chg, sizeof(iecp->raw_chg));
0, MPAGE_CONTROL_CHANGEABLE,
iecp->raw_chg, sizeof(iecp->raw_chg));
else if (6 == iecp->modese_len)
err = scsiModeSense(device, INFORMATIONAL_EXCEPTIONS_CONTROL_PAGE,
MPAGE_CONTROL_CHANGEABLE,
0, MPAGE_CONTROL_CHANGEABLE,
iecp->raw_chg, sizeof(iecp->raw_chg));
if (err)
return err;
@ -1005,7 +1020,7 @@ int scsiGetTemp(int device, UINT8 *currenttemp, UINT8 *triptemp)
int err;
memset(tBuf, 0, sizeof(tBuf));
if ((err = scsiLogSense(device, TEMPERATURE_LPAGE, tBuf,
if ((err = scsiLogSense(device, TEMPERATURE_LPAGE, 0, tBuf,
sizeof(tBuf), 0))) {
*currenttemp = 0;
*triptemp = 0;
@ -1039,7 +1054,7 @@ int scsiCheckIE(int device, int hasIELogPage, int hasTempLogPage,
memset(tBuf,0,sizeof(tBuf)); // need to clear stack space of junk
memset(&sense_info, 0, sizeof(sense_info));
if (hasIELogPage) {
if ((err = scsiLogSense(device, IE_LPAGE, tBuf,
if ((err = scsiLogSense(device, IE_LPAGE, 0, tBuf,
sizeof(tBuf), 0))) {
pout("Log Sense failed, IE page [%s]\n", scsiErrString(err));
return err;
@ -1696,8 +1711,8 @@ int scsiFetchExtendedSelfTestTime(int device, int * durationSec, int modese_len)
memset(buff, 0, sizeof(buff));
if (modese_len <= 6) {
if ((err = scsiModeSense(device, CONTROL_MODE_PAGE,
MPAGE_CONTROL_CURRENT,
if ((err = scsiModeSense(device, CONTROL_MODE_PAGE, 0,
MPAGE_CONTROL_CURRENT,
buff, sizeof(buff)))) {
if (SIMPLE_ERR_BAD_OPCODE == err)
modese_len = 10;
@ -1707,7 +1722,7 @@ int scsiFetchExtendedSelfTestTime(int device, int * durationSec, int modese_len)
modese_len = 6;
}
if (10 == modese_len) {
err = scsiModeSense10(device, CONTROL_MODE_PAGE,
err = scsiModeSense10(device, CONTROL_MODE_PAGE, 0,
MPAGE_CONTROL_CURRENT,
buff, sizeof(buff));
if (err)
@ -1855,13 +1870,13 @@ int scsiCountFailedSelfTests(int fd, int noisy)
UINT8 * ucp;
unsigned char resp[LOG_RESP_SELF_TEST_LEN];
if ((err = scsiLogSense(fd, SELFTEST_RESULTS_LPAGE, resp,
if ((err = scsiLogSense(fd, SELFTEST_RESULTS_LPAGE, 0, resp,
LOG_RESP_SELF_TEST_LEN, 0))) {
if (noisy)
pout("scsiCountSelfTests Failed [%s]\n", scsiErrString(err));
return -1;
}
if (resp[0] != SELFTEST_RESULTS_LPAGE) {
if ((resp[0] & 0x3f) != SELFTEST_RESULTS_LPAGE) {
if (noisy)
pout("Self-test Log Sense Failed, page mismatch\n");
return -1;
@ -1904,7 +1919,7 @@ int scsiSelfTestInProgress(int fd, int * inProgress)
UINT8 * ucp;
unsigned char resp[LOG_RESP_SELF_TEST_LEN];
if (scsiLogSense(fd, SELFTEST_RESULTS_LPAGE, resp,
if (scsiLogSense(fd, SELFTEST_RESULTS_LPAGE, 0, resp,
LOG_RESP_SELF_TEST_LEN, 0))
return -1;
if (resp[0] != SELFTEST_RESULTS_LPAGE)
@ -1933,7 +1948,7 @@ int scsiFetchControlGLTSD(int device, int modese_len, int current)
memset(buff, 0, sizeof(buff));
if (modese_len <= 6) {
if ((err = scsiModeSense(device, CONTROL_MODE_PAGE, pc,
if ((err = scsiModeSense(device, CONTROL_MODE_PAGE, 0, pc,
buff, sizeof(buff)))) {
if (SIMPLE_ERR_BAD_OPCODE == err)
modese_len = 10;
@ -1943,7 +1958,7 @@ int scsiFetchControlGLTSD(int device, int modese_len, int current)
modese_len = 6;
}
if (10 == modese_len) {
err = scsiModeSense10(device, CONTROL_MODE_PAGE, pc,
err = scsiModeSense10(device, CONTROL_MODE_PAGE, 0, pc,
buff, sizeof(buff));
if (err)
return -EINVAL;
@ -1966,8 +1981,8 @@ int scsiSetControlGLTSD(int device, int enabled, int modese_len)
memset(buff, 0, sizeof(buff));
if (modese_len <= 6) {
if ((err = scsiModeSense(device, CONTROL_MODE_PAGE,
MPAGE_CONTROL_CURRENT,
if ((err = scsiModeSense(device, CONTROL_MODE_PAGE, 0,
MPAGE_CONTROL_CURRENT,
buff, sizeof(buff)))) {
if (SIMPLE_ERR_BAD_OPCODE == err)
modese_len = 10;
@ -1977,8 +1992,8 @@ int scsiSetControlGLTSD(int device, int enabled, int modese_len)
modese_len = 6;
}
if (10 == modese_len) {
err = scsiModeSense10(device, CONTROL_MODE_PAGE,
MPAGE_CONTROL_CURRENT,
err = scsiModeSense10(device, CONTROL_MODE_PAGE, 0,
MPAGE_CONTROL_CURRENT,
buff, sizeof(buff));
if (err)
return err;
@ -1993,12 +2008,12 @@ int scsiSetControlGLTSD(int device, int enabled, int modese_len)
return 0; /* GLTSD already in wanted state so nothing to do */
if (modese_len == 6)
err = scsiModeSense(device, CONTROL_MODE_PAGE,
MPAGE_CONTROL_CHANGEABLE,
err = scsiModeSense(device, CONTROL_MODE_PAGE, 0,
MPAGE_CONTROL_CHANGEABLE,
ch_buff, sizeof(ch_buff));
else
err = scsiModeSense10(device, CONTROL_MODE_PAGE,
MPAGE_CONTROL_CHANGEABLE,
err = scsiModeSense10(device, CONTROL_MODE_PAGE, 0,
MPAGE_CONTROL_CHANGEABLE,
ch_buff, sizeof(ch_buff));
if (err)
return err;
@ -2034,8 +2049,8 @@ int scsiFetchTransportProtocol(int device, int modese_len)
memset(buff, 0, sizeof(buff));
if (modese_len <= 6) {
if ((err = scsiModeSense(device, PROTOCOL_SPECIFIC_PORT_PAGE,
MPAGE_CONTROL_CURRENT,
if ((err = scsiModeSense(device, PROTOCOL_SPECIFIC_PORT_PAGE, 0,
MPAGE_CONTROL_CURRENT,
buff, sizeof(buff)))) {
if (SIMPLE_ERR_BAD_OPCODE == err)
modese_len = 10;
@ -2045,8 +2060,8 @@ int scsiFetchTransportProtocol(int device, int modese_len)
modese_len = 6;
}
if (10 == modese_len) {
err = scsiModeSense10(device, PROTOCOL_SPECIFIC_PORT_PAGE,
MPAGE_CONTROL_CURRENT,
err = scsiModeSense10(device, PROTOCOL_SPECIFIC_PORT_PAGE, 0,
MPAGE_CONTROL_CURRENT,
buff, sizeof(buff));
if (err)
return -EINVAL;
@ -2069,11 +2084,15 @@ int isLinuxLibAta(unsigned char * vpd_di_buff, int len)
int k, id_len, c_set, assoc, id_type, i_len;
unsigned char * ucp;
unsigned char * ip;
unsigned char buff1[20];
unsigned char buff2[20];
if (len < 4) {
/* Device identification VPD page length too short */
return 0;
}
buff1[0] = '\0';
buff2[0] = '\0';
len -= 4;
ucp = vpd_di_buff + 4;
for (k = 0; k < len; k += id_len, ucp += id_len) {
@ -2087,9 +2106,24 @@ int isLinuxLibAta(unsigned char * vpd_di_buff, int len)
c_set = (ucp[0] & 0xf);
assoc = ((ucp[1] >> 4) & 0x3);
id_type = (ucp[1] & 0xf);
if ((0 == id_type) && (2 == c_set) && (0 == assoc) &&
(0 == strncmp((const char *)ip,
"Linux ATA-SCSI simulator", i_len))) {
if ((0 == id_type) && (2 == c_set) && (0 == assoc)) {
/* assoc=lu, c_set=ascii, id_type=vendor */
if (0 == strncmp((const char *)ip,
"Linux ATA-SCSI simulator", i_len)) {
/* until lk 2.6.16 */
return 1;
}
memcpy(buff1, ip, sizeof(buff1));
}
if ((1 == id_type) && (2 == c_set) && (0 == assoc)) {
/* assoc=lu, c_set=ascii, id_type=t10 vendor id */
if (0 == strncmp((const char *)ip, "ATA", 3))
memcpy(buff2, ip + 48, sizeof(buff2));
}
}
if (buff1[0] && buff2[0]) {
if (0 == memcmp(buff1, buff2, sizeof(buff1))) {
/* after lk 2.6.16, look for serial number match */
return 1;
}
}

View File

@ -32,7 +32,7 @@
#ifndef SCSICMDS_H_
#define SCSICMDS_H_
#define SCSICMDS_H_CVSID "$Id: scsicmds.h,v 1.57 2006/04/12 14:54:28 ballen4705 Exp $\n"
#define SCSICMDS_H_CVSID "$Id: scsicmds.h,v 1.62 2006/09/12 00:22:49 dpgilbert Exp $\n"
#include <stdio.h>
#include <stdlib.h>
@ -77,6 +77,13 @@
#define READ_DEFECT_10 0x37
#endif
#ifndef SAT_ATA_PASSTHROUGH_12
#define SAT_ATA_PASSTHROUGH_12 0xa1
#endif
#ifndef SAT_ATA_PASSTHROUGH_16
#define SAT_ATA_PASSTHROUGH_16 0x85
#endif
typedef unsigned char UINT8;
typedef char INT8;
typedef unsigned int UINT32;
@ -163,6 +170,7 @@ struct scsiNonMediumError {
#define STARTSTOP_CYCLE_COUNTER_LPAGE 0x0e
#define APPLICATION_CLIENT_LPAGE 0x0f
#define SELFTEST_RESULTS_LPAGE 0x10
#define BACKGROUND_RESULTS_LPAGE 0x15 /* SBC-3 */
#define IE_LPAGE 0x2f
/* Seagate vendor specific log pages. */
@ -200,6 +208,9 @@ Documentation, see http://www.storage.ibm.com/techsup/hddtech/prodspecs.htm */
#define INFORMATIONAL_EXCEPTIONS_CONTROL_PAGE 0x1c
#define FAULT_FAILURE_REPORTING_PAGE 0x1c
/* Background control mode subpage is [0x1c,0x1] */
#define BACKGROUND_CONTROL_M_SUBPAGE 0x1 /* SBC-2 */
#define ALL_MODE_PAGES 0x3f
/* Mode page control field */
@ -212,6 +223,8 @@ Documentation, see http://www.storage.ibm.com/techsup/hddtech/prodspecs.htm */
#define SCSI_STATUS_CHECK_CONDITION 0x2
/* defines for useful Sense Key codes */
#define SCSI_SK_NO_SENSE 0x0
#define SCSI_SK_RECOVERED_ERR 0x1
#define SCSI_SK_NOT_READY 0x2
#define SCSI_SK_MEDIUM_ERROR 0x3
#define SCSI_SK_HARDWARE_ERROR 0x4
@ -227,6 +240,8 @@ Documentation, see http://www.storage.ibm.com/techsup/hddtech/prodspecs.htm */
#define SCSI_ASC_WARNING 0xb
#define SCSI_ASC_IMPENDING_FAILURE 0x5d
#define SCSI_ASCQ_ATA_PASS_THROUGH 0x1d
/* Simplified error code (negative values as per errno) */
#define SIMPLE_NO_ERROR 0
#define SIMPLE_ERR_NOT_READY 1
@ -262,6 +277,8 @@ Documentation, see http://www.storage.ibm.com/techsup/hddtech/prodspecs.htm */
void scsi_do_sense_disect(const struct scsi_cmnd_io * in,
struct scsi_sense_disect * out);
int scsiSimpleSenseFilter(const struct scsi_sense_disect * sinfo);
const char * scsiErrString(int scsiErr);
/* STANDARD SCSI Commands */
@ -271,14 +288,16 @@ int scsiStdInquiry(int device, UINT8 *pBuf, int bufLen);
int scsiInquiryVpd(int device, int vpd_page, UINT8 *pBuf, int bufLen);
int scsiLogSense(int device, int pagenum, UINT8 *pBuf, int bufLen,
int known_resp_len);
int scsiLogSense(int device, int pagenum, int subpagenum, UINT8 *pBuf,
int bufLen, int known_resp_len);
int scsiModeSense(int device, int pagenum, int pc, UINT8 *pBuf, int bufLen);
int scsiModeSense(int device, int pagenum, int subpagenum, int pc,
UINT8 *pBuf, int bufLen);
int scsiModeSelect(int device, int sp, UINT8 *pBuf, int bufLen);
int scsiModeSense10(int device, int pagenum, int pc, UINT8 *pBuf, int bufLen);
int scsiModeSense10(int device, int pagenum, int subpagenum, int pc,
UINT8 *pBuf, int bufLen);
int scsiModeSelect10(int device, int sp, UINT8 *pBuf, int bufLen);
@ -336,6 +355,9 @@ const char * scsiTapeAlertsChangerDevice(unsigned short code);
const char * scsi_get_opcode_name(UINT8 opcode);
void dStrHex(const char* str, int len, int no_ascii);
inline void dStrHex(const unsigned char* str, int len, int no_ascii)
{ dStrHex((const char *)str, len, no_ascii); }
/* SCSI command transmission interface function declaration. Its
* definition is target OS specific (see os_<OS>.c file).

View File

@ -1,5 +1,5 @@
/*
* scsiprint.c
* scsiprint.cpp
*
* Home page of code is: http://smartmontools.sourceforge.net
*
@ -38,10 +38,11 @@
#include "scsiprint.h"
#include "smartctl.h"
#include "utility.h"
#include "scsiata.h"
#define GBUF_SIZE 65535
const char* scsiprint_c_cvsid="$Id: scsiprint.c,v 1.107 2006/04/12 16:18:57 ballen4705 Exp $"
const char* scsiprint_c_cvsid="$Id: scsiprint.cpp,v 1.118 2006/09/27 21:42:03 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
@ -52,7 +53,7 @@ extern int exitstatus;
UINT8 gBuf[GBUF_SIZE];
#define LOG_RESP_LEN 252
#define LOG_RESP_LONG_LEN 8192
#define LOG_RESP_LONG_LEN 16384
#define LOG_RESP_TAPE_ALERT_LEN 0x144
/* Log pages supported */
@ -65,6 +66,7 @@ static int gWriteECounterLPage = 0;
static int gVerifyECounterLPage = 0;
static int gNonMediumELPage = 0;
static int gLastNErrorLPage = 0;
static int gBackgroundResultsLPage = 0;
static int gTapeAlertsLPage = 0;
static int gSeagateCacheLPage = 0;
static int gSeagateFactoryLPage = 0;
@ -83,7 +85,7 @@ static void scsiGetSupportedLogPages(int device)
{
int i, err;
if ((err = scsiLogSense(device, SUPPORTED_LPAGES, gBuf,
if ((err = scsiLogSense(device, SUPPORTED_LPAGES, 0, gBuf,
LOG_RESP_LEN, 0))) {
if (con->reportscsiioctl > 0)
pout("Log Sense for supported pages failed [%s]\n",
@ -121,6 +123,9 @@ static void scsiGetSupportedLogPages(int device)
case IE_LPAGE:
gSmartLPage = 1;
break;
case BACKGROUND_RESULTS_LPAGE:
gBackgroundResultsLPage = 1;
break;
case TAPE_ALERTS_LPAGE:
gTapeAlertsLPage = 1;
break;
@ -194,7 +199,7 @@ static int scsiGetTapeAlertsData(int device, int peripheral_type)
int failures = 0;
PRINT_ON(con);
if ((err = scsiLogSense(device, TAPE_ALERTS_LPAGE, gBuf,
if ((err = scsiLogSense(device, TAPE_ALERTS_LPAGE, 0, gBuf,
LOG_RESP_TAPE_ALERT_LEN, LOG_RESP_TAPE_ALERT_LEN))) {
pout("scsiGetTapesAlertData Failed [%s]\n", scsiErrString(err));
PRINT_OFF(con);
@ -234,44 +239,62 @@ static int scsiGetTapeAlertsData(int device, int peripheral_type)
static void scsiGetStartStopData(int device)
{
UINT32 currentStartStop;
UINT32 recommendedStartStop;
int err, len, k;
char str[6];
UINT32 u;
int err, len, k, extra, pc;
unsigned char * ucp;
if ((err = scsiLogSense(device, STARTSTOP_CYCLE_COUNTER_LPAGE, gBuf,
if ((err = scsiLogSense(device, STARTSTOP_CYCLE_COUNTER_LPAGE, 0, gBuf,
LOG_RESP_LEN, 0))) {
PRINT_ON(con);
pout("scsiGetStartStopData Failed [%s]\n", scsiErrString(err));
PRINT_OFF(con);
return;
}
if (gBuf[0] != STARTSTOP_CYCLE_COUNTER_LPAGE) {
if ((gBuf[0] & 0x3f) != STARTSTOP_CYCLE_COUNTER_LPAGE) {
PRINT_ON(con);
pout("StartStop Log Sense Failed, page mismatch\n");
PRINT_OFF(con);
return;
}
len = ((gBuf[2] << 8) | gBuf[3]) + 4;
if (len > 13) {
for (k = 0; k < 2; ++k)
str[k] = gBuf[12 + k];
str[k] = '\0';
pout("Manufactured in week %s of year ", str);
for (k = 0; k < 4; ++k)
str[k] = gBuf[8 + k];
str[k] = '\0';
pout("%s\n", str);
}
if (len > 39) {
recommendedStartStop = (gBuf[28] << 24) | (gBuf[29] << 16) |
(gBuf[30] << 8) | gBuf[31];
currentStartStop = (gBuf[36] << 24) | (gBuf[37] << 16) |
(gBuf[38] << 8) | gBuf[39];
pout("Current start stop count: %u times\n", currentStartStop);
if (0xffffffff != recommendedStartStop)
pout("Recommended maximum start stop count: %u times\n",
recommendedStartStop);
len = ((gBuf[2] << 8) | gBuf[3]);
ucp = gBuf + 4;
for (k = len; k > 0; k -= extra, ucp += extra) {
if (k < 3) {
PRINT_ON(con);
pout("StartStop Log Sense Failed: short\n");
PRINT_OFF(con);
return;
}
extra = ucp[3] + 4;
pc = (ucp[0] << 8) + ucp[1];
switch (pc) {
case 1:
if (10 == extra)
pout("Manufactured in week %.2s of year %.4s\n", ucp + 8,
ucp + 4);
break;
case 2:
/* ignore Accounting date */
break;
case 3:
if (extra > 7) {
u = (ucp[4] << 24) | (ucp[5] << 16) | (ucp[6] << 8) | ucp[7];
if (0xffffffff != u)
pout("Recommended maximum start stop count: %u times\n",
u);
}
break;
case 4:
if (extra > 7) {
u = (ucp[4] << 24) | (ucp[5] << 16) | (ucp[6] << 8) | ucp[7];
if (0xffffffff != u)
pout("Current start stop count: %u times\n", u);
}
break;
default:
/* ignore */
break;
}
}
}
@ -331,14 +354,14 @@ static void scsiPrintSeagateCacheLPage(int device)
unsigned char * xp;
uint64_t ull;
if ((err = scsiLogSense(device, SEAGATE_CACHE_LPAGE, gBuf,
if ((err = scsiLogSense(device, SEAGATE_CACHE_LPAGE, 0, gBuf,
LOG_RESP_LEN, 0))) {
PRINT_ON(con);
pout("Seagate Cache Log Sense Failed: %s\n", scsiErrString(err));
PRINT_OFF(con);
return;
}
if (gBuf[0] != SEAGATE_CACHE_LPAGE) {
if ((gBuf[0] & 0x3f) != SEAGATE_CACHE_LPAGE) {
PRINT_ON(con);
pout("Seagate Cache Log Sense Failed, page mismatch\n");
PRINT_OFF(con);
@ -406,14 +429,14 @@ static void scsiPrintSeagateFactoryLPage(int device)
unsigned char * xp;
uint64_t ull;
if ((err = scsiLogSense(device, SEAGATE_FACTORY_LPAGE, gBuf,
if ((err = scsiLogSense(device, SEAGATE_FACTORY_LPAGE, 0, gBuf,
LOG_RESP_LEN, 0))) {
PRINT_ON(con);
pout("scsiPrintSeagateFactoryLPage Failed [%s]\n", scsiErrString(err));
PRINT_OFF(con);
return;
}
if (gBuf[0] != SEAGATE_FACTORY_LPAGE) {
if ((gBuf[0] & 0x3f) != SEAGATE_FACTORY_LPAGE) {
PRINT_ON(con);
pout("Seagate/Hitachi Factory Log Sense Failed, page mismatch\n");
PRINT_OFF(con);
@ -504,17 +527,17 @@ static void scsiPrintErrorCounterLog(int device)
double processed_gb;
if (gReadECounterLPage && (0 == scsiLogSense(device,
READ_ERROR_COUNTER_LPAGE, gBuf, LOG_RESP_LEN, 0))) {
READ_ERROR_COUNTER_LPAGE, 0, gBuf, LOG_RESP_LEN, 0))) {
scsiDecodeErrCounterPage(gBuf, &errCounterArr[0]);
found[0] = 1;
}
if (gWriteECounterLPage && (0 == scsiLogSense(device,
WRITE_ERROR_COUNTER_LPAGE, gBuf, LOG_RESP_LEN, 0))) {
WRITE_ERROR_COUNTER_LPAGE, 0, gBuf, LOG_RESP_LEN, 0))) {
scsiDecodeErrCounterPage(gBuf, &errCounterArr[1]);
found[1] = 1;
}
if (gVerifyECounterLPage && (0 == scsiLogSense(device,
VERIFY_ERROR_COUNTER_LPAGE, gBuf, LOG_RESP_LEN, 0))) {
VERIFY_ERROR_COUNTER_LPAGE, 0, gBuf, LOG_RESP_LEN, 0))) {
scsiDecodeErrCounterPage(gBuf, &errCounterArr[2]);
ecp = &errCounterArr[2];
for (k = 0; k < 7; ++k) {
@ -546,7 +569,7 @@ static void scsiPrintErrorCounterLog(int device)
else
pout("\nError Counter logging not supported\n");
if (gNonMediumELPage && (0 == scsiLogSense(device,
NON_MEDIUM_ERROR_LPAGE, gBuf, LOG_RESP_LEN, 0))) {
NON_MEDIUM_ERROR_LPAGE, 0, gBuf, LOG_RESP_LEN, 0))) {
scsiDecodeNonMediumErrPage(gBuf, &nme);
if (nme.gotPC0)
pout("\nNon-medium error count: %8"PRIu64"\n", nme.counterPC0);
@ -558,12 +581,14 @@ static void scsiPrintErrorCounterLog(int device)
nme.counterPE_H);
}
if (gLastNErrorLPage && (0 == scsiLogSense(device,
LAST_N_ERROR_LPAGE, gBuf, LOG_RESP_LONG_LEN, 0))) {
LAST_N_ERROR_LPAGE, 0, gBuf, LOG_RESP_LONG_LEN, 0))) {
unsigned char * ucp;
int num, k, pc, pl;
int num, k, pc, pl, truncated;
num = (gBuf[2] << 8) + gBuf[3] + 4;
num = (num < LOG_RESP_LONG_LEN) ? num : LOG_RESP_LONG_LEN;
truncated = (num > LOG_RESP_LONG_LEN) ? num : 0;
if (truncated)
num = LOG_RESP_LONG_LEN;
ucp = gBuf + 4;
num -= 4;
if (num < 4)
@ -590,10 +615,13 @@ static void scsiPrintErrorCounterLog(int device)
pout(" Error event %d:\n", pc);
pout(" [data counter??]:\n");
dStrHex((const char *)ucp + 4, pl - 4, 1);
}
}
}
}
}
if (truncated)
pout(" >>>> log truncated, fetched %d of %d available "
"bytes\n", LOG_RESP_LONG_LEN, truncated);
}
}
}
@ -640,14 +668,14 @@ static int scsiPrintSelfTest(int device)
UINT8 * ucp;
uint64_t ull=0;
if ((err = scsiLogSense(device, SELFTEST_RESULTS_LPAGE, gBuf,
if ((err = scsiLogSense(device, SELFTEST_RESULTS_LPAGE, 0, gBuf,
LOG_RESP_SELF_TEST_LEN, 0))) {
PRINT_ON(con);
pout("scsiPrintSelfTest Failed [%s]\n", scsiErrString(err));
PRINT_OFF(con);
return FAILSMART;
}
if (gBuf[0] != SELFTEST_RESULTS_LPAGE) {
if ((gBuf[0] & 0x3f) != SELFTEST_RESULTS_LPAGE) {
PRINT_ON(con);
pout("Self-test Log Sense Failed, page mismatch\n");
PRINT_OFF(con);
@ -777,6 +805,135 @@ static int scsiPrintSelfTest(int device)
return retval;
}
static const char * bms_status[] = {
"no scans active",
"scan is active",
"pre-scan is active",
"halted due to fatal error",
"halted due to a vendor specific pattern of error",
"halted due to medium formatted without P-List",
"halted - vendor specific cause",
"halted due to temperature out of range",
"halted until BM interval timer expires", /* 8 */
};
static const char * reassign_status[] = {
"No reassignment needed",
"Require Reassign or Write command",
"Successfully reassigned",
"Reserved [0x3]",
"Failed",
"Recovered via rewrite in-place",
"Reassigned by app, has valid data",
"Reassigned by app, has no valid data",
"Unsuccessfully reassigned by app", /* 8 */
};
// See SCSI Block Commands - 3 (SBC-3) rev 6 (draft) section 6.2.2 .
// Returns 0 if ok else FAIL* bitmask. Note can have a status entry
// and up to 2048 events (although would hope to have less). May set
// FAILLOG if serious errors detected (in the future).
static int scsiPrintBackgroundResults(int device)
{
int num, j, m, err, pc, pl, truncated;
int noheader = 1;
int firstresult = 1;
int retval = 0;
UINT8 * ucp;
if ((err = scsiLogSense(device, BACKGROUND_RESULTS_LPAGE, 0, gBuf,
LOG_RESP_LONG_LEN, 0))) {
PRINT_ON(con);
pout("scsiPrintBackgroundResults Failed [%s]\n", scsiErrString(err));
PRINT_OFF(con);
return FAILSMART;
}
if ((gBuf[0] & 0x3f) != BACKGROUND_RESULTS_LPAGE) {
PRINT_ON(con);
pout("Background scan results Log Sense Failed, page mismatch\n");
PRINT_OFF(con);
return FAILSMART;
}
// compute page length
num = (gBuf[2] << 8) + gBuf[3] + 4;
if (num < 20) {
PRINT_ON(con);
pout("Background scan results Log Sense length is %d, no scan "
"status\n", num);
PRINT_OFF(con);
return FAILSMART;
}
truncated = (num > LOG_RESP_LONG_LEN) ? num : 0;
if (truncated)
num = LOG_RESP_LONG_LEN;
ucp = gBuf + 4;
num -= 4;
while (num > 3) {
pc = (ucp[0] << 8) | ucp[1];
// pcb = ucp[2];
pl = ucp[3] + 4;
switch (pc) {
case 0:
if (noheader) {
noheader = 0;
pout("\nBackground scan results log\n");
}
pout(" Status: ");
if ((pl < 16) || (num < 16)) {
pout("\n");
break;
}
j = ucp[9];
if (j < (int)(sizeof(bms_status) / sizeof(bms_status[0])))
pout("%s\n", bms_status[j]);
else
pout("unknown [0x%x] background scan status value\n", j);
j = (ucp[4] << 24) + (ucp[5] << 16) + (ucp[6] << 8) + ucp[7];
pout(" Accumulated power on time, hours:minutes %d:%02d "
"[%d minutes]\n", (j / 60), (j % 60), j);
pout(" Number of background scans performed: %d, ",
(ucp[10] << 8) + ucp[11]);
pout("scan progress: %.2f%%\n",
(double)((ucp[12] << 8) + ucp[13]) * 100.0 / 65536.0);
break;
default:
if (noheader) {
noheader = 0;
pout("\nBackground scan results log\n");
}
if (firstresult) {
firstresult = 0;
pout("\n # when lba(hex) [sk,asc,ascq] "
"reassign_status\n");
}
pout(" %3d ", pc);
if ((pl < 24) || (num < 24)) {
if (pl < 24)
pout("parameter length >= 24 expected, got %d\n", pl);
break;
}
j = (ucp[4] << 24) + (ucp[5] << 16) + (ucp[6] << 8) + ucp[7];
pout("%4d:%02d ", (j / 60), (j % 60));
for (m = 0; m < 8; ++m)
pout("%02x", ucp[16 + m]);
pout(" [%x,%x,%x] ", ucp[8] & 0xf, ucp[9], ucp[10]);
j = (ucp[8] >> 4) & 0xf;
if (j <
(int)(sizeof(reassign_status) / sizeof(reassign_status[0])))
pout("%s\n", reassign_status[j]);
else
pout("Reassign status: reserved [0x%x]\n", j);
break;
}
num -= pl;
ucp += pl;
}
if (truncated)
pout(" >>>> log truncated, fetched %d of %d available "
"bytes\n", LOG_RESP_LONG_LEN, truncated);
return retval;
}
static const char * peripheral_dt_arr[] = {
"disk",
"tape",
@ -850,8 +1007,6 @@ static int scsiGetDriveInfo(int device, UINT8 * peripheral_type, int all)
peri_dt = gBuf[0] & 0x1f;
if (peripheral_type)
*peripheral_type = peri_dt;
if (! all)
return 0;
if (len < 36) {
PRINT_ON(con);
@ -867,21 +1022,37 @@ static int scsiGetDriveInfo(int device, UINT8 * peripheral_type, int all)
memset(revision, 0, sizeof(revision));
strncpy(revision, (char *)&gBuf[32], 4);
pout("Device: %s %s Version: %s\n", manufacturer, product, revision);
if (all && (0 != strncmp(manufacturer, "ATA", 3)))
pout("Device: %s %s Version: %s\n", manufacturer, product, revision);
if (0 == strncmp(manufacturer, "3ware", 5) || 0 == strncmp(manufacturer, "AMCC", 4) ) {
#if defined(_WIN32) || defined(__CYGWIN__)
pout("please try changing device to /dev/hdX,N\n");
#else
pout("please try adding '-d 3ware,N'\n");
pout("you may also need to change device to /dev/twaN or /dev/tweN\n");
#endif
return 2;
} else if ((len >= 42) &&
(0 == strncmp((const char *)(gBuf + 36), "MVSATA", 6))) {
pout("please try '-d marvell'\n");
return 2;
} else if ((0 == con->controller_explicit) &&
(0 == strncmp(manufacturer, "ATA ", 8)) &&
has_sat_pass_through(device, 0)) {
con->controller_type = CONTROLLER_SAT;
if (con->reportscsiioctl > 0) {
PRINT_ON(con);
pout("Detected SAT interface, switch to device type 'sat'\n");
PRINT_OFF(con);
}
return 2;
} else if ((avail_len >= 96) && (0 == strncmp(manufacturer, "ATA", 3))) {
/* <<<< This is Linux specific code to detect SATA disks using a
SCSI-ATA command translation layer. This may be generalized
later when the t10.org SAT project matures. >>>> */
req_len = 96;
pout("Device: %s %s Version: %s\n", manufacturer, product, revision);
req_len = 252;
memset(gBuf, 0, req_len);
if ((err = scsiInquiryVpd(device, 0x83, gBuf, req_len))) {
PRINT_ON(con);
@ -895,11 +1066,13 @@ static int scsiGetDriveInfo(int device, UINT8 * peripheral_type, int all)
if (isLinuxLibAta(gBuf, len)) {
pout("\nIn Linux, SATA disks accessed via libata are "
"only supported by smartmontools\n"
"for kernel versions 2.6.15 and above. Try "
"an additional '-d ata' argument.\n");
"for kernel versions 2.6.15 and above.\n Try "
"an additional '-d ata' or '-d sat' argument.\n");
return 2;
}
}
if (! all)
return 0;
/* Do this here to try and detect badly conforming devices (some USB
keys) that will lock up on a InquiryVpd or log sense or ... */
@ -1188,6 +1361,19 @@ int scsiPrintMain(int fd)
if (0 != res)
failuretest(OPTIONAL_CMD, returnval|=res);
}
if (con->smartbackgroundlog) {
if (! checkedSupportedLogPages)
scsiGetSupportedLogPages(fd);
res = 0;
if (gBackgroundResultsLPage)
res = scsiPrintBackgroundResults(fd);
else {
pout("Device does not support Background scan results logging\n");
failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
}
if (0 != res)
failuretest(OPTIONAL_CMD, returnval|=res);
}
if (con->smartexeoffimmediate) {
if (scsiSmartDefaultSelfTest(fd))
return returnval | FAILSMART;

View File

@ -1,7 +1,7 @@
.ig
Copyright (C) 2002-6 Bruce Allen <smartmontools-support@lists.sourceforge.net>
$Id: smartctl.8.in,v 1.78 2006/04/12 15:45:38 ballen4705 Exp $
$Id: smartctl.8.in,v 1.86 2006/09/27 21:42:03 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
@ -63,7 +63,8 @@ SCSI Tape Drives and Changers with TapeAlert support use the devices
For SATA disks accessed with libata, use \fB"/dev/sd[a\-z]"\fP
and append \fB"\-d ata"\fP. For disks behind 3ware controllers
you may need \fB"/dev/sd[a\-z]"\fP or \fB"/dev/twe[0\-9]"\fP
or \fB"/dev/twa[0\-9]"\fP: see details below.
or \fB"/dev/twa[0\-9]"\fP: see details below. For disks behind
HighPoint RocketRAID controllers you may need \fB"/dev/sd[a\-z]"\fP.
More general paths (such as devfs ones) may also be specified.
.IP \fBDARWIN\fP: 9
Use the forms \fB/dev/disk[0\-9]\fP or equivalently \fBdisk[0\-9]\fP or equivalently
@ -83,9 +84,15 @@ 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 forms \fB"/dev/hd[a\-j]"\fP for IDE/ATA devices
"\\\\.\\PhysicalDrive[0\-9]" on WinNT4/2000/XP,
\fB"/dev/hd[a\-d]"\fP for standard IDE/ATA devices on Win95/98/98SE/ME,
"\\\\.\\PhysicalDrive[0\-9]" on WinNT4/2000/XP/2003,
and \fB"/dev/scsi[0\-9][0\-f]"\fP for SCSI devices on ASPI adapter 0\-9, ID 0\-15.
For IDE/ATA devices on Win95/98/98SE/ME, use \fB"/dev/hd[a\-d]"\fP for standard 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).
For disks behind 3ware controllers use \fB"/dev/hd[a\-j],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.
The option \'-d 3ware,N\' is not necessary on Windows.
The prefix \fB"/dev/"\fP is optional.
.IP \fBCYGWIN\fP: 9
See "WINDOWS" above.
@ -98,7 +105,7 @@ this guess
Note that the printed output of \fBsmartctl\fP displays most numerical
values in base 10 (decimal), but some values are displayed in base 16
(hexidecimal). To distinguish them, the base 16 values are always
(hexadecimal). To distinguish them, the base 16 values are always
displayed with a leading \fB"0x"\fP, for example: "0xff". This man
page follows the same convention.
@ -110,9 +117,9 @@ will execute the corresponding commands in the order: INFORMATION,
ENABLE/DISABLE, DISPLAY DATA, RUN/ABORT TESTS.
SCSI devices only accept the options \fB\-h, \-V, \-i, \-a, \-A, \-d,
\-s, \-S,\-H, \-t, \-C, \-l selftest, \-l error, \-r,\fP and
\fB\-X\fP. TapeAlert devices only accept the options \fB\-h, \-V,
\-i, \-a, \-A, \-d, \-s, \-S, \-t, \-l selftest, \-l error, \-r,\fP
\-s, \-S,\-H, \-t, \-C, \-l background, \-l error, \-l selftest, \-r,\fP
and \fB\-X\fP. TapeAlert devices only accept the options \fB\-h, \-V,
\-i, \-a, \-A, \-d, \-s, \-S, \-t, \-l error, \-l selftest, \-r,\fP
and \fB\-H\fP.
Long options are not supported on all systems. Use
@ -139,7 +146,8 @@ mode) print current user drive capacity in bytes. (If drive is has a
user protected area reserved, or is "clipped", this may be smaller
than the potential maximum drive capacity.) Indicates if the drive is
in the smartmontools database (see \'\-v\' options below). If so, the
drive model family may also be printed.
drive model family may also be printed. If \'\-n\' (see below) is
specified, the power mode of the drive is printed.
.TP
.B \-a, \-\-all
Prints all SMART information about the disk, or TapeAlert information
@ -177,9 +185,16 @@ use the exit status of \fBsmartctl\fP (see RETURN VALUES below).
.TP
.B \-d TYPE, \-\-device=TYPE
Specifies the type of the device. The valid arguments to this option
are \fIata\fP, \fIscsi\fP, \fImarvell\fP, and \fI3ware,N\fP. If this option is not
used then \fBsmartctl\fP will attempt to guess the device type from
the device name.
are \fIata\fP, \fIscsi\fP, \fIsat\fP, \fImarvell\fP, \fI3ware,N\fP, and \fIhpt,L/M\fP
or \fIhpt,L/M/N\fP. If this option is not used then \fBsmartctl\fP will attempt to
guess the device type from the device name.
The \'sat\' device type is for ATA disks that have a SCSI to ATA
Translation (SAT) Layer (SATL) between the disk and the operating system.
SAT defines two ATA PASS THROUGH SCSI commands, one 12 bytes long and
the other 16 bytes long that \fBsmartctl\fP will utilize when this device
type is selected. The default is the 16 byte variant which can be
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
@ -189,8 +204,8 @@ 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).
To look at ATA disks behind 3ware SCSI RAID controllers, use syntax
such as:
Under Linux and FreeBSD, to look at ATA disks behind 3ware SCSI RAID controllers,
use syntax such as:
.nf
\fBsmartctl \-a \-d 3ware,2 /dev/sda\fP
.fi
@ -255,7 +270,26 @@ using the character device interface /dev/twa0\-15 and /dev/twe0\-15.
The necessary WRITE LOG commands can not be passed through the SCSI
interface.
.B 3ware controllers are currently ONLY supported under Linux and FreeBSD.
.B 3ware controllers are supported under Linux, FreeBSD and Windows.
To look at (S)ATA disks behind HighPoint RocketRAID controllers, use syntax
such as:
.nf
\fBsmartctl \-a \-d hpt,1/3 /dev/sda\fP
.fi
or
.nf
\fBsmartctl \-a \-d hpt,1/2/3 /dev/sda\fP
.fi
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
the disks derived from the HighPoint RocketRAID controllers. And also
these values are limited by the model of the HighPoint RocketRAID controller.
.B HighPoint RocketRAID controllers are currently ONLY supported under Linux.
.TP
.B \-T TYPE, \-\-tolerance=TYPE
@ -347,6 +381,30 @@ the integer with no spaces. For example,
The default
level is 1, so \'\-r ataioctl,1\' and \'\-r ataioctl\' are equivalent.
.TP
.B \-n POWERMODE, \-\-nocheck=POWERMODE
Specifieds if \fBsmartctl\fP should exit before performing any checks
when the device is in a low\-power mode. It may be used to prevent a disk
from being spun\-up by \fBsmartctl\fP. The power mode is ignored by
default. The allowed values of POWERMODE are:
.I never
\- check the device always, but print the power mode if \'\-i\' is
specified.
.I sleep
\- check the device unless it is in SLEEP mode.
.I standby
\- check the device unless it is in SLEEP or STANDBY mode. In
these modes most disks are not spinning, so if you want to prevent
a disk from spinning up, this is probably what you want.
.I idle
\- check the device unless it is in SLEEP, STANDBY or IDLE mode.
In the IDLE state, most disks are still spinning, so this is probably
not what you want.
.TP
.B SMART FEATURE ENABLE/DISABLE COMMANDS:
.IP
@ -582,7 +640,8 @@ relatively free format (compared with ATA disk attributes).
.TP
.B \-l TYPE, \-\-log=TYPE
Prints either the SMART Error Log, the SMART Self\-Test Log, the SMART
Selective Self\-Test Log [ATA only], or the Log Directory [ATA only].
Selective Self\-Test Log [ATA only], the Log Directory [ATA only], or
the Background Scan Results Log [SCSI only].
The valid arguments to this option are:
.I error
@ -732,6 +791,18 @@ extended and comprehensive SMART self\-test and error logs. If your
disk supports these, and you would like to assist, please contact the
\fBsmartmontools\fP developers.]
.I background [SCSI]
\- the background scan results log outputs information derived from
Background Media Scans (BMS) done after power up and/or periodocally (e.g.
every 24 hours) on recent SCSI disks. If supported, the BMS status
is output first, indicating whether a background scan is currently
underway (and if so a progress percentage), the amount of time the disk
has been powered up and the number of scans already completed. Then there
is a header and a line for each background scan "event". These will
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 ).
.TP
.B \-v N,OPTION, \-\-vendorattribute=N,OPTION
Sets a vendor\-specific display OPTION for Attribute N. This option
@ -1149,6 +1220,20 @@ RAID 9000 controller card.
.fi
Start a short self\-test on the fourth ATA disk connected to the 3ware RAID
controller card which is the second SCSI device /dev/sdb.
.PP
.nf
.B smartctl \-a \-d hpt,1/3 /dev/sda
.fi
Examine all SMART data for the (S)ATA disk directly connected to the third channel of the
first HighPoint RocketRAID controller card.
.nf
.PP
.nf
.B smartctl \-t short \-d hpt,1/1/2 /dev/sda
.fi
Start a short self\-test on the (S)ATA disk connected to second pmport on the
first channel of the first HighPoint RocketRAID controller card.
.PP
.nf
.B smartctl \-t select,10\-100 \-t select,30\-300 \-t afterselect,on \-t pending,45 /dev/hda
.fi
@ -1284,7 +1369,7 @@ these documents may be found in the References section of the
.SH
CVS ID OF THIS PAGE:
$Id: smartctl.8.in,v 1.78 2006/04/12 15:45:38 ballen4705 Exp $
$Id: smartctl.8.in,v 1.86 2006/09/27 21:42:03 chrfranke 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

@ -1,5 +1,5 @@
/*
* smartctl.c
* smartctl.cpp
*
* Home page of code is: http://smartmontools.sourceforge.net
*
@ -50,7 +50,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.c,v 1.143 2006/04/12 14:54:28 ballen4705 Exp $"
const char* smartctl_c_cvsid="$Id: smartctl.cpp,v 1.155 2006/09/20 16:17:31 shattered 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
@ -143,13 +143,15 @@ void Usage (void){
" -q TYPE, --quietmode=TYPE (ATA)\n"
" Set smartctl quiet mode to one of: errorsonly, silent\n\n"
" -d TYPE, --device=TYPE\n"
" Specify device type to one of: ata, scsi, marvell, 3ware,N\n\n"
" Specify device type to one of: ata, scsi, marvell, sat, 3ware,N\n\n"
" -T TYPE, --tolerance=TYPE (ATA)\n"
" Tolerance: normal, conservative, permissive, verypermissive\n\n"
" -b TYPE, --badsum=TYPE (ATA)\n"
" Set action on bad checksum to one of: warn, exit, ignore\n\n"
" -r TYPE, --report=TYPE\n"
" Report transactions (see man page)\n\n"
" -n MODE, --nocheck=MODE (ATA)\n"
" No check if: never, sleep, standby, idle (see man page)\n\n"
);
#else
printf(
@ -157,7 +159,8 @@ void Usage (void){
" -d TYPE Specify device type to one of: ata, scsi, 3ware,N\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"
" -r TYPE Report transactions (see man page)\n"
" -n MODE No check if: never, sleep, standby, idle (see man page) (ATA)\n\n"
);
#endif
printf("============================== DEVICE FEATURE ENABLE/DISABLE COMMANDS =====\n\n");
@ -187,7 +190,8 @@ void Usage (void){
" -A, --attributes \n"
" Show device SMART vendor-specific Attributes and values\n\n"
" -l TYPE, --log=TYPE\n"
" Show device log. TYPE: error, selftest, selective, directory\n\n"
" Show device log. TYPE: error, selftest, selective, directory,\n"
" background\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"
@ -200,7 +204,8 @@ void Usage (void){
" -H Show device SMART health status\n"
" -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"
" -l TYPE Show device log. TYPE: error, selftest, selective, directory,\n"
" background\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"
" -P TYPE Drive-specific presets: use, ignore, show, showall (ATA)\n\n"
@ -234,7 +239,7 @@ const char *getvalidarglist(char opt) {
case 'q':
return "errorsonly, silent";
case 'd':
return "ata, scsi, marvell, 3ware,N";
return "ata, scsi, marvell, sat, 3ware,N, hpt,L/M/N";
case 'T':
return "normal, conservative, permissive, verypermissive";
case 'b':
@ -246,13 +251,15 @@ const char *getvalidarglist(char opt) {
case 'S':
return "on, off";
case 'l':
return "error, selftest, selective, directory";
return "error, selftest, selective, directory, background";
case 'P':
return "use, ignore, show, showall";
case 't':
return "offline, short, long, conveyance, select,M-N, pending,N, afterselect,on, afterselect,off";
case 'F':
return "none, samsung, samsung2";
case 'n':
return "never, sleep, standby, idle";
case 'v':
default:
return NULL;
@ -298,7 +305,7 @@ void ParseOpts (int argc, char** argv){
extern int optopt, optind, opterr;
char extraerror[256];
// Please update getvalidarglist() if you edit shortopts
const char *shortopts = "h?Vq:d:T:b:r:s:o:S:HcAl:iav:P:t:CXF:";
const char *shortopts = "h?Vq:d:T:b:r:s:o:S:HcAl:iav:P:t:CXF:n:";
#ifdef HAVE_GETOPT_LONG
char *arg;
// Please update getvalidarglist() if you edit longopts
@ -328,6 +335,7 @@ void ParseOpts (int argc, char** argv){
{ "captive", no_argument, 0, 'C' },
{ "abort", no_argument, 0, 'X' },
{ "firmwarebug", required_argument, 0, 'F' },
{ "nocheck", required_argument, 0, 'n' },
{ 0, 0, 0, 0 }
};
#endif
@ -365,15 +373,82 @@ void ParseOpts (int argc, char** argv){
}
break;
case 'd':
con->controller_explicit = 1;
if (!strcmp(optarg,"ata")) {
con->controller_type = CONTROLLER_ATA;
con->controller_type = CONTROLLER_ATA;
con->controller_port = 0;
} else if (!strcmp(optarg,"scsi")) {
con->controller_type = CONTROLLER_SCSI;
con->controller_type = CONTROLLER_SCSI;
con->controller_port = 0;
} else if (!strcmp(optarg,"marvell")) {
con->controller_type = CONTROLLER_MARVELL_SATA;
con->controller_type = CONTROLLER_MARVELL_SATA;
con->controller_port = 0;
} else if (!strncmp(optarg, "sat", 3)) {
con->controller_type = CONTROLLER_SAT;
con->controller_port = 0;
con->satpassthrulen = 0;
if (strlen(optarg) > 3) {
int k;
char * cp;
cp = strchr(optarg, ',');
if (cp && (1 == sscanf(cp + 1, "%d", &k)) &&
((0 == k) || (12 == k) || (16 == k)))
con->satpassthrulen = k;
else {
sprintf(extraerror, "Option '-d sat,<n>' requires <n> to be "
"0, 12 or 16\n");
badarg = TRUE;
}
}
} else if (!strncmp(optarg, "hpt", 3)){
unsigned char i, slash = 0;
con->hpt_data[0] = 0;
con->hpt_data[1] = 0;
con->hpt_data[2] = 0;
con->controller_type = CONTROLLER_HPT;
for (i=4; i < strlen(optarg); i++) {
if(optarg[i] == '/') {
slash++;
if(slash == 3) {
sprintf(extraerror, "Option '-d hpt,L/M/N' supports 2-3 items\n");
badarg = TRUE;
break;
}
}
else if ((optarg[i])>='0' && (optarg[i])<='9') {
if (con->hpt_data[slash]>1) { /* hpt_data[x] max 19 */
badarg = TRUE;
break;
}
con->hpt_data[slash] = con->hpt_data[slash]*10 + optarg[i] - '0';
}
else {
badarg = TRUE;
break;
}
}
if (slash == 0) {
sprintf(extraerror, "Option '-d hpt,L/M/N' requires 2-3 items\n");
badarg = TRUE;
} else if (badarg != TRUE) {
if (con->hpt_data[0]==0 || con->hpt_data[0]>8){
sprintf(extraerror, "Option '-d hpt,L/M/N' no/invalid controller id L supplied\n");
badarg = TRUE;
}
if (con->hpt_data[1]==0 || con->hpt_data[1]>8){
sprintf(extraerror, "Option '-d hpt,L/M/N' no/invalid channel number M supplied\n");
badarg = TRUE;
}
if (slash==2) {
if ( con->hpt_data[2]==0 || con->hpt_data[2]>15) {
sprintf(extraerror, "Option '-d hpt,L/M/N' no/invalid pmport number N supplied\n");
badarg = TRUE;
}
} else {
con->hpt_data[2]=1;
}
}
} else {
// look for RAID-type device
int i;
@ -394,7 +469,7 @@ void ParseOpts (int argc, char** argv){
badarg = TRUE;
} else {
// NOTE: controller_port == disk number + 1
con->controller_type = CONTROLLER_3WARE;
con->controller_type = CONTROLLER_3WARE;
con->controller_port = i+1;
}
free(s);
@ -518,6 +593,8 @@ void ParseOpts (int argc, char** argv){
con->selectivetestlog = TRUE;
} else if (!strcmp(optarg,"directory")) {
con->smartlogdirectory = TRUE;
} else if (!strcmp(optarg,"background")) {
con->smartbackgroundlog = TRUE;
} else {
badarg = TRUE;
}
@ -533,6 +610,7 @@ void ParseOpts (int argc, char** argv){
con->smarterrorlog = TRUE;
con->smartselftestlog = TRUE;
con->selectivetestlog = TRUE;
/* con->smartbackgroundlog = TRUE; */
break;
case 'v':
// parse vendor-specific definitions of attributes
@ -643,6 +721,19 @@ void ParseOpts (int argc, char** argv){
con->smartselftestabort = TRUE;
con->testcase = ABORT_SELF_TEST;
break;
case 'n':
// skip disk check if in low-power mode
if (!strcmp(optarg, "never"))
con->powermode = 1; // do not skip, but print mode
else if (!strcmp(optarg, "sleep"))
con->powermode = 2;
else if (!strcmp(optarg, "standby"))
con->powermode = 3;
else if (!strcmp(optarg, "idle"))
con->powermode = 4;
else
badarg = TRUE;
break;
case 'h':
con->dont_print=FALSE;
printslogan();
@ -781,7 +872,7 @@ void ParseOpts (int argc, char** argv){
// values. This means the objects of type char or short int (whether
// signed or not) are promoted to either int or unsigned int, as
// appropriate.]
void pout(char *fmt, ...){
void pout(const char *fmt, ...){
va_list ap;
// initialize variable argument list
@ -798,9 +889,9 @@ void pout(char *fmt, ...){
return;
}
// This function is used by utility.c to report LOG_CRIT errors.
// This function is used by utility.cpp to report LOG_CRIT errors.
// The smartctl version prints to stdout instead of syslog().
void PrintOut(int priority, char *fmt, ...) {
void PrintOut(int priority, const char *fmt, ...) {
va_list ap;
// avoid warning message about unused variable from gcc -W: just
@ -848,6 +939,7 @@ int main (int argc, char **argv){
// set up mode for open() call. SCSI case is:
switch (con->controller_type) {
case CONTROLLER_SCSI:
case CONTROLLER_SAT:
mode="SCSI";
break;
case CONTROLLER_3WARE_9000_CHAR:
@ -886,6 +978,8 @@ int main (int argc, char **argv){
break;
case CONTROLLER_SCSI:
retval = scsiPrintMain(fd);
if ((0 == retval) && (CONTROLLER_SAT == con->controller_type))
retval = ataPrintMain(fd);
break;
default:
retval = ataPrintMain(fd);

View File

@ -25,7 +25,7 @@
#ifndef SMARTCTL_H_
#define SMARTCTL_H_
#define SMARTCTL_H_CVSID "$Id: smartctl.h,v 1.23 2006/04/12 14:54:28 ballen4705 Exp $\n"
#define SMARTCTL_H_CVSID "$Id: smartctl.h,v 1.24 2006/07/20 20:59:45 chrfranke Exp $\n"
/* Boolean Values */
#define TRUE 0x01
@ -39,6 +39,9 @@
// device open failed
#define FAILDEV (0x01<<1)
// device is in low power mode and -n option requests to exit
#define FAILPOWER (0x01<<1)
// read device identity (ATA only) failed
#define FAILID (0x01<<1)

View File

@ -1,7 +1,7 @@
.ig
Copyright (C) 2002-6 Bruce Allen <smartmontools-support@lists.sourceforge.net>
$Id: smartd.8.in,v 1.100 2006/04/12 13:55:44 ballen4705 Exp $
$Id: smartd.8.in,v 1.106 2006/09/27 21:42:03 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
@ -107,6 +107,10 @@ 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,
and \fB"/dev/scsi[0-9][0-7]"\fP (ASPI adapter 0-9, ID 0-7) for SCSI
devices on all versions of Windows.
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 \fBCYGWIN\fP: 9
See "WINDOWS" above.
.IP \fBOS/2,eComStation\fP: 9
@ -340,7 +344,7 @@ equivalent.
.B \-\-service
Cygwin and Windows only: Enables \fBsmartd\fP to run as a Windows service.
On Cygwin, this option simply prevents fork'ing into background mode to
On Cygwin, this option simply prevents forking into background mode to
allow running \fBsmartd\fP as service via cygrunsrv, see NOTES below.
On Windows, this option enables the buildin service support.
@ -479,7 +483,11 @@ Section below!
.B # This is an example smartd startup config file
.B # /usr/local/etc/smartd.conf for monitoring three
.B # ATA disks, three SCSI disks, six ATA disks
.B # behind two 3ware controllers and one SATA disk
.B # behind two 3ware controllers, three SATA disks
.B # directly connected to the highpoint rocket-
.B # raid controller, two SATA disks connected to
.B # the highpoint controller via a pmport device
.B # and one SATA disk.
.B #
.nf
.B # First ATA disk on two different interfaces. On
@ -528,6 +536,21 @@ Section below!
.B \ \ /dev/twa0 -d 3ware,1 -a -s L/../../7/02
.B #
.nf
.B # Three SATA disks on a highpoint rocketraid controller.
.B # Start short self-tests daily between 1-2, 2-3, and
.B # 3-4 am.
.B \ \ /dev/sde -d hpt,1/1 -a -s S/../.././01
.B \ \ /dev/sde -d hpt,1/2 -a -s S/../.././02
.B \ \ /dev/sde -d hpt,1/3 -a -s S/../.././03
.B #
.nf
.B # Two SATA disks connected to a highpoint rocketraid
.B # via a pmport device. Start long self-tests Sundays
.B # between midnight and 1am and 2-3 am
.B \ \ /dev/sde -d hpt,1/4/1 -a -s L/../../7/00
.B \ \ /dev/sde -d hpt,1/4/2 -a -s L/../../7/02
.B #
.nf
.B # The following line enables monitoring of the
.B # ATA Error Log and the Self-Test Error Log.
.B # It also tracks changes in both Prefailure
@ -595,7 +618,7 @@ directives can be used for these disks (but see note below).
.TP
.B \-d TYPE
Specifies the type of the device. This Directive may be used multiple
times for one device, but the arguments \fIata\fP, \fIscsi\fP,
times for one device, but the arguments \fIata\fP, \fIscsi\fP, \fIsat\fP,
\fImarvell\fP, and \fI3ware,N\fP are mutually-exclusive. If more than
one is given then \fBsmartd\fP will use the last one which appears.
@ -620,6 +643,18 @@ from issuing SCSI commands to an ATA device.
\fBsmartd\fP
from issuing ATA commands to a SCSI device.
.I sat
\- the device type is SCSI to ATA Translation (SAT).
\fBsmartd\fP
will generate ATA (smart) commands and then package them in
the SAT defined ATA PASS THROUGH SCSI commands. The commands
are then routed through the SCSI pass through interface to the
operating system. There are two types of ATA PASS THROUGH
SCSI commands: a 12 byte and 16 byte variant.
\fBsmartd\fP
can use either and defaults to the 16 byte variant. This can
be overridden with this syntax: \'\-d sat,12\' or \'\-d sat,16\'.
.I marvell
\- Under Linux, interact with SATA disks behind Marvell chip-set
controllers (using the Marvell rather than libata driver).
@ -667,6 +702,19 @@ controllers).
.B 3ware controllers are currently ONLY supported under Linux.
.I hpt,L/M/N
\- the device consists of one or more ATA disks connected to a HighPoint
RocketRAID controller. 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. And also these
values are limited by the model of the HighPoint RocketRAID controller.
In log files and email messages this disk will be identified as
hpt_X/X/X and X/X/X is the same as L/M/N, note if no N indicated, N set
to the default value 1.
.B HighPoint RocketRAID controllers are currently ONLY supported under Linux.
.I removable
\- the device or its media is removable. This indicates to
\fBsmartd\fP
@ -721,6 +769,9 @@ this is probably what you want.
In the IDLE state, most disks are still spinning, so this is probably
not what you want.
When a self test is scheduled (see \'\-s\' Directive below), the
\'\fB\-n\fP\' Directive is ignored, and all tests are carried out.
When a periodic test is skipped, \fBsmartd\fP normally writes an
informal log message. The message can be suppressed by appending
the option \',q\' to POWERMODE (like \'\-n standby,q\').
@ -1030,13 +1081,15 @@ is set to the argument of \-M exec, if present or else to \'mail\'
.IP \fBSMARTD_DEVICE\fP 4
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). Here
N=0,...,15 denotes the ATA disk behind a 3ware RAID controller.
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
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
scsi, this is the same as SMARTD_DEVICE. For 3ware RAID controllers,
the form used is \'/dev/sdc [3ware_disk_01]\'. In this case the device
string contains a space and is NOT quoted. So to use
the form used is \'/dev/sdc [3ware_disk_01]\'. For HighPoint RocketRAID
controller, the form is \'/dev/sdd [hpt_1/1/1]\'. In these cases the
device string contains a space and is NOT quoted. So to use
$SMARTD_DEVICESTRING in a bash script you should probably enclose it
in double quotes.
.IP \fBSMARTD_FAILTYPE\fP 4
@ -1276,6 +1329,41 @@ to know, because if you have data stored in this disk sector, and you
need to read it, the read will fail. Please see the previous \'\-C\'
option for more details.
.TP
.B \-W DIFF[,INFO[,CRIT]]
Report if the current temperature had changed by at least \fBDIFF\fP
degrees since last report. Report or Warn if the temperature is greater
or equal than one of \fBINFO\fP or \fBCRIT\fP degrees Celsius. If the
limit \fBCRIT\fP is reached, a message with loglevel
\fB\'LOG_CRITICAL\'\fP will be logged to syslog and a warning email
will be send if '-m' is specified. If only the limit \fBINFO\fP is
reached, a message with loglevel \fB\'LOG_INFO\'\fP will be logged.
To disable any of the 3 reports, set the corresponding limit to 0.
Trailing zero arguments may be omitted. By default, all temperature
reports are disabled (\'-W 0\').
To track temperature changes of at least 2 degrees, use:
.nf
\fB \-W 2
.fi
To log informal messages on temperatures of at least 40 degrees, use:
.nf
\fB \-W 0,40
.fi
For warning messages/mails on temperatures of at least 45 degrees, use:
.nf
\fB \-W 0,0,45
.fi
To combine all of the above reports, use:
.nf
\fB \-W 2,40,45
.fi
For ATA devices, smartd interprets Attribute 194 as Temperature Celsius
by default. This can be changed to Attribute 9 or 220 by the drive
database or by the \'-v\' directive, see below.
.TP
.B \-F TYPE
[ATA only] Modifies the behavior of \fBsmartd\fP to compensate for
@ -1841,4 +1929,4 @@ smartmontools home page at \fBhttp://smartmontools.sourceforge.net/#references\f
.SH
CVS ID OF THIS PAGE:
$Id: smartd.8.in,v 1.100 2006/04/12 13:55:44 ballen4705 Exp $
$Id: smartd.8.in,v 1.106 2006/09/27 21:42:03 chrfranke Exp $

View File

@ -2,7 +2,7 @@
# Home page is: http://smartmontools.sourceforge.net
# $Id: smartd.conf,v 1.40 2006/04/12 14:00:12 ballen4705 Exp $
# $Id: smartd.conf,v 1.42 2006/09/15 08:01:20 sxzzsf Exp $
# smartd will re-read the configuration file if it receives a HUP
# signal
@ -32,15 +32,21 @@ DEVICESCAN
# changes in all attributes except for attribute 194
#/dev/hdb -H -l error -l selftest -t -I 194
# Monitor all attributes except normalized Temperature (usually 194),
# but track Temperature changes >= 4 Celsius, report Temperatures
# >= 45 Celsius and changes in Raw value of Reallocated_Sector_Ct (5).
# Send mail on SMART failures or when Temperature is >= 55 Celsius.
#/dev/hdc -a -I 194 -W 4,45,55 -R 5 -m admin@example.com
# Linux-specific example: monitor a SATA (Serial ATA) disk which uses
# the libata driver. This requires a Linux 2.6.15 or later kernel.
# Note that the disk is addressed via a SCSI device, but the
# underlying disk type is actually ATA
# /dev/sda -a -d ata
#/dev/sda -a -d ata
# A very silent check. Only report SMART health status if it fails
# But send an email in this case
#/dev/hdc -H -m admin@example.com
#/dev/hdc -H -C 0 -U 0 -m admin@example.com
# First two SCSI disks. This will monitor everything that smartd can
# monitor. Start extended self-tests Wednesdays between 6-7pm and
@ -64,10 +70,21 @@ DEVICESCAN
#/dev/twa0 -d 3ware,0 -a -s L/../../2/01
#/dev/twa0 -d 3ware,1 -a -s L/../../2/03
# Monitor 3 ATA disks directly connected to a HighPoint RocketRAID. Start long
# self-tests Sundays between 1-2, 2-3, and 3-4 am.
#/dev/sdd -d hpt,1/1 -a -s L/../../7/01
#/dev/sdd -d hpt,1/2 -a -s L/../../7/02
#/dev/sdd -d hpt,1/3 -a -s L/../../7/03
# Monitor 2 ATA disks connected to the same PMPort which connected to the
# HighPoint RocketRAID. Start long self-tests Tuesdays between 1-2 and 3-4 am
#/dev/sdd -d hpt,1/4/1 -a -s L/../../2/01
#/dev/sdd -d hpt,1/4/2 -a -s L/../../2/03
# HERE IS A LIST OF DIRECTIVES FOR THIS CONFIGURATION FILE.
# PLEASE SEE THE smartd.conf MAN PAGE FOR DETAILS
#
# -d TYPE Set the device type: ata, scsi, marvell, removable, 3ware,N
# -d TYPE Set the device type: ata, scsi, marvell, removable, 3ware,N, hpt,L/M/N
# -T TYPE set the tolerance to one of: normal, permissive
# -o VAL Enable/disable automatic offline tests (on/off)
# -S VAL Enable/disable attribute autosave (on/off)
@ -87,6 +104,7 @@ DEVICESCAN
# -I ID Ignore Attribute ID for -p, -u or -t Directive
# -C ID Report if Current Pending Sector count non-zero
# -U ID Report if Offline Uncorrectable count non-zero
# -W D,I,C Monitor Temperature D)ifference, I)nformal limit, C)ritical limit
# -v N,ST Modifies labeling of Attribute N (see man page)
# -a Default: equivalent to -H -f -t -l error -l selftest -C 197 -U 198
# -F TYPE Use firmware bug workaround. Type is one of: none, samsung

View File

@ -1,7 +1,7 @@
.ig
Copyright (C) 2002-6 Bruce Allen <smartmontools-support@lists.sourceforge.net>
$Id: smartd.conf.5.in,v 1.73 2006/04/12 14:03:14 ballen4705 Exp $
$Id: smartd.conf.5.in,v 1.77 2006/09/15 08:01:20 sxzzsf 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
@ -118,7 +118,11 @@ Section below!
.B # This is an example smartd startup config file
.B # /usr/local/etc/smartd.conf for monitoring three
.B # ATA disks, three SCSI disks, six ATA disks
.B # behind two 3ware controllers and one SATA disk
.B # behind two 3ware controllers, three SATA disks
.B # directly connected to the highpoint rocket-
.B # raid controller, two SATA disks connected to
.B # the highpoint rocketraid controller via a pmport
.B # device and one SATA disk.
.B #
.nf
.B # First ATA disk on two different interfaces. On
@ -167,6 +171,21 @@ Section below!
.B \ \ /dev/twa0 -d 3ware,1 -a -s L/../../7/02
.B #
.nf
.B # Three SATA disks on a highpoint rocketraid controller.
.B # Start short self-tests daily between 1-2, 2-3, and
.B # 3-4 am.
.B \ \ /dev/sde -d hpt,1/1 -a -s S/../.././01
.B \ \ /dev/sde -d hpt,1/2 -a -s S/../.././02
.B \ \ /dev/sde -d hpt,1/3 -a -s S/../.././03
.B #
.nf
.B # Two SATA disks connected to a highpoint rocketraid
.B # via a pmport device. Start long self-tests Sundays
.B # between midnight and 1am and 2-3 am.
.B \ \ /dev/sde -d hpt,1/4/1 -a -s L/../../7/00
.B \ \ /dev/sde -d hpt,1/4/2 -a -s L/../../7/02
.B #
.nf
.B # The following line enables monitoring of the
.B # ATA Error Log and the Self-Test Error Log.
.B # It also tracks changes in both Prefailure
@ -234,7 +253,7 @@ directives can be used for these disks (but see note below).
.TP
.B \-d TYPE
Specifies the type of the device. This Directive may be used multiple
times for one device, but the arguments \fIata\fP, \fIscsi\fP,
times for one device, but the arguments \fIata\fP, \fIscsi\fP, \fIsat\fP,
\fImarvell\fP, and \fI3ware,N\fP are mutually-exclusive. If more than
one is given then \fBsmartd\fP will use the last one which appears.
@ -259,6 +278,18 @@ from issuing SCSI commands to an ATA device.
\fBsmartd\fP
from issuing ATA commands to a SCSI device.
.I sat
\- the device type is SCSI to ATA Translation (SAT).
\fBsmartd\fP
will generate ATA (smart) commands and then package them in
the SAT defined ATA PASS THROUGH SCSI commands. The commands
are then routed through the SCSI pass through interface to the
operating system. There are two types of ATA PASS THROUGH
SCSI commands: a 12 byte and 16 byte variant.
\fBsmartd\fP
can use either and defaults to the 16 byte variant. This can
be overridden with this syntax: \'\-d sat,12\' or \'\-d sat,16\'.
.I marvell
\- Under Linux, interact with SATA disks behind Marvell chip-set
controllers (using the Marvell rather than libata driver).
@ -306,6 +337,19 @@ controllers).
.B 3ware controllers are currently ONLY supported under Linux.
.I hpt,L/M/N
\- the device consists of one or more ATA disks connected to a HighPoint
RocketRAID controller. 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. And also these
values are limited by the model of the HighPoint RocketRAID controller.
In log files and email messages this disk will be identified as
hpt_X/X/X and X/X/X is the same as L/M/N, note if no N indicated, N set
to the default value 1.
.B HighPoint RocketRAID controllers are currently ONLY supported under Linux.
.I removable
\- the device or its media is removable. This indicates to
\fBsmartd\fP
@ -360,6 +404,9 @@ this is probably what you want.
In the IDLE state, most disks are still spinning, so this is probably
not what you want.
When a self test is scheduled (see \'\-s\' Directive below), the
\'\fB\-n\fP\' Directive is ignored, and all tests are carried out.
When a periodic test is skipped, \fBsmartd\fP normally writes an
informal log message. The message can be suppressed by appending
the option \',q\' to POWERMODE (like \'\-n standby,q\').
@ -669,13 +716,15 @@ is set to the argument of \-M exec, if present or else to \'mail\'
.IP \fBSMARTD_DEVICE\fP 4
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). Here
N=0,...,15 denotes the ATA disk behind a 3ware RAID controller.
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
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
scsi, this is the same as SMARTD_DEVICE. For 3ware RAID controllers,
the form used is \'/dev/sdc [3ware_disk_01]\'. In this case the device
string contains a space and is NOT quoted. So to use
the form used is \'/dev/sdc [3ware_disk_01]\'. For HighPoint RocketRAID
controller, the form is \'/dev/sdd [hpt_1/1/1]\'. In these cases the
device string contains a space and is NOT quoted. So to use
$SMARTD_DEVICESTRING in a bash script you should probably enclose it
in double quotes.
.IP \fBSMARTD_FAILTYPE\fP 4
@ -915,6 +964,41 @@ to know, because if you have data stored in this disk sector, and you
need to read it, the read will fail. Please see the previous \'\-C\'
option for more details.
.TP
.B \-W DIFF[,INFO[,CRIT]]
Report if the current temperature had changed by at least \fBDIFF\fP
degrees since last report. Report or Warn if the temperature is greater
or equal than one of \fBINFO\fP or \fBCRIT\fP degrees Celsius. If the
limit \fBCRIT\fP is reached, a message with loglevel
\fB\'LOG_CRITICAL\'\fP will be logged to syslog and a warning email
will be send if '-m' is specified. If only the limit \fBINFO\fP is
reached, a message with loglevel \fB\'LOG_INFO\'\fP will be logged.
To disable any of the 3 reports, set the corresponding limit to 0.
Trailing zero arguments may be omitted. By default, all temperature
reports are disabled (\'-W 0\').
To track temperature changes of at least 2 degrees, use:
.nf
\fB \-W 2
.fi
To log informal messages on temperatures of at least 40 degrees, use:
.nf
\fB \-W 0,40
.fi
For warning messages/mails on temperatures of at least 45 degrees, use:
.nf
\fB \-W 0,0,45
.fi
To combine all of the above reports, use:
.nf
\fB \-W 2,40,45
.fi
For ATA devices, smartd interprets Attribute 194 as Temperature Celsius
by default. This can be changed to Attribute 9 or 220 by the drive
database or by the \'-v\' directive, see below.
.TP
.B \-F TYPE
[ATA only] Modifies the behavior of \fBsmartd\fP to compensate for
@ -1250,4 +1334,4 @@ SEE ALSO:
.SH
CVS ID OF THIS PAGE:
$Id: smartd.conf.5.in,v 1.73 2006/04/12 14:03:14 ballen4705 Exp $
$Id: smartd.conf.5.in,v 1.77 2006/09/15 08:01:20 sxzzsf Exp $

View File

@ -67,7 +67,7 @@ typedef int pid_t;
#ifdef __CYGWIN__
// From <windows.h>:
// BOOL WINAPI FreeConsole(void);
int __stdcall FreeConsole(void);
extern "C" int __stdcall FreeConsole(void);
#include <io.h> // setmode()
#endif // __CYGWIN__
@ -106,23 +106,23 @@ int __stdcall FreeConsole(void);
#endif // _WIN32
#if defined (__SVR4) && defined (__sun)
int getdomainname(char *, int); /* no declaration in header files! */
extern "C" int getdomainname(char *, int); // no declaration in header files!
#endif
#define ARGUSED(x) ((void)(x))
// These are CVS identification information for *.c and *.h files
// These are CVS identification information for *.cpp and *.h 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.c,v 1.362 2006/04/12 16:18:57 ballen4705 Exp $";
static const char *filenameandversion="$Id: smartd.cpp,v 1.378 2006/09/20 16:17:31 shattered 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.c,v 1.362 2006/04/12 16:18:57 ballen4705 Exp $"
const char *smartd_c_cvsid="$Id: smartd.cpp,v 1.378 2006/09/20 16:17:31 shattered Exp $"
ATACMDS_H_CVSID ATAPRINT_H_CVSID CONFIG_H_CVSID
#ifdef DAEMON_WIN32_H_CVSID
DAEMON_WIN32_H_CVSID
@ -271,20 +271,20 @@ cfgfile **AllocateMoreSpace(cfgfile **oldarray, int *oldsize, char *listname){
// Perhaps increase in the future.
const int BLOCKSIZE=8;
int i;
int old = *oldsize;
int new = old + BLOCKSIZE;
cfgfile **newptr=realloc(oldarray, new*sizeof(cfgfile *));
int olds = *oldsize;
int news = olds + BLOCKSIZE;
cfgfile **newptr=(cfgfile **)realloc(oldarray, news*sizeof(cfgfile *));
// did we get more space?
if (newptr) {
// clear remaining entries ala calloc()
for (i=old; i<new; i++)
for (i=olds; i<news; i++)
newptr[i]=NULL;
bytes += BLOCKSIZE*sizeof(cfgfile *);
*oldsize=new;
*oldsize=news;
#if 0
PrintOut(LOG_INFO, "allocating %d slots for %s\n", BLOCKSIZE, listname);
@ -533,7 +533,8 @@ void MailWarning(cfgfile *cfg, int which, char *fmt, ...){
"FailedReadSmartSelfTestLog", // 8
"FailedOpenDevice", // 9
"CurrentPendingSector", // 10
"OfflineUncorrectableSector" // 11
"OfflineUncorrectableSector", // 11
"Temperature" // 12
};
char *address, *executable;
@ -544,7 +545,7 @@ void MailWarning(cfgfile *cfg, int which, char *fmt, ...){
#else
char stdinbuf[1024]; int boxmsgoffs, boxtype;
#endif
char *newadd=NULL, *newwarn=NULL;
const char *newadd=NULL, *newwarn=NULL;
const char *unknown="[Unknown]";
// See if user wants us to send mail
@ -722,6 +723,21 @@ void MailWarning(cfgfile *cfg, int which, char *fmt, ...){
case CONTROLLER_SCSI:
exportenv(environ_strings[8], "SMARTD_DEVICETYPE", "scsi");
exportenv(environ_strings[9], "SMARTD_DEVICE", cfg->name);
case CONTROLLER_SAT:
exportenv(environ_strings[8], "SMARTD_DEVICETYPE", "sat");
exportenv(environ_strings[9], "SMARTD_DEVICE", cfg->name);
case CONTROLLER_HPT:
{
char *s,devicetype[16];
sprintf(devicetype, "hpt,%d/%d/%d", cfg->hpt_data[0],
cfg->hpt_data[1], cfg->hpt_data[2]);
exportenv(environ_strings[8], "SMARTD_DEVICETYPE", devicetype);
if ((s=strchr(cfg->name, ' ')))
*s='\0';
exportenv(environ_strings[9], "SMARTD_DEVICE", cfg->name);
if (s)
*s=' ';
}
}
snprintf(fullmessage, 1024,
@ -903,7 +919,7 @@ void MailWarning(cfgfile *cfg, int which, char *fmt, ...){
// values. This means the objects of type char or short int (whether
// signed or not) are promoted to either int or unsigned int, as
// appropriate.]
void pout(char *fmt, ...){
void pout(const char *fmt, ...){
va_list ap;
// get the correct time in syslog()
@ -930,8 +946,8 @@ void pout(char *fmt, ...){
}
// This function prints either to stdout or to the syslog as needed.
// This function is also used by utility.c to report LOG_CRIT errors.
void PrintOut(int priority,char *fmt, ...){
// This function is also used by utility.cpp to report LOG_CRIT errors.
void PrintOut(int priority, const char *fmt, ...){
va_list ap;
// get the correct time in syslog()
@ -1074,7 +1090,7 @@ void PrintHead(){
void Directives() {
PrintOut(LOG_INFO,
"Configuration file (%s) Directives (after device name):\n"
" -d TYPE Set the device type: ata, scsi, marvell, removable, 3ware,N\n"
" -d TYPE Set the device type: ata, scsi, marvell, removable, sat, 3ware,N, hpt,L/M/N\n"
" -T TYPE Set the tolerance to one of: normal, permissive\n"
" -o VAL Enable/disable automatic offline tests (on/off)\n"
" -S VAL Enable/disable attribute autosave (on/off)\n"
@ -1094,6 +1110,7 @@ void Directives() {
" -I ID Ignore Attribute ID for -p, -u or -t Directive\n"
" -C ID Monitor Current Pending Sectors in Attribute ID\n"
" -U ID Monitor Offline Uncorrectable Sectors in Attribute ID\n"
" -W D,I,C Monitor Temperature D)ifference, I)nformal limit, C)ritical limit\n"
" -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"
@ -1191,7 +1208,7 @@ static int OpenDevice(char *device, char *mode, int scanning) {
char *s=device;
// If there is an ASCII "space" character in the device name,
// terminate string there. This is for 3ware devices only.
// terminate string there. This is for 3ware and highpoint devices only.
if ((s=strchr(device,' ')))
*s='\0';
@ -1210,8 +1227,8 @@ static int OpenDevice(char *device, char *mode, int scanning) {
// If no debug and scanning - don't print errors
if (debugmode || !scanning) {
if (errno==ENOENT || errno==ENOTDIR)
errno=ENODEV;
errno=ENODEV;
PrintOut(LOG_INFO,"Device: %s, %s, open() failed\n",
device, strerror(errno));
}
@ -1271,6 +1288,7 @@ int ATADeviceScan(cfgfile *cfg, int scanning){
case CONTROLLER_ATA:
case CONTROLLER_3WARE_678K:
case CONTROLLER_MARVELL_SATA:
case CONTROLLER_HPT:
case CONTROLLER_UNKNOWN:
mode="ATA";
break;
@ -1280,6 +1298,9 @@ int ATADeviceScan(cfgfile *cfg, int scanning){
case CONTROLLER_3WARE_9000_CHAR:
mode="ATA_3WARE_9000";
break;
case CONTROLLER_SAT:
mode="SCSI";
break;
default:
// not a recognized ATA or SATA device. We should never enter
// this branch.
@ -1294,8 +1315,13 @@ int ATADeviceScan(cfgfile *cfg, int scanning){
// pass user settings on to low-level ATA commands
con->controller_port=cfg->controller_port;
con->hpt_data[0]=cfg->hpt_data[0];
con->hpt_data[1]=cfg->hpt_data[1];
con->hpt_data[2]=cfg->hpt_data[2];
con->controller_type=cfg->controller_type;
con->controller_explicit=cfg->controller_explicit;
con->fixfirmwarebug = cfg->fixfirmwarebug;
con->satpassthrulen = cfg->satpassthrulen;
// Get drive identity structure
if ((retid=ataReadHDIdentity (fd,&drive))){
@ -1392,7 +1418,7 @@ int ATADeviceScan(cfgfile *cfg, int scanning){
// but sadly not for ATA-5. Sigh.
// do we need to retain SMART data after returning from this routine?
retainsmartdata=cfg->usagefailed || cfg->prefail || cfg->usage;
retainsmartdata=cfg->usagefailed || cfg->prefail || cfg->usage || cfg->tempdiff || cfg->tempinfo || cfg->tempcrit;
// do we need to get SMART data?
if (retainsmartdata || cfg->autoofflinetest || cfg->selftest || cfg->errorlog || cfg->pending!=DONT_MONITOR_UNC) {
@ -1411,11 +1437,12 @@ int ATADeviceScan(cfgfile *cfg, int scanning){
ataReadSmartThresholds (fd,cfg->smartthres)){
PrintOut(LOG_INFO,"Device: %s, Read SMART Values and/or Thresholds Failed\n",name);
retainsmartdata=cfg->usagefailed=cfg->prefail=cfg->usage=0;
cfg->tempdiff = cfg->tempinfo = cfg->tempcrit = 0;
cfg->pending=DONT_MONITOR_UNC;
}
// see if the necessary Attribute is there to monitor offline or
// current pending sectors
// current pending sectors or temperature
TranslatePending(cfg->pending, &currentpending, &offlinepending);
if (currentpending && ATAReturnAttributeRawValue(currentpending, cfg->smartval)<0) {
@ -1431,12 +1458,18 @@ int ATADeviceScan(cfgfile *cfg, int scanning){
cfg->pending &= 0x00ff;
cfg->pending |= OFF_UNC_DEFAULT<<8;
}
if ( (cfg->tempdiff || cfg->tempinfo || cfg->tempcrit)
&& !ATAReturnTemperatureValue(cfg->smartval, cfg->attributedefs)) {
PrintOut(LOG_CRIT, "Device: %s, can't monitor Temperature, ignoring -W Directive\n", name);
cfg->tempdiff = cfg->tempinfo = cfg->tempcrit = 0;
}
}
// enable/disable automatic on-line testing
if (cfg->autoofflinetest){
// is this an enable or disable request?
char *what=(cfg->autoofflinetest==1)?"disable":"enable";
const char *what=(cfg->autoofflinetest==1)?"disable":"enable";
if (!cfg->smartval)
PrintOut(LOG_INFO,"Device: %s, could not %s SMART Automatic Offline Testing.\n",name, what);
else {
@ -1521,8 +1554,9 @@ int ATADeviceScan(cfgfile *cfg, int scanning){
}
// If no tests available or selected, return
if (!(cfg->errorlog || cfg->selftest || cfg->smartcheck ||
cfg->usagefailed || cfg->prefail || cfg->usage)) {
if (!(cfg->errorlog || cfg->selftest || cfg->smartcheck ||
cfg->usagefailed || cfg->prefail || cfg->usage ||
cfg->tempdiff || cfg->tempinfo || cfg->tempcrit )) {
CloseDevice(fd, name);
return 3;
}
@ -1578,7 +1612,7 @@ static int SCSIFilterKnown(int fd, char * device)
/* <<<< This is Linux specific code to detect SATA disks using a
SCSI-ATA command translation layer. This may be generalized
later when the t10.org SAT project matures. >>>> */
req_len = 96;
req_len = 252;
memset(di_buff, 0, req_len);
if (scsiInquiryVpd(fd, 0x83, (unsigned char *)di_buff, req_len)) {
return 0; // guess it is normal device
@ -1587,8 +1621,9 @@ static int SCSIFilterKnown(int fd, char * device)
len = (avail_len < req_len) ? avail_len : req_len;
if (isLinuxLibAta((unsigned char *)di_buff, len)) {
PrintOut(LOG_INFO, "Device %s: SATA disks accessed via libata are "
"supported by Linux kernel versions 2.6.15-rc1 and above.\n"
"Try adding '-d ata' to the smartd.conf config file line.\n", device);
"supported by Linux\nkernel versions 2.6.15-rc1 and above. "
"Try adding '-d ata' or\n'-d sat' to the smartd.conf "
"config file line.\n", device);
return 1;
}
}
@ -1674,7 +1709,7 @@ static int SCSIDeviceScan(cfgfile *cfg, int scanning) {
// Flag that certain log pages are supported (information may be
// available from other sources).
if (0 == scsiLogSense(fd, SUPPORTED_LPAGES, tBuf, sizeof(tBuf), 0)) {
if (0 == scsiLogSense(fd, SUPPORTED_LPAGES, 0, tBuf, sizeof(tBuf), 0)) {
for (k = 4; k < tBuf[3] + LOGPAGEHDRSIZE; ++k) {
switch (tBuf[k]) {
case TEMPERATURE_LPAGE:
@ -1711,6 +1746,10 @@ static int SCSIDeviceScan(cfgfile *cfg, int scanning) {
&asc, &ascq, &currenttemp, &triptemp)) {
PrintOut(LOG_INFO, "Device: %s, unexpectedly failed to read SMART values\n", device);
cfg->SuppressReport = 1;
if (cfg->tempdiff || cfg->tempinfo || cfg->tempcrit) {
PrintOut(LOG_CRIT, "Device: %s, can't monitor Temperature, ignoring -W Directive\n", device);
cfg->tempdiff = cfg->tempinfo = cfg->tempcrit = 0;
}
}
}
@ -1759,8 +1798,8 @@ static int SCSIDeviceScan(cfgfile *cfg, int scanning) {
// is NOT the attribute ID number.. If (Normalized & Raw) equal,
// then return 0, else nonzero.
int ATACompareValues(changedattribute_t *delta,
struct ata_smart_values *new,
struct ata_smart_values *old,
struct ata_smart_values *newv,
struct ata_smart_values *oldv,
struct ata_smart_thresholds_pvt *thresholds,
int n, char *name){
struct ata_smart_attribute *now,*was;
@ -1769,12 +1808,12 @@ int ATACompareValues(changedattribute_t *delta,
int sameraw;
// check that attribute number in range, and no null pointers
if (n<0 || n>=NUMBER_ATA_SMART_ATTRIBUTES || !new || !old || !thresholds)
if (n<0 || n>=NUMBER_ATA_SMART_ATTRIBUTES || !newv || !oldv || !thresholds)
return 0;
// pointers to disk's values and vendor's thresholds
now=new->vendor_attributes+n;
was=old->vendor_attributes+n;
now=newv->vendor_attributes+n;
was=oldv->vendor_attributes+n;
thre=thresholds->thres_entries+n;
// consider only valid attributes
@ -1861,20 +1900,20 @@ int IsAttributeOff(unsigned char attr, unsigned char **datap, int set, int which
// If the self-test log has got more self-test errors (or more recent
// self-test errors) recorded, then notify user.
void CheckSelfTestLogs(cfgfile *cfg, int new){
void CheckSelfTestLogs(cfgfile *cfg, int newi){
char *name=cfg->name;
if (new<0)
if (newi<0)
// command failed
MailWarning(cfg, 8, "Device: %s, Read SMART Self-Test Log Failed", name);
else {
// old and new error counts
int oldc=cfg->selflogcount;
int newc=SELFTEST_ERRORCOUNT(new);
int newc=SELFTEST_ERRORCOUNT(newi);
// old and new error timestamps in hours
int oldh=cfg->selfloghour;
int newh=SELFTEST_ERRORHOURS(new);
int newh=SELFTEST_ERRORHOURS(newi);
if (oldc<newc) {
// increase in error count
@ -1973,7 +2012,7 @@ void PrintTestSchedule(cfgfile **atadevices, cfgfile **scsidevices){
cnt_t * testcnts; // testcnts[numdev][4]
if (numdev <= 0)
return;
testcnts = calloc(numdev, sizeof(testcnts[0]));
testcnts = (cnt_t *)calloc(numdev, sizeof(testcnts[0]));
if (!testcnts)
return;
@ -2142,16 +2181,69 @@ int DoATASelfTest(int fd, cfgfile *cfg, char testtype) {
return retval;
}
// Check Temperature limits
static void CheckTemperature(cfgfile * cfg, unsigned char currtemp, unsigned char triptemp)
{
const char *minchg = "", *maxchg = "";
if (!(0 < currtemp && currtemp < 255)) {
PrintOut(LOG_INFO, "Device: %s, failed to read Temperature\n", cfg->name);
return;
}
if (!cfg->temperature) {
PrintOut(LOG_INFO, "Device: %s, initial Temperature is %d Celsius\n",
cfg->name, (int)currtemp);
if (triptemp)
PrintOut(LOG_INFO, " [trip Temperature is %d Celsius]\n", (int)triptemp);
cfg->temperature = cfg->tempmin = cfg->tempmax = currtemp;
}
else {
// Update [min,max]
if (currtemp < cfg->tempmin) {
cfg->tempmin = currtemp; minchg = "!";
cfg->tempmininc = 0;
}
else if (cfg->tempmininc) {
// increase min Temperature during first 30 minutes
cfg->tempmin = currtemp;
cfg->tempmininc--;
}
if (currtemp > cfg->tempmax) {
cfg->tempmax = currtemp; maxchg = "!";
}
// Track changes
if (cfg->tempdiff && (*minchg || *maxchg || abs((int)currtemp - (int)cfg->temperature) >= cfg->tempdiff)) {
PrintOut(LOG_INFO, "Device: %s, Temperature changed %+d Celsius to %u Celsius (Min/Max %u%s/%u%s)\n",
cfg->name, (int)currtemp-(int)cfg->temperature, currtemp, cfg->tempmin, minchg, cfg->tempmax, maxchg);
cfg->temperature = currtemp;
}
}
// Check limits
if (cfg->tempcrit && currtemp >= cfg->tempcrit) {
PrintOut(LOG_CRIT, "Device: %s, Temperature %u Celsius reached critical limit of %u Celsius (Min/Max %u%s/%u%s)\n",
cfg->name, currtemp, cfg->tempcrit, cfg->tempmin, minchg, cfg->tempmax, maxchg);
MailWarning(cfg, 12, "Device: %s, Temperature %d Celsius reached critical limit of %u Celsius (Min/Max %u%s/%u%s)\n",
cfg->name, currtemp, cfg->tempcrit, cfg->tempmin, minchg, cfg->tempmax, maxchg);
}
else if (cfg->tempinfo && currtemp >= cfg->tempinfo) {
PrintOut(LOG_INFO, "Device: %s, Temperature %u Celsius reached limit of %u Celsius (Min/Max %u%s/%u%s)\n",
cfg->name, currtemp, cfg->tempinfo, cfg->tempmin, minchg, cfg->tempmax, maxchg);
}
}
int ATACheckDevice(cfgfile *cfg){
int fd,i;
char *name=cfg->name;
char *mode="ATA";
char testtype=0;
// fix firmware bug if requested
con->fixfirmwarebug=cfg->fixfirmwarebug;
con->controller_port=cfg->controller_port;
con->controller_type=cfg->controller_type;
con->controller_explicit=cfg->controller_explicit;
// If user has asked, test the email warning system
if (cfg->mailwarn && cfg->mailwarn->emailtest)
@ -2172,14 +2264,36 @@ int ATACheckDevice(cfgfile *cfg){
return 1;
}
// if the user has asked, and device is capable (or we're not yet
// 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) {
// long test
if (!cfg->testdata->not_cap_long && DoTestNow(cfg, 'L', 0)>0)
testtype = 'L';
// short test
else if (!cfg->testdata->not_cap_short && DoTestNow(cfg, 'S', 0)>0)
testtype = 'S';
// conveyance test
else if (!cfg->testdata->not_cap_conveyance && DoTestNow(cfg, 'C', 0)>0)
testtype = 'C';
// offline immediate
else if (!cfg->testdata->not_cap_offline && DoTestNow(cfg, 'O', 0)>0)
testtype = 'O';
}
// user may have requested (with the -n Directive) to leave the disk
// alone if it is in idle or sleeping mode. In this case check the
// power mode and exit without check if needed
if (cfg->powermode){
int dontcheck=0, powermode=ataCheckPowerMode(fd);
char *mode=NULL;
if (powermode >= 0) {
int powermode2 = ataCheckPowerMode(fd);
if (0 <= powermode && powermode < 0xff) {
// wait for possible spin up and check again
int powermode2;
sleep(5);
powermode2 = ataCheckPowerMode(fd);
if (powermode2 > powermode)
PrintOut(LOG_INFO, "Device: %s, CHECK POWER STATUS spins up disk (0x%02x -> 0x%02x)\n", name, powermode, powermode2);
powermode = powermode2;
@ -2190,38 +2304,51 @@ int ATACheckDevice(cfgfile *cfg){
// SLEEP
mode="SLEEP";
if (cfg->powermode>=1)
dontcheck=1;
dontcheck=1;
break;
case 0:
// STANDBY
mode="STANDBY";
if (cfg->powermode>=2)
dontcheck=1;
dontcheck=1;
break;
case 0x80:
// IDLE
mode="IDLE";
if (cfg->powermode>=3)
dontcheck=1;
dontcheck=1;
break;
case 0xff:
// ACTIVE/IDLE
mode="ACTIVE or IDLE";
break;
default:
// UNKNOWN
PrintOut(LOG_CRIT, "Device: %s, CHECK POWER STATUS returned %d, not ATA compliant, ignoring -n Directive\n",
name, powermode);
name, powermode);
cfg->powermode=0;
break;
}
// if we are going to skip a check, return now
if (dontcheck){
CloseDevice(fd, name);
if (!cfg->powerquiet) // to avoid waking up system disk
PrintOut(LOG_INFO, "Device: %s, is in %s mode, skipping checks\n", name, mode);
return 0;
}
// but ignore powermode on scheduled selftest
if (!testtype) {
CloseDevice(fd, name);
if (!cfg->powerskipcnt && !cfg->powerquiet) // report first only and avoid waking up system disk
PrintOut(LOG_INFO, "Device: %s, is in %s mode, suspending checks\n", name, mode);
cfg->powerskipcnt++;
return 0;
}
PrintOut(LOG_INFO, "Device: %s, %s mode ignored due to scheduled self test (%d check%s skipped)\n",
name, mode, cfg->powerskipcnt, (cfg->powerskipcnt==1?"":"s"));
cfg->powerskipcnt = 0;
}
else if (cfg->powerskipcnt) {
PrintOut(LOG_INFO, "Device: %s, is back in %s mode, resuming checks (%d check%s skipped)\n",
name, mode, cfg->powerskipcnt, (cfg->powerskipcnt==1?"":"s"));
cfg->powerskipcnt = 0;
}
}
// check smart status
@ -2238,7 +2365,8 @@ int ATACheckDevice(cfgfile *cfg){
}
// Check everything that depends upon SMART Data (eg, Attribute values)
if (cfg->usagefailed || cfg->prefail || cfg->usage || cfg->pending!=DONT_MONITOR_UNC){
if ( cfg->usagefailed || cfg->prefail || cfg->usage || cfg->pending!=DONT_MONITOR_UNC
|| cfg->tempdiff || cfg->tempinfo || cfg->tempcrit ){
struct ata_smart_values curval;
struct ata_smart_thresholds_pvt *thresh=cfg->smartthres;
@ -2268,6 +2396,10 @@ int ATACheckDevice(cfgfile *cfg){
}
}
// check temperature limits
if (cfg->tempdiff || cfg->tempinfo || cfg->tempcrit)
CheckTemperature(cfg, ATAReturnTemperatureValue(&curval, cfg->attributedefs), 0);
if (cfg->usagefailed || cfg->prefail || cfg->usage) {
// look for failed usage attributes, or track usage or prefail attributes
@ -2352,45 +2484,32 @@ int ATACheckDevice(cfgfile *cfg){
// check if number of ATA errors has increased
if (cfg->errorlog){
int new,old=cfg->ataerrorcount;
int newc,oldc=cfg->ataerrorcount;
// new number of errors
new=ATAErrorCount(fd, name);
newc=ATAErrorCount(fd, name);
// did command fail?
if (new<0)
if (newc<0)
// lack of PrintOut here is INTENTIONAL
MailWarning(cfg, 7, "Device: %s, Read SMART Error Log Failed", name);
// has error count increased?
if (new>old){
if (newc>oldc){
PrintOut(LOG_CRIT, "Device: %s, ATA error count increased from %d to %d\n",
name, old, new);
name, oldc, newc);
MailWarning(cfg, 4, "Device: %s, ATA error count increased from %d to %d",
name, old, new);
name, oldc, newc);
}
// this last line is probably not needed, count always increases
if (new>=0)
cfg->ataerrorcount=new;
if (newc>=0)
cfg->ataerrorcount=newc;
}
// if the user has asked, and device is capable (or we're not yet
// sure) carry out scheduled self-tests.
if (cfg->testdata) {
// long test
if (!cfg->testdata->not_cap_long && DoTestNow(cfg, 'L', 0)>0)
DoATASelfTest(fd, cfg, 'L');
// short test
else if (!cfg->testdata->not_cap_short && DoTestNow(cfg, 'S', 0)>0)
DoATASelfTest(fd, cfg, 'S');
// conveyance test
else if (!cfg->testdata->not_cap_conveyance && DoTestNow(cfg, 'C', 0)>0)
DoATASelfTest(fd, cfg, 'C');
// offline immediate
else if (!cfg->testdata->not_cap_offline && DoTestNow(cfg, 'O', 0)>0)
DoATASelfTest(fd, cfg, 'O');
}
// carry out scheduled self-test
if (testtype)
DoATASelfTest(fd, cfg, testtype);
// Don't leave device open -- the OS/user may want to access it
// before the next smartd cycle!
@ -2398,9 +2517,6 @@ int ATACheckDevice(cfgfile *cfg){
return 0;
}
#define DEF_SCSI_REPORT_TEMPERATURE_DELTA 2
static int scsi_report_temperature_delta = DEF_SCSI_REPORT_TEMPERATURE_DELTA;
int SCSICheckDevice(cfgfile *cfg)
{
UINT8 asc, ascq;
@ -2442,29 +2558,11 @@ int SCSICheckDevice(cfgfile *cfg)
} else if (debugmode)
PrintOut(LOG_INFO,"Device: %s, Acceptable asc,ascq: %d,%d\n",
name, (int)asc, (int)ascq);
if (currenttemp && currenttemp!=255) {
if (cfg->Temperature) {
if (abs(((int)currenttemp - (int)cfg->Temperature)) >=
scsi_report_temperature_delta) {
PrintOut(LOG_INFO, "Device: %s, Temperature changed %d Celsius "
"to %d Celsius since last report\n", name,
(int)(currenttemp - cfg->Temperature),
(int)currenttemp);
cfg->Temperature = currenttemp;
}
}
else {
PrintOut(LOG_INFO, "Device: %s, initial Temperature is %d "
"Celsius\n", name, (int)currenttemp);
if (triptemp)
PrintOut(LOG_INFO, " [trip Temperature is %d Celsius]\n",
(int)triptemp);
cfg->Temperature = currenttemp;
cfg->Temperature = currenttemp;
}
}
// check temperature limits
if (cfg->tempdiff || cfg->tempinfo || cfg->tempcrit)
CheckTemperature(cfg, currenttemp, triptemp);
// check if number of selftest errors has increased (note: may also DECREASE)
if (cfg->selftest)
CheckSelfTestLogs(cfg, scsiCountFailedSelfTests(fd, 0));
@ -2623,7 +2721,7 @@ void printoutvaliddirectiveargs(int priority, char d) {
PrintOut(priority, "valid_regular_expression");
break;
case 'd':
PrintOut(priority, "ata, scsi, marvell, removable, 3ware,N");
PrintOut(priority, "ata, scsi, marvell, removable, sat, 3ware,N, hpt,L/M/N");
break;
case 'T':
PrintOut(priority, "normal, permissive");
@ -2685,6 +2783,30 @@ int GetInteger(char *arg, char *name, char *token, int lineno, char *configfile,
return val;
}
// Get 1-3 small integer(s) for '-W' directive
int Get3Integers(const char *arg, const char *name, const char *token, int lineno, const char *configfile,
unsigned char * val1, unsigned char * val2, unsigned char * val3){
unsigned v1 = 0, v2 = 0, v3 = 0;
int n1 = -1, n2 = -1, n3 = -1, len;
if (!arg) {
PrintOut(LOG_CRIT,"File %s line %d (drive %s): Directive: %s takes 1-3 integer argument(s) from 0 to 255.\n",
configfile, lineno, name, token);
return -1;
}
len = strlen(arg);
if (!( sscanf(arg, "%u%n,%u%n,%u%n", &v1, &n1, &v2, &n2, &v3, &n3) >= 1
&& (n1 == len || n2 == len || n3 == len) && v1 <= 255 && v2 <= 255 && v3 <= 255)) {
PrintOut(LOG_CRIT,"File %s line %d (drive %s): Directive: %s has argument: %s; needs 1-3 integer(s) from 0 to 255.\n",
configfile, lineno, name, token, arg);
return -1;
}
*val1 = (unsigned char)v1; *val2 = (unsigned char)v2; *val3 = (unsigned char)v3;
return 0;
}
// This function returns 1 if it has correctly parsed one token (and
// any arguments), else zero if no tokens remain. It returns -1 if an
// error was encountered.
@ -2773,6 +2895,7 @@ int ParseToken(char *token,cfgfile *cfg){
break;
case 'd':
// specify the device type
cfg->controller_explicit = 1;
if ((arg = strtok(NULL, delim)) == NULL) {
missingarg = 1;
} else if (!strcmp(arg, "ata")) {
@ -2784,6 +2907,80 @@ int ParseToken(char *token,cfgfile *cfg){
} else if (!strcmp(arg, "marvell")) {
cfg->controller_port =0;
cfg->controller_type = CONTROLLER_MARVELL_SATA;
} else if (!strncmp(arg, "sat", 3)) {
cfg->controller_type = CONTROLLER_SAT;
cfg->controller_port = 0;
cfg->satpassthrulen = 0;
if (strlen(arg) > 3) {
int k;
char * cp;
cp = strchr(arg, ',');
if (cp && (1 == sscanf(cp + 1, "%d", &k)) &&
((0 == k) || (12 == k) || (16 == k)))
cfg->satpassthrulen = k;
else {
PrintOut(LOG_CRIT, "File %s line %d (drive %s): Directive "
"'-d sat,<n>' requires <n> to be 0, 12 or 16\n",
configfile, lineno, name);
badarg = 1;
}
}
} else if (!strncmp(arg, "hpt", 3)){
unsigned char i, slash = 0;
cfg->hpt_data[0] = 0;
cfg->hpt_data[1] = 0;
cfg->hpt_data[2] = 0;
cfg->controller_type = CONTROLLER_HPT;
for (i=4; i < strlen(arg); i++) {
if(arg[i] == '/') {
slash++;
if(slash == 3) {
PrintOut(LOG_CRIT, "File %s line %d (drive %s): Directive "
"'-d hpt,L/M/N' supports 2-3 items\n",
configfile, lineno, name);
badarg = TRUE;
break;
}
}
else if ((arg[i])>='0' && (arg[i])<='9') {
if (cfg->hpt_data[slash]>1) { /* hpt_data[x] max 19 */
badarg = TRUE;
break;
}
cfg->hpt_data[slash] = cfg->hpt_data[slash]*10 + arg[i] - '0';
}
else {
badarg = TRUE;
break;
}
}
if ( slash == 0 ) {
badarg = TRUE;
} else if (badarg != TRUE) {
if (cfg->hpt_data[0]==0 || cfg->hpt_data[0]>8){
PrintOut(LOG_CRIT, "File %s line %d (drive %s): Directive "
"'-d hpt,L/M/N' no/invalid controller id L supplied\n",
configfile, lineno, name);
badarg = TRUE;
}
if (cfg->hpt_data[1]==0 || cfg->hpt_data[1]>8){
PrintOut(LOG_CRIT, "File %s line %d (drive %s): Directive "
"'-d hpt,L/M/N' no/invalid channel number M supplied\n",
configfile, lineno, name);
badarg = TRUE;
}
if (slash==2){
if (cfg->hpt_data[2]==0 || cfg->hpt_data[2]>15){
PrintOut(LOG_CRIT, "File %s line %d (drive %s): Directive "
"'-d hpt,L/M/N' no/invalid pmport number N supplied\n",
configfile, lineno, name);
badarg = TRUE;
}
} else { /* no pmport device */
cfg->hpt_data[2]=1;
}
}
} else if (!strcmp(arg, "removable")) {
cfg->removable = 1;
} else {
@ -3017,6 +3214,15 @@ int ParseToken(char *token,cfgfile *cfg){
IsAttributeOff(val, &cfg->monitorattflags, 1, MONITOR_RAWPRINT, __LINE__);
IsAttributeOff(val, &cfg->monitorattflags, 1, MONITOR_RAW, __LINE__);
break;
case 'W':
// track Temperature
if ((val=Get3Integers(arg=strtok(NULL,delim), name, token, lineno, configfile,
&cfg->tempdiff, &cfg->tempinfo, &cfg->tempcrit))<0)
return -1;
// increase min Temperature during first 30 minutes
if (!(cfg->tempmininc = (unsigned char)(CHECKTIME / checktime)))
cfg->tempmininc = 1;
break;
case 'v':
// non-default vendor-specific attribute meaning
if (!(arg=strtok(NULL,delim))) {
@ -3246,9 +3452,33 @@ int ParseConfigLine(int entry, int lineno,char *line){
bytes+=16;
}
if (cfg->hpt_data[0]) {
int len=17+strlen(cfg->name);
char *newname;
if (devscan){
PrintOut(LOG_CRIT, "smartd: can not scan for highpoint devices (line %d of file %s)\n",
lineno, configfile);
return -2;
}
if (!(newname=(char *)calloc(len,1))) {
PrintOut(LOG_INFO,"No memory to parse file: %s line %d, %s\n", configfile, lineno, strerror(errno));
EXIT(EXIT_NOMEM);
}
// Make new device name by adding a space then RAID disk number
snprintf(newname, len, "%s [hpt_%d/%d/%d]", cfg->name, cfg->hpt_data[0],
cfg->hpt_data[1], cfg->hpt_data[2]);
cfg->name=CheckFree(cfg->name, __LINE__,filenameandversion);
cfg->name=newname;
bytes+=16;
}
// If NO monitoring directives are set, then set all of them.
if (!(cfg->smartcheck || cfg->usagefailed || cfg->prefail ||
cfg->usage || cfg->selftest || cfg->errorlog )){
cfg->usage || cfg->selftest || cfg->errorlog ||
cfg->tempdiff || cfg->tempinfo || cfg->tempcrit )) {
PrintOut(LOG_INFO,"Drive: %s, implied '-a' Directive on line %d of file %s\n",
cfg->name, cfg->lineno, configfile);

View File

@ -32,7 +32,7 @@
#ifndef SMARTD_H_CVSID
#define SMARTD_H_CVSID "$Id: smartd.h,v 1.76 2006/04/12 14:54:28 ballen4705 Exp $\n"
#define SMARTD_H_CVSID "$Id: smartd.h,v 1.83 2006/09/15 08:01:21 sxzzsf Exp $\n"
#endif
// Configuration file
@ -64,7 +64,7 @@
// Number of allowed mail message types
#define SMARTD_NMAIL 12
#define SMARTD_NMAIL 13
typedef struct mailinfo_s {
int logged;// number of times an email has been sent
@ -168,8 +168,11 @@ typedef struct configfile_s {
// REGISTERED AND WE LEARN ITS CAPABILITIES.
int lineno; // Line number of entry in file
char *name; // Device name (+ optional [3ware_disk_XX])
unsigned char controller_type; // Controller type, ATA/SCSI/3Ware/(more to come)
unsigned char controller_explicit; // Controller (device) type has been specified explicitly
unsigned char controller_type; // Controller type, ATA/SCSI/SAT/3Ware/(more to come)
unsigned char controller_port; // 1 + (disk number in controller). 0 means controller only handles one disk.
unsigned char hpt_data[3]; // combined controller/channle/pmport for highpoint rocketraid controller
unsigned char satpassthrulen; // length of SAT ata pass through scsi commands (12, 16 or 0 (platform choice))
char smartcheck; // Check SMART status
char usagefailed; // Check for failed Usage Attributes
char prefail; // Track changes in Prefail Attributes
@ -185,6 +188,9 @@ typedef struct configfile_s {
char removable; // Device may disappear (not be present)
char powermode; // skip check, if disk in idle or standby mode
char powerquiet; // skip powermode 'skipping checks' message
unsigned char tempdiff; // Track Temperature changes >= this limit
unsigned char tempinfo, tempcrit; // Track Temperatures >= these limits as LOG_INFO, LOG_CRIT+mail
unsigned char tempmin, tempmax; // Min/Max Temperatures
unsigned char selflogcount; // total number of self-test errors
unsigned short selfloghour; // lifetime hours of last self-test error
testinfo *testdata; // Pointer to data on scheduled testing
@ -193,11 +199,13 @@ typedef struct configfile_s {
// THE NEXT SET OF ENTRIES ALSO TRACK DEVICE STATE AND ARE DYNAMIC
maildata *mailwarn; // non-NULL: info about sending mail or executing script
unsigned char temperature; // last recorded Temperature (in Celsius)
unsigned char tempmininc; // #checks where Min Temperature is increased after powerup
int powerskipcnt; // Number of checks skipped due to idle or standby mode
// SCSI ONLY
unsigned char SmartPageSupported; // has log sense IE page (0x2f)
unsigned char TempPageSupported; // has log sense temperature page (0xd)
unsigned char Temperature; // last recorded figure (in Celsius)
unsigned char SuppressReport; // minimize nuisance reports
unsigned char modese_len; // mode sense/select cmd len: 0 (don't
// know yet) 6 or 10
@ -241,7 +249,7 @@ typedef struct changedattribute_s {
#ifndef __GNUC__
#define __attribute__(x) /* nothing */
#endif
void PrintOut(int priority,char *fmt, ...) __attribute__ ((format(printf, 2, 3)));
void PrintOut(int priority, const char *fmt, ...) __attribute__ ((format(printf, 2, 3)));
void PrintAndMail(cfgfile *cfg, int which, int priority, char *fmt, ...) __attribute__ ((format(printf, 4, 5)));

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.36
Version: 5.37
License: GPL
Group: Applications/System
Group(de): Applikationen/System
@ -26,16 +26,19 @@ Obsoletes: ucsc-smartsuite
Obsoletes: smartsuite
Packager: Bruce Allen <smartmontools-support@lists.sourceforge.net>
%define redhat %(test ! -f /etc/redhat-release ; echo $?)
%define redhat %(test ! -f /etc/fedora-release ; echo $?)
%define mandrake %(test ! -f /etc/mandrake-release ; echo $?)
%define suse %(test ! -f /etc/SuSE-release ; echo $?)
%define redhat %(test ! -f /etc/redhat-release ; echo $?)
%define fedora %(test ! -f /etc/fedora-release ; echo $?)
%if %{fedora}
%define redhat 1
%endif
# Source code can be found at:
# http://ftp1.sourceforge.net/smartmontools/smartmontools-%{version}-%{release}.tar.gz
# CVS ID of this file is:
# $Id: smartmontools.spec,v 1.167 2006/04/12 17:39:32 ballen4705 Exp $
# $Id: smartmontools.spec,v 1.169 2006/09/09 02:59:03 ballen4705 Exp $
# Copyright (C) 2002-6 Bruce Allen <smartmontools-support@lists.sourceforge.net>
# Home page: http://smartmontools.sourceforge.net/

View File

@ -1,5 +1,5 @@
/*
* utility.c
* utility.cpp
*
* Home page of code is: http://smartmontools.sourceforge.net
*
@ -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.c,v 1.61 2006/04/12 14:54:28 ballen4705 Exp $"
const char* utility_c_cvsid="$Id: utility.cpp,v 1.62 2006/08/09 20:40:20 chrfranke Exp $"
CONFIG_H_CVSID INT64_H_CVSID UTILITY_H_CVSID;
const char * packet_types[] = {
@ -365,7 +365,7 @@ void syserror(const char *message){
// regcomp().
void printregexwarning(int errcode, regex_t *compiled){
size_t length = regerror(errcode, compiled, NULL, 0);
char *buffer = malloc(length);
char *buffer = (char*)malloc(length);
if (!buffer){
pout("Out of memory in printregexwarning()\n");
return;
@ -543,20 +543,20 @@ int64_t bytes = 0;
// Helps debugging. If the second argument is non-negative, then
// decrement bytes by that amount. Else decrement bytes by (one plus)
// length of null terminated string.
void *FreeNonZero(void *address, int size, int line, const char* file){
void *FreeNonZero1(void *address, int size, int line, const char* file){
if (address) {
if (size<0)
bytes-=1+strlen(address);
bytes-=1+strlen((char*)address);
else
bytes-=size;
return CheckFree(address, line, file);
return CheckFree1(address, line, file);
}
return NULL;
}
// To help with memory checking. Use when it is known that address is
// NOT null.
void *CheckFree(void *address, int whatline, const char* file){
void *CheckFree1(void *address, int whatline, const char* file){
if (address){
free(address);
return NULL;

View File

@ -25,7 +25,7 @@
#ifndef UTILITY_H_
#define UTILITY_H_
#define UTILITY_H_CVSID "$Id: utility.h,v 1.43 2006/04/12 14:54:28 ballen4705 Exp $\n"
#define UTILITY_H_CVSID "$Id: utility.h,v 1.46 2006/08/25 06:06:25 sxzzsf Exp $\n"
#include <time.h>
#include <sys/types.h> // for regex.h (according to POSIX)
@ -59,7 +59,7 @@ void printone(char *block, const char *cvsid);
#ifndef __GNUC__
#define __attribute__(x) /* nothing */
#endif
void pout(char *fmt, ...)
void pout(const char *fmt, ...)
__attribute__ ((format (printf, 1, 2)));
// replacement for perror() with redirected output.
@ -96,7 +96,12 @@ int make_device_names (char ***devlist, const char* name);
void *Calloc(size_t nmemb, size_t size);
// Utility function to free memory
void *FreeNonZero(void* address, int size, int whatline, const char* file);
void *FreeNonZero1(void* address, int size, int whatline, const char* file);
// Typesafe version of above
template <class T>
inline T * FreeNonZero(T * address, int size, int whatline, const char* file)
{ return (T *)FreeNonZero1((void *)address, size, whatline, 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
@ -105,7 +110,12 @@ char *CustomStrDup(char *ptr, int mustexist, int whatline, const char* file);
// To help with memory checking. Use when it is known that address is
// NOT null.
void *CheckFree(void *address, int whatline, const char* file);
void *CheckFree1(void *address, int whatline, const char* file);
// Typesafe version of above
template <class T>
inline T * CheckFree(T * address, int whatline, const char* file)
{ return (T *)CheckFree1((void *)address, whatline, file); }
// This function prints either to stdout or to the syslog as needed
@ -115,7 +125,7 @@ void *CheckFree(void *address, int whatline, const char* file);
// values. This means the objects of type char or short int (whether
// signed or not) are promoted to either int or unsigned int, as
// appropriate.]
void PrintOut(int priority,char *fmt, ...);
void PrintOut(int priority, const char *fmt, ...) __attribute__ ((format(printf, 2, 3)));
// run time, determine byte ordering
int isbigendian();
@ -174,6 +184,7 @@ void MsecToText(unsigned int msec, char *txt);
#define CONTROLLER_3WARE_9000_CHAR 0x05 // set by guess_device_type()
#define CONTROLLER_3WARE_678K_CHAR 0x06 // set by guess_device_type()
#define CONTROLLER_MARVELL_SATA 0x07 // SATA drives behind Marvell controllers
#define CONTROLLER_SAT 0x08 // SATA device behind a SCSI ATA Translation (SAT) layer
#define CONTROLLER_HPT 0x09 // SATA drives behind HighPoint Raid controllers
#endif