Imported Upstream version 5.38+svn2879

This commit is contained in:
Giuseppe Iuculano 2009-08-30 18:43:15 +02:00
parent 34ad0c5ffe
commit 2127e1931e
80 changed files with 26290 additions and 29344 deletions

View File

@ -1,4 +1,4 @@
$Id: AUTHORS,v 1.19 2007/12/08 12:58:53 chrfranke Exp $
$Id: AUTHORS,v 1.22 2008/09/23 23:55:29 jharg Exp $
This code was originally developed as a Senior Thesis by Michael
Cornwell at the Concurrent Systems Laboratory (now part of the Storage
@ -25,6 +25,7 @@ Kai M
Eduard Martinescu <martines@rochester.rr.com>
Frédéric L. W. Meunier <http://www.pervalidus.net/contact.html>
Keiji Sawada <card_captor@users.sourceforge.net>
Manfred Schwarb <manfred99@gmx.ch>
David Snyder <dasnyderx@yahoo.com>
Sergey Svishchev <svs@ropnet.ru>
Phil Williams <phil@subbacultcha.demon.co.uk>
@ -33,3 +34,5 @@ Yuri Dario <mc6530@mclink.it>
Shengfeng Zhou <linux@highpoint-tech.com>
Praveen Chidambaram <bunchofmails@gmail.com>
Joerg Hering <hering.ruegen@gmx.de>
Tomas Smetana <tsmetana@redhat.com>
Jordan Hargrave <jordan_hargrave@dell.com>

723
CHANGELOG
View File

@ -1,40 +1,711 @@
CHANGELOG for smartmontools
$Id: CHANGELOG,v 1.661 2008/03/10 10:44:30 ballen4705 Exp $
$Id: CHANGELOG 2879 2009-08-29 17:19:00Z chrfranke $
The most recent version of this file is:
http://smartmontools.cvs.sourceforge.net/smartmontools/sm5/CHANGELOG?view=markup
http://smartmontools.svn.sourceforge.net/viewvc/smartmontools/trunk/smartmontools/CHANGELOG?view=markup
Maintainers / Developers Key:
[BA] Bruce Allen
[EB] Erik Inge Bolsø
[SB] Stanislav Brabec
[PC] Peter Cassidy
[YD] Yuri Dario
[CD] Casper Dik
[CF] Christian Franke
[GF] Guilhem Frézou
[DG] Douglas Gilbert
[GG] Guido Guenther
[GK] Geoff Keating
[DK] Dr. David Kirkby
[JH] Joerg Hering
[KM] Kai Mäkisara
[EM] Eduard Martinescu
[FM] Frédéric L. W. Meunier
[KS] Keiji Sawada
[DS] David Snyder
[SS] Sergey Svishchev
[PW] Phil Williams
[LW] Leon Woestenberg
[RZ] Richard Zybert
[SZ] Sf Zhou
Maintainers / Developers Key (alphabetic order):
[BA] Bruce Allen
[OB] Oliver Bock
[EB] Erik Inge Bolsø
[SB] Stanislav Brabec
[PC] Peter Cassidy
[MC] Matthieu Castet
[YD] Yuri Dario
[CD] Casper Dik
[CF] Christian Franke
[GF] Guilhem Frézou
[DG] Douglas Gilbert
[GG] Guido Guenther
[JPH] Jordan Powell Hargrave
[JH] Joerg Hering
[GK] Geoff Keating
[DK] Dr. David Kirkby
[DL] Dan Lukes
[KM] Kai Mäkisara
[EM] Eduard Martinescu
[FM] Frédéric L. W. Meunier
[GP] Gabriele Pohl
[AR] Adam Radford
[KS] Keiji Sawada
[MS] Manfred Schwarb
[TS] Tomas Smetana
[DS] David Snyder
[SS] Sergey Svishchev
[PW] Phil Williams
[LW] Leon Woestenberg
[SZ] Shengfeng Zhou
[RZ] Richard Zybert
NOTES FOR FUTURE RELEASES: see TODO file.
<DEVELOPERS: ADDITIONS TO THE CHANGE LOG GO JUST BELOW HERE, PLEASE>
[CF] Fix max number of 3ware devices, 128 devices are supported again.
Regression was introduced during migration to new interface.
Thanks to Michael Holweg for the problem report.
[CF] Windows installer: Add 'DisplayVersion' to uninstall registry key.
[MS] knowndrives.cpp updates:
- Marvell SSD SD88SA024BA0
- Fujitsu MHZ2 BH series
- Fujitsu MHZ2 BJ series
- Seagate Maxtor DiamondMax 23
- WD Caviar Green: Add some 32MB cache variants
- relax OCZ-Vertex pattern
[CF] Add USB ID of Verbatim FW/USB160.
[CF] Fix data type bug in checksum test for multi sector logs.
[CF] Add USB ID of Seagate FreeAgent Go.
[MS] Add experimental feature to log attribute values at each check
cycle (ATA only), activated with the smartd option
"-A PREFIX" / "--attributelog=PREFIX".
Introduce configure options "--enable-attributelog" and
"--with-attributelog=PREFIX" to enable feature by default.
[DG] [SAT] Heads up about a non backwardly compatible change
introduced in draft SAT-2 (sat2r8b.pdf) that will break our
existing SAT processing code. Action needed if change stands.
[MS] smartd.cpp: Adjust umask
[CF] Makefile.am: Remove 'uninstall-docsDATA' target to fix
'make distcheck' with automake 1.11. The 'make uninstall'
of examplescripts fails if docdir does no longer exist.
[CF] Remove 'scsiata.h'. The 'scsiata.cpp' module now implements
parts of 'dev_interface.h'.
[CF] smartctl: Don't report an attribute as failed if threshold is 0.
[CF] Print only one warning on checksum errors in multi sector log.
Remove casts from calls of checksum().
[DG] minor changes to SCSI background scan strings
[MS] knowndrives.cpp updates:
- Fujitsu MHW2 BJ series
- WD Caviar Black family
[MS] Makefile.am: Make creation of svnversion.h independent of
locale settings
[CF] Require to specify PORT parameter of '-d usbjmicron' if two disks
are connected.
[CF] smartctl: Limit default number of printed entries for
'-l xerror' to 8, for '-l xselftest' to 25.
[CF] smartctl: Fix number of entries in '-l xselftest' output.
[CF] Add USB IDs of a SunplusIT bridge, three WD drives, and an
unsupported Iomega drive.
[CF] Makefile.am: Use 'svnversion' instead of 'svn info' to get
the revision number. This also checks for mixed and modified
working copies.
[CF] Remove CVS Id strings from '-V, --version' output.
[CF] Update CONTRIBUTORS section on man pages.
[CF] Makefile.am: 'make maintainer-clean' now removes also files
generated by './autogen.sh'.
[CF] Invalidate 'do_release' script, it needs some rework for SVN.
[CF] Update documentation files for SVN.
[CF] Rename trunk/sm5 to trunk/smartmontools.
[CF] Print SVN revision number instead of time in version info line.
Get SVN revision number from svn (if available) or guess from
Id strings. Rename generated file to svnversion.h.
[CF] Makefile.am: Modify generation of cvsversion.h for SVN.
[GP] Convert CVS repository to SVN.
[CF] smartd: Fix size of monitor flag array from previous commit.
[CF] Makefile.am: Add missing 'megaraid.h'.
[CF] smartd: Add '!' flag to '-r' and '-R' directives. If specified,
message is logged as LOG_CRIT and warning mail is sent if
attribute normalized or raw value changes.
[CF] Replace global 'con->...' variables used for selective self-tests
by local variables.
[GK] Add names for some attributes used in Samsung MLC drives:
178-180 & 183
[CF] smartctl: Add option '-x, --xall' to print all info including
extended SMART logs and non-SMART info.
[CF] smartctl: Add '-l xerror,error' and '-l xselftest,selftest' to print
the old logs if the extended logs are not supported.
[MS] knowndrives.cpp updates:
- Western Digital AV-GP series
- Transcend Solid-State Drive and Transcend Solid-State Drive V series
- Seagate Momentus 5400.5 series
[CF] Disable 48-bit ATA commands for JMicron USB bridges by default
because these commands do not work with all devices.
Add '-d usbjmicron,x' to enable 48-bit commands.
Thanks to Alexander Shaduri for the problem report.
[CF] smartd: Don't ignore the '-n' directive when a self-test is
scheduled. Start the self-test later when the disk is active
again.
[DG] SCSI (SAS): implement '-l sasphy,reset' (reset part was stub
prior to this)
[DG] add 'ATA, SCSI command sets and SAT' section to smartctl.8 .
[SCSI] add 'number of background medium scans' field
[DG] SCSI (SAS): add '-l sasphy' and '-l sasphy,reset' into smartctl
to output SAS device phy information (from the Protocol specific
log page)
[CF] autogen.sh: Remove 'CYGWIN=check_case:strict', this does no
longer work on Cygwin 1.7. Print warning if Automake version
cannot handle case insensitive filesystems.
[CF] Remove '#define TRUE/FALSE', use 'bool' and 'true/false'.
[CF] Add 'options' parameter to SCSI printing routine. Move global
'con->...' smartctl variables to 'options' parameters of
printing routines.
[CF] Windows: Remove outdated entry about undocumented system calls
from WARNINGS file.
[CF] Print General Purpose Logs even if GPL feature bit is missing.
Needed for some older disks which implement READ LOG EXT but
do not report the GPL feature set.
Change order of the extended log outputs ('-l xerror',
'-l xselftest', '-l sataphy'). Extended logs are now printed
before their old versions.
[CF] autogen.sh: automake 1.10.2 and 1.11 are OK.
[CF] Fix syntax error in prototype of 'safe_snprintf()'.
Thanks to Alexander Shaduri for bug report and patch.
[DG] SCSI: Fetch load-unload cycle counts.
[CF] Windows: Add Win-7 and Win2008 to get_os_version_str().
[CF] smartd: Fix '-M test' directive in conjunction with '-s' option.
Thanks to Matthias Becher for the problem report.
[MS] knowndrives.cpp updates:
- Add Seagate Barracuda 7200.12 series
- Add Seagate Momentus 5400.4 series
- Add Hitachi Deskstar 7K1000.B series
- Add Transcend SSD TS32GSSD25-M
- Add OCZ Vertex 1199
[CF] knowndrives.cpp updates:
Add Samsung S250 series.
Add '-v 198,increasing' to Samsung P80.
Replace '#if/#endif' by comment to fix configure option
'--enable-drivedb'.
[CF] knowndrives.cpp update:
Add Seagate 7200.11 with 'CC' firmware which is unaffected
by the bug. Thanks to Bas Mevissen for the patch.
[CF] Replace global 'con->...' variables used for drive presets
by local variables.
[CF] Simplify '-v' vendor attribute option parsing.
Add '-v 197,increasing' and '-v 198,increasing' options
to specifiy that an uncorrectable count is never reset.
This modifies the printed attribute names and smartd's
default setting of '-C' and '-U' directives.
Both '-v' options can also be preset in the drive database.
[CF] Add '+' modifier to smartd '-C' and '-U' directives.
If specified, a warning is only printed if the raw value
increases.
[CF] Add smartctl option '-l xselftest[,NUM]' to print
ATA SMART Extended Self-test Log (GP Log 0x07).
[CF] Add experimental option '-d usbsunplus' for drives behind
SunplusIT USB bridges. Tested on WinXP with SPIF215(?) in
TrekStor DataStation maxi m.u.. Many thanks to SunplusIT
tech support for providing the required information.
[CF] Windows: Provide a non-console version of smartctl.exe
as smartctl-nc.exe. This prevents that a new console is
opened when smartctl is run from a GUI program with
stdio redirected.
Used by GSmartControl (http://gsmartcontrol.berlios.de/).
[CF] Remove support for platforms without getopt_long() in
smartctl.cpp and smartd.cpp. If getopt_long() is missing,
./configure aborts with an explanatory message.
For now, short option help texts are only removed from
os_linux.cpp and os_win32.cpp. HAVE_GETOPT_LONG is still
defined in config.h.
[CF] Add smartctl '-d test' option to print the result of the
device type detection.
[CF] Enhance USB device type autodetection, use bcdDevice if known.
Add Cypress CY7C68300B/C (AT2LP) to the table.
[CF] Linux: Add experimental USB device type autodetection.
Uses USB ID info found through symlink "/sys/block/sdX/device".
[CF] Windows: Add experimental USB device type autodetection.
Uses WMI command line tool 'wmic' to query USB ID.
[CF] Add function smart_interface::get_usb_dev_type_by_id() to map
USB vendor:product IDs to '-d type' names. Can be used by
platform dependent layer to autodetect USB devices if ID of
USB bridge is known.
[CF] smartd: Log changes of self-test execution status if
'-l selftest'is specified.
[CF] knowndrives.cpp update:
Samsung SpinPoint F1 RE series
[MS] knowndrives.cpp update:
Seagate Momentus 5400.6 series
[CF] Add forgotten SCSI sense checks to class usbjmicron_device.
[CF] Add new SMART STATUS check command for JMicron USB bridges.
Should support also older chip versions and prevents a race
condition.
[CF] Windows: Fix win_scsi_device::scsi_pass_through() for single byte
data transfers. Required for JMicron SMART STATUS check.
[MS] knowndrives.cpp update:
Add Hitachi Travelstar C4K60 family (1.8" slim drives)
[MS] Workaround for huge raw values of attribute 9, needed
for Hitachi Travelstar C4K60. For the Power_On_Minutes case,
clip the display to 4 bytes and show the remaining part,
if existent, in parens.
[CF] Add experimental option '-d usbjmicron[,PORT]' for drives
behind JMicron USB bridges. Tested on WinXP with JM20336 in
AixCase AIX-ESU35CD. Many thanks to JMicron tech support
for providing the required information.
[MS] knowndrives.cpp update:
Add WD Caviar Green 8MB and 32MB cache variants, stretch to 2TB.
[CF] knowndrives.cpp updates: Add more entries for Samsung P80 disks
with old and unknown firmware. Remove old entries which would
match any new Samsung model reusing old firmware version number.
[CF] Windows: Add a workaround for missing multi-sector support
for ATA READ LOG EXT command.
[CF] Fix Extended Comprehensive Error Log index base.
Add workaround for Samsung disks using reserved byte as index.
[CF] knowndrives.cpp updates: Update bug warnings for
Seagate 7200.11, ES.2 and DiamondMax 22. Add new entries
for fixed firmware versions.
[CF] Add smartctl option '-l xerror[,NUM]' to print
ATA SMART Extended Comprehensive Error Log (GP Log 0x03).
[MS] knowndrives.cpp update:
Added remaining WD Scorpio Blue SATA II drives
[CF] Minor fix to remove ID 0 from 'smartctl -l sataphy ...' output.
[CF] knowndrives.cpp updates: Add warnings about possible firmware
bugs to Seagate 7200.11, ES.2 and DiamondMax 22 entries.
[CF] knowndrives.cpp updates: Add Samsung SpinPoint F1 series.
[CF] Windows: Fix return value of scsi_pass_through(). Regression
was introduced during migration to new interface. SAT over USB
now works on XP (both '-d sat,12' and '-d sat,16').
[MS] knowndrives.cpp updates:
- Added Western Digital RE2-GP family
- Added Hitachi Travelstar E5K160 family
- Allow uppercase variants of Hitachi 5K160 drives
[CF] Fix smartctl crash on '-l directory,[gs]'. Allow to override
missing GPL feature bit or missing log dir entry with
'-T permissive' option.
[SZ] os_freebsd.cpp, os_freebsd.h updates:
Support HighPoint RocketRAID controller under FreeBSD
[MS] knowndrives.cpp updates:
- Added Western Digital RE3 32MB cache variants
- Added WD Caviar Green 32MB cache variant (WD10EADS)
- Added WD Scorpio Black family
[DG] Accept half healthy (and half unhealthy) indication from the
SMART RETURN STATUS. This makes allowance for SAT implementations
(e.g. via USB) that truncate the SCSI sense buffer to 18 bytes.
This truncation causes the SMART RETURN STATUS indication to be
half health or unhealthy. If the half indication is used, then
warn if '-r ioctl' is given.
[MS] knowndrives.cpp updates:
- Added Apple SSD
- Added Seagate U8 family
[DL] os_freebsd.cpp:
Added support for CHECK_POWER_MODE and WRITE_LOG commands
[MS] knowndrives.cpp update:
There seem to exist WD Raptors with SATA II interface, add them.
[MS] knowndrives.cpp updates:
- Added remaining Seagate Barracuda 7200.11 drives
- Added HP 1TB SATA disk
[MS] knowndrives.cpp updates:
- Added Maxtor 92040U6 (DiamondMax Plus 6800)
- Added Seagate Maxtor DiamondMax 21 500GB version
- Added QUANTUM FIREBALLlct15 22
- Added QUANTUM FIREBALL CR6.4A
- Added QUANTUM FIREBALLP LM20.4
- Added SUN branded Toshiba MK4019GAX
- Added TOSHIBA MK1016GAP and relatives: MK1[05]1[67]GAP
- Added Western Digital WD800AB and WD2500AB
- Some Hitachi 7K160 drives have garbage at end of name: permit it
[CF] Add smartd '-n powermode,N' directive parameter to limit the
number of skipped checks. Thanks to Michal Hlavinka for the patch.
[MS] knowndrives.cpp updates:
- Added Hitachi Endurastar J4K30/N4K30
- Added Hitachi Travelstar 4K120 series
- Some Hitachi 7K80 drives have garbage at end of name: permit it
- IBM Travelstar 6GN series
[MS] knowndrives.cpp updates:
- Added Quantum Fireball ST4300A
- Added Asus-Phison SSD (solid state disk)
- Added Seagate DB35.3 Series
- Added remaining disks of the Seagate SV35.2 Series
[MS] Fix trivial compile error with "-pedantic"
[MS] Workaround for huge raw values of Reallocated_Sector_Ct and
Reallocated_Event_Ct for newer Fujitsu disks (only the lower
16 bits seem to be meaningful). Clip the display to 16 bits
and show the remaining part, if existent, in parens. Patch by [CF].
[CF] smartd DEVICESCAN: Fix autodetection of SAT devices.
Thanks to Stanislav Brabec for bug report and testing.
[MS] knowndrives.cpp update:
Convert file to full string regex: remove "^$" from pattern
[MS] knowndrives.cpp updates:
- Added Seagate Momentus 5400 PSD series (hybrid drives)
- Added Seagate Momentus 7200.3 series
- Added Hitachi Deskstar 7K250 (SUN branded)
- There are Hitachi Travelstar 5K250 drives with capital "HITACHI"
- Correct regex for Maxtor VL 30 drives
[CF] Add configure options '--enable-savestates' and
'--with-savestates=PREFIX' to enable smartd persistence
('-s' option) by default.
[CF] smartd: Add '-s ([cnr]/../.././..)' directive to run scheduled
selective self-tests. Useful to perform full tests of large disks
not running 24x7.
[CF] Allow to read local drive database entries from optional file
'${sysconfdir}/smart_drivedb.h'.
Add configure options '--enable-drivedb' and '--with-drivedbdir=DIR'.
If specified, drive database is read from '${drivedbdir}/drivedb.h'.
(default '${prefix}/share/smartmontools/drivedb.h'). This file
is build from knowndrives.cpp.
[MS] knowndrives.cpp updates:
- Added 640GB variants of Western Digital AAKS and AACS drives
- Added Western Digital AV ATA family
- Added 160GB variant of Hitachi P7K500
- Added 500GB variant of Hitachi 7K1000
- Some cleanup for Quantum disks
- Added Seagate Maxtor DiamondMax 22 family
[CF] Use full string match for regexp in drive database.
[CF] Add option '-d sat+TYPE' to use SAT with controllers which
require option '-d TYPE'. Should work with '-d sat+megaraid,N'.
As a side effect, '-d usbcypress+TYPE' is also supported.
[CF] Add parser to read drive database from a file. Add '-B' option
to smartctl and smartd to specify database file name. File syntax
is identical to the C/C++ syntax used to inialize the internal
database array.
[CF] New syntax for drive database: Specify presets by strings
with '-v' and '-F' options. Use empty strings instead of NULL.
[JPH] Added Linux support for viewing disks behind MegaRAID
controllers
[CF] smartd: Improve min/max temperature recording in conjunction
with '-s' option.
[CF] Add a wrapper class for FILE *.
[CF] smartd: Add experimental support for state persistence (ATA only).
Add option '-s' to specify path prefix for state files.
Rework scheduled self-test detection to support persistence.
If any test schedules are within downtime, the highest priority
test is run after next startup.
[CF] Remove casts from 'format_ata_string()' calls.
[CF] Minor changes to fix errors and warnings from Cygwin gcc 4.3.0.
[CF] smartd: Remove SCSITIMEOUT code. According to smartd.h 1.54 CVS log
from 2003-10-27, it did never work.
[CF] Remove dependencies ataprint.cpp and scsiprint.cpp from smartd.
Move common ATA functions from ataprint.cpp to atacmds.cpp.
Module scsiprint.cpp was apparently never used in smartd.
[CF] Move smartd local declarations from smartd.h and utility.h to
smartd.cpp. Remove smartd.h.
[CF] Fixed extra '\n' in "Offline data collection status" output.
Thanks to Alexander Shaduri for the patch.
[CF] smartd: Separate device configuration data from device state data.
Use references instead of pointers for configuration and state data.
[CF] Add const-correctness and static to ATA support functions.
[CF] Add a wrapper class for regex.
[CF] Simplify 'create_vendor_attribute_arg_list()'.
[CF] smartd: Rework of main data structures. Remove explicit memory
allocations, use STL containers and structs with value semantics
instead. Remove old malloc/free based memory management helper
functions unless old interface is still in use.
[CF] Linux: Cleanup device scan, remove name list, create objects directly.
[CF] Linux: Cleanup smart_device::open(), type strings are no longer used.
[CF] Remove CONTROLLER_* defines and variables unless old interface
is still in use.
[CF] Linux: Migrate 3ware interface to 'ata_pass_through()'.
Multi-sector support is not complete yet. 48-bit commands
possibly work.
WARNING: Not tested, please review code before first test!
[CF] Linux: Migrate os_linux.cpp to new interface.
[CF] Add direct access to 16-bit registers in 'ata_in/out_regs_48bit'.
[CF] Add 'ata_cmd_is_ok()' parameter check,
remove 'ata_pass_through_28/48bit()' functions.
[CF] Add CVS date/time from cvsversion.h to man pages also.
[CF] Add configure option '--with-os-deps='os_module.o ...' to specify
alternate OS interface modules. Useful for testing during migration.
[CF] Remove declarations of 'optarg', 'optind', ..., include <unistd.h>
instead. This fixes 'auto-importing' linker warnings on Cygwin.
[CF] Add '-l sataphy[,reset]' to print SATA Phy Event Counters.
[CF] Add '-l gplog,ADDR[,FIRST[-LAST|+SIZE]]' and '-l smartlog,...'
to dump any log page accessible via GP or SMART read log commands.
[CF] Enhance '-l directory' to print both GP and SMART Log directories.
Add '-l directory[,gs]' modifiers to select GP or SMART log.
Enhance 'ata_cmd_in' parameter struct for 48-bit commands.
[CF] Windows: Add full ATA pass through support including 48-bit commands.
[CF] Windows: Migrate os_win32.cpp to new interface.
[CF] SAT: Add full ATA pass through support including 48-bit commands.
[MS] knowndrives.cpp update
- Added FUJITSU MHZ2250BS G2 and family
[MS] knowndrives.cpp updates
- Added Maxtor DiamondMax 60 94098H6
- Added Maxtor DiamondMax 1280 84000A6 and family
- Added Maxtor DiamondMax VL 30 31536H2 (ATA100) and family
- Some Seagate Barracuda 7200.9 have garbage at end of name: permit it
- Added Seagate Barracuda ATA ST320430A and family
- Regression from previous checkin: add WD RE2 WD...0ABYS again
- Added WD RE3 WD5002ABYS and family
- Added Quantum Fireball CR13.0A
- Added Hitachi Travelstar 5K250 HTS542525K9SA00 and family
- Added WD AC420400D and add whole range of AC.... which
have 5400rpm or higher (i.e. PIO-only drives omitted)
[MS] knowndrives.cpp updates
- WD: Separated entries for EIDE and SATA
- WD: Separated entries for Caviar SE, SE16, RE, RE2
- WD Named: WD Caviar AC series
- WD Renamed: WD Caviar RE/RE2 -> WD RE/RE2
- WD Renamed: WD Caviar SE/SE16 WD....AA[A-Z][A-Z] -> WD Caviar Blue
- WD Renamed: WD Scorpio WD....BEV[A-Z] -> WD Scorpio Blue
- Added WD Scorpio Blue WD3200BEVT
- Added WD RE2 WD5001ABYS and family
- Added WD Caviar Green WD5000AACS and family
- Added WD VelociRaptor WD3000GLFS and family
- Added Seagate Barracuda ES.2 ST31000340NS and family
- Added Samsung SP80A4H
- Added Maxtor DiamondMax 21 STM3160215AS and STM3320620AS
- Added Seagate Barracuda 7200.7 ST380819AS
- Added Maxtor DiamondMax 10 6B100P0
- Added Seagate SV35.2 Series
- Added Fujitsu MHY2120BH and family
- Added Fujitsu MHW2080BH PL (PL variant)
- Added Toshiba MK3252GSX and family
[BA] Fix smartctl bug: when running in silent mode '-q errorsonly'
do not print the Selective Self-test log. Any errors will
ALREADY appear in the SMART Self-test log.
[CF] Add missing 'const' and other minor fixes to prevent gcc warnings.
[OB] Added information message about supported Areca firmware versions.
It's displayed in case the ATA device identification fails.
[CF] Add configuration file for Doxygen.
[CF] Add new object oriented interface to access ATA and SCSI devices.
smartctl and smartd are modified to use the new classes in
'dev_interface.{h,cpp}'. The template class in 'dev_tunnelled.h'
is used in 'scsiata.cpp'. The code in 'dev_ata_cmd_set.{h,cpp}'
supports migration from old function 'ata_command_interface()'.
All existing 'os_*.cpp' modules should still work without any changes.
The required adapter classes from 'dev_legacy.cpp' are automatically
added by configure if necessary.
[BA] Updated smartd and smartctl and smartd.conf man-page documentation
to reflect support for Areca SATA RAID controller cards.
[OB] Added support for Areca controllers to smartd. Extensive tests
as well as documentation are still pending however.
[OB] Implemented device locking for Areca controllers in smartctl
[BA] Fixed selective self-test code. Data structure revision number
may be != 1 if no selective self-test has ever been run. Host
MUST set this value (at least at the first selective self-test
instance). Thanks to Curtis Stevens of WDC for clarification.
[MC] usbcypress autodetection
[BA] Starting to commit Areca code. For now just smartctl.
More changes and documentation coming soon.
Need Areca firmware version 1.45 dated 10 June 2008 or later.
May need changes in opening /dev/sg and file locking.
Many thanks to Hank Wu!
[CF] smartd: Fix too small name buffer for 3ware with >100 devices.
[JH] now C++ Support for QNX Target
already tested for QNX 6.3.2 on x86 and armle target
[CF] Allow to set BUILD_INFO from make command line.
[CF] Windows: Add MSVC8 support, remove MSVC6 project files.
[MC] Add usbcypress device support for smartd.
[CF] Add output of latest CVS date/time stamp to version info.
New file cvsversion.h is generated by Makefile.
Move formatting of version info to utility.cpp.
[AR] Fix bug in 3ware node creation where nodes would be created
then deleted, then recreated.
[BA] Add missing CCISS cvs version tags to '-V' printouts.
[TS] Linux: Ensure the 3ware device nodes are created with a correct
SELinux security context.
[AR] Add support for up to 128 devices on 3ware controllers.
[CF] C++: Added new main() with exception handlers, replaced
exit(x) with throw(x), removed global variable 'exitstatus'.
Necessary for future changes, because exit() does not call
any destructors.
[SS] FreeBSD: plug file descriptor leak in smartd (only happens with
CISS devices). Reported by Vadim Ostranitsyn.
[SS] FreeBSD: allow smartctl to interact with SCSI /dev/pass devices,
thus enabling it to work with RAID controllers that expose disks
via these devices. From scottl@ via FreeBSD ports.
[MC] Add usbcypress device support for smartctl.
[KS] INSTALL on Solaris: updated description to use C++ compiler.
[KS] configure.in on Solaris: added options for Sun's compiler to
suppress trivial warnings.
[KS] configure.in on Solaris: added direction to search suitable
libraries for getaddrinfo().
[TS] smartd on Linux: remove forgotten return from deviceopen();
SCSI device descriptors had the FD_CLOEXEC flag unset.
[CF] Added 'const' to avoid warning on depreciated string constant
to 'char *' conversion.
[CF] autogen.sh: automake 1.10.1 is OK. Updated message texts.
[BA] removed smartmontools.spec file (now in CVS Attic). This
was not being used by RH or FC anyhow, and was out of
date and not maintained.
[BA] smartd on Linux: sets FD_CLOEXEC on the opened device file
descriptor. The descriptor is otherwise leaked to other
applications (mail sender) which may be considered a security
risk and may result in AVC messages on SELinux-enabled systems.
Thanks to: Tomá Smetana" <tsmetana@redhat.com>.
[BA] smartd: when sending email, to gather information about the
host for the body of the email, eliminate gethostbyname()
in favor of the IPv6-friendly function getaddrinfo() if the
latter is available. Info may be found here
http://udrepper.livejournal.com/16116.html
and here
http://people.redhat.com/drepper/userapi-ipv6.html
Thanks to: Tomá Smetana" <tsmetana@redhat.com>.
Smartmontools developers: please check that smartd still LINKS
properly on your systems.
[BA] Fix ugly syntax bug in os_freebsd.cpp. How did this go
undetected for so long??
SMARTMONTOOLS STABLE RELEASE 5.38 2008/03/10

241
Doxyfile Normal file
View File

@ -0,0 +1,241 @@
# Doxyfile 1.5.5
#---------------------------------------------------------------------------
# Project related configuration options
#---------------------------------------------------------------------------
DOXYFILE_ENCODING = UTF-8
PROJECT_NAME = smartmontools
PROJECT_NUMBER =
OUTPUT_DIRECTORY = doc
CREATE_SUBDIRS = NO
OUTPUT_LANGUAGE = English
BRIEF_MEMBER_DESC = YES
REPEAT_BRIEF = YES
ABBREVIATE_BRIEF =
ALWAYS_DETAILED_SEC = YES
INLINE_INHERITED_MEMB = NO
FULL_PATH_NAMES = YES
STRIP_FROM_PATH =
STRIP_FROM_INC_PATH =
SHORT_NAMES = NO
JAVADOC_AUTOBRIEF = YES
QT_AUTOBRIEF = NO
MULTILINE_CPP_IS_BRIEF = NO
DETAILS_AT_TOP = NO
INHERIT_DOCS = YES
SEPARATE_MEMBER_PAGES = NO
TAB_SIZE = 8
ALIASES =
OPTIMIZE_OUTPUT_FOR_C = NO
OPTIMIZE_OUTPUT_JAVA = NO
OPTIMIZE_FOR_FORTRAN = NO
OPTIMIZE_OUTPUT_VHDL = NO
BUILTIN_STL_SUPPORT = NO
CPP_CLI_SUPPORT = NO
SIP_SUPPORT = NO
DISTRIBUTE_GROUP_DOC = NO
SUBGROUPING = YES
TYPEDEF_HIDES_STRUCT = NO
#---------------------------------------------------------------------------
# Build related configuration options
#---------------------------------------------------------------------------
EXTRACT_ALL = YES
EXTRACT_PRIVATE = YES
EXTRACT_STATIC = YES
EXTRACT_LOCAL_CLASSES = YES
EXTRACT_LOCAL_METHODS = NO
EXTRACT_ANON_NSPACES = YES
HIDE_UNDOC_MEMBERS = NO
HIDE_UNDOC_CLASSES = NO
HIDE_FRIEND_COMPOUNDS = NO
HIDE_IN_BODY_DOCS = NO
INTERNAL_DOCS = NO
CASE_SENSE_NAMES = YES
HIDE_SCOPE_NAMES = NO
SHOW_INCLUDE_FILES = YES
INLINE_INFO = YES
SORT_MEMBER_DOCS = YES
SORT_BRIEF_DOCS = NO
SORT_GROUP_NAMES = NO
SORT_BY_SCOPE_NAME = NO
GENERATE_TODOLIST = YES
GENERATE_TESTLIST = YES
GENERATE_BUGLIST = YES
GENERATE_DEPRECATEDLIST= YES
ENABLED_SECTIONS =
MAX_INITIALIZER_LINES = 30
SHOW_USED_FILES = YES
SHOW_DIRECTORIES = NO
FILE_VERSION_FILTER =
#---------------------------------------------------------------------------
# configuration options related to warning and progress messages
#---------------------------------------------------------------------------
QUIET = NO
WARNINGS = YES
WARN_IF_UNDOCUMENTED = NO
WARN_IF_DOC_ERROR = YES
WARN_NO_PARAMDOC = NO
WARN_FORMAT = "$file:$line: $text"
WARN_LOGFILE =
#---------------------------------------------------------------------------
# configuration options related to the input files
#---------------------------------------------------------------------------
INPUT =
INPUT_ENCODING = UTF-8
FILE_PATTERNS = dev*.h \
dev*.cpp \
scsiata.cpp
RECURSIVE = NO
EXCLUDE =
EXCLUDE_SYMLINKS = NO
EXCLUDE_PATTERNS =
EXCLUDE_SYMBOLS =
EXAMPLE_PATH =
EXAMPLE_PATTERNS =
EXAMPLE_RECURSIVE = NO
IMAGE_PATH =
INPUT_FILTER =
FILTER_PATTERNS =
FILTER_SOURCE_FILES = NO
#---------------------------------------------------------------------------
# configuration options related to source browsing
#---------------------------------------------------------------------------
SOURCE_BROWSER = YES
INLINE_SOURCES = NO
STRIP_CODE_COMMENTS = NO
REFERENCED_BY_RELATION = NO
REFERENCES_RELATION = NO
REFERENCES_LINK_SOURCE = YES
USE_HTAGS = NO
VERBATIM_HEADERS = YES
#---------------------------------------------------------------------------
# configuration options related to the alphabetical class index
#---------------------------------------------------------------------------
ALPHABETICAL_INDEX = NO
COLS_IN_ALPHA_INDEX = 5
IGNORE_PREFIX =
#---------------------------------------------------------------------------
# configuration options related to the HTML output
#---------------------------------------------------------------------------
GENERATE_HTML = YES
HTML_OUTPUT = html
HTML_FILE_EXTENSION = .html
HTML_HEADER =
HTML_FOOTER =
HTML_STYLESHEET =
HTML_ALIGN_MEMBERS = YES
GENERATE_HTMLHELP = NO
GENERATE_DOCSET = NO
DOCSET_FEEDNAME = "Doxygen generated docs"
DOCSET_BUNDLE_ID = org.doxygen.Project
HTML_DYNAMIC_SECTIONS = NO
CHM_FILE =
HHC_LOCATION =
GENERATE_CHI = NO
BINARY_TOC = NO
TOC_EXPAND = NO
DISABLE_INDEX = NO
ENUM_VALUES_PER_LINE = 4
GENERATE_TREEVIEW = NO
TREEVIEW_WIDTH = 250
#---------------------------------------------------------------------------
# configuration options related to the LaTeX output
#---------------------------------------------------------------------------
GENERATE_LATEX = YES
LATEX_OUTPUT = latex
LATEX_CMD_NAME = latex
MAKEINDEX_CMD_NAME = makeindex
COMPACT_LATEX = NO
PAPER_TYPE = a4wide
EXTRA_PACKAGES =
LATEX_HEADER =
PDF_HYPERLINKS = YES
USE_PDFLATEX = YES
LATEX_BATCHMODE = NO
LATEX_HIDE_INDICES = NO
#---------------------------------------------------------------------------
# configuration options related to the RTF output
#---------------------------------------------------------------------------
GENERATE_RTF = NO
RTF_OUTPUT = rtf
COMPACT_RTF = NO
RTF_HYPERLINKS = NO
RTF_STYLESHEET_FILE =
RTF_EXTENSIONS_FILE =
#---------------------------------------------------------------------------
# configuration options related to the man page output
#---------------------------------------------------------------------------
GENERATE_MAN = NO
MAN_OUTPUT = man
MAN_EXTENSION = .3
MAN_LINKS = NO
#---------------------------------------------------------------------------
# configuration options related to the XML output
#---------------------------------------------------------------------------
GENERATE_XML = NO
XML_OUTPUT = xml
XML_SCHEMA =
XML_DTD =
XML_PROGRAMLISTING = YES
#---------------------------------------------------------------------------
# configuration options for the AutoGen Definitions output
#---------------------------------------------------------------------------
GENERATE_AUTOGEN_DEF = NO
#---------------------------------------------------------------------------
# configuration options related to the Perl module output
#---------------------------------------------------------------------------
GENERATE_PERLMOD = NO
PERLMOD_LATEX = NO
PERLMOD_PRETTY = YES
PERLMOD_MAKEVAR_PREFIX =
#---------------------------------------------------------------------------
# Configuration options related to the preprocessor
#---------------------------------------------------------------------------
ENABLE_PREPROCESSING = YES
MACRO_EXPANSION = NO
EXPAND_ONLY_PREDEF = NO
SEARCH_INCLUDES = YES
INCLUDE_PATH =
INCLUDE_FILE_PATTERNS =
PREDEFINED =
EXPAND_AS_DEFINED =
SKIP_FUNCTION_MACROS = YES
#---------------------------------------------------------------------------
# Configuration::additions related to external references
#---------------------------------------------------------------------------
TAGFILES =
GENERATE_TAGFILE =
ALLEXTERNALS = NO
EXTERNAL_GROUPS = YES
PERL_PATH = /usr/bin/perl
#---------------------------------------------------------------------------
# Configuration options related to the dot tool
#---------------------------------------------------------------------------
CLASS_DIAGRAMS = YES
MSCGEN_PATH =
HIDE_UNDOC_RELATIONS = YES
HAVE_DOT = NO
CLASS_GRAPH = YES
COLLABORATION_GRAPH = YES
GROUP_GRAPHS = YES
UML_LOOK = NO
TEMPLATE_RELATIONS = NO
INCLUDE_GRAPH = YES
INCLUDED_BY_GRAPH = YES
CALL_GRAPH = NO
CALLER_GRAPH = NO
GRAPHICAL_HIERARCHY = YES
DIRECTORY_GRAPH = YES
DOT_IMAGE_FORMAT = png
DOT_PATH =
DOTFILE_DIRS =
DOT_GRAPH_MAX_NODES = 50
MAX_DOT_GRAPH_DEPTH = 0
DOT_TRANSPARENT = YES
DOT_MULTI_TARGETS = NO
GENERATE_LEGEND = YES
DOT_CLEANUP = YES
#---------------------------------------------------------------------------
# Configuration::additions related to the search engine
#---------------------------------------------------------------------------
SEARCHENGINE = NO

97
INSTALL
View File

@ -1,7 +1,7 @@
Smartmontools installation instructions
=======================================
$Id: INSTALL,v 1.73 2007/04/27 08:50:00 geoffk1 Exp $
$Id: INSTALL 2844 2009-07-18 12:59:21Z chrfranke $
Please also see the smartmontools home page:
http://smartmontools.sourceforge.net/
@ -9,7 +9,7 @@ http://smartmontools.sourceforge.net/
Table of contents:
[1] System requirements
[2] Installing from CVS
[2] Installing from SVN
[3] Installing from source tarball
[4] Guidelines for different Linux distributions
[5] Guidelines for FreeBSD
@ -209,23 +209,19 @@ Table of contents:
Innotek LibC 0.5 runtime is required.
Currently only ATA disks are supported, SCSI support will be added.
[2] Installing from CVS
[2] Installing from SVN
=======================
Get the sources from the CVS repository:
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)
Get the sources from the SVN repository:
svn co https://smartmontools.svn.sourceforge.net/svnroot/smartmontools/trunk/smartmontools smartmontools
Then type:
./autogen.sh
and continue with step [3] below, skipping the "unpack the tarball" step.
Further details of using CVS can be found at the URL above.
The autogen.sh command is ONLY required when installing from
CVS. You need GNU Autoconf (version 2.50 or greater), GNU Automake
(version 1.6 or greater) and their dependencies installed in order
SVN. You need GNU Autoconf (version 2.50 or greater), GNU Automake
(version 1.7 or greater) and their dependencies installed in order
to run it. You can get these here:
http://www.gnu.org/directory/GNU/autoconf.html
http://www.gnu.org/directory/GNU/automake.html
@ -233,7 +229,7 @@ Table of contents:
[3] Installing from the source tarball
======================================
If you are NOT installing from CVS, then unpack the tarball:
If you are NOT installing from SVN, then unpack the tarball:
tar zxvf smartmontools-5.VERSION.tar.gz
Then:
@ -263,6 +259,12 @@ Table of contents:
./configure, or else do:
make CFLAGS='your options'
The first output line of smartctl and smartd provides information
about release number, last SVN checkin date and revison, platform,
and package. The latter defaults to "(local build)" and can be
changed by the variable BUILD_INFO, for example:
make BUILD_INFO='"(Debian 5.39-2)"'
[4] Guidelines for different Linux distributions
================================================
@ -332,10 +334,6 @@ SuSE:
--with-docdir=/usr/local/share/doc/smartmontools-VERSION \
--enable-sample
Also, it is important that you use GNU make (gmake from /usr/ports/devel/gmake)
to build smartmontools, as the default FreeBSD make doesn't know how to build
the man pages.
NOTE: --enable-sample will cause the smartd.conf and smartd RC files to
be installed with the string '.sample' append to the name, so you will end
up with the following:
@ -368,17 +366,17 @@ SuSE:
smartmontools has been partially but not completely ported to
Solaris. It includes complete SCSI support but no ATA or 3ware
support. It can be compiled with either cc or gcc. To compile
with gcc:
support. It can be compiled with either CC (Sun's C++ compiler)
or GNU g++.
To compile with g++:
./configure [args]
make
To compile with Sun cc:
To compile with Sun CC:
setenv CC cc [csh syntax], or
CC=cc [sh syntax]
./configure [args]
env CC=cc CXX=CC ./configure [args]
make
The correct arguments [args] to configure are:
@ -426,7 +424,7 @@ Same as Red Hat:
file type ("binmode" mount option) set. The "autogen.sh" script prints a
warning if DOS type is selected.
If installing from CVS, you may check out all files either with CR/LF
If installing from SVN, you may check out all files either with CR/LF
or LF line endings. Starting with release 3.1-7, Cygwin's bash does no
longer accept scripts with CR/LF by default. To run the initial script
./autogen.sh checked out with CR/LF on a "binmode" mount, type:
@ -469,7 +467,7 @@ To create a Windows installer, use:
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.
download location.
To both create and run the (interactive) installer, use:
@ -484,16 +482,22 @@ To both create and run the (interactive) installer, use:
or a native Win32 release of Info-ZIP, http://www.info-zip.org) are
necessary but may be not installed by Cygwin's default settings.
It is also possible to compile smartmontools with MSVC 6.0.
The project files (smartmontools_vc6.dsw, smart{ctl,d}_vc6.dsp) are
included in CVS (but not in source tarball). The config_vc6.h is no
longer maintained in CVS. The command:
To prepare os_win32 directory for MSVC8, use the following on Cygwin:
make config-vc6
mkdir vctmp && cd vctmp
../configure --build=mingw32
make config-vc8
builds config_vc6.h from MinGW's config.h. Unlike MinGW, MSVC 6.0
can also be used to build the syslog message file tool syslogevt.exe.
See smartd man page for usage information about this tool.
The MSVC8 project files (os_win32/smartmontools_vc8.sln,
os_win32/smart{ctl,d}_vc8.vcproj) are included in SVN (but not in
source tarball). The target config-vc8 from a Makefile configured
for MinGW creates os_win32/{config,svnversion}_vc8.h from
./{config,svnversion}.h. The configure skript must be run outside
of the source directory to avoid inclusion of the original config.h.
Unlike MinGW, MSVC can also be used to build the syslog message file
tool syslogevt.exe. See smartd man page for usage information about
this tool.
[11] Guidelines for OS/2, eComStation
@ -581,7 +585,7 @@ The following files are installed if ./configure has no options:
/usr/local/share/man/man8/smartctl.8 [Manual page]
/usr/local/share/man/man8/smartd.8 [Manual page]
/usr/local/share/doc/smartmontools-5.X/AUTHORS [Information about the authors and developers]
/usr/local/share/doc/smartmontools-5.X/CHANGELOG [A log of changes. Also see CVS]
/usr/local/share/doc/smartmontools-5.X/CHANGELOG [A log of changes. Also see SVN]
/usr/local/share/doc/smartmontools-5.X/COPYING [GNU General Public License Version 2]
/usr/local/share/doc/smartmontools-5.X/INSTALL [Installation instructions: what you're reading!]
/usr/local/share/doc/smartmontools-5.X/NEWS [Significant bugs discovered in old versions]
@ -607,6 +611,19 @@ if groff is available:
make MAN2HTML='groff -man -Thtml' htmlman
Some of the source files are prepared for the documentation
generator Doxygen (http://www.doxygen.org/). If Doxygen is installed,
the command:
doxygen
creates HTML documentation in doc/html and LaTeX documentation
in doc/latex. If TeX is installed, the following command creates
a documentation file doc/latex/refman.pdf:
( cd doc/latex && make pdf )
[14] Detailed description of arguments to configure command
===========================================================
@ -629,8 +646,16 @@ OPTIONS DEFAULT AFFECTS
Contents of smartd/smartd.conf man pages;
Directory for rc.d/init.d/smartd init script
--with-initscriptdir ${sysconfdir}/init.d/rc.d Location of init scripts
--with-docdir ${prefix}/share/doc/smartmontools-5.X Location of the documentation
--enable-sample --disable-sample Adds the string '.sample' to the names of the smartd.conf file and the smartd RC file
--with-docdir ${prefix}/share/doc/smartmontools-5.X Location of the documentation
--enable-sample --disable-sample Adds the string '.sample' to the names of the smartd.conf file and the smartd RC file
--with-os-deps os_<guessed>.o OS dependent module(s)
--with-selinux <not set> Enables SELinux support. If smartmontools has to create the /dev/tw[ae] device
nodes for 3ware/AMCC controllers, this option ensures that the nodes are created
with correct SELinux file contexts.
--enable-drivedb --disable-drivedb Enables default drive database file '${drivedbdir}/drivedb.h'
--with-drivedbdir ${prefix}/share/smartmontools/drivedb.h Directory for 'drivedb.h' (specifying this option implies --enable-drivedb)
--enable-savestates --disable-savestates Enables default smartd state files '${savestates}MODEL-SERIAL.ata.state'
--with-savestates ${prefix}/var/lib/smartmontools/smartd. Prefix for smartd state files (specifying this option implies --enable-savestates)
Here's an example:
If you set --prefix=/home/joe and none of the other four

View File

@ -1,6 +1,6 @@
## Process this file with automake to produce Makefile.in
#
# $Id: Makefile.am,v 1.81 2007/04/01 16:49:44 shattered Exp $
# $Id: Makefile.am 2878 2009-08-26 20:03:06Z chrfranke $
#
@SET_MAKE@
@ -8,20 +8,33 @@
# Make sure .cpp takes precedence to avoid compiling old .c file
SUFFIXES = .cpp .c .s .o
# BUILD_INFO can be provided by package maintainers (see INSTALL file)
BUILD_INFO= "(local build)"
AM_CPPFLAGS = -DSMARTMONTOOLS_SYSCONFDIR=\"$(sysconfdir)\"
AM_CPPFLAGS = -DBUILD_INFO='$(BUILD_INFO)' -DSMARTMONTOOLS_SYSCONFDIR='"$(sysconfdir)"'
if ENABLE_DRIVEDB
AM_CPPFLAGS += -DSMARTMONTOOLS_DRIVEDBDIR='"$(drivedbdir)"'
endif
if ENABLE_SAVESTATES
AM_CPPFLAGS += -DSMARTMONTOOLS_SAVESTATES='"$(savestates)"'
endif
if ENABLE_ATTRIBUTELOG
AM_CPPFLAGS += -DSMARTMONTOOLS_ATTRIBUTELOG='"$(attributelog)"'
endif
sbin_PROGRAMS = smartd \
smartctl
smartd_SOURCES = smartd.cpp \
smartd.h \
atacmdnames.cpp \
atacmdnames.h \
atacmds.cpp \
atacmds.h \
ataprint.cpp \
ataprint.h \
dev_ata_cmd_set.cpp \
dev_ata_cmd_set.h \
dev_interface.cpp \
dev_interface.h \
dev_tunnelled.h \
extern.h \
int64.h \
knowndrives.cpp \
@ -29,9 +42,6 @@ smartd_SOURCES = smartd.cpp \
scsicmds.cpp \
scsicmds.h \
scsiata.cpp \
scsiata.h \
scsiprint.cpp \
scsiprint.h \
utility.cpp \
utility.h
@ -55,7 +65,9 @@ EXTRA_smartd_SOURCES = os_darwin.cpp \
os_generic.cpp \
os_generic.h \
cciss.cpp \
cciss.h
cciss.h \
dev_legacy.cpp \
megaraid.h
if OS_WIN32_MINGW
@ -87,6 +99,11 @@ smartctl_SOURCES= smartctl.cpp \
atacmds.h \
ataprint.cpp \
ataprint.h \
dev_ata_cmd_set.cpp \
dev_ata_cmd_set.h \
dev_interface.cpp \
dev_interface.h \
dev_tunnelled.h \
extern.h \
int64.h \
knowndrives.cpp \
@ -94,12 +111,12 @@ smartctl_SOURCES= smartctl.cpp \
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@
@ -117,7 +134,9 @@ EXTRA_smartctl_SOURCES = os_linux.cpp \
os_generic.cpp \
os_generic.h \
cciss.cpp \
cciss.h
cciss.h \
dev_legacy.cpp \
megaraid.h
if OS_WIN32_MINGW
@ -211,8 +230,7 @@ smartd.conf$(smartd_suffix): smartd.conf
cp ${srcdir}/smartd.conf smartd.conf$(smartd_suffix)
endif
EXTRA_DIST = smartmontools.spec \
smartd.initd.in \
EXTRA_DIST = smartd.initd.in \
smartd.8.in \
smartctl.8.in \
smartd.conf.5.in \
@ -224,7 +242,8 @@ EXTRA_DIST = smartmontools.spec \
os_win32/installer.nsi \
$(docs_DATA)
CLEANFILES = smartd.conf.5 \
CLEANFILES = drivedb.h \
smartd.conf.5 \
smartd.conf.4 \
smartd.8 \
smartd.1m \
@ -236,13 +255,70 @@ CLEANFILES = smartd.conf.5 \
smartctl.8.txt \
smartd.conf.5.html \
smartd.conf.5.txt \
smartd.initd \
smartd.initd \
svnversion.h \
SMART
if SMARTD_SUFFIX
CLEANFILES += smartd.conf$(smartd_suffix)
endif
# 'make maintainer-clean' also removes files generated by './autogen.sh'
MAINTAINERCLEANFILES = \
$(srcdir)/Makefile.in \
$(srcdir)/aclocal.m4 \
$(srcdir)/configure \
$(srcdir)/config.guess \
$(srcdir)/config.h.in \
$(srcdir)/config.h.in~ \
$(srcdir)/config.sub \
$(srcdir)/depcomp \
$(srcdir)/install-sh \
$(srcdir)/missing \
$(srcdir)/mkinstalldirs
utility.o: svnversion.h
if IS_SVN_BUILD
# Get version info from SVN
svnversion.h: CHANGELOG Makefile $(srcdir)/.svn/entries
echo '/* svnversion.h. Generated by Makefile from svn info. */' > $@
(cd $(srcdir) \
&& svnversion 2>/dev/null | sed -n 's,^\([0-9].*\),REV "\1",p' \
&& TZ= LC_ALL=C svn info 2>/dev/null \
| sed -n 'h;s,^.* Date: *\([^ ]*\) .*$$,DATE "\1",p;g;s,^.* Date: *[^ ]* *\([^ ]*\) .*$$,TIME "\1",p') \
| sed 's,^,#define SMARTMONTOOLS_SVN_,' >> $@
else
# SVN not available, guess version info from Id strings
svnversion.h: CHANGELOG Makefile
echo '/* svnversion.h. Generated by Makefile from Id strings. */' > $@
(cd $(srcdir) && cat CHANGELOG Makefile.am configure.in smart*.in *.cpp *.h *.s) \
| sed -n 's,^.*\$$[I][d]: [^ ]* \([0-9][0-9]* [0-9][-0-9]* [0-9][:0-9]*\)[^:0-9][^$$]*\$$.*$$,\1,p' \
| sort -n -r \
| sed -n 'h;s,^\([^ ]*\) .*$$,REV "\1",p;g;s,^[^ ]* \([^ ]*\) .*$$,DATE "\1",p;g;s,^[^ ]* [^ ]* \([^ ]*\)$$,TIME "\1",p;q' \
| sed 's,^,#define SMARTMONTOOLS_SVN_,' >> $@
endif
# Drive Database
drivedb.h: knowndrives.cpp Makefile
echo '/* drivedb.h. Generated from knowndrives.cpp by Makefile. */' > $@
sed '1,/^\/\/ BEGIN drivedb.h/d;/^\/\/ END drivedb.h/,$$d;s/^ //' $(srcdir)/knowndrives.cpp >> $@
if ENABLE_DRIVEDB
drivedb_DATA = drivedb.h
endif
if ENABLE_SAVESTATES
# Create $(savestatesdir) only
savestates_DATA =
endif
if ENABLE_ATTRIBUTELOG
# Create $(attributelogdir) only
attributelog_DATA =
endif
smartd.conf.5.in: smartd.8.in
sed '1,/STARTINCLUDE/ D;/ENDINCLUDE/,$$D' < $(srcdir)/smartd.8.in > $(top_builddir)/tmp.directives
@ -255,6 +331,7 @@ smartd.conf.5.in: smartd.8.in
cat $(top_builddir)/tmp.tail >> $(srcdir)/smartd.conf.5.in
rm -f $(top_builddir)/tmp.head $(top_builddir)/tmp.tail $(top_builddir)/tmp.directives
if INSTALL_INITSCRIPT
if OS_DARWIN
initd_DATA = SMART \
os_darwin/StartupParameters.plist \
@ -263,6 +340,7 @@ initd_DATA = SMART \
initd_install_name = SMART
initd_DATA_install = install-initdDATA-darwin
initd_DATA_uninstall = uninstall-initdDATA-darwin
SMART : os_darwin/SMART.in
sed "s|/usr/sbin/|$(sbindir)/|" $< > $@
@ -288,6 +366,9 @@ install-initdDATA-darwin: $(initd_DATA)
@echo -e "# to learn about it. A sample configuration file can be found in:\n# ${docdir}\n#"
@echo -e "####################################################################\n\n"
uninstall-initdDATA-darwin:
rm -rf $(DESTDIR)$(initddir)/$(initd_install_name)
else
initd_DATA = smartd.initd
@ -298,6 +379,7 @@ smartd.initd: $(srcdir)/smartd.initd.in Makefile
initd_install_name = smartd$(smartd_suffix)
initd_DATA_install = install-initdDATA-generic
initd_DATA_uninstall = uninstall-initdDATA-generic
install-initdDATA-generic: $(initd_DATA)
$(mkinstalldirs) $(DESTDIR)$(initddir)
@ -310,26 +392,72 @@ install-initdDATA-generic: $(initd_DATA)
@echo -e "# to learn about it. A sample configuration file can be found in:\n# ${docdir}\n#"
@echo -e "####################################################################\n\n"
uninstall-initdDATA-generic:
rm -rf $(DESTDIR)$(initddir)/$(initd_install_name)
endif
else
initd_DATA_install = install-initdDATA-null
initd_DATA_uninstall = uninstall-initdDATA-null
install-initdDATA-null:
uninstall-initdDATA-null:
endif
install-initdDATA : $(initd_DATA_install)
uninstall-initdDATA:
rm -rf $(DESTDIR)$(initddir)/$(initd_install_name)
uninstall-initdDATA: $(initd_DATA_uninstall)
uninstall-docsDATA:
rm -rf $(DESTDIR)$(docsdir)
if ENABLE_DRIVEDB
MAN_DRIVEDB = sed "s|/usr/local/share/smartmontools/drivedb\\.h|$(drivedbdir)/drivedb.h|g"
else
MAN_DRIVEDB = sed '/BEGIN ENABLE_DRIVEDB/,/END ENABLE_DRIVEDB/d'
endif
smart%: $(srcdir)/smart%.in Makefile
if ENABLE_SAVESTATES
MAN_SAVESTATES = sed "s|/usr/local/var/lib/smartmontools/smartd\\.|$(savestates)|g"
else
MAN_SAVESTATES = sed '/BEGIN ENABLE_SAVESTATES/,/END ENABLE_SAVESTATES/d'
endif
if ENABLE_ATTRIBUTELOG
MAN_ATTRIBUTELOG = sed "s|/usr/local/var/lib/smartmontools/attrlog\\.|$(attributelog)|g"
else
MAN_ATTRIBUTELOG = sed '/BEGIN ENABLE_ATTRIBUTELOG/,/END ENABLE_ATTRIBUTELOG/d'
endif
if OS_FREEBSD
.for file in $(man_MANS)
${file}: $(srcdir)/${file}.in Makefile svnversion.h
sed "s|CURRENT_CVS_VERSION|$(releaseversion)|g; \
s|CURRENT_CVS_DATE|`sed -n 's,^.*DATE[^"]*"\([^"]*\)".*$$,\1,p' svnversion.h`|g; \
s|CURRENT_CVS_TIME|`sed -n 's,^.*TIME[^"]*"\([^"]*\)".*$$,\1,p' svnversion.h`|g; \
s|/usr/local/share/man/|$(mandir)/|g; \
s|/usr/local/sbin/|$(sbindir)/|g; \
s|/usr/local/etc/rc\\.d/init.d/|$(initddir)/|g; \
s|/usr/local/share/doc/smartmontools-5.1/|$(docsdir)/|g; \
s|/usr/local/etc/smartd\\.conf|$(sysconfdir)/smartd.conf|g; \
s|/usr/local/etc/smart_drivedb\\.h|$(sysconfdir)/smart_drivedb\\.h|g" ${.ALLSRC:M*.in} | \
$(MAN_DRIVEDB) | \
$(MAN_SAVESTATES) | \
$(MAN_ATTRIBUTELOG) > $@
.endfor
else
smart%: $(srcdir)/smart%.in Makefile svnversion.h
sed "s|CURRENT_CVS_VERSION|$(releaseversion)|g" $< | \
sed "s|CURRENT_CVS_DATE|$(smartmontools_release_date)|g" | \
sed "s|CURRENT_CVS_TIME|$(smartmontools_release_time)|g" | \
sed "s|CURRENT_CVS_DATE|`sed -n 's,^.*DATE[^"]*"\([^"]*\)".*$$,\1,p' svnversion.h`|g" | \
sed "s|CURRENT_CVS_TIME|`sed -n 's,^.*TIME[^"]*"\([^"]*\)".*$$,\1,p' svnversion.h`|g" | \
sed "s|/usr/local/share/man/|$(mandir)/|g" | \
sed "s|/usr/local/sbin/|$(sbindir)/|g" | \
sed "s|/usr/local/etc/rc\\.d/init.d/|$(initddir)/|g" | \
sed "s|/usr/local/share/doc/smartmontools-5.1/|$(docsdir)/|g" | \
sed "s|/usr/local/etc/smartd\\.conf|$(sysconfdir)/smartd.conf|g" > $@
sed "s|/usr/local/etc/smartd\\.conf|$(sysconfdir)/smartd.conf|g" | \
sed "s|/usr/local/etc/smart_drivedb\\.h|$(sysconfdir)/smart_drivedb\\.h|g" | \
$(MAN_DRIVEDB) | \
$(MAN_SAVESTATES) | \
$(MAN_ATTRIBUTELOG) > $@
endif
# Commands to convert man pages into .html and .txt
# TODO: configure
@ -385,6 +513,7 @@ exedir_win32 = $(distdir_win32)/bin
docdir_win32 = $(distdir_win32)/doc
FILES_WIN32 = $(exedir_win32)/smartctl.exe \
$(exedir_win32)/smartctl-nc.exe \
$(exedir_win32)/smartd.exe \
$(docdir_win32)/AUTHORS.txt \
$(docdir_win32)/CHANGELOG.txt \
@ -402,7 +531,9 @@ FILES_WIN32 = $(exedir_win32)/smartctl.exe \
$(docdir_win32)/smartd.conf.5.html \
$(docdir_win32)/smartd.conf.5.txt
CLEANFILES += $(FILES_WIN32) $(exedir_win32)/syslogevt.exe distdir.mkdir syslogevt.check
CLEANFILES += $(FILES_WIN32) $(exedir_win32)/syslogevt.exe \
smartctl-nc.exe smartctl-nc.exe.tmp \
distdir.mkdir syslogevt.check
# Textfile converter from cygutils
UNIX2DOS = unix2dos -D
@ -435,8 +566,11 @@ $(distinst_win32): $(srcdir)/os_win32/installer.nsi distdir.mkdir $(FILES_WIN32)
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"
date=`sed -n 's,^.*DATE[^"]*"\([^"]*\)".*$$,\1,p' svnversion.h`; \
rev=`sed -n 's,^.*REV[^"]*"\([^"]*\)".*$$,r\1,p' svnversion.h`; \
verstr="$(PACKAGE_VERSION) $$date $$rev "$(BUILD_INFO); \
echo "$$makensis /V2 /NOCD /DINPDIR=$(distdir_win32) /DOUTFILE=$(distinst_win32) /DVERSTR='$$verstr' $(srcdir)/os_win32/installer.nsi"; \
"$$makensis" /V2 /NOCD /DINPDIR="$(distdir_win32)" /DOUTFILE="$(distinst_win32)" /DVERSTR="$$verstr" "$(srcdir)/os_win32/installer.nsi"
cleandist-win32:
rm -rf $(distdir_win32) distdir.mkdir syslogevt.check
@ -473,15 +607,34 @@ $(docdir_win32)/%.conf: $(srcdir)/%.conf
$(UNIX2DOS) < $< > $@
touch -r $< $@
# Build non-console version of smartctl for GSmartControl.
# The script below changes the word at offset 220 (Subsystem) from 3
# (Console) to 2 (GUI) in a copy of smartctl.exe.
# This will be changed when a tool (like 'editbin') is available in
# the Cygwin distribution
smartctl-nc.exe: smartctl.exe
@rm -f $@
cp -p smartctl.exe $@.tmp
@if test `od -A n -j 220 -N 2 -d $@.tmp` -eq 3; then :; \
else echo "invalid EXE header"; exit 1; fi
@echo "editbin /subsystem:windows $@.tmp"
@echo -ne '\002' | dd bs=1 seek=220 count=1 conv=notrunc of=$@.tmp 2>/dev/null
@if test `od -A n -j 220 -N 2 -d $@.tmp` -eq 2; then :; \
else echo "EXE patch failed"; exit 1; fi
mv -f $@.tmp $@
# Build config_vc6.h for MSVC 6 from MinGW config.h
config-vc6: $(srcdir)/os_win32/config_vc6.h
# Build {config,svnversion}_vc8.h for MSVC8 from MinGW {config,svnversion}.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\|STRINGS_H\|STRTOULL\|U*INT64_T\|UNISTD_H\) 1$$,/* #undef HAVE_\1 */,' | \
sed 's,i.86-pc-mingw32,i686-pc-win32vc6,' > $@
config-vc8: $(srcdir)/os_win32/config_vc8.h $(srcdir)/os_win32/svnversion_vc8.h
$(srcdir)/os_win32/config_vc8.h: config.h
sed '1i/* config_vc8.h. Generated from config.h by Makefile. */' $< | \
sed 's,^#define HAVE_\(ATTR_PACKED\|INTTYPES_H\|STDINT_H\|STRINGS_H\|STRTOULL\|U*INT64_T\|UNISTD_H\|WORKING_SNPRINTF\) 1$$,/* #undef HAVE_\1 */,' | \
sed 's,i.86-pc-mingw32,i686-pc-win32vc8,' > $@
$(srcdir)/os_win32/svnversion_vc8.h: svnversion.h
cp svnversion.h $@
endif

File diff suppressed because it is too large Load Diff

53
NEWS
View File

@ -1,16 +1,61 @@
smartmontools NEWS
------------------
CVS ID: $Id: NEWS,v 1.35 2008/03/10 10:44:30 ballen4705 Exp $
$Id: NEWS 2844 2009-07-18 12:59:21Z chrfranke $
The most up-to-date version of this file is:
http://smartmontools.cvs.sourceforge.net/smartmontools/sm5/NEWS?view=markup
http://smartmontools.svn.sourceforge.net/viewvc/smartmontools/trunk/smartmontools/NEWS?view=markup
Date <Not released yet, please try current SVN>
Summary: smartmontools release 5.39 (UNSTABLE/EXPERIMENTAL)
-----------------------------------------------------------
- Sourcecode repository moved from CVS to SVN
- Support for USB devices with Cypress, JMicron and Sunplus USB bridges
- USB device type autodetection for some devices on Linux and Windows
(http://smartmontools.wiki.sourceforge.net/overview_USB-Support)
- Support for Areca controllers on Linux
- Support for MegaRAID controllers on Linux
- Support for HighPoint RocketRAID controllers on FreeBSD
- Support RAID controllers using /dev/pass devices on FreeBSD
- Support CHECK_POWER_MODE and WRITE_LOG on FreeBSD
- Support for up to 128 devices on 3ware controllers
- smartctl option '-l xerror' to print ATA SMART Extended Comprehensive
Error Log
- smartctl option '-l xselftest' to print ATA SMART Extended Self-test Log
- smartctl option '-l sataphy' to print SATA Phy Event Counters
- smartctl options '-l gplog,...' and '-l smartlog,...' to print any log page
- smartctl prints SCSI load/unload cycle counts
- Improve display of huge raw values of some SMART attributes
- Option '-d sat+TYPE' to use SAT with controllers which require '-d TYPE'
- Many additions to drive database
- New simplified syntax for drive database
- Option '-B FILE' to read drive database from a file
- Configure option to add drive database file to distribution
- smartd can now handle attributes 197 and 198 with increasing raw values
- smartd logs changes of self-test execution status
- smartd directive '-n powermode,N' to limit the number of skipped checks
- smartd supports scheduled Selective Self-Tests
- Self-tests scheduled during downtime are run after next startup
- Option '-s PREFIX' to store smartd internal state until next startup
- Configure option to enable the above by default
- Change to an object oriented interface to access ATA and SCSI devices
- Linux and Win32 modules migrated to new interface
- Rework of smartd data structures
- Checkin date and SVN revision and optional BUILD_INFO printed in version info
- Better support for gSmartControl on Windows
- SELinux fixes to 3ware device node creation
- Fix CCISS file descriptor leak on FreeBSD
- Compile fixes for Solaris and FreeBSD
- Use getaddrinfo() instead of gethostbyname() to support IPv6
- C++ Support for QNX Target, already tested for QNX 6.3.2 on x86 and
armle target
- Additional support for Samsung MLC flash drives
Date 2008-03-10
Summary: smartmontools release 5.38 (STABLE)
--------------------------------------------
This is a stable release of smartmontools. In addition to changes
below, it includes:
- Libata/Marvell driver devices no longer need explicit '-d' switch
- DEVICESCAN automatically detects libata/marvell driver SATA devices
- Fixed auto-offline/autosave support in FreeBSD
@ -38,7 +83,7 @@ below, it includes:
- Additional command line options for selective self-tests
- Compilation fixes for various platforms.
See CHANGELOG for more details, or smartmontools CVS for still further
See CHANGELOG for more details, or smartmontools SVN for still further
details.
Date 2006-12-20

29
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.57 2008/03/04 22:09:47 ballen4705 Exp $
$Id: README 2844 2009-07-18 12:59:21Z chrfranke $
== HOME ==
The home for smartmontools is located at:
@ -19,7 +19,7 @@ You will find a mailing list for support and other questions at:
== COPYING ==
Copyright (C) 2002-8 Bruce Allen <smartmontools-support@lists.sourceforge.net>
Copyright (C) 2002-9 Bruce Allen <smartmontools-support@lists.sourceforge.net>
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the Free
@ -71,32 +71,19 @@ Source tarballs
http://sourceforge.net/project/showfiles.php?group_id=64297
CVS
SVN
---
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
svn co https://smartmontools.svn.sourceforge.net/svnroot/smartmontools/trunk/smartmontools smartmontools
This will create a subdirectory called sm5/ containing the code.
This will create a subdirectory called smartmontools containing the code.
To instead get the 5.1-16 release:
To instead get the 5.38 release:
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:
cd sm5
cvs up -r RELEASE_5_1_18
To update any tagged release to the latest development code:
cd sm5
cvs up -A
svn co https://smartmontools.svn.sourceforge.net/svnroot/smartmontools/tags/RELEASE_5_38/sm5 smartmontools
You can see what the different tags are by looking at
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".
http://smartmontools.svn.sourceforge.net/viewvc/smartmontools/tags/
== BUILDING/INSTALLING SMARTMONTOOLS ==

68
TODO
View File

@ -1,34 +1,6 @@
TODO list for smartmontools:
$Id: TODO,v 1.64 2007/09/03 19:36:58 chrfranke Exp $
SATA devices under Linux
------------------------
These work OK if you use the standard IDe drivers in drivers/ide.
The situation is more complicated if you use libata.
Prior to Linux kernel version 2.6.15-rc1, libata does not support the
HDIO_DRIVE_TASK, HDIO_DRIVE_CMD, and HDIO_DRIVE_TASKFILE ioctl()s that
are needed by smartmontools. Support for HDIO_DRIVE_TASK and
HDIO_DRIVE_CMD was added into libata by Jeff Garzik starting with
Linux kernel version 2.6.15-rc1. Starting with this version, you can
use all the smartmontools commands apart from initiating selective
self-tests (which also requires HDIO_DRIVE_TASKFILE). A typical
command line might look like this:
smartctl -a -d ata /dev/sda
The '-d ata' is required, since otherwise smartmontools will assume
that the device is SCSI, not ATA/SATA. Similar syntax will work with
smartd.
You may be able to patch earlier versions of libata. Please search the
Linux Kernel Mailing list to find this patch, or look at the thread:
http://groups.google.de/groups?hl=en&lr=&ie=UTF-8&threadm=2yYBY-4HB-55%40gated-at.bofh.it&rnum=3&prev=/groups%3Fq%3Dsmartmontools%26hl%3Den%26lr%3D%26ie%3DUTF-8%26scoring%3Dd%26selm%3D2yYBY-4HB-55%2540gated-at.bofh.it%26rnum%3D3
To use this, just use (for example) 'smartctl -a -d ata /dev/sda'.
Since this looks like this patch will become standard, we need to add something
to smartmontools to automatically recognize the libata, and add the '-d ata'
automatically.
$Id: TODO 2845 2009-07-18 13:25:18Z chrfranke $
USB devices under Linux
-----------------------
@ -38,42 +10,19 @@ command sets. Work on improving the detection and bail-out procedures
for these flawed devices, so that the user sees an informative error
message and smartd/smartctl don't hang.
ATA-4 (no kidding!)
-------------------
smartctl: add another -t TESTTYPE option to accomodate old-style ATA-4
IBM disks (ATA-4 has no self-test commands). See IBM S25L-2426-02 OEM
HARD DISK DRIVE SPECIFICATIONS for DBCA-203240/204860/206480 2.5-Inch
Hard Disk Drive with ATA Interface Revision (1.0)
http://www.hgst.com/tech/techlib.nsf/techdocs/85256AB8006A31E587256A7D00642A1D/$file/dbca_sp.pdf
section 12.30.1.5 for details. These disks offer no self-test option,
and the -t offline command only tests a small part of the disk (a
'segment'). We need a -t multioffline that:
(1) issues auto offline immediate command (tests ONE segment)
(2) waits until estimated completion time
(3) tests if off-line data collection status is set to 0x02 (all
segments completed)
(4) if not, return to (1)
ATA-6/7
-------
Support extended error logs
Support extended self-test logs
ATA-8
-----
Add ability to print counters/values from "Device Statistics" pages
(General Purpose Log address 0x04).
See ATA ACS-2 T13/2015-D Revision 1, Section A.5.
smartctl/smartd
---------------
Add additional -v options (corresponding to comments in
atacmds.c:ataPrintSmartAttribName().
Add interface to Megaraid ATA RAID controllers (Erik)
smartctl:
---------
Add command line option to issue SMART SAVE ATTRIBUTE VALUES command
Feature Register value ATA_SMART_SAVE 0xd3
Perhaps modify the -q option (quiet mode) so that it only warns of ATA
errors if they have (say) taken place in the last 168 hours (week).
Parse and print additional Attribute flag meanings (IBM ones, eg
performance etc). These are now documented in atacmds.h -- we just
need to modify the format of the Attribute table.
@ -101,6 +50,11 @@ that can be monitored.
Packaging
---------
Rework 'do_release' script for SVN.
Under freebsd and solaris, the following are wrong:
smartd.conf: has linux device paths
smart*.in : man pages have (mostly) linux device paths
configure packages with --enable-drivedb (?)
configure packages with --enable-savestates (?)

View File

@ -1,7 +1,7 @@
$Id: WARNINGS,v 1.33 2006/05/19 16:33:33 chrfranke Exp $
$Id: WARNINGS 2844 2009-07-18 12:59:21Z chrfranke $
The most recent version of this file can be found here:
http://smartmontools.cvs.sourceforge.net/smartmontools/sm5/WARNINGS?view=markup
http://smartmontools.svn.sourceforge.net/viewvc/smartmontools/trunk/smartmontools/WARNINGS?view=markup
The following are reports of serious problems (eg system lockup) which
were due to smartmontools. There are DARWIN, LINUX, FREEBSD, SOLARIS
@ -99,17 +99,7 @@ SOLARIS
CYGWIN and WINDOWS
------------------
SYSTEM: Any Windows NT4, 2000 or XP system.
PROBLEM: Use of undocumented system calls for IDE/ATA read log
(smartctl -l, --log, -a, --all) may affect system stability.
REPORTER: Christian Franke <smartmontools-support@lists.sourceforge.net>
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
command SCSIOP_ATA_PASSTHROUGH (0xCC).
2000/XP: Undocumented IOCTL_IDE_PASS_THROUGH.
[No problem reports yet.]
DARWIN

925
aclocal.m4 vendored
View File

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

View File

@ -26,7 +26,7 @@
#define COMMAND_TABLE_SIZE 256
const char *atacmdnames_c_cvsid="$Id: atacmdnames.cpp,v 1.16 2008/03/04 22:09:47 ballen4705 Exp $" ATACMDNAMES_H_CVSID;
const char *atacmdnames_c_cvsid="$Id: atacmdnames.cpp,v 1.17 2008/03/29 23:41:28 shattered Exp $" ATACMDNAMES_H_CVSID;
const char cmd_reserved[] = "[RESERVED]";
const char cmd_vendor_specific[] = "[VENDOR SPECIFIC]";
@ -289,7 +289,7 @@ const char *command_table[COMMAND_TABLE_SIZE] = {
f_reg is used in look_up_ata_command(). If this
command code is reclaimed in a future standard then
be sure to update look_up_ata_command(). */
"FLUSH CACHE EXIT",
"FLUSH CACHE EXT",
cmd_reserved,
"IDENTIFY DEVICE",
"MEDIA EJECT",

File diff suppressed because it is too large Load Diff

360
atacmds.h
View File

@ -3,7 +3,8 @@
*
* Home page of code is: http://smartmontools.sourceforge.net
*
* Copyright (C) 2002-8 Bruce Allen <smartmontools-support@lists.sourceforge.net>
* Copyright (C) 2002-9 Bruce Allen <smartmontools-support@lists.sourceforge.net>
* Copyright (C) 2008-9 Christian Franke <smartmontools-support@lists.sourceforge.net>
* Copyright (C) 1999-2000 Michael Cornwell <cornwell@acm.org>
*
* This program is free software; you can redistribute it and/or modify
@ -25,7 +26,9 @@
#ifndef ATACMDS_H_
#define ATACMDS_H_
#define ATACMDS_H_CVSID "$Id: atacmds.h,v 1.90 2008/03/04 22:09:47 ballen4705 Exp $\n"
#define ATACMDS_H_CVSID "$Id: atacmds.h 2859 2009-07-23 18:55:06Z chrfranke $"
#include "dev_interface.h" // ata_device
// Macro to check expected size of struct at compile time using a
// dummy typedef. On size mismatch, compiler reports a negative array
@ -64,11 +67,22 @@ typedef enum {
WRITE_LOG
} smart_command_set;
// Possible values for fix_firmwarebug.
enum {
FIX_NOTSPECIFIED = 0,
FIX_NONE,
FIX_SAMSUNG,
FIX_SAMSUNG2,
FIX_SAMSUNG3
};
// ATA Specification Command Register Values (Commands)
#define ATA_IDENTIFY_DEVICE 0xec
#define ATA_IDENTIFY_PACKET_DEVICE 0xa1
#define ATA_SMART_CMD 0xb0
#define ATA_CHECK_POWER_MODE 0xe5
// 48-bit commands
#define ATA_READ_LOG_EXT 0x2F
// ATA Specification Feature Register Values (SMART Subcommands).
// Note that some are obsolete as of ATA-7.
@ -298,6 +312,90 @@ struct ata_smart_errorlog {
#pragma pack()
ASSERT_SIZEOF_STRUCT(ata_smart_errorlog, 512);
// Extended Comprehensive SMART Error Log data structures
// See Section A.7 of
// AT Attachment 8 - ATA/ATAPI Command Set (ATA8-ACS)
// T13/1699-D Revision 6a (Working Draft), September 6, 2008.
// Command data structure
// Table A.9 of T13/1699-D Revision 6a
#pragma pack(1)
struct ata_smart_exterrlog_command
{
unsigned char device_control_register;
unsigned char features_register;
unsigned char features_register_hi;
unsigned char count_register;
unsigned char count_register_hi;
unsigned char lba_low_register;
unsigned char lba_low_register_hi;
unsigned char lba_mid_register;
unsigned char lba_mid_register_hi;
unsigned char lba_high_register;
unsigned char lba_high_register_hi;
unsigned char device_register;
unsigned char command_register;
unsigned char reserved;
unsigned int timestamp;
} ATTR_PACKED;
#pragma pack()
ASSERT_SIZEOF_STRUCT(ata_smart_exterrlog_command, 18);
// Error data structure
// Table A.10 T13/1699-D Revision 6a
#pragma pack(1)
struct ata_smart_exterrlog_error
{
unsigned char device_control_register;
unsigned char error_register;
unsigned char count_register;
unsigned char count_register_hi;
unsigned char lba_low_register;
unsigned char lba_low_register_hi;
unsigned char lba_mid_register;
unsigned char lba_mid_register_hi;
unsigned char lba_high_register;
unsigned char lba_high_register_hi;
unsigned char device_register;
unsigned char status_register;
unsigned char extended_error[19];
unsigned char state;
unsigned short timestamp;
} ATTR_PACKED;
#pragma pack()
ASSERT_SIZEOF_STRUCT(ata_smart_exterrlog_error, 34);
// Error log data structure
// Table A.8 of T13/1699-D Revision 6a
#pragma pack(1)
struct ata_smart_exterrlog_error_log
{
ata_smart_exterrlog_command commands[5];
ata_smart_exterrlog_error error;
} ATTR_PACKED;
#pragma pack()
ASSERT_SIZEOF_STRUCT(ata_smart_exterrlog_error_log, 124);
// Ext. Comprehensive SMART error log
// Table A.7 of T13/1699-D Revision 6a
#pragma pack(1)
struct ata_smart_exterrlog
{
unsigned char version;
unsigned char reserved1;
unsigned short error_log_index;
ata_smart_exterrlog_error_log error_logs[4];
unsigned short device_error_count;
unsigned char reserved2[9];
unsigned char checksum;
} ATTR_PACKED;
#pragma pack()
ASSERT_SIZEOF_STRUCT(ata_smart_exterrlog, 512);
// Table 45 of T13/1321D Rev 1 spec (Self-test log descriptor entry)
#pragma pack(1)
struct ata_smart_selftestlog_struct {
@ -324,6 +422,42 @@ struct ata_smart_selftestlog {
#pragma pack()
ASSERT_SIZEOF_STRUCT(ata_smart_selftestlog, 512);
// Extended SMART Self-test log data structures
// See Section A.8 of
// AT Attachment 8 - ATA/ATAPI Command Set (ATA8-ACS)
// T13/1699-D Revision 6a (Working Draft), September 6, 2008.
// Extended Self-test log descriptor entry
// Table A.13 of T13/1699-D Revision 6a
#pragma pack(1)
struct ata_smart_extselftestlog_desc
{
unsigned char self_test_type;
unsigned char self_test_status;
unsigned short timestamp;
unsigned char checkpoint;
unsigned char failing_lba[6];
unsigned char vendorspecific[15];
} ATTR_PACKED;
#pragma pack()
ASSERT_SIZEOF_STRUCT(ata_smart_extselftestlog_desc, 26);
// Extended Self-test log data structure
// Table A.12 of T13/1699-D Revision 6a
#pragma pack(1)
struct ata_smart_extselftestlog
{
unsigned char version;
unsigned char reserved1;
unsigned short log_desc_index;
struct ata_smart_extselftestlog_desc log_descs[19];
unsigned char vendor_specifc[2];
unsigned char reserved2[11];
unsigned char chksum;
} ATTR_PACKED;
#pragma pack()
ASSERT_SIZEOF_STRUCT(ata_smart_extselftestlog, 512);
// SMART LOG DIRECTORY Table 52 of T13/1532D Vol 1 Rev 1a
#pragma pack(1)
struct ata_smart_log_entry {
@ -457,97 +591,141 @@ struct ata_sct_temperature_history_table
#pragma pack()
ASSERT_SIZEOF_STRUCT(ata_sct_temperature_history_table, 512);
// Possible values for span_args.mode
enum {
SEL_RANGE, // MIN-MAX
SEL_REDO, // redo this
SEL_NEXT, // do next range
SEL_CONT // redo or next depending of last test status
};
// Arguments for selective self-test
struct ata_selective_selftest_args
{
// Arguments for each span
struct span_args
{
uint64_t start; // First block
uint64_t end; // Last block
int mode; // SEL_*, see above
span_args()
: start(0), end(0), mode(SEL_RANGE) { }
};
span_args span[5]; // Range and mode for 5 spans
int num_spans; // Number of spans
int pending_time; // One plus time in minutes to wait after powerup before restarting
// interrupted offline scan after selective self-test.
int scan_after_select; // Run offline scan after selective self-test:
// 0: don't change,
// 1: turn off scan after selective self-test,
// 2: turn on scan after selective self-test.
ata_selective_selftest_args()
: num_spans(0), pending_time(0), scan_after_select(0) { }
};
// Get information from drive
int ataReadHDIdentity(int device, struct ata_identify_device *buf);
int ataCheckPowerMode(int device);
int ataReadHDIdentity(ata_device * device, struct ata_identify_device *buf);
int ataCheckPowerMode(ata_device * device);
/* Read S.M.A.R.T information from drive */
int ataReadSmartValues(int device,struct ata_smart_values *);
int ataReadSmartThresholds(int device, struct ata_smart_thresholds_pvt *);
int ataReadErrorLog(int device, struct ata_smart_errorlog *);
int ataReadSelfTestLog(int device, struct ata_smart_selftestlog *);
int ataReadSelectiveSelfTestLog(int device, struct ata_selective_self_test_log *data);
int ataSmartStatus(int device);
int ataSetSmartThresholds(int device, struct ata_smart_thresholds_pvt *);
int ataReadLogDirectory(int device, struct ata_smart_log_directory *);
int ataReadSmartValues(ata_device * device,struct ata_smart_values *);
int ataReadSmartThresholds(ata_device * device, struct ata_smart_thresholds_pvt *);
int ataReadErrorLog (ata_device * device, ata_smart_errorlog *data,
unsigned char fix_firmwarebug);
int ataReadSelfTestLog(ata_device * device, ata_smart_selftestlog * data,
unsigned char fix_firmwarebug);
int ataReadSelectiveSelfTestLog(ata_device * device, struct ata_selective_self_test_log *data);
int ataSetSmartThresholds(ata_device * device, struct ata_smart_thresholds_pvt *);
int ataReadLogDirectory(ata_device * device, ata_smart_log_directory *, bool gpl);
// Read GP Log page(s)
bool ataReadLogExt(ata_device * device, unsigned char logaddr,
unsigned char features, unsigned page,
void * data, unsigned nsectors);
// Read SMART Log page(s)
bool ataReadSmartLog(ata_device * device, unsigned char logaddr,
void * data, unsigned nsectors);
// Read SMART Extended Comprehensive Error Log
bool ataReadExtErrorLog(ata_device * device, ata_smart_exterrlog * log,
unsigned nsectors);
// Read SMART Extended Self-test Log
bool ataReadExtSelfTestLog(ata_device * device, ata_smart_extselftestlog * log,
unsigned nsectors);
// Read SCT information
int ataReadSCTStatus(int device, ata_sct_status_response * sts);
int ataReadSCTTempHist(int device, ata_sct_temperature_history_table * tmh,
int ataReadSCTStatus(ata_device * device, ata_sct_status_response * sts);
int ataReadSCTTempHist(ata_device * device, ata_sct_temperature_history_table * tmh,
ata_sct_status_response * sts);
// Set SCT temperature logging interval
int ataSetSCTTempInterval(int device, unsigned interval, bool persistent);
int ataSetSCTTempInterval(ata_device * device, unsigned interval, bool persistent);
/* Enable/Disable SMART on device */
int ataEnableSmart ( int device );
int ataDisableSmart (int device );
int ataEnableAutoSave(int device);
int ataDisableAutoSave(int device);
int ataEnableSmart (ata_device * device);
int ataDisableSmart (ata_device * device);
int ataEnableAutoSave(ata_device * device);
int ataDisableAutoSave(ata_device * device);
/* Automatic Offline Testing */
int ataEnableAutoOffline ( int device );
int ataDisableAutoOffline (int device );
int ataEnableAutoOffline (ata_device * device);
int ataDisableAutoOffline (ata_device * device);
/* S.M.A.R.T. test commands */
int ataSmartOfflineTest (int device);
int ataSmartExtendSelfTest (int device);
int ataSmartShortSelfTest (int device);
int ataSmartShortCapSelfTest (int device);
int ataSmartExtendCapSelfTest (int device);
int ataSmartSelfTestAbort (int device);
int ataSmartOfflineTest (ata_device * device);
int ataSmartExtendSelfTest (ata_device * device);
int ataSmartShortSelfTest (ata_device * device);
int ataSmartShortCapSelfTest (ata_device * device);
int ataSmartExtendCapSelfTest (ata_device * device);
int ataSmartSelfTestAbort (ata_device * device);
int ataWriteSelectiveSelfTestLog(ata_device * device, ata_selective_selftest_args & args,
const ata_smart_values * sv, uint64_t num_sectors);
// Returns the latest compatibility of ATA/ATAPI Version the device
// supports. Returns -1 if Version command is not supported
int ataVersionInfo (const char **description, struct ata_identify_device *drive, unsigned short *minor);
int ataVersionInfo(const char ** description, const ata_identify_device * drive, unsigned short * minor);
// If SMART supported, this is guaranteed to return 1 if SMART is enabled, else 0.
int ataDoesSmartWork(int device);
int ataDoesSmartWork(ata_device * device);
// returns 1 if SMART supported, 0 if not supported or can't tell
int ataSmartSupport ( struct ata_identify_device *drive);
int ataSmartSupport(const ata_identify_device * drive);
// Return values:
// 1: SMART enabled
// 0: SMART disabled
// -1: can't tell if SMART is enabled -- try issuing ataDoesSmartWork command to see
int ataIsSmartEnabled(struct ata_identify_device *drive);
int ataIsSmartEnabled(const ata_identify_device * drive);
/* Check SMART for Threshold failure */
// onlyfailed=0 : are or were any age or prefailure attributes <= threshold
// onlyfailed=1: are any prefailure attributes <= threshold now
int ataCheckSmart ( struct ata_smart_values *data, struct ata_smart_thresholds_pvt *thresholds, int onlyfailed);
int ataCheckSmart(const ata_smart_values * data, const ata_smart_thresholds_pvt * thresholds, int onlyfailed);
int ataSmartStatus2(int device);
int ataSmartStatus2(ata_device * device);
// int isOfflineTestTime ( struct ata_smart_values data)
// returns S.M.A.R.T. Offline Test Time in seconds
int isOfflineTestTime ( struct ata_smart_values *data);
int isSmartErrorLogCapable(const ata_smart_values * data, const ata_identify_device * identity);
int isShortSelfTestTime ( struct ata_smart_values *data);
int isSmartTestLogCapable(const ata_smart_values * data, const ata_identify_device * identity);
int isExtendedSelfTestTime ( struct ata_smart_values *data);
int isGeneralPurposeLoggingCapable(const ata_identify_device * identity);
int isSmartErrorLogCapable(struct ata_smart_values *data, struct ata_identify_device *identity);
int isSupportExecuteOfflineImmediate(const ata_smart_values * data);
int isSmartTestLogCapable(struct ata_smart_values *data, struct ata_identify_device *identity);
int isSupportAutomaticTimer(const ata_smart_values * data);
int isGeneralPurposeLoggingCapable(struct ata_identify_device *identity);
int isSupportOfflineAbort(const ata_smart_values * data);
int isSupportExecuteOfflineImmediate ( struct ata_smart_values *data);
int isSupportOfflineSurfaceScan(const ata_smart_values * data);
int isSupportAutomaticTimer ( struct ata_smart_values *data);
int isSupportSelfTest(const ata_smart_values * data);
int isSupportOfflineAbort ( struct ata_smart_values *data);
int isSupportConveyanceSelfTest(const ata_smart_values * data);
int isSupportOfflineSurfaceScan ( struct ata_smart_values *data);
int isSupportSelfTest (struct ata_smart_values *data);
int isSupportConveyanceSelfTest(struct ata_smart_values *data);
int isSupportSelectiveSelfTest(struct ata_smart_values *data);
int isSupportSelectiveSelfTest(const ata_smart_values * data);
inline bool isSCTCapable(const ata_identify_device *drive)
{ return !!(drive->words088_255[206-88] & 0x01); } // 0x01 = SCT support
@ -558,19 +736,20 @@ inline bool isSCTFeatureControlCapable(const ata_identify_device *drive)
inline bool isSCTDataTableCapable(const ata_identify_device *drive)
{ return ((drive->words088_255[206-88] & 0x21) == 0x21); } // 0x20 = SCT Data Table support
int ataSmartTest(int device, int testtype, struct ata_smart_values *data, uint64_t num_sectors);
int ataSmartTest(ata_device * device, int testtype, const ata_selective_selftest_args & args,
const ata_smart_values * sv, uint64_t num_sectors);
int TestTime(struct ata_smart_values *data,int testtype);
int TestTime(const ata_smart_values * data, int testtype);
// Prints the raw value (with appropriate formatting) into the
// character string out.
int64_t ataPrintSmartAttribRawValue(char *out,
struct ata_smart_attribute *attribute,
unsigned char *defs);
const ata_smart_attribute * attribute,
const unsigned char * defs);
// Prints Attribute Name for standard SMART attributes. Writes a
// 30 byte string with attribute name into output
void ataPrintSmartAttribName(char *output, unsigned char id, unsigned char *definitions);
void ataPrintSmartAttribName(char * out, unsigned char id, const unsigned char * definitions);
// This checks the n'th attribute in the attribute list, NOT the
// attribute with id==n. If the attribute does not exist, or the
@ -578,8 +757,8 @@ void ataPrintSmartAttribName(char *output, unsigned char id, unsigned char *defi
// <= threshold (failing) then we the attribute number if it is a
// prefail attribute. Else we return minus the attribute number if it
// is a usage attribute.
int ataCheckAttribute(struct ata_smart_values *data,
struct ata_smart_thresholds_pvt *thresholds,
int ataCheckAttribute(const ata_smart_values * data,
const ata_smart_thresholds_pvt * thresholds,
int n);
// External handler function, for when a checksum is not correct. Can
@ -591,11 +770,11 @@ void checksumwarning(const char *string);
// Returns raw value of Attribute with ID==id. This will be in the
// range 0 to 2^48-1 inclusive. If the Attribute does not exist,
// return -1.
int64_t ATAReturnAttributeRawValue(unsigned char id, struct ata_smart_values *data);
int64_t ATAReturnAttributeRawValue(unsigned char id, const 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);
unsigned char ATAReturnTemperatureValue(const ata_smart_values * data, const unsigned char * defs);
// This are the meanings of the Self-test failure checkpoint byte.
@ -609,41 +788,62 @@ const char *SelfTestFailureCodeName(unsigned char which);
#define MAX_ATTRIBUTE_NUM 256
extern const char *vendorattributeargs[];
// function to parse pairs like "9,minutes" or "220,temp". See end of
// extern.h for definition of defs[]. Returns 0 if pair recognized,
// else 1 if there is a problem. Allocates memory for array if the
// array address is *defs==NULL.
int parse_attribute_def(char *pair, unsigned char **defs);
// else 1 if there is a problem.
int parse_attribute_def(const char * pair, unsigned char * defs);
// Function to return a string containing a list of the arguments in
// vendorattributeargs[]. Returns NULL if the required memory can't
// be allocated.
char *create_vendor_attribute_arg_list(void);
// Get ID and increase flag of current pending or offline
// uncorrectable attribute.
unsigned char get_unc_attr_id(bool offline, const unsigned char * defs,
bool & increase);
// Return a multiline string containing a list of valid arguments for
// parse_attribute_def().
std::string create_vendor_attribute_arg_list();
// These are two of the functions that are defined in os_*.c and need
// to be ported to get smartmontools onto another OS.
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);
// Moved to C++ interface
//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);
//int areca_command_interface(int fd, int disknum, smart_command_set command, int select, char *data);
// "smartctl -r ataioctl,2 ..." output parser pseudo-device
int parsedev_open(const char * name);
void parsedev_close(int fd);
// Optional functions of os_*.c
#ifdef HAVE_ATA_IDENTIFY_IS_CACHED
// Return true if OS caches the ATA identify sector
int ata_identify_is_cached(int fd);
//int ata_identify_is_cached(int fd);
#endif
// This function is exported to give low-level capability
int smartcommandhandler(int device, smart_command_set command, int select, char *data);
int smartcommandhandler(ata_device * device, smart_command_set command, int select, char *data);
// Print one self-test log entry.
bool ataPrintSmartSelfTestEntry(unsigned testnum, unsigned char test_type,
unsigned char test_status,
unsigned short timestamp,
uint64_t failing_lba,
bool print_error_only, bool & print_header);
// Print Smart self-test log, used by smartctl and smartd.
int ataPrintSmartSelfTestlog(const ata_smart_selftestlog * data, bool allentries,
unsigned char fix_firmwarebug);
// Get number of sectors from IDENTIFY sector.
uint64_t get_num_sectors(const ata_identify_device * drive);
// Convenience function for formatting strings from ata_identify_device.
void format_ata_string(char * out, const char * in, int n, bool fix_swap);
inline void format_ata_string(char * out, const unsigned char * in, int n, bool fix_swap)
{ format_ata_string(out, (const char *)in, n, fix_swap); }
// Utility routines.
unsigned char checksum(const void * data);
void swap2(char *location);
void swap4(char *location);
void swap8(char *location);
@ -655,4 +855,8 @@ inline void swapx(unsigned int * p)
inline void swapx(uint64_t * p)
{ swap8((char*)p); }
// Return pseudo-device to parse "smartctl -r ataioctl,2 ..." output
// and simulate an ATA device with same behaviour
ata_device * get_parsed_ata_device(smart_interface * intf, const char * dev_name);
#endif /* ATACMDS_H_ */

File diff suppressed because it is too large Load Diff

View File

@ -3,7 +3,8 @@
*
* Home page of code is: http://smartmontools.sourceforge.net
*
* Copyright (C) 2002-8 Bruce Allen <smartmontools-support@lists.sourceforge.net>
* Copyright (C) 2002-9 Bruce Allen <smartmontools-support@lists.sourceforge.net>
* Copyright (C) 2008-9 Christian Franke <smartmontools-support@lists.sourceforge.net>
* Copyright (C) 1999-2000 Michael Cornwell <cornwell@acm.org>
*
* This program is free software; you can redistribute it and/or modify
@ -25,37 +26,97 @@
#ifndef ATAPRINT_H_
#define ATAPRINT_H_
#define ATAPRINT_H_CVSID "$Id: ataprint.h,v 1.31 2008/03/04 22:09:47 ballen4705 Exp $\n"
#define ATAPRINT_H_CVSID "$Id: ataprint.h,v 1.43 2009/07/07 19:28:29 chrfranke Exp $\n"
#include <stdio.h>
#include <stdlib.h>
#include <vector>
/* Prints ATA Drive Information and S.M.A.R.T. Capability */
int ataPrintDriveInfo(struct ata_identify_device *);
// Request to dump a GP or SMART log
struct ata_log_request
{
bool gpl; // false: SMART, true: GP
unsigned char logaddr; // Log address
unsigned page; // First page (sector)
unsigned nsectors; // # Sectors
void ataPrintGeneralSmartValues(struct ata_smart_values *, struct ata_identify_device *);
ata_log_request()
: gpl(false), logaddr(0), page(0), nsectors(0)
{ }
};
void ataPrintSmartThresholds(struct ata_smart_thresholds_pvt *);
// Options for ataPrintMain
// TODO: Move remaining options from con->* to here.
struct ata_print_options
{
bool drive_info;
bool smart_check_status;
bool smart_general_values;
bool smart_vendor_attrib;
bool smart_error_log;
bool smart_selftest_log;
bool smart_selective_selftest_log;
// returns number of errors in Errorlog
int ataPrintSmartErrorlog(struct ata_smart_errorlog *);
bool gp_logdir, smart_logdir;
unsigned smart_ext_error_log;
unsigned smart_ext_selftest_log;
bool retry_error_log, retry_selftest_log;
int ataPrintLogDirectory(struct ata_smart_log_directory *);
std::vector<ata_log_request> log_requests;
void PrintSmartAttributes(struct ata_smart_values *);
bool sct_temp_sts, sct_temp_hist;
bool sataphy, sataphy_reset;
void PrintSmartAttribWithThres(struct ata_smart_values *,
struct ata_smart_thresholds_pvt *,
int onlyfailed);
bool smart_disable, smart_enable;
bool smart_auto_offl_disable, smart_auto_offl_enable;
bool smart_auto_save_disable, smart_auto_save_enable;
// returns number of entries that had logged errors
int ataPrintSmartSelfTestlog(struct ata_smart_selftestlog *, int allentries);
int smart_selftest_type; // OFFLINE_FULL_SCAN, ..., see atacmds.h. -1 for no test
ata_selective_selftest_args smart_selective_args; // Extra args for selective self-test
void ataPseudoCheckSmart(struct ata_smart_values *, struct ata_smart_thresholds_pvt *);
unsigned sct_temp_int;
bool sct_temp_int_pers;
// Convenience function for formatting strings from ata_identify_device.
void format_ata_string(char *out, const char *in, int n);
unsigned char fix_firmwarebug; // FIX_*, see atacmds.h
bool fix_swapped_id; // Fix swapped ID strings returned by some buggy drivers
int ataPrintMain(int fd);
// The i'th entry in this array will modify the printed meaning of
// the i'th SMART attribute. The default definitions of the
// Attributes are obtained by having the array be all zeros. If
// attributedefs[i] is nonzero, it means that the i'th attribute has
// a non-default meaning. See the ataPrintSmartAttribName and
// and parse_attribute_def functions.
unsigned char attributedefs[256];
bool ignore_presets; // Ignore presets from drive database
bool show_presets; // Show presets and exit
unsigned char powermode; // Skip check, if disk in idle or standby mode
ata_print_options()
: drive_info(false),
smart_check_status(false),
smart_general_values(false),
smart_vendor_attrib(false),
smart_error_log(false),
smart_selftest_log(false),
smart_selective_selftest_log(false),
gp_logdir(false), smart_logdir(false),
smart_ext_error_log(0),
smart_ext_selftest_log(0),
retry_error_log(false), retry_selftest_log(false),
sct_temp_sts(false), sct_temp_hist(false),
sataphy(false), sataphy_reset(false),
smart_disable(false), smart_enable(false),
smart_auto_offl_disable(false), smart_auto_offl_enable(false),
smart_auto_save_disable(false), smart_auto_save_enable(false),
smart_selftest_type(-1),
sct_temp_int(0), sct_temp_int_pers(false),
fix_firmwarebug(FIX_NOTSPECIFIED),
fix_swapped_id(false),
ignore_presets(false),
show_presets(false),
powermode(0)
{ memset(attributedefs, 0, sizeof(attributedefs)); }
};
int ataPrintMain(ata_device * device, const ata_print_options & options);
#endif

View File

@ -1,5 +1,5 @@
#!/bin/sh
# $Id: autogen.sh,v 1.18 2008/01/29 18:36:20 chrfranke Exp $
# $Id: autogen.sh 2844 2009-07-18 12:59:21Z chrfranke $
#
# Generate ./configure from config.in and Makefile.in from Makefile.am.
# This also adds files like missing,depcomp,install-sh to the source
@ -10,10 +10,6 @@
# Cygwin?
test -x /usr/bin/uname && /usr/bin/uname | grep -i CYGWIN >/dev/null &&
{
# Enable strict case checking
# (to avoid e.g. "DIST_COMMON = ... ChangeLog ..." in Makefile.in)
export CYGWIN="${CYGWIN}${CYGWIN:+ }check_case:strict"
# Check for Unix text file type
echo > dostest.tmp
test "`wc -c < dostest.tmp`" -eq 1 ||
@ -36,17 +32,18 @@ typep()
return 1
}
test -x "$AUTOMAKE" || AUTOMAKE=`typep automake-1.10` || AUTOMAKE=`typep automake-1.9` ||
AUTOMAKE=`typep automake-1.8` || AUTOMAKE=`typep automake-1.7` || AUTOMAKE=`typep automake17` ||
test -x "$AUTOMAKE" || AUTOMAKE=`typep automake-1.11` || AUTOMAKE=`typep automake-1.10` ||
AUTOMAKE=`typep automake-1.9` || AUTOMAKE=`typep automake-1.8` ||
AUTOMAKE=`typep automake-1.7` || AUTOMAKE=`typep automake17` ||
{
echo
echo "You must have at least GNU Automake 1.7 (up to 1.9.x) installed"
echo "in order to bootstrap smartmontools from CVS. Download the"
echo "You must have at least GNU Automake 1.7 (up to 1.11) installed"
echo "in order to bootstrap smartmontools from SVN. Download the"
echo "appropriate package for your distribution, or the source tarball"
echo "from ftp://ftp.gnu.org/gnu/automake/ ."
echo
echo "Also note that support for new Automake series (anything newer"
echo "than 1.9.x) is only added after extensive tests. If you live in"
echo "than 1.11) is only added after extensive tests. If you live in"
echo "the bleeding edge, you should know what you're doing, mainly how"
echo "to test it before the developers. Be patient."
exit 1;
@ -55,31 +52,45 @@ exit 1;
test -x "$ACLOCAL" || ACLOCAL="aclocal`echo "$AUTOMAKE" | sed 's/.*automake//'`" && ACLOCAL=`typep "$ACLOCAL"` ||
{
echo
echo "autogen.sh found automake-1.7, automake-1.8, or automake-1.9 in"
echo "your PATH, but not the respective aclocal-1.7, aclocal-1.8, or"
echo "aclocal-1.9. Your installation of GNU Automake is broken or"
echo "incomplete."
echo "autogen.sh found automake-1.X, but not the respective aclocal-1.X."
echo "Your installation of GNU Automake is broken or incomplete."
exit 2;
}
# Warn if Automake version is unknown
ver=
# Detect Automake version
case "$AUTOMAKE" in
*automake-1.[78]|*automake17)
;;
*automake-1.7|*automake17)
ver=1.7 ;;
*automake-1.8)
ver=1.8 ;;
*)
ver="`$AUTOMAKE --version | sed -n '1s,^.*\([12]\.[.0-9]*[-pl0-9]*\).*$,\1,p'`"
ver="${ver:-?.?.?}"
case "$ver" in
1.[78]*|1.9.[1-6]|1.10) ver= ;;
esac ;;
esac
test -z "$ver" ||
{
echo "Note: GNU Automake version ${ver} was not tested by the developers."
echo "Please report success/failure to the smartmontools-support mailing list."
}
# Warn if Automake version was not tested or does not support filesystem
case "$ver" in
1.[78]|1.[78].*)
# Check for case sensitive filesystem
# (to avoid e.g. "DIST_COMMON = ... ChangeLog ..." in Makefile.in on Cygwin)
rm -f CASETEST.TMP
echo > casetest.tmp
test -f CASETEST.TMP &&
{
echo "Warning: GNU Automake version ${ver} does not properly handle case"
echo "insensitive filesystems. Some make targets may not work."
}
rm -f casetest.tmp
;;
1.9.[1-6]|1.10|1.10.[12]|1.11)
# OK
;;
*)
echo "Note: GNU Automake version ${ver} was not tested by the developers."
echo "Please report success/failure to the smartmontools-support mailing list."
esac
set -e # stops on error status

View File

@ -26,6 +26,9 @@
#include "scsicmds.h"
#include "utility.h"
const char *cciss_c_cvsid="$Id: cciss.cpp,v 1.9 2008/07/30 20:42:53 chrfranke Exp $"
CONFIG_H_CVSID INT64_H_CVSID SCSICMDS_H_CVSID UTILITY_H_CVSID;
typedef struct _ReportLUNdata_struct
{
uint32_t LUNListLength; /* always big-endian */
@ -177,7 +180,6 @@ static int cciss_getlun(int device, int target, unsigned char *physlun, int repo
unsigned char CDB[16]= {0};
ReportLunData_struct *luns;
int reportlunsize = sizeof(*luns) + CISS_MAX_PHYS_LUN * 8;
int i;
int ret;
luns = (ReportLunData_struct *)malloc(reportlunsize);
@ -209,7 +211,7 @@ static int cciss_getlun(int device, int target, unsigned char *physlun, int repo
pout("%02x ",*stuff++);
pout("%02x\n",*stuff++);
}
pout("===== [%s] DATA END (%d Bytes) =====\n\n", "LUN DATA", sizeof(_ReportLUNdata_struct));
pout("===== [%s] DATA END (%u Bytes) =====\n\n", "LUN DATA", (unsigned)sizeof(_ReportLUNdata_struct));
}
if (target >= 0 && target < (int) be32toh(luns->LUNListLength) / 8)

1500
config.guess vendored

File diff suppressed because it is too large Load Diff

View File

@ -1,157 +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 <dev/ciss/cissio.h> header file. */
#undef HAVE_DEV_CISS_CISSIO_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 <linux/cciss_ioctl.h> header file. */
#undef HAVE_LINUX_CCISS_IOCTL_H
/* Define to 1 if you have the <linux/compiler.h> header file. */
#undef HAVE_LINUX_COMPILER_H
/* Define to 1 if you have the <locale.h> header file. */
#undef HAVE_LOCALE_H
/* 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

1616
config.sub vendored

File diff suppressed because it is too large Load Diff

9685
configure vendored

File diff suppressed because it is too large Load Diff

View File

@ -1,13 +1,13 @@
#
# $Id: configure.in,v 1.135 2008/03/10 10:44:30 ballen4705 Exp $
# $Id: configure.in 2870 2009-08-02 20:38:30Z manfred99 $
#
dnl Process this file with autoconf to produce a configure script.
AC_PREREQ(2.50)
AC_INIT(smartmontools, 5.38, smartmontools-support@lists.sourceforge.net)
AC_INIT(smartmontools, 5.39, 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.135 2008/03/10 10:44:30 ballen4705 Exp $'`
smartmontools_cvs_tag=`echo '$Id: configure.in 2870 2009-08-02 20:38:30Z manfred99 $'`
smartmontools_release_date=2008/03/10
smartmontools_release_time="10:44:07 GMT"
@ -43,14 +43,28 @@ case "${host}" in
;;
esac
dnl Checks for libraries.needed for gethostbyname (Solaris needs
# Check for SVN.
AC_MSG_CHECKING([whether this is a build from SVN])
is_svn_build=no
if test -f "$srcdir/.svn/entries"; then
is_svn_build=unknown
if (cd "$srcdir" && svn --version && svnversion && svn info) >/dev/null 2>&1; then
is_svn_build=yes
fi
fi
AM_CONDITIONAL(IS_SVN_BUILD, [test "$is_svn_build" = "yes"])
AC_MSG_RESULT([$is_svn_build])
dnl Checks for libraries needed for name services (Solaris needs
dnl libnsl, might in the future also need libsocket)
# AC_SEARCH_LIBS (FUNCTION, SEARCH-LIBS, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND], [OTHER-LIBRARIES])
AC_SEARCH_LIBS(gethostbyname, nsl, , AC_SEARCH_LIBS(gethostbyname, nsl, , , -lsocket), , )
AC_SEARCH_LIBS(socket, socket)
AC_SEARCH_LIBS(gethostbyname, nsl)
AC_SEARCH_LIBS(getaddrinfo, nsl)
AC_SEARCH_LIBS(getdomainname, nsl)
dnl Checks for header files.
AC_CHECK_HEADERS([locale.h])
AC_CHECK_HEADERS([getopt.h])
AC_CHECK_HEADERS([dev/ata/atavar.h])
AC_CHECK_HEADERS([netdb.h])
dnl we need [u]int64_t and friends.
@ -78,10 +92,16 @@ dnl Checks for typedefs, structures, and compiler characteristics.
AC_CHECK_TYPES([int64_t, uint64_t])
dnl Checks for library functions.
AC_CHECK_FUNCS([getopt])
AC_CHECK_FUNCS([getopt_long])
AC_CHECK_FUNCS([getopt_long], , [
AC_MSG_NOTICE([smartmontools does no longer support platforms without getopt_long().])
AC_MSG_NOTICE([Please inform ${PACKAGE_BUGREPORT},])
AC_MSG_NOTICE([including details about your build environment.])
AC_MSG_ERROR([function getopt_long() not found])
])
AC_CHECK_FUNCS([getdomainname])
AC_CHECK_FUNCS([gethostname])
AC_CHECK_FUNCS([getaddrinfo])
AC_CHECK_FUNCS([gethostbyname])
AC_CHECK_FUNCS([sigset])
AC_CHECK_FUNCS([strtoull])
@ -124,14 +144,66 @@ AC_SUBST([exampledir], ['${docdir}/examplescripts'])
AC_ARG_WITH(initscriptdir,[AC_HELP_STRING([--with-initscriptdir=dir],[Location of init scripts (default is ${sysconfdir}/rc.d/init.d)])],[initddir="$withval"],[initddir='${sysconfdir}/rc.d/init.d'])
AC_SUBST(initddir)
AM_CONDITIONAL(INSTALL_INITSCRIPT, [test "$with_initscriptdir" != "no"])
AC_ARG_WITH(docdir,[AC_HELP_STRING([--with-docdir=dir],[Location of documentation (default is ${prefix}/share/doc/smartmontools-5.X)])],[docdir="$withval"],[docdir='${prefix}/share/doc/${PACKAGE}-${VERSION}'])
AC_SUBST(docdir)
AC_ARG_ENABLE(drivedb, [AC_HELP_STRING([--enable-drivedb],[Enables drive database file])])
AC_ARG_WITH(drivedbdir,
[AC_HELP_STRING([--with-drivedbdir=DIR],[Location of drive database file (implies --enable-drivedb) [DATADIR/smartmontools]])],
[drivedbdir="$withval"; enable_drivedb="yes"],
[drivedbdir=; test "$enable_drivedb" = "yes" && drivedbdir='${datadir}/${PACKAGE}'])
AC_SUBST(drivedbdir)
AM_CONDITIONAL(ENABLE_DRIVEDB, [test "$enable_drivedb" = "yes"])
AC_ARG_ENABLE(savestates, [AC_HELP_STRING([--enable-savestates],[Enables default smartd state files])])
AC_ARG_WITH(savestates,
[AC_HELP_STRING([--with-savestates=PREFIX],[Prefix for default smartd state files (implies --enable-savestates) [LOCALSTATEDIR/lib/smartmontools/smartd.]])],
[savestates="$withval"; enable_savestates="yes"],
[savestates=; test "$enable_savestates" = "yes" && savestates='${localstatedir}/lib/${PACKAGE}/smartd.'])
savestatesdir="${savestates%/*}"
AC_SUBST(savestates)
AC_SUBST(savestatesdir)
AM_CONDITIONAL(ENABLE_SAVESTATES, [test "$enable_savestates" = "yes"])
AC_ARG_ENABLE(attributelog, [AC_HELP_STRING([--enable-attributelog],[Enables default smartd attribute log files])])
AC_ARG_WITH(attributelog,
[AC_HELP_STRING([--with-attributelog=PREFIX],[Prefix for default smartd attribute log files (implies --enable-attributelog) [LOCALSTATEDIR/lib/smartmontools/attrlog.]])],
[attributelog="$withval"; enable_attributelog="yes"],
[attributelog=; test "$enable_attributelog" = "yes" && attributelog='${localstatedir}/lib/${PACKAGE}/attrlog.'])
attributelogdir="${attributelog%/*}"
AC_SUBST(attributelog)
AC_SUBST(attributelogdir)
AM_CONDITIONAL(ENABLE_ATTRIBUTELOG, [test "$enable_attributelog" = "yes"])
AC_ARG_ENABLE(sample,[AC_HELP_STRING([--enable-sample],[Enables appending .sample to the installed smartd rc script and configuration file])],[smartd_suffix='.sample'],[smartd_suffix=''])
AC_SUBST(smartd_suffix)
AM_CONDITIONAL(SMARTD_SUFFIX, test $smartd_suffix)
AC_ARG_WITH(os-deps,
[AC_HELP_STRING([--with-os-deps='os_module.o ...'],[Specify OS dependent module(s) [guessed]])],
[ for x in $with_os_deps; do
case $x in
*.o) ;;
*) AC_MSG_ERROR([non-object file specified by --with-os-deps]) ;;
esac
done
],[])
AC_ARG_WITH(selinux,[AC_HELP_STRING([--with-selinux],[Enables SELinux support])],
[
AC_CHECK_HEADERS([selinux/selinux.h], [], [echo "*** Error: Missing SELinux header files";exit 1])
AC_CHECK_LIB(selinux, matchpathcon, [with_selinux=yes], [echo "*** Error: Missing or incorrect SELinux library files"; exit 1],)
],[])
AC_SUBST(with_selinux)
if test "$with_selinux" = "yes"; then
AC_DEFINE(WITH_SELINUX, [1], [Define to 1 if SELinux support is enabled])
fi
if test "$prefix" = "NONE"; then
dnl no prefix and no mandir, so use ${prefix}/share/man as default
if test "$mandir" = '${prefix}/man'; then
@ -143,11 +215,16 @@ AC_SUBST(releaseversion,['${PACKAGE}-${VERSION}'])
AC_SUBST(smartmontools_release_date)
AC_SUBST(smartmontools_release_time)
AC_MSG_CHECKING([for OS dependent modules and libraries])
dnl if OS not recognized, then use the os_generic modules
case "${host}" in
*-*-linux*)
AC_SUBST([os_deps], ['os_linux.o cciss.o'])
AC_SUBST([os_libs], ['']) ;;
if test "$with_selinux" = "yes"; then
AC_SUBST([os_libs], ['-lselinux'])
else
AC_SUBST([os_libs], [''])
fi;;
*-*-freebsd*|*-*-dragonfly*|*-*-kfreebsd*-gnu*)
AC_SUBST([os_deps], ['os_freebsd.o cciss.o'])
AC_SUBST([os_libs], ['-lcam']);;
@ -184,6 +261,10 @@ case "${host}" in
AC_SUBST([os_libs], ['']) ;;
esac
# Replace if '--with-os-deps' was specified
test -z "$with_os_deps" || os_deps="$with_os_deps"
AC_MSG_RESULT([$os_deps $os_libs])
# Define symbols for optional functions in OS specific module
case "${os_deps}" in
os_win32*)
@ -194,10 +275,23 @@ case "${os_deps}" in
AC_DEFINE(HAVE_GET_OS_VERSION_STR, 1, [Define to 1 if you have the `get_os_version_str' function in os_*.c.]) ;;
esac
# Check if we need adapter to old interface (dev_legacy.cpp)
os_src=`echo "${os_deps}"|sed -n 's,^\([[^ .]]*\)\.o.*$,\1.cpp,p'`
AC_MSG_CHECKING([whether ${os_src} uses new interface])
if grep "smart_interface" "${srcdir}/${os_src}" >/dev/null 2>&1; then
os_new_interface=yes
else
os_new_interface=no
os_deps="${os_deps} dev_legacy.o"
AC_DEFINE(OLD_INTERFACE, 1, [Define to 1 if os_*.cpp still uses the old interface])
fi
AC_MSG_RESULT([$os_new_interface])
dnl Define platform-specific symbol.
AM_CONDITIONAL(OS_DARWIN, [echo $host_os | grep '^darwin' > /dev/null])
AM_CONDITIONAL(OS_SOLARIS, [echo $host_os | grep '^solaris' > /dev/null])
AM_CONDITIONAL(OS_WIN32_MINGW, [echo $host_os | grep '^mingw' > /dev/null])
AM_CONDITIONAL(OS_FREEBSD, [echo $host_os | grep '^freebsd' > /dev/null])
dnl Add -Wall and -W if using gcc and its not already specified.
if test "x$GCC" = "xyes"; then
@ -230,9 +324,8 @@ else
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"
dnl suppress trivial warnings
CXXFLAGS="-erroff=%none,wbadinitl,wbadasgl,badargtypel2w,badargtype2w $CXXFLAGS"
fi
esac
fi

584
depcomp
View File

@ -1,584 +0,0 @@
#! /bin/sh
# depcomp - compile a program generating dependencies as side-effects
scriptversion=2006-10-15.18
# Copyright (C) 1999, 2000, 2003, 2004, 2005, 2006 Free Software
# Foundation, Inc.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
# 02110-1301, USA.
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program.
# Originally written by Alexandre Oliva <oliva@dcc.unicamp.br>.
case $1 in
'')
echo "$0: No command. Try \`$0 --help' for more information." 1>&2
exit 1;
;;
-h | --h*)
cat <<\EOF
Usage: depcomp [--help] [--version] PROGRAM [ARGS]
Run PROGRAMS ARGS to compile a file, generating dependencies
as side-effects.
Environment variables:
depmode Dependency tracking mode.
source Source file read by `PROGRAMS ARGS'.
object Object file output by `PROGRAMS ARGS'.
DEPDIR directory where to store dependencies.
depfile Dependency file to output.
tmpdepfile Temporary file to use when outputing dependencies.
libtool Whether libtool is used (yes/no).
Report bugs to <bug-automake@gnu.org>.
EOF
exit $?
;;
-v | --v*)
echo "depcomp $scriptversion"
exit $?
;;
esac
if test -z "$depmode" || test -z "$source" || test -z "$object"; then
echo "depcomp: Variables source, object and depmode must be set" 1>&2
exit 1
fi
# Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po.
depfile=${depfile-`echo "$object" |
sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`}
tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`}
rm -f "$tmpdepfile"
# Some modes work just like other modes, but use different flags. We
# parameterize here, but still list the modes in the big case below,
# to make depend.m4 easier to write. Note that we *cannot* use a case
# here, because this file can only contain one case statement.
if test "$depmode" = hp; then
# HP compiler uses -M and no extra arg.
gccflag=-M
depmode=gcc
fi
if test "$depmode" = dashXmstdout; then
# This is just like dashmstdout with a different argument.
dashmflag=-xM
depmode=dashmstdout
fi
case "$depmode" in
gcc3)
## gcc 3 implements dependency tracking that does exactly what
## we want. Yay! Note: for some reason libtool 1.4 doesn't like
## it if -MD -MP comes after the -MF stuff. Hmm.
## Unfortunately, FreeBSD c89 acceptance of flags depends upon
## the command line argument order; so add the flags where they
## appear in depend2.am. Note that the slowdown incurred here
## affects only configure: in makefiles, %FASTDEP% shortcuts this.
for arg
do
case $arg in
-c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;;
*) set fnord "$@" "$arg" ;;
esac
shift # fnord
shift # $arg
done
"$@"
stat=$?
if test $stat -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"
;;
hp2)
# The "hp" stanza above does not work with aCC (C++) and HP's ia64
# compilers, which have integrated preprocessors. The correct option
# to use with these is +Maked; it writes dependencies to a file named
# 'foo.d', which lands next to the object file, wherever that
# happens to be.
# Much of this is similar to the tru64 case; see comments there.
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
tmpdepfile1=$dir$base.d
tmpdepfile2=$dir.libs/$base.d
"$@" -Wc,+Maked
else
tmpdepfile1=$dir$base.d
tmpdepfile2=$dir$base.d
"$@" +Maked
fi
stat=$?
if test $stat -eq 0; then :
else
rm -f "$tmpdepfile1" "$tmpdepfile2"
exit $stat
fi
for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2"
do
test -f "$tmpdepfile" && break
done
if test -f "$tmpdepfile"; then
sed -e "s,^.*\.[a-z]*:,$object:," "$tmpdepfile" > "$depfile"
# Add `dependent.h:' lines.
sed -ne '2,${; s/^ *//; s/ \\*$//; s/$/:/; p;}' "$tmpdepfile" >> "$depfile"
else
echo "#dummy" > "$depfile"
fi
rm -f "$tmpdepfile" "$tmpdepfile2"
;;
tru64)
# The Tru64 compiler uses -MD to generate dependencies as a side
# effect. `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'.
# At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put
# dependencies in `foo.d' instead, so we check for that too.
# Subdirectories are respected.
dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
test "x$dir" = "x$object" && dir=
base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
if test "$libtool" = yes; then
# With Tru64 cc, shared objects can also be used to make a
# static library. This mechanism is used in libtool 1.4 series to
# handle both shared and static libraries in a single compilation.
# With libtool 1.4, dependencies were output in $dir.libs/$base.lo.d.
#
# With libtool 1.5 this exception was removed, and libtool now
# generates 2 separate objects for the 2 libraries. These two
# compilations output dependencies in $dir.libs/$base.o.d and
# in $dir$base.o.d. We have to check for both files, because
# one of the two compilations can be disabled. We should prefer
# $dir$base.o.d over $dir.libs/$base.o.d because the latter is
# automatically cleaned when .libs/ is deleted, while ignoring
# the former would cause a distcleancheck panic.
tmpdepfile1=$dir.libs/$base.lo.d # libtool 1.4
tmpdepfile2=$dir$base.o.d # libtool 1.5
tmpdepfile3=$dir.libs/$base.o.d # libtool 1.5
tmpdepfile4=$dir.libs/$base.d # Compaq CCC V6.2-504
"$@" -Wc,-MD
else
tmpdepfile1=$dir$base.o.d
tmpdepfile2=$dir$base.d
tmpdepfile3=$dir$base.d
tmpdepfile4=$dir$base.d
"$@" -MD
fi
stat=$?
if test $stat -eq 0; then :
else
rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4"
exit $stat
fi
for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4"
do
test -f "$tmpdepfile" && break
done
if test -f "$tmpdepfile"; then
sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile"
# That's a tab and a space in the [].
sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile"
else
echo "#dummy" > "$depfile"
fi
rm -f "$tmpdepfile"
;;
#nosideeffect)
# This comment above is used by automake to tell side-effect
# dependency tracking mechanisms from slower ones.
dashmstdout)
# Important note: in order to support this mode, a compiler *must*
# always write the preprocessed file to stdout, regardless of -o.
"$@" || exit $?
# Remove the call to Libtool.
if test "$libtool" = yes; then
while test $1 != '--mode=compile'; do
shift
done
shift
fi
# Remove `-o $object'.
IFS=" "
for arg
do
case $arg in
-o)
shift
;;
$object)
shift
;;
*)
set fnord "$@" "$arg"
shift # fnord
shift # $arg
;;
esac
done
test -z "$dashmflag" && dashmflag=-M
# Require at least two characters before searching for `:'
# in the target name. This is to cope with DOS-style filenames:
# a dependency such as `c:/foo/bar' could be seen as target `c' otherwise.
"$@" $dashmflag |
sed 's:^[ ]*[^: ][^:][^:]*\:[ ]*:'"$object"'\: :' > "$tmpdepfile"
rm -f "$depfile"
cat < "$tmpdepfile" > "$depfile"
tr ' ' '
' < "$tmpdepfile" | \
## Some versions of the HPUX 10.20 sed can't process this invocation
## correctly. Breaking it into two sed invocations is a workaround.
sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
rm -f "$tmpdepfile"
;;
dashXmstdout)
# This case only exists to satisfy depend.m4. It is never actually
# run, as this mode is specially recognized in the preamble.
exit 1
;;
makedepend)
"$@" || exit $?
# Remove any Libtool call
if test "$libtool" = yes; then
while test $1 != '--mode=compile'; do
shift
done
shift
fi
# X makedepend
shift
cleared=no
for arg in "$@"; do
case $cleared in
no)
set ""; shift
cleared=yes ;;
esac
case "$arg" in
-D*|-I*)
set fnord "$@" "$arg"; shift ;;
# Strip any option that makedepend may not understand. Remove
# the object too, otherwise makedepend will parse it as a source file.
-*|$object)
;;
*)
set fnord "$@" "$arg"; shift ;;
esac
done
obj_suffix="`echo $object | sed 's/^.*\././'`"
touch "$tmpdepfile"
${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@"
rm -f "$depfile"
cat < "$tmpdepfile" > "$depfile"
sed '1,2d' "$tmpdepfile" | tr ' ' '
' | \
## Some versions of the HPUX 10.20 sed can't process this invocation
## correctly. Breaking it into two sed invocations is a workaround.
sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
rm -f "$tmpdepfile" "$tmpdepfile".bak
;;
cpp)
# Important note: in order to support this mode, a compiler *must*
# always write the preprocessed file to stdout.
"$@" || exit $?
# Remove the call to Libtool.
if test "$libtool" = yes; then
while test $1 != '--mode=compile'; do
shift
done
shift
fi
# Remove `-o $object'.
IFS=" "
for arg
do
case $arg in
-o)
shift
;;
$object)
shift
;;
*)
set fnord "$@" "$arg"
shift # fnord
shift # $arg
;;
esac
done
"$@" -E |
sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \
-e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' |
sed '$ s: \\$::' > "$tmpdepfile"
rm -f "$depfile"
echo "$object : \\" > "$depfile"
cat < "$tmpdepfile" >> "$depfile"
sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile"
rm -f "$tmpdepfile"
;;
msvisualcpp)
# Important note: in order to support this mode, a compiler *must*
# always write the preprocessed file to stdout, regardless of -o,
# because we must use -o when running libtool.
"$@" || exit $?
IFS=" "
for arg
do
case "$arg" in
"-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI")
set fnord "$@"
shift
shift
;;
*)
set fnord "$@" "$arg"
shift
shift
;;
esac
done
"$@" -E |
sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::echo "`cygpath -u \\"\1\\"`":p' | sort | uniq > "$tmpdepfile"
rm -f "$depfile"
echo "$object : \\" > "$depfile"
. "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s:: \1 \\:p' >> "$depfile"
echo " " >> "$depfile"
. "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s::\1\::p' >> "$depfile"
rm -f "$tmpdepfile"
;;
none)
exec "$@"
;;
*)
echo "Unknown depmode $depmode" 1>&2
exit 1
;;
esac
exit 0
# Local Variables:
# mode: shell-script
# sh-indentation: 2
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-end: "$"
# End:

126
dev_ata_cmd_set.cpp Normal file
View File

@ -0,0 +1,126 @@
/*
* dev_ata_cmd_set.cpp
*
* Home page of code is: http://smartmontools.sourceforge.net
*
* Copyright (C) 2008 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, see <http://www.gnu.org/licenses/>.
*
*/
#include "config.h"
#include "int64.h"
#include "atacmds.h"
#include "dev_ata_cmd_set.h"
#include <errno.h>
const char * dev_ata_cmd_set_cpp_cvsid = "$Id: dev_ata_cmd_set.cpp,v 1.4 2008/10/24 21:49:23 manfred99 Exp $"
DEV_ATA_CMD_SET_H_CVSID;
/////////////////////////////////////////////////////////////////////////////
// ata_device_with_command_set
// Adapter routine to implement new ATA pass through with old interface
bool ata_device_with_command_set::ata_pass_through(const ata_cmd_in & in, ata_cmd_out & out)
{
if (!ata_cmd_is_ok(in, true)) // data_out_support
return false;
smart_command_set command = (smart_command_set)-1;
int select = 0;
char * data = (char *)in.buffer;
char buffer[512];
switch (in.in_regs.command) {
case ATA_IDENTIFY_DEVICE:
command = IDENTIFY;
break;
case ATA_IDENTIFY_PACKET_DEVICE:
command = PIDENTIFY;
break;
case ATA_CHECK_POWER_MODE:
command = CHECK_POWER_MODE;
data = buffer; data[0] = 0;
break;
case ATA_SMART_CMD:
switch (in.in_regs.features) {
case ATA_SMART_ENABLE:
command = ENABLE;
break;
case ATA_SMART_READ_VALUES:
command = READ_VALUES;
break;
case ATA_SMART_READ_THRESHOLDS:
command = READ_THRESHOLDS;
break;
case ATA_SMART_READ_LOG_SECTOR:
command = READ_LOG;
select = in.in_regs.lba_low;
break;
case ATA_SMART_WRITE_LOG_SECTOR:
command = WRITE_LOG;
select = in.in_regs.lba_low;
break;
case ATA_SMART_DISABLE:
command = DISABLE;
break;
case ATA_SMART_STATUS:
command = (in.out_needed.lba_high ? STATUS_CHECK : STATUS);
break;
case ATA_SMART_AUTO_OFFLINE:
command = AUTO_OFFLINE;
select = in.in_regs.sector_count;
break;
case ATA_SMART_AUTOSAVE:
command = AUTOSAVE;
select = in.in_regs.sector_count;
break;
case ATA_SMART_IMMEDIATE_OFFLINE:
command = IMMEDIATE_OFFLINE;
select = in.in_regs.lba_low;
break;
default:
return set_err(ENOSYS, "Unknown SMART command");
}
break;
default:
return set_err(ENOSYS, "Non-SMART commands not implemented");
}
clear_err(); errno = 0;
int rc = ata_command_interface(command, select, data);
if (rc < 0) {
if (!get_errno())
set_err(errno);
return false;
}
switch (command) {
case CHECK_POWER_MODE:
out.out_regs.sector_count = data[0];
break;
case STATUS_CHECK:
switch (rc) {
case 0: // Good SMART status
out.out_regs.lba_high = 0xc2; out.out_regs.lba_mid = 0x4f;
break;
case 1: // Bad SMART status
out.out_regs.lba_high = 0x2c; out.out_regs.lba_mid = 0xf4;
break;
}
break;
default:
break;
}
return true;
}

46
dev_ata_cmd_set.h Normal file
View File

@ -0,0 +1,46 @@
/*
* dev_ata_cmd_set.h
*
* Home page of code is: http://smartmontools.sourceforge.net
*
* Copyright (C) 2008 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, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef DEV_ATA_CMD_SET_H
#define DEV_ATA_CMD_SET_H
#define DEV_ATA_CMD_SET_H_CVSID "$Id: dev_ata_cmd_set.h,v 1.3 2008/08/23 21:32:12 chrfranke Exp $\n"
#include "atacmds.h" // smart_command_set
#include "dev_interface.h"
/////////////////////////////////////////////////////////////////////////////
// ata_device_with_command_set
/// Adapter class to implement new ATA pass through old interface.
class ata_device_with_command_set
: public /*implements*/ ata_device
{
public:
/// ATA pass through mapped to ata_command_interface().
virtual bool ata_pass_through(const ata_cmd_in & in, ata_cmd_out & out);
protected:
/// Old ATA interface called by ata_pass_through()
virtual int ata_command_interface(smart_command_set command, int select, char * data) = 0;
ata_device_with_command_set()
: smart_device(never_called) { }
};
#endif // DEV_ATA_CMD_SET_H

348
dev_interface.cpp Normal file
View File

@ -0,0 +1,348 @@
/*
* dev_interface.cpp
*
* Home page of code is: http://smartmontools.sourceforge.net
*
* Copyright (C) 2008 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, see <http://www.gnu.org/licenses/>.
*
*/
#include "config.h"
#include "int64.h"
#include "atacmds.h"
#include "scsicmds.h"
#include "dev_interface.h"
#include "dev_tunnelled.h"
#include "utility.h"
#include <stdexcept>
const char * dev_interface_cpp_cvsid = "$Id: dev_interface.cpp,v 1.5 2009/01/30 18:34:55 chrfranke Exp $"
DEV_INTERFACE_H_CVSID;
/////////////////////////////////////////////////////////////////////////////
// smart_device
smart_device::smart_device(smart_interface * intf, const char * dev_name,
const char * dev_type, const char * req_type)
: m_intf(intf), m_info(dev_name, dev_type, req_type),
m_ata_ptr(0), m_scsi_ptr(0)
{
}
smart_device::smart_device(do_not_use_in_implementation_classes)
: m_intf(0), m_ata_ptr(0), m_scsi_ptr(0)
{
throw std::logic_error("smart_device: wrong constructor called in implementation class");
}
smart_device::~smart_device() throw()
{
}
bool smart_device::set_err(int no, const char * msg, ...)
{
if (!msg)
return set_err(no);
m_err.no = no;
va_list ap; va_start(ap, msg);
m_err.msg = vstrprintf(msg, ap);
va_end(ap);
return false;
}
bool smart_device::set_err(int no)
{
smi()->set_err_var(&m_err, no);
return false;
}
smart_device * smart_device::autodetect_open()
{
open();
return this;
}
bool smart_device::owns(const smart_device * /*dev*/) const
{
return false;
}
void smart_device::release(const smart_device * /*dev*/)
{
}
/////////////////////////////////////////////////////////////////////////////
// ata_device
ata_in_regs_48bit::ata_in_regs_48bit()
: features_16(features, prev.features),
sector_count_16(sector_count, prev.sector_count),
lba_low_16(lba_low, prev.lba_low),
lba_mid_16(lba_mid, prev.lba_mid),
lba_high_16(lba_high, prev.lba_high)
{
}
ata_out_regs_48bit::ata_out_regs_48bit()
: sector_count_16(sector_count, prev.sector_count),
lba_low_16(lba_low, prev.lba_low),
lba_mid_16(lba_mid, prev.lba_mid),
lba_high_16(lba_high, prev.lba_high)
{
}
ata_cmd_in::ata_cmd_in()
: direction(no_data),
buffer(0),
size(0)
{
}
ata_cmd_out::ata_cmd_out()
{
}
bool ata_device::ata_pass_through(const ata_cmd_in & in)
{
ata_cmd_out dummy;
return ata_pass_through(in, dummy);
}
bool ata_device::ata_cmd_is_ok(const ata_cmd_in & in,
bool data_out_support /*= false*/,
bool multi_sector_support /*= false*/,
bool ata_48bit_support /*= false*/)
{
// Check DATA IN/OUT
switch (in.direction) {
case ata_cmd_in::no_data: break;
case ata_cmd_in::data_in: break;
case ata_cmd_in::data_out: break;
default:
return set_err(EINVAL, "Invalid data direction %d", (int)in.direction);
}
// Check buffer size
if (in.direction == ata_cmd_in::no_data) {
if (in.size)
return set_err(EINVAL, "Buffer size %u > 0 for NO DATA command", in.size);
}
else {
if (!in.buffer)
return set_err(EINVAL, "Buffer not set for DATA IN/OUT command");
unsigned count = (in.in_regs.prev.sector_count<<16)|in.in_regs.sector_count;
// TODO: Add check for sector count == 0
if (count * 512 != in.size)
return set_err(EINVAL, "Sector count %u does not match buffer size %u", count, in.size);
}
// Check features
if (in.direction == ata_cmd_in::data_out && !data_out_support)
return set_err(ENOSYS, "DATA OUT ATA commands not supported");
if (!(in.size == 0 || in.size == 512) && !multi_sector_support)
return set_err(ENOSYS, "Multi-sector ATA commands not supported");
if (in.in_regs.is_48bit_cmd() && !ata_48bit_support)
return set_err(ENOSYS, "48-bit ATA commands not supported");
return true;
}
bool ata_device::ata_identify_is_cached() const
{
return false;
}
/////////////////////////////////////////////////////////////////////////////
// tunnelled_device_base
tunnelled_device_base::tunnelled_device_base(smart_device * tunnel_dev)
: smart_device(never_called),
m_tunnel_base_dev(tunnel_dev)
{
}
tunnelled_device_base::~tunnelled_device_base() throw()
{
delete m_tunnel_base_dev;
}
bool tunnelled_device_base::is_open() const
{
return (m_tunnel_base_dev && m_tunnel_base_dev->is_open());
}
bool tunnelled_device_base::open()
{
if (!m_tunnel_base_dev)
return set_err(ENOSYS);
if (!m_tunnel_base_dev->open())
return set_err(m_tunnel_base_dev->get_err());
return true;
}
bool tunnelled_device_base::close()
{
if (!m_tunnel_base_dev)
return true;
if (!m_tunnel_base_dev->close())
return set_err(m_tunnel_base_dev->get_err());
return true;
}
bool tunnelled_device_base::owns(const smart_device * dev) const
{
return (m_tunnel_base_dev && (m_tunnel_base_dev == dev));
}
void tunnelled_device_base::release(const smart_device * dev)
{
if (m_tunnel_base_dev == dev)
m_tunnel_base_dev = 0;
}
/////////////////////////////////////////////////////////////////////////////
// smart_interface
// Pointer to (usually singleton) interface object returned by ::smi()
smart_interface * smart_interface::s_instance;
const char * smart_interface::get_os_version_str()
{
return SMARTMONTOOLS_BUILD_HOST;
}
const char * smart_interface::get_valid_dev_types_str()
{
static std::string buf;
if (!buf.empty())
return buf.c_str();
// default
buf = "ata, scsi, sat[,N][+TYPE]";
// append custom
const char * add = get_valid_custom_dev_types_str();
if (!add || !*add)
return buf.c_str();
buf += ", "; buf += add;
return buf.c_str();
}
const char * smart_interface::get_app_examples(const char * /*appname*/)
{
return 0;
}
void smart_interface::set_err(int no, const char * msg, ...)
{
if (!msg) {
set_err(no); return;
}
m_err.no = no;
va_list ap; va_start(ap, msg);
m_err.msg = vstrprintf(msg, ap);
va_end(ap);
}
void smart_interface::set_err(int no)
{
set_err_var(&m_err, no);
}
void smart_interface::set_err_var(smart_device::error_info * err, int no)
{
err->no = no;
err->msg = get_msg_for_errno(no);
if (err->msg.empty() && no != 0)
err->msg = strprintf("Unknown error %d", no);
}
const char * smart_interface::get_msg_for_errno(int no)
{
return strerror(no);
}
/////////////////////////////////////////////////////////////////////////////
// Default device factory
smart_device * smart_interface::get_smart_device(const char * name, const char * type)
{
clear_err();
if (!type || !*type) {
smart_device * dev = autodetect_smart_device(name);
if (!dev && !get_errno())
set_err(EINVAL, "Unable to detect device type");
return dev;
}
smart_device * dev = get_custom_smart_device(name, type);
if (dev || get_errno())
return dev;
if (!strcmp(type, "ata"))
dev = get_ata_device(name, type);
else if (!strcmp(type, "scsi"))
dev = get_scsi_device(name, type);
else if ( ((!strncmp(type, "sat", 3) && (!type[3] || strchr(",+", type[3])))
|| (!strncmp(type, "usb", 3)))) {
// Split "sat...+base..." -> ("sat...", "base...")
unsigned satlen = strcspn(type, "+");
std::string sattype(type, satlen);
const char * basetype = (type[satlen] ? type+satlen+1 : "");
// Recurse to allocate base device, default is standard SCSI
if (!*basetype)
basetype = "scsi";
dev = get_smart_device(name, basetype);
if (!dev) {
set_err(EINVAL, "Type '%s+...': %s", sattype.c_str(), get_errmsg());
return 0;
}
// Result must be SCSI
if (!dev->is_scsi()) {
delete dev;
set_err(EINVAL, "Type '%s+...': Device type '%s' is not SCSI", sattype.c_str(), basetype);
return 0;
}
// Attach SAT tunnel
try {
ata_device * satdev = get_sat_device(sattype.c_str(), dev->to_scsi());
if (!satdev) {
delete dev;
return 0;
}
return satdev;
}
catch (...) {
delete dev; throw;
}
}
else {
set_err(EINVAL, "Unknown device type '%s'", type);
return 0;
}
if (!dev && !get_errno())
set_err(EINVAL, "Not a device of type '%s'", type);
return dev;
}
smart_device * smart_interface::get_custom_smart_device(const char * /*name*/, const char * /*type*/)
{
return 0;
}
const char * smart_interface::get_valid_custom_dev_types_str()
{
return 0;
}

727
dev_interface.h Normal file
View File

@ -0,0 +1,727 @@
/*
* dev_interface.h
*
* Home page of code is: http://smartmontools.sourceforge.net
*
* Copyright (C) 2008-9 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, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef DEV_INTERFACE_H
#define DEV_INTERFACE_H
#define DEV_INTERFACE_H_CVSID "$Id: dev_interface.h,v 1.9 2009/03/12 20:31:12 chrfranke Exp $\n"
#include <stdarg.h>
#include <string>
#include <vector>
#if !defined(__GNUC__) && !defined(__attribute__)
#define __attribute__(x) /**/
#endif
#ifdef _MSC_VER // Disable MSVC warning
#pragma warning(disable:4250) // 'class1' : inherits 'class2::member' via dominance
#endif
/////////////////////////////////////////////////////////////////////////////
// Common functionality for all device types
// Forward declarations
class smart_interface;
class ata_device;
class scsi_device;
/// Base class for all devices
class smart_device
{
// Types
public:
/// Device info strings
struct device_info {
device_info()
{ }
device_info(const char * d_name, const char * d_type, const char * r_type)
: dev_name(d_name), info_name(d_name),
dev_type(d_type), req_type(r_type)
{ }
std::string dev_name; ///< Device (path)name
std::string info_name; ///< Informal name
std::string dev_type; ///< Actual device type
std::string req_type; ///< Device type requested by user, empty if none
};
/// Error (number,message) pair
struct error_info {
explicit error_info(int n = 0)
: no(n) { }
error_info(int n, const char * m)
: no(n), msg(m) { }
void clear()
{ no = 0; msg.erase(); }
int no; ///< Error number
std::string msg; ///< Error message
};
// Construction
protected:
/// Constructor to init interface and device info.
/// Must be called in implementation classes.
smart_device(smart_interface * intf, const char * dev_name,
const char * dev_type, const char * req_type);
/// Dummy enum for dummy constructor.
enum do_not_use_in_implementation_classes { never_called };
/// Dummy constructor for abstract classes.
/// Must never be called in implementation classes.
smart_device(do_not_use_in_implementation_classes);
public:
virtual ~smart_device() throw();
// Attributes
public:
///////////////////////////////////////////////
// Dynamic downcasts to actual device flavor
/// Return true if ATA device
bool is_ata() const
{ return !!m_ata_ptr; }
/// Return true if SCSI device
bool is_scsi() const
{ return !!m_scsi_ptr; }
/// Downcast to ATA device.
ata_device * to_ata()
{ return m_ata_ptr; }
/// Downcast to ATA device (const).
const ata_device * to_ata() const
{ return m_ata_ptr; }
/// Downcast to SCSI device.
scsi_device * to_scsi()
{ return m_scsi_ptr; }
/// Downcast to ATA device (const).
const scsi_device * to_scsi() const
{ return m_scsi_ptr; }
///////////////////////////////////////////////
// Device information
/// Get device info struct.
const device_info & get_info() const
{ return m_info; }
/// Get device (path)name.
const char * get_dev_name() const
{ return m_info.dev_name.c_str(); }
/// Get informal name.
const char * get_info_name() const
{ return m_info.info_name.c_str(); }
/// Get device type.
const char * get_dev_type() const
{ return m_info.dev_type.c_str(); }
/// Get type requested by user, empty if none.
const char * get_req_type() const
{ return m_info.req_type.c_str(); }
protected:
/// R/W access to device info struct.
device_info & set_info()
{ return m_info; }
public:
///////////////////////////////////////////////
// Last error information
/// Get last error info struct.
const error_info & get_err() const
{ return m_err; }
/// Get last error number.
int get_errno() const
{ return m_err.no; }
/// Get last error message.
const char * get_errmsg() const
{ return m_err.msg.c_str(); }
/// Set last error number and message.
/// Printf()-like formatting is supported.
/// Returns false always to allow use as a return expression.
bool set_err(int no, const char * msg, ...)
__attribute__ ((format (printf, 3, 4)));
/// Set last error info struct.
bool set_err(const error_info & err)
{ m_err = err; return false; }
/// Clear last error info.
void clear_err()
{ m_err.clear(); }
/// Set last error number and default message.
/// Message is retrieved from interface's get_msg_for_errno(no).
bool set_err(int no);
// Operations
public:
///////////////////////////////////////////////
// Device open/close
// Must be implemented in derived class
/// Return true if device is open.
virtual bool is_open() const = 0;
/// Open device, return false on error.
virtual bool open() = 0;
/// Close device, return false on error.
virtual bool close() = 0;
/// Open device with autodetection support.
/// May return another device for further access.
/// In this case, the original pointer is no longer valid.
/// Default Implementation calls 'open()' and returns 'this'.
virtual smart_device * autodetect_open();
///////////////////////////////////////////////
// Support for tunnelled devices
/// Return true if other device is owned by this device.
/// Default implementation returns false.
virtual bool owns(const smart_device * dev) const;
/// Release ownership of other device.
/// Default implementation does nothing.
virtual void release(const smart_device * dev);
protected:
/// Set dynamic downcast for ATA
void this_is_ata(ata_device * ata);
// {see below;}
/// Set dynamic downcast for SCSI
void this_is_scsi(scsi_device * scsi);
// {see below;}
/// Get interface which produced this object.
smart_interface * smi()
{ return m_intf; }
/// Get interface which produced this object (const).
const smart_interface * smi() const
{ return m_intf; }
// Implementation
private:
smart_interface * m_intf;
device_info m_info;
ata_device * m_ata_ptr;
scsi_device * m_scsi_ptr;
error_info m_err;
// Prevent copy/assigment
smart_device(const smart_device &);
void operator=(const smart_device &);
};
/////////////////////////////////////////////////////////////////////////////
// ATA specific interface
/// ATA register value and info whether is has been ever set
// (Automatically set by first assignment)
class ata_register
{
public:
ata_register()
: m_val(0x00), m_is_set(false) { }
ata_register & operator=(unsigned char val)
{ m_val = val; m_is_set = true; return * this; }
unsigned char val() const
{ return m_val; }
operator unsigned char() const
{ return m_val; }
bool is_set() const
{ return m_is_set; }
private:
unsigned char m_val; ///< Register value
bool m_is_set; ///< true if set
};
/// ATA Input registers (for 28-bit commands)
struct ata_in_regs
{
// ATA-6/7 register names // ATA-3/4/5 // ATA-8
ata_register features; // features // features
ata_register sector_count; // sector count // count
ata_register lba_low; // sector number // ]
ata_register lba_mid; // cylinder low // ] lba
ata_register lba_high; // cylinder high // ]
ata_register device; // device/head // device
ata_register command; // command // command
/// Return true if any register is set
bool is_set() const
{ return (features.is_set() || sector_count.is_set()
|| lba_low.is_set() || lba_mid.is_set() || lba_high.is_set()
|| device.is_set() || command.is_set()); }
};
/// ATA Output registers (for 28-bit commands)
struct ata_out_regs
{
ata_register error;
ata_register sector_count;
ata_register lba_low;
ata_register lba_mid;
ata_register lba_high;
ata_register device;
ata_register status;
/// Return true if any register is set
bool is_set() const
{ return (error.is_set() || sector_count.is_set()
|| lba_low.is_set() || lba_mid.is_set() || lba_high.is_set()
|| device.is_set() || status.is_set()); }
};
/// 16-bit alias to a 8-bit ATA register pair.
class ata_reg_alias_16
{
public:
ata_reg_alias_16(ata_register & lo, ata_register & hi)
: m_lo(lo), m_hi(hi) { }
ata_reg_alias_16 & operator=(unsigned short val)
{ m_lo = (unsigned char) val;
m_hi = (unsigned char)(val >> 8);
return * this; }
unsigned short val() const
{ return m_lo | (m_hi << 8); }
operator unsigned short() const
{ return m_lo | (m_hi << 8); }
private:
ata_register & m_lo, & m_hi;
// References must not be copied.
ata_reg_alias_16(const ata_reg_alias_16 &);
void operator=(const ata_reg_alias_16 &);
};
/// ATA Input registers for 48-bit commands
// See section 4.14 of T13/1532D Volume 1 Revision 4b
//
// Uses ATA-6/7 method to specify 16-bit registers as
// recent (low byte) and previous (high byte) content of
// 8-bit registers.
//
// (ATA-8 ACS does not longer follow this scheme, it uses
// abstract registers with sufficient size and leaves the
// actual mapping to the transport layer.)
//
struct ata_in_regs_48bit
: public ata_in_regs // "most recently written" registers
{
ata_in_regs prev; ///< "previous content"
// 16-bit aliases for above pair.
ata_reg_alias_16 features_16;
ata_reg_alias_16 sector_count_16;
ata_reg_alias_16 lba_low_16;
ata_reg_alias_16 lba_mid_16;
ata_reg_alias_16 lba_high_16;
/// Return true if 48-bit command
bool is_48bit_cmd() const
{ return prev.is_set(); }
/// Return true if 48-bit command with any nonzero high byte
bool is_real_48bit_cmd() const
{ return ( prev.features || prev.sector_count
|| prev.lba_low || prev.lba_mid || prev.lba_high); }
ata_in_regs_48bit();
};
/// ATA Output registers for 48-bit commands
struct ata_out_regs_48bit
: public ata_out_regs // read with HOB=0
{
ata_out_regs prev; ///< read with HOB=1
// 16-bit aliases for above pair.
ata_reg_alias_16 sector_count_16;
ata_reg_alias_16 lba_low_16;
ata_reg_alias_16 lba_mid_16;
ata_reg_alias_16 lba_high_16;
ata_out_regs_48bit();
};
/// Flags for each ATA output register
struct ata_out_regs_flags
{
bool error, sector_count, lba_low, lba_mid, lba_high, device, status;
/// Return true if any flag is set.
bool is_set() const
{ return ( error || sector_count || lba_low
|| lba_mid || lba_high || device || status); }
/// Default constructor clears all flags.
ata_out_regs_flags()
: error(false), sector_count(false), lba_low(false), lba_mid(false),
lba_high(false), device(false), status(false) { }
};
/// ATA pass through input parameters
struct ata_cmd_in
{
ata_in_regs_48bit in_regs; ///< Input registers
ata_out_regs_flags out_needed; ///< True if output register value needed
enum { no_data = 0, data_in, data_out } direction; ///< I/O direction
void * buffer; ///< Pointer to data buffer
unsigned size; ///< Size of buffer
/// Prepare for 28-bit DATA IN command
void set_data_in(void * buf, unsigned nsectors)
{
buffer = buf;
in_regs.sector_count = nsectors;
direction = data_in;
size = nsectors * 512;
}
/// Prepare for 28-bit DATA OUT command
void set_data_out(const void * buf, unsigned nsectors)
{
buffer = const_cast<void *>(buf);
in_regs.sector_count = nsectors;
direction = data_out;
size = nsectors * 512;
}
/// Prepare for 48-bit DATA IN command
void set_data_in_48bit(void * buf, unsigned nsectors)
{
buffer = buf;
// Note: This also sets 'in_regs.is_48bit_cmd()'
in_regs.sector_count_16 = nsectors;
direction = data_in;
size = nsectors * 512;
}
ata_cmd_in();
};
/// ATA pass through output parameters
struct ata_cmd_out
{
ata_out_regs_48bit out_regs; ///< Output registers
ata_cmd_out();
};
/// ATA device access
class ata_device
: virtual public /*extends*/ smart_device
{
public:
/// ATA pass through.
/// Return false on error.
/// Must be implemented in derived class.
virtual bool ata_pass_through(const ata_cmd_in & in, ata_cmd_out & out) = 0;
/// ATA pass through without output registers.
/// Return false on error.
/// Calls ata_pass_through(in, dummy), cannot be reimplemented.
bool ata_pass_through(const ata_cmd_in & in);
/// Return true if OS caches ATA identify sector.
/// Default implementation returns false.
virtual bool ata_identify_is_cached() const;
protected:
/// Check command input parameters.
/// Calls set_err(...) accordingly.
bool ata_cmd_is_ok(const ata_cmd_in & in,
bool data_out_support = false,
bool multi_sector_support = false,
bool ata_48bit_support = false);
/// Default constructor, registers device as ATA.
ata_device()
: smart_device(never_called)
{ this_is_ata(this); }
};
/////////////////////////////////////////////////////////////////////////////
// SCSI specific interface
struct scsi_cmnd_io;
/// SCSI device access
class scsi_device
: virtual public /*extends*/ smart_device
{
public:
/// SCSI pass through.
/// Returns false on error.
virtual bool scsi_pass_through(scsi_cmnd_io * iop) = 0;
protected:
/// Default constructor, registers device as SCSI.
scsi_device()
: smart_device(never_called)
{ this_is_scsi(this); }
};
/////////////////////////////////////////////////////////////////////////////
// Set dynamic downcasts
// Note that due to virtual inheritance,
// (ata == this) does not imply ((void*)ata == (void*)this))
inline void smart_device::this_is_ata(ata_device * ata)
{
m_ata_ptr = (ata == this ? ata : 0);
}
inline void smart_device::this_is_scsi(scsi_device * scsi)
{
m_scsi_ptr = (scsi == this ? scsi : 0);
}
/////////////////////////////////////////////////////////////////////////////
// smart_device_list
/// List of devices for DEVICESCAN
class smart_device_list
{
// Construction
public:
smart_device_list()
{ }
~smart_device_list() throw()
{
for (unsigned i = 0; i < m_list.size(); i++)
delete m_list[i];
}
// Attributes
unsigned size() const
{ return m_list.size(); }
// Operations
void clear()
{
for (unsigned i = 0; i < m_list.size(); i++)
delete m_list[i];
m_list.clear();
}
void add(smart_device * dev)
{ m_list.push_back(dev); }
void push_back(smart_device * dev)
{ m_list.push_back(dev); }
smart_device * at(unsigned i)
{ return m_list.at(i); }
const smart_device * at(unsigned i) const
{ return m_list.at(i); }
smart_device * release(unsigned i)
{
smart_device * dev = m_list.at(i);
m_list[i] = 0;
return dev;
}
// Implementation
private:
std::vector<smart_device *> m_list;
// Prevent copy/assigment
smart_device_list(const smart_device_list &);
void operator=(const smart_device_list &);
};
/////////////////////////////////////////////////////////////////////////////
// smart_interface
/// The platform interface abstraction
class smart_interface
{
public:
/// Initialize platform interface and register with smi().
/// Must be implemented by platform module and register interface with set()
static void init();
smart_interface()
{ }
virtual ~smart_interface() throw()
{ }
/// Return build host and OS version as static string
virtual const char * get_os_version_str();
/// Return valid args for device type option/directive.
/// Default implementation returns "ata, scsi" concatenated
/// with result from get_valid_custom_dev_types_str() below.
virtual const char * get_valid_dev_types_str();
/// Return example string for program 'appname'.
/// Default implementation returns 0.
/// For the migration of print_smartctl_examples(),
/// function is allowed to print examples to stdout.
/// TODO: Remove this hack.
virtual const char * get_app_examples(const char * appname);
///////////////////////////////////////////////
// Last error information
/// Get last error info struct.
const smart_device::error_info & get_err() const
{ return m_err; }
/// Get last error number.
int get_errno() const
{ return m_err.no; }
/// Get last error message.
const char * get_errmsg() const
{ return m_err.msg.c_str(); }
/// Set last error number and message.
/// Printf()-like formatting is supported.
void set_err(int no, const char * msg, ...)
__attribute__ ((format (printf, 3, 4)));
/// Set last error info struct.
void set_err(const smart_device::error_info & err)
{ m_err = err; }
/// Clear last error info.
void clear_err()
{ m_err.clear(); }
/// Set last error number and default message.
/// Message is retrieved from get_msg_for_errno(no).
void set_err(int no);
/// Set last error number and default message to any error_info.
/// Used by set_err(no).
void set_err_var(smart_device::error_info * err, int no);
/// Convert error number into message, used by set_err(no).
/// Default implementation returns strerror(no).
virtual const char * get_msg_for_errno(int no);
///////////////////////////////////////////////////////////////////////////
// Device factory:
/// Return device object for device 'name' with some 'type'.
/// 'type' is 0 if not specified by user.
/// Return 0 on error.
/// Default implementation selects between ata, scsi and custom device.
virtual smart_device * get_smart_device(const char * name, const char * type);
/// Fill 'devlist' with devices of some 'type' with devices names.
/// specified by some optional 'pattern'.
/// Return false on error.
virtual bool scan_smart_devices(smart_device_list & devlist, const char * type,
const char * pattern = 0) = 0;
protected:
/// Return standard ATA device.
virtual ata_device * get_ata_device(const char * name, const char * type) = 0;
/// Return standard SCSI device.
virtual scsi_device * get_scsi_device(const char * name, const char * type) = 0;
/// Autodetect device if no device type specified.
virtual smart_device * autodetect_smart_device(const char * name) = 0;
/// Return device for platform specific 'type'.
/// Default implementation returns 0.
virtual smart_device * get_custom_smart_device(const char * name, const char * type);
/// Return valid 'type' args accepted by above.
/// This is called in get_valid_dev_types_str().
/// Default implementation returns 0.
virtual const char * get_valid_custom_dev_types_str();
/// Return ATA->SCSI filter for SAT or USB.
/// Override only if platform needs special handling.
virtual ata_device * get_sat_device(const char * type, scsi_device * scsidev);
//{ implemented in scsiata.cpp }
public:
/// Try to detect a SAT device behind a SCSI interface.
/// Inquiry data can be passed if available.
/// Return appropriate device if yes, otherwise 0.
/// Override only if platform needs special handling.
virtual ata_device * autodetect_sat_device(scsi_device * scsidev,
const unsigned char * inqdata, unsigned inqsize);
//{ implemented in scsiata.cpp }
/// Get type name for USB device with known VENDOR:PRODUCT ID.
/// Return name if device known and supported, otherwise 0.
virtual const char * get_usb_dev_type_by_id(int vendor_id, int product_id,
int version = -1);
//{ implemented in scsiata.cpp }
protected:
/// Set interface to use, must be called from init().
static void set(smart_interface * intf)
{ s_instance = intf; }
// Implementation
private:
smart_device::error_info m_err;
friend smart_interface * smi(); // below
static smart_interface * s_instance; ///< Pointer to the interface object.
// Prevent copy/assigment
smart_interface(const smart_interface &);
void operator=(const smart_interface &);
};
/////////////////////////////////////////////////////////////////////////////
// smi()
/// Global access to the (usually singleton) smart_interface
inline smart_interface * smi()
{ return smart_interface::s_instance; }
/////////////////////////////////////////////////////////////////////////////
#endif // DEV_INTERFACE_H

669
dev_legacy.cpp Normal file
View File

@ -0,0 +1,669 @@
/*
* dev_legacy.cpp
*
* Home page of code is: http://smartmontools.sourceforge.net
*
* Copyright (C) 2008 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, see <http://www.gnu.org/licenses/>.
*
*/
#include "config.h"
#include "int64.h"
#include "extern.h"
#include "utility.h"
#include "atacmds.h"
#include "scsicmds.h"
#include "dev_interface.h"
#include "dev_ata_cmd_set.h"
const char * dev_legacy_cpp_cvsid = "$Id: dev_legacy.cpp 2879 2009-08-29 17:19:00Z chrfranke $"
DEV_INTERFACE_H_CVSID;
extern smartmonctrl * con; // con->reportscsiioctl
/////////////////////////////////////////////////////////////////////////////
// Legacy interface declarations (now commented out globally):
// from utility.h:
int guess_device_type(const char * dev_name);
int make_device_names (char ***devlist, const char* name);
int deviceopen(const char *pathname, char *type);
int deviceclose(int fd);
#ifdef HAVE_GET_OS_VERSION_STR
const char * get_os_version_str(void);
#endif
// from atacmds.h:
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);
int areca_command_interface(int fd, int disknum, smart_command_set command, int select, char *data);
#ifdef HAVE_ATA_IDENTIFY_IS_CACHED
int ata_identify_is_cached(int fd);
#endif
// from scsicmds.h:
int do_scsi_cmnd_io(int dev_fd, struct scsi_cmnd_io * iop, int report);
// from smartctl.h:
void print_smartctl_examples();
/////////////////////////////////////////////////////////////////////////////
namespace os { // No need to publish anything, name provided for Doxygen
/////////////////////////////////////////////////////////////////////////////
/// Implement shared open/close routines with old functions.
class legacy_smart_device
: virtual public /*implements*/ smart_device
{
public:
explicit legacy_smart_device(const char * mode)
: smart_device(never_called),
m_fd(-1), m_mode(mode) { }
virtual ~legacy_smart_device() throw();
virtual bool is_open() const;
virtual bool open();
virtual bool close();
protected:
/// Return filedesc for derived classes.
int get_fd() const
{ return m_fd; }
private:
int m_fd; ///< filedesc, -1 if not open.
const char * m_mode; ///< Mode string for deviceopen().
};
legacy_smart_device::~legacy_smart_device() throw()
{
if (m_fd >= 0)
::deviceclose(m_fd);
}
bool legacy_smart_device::is_open() const
{
return (m_fd >= 0);
}
bool legacy_smart_device::open()
{
m_fd = ::deviceopen(get_dev_name(), (char*)m_mode);
if (m_fd < 0) {
set_err((errno==ENOENT || errno==ENOTDIR) ? ENODEV : errno);
return false;
}
return true;
}
bool legacy_smart_device::close()
{
int fd = m_fd; m_fd = -1;
if (::deviceclose(fd) < 0) {
set_err(errno);
return false;
}
return true;
}
/////////////////////////////////////////////////////////////////////////////
/// Implement standard ATA support with old functions
class legacy_ata_device
: public /*implements*/ ata_device_with_command_set,
public /*extends*/ legacy_smart_device
{
public:
legacy_ata_device(smart_interface * intf, const char * dev_name, const char * req_type);
#ifdef HAVE_ATA_IDENTIFY_IS_CACHED
virtual bool ata_identify_is_cached() const;
#endif
protected:
virtual int ata_command_interface(smart_command_set command, int select, char * data);
};
legacy_ata_device::legacy_ata_device(smart_interface * intf, const char * dev_name, const char * req_type)
: smart_device(intf, dev_name, "ata", req_type),
legacy_smart_device("ATA")
{
}
int legacy_ata_device::ata_command_interface(smart_command_set command, int select, char * data)
{
return ::ata_command_interface(get_fd(), command, select, data);
}
#ifdef HAVE_ATA_IDENTIFY_IS_CACHED
bool legacy_ata_device::ata_identify_is_cached() const
{
return !!::ata_identify_is_cached(get_fd());
}
#endif
/////////////////////////////////////////////////////////////////////////////
/// Implement AMCC/3ware RAID support with old functions
class legacy_escalade_device
: public /*implements*/ ata_device_with_command_set,
public /*extends*/ legacy_smart_device
{
public:
legacy_escalade_device(smart_interface * intf, const char * dev_name,
int escalade_type, int disknum);
protected:
virtual int ata_command_interface(smart_command_set command, int select, char * data);
private:
int m_escalade_type; ///< Type string for escalade_command_interface().
int m_disknum; ///< Disk number.
};
legacy_escalade_device::legacy_escalade_device(smart_interface * intf, const char * dev_name,
int escalade_type, int disknum)
: smart_device(intf, dev_name, "3ware", "3ware"),
legacy_smart_device(
escalade_type==CONTROLLER_3WARE_9000_CHAR ? "ATA_3WARE_9000" :
escalade_type==CONTROLLER_3WARE_678K_CHAR ? "ATA_3WARE_678K" :
/* CONTROLLER_3WARE_678K */ "ATA" ),
m_escalade_type(escalade_type), m_disknum(disknum)
{
set_info().info_name = strprintf("%s [3ware_disk_%02d]", dev_name, disknum);
}
int legacy_escalade_device::ata_command_interface(smart_command_set command, int select, char * data)
{
return ::escalade_command_interface(get_fd(), m_disknum, m_escalade_type, command, select, data);
}
/////////////////////////////////////////////////////////////////////////////
/// Implement Areca RAID support with old functions
class legacy_areca_device
: public /*implements*/ ata_device_with_command_set,
public /*extends*/ legacy_smart_device
{
public:
legacy_areca_device(smart_interface * intf, const char * dev_name, int disknum);
protected:
virtual int ata_command_interface(smart_command_set command, int select, char * data);
private:
int m_disknum; ///< Disk number.
};
legacy_areca_device::legacy_areca_device(smart_interface * intf, const char * dev_name, int disknum)
: smart_device(intf, dev_name, "areca", "areca"),
legacy_smart_device("ATA_ARECA"),
m_disknum(disknum)
{
set_info().info_name = strprintf("%s [areca_%02d]", dev_name, disknum);
}
int legacy_areca_device::ata_command_interface(smart_command_set command, int select, char * data)
{
return ::areca_command_interface(get_fd(), m_disknum, command, select, data);
}
/////////////////////////////////////////////////////////////////////////////
/// Implement Marvell support with old functions
class legacy_marvell_device
: public /*implements*/ ata_device_with_command_set,
public /*extends*/ legacy_smart_device
{
public:
legacy_marvell_device(smart_interface * intf, const char * dev_name, const char * req_type);
protected:
virtual int ata_command_interface(smart_command_set command, int select, char * data);
};
legacy_marvell_device::legacy_marvell_device(smart_interface * intf,
const char * dev_name, const char * req_type)
: smart_device(intf, dev_name, "marvell", req_type),
legacy_smart_device("ATA")
{
}
int legacy_marvell_device::ata_command_interface(smart_command_set command, int select, char * data)
{
return ::marvell_command_interface(get_fd(), command, select, data);
}
/////////////////////////////////////////////////////////////////////////////
/// Implement Highpoint RAID support with old functions
class legacy_highpoint_device
: public /*implements*/ ata_device_with_command_set,
public /*extends*/ legacy_smart_device
{
public:
legacy_highpoint_device(smart_interface * intf, const char * dev_name,
unsigned char controller, unsigned char channel, unsigned char port);
protected:
virtual int ata_command_interface(smart_command_set command, int select, char * data);
private:
unsigned char m_hpt_data[3]; ///< controller/channel/port
};
legacy_highpoint_device::legacy_highpoint_device(smart_interface * intf, const char * dev_name,
unsigned char controller, unsigned char channel, unsigned char port)
: smart_device(intf, dev_name, "hpt", "hpt"),
legacy_smart_device("ATA")
{
m_hpt_data[0] = controller; m_hpt_data[1] = channel; m_hpt_data[2] = port;
set_info().info_name = strprintf("%s [hpt_disk_%u/%u/%u]", dev_name, m_hpt_data[0], m_hpt_data[1], m_hpt_data[2]);
}
int legacy_highpoint_device::ata_command_interface(smart_command_set command, int select, char * data)
{
unsigned char old_hpt_data[3];
memcpy(old_hpt_data, con->hpt_data, 3);
memcpy(con->hpt_data, m_hpt_data, 3);
int status = ::highpoint_command_interface(get_fd(), command, select, data);
memcpy(con->hpt_data, old_hpt_data, 3);
return status;
}
/////////////////////////////////////////////////////////////////////////////
/// Implement standard SCSI support with old functions
class legacy_scsi_device
: public /*implements*/ scsi_device,
public /*extends*/ legacy_smart_device
{
public:
legacy_scsi_device(smart_interface * intf, const char * dev_name, const char * req_type);
virtual smart_device * autodetect_open();
virtual bool scsi_pass_through(scsi_cmnd_io * iop);
};
legacy_scsi_device::legacy_scsi_device(smart_interface * intf,
const char * dev_name, const char * req_type)
: smart_device(intf, dev_name, "scsi", req_type),
legacy_smart_device("SCSI")
{
}
bool legacy_scsi_device::scsi_pass_through(scsi_cmnd_io * iop)
{
unsigned char oldtype = con->controller_type, oldport = con->controller_port;
con->controller_type = CONTROLLER_SCSI; con->controller_port = 0;
int status = ::do_scsi_cmnd_io(get_fd(), iop, con->reportscsiioctl);
con->controller_type = oldtype; con->controller_port = oldport;
if (status < 0) {
set_err(-status);
return false;
}
return true;
}
/////////////////////////////////////////////////////////////////////////////
/// Implement CCISS RAID support with old functions
class legacy_cciss_device
: public /*implements*/ scsi_device,
public /*extends*/ legacy_smart_device
{
public:
legacy_cciss_device(smart_interface * intf, const char * name, unsigned char disknum);
virtual bool scsi_pass_through(scsi_cmnd_io * iop);
private:
unsigned char m_disknum; ///< Disk number.
};
legacy_cciss_device::legacy_cciss_device(smart_interface * intf,
const char * dev_name, unsigned char disknum)
: smart_device(intf, dev_name, "cciss", "cciss"),
legacy_smart_device("SCSI"),
m_disknum(disknum)
{
set_info().info_name = strprintf("%s [cciss_disk_%02d]", dev_name, disknum);
}
bool legacy_cciss_device::scsi_pass_through(scsi_cmnd_io * iop)
{
// See os_linux.cpp
unsigned char oldtype = con->controller_type, oldport = con->controller_port;
con->controller_type = CONTROLLER_CCISS; con->controller_port = m_disknum+1;
int status = ::do_scsi_cmnd_io(get_fd(), iop, con->reportscsiioctl);
con->controller_type = oldtype; con->controller_port = oldport;
if (status < 0) {
set_err(-status);
return false;
}
return true;
}
/////////////////////////////////////////////////////////////////////////////
/// SCSI open with autodetection support
smart_device * legacy_scsi_device::autodetect_open()
{
// Open device
if (!open())
return this;
// No Autodetection if device type was specified by user
if (*get_req_type())
return this;
// The code below is based on smartd.cpp:SCSIFilterKnown()
// Get INQUIRY
unsigned char req_buff[64] = {0, };
int req_len = 36;
if (scsiStdInquiry(this, req_buff, req_len)) {
// Marvell controllers fail on a 36 bytes StdInquiry, but 64 suffices
// watch this spot ... other devices could lock up here
req_len = 64;
if (scsiStdInquiry(this, req_buff, req_len)) {
// device doesn't like INQUIRY commands
close();
set_err(EIO, "INQUIRY failed");
return this;
}
}
int avail_len = req_buff[4] + 5;
int len = (avail_len < req_len ? avail_len : req_len);
if (len < 36)
return this;
// Use INQUIRY to detect type
smart_device * newdev = 0;
try {
// 3ware ?
if (!memcmp(req_buff + 8, "3ware", 5) || !memcmp(req_buff + 8, "AMCC", 4)) {
close();
#if defined(_WIN32) || defined(__CYGWIN__)
set_err(EINVAL, "AMCC/3ware controller, please try changing device to %s,N", get_dev_name());
#else
set_err(EINVAL, "AMCC/3ware controller, please try adding '-d 3ware,N',\n"
"you may need to replace %s with /dev/twaN or /dev/tweN", get_dev_name());
#endif
return this;
}
// Marvell ?
if (len >= 42 && !memcmp(req_buff + 36, "MVSATA", 6)) { // TODO: Linux-specific?
//pout("Device %s: using '-d marvell' for ATA disk with Marvell driver\n", get_dev_name());
close();
newdev = new legacy_marvell_device(smi(), get_dev_name(), get_req_type());
newdev->open(); // TODO: Can possibly pass open fd
delete this;
return newdev;
}
// SAT or USB ?
newdev = smi()->autodetect_sat_device(this, req_buff, len);
if (newdev)
// NOTE: 'this' is now owned by '*newdev'
return newdev;
}
catch (...) {
// Cleanup if exception occurs after newdev was allocated
delete newdev;
throw;
}
// Nothing special found
return this;
}
/////////////////////////////////////////////////////////////////////////////
/// Implement platform interface with old functions.
class legacy_smart_interface
: public /*implements*/ smart_interface
{
public:
#ifdef HAVE_GET_OS_VERSION_STR
virtual const char * get_os_version_str();
#endif
virtual const char * get_app_examples(const char * appname);
virtual bool scan_smart_devices(smart_device_list & devlist, const char * type,
const char * pattern = 0);
protected:
virtual ata_device * get_ata_device(const char * name, const char * type);
virtual scsi_device * get_scsi_device(const char * name, const char * type);
virtual smart_device * autodetect_smart_device(const char * name);
virtual smart_device * get_custom_smart_device(const char * name, const char * type);
virtual const char * get_valid_custom_dev_types_str();
};
//////////////////////////////////////////////////////////////////////
#ifdef HAVE_GET_OS_VERSION_STR
const char * legacy_smart_interface::get_os_version_str()
{
return ::get_os_version_str();
}
#endif
const char * legacy_smart_interface::get_app_examples(const char * appname)
{
if (!strcmp(appname, "smartctl"))
::print_smartctl_examples(); // this prints to stdout ...
return 0; // ... so don't print again.
}
ata_device * legacy_smart_interface::get_ata_device(const char * name, const char * type)
{
return new legacy_ata_device(this, name, type);
}
scsi_device * legacy_smart_interface::get_scsi_device(const char * name, const char * type)
{
return new legacy_scsi_device(this, name, type);
}
smart_device * legacy_smart_interface::autodetect_smart_device(const char * name)
{
switch (::guess_device_type(name)) {
case CONTROLLER_ATA : return new legacy_ata_device(this, name, "");
case CONTROLLER_SCSI: return new legacy_scsi_device(this, name, "");
}
// TODO: Test autodetect device here
return 0;
}
static void free_devnames(char * * devnames, int numdevs)
{
static const char version[] = "$Id: dev_legacy.cpp 2879 2009-08-29 17:19:00Z chrfranke $";
for (int i = 0; i < numdevs; i++)
FreeNonZero(devnames[i], -1,__LINE__, version);
FreeNonZero(devnames, (sizeof (char*) * numdevs),__LINE__, version);
}
bool legacy_smart_interface::scan_smart_devices(smart_device_list & devlist,
const char * type, const char * pattern /*= 0*/)
{
if (pattern) {
set_err(EINVAL, "DEVICESCAN with pattern not implemented yet");
return false;
}
// Make namelists
char * * atanames = 0; int numata = 0;
if (!type || !strcmp(type, "ata")) {
numata = ::make_device_names(&atanames, "ATA");
if (numata < 0) {
set_err(ENOMEM);
return false;
}
}
char * * scsinames = 0; int numscsi = 0;
if (!type || !strcmp(type, "scsi")) {
numscsi = ::make_device_names(&scsinames, "SCSI");
if (numscsi < 0) {
free_devnames(atanames, numata);
set_err(ENOMEM);
return false;
}
}
// Add to devlist
int i;
if (type==NULL)
type="";
for (i = 0; i < numata; i++) {
ata_device * atadev = get_ata_device(atanames[i], type);
if (atadev)
devlist.add(atadev);
}
free_devnames(atanames, numata);
for (i = 0; i < numscsi; i++) {
scsi_device * scsidev = get_scsi_device(scsinames[i], type);
if (scsidev)
devlist.add(scsidev);
}
free_devnames(scsinames, numscsi);
return true;
}
smart_device * legacy_smart_interface::get_custom_smart_device(const char * name, const char * type)
{
// Marvell ?
if (!strcmp(type, "marvell"))
return new legacy_marvell_device(this, name, type);
// 3Ware ?
int disknum = -1, n1 = -1, n2 = -1;
if (sscanf(type, "3ware,%n%d%n", &n1, &disknum, &n2) == 1 || n1 == 6) {
if (n2 != (int)strlen(type)) {
set_err(EINVAL, "Option -d 3ware,N requires N to be a non-negative integer");
return 0;
}
if (!(0 <= disknum && disknum <= 127)) {
set_err(EINVAL, "Option -d 3ware,N (N=%d) must have 0 <= N <= 127", disknum);
return 0;
}
int contr = ::guess_device_type(name);
if (contr != CONTROLLER_3WARE_9000_CHAR && contr != CONTROLLER_3WARE_678K_CHAR)
contr = CONTROLLER_3WARE_678K;
return new legacy_escalade_device(this, name, contr, disknum);
}
// Areca?
disknum = n1 = n2 = -1;
if (sscanf(type, "areca,%n%d%n", &n1, &disknum, &n2) == 1 || n1 == 6) {
if (n2 != (int)strlen(type)) {
set_err(EINVAL, "Option -d areca,N requires N to be a non-negative integer");
return 0;
}
if (!(1 <= disknum && disknum <= 24)) {
set_err(EINVAL, "Option -d areca,N (N=%d) must have 1 <= N <= 24", disknum);
return 0;
}
return new legacy_areca_device(this, name, disknum);
}
// Highpoint ?
int controller = -1, channel = -1; disknum = 1;
n1 = n2 = -1; int n3 = -1;
if (sscanf(type, "hpt,%n%d/%d%n/%d%n", &n1, &controller, &channel, &n2, &disknum, &n3) >= 2 || n1 == 4) {
int len = strlen(type);
if (!(n2 == len || n3 == len)) {
set_err(EINVAL, "Option '-d hpt,L/M/N' supports 2-3 items");
return 0;
}
if (!(1 <= controller && controller <= 8)) {
set_err(EINVAL, "Option '-d hpt,L/M/N' invalid controller id L supplied");
return 0;
}
if (!(1 <= channel && channel <= 8)) {
set_err(EINVAL, "Option '-d hpt,L/M/N' invalid channel number M supplied");
return 0;
}
if (!(1 <= disknum && disknum <= 15)) {
set_err(EINVAL, "Option '-d hpt,L/M/N' invalid pmport number N supplied");
return 0;
}
return new legacy_highpoint_device(this, name, controller, channel, disknum);
}
// CCISS ?
disknum = n1 = n2 = -1;
if (sscanf(type, "cciss,%n%d%n", &n1, &disknum, &n2) == 1 || n1 == 6) {
if (n2 != (int)strlen(type)) {
set_err(EINVAL, "Option -d cciss,N requires N to be a non-negative integer");
return 0;
}
if (!(0 <= disknum && disknum <= 15)) {
set_err(EINVAL, "Option -d cciss,N (N=%d) must have 0 <= N <= 15", disknum);
return 0;
}
return new legacy_cciss_device(this, name, disknum);
}
return 0;
}
const char * legacy_smart_interface::get_valid_custom_dev_types_str()
{
return "marvell, areca,N, 3ware,N, hpt,L/M/N, cciss,N";
}
} // namespace
/////////////////////////////////////////////////////////////////////////////
/// Initialize platform interface and register with smi()
void smart_interface::init()
{
static os::legacy_smart_interface the_interface;
smart_interface::set(&the_interface);
}

92
dev_tunnelled.h Normal file
View File

@ -0,0 +1,92 @@
/*
* dev_tunnelled.h
*
* Home page of code is: http://smartmontools.sourceforge.net
*
* Copyright (C) 2008 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, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef DEV_TUNNELLED_H
#define DEV_TUNNELLED_H
#define DEV_TUNNELLED_H_CVSID "$Id: dev_tunnelled.h,v 1.1 2008/07/25 21:16:00 chrfranke Exp $\n"
#include "dev_interface.h"
/////////////////////////////////////////////////////////////////////////////
// tunnelled_device_base
/// Common functionality for all tunnelled_device classes.
class tunnelled_device_base
: virtual public /*implements*/ smart_device
{
protected:
explicit tunnelled_device_base(smart_device * tunnel_dev);
public:
virtual ~tunnelled_device_base() throw();
virtual bool is_open() const;
virtual bool open();
virtual bool close();
virtual bool owns(const smart_device * dev) const;
virtual void release(const smart_device * dev);
private:
smart_device * m_tunnel_base_dev;
};
/////////////////////////////////////////////////////////////////////////////
// tunnelled_device
/// Implement a device by tunneling through another device
template <class BaseDev, class TunnelDev>
class tunnelled_device
: public BaseDev,
public tunnelled_device_base
{
public:
typedef TunnelDev tunnel_device_type;
protected:
explicit tunnelled_device(tunnel_device_type * tunnel_dev)
: smart_device(smart_device::never_called),
tunnelled_device_base(tunnel_dev),
m_tunnel_dev(tunnel_dev)
{ }
public:
virtual void release(const smart_device * dev)
{
if (m_tunnel_dev == dev)
m_tunnel_dev = 0;
tunnelled_device_base::release(dev);
}
tunnel_device_type * get_tunnel_dev()
{ return m_tunnel_dev; }
const tunnel_device_type * get_tunnel_dev() const
{ return m_tunnel_dev; }
private:
tunnel_device_type * m_tunnel_dev;
};
#endif // DEV_TUNNELLED_H

99
do_release Executable file
View File

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

View File

@ -1,4 +1,8 @@
## Process this file with automake to produce Makefile.in
#
# $Id: Makefile.am 2846 2009-07-18 14:18:51Z chrfranke $
#
examplesdir=$(exampledir)
examples_DATA = README
@ -9,3 +13,5 @@ examples_SCRIPTS = Example1 \
Example4
EXTRA_DIST = $(examples_SCRIPTS)
MAINTAINERCLEANFILES = $(srcdir)/Makefile.in

View File

@ -1,381 +0,0 @@
# Makefile.in generated by automake 1.10 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
# 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
@SET_MAKE@
VPATH = @srcdir@
pkgdatadir = $(datadir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
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@
AMTAR = @AMTAR@
ASFLAGS = @ASFLAGS@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
CC = @CC@
CCAS = @CCAS@
CCASDEPMODE = @CCASDEPMODE@
CCASFLAGS = @CCASFLAGS@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CPPFLAGS = @CPPFLAGS@
CXX = @CXX@
CXXCPP = @CXXCPP@
CXXDEPMODE = @CXXDEPMODE@
CXXFLAGS = @CXXFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
GREP = @GREP@
INSTALL = @INSTALL@
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@
MAKEINFO = @MAKEINFO@
MKDIR_P = @MKDIR_P@
OBJEXT = @OBJEXT@
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@
STRIP = @STRIP@
VERSION = @VERSION@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
ac_ct_CC = @ac_ct_CC@
ac_ct_CXX = @ac_ct_CXX@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
datadir = @datadir@
datarootdir = @datarootdir@
docdir = @docdir@
dvidir = @dvidir@
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@
htmldir = @htmldir@
includedir = @includedir@
infodir = @infodir@
initddir = @initddir@
install_sh = @install_sh@
libc_have_working_snprintf = @libc_have_working_snprintf@
libdir = @libdir@
libexecdir = @libexecdir@
localedir = @localedir@
localstatedir = @localstatedir@
mandir = @mandir@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
os_deps = @os_deps@
os_libs = @os_libs@
pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
releaseversion = @releaseversion@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
smartd_suffix = @smartd_suffix@
smartmontools_release_date = @smartmontools_release_date@
smartmontools_release_time = @smartmontools_release_time@
srcdir = @srcdir@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
examplesdir = $(exampledir)
examples_DATA = README
examples_SCRIPTS = Example1 \
Example2 \
Example3 \
Example4
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
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)'; \
dist_files=`for file in $$list; do echo $$file; done | \
sed -e "s|^$$srcdirstrip/||;t" \
-e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
case $$dist_files in \
*/*) $(MKDIR_P) `echo "$$dist_files" | \
sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
sort -u` ;; \
esac; \
for file in $$dist_files; do \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
if test -d $$d/$$file; then \
dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
if test -d $(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-dvi: install-dvi-am
install-exec-am:
install-html: install-html-am
install-info: install-info-am
install-man:
install-pdf: install-pdf-am
install-ps: install-ps-am
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
.MAKE: install-am install-strip
.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-dvi \
install-dvi-am install-examplesDATA install-examplesSCRIPTS \
install-exec install-exec-am install-html install-html-am \
install-info install-info-am install-man install-pdf \
install-pdf-am install-ps install-ps-am install-strip \
installcheck installcheck-am installdirs maintainer-clean \
maintainer-clean-generic mostlyclean mostlyclean-generic pdf \
pdf-am ps ps-am uninstall uninstall-am uninstall-examplesDATA \
uninstall-examplesSCRIPTS
# 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

@ -3,7 +3,7 @@
*
* Home page of code is: http://smartmontools.sourceforge.net
*
* Copyright (C) 2002-8 Bruce Allen <smartmontools-support@lists.sourceforge.net>
* Copyright (C) 2002-9 Bruce Allen <smartmontools-support@lists.sourceforge.net>
* Copyright (C) 1999-2000 Michael Cornwell <cornwell@acm.org>
*
* This program is free software; you can redistribute it and/or modify
@ -25,95 +25,27 @@
#ifndef EXTERN_H_
#define EXTERN_H_
#define EXTERN_H_CVSID "$Id: extern.h,v 1.54 2008/03/04 22:09:47 ballen4705 Exp $\n"
// Possible values for fixfirmwarebug. If user has NOT specified -F at
// all, then value is 0.
#define FIX_NOTSPECIFIED 0
#define FIX_NONE 1
#define FIX_SAMSUNG 2
#define FIX_SAMSUNG2 3
#define FIX_SAMSUNG3 4
#define EXTERN_H_CVSID "$Id: extern.h,v 1.63 2009/07/07 19:28:29 chrfranke Exp $\n"
// Block used for global control/communications. If you need more
// global variables, this should be the only place that you need to
// add them.
typedef struct smartmonctrl_s {
// spans for selective self-test
uint64_t smartselectivespan[5][2];
// mode for each span, see SEL_* in utility.h
char smartselectivemode[5];
// number of spans
int smartselectivenumspans;
int testcase;
unsigned scttempint;
// one plus time in minutes to wait after powerup before restarting
// interrupted offline scan after selective self-test.
int pendingtime;
// run offline scan after selective self-test. 0: don't change, 1:
// 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;
unsigned char generalsmartvalues;
unsigned char smartlogdirectory;
unsigned char smartselftestlog;
unsigned char selectivetestlog;
unsigned char smarterrorlog;
unsigned char smartbackgroundlog;
unsigned char scttempsts;
unsigned char scttemphist;
unsigned char scttempintp;
unsigned char smartdisable;
unsigned char smartenable;
unsigned char smartstatus;
unsigned char smartexeoffimmediate;
unsigned char smartshortselftest;
unsigned char smartextendselftest;
unsigned char smartconveyanceselftest;
unsigned char smartselectiveselftest;
unsigned char smartshortcapselftest;
unsigned char smartextendcapselftest;
unsigned char smartconveyancecapselftest;
unsigned char smartselectivecapselftest;
unsigned char smartselftestabort;
unsigned char smartautoofflineenable;
unsigned char smartautoofflinedisable;
unsigned char smartautosaveenable;
unsigned char smartautosavedisable;
unsigned char printing_switchable;
unsigned char dont_print;
unsigned char dont_print_serial;
bool printing_switchable;
bool dont_print;
bool dont_print_serial;
unsigned char permissive;
unsigned char conservative;
unsigned char checksumfail;
unsigned char checksumignore;
bool conservative;
unsigned char reportataioctl;
unsigned char reportscsiioctl;
unsigned char fixfirmwarebug;
unsigned char fixswappedid;
unsigned char satpassthrulen;
// Controller type (device type) has been specified explicitly
unsigned char controller_explicit;
#ifdef OLD_INTERFACE
// 3Ware controller type, but also extensible to other contoller types
unsigned char controller_type;
unsigned char controller_type; // TODO: Only needed for os_linux.cpp
// For 3Ware controllers, nonzero value is 1 plus the disk number
unsigned char controller_port;
unsigned char controller_port; // TODO: Only needed for os_linux.cpp
// 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
// the i'th SMART attribute. The default definitions of the
// Attributes are obtained by having the array be all zeros. If
// attributedefs[i] is nonzero, it means that the i'th attribute has
// a non-default meaning. See the ataPrintSmartAttribName and
// and parse_attribute_def functions.
unsigned char attributedefs[256];
unsigned char hpt_data[3]; // TODO: Only needed for os_linux.cpp
#endif
} smartmonctrl;
#endif

View File

@ -1,507 +0,0 @@
#!/bin/sh
# install - install a program, script, or datafile
scriptversion=2006-10-14.15
# This originates from X11R5 (mit/util/scripts/install.sh), which was
# later released in X11R6 (xc/config/util/install.sh) with the
# following copyright and license.
#
# Copyright (C) 1994 X Consortium
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to
# deal in the Software without restriction, including without limitation the
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
# sell copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
# Except as contained in this notice, the name of the X Consortium shall not
# be used in advertising or otherwise to promote the sale, use or other deal-
# ings in this Software without prior written authorization from the X Consor-
# tium.
#
#
# FSF changes to this file are in the public domain.
#
# Calling this script install-sh is preferred over install.sh, to prevent
# `make' implicit rules from creating a file called install from it
# when there is no Makefile.
#
# This script is compatible with the BSD install script, but was written
# from scratch.
nl='
'
IFS=" "" $nl"
# set DOITPROG to echo to test this script
# Don't use :- since 4.3BSD and earlier shells don't like it.
doit="${DOITPROG-}"
if test -z "$doit"; then
doit_exec=exec
else
doit_exec=$doit
fi
# Put in absolute file names if you don't have them in your path;
# or use environment vars.
mvprog="${MVPROG-mv}"
cpprog="${CPPROG-cp}"
chmodprog="${CHMODPROG-chmod}"
chownprog="${CHOWNPROG-chown}"
chgrpprog="${CHGRPPROG-chgrp}"
stripprog="${STRIPPROG-strip}"
rmprog="${RMPROG-rm}"
mkdirprog="${MKDIRPROG-mkdir}"
posix_glob=
posix_mkdir=
# Desired mode of installed file.
mode=0755
chmodcmd=$chmodprog
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 $# -ne 0; do
case $1 in
-c) shift
continue;;
-d) dir_arg=true
shift
continue;;
-g) chgrpcmd="$chgrpprog $2"
shift
shift
continue;;
--help) echo "$usage"; exit $?;;
-m) mode=$2
shift
shift
case $mode in
*' '* | *' '* | *'
'* | *'*'* | *'?'* | *'['*)
echo "$0: invalid mode: $mode" >&2
exit 1;;
esac
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 $?;;
--) shift
break;;
-*) echo "$0: invalid option: $1" >&2
exit 1;;
*) break;;
esac
done
if test $# -ne 0 && test -z "$dir_arg$dstarg"; then
# When -d is used, all remaining arguments are directories to create.
# When -t is used, the destination is already specified.
# Otherwise, the last argument is the destination. Remove it from $@.
for arg
do
if test -n "$dstarg"; then
# $@ is not empty: it contains at least $arg.
set fnord "$@" "$dstarg"
shift # fnord
fi
shift # arg
dstarg=$arg
done
fi
if test $# -eq 0; then
if test -z "$dir_arg"; then
echo "$0: no input file specified." >&2
exit 1
fi
# It's OK to call `install-sh -d' without argument.
# This can happen when creating conditional directories.
exit 0
fi
if test -z "$dir_arg"; then
trap '(exit $?); exit' 1 2 13 15
# Set umask so as not to create temps with too-generous modes.
# However, 'strip' requires both read and write access to temps.
case $mode in
# Optimize common cases.
*644) cp_umask=133;;
*755) cp_umask=22;;
*[0-7])
if test -z "$stripcmd"; then
u_plus_rw=
else
u_plus_rw='% 200'
fi
cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
*)
if test -z "$stripcmd"; then
u_plus_rw=
else
u_plus_rw=,u+rw
fi
cp_umask=$mode$u_plus_rw;;
esac
fi
for src
do
# Protect names starting with `-'.
case $src in
-*) src=./$src ;;
esac
if test -n "$dir_arg"; then
dst=$src
dstdir=$dst
test -d "$dstdir"
dstdir_status=$?
else
# Waiting for this to be detected by the "$cpprog $src $dsttmp" command
# might cause directories to be created, which would be especially bad
# if $src (and thus $dsttmp) contains '*'.
if test ! -f "$src" && test ! -d "$src"; then
echo "$0: $src does not exist." >&2
exit 1
fi
if test -z "$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
dstdir=$dst
dst=$dstdir/`basename "$src"`
dstdir_status=0
else
# Prefer dirname, but fall back on a substitute if dirname fails.
dstdir=`
(dirname "$dst") 2>/dev/null ||
expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
X"$dst" : 'X\(//\)[^/]' \| \
X"$dst" : 'X\(//\)$' \| \
X"$dst" : 'X\(/\)' \| . 2>/dev/null ||
echo X"$dst" |
sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
s//\1/
q
}
/^X\(\/\/\)[^/].*/{
s//\1/
q
}
/^X\(\/\/\)$/{
s//\1/
q
}
/^X\(\/\).*/{
s//\1/
q
}
s/.*/./; q'
`
test -d "$dstdir"
dstdir_status=$?
fi
fi
obsolete_mkdir_used=false
if test $dstdir_status != 0; then
case $posix_mkdir in
'')
# Create intermediate dirs using mode 755 as modified by the umask.
# This is like FreeBSD 'install' as of 1997-10-28.
umask=`umask`
case $stripcmd.$umask in
# Optimize common cases.
*[2367][2367]) mkdir_umask=$umask;;
.*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;
*[0-7])
mkdir_umask=`expr $umask + 22 \
- $umask % 100 % 40 + $umask % 20 \
- $umask % 10 % 4 + $umask % 2
`;;
*) mkdir_umask=$umask,go-w;;
esac
# With -d, create the new directory with the user-specified mode.
# Otherwise, rely on $mkdir_umask.
if test -n "$dir_arg"; then
mkdir_mode=-m$mode
else
mkdir_mode=
fi
posix_mkdir=false
case $umask in
*[123567][0-7][0-7])
# POSIX mkdir -p sets u+wx bits regardless of umask, which
# is incompatible with FreeBSD 'install' when (umask & 300) != 0.
;;
*)
tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0
if (umask $mkdir_umask &&
exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1
then
if test -z "$dir_arg" || {
# Check for POSIX incompatibilities with -m.
# HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
# other-writeable bit of parent directory when it shouldn't.
# FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
ls_ld_tmpdir=`ls -ld "$tmpdir"`
case $ls_ld_tmpdir in
d????-?r-*) different_mode=700;;
d????-?--*) different_mode=755;;
*) false;;
esac &&
$mkdirprog -m$different_mode -p -- "$tmpdir" && {
ls_ld_tmpdir_1=`ls -ld "$tmpdir"`
test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
}
}
then posix_mkdir=:
fi
rmdir "$tmpdir/d" "$tmpdir"
else
# Remove any dirs left behind by ancient mkdir implementations.
rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null
fi
trap '' 0;;
esac;;
esac
if
$posix_mkdir && (
umask $mkdir_umask &&
$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
)
then :
else
# The umask is ridiculous, or mkdir does not conform to POSIX,
# or it failed possibly due to a race condition. Create the
# directory the slow way, step by step, checking for races as we go.
case $dstdir in
/*) prefix=/ ;;
-*) prefix=./ ;;
*) prefix= ;;
esac
case $posix_glob in
'')
if (set -f) 2>/dev/null; then
posix_glob=true
else
posix_glob=false
fi ;;
esac
oIFS=$IFS
IFS=/
$posix_glob && set -f
set fnord $dstdir
shift
$posix_glob && set +f
IFS=$oIFS
prefixes=
for d
do
test -z "$d" && continue
prefix=$prefix$d
if test -d "$prefix"; then
prefixes=
else
if $posix_mkdir; then
(umask=$mkdir_umask &&
$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
# Don't fail if two instances are running concurrently.
test -d "$prefix" || exit 1
else
case $prefix in
*\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
*) qprefix=$prefix;;
esac
prefixes="$prefixes '$qprefix'"
fi
fi
prefix=$prefix/
done
if test -n "$prefixes"; then
# Don't fail if two instances are running concurrently.
(umask $mkdir_umask &&
eval "\$doit_exec \$mkdirprog $prefixes") ||
test -d "$dstdir" || exit 1
obsolete_mkdir_used=true
fi
fi
fi
if test -n "$dir_arg"; then
{ test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&
{ test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&
{ test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||
test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1
else
# Make a couple of temp file names in the proper directory.
dsttmp=$dstdir/_inst.$$_
rmtmp=$dstdir/_rm.$$_
# Trap to clean up those temp files at exit.
trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
# Copy the file name to the temp name.
(umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") &&
# and set any options; do chmod last to preserve setuid bits.
#
# If any of these fail, we abort the whole thing. If we want to
# ignore errors from any of these, just make sure not to ignore
# errors from the above "$doit $cpprog $src $dsttmp" command.
#
{ test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } \
&& { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } \
&& { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } \
&& { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&
# Now rename the file to the real destination.
{ $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null \
|| {
# The rename failed, perhaps because mv can't rename something else
# to itself, or perhaps because mv is so ancient that it does not
# support -f.
# Now remove or move aside any old file at destination location.
# We try this two ways since rm can't unlink itself on some
# systems and the destination file might be busy for other
# reasons. In this case, the final cleanup might fail but the new
# file should still install successfully.
{
if test -f "$dst"; then
$doit $rmcmd -f "$dst" 2>/dev/null \
|| { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null \
&& { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }; }\
|| {
echo "$0: cannot unlink or rename $dst" >&2
(exit 1); exit 1
}
else
:
fi
} &&
# Now rename the file to the real destination.
$doit $mvcmd "$dsttmp" "$dst"
}
} || exit 1
trap '' 0
fi
done
# Local variables:
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-end: "$"
# End:

File diff suppressed because it is too large Load Diff

View File

@ -5,6 +5,7 @@
* Address of support mailing list: smartmontools-support@lists.sourceforge.net
*
* Copyright (C) 2003-8 Philip Williams, Bruce Allen
* Copyright (C) 2008 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
@ -20,58 +21,45 @@
#ifndef KNOWNDRIVES_H_
#define KNOWNDRIVES_H_
#define KNOWNDRIVES_H_CVSID "$Id: knowndrives.h,v 1.18 2008/03/04 22:09:47 ballen4705 Exp $\n"
#define KNOWNDRIVES_H_CVSID "$Id: knowndrives.h,v 1.23 2009/04/16 21:24:08 chrfranke Exp $\n"
/* Structure used to store settings for specific drives in knowndrives[]. The
* elements are used in the following ways:
*
* modelfamily Informal string about the model family/series of a
* device. Set to NULL if no info (apart from device id)
* device. Set to "" if no info (apart from device id)
* known.
* modelregexp POSIX regular expression to match the model of a device.
* This should never be NULL (except to terminate the
* knowndrives array).
* This should never be "".
* firmwareregexp POSIX regular expression to match a devices's firmware
* version. This is optional and should be NULL if it is not
* to be used. If it is non-NULL then it will be used to
* version. This is optional and should be "" if it is not
* to be used. If it is nonempty then it will be used to
* narrow the set of devices matched by modelregexp.
* warningmsg A message that may be displayed for matching drives. For
* example, to inform the user that they may need to apply a
* firmware patch.
* vendoropts Pointer to first element of an array of vendor-specific
* option attribute/value pairs that should be set for a
* matching device unless the user has requested otherwise.
* The user's own settings override these. The array should
* be terminated with the entry {0,0}.
* specialpurpose Pointer to a function that defines some additional action
* that may be taken for matching devices.
* functiondesc A description of the effect of the specialpurpose
* function. Used by showpresets() and showallpresets() to
* make the output more informative.
* presets String with vendor-specific attribute ('-v') and firmware
* bug fix ('-F') options. Same syntax as in smartctl command
* line. The user's own settings override these.
*/
typedef struct drivesettings_s {
struct drive_settings {
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. */
extern const drivesettings knowndrives[];
const char * presets;
};
// Searches knowndrives[] for a drive with the given model number and firmware
// string.
int lookupdrive(const char *model, const char *firmware);
const drive_settings * lookup_drive(const char * model, const char * firmware);
// Shows the presets (if any) that are available for the given drive.
void showpresets(const struct ata_identify_device *drive);
void show_presets(const ata_identify_device * drive, bool fix_swapped_id);
// Shows all presets for drives in knowndrives[].
// Returns <0 on syntax error in regular expressions.
int showallpresets(void);
// Returns #syntax errors.
int showallpresets();
// Shows all matching presets for a drive in knowndrives[].
// Returns # matching entries.
@ -80,9 +68,14 @@ int showmatchingpresets(const char *model, const char *firmware);
// Sets preset vendor attribute options in opts by finding the entry
// (if any) for the given drive in knowndrives[]. Values that have
// already been set in opts will not be changed. Also sets options in
// con. Returns <0 if drive not recognized else index of drive in
// database.
int applypresets(const struct ata_identify_device *drive, unsigned char **opts,
smartmonctrl *con);
// con. Returns false if drive not recognized.
bool apply_presets(const ata_identify_device * drive, unsigned char * opts,
unsigned char & fix_firmwarebug, bool fix_swapped_id);
// Read drive database from file.
bool read_drive_database(const char * path);
// Read drive databases from standard places.
bool read_default_drive_databases();
#endif

225
megaraid.h Normal file
View File

@ -0,0 +1,225 @@
int megaraid_io_interface(int device, int target, struct scsi_cmnd_io *, int);
#undef u32
#define u8 uint8_t
#define u16 uint16_t
#define u32 uint32_t
#define u64 uint64_t
/*======================================================
* PERC2/3/4 Passthrough SCSI Command Interface
*
* Contents from:
* drivers/scsi/megaraid/megaraid_ioctl.h
* drivers/scsi/megaraid/mbox_defs.h
*======================================================*/
#define MEGAIOC_MAGIC 'm'
#define MEGAIOCCMD _IOWR(MEGAIOC_MAGIC, 0, struct uioctl_t)
/* Following subopcode work for opcode == 0x82 */
#define MKADAP(adapno) (MEGAIOC_MAGIC << 8 | adapno)
#define MEGAIOC_QNADAP 'm'
#define MEGAIOC_QDRVRVER 'e'
#define MEGAIOC_QADAPINFO 'g'
#define MEGA_MBOXCMD_PASSTHRU 0x03
#define MAX_REQ_SENSE_LEN 0x20
#define MAX_CDB_LEN 10
typedef struct
{
uint8_t timeout : 3;
uint8_t ars : 1;
uint8_t reserved : 3;
uint8_t islogical : 1;
uint8_t logdrv;
uint8_t channel;
uint8_t target;
uint8_t queuetag;
uint8_t queueaction;
uint8_t cdb[MAX_CDB_LEN];
uint8_t cdblen;
uint8_t reqsenselen;
uint8_t reqsensearea[MAX_REQ_SENSE_LEN];
uint8_t numsgelements;
uint8_t scsistatus;
uint32_t dataxferaddr;
uint32_t dataxferlen;
} __attribute__((packed)) mega_passthru;
typedef struct
{
uint8_t cmd;
uint8_t cmdid;
uint8_t opcode;
uint8_t subopcode;
uint32_t lba;
uint32_t xferaddr;
uint8_t logdrv;
uint8_t resvd[3];
uint8_t numstatus;
uint8_t status;
} __attribute__((packed)) megacmd_t;
typedef struct {
uint8_t *pointer;
#if BITS_PER_LONG == 32
uint8_t pad[4];
#endif
} ptr_t;
struct uioctl_t
{
uint32_t inlen;
uint32_t outlen;
union {
uint8_t fca[16];
struct {
uint8_t opcode;
uint8_t subopcode;
uint16_t adapno;
ptr_t buffer;
uint32_t length;
} __attribute__((packed)) fcs;
} __attribute__((packed)) ui;
megacmd_t mbox;
mega_passthru pthru;
ptr_t data;
} __attribute__((packed));
/*===================================================
* PERC5/6 Passthrough SCSI Command Interface
*
* Contents from:
* drivers/scsi/megaraid/megaraid_sas.h
*===================================================*/
#define MEGASAS_MAGIC 'M'
#define MEGASAS_IOC_FIRMWARE _IOWR(MEGASAS_MAGIC, 1, struct megasas_iocpacket)
#define MFI_CMD_PD_SCSI_IO 0x04
#define MFI_FRAME_SGL64 0x02
#define MFI_FRAME_DIR_READ 0x10
#define MAX_IOCTL_SGE 16
struct megasas_sge32 {
u32 phys_addr;
u32 length;
} __attribute__ ((packed));
struct megasas_sge64 {
u64 phys_addr;
u32 length;
} __attribute__ ((packed));
union megasas_sgl {
struct megasas_sge32 sge32[1];
struct megasas_sge64 sge64[1];
} __attribute__ ((packed));
struct megasas_header {
u8 cmd; /*00h */
u8 sense_len; /*01h */
u8 cmd_status; /*02h */
u8 scsi_status; /*03h */
u8 target_id; /*04h */
u8 lun; /*05h */
u8 cdb_len; /*06h */
u8 sge_count; /*07h */
u32 context; /*08h */
u32 pad_0; /*0Ch */
u16 flags; /*10h */
u16 timeout; /*12h */
u32 data_xferlen; /*14h */
} __attribute__ ((packed));
struct megasas_pthru_frame {
u8 cmd; /*00h */
u8 sense_len; /*01h */
u8 cmd_status; /*02h */
u8 scsi_status; /*03h */
u8 target_id; /*04h */
u8 lun; /*05h */
u8 cdb_len; /*06h */
u8 sge_count; /*07h */
u32 context; /*08h */
u32 pad_0; /*0Ch */
u16 flags; /*10h */
u16 timeout; /*12h */
u32 data_xfer_len; /*14h */
u32 sense_buf_phys_addr_lo; /*18h */
u32 sense_buf_phys_addr_hi; /*1Ch */
u8 cdb[16]; /*20h */
union megasas_sgl sgl; /*30h */
} __attribute__ ((packed));
struct megasas_dcmd_frame {
u8 cmd; /*00h */
u8 reserved_0; /*01h */
u8 cmd_status; /*02h */
u8 reserved_1[4]; /*03h */
u8 sge_count; /*07h */
u32 context; /*08h */
u32 pad_0; /*0Ch */
u16 flags; /*10h */
u16 timeout; /*12h */
u32 data_xfer_len; /*14h */
u32 opcode; /*18h */
union { /*1Ch */
u8 b[12];
u16 s[6];
u32 w[3];
} mbox;
union megasas_sgl sgl; /*28h */
} __attribute__ ((packed));
struct megasas_iocpacket {
u16 host_no;
u16 __pad1;
u32 sgl_off;
u32 sge_count;
u32 sense_off;
u32 sense_len;
union {
u8 raw[128];
struct megasas_header hdr;
} frame;
struct iovec sgl[MAX_IOCTL_SGE];
} __attribute__ ((packed));
#undef u8
#undef u16
#undef u32
#undef u64

367
missing
View File

@ -1,367 +0,0 @@
#! /bin/sh
# Common stub for a few missing GNU programs while installing.
scriptversion=2006-05-10.23
# Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005, 2006
# Free Software Foundation, Inc.
# Originally by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
# 02110-1301, USA.
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program.
if test $# -eq 0; then
echo 1>&2 "Try \`$0 --help' for more information"
exit 1
fi
run=:
sed_output='s/.* --output[ =]\([^ ]*\).*/\1/p'
sed_minuso='s/.* -o \([^ ]*\).*/\1/p'
# 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'
autom4te touch the output file, or create a stub one
automake touch all \`Makefile.in' files
bison create \`y.tab.[ch]', if possible, from existing .[ch]
flex create \`lex.yy.c', if possible, from existing .c
help2man touch the output file
lex create \`lex.yy.c', if possible, from existing .c
makeinfo touch the output file
tar try tar, gnutar, gtar, then tar without non-portable flags
yacc create \`y.tab.[ch]', if possible, from existing .[ch]
Send bug reports to <bug-automake@gnu.org>."
exit $?
;;
-v|--v|--ve|--ver|--vers|--versi|--versio|--version)
echo "missing $scriptversion (GNU Automake)"
exit $?
;;
-*)
echo 1>&2 "$0: Unknown \`$1' option"
echo 1>&2 "Try \`$0 --help' for more information"
exit 1
;;
esac
# Now exit if we have it, but it failed. Also exit now if we
# don't have it and --version was passed (most likely to detect
# the program).
case $1 in
lex|yacc)
# Not GNU programs, they don't have --version.
;;
tar)
if test -n "$run"; then
echo 1>&2 "ERROR: \`tar' requires --run"
exit 1
elif test "x$2" = "x--version" || test "x$2" = "x--help"; then
exit 1
fi
;;
*)
if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
# We have it, but it failed.
exit 1
elif test "x$2" = "x--version" || test "x$2" = "x--help"; then
# Could not run --version or --help. This is probably someone
# running `$TOOL --version' or `$TOOL --help' to check whether
# $TOOL exists and not knowing $TOOL uses missing.
exit 1
fi
;;
esac
# If it does not exist, or fails to run (possibly an outdated version),
# try to emulate it.
case $1 in
aclocal*)
echo 1>&2 "\
WARNING: \`$1' is $msg. You should only need it if
you modified \`acinclude.m4' or \`${configure_ac}'. You might want
to install the \`Automake' and \`Perl' packages. Grab them from
any GNU archive site."
touch aclocal.m4
;;
autoconf)
echo 1>&2 "\
WARNING: \`$1' is $msg. You should only need it if
you modified \`${configure_ac}'. You might want to install the
\`Autoconf' and \`GNU m4' packages. Grab them from any GNU
archive site."
touch configure
;;
autoheader)
echo 1>&2 "\
WARNING: \`$1' is $msg. You should only need it if
you modified \`acconfig.h' or \`${configure_ac}'. You might want
to install the \`Autoconf' and \`GNU m4' packages. Grab them
from any GNU archive site."
files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}`
test -z "$files" && files="config.h"
touch_files=
for f in $files; do
case $f in
*:*) touch_files="$touch_files "`echo "$f" |
sed -e 's/^[^:]*://' -e 's/:.*//'`;;
*) touch_files="$touch_files $f.in";;
esac
done
touch $touch_files
;;
automake*)
echo 1>&2 "\
WARNING: \`$1' is $msg. You should only need it if
you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'.
You might want to install the \`Automake' and \`Perl' packages.
Grab them from any GNU archive site."
find . -type f -name Makefile.am -print |
sed 's/\.am$/.in/' |
while read f; do touch "$f"; done
;;
autom4te)
echo 1>&2 "\
WARNING: \`$1' is needed, but is $msg.
You might have modified some files without having the
proper tools for further handling them.
You can get \`$1' as part of \`Autoconf' from any GNU
archive site."
file=`echo "$*" | sed -n "$sed_output"`
test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"`
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 test $# -ne 1; then
eval LASTARG="\${$#}"
case $LASTARG in
*.y)
SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'`
if test -f "$SRCFILE"; then
cp "$SRCFILE" y.tab.c
fi
SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'`
if test -f "$SRCFILE"; then
cp "$SRCFILE" y.tab.h
fi
;;
esac
fi
if test ! -f y.tab.h; then
echo >y.tab.h
fi
if test ! -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 test $# -ne 1; then
eval LASTARG="\${$#}"
case $LASTARG in
*.l)
SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'`
if test -f "$SRCFILE"; then
cp "$SRCFILE" lex.yy.c
fi
;;
esac
fi
if test ! -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 "$sed_output"`
test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"`
if test -f "$file"; then
touch $file
else
test -z "$file" || exec >$file
echo ".ab help2man is required to generate this page"
exit 1
fi
;;
makeinfo)
echo 1>&2 "\
WARNING: \`$1' is $msg. You should only need it if
you modified a \`.texi' or \`.texinfo' file, or any other file
indirectly affecting the aspect of the manual. The spurious
call might also be the consequence of using a buggy \`make' (AIX,
DU, IRIX). You might want to install the \`Texinfo' package or
the \`GNU make' package. Grab either from any GNU archive site."
# The file to touch is that specified with -o ...
file=`echo "$*" | sed -n "$sed_output"`
test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"`
if test -z "$file"; then
# ... or it is the one specified with @setfilename ...
infile=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'`
file=`sed -n '
/^@setfilename/{
s/.* \([^ ]*\) *$/\1/
p
q
}' $infile`
# ... or it is derived from the source name (dir/f.texi becomes f.info)
test -z "$file" && file=`echo "$infile" | sed 's,.*/,,;s,.[^.]*$,,'`.info
fi
# If the file does not exist, the user really needs makeinfo;
# let's fail without touching anything.
test -f $file || exit 1
touch $file
;;
tar)
shift
# We have already tried tar in the generic part.
# Look for gnutar/gtar before invocation to avoid ugly error
# messages.
if (gnutar --version > /dev/null 2>&1); then
gnutar "$@" && exit 0
fi
if (gtar --version > /dev/null 2>&1); then
gtar "$@" && exit 0
fi
firstarg="$1"
if shift; then
case $firstarg in
*o*)
firstarg=`echo "$firstarg" | sed s/o//`
tar "$firstarg" "$@" && exit 0
;;
esac
case $firstarg in
*h*)
firstarg=`echo "$firstarg" | sed s/h//`
tar "$firstarg" "$@" && exit 0
;;
esac
fi
echo 1>&2 "\
WARNING: I can't seem to be able to run \`tar' with the given arguments.
You may want to install GNU tar or Free paxutils, or check the
command line arguments."
exit 1
;;
*)
echo 1>&2 "\
WARNING: \`$1' is needed, and is $msg.
You might have modified some files without having the
proper tools for further handling them. Check the \`README' file,
it often tells you about the needed prerequisites for installing
this package. You may also peek at any GNU archive site, in case
some other package would contain this missing \`$1' program."
exit 1
;;
esac
exit 0
# Local variables:
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-end: "$"
# End:

View File

@ -44,7 +44,7 @@
#include "os_darwin.h"
// Needed by '-V' option (CVS versioning) of smartd/smartctl
const char *os_XXXX_c_cvsid="$Id: os_darwin.cpp,v 1.20 2008/03/04 22:09:47 ballen4705 Exp $" \
const char *os_XXXX_c_cvsid="$Id: os_darwin.cpp,v 1.21 2008/06/12 21:46:31 ballen4705 Exp $" \
ATACMDS_H_CVSID CONFIG_H_CVSID INT64_H_CVSID OS_DARWIN_H_CVSID SCSICMDS_H_CVSID UTILITY_H_CVSID;
// Print examples for smartctl.
@ -435,6 +435,21 @@ int escalade_command_interface(int fd, int escalade_port, int escalade_type,
return -1;
}
int areca_command_interface(int fd, int escalade_port,
smart_command_set command, int select,
char *data)
{
fd = fd;
escalade_port = escalade_port;
command = command;
select = select;
data = data;
return -1;
}
int marvell_command_interface(int fd, smart_command_set command,
int select, char *data)
{

File diff suppressed because it is too large Load Diff

View File

@ -82,19 +82,20 @@
#ifndef OS_FREEBSD_H_
#define OS_FREEBSD_H_
#define OS_FREEBSD_H_CVSID "$Id: os_freebsd.h,v 1.22 2008/03/04 22:09:47 ballen4705 Exp $\n"
#define OS_FREEBSD_H_CVSID "$Id: os_freebsd.h,v 1.26 2009/01/14 02:39:00 sxzzsf Exp $\n"
struct freebsd_dev_channel {
int channel; // the ATA channel to work with
int device; // the device on the channel
#ifndef IOCATAREQUEST
int atacommand; // the ATA Command file descriptor (/dev/ata)
#endif
char* devname; // the SCSI device name
int unitnum; // the SCSI unit number
int scsicontrol; // the SCSI control interface
};
#define FREEBSD_MAXDEV 64
#define FREEBSD_FDOFFSET 16;
#define FREEBSD_FDOFFSET 16
#define MAX_NUM_DEV 26
#ifdef HAVE_SYS_TWEREG_H
@ -573,6 +574,56 @@ typedef struct tw_osli_ioctl_with_payload {
#endif
#define HPT_CTL_CODE(x) (x+0xFF00)
#define HPT_IOCTL_GET_CHANNEL_INFO HPT_CTL_CODE(3)
#define HPT_IOCTL_GET_CHANNEL_INFO_V2 HPT_CTL_CODE(53)
#define HPT_IOCTL_IDE_PASS_THROUGH HPT_CTL_CODE(24)
#define HPT_READ 1
#define HPT_WRITE 2
#define HPT_IOCTL_MAGIC 0xA1B2C3D4
#define MAXDEV_PER_CHANNEL 2
#define PMPORT_PER_CHANNEL 15 /* max devices connected to this channel via pmport */
typedef struct _HPT_CHANNEL_INFO {
unsigned int reserve1;
unsigned int reserve2;
unsigned int devices[MAXDEV_PER_CHANNEL];
} HPT_CHANNEL_INFO, *PHPT_CHANNEL_INFO;
typedef struct _HPT_CHANNEL_INFO_V2 {
unsigned int reserve1;
unsigned int reserve2;
unsigned int devices[PMPORT_PER_CHANNEL];
} HPT_CHANNEL_INFO_V2, *PHPT_CHANNEL_INFO_V2;
typedef struct _HPT_IOCTL_PARAM {
unsigned int magic; /* used to check if it's a valid ioctl packet */
unsigned int ctrl_code; /* operation control code */
void* in; /* input data buffer */
unsigned int in_size; /* size of input data buffer */
void* out; /* output data buffer */
unsigned int out_size; /* size of output data buffer */
void* returned_size; /* count of chars returned */
} HPT_IOCTL_PARAM, *PHPT_IOCTL_PARAM;
#define HPT_DO_IOCONTROL _IOW('H', 0, HPT_IOCTL_PARAM)
typedef struct _HPT_PASS_THROUGH_HEADER {
unsigned int id; /* disk ID */
unsigned char feature;
unsigned char sectorcount;
unsigned char lbalow;
unsigned char lbamid;
unsigned char lbahigh;
unsigned char driverhead;
unsigned char command;
unsigned char sectors; /* data size in sectors, if the command has data transfer */
unsigned char protocol; /* HPT_(READ,WRITE) or zero for non-DATA */
unsigned char reserve[3];
}
HPT_PASS_THROUGH_HEADER, *PHPT_PASS_THROUGH_HEADER;
#ifndef __unused
#define __unused __attribute__ ((__unused__))

View File

@ -5,6 +5,7 @@
*
* Copyright (C) YEAR YOUR_NAME <smartmontools-support@lists.sourceforge.net>
* Copyright (C) 2003-8 Bruce Allen <smartmontools-support@lists.sourceforge.net>
* Copyright (C) 2008 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
@ -70,9 +71,7 @@
// These are needed to define prototypes and structures for the
// functions defined below
#include "int64.h"
#include "atacmds.h"
#include "scsicmds.h"
#include "utility.h"
// This is to include whatever structures and prototypes you define in
@ -83,9 +82,8 @@
// 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.cpp,v 1.26 2008/03/04 22:09:47 ballen4705 Exp $" \
ATACMDS_H_CVSID CONFIG_H_CVSID INT64_H_CVSID OS_GENERIC_H_CVSID SCSICMDS_H_CVSID UTILITY_H_CVSID;
const char *os_XXXX_c_cvsid="$Id: os_generic.cpp,v 1.28 2009/01/20 00:31:17 dlukes Exp $" \
ATACMDS_H_CVSID CONFIG_H_CVSID OS_GENERIC_H_CVSID UTILITY_H_CVSID;
// This is here to prevent compiler warnings for unused arguments of
// functions.
@ -138,7 +136,7 @@ static void unsupported(){
// 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(){
static void print_smartctl_examples(){
printf("=================================================== SMARTCTL EXAMPLES =====\n\n");
#ifdef HAVE_GETOPT_LONG
printf(
@ -165,115 +163,123 @@ void print_smartctl_examples(){
return;
}
// tries to guess device type given the name (a path). See utility.h
// for return values.
int guess_device_type (const char* dev_name) {
ARGUSED(dev_name);
unsupported();
return CONTROLLER_UNKNOWN;
}
/////////////////////////////////////////////////////////////////////////////
// makes a list of ATA or SCSI devices for the DEVICESCAN directive of
// smartd. Returns number N of devices, or -1 if out of
// memory. Allocates N+1 arrays: one of N pointers (devlist); the
// other N arrays each contain null-terminated character strings. In
// the case N==0, no arrays are allocated because the array of 0
// pointers has zero length, equivalent to calling malloc(0).
int make_device_names (char*** devlist, const char* name) {
ARGUSED(devlist);
ARGUSED(name);
unsupported();
return 0;
}
namespace generic { // No need to publish anything, name provided for Doxygen
// 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){
ARGUSED(pathname);
ARGUSED(type);
unsupported();
return -1;
}
// Like close(). Acts only on integer handles returned by
// deviceopen() above.
int deviceclose(int fd){
ARGUSED(fd);
unsupported();
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"
int ata_command_interface(int fd, smart_command_set command, int select, char *data){
ARGUSED(fd);
ARGUSED(command);
ARGUSED(select);
ARGUSED(data);
unsupported();
return -1;
}
int marvell_command_interface(int fd, smart_command_set command, int select, char *data){
ARGUSED(fd);
ARGUSED(command);
ARGUSED(select);
ARGUSED(data);
unsupported();
return -1;
}
int highpoint_command_interface(int fd, smart_command_set command, int select, char *data)
class generic_smart_interface
: public /*implements*/ smart_interface
{
ARGUSED(fd);
ARGUSED(command);
ARGUSED(select);
ARGUSED(data);
unsupported();
return -1;
public:
#ifdef HAVE_GET_OS_VERSION_STR
virtual const char * get_os_version_str();
#endif
virtual const char * get_app_examples(const char * appname);
virtual bool scan_smart_devices(smart_device_list & devlist, const char * type,
const char * pattern = 0);
protected:
virtual ata_device * get_ata_device(const char * name, const char * type);
virtual scsi_device * get_scsi_device(const char * name, const char * type);
virtual smart_device * autodetect_smart_device(const char * name);
virtual smart_device * get_custom_smart_device(const char * name, const char * type);
virtual const char * get_valid_custom_dev_types_str();
};
//////////////////////////////////////////////////////////////////////
#ifdef HAVE_GET_OS_VERSION_STR
/// Return build host and OS version as static string
const char * generic_smart_interface::get_os_version_str()
{
return ::get_os_version_str();
}
#endif
const char * generic_smart_interface::get_app_examples(const char * appname)
{
if (!strcmp(appname, "smartctl"))
::print_smartctl_examples(); // this prints to stdout ...
return 0; // ... so don't print again.
}
// Interface to ATA devices behind 3ware escalade/apache RAID
// controller cards. Same description as ata_command_interface()
// above except that 0 <= disknum <= 15 specifies the ATA disk
// attached to the controller, and controller_type specifies the
// precise type of 3ware controller. See os_linux.c
int escalade_command_interface(int fd, int disknum, int controller_type, smart_command_set command, int select, char *data){
ARGUSED(fd);
ARGUSED(disknum);
ARGUSED(controller_type);
ARGUSED(command);
ARGUSED(select);
ARGUSED(data);
// Return ATA device object for the given device name or NULL
// the type is always set to "ata"
ata_device * generic_smart_interface::get_ata_device(const char * name, const char * type)
{
ARGUSED(name);
ARGUSED(type);
unsupported();
return -1;
return NULL;
}
#include <errno.h>
// Interface to SCSI devices. See os_linux.c
int do_scsi_cmnd_io(int fd, struct scsi_cmnd_io * iop, int report) {
ARGUSED(fd);
ARGUSED(iop);
ARGUSED(report);
// Return SCSI device object for the given device name or NULL
// the type is always set to "scsi"
scsi_device * generic_smart_interface::get_scsi_device(const char * name, const char * type)
{
ARGUSED(name);
ARGUSED(type);
unsupported();
return -ENOSYS;
return NULL;
}
// Return device object for the given device name (autodetect the device type)
smart_device * generic_smart_interface::autodetect_smart_device(const char * name)
{
ARGUSED(name);
// for the given name return the apropriate device type
unsupported();
return NULL;
}
// Fill devlist with all OS's disk devices of given type that match the pattern
bool generic_smart_interface::scan_smart_devices(smart_device_list & devlist,
const char * type, const char * pattern /*= 0*/)
{
ARGUSED(devlist);
ARGUSED(type);
ARGUSED(pattern);
unsupported();
return false;
}
// Return device object of the given type with specified name or NULL
smart_device * generic_smart_interface::get_custom_smart_device(const char * name, const char * type)
{
ARGUSED(name);
ARGUSED(type);
unsupported();
return NULL;
}
const char * generic_smart_interface::get_valid_custom_dev_types_str()
{
return "";
}
} // namespace
/////////////////////////////////////////////////////////////////////////////
/// Initialize platform interface and register with smi()
void smart_interface::init()
{
static generic::generic_smart_interface the_interface;
smart_interface::set(&the_interface);
}

File diff suppressed because it is too large Load Diff

View File

@ -24,14 +24,14 @@
#include "os_netbsd.h"
#include <unistd.h>
const char *os_XXXX_c_cvsid = "$Id: os_netbsd.cpp,v 1.24 2008/03/04 22:09:47 ballen4705 Exp $" \
const char *os_XXXX_c_cvsid = "$Id: os_netbsd.cpp,v 1.25 2008/06/12 21:46:31 ballen4705 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 */
extern long long bytes;
enum warnings {
BAD_SMART, NO_3WARE, MAX_MSG
BAD_SMART, NO_3WARE, NO_ARECA, MAX_MSG
};
/* Utility function for printing warnings */
@ -350,6 +350,13 @@ escalade_command_interface(int fd, int disknum, int escalade_type, smart_command
return -1;
}
int
areca_command_interface(int fd, int disknum, smart_command_set command, int select, char *data)
{
printwarning(NO_ARECA, NULL);
return -1;
}
int
do_scsi_cmnd_io(int fd, struct scsi_cmnd_io * iop, int report)
{

View File

@ -25,14 +25,14 @@
#include "utility.h"
#include "os_openbsd.h"
const char *os_XXXX_c_cvsid = "$Id: os_openbsd.cpp,v 1.16 2008/03/04 22:09:47 ballen4705 Exp $" \
const char *os_XXXX_c_cvsid = "$Id: os_openbsd.cpp,v 1.17 2008/06/12 21:46:31 ballen4705 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 */
extern long long bytes;
enum warnings {
BAD_SMART, NO_3WARE, MAX_MSG
BAD_SMART, NO_3WARE, NO_ARECA, MAX_MSG
};
/* Utility function for printing warnings */
@ -361,6 +361,13 @@ escalade_command_interface(int fd, int disknum, int escalade_type, smart_command
return -1;
}
int
areca_command_interface(int fd, int disknum, smart_command_set command, int select, char *data)
{
printwarning(NO_ARECA, NULL);
return -1;
}
int
do_scsi_cmnd_io(int fd, struct scsi_cmnd_io * iop, int report)
{

555
os_os2.cpp Normal file
View File

@ -0,0 +1,555 @@
/*
* os_os2.c
*
* Home page of code is: http://smartmontools.sourceforge.net
*
* Copyright (C) 2004-8 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.9 2008/06/12 21:46:31 ballen4705 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;
}
int areca_command_interface(int fd, int disknum, 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-8 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.5 2008/03/04 22:09:47 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 */

643
os_qnxnto.cpp Normal file
View File

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

896
os_qnxnto.h Normal file
View File

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

View File

@ -39,9 +39,9 @@
extern long long bytes;
static const char *filenameandversion="$Id: os_solaris.cpp,v 1.30 2008/03/04 22:09:47 ballen4705 Exp $";
static const char *filenameandversion="$Id: os_solaris.cpp,v 1.32 2008/06/12 21:46:31 ballen4705 Exp $";
const char *os_XXXX_c_cvsid="$Id: os_solaris.cpp,v 1.30 2008/03/04 22:09:47 ballen4705 Exp $" \
const char *os_XXXX_c_cvsid="$Id: os_solaris.cpp,v 1.32 2008/06/12 21:46:31 ballen4705 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
@ -336,7 +336,7 @@ int ata_command_interface(int fd, smart_command_set command, int select, char *d
return smart_status_check(fd);
default:
pout("Unrecognized command %d in ata_command_interface() of os_solaris.c\n", command);
exit(1);
EXIT(1);
break;
}
#else /* __sparc */
@ -362,6 +362,15 @@ int escalade_command_interface(int fd, int disknum, int escalade_type, smart_com
return -1;
}
int areca_command_interface(int fd, int disknum, smart_command_set command, int select, char *data){
ARGUSED(fd); ARGUSED(disknum);
ARGUSED(command); ARGUSED(select); ARGUSED(data);
if (printwarning(1))
return -1;
return -1;
}
#include <errno.h>
#include <sys/scsi/generic/commands.h>
#include <sys/scsi/generic/status.h>

File diff suppressed because it is too large Load Diff

View File

@ -1,20 +1,20 @@
;
; installer.nsi - NSIS install script for smartmontools
;
; Copyright (C) 2006-8 Christian Franke <smartmontools-support@lists.sourceforge.net>
; Copyright (C) 2006-9 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.29)
; Process with makensis to create installer (tested with NSIS 2.45)
;
; $Id: installer.nsi,v 1.4 2008/03/04 22:09:48 ballen4705 Exp $
; $Id: installer.nsi 2878 2009-08-26 20:03:06Z chrfranke $
;
;--------------------------------------------------------------------
; Command line arguments:
; makensis /DINPDIR=<input-dir> /DOUTFILE=<output-file> installer.nsi
; makensis /DINPDIR=<input-dir> /DOUTFILE=<output-file> /DVERSTR=<version-string> installer.nsi
!ifndef INPDIR
!define INPDIR "."
@ -106,6 +106,15 @@ SectionGroup "!Program files"
SectionEnd
Section "smartctl-nc (GSmartControl)" SMARTCTL_NC_SECTION
SectionIn 1 2
SetOutPath "$INSTDIR\bin"
File "${INPDIR}\bin\smartctl-nc.exe"
SectionEnd
SectionGroupEnd
Section "!Documentation" DOC_SECTION
@ -143,6 +152,9 @@ Section "Uninstaller" UNINST_SECTION
; Write uninstall keys and program
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\smartmontools" "DisplayName" "smartmontools"
!ifdef VERSTR
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\smartmontools" "DisplayVersion" "${VERSTR}"
!endif
;WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\smartmontools" "Publisher" "smartmontools"
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\smartmontools" "UninstallString" '"$INSTDIR\uninst-smartmontools.exe"'
;WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\smartmontools" "URLInfoAbout" "http://smartmontools.sourceforge.net/"
@ -378,6 +390,7 @@ Section "Uninstall"
; Remove files
Delete "$INSTDIR\bin\smartctl.exe"
Delete "$INSTDIR\bin\smartctl-nc.exe"
Delete "$INSTDIR\bin\smartd.exe"
Delete "$INSTDIR\bin\syslogevt.exe"
Delete "$INSTDIR\bin\smartctl-run.bat"
@ -462,6 +475,7 @@ FunctionEnd
Function SkipProgPath
!insertmacro CheckSection ${SMARTCTL_SECTION}
!insertmacro CheckSection ${SMARTCTL_NC_SECTION}
!insertmacro CheckSection ${SMARTD_SECTION}
!insertmacro CheckSection ${DOC_SECTION}
!insertmacro CheckSection ${MENU_SECTION}

1051
os_win32/smartctl_vc8.vcproj Normal file

File diff suppressed because it is too large Load Diff

1003
os_win32/smartd_vc8.vcproj Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,32 @@

Microsoft Visual Studio Solution File, Format Version 9.00
# Visual Studio 2005
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "smartctl_vc8", "smartctl_vc8.vcproj", "{3AFEDCDD-D289-4543-A91D-EFBA6C710247}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "smartd_vc8", "smartd_vc8.vcproj", "{C0762191-C2AC-40B6-A2EB-F1658BBDC4C6}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "syslogevt_vc8", "syslogevt_vc8.vcproj", "{FAB7557B-86EA-405D-B49D-33AB3F4D3E33}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Release|Win32 = Release|Win32
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{3AFEDCDD-D289-4543-A91D-EFBA6C710247}.Debug|Win32.ActiveCfg = Debug|Win32
{3AFEDCDD-D289-4543-A91D-EFBA6C710247}.Debug|Win32.Build.0 = Debug|Win32
{3AFEDCDD-D289-4543-A91D-EFBA6C710247}.Release|Win32.ActiveCfg = Release|Win32
{3AFEDCDD-D289-4543-A91D-EFBA6C710247}.Release|Win32.Build.0 = Release|Win32
{C0762191-C2AC-40B6-A2EB-F1658BBDC4C6}.Debug|Win32.ActiveCfg = Debug|Win32
{C0762191-C2AC-40B6-A2EB-F1658BBDC4C6}.Debug|Win32.Build.0 = Debug|Win32
{C0762191-C2AC-40B6-A2EB-F1658BBDC4C6}.Release|Win32.ActiveCfg = Release|Win32
{C0762191-C2AC-40B6-A2EB-F1658BBDC4C6}.Release|Win32.Build.0 = Release|Win32
{FAB7557B-86EA-405D-B49D-33AB3F4D3E33}.Debug|Win32.ActiveCfg = Debug|Win32
{FAB7557B-86EA-405D-B49D-33AB3F4D3E33}.Debug|Win32.Build.0 = Debug|Win32
{FAB7557B-86EA-405D-B49D-33AB3F4D3E33}.Release|Win32.ActiveCfg = Release|Win32
{FAB7557B-86EA-405D-B49D-33AB3F4D3E33}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

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-8 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.5 2008/03/04 22:09:48 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.5 $ Copyright (C) 2004-8 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-8 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.5 2008/03/04 22:09:48 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
.

View File

@ -0,0 +1,205 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="8,00"
Name="syslogevt_vc8"
ProjectGUID="{FAB7557B-86EA-405D-B49D-33AB3F4D3E33}"
RootNamespace="syslogevt_vc8"
Keyword="Win32Proj"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="syslogevt_vc8.d"
IntermediateDirectory="syslogevt_vc8.d"
ConfigurationType="1"
CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
PreprocessorDefinitions="_DEBUG;_CONSOLE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="true"
DebugInformationFormat="4"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
LinkIncremental="2"
GenerateDebugInformation="true"
SubSystem="1"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCWebDeploymentTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="syslogevt_vc8.r"
IntermediateDirectory="syslogevt_vc8.r"
ConfigurationType="1"
CharacterSet="2"
WholeProgramOptimization="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
PreprocessorDefinitions="NDEBUG;_CONSOLE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE"
RuntimeLibrary="2"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="true"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
OutputFile="syslogevt.exe"
LinkIncremental="1"
GenerateDebugInformation="true"
ProgramDatabaseFile="$(IntDir)\$(TargetName).pdb"
SubSystem="1"
OptimizeReferences="2"
EnableCOMDATFolding="2"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCWebDeploymentTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<File
RelativePath=".\syslogevt.c"
>
</File>
<File
RelativePath=".\syslogevt.mc"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCustomBuildTool"
Description="mc -r $(IntDir) syslogevt.mc"
CommandLine="mc -r $(IntDir) syslogevt.mc&#x0D;&#x0A;"
Outputs="$(IntDir)\syslogevt.rc;$(IntDir)\msg00001.bin;syslogevt.h"
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCustomBuildTool"
Description="mc -r $(IntDir) syslogevt.mc"
CommandLine="mc -r $(IntDir) syslogevt.mc&#x0D;&#x0A;"
Outputs="$(IntDir)\syslogevt.rc;$(IntDir)\msg00001.bin;syslogevt.h"
/>
</FileConfiguration>
</File>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

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

File diff suppressed because it is too large Load Diff

View File

@ -1,78 +0,0 @@
/*
* 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

@ -45,9 +45,11 @@
#include "int64.h"
#include "extern.h"
#include "scsicmds.h"
#include "atacmds.h" // FIXME: for smart_command_set only
#include "dev_interface.h"
#include "utility.h"
const char *scsicmds_c_cvsid="$Id: scsicmds.cpp,v 1.96 2008/03/04 22:09:47 ballen4705 Exp $"
const char *scsicmds_c_cvsid="$Id: scsicmds.cpp,v 1.98 2009/06/24 04:10:10 dpgilbert Exp $"
CONFIG_H_CVSID EXTERN_H_CVSID INT64_H_CVSID SCSICMDS_H_CVSID UTILITY_H_CVSID;
/* for passing global control variables */
@ -121,6 +123,7 @@ static struct scsi_opcode_name opcode_name_arr[] = {
{RECEIVE_DIAGNOSTIC, "receive diagnostic"}, /* 0x1c */
{SEND_DIAGNOSTIC, "send diagnostic"}, /* 0x1d */
{READ_DEFECT_10, "read defect list(10)"}, /* 0x37 */
{LOG_SELECT, "log select"}, /* 0x4c */
{LOG_SENSE, "log sense"}, /* 0x4d */
{MODE_SELECT_10, "mode select(10)"}, /* 0x55 */
{MODE_SENSE_10, "mode sense(10)"}, /* 0x5a */
@ -249,7 +252,7 @@ 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, int subpagenum, UINT8 *pBuf,
int scsiLogSense(scsi_device * device, int pagenum, int subpagenum, UINT8 *pBuf,
int bufLen, int known_resp_len)
{
struct scsi_cmnd_io io_hdr;
@ -287,9 +290,8 @@ int scsiLogSense(int device, int pagenum, int subpagenum, UINT8 *pBuf,
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)
return status;
if (!device->scsi_pass_through(&io_hdr))
return -device->get_errno();
scsi_do_sense_disect(&io_hdr, &sinfo);
if ((res = scsiSimpleSenseFilter(&sinfo)))
return res;
@ -323,9 +325,8 @@ int scsiLogSense(int device, int pagenum, int subpagenum, UINT8 *pBuf,
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)
return status;
if (!device->scsi_pass_through(&io_hdr))
return -device->get_errno();
scsi_do_sense_disect(&io_hdr, &sinfo);
status = scsiSimpleSenseFilter(&sinfo);
if (0 != status)
@ -338,11 +339,47 @@ int scsiLogSense(int device, int pagenum, int subpagenum, UINT8 *pBuf,
return 0;
}
/* Sends a LOG SELECT command. Can be used to set log page values
* or reset one log page (or all of them) to its defaults (typically zero).
* Returns 0 if ok, 1 if NOT READY, 2 if command not supported, * 3 if
* field in command not supported, * 4 if bad parameter to command or
* returns negated errno. SPC-4 sections 6.5 and 7.2 (rev 20) */
int scsiLogSelect(scsi_device * device, int pcr, int sp, int pc, int pagenum,
int subpagenum, UINT8 *pBuf, int bufLen)
{
struct scsi_cmnd_io io_hdr;
struct scsi_sense_disect sinfo;
UINT8 cdb[10];
UINT8 sense[32];
memset(&io_hdr, 0, sizeof(io_hdr));
memset(cdb, 0, sizeof(cdb));
io_hdr.dxfer_dir = DXFER_TO_DEVICE;
io_hdr.dxfer_len = bufLen;
io_hdr.dxferp = pBuf;
cdb[0] = LOG_SELECT;
cdb[1] = (pcr ? 2 : 0) | (sp ? 1 : 0);
cdb[2] = ((pc << 6) & 0xc0) | (pagenum & 0x3f);
cdb[3] = (subpagenum & 0xff);
cdb[7] = ((bufLen >> 8) & 0xff);
cdb[8] = (bufLen & 0xff);
io_hdr.cmnd = cdb;
io_hdr.cmnd_len = sizeof(cdb);
io_hdr.sensep = sense;
io_hdr.max_sense_len = sizeof(sense);
io_hdr.timeout = SCSI_TIMEOUT_DEFAULT;
if (!device->scsi_pass_through(&io_hdr))
return -device->get_errno();
scsi_do_sense_disect(&io_hdr, &sinfo);
return scsiSimpleSenseFilter(&sinfo);
}
/* Send MODE SENSE (6 byte) command. Returns 0 if ok, 1 if NOT READY,
* 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 subpagenum, int pc,
int scsiModeSense(scsi_device * device, int pagenum, int subpagenum, int pc,
UINT8 *pBuf, int bufLen)
{
struct scsi_cmnd_io io_hdr;
@ -368,15 +405,13 @@ int scsiModeSense(int device, int pagenum, int subpagenum, int pc,
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)
return status;
if (!device->scsi_pass_through(&io_hdr))
return -device->get_errno();
scsi_do_sense_disect(&io_hdr, &sinfo);
status = scsiSimpleSenseFilter(&sinfo);
if (SIMPLE_ERR_TRY_AGAIN == status) {
status = do_scsi_cmnd_io(device, &io_hdr, con->reportscsiioctl);
if (0 != status)
return status;
if (!device->scsi_pass_through(&io_hdr))
return -device->get_errno();
scsi_do_sense_disect(&io_hdr, &sinfo);
status = scsiSimpleSenseFilter(&sinfo);
}
@ -399,13 +434,13 @@ int scsiModeSense(int device, int pagenum, int subpagenum, int pc,
* 2 if command not supported (then MODE SELECT(10) may be supported),
* 3 if field in command not supported, 4 if bad parameter to command
* or returns negated errno. SPC-3 sections 6.7 and 7.4 (rev 22a) */
int scsiModeSelect(int device, int sp, UINT8 *pBuf, int bufLen)
int scsiModeSelect(scsi_device * device, int sp, UINT8 *pBuf, int bufLen)
{
struct scsi_cmnd_io io_hdr;
struct scsi_sense_disect sinfo;
UINT8 cdb[6];
UINT8 sense[32];
int status, pg_offset, pg_len, hdr_plus_1_pg;
int pg_offset, pg_len, hdr_plus_1_pg;
pg_offset = 4 + pBuf[3];
if (pg_offset + 2 >= bufLen)
@ -430,9 +465,8 @@ int scsiModeSelect(int device, int sp, UINT8 *pBuf, int bufLen)
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)
return status;
if (!device->scsi_pass_through(&io_hdr))
return -device->get_errno();
scsi_do_sense_disect(&io_hdr, &sinfo);
return scsiSimpleSenseFilter(&sinfo);
}
@ -441,7 +475,7 @@ 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 subpagenum, int pc,
int scsiModeSense10(scsi_device * device, int pagenum, int subpagenum, int pc,
UINT8 *pBuf, int bufLen)
{
struct scsi_cmnd_io io_hdr;
@ -466,15 +500,13 @@ int scsiModeSense10(int device, int pagenum, int subpagenum, int pc,
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)
return status;
if (!device->scsi_pass_through(&io_hdr))
return -device->get_errno();
scsi_do_sense_disect(&io_hdr, &sinfo);
status = scsiSimpleSenseFilter(&sinfo);
if (SIMPLE_ERR_TRY_AGAIN == status) {
status = do_scsi_cmnd_io(device, &io_hdr, con->reportscsiioctl);
if (0 != status)
return status;
if (!device->scsi_pass_through(&io_hdr))
return -device->get_errno();
scsi_do_sense_disect(&io_hdr, &sinfo);
status = scsiSimpleSenseFilter(&sinfo);
}
@ -497,13 +529,13 @@ int scsiModeSense10(int device, int pagenum, int subpagenum, int pc,
* command not supported (then MODE SELECT(6) may be supported), 3 if field
* in command not supported, 4 if bad parameter to command or returns
* negated errno. SPC-3 sections 6.8 and 7.4 (rev 22a) */
int scsiModeSelect10(int device, int sp, UINT8 *pBuf, int bufLen)
int scsiModeSelect10(scsi_device * device, int sp, UINT8 *pBuf, int bufLen)
{
struct scsi_cmnd_io io_hdr;
struct scsi_sense_disect sinfo;
UINT8 cdb[10];
UINT8 sense[32];
int status, pg_offset, pg_len, hdr_plus_1_pg;
int pg_offset, pg_len, hdr_plus_1_pg;
pg_offset = 8 + (pBuf[6] << 8) + pBuf[7];
if (pg_offset + 2 >= bufLen)
@ -529,9 +561,8 @@ int scsiModeSelect10(int device, int sp, UINT8 *pBuf, int bufLen)
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)
return status;
if (!device->scsi_pass_through(&io_hdr))
return -device->get_errno();
scsi_do_sense_disect(&io_hdr, &sinfo);
return scsiSimpleSenseFilter(&sinfo);
}
@ -539,13 +570,12 @@ int scsiModeSelect10(int device, int sp, UINT8 *pBuf, int bufLen)
/* Standard INQUIRY returns 0 for ok, anything else is a major problem.
* bufLen should be 36 for unsafe devices (like USB mass storage stuff)
* otherwise they can lock up! SPC-3 sections 6.4 and 7.6 (rev 22a) */
int scsiStdInquiry(int device, UINT8 *pBuf, int bufLen)
int scsiStdInquiry(scsi_device * device, UINT8 *pBuf, int bufLen)
{
struct scsi_sense_disect sinfo;
struct scsi_cmnd_io io_hdr;
UINT8 cdb[6];
UINT8 sense[32];
int status;
if ((bufLen < 0) || (bufLen > 255))
return -EINVAL;
@ -562,9 +592,8 @@ int scsiStdInquiry(int device, UINT8 *pBuf, int bufLen)
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)
return status;
if (!device->scsi_pass_through(&io_hdr))
return -device->get_errno();
scsi_do_sense_disect(&io_hdr, &sinfo);
return scsiSimpleSenseFilter(&sinfo);
}
@ -573,13 +602,13 @@ int scsiStdInquiry(int device, UINT8 *pBuf, int bufLen)
* (unlikely), 2 if command not supported, 3 if field in command not
* supported, 5 if response indicates that EVPD bit ignored or returns
* negated errno. SPC-3 section 6.4 and 7.6 (rev 22a) */
int scsiInquiryVpd(int device, int vpd_page, UINT8 *pBuf, int bufLen)
int scsiInquiryVpd(scsi_device * device, int vpd_page, UINT8 *pBuf, int bufLen)
{
struct scsi_cmnd_io io_hdr;
struct scsi_sense_disect sinfo;
UINT8 cdb[6];
UINT8 sense[32];
int status, res;
int res;
if ((bufLen < 0) || (bufLen > 255))
return -EINVAL;
@ -600,9 +629,8 @@ int scsiInquiryVpd(int device, int vpd_page, UINT8 *pBuf, int bufLen)
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)
return status;
if (!device->scsi_pass_through(&io_hdr))
return -device->get_errno();
scsi_do_sense_disect(&io_hdr, &sinfo);
if ((res = scsiSimpleSenseFilter(&sinfo)))
return res;
@ -619,13 +647,13 @@ int scsiInquiryVpd(int device, int vpd_page, UINT8 *pBuf, int bufLen)
/* REQUEST SENSE command. Returns 0 if ok, anything else major problem.
* SPC-3 section 6.27 (rev 22a) */
int scsiRequestSense(int device, struct scsi_sense_disect * sense_info)
int scsiRequestSense(scsi_device * device, struct scsi_sense_disect * sense_info)
{
struct scsi_cmnd_io io_hdr;
UINT8 cdb[6];
UINT8 sense[32];
UINT8 buff[18];
int status, len;
int len;
UINT8 ecode;
memset(&io_hdr, 0, sizeof(io_hdr));
@ -641,8 +669,9 @@ int scsiRequestSense(int device, struct scsi_sense_disect * sense_info)
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) && (sense_info)) {
if (!device->scsi_pass_through(&io_hdr))
return -device->get_errno();
if (sense_info) {
ecode = buff[0] & 0x7f;
sense_info->error_code = ecode;
sense_info->sense_key = buff[2] & 0xf;
@ -656,19 +685,18 @@ int scsiRequestSense(int device, struct scsi_sense_disect * sense_info)
}
}
}
return status;
return 0;
}
/* SEND DIAGNOSTIC command. Returns 0 if ok, 1 if NOT READY, 2 if command
* not supported, 3 if field in command not supported or returns negated
* errno. SPC-3 section 6.28 (rev 22a) */
int scsiSendDiagnostic(int device, int functioncode, UINT8 *pBuf, int bufLen)
int scsiSendDiagnostic(scsi_device * device, int functioncode, UINT8 *pBuf, int bufLen)
{
struct scsi_cmnd_io io_hdr;
struct scsi_sense_disect sinfo;
UINT8 cdb[6];
UINT8 sense[32];
int status;
memset(&io_hdr, 0, sizeof(io_hdr));
memset(cdb, 0, sizeof(cdb));
@ -691,9 +719,8 @@ int scsiSendDiagnostic(int device, int functioncode, UINT8 *pBuf, int bufLen)
/* worst case is an extended foreground self test on a big disk */
io_hdr.timeout = SCSI_TIMEOUT_SELF_TEST;
status = do_scsi_cmnd_io(device, &io_hdr, con->reportscsiioctl);
if (0 != status)
return status;
if (!device->scsi_pass_through(&io_hdr))
return -device->get_errno();
scsi_do_sense_disect(&io_hdr, &sinfo);
return scsiSimpleSenseFilter(&sinfo);
}
@ -701,14 +728,13 @@ int scsiSendDiagnostic(int device, int functioncode, UINT8 *pBuf, int bufLen)
/* RECEIVE DIAGNOSTIC command. Returns 0 if ok, 1 if NOT READY, 2 if
* command not supported, 3 if field in command not supported or returns
* negated errno. SPC-3 section 6.18 (rev 22a) */
int scsiReceiveDiagnostic(int device, int pcv, int pagenum, UINT8 *pBuf,
int scsiReceiveDiagnostic(scsi_device * device, int pcv, int pagenum, UINT8 *pBuf,
int bufLen)
{
struct scsi_cmnd_io io_hdr;
struct scsi_sense_disect sinfo;
UINT8 cdb[6];
UINT8 sense[32];
int status;
memset(&io_hdr, 0, sizeof(io_hdr));
memset(cdb, 0, sizeof(cdb));
@ -726,20 +752,18 @@ int scsiReceiveDiagnostic(int device, int pcv, int pagenum, UINT8 *pBuf,
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)
return status;
if (!device->scsi_pass_through(&io_hdr))
return -device->get_errno();
scsi_do_sense_disect(&io_hdr, &sinfo);
return scsiSimpleSenseFilter(&sinfo);
}
/* TEST UNIT READY command. SPC-3 section 6.33 (rev 22a) */
static int _testunitready(int device, struct scsi_sense_disect * sinfo)
static int _testunitready(scsi_device * device, struct scsi_sense_disect * sinfo)
{
struct scsi_cmnd_io io_hdr;
UINT8 cdb[6];
UINT8 sense[32];
int status;
memset(&io_hdr, 0, sizeof(io_hdr));
memset(cdb, 0, sizeof(cdb));
@ -753,16 +777,15 @@ static int _testunitready(int device, struct scsi_sense_disect * sinfo)
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)
return status;
if (!device->scsi_pass_through(&io_hdr))
return -device->get_errno();
scsi_do_sense_disect(&io_hdr, sinfo);
return 0;
}
/* Returns 0 for device responds and media ready, 1 for device responds and
media not ready, or returns a negated errno value */
int scsiTestUnitReady(int device)
int scsiTestUnitReady(scsi_device * device)
{
struct scsi_sense_disect sinfo;
int status;
@ -784,14 +807,13 @@ int scsiTestUnitReady(int device)
/* READ DEFECT (10) command. Returns 0 if ok, 1 if NOT READY, 2 if
* command not supported, 3 if field in command not supported or returns
* negated errno. SBC-2 section 5.12 (rev 16) */
int scsiReadDefect10(int device, int req_plist, int req_glist, int dl_format,
int scsiReadDefect10(scsi_device * device, int req_plist, int req_glist, int dl_format,
UINT8 *pBuf, int bufLen)
{
struct scsi_cmnd_io io_hdr;
struct scsi_sense_disect sinfo;
UINT8 cdb[10];
UINT8 sense[32];
int status;
memset(&io_hdr, 0, sizeof(io_hdr));
memset(cdb, 0, sizeof(cdb));
@ -809,9 +831,8 @@ int scsiReadDefect10(int device, int req_plist, int req_glist, int dl_format,
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)
return status;
if (!device->scsi_pass_through(&io_hdr))
return -device->get_errno();
scsi_do_sense_disect(&io_hdr, &sinfo);
return scsiSimpleSenseFilter(&sinfo);
}
@ -860,7 +881,7 @@ int scsiModePageOffset(const UINT8 * resp, int len, int modese_len)
* tries a 10 byte MODE SENSE command. Returns 0 if successful, a positive
* number if a known error (see SIMPLE_ERR_ ...) or a negative errno
* value. */
int scsiFetchIECmpage(int device, struct scsi_iec_mode_page *iecp, int modese_len)
int scsiFetchIECmpage(scsi_device * device, struct scsi_iec_mode_page *iecp, int modese_len)
{
int err = 0;
@ -950,7 +971,7 @@ int scsi_IsWarningEnabled(const struct scsi_iec_mode_page *iecp)
* is to be re-examined.
* When -r ioctl is invoked 3 or more time on 'smartctl -s on ...'
* then set the TEST bit (causes asc,ascq pair of 0x5d,0xff). */
int scsiSetExceptionControlAndWarning(int device, int enabled,
int scsiSetExceptionControlAndWarning(scsi_device * device, int enabled,
const struct scsi_iec_mode_page *iecp)
{
int k, offset, resp_len;
@ -1025,7 +1046,7 @@ int scsiSetExceptionControlAndWarning(int device, int enabled,
return err;
}
int scsiGetTemp(int device, UINT8 *currenttemp, UINT8 *triptemp)
int scsiGetTemp(scsi_device * device, UINT8 *currenttemp, UINT8 *triptemp)
{
UINT8 tBuf[252];
int err;
@ -1047,7 +1068,7 @@ int scsiGetTemp(int device, UINT8 *currenttemp, UINT8 *triptemp)
* Fetching asc/ascq code potentially flagging an exception or warning.
* Returns 0 if ok, else error number. A current temperature of 255
* (Celsius) implies that the temperature not available. */
int scsiCheckIE(int device, int hasIELogPage, int hasTempLogPage,
int scsiCheckIE(scsi_device * device, int hasIELogPage, int hasTempLogPage,
UINT8 *asc, UINT8 *ascq, UINT8 *currenttemp,
UINT8 *triptemp)
{
@ -1630,7 +1651,7 @@ const char * scsiGetIEString(UINT8 asc, UINT8 ascq)
/* This is not documented in t10.org, page 0x80 is vendor specific */
/* Some IBM disks do an offline read-scan when they get this command. */
int scsiSmartIBMOfflineTest(int device)
int scsiSmartIBMOfflineTest(scsi_device * device)
{
UINT8 tBuf[256];
int res;
@ -1651,7 +1672,7 @@ int scsiSmartIBMOfflineTest(int device)
return res;
}
int scsiSmartDefaultSelfTest(int device)
int scsiSmartDefaultSelfTest(scsi_device * device)
{
int res;
@ -1661,7 +1682,7 @@ int scsiSmartDefaultSelfTest(int device)
return res;
}
int scsiSmartShortSelfTest(int device)
int scsiSmartShortSelfTest(scsi_device * device)
{
int res;
@ -1671,7 +1692,7 @@ int scsiSmartShortSelfTest(int device)
return res;
}
int scsiSmartExtendSelfTest(int device)
int scsiSmartExtendSelfTest(scsi_device * device)
{
int res;
@ -1682,7 +1703,7 @@ int scsiSmartExtendSelfTest(int device)
return res;
}
int scsiSmartShortCapSelfTest(int device)
int scsiSmartShortCapSelfTest(scsi_device * device)
{
int res;
@ -1692,7 +1713,7 @@ int scsiSmartShortCapSelfTest(int device)
return res;
}
int scsiSmartExtendCapSelfTest(int device)
int scsiSmartExtendCapSelfTest(scsi_device * device)
{
int res;
@ -1703,7 +1724,7 @@ int scsiSmartExtendCapSelfTest(int device)
return res;
}
int scsiSmartSelfTestAbort(int device)
int scsiSmartSelfTestAbort(scsi_device * device)
{
int res;
@ -1715,7 +1736,7 @@ int scsiSmartSelfTestAbort(int device)
/* Returns 0 and the expected duration of an extended self test (in seconds)
if successful; any other return value indicates a failure. */
int scsiFetchExtendedSelfTestTime(int device, int * durationSec, int modese_len)
int scsiFetchExtendedSelfTestTime(scsi_device * device, int * durationSec, int modese_len)
{
int err, offset, res;
UINT8 buff[64];
@ -1875,7 +1896,7 @@ void scsiDecodeNonMediumErrPage(unsigned char *resp,
tests (typically by the user) and self tests in progress are not
considered failures. See Working Draft SCSI Primary Commands - 3
(SPC-3) section 7.2.10 T10/1416-D (rev 22a) */
int scsiCountFailedSelfTests(int fd, int noisy)
int scsiCountFailedSelfTests(scsi_device * fd, int noisy)
{
int num, k, n, err, res, fails, fail_hour;
UINT8 * ucp;
@ -1924,7 +1945,7 @@ int scsiCountFailedSelfTests(int fd, int noisy)
/* Returns 0 if able to read self test log page; then outputs 1 into
*inProgress if self test still in progress, else outputs 0. */
int scsiSelfTestInProgress(int fd, int * inProgress)
int scsiSelfTestInProgress(scsi_device * fd, int * inProgress)
{
int num;
UINT8 * ucp;
@ -1951,7 +1972,7 @@ int scsiSelfTestInProgress(int fd, int * inProgress)
malformed. Returns 0 if GLTSD bit is zero and returns 1 if the GLTSD
bit is set. Examines default mode page when current==0 else examines
current mode page. */
int scsiFetchControlGLTSD(int device, int modese_len, int current)
int scsiFetchControlGLTSD(scsi_device * device, int modese_len, int current)
{
int err, offset;
UINT8 buff[64];
@ -1984,7 +2005,7 @@ int scsiFetchControlGLTSD(int device, int modese_len, int current)
0 attempts to clear GLTSD otherwise it attempts to set it. Returns 0 if
successful, negative if low level error, > 0 if higher level error (e.g.
SIMPLE_ERR_BAD_PARAM if GLTSD bit is not changeable). */
int scsiSetControlGLTSD(int device, int enabled, int modese_len)
int scsiSetControlGLTSD(scsi_device * device, int enabled, int modese_len)
{
int err, offset, resp_len, sp;
UINT8 buff[64];
@ -2053,7 +2074,7 @@ int scsiSetControlGLTSD(int device, int enabled, int modese_len)
/* Returns a negative value if failed to fetch Protocol specific port mode
page or it was malformed. Returns transport protocol identifier when
value >= 0 . */
int scsiFetchTransportProtocol(int device, int modese_len)
int scsiFetchTransportProtocol(scsi_device * device, int modese_len)
{
int err, offset;
UINT8 buff[64];

View File

@ -32,7 +32,7 @@
#ifndef SCSICMDS_H_
#define SCSICMDS_H_
#define SCSICMDS_H_CVSID "$Id: scsicmds.h,v 1.66 2008/03/04 22:09:47 ballen4705 Exp $\n"
#define SCSICMDS_H_CVSID "$Id: scsicmds.h,v 1.69 2009/06/24 04:10:10 dpgilbert Exp $\n"
#include <stdio.h>
#include <stdlib.h>
@ -41,11 +41,14 @@
/* #define SCSI_DEBUG 1 */ /* Comment out to disable command debugging */
/* Following conditional defines bypass inclusion of scsi/scsi.h and
* scsi/scsi_ioctl.h . Issue will be resolved later ... */
/* Following conditional defines just in case OS already has them defined.
* If they are defined we hope they are defined correctly (for SCSI). */
#ifndef TEST_UNIT_READY
#define TEST_UNIT_READY 0x0
#endif
#ifndef LOG_SELECT
#define LOG_SELECT 0x4c
#endif
#ifndef LOG_SENSE
#define LOG_SENSE 0x4d
#endif
@ -171,6 +174,7 @@ struct scsiNonMediumError {
#define APPLICATION_CLIENT_LPAGE 0x0f
#define SELFTEST_RESULTS_LPAGE 0x10
#define BACKGROUND_RESULTS_LPAGE 0x15 /* SBC-3 */
#define PROTOCOL_SPECIFIC_LPAGE 0x18
#define IE_LPAGE 0x2f
/* Seagate vendor specific log pages. */
@ -277,6 +281,8 @@ Documentation, see http://www.storage.ibm.com/techsup/hddtech/prodspecs.htm */
#define LOGPAGEHDRSIZE 4
class scsi_device;
void scsi_do_sense_disect(const struct scsi_cmnd_io * in,
struct scsi_sense_disect * out);
@ -285,73 +291,76 @@ int scsiSimpleSenseFilter(const struct scsi_sense_disect * sinfo);
const char * scsiErrString(int scsiErr);
/* STANDARD SCSI Commands */
int scsiTestUnitReady(int device);
int scsiTestUnitReady(scsi_device * device);
int scsiStdInquiry(int device, UINT8 *pBuf, int bufLen);
int scsiStdInquiry(scsi_device * device, UINT8 *pBuf, int bufLen);
int scsiInquiryVpd(int device, int vpd_page, UINT8 *pBuf, int bufLen);
int scsiInquiryVpd(scsi_device * device, int vpd_page, UINT8 *pBuf, int bufLen);
int scsiLogSense(int device, int pagenum, int subpagenum, UINT8 *pBuf,
int bufLen, int known_resp_len);
int scsiLogSense(scsi_device * device, int pagenum, int subpagenum, UINT8 *pBuf,
int bufLen, int known_resp_len);
int scsiModeSense(int device, int pagenum, int subpagenum, int pc,
int scsiLogSelect(scsi_device * device, int pcr, int sp, int pc, int pagenum,
int subpagenum, UINT8 *pBuf, int bufLen);
int scsiModeSense(scsi_device * device, int pagenum, int subpagenum, int pc,
UINT8 *pBuf, int bufLen);
int scsiModeSelect(int device, int sp, UINT8 *pBuf, int bufLen);
int scsiModeSelect(scsi_device * device, int sp, UINT8 *pBuf, int bufLen);
int scsiModeSense10(int device, int pagenum, int subpagenum, int pc,
UINT8 *pBuf, int bufLen);
int scsiModeSense10(scsi_device * device, int pagenum, int subpagenum, int pc,
UINT8 *pBuf, int bufLen);
int scsiModeSelect10(int device, int sp, UINT8 *pBuf, int bufLen);
int scsiModeSelect10(scsi_device * device, int sp, UINT8 *pBuf, int bufLen);
int scsiModePageOffset(const UINT8 * resp, int len, int modese_len);
int scsiRequestSense(int device, struct scsi_sense_disect * sense_info);
int scsiRequestSense(scsi_device * device, struct scsi_sense_disect * sense_info);
int scsiSendDiagnostic(int device, int functioncode, UINT8 *pBuf, int bufLen);
int scsiSendDiagnostic(scsi_device * device, int functioncode, UINT8 *pBuf, int bufLen);
int scsiReceiveDiagnostic(int device, int pcv, int pagenum, UINT8 *pBuf,
int scsiReceiveDiagnostic(scsi_device * device, int pcv, int pagenum, UINT8 *pBuf,
int bufLen);
int scsiReadDefect10(int device, int req_plist, int req_glist, int dl_format,
int scsiReadDefect10(scsi_device * device, int req_plist, int req_glist, int dl_format,
UINT8 *pBuf, int bufLen);
/* SMART specific commands */
int scsiCheckIE(int device, int hasIELogPage, int hasTempLogPage, UINT8 *asc,
int scsiCheckIE(scsi_device * device, int hasIELogPage, int hasTempLogPage, UINT8 *asc,
UINT8 *ascq, UINT8 *currenttemp, UINT8 *triptemp);
int scsiFetchIECmpage(int device, struct scsi_iec_mode_page *iecp,
int scsiFetchIECmpage(scsi_device * device, struct scsi_iec_mode_page *iecp,
int modese_len);
int scsi_IsExceptionControlEnabled(const struct scsi_iec_mode_page *iecp);
int scsi_IsWarningEnabled(const struct scsi_iec_mode_page *iecp);
int scsiSetExceptionControlAndWarning(int device, int enabled,
int scsiSetExceptionControlAndWarning(scsi_device * device, int enabled,
const struct scsi_iec_mode_page *iecp);
void scsiDecodeErrCounterPage(unsigned char * resp,
struct scsiErrorCounter *ecp);
void scsiDecodeNonMediumErrPage(unsigned char * resp,
struct scsiNonMediumError *nmep);
int scsiFetchExtendedSelfTestTime(int device, int * durationSec,
int scsiFetchExtendedSelfTestTime(scsi_device * device, int * durationSec,
int modese_len);
int scsiCountFailedSelfTests(int fd, int noisy);
int scsiSelfTestInProgress(int fd, int * inProgress);
int scsiFetchControlGLTSD(int device, int modese_len, int current);
int scsiSetControlGLTSD(int device, int enabled, int modese_len);
int scsiFetchTransportProtocol(int device, int modese_len);
int scsiCountFailedSelfTests(scsi_device * device, int noisy);
int scsiSelfTestInProgress(scsi_device * device, int * inProgress);
int scsiFetchControlGLTSD(scsi_device * device, int modese_len, int current);
int scsiSetControlGLTSD(scsi_device * device, int enabled, int modese_len);
int scsiFetchTransportProtocol(scsi_device * device, int modese_len);
/* T10 Standard IE Additional Sense Code strings taken from t10.org */
const char* scsiGetIEString(UINT8 asc, UINT8 ascq);
int scsiGetTemp(int device, UINT8 *currenttemp, UINT8 *triptemp);
int scsiGetTemp(scsi_device * device, UINT8 *currenttemp, UINT8 *triptemp);
int scsiSmartIBMOfflineTest(int device);
int scsiSmartIBMOfflineTest(scsi_device * device);
int scsiSmartDefaultSelfTest(int device);
int scsiSmartShortSelfTest(int device);
int scsiSmartExtendSelfTest(int device);
int scsiSmartShortCapSelfTest(int device);
int scsiSmartExtendCapSelfTest(int device);
int scsiSmartSelfTestAbort(int device);
int scsiSmartDefaultSelfTest(scsi_device * device);
int scsiSmartShortSelfTest(scsi_device * device);
int scsiSmartExtendSelfTest(scsi_device * device);
int scsiSmartShortCapSelfTest(scsi_device * device);
int scsiSmartExtendCapSelfTest(scsi_device * device);
int scsiSmartSelfTestAbort(scsi_device * device);
const char * scsiTapeAlertsTapeDevice(unsigned short code);
const char * scsiTapeAlertsChangerDevice(unsigned short code);
@ -370,7 +379,9 @@ inline void dStrHex(const unsigned char* str, int len, int no_ascii)
* (e.g. CHECK CONDITION). If the SCSI command could not be issued
* (e.g. device not present or not a SCSI device) or some other problem
* arises (e.g. timeout) then returns a negative errno value. */
int do_scsi_cmnd_io(int dev_fd, struct scsi_cmnd_io * iop, int report);
// Moved to C++ interface
//int do_scsi_cmnd_io(int dev_fd, struct scsi_cmnd_io * iop, int report);
#endif

View File

@ -3,11 +3,11 @@
*
* Home page of code is: http://smartmontools.sourceforge.net
*
* Copyright (C) 2002-8 Bruce Allen <smartmontools-support@lists.sourceforge.net>
* Copyright (C) 2002-9 Bruce Allen <smartmontools-support@lists.sourceforge.net>
* Copyright (C) 2000 Michael Cornwell <cornwell@acm.org>
*
* Additional SCSI work:
* Copyright (C) 2003-8 Douglas Gilbert <dougg@torque.net>
* Copyright (C) 2003-9 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
@ -35,25 +35,23 @@
#include "int64.h"
#include "extern.h"
#include "scsicmds.h"
#include "atacmds.h" // smart_command_set
#include "dev_interface.h"
#include "scsiprint.h"
#include "smartctl.h"
#include "utility.h"
#include "scsiata.h"
#define GBUF_SIZE 65535
const char* scsiprint_c_cvsid="$Id: scsiprint.cpp,v 1.121 2008/03/04 22:09:47 ballen4705 Exp $"
CONFIG_H_CVSID EXTERN_H_CVSID INT64_H_CVSID SCSICMDS_H_CVSID SCSIPRINT_H_CVSID SMARTCTL_H_CVSID UTILITY_H_CVSID;
const char * scsiprint_c_cvsid = "$Id: scsiprint.cpp 2861 2009-07-24 16:47:03Z chrfranke $"
SCSIPRINT_H_CVSID;
// control block which points to external global control variables
extern smartmonctrl *con;
// to hold onto exit code for atexit routine
extern int exitstatus;
UINT8 gBuf[GBUF_SIZE];
#define LOG_RESP_LEN 252
#define LOG_RESP_LONG_LEN 16384
#define LOG_RESP_LONG_LEN ((62 * 256) + 252)
#define LOG_RESP_TAPE_ALERT_LEN 0x144
/* Log pages supported */
@ -67,6 +65,7 @@ static int gVerifyECounterLPage = 0;
static int gNonMediumELPage = 0;
static int gLastNErrorLPage = 0;
static int gBackgroundResultsLPage = 0;
static int gProtocolSpecificLPage = 0;
static int gTapeAlertsLPage = 0;
static int gSeagateCacheLPage = 0;
static int gSeagateFactoryLPage = 0;
@ -81,7 +80,7 @@ static int modese_len = 0;
// simply returns to the calling routine.
extern void failuretest(int type, int returnvalue);
static void scsiGetSupportedLogPages(int device)
static void scsiGetSupportedLogPages(scsi_device * device)
{
int i, err;
@ -126,6 +125,9 @@ static void scsiGetSupportedLogPages(int device)
case BACKGROUND_RESULTS_LPAGE:
gBackgroundResultsLPage = 1;
break;
case PROTOCOL_SPECIFIC_LPAGE:
gProtocolSpecificLPage = 1;
break;
case TAPE_ALERTS_LPAGE:
gTapeAlertsLPage = 1;
break;
@ -143,7 +145,7 @@ static void scsiGetSupportedLogPages(int device)
/* Returns 0 if ok, -1 if can't check IE, -2 if can check and bad
(or at least something to report). */
static int scsiGetSmartData(int device, int attribs)
static int scsiGetSmartData(scsi_device * device, bool attribs)
{
UINT8 asc;
UINT8 ascq;
@ -187,14 +189,14 @@ static int scsiGetSmartData(int device, int attribs)
// Returns number of logged errors or zero if none or -1 if fetching
// TapeAlerts fails
static char *severities = "CWI";
static const char * const severities = "CWI";
static int scsiGetTapeAlertsData(int device, int peripheral_type)
static int scsiGetTapeAlertsData(scsi_device * device, int peripheral_type)
{
unsigned short pagelength;
unsigned short parametercode;
int i, err;
char *s;
const char *s;
const char *ts;
int failures = 0;
@ -237,7 +239,7 @@ static int scsiGetTapeAlertsData(int device, int peripheral_type)
return failures;
}
static void scsiGetStartStopData(int device)
static void scsiGetStartStopData(scsi_device * device)
{
UINT32 u;
int err, len, k, extra, pc;
@ -280,7 +282,7 @@ static void scsiGetStartStopData(int device)
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",
pout("Specified cycle count over device lifetime: %u\n",
u);
}
break;
@ -288,7 +290,22 @@ static void scsiGetStartStopData(int device)
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);
pout("Accumulated start-stop cycles: %u\n", u);
}
break;
case 5:
if (extra > 7) {
u = (ucp[4] << 24) | (ucp[5] << 16) | (ucp[6] << 8) | ucp[7];
if (0xffffffff != u)
pout("Specified load-unload count over device "
"lifetime: %u\n", u);
}
break;
case 6:
if (extra > 7) {
u = (ucp[4] << 24) | (ucp[5] << 16) | (ucp[6] << 8) | ucp[7];
if (0xffffffff != u)
pout("Accumulated load-unload cycles: %u\n", u);
}
break;
default:
@ -298,7 +315,7 @@ static void scsiGetStartStopData(int device)
}
}
static void scsiPrintGrownDefectListLen(int device)
static void scsiPrintGrownDefectListLen(scsi_device * device)
{
int err, dl_format, dl_len, div;
@ -347,7 +364,7 @@ static void scsiPrintGrownDefectListLen(int device)
}
}
static void scsiPrintSeagateCacheLPage(int device)
static void scsiPrintSeagateCacheLPage(scsi_device * device)
{
int k, j, num, pl, pc, err, len;
unsigned char * ucp;
@ -422,7 +439,7 @@ static void scsiPrintSeagateCacheLPage(int device)
}
}
static void scsiPrintSeagateFactoryLPage(int device)
static void scsiPrintSeagateFactoryLPage(scsi_device * device)
{
int k, j, num, pl, pc, len, err, good, bad;
unsigned char * ucp;
@ -516,7 +533,7 @@ static void scsiPrintSeagateFactoryLPage(int device)
}
}
static void scsiPrintErrorCounterLog(int device)
static void scsiPrintErrorCounterLog(scsi_device * device)
{
struct scsiErrorCounter errCounterArr[3];
struct scsiErrorCounter * ecp;
@ -639,8 +656,8 @@ static const char * self_test_code[] = {
static const char * self_test_result[] = {
"Completed ",
"Interrupted ('-X' switch)",
"Interrupted (bus reset ?)",
"Aborted (by user command)",
"Aborted (device reset ?) ",
"Unknown error, incomplete",
"Completed, segment failed",
"Failed in first segment ",
@ -660,7 +677,7 @@ static const char * self_test_result[] = {
// Returns 0 if ok else FAIL* bitmask. Note that if any of the most recent
// 20 self tests fail (result code 3 to 7 inclusive) then FAILLOG and/or
// FAILSMART is returned.
static int scsiPrintSelfTest(int device)
static int scsiPrintSelfTest(scsi_device * device)
{
int num, k, n, res, err, durationSec;
int noheader = 1;
@ -814,15 +831,15 @@ static const char * bms_status[] = {
"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 */
"waiting until BMS interval timer expires", /* 8 */
};
static const char * reassign_status[] = {
"No reassignment needed",
"Require Reassign or Write command",
"Reserved [0x0]",
"Require Write or Reassign Blocks command",
"Successfully reassigned",
"Reserved [0x3]",
"Failed",
"Reassignment by disk failed",
"Recovered via rewrite in-place",
"Reassigned by app, has valid data",
"Reassigned by app, has no valid data",
@ -833,7 +850,7 @@ static const char * reassign_status[] = {
// 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)
static int scsiPrintBackgroundResults(scsi_device * device)
{
int num, j, m, err, pc, pl, truncated;
int noheader = 1;
@ -895,6 +912,8 @@ static int scsiPrintBackgroundResults(int device)
(ucp[10] << 8) + ucp[11]);
pout("scan progress: %.2f%%\n",
(double)((ucp[12] << 8) + ucp[13]) * 100.0 / 65536.0);
pout(" Number of background medium scans performed: %d\n",
(ucp[14] << 8) + ucp[15]);
break;
default:
if (noheader) {
@ -934,6 +953,334 @@ static int scsiPrintBackgroundResults(int device)
return retval;
}
static void show_sas_phy_event_info(int peis, unsigned int val,
unsigned thresh_val)
{
unsigned int u;
switch (peis) {
case 0:
pout(" No event\n");
break;
case 0x1:
pout(" Invalid word count: %u\n", val);
break;
case 0x2:
pout(" Running disparity error count: %u\n", val);
break;
case 0x3:
pout(" Loss of dword synchronization count: %u\n", val);
break;
case 0x4:
pout(" Phy reset problem count: %u\n", val);
break;
case 0x5:
pout(" Elasticity buffer overflow count: %u\n", val);
break;
case 0x6:
pout(" Received ERROR count: %u\n", val);
break;
case 0x20:
pout(" Received address frame error count: %u\n", val);
break;
case 0x21:
pout(" Transmitted abandon-class OPEN_REJECT count: %u\n", val);
break;
case 0x22:
pout(" Received abandon-class OPEN_REJECT count: %u\n", val);
break;
case 0x23:
pout(" Transmitted retry-class OPEN_REJECT count: %u\n", val);
break;
case 0x24:
pout(" Received retry-class OPEN_REJECT count: %u\n", val);
break;
case 0x25:
pout(" Received AIP (WATING ON PARTIAL) count: %u\n", val);
break;
case 0x26:
pout(" Received AIP (WAITING ON CONNECTION) count: %u\n", val);
break;
case 0x27:
pout(" Transmitted BREAK count: %u\n", val);
break;
case 0x28:
pout(" Received BREAK count: %u\n", val);
break;
case 0x29:
pout(" Break timeout count: %u\n", val);
break;
case 0x2a:
pout(" Connection count: %u\n", val);
break;
case 0x2b:
pout(" Peak transmitted pathway blocked count: %u\n",
val & 0xff);
pout(" Peak value detector threshold: %u\n",
thresh_val & 0xff);
break;
case 0x2c:
u = val & 0xffff;
if (u < 0x8000)
pout(" Peak transmitted arbitration wait time (us): "
"%u\n", u);
else
pout(" Peak transmitted arbitration wait time (ms): "
"%u\n", 33 + (u - 0x8000));
u = thresh_val & 0xffff;
if (u < 0x8000)
pout(" Peak value detector threshold (us): %u\n",
u);
else
pout(" Peak value detector threshold (ms): %u\n",
33 + (u - 0x8000));
break;
case 0x2d:
pout(" Peak arbitration time (us): %u\n", val);
pout(" Peak value detector threshold: %u\n", thresh_val);
break;
case 0x2e:
pout(" Peak connection time (us): %u\n", val);
pout(" Peak value detector threshold: %u\n", thresh_val);
break;
case 0x40:
pout(" Transmitted SSP frame count: %u\n", val);
break;
case 0x41:
pout(" Received SSP frame count: %u\n", val);
break;
case 0x42:
pout(" Transmitted SSP frame error count: %u\n", val);
break;
case 0x43:
pout(" Received SSP frame error count: %u\n", val);
break;
case 0x44:
pout(" Transmitted CREDIT_BLOCKED count: %u\n", val);
break;
case 0x45:
pout(" Received CREDIT_BLOCKED count: %u\n", val);
break;
case 0x50:
pout(" Transmitted SATA frame count: %u\n", val);
break;
case 0x51:
pout(" Received SATA frame count: %u\n", val);
break;
case 0x52:
pout(" SATA flow control buffer overflow count: %u\n", val);
break;
case 0x60:
pout(" Transmitted SMP frame count: %u\n", val);
break;
case 0x61:
pout(" Received SMP frame count: %u\n", val);
break;
case 0x63:
pout(" Received SMP frame error count: %u\n", val);
break;
default:
break;
}
}
static void show_sas_port_param(unsigned char * ucp, int param_len)
{
int j, m, n, nphys, pcb, t, sz, spld_len;
unsigned char * vcp;
uint64_t ull;
unsigned int ui;
char s[64];
sz = sizeof(s);
pcb = ucp[2];
t = (ucp[0] << 8) | ucp[1];
pout("relative target port id = %d\n", t);
pout(" generation code = %d\n", ucp[6]);
nphys = ucp[7];
pout(" number of phys = %d\n", nphys);
for (j = 0, vcp = ucp + 8; j < (param_len - 8);
vcp += spld_len, j += spld_len) {
pout(" phy identifier = %d\n", vcp[1]);
spld_len = vcp[3];
if (spld_len < 44)
spld_len = 48; /* in SAS-1 and SAS-1.1 vcp[3]==0 */
else
spld_len += 4;
t = ((0x70 & vcp[4]) >> 4);
switch (t) {
case 0: snprintf(s, sz, "no device attached"); break;
case 1: snprintf(s, sz, "end device"); break;
case 2: snprintf(s, sz, "expander device"); break;
case 3: snprintf(s, sz, "expander device (fanout)"); break;
default: snprintf(s, sz, "reserved [%d]", t); break;
}
pout(" attached device type: %s\n", s);
t = 0xf & vcp[4];
switch (t) {
case 0: snprintf(s, sz, "unknown"); break;
case 1: snprintf(s, sz, "power on"); break;
case 2: snprintf(s, sz, "hard reset"); break;
case 3: snprintf(s, sz, "SMP phy control function"); break;
case 4: snprintf(s, sz, "loss of dword synchronization"); break;
case 5: snprintf(s, sz, "mux mix up"); break;
case 6: snprintf(s, sz, "I_T nexus loss timeout for STP/SATA");
break;
case 7: snprintf(s, sz, "break timeout timer expired"); break;
case 8: snprintf(s, sz, "phy test function stopped"); break;
case 9: snprintf(s, sz, "expander device reduced functionality");
break;
default: snprintf(s, sz, "reserved [0x%x]", t); break;
}
pout(" attached reason: %s\n", s);
t = (vcp[5] & 0xf0) >> 4;
switch (t) {
case 0: snprintf(s, sz, "unknown"); break;
case 1: snprintf(s, sz, "power on"); break;
case 2: snprintf(s, sz, "hard reset"); break;
case 3: snprintf(s, sz, "SMP phy control function"); break;
case 4: snprintf(s, sz, "loss of dword synchronization"); break;
case 5: snprintf(s, sz, "mux mix up"); break;
case 6: snprintf(s, sz, "I_T nexus loss timeout for STP/SATA");
break;
case 7: snprintf(s, sz, "break timeout timer expired"); break;
case 8: snprintf(s, sz, "phy test function stopped"); break;
case 9: snprintf(s, sz, "expander device reduced functionality");
break;
default: snprintf(s, sz, "reserved [0x%x]", t); break;
}
pout(" reason: %s\n", s);
t = (0xf & vcp[5]);
switch (t) {
case 0: snprintf(s, sz, "phy enabled; unknown");
break;
case 1: snprintf(s, sz, "phy disabled"); break;
case 2: snprintf(s, sz, "phy enabled; speed negotiation failed");
break;
case 3: snprintf(s, sz, "phy enabled; SATA spinup hold state");
break;
case 4: snprintf(s, sz, "phy enabled; port selector");
break;
case 5: snprintf(s, sz, "phy enabled; reset in progress");
break;
case 6: snprintf(s, sz, "phy enabled; unsupported phy attached");
break;
case 8: snprintf(s, sz, "phy enabled; 1.5 Gbps"); break;
case 9: snprintf(s, sz, "phy enabled; 3 Gbps"); break;
case 0xa: snprintf(s, sz, "phy enabled; 6 Gbps"); break;
default: snprintf(s, sz, "reserved [%d]", t); break;
}
pout(" negotiated logical link rate: %s\n", s);
pout(" attached initiator port: ssp=%d stp=%d smp=%d\n",
!! (vcp[6] & 8), !! (vcp[6] & 4), !! (vcp[6] & 2));
pout(" attached target port: ssp=%d stp=%d smp=%d\n",
!! (vcp[7] & 8), !! (vcp[7] & 4), !! (vcp[7] & 2));
for (n = 0, ull = vcp[8]; n < 8; ++n) {
ull <<= 8; ull |= vcp[8 + n];
}
pout(" SAS address = 0x%" PRIx64 "\n", ull);
for (n = 0, ull = vcp[16]; n < 8; ++n) {
ull <<= 8; ull |= vcp[16 + n];
}
pout(" attached SAS address = 0x%" PRIx64 "\n", ull);
pout(" attached phy identifier = %d\n", vcp[24]);
ui = (vcp[32] << 24) | (vcp[33] << 16) | (vcp[34] << 8) | vcp[35];
pout(" Invalid DWORD count = %u\n", ui);
ui = (vcp[36] << 24) | (vcp[37] << 16) | (vcp[38] << 8) | vcp[39];
pout(" Running disparity error count = %u\n", ui);
ui = (vcp[40] << 24) | (vcp[41] << 16) | (vcp[42] << 8) | vcp[43];
pout(" Loss of DWORD synchronization = %u\n", ui);
ui = (vcp[44] << 24) | (vcp[45] << 16) | (vcp[46] << 8) | vcp[47];
pout(" Phy reset problem = %u\n", ui);
if (spld_len > 51) {
int num_ped, peis;
unsigned char * xcp;
unsigned int pvdt;
num_ped = vcp[51];
if (num_ped > 0)
pout(" Phy event descriptors:\n");
xcp = vcp + 52;
for (m = 0; m < (num_ped * 12); m += 12, xcp += 12) {
peis = xcp[3];
ui = (xcp[4] << 24) | (xcp[5] << 16) | (xcp[6] << 8) |
xcp[7];
pvdt = (xcp[8] << 24) | (xcp[9] << 16) | (xcp[10] << 8) |
xcp[11];
show_sas_phy_event_info(peis, ui, pvdt);
}
}
}
}
// Returns 1 if okay, 0 if non SAS descriptors
static int show_protocol_specific_page(unsigned char * resp, int len)
{
int k, num, param_len;
unsigned char * ucp;
num = len - 4;
for (k = 0, ucp = resp + 4; k < num; ) {
param_len = ucp[3] + 4;
if (6 != (0xf & ucp[4]))
return 0; /* only decode SAS log page */
if (0 == k)
pout("Protocol Specific port log page for SAS SSP\n");
show_sas_port_param(ucp, param_len);
k += param_len;
ucp += param_len;
}
return 1;
}
// See Serial Attached SCSI (SAS-2) (e.g. revision 16) the Protocol Specific
// log pageSerial Attached SCSI (SAS-2) (e.g. revision 16) the Protocol
// Specific log page.
// Returns 0 if ok else FAIL* bitmask. Note that if any of the most recent
// 20 self tests fail (result code 3 to 7 inclusive) then FAILLOG and/or
// FAILSMART is returned.
static int scsiPrintSasPhy(scsi_device * device, int reset)
{
int num, err;
if ((err = scsiLogSense(device, PROTOCOL_SPECIFIC_LPAGE, 0, gBuf,
LOG_RESP_LONG_LEN, 0))) {
PRINT_ON(con);
pout("scsiPrintSasPhy Log Sense Failed [%s]\n", scsiErrString(err));
PRINT_OFF(con);
return FAILSMART;
}
if ((gBuf[0] & 0x3f) != PROTOCOL_SPECIFIC_LPAGE) {
PRINT_ON(con);
pout("Protocol specific Log Sense Failed, page mismatch\n");
PRINT_OFF(con);
return FAILSMART;
}
// compute page length
num = (gBuf[2] << 8) + gBuf[3];
if (1 != show_protocol_specific_page(gBuf, num + 4)) {
PRINT_ON(con);
pout("Only support protocol specific log page on SAS devices\n");
PRINT_OFF(con);
return FAILSMART;
}
if (reset) {
if ((err = scsiLogSelect(device, 1 /* pcr */, 0 /* sp */, 0 /* pc */,
PROTOCOL_SPECIFIC_LPAGE, 0, NULL, 0))) {
PRINT_ON(con);
pout("scsiPrintSasPhy Log Select (reset) Failed [%s]\n",
scsiErrString(err));
PRINT_OFF(con);
return FAILSMART;
}
}
return 0;
}
static const char * peripheral_dt_arr[] = {
"disk",
"tape",
@ -973,7 +1320,7 @@ static const char * transport_proto_arr[] = {
};
/* Returns 0 on success, 1 on general error and 2 for early, clean exit */
static int scsiGetDriveInfo(int device, UINT8 * peripheral_type, int all)
static int scsiGetDriveInfo(scsi_device * device, UINT8 * peripheral_type, bool all)
{
char manufacturer[9];
char product[17];
@ -1025,29 +1372,7 @@ static int scsiGetDriveInfo(int device, UINT8 * peripheral_type, int all)
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 ((0 == con->controller_explicit) &&
if (!*device->get_req_type()/*no type requested*/ &&
(0 == strncmp(manufacturer, "ATA", 3))) {
pout("\nProbable ATA device behind a SAT layer\n"
"Try an additional '-d ata' or '-d sat' argument.\n");
@ -1154,7 +1479,7 @@ static int scsiGetDriveInfo(int device, UINT8 * peripheral_type, int all)
return 0;
}
static int scsiSmartEnable(int device)
static int scsiSmartEnable(scsi_device * device)
{
struct scsi_iec_mode_page iec;
int err;
@ -1190,7 +1515,7 @@ static int scsiSmartEnable(int device)
return 0;
}
static int scsiSmartDisable(int device)
static int scsiSmartDisable(scsi_device * device)
{
struct scsi_iec_mode_page iec;
int err;
@ -1226,7 +1551,7 @@ static int scsiSmartDisable(int device)
return 0;
}
static void scsiPrintTemp(int device)
static void scsiPrintTemp(scsi_device * device)
{
UINT8 temp = 0;
UINT8 trip = 0;
@ -1245,14 +1570,14 @@ static void scsiPrintTemp(int device)
}
/* Main entry point used by smartctl command. Return 0 for success */
int scsiPrintMain(int fd)
int scsiPrintMain(scsi_device * device, const scsi_print_options & options)
{
int checkedSupportedLogPages = 0;
UINT8 peripheral_type = 0;
int returnval = 0;
int res, durationSec;
res = scsiGetDriveInfo(fd, &peripheral_type, con->driveinfo);
res = scsiGetDriveInfo(device, &peripheral_type, options.drive_info);
if (res) {
if (2 == res)
return 0;
@ -1260,45 +1585,45 @@ int scsiPrintMain(int fd)
failuretest(MANDATORY_CMD, returnval |= FAILID);
}
if (con->smartenable) {
if (scsiSmartEnable(fd))
if (options.smart_enable) {
if (scsiSmartEnable(device))
failuretest(MANDATORY_CMD, returnval |= FAILSMART);
}
if (con->smartdisable) {
if (scsiSmartDisable(fd))
if (options.smart_disable) {
if (scsiSmartDisable(device))
failuretest(MANDATORY_CMD,returnval |= FAILSMART);
}
if (con->smartautosaveenable) {
if (scsiSetControlGLTSD(fd, 0, modese_len)) {
if (options.smart_auto_save_enable) {
if (scsiSetControlGLTSD(device, 0, modese_len)) {
pout("Enable autosave (clear GLTSD bit) failed\n");
failuretest(OPTIONAL_CMD,returnval |= FAILSMART);
}
}
if (con->smartautosavedisable) {
if (scsiSetControlGLTSD(fd, 1, modese_len)) {
if (options.smart_auto_save_disable) {
if (scsiSetControlGLTSD(device, 1, modese_len)) {
pout("Disable autosave (set GLTSD bit) failed\n");
failuretest(OPTIONAL_CMD,returnval |= FAILSMART);
}
}
if (con->checksmart) {
scsiGetSupportedLogPages(fd);
if (options.smart_check_status) {
scsiGetSupportedLogPages(device);
checkedSupportedLogPages = 1;
if ((SCSI_PT_SEQUENTIAL_ACCESS == peripheral_type) ||
(SCSI_PT_MEDIUM_CHANGER == peripheral_type)) { /* tape device */
if (gTapeAlertsLPage) {
if (con->driveinfo)
if (options.drive_info)
pout("TapeAlert Supported\n");
if (-1 == scsiGetTapeAlertsData(fd, peripheral_type))
if (-1 == scsiGetTapeAlertsData(device, peripheral_type))
failuretest(OPTIONAL_CMD, returnval |= FAILSMART);
}
else
pout("TapeAlert Not Supported\n");
} else { /* disk, cd/dvd, enclosure, etc */
if ((res = scsiGetSmartData(fd, con->smartvendorattrib))) {
if ((res = scsiGetSmartData(device, options.smart_vendor_attrib))) {
if (-2 == res)
returnval |= FAILSTATUS;
else
@ -1306,38 +1631,38 @@ int scsiPrintMain(int fd)
}
}
}
if (con->smartvendorattrib) {
if (options.smart_vendor_attrib) {
if (! checkedSupportedLogPages)
scsiGetSupportedLogPages(fd);
scsiGetSupportedLogPages(device);
if (gTempLPage) {
if (con->checksmart)
if (options.smart_check_status)
pout("\n");
scsiPrintTemp(fd);
scsiPrintTemp(device);
}
if (gStartStopLPage)
scsiGetStartStopData(fd);
scsiGetStartStopData(device);
if (SCSI_PT_DIRECT_ACCESS == peripheral_type) {
scsiPrintGrownDefectListLen(fd);
scsiPrintGrownDefectListLen(device);
if (gSeagateCacheLPage)
scsiPrintSeagateCacheLPage(fd);
scsiPrintSeagateCacheLPage(device);
if (gSeagateFactoryLPage)
scsiPrintSeagateFactoryLPage(fd);
scsiPrintSeagateFactoryLPage(device);
}
}
if (con->smarterrorlog) {
if (options.smart_error_log) {
if (! checkedSupportedLogPages)
scsiGetSupportedLogPages(fd);
scsiPrintErrorCounterLog(fd);
if (1 == scsiFetchControlGLTSD(fd, modese_len, 1))
scsiGetSupportedLogPages(device);
scsiPrintErrorCounterLog(device);
if (1 == scsiFetchControlGLTSD(device, modese_len, 1))
pout("\n[GLTSD (Global Logging Target Save Disable) set. "
"Enable Save with '-S on']\n");
}
if (con->smartselftestlog) {
if (options.smart_selftest_log) {
if (! checkedSupportedLogPages)
scsiGetSupportedLogPages(fd);
scsiGetSupportedLogPages(device);
res = 0;
if (gSelfTestLPage)
res = scsiPrintSelfTest(fd);
res = scsiPrintSelfTest(device);
else {
pout("Device does not support Self Test logging\n");
failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
@ -1345,12 +1670,12 @@ int scsiPrintMain(int fd)
if (0 != res)
failuretest(OPTIONAL_CMD, returnval|=res);
}
if (con->smartbackgroundlog) {
if (options.smart_background_log) {
if (! checkedSupportedLogPages)
scsiGetSupportedLogPages(fd);
scsiGetSupportedLogPages(device);
res = 0;
if (gBackgroundResultsLPage)
res = scsiPrintBackgroundResults(fd);
res = scsiPrintBackgroundResults(device);
else {
pout("Device does not support Background scan results logging\n");
failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
@ -1358,27 +1683,27 @@ int scsiPrintMain(int fd)
if (0 != res)
failuretest(OPTIONAL_CMD, returnval|=res);
}
if (con->smartexeoffimmediate) {
if (scsiSmartDefaultSelfTest(fd))
if (options.smart_default_selftest) {
if (scsiSmartDefaultSelfTest(device))
return returnval | FAILSMART;
pout("Default Self Test Successful\n");
}
if (con->smartshortcapselftest) {
if (scsiSmartShortCapSelfTest(fd))
if (options.smart_short_cap_selftest) {
if (scsiSmartShortCapSelfTest(device))
return returnval | FAILSMART;
pout("Short Foreground Self Test Successful\n");
}
if (con->smartshortselftest ) {
if (scsiSmartShortSelfTest(fd))
if (options.smart_short_selftest) {
if (scsiSmartShortSelfTest(device))
return returnval | FAILSMART;
pout("Short Background Self Test has begun\n");
pout("Use smartctl -X to abort test\n");
}
if (con->smartextendselftest) {
if (scsiSmartExtendSelfTest(fd))
if (options.smart_extend_selftest) {
if (scsiSmartExtendSelfTest(device))
return returnval | FAILSMART;
pout("Extended Background Self Test has begun\n");
if ((0 == scsiFetchExtendedSelfTestTime(fd, &durationSec,
if ((0 == scsiFetchExtendedSelfTestTime(device, &durationSec,
modese_len)) && (durationSec > 0)) {
time_t t = time(NULL);
@ -1389,15 +1714,19 @@ int scsiPrintMain(int fd)
}
pout("Use smartctl -X to abort test\n");
}
if (con->smartextendcapselftest) {
if (scsiSmartExtendCapSelfTest(fd))
if (options.smart_extend_cap_selftest) {
if (scsiSmartExtendCapSelfTest(device))
return returnval | FAILSMART;
pout("Extended Foreground Self Test Successful\n");
}
if (con->smartselftestabort) {
if (scsiSmartSelfTestAbort(fd))
if (options.smart_selftest_abort) {
if (scsiSmartSelfTestAbort(device))
return returnval | FAILSMART;
pout("Self Test returned without error\n");
}
if (options.sasphy) {
if (scsiPrintSasPhy(device, options.sasphy_reset))
return returnval | FAILSMART;
}
return returnval;
}

View File

@ -3,11 +3,11 @@
*
* Home page of code is: http://smartmontools.sourceforge.net
*
* Copyright (C) 2002-8 Bruce Allen <smartmontools-support@lists.sourceforge.net>
* Copyright (C) 2002-9 Bruce Allen <smartmontools-support@lists.sourceforge.net>
* Copyright (C) 2000 Michael Cornwell <cornwell@acm.org>
*
* Additional SCSI work:
* Copyright (C) 2003-8 Douglas Gilbert <dougg@torque.net>
* Copyright (C) 2003-9 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
@ -26,12 +26,49 @@
*/
/* scsismart version number */
#ifndef SCSI_PRINT_H_
#define SCSI_PRINT_H_
#define SCSIPRINT_H_CVSID "$Id: scsiprint.h,v 1.21 2008/03/04 22:09:47 ballen4705 Exp $\n"
#define SCSIPRINT_H_CVSID "$Id: scsiprint.h,v 1.24 2009/06/21 02:39:32 dpgilbert Exp $\n"
int scsiPrintMain(int fd);
// Options for scsiPrintMain
// TODO: Move remaining options from con->* to here.
struct scsi_print_options
{
bool drive_info;
bool smart_check_status;
bool smart_vendor_attrib;
bool smart_error_log;
bool smart_selftest_log;
bool smart_background_log;
bool smart_disable, smart_enable;
bool smart_auto_save_disable, smart_auto_save_enable;
bool smart_default_selftest;
bool smart_short_selftest, smart_short_cap_selftest;
bool smart_extend_selftest, smart_extend_cap_selftest;
bool smart_selftest_abort;
bool sasphy, sasphy_reset;
scsi_print_options()
: drive_info(false),
smart_check_status(false),
smart_vendor_attrib(false),
smart_error_log(false),
smart_selftest_log(false),
smart_background_log(false),
smart_disable(false), smart_enable(false),
smart_auto_save_disable(false), smart_auto_save_enable(false),
smart_default_selftest(false),
smart_short_selftest(false), smart_short_cap_selftest(false),
smart_extend_selftest(false), smart_extend_cap_selftest(false),
smart_selftest_abort(false),
sasphy(false), sasphy_reset(false)
{ }
};
int scsiPrintMain(scsi_device * device, const scsi_print_options & options);
#endif

View File

@ -1,7 +1,7 @@
.ig
Copyright (C) 2002-8 Bruce Allen <smartmontools-support@lists.sourceforge.net>
Copyright (C) 2002-9 Bruce Allen <smartmontools-support@lists.sourceforge.net>
$Id: smartctl.8.in,v 1.105 2008/03/04 22:09:47 ballen4705 Exp $
$Id: smartctl.8.in 2855 2009-07-21 19:55:08Z chrfranke $
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
@ -54,18 +54,23 @@ ignored and/or return an error.
from SCSI tape drives and changers.
The user must specify the device to be controlled or interrogated as
the final argument to \fBsmartctl\fP. Device paths are as follows:
the final argument to \fBsmartctl\fP. The command set used by the device
is often derived from the device path but may need help with the \'\-d\'
option (for more information see the section on "ATA, SCSI command sets
and SAT" below). Device paths are as follows:
.IP \fBLINUX\fP: 9
Use the forms \fB"/dev/hd[a\-t]"\fP for IDE/ATA
devices, and \fB"/dev/sd[a\-z]"\fP for SCSI devices. For
SCSI Tape Drives and Changers with TapeAlert support use the devices
\fB"/dev/nst*"\fP and \fB"/dev/sg*"\fP.
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. 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.
Use the forms \fB"/dev/hd[a\-t]"\fP for IDE/ATA devices, and
\fB"/dev/sd[a\-z]"\fP for SCSI devices. For SCSI Tape Drives and
Changers with TapeAlert support use the devices \fB"/dev/nst*"\fP and
\fB"/dev/sg*"\fP. 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. For disks behind HighPoint RocketRAID controllers you may need
\fB"/dev/sd[a\-z]"\fP. For disks behind Areca SATA RAID controllers,
you need \fB"/dev/sg[2\-9]"\fP (note that smartmontools interacts with
the Areca controllers via a SCSI generic device which is different
than the SCSI device used for reading and writing data)!
.IP \fBDARWIN\fP: 9
Use the forms \fB/dev/disk[0\-9]\fP or equivalently \fBdisk[0\-9]\fP or equivalently
\fB/dev/rdisk[0\-9]\fP. Long forms are also available: please use \'\-h\' to see some
@ -99,7 +104,8 @@ Use one the forms \fB"/dev/tape[0\-255]"\fP, \fB"/dev/st[0\-255]"\fP,
or \fB"/dev/nst[0\-255]"\fP for SCSI tape drives "\\\\.\\Tape[0\-255]".
Alternatively, drive letters \fB"X:"\fP or \fB"X:\\"\fP may be used to
specify the physical drive behind a mounted partition.
specify the (\'basic\') disk behind a mounted partition. This does
not work with \'dynamic\' disks.
For disks behind 3ware 9000 controllers use \fB"/dev/sd[a\-z],N"\fP where
N specifies the disk number (3ware \'port\') behind the controller
@ -137,12 +143,6 @@ The options are grouped below into several categories. \fBsmartctl\fP
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 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
.B \'smartctl \-h\'
to see the available options.
@ -154,9 +154,9 @@ to see the available options.
Prints a usage message to STDOUT and exits.
.TP
.B \-V, \-\-version, \-\-copyright, \-\-license
Prints version, copyright, license, home page and CVS\-id information
for your copy of \fBsmartctl\fP to STDOUT and then exits. Please
include this information if you are reporting bugs or problems.
Prints version, copyright, license, home page and SVN revision
information for your copy of \fBsmartctl\fP to STDOUT and then exits.
Please include this information if you are reporting bugs or problems.
.TP
.B \-i, \-\-info
Prints the device model number, serial number, firmware version, and
@ -181,8 +181,20 @@ and for SCSI, this is equivalent to
.nf
\'\-H \-i \-A \-l error \-l selftest\'.
.fi
Note that for ATA disks this does \fBnot\fP enable the \'\-l
directory\' option.
Note that for ATA disks this does \fBnot\fP enable the non-SMART options
and the SMART options which require support for 48-bit ATA commands.
.TP
.B \-x, \-\-xall
Prints all SMART and non-SMART information about the device. For ATA
devices this is equivalent to
.nf
\'\-H \-i \-c \-A \-l xerror,error \-l xselftest,selftest \-l selective
\-l directory \-l scttemp \-l sataphy\'.
.fi
and for SCSI, this is equivalent to
.nf
\'\-H \-i \-A \-l error \-l selftest \-l background \-l sasphy\'.
.fi
.TP
.B RUN\-TIME BEHAVIOR OPTIONS:
@ -210,9 +222,17 @@ 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, \fIsat\fP, \fImarvell\fP, \fI3ware,N\fP, and \fIhpt,L/M\fP,
\fIcciss,N\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.
are \fIata\fP, \fIscsi\fP, \fIsat\fP, \fImarvell\fP, \fI3ware,N\fP,
\fIareca,N\fP, \fIusbcypress\fP, \fIusbjmicron\fP, \fIusbsunplus\fP,
\fIcciss,N\fP, \fIhpt,L/M\fP (or \fIhpt,L/M/N\fP), and \fItest\fP.
If this option is not used then \fBsmartctl\fP will attempt to guess
the device type from the device name or from controller type info
provided by the operating system.
If \'test\' is used as the TYPE name, \fBsmartctl\fP prints the guessed
TYPE name, then opens the device and prints the (possibly changed) TYPE
name and then exists without performing any further commands.
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.
@ -221,6 +241,26 @@ 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\'.
The \'usbcypress\' device type is for ATA disks that are behind a Cypress
usb-pata bridge. This will use the ATACB proprietary scsi pass through command. There is no autodetection at the moment. The best way to know if your device support it, is to check your device usb id (most Cypress usb ata bridge got vid=0x04b4, pid=0x6830) or to try it (if the usb device doesn't support ATACB, smartmontools print an error).
The default scsi operation code is 0x24, but although it can be overridden
with \'\-d usbcypress,0xn\', where n is the scsi operation code,
you're running the risk of damage to the device or filesystems on it.
[NEW EXPERIMENTAL SMARTCTL FEATURE] The \'usbjmicron\' device type is for
SATA disks that are behind a JMicron USB to PATA/SATA bridge. The 48-bit
ATA commands (required e.g. for \'\-l xerror\', see below) do not work with
all of these bridges and are therefore disabled by default. These commands
can be enabled by \'\-d usbjmicron,x\'. CAUTION: Specifying \',x\' for a
device which do not support it results in I/O errors and may disconnect
the drive. The port can be specified by \'\-d usbjmicron[,x],PORT\' where
PORT is 0 (master) or 1 (slave). This is not necessary if only one disk is
connected to the USB bridge. If two disks are connected, an error message
is printed if no PORT is specified.
[NEW EXPERIMENTAL SMARTCTL FEATURE] The \'usbsunplus\' device type is for
SATA disks that are behind a SunplusIT USB to SATA bridge.
Under Linux, to look at SATA disks behind Marvell SATA controllers
(using Marvell's \'linuxIAL\' driver rather than libata driver) use \'\-d marvell\'. Such
controllers show up as Marvell Technology Group Ltd. SATA I or II controllers
@ -229,6 +269,22 @@ 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).
Under Linux , to look at SCSI/SAS disks behind LSI MegaRAID controllers,
use syntax such as:
.nf
\fBsmartctl \-a \-d megaraid,2 /dev/sda\fP
.fi
.nf
\fBsmartctl \-a \-d megaraid,0 /dev/sdb\fP
.fi
where in the argument \fImegaraid,N\fP, the integer N is the physical disk
number within the MegaRAID controller. This interface will also work for
Dell PERC controllers. The following /dev/XXX entry must exist:
.fi
For PERC2/3/4 controllers: \fB/dev/megadev0\fP
.fi
For PERC5/6 controllers: \fB/dev/megaraid_sas_ioctl_node\fP
Under Linux and FreeBSD, to look at ATA disks behind 3ware SCSI RAID controllers,
use syntax such as:
.nf
@ -242,7 +298,7 @@ use syntax such as:
.fi
where in the argument \fI3ware,N\fP, the integer N is the disk number
(3ware \'port\') within the 3ware ATA RAID controller. The allowed
values of N are from 0 to 31 inclusive. The first two forms, which
values of N are from 0 to 127 inclusive. The first two forms, which
refer to devices /dev/sda\-z and /dev/twe0\-15, may be used with 3ware
series 6000, 7000, and 8000 series controllers that use the 3x\-xxxx
driver. \fBNote that the /dev/sda\-z form is deprecated\fP starting
@ -295,33 +351,66 @@ 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 supported under Linux, FreeBSD and Windows.
.B Areca SATA RAID controllers are currently supported under Linux only.
To look at SATA disks behind Areca RAID controllers, use syntax such
as:
.nf
\fBsmartctl \-a \-d areca,2 /dev/sg2\fP
.fi
.nf
\fBsmartctl \-a \-d areca,3 /dev/sg3\fP
.fi
where in the argument \fIareca,N\fP, the integer N is the disk number
(Areca \'port\') within the Areca SATA RAID controller. The allowed
values of N are from 1 to 24 inclusive. The first line above
addresses the second disk on the first Areca RAID controller. The
second line addresses the third disk on the second Areca RAID
controller. To help identify the correct device, use the command:
.nf
\fBcat /proc/scsi/sg/device_hdr /proc/scsi/sg/devices\fP
.fi
to show the SCSI generic devices (one per line, starting with
/dev/sg0). The correct SCSI generic devices to address for
smartmontools are the ones with the type field equal to 3. If the
incorrect device is addressed, please read the warning/error messages
carefully. They should provide hints about what devices to use.
Important: the Areca controller must have firmware version 1.46 or
later. Lower-numbered firmware versions will give (harmless) SCSI
error messages and no SMART information.
To look at (S)ATA disks behind HighPoint RocketRAID controllers, use syntax
such as:
.nf
\fBsmartctl \-a \-d hpt,1/3 /dev/sda\fP
\fBsmartctl \-a \-d hpt,1/3 /dev/sda\fP (under Linux)
.fi
or
.nf
\fBsmartctl \-a \-d hpt,1/2/3 /dev/sda\fP
\fBsmartctl \-a \-d hpt,1/2/3 /dev/sda\fP (under Linux)
.fi
.nf
\fBsmartctl \-a \-d hpt,1/3 /dev/hptrr\fP (under FreeBSD)
.fi
.nf
\fBsmartctl \-a \-d hpt,1/2/3 /dev/hptrr\fP (under FreeBSD)
.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.
inclusive, M are from 1 to 8 inclusive and N from 1 to 5 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.
the disks derived from the HighPoint RocketRAID controllers under Linux and
under FreeBSD, it is the character device which the driver registered (eg,
/dev/hptrr, /dev/hptmv6). And also these values are limited by the model
of the HighPoint RocketRAID controller.
.B HighPoint RocketRAID controllers are currently ONLY supported under Linux.
.B HighPoint RocketRAID controllers are currently ONLY supported under Linux and FreeBSD.
.B cciss controllers are currently ONLY supported under Linux.
.TP
.B \-T TYPE, \-\-tolerance=TYPE
Specifies how tolerant \fBsmartctl\fP should be of ATA and SMART command
failures.
[ATA only] Specifies how tolerant \fBsmartctl\fP should be of ATA and SMART
command failures.
The behavior of \fBsmartctl\fP depends upon whether the command is
"\fBoptional\fP" or "\fBmandatory\fP". Here "\fBmandatory\fP" means
@ -361,9 +450,9 @@ Please see the note above.
.TP
.B \-b TYPE, \-\-badsum=TYPE
Specifies the action \fBsmartctl\fP should take if a checksum error is
detected in the: (1) Device Identity Structure, (2) SMART Self\-Test
Log Structure, (3) SMART Attribute Value Structure, (4) SMART
[ATA only] Specifies the action \fBsmartctl\fP should take if a checksum
error is detected in the: (1) Device Identity Structure, (2) SMART
Self\-Test Log Structure, (3) SMART Attribute Value Structure, (4) SMART
Attribute Threshold Structure, or (5) ATA Error Log Structure.
The valid arguments to this option are:
@ -417,9 +506,9 @@ behaviour. This is does not work for SCSI devices yet.
.TP
.B \-n POWERMODE, \-\-nocheck=POWERMODE
Specifieds if \fBsmartctl\fP should exit before performing any checks
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
[ATA only] Specifies 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
@ -454,16 +543,16 @@ the corresponding disable command.
.B \-s VALUE, \-\-smart=VALUE
Enables or disables SMART on device. The valid arguments to
this option are \fIon\fP and \fIoff\fP. Note that the command \'\-s on\'
(perhaps used with with the \'\-o on\' and \'\-S on\' options) should be placed
in a start\-up script for your machine, for example in rc.local or rc.sysinit.
In principle the SMART feature settings are preserved over
(perhaps used with with the \'\-o on\' and \'\-S on\' options) should be
placed in a start\-up script for your machine, for example in rc.local or
rc.sysinit. In principle the SMART feature settings are preserved over
power\-cycling, but it doesn\'t hurt to be sure. It is not necessary (or
useful) to enable SMART to see the TapeAlert messages.
.TP
.B \-o VALUE, \-\-offlineauto=VALUE
Enables or disables SMART automatic offline test, which scans the drive
every four hours for disk defects. This command can be given during normal
system operation. The valid arguments to this option are \fIon\fP
[ATA only] Enables or disables SMART automatic offline test, which scans the
drive every four hours for disk defects. This command can be given during
normal system operation. The valid arguments to this option are \fIon\fP
and \fIoff\fP.
Note that the SMART automatic offline test command is listed as
@ -568,8 +657,8 @@ this happens, use the \'\-a\' option to get more information, and
.B get your data off the disk and to someplace safe as soon as you can.
.TP
.B \-c, \-\-capabilities
Prints only the generic SMART capabilities. These show
what SMART features are implemented and how the device will
[ATA only] Prints only the generic SMART capabilities. These
show what SMART features are implemented and how the device will
respond to some of the different SMART commands. For example it
shows if the device logs errors, if it supports offline surface
scanning, and so on. If the device can carry out self\-tests, this
@ -585,8 +674,8 @@ for further information about the the flags and capabilities described
by this option.
.TP
.B \-A, \-\-attributes
Prints only the vendor specific SMART Attributes. The Attributes are
numbered from 1 to 253 and have specific names and ID numbers. For
[ATA] Prints only the vendor specific SMART Attributes. The Attributes
are numbered from 1 to 253 and have specific names and ID numbers. For
example Attribute 12 is "power cycle count": how many times has the
disk been powered up.
@ -667,7 +756,7 @@ Attribute fields has been made entirely vendor\-specific. However most
ATA/ATAPI\-5 disks seem to respect their meaning, so we have retained
the option of printing the Attribute values.
For SCSI devices the "attributes" are obtained from the temperature
[SCSI] For SCSI devices the "attributes" are obtained from the temperature
and start\-stop cycle counter log pages. Certain vendor specific
attributes are listed if recognised. The attributes are output in a
relatively free format (compared with ATA disk attributes).
@ -679,8 +768,8 @@ the Background Scan Results Log [SCSI only].
The valid arguments to this option are:
.I error
\- prints only the SMART error log. SMART disks maintain a log of the
most recent five non\-trivial errors. For each of these errors, the
\- [ATA] prints the Summary SMART error log. SMART disks maintain a log
of the most recent five non\-trivial errors. For each of these errors, the
disk power\-on lifetime at which the error occurred is recorded, as is
the device status (idle, standby, etc) at the time of the error. For
some common types of errors, the Error Register (ER) and Status
@ -753,13 +842,34 @@ Please note that some manufacturers \fBignore\fP the ATA
specifications, and make entries in the error log if the device
receives a command which is not implemented or is not valid.
.I error [SCSI]
\- prints the error counter log pages for reads, write and verifies.
.I error
\- [SCSI] prints the error counter log pages for reads, write and verifies.
The verify row is only output if it has an element other than zero.
.I xerror[,NUM][,error]
\- [ATA only] [NEW EXPERIMENTAL SMARTCTL FEATURE] prints the Extended
Comprehensive SMART error log (General Purpose Log address 0x03).
Unlike the Summary SMART error log (see \'\-l error\' above),
it provides sufficient space to log the contents of the 48-bit
LBA register set introduced with ATA-6. It also supports logs
with more than one sector. Each sector holds up to 4 log entries.
The actual number of log sectors is vendor specific, typical values
for HDD are 2 (Samsung), 5 (Seagate) or 6 (WD). Some recent SSD devices
have much larger error logs.
Only the 8 most recent error log entries are printed by default.
This number can be changed by the optional parameter NUM.
If ',error' is appended and the Extended Comprehensive SMART error
log is not supported, the Summary SMART self-test log is printed.
Please note that some recent (e.g. Samsung) drives report errors only
in the Comprehensive SMART error log. The Summary SMART error log can
be read but is always empty.
.I selftest
\- prints the SMART self\-test log. The disk maintains a self\-test log
showing the results of the self tests, which can be run using the
\- [ATA] prints the SMART self\-test log. The disk maintains a self\-test
log showing the results of the self tests, which can be run using the
\'\-t\' option described below. For each of the most recent
twenty\-one self\-tests, the log shows the type of test (short or
extended, off\-line or captive) and the final status of the test. If
@ -771,9 +881,9 @@ printed in decimal notation. On Linux systems the smartmontools
web page has instructions about how to convert this LBA address to the
name of the disk file containing the erroneous block.
.I selftest [SCSI]
\- the self\-test log for a SCSI device has a slightly different format
than for an ATA device. For each of the most recent twenty
.I selftest
\- [SCSI] the self\-test log for a SCSI device has a slightly different
format than for an ATA device. For each of the most recent twenty
self\-tests, it shows the type of test and the status (final or in
progress) of the test. SCSI standards use the terms "foreground" and
"background" (rather than ATA\'s corresponding "captive" and
@ -793,9 +903,22 @@ Additional Sense Code Qualifier (ASQ) are also printed. The self tests
can be run using the \'\-t\' option described below (using the ATA
test terminology).
.I selective [ATA]
\- Some ATA\-7 disks (example: Maxtor) also maintain a selective
self\-test log. Please see the \'\-t select\' option below for a
.I xselftest[,NUM][,selftest]
\- [ATA only] [NEW EXPERIMENTAL SMARTCTL FEATURE] prints the Extended
SMART self\-test log (General Purpose Log address 0x07). Unlike the SMART
self\-test log (see \'\-l selftest\' above), it supports 48-bit LBA
and logs with more than one sector. Each sector holds up to 19 log
entries. The actual number of log sectors is vendor specific, typical
values are 1 (Seagate) or 2 (Samsung).
Only the 25 most recent log entries are printed by default. This number
can be changed by the optional parameter NUM.
If ',selftest' is appended and the Extended SMART self-test log is not
supported, the old SMART self-test log is printed.
.I selective
\- [ATA only] Please see the \'\-t select\' option below for a
description of selective self\-tests. The selective self\-test log
shows the start/end Logical Block Addresses (LBA) of each of the five
test spans, and their current test status. If the span is being
@ -809,9 +932,9 @@ delay before restarting this read\-scan if it is interrupted (see
report unusual or incorrect behavior to the smartmontools\-support
mailing list.
.I directory
\- if the device supports the General Purpose Logging feature set
(ATA\-6 and ATA\-7 only) then this prints the Log Directory (the log at
.I directory[,gs]
\- [ATA only] if the device supports the General Purpose Logging feature
set (ATA\-6 and above) then this prints the Log Directory (the log at
address 0). The Log Directory shows what logs are available and their
length in sectors (512 bytes). The contents of the logs at address 1
[Summary SMART error log] and at address 6 [SMART self\-test log] may
@ -819,16 +942,16 @@ be printed using the previously\-described
.I error
and
.I selftest
arguments to this option. [Please note: this is a new, experimental
feature. We would like to add support for printing the contents of
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.]
arguments to this option.
If your version of smartctl supports 48-bit ATA commands, both the
General Purpose Log (GPL) and SMART Log (SL) directories are printed in
one combined table. The output can be restricted to the GPL directory or
SL directory by \'\-l directory,q\' or \'\-l directory,s\' respectively.
.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
.I background
\- [SCSI only] 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
@ -837,9 +960,9 @@ typically be either recovered or unrecoverable errors. That latter group
may need some attention. There is a description of the background scan
mechansim in section 4.18 of SBC\-3 revision 6 (see www.t10.org ).
.I scttemp, scttempsts, scttemphist [ATA]
\- [NEW EXPERIMENTAL SMARTCTL FEATURE] prints the disk temperature
information provided by the SMART Command Transport (SCT) commands.
.I scttemp, scttempsts, scttemphist
\- [ATA only] prints the disk temperature information provided by the
SMART Command Transport (SCT) commands.
The option \'scttempsts\' prints current temperature and temperature
ranges returned by the SCT Status command, \'scttemphist\' prints
temperature limits and the temperature history table returned by
@ -850,10 +973,52 @@ configured with the \'\-t scttempint,N[,p]\' option, see below.
The SCT commands are specified in the proposed ATA\-8 Command Set
(ACS), and are already implemented in some recent ATA\-7 disks.
.I sataphy[,reset]
\- [SATA only] [NEW EXPERIMENTAL SMARTCTL FEATURE] prints values
and descriptions of the SATA Phy Event Counters (General Purpose Log
address 0x11). If \'\-l sataphy,reset\' is specified, all counters
are reset after reading the values.
.I sasphy[,reset]
\- [SAS (SCSI) only] [NEW EXPERIMENTAL SMARTCTL FEATURE] prints values
and descriptions of the SAS (SSP) Protocol Specific log page (log page
0x18). If \'\-l sasphy,reset\' is specified, all counters
are reset after reading the values.
.I gplog,ADDR[,FIRST[\-LAST|+SIZE]]
\- [ATA only] [NEW EXPERIMENTAL SMARTCTL FEATURE] prints a hex dump
of any log accessible via General Purpose Logging (GPL) feature.
The log address ADDR is the hex address listed in the log directory
(see \'\-l directory\' above). The range of log sectors (pages) can
be specified by decimal values FIRST\-LAST or FIRST+SIZE. FIRST
defaults to 0, SIZE defaults to 1. LAST can be set to \'max\' to
specify the last page of the log.
.I smartlog,ADDR[,FIRST[\-LAST|+SIZE]]
\- [ATA only] [NEW EXPERIMENTAL SMARTCTL FEATURE] prints a hex dump
of any log accessible via SMART Read Log command. See
\'\-l gplog,...\' above for parameter syntax.
For example, all these commands:
.nf
smartctl \-l gplog,0x80,10-15 /dev/sda
smartctl \-l gplog,0x80,10+6 /dev/sda
smartctl \-l smartlog,0x80,10-15 /dev/sda
.fi
print pages 10-15 of log 0x80 (first host vendor specific log).
The hex dump format is compatible with the \'xxd \-r\' command.
This command:
.nf
smartctl \-l gplog,0x11 /dev/sda | grep ^0 | xxd -r >log.bin
.fi
writes a binary representation of the one sector log 0x11
(SATA Phy Event Counters) to file log.bin.
.TP
.B \-v N,OPTION, \-\-vendorattribute=N,OPTION
Sets a vendor\-specific display OPTION for Attribute N. This option
may be used multiple times. Valid arguments to this option are:
[ATA only] Sets a vendor\-specific display OPTION for Attribute N. This
option may be used multiple times. Valid arguments to this option are:
.I help
\- Prints (to STDOUT) a list of all valid arguments to this option,
@ -904,6 +1069,14 @@ with RK100\-13 firmware).
interpretation is unknown. This is primarily useful for the \-P
(presets) option.
.I 197,increasing
\- Raw Attribute number 197 (Current Pending Sector Count) is not
reset if uncorrectable sectors are reallocated.
.I 198,increasing
\- Raw Attribute number 198 (Offline Uncorrectable Sector Count) is not
reset if uncorrectable sectors are reallocated.
.I 198,offlinescanuncsectorct
\- Raw Attribute number 198 is the Offline Scan UNC Sector Count.
@ -943,8 +1116,8 @@ value for Attribute 123 in this form.
.TP
.B \-F TYPE, \-\-firmwarebug=TYPE
Modifies the behavior of \fBsmartctl\fP to compensate for some known
and understood device firmware or driver bug. Except \'swapid\',
[ATA only] Modifies the behavior of \fBsmartctl\fP to compensate for some
known and understood device firmware or driver bug. Except \'swapid\',
the arguments to this option are exclusive, so that only the final
option given is used. The valid values are:
@ -989,8 +1162,8 @@ firmware version) returned by some buggy device drivers.
.TP
.B \-P TYPE, \-\-presets=TYPE
Specifies whether \fBsmartctl\fP should use any preset options that
are available for this drive. By default, if the drive is recognized
[ATA only] Specifies whether \fBsmartctl\fP should use any preset options
that are available for this drive. By default, if the drive is recognized
in the \fBsmartmontools\fP database, then the presets are used.
\fBsmartctl\fP can automatically set appropriate options for known
@ -1048,6 +1221,43 @@ lists all entries matching MODEL, and the command:
.fi
lists all entries for this MODEL and a specific FIRMWARE version.
.TP
.B \-B [+]FILE, \-\-drivedb=[+]FILE
[ATA only] [NEW EXPERIMENTAL SMARTCTL FEATURE] Read the drive database from
FILE. The new database replaces the built in database by default. If \'+\' is
specified, then the new entries prepend the built in entries.
If this option is not specified, optional entries are read from the file
\fB/usr/local/etc/smart_drivedb.h\fP (Windows: \fB./smart_drivedb.conf\fP).
.\" BEGIN ENABLE_DRIVEDB
If \fB/usr/local/share/smartmontools/drivedb.h\fP is present, the
contents of this file is used instead of the built in table.
.\" END ENABLE_DRIVEDB
The database files use the same C/C++ syntax that is used to initialize
the built in database array. C/C++ style comments are allowed.
Example:
.nf
/* Full entry: */
{
"Model family", // Info about model family/series.
"MODEL1.*REGEX", // Regular expression to match model of device.
"VERSION.*REGEX", // Regular expression to match firmware version(s).
"Some warning", // Warning message.
"\-v 9,minutes" // String of preset \-v and \-F options.
},
/* Minimal entry: */
{
"", // No model family/series info.
"MODEL2.*REGEX", // Regular expression to match model of device.
"", // All firmware versions.
"", // No warning.
"" // No options preset.
},
/* ... */
.fi
.TP
.B SMART RUN/ABORT OFFLINE TEST AND SELF\-TEST OPTIONS:
.TP
@ -1105,7 +1315,7 @@ above. Note that this command can be given during normal
system operation (unless run in captive mode \- see the \'\-C\' option below).
.I conveyance
\- [ATA ONLY] runs a SMART Conveyance Self Test (minutes). This
\- [ATA only] runs a SMART Conveyance Self Test (minutes). This
self\-test routine is intended to identify damage incurred during
transporting of the device. This self\-test routine should take on the
order of minutes to complete. Note that this command can be given
@ -1113,13 +1323,12 @@ during normal system operation (unless run in captive mode \- see the
\'\-C\' option below).
.I select,N\-M, select,N+SIZE
\- [ATA ONLY] [EXPERIMENTAL SMARTCTL FEATURE] runs a SMART
Selective Self Test, to test a \fBrange\fP of disk Logical Block
Addresses (LBAs), rather than the entire disk. Each range of LBAs
that is checked is called a "span" and is specified by a starting LBA
(N) and an ending LBA (M) with N less than or equal to M. The range
can also be specified as N+SIZE. A span at the end of a disk can
be specified by N\-\fBmax\fP.
\- [ATA only] runs a SMART Selective Self Test, to test a \fBrange\fP
of disk Logical Block Addresses (LBAs), rather than the entire disk.
Each range of LBAs that is checked is called a "span" and is specified
by a starting LBA (N) and an ending LBA (M) with N less than or equal
to M. The range can also be specified as N+SIZE. A span at the end of
a disk can be specified by N\-\fBmax\fP.
For example the commands:
.nf
@ -1165,10 +1374,10 @@ The following variants of the selective self\-test command use spans based
on the ranges from past tests already stored on the disk:
.I select,redo[+SIZE]
\- [ATA ONLY] [NEW EXPERIMENTAL SMARTCTL FEATURE] redo the last SMART
Selective Self Test using the same LBA range. The starting LBA is identical
to the LBA used by last test, same for ending LBA unless a new span size
is specified by optional +SIZE argument.
\- [ATA only] redo the last SMART Selective Self Test using the same LBA
range. The starting LBA is identical to the LBA used by last test, same
for ending LBA unless a new span size is specified by optional +SIZE
argument.
For example the commands:
.nf
@ -1184,10 +1393,10 @@ have the same effect as:
.fi
.I select,next[+SIZE]
\- [ATA ONLY] [NEW EXPERIMENTAL SMARTCTL FEATURE] runs a SMART Selective
Self Test on the LBA range which follows the range of the last test. The
starting LBA is set to (ending LBA +1) of the last test. A new span size
may be specified by the optional +SIZE argument.
\- [ATA only] runs a SMART Selective Self Test on the LBA range which
follows the range of the last test. The starting LBA is set to (ending
LBA +1) of the last test. A new span size may be specified by the
optional +SIZE argument.
For example the commands:
.nf
@ -1208,12 +1417,12 @@ the total number of spans to check the full disk will not be changed
by future uses of \'\-t select,next\'.
.I select,cont[+SIZE]
\- [ATA ONLY] [NEW EXPERIMENTAL SMARTCTL FEATURE] performs a \'redo\'
(above) if the self test status reports that the last test was aborted
by the host. Otherwise it run the \'next\' (above) test.
\- [ATA only] performs a \'redo\' (above) if the self test status reports
that the last test was aborted by the host. Otherwise it run the \'next\'
(above) test.
.I afterselect,on
\- [ATA ONLY] perform an offline read scan after a Selective Self\-test
\- [ATA only] perform an offline read scan after a Selective Self\-test
has completed. This option must be used together with one or more of
the \fIselect,N\-M\fP options above. If the LBAs that have been
specified in the Selective self\-test pass the test with no errors
@ -1224,13 +1433,13 @@ timer (see below). The value of this option is preserved between
selective self\-tests.
.I afterselect,off
\- [ATA ONLY] do not read scan the remainder of the disk after a
\- [ATA only] do not read scan the remainder of the disk after a
Selective self\-test has completed. This option must be use together
with one or more of the \fIselect,N\-M\fP options above. The value of this
option is preserved between selective self\-tests.
.I pending,N
\- [ATA ONLY] set the pending offline read scan timer to N minutes.
\- [ATA only] set the pending offline read scan timer to N minutes.
Here N is an integer in the range from 0 to 65535 inclusive. If the
device is powered off during a read scan after a Selective self\-test,
then resume the test automatically N minutes after power\-up. This
@ -1239,13 +1448,12 @@ options above. The value of this option is preserved between selective
self\-tests.
.I scttempint,N[,p]
\- [ATA ONLY] [NEW EXPERIMENTAL SMARTCTL FEATURE] set the time interval
for SCT temperature logging to N minutes. If \',p\' is specified, the
setting is preserved across power cycles. Otherwise, the setting is
volatile and will be reverted to default (1 minute), or last
non-volatile setting by the next hard reset. This command also clears
the temperature history table. See \'\-l scttemp\' above for more
information about SCT temperature logging.
\- [ATA only] set the time interval for SCT temperature logging to N
minutes. If \',p\' is specified, the setting is preserved across power
cycles. Otherwise, the setting is volatile and will be reverted to
default (1 minute), or last non-volatile setting by the next hard reset.
This command also clears the temperature history table. See
\'\-l scttemp\' above for more information about SCT temperature logging.
.TP
.B \-C, \-\-captive
@ -1264,16 +1472,67 @@ Aborts non\-captive SMART Self Tests. Note that this
command will abort the Offline Immediate Test routine only if your
disk has the "Abort Offline collection upon new command" capability.
.PP
.SH ATA, SCSI command sets and SAT
In the past there has been a clear distinction between storage devices
that used the ATA and SCSI command sets. This distinction was often
reflected in their device naming and hardware. Now various SCSI
transports (e.g. SAS, FC and iSCSI) can interconnect to both SCSI
disks (e.g. FC and SAS) and ATA disks (especially SATA). USB and
IEEE 1394 storage devices use the SCSI command set externally but
almost always contain ATA or SATA disks (or flash). The storage
subsystems in some operating systems have started to remove the
distinction between ATA and SCSI in their device naming policies.
.PP
99% of operations that an OS performs on a disk involve the SCSI INQUIRY,
READ CAPACITY, READ and WRITE commands, or their ATA equivalents. Since
the SCSI commands are slightly more general than their ATA equivalents,
many OSes are generating SCSI commands (mainly READ and WRITE) and
letting a lower level translate them to their ATA equivalents as the
need arises. An important note here is that "lower level" may be in
external equipment and hence outside the control of an OS.
.PP
SCSI to ATA Translation (SAT) is a standard (ANSI INCITS 431-2007) that
specifies how this translation is done. For the other 1% of operations
that an OS performs on a disk, SAT provides two options. First is an
optional ATA PASS-THROUGH SCSI command (there are two variants). The
second is a translation from the closest SCSI command. Most current
interest is in the "pass-through" option.
.PP
The relevance to smartmontools (and hence smartctl) is that its
interactions with disks fall solidly into the "1%" category. So even
if the OS can happily treat (and name) a disk as "SCSI", smartmontools
needs to detect the native command set and act accordingly.
As more storage manufacturers (including external SATA drives) comply
with SAT, smartmontools is able to automatically distinguish the native
command set of the device. In some cases the '\-d sat' option is needed
on the command line.
.PP
There are also virtual disks which typically have no useful information
to convey to smartmontools, but could conceivably in the future. An
example of a virtual disk is the OS's view of a RAID 1 box. There are
most likely two SATA disks inside a RAID 1 box. Addressing those SATA
disks from a distant OS is a challenge for smartmontools. Another
approach is running a tool like smartmontools inside the RAID 1 box (e.g.
a Network Attached Storage (NAS) box) and fetching the logs via a
browser.
.PP
.SH EXAMPLES
.nf
.B smartctl \-a /dev/hda
.fi
Print all SMART information for drive /dev/hda (Primary Master).
Print a large amount of SMART information for drive /dev/hda which is
typically an ATA (IDE) or SATA disk in Linux.
.PP
.nf
.B smartctl \-a /dev/sdb
.fi
Print a large amount of SMART information for drive /dev/sda . This may
be a SCSI disk or an ATA (SATA) disk.
.PP
.nf
.B smartctl \-s off /dev/hdd
.fi
Disable SMART on drive /dev/hdd (Secondary Slave).
Disable SMART monitoring and data log collection on drive /dev/hdd .
.PP
.nf
.B smartctl \-\-smart=on \-\-offlineauto=on \-\-saveauto=on /dev/hda
@ -1346,14 +1605,22 @@ 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
.B smartctl \-t long \-d areca,4 /dev/sg2
.fi
Start a long self\-test on the fourth SATA disk connected to an Areca RAID
controller addressed by /dev/sg2.
.PP
.nf
.B smartctl \-a \-d hpt,1/3 /dev/sda (under Linux)
.B smartctl \-a \-d hpt,1/3 /dev/hptrr (under FreeBSD)
.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
.B smartctl \-t short \-d hpt,1/1/2 /dev/sda (under Linux)
.B smartctl \-t short \-d hpt,1/1/2 /dev/hptrr (under FreeBSD)
.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.
@ -1438,18 +1705,20 @@ University of Wisconsin \- Milwaukee Physics Department
The following have made large contributions to smartmontools:
.nf
\fBCasper Dik\fP (Solaris SCSI interface)
\fBChristian Franke\fP (Windows interface and Cygwin package)
\fBChristian Franke\fP (Windows interface, C++ redesign, USB support, ...)
\fBDouglas Gilbert\fP (SCSI subsystem)
\fBGuido Guenther\fP (Autoconf/Automake packaging)
\fBGeoffrey Keating\fP (Darwin ATA interface)
\fBEduard Martinescu\fP (FreeBSD interface)
\fBFr\*'ed\*'eric L. W. Meunier\fP (Web site and Mailing list)
\fBGabriele Pohl\fP (Web site and Wiki, conversion from CVS to SVN)
\fBKeiji Sawada\fP (Solaris ATA interface)
\fBManfred Schwarb\fP (Drive database)
\fBSergey Svishchev\fP (NetBSD interface)
\fBDavid Snyder and Sergey Svishchev\fP (OpenBSD interface)
\fBPhil Williams\fP (User interface and drive database)
\fBYuri Dario\fP (OS/2, eComStation interface)
\fBShengfeng Zhou\fP (Linux Highpoint RocketRaid interface)
\fBShengfeng Zhou\fP (Linux/FreeBSD HighPoint RocketRAID interface)
.fi
Many other individuals have made smaller contributions and corrections.
@ -1499,8 +1768,8 @@ these documents may be found in the References section of the
\fBhttp://smartmontools.sourceforge.net/\fP .
.SH
CVS ID OF THIS PAGE:
$Id: smartctl.8.in,v 1.105 2008/03/04 22:09:47 ballen4705 Exp $
SVN ID OF THIS PAGE:
$Id: smartctl.8.in 2855 2009-07-21 19:55:08Z chrfranke $
.\" Local Variables:
.\" mode: nroff
.\" End:

File diff suppressed because it is too large Load Diff

View File

@ -3,7 +3,7 @@
*
* Home page of code is: http://smartmontools.sourceforge.net
*
* Copyright (C) 2002-8 Bruce Allen <smartmontools-support@lists.sourceforge.net>
* Copyright (C) 2002-9 Bruce Allen <smartmontools-support@lists.sourceforge.net>
* Copyright (C) 2000 Michael Cornwell <cornwell@acm.org>
*
* This program is free software; you can redistribute it and/or modify
@ -25,11 +25,7 @@
#ifndef SMARTCTL_H_
#define SMARTCTL_H_
#define SMARTCTL_H_CVSID "$Id: smartctl.h,v 1.25 2008/03/04 22:09:47 ballen4705 Exp $\n"
/* Boolean Values */
#define TRUE 0x01
#define FALSE 0x00
#define SMARTCTL_H_CVSID "$Id: smartctl.h,v 1.27 2009/06/20 19:11:04 chrfranke Exp $\n"
// Return codes (bitmask)
@ -72,6 +68,7 @@
#define OPTIONAL_CMD 1
#define MANDATORY_CMD 2
void print_smartctl_examples();
// Moved to C++ interface
//void print_smartctl_examples();
#endif

View File

@ -1,7 +1,7 @@
.ig
Copyright (C) 2002-8 Bruce Allen <smartmontools-support@lists.sourceforge.net>
$Id: smartd.8.in,v 1.121 2008/03/04 22:09:47 ballen4705 Exp $
$Id: smartd.8.in 2870 2009-08-02 20:38:30Z manfred99 $
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
@ -128,9 +128,40 @@ below).
OPTIONS
Long options are not supported on all systems. Use \fB\'smartd
\-h\'\fP to see the available options.
.TP
.B \-A PREFIX, \-\-attributelog=PREFIX
[NEW EXPERIMENTAL SMARTD FEATURE] [ATA ONLY]
Writes \fBsmartd\fP attribute information (normalized and raw attribute values)
to files \'PREFIX\'\'MODEL\-SERIAL.ata.csv\'. At each check cycle attributes
are logged as a line of semicolon separated triplets of the form
"attribute-ID;attribute-norm-value;attribute-raw-value;". Each line is
led by a date string of the form "yyyy-mm-dd HH:MM:SS" (in UTC).
.\" BEGIN ENABLE_ATTRIBUTELOG
If this option is not specified, attribute information is written to files
\'/usr/local/var/lib/smartmontools/attrlog.MODEL\-SERIAL.ata.csv\'.
To disable attribute log files, specify this option with an empty string
argument: \'-A ""\'.
.\" END ENABLE_ATTRIBUTELOG
MODEL and SERIAL are build from drive identify information, invalid
characters are replaced by underline.
If the PREFIX has the form \'/path/dir/\' (e.g. \'/var/lib/smartd/\'), then
files \'MODEL\-SERIAL.ata.csv\' are created in directory \'/path/dir\'.
If the PREFIX has the form \'/path/name\' (e.g. \'/var/lib/misc/attrlog\-\'),
then files 'nameMODEL\-SERIAL.ata.csv' are created in directory '/path/'.
The path must be absolute, except if debug mode is enabled.
.TP
.B \-B [+]FILE, \-\-drivedb=[+]FILE
[NEW EXPERIMENTAL SMARTD FEATURE] Read the drive database from FILE.
The new database replaces the built in database by default. If \'+\' is
specified, then the new entries prepend the built in entries.
Please see the \fBsmartctl\fP man page for further details.
.TP
.B \-c FILE, \-\-configfile=FILE
Read \fBsmartd\fP configuration Directives from FILE, instead of from
the default location \fB/usr/local/etc/smartd.conf\fP (Windows: \fB./smartd.conf\fP).
If FILE does \fBnot\fP exist, then \fBsmartd\fP will print an error
@ -168,6 +199,7 @@ appear in the configuration file following the device name.
.TP
.B \-h, \-\-help, \-\-usage
Prints usage message to STDOUT and exits.
.TP
.B \-i N, \-\-interval=N
Sets the interval between disk checks to \fIN\fP seconds, where
@ -353,6 +385,36 @@ comma then the integer with no spaces. For example, \fIataioctl,2\fP
The default level is 1, so \'\-r ataioctl,1\' and \'\-r ataioctl\' are
equivalent.
.TP
.B \-s PREFIX, \-\-savestates=PREFIX
[NEW EXPERIMENTAL SMARTD FEATURE] [ATA ONLY]
Reads/writes \fBsmartd\fP state information from/to files
\'PREFIX\'\'MODEL\-SERIAL.ata.state\'. This preserves SMART attributes, drive
min and max temperatures (\-W directive), info about last sent warning email
(\-m directive), and the time of next check of the self-test REGEXP
(\-s directive) across boot cycles.
.\" BEGIN ENABLE_SAVESTATES
If this option is not specified, state information is maintained in files
\'/usr/local/var/lib/smartmontools/smartd.MODEL\-SERIAL.ata.state\'.
To disable state files, specify this option with an empty string
argument: \'-s ""\'.
.\" END ENABLE_SAVESTATES
MODEL and SERIAL are build from drive identify information, invalid
characters are replaced by underline.
If the PREFIX has the form \'/path/dir/\' (e.g. \'/var/lib/smartd/\'), then
files \'MODEL\-SERIAL.ata.state\' are created in directory \'/path/dir\'.
If the PREFIX has the form \'/path/name\' (e.g. \'/var/lib/misc/smartd\-\'),
then files 'nameMODEL\-SERIAL.ata.state' are created in directory '/path/'.
The path must be absolute, except if debug mode is enabled.
The state information files are read on smartd startup. The files are
always (re)written after reading the configuration file, before rereading
the configuration file (SIGHUP), before smartd shutdown, and after a check
forced by SIGUSR1. After a normal check cycle, a file is only rewritten if
an important change (which usually results in a SYSLOG output) occurred.
.TP
.B \-\-service
Cygwin and Windows only: Enables \fBsmartd\fP to run as a Windows service.
@ -367,10 +429,9 @@ See NOTES below for details.
.TP
.B \-V, \-\-version, \-\-license, \-\-copyright
Prints license, copyright, and CVS version information onto
STDOUT and then exits. Please include this information if you are
reporting bugs, or have specific questions about the behavior of
\fBsmartd\fP.
Prints version, copyright, license, home page and SVN revision
information for your copy of \fBsmartd\fP to STDOUT and then exits.
Please include this information if you are reporting bugs or problems.
.SH EXAMPLES
@ -497,10 +558,11 @@ Section below!
.B # /usr/local/etc/smartd.conf for monitoring three
.B # ATA disks, three SCSI disks, six ATA disks
.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 # directly connected to the HighPoint Rocket-
.B # RAID controller, two SATA disks connected to
.B # the HighPoint RocketRAID controller via a pmport
.B # device, four SATA disks connected to an Areca
.B # RAID controller, and one SATA disk.
.B #
.nf
.B # First ATA disk on two different interfaces. On
@ -532,6 +594,15 @@ Section below!
.B \ \ /dev/sda -a -d sat
.B #
.nf
.B # Three disks connected to a MegaRAID controller
.B # Start short self-tests daily between 1-2, 2-3, and
.B # 3-4 am.
.B \ \ /dev/sda -d megaraid,0 -a -s S/../.././01
.B \ \ /dev/sda -d megaraid,1 -a -s S/../.././02
.B \ \ /dev/sda -d megaraid,2 -a -s S/../.././03
.B
.B #
.nf
.B # Four ATA disks on a 3ware 6/7/8000 controller.
.B # Start short self-tests daily between midnight and 1am,
.B # 1-2, 2-3, and 3-4 am. Starting with the Linux 2.6
@ -551,19 +622,36 @@ 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 # 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 # under Linux
.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 # or under FreeBSD
.B # /dev/hptrr -d hpt,1/1 -a -s S/../.././01
.B # /dev/hptrr -d hpt,1/2 -a -s S/../.././02
.B # /dev/hptrr -d hpt,1/3 -a -s S/../.././03
.B #
.nf
.B # Two SATA disks connected to a highpoint rocketraid
.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 # under Linux
.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 # or under FreeBSD
.B # /dev/hptrr -d hpt,1/4/1 -a -s L/../../7/00
.B # /dev/hptrr -d hpt,1/4/2 -a -s L/../../7/02
.B #
.nf
.B # Three SATA disks connected to an Areca
.B # RAID controller. Start long self-tests Sundays
.B # between midnight and 3 am.
.B \ \ /dev/sg2 -d areca,1 -a -s L/../../7/00
.B \ \ /dev/sg2 -d areca,2 -a -s L/../../7/01
.B \ \ /dev/sg2 -d areca,3 -a -s L/../../7/02
.B #
.nf
.B # The following line enables monitoring of the
@ -630,12 +718,22 @@ or /dev/twa?) must be listed, along with the \'\-d 3ware,N\' Directive
appear to \fBsmartd\fP as normal ATA devices. Hence all the ATA
directives can be used for these disks (but see note below).
.B If an Areca controller is used
then the corresponding SCSI generic device (/dev/sg?) must be listed,
along with the \'\-d areca,N\' Directive (see below). The individual
SATA disks hosted by the Areca controller appear to \fBsmartd\fP as
normal ATA devices. Hence all the ATA directives can be used for
these disks. Areca firmware version 1.46 or later which supports
smartmontools must be used; Please see the \fBsmartctl\fP man page for
further details.
.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, \fIsat\fP,
\fImarvell\fP, \fIcciss,N\fP and \fI3ware,N\fP are mutually-exclusive. If more
than one is given then \fBsmartd\fP will use the last one which appears.
times for one device, but the arguments \fIata\fP, \fIscsi\fP,
\fIsat\fP, \fImarvell\fP, \fIcciss,N\fP, \fIareca,N\fP, \fImegaraid,N\fP
and \fI3ware,N\fP are mutually-exclusive. If more than one is given then
\fBsmartd\fP will use the last one which appears.
If none of these three arguments is given, then \fBsmartd\fP will
first attempt to guess the device type by looking at whether the sixth
@ -674,12 +772,19 @@ be overridden with this syntax: \'\-d sat,12\' or \'\-d sat,16\'.
\- Under Linux, interact with SATA disks behind Marvell chip-set
controllers (using the Marvell rather than libata driver).
.I megaraid,N
\- the device consists of one or more SCSI/SAS/SATA disks connected
to a MegaRAID controller. The non-negative integer N (in the range
of 0 to 127 inclusive) denotes which disk on the controller is monitored.
In log files and email messages this disk will be identified as
megaraid_disk_XXX with XXX in the range from 000 to 127 inclusive.
.I 3ware,N
\- the device consists of one or more ATA disks connected to a 3ware
RAID controller. The non-negative integer N (in the range from 0 to 31
RAID controller. The non-negative integer N (in the range from 0 to 127
inclusive) denotes which disk on the controller is monitored. In log
files and email messages this disk will be identified as 3ware_disk_XX
with XX in the range from 00 to 31 inclusive.
files and email messages this disk will be identified as 3ware_disk_XXX
with XXX in the range from 000 to 127 inclusive.
This Directive may at first appear confusing, because the 3ware
controller is a SCSI device (such as /dev/sda) and should be listed as
@ -714,6 +819,13 @@ Alternatively use the character device interfaces /dev/twe0-15 (3ware
6/7/8000 series controllers) or /dev/twa0-15 (3ware 9000 series
controllers).
.I areca,N
\- the device consists of one or more SATA disks connected to an Areca
SATA RAID controller. The positive integer N (in the range from 1 to
24 inclusive) denotes which disk on the controller is monitored. In
log files and email messages this disk will be identifed as
areca_disk_XX with XX in the range from 01 to 24 inclusive.
.I cciss,N
\- the device consists of one or more SCSI disks connected to a cciss
RAID controller. The non-negative integer N (in the range from 0 to 15
@ -721,7 +833,7 @@ inclusive) denotes which disk on the controller is monitored. In log
files and email messages this disk will be identified as cciss_disk_XX
with XX in the range from 00 to 15 inclusive.
.B 3ware and cciss controllers are currently ONLY supported under Linux.
.B 3ware, MegaRAID, Areca and cciss 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
@ -734,7 +846,7 @@ 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.
.B HighPoint RocketRAID controllers are currently ONLY supported under Linux and FreeBSD.
.I removable
\- the device or its media is removable. This indicates to
@ -745,7 +857,7 @@ behavior) if the device does not appear to be present when
with the other \'\-d\' Directives.
.TP
.B \-n POWERMODE[,q]
.B \-n POWERMODE[,N][,q]
This \'nocheck\' Directive is used to prevent a disk from being
spun-up when it is periodically polled by \fBsmartd\fP.
@ -790,14 +902,18 @@ 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.
Maximum number of skipped checks (in a row) can be specified by
appending positive number \',N\' to POWERMODE (like \'\-n standby,15\').
After N checks are skipped in a row, powermode is ignored and the
check is performed anyway.
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\').
This prevents a laptop disk from spinning up due to this message.
Both \',N\' and \',q\' can be specified together.
.TP
.B \-T TYPE
Specifies how tolerant
@ -886,6 +1002,15 @@ match (in turn) are: \'L\' for a \fBL\fPong Self-Test, \'S\' for a
only), and \'O\' for an \fBO\fPffline Immediate Test (ATA only). As
soon as a match is found, the test will be started and no additional
matches will be sought for that device and that polling cycle.
[NEW EXPERIMENTAL SMARTD FEATURE] To run scheduled Selective
Self-Tests, use \'n\' for \fBn\fPext span, \'r\' to \fBr\fPedo last
span, or \'c\' to \fBc\fPontinue with next span or redo last span
based on status of last test. The LBA range is based on the first
span from the last test.
See the \fBsmartctl \-t select,[next|redo|cont]\fP options for
further info.
.IP \fBMM\fP 4
is the month of the year, expressed with two decimal digits. The
range is from 01 (January) to 12 (December) inclusive. Do \fBnot\fP
@ -931,6 +1056,19 @@ Self-Test every Saturday at 3-4am, use:
.nf
\fB \-s (O/../.././(00|06|12|18)|S/../.././01|L/../../6/03)\fP
.fi
If Long Self-Tests of a large disks take longer than the system uptime,
a full disk test can be performed by several Selective Self-Tests.
To setup a full test of a 1TB disk within 20 days (one 50GB span
each day), run this command once:
.nf
smartctl -t select,0-99999999 /dev/sda
.fi
To run the next test spans on Monday-Friday between 12-13am, run smartd
with this directive:
.nf
\fB \-s n/../../[1-5]/12\fP
.fi
Scheduled tests are run immediately following the regularly-scheduled
device polling, if the current local date, time, and test type, match
@ -938,8 +1076,8 @@ device polling, if the current local date, time, and test type, match
occurs every thirty minutes after starting \fBsmartd\fP. Take caution
if you use the \'\-i\' option to make this polling interval more than
sixty minutes: the poll times may fail to coincide with any of the
testing times that you have specified with \fBREGEXP\fP, and so the
self tests may not take place as you wish.
testing times that you have specified with \fBREGEXP\fP. In this case
the test will be run following the next device polling.
Before running an offline or self-test, \fBsmartd\fP checks to be sure
that a self-test is not already running. If a self-test \fBis\fP
@ -960,6 +1098,16 @@ that you constructed \fBREGEXP\fP correctly. The matching order
if multiple test types are all scheduled for the same hour, the
longer test type has precedence. This is usually the desired behavior.
If the scheduled tests are used in conjunction with state persistence
(\'\-s\' option), smartd will also try to match the hours since last
shutdown (or 90 days at most). If any test would have been started
during downtime, the longest (see above) of these tests is run after
second device polling.
If the \'\-n\' directive is used and any test would have been started
during disk standby time, the longest of these tests is run when the
disk is active again.
Unix users: please beware that the rules for extended regular
expressions [regex(7)] are \fBnot\fP the same as the rules for
file\-name pattern matching by the shell [glob(7)]. \fBsmartd\fP will
@ -1110,17 +1258,19 @@ 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, hpt,L/M/N).
Here N=0,...,23 denotes the ATA disk behind a 3ware RAID controller and
L/M/N denotes the SATA disk behind a HighPoint RocketRAID controller.
is set to the device type (possible values: ata, scsi, 3ware,N,
areca,N, hpt,L/M/N). Here N=0,...,127 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]\'. 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.
the form used is \'/dev/sdc [3ware_disk_01]\'. For HighPoint
RocketRAID controller, the form is \'/dev/sdd [hpt_1/1/1]\' under Linux
or \'/dev/hptrr [hpt_1/1/1]\' under FreeBSD. For Areca controllers, the
form is \'/dev/sg2 [areca_disk_09]\'. 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
gives the reason for the warning or message email. The possible values that
it takes and their meanings are:
@ -1289,7 +1439,7 @@ temperature (usually Attribute 194 or 231). It\'s annoying to get reports
each time the temperature changes. This Directive may appear multiple
times for a single device, if you want to ignore multiple Attributes.
.TP
.B \-r ID
.B \-r ID[!]
When tracking, report the \fIRaw\fP value of Attribute \fBID\fP along
with its (normally reported) \fINormalized\fP value. \fBID\fP must be
a decimal integer in the range from 1 to 255. This Directive modifies
@ -1300,8 +1450,12 @@ multiple times.
A common use of this Directive is to track the device Temperature
(often ID=194 or 231).
If the optional flag \'!\' is appended, a change of the Normalized
value is considered critical. The report will be logged as LOG_CRIT
and a warning email will be sent if \'-m\' is specified.
.TP
.B \-R ID
.B \-R ID[!]
When tracking, report whenever the \fIRaw\fP value of Attribute
\fBID\fP changes. (Normally \fBsmartd\fP only tracks/reports changes
of the \fINormalized\fP Attribute values.) \fBID\fP must be a decimal
@ -1319,8 +1473,13 @@ A common use of this Directive is to track the device Temperature
different types of system behavior affects the values of certain
Attributes.
If the optional flag \'!\' is appended, a change of the Raw
value is considered critical. The report will be logged as
LOG_CRIT and a warning email will be sent if \'-m\' is specified.
An example is \'-R 5!\' to warn when new sectors are reallocated.
.TP
.B \-C ID
.B \-C ID[+]
[ATA only] Report if the current number of pending sectors is
non-zero. Here \fBID\fP is the id number of the Attribute whose raw
value is the Current Pending Sector count. The allowed range of
@ -1329,6 +1488,11 @@ ID\ =\ 0. If the \fB\-C ID\fP option is not given, then it defaults to
\fB\-C 197\fP (since Attribute 197 is generally used to monitor
pending sectors).
If \'+\' is specified, a report is only printed if the number of sectors
has increased between two check cycles. Some disks do not reset this
attribute when a bad sector is reallocated.
See also \'\-v 197,increasing\' below.
A pending sector is a disk sector (containing 512 bytes of your data)
which the device would like to mark as ``bad" and reallocate.
Typically this is because your computer tried to read that sector, and
@ -1342,7 +1506,7 @@ device substitute a spare good sector for the bad one) but at the
price of losing the 512 bytes of data stored there.
.TP
.B \-U ID
.B \-U ID[+]
[ATA only] Report if the number of offline uncorrectable sectors is
non-zero. Here \fBID\fP is the id number of the Attribute whose raw
value is the Offline Uncorrectable Sector count. The allowed range of
@ -1351,6 +1515,10 @@ ID\ =\ 0. If the \fB\-U ID\fP option is not given, then it defaults to
\fB\-U 198\fP (since Attribute 198 is generally used to monitor
offline uncorrectable sectors).
If \'+\' is specified, a report is only printed if the number of sectors
has increased since the last check cycle. Some disks do not reset this
attribute when a bad sector is reallocated.
See also \'\-v 198,increasing\' below.
An offline uncorrectable sector is a disk sector which was not
readable during an off\-line scan or a self\-test. This is important
@ -1361,13 +1529,19 @@ 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
degrees since last report, or if new min or max temperature is detected.
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.
If this directive is used in conjunction with state persistence
(\'\-s\' option), the min and max temperature values are preserved
across boot cycles. The minimum temperature value is not updated
during the first 30 minutes after startup.
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\').
@ -1486,6 +1660,16 @@ with RK100-13 firmware).
interpretation is unknown. This is primarily useful for the -P
(presets) Directive.
.I 197,increasing
\- Raw Attribute number 197 (Current Pending Sector Count) is not
reset if uncorrectable sectors are reallocated. This also sets
\'-C 197+\' if no other \'-C\' directive is specified.
.I 198,increasing
\- Raw Attribute number 198 (Offline Uncorrectable Sector Count) is not
reset if uncorrectable sector are reallocated. This also sets
\'-U 198+\' if no other \'-U\' directive is specified.
.I 198,offlinescanuncsectorct
\- Raw Attribute number 198 is the Offline Scan UNC Sector Count.
@ -1904,17 +2088,19 @@ University of Wisconsin \- Milwaukee Physics Department
The following have made large contributions to smartmontools:
.nf
\fBCasper Dik\fP (Solaris SCSI interface)
\fBChristian Franke\fP (Windows interface and Cygwin package)
\fBChristian Franke\fP (Windows interface, C++ redesign, USB support, ...)
\fBDouglas Gilbert\fP (SCSI subsystem)
\fBGuido Guenther\fP (Autoconf/Automake packaging)
\fBGeoffrey Keating\fP (Darwin ATA interface)
\fBEduard Martinescu\fP (FreeBSD interface)
\fBFr\*'ed\*'eric L. W. Meunier\fP (Web site and Mailing list)
\fBGabriele Pohl\fP (Web site and Wiki, conversion from CVS to SVN)
\fBKeiji Sawada\fP (Solaris ATA interface)
\fBManfred Schwarb\fP (Drive database)
\fBSergey Svishchev\fP (NetBSD interface)
\fBDavid Snyder and Sergey Svishchev\fP (OpenBSD interface)
\fBPhil Williams\fP (User interface and drive database)
\fBShengfeng Zhou\fP (Linux Highpoint RocketRaid interface)
\fBShengfeng Zhou\fP (Linux/FreeBSD HighPoint RocketRAID interface)
.fi
Many other individuals have made smaller contributions and corrections.
@ -1964,5 +2150,5 @@ these documents may be found in the References section of the
smartmontools home page at \fBhttp://smartmontools.sourceforge.net/#references\fP .
.SH
CVS ID OF THIS PAGE:
$Id: smartd.8.in,v 1.121 2008/03/04 22:09:47 ballen4705 Exp $
SVN ID OF THIS PAGE:
$Id: smartd.8.in 2870 2009-08-02 20:38:30Z manfred99 $

View File

@ -1,7 +1,7 @@
.ig
Copyright (C) 2002-8 Bruce Allen <smartmontools-support@lists.sourceforge.net>
$Id: smartd.conf.5.in,v 1.87 2008/03/04 22:09:47 ballen4705 Exp $
$Id: smartd.conf.5.in 2847 2009-07-18 14:58:44Z chrfranke $
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
@ -119,10 +119,11 @@ Section below!
.B # /usr/local/etc/smartd.conf for monitoring three
.B # ATA disks, three SCSI disks, six ATA disks
.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 # directly connected to the HighPoint Rocket-
.B # RAID controller, two SATA disks connected to
.B # the HighPoint RocketRAID controller via a pmport
.B # device, four SATA disks connected to an Areca
.B # RAID controller, and one SATA disk.
.B #
.nf
.B # First ATA disk on two different interfaces. On
@ -154,6 +155,15 @@ Section below!
.B \ \ /dev/sda -a -d sat
.B #
.nf
.B # Three disks connected to a MegaRAID controller
.B # Start short self-tests daily between 1-2, 2-3, and
.B # 3-4 am.
.B \ \ /dev/sda -d megaraid,0 -a -s S/../.././01
.B \ \ /dev/sda -d megaraid,1 -a -s S/../.././02
.B \ \ /dev/sda -d megaraid,2 -a -s S/../.././03
.B
.B #
.nf
.B # Four ATA disks on a 3ware 6/7/8000 controller.
.B # Start short self-tests daily between midnight and 1am,
.B # 1-2, 2-3, and 3-4 am. Starting with the Linux 2.6
@ -173,19 +183,36 @@ 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 # 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 # under Linux
.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 # or under FreeBSD
.B # /dev/hptrr -d hpt,1/1 -a -s S/../.././01
.B # /dev/hptrr -d hpt,1/2 -a -s S/../.././02
.B # /dev/hptrr -d hpt,1/3 -a -s S/../.././03
.B #
.nf
.B # Two SATA disks connected to a highpoint rocketraid
.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 # under Linux
.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 # or under FreeBSD
.B # /dev/hptrr -d hpt,1/4/1 -a -s L/../../7/00
.B # /dev/hptrr -d hpt,1/4/2 -a -s L/../../7/02
.B #
.nf
.B # Three SATA disks connected to an Areca
.B # RAID controller. Start long self-tests Sundays
.B # between midnight and 3 am.
.B \ \ /dev/sg2 -d areca,1 -a -s L/../../7/00
.B \ \ /dev/sg2 -d areca,2 -a -s L/../../7/01
.B \ \ /dev/sg2 -d areca,3 -a -s L/../../7/02
.B #
.nf
.B # The following line enables monitoring of the
@ -252,12 +279,22 @@ or /dev/twa?) must be listed, along with the \'\-d 3ware,N\' Directive
appear to \fBsmartd\fP as normal ATA devices. Hence all the ATA
directives can be used for these disks (but see note below).
.B If an Areca controller is used
then the corresponding SCSI generic device (/dev/sg?) must be listed,
along with the \'\-d areca,N\' Directive (see below). The individual
SATA disks hosted by the Areca controller appear to \fBsmartd\fP as
normal ATA devices. Hence all the ATA directives can be used for
these disks. Areca firmware version 1.46 or later which supports
smartmontools must be used; Please see the \fBsmartctl\fP man page for
further details.
.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, \fIsat\fP,
\fImarvell\fP, \fIcciss,N\fP and \fI3ware,N\fP are mutually-exclusive. If more
than one is given then \fBsmartd\fP will use the last one which appears.
times for one device, but the arguments \fIata\fP, \fIscsi\fP,
\fIsat\fP, \fImarvell\fP, \fIcciss,N\fP, \fIareca,N\fP, \fImegaraid,N\fP
and \fI3ware,N\fP are mutually-exclusive. If more than one is given then
\fBsmartd\fP will use the last one which appears.
If none of these three arguments is given, then \fBsmartd\fP will
first attempt to guess the device type by looking at whether the sixth
@ -296,12 +333,19 @@ be overridden with this syntax: \'\-d sat,12\' or \'\-d sat,16\'.
\- Under Linux, interact with SATA disks behind Marvell chip-set
controllers (using the Marvell rather than libata driver).
.I megaraid,N
\- the device consists of one or more SCSI/SAS/SATA disks connected
to a MegaRAID controller. The non-negative integer N (in the range
of 0 to 127 inclusive) denotes which disk on the controller is monitored.
In log files and email messages this disk will be identified as
megaraid_disk_XXX with XXX in the range from 000 to 127 inclusive.
.I 3ware,N
\- the device consists of one or more ATA disks connected to a 3ware
RAID controller. The non-negative integer N (in the range from 0 to 31
RAID controller. The non-negative integer N (in the range from 0 to 127
inclusive) denotes which disk on the controller is monitored. In log
files and email messages this disk will be identified as 3ware_disk_XX
with XX in the range from 00 to 31 inclusive.
files and email messages this disk will be identified as 3ware_disk_XXX
with XXX in the range from 000 to 127 inclusive.
This Directive may at first appear confusing, because the 3ware
controller is a SCSI device (such as /dev/sda) and should be listed as
@ -336,6 +380,13 @@ Alternatively use the character device interfaces /dev/twe0-15 (3ware
6/7/8000 series controllers) or /dev/twa0-15 (3ware 9000 series
controllers).
.I areca,N
\- the device consists of one or more SATA disks connected to an Areca
SATA RAID controller. The positive integer N (in the range from 1 to
24 inclusive) denotes which disk on the controller is monitored. In
log files and email messages this disk will be identifed as
areca_disk_XX with XX in the range from 01 to 24 inclusive.
.I cciss,N
\- the device consists of one or more SCSI disks connected to a cciss
RAID controller. The non-negative integer N (in the range from 0 to 15
@ -343,7 +394,7 @@ inclusive) denotes which disk on the controller is monitored. In log
files and email messages this disk will be identified as cciss_disk_XX
with XX in the range from 00 to 15 inclusive.
.B 3ware and cciss controllers are currently ONLY supported under Linux.
.B 3ware, MegaRAID, Areca and cciss 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
@ -356,7 +407,7 @@ 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.
.B HighPoint RocketRAID controllers are currently ONLY supported under Linux and FreeBSD.
.I removable
\- the device or its media is removable. This indicates to
@ -367,7 +418,7 @@ behavior) if the device does not appear to be present when
with the other \'\-d\' Directives.
.TP
.B \-n POWERMODE[,q]
.B \-n POWERMODE[,N][,q]
This \'nocheck\' Directive is used to prevent a disk from being
spun-up when it is periodically polled by \fBsmartd\fP.
@ -412,14 +463,18 @@ 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.
Maximum number of skipped checks (in a row) can be specified by
appending positive number \',N\' to POWERMODE (like \'\-n standby,15\').
After N checks are skipped in a row, powermode is ignored and the
check is performed anyway.
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\').
This prevents a laptop disk from spinning up due to this message.
Both \',N\' and \',q\' can be specified together.
.TP
.B \-T TYPE
Specifies how tolerant
@ -508,6 +563,15 @@ match (in turn) are: \'L\' for a \fBL\fPong Self-Test, \'S\' for a
only), and \'O\' for an \fBO\fPffline Immediate Test (ATA only). As
soon as a match is found, the test will be started and no additional
matches will be sought for that device and that polling cycle.
[NEW EXPERIMENTAL SMARTD FEATURE] To run scheduled Selective
Self-Tests, use \'n\' for \fBn\fPext span, \'r\' to \fBr\fPedo last
span, or \'c\' to \fBc\fPontinue with next span or redo last span
based on status of last test. The LBA range is based on the first
span from the last test.
See the \fBsmartctl \-t select,[next|redo|cont]\fP options for
further info.
.IP \fBMM\fP 4
is the month of the year, expressed with two decimal digits. The
range is from 01 (January) to 12 (December) inclusive. Do \fBnot\fP
@ -553,6 +617,19 @@ Self-Test every Saturday at 3-4am, use:
.nf
\fB \-s (O/../.././(00|06|12|18)|S/../.././01|L/../../6/03)\fP
.fi
If Long Self-Tests of a large disks take longer than the system uptime,
a full disk test can be performed by several Selective Self-Tests.
To setup a full test of a 1TB disk within 20 days (one 50GB span
each day), run this command once:
.nf
smartctl -t select,0-99999999 /dev/sda
.fi
To run the next test spans on Monday-Friday between 12-13am, run smartd
with this directive:
.nf
\fB \-s n/../../[1-5]/12\fP
.fi
Scheduled tests are run immediately following the regularly-scheduled
device polling, if the current local date, time, and test type, match
@ -560,8 +637,8 @@ device polling, if the current local date, time, and test type, match
occurs every thirty minutes after starting \fBsmartd\fP. Take caution
if you use the \'\-i\' option to make this polling interval more than
sixty minutes: the poll times may fail to coincide with any of the
testing times that you have specified with \fBREGEXP\fP, and so the
self tests may not take place as you wish.
testing times that you have specified with \fBREGEXP\fP. In this case
the test will be run following the next device polling.
Before running an offline or self-test, \fBsmartd\fP checks to be sure
that a self-test is not already running. If a self-test \fBis\fP
@ -582,6 +659,16 @@ that you constructed \fBREGEXP\fP correctly. The matching order
if multiple test types are all scheduled for the same hour, the
longer test type has precedence. This is usually the desired behavior.
If the scheduled tests are used in conjunction with state persistence
(\'\-s\' option), smartd will also try to match the hours since last
shutdown (or 90 days at most). If any test would have been started
during downtime, the longest (see above) of these tests is run after
second device polling.
If the \'\-n\' directive is used and any test would have been started
during disk standby time, the longest of these tests is run when the
disk is active again.
Unix users: please beware that the rules for extended regular
expressions [regex(7)] are \fBnot\fP the same as the rules for
file\-name pattern matching by the shell [glob(7)]. \fBsmartd\fP will
@ -732,17 +819,19 @@ 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, hpt,L/M/N).
Here N=0,...,23 denotes the ATA disk behind a 3ware RAID controller and
L/M/N denotes the SATA disk behind a HighPoint RocketRAID controller.
is set to the device type (possible values: ata, scsi, 3ware,N,
areca,N, hpt,L/M/N). Here N=0,...,127 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]\'. 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.
the form used is \'/dev/sdc [3ware_disk_01]\'. For HighPoint
RocketRAID controller, the form is \'/dev/sdd [hpt_1/1/1]\' under Linux
or \'/dev/hptrr [hpt_1/1/1]\' under FreeBSD. For Areca controllers, the
form is \'/dev/sg2 [areca_disk_09]\'. 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
gives the reason for the warning or message email. The possible values that
it takes and their meanings are:
@ -911,7 +1000,7 @@ temperature (usually Attribute 194 or 231). It\'s annoying to get reports
each time the temperature changes. This Directive may appear multiple
times for a single device, if you want to ignore multiple Attributes.
.TP
.B \-r ID
.B \-r ID[!]
When tracking, report the \fIRaw\fP value of Attribute \fBID\fP along
with its (normally reported) \fINormalized\fP value. \fBID\fP must be
a decimal integer in the range from 1 to 255. This Directive modifies
@ -922,8 +1011,12 @@ multiple times.
A common use of this Directive is to track the device Temperature
(often ID=194 or 231).
If the optional flag \'!\' is appended, a change of the Normalized
value is considered critical. The report will be logged as LOG_CRIT
and a warning email will be sent if \'-m\' is specified.
.TP
.B \-R ID
.B \-R ID[!]
When tracking, report whenever the \fIRaw\fP value of Attribute
\fBID\fP changes. (Normally \fBsmartd\fP only tracks/reports changes
of the \fINormalized\fP Attribute values.) \fBID\fP must be a decimal
@ -941,8 +1034,13 @@ A common use of this Directive is to track the device Temperature
different types of system behavior affects the values of certain
Attributes.
If the optional flag \'!\' is appended, a change of the Raw
value is considered critical. The report will be logged as
LOG_CRIT and a warning email will be sent if \'-m\' is specified.
An example is \'-R 5!\' to warn when new sectors are reallocated.
.TP
.B \-C ID
.B \-C ID[+]
[ATA only] Report if the current number of pending sectors is
non-zero. Here \fBID\fP is the id number of the Attribute whose raw
value is the Current Pending Sector count. The allowed range of
@ -951,6 +1049,11 @@ ID\ =\ 0. If the \fB\-C ID\fP option is not given, then it defaults to
\fB\-C 197\fP (since Attribute 197 is generally used to monitor
pending sectors).
If \'+\' is specified, a report is only printed if the number of sectors
has increased between two check cycles. Some disks do not reset this
attribute when a bad sector is reallocated.
See also \'\-v 197,increasing\' below.
A pending sector is a disk sector (containing 512 bytes of your data)
which the device would like to mark as ``bad" and reallocate.
Typically this is because your computer tried to read that sector, and
@ -964,7 +1067,7 @@ device substitute a spare good sector for the bad one) but at the
price of losing the 512 bytes of data stored there.
.TP
.B \-U ID
.B \-U ID[+]
[ATA only] Report if the number of offline uncorrectable sectors is
non-zero. Here \fBID\fP is the id number of the Attribute whose raw
value is the Offline Uncorrectable Sector count. The allowed range of
@ -973,6 +1076,10 @@ ID\ =\ 0. If the \fB\-U ID\fP option is not given, then it defaults to
\fB\-U 198\fP (since Attribute 198 is generally used to monitor
offline uncorrectable sectors).
If \'+\' is specified, a report is only printed if the number of sectors
has increased since the last check cycle. Some disks do not reset this
attribute when a bad sector is reallocated.
See also \'\-v 198,increasing\' below.
An offline uncorrectable sector is a disk sector which was not
readable during an off\-line scan or a self\-test. This is important
@ -983,13 +1090,19 @@ 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
degrees since last report, or if new min or max temperature is detected.
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.
If this directive is used in conjunction with state persistence
(\'\-s\' option), the min and max temperature values are preserved
across boot cycles. The minimum temperature value is not updated
during the first 30 minutes after startup.
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\').
@ -1108,6 +1221,16 @@ with RK100-13 firmware).
interpretation is unknown. This is primarily useful for the -P
(presets) Directive.
.I 197,increasing
\- Raw Attribute number 197 (Current Pending Sector Count) is not
reset if uncorrectable sectors are reallocated. This also sets
\'-C 197+\' if no other \'-C\' directive is specified.
.I 198,increasing
\- Raw Attribute number 198 (Offline Uncorrectable Sector Count) is not
reset if uncorrectable sector are reallocated. This also sets
\'-U 198+\' if no other \'-U\' directive is specified.
.I 198,offlinescanuncsectorct
\- Raw Attribute number 198 is the Offline Scan UNC Sector Count.
@ -1317,17 +1440,19 @@ University of Wisconsin \- Milwaukee Physics Department
The following have made large contributions to smartmontools:
.nf
\fBCasper Dik\fP (Solaris SCSI interface)
\fBChristian Franke\fP (Windows interface and Cygwin package)
\fBChristian Franke\fP (Windows interface, C++ redesign, USB support, ...)
\fBDouglas Gilbert\fP (SCSI subsystem)
\fBGuido Guenther\fP (Autoconf/Automake packaging)
\fBGeoffrey Keating\fP (Darwin ATA interface)
\fBEduard Martinescu\fP (FreeBSD interface)
\fBFr\*'ed\*'eric L. W. Meunier\fP (Web site and Mailing list)
\fBGabriele Pohl\fP (Web site and Wiki, conversion from CVS to SVN)
\fBKeiji Sawada\fP (Solaris ATA interface)
\fBManfred Schwarb\fP (Drive database)
\fBSergey Svishchev\fP (NetBSD interface)
\fBDavid Snyder and Sergey Svishchev\fP (OpenBSD interface)
\fBPhil Williams\fP (User interface and drive database)
\fBShengfeng Zhou\fP (Linux Highpoint RocketRaid interface)
\fBShengfeng Zhou\fP (Linux/FreeBSD HighPoint RocketRAID interface)
.fi
Many other individuals have made smaller contributions and corrections.
@ -1356,5 +1481,5 @@ SEE ALSO:
\fBsyslog.conf\fP(5), \fBbadblocks\fP(8), \fBide\-smart\fP(8), \fBregex\fP(7).
.SH
CVS ID OF THIS PAGE:
$Id: smartd.conf.5.in,v 1.87 2008/03/04 22:09:47 ballen4705 Exp $
SVN ID OF THIS PAGE:
$Id: smartd.conf.5.in 2847 2009-07-18 14:58:44Z chrfranke $

3756
smartd.cpp

File diff suppressed because it is too large Load Diff

314
smartd.h
View File

@ -1,314 +0,0 @@
/*
* smartd.h
*
* Home page of code is: http://smartmontools.sourceforge.net
*
* Copyright (C) 2002-8 Bruce Allen <smartmontools-support@lists.sourceforge.net>
* Copyright (C) 2000 Michael Cornwell <cornwell@acm.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* You should have received a copy of the GNU General Public License
* (for example COPYING); if not, write to the Free
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* This code was originally developed as a Senior Thesis by Michael Cornwell
* at the Concurrent Systems Laboratory (now part of the Storage Systems
* Research Center), Jack Baskin School of Engineering, University of
* California, Santa Cruz. http://ssrc.soe.ucsc.edu/
*
*/
#ifndef SMARTD_H_
#define SMARTD_H_
// Needed since some structure definitions below require POSIX
// extended regular expressions.
#include <sys/types.h>
#include <regex.h>
#ifndef SMARTD_H_CVSID
#define SMARTD_H_CVSID "$Id: smartd.h,v 1.86 2008/03/04 22:09:47 ballen4705 Exp $\n"
#endif
// Configuration file
#define CONFIGFILENAME "smartd.conf"
// Scan directive for configuration file
#define SCANDIRECTIVE "DEVICESCAN"
// maximum line length in configuration file
#define MAXLINELEN 256
// maximum length of a continued line in configuration file
#define MAXCONTLINE 1023
// default for how often SMART status is checked, in seconds
#define CHECKTIME 1800
/* Boolean Values */
#define TRUE 0x01
#define FALSE 0x00
// Number of monitoring flags per Attribute and offsets. See
// monitorattflags below.
#define NMONITOR 4
#define MONITOR_FAILUSE 0
#define MONITOR_IGNORE 1
#define MONITOR_RAWPRINT 2
#define MONITOR_RAW 3
// Number of allowed mail message types
#define SMARTD_NMAIL 13
typedef struct mailinfo_s {
int logged;// number of times an email has been sent
time_t firstsent;// time first email was sent, as defined by time(2)
time_t lastsent; // time last email was sent, as defined by time(2)
} mailinfo;
// If user has requested email warning messages, then this structure
// stores the information about them, and track type/date of email
// messages.
typedef struct maildata_s {
mailinfo maillog[SMARTD_NMAIL]; // log info on when mail sent
char *emailcmdline; // script to execute
char *address; // email address, or null
unsigned char emailfreq; // Emails once (1) daily (2) diminishing (3)
unsigned char emailtest; // Send test email?
} maildata;
// If user has requested automatic testing, then this structure stores
// their regular expression pattern, the compiled form of that regex,
// and information about the disk capabilities and when the last text
// took place
typedef struct testinfo_s {
char *regex; // text form of regex
regex_t cregex; // compiled form of regex
unsigned short hour; // 1+hour of year when last scheduled self-test done
char testtype; // type of test done at hour indicated just above
signed char not_cap_offline; // 0==unknown OR capable of offline, 1==not capable
signed char not_cap_conveyance;
signed char not_cap_short;
signed char not_cap_long;
} testinfo;
// cfgfile is the main data structure of smartd. It is used in two
// ways. First, to store a list of devices/options given in the
// configuration smartd.conf or constructed with DEVICESCAN. And
// second, to point to or provide all persistent storage needed to
// track a device, if registered either as SCSI or ATA.
//
// After parsing the config file, each valid entry has a cfgfile data
// structure allocated in memory for it. In parsing the configuration
// file, some storage space may be needed, of indeterminate length,
// for example for the device name. When this happens, memory should
// be allocated and then pointed to from within the corresponding
// cfgfile structure.
// After parsing the configuration file, each device is then checked
// to see if it can be monitored (this process is called "registering
// the device". This is done in [scsi|ata]devicescan, which is called
// exactly once, after the configuration file has been parsed and
// cfgfile data structures have been created for each of its entries.
//
// If a device can not be monitored, the memory for its cfgfile data
// structure should be freed by calling rmconfigentry(cfgfile *). In
// this case, we say that this device "was not registered". All
// memory associated with that particular cfgfile structure is thus
// freed.
//
// The remaining devices are polled in a timing look, where
// [ata|scsi]CheckDevice looks at each entry in turn.
//
// If you want to add small amounts of "private" data on a per-device
// basis, just make a new field in cfgfile. This is guaranteed zero
// on startup (when ata|scsi]scsidevicescan(cfgfile *cfg) is first
// called with a pointer to cfgfile.
//
// If you need *substantial* persistent data space for a device
// (dozens or hundreds of bytes) please add a pointer field to
// cfgfile. As before, this is guaranteed NULL when
// ata|scsi]scsidevicescan(cfgfile *cfg) is called. Allocate space for
// it in scsidevicescan or atadevicescan, if needed, and deallocate
// the space in rmconfigentry(cfgfile *cfg). Be sure to make the
// pointer NULL unless it points to an area of the heap that can be
// deallocated with free(). In other words, a non-NULL pointer in
// cfgfile means "this points to data space that should be freed if I
// stop monitoring this device." If you don't need the space anymore,
// please call free() and then SET THE POINTER IN cfgfile TO NULL.
//
// Note that we allocate one cfgfile structure per device. This is
// why substantial persisent data storage should only be pointed to
// from within cfgfile, not kept within cfgfile itself - it saves
// memory for those devices that don't need that type of persistent
// data.
//
// In general, the capabilities of devices should be checked at
// registration time within atadevicescan() and scsidevicescan(), and
// then noted within *cfg. So if device lacks some capability, this
// should be visible within *cfg after returning from
// [ata|scsi]devicescan.
//
// Devices are then checked, once per polling interval, within
// ataCheckDevice() and scsiCheckDevice(). These should only check
// the capabilities that devices already are known to have (as noted
// within *cfg).
typedef struct configfile_s {
// FIRST SET OF ENTRIES CORRESPOND TO WHAT THE USER PUT IN THE
// CONFIG FILE. SOME ENTRIES MAY BE MODIFIED WHEN A DEVICE IS
// 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_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
char usage; // Track changes in Usage Attributes
char selftest; // Monitor number of selftest errors
char errorlog; // Monitor number of ATA errors
char permissive; // Ignore failed SMART commands
char autosave; // 1=disable, 2=enable Autosave Attributes
char autoofflinetest; // 1=disable, 2=enable Auto Offline Test
unsigned char fixfirmwarebug; // Fix firmware bug
char ignorepresets; // Ignore database of -v options
char showpresets; // Show database entry for this device
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
unsigned short pending; // lower 8 bits: ID of current pending sector count
// upper 8 bits: ID of offline pending sector count
// 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 SuppressReport; // minimize nuisance reports
unsigned char modese_len; // mode sense/select cmd len: 0 (don't
// know yet) 6 or 10
unsigned char notused2[3]; // for packing alignment
// ATA ONLY FROM HERE ON TO THE END
int ataerrorcount; // Total number of ATA errors
// following NMONITOR items each point to 32 bytes, in the form of
// 32x8=256 single bit flags
// valid attribute numbers are from 1 <= x <= 255
// monitorattflags+0 set: ignore failure for a usage attribute
// monitorattflats+32 set: don't track attribute
// monitorattflags+64 set: print raw value when tracking
// monitorattflags+96 set: track changes in raw value
unsigned char *monitorattflags;
// NULL UNLESS (1) STORAGE IS ALLOCATED WHEN CONFIG FILE SCANNED
// (SET BY USER) or (2) IT IS SET WHEN DRIVE IS AUTOMATICALLY
// RECOGNIZED IN DATABASE (WHEN DRIVE IS REGISTERED)
unsigned char *attributedefs; // -v options, see end of extern.h for def
// ATA ONLY - SAVE SMART DATA. NULL POINTERS UNLESS NEEDED. IF
// NEEDED, ALLOCATED WHEN DEVICE REGISTERED.
struct ata_smart_values *smartval; // Pointer to SMART data
struct ata_smart_thresholds_pvt *smartthres; // Pointer to SMART thresholds
// Added to distinguish ATA and SCSI entries on list
int WhichCheckDevice;
} cfgfile;
typedef struct changedattribute_s {
unsigned char newval;
unsigned char oldval;
unsigned char id;
unsigned char prefail;
unsigned char sameraw;
} changedattribute_t;
// Declare our own printing functions. Doing this provides error
// messages if the argument number/types don't match the format.
#ifndef __GNUC__
#define __attribute__(x) /* nothing */
#endif
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)));
/* Debugging notes: to check for memory allocation/deallocation problems, use:
export LD_PRELOAD=libnjamd.so;
export NJAMD_PROT=strict;
export NJAMD_CHK_FREE=error;
export NJAMD_DUMP_LEAKS_ON_EXIT=num;
export NJAMD_DUMP_LEAKS_ON_EXIT=3;
export NJAMD_TRACE_LIBS=1
*/
// Number of seconds to allow for registering a SCSI device. If this
// time expires without sucess or failure, then treat it as failure.
// Set to 0 to eliminate this timeout feature from the code
// (equivalent to an infinite timeout interval).
#define SCSITIMEOUT 0
// This is for solaris, where signal() resets the handler to SIG_DFL
// after the first signal is caught.
#ifdef HAVE_SIGSET
#define SIGNALFN sigset
#else
#define SIGNALFN signal
#endif
#define SELFTEST_ERRORCOUNT(x) (x & 0xff)
#define SELFTEST_ERRORHOURS(x) ((x >> 8) & 0xffff)
// cfg->pending is a 16 bit unsigned quantity. If the least
// significant 8 bits are zero, this means monitor Attribute
// CUR_UNC_DEFAULT's raw value. If they are CUR_UNC_DEFAULT, this
// means DON'T MONITOR. If the most significant 8 bits are zero, this
// means monitor Attribute OFF_UNC_DEFAULT's raw value. If they are
// OFF_UNC_DEFAULT, this means DON'T MONITOR.
#define OFF_UNC_DEFAULT 198
#define CUR_UNC_DEFAULT 197
#define CURR_PEND(x) (x & 0xff)
#define OFF_PEND(x) ((x >> 8) & 0xff)
// if cfg->pending has this value, dont' monitor
#define DONT_MONITOR_UNC (256*OFF_UNC_DEFAULT+CUR_UNC_DEFAULT)
// Some return values from SCSIFilterKnown(), used to detect known
// device types hidden behind SCSI devices.
#define SCSIFK_FAILED -1
#define SCSIFK_NORMAL 0
#define SCSIFK_3WARE 11
#define SCSIFK_SAT 12
#define SCSIFK_MARVELL 13
// Make additions BEFORE this line. The line is the end of
// double-inclusion protection and should remain the final line.
#endif // #ifndef SMARTD_H_

File diff suppressed because it is too large Load Diff

View File

@ -3,7 +3,8 @@
*
* Home page of code is: http://smartmontools.sourceforge.net
*
* Copyright (C) 2002-8 Bruce Allen <smartmontools-support@lists.sourceforge.net>
* Copyright (C) 2002-9 Bruce Allen <smartmontools-support@lists.sourceforge.net>
* Copyright (C) 2008-9 Christian Franke <smartmontools-support@lists.sourceforge.net>
* Copyright (C) 2000 Michael Cornwell <cornwell@acm.org>
*
* This program is free software; you can redistribute it and/or modify
@ -39,13 +40,18 @@
#include <mbstring.h> // _mbsinc()
#endif
#include <stdexcept>
#include "config.h"
#include "svnversion.h"
#include "int64.h"
#include "utility.h"
// Any local header files should be represented by a CVSIDX just below.
const char* utility_c_cvsid="$Id: utility.cpp,v 1.65 2008/03/04 22:09:47 ballen4705 Exp $"
CONFIG_H_CVSID INT64_H_CVSID UTILITY_H_CVSID;
#include "atacmds.h"
#include "dev_interface.h"
const char * utility_cpp_cvsid = "$Id: utility.cpp 2848 2009-07-18 20:14:38Z chrfranke $"
UTILITY_H_CVSID INT64_H_CVSID;
const char * packet_types[] = {
"Direct-access (disk)",
@ -70,13 +76,50 @@ const char * packet_types[] = {
const char *reportbug="Please report this bug to the Smartmontools developers at " PACKAGE_BUGREPORT ".\n";
// hang on to exit code, so we can make use of more generic 'atexit()'
// functionality and still check our exit code
int exitstatus = 0;
// command-line argument: are we running in debug mode?.
unsigned char debugmode = 0;
// BUILD_INFO can be provided by package maintainers
#ifndef BUILD_INFO
#define BUILD_INFO "(local build)"
#endif
// Make version information string
std::string format_version_info(const char * prog_name, bool full /*= false*/)
{
std::string info = strprintf(
"%s "PACKAGE_VERSION" "SMARTMONTOOLS_SVN_DATE" r"SMARTMONTOOLS_SVN_REV
" [%s] "BUILD_INFO"\n"
"Copyright (C) 2002-9 by Bruce Allen, http://smartmontools.sourceforge.net\n",
prog_name, smi()->get_os_version_str()
);
if (!full)
return info;
info += strprintf(
"\n"
"%s comes with ABSOLUTELY NO WARRANTY. This is free\n"
"software, and you are welcome to redistribute it under\n"
"the terms of the GNU General Public License Version 2.\n"
"See http://www.gnu.org for further details.\n"
"\n"
"smartmontools release "PACKAGE_VERSION
" dated "SMARTMONTOOLS_RELEASE_DATE" at "SMARTMONTOOLS_RELEASE_TIME"\n"
"smartmontools SVN rev "SMARTMONTOOLS_SVN_REV
" dated "SMARTMONTOOLS_SVN_DATE" at "SMARTMONTOOLS_SVN_TIME"\n"
"smartmontools build host: "SMARTMONTOOLS_BUILD_HOST"\n"
"smartmontools build configured: "SMARTMONTOOLS_CONFIGURE_DATE "\n"
"%s compile dated "__DATE__" at "__TIME__"\n",
prog_name, prog_name
);
info += strprintf(
"smartmontools configure arguments: %s\n",
(sizeof(SMARTMONTOOLS_CONFIGURE_ARGS) > 1 ?
SMARTMONTOOLS_CONFIGURE_ARGS : "[no arguments given]")
);
return info;
}
// Solaris only: Get site-default timezone. This is called from
// UpdateTimezone() when TZ environment variable is unset at startup.
@ -117,9 +160,9 @@ static char *ReadSiteDefaultTimezone(){
void FixGlibcTimeZoneBug(){
#if __GLIBC__
if (!getenv("TZ")) {
putenv("TZ=GMT");
putenv((char *)"TZ=GMT"); // POSIX prototype is 'int putenv(char *)'
tzset();
putenv("TZ");
putenv((char *)"TZ");
tzset();
}
#elif _WIN32
@ -230,7 +273,7 @@ int isbigendian(){
// timezone info (sigh).
void dateandtimezoneepoch(char *buffer, time_t tval){
struct tm *tmval;
char *timezonename;
const char *timezonename;
char datebuffer[DATEANDEPOCHLEN];
int lenm1;
#ifdef _WIN32
@ -285,61 +328,6 @@ void dateandtimezone(char *buffer){
return;
}
// These are two utility functions for printing CVS IDs. Massagecvs()
// returns distance that it has moved ahead in the input string
int massagecvs(char *out, const char *cvsid){
char *copy,*filename,*date,*version;
int retVal=0;
const char delimiters[] = " ,$";
// make a copy on the heap, go to first token,
if (!(copy=strdup(cvsid)))
return 0;
if (!(filename=strtok(copy, delimiters)))
goto endmassage;
// move to first instance of "Id:"
while (strcmp(filename,"Id:"))
if (!(filename=strtok(NULL, delimiters)))
goto endmassage;
// get filename, skip "v", get version and date
if (!( filename=strtok(NULL, delimiters) ) ||
!( strtok(NULL, delimiters) ) ||
!( version=strtok(NULL, delimiters) ) ||
!( date=strtok(NULL, delimiters) ) )
goto endmassage;
sprintf(out,"%-16s revision: %-5s date: %-15s", filename, version, date);
retVal = (date-copy)+strlen(date);
endmassage:
free(copy);
return retVal;
}
// prints a single set of CVS ids
void printone(char *block, const char *cvsid){
char strings[CVSMAXLEN];
const char *here=cvsid;
int bi=0, len=strlen(cvsid)+1;
// check that the size of the output block is sufficient
if (len>=CVSMAXLEN) {
pout("CVSMAXLEN=%d must be at least %d\n",CVSMAXLEN,len+1);
EXIT(1);
}
// loop through the different strings
while (bi<CVSMAXLEN && (len=massagecvs(strings,here))){
bi+=snprintf(block+bi,CVSMAXLEN-bi,"%s %s\n",(bi==0?"Module:":" uses:"),strings);
here+=len;
}
return;
}
// A replacement for perror() that sends output to our choice of
// printing. If errno not set then just print message.
void syserror(const char *message){
@ -361,21 +349,6 @@ void syserror(const char *message){
return;
}
// Prints a warning message for a failed regular expression compilation from
// regcomp().
void printregexwarning(int errcode, regex_t *compiled){
size_t length = regerror(errcode, compiled, NULL, 0);
char *buffer = (char*)malloc(length);
if (!buffer){
pout("Out of memory in printregexwarning()\n");
return;
}
regerror(errcode, compiled, buffer, length);
pout("%s\n", buffer);
free(buffer);
return;
}
// POSIX extended regular expressions interpret unmatched ')' ordinary:
// "The close-parenthesis shall be considered special in this context
// only if matched with a preceding open-parenthesis."
@ -385,7 +358,8 @@ void printregexwarning(int errcode, regex_t *compiled){
//
// The check below is rather incomplete because it does not handle
// e.g. '\)' '[)]'.
// But it should work for the regex subset used in drive database.
// But it should work for the regex subset used in drive database
// and smartd '-s' directives.
static int check_regex_nesting(const char * pattern)
{
int level = 0, i;
@ -398,22 +372,88 @@ static int check_regex_nesting(const char * pattern)
return level;
}
// A wrapper for regcomp(). Returns zero for success, non-zero otherwise.
int compileregex(regex_t *compiled, const char *pattern, int cflags)
{
int errorcode;
// Wrapper class for regex(3)
if ( (errorcode = regcomp(compiled, pattern, cflags))
|| check_regex_nesting(pattern) < 0 ) {
pout("Internal error: unable to compile regular expression \"%s\" ", pattern);
if (errorcode)
printregexwarning(errorcode, compiled);
else
pout("Unmatched ')'\n");
pout("Please inform smartmontools developers at " PACKAGE_BUGREPORT "\n");
return 1;
regular_expression::regular_expression()
: m_flags(0)
{
memset(&m_regex_buf, 0, sizeof(m_regex_buf));
}
regular_expression::regular_expression(const char * pattern, int flags)
{
memset(&m_regex_buf, 0, sizeof(m_regex_buf));
compile(pattern, flags);
}
regular_expression::~regular_expression()
{
free_buf();
}
regular_expression::regular_expression(const regular_expression & x)
{
memset(&m_regex_buf, 0, sizeof(m_regex_buf));
copy(x);
}
regular_expression & regular_expression::operator=(const regular_expression & x)
{
free_buf();
copy(x);
return *this;
}
void regular_expression::free_buf()
{
if (nonempty(&m_regex_buf, sizeof(m_regex_buf))) {
regfree(&m_regex_buf);
memset(&m_regex_buf, 0, sizeof(m_regex_buf));
}
return 0;
}
void regular_expression::copy(const regular_expression & x)
{
m_pattern = x.m_pattern;
m_flags = x.m_flags;
m_errmsg = x.m_errmsg;
if (!m_pattern.empty() && m_errmsg.empty()) {
// There is no POSIX compiled-regex-copy command.
if (!compile())
throw std::runtime_error(strprintf(
"Unable to recompile regular expression \"%s\": %s",
m_pattern.c_str(), m_errmsg.c_str()));
}
}
bool regular_expression::compile(const char * pattern, int flags)
{
free_buf();
m_pattern = pattern;
m_flags = flags;
return compile();
}
bool regular_expression::compile()
{
int errcode = regcomp(&m_regex_buf, m_pattern.c_str(), m_flags);
if (errcode) {
char errmsg[512];
regerror(errcode, &m_regex_buf, errmsg, sizeof(errmsg));
m_errmsg = errmsg;
free_buf();
return false;
}
if (check_regex_nesting(m_pattern.c_str()) < 0) {
m_errmsg = "Unmatched ')'";
free_buf();
return false;
}
m_errmsg.clear();
return true;
}
// Splits an argument to the -r option into a name part and an (optional)
@ -465,25 +505,27 @@ int split_report_arg2(char *s, int *i){
}
#ifndef HAVE_STRTOULL
// Replacement for missing strtoull() (Linux with libc < 6, MSVC 6.0)
// Functionality reduced to split_selective_arg()'s requirements.
// Replacement for missing strtoull() (Linux with libc < 6, MSVC)
// Functionality reduced to requirements of smartd and split_selective_arg().
static uint64_t strtoull(const char * p, char * * endp, int base)
uint64_t strtoull(const char * p, char * * endp, int base)
{
uint64_t result, maxres;
int i = 0;
char c = p[i++];
// assume base == 0
if (c == '0') {
if (p[i] == 'x' || p[i] == 'X') {
base = 16; i++;
if (!base) {
if (c == '0') {
if (p[i] == 'x' || p[i] == 'X') {
base = 16; i++;
}
else
base = 8;
c = p[i++];
}
else
base = 8;
c = p[i++];
base = 10;
}
else
base = 10;
result = 0;
maxres = ~(uint64_t)0 / (unsigned)base;
@ -507,7 +549,8 @@ static uint64_t strtoull(const char * p, char * * endp, int base)
result = result * (unsigned)base + digit;
c = p[i++];
}
*endp = (char *)p + i - 1;
if (endp)
*endp = (char *)p + i - 1;
return result;
}
#endif // HAVE_STRTOLL
@ -565,7 +608,14 @@ int split_selective_arg(char *s, uint64_t *start,
return 0;
}
#ifdef OLD_INTERFACE
// smartd exit codes
#define EXIT_NOMEM 8 // out of memory
#define EXIT_BADCODE 10 // internal error - should NEVER happen
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.
@ -634,13 +684,16 @@ char *CustomStrDup(const char *ptr, int mustexist, int whatline, const char* fil
return tmp;
}
// Returns nonzero if region of memory contains non-zero entries
int nonempty(unsigned char *testarea,int n){
int i;
for (i=0;i<n;i++)
if (testarea[i])
return 1;
return 0;
#endif // OLD_INTERFACE
// Returns true if region of memory contains non-zero entries
bool nonempty(const void * data, int size)
{
for (int i = 0; i < size; i++)
if (((const unsigned char *)data)[i])
return true;
return false;
}
@ -672,6 +725,24 @@ void MsecToText(unsigned int msec, char *txt){
return;
}
// return (v)sprintf() formatted std::string
std::string vstrprintf(const char * fmt, va_list ap)
{
char buf[512];
vsnprintf(buf, sizeof(buf), fmt, ap);
buf[sizeof(buf)-1] = 0;
return buf;
}
std::string strprintf(const char * fmt, ...)
{
va_list ap; va_start(ap, fmt);
std::string str = vstrprintf(fmt, ap);
va_end(ap);
return str;
}
#ifndef HAVE_WORKING_SNPRINTF
// Some versions of (v)snprintf() don't append null char on overflow (MSVCRT.DLL),

229
utility.h
View File

@ -3,7 +3,8 @@
*
* Home page of code is: http://smartmontools.sourceforge.net
*
* Copyright (C) 2002-8 Bruce Allen <smartmontools-support@lists.sourceforge.net>
* Copyright (C) 2002-9 Bruce Allen <smartmontools-support@lists.sourceforge.net>
* Copyright (C) 2008-9 Christian Franke <smartmontools-support@lists.sourceforge.net>
* Copyright (C) 2000 Michael Cornwell <cornwell@acm.org>
*
* This program is free software; you can redistribute it and/or modify
@ -25,21 +26,42 @@
#ifndef UTILITY_H_
#define UTILITY_H_
#define UTILITY_H_CVSID "$Id: utility.h,v 1.51 2008/03/04 22:09:47 ballen4705 Exp $\n"
#define UTILITY_H_CVSID "$Id: utility.h 2848 2009-07-18 20:14:38Z chrfranke $"
#include <time.h>
#include <sys/types.h> // for regex.h (according to POSIX)
#include <regex.h>
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#include <string>
#if !defined(__GNUC__) && !defined(__attribute__)
#define __attribute__(x) /**/
#endif
// Make version information string
std::string format_version_info(const char * prog_name, bool full = false);
// return (v)sprintf() formated std::string
std::string strprintf(const char * fmt, ...)
__attribute__ ((format (printf, 1, 2)));
std::string vstrprintf(const char * fmt, va_list ap);
#ifndef HAVE_WORKING_SNPRINTF
// Substitute by safe replacement functions
#include <stdarg.h>
int safe_snprintf(char *buf, int size, const char *fmt, ...);
int safe_snprintf(char *buf, int size, const char *fmt, ...)
__attribute__ ((format (printf, 3, 4)));
int safe_vsnprintf(char *buf, int size, const char *fmt, va_list ap);
#define snprintf safe_snprintf
#define vsnprintf safe_vsnprintf
#endif
#ifndef HAVE_STRTOULL
// Replacement for missing strtoull() (Linux with libc < 6, MSVC)
uint64_t strtoull(const char * p, char * * endp, int base);
#endif
// Utility function prints current date and time and timezone into a
// character buffer of length>=64. All the fuss is needed to get the
// right timezone info (sigh).
@ -48,40 +70,21 @@ void dateandtimezone(char *buffer);
// Same, but for time defined by epoch tval
void dateandtimezoneepoch(char *buffer, time_t tval);
// utility function for printing out CVS strings
#define CVSMAXLEN 1024
void printone(char *block, const char *cvsid);
// like printf() except that we can control it better. Note --
// although the prototype is given here in utility.h, the function
// itself is defined differently in smartctl and smartd. So the
// function definition(s) are in smartd.c and in smartctl.c.
#ifndef __GNUC__
#define __attribute__(x) /* nothing */
#endif
void pout(const char *fmt, ...)
__attribute__ ((format (printf, 1, 2)));
// replacement for perror() with redirected output.
void syserror(const char *message);
// Prints a warning message for a failed regular expression compilation from
// regcomp().
void printregexwarning(int errcode, regex_t *compiled);
// A wrapper for regcomp(). Returns zero for success, non-zero otherwise.
int compileregex(regex_t *compiled, const char *pattern, int cflags);
// Function for processing -r option in smartctl and smartd
int split_report_arg(char *s, int *i);
// Function for processing -c option in smartctl and smartd
int split_report_arg2(char *s, int *i);
// Possible values for smartselectivemode
#define SEL_RANGE 0 // MIN-MAX
#define SEL_REDO 1 // redo this
#define SEL_NEXT 2 // do next range
#define SEL_CONT 3 // redo or next depending of last test status
// Function for processing -t selective... option in smartctl
int split_selective_arg(char *s, uint64_t *start, uint64_t *stop, int *mode);
@ -89,14 +92,20 @@ int split_selective_arg(char *s, uint64_t *start, uint64_t *stop, int *mode);
// Guess device type (ata or scsi) based on device name
// Guessing will now use Controller Type defines below
int guess_device_type(const char * dev_name);
// Moved to C++ interface
//int guess_device_type(const char * dev_name);
// Create and return the list of devices to probe automatically
// if the DEVICESCAN option is in the smartd config file
int make_device_names (char ***devlist, const char* name);
// Moved to C++ interface
//int make_device_names (char ***devlist, const char* name);
// Replacement for exit(status)
// (exit is not compatible with C++ destructors)
#define EXIT(status) { throw (int)(status); }
#define EXIT(x) { exitstatus = (x); exit((x)); }
#ifdef OLD_INTERFACE
// replacement for calloc() that tracks memory usage
void *Calloc(size_t nmemb, size_t size);
@ -123,6 +132,8 @@ template <class T>
inline T * CheckFree(T * address, int whatline, const char* file)
{ return (T *)CheckFree1((void *)address, whatline, file); }
#endif // OLD_INTERFACE
// This function prints either to stdout or to the syslog as needed
// [From GLIBC Manual: Since the prototype doesn't specify types for
@ -141,18 +152,19 @@ int isbigendian();
// the ATA standard for packet devices to define the device type.
const char *packetdevicetype(int type);
int deviceopen(const char *pathname, char *type);
// Moved to C++ interface
//int deviceopen(const char *pathname, char *type);
int deviceclose(int fd);
//int deviceclose(int fd);
// Optional functions of os_*.c
#ifdef HAVE_GET_OS_VERSION_STR
// Return build host and OS version as static string
const char * get_os_version_str(void);
//const char * get_os_version_str(void);
#endif
// returns 1 if any of the n bytes are nonzero, else zero.
int nonempty(unsigned char *testarea,int n);
// returns true if any of the n bytes are nonzero, else zero.
bool nonempty(const void * data, int size);
// needed to fix glibc bug
void FixGlibcTimeZoneBug();
@ -160,27 +172,151 @@ void FixGlibcTimeZoneBug();
// convert time in msec to a text string
void MsecToText(unsigned int msec, char *txt);
// Exit codes
#define EXIT_BADCMD 1 // command line did not parse
#define EXIT_BADCONF 2 // syntax error in config file
#define EXIT_STARTUP 3 // problem forking daemon
#define EXIT_PID 4 // problem creating pid file
#define EXIT_NOCONF 5 // config file does not exist
#define EXIT_READCONF 6 // config file exists but cannot be read
// Wrapper class for a raw data buffer
class raw_buffer
{
public:
explicit raw_buffer(unsigned sz, unsigned char val = 0)
: m_data(new unsigned char[sz]),
m_size(sz)
{ memset(m_data, val, m_size); }
#define EXIT_NOMEM 8 // out of memory
#define EXIT_BADCODE 10 // internal error - should NEVER happen
~raw_buffer()
{ delete [] m_data; }
#define EXIT_BADDEV 16 // we can't monitor this device
#define EXIT_NODEV 17 // no devices to monitor
unsigned size() const
{ return m_size; }
#define EXIT_SIGNAL 254 // abort on signal
unsigned char * data()
{ return m_data; }
const unsigned char * data() const
{ return m_data; }
private:
unsigned char * m_data;
unsigned m_size;
raw_buffer(const raw_buffer &);
void operator=(const raw_buffer &);
};
/// Wrapper class for FILE *.
class stdio_file
{
public:
explicit stdio_file(FILE * f = 0, bool owner = false)
: m_file(f), m_owner(owner) { }
stdio_file(const char * name, const char * mode)
: m_file(fopen(name, mode)), m_owner(true) { }
~stdio_file()
{
if (m_file && m_owner)
fclose(m_file);
}
bool open(const char * name, const char * mode)
{
m_file = fopen(name, mode);
m_owner = true;
return !!m_file;
}
void open(FILE * f, bool owner = false)
{
m_file = f;
m_owner = owner;
}
bool close()
{
if (!m_file)
return true;
bool ok = !ferror(m_file);
if (fclose(m_file))
ok = false;
m_file = 0;
return ok;
}
operator FILE * ()
{ return m_file; }
bool operator!() const
{ return !m_file; }
private:
FILE * m_file;
bool m_owner;
stdio_file(const stdio_file &);
void operator=(const stdio_file &);
};
/// Wrapper class for regex(3).
/// Supports copy & assignment and is compatible with STL containers.
class regular_expression
{
public:
// Construction & assignment
regular_expression();
regular_expression(const char * pattern, int flags);
~regular_expression();
regular_expression(const regular_expression & x);
regular_expression & operator=(const regular_expression & x);
/// Set and compile new pattern, return false on error.
bool compile(const char * pattern, int flags);
// Get pattern from last compile().
const char * get_pattern() const
{ return m_pattern.c_str(); }
/// Get error message from last compile().
const char * get_errmsg() const
{ return m_errmsg.c_str(); }
// Return true if pattern is not set or bad.
bool empty() const
{ return (m_pattern.empty() || !m_errmsg.empty()); }
/// Return true if substring matches pattern
bool match(const char * str, int flags = 0) const
{ return !regexec(&m_regex_buf, str, 0, (regmatch_t*)0, flags); }
/// Return true if full string matches pattern
bool full_match(const char * str, int flags = 0) const
{
regmatch_t range;
return ( !regexec(&m_regex_buf, str, 1, &range, flags)
&& range.rm_so == 0 && range.rm_eo == (int)strlen(str));
}
/// Return true if substring matches pattern, fill regmatch_t array.
bool execute(const char * str, unsigned nmatch, regmatch_t * pmatch, int flags = 0) const
{ return !regexec(&m_regex_buf, str, nmatch, pmatch, flags); }
private:
std::string m_pattern;
int m_flags;
regex_t m_regex_buf;
std::string m_errmsg;
void free_buf();
void copy(const regular_expression & x);
bool compile();
};
// macros to control printing
#define PRINT_ON(control) {if (control->printing_switchable) control->dont_print=0;}
#define PRINT_OFF(control) {if (control->printing_switchable) control->dont_print=1;}
#define PRINT_ON(control) {if (control->printing_switchable) control->dont_print=false;}
#define PRINT_OFF(control) {if (control->printing_switchable) control->dont_print=true;}
#ifdef OLD_INTERFACE
// possible values for controller_type in extern.h
#define CONTROLLER_UNKNOWN 0x00
#define CONTROLLER_ATA 0x01
@ -194,5 +330,8 @@ void MsecToText(unsigned int msec, char *txt);
#define CONTROLLER_HPT 0x09 // SATA drives behind HighPoint Raid controllers
#define CONTROLLER_CCISS 0x10 // CCISS controller
#define CONTROLLER_PARSEDEV 0x11 // "smartctl -r ataioctl,2 ..." output parser pseudo-device
#define CONTROLLER_USBCYPRESS 0x12 // ATA device behind Cypress USB bridge
#define CONTROLLER_ARECA 0x13 // Areca controller
#endif
#endif