]> git.proxmox.com Git - mirror_smartmontools-debian.git/commitdiff
Merge branch 'upstream' of git.debian.org:/git/collab-maint/smartmontools into upstream
authorGiuseppe Iuculano <iuculano@debian.org>
Sat, 30 Jul 2016 16:53:10 +0000 (18:53 +0200)
committerGiuseppe Iuculano <iuculano@debian.org>
Sat, 30 Jul 2016 16:53:10 +0000 (18:53 +0200)
30 files changed:
1  2 
AUTHORS
ChangeLog
INSTALL
Makefile.am
NEWS
README
atacmds.cpp
atacmds.h
ataidentify.cpp
ataprint.cpp
autogen.sh
configure.ac
drivedb.h
os_linux.cpp
os_win32.cpp
os_win32/installer.nsi
scsiata.cpp
scsicmds.cpp
scsicmds.h
scsiprint.cpp
smartctl.8.in
smartctl.cpp
smartd.8.in
smartd.conf
smartd.conf.5.in
smartd.cpp
update-smart-drivedb.8.in
update-smart-drivedb.in
utility.cpp
utility.h

diff --cc AUTHORS
index 62cd8f2812dc7ce0c3bf8a8a2e73861d543acee1,748dbfaa0f93ac977a695b4c33fa76e762d4eee8..94316183f2837cbf5cd57025b5e16de4a04bfdaa
+++ b/AUTHORS
@@@ -1,4 -1,4 +1,8 @@@
++<<<<<<< HEAD
 +$Id: AUTHORS 4285 2016-04-10 13:17:11Z chrfranke $
++=======
+ $Id: AUTHORS 4101 2015-05-30 17:52:05Z chrfranke $
++>>>>>>> 3d8ad6fa4529eb02ae1391a1e937bf57aad3fb74
  
  Developers / Maintainers / Contributors:
  
@@@ -12,7 -12,6 +16,10 @@@ Yuri Dario              <mc6530@mclink.
  Casper Dik              <...>
  Christian Franke        <franke@computer.org>
  Guilhem Frézou          <...>
++<<<<<<< HEAD
 +Thomas Gatterweh        <thomas_gatterweh@hotmail.com>
++=======
++>>>>>>> 3d8ad6fa4529eb02ae1391a1e937bf57aad3fb74
  Douglas Gilbert         <dgilbert@interlog.com>
  Guido Guenther          <agx@sigxcpu.org>
  Jordan Hargrave         <jordan_hargrave@dell.com>
diff --cc ChangeLog
index 107304e35eb41bd3942984070ee26cfdefa4eed1,d5ac441c434fa41d3964b946b4d88984797267df..9bc638c448b35fd5848a12c1fc777682973a419b
+++ b/ChangeLog
++<<<<<<< HEAD
 +$Id: ChangeLog 4324 2016-05-31 20:45:50Z chrfranke $
 +
 +2016-05-31  Christian Franke  <franke@computer.org>
 +
 +      drivedb.h:
 +      - Intel 311/313 Series SSDs: mSATA, *H (HP) variant
 +      - Intel 520 Series SSDs: *L (Lenovo) variant
 +      - HGST Ultrastar He6/He8: attribute 22 "Helium_Level"
 +      - Western Digital Red: 8TB, attribute 22 "Helium_Level"
 +      - USB: WD My Passport Ultra (0x1058:0x0837) (ticket #696)
 +      - USB: WD My Passport (0x1058:0x083a)
 +      - USB: WD My Book (0x1058:0x111d)
 +
 +2016-05-10  Christian Franke  <franke@computer.org>
 +
 +      os_openbsd.cpp: Compile fix (regression from r4156).
 +
 +      os_netbsd.cpp: Apply patch-os__netbsd.cpp 1.3 (2016-05-08) from
 +      pkgsrc.se/sysutils/smartmontools:
 +      - Compile fix (regression from r4156).
 +      - Use a raw disk device file on NetBSD.
 +
 +2016-05-07  Christian Franke  <franke@computer.org>
 +
 +      smartmontools 6.5
 +
 +2016-05-06  Christian Franke  <franke@computer.org>
 +
 +      drivedb.h:
 +      - Samsung SpinPoint P80 SD: *J/P variant
 +      - Seagate Samsung SpinPoint M7E
 +      - Hitachi/HGST Travelstar Z5K500: *E680 variant
 +      - Hitachi Travelstar 7K500: HITACHI variant
 +      - Hitachi Ultrastar 7K3000: *A641 variant
 +      - HGST Ultrastar He8
 +      - Toshiba 2.5" HDD MQ01ABD...: *V variant
 +      - Seagate Desktop HDD.15: 5TB
 +      - Seagate SV35.3
 +      - Seagate SV35: *0001 variant
 +      - Seagate DB35: SATA variant
 +      - Western Digital Blue: 2-6TB, *Z variant
 +      - Western Digital RE4-GP: *2003* variant
 +      - Western Digital Re: Rename, 2-6TB
 +      - Western Digital Caviar Green: SATA 6Gb/s variant
 +      - Western Digital Caviar Black: *7501AAES*
 +      - Western Digital Blue Mobile: 2TB
 +      - Western Digital Elements / My Passport (USB, AF): *7500B*, 3TB
 +
 +2016-05-01  Christian Franke  <franke@computer.org>
 +
 +      drivedb.h:
 +      - Samsung based SSDs: 840 EVO 750GB (ticket #692), 850 EVO M.2,
 +        SM843T *HCFV* variant
 +      - USB: WD My Passport (0x1058:0x07ae) (ticket #686)
 +      - USB: JMicron JMS561 (0x152d:0x9561)
 +
 +      nvmecmds.cpp: Enhance debug hex dump to sizeof Identify structs.
 +      Do not dump trailing zero bytes.
 +
 +2016-04-27  Christian Franke  <franke@computer.org>
 +
 +      nvmeprint.cpp, nvmeprint.h, smartctl.cpp, smartctl.8.in:
 +      Add NVMe support for 'smartctl -c'.  Print various drive and
 +      namespace capabilites.  Remove related info from '-i' output.
 +
 +2016-04-24  Christian Franke  <franke@computer.org>
 +
 +      nvmeprint.cpp: Fix formatting of error log with unset LBA fields.
 +
 +      utility.cpp, utility.h: Skip leading blanks in format_char_array().
 +      Some NVMe devices return right aligned text fields.
 +
 +      configure.ac, smartd.cpp: Remove include of netdb.h.
 +      No longer needed since r3712.
 +
 +      smartd.cpp, smartd.conf.5.in: Remove support for '-m [sys]msgbox'.
 +
 +2016-04-23  Christian Franke  <franke@computer.org>
 +
 +      drivedb.h:
 +      - Innodisk 3ME SSDs
 +      - Innodisk 3IE2/3MG2/3SE2-P SSDs: Rename, add 3SE2-P
 +      - Innodisk 3IE3/3ME3 SSDs: Rename, add 3IE3
 +      - USB: Buffalo MiniStation HD-PNFU3 (0x0411:0x0251) (ticket #683)
 +      - USB: Renesas uPD720231A (0x045b:0x022a)
 +      - USB: Toshiba Canvio (0x0480:0x0210, 0x0480:0xa20c)
 +      - USB: Samsung G2 Portable (0x04e8:0x6032): 2nd entry with -d sat
 +      - USB: Iomega LDHD-UPS (0x059b:0x0278)
 +      - USB: Iomega LPHD-UP (0x059b:0x0470)
 +      - USB: LaCie Desktop Hard Drive (0x059f:0x1016)
 +      - USB: SanDisk SDCZ80 Flash Drive (0x0781:0x5588)
 +      - USB: Seagate Backup Plus USB 3.0 (0x0bc2:0xab2[05])
 +      - USB: WD My Passport Ultra (0x1058:0x0822)
 +      - USB: WD Elements (0x1058:0x25a2)
 +      - USB: JMicron JMS561 (0x152d:0x1561)
 +      - USB: VIA VL711 (0x2109:0x0711): change to -d sat (ticket #594)
 +      - USB: Sharkoon QuickPort XT USB 3.0 (0x357d:0x7788)
 +
 +2016-04-16  Christian Franke  <franke@computer.org>
 +
 +      smartctl.cpp: Allow NVMe debug messages during --scan.
 +      Suppress "Device open changed type ..." message unless debug
 +      mode is enabled.
 +
 +      atacmds.cpp: Remove duplicate POWER MODE error message.
 +
 +      smartd.cpp: Remove dead increment (cppcheck: unreadVariable).
 +      Do not write localized decimal point to syslog().
 +
 +      configure.ac, Makefile.am: Add '--with-update-smart-drivedb=no'
 +      option to disable drive database update script.  Useful if
 +      maintainers do not want the script due to security concerns
 +      and/or want to provide database updates as a separate package
 +      (Debian bug 804299, FreeBSD Bugzilla 208398).
 +      smartctl.8.in, smartd.8.in: Hide references to script if disabled.
 +
 +      nvmeprint.cpp: Add Power State and Namespace info to '-i' output.
 +      Do not print unset or duplicate info unless debug mode is enabled.
 +      nvmecmds.cpp, nvmecmds.h: Add Identify Namespace support.
 +
 +2016-04-15  Christian Franke  <franke@computer.org>
 +
 +      os_linux.cpp: Fix harmless bug in errno check of HPTIO_CTL ioctl()
 +      calls.  Bug was introduced 10 years ago in r2237.
 +
 +2016-04-15  Yuriy M. Kaminskiy  <yumkam@gmail.com>
 +
 +      os_linux.cpp: Fix harmless bug in errno check of HDIO_DRIVE_TASK*
 +      ioctl() calls.  Bug was introduced 12 years ago in r1609, the fix
 +      in r4003 was incomplete.
 +
 +2016-04-14  Christian Franke  <franke@computer.org>
 +
 +      nvmeprint.cpp: Fix size factor of Data Units Read/Written counters.
 +      os_win32.cpp: Fix device count in win_nvme_device::open().
 +
 +      Thanks to Oliver Bruchmann for bug reports and testing.
 +
 +2016-04-12  Douglas Gilbert  <dgilbert@interlog.com>
 +
 +      scsiprint.cpp: improve handling when no tape cartridge is
 +      in the tape drive.
 +
 +2016-04-12  Alex Samorukov  <samm@os2.kiev.ua>
 +
 +      scsiprint.cpp, smartd.cpp: workaround for the buggy ST8000NM0075/E001,
 +      request log page list with a fixed length (ticket #678).
 +
 +2016-04-11  Alex Samorukov  <samm@os2.kiev.ua>
 +
 +      drivedb.h: add Samsung SM863 series, ticket #681
 +
 +2016-04-10  Christian Franke  <franke@computer.org>
 +
 +      os_win32.cpp: Include also unknown and unsupported USB devices
 +      in device scan result.  Move USB device handling to new function.
 +      Add Windows Server 2016 to get_os_version_str().
 +
 +      AUTHORS: Add Thomas Gatterweh.
 +      smartd.cpp: Check is_powered_down() also with '-n sleep'.
 +
 +2016-04-10  Thomas Gatterweh  <thomas_gatterweh@hotmail.com>
 +
 +      Prevent drive spin up by '-n standby' check on Windows (ticket #677):
 +      dev_interface.cpp, dev_interface.h:
 +      Add smart_device::is_powered_down().
 +      os_win32.cpp: Add win_ata_device::is_powered_down().  Open device
 +      without READ or WRITE access to prevent spin up.
 +      smartctl.cpp, smartd.cpp: Add check for is_powered_down().
 +
 +2016-04-09  Christian Franke  <franke@computer.org>
 +
 +      configure.ac, os_win32.cpp, smartd.8.in: Add NVMe DEVICESCAN
 +      support for Windows.
 +
 +      smartctl.8.in, smartd.8.in, smartd.conf.5.in: Document NVMe
 +      support for Windows.
 +
 +      nvmecmds.cpp, os_win32.cpp: Use NSID=0 for Identify Controller
 +      command.  This fixes NVMe access via Samsung driver on Windows.
 +
 +2016-04-08  Christian Franke  <franke@computer.org>
 +
 +      os_win.cpp: Add initial NVMe support for Windows.
 +      Successfully tested with Intel driver.
 +      Does not work with Samsung driver.
 +
 +      Thanks to Minkyu Kim for testing.
 +
 +2016-04-02  Christian Franke  <franke@computer.org>
 +
 +      Fix memory leak if get_sat_device() is called with unknown 'type':
 +      scsiata.cpp: get_sat_device(): Delete 'scsidev' on error.
 +      dev_interface.h: Update documentation of get_sat_device().
 +      dev_interface.cpp: Fix use of get_sat_device().
 +      (All other uses of get_sat_device() are already sane).
 +
 +      dev_interface.cpp, dev_interface.h: Add counter for objects derived
 +      from 'smart_device'.
 +      smartctl.cpp, smartd.cpp: Print error message if any objects remain
 +      on exit.
 +
 +      os_linux.cpp: linux_megaraid_device: Remove unused member variable
 +      'm_busnum' (clang++: -Wunused-private-field) and the related ctor
 +      parameter.
 +
 +      os_linux.cpp: Fixes suggested by clang analyser:
 +      Add or remove inconsistent nullptr checks.
 +      Remove dead increments.
 +
 +2016-04-01  Douglas Gilbert  <dgilbert@interlog.com>
 +
 +      scsiprint.cpp: add missing commas in peripheral_dt_arr and
 +        add number of elements (2**5) so that won't happen again.
 +
 +2016-03-31  Alex Samorukov  <samm@os2.kiev.ua>
 +
 +      drivedb.h: 
 +       - add samsung SAMSUNG-MZ7PC series (ticket #679)
 +       - add KINGSTON SKC400S37128G (SSDNow KC400) (ticket #673, patch provided
 +         by the reporter)
 +       - add SanDisk SSD Plus series (ticket #674)
 +       - add XceedIOPS SSD series (ticket #672)
 +       - add Crucial BX200 SSD (ticket #643)
 +
 +2016-03-30  Christian Franke  <franke@computer.org>
 +
 +      Add support for multiple '-d TYPE' options for device scanning:
 +      dev_interface.cpp, dev_interface.cpp: Add new version of
 +      scan_smart_devices() which accepts list of types.
 +      smartctl.cpp, smartd.cpp: Allow multiple '-d TYPE' options.
 +      Use new scan_smart_devices().
 +      smartctl.8.in, smartd.conf.5.in: Document it.
 +
 +      Makefile.am: Add man page support for --with-nvme-devicescan.
 +      smartd.8.in: Document NVMe DEVICESCAN for Linux.
 +
 +      configure.ac: Use `...` instead of $(...) due to possible parsing
 +      problems since r4260.  Remove workaround for related bash bug.
 +
 +2016-03-28  Christian Franke  <franke@computer.org>
 +
 +      Add NVMe DEVICESCAN support for Linux:
 +      configure.ac: Add --with-nvme-devicescan option.
 +      os_linux.cpp: Scan for '/dev/nvme[0-99]' if '-d nvme' is specified
 +      or --with-nvme-devicescan is set.
 +      smartctl.cpp: Add "NVMe" to --scan info.
 +
 +      smartctl.8.in, smartd.8.in, smartd.conf.5.in: Enable NVMe
 +      sections also for FreeBSD.
 +
 +      configure.ac: Write configuration summary also to config.log.
 +
 +2016-03-28  Alex Samorukov  <samm@os2.kiev.ua>
 +
 +      os_freebsd.cpp: Add initial FreeBSD NVMe support (ticket #657)
 +
 +2016-03-27  Christian Franke  <franke@computer.org>
 +
 +      ataprint.cpp: Support POWER MODE values introduced in ATA ACS-2
 +      (ticket #184, smartctl only).
 +
 +2016-03-27  Thomas Gatterweh  <thomas_gatterweh@hotmail.com>
 +
 +      atacmds.cpp, smartd.cpp: Support POWER MODE values introduced
 +      in ATA ACS-2 (ticket #184, smartd only).
 +
 +2016-03-26  Christian Franke  <franke@computer.org>
 +
 +      os_win32.cpp: Rearrange code such that no forward declarations
 +      are needed.
 +
 +      os_freebsd.cpp, os_netbsd.cpp, os_openbsd.cpp, os_solaris.cpp,
 +      utility.cpp: Remove variable 'bytes'.  Only used for a memory
 +      leak check which was removed in r2629 (2008-08-29).
 +
 +      os_solaris.cpp, utility.cpp, utility.h:
 +      Remove CustomStrDup(), use strdup() instead.
 +
 +      dev_legacy.cpp, utility.cpp, utility.h:
 +      Remove FreeNonZero(), use free() instead.
 +
 +      smartctl.cpp, smartd.cpp, utility.cpp, utility.h:
 +      Remove split_report_arg(), use sscanf() instead.
 +
 +      Add basic NVMe support for smartd (-H -l error -W):
 +      Makefile.am, os_win32/vc10/smartd.vcxproj: Add nvmecmds.cpp to smartd.
 +      smartd.cpp: Add NVMeDeviceScan() and NVMeCheckDevice().
 +      smartd.8.in, smartd.conf.5.in: Document NVMe support.
 +
 +      nvmeprint.cpp: Remove ary_to_str().
 +      utility.cpp, utility.h: Add format_char_array().
 +
 +2016-03-24  Christian Franke  <franke@computer.org>
 +
 +      dev_interface.cpp: Add missing 'usbprolific' to help text.
 +
 +      nvmecmds.cpp, nvmeprint.cpp: Add support for '-q noserial'.
 +
 +      smartd.cpp: Remove outdated declaration of getdomainname().
 +
 +      utility.cpp: Add C++ language version to output of -V option.
 +
 +2016-03-20  Christian Franke  <franke@computer.org>
 +
 +      nvmecmds.cpp, nvmecmds.h, nvmeprint.cpp, nvmeprint.h, smartctl.cpp:
 +      Add options '-l error[,NUM]' and '-l nvmelog,PAGE,SIZE' for NVMe
 +      devices.
 +      scsicmds.cpp: dStrHex(): Don't print trailing spaces.
 +      smartctl.8.in: Document '-l error[,NUM]', '-l nvmelog,PAGE,SIZE'
 +      and '-r nvmeioctl'.
 +
 +2016-03-18  Christian Franke  <franke@computer.org>
 +
 +      Add basic NVMe support for smartctl (-i -H -A) on Linux:
 +      Makefile.am: Add new files.
 +      dev_interface.cpp, dev_interface.h: Add class nvme_device.
 +      linux_nvme_ioctl.h: New file imported from Linux kernel sources
 +      (include/uapi/linux/nvme_ioctl.h 9d99a8d 2015-10-09).
 +      nvmecmds.cpp, nvmecmds.h: New module with NVMe command wrapper
 +      functions for smartctl and smartd.
 +      nvmeprint.cpp, nvmeprint.h: New module with nvmePrintMain().
 +      smartctl.cpp: Add nvmePrintMain() support.
 +      os_linux.cpp: Add class linux_nvme_device.
 +      os_win32/vc10/smart*.vcxproj*: Add new files.
 +      smartctl.8.in: Document NVMe support.
 +
 +2016-03-14  Douglas Gilbert  <dgilbert@interlog.com>
 +
 +      scsiprint.cpp: work on LB provisioning corner cases; LBPRZ now
 +      3 bits wide (in response to ticket #664)
 +
 +2016-03-14  Alex Samorukov  <samm@os2.kiev.ua>
 +
 +      drivedb.h:
 +       - extend Apple SSD regexp (ticket #668)
 +       - Add OCZ VeloDrive R (ticket #667)
 +
 +2016-03-12  Alex Samorukov  <samm@os2.kiev.ua>
 +
 +      drivedb.h: Add Phison Driven SSDs:
 +       - Kingston UV300 SSD series (ticket #663)
 +       - Kingston SSDNow KC310/V310
 +       - HyperX Savage
 +
 +2016-03-11  Alex Samorukov  <samm@os2.kiev.ua>
 +
 +      drivedb.h: Add Kingston UV300 SSD series
 +
 +2016-03-06  Christian Franke  <franke@computer.org>
 +
 +      drivedb.h: Samsung based SSDs: Fix PM863 regexp, attribute IDs and
 +      name length (regression from r4227).
 +
 +2016-03-03  Alex Samorukov  <samm@os2.kiev.ua>
 +
 +      drivedb.h: Adata HD710 1TB USB3 (ticket #662)
 +
 +2016-02-29  Alex Samorukov  <samm@os2.kiev.ua>
 +
 +      drivedb.h: PM863 Series (ticket #661)
 +
 +2016-02-28  Alex Samorukov  <samm@os2.kiev.ua>
 +
 +      drivedb.h: OWC Aura Pro 480 GB (ticket #660)
 +
 +2016-02-26  Christian Franke  <franke@computer.org>
 +
 +      update-smart-drivedb.in: Use HTTPS for '-u sf' (ticket #659).
 +      Improve file modification check.
 +      update-smart-drivedb.8.in: Document changed URL.
 +
 +      os_win32/vc10/smartctl.vcxproj: Workaround for missing support of
 +      '__func__' (included in C99 and C++11, but not in C++03).
 +
 +2016-02-15  Alex Samorukov  <samm@os2.kiev.ua>
 +
 +      drivedb.h: APPLE SSD TS064E (ticket #655)
 +
 +2016-02-02  Douglas Gilbert  <dgilbert@interlog.com>
 +
 +      scsiprint.cpp: output unavailable rather than 255C for Drive
 +        Trip temperature; skip background scan lpage for tape drives
 +
 +2016-02-02  Christian Franke  <franke@computer.org>
 +
 +      drivedb.h:
 +      - Crucial/Micron MX100/MX200/M5x0/M600 Client SSDs: 250GB MX200
 +        (ticket #644), M500 mSATA and M.2
 +      - OCZ Trion SSDs: Rename, add Trion 150
 +      - Innodisk 3ME3 SSDs: SATADOM-SL 3IE3
 +
 +2016-01-25  Alex Samorukov  <samm@os2.kiev.ua>
 +
 +      os_darwin: add launchctl script for the smartd and remove depricated one.
 +      "On current systems there is only one recommend way: launchd"
 +
 +2016-01-24  Alex Samorukov  <samm@os2.kiev.ua>
 +
 +      os_freebsd.cpp: fix possible reallocf with 0 bytes arg (ticket #640)
 +      drivedb.h: add Corsair Extreme SSD (ticket #642)
 +      os_darwin.cpp: fix error reporting if open fails
 +
 +2016-01-23  Alex Samorukov  <samm@os2.kiev.ua>
 +
 +      os_darwin.cpp: do not print bogus memory allocation error message if
 +        there are no devices found
 +
 +2016-01-22  Christian Franke  <franke@computer.org>
 +
 +      Various fixes suggested by clang analyser (ticket #640):
 +      dev_areca.cpp: Fix check of ARCMSR_READ_RQBUFFER result.
 +      knowndrives.cpp: Add missing member initialization.
 +      smartd.cpp: Fix crash on missing argument to '-s' directive.
 +      Add missing variable initialization.  Remove redundant assignment.
 +
 +2016-01-21  Alex Samorukov <samm@os2.kiev.ua>
 +
 +      drivedb.h: Added ADATA SP550 SSD (ticket #638)
 +      os_freebsd.cpp: Reduce variable scope where possible (cppcheck: variableScope)
 +      os_openbsd/os_netbsd - removed never used warning code defines (cppcheck)
 +
 +2016-01-21  Christian Franke  <franke@computer.org>
 +
 +      ataprint.cpp, smartd.cpp: Don't issue SCT commands if ATA Security
 +      is locked (ticket #637).
 +
 +2016-01-19  Alex Samorukov <samm@os2.kiev.ua>
 +
 +      drivedb.h:
 +       - Samsung PM871 SSD family (ticket #636)
 +       - Fixed detection for Samsung SSD 850 EVO mSATA 120GB (ticket #635)
 +       - Fixed Western Digital Caviar Black regexp, extended WD Black (ticket #631)
 +
 +2016-01-06  Christian Franke  <franke@computer.org>
 +
 +      drivedb.h:
 +      - SandForce Driven SSDs: Extra warning entry for buggy Corsair Force LS
 +        (ticket #628)
 +      - Innodisk 3MG2-P SSDs: 1.8" variant
 +      - Innodisk 3ME3 SSDs
 +      - USB: Seagate Expansion Portable (0x0bc2:0x2322) (ticket #627)
 +      - USB: Jess-Link (0x0dbf:0x9001)
 +
 +2016-01-01  Christian Franke  <franke@computer.org>
 +
 +      Happy New Year! Update copyright year in version info.
 +
 +2015-12-19  Christian Franke  <franke@computer.org>
 +
 +      Makefile.am: Fix path of 'smart-pkg-uninstall' (Regression from r4190).
 +
 +      update-smart-drivedb.8.in: Fix platform specific formatting.
 +
 +2015-12-18  Alex Samorukov <samm@os2.kiev.ua>
 +
 +      os_netbsd.cpp, os_openbsd.cpp: fix ioctl returtn value check
 +      os_darwin.cpp: fix error handling
 +      os_darwin: use /usr/local/ prefix to install on 10.11 (El Capitan)
 +
 +2015-12-16  Douglas Gilbert  <dgilbert@interlog.com>
 +
 +      scsiprint.cpp: stop tape drive looking for Solid State media
 +      log page (ticket #314).
 +
 +2015-12-14  Douglas Gilbert  <dgilbert@interlog.com>
 +
 +      scsiprint.cpp: fix compiler warning for is_tape. Clean code around
 +      handling of tape drives.
 +
 +2015-12-14  Christian Franke  <franke@computer.org>
 +
 +      drivedb.h:
 +      - Intel 320 Series SSDs: 1.8" microSATA
 +      - Intel 53x and Pro 2500 Series SSDs: Rename, add 535 (ticket #625),
 +        add Pro 2500
 +      - Intel 730 and DC S35x0/3610/3700 Series SSDs: Rename,
 +        add S3510/3610, 1.2TB, 1.6TB
 +      - USB: LaCie (0x059f:0x106f) (ticket #624)
 +      - USB: WD My Passport (0x1058:0x071a, 0x1058:0x0816)
 +      - USB: Initio (0x13fd:0x1650)
 +      - USB: Unknown (0xabcd:0x6103)
 +
 +      update-smart-drivedb.in: Add '-s SMARTCTL' option.
 +      update-smart-drivedb.8.in: Document it.
 +
 +2015-12-07  Christian Franke  <franke@computer.org>
 +
 +      configure.ac: Append 'svn' to list of download tools.
 +
 +      update-smart-drivedb.in: Use HTTPS download by default.
 +      Add options '-t TOOL', '-u LOCATION', '--cacert FILE',
 +      '--capath DIR', '--insecure' and '--dryrun'.
 +      Add 'svn' as new download tool.
 +      Ignore differences in SVN Id string (re-added).
 +      Remove usage of 'which' command.
 +
 +      update-smart-drivedb.8.in: Document the new options.
 +
 +2015-11-23  Christian Franke  <franke@computer.org>
 +
 +      atacmds.cpp: parse_attribute_def(): Init buffers before sscanf() call
 +      (cppcheck-1.71: uninitvar).
 +
 +      scsiprint.cpp: Fix GLTSD bit set/cleared info messages (ticket #621).
 +
 +2015-11-22  Christian Franke  <franke@computer.org>
 +
 +      Makefile.am: Add NEWS file to svnversion.h target.
 +
 +      os_win32/installer.nsi: Select 64-bit version on 64-bit Windows.
 +      Fix installation of runcmda.exe.  Update links.
 +
 +2015-11-15  Christian Franke  <franke@computer.org>
 +
 +      configure.ac: Check whether MinGW adds an application manifest.
 +
 +      Makefile.am: Add default manifest for MinGW builds.
 +
 +      os_win32/default.manifest: New default application manifest.
 +      Remove external application manifests.
 +
 +      os_win32/installer.nsi: Use macros from 'LogicLib.nsh' where possible.
 +      Add missing MessageBox /SD options.
 +      Remove external application manifests.
 +
 +2015-11-07  Christian Franke  <franke@computer.org>
 +
 +      drivedb.h:
 +      - Micron M500DC/M510DC Enterprise SSDs: Rename, add M510DC
 +      - SandForce Driven SSDs: Mushkin Chronos 7mm/MX/G2, Enhanced ECO2
 +      - Innodisk 3MG2-P SSDs
 +      - SiliconMotion based SSDs: Crucial BX100 (ticket #597)
 +
 +2015-10-31  Christian Franke  <franke@computer.org>
 +
 +      atacmds.cpp, atacmds.h, knowndrives.cpp, knowndrives.h:
 +      Read default SMART attribute settings from drivedb.h (ticket #465).
 +      Remove hard-coded attribute names and format settings.
 +
 +      drivedb.h: Uncomment default settings to create the "DEFAULT" entry.
 +      Add ",HDD" or ",SSD" to HDD/SSD specific settings.
 +
 +      smartctl.cpp, smartd.cpp: Use new database initialization function.
 +
 +      Create branch RELEASE_6_4_DRIVEDB with last drivedb.h file
 +      compatible with smartmontools 6.4.
 +
 +2015-10-22  Paul Grabinar  <pgrabinar@ocz.com>
 +
 +      drivedb.h:
 +      - SandForce Driven SSDs: OCZ RevoDrive 350, Z-Drive 4500
 +      - Indilinx Barefoot 3 based SSDs: Add attributes,
 +        OCZ ARC 100, Saber 1000, Vector 180, Vertex 460A
 +      - OCZ Intrepid 3000 SSDs: Intrepid 3700
 +      - OCZ Trion
 +
 +2015-10-20  Christian Franke  <franke@computer.org>
 +
 +      Reduce variable scope where possible (cppcheck: variableScope).
 +
 +      Makefile.am: Remove *.s from files used to generate svnversion.h.
 +
 +2015-10-18  Alex Samorukov <samm@os2.kiev.ua>
 +
 +      fixes suggested by cppcheck:
 +      Check realloc result to avoid memory leak (memleakOnRealloc)
 +      Fix printf() signednsess (invalidPrintfArgType_sint)
 +
 +2015-10-17  Christian Franke  <franke@computer.org>
 +
 +      Various fixes suggested by cppcheck:
 +      Close FILE pointer before reopening it (cppcheck: publicAllocationError).
 +      Add missing member initializations to ctors (cppcheck: uninitMemberVar).
 +      Remove redundant nullptr check (cppcheck: nullPointerRedundantCheck).
 +      Remove redundant assignments (cppcheck: redundantAssignment).
 +      Clarify calculation precedence (cppcheck: clarifyCalculation).
 +      Use C++-style casts for pointer types (cppcheck: cstyleCast).
 +      Remove duplicate on both sides of '||' (cppcheck: duplicateExpression).
 +      Declare ctors with one argument as 'explicit'
 +      (cppcheck: noExplicitConstructor).
 +      Remove unread variables and assignments (cppcheck: unreadVariable).
 +      Fix signedness of sscanf() formats strings
 +      (cppcheck: invalidScanfArgType_int).
 +
 +2015-10-14  Christian Franke  <franke@computer.org>
 +
 +      configure.ac: Disable os_solaris_ata.o by default.
 +      Add --with-solaris-sparc-ata option to enable.
 +      Makefile.am: Exclude os_solaris_ata.s from source tarball
 +      (Debian bug 729842).
 +      os_solaris.cpp: Check for WITH_SOLARIS_SPARC_ATA instead of __sparc.
 +
 +2015-10-13  Christian Franke  <franke@computer.org>
 +
 +      Makefile.am: Fix error handling in various shell scripts.
 +
 +2015-10-13  Casper Dik  <...>
 +
 +      os_solaris.cpp: Detect SATA devices as SCSI devices.  This adds
 +      support for auto detection of SATA devices behind SAT layer.
 +      Set USCSI_SILENT flag to suppress /dev/console messages on command
 +      error.
 +
 +2015-10-11  Christian Franke  <franke@computer.org>
 +
 +      drivedb.h: SiliconMotion based SSDs: Transcend SSD370S, SSD420,
 +      update attribute 245 (ticket #595, ticket #602).
 +
 +2015-10-10  Christian Franke  <franke@computer.org>
 +
 +      Makefile.am: Use MKDIR_P to create directories
 +      (available since automake 1.10).
 +
 +      os_win32.cpp: Detect USB ID if WMI reports type name "SCSI" instead
 +      of "USBSTOR".
 +      Detect USB ID also if drive letter is specified as device name.
 +
 +2015-10-04  Christian Franke  <franke@computer.org>
 +
 +      drivedb.h:
 +      - USB: Genesys Logic (0x05e3:0x0735)
 +      - USB: Addonics (0x0bf6:0x1001): unsupported (ticket #609)
 +      - USB: Initio (0x13fd:0x3920)
 +      - USB: JMicron JMS539 (0x152d:0x0539, 0x0100): Set from -d usbjmicron to
 +        unsupported because some devices may require -d sat instead (ticket #552).
 +      - USB: JMicron (0x152d:0x0565) (ticket #607)
 +      - USB: VIA VL711 (0x2109:0x0711): unsupported (ticket #594)
 +      - USB: Hitachi Touro Mobile (0x4971:0x1024)
 +
 +2015-09-25  Christian Franke  <franke@computer.org>
 +
 +      scsiata.cpp: Ignore SAT ATA PASS-THROUGH fixed format sense data if no
 +      ATA status bit is set (ticket #612).
 +
 +2015-09-23 Alex Samorukov <samm@os2.kiev.ua>
 +
 +      drivedb.h: Innostor USB3.0 to SATAIII bridge (#611)
 +
 +2015-09-21 Alex Samorukov <samm@os2.kiev.ua>
 +
 +      drivedb.h: decode 188 attribute for the "Seagate Enterprise Capacity
 +      3.5 HDD" drives family, (see #551).
 +
 +2015-09-04 Alex Samorukov <samm@os2.kiev.ua>
 +
 +      Makefile.am: integrate darwin dmg build process to the Makefile
 +
 +2015-09-03 Alex Samorukov <samm@os2.kiev.ua>
 +
 +      os_darwin: Initial import of the files required to build
 +      OSX/smartmontools native package (see #555).
 +
 +2015-08-27  Alex Samorukov <samm@os2.kiev.ua>
 +
 +      Homepage URL updated from the sourceforge to smartmontools.org (r4120)
 +
 +2015-08-26  Alex Samorukov <samm@os2.kiev.ua>
 +
 +      os_darwin.cpp: Implement get_os_version_str() for the darwin.
 +
 +2015-08-17  Christian Franke  <franke@computer.org>
 +
 +      scsiata.cpp: Ignore bogus SCSI sense_key if ATA status in
 +      SAT ATA Return Descriptor indicates success (ticket #548).
 +
 +2015-08-08  Christian Franke  <franke@computer.org>
 +
 +      os_win32.cpp: Fix get_os_version_str() for Windows >= 8.1.
 +      Add Windows 10 Final.
 +
 +2015-08-02  Christian Franke  <franke@computer.org>
 +
 +      configure.ac: Remove '--disable-drivedb',
 +      '--enable-savestates', '--enable-attributelog'.
 +      Print error message if used.
 +
 +2015-07-15  Christian Franke  <franke@computer.org>
 +
 +      autogen.sh: Drop support for automake 1.7 - 1.9.x.
 +      Rework search for automake-VERSION.
 +      configure.ac: Drop support for autoconf 2.5x.
 +      Drop support for automake 1.7 - 1.9.x.
 +      Remove --with-docdir option.
 +
 +2015-06-24  Alex Samorukov <samm@os2.kiev.ua>
 +
 +      drivedb.h:
 +      - USB: SimpleTech 3.0 bridge (0x4971:0x8017), reported in #554
++=======
+ $Id: ChangeLog 4109 2015-06-04 16:30:15Z chrfranke $
++>>>>>>> 3d8ad6fa4529eb02ae1391a1e937bf57aad3fb74
  
  2015-06-04  Christian Franke  <franke@computer.org>
  
diff --cc INSTALL
index 011622ac358ae950d2902ed5392313767f3faee6,49a647920a6f89d278afc51c4b1a276b1efd1abf..fbb1471977e57cb2c0874163cc388eee74d72a59
+++ b/INSTALL
@@@ -1,10 -1,10 +1,14 @@@
  Smartmontools installation instructions
  =======================================
  
++<<<<<<< HEAD
 +$Id: INSTALL 4120 2015-08-27 16:12:21Z samm2 $
++=======
+ $Id: INSTALL 4094 2015-05-27 21:41:17Z chrfranke $
++>>>>>>> 3d8ad6fa4529eb02ae1391a1e937bf57aad3fb74
  
  Please also see the smartmontools home page:
 -http://smartmontools.sourceforge.net/
 +http://www.smartmontools.org/
  
  Table of contents:
  
diff --cc Makefile.am
index c496bc9e202cfe42295cacb8592f05fcb2d22d2e,dafe35856c2cafc1b33e885b3c7795bfc3bd6298..da765f73dc80e1042561c6a878c663ef88045404
@@@ -1,6 -1,6 +1,10 @@@
  ## Process this file with automake to produce Makefile.in
  #
++<<<<<<< HEAD
 +# $Id: Makefile.am 4299 2016-04-16 19:45:57Z chrfranke $
++=======
+ # $Id: Makefile.am 4102 2015-06-01 19:25:47Z chrfranke $
++>>>>>>> 3d8ad6fa4529eb02ae1391a1e937bf57aad3fb74
  #
  
  @SET_MAKE@
@@@ -265,8 -255,8 +269,13 @@@ endi
  all-local: $(extra_MANS)
  install-man: $(extra_MANS)
        @$(NORMAL_INSTALL)
++<<<<<<< HEAD
 +      $(MKDIR_P) '$(DESTDIR)$(mandir)/man4'
 +      $(MKDIR_P) '$(DESTDIR)$(mandir)/man1m'
++=======
+       $(mkinstalldirs) '$(DESTDIR)$(mandir)/man4'
+       $(mkinstalldirs) '$(DESTDIR)$(mandir)/man1m'
++>>>>>>> 3d8ad6fa4529eb02ae1391a1e937bf57aad3fb74
        for i in $(extra_MANS); do \
          if test -f $(srcdir)/$$i; then file=$(srcdir)/$$i; \
          else file=$$i; fi; \
@@@ -329,7 -319,7 +338,11 @@@ sysconf_DATA = smartd.con
  
  # If modified smartd.conf exists install smartd.conf.sample instead
  install-sysconfDATA: $(sysconf_DATA)
++<<<<<<< HEAD
 +      $(MKDIR_P) '$(DESTDIR)$(sysconfdir)'
++=======
+       $(mkinstalldirs) '$(DESTDIR)$(sysconfdir)'
++>>>>>>> 3d8ad6fa4529eb02ae1391a1e937bf57aad3fb74
        @s="$(srcdir)/smartd.conf"; \
        f="$(DESTDIR)$(sysconfdir)/smartd.conf$(smartd_suffix)"; \
        if test -z "$(smartd_suffix)" && test -f "$$f"; then \
@@@ -500,7 -501,7 +513,11 @@@ initd_DATA_install = install-initdDATA-
  initd_DATA_uninstall = uninstall-initdDATA-generic
  
  install-initdDATA-generic: $(initd_DATA)
++<<<<<<< HEAD
 +      $(MKDIR_P) '$(DESTDIR)$(initddir)'
++=======
+       $(mkinstalldirs) '$(DESTDIR)$(initddir)'
++>>>>>>> 3d8ad6fa4529eb02ae1391a1e937bf57aad3fb74
        $(INSTALL_SCRIPT) '$(top_builddir)/$(initdfile)' '$(DESTDIR)$(initddir)/smartd$(smartd_suffix)'
  
  uninstall-initdDATA-generic:
@@@ -524,8 -525,8 +541,13 @@@ systemdsystemunit_DATA = smartd.servic
  endif
  
  smartd.service: smartd.service.in Makefile
++<<<<<<< HEAD
 +      @echo ' $$(SMARTD_SERVICE_FILTER) < $(srcdir)/smartd.service.in > $@'
 +      @{ \
++=======
+       @echo '  cat $(srcdir)/smartd.service.in | $$(SMARTD_SERVICE_FILTER) > $@'
+       @cat $(srcdir)/smartd.service.in | \
++>>>>>>> 3d8ad6fa4529eb02ae1391a1e937bf57aad3fb74
        sed 's|/usr/local/sbin/smartd|$(sbindir)/smartd|' | \
        if test -n '$(systemdenvfile)'; then \
          sed 's|/usr/local/etc/sysconfig/smartmontools|$(systemdenvfile)|'; \
  installdirs-local:
        @for d in '$(smartdplugindir)' '$(savestatesdir)' '$(attributelogdir)'; do \
          test -n "$$d" || continue; \
++<<<<<<< HEAD
 +        echo " $(MKDIR_P) '$(DESTDIR)$$d'"; \
 +        $(MKDIR_P) "$(DESTDIR)$$d" || exit 1; \
++=======
+         echo " $(mkinstalldirs) '$(DESTDIR)$$d'"; \
+         $(mkinstalldirs) "$(DESTDIR)$$d" || exit 1; \
++>>>>>>> 3d8ad6fa4529eb02ae1391a1e937bf57aad3fb74
        done
  
  install-data-local: installdirs-local
  #
  # Build man pages
  #
++<<<<<<< HEAD
 +MAN_FILTER = { \
++=======
+ MAN_FILTER = \
++>>>>>>> 3d8ad6fa4529eb02ae1391a1e937bf57aad3fb74
      sed -e 's|CURRENT_SVN_VERSION|$(releaseversion)|g' \
          -e "s|CURRENT_SVN_DATE|`sed -n 's,^.*DATE[^"]*"\([^"]*\)".*$$,\1,p' svnversion.h`|g" \
          -e "s|CURRENT_SVN_REV|`sed -n 's,^.*REV[^"]*"\([^"]*\)".*$$,r\1,p' svnversion.h`|g" \
      else \
        sed '/^\.\\" %IF ENABLE_DRIVEDB/,/^\.\\" %ENDIF ENABLE_DRIVEDB/ s,^,.\\"\# ,' ; \
      fi | \
++<<<<<<< HEAD
 +    if test '$(with_update_smart_drivedb)' = 'yes'; then \
 +      cat; \
 +    else \
 +      sed '/^\.\\" %IF ENABLE_UPDATE_SMART_DRIVEDB/,/^\.\\" %ENDIF ENABLE_UPDATE_SMART_DRIVEDB/ s,^,.\\"\# ,' ; \
 +    fi | \
++=======
++>>>>>>> 3d8ad6fa4529eb02ae1391a1e937bf57aad3fb74
      if test -n '$(initddir)'; then \
        sed 's|/usr/local/etc/rc\.d/init\.d/|$(initddir)/|g' ; \
      else \
      else \
        sed '/^\.\\" %IF ENABLE_CAPABILITIES/,/^\.\\" %ENDIF ENABLE_CAPABILITIES/ s,^,.\\"\# ,' ; \
      fi | \
++<<<<<<< HEAD
 +    if test '$(with_nvme_devicescan)' = 'yes'; then \
 +      cat; \
 +    else \
 +      sed '/^\.\\" %IF ENABLE_NVME_DEVICESCAN/,/^\.\\" %ENDIF ENABLE_NVME_DEVICESCAN/ s,^,.\\"\# ,' ; \
 +    fi | \
++=======
++>>>>>>> 3d8ad6fa4529eb02ae1391a1e937bf57aad3fb74
      if test -n '$(os_man_filter)'; then \
        sed -e 's,OS_MAN_FILTER,$(os_man_filter),g' \
            -e '/^\.\\" %IF NOT OS .*$(os_man_filter)/,/^.\\" %ENDIF NOT OS .*$(os_man_filter)/ s,^,.\\"\# ,' \
diff --cc NEWS
index 6db7d288586c2ab90b81653a14d8054163621a8e,b14909b15117c26888ea9f5a6fb9243a9fd50785..6f1f1466eaa1b3c8c355fd7007704637e91c8ab7
--- 1/NEWS
--- 2/NEWS
+++ b/NEWS
@@@ -1,55 -1,10 +1,62 @@@
  smartmontools NEWS
  ------------------
++<<<<<<< HEAD
 +$Id: NEWS 4318 2016-05-07 11:18:20Z chrfranke $
++=======
+ $Id: NEWS 4109 2015-06-04 16:30:15Z chrfranke $
++>>>>>>> 3d8ad6fa4529eb02ae1391a1e937bf57aad3fb74
  
  The most up-to-date version of this file is:
  http://sourceforge.net/p/smartmontools/code/HEAD/tree/trunk/smartmontools/NEWS
  
++<<<<<<< HEAD
 +Date 2016-05-07
 +Summary: smartmontools release 6.5
 +-----------------------------------------------------------
 +- Experimental support for NVMe devices on FreeBSD, Linux and Windows.
 +- smartctl '-i', '-c', '-H' and '-l error': NVMe support.
 +- smartctl '-l nvmelog': New option for NVMe.
 +- smartd.conf '-H', '-l error' and '-W': NVMe support.
 +- Optional NVMe device scanning support on Linux and Windows.
 +- configure option '--with-nvme-devicescan' to include NVMe in
 +  default device scanning result.
 +- Device scanning now allows to specify multiple '-d TYPE' options.
 +- ATA: Added new POWER MODE values introduced in ATA ACS-2.
 +- ATA: SCT commands are no longer issued if ATA Security is locked.
 +- SCSI: LB provisioning improvements.
 +- SCSI: Fixed GLTSD bit set/cleared info messages.
 +- SCSI: Solid State media log page is no longer checked for tapes.
 +- SCSI: Improved handling when no tape cartridge in drive.
 +- SCSI: Workaround for buggy Seagate firmware.
 +- SAT: Improved heuristics to detect bogus sense data from SAT layer.
 +- smartd: Fixed crash on missing argument to '-s' directive.
 +- update-smart-drivedb: Now uses HTTPS for download by default.
 +- update-smart-drivedb: New options to select URL and download tool.
 +- update-smart-drivedb: New download tool 'svn'.
 +- configure option '--without-update-smart-drivedb' to disable
 +  update-smart-drivedb script.
 +- configure options '--disable-drivedb', '--enable-savestates',
 +  '--enable-attributelog' and '--with-docdir' are no longer supported.
 +- autoconf < 2.60 and automake < 1.10 are no longer supported.
 +- Drive database file now also includes the DEFAULT setting
 +  for each attribute.
 +- HDD, SSD and USB additions to drive database.
 +- Darwin: New support files for package installer.
 +  New makefile target 'install-darwin' builds DMG image.
 +- Solaris: Auto detection of SATA devices behind SAT layer.
 +- Solaris SPARC: Legacy ATA support disabled by default.
 +  New configure option '--with-solaris-sparc-ata' enables it.
 +  File os_solaris_ata.s is no longer included in source tarball.
 +- Windows: Auto detection of USB devices specified by drive letter.
 +- Windows: Device scanning does no longer ignore unknown USB devices.
 +- Windows: Prevent drive spin up by '-n standby' check.
 +- Windows: New application manifests indicating Win 10 support.
 +- Windows smartd: '-m [sys]msgbox' is no longer supported.
 +- Windows installer: Defaults to 64-bit version on 64-bit Windows.
 +- Various code changes suggested by Clang Static Analyser and Cppcheck.
 +
++=======
++>>>>>>> 3d8ad6fa4529eb02ae1391a1e937bf57aad3fb74
  Date 2015-06-04
  Summary: smartmontools release 6.4
  -----------------------------------------------------------
diff --cc README
index 6d20c011416592a689c10aa87aa0b16481c28824,48f592ec43694a0ce40064830093fbe4d5d89939..b7ad13871ebd85d2959724de7a3ebe82b07ad289
--- 1/README
--- 2/README
+++ b/README
@@@ -3,7 -3,7 +3,11 @@@ smartmontools - S.M.A.R.T. utility tool
  OSX, FreeBSD, Linux, NetBSD, OpenBSD, Solaris, and Windows.
  ==========================================================
  
++<<<<<<< HEAD
 +$Id: README 4120 2015-08-27 16:12:21Z samm2 $
++=======
+ $Id: README 4063 2015-04-19 17:34:25Z chrfranke $
++>>>>>>> 3d8ad6fa4529eb02ae1391a1e937bf57aad3fb74
  
  == HOME ==
  The home for smartmontools is located at:
diff --cc atacmds.cpp
index f1974916c8c08a7b2517198c60b0679a35e77c5b,88ec6b94f8e04a6d044385b0e38b0152182c01c7..9d77f8e29f64bf376db6d3bc3670b78f5e8653fe
@@@ -1,10 -1,10 +1,15 @@@
  /*
   * atacmds.cpp
   * 
 - * Home page of code is: http://smartmontools.sourceforge.net
 + * Home page of code is: http://www.smartmontools.org
   *
++<<<<<<< HEAD
 + * Copyright (C) 2002-11 Bruce Allen
 + * Copyright (C) 2008-15 Christian Franke
++=======
+  * Copyright (C) 2002-11 Bruce Allen <smartmontools-support@lists.sourceforge.net>
+  * Copyright (C) 2008-15 Christian Franke <smartmontools-support@lists.sourceforge.net>
++>>>>>>> 3d8ad6fa4529eb02ae1391a1e937bf57aad3fb74
   * Copyright (C) 1999-2000 Michael Cornwell <cornwell@acm.org>
   * Copyright (C) 2000 Andre Hedrick <andre@linux-ide.org>
   *
  #include "utility.h"
  #include "dev_ata_cmd_set.h" // for parsed_ata_device
  
++<<<<<<< HEAD
 +const char * atacmds_cpp_cvsid = "$Id: atacmds.cpp 4301 2016-04-16 20:48:29Z chrfranke $"
++=======
+ const char * atacmds_cpp_cvsid = "$Id: atacmds.cpp 4048 2015-03-29 16:09:04Z chrfranke $"
++>>>>>>> 3d8ad6fa4529eb02ae1391a1e937bf57aad3fb74
                                   ATACMDS_H_CVSID;
  
  // Print ATA debug messages?
diff --cc atacmds.h
index 5768677acd2fec3b18b13572ab1a2a2ec14d08f0,5ac43ffc80228f601b5c6baabbe86975286cc374..a66364fcd2a564da7778cdcc6f3d3c80e7842e55
+++ b/atacmds.h
@@@ -1,10 -1,10 +1,15 @@@
  /*
   * atacmds.h
   *
 - * Home page of code is: http://smartmontools.sourceforge.net
 + * Home page of code is: http://www.smartmontools.org
   *
++<<<<<<< HEAD
 + * Copyright (C) 2002-11 Bruce Allen
 + * Copyright (C) 2008-15 Christian Franke
++=======
+  * Copyright (C) 2002-11 Bruce Allen <smartmontools-support@lists.sourceforge.net>
+  * Copyright (C) 2008-15 Christian Franke <smartmontools-support@lists.sourceforge.net>
++>>>>>>> 3d8ad6fa4529eb02ae1391a1e937bf57aad3fb74
   * Copyright (C) 1999-2000 Michael Cornwell <cornwell@acm.org>
   *
   * This program is free software; you can redistribute it and/or modify
  #ifndef ATACMDS_H_
  #define ATACMDS_H_
  
++<<<<<<< HEAD
 +#define ATACMDS_H_CVSID "$Id: atacmds.h 4162 2015-10-31 16:36:16Z chrfranke $"
++=======
+ #define ATACMDS_H_CVSID "$Id: atacmds.h 4048 2015-03-29 16:09:04Z chrfranke $"
++>>>>>>> 3d8ad6fa4529eb02ae1391a1e937bf57aad3fb74
  
  #include "dev_interface.h" // ata_device
  
diff --cc ataidentify.cpp
index ec3c40edd7d3f5256442ce468748aec2d1598809,0565323b3a149c681d6bd1ae5aecdaa58bebec1b..90a91431a691d08258227bdb6cb86967b2eac922
  #include "config.h"
  #include "ataidentify.h"
  
++<<<<<<< HEAD
 +const char * ataidentify_cpp_cvsid = "$Id: ataidentify.cpp 4120 2015-08-27 16:12:21Z samm2 $"
++=======
+ const char * ataidentify_cpp_cvsid = "$Id: ataidentify.cpp 4074 2015-05-01 16:03:50Z chrfranke $"
++>>>>>>> 3d8ad6fa4529eb02ae1391a1e937bf57aad3fb74
    ATAIDENTIFY_H_CVSID;
  
  #include "int64.h"
diff --cc ataprint.cpp
index fe94593caa344a86c67956c44a95628c4c170285,33fd8b73fcc1e598aeb531f6b6f6a41339bf1e8c..6f47fd99a91f317b021ccc41920ab9781dca4842
@@@ -1,10 -1,10 +1,14 @@@
  /*
   * ataprint.cpp
   *
 - * Home page of code is: http://smartmontools.sourceforge.net
 + * Home page of code is: http://www.smartmontools.org
   *
   * Copyright (C) 2002-11 Bruce Allen
++<<<<<<< HEAD
 + * Copyright (C) 2008-16 Christian Franke
++=======
+  * Copyright (C) 2008-15 Christian Franke
++>>>>>>> 3d8ad6fa4529eb02ae1391a1e937bf57aad3fb74
   * Copyright (C) 1999-2000 Michael Cornwell <cornwell@acm.org>
   *
   * This program is free software; you can redistribute it and/or modify
  #include "utility.h"
  #include "knowndrives.h"
  
++<<<<<<< HEAD
 +const char * ataprint_cpp_cvsid = "$Id: ataprint.cpp 4256 2016-03-27 16:51:32Z chrfranke $"
++=======
+ const char * ataprint_cpp_cvsid = "$Id: ataprint.cpp 4104 2015-06-03 18:50:39Z chrfranke $"
++>>>>>>> 3d8ad6fa4529eb02ae1391a1e937bf57aad3fb74
                                    ATAPRINT_H_CVSID;
  
  
@@@ -697,7 -697,6 +705,10 @@@ static void print_drive_info(const ata_
    pout("ATA Version is:   %s\n", infofound(ataver.c_str()));
  
    // Print Transport specific version
++<<<<<<< HEAD
 +    // cppcheck-suppress variableScope
++=======
++>>>>>>> 3d8ad6fa4529eb02ae1391a1e937bf57aad3fb74
    char buf[32] = "";
    unsigned short word222 = drive->words088_255[222-88];
    if (word222 != 0x0000 && word222 != 0xffff) switch (word222 >> 12) {
@@@ -1543,13 -1542,13 +1554,23 @@@ static void print_device_statistics_pag
        page, offset,
        abs(size),
        valstr,
++<<<<<<< HEAD
 +      ((flags & 0x20) ? 'N' : '-'), // normalized statistics
 +      ((flags & 0x10) ? 'D' : '-'), // supports DSN (ACS-3)
 +      ((flags & 0x08) ? 'C' : '-'), // monitored condition met (ACS-3)
 +      ((flags & 0x07) ? '+' : ' '), // reserved flags
 +      ( info          ? info[i].name :
 +       (page == 0xff) ? "Vendor Specific" // ACS-4
 +                      : "Unknown"        ));
++=======
+       (flags & 0x20 ? 'N' : '-'), // normalized statistics
+       (flags & 0x10 ? 'D' : '-'), // supports DSN (ACS-3)
+       (flags & 0x08 ? 'C' : '-'), // monitored condition met (ACS-3)
+       (flags & 0x07 ? '+' : ' '), // reserved flags
+       (info         ? info[i].name :
+        page == 0xff ? "Vendor Specific" // ACS-4
+                     : "Unknown"        ));
++>>>>>>> 3d8ad6fa4529eb02ae1391a1e937bf57aad3fb74
    }
  }
  
diff --cc autogen.sh
index f73610bf706599e327d348812090df5e1cf8a3fe,caf17449e8e87478283033b28cf0590701e372ad..e22ca8f6ee65b23750ecec807e9a15dda433a768
@@@ -1,7 -1,7 +1,11 @@@
  #!/bin/sh
++<<<<<<< HEAD
 +# $Id: autogen.sh 4115 2015-07-15 20:52:26Z chrfranke $
++=======
+ # $Id: autogen.sh 4053 2015-04-14 20:18:50Z chrfranke $
++>>>>>>> 3d8ad6fa4529eb02ae1391a1e937bf57aad3fb74
  #
 -# Generate ./configure from config.in and Makefile.in from Makefile.am.
 +# Generate ./configure from configure.ac 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
@@@ -23,40 -23,77 +27,62 @@@ test -x /usr/bin/uname && /usr/bin/unam
      rm -f dostest.tmp
  }
  
 -typep()
 -{
 -    cmd=$1 ; TMP=$IFS ; IFS=: ; set $PATH
 -    for dir
 -    do
 -      if [ -x "$dir/$cmd" ]; then
 -          echo "$dir/$cmd"
 -          IFS=$TMP
 -          return 0
 -        fi
 -    done
 -    IFS=$TMP
 -    return 1
 -}
 +# Find automake
 +if [ -n "$AUTOMAKE" ]; then
 +  ver=$("$AUTOMAKE" --version) || exit 1
 +else
 +  maxver=
 +  for v in 1.15 1.14 1.13 1.12 1.11 1.10; do
 +    minver=$v; test -n "$maxver" || maxver=$v
 +    ver=$(automake-$v --version 2>/dev/null) || continue
 +    AUTOMAKE="automake-$v"
 +    break
 +  done
 +  if [ -z "$AUTOMAKE" ]; then
 +    echo "GNU Automake $minver (up to $maxver) is required to bootstrap smartmontools from SVN."
 +    exit 1;
 +  fi
 +fi
  
++<<<<<<< HEAD
 +ver=$(echo "$ver" | sed -n '1s,^.*[^.0-9]\([12]\.[0-9][-.0-9pl]*\).*$,\1,p')
 +if [ -z "$ver" ]; then
 +  echo "$AUTOMAKE: Unable to determine automake version."
 +  exit 1
 +fi
++=======
+ test -x "$AUTOMAKE" ||
+     AUTOMAKE=`typep automake-1.15` || 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.15) 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.15) 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;
+ }
++>>>>>>> 3d8ad6fa4529eb02ae1391a1e937bf57aad3fb74
  
 -test -x "$ACLOCAL" || ACLOCAL="aclocal`echo "$AUTOMAKE" | sed 's/.*automake//'`" && ACLOCAL=`typep "$ACLOCAL"` ||
 -{
 -echo
 -echo "autogen.sh found automake-1.X, but not the respective aclocal-1.X."
 -echo "Your installation of GNU Automake is broken or incomplete."
 -exit 2;
 -}
 +# Check aclocal
 +if [ -z "$ACLOCAL" ]; then
 +  ACLOCAL="aclocal$(echo "$AUTOMAKE" | sed -n 's,^.*automake\(-[.0-9]*\),\1,p')"
 +fi
  
 -# Detect Automake version
 -case "$AUTOMAKE" in
 -  *automake-1.7|*automake17)
 -    ver=1.7 ;;
 -  *automake-1.8)
 -    ver=1.8 ;;
 -  *)
 -    ver="`$AUTOMAKE --version | sed -n '1s,^.*[^.0-9]\([12]\.[0-9][-.0-9pl]*\).*$,\1,p'`"
 -    ver="${ver:-?.?.?}"
 -esac
 +"$ACLOCAL" --version >/dev/null || exit 1
  
 -# Warn if Automake version was not tested or does not support filesystem
 +# Warn if Automake version was not tested
  amwarnings=$warnings
  case "$ver" in
 -  1.[78]|1.[78].*)
 -    # Check for case sensitive filesystem
 -    # (to avoid e.g. "DIST_COMMON = ... ChangeLog ..." in Makefile.in on Cygwin)
 -    rm -f CASETEST.TMP
 -    echo > casetest.tmp
 -    test -f CASETEST.TMP &&
 -    {
 -      echo "Warning: GNU Automake version ${ver} does not properly handle case"
 -      echo "insensitive filesystems. Some make targets may not work."
 -    }
 -    rm -f casetest.tmp
 -    ;;
 -
 -  1.9.[1-6]|1.10|1.10.[123]|1.11|1.11.[1-6]|1.12.[2-6]|1.13.[34])
 +  1.10|1.10.[123]|1.11|1.11.[1-6]|1.12.[2-6]|1.13.[34])
      # OK
      ;;
  
      echo "Please report success/failure to the smartmontools-support mailing list."
  esac
  
++<<<<<<< HEAD
 +# required for aclocal-1.10 --install
++=======
+ # Warn if Automake version is too old
+ case "$ver" in
+   1.[789]|1.[789].*)
+     echo "WARNING:"
+     echo "The use of GNU Automake version $ver is deprecated.  Support for Automake"
+     echo "versions 1.7 - 1.9.x will be removed in a future release of smartmontools."
+ esac
+ # Install pkg-config macros
+ # (Don't use 'aclocal -I m4 --install' to keep support for automake < 1.10)
++>>>>>>> 3d8ad6fa4529eb02ae1391a1e937bf57aad3fb74
  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" &&
 -{
 -  echo "$0: installing \`m4/pkg.m4' from \`$acdir/pkg.m4'"
 -  cp "$acdir/pkg.m4" m4/pkg.m4
 -}
 -test -f m4/pkg.m4 ||
 -  echo "Warning: cannot install m4/pkg.m4, 'make dist' and systemd detection will not work."
  
  set -e        # stops on error status
  
diff --cc configure.ac
index f0d47338198bb05a0c40b02c1604918c2a64e7e9,804291f1e74f1d6c9b91d10e44eae6fed18f27c9..58e56175f39d61740b69a2b1861a3984f62d2a99
@@@ -1,14 -1,14 +1,24 @@@
  #
++<<<<<<< HEAD
 +# $Id: configure.ac 4319 2016-05-07 12:14:20Z chrfranke $
++=======
+ # $Id: configure.ac 4109 2015-06-04 16:30:15Z chrfranke $
++>>>>>>> 3d8ad6fa4529eb02ae1391a1e937bf57aad3fb74
  #
  dnl Process this file with autoconf to produce a configure script.
 -AC_PREREQ(2.50)
 -AC_INIT(smartmontools, 6.4, smartmontools-support@lists.sourceforge.net)
 -AC_CONFIG_SRCDIR(smartctl.cpp)
 -
 +AC_PREREQ([2.60])
 +AC_INIT(smartmontools, 6.6, smartmontools-support@lists.sourceforge.net)
 +AM_INIT_AUTOMAKE([1.10 foreign])
 +
++<<<<<<< HEAD
 +smartmontools_cvs_tag=`echo '$Id: configure.ac 4319 2016-05-07 12:14:20Z chrfranke $'`
 +smartmontools_release_date=2016-05-07
 +smartmontools_release_time="11:17:46 UTC"
++=======
+ smartmontools_cvs_tag=`echo '$Id: configure.ac 4109 2015-06-04 16:30:15Z chrfranke $'`
+ smartmontools_release_date=2015-06-04
+ smartmontools_release_time="16:29:41 UTC"
++>>>>>>> 3d8ad6fa4529eb02ae1391a1e937bf57aad3fb74
  
  AC_DEFINE_UNQUOTED(SMARTMONTOOLS_CONFIGURE_ARGS, "$ac_configure_args",            [smartmontools Configure Arguments])
  AC_DEFINE_UNQUOTED(SMARTMONTOOLS_RELEASE_DATE,   "$smartmontools_release_date",   [smartmontools Release Date])
@@@ -232,24 -231,34 +242,53 @@@ case "${host}" i
  esac
  AC_SUBST(initdfile)
  
++<<<<<<< HEAD
++=======
+ autoconf_25x=${docdir:-yes}
+ AC_ARG_WITH(docdir,
+   [AS_HELP_STRING([--with-docdir=DIR], [Deprecated (use --docdir=DIR instead)])],
+   [docdir="$withval"],
+   [ if test -z "$docdir"; then
+       # autoconf 2.5x without '--docdir' support
+       docdir='${datadir}/doc/${PACKAGE}'
+     fi
+   ])
+ AC_SUBST(docdir)
++>>>>>>> 3d8ad6fa4529eb02ae1391a1e937bf57aad3fb74
  AC_ARG_WITH(exampledir,
    [AS_HELP_STRING([--with-exampledir=DIR], [Location of example scripts [DOCDIR/examplescripts]])],
    [exampledir="$withval"], [exampledir='${docdir}/examplescripts'])
  AC_SUBST(exampledir)
  
++<<<<<<< HEAD
 +drivedbdir='${datadir}/${PACKAGE}'
 +AC_ARG_WITH(drivedbdir,
 +  [AS_HELP_STRING([--with-drivedbdir@<:@=DIR|yes|no@:>@], [Location of drive database file [DATADIR/smartmontools]])],
 +  [case "$withval" in yes) ;; no) drivedbdir= ;; *) drivedbdir="$withval" ;; esac])
 +AC_SUBST(drivedbdir)
 +AM_CONDITIONAL(ENABLE_DRIVEDB, [test -n "$drivedbdir"])
 +
 +AC_ARG_WITH(update-smart_drivedb,
 +  [AS_HELP_STRING([--with-update-smart-drivedb@<:@=yes|no@:>@], [Install update-smart-drivedb script [yes]])],
 +  [], [with_update_smart_drivedb=yes])
 +test -n "$drivedbdir" || with_update_smart_drivedb=no
 +AC_SUBST(with_update_smart_drivedb)
 +AM_CONDITIONAL(ENABLE_UPDATE_SMART_DRIVEDB, [test "$with_update_smart_drivedb" = "yes"])
++=======
+ used_deprecated_option=no
+ AC_ARG_ENABLE(drivedb,
+   [AS_HELP_STRING([--disable-drivedb], [Deprecated (use --without-drivedbdir instead)])],
+   [used_deprecated_option=yes], [enable_drivedb=yes])
+ drivedbdir=
+ AC_ARG_WITH(drivedbdir,
+   [AS_HELP_STRING([--with-drivedbdir=@<:@DIR|no@:>@], [Location of drive database file [DATADIR/smartmontools]])],
+   [test "$withval" != "no" && drivedbdir="$withval"],
+   [test "$enable_drivedb" != "no" && drivedbdir='${datadir}/${PACKAGE}'])
+ AC_SUBST(drivedbdir)
+ AM_CONDITIONAL(ENABLE_DRIVEDB, [test -n "$drivedbdir"])
++>>>>>>> 3d8ad6fa4529eb02ae1391a1e937bf57aad3fb74
  
  AC_ARG_WITH(smartdscriptdir,
    [AS_HELP_STRING([--with-smartdscriptdir=DIR], [Location of smartd_warning.sh script [SYSCONFDIR]])],
@@@ -263,23 -272,31 +302,50 @@@ AC_ARG_WITH(smartdplugindir
    [smartdplugindir='${smartdscriptdir}/smartd_warning.d'])
  AC_SUBST(smartdplugindir)
  
++<<<<<<< HEAD
 +savestates=
 +AC_ARG_WITH(savestates,
 +  [AS_HELP_STRING([--with-savestates@<:@=PREFIX|yes|no@:>@],
 +    [Enable default smartd state files [no] (yes=LOCALSTATEDIR/lib/smartmontools/smartd.)])],
 +  [case "$withval" in yes) savestates='${localstatedir}/lib/${PACKAGE}/smartd.' ;;
 +                      no) ;; *) savestates="$withval" ;; esac])
++=======
+ AC_ARG_ENABLE(savestates,
+   [AS_HELP_STRING([--enable-savestates], [Deprecated (use --with-savestates@<:@=yes@:>@ instead)])],
+   [used_deprecated_option=yes], [enable_savestates=no])
+ savestates='${localstatedir}/lib/${PACKAGE}/smartd.'
+ AC_ARG_WITH(savestates,
+   [AS_HELP_STRING([--with-savestates@<:@=PREFIX|yes|no@:>@],
+     [Enable default smartd state files [no] (yes=LOCALSTATEDIR/lib/smartmontools/smartd.)])],
+   [case "$withval" in yes) ;; no) savestates= ;; *) savestates="$withval" ;; esac],
+   [test "$enable_savestates" != "yes" && savestates=])
++>>>>>>> 3d8ad6fa4529eb02ae1391a1e937bf57aad3fb74
  savestatesdir="${savestates%/*}"
  AC_SUBST(savestates)
  AC_SUBST(savestatesdir)
  AM_CONDITIONAL(ENABLE_SAVESTATES, [test -n "$savestates"])
++<<<<<<< HEAD
 +
 +attributelog=
 +AC_ARG_WITH(attributelog,
 +  [AS_HELP_STRING([--with-attributelog@<:@=PREFIX|yes|no@:>@],
 +    [Enable default smartd attribute log files [no] (yes=LOCALSTATEDIR/lib/smartmontools/attrlog.)])],
 +  [case "$withval" in yes) attributelog='${localstatedir}/lib/${PACKAGE}/attrlog.' ;;
 +                      no) ;; *) attributelog="$withval" ;; esac])
++=======
+ AC_ARG_ENABLE(attributelog,
+   [AS_HELP_STRING([--enable-attributelog], [Deprecated (use --with-attributelog@<:@=yes@:>@ instead)])],
+   [used_deprecated_option=yes], [enable_attributelog=no])
+ attributelog='${localstatedir}/lib/${PACKAGE}/attrlog.'
+ AC_ARG_WITH(attributelog,
+   [AS_HELP_STRING([--with-attributelog@<:@=PREFIX|yes|no@:>@],
+     [Enable default smartd attribute log files [no] (yes=LOCALSTATEDIR/lib/smartmontools/attrlog.)])],
+   [case "$withval" in yes) ;; no) attributelog= ;; *) attributelog="$withval" ;; esac],
+   [test "$enable_attributelog" != "yes" && attributelog=])
++>>>>>>> 3d8ad6fa4529eb02ae1391a1e937bf57aad3fb74
  attributelogdir="${attributelog%/*}"
  AC_SUBST(attributelog)
  AC_SUBST(attributelogdir)
@@@ -392,42 -385,13 +458,50 @@@ if test "$libc_have_working_snprintf" 
    AC_DEFINE(HAVE_WORKING_SNPRINTF, 1, [Define to 1 if the `snprintf' function is sane.]) dnl `vim syntax
  fi
  
++<<<<<<< HEAD
 +os_win32_manifest=
 +case "$host" in
 +  *-*-mingw*)
 +    # Newer MinGW may add a default manifest
 +    AC_MSG_CHECKING([whether $CC adds an application manifest])
 +    cc_adds_manifest=no
 +    AC_LINK_IFELSE([AC_LANG_PROGRAM()], [
 +        if "$WINDRES" -O rc conftest.exe 2>/dev/null | grep '^1.*RT_MANIFEST' >/dev/null 2>&1; then
 +          cc_adds_manifest=incomplete
 +          # Manifest must provide a Win 10 compatibility ID
 +          if "$WINDRES" -O rc conftest.exe 2>/dev/null | grep '{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}' >/dev/null 2>&1; then
 +            cc_adds_manifest=yes
 +          fi
 +        fi],
 +      [AC_MSG_ERROR([test compile failed])])
 +    AC_MSG_RESULT([$cc_adds_manifest])
 +    test "$cc_adds_manifest" = "yes" || os_win32_manifest='default.manifest.o'
 +    ;;
 +esac
 +
 +# TODO: Remove after smartmontools 6.5
 +AC_ARG_WITH(docdir,
 +  [AS_HELP_STRING([--with-docdir=DIR], [(removed, use --docdir=DIR instead)])],
 +  [AC_MSG_ERROR([--with-docdir is no longer supported, use --docdir instead])])
 +AC_ARG_ENABLE(drivedb,
 +  [AS_HELP_STRING([--disable-drivedb], [(removed, use --without-drivedbdir instead)])])
 +AC_ARG_ENABLE(savestates,
 +  [AS_HELP_STRING([--enable-savestates], [(removed, use --with-savestates@<:@=yes@:>@ instead)])])
 +AC_ARG_ENABLE(attributelog,
 +  [AS_HELP_STRING([--enable-attributelog], [(removed, use --with-attributelog@<:@=yes@:>@ instead)])])
 +if test -n "${enable_drivedb+set}${enable_savestates+set}${enable_attributelog+set}"; then
 +  AC_MSG_ERROR([Options --disable-drivedb, --enable-savestates, --enable-attributelog are no longer supported.
 +Use --without-drivedbdir, --with-savestates, --with-attributelog instead.])
++=======
+ if test "$prefix" = "NONE"; then
+     # Fix mandir default set by autoconf 2.5x
+     if test "$mandir" = '${prefix}/man'; then
+       AC_SUBST([mandir], ['${prefix}/share/man'])
+     fi
++>>>>>>> 3d8ad6fa4529eb02ae1391a1e937bf57aad3fb74
  fi
  
 +
  AC_SUBST(releaseversion,['${PACKAGE}-${VERSION}'])
  AC_SUBST(smartmontools_release_date)
  AC_SUBST(smartmontools_release_time)
@@@ -602,125 -563,102 +676,146 @@@ AC_CONFIG_FILES(Makefile
  AC_OUTPUT
  AC_PROG_MAKE_SET
  
 -echo "-----------------------------------------------------------------------------" >&AS_MESSAGE_FD
 -echo "${PACKAGE}-${VERSION} configuration:" >&AS_MESSAGE_FD
 -echo "host operating system:  $host" >&AS_MESSAGE_FD
 -echo "C++ compiler:           $CXX" >&AS_MESSAGE_FD
 -echo "C compiler:             $CC" >&AS_MESSAGE_FD
 -echo "preprocessor flags:     $CPPFLAGS" >&AS_MESSAGE_FD
 -echo "C++ compiler flags:     $CXXFLAGS" >&AS_MESSAGE_FD
 -echo "C compiler flags:       $CFLAGS" >&AS_MESSAGE_FD
 -echo "linker flags:           $LDFLAGS" >&AS_MESSAGE_FD
 -echo "OS specific modules:    $os_deps $os_libs $LIBS" >&AS_MESSAGE_FD
 -
 -case "$host_os" in
 -  mingw*)
 -    echo "resource compiler:      $WINDRES" >&AS_MESSAGE_FD
 -    echo "message compiler:       $WINDMC" >&AS_MESSAGE_FD
 -    echo "NSIS compiler:          $MAKENSIS" >&AS_MESSAGE_FD
 -    if test -n "$drivedbdir"; then
 -      echo "drive database file:    EXEDIR/drivedb.h" >&AS_MESSAGE_FD
 -      if test -n "$MAKENSIS"; then
 -        echo "database update tool:   EXEDIR/update-smart-drivedb.exe" >&AS_MESSAGE_FD
 +# Note: Use `...` here as some shells do not properly parse '$(... case $x in X) ...)'
 +info=`
 +  echo "-----------------------------------------------------------------------------"
 +  echo "${PACKAGE}-${VERSION} configuration:"
 +  echo "host operating system:  $host"
 +  echo "C++ compiler:           $CXX"
 +  echo "C compiler:             $CC"
 +  echo "preprocessor flags:     $CPPFLAGS"
 +  echo "C++ compiler flags:     $CXXFLAGS"
 +  echo "C compiler flags:       $CFLAGS"
 +  echo "linker flags:           $LDFLAGS"
 +  echo "OS specific modules:    $os_deps $os_libs $LIBS"
 +
 +  case "$host_os" in
 +    mingw*)
 +      echo "application manifest:   ${os_win32_manifest:-built-in}"
 +      echo "resource compiler:      $WINDRES"
 +      echo "message compiler:       $WINDMC"
 +      echo "NSIS compiler:          $MAKENSIS"
 +      if test -n "$drivedbdir"; then
 +        echo "drive database file:    EXEDIR/drivedb.h"
 +        if test -n "$MAKENSIS"; then
 +          echo "database update tool:   EXEDIR/update-smart-drivedb.exe"
 +        fi
 +      else
 +        echo "drive database file:    [[disabled]]"
        fi
 -    else
 -      echo "drive database file:    [[disabled]]" >&AS_MESSAGE_FD
 -    fi
 -    if test -n "$savestates"; then
 -      echo "smartd save files:      `eval eval eval echo $savestates`MODEL-SERIAL.TYPE.state" >&AS_MESSAGE_FD
 -    fi
 -    if test -n "$attributelog"; then
 -      echo "smartd attribute logs:  `eval eval eval echo $attributelog`MODEL-SERIAL.TYPE.csv" >&AS_MESSAGE_FD
 -    fi
 -    ;;
 -
 -  *)
 -    echo "binary install path:    `eval eval eval echo $sbindir`" >&AS_MESSAGE_FD
 -    echo "man page install path:  `eval eval eval echo $mandir`" >&AS_MESSAGE_FD
 -    echo "doc file install path:  `eval eval eval echo $docdir`" >&AS_MESSAGE_FD
 -    echo "examples install path:  `eval eval eval echo $exampledir`" >&AS_MESSAGE_FD
 -    if test -n "$drivedbdir"; then
 -      echo "drive database file:    `eval eval eval echo $drivedbdir`/drivedb.h" >&AS_MESSAGE_FD
 -      echo "database update script: `eval eval eval echo $sbindir`/update-smart-drivedb" >&AS_MESSAGE_FD
 -      echo "download tools:         `eval eval eval echo $os_dltools`" >&AS_MESSAGE_FD
 -    else
 -      echo "drive database file:    [[disabled]]" >&AS_MESSAGE_FD
 -    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 $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
 -      echo "smartd initd script:    [[disabled]]" >&AS_MESSAGE_FD
 -    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
 +      if test -n "$savestates"; then
 +        echo "smartd save files:      \`eval eval eval echo $savestates\`MODEL-SERIAL.TYPE.state"
 +      fi
 +      if test -n "$attributelog"; then
 +        echo "smartd attribute logs:  \`eval eval eval echo $attributelog\`MODEL-SERIAL.TYPE.csv"
 +      fi
 +      echo "NVMe DEVICESCAN:        ${with_nvme_devicescan-no}"
 +      ;;
 +
 +    *)
 +      echo "binary install path:    \`eval eval eval echo $sbindir\`"
 +      echo "man page install path:  \`eval eval eval echo $mandir\`"
 +      echo "doc file install path:  \`eval eval eval echo $docdir\`"
 +      echo "examples install path:  \`eval eval eval echo $exampledir\`"
 +      if test -n "$drivedbdir"; then
 +        echo "drive database file:    \`eval eval eval echo $drivedbdir\`/drivedb.h"
 +        if test "$with_update_smart_drivedb" = "yes"; then
 +          echo "database update script: \`eval eval eval echo $sbindir\`/update-smart-drivedb"
 +          echo "download tools:         \`eval eval eval echo $os_dltools\`"
 +        else
 +          echo "database update script: [[disabled]]"
 +        fi
        else
 -        echo "smartd environ file:    [[disabled]]" >&AS_MESSAGE_FD
 +        echo "drive database file:    [[disabled]]"
        fi
 -    fi
 -    if test -n "$savestates"; then
 -      echo "smartd save files:      `eval eval eval echo $savestates`MODEL-SERIAL.TYPE.state" >&AS_MESSAGE_FD
 -    else
 -      echo "smartd save files:      [[disabled]]" >&AS_MESSAGE_FD
 -    fi
 -    if test -n "$attributelog"; then
 -      echo "smartd attribute logs:  `eval eval eval echo $attributelog`MODEL-SERIAL.TYPE.csv" >&AS_MESSAGE_FD
 -    else
 -      echo "smartd attribute logs:  [[disabled]]" >&AS_MESSAGE_FD
 -    fi
 -    echo "libcap-ng support:      $use_libcap_ng" >&AS_MESSAGE_FD
 -    case "$host_os" in
 -      linux*) echo "SELinux support:        ${with_selinux-no}" >&AS_MESSAGE_FD ;;
 -    esac
 +      echo "local drive database:   \`eval eval eval echo $sysconfdir\`/smart_drivedb.h"
 +      echo "smartd config file:     \`eval eval eval echo $sysconfdir\`/smartd.conf${smartd_suffix}"
 +      echo "smartd warning script:  \`eval eval eval echo $smartdscriptdir\`/smartd_warning.sh"
 +      if test -n "$smartdplugindir"; then
 +        echo "smartd plugin path:     \`eval eval eval echo $smartdplugindir\`"
 +      else
 +        echo "smartd plugin path:     [[disabled]]"
 +      fi
 +      if test -n "$initddir"; then
 +        echo "smartd initd script:    \`eval eval eval echo $initddir\`/${initdfile}"
 +      elif test -z "$systemdsystemunitdir"; then
 +        echo "smartd initd script:    [[disabled]]"
 +      fi
 +      if test -n "$systemdsystemunitdir"; then
 +        echo "smartd systemd file:    \`eval eval eval echo $systemdsystemunitdir\`/smartd.service"
 +        if test -n "$systemdenvfile"; then
 +          echo "smartd environ file:    \`eval eval eval echo $systemdenvfile\`"
 +        else
 +          echo "smartd environ file:    [[disabled]]"
 +        fi
 +      fi
 +      if test -n "$savestates"; then
 +        echo "smartd save files:      \`eval eval eval echo $savestates\`MODEL-SERIAL.TYPE.state"
 +      else
 +        echo "smartd save files:      [[disabled]]"
 +      fi
 +      if test -n "$attributelog"; then
 +        echo "smartd attribute logs:  \`eval eval eval echo $attributelog\`MODEL-SERIAL.TYPE.csv"
 +      else
 +        echo "smartd attribute logs:  [[disabled]]"
 +      fi
 +      echo "libcap-ng support:      $use_libcap_ng"
 +      case "$host_os" in
 +        linux*) echo "SELinux support:        ${with_selinux-no}" ;;
 +      esac
 +      case "$host_os" in
 +        linux*|cygwin*) echo "NVMe DEVICESCAN:        ${with_nvme_devicescan-no}" ;;
 +      esac
 +      ;;
 +  esac
 +  echo "-----------------------------------------------------------------------------"
 +`
 +
 +AC_MSG_NOTICE([
 +$info
 +])
 +
 +# TODO: Remove when NVMe support is no longer EXPERIMENTAL
 +case "$host_os:${with_nvme_devicescan+set}" in
 +  linux*:|cygwin*:|mingw*:)
 +    AC_MSG_WARN([
 +This version of smartmontools provides NVMe support which is still
 +EXPERIMENTAL.  NVMe devices are not yet included in smartd.conf
 +'DEVICESCAN' and 'smartctl --scan' unless '-d nvme' is specified.
 +Use option '--with-nvme-devicescan' to include NVMe devices.
 +Use option '--without-nvme-devicescan' to suppress this warning.])
 +    ;;
 +esac
 +
 +# TODO: Remove after smartmontools 6.5
 +case "$host:${with_solaris_sparc_ata+set}" in
 +  sparc-*-solaris*:)
 +    AC_MSG_WARN([
 +Legacy ATA support is no longer enabled by default on Solaris SPARC.
 +The required source file 'os_solaris_ata.s' is no longer included in
 +the source tarball but still available in the SVN repository.
 +Use option '--with-solaris-sparc-ata' to enable legacy ATA support.
 +Use option '--without-solaris-sparc-ata' to suppress this warning.])
      ;;
  esac
++<<<<<<< HEAD
++=======
+ echo "-----------------------------------------------------------------------------" >&AS_MESSAGE_FD
+ if test "$autoconf_25x" = "yes"; then
+  echo "WARNING:" >&AS_MESSAGE_FD
+  echo "Support for old autoconf 2.5x versions will be removed in a future" >&AS_MESSAGE_FD
+  echo "release of smartmontools." >&AS_MESSAGE_FD
+ elif test "${with_docdir+set}" = "set"; then
+  echo "WARNING:" >&AS_MESSAGE_FD
+  echo "Option --with-docdir is deprecated and will be removed in a future" >&AS_MESSAGE_FD
+  echo "release of smartmontools.  Use --docdir instead." >&AS_MESSAGE_FD
+ fi
+ if test "$used_deprecated_option" = "yes"; then
+   echo "WARNING:" >&AS_MESSAGE_FD
+   echo "Options --disable-drivedb, --enable-savestates, --enable-attributelog are" >&AS_MESSAGE_FD
+   echo "deprecated and will be removed in a future release of smartmontools." >&AS_MESSAGE_FD
+   echo "Use --without-drivedb, --with-savestates, --with-attributelog instead." >&AS_MESSAGE_FD
+ fi
++>>>>>>> 3d8ad6fa4529eb02ae1391a1e937bf57aad3fb74
diff --cc drivedb.h
index 65c1c4527fa0b78cca0519148de2f3848e9870fa,0a4336ba3ddc07178a73c9eb75cba8f40fc11408..b61d0283812821c2c1723fc8487b173eb4839f83
+++ b/drivedb.h
@@@ -1,10 -1,10 +1,14 @@@
  /*
   * drivedb.h - smartmontools drive database file
   *
 - * Home page of code is: http://smartmontools.sourceforge.net
 + * Home page of code is: http://www.smartmontools.org
   *
   * Copyright (C) 2003-11 Philip Williams, Bruce Allen
++<<<<<<< HEAD
 + * Copyright (C) 2008-16 Christian Franke
++=======
+  * Copyright (C) 2008-15 Christian Franke
++>>>>>>> 3d8ad6fa4529eb02ae1391a1e937bf57aad3fb74
   *
   * 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
  /*
  const drive_settings builtin_knowndrives[] = {
   */
++<<<<<<< HEAD
 +  { "$Id: drivedb.h 4324 2016-05-31 20:45:50Z chrfranke $",
++=======
+   { "$Id: drivedb.h 4105 2015-06-03 19:32:30Z chrfranke $",
++>>>>>>> 3d8ad6fa4529eb02ae1391a1e937bf57aad3fb74
      "-", "-",
      "This is a dummy entry to hold the SVN-Id of drivedb.h",
      ""
    },
    { "Crucial/Micron MX100/MX200/M5x0/M600 Client SSDs",
      "Crucial_CT(128|256|512)MX100SSD1|"// tested with Crucial_CT256MX100SSD1/MU01
++<<<<<<< HEAD
 +    "Crucial_CT(200|250|256|500|512|1000|1024)MX200SSD[1346]|" // tested with Crucial_CT500MX200SSD1/MU01,
 +      // Crucial_CT1024MX200SSD1/MU01, Crucial_CT250MX200SSD3/MU01, Crucial_CT250MX200SSD1/MU03
 +    "Crucial_CT(120|240|480|960)M500SSD[134]|" // tested with Crucial_CT960M500SSD1/MU03,
 +      // Crucial_CT240M500SSD4/MU05
 +    "Crucial_CT(128|256|512|1024)M550SSD[13]|" // tested with Crucial_CT512M550SSD3/MU01,
 +      // Crucial_CT1024M550SSD1/MU01
++=======
+     "Crucial_CT(200|256|500|512|1000|1024)MX200SSD[1346]|" // tested with Crucial_CT500MX200SSD1/MU01,
+       // Crucial_CT1024MX200SSD1/MU01
+     "Crucial_CT(120|240|480|960)M500SSD1|" // tested with Crucial_CT960M500SSD1/MU03
+     "Crucial_CT(128|256|512|1024)M550SSD[13]|" // tested with Crucial_CT512M550SSD3/MU01, Crucial_CT1024M550SSD1/MU01
++>>>>>>> 3d8ad6fa4529eb02ae1391a1e937bf57aad3fb74
      "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
      "KINGSTON SMS200S3(30|60|120)G|" // mSATA, SF-2241, tested with SMS200S3120G/KC3ABBF0
      "KINGSTON SMS450S3(32|64|128)G|" // mSATA, SF-2281, tested with SMS450S3128G/503ABBF0
      "KINGSTON (SV300|SKC100|SE100)S3.*G|" // other SF-2281
++<<<<<<< HEAD
 +    "MKNSSDCR(45|60|90|120|180|240|360|480)GB(-(7|DX7?|MX|G2))?|" // Mushkin Chronos (7mm/Deluxe/MX/G2),
 +      // SF-2281, tested with MKNSSDCR120GB, MKNSSDCR120GB-MX/560ABBF0, MKNSSDCR480GB-DX7/603ABBF0
 +    "MKNSSDEC(60|120|240|480|512)GB|" // Mushkin Enhanced ECO2, tested with MKNSSDEC120GB/604ABBF0
++=======
+     "MKNSSDCR(45|60|90|120|180|240|480)GB(-[DM]X)?|" // Mushkin Chronos (Deluxe/Enhanced), SF-2281,
+       // tested with MKNSSDCR120GB, MKNSSDCR120GB-MX/560ABBF0
++>>>>>>> 3d8ad6fa4529eb02ae1391a1e937bf57aad3fb74
      "MKNSSDAT(30|40|60|120|180|240|480)GB(-(DX|V))?|" // Mushkin Atlas (Deluxe/Value), mSATA, SF-2281,
        // tested with MKNSSDAT120GB-V/540ABBF0
      "Mushkin MKNSSDCL(40|60|80|90|115|120|180|240|480)GB-DX2?|" // Mushkin Callisto deluxe,
    //"-v 233,raw48,Media_Wearout_Indicator"
    },
    { "Indilinx Barefoot 3 based SSDs",
++<<<<<<< HEAD
 +    "OCZ-VECTOR(1[58]0)?|" // tested with OCZ-VECTOR/1.03, OCZ-VECTOR150/1.2, OCZ-VECTOR180
 +    "OCZ-VERTEX4[56]0A?|" // Barefoot 3 M10, tested with OCZ-VERTEX450/1.0, OCZ-VERTEX460/1.0, VERTEX460A
 +    "OCZ-SABER1000|"
 +    "OCZ-ARC100|"
++=======
+     "OCZ-VECTOR(150)?|" // tested with OCZ-VECTOR/1.03, OCZ-VECTOR150/1.2
+     "OCZ-VERTEX4[56]0|" // Barefoot 3 M10, tested with OCZ-VERTEX450/1.0, OCZ-VERTEX460/1.0
++>>>>>>> 3d8ad6fa4529eb02ae1391a1e937bf57aad3fb74
      "Radeon R7", // Barefoot 3 M00, tested with Radeon R7/1.00
      "", "",
      "-v 5,raw48,Runtime_Bad_Block "
      "-v 233,raw48,Remaining_Lifetime_Perc "
      "-v 241,raw48,Host_Writes_GiB " // M00/M10
      "-v 242,raw48,Host_Reads_GiB "  // M00/M10
++<<<<<<< HEAD
 +    "-v 249,raw48,Total_NAND_Prog_Ct_GiB "
 +    "-v 251,raw48,Total_NAND_Read_Ct_GiB"
 +  },
 +  { "OCZ Intrepid 3000 SSDs", // tested with OCZ INTREPID 3600/1.4.3.6, 3800/1.4.3.0, 3700/1.5.0.4
 +    "OCZ INTREPID 3[678]00",
++=======
+     "-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",
++>>>>>>> 3d8ad6fa4529eb02ae1391a1e937bf57aad3fb74
      "", "",
      "-v 5,raw48,Runtime_Bad_Block "
    //"-v 9,raw24(raw8),Power_On_Hours "
      "-v 236,raw48,Unstable_Power_Count "
      "-v 240,raw48,Write_Head"
    },
++<<<<<<< HEAD
 +  { "Innodisk 3ME SSDs", // tested with 2.5" SATA SSD 3ME/S140714
 +    "((1\\.8|2\\.5)\"? SATA SSD|SATA Slim) 3ME",
 +    "", "",
 +  //"-v 1,raw48,Raw_Read_Error_Rate "
 +  //"-v 2,raw48,Throughput_Performance "
 +  //"-v 3,raw16(avg16),Spin_Up_Time "
 +  //"-v 5,raw48,Reallocated_Sector_Count "
 +    "-v 7,raw48,Seek_Error_Rate "       // ?
 +    "-v 8,raw48,Seek_Time_Performance " // ?
 +  //"-v 9,raw24(raw8),Power_On_Hours "
 +    "-v 10,raw48,Spin_Retry_Count "     // ?
 +  //"-v 12,raw48,Power_Cycle_Count "
 +    "-v 168,raw48,SATA_PHY_Error_Count "
 +    "-v 169,raw48,Unknown_Innodisk_Attr "
 +    "-v 170,raw16,Bad_Block_Count "
 +    "-v 173,raw16,Erase_Count "
 +    "-v 175,raw48,Bad_Cluster_Table_Count "
 +    "-v 176,raw48,Uncorr_RECORD_Count "
 +  //"-v 192,raw48,Power-Off_Retract_Count "
 +  //"-v 194,tempminmax,Temperature_Celsius " // ] only in spec
 +  //"-v 197,raw48,Current_Pending_Sector "
 +    "-v 225,raw48,Unknown_Innodisk_Attr "
 +    "-v 229,hex48,Flash_ID "
 +    "-v 235,raw48,Later_Bad_Block "
 +    "-v 236,raw48,Unstable_Power_Count "
 +    "-v 240,raw48,Write_Head"
 +  },
 +  { "Innodisk 3IE2/3MG2/3SE2-P SSDs", // tested with 2.5" SATA SSD 3MG2-P/M140402,
 +      // 1.8 SATA SSD 3IE2-P/M150821, 2.5" SATA SSD 3IE2-P/M150821,
 +      // SATA Slim 3MG2-P/M141114, M.2 (S80) 3MG2-P/M141114, M.2 (S42) 3SE2-P/M150821
 +    "((1\\.8|2\\.5)\"? SATA SSD|SATA Slim|M\\.2 \\(S(42|80)\\)) 3(IE|MG|SE)2-P",
 +    "", "",
 +  //"-v 1,raw48,Raw_Read_Error_Rate "
 +  //"-v 2,raw48,Throughput_Performance "
 +  //"-v 9,raw24(raw8),Power_On_Hours "
 +  //"-v 12,raw48,Power_Cycle_Count "
 +    "-v 160,raw48,Uncorrectable_Error_Cnt "
 +    "-v 161,raw48,Number_of_Pure_Spare "
 +    "-v 163,raw48,Initial_Bad_Block_Count "
 +    "-v 164,raw48,Total_Erase_Count "
 +    "-v 165,raw48,Max_Erase_Count "
 +    "-v 166,raw48,Min_Erase_Count "
 +    "-v 167,raw48,Average_Erase_Count "
 +    "-v 168,raw48,Max_Erase_Count_of_Spec "
 +    "-v 169,raw48,Remaining_Lifetime_Perc "
 +  //"-v 175,raw48,Program_Fail_Count_Chip "
 +  //"-v 176,raw48,Erase_Fail_Count_Chip "
 +  //"-v 177,raw48,Wear_Leveling_Count "
 +    "-v 178,raw48,Runtime_Invalid_Blk_Cnt "
 +  //"-v 181,raw48,Program_Fail_Cnt_Total "
 +  //"-v 182,raw48,Erase_Fail_Count_Total "
 +  //"-v 187,raw48,Reported_Uncorrect " // ] only in spec
 +  //"-v 192,raw48,Power-Off_Retract_Count "
 +  //"-v 194,tempminmax,Temperature_Celsius "
 +  //"-v 195,raw48,Hardware_ECC_Recovered "
 +  //"-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 225,raw48,Host_Writes_32MiB "  // ]
 +  //"-v 232,raw48,Available_Reservd_Space "
 +    "-v 233,raw48,Flash_Writes_32MiB " // ]
 +    "-v 234,raw48,Flash_Reads_32MiB "  // ]
 +    "-v 241,raw48,Host_Writes_32MiB "
 +    "-v 242,raw48,Host_Reads_32MiB "
 +    "-v 245,raw48,Flash_Writes_32MiB"
 +  },
 +  { "Innodisk 3IE3/3ME3 SSDs", // tested with 2.5" SATA SSD 3ME3/S15A19, CFast 3ME3/S15A19
 +      // InnoDisk Corp. - mSATA 3ME3/S15A19, mSATA mini 3ME3/S15A19, M.2 (S42) 3ME3,
 +      // SATA Slim 3ME3/S15A19, SATADOM-MH 3ME3/S15A19, SATADOM-ML 3ME3/S15A19,
 +      // SATADOM-MV 3ME3/S15A19, SATADOM-SL 3ME3/S15A19, SATADOM-SV 3ME3/S15A19,
 +      // SATADOM-SL 3IE3/S151019N, 2.5" SATA SSD 3IE3/S15C14i, CFast 3IE3/S15C14i,
 +      // InnoDisk Corp. - mSATA 3IE3/S15C14i, Mini PCIeDOM 1IE3/S15C14i,
 +      // mSATA mini 3IE3/S15C14i, M.2 (S42) 3IE3/S15C14i, SATA Slim 3IE3/S15C14i,
 +      // SATADOM-SH 3IE3 V2/S15C14i, SATADOM-SL 3IE3 V2/S15A19i, SATADOM-SV 3IE3 V2/S15C14i
 +    "(2.5\" SATA SSD|CFast|InnoDisk Corp\\. - mSATA|Mini PCIeDOM|mSATA mini|"
 +    "M\\.2 \\(S42\\)|SATA Slim|SATADOM-[MS][HLV]) 3[IM]E3( V2)?",
 +    "", "",
 +  //"-v 1,raw48,Raw_Read_Error_Rate "
 +  //"-v 2,raw48,Throughput_Performance "
 +  //"-v 3,raw16(avg16),Spin_Up_Time "
 +    "-v 5,raw48,Later_Bad_Block "
 +    "-v 7,raw48,Seek_Error_Rate "       // ?
 +    "-v 8,raw48,Seek_Time_Performance " // ?
 +  //"-v 9,raw24(raw8),Power_On_Hours "
 +    "-v 10,raw48,Spin_Retry_Count "     // ?
 +  //"-v 12,raw48,Power_Cycle_Count "
 +    "-v 163,raw48,Total_Bad_Block_Count "
 +    "-v 165,raw48,Max_Erase_Count "
 +    "-v 167,raw48,Average_Erase_Count "
 +    "-v 168,raw48,SATA_PHY_Error_Count "
 +    "-v 169,raw48,Remaining_Lifetime_Perc "
 +    "-v 170,raw48,Spare_Block_Count "
 +    "-v 171,raw48,Program_Fail_Count "
 +    "-v 172,raw48,Erase_Fail_Count "
 +    "-v 175,raw48,Bad_Cluster_Table_Count "
 +    "-v 176,raw48,RANGE_RECORD_Count "
 +  //"-v 187,raw48,Reported_Uncorrect "
 +  //"-v 192,raw48,Power-Off_Retract_Count "
 +  //"-v 194,tempminmax,Temperature_Celsius "
 +  //"-v 197,raw48,Current_Pending_Sector "
 +    "-v 225,raw48,Data_Log_Write_Count "
 +    "-v 229,hex48,Flash_ID "
 +    "-v 232,raw48,Spares_Remaining_Perc "
 +    "-v 235,raw16,Later_Bad_Blk_Inf_R/W/E " // Read/Write/Erase
 +    "-v 240,raw48,Write_Head "
 +    "-v 241,raw48,Host_Writes_32MiB "
 +    "-v 242,raw48,Host_Reads_32MiB"
 +  },
++=======
++>>>>>>> 3d8ad6fa4529eb02ae1391a1e937bf57aad3fb74
    { "InnoDisk iCF 9000 CompactFlash Cards", // tested with InnoDisk Corp. - iCF9000 1GB/140808,
         // ..., InnoDisk Corp. - iCF9000 64GB/140808
      "InnoDisk Corp\\. - iCF9000 (1|2|4|8|16|32|64)GB",
      "-v 228,raw48,Workload_Minutes"
    },
    { "Intel 311/313 Series SSDs", // tested with INTEL SSDSA2VP020G2/2CV102M5,
++<<<<<<< HEAD
 +      // INTEL SSDSA2VP020G3/9CV10379, INTEL SSDMAEXC024G3H/9CV10379
 +    "INTEL SSD(SA2VP|MAEXC)(020|024)G[23]H?",
 +      // SA2VP = 2.5", MAEXC = mSATA, G2 = 311, G3 = 313
++=======
+       // INTEL SSDSA2VP020G3/9CV10379,
+     "INTEL SSDSA2VP(020|024)G[23]", // G3 = 313 Series
++>>>>>>> 3d8ad6fa4529eb02ae1391a1e937bf57aad3fb74
      "", "",
    //"-v 3,raw16(avg16),Spin_Up_Time "
    //"-v 4,raw48,Start_Stop_Count "
      "-v 242,raw48,Host_Reads_32MiB "
      "-v 249,raw48,NAND_Writes_1GiB"
    },
++<<<<<<< HEAD
 +  { "Intel 53x and Pro 2500 Series SSDs", // SandForce SF-2281, tested with
 +      // INTEL SSDSC2BW180A4/DC12, SSDSC2BW240A4/DC12, SSDMCEAW120A4/DC33
 +      // INTEL SSDMCEAW240A4/DC33, SSDSC2BF480A5/TG26, SSDSC2BW240H6/RG21
 +    "INTEL SSD(MCEA|SC2B|SCKJ)[WF](056|080|120|180|240|360|480)(A4|A5|H6)",
 +      // SC2B = 2.5", MCEA = mSATA, SCKJ = M.2; A4 = 530, A5 = Pro 2500, H6 = 535
++=======
+   { "Intel 530 Series SSDs", // tested with INTEL SSDSC2BW180A4/DC12, SSDSC2BW240A4/DC12,
+       // INTEL SSDMCEAW120A4/DC33, INTEL SSDMCEAW240A4/DC33
+     "INTEL SSD(MCEA|SC2B)W(080|120|180|240|360|480)A4", // MCEA = mSATA
++>>>>>>> 3d8ad6fa4529eb02ae1391a1e937bf57aad3fb74
      "", "",
    //"-v 5,raw16(raw16),Reallocated_Sector_Ct "
      "-v 9,msec24hour32,Power_On_Hours_and_Msec "
      "SAMSUNG SSD SM841N (mSATA )?(128|256|512)GB|" // tested with SAMSUNG SSD SM841N mSATA 256GB
      "SAMSUNG 470 Series SSD|"  // tested with SAMSUNG 470 Series SSD 64GB/AXM09B1Q
      "SAMSUNG SSD 830 Series|"  // tested with SAMSUNG SSD 830 Series 64GB/CXM03B1Q
 +    "MZ7PC(512|256|128|064)HA(GH|FU|DR)-000.*|" // probably PM830, tested with SAMSUNG MZ7PC128HAFU-000L1/CXM04L1Q
      "Samsung SSD 840 (PRO )?Series|" // tested with Samsung SSD 840 PRO Series 128GB/DXM04B0Q,
        // Samsung SSD 840 Series/DXT06B0Q
++<<<<<<< HEAD
 +    "Samsung SSD 8[45]0 EVO (mSATA |M\\.2 )?((120|250|500|750)G|1T)B( mSATA)?|" // tested with
 +      // Samsung SSD 840 EVO (120|250|500|750)GB/EXT0AB0Q,
 +      // Samsung SSD 840 EVO (120|250)GB/EXT0BB6Q, 1TB/EXT0BB0Q, 120GB mSATA/EXT41B6Q,
 +      // Samsung SSD 850 EVO 250GB/EMT01B6Q
 +      // Samsung SSD 850 EVO M.2 250GB/EMT21B6Q
 +      // Samsung SSD 850 EVO mSATA 120GB/EMT41B6Q
 +    "Samsung SSD 850 PRO ((128|256|512)G|1T)B|" // tested with Samsung SSD 850 PRO 128GB/EXM01B6Q,
 +      // Samsung SSD 850 PRO 1TB/EXM01B6Q
 +    "SAMSUNG MZ7WD((120|240)H[AC]FV|480HAGM|960HAGP)-00003|" // SM843T Series, tested with
 +      // SAMSUNG MZ7WD120HAFV-00003/DXM85W3Q, SAMSUNG MZ7WD120HCFV-00003/DXM9203Q
 +    "SAMSUNG MZ7GE(240HMGR|(480|960)HMHP)-00003|" // SM853T Series, tested with
 +      // SAMSUNG MZ7GE240HMGR-00003/EXT0303Q
 +    "SAMSUNG MZ7LM(120|240|480|960|1T9|3T8)HC(JM|HP|GR|FD)-.*|" // PM863 Series, tested with
 +      // SAMSUNG MZ7LM960HCHP-0E003/GXT3003Q
 +    "SAMSUNG MZ7KM(120|240|480|960|1T9)HA(JM|HP|GR|FD|JM)-.*|" // SM863, tested with MZ7KM480HAHP-0E005/GXM1003Q
 +    "SAMSUNG MZ[7N]LN(128|256|512)HC(HP|GR|JH)-.*", // PM871 Series, tested with SAMSUNG MZ7LN128HCHP
++=======
+     "Samsung SSD 8[45]0 EVO ((120|250|500)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 SSD 850 EVO 250GB/EMT01B6Q
+     "Samsung SSD 850 PRO ((128|256|512)G|1T)B|" // tested with Samsung SSD 850 PRO 128GB/EXM01B6Q,
+       // Samsung SSD 850 PRO 1TB/EXM01B6Q
+     "SAMSUNG MZ7WD((120|240)HAFV|480HAGM|960HAGP)-00003|" // SM843T Series, tested with
+       // SAMSUNG MZ7WD120HAFV-00003/DXM85W3Q
+     "SAMSUNG MZ7GE(240HMGR|(480|960)HMHP)-00003", // SM853T Series, tested with
+       // SAMSUNG MZ7GE240HMGR-00003/EXT0303Q
++>>>>>>> 3d8ad6fa4529eb02ae1391a1e937bf57aad3fb74
      "", "",
    //"-v 5,raw16(raw16),Reallocated_Sector_Ct "
    //"-v 9,raw24(raw8),Power_On_Hours "
      "-v 235,raw48,POR_Recovery_Count " // 830/840/850 Series
    //"-v 241,raw48,Total_LBAs_Written "
    //"-v 242,raw48,Total_LBAs_Read " // PM851, SM841N
++<<<<<<< HEAD
 +    "-v 243,raw48,SATA_Downshift_Ct " // PM863
 +    "-v 244,raw48,Thermal_Throttle_St " // PM863
 +    "-v 245,raw48,Timed_Workld_Media_Wear " // PM863
 +    "-v 246,raw48,Timed_Workld_RdWr_Ratio " // PM863
 +    "-v 247,raw48,Timed_Workld_Timer " // PM863
 +    "-v 250,raw48,SATA_Iface_Downshift " // from the spec
 +    "-v 251,raw48,NAND_Writes" // PM863
++=======
++>>>>>>> 3d8ad6fa4529eb02ae1391a1e937bf57aad3fb74
    },
    { "Marvell based SanDisk SSDs",
      "SanDisk SD5SG2[0-9]*G1052E|" // X100 (88SS9174), tested with SanDisk SD5SG2256G1052E/10.04.01
      "-v 244,raw48,Thermal_Throttle "
    },
    { "SiliconMotion based SSDs", // SM2246EN (Transcend TS6500)
++<<<<<<< HEAD
 +    "CT(120|250|500|1000)BX100SSD1|" // Crucial BX100, tested with CT250BX100SSD1/MU02,
 +      // CT500BX100SSD1/MU02, CT1000BX100SSD1/MU02
 +    "CT(240|480|960)BX200SSD1|" // Crucial BX200 Solid State Drive, tested with CT480BX200SSD1/MU02.6
 +    "TS((16|32|64|128|256|512)G|1T)(SSD|MSA)(370S?|420I?)|" // Transcend SSD370/420 SATA/mSATA, TS6500,
 +      // tested with TS32GMSA370/20140402, TS16GMSA370/20140516, TS64GSSD370/20140516,
 +      // TS256GSSD370/N0815B, TS256GSSD370S/N1114H, TS512GSSD370S/N1114H, TS32GSSD420I/N1114H
 +    "ADATA SP550", // ADATA SP550/O0803B5a
++=======
+     "TS((16|32|64|128|256|512)G|1T)(SSD|MSA)370", // Transcend SSD370 SATA/mSATA, TS6500, tested with
+       // TS32GMSA370/20140402, TS16GMSA370/20140516, TS64GSSD370/20140516, TS256GSSD370/N0815B
++>>>>>>> 3d8ad6fa4529eb02ae1391a1e937bf57aad3fb74
      "", "",
    //"-v 1,raw48,Raw_Read_Error_Rate "
    //"-v 2,raw48,Throughput_Performance "
    //"-v 9,raw24(raw8),Power_On_Hours "
    //"-v 12,raw48,Power_Cycle_Count "
++<<<<<<< HEAD
 +    "-v 148,raw48,Total_SLC_Erase_Ct "
 +    "-v 149,raw48,Max_SLC_Erase_Ct "
 +    "-v 150,raw48,Min_SLC_Erase_Ct "
 +    "-v 151,raw48,Average_SLC_Erase_Ct "
++=======
++>>>>>>> 3d8ad6fa4529eb02ae1391a1e937bf57aad3fb74
      "-v 160,raw48,Uncorrectable_Error_Cnt "
      "-v 161,raw48,Valid_Spare_Block_Cnt "
      "-v 163,raw48,Initial_Bad_Block_Count "
    //"-v 232,raw48,Available_Reservd_Space "
      "-v 241,raw48,Host_Writes_32MiB "
      "-v 242,raw48,Host_Reads_32MiB "
++<<<<<<< HEAD
 +    "-v 245,raw48,TLC_Writes_32MiB " // FW N0815B, N1114H
 +    "-v 246,raw48,SLC_Writes_32MiB "
 +    "-v 247,raw48,Raid_Recoverty_Ct"
++=======
+     "-v 245,raw48,Unkn_SiliconMotion_Attr" // FW N0815B
++>>>>>>> 3d8ad6fa4529eb02ae1391a1e937bf57aad3fb74
    },
    { "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
    },
    { "Hitachi/HGST Travelstar Z5K320", // tested with Hitachi HTS543232A7A384/ES2OA70K
      "(Hitachi|HGST) HT[ES]5432(16|25|32)A7A38[145]",
++<<<<<<< HEAD
 +    "", "", ""
 +  },
 +  { "Hitachi Travelstar 5K500.B", // tested with Hitachi HTS545050B9SA00/PB4OC60X
 +    "(Hitachi )?HT[ES]5450(12|16|25|32|40|50)B9(A30[01]|SA00)",
 +    "", "", ""
 +  },
 +  { "Hitachi/HGST Travelstar Z5K500", // tested with HGST HTS545050A7E380/GG2OAC90,
 +      // Hitachi HTS545032A7E380/GGBOA7A0, HGST HTS545050A7E680/GR2OA230,
 +      // APPLE HDD HTS545050A7E362/GG2AB990
 +    "(Hitachi|HGST|APPLE HDD) HT[ES]5450(25|32|50)A7E(362|38[01]|680)",
++=======
+     "", "", ""
+   },
+   { "Hitachi Travelstar 5K500.B", // tested with Hitachi HTS545050B9SA00/PB4OC60X
+     "(Hitachi )?HT[ES]5450(12|16|25|32|40|50)B9(A30[01]|SA00)",
+     "", "", ""
+   },
+   { "Hitachi/HGST Travelstar Z5K500", // tested with HGST HTS545050A7E380/GG2OAC90,
+       // Hitachi HTS545032A7E380/GGBOA7A0, APPLE HDD HTS545050A7E362/GG2AB990
+     "(Hitachi|HGST|APPLE HDD) HT[ES]5450(25|32|50)A7E3(62|8[01])",
++>>>>>>> 3d8ad6fa4529eb02ae1391a1e937bf57aad3fb74
      "", "", ""
    },
    { "Hitachi/HGST Travelstar 5K750", // tested with Hitachi HTS547575A9E384/JE4OA60A,
      "(HITACHI )?HT[ES]7232(16|25|32)A7A36[145]",
      "", "", ""
    },
++<<<<<<< HEAD
 +  { "Hitachi Travelstar 7K500", // tested with Hitachi HTS725050A9A360/PC4OC70D,
 +    // HITACHI HTS725032A9A364/PC3ZC70F
 +    "(Hitachi |HITACHI )?HT[ES]7250(12|16|25|32|50)A9A36[02-5]",
++=======
+   { "Hitachi Travelstar 7K500", // tested with Hitachi HTS725050A9A360/PC4OC70D
+     "(Hitachi )?HT[ES]7250(12|16|25|32|50)A9A36[02-5]",
++>>>>>>> 3d8ad6fa4529eb02ae1391a1e937bf57aad3fb74
      "", "", ""
    },
    { "Hitachi/HGST Travelstar Z7K500", // tested with HITACHI HTS725050A7E630/GH2ZB390,
    },
    { "HGST Ultrastar He6", // tested with HGST HUS726060ALA640/AHGNT1E2
      "HGST HUS726060ALA64[01]",
++<<<<<<< HEAD
 +    "", "",
 +    "-v 22,raw48,Helium_Level"
 +  },
 +  { "HGST Ultrastar He8", // tested with HGST HUH728060ALE600/GR2OA230
 +    "HGST HUH7280(60|80)AL[EN]60[014]",
 +    "", "",
 +    "-v 22,raw48,Helium_Level"
++=======
+     "", "", ""
++>>>>>>> 3d8ad6fa4529eb02ae1391a1e937bf57aad3fb74
    },
    { "HGST MegaScale 4000", // tested with HGST HMS5C4040ALE640/MPAOA580
      "HGST HMS5C4040[AB]LE64[01]", // B = DC 4000.B
      "TOSHIBA MQ01ABC(100|150|200)",
      "", "", ""
    },
++<<<<<<< HEAD
 +  { "Toshiba 2.5\" HDD MQ01ABD...", // tested with TOSHIBA MQ01ABD100/AX001U,
 +      // TOSHIBA MQ01ABD100V/AX001Q
 +    "TOSHIBA MQ01ABD(025|032|050|064|075|100)V?",
 +    "", "", ""
 +  },
 +  { "Toshiba 2.5\" HDD MQ01ABF...", // tested with TOSHIBA MQ01ABF050/AM001J
 +    "TOSHIBA MQ01ABF(050|075|100)",
 +    "", "", ""
 +  },
 +  { "Toshiba 2.5\" HDD MQ01UBB... (USB 3.0)", // tested with TOSHIBA MQ01UBB200/AY000U (0x0480:0xa100)
 +    "TOSHIBA MQ01UBB200",
 +    "", "", ""
 +  },
++=======
+   { "Toshiba 2.5\" HDD MQ01ABD...", // tested with TOSHIBA MQ01ABD100/AX001U
+     "TOSHIBA MQ01ABD(025|032|050|064|075|100)",
+     "", "", ""
+   },
+   { "Toshiba 2.5\" HDD MQ01ABF...", // tested with TOSHIBA MQ01ABF050/AM001J
+     "TOSHIBA MQ01ABF(050|075|100)",
+     "", "", ""
+   },
+   { "Toshiba 2.5\" HDD MQ01UBB... (USB 3.0)", // tested with TOSHIBA MQ01UBB200/AY000U (0x0480:0xa100)
+     "TOSHIBA MQ01UBB200",
+     "", "", ""
+   },
++>>>>>>> 3d8ad6fa4529eb02ae1391a1e937bf57aad3fb74
    { "Toshiba 2.5\" HDD MQ01UBD... (USB 3.0)", // tested with TOSHIBA MQ01UBD050/AX001U (0x0480:0xa007),
        // TOSHIBA MQ01UBD100/AX001U (0x0480:0x0201, 0x0480:0xa200)
      "TOSHIBA MQ01UBD(050|075|100)",
    { "Seagate Constellation.2 (SATA)", // 2.5", tested with ST91000640NS/SN02, MM1000GBKAL/HPGB
      "ST9(25061|50062|100064)[012]NS|" // *SS = SAS
      "MM1000GBKAL", // HP OEM
++<<<<<<< HEAD
++=======
+     "", "", ""
+   },
+   { "Seagate Enterprise Capacity 3.5 HDD", // tested with ST6000NM0024-1HT17Z/SN02
+     "ST[2456]000NM0[01][248]4-.*", // *[069]4 = 4Kn
++>>>>>>> 3d8ad6fa4529eb02ae1391a1e937bf57aad3fb74
      "", "", ""
    },
 +  { "Seagate Enterprise Capacity 3.5 HDD", // tested with ST6000NM0024-1HT17Z/SN02
 +    "ST[2456]000NM0[01][248]4-.*", // *[069]4 = 4Kn
 +    "", "", 
 +    "-v 188,raw16"
 +  },
    { "Seagate NAS HDD", // tested with ST2000VN000-1H3164/SC42, ST3000VN000-1H4167/SC43
      "ST[234]000VN000-.*",
      "", "", ""
      "", "", ""
    },
    { "Western Digital Blue", // tested with WDC WD5000AZLX-00K4KA0/80.00A80,
++<<<<<<< HEAD
 +      // WDC WD10EZEX-00RKKA0/80.00A80, WDC WD10EZEX-75M2NA0/01.01A01, WDC WD40EZRZ-00WN9B0/80.00A80
 +    "WDC WD((25|32|50)00AAKX|5000AZ(LX|RZ)|7500A(AL|ZE)X|10E(AL|ZE)X|[1-6]0EZRZ)-.*",
++=======
+       // WDC WD10EZEX-00RKKA0/80.00A80, WDC WD10EZEX-75M2NA0/01.01A01
+     "WDC WD((25|32|50)00AAK|5000AZL|7500AAL|10EAL|10EZE)X-.*",
++>>>>>>> 3d8ad6fa4529eb02ae1391a1e937bf57aad3fb74
      "", "", ""
    },
    { "Western Digital RE Serial ATA",
    },
    { "Western Digital Red", // tested with WDC WD10EFRX-68JCSN0/01.01A01,
        // WDC WD10JFCX-68N6GN0/01.01A01, WDC WD40EFRX-68WT0N0/80.00A80,
++<<<<<<< HEAD
 +      // WDC WD60EFRX-68MYMN1/82.00A82, WDC WD80EFZX-68UW8N0/83.H0A83
 +    "WDC WD(7500BFC|10JFC|[1-6]0EFR|80EFZ)X-.*",
 +    "", "",
 +    "-v 22,raw48,Helium_Level" // WD80EFZX
 +  },
++  { "Western Digital Red Pro", // tested with WDC WD2001FFSX-68JNUN0/81.00A81
++    "WDC WD[234]001FFSX-.*",
++=======
+       // WDC WD60EFRX-68MYMN1/82.00A82
+     "WDC WD(7500BFC|10JFC|(10|20|30|40|50|60)EFR)X-.*",
+     "", "", ""
+   },
    { "Western Digital Red Pro", // tested with WDC WD2001FFSX-68JNUN0/81.00A81
      "WDC WD[234]001FFSX-.*",
      "", "", ""
    },
++  { "Western Digital Purple", // tested with WDC WD40PURX-64GVNY0/80.00A80
++    "WDC WD[123456]0PURX-.*",
++>>>>>>> 3d8ad6fa4529eb02ae1391a1e937bf57aad3fb74
++    "", "", ""
++  },
    { "Western Digital Purple", // tested with WDC WD40PURX-64GVNY0/80.00A80
      "WDC WD[123456]0PURX-.*",
      "", "", ""
      "",
      "-d sat"
    },
++<<<<<<< HEAD
 +  { "USB: Toshiba Canvio; ", // 0x0210: TOSHIBA MQ03UBB300
 +    "0x0480:0x02(01|10)",
++=======
+   { "USB: Toshiba Canvio Basics; ", // TOSHIBA MQ01UBD100
+     "0x0480:0x(0201|a200)",
++>>>>>>> 3d8ad6fa4529eb02ae1391a1e937bf57aad3fb74
      "",
      "",
      "-d sat"
      "",
      "-d sat"
    },
++<<<<<<< HEAD
 +  { "USB: Toshiba Stor.E; ",
 +    "0x0480:0xa00[9ace]",
++=======
+   { "USB: Toshiba Stor.E Basics; ",
+     "0x0480:0xa00[9ce]",
++>>>>>>> 3d8ad6fa4529eb02ae1391a1e937bf57aad3fb74
      "", // 0x0000 (0xa00e)
      "",
      "-d sat"
      "",
      "-d sat"
    },
++<<<<<<< HEAD
++=======
+   { "USB: Toshiba Canvio ALU; ", // TOSHIBA MQ01UBB200
+     "0x0480:0xa100",
+     "",
+     "",
+     "-d sat"
+   },
++>>>>>>> 3d8ad6fa4529eb02ae1391a1e937bf57aad3fb74
    { "USB: Toshiba Canvio Desktop; ",
      "0x0480:0xd0(00|10|11)",
      "", // 0x0316 (0xd011)
      "-d usbsunplus"
    },
    { "USB: Iomega; JMicron",
++<<<<<<< HEAD
 +    "0x059b:0x0(47[05]|575)", // 0x0470: LPHD-UP, 0x0475: GDHDU2 (0x0100), 0x0575: LDHD-UP
++=======
+     "0x059b:0x0[45]75", // 0x0475: Iomega GDHDU2 (0x0100), 0x0575: LDHD-UP
++>>>>>>> 3d8ad6fa4529eb02ae1391a1e937bf57aad3fb74
      "",
      "",
      "-d usbjmicron"
    { "USB: LaCie Rugged Triple Interface; ",
      "0x059f:0x100c",
      "", // 0x0001
++<<<<<<< HEAD
++=======
+     "",
+     "-d sat"
+   },
+   { "USB: LaCie hard disk (Neil Poulton design);",
+     "0x059f:0x1018",
++>>>>>>> 3d8ad6fa4529eb02ae1391a1e937bf57aad3fb74
      "",
 +    "-d sat"
 +  },
 +  { "USB: LaCie Desktop Hard Drive; ",
 +    "0x059f:0x101[68]", // 0x1016: SAMSUNG HD103UJ
 +    "", // 0x0001
      "",
      "-d sat"
    },
      "",
      "-d sat"
    },
++<<<<<<< HEAD
 +  { "USB: ; Genesys Logic",
 +    "0x05e3:0x0735",
 +    "", // 0x1003
 +    "",
 +    "-d sat"
 +  },
++=======
++>>>>>>> 3d8ad6fa4529eb02ae1391a1e937bf57aad3fb74
    // Micron
    { "USB: Micron USB SSD; ",
      "0x0634:0x0655",
    },
    // SanDisk
    { "USB: SanDisk SDCZ80 Flash Drive; Fujitsu", // ATA ID: SanDisk pSSD
++<<<<<<< HEAD
 +    "0x0781:0x558[08]",
++=======
+     "0x0781:0x5580",
++>>>>>>> 3d8ad6fa4529eb02ae1391a1e937bf57aad3fb74
      "",
      "",
      "-d sat"
      "-d sat"
    },
    { "USB: Seagate Expansion Portable; ",
++<<<<<<< HEAD
 +    "0x0bc2:0x23(00|12|20|21|22)",
 +    "", // 12=0x0219, 22=0x0000
++=======
+     "0x0bc2:0x23(00|12|20|21)",
+     "", // 0x0219 (0x2312)
++>>>>>>> 3d8ad6fa4529eb02ae1391a1e937bf57aad3fb74
      "",
      "-d sat"
    },
    },
    { "USB: Seagate Backup Plus Desktop USB 3.0; ",
      "0x0bc2:0xa(0a[14]|b31)", // 4TB, 3TB (8 LBA/1 PBA offset), 5TB
++<<<<<<< HEAD
++=======
 +    "",
 +    "",
 +    "-d sat"
 +  },
++  { "USB: Seagate Slim Portable Drive; ", // SRD00F1
++    "0x0bc2:0xab00",
++>>>>>>> 3d8ad6fa4529eb02ae1391a1e937bf57aad3fb74
+     "",
+     "",
+     "-d sat"
+   },
++<<<<<<< HEAD
    { "USB: Seagate Slim Portable Drive; ", // SRD00F1
      "0x0bc2:0xab00",
      "",
      "",
      "-d sat"
    },
 +  { "USB: Seagate Backup Plus USB 3.0; ",
 +    "0x0bc2:0xab2[0145]", // 0xab24: Slim (ticket #443), 0xab25: Mac
++=======
+   { "USB: Seagate Backup Plus Slim USB 3.0; ", // (ticket #443)
+     "0x0bc2:0xab2[14]",
++>>>>>>> 3d8ad6fa4529eb02ae1391a1e937bf57aad3fb74
      "", // 0x0100
      "",
      "-d sat"
      "-d usbcypress"
    },
    { "USB: WD My Passport; ",
++<<<<<<< HEAD
 +    "0x1058:0x0(70[245a]|71a|730|74[0128a]|7a[8e]|81[06]|82[02]|83[37a])",
 +    "", // 822=0x1007, 837=0x1072
++=======
+     "0x1058:0x0(70[245a]|730|74[0128a]|7a8|8[123]0)",
+     "",
++>>>>>>> 3d8ad6fa4529eb02ae1391a1e937bf57aad3fb74
      "",
      "-d sat"
    },
      "-d sat"
    },
    { "USB: WD My Book; ",
++<<<<<<< HEAD
 +    "0x1058:0x11(0[01245]|1[0d]|30|40)",
 +    "", // 00/01=0x0165, 02=0x1028, 10=0x1030, 1d=0x1020, 30=0x1012, 40=0x1003
 +    "",
 +    "-d sat"
 +  },
 +  { "USB: WD Elements; ",
 +    "0x1058:0x25a2",
 +    "", // 0x1004
++=======
+     "0x1058:0x11(00|01|02|04|05|10|30|40)",
+     "", // 00/01=0x0165, 02=0x1028, 10=0x1030, 30=0x1012, 40=0x1003
++>>>>>>> 3d8ad6fa4529eb02ae1391a1e937bf57aad3fb74
      "",
      "-d sat"
    },
    },
    // ADATA
    { "USB: ADATA; ",
++<<<<<<< HEAD
 +    "0x125f:0xa(11|31|35|15)a", // 0xa11a: Classic CH11 1TB, 0xa31a: HV620 2TB (0x0100)
 +    "", // 0xa35a: HD650 2TB (0x6503), 0xa15a: HD710 1TB
++=======
+     "0x125f:0xa(11|31|35)a", // 0xa11a: Classic CH11 1TB, 0xa31a: HV620 2TB (0x0100)
+     "", // 0xa35a: HD650 2TB (0x6503)
++>>>>>>> 3d8ad6fa4529eb02ae1391a1e937bf57aad3fb74
      "",
      "-d sat"
    },
      "-d sat"
    },
    { "USB: ; Initio",
++<<<<<<< HEAD
 +    "0x13fd:0x39[124]0", // 0x3910: Seagate Expansion Portable SRD00F1 (0x0100)
 +    "", // 0x3920: ezDISK EZ370 (0x0205)
 +    "", // 0x3940: MS-TECH LU-275S (0x0306)
++=======
+     "0x13fd:0x39[14]0", // 0x3910: Seagate Expansion Portable SRD00F1 (0x0100)
+     "", // 0x3940: MS-TECH LU-275S (0x0306)
+     "",
++>>>>>>> 3d8ad6fa4529eb02ae1391a1e937bf57aad3fb74
      "-d sat"
    },
    // Super Top
    },
    { "USB: ; JMicron JMS539", // USB2/3->SATA (new firmware)
      "0x152d:0x0539",
++<<<<<<< HEAD
 +    "0x020[56]|"   //  2.05, ZTC USB 3.0 enclosure (ticket #338)
++=======
+     "0x020[56]|"   //  2.05, ticket #338
++>>>>>>> 3d8ad6fa4529eb02ae1391a1e937bf57aad3fb74
      "0x28(03|12)", // 28.03, Mediasonic ProBox HF2-SU3S2 Rev 2 (port multiplier, ticket #504)
      "",            // 28.12, Mediasonic ProBox H82-SU3S2 (port multiplier)
      "-d sat"
      "",
      "-d usbjmicron,x"
    },
++<<<<<<< HEAD
 +  { "USB: ; JMicron", // USB2/3->2xSATA
 +    "0x152d:0x0565",
 +    "", // 0x9114, Akasa DuoDock X (ticket #607)
 +    "",
 +    "-d sat"
 +  },
++=======
++>>>>>>> 3d8ad6fa4529eb02ae1391a1e937bf57aad3fb74
    { "USB: ; JMicron JMS567", // USB2/3->SATA
      "0x152d:0x0567",
      "", // 0x0114
      "",
      "-d sat" // ATA output registers missing
    },
++<<<<<<< HEAD
 +  { "USB: ; VIA VL711", // USB2/3->SATA
 +    "0x2109:0x0711",
 +    "", // 0x0114, Mediasonic ProBox K32-SU3 (ticket #594)
 +    "", // 0x0507, Intenso 2,5" Memory Case 2TB USB3
 +    "-d sat"
 +  },
++=======
++>>>>>>> 3d8ad6fa4529eb02ae1391a1e937bf57aad3fb74
    // 0x2537 (?)
    { "USB: ; ", // USB 3.0
      "0x2537:0x106[68]", // 0x1066: Orico 2599US3, 0x1068: Fantec ER-35U3
      "-d sat" // ATA output registers missing
    },
    { "USB: Hitachi Touro Mobile; ", // 1TB
++<<<<<<< HEAD
 +    "0x4971:0x102[04]",
 +    "", // 0x0100
 +    "",
 +    "-d sat"
 +  },
 +  { "USB: SimpleTech;", // USB 3.0 HDD BOX Agestar,  Rock External HDD 3,5" UASP
 +    "0x4971:0x8017",
++=======
+     "0x4971:0x1020",
++>>>>>>> 3d8ad6fa4529eb02ae1391a1e937bf57aad3fb74
      "",
      "",
      "-d sat"
diff --cc os_linux.cpp
index 629792f52b272b52aed4940ff9cbbd97151d61d8,c9b58a3149ae024c3495fad91697f99ca97a604f..3440d4a0474178113447eda0e7a7b5ce540ccc0f
@@@ -1,11 -1,11 +1,15 @@@
  /*
   *  os_linux.cpp
   *
 - * Home page of code is: http://smartmontools.sourceforge.net
 + * Home page of code is: http://www.smartmontools.org
   *
 - * Copyright (C) 2003-11 Bruce Allen <smartmontools-support@lists.sourceforge.net>
 + * Copyright (C) 2003-11 Bruce Allen
   * Copyright (C) 2003-11 Doug Gilbert <dgilbert@interlog.com>
++<<<<<<< HEAD
 + * Copyright (C) 2008-16 Christian Franke
++=======
+  * Copyright (C) 2008-15 Christian Franke <smartmontools-support@lists.sourceforge.net>
++>>>>>>> 3d8ad6fa4529eb02ae1391a1e937bf57aad3fb74
   *
   * Original AACRaid code:
   *  Copyright (C) 2014    Raghava Aditya <raghava.aditya@pmcs.com>
  
  #define ARGUSED(x) ((void)(x))
  
++<<<<<<< HEAD
 +const char * os_linux_cpp_cvsid = "$Id: os_linux.cpp 4295 2016-04-15 20:01:32Z chrfranke $"
++=======
+ const char * os_linux_cpp_cvsid = "$Id: os_linux.cpp 4047 2015-03-22 16:16:24Z chrfranke $"
++>>>>>>> 3d8ad6fa4529eb02ae1391a1e937bf57aad3fb74
    OS_LINUX_H_CVSID;
  extern unsigned char failuretest_permissive;
  
@@@ -379,9 -377,9 +387,15 @@@ int linux_ata_device::ata_command_inter
      // copy user data into the task request structure
      memcpy(task+sizeof(ide_task_request_t), data, 512);
  
++<<<<<<< HEAD
 +    if (ioctl(get_fd(), HDIO_DRIVE_TASKFILE, task)) {
 +      if (errno==EINVAL)
 +        pout("Kernel lacks HDIO_DRIVE_TASKFILE support; compile kernel with CONFIG_IDE_TASK_IOCTL set\n");
++=======
+     if ((retval=ioctl(get_fd(), HDIO_DRIVE_TASKFILE, task))) {
+       if (errno==-EINVAL)
+         pout("Kernel lacks HDIO_DRIVE_TASKFILE support; compile kernel with CONFIG_IDE_TASKFILE_IO set\n");
++>>>>>>> 3d8ad6fa4529eb02ae1391a1e937bf57aad3fb74
        return -1;
      }
      return 0;
      buff[4]=normal_lo;
      buff[5]=normal_hi;
  
++<<<<<<< HEAD
 +    if (ioctl(get_fd(), HDIO_DRIVE_TASK, buff)) {
 +      if (errno==EINVAL) {
++=======
+     if ((retval=ioctl(get_fd(), HDIO_DRIVE_TASK, buff))) {
+       if (errno==-EINVAL) {
++>>>>>>> 3d8ad6fa4529eb02ae1391a1e937bf57aad3fb74
          pout("Error SMART Status command via HDIO_DRIVE_TASK failed");
          pout("Rebuild older linux 2.2 kernels with HDIO_DRIVE_TASK support added\n");
        }
diff --cc os_win32.cpp
index b10e9215081d4c774787d5e29e08a1fd1a5b3aa4,11b73198a73bb375df0afe9d681e00b79f945144..1348d7d1a8efa1723787aa2095ca57a998759365
@@@ -1,9 -1,9 +1,13 @@@
  /*
   * os_win32.cpp
   *
 - * Home page of code is: http://smartmontools.sourceforge.net
 + * Home page of code is: http://www.smartmontools.org
   *
++<<<<<<< HEAD
 + * Copyright (C) 2004-16 Christian Franke
++=======
+  * Copyright (C) 2004-15 Christian Franke
++>>>>>>> 3d8ad6fa4529eb02ae1391a1e937bf57aad3fb74
   *
   * Original AACRaid code:
   *  Copyright (C) 2015    Nidhi Malhotra <nidhi.malhotra@pmcs.com>
  #define strnicmp strncasecmp
  #endif
  
++<<<<<<< HEAD
 +const char * os_win32_cpp_cvsid = "$Id: os_win32.cpp 4293 2016-04-14 19:33:05Z chrfranke $";
++=======
+ const char * os_win32_cpp_cvsid = "$Id: os_win32.cpp 4098 2015-05-30 16:37:37Z chrfranke $";
++>>>>>>> 3d8ad6fa4529eb02ae1391a1e937bf57aad3fb74
  
  /////////////////////////////////////////////////////////////////////////////
  // Windows I/O-controls, some declarations are missing in the include files
@@@ -496,710 -416,788 +504,941 @@@ static void print_ide_regs_io(const IDE
  
  /////////////////////////////////////////////////////////////////////////////
  
 -class csmi_device
 -: virtual public /*extends*/ smart_device
 -{
 -public:
 -  /// Get bitmask of used ports
 -  unsigned get_ports_used();
 +// call SMART_GET_VERSION, return device map or -1 on error
  
 -protected:
 -  csmi_device()
 -    : smart_device(never_called)
 -    { memset(&m_phy_ent, 0, sizeof(m_phy_ent)); }
 +static int smart_get_version(HANDLE hdevice, GETVERSIONINPARAMS_EX * ata_version_ex = 0)
 +{
 +  GETVERSIONINPARAMS vers; memset(&vers, 0, sizeof(vers));
 +  const GETVERSIONINPARAMS_EX & vers_ex = (const GETVERSIONINPARAMS_EX &)vers;
 +  DWORD num_out;
  
 -  /// Get phy info
 -  bool get_phy_info(CSMI_SAS_PHY_INFO & phy_info);
 +  if (!DeviceIoControl(hdevice, SMART_GET_VERSION,
 +    NULL, 0, &vers, sizeof(vers), &num_out, NULL)) {
 +    if (ata_debugmode)
 +      pout("  SMART_GET_VERSION failed, Error=%u\n", (unsigned)GetLastError());
 +    errno = ENOSYS;
 +    return -1;
 +  }
 +  assert(num_out == sizeof(GETVERSIONINPARAMS));
  
 -  /// Select physical drive
 -  bool select_port(int port);
 +  if (ata_debugmode > 1) {
 +    pout("  SMART_GET_VERSION suceeded, bytes returned: %u\n"
 +         "    Vers = %d.%d, Caps = 0x%x, DeviceMap = 0x%02x\n",
 +      (unsigned)num_out, vers.bVersion, vers.bRevision,
 +      (unsigned)vers.fCapabilities, vers.bIDEDeviceMap);
 +    if (vers_ex.wIdentifier == SMART_VENDOR_3WARE)
 +      pout("    Identifier = %04x(3WARE), ControllerId=%u, DeviceMapEx = 0x%08x\n",
 +      vers_ex.wIdentifier, vers_ex.wControllerId, (unsigned)vers_ex.dwDeviceMapEx);
 +  }
  
 -  /// Get info for selected physical drive
 -  const CSMI_SAS_PHY_ENTITY & get_phy_ent() const
 -    { return m_phy_ent; }
 +  if (ata_version_ex)
 +    *ata_version_ex = vers_ex;
  
 -  /// Call platform-specific CSMI ioctl
 -  virtual bool csmi_ioctl(unsigned code, IOCTL_HEADER * csmi_buffer,
 -    unsigned csmi_bufsiz) = 0;
 +  // TODO: Check vers.fCapabilities here?
 +  return vers.bIDEDeviceMap;
 +}
  
 -private:
 -  CSMI_SAS_PHY_ENTITY m_phy_ent; ///< CSMI info for this phy
 -};
  
 +// call SMART_* ioctl
  
 -class csmi_ata_device
 -: virtual public /*extends*/ csmi_device,
 -  virtual public /*implements*/ ata_device
 +static int smart_ioctl(HANDLE hdevice, IDEREGS * regs, char * data, unsigned datasize, int port)
  {
 -public:
 -  virtual bool ata_pass_through(const ata_cmd_in & in, ata_cmd_out & out);
 +  SENDCMDINPARAMS inpar;
 +  SENDCMDINPARAMS_EX & inpar_ex = (SENDCMDINPARAMS_EX &)inpar;
  
 -protected:
 -  csmi_ata_device()
 -    : smart_device(never_called) { }
 -};
 +  unsigned char outbuf[sizeof(SENDCMDOUTPARAMS)-1 + 512];
 +  const SENDCMDOUTPARAMS * outpar;
 +  DWORD code, num_out;
 +  unsigned int size_out;
 +  const char * name;
  
 +  memset(&inpar, 0, sizeof(inpar));
 +  inpar.irDriveRegs = *regs;
  
 -//////////////////////////////////////////////////////////////////////
 +  // Older drivers may require bits 5 and 7 set
 +  // ATA-3: bits shall be set, ATA-4 and later: bits are obsolete
 +  inpar.irDriveRegs.bDriveHeadReg |= 0xa0;
  
 -class win_csmi_device
 -: public /*implements*/ csmi_ata_device
 -{
 -public:
 -  win_csmi_device(smart_interface * intf, const char * dev_name,
 -    const char * req_type);
 +  // Drive number 0-3 was required on Win9x/ME only
 +  //inpar.irDriveRegs.bDriveHeadReg |= (drive & 1) << 4;
 +  //inpar.bDriveNumber = drive;
  
 -  virtual ~win_csmi_device() throw();
 +  if (port >= 0) {
 +    // Set RAID port
 +    inpar_ex.wIdentifier = SMART_VENDOR_3WARE;
 +    inpar_ex.bPortNumber = port;
 +  }
  
 -  virtual bool open();
 +  if (datasize == 512) {
 +    code = SMART_RCV_DRIVE_DATA; name = "SMART_RCV_DRIVE_DATA";
 +    inpar.cBufferSize = size_out = 512;
 +  }
 +  else if (datasize == 0) {
 +    code = SMART_SEND_DRIVE_COMMAND; name = "SMART_SEND_DRIVE_COMMAND";
 +    if (regs->bFeaturesReg == ATA_SMART_STATUS)
 +      size_out = sizeof(IDEREGS); // ioctl returns new IDEREGS as data
 +      // Note: cBufferSize must be 0 on Win9x
 +    else
 +      size_out = 0;
 +  }
 +  else {
 +    errno = EINVAL;
 +    return -1;
 +  }
  
 -  virtual bool close();
 +  memset(&outbuf, 0, sizeof(outbuf));
  
 -  virtual bool is_open() const;
 +  if (!DeviceIoControl(hdevice, code, &inpar, sizeof(SENDCMDINPARAMS)-1,
 +    outbuf, sizeof(SENDCMDOUTPARAMS)-1 + size_out, &num_out, NULL)) {
 +    // CAUTION: DO NOT change "regs" Parameter in this case, see win_ata_device::ata_pass_through()
 +    long err = GetLastError();
 +    if (ata_debugmode && (err != ERROR_INVALID_PARAMETER || ata_debugmode > 1)) {
 +      pout("  %s failed, Error=%ld\n", name, err);
 +      print_ide_regs_io(regs, NULL);
 +    }
 +    errno = (   err == ERROR_INVALID_FUNCTION/*9x*/
 +             || err == ERROR_INVALID_PARAMETER/*NT/2K/XP*/
 +             || err == ERROR_NOT_SUPPORTED ? ENOSYS : EIO);
 +    return -1;
 +  }
 +  // NOTE: On Win9x, inpar.irDriveRegs now contains the returned regs
  
 -  bool open_scsi();
 -
 -protected:
 -  virtual bool csmi_ioctl(unsigned code, IOCTL_HEADER * csmi_buffer,
 -    unsigned csmi_bufsiz);
 -
 -private:
 -  HANDLE m_fh; ///< Controller device handle
 -  int m_port; ///< Port number
 -};
 -
 -
 -//////////////////////////////////////////////////////////////////////
 -
 -class win_tw_cli_device
 -: public /*implements*/ ata_device_with_command_set
 -{
 -public:
 -  win_tw_cli_device(smart_interface * intf, const char * dev_name, const char * req_type);
 -
 -  virtual bool is_open() const;
 +  outpar = (const SENDCMDOUTPARAMS *)outbuf;
  
 -  virtual bool open();
 +  if (outpar->DriverStatus.bDriverError) {
 +    if (ata_debugmode) {
 +      pout("  %s failed, DriverError=0x%02x, IDEError=0x%02x\n", name,
 +        outpar->DriverStatus.bDriverError, outpar->DriverStatus.bIDEError);
 +      print_ide_regs_io(regs, NULL);
 +    }
 +    errno = (!outpar->DriverStatus.bIDEError ? ENOSYS : EIO);
 +    return -1;
 +  }
  
 -  virtual bool close();
 +  if (ata_debugmode > 1) {
 +    pout("  %s suceeded, bytes returned: %u (buffer %u)\n", name,
 +      (unsigned)num_out, (unsigned)outpar->cBufferSize);
 +    print_ide_regs_io(regs, (regs->bFeaturesReg == ATA_SMART_STATUS ?
 +      (const IDEREGS *)(outpar->bBuffer) : NULL));
 +  }
  
 -protected:
 -  virtual int ata_command_interface(smart_command_set command, int select, char * data);
 +  if (datasize)
 +    memcpy(data, outpar->bBuffer, 512);
 +  else if (regs->bFeaturesReg == ATA_SMART_STATUS) {
 +    if (nonempty(outpar->bBuffer, sizeof(IDEREGS)))
 +      memcpy(regs, outpar->bBuffer, sizeof(IDEREGS));
 +    else {  // Workaround for driver not returning regs
 +      if (ata_debugmode)
 +        pout("  WARNING: driver does not return ATA registers in output buffer!\n");
 +      *regs = inpar.irDriveRegs;
 +    }
 +  }
  
 -private:
 -  bool m_ident_valid, m_smart_valid;
 -  ata_identify_device m_ident_buf;
 -  ata_smart_values m_smart_buf;
 -};
 +  return 0;
 +}
  
+ /////////////////////////////////////////////////////////////////////////////
+ //// PMC aacraid Support
+ class win_aacraid_device
+ :public /*implements*/ scsi_device,
+ public /*extends*/ win_smart_device
+ {
+ public:
+   win_aacraid_device(smart_interface *intf, const char *dev_name,unsigned int ctrnum, unsigned int target, unsigned int lun);
+   virtual ~win_aacraid_device() throw();
+   virtual bool open();
+   virtual bool scsi_pass_through(struct scsi_cmnd_io *iop);
+ private:
+   //Device Host number
+   int m_ctrnum;
+   //Channel(Lun) of the device
+   int m_lun;
+   //Id of the device
+   int m_target;
+ };
  
  /////////////////////////////////////////////////////////////////////////////
 -/// Areca RAID support
 +// IDE PASS THROUGH (2000, XP, undocumented)
 +//
 +// Based on WinATA.cpp, 2002 c't/Matthias Withopf
 +// ftp://ftp.heise.de/pub/ct/listings/0207-218.zip
  
 -///////////////////////////////////////////////////////////////////
 -// SATA(ATA) device behind Areca RAID Controller
 -class win_areca_ata_device
 -: public /*implements*/ areca_ata_device,
 -  public /*extends*/ win_smart_device
 +static int ide_pass_through_ioctl(HANDLE hdevice, IDEREGS * regs, char * data, unsigned datasize)
  {
 -public:
 -  win_areca_ata_device(smart_interface * intf, const char * dev_name, int disknum, int encnum = 1);
 -  virtual bool open();
 -  virtual smart_device * autodetect_open();
 -  virtual bool arcmsr_lock();
 -  virtual bool arcmsr_unlock();
 -  virtual int arcmsr_do_scsi_io(struct scsi_cmnd_io * iop);
 -
 -private:
 -  HANDLE m_mutex;
 -};
 +  if (datasize > 512) {
 +    errno = EINVAL;
 +    return -1;
 +  }
 +  unsigned int size = sizeof(ATA_PASS_THROUGH)-1 + datasize;
 +  ATA_PASS_THROUGH * buf = (ATA_PASS_THROUGH *)VirtualAlloc(NULL, size, MEM_COMMIT, PAGE_READWRITE);
 +  DWORD num_out;
 +  const unsigned char magic = 0xcf;
  
 -///////////////////////////////////////////////////////////////////
 -// SAS(SCSI) device behind Areca RAID Controller
 -class win_areca_scsi_device
 -: public /*implements*/ areca_scsi_device,
 -  public /*extends*/ win_smart_device
 -{
 -public:
 -  win_areca_scsi_device(smart_interface * intf, const char * dev_name, int disknum, int encnum = 1);
 -  virtual bool open();
 -  virtual smart_device * autodetect_open();
 -  virtual bool arcmsr_lock();
 -  virtual bool arcmsr_unlock();
 -  virtual int arcmsr_do_scsi_io(struct scsi_cmnd_io * iop);
 +  if (!buf) {
 +    errno = ENOMEM;
 +    return -1;
 +  }
  
 -private:
 -  HANDLE m_mutex;
 -};
 +  buf->IdeReg = *regs;
 +  buf->DataBufferSize = datasize;
 +  if (datasize)
 +    buf->DataBuffer[0] = magic;
  
 +  if (!DeviceIoControl(hdevice, IOCTL_IDE_PASS_THROUGH,
 +    buf, size, buf, size, &num_out, NULL)) {
 +    long err = GetLastError();
 +    if (ata_debugmode) {
 +      pout("  IOCTL_IDE_PASS_THROUGH failed, Error=%ld\n", err);
 +      print_ide_regs_io(regs, NULL);
 +    }
 +    VirtualFree(buf, 0, MEM_RELEASE);
 +    errno = (err == ERROR_INVALID_FUNCTION || err == ERROR_NOT_SUPPORTED ? ENOSYS : EIO);
 +    return -1;
 +  }
  
 -//////////////////////////////////////////////////////////////////////
 -// Platform specific interface
 +  // Check ATA status
 +  if (buf->IdeReg.bCommandReg/*Status*/ & 0x01) {
 +    if (ata_debugmode) {
 +      pout("  IOCTL_IDE_PASS_THROUGH command failed:\n");
 +      print_ide_regs_io(regs, &buf->IdeReg);
 +    }
 +    VirtualFree(buf, 0, MEM_RELEASE);
 +    errno = EIO;
 +    return -1;
 +  }
  
 -class win_smart_interface
 -: public /*implements part of*/ smart_interface
 -{
 -public:
 -  virtual std::string get_os_version_str();
 +  // Check and copy data
 +  if (datasize) {
 +    if (   num_out != size
 +        || (buf->DataBuffer[0] == magic && !nonempty(buf->DataBuffer+1, datasize-1))) {
 +      if (ata_debugmode) {
 +        pout("  IOCTL_IDE_PASS_THROUGH output data missing (%u, %u)\n",
 +          (unsigned)num_out, (unsigned)buf->DataBufferSize);
 +        print_ide_regs_io(regs, &buf->IdeReg);
 +      }
 +      VirtualFree(buf, 0, MEM_RELEASE);
 +      errno = EIO;
 +      return -1;
 +    }
 +    memcpy(data, buf->DataBuffer, datasize);
 +  }
  
 -  virtual std::string get_app_examples(const char * appname);
 +  if (ata_debugmode > 1) {
 +    pout("  IOCTL_IDE_PASS_THROUGH suceeded, bytes returned: %u (buffer %u)\n",
 +      (unsigned)num_out, (unsigned)buf->DataBufferSize);
 +    print_ide_regs_io(regs, &buf->IdeReg);
 +  }
 +  *regs = buf->IdeReg;
  
 -#ifndef __CYGWIN__
 -  virtual int64_t get_timer_usec();
 -#endif
 +  // Caution: VirtualFree() fails if parameter "dwSize" is nonzero
 +  VirtualFree(buf, 0, MEM_RELEASE);
 +  return 0;
 +}
  
 -  virtual bool disable_system_auto_standby(bool disable);
  
 -  virtual bool scan_smart_devices(smart_device_list & devlist, const char * type,
 -    const char * pattern = 0);
 +/////////////////////////////////////////////////////////////////////////////
 +// ATA PASS THROUGH (Win2003, XP SP2)
  
 -protected:
 -  virtual ata_device * get_ata_device(const char * name, const char * type);
 +// Warning:
 +// IOCTL_ATA_PASS_THROUGH[_DIRECT] can only handle one interrupt/DRQ data
 +// transfer per command. Therefore, multi-sector transfers are only supported
 +// for the READ/WRITE MULTIPLE [EXT] commands. Other commands like READ/WRITE SECTORS
 +// or READ/WRITE LOG EXT work only with single sector transfers.
 +// The latter are supported on Vista (only) through new ATA_FLAGS_NO_MULTIPLE.
 +// See:
 +// http://social.msdn.microsoft.com/Forums/en-US/storageplatformata/thread/eb408507-f221-455b-9bbb-d1069b29c4da
  
 -  virtual scsi_device * get_scsi_device(const char * name, const char * type);
 +static int ata_pass_through_ioctl(HANDLE hdevice, IDEREGS * regs, IDEREGS * prev_regs, char * data, int datasize)
 +{
 +  const int max_sectors = 32; // TODO: Allocate dynamic buffer
  
 -  virtual smart_device * autodetect_smart_device(const char * name);
 +  typedef struct {
 +    ATA_PASS_THROUGH_EX apt;
 +    ULONG Filler;
 +    UCHAR ucDataBuf[max_sectors * 512];
 +  } ATA_PASS_THROUGH_EX_WITH_BUFFERS;
  
 -  virtual smart_device * get_custom_smart_device(const char * name, const char * type);
 +  const unsigned char magic = 0xcf;
  
 -  virtual std::string get_valid_custom_dev_types_str();
 -};
 +  ATA_PASS_THROUGH_EX_WITH_BUFFERS ab; memset(&ab, 0, sizeof(ab));
 +  ab.apt.Length = sizeof(ATA_PASS_THROUGH_EX);
 +  //ab.apt.PathId = 0;
 +  //ab.apt.TargetId = 0;
 +  //ab.apt.Lun = 0;
 +  ab.apt.TimeOutValue = 10;
 +  unsigned size = offsetof(ATA_PASS_THROUGH_EX_WITH_BUFFERS, ucDataBuf);
 +  ab.apt.DataBufferOffset = size;
  
 +  if (datasize > 0) {
 +    if (datasize > (int)sizeof(ab.ucDataBuf)) {
 +      errno = EINVAL;
 +      return -1;
 +    }
 +    ab.apt.AtaFlags = ATA_FLAGS_DATA_IN;
 +    ab.apt.DataTransferLength = datasize;
 +    size += datasize;
 +    ab.ucDataBuf[0] = magic;
 +  }
 +  else if (datasize < 0) {
 +    if (-datasize > (int)sizeof(ab.ucDataBuf)) {
 +      errno = EINVAL;
 +      return -1;
 +    }
 +    ab.apt.AtaFlags = ATA_FLAGS_DATA_OUT;
 +    ab.apt.DataTransferLength = -datasize;
 +    size += -datasize;
 +    memcpy(ab.ucDataBuf, data, -datasize);
 +  }
 +  else {
 +    assert(ab.apt.AtaFlags == 0);
 +    assert(ab.apt.DataTransferLength == 0);
 +  }
  
 -//////////////////////////////////////////////////////////////////////
 +  assert(sizeof(ab.apt.CurrentTaskFile) == sizeof(IDEREGS));
 +  IDEREGS * ctfregs = (IDEREGS *)ab.apt.CurrentTaskFile;
 +  IDEREGS * ptfregs = (IDEREGS *)ab.apt.PreviousTaskFile;
 +  *ctfregs = *regs;
  
 -#ifndef _WIN64
 -// Running on 64-bit Windows as 32-bit app ?
 -static bool is_wow64()
 -{
 -  BOOL (WINAPI * IsWow64Process_p)(HANDLE, PBOOL) =
 -    (BOOL (WINAPI *)(HANDLE, PBOOL))
 -    GetProcAddress(GetModuleHandleA("kernel32.dll"), "IsWow64Process");
 -  if (!IsWow64Process_p)
 -    return false;
 -  BOOL w64 = FALSE;
 -  if (!IsWow64Process_p(GetCurrentProcess(), &w64))
 -    return false;
 -  return !!w64;
 -}
 -#endif // _WIN64
 +  if (prev_regs) {
 +    *ptfregs = *prev_regs;
 +    ab.apt.AtaFlags |= ATA_FLAGS_48BIT_COMMAND;
 +  }
  
 -// Return info string about build host and OS version
 -std::string win_smart_interface::get_os_version_str()
 -{
 -  char vstr[sizeof(SMARTMONTOOLS_BUILD_HOST)-1+sizeof("-2003r2(64)-sp2.1")+13]
 -    = SMARTMONTOOLS_BUILD_HOST;
 -  if (vstr[1] < '6')
 -    vstr[1] = '6';
 -  char * const vptr = vstr+sizeof(SMARTMONTOOLS_BUILD_HOST)-1;
 -  const int vlen = sizeof(vstr)-sizeof(SMARTMONTOOLS_BUILD_HOST);
 -  assert(vptr == vstr+strlen(vstr) && vptr+vlen+1 == vstr+sizeof(vstr));
 -
 -  OSVERSIONINFOEXA vi; memset(&vi, 0, sizeof(vi));
 -  vi.dwOSVersionInfoSize = sizeof(vi);
 -  if (!GetVersionExA((OSVERSIONINFOA *)&vi)) {
 -    memset(&vi, 0, sizeof(vi));
 -    vi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOA);
 -    if (!GetVersionExA((OSVERSIONINFOA *)&vi))
 -      return vstr;
 +  DWORD num_out;
 +  if (!DeviceIoControl(hdevice, IOCTL_ATA_PASS_THROUGH,
 +    &ab, size, &ab, size, &num_out, NULL)) {
 +    long err = GetLastError();
 +    if (ata_debugmode) {
 +      pout("  IOCTL_ATA_PASS_THROUGH failed, Error=%ld\n", err);
 +      print_ide_regs_io(regs, NULL);
 +    }
 +    errno = (err == ERROR_INVALID_FUNCTION || err == ERROR_NOT_SUPPORTED ? ENOSYS : EIO);
 +    return -1;
    }
  
 -  const char * w = 0;
 -  if (vi.dwPlatformId == VER_PLATFORM_WIN32_NT) {
 -
 -    if (vi.dwMajorVersion > 6 || (vi.dwMajorVersion == 6 && vi.dwMinorVersion >= 2)) {
 -      // Starting with Windows 8.1 Preview, GetVersionEx() does no longer report the
 -      // actual OS version, see:
 -      // http://msdn.microsoft.com/en-us/library/windows/desktop/dn302074.aspx
 -
 -      ULONGLONG major_equal = VerSetConditionMask(0, VER_MAJORVERSION, VER_EQUAL);
 -      for (unsigned major = vi.dwMajorVersion; major <= 9; major++) {
 -        OSVERSIONINFOEXA vi2; memset(&vi2, 0, sizeof(vi2));
 -        vi2.dwOSVersionInfoSize = sizeof(vi2); vi2.dwMajorVersion = major;
 -        if (!VerifyVersionInfo(&vi2, VER_MAJORVERSION, major_equal))
 -          continue;
 -        if (vi.dwMajorVersion < major) {
 -          vi.dwMajorVersion = major; vi.dwMinorVersion = 0;
 -        }
 -
 -        ULONGLONG minor_equal = VerSetConditionMask(0, VER_MINORVERSION, VER_EQUAL);
 -        for (unsigned minor = vi.dwMinorVersion; minor <= 9; minor++) {
 -          memset(&vi2, 0, sizeof(vi2)); vi2.dwOSVersionInfoSize = sizeof(vi2);
 -          vi2.dwMinorVersion = minor;
 -          if (!VerifyVersionInfo(&vi2, VER_MINORVERSION, minor_equal))
 -            continue;
 -          vi.dwMinorVersion = minor;
 -          break;
 -        }
 -
 -        break;
 -      }
 +  // Check ATA status
 +  if (ctfregs->bCommandReg/*Status*/ & (0x01/*Err*/|0x08/*DRQ*/)) {
 +    if (ata_debugmode) {
 +      pout("  IOCTL_ATA_PASS_THROUGH command failed:\n");
 +      print_ide_regs_io(regs, ctfregs);
      }
 +    errno = EIO;
 +    return -1;
 +  }
  
++<<<<<<< HEAD
 +  // Check and copy data
 +  if (datasize > 0) {
 +    if (   num_out != size
 +        || (ab.ucDataBuf[0] == magic && !nonempty(ab.ucDataBuf+1, datasize-1))) {
 +      if (ata_debugmode) {
 +        pout("  IOCTL_ATA_PASS_THROUGH output data missing (%u)\n", (unsigned)num_out);
 +        print_ide_regs_io(regs, ctfregs);
++=======
+     if (vi.dwMajorVersion <= 0xf && vi.dwMinorVersion <= 0xf) {
+       bool ws = (vi.wProductType <= VER_NT_WORKSTATION);
+       switch (vi.dwMajorVersion << 4 | vi.dwMinorVersion) {
+         case 0x50: w =       "2000";              break;
+         case 0x51: w =       "xp";                break;
+         case 0x52: w = (!GetSystemMetrics(89/*SM_SERVERR2*/)
+                            ? "2003"  : "2003r2"); break;
+         case 0x60: w = (ws ? "vista" : "2008"  ); break;
+         case 0x61: w = (ws ? "win7"  : "2008r2"); break;
+         case 0x62: w = (ws ? "win8"  : "2012"  ); break;
+         case 0x63: w = (ws ? "win8.1": "2012r2"); break;
+         case 0x64: w = (ws ? "win10" : "w10srv"); break;
++>>>>>>> 3d8ad6fa4529eb02ae1391a1e937bf57aad3fb74
        }
 +      errno = EIO;
 +      return -1;
      }
 +    memcpy(data, ab.ucDataBuf, datasize);
    }
  
 -  const char * w64 = "";
 -#ifndef _WIN64
 -  if (is_wow64())
 -    w64 = "(64)";
 -#endif
 +  if (ata_debugmode > 1) {
 +    pout("  IOCTL_ATA_PASS_THROUGH suceeded, bytes returned: %u\n", (unsigned)num_out);
 +    print_ide_regs_io(regs, ctfregs);
 +  }
 +  *regs = *ctfregs;
 +  if (prev_regs)
 +    *prev_regs = *ptfregs;
  
 -  if (!w)
 -    snprintf(vptr, vlen, "-%s%u.%u%s",
 -      (vi.dwPlatformId==VER_PLATFORM_WIN32_NT ? "nt" : "??"),
 -      (unsigned)vi.dwMajorVersion, (unsigned)vi.dwMinorVersion, w64);
 -  else if (vi.wServicePackMinor)
 -    snprintf(vptr, vlen, "-%s%s-sp%u.%u", w, w64, vi.wServicePackMajor, vi.wServicePackMinor);
 -  else if (vi.wServicePackMajor)
 -    snprintf(vptr, vlen, "-%s%s-sp%u", w, w64, vi.wServicePackMajor);
 -  else
 -    snprintf(vptr, vlen, "-%s%s", w, w64);
 -  return vstr;
 +  return 0;
  }
  
 -#ifndef __CYGWIN__
 -// MSVCRT only provides ftime() which uses GetSystemTime()
 -// This provides only ~15ms resolution by default.
 -// Use QueryPerformanceCounter instead (~300ns).
 -// (Cygwin provides CLOCK_MONOTONIC which has the same effect)
 -int64_t win_smart_interface::get_timer_usec()
 -{
 -  static int64_t freq = 0;
  
 -  LARGE_INTEGER t;
 -  if (freq == 0)
 -    freq = (QueryPerformanceFrequency(&t) ? t.QuadPart : -1);
 -  if (freq <= 0)
 -    return smart_interface::get_timer_usec();
 +/////////////////////////////////////////////////////////////////////////////
 +// SMART IOCTL via SCSI MINIPORT ioctl
  
 -  if (!QueryPerformanceCounter(&t))
 -    return -1;
 -  if (!(0 <= t.QuadPart && t.QuadPart <= (int64_t)(~(uint64_t)0 >> 1)/1000000))
 -    return -1;
 +// This function is handled by ATAPI port driver (atapi.sys) or by SCSI
 +// miniport driver (via SCSI port driver scsiport.sys).
 +// It can be used to skip the missing or broken handling of some SMART
 +// command codes (e.g. READ_LOG) in the disk class driver (disk.sys)
  
 -  return (t.QuadPart * 1000000LL) / freq;
 -}
 -#endif // __CYGWIN__
 +static int ata_via_scsi_miniport_smart_ioctl(HANDLE hdevice, IDEREGS * regs, char * data, int datasize)
 +{
 +  // Select code
 +  DWORD code = 0; const char * name = 0;
 +  if (regs->bCommandReg == ATA_IDENTIFY_DEVICE) {
 +    code = IOCTL_SCSI_MINIPORT_IDENTIFY; name = "IDENTIFY";
 +  }
 +  else if (regs->bCommandReg == ATA_SMART_CMD) switch (regs->bFeaturesReg) {
 +    case ATA_SMART_READ_VALUES:
 +      code = IOCTL_SCSI_MINIPORT_READ_SMART_ATTRIBS; name = "READ_SMART_ATTRIBS"; break;
 +    case ATA_SMART_READ_THRESHOLDS:
 +      code = IOCTL_SCSI_MINIPORT_READ_SMART_THRESHOLDS; name = "READ_SMART_THRESHOLDS"; break;
 +    case ATA_SMART_ENABLE:
 +      code = IOCTL_SCSI_MINIPORT_ENABLE_SMART; name = "ENABLE_SMART"; break;
 +    case ATA_SMART_DISABLE:
 +      code = IOCTL_SCSI_MINIPORT_DISABLE_SMART; name = "DISABLE_SMART"; break;
 +    case ATA_SMART_STATUS:
 +      code = IOCTL_SCSI_MINIPORT_RETURN_STATUS; name = "RETURN_STATUS"; break;
 +    case ATA_SMART_AUTOSAVE:
 +      code = IOCTL_SCSI_MINIPORT_ENABLE_DISABLE_AUTOSAVE; name = "ENABLE_DISABLE_AUTOSAVE"; break;
 +  //case ATA_SMART_SAVE: // obsolete since ATA-6, not used by smartmontools
 +  //  code = IOCTL_SCSI_MINIPORT_SAVE_ATTRIBUTE_VALUES; name = "SAVE_ATTRIBUTE_VALUES"; break;
 +    case ATA_SMART_IMMEDIATE_OFFLINE:
 +      code = IOCTL_SCSI_MINIPORT_EXECUTE_OFFLINE_DIAGS; name = "EXECUTE_OFFLINE_DIAGS"; break;
 +    case ATA_SMART_AUTO_OFFLINE:
 +      code = IOCTL_SCSI_MINIPORT_ENABLE_DISABLE_AUTO_OFFLINE; name = "ENABLE_DISABLE_AUTO_OFFLINE"; break;
 +    case ATA_SMART_READ_LOG_SECTOR:
 +      code = IOCTL_SCSI_MINIPORT_READ_SMART_LOG; name = "READ_SMART_LOG"; break;
 +    case ATA_SMART_WRITE_LOG_SECTOR:
 +      code = IOCTL_SCSI_MINIPORT_WRITE_SMART_LOG; name = "WRITE_SMART_LOG"; break;
 +  }
 +  if (!code) {
 +    errno = ENOSYS;
 +    return -1;
 +  }
  
 +  // Set SRB
 +  struct {
 +    SRB_IO_CONTROL srbc;
 +    union {
 +      SENDCMDINPARAMS in;
 +      SENDCMDOUTPARAMS out;
 +    } params;
 +    char space[512-1];
 +  } sb;
 +  ASSERT_SIZEOF(sb, sizeof(SRB_IO_CONTROL)+sizeof(SENDCMDINPARAMS)-1+512);
 +  memset(&sb, 0, sizeof(sb));
  
++<<<<<<< HEAD
 +  unsigned size;
 +  if (datasize > 0) {
 +    if (datasize > (int)sizeof(sb.space)+1) {
 +      errno = EINVAL;
 +      return -1;
 +    }
 +    size = datasize;
 +  }
 +  else if (datasize < 0) {
 +    if (-datasize > (int)sizeof(sb.space)+1) {
 +      errno = EINVAL;
 +      return -1;
 +    }
 +    size = -datasize;
 +    memcpy(sb.params.in.bBuffer, data, size);
 +  }
 +  else if (code == IOCTL_SCSI_MINIPORT_RETURN_STATUS)
 +    size = sizeof(IDEREGS);
 +  else
 +    size = 0;
 +  sb.srbc.HeaderLength = sizeof(SRB_IO_CONTROL);
 +  memcpy(sb.srbc.Signature, "SCSIDISK", 8); // atapi.sys
 +  sb.srbc.Timeout = 60; // seconds
 +  sb.srbc.ControlCode = code;
 +  //sb.srbc.ReturnCode = 0;
 +  sb.srbc.Length = sizeof(SENDCMDINPARAMS)-1 + size;
 +  sb.params.in.irDriveRegs = *regs;
 +  sb.params.in.cBufferSize = size;
++=======
+ // Return value for device detection functions
+ enum win_dev_type { DEV_UNKNOWN = 0, DEV_ATA, DEV_SCSI, DEV_SAT, DEV_USB };
++>>>>>>> 3d8ad6fa4529eb02ae1391a1e937bf57aad3fb74
  
 -static win_dev_type get_phy_drive_type(int drive);
 -static win_dev_type get_phy_drive_type(int drive, GETVERSIONINPARAMS_EX * ata_version_ex);
 -static win_dev_type get_log_drive_type(int drive);
 -static bool get_usb_id(int drive, unsigned short & vendor_id,
 -                       unsigned short & product_id);
 +  // Call miniport ioctl
 +  size += sizeof(SRB_IO_CONTROL) + sizeof(SENDCMDINPARAMS)-1;
 +  DWORD num_out;
 +  if (!DeviceIoControl(hdevice, IOCTL_SCSI_MINIPORT,
 +    &sb, size, &sb, size, &num_out, NULL)) {
 +    long err = GetLastError();
 +    if (ata_debugmode) {
 +      pout("  IOCTL_SCSI_MINIPORT_%s failed, Error=%ld\n", name, err);
 +      print_ide_regs_io(regs, NULL);
 +    }
 +    errno = (err == ERROR_INVALID_FUNCTION || err == ERROR_NOT_SUPPORTED ? ENOSYS : EIO);
 +    return -1;
 +  }
  
 -static const char * ata_get_def_options(void);
 +  // Check result
 +  if (sb.srbc.ReturnCode) {
 +    if (ata_debugmode) {
 +      pout("  IOCTL_SCSI_MINIPORT_%s failed, ReturnCode=0x%08x\n", name, (unsigned)sb.srbc.ReturnCode);
 +      print_ide_regs_io(regs, NULL);
 +    }
 +    errno = EIO;
 +    return -1;
 +  }
  
 +  if (sb.params.out.DriverStatus.bDriverError) {
 +    if (ata_debugmode) {
 +      pout("  IOCTL_SCSI_MINIPORT_%s failed, DriverError=0x%02x, IDEError=0x%02x\n", name,
 +        sb.params.out.DriverStatus.bDriverError, sb.params.out.DriverStatus.bIDEError);
 +      print_ide_regs_io(regs, NULL);
 +    }
 +    errno = (!sb.params.out.DriverStatus.bIDEError ? ENOSYS : EIO);
 +    return -1;
 +  }
  
 -static int is_permissive()
 -{
 -  if (!failuretest_permissive) {
 -    pout("To continue, add one or more '-T permissive' options.\n");
 -    return 0;
 +  if (ata_debugmode > 1) {
 +    pout("  IOCTL_SCSI_MINIPORT_%s suceeded, bytes returned: %u (buffer %u)\n", name,
 +      (unsigned)num_out, (unsigned)sb.params.out.cBufferSize);
 +    print_ide_regs_io(regs, (code == IOCTL_SCSI_MINIPORT_RETURN_STATUS ?
 +                             (const IDEREGS *)(sb.params.out.bBuffer) : 0));
    }
 -  failuretest_permissive--;
 -  return 1;
 -}
  
 -// return number for drive letter, -1 on error
 -// "[A-Za-z]:([/\\][.]?)?" => 0-25
 -// Accepts trailing '"' to fix broken "X:\" parameter passing from .bat files
 -static int drive_letter(const char * s)
 -{
 -  return (   (('A' <= s[0] && s[0] <= 'Z') || ('a' <= s[0] && s[0] <= 'z'))
 -          && s[1] == ':'
 -          && (!s[2] || (   strchr("/\\\"", s[2])
 -                        && (!s[3] || (s[3] == '.' && !s[4])))              ) ?
 -          (s[0] & 0x1f) - 1 : -1);
 -}
 +  if (datasize > 0)
 +    memcpy(data, sb.params.out.bBuffer, datasize);
 +  else if (datasize == 0 && code == IOCTL_SCSI_MINIPORT_RETURN_STATUS)
 +    memcpy(regs, sb.params.out.bBuffer, sizeof(IDEREGS));
  
 -// Skip trailing "/dev/", do not allow "/dev/X:"
 -static const char * skipdev(const char * s)
 -{
 -  return (!strncmp(s, "/dev/", 5) && drive_letter(s+5) < 0 ? s+5 : s);
 +  return 0;
  }
  
 -ata_device * win_smart_interface::get_ata_device(const char * name, const char * type)
 -{
 -  const char * testname = skipdev(name);
 -  if (!strncmp(testname, "csmi", 4))
 -    return new win_csmi_device(this, name, type);
 -  if (!strncmp(testname, "tw_cli", 6))
 -    return new win_tw_cli_device(this, name, type);
 -  return new win_ata_device(this, name, type);
 -}
  
 -scsi_device * win_smart_interface::get_scsi_device(const char * name, const char * type)
 -{
 -  return new win_scsi_device(this, name, type);
 -}
 +/////////////////////////////////////////////////////////////////////////////
 +// ATA PASS THROUGH via 3ware specific SCSI MINIPORT ioctl
  
 -static int sdxy_to_phydrive(const char (& xy)[2+1])
 +static int ata_via_3ware_miniport_ioctl(HANDLE hdevice, IDEREGS * regs, char * data, int datasize, int port)
  {
 -  int phydrive = xy[0] - 'a';
 -  if (xy[1])
 -    phydrive = (phydrive + 1) * ('z' - 'a' + 1) + (xy[1] - 'a');
 -  return phydrive;
 -}
 -
 -static win_dev_type get_dev_type(const char * name, int & phydrive)
 -{
 -  phydrive = -1;
 -  name = skipdev(name);
 -  if (!strncmp(name, "st", 2))
 -    return DEV_SCSI;
 -  if (!strncmp(name, "nst", 3))
 -    return DEV_SCSI;
 -  if (!strncmp(name, "tape", 4))
 -    return DEV_SCSI;
 +  struct {
 +    SRB_IO_CONTROL srbc;
 +    IDEREGS regs;
 +    UCHAR buffer[512];
 +  } sb;
 +  ASSERT_SIZEOF(sb, sizeof(SRB_IO_CONTROL)+sizeof(IDEREGS)+512);
  
 -  int logdrive = drive_letter(name);
 -  if (logdrive >= 0) {
 -    win_dev_type type = get_log_drive_type(logdrive);
 -    return (type != DEV_UNKNOWN ? type : DEV_SCSI);
 +  if (!(0 <= datasize && datasize <= (int)sizeof(sb.buffer) && port >= 0)) {
 +    errno = EINVAL;
 +    return -1;
    }
 +  memset(&sb, 0, sizeof(sb));
 +  strncpy((char *)sb.srbc.Signature, "<3ware>", sizeof(sb.srbc.Signature));
 +  sb.srbc.HeaderLength = sizeof(SRB_IO_CONTROL);
 +  sb.srbc.Timeout = 60; // seconds
 +  sb.srbc.ControlCode = 0xA0000000;
 +  sb.srbc.ReturnCode = 0;
 +  sb.srbc.Length = sizeof(IDEREGS) + (datasize > 0 ? datasize : 1);
 +  sb.regs = *regs;
 +  sb.regs.bReserved = port;
  
 -  char drive[2+1] = "";
 -  if (sscanf(name, "sd%2[a-z]", drive) == 1) {
 -    phydrive = sdxy_to_phydrive(drive);
 -    return get_phy_drive_type(phydrive);
 +  DWORD num_out;
 +  if (!DeviceIoControl(hdevice, IOCTL_SCSI_MINIPORT,
 +    &sb, sizeof(sb), &sb, sizeof(sb), &num_out, NULL)) {
 +    long err = GetLastError();
 +    if (ata_debugmode) {
 +      pout("  ATA via IOCTL_SCSI_MINIPORT failed, Error=%ld\n", err);
 +      print_ide_regs_io(regs, NULL);
 +    }
 +    errno = (err == ERROR_INVALID_FUNCTION ? ENOSYS : EIO);
 +    return -1;
    }
  
 -  phydrive = -1;
 -  if (sscanf(name, "pd%d", &phydrive) == 1 && phydrive >= 0)
 -    return get_phy_drive_type(phydrive);
 -  return DEV_UNKNOWN;
 -}
 -
 -smart_device * win_smart_interface::get_custom_smart_device(const char * name, const char * type)
 -{
 -  // Areca?
 -  int disknum = -1, n1 = -1, n2 = -1;
 -  int encnum = 1;
 -  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;
 +  if (sb.srbc.ReturnCode) {
 +    if (ata_debugmode) {
 +      pout("  ATA via IOCTL_SCSI_MINIPORT failed, ReturnCode=0x%08x\n", (unsigned)sb.srbc.ReturnCode);
 +      print_ide_regs_io(regs, NULL);
      }
 +    errno = EIO;
 +    return -1;
 +  }
  
++<<<<<<< HEAD
 +  // Copy data
 +  if (datasize > 0)
 +    memcpy(data, sb.buffer, datasize);
 +
 +  if (ata_debugmode > 1) {
 +    pout("  ATA via IOCTL_SCSI_MINIPORT suceeded, bytes returned: %u\n", (unsigned)num_out);
 +    print_ide_regs_io(regs, &sb.regs);
++=======
+     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));
+         snprintf(devpath, sizeof(devpath), "\\\\.\\scsi%d:", idx);
+         win_areca_ata_device *arcdev = new win_areca_ata_device(this, devpath, disknum, encnum);
+         if(arcdev->arcmsr_probe()) {
+           if(ctlrindex-- == 0) {
+             return arcdev;
+           }
+         }
+         delete arcdev;
+       }
+       set_err(ENOENT, "No Areca controller found");
+     }
+     else
+       set_err(EINVAL, "Option -d areca,N/E requires device name /dev/arcmsrX");
+     return 0;
+   }
+   // aacraid?
+   unsigned ctrnum, lun, target;
+   n1 = -1;
+   if (   sscanf(type, "aacraid,%u,%u,%u%n", &ctrnum, &lun, &target, &n1) >= 3
+       && n1 == (int)strlen(type)) {
+ #define aacraid_MAX_CTLR_NUM  16
+     if (ctrnum >= aacraid_MAX_CTLR_NUM) {
+       set_err(EINVAL, "aacraid: invalid host number %u", ctrnum);
+       return 0;
+     }
+     /*
+     1. scan from "\\\\.\\scsi[0]:" up to "\\\\.\\scsi[AACRAID_MAX_CTLR_NUM]:" and
+     2. map ARCX into "\\\\.\\scsiX"
+     */
+     memset(devpath, 0, sizeof(devpath));
+     unsigned ctlrindex = 0;
+     for (int portNum = 0; portNum < aacraid_MAX_CTLR_NUM; portNum++){
+       char subKey[63];
+       snprintf(subKey, sizeof(subKey), "HARDWARE\\DEVICEMAP\\Scsi\\Scsi Port %d", portNum);
+       HKEY hScsiKey = 0;
+       long regStatus = RegOpenKeyExA(HKEY_LOCAL_MACHINE, subKey, 0, KEY_READ, &hScsiKey);
+       if (regStatus == ERROR_SUCCESS){
+         char driverName[20];
+         DWORD driverNameSize = sizeof(driverName);
+         DWORD regType = 0;
+         regStatus = RegQueryValueExA(hScsiKey, "Driver", NULL, &regType, (LPBYTE) driverName, &driverNameSize);
+         if (regStatus == ERROR_SUCCESS){
+           if (regType == REG_SZ){
+             if (stricmp(driverName, "arcsas") == 0){
+               if(ctrnum == ctlrindex){
+                 snprintf(devpath, sizeof(devpath), "\\\\.\\Scsi%d:", portNum);
+                 return get_sat_device("sat,auto",
+                   new win_aacraid_device(this, devpath, ctrnum, target, lun));
+               }
+               ctlrindex++;
+             }
+           }
+         }
+         RegCloseKey(hScsiKey);
+       }
+     }
+     set_err(EINVAL, "aacraid: host %u not found", ctrnum);
+     return 0;
++>>>>>>> 3d8ad6fa4529eb02ae1391a1e937bf57aad3fb74
    }
 +  *regs = sb.regs;
  
    return 0;
  }
  
++<<<<<<< HEAD
++=======
+ std::string win_smart_interface::get_valid_custom_dev_types_str()
+ {
+   return "aacraid,H,L,ID, areca,N[/E]";
+ }
++>>>>>>> 3d8ad6fa4529eb02ae1391a1e937bf57aad3fb74
  
 +/////////////////////////////////////////////////////////////////////////////
  
 -smart_device * win_smart_interface::autodetect_smart_device(const char * name)
 +// 3ware specific call to update the devicemap returned by SMART_GET_VERSION.
 +// 3DM/CLI "Rescan Controller" function does not to always update it.
 +
 +static int update_3ware_devicemap_ioctl(HANDLE hdevice)
  {
 -  const char * testname = skipdev(name);
 -  if (str_starts_with(testname, "hd"))
 -    return new win_ata_device(this, name, "");
 +  SRB_IO_CONTROL srbc;
 +  memset(&srbc, 0, sizeof(srbc));
 +  strncpy((char *)srbc.Signature, "<3ware>", sizeof(srbc.Signature));
 +  srbc.HeaderLength = sizeof(SRB_IO_CONTROL);
 +  srbc.Timeout = 60; // seconds
 +  srbc.ControlCode = 0xCC010014;
 +  srbc.ReturnCode = 0;
 +  srbc.Length = 0;
  
 -  if (str_starts_with(testname, "tw_cli"))
 -    return new win_tw_cli_device(this, name, "");
 +  DWORD num_out;
 +  if (!DeviceIoControl(hdevice, IOCTL_SCSI_MINIPORT,
 +    &srbc, sizeof(srbc), &srbc, sizeof(srbc), &num_out, NULL)) {
 +    long err = GetLastError();
 +    if (ata_debugmode)
 +      pout("  UPDATE DEVICEMAP via IOCTL_SCSI_MINIPORT failed, Error=%ld\n", err);
 +    errno = (err == ERROR_INVALID_FUNCTION ? ENOSYS : EIO);
 +    return -1;
 +  }
 +  if (srbc.ReturnCode) {
 +    if (ata_debugmode)
 +      pout("  UPDATE DEVICEMAP via IOCTL_SCSI_MINIPORT failed, ReturnCode=0x%08x\n", (unsigned)srbc.ReturnCode);
 +    errno = EIO;
 +    return -1;
 +  }
 +  if (ata_debugmode > 1)
 +    pout("  UPDATE DEVICEMAP via IOCTL_SCSI_MINIPORT suceeded\n");
 +  return 0;
 +}
  
 -  if (str_starts_with(testname, "csmi"))
 -    return new win_csmi_device(this, name, "");
  
 -  int phydrive = -1;
 -  win_dev_type type = get_dev_type(name, phydrive);
 +/////////////////////////////////////////////////////////////////////////////
 +// IOCTL_STORAGE_QUERY_PROPERTY
 +
++<<<<<<< HEAD
 +union STORAGE_DEVICE_DESCRIPTOR_DATA {
 +  STORAGE_DEVICE_DESCRIPTOR desc;
 +  char raw[256];
 +};
 +
 +// Get STORAGE_DEVICE_DESCRIPTOR_DATA for device.
 +// (This works without admin rights)
 +
 +static int storage_query_property_ioctl(HANDLE hdevice, STORAGE_DEVICE_DESCRIPTOR_DATA * data)
 +{
 +  STORAGE_PROPERTY_QUERY query = {StorageDeviceProperty, PropertyStandardQuery, {0} };
 +  memset(data, 0, sizeof(*data));
  
 +  DWORD num_out;
 +  if (!DeviceIoControl(hdevice, IOCTL_STORAGE_QUERY_PROPERTY,
 +    &query, sizeof(query), data, sizeof(*data), &num_out, NULL)) {
 +    if (ata_debugmode > 1 || scsi_debugmode > 1)
 +      pout("  IOCTL_STORAGE_QUERY_PROPERTY failed, Error=%u\n", (unsigned)GetLastError());
 +    errno = ENOSYS;
 +    return -1;
++=======
+   if (type == DEV_ATA)
+     return new win_ata_device(this, name, "");
+   if (type == DEV_SCSI)
+     return new win_scsi_device(this, name, "");
+   if (type == DEV_SAT)
+     return get_sat_device("sat", new win_scsi_device(this, name, ""));
+   if (type == DEV_USB) {
+     // Get USB bridge ID
+     unsigned short vendor_id = 0, product_id = 0;
+     if (!(phydrive >= 0 && get_usb_id(phydrive, vendor_id, product_id))) {
+       set_err(EINVAL, "Unable to read USB device ID");
+       return 0;
+     }
+     // Get type name for this ID
+     const char * usbtype = get_usb_dev_type_by_id(vendor_id, product_id);
+     if (!usbtype)
+       return 0;
+     // Return SAT/USB device for this type
+     return get_sat_device(usbtype, new win_scsi_device(this, name, ""));
++>>>>>>> 3d8ad6fa4529eb02ae1391a1e937bf57aad3fb74
    }
  
 +  if (ata_debugmode > 1 || scsi_debugmode > 1) {
 +    pout("  IOCTL_STORAGE_QUERY_PROPERTY returns:\n"
 +         "    Vendor:   \"%s\"\n"
 +         "    Product:  \"%s\"\n"
 +         "    Revision: \"%s\"\n"
 +         "    Removable: %s\n"
 +         "    BusType:   0x%02x\n",
 +         (data->desc.VendorIdOffset        ? data->raw+data->desc.VendorIdOffset : "(null)"),
 +         (data->desc.ProductIdOffset       ? data->raw+data->desc.ProductIdOffset : "(null)"),
 +         (data->desc.ProductRevisionOffset ? data->raw+data->desc.ProductRevisionOffset : "(null)"),
 +         (data->desc.RemovableMedia? "Yes":"No"), data->desc.BusType
 +    );
 +  }
    return 0;
  }
  
  
 -// Scan for devices
 +/////////////////////////////////////////////////////////////////////////////
 +// IOCTL_STORAGE_PREDICT_FAILURE
  
 -bool win_smart_interface::scan_smart_devices(smart_device_list & devlist,
 -  const char * type, const char * pattern /* = 0*/)
 +// Call IOCTL_STORAGE_PREDICT_FAILURE, return PredictFailure value
 +// or -1 on error, opionally return VendorSpecific data.
 +// (This works without admin rights)
 +
 +static int storage_predict_failure_ioctl(HANDLE hdevice, char * data = 0)
  {
 -  if (pattern) {
 -    set_err(EINVAL, "DEVICESCAN with pattern not implemented yet");
 -    return false;
 -  }
 +  STORAGE_PREDICT_FAILURE pred;
 +  memset(&pred, 0, sizeof(pred));
  
 -  // Check for "[*,]pd" type
 -  bool pd = false;
 -  char type2[16+1] = "";
 -  if (type) {
 -    int nc = -1;
 -    if (!strcmp(type, "pd")) {
 -      pd = true;
 -      type = 0;
 -    }
 -    else if (sscanf(type, "%16[^,],pd%n", type2, &nc) == 1 &&
 -             nc == (int)strlen(type)) {
 -      pd = true;
 -      type = type2;
 -    }
 +  DWORD num_out;
 +  if (!DeviceIoControl(hdevice, IOCTL_STORAGE_PREDICT_FAILURE,
 +    0, 0, &pred, sizeof(pred), &num_out, NULL)) {
 +    if (ata_debugmode > 1)
 +      pout("  IOCTL_STORAGE_PREDICT_FAILURE failed, Error=%u\n", (unsigned)GetLastError());
 +    errno = ENOSYS;
 +    return -1;
    }
  
++<<<<<<< HEAD
 +  if (ata_debugmode > 1) {
 +    pout("  IOCTL_STORAGE_PREDICT_FAILURE returns:\n"
 +         "    PredictFailure: 0x%08x\n"
 +         "    VendorSpecific: 0x%02x,0x%02x,0x%02x,...,0x%02x\n",
 +         (unsigned)pred.PredictFailure,
 +         pred.VendorSpecific[0], pred.VendorSpecific[1], pred.VendorSpecific[2],
 +         pred.VendorSpecific[sizeof(pred.VendorSpecific)-1]
 +    );
 +  }
 +  if (data)
 +    memcpy(data, pred.VendorSpecific, sizeof(pred.VendorSpecific));
 +  return (!pred.PredictFailure ? 0 : 1);
 +}
++=======
+   // Set valid types
+   bool ata, scsi, sat, usb, csmi;
+   if (!type) {
+     ata = scsi = usb = sat = csmi = true;
+   }
+   else {
+     ata = scsi = usb = sat = csmi = false;
+     if (!strcmp(type, "ata"))
+       ata = true;
+     else if (!strcmp(type, "scsi"))
+       scsi = true;
+     else if (!strcmp(type, "sat"))
+       sat = true;
+     else if (!strcmp(type, "usb"))
+       usb = true;
+     else if (!strcmp(type, "csmi"))
+       csmi = true;
+     else {
+       set_err(EINVAL,
+               "Invalid type '%s', valid arguments are: ata[,pd], scsi[,pd], sat[,pd], usb[,pd], csmi, pd",
+               type);
+       return false;
+     }
+   }
+   char name[20];
+   if (ata || scsi || sat || usb) {
+     // Scan up to 128 drives and 2 3ware controllers
+     const int max_raid = 2;
+     bool raid_seen[max_raid] = {false, false};
+     for (int i = 0; i < 128; i++) {
+       if (pd)
+         snprintf(name, sizeof(name), "/dev/pd%d", i);
+       else if (i + 'a' <= 'z')
+         snprintf(name, sizeof(name), "/dev/sd%c", i + 'a');
+       else
+         snprintf(name, sizeof(name), "/dev/sd%c%c",
+                  i / ('z'-'a'+1) - 1 + 'a',
+                  i % ('z'-'a'+1)     + 'a');
++>>>>>>> 3d8ad6fa4529eb02ae1391a1e937bf57aad3fb74
  
 -      GETVERSIONINPARAMS_EX vers_ex;
  
 -      switch (get_phy_drive_type(i, (ata ? &vers_ex : 0))) {
 -        case DEV_ATA:
 -          // Driver supports SMART_GET_VERSION or STORAGE_QUERY_PROPERTY returned ATA/SATA
 -          if (!ata)
 -            continue;
 +// Build IDENTIFY information from STORAGE_DEVICE_DESCRIPTOR
 +static int get_identify_from_device_property(HANDLE hdevice, ata_identify_device * id)
 +{
 +  STORAGE_DEVICE_DESCRIPTOR_DATA data;
 +  if (storage_query_property_ioctl(hdevice, &data))
 +    return -1;
  
 -          // Interpret RAID drive map if present
 -          if (vers_ex.wIdentifier == SMART_VENDOR_3WARE) {
 -            // Skip if too many controllers or logical drive from this controller already seen
 -            if (!(vers_ex.wControllerId < max_raid && !raid_seen[vers_ex.wControllerId]))
 -              continue;
 -            raid_seen[vers_ex.wControllerId] = true;
 -            // Add physical drives
 -            int len = strlen(name);
 -            for (int pi = 0; pi < 32; pi++) {
 -              if (vers_ex.dwDeviceMapEx & (1L << pi)) {
 -                snprintf(name+len, sizeof(name)-1-len, ",%u", pi);
 -                devlist.push_back( new win_ata_device(this, name, "ata") );
 -              }
 -            }
 -          }
 -          else {
 -            devlist.push_back( new win_ata_device(this, name, "ata") );
 -          }
 -          break;
 +  memset(id, 0, sizeof(*id));
  
 -        case DEV_SCSI:
 -          // STORAGE_QUERY_PROPERTY returned SCSI/SAS/...
 -          if (!scsi)
 -            continue;
 -          devlist.push_back( new win_scsi_device(this, name, "scsi") );
 -          break;
 +  // Some drivers split ATA model string into VendorId and ProductId,
 +  // others return it as ProductId only.
 +  char model[sizeof(id->model) + 1] = "";
  
++<<<<<<< HEAD
 +  unsigned i = 0;
 +  if (data.desc.VendorIdOffset) {
 +    for ( ;i < sizeof(model)-1 && data.raw[data.desc.VendorIdOffset+i]; i++)
 +      model[i] = data.raw[data.desc.VendorIdOffset+i];
 +  }
++=======
+         case DEV_SAT:
+           // STORAGE_QUERY_PROPERTY returned VendorId "ATA     "
+           if (!sat)
+             continue;
+           devlist.push_back( get_sat_device("sat", new win_scsi_device(this, name, "")) );
+           break;
+         case DEV_USB:
+           // STORAGE_QUERY_PROPERTY returned USB
+           if (!usb)
+             continue;
+           {
+             // TODO: Use common function for this and autodetect_smart_device()
+             // Get USB bridge ID
+             unsigned short vendor_id = 0, product_id = 0;
+             if (!get_usb_id(i, vendor_id, product_id))
+               continue;
+             // Get type name for this ID
+             const char * usbtype = get_usb_dev_type_by_id(vendor_id, product_id);
+             if (!usbtype)
+               continue;
+             // Return SAT/USB device for this type
+             ata_device * dev = get_sat_device(usbtype, new win_scsi_device(this, name, ""));
+             if (!dev)
+               continue;
+             devlist.push_back(dev);
+           }
+           break;
++>>>>>>> 3d8ad6fa4529eb02ae1391a1e937bf57aad3fb74
  
 -        default:
 -          // Unknown type
 -          break;
 -      }
 -    }
 -  }
 -
 -  if (csmi) {
 -    // Scan CSMI devices
 -    for (int i = 0; i <= 9; i++) {
 -      snprintf(name, sizeof(name)-1, "/dev/csmi%d,0", i);
 -      win_csmi_device test_dev(this, name, "");
 -      if (!test_dev.open_scsi())
 -        continue;
 -
 -      unsigned ports_used = test_dev.get_ports_used();
 -      if (!ports_used)
 -        continue;
 -
 -      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") );
 -      }
 -    }
 +  if (data.desc.ProductIdOffset) {
 +    while (i > 1 && model[i-2] == ' ') // Keep last blank from VendorId
 +      i--;
 +    // Ignore VendorId "ATA"
 +    if (i <= 4 && !strncmp(model, "ATA", 3) && (i == 3 || model[3] == ' '))
 +      i = 0;
 +    for (unsigned j = 0; i < sizeof(model)-1 && data.raw[data.desc.ProductIdOffset+j]; i++, j++)
 +      model[i] = data.raw[data.desc.ProductIdOffset+j];
    }
 -  return true;
 -}
  
 +  while (i > 0 && model[i-1] == ' ')
 +    i--;
 +  model[i] = 0;
 +  copy_swapped(id->model, model, sizeof(id->model));
  
 -// get examples for smartctl
 -std::string win_smart_interface::get_app_examples(const char * appname)
 -{
 -  if (strcmp(appname, "smartctl"))
 -    return "";
 -  return "=================================================== SMARTCTL EXAMPLES =====\n\n"
 -         "  smartctl -a /dev/sda                       (Prints all SMART information)\n\n"
 -         "  smartctl --smart=on --offlineauto=on --saveauto=on /dev/sda\n"
 -         "                                              (Enables SMART on first disk)\n\n"
 -         "  smartctl -t long /dev/sda              (Executes extended disk self-test)\n\n"
 -         "  smartctl --attributes --log=selftest --quietmode=errorsonly /dev/sda\n"
 -         "                                      (Prints Self-Test & Attribute errors)\n"
 -         "  smartctl -a /dev/sda\n"
 -         "             (Prints all information for disk on PhysicalDrive 0)\n"
 -         "  smartctl -a /dev/pd3\n"
 -         "             (Prints all information for disk on PhysicalDrive 3)\n"
 -         "  smartctl -a /dev/tape1\n"
 -         "             (Prints all information for SCSI tape on Tape 1)\n"
 -         "  smartctl -A /dev/hdb,3\n"
 -         "                (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"
 -         "  's': SMART_* IOCTLs,         'a': IOCTL_ATA_PASS_THROUGH,\n"
 -         "  'i': IOCTL_IDE_PASS_THROUGH, 'f': IOCTL_STORAGE_*,\n"
 -         "  'm': IOCTL_SCSI_MINIPORT_*.\n"
 -      + strprintf(
 -         "  The default on this system is /dev/sdX:%s\n", ata_get_def_options()
 -        );
 -}
 +  if (data.desc.ProductRevisionOffset)
 +    copy_swapped(id->fw_rev, data.raw+data.desc.ProductRevisionOffset, sizeof(id->fw_rev));
  
 +  id->command_set_1 = 0x0001; id->command_set_2 = 0x4000; // SMART supported, words 82,83 valid
 +  id->cfs_enable_1  = 0x0001; id->csf_default   = 0x4000; // SMART enabled, words 85,87 valid
 +  return 0;
 +}
  
 -bool win_smart_interface::disable_system_auto_standby(bool disable)
 +// Get Serial Number in IDENTIFY from WMI
 +static bool get_serial_from_wmi(int drive, ata_identify_device * id)
  {
 -  if (disable) {
 -    SYSTEM_POWER_STATUS ps;
 -    if (!GetSystemPowerStatus(&ps))
 -      return set_err(ENOSYS, "Unknown power status");
 -    if (ps.ACLineStatus != 1) {
 -      SetThreadExecutionState(ES_CONTINUOUS);
 -      if (ps.ACLineStatus == 0)
 -        set_err(EIO, "AC offline");
 -      else
 -        set_err(EIO, "Unknown AC line status");
 -      return false;
 -    }
 +  bool debug = (ata_debugmode > 1);
 +
 +  wbem_services ws;
 +  if (!ws.connect()) {
 +    if (debug)
 +      pout("WMI connect failed\n");
 +    return false;
    }
  
 -  if (!SetThreadExecutionState(ES_CONTINUOUS | (disable ? ES_SYSTEM_REQUIRED : 0)))
 -    return set_err(ENOSYS);
 +  wbem_object wo;
 +  if (!ws.query1(wo, "SELECT Model,SerialNumber FROM Win32_DiskDrive WHERE "
 +                     "DeviceID=\"\\\\\\\\.\\\\PHYSICALDRIVE%d\"", drive))
 +    return false;
 +
 +  std::string serial = wo.get_str("SerialNumber");
 +  if (debug)
 +    pout("  WMI:PhysicalDrive%d: \"%s\", S/N:\"%s\"\n", drive, wo.get_str("Model").c_str(), serial.c_str());
 +
 +  copy_swapped(id->serial_no, serial.c_str(), sizeof(id->serial_no));
    return true;
  }
  
@@@ -2130,331 -2090,224 +2369,390 @@@ bool csmi_device::select_port(int port
  }
  
  
 -/////////////////////////////////////////////////////////////////////////////
 -// IOCTL_STORAGE_PREDICT_FAILURE
 +//////////////////////////////////////////////////////////////////////
 +// csmi_ata_device
  
 -// Call IOCTL_STORAGE_PREDICT_FAILURE, return PredictFailure value
 -// or -1 on error, opionally return VendorSpecific data.
 -// (This works without admin rights)
 +class csmi_ata_device
 +: virtual public /*extends*/ csmi_device,
 +  virtual public /*implements*/ ata_device
 +{
 +public:
 +  virtual bool ata_pass_through(const ata_cmd_in & in, ata_cmd_out & out);
  
 -static int storage_predict_failure_ioctl(HANDLE hdevice, char * data = 0)
 +protected:
 +  csmi_ata_device()
 +    : smart_device(never_called) { }
 +};
 +
 +
 +//////////////////////////////////////////////////////////////////////
 +
 +bool csmi_ata_device::ata_pass_through(const ata_cmd_in & in, ata_cmd_out & out)
  {
 -  STORAGE_PREDICT_FAILURE pred;
 -  memset(&pred, 0, sizeof(pred));
 +  if (!ata_cmd_is_supported(in,
 +    ata_device::supports_data_out |
 +    ata_device::supports_output_regs |
 +    ata_device::supports_multi_sector |
 +    ata_device::supports_48bit,
 +    "CMSI")
 +  )
 +    return false;
  
 -  DWORD num_out;
 -  if (!DeviceIoControl(hdevice, IOCTL_STORAGE_PREDICT_FAILURE,
 -    0, 0, &pred, sizeof(pred), &num_out, NULL)) {
 -    if (ata_debugmode > 1)
 -      pout("  IOCTL_STORAGE_PREDICT_FAILURE failed, Error=%u\n", (unsigned)GetLastError());
 -    errno = ENOSYS;
 -    return -1;
 +  // Create buffer with appropriate size
 +  raw_buffer pthru_raw_buf(sizeof(CSMI_SAS_STP_PASSTHRU_BUFFER) + in.size);
 +  CSMI_SAS_STP_PASSTHRU_BUFFER * pthru_buf = (CSMI_SAS_STP_PASSTHRU_BUFFER *)pthru_raw_buf.data();
 +
 +  // Set addresses from Phy info
 +  CSMI_SAS_STP_PASSTHRU & pthru = pthru_buf->Parameters;
 +  const CSMI_SAS_PHY_ENTITY & phy_ent = get_phy_ent();
 +  pthru.bPhyIdentifier = phy_ent.Identify.bPhyIdentifier;
 +  pthru.bPortIdentifier = phy_ent.bPortIdentifier;
 +  memcpy(pthru.bDestinationSASAddress, phy_ent.Attached.bSASAddress,
 +    sizeof(pthru.bDestinationSASAddress));
 +  pthru.bConnectionRate = CSMI_SAS_LINK_RATE_NEGOTIATED;
 +
 +  // Set transfer mode
 +  switch (in.direction) {
 +    case ata_cmd_in::no_data:
 +      pthru.uFlags = CSMI_SAS_STP_PIO | CSMI_SAS_STP_UNSPECIFIED;
 +      break;
 +    case ata_cmd_in::data_in:
 +      pthru.uFlags = CSMI_SAS_STP_PIO | CSMI_SAS_STP_READ;
 +      pthru.uDataLength = in.size;
 +      break;
 +    case ata_cmd_in::data_out:
 +      pthru.uFlags = CSMI_SAS_STP_PIO | CSMI_SAS_STP_WRITE;
 +      pthru.uDataLength = in.size;
 +      memcpy(pthru_buf->bDataBuffer, in.buffer, in.size);
 +      break;
 +    default:
 +      return set_err(EINVAL, "csmi_ata_device::ata_pass_through: invalid direction=%d",
 +        (int)in.direction);
    }
  
 -  if (ata_debugmode > 1) {
 -    pout("  IOCTL_STORAGE_PREDICT_FAILURE returns:\n"
 -         "    PredictFailure: 0x%08x\n"
 -         "    VendorSpecific: 0x%02x,0x%02x,0x%02x,...,0x%02x\n",
 -         (unsigned)pred.PredictFailure,
 -         pred.VendorSpecific[0], pred.VendorSpecific[1], pred.VendorSpecific[2],
 -         pred.VendorSpecific[sizeof(pred.VendorSpecific)-1]
 -    );
 +  // Set host-to-device FIS
 +  {
 +    unsigned char * fis = pthru.bCommandFIS;
 +    const ata_in_regs & lo = in.in_regs;
 +    const ata_in_regs & hi = in.in_regs.prev;
 +    fis[ 0] = 0x27; // Type: host-to-device FIS
 +    fis[ 1] = 0x80; // Bit7: Update command register
 +    fis[ 2] = lo.command;
 +    fis[ 3] = lo.features;
 +    fis[ 4] = lo.lba_low;
 +    fis[ 5] = lo.lba_mid;
 +    fis[ 6] = lo.lba_high;
 +    fis[ 7] = lo.device;
 +    fis[ 8] = hi.lba_low;
 +    fis[ 9] = hi.lba_mid;
 +    fis[10] = hi.lba_high;
 +    fis[11] = hi.features;
 +    fis[12] = lo.sector_count;
 +    fis[13] = hi.sector_count;
 +  }
 +
 +  // Call ioctl
 +  if (!csmi_ioctl(CC_CSMI_SAS_STP_PASSTHRU, &pthru_buf->IoctlHeader, pthru_raw_buf.size())) {
 +    return false;
    }
 -  if (data)
 -    memcpy(data, pred.VendorSpecific, sizeof(pred.VendorSpecific));
 -  return (!pred.PredictFailure ? 0 : 1);
 -}
  
 +  // Get device-to-host FIS
 +  {
 +    const unsigned char * fis = pthru_buf->Status.bStatusFIS;
 +    ata_out_regs & lo = out.out_regs;
 +    lo.status       = fis[ 2];
 +    lo.error        = fis[ 3];
 +    lo.lba_low      = fis[ 4];
 +    lo.lba_mid      = fis[ 5];
 +    lo.lba_high     = fis[ 6];
 +    lo.device       = fis[ 7];
 +    lo.sector_count = fis[12];
 +    if (in.in_regs.is_48bit_cmd()) {
 +      ata_out_regs & hi = out.out_regs.prev;
 +      hi.lba_low      = fis[ 8];
 +      hi.lba_mid      = fis[ 9];
 +      hi.lba_high     = fis[10];
 +      hi.sector_count = fis[13];
 +    }
 +  }
  
 -/////////////////////////////////////////////////////////////////////////////
 +  // Get data
 +  if (in.direction == ata_cmd_in::data_in)
 +    // TODO: Check ptru_buf->Status.uDataBytes
 +    memcpy(in.buffer, pthru_buf->bDataBuffer, in.size);
  
++<<<<<<< HEAD
++=======
+ // Return true if ATA drive behind a SAT layer
+ static bool is_sat(const STORAGE_DEVICE_DESCRIPTOR_DATA * data)
+ {
+   if (!data->desc.VendorIdOffset)
+     return false;
+   if (strcmp(data->raw + data->desc.VendorIdOffset, "ATA     "))
+     return false;
+   return true;
+ }
+ // Return true if Intel ICHxR RAID volume
+ static bool is_intel_raid_volume(const STORAGE_DEVICE_DESCRIPTOR_DATA * data)
+ {
+   if (!(data->desc.VendorIdOffset && data->desc.ProductIdOffset))
+     return false;
+   const char * vendor = data->raw + data->desc.VendorIdOffset;
+   if (!(!strnicmp(vendor, "Intel", 5) && strspn(vendor+5, " ") == strlen(vendor+5)))
+     return false;
+   if (strnicmp(data->raw + data->desc.ProductIdOffset, "Raid ", 5))
+     return false;
++>>>>>>> 3d8ad6fa4529eb02ae1391a1e937bf57aad3fb74
    return true;
  }
  
 -// get DEV_* for open handle
 -static win_dev_type get_controller_type(HANDLE hdevice, bool admin, GETVERSIONINPARAMS_EX * ata_version_ex)
 +
 +//////////////////////////////////////////////////////////////////////
 +// win_csmi_device
 +
 +class win_csmi_device
 +: public /*implements*/ csmi_ata_device
  {
 -  // Get BusType from device descriptor
 -  STORAGE_DEVICE_DESCRIPTOR_DATA data;
 -  if (storage_query_property_ioctl(hdevice, &data))
 -    return DEV_UNKNOWN;
 +public:
 +  win_csmi_device(smart_interface * intf, const char * dev_name,
 +    const char * req_type);
  
++<<<<<<< HEAD
 +  virtual ~win_csmi_device() throw();
 +
 +  virtual bool open();
 +
 +  virtual bool close();
++=======
+   // Newer BusType* values are missing in older includes
+   switch ((int)data.desc.BusType) {
+     case BusTypeAta:
+     case 0x0b: // BusTypeSata
+       // Certain Intel AHCI drivers (C600+/C220+) have broken
+       // IOCTL_ATA_PASS_THROUGH support and a working SAT layer
+       if (is_sat(&data))
+         return DEV_SAT;
+       if (ata_version_ex)
+         memset(ata_version_ex, 0, sizeof(*ata_version_ex));
+       return DEV_ATA;
+     case BusTypeScsi:
+     case BusTypeRAID:
+       if (is_sat(&data))
+         return DEV_SAT;
+       // Intel ICHxR RAID volume: reports SMART_GET_VERSION but does not support SMART_*
+       if (is_intel_raid_volume(&data))
+         return DEV_SCSI;
+       // LSI/3ware RAID volume: supports SMART_*
+       if (admin && smart_get_version(hdevice, ata_version_ex) >= 0)
+         return DEV_ATA;
+       return DEV_SCSI;
+     case 0x09: // BusTypeiScsi
+     case 0x0a: // BusTypeSas
+       if (is_sat(&data))
+         return DEV_SAT;
+       return DEV_SCSI;
++>>>>>>> 3d8ad6fa4529eb02ae1391a1e937bf57aad3fb74
  
 -    case BusTypeUsb:
 -      return DEV_USB;
 +  virtual bool is_open() const;
  
 -    default:
 -      return DEV_UNKNOWN;
 -  }
 -  /*NOTREACHED*/
 +  bool open_scsi();
 +
 +protected:
 +  virtual bool csmi_ioctl(unsigned code, IOCTL_HEADER * csmi_buffer,
 +    unsigned csmi_bufsiz);
 +
 +private:
 +  HANDLE m_fh; ///< Controller device handle
 +  int m_port; ///< Port number
 +};
 +
 +
 +//////////////////////////////////////////////////////////////////////
 +
 +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_port(-1)
 +{
  }
  
 -// get DEV_* for device path
 -static win_dev_type get_controller_type(const char * path, GETVERSIONINPARAMS_EX * ata_version_ex = 0)
 +win_csmi_device::~win_csmi_device() throw()
  {
 -  bool admin = true;
 -  HANDLE h = CreateFileA(path, GENERIC_READ|GENERIC_WRITE,
 -    FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
 -  if (h == INVALID_HANDLE_VALUE) {
 -    admin = false;
 -    h = CreateFileA(path, 0,
 -      FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
 -    if (h == INVALID_HANDLE_VALUE)
 -      return DEV_UNKNOWN;
 -  }
 -  if (ata_debugmode > 1 || scsi_debugmode > 1)
 -    pout(" %s: successfully opened%s\n", path, (!admin ? " (without admin rights)" :""));
 -  win_dev_type type = get_controller_type(h, admin, ata_version_ex);
 -  CloseHandle(h);
 -  return type;
 +  if (m_fh != INVALID_HANDLE_VALUE)
 +    CloseHandle(m_fh);
  }
  
 -// get DEV_* for physical drive number
 -static win_dev_type get_phy_drive_type(int drive, GETVERSIONINPARAMS_EX * ata_version_ex)
 +bool win_csmi_device::is_open() const
  {
 -  char path[30];
 -  snprintf(path, sizeof(path)-1, "\\\\.\\PhysicalDrive%d", drive);
 -  return get_controller_type(path, ata_version_ex);
 +  return (m_fh != INVALID_HANDLE_VALUE);
  }
  
 -static win_dev_type get_phy_drive_type(int drive)
 +bool win_csmi_device::close()
  {
 -  return get_phy_drive_type(drive, 0);
 +  if (m_fh == INVALID_HANDLE_VALUE)
 +    return true;
 +  BOOL rc = CloseHandle(m_fh);
 +  m_fh = INVALID_HANDLE_VALUE;
 +  return !!rc;
  }
  
 -// get DEV_* for logical drive number
 -static win_dev_type get_log_drive_type(int drive)
 +
 +bool win_csmi_device::open_scsi()
  {
 -  char path[30];
 -  snprintf(path, sizeof(path)-1, "\\\\.\\%c:", 'A'+drive);
 -  return get_controller_type(path);
 +  // Parse name
 +  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, &port, &nc) >= 0
 +        && nc == (int)strlen(name) && contr_no <= 9 && port < 32)  )
 +    return set_err(EINVAL);
 +
 +  // Open controller handle
 +  char devpath[30];
 +  snprintf(devpath, sizeof(devpath)-1, "\\\\.\\Scsi%u:", contr_no);
 +
 +  HANDLE h = CreateFileA(devpath, GENERIC_READ|GENERIC_WRITE,
 +    FILE_SHARE_READ|FILE_SHARE_WRITE,
 +    (SECURITY_ATTRIBUTES *)0, OPEN_EXISTING, 0, 0);
 +
 +  if (h == INVALID_HANDLE_VALUE) {
 +    long err = GetLastError();
 +    if (err == ERROR_FILE_NOT_FOUND)
 +      set_err(ENOENT, "%s: not found", devpath);
 +    else if (err == ERROR_ACCESS_DENIED)
 +      set_err(EACCES, "%s: access denied", devpath);
 +    else
 +      set_err(EIO, "%s: Error=%ld", devpath, err);
 +    return false;
 +  }
 +
 +  if (scsi_debugmode > 1)
 +    pout(" %s: successfully opened\n", devpath);
 +
 +  m_fh = h;
 +  m_port = port;
 +  return true;
  }
  
 -// Build IDENTIFY information from STORAGE_DEVICE_DESCRIPTOR
 -static int get_identify_from_device_property(HANDLE hdevice, ata_identify_device * id)
 +
 +bool win_csmi_device::open()
  {
 -  STORAGE_DEVICE_DESCRIPTOR_DATA data;
 -  if (storage_query_property_ioctl(hdevice, &data))
 -    return -1;
 +  if (!open_scsi())
 +    return false;
  
 -  memset(id, 0, sizeof(*id));
 +  // Get Phy info for this drive
 +  if (!select_port(m_port)) {
 +    close();
 +    return false;
 +  }
  
 -  // Some drivers split ATA model string into VendorId and ProductId,
 -  // others return it as ProductId only.
 -  char model[sizeof(id->model) + 1] = "";
 +  return true;
 +}
  
 -  unsigned i = 0;
 -  if (data.desc.VendorIdOffset) {
 -    for ( ;i < sizeof(model)-1 && data.raw[data.desc.VendorIdOffset+i]; i++)
 -      model[i] = data.raw[data.desc.VendorIdOffset+i];
 +
 +bool win_csmi_device::csmi_ioctl(unsigned code, IOCTL_HEADER * csmi_buffer,
 +  unsigned csmi_bufsiz)
 +{
 +  // Determine signature
 +  const char * sig;
 +  switch (code) {
 +    case CC_CSMI_SAS_GET_DRIVER_INFO:
 +      sig = CSMI_ALL_SIGNATURE; break;
 +    case CC_CSMI_SAS_GET_PHY_INFO:
 +    case CC_CSMI_SAS_STP_PASSTHRU:
 +      sig = CSMI_SAS_SIGNATURE; break;
 +    default:
 +      return set_err(ENOSYS, "Unknown CSMI code=%u", code);
    }
  
 -  if (data.desc.ProductIdOffset) {
 -    while (i > 1 && model[i-2] == ' ') // Keep last blank from VendorId
 -      i--;
 -    // Ignore VendorId "ATA"
 -    if (i <= 4 && !strncmp(model, "ATA", 3) && (i == 3 || model[3] == ' '))
 -      i = 0;
 -    for (unsigned j = 0; i < sizeof(model)-1 && data.raw[data.desc.ProductIdOffset+j]; i++, j++)
 -      model[i] = data.raw[data.desc.ProductIdOffset+j];
 +  // Set header
 +  csmi_buffer->HeaderLength = sizeof(IOCTL_HEADER);
 +  strncpy((char *)csmi_buffer->Signature, sig, sizeof(csmi_buffer->Signature));
 +  csmi_buffer->Timeout = CSMI_SAS_TIMEOUT;
 +  csmi_buffer->ControlCode = code;
 +  csmi_buffer->ReturnCode = 0;
 +  csmi_buffer->Length = csmi_bufsiz - sizeof(IOCTL_HEADER);
 +
 +  // Call function
 +  DWORD num_out = 0;
 +  if (!DeviceIoControl(m_fh, IOCTL_SCSI_MINIPORT,
 +    csmi_buffer, csmi_bufsiz, csmi_buffer, csmi_bufsiz, &num_out, (OVERLAPPED*)0)) {
 +    long err = GetLastError();
 +    if (scsi_debugmode)
 +      pout("  IOCTL_SCSI_MINIPORT(CC_CSMI_%u) failed, Error=%ld\n", code, err);
 +    if (   err == ERROR_INVALID_FUNCTION
 +        || err == ERROR_NOT_SUPPORTED
 +        || err == ERROR_DEV_NOT_EXIST)
 +      return set_err(ENOSYS, "CSMI is not supported (Error=%ld)", err);
 +    else
 +      return set_err(EIO, "CSMI(%u) failed with Error=%ld", code, err);
    }
  
 -  while (i > 0 && model[i-1] == ' ')
 -    i--;
 -  model[i] = 0;
 -  copy_swapped(id->model, model, sizeof(id->model));
 +  // Check result
 +  if (csmi_buffer->ReturnCode) {
 +    if (scsi_debugmode) {
 +      pout("  IOCTL_SCSI_MINIPORT(CC_CSMI_%u) failed, ReturnCode=%u\n",
 +        code, (unsigned)csmi_buffer->ReturnCode);
 +    }
 +    return set_err(EIO, "CSMI(%u) failed with ReturnCode=%u", code, (unsigned)csmi_buffer->ReturnCode);
 +  }
  
 -  if (data.desc.ProductRevisionOffset)
 -    copy_swapped(id->fw_rev, data.raw+data.desc.ProductRevisionOffset, sizeof(id->fw_rev));
 +  if (scsi_debugmode > 1)
 +    pout("  IOCTL_SCSI_MINIPORT(CC_CSMI_%u) succeeded, bytes returned: %u\n", code, (unsigned)num_out);
  
 -  id->command_set_1 = 0x0001; id->command_set_2 = 0x4000; // SMART supported, words 82,83 valid
 -  id->cfs_enable_1  = 0x0001; id->csf_default   = 0x4000; // SMART enabled, words 85,87 valid
 -  return 0;
 +  return true;
  }
  
 -// Get Serial Number in IDENTIFY from WMI
 -static bool get_serial_from_wmi(int drive, ata_identify_device * id)
 -{
 -  bool debug = (ata_debugmode > 1);
  
 -  wbem_services ws;
 -  if (!ws.connect()) {
 -    if (debug)
 -      pout("WMI connect failed\n");
 -    return false;
 -  }
 +//////////////////////////////////////////////////////////////////////
 +// win_tw_cli_device
 +
 +// Routines for pseudo device /dev/tw_cli/*
 +// Parses output of 3ware "tw_cli /cx/py show all" or 3DM SMART data window
 +// TODO: This is OS independent
 +
 +class win_tw_cli_device
 +: public /*implements*/ ata_device_with_command_set
 +{
 +public:
 +  win_tw_cli_device(smart_interface * intf, const char * dev_name, const char * req_type);
 +
 +  virtual bool is_open() const;
 +
 +  virtual bool open();
 +
 +  virtual bool close();
 +
 +protected:
 +  virtual int ata_command_interface(smart_command_set command, int select, char * data);
 +
 +private:
 +  bool m_ident_valid, m_smart_valid;
 +  ata_identify_device m_ident_buf;
 +  ata_smart_values m_smart_buf;
 +};
 +
 +
 +/////////////////////////////////////////////////////////////////////////////
  
 -  wbem_object wo;
 -  if (!ws.query1(wo, "SELECT Model,SerialNumber FROM Win32_DiskDrive WHERE "
 -                     "DeviceID=\"\\\\\\\\.\\\\PHYSICALDRIVE%d\"", drive))
 -    return false;
 +win_tw_cli_device::win_tw_cli_device(smart_interface * intf, const char * dev_name, const char * req_type)
 +: smart_device(intf, dev_name, "tw_cli", req_type),
 +  m_ident_valid(false), m_smart_valid(false)
 +{
 +  memset(&m_ident_buf, 0, sizeof(m_ident_buf));
 +  memset(&m_smart_buf, 0, sizeof(m_smart_buf));
 +}
  
 -  std::string serial = wo.get_str("SerialNumber");
 -  if (debug)
 -    pout("  WMI:PhysicalDrive%d: \"%s\", S/N:\"%s\"\n", drive, wo.get_str("Model").c_str(), serial.c_str());
  
 -  copy_swapped(id->serial_no, serial.c_str(), sizeof(id->serial_no));
 -  return true;
 +bool win_tw_cli_device::is_open() const
 +{
 +  return (m_ident_valid || m_smart_valid);
  }
  
  
@@@ -4434,7 -3966,174 +4732,171 @@@ bool win_smart_interface::disable_syste
    return true;
  }
  
+ // AACRAID
+ win_aacraid_device::win_aacraid_device(smart_interface * intf,
+   const char *dev_name, unsigned ctrnum, unsigned target, unsigned lun)
+ : smart_device(intf, dev_name, "aacraid", "aacraid"),
+   m_ctrnum(ctrnum), m_lun(lun), m_target(target)
+ {
+   set_info().info_name = strprintf("%s [aacraid_disk_%02d_%02d_%d]", dev_name, m_ctrnum, m_lun, m_target);
+   set_info().dev_type  = strprintf("aacraid,%d,%d,%d", m_ctrnum, m_lun, m_target);
+ }
+ win_aacraid_device::~win_aacraid_device() throw()
+ {
+ }
+ bool win_aacraid_device::open()
+ {
+   if (is_open())
+     return true;
+   HANDLE hFh = CreateFile( get_dev_name(),
+           GENERIC_READ|GENERIC_WRITE,
+           FILE_SHARE_READ|FILE_SHARE_WRITE,
+           NULL,
+           OPEN_EXISTING,
+           0,
+           0);
+   if (hFh == INVALID_HANDLE_VALUE)
+     return set_err(ENODEV, "Open failed, Error=%u", (unsigned)GetLastError());
+   set_fh(hFh);
+   return true;
+ }
+ bool win_aacraid_device::scsi_pass_through(struct 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 : (int)iop->dxfer_len) , 1);
+       }
+     else
+       j += snprintf(&buff[j], (sz > j ? (sz - j) : 0), "]\n");
+       pout("buff %s\n",buff);
+   }
+   char ioBuffer[1000];
+   SRB_IO_CONTROL * pSrbIO = (SRB_IO_CONTROL *) ioBuffer;
+   SCSI_REQUEST_BLOCK * pScsiIO = (SCSI_REQUEST_BLOCK *) (ioBuffer + sizeof(SRB_IO_CONTROL));
+   DWORD scsiRequestBlockSize = sizeof(SCSI_REQUEST_BLOCK);
+   char *pRequestSenseIO = (char *) (ioBuffer + sizeof(SRB_IO_CONTROL) + scsiRequestBlockSize);
+   DWORD dataOffset = (sizeof(SRB_IO_CONTROL) + scsiRequestBlockSize  + 7) & 0xfffffff8;
+   char *pDataIO = (char *) (ioBuffer + dataOffset);
+   memset(pScsiIO, 0, scsiRequestBlockSize);
+   pScsiIO->Length    = (USHORT) scsiRequestBlockSize;
+   pScsiIO->Function  = SRB_FUNCTION_EXECUTE_SCSI;
+   pScsiIO->PathId    = 0;
+   pScsiIO->TargetId  = m_target;
+   pScsiIO->Lun       = m_lun;
+   pScsiIO->CdbLength = (int)iop->cmnd_len;
+   switch(iop->dxfer_dir){
+     case DXFER_NONE:
+       pScsiIO->SrbFlags = SRB_NoDataXfer;
+       break;
+     case DXFER_FROM_DEVICE:
+       pScsiIO->SrbFlags |= SRB_DataIn;
+       break;
+     case DXFER_TO_DEVICE:
+       pScsiIO->SrbFlags |= SRB_DataOut;
+       break;
+     default:
+       pout("aacraid: bad dxfer_dir\n");
+       return set_err(EINVAL, "aacraid: bad dxfer_dir\n");
+   }
+   pScsiIO->DataTransferLength = (ULONG)iop->dxfer_len;
+   pScsiIO->TimeOutValue = iop->timeout;
+   UCHAR *pCdb = (UCHAR *) pScsiIO->Cdb;
+   memcpy(pCdb, iop->cmnd, 16);
+   if (iop->max_sense_len){
+     memset(pRequestSenseIO, 0, iop->max_sense_len);
+   }
+   if (pScsiIO->SrbFlags & SRB_FLAGS_DATA_OUT){
+     memcpy(pDataIO, iop->dxferp, iop->dxfer_len);
+   }
+   else if (pScsiIO->SrbFlags & SRB_FLAGS_DATA_IN){
+     memset(pDataIO, 0, iop->dxfer_len);
+   }
+   DWORD bytesReturned = 0;
+   memset(pSrbIO, 0, sizeof(SRB_IO_CONTROL));
+   pSrbIO->HeaderLength = sizeof(SRB_IO_CONTROL);
+   memcpy(pSrbIO->Signature, "AACAPI", 7);
+   pSrbIO->ControlCode = ARCIOCTL_SEND_RAW_SRB;
+   pSrbIO->Length = (dataOffset + iop->dxfer_len - sizeof(SRB_IO_CONTROL) + 7) & 0xfffffff8;
+   pSrbIO->Timeout = 3*60;
+   if (!DeviceIoControl(
+                    get_fh(),
+                    IOCTL_SCSI_MINIPORT,
+                    ioBuffer,
+                    sizeof(SRB_IO_CONTROL) + pSrbIO->Length,
+                    ioBuffer,
+                    sizeof(SRB_IO_CONTROL) + pSrbIO->Length,
+                    &bytesReturned,
+                    NULL)
+      ) {
+     return set_err(EIO, "ARCIOCTL_SEND_RAW_SRB failed, Error=%u", (unsigned)GetLastError());
+   }
+   iop->scsi_status = pScsiIO->ScsiStatus;
+   if (SCSI_STATUS_CHECK_CONDITION & iop->scsi_status) {
+     int slen = sizeof(pRequestSenseIO) + 8;
+     if (slen > (int)sizeof(pRequestSenseIO))
+       slen = sizeof(pRequestSenseIO);
+     if (slen > (int)iop->max_sense_len)
+       slen = (int)iop->max_sense_len;
+     memcpy(iop->sensep, pRequestSenseIO, 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_dir == DXFER_FROM_DEVICE){
+      memcpy(iop->dxferp,pDataIO, iop->dxfer_len);
+   }
+   if((iop->dxfer_dir == DXFER_FROM_DEVICE) && (report > 1)){
+     int trunc = (iop->dxfer_len > 256) ? 1 : 0;
+     pout("  Incoming data, len=%d, resid=%d%s:\n", (int)iop->dxfer_len, iop->resid,
+       (trunc ? " [only first 256 bytes shown]" : ""));
+     dStrHex((CHAR*)pDataIO, (trunc ? 256 : (int)(iop->dxfer_len)) , 1);
+   }
+   return true;
+ }
  
 -//////////////////////////////////////////////////////////////////////////////////////////////////
 -
 -
  } // namespace
  
  /////////////////////////////////////////////////////////////////////////////
index 78ce0145279047fdb7198798eaca9a128d878f23,d06e0859e242ec27299e560e8496945083549651..6ac484326d0e69e28d10f18440d39a7f34a8f26c
  ; You should have received a copy of the GNU General Public License
  ; (for example COPYING); If not, see <http://www.gnu.org/licenses/>.
  ;
++<<<<<<< HEAD
 +; $Id: installer.nsi 4174 2015-11-22 16:19:29Z chrfranke $
++=======
+ ; $Id: installer.nsi 4072 2015-04-28 20:35:15Z chrfranke $
++>>>>>>> 3d8ad6fa4529eb02ae1391a1e937bf57aad3fb74
  ;
  
  
@@@ -717,19 -658,16 +721,32 @@@ Function AddToPat
    System::Call "advapi32::RegQueryValueEx(i $3, t'PATH', i 0, i 0, t.r1, *i ${NSIS_MAX_STRLEN} r2) i.r4"
    System::Call "advapi32::RegCloseKey(i $3)"
  
++<<<<<<< HEAD
 +  ${If} $4 = 234 ; ERROR_MORE_DATA
 +    DetailPrint "AddToPath: original length $2 > ${NSIS_MAX_STRLEN}"
 +    MessageBox MB_OK "PATH not updated, original length $2 > ${NSIS_MAX_STRLEN}" /SD IDOK
 +    Goto done
 +  ${EndIf}
 +
 +  ${If} $4 <> 0 ; NO_ERROR
 +    ${If} $4 <> 2 ; ERROR_FILE_NOT_FOUND
 +      DetailPrint "AddToPath: unexpected error code $4"
 +      Goto done
 +    ${EndIf}
 +    StrCpy $1 ""
 +  ${EndIf}
++=======
+   IntCmp $4 234 0 +4 +4 ; $4 == ERROR_MORE_DATA
+     DetailPrint "AddToPath: original length $2 > ${NSIS_MAX_STRLEN}"
+     MessageBox MB_OK "PATH not updated, original length $2 > ${NSIS_MAX_STRLEN}"
+     Goto done
+   IntCmp $4 0 +5 ; $4 != NO_ERROR
+     IntCmp $4 2 +3 ; $4 != ERROR_FILE_NOT_FOUND
+       DetailPrint "AddToPath: unexpected error code $4"
+       Goto done
+     StrCpy $1 ""
++>>>>>>> 3d8ad6fa4529eb02ae1391a1e937bf57aad3fb74
  
    ; Check if already in PATH
    Push "$1;"
    StrLen $3 $1
    IntOp $2 $2 + $3
    IntOp $2 $2 + 2 ; $2 = strlen(dir) + strlen(PATH) + sizeof(";")
++<<<<<<< HEAD
 +  ${If} $2 > ${NSIS_MAX_STRLEN}
 +    DetailPrint "AddToPath: new length $2 > ${NSIS_MAX_STRLEN}"
 +    MessageBox MB_OK "PATH not updated, new length $2 > ${NSIS_MAX_STRLEN}." /SD IDOK
 +    Goto done
 +  ${EndIf}
++=======
+   IntCmp $2 ${NSIS_MAX_STRLEN} +4 +4 0
+     DetailPrint "AddToPath: new length $2 > ${NSIS_MAX_STRLEN}"
+     MessageBox MB_OK "PATH not updated, new length $2 > ${NSIS_MAX_STRLEN}."
+     Goto done
++>>>>>>> 3d8ad6fa4529eb02ae1391a1e937bf57aad3fb74
  
    ; Append dir to PATH
    DetailPrint "Add to PATH: $0"
diff --cc scsiata.cpp
index 26a9290c4d0a32e718ed34a8eecc73cb0440b948,fbe603b356ed563a60d538d12f69c7d69bbd617e..217acd6cc4ea467e82b12261d782840fa1648bfb
  #include "dev_ata_cmd_set.h" // ata_device_with_command_set
  #include "dev_tunnelled.h" // tunnelled_device<>
  
++<<<<<<< HEAD
 +const char * scsiata_cpp_cvsid = "$Id: scsiata.cpp 4276 2016-04-02 19:13:39Z chrfranke $";
++=======
+ const char * scsiata_cpp_cvsid = "$Id: scsiata.cpp 4041 2015-03-14 00:50:20Z dpgilbert $";
++>>>>>>> 3d8ad6fa4529eb02ae1391a1e937bf57aad3fb74
  
  /* This is a slightly stretched SCSI sense "descriptor" format header.
     The addition is to allow the 0x70 and 0x71 response codes. The idea
@@@ -394,16 -394,6 +398,19 @@@ bool sat_device::ata_pass_through(cons
          }
          scsi_do_sense_disect(&io_hdr, &sinfo);
          int status = scsiSimpleSenseFilter(&sinfo);
++<<<<<<< HEAD
 +
 +        // Workaround for bogus sense_key in sense data with SAT ATA Return Descriptor
 +        if (   status && ck_cond && ardp && ard_len > 13
 +            && (ardp[13] & 0xc1) == 0x40 /* !BSY && DRDY && !ERR */) {
 +            if (scsi_debugmode > 0)
 +                pout("ATA status (0x%02x) indicates success, ignoring SCSI sense_key\n",
 +                     ardp[13]);
 +            status = 0;
 +        }
 +
++=======
++>>>>>>> 3d8ad6fa4529eb02ae1391a1e937bf57aad3fb74
          if (0 != status) {  /* other than no_sense and recovered_error */
              if (scsi_debugmode > 0) {
                  pout("sat_device::ata_pass_through: scsi error: %s\n",
                  }
              } else if ((! sense_descriptor) &&
                         (0 == ssh.asc) &&
++<<<<<<< HEAD
 +                       (SCSI_ASCQ_ATA_PASS_THROUGH == ssh.ascq) &&
 +                       (0 != io_hdr.sensep[4] /* Some ATA STATUS bit must be set */)) {
++=======
+                        (SCSI_ASCQ_ATA_PASS_THROUGH == ssh.ascq)) {
++>>>>>>> 3d8ad6fa4529eb02ae1391a1e937bf57aad3fb74
                  /* in SAT-2 and later, ATA registers may be passed back via
                   * fixed format sense data [ref: sat3r07 section 12.2.2.7] */
                  ata_out_regs & lo = out.out_regs;
@@@ -1538,15 -1520,15 +1549,19 @@@ ata_device * smart_interface::get_sat_d
        set_err(EINVAL, "Option '-d usbjmicron[,p][,x],<n>' requires <n> to be 0 or 1");
        return 0;
      }
 -    return new usbjmicron_device(this, scsidev, type, prolific, ata_48bit_support, port);
 +    satdev = new usbjmicron_device(this, scsidev, type, prolific, ata_48bit_support, port);
 +  }
 +
 +  else if (!strcmp(type, "usbprolific")) {
 +    satdev = new usbprolific_device(this, scsidev, type);
    }
  
+   else if (!strcmp(type, "usbprolific")) {
+     return new usbprolific_device(this, scsidev, type);
+   }
    else if (!strcmp(type, "usbsunplus")) {
 -    return new usbsunplus_device(this, scsidev, type);
 +    satdev = new usbsunplus_device(this, scsidev, type);
    }
  
    else {
diff --cc scsicmds.cpp
index eb4fb1dd1847e215261106bfb4c088d5ba597c3c,d306d72d5e9771e5d4f331ea809c62ad116eae0d..065962e78a6637aa084f5ca3560a17dc5dd8f320
@@@ -5,7 -5,9 +5,13 @@@
   *
   * Copyright (C) 2002-8 Bruce Allen
   * Copyright (C) 1999-2000 Michael Cornwell <cornwell@acm.org>
++<<<<<<< HEAD
 + * Copyright (C) 2003-16 Douglas Gilbert <dgilbert@interlog.com>
++=======
+  *
+  * Additional SCSI work:
+  * Copyright (C) 2003-15 Douglas Gilbert <dgilbert@interlog.com>
++>>>>>>> 3d8ad6fa4529eb02ae1391a1e937bf57aad3fb74
   *
   * 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
  #include "dev_interface.h"
  #include "utility.h"
  
++<<<<<<< HEAD
 +const char *scsicmds_c_cvsid="$Id: scsicmds.cpp 4243 2016-03-20 18:29:36Z chrfranke $"
++=======
+ const char *scsicmds_c_cvsid="$Id: scsicmds.cpp 4081 2015-05-10 16:42:50Z chrfranke $"
++>>>>>>> 3d8ad6fa4529eb02ae1391a1e937bf57aad3fb74
    SCSICMDS_H_CVSID;
  
  // Print SCSI debug messages?
diff --cc scsicmds.h
index 65402fac56a06fec3fa81612a6a289fd8f8291fa,30a5c97388f42b2bbd8d4c3202f0a2533fd272cc..3451fec78f1d8768d5bc13480f53f29788b9e860
@@@ -5,6 -5,8 +5,11 @@@
   *
   * Copyright (C) 2002-8 Bruce Allen
   * Copyright (C) 2000 Michael Cornwell <cornwell@acm.org>
++<<<<<<< HEAD
++=======
+  *
+  * Additional SCSI work:
++>>>>>>> 3d8ad6fa4529eb02ae1391a1e937bf57aad3fb74
   * Copyright (C) 2003-15 Douglas Gilbert <dgilbert@interlog.com>
   *
   * This program is free software; you can redistribute it and/or modify
  #ifndef SCSICMDS_H_
  #define SCSICMDS_H_
  
++<<<<<<< HEAD
 +#define SCSICMDS_H_CVSID "$Id: scsicmds.h 4152 2015-10-17 16:08:21Z chrfranke $\n"
++=======
+ #define SCSICMDS_H_CVSID "$Id: scsicmds.h 4081 2015-05-10 16:42:50Z chrfranke $\n"
++>>>>>>> 3d8ad6fa4529eb02ae1391a1e937bf57aad3fb74
  
  #include <stdio.h>
  #include <stdlib.h>
diff --cc scsiprint.cpp
index 42e43e65a4c4148871926c728ba6b3e2349abd2c,5e4cb4d164d6d0a08dc27337e369db88c1cb35d3..52b701246abd94d1d91503aad2b9c1961bb227be
  
  #define GBUF_SIZE 65535
  
++<<<<<<< HEAD
 +const char * scsiprint_c_cvsid = "$Id: scsiprint.cpp 4292 2016-04-12 23:06:59Z dpgilbert $"
++=======
+ const char * scsiprint_c_cvsid = "$Id: scsiprint.cpp 4040 2015-03-10 22:30:44Z dpgilbert $"
++>>>>>>> 3d8ad6fa4529eb02ae1391a1e937bf57aad3fb74
                                   SCSIPRINT_H_CVSID;
  
  
diff --cc smartctl.8.in
index 943b6221d7b045730947d156903af031a0285a34,b9bf574a9dc410aa76146f2c8dc948664870810f..6ad026966133f23226f1d0f03aacc238c80296a6
@@@ -1,8 -1,8 +1,14 @@@
  .ig
  Copyright (C) 2002-10 Bruce Allen
++<<<<<<< HEAD
 +Copyright (C) 2004-16 Christian Franke
 +
 +$Id: smartctl.8.in 4311 2016-04-27 21:03:01Z chrfranke $
++=======
+ Copyright (C) 2004-15 Christian Franke
+ $Id: smartctl.8.in 4099 2015-05-30 17:32:13Z chrfranke $
++>>>>>>> 3d8ad6fa4529eb02ae1391a1e937bf57aad3fb74
  
  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
@@@ -134,13 -132,6 +140,16 @@@ scsi controller "\\\\.\\Scsi[0\-9]:"
  
  For SATA or SAS disks behind an Areca controller use
  \fB"/dev/arcmsr[0\-9]"\fP, see \'\-d areca,N[/E]\' below.
++<<<<<<< HEAD
 +
 +[NEW EXPERIMENTAL SMARTCTL FEATURE]
 +Use the forms \fB"/dev/nvme[0\-9]"\fP (broadcast namespace) or
 +\fB"/dev/nvme[0\-9]n[1\-9]"\fP (specific namespace 1\-9) for first,
 +second, ..., NVMe device.
 +Alternatively use the forms \fB"/dev/nvmes[0\-9][n[1\-9]]"\fP for NVMe devices
 +behind the logical scsi controller "\\\\.\\Scsi[0\-9]:".
++=======
++>>>>>>> 3d8ad6fa4529eb02ae1391a1e937bf57aad3fb74
  
  The prefix \fB"/dev/"\fP is optional.
  .\" %ENDIF OS Windows Cygwin
@@@ -995,16 -943,9 +1004,19 @@@ Please note that the TapeAlert log pag
  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.
++<<<<<<< HEAD
 +.\" %IF OS FreeBSD Linux Windows Cygwin
 +
 +[NVMe] [FreeBSD, Linux, Windows and Cygwin only]
 +[NEW EXPERIMENTAL SMARTCTL FEATURE]
 +NVMe status is obtained by reading the "Critical Warning" byte from
 +the SMART/Health Information log.
 +.\" %ENDIF OS FreeBSD Linux Windows Cygwin
++=======
++>>>>>>> 3d8ad6fa4529eb02ae1391a1e937bf57aad3fb74
  .TP
  .B \-c, \-\-capabilities
 -[ATA only] Prints only the generic SMART capabilities.  These
 +[ATA] Prints only the generic SMART capabilities.  These
  show what SMART features are implemented and how the device will
  respond to some of the different SMART commands.  For example it
  shows if the device logs errors, if it supports offline surface
@@@ -2104,17 -2006,17 +2116,31 @@@ browser
  .SH EXAMPLES
  .nf
  .B smartctl \-a /dev/sda
++<<<<<<< HEAD
+ .fi
+ Print a large amount of SMART information for drive /dev/sda .
+ .PP
+ .nf
+ .B smartctl \-s off /dev/sdd
+ .fi
+ Disable SMART monitoring and data log collection on drive /dev/sdd .
+ .PP
+ .nf
+ .B smartctl \-\-smart=on \-\-offlineauto=on \-\-saveauto=on /dev/sda
+ .fi
++=======
 +.fi
 +Print a large amount of SMART information for drive /dev/sda .
 +.PP
 +.nf
 +.B smartctl \-s off /dev/sdd
 +.fi
 +Disable SMART monitoring and data log collection on drive /dev/sdd .
 +.PP
 +.nf
 +.B smartctl \-\-smart=on \-\-offlineauto=on \-\-saveauto=on /dev/sda
 +.fi
++>>>>>>> 3d8ad6fa4529eb02ae1391a1e937bf57aad3fb74
  Enable SMART on drive /dev/sda, enable automatic offline
  testing every four hours, and enable autosaving of
  SMART Attributes.  This is a good start-up line for your system\'s
@@@ -2358,4 -2256,4 +2384,8 @@@ Links to these and other documents may 
  .SH PACKAGE VERSION
  CURRENT_SVN_VERSION CURRENT_SVN_DATE CURRENT_SVN_REV
  .br
++<<<<<<< HEAD
 +$Id: smartctl.8.in 4311 2016-04-27 21:03:01Z chrfranke $
++=======
+ $Id: smartctl.8.in 4099 2015-05-30 17:32:13Z chrfranke $
++>>>>>>> 3d8ad6fa4529eb02ae1391a1e937bf57aad3fb74
diff --cc smartctl.cpp
index 3c2e40569486cf097411416947cd4c8f03f258a9,53ee298bfb589dcc48a1b96e859c80d6f3daf5cb..56158635f648670fe5427529bd2a8596222472c3
@@@ -1,10 -1,10 +1,14 @@@
  /*
   * smartctl.cpp
   *
 - * Home page of code is: http://smartmontools.sourceforge.net
 + * Home page of code is: http://www.smartmontools.org
   *
   * Copyright (C) 2002-11 Bruce Allen
++<<<<<<< HEAD
 + * Copyright (C) 2008-16 Christian Franke
++=======
+  * Copyright (C) 2008-15 Christian Franke
++>>>>>>> 3d8ad6fa4529eb02ae1391a1e937bf57aad3fb74
   * Copyright (C) 2000 Michael Cornwell <cornwell@acm.org>
   *
   * This program is free software; you can redistribute it and/or modify
  #include "smartctl.h"
  #include "utility.h"
  
++<<<<<<< HEAD
 +const char * smartctl_cpp_cvsid = "$Id: smartctl.cpp 4311 2016-04-27 21:03:01Z chrfranke $"
++=======
+ const char * smartctl_cpp_cvsid = "$Id: smartctl.cpp 4080 2015-05-05 20:31:22Z chrfranke $"
++>>>>>>> 3d8ad6fa4529eb02ae1391a1e937bf57aad3fb74
    CONFIG_H_CVSID SMARTCTL_H_CVSID;
  
  // Globals to control printing
diff --cc smartd.8.in
index 3ea06283bff1246c97adaa5f01cd3ef861922da5,8dd7ef4abe2cb085b67c2ad9c4c74916923a9b10..88375e26d821713e6d817f39ac7bc7658ece7943
@@@ -1,8 -1,8 +1,14 @@@
  .ig
  Copyright (C) 2002-10 Bruce Allen
++<<<<<<< HEAD
 +Copyright (C) 2004-16 Christian Franke
 +
 +$Id: smartd.8.in 4299 2016-04-16 19:45:57Z chrfranke $
++=======
+ Copyright (C) 2004-15 Christian Franke
+ $Id: smartd.8.in 4102 2015-06-01 19:25:47Z chrfranke $
++>>>>>>> 3d8ad6fa4529eb02ae1391a1e937bf57aad3fb74
  
  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
@@@ -735,6 -714,6 +741,17 @@@ optional local drive database (see \'\-
  .\" %ENDIF NOT OS Windows
  .SH AUTHORS
  \fBBruce Allen\fP (project initiator),
++<<<<<<< HEAD
++.br
++\fBChristian Franke\fP (project manager, Windows port and all sort of things),
++.br
++\fBDouglas Gilbert\fP (SCSI subsystem),
++.br
++\fBVolker Kuhlmann\fP (moderator of support and database mailing list),
++.br
++\fBGabriele Pohl\fP (wiki & development team support),
++.br
++=======
  .br
  \fBChristian Franke\fP (project manager, Windows port and all sort of things),
  .br
  .br
  \fBGabriele Pohl\fP (wiki & development team support),
  .br
++>>>>>>> 3d8ad6fa4529eb02ae1391a1e937bf57aad3fb74
  \fBAlex Samorukov\fP (FreeBSD port and more, new Trac wiki).
  
  Many other individuals have made contributions and corrections,
@@@ -793,4 -768,4 +811,8 @@@ Links to these and other documents may 
  .SH PACKAGE VERSION
  CURRENT_SVN_VERSION CURRENT_SVN_DATE CURRENT_SVN_REV
  .br
++<<<<<<< HEAD
 +$Id: smartd.8.in 4299 2016-04-16 19:45:57Z chrfranke $
++=======
+ $Id: smartd.8.in 4102 2015-06-01 19:25:47Z chrfranke $
++>>>>>>> 3d8ad6fa4529eb02ae1391a1e937bf57aad3fb74
diff --cc smartd.conf
index d4a0d10adb944d5defb70dd876aaf3bb17f7353b,40fa10ec9855ae262fc15c31586da6f14bc134af..15125056a85cdc87e5cfd6aa50e48af48d4feb98
@@@ -1,8 -1,8 +1,12 @@@
  # Sample configuration file for smartd.  See man smartd.conf.
  
 -# Home page is: http://smartmontools.sourceforge.net
 +# Home page is: http://www.smartmontools.org
  
++<<<<<<< HEAD
 +# $Id: smartd.conf 4120 2015-08-27 16:12:21Z samm2 $
++=======
+ # $Id: smartd.conf 4047 2015-03-22 16:16:24Z chrfranke $
++>>>>>>> 3d8ad6fa4529eb02ae1391a1e937bf57aad3fb74
  
  # smartd will re-read the configuration file if it receives a HUP
  # signal
index 7c38e649a0300a43f65ed720b87b341be9cc1453,21b031fc4467c5af0de29b5ffc680e435f9324dc..d39babba5a828c3b209187b66a280b6ca5906707
@@@ -1,8 -1,8 +1,14 @@@
  .ig
  Copyright (C) 2002-10 Bruce Allen
++<<<<<<< HEAD
 +Copyright (C) 2004-16 Christian Franke
 +
 +$Id: smartd.conf.5.in 4307 2016-04-24 12:37:31Z chrfranke $
++=======
+ Copyright (C) 2004-15 Christian Franke
+ $Id: smartd.conf.5.in 4103 2015-06-01 19:51:18Z chrfranke $
++>>>>>>> 3d8ad6fa4529eb02ae1391a1e937bf57aad3fb74
  
  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
@@@ -578,7 -566,7 +584,11 @@@ Directive are \fIon\fP and \fIoff\fP.  
  [Please see the \fBsmartctl \-S\fP command-line option.]
  .TP
  .B \-H
++<<<<<<< HEAD
 +[ATA] Check the health status of the disk with the SMART RETURN
++=======
+ [ATA only] Check the health status of the disk with the SMART RETURN
++>>>>>>> 3d8ad6fa4529eb02ae1391a1e937bf57aad3fb74
  STATUS command.
  If this command reports a failing health status, then disk
  failure is predicted in less than 24 hours, and a message at loglevel
@@@ -1518,10 -1479,6 +1528,13 @@@ will do the same, but restricts the sca
  will do the same, but only monitors the SMART health status of the
  devices, (rather than the default \-a, which monitors all SMART
  properties).
++<<<<<<< HEAD
 +.br
 +[NEW EXPERIMENTAL SMARTD FEATURE]
 +Multiple \'\-d TYPE\' options may be specified with DEVICESCAN
 +to combine the scan results of more than one TYPE.
++=======
++>>>>>>> 3d8ad6fa4529eb02ae1391a1e937bf57aad3fb74
  
  Configuration entries for specific devices may precede the \fBDEVICESCAN\fP entry.
  For example
@@@ -1613,4 -1570,4 +1626,8 @@@ full path of this file
  .SH PACKAGE VERSION
  CURRENT_SVN_VERSION CURRENT_SVN_DATE CURRENT_SVN_REV
  .br
++<<<<<<< HEAD
 +$Id: smartd.conf.5.in 4307 2016-04-24 12:37:31Z chrfranke $
++=======
+ $Id: smartd.conf.5.in 4103 2015-06-01 19:51:18Z chrfranke $
++>>>>>>> 3d8ad6fa4529eb02ae1391a1e937bf57aad3fb74
diff --cc smartd.cpp
index 99e0c23762a3cc8daaf686a28fae584a0cf9dacb,98c8ca4d00d5178504f893919654cddce7765be7..588e1f485daa7527c673c98e27a66806b80efbe6
@@@ -1,10 -1,10 +1,14 @@@
  /*
 - * Home page of code is: http://smartmontools.sourceforge.net
 + * Home page of code is: http://www.smartmontools.org
   *
 - * Copyright (C) 2002-11 Bruce Allen <smartmontools-support@lists.sourceforge.net>
 + * Copyright (C) 2002-11 Bruce Allen
 + * Copyright (C) 2008-16 Christian Franke
   * Copyright (C) 2000    Michael Cornwell <cornwell@acm.org>
   * Copyright (C) 2008    Oliver Bock <brevilo@users.sourceforge.net>
++<<<<<<< HEAD
++=======
+  * Copyright (C) 2008-15 Christian Franke <smartmontools-support@lists.sourceforge.net>
++>>>>>>> 3d8ad6fa4529eb02ae1391a1e937bf57aad3fb74
   *
   * 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
@@@ -100,11 -102,13 +104,19 @@@ typedef int pid_t
  #define SIGQUIT_KEYNAME "CONTROL-\\"
  #endif // _WIN32
  
++<<<<<<< HEAD
 +const char * smartd_cpp_cvsid = "$Id: smartd.cpp 4308 2016-04-24 13:36:10Z chrfranke $"
++=======
+ #if defined (__SVR4) && defined (__sun)
+ extern "C" int getdomainname(char *, int); // no declaration in header files!
+ #endif
+ const char * smartd_cpp_cvsid = "$Id: smartd.cpp 4059 2015-04-18 17:01:31Z chrfranke $"
++>>>>>>> 3d8ad6fa4529eb02ae1391a1e937bf57aad3fb74
    CONFIG_H_CVSID;
  
 +using namespace smartmontools;
 +
  // smartd exit codes
  #define EXIT_BADCMD    1   // command line did not parse
  #define EXIT_BADCONF   2   // syntax error in config file
index 1517be5dcc08e7f8bc9831c63f1858b5a2cc5d54,092791ed9dc9a594a5d45d1452f3e7713e86974d..e72b0ef8e82eef608a2564b2723e9320f7a3a2a7
@@@ -1,8 -1,8 +1,14 @@@
  .ig
  Copyright (C) 2013 Hannes von Haugwitz <hannes@vonhaugwitz.com>
++<<<<<<< HEAD
 +Copyright (C) 2014-16 Christian Franke
 +
 +$Id: update-smart-drivedb.8.in 4223 2016-02-26 20:18:40Z chrfranke $
++=======
+ Copyright (C) 2014-15 Christian Franke <smartmontools-support@lists.sourceforge.net>
+ $Id: update-smart-drivedb.8.in 4054 2015-04-15 19:04:49Z chrfranke $
++>>>>>>> 3d8ad6fa4529eb02ae1391a1e937bf57aad3fb74
  
  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
@@@ -163,4 -106,4 +169,8 @@@ Alternatively send the info to the smar
  .SH PACKAGE VERSION
  CURRENT_SVN_VERSION CURRENT_SVN_DATE CURRENT_SVN_REV
  .br
++<<<<<<< HEAD
 +$Id: update-smart-drivedb.8.in 4223 2016-02-26 20:18:40Z chrfranke $
++=======
+ $Id: update-smart-drivedb.8.in 4054 2015-04-15 19:04:49Z chrfranke $
++>>>>>>> 3d8ad6fa4529eb02ae1391a1e937bf57aad3fb74
index 98434446c3004195f9c2cc24338df299f33b7215,1b53a52c6521c99cff60cc6c0b73b4c0f5ff4c19..634bd83d3d11604e4dc3d35f91ddbe2e1dbfd74e
@@@ -2,7 -2,7 +2,11 @@@
  #
  # smartmontools drive database update script
  #
++<<<<<<< HEAD
 +# Copyright (C) 2010-16 Christian Franke
++=======
+ # Copyright (C) 2010-14 Christian Franke <smartmontools-support@lists.sourceforge.net>
++>>>>>>> 3d8ad6fa4529eb02ae1391a1e937bf57aad3fb74
  #
  # 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/>.
  #
++<<<<<<< HEAD
 +# $Id: update-smart-drivedb.in 4224 2016-02-26 20:29:24Z chrfranke $
++=======
+ # $Id: update-smart-drivedb.in 4019 2014-12-06 20:12:50Z chrfranke $
++>>>>>>> 3d8ad6fa4529eb02ae1391a1e937bf57aad3fb74
  #
  
  set -e
  touch "$DEST.new"
  chmod 0644 "$DEST.new"
  
++<<<<<<< HEAD
 +if [ "$smtctl" != "-" ]; then
 +  # Check syntax
 +  rm -f "$DEST.error"
 +  if "$smtctl" -B "$DEST.new" -P showall >/dev/null; then
 +    test -n "$q" || echo "$smtctl: syntax OK"
 +  else
 +    mv "$DEST.new" "$DEST.error"
 +    echo "$DEST.error: rejected by $smtctl, probably no longer compatible" >&2
 +    exit 1
 +  fi
++=======
+ # Check syntax
+ rm -f "$DEST.error"
+ if "$SMARTCTL" -B "$DEST.new" -P showall >/dev/null; then :; else
+   mv "$DEST.new" "$DEST.error"
+   echo "$DEST.error: rejected by $SMARTCTL, probably no longer compatible" >&2
+   exit 1
++>>>>>>> 3d8ad6fa4529eb02ae1391a1e937bf57aad3fb74
  fi
  
 -# Keep old file if identical
 +# Keep old file if identical, ignore missing Id keyword expansion in new file
  rm -f "$DEST.lastcheck"
  if [ -f "$DEST" ]; then
 -  if cmp "$DEST" "$DEST.new" >/dev/null 2>/dev/null; then
 +  if    cmp "$DEST" "$DEST.new" >/dev/null 2>/dev/null \
 +     || cat "$DEST" | sed 's|\$''Id''[^$]*\$|$''Id''$|' \
 +        | cmp - "$DEST.new" >/dev/null 2>/dev/null; then
      rm -f "$DEST.new"
      touch "$DEST.lastcheck"
      echo "$DEST is already up to date"
diff --cc utility.cpp
index 40fb2bdc09fc074da1a6a6863eb5dcb8ef1b2a5b,ee6aadb2f4695b5b416c79d8f60bc5662ae1a53d..17af257976a3724a83870e72582d79e468c3e56e
@@@ -1,10 -1,10 +1,15 @@@
  /*
   * utility.cpp
   *
 - * Home page of code is: http://smartmontools.sourceforge.net
 + * Home page of code is: http://www.smartmontools.org
   *
++<<<<<<< HEAD
 + * Copyright (C) 2002-12 Bruce Allen
 + * Copyright (C) 2008-16 Christian Franke
++=======
+  * Copyright (C) 2002-12 Bruce Allen <smartmontools-support@lists.sourceforge.net>
+  * Copyright (C) 2008-15 Christian Franke <smartmontools-support@lists.sourceforge.net>
++>>>>>>> 3d8ad6fa4529eb02ae1391a1e937bf57aad3fb74
   * Copyright (C) 2000 Michael Cornwell <cornwell@acm.org>
   *
   * This program is free software; you can redistribute it and/or modify
  #include "atacmds.h"
  #include "dev_interface.h"
  
++<<<<<<< HEAD
 +const char * utility_cpp_cvsid = "$Id: utility.cpp 4309 2016-04-24 14:59:15Z chrfranke $"
++=======
+ const char * utility_cpp_cvsid = "$Id: utility.cpp 4031 2015-01-01 10:47:48Z chrfranke $"
++>>>>>>> 3d8ad6fa4529eb02ae1391a1e937bf57aad3fb74
                                   UTILITY_H_CVSID INT64_H_CVSID;
  
  const char * packet_types[] = {
@@@ -90,7 -90,7 +99,11 @@@ std::string format_version_info(const c
        "(build date " __DATE__ ")" // checkout without expansion of Id keywords
  #endif
        " [%s] " BUILD_INFO "\n"
++<<<<<<< HEAD
 +    "Copyright (C) 2002-16, Bruce Allen, Christian Franke, www.smartmontools.org\n",
++=======
+     "Copyright (C) 2002-15, Bruce Allen, Christian Franke, www.smartmontools.org\n",
++>>>>>>> 3d8ad6fa4529eb02ae1391a1e937bf57aad3fb74
      prog_name, smi()->get_os_version_str().c_str()
    );
    if (!full)
@@@ -624,6 -644,53 +637,56 @@@ int split_selective_arg(char *s, uint64
    return 0;
  }
  
++<<<<<<< HEAD
++=======
+ #ifdef OLD_INTERFACE
+ int64_t bytes = 0;
+ // Helps debugging.  If the second argument is non-negative, then
+ // decrement bytes by that amount.  Else decrement bytes by (one plus)
+ // length of null terminated string.
+ void *FreeNonZero(void *address, int size, int /*line*/, const char* /*file*/){
+   if (address) {
+     if (size<0)
+       bytes-=1+strlen((char*)address);
+     else
+       bytes-=size;
+     free(address);
+   }
+   return NULL;
+ }
+ // A custom version of strdup() that keeps track of how much memory is
+ // being allocated. If mustexist is set, it also throws an error if we
+ // try to duplicate a NULL string.
+ char *CustomStrDup(const char *ptr, int mustexist, int /*whatline*/, const char* /*file*/){
+   char *tmp;
+   // report error if ptr is NULL and mustexist is set
+   if (ptr==NULL){
+     if (mustexist)
+       throw std::runtime_error("Internal error in CustomStrDup()");
+     else
+       return NULL;
+   }
+   // make a copy of the string...
+   tmp=strdup(ptr);
+   
+   if (!tmp)
+     throw std::bad_alloc();
+   
+   // and track memory usage
+   bytes+=1+strlen(ptr);
+   
+   return tmp;
+ }
+ #endif // OLD_INTERFACE
++>>>>>>> 3d8ad6fa4529eb02ae1391a1e937bf57aad3fb74
  // Returns true if region of memory contains non-zero entries
  bool nonempty(const void * data, int size)
  {
diff --cc utility.h
index bd56a24933aae4efd55ca2bdf522714d0dbcd874,346e0f33297a9c321d8a66e9168e7d8fc87df534..2ede7820829317408fecc9f4dd07962580d1f081
+++ b/utility.h
  #ifndef UTILITY_H_
  #define UTILITY_H_
  
++<<<<<<< HEAD
 +#define UTILITY_H_CVSID "$Id: utility.h 4309 2016-04-24 14:59:15Z chrfranke $"
++=======
+ #define UTILITY_H_CVSID "$Id: utility.h 4028 2014-12-13 14:59:48Z chrfranke $"
++>>>>>>> 3d8ad6fa4529eb02ae1391a1e937bf57aad3fb74
  
  #include <time.h>
  #include <sys/types.h> // for regex.h (according to POSIX)
@@@ -99,6 -102,19 +103,22 @@@ int split_selective_arg(char *s, uint64
  // (exit is not compatible with C++ destructors)
  #define EXIT(status) { throw (int)(status); }
  
++<<<<<<< HEAD
++=======
+ #ifdef OLD_INTERFACE
+ // Utility function to free memory
+ void *FreeNonZero(void* address, int size, int whatline, const char* file);
+ // A custom version of strdup() that keeps track of how much memory is
+ // being allocated. If mustexist is set, it also throws an error if we
+ // try to duplicate a NULL string.
+ char *CustomStrDup(const char *ptr, int mustexist, int whatline, const char* file);
+ #endif // OLD_INTERFACE
++>>>>>>> 3d8ad6fa4529eb02ae1391a1e937bf57aad3fb74
  // Compile time check of byte ordering
  // (inline const function allows compiler to remove dead code)
  inline bool isbigendian()