]> git.proxmox.com Git - mirror_smartmontools-debian.git/commitdiff
Imported Upstream version 5.42+svn3561
authorGiuseppe Iuculano <iuculano@debian.org>
Wed, 13 Jun 2012 14:26:15 +0000 (16:26 +0200)
committerGiuseppe Iuculano <iuculano@debian.org>
Wed, 13 Jun 2012 14:26:15 +0000 (16:26 +0200)
17 files changed:
CHANGELOG
INSTALL
Makefile.am
NEWS
ataprint.cpp
dev_interface.cpp
dev_interface.h
drivedb.h
os_freebsd.cpp
os_linux.cpp
os_win32.cpp
os_win32/installer.nsi
smartctl.8.in
smartd.8.in
smartd.conf.5.in
smartd.service.in
utility.h

index 23994e4d272b57c6cd90548683b35030e33b5a60..cac139eb1fd6857f953c02faa91d63db0214199f 100644 (file)
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,6 +1,6 @@
 CHANGELOG for smartmontools
 
-$Id: CHANGELOG 3539 2012-05-01 19:57:02Z chrfranke $
+$Id: CHANGELOG 3561 2012-06-05 19:49:31Z chrfranke $
 
 The most recent version of this file is:
 http://smartmontools.svn.sourceforge.net/viewvc/smartmontools/trunk/smartmontools/CHANGELOG?view=markup
@@ -41,6 +41,68 @@ Maintainers / Developers Key (alphabetic order):
 
 <DEVELOPERS: ADDITIONS TO THE CHANGE LOG GO JUST BELOW HERE, PLEASE>
 
+  [CF] man pages: Minor updates and syntax fixes.
+
+  [CF] smartd.service.in: Add ExecReload and StandardOutput.
+       Make EnvironmentFile optional (ticket #194).
+
+  [CF] drivedb.h USB updates:
+       - HP Desktop HD BD07 (0x03f0:0xbd07)
+       - Iomega Prestige Desktop USB 3.0 (0x059b:0x0070)
+       - Prolific PL2507 (0x067b:0x2507): unsupported -> -d usbjmicron,0
+       - WD My Passport USB 3.0 (0x1058:0x0748)
+       - WD My Book Essential USB 3.0 (0x1058:0x1140)
+       - Sharkoon SATA QuickDeck Pro (0x1f75:0x0888): unsupported
+       - Hitachi Touro Desk (0x4971:0x1015)
+
+  [CF] Move function str_starts_with() to utility.h.
+
+  [CF] smartctl.8.in, smartd.conf.5.in: Note required Areca SAS firmware version.
+
+  [CF] INSTALL, smartctl.8.in: Announce OS X SAT SMART Driver (ticket #25).
+
+  [CF] Add smart_device::is_syscall_unsup().
+
+  [CF] os_win32.cpp: Avoid ENOTSUP which is not provided by some versions
+       of MinGW.
+
+  [DG] os_linux.cpp: Fix scsi pass-through SG_INFO_CHECK mask logic
+       (ticket #225)
+
+  [CF] drivedb.h updates:
+       - Sandforce Driven SSDs: OCZ-NOCTI
+       - Intel 330 Series SSDs (ticket #227)
+
+  [CF] smartctl.8.in, smartd.conf.5.in: Document '-d areca N[/E]' support
+       for Windows.
+
+  [CF] os_win32.cpp: Add help text and error messages for '-d areca,N[/E]'.
+
+  [CF] os_win32.cpp win_areca_device: Disable full 48-bit ATA support.
+       Add missing set_err() calls.  Remove unused function and parameter.
+
+  [CF] os_win32.cpp: Add support for SATA disks behind Areca SATA and SAS
+       controllers.  Requires '-d areca,N[/E]' as type and '[/dev/]arcmsrX'
+       as device name.
+
+       Patch was provided by Hank Wu from Areca.
+
+  [CF] Windows installer: Make name of checksum file 32-/64-bit specific.
+
+  [CF] Windows installer: Add support for combined 32-/64-bit installer.
+
+  [CF] Windows installer: Drop support for UBCD4Win.
+
+  [AS] os_freebsd.cpp: sync Areca code with linux version by adding optional 
+       enclosure number.
+
+  [CF] smartctl.8.in, smartd.conf.5.in: Add brief doc for '-d areca N/E'.
+
+  [CF] os_linux.cpp: Add optional enclosure number to '-d areca' option.
+       This adds support for SATA disks behind Areca SAS controllers.
+
+       Patch was provided by Hank Wu from Areca.
+
   [CF] smartctl: Add log addresses and statistics value from ACS-3 revision 2.
 
   [CF] drivedb.h updates:
diff --git a/INSTALL b/INSTALL
index 36fcb952e1263437537d4f37d14161d06af5426f..1863c34f4f4831f2982030a1144c83b210517536 100644 (file)
--- a/INSTALL
+++ b/INSTALL
@@ -1,7 +1,7 @@
 Smartmontools installation instructions
 =======================================
 
-$Id: INSTALL 3537 2012-04-28 13:22:41Z chrfranke $
+$Id: INSTALL 3555 2012-06-01 21:07:33Z chrfranke $
 
 Please also see the smartmontools home page:
 http://smartmontools.sourceforge.net/
@@ -193,6 +193,13 @@ Table of contents:
     hard drive comes with the offline test switched on by default, so
     even that works.
 
+    The OS X SAT SMART Driver provides access to SMART data for SAT capable
+    USB and Firewire devices:
+    https://github.com/kasbert/OS-X-SAT-SMART-Driver
+    https://github.com/RJVB/OS-X-SAT-SMART-Driver
+    This does not require any smartctl -d TYPE option and should work also
+    with older smartmontools releases.
+
     H) OS/2, eComStation
 
     The code was tested on eComStation 1.1, but it should work on all versions
@@ -495,6 +502,11 @@ To create a Windows installer, use:
   It is also possible to (cross-)build the installer on Linux.
   This was successfully tested on Debian with package "nsis".
 
+To create a combined 32-/64-bit installer, use this in 32-bit build
+directory if 64-build directory is at ../build64:
+
+  make builddir_win64=../build64 installer_win32
+
 To both create and run the (interactive) installer, use:
 
   make install-win32
index cd3d8a51e06ab0da622230c2cfc9bdc536986b04..d1055560fd12e2e576f19ba6e7899e4fad4034ed 100644 (file)
@@ -1,6 +1,6 @@
 ## Process this file with automake to produce Makefile.in
 #
-# $Id: Makefile.am 3527 2012-03-25 16:42:24Z chrfranke $
+# $Id: Makefile.am 3545 2012-05-25 21:19:03Z chrfranke $
 #
 
 @SET_MAKE@
@@ -656,7 +656,7 @@ FILES_WIN32 = \
         $(docdir_win32)/README.txt \
         $(docdir_win32)/TODO.txt \
         $(docdir_win32)/WARNINGS.txt \
-        $(docdir_win32)/checksums.txt \
+        $(docdir_win32)/checksums$(win_bits).txt \
         $(docdir_win32)/smartd.conf \
         $(docdir_win32)/smartctl.8.html \
         $(docdir_win32)/smartctl.8.txt \
@@ -708,11 +708,13 @@ if OS_WIN32_NSIS
 # Build NSIS installer
 # Note: Only option character '-' is also compatible with Linux version of makensis
 $(distinst_win32): os_win32/installer.nsi distdir.mkdir $(FILES_WIN32)
+       test -z '$(builddir_win64)' || ( cd $(builddir_win64) && make distdir-win32 )
        @date=`sed -n 's,^.*DATE[^"]*"\([^"]*\)".*$$,\1,p' svnversion.h`; \
        rev=`sed -n 's,^.*REV[^"]*"\([^"]*\)".*$$,r\1,p' svnversion.h`; \
        verstr="$(PACKAGE_VERSION) $$date $$rev "$(BUILD_INFO); \
-       echo "'$(MAKENSIS)' -V2 -NOCD -DINPDIR=$(distdir_win32) -DOUTFILE=$@ -DVERSTR='$$verstr' $<"; \
-       '$(MAKENSIS)' -V2 -NOCD -DINPDIR=$(distdir_win32) -DOUTFILE=$@ -DVERSTR="$$verstr" $<
+       d64=; test -z '$(builddir_win64)' || d64='-DINPDIR64=$(builddir_win64)/$(PACKAGE)-$(VERSION).win64'; \
+       echo "'$(MAKENSIS)' -V2 -NOCD -DINPDIR=$(distdir_win32) $$d64 -DOUTFILE=$@ -DVERSTR='$$verstr' $<"; \
+       '$(MAKENSIS)' -V2 -NOCD -DINPDIR=$(distdir_win32) $$d64 -DOUTFILE=$@ -DVERSTR="$$verstr" $<
        md5sum $@ > $@.md5
        sha1sum $@ > $@.sha1
        sha256sum $@ > $@.sha256
@@ -772,7 +774,7 @@ $(docdir_win32)/%.conf: $(srcdir)/%.conf
        $(UNIX2DOS) < $< > $@
        touch -r $< $@
 
-$(docdir_win32)/checksums.txt: $(EXEFILES_WIN32)
+$(docdir_win32)/checksums$(win_bits).txt: $(EXEFILES_WIN32)
        (cd $(exedir_win32) && md5sum *.exe && sha1sum *.exe && sha256sum *.exe) \
        | $(UNIX2DOS) > $@
 
diff --git a/NEWS b/NEWS
index 07cbf41300aa7f130ef781a6332420281f7a90ed..a5b41cda93390f6e31606655cd9fd03e49f43175 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,6 +1,6 @@
 smartmontools NEWS
 ------------------
-$Id: NEWS 3530 2012-03-27 19:54:06Z chrfranke $
+$Id: NEWS 3557 2012-06-04 19:50:21Z chrfranke $
 
 The most up-to-date version of this file is:
 http://smartmontools.svn.sourceforge.net/viewvc/smartmontools/trunk/smartmontools/NEWS?view=markup
@@ -18,9 +18,14 @@ Summary: smartmontools release 5.43
   already running.  Override with new option '-t force'.
 - smartctl supports extended self-test polling times
   greater than 255 minutes.
+- Controller-independent SAT detection: '-d sat,auto[+TYPE]'.
 - smartd.conf DEFAULT directive.
+- Many HDD, SSD and USB additions to drive database.
+- Linux and FreeBSD: Support for SATA disks behind Areca SAS controllers.
+- Windows: Support for SATA disks behind Areca controllers.
 - Windows smartd: directives '-l offlinests,ns' and
   '-l selfteststs,ns'.
+- Windows installer: Combined 32-/64-bit support.
 - FreeBSD: fixed crash on SCSI devices with FreeBSD9-RC1
 
 Date 2011-10-20
index 0007d34134f2e0fbc97da7f9e8bb3b030b42d855..4fd2724f68c735f1741c1bed60bf0f02bd154465 100644 (file)
@@ -40,7 +40,7 @@
 #include "utility.h"
 #include "knowndrives.h"
 
-const char * ataprint_cpp_cvsid = "$Id: ataprint.cpp 3539 2012-05-01 19:57:02Z chrfranke $"
+const char * ataprint_cpp_cvsid = "$Id: ataprint.cpp 3554 2012-06-01 20:11:46Z chrfranke $"
                                   ATAPRINT_H_CVSID;
 
 
@@ -2146,7 +2146,7 @@ int ataPrintMain (ata_device * device, const ata_print_options & options)
     int powermode = ataCheckPowerMode(device);
     switch (powermode) {
       case -1:
-        if (device->get_errno() == ENOSYS) {
+        if (device->is_syscall_unsup()) {
           pout("CHECK POWER MODE not implemented, ignoring -n option\n"); break;
         }
         powername = "SLEEP";   powerlimit = 2;
index b63f34cdc57c11e78c9750789620514c1be9955b..7651244aeb069e88d6bbf16775e3c50e53e7f02d 100644 (file)
@@ -31,7 +31,7 @@
 #include <sys/timeb.h>
 #endif
 
-const char * dev_interface_cpp_cvsid = "$Id: dev_interface.cpp 3524 2012-03-21 22:19:31Z chrfranke $"
+const char * dev_interface_cpp_cvsid = "$Id: dev_interface.cpp 3554 2012-06-01 20:11:46Z chrfranke $"
   DEV_INTERFACE_H_CVSID;
 
 /////////////////////////////////////////////////////////////////////////////
@@ -54,6 +54,17 @@ smart_device::~smart_device() throw()
 {
 }
 
+bool smart_device::is_syscall_unsup() const
+{
+  if (get_errno() == ENOSYS)
+    return true;
+#ifdef ENOTSUP
+  if (get_errno() == ENOTSUP)
+    return true;
+#endif
+  return false;
+}
+
 bool smart_device::set_err(int no, const char * msg, ...)
 {
   if (!msg)
index d887b608f01b6b551bc999c859a34a40c8714bc6..136831cc41edfb0466ecb97ae5e95b3ced6004fd 100644 (file)
@@ -18,7 +18,7 @@
 #ifndef DEV_INTERFACE_H
 #define DEV_INTERFACE_H
 
-#define DEV_INTERFACE_H_CVSID "$Id: dev_interface.h 3524 2012-03-21 22:19:31Z chrfranke $\n"
+#define DEV_INTERFACE_H_CVSID "$Id: dev_interface.h 3554 2012-06-01 20:11:46Z chrfranke $\n"
 
 #include "utility.h"
 
@@ -147,6 +147,10 @@ public:
   const char * get_errmsg() const
     { return m_err.msg.c_str(); }
 
+  /// Return true if last error indicates an unsupported system call.
+  /// Default implementation returns true on ENOSYS and ENOTSUP.
+  virtual bool is_syscall_unsup() const;
+
   /// Set last error number and message.
   /// Printf()-like formatting is supported.
   /// Returns false always to allow use as a return expression.
@@ -183,7 +187,7 @@ public:
   /// Open device with autodetection support.
   /// May return another device for further access.
   /// In this case, the original pointer is no longer valid.
-  /// Default Implementation calls 'open()' and returns 'this'.
+  /// Default implementation calls 'open()' and returns 'this'.
   virtual smart_device * autodetect_open();
 
   ///////////////////////////////////////////////
index 819dea6e446cf34dfad1aa9ed6a899b8e2b9227f..31cce28db3e4bd4b09d03e84a8121b7bf0ef61db 100644 (file)
--- a/drivedb.h
+++ b/drivedb.h
@@ -75,7 +75,7 @@
 /*
 const drive_settings builtin_knowndrives[] = {
  */
-  { "$Id: drivedb.h 3538 2012-05-01 19:45:49Z chrfranke $",
+  { "$Id: drivedb.h 3559 2012-06-05 18:35:10Z chrfranke $",
     "-", "-",
     "This is a dummy entry to hold the SVN-Id of drivedb.h",
     ""
@@ -204,6 +204,7 @@ const drive_settings builtin_knowndrives[] = {
     "KINGSTON SH100S3(120|240)G|" // Hyper-X, SF-2281, tested with SH100S3240G/320ABBF0
     "OCZ[ -](AGILITY2([ -]EX)?|COLOSSUS2|ONYX2|VERTEX(2|-LE))( [123]\\..*)?|" // SF-1200,
       // tested with OCZ-VERTEX2/1.11, OCZ-VERTEX2 3.5/1.11
+    "OCZ-NOCTI|" // mSATA, SF-2100, tested with OCZ-NOCTI/2.15
     "OCZ-REVODRIVE3?( X2)?|" // PCIe, SF-1200/2281, tested with
       // OCZ-REVODRIVE( X2)?/1.20, OCZ-REVODRIVE3 X2/2.11
     "OCZ[ -](VELO|VERTEX2[ -](EX|PRO))( [123]\\..*)?|" // SF-1500, tested with
@@ -456,6 +457,22 @@ const drive_settings builtin_knowndrives[] = {
     "-v 242,raw48,Host_Reads_32MiB "
     "-v 249,raw48,NAND_Writes_1GiB"
   },
+  { "Intel 330 Series SSDs", // tested with INTEL SSDSC2CT180A3/300i
+    "INTEL SSDSC2CT(060|120|180)A3",
+    "", "",
+  //"-v 5,raw16(raw16),Reallocated_Sector_Ct "
+    "-v 9,msec24hour32,Power_On_Hours_and_Msec "
+  //"-v 12,raw48,Power_Cycle_Count "
+  //"-v 181,raw48,Program_Fail_Cnt_Total " // ] Missing in 330 specification from April 2012
+  //"-v 182,raw48,Erase_Fail_Count_Total " // ]
+  //"-v 192,raw48,Power-Off_Retract_Count "
+    "-v 225,raw48,Host_Writes_32MiB "
+  //"-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"
+  },
   { "Kingston branded X25-V SSDs", // fixed firmware
     "KINGSTON SSDNow 40GB",
     "2CV102(J[89A-Z]|[K-Z].)", // >= "2CV102J8"
@@ -2214,6 +2231,13 @@ const drive_settings builtin_knowndrives[] = {
   // USB ID entries
   ////////////////////////////////////////////////////
 
+  // Hewlett-Packard
+  { "USB: HP Desktop HD BD07; ", // 2TB
+    "0x03f0:0xbd07",
+    "",
+    "",
+    "-d sat"
+  },
   // ALi
   { "USB: ; ALi M5621", // USB->PATA
     "0x0402:0x5621",
@@ -2345,6 +2369,12 @@ const drive_settings builtin_knowndrives[] = {
     "-d usbsunplus"
   },
   // Iomega
+  { "USB: Iomega Prestige Desktop USB 3.0; ",
+    "0x059b:0x0070",
+    "", // 0x0004
+    "",
+    "-d sat" // ATA output registers missing
+  },
   { "USB: Iomega LPHD080-0; ",
     "0x059b:0x0272",
     "",
@@ -2468,7 +2498,7 @@ const drive_settings builtin_knowndrives[] = {
     "0x067b:0x2507",
     "",
     "",
-    "" // unsupported
+    "-d usbjmicron,0" // Port number is required
   },
   { "USB: ; Prolific PL3507", // USB+IEE1394->PATA
     "0x067b:0x3507",
@@ -2746,6 +2776,12 @@ const drive_settings builtin_knowndrives[] = {
     "",
     "-d sat"
   },
+  { "USB: WD My Passport USB 3.0; ",
+    "0x1058:0x0748",
+    "",
+    "",
+    "-d sat"
+  },
   { "USB: WD My Book ES; ",
     "0x1058:0x0906",
     "", // 0x0012
@@ -2819,8 +2855,8 @@ const drive_settings builtin_knowndrives[] = {
     "-d sat"
   },
   { "USB: WD My Book Essential USB 3.0; ", // 3TB
-    "0x1058:0x1130",
-    "", // 0x1012
+    "0x1058:0x11[34]0",
+    "", // 0x1012/0x1003
     "",
     "-d sat"
   },
@@ -3020,6 +3056,13 @@ const drive_settings builtin_knowndrives[] = {
     "",
     "-d usbsunplus"
   },
+  // Unknown: 0x1f75
+  { "USB: Sharkoon SATA QuickDeck Pro; ", // USB 2.0/3.0
+    "0x1f75:0x0888",
+    "", // 0x0034
+    "",
+    "" // unsupported
+  },
   // Hitachi/SimpleTech
   { "USB: Hitachi Touro Desk; JMicron", // 3TB
     "0x4971:0x1011",
@@ -3027,6 +3070,12 @@ const drive_settings builtin_knowndrives[] = {
     "",
     "-d usbjmicron"
   },
+  { "USB: Hitachi Touro Desk 3.0; ", // 2TB
+    "0x4971:0x1015",
+    "", // 0x0000
+    "",
+    "-d sat" // ATA output registers missing
+  },
   { "USB: Hitachi/SimpleTech; JMicron", // 1TB
     "0x4971:0xce17",
     "",
index 5038b1219ecc52e6aff98c95e677ec81cf308586..d9a6add0dddfa0f029c5b399dffe50d4f401cf52 100644 (file)
@@ -74,7 +74,7 @@
 #define PATHINQ_SETTINGS_SIZE   128
 #endif
 
-const char *os_XXXX_c_cvsid="$Id: os_freebsd.cpp 3525 2012-03-22 08:54:52Z samm2 $" \
+const char *os_XXXX_c_cvsid="$Id: os_freebsd.cpp 3542 2012-05-18 18:18:45Z 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
@@ -194,8 +194,8 @@ static const char  smartctl_examples[] =
   "  smartctl -a --device=cciss,0 /dev/ciss0\n"
          "                              (Prints all SMART information for first disk \n"
          "                               on Common Interface for SCSI-3 Support driver)\n"
-  "  smartctl -a --device=areca,1 /dev/arcmsr0\n"
-         "                              (Prints all SMART information for first disk \n"
+  "  smartctl -a --device=areca,3/1 /dev/arcmsr0\n"
+         "                              (Prints all SMART information for 3rd disk in the 1st enclosure \n"
          "                               on first ARECA RAID controller)\n"
 
          ;
@@ -1089,7 +1089,7 @@ class freebsd_areca_device
   public /*extends*/ freebsd_smart_device
 {
 public:
-  freebsd_areca_device(smart_interface * intf, const char * dev_name, int disknum);
+  freebsd_areca_device(smart_interface * intf, const char * dev_name, int disknum, int encnum = 1);
 
 protected:
   virtual bool ata_pass_through(const ata_cmd_in & in, ata_cmd_out & out); 
@@ -1313,12 +1313,13 @@ static int arcmsr_command_handler(int fd, unsigned long arcmsr_cmd, unsigned cha
 }
 
 
-freebsd_areca_device::freebsd_areca_device(smart_interface * intf, const char * dev_name, int disknum)
+freebsd_areca_device::freebsd_areca_device(smart_interface * intf, const char * dev_name, int disknum, int encnum)
 : smart_device(intf, dev_name, "areca", "areca"),
   freebsd_smart_device("ATA"),
-  m_disknum(disknum)
+  m_disknum(disknum),
+  m_encnum(encnum)
 {
-  set_info().info_name = strprintf("%s [areca_%02d]", dev_name, disknum);
+  set_info().info_name = strprintf("%s [areca_disk#%02d_enc#%02d]", dev_name, disknum, encnum);
 }
 
 // Areca RAID Controller
@@ -1437,7 +1438,8 @@ if (!ata_cmd_is_ok(in,
            return set_err(ENOTSUP, "DATA OUT not supported for this Areca controller type");
        }
 
-       areca_packet[11] = m_disknum - 1;                  // drive number
+       areca_packet[11] = m_disknum - 1;               // disk #
+       areca_packet[19] = m_encnum - 1;                // enc#
 
        // ----- BEGIN TO SETUP CHECKSUM -----
        for ( int loop = 3; loop < areca_packet_len - 1; loop++ )
@@ -2270,13 +2272,14 @@ smart_device * freebsd_smart_interface::get_custom_smart_device(const char * nam
 #endif
   // Areca?
   disknum = n1 = n2 = -1;
-  if (sscanf(type, "areca,%n%d%n", &n1, &disknum, &n2) == 1 || n1 == 6) {
-    if (n2 != (int)strlen(type)) {
-      set_err(EINVAL, "Option -d areca,N requires N to be a non-negative integer");
+  int encnum = 1;
+  if (sscanf(type, "areca,%n%d/%d%n", &n1, &disknum, &encnum, &n2) >= 1 || n1 == 6) {
+    if (!(1 <= disknum && disknum <= 128)) {
+      set_err(EINVAL, "Option -d areca,N/E (N=%d) must have 1 <= N <= 128", disknum);
       return 0;
     }
-    if (!(1 <= disknum && disknum <= 24)) {
-      set_err(EINVAL, "Option -d areca,N (N=%d) must have 1 <= N <= 24", disknum);
+    if (!(1 <= encnum && encnum <= 8)) {
+      set_err(EINVAL, "Option -d areca,N/E (E=%d) must have 1 <= E <= 8", encnum);
       return 0;
     }
     return new freebsd_areca_device(this, name, disknum);
@@ -2287,7 +2290,7 @@ smart_device * freebsd_smart_interface::get_custom_smart_device(const char * nam
 
 std::string freebsd_smart_interface::get_valid_custom_dev_types_str()
 {
-  return "3ware,N, hpt,L/M/N, cciss,N, areca,N"
+  return "3ware,N, hpt,L/M/N, cciss,N, areca,N/E"
 #if FREEBSDVER > 800100
   ", atacam"
 #endif
index 46c8b3a40bf0268d58cddc0921813cf4dfc44fc5..b68575a12e348a995accad3021b1808b025b0a06 100644 (file)
@@ -5,9 +5,9 @@
  *
  * Copyright (C) 2003-11 Bruce Allen <smartmontools-support@lists.sourceforge.net>
  * Copyright (C) 2003-11 Doug Gilbert <dgilbert@interlog.com>
- * Copyright (C) 2008    Hank Wu <hank@areca.com.tw>
+ * Copyright (C) 2008-12 Hank Wu <hank@areca.com.tw>
  * Copyright (C) 2008    Oliver Bock <brevilo@users.sourceforge.net>
- * Copyright (C) 2008-11 Christian Franke <smartmontools-support@lists.sourceforge.net>
+ * Copyright (C) 2008-12 Christian Franke <smartmontools-support@lists.sourceforge.net>
  * Copyright (C) 2008    Jordan Hargrave <jordan_hargrave@dell.com>
  *
  *  Parts of this file are derived from code that was
@@ -89,7 +89,7 @@
 
 #define ARGUSED(x) ((void)(x))
 
-const char * os_linux_cpp_cvsid = "$Id: os_linux.cpp 3441 2011-10-12 17:22:15Z chrfranke $"
+const char * os_linux_cpp_cvsid = "$Id: os_linux.cpp 3558 2012-06-05 16:42:05Z chrfranke $"
   OS_LINUX_H_CVSID;
 
 
@@ -196,8 +196,9 @@ static const char  smartctl_examples[] =
                  "  smartctl --all --device=hpt,1/1/3 /dev/sda\n"
                  "          (Prints all SMART info for the SATA disk attached to the 3rd PMPort\n"
                  "           of the 1st channel on the 1st HighPoint RAID controller)\n"
-                 "  smartctl --all --device=areca,3 /dev/sg2\n"
-                 "          (Prints all SMART info for 3rd ATA disk on Areca RAID controller)\n"
+                 "  smartctl --all --device=areca,3/1 /dev/sg2\n"
+                 "          (Prints all SMART info for 3rd ATA disk of the 1st enclosure\n"
+                 "           on Areca RAID controller)\n"
   ;
 
 
@@ -605,7 +606,7 @@ static int sg_io_cmnd_io(int dev_fd, struct scsi_cmnd_io * iop, int report,
         }
     }
 
-    if (io_hdr.info | SG_INFO_CHECK) { /* error or warning */
+    if (io_hdr.info & SG_INFO_CHECK) { /* error or warning */
         int masked_driver_status = (LSCSI_DRIVER_MASK & io_hdr.driver_status);
 
         if (0 != io_hdr.host_status) {
@@ -1652,13 +1653,14 @@ class linux_areca_device
   public /*extends*/ linux_smart_device
 {
 public:
-  linux_areca_device(smart_interface * intf, const char * dev_name, int disknum);
+  linux_areca_device(smart_interface * intf, const char * dev_name, int disknum, int encnum = 1);
 
 protected:
   virtual bool ata_pass_through(const ata_cmd_in & in, ata_cmd_out & out); 
 
 private:
   int m_disknum; ///< Disk number.
+  int m_encnum;  ///< Enclosure number.
 };
 
 
@@ -1964,12 +1966,13 @@ static int arcmsr_command_handler(int fd, unsigned long arcmsr_cmd, unsigned cha
 }
 
 
-linux_areca_device::linux_areca_device(smart_interface * intf, const char * dev_name, int disknum)
+linux_areca_device::linux_areca_device(smart_interface * intf, const char * dev_name, int disknum, int encnum)
 : smart_device(intf, dev_name, "areca", "areca"),
   linux_smart_device(O_RDWR | O_EXCL | O_NONBLOCK),
-  m_disknum(disknum)
+  m_disknum(disknum),
+  m_encnum(encnum)
 {
-  set_info().info_name = strprintf("%s [areca_%02d]", dev_name, disknum);
+  set_info().info_name = strprintf("%s [areca_disk#%02d_enc#%02d]", dev_name, disknum, encnum);
 }
 
 // Areca RAID Controller
@@ -2093,7 +2096,8 @@ if (!ata_cmd_is_ok(in,
            return set_err(ENOTSUP, "DATA OUT not supported for this Areca controller type");
        }
 
-       areca_packet[11] = m_disknum - 1;                  // drive number
+       areca_packet[11] = m_disknum - 1;  // disk#
+       areca_packet[19] = m_encnum - 1;   // enc#
 
        // ----- BEGIN TO SETUP CHECKSUM -----
        for ( int loop = 3; loop < areca_packet_len - 1; loop++ )
@@ -2927,12 +2931,6 @@ smart_device * linux_smart_interface::missing_option(const char * opt)
   return 0;
 }
 
-// Return true if STR starts with PREFIX.
-static inline bool str_starts_with(const char * str, const char * prefix)
-{
-  return !strncmp(str, prefix, strlen(prefix));
-}
-
 // Return kernel release as integer ("2.6.31" -> 206031)
 static unsigned get_kernel_release()
 {
@@ -3060,16 +3058,17 @@ smart_device * linux_smart_interface::get_custom_smart_device(const char * name,
 
   // Areca?
   disknum = n1 = n2 = -1;
-  if (sscanf(type, "areca,%n%d%n", &n1, &disknum, &n2) == 1 || n1 == 6) {
-    if (n2 != (int)strlen(type)) {
-      set_err(EINVAL, "Option -d areca,N requires N to be a non-negative integer");
+  int encnum = 1;
+  if (sscanf(type, "areca,%n%d/%d%n", &n1, &disknum, &encnum, &n2) >= 1 || n1 == 6) {
+    if (!(1 <= disknum && disknum <= 128)) {
+      set_err(EINVAL, "Option -d areca,N/E (N=%d) must have 1 <= N <= 128", disknum);
       return 0;
     }
-    if (!(1 <= disknum && disknum <= 24)) {
-      set_err(EINVAL, "Option -d areca,N (N=%d) must have 1 <= N <= 24", disknum);
+    if (!(1 <= encnum && encnum <= 8)) {
+      set_err(EINVAL, "Option -d areca,N/E (E=%d) must have 1 <= E <= 8", encnum);
       return 0;
     }
-    return new linux_areca_device(this, name, disknum);
+    return new linux_areca_device(this, name, disknum, encnum);
   }
 
   // Highpoint ?
@@ -3121,7 +3120,7 @@ smart_device * linux_smart_interface::get_custom_smart_device(const char * name,
 
 std::string linux_smart_interface::get_valid_custom_dev_types_str()
 {
-  return "marvell, areca,N, 3ware,N, hpt,L/M/N, megaraid,N"
+  return "marvell, areca,N/E, 3ware,N, hpt,L/M/N, megaraid,N"
 #ifdef HAVE_LINUX_CCISS_IOCTL_H
                                               ", cciss,N"
 #endif
index 1ab57490b38fc9d5cfb85b1362a17be4b19c811b..ace6d32efeb08ff0cfa43b7b50969e8a18ab5c30 100644 (file)
@@ -4,6 +4,7 @@
  * Home page of code is: http://smartmontools.sourceforge.net
  *
  * Copyright (C) 2004-12 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
  * it under the terms of the GNU General Public License as published by
@@ -85,7 +86,7 @@
 #define SELECT_WIN_32_64(x32, x64) (x64)
 #endif
 
-const char * os_win32_cpp_cvsid = "$Id: os_win32.cpp 3524 2012-03-21 22:19:31Z chrfranke $";
+const char * os_win32_cpp_cvsid = "$Id: os_win32.cpp 3558 2012-06-05 16:42:05Z chrfranke $";
 
 // Disable Win9x/ME specific code if no longer supported by compiler.
 #ifdef _WIN64
@@ -531,6 +532,57 @@ private:
 };
 
 
+/////////////////////////////////////////////////////////////////////////////
+/// Areca RAID support
+
+/* ARECA IO CONTROL CODE*/
+#define ARCMSR_IOCTL_READ_RQBUFFER           0x90002004
+#define ARCMSR_IOCTL_WRITE_WQBUFFER          0x90002008
+#define ARCMSR_IOCTL_CLEAR_RQBUFFER          0x9000200C
+#define ARCMSR_IOCTL_CLEAR_WQBUFFER          0x90002010
+#define ARCMSR_IOCTL_RETURN_CODE_3F          0x90002018
+#define ARECA_SIG_STR              "ARCMSR"
+
+
+// The SRB_IO_CONTROL & SRB_BUFFER structures are used to communicate(to/from) to areca driver
+typedef struct _SRB_IO_CONTROL
+{
+  unsigned int HeaderLength;
+  unsigned char Signature[8];
+  unsigned int Timeout;
+  unsigned int ControlCode;
+  unsigned int ReturnCode;
+  unsigned int Length;
+} sSRB_IO_CONTROL;
+
+typedef struct _SRB_BUFFER
+{
+  sSRB_IO_CONTROL srbioctl;
+  unsigned char   ioctldatabuffer[1032]; // the buffer to put the command data to/from firmware
+} sSRB_BUFFER;
+
+class win_areca_device
+: public /*implements*/ ata_device,
+  public /*extends*/ win_smart_device
+{
+public:
+  win_areca_device(smart_interface * intf, const char * dev_name, HANDLE fh, int disknum, int encnum = 1);
+
+  static int arcmsr_command_handler(HANDLE fh, unsigned long arcmsr_cmd, unsigned char *data, int data_len);
+
+protected:
+  virtual bool open();
+
+  virtual bool ata_pass_through(const ata_cmd_in & in, ata_cmd_out & out);
+
+  bool arcmsr_ata_pass_through(const ata_cmd_in & in, ata_cmd_out & out);
+
+private:
+  int m_disknum; ///< Disk number.
+  int m_encnum;  ///< Enclosure number.
+};
+
+
 //////////////////////////////////////////////////////////////////////
 // Platform specific interfaces
 
@@ -596,6 +648,10 @@ protected:
   virtual scsi_device * get_scsi_device(const char * name, const char * type);
 
   virtual smart_device * autodetect_smart_device(const char * name);
+
+  virtual smart_device * get_custom_smart_device(const char * name, const char * type);
+
+  virtual std::string get_valid_custom_dev_types_str();
 };
 
 
@@ -827,6 +883,62 @@ smart_device * win_smart_interface::autodetect_smart_device(const char * name)
   return 0;
 }
 
+
+smart_device * winnt_smart_interface::get_custom_smart_device(const char * name, const char * type)
+{
+  // Areca?
+  int disknum = -1, n1 = -1, n2 = -1;
+  int encnum = 1;
+  HANDLE fh = INVALID_HANDLE_VALUE;
+  char devpath[32];
+
+  if (sscanf(type, "areca,%n%d/%d%n", &n1, &disknum, &encnum, &n2) >= 1 || n1 == 6) {
+    if (!(1 <= disknum && disknum <= 128)) {
+      set_err(EINVAL, "Option -d areca,N/E (N=%d) must have 1 <= N <= 128", disknum);
+      return 0;
+    }
+    if (!(1 <= encnum && encnum <= 8)) {
+      set_err(EINVAL, "Option -d areca,N/E (E=%d) must have 1 <= E <= 8", encnum);
+      return 0;
+    }
+
+    name = skipdev(name);
+#define ARECA_MAX_CTLR_NUM  16
+    n1 = -1;
+    int ctlrindex = 0;
+    if (sscanf(name, "arcmsr%d%n", &ctlrindex, &n1) >= 1 && n1 == (int)strlen(name)) {
+      /*
+       1. scan from "\\\\.\\scsi[0]:" up to "\\\\.\\scsi[ARECA_MAX_CTLR_NUM]:" and
+       2. map arcmsrX into "\\\\.\\scsiX"
+      */
+      for (int idx = 0; idx < ARECA_MAX_CTLR_NUM; idx++) {
+        memset(devpath, 0, sizeof(devpath));
+        sprintf(devpath, "\\\\.\\scsi%d:", idx);
+        if ( (fh = CreateFile( devpath, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE,
+                               NULL, OPEN_EXISTING, 0, NULL )) != INVALID_HANDLE_VALUE ) {
+          if (win_areca_device::arcmsr_command_handler(fh, ARCMSR_IOCTL_RETURN_CODE_3F, NULL, 0) == 0) {
+            if (ctlrindex-- == 0) {
+              return new win_areca_device(this, devpath, fh, disknum, encnum);
+            }
+          }
+          CloseHandle(fh);
+        }
+      }
+      set_err(ENOENT, "No Areca controller found");
+    }
+    else
+      set_err(EINVAL, "Option -d areca,N/E requires device name /dev/arcmsrX");
+  }
+
+  return 0;
+}
+
+std::string winnt_smart_interface::get_valid_custom_dev_types_str()
+{
+  return "areca,N[/E]";
+}
+
+
 smart_device * winnt_smart_interface::autodetect_smart_device(const char * name)
 {
   smart_device * dev = win_smart_interface::autodetect_smart_device(name);
@@ -1040,6 +1152,9 @@ std::string win_smart_interface::get_app_examples(const char * appname)
          "                (Prints Attributes for physical drive 3 on 3ware 9000 RAID)\n"
          "  smartctl -A /dev/tw_cli/c0/p1\n"
          "            (Prints Attributes for 3ware controller 0, port 1 using tw_cli)\n"
+         "  smartctl --all --device=areca,3/1 /dev/arcmsr0\n"
+         "           (Prints all SMART info for 3rd ATA disk of the 1st enclosure\n"
+         "            on 1st Areca RAID controller)\n"
          "\n"
          "  ATA SMART access methods and ordering may be specified by modifiers\n"
          "  following the device name: /dev/hdX:[saicm], where\n"
@@ -2219,12 +2334,6 @@ static int get_identify_from_device_property(HANDLE hdevice, ata_identify_device
 /////////////////////////////////////////////////////////////////////////////
 // USB ID detection using WMI
 
-// Return true if STR starts with PREFIX.
-static inline bool str_starts_with(const std::string & str, const char * prefix)
-{
-  return !strncmp(str.c_str(), prefix, strlen(prefix));
-}
-
 // Get USB ID for a physical drive number
 static bool get_usb_id(int drive, unsigned short & vendor_id, unsigned short & product_id)
 {
@@ -4175,6 +4284,632 @@ bool win_scsi_device::scsi_pass_through(struct scsi_cmnd_io * iop)
   return true;
 }
 
+// Interface to SPT SCSI devices.  See scsicmds.h and os_linux.c
+static long scsi_pass_through_direct(HANDLE fd, struct scsi_cmnd_io * iop)
+{
+  int report = scsi_debugmode; // TODO
+
+  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(iop->dxferp, (trunc ? 256 : iop->dxfer_len) , 1);
+    }
+    else
+      j += snprintf(&buff[j], (sz > j ? (sz - j) : 0), "]\n");
+    pout("%s", buff);
+  }
+
+  SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER sb;
+  if (iop->cmnd_len > (int)sizeof(sb.spt.Cdb)) {
+    return EINVAL;
+  }
+
+  memset(&sb, 0, sizeof(sb));
+  sb.spt.Length = sizeof(SCSI_PASS_THROUGH_DIRECT);
+  //sb.spt.PathId = 0;
+  sb.spt.TargetId = 127;
+  //sb.spt.Lun = 0;
+  sb.spt.CdbLength = iop->cmnd_len;
+  memcpy(sb.spt.Cdb, iop->cmnd, iop->cmnd_len);
+  sb.spt.SenseInfoLength = sizeof(sb.ucSenseBuf);
+  sb.spt.SenseInfoOffset =
+    offsetof(SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER, ucSenseBuf);
+  sb.spt.TimeOutValue = (iop->timeout ? iop->timeout : 60);
+
+  bool direct = true;
+  switch (iop->dxfer_dir) {
+    case DXFER_NONE:
+      sb.spt.DataIn = SCSI_IOCTL_DATA_UNSPECIFIED;
+      break;
+    case DXFER_FROM_DEVICE:
+      sb.spt.DataIn = SCSI_IOCTL_DATA_IN;
+      sb.spt.DataTransferLength = iop->dxfer_len;
+      sb.spt.DataBuffer = iop->dxferp;
+      // IOCTL_SCSI_PASS_THROUGH_DIRECT does not support single byte
+      // transfers (needed for SMART STATUS check of JMicron USB bridges)
+      if (sb.spt.DataTransferLength == 1)
+        direct = false;
+      break;
+    case DXFER_TO_DEVICE:
+      sb.spt.DataIn = SCSI_IOCTL_DATA_OUT;
+      sb.spt.DataTransferLength = iop->dxfer_len;
+      sb.spt.DataBuffer = iop->dxferp;
+      break;
+    default:
+      return EINVAL;
+  }
+
+  long err = 0;
+  if (direct) {
+    DWORD num_out;
+    if (!DeviceIoControl(fd, IOCTL_SCSI_PASS_THROUGH_DIRECT,
+           &sb, sizeof(sb), &sb, sizeof(sb), &num_out, 0))
+      err = GetLastError();
+  }
+  else
+    err = scsi_pass_through_indirect(fd, &sb);
+
+  if (err)
+  {
+    return err;
+  }
+
+  iop->scsi_status = sb.spt.ScsiStatus;
+  if (SCSI_STATUS_CHECK_CONDITION & iop->scsi_status) {
+    int slen = sb.ucSenseBuf[7] + 8;
+
+    if (slen > (int)sizeof(sb.ucSenseBuf))
+      slen = sizeof(sb.ucSenseBuf);
+    if (slen > (int)iop->max_sense_len)
+      slen = iop->max_sense_len;
+    memcpy(iop->sensep, sb.ucSenseBuf, slen);
+    iop->resp_sense_len = slen;
+    if (report) {
+      if (report > 1) {
+        pout("  >>> Sense buffer, len=%d:\n", slen);
+        dStrHex(iop->sensep, slen , 1);
+      }
+      if ((iop->sensep[0] & 0x7f) > 0x71)
+        pout("  status=%x: [desc] sense_key=%x asc=%x ascq=%x\n",
+             iop->scsi_status, iop->sensep[1] & 0xf,
+             iop->sensep[2], iop->sensep[3]);
+      else
+        pout("  status=%x: sense_key=%x asc=%x ascq=%x\n",
+             iop->scsi_status, iop->sensep[2] & 0xf,
+             iop->sensep[12], iop->sensep[13]);
+    }
+  } else
+    iop->resp_sense_len = 0;
+
+  if ((iop->dxfer_len > 0) && (sb.spt.DataTransferLength > 0))
+    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,
+        (trunc ? " [only first 256 bytes shown]" : ""));
+        dStrHex(iop->dxferp, (trunc ? 256 : iop->dxfer_len) , 1);
+  }
+
+  return 0;
+}
+
+
+#if 0 // For debugging areca code
+
+static void dumpdata(unsigned char *block, int len)
+{
+  int ln = (len / 16) + 1;   // total line#
+  unsigned char c;
+  int pos = 0;
+
+  printf(" Address = %p, Length = (0x%x)%d\n", block, len, len);
+  printf("      0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F      ASCII      \n");
+  printf("=====================================================================\n");
+
+  for ( int l = 0; l < ln && len; l++ )
+  {
+    // printf the line# and the HEX data
+    // if a line data length < 16 then append the space to the tail of line to reach 16 chars
+    printf("%02X | ", l);
+    for ( pos = 0; pos < 16 && len; pos++, len-- )
+    {
+      c = block[l*16+pos];
+      printf("%02X ", c);
+    }
+
+    if ( pos < 16 )
+    {
+      for ( int loop = pos; loop < 16; loop++ )
+      {
+        printf("   ");
+      }
+    }
+
+    // print ASCII char
+    for ( int loop = 0; loop < pos; loop++ )
+    {
+      c = block[l*16+loop];
+      if ( c >= 0x20 && c <= 0x7F )
+      {
+        printf("%c", c);
+      }
+      else
+      {
+        printf(".");
+      }
+    }
+    printf("\n");
+  }
+  printf("=====================================================================\n");
+}
+
+#endif
+
+// PURPOSE
+//   This is an interface routine meant to isolate the OS dependent
+//   parts of the code, and to provide a debugging interface.  Each
+//   different port and OS needs to provide it's own interface.  This
+//   is the Windows interface to the Areca "arcmsr" driver.  It allows ATA
+//   commands to be passed through the SCSI driver.
+// DETAILED DESCRIPTION OF ARGUMENTS
+//   fd: is the file descriptor provided by open()
+//   disknum is the disk number (0 to 127) in the RAID array
+//   command: defines the different operations.
+//   select: additional input data if needed (which log, which type of
+//           self-test).
+//   data:   location to write output data, if needed (512 bytes).
+//   Note: not all commands use all arguments.
+// RETURN VALUES
+//  -1 if the command failed
+//   0 if the command succeeded,
+//   STATUS_CHECK routine:
+//  -1 if the command failed
+//   0 if the command succeeded and disk SMART status is "OK"
+//   1 if the command succeeded and disk SMART status is "FAILING"
+int win_areca_device::arcmsr_command_handler(HANDLE fd, unsigned long arcmsr_cmd, unsigned char *data, int data_len)
+{
+  int ioctlreturn = 0;
+  sSRB_BUFFER sBuf;
+  struct scsi_cmnd_io io_hdr;
+  int dir = DXFER_TO_DEVICE;
+
+  UINT8 cdb[10];
+  UINT8 sense[32];
+
+  unsigned char *areca_return_packet;
+  int total = 0;
+  int expected = -1;
+  unsigned char return_buff[2048];
+  unsigned char *ptr = &return_buff[0];
+  memset(return_buff, 0, sizeof(return_buff));
+
+  memset((unsigned char *)&sBuf, 0, sizeof(sBuf));
+  memset(&io_hdr, 0, sizeof(io_hdr));
+  memset(cdb, 0, sizeof(cdb));
+  memset(sense, 0, sizeof(sense));
+
+
+  sBuf.srbioctl.HeaderLength = sizeof(sSRB_IO_CONTROL);
+  memcpy(sBuf.srbioctl.Signature, ARECA_SIG_STR, strlen(ARECA_SIG_STR));
+  sBuf.srbioctl.Timeout = 10000;
+  sBuf.srbioctl.ControlCode = arcmsr_cmd;
+
+  switch ( arcmsr_cmd )
+  {
+  // command for writing data to driver
+  case ARCMSR_IOCTL_WRITE_WQBUFFER:
+    if ( data && data_len )
+    {
+      sBuf.srbioctl.Length = data_len;
+      memcpy((unsigned char *)sBuf.ioctldatabuffer, (unsigned char *)data, data_len);
+    }
+    // commands for clearing related buffer of driver
+  case ARCMSR_IOCTL_CLEAR_RQBUFFER:
+  case ARCMSR_IOCTL_CLEAR_WQBUFFER:
+    cdb[0] = 0x3B; //SCSI_WRITE_BUF command;
+    break;
+  // command for reading data from driver
+  case ARCMSR_IOCTL_READ_RQBUFFER:
+  // command for identifying driver
+  case ARCMSR_IOCTL_RETURN_CODE_3F:
+    cdb[0] = 0x3C; //SCSI_READ_BUF command;
+    dir = DXFER_FROM_DEVICE;
+    break;
+  default:
+    // unknown arcmsr commands
+    return -1;
+  }
+
+  cdb[1] = 0x01;
+  cdb[2] = 0xf0;
+
+  io_hdr.dxfer_dir = dir;
+  io_hdr.dxfer_len = sizeof(sBuf);
+  io_hdr.dxferp = (unsigned char *)&sBuf;
+  io_hdr.cmnd = cdb;
+  io_hdr.cmnd_len = sizeof(cdb);
+  io_hdr.sensep = sense;
+  io_hdr.max_sense_len = sizeof(sense);
+  io_hdr.timeout = SCSI_TIMEOUT_DEFAULT;
+
+  while ( 1 )
+  {
+    ioctlreturn = scsi_pass_through_direct(fd, &io_hdr);
+    if ( ioctlreturn || io_hdr.scsi_status )
+    {
+      // errors found
+      break;
+    }
+
+    if ( arcmsr_cmd != ARCMSR_IOCTL_READ_RQBUFFER )
+    {
+      // if succeeded, just returns the length of outgoing data
+      return data_len;
+    }
+
+    if ( sBuf.srbioctl.Length )
+    {
+      //dumpdata(&sBuf.ioctldatabuffer[0], sBuf.srbioctl.Length);
+      memcpy(ptr, &sBuf.ioctldatabuffer[0], sBuf.srbioctl.Length);
+      ptr += sBuf.srbioctl.Length;
+      total += sBuf.srbioctl.Length;
+      // the returned bytes enough to compute payload length ?
+      if ( expected < 0 && total >= 5 )
+      {
+        areca_return_packet = (unsigned char *)&return_buff[0];
+        if ( areca_return_packet[0] == 0x5E &&
+           areca_return_packet[1] == 0x01 &&
+           areca_return_packet[2] == 0x61 )
+        {
+          // valid header, let's compute the returned payload length,
+          // we expected the total length is
+          // payload + 3 bytes header + 2 bytes length + 1 byte checksum
+          expected = areca_return_packet[4] * 256 + areca_return_packet[3] + 6;
+        }
+      }
+
+      if ( total >= 7 && total >= expected )
+      {
+        //printf("total bytes received = %d, expected length = %d\n", total, expected);
+
+        // ------ Okay! we received enough --------
+        break;
+      }
+    }
+  }
+
+  // Deal with the different error cases
+  if ( arcmsr_cmd == ARCMSR_IOCTL_RETURN_CODE_3F )
+  {
+    // Silence the ARCMSR_IOCTL_RETURN_CODE_3F's error, no pout(...)
+    return -4;
+  }
+
+  if ( ioctlreturn )
+  {
+    pout("do_scsi_cmnd_io with write buffer failed code = %x\n", ioctlreturn);
+    return -2;
+  }
+
+  if ( io_hdr.scsi_status )
+  {
+    pout("io_hdr.scsi_status with write buffer failed code = %x\n", io_hdr.scsi_status);
+    return -3;
+  }
+
+  if ( data )
+  {
+    memcpy(data, return_buff, total);
+  }
+
+  return total;
+}
+
+
+win_areca_device::win_areca_device(smart_interface * intf, const char * dev_name, HANDLE fh, int disknum, int encnum)
+: smart_device(intf, dev_name, "areca", "areca"),
+  m_disknum(disknum),
+  m_encnum(encnum)
+{
+  set_fh(fh);
+  set_info().info_name = strprintf("%s [areca_disk#%02d_enc#%02d]", dev_name, disknum, encnum);
+}
+
+bool win_areca_device::open()
+{
+  HANDLE hFh;
+
+  if( is_open() )
+  {
+    return true;
+  }
+
+  hFh = CreateFile( get_dev_name(),
+                    GENERIC_READ|GENERIC_WRITE,
+                    FILE_SHARE_READ|FILE_SHARE_WRITE,
+                    NULL,
+                    OPEN_EXISTING,
+                    0,
+                    NULL );
+  if(hFh == INVALID_HANDLE_VALUE)
+  {
+    return false;
+  }
+
+  set_fh(hFh);
+  return true;
+}
+
+// Areca RAID Controller
+bool win_areca_device::arcmsr_ata_pass_through(const ata_cmd_in & in, ata_cmd_out & out)
+{
+  // ATA input registers
+  typedef struct _ATA_INPUT_REGISTERS
+  {
+    unsigned char features;
+    unsigned char sector_count;
+    unsigned char sector_number;
+    unsigned char cylinder_low;
+    unsigned char cylinder_high;
+    unsigned char device_head;
+    unsigned char command;
+    unsigned char reserved[8];
+    unsigned char data[512]; // [in/out] buffer for outgoing/incoming data
+  } sATA_INPUT_REGISTERS;
+
+  // ATA output registers
+  // Note: The output registers is re-sorted for areca internal use only
+  typedef struct _ATA_OUTPUT_REGISTERS
+  {
+    unsigned char error;
+    unsigned char status;
+    unsigned char sector_count;
+    unsigned char sector_number;
+    unsigned char cylinder_low;
+    unsigned char cylinder_high;
+  } sATA_OUTPUT_REGISTERS;
+
+  // Areca packet format for outgoing:
+  // B[0~2] : 3 bytes header, fixed value 0x5E, 0x01, 0x61
+  // B[3~4] : 2 bytes command length + variant data length, little endian
+  // B[5]   : 1 bytes areca defined command code, ATA passthrough command code is 0x1c
+  // B[6~last-1] : variant bytes payload data
+  // B[last] : 1 byte checksum, simply sum(B[3] ~ B[last -1])
+  //
+  //
+  //   header 3 bytes  length 2 bytes   cmd 1 byte    payload data x bytes  cs 1 byte
+  // +--------------------------------------------------------------------------------+
+  // + 0x5E 0x01 0x61 |   0x00 0x00   |     0x1c   | .................... |   0x00    |
+  // +--------------------------------------------------------------------------------+
+  //
+
+  //Areca packet format for incoming:
+  // B[0~2] : 3 bytes header, fixed value 0x5E, 0x01, 0x61
+  // B[3~4] : 2 bytes payload length, little endian
+  // B[5~last-1] : variant bytes returned payload data
+  // B[last] : 1 byte checksum, simply sum(B[3] ~ B[last -1])
+  //
+  //
+  //   header 3 bytes  length 2 bytes   payload data x bytes  cs 1 byte
+  // +-------------------------------------------------------------------+
+  // + 0x5E 0x01 0x61 |   0x00 0x00   | .................... |   0x00    |
+  // +-------------------------------------------------------------------+
+  unsigned char    areca_packet[640];
+  int areca_packet_len = sizeof(areca_packet);
+  unsigned char cs = 0;
+
+  sATA_INPUT_REGISTERS *ata_cmd;
+
+  // For debugging
+#if 0
+  memset(sInq, 0, sizeof(sInq));
+  scsiStdInquiry(fd, (unsigned char *)sInq, (int)sizeof(sInq));
+  dumpdata((unsigned char *)sInq, sizeof(sInq));
+#endif
+  memset(areca_packet, 0, areca_packet_len);
+
+  // ----- BEGIN TO SETUP HEADERS -------
+  areca_packet[0] = 0x5E;
+  areca_packet[1] = 0x01;
+  areca_packet[2] = 0x61;
+  areca_packet[3] = (unsigned char)((areca_packet_len - 6) & 0xff);
+  areca_packet[4] = (unsigned char)(((areca_packet_len - 6) >> 8) & 0xff);
+  areca_packet[5] = 0x1c;  // areca defined code for ATA passthrough command
+
+  // ----- BEGIN TO SETUP PAYLOAD DATA -----
+  memcpy(&areca_packet[7], "SmrT", 4);  // areca defined password
+  ata_cmd = (sATA_INPUT_REGISTERS *)&areca_packet[12];
+
+  // Set registers
+  {
+    const ata_in_regs & r = in.in_regs;
+    ata_cmd->features      = r.features;
+    ata_cmd->sector_count  = r.sector_count;
+    ata_cmd->sector_number = r.lba_low;
+    ata_cmd->cylinder_low  = r.lba_mid;
+    ata_cmd->cylinder_high = r.lba_high;
+    ata_cmd->device_head   = r.device;
+    ata_cmd->command       = r.command;
+  }
+  bool readdata = false;
+  if (in.direction == ata_cmd_in::data_in) {
+      readdata = true;
+      // the command will read data
+      areca_packet[6] = 0x13;
+  }
+  else if ( in.direction == ata_cmd_in::no_data )
+  {
+    // the commands will return no data
+    areca_packet[6] = 0x15;
+  }
+  else if (in.direction == ata_cmd_in::data_out)
+  {
+    // the commands will write data
+    memcpy(ata_cmd->data, in.buffer, in.size);
+    areca_packet[6] = 0x14;
+  }
+  else {
+      // COMMAND NOT SUPPORTED VIA ARECA IOCTL INTERFACE
+      return set_err(ENOSYS);
+  }
+
+  areca_packet[11] = m_disknum - 1;  // disk#
+  areca_packet[19] = m_encnum - 1;   // enc#
+
+  // ----- BEGIN TO SETUP CHECKSUM -----
+  for ( int loop = 3; loop < areca_packet_len - 1; loop++ )
+  {
+    cs += areca_packet[loop];
+  }
+  areca_packet[areca_packet_len-1] = cs;
+
+  // ----- BEGIN TO SEND TO ARECA DRIVER ------
+  int expected = 0;
+  unsigned char return_buff[2048];
+  memset(return_buff, 0, sizeof(return_buff));
+
+  expected = arcmsr_command_handler(get_fh(), ARCMSR_IOCTL_CLEAR_RQBUFFER, NULL, 0);
+  if (expected==-3) {
+      return set_err(EIO);
+  }
+
+  expected = arcmsr_command_handler(get_fh(), ARCMSR_IOCTL_CLEAR_WQBUFFER, NULL, 0);
+  expected = arcmsr_command_handler(get_fh(), ARCMSR_IOCTL_WRITE_WQBUFFER, areca_packet, areca_packet_len);
+  if ( expected > 0 )
+  {
+    expected = arcmsr_command_handler(get_fh(), ARCMSR_IOCTL_READ_RQBUFFER, return_buff, sizeof(return_buff));
+  }
+  if ( expected < 0 )
+  {
+    return set_err(EIO);
+  }
+
+  // ----- VERIFY THE CHECKSUM -----
+  cs = 0;
+  for ( int loop = 3; loop < expected - 1; loop++ )
+  {
+    cs += return_buff[loop];
+  }
+
+  if ( return_buff[expected - 1] != cs )
+  {
+    return set_err(EIO);
+  }
+
+  sATA_OUTPUT_REGISTERS *ata_out = (sATA_OUTPUT_REGISTERS *)&return_buff[5] ;
+  if ( ata_out->status )
+  {
+    if ( in.in_regs.command == ATA_IDENTIFY_DEVICE
+     && !nonempty((unsigned char *)in.buffer, in.size))
+     {
+        return set_err(ENODEV, "No drive on port %d", m_disknum);
+     }
+  }
+
+  // returns with data
+  if (readdata)
+  {
+    memcpy(in.buffer, &return_buff[7], in.size);
+  }
+
+  // Return register values
+  {
+    ata_out_regs & r = out.out_regs;
+    r.error          = ata_out->error;
+    r.sector_count   = ata_out->sector_count;
+    r.lba_low        = ata_out->sector_number;
+    r.lba_mid        = ata_out->cylinder_low;
+    r.lba_high       = ata_out->cylinder_high;
+    r.status         = ata_out->status;
+  }
+  return true;
+}
+
+
+bool win_areca_device::ata_pass_through(const ata_cmd_in & in, ata_cmd_out & out)
+{
+#define    SYNCOBJNAME "Global\\SynIoctlMutex"
+  int ctlrnum = -1;
+  char mutexstr[64];
+  SECURITY_ATTRIBUTES sa;
+  PSECURITY_DESCRIPTOR pSD;
+  HANDLE hmutex;
+
+  if (!ata_cmd_is_ok(in,
+    true, // data_out_support
+    false, // TODO: multi_sector_support
+    true) // ata_48bit_support
+  )
+    return false;
+
+  // Support 48-bit commands with zero high bytes
+  if (in.in_regs.is_real_48bit_cmd())
+    return set_err(ENOSYS, "48-bit ATA commands not fully supported by Areca");
+
+  if (sscanf(get_dev_name(), "\\\\.\\scsi%d:", &ctlrnum) < 1)
+    return set_err(EINVAL, "unable to parse device name");
+
+  memset(mutexstr, 0, sizeof(mutexstr));
+  sprintf(mutexstr, "%s%d",SYNCOBJNAME, ctlrnum);
+  pSD = (PSECURITY_DESCRIPTOR)LocalAlloc(LPTR, SECURITY_DESCRIPTOR_MIN_LENGTH);
+  if ( !InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION) )
+  {
+    LocalFree((HLOCAL)pSD);
+    return set_err(EIO, "InitializeSecurityDescriptor failed");
+  }
+
+  if ( !SetSecurityDescriptorDacl(pSD, TRUE, (PACL)NULL, FALSE) )
+  {
+    LocalFree((HLOCAL)pSD);
+    return set_err(EIO, "SetSecurityDescriptor failed");
+  }
+
+  sa.nLength = sizeof(SECURITY_ATTRIBUTES);
+  sa.lpSecurityDescriptor = pSD;
+  sa.bInheritHandle = TRUE;
+  hmutex = CreateMutex(&sa, FALSE, mutexstr);
+  if ( hmutex == NULL )
+  {
+    LocalFree((HLOCAL)pSD);
+    return set_err(EIO, "CreateMutex failed");
+  }
+
+  // atomic access to driver
+  WaitForSingleObject(hmutex, INFINITE);
+  bool ok = arcmsr_ata_pass_through(in,out);
+  ReleaseMutex(hmutex);
+
+  if(hmutex)
+  {
+    CloseHandle(hmutex);
+  }
+
+  if ( (HLOCAL)pSD )
+  {
+    LocalFree((HLOCAL)pSD);
+  }
+
+  return ok;
+}
+
 
 //////////////////////////////////////////////////////////////////////////////////////////////////
 
index 101c04f4f106e726d3b81795aa5a689ca74a8899..d918ac6fd7726a05971fcf5ff40123fbeb8618df 100644 (file)
@@ -3,7 +3,7 @@
 ;
 ; Home page of code is: http://smartmontools.sourceforge.net
 ;
-; Copyright (C) 2006-11 Christian Franke <smartmontools-support@lists.sourceforge.net>
+; Copyright (C) 2006-12 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
 ; 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 3457 2011-10-20 16:36:47Z chrfranke $
+; $Id: installer.nsi 3545 2012-05-25 21:19:03Z chrfranke $
 ;
 
 
 ;--------------------------------------------------------------------
 ; Command line arguments:
-; makensis -DINPDIR=<input-dir> -DOUTFILE=<output-file> -DVERSTR=<version-string> installer.nsi
+; makensis -DINPDIR=<input-dir> -DINPDIR64=<input-dir-64-bit> \
+;   -DOUTFILE=<output-file> -DVERSTR=<version-string> installer.nsi
 
 !ifndef INPDIR
   !define INPDIR "."
@@ -40,11 +41,17 @@ SetCompressor /solid lzma
 XPStyle on
 InstallColors /windows
 
-InstallDir "$PROGRAMFILES\smartmontools"
-InstallDirRegKey HKLM "Software\smartmontools" "Install_Dir"
+; Set in .onInit
+;InstallDir "$PROGRAMFILES\smartmontools"
+;InstallDirRegKey HKLM "Software\smartmontools" "Install_Dir"
 
 Var EDITOR
-Var UBCDDIR
+
+!ifdef INPDIR64
+  Var X64
+  Var INSTDIR32
+  Var INSTDIR64
+!endif
 
 LicenseData "${INPDIR}\doc\COPYING.txt"
 
@@ -61,12 +68,11 @@ RequestExecutionLevel admin
 
 Page license
 Page components
-Page directory SkipProgPath "" ""
-PageEx directory
-  PageCallbacks SkipUBCDPath "" ""
-  DirText "Setup will install the UBCD4Win plugin in the following folder."
-  DirVar $UBCDDIR
-PageExEnd
+!ifdef INPDIR64
+  Page directory CheckX64
+!else
+  Page directory
+!endif
 Page instfiles
 
 UninstPage uninstConfirm
@@ -75,20 +81,41 @@ UninstPage instfiles
 InstType "Full"
 InstType "Extract files only"
 InstType "Drive menu"
-InstType "UBCD4Win plugin"
 
 
 ;--------------------------------------------------------------------
 ; Sections
 
+!ifdef INPDIR64
+  Section "64-bit version (EXPERIMENTAL)" X64_SECTION
+    ; Handled in Function CheckX64
+  SectionEnd
+!endif
+
 SectionGroup "!Program files"
 
+  !macro FileExe path option
+    !ifdef INPDIR64
+      ; Use dummy SetOutPath to control archive location of executables
+      StrCmp $X64 "" +5
+        Goto +2
+          SetOutPath "$INSTDIR\bin64"
+        File ${option} '${INPDIR64}\${path}'
+      GoTo +4
+        Goto +2
+          SetOutPath "$INSTDIR\bin"
+        File ${option} '${INPDIR}\${path}'
+    !else
+      File ${option} '${INPDIR}\${path}'
+    !endif
+  !macroend
+
   Section "smartctl" SMARTCTL_SECTION
 
     SectionIn 1 2
 
     SetOutPath "$INSTDIR\bin"
-    File "${INPDIR}\bin\smartctl.exe"
+    !insertmacro FileExe "bin\smartctl.exe" ""
 
   SectionEnd
 
@@ -105,14 +132,15 @@ SectionGroup "!Program files"
       StrCmp $0 "" nosrv
         ExecWait "net stop smartd" $1
   nosrv:
-    File "${INPDIR}\bin\smartd.exe"
+    !insertmacro FileExe "bin\smartd.exe" ""
 
     IfFileExists "$INSTDIR\bin\smartd.conf" 0 +2
       MessageBox MB_YESNO|MB_ICONQUESTION|MB_DEFBUTTON2 "Replace existing configuration file$\n$INSTDIR\bin\smartd.conf ?" IDYES 0 IDNO +2
         File "${INPDIR}\doc\smartd.conf"
 
-    IfFileExists "$WINDIR\system32\cmd.exe" 0 +2
-      File /nonfatal "${INPDIR}\bin\syslogevt.exe"
+    IfFileExists "$WINDIR\system32\cmd.exe" 0 nosysl
+      !insertmacro FileExe "bin\syslogevt.exe" /nonfatal
+    nosysl:
 
     ; Restart service ?
     StrCmp $1 "0" 0 +3
@@ -126,7 +154,7 @@ SectionGroup "!Program files"
     SectionIn 1 2
 
     SetOutPath "$INSTDIR\bin"
-    File "${INPDIR}\bin\smartctl-nc.exe"
+    !insertmacro FileExe "bin\smartctl-nc.exe" ""
 
   SectionEnd
 
@@ -155,7 +183,14 @@ Section "!Documentation" DOC_SECTION
   File "${INPDIR}\doc\README.txt"
   File "${INPDIR}\doc\TODO.txt"
   File "${INPDIR}\doc\WARNINGS.txt"
-  File "${INPDIR}\doc\checksums.txt"
+!ifdef INPDIR64
+  StrCmp $X64 "" +3
+    File "${INPDIR64}\doc\checksums64.txt"
+  GoTo +2
+    File "${INPDIR}\doc\checksums32.txt"
+!else
+  File "${INPDIR}\doc\checksums??.txt"
+!endif
   File "${INPDIR}\doc\smartctl.8.html"
   File "${INPDIR}\doc\smartctl.8.txt"
   File "${INPDIR}\doc\smartd.8.html"
@@ -169,7 +204,7 @@ SectionEnd
 Section "Uninstaller" UNINST_SECTION
 
   SectionIn 1
-  AddSize 35
+  AddSize 40
 
   CreateDirectory "$INSTDIR"
 
@@ -209,10 +244,11 @@ Section "Start Menu Shortcuts" MENU_SECTION
 
   ; runcmdu
   IfFileExists "$INSTDIR\bin\smartctl.exe" 0 +2
-  IfFileExists "$INSTDIR\bin\smartd.exe" 0 +4
+  IfFileExists "$INSTDIR\bin\smartd.exe" 0 noruncmd
     SetOutPath "$INSTDIR\bin"
-    File "${INPDIR}\bin\runcmdu.exe"
+    !insertmacro FileExe "bin\runcmdu.exe" ""
     File "${INPDIR}\bin\runcmdu.exe.manifest"
+  noruncmd:
 
   ; smartctl
   IfFileExists "$INSTDIR\bin\smartctl.exe" 0 noctl
@@ -352,49 +388,6 @@ SectionGroup "Add smartctl to drive menu"
 
 SectionGroupEnd
 
-Section "UBCD4Win Plugin" UBCD_SECTION
-
-  SectionIn 4
-
-  SetOutPath "$UBCDDIR"
-  DetailPrint "Create file: smartmontools.inf"
-  FileOpen $0 "$UBCDDIR\smartmontools.inf" "w"
-  FileWrite $0 '; smartmontools.inf$\r$\n; PE Builder v3 plug-in INF file$\r$\n'
-  FileWrite $0 '; Created by smartmontools installer$\r$\n'
-  FileWrite $0 '; http://smartmontools.sourceforge.net/$\r$\n$\r$\n'
-  FileWrite $0 '[Version]$\r$\nSignature= "$$Windows NT$$"$\r$\n$\r$\n'
-  FileWrite $0 '[PEBuilder]$\r$\nName="Disk -Diagnostic: smartmontools"$\r$\n'
-  FileWrite $0 'Enable=1$\r$\nHelp="files\smartctl.8.html"$\r$\n$\r$\n'
-  FileWrite $0 '[WinntDirectories]$\r$\na=Programs\smartmontools,2$\r$\n$\r$\n'
-  FileWrite $0 '[SourceDisksFolders]$\r$\nfiles=a,,1$\r$\n$\r$\n'
-  FileWrite $0 '[Append]$\r$\nnu2menu.xml, smartmontools_nu2menu.xml$\r$\n'
-  FileClose $0
-
-  DetailPrint "Create file: smartmontools_nu2menu.xml"
-  FileOpen $0 "$UBCDDIR\smartmontools_nu2menu.xml" "w"
-  FileWrite $0 '<!-- Nu2Menu entry for smartmontools -->$\r$\n<NU2MENU>$\r$\n'
-  FileWrite $0 '$\t<MENU ID="Programs">$\r$\n$\t$\t<MITEM TYPE="POPUP" MENUID="Disk Tools">'
-  FileWrite $0 'Disk Tools</MITEM>$\r$\n$\t</MENU>$\r$\n$\t<MENU ID="Disk Tools">$\r$\n'
-  FileWrite $0 '$\t$\t<MITEM TYPE="POPUP" MENUID="Diagnostic">Diagnostic</MITEM>$\r$\n$\t</MENU>'
-  FileWrite $0 '$\r$\n$\t<MENU ID="Diagnostic">$\r$\n$\t$\t<MITEM TYPE="ITEM" DISABLED="'
-  FileWrite $0 '@Not(@FileExists(@GetProgramDrive()\Programs\smartmontools\smartctl.exe))" '
-  FileWrite $0 'CMD="RUN" FUNC="cmd.exe /k cd /d @GetProgramDrive()\Programs\smartmontools&'
-  FileWrite $0 'set PATH=@GetProgramDrive()\Programs\smartmontools;%PATH%  ">'
-  FileWrite $0 'smartctl</MITEM>$\r$\n$\t</MENU>$\r$\n</NU2MENU>$\r$\n'
-  FileClose $0
-  
-  SetOutPath "$UBCDDIR\files"
-  File "${INPDIR}\bin\smartctl.exe"
-  File "${INPDIR}\bin\smartd.exe"
-  File "${INPDIR}\doc\smartctl.8.html"
-  File "${INPDIR}\doc\smartctl.8.txt"
-  File "${INPDIR}\doc\smartd.8.html"
-  File "${INPDIR}\doc\smartd.8.txt"
-  File "${INPDIR}\doc\smartd.conf"
-
-SectionEnd
-
-
 ;--------------------------------------------------------------------
 
 Section "Uninstall"
@@ -457,7 +450,7 @@ Section "Uninstall"
   Delete "$INSTDIR\doc\README.txt"
   Delete "$INSTDIR\doc\TODO.txt"
   Delete "$INSTDIR\doc\WARNINGS.txt"
-  Delete "$INSTDIR\doc\checksums.txt"
+  Delete "$INSTDIR\doc\checksums*.txt"
   Delete "$INSTDIR\doc\smartctl.8.html"
   Delete "$INSTDIR\doc\smartctl.8.txt"
   Delete "$INSTDIR\doc\smartd.8.html"
@@ -506,19 +499,37 @@ SectionEnd
 ;--------------------------------------------------------------------
 ; Functions
 
+!macro AdjustSectionSize section
+  SectionGetSize ${section} $0
+  IntOp $0 $0 / 2
+  SectionSetSize ${section} $0
+!macroend
+
 Function .onInit
 
+  ; Set default install directories
+  StrCmp $INSTDIR "" 0 endinst ; /D=PATH option specified ?
+  ReadRegStr $INSTDIR HKLM "Software\smartmontools" "Install_Dir"
+  StrCmp $INSTDIR "" 0 endinst ; Already installed ?
+    StrCpy $INSTDIR "$PROGRAMFILES\smartmontools"
+!ifdef INPDIR64
+    StrCpy $INSTDIR32 $INSTDIR
+    StrCpy $INSTDIR64 "$PROGRAMFILES64\smartmontools"
+!endif
+  endinst:
+
+!ifdef INPDIR64
+  ; Sizes of binary sections include 32-bit and 64-bit executables
+  !insertmacro AdjustSectionSize ${SMARTCTL_SECTION}
+  !insertmacro AdjustSectionSize ${SMARTD_SECTION}
+  !insertmacro AdjustSectionSize ${SMARTCTL_NC_SECTION}
+!endif
+
   ; Use Notepad++ if installed
   StrCpy $EDITOR "$PROGRAMFILES\Notepad++\notepad++.exe"
   IfFileExists "$EDITOR" +2 0
     StrCpy $EDITOR "notepad.exe"
 
-  ; Get UBCD4Win install location
-  ReadRegStr $0 HKLM "Software\UBCD4Win" "InstallPath"
-  StrCmp $0 "" 0 +2
-    StrCpy $0 "C:\UBCD4Win"
-  StrCpy $UBCDDIR "$0\plugin\Disk\Diagnostic\smartmontools"
-
   ; Hide "Add install dir to PATH" on 9x/ME
   IfFileExists "$WINDIR\system32\cmd.exe" +2 0
     SectionSetText ${PATH_SECTION} ""
@@ -526,6 +537,27 @@ Function .onInit
   Call ParseCmdLine
 FunctionEnd
 
+; Check x64 section and update INSTDIR accordingly
+
+!ifdef INPDIR64
+Function CheckX64
+  SectionGetFlags ${X64_SECTION} $0
+  IntOp $0 $0 & ${SF_SELECTED}
+  IntCmp $0 ${SF_SELECTED} x64
+    StrCpy $X64 ""
+    StrCmp $INSTDIR32 "" +3
+      StrCpy $INSTDIR $INSTDIR32
+      StrCpy $INSTDIR32 ""
+    Goto done
+  x64:
+    StrCpy $X64 "t"
+    StrCmp $INSTDIR64 "" +3
+      StrCpy $INSTDIR $INSTDIR64
+      StrCpy $INSTDIR64 ""
+  done:
+FunctionEnd
+!endif
+
 ; Command line parsing
 !macro CheckCmdLineOption name section
   StrCpy $allopts "$allopts,${name}"
@@ -554,6 +586,12 @@ Function ParseCmdLine
   Var /global nomatch
   StrCpy $nomatch "t"
   ; turn sections on or off
+!ifdef INPDIR64
+  !insertmacro CheckCmdLineOption "x64" ${X64_SECTION}
+  Call CheckX64
+  StrCmp $opts "x64" 0 +2
+    Return ; leave sections unchanged if only "x64" is specified
+!endif
   !insertmacro CheckCmdLineOption "smartctl" ${SMARTCTL_SECTION}
   !insertmacro CheckCmdLineOption "smartd" ${SMARTD_SECTION}
   !insertmacro CheckCmdLineOption "smartctlnc" ${SMARTCTL_NC_SECTION}
@@ -569,7 +607,6 @@ Function ParseCmdLine
   !insertmacro CheckCmdLineOption "drive3" ${DRIVE_3_SECTION}
   !insertmacro CheckCmdLineOption "drive4" ${DRIVE_4_SECTION}
   !insertmacro CheckCmdLineOption "drive5" ${DRIVE_5_SECTION}
-  !insertmacro CheckCmdLineOption "ubcd" ${UBCD_SECTION}
   StrCmp $opts "-" done
   StrCmp $nomatch "" done
     StrCpy $0 "$allopts,-" "" 1
@@ -578,45 +615,12 @@ Function ParseCmdLine
 done:
 FunctionEnd
 
-; Directory page callbacks
-
-!macro CheckSection section
-  SectionGetFlags ${section} $0
-  IntOp $0 $0 & 1
-  IntCmp $0 1 done
-!macroend
-
-Function SkipProgPath
-  !insertmacro CheckSection ${SMARTCTL_SECTION}
-  !insertmacro CheckSection ${SMARTCTL_NC_SECTION}
-  !insertmacro CheckSection ${SMARTD_SECTION}
-  !insertmacro CheckSection ${DRIVEDB_SECTION}
-  !insertmacro CheckSection ${DOC_SECTION}
-  !insertmacro CheckSection ${MENU_SECTION}
-  !insertmacro CheckSection ${PATH_SECTION}
-  !insertmacro CheckSection ${DRIVE_0_SECTION}
-  !insertmacro CheckSection ${DRIVE_1_SECTION}
-  !insertmacro CheckSection ${DRIVE_2_SECTION}
-  !insertmacro CheckSection ${DRIVE_3_SECTION}
-  !insertmacro CheckSection ${DRIVE_4_SECTION}
-  !insertmacro CheckSection ${DRIVE_5_SECTION}
-  Abort
-done:
-FunctionEnd
-
-Function SkipUBCDPath
-  !insertmacro CheckSection ${UBCD_SECTION}
-  Abort
-done:
-FunctionEnd
-
-
 ; Install runcmda.exe if missing
 
 Function CheckRunCmdA
   IfFileExists "$INSTDIR\bin\runcmda.exe" done 0
     SetOutPath "$INSTDIR\bin"
-    File "${INPDIR}\bin\runcmda.exe"
+    !insertmacro FileExe "bin\runcmda.exe" ""
     File "${INPDIR}\bin\runcmda.exe.manifest"
   done:
 FunctionEnd
@@ -789,6 +793,10 @@ FunctionEnd
 !endif
 
 Function ShellLinkSetRunAs
+  ; Set archive location of $PLUGINSDIR
+  Goto +2
+    SetOutPath "$INSTDIR"
+
   System::Store S ; push $0-$9, $R0-$R9
   pop $9
   ; $0 = CoCreateInstance(CLSID_ShellLink, 0, CLSCTX_INPROC_SERVER, IID_IShellLink, &$1)
index 5034ff66ec7acf8c60b8ac20caed24355add5a43..42ea7192fcbe8244406af30635ba82c076a742b9 100644 (file)
@@ -1,7 +1,7 @@
 .ig
  Copyright (C) 2002-10 Bruce Allen <smartmontools-support@lists.sourceforge.net>
 
- $Id: smartctl.8.in 3530 2012-03-27 19:54:06Z chrfranke $
+ $Id: smartctl.8.in 3561 2012-06-05 19:49:31Z 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
@@ -85,6 +85,9 @@ than the SCSI device used for reading and writing data)!
 Use the forms \fB/dev/disk[0\-9]\fP or equivalently \fBdisk[0\-9]\fP or equivalently
 \fB/dev/rdisk[0\-9]\fP.  Long forms are also available: please use \'\-h\' to see some
 examples. Note that there is currently no Darwin SCSI support.
+
+Use the OS X SAT SMART Driver to access SMART data on SAT capable USB and
+Firewire devices (see INSTALL file).
 .\" %ENDIF OS Darwin
 .\" %IF OS FreeBSD
 .IP \fBFREEBSD\fP: 9
@@ -138,9 +141,13 @@ in the driver. Use \fB"/dev/tw_cli/stdin"\fP or \fB"/dev/tw_cli/clip"\fP
 to parse CLI or 3DM output from standard input or clipboard.
 The option \'\-d 3ware,N\' is not necessary on Windows.
 
-[NEW EXPERIMENTAL SMARTCTL FEATURE] For disks behind Intel Matrix RAID
-driver use \fB"/dev/csmi[0\-9],N"\fP where N specifies the port behind
-the logical scsi controller "\\\\.\\Scsi[0\-9]:".
+For disks behind an Intel ICHxR controller with RST driver use
+\fB"/dev/csmi[0\-9],N"\fP where N specifies the port behind the logical
+scsi controller "\\\\.\\Scsi[0\-9]:".
+
+[NEW EXPERIMENTAL SMARTCTL FEATURE] For SATA disks behind an Areca SATA
+or SAS controller use \fB"/dev/arcmsr[0\-9]"\fP, see \'\-d areca,N[/E]\' below.
+
 The prefix \fB"/dev/"\fP is optional.
 .\" %ENDIF OS Windows Cygwin
 .\" %IF OS Cygwin
@@ -301,7 +308,8 @@ SAT defines two ATA PASS THROUGH SCSI commands, one 12 bytes long and
 the other 16 bytes long.  The default is the 16 byte variant which can be
 overridden with either \'\-d sat,12\' or \'\-d sat,16\'.
 
-If \'-d sat,auto\' is specified, device type SAT (for ATA/SATA disks) is
+[NEW EXPERIMENTAL SMARTCTL FEATURE] If \'-d sat,auto\' is specified,
+device type SAT (for ATA/SATA disks) is
 only used if the SCSI INQUIRY data reports a SATL (VENDOR: "ATA     ").
 Otherwise device type SCSI (for SCSI/SAS disks) is used.
 
@@ -433,12 +441,12 @@ The necessary WRITE LOG commands can not be passed through the SCSI
 interface.
 
 .\" %ENDIF OS FreeBSD Linux
-.\" %IF OS Linux FreeBSD
+.\" %IF OS FreeBSD Linux Windows Cygwin
 .I areca,N
-\- [Linux and FreeBSD only] the device consists of one or more SATA disks connected to an
-Areca SATA RAID controller.  The positive integer N (in the range from 1 to
-24 inclusive) denotes which disk on the controller is monitored.
-.\" %ENDIF OS Linux FreeBSD
+\- [FreeBSD, Linux, Windows and Cygwin only] the device consists of one or more SATA disks
+connected to an Areca SATA RAID controller.  The positive integer N (in the range
+from 1 to 24 inclusive) denotes which disk on the controller is monitored.
+.\" %ENDIF OS FreeBSD Linux Windows Cygwin
 .\" %IF OS Linux
 On Linux use syntax such as:
 .nf
@@ -457,11 +465,22 @@ On FreeBSD use syntax such as:
 \fBsmartctl \-a \-d areca,3 /dev/arcmsr2\fP
 .fi
 .\" %ENDIF OS FreeBSD
+.\" %IF OS Windows Cygwin
+[NEW EXPERIMENTAL SMARTCTL FEATURE] On Windows and Cygwin use syntax such as:
+.nf
+\fBsmartctl \-a \-d areca,2 /dev/arcmsr0\fP
+.fi
+.nf
+\fBsmartctl \-a \-d areca,3 /dev/arcmsr1\fP
+.fi
+.\" %ENDIF OS Windows Cygwin
+.\" %IF OS FreeBSD Linux Windows Cygwin
 The first line above addresses the second disk on the first Areca RAID controller.
 The second line addresses the third disk on the second Areca RAID
 controller.  
+.\" %ENDIF OS FreeBSD Linux Windows Cygwin
 .\" %IF OS Linux
-To help identify the correct device on Linus, use the command:
+To help identify the correct device on Linux, use the command:
 .nf
 \fBcat /proc/scsi/sg/device_hdr /proc/scsi/sg/devices\fP
 .fi
@@ -471,13 +490,21 @@ smartmontools are the ones with the type field equal to 3.  If the
 incorrect device is addressed, please read the warning/error messages
 carefully.  They should provide hints about what devices to use.
 .\" %ENDIF OS Linux
+.\" %IF OS FreeBSD Linux Windows Cygwin
 
-.\" %IF OS Linux FreeBSD
 Important: the Areca controller must have firmware version 1.46 or
 later.  Lower-numbered firmware versions will give (harmless) SCSI
 error messages and no SMART information.
 
-.\" %ENDIF OS Linux FreeBSD
+.I areca,N/E
+\- [FreeBSD, Linux, Windows and Cygwin only] [NEW EXPERIMENTAL SMARTCTL FEATURE] the
+device consists of one or more SATA disks connected to an Areca SAS RAID controller.
+The integer N (range 1 to 128) denotes the channel (slot) and E (range
+1 to 8) denotes the enclosure.
+Important: This requires upcoming Areca SAS controller firmware version 1.51 or a
+recent beta version.
+
+.\" %ENDIF OS FreeBSD Linux Windows Cygwin
 .\" %IF OS FreeBSD Linux
 .I cciss,N
 \- [FreeBSD and Linux only] the device consists of one or more SCSI/SAS disks
@@ -1064,9 +1091,9 @@ This number can be changed by the optional parameter NUM.
 If ',error' is appended and the Extended Comprehensive SMART error
 log is not supported, the Summary SMART self-test log is printed.
 
-Please note that some recent (e.g. Samsung) drives report errors only
-in the Extended Comprehensive SMART error log. The Summary SMART error
-log can be read but is always empty.
+Please note that recent drives may report errors only in the Extended
+Comprehensive SMART error log.  The Summary SMART error log may be reported
+as supported but is always empty then.
 
 .I selftest
 \- [ATA] prints the SMART self\-test log.  The disk maintains a self\-test
@@ -1198,7 +1225,8 @@ and descriptions of the ATA Device Statistics log pages
 entries from all supported pages are printed.  If PAGE 0 is specified,
 the list of supported pages is printed.  Device Statistics was
 introduced in ATA\-8 ACS and is only supported by some recent devices
-(e.g. Intel 320 and 710 Series SSDs).
+(e.g. Hitachi 7K3000, Intel 320, 330 and 710 Series SSDs, Crucial/Micron
+m4 SSDs).
 
 .I sataphy[,reset]
 \- [SATA only] prints values and descriptions of the SATA Phy Event
@@ -1824,7 +1852,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\-M/X25\-M G2 and 320 Series) SSDs only:
+Example for Intel (X18/X25\-M G2, 320, 520 and 710 Series) 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
@@ -2164,4 +2192,4 @@ Links to these and other documents may be found on the Links page of the
 
 .SH
 SVN ID OF THIS PAGE:
-$Id: smartctl.8.in 3530 2012-03-27 19:54:06Z chrfranke $
+$Id: smartctl.8.in 3561 2012-06-05 19:49:31Z chrfranke $
index d3f7cc63568c22cfa0a5d6509b712c257b57107a..d23497483a8c16e74e149826831f7eeeafb7d7f4 100644 (file)
@@ -1,7 +1,7 @@
 .ig
 Copyright (C) 2002-10 Bruce Allen <smartmontools-support@lists.sourceforge.net>
  
-$Id: smartd.8.in 3529 2012-03-25 17:26:10Z chrfranke $
+$Id: smartd.8.in 3561 2012-06-05 19:49:31Z 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
@@ -116,7 +116,7 @@ Authoritative list of disk devices is obtained from sysctl
 .\" %ENDIF OS NetBSD OpenBSD
 .\" %IF OS Solaris
 .IP \fBSOLARIS:\fP 9
-Examine all entries \fB"/dev/rdsk/c?t?d?s?"\fP for IDE/ATA and SCSI disk
+Examine all entries \fB"/dev/rdsk/*s0"\fP for IDE/ATA and SCSI disk
 devices, and entries \fB"/dev/rmt/*"\fP for SCSI tape devices.
 .\" %ENDIF OS Solaris
 .\" %IF OS Darwin
@@ -140,9 +140,9 @@ If a 3ware 9000 controller is installed, examine all entries
 \fB"/dev/sdX"\fP) and all physical disks (\'ports\' \fB",N"\fP)
 detected behind this controller. Same for a second controller if present.
 
-[NEW EXPERIMENTAL SMARTD FEATURE] If directive \'\-d csmi\' is specified,
-examine all entries \fB"/dev/csmi[0\-9],N"\fP for drives behind Intel
-Matrix RAID driver.
+If directive \'\-d csmi\' or no \'\-d\' directive is specified,
+examine all entries \fB"/dev/csmi[0\-9],N"\fP for drives behind an Intel
+ICHxR controller with RST driver.
 .\" %ENDIF OS Windows Cygwin
 .\" %IF OS Cygwin
 .IP \fBCYGWIN\fP: 9
@@ -223,7 +223,7 @@ file.  Please use CONTROL-\e to exit
 .\" %IF OS Windows
 (Windows: CONTROL\-Break).
 
-Windows only: The "debug" mode can be toggled by the command
+[Windows only] The "debug" mode can be toggled by the command
 \fBsmartd sigusr2\fP. A new console for debug output is opened when
 debug mode is enabled.
 .\" %ENDIF OS Windows
@@ -456,7 +456,7 @@ an important change (which usually results in a SYSLOG output) occurred.
 .\" %IF OS Windows
 .TP
 .B \-\-service
-Windows only: Enables \fBsmartd\fP to run as a Windows service.
+[Windows only] Enables \fBsmartd\fP to run as a Windows service.
 The option must be specified in the service command line as the first
 argument. It should not be used from console.
 See NOTES below for details.
@@ -685,7 +685,7 @@ A compile time constant of\fB smartd\fP was too small.  This can be caused by an
 excessive number of disks, or by lines in \fB /usr/local/etc/smartd.conf\fP that are too long.
 Please report this problem to \fB smartmontools-support@lists.sourceforge.net\fP.
 .TP
-.B 10
+.B 10:
 An inconsistency was found in \fBsmartd\fP\'s internal data
 structures. This should never happen.  It must be due to either a
 coding or compiler bug.  \fIPlease\fP report such failures to
@@ -788,4 +788,4 @@ Links to these and other documents may be found on the Links page of the
 
 .SH
 SVN ID OF THIS PAGE:
-$Id: smartd.8.in 3529 2012-03-25 17:26:10Z chrfranke $
+$Id: smartd.8.in 3561 2012-06-05 19:49:31Z chrfranke $
index daccfc71d5ddc20427cbf53ddf9562c1f84e8731..06425eea68036db55374d2abfe5c1eaf60d73566 100644 (file)
@@ -1,7 +1,7 @@
 .ig
 Copyright (C) 2002-10 Bruce Allen <smartmontools-support@lists.sourceforge.net>
 
-$Id: smartd.conf.5.in 3519 2012-03-06 20:01:44Z chrfranke $
+$Id: smartd.conf.5.in 3561 2012-06-05 19:49:31Z 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
@@ -53,7 +53,7 @@ running.
 In the absence of a configuration file
 \fBsmartd\fP will try to open all available devices.
 .\" %IF OS Linux
-Ubder linux will try to open the 20 ATA devices
+Under linux \fBsmartd\fP will try to open the 20 ATA devices
 .B /dev/hd[a-t] 
 and the 26 SCSI devices
 .B /dev/sd[a-z].
@@ -386,7 +386,8 @@ SAT defines two ATA PASS THROUGH SCSI commands, one 12 bytes long and
 the other 16 bytes long.  The default is the 16 byte variant which can be
 overridden with either \'\-d sat,12\' or \'\-d sat,16\'.
 
-If \'-d sat,auto\' is specified, device type SAT (for ATA/SATA disks) is
+[NEW EXPERIMENTAL SMARTD FEATURE] If \'-d sat,auto\' is specified,
+device type SAT (for ATA/SATA disks) is
 only used if the SCSI INQUIRY data reports a SATL (VENDOR: "ATA     ").
 Otherwise device type SCSI (for SCSI/SAS disks) is used.
 
@@ -448,16 +449,24 @@ logical device corresponding to the particular physical disks.
 Please see the \fBsmartctl\fP(8) man page for further details.
 
 .\" %ENDIF OS FreeBSD Linux
-.\" %IF OS Linux FreeBSD
+.\" %IF OS FreeBSD Linux Windows Cygwin
 .I areca,N
-\- [Linux and FreeBSD only] the device consists of one or more SATA disks connected to an
-Areca SATA RAID controller.  The positive integer N (in the range from 1 to
-24 inclusive) denotes which disk on the controller is monitored.
+\- [FreeBSD, Linux, Windows and Cygwin only] the device consists of one or more SATA disks
+connected to an Areca SATA RAID controller.  The positive integer N (in the range
+from 1 to 24 inclusive) denotes which disk on the controller is monitored.
 In log files and email messages this disk will be identifed as
 areca_disk_XX with XX in the range from 01 to 24 inclusive.
 Please see the \fBsmartctl\fP(8) man page for further details.
 
-.\" %ENDIF OS Linux FreeBSD
+.I areca,N/E
+\- [FreeBSD, Linux, Windows and Cygwin only] [NEW EXPERIMENTAL SMARTD FEATURE] the
+device consists of one or more SATA disks connected to an Areca SAS RAID controller.
+The integer N (range 1 to 128) denotes the channel (slot) and E (range
+1 to 8) denotes the enclosure.
+Important: This requires upcoming Areca SAS controller firmware version 1.51 or a
+recent beta version.
+
+.\" %ENDIF OS FreeBSD Linux Windows Cygwin
 .\" %IF OS FreeBSD Linux
 .I cciss,N
 \- [FreeBSD and Linux only] the device consists of one or more SCSI/SAS disks
@@ -669,9 +678,8 @@ battery.
 .\" %ENDIF OS Cygwin Windows
 
 .I scterc,READTIME,WRITETIME
-\- [ATA only] [NEW EXPERIMENTAL SMARTD FEATURE] sets the SCT Error
-Recovery Control settings to the specified values (deciseconds)
-when \fBsmartd\fP starts up and has no further effect.
+\- [ATA only] sets the SCT Error Recovery Control settings to the specified
+values (deciseconds) when \fBsmartd\fP starts up and has no further effect.
 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.
@@ -725,10 +733,10 @@ The LBA range is based on the first span from the last test.
 See the \fBsmartctl \-t select,[next|redo|cont]\fP options for
 further info.
 
-[NEW EXPERIMENTAL SMARTD FEATURE] 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.
+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
@@ -1134,13 +1142,13 @@ or age of the device has exceeded its intended design life period."
 .TP
 .B \-p
 [ATA only] Report anytime that a Prefail Attribute has changed
-its value since the last check, 30 minutes ago. [Please see the
+its value since the last check. [Please see the
 .B smartctl \-A
 command-line option.]
 .TP
 .B \-u
 [ATA only] Report anytime that a Usage Attribute has changed its value
-since the last check, 30 minutes ago. [Please see the
+since the last check. [Please see the
 .B smartctl \-A
 command-line option.]
 .TP
@@ -1292,19 +1300,19 @@ reports are disabled (\'-W 0\').
 
 To track temperature changes of at least 2 degrees, use:
 .nf
-\fB \-W 2
+.B \-W 2
 .fi
 To log informal messages on temperatures of at least 40 degrees, use:
 .nf
-\fB \-W 0,40
+.B \-W 0,40
 .fi
 For warning messages/mails on temperatures of at least 45 degrees, use:
 .nf
-\fB \-W 0,0,45
+.B \-W 0,0,45
 .fi
 To combine all of the above reports, use:
 .nf
-\fB \-W 2,40,45
+.B \-W 2,40,45
 .fi
 
 For ATA devices, smartd interprets Attribute 194 as Temperature Celsius
@@ -1575,4 +1583,4 @@ SEE ALSO:
 
 .SH
 SVN ID OF THIS PAGE:
-$Id: smartd.conf.5.in 3519 2012-03-06 20:01:44Z chrfranke $
+$Id: smartd.conf.5.in 3561 2012-06-05 19:49:31Z chrfranke $
index 94930ee9a3f4d672c7f75d3af3ac9a5cdb0a6174..1ce551b304020126313e880ac018c724beb8c979 100644 (file)
@@ -3,8 +3,10 @@ Description=Self Monitoring and Reporting Technology (SMART) Daemon
 After=syslog.target
 
 [Service]
-EnvironmentFile=/usr/local/etc/sysconfig/smartmontools
+EnvironmentFile=-/usr/local/etc/sysconfig/smartmontools
 ExecStart=/usr/local/sbin/smartd -n $smartd_opts
+ExecReload=/bin/kill -HUP $MAINPID
+StandardOutput=syslog
 
 [Install]
 WantedBy=multi-user.target
index 5635655f408b7351fe6fd6418c32ecf1fecda679..13d5ac9a424062338cf0a7cd136b61e08a5c2e7c 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-11 Christian Franke <smartmontools-support@lists.sourceforge.net>
+ * Copyright (C) 2008-12 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,7 +26,7 @@
 #ifndef UTILITY_H_
 #define UTILITY_H_
 
-#define UTILITY_H_CVSID "$Id: utility.h 3475 2011-11-10 21:43:40Z chrfranke $"
+#define UTILITY_H_CVSID "$Id: utility.h 3558 2012-06-05 16:42:05Z chrfranke $"
 
 #include <time.h>
 #include <sys/types.h> // for regex.h (according to POSIX)
@@ -54,6 +54,13 @@ std::string strprintf(const char * fmt, ...)
     __attribute_format_printf(1, 2);
 std::string vstrprintf(const char * fmt, va_list ap);
 
+// Return true if STR starts with PREFIX
+inline bool str_starts_with(const char * str, const char * prefix)
+  { return !strncmp(str, prefix, strlen(prefix)); }
+
+inline bool str_starts_with(const std::string & str, const char * prefix)
+  { return !strncmp(str.c_str(), prefix, strlen(prefix)); }
+
 #ifndef HAVE_WORKING_SNPRINTF
 // Substitute by safe replacement functions
 int safe_snprintf(char *buf, int size, const char *fmt, ...)