]> git.proxmox.com Git - mirror_smartmontools-debian.git/commitdiff
Imported Upstream version 6.3+svn3990
authorGiuseppe Iuculano <iuculano@debian.org>
Sun, 5 Oct 2014 07:03:54 +0000 (09:03 +0200)
committerGiuseppe Iuculano <iuculano@debian.org>
Sun, 5 Oct 2014 07:03:54 +0000 (09:03 +0200)
46 files changed:
ChangeLog
INSTALL
Makefile.am
NEWS
README
TODO
WARNINGS
aacraid.h [new file with mode: 0644]
atacmds.cpp
ataidentify.cpp
ataprint.cpp
autogen.sh
cciss.cpp
configure.ac
dev_areca.cpp
dev_areca.h
drivedb.h
examplescripts/Example1
examplescripts/Example2
examplescripts/Example3
examplescripts/Example4
examplescripts/Example5 [new file with mode: 0755]
examplescripts/Example6 [new file with mode: 0755]
examplescripts/README
os_darwin.cpp
os_freebsd.cpp
os_linux.cpp
os_win32.cpp
os_win32/daemon_win32.cpp
os_win32/installer.nsi
os_win32/smartctl_res.rc.in
os_win32/smartd_res.rc.in
scsiata.cpp
scsicmds.cpp
scsicmds.h
scsiprint.cpp
smartctl.8.in
smartctl.cpp
smartd.8.in
smartd.conf.5.in
smartd.cpp
smartd.service.in
smartd_warning.sh.in
update-smart-drivedb.8.in [new file with mode: 0644]
utility.cpp
utility.h

index 9e8131f8f0cd7fb1a4924da2dafa3f5873ac739c..b334db936d7277d4fcc8a331f215429e66bcbfb5 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,4 +1,519 @@
-$Id: ChangeLog 3841 2013-07-26 17:38:57Z chrfranke $
+$Id: ChangeLog 3990 2014-09-29 17:59:37Z samm2 $
+
+2014-09-29  Alex Samorukov  <samm@os2.kiev.ua>
+
+       drivedb.h: Added Seagate Backup Plus Slim Portable USB 3.0 drive
+
+2014-08-29  Christian Franke  <franke@computer.org>
+
+       drivedb.h: Fix regex syntax error (regression from r3988).
+
+2014-08-22  Alex Samorukov  <samm@os2.kiev.ua>
+
+       drivedb.h:
+       - fixed SanDisk X210 regular expression
+
+2014-08-21  Alex Samorukov  <samm@os2.kiev.ua>
+
+       drivedb.h:
+       - added SanDisk X300s SSD
+       - extended Apacer SSD support based on APSDM004G13AN-AT user report
+
+2014-08-16  Alex Samorukov  <samm@os2.kiev.ua>
+
+       ataprint.cpp: '-l devstat' - workaround for buggy firmware by provided
+       Christian Franke
+
+2014-08-15  Alex Samorukov  <samm@os2.kiev.ua>
+
+       ataprint.cpp: device statistic - use smart log if GP log is not available
+
+2014-08-15  Alex Samorukov  <samm@os2.kiev.ua>
+
+       os_darwin.cpp:
+       - Migrated to the new interface
+       - Added multisector support
+       - Fixed smart autosave processing
+
+2014-07-26  Christian Franke  <franke@computer.org>
+
+       smartmontools 6.3
+
+2014-07-25  Christian Franke  <franke@computer.org>
+
+       drivedb.h:
+       - Apple SD/SM/TS...E/F SSDs: Rename, add TS*[EF]
+       - JMicron based SSDs: Fix regex for Apple TS*C
+       - Marvell based SanDisk SSDs: X210
+
+2014-07-25  Alex Samorukov  <samm@os2.kiev.ua>
+
+       drivedb.h: Apple SM* SSD - add attribute 173 description (guessed)
+
+2014-07-23  Christian Franke  <franke@computer.org>
+
+       ataprint.cpp: Print SCT Status regardless of SCT Data Table support.
+       atacmds.cpp: ataReadSCTTempHist(): Do not reread initial SCT Status.
+       configure.ac: Fix typo in help text.  Add MinGW comment.
+
+2014-07-22  Christian Franke  <franke@computer.org>
+
+       drivedb.h:
+       - Apple SD/SM...E/F SSDs (ticket #342)
+       - Apple SSD SM128, Asus-Phison SSD: Remove (missing attribute info)
+
+2014-07-20  Christian Franke  <franke@computer.org>
+
+       atacmds.cpp: Rework heuristics for 'tempminmax' format.
+       Now supports negative values (ticket #291) and WDC over temperature
+       counter.
+       Change default for Head_Flying_Hours to 'raw24(raw8)'.  This provides
+       more reasonable output for Seagate HDDs missing in drivedb.h.
+       drivedb.h: Comment new default for Head_Flying_Hours.
+       smartctl.8.in, smartd.8.in, smartd.conf.5.in:
+       Fix usage of line breaks and empty lines.
+
+2014-07-19  Christian Franke  <franke@computer.org>
+
+       smartctl.8.in, smartd.8.in, smartd.conf.5.in, update-smart-drivedb.8.in:
+       Add FILES section.  Move FULL PATH info to FILES section.
+       Rename REFERENCES section.  Move HOME PAGE info to REFERENCES section.
+       Remove AUTHORS section from smartd.conf man page.
+       Update or remove various outdated info.
+
+2014-07-18  Christian Franke  <franke@computer.org>
+
+       configure.ac: Use 'email' instead of 'mail' on Cygwin.
+       Remove outdated '-mno-cygwin' error check.
+       Makefile.am, smartd.conf.5.in: Replace 'mail' by actual platform
+       specific mailer.
+       examplescripts/README, examplescripts/Example[123]: Remove bashisms.
+       Use '/usr/bin/mail' instead of '/bin/mail'.
+       os_win32/daemon_win32.cpp: Support older MinGW headers with missing
+       struct SERVICE_DELAYED_AUTO_START_INFO.
+
+2014-07-17  Christian Franke  <franke@computer.org>
+
+       drivedb.h:
+       - Crucial/Micron MX100/M500/M510/M550 Client SSDs: Rename, add MX100,
+         update MX510/550
+       - Indilinx Barefoot based SSDs: OCZ Vertex 1.10
+       - Intel 320 Series SSDs: 'L' variant
+       - JMicron based SSDs: Transcend *18M-M variant
+       - Plextor M3/M5 (Pro) Series SSDs: M5M (mSATA) variant
+       - Samsung based SSDs: 840 EVO
+
+2014-07-16  Christian Franke  <franke@computer.org>
+
+       drivedb.h:
+       - Marvell based SanDisk SSDs: Extreme II (ticket #334), others
+       - SanDisk based SSDs: iSSD P4 (ticket #272), U100 (ticket #337), others
+       - USB: Iomega (0x059b:0x047a)
+       - USB: WD My Passport: Merge entries
+       - USB: WD My Passport USB 3.0 (0x1058:0x074a, 0x1058:0x0820)
+       - USB: ADATA (0x125f:0xa[13]1a)
+       - USB: JMicron JMS539 (0x152d:0x0539): New FW supports SAT (ticket #338)
+       - USB: TrekStor Datastation (0x1e68:0x0050) (Red Hat Bugzilla 954162)
+
+2014-07-13  Christian Franke  <franke@computer.org>
+
+       atacmds.cpp: Add missing const and initialization.
+       Don't print extra '\n' if self-test log is empty.
+       ataprint.cpp: Add new ACS-4 log.
+       cciss.cpp: Fix C++11 builds on Linux.  GCC and CLang do not
+       predefine 'linux' when in '-std=c++11' mode.
+       smartd.cpp: Update description of Windows smartd service.
+       README: Update license info.  Remove outdated ATA references.
+
+2014-07-10  Christian Franke  <franke@computer.org>
+
+       Makefile.am: Rework build of Solaris specific man pages.
+       This fixes some bogus and some missing replacements.
+       smartctl.8.in, smartd.8.in, smartd.conf.5.in: Minor typo and syntax
+       fixes.
+
+2014-07-09  Christian Franke  <franke@computer.org>
+
+       smartctl.8.in, smartd.8.in, smartd.conf.5.in: Avoid '.SH' macros with no
+       argument.  Remove colons from section names.
+       Merge sections CONTRIBUTORS and CREDITS with AUTHORS.
+       Update SEE ALSO sections.
+
+2014-07-05  Christian Franke  <franke@computer.org>
+
+       configure.ac: Remove snprintf() compile time test.
+       Add '--with-working-snprintf' configure option.
+       Add __USE_MINGW_ANSI_STDIO test for MinGW GCC.
+       utility.cpp: Add snprintf() runtime test.
+       Add GCC version to output of -V option.
+       Makefile.am: Add update-smart-drivedb.1m for Solaris.
+
+2014-06-30  Christian Franke  <franke@computer.org>
+
+       configure.ac: Update macros as suggested by 'autoconf --warnings=obsolete'.
+       Makefile.am: Add creation of empty directories to install targets.
+
+2014-06-29  Christian Franke  <franke@computer.org>
+
+       configure.ac, Makefile.am, smartd.cpp, smartd_warning.sh.in:
+       Add '--with-smartdscriptdir' configure option to change location of
+       smartd_warning.sh (Debian bug 710815).
+       Add '--with-smartdplugindir' configure option to change (or disable)
+       smartd_warning.sh plugin location.
+       smartd.conf.5.in: Optionally hide the plugin documentation.
+
+2014-06-27  Christian Franke  <franke@computer.org>
+
+       Makefile.am: Add update-smart-drivedb.8 target.
+       update-smart-drivedb.8.in: Add copyright and version info.
+       Adjust path names for make target.
+       Add FreeBSD/OpenBSD specific info.
+
+2014-06-27  Hannes von Haugwitz  <hannes@vonhaugwitz.com>
+
+       update-smart-drivedb.8.in: New man page (Debian bug 708433).
+
+2014-06-27  Christian Franke  <franke@computer.org>
+
+       configure.ac: Suppress pkg-config warnings about missing 'systemd.pc'.
+       Makefile.am: Silence build of man pages and svnversion.h.
+       This makes '--enable-silent-rules' or 'make V=0' more effective
+       (available since automake 1.13).
+
+2014-06-27  Christian Franke  <franke@computer.org>
+
+       drivedb.h:
+       - Crucial/Micron RealSSD C300/M500: New attributes (ticket #326)
+       - SandForce Driven SSDs: ADATA XM11, Corsair Force LS, OWC Aura Pro 6G
+         OWC Mercury Electra Pro 3G, PNY Prevail Elite, Transcend SSD320/720
+
+2014-06-25  Christian Franke  <franke@computer.org>
+
+       os_win32.cpp: Fix calculation of SCSI resid.
+
+2014-06-23  Christian Franke  <franke@computer.org>
+
+       scsiata.cpp: usbjmicron_device: Fix SMART Status check for USB bridges
+       which always return 0x01.  Add JMicron specific error messages.
+
+2014-06-22  Christian Franke  <franke@computer.org>
+
+       atacmds.cpp, ataprint.cpp: Improve messages for unsupported SMART Status
+       command.
+       ataprint.cpp: Print form factor.
+
+2014-06-21  Christian Franke  <franke@computer.org>
+
+       drivedb.h:
+       - Crucial/Micron M500/M510/M550 Client SSDs
+       - Micron M500DC Enterprise SSDs
+       Based on patch provided by Clayton Hawkings from Micron.
+
+2014-06-20  Christian Franke  <franke@computer.org>
+
+       autogen.sh: automake 1.14.1 works.
+
+2014-06-20  Christian Franke  <franke@computer.org>
+
+       scsiata.cpp: usbjmicron_device: Check SCSI resid for SMART STATUS.
+       Some (Prolific) USB bridges do not transfer a status byte.
+       os_win32.cpp: Include SCSI resid in debug output.
+
+2014-06-19  Douglas Gilbert  <dgilbert@interlog.com>
+
+       scsiprint.cpp:
+       - minor comment clean-up
+
+2014-06-19  Christian Franke  <franke@computer.org>
+
+       drivedb.h:
+       - Intel 730 and DC S3500/S3700 Series SSDs: rename, add 730 and S3700.
+       Remove extra S3700 entry.  Based on patch provided by Tim Small.
+
+2014-06-18  Christian Franke  <franke@computer.org>
+
+       os_win32.cpp: Fix CSMI support for older Intel RST drivers which set
+       bPortIdentifier=0xff (regression from r3888).
+       os_win32/installer.nsi: Create standard InstallLocation registry entry.
+       Keep old Install_Dir entry if needed for GSmartControl.
+       Update links in registry and shortcuts.
+
+2014-06-18  Christian Franke  <franke@computer.org>
+
+       drivedb.h:
+       - USB: Buffalo MiniStationHD-PCFU3 (0x0411:0x0240)
+       - USB: Toshiba Stor.E Plus (0x0480:0xa00a) (Debian bug 734395)
+       - USB: Samsung D3 Station (0x04e8:0x6124) (ticket #332)
+       - USB: Samsung M3 Portable (0x04e8:0x61b[45])
+       - USB: Seagate Expansion Portable (0x0bc2:0x2312)
+       - USB: Seagate Expansion External (0x0bc2:0x3312) (ticket #320)
+       - USB: WD Elements (0x1058:0x10[ab]8) (ticket #331)
+       - USB: ASMedia AS2105 (0x174c:0x5136)
+
+2014-06-16  Christian Franke  <franke@computer.org>
+
+       drivedb.h:
+       - Seagate Laptop Thin HDD
+       - Seagate Barracuda 7200.14 (AF): *DM000 variant
+       - Seagate Barracuda Green (AF): no warnings for newer firmware versions
+       - Seagate Constellation.2 (SATA)
+       - Seagate NAS HDD
+       - Seagate Video 3.5 HDD
+
+2014-06-15  Christian Franke  <franke@computer.org>
+
+       drivedb.h, smartctl.8.in, smartd.8.in, INSTALL, NEWS, TODO, WARNINGS:
+       Fix old Trac links.
+
+2014-05-23 Alex Samorukov  <samm@os2.kiev.ua>
+
+       os_freebsd.cpp: fixed #321 (compiler warning on 32 bit architectures),
+       patch provided by tijl
+
+2014-05-01  Christian Franke  <franke@computer.org>
+
+       os_linux.cpp: Clarify copyright info in GPL header.
+       smartctl.8.in, smartd.conf.5.in: Update '-d aacraid' info.
+
+2014-04-30  Douglas Gilbert  <dgilbert@interlog.com>
+
+       scsiprint.cpp:
+       - Lowest aligned LBA > 0 not common so only output in that case
+
+2014-04-28  Christian Franke  <franke@computer.org>
+
+       autogen.sh: Allow automake 1.14, suppress 'subdir-objects' warning.
+       Makefile.am: Add new 'compile' script to target 'maintainer-clean'.
+
+2014-04-28  Douglas Gilbert  <dgilbert@interlog.com>
+
+       scsicmds.h, scsicmds.cpp, scsiprint.h:
+       - improve handling of modern SCSI disks (SAS SSDs)
+         show compliance (SCSI version), show 12 Gbps SAS-3
+         speed, and flag ZBC presence
+
+2014-04-27  Alex Samorukov  <samm@os2.kiev.ua>
+
+       drivedb.h:
+       - Toshiba 3.5" MG03ACAxxx(Y) Enterprise HDD
+
+2014-04-27  Christian Franke  <franke@computer.org>
+
+       Fixes for aacraid patch:
+       aacraid.h: Fix typo which breaks 32-bit build.
+       os_linux.cpp:  Remove useless member variable afd.
+       Fix error handling of /proc/devices parsing.
+       Avoid unsafe sprintf().  Fix help text.
+
+2014-04-27  Raghava Aditya  <raghava.aditya@pmcs.com>
+
+       os_linux.cpp:
+       - Added support for aacraid drivers
+       - Created a new interface for aacraid
+                smartctl -d aacraid,H,L,ID /dev/sdx
+
+2014-04-18  Douglas Gilbert  <dgilbert@interlog.com>
+
+       scsicmds.cpp:
+       - supported_vpd_pages(): lower response length to stop sense data
+          noise on old disks (pre SPC-3)
+
+2014-04-17  Christian Franke  <franke@computer.org>
+
+       drivedb.h:
+       - Western Digital RE4 (SATA 6Gb/s): WD2000FYYX
+       - Western Digital Se
+       - Western Digital Caviar Green (AF, SATA 6Gb/s): 4TB
+       - Western Digital Black: Rename, add 3TB, AF, remove extra AF entry
+       - Western Digital Red: 4TB (ticket #322)
+       - Western Digital Blue Mobile
+
+2014-04-10  Christian Franke  <franke@computer.org>
+
+       os_win32.cpp: Rework CSMI port scanning.
+       Use bPortIdentifier instead of Phy array index for addressing.
+       Ignore possibly bogus bNumberOfPhys (ticket #325).
+
+2014-04-09  Douglas Gilbert  <dgilbert@interlog.com>
+
+       scsiprint.cpp:
+       - add guard to scsiPrintSasPhy() invocation; resolve ticket #204
+
+2014-04-06  Christian Franke  <franke@computer.org>
+
+       WARNINGS: Remove all entries.  Add link to Warnings page in Wiki.
+
+2014-03-13  Christian Franke  <franke@computer.org>
+
+       drivedb.h:
+       - Crucial/Micron RealSSD C300/M500: *SSD1 variant
+       - SandForce Driven SSDs: ADATA SP300, ADATA SP800, ADATA SP900 DL2,
+       Corsair Force SSD, Kingston SE50S3, Kingston SKC380S3,
+       Smart Storage XceedIOPS2, VisionTek GoDrive
+       - Indilinx Barefoot 3 based SSDs: OCZ VERTEX 450
+       - JMicron based SSDs: ADATA SP600
+       - Plextor M3/M5 (Pro) Series SSDs: Rename, add M5S (ticket #297), M5Pro
+
+2014-03-06  Christian Franke  <franke@computer.org>
+
+       drivedb.h:
+       - OCZ Intrepid 3000 SSDs
+       - Intel 320 Series SSDs: 'D' variant (ticket #315)
+       - Intel DC S3500 Series SSDs: 'T' variant (ticket #315)
+
+2014-03-05  Christian Franke  <franke@computer.org>
+
+       ataprint.cpp: Check SCT Feature Control support bit for '-g/-s wcreorder'.
+       This prevents bogus error messages if SCT support excludes SCT Feature
+       Control command.
+       atacmds.cpp: Fix error message text for SCT Feature Control command.
+
+2014-03-03  Christian Franke  <franke@computer.org>
+
+       smartctl.8.in, smartd.8.in, smartd.conf.5.in: Remove bashisms from
+       shell script examples.
+
+2014-03-03  Christian Franke  <franke@computer.org>
+
+       Makefile.am, os_win32/smart*_res.rc.in: Set Copyright year in
+       Windows VERSIONINFO resource.
+
+2014-03-03  Christian Franke  <franke@computer.org>
+
+       os_linux.cpp: Fix glob(3) max path count (ticket #317).
+
+2014-03-03  Christian Franke  <franke@computer.org>
+
+       configure.ac, Makefile.am: Add '--with-systemdenvfile=[FILE|no]'
+       configure option to change or remove (ticket #316) the systemd
+       EnvironmentFile setting.
+       smartd.service.in: Add a reference to documentation (ticket #316).
+
+2014-02-18  Alex Samorukov  <samm@os2.kiev.ua>
+       os_freebsd.cpp: use %lu for iop->resp_sense_len
+
+2014-02-16  Alex Samorukov  <samm@os2.kiev.ua>
+       os_freebsd.cpp: mass updates, provided by Tijl Coosemans
+       - Remove some unused private fields from some classes (found by Clang)
+       - In freebsd_scsi_device::scsi_pass_through:
+       * Make sure this function returns false on error instead of an error
+         code that gets converted to true.
+       * Put printing of the "Incoming data" debug info right after the
+         cam_send_ccb() call and before the error checking to make debugging 
+         easier.
+       * When copying sense data make sure the fields in the CCB are actually
+         valid with CAM_AUTOSNS_VALID.  Also make sure that the size of the 
+         sense data doesn't overflow max_sense_len.  This was the real cause for
+         the crash in ports/181836.
+       * Add some debug printing on the sense data.
+
+2014-02-03  Christian Franke  <franke@computer.org>
+
+       dev_areca.cpp: Check cmds index before use (ticket #312).
+       Make cmds array static const.
+
+2014-01-01  Christian Franke  <franke@computer.org>
+
+       Happy New Year! Update copyright year in version info.
+
+2013-12-21  Christian Franke  <franke@computer.org>
+
+       drivedb.h:
+       - Intel 525 Series SSDs
+       - Intel 530 Series SSDs (ticket #308)
+
+2013-12-19  Christian Franke  <franke@computer.org>
+
+       drivedb.h:
+       - Seagate Samsung Spinpoint F4
+       - Seagate Desktop SSHD
+       - Seagate Constellation CS
+       - Western Digital Red: *JFCX variant
+       - Western Digital Green Mobile
+       - Western Digital Elements / My Passport (USB): rename
+
+2013-12-19  Christian Franke  <franke@computer.org>
+
+       autogen.sh: automake 1.13.3 works.
+
+2013-12-14  Christian Franke  <franke@computer.org>
+
+       drivedb.h:
+       - Toshiba 2.5" HDD MK..65GSX: "... H" (USB?) variant
+       - Toshiba 2.5" HDD MQ01UBD... (USB 3.0)
+       - USB: Toshiba Stor.E Slim USB 3.0 (0x0480:0x0100)
+       - USB: Toshiba Stor.E Basics (0x0480:0xa009)
+       - USB: Toshiba Stor.E (0x0939:0x0b15)
+       - USB: Seagate FreeAgent GoFlex (0x0bc2:0x5020)
+       - USB: WD My Passport Ultra (0x1058:0x0741)
+       - USB: WD Elements (0x1058:0x1048)
+       - USB: Initio (0x13fd:0x1640) (ticket #295)
+       - USB: LucidPORT (0x1759:0x5100)
+
+2013-12-08  Christian Franke  <franke@computer.org>
+
+       drivedb.h:
+       - Apacer SDM4: SFDDA01C firmware (ticket #304).
+       - Crucial/Micron RealSSD m4/C400/P400: M4 SSD1 (ticket #306).
+       - Seagate Barracuda 7200.14: Check part number to avoid bogus
+       firmware bug warning (ticket #298).
+
+2013-11-23  Christian Franke  <franke@computer.org>
+
+       configure.ac, utility.cpp: Remove __DATE__, __TIME__
+       and SMARTMONTOOLS_CONFIGURE_DATE.
+       This obsoletes OpenSUSE nobuild-date.patch.
+       Reproducible builds are now supported.
+
+2013-11-15  Alex Samorukov <samm@os2.kiev.ua>
+
+       os_freebsd.cpp: Fix crash on FreeBSD 9.2 caused by wrong
+       SCSI status check condition.
+       os_freebsd.cpp: Print debug info on errors only if requested.
+
+2013-11-07  Matt Kraai  <...>
+
+       smartctl.cpp: Add missing stdlib.h.
+       This fixes build on QNX 6.3.2 (ticket #300).
+
+2013-11-07  Roger Röhrig  <...>
+
+       drivedb.h: Intel DC S3500 Series SSDs: Add -F xerrorlba.
+
+2013-11-07  Roger Röhrig  <...>
+
+       atacmds.cpp: Fix Extended Comprehensive Error Log timestamp
+       byte order on big endian machines.
+
+2013-09-12  Christoph Egger  <christoph@debian.org>
+
+       dev_areca.h: Fix build on kFreeBSD (Debian bug 717567).
+       This obsoletes Debian kfreebsd.patch.
+
+2013-08-17  Christian Franke  <franke@computer.org>
+
+       examplescripts: Add scripts from Debian and Fedora packages.
+
+2013-08-17  Christian Franke  <franke@computer.org>
+
+       Add spaces between string literals and macro identifiers.
+       This avoids the interpretation as user-defined literals if
+       C++11 is enabled (g++ -std=gnu++11).
+
+2013-08-15 Dan Lukes  <dan+smartmontools.changelog@obluda.cz>
+
+       drivedb.h: Intel DC S3500 Series SSDs
+
+2013-08-12  Christian Franke  <franke@computer.org>
+
+       drivedb.h: Intel 320 Series SSDs: Add attribute 183 and 199.
+
+2013-08-10  Christian Franke  <franke@computer.org>
+
+       autogen.sh: automake 1.10.3, 1.12.6, and 1.13.4 work.
+       The new automake 1.14 is left out for now due to the
+       'subdir-objects' warning and the new 'compile' script.
+       Add options '--force' and '--warnings=CATEGORY'.
 
 2013-07-26  Christian Franke  <franke@computer.org>
 
diff --git a/INSTALL b/INSTALL
index 64d68addd965d734fcae7f55803bcff1ee2c5246..3335f63efa9eecf8da9933009a8d3aa508374e53 100644 (file)
--- a/INSTALL
+++ b/INSTALL
@@ -1,7 +1,7 @@
 Smartmontools installation instructions
 =======================================
 
-$Id: INSTALL 3817 2013-06-09 16:59:50Z chrfranke $
+$Id: INSTALL 3935 2014-07-05 16:28:06Z chrfranke $
 
 Please also see the smartmontools home page:
 http://smartmontools.sourceforge.net/
@@ -578,8 +578,8 @@ variable.
 Source and binary packages for Windows are available at
 http://sourceforge.net/projects/smartmontools/files/
 
-Refer to http://sourceforge.net/apps/trac/smartmontools/wiki/Download
-for any additional download and installation instructions.
+Refer to http://www.smartmontools.org/wiki/Download for any additional
+download and installation instructions.
 
 The following files are installed if ./configure has no options:
 
@@ -661,6 +661,7 @@ OPTIONS              DEFAULT                                      AFFECTS
                                                                   Directory for rc.d/init.d/smartd init script
 --with-initscriptdir           auto                               Location of init scripts
 --with-systemdsystemunitdir    auto                               Location of systemd service files
+--with-systemdenvfile ${sysconfdir}/sysconfig/smartmontools       Path of environment file for system service
 --with-docdir         ${prefix}/share/doc/smartmontools           Location of the documentation
 --with-exampledir     ${docdir}/examplescripts                    Location of example scripts
 --enable-sample       --disable-sample                            Adds the string '.sample' to the names of the smartd.conf file and the smartd RC file
@@ -672,10 +673,13 @@ OPTIONS              DEFAULT                                      AFFECTS
                                                                   available, option --capabilities is added to smartd.
 --disable-drivedb     --enable-drivedb                            Disables default drive database file '${drivedbdir}/drivedb.h'
 --with-drivedbdir     ${prefix}/share/smartmontools               Directory for 'drivedb.h' (implies --enable-drivedb)
+--with-smartdscriptdir    ${sysconfdir}                           Directory for 'smartd_warning.sh' script
+--with-smartdplugindir    ${sysconfdir}/smartd_warning.d          Directory for 'smartd_warning.sh' plugin scripts
 --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 (implies --enable-savestates)
 --enable-attributelog --disable-attributelog                      Enables default smartd attribute log files
 --with-attributelog   ${prefix}/var/lib/smartmontools/attrlog.    Prefix for smartd attribute log files (implies --enable-attributelog)
+--with-working-snprintf    MinGW:guessed,others:yes               Function snprintf() handles output truncation as specified by C99
 
 Please note that in previous versions of smartmontools (<= 5.39) the
 default for --with-docdir was
index 25f625e58e9e7f33240f88d10cd16677b8305ac5..440153711469fea1531749cd2fa44056231ffdf5 100644 (file)
@@ -1,6 +1,6 @@
 ## Process this file with automake to produce Makefile.in
 #
-# $Id: Makefile.am 3759 2013-01-26 21:11:02Z chrfranke $
+# $Id: Makefile.am 3957 2014-07-18 18:39:06Z chrfranke $
 #
 
 @SET_MAKE@
@@ -13,7 +13,11 @@ SUFFIXES = .cpp .c .s .o
 # BUILD_INFO can be provided by package maintainers (see INSTALL file)
 BUILD_INFO= "(local build)"
 
-AM_CPPFLAGS = -DBUILD_INFO='$(BUILD_INFO)' -DSMARTMONTOOLS_SYSCONFDIR='"$(sysconfdir)"'
+AM_CPPFLAGS = \
+        -DBUILD_INFO='$(BUILD_INFO)' \
+        -DSMARTMONTOOLS_SYSCONFDIR='"$(sysconfdir)"' \
+        -DSMARTMONTOOLS_SMARTDSCRIPTDIR='"$(smartdscriptdir)"'
+
 if ENABLE_DRIVEDB
 AM_CPPFLAGS += -DSMARTMONTOOLS_DRIVEDBDIR='"$(drivedbdir)"'
 endif
@@ -96,6 +100,7 @@ EXTRA_smartctl_SOURCES = \
         os_win32.cpp \
         os_generic.cpp \
         os_generic.h \
+        aacraid.h \
         cciss.cpp \
         cciss.h \
         cissio_freebsd.h \
@@ -155,6 +160,7 @@ EXTRA_smartd_SOURCES = \
         os_win32.cpp \
         os_generic.cpp \
         os_generic.h \
+        aacraid.h \
         cciss.cpp \
         cciss.h \
         cissio_freebsd.h \
@@ -242,6 +248,11 @@ if OS_SOLARIS
 extra_MANS =      smartd.conf.4 \
                   smartctl.1m   \
                   smartd.1m
+if ENABLE_DRIVEDB
+extra_MANS += update-smart-drivedb.1m
+endif
+
+all-local: $(extra_MANS)
 install-man: $(extra_MANS)
        @$(NORMAL_INSTALL)
        $(mkinstalldirs) $(DESTDIR)$(mandir)/man4
@@ -268,27 +279,17 @@ uninstall-man:
          echo " rm -f $(DESTDIR)$(mandir)/man$$ext/$$inst"; \
          rm -f $(DESTDIR)$(mandir)/man$$ext/$$inst; \
        done
-%.1m: %.8
-       awk '/^.TH/ {$$3="1m"} {print}' < $< | \
-       sed -e 's/smartd\.conf\(.*\)(5)/smartd.conf\1(4)/g' \
-            -e 's/syslog\.conf\(.*\)(5)/syslog.conf\1(4)/g' \
-           -e 's/smartctl\(.*\)(8)/smartctl\1(1m)/g' \
-           -e 's/syslogd\(.*\)(8)/syslogd\1(1m)/g' \
-            -e 's|/var/log/messages|/var/adm/messages|g' \
-           -e 's/smartd\(.*\)(8)/smartd\1(1m)/g' > $@
-%.4: %.5
-       awk '/^.TH/ {$$3="4"}  {print}' < $< | \
-       sed -e 's/smartd\.conf\(.*\)(5)/smartd.conf\1(4)/g' \
-            -e 's/syslog\.conf\(.*\)(5)/syslog.conf\1(4)/g' \
-           -e 's/smartctl\(.*\)(8)/smartdctl\1(1m)/g' \
-           -e 's/syslogd\(.*\)(8)/syslogd\1(1m)/g' \
-            -e 's|/var/log/messages|/var/adm/messages|g' \
-           -e 's/smartd\(.*\)(8)/smartd\1(1m)/g' > $@
 else
 # For systems that adopts traditional manner
+
 man_MANS =        smartd.conf.5 \
                   smartctl.8    \
                   smartd.8
+
+if ENABLE_DRIVEDB
+man_MANS += update-smart-drivedb.8
+endif
+
 endif
 
 docsdir=$(docdir)
@@ -311,7 +312,9 @@ examples_SCRIPTS = \
         examplescripts/Example1 \
         examplescripts/Example2 \
         examplescripts/Example3 \
-        examplescripts/Example4
+        examplescripts/Example4 \
+        examplescripts/Example5 \
+        examplescripts/Example6
 
 sysconf_DATA = smartd.conf
 
@@ -345,9 +348,7 @@ uninstall-sysconfDATA:
        echo " rm -f $$f"; \
        rm -f "$$f"
 
-# automake does not allow 'sysconf_SCRIPTS'
-sysscriptdir = $(sysconfdir)
-sysscript_SCRIPTS = smartd_warning.sh
+smartdscript_SCRIPTS = smartd_warning.sh
 
 EXTRA_DIST = \
         autogen.sh \
@@ -360,6 +361,7 @@ EXTRA_DIST = \
         smartd.service.in \
         smartd_warning.sh.in \
         update-smart-drivedb.in \
+        update-smart-drivedb.8.in \
         m4/pkg.m4 \
         os_darwin/SMART.in \
         os_darwin/StartupParameters.plist \
@@ -398,12 +400,15 @@ CLEANFILES = \
         smartd_warning.sh \
         svnversion.h \
         update-smart-drivedb \
+        update-smart-drivedb.8 \
+        update-smart-drivedb.1m \
         SMART
 
 # 'make maintainer-clean' also removes files generated by './autogen.sh'
 MAINTAINERCLEANFILES = \
         $(srcdir)/Makefile.in \
         $(srcdir)/aclocal.m4 \
+        $(srcdir)/compile \
         $(srcdir)/configure \
         $(srcdir)/config.guess \
         $(srcdir)/config.h.in \
@@ -420,8 +425,9 @@ utility.o: svnversion.h
 if IS_SVN_BUILD
 # Get version info from SVN
 svnversion.h: ChangeLog Makefile $(svn_deps)
-       echo '/* svnversion.h.  Generated by Makefile from svn info.  */' > $@
-       (cd $(srcdir) \
+       @echo '  svn info | $$(VERSION_FROM_SVN_INFO) > $@'
+       @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') \
@@ -430,8 +436,9 @@ 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.ac smart*.in *.cpp *.h *.s) \
+       @echo '  cat ChangeLog $$(SOURCES) | $$(VERSION_FROM_SVN_IDS) > $@'
+       @echo '/* svnversion.h.  Generated by Makefile from Id strings.  */' > $@
+       @(cd $(srcdir) && cat ChangeLog Makefile.am configure.ac 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' \
@@ -443,16 +450,6 @@ 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
-
 update-smart-drivedb: update-smart-drivedb.in config.status
        $(SHELL) ./config.status --file=$@
        chmod +x $@
@@ -530,10 +527,30 @@ systemdsystemunit_DATA = smartd.service
 endif
 
 smartd.service: smartd.service.in Makefile
-       sed -e 's|/usr/local/sbin/smartd|$(sbindir)/smartd|g' \
-           -e 's|/usr/local/etc/sysconfig/smartmontools|$(sysconfdir)/sysconfig/smartmontools|g' \
-       $(srcdir)/smartd.service.in > $@
+       cat $(srcdir)/smartd.service.in | \
+       sed 's|/usr/local/sbin/smartd|$(sbindir)/smartd|' | \
+       if test -n '$(systemdenvfile)'; then \
+         sed 's|/usr/local/etc/sysconfig/smartmontools|$(systemdenvfile)|'; \
+       else \
+         sed -e '/^EnvironmentFile=/d' -e 's| *\$$smartd[_a-z]* *||g'; \
+       fi > $@
+
+
+# Create empty directories if configured.
+# Default install rules no longer create empty directories since automake 1.11.
+# Uses $(mkinstalldirs) instead of $(MKDIR_P) to preserve support for automake 1.7 - 1.9.
+installdirs-local:
+       @for d in '$(smartdplugindir)' '$(savestatesdir)' '$(attributelogdir)'; do \
+         test -n "$$d" || continue; \
+         echo "$(mkinstalldirs) $(DESTDIR)$$d"; \
+         $(mkinstalldirs) "$(DESTDIR)$$d" || exit 1; \
+       done
+
+install-data-local: installdirs-local
 
+#
+# Build man pages
+#
 if ENABLE_CAPABILITIES
 MAN_CAPABILITIES = cat
 else
@@ -569,8 +586,17 @@ MAN_FILTER = \
         -e 's|/usr/local/share/doc/smartmontools/|$(docsdir)/|g' \
         -e 's|!exampledir!|$(exampledir)/|g' \
         -e 's|/usr/local/etc/smartd\.conf|$(sysconfdir)/smartd.conf|g' \
-        -e 's|/usr/local/etc/smartd_warning\.|$(sysconfdir)/smartd_warning.|g' \
-        -e 's|/usr/local/etc/smart_drivedb\.h|$(sysconfdir)/smart_drivedb.h|g' | \
+        -e 's|/usr/local/etc/smart_drivedb\.h|$(sysconfdir)/smart_drivedb.h|g' \
+        -e 's|/usr/local/etc/smartd_warning\.sh|$(smartdscriptdir)/smartd_warning.sh|g' \
+        -e 's|\\fBmail\\fP|\\fB$(os_mailer)\\fP|g' \
+        -e 's|\\'\''mail\\'\''|\\'\''$(os_mailer)\\'\''|g' \
+        -e 's|/usr/bin/mail|/usr/bin/$(os_mailer)|g' \
+        -e 's|RELEASE_6_0_DRIVEDB|@DRIVEDB_BRANCH@|g' | \
+    if test -n '$(smartdplugindir)'; then \
+      sed 's|/usr/local/etc/smartd_warning\.d|$(smartdplugindir)|g' ; \
+    else \
+      sed '/^\.\\" %IF ENABLE_SMARTDPLUGINDIR/,/^\.\\" %ENDIF ENABLE_SMARTDPLUGINDIR/ s,^,.\\"\# ,' ; \
+    fi | \
     $(MAN_ATTRIBUTELOG) | \
     $(MAN_CAPABILITIES) | \
     $(MAN_DRIVEDB) | \
@@ -589,13 +615,45 @@ MAN_FILTER = \
 
 # Implicit rule 'smart%: smart%.in ...' does not work with BSD make
 smartctl.8: smartctl.8.in Makefile svnversion.h
-       cat $(srcdir)/smartctl.8.in | $(MAN_FILTER) > $@
+       @echo '  cat $(srcdir)/smartctl.8.in | $$(MAN_FILTER) > $@'
+       @cat $(srcdir)/smartctl.8.in | $(MAN_FILTER) > $@
 
 smartd.8: smartd.8.in Makefile svnversion.h
-       cat $(srcdir)/smartd.8.in | $(MAN_FILTER) > $@
+       @echo '  cat $(srcdir)/smartd.8.in | $$(MAN_FILTER) > $@'
+       @cat $(srcdir)/smartd.8.in | $(MAN_FILTER) > $@
 
 smartd.conf.5: smartd.conf.5.in Makefile svnversion.h
-       cat $(srcdir)/smartd.conf.5.in | $(MAN_FILTER) > $@
+       @echo '  cat $(srcdir)/smartd.conf.5.in | $$(MAN_FILTER) > $@'
+       @cat $(srcdir)/smartd.conf.5.in | $(MAN_FILTER) > $@
+
+update-smart-drivedb.8: update-smart-drivedb.8.in Makefile svnversion.h
+       @echo '  cat $(srcdir)/update-smart-drivedb.8.in | $$(MAN_FILTER) > $@'
+       @cat $(srcdir)/update-smart-drivedb.8.in | $(MAN_FILTER) > $@
+
+# Build Solaris specific man pages
+SOLARIS_MAN_FILTER = \
+    sed -e '/^\.TH/s, \([58]\) , !!\1!! ,' \
+        -e '/^\.BR/s, (\([578]\)), (!!\1!!),' \
+        -e 's,\\fP(\([578]\)),\\fP(!!\1!!),g' \
+        -e 's,!!5!!,4,g' -e 's,!!7!!,5,g' -e 's,!!8!!,1m,g' \
+        -e 's,/var/log/messages,/var/adm/messages,g'
+
+smartctl.1m: smartctl.8
+       @echo '  cat smartctl.8 | $$(SOLARIS_MAN_FILTER) > $@'
+       @cat smartctl.8 | $(SOLARIS_MAN_FILTER) > $@
+
+smartd.1m: smartd.8
+       @echo '  cat smartd.8 | $$(SOLARIS_MAN_FILTER) > $@'
+       @cat smartd.8 | $(SOLARIS_MAN_FILTER) > $@
+
+smartd.conf.4: smartd.conf.5
+       @echo '  cat smartd.conf.5 | $$(SOLARIS_MAN_FILTER) > $@'
+       @cat smartd.conf.5 | $(SOLARIS_MAN_FILTER) > $@
+
+update-smart-drivedb.1m: update-smart-drivedb.8
+       @echo '  cat update-smart-drivedb.8 | $$(SOLARIS_MAN_FILTER) > $@'
+       @cat update-smart-drivedb.8 | $(SOLARIS_MAN_FILTER) > $@
+
 
 # Commands to convert man pages into .html and .txt
 # TODO: configure
@@ -657,12 +715,13 @@ smartctl_res.o: smartctl_res.rc
 smartd_res.o: smartd_res.rc syslogevt.rc
        $(WINDRES) -I. $< $@
 
-# Convert version for VERSIONINFO resource: 6.1 r3754 -> 6.1.0.3754
+# Convert version for VERSIONINFO resource: 6.1 r3754 -> 6.1.0.3754, set Copyright year
 WIN_RC_FILTER = \
     ( ver=`echo '$(PACKAGE_VERSION).0' | sed -n 's,^\([0-9]*\.[0-9]*\.[0-9]*\).*$$,\1,p'`; \
       rev=`sed -n 's,^.*REV[^"]*"\([0-9]*\).*$$,\1,p' svnversion.h`; \
       txtver="$${ver:-0.0.0}.$${rev:-0}"; binver=`echo "$$txtver" | sed 's|\.|,|g'`; \
-      sed -e "s|@BINARY_VERSION@|$$binver|g" -e "s|@TEXT_VERSION@|$$txtver|g"; )
+      yy=`sed -n 's,^.*DATE[^"]*"20\([0-9][0-9]\).*$$,\1,p' svnversion.h`; yy="$${yy:-XX}"; \
+      sed -e "s|@BINARY_VERSION@|$$binver|g" -e "s|@TEXT_VERSION@|$$txtver|g" -e "s|@YY@|$$yy|g"; )
 
 smartctl_res.rc: os_win32/smartctl_res.rc.in Makefile svnversion.h
        cat $< | $(WIN_RC_FILTER) > $@
diff --git a/NEWS b/NEWS
index 7a550c88eb7e60de771765371093eea609938855..03cd432a5c3d077b7730e4e434f1d2c04105ea8f 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,10 +1,34 @@
 smartmontools NEWS
 ------------------
-$Id: NEWS 3841 2013-07-26 17:38:57Z chrfranke $
+$Id: NEWS 3979 2014-08-15 11:09:41Z samm2 $
 
 The most up-to-date version of this file is:
 http://sourceforge.net/p/smartmontools/code/HEAD/tree/trunk/smartmontools/NEWS
 
+- darwin: '-S' command implemented, '-l devstat' should work now
+
+Date 2014-07-26
+Summary: smartmontools release 6.3
+-----------------------------------------------------------
+- smartctl: Fixed bogus error messages from '-g/-s wcreorder'.
+- smartctl prints ATA form factor.
+- SCSI: Improved support of modern disks (SAS SSDs).
+- SCSI: Fixed sense data noise from old disks.
+- update-smart-drivedb man page.
+- configure option '--with-smartdscriptdir'.
+- configure option '--with-smartdplugindir'.
+- configure option '--with-systemdenvfile'.
+- configure option '--with-working-snprintf'.
+- Removed build time stamps to support reproducible builds.
+- Compile fixes for C++11.
+- HDD, SSD and USB additions to drive database.
+- Linux: Support for controllers behind AACRAID driver.
+- Linux: Fixed DEVICESCAN max path count.
+- FreeBSD: Fixed possible crash caused by wrong SCSI error handling.
+- FreeBSD: Compile fix for kFreeBSD.
+- Windows: Reworked CSMI port scanning.
+- QNX: Compile fix.
+
 Date 2013-07-26
 Summary: smartmontools release 6.2
 -----------------------------------------------------------
@@ -209,7 +233,7 @@ 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, Windows and FreeBSD
-  (http://sourceforge.net/apps/trac/smartmontools/wiki/Supported_USB-Devices)
+  (http://www.smartmontools.org/wiki/Supported_USB-Devices)
 - Support for Areca controllers on Linux
 - Support for MegaRAID controllers on Linux
 - Support for HighPoint RocketRAID controllers on FreeBSD
diff --git a/README b/README
index 4a52100549fb49e7149597a522211d97df02de64..02c1b741437d06850dd15498d4159f008bdd6777 100644 (file)
--- a/README
+++ b/README
@@ -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 3817 2013-06-09 16:59:50Z chrfranke $
+$Id: README 3949 2014-07-13 17:23:40Z chrfranke $
 
 == HOME ==
 The home for smartmontools is located at:
@@ -20,6 +20,7 @@ You will find a mailing list for support and other questions at:
 
 == COPYING ==
 Copyright (C) 2002-9 Bruce Allen <smartmontools-support@lists.sourceforge.net>
+Copyright (C) 2004-14 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
@@ -27,8 +28,7 @@ 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.,
-51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+example COPYING).  If not, see <http://www.gnu.org/licenses/>.
 
 
 == CREDITS ==
@@ -41,16 +41,9 @@ California, Santa Cruz. http://ssrc.soe.ucsc.edu/
 == OVERVIEW ==
 smartmontools contains utilities that control and monitor storage
 devices using the Self-Monitoring, Analysis and Reporting Technology
-(S.M.A.R.T.) system build into ATA and SCSI Hard Drives. This is used
-to check the reliability of the hard drive and to predict drive
-failures.  smartmontools Version 5.x is designed to comply to the
-ATA/ATAPI-5 specification (Revision 1).  Future releases of
-smartmontools (Versions 6.x and 7.x) will comply with the ATA/ATAPI-6
-and ATA/ATAPI-7 specifications.
-
-This package is meant to be an up-to-date replacement for the
-ucsc-smartsuite and smartsuite packages, and is derived from that
-code.
+(SMART) system build into ATA/SATA and SCSI/SAS hard drives and
+solid-state drives.  This is used to check the reliability of the
+drive and to predict drive failures.
 
 
 == CONTENTS ==
@@ -89,9 +82,6 @@ http://sourceforge.net/p/smartmontools/code/HEAD/tree/tags/
 
 Refer to the "INSTALL" file for detailed installation instructions.
 
-See the "WARNINGS" file for reports of hardware where these utilities
-might cause serious problems such as lockups.
-
 == GETTING STARTED ==
 
 To examine SMART data from a disk, try:
diff --git a/TODO b/TODO
index 22d63583ac838d8cfb66a717c46ff0bf9827567a..36cf4d6209926dddb26c6314bd10bbe5c11087e6 100644 (file)
--- a/TODO
+++ b/TODO
@@ -1,4 +1,4 @@
-$Id: TODO 3175 2010-10-02 14:34:09Z chrfranke $
+$Id: TODO 3904 2014-06-15 14:21:15Z chrfranke $
 
 This file is no longer maintained, please use the ticket reports:
-http://sourceforge.net/apps/trac/smartmontools/report
+http://www.smartmontools.org/report
index a96499405ba5ada9785e3f966628ecdf96120b7f..0cfce2abe5acc5bc54edaa650ae514c8459094fa 100644 (file)
--- a/WARNINGS
+++ b/WARNINGS
@@ -1,122 +1,4 @@
-$Id: WARNINGS 3817 2013-06-09 16:59:50Z chrfranke $
+$Id: WARNINGS 3904 2014-06-15 14:21:15Z chrfranke $
 
-The most recent version of this file can be found here:
-http://sourceforge.net/p/smartmontools/code/HEAD/tree/trunk/smartmontools/WARNINGS
-
-The following are reports of serious problems (eg system lockup) which
-were due to smartmontools.  There are DARWIN, LINUX, FREEBSD, SOLARIS
-and WINDOWS sections below.
-
-
-LINUX
------
-
-You may also wish to search the linux-kernel mailing list for problem
-reports concerning smartmontools.  Here is the URL:
-http://groups.google.com/groups?as_q=smartmontools&safe=images&ie=UTF-8&oe=UTF-8&as_ugroup=linux.kernel&lr=&num=100&hl=en
-
-SYSTEM:   Any system with USB ports and USB storage devices
-PROBLEM:  Using smartd/smartctl on USB "SCSI" storage devices can cause kernel hang
-REPORTER: see link below
-LINK:     https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=107615
-NOTE:     USB storage devices are handled as SCSI devices by the kernel. But many of these
-          devices do not comply with SCSI specs, and can cause the kernel to hang.
-          Avoid using smartd/smartctl on these devices (they don't do SMART anyway).
-          In particular, the use of smartd DEVICESCAN in /etc/smartd.conf can cause
-          these devices (typically represented by /dev/sda or /dev/sdb) to hang, and
-          the kernel to lock up.
-FIXED:    This problem should be fixed in smartmontools-5.25 and greater.
-
-
-SYSTEM:   Intel 875WP1-E motherboard with SATA drives on motherboard's SATA ports
-PROBLEM:  smartd makes NTP time drift
-REPORTER: nohez@cmie.com
-LINK:     http://groups.google.de/groups?hl=en&lr=&ie=UTF-8&oe=UTF-8&safe=off&selm=Pine.LNX.4.33.0310111545530.1047-100000%40venus.cmie.ernet.in.lucky.linux.kernel
-NOTE:     When using SATA disks, linux kernel k_smp-2.4.21-108 (SMP because
-          of hyper-threading) and xntp-4.1.1-177, the server time went
-          out of sync with system time.  Problem goes away when SATA
-          disks removed.
-
-
-SYSTEM:   Dell servers using AACRAID (SCSI)
-PROBLEM:  Locked up, needed to be rebooted
-REPORTER: drew@eastvan.bc.ca
-LINK:     http://sourceforge.net/mailarchive/forum.php?thread_id=1311313&forum_id=12495
-
-
-SYSTEM:   Box with Promise 20265 IDE-controller (pdc202xx-driver) and > 2.4.18 kernel with ide-taskfile support
-PROBLEM:  Smartctl locks system solid when used on /dev/hd[ef].
-REPORTER: Georg Acher <acher@in.tum.de>
-LINK:     http://sourceforge.net/mailarchive/forum.php?thread_id=1457979&forum_id=12495
-NOTE:     Lockup doesn't happen with 2.4.18 kernel, and doesn't affect /dev/hd[a-d]
-          This appears to be a problem with the pdc202xx-driver and has been reported
-          to the pdcx maintainers.  If you enable the Promise-BIOS (ATA100-BIOS) then
-          everything will work fine.  But if you disable it, then the machine will hang.
-
-
-SYSTEM:   Box with Promise 20262 IDE-controller
-PROBLEM:  Smartctl locks system solid
-REPORTER: Ben Low <ben@bdlow.net>
-LINK:     http://sourceforge.net/mailarchive/message.php?msg_id=5074201
-NOTE:     Similar to previous report: Promise Ultra66 2-port card (20262) which, with
-          linux 2.4.20, suffers from the lockups reported above.  But it was
-          impossible to enable the Promiste BIOS.  A kernel patch is referenced
-          to fix the problem.
-
-
-SYSTEM:   Promise 20265 IDE-controller
-PROBLEM:  Smartctl locks system solid when used on CDROM/DVD device
-REPORTER: see link below
-LINK:     http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=208964
-NOTE:     Problem seems to affect kernel 2.4.21 only.
-
-
-SYSTEM:   Promise IDE-controllers and perhaps others also
-PROBLEM:  System freezes under heavy load, perhaps when running SMART commands
-REPORTER: Mario 'BitKoenig' Holbe Mario.Holbe@RZ.TU-Ilmenau.DE
-LINK:     http://groups.google.de/groups?hl=en&lr=&ie=UTF-8&oe=UTF-8&selm=1wUXW-2FA-9%40gated-at.bofh.it
-NOTE:     Before freezing, SYSLOG shows the following message(s)
-          kernel: hdf: dma timer expiry: dma status == 0xXX
-                 where XX is two hexidecimal digits. This may be a kernel bug
-          or an underlying hardware problem.  It's not clear if
-          smartmontools plays a role in provoking this problem.  FINAL
-          NOTE: Problem was COMPLETELY resolved by replacing the power
-          supply.  See URL above, entry on May 29, 2004 by Holbe.  Other
-          things to try are exchanging cables, and cleaning PCI slots.
-
-FREEBSD
--------
-
-[No problem reports yet.]
-
-
-SOLARIS
--------
-
-[No problem reports yet.]
-
-
-CYGWIN and WINDOWS
-------------------
-
-[No problem reports yet.]
-
-
-DARWIN
-------
-
-SYSTEM:   Any system before Tiger
-PROBLEM:  Can't switch off SMART, can't switch off auto-save, can't run
-          short tests.
-REPORTER: Geoff Keating <geoffk@geoffk.org>
-NOTE:     There's a bug in the system library: when you ask it to
-          do any of these things, it does the inverse (switches on,
-          runs extended tests).  Radar 3727283.
-
-SYSTEM:          All known systems
-PROBLEM:  When drive is asleep, SMART commands fail
-REPORTER: Geoff Keating <geoffk@geoffk.org>
-NOTE:    You can prevent the drive from sleeping by saying
-         pmset -a disksleep 0
-         or by unchecking the 'Put the hard disk(s) to sleep when possible'
-         checkbox in the Energy Saver preferences.  Radar 4094403.
+This file is no longer maintained, please see:
+http://www.smartmontools.org/wiki/Warnings
diff --git a/aacraid.h b/aacraid.h
new file mode 100644 (file)
index 0000000..de7527a
--- /dev/null
+++ b/aacraid.h
@@ -0,0 +1,105 @@
+/* aacraid.h
+ * Copyright (C) 2014 Raghava Aditya <Raghava.Aditya@pmcs.com>
+ *
+ * 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/>.
+ *
+ */
+
+// Check windows
+#if _WIN32 || _WIN64
+#if _WIN64
+  #define ENVIRONMENT64
+#else
+  #define ENVIRONMENT32
+#endif
+#endif
+
+// Check GCC
+#if __GNUC__
+#if __x86_64__ || __ppc64__
+  #define ENVIRONMENT64
+#else
+  #define ENVIRONMENT32
+#endif
+#endif
+
+#define METHOD_BUFFERED 0
+#define METHOD_NEITHER  3
+
+#define CTL_CODE(function, method) ((4<< 16) | ((function) << 2) | (method) )
+
+#define FSACTL_SEND_RAW_SRB  CTL_CODE(2067, METHOD_BUFFERED)
+
+#define  SRB_FUNCTION_EXECUTE_SCSI 0X00
+
+#define  SRB_DataIn      0x0040
+#define  SRB_DataOut     0x0080
+#define  SRB_NoDataXfer  0x0000
+
+typedef struct {
+  uint32_t lo32;
+  uint32_t hi32;
+  }  address64;
+
+typedef struct {
+  address64 addr64;
+  uint32_t length;  /* Length. */
+  }  user_sgentry64;
+
+typedef struct {
+  uint32_t addr32;
+  uint32_t length;
+  }  user_sgentry32;
+
+typedef struct {
+  uint32_t         count;
+  user_sgentry64   sg64[1];
+  }  user_sgmap64;
+
+typedef struct {
+  uint32_t         count;
+  user_sgentry32   sg32[1];
+  }  user_sgmap32;
+
+typedef struct {
+  uint32_t function;           //SRB_FUNCTION_EXECUTE_SCSI 0x00
+  uint32_t channel;            //bus
+  uint32_t id;                 //use the ID number this is wrong
+  uint32_t lun;                //Logical unit number
+  uint32_t timeout;
+  uint32_t flags;              //Interesting stuff I must say
+  uint32_t count;              // Data xfer size
+  uint32_t retry_limit;        // We shall see
+  uint32_t cdb_size;           // Length of CDB
+  uint8_t  cdb[16];            // The actual cdb command
+  user_sgmap64 sg64;           // pDatabuffer and address of Databuffer
+  }  user_aac_srb64;
+
+typedef struct {
+  uint32_t function;           //SRB_FUNCTION_EXECUTE_SCSI 0x00
+  uint32_t channel;            //bus
+  uint32_t id;                 //use the ID number this is wrong
+  uint32_t lun;                //Logical unit number
+  uint32_t timeout;
+  uint32_t flags;              //Interesting stuff I must say
+  uint32_t count;              // Data xfer size
+  uint32_t retry_limit;        // We shall see
+  uint32_t cdb_size;           // Length of CDB
+  uint8_t  cdb[16];            // The actual cdb command
+  user_sgmap32 sg32;           // pDatabuffer and address of Databuffer
+  }  user_aac_srb32;
+
+typedef struct {
+  uint32_t status;
+  uint32_t srb_status;
+  uint32_t scsi_status;
+  uint32_t data_xfer_length;
+  uint32_t sense_data_size;
+  uint8_t  sense_data[30];
+  }  user_aac_reply;
index 629ff2e314b70a23f9e392764a0164c8e6900be5..c27e593d3c37fa96f700b167c3042b13fcb4411b 100644 (file)
@@ -4,7 +4,7 @@
  * Home page of code is: http://smartmontools.sourceforge.net
  *
  * Copyright (C) 2002-11 Bruce Allen <smartmontools-support@lists.sourceforge.net>
- * Copyright (C) 2008-13 Christian Franke <smartmontools-support@lists.sourceforge.net>
+ * Copyright (C) 2008-14 Christian Franke <smartmontools-support@lists.sourceforge.net>
  * Copyright (C) 1999-2000 Michael Cornwell <cornwell@acm.org>
  * Copyright (C) 2000 Andre Hedrick <andre@linux-ide.org>
  *
@@ -35,7 +35,7 @@
 #include "utility.h"
 #include "dev_ata_cmd_set.h" // for parsed_ata_device
 
-const char * atacmds_cpp_cvsid = "$Id: atacmds.cpp 3825 2013-07-06 21:38:25Z samm2 $"
+const char * atacmds_cpp_cvsid = "$Id: atacmds.cpp 3971 2014-07-23 18:57:55Z chrfranke $"
                                  ATACMDS_H_CVSID;
 
 // Print ATA debug messages?
@@ -134,7 +134,7 @@ const format_name_entry format_names[] = {
 const unsigned num_format_names = sizeof(format_names)/sizeof(format_names[0]);
 
 // Table to map old to new '-v' option arguments
-const char * map_old_vendor_opts[][2] = {
+const char * const map_old_vendor_opts[][2] = {
   {  "9,halfminutes"              , "9,halfmin2hour,Power_On_Half_Minutes"},
   {  "9,minutes"                  , "9,min2hour,Power_On_Minutes"},
   {  "9,seconds"                  , "9,sec2hour,Power_On_Seconds"},
@@ -172,7 +172,7 @@ bool parse_attribute_def(const char * opt, ata_vendor_attr_defs & defs,
   int id = 0, n1 = -1, n2 = -1;
   char fmtname[32+1], attrname[32+1];
   if (opt[0] == 'N') {
-    // "N,format"
+    // "N,format[,name]"
     if (!(   sscanf(opt, "N,%32[^,]%n,%32[^,]%n", fmtname, &n1, attrname, &n2) >= 1
           && (n1 == len || n2 == len)))
       return false;
@@ -196,6 +196,7 @@ bool parse_attribute_def(const char * opt, ata_vendor_attr_defs & defs,
   // Split "format[:byteorder]"
   char byteorder[8+1] = "";
   if (strchr(fmtname, ':')) {
+    n1 = n2 = -1;
     if (!(   sscanf(fmtname, "%*[^:]%n:%8[012345rvwz]%n", &n1, byteorder, &n2) >= 1
           && n2 == (int)strlen(fmtname)))
       return false;
@@ -598,8 +599,7 @@ int smartcommandhandler(ata_device * device, smart_command_set command, int sele
                  "probable SAT/USB truncation\n");
         }
         else if (!out.out_regs.is_set()) {
-          pout("SMART STATUS RETURN: incomplete response, ATA output registers missing\n");
-          device->set_err(ENOSYS);
+          device->set_err(ENOSYS, "Incomplete response, ATA output registers missing");
           retval = -1;
         }
         else {
@@ -608,7 +608,7 @@ int smartcommandhandler(ata_device * device, smart_command_set command, int sele
           pout("Please get assistance from %s\n", PACKAGE_HOMEPAGE);
           pout("Register values returned from SMART Status command are:\n");
           print_regs(" ", out.out_regs);
-          device->set_err(EIO);
+          device->set_err(ENOSYS, "Invalid ATA output register values");
           retval = -1;
         }
         break;
@@ -1274,9 +1274,9 @@ int ataWriteSelectiveSelfTestLog(ata_device * device, ata_selective_selftest_arg
             uint64_t spans = (num_sectors + oldsize-1) / oldsize;
             uint64_t newsize = (num_sectors + spans-1) / spans;
             uint64_t newstart = num_sectors - newsize, newend = num_sectors - 1;
-            pout("Span %d changed from %"PRIu64"-%"PRIu64" (%"PRIu64" sectors)\n",
+            pout("Span %d changed from %" PRIu64 "-%" PRIu64 " (%" PRIu64 " sectors)\n",
                  i, start, end, oldsize);
-            pout("                 to %"PRIu64"-%"PRIu64" (%"PRIu64" sectors) (%"PRIu64" spans)\n",
+            pout("                 to %" PRIu64 "-%" PRIu64 " (%" PRIu64 " sectors) (%" PRIu64 " spans)\n",
                  newstart, newend, newsize, spans);
             start = newstart; end = newend;
           }
@@ -1293,7 +1293,7 @@ int ataWriteSelectiveSelfTestLog(ata_device * device, ata_selective_selftest_arg
       end = num_sectors - 1;
     }
     if (!(start <= end && end < num_sectors)) {
-      pout("Invalid selective self-test span %d: %"PRIu64"-%"PRIu64" (%"PRIu64" sectors)\n",
+      pout("Invalid selective self-test span %d: %" PRIu64 "-%" PRIu64 " (%" PRIu64 " sectors)\n",
         i, start, end, num_sectors);
       return -1;
     }
@@ -1476,11 +1476,12 @@ bool ataReadExtErrorLog(ata_device * device, ata_smart_exterrlog * log,
   if (isbigendian()) {
     swapx(&log->device_error_count);
     swapx(&log->error_log_index);
-
     for (unsigned i = 0; i < nsectors; i++) {
-      for (unsigned j = 0; j < 4; j++)
-        swapx(&log->error_logs[i].commands[j].timestamp);
-      swapx(&log->error_logs[i].error.timestamp);
+      for (unsigned j = 0; j < 4; j++) {
+        for (unsigned k = 0; k < 5; k++)
+           swapx(&log[i].error_logs[j].commands[k].timestamp);
+        swapx(&log[i].error_logs[j].error.timestamp);
+      }
     }
   }
 
@@ -1648,7 +1649,7 @@ int ataSmartTest(ata_device * device, int testtype, bool force,
     int i;
     pout("SPAN         STARTING_LBA           ENDING_LBA\n");
     for (i = 0; i < selargs_io.num_spans; i++)
-      pout("   %d %20"PRId64" %20"PRId64"\n", i,
+      pout("   %d %20" PRId64 " %20" PRId64 "\n", i,
            selargs_io.span[i].start,
            selargs_io.span[i].end);
   }
@@ -1869,7 +1870,8 @@ static ata_attr_raw_format get_default_raw_format(unsigned char id)
   case 196: // Reallocated event count
     return RAWFMT_RAW16_OPT_RAW16;
 
-  case 9:  // Power on hours
+  case 9:   // Power on hours
+  case 240: // Head flying hours
     return RAWFMT_RAW24_OPT_RAW8;
 
   case 190: // Temperature
@@ -1926,6 +1928,33 @@ uint64_t ata_get_attr_raw_value(const ata_smart_attribute & attr,
   return rawvalue;
 }
 
+// Helper functions for RAWFMT_TEMPMINMAX
+static inline int check_temp_word(unsigned word)
+{
+  if (word <= 0x7f)
+    return 0x11; // >= 0, signed byte or word
+  if (word <= 0xff)
+    return 0x01; // < 0, signed byte
+  if (0xff80 <= word)
+    return 0x10; // < 0, signed word
+  return 0x00;
+}
+
+static bool check_temp_range(int t, unsigned char ut1, unsigned char ut2,
+                             int & lo, int & hi)
+{
+  int t1 = (signed char)ut1, t2 = (signed char)ut2;
+  if (t1 > t2) {
+    int tx = t1; t1 = t2; t2 = tx;
+  }
+
+  if (   -60 <= t1 && t1 <= t && t <= t2 && t2 <= 120
+      && !(t1 == -1 && t2 <= 0)                      ) {
+    lo = t1; hi = t2;
+    return true;
+  }
+  return false;
+}
 
 // Format attribute raw value.
 std::string ata_format_attr_raw_value(const ata_smart_attribute & attr,
@@ -1967,19 +1996,19 @@ std::string ata_format_attr_raw_value(const ata_smart_attribute & attr,
   case RAWFMT_RAW48:
   case RAWFMT_RAW56:
   case RAWFMT_RAW64:
-    s = strprintf("%"PRIu64, rawvalue);
+    s = strprintf("%" PRIu64, rawvalue);
     break;
 
   case RAWFMT_HEX48:
-    s = strprintf("0x%012"PRIx64, rawvalue);
+    s = strprintf("0x%012" PRIx64, rawvalue);
     break;
 
   case RAWFMT_HEX56:
-    s = strprintf("0x%014"PRIx64, rawvalue);
+    s = strprintf("0x%014" PRIx64, rawvalue);
     break;
 
   case RAWFMT_HEX64:
-    s = strprintf("0x%016"PRIx64, rawvalue);
+    s = strprintf("0x%016" PRIx64, rawvalue);
     break;
 
   case RAWFMT_RAW16_OPT_RAW16:
@@ -2016,7 +2045,7 @@ std::string ata_format_attr_raw_value(const ata_smart_attribute & attr,
       int64_t temp = word[0]+(word[1]<<16);
       int64_t tmp1 = temp/60;
       int64_t tmp2 = temp%60;
-      s = strprintf("%"PRIu64"h+%02"PRIu64"m", tmp1, tmp2);
+      s = strprintf("%" PRIu64 "h+%02" PRIu64 "m", tmp1, tmp2);
       if (word[2])
         s += strprintf(" (%u)", word[2]);
     }
@@ -2028,7 +2057,7 @@ std::string ata_format_attr_raw_value(const ata_smart_attribute & attr,
       int64_t hours = rawvalue/3600;
       int64_t minutes = (rawvalue-3600*hours)/60;
       int64_t seconds = rawvalue%60;
-      s = strprintf("%"PRIu64"h+%02"PRIu64"m+%02"PRIu64"s", hours, minutes, seconds);
+      s = strprintf("%" PRIu64 "h+%02" PRIu64 "m+%02" PRIu64 "s", hours, minutes, seconds);
     }
     break;
 
@@ -2037,7 +2066,7 @@ std::string ata_format_attr_raw_value(const ata_smart_attribute & attr,
       // 30-second counter
       int64_t hours = rawvalue/120;
       int64_t minutes = (rawvalue-120*hours)/2;
-      s += strprintf("%"PRIu64"h+%02"PRIu64"m", hours, minutes);
+      s += strprintf("%" PRIu64 "h+%02" PRIu64 "m", hours, minutes);
     }
     break;
 
@@ -2056,34 +2085,63 @@ std::string ata_format_attr_raw_value(const ata_smart_attribute & attr,
     // Temperature
     {
       // Search for possible min/max values
-      // 00 HH 00 LL 00 TT (Hitachi/IBM)
-      // 00 00 HH LL 00 TT (Maxtor, Samsung)
+      // [5][4][3][2][1][0] raw[]
+      // [ 2 ] [ 1 ] [ 0 ]  word[]
+      // xx HH xx LL xx TT (Hitachi/HGST)
+      // xx LL xx HH xx TT (Kingston SSDs)
+      // 00 00 HH LL xx TT (Maxtor, Samsung, Seagate, Toshiba)
       // 00 00 00 HH LL TT (WDC)
-      unsigned char lo = 0, hi = 0;
-      int cnt = 0;
-      for (int i = 1; i < 6; i++) {
-        if (raw[i])
-          switch (cnt++) {
-            case 0:
-              lo = raw[i];
-              break;
-            case 1:
-              if (raw[i] < lo) {
-                hi = lo; lo = raw[i];
-              }
-              else
-                hi = raw[i];
-              break;
-          }
+      // CC CC HH LL xx TT (WDC, CCCC=over temperature count)
+      // (xx = 00/ff, possibly sign extension of lower byte)
+
+      int t = (signed char)raw[0];
+      int lo = 0, hi = 0;
+
+      int tformat;
+      int ctw0 = check_temp_word(word[0]);
+      if (!word[2]) {
+        if (!word[1] && ctw0)
+          // 00 00 00 00 xx TT
+          tformat = 0;
+        else if (ctw0 && check_temp_range(t, raw[2], raw[3], lo, hi))
+          // 00 00 HL LH xx TT
+          tformat = 1;
+        else if (!raw[3] && check_temp_range(t, raw[1], raw[2], lo, hi))
+          // 00 00 00 HL LH TT
+          tformat = 2;
+        else
+          tformat = -1;
+      }
+      else if (ctw0) {
+        if (   (ctw0 & check_temp_word(word[1]) & check_temp_word(word[2])) != 0x00
+            && check_temp_range(t, raw[2], raw[4], lo, hi)                         )
+          // xx HL xx LH xx TT
+          tformat = 3;
+        else if (   word[2] < 0x7fff
+                 && check_temp_range(t, raw[2], raw[3], lo, hi)
+                 && hi >= 40                                   )
+          // CC CC HL LH xx TT
+          tformat = 4;
+        else
+          tformat = -2;
       }
-
-      unsigned char t = raw[0];
-      if (cnt == 0)
-        s = strprintf("%d", t);
-      else if (cnt == 2 && 0 < lo && lo <= t && t <= hi && hi < 128)
-        s = strprintf("%d (Min/Max %d/%d)", t, lo, hi);
       else
-        s = strprintf("%d (%d %d %d %d %d)", t, raw[5], raw[4], raw[3], raw[2], raw[1]);
+        tformat = -3;
+
+      switch (tformat) {
+        case 0:
+          s = strprintf("%d", t);
+          break;
+        case 1: case 2: case 3:
+          s = strprintf("%d (Min/Max %d/%d)", t, lo, hi);
+          break;
+        case 4:
+          s = strprintf("%d (Min/Max %d/%d #%d)", t, lo, hi, word[2]);
+          break;
+        default:
+          s = strprintf("%d (%d %d %d %d %d)", raw[0], raw[5], raw[4], raw[3], raw[2], raw[1]);
+          break;
+      }
     }
     break;
 
@@ -2380,13 +2438,11 @@ int ataReadSCTStatus(ata_device * device, ata_sct_status_response * sts)
   return 0;
 }
 
-// Read SCT Temperature History Table and Status
+// Read SCT Temperature History Table
 int ataReadSCTTempHist(ata_device * device, ata_sct_temperature_history_table * tmh,
                        ata_sct_status_response * sts)
 {
-  // Check initial status
-  if (ataReadSCTStatus(device, sts))
-    return -1;
+  // Initial SCT status must be provided by caller
 
   // Do nothing if other SCT command is executing
   if (sts->ext_status_code == 0xffff) {
@@ -2491,7 +2547,7 @@ int ataGetSetSCTWriteCacheReordering(ata_device * device, bool enable, bool pers
 
   ata_cmd_out out;
   if (!device->ata_pass_through(in, out)) {
-    pout("Write SCT (%cet) XXX Error Recovery Control Command failed: %s\n",
+    pout("Write SCT (%cet) Feature Control Command failed: %s\n",
       (!set ? 'G' : 'S'), device->get_errmsg());
     return -1;
   }
@@ -2729,7 +2785,7 @@ int ataPrintSmartSelfTestEntry(unsigned testnum, unsigned char test_type,
 
   char msglba[32];
   if (retval < 0 && failing_lba < 0xffffffffffffULL)
-    snprintf(msglba, sizeof(msglba), "%"PRIu64, failing_lba);
+    snprintf(msglba, sizeof(msglba), "%" PRIu64, failing_lba);
   else {
     msglba[0] = '-'; msglba[1] = 0;
   }
@@ -2753,7 +2809,7 @@ int ataPrintSmartSelfTestlog(const ata_smart_selftestlog * data, bool allentries
     pout("Warning: ATA Specification requires self-test log structure revision number = 1\n");
   if (data->mostrecenttest==0){
     if (allentries)
-      pout("No self-tests have been logged.  [To run self-tests, use: smartctl -t]\n\n");
+      pout("No self-tests have been logged.  [To run self-tests, use: smartctl -t]\n");
     return 0;
   }
 
index 900cd20e35f281bcc3517478dcb2a12b71e1f5b5..fb47ae1aede6a36e81b9ded4f098ff61279c99f8 100644 (file)
@@ -18,7 +18,7 @@
 #include "config.h"
 #include "ataidentify.h"
 
-const char * ataidentify_cpp_cvsid = "$Id: ataidentify.cpp 3785 2013-03-07 21:58:05Z chrfranke $"
+const char * ataidentify_cpp_cvsid = "$Id: ataidentify.cpp 3851 2013-08-17 20:10:11Z chrfranke $"
   ATAIDENTIFY_H_CVSID;
 
 #include "int64.h"
@@ -683,9 +683,9 @@ void ata_print_identify_data(const void * id, bool all_words, int bit_level)
             if (word + 1 == word2 && strstr(desc, "(DWord)"))
               pout("  (%u)\n", ((unsigned)get_word(id, word2) << 16) | w);
             else if (word + 3 == word2 && strstr(desc, "(QWord)"))
-              pout("  (%"PRIu64")\n", ((uint64_t)get_word(id, word + 3) << 48)
-                                    | ((uint64_t)get_word(id, word + 2) << 32)
-                                    | ((unsigned)get_word(id, word + 1) << 16) | (unsigned)w);
+              pout("  (%" PRIu64 ")\n", ((uint64_t)get_word(id, word + 3) << 48)
+                                      | ((uint64_t)get_word(id, word + 2) << 32)
+                                      | ((unsigned)get_word(id, word + 1) << 16) | (unsigned)w);
             else
               pout("\n");
           }
index 9239dcaf36ce8e016f2016a62063fd57269167a2..7b6ed2cc6c8b6f47668b877a15a10ba8913d16cb 100644 (file)
@@ -4,7 +4,7 @@
  * Home page of code is: http://smartmontools.sourceforge.net
  *
  * Copyright (C) 2002-11 Bruce Allen <smartmontools-support@lists.sourceforge.net>
- * Copyright (C) 2008-13 Christian Franke <smartmontools-support@lists.sourceforge.net>
+ * Copyright (C) 2008-14 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
@@ -40,7 +40,7 @@
 #include "utility.h"
 #include "knowndrives.h"
 
-const char * ataprint_cpp_cvsid = "$Id: ataprint.cpp 3831 2013-07-20 14:25:56Z chrfranke $"
+const char * ataprint_cpp_cvsid = "$Id: ataprint.cpp 3982 2014-08-16 21:07:19Z samm2 $"
                                   ATAPRINT_H_CVSID;
 
 
@@ -380,7 +380,7 @@ static std::string format_st_er_desc(
       lba48  |= lba48_regs->lba_mid_register;
       lba48 <<= 8;
       lba48  |= lba48_regs->lba_low_register;
-      str += strprintf(" at LBA = 0x%08"PRIx64" = %"PRIu64, lba48, lba48);
+      str += strprintf(" at LBA = 0x%08" PRIx64 " = %" PRIu64, lba48, lba48);
     }
   }
 
@@ -565,7 +565,7 @@ static void print_drive_info(const ata_identify_device * drive,
     unsigned oui = 0; uint64_t unique_id = 0;
     int naa = ata_get_wwn(drive, oui, unique_id);
     if (naa >= 0)
-      pout("LU WWN Device Id: %x %06x %09"PRIx64"\n", naa, oui, unique_id);
+      pout("LU WWN Device Id: %x %06x %09" PRIx64 "\n", naa, oui, unique_id);
 
     // Additional Product Identifier (OEM Id) string in words 170-173
     // (e08130r1, added in ACS-2 Revision 1, December 17, 2008)
@@ -607,6 +607,24 @@ static void print_drive_info(const ata_identify_device * drive,
       pout("Rotation Rate:    Unknown (0x%04x)\n", -rpm);
   }
 
+  // Print form factor if reported
+  unsigned short word168 = drive->words088_255[168-88];
+  if (word168) {
+    const char * inches;
+    switch (word168) {
+      case 0x1: inches = "5.25"; break;
+      case 0x2: inches = "3.5"; break;
+      case 0x3: inches = "2.5"; break;
+      case 0x4: inches = "1.8"; break;
+      case 0x5: inches = "< 1.8"; break;
+      default : inches = 0;
+    }
+    if (inches)
+      pout("Form Factor:      %s inches\n", inches);
+    else
+      pout("Form Factor:      Unknown (0x%04x)\n", word168);
+  }
+
   // See if drive is recognized
   pout("Device is:        %s\n", !dbentry ?
        "Not in smartctl database [for details use: -P showall]":
@@ -1124,7 +1142,7 @@ static const char * GetLogName(unsigned logaddr)
       case 0x09: return "Selective self-test log";
       case 0x0a: return "Device Statistics Notification"; // ACS-3
       case 0x0b: return "Reserved for CFA"; // ACS-3
-
+      case 0x0c: return "Pending Defects log"; // ACS-4
       case 0x0d: return "LPS Mis-alignment log"; // ACS-2
 
       case 0x10: return "NCQ Command Error log";
@@ -1133,7 +1151,8 @@ static const char * GetLogName(unsigned logaddr)
       case 0x13: return "SATA NCQ Send and Receive log"; // ACS-3
       case 0x14:
       case 0x15:
-      case 0x16: return "Reserved for Serial ATA";
+      case 0x16:
+      case 0x17: return "Reserved for Serial ATA";
 
       case 0x19: return "LBA Status log"; // ACS-3
 
@@ -1162,7 +1181,7 @@ static const char * GetLogName(unsigned logaddr)
 static const char * get_log_rw(unsigned logaddr)
 {
    if (   (                   logaddr <= 0x08)
-       || (0x0d == logaddr)
+       || (0x0c <= logaddr && logaddr <= 0x0d)
        || (0x10 <= logaddr && logaddr <= 0x13)
        || (0x19 == logaddr)
        || (0x20 <= logaddr && logaddr <= 0x25)
@@ -1421,6 +1440,12 @@ static void print_device_statistics_page(const unsigned char * data, int page,
     if (!(flags & 0x80))
       continue;
 
+    // Stop if unknown entries contain garbage data due to buggy firmware
+    if (!info && (data[offset+5] || data[offset+6])) {
+      pout("%3d  0x%03x  -                -  [Trailing garbage ignored]\n", page, offset);
+      break;
+    }
+
     // Get value size, default to max if unknown
     int size = (info ? info[i].size : 7);
 
@@ -1437,7 +1462,7 @@ static void print_device_statistics_page(const unsigned char * data, int page,
         for (int j = 0; j < size; j++)
           val |= (int64_t)data[offset+j] << (j*8);
       }
-      snprintf(valstr, sizeof(valstr), "%"PRId64, val);
+      snprintf(valstr, sizeof(valstr), "%" PRId64, val);
     }
     else {
       // Value not known (yet)
@@ -1457,11 +1482,18 @@ static void print_device_statistics_page(const unsigned char * data, int page,
 }
 
 static bool print_device_statistics(ata_device * device, unsigned nsectors,
-  const std::vector<int> & single_pages, bool all_pages, bool ssd_page)
+  const std::vector<int> & single_pages, bool all_pages, bool ssd_page,
+  bool use_gplog)
 {
   // Read list of supported pages from page 0
   unsigned char page_0[512] = {0, };
-  if (!ataReadLogExt(device, 0x04, 0, 0, page_0, 1)) {
+  int rc;
+  
+  if (use_gplog)
+    rc = ataReadLogExt(device, 0x04, 0, 0, page_0, 1);
+  else
+    rc = ataReadSmartLog(device, 0x04, page_0, 1);
+  if (!rc) {
     pout("Read Device Statistics page 0 failed\n\n");
     return false;
   }
@@ -1500,7 +1532,8 @@ static bool print_device_statistics(ata_device * device, unsigned nsectors,
 
   // Print list of supported pages if requested
   if (print_page_0) {
-    pout("Device Statistics (GP Log 0x04) supported pages\n");
+    pout("Device Statistics (%s Log 0x04) supported pages\n", 
+      use_gplog ? "GP" : "SMART");
     pout("Page Description\n");
     for (i = 0; i < nentries; i++) {
       int page = page_0[8+1+i];
@@ -1512,18 +1545,35 @@ static bool print_device_statistics(ata_device * device, unsigned nsectors,
 
   // Read & print pages
   if (!pages.empty()) {
-    pout("Device Statistics (GP Log 0x04)\n");
+    pout("Device Statistics (%s Log 0x04)\n",
+      use_gplog ? "GP" : "SMART");
     pout("Page Offset Size         Value  Description\n");
     bool need_trailer = false;
+    int max_page = 0;
+    
+    if (!use_gplog)
+    for (i = 0; i < pages.size(); i++) {
+      int page = pages[i];
+      if (max_page < page && page < 0xff)
+        max_page = page;
+    }
+    
+    raw_buffer pages_buf((max_page+1) * 512);
+
+     if (!use_gplog && !ataReadSmartLog(device, 0x04, pages_buf.data(), max_page+1)) {
+      pout("Read Device Statistics pages 0-%d failed\n\n", max_page);
+      return false;
+    }
 
     for (i = 0; i <  pages.size(); i++) {
       int page = pages[i];
-      unsigned char page_n[512] = {0, };
-      if (!ataReadLogExt(device, 0x04, 0, page, page_n, 1)) {
+      if (use_gplog && !ataReadLogExt(device, 0x04, 0, page, pages_buf.data(), 1)) {
         pout("Read Device Statistics page %d failed\n\n", page);
         return false;
       }
-      print_device_statistics_page(page_n, page, need_trailer);
+
+      int offset = (use_gplog ? 0 : page * 512);
+      print_device_statistics_page(pages_buf.data() + offset, page, need_trailer);
     }
 
     if (need_trailer)
@@ -1595,7 +1645,7 @@ static void PrintSataPhyEventCounters(const unsigned char * data, bool reset)
     }
 
     // Counters stop at max value, add '+' in this case
-    pout("0x%04x  %u %12"PRIu64"%c %s\n", id, size, val,
+    pout("0x%04x  %u %12" PRIu64 "%c %s\n", id, size, val,
       (val == max_val ? '+' : ' '), name);
   }
   if (reset)
@@ -2034,9 +2084,9 @@ static void ataPrintSelectiveSelfTestLog(const ata_selective_self_test_log * log
   
   // we need at least 7 characters wide fields to accomodate the
   // labels
-  if ((field1=snprintf(tmp,64, "%"PRIu64, maxl))<7)
+  if ((field1=snprintf(tmp,64, "%" PRIu64, maxl))<7)
     field1=7;
-  if ((field2=snprintf(tmp,64, "%"PRIu64, maxr))<7)
+  if ((field2=snprintf(tmp,64, "%" PRIu64, maxr))<7)
     field2=7;
 
   // now print the five test spans
@@ -2048,19 +2098,19 @@ static void ataPrintSelectiveSelfTestLog(const ata_selective_self_test_log * log
     
     if ((i+1)==(int)log->currentspan)
       // this span is currently under test
-      pout("    %d  %*"PRIu64"  %*"PRIu64"  %s [%01d0%% left] (%"PRIu64"-%"PRIu64")\n",
+      pout("    %d  %*" PRIu64 "  %*" PRIu64 "  %s [%01d0%% left] (%" PRIu64 "-%" PRIu64 ")\n",
           i+1, field1, start, field2, end, msg,
           (int)(sv->self_test_exec_status & 0xf), current, currentend);
     else
       // this span is not currently under test
-      pout("    %d  %*"PRIu64"  %*"PRIu64"  Not_testing\n",
+      pout("    %d  %*" PRIu64 "  %*" PRIu64 "  Not_testing\n",
           i+1, field1, start, field2, end);
   }  
   
   // if we are currently read-scanning, print LBAs and the status of
   // the read scan
   if (log->currentspan>5)
-    pout("%5d  %*"PRIu64"  %*"PRIu64"  Read_scanning %s\n",
+    pout("%5d  %*" PRIu64 "  %*" PRIu64 "  Read_scanning %s\n",
         (int)log->currentspan, field1, current, field2, currentend,
         OfflineDataCollectionStatus(sv->offline_data_collection_status));
   
@@ -2431,7 +2481,12 @@ int ataPrintMain (ata_device * device, const ata_print_options & options)
   );
 
   // SMART and GP log directories needed ?
-  bool need_smart_logdir = options.smart_logdir;
+  bool need_smart_logdir = ( 
+          options.smart_logdir
+       || options.devstat_all_pages // devstat fallback to smartlog if needed
+       || options.devstat_ssd_page
+       || !options.devstat_pages.empty()
+    );
 
   bool need_gp_logdir  = (
           options.gp_logdir
@@ -2618,35 +2673,22 @@ int ataPrintMain (ata_device * device, const ata_print_options & options)
   if (options.get_security)
     print_ata_security_status("ATA Security is:  ", drive.words088_255[128-88]);
 
-  // Check if SCT commands available
-  bool sct_ok = false;
-  if (need_sct_support) {
-    if (!isSCTCapable(&drive)) {
-      failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
+  // Print write cache reordering status
+  if (options.sct_wcache_reorder_get) {
+    if (isSCTFeatureControlCapable(&drive)) {
+      int wcache_reorder = ataGetSetSCTWriteCacheReordering(device,
+        false /*enable*/, false /*persistent*/, false /*set*/);
+
+      if (-1 <= wcache_reorder && wcache_reorder <= 2)
+        pout("Wt Cache Reorder: %s\n",
+          (wcache_reorder == -1 ? "Unknown (SCT Feature Control command failed)" :
+           wcache_reorder == 0  ? "Unknown" : // not defined in standard but returned on some drives if not set
+           wcache_reorder == 1  ? "Enabled" : "Disabled"));
+      else
+        pout("Wt Cache Reorder: Unknown (0x%02x)\n", wcache_reorder);
     }
     else
-      sct_ok = true;
-  }
-
-  // Print write cache reordering status
-  if (sct_ok && options.sct_wcache_reorder_get) {
-    int wcache_reorder=ataGetSetSCTWriteCacheReordering(device,
-      false /* enable */, false /* persistent */, false /*set*/);
-      pout("Wt Cache Reorder: ");
-      switch(wcache_reorder) {
-        case 0: /* not defined in standard but returned on some drives if not set */
-        pout("Unknown"); break;
-        case 1:
-        pout("Enabled"); break;
-        case 2:
-        pout("Disabled"); break;
-        default: /* error? */
-        pout("N/A"); break;
-      }
-      pout("\n");
-  }
-  if (!sct_ok && options.sct_wcache_reorder_get) {
-    pout("Wt Cache Reorder: Unavailable\n");
+      pout("Wt Cache Reorder: Unavailable\n");
   }
 
   // Print remaining drive info
@@ -2733,15 +2775,15 @@ int ataPrintMain (ata_device * device, const ata_print_options & options)
   }
 
   // Enable/Disable write cache reordering
-  if (sct_ok && options.sct_wcache_reorder_set) {
+  if (options.sct_wcache_reorder_set) {
     bool enable = (options.sct_wcache_reorder_set > 0);
-
-    int wcache_reorder=ataGetSetSCTWriteCacheReordering(device,
-      enable, false /* persistent */, true /*set*/);
-
-    if (wcache_reorder < 0) {
-        pout("Write cache reordering %sable failed: %s\n", (enable ? "en" : "dis"), device->get_errmsg());
-        returnval |= FAILSMART;
+    if (!isSCTFeatureControlCapable(&drive))
+      pout("Write cache reordering %sable failed: SCT Feature Control command not supported\n",
+        (enable ? "en" : "dis"));
+    else if (ataGetSetSCTWriteCacheReordering(device,
+               enable, false /*persistent*/, true /*set*/) < 0) {
+      pout("Write cache reordering %sable failed: %s\n", (enable ? "en" : "dis"), device->get_errmsg());
+      returnval |= FAILSMART;
     }
     else
       pout("Write cache reordering %sabled\n", (enable ? "en" : "dis"));
@@ -2941,7 +2983,11 @@ int ataPrintMain (ata_device * device, const ata_print_options & options)
       // The ATA SMART RETURN STATUS command provides the result in the ATA output
       // registers. Buggy ATA/SATA drivers and SAT Layers often do not properly
       // return the registers values.
+      pout("SMART Status %s: %s\n",
+           (device->is_syscall_unsup() ? "not supported" : "command failed"),
+           device->get_errmsg());
       failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
+
       if (!(smart_val_ok && smart_thres_ok)) {
         print_on();
         pout("SMART overall-health self-assessment test result: UNKNOWN!\n"
@@ -2951,6 +2997,7 @@ int ataPrintMain (ata_device * device, const ata_print_options & options)
         print_on();
         pout("SMART overall-health self-assessment test result: FAILED!\n"
              "Drive failure expected in less than 24 hours. SAVE ALL DATA.\n");
+        pout("Warning: This result is based on an Attribute check.\n");
         print_off();
         returnval|=FAILATTR;
         returnval|=FAILSTATUS;
@@ -3217,6 +3264,8 @@ int ataPrintMain (ata_device * device, const ata_print_options & options)
     }
   }
 
+  // Check if SCT commands available
+  bool sct_ok = isSCTCapable(&drive);
   if(!sct_ok && (options.sct_temp_sts || options.sct_temp_hist || options.sct_temp_int
                  || options.sct_erc_get || options.sct_erc_set                        ))
     pout("SCT Commands not supported\n\n");
@@ -3224,35 +3273,41 @@ int ataPrintMain (ata_device * device, const ata_print_options & options)
   // Print SCT status and temperature history table
   if (sct_ok && (options.sct_temp_sts || options.sct_temp_hist || options.sct_temp_int)) {
     for (;;) {
-      if (options.sct_temp_sts || options.sct_temp_hist) {
-        ata_sct_status_response sts;
-        ata_sct_temperature_history_table tmh;
-        if (!options.sct_temp_hist) {
-          // Read SCT status only
-          if (ataReadSCTStatus(device, &sts)) {
-            failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
-            break;
-          }
-        }
-        else {
-          if (!isSCTDataTableCapable(&drive)) {
-            pout("SCT Data Table command not supported\n\n");
-            failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
-            break;
-          }
-          // Read SCT status and temperature history
-          if (ataReadSCTTempHist(device, &tmh, &sts)) {
-            pout("Read SCT Temperature History failed\n\n");
-            failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
-            break;
-          }
+      bool sct_temp_hist_ok = isSCTDataTableCapable(&drive);
+      ata_sct_status_response sts;
+
+      if (options.sct_temp_sts || (options.sct_temp_hist && sct_temp_hist_ok)) {
+        // Read SCT status
+        if (ataReadSCTStatus(device, &sts)) {
+          pout("\n");
+          failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
+          break;
         }
-        if (options.sct_temp_sts)
+        if (options.sct_temp_sts) {
           ataPrintSCTStatus(&sts);
-        if (options.sct_temp_hist)
-          ataPrintSCTTempHist(&tmh);
+          pout("\n");
+        }
+      }
+
+      if (!sct_temp_hist_ok && (options.sct_temp_hist || options.sct_temp_int)) {
+        pout("SCT Data Table command not supported\n\n");
+        failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
+        break;
+      }
+
+      if (options.sct_temp_hist) {
+        // Read SCT temperature history,
+        // requires initial SCT status from above
+        ata_sct_temperature_history_table tmh;
+        if (ataReadSCTTempHist(device, &tmh, &sts)) {
+          pout("Read SCT Temperature History failed\n\n");
+          failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
+          break;
+        }
+        ataPrintSCTTempHist(&tmh);
         pout("\n");
       }
+
       if (options.sct_temp_int) {
         // Set new temperature logging interval
         if (!isSCTFeatureControlCapable(&drive)) {
@@ -3319,11 +3374,18 @@ int ataPrintMain (ata_device * device, const ata_print_options & options)
 
   // Print Device Statistics
   if (options.devstat_all_pages || options.devstat_ssd_page || !options.devstat_pages.empty()) {
-    unsigned nsectors = GetNumLogSectors(gplogdir, 0x04, true);
+    bool use_gplog = true;
+    unsigned nsectors = 0;
+    if (gplogdir) 
+      nsectors = GetNumLogSectors(gplogdir, 0x04, false);
+    else if (smartlogdir){ // for systems without ATA_READ_LOG_EXT
+      nsectors = GetNumLogSectors(smartlogdir, 0x04, false);
+      use_gplog = false;
+    }
     if (!nsectors)
-      pout("Device Statistics (GP Log 0x04) not supported\n\n");
+      pout("Device Statistics (GP/SMART Log 0x04) not supported\n\n");
     else if (!print_device_statistics(device, nsectors, options.devstat_pages,
-               options.devstat_all_pages, options.devstat_ssd_page))
+               options.devstat_all_pages, options.devstat_ssd_page, use_gplog))
       failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
   }
 
index 0a472d2c10f5c0d2e0bb748545b1e9ff3c411149..8fe3859bf372e1fcba28e02387f8bb36794a0606 100755 (executable)
@@ -1,11 +1,17 @@
 #!/bin/sh
-# $Id: autogen.sh 3829 2013-07-08 15:13:16Z samm2 $
+# $Id: autogen.sh 3917 2014-06-20 19:57:41Z chrfranke $
 #
 # Generate ./configure from config.in and Makefile.in from Makefile.am.
 # This also adds files like missing,depcomp,install-sh to the source
 # directory. To update these files at a later date use:
 #      autoreconf -f -i -v
 
+force=; warnings=
+while [ $# -gt 0 ]; do case $1 in
+  --force) force=$1; shift ;;
+  --warnings=?*) warnings="${warnings} $1"; shift ;;
+  *) echo "Usage: $0 [--force] [--warnings=CATEGORY ...]"; exit 1 ;;
+esac; done
 
 # Cygwin?
 test -x /usr/bin/uname && /usr/bin/uname | grep -i CYGWIN >/dev/null &&
@@ -32,19 +38,21 @@ typep()
     return 1
 }
 
-test -x "$AUTOMAKE" || AUTOMAKE=`typep automake-1.12` ||
+test -x "$AUTOMAKE" ||
+    AUTOMAKE=`typep automake-1.14` ||
+    AUTOMAKE=`typep automake-1.13` || AUTOMAKE=`typep automake-1.12` ||
     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.11) installed"
+echo "You must have at least GNU Automake 1.7 (up to 1.14) 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.11) is only added after extensive tests. If you live in"
+echo "than 1.14) 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;
@@ -70,6 +78,7 @@ case "$AUTOMAKE" in
 esac
 
 # Warn if Automake version was not tested or does not support filesystem
+amwarnings=$warnings
 case "$ver" in
   1.[78]|1.[78].*)
     # Check for case sensitive filesystem
@@ -84,10 +93,16 @@ case "$ver" in
     rm -f casetest.tmp
     ;;
 
-  1.9.[1-6]|1.10|1.10.[12]|1.11|1.11.[1-6]|1.12.[2-5])
+  1.9.[1-6]|1.10|1.10.[123]|1.11|1.11.[1-6]|1.12.[2-6]|1.13.[34])
     # OK
     ;;
 
+  1.14|1.14.1)
+    # TODO: Enable 'subdir-objects' in configure.ac
+    # For now, suppress 'subdir-objects' forward-incompatibility warning
+    test -n "$warnings" || amwarnings="--warnings=no-unsupported"
+    ;;
+
   *)
     echo "Note: GNU Automake version ${ver} was not tested by the developers."
     echo "Please report success/failure to the smartmontools-support mailing list."
@@ -96,6 +111,7 @@ esac
 # Install pkg-config macros
 # (Don't use 'aclocal -I m4 --install' to keep support for automake < 1.10)
 test -d m4 || mkdir m4 || exit 1
+test -z "$force" || rm -f m4/pkg.m4
 test -f m4/pkg.m4 || acdir=`${ACLOCAL} --print-ac-dir` &&
   test -n "$acdir" && test -f "$acdir/pkg.m4" &&
 {
@@ -107,7 +123,9 @@ test -f m4/pkg.m4 ||
 
 set -e # stops on error status
 
-${ACLOCAL} -I m4
-autoheader
-${AUTOMAKE} --add-missing --copy
-autoconf
+test -z "$warnings" || set -x
+
+${ACLOCAL} -I m4 $force $warnings
+autoheader $force $warnings
+${AUTOMAKE} --add-missing --copy ${force:+--force-missing} $amwarnings
+autoconf $force $warnings
index 7d039b18dbf516d26cb7c4c2712aa4a3b2fab548..bf074ed88baceb258e9286e132b4c8473c64564f 100644 (file)
--- a/cciss.cpp
+++ b/cciss.cpp
@@ -5,7 +5,7 @@
 
 #include "config.h"
 
-#if defined(linux)
+#if defined(linux) || defined(__linux__)
 #  include <sys/ioctl.h>
 #  ifdef HAVE_LINUX_COMPILER_H
 #    include <linux/compiler.h>
@@ -38,7 +38,7 @@
 #include "scsicmds.h"
 #include "utility.h"
 
-const char * cciss_cpp_cvsid = "$Id: cciss.cpp 3578 2012-07-20 17:26:32Z chrfranke $"
+const char * cciss_cpp_cvsid = "$Id: cciss.cpp 3945 2014-07-13 15:29:05Z chrfranke $"
   CCISS_H_CVSID;
 
 typedef struct _ReportLUNdata_struct
index 26472eba0560ccac8fca42422782c23d7012e1a9..e7f083f27b2e12c6c28134b47bebc287158e862c 100644 (file)
@@ -1,30 +1,28 @@
 #
-# $Id: configure.ac 3841 2013-07-26 17:38:57Z chrfranke $
+# $Id: configure.ac 3977 2014-07-26 11:03:24Z chrfranke $
 #
 dnl Process this file with autoconf to produce a configure script.
 AC_PREREQ(2.50)
-AC_INIT(smartmontools, 6.2, smartmontools-support@lists.sourceforge.net)
+AC_INIT(smartmontools, 6.4, 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.ac 3841 2013-07-26 17:38:57Z chrfranke $'`
-smartmontools_release_date=2013-07-26
-smartmontools_release_time="17:38:20 UTC"
+smartmontools_cvs_tag=`echo '$Id: configure.ac 3977 2014-07-26 11:03:24Z chrfranke $'`
+smartmontools_release_date=2014-07-26
+smartmontools_release_time="09:49:11 UTC"
 
 AC_DEFINE_UNQUOTED(SMARTMONTOOLS_CONFIGURE_ARGS, "$ac_configure_args",            [smartmontools Configure Arguments])
-AC_DEFINE_UNQUOTED(SMARTMONTOOLS_CONFIGURE_DATE, "$smartmontools_configure_date", [smartmontools Configure Date])
 AC_DEFINE_UNQUOTED(SMARTMONTOOLS_RELEASE_DATE,   "$smartmontools_release_date",   [smartmontools Release Date])
 AC_DEFINE_UNQUOTED(SMARTMONTOOLS_RELEASE_TIME,   "$smartmontools_release_time",   [smartmontools Release Time])
 AC_DEFINE_UNQUOTED(CONFIG_H_CVSID,               "$smartmontools_cvs_tag",        [smartmontools CVS Tag])
 AC_DEFINE_UNQUOTED(PACKAGE_HOMEPAGE,             "http://smartmontools.sourceforge.net/", [smartmontools Home Page])
 
-AM_CONFIG_HEADER(config.h)
+AC_CONFIG_HEADER([config.h])
 
 AM_INIT_AUTOMAKE([foreign])
 
 AM_MAINTAINER_MODE
 
-AC_LANG_CPLUSPLUS
+AC_LANG([C++])
 dnl Checks for programs.
 AC_PROG_CXX
 AM_PROG_AS
@@ -43,15 +41,10 @@ AC_ARG_VAR(MAKENSIS, [NSIS compiler command])
 AC_CANONICAL_HOST
 case "${host}" in
   *-*-mingw*)
-    # Cygwin gcc 4.x does no longer support '-mno-cygwin' to select MinGW gcc.
-    if test "${build}" = "${host}" && test -x /usr/bin/uname && \
-    /usr/bin/uname | grep -i '^CYGWIN' >/dev/null; then
-      AC_MSG_ERROR([Build with MinGW on Cygwin requires cross-compilation, see INSTALL file.])
-    fi
     AC_CHECK_TOOL(WINDMC, [windmc])
     AC_CHECK_TOOL(WINDRES, [windres])
 
-    AC_MSG_CHECKING([checking for makensis])
+    AC_MSG_CHECKING([for makensis])
     if test -z "$MAKENSIS"; then
       if test -n "$PROGRAMFILES" && "$PROGRAMFILES/NSIS/makensis" -VERSION >/dev/null 2>&1; then
         MAKENSIS="$PROGRAMFILES/NSIS/makensis"
@@ -138,19 +131,6 @@ AC_CHECK_FUNCS([clock_gettime ftime gettimeofday])
 # Check byte ordering (defines WORDS_BIGENDIAN)
 AC_C_BIGENDIAN
 
-# Check whether snprintf appends null char and returns expected length on overflow
-AC_MSG_CHECKING([for working snprintf])
-AC_RUN_IFELSE([AC_LANG_PROGRAM([[#include <stdio.h>]], [[ char buf[]="ABCDEFGHI";
-               int i=snprintf(buf,8,"12345678"); return !(!buf[7] && i==8); ]])],
-              [libc_have_working_snprintf=yes],
-              [libc_have_working_snprintf=no],
-              [libc_have_working_snprintf=unknown])
-AC_SUBST(libc_have_working_snprintf)
-if test "$libc_have_working_snprintf" = "yes"; then
-  AC_DEFINE(HAVE_WORKING_SNPRINTF, 1, [Define to 1 if the `snprintf' function is sane])
-fi
-AC_MSG_RESULT([$libc_have_working_snprintf])
-
 # check for __attribute__((packed))
 # (sizeof() check is required to avoid false positives if other
 # __attribute__((x)) are supported)
@@ -169,16 +149,23 @@ AC_SUBST(CPPFLAGS)
 AC_SUBST(LDFLAGS)
 AC_SUBST(ASFLAGS)
 
+AC_ARG_WITH(systemdenvfile,
+  [AS_HELP_STRING([--with-systemdenvfile=@<:@FILE|no@:>@],
+    [Path of systemd EnvironmentFile (implies --with-systemdsystemunitdir=yes) [SYSCONFDIR/sysconfig/smartmontools]])],
+  [systemdenvfile=; test "$withval" != "no" && systemdenvfile="$withval"; systemd_default=yes],
+  [systemdenvfile='${sysconfdir}/sysconfig/smartmontools'; systemd_default=auto])
+AC_SUBST(systemdenvfile)
+
 AC_ARG_WITH(systemdsystemunitdir,
   [AS_HELP_STRING([--with-systemdsystemunitdir@<:@=DIR|auto|yes|no@:>@], [Location of systemd service files [auto]])],
-  [], [with_systemdsystemunitdir=auto])
+  [], [with_systemdsystemunitdir=$systemd_default])
 
 systemdsystemunitdir=
 case "$with_systemdsystemunitdir" in
  auto|yes)
    if test -n "$PKG_CONFIG"; then
      AC_MSG_CHECKING([for systemdsystemunitdir])
-     systemdsystemunitdir=`$PKG_CONFIG --variable=systemdsystemunitdir systemd`
+     systemdsystemunitdir=`$PKG_CONFIG --variable=systemdsystemunitdir systemd 2>/dev/null`
      AC_MSG_RESULT([${systemdsystemunitdir:-no}])
    fi
    case "$with_systemdsystemunitdir:$sysconfdir:$systemdsystemunitdir" in
@@ -193,7 +180,7 @@ AC_SUBST(systemdsystemunitdir)
 AM_CONDITIONAL(INSTALL_SYSTEMDUNIT, [test -n "$systemdsystemunitdir"])
 
 AC_ARG_WITH(initscriptdir,
-  [AC_HELP_STRING([--with-initscriptdir@<:@=DIR|auto|yes|no@:>@], [Location of init scripts [auto]])],
+  [AS_HELP_STRING([--with-initscriptdir@<:@=DIR|auto|yes|no@:>@], [Location of init scripts [auto]])],
   [], [with_initscriptdir=auto])
 
 initddir=
@@ -228,7 +215,7 @@ esac
 AC_SUBST(initdfile)
 
 AC_ARG_WITH(docdir,
-  [AC_HELP_STRING([--with-docdir=DIR],[Location of documentation [DATADIR/doc/smartmontools]])],
+  [AS_HELP_STRING([--with-docdir=DIR], [Location of documentation [DATADIR/doc/smartmontools]])],
   [docdir="$withval"],
   [ if test -z "$docdir"; then
       # autoconf 2.5x without '--docdir' support
@@ -238,25 +225,38 @@ AC_ARG_WITH(docdir,
 AC_SUBST(docdir)
 
 AC_ARG_WITH(exampledir,
-  [AC_HELP_STRING([--with-exampledir=DIR],[Location of example scripts [DOCDIR/examplescripts]])],
+  [AS_HELP_STRING([--with-exampledir=DIR], [Location of example scripts [DOCDIR/examplescripts]])],
   [exampledir="$withval"], [exampledir='${docdir}/examplescripts'])
 AC_SUBST(exampledir)
 
 AC_ARG_ENABLE(drivedb,
-  [AC_HELP_STRING([--disable-drivedb],[Disables drive database file])],
+  [AS_HELP_STRING([--disable-drivedb], [Disables drive database file])],
   [], [enable_drivedb=yes])
 
 AC_ARG_WITH(drivedbdir,
-  [AC_HELP_STRING([--with-drivedbdir=DIR],[Location of drive database file (implies --enable-drivedb) [DATADIR/smartmontools]])],
+  [AS_HELP_STRING([--with-drivedbdir=DIR], [Location of drive database file [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(smartdscriptdir,
+  [AS_HELP_STRING([--with-smartdscriptdir=DIR], [Location of smartd_warning.sh script [SYSCONFDIR]])],
+  [smartdscriptdir="$withval"], [smartdscriptdir='${sysconfdir}'])
+AC_SUBST(smartdscriptdir)
+
+AC_ARG_WITH(smartdplugindir,
+  [AS_HELP_STRING([--with-smartdplugindir=@<:@DIR|no@:>@],
+    [Location of smartd_warning.sh plugin scripts [SMARTDSCRIPTDIR/smartd_warning.d]])],
+  [smartdplugindir=; test "$withval" != "no" && smartdplugindir="$withval"],
+  [smartdplugindir='${smartdscriptdir}/smartd_warning.d'])
+AC_SUBST(smartdplugindir)
+
+AC_ARG_ENABLE(savestates, [AS_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.]])],
+  [AS_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%/*}"
@@ -264,10 +264,11 @@ 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_ENABLE(attributelog, [AS_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.]])],
+  [AS_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%/*}"
@@ -276,13 +277,13 @@ 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])],
+  [AS_HELP_STRING([--enable-sample], [Enables appending .sample to the installed smartd rc script and configuration file])],
   [smartd_suffix=; test "$enableval" = "yes" && smartd_suffix=".sample"],
   [smartd_suffix=;])
 AC_SUBST(smartd_suffix)
 
 AC_ARG_WITH(os-deps,
-  [AC_HELP_STRING([--with-os-deps='os_module.o ...'],[Specify OS dependent module(s) [guessed]])],
+  [AS_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) ;;
@@ -292,7 +293,7 @@ AC_ARG_WITH(os-deps,
   ],[])
 
 AC_ARG_WITH(selinux,
-  [AC_HELP_STRING([--with-selinux@<:@=yes|no@:>@],[Enables SELinux support [no]])],
+  [AS_HELP_STRING([--with-selinux@<:@=yes|no@:>@], [Enables SELinux support [no]])],
   [ if test "$withval" = "yes"; then
       AC_CHECK_HEADERS([selinux/selinux.h], [], [AC_MSG_ERROR([Missing SELinux header files])])
       AC_CHECK_LIB(selinux, matchpathcon, [], [AC_MSG_ERROR([Missing or incorrect SELinux library files])])
@@ -304,7 +305,7 @@ if test "$with_selinux" = "yes"; then
 fi
 
 AC_ARG_WITH(libcap-ng,
-  [AC_HELP_STRING([--with-libcap-ng@<:@=auto|yes|no@:>@],[Add Libcap-ng support to smartd [auto]])],
+  [AS_HELP_STRING([--with-libcap-ng@<:@=auto|yes|no@:>@], [Add Libcap-ng support to smartd [auto]])],
   [], [with_libcap_ng=auto])
 
 use_libcap_ng=no
@@ -325,6 +326,40 @@ AC_SUBST(CAPNG_LDADD)
 AM_CONDITIONAL(ENABLE_CAPABILITIES, [test "$use_libcap_ng" = "yes"])
 AC_MSG_RESULT([$use_libcap_ng])
 
+# Assume broken snprintf only on Windows with MSVCRT (MinGW without ANSI stdio support)
+libc_have_working_snprintf=yes
+
+case "$host" in
+  *-*-mingw*)
+    case " $CPPFLAGS $CXXFLAGS" in
+      *\ -[[DU]]__USE_MINGW_ANSI_STDIO*)
+        ;;
+      *)
+        # Older MinGW do not properly define PRI?64 if __USE_MINGW_ANSI_STDIO is set
+        # Newer MinGW set __USE_MINGW_ANSI_STDIO in first C++ include which may be too late
+        AC_MSG_CHECKING([whether __USE_MINGW_ANSI_STDIO is defined by C++ includes])
+        AC_PREPROC_IFELSE([AC_LANG_SOURCE([[
+          #undef __USE_MINGW_ANSI_STDIO
+          #include <iostream>
+          #ifndef __USE_MINGW_ANSI_STDIO
+            #error false
+          #endif]])],
+        [CXXFLAGS="-D__USE_MINGW_ANSI_STDIO $CXXFLAGS"],
+        [libc_have_working_snprintf=no])
+        AC_MSG_RESULT([$libc_have_working_snprintf])
+        ;;
+    esac ;;
+esac
+
+AC_ARG_WITH(working-snprintf,
+  [AS_HELP_STRING([--with-working-snprintf@<:@=yes|no@:>@],
+    [Function snprintf() handles output truncation as specified by C99 [MinGW:guessed,others:yes]])],
+  [libc_have_working_snprintf=$withval])
+
+if test "$libc_have_working_snprintf" = "yes"; then
+  AC_DEFINE(HAVE_WORKING_SNPRINTF, 1, [Define to 1 if the `snprintf' function is sane])
+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
@@ -388,6 +423,7 @@ case "${host}" in
     ;;
   *-*-cygwin*)
     os_deps='os_win32.o dev_areca.o'
+    os_mailer='email'
     os_hostname="'hostname' 'echo "'"${HOSTNAME?unset}"'"'"
     os_dnsdomainname="'dnsdomainname' 'hostname -d' 'echo "'"${USERDNSDOMAIN?unset}"'"'"
     os_nisdomainname=
@@ -548,7 +584,12 @@ case "$host_os" in
     fi
     echo "local drive database:   `eval eval eval echo $sysconfdir`/smart_drivedb.h" >&AS_MESSAGE_FD
     echo "smartd config file:     `eval eval eval echo $sysconfdir`/smartd.conf${smartd_suffix}" >&AS_MESSAGE_FD
-    echo "smartd warning script:  `eval eval eval echo $sysconfdir`/smartd_warning.sh" >&AS_MESSAGE_FD
+    echo "smartd warning script:  `eval eval eval echo $smartdscriptdir`/smartd_warning.sh" >&AS_MESSAGE_FD
+    if test -n "$smartdplugindir"; then
+      echo "smartd plugin path:     `eval eval eval echo $smartdplugindir`" >&AS_MESSAGE_FD
+    else
+      echo "smartd plugin path:     [[disabled]]" >&AS_MESSAGE_FD
+    fi
     if test -n "$initddir"; then
       echo "smartd initd script:    `eval eval eval echo $initddir`/smartd${smartd_suffix}" >&AS_MESSAGE_FD
     elif test -z "$systemdsystemunitdir"; then
@@ -556,6 +597,11 @@ case "$host_os" in
     fi
     if test -n "$systemdsystemunitdir"; then
       echo "smartd systemd file:    `eval eval eval echo $systemdsystemunitdir`/smartd.service" >&AS_MESSAGE_FD
+      if test -n "$systemdenvfile"; then
+        echo "smartd environ file:    `eval eval eval echo $systemdenvfile`" >&AS_MESSAGE_FD
+      else
+        echo "smartd environ file:    [[disabled]]" >&AS_MESSAGE_FD
+      fi
     fi
     if test -n "$savestates"; then
       echo "smartd save files:      `eval eval eval echo $savestates`MODEL-SERIAL.TYPE.state" >&AS_MESSAGE_FD
index ec4afee4dae6f04bc3a8041357896c912629529b..941d90a2048d7e6542eb38c4343ace6baafc0c99 100644 (file)
@@ -21,7 +21,7 @@
 #include "dev_interface.h"
 #include "dev_areca.h"
 
-const char * dev_areca_cpp_cvsid = "$Id: dev_areca.cpp 3835 2013-07-20 18:37:19Z chrfranke $"
+const char * dev_areca_cpp_cvsid = "$Id: dev_areca.cpp 3872 2014-02-03 21:07:51Z chrfranke $"
   DEV_ARECA_H_CVSID;
 
 #include "atacmds.h"
@@ -114,7 +114,10 @@ generic_areca_device::~generic_areca_device() throw()
 //   1 if the command succeeded and disk SMART status is "FAILING"
 int generic_areca_device::arcmsr_command_handler(unsigned long arcmsr_cmd, unsigned char *data, int data_len)
 {
-  unsigned int cmds[] =
+  if (arcmsr_cmd >= ARCMSR_CMD_TOTAL)
+    return -1;
+
+  static const unsigned int cmds[ARCMSR_CMD_TOTAL] =
   {
     ARCMSR_IOCTL_READ_RQBUFFER,
     ARCMSR_IOCTL_WRITE_WQBUFFER,
@@ -145,11 +148,6 @@ int generic_areca_device::arcmsr_command_handler(unsigned long arcmsr_cmd, unsig
   sBuf.srbioctl.Timeout = 10000;
   sBuf.srbioctl.ControlCode = cmds[arcmsr_cmd];
 
-  if(arcmsr_cmd >= ARCMSR_CMD_TOTAL)
-  {
-      return -1;
-  }
-
   switch ( arcmsr_cmd )
   {
   // command for writing data to driver
index ace29cb83955acaf5dc02376a61d61764f3fb3fd..612717111567ff143e90e967a4c584aa51b2f3a8 100644 (file)
@@ -18,7 +18,7 @@
 #ifndef DEV_ARECA_H
 #define DEV_ARECA_H
 
-#define DEV_ARECA_H_CVSID "$Id: dev_areca.h 3763 2013-01-31 22:25:25Z chrfranke $"
+#define DEV_ARECA_H_CVSID "$Id: dev_areca.h 3854 2013-09-12 05:36:20Z chrfranke $"
 
 /////////////////////////////////////////////////////////////////////////////
 /// Areca RAID support
@@ -58,7 +58,7 @@ ARCMSR_CMD_TOTAL
 #define ARCMSR_IOCTL_CLEAR_RQBUFFER          (ARECA_SATA_RAID | FUNCTION_CLEAR_RQBUFFER)
 #define ARCMSR_IOCTL_CLEAR_WQBUFFER          (ARECA_SATA_RAID | FUNCTION_CLEAR_WQBUFFER)
 #define ARCMSR_IOCTL_RETURN_CODE_3F          (ARECA_SATA_RAID | FUNCTION_RETURN_CODE_3F)
-#elif defined(__FreeBSD__)
+#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
 #include <sys/ioctl.h> // _IOWR
 
 /*FunctionCode*/
index 1be81d13c1d93adc677e6293fec08e2656cadc14..0d6288b5d5ddb2f462a977ac84afe7611d922b0e 100644 (file)
--- a/drivedb.h
+++ b/drivedb.h
@@ -4,7 +4,7 @@
  * Home page of code is: http://smartmontools.sourceforge.net
  *
  * Copyright (C) 2003-11 Philip Williams, Bruce Allen
- * Copyright (C) 2008-13 Christian Franke <smartmontools-support@lists.sourceforge.net>
+ * Copyright (C) 2008-14 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
@@ -75,7 +75,7 @@
 /*
 const drive_settings builtin_knowndrives[] = {
  */
-  { "$Id: drivedb.h 3840 2013-07-25 21:29:08Z chrfranke $",
+  { "$Id: drivedb.h 3990 2014-09-29 17:59:37Z samm2 $",
     "-", "-",
     "This is a dummy entry to hold the SVN-Id of drivedb.h",
     ""
@@ -144,7 +144,7 @@ const drive_settings builtin_knowndrives[] = {
     "-v 232,raw48,Available_Reservd_Space "
     "-v 233,raw48,Media_Wearout_Indicator "       // SSD only
     //  234-239 Unknown_Attribute
-    "-v 240,raw48,Head_Flying_Hours "             // HDD only
+    "-v 240,raw24(raw8),Head_Flying_Hours "       // HDD only, smartmontools <= r3966: raw48
     "-v 241,raw48,Total_LBAs_Written "
     "-v 242,raw48,Total_LBAs_Read "
     //  243-249 Unknown_Attribute
@@ -153,28 +153,42 @@ const drive_settings builtin_knowndrives[] = {
     "-v 254,raw48,Free_Fall_Sensor "              // HDD only
   */
   },
-  { "Apple SSD SM128", // Samsung?
-    "APPLE SSD SM128",
-    "", "", ""
-  },
-  { "Apacer SDM4",
-    "2GB SATA Flash Drive", // tested with APSDM002G15AN-CT/SFI2101D
-    "SFI2101D", "",
+  { "Apacer SSD",
+    "(2|4|8|16|32)GB SATA Flash Drive", // tested with APSDM002G15AN-CT/SFDDA01C and SFI2101D, APSDM004G13AN-AT/SFDE001A
+    "SF(DDA01C|I2101D|DE001A)", "", // spec found at http://wfcache.advantech.com/www/certified-peripherals/documents/96fmcff-04g-cs-ap_Datasheet.pdf
     "-v 160,raw48,Initial_Bad_Block_Count "
     "-v 161,raw48,Bad_Block_Count "
     "-v 162,raw48,Spare_Block_Count "
     "-v 163,raw48,Max_Erase_Count "
-    "-v 164,raw48,Min_Erase_Count " // could be wrong
+    "-v 164,raw48,Average_Erase_Count "
     "-v 165,raw48,Average_Erase_Count " // could be wrong
+    "-v 166,raw48,Later_Bad_Block_Count "
+    "-v 167,raw48,SSD_Protect_Mode "
+    "-v 168,raw48,SATA_PHY_Err_Ct "
   },
-  { "Asus-Phison SSD",
-    "ASUS-PHISON SSD",
-    "", "", ""
+  { "Apple SD/SM/TS...E/F SSDs", // SanDisk/Samsung/Toshiba?
+    "APPLE SSD (S[DM]|TS)0?(128|256|512|768)[EF]", // tested with APPLE SSD SD256E/1021AP, SD0128F/A223321
+     // APPLE SSD SM768E/CXM90A1Q, SM0512F/UXM2JA1Q, TS0256F/109L0704
+    "", "",
+  //"-v 1,raw48,Raw_Read_Error_Rate "
+  //"-v 5,raw16(raw16),Reallocated_Sector_Ct "
+  //"-v 9,raw24(raw8),Power_On_Hours "
+  //"-v 12,raw48,Power_Cycle_Count "
+  //"-v 169,raw48,Unknown_Attribute "
+    "-v 173,raw48,Wear_Leveling_Count " // ]
+    "-v 174,raw48,Host_Reads_MiB "      // ] guessed (ticket #342), S[DM]*F only
+    "-v 175,raw48,Host_Writes_MiB "     // ]
+  //"-v 192,raw48,Power-Off_Retract_Count "
+  //"-v 194,tempminmax,Temperature_Celsius "
+  //"-v 197,raw48,Current_Pending_Sector "
+  //"-v 199,raw48,UDMA_CRC_Error_Count "
+  //"-v 240,raw48,Unknown_SSD_Attribute "
   },
   { "Crucial/Micron RealSSD C300/M500", // Marvell 88SS91xx
     "C300-CTFDDA[AC](064|128|256)MAG|" // Marvell 88SS9174 BJP2, tested with C300-CTFDDAC128MAG/0002,
       // C300-CTFDDAC064MAG/0006
-    "Crucial_CT(120|240|480)M500SSD3", // Marvell 88SS9187 BLD2, tested with Crucial_CT120M500SSD3/MU02
+    "Crucial_CT(120|240|480)M500SSD[13]", // Marvell 88SS9187 BLD2, tested with Crucial_CT120M500SSD3/MU02,
+      // Crucial_CT120M500SSD1/MU02, Crucial_CT240M500SSD1/MU03, Crucial_CT480M500SSD1/MU03
     "", "",
   //"-v 1,raw48,Raw_Read_Error_Rate "
   //"-v 5,raw16(raw16),Reallocated_Sector_Ct "
@@ -197,12 +211,16 @@ const drive_settings builtin_knowndrives[] = {
   //"-v 197,raw48,Current_Pending_Sector "
   //"-v 198,raw48,Offline_Uncorrectable "
   //"-v 199,raw48,UDMA_CRC_Error_Count "
-    "-v 202,raw48,Perc_Rated_Life_Used "
-    "-v 206,raw48,Write_Error_Rate"
+    "-v 202,raw48,Percent_Lifetime_Used "
+    "-v 206,raw48,Write_Error_Rate "
+    "-v 210,raw48,Success_RAIN_Recov_Cnt "
+    "-v 246,raw48,Total_Host_Sector_Write "
+    "-v 247,raw48,Host_Program_Page_Count "
+    "-v 248,raw48,Bckgnd_Program_Page_Cnt"
   },
   { "Crucial/Micron RealSSD m4/C400/P400", // Marvell 9176, fixed firmware
     "C400-MTFDDA[ACK](064|128|256|512)MAM|"
-    "M4-CT(064|128|256|512)M4SSD[23]|" // tested with M4-CT512M4SSD2/0309
+    "M4-CT(064|128|256|512)M4SSD[123]|" // tested with M4-CT512M4SSD2/0309
     "MTFDDAK(064|128|256|512|050|100|200|400)MA[RN]-1[JKS]1AA.*", // tested with
                                              // MTFDDAK256MAR-1K1AA/MA52
     "030[9-Z]|03[1-Z].|0[4-Z]..|[1-Z]....*", // >= "0309"
@@ -233,7 +251,7 @@ const drive_settings builtin_knowndrives[] = {
   },
   { "Crucial/Micron RealSSD m4/C400", // Marvell 9176, buggy or unknown firmware
     "C400-MTFDDA[ACK](064|128|256|512)MAM|" // tested with C400-MTFDDAC256MAM/0002
-    "M4-CT(064|128|256|512)M4SSD[23]", // tested with M4-CT064M4SSD2/0002,
+    "M4-CT(064|128|256|512)M4SSD[123]", // tested with M4-CT064M4SSD2/0002,
       // M4-CT064M4SSD2/0009, M4-CT256M4SSD3/000F
     "",
     "This drive may hang after 5184 hours of power-on time:\n"
@@ -252,22 +270,83 @@ const drive_settings builtin_knowndrives[] = {
     "-v 202,raw48,Perc_Rated_Life_Used "
     "-v 206,raw48,Write_Error_Rate"
   },
+  { "Crucial/Micron MX100/M500/M510/M550 Client SSDs",
+    "Crucial_CT(128|256|512)MX100SSD1|"// tested with Crucial_CT256MX100SSD1/MU01
+    "Micron_M500_MTFDDA[KTV](120|240|480|960)MAV|"// tested with Micron_M500_MTFDDAK960MAV/MU05
+    "(Micron_)?M510[_-]MTFDDA[KTV](128|256)MAZ|" // tested with M510-MTFDDAK256MAZ/MU01
+    "(Micron_)?M550[_-]MTFDDA[KTV](064|128|256|512|1T0)MAY", // tested with M550-MTFDDAK256MAY/MU01
+    "", "",
+  //"-v 1,raw48,Raw_Read_Error_Rate "
+    "-v 5,raw48,Reallocate_NAND_Blk_Cnt "
+  //"-v 9,raw24(raw8),Power_On_Hours "
+  //"-v 12,raw48,Power_Cycle_Count "
+    "-v 171,raw48,Program_Fail_Count "
+    "-v 172,raw48,Erase_Fail_Count "
+    "-v 173,raw48,Ave_Block-Erase_Count "
+    "-v 174,raw48,Unexpect_Power_Loss_Ct "
+    "-v 180,raw48,Unused_Reserve_NAND_Blk "
+    "-v 183,raw48,SATA_Interfac_Downshift "
+    "-v 184,raw48,Error_Correction_Count "
+  //"-v 187,raw48,Reported_Uncorrect "
+  //"-v 194,tempminmax,Temperature_Celsius "
+  //"-v 196,raw16(raw16),Reallocated_Event_Count "
+  //"-v 197,raw48,Current_Pending_Sector "
+  //"-v 198,raw48,Offline_Uncorrectable "
+  //"-v 199,raw48,UDMA_CRC_Error_Count "
+    "-v 202,raw48,Percent_Lifetime_Used "
+    "-v 206,raw48,Write_Error_Rate "
+    "-v 210,raw48,Success_RAIN_Recov_Cnt "
+    "-v 246,raw48,Total_Host_Sector_Write "
+    "-v 247,raw48,Host_Program_Page_Count "
+    "-v 248,raw48,Bckgnd_Program_Page_Cnt"
+  },
+  { "Micron M500DC Enterprise SSDs",
+    "Micron_M500DC_(EE|MT)FDDA[AK](120|240|480|800)MBB", // tested with
+      // Micron_M500DC_EEFDDAA120MBB/129, Micron_M500DC_MTFDDAK800MBB/0129
+    "", "",
+  //"-v 1,raw48,Raw_Read_Error_Rate "
+    "-v 5,raw48,Reallocated_Block_Count "
+  //"-v 9,raw24(raw8),Power_On_Hours "
+  //"-v 12,raw48,Power_Cycle_Count "
+    "-v 170,raw48,Reserved_Block_Count "
+    "-v 171,raw48,Program_Fail_Count "
+    "-v 172,raw48,Erase_Fail_Count "
+    "-v 173,raw48,Ave_Block-Erase_Count "
+    "-v 174,raw48,Unexpect_Power_Loss_Ct "
+    "-v 184,raw48,Error_Correction_Count "
+  //"-v 187,raw48,Reported_Uncorrect "
+    "-v 188,raw48,Command_Timeouts "
+  //"-v 194,tempminmax,Temperature_Celsius "
+    "-v 195,raw48,Cumulativ_Corrected_ECC "
+  //"-v 197,raw48,Current_Pending_Sector "
+  //"-v 198,raw48,Offline_Uncorrectable "
+  //"-v 199,raw48,UDMA_CRC_Error_Count "
+    "-v 202,raw48,Percent_Lifetime_Remain "
+    "-v 206,raw48,Write_Error_Rate "
+    "-v 247,raw48,Host_Program_Page_Count "
+    "-v 248,raw48,Bckgnd_Program_Page_Cnt"
+  },
   { "SandForce Driven SSDs",
     "SandForce 1st Ed\\.|" // Demo Drive, tested with firmware 320A13F0
     "ADATA SSD S(396|510|599) .?..GB|" // tested with ADATA SSD S510 60GB/320ABBF0,
       // ADATA SSD S599 256GB/3.1.0, 64GB/3.4.6
-    "ADATA SP900|" // Premier Pro, SF-2281, tested with ADATA SP900/5.0.6
+    "ADATA SP[389]00|" // tested with ADATA SP300/5.0.2d, SP800/5.0.6c,
+      // ADATA SP900/5.0.6 (Premier Pro, SF-2281)
+    "ADATA SSD SP900 (64|128|256)GB-DL2|" // tested with ADATA SSD SP900 256GB-DL2/5.0.6
+    "ADATA XM11 (128|256)GB|" // tested with ADATA XM11 128GB/5.0.1
     "Corsair CSSD-F(40|60|80|115|120|160|240)GBP?2.*|" // Corsair Force, tested with
       // Corsair CSSD-F40GB2/1.1, Corsair CSSD-F115GB2-A/2.1a
-    "Corsair Force (SSD|GS|GT)|" // SF-2281, tested with
-      // Corsair Force 3 SSD/1.3.2, GT/1.3.3, GS/5.03
+    "Corsair Force ((3 |LS )?SSD|GS|GT)|" // SF-2281, tested with
+      // Corsair Force SSD/5.05, 3 SSD/1.3.2, GT/1.3.3, GS/5.03, LS SSD/S8FM06.5
     "FM-25S2S-(60|120|240)GBP2|" // G.SKILL Phoenix Pro, SF-1200, tested with
       // FM-25S2S-240GBP2/4.2
     "FTM(06|12|24|48)CT25H|" // Supertalent TeraDrive CT, tested with
       // FTM24CT25H/STTMP2P1
+    "KINGSTON SE50S3(100|240|480)G|" // tested with SE50S3100G/KE1ABBF0
     "KINGSTON SH10[03]S3(90|120|240|480)G|" // HyperX (3K), SF-2281, tested with
       // SH100S3240G/320ABBF0, SH103S3120G/505ABBF0
-    "KINGSTON SKC300S37A(60|120|240|480)G|" // SF-2281, tested with SKC300S37A120G/KC4ABBF0
+    "KINGSTON SKC(300S37A|380S3)(60|120|240|480)G|" // SF-2281, tested with SKC300S37A120G/KC4ABBF0,
+      // SKC380S3120G/507ABBF0
     "KINGSTON SVP200S3(7A)?(60|90|120|240|480)G|" // V+ 200, SF-2281, tested with
       // SVP200S37A480G/502ABBF0, SVP200S390G/332ABBF0
     "KINGSTON SMS200S3(30|60|120)G|" // mSATA, SF-2241, tested with SMS200S3120G/KC3ABBF0
@@ -294,22 +373,26 @@ const drive_settings builtin_knowndrives[] = {
     "(APOC|DENC|DENEVA|FTNC|GFGC|MANG|MMOC|NIMC|TMSC).*|" // other OCZ SF-1200,
       // tested with DENCSTE251M11-0120/1.33, DENEVA PCI-E/1.33
     "(DENR|DRSAK|EC188|NIMR|PSIR|TRSAK).*|" // other OCZ SF-1500
-    "OWC Mercury Electra [36]G SSD|" // tested with
-      // OWC Mercury Electra 6G SSD/502ABBF0
-    "OWC Mercury Extreme Pro (RE )?SSD|" // tested with
-      // OWC Mercury Extreme Pro SSD/360A13F0
-    "OWC Mercury EXTREME Pro 6G SSD|" // tested with
-      // OWC Mercury EXTREME Pro 6G SSD/507ABBF0
+    "OWC Aura Pro 6G SSD|" // tested with OWC Aura Pro 6G SSD/507ABBF0
+    "OWC Mercury Electra (Pro )?[36]G SSD|" // tested with
+      // OWC Mercury Electra 6G SSD/502ABBF0, OWC Mercury Electra Pro 3G SSD/541ABBF0
+    "OWC Mercury E(xtreme|XTREME) Pro (6G |RE )?SSD|" // tested with
+      // OWC Mercury Extreme Pro SSD/360A13F0, OWC Mercury EXTREME Pro 6G SSD/507ABBF0
     "Patriot Pyro|" // tested with Patriot Pyro/332ABBF0
     "SanDisk SDSSDX(60|120|240|480)GG25|" // SanDisk Extreme, SF-2281, tested with
       // SDSSDX240GG25/R201
     "SuperSSpeed S301 [0-9]*GB|" // SF-2281, tested with SuperSSpeed S301 128GB/503
+    "SG9XCS2D(0?50|100|200|400)GESLT|" // Smart Storage Systems XceedIOPS2, tested with
+      // SG9XCS2D200GESLT/SA03L370
+    "SSD9SC(120|240|480)GED[EA]|" // PNY Prevail Elite, tested with SSD9SC120GEDA/334ABBF0
     "(TX32|TX31C1|VN0.?..GCNMK).*|" // Smart Storage Systems XceedSTOR
     "(TX22D1|TX21B1).*|" // Smart Storage Systems XceedIOPS2
     "TX52D1.*|" // Smart Storage Systems Xcel-200
-    "TS(64|128|256|512)GSSD320|" // Transcend SSD320, SF-2281, tested with TS128GSSD320
-    "UGB(88P|99S)GC...H[BF].", // Unigen, tested with
+    "TS(64|128|256|512)GSSD[37]20|" // Transcend SSD320/720, SF-2281, tested with
+      // TS128GSSD320, TS256GSSD720/5.2.0
+    "UGB(88P|99S)GC...H[BF].|" // Unigen, tested with
       // UGB88PGC100HF2/MP Rev2, UGB99SGC100HB3/RC Rev3
+    "VisionTek GoDrive (60|120|240|480)GB", // tested with VisionTek GoDrive 480GB/506ABBF0
     "", "",
     "-v 1,raw24/raw32,Raw_Read_Error_Rate "
     "-v 5,raw48,Retired_Block_Count "
@@ -347,8 +430,8 @@ const drive_settings builtin_knowndrives[] = {
     "Corsair CSSD-V(32|60|64|128|256)GB2|" // Corsair Nova, tested with Corsair CSSD-V32GB2/2.2
     "CRUCIAL_CT(64|128|256)M225|" // tested with CRUCIAL_CT64M225/1571
     "G.SKILL FALCON (64|128|256)GB SSD|" // tested with G.SKILL FALCON 128GB SSD/2030
-    "OCZ[ -](AGILITY|ONYX|VERTEX( 1199|-TURBO)?)|" // tested with
-      // OCZ-ONYX/1.6, OCZ-VERTEX 1199/00.P97, OCZ-VERTEX/1.30, OCZ VERTEX-TURBO/1.5
+    "OCZ[ -](AGILITY|ONYX|VERTEX( 1199|-TURBO| v1\\.10)?)|" // tested with
+      // OCZ-ONYX/1.6, OCZ-VERTEX 1199/00.P97, OCZ-VERTEX/1.30, OCZ VERTEX-TURBO/1.5, OCZ-VERTEX v1.10/1370
     "Patriot[ -]Torqx.*|"
     "RENICE Z2|" // tested with RENICE Z2/2030
     "STT_FT[MD](28|32|56|64)GX25H|" // Super Talent Ultradrive GX, tested with STT_FTM64GX25H/1916
@@ -397,7 +480,8 @@ const drive_settings builtin_knowndrives[] = {
   //"-v 233,raw48,Media_Wearout_Indicator"
   },
   { "Indilinx Barefoot 3 based SSDs",
-    "OCZ-VECTOR", // tested with OCZ-VECTOR/1.03
+    "OCZ-VECTOR|" // tested with OCZ-VECTOR/1.03
+    "OCZ-VERTEX450", // tested with OCZ-VERTEX450/1.0 (Barefoot 3 M10)
     "", "", ""
     "-v 5,raw48,Runtime_Bad_Block "
   //"-v 9,raw24(raw8),Power_On_Hours "
@@ -413,8 +497,44 @@ const drive_settings builtin_knowndrives[] = {
     "-v 208,raw48,Average_Erase_Count "
     "-v 210,raw48,SATA_CRC_Error_Count "
     "-v 233,raw48,Remaining_Lifetime_Perc "
+    "-v 241,raw48,Host_Writes_GiB " // M10
+    "-v 242,raw48,Host_Reads_GiB "  // M10
     "-v 249,raw48,Total_NAND_Prog_Ct_GiB"
   },
+  { "OCZ Intrepid 3000 SSDs", // tested with OCZ INTREPID 3600/1.4.3.6, 3800/1.4.3.0
+    "OCZ INTREPID 3[68]00",
+    "", "", ""
+    "-v 5,raw48,Runtime_Bad_Block "
+  //"-v 9,raw24(raw8),Power_On_Hours "
+  //"-v 12,raw48,Power_Cycle_Count "
+    "-v 100,raw48,Total_Blocks_Erased "
+    "-v 171,raw48,Avail_OP_Block_Count "
+    "-v 174,raw48,Pwr_Cycle_Ct_Unplanned "
+    "-v 184,raw48,Factory_Bad_Block_Count "
+    "-v 187,raw48,Total_Unc_NAND_Reads "
+    "-v 190,tempminmax,Temperature_Celsius "
+    "-v 195,raw48,Total_Prog_Failures "
+    "-v 196,raw48,Total_Erase_Failures "
+    "-v 197,raw48,Total_Unc_Read_Failures "
+    "-v 198,raw48,Host_Reads_GiB "
+    "-v 199,raw48,Host_Writes_GiB "
+    "-v 202,raw48,Total_Read_Bits_Corr_Ct "
+    "-v 205,raw48,Max_Rated_PE_Count "
+    "-v 206,raw48,Min_Erase_Count "
+    "-v 207,raw48,Max_Erase_Count "
+    "-v 208,raw48,Average_Erase_Count "
+    "-v 210,raw48,SATA_CRC_Error_Count "
+    "-v 211,raw48,SATA_UNC_Count "
+    "-v 212,raw48,NAND_Reads_with_Retry "
+    "-v 213,raw48,Simple_Rd_Rtry_Attempts "
+    "-v 214,raw48,Adaptv_Rd_Rtry_Attempts "
+    "-v 221,raw48,Int_Data_Path_Prot_Unc "
+    "-v 222,raw48,RAID_Recovery_Count "
+    "-v 230,raw48,SuperCap_Charge_Status " // 0=not charged, 1=fully charged, 2=unknown
+    "-v 233,raw48,Remaining_Lifetime_Perc "
+    "-v 249,raw48,Total_NAND_Prog_Ct_GiB "
+    "-v 251,raw48,Total_NAND_Read_Ct_GiB"
+  },
   { "InnoDisk InnoLite SATADOM D150QV-L SSDs", // tested with InnoLite SATADOM D150QV-L/120319
     "InnoLite SATADOM D150QV-L",
     "", "",
@@ -528,8 +648,9 @@ const drive_settings builtin_knowndrives[] = {
     "-v 242,raw48,Host_Reads_32MiB"
   },
   { "Intel 320 Series SSDs", // tested with INTEL SSDSA2CT040G3/4PC10362,
-      // INTEL SSDSA2CW160G3/4PC10362, INTEL SSDSA2BT040G3/4PC10362, INTEL SSDSA2BW120G3A/4PC10362
-    "INTEL SSDSA[12][BC][WT](040|080|120|160|300|600)G3A?",
+      // INTEL SSDSA2CW160G3/4PC10362, INTEL SSDSA2BT040G3/4PC10362, INTEL SSDSA2BW120G3A/4PC10362,
+      // INTEL SSDSA2BW300G3D/4PC10362, INTEL SSDSA2BW160G3L/4PC1LE04
+    "INTEL SSDSA[12][BC][WT](040|080|120|160|300|600)G3[ADL]?",
     "", "",
     "-F nologdir "
   //"-v 3,raw16(avg16),Spin_Up_Time "
@@ -540,8 +661,10 @@ const drive_settings builtin_knowndrives[] = {
     "-v 170,raw48,Reserve_Block_Count "
     "-v 171,raw48,Program_Fail_Count "
     "-v 172,raw48,Erase_Fail_Count "
+    "-v 183,raw48,SATA_Downshift_Count " // FW >= 4Px10362
   //"-v 184,raw48,End-to-End_Error "
   //"-v 187,raw48,Reported_Uncorrect "
+    "-v 199,raw48,CRC_Error_Count "      // FW >= 4Px10362
     "-v 192,raw48,Unsafe_Shutdown_Count "
     "-v 225,raw48,Host_Writes_32MiB "
     "-v 226,raw48,Workld_Media_Wear_Indic " // Timed Workload Media Wear Indicator (percent*1024)
@@ -615,6 +738,58 @@ const drive_settings builtin_knowndrives[] = {
     "-v 242,raw48,Host_Reads_32MiB "
     "-v 249,raw48,NAND_Writes_1GiB"
   },
+  { "Intel 525 Series SSDs", // mSATA, tested with SSDMCEAC120B3/LLLi
+    "INTEL SSDMCEAC(030|060|090|120|180|240)B3",
+    "", "",
+  //"-v 5,raw16(raw16),Reallocated_Sector_Ct "
+    "-v 9,msec24hour32,Power_On_Hours_and_Msec "
+  //"-v 12,raw48,Power_Cycle_Count "
+    "-v 170,raw48,Available_Reservd_Space "
+    "-v 171,raw48,Program_Fail_Count "
+    "-v 172,raw48,Erase_Fail_Count "
+    "-v 174,raw48,Unexpect_Power_Loss_Ct "
+    "-v 183,raw48,SATA_Downshift_Count "
+  //"-v 184,raw48,End-to-End_Error "
+    "-v 187,raw48,Uncorrectable_Error_Cnt "
+  //"-v 190,tempminmax,Airflow_Temperature_Cel "
+  //"-v 192,raw48,Power-Off_Retract_Count "
+  //"-v 199,raw48,UDMA_CRC_Error_Count "
+    "-v 225,raw48,Host_Writes_32MiB "
+    "-v 226,raw48,Workld_Media_Wear_Indic "
+    "-v 227,raw48,Workld_Host_Reads_Perc "
+    "-v 228,raw48,Workload_Minutes "
+  //"-v 232,raw48,Available_Reservd_Space "
+  //"-v 233,raw48,Media_Wearout_Indicator "
+    "-v 241,raw48,Host_Writes_32MiB "
+    "-v 242,raw48,Host_Reads_32MiB "
+    "-v 249,raw48,NAND_Writes_1GiB"
+  },
+  { "Intel 530 Series SSDs", // tested with INTEL SSDSC2BW180A4/DC12, SSDSC2BW240A4/DC12
+    "INTEL SSDSC2BW(080|120|180|240|360|480)A4",
+    "", "",
+  //"-v 5,raw16(raw16),Reallocated_Sector_Ct "
+    "-v 9,msec24hour32,Power_On_Hours_and_Msec "
+  //"-v 12,raw48,Power_Cycle_Count "
+    "-v 170,raw48,Available_Reservd_Space "
+    "-v 171,raw48,Program_Fail_Count "
+    "-v 172,raw48,Erase_Fail_Count "
+    "-v 174,raw48,Unexpect_Power_Loss_Ct "
+    "-v 183,raw48,SATA_Downshift_Count "
+  //"-v 184,raw48,End-to-End_Error "
+    "-v 187,raw48,Uncorrectable_Error_Cnt "
+  //"-v 190,tempminmax,Airflow_Temperature_Cel "
+  //"-v 192,raw48,Power-Off_Retract_Count "
+  //"-v 199,raw48,UDMA_CRC_Error_Count "
+    "-v 225,raw48,Host_Writes_32MiB "
+    "-v 226,raw48,Workld_Media_Wear_Indic "
+    "-v 227,raw48,Workld_Host_Reads_Perc "
+    "-v 228,raw48,Workload_Minutes "
+  //"-v 232,raw48,Available_Reservd_Space "
+  //"-v 233,raw48,Media_Wearout_Indicator "
+    "-v 241,raw48,Host_Writes_32MiB "
+    "-v 242,raw48,Host_Reads_32MiB "
+    "-v 249,raw48,NAND_Writes_1GiB"
+  },
   { "Intel 330/335 Series SSDs", // tested with INTEL SSDSC2CT180A3/300i, SSDSC2CT240A3/300i,
       // INTEL SSDSC2CT240A4/335t
     "INTEL SSDSC2CT(060|120|180|240)A[34]", // A4 = 335 Series
@@ -632,8 +807,9 @@ const drive_settings builtin_knowndrives[] = {
     "-v 242,raw48,Host_Reads_32MiB "
     "-v 249,raw48,NAND_Writes_1GiB"
   },
-  { "Intel DC S3700 Series SSDs", // tested with INTEL SSDSC2BA200G3/5DV10250
-    "INTEL SSDSC(1N|2B)A(100|200|400|800)G3",
+  { "Intel 730 and DC S3500/S3700 Series SSDs", // tested with INTEL SSDSC2BP480G4, SSDSC2BB120G4/D2010355,
+      // INTEL SSDSC2BB800G4T, SSDSC2BA200G3/5DV10250
+    "INTEL SSDSC(1N|2B)[ABP](080|100|120|160|200|240|300|400|480|600|800)G[34]T?", // A=S3700, B=S3500, P=730
     "", "",
   //"-v 3,raw16(avg16),Spin_Up_Time "
   //"-v 4,raw48,Start_Stop_Count "
@@ -644,7 +820,7 @@ const drive_settings builtin_knowndrives[] = {
     "-v 171,raw48,Program_Fail_Count "
     "-v 172,raw48,Erase_Fail_Count "
     "-v 174,raw48,Unsafe_Shutdown_Count "
-    "-v 175,raw48,Power_Loss_Cap_Test "
+    "-v 175,raw16(raw16),Power_Loss_Cap_Test "
     "-v 183,raw48,SATA_Downshift_Count "
   //"-v 184,raw48,End-to-End_Error "
   //"-v 187,raw48,Reported_Uncorrect "
@@ -659,9 +835,10 @@ const drive_settings builtin_knowndrives[] = {
     "-v 228,raw48,Workload_Minutes " // 226,227,228 can be reset by 'smartctl -t vendor,0x40'
   //"-v 232,raw48,Available_Reservd_Space "
   //"-v 233,raw48,Media_Wearout_Indicator "
-    "-v 234,raw48,Thermal_Throttle "
+    "-v 234,raw24/raw32:04321,Thermal_Throttle "
     "-v 241,raw48,Host_Writes_32MiB "
-    "-v 242,raw48,Host_Reads_32MiB"
+    "-v 242,raw48,Host_Reads_32MiB "
+    "-F xerrorlba" // tested with SSDSC2BB600G4/D2010355
   },
   { "Kingston branded X25-V SSDs", // fixed firmware
     "KINGSTON SSDNow 40GB",
@@ -688,8 +865,9 @@ const drive_settings builtin_knowndrives[] = {
   },
   { "JMicron based SSDs", // JMicron JMF60x
     "Kingston SSDNow V Series [0-9]*GB|" // tested with Kingston SSDNow V Series 64GB/B090522a
-    "TS(2|4|8|16|32|64|128|192)GSSD25S?-(M|S)", // Transcend IDE and SATA, tested with TS32GSSD25-M/V090331
-    "[BV].*", // other Transcend SSD versions will be catched by subsequent entry
+    "TS(2|4|8|16|32|64|128|192)GSSD(18|25)[MS]?-[MS]", // Transcend IDE and SATA, tested with
+      // TS32GSSD25-M/V090331, TS32GSSD18M-M/v090331
+    "[BVv].*", // other Transcend SSD versions will be catched by subsequent entry
     "",
   //"-v 9,raw24(raw8),Power_On_Hours " // raw value always 0?
   //"-v 12,raw48,Power_Cycle_Count "
@@ -700,9 +878,10 @@ const drive_settings builtin_knowndrives[] = {
     "-v 234,raw24/raw24:w01234,Avg/Max_Erase_Count "
     "-v 235,raw24/raw24:w01z23,Good/Sys_Block_Count"
   },
-  { "JMicron based SSDs", // JMicron JMF61x
+  { "JMicron based SSDs", // JMicron JMF61x, JMF661
     "ADATA S596 Turbo|"  // tested with ADATA S596 Turbo 256GB SATA SSD (JMicron JMF616)
-    "APPLE SSD TS.*|"  // Toshiba?, tested with APPLE SSD TS064C/CJAA0201
+    "ADATA SP600|"  // tested with ADATA SP600/2.4 (JMicron JMF661)
+    "APPLE SSD TS(064|128|256|512)C|"  // Toshiba?, tested with APPLE SSD TS064C/CJAA0201
     "KINGSTON SNV425S2(64|128)GB|"  // SSDNow V Series (2. Generation, JMF618),
                                     // tested with KINGSTON SNV425S264GB/C091126a
     "KINGSTON SSDNOW 30GB|" // tested with KINGSTON SSDNOW 30GB/AJXA0202
@@ -729,17 +908,18 @@ const drive_settings builtin_knowndrives[] = {
     "-v 168,raw48,SATA_Phy_Error_Count "
   //"-v 169,raw48,Unknown_Attribute "
     "-v 170,raw16,Bad_Block_Count "
-    "-v 173,raw16,Erase_Count "
+    "-v 173,raw16,Erase_Count " // JMF661: different?
     "-v 175,raw48,Bad_Cluster_Table_Count "
     "-v 192,raw48,Unexpect_Power_Loss_Ct "
   //"-v 194,tempminmax,Temperature_Celsius "
   //"-v 197,raw48,Current_Pending_Sector "
     "-v 240,raw48,Unknown_Attribute"
   },
-  { "Plextor M3 (Pro) Series SSDs", // Marvell 9174, tested with PLEXTOR PX-128M3/1.01,
-      // PLEXTOR PX-128M3P/1.04, PLEXTOR PX-256M3/1.05
+  { "Plextor M3/M5 (Pro) Series SSDs", // Marvell 88SS9174 (M3, M5S), 88SS9187 (M5Pro), tested with
+      // PLEXTOR PX-128M3/1.01, PX-128M3P/1.04, PX-256M3/1.05, PX-128M5S/1.02, PX-256M5S/1.03,
+      // PX-128M5M/1.05, PX-128M5S/1.05, PX-128M5Pro/1.05, PX-512M5Pro/1.06
       // (1.04/5 Firmware self-test log lifetime unit is bogus, possibly 1/256 hours)
-    "PLEXTOR PX-(64|128|256|512)M3P?",
+    "PLEXTOR PX-(64|128|256|512)M(3P?|5[MS]|5Pro)",
     "", "",
   //"-v 1,raw48,Raw_Read_Error_Rate "
   //"-v 5,raw16(raw16),Reallocated_Sector_Ct "
@@ -755,7 +935,8 @@ const drive_settings builtin_knowndrives[] = {
   //"-v 198,raw48,Offline_Uncorrectable "
   //"-v 199,raw48,UDMA_CRC_Error_Count "
   //"-v 232,raw48,Available_Reservd_Space "
-    ""
+    "-v 241,raw48,Host_Writes_32MiB "
+    "-v 242,raw48,Host_Reads_32MiB"
   },
   { "Samsung based SSDs",
     "SAMSUNG SSD PM800 .*GB|"  // SAMSUNG PM800 SSDs, tested with SAMSUNG SSD PM800 TH 64GB/VBM25D1Q
@@ -764,6 +945,8 @@ const drive_settings builtin_knowndrives[] = {
     "SAMSUNG SSD 830 Series|"  // tested with SAMSUNG SSD 830 Series 64GB/CXM03B1Q
     "Samsung SSD 840 (PRO )?Series|" // tested with Samsung SSD 840 PRO Series 128GB/DXM04B0Q,
       // Samsung SSD 840 Series/DXT06B0Q
+    "Samsung SSD 840 EVO ([0-9]*G|1T)B( mSATA)?|"  // tested with Samsung SSD 840 EVO (120|250|500)GB/EXT0AB0Q,
+      // Samsung SSD 840 EVO (120|250)GB/EXT0BB6Q, 1TB/EXT0BB0Q, 120GB mSATA/EXT41B6Q
     "SAMSUNG MZ7WD((120|240)HAFV|480HAGM|960HAGP)-00003", // SM843T Series, tested with
       // SAMSUNG MZ7WD120HAFV-00003/DXM85W3Q
     "", "",
@@ -791,6 +974,55 @@ const drive_settings builtin_knowndrives[] = {
     "-v 235,raw48,POR_Recovery_Count " // 830/840 Series
   //"-v 241,raw48,Total_LBAs_Written"
   },
+  { "Marvell based SanDisk SSDs",
+    "SanDisk SD5SG2[0-9]*G1052E|" // X100 (88SS9174), tested with SanDisk SD5SG2256G1052E/10.04.01
+    "SanDisk SD6SB[12]M[0-9]*G(1022I)?|" // X110/X210 (88SS9175), tested with SanDisk SD6SB1M064G1022I/X231600,
+      // SanDisk SD6SB1M256G1022I/X231600, SanDisk SD6SB2M512G1022I/X210400
+    "SanDisk SDSSDHP[0-9]*G|" // Ultra Plus (88SS9175), tested with SanDisk SDSSDHP128G/X23[01]6RL
+    "SanDisk SDSSDXP[0-9]*G", // Extreme II (88SS9187), tested with SanDisk SDSSDXP480G/R1311
+    "", "",
+  //"-v 5,raw16(raw16),Reallocated_Sector_Ct "
+  //"-v 9,raw24(raw8),Power_On_Hours "
+  //"-v 12,raw48,Power_Cycle_Count "
+    "-v 166,raw48,Min_W/E_Cycle "
+    "-v 167,raw48,Min_Bad_Block/Die "
+    "-v 168,raw48,Maximum_Erase_Cycle "
+    "-v 169,raw48,Total_Bad_Block "
+    "-v 171,raw48,Program_Fail_Count "
+    "-v 172,raw48,Erase_Fail_Count "
+    "-v 173,raw48,Avg_Write_Erase_Ct "
+    "-v 174,raw48,Unexpect_Power_Loss_Ct "
+  //"-v 187,raw48,Reported_Uncorrect "
+  //"-v 194,tempminmax,Temperature_Celsius "
+    "-v 212,raw48,SATA_PHY_Error "
+    "-v 230,raw48,Perc_Write_Erase_Count "
+    "-v 232,raw48,Perc_Avail_Resrvd_Space "
+    "-v 233,raw48,Total_NAND_Writes_GiB "
+    "-v 241,raw48,Total_Writes_GiB "
+    "-v 242,raw48,Total_Reads_GiB "
+  //"-v 243,raw48,Unknown_Attribute "
+  },
+  { "SanDisk based SSDs",
+    "SanDisk iSSD P4 [0-9]*GB|" // tested with SanDisk iSSD P4 16GB/SSD 9.14
+    "SanDisk SDSSDP[0-9]*G|" // tested with SanDisk SDSSDP064G/1.0.0, SDSSDP128G/2.0.0
+    "SanDisk SSD i100 [0-9]*GB|" // tested with SanDisk SSD i100 8GB/11.56.04, 24GB/11.56.04
+    "SanDisk SSD U100 ([0-9]*GB|SMG2)|" // tested with SanDisk SSD U100 8GB/10.56.00, 256GB/10.01.02, SMG2/10.56.04
+    "SanDisk SD7[SU]B3Q(064|128|256|512)G.*", // tested with SD7SB3Q064G1122/SD7UB3Q256G1122/SD7SB3Q128G
+    "", "",
+  //"-v 5,raw16(raw16),Reallocated_Sector_Ct "
+  //"-v 9,raw24(raw8),Power_On_Hours "
+  //"-v 12,raw48,Power_Cycle_Count "
+    "-v 171,raw48,Program_Fail_Count "
+    "-v 172,raw48,Erase_Fail_Count "
+    "-v 173,raw48,Avg_Write_Erase_Ct "
+    "-v 174,raw48,Unexpect_Power_Loss_Ct "
+  //"-v 187,raw48,Reported_Uncorrect "
+    "-v 230,raw48,Perc_Write_Erase_Count "
+    "-v 232,raw48,Perc_Avail_Resrvd_Space "
+    "-v 234,raw48,Perc_Write_Erase_Ct_BC "
+  //"-v 241,raw48,Total_LBAs_Written "
+  //"-v 242,raw48,Total_LBAs_Read "
+  },
   { "Smart Storage Systems Xcel-10 SSDs",  // based on http://www.smartm.com/files/salesLiterature/storage/xcel10.pdf
     "SMART A25FD-(32|64|128)GI32N", // tested with SMART A25FD-128GI32N/B9F23D4K
     "",
@@ -1139,6 +1371,10 @@ const drive_settings builtin_knowndrives[] = {
     "SAMSUNG HE(502H|754J|103S)J",
     "", "", ""
   },
+  { "Seagate Samsung Spinpoint F4", // tested with ST250DM001 HD256GJ/1AR10001
+    "ST(250|320)DM001 HD(256G|322G|323H)J",
+    "", "", ""
+  },
   { "SAMSUNG SpinPoint F4 EG (AF)",// tested with HD204UI/1AQ10001(buggy|fixed)
     "SAMSUNG HD(155|204)UI",
     "", // 1AQ10001
@@ -1148,7 +1384,7 @@ const drive_settings builtin_knowndrives[] = {
     "Buggy and fixed firmware report same version number!\n"
     "See the following web pages for details:\n"
     "http://knowledge.seagate.com/articles/en_US/FAQ/223571en\n"
-    "http://sourceforge.net/apps/trac/smartmontools/wiki/SamsungF4EGBadBlocks",
+    "http://www.smartmontools.org/wiki/SamsungF4EGBadBlocks",
     ""
   },
   { "SAMSUNG SpinPoint S250", // tested with HD200HJ/KF100-06
@@ -1887,8 +2123,8 @@ const drive_settings builtin_knowndrives[] = {
     "", "", ""
   },
   { "Toshiba 2.5\" HDD MK..65GSX", // tested with TOSHIBA MK5065GSX/GJ003A, MK3265GSXN/GH012H,
-      // MK5065GSXF/GP006B
-    "TOSHIBA MK(16|25|32|50|64)65GSX[FN]?",
+      // MK5065GSXF/GP006B, MK2565GSX H/GJ003A
+    "TOSHIBA MK(16|25|32|50|64)65GSX[FN]?( H)?", // "... H" = USB ?
     "", "", ""
   },
   { "Toshiba 2.5\" HDD MK..76GSX", // tested with TOSHIBA MK3276GSX/GS002D
@@ -1901,10 +2137,18 @@ const drive_settings builtin_knowndrives[] = {
     "TOSHIBA MQ01ABD(025|032|050|064|075|100)",
     "", "", ""
   },
+  { "Toshiba 2.5\" HDD MQ01UBD... (USB 3.0)", // tested with TOSHIBA MQ01ABD100/AX001U
+    "TOSHIBA MQ01UBD(050|075|100)",
+    "", "", ""
+  },
   { "Toshiba 3.5\" HDD MK.002TSKB", // tested with TOSHIBA MK1002TSKB/MT1A
     "TOSHIBA MK(10|20)02TSKB",
     "", "", ""
   },
+  { "Toshiba 3.5\" MG03ACAxxx(Y) Enterprise HDD", // tested with TOSHIBA MG03ACA100/FL1A
+    "TOSHIBA MG03ACA[1234]00Y?",
+    "", "", ""
+  },
   { "Toshiba 3.5\" HDD DT01ACA...", // tested with TOSHIBA DT01ACA100/MS2OA750,
       // TOSHIBA DT01ACA200/MX4OABB0, TOSHIBA DT01ACA300/MX6OABB0
     "TOSHIBA DT01ACA(025|032|050|075|100|150|200|300)",
@@ -2037,6 +2281,10 @@ const drive_settings builtin_knowndrives[] = {
     "ST(160|250|320)LT0(07|09|11|14)-.*",
     "", "", ""
   },
+  { "Seagate Laptop Thin HDD", // tested with ST500LT012-9WS142/0001SDM1
+    "ST(250|320|500)LT0(12|15|25)-.*",
+    "", "", ""
+  },
   { "Seagate Laptop SSHD", // tested with ST500LM000-1EJ162/SM11
     "ST(500|1000)LM0(00|14)-.*",
     "", "", ""
@@ -2183,14 +2431,14 @@ const drive_settings builtin_knowndrives[] = {
   },
   { "Seagate Barracuda 7200.14 (AF)", // new firmware, tested with
       // ST3000DM001-9YN166/CC4H, ST3000DM001-9YN166/CC9E
-    "ST(1000|1500|2000|2500|3000)DM00[1-3]-.*",
+    "ST(1000|1500|2000|2500|3000)DM00[1-3]-9YN16.",
     "CC(4[H-Z]|[5-9A-Z]..*)", // >= "CC4H"
     "",
     "-v 188,raw16 -v 240,msec24hour32" // tested with ST3000DM001-9YN166/CC4H
   },
   { "Seagate Barracuda 7200.14 (AF)", // old firmware, tested with
       // ST1000DM003-9YN162/CC46
-    "ST(1000|1500|2000|2500|3000)DM00[1-3]-.*",
+    "ST(1000|1500|2000|2500|3000)DM00[1-3]-9YN16.",
     "CC4[679CG]",
     "A firmware update for this drive is available,\n"
     "see the following Seagate web pages:\n"
@@ -2199,7 +2447,7 @@ const drive_settings builtin_knowndrives[] = {
     "-v 188,raw16 -v 240,msec24hour32"
   },
   { "Seagate Barracuda 7200.14 (AF)", // unknown firmware
-    "ST(1000|1500|2000|2500|3000)DM00[1-3]-.*",
+    "ST(1000|1500|2000|2500|3000)DM00[1-3]-9YN16.",
     "",
     "A firmware update for this drive may be available,\n"
     "see the following Seagate web pages:\n"
@@ -2207,6 +2455,13 @@ const drive_settings builtin_knowndrives[] = {
     "http://knowledge.seagate.com/articles/en_US/FAQ/223651en",
     "-v 188,raw16 -v 240,msec24hour32"
   },
+  { "Seagate Barracuda 7200.14 (AF)", // different part number, tested with
+      // ST1000DM003-1CH162/CC47, ST1000DM003-1CH162/CC49, ST2000DM001-1CH164/CC24,
+      // ST1000DM000-9TS15E/CC92
+    "ST(1000|1500|2000|2500|3000)DM00[0-3]-.*",
+    "", "",
+    "-v 188,raw16 -v 240,msec24hour32"
+  },
   { "Seagate Barracuda 7200.14 (AF)", // < 1TB, tested with ST250DM000-1BC141
     "ST(250|320|500|750)DM00[0-3]-.*",
     "", "",
@@ -2217,6 +2472,11 @@ const drive_settings builtin_knowndrives[] = {
     "", "",
     "-v 188,raw16 -v 240,msec24hour32"
   },
+  { "Seagate Desktop SSHD", // tested with ST2000DX001-1CM164/CC43
+    "ST(1000|2000|4000)DX001-.*",
+    "", "",
+    "-v 188,raw16 -v 240,msec24hour32"
+  },
   { "Seagate Barracuda LP", // new firmware
     "ST3(500412|1000520|1500541|2000542)AS",
     "CC3[5-9A-Z]",
@@ -2234,7 +2494,7 @@ const drive_settings builtin_knowndrives[] = {
   },
   { "Seagate Barracuda Green (AF)", // new firmware
     "ST((10|15|20)00DL00[123])-.*",
-    "CC3[2-9A-Z]",
+    "CC(3[2-9A-Z]|[4-9A-Z]..*)", // >= "CC32"
     "", ""
   },
   { "Seagate Barracuda Green (AF)", // unknown firmware
@@ -2295,6 +2555,18 @@ const drive_settings builtin_knowndrives[] = {
     "ST[1234]000NM00[35]3-.*",
     "", "", ""
   },
+  { "Seagate Constellation CS", // tested with ST3000NC000/CE02, ST3000NC002-1DY166/CN02
+    "ST(1000|2000|3000)NC00[0-3](-.*)?",
+    "", "", ""
+  },
+  { "Seagate Constellation.2 (SATA)", // 2.5", tested with ST91000640NS/SN02
+    "ST9(25061|50062|100064)[012]NS", // *SS = SAS
+    "", "", ""
+  },
+  { "Seagate NAS HDD", // tested with ST2000VN000-1H3164/SC42, ST3000VN000-1H4167/SC43
+    "ST[234]000VN000-.*",
+    "", "", ""
+  },
   { "Seagate Pipeline HD 5900.1",
     "ST3(160310|320[34]10|500(321|422))CS",
     "", "", ""
@@ -2303,6 +2575,10 @@ const drive_settings builtin_knowndrives[] = {
     "ST3(160316|250[34]12|320(311|413)|500(312|414)|1000(322|424))CS",
     "", "", ""
   },
+  { "Seagate Video 3.5 HDD", // tested with ST4000VM000-1F3168/SC23, SC25
+    "ST(10|15|20|30|40)00VM00[023]-.*",
+    "", "", ""
+  },
   { "Seagate Medalist 17240, 13030, 10231, 8420, and 4310",
     "ST3(17240|13030|10231|8420|4310)A",
     "", "", ""
@@ -2473,8 +2749,13 @@ const drive_settings builtin_knowndrives[] = {
     "WDC WD2002FYPS-.*",
     "", "", ""
   },
-  { "Western Digital RE4 (SATA 6Gb/s)", // tested with WDC WD2000FYYZ-01UL1B0/01.01K01
-    "WDC WD(20|30|40)00FYYZ-.*",
+  { "Western Digital RE4 (SATA 6Gb/s)", // tested with WDC WD2000FYYZ-01UL1B0/01.01K01,
+      // WD2000FYYX/00.0D1K2
+    "WDC WD(20|30|40)00FYYZ-.*|WD2000FYYX",
+    "", "", ""
+  },
+  { "Western Digital Se", // tested with WDC WD2000F9YZ-09N20L0/01.01A01
+    "WDC WD(1002|2000|3000|4000)F9YZ-.*",
     "", "", ""
   },
   { "Western Digital Caviar Green",
@@ -2489,21 +2770,18 @@ const drive_settings builtin_knowndrives[] = {
   },
   { "Western Digital Caviar Green (AF, SATA 6Gb/s)", // tested with
       // WDC WD10EZRX-00A8LB0/01.01A01, WDC WD20EZRX-00DC0B0/80.00A80,
-      // WDC WD30EZRX-00MMMB0/80.00A80
-    "WDC WD(7500AA|(10|15|20)EA|(10|20|25|30)EZ)RX-.*",
+      // WDC WD30EZRX-00MMMB0/80.00A80, WDC WD40EZRX-00SPEB0/80.00A80
+    "WDC WD(7500AA|(10|15|20)EA|(10|20|25|30|40)EZ)RX-.*",
     "", "", ""
   },
   { "Western Digital Caviar Black",
     "WDC WD((500|640|750)1AAL|1001FA[EL]|2001FAS)S-.*",
     "", "", ""
   },
-  { "Western Digital Caviar Black",  // SATA 6 Gb/s variants, tested with
-      //  WDC WD4001FAEX-00MJRA0/01.01L01
-    "WDC WD(5002AAL|(64|75)02AAE|((10|15|20)02|4001)FAE)X-.*",
-    "", "", ""
-  },
-  { "Western Digital Caviar Black (AF)", // tested with WDC WD5003AZEX-00RKKA0/80.00A80
-    "WDC WD(5003AZE)X-.*",
+  { "Western Digital Black", // tested with
+      // WDC WD5003AZEX-00RKKA0/80.00A80, WDC WD1003FZEX-00MK2A0/01.01A01,
+      // WDC WD3001FAEX-00MJRA0/01.01L01, WDC WD4001FAEX-00MJRA0/01.01L01
+    "WDC WD(5002AAL|5003AZE|(64|75)02AAE|((10|15|20)0[23]|[34]001)F[AZ]E)X-.*",
     "", "", ""
   },
   { "Western Digital AV ATA", // tested with WDC WD3200AVJB-63J5A0/01.03E01
@@ -2571,15 +2849,24 @@ const drive_settings builtin_knowndrives[] = {
     "WDC WD(50|75)00BPKT-.*",
     "", "", ""
   },
-  { "Western Digital Red (AF)", // tested with WDC WD10EFRX-68JCSN0/01.01A01
-    "WDC WD(10|20|30)EFRX-.*",
+  { "Western Digital Red (AF)", // tested with WDC WD10EFRX-68JCSN0/01.01A01,
+      // WDC WD10JFCX-68N6GN0/01.01A01, WDC WD40EFRX-68WT0N0/80.00A80
+    "WDC WD(10|20|30|40)[EJ]F[CR]X-.*",
+    "", "", ""
+  },
+  { "Western Digital Blue Mobile", // tested with WDC WD5000LPVX-08V0TT2/03.01A03
+    "WDC WD((25|32|50|75)00[BLM]|10[JS])P[CV][TX]-.*",
+    "", "", ""
+  },
+  { "Western Digital Green Mobile", // tested with WDC WD20NPVX-00EA4T0/01.01A01
+    "WDC WD(15|20)NPV[TX]-.*",
     "", "", ""
   },
-  { "Western Digital My Passport (USB)", // tested with WDC WD5000BMVW-11AMCS0/01.01A01
+  { "Western Digital Elements / My Passport (USB)", // tested with WDC WD5000BMVW-11AMCS0/01.01A01
     "WDC WD(25|32|40|50)00BMV[UVW]-.*",  // *W-* = USB 3.0
     "", "", ""
   },
-  { "Western Digital My Passport (USB, AF)", // tested with
+  { "Western Digital Elements / My Passport (USB, AF)", // tested with
       // WDC WD5000KMVV-11TK7S1/01.01A01, WDC WD10TMVW-11ZSMS5/01.01A01,
       // WDC WD10JMVW-11S5XS1/01.01A01, WDC WD20NMVW-11W68S0/01.01A01
     "WDC WD(5000[LK]|7500K|10[JT]|20N)MV[VW]-.*", // *W-* = USB 3.0
@@ -2672,6 +2959,12 @@ const drive_settings builtin_knowndrives[] = {
     "",
     "-d sat"
   },
+  { "USB: Buffalo MiniStationHD-PCFU3; ",
+    "0x0411:0x0240",
+    "",
+    "",
+    "-d sat"
+  },
   // LG Electronics
   { "USB: LG Mini HXD5; JMicron",
     "0x043e:0x70f1",
@@ -2687,6 +2980,12 @@ const drive_settings builtin_knowndrives[] = {
     "-d sat"
   },
   // Toshiba
+  { "USB: Toshiba Stor.E Slim USB 3.0; ", // 1TB, MQ01UBD100
+    "0x0480:0x0100",
+    "", // 0x0000
+    "",
+    "-d sat"
+  },
   { "USB: Toshiba Canvio 500GB; SunPlus",
     "0x0480:0xa004",
     "",
@@ -2705,6 +3004,18 @@ const drive_settings builtin_knowndrives[] = {
     "",
     "-d sat"
   },
+  { "USB: Toshiba Stor.E Basics; ", // 1TB
+    "0x0480:0xa009",
+    "",
+    "",
+    "-d sat"
+  },
+  { "USB: Toshiba Stor.E Plus", // 2TB
+    "0x0480:0xa00a",
+    "",
+    "",
+    "-d sat"
+  },
   { "USB: Toshiba Canvio Desktop; ", // 2TB
     "0x0480:0xd010",
     "",
@@ -2788,8 +3099,14 @@ const drive_settings builtin_knowndrives[] = {
     "",
     "-d sat"
   },
-  { "USB: Samsung M3 Portable USB 3.0; ", // 1TB
-    "0x04e8:0x61b6",
+  { "USB: Samsung D3 Station; ", // 3TB
+    "0x04e8:0x6124",
+    "", // 0x200
+    "",
+    "-d sat"
+  },
+  { "USB: Samsung M3 Portable USB 3.0; ",
+    "0x04e8:0x61b[456]", // 4=2TB, 5=1.5TB, 6=1TB
     "", // 0x0e00
     "",
     "-d sat"
@@ -2850,6 +3167,12 @@ const drive_settings builtin_knowndrives[] = {
     "",
     "-d usbjmicron"
   },
+  { "USB: Iomega; JMicron",
+    "0x059b:0x047a",
+    "", // 0x0100
+    "",
+    "-d sat" // works also with "-d usbjmicron"
+  },
   // LaCie
   { "USB: LaCie hard disk (FA Porsche design);",
     "0x059f:0x0651",
@@ -3041,7 +3364,7 @@ const drive_settings builtin_knowndrives[] = {
   },
   // Lumberg, Inc.
   { "USB: Toshiba Stor.E; Sunplus",
-    "0x0939:0x0b16",
+    "0x0939:0x0b1[56]",
     "",
     "",
     "-d usbsunplus"
@@ -3066,7 +3389,7 @@ const drive_settings builtin_knowndrives[] = {
     "-d sat"
   },
   { "USB: Seagate Expansion Portable; ",
-    "0x0bc2:0x2300",
+    "0x0bc2:0x23(00|12)",
     "",
     "",
     "-d sat"
@@ -3090,13 +3413,13 @@ const drive_settings builtin_knowndrives[] = {
     "-d sat,12"
   },
   { "USB: Seagate Expansion External; ", // 2TB, 3TB
-    "0x0bc2:0x33(00|20|32)",
+    "0x0bc2:0x33(00|12|20|32)",
     "",
     "",
     "-d sat"
   },
   { "USB: Seagate FreeAgent GoFlex USB 2.0; ",
-    "0x0bc2:0x5021",
+    "0x0bc2:0x502[01]",
     "",
     "",
     "-d sat"
@@ -3143,6 +3466,12 @@ const drive_settings builtin_knowndrives[] = {
     "",
     "-d sat"
   },
+  { "USB: Seagate Backup Plus Slim USB 3.0; ", // (ticket #443)
+    "0x0bc2:0xab24",
+    "", // 0x0100
+    "",
+    "-d sat"
+  },
   // Dura Micro
   { "USB: Dura Micro; Cypress",
     "0x0c0b:0xb001",
@@ -3227,44 +3556,14 @@ const drive_settings builtin_knowndrives[] = {
     "",
     "-d usbcypress"
   },
-  { "USB: WD My Passport Portable; ",
-    "0x1058:0x0702",
-    "", // 0x0102
-    "",
-    "-d sat"
-  },
-  { "USB: WD My Passport Essential; ",
-    "0x1058:0x0704",
-    "", // 0x0175
-    "",
-    "-d sat"
-  },
-  { "USB: WD My Passport Elite; ",
-    "0x1058:0x0705",
-    "", // 0x0175
-    "",
-    "-d sat"
-  },
-  { "USB: WD My Passport 070A; ",
-    "0x1058:0x070a",
-    "", // 0x1028
-    "",
-    "-d sat"
-  },
-  { "USB: WD My Passport 0730; ",
-    "0x1058:0x0730",
-    "", // 0x1008
-    "",
-    "-d sat"
-  },
-  { "USB: WD My Passport Essential SE USB 3.0; ",
-    "0x1058:0x074[02]",
+  { "USB: WD My Passport; ",
+    "0x1058:0x07(0[245a]|30)",
     "",
     "",
     "-d sat"
   },
   { "USB: WD My Passport USB 3.0; ",
-    "0x1058:0x07[4a]8",
+    "0x1058:0x0(74[0128a]|7a8|820)",
     "",
     "",
     "-d sat"
@@ -3294,7 +3593,7 @@ const drive_settings builtin_knowndrives[] = {
     "-d sat"
   },
   { "USB: WD Elements; ",
-    "0x1058:0x10(10|a2)",
+    "0x1058:0x10(10|48|a2)",
     "", // 0x0105
     "",
     "-d sat"
@@ -3317,6 +3616,12 @@ const drive_settings builtin_knowndrives[] = {
     "",
     "-d sat"
   },
+  { "USB: WD Elements; ",
+    "0x1058:0x10[ab]8", // a=1TB, b=2TB
+    "", // a=0x1042, b=0x1007
+    "",
+    "-d sat"
+  },
   { "USB: WD My Book Essential; ",
     "0x1058:0x1100",
     "", // 0x0165
@@ -3360,7 +3665,13 @@ const drive_settings builtin_knowndrives[] = {
     "",
     "-d sat"
   },
-  // A-DATA
+  // ADATA
+  { "USB: ADATA; ",
+    "0x125f:0xa[13]1a", // 1=Classic CH11 1TB, 3=DashDrive HV620 2TB
+    "", // 0x0100
+    "",
+    "-d sat"
+  },
   { "USB: A-DATA SH93; Cypress",
     "0x125f:0xa93a",
     "", // 0x0150
@@ -3410,6 +3721,12 @@ const drive_settings builtin_knowndrives[] = {
     "",
     "-d sat"
   },
+  { "USB: ; Initio",
+    "0x13fd:0x1640",
+    "", // 0x0864
+    "",
+    "-d sat,12" // some SMART commands fail, see ticket #295
+  },
   { "USB: Intenso Memory Station 2,5\"; Initio",
     "0x13fd:0x1840",
     "",
@@ -3430,12 +3747,19 @@ const drive_settings builtin_knowndrives[] = {
     "-d usbcypress"
   },
   // JMicron
-  { "USB: ; JMicron USB 3.0",
+  { "USB: ; JMicron JMS539", // USB2/3->SATA (old firmware)
     "0x152d:0x0539",
-    "", // 0x0100
+    "0x0100",  //  1.00
     "",
     "-d usbjmicron"
   },
+  { "USB: ; JMicron JMS539", // USB2/3->SATA (new firmware)
+    "0x152d:0x0539",
+    "0x0205|"  //  2.05, ticket #338
+    "0x2812",  // 28.12, Mediasonic ProBox H82-SU3S2 (port multiplier)
+    "",
+    "-d sat"
+  },
   { "USB: ; JMicron ", // USB->SATA->4xSATA (port multiplier)
     "0x152d:0x0551",
     "", // 0x0100
@@ -3511,6 +3835,12 @@ const drive_settings builtin_knowndrives[] = {
     "",
     "-d sat"
   },
+  { "USB: ; ASMedia AS2105", // Icy Box IB-AC603A-U3
+    "0x174c:0x5136",
+    "", // 0x0001
+    "",
+    "-d sat"
+  },
   // LucidPort
   { "USB: ; LucidPORT USB300", // RaidSonic ICY BOX IB-110StU3-B, Sharkoon SATA QuickPort H3
     "0x1759:0x500[02]", // 0x5000: USB 2.0, 0x5002: USB 3.0
@@ -3518,6 +3848,12 @@ const drive_settings builtin_knowndrives[] = {
     "",
     "-d sat"
   },
+  { "USB: ; LucidPort", // Fuj:tech SATA-USB3 dock
+    "0x1759:0x5100",
+    "", // 0x2580
+    "",
+    "-d sat"
+  },
   // Verbatim
   { "USB: Verbatim Portable Hard Drive; Sunplus",
     "0x18a5:0x0214",
@@ -3569,6 +3905,13 @@ const drive_settings builtin_knowndrives[] = {
     "",
     "-d usbsunplus"
   },
+  // TrekStor
+  { "USB: TrekStor DataStation; ", // DataStation maxi light (USB 3.0)
+    "0x1e68:0x0050",
+    "", // 0x0100
+    "",
+    "-d sat"
+  },
   // Innostor
   { "USB: ; Innostor IS888", // Sharkoon SATA QuickDeck Pro USB 3.0
     "0x1f75:0x0888",
index 9f4726f9f87bd1c41dd201c4850d44aec1a7f81b..070e87c7554871307be925e73f2d0f5267bb6f8c 100755 (executable)
@@ -1,4 +1,4 @@
-#!/bin/bash 
+#! /bin/sh
 #
 # This is a script from the smartmontools examplescripts/ directory.
 # It can be used as an argument to the -M exec Directive in
@@ -8,7 +8,7 @@
 # Please see man 8 smartd or man 5 smartd.conf for further
 # information.
 #
-# $Id: Example1,v 1.7 2004/08/29 02:33:17 ballen4705 Exp $
+# $Id: Example1 3958 2014-07-18 19:13:32Z chrfranke $
 
 # Save standard input into a temp file
 cat > /root/tempfile
@@ -36,9 +36,9 @@ echo "$SMARTD_TFIRSTEPOCH"  >> /root/tempfile
 # Run smartctl -a and save output in temp file
 /usr/sbin/smartctl -a -d $SMARTD_DEVICETYPE $SMARTD_DEVICE >> /root/tempfile
 
-# Email the contents of the temp file. Solaris and other OSes
-# may need to use /bin/mailx not /bin/mail.
-/bin/mail -s "SMART errors detected on host: `hostname`" $SMARTD_ADDRESS < /root/tempfile
+# Email the contents of the temp file.  Solaris and
+# other OSes may need to use /usr/bin/mailx below.
+/usr/bin/mail -s "SMART errors detected on host: `hostname`" $SMARTD_ADDRESS < /root/tempfile
 
 # And exit
 exit 0
index f6534332b3fce622decbd9f8ecedf04e5f0f7222..688216433b65fa97e95e96e0f98a37a1a843412e 100755 (executable)
@@ -1,4 +1,4 @@
-#! /bin/bash
+#! /bin/sh
 #
 # This is a script from the smartmontools examplescripts/ directory.
 # It can be used as an argument to the -M exec Directive in
@@ -8,7 +8,7 @@
 # Please see man 8 smartd or man 5 smartd.conf for further
 # information.
 #
-# $Id: Example2,v 1.4 2004/01/07 16:49:56 ballen4705 Exp $
+# $Id: Example2 3958 2014-07-18 19:13:32Z chrfranke $
 
 # Save the email message (STDIN) to a file:
 cat > /root/msg
@@ -16,7 +16,7 @@ cat > /root/msg
 # Append the output of smartctl -a to the message:
 /usr/sbin/smartctl -a -d $SMARTD_DEVICETYPE $SMARTD_DEVICE >> /root/msg
 
-# Now email the message to the user at address ADD.  Solaris and
-# other OSes may need to use /bin/mailx below.
-/bin/mail -s "$SMARTD_SUBJECT" $SMARTD_ADDRESS < /root/msg
+# Now email the message to the user.  Solaris and
+# other OSes may need to use /usr/bin/mailx below.
+/usr/bin/mail -s "$SMARTD_SUBJECT" $SMARTD_ADDRESS < /root/msg
 
index cda752a1fe0463fdbb6f5b00af2fc389b5446588..d23a6a57fffa5c91d24dd3de6cde9dc1a7f17ea8 100755 (executable)
@@ -1,4 +1,4 @@
-#! /bin/bash
+#! /bin/sh
 #
 # This is a script from the smartmontools examplescripts/ directory.
 # It can be used as an argument to the -M exec Directive in
@@ -8,7 +8,7 @@
 # Please see man 8 smartd or man 5 smartd.conf for further
 # information.
 #
-# $Id: Example3 3187 2010-10-16 13:34:18Z chrfranke $
+# $Id: Example3 3958 2014-07-18 19:13:32Z chrfranke $
 
 # Warn all users of a problem     
 wall <<EOF
index f436b0f298847723b9d61982569e420343e55c55..4aaebbc75fe3180890ea0eb1a136785895ac6c60 100755 (executable)
@@ -1,5 +1,8 @@
 #! /bin/sh
 
+# Send message if /usr/lib/powersave/powersave-notify exists or exit silently
+[ -x /usr/lib/powersave/powersave-notify ] || exit 0
+
 /usr/lib/powersave/powersave-notify "<b>Your hard disk drive is failing!</b>
 S.M.A.R.T. message:
 $SMARTD_MESSAGE"
diff --git a/examplescripts/Example5 b/examplescripts/Example5
new file mode 100755 (executable)
index 0000000..a85961c
--- /dev/null
@@ -0,0 +1,10 @@
+#!/bin/bash -e
+
+tmp=$(tempfile)
+cat >$tmp
+
+run-parts --report --lsbsysinit --arg=$tmp --arg="$1" \
+    --arg="$2" --arg="$3" -- /etc/smartmontools/run.d
+
+rm -f $tmp
+
diff --git a/examplescripts/Example6 b/examplescripts/Example6
new file mode 100755 (executable)
index 0000000..b789c72
--- /dev/null
@@ -0,0 +1,15 @@
+#! /bin/sh
+
+# Send mail
+echo "$SMARTD_MESSAGE" | mail -s "$SMARTD_FAILTYPE" "$SMARTD_ADDRESS"
+
+# Notify desktop user
+MESSAGE="WARNING: Your hard drive is failing"
+
+# direct write to terminals, do not use 'wall', because we don't want its ugly header
+for t in $(who | awk '{ print $2; }' | grep -e '^tty' -e '^pts/')
+do
+  echo "$MESSAGE
+$SMARTD_MESSAGE" >/dev/$t 2>/dev/null ||:
+done
+
index dfeccfec5bd6ab4a3d962b09d8978ac9f56f5e2e..43a351be0432d8215511947ad3d5357eac08d19c 100644 (file)
@@ -1,8 +1,9 @@
 # Home page: http://smartmontools.sourceforge.net
 #
-# $Id: README 3728 2012-12-13 17:57:50Z chrfranke $
+# $Id: README 3958 2014-07-18 19:13:32Z chrfranke $
 #
 # Copyright (C) 2003-8 Bruce Allen <smartmontools-support@lists.sourceforge.net>
+# Copyright (C) 2009-14 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
 # 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., 51
-# Franklin Street, Fifth Floor, Boston, 02110-1301 USA.
+# example COPYING).  If not, see <http://www.gnu.org/licenses/>.
 #
 # 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/
 
-This directory contains executable bash scripts, that are intended for
+This directory contains executable shell scripts, that are intended for
 use with the
   -m address -M exec /path/to/an/executable
 Directive in /etc/smartd.conf.
@@ -35,16 +35,24 @@ and include a brief description to use below.
 
 The files contained in this directory are:
 
-Example1: appends values of $SMARTD_* environment variables and the output
+Example1: Appends values of $SMARTD_* environment variables and the output
           of smartctl -a to the normal email message, and sends that
           to the email address listed as the argument to the -m
           Directive.
 
 Example2: Appends output of smartctl -a to the normal email message
-         and sends that to the email address listed as the argument
-         to the -m Directive.
+          and sends that to the email address listed as the argument
+          to the -m Directive.
 
 Example3: Uses wall(1) to send a warning message to all users, then powers
           down the machine.
 
 Example4: Uses powersave-notify to issue a desktop neutral warning.
+          (/etc/smartmontools/run.d/10powersave-notify from Debian package)
+
+Example5: Uses run-parts(8) to run scripts from /etc/smartmontools/run.d/.
+          (/usr/share/smartmontools/smartd-runner from Debian package)
+
+Example6: Sends a warning mail and then notifies the users by direct write
+          to terminals.
+          (/usr/libexec/smartmontools/smartdnotify from Fedora package)
index eabdee9846eefc3a1b5f946a1d7f2fd1495aea2b..8d05d1cd858c60cfd4f0b1869441cbac3c3b6366 100644 (file)
@@ -1,18 +1,19 @@
 /*
- * os_darwin.c
+ * os_darwin.cpp
  *
  * Home page of code is: http://smartmontools.sourceforge.net
  *
  * Copyright (C) 2004-8 Geoffrey Keating <geoffk@geoffk.org>
+ * Copyright (C) 2014 Alex Samorukov <samm@os2.kiev.ua>
  *
  * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *  You should have received a copy of the GNU General Public License
+ *  along with smartmontools.  If not, see <http://www.gnu.org/licenses/>.
+ *
  */
 
 #include <stdbool.h>
 #include "atacmds.h"
 #include "scsicmds.h"
 #include "utility.h"
-
 #include "os_darwin.h"
+#include "dev_interface.h"
 
 // Needed by '-V' option (CVS versioning) of smartd/smartctl
-const char *os_XXXX_c_cvsid="$Id: os_darwin.cpp 3805 2013-03-29 19:54:18Z chrfranke $" \
+const char *os_darwin_cpp_cvsid="$Id: os_darwin.cpp 3982 2014-08-16 21:07:19Z samm2 $" \
 ATACMDS_H_CVSID CONFIG_H_CVSID INT64_H_CVSID OS_DARWIN_H_CVSID SCSICMDS_H_CVSID UTILITY_H_CVSID;
 
-// Print examples for smartctl.
-void print_smartctl_examples(){
-  printf("=================================================== SMARTCTL EXAMPLES =====\n\n");
-  printf(
+// examples for smartctl
+static const char  smartctl_examples[] =
+         "=================================================== SMARTCTL EXAMPLES =====\n\n"
          "  smartctl -a disk0                            (Prints all SMART information)\n\n"
          "  smartctl -t long /dev/disk0              (Executes extended disk self-test)\n\n"
 #ifdef HAVE_GETOPT_LONG
@@ -66,15 +66,64 @@ void print_smartctl_examples(){
          "                                                 (You can use IOService: ...)\n\n"
          "  smartctl -c IODeviceTree:/pci@f4000000/ata-6@D/@0:0\n"
          "                                                       (... Or IODeviceTree:)\n"
-         );
-  return;
+         ;
+
+
+// Information that we keep about each device.
+
+static struct {
+  io_object_t ioob;
+  IOCFPlugInInterface **plugin;
+  IOATASMARTInterface **smartIf;
+} devices[20];
+
+const char * dev_darwin_cpp_cvsid = "$Id: os_darwin.cpp 3982 2014-08-16 21:07:19Z samm2 $"
+  DEV_INTERFACE_H_CVSID;
+
+/////////////////////////////////////////////////////////////////////////////
+
+namespace os { // No need to publish anything, name provided for Doxygen
+
+/////////////////////////////////////////////////////////////////////////////
+/// Implement shared open/close routines with old functions.
+
+class darwin_smart_device
+: virtual public /*implements*/ smart_device
+{
+public:
+  explicit darwin_smart_device(const char * mode)
+    : smart_device(never_called),
+      m_fd(-1), m_mode(mode) { }
+
+  virtual ~darwin_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().
+};
+
+
+darwin_smart_device::~darwin_smart_device() throw()
+{
+  if (m_fd >= 0)
+    darwin_smart_device::close();
 }
 
-// tries to guess device type given the name (a path).  See utility.h
-// for return values.
-int guess_device_type (const char * /* dev_name */) {
-  // Only ATA is supported right now, so that's what it'd better be.
-  return CONTROLLER_ATA;
+bool darwin_smart_device::is_open() const
+{
+  return (m_fd >= 0);
 }
 
 // Determine whether 'dev' is a SMART-capable device.
@@ -96,115 +145,39 @@ static bool is_smart_capable (io_object_t dev) {
   // If it's an kIOATABlockStorageDeviceClass then we're successful
   // only if its ATA features indicate it supports SMART.
   if (IOObjectConformsTo (dev, kIOATABlockStorageDeviceClass)
-      && (diskChars = (CFDictionaryRef)IORegistryEntryCreateCFProperty                                                                                                           
-         (dev, CFSTR (kIOPropertyDeviceCharacteristicsKey),
-          kCFAllocatorDefault, kNilOptions)) != NULL)
+    && (diskChars = (CFDictionaryRef)IORegistryEntryCreateCFProperty                                                                                                           
+      (dev, CFSTR (kIOPropertyDeviceCharacteristicsKey),
+        kCFAllocatorDefault, kNilOptions)) != NULL)
     {
       CFNumberRef diskFeatures = NULL;
       UInt32 ataFeatures = 0;
 
       if (CFDictionaryGetValueIfPresent (diskChars, CFSTR ("ATA Features"),
-                                        (const void **)&diskFeatures))
-       CFNumberGetValue (diskFeatures, kCFNumberLongType,
-                         &ataFeatures);
+        (const void **)&diskFeatures))
+      CFNumberGetValue (diskFeatures, kCFNumberLongType,
+        &ataFeatures);
       CFRelease (diskChars);
       if (diskFeatures)
-       CFRelease (diskFeatures);
+        CFRelease (diskFeatures);
       
       return (ataFeatures & kIOATAFeatureSMART) != 0;
     }
   return false;
 }
 
-
-// makes a list of ATA or SCSI devices for the DEVICESCAN directive of
-// smartd.  Returns number N of devices, or -1 if out of
-// memory. Allocates N+1 arrays: one of N pointers (devlist); the
-// 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) {
-  IOReturn err;
-  io_iterator_t i;
-  io_object_t device = MACH_PORT_NULL;
-  int result;
-  int index;
-
-  // We treat all devices as ATA so long as they support SMARTLib.
-  if (strcmp (name, "ATA") != 0)
-    return 0;
-
-  err = IOServiceGetMatchingServices 
-    (kIOMasterPortDefault, IOServiceMatching (kIOBlockStorageDeviceClass), &i);
-  if (err != kIOReturnSuccess)
-    return -1;
-
-  // Count the devices.
-  result = 0;
-  while ((device = IOIteratorNext (i)) != MACH_PORT_NULL) {
-    if (is_smart_capable (device))
-      result++;
-    IOObjectRelease (device);
-  }
-
-  // Create an array of service names.
-  IOIteratorReset (i);
-  *devlist = (char**)Calloc (result, sizeof (char *)); 
-  if (! *devlist)
-    goto error;
-  index = 0;
-  while ((device = IOIteratorNext (i)) != MACH_PORT_NULL) {
-    if (is_smart_capable (device))
-      {
-       io_string_t devName;
-       IORegistryEntryGetPath(device, kIOServicePlane, devName);
-       (*devlist)[index] = CustomStrDup (devName, true, __LINE__, __FILE__);
-       if (! (*devlist)[index])
-         goto error;
-       index++;
-      }
-    IOObjectRelease (device);
-  }
-
-  IOObjectRelease (i);
-  return result;
-
- error:
-  if (device != MACH_PORT_NULL)
-    IOObjectRelease (device);
-  IOObjectRelease (i);
-  if (*devlist)
-    {
-      for (index = 0; index < result; index++)
-       if ((*devlist)[index])
-         FreeNonZero ((*devlist)[index], 0, __LINE__, __FILE__);
-      FreeNonZero (*devlist, result * sizeof (char *), __LINE__, __FILE__);
-    }
-  return -1;
-}
-
-// Information that we keep about each device.
-
-static struct {
-  io_object_t ioob;
-  IOCFPlugInInterface **plugin;
-  IOATASMARTInterface **smartIf;
-} devices[20];
-
-// Like open().  Return non-negative integer handle, only used by the
-// functions below.  type=="ATA" or "SCSI".  The return value is
-// an index into the devices[] array.  If the device can't be opened,
-// sets errno and returns -1.
-// Acceptable device names are:
-// /dev/disk*
-// /dev/rdisk*
-// disk*
-// IOService:*
-// IODeviceTree:*
-int deviceopen(const char *pathname, char *type){
+bool darwin_smart_device::open()
+{
+  // Acceptable device names are:
+  // /dev/disk*
+  // /dev/rdisk*
+  // disk*
+  // IOService:*
+  // IODeviceTree:*
   size_t devnum;
   const char *devname;
   io_object_t disk;
+  const char *pathname = get_dev_name();
+  char *type = const_cast<char*>(m_mode);
   
   if (strcmp (type, "ATA") != 0)
     {
@@ -258,11 +231,11 @@ int deviceopen(const char *pathname, char *type){
       // Find this device's parent and try again.
       err = IORegistryEntryGetParentEntry (disk, kIOServicePlane, &disk);
       if (err != kIOReturnSuccess || ! disk)
-       {
-         errno = ENODEV;
-         IOObjectRelease (prevdisk);
-         return -1;
-       }
+      {
+        errno = ENODEV;
+        IOObjectRelease (prevdisk);
+        return -1;
+      }
     }
   
   devices[devnum].ioob = disk;
@@ -275,151 +248,332 @@ int deviceopen(const char *pathname, char *type){
 
     // Create an interface to the ATA SMART library.
     if (IOCreatePlugInInterfaceForService (disk,
-                                          kIOATASMARTUserClientTypeID,
-                                          kIOCFPlugInInterfaceID,
-                                          &devices[devnum].plugin,
-                                          &dummy) == kIOReturnSuccess)
-      (*devices[devnum].plugin)->QueryInterface
-       (devices[devnum].plugin,
-        CFUUIDGetUUIDBytes ( kIOATASMARTInterfaceID),
-         (void **)&devices[devnum].smartIf);
+      kIOATASMARTUserClientTypeID,
+      kIOCFPlugInInterfaceID,
+      &devices[devnum].plugin,
+      &dummy) == kIOReturnSuccess)
+    (*devices[devnum].plugin)->QueryInterface
+    (devices[devnum].plugin,
+      CFUUIDGetUUIDBytes ( kIOATASMARTInterfaceID),
+      (void **)&devices[devnum].smartIf);
   }
   
-  return devnum;
+  
+  m_fd = devnum;
+  if (m_fd < 0) {
+    set_err((errno==ENOENT || errno==ENOTDIR) ? ENODEV : errno);
+    return false;
+  }
+  return true;
 }
 
-// Like close().  Acts only on integer handles returned by
-// deviceopen() above.
-int deviceclose(int fd){
+bool darwin_smart_device::close()
+{
+  int fd = m_fd; m_fd = -1;
   if (devices[fd].smartIf)
     (*devices[fd].smartIf)->Release (devices[fd].smartIf);
   if (devices[fd].plugin)
     IODestroyPlugInInterface (devices[fd].plugin);
   IOObjectRelease (devices[fd].ioob);
   devices[fd].ioob = MACH_PORT_NULL;
-  return 0;
+  return true;
+}
+
+// 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).
+static int make_device_names (char*** devlist, const char* name) {
+  IOReturn err;
+  io_iterator_t i;
+  io_object_t device = MACH_PORT_NULL;
+  int result;
+  int index;
+
+  // We treat all devices as ATA so long as they support SMARTLib.
+  if (strcmp (name, "ATA") != 0)
+    return 0;
+
+  err = IOServiceGetMatchingServices 
+    (kIOMasterPortDefault, IOServiceMatching (kIOBlockStorageDeviceClass), &i);
+  if (err != kIOReturnSuccess)
+    return -1;
+
+  // Count the devices.
+  result = 0;
+  while ((device = IOIteratorNext (i)) != MACH_PORT_NULL) {
+    if (is_smart_capable (device))
+      result++;
+    IOObjectRelease (device);
+  }
+
+  // Create an array of service names.
+  IOIteratorReset (i);
+  *devlist = (char**)calloc (result, sizeof (char *)); 
+  if (! *devlist)
+    goto error;
+  index = 0;
+  while ((device = IOIteratorNext (i)) != MACH_PORT_NULL) {
+    if (is_smart_capable (device))
+    {
+      io_string_t devName;
+      IORegistryEntryGetPath(device, kIOServicePlane, devName);
+      (*devlist)[index] = strdup (devName);
+      if (! (*devlist)[index])
+        goto error;
+      index++;
+    }
+    IOObjectRelease (device);
+  }
+
+  IOObjectRelease (i);
+  return result;
+
+ error:
+  if (device != MACH_PORT_NULL)
+    IOObjectRelease (device);
+  IOObjectRelease (i);
+  if (*devlist)
+  {
+    for (index = 0; index < result; index++)
+      if ((*devlist)[index])
+      free ((*devlist)[index]);
+      free (*devlist);
+    }
+  return -1;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+/// Implement standard ATA support
+
+class darwin_ata_device
+: public /*implements*/ ata_device,
+  public /*extends*/ darwin_smart_device
+{
+public:
+  darwin_ata_device(smart_interface * intf, const char * dev_name, const char * req_type);
+  virtual bool ata_pass_through(const ata_cmd_in & in, ata_cmd_out & out);
+
+protected:
+  // virtual int ata_command_interface(smart_command_set command, int select, char * data);
+};
+
+darwin_ata_device::darwin_ata_device(smart_interface * intf, const char * dev_name, const char * req_type)
+: smart_device(intf, dev_name, "ata", req_type),
+  darwin_smart_device("ATA")
+{
 }
 
-// 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"
-
-// Things that aren't available in the Darwin interfaces:
-// - Tests other than short and extended (in particular, can't run
-//   an immediate offline test)
-// - Captive-mode tests, aborting tests
-// - ability to switch automatic offline testing on or off
-
-// Note that some versions of Darwin, at least 7H63 and earlier,
-// have a buggy library that treats the boolean value in
-// SMARTEnableDisableOperations, SMARTEnableDisableAutosave, and
-// SMARTExecuteOffLineImmediate as always being true.
-int
-ata_command_interface(int fd, smart_command_set command,
-                     int select, char *data)
+bool darwin_ata_device::ata_pass_through(const ata_cmd_in & in, ata_cmd_out & out)
 {
+  if (!ata_cmd_is_ok(in,
+    true, // data_out_support
+    true, // multi_sector_support
+    false) // not supported by API
+    )
+  return false;
+  
+  int select = 0;
+  char * data = (char *)in.buffer;
+  int fd = get_fd();
   IOATASMARTInterface **ifp = devices[fd].smartIf;
   IOATASMARTInterface *smartIf;
   IOReturn err;
   int timeoutCount = 5;
+  int rc = 0;
   
   if (! ifp)
     return -1;
   smartIf = *ifp;
-
+  clear_err(); errno = 0;
   do {
-    switch (command)
+  switch (in.in_regs.command) {
+    case ATA_IDENTIFY_DEVICE:
       {
-      case STATUS:
-       return 0;
-      case STATUS_CHECK:
-       {
-         Boolean is_failing;
-         err = smartIf->SMARTReturnStatus (ifp, &is_failing);
-         if (err == kIOReturnSuccess && is_failing)
-           return 1;
-         break;
-       }
-      case ENABLE:
-      case DISABLE:
-       err = smartIf->SMARTEnableDisableOperations (ifp, command == ENABLE);
-       break;
-      case AUTOSAVE:
-       err = smartIf->SMARTEnableDisableAutosave (ifp, select != 0);
-       break;
-      case IMMEDIATE_OFFLINE:
-       if (select != SHORT_SELF_TEST && select != EXTEND_SELF_TEST)
-         {
-           errno = EINVAL;
-           return -1;
-         }
-       err = smartIf->SMARTExecuteOffLineImmediate (ifp, 
-                                                    select == EXTEND_SELF_TEST);
-       break;
-      case READ_VALUES:
-       err = smartIf->SMARTReadData (ifp, (ATASMARTData *)data);
-       break;
-      case READ_THRESHOLDS:
-       err = smartIf->SMARTReadDataThresholds (ifp, 
-                                               (ATASMARTDataThresholds *)data);
-       break;
-      case READ_LOG:
-       err = smartIf->SMARTReadLogAtAddress (ifp, select, data, 512);
-       break;
-      case WRITE_LOG:
-       err = smartIf->SMARTWriteLogAtAddress (ifp, select, data, 512);
-       break;
-      case IDENTIFY:
-       {
-         UInt32 dummy;
-         err = smartIf->GetATAIdentifyData (ifp, data, 512, &dummy);
-         if (err != kIOReturnSuccess && err != kIOReturnTimeout
-             && err != kIOReturnNotResponding)
-           printf ("identify failed: %#x\n", (unsigned) err);
-         if (err == kIOReturnSuccess && isbigendian())
-           {
-             int i;
-             /* The system has already byte-swapped, undo it.  */
-             for (i = 0; i < 256; i+=2)
-               swap2 (data + i);
-           }
-       }
-       break;
-      case CHECK_POWER_MODE:
-       // The information is right there in the device registry, but how
-       // to get to it portably?
+        UInt32 dummy;
+        err = smartIf->GetATAIdentifyData (ifp, data, 512, &dummy);
+        if (err != kIOReturnSuccess && err != kIOReturnTimeout
+          && err != kIOReturnNotResponding)
+        printf ("identify failed: %#x\n", (unsigned) rc);
+        if (err == kIOReturnSuccess && isbigendian())
+        {
+          int i;
+          /* The system has already byte-swapped, undo it.  */
+          for (i = 0; i < 256; i+=2)
+            swap2 (data + i);
+        }
+      }
+      break;
+    case ATA_IDENTIFY_PACKET_DEVICE:
+    case ATA_CHECK_POWER_MODE:
+      errno = ENOTSUP;
+      err = -1;
+      break;
+    case ATA_SMART_CMD:
+      switch (in.in_regs.features) {
+      case ATA_SMART_READ_VALUES:
+        err = smartIf->SMARTReadData (ifp, (ATASMARTData *)data);
+        break;
+      case ATA_SMART_READ_THRESHOLDS:
+        err = smartIf->SMARTReadDataThresholds (ifp, 
+          (ATASMARTDataThresholds *)data);
+        break;
+      case ATA_SMART_READ_LOG_SECTOR:
+        err = smartIf->SMARTReadLogAtAddress (ifp, in.in_regs.lba_low, data, 512 * in.in_regs.sector_count);
+        break;
+      case ATA_SMART_WRITE_LOG_SECTOR:
+        err = smartIf->SMARTWriteLogAtAddress (ifp, in.in_regs.lba_low, data, 512 * in.in_regs.sector_count);
+        break;
+      case ATA_SMART_ENABLE:
+      case ATA_SMART_DISABLE:
+        err = smartIf->SMARTEnableDisableOperations (ifp, in.in_regs.features == ATA_SMART_ENABLE);
+        break;
+      case ATA_SMART_STATUS:
+        if (in.out_needed.lba_high) // statuscheck
+        {
+          Boolean is_failing;
+          err = smartIf->SMARTReturnStatus (ifp, &is_failing);
+          if (err == kIOReturnSuccess && is_failing) {
+            err = -1; // thresholds exceeded condition
+            out.out_regs.lba_high = 0x2c; out.out_regs.lba_mid = 0xf4;
+          }
+          else
+            out.out_regs.lba_high = 0xc2; out.out_regs.lba_mid = 0x4f;
+          break;
+        }
+        else err = 0;
+        break;
+      case ATA_SMART_AUTOSAVE:
+        err = smartIf->SMARTEnableDisableAutosave (ifp, 
+          (in.in_regs.sector_count == 241 ? true : false));
+        break;
+      case ATA_SMART_IMMEDIATE_OFFLINE:
+        select = in.in_regs.lba_low;
+        if (select != SHORT_SELF_TEST && select != EXTEND_SELF_TEST)
+        {
+          errno = EINVAL;
+          err = -1;
+        }
+        err = smartIf->SMARTExecuteOffLineImmediate (ifp, 
+          select == EXTEND_SELF_TEST);
+        break;
+      case ATA_SMART_AUTO_OFFLINE:
+        return set_err(ENOSYS, "SMART command not supported");
       default:
-       errno = ENOTSUP;
-       return -1;
+        return set_err(ENOSYS, "Unknown SMART command");
       }
-    /* This bit is a bit strange.  Apparently, when the drive is spun
-       down, the intended behaviour of these calls is that they fail,
-       return kIOReturnTimeout and then power the drive up.  So if
-       you get a timeout, you have to try again to get the actual
-       command run, but the drive is already powering up so you can't
-       use this for CHECK_POWER_MODE.  */
-    if (err == kIOReturnTimeout || err == kIOReturnNotResponding)
-      sleep (1);
+      break;
+    default:
+      return set_err(ENOSYS, "Non-SMART commands not implemented");
+    }
   } while ((err == kIOReturnTimeout || err == kIOReturnNotResponding)
-          && timeoutCount-- > 0);
+  && timeoutCount-- > 0);
   if (err == kIOReturnExclusiveAccess)
     errno = EBUSY;
-  return err == kIOReturnSuccess ? 0 : -1;
+  rc = err == kIOReturnSuccess ? 0 : -1;
+  if (rc < 0) {
+    if (!get_errno())
+      set_err(errno);
+    return false;
+  }
+  return true;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+/// Implement platform interface
+
+class darwin_smart_interface
+: public /*implements*/ smart_interface
+{
+public:
+  virtual std::string 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);
+
+};
+
+
+//////////////////////////////////////////////////////////////////////
+
+std::string darwin_smart_interface::get_app_examples(const char * appname)
+{
+  if (!strcmp(appname, "smartctl"))
+    return smartctl_examples;
+  return ""; // ... so don't print again.
 }
 
-// Interface to SCSI devices.  See os_linux.c
-int do_scsi_cmnd_io(int /* fd */, struct scsi_cmnd_io * /* iop */, int /* report */) {
-  return -ENOSYS;
+ata_device * darwin_smart_interface::get_ata_device(const char * name, const char * type)
+{
+  return new darwin_ata_device(this, name, type);
+}
+
+scsi_device * darwin_smart_interface::get_scsi_device(const char *, const char *)
+{
+  return 0; // scsi devices are not supported [yet]
+}
+
+
+smart_device * darwin_smart_interface::autodetect_smart_device(const char * name)
+{
+  return new darwin_ata_device(this, name, "");
+}
+
+static void free_devnames(char * * devnames, int numdevs)
+{
+  for (int i = 0; i < numdevs; i++)
+    free(devnames[i]);
+  free(devnames);
+}
+
+bool darwin_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;
+    }
+  }
+
+  // Add to devlist
+  int i;
+  if (!type)
+    type="";
+  for (i = 0; i < numata; i++) {
+    ata_device * atadev = get_ata_device(atanames[i], type);
+    if (atadev)
+      devlist.push_back(atadev);
+  }
+  free_devnames(atanames, numata);
+  return true;
+}
+
+} // namespace
+
+
+/////////////////////////////////////////////////////////////////////////////
+/// Initialize platform interface and register with smi()
+
+void smart_interface::init()
+{
+  static os::darwin_smart_interface the_interface;
+  smart_interface::set(&the_interface);
 }
index 502d228f09297487a58cb98e3e6a12b73e9139d4..9c5db2bbf7eb8f8cd2ba6eee52635bd8a98a3a41 100644 (file)
@@ -75,7 +75,7 @@
 #define PATHINQ_SETTINGS_SIZE   128
 #endif
 
-const char *os_XXXX_c_cvsid="$Id: os_freebsd.cpp 3824 2013-07-05 10:40:38Z samm2 $" \
+const char *os_XXXX_c_cvsid="$Id: os_freebsd.cpp 3902 2014-05-23 19:14:15Z samm2 $" \
 ATACMDS_H_CVSID CCISS_H_CVSID CONFIG_H_CVSID INT64_H_CVSID OS_FREEBSD_H_CVSID SCSICMDS_H_CVSID UTILITY_H_CVSID;
 
 #define NO_RETURN 0
@@ -135,9 +135,9 @@ class freebsd_smart_device
 : virtual public /*implements*/ smart_device
 {
 public:
-  explicit freebsd_smart_device(const char * mode)
+  explicit freebsd_smart_device()
     : smart_device(never_called),
-      m_fd(-1), m_mode(mode) { }
+      m_fd(-1) { }
 
   virtual ~freebsd_smart_device() throw();
 
@@ -157,7 +157,6 @@ protected:
 
 private:
   int m_fd; ///< filedesc, -1 if not open.
-  const char * m_mode; ///< Mode string for deviceopen().
 };
 
 #ifdef __GLIBC__
@@ -249,7 +248,7 @@ protected:
 
 freebsd_ata_device::freebsd_ata_device(smart_interface * intf, const char * dev_name, const char * req_type)
 : smart_device(intf, dev_name, "ata", req_type),
-  freebsd_smart_device("ATA")
+  freebsd_smart_device()
 {
 }
 
@@ -445,7 +444,8 @@ int freebsd_atacam_device::do_cmd( struct ata_ioc_request* request, bool is_48bi
   }
 
   if ((ccb.ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
-    cam_error_print(m_camdev, &ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
+    if(scsi_debugmode > 0)
+      cam_error_print(m_camdev, &ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
     set_err(EIO);
     return -1;
   }
@@ -489,10 +489,7 @@ private:
 freebsd_escalade_device::freebsd_escalade_device(smart_interface * intf, const char * dev_name,
     int escalade_type, int disknum)
 : smart_device(intf, dev_name, "3ware", "3ware"),
-  freebsd_smart_device(
-    escalade_type==CONTROLLER_3WARE_9000_CHAR ? "ATA_3WARE_9000" :
-    escalade_type==CONTROLLER_3WARE_678K_CHAR ? "ATA_3WARE_678K" :
-    /*             CONTROLLER_3WARE_678K     */ "ATA"             ),
+  freebsd_smart_device(),
   m_escalade_type(escalade_type), m_disknum(disknum)
 {
   set_info().info_name = strprintf("%s [3ware_disk_%02d]", dev_name, disknum);
@@ -704,7 +701,7 @@ private:
 freebsd_highpoint_device::freebsd_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"),
-  freebsd_smart_device("ATA")
+  freebsd_smart_device()
 {
   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]);
@@ -897,7 +894,6 @@ public:
   virtual bool close();
   
 private:
-  int m_fd;
   struct cam_device *m_camdev;
 };
 
@@ -921,17 +917,16 @@ bool freebsd_scsi_device::close(){
 freebsd_scsi_device::freebsd_scsi_device(smart_interface * intf,
   const char * dev_name, const char * req_type)
 : smart_device(intf, dev_name, "scsi", req_type),
-  freebsd_smart_device("SCSI")
+  freebsd_smart_device()
 {
 }
 
 
 bool freebsd_scsi_device::scsi_pass_through(scsi_cmnd_io * iop)
 {
-  int report=scsi_debugmode;
   union ccb *ccb;
 
-  if (report > 0) {
+  if (scsi_debugmode) {
     unsigned int k;
     const unsigned char * ucp = iop->cmnd;
     const char * np;
@@ -940,7 +935,7 @@ bool freebsd_scsi_device::scsi_pass_through(scsi_cmnd_io * iop)
     pout(" [%s: ", np ? np : "<unknown opcode>");
     for (k = 0; k < iop->cmnd_len; ++k)
       pout("%02x ", ucp[k]);
-    if ((report > 1) && 
+    if ((scsi_debugmode > 1) && 
       (DXFER_TO_DEVICE == iop->dxfer_dir) && (iop->dxferp)) {
     int trunc = (iop->dxfer_len > 256) ? 1 : 0;
 
@@ -949,18 +944,21 @@ bool freebsd_scsi_device::scsi_pass_through(scsi_cmnd_io * iop)
     dStrHex(iop->dxferp, (trunc ? 256 : iop->dxfer_len) , 1);
       }
       else
-        pout("]");
+        pout("]\n");
   }
 
   if(m_camdev==NULL) {
-    warnx("error: camdev=0!");
-    return -ENOTTY;
+    if (scsi_debugmode)
+      pout("  error: camdev=0!\n");
+    return set_err(ENOTTY);
   }
 
   if (!(ccb = cam_getccb(m_camdev))) {
-    warnx("error allocating ccb");
-    return -ENOMEM;
+    if (scsi_debugmode)
+      pout("  error allocating ccb\n");
+    return set_err(ENOMEM);
   }
+
   // mfi SAT layer is known to be buggy
   if(!strcmp("mfi",m_camdev->sim_name)) {
     if (iop->cmnd[0] == SAT_ATA_PASSTHROUGH_12 || iop->cmnd[0] == SAT_ATA_PASSTHROUGH_16) { 
@@ -984,8 +982,8 @@ bool freebsd_scsi_device::scsi_pass_through(scsi_cmnd_io * iop)
     sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
 
   cam_fill_csio(&ccb->csio,
-    /*retrires*/ 1,
-    /*cbfcnp*/ NULL,
+    /* retries */ 1,
+    /* cbfcnp */ NULL,
     /* flags */ (iop->dxfer_dir == DXFER_NONE ? CAM_DIR_NONE :(iop->dxfer_dir == DXFER_FROM_DEVICE ? CAM_DIR_IN : CAM_DIR_OUT)),
     /* tagaction */ MSG_SIMPLE_Q_TAG,
     /* dataptr */ iop->dxferp,
@@ -996,44 +994,81 @@ bool freebsd_scsi_device::scsi_pass_through(scsi_cmnd_io * iop)
   memcpy(ccb->csio.cdb_io.cdb_bytes,iop->cmnd,iop->cmnd_len);
 
   if (cam_send_ccb(m_camdev,ccb) < 0) {
-    warn("error sending SCSI ccb");
-    cam_error_print(m_camdev,ccb,CAM_ESF_ALL,CAM_EPF_ALL,stderr);
+    if (scsi_debugmode) {
+      pout("  error sending SCSI ccb\n");
+      cam_error_print(m_camdev,ccb,CAM_ESF_ALL,CAM_EPF_ALL,stderr);
+    }
     cam_freeccb(ccb);
-    return -EIO;
+    return set_err(EIO);
+  }
+
+  if (scsi_debugmode) {
+    pout("  CAM status=0x%x, SCSI status=0x%x, resid=0x%x\n",
+         ccb->ccb_h.status, ccb->csio.scsi_status, ccb->csio.resid);
+    if ((scsi_debugmode > 1) && (DXFER_FROM_DEVICE == iop->dxfer_dir)) {
+      int trunc, len;
+
+      len = iop->dxfer_len - ccb->csio.resid;
+      trunc = (len > 256) ? 1 : 0;
+      if (len > 0) {
+        pout("  Incoming data, len=%d%s:\n", len,
+             (trunc ? " [only first 256 bytes shown]" : ""));
+        dStrHex(iop->dxferp, (trunc ? 256 : len), 1);
+      }
+      else
+        pout("  Incoming data trimmed to nothing by resid\n");
+    }
   }
 
   if (((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) && ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_SCSI_STATUS_ERROR)) {
-    cam_error_print(m_camdev,ccb,CAM_ESF_ALL,CAM_EPF_ALL,stderr);
+    if (scsi_debugmode)
+      cam_error_print(m_camdev,ccb,CAM_ESF_ALL,CAM_EPF_ALL,stderr);
     cam_freeccb(ccb);
-    return -EIO;
+    return set_err(EIO);
   }
 
-  if (iop->sensep) {
+  iop->resid = ccb->csio.resid;
+  iop->scsi_status = ccb->csio.scsi_status;
+  if (iop->sensep && (ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0) {
+    if (scsi_debugmode)
+      pout("  sense_len=0x%x, sense_resid=0x%x\n",
+           ccb->csio.sense_len, ccb->csio.sense_resid);
     iop->resp_sense_len = ccb->csio.sense_len - ccb->csio.sense_resid;
-    memcpy(iop->sensep,&(ccb->csio.sense_data),iop->resp_sense_len);
+    /* Some SCSI controller device drivers miscalculate the sense_resid
+       field so cap resp_sense_len on max_sense_len. */
+    if (iop->resp_sense_len > iop->max_sense_len)
+      iop->resp_sense_len = iop->max_sense_len;
+    if (iop->resp_sense_len > 0) {
+      memcpy(iop->sensep, &(ccb->csio.sense_data), iop->resp_sense_len);
+      if (scsi_debugmode) {
+        if (scsi_debugmode > 1) {
+          pout("  >>> Sense buffer, len=%zu:\n", iop->resp_sense_len);
+          dStrHex(iop->sensep, iop->resp_sense_len, 1);
+        }
+        if ((iop->sensep[0] & 0x7f) > 0x71)
+          pout("  status=0x%x: [desc] sense_key=0x%x asc=0x%x ascq=0x%x\n",
+               iop->scsi_status, iop->sensep[1] & 0xf,
+               iop->sensep[2], iop->sensep[3]);
+        else
+          pout("  status=0x%x: sense_key=0x%x asc=0x%x ascq=0x%x\n",
+               iop->scsi_status, iop->sensep[2] & 0xf,
+               iop->sensep[12], iop->sensep[13]);
+      }
+    }
+    else if (scsi_debugmode)
+      pout("  status=0x%x\n", iop->scsi_status);
   }
-
-  iop->scsi_status = ccb->csio.scsi_status;
+  else if (scsi_debugmode)
+    pout("  status=0x%x\n", iop->scsi_status);
 
   cam_freeccb(ccb);
 
-  if (report > 0) {
-    int trunc;
-
-    pout("  status=0\n");
-    trunc = (iop->dxfer_len > 256) ? 1 : 0;
-
-    pout("  Incoming data, len=%d%s:\n", (int)iop->dxfer_len,
-      (trunc ? " [only first 256 bytes shown]" : ""));
-    dStrHex(iop->dxferp, (trunc ? 256 : iop->dxfer_len) , 1);
-  }
-
   // mfip replacing PDT of the device so response does not make a sense
   // this sets PDT to 00h - direct-access block device
   if((!strcmp("mfi", m_camdev->sim_name) || !strcmp("mpt", m_camdev->sim_name))
    && iop->cmnd[0] == INQUIRY) {
-     if (report > 0) {
-        pout("device on %s controller, patching PDT\n", m_camdev->sim_name);
+     if (scsi_debugmode) {
+        pout("  device on %s controller, patching PDT\n", m_camdev->sim_name);
      }
      iop->dxferp[0] = iop->dxferp[0] & 0xe0;
   }
@@ -1077,7 +1112,7 @@ public:
 // Areca RAID Controller(SATA Disk)
 freebsd_areca_ata_device::freebsd_areca_ata_device(smart_interface * intf, const char * dev_name, int disknum, int encnum)
 : smart_device(intf, dev_name, "areca", "areca"),
-  freebsd_smart_device("ATA")
+  freebsd_smart_device()
 {
   set_disknum(disknum);
   set_encnum(encnum);
@@ -1146,7 +1181,7 @@ bool freebsd_areca_ata_device::arcmsr_unlock()
 // Areca RAID Controller(SAS Device)
 freebsd_areca_scsi_device::freebsd_areca_scsi_device(smart_interface * intf, const char * dev_name, int disknum, int encnum)
 : smart_device(intf, dev_name, "areca", "areca"),
-  freebsd_smart_device("SCSI")
+  freebsd_smart_device()
 {
   set_disknum(disknum);
   set_encnum(encnum);
@@ -1220,7 +1255,7 @@ bool freebsd_cciss_device::open()
 freebsd_cciss_device::freebsd_cciss_device(smart_interface * intf,
   const char * dev_name, unsigned char disknum)
 : smart_device(intf, dev_name, "cciss", "cciss"),
-  freebsd_smart_device("SCSI"),
+  freebsd_smart_device(),
   m_disknum(disknum)
 {
   set_info().info_name = strprintf("%s [cciss_disk_%02d]", dev_name, disknum);
index dbdab1f4be3e3ee9ffdc214198680dec4e8ea3e4..4a96a821f02393f153f586e0be3a2aa7c2109bd0 100644 (file)
@@ -5,16 +5,23 @@
  *
  * Copyright (C) 2003-11 Bruce Allen <smartmontools-support@lists.sourceforge.net>
  * Copyright (C) 2003-11 Doug Gilbert <dgilbert@interlog.com>
- * Copyright (C) 2008-12 Hank Wu <hank@areca.com.tw>
- * Copyright (C) 2008    Oliver Bock <brevilo@users.sourceforge.net>
- * Copyright (C) 2008-12 Christian Franke <smartmontools-support@lists.sourceforge.net>
- * Copyright (C) 2008    Jordan Hargrave <jordan_hargrave@dell.com>
+ * Copyright (C) 2008-14 Christian Franke <smartmontools-support@lists.sourceforge.net>
  *
- *  Parts of this file are derived from code that was
+ * Original AACRaid code:
+ *  Copyright (C) 2014    Raghava Aditya <raghava.aditya@pmcs.com>
+ *
+ * Original Areca code:
+ *  Copyright (C) 2008-12 Hank Wu <hank@areca.com.tw>
+ *  Copyright (C) 2008    Oliver Bock <brevilo@users.sourceforge.net>
+ *
+ * Original MegaRAID code:
+ *  Copyright (C) 2008    Jordan Hargrave <jordan_hargrave@dell.com>
+ *
+ * 3ware code was derived from code that was:
  *
  *  Written By: Adam Radford <linux@3ware.com>
  *  Modifications By: Joel Jacobson <linux@3ware.com>
- *                   Arnaldo Carvalho de Melo <acme@conectiva.com.br>
+ *                    Arnaldo Carvalho de Melo <acme@conectiva.com.br>
  *                    Brad Strand <linux@3ware.com>
  *
  *  Copyright (C) 1999-2003 3ware Inc.
@@ -80,6 +87,7 @@
 #include "utility.h"
 #include "cciss.h"
 #include "megaraid.h"
+#include "aacraid.h"
 
 #include "dev_interface.h"
 #include "dev_ata_cmd_set.h"
@@ -91,7 +99,7 @@
 
 #define ARGUSED(x) ((void)(x))
 
-const char * os_linux_cpp_cvsid = "$Id: os_linux.cpp 3824 2013-07-05 10:40:38Z samm2 $"
+const char * os_linux_cpp_cvsid = "$Id: os_linux.cpp 3900 2014-05-01 17:08:59Z chrfranke $"
   OS_LINUX_H_CVSID;
 extern unsigned char failuretest_permissive;
 
@@ -859,6 +867,217 @@ bool linux_scsi_device::scsi_pass_through(scsi_cmnd_io * iop)
   return true;
 }
 
+/////////////////////////////////////////////////////////////////////////////
+/// PMC AacRAID support
+
+class linux_aacraid_device
+:public   scsi_device,
+ public /*extends */   linux_smart_device
+{
+public:
+  linux_aacraid_device(smart_interface *intf, const char *dev_name,
+    unsigned int host, unsigned int channel, unsigned int device);
+
+  virtual ~linux_aacraid_device() throw();
+
+  virtual bool open();
+
+  virtual bool scsi_pass_through(scsi_cmnd_io *iop);
+
+private:
+  //Device Host number
+  int aHost;
+
+  //Channel(Lun) of the device
+  int aLun;
+
+  //Id of the device
+  int aId;
+
+};
+
+linux_aacraid_device::linux_aacraid_device(smart_interface *intf,
+  const char *dev_name, unsigned int host, unsigned int channel, unsigned int device)
+   : smart_device(intf,dev_name,"aacraid","aacraid"),
+     linux_smart_device(O_RDWR|O_NONBLOCK),
+     aHost(host), aLun(channel), aId(device)
+{
+  set_info().info_name = strprintf("%s [aacraid_disk_%02d_%02d_%d]",dev_name,aHost,aLun,aId);
+  set_info().dev_type  = strprintf("aacraid,%d,%d,%d",aHost,aLun,aId);
+}
+
+linux_aacraid_device::~linux_aacraid_device() throw()
+{
+}
+
+bool linux_aacraid_device::open()
+{
+  //Create the character device name based on the host number
+  //Required for get stats from disks connected to different controllers
+  char dev_name[128];
+  snprintf(dev_name, sizeof(dev_name), "/dev/aac%d", aHost);
+
+  //Initial open of dev name to check if it exsists
+  int afd = ::open(dev_name,O_RDWR);
+
+  if(afd < 0 && errno == ENOENT) {
+
+    FILE *fp = fopen("/proc/devices","r");
+    if(NULL == fp)
+      return set_err(errno,"cannot open /proc/devices:%s",
+                     strerror(errno));
+
+    char line[256];
+    int mjr = -1;
+
+    while(fgets(line,sizeof(line),fp) !=NULL) {
+      int nc = -1;
+      if(sscanf(line,"%d aac%n",&mjr,&nc) == 1
+                && nc > 0 && '\n' == line[nc])
+        break;
+      mjr = -1;
+    }
+
+    //work with /proc/devices is done
+    fclose(fp);
+
+    if (mjr < 0)
+      return set_err(ENOENT, "aac entry not found in /proc/devices");
+
+    //Create misc device file in /dev/ used for communication with driver
+    if(mknod(dev_name,S_IFCHR,makedev(mjr,aHost)))
+      return set_err(errno,"cannot create %s:%s",dev_name,strerror(errno));
+
+    afd = ::open(dev_name,O_RDWR);
+  }
+
+  if(afd < 0)
+    return set_err(errno,"cannot open %s:%s",dev_name,strerror(errno));
+
+  set_fd(afd);
+  return true;
+}
+
+bool linux_aacraid_device::scsi_pass_through(scsi_cmnd_io *iop)
+{
+  int report = scsi_debugmode;
+
+  if (report > 0) {
+    int k, j;
+    const unsigned char * ucp = iop->cmnd;
+    const char * np;
+    char buff[256];
+    const int sz = (int)sizeof(buff);
+
+    np = scsi_get_opcode_name(ucp[0]);
+    j  = snprintf(buff, sz, " [%s: ", np ? np : "<unknown opcode>");
+    for (k = 0; k < (int)iop->cmnd_len; ++k)
+      j += snprintf(&buff[j], (sz > j ? (sz - j) : 0), "%02x ", ucp[k]);
+      if ((report > 1) &&
+        (DXFER_TO_DEVICE == iop->dxfer_dir) && (iop->dxferp)) {
+        int trunc = (iop->dxfer_len > 256) ? 1 : 0;
+
+        j += snprintf(&buff[j], (sz > j ? (sz - j) : 0), "]\n  Outgoing "
+                      "data, len=%d%s:\n", (int)iop->dxfer_len,
+                      (trunc ? " [only first 256 bytes shown]" : ""));
+        dStrHex((const char *)iop->dxferp,
+               (trunc ? 256 : iop->dxfer_len) , 1);
+    }
+    else
+      j += snprintf(&buff[j], (sz > j ? (sz - j) : 0), "]\n");
+
+    pout("%s", buff);
+  }
+
+
+  //return test commands
+  if (iop->cmnd[0] == 0x00)
+    return true;
+
+  user_aac_reply *pReply;
+
+  #ifdef ENVIRONMENT64
+    // Create user 64 bit request
+    user_aac_srb64  *pSrb;
+    uint8_t aBuff[sizeof(user_aac_srb64) + sizeof(user_aac_reply)] = {0,};
+
+    pSrb    = (user_aac_srb64*)aBuff;
+    pReply  = (user_aac_reply*)(aBuff+sizeof(user_aac_srb64));
+
+ #elif defined(ENVIRONMENT32)
+    //Create user 32 bit request
+    user_aac_srb32  *pSrb;
+    uint8_t aBuff[sizeof(user_aac_srb32) + sizeof(user_aac_reply)] = {0,};
+
+    pSrb    = (user_aac_srb32*)aBuff;
+    pReply  = (user_aac_reply*)(aBuff+sizeof(user_aac_srb32));
+
+ #endif
+
+  pSrb->function = SRB_FUNCTION_EXECUTE_SCSI;
+  //channel is 0 always
+  pSrb->channel  = 0;
+  pSrb->id       = aId;
+  pSrb->lun      = aLun;
+  pSrb->timeout  = 0;
+
+  pSrb->retry_limit = 0;
+  pSrb->cdb_size    = iop->cmnd_len;
+
+  switch(iop->dxfer_dir) {
+    case DXFER_NONE:
+      pSrb->flags = SRB_NoDataXfer;
+      break;
+    case DXFER_FROM_DEVICE:
+      pSrb->flags = SRB_DataIn;
+      break;
+    case DXFER_TO_DEVICE:
+      pSrb->flags = SRB_DataOut;
+      break;
+    default:
+      pout("aacraid: bad dxfer_dir\n");
+      return set_err(EINVAL, "aacraid: bad dxfer_dir\n");
+  }
+
+  if(iop->dxfer_len > 0) {
+
+    #ifdef ENVIRONMENT64
+      pSrb->sg64.count = 1;
+      pSrb->sg64.sg64[0].addr64.lo32 = ((intptr_t)iop->dxferp) &
+                                         0x00000000ffffffff;
+      pSrb->sg64.sg64[0].addr64.hi32 = ((intptr_t)iop->dxferp) >> 32;
+
+      pSrb->sg64.sg64[0].length = (uint32_t)iop->dxfer_len;
+      pSrb->count = sizeof(user_aac_srb64) +
+                          (sizeof(user_sgentry64)*(pSrb->sg64.count-1));
+    #elif defined(ENVIRONMENT32)
+      pSrb->sg32.count = 1;
+      pSrb->sg32.sg32[0].addr32 = (intptr_t)iop->dxferp;
+
+      pSrb->sg32.sg32[0].length = (uint32_t)iop->dxfer_len;
+      pSrb->count = sizeof(user_aac_srb32) +
+                          (sizeof(user_sgentry32)*(pSrb->sg32.count-1));
+    #endif
+
+  }
+
+  memcpy(pSrb->cdb,iop->cmnd,iop->cmnd_len);
+
+  int rc = 0;
+  errno = 0;
+  rc = ioctl(get_fd(),FSACTL_SEND_RAW_SRB,pSrb);
+  if(rc!= 0 || pReply->srb_status != 0x01) {
+    if(pReply->srb_status == 0x08) {
+      return set_err(EIO, "aacraid: Device %d %d does not exist\n" ,aLun,aId );
+    }
+  return set_err((errno ? errno : EIO), "aacraid result: %d.%d = %d/%d",
+                            aLun, aId, errno,
+                            pReply->srb_status);
+  }
+  return true;
+}
+
+
 /////////////////////////////////////////////////////////////////////////////
 /// LSI MegaRAID support
 
@@ -2488,7 +2707,7 @@ bool linux_smart_interface::get_dev_list(smart_device_list & devlist,
   }
 
   // did we find too many paths?
-  const int max_pathc = 32;
+  const int max_pathc = 1024;
   int n = (int)globbuf.gl_pathc;
   if (n > max_pathc) {
     pout("glob(3) found %d > MAX=%d devices matching pattern %s: ignoring %d paths\n",
@@ -2939,12 +3158,23 @@ smart_device * linux_smart_interface::get_custom_smart_device(const char * name,
   if (sscanf(type, "megaraid,%d", &disknum) == 1) {
     return new linux_megaraid_device(this, name, 0, disknum);
   }
+
+  //aacraid?
+  unsigned int device;
+  unsigned int host;
+  if(sscanf(type, "aacraid,%d,%d,%d", &host, &channel, &device)==3) {
+    //return new linux_aacraid_device(this,name,channel,device);
+    return get_sat_device("sat,auto",
+      new linux_aacraid_device(this, name, host, channel, device));
+
+  }
+
   return 0;
 }
 
 std::string linux_smart_interface::get_valid_custom_dev_types_str()
 {
-  return "marvell, areca,N/E, 3ware,N, hpt,L/M/N, megaraid,N"
+  return "marvell, areca,N/E, 3ware,N, hpt,L/M/N, megaraid,N, aacraid,H,L,ID"
 #ifdef HAVE_LINUX_CCISS_IOCTL_H
                                               ", cciss,N"
 #endif
index 8e4abfb2479afe5f0549ffb08634a97dd6336ee2..2414d131be55dc0e39e6f4485c069961ef531fc7 100644 (file)
@@ -3,7 +3,7 @@
  *
  * Home page of code is: http://smartmontools.sourceforge.net
  *
- * Copyright (C) 2004-13 Christian Franke <smartmontools-support@lists.sourceforge.net>
+ * Copyright (C) 2004-14 Christian Franke <smartmontools-support@lists.sourceforge.net>
  * Copyright (C) 2012    Hank Wu <hank@areca.com.tw>
  *
  * This program is free software; you can redistribute it and/or modify
@@ -95,7 +95,7 @@
 #define SELECT_WIN_32_64(x32, x64) (x64)
 #endif
 
-const char * os_win32_cpp_cvsid = "$Id: os_win32.cpp 3830 2013-07-18 20:59:53Z chrfranke $";
+const char * os_win32_cpp_cvsid = "$Id: os_win32.cpp 3923 2014-06-25 17:10:46Z chrfranke $";
 
 /////////////////////////////////////////////////////////////////////////////
 // Windows I/O-controls, some declarations are missing in the include files
@@ -400,19 +400,19 @@ class csmi_device
 : virtual public /*extends*/ smart_device
 {
 public:
-  /// Get phy info
-  bool get_phy_info(CSMI_SAS_PHY_INFO & phy_info);
-
-  /// Check physical drive existence
-  bool check_phy(const CSMI_SAS_PHY_INFO & phy_info, unsigned phy_no);
+  /// Get bitmask of used ports
+  unsigned get_ports_used();
 
 protected:
   csmi_device()
     : smart_device(never_called)
     { memset(&m_phy_ent, 0, sizeof(m_phy_ent)); }
 
+  /// Get phy info
+  bool get_phy_info(CSMI_SAS_PHY_INFO & phy_info);
+
   /// Select physical drive
-  bool select_phy(unsigned phy_no);
+  bool select_port(int port);
 
   /// Get info for selected physical drive
   const CSMI_SAS_PHY_ENTITY & get_phy_ent() const
@@ -465,7 +465,7 @@ protected:
 
 private:
   HANDLE m_fh; ///< Controller device handle
-  unsigned m_phy_no; ///< Physical drive number
+  int m_port; ///< Port number
 };
 
 
@@ -1013,12 +1013,13 @@ bool win_smart_interface::scan_smart_devices(smart_device_list & devlist,
       win_csmi_device test_dev(this, name, "");
       if (!test_dev.open_scsi())
         continue;
-      CSMI_SAS_PHY_INFO phy_info;
-      if (!test_dev.get_phy_info(phy_info))
+
+      unsigned ports_used = test_dev.get_ports_used();
+      if (!ports_used)
         continue;
 
-      for (int pi = 0; pi < phy_info.bNumberOfPhys; pi++) {
-        if (!test_dev.check_phy(phy_info, pi))
+      for (int pi = 0; pi < 32; pi++) {
+        if (!(ports_used & (1 << pi)))
           continue;
         snprintf(name, sizeof(name)-1, "/dev/csmi%d,%d", i, pi);
         devlist.push_back( new win_csmi_device(this, name, "ata") );
@@ -2888,14 +2889,19 @@ bool csmi_device::get_phy_info(CSMI_SAS_PHY_INFO & phy_info)
     return false;
 
   phy_info = phy_info_buf.Information;
-  if (phy_info.bNumberOfPhys > sizeof(phy_info.Phy)/sizeof(phy_info.Phy[0]))
+
+  const int max_number_of_phys = sizeof(phy_info.Phy) / sizeof(phy_info.Phy[0]);
+  if (phy_info.bNumberOfPhys > max_number_of_phys)
     return set_err(EIO, "CSMI_SAS_PHY_INFO: Bogus NumberOfPhys=%d", phy_info.bNumberOfPhys);
 
   if (scsi_debugmode > 1) {
     pout("CSMI_SAS_PHY_INFO: NumberOfPhys=%d\n", phy_info.bNumberOfPhys);
-    for (int i = 0; i < phy_info.bNumberOfPhys; i++) {
+    for (int i = 0; i < max_number_of_phys; i++) {
       const CSMI_SAS_PHY_ENTITY & pe = phy_info.Phy[i];
       const CSMI_SAS_IDENTIFY & id = pe.Identify, & at = pe.Attached;
+      if (id.bDeviceType == CSMI_SAS_NO_DEVICE_ATTACHED)
+        continue;
+
       pout("Phy[%d] Port:   0x%02x\n", i, pe.bPortIdentifier);
       pout("  Type:        0x%02x, 0x%02x\n", id.bDeviceType, at.bDeviceType);
       pout("  InitProto:   0x%02x, 0x%02x\n", id.bInitiatorPortProtocol, at.bInitiatorPortProtocol);
@@ -2913,40 +2919,92 @@ bool csmi_device::get_phy_info(CSMI_SAS_PHY_INFO & phy_info)
   return true;
 }
 
-bool csmi_device::check_phy(const CSMI_SAS_PHY_INFO & phy_info, unsigned phy_no)
+unsigned csmi_device::get_ports_used()
 {
-  // Check Phy presence
-  if (phy_no >= phy_info.bNumberOfPhys)
-    return set_err(ENOENT, "Port %u does not exist (#ports: %d)", phy_no,
-      phy_info.bNumberOfPhys);
+  CSMI_SAS_PHY_INFO phy_info;
+  if (!get_phy_info(phy_info))
+    return 0;
 
-  const CSMI_SAS_PHY_ENTITY & phy_ent = phy_info.Phy[phy_no];
-  if (phy_ent.Attached.bDeviceType == CSMI_SAS_NO_DEVICE_ATTACHED)
-    return set_err(ENOENT, "No device on port %u", phy_no);
+  unsigned ports_used = 0;
+  for (unsigned i = 0; i < sizeof(phy_info.Phy) / sizeof(phy_info.Phy[0]); i++) {
+    const CSMI_SAS_PHY_ENTITY & pe = phy_info.Phy[i];
+    if (pe.Identify.bDeviceType == CSMI_SAS_NO_DEVICE_ATTACHED)
+      continue;
+    if (pe.Attached.bDeviceType == CSMI_SAS_NO_DEVICE_ATTACHED)
+      continue;
+    switch (pe.Attached.bTargetPortProtocol) {
+      case CSMI_SAS_PROTOCOL_SATA:
+      case CSMI_SAS_PROTOCOL_STP:
+        break;
+      default:
+        continue;
+    }
 
-  switch (phy_ent.Attached.bTargetPortProtocol) {
-    case CSMI_SAS_PROTOCOL_SATA:
-    case CSMI_SAS_PROTOCOL_STP:
-      break;
-    default:
-      return set_err(ENOENT, "No SATA device on port %u (protocol: %u)",
-        phy_no, phy_ent.Attached.bTargetPortProtocol);
+    if (pe.bPortIdentifier == 0xff)
+      // Older (<= 9.*) Intel RST driver
+      ports_used |= (1 << i);
+    else
+      ports_used |= (1 << pe.bPortIdentifier);
   }
 
-  return true;
+  return ports_used;
 }
 
-bool csmi_device::select_phy(unsigned phy_no)
+
+bool csmi_device::select_port(int port)
 {
   CSMI_SAS_PHY_INFO phy_info;
   if (!get_phy_info(phy_info))
     return false;
 
+  // Find port
+  int max_port = -1, port_index = -1;
+  for (unsigned i = 0; i < sizeof(phy_info.Phy) / sizeof(phy_info.Phy[0]); i++) {
+    const CSMI_SAS_PHY_ENTITY & pe = phy_info.Phy[i];
+    if (pe.Identify.bDeviceType == CSMI_SAS_NO_DEVICE_ATTACHED)
+      continue;
 
-  if (!check_phy(phy_info, phy_no))
-    return false;
+    if (pe.bPortIdentifier == 0xff) {
+      // Older (<= 9.*) Intel RST driver
+      max_port = phy_info.bNumberOfPhys - 1;
+      if (i >= phy_info.bNumberOfPhys)
+        break;
+      if ((int)i != port)
+        continue;
+    }
+    else {
+      if (pe.bPortIdentifier > max_port)
+        max_port = pe.bPortIdentifier;
+      if (pe.bPortIdentifier != port)
+        continue;
+    }
 
-  m_phy_ent = phy_info.Phy[phy_no];
+    port_index = i;
+    break;
+  }
+
+  if (port_index < 0) {
+    if (port <= max_port)
+      return set_err(ENOENT, "Port %d is disabled", port);
+    else
+      return set_err(ENOENT, "Port %d does not exist (#ports: %d)", port,
+        max_port + 1);
+  }
+
+  const CSMI_SAS_PHY_ENTITY & phy_ent = phy_info.Phy[port_index];
+  if (phy_ent.Attached.bDeviceType == CSMI_SAS_NO_DEVICE_ATTACHED)
+    return set_err(ENOENT, "No device on port %d", port);
+
+  switch (phy_ent.Attached.bTargetPortProtocol) {
+    case CSMI_SAS_PROTOCOL_SATA:
+    case CSMI_SAS_PROTOCOL_STP:
+      break;
+    default:
+      return set_err(ENOENT, "No SATA device on port %d (protocol: %d)",
+        port, phy_ent.Attached.bTargetPortProtocol);
+  }
+
+  m_phy_ent = phy_ent;
   return true;
 }
 
@@ -3055,7 +3113,7 @@ bool csmi_ata_device::ata_pass_through(const ata_cmd_in & in, ata_cmd_out & out)
 win_csmi_device::win_csmi_device(smart_interface * intf, const char * dev_name,
   const char * req_type)
 : smart_device(intf, dev_name, "ata", req_type),
-  m_fh(INVALID_HANDLE_VALUE), m_phy_no(0)
+  m_fh(INVALID_HANDLE_VALUE), m_port(-1)
 {
 }
 
@@ -3083,10 +3141,10 @@ bool win_csmi_device::close()
 bool win_csmi_device::open_scsi()
 {
   // Parse name
-  unsigned contr_no = ~0, phy_no = ~0; int nc = -1;
+  unsigned contr_no = ~0, port = ~0; int nc = -1;
   const char * name = skipdev(get_dev_name());
-  if (!(   sscanf(name, "csmi%u,%u%n", &contr_no, &phy_no, &nc) >= 0
-        && nc == (int)strlen(name) && contr_no <= 9 && phy_no < 32)  )
+  if (!(   sscanf(name, "csmi%u,%u%n", &contr_no, &port, &nc) >= 0
+        && nc == (int)strlen(name) && contr_no <= 9 && port < 32)  )
     return set_err(EINVAL);
 
   // Open controller handle
@@ -3112,7 +3170,7 @@ bool win_csmi_device::open_scsi()
     pout(" %s: successfully opened\n", devpath);
 
   m_fh = h;
-  m_phy_no = phy_no;
+  m_port = port;
   return true;
 }
 
@@ -3123,7 +3181,7 @@ bool win_csmi_device::open()
     return false;
 
   // Get Phy info for this drive
-  if (!select_phy(m_phy_no)) {
+  if (!select_port(m_port)) {
     close();
     return false;
   }
@@ -3427,14 +3485,14 @@ bool win_scsi_device::scsi_pass_through(struct scsi_cmnd_io * iop)
   } else
     iop->resp_sense_len = 0;
 
-  if ((iop->dxfer_len > 0) && (sb.spt.DataTransferLength > 0))
+  if (iop->dxfer_len > sb.spt.DataTransferLength)
     iop->resid = iop->dxfer_len - sb.spt.DataTransferLength;
   else
     iop->resid = 0;
 
   if ((iop->dxfer_dir == DXFER_FROM_DEVICE) && (report > 1)) {
      int trunc = (iop->dxfer_len > 256) ? 1 : 0;
-     pout("  Incoming data, len=%d%s:\n", (int)iop->dxfer_len,
+     pout("  Incoming data, len=%d, resid=%d%s:\n", (int)iop->dxfer_len, iop->resid,
         (trunc ? " [only first 256 bytes shown]" : ""));
         dStrHex(iop->dxferp, (trunc ? 256 : iop->dxfer_len) , 1);
   }
@@ -3553,14 +3611,14 @@ static long scsi_pass_through_direct(HANDLE fd, UCHAR targetid, struct scsi_cmnd
   } else
     iop->resp_sense_len = 0;
 
-  if ((iop->dxfer_len > 0) && (sb.spt.DataTransferLength > 0))
+  if (iop->dxfer_len > sb.spt.DataTransferLength)
     iop->resid = iop->dxfer_len - sb.spt.DataTransferLength;
   else
     iop->resid = 0;
 
   if ((iop->dxfer_dir == DXFER_FROM_DEVICE) && (report > 1)) {
      int trunc = (iop->dxfer_len > 256) ? 1 : 0;
-     pout("  Incoming data, len=%d%s:\n", (int)iop->dxfer_len,
+     pout("  Incoming data, len=%d, resid=%d%s:\n", (int)iop->dxfer_len, iop->resid,
         (trunc ? " [only first 256 bytes shown]" : ""));
         dStrHex(iop->dxferp, (trunc ? 256 : iop->dxfer_len) , 1);
   }
index 9404efd0c486ee957a9d7519f6e505260d3d803f..56b0d79c552abe42238ff693929e00498f4fd588 100644 (file)
@@ -3,7 +3,7 @@
  *
  * Home page of code is: http://smartmontools.sourceforge.net
  *
- * Copyright (C) 2004-13 Christian Franke <smartmontools-support@lists.sourceforge.net>
+ * Copyright (C) 2004-14 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,7 +20,7 @@
 
 #include "daemon_win32.h"
 
-const char * daemon_win32_cpp_cvsid = "$Id: daemon_win32.cpp 3834 2013-07-20 16:17:13Z chrfranke $"
+const char * daemon_win32_cpp_cvsid = "$Id: daemon_win32.cpp 3959 2014-07-18 19:22:18Z chrfranke $"
   DAEMON_WIN32_H_CVSID;
 
 #include <stdio.h>
@@ -34,11 +34,6 @@ const char * daemon_win32_cpp_cvsid = "$Id: daemon_win32.cpp 3834 2013-07-20 16:
 #include <crtdbg.h>
 #endif
 
-#ifndef SERVICE_CONFIG_DELAYED_AUTO_START_INFO
-// Missing in older MinGW headers
-#define SERVICE_CONFIG_DELAYED_AUTO_START_INFO 3
-#endif
-
 
 /////////////////////////////////////////////////////////////////////////////
 
@@ -1011,8 +1006,13 @@ static int svcadm_main(const char * ident, const daemon_winsvc_options * svc_opt
     if (   GetVersionExA(&ver)
         && ver.dwPlatformId == VER_PLATFORM_WIN32_NT
         && ver.dwMajorVersion >= 6 /* Vista */      ) {
-      SERVICE_DELAYED_AUTO_START_INFO sdasi = { TRUE };
-      ChangeServiceConfig2A(hs, SERVICE_CONFIG_DELAYED_AUTO_START_INFO, &sdasi);
+      // SERVICE_{,CONFIG_}DELAYED_AUTO_START_INFO are missing in older MinGW headers
+      struct /* SERVICE_DELAYED_AUTO_START_INFO */ {
+        BOOL fDelayedAutostart;
+      } sdasi = { TRUE };
+      // typedef char ASSERT_sizeof_sdasi[sizeof(sdasi) == sizeof(SERVICE_DELAYED_AUTO_START_INFO) ? 1 : -1];
+      // typedef char ASSERT_const_scdasi[SERVICE_CONFIG_DELAYED_AUTO_START_INFO == 3 ? 1 : -1];
+      ChangeServiceConfig2A(hs, 3 /* SERVICE_CONFIG_DELAYED_AUTO_START_INFO */, &sdasi);
     }
   }
   else {
index 9682946b0d2b8c8bfe5096d9599d92c50e6c1fec..23a8f5b9c5fa92213be0f56f31a61bfe813ffb22 100644 (file)
@@ -3,7 +3,7 @@
 ;
 ; Home page of code is: http://smartmontools.sourceforge.net
 ;
-; Copyright (C) 2006-13 Christian Franke <smartmontools-support@lists.sourceforge.net>
+; Copyright (C) 2006-14 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
@@ -13,7 +13,7 @@
 ; You should have received a copy of the GNU General Public License
 ; (for example COPYING); If not, see <http://www.gnu.org/licenses/>.
 ;
-; $Id: installer.nsi 3759 2013-01-26 21:11:02Z chrfranke $
+; $Id: installer.nsi 3912 2014-06-18 19:03:30Z chrfranke $
 ;
 
 
@@ -208,20 +208,23 @@ Section "Uninstaller" UNINST_SECTION
 
   CreateDirectory "$INSTDIR"
 
-  ; Save installation location
-  WriteRegStr HKLM "Software\smartmontools" "Install_Dir" "$INSTDIR"
+  ; Keep old Install_Dir registry entry for GSmartControl
+  ReadRegStr $0 HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\GSmartControl" "InstallLocation"
+  ReadRegStr $1 HKLM "Software\smartmontools" "Install_Dir"
+  StrCmp "$0$1" "" +2 0
+    WriteRegStr HKLM "Software\smartmontools" "Install_Dir" "$INSTDIR"
 
   ; 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" "InstallLocation" "$INSTDIR"
   WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\smartmontools" "UninstallString" '"$INSTDIR\uninst-smartmontools.exe"'
-  ;WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\smartmontools" "URLInfoAbout" "http://smartmontools.sourceforge.net/"
-  WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\smartmontools" "HelpLink"     "http://smartmontools.sourceforge.net/"
-  ;WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\smartmontools" "URLUpdateInfo" "http://sourceforge.net/project/showfiles.php?group_id=64297"
-  WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\smartmontools" "URLUpdateInfo" "http://smartmontools-win32.dyndns.org/"
+  WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\smartmontools" "Publisher"     "smartmontools.org"
+  WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\smartmontools" "URLInfoAbout"  "http://www.smartmontools.org/"
+  WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\smartmontools" "HelpLink"      "http://sourceforge.net/projects/smartmontools/support"
+  WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\smartmontools" "URLUpdateInfo" "http://smartmontools.no-ip.org/"
   WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\smartmontools" "NoModify" 1
   WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\smartmontools" "NoRepair" 1
   WriteUninstaller "uninst-smartmontools.exe"
@@ -313,11 +316,11 @@ Section "Start Menu Shortcuts" MENU_SECTION
     CreateShortCut "$SMPROGRAMS\smartmontools\Documentation\ChangeLog.lnk" "$INSTDIR\doc\ChangeLog.txt"
     CreateShortCut "$SMPROGRAMS\smartmontools\Documentation\COPYING.lnk"   "$INSTDIR\doc\COPYING.txt"
     CreateShortCut "$SMPROGRAMS\smartmontools\Documentation\NEWS.lnk"      "$INSTDIR\doc\NEWS.txt"
-    CreateShortCut "$SMPROGRAMS\smartmontools\Documentation\Windows version download page.lnk" "http://smartmontools-win32.dyndns.org/smartmontools/"
+    CreateShortCut "$SMPROGRAMS\smartmontools\Documentation\Windows version download page.lnk" "http://smartmontools.no-ip.org/"
   nodoc:
 
   ; Homepage
-  CreateShortCut "$SMPROGRAMS\smartmontools\smartmontools Home Page.lnk" "http://smartmontools.sourceforge.net/"
+  CreateShortCut "$SMPROGRAMS\smartmontools\smartmontools Home Page.lnk" "http://www.smartmontools.org/"
 
   ; drivedb.h update
   IfFileExists "$INSTDIR\bin\update-smart-drivedb.exe" 0 noupdb
@@ -500,6 +503,8 @@ Function .onInit
 
   ; Set default install directories
   StrCmp $INSTDIR "" 0 endinst ; /D=PATH option specified ?
+  ReadRegStr $INSTDIR HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\smartmontools" "InstallLocation"
+  StrCmp $INSTDIR "" 0 endinst ; Already installed ?
   ReadRegStr $INSTDIR HKLM "Software\smartmontools" "Install_Dir"
   StrCmp $INSTDIR "" 0 endinst ; Already installed ?
     StrCpy $INSTDIR "$PROGRAMFILES\smartmontools"
index b4d6d377f1aecc522b3c3c98bd1a680bcb978e12..b2068e698e4ddadf5a49cdfb21d7d138b54a52cb 100644 (file)
@@ -1,7 +1,7 @@
 //
 // os_win32/smartctl_res.rc.in
 //
-// $Id: smartctl_res.rc.in 3755 2013-01-26 15:13:08Z chrfranke $
+// $Id: smartctl_res.rc.in 3878 2014-03-03 18:45:21Z chrfranke $
 //
 
 1 VERSIONINFO
@@ -21,7 +21,7 @@ BEGIN
             VALUE "FileDescription", "Control and Monitor Utility for SMART Disks"
             VALUE "FileVersion", "@TEXT_VERSION@"
             VALUE "InternalName", "smartctl"
-            VALUE "LegalCopyright", "(C) 2002-13, Bruce Allen, Christian Franke, www.smartmontools.org"
+            VALUE "LegalCopyright", "(C) 2002-@YY@, Bruce Allen, Christian Franke, www.smartmontools.org"
             VALUE "OriginalFilename", "smartctl.exe"
             VALUE "ProductName", "smartmontools"
             VALUE "ProductVersion", "@TEXT_VERSION@"
index f7900eeb1e6278df6a8efe930e29a1356c28afc1..07529b73c3b6ece2da979ecb75af8902aaa99a03 100644 (file)
@@ -1,7 +1,7 @@
 //
 // os_win32/smartd_res.rc.in
 //
-// $Id: smartd_res.rc.in 3756 2013-01-26 16:16:35Z chrfranke $
+// $Id: smartd_res.rc.in 3878 2014-03-03 18:45:21Z chrfranke $
 //
 
 1 VERSIONINFO
@@ -21,7 +21,7 @@ BEGIN
             VALUE "FileDescription", "SMART Disk Monitoring Daemon"
             VALUE "FileVersion", "@TEXT_VERSION@"
             VALUE "InternalName", "smartd"
-            VALUE "LegalCopyright", "(C) 2002-13, Bruce Allen, Christian Franke, www.smartmontools.org"
+            VALUE "LegalCopyright", "(C) 2002-@YY@, Bruce Allen, Christian Franke, www.smartmontools.org"
             VALUE "OriginalFilename", "smartd.exe"
             VALUE "ProductName", "smartmontools"
             VALUE "ProductVersion", "@TEXT_VERSION@"
index f7b790df1537e6c1a98d177d73a2c716d189a437..abcb468d80161811c68f816e43b343a1884981c9 100644 (file)
@@ -62,7 +62,7 @@
 #include "dev_ata_cmd_set.h" // ata_device_with_command_set
 #include "dev_tunnelled.h" // tunnelled_device<>
 
-const char * scsiata_cpp_cvsid = "$Id: scsiata.cpp 3741 2013-01-02 17:06:54Z chrfranke $";
+const char * scsiata_cpp_cvsid = "$Id: scsiata.cpp 3922 2014-06-23 19:17:18Z chrfranke $";
 
 /* This is a slightly stretched SCSI sense "descriptor" format header.
    The addition is to allow the 0x70 and 0x71 response codes. The idea
@@ -980,7 +980,7 @@ bool usbjmicron_device::ata_pass_through(const ata_cmd_in & in, ata_cmd_out & ou
   memset(&io_hdr, 0, sizeof(io_hdr));
 
   bool rwbit = true;
-  unsigned char smart_status = 0;
+  unsigned char smart_status = 0xff;
 
   bool is_smart_status = (   in.in_regs.command  == ATA_SMART_CMD
                           && in.in_regs.features == ATA_SMART_STATUS);
@@ -1038,15 +1038,22 @@ bool usbjmicron_device::ata_pass_through(const ata_cmd_in & in, ata_cmd_out & ou
 
   if (in.out_needed.is_set()) {
     if (is_smart_status) {
+      if (io_hdr.resid == 1)
+        // Some (Prolific) USB bridges do not transfer a status byte
+        return set_err(ENOSYS, "Incomplete response, status byte missing [JMicron]");
+
       switch (smart_status) {
-        case 0x01: case 0xc2:
+        case 0xc2:
           out.out_regs.lba_high = 0xc2;
           out.out_regs.lba_mid = 0x4f;
           break;
-        case 0x00: case 0x2c:
+        case 0x2c:
           out.out_regs.lba_high = 0x2c;
           out.out_regs.lba_mid = 0xf4;
           break;
+        default:
+          // Some (JM20336) USB bridges always return 0x01, regardless of SMART Status
+          return set_err(ENOSYS, "Invalid status byte (0x%02x) [JMicron]", smart_status);
       }
     }
 
index 623be8d65aee1fc83da60685749ae6b18aae19fc..bb505c0c3e69dd9fd5addfaea0098f4b4e1a0294 100644 (file)
@@ -49,7 +49,7 @@
 #include "dev_interface.h"
 #include "utility.h"
 
-const char *scsicmds_c_cvsid="$Id: scsicmds.cpp 3820 2013-06-17 08:45:10Z samm2 $"
+const char *scsicmds_c_cvsid="$Id: scsicmds.cpp 3915 2014-06-19 18:24:57Z dpgilbert $"
   SCSICMDS_H_CVSID;
 
 // Print SCSI debug messages?
@@ -60,7 +60,7 @@ supported_vpd_pages * supported_vpd_pages_p = NULL;
 
 supported_vpd_pages::supported_vpd_pages(scsi_device * device) : num_valid(0)
 {
-    unsigned char b[0x1fc];     /* size chosen for old INQUIRY command */
+    unsigned char b[0xfc];     /* pre SPC-3 INQUIRY max response size */
     int n;
 
     memset(b, 0, sizeof(b));
@@ -1441,12 +1441,13 @@ scsiSetExceptionControlAndWarning(scsi_device * device, int enabled,
     if (offset < 0)
         return -EINVAL;
     memcpy(rout, iecp->raw_curr, SCSI_IECMP_RAW_LEN);
+    /* mask out DPOFUA device specific (disk) parameter bit */
     if (10 == iecp->modese_len) {
         resp_len = (rout[0] << 8) + rout[1] + 2;
-        rout[3] &= 0xef;    /* for disks mask out DPOFUA bit */
+        rout[3] &= 0xef;
     } else {
         resp_len = rout[0] + 1;
-        rout[2] &= 0xef;    /* for disks mask out DPOFUA bit */
+        rout[2] &= 0xef;
     }
     sp = (rout[offset] & 0x80) ? 1 : 0; /* PS bit becomes 'SELECT's SP bit */
     if (enabled) {
@@ -2479,7 +2480,8 @@ scsiFetchControlGLTSD(scsi_device * device, int modese_len, int current)
  * RIGID_DISK_DRIVE_GEOMETRY_PAGE mode page. */
 
 int
-scsiGetRPM(scsi_device * device, int modese_len, int * form_factorp)
+scsiGetRPM(scsi_device * device, int modese_len, int * form_factorp,
+           int * haw_zbcp)
 {
     int err, offset, speed;
     UINT8 buff[64];
@@ -2492,10 +2494,14 @@ scsiGetRPM(scsi_device * device, int modese_len, int * form_factorp)
         speed = (buff[4] << 8) + buff[5];
         if (form_factorp)
             *form_factorp = buff[7] & 0xf;
+        if (haw_zbcp)
+            *haw_zbcp = !!(0x10 & buff[8]);
         return speed;
     }
     if (form_factorp)
         *form_factorp = 0;
+    if (haw_zbcp)
+        *haw_zbcp = 0;
     if (modese_len <= 6) {
         if ((err = scsiModeSense(device, RIGID_DISK_DRIVE_GEOMETRY_PAGE, 0, pc,
                                  buff, sizeof(buff)))) {
@@ -2599,12 +2605,13 @@ scsiGetSetCache(scsi_device * device,  int modese_len, short int * wcep,
           buff[offset + 2] &= 0xfe; // clear bit
     }
 
+    /* mask out DPOFUA device specific (disk) parameter bit */
     if (10 == modese_len) {
         resp_len = (buff[0] << 8) + buff[1] + 2;
-        buff[3] &= 0xef;    /* for disks mask out DPOFUA bit */
+        buff[3] &= 0xef;
     } else {
         resp_len = buff[0] + 1;
-        buff[2] &= 0xef;    /* for disks mask out DPOFUA bit */
+        buff[2] &= 0xef;
     }
     sp = 0; /* Do not change saved values */
     if (10 == modese_len)
@@ -2667,14 +2674,15 @@ scsiSetControlGLTSD(scsi_device * device, int enabled, int modese_len)
     if (err)
         return err;
     if (0 == (ch_buff[offset + 2] & 2))
-        return SIMPLE_ERR_BAD_PARAM;  /* GLTSD bit not chageable */
+        return SIMPLE_ERR_BAD_PARAM;  /* GLTSD bit not changeable */
 
+    /* mask out DPOFUA device specific (disk) parameter bit */
     if (10 == modese_len) {
         resp_len = (buff[0] << 8) + buff[1] + 2;
-        buff[3] &= 0xef;    /* for disks mask out DPOFUA bit */
+        buff[3] &= 0xef;    
     } else {
         resp_len = buff[0] + 1;
-        buff[2] &= 0xef;    /* for disks mask out DPOFUA bit */
+        buff[2] &= 0xef;
     }
     sp = (buff[offset] & 0x80) ? 1 : 0; /* PS bit becomes 'SELECT's SP bit */
     if (enabled)
index afe656ecf99e154f4ad13a55420cee9a1ab35b0f..c28e830742577148b9601a83618d03876a2dc1aa 100644 (file)
@@ -32,7 +32,7 @@
 #ifndef SCSICMDS_H_
 #define SCSICMDS_H_
 
-#define SCSICMDS_H_CVSID "$Id: scsicmds.h 3783 2013-03-02 01:51:12Z dpgilbert $\n"
+#define SCSICMDS_H_CVSID "$Id: scsicmds.h 3896 2014-04-28 04:31:25Z dpgilbert $\n"
 
 #include <stdio.h>
 #include <stdlib.h>
@@ -420,7 +420,8 @@ 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);
-int scsiGetRPM(scsi_device * device, int modese_len, int * form_factorp);
+int scsiGetRPM(scsi_device * device, int modese_len, int * form_factorp,
+               int * haw_zbcp);
 int scsiGetSetCache(scsi_device * device,  int modese_len, short int * wce,
                     short int * rcd);
 uint64_t scsiGetSize(scsi_device * device, unsigned int * lb_sizep,
index 5c5b6e09fc0cb31320fb68820108bf309b4a885a..95568b4045b10088ee603a4ca59412abf9458e5b 100644 (file)
@@ -42,7 +42,7 @@
 
 #define GBUF_SIZE 65535
 
-const char * scsiprint_c_cvsid = "$Id: scsiprint.cpp 3807 2013-04-18 17:11:12Z chrfranke $"
+const char * scsiprint_c_cvsid = "$Id: scsiprint.cpp 3898 2014-04-30 17:44:13Z dpgilbert $"
                                  SCSIPRINT_H_CVSID;
 
 
@@ -470,7 +470,7 @@ scsiPrintSeagateCacheLPage(scsi_device * device)
                 ull <<= 8;
             ull |= xp[j];
         }
-        pout(" = %"PRIu64"\n", ull);
+        pout(" = %" PRIu64 "\n", ull);
         num -= pl;
         ucp += pl;
     }
@@ -565,7 +565,7 @@ scsiPrintSeagateFactoryLPage(scsi_device * device)
             if (0 == pc)
                 pout(" = %.2f\n", ull / 60.0 );
             else
-                pout(" = %"PRIu64"\n", ull);
+                pout(" = %" PRIu64 "\n", ull);
         }
         num -= pl;
         ucp += pl;
@@ -616,11 +616,11 @@ scsiPrintErrorCounterLog(scsi_device * device)
             if (! found[k])
                 continue;
             ecp = &errCounterArr[k];
-            pout("%s%8"PRIu64" %8"PRIu64"  %8"PRIu64"  %8"PRIu64"   %8"PRIu64,
+            pout("%s%8" PRIu64 " %8" PRIu64 "  %8" PRIu64 "  %8" PRIu64 "   %8" PRIu64,
                  pageNames[k], ecp->counter[0], ecp->counter[1],
                  ecp->counter[2], ecp->counter[3], ecp->counter[4]);
             processed_gb = ecp->counter[5] / 1000000000.0;
-            pout("   %12.3f    %8"PRIu64"\n", processed_gb, ecp->counter[6]);
+            pout("   %12.3f    %8" PRIu64 "\n", processed_gb, ecp->counter[6]);
         }
     }
     else
@@ -629,12 +629,12 @@ scsiPrintErrorCounterLog(scsi_device * device)
                 NON_MEDIUM_ERROR_LPAGE, 0, gBuf, LOG_RESP_LEN, 0))) {
         scsiDecodeNonMediumErrPage(gBuf, &nme);
         if (nme.gotPC0)
-            pout("\nNon-medium error count: %8"PRIu64"\n", nme.counterPC0);
+            pout("\nNon-medium error count: %8" PRIu64 "\n", nme.counterPC0);
         if (nme.gotTFE_H)
-            pout("Track following error count [Hitachi]: %8"PRIu64"\n",
+            pout("Track following error count [Hitachi]: %8" PRIu64 "\n",
                  nme.counterTFE_H);
         if (nme.gotPE_H)
-            pout("Positioning error count [Hitachi]: %8"PRIu64"\n",
+            pout("Positioning error count [Hitachi]: %8" PRIu64 "\n",
                  nme.counterPE_H);
     }
     if (gLastNErrorLPage && (0 == scsiLogSense(device,
@@ -843,8 +843,8 @@ scsiPrintSelfTest(scsi_device * device)
             char buff[32];
 
             // was hex but change to decimal to conform with ATA
-            snprintf(buff, sizeof(buff), "%"PRIu64, ull);
-            // snprintf(buff, sizeof(buff), "0x%"PRIx64, ull);
+            snprintf(buff, sizeof(buff), "%" PRIu64, ull);
+            // snprintf(buff, sizeof(buff), "0x%" PRIx64, ull);
             pout("%18s", buff);
         } else
             pout("                 -");
@@ -863,7 +863,7 @@ scsiPrintSelfTest(scsi_device * device)
     else
     if ((0 == scsiFetchExtendedSelfTestTime(device, &durationSec,
                         modese_len)) && (durationSec > 0)) {
-        pout("Long (extended) Self Test duration: %d seconds "
+        pout("\nLong (extended) Self Test duration: %d seconds "
              "[%.1f minutes]\n", durationSec, durationSec / 60.0);
     }
     pout("\n");
@@ -1048,11 +1048,12 @@ scsiPrintSSMedia(scsi_device * device)
         case 1:
             if (pl < 8) {
                 print_on();
-                pout("Percentage used endurance indicator too short (pl=%d)\n", pl);
+                pout("SS Media Percentage used endurance indicator parameter "
+                     "too short (pl=%d)\n", pl);
                 print_off();
                 return FAILSMART;
             }
-            pout("SS Media used endurance indicator: %d%%\n", ucp[7]);
+            pout("Percentage used endurance indicator: %d%%\n", ucp[7]);
         default:        /* ignore other parameter codes */
             break;
         }
@@ -1221,7 +1222,7 @@ show_sas_port_param(unsigned char * ucp, int param_len)
         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 1: snprintf(s, sz, "SAS or SATA 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;
@@ -1279,6 +1280,7 @@ show_sas_port_param(unsigned char * ucp, int param_len)
         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;
+        case 0xb: snprintf(s, sz, "phy enabled; 12 Gbps"); break;
         default: snprintf(s, sz, "reserved [%d]", t); break;
         }
         pout("    negotiated logical link rate: %s\n", s);
@@ -1347,12 +1349,8 @@ show_protocol_specific_page(unsigned char * resp, int len)
 }
 
 
-// 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.
+// See Serial Attached SCSI (SPL-3) (e.g. revision 6g) the Protocol Specific
+// log page [0x18]. Returns 0 if ok else FAIL* bitmask.
 static int
 scsiPrintSasPhy(scsi_device * device, int reset)
 {
@@ -1410,6 +1408,22 @@ static const char * peripheral_dt_arr[] = {
         "enclosure",
         "simplified disk",
         "optical card reader"
+        "reserved [0x10]"
+        "object based storage"
+        "automation/driver interface"
+        "security manager device"
+        "host managed zoned block device"
+        "reserved [0x15]"
+        "reserved [0x16]"
+        "reserved [0x17]"
+        "reserved [0x18]"
+        "reserved [0x19]"
+        "reserved [0x1a]"
+        "reserved [0x1b]"
+        "reserved [0x1c]"
+        "reserved [0x1d]"
+        "well known logical unit"
+        "unknown or no device type"
 };
 
 static const char * transport_proto_arr[] = {
@@ -1419,11 +1433,11 @@ static const char * transport_proto_arr[] = {
         "IEEE 1394 (SBP-2)",
         "RDMA (SRP)",
         "iSCSI",
-        "SAS",
+        "SAS (SPL-3)",
         "ADT",
-        "0x8",
-        "0x9",
-        "0xa",
+        "ATA (ACS-2)",
+        "UAS",
+        "SOP",
         "0xb",
         "0xc",
         "0xd",
@@ -1437,12 +1451,13 @@ scsiGetDriveInfo(scsi_device * device, UINT8 * peripheral_type, bool all)
 {
     char timedatetz[DATEANDEPOCHLEN];
     struct scsi_iec_mode_page iec;
-    int err, iec_err, len, req_len, avail_len, n;
+    int err, iec_err, len, req_len, avail_len, n, scsi_version;
     int is_tape = 0;
     int peri_dt = 0;
     int returnval = 0;
     int transport = -1;
     int form_factor = 0;
+    int haw_zbc = 0;
     int protect = 0;
 
     memset(gBuf, 0, 96);
@@ -1474,6 +1489,9 @@ scsiGetDriveInfo(scsi_device * device, UINT8 * peripheral_type, bool all)
         print_off();
         return 1;
     }
+    // Upper bits of version bytes were used in older standards
+    // Only interested in SPC-4 (0x6) and SPC-5 (assumed to be 0x7)
+    scsi_version = gBuf[2] & 0x7;
 
     if (all && (0 != strncmp((char *)&gBuf[8], "ATA", 3))) {
         char vendor[8+1], product[16+1], revision[4+1];
@@ -1486,6 +1504,10 @@ scsiGetDriveInfo(scsi_device * device, UINT8 * peripheral_type, bool all)
         pout("Product:              %.16s\n", product);
         if (gBuf[32] >= ' ')
             pout("Revision:             %.4s\n", revision);
+        if (scsi_version == 0x6)
+            pout("Compliance:           SPC-4\n");
+        else if (scsi_version == 0x7)
+            pout("Compliance:           SPC-5\n");
     }
 
     if (!*device->get_req_type()/*no type requested*/ &&
@@ -1527,7 +1549,8 @@ scsiGetDriveInfo(scsi_device * device, UINT8 * peripheral_type, bool all)
                              (lb_size * (1 << lb_per_pb_exp)));
                     pout("Physical block size:  %s bytes\n", lb_str);
                     n = ((rc16_12[2] & 0x3f) << 8) + rc16_12[3];
-                    pout("Lowest aligned LBA:   %d\n", n);
+                    if (n > 0)  // not common so cut the clutter
+                        pout("Lowest aligned LBA:   %d\n", n);
                 }
                 if (rc16_12[0] & 0x1) { /* PROT_EN set */
                     int p_type = ((rc16_12[0] >> 1) & 0x7);
@@ -1566,8 +1589,8 @@ scsiGetDriveInfo(scsi_device * device, UINT8 * peripheral_type, bool all)
                 lbprz = !! (lb_prov_resp[5] & 0x4);
             switch (prov_type) {
             case 0:
-                pout("Logical block provisioning type unreported, "
-                     "LBPME=%d, LBPRZ=%d\n", lbpme, lbprz);
+                pout("LB provisioning type: unreported, LBPME=%d, LBPRZ=%d\n",
+                     lbpme, lbprz);
                 break;
             case 1:
                 pout("LU is resource provisioned, LBPRZ=%d\n", lbprz);
@@ -1583,10 +1606,14 @@ scsiGetDriveInfo(scsi_device * device, UINT8 * peripheral_type, bool all)
         } else if (1 == lbpme)
             pout("Logical block provisioning enabled, LBPRZ=%d\n", lbprz);
 
-        int rpm = scsiGetRPM(device, modese_len, &form_factor);
-        if (rpm > 0) {
-            if (1 == rpm)
+        int rpm = scsiGetRPM(device, modese_len, &form_factor, &haw_zbc);
+        if (rpm >= 0) {
+            if (0 == rpm)
+                ;       // Not reported
+            else if (1 == rpm)
                 pout("Rotation Rate:        Solid State Device\n");
+            else if ((rpm <= 0x400) || (0xffff == rpm))
+                ;       // Reserved
             else
                 pout("Rotation Rate:        %d rpm\n", rpm);
         }
@@ -1613,6 +1640,8 @@ scsiGetDriveInfo(scsi_device * device, UINT8 * peripheral_type, bool all)
             if (cp)
                 pout("Form Factor:          %s inches\n", cp);
         }
+        if (haw_zbc > 0)
+            pout("Host aware zoned block capable\n");
     }
 
     /* Do this here to try and detect badly conforming devices (some USB
@@ -2107,7 +2136,7 @@ scsiPrintMain(scsi_device * device, const scsi_print_options & options)
         pout("Self Test returned without error\n");
         any_output = true;
     }
-    if (options.sasphy) {
+    if (options.sasphy && gProtocolSpecificLPage) {
         if (scsiPrintSasPhy(device, options.sasphy_reset))
             return returnval | FAILSMART;
         any_output = true;
index e7a2dcea1e49331fde9551e23310518c5e85ebbc..aa79757402535d354ba834426fd3ca24a95dd0a2 100644 (file)
@@ -1,8 +1,8 @@
 .ig
 Copyright (C) 2002-10 Bruce Allen <smartmontools-support@lists.sourceforge.net>
-Copyright (C) 2004-13 Christian Franke <smartmontools-support@lists.sourceforge.net>
+Copyright (C) 2004-14 Christian Franke <smartmontools-support@lists.sourceforge.net>
 
-$Id: smartctl.8.in 3832 2013-07-20 14:49:31Z chrfranke $
+$Id: smartctl.8.in 3965 2014-07-20 14:46:41Z 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
@@ -25,11 +25,6 @@ California, Santa Cruz. http://ssrc.soe.ucsc.edu/
 .SH SYNOPSIS
 .B smartctl [options] device
 
-.\" %IF NOT OS Windows
-.SH FULL PATH
-.B /usr/local/sbin/smartctl
-
-.\" %ENDIF NOT OS Windows
 .SH PACKAGE VERSION
 CURRENT_SVN_VERSION CURRENT_SVN_DATE CURRENT_SVN_REV
 
@@ -47,7 +42,7 @@ and predict drive failures, and to carry out different types of drive
 self-tests.
 \fBsmartctl\fP also supports some features not related to SMART.
 This version of \fBsmartctl\fP is compatible with
-ACS-2, ATA8-ACS, ATA/ATAPI-7 and earlier standards
+ACS-3, ACS-2, ATA8-ACS, ATA/ATAPI-7 and earlier standards
 (see \fBREFERENCES\fP below).
 
 \fBsmartctl\fP also provides support for polling TapeAlert messages
@@ -164,9 +159,7 @@ values in base 10 (decimal), but some values are displayed in base 16
 displayed with a leading \fB"0x"\fP, for example: "0xff". This man
 page follows the same convention.
 
-.PP
 .SH OPTIONS
-.PP
 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.
@@ -195,8 +188,7 @@ drive model family may also be printed. If \'\-n\' (see below) is
 specified, the power mode of the drive is printed.
 .TP
 .B \-\-identify[=[w][nvb]]
-[ATA only] [NEW EXPERIMENTAL SMARTCTL FEATURE] Prints an annotated
-table of the IDENTIFY DEVICE data.
+[ATA only] Prints an annotated table of the IDENTIFY DEVICE data.
 By default, only valid words (words not equal to 0x0000 or 0xffff)
 and nonzero bits and bit fields are printed.
 This can be changed by the optional argument which consists of one or
@@ -375,11 +367,28 @@ It is possible to set RAID device name as /dev/bus/N, where N is a SCSI bus
 number.
 
 The following entry in /proc/devices must exist:
-.fi
+.br
 For PERC2/3/4 controllers: \fBmegadevN\fP
-.fi
+.br
 For PERC5/6 controllers: \fBmegaraid_sas_ioctlN\fP
 
+.I aacraid,H,L,ID
+\- [Linux only] [NEW EXPERIMENTAL SMARTCTL FEATURE]
+the device consists of one or more SCSI/SAS disks connected to an AacRaid controller.
+The non-negative integers H,L,ID (Host number, Lun, ID) denote which disk
+on the controller is monitored.
+Use syntax such as:
+.nf
+\fBsmartctl \-a \-d aacraid,0,0,66 /dev/sda\fP
+.fi
+.nf
+\fBsmartctl \-a \-d aacraid,0,0,66 /dev/sdb\fP
+.fi
+The L and ID numbers of a disk can be found in /proc/scsi/scsi
+
+The following entry in /proc/devices must exist: \fBaac\fP.
+Character device nodes /dev/aacH (H=Host number) are created if required.
+
 .\" %ENDIF OS Linux
 .\" %IF OS FreeBSD Linux
 .I 3ware,N
@@ -736,11 +745,7 @@ Note that the SMART automatic offline test command is listed as
 "Obsolete" in every version of the ATA and ATA/ATAPI Specifications.
 It was originally part of the SFF-8035i Revision 2.0 specification,
 but was never part of any ATA specification.  However it is
-implemented and used by many vendors. [Good documentation can be found
-in IBM\'s Official Published Disk Specifications.  For example the IBM
-Travelstar 40GNX Hard Disk Drive Specifications (Revision 1.1, 22
-April 2002, Publication # 1541, Document S07N-7715-02) page 164. You
-can also read the SFF-8035i Specification -- see REFERENCES below.]
+implemented and used by many vendors.
 You can tell if automatic offline testing is supported by seeing if
 this command enables and disables it, as indicated by the \'Auto
 Offline Data Collection\' part of the SMART capabilities report
@@ -1098,13 +1103,12 @@ specification.  Some commands are not defined in any version of the
 ATA specification but are in common use nonetheless; these are marked
 \fB[NS]\fP, meaning non-standard.
 
-The ATA Specification (ATA-5 Revision 1c, Section 8.41.6.8.2) says:
-\fB"Error log structures shall include UNC errors, IDNF errors for
-which the address requested was valid, servo errors, write fault
-errors, etc.  Error log data structures shall not include errors
-attributed to the receipt of faulty commands such as command codes not
-implemented by the device or requests with invalid parameters or
-invalid addresses."\fP The definitions of these terms are:
+The ATA Specification (ATA ACS-2 Revision 7, Section A.7.1) says:
+\fB"Error log data structures shall include, but are not limited to,
+Uncorrectable errors, ID Not Found errors for which the LBA requested was
+valid, servo errors, and write fault errors.  Error log data structures
+shall not include errors attributed to the receipt of faulty commands."\fP
+The definitions of these terms are:
 .br
 \fBUNC\fP (\fBUNC\fPorrectable): data is uncorrectable.  This refers
 to data which has been read from the disk, but for which the Error
@@ -1142,8 +1146,7 @@ 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).
+specific.
 
 Only the 8 most recent error log entries are printed by default.
 This number can be changed by the optional parameter NUM.
@@ -1197,7 +1200,7 @@ test terminology).
 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).
+is vendor specific.
 
 Only the 25 most recent log entries are printed by default. This number
 can be changed by the optional parameter NUM.
@@ -1270,7 +1273,7 @@ is vendor specific, typical values are 1, 2, or 5 minutes.
 .I scterc[,READTIME,WRITETIME]
 \- [ATA only] prints values and descriptions of the SCT Error Recovery
 Control settings. These are equivalent to TLER (as used by Western
-Digital), CCTL (as used by Samsung and Hitachi) and ERC (as used by
+Digital), CCTL (as used by Samsung and Hitachi/HGST) and ERC (as used by
 Seagate). READTIME and WRITETIME arguments (deciseconds) set the
 specified values. Values of 0 disable the feature, other values less
 than 65 are probably not supported. For RAID configurations, this is
@@ -1281,9 +1284,7 @@ typically set to 70,70 deciseconds.
 log pages (General Purpose Log address 0x04).  If no PAGE number is specified,
 entries from all supported pages are printed.  If PAGE 0 is specified,
 the list of supported pages is printed.  Device Statistics was
-introduced in ACS-2 and is only supported by some recent devices
-(e.g. Hitachi 7K3000, Intel 320, 330, 520 and 710 Series SSDs, Crucial/Micron
-m4 SSDs).
+introduced in ACS-2 and is only supported by some recent devices.
 
 .I sataphy[,reset]
 \- [SATA only] prints values and descriptions of the SATA Phy Event
@@ -1525,10 +1526,6 @@ is not reset if uncorrectable sectors are reallocated
 .I 220,temp
 \- same as:
 .I 220,tempminmax,Temperature_Celsius.
-
-Note: a table of hard drive models, listing which Attribute
-corresponds to temperature, can be found at:
-\fBhttp://www.guzu.net/linux/hddtemp.db\fP
 .TP
 .B \-F TYPE, \-\-firmwarebug=TYPE
 [ATA only] Modifies the behavior of \fBsmartctl\fP to compensate for some
@@ -1538,7 +1535,7 @@ multiple times.  The valid arguments are:
 .I none
 \- Assume that the device firmware obeys the ATA specifications.  This
 is the default, unless the device has presets for \'\-F\' in the
-drive database.  Using this option on the command line will over-ride any
+drive database.  Using this option on the command line will override any
 preset values.
 
 .I nologdir
@@ -1573,7 +1570,7 @@ execution status (see options \'\-c\' or \'\-a\' above) accordingly.
 
 .I xerrorlba
 \- Fixes LBA byte ordering in Extended Comprehensive SMART error log.
-Some disk use little endian byte ordering instead of ATA register
+Some disks use little endian byte ordering instead of ATA register
 ordering to specifiy the LBA addresses in the log entries.
 
 .I swapid
@@ -1585,15 +1582,6 @@ firmware version) returned by some buggy device drivers.
 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
-drives.  For example, the Maxtor 4D080H4 uses Attribute 9 to stores
-power-on time in minutes whereas most drives use that Attribute to
-store the power-on time in hours.  The command-line option \'\-v
-9,minutes\' ensures that \fBsmartctl\fP correctly interprets Attribute
-9 in this case, but that option is preset for the Maxtor 4D080H4 and
-so need not be specified by the user on the \fBsmartctl\fP command
-line.
-
 The argument
 .I show
 will show any preset options for your drive and the argument
@@ -1926,7 +1914,7 @@ T13/1699-D Revision 6a (ATA8-ACS).  Note that the subcommands
 \fBWARNING: Only run subcommands documented by the vendor of the
 device.\fP
 
-Example for Intel (X18/X25-M G2, 320, 520 and 710 Series) SSDs only:
+Example for some Intel SSDs only:
 The subcommand 0x40 (\'\-t vendor,0x40\') clears the timed workload
 related SMART attributes (226, 227, 228).  Note that the raw values of
 these attributes are held at 65535 (0xffff) until the workload timer
@@ -1951,7 +1939,7 @@ mounted partitions!\fP
 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
@@ -1995,7 +1983,7 @@ 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
@@ -2124,7 +2112,7 @@ device is restored.
 .fi
 Examine all SMART data for the first SCSI disk connected to a cciss
 RAID controller card.
-.PP
+
 .SH RETURN VALUES
 The return values of \fBsmartctl\fP are defined by a bitmask.  If all
 is well with the disk, the return value (exit status) of
@@ -2165,8 +2153,8 @@ The device self-test log contains records of errors.
 self-test are ignored.
 .PP
 To test within the shell for whether or not the different bits are
-turned on or off, you can use the following type of construction (this
-is bash syntax):
+turned on or off, you can use the following type of construction
+(which should work with any POSIX compatible shell):
 .nf
 .B smartstat=$(($? & 8))
 .fi
@@ -2175,23 +2163,37 @@ This looks at only at bit 3 of the exit status
 (since 8=2^3).  The shell variable
 $smartstat will be nonzero if SMART status check returned "disk
 failing" and zero otherwise.
-
-This bash script prints all status bits:
+.PP
+This shell script prints all status bits:
 .nf
-status=$?
-for ((i=0; i<8; i++)); do
-  echo "Bit $i: $((status & 2**i && 1))"
+val=$?; mask=1
+for i in 0 1 2 3 4 5 6 7; do
+  echo "Bit $i: $(((val & mask) && 1))"
+  mask=$((mask << 1))
 done
 .fi
 
-.PP
+.\" %IF NOT OS Windows
+.SH FILES
+.TP
+.B /usr/local/sbin/smartctl
+full path of this executable.
+.\" %IF ENABLE_DRIVEDB
+.TP
+.B /usr/local/share/smartmontools/drivedb.h
+drive database (see \'\-B\' option).
+.\" %ENDIF ENABLE_DRIVEDB
+.TP
+.B /usr/local/etc/smart_drivedb.h
+optional local drive database (see \'\-B\' option).
+
+.\" %ENDIF NOT OS Windows
 .SH NOTES
 The TapeAlert log page flags are cleared for the initiator when the
 page is read. This means that each alert condition is reported only
 once by \fBsmartctl\fP for each initiator for each activation of the
 condition.
 
-.PP
 .SH AUTHORS
 \fBBruce Allen\fP
 .br
@@ -2202,49 +2204,53 @@ since 2009)
 .br
 \fBsmartmontools\-support@lists.sourceforge.net\fP
 
-.PP
-.SH CONTRIBUTORS
 The following have made large contributions to smartmontools:
-.nf
+.br
 \fBCasper Dik\fP (Solaris SCSI interface)
+.br
 \fBDouglas Gilbert\fP (SCSI subsystem)
+.br
 \fBGuido Guenther\fP (Autoconf/Automake packaging)
+.br
 \fBGeoffrey Keating\fP (Darwin ATA interface)
+.br
 \fBEduard Martinescu\fP (FreeBSD interface)
+.br
 \fBFr\['e]d\['e]ric L. W. Meunier\fP (Web site and Mailing list)
+.br
 \fBGabriele Pohl\fP (Web site and Wiki, conversion from CVS to SVN)
+.br
 \fBKeiji Sawada\fP (Solaris ATA interface)
+.br
 \fBManfred Schwarb\fP (Drive database)
+.br
 \fBSergey Svishchev\fP (NetBSD interface)
+.br
 \fBDavid Snyder and Sergey Svishchev\fP (OpenBSD interface)
+.br
 \fBPhil Williams\fP (User interface and drive database)
+.br
 \fBYuri Dario\fP (OS/2, eComStation interface)
+.br
 \fBShengfeng Zhou\fP (Linux/FreeBSD HighPoint RocketRAID interface)
-.fi
+.br
 Many other individuals have made smaller contributions and corrections.
 
-.PP
-.SH CREDITS
-.fi
-This code was derived from the smartsuite package, written by Michael
-Cornwell, and from the previous UCSC smartsuite package.  It extends
-these to cover ATA-5 disks.  This code was originally developed as a
+The first smartmontools code was derived from the smartsuite package,
+written by Michael Cornwell, and from the previous UCSC smartsuite package.
+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. \fBhttp://ssrc.soe.ucsc.edu/\fP .
-.SH
-HOME PAGE FOR SMARTMONTOOLS: 
-.fi
-Please see the following web site for updates, further documentation, bug
-reports and patches: \fBhttp://smartmontools.sourceforge.net/\fP
 
-.SH
-SEE ALSO:
-\fBsmartd\fP(8), \fBbadblocks\fP(8), \fBide\-smart\fP(8).
-.SH
-REFERENCES FOR SMART
-.fi
+.SH SEE ALSO
+\fBsmartd\fP(8), \fBupdate-smart-drivedb\fP(8).
+
+.SH REFERENCES
+Please see the following web site for more info:
+\fBhttp://smartmontools.sourceforge.net/\fP
+
 An introductory article about smartmontools is \fIMonitoring Hard
 Disks with SMART\fP, by Bruce Allen, Linux Journal, January 2004,
 pages 74-77. This is \fBhttp://www.linuxjournal.com/article/6983\fP
@@ -2256,15 +2262,12 @@ volume of the \'AT Attachment with Packet Interface-7\' (ATA/ATAPI-7)
 specification Revision 4b.  This documents the SMART functionality which the
 \fBsmartmontools\fP utilities provide access to.
 
-.fi
 The functioning of SMART was originally defined by the SFF-8035i
 revision 2 and the SFF-8055i revision 1.4 specifications.  These are
 publications of the Small Form Factors (SFF) Committee.
 
 Links to these and other documents may be found on the Links page of the
-\fBsmartmontools\fP Wiki at
-\fBhttp://sourceforge.net/apps/trac/smartmontools/wiki/Links\fP .
+\fBsmartmontools\fP Wiki at \fBhttp://www.smartmontools.org/wiki/Links\fP .
 
-.SH
-SVN ID OF THIS PAGE:
-$Id: smartctl.8.in 3832 2013-07-20 14:49:31Z chrfranke $
+.SH SVN ID OF THIS PAGE
+$Id: smartctl.8.in 3965 2014-07-20 14:46:41Z chrfranke $
index 61c7c93e30c0be72a36ef543fc1aff81c71b5480..bbaec43859f8f5d9bcb0ccb0b3acbc250d37fa90 100644 (file)
@@ -4,7 +4,7 @@
  * Home page of code is: http://smartmontools.sourceforge.net
  *
  * Copyright (C) 2002-11 Bruce Allen <smartmontools-support@lists.sourceforge.net>
- * Copyright (C) 2008-12 Christian Franke <smartmontools-support@lists.sourceforge.net>
+ * Copyright (C) 2008-14 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
@@ -26,6 +26,7 @@
 #include <stdio.h>
 #include <sys/types.h>
 #include <string.h>
+#include <stdlib.h>
 #include <stdarg.h>
 #include <stdexcept>
 #include <getopt.h>
@@ -50,7 +51,7 @@
 #include "smartctl.h"
 #include "utility.h"
 
-const char * smartctl_cpp_cvsid = "$Id: smartctl.cpp 3826 2013-07-06 21:57:29Z samm2 $"
+const char * smartctl_cpp_cvsid = "$Id: smartctl.cpp 3936 2014-07-05 17:16:23Z chrfranke $"
   CONFIG_H_CVSID SMARTCTL_H_CVSID;
 
 // Globals to control printing
@@ -724,7 +725,7 @@ static const char * parse_options(int argc, char** argv,
         } else {
           if (ataopts.smart_selective_args.num_spans >= 5 || start > stop) {
             if (start > stop) {
-              snprintf(extraerror, sizeof(extraerror), "ERROR: Start LBA (%"PRIu64") > ending LBA (%"PRId64") in argument \"%s\"\n",
+              snprintf(extraerror, sizeof(extraerror), "ERROR: Start LBA (%" PRIu64 ") > ending LBA (%" PRId64 ") in argument \"%s\"\n",
                 start, stop, optarg);
             } else {
               snprintf(extraerror, sizeof(extraerror),"ERROR: No more than five selective self-test spans may be"
@@ -1212,8 +1213,8 @@ void scan_devices(const char * type, bool with_open, char ** argv)
 // Main program without exception handling
 static int main_worker(int argc, char **argv)
 {
-  // Throw if CPU endianess does not match compile time test.
-  check_endianness();
+  // Throw if runtime environment does not match compile time test.
+  check_config();
 
   // Initialize interface
   smart_interface::init();
index f90f3b699f15062f3e7bba1a0d81cd3c8ca3a7e4..c6f1568e3257bd2171d5b4323ff04f8be0fbadbe 100644 (file)
@@ -1,8 +1,8 @@
 .ig
 Copyright (C) 2002-10 Bruce Allen <smartmontools-support@lists.sourceforge.net>
-Copyright (C) 2004-13 Christian Franke <smartmontools-support@lists.sourceforge.net>
+Copyright (C) 2004-14 Christian Franke <smartmontools-support@lists.sourceforge.net>
 
-$Id: smartd.8.in 3799 2013-03-15 17:47:25Z chrfranke $
+$Id: smartd.8.in 3965 2014-07-20 14:46:41Z 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
@@ -25,11 +25,6 @@ California, Santa Cruz. http://ssrc.soe.ucsc.edu/
 .SH SYNOPSIS
 .B smartd [options]
 
-.\" %IF NOT OS Windows
-.SH FULL PATH
-.B /usr/local/sbin/smartd
-
-.\" %ENDIF NOT OS Windows
 .SH PACKAGE VERSION
 CURRENT_SVN_VERSION CURRENT_SVN_DATE CURRENT_SVN_REV
 
@@ -46,7 +41,7 @@ The purpose of SMART is to monitor the reliability of the hard drive
 and predict drive failures, and to carry out different types of drive
 self-tests.
 This version of \fBsmartd\fP is compatible with
-ACS-2, ATA8-ACS, ATA/ATAPI-7 and earlier standards
+ACS-3, ACS-2, ATA8-ACS, ATA/ATAPI-7 and earlier standards
 (see \fBREFERENCES\fP below).
 
 \fBsmartd\fP will attempt to enable SMART monitoring on ATA devices
@@ -76,9 +71,9 @@ file \fB/usr/local/etc/smartd.conf\fP (Windows: \fBEXEDIR/smartd.conf\fP).
 If the configuration file is subsequently modified, \fBsmartd\fP
 can be told to re-read the configuration file by sending it a
 \fBHUP\fP signal, for example with the command:
-.fi
+.br
 \fBkillall -HUP smartd\fP.
-.fi
+.br
 .\" %IF OS Windows
 (Windows: See NOTES below.)
 .\" %ENDIF OS Windows
@@ -150,9 +145,7 @@ Disks behind Areca RAID controllers are not included.
 for \fIall\fP possible SMART errors (corresponding to the \fB\'\-a\'\fP
 Directive in the configuration file; see the \fBsmartd.conf\fP(5) man page).
 
-.SH 
-OPTIONS
-
+.SH OPTIONS
 .TP
 .B \-A PREFIX, \-\-attributelog=PREFIX
 Writes \fBsmartd\fP attribute information (normalized and raw
@@ -199,7 +192,7 @@ to perform quick and simple checks without a configuration file.
 .\" %IF ENABLE_CAPABILITIES
 .TP
 .B \-C, \-\-capabilities
-Use \fBcapabilities(7)\fP.
+Use \fBcapabilities\fP(7).
 
 Warning: Mail notification does not work when used.
 .\" %ENDIF ENABLE_CAPABILITIES
@@ -207,7 +200,7 @@ Warning: Mail notification does not work when used.
 .B \-d, \-\-debug
 Runs \fBsmartd\fP in "debug" mode. In this mode, it displays status
 information to STDOUT rather than logging it to SYSLOG and does not
-\fBfork(2)\fP into the background and detach from the controlling
+\fBfork\fP(2) into the background and detach from the controlling
 terminal.  In this mode, \fBsmartd\fP also prints more verbose
 information about what it is doing than when operating in "daemon"
 mode. In this mode, the \fBINT\fP signal (normally generated from a
@@ -224,8 +217,8 @@ debug mode is enabled.
 .B \-D, \-\-showdirectives
 Prints a list (to STDOUT) of all the possible Directives which may
 appear in the configuration file /usr/local/etc/smartd.conf, and then exits.
-These Directives are also described later in this man page. They may
-appear in the configuration file following the device name.
+These Directives are described in the \fBsmartd.conf\fP(5) man page.
+They may appear in the configuration file following the device name.
 .TP
 .B \-h, \-\-help, \-\-usage
 Prints usage message to STDOUT and exits.
@@ -248,7 +241,7 @@ also use:
 .B killall -USR1 smartd
 .fi
 for the same purpose.
-.fi
+.br
 .\" %IF OS Windows
 (Windows: See NOTES below.)
 .\" %ENDIF OS Windows
@@ -261,35 +254,14 @@ then by default messages from \fBsmartd\fP are logged to the facility
 \fIdaemon\fP.
 
 If you would like to have \fBsmartd\fP messages logged somewhere other
-than the default location, this can typically be accomplished with
-(for example) the following steps:
-.RS 7
-.IP \fB[1]\fP 4
-Modify the script that starts \fBsmartd\fP to include the \fBsmartd\fP
-command-line argument \'\-l local3\'.  This tells \fBsmartd\fP to log its
-messages to facility \fBlocal3\fP.
-.IP \fB[2]\fP 4
-Modify the \fBsyslogd\fP configuration file (typically
-\fB/etc/syslog.conf\fP) by adding a line of the form:
-.nf
-\fBlocal3.* /var/log/smartd.log\fP
-.fi
-This tells \fBsyslogd\fP to log all the messages from facility \fBlocal3\fP to
-the designated file: /var/log/smartd.log.
-.IP \fB[3]\fP 4
-Tell \fBsyslogd\fP to re-read its configuration file, typically by
-sending the \fBsyslogd\fP process a \fBSIGHUP\fP hang-up signal.
-.IP \fB[4]\fP 4
-Start (or restart) the \fBsmartd\fP daemon.
-.RE
-.\"  The following two lines are a workaround for a man2html bug.  Please leave them.
-.\" They define a non-existent option; useful because man2html can't correctly reset the margins.
-.TP
-.B \&
+than the default location, include (for example) \'\-l local3\' in its
+start up argument list.
+Tell the syslog daemon to log all messages from facility \fBlocal3\fP
+to (for example) \'/var/log/smartd.log\'.
+
 For more detailed information, please refer to the man pages for
-\fBsyslog.conf\fP, \fBsyslogd\fP, and \fBsyslog\fP.  You may also want
-to modify the log rotation configuration files; see the man pages for
-\fBlogrotate\fP and examine your system\'s /etc/logrotate.conf file.
+the local syslog daemon, typically \fBsyslogd\fP(8), \fBsyslog-ng\fP(8)
+or \fBrsyslogd\fP(8).
 .\" %IF OS Cygwin
 
 Cygwin: If no \fBsyslogd\fP is running, the \'\-l\' option has no effect.
@@ -473,30 +445,25 @@ 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
-
-.B
-smartd
-.fi
+.B smartd
+.br
 Runs the daemon in forked mode. This is the normal way to run
 \fBsmartd\fP.
 Entries are logged to SYSLOG.
 
-.B
-smartd -d -i 30
-.fi
+.B smartd -d -i 30
+.br
 Run in foreground (debug) mode, checking the disk status
 every 30 seconds.
 
-.B
-smartd -q onecheck
-.fi
+.B smartd -q onecheck
+.br
 Registers devices, and checks the status of the devices exactly
-once. The exit status (the bash
+once. The exit status (the shell
 .B $?
 variable) will be zero if all went well, and nonzero if no devices
 were detected or some other problem was encountered.
 
-.fi 
 Note that \fBsmartmontools\fP provides a start-up script in
 \fB/usr/local/etc/rc.d/init.d/smartd\fP which is responsible for starting and
 stopping the daemon via the normal init interface.  Using this script,
@@ -508,8 +475,10 @@ and stop it by using the command:
 .nf
 .B /usr/local/etc/rc.d/init.d/smartd stop
 .fi
+
 .SH CONFIGURATION
-The syntax of the smartd.conf(5) file is discussed separately.
+The syntax of the \fBsmartd.conf\fP(5) file is discussed separately.
+
 .SH NOTES
 \fBsmartd\fP
 will make log entries at loglevel 
@@ -642,21 +611,19 @@ checks disks immediately (like \fBSIGUSR1\fP).
 
 .\" %ENDIF OS Windows
 .SH LOG TIMESTAMP TIMEZONE
-
 When \fBsmartd\fP makes log entries, these are time-stamped.  The time
 stamps are in the computer's local time zone, which is generally set
 using either the environment variable \'\fBTZ\fP\' or using a
 time-zone file such as \fB/etc/localtime\fP.  You may wish to change
 the timezone while \fBsmartd\fP is running (for example, if you carry
 a laptop to a new time-zone and don't reboot it).  Due to a bug in the
-\fBtzset(3)\fP function of many unix standard C libraries, the
+\fBtzset\fP(3) function of many unix standard C libraries, the
 time-zone stamps of \fBsmartd\fP might not change.  For some systems,
 \fBsmartd\fP will work around this problem \fIif\fP the time-zone is
 set using \fB/etc/localtime\fP. The work-around \fIfails\fP if the
 time-zone is set using the \'\fBTZ\fP\' variable (or a file that it
 points to).
 
-
 .SH RETURN VALUES
 The return value (exit status) of 
 \fBsmartd\fP
@@ -722,7 +689,34 @@ status is then 128 plus the signal number.  For example if
 \fBsmartd\fP
 is killed by SIGKILL (signal 9) then the exit status is 137.
 
-.PP
+.\" %IF NOT OS Windows
+.SH FILES
+.TP
+.B /usr/local/sbin/smartd
+full path of this executable.
+.TP
+.B /usr/local/etc/smartd.conf
+configuration file (see \fBsmartd.conf\fP(5) man page).
+.TP
+.B /usr/local/etc/smartd_warning.sh
+script run on warnings (see \'\-M exec\' directive on
+\fBsmartd.conf\fP(5) man page).
+.\" %IF ENABLE_SMARTDPLUGINDIR
+.TP
+.B /usr/local/etc/smartd_warning.d/
+plugin directory for smartd warning script (see \'\-m\' directive on
+\fBsmartd.conf\fP(5) man page).
+.\" %ENDIF ENABLE_SMARTDPLUGINDIR
+.\" %IF ENABLE_DRIVEDB
+.TP
+.B /usr/local/share/smartmontools/drivedb.h
+drive database (see \'\-B\' option).
+.\" %ENDIF ENABLE_DRIVEDB
+.TP
+.B /usr/local/etc/smart_drivedb.h
+optional local drive database (see \'\-B\' option).
+
+.\" %ENDIF NOT OS Windows
 .SH AUTHORS
 \fBBruce Allen\fP
 .br
@@ -733,50 +727,51 @@ since 2009)
 .br
 \fBsmartmontools\-support@lists.sourceforge.net\fP
 
-.PP
-.SH CONTRIBUTORS
 The following have made large contributions to smartmontools:
-.nf
+.br
 \fBCasper Dik\fP (Solaris SCSI interface)
+.br
 \fBDouglas Gilbert\fP (SCSI subsystem)
+.br
 \fBGuido Guenther\fP (Autoconf/Automake packaging)
+.br
 \fBGeoffrey Keating\fP (Darwin ATA interface)
+.br
 \fBEduard Martinescu\fP (FreeBSD interface)
+.br
 \fBFr\['e]d\['e]ric L. W. Meunier\fP (Web site and Mailing list)
+.br
 \fBGabriele Pohl\fP (Web site and Wiki, conversion from CVS to SVN)
+.br
 \fBKeiji Sawada\fP (Solaris ATA interface)
+.br
 \fBManfred Schwarb\fP (Drive database)
+.br
 \fBSergey Svishchev\fP (NetBSD interface)
+.br
 \fBDavid Snyder and Sergey Svishchev\fP (OpenBSD interface)
+.br
 \fBPhil Williams\fP (User interface and drive database)
+.br
 \fBShengfeng Zhou\fP (Linux/FreeBSD HighPoint RocketRAID interface)
-.fi
+.br
 Many other individuals have made smaller contributions and corrections.
 
-.PP
-.SH CREDITS
-.fi
-This code was derived from the smartsuite package, written by Michael
-Cornwell, and from the previous UCSC smartsuite package.  It extends
-these to cover ATA-5 disks.  This code was originally developed as a
+The first smartmontools code was derived from the smartsuite package,
+written by Michael Cornwell, and from the previous UCSC smartsuite package.
+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. \fBhttp://ssrc.soe.ucsc.edu/\fP .
-.SH
-HOME PAGE FOR SMARTMONTOOLS: 
-.fi
-Please see the following web site for updates, further documentation, bug
-reports and patches: \fBhttp://smartmontools.sourceforge.net/\fP
 
-.SH
-SEE ALSO:
-\fBsmartd.conf\fP(5), \fBsmartctl\fP(8), \fBsyslogd\fP(8),
-\fBsyslog.conf\fP(5), \fBbadblocks\fP(8), \fBide\-smart\fP(8), \fBregex\fP(7).
+.SH SEE ALSO
+\fBsmartd.conf\fP(5), \fBsmartctl\fP(8), \fBupdate-smart-drivedb\fP(8).
+
+.SH REFERENCES
+Please see the following web site for more info:
+\fBhttp://smartmontools.sourceforge.net/\fP
 
-.SH
-REFERENCES FOR SMART
-.fi
 An introductory article about smartmontools is \fIMonitoring Hard
 Disks with SMART\fP, by Bruce Allen, Linux Journal, January 2004,
 pages 74-77. This is \fBhttp://www.linuxjournal.com/article/6983\fP
@@ -788,15 +783,12 @@ volume of the \'AT Attachment with Packet Interface-7\' (ATA/ATAPI-7)
 specification Revision 4b.  This documents the SMART functionality which the
 \fBsmartmontools\fP utilities provide access to.
 
-.fi
 The functioning of SMART was originally defined by the SFF-8035i
 revision 2 and the SFF-8055i revision 1.4 specifications.  These are
 publications of the Small Form Factors (SFF) Committee.
 
 Links to these and other documents may be found on the Links page of the
-\fBsmartmontools\fP Wiki at
-\fBhttp://sourceforge.net/apps/trac/smartmontools/wiki/Links\fP .
+\fBsmartmontools\fP Wiki at \fBhttp://www.smartmontools.org/wiki/Links\fP .
 
-.SH
-SVN ID OF THIS PAGE:
-$Id: smartd.8.in 3799 2013-03-15 17:47:25Z chrfranke $
+.SH SVN ID OF THIS PAGE
+$Id: smartd.8.in 3965 2014-07-20 14:46:41Z chrfranke $
index f3722624c9be49dbc37f6b829d874d5d37b2485e..0acec7d17f62176b866289a1296067e317c345e8 100644 (file)
@@ -1,8 +1,8 @@
 .ig
 Copyright (C) 2002-10 Bruce Allen <smartmontools-support@lists.sourceforge.net>
-Copyright (C) 2004-13 Christian Franke <smartmontools-support@lists.sourceforge.net>
+Copyright (C) 2004-14 Christian Franke <smartmontools-support@lists.sourceforge.net>
 
-$Id: smartd.conf.5.in 3833 2013-07-20 15:00:04Z chrfranke $
+$Id: smartd.conf.5.in 3965 2014-07-20 14:46:41Z 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
@@ -22,11 +22,6 @@ California, Santa Cruz. http://ssrc.soe.ucsc.edu/
 .SH NAME
 \fBsmartd.conf\fP \- SMART Disk Monitoring Daemon Configuration File\fP
 
-.\" %IF NOT OS Windows
-.SH FULL PATH
-.B /usr/local/etc/smartd.conf
-
-.\" %ENDIF NOT OS Windows
 .SH PACKAGE VERSION
 CURRENT_SVN_VERSION CURRENT_SVN_DATE CURRENT_SVN_REV
 
@@ -84,8 +79,8 @@ non-whitespace or non-comment item on a line.
 Note: a line whose first character is a hash sign \'#\' is treated as
 a white-space blank line, \fBnot\fP as a non-existent line, and will
 \fBend\fP a continuation line.
-.PP 0
-.fi
+.PP
+
 Here is an example configuration file.  It\'s for illustrative purposes
 only; please don\'t copy it onto your system without reading to the end
 of the
@@ -104,7 +99,6 @@ Section below!
 .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
 .B # the second disk, start a long self-test every
 .B # Sunday between 3 and 4 am.
@@ -112,19 +106,16 @@ Section below!
 .B \ \ /dev/hda -a -m admin@example.com,root@localhost 
 .B \ \ /dev/hdc -a -I 194 -I 5 -i 12 -s L/../../7/03
 .B #
-.nf
 .B # SCSI disks.  Send a TEST warning email to admin on
 .B # startup.
 .B #
 .B \ \ /dev/sda
 .B \ \ /dev/sdb -m admin@example.com -M test
 .B #
-.nf
 .B # Strange device.  It\'s SCSI. Start a scheduled
 .B # long self test between 5 and 6 am Monday/Thursday
 .B \ \ /dev/weird -d scsi -s L/../../(1|4)/05
 .B #
-.nf
 .B # An ATA disk may appear as a SCSI device to the
 .B # OS. If a SCSI to ATA Translation (SAT) layer
 .B # is between the OS and the device then this can be
@@ -133,7 +124,6 @@ Section below!
 .B # environments.
 .B \ \ /dev/sda -a -d sat
 .B #
-.nf
 .\" %IF OS Linux
 .B # Three disks connected to a MegaRAID controller
 .B # Start short self-tests daily between 1-2, 2-3, and
@@ -142,10 +132,15 @@ Section below!
 .B \ \ /dev/sda -d megaraid,1 -a -s S/../.././02
 .B \ \ /dev/sda -d megaraid,2 -a -s S/../.././03
 .B \ \ /dev/bus/0 -d megaraid,2 -a -s S/../.././03
-.B
+.B #
+.B # Three disks connected to an AacRaid controller
+.B # Start short self-tests daily between 1-2, 2-3, and
+.B # 3-4 am.
+.B \ \ /dev/sda -d aacraid,0,0,66 -a -s S/../.././01
+.B \ \ /dev/sda -d aacraid,0,0,67 -a -s S/../.././02
+.B \ \ /dev/sda -d aacraid,0,0,68 -a -s S/../.././03
 .B #
 .\" %ENDIF OS Linux
-.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
@@ -157,14 +152,12 @@ Section below!
 .B \ \ /dev/sdd -d 3ware,2 -a -s S/../.././02
 .B \ \ /dev/sdd -d 3ware,3 -a -s S/../.././03
 .B #
-.nf
 .B # Two ATA disks on a 3ware 9000 controller.
 .B # Start long self-tests Sundays between midnight and
 .B # 1am and 2-3 am
 .B \ \ /dev/twa0 -d 3ware,0 -a -s L/../../7/00
 .B \ \ /dev/twa0 -d 3ware,1 -a -s L/../../7/02
 .B #
-.nf
 .B # Two SATA (not SAS) disks on a 3ware 9750 controller.
 .B # Start long self-tests Sundays between midnight and
 .B # 1am and 2-3 am
@@ -177,7 +170,6 @@ Section below!
 .B \ \ /dev/tws0 -d 3ware,1 -a -s L/../../7/02
 .\" %ENDIF OS FreeBSD
 .B #
-.nf
 .B # Three SATA disks on a HighPoint RocketRAID controller.
 .B # Start short self-tests daily between 1-2, 2-3, and
 .B # 3-4 am.
@@ -194,7 +186,6 @@ Section below!
 .B  /dev/hptrr -d hpt,1/3 -a -s S/../.././03
 .\" %ENDIF OS FreeBSD
 .B #
-.nf
 .B # Two SATA disks connected to a HighPoint RocketRAID 
 .B # via a pmport device.  Start long self-tests Sundays
 .B # between midnight and 1am and 2-3 am.
@@ -209,7 +200,6 @@ Section below!
 .B \ \ /dev/hptrr -d hpt,1/4/2 -a -s L/../../7/02
 .B #
 .\" %ENDIF OS FreeBSD
-.nf
 .B # Three SATA disks connected to an Areca
 .B # RAID controller. Start long self-tests Sundays
 .B # between midnight and 3 am.
@@ -224,7 +214,6 @@ Section below!
 .B \ \ /dev/arcmsr0 -d areca,3 -a -s L/../../7/02
 .\" %ENDIF OS FreeBSD
 .B #
-.nf
 .B # The following line enables monitoring of the 
 .B # ATA Error Log and the Self-Test Error Log.  
 .B # It also tracks changes in both Prefailure
@@ -241,10 +230,7 @@ Section below!
 .B ################################################
 .fi
 
-.PP 
 .SH CONFIGURATION FILE DIRECTIVES
-.PP
-
 If a non-comment entry in the configuration file is the text string
 .B DEVICESCAN
 in capital letters, then
@@ -256,14 +242,13 @@ may optionally be followed by Directives that will apply to all
 devices that are found in the scan.  Please see below for additional
 details.
 
-[NEW EXPERIMENTAL SMARTD FEATURE] If an entry in the configuration file
-starts with
+If an entry in the configuration file starts with
 .B DEFAULT
 instead of a device name, then all directives in this entry are set
 as defaults for the next device entries.
-
+.PP
 This configuration:
-
+.PP
 .nf
 \ \ DEFAULT -a -R5! -W 2,40,45 -I 194 -s L/../../7/00 -m admin@example.com
 \ \ /dev/sda
@@ -273,9 +258,9 @@ This configuration:
 \ \ /dev/sdd
 \ \ /dev/sde -d removable
 .fi
-
+.PP
 has the same effect as:
-
+.PP
 .nf
 \ \ /dev/sda -a -R5! -W 2,40,45 -I 194 -s L/../../7/00 -m admin@example.com
 \ \ /dev/sdb -a -R5! -W 2,40,45 -I 194 -s L/../../7/00 -m admin@example.com
@@ -284,7 +269,7 @@ has the same effect as:
 \ \ /dev/sde -d removable -H -m admin@example.com
 .fi
 
-.sp 2
+
 The following are the Directives that may appear following the device
 name or
 .B DEVICESCAN
@@ -412,6 +397,14 @@ It is possible to set RAID device name as /dev/bus/N, where N is a SCSI bus
 number.
 Please see the \fBsmartctl\fP(8) man page for further details.
 
+.I aacraid,H,L,ID
+\- [Linux only] [NEW EXPERIMENTAL SMARTD FEATURE]
+the device consists of one or more SCSI/SAS disks connected to an AacRaid controller.
+The non-negative integers H,L,ID (Host number, Lun, ID) denote which disk
+on the controller is monitored.
+In log files and email messages this disk will be identified as aacraid_disk_HH_LL_ID.
+Please see the \fBsmartctl\fP(8) man page for further details.
+
 .\" %ENDIF OS Linux
 .\" %IF OS FreeBSD Linux
 .I 3ware,N
@@ -667,7 +660,6 @@ Values of 0 disable the feature, other values less than 65 are probably
 not supported.  For RAID configurations, this is typically set to
 70,70 deciseconds.
 [Please see the \fBsmartctl \-l scterc\fP command-line option.]
-
 .TP
 .B \-e NAME[,VALUE]
 Sets non-SMART device settings when \fBsmartd\fP starts up and has no
@@ -693,7 +685,6 @@ IDLE mode.
 
 .I wcache,[on|off]
 \- [ATA only] Sets the volatile write cache feature.
-
 .TP
 .B \-s REGEXP
 Run Self-Tests or Offline Immediate Tests, at scheduled times.  A
@@ -720,7 +711,6 @@ Some disks (e.g. WD) do not preserve the selective self test log accross
 power cycles.  If state persistence (\'\-s\' option) is enabled, the last
 test span is preserved by smartd and used if (and only if) the selective
 self test log is empty.
-
 .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
@@ -819,8 +809,8 @@ 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
+expressions [\fBregex\fP(7)] are \fBnot\fP the same as the rules for
+file-name pattern matching by the shell [\fBglob\fP(7)].  \fBsmartd\fP will
 issue harmless informational warning messages if it detects characters
 in \fBREGEXP\fP that appear to indicate that you have made this
 mistake.
@@ -848,25 +838,14 @@ Directive described below to send one test email message on
 \fBsmartd\fP
 startup.
 
-By default, email is sent using the system 
-.B mail
-command.  In order that
-\fBsmartd\fP
-find the mail command (normally /bin/mail) an executable named
-.B \'mail\'
-must be in the path of the shell or environment from which
+By default, email is sent using the system \fBmail\fP(1) command.
+In order that \fBsmartd\fP find this command (normally /usr/bin/mail) the
+executable must be in the path of the shell or environment from which
 \fBsmartd\fP
 was started.  If you wish to specify an explicit path to the mail
 executable (for example /usr/local/bin/mail) or a custom script to
 run, please use the \'\-M exec\' Directive below.
 
-.\" %IF OS Solaris
-Note that by default under Solaris, in the previous paragraph,
-\'\fBmailx\fP\' and \'\fB/bin/mailx\fP\' are used, since Solaris
-\'/bin/mail\' does not accept a \'\-s\' (Subject) command-line
-argument.
-
-.\" %ENDIF OS Solaris
 .\" %IF OS Windows
 On Windows, the \'\fBBlat\fP\' mailer
 (\fBhttp://blat.sourceforge.net/\fP) is used by default.
@@ -886,6 +865,7 @@ sending mail, this should help you to understand and fix them.  If
 you have mail problems, we recommend running \fBsmartd\fP in debug
 mode with the \'-d\' flag, using the \'-M test\' Directive described
 below.
+.\" %IF ENABLE_SMARTDPLUGINDIR
 .\" %IF NOT OS Windows
 
 [NEW EXPERIMENTAL SMARTD FEATURE]
@@ -898,6 +878,7 @@ are run instead.
 This is handled by the script /usr/local/etc/smartd_warning.sh
 (see also \'\-M exec\' below).
 .\" %ENDIF NOT OS Windows
+.\" %ENDIF ENABLE_SMARTDPLUGINDIR
 .\" %IF OS Windows
 
 [Windows only] [NEW EXPERIMENTAL SMARTD FEATURE]
@@ -995,7 +976,7 @@ exported by \fBsmartd\fP are:
 .RS 7
 .IP \fBSMARTD_MAILER\fP 4
 is set to the argument of \-M exec, if present or else to \'mail\'
-(examples: /bin/mail, mail).
+(examples: /usr/local/bin/mail, mail).
 .IP \fBSMARTD_DEVICE\fP 4
 is set to the device path (examples: /dev/hda, /dev/sdb).
 .IP \fBSMARTD_DEVICETYPE\fP 4
@@ -1009,7 +990,7 @@ 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]\' on Linux or  \'/dev/arcmsr0 [areca_disk_09]\' on FreeBSD.  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.
+shell script you should probably enclose it in double quotes.
 .IP \fBSMARTD_DEVICEINFO\fP 4
 is set to device identify information.  It includes most of the info printed
 by \fBsmartctl \-i\fP but uses a brief single line format.
@@ -1018,46 +999,33 @@ The string contains space characters and is NOT quoted.
 .IP \fBSMARTD_FAILTYPE\fP 4
 gives the reason for the warning or message email.  The possible values that
 it takes and their meanings are:
-.nf
-.fi
+.br
 \fIEmailTest\fP: this is an email test message.
-.nf
-.fi
+.br
 \fIHealth\fP: the SMART health status indicates imminent failure.
-.nf
-.fi
+.br
 \fIUsage\fP: a usage Attribute has failed.
-.nf
-.fi
+.br
 \fISelfTest\fP: the number of self-test failures has increased.
-.nf
-.fi
+.br
 \fIErrorCount\fP: the number of errors in the ATA error log has increased.
-.nf
-.fi
+.br
 \fICurrentPendingSector\fP: one of more disk sectors could not be
 read and are marked to be reallocated (replaced with spare sectors).
-.nf
-.fi
+.br
 \fIOfflineUncorrectableSector\fP: during off-line testing, or self-testing,
 one or more disk sectors could not be read.
-.nf
-.fi
+.br
 \fITemperature\fP: Temperature reached critical limit (see \-W directive).
-.nf
-.fi
+.br
 \fIFailedHealthCheck\fP: the SMART health status command failed.
-.nf
-.fi
+.br
 \fIFailedReadSmartData\fP: the command to read SMART Attribute data failed.
-.nf
-.fi
+.br
 \fIFailedReadSmartErrorLog\fP: the command to read the SMART error log failed.
-.nf
-.fi
+.br
 \fIFailedReadSmartSelfTestLog\fP: the command to read the SMART self-test log failed.
-.nf
-.fi
+.br
 \fIFailedOpenDevice\fP: the open() command to the device failed.
 .IP \fBSMARTD_ADDRESS\fP 4
 is determined by the address argument ADD of the \'\-m\' Directive.
@@ -1066,7 +1034,7 @@ Otherwise, it is set to the comma-separated-list of email addresses
 given by the argument ADD, with the commas replaced by spaces
 (example:admin@example.com root).  If more than one email address is
 given, then this string will contain space characters and is NOT
-quoted, so to use it in a bash script you may want to enclose it in
+quoted, so to use it in a shell script you may want to enclose it in
 double quotes.
 .\" %IF OS Windows
 .IP \fBSMARTD_ADDRCSV\fP 4
@@ -1077,14 +1045,14 @@ SMARTD_ADDRESS.
 is set to the one sentence summary warning email message string from
 \fBsmartd\fP. 
 This message string contains space characters and is NOT quoted. So to
-use $SMARTD_MESSAGE in a bash script you should probably enclose it in
+use $SMARTD_MESSAGE in a shell script you should probably enclose it in
 double quotes.
 .\" %IF NOT OS Windows
 .IP \fBSMARTD_FULLMESSAGE\fP 4
 is set to the contents of the entire email warning message string from
 \fBsmartd\fP. 
 This message string contains space and return characters and is NOT quoted. So to
-use $SMARTD_FULLMESSAGE in a bash script you should probably enclose it in
+use $SMARTD_FULLMESSAGE in a shell script you should probably enclose it in
 double quotes.
 .\" %ENDIF NOT OS Windows
 .\" %IF OS Windows
@@ -1098,8 +1066,7 @@ the mailer or command exits.
 is a text string giving the time and date at which the first problem
 of this type was reported. This text string contains space characters
 and no newlines, and is NOT quoted. For example:
-.nf
-.fi
+.br
 Sun Feb  9 14:58:19 2003 CST
 .IP \fBSMARTD_TFIRSTEPOCH\fP 4
 is an integer, which is the unix epoch (number of seconds since Jan 1,
@@ -1128,9 +1095,9 @@ command-line arguments:
 .fi
 that would normally be provided to \'mail\'.  Examples include:
 .nf
-.B -m user@home -M exec /bin/mail
+.B -m user@home -M exec /usr/bin/mail
 .B -m admin@work -M exec /usr/local/bin/mailto
-.B -m root -M exec /Example_1/bash/script/below
+.B -m root -M exec /Example_1/shell/script/below
 .fi
 
 .\" %IF OS Windows
@@ -1149,7 +1116,7 @@ STDIN and
 .B no
 command-line arguments, for example:
 .nf
-.B -m <nomailer> -M exec /Example_2/bash/script/below
+.B -m <nomailer> -M exec /Example_2/shell/script/below
 .fi
 If the executable produces any STDERR/STDOUT output, then \fBsmartd\fP
 assumes that something is going wrong, and a snippet of that output
@@ -1186,7 +1153,6 @@ SMARTD_SUBJECT and SMARTD_FULLMESSAGE
 .\"! SMARTD_SUBJECT, SMARTD_FULLMSGFILE and SMARTD_ADDRCSV
 .\" %ENDIF OS Windows
 are set by the script before running the executable.
-
 .TP
 .B \-f
 [ATA only] Check for \'failure\' of any Usage Attributes.  If these
@@ -1382,7 +1348,7 @@ multiple times.  The valid arguments are:
 .I none
 \- Assume that the device firmware obeys the ATA specifications.  This
 is the default, unless the device has presets for \'\-F\' in the
-drive database.  Using this directive will over-ride any preset values.
+drive database.  Using this directive will override any preset values.
 
 .I nologdir
 \- Suppresses read attempts of SMART or GP Log Directory.
@@ -1430,7 +1396,7 @@ 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 sets \'-U 198+\'
+reset if uncorrectable sectors are reallocated.  This sets \'-U 198+\'
 if no other \'-U\' directive is specified.
 .TP
 .B \-P TYPE
@@ -1555,7 +1521,7 @@ to the output of the smartd email warning message and sends it to ADDRESS.
 
 .nf
 \fB
-#! /bin/bash
+#! /bin/sh
 
 # Save the email message (STDIN) to a file:
 cat > /root/msg
@@ -1564,7 +1530,7 @@ cat > /root/msg
 /usr/local/sbin/smartctl -a -d $SMART_DEVICETYPE $SMARTD_DEVICE >> /root/msg
  
 # Now email the message to the user at address ADD:
-/bin/mail -s "$SMARTD_SUBJECT" $SMARTD_ADDRESS < /root/msg
+/usr/bin/mail -s "$SMARTD_SUBJECT" $SMARTD_ADDRESS < /root/msg
 \fP
 .fi
 
@@ -1574,16 +1540,18 @@ then powers down the machine.
 
 .nf
 \fB
-#! /bin/bash
+#! /bin/sh
 
 # Warn all users of a problem
-wall \'Problem detected with disk: \' "$SMARTD_DEVICESTRING"
-wall \'Warning message from smartd is: \' "$SMARTD_MESSAGE"
-wall \'Shutting down machine in 30 seconds... \'
+wall <<EOF
+Problem detected with disk: $SMARTD_DEVICESTRING
+Warning message from smartd is: $SMARTD_MESSAGE
+Shutting down machine in 30 seconds...
+EOF
+
 # Wait half a minute
 sleep 30
+
 # Power down the machine
 /sbin/shutdown -hf now
 \fP
@@ -1602,58 +1570,16 @@ this is interpreted as indicating that there was an internal error
 within the script, and a snippet of STDOUT/STDERR is logged to SYSLOG.
 The remainder is flushed.
 
-.PP
-.SH AUTHORS
-\fBBruce Allen\fP
-.br
-University of Wisconsin \- Milwaukee Physics Department
-.br
-\fBChristian Franke\fP (Windows interface, C++ redesign, most enhancements
-since 2009)
-.br
-\fBsmartmontools\-support@lists.sourceforge.net\fP
-
-.PP
-.SH CONTRIBUTORS
-The following have made large contributions to smartmontools:
-.nf
-\fBCasper Dik\fP (Solaris SCSI interface)
-\fBDouglas Gilbert\fP (SCSI subsystem)
-\fBGuido Guenther\fP (Autoconf/Automake packaging)
-\fBGeoffrey Keating\fP (Darwin ATA interface)
-\fBEduard Martinescu\fP (FreeBSD interface)
-\fBFr\['e]d\['e]ric 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/FreeBSD HighPoint RocketRAID interface)
-.fi
-Many other individuals have made smaller contributions and corrections.
-
-.PP
-.SH CREDITS
-.fi
-This code was derived from the smartsuite package, written by Michael
-Cornwell, and from the previous UCSC smartsuite package.  It extends
-these to cover ATA-5 disks.  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. \fBhttp://ssrc.soe.ucsc.edu/\fP .
-.SH
-HOME PAGE FOR SMARTMONTOOLS: 
-.fi
-Please see the following web site for updates, further documentation, bug
-reports and patches: \fBhttp://smartmontools.sourceforge.net/\fP
+.\" %IF NOT OS Windows
+.SH FILES
+.TP
+.B /usr/local/etc/smartd.conf
+full path of this file.
 
-.SH
-SEE ALSO:
-\fBsmartd\fP(8), \fBsmartctl\fP(8), \fBsyslogd\fP(8),
-\fBsyslog.conf\fP(5), \fBbadblocks\fP(8), \fBide\-smart\fP(8), \fBregex\fP(7).
+.\" %ENDIF NOT OS Windows
+.SH SEE ALSO
+\fBsmartd\fP(8), \fBsmartctl\fP(8),
+\fBmail\fP(1), \fBregex\fP(7).
 
-.SH
-SVN ID OF THIS PAGE:
-$Id: smartd.conf.5.in 3833 2013-07-20 15:00:04Z chrfranke $
+.SH SVN ID OF THIS PAGE
+$Id: smartd.conf.5.in 3965 2014-07-20 14:46:41Z chrfranke $
index fec123552e8cbcbf0676f90a348bfba878068156..7013e60f9c294b3d2213a62734543788448bef56 100644 (file)
@@ -4,7 +4,7 @@
  * Copyright (C) 2002-11 Bruce Allen <smartmontools-support@lists.sourceforge.net>
  * Copyright (C) 2000    Michael Cornwell <cornwell@acm.org>
  * Copyright (C) 2008    Oliver Bock <brevilo@users.sourceforge.net>
- * Copyright (C) 2008-13 Christian Franke <smartmontools-support@lists.sourceforge.net>
+ * Copyright (C) 2008-14 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
@@ -106,7 +106,7 @@ typedef int pid_t;
 extern "C" int getdomainname(char *, int); // no declaration in header files!
 #endif
 
-const char * smartd_cpp_cvsid = "$Id: smartd.cpp 3802 2013-03-24 18:36:21Z chrfranke $"
+const char * smartd_cpp_cvsid = "$Id: smartd.cpp 3948 2014-07-13 16:53:30Z chrfranke $"
   CONFIG_H_CVSID;
 
 // smartd exit codes
@@ -676,13 +676,13 @@ static bool read_dev_state(const char * path, persistent_dev_state & state)
 static void write_dev_state_line(FILE * f, const char * name, uint64_t val)
 {
   if (val)
-    fprintf(f, "%s = %"PRIu64"\n", name, val);
+    fprintf(f, "%s = %" PRIu64 "\n", name, val);
 }
 
 static void write_dev_state_line(FILE * f, const char * name1, int id, const char * name2, uint64_t val)
 {
   if (val)
-    fprintf(f, "%s.%d.%s = %"PRIu64"\n", name1, id, name2, val);
+    fprintf(f, "%s.%d.%s = %" PRIu64 "\n", name1, id, name2, val);
 }
 
 // Write a state file
@@ -757,7 +757,7 @@ static bool write_dev_attrlog(const char * path, const dev_state & state)
     const persistent_dev_state::ata_attribute & pa = state.ata_attributes[i];
     if (!pa.id)
       continue;
-    fprintf(f, "\t%d;%d;%"PRIu64";", pa.id, pa.val, pa.raw);
+    fprintf(f, "\t%d;%d;%" PRIu64 ";", pa.id, pa.val, pa.raw);
   }
   // SCSI ONLY
   const struct scsiErrorCounter * ecp;
@@ -765,13 +765,13 @@ static bool write_dev_attrlog(const char * path, const dev_state & state)
   for (int k = 0; k < 3; ++k) {
     if ( !state.scsi_error_counters[k].found ) continue;
     ecp = &state.scsi_error_counters[k].errCounter;
-     fprintf(f, "\t%s-corr-by-ecc-fast;%"PRIu64";"
-       "\t%s-corr-by-ecc-delayed;%"PRIu64";"
-       "\t%s-corr-by-retry;%"PRIu64";"
-       "\t%s-total-err-corrected;%"PRIu64";"
-       "\t%s-corr-algorithm-invocations;%"PRIu64";"
+     fprintf(f, "\t%s-corr-by-ecc-fast;%" PRIu64 ";"
+       "\t%s-corr-by-ecc-delayed;%" PRIu64 ";"
+       "\t%s-corr-by-retry;%" PRIu64 ";"
+       "\t%s-total-err-corrected;%" PRIu64 ";"
+       "\t%s-corr-algorithm-invocations;%" PRIu64 ";"
        "\t%s-gb-processed;%.3f;"
-       "\t%s-total-unc-errors;%"PRIu64";",
+       "\t%s-total-unc-errors;%" PRIu64 ";",
        pageNames[k], ecp->counter[0],
        pageNames[k], ecp->counter[1],
        pageNames[k], ecp->counter[2],
@@ -781,7 +781,7 @@ static bool write_dev_attrlog(const char * path, const dev_state & state)
        pageNames[k], ecp->counter[6]);
   }
   if(state.scsi_nonmedium_error.found && state.scsi_nonmedium_error.nme.gotPC0) {
-    fprintf(f, "\tnon-medium-errors;%"PRIu64";", state.scsi_nonmedium_error.nme.counterPC0);
+    fprintf(f, "\tnon-medium-errors;%" PRIu64 ";", state.scsi_nonmedium_error.nme.counterPC0);
   }
   // write SCSI current temperature if it is monitored
   if(state.TempPageSupported && state.temperature)
@@ -1491,7 +1491,7 @@ static void Usage()
   PrintOut(LOG_INFO,"  -A PREFIX, --attributelog=PREFIX\n");
   PrintOut(LOG_INFO,"        Log ATA attribute information to {PREFIX}MODEL-SERIAL.ata.csv\n");
 #ifdef SMARTMONTOOLS_ATTRIBUTELOG
-  PrintOut(LOG_INFO,"        [default is "SMARTMONTOOLS_ATTRIBUTELOG"MODEL-SERIAL.ata.csv]\n");
+  PrintOut(LOG_INFO,"        [default is " SMARTMONTOOLS_ATTRIBUTELOG "MODEL-SERIAL.ata.csv]\n");
 #endif
   PrintOut(LOG_INFO,"\n");
   PrintOut(LOG_INFO,"  -B [+]FILE, --drivedb=[+]FILE\n");
@@ -1537,13 +1537,13 @@ static void Usage()
   PrintOut(LOG_INFO,"  -s PREFIX, --savestates=PREFIX\n");
   PrintOut(LOG_INFO,"        Save disk states to {PREFIX}MODEL-SERIAL.TYPE.state\n");
 #ifdef SMARTMONTOOLS_SAVESTATES
-  PrintOut(LOG_INFO,"        [default is "SMARTMONTOOLS_SAVESTATES"MODEL-SERIAL.TYPE.state]\n");
+  PrintOut(LOG_INFO,"        [default is " SMARTMONTOOLS_SAVESTATES "MODEL-SERIAL.TYPE.state]\n");
 #endif
   PrintOut(LOG_INFO,"\n");
   PrintOut(LOG_INFO,"  -w NAME, --warnexec=NAME\n");
   PrintOut(LOG_INFO,"        Run executable NAME on warnings\n");
 #ifndef _WIN32
-  PrintOut(LOG_INFO,"        [default is "SMARTMONTOOLS_SYSCONFDIR"/smartd_warning.sh]\n\n");
+  PrintOut(LOG_INFO,"        [default is " SMARTMONTOOLS_SMARTDSCRIPTDIR "/smartd_warning.sh]\n\n");
 #else
   PrintOut(LOG_INFO,"        [default is %s/smartd_warning.cmd]\n\n", get_exe_dir().c_str());
 #endif
@@ -1698,7 +1698,7 @@ static bool check_pending_id(const dev_config & cfg, const dev_state & state,
   uint64_t rawval = ata_get_attr_raw_value(state.smartval.vendor_attributes[i],
     cfg.attribute_defs);
   if (rawval >= (state.num_sectors ? state.num_sectors : 0xffffffffULL)) {
-    PrintOut(LOG_INFO, "Device: %s, ignoring %s count - bogus Attribute %d value %"PRIu64" (0x%"PRIx64")\n",
+    PrintOut(LOG_INFO, "Device: %s, ignoring %s count - bogus Attribute %d value %" PRIu64 " (0x%" PRIx64 ")\n",
              cfg.name.c_str(), msg, id, rawval, rawval);
     return false;
   }
@@ -1781,7 +1781,7 @@ static int ATADeviceScan(dev_config & cfg, dev_state & state, ata_device * atade
   unsigned oui = 0; uint64_t unique_id = 0;
   int naa = ata_get_wwn(&drive, oui, unique_id);
   if (naa >= 0)
-    snprintf(wwn, sizeof(wwn), "WWN:%x-%06x-%09"PRIx64", ", naa, oui, unique_id);
+    snprintf(wwn, sizeof(wwn), "WWN:%x-%06x-%09" PRIx64 ", ", naa, oui, unique_id);
 
   // Format device id string for warning emails
   char cap[32];
@@ -2749,7 +2749,7 @@ static int DoATASelfTest(const dev_config & cfg, dev_state & state, ata_device *
       return 1;
     }
     uint64_t start = selargs.span[0].start, end = selargs.span[0].end;
-    PrintOut(LOG_INFO, "Device: %s, %s test span at LBA %"PRIu64" - %"PRIu64" (%"PRIu64" sectors, %u%% - %u%% of disk).\n",
+    PrintOut(LOG_INFO, "Device: %s, %s test span at LBA %" PRIu64 " - %" PRIu64 " (%" PRIu64 " sectors, %u%% - %u%% of disk).\n",
       name, (selargs.span[0].mode == SEL_NEXT ? "next" : "redo"),
       start, end, end - start + 1,
       (unsigned)((100 * start + state.num_sectors/2) / state.num_sectors),
@@ -2800,9 +2800,9 @@ static void check_pending(const dev_config & cfg, dev_state & state,
     return;
 
   // Format message.
-  std::string s = strprintf("Device: %s, %"PRId64" %s", cfg.name.c_str(), rawval, msg);
+  std::string s = strprintf("Device: %s, %" PRId64 " %s", cfg.name.c_str(), rawval, msg);
   if (prev_rawval > 0 && rawval != prev_rawval)
-    s += strprintf(" (changed %+"PRId64")", rawval - prev_rawval);
+    s += strprintf(" (changed %+" PRId64 ")", rawval - prev_rawval);
 
   PrintOut(LOG_CRIT, "%s\n", s.c_str());
   MailWarning(cfg, state, mailtype, "%s", s.c_str());
@@ -4254,10 +4254,10 @@ static int ParseConfigFile(dev_config_vector & conf_entries)
   // No configuration file found -- use fake one
   int entry = 0;
   if (!f) {
-    char fakeconfig[] = SCANDIRECTIVE" -a"; // TODO: Remove this hack, build cfg_entry.
+    char fakeconfig[] = SCANDIRECTIVE " -a"; // TODO: Remove this hack, build cfg_entry.
 
     if (ParseConfigLine(conf_entries, default_conf, 0, fakeconfig) != -1)
-      throw std::logic_error("Internal error parsing "SCANDIRECTIVE);
+      throw std::logic_error("Internal error parsing " SCANDIRECTIVE);
     return 0;
   }
 
@@ -4395,8 +4395,8 @@ static void ParseOpts(int argc, char **argv)
 {
   // Init default path names
 #ifndef _WIN32
-  configfile = SMARTMONTOOLS_SYSCONFDIR"/smartd.conf";
-  warning_script = SMARTMONTOOLS_SYSCONFDIR"/smartd_warning.sh";
+  configfile = SMARTMONTOOLS_SYSCONFDIR "/smartd.conf";
+  warning_script = SMARTMONTOOLS_SMARTDSCRIPTDIR "/smartd_warning.sh";
 #else
   std::string exedir = get_exe_dir();
   static std::string configfile_str = exedir + "/smartd.conf";
@@ -5028,7 +5028,7 @@ static int main_worker(int argc, char **argv)
         PrintOut(LOG_INFO,
                  caughtsigHUP==1?
                  "Signal HUP - rereading configuration file %s\n":
-                 "\a\nSignal INT - rereading configuration file %s ("SIGQUIT_KEYNAME" quits)\n\n",
+                 "\a\nSignal INT - rereading configuration file %s (" SIGQUIT_KEYNAME " quits)\n\n",
                  configfile);
       }
 
@@ -5178,9 +5178,9 @@ int main(int argc, char **argv){
     "smartd", "SmartD Service", // servicename, displayname
     // description
     "Controls and monitors storage devices using the Self-Monitoring, "
-    "Analysis and Reporting Technology System (S.M.A.R.T.) "
-    "built into ATA and SCSI Hard Drives. "
-    PACKAGE_HOMEPAGE
+    "Analysis and Reporting Technology System (SMART) built into "
+    "ATA/SATA and SCSI/SAS hard drives and solid-state drives. "
+    "www.smartmontools.org"
   };
   // daemon_main() handles daemon and service specific commands
   // and starts smartd_main() direct, from a new process,
index 1ce551b304020126313e880ac018c724beb8c979..dc8b14374a51904a0a47f30b798d42ee7d407047 100644 (file)
@@ -1,5 +1,6 @@
 [Unit]
 Description=Self Monitoring and Reporting Technology (SMART) Daemon
+Documentation=man:smartd(8) man:smartd.conf(5)
 After=syslog.target
 
 [Service]
index a077255062b6ed5c249238f7c5cf3faa0b5afd5e..81be61098d079ae37487208e591147f45b86c1c6 100644 (file)
@@ -2,7 +2,7 @@
 #
 # smartd warning script
 #
-# Copyright (C) 2012-13 Christian Franke <smartmontools-support@lists.sourceforge.net>
+# Copyright (C) 2012-14 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
@@ -12,7 +12,7 @@
 # You should have received a copy of the GNU General Public License
 # (for example COPYING); If not, see <http://www.gnu.org/licenses/>.
 #
-# $Id: smartd_warning.sh.in 3809 2013-04-18 19:41:40Z chrfranke $
+# $Id: smartd_warning.sh.in 3932 2014-06-29 19:02:38Z chrfranke $
 #
 
 set -e
@@ -22,12 +22,13 @@ PACKAGE="@PACKAGE@"
 VERSION="@VERSION@"
 prefix="@prefix@"
 sysconfdir="@sysconfdir@"
+smartdscriptdir="@smartdscriptdir@"
 
 # Default mailer
 os_mailer="@os_mailer@"
 
-# Plugin directory
-plugindir="$sysconfdir/smartd_warning.d"
+# Plugin directory (disabled if empty)
+plugindir="@smartdplugindir@"
 
 # Parse options
 dryrun=
@@ -127,7 +128,8 @@ export SMARTD_FULLMESSAGE="$fullmessage
 "
 
 # Run plugin scripts if requested
-case " $SMARTD_ADDRESS" in
+if test -n "$plugindir"; then
+ case " $SMARTD_ADDRESS" in
   *\ @*)
     if [ -n "$dryrun" ]; then
       echo "export SMARTD_SUBJECT='$SMARTD_SUBJECT'"
@@ -177,7 +179,8 @@ case " $SMARTD_ADDRESS" in
     # Send email to remaining addresses
     test -n "$SMARTD_ADDRESS" || exit 0
     ;;
-esac
+ esac
+fi
 
 # Send mail or run command
 if [ -n "$SMARTD_ADDRESS" ]; then
diff --git a/update-smart-drivedb.8.in b/update-smart-drivedb.8.in
new file mode 100644 (file)
index 0000000..24e6afc
--- /dev/null
@@ -0,0 +1,104 @@
+.ig
+Copyright (C) 2013 Hannes von Haugwitz <hannes@vonhaugwitz.com>
+Copyright (C) 2014 Christian Franke <smartmontools-support@lists.sourceforge.net>
+
+$Id: update-smart-drivedb.8.in 3961 2014-07-19 16:44:10Z 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 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/>.
+
+..
+.TH UPDATE-SMART-DRIVEDB 8 CURRENT_SVN_DATE CURRENT_SVN_VERSION CURRENT_SVN_DATE
+.SH NAME
+update-smart-drivedb \- update smartmontools drive database
+
+.SH "SYNOPSIS"
+.B update-smart-drivedb
+.RB [ -v ]
+.RI [ DESTFILE ]
+
+.SH PACKAGE VERSION
+CURRENT_SVN_VERSION CURRENT_SVN_DATE CURRENT_SVN_REV
+
+.SH "DESCRIPTION"
+.B update-smart-drivedb
+updates
+.B /usr/local/share/smartmontools/drivedb.h
+or
+.I DESTFILE
+from smartmontools SVN repository.
+
+It tries to download first from the current branch and then from
+trunk. The tools used for downloading are either
+.BR curl (1),
+.BR wget "(1) or"
+.BR lynx (1).
+.\" %IF OS FreeBSD
+On FreeBSD,
+.BR fetch (1)
+is used as a fallback.
+.\" %ENDIF OS FreeBSD
+.\" %IF OS OpenBSD
+On OpenBSD,
+.BR ftp (1)
+is used as a fallback.
+.\" %ENDIF OS OpenBSD
+
+The old file is kept if the downloaded file is identical (ignoring
+the differences in Id string) otherwise it is moved to
+.BR drivedb.h.old .
+
+.SH "OPTIONS"
+.TP
+\-v
+verbose output
+
+.SH "EXAMPLES"
+.nf
+# update-smart-drivedb
+/usr/local/share/smartmontools/drivedb.h updated from branches/RELEASE_6_0_DRIVEDB
+.fi
+
+.SH "EXIT STATUS"
+The exit status is 0 if the database has been successfully
+updated. If an error occurs the exit status is 1.
+
+.SH FILES
+.TP
+.B /usr/local/sbin/update-smart-drivedb
+full path of this script.
+.TP
+.B /usr/local/sbin/smartctl
+used to check syntax of new drive database.
+.TP
+.B /usr/local/share/smartmontools/drivedb.h
+current drive database.
+.TP
+.B /usr/local/share/smartmontools/drivedb.h.old
+previous drive database.
+.TP
+.B /usr/local/share/smartmontools/drivedb.h.error
+new drive database rejected due to syntax errors.
+.TP
+.B /usr/local/share/smartmontools/drivedb.h.lastcheck
+empty file created if downloaded file was identical.
+
+.SH "SEE ALSO"
+.BR smartctl (8),
+.BR smartd (8).
+
+.SH AUTHORS
+\fBChristian Franke\fP
+.br
+\fBsmartmontools\-support@lists.sourceforge.net\fP
+.br
+This manual page was originally written by
+.BR "Hannes von Haugwitz <hannes@vonhaugwitz.com>" .
+
+.SH SVN ID OF THIS PAGE
+$Id: update-smart-drivedb.8.in 3961 2014-07-19 16:44:10Z chrfranke $
index 7cd81ca14aa4e6117bf00c114e67c919a21b6842..09a4f1f1bb45c86afe9c0b1b37113e0533df4354 100644 (file)
@@ -4,7 +4,7 @@
  * Home page of code is: http://smartmontools.sourceforge.net
  *
  * Copyright (C) 2002-12 Bruce Allen <smartmontools-support@lists.sourceforge.net>
- * Copyright (C) 2008-13 Christian Franke <smartmontools-support@lists.sourceforge.net>
+ * Copyright (C) 2008-14 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
@@ -52,7 +52,7 @@
 #include "atacmds.h"
 #include "dev_interface.h"
 
-const char * utility_cpp_cvsid = "$Id: utility.cpp 3838 2013-07-21 16:32:27Z chrfranke $"
+const char * utility_cpp_cvsid = "$Id: utility.cpp 3937 2014-07-05 17:51:21Z chrfranke $"
                                  UTILITY_H_CVSID INT64_H_CVSID;
 
 const char * packet_types[] = {
@@ -83,14 +83,14 @@ const char * packet_types[] = {
 std::string format_version_info(const char * prog_name, bool full /*= false*/)
 {
   std::string info = strprintf(
-    "%s "PACKAGE_VERSION" "
+    "%s " PACKAGE_VERSION " "
 #ifdef SMARTMONTOOLS_SVN_REV
-      SMARTMONTOOLS_SVN_DATE" r"SMARTMONTOOLS_SVN_REV
+      SMARTMONTOOLS_SVN_DATE " r" SMARTMONTOOLS_SVN_REV
 #else
-      "(build date "__DATE__")" // checkout without expansion of Id keywords
+      "(build date " __DATE__ ")" // checkout without expansion of Id keywords
 #endif
-      " [%s] "BUILD_INFO"\n"
-    "Copyright (C) 2002-13, Bruce Allen, Christian Franke, www.smartmontools.org\n",
+      " [%s] " BUILD_INFO "\n"
+    "Copyright (C) 2002-14, Bruce Allen, Christian Franke, www.smartmontools.org\n",
     prog_name, smi()->get_os_version_str().c_str()
   );
   if (!full)
@@ -106,21 +106,21 @@ std::string format_version_info(const char * prog_name, bool full /*= false*/)
     "\n",
     prog_name
   );
-  info += strprintf(
-    "smartmontools release "PACKAGE_VERSION
-      " dated "SMARTMONTOOLS_RELEASE_DATE" at "SMARTMONTOOLS_RELEASE_TIME"\n"
+  info +=
+    "smartmontools release " PACKAGE_VERSION
+      " dated " SMARTMONTOOLS_RELEASE_DATE " at " SMARTMONTOOLS_RELEASE_TIME "\n"
 #ifdef SMARTMONTOOLS_SVN_REV
-    "smartmontools SVN rev "SMARTMONTOOLS_SVN_REV
-      " dated "SMARTMONTOOLS_SVN_DATE" at "SMARTMONTOOLS_SVN_TIME"\n"
+    "smartmontools SVN rev " SMARTMONTOOLS_SVN_REV
+      " dated " SMARTMONTOOLS_SVN_DATE " at " SMARTMONTOOLS_SVN_TIME "\n"
 #else
     "smartmontools SVN rev is unknown\n"
 #endif
-    "smartmontools build host: "SMARTMONTOOLS_BUILD_HOST"\n"
-    "smartmontools build configured: "SMARTMONTOOLS_CONFIGURE_DATE "\n"
-    "%s compile dated "__DATE__" at "__TIME__"\n"
-    "smartmontools configure arguments: ",
-    prog_name
-  );
+    "smartmontools build host: " SMARTMONTOOLS_BUILD_HOST "\n"
+#if defined(__GNUC__) && defined(__VERSION__) // works also with CLang
+    "smartmontools build with: GCC " __VERSION__ "\n"
+#endif
+    "smartmontools configure arguments: "
+  ;
   info += (sizeof(SMARTMONTOOLS_CONFIGURE_ARGS) > 1 ?
            SMARTMONTOOLS_CONFIGURE_ARGS : "[no arguments given]");
   info += '\n';
@@ -265,7 +265,7 @@ const char *packetdevicetype(int type){
 }
 
 // Runtime check of byte ordering, throws if different from isbigendian().
-void check_endianness()
+static void check_endianness()
 {
   union {
     // Force compile error if int type is not 32bit.
@@ -735,7 +735,7 @@ const char * format_with_thousands_sep(char * str, int strsize, uint64_t val,
   }
 
   char num[64];
-  snprintf(num, sizeof(num), "%"PRIu64, val);
+  snprintf(num, sizeof(num), "%" PRIu64, val);
   int numlen = strlen(num);
 
   int i = 0, j = 0;
@@ -783,12 +783,12 @@ const char * format_capacity(char * str, int strsize, uint64_t val,
   if (i == 0)
     snprintf(str, strsize, "%u B", (unsigned)n);
   else if (n >= 100) // "123 xB"
-    snprintf(str, strsize, "%"PRIu64" %cB", n, prefixes[i]);
+    snprintf(str, strsize, "%" PRIu64 " %cB", n, prefixes[i]);
   else if (n >= 10)  // "12.3 xB"
-    snprintf(str, strsize, "%"PRIu64"%s%u %cB", n, decimal_point,
+    snprintf(str, strsize, "%" PRIu64 "%s%u %cB", n, decimal_point,
         (unsigned)(((val % d) * 10) / d), prefixes[i]);
   else               // "1.23 xB"
-    snprintf(str, strsize, "%"PRIu64"%s%02u %cB", n, decimal_point,
+    snprintf(str, strsize, "%" PRIu64 "%s%02u %cB", n, decimal_point,
         (unsigned)(((val % d) * 100) / d), prefixes[i]);
 
   return str;
@@ -814,8 +814,8 @@ std::string strprintf(const char * fmt, ...)
 
 
 #ifndef HAVE_WORKING_SNPRINTF
-// Some versions of (v)snprintf() don't append null char on overflow (MSVCRT.DLL),
-// and/or return -1 on overflow (old Linux).
+// Some versions of (v)snprintf() don't append null char (MSVCRT.DLL),
+// and/or return -1 on output truncation (glibc <= 2.0.6).
 // Below are sane replacements substituted by #define in utility.h.
 
 #undef vsnprintf
@@ -844,5 +844,25 @@ int safe_snprintf(char *buf, int size, const char *fmt, ...)
   return i;
 }
 
-#endif
+#else // HAVE_WORKING_SNPRINTF
+
+static void check_snprintf()
+{
+  char buf[] =              "ABCDEFGHI";
+  int n1 = snprintf(buf, 8, "123456789");
+  int n2 = snprintf(buf, 0, "X");
+  if (!(!strcmp(buf, "1234567") && n1 == 9 && n2 == 1))
+    throw std::logic_error("Function snprintf() does not conform to C99,\n"
+                           "please contact " PACKAGE_BUGREPORT);
+}
+
+#endif // HAVE_WORKING_SNPRINTF
 
+// Runtime check of ./configure result, throws on error.
+void check_config()
+{
+  check_endianness();
+#ifdef HAVE_WORKING_SNPRINTF
+  check_snprintf();
+#endif
+}
index 72764ee57614eed61ba2f96d55cfa811f8297b8a..b172029d03436e4eaadf48d47114925e08386acc 100644 (file)
--- a/utility.h
+++ b/utility.h
@@ -4,7 +4,7 @@
  * Home page of code is: http://smartmontools.sourceforge.net
  *
  * Copyright (C) 2002-11 Bruce Allen <smartmontools-support@lists.sourceforge.net>
- * Copyright (C) 2008-12 Christian Franke <smartmontools-support@lists.sourceforge.net>
+ * Copyright (C) 2008-14 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,7 +25,7 @@
 #ifndef UTILITY_H_
 #define UTILITY_H_
 
-#define UTILITY_H_CVSID "$Id: utility.h 3719 2012-12-03 21:19:33Z chrfranke $"
+#define UTILITY_H_CVSID "$Id: utility.h 3936 2014-07-05 17:16:23Z chrfranke $"
 
 #include <time.h>
 #include <sys/types.h> // for regex.h (according to POSIX)
@@ -155,8 +155,8 @@ inline bool isbigendian()
 #endif
 }
 
-// Runtime check of byte ordering, throws if different from isbigendian().
-void check_endianness();
+// Runtime check of ./configure result, throws on error.
+void check_config();
 
 // This value follows the peripheral device type value as defined in
 // SCSI Primary Commands, ANSI INCITS 301:1997.  It is also used in