diff --git a/sm5/CHANGELOG b/sm5/CHANGELOG
index bafb547074ef53dc4f13c2ed3af3b84080b99eed..70654a144188188f2bcf932530c5f42a765d0cff 100644
--- a/sm5/CHANGELOG
+++ b/sm5/CHANGELOG
@@ -1,6 +1,6 @@
 CHANGELOG for smartmontools
 
-$Id: CHANGELOG,v 1.658 2008/03/03 22:38:48 shattered Exp $
+$Id: CHANGELOG,v 1.659 2008/03/04 21:24:58 ballen4705 Exp $
 
 The most recent version of this file is:
 http://smartmontools.cvs.sourceforge.net/smartmontools/sm5/CHANGELOG?view=markup
@@ -36,7 +36,19 @@ NOTES FOR FUTURE RELEASES: see TODO file.
 
 
 
-SMARTMONTOOLS STABLE RELEASE 5.38 2008/02/24
+SMARTMONTOOLS STABLE RELEASE 5.38 2008/03/04
+
+  [BA] smartd.initd.in addition from Erwan Velu <erwan@seanodes.com>
+
+  [BA] smartd fixes:
+
+       - On Linux, DEVICESCAN now automatically recognizes SATA devices
+         behind libata, and SATA devices behind the Marvell driver, and
+         treats them correctly.
+
+       - On Linux, a '-d sat' or '-d marvell' is automatically added
+         if libata or the marvell driver are recognized behind a SCSI
+         device type
 
   [SS] (Maybe) fix attribute autosave in FreeBSD.
 
diff --git a/sm5/NEWS b/sm5/NEWS
index 059fc6a7310be59070ad1b04b7f2a5c5724cf071..0df7b1ee7545d92c12efe1b7b6fed19259e4310c 100644
--- a/sm5/NEWS
+++ b/sm5/NEWS
@@ -1,17 +1,19 @@
 smartmontools NEWS
 ------------------
-CVS ID: $Id: NEWS,v 1.33 2008/02/24 20:16:31 ballen4705 Exp $
+CVS ID: $Id: NEWS,v 1.34 2008/03/04 21:24:58 ballen4705 Exp $
 
 The most up-to-date version of this file is:
 http://smartmontools.cvs.sourceforge.net/smartmontools/sm5/NEWS?view=markup
 
-Date 2008-02-24
+Date 2008-03-04
 Summary: smartmontools release 5.38 (STABLE)
 --------------------------------------------
 This is a stable release of smartmontools.  In addition to changes
 below, it includes:
 
- - Fixed auto-offline support in FreeBSD
+ - Libata/Marvell driver devices no longer need explicit '-d' switch
+ - DEVICESCAN automatically detects libata/marvell driver SATA devices 
+ - Fixed auto-offline/autosave support in FreeBSD
  - SAT device type + SCSI generic devices work properly with smartd under Linux
  - Many additions to drive database
  - More portable autogen/autoconf/automake script set
diff --git a/sm5/smartd.cpp b/sm5/smartd.cpp
index fa809c8532733efd4a2147a55e1f404fecbbc846..48d748eacd09801a7b4c2c960e0f5d171d6c93fa 100644
--- a/sm5/smartd.cpp
+++ b/sm5/smartd.cpp
@@ -119,14 +119,14 @@ extern "C" int getdomainname(char *, int); // no declaration in header files!
 extern const char *atacmdnames_c_cvsid, *atacmds_c_cvsid, *ataprint_c_cvsid, *escalade_c_cvsid, 
                   *knowndrives_c_cvsid, *os_XXXX_c_cvsid, *scsicmds_c_cvsid, *utility_c_cvsid;
 
-static const char *filenameandversion="$Id: smartd.cpp,v 1.395 2007/11/26 18:11:32 guidog Exp $";
+static const char *filenameandversion="$Id: smartd.cpp,v 1.396 2008/03/04 21:24:58 ballen4705 Exp $";
 #ifdef NEED_SOLARIS_ATA_CODE
 extern const char *os_solaris_ata_s_cvsid;
 #endif
 #ifdef _WIN32
 extern const char *daemon_win32_c_cvsid, *hostname_win32_c_cvsid, *syslog_win32_c_cvsid;
 #endif
-const char *smartd_c_cvsid="$Id: smartd.cpp,v 1.395 2007/11/26 18:11:32 guidog Exp $" 
+const char *smartd_c_cvsid="$Id: smartd.cpp,v 1.396 2008/03/04 21:24:58 ballen4705 Exp $" 
 ATACMDS_H_CVSID ATAPRINT_H_CVSID CONFIG_H_CVSID
 #ifdef DAEMON_WIN32_H_CVSID
 DAEMON_WIN32_H_CVSID
@@ -189,8 +189,8 @@ int cfgentries_max=0;
 
 // pointers to ATA and SCSI devices being monitored, maximum and
 // actual numbers
-cfgfile **atadevlist=NULL, **scsidevlist=NULL;
-int atadevlist_max=0, scsidevlist_max=0;
+cfgfile **ATAandSCSIdevlist=NULL;
+int ATAandSCSIdevlist_max=0;
 int numdevata=0, numdevscsi=0;
 
 // track memory usage
@@ -392,17 +392,11 @@ void RmAllConfigEntries(){
 void RmAllDevEntries(){
   int i;
   
-  for (i=0; i<atadevlist_max; i++)
-    RmConfigEntry(atadevlist+i, __LINE__);
-
-  atadevlist=FreeNonZero(atadevlist, sizeof(cfgfile *)*atadevlist_max, __LINE__, filenameandversion);
-  atadevlist_max=0;
-
-  for (i=0; i<scsidevlist_max; i++)
-    RmConfigEntry(scsidevlist+i, __LINE__);
+  for (i=0; i<ATAandSCSIdevlist_max; i++)
+      RmConfigEntry(ATAandSCSIdevlist+i, __LINE__);
   
-  scsidevlist=FreeNonZero(scsidevlist, sizeof(cfgfile *)*scsidevlist_max, __LINE__, filenameandversion);
-  scsidevlist_max=0;
+  ATAandSCSIdevlist=FreeNonZero(ATAandSCSIdevlist, sizeof(cfgfile *)*ATAandSCSIdevlist_max, __LINE__, filenameandversion);
+  ATAandSCSIdevlist_max=0;
 
   return;
 }
@@ -1609,8 +1603,8 @@ int ATADeviceScan(cfgfile *cfg, int scanning){
   }
   
   // Do we still have entries available?
-  while (numdevata>=atadevlist_max)
-    atadevlist=AllocateMoreSpace(atadevlist, &atadevlist_max, "ATA device");
+  while (numdevata+numdevscsi>=ATAandSCSIdevlist_max)
+    ATAandSCSIdevlist=AllocateMoreSpace(ATAandSCSIdevlist, &ATAandSCSIdevlist_max, "ATA and SCSI devices");
   
   // register device
   PrintOut(LOG_INFO,"Device: %s, is SMART capable. Adding to \"monitor\" list.\n",name);
@@ -1624,10 +1618,12 @@ int ATADeviceScan(cfgfile *cfg, int scanning){
   return 0;
 }
 
-// Returns 0 if normal SCSI device. Returns -1 if INQUIRY fails.
+// Returns 0 if normal SCSI device.
+// Returns -1 if INQUIRY fails.
 // Returns 2 if ATA device detected behind SAT layer.
+// Returns 3 if ATA device detected behind Marvell controller.
 // Returns 1 if other device detected that we don't want to treat
-// as a normal SCSI device.
+//     as a normal SCSI device.
 static int SCSIFilterKnown(int fd, char * device)
 {
   char req_buff[256];
@@ -1642,7 +1638,7 @@ static int SCSIFilterKnown(int fd, char * device)
     if (scsiStdInquiry(fd, (unsigned char *)req_buff, req_len)) {
       PrintOut(LOG_INFO, "Device: %s, failed on INQUIRY; skip device\n", device);
       // device doesn't like INQUIRY commands
-      return -1;
+      return SCSIFK_FAILED;
     }
   }
   avail_len = req_buff[4] + 5;
@@ -1651,29 +1647,25 @@ static int SCSIFilterKnown(int fd, char * device)
     if (0 == strncmp(req_buff + 8, "3ware", 5) || 0 == strncmp(req_buff + 8, "AMCC", 4) ) {
       PrintOut(LOG_INFO, "Device %s, please try adding '-d 3ware,N'\n", device);
       PrintOut(LOG_INFO, "Device %s, you may need to replace %s with /dev/twaN or /dev/tweN\n", device, device);
-      return 1;
+      return SCSIFK_3WARE;
     } else if ((len >= 42) && (0 == strncmp(req_buff + 36, "MVSATA", 6))) {
-      PrintOut(LOG_INFO, "Device %s, please try '-d marvell'\n", device);
-      return 1;
+      PrintOut(LOG_INFO, "Device %s: using '-d marvell' for ATA disk with Marvell driver\n", device);
+      return SCSIFK_MARVELL;
     } else if ((avail_len >= 36) &&
                (0 == strncmp(req_buff + 8, "ATA     ", 8)) &&
 	       has_sat_pass_through(fd, 0 /* non-packet dev */)) {
-
-      PrintOut(LOG_INFO, "Device %s: ATA disk detected behind SAT layer\n",
+      PrintOut(LOG_INFO, "Device %s: using '-d sat' for ATA disk behind SAT layer.\n",
                device);
-      PrintOut(LOG_INFO, "  Try adding '-d sat' to the device line in the "
-               "smartd.conf file.\n");
-      PrintOut(LOG_INFO, "  For example: '%s -a -d sat'\n", device);
-      return 2;
+      return SCSIFK_SAT;
     }
   }
-  return 0;
+  return SCSIFK_NORMAL;
 }
 
 // on success, return 0. On failure, return >0.  Never return <0,
 // please.
 static int SCSIDeviceScan(cfgfile *cfg, int scanning) {
-  int k, fd, err; 
+    int k, fd, err, retval; 
   char *device = cfg->name;
   struct scsi_iec_mode_page iec;
   UINT8  tBuf[64];
@@ -1702,9 +1694,18 @@ static int SCSIDeviceScan(cfgfile *cfg, int scanning) {
 
   // early skip if device known and needs to be handled by some other
   // device type (e.g. '-d 3ware,<n>')
-  if (SCSIFilterKnown(fd, device)) {
+  if ((retval = SCSIFilterKnown(fd, device))) {
     CloseDevice(fd, device);
-    return 2; 
+
+    if (retval==SCSIFK_SAT)
+	// SATA Device behind SAT layer
+	return SCSIFK_SAT;
+
+    if (retval==SCSIFK_MARVELL)
+        // ATA/SATA device behind Marvell driver
+	return SCSIFK_MARVELL;
+    
+    return 2;
   }
     
   // check that device is ready for commands. IE stores its stuff on
@@ -1751,8 +1752,8 @@ static int SCSIDeviceScan(cfgfile *cfg, int scanning) {
   }
   
   // Device exists, and does SMART.  Add to list (allocating more space if needed)
-  while (numdevscsi >= scsidevlist_max)
-    scsidevlist=AllocateMoreSpace(scsidevlist, &scsidevlist_max, "SCSI device");
+  while (numdevscsi+numdevata >= ATAandSCSIdevlist_max)
+    ATAandSCSIdevlist=AllocateMoreSpace(ATAandSCSIdevlist, &ATAandSCSIdevlist_max, "ATA and SCSI devices");
   
   // Flag that certain log pages are supported (information may be
   // available from other sources).
@@ -1842,6 +1843,29 @@ static int SCSIDeviceScan(cfgfile *cfg, int scanning) {
   return 0;
 }
 
+// modified treatment of SCSI device behind SAT layer
+static int SCSIandSATDeviceScan(cfgfile *cfg, int scanning) {
+  int retval = SCSIDeviceScan(cfg, scanning);
+  cfg->WhichCheckDevice=1; // default SCSI device
+  
+  if (retval==SCSIFK_SAT) {
+    // found SATA device behind SAT translation layer	
+    cfg->controller_type=CONTROLLER_SAT;
+    cfg->WhichCheckDevice=0; // actually SATA device!
+    return ATADeviceScan(cfg, scanning);
+  }
+
+  if (retval==SCSIFK_MARVELL) {
+    // found SATA device behind Marvell controller
+    cfg->controller_type=CONTROLLER_MARVELL_SATA;
+    cfg->WhichCheckDevice=0; // actually SATA device!
+    return ATADeviceScan(cfg, scanning);
+  }
+
+  return retval; 
+}
+
+
 // We compare old and new values of the n'th attribute.  Note that n
 // is NOT the attribute ID number.. If (Normalized & Raw) equal,
 // then return 0, else nonzero.
@@ -2050,7 +2074,7 @@ int DoTestNow(cfgfile *cfg, char testtype, time_t testtime) {
 }
 
 // Print a list of future tests.
-void PrintTestSchedule(cfgfile **atadevices, cfgfile **scsidevices){
+void PrintTestSchedule(cfgfile **ATAandSCSIdevices){
   int i, t;
   cfgfile * cfg;
   char datenow[DATEANDEPOCHLEN], date[DATEANDEPOCHLEN];
@@ -2073,8 +2097,8 @@ void PrintTestSchedule(cfgfile **atadevices, cfgfile **scsidevices){
     // Check for each device whether a test will be run
     time_t testtime = now + seconds;
     for (i=0; i<numdev; i++) {
-      cfg = (i<numdevata? atadevices[i] : scsidevices[i-numdevata]);
-      for (t=0; t<(i<numdevata?4:2); t++) {
+	cfg = ATAandSCSIdevices[i];
+      for (t=0; t<(cfg->WhichCheckDevice==0?4:2); t++) {
         char testtype = "LSCO"[t];
         if (DoTestNow(cfg, testtype, testtime)) {
           // Report at most 5 tests of each type
@@ -2092,8 +2116,8 @@ void PrintTestSchedule(cfgfile **atadevices, cfgfile **scsidevices){
   dateandtimezoneepoch(date, now+seconds);
   PrintOut(LOG_INFO, "\nTotals [%s - %s]:\n", datenow, date);
   for (i=0; i<numdev; i++) {
-    cfg = (i<numdevata? atadevices[i] : scsidevices[i-numdevata]);
-    for (t=0; t<(i<numdevata?4:2); t++) {
+      cfg = ATAandSCSIdevices[i];
+    for (t=0; t<(cfg->WhichCheckDevice==0?4:2); t++) {
       PrintOut(LOG_INFO, "Device: %s, will do %3d test%s of type %c\n", cfg->name, testcnts[i][t],
         (testcnts[i][t]==1?"":"s"), "LSCO"[t]);
     }
@@ -2657,14 +2681,15 @@ int SCSICheckDevice(cfgfile *cfg, bool allow_selftests)
 }
 
 // Checks the SMART status of all ATA and SCSI devices
-void CheckDevicesOnce(cfgfile **atadevices, cfgfile **scsidevices, bool allow_selftests){
+void CheckDevicesOnce(cfgfile **ATAandSCSIdevices, bool allow_selftests){
   int i;
   
-  for (i=0; i<numdevata; i++) 
-    ATACheckDevice(atadevices[i], allow_selftests);
-  
-  for (i=0; i<numdevscsi; i++)
-    SCSICheckDevice(scsidevices[i], allow_selftests);
+  for (i=0; i<numdevata+numdevscsi; i++) {
+      if (ATAandSCSIdevices[i]->WhichCheckDevice==1)
+	  SCSICheckDevice(ATAandSCSIdevices[i], allow_selftests);
+      else
+	  ATACheckDevice(ATAandSCSIdevices[i], allow_selftests);
+  }
 
   return;
 }
@@ -4253,9 +4278,11 @@ void RegisterDevices(int scanning){
       else {
         // move onto the list of ata devices
         cfgentries[i]=NULL;
-        while (numdevata>=atadevlist_max)
-          atadevlist=AllocateMoreSpace(atadevlist, &atadevlist_max, "ATA device");
-        atadevlist[numdevata++]=ent;
+        while (numdevata+numdevscsi>=ATAandSCSIdevlist_max)
+	    ATAandSCSIdevlist=AllocateMoreSpace(ATAandSCSIdevlist, &ATAandSCSIdevlist_max, "ATA and SCSI devices");
+	ent->WhichCheckDevice=0;
+        ATAandSCSIdevlist[numdevscsi+numdevata]=ent;
+        numdevata++;
       }
     }
     
@@ -4274,7 +4301,7 @@ void RegisterDevices(int scanning){
       if (sigaction(SIGALRM, &alarmAction, &defaultaction)) {
         // if we can't set timeout, just scan device
         PrintOut(LOG_CRIT, "Unable to initialize SCSI timeout mechanism.\n");
-        retscsi=SCSIDeviceScan(ent, scanning);
+        retscsi=SCSIandSATDeviceScan(ent, scanning);
       }
       else {
         // prepare return point in case of bad SCSI device
@@ -4284,7 +4311,7 @@ void RegisterDevices(int scanning){
         else {
         // Set alarm, make SCSI call, reset alarm
           alarm(SCSITIMEOUT);
-          retscsi=SCSIDeviceScan(ent, scanning);
+          retscsi=SCSIandSATDeviceScan(ent, scanning);
           alarm(0);
         }
         if (sigaction(SIGALRM, &defaultaction, NULL)){
@@ -4292,7 +4319,7 @@ void RegisterDevices(int scanning){
         }
       }
 #else
-      retscsi=SCSIDeviceScan(ent, scanning);
+      retscsi=SCSIandSATDeviceScan(ent, scanning);
 #endif   
 
       // Now scan SCSI device...
@@ -4304,9 +4331,10 @@ void RegisterDevices(int scanning){
       else {
         // move onto the list of scsi devices
         cfgentries[i]=NULL;
-        while (numdevscsi>=scsidevlist_max)
-          scsidevlist=AllocateMoreSpace(scsidevlist, &scsidevlist_max, "SCSI device");
-        scsidevlist[numdevscsi++]=ent;
+        while (numdevscsi+numdevata>=ATAandSCSIdevlist_max)
+	  ATAandSCSIdevlist=AllocateMoreSpace(ATAandSCSIdevlist, &ATAandSCSIdevlist_max, "ATA and SCSI devices");
+        ATAandSCSIdevlist[numdevata+numdevscsi]=ent;
+        numdevscsi++;
       }
     }
     
@@ -4430,7 +4458,7 @@ static int smartd_main(int argc, char **argv)
 
       if (quit==4) {
         // user has asked to print test schedule
-        PrintTestSchedule(atadevlist, scsidevlist);
+        PrintTestSchedule(ATAandSCSIdevlist);
         EXIT(0);
       }
       
@@ -4440,7 +4468,7 @@ static int smartd_main(int argc, char **argv)
 
     // check all devices once,
     // self tests are not started in first pass unless '-q onecheck' is specified
-    CheckDevicesOnce(atadevlist, scsidevlist, (!firstpass || quit==3)); 
+    CheckDevicesOnce(ATAandSCSIdevlist, (!firstpass || quit==3)); 
     
     // user has asked us to exit after first check
     if (quit==3) {
diff --git a/sm5/smartd.h b/sm5/smartd.h
index 1ac23e396fc44b093935a5ca290f7ffaba27327b..2518c066427ce8075e8b2727a86f534ef97a3c9a 100644
--- a/sm5/smartd.h
+++ b/sm5/smartd.h
@@ -32,7 +32,7 @@
 
 
 #ifndef SMARTD_H_CVSID
-#define SMARTD_H_CVSID "$Id: smartd.h,v 1.84 2006/11/11 17:50:50 ballen4705 Exp $\n"
+#define SMARTD_H_CVSID "$Id: smartd.h,v 1.85 2008/03/04 21:24:58 ballen4705 Exp $\n"
 #endif
 
 // Configuration file
@@ -233,6 +233,9 @@ typedef struct configfile_s {
   struct ata_smart_values *smartval;       // Pointer to SMART data
   struct ata_smart_thresholds_pvt *smartthres; // Pointer to SMART thresholds
 
+  // Added to distinguish ATA and SCSI entries on list
+  int WhichCheckDevice;
+
 } cfgfile;
 
 
@@ -278,7 +281,6 @@ export NJAMD_TRACE_LIBS=1
 #define SIGNALFN signal
 #endif
 
-#endif
 
 #define SELFTEST_ERRORCOUNT(x) (x & 0xff)
 #define SELFTEST_ERRORHOURS(x) ((x >> 8) & 0xffff)
@@ -297,3 +299,16 @@ export NJAMD_TRACE_LIBS=1
 
 // if cfg->pending has this value, dont' monitor
 #define DONT_MONITOR_UNC (256*OFF_UNC_DEFAULT+CUR_UNC_DEFAULT)
+
+// Some return values from SCSIFilterKnown(), used to detect known
+// device types hidden behind SCSI devices.
+
+#define SCSIFK_FAILED   -1
+#define SCSIFK_NORMAL    0
+#define SCSIFK_3WARE    11
+#define SCSIFK_SAT      12
+#define SCSIFK_MARVELL  13
+
+// Make additions BEFORE this line.  The line is the end of
+// double-inclusion protection and should remain the final line.
+#endif  // #ifndef SMARTD_H_
diff --git a/sm5/smartd.initd.in b/sm5/smartd.initd.in
index 9b2ca48533efafe76cc8e67102bedf84593cbf02..aefb5aa7c011a607aafe759a2ff53f4bf887327e 100755
--- a/sm5/smartd.initd.in
+++ b/sm5/smartd.initd.in
@@ -2,7 +2,7 @@
 
 # smartmontools init file for smartd
 # Copyright (C) 2002-7 Bruce Allen <smartmontools-support@lists.sourceforge.net>
-# $Id: smartd.initd.in,v 1.36 2007/11/01 20:53:30 chrfranke Exp $
+# $Id: smartd.initd.in,v 1.37 2008/03/04 21:24:58 ballen4705 Exp $
 
 # For RedHat and cousins:
 # chkconfig: 2345 40 40
@@ -11,15 +11,16 @@
 
 # For SuSE and cousins
 ### BEGIN INIT INFO
-# Provides:          smartd
-# Required-Start:    $syslog
+# Provides:                   smartd
+# Required-Start:             $syslog
 # X-UnitedLinux-Should-Start: $sendmail
-# Required-Stop:     $syslog
+# Should-Start:               $sendmail
+# Required-Stop:              $syslog
 # X-UnitedLinux-Should-Stop:
-# Default-Start:     2 3 5
+# Default-Start:              2 3 5
 # Default-Stop:
-# Short-Description: Monitors disk and tape health via S.M.A.R.T.
-# Description:       Start S.M.A.R.T. disk and tape monitor.
+# Short-Description:          Monitors disk and tape health via S.M.A.R.T.
+# Description:                Start S.M.A.R.T. disk and tape monitor.
 ### END INIT INFO
 
 # This program is free software; you can redistribute it and/or modify it