diff --git a/smartmontools/atacmds.cpp b/smartmontools/atacmds.cpp
index 87810090e3cd42fa540aa3d8d8e4284074eb94ba..9e96ecff0c046c21e8e9c52769388a13a1a86cf5 100644
--- a/smartmontools/atacmds.cpp
+++ b/smartmontools/atacmds.cpp
@@ -1479,10 +1479,9 @@ int ataDisableAutoSave(ata_device * device){
 // marked "OBSOLETE". It is defined in SFF-8035i Revision 2, and most
 // vendors still support it for backwards compatibility. IBM documents
 // it for some drives.
-int ataEnableAutoOffline (ata_device * device){
+int ataEnableAutoOffline (ata_device * device, int timeout){
   
-  /* timer hard coded to 4 hours */  
-  if (smartcommandhandler(device, AUTO_OFFLINE, 248, NULL)){
+  if (smartcommandhandler(device, AUTO_OFFLINE, timeout, NULL)){
     syserror("Error SMART Enable Automatic Offline failed");
     return -1;
   }
diff --git a/smartmontools/atacmds.h b/smartmontools/atacmds.h
index f5b8becaacb27be686830c2e477e809e942e9de3..a4cdd6968205b61eef854ae776e8815529efadfb 100644
--- a/smartmontools/atacmds.h
+++ b/smartmontools/atacmds.h
@@ -735,7 +735,7 @@ int ataEnableAutoSave(ata_device * device);
 int ataDisableAutoSave(ata_device * device);
 
 /* Automatic Offline Testing */
-int ataEnableAutoOffline (ata_device * device);
+int ataEnableAutoOffline (ata_device * device, int timeout);
 int ataDisableAutoOffline (ata_device * device);
 
 /* S.M.A.R.T. test commands */
diff --git a/smartmontools/ataprint.cpp b/smartmontools/ataprint.cpp
index 51fef8ac8957197365c45eac778bd88b25f5acf0..7b2015a07876e7f3fc44b3080c6c45c92ed91469 100644
--- a/smartmontools/ataprint.cpp
+++ b/smartmontools/ataprint.cpp
@@ -1929,12 +1929,44 @@ int ataPrintMain (ata_device * device, const ata_print_options & options)
       failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
     }
     needupdate=1;
-    if (ataEnableAutoOffline(device)){
+    
+    int atat = secs_to_atatimer(options.smart_auto_offl_timeout);
+    
+    if (ataEnableAutoOffline(device, atat)){
       pout( "Smartctl: SMART Enable Automatic Offline Failed.\n\n");
       failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
     }
-    else
-      pout("SMART Automatic Offline Testing Enabled every four hours.\n");
+    else {
+      pout("SMART Automatic Offline Testing Enabled");
+
+      int timeout;
+      
+      timeout = atatimer_to_secs(atat);
+
+      if (timeout > 0) {
+      
+        pout(" every");
+        
+        if (timeout==8*3600) {
+          pout(" 8-12 hours");
+        } else {
+          int hours, mins;
+
+          hours = timeout / 3600;
+          timeout%=3600;
+          mins = timeout / 60;
+          timeout%=60;
+      
+          if (hours > 0)
+            pout(" %d hour%s", hours, hours>1?"s":"");
+          if (mins > 0)
+            pout(" %d minute%s", mins, mins>1?"s":"");
+          if (timeout > 0)
+            pout(" %d second%s", timeout, timeout>1?"s":"");
+        };
+      };
+      pout(".\n");
+    }
   }
 
   if (options.smart_auto_offl_disable) {
diff --git a/smartmontools/ataprint.h b/smartmontools/ataprint.h
index 6c8c5eef27bbd88143076ccd5ebf331e74015ea5..56828459955fd3ae26309a52139ea25bf5b4f223 100644
--- a/smartmontools/ataprint.h
+++ b/smartmontools/ataprint.h
@@ -67,6 +67,7 @@ struct ata_print_options
 
   bool smart_disable, smart_enable;
   bool smart_auto_offl_disable, smart_auto_offl_enable;
+  int smart_auto_offl_timeout;
   bool smart_auto_save_disable, smart_auto_save_enable;
 
   int smart_selftest_type; // OFFLINE_FULL_SCAN, ..., see atacmds.h. -1 for no test
@@ -100,6 +101,7 @@ struct ata_print_options
       sataphy(false), sataphy_reset(false),
       smart_disable(false), smart_enable(false),
       smart_auto_offl_disable(false), smart_auto_offl_enable(false),
+      smart_auto_offl_timeout(4*3600),
       smart_auto_save_disable(false), smart_auto_save_enable(false),
       smart_selftest_type(-1),
       sct_temp_int(0), sct_temp_int_pers(false),
diff --git a/smartmontools/smartctl.cpp b/smartmontools/smartctl.cpp
index 93ba92894bcdb981938510528d4fb0674fcd7b46..f5a12c7ab61afbf657b4fdbf585ed48c5e7afa4e 100644
--- a/smartmontools/smartctl.cpp
+++ b/smartmontools/smartctl.cpp
@@ -362,9 +362,47 @@ const char * parse_options(int argc, char** argv,
       }
       break;
     case 'o':
-      if (!strcmp(optarg,"on")) {
+      if (!strncmp(optarg,"on", 2)) {
         ataopts.smart_auto_offl_enable  = true;
         ataopts.smart_auto_offl_disable = false;
+        if (optarg[2]=='\0') {
+          ataopts.smart_auto_offl_timeout = 4*3600; /* default is 4 hours */
+          break;
+        };
+        if (optarg[2]!=',' || optarg[3]=='\0') {
+          badarg = true;
+          break;
+        };
+
+        long timeout;
+        char *endptr;
+        
+        timeout = strtol(optarg+3, &endptr, 0);
+        if (timeout < 1) {
+          badarg = true; // non-positive number
+          break;
+        };
+        
+        switch (*endptr) {
+        case 's':
+          endptr++;
+          break;
+        case 'm':
+          timeout*=60;
+          endptr++;
+          break;
+        case 'h':
+          timeout*=3600;
+          endptr++;
+          break;
+        };
+
+        if (*endptr != '\0') {
+          badarg = true; // extra character after parameter
+          break;
+        };
+        
+        ataopts.smart_auto_offl_timeout = (int)timeout;
       } else if (!strcmp(optarg,"off")) {
         ataopts.smart_auto_offl_disable = true;
         ataopts.smart_auto_offl_enable  = false;
diff --git a/smartmontools/smartd.cpp b/smartmontools/smartd.cpp
index 85044e7f5dec82c2596c0acce90c9c5711741594..663254b5e6569dd2afe1ced9bbb0c96e2bdea906 100644
--- a/smartmontools/smartd.cpp
+++ b/smartmontools/smartd.cpp
@@ -258,6 +258,7 @@ struct dev_config
   bool permissive;                        // Ignore failed SMART commands
   char autosave;                          // 1=disable, 2=enable Autosave Attributes
   char autoofflinetest;                   // 1=disable, 2=enable Auto Offline Test
+  int  autoofflinetestperiod;             // seconds between two Auto Offline Test
   unsigned char fix_firmwarebug;          // FIX_*, see atacmds.h
   bool ignorepresets;                     // Ignore database of -v options
   bool showpresets;                       // Show database entry for this device
@@ -299,6 +300,7 @@ dev_config::dev_config()
   permissive(false),
   autosave(0),
   autoofflinetest(0),
+  autoofflinetestperiod(4*3600),
   fix_firmwarebug(FIX_NOTSPECIFIED),
   ignorepresets(false),
   showpresets(false),
@@ -1748,7 +1750,7 @@ static int ATADeviceScan(dev_config & cfg, dev_state & state, ata_device * atade
       if (!isSupportAutomaticTimer(&state.smartval))
         PrintOut(LOG_INFO,"Device: %s, SMART Automatic Offline Testing unsupported...\n",name);
       // ... but then try anyway
-      if ((cfg.autoofflinetest==1)?ataDisableAutoOffline(atadev):ataEnableAutoOffline(atadev))
+      if ((cfg.autoofflinetest==1)?ataDisableAutoOffline(atadev):ataEnableAutoOffline(atadev, secs_to_atatimer(cfg.autoofflinetestperiod)))
         PrintOut(LOG_INFO,"Device: %s, %s SMART Automatic Offline Testing failed.\n", name, what);
       else
         PrintOut(LOG_INFO,"Device: %s, %sd SMART Automatic Offline Testing.\n", name, what);
@@ -3202,8 +3204,46 @@ static int ParseToken(char * token, dev_config & cfg)
     // automatic offline testing enable/disable
     if ((arg = strtok(NULL, delim)) == NULL) {
       missingarg = 1;
-    } else if (!strcmp(arg, "on")) {
+    } else if (!strncmp(arg, "on", 2)) {
       cfg.autoofflinetest = 2;
+      if (arg[2]=='\0') {
+        cfg.autoofflinetestperiod = 4*3600; /* default value */
+        break;
+      };
+      if (optarg[2]!=',' || optarg[3]=='\0') {
+        badarg = 1;
+        break;
+      };
+      
+      long timeout;
+      char *endptr;
+      
+      timeout = strtol(optarg+3, &endptr, 0);
+      if (timeout < 1) {
+        badarg = 1; // non-positive number
+        break;
+      };
+      
+      switch (*endptr) {
+      case 's':
+        endptr++;
+        break;
+      case 'm':
+        timeout*=60;
+        endptr++;
+        break;
+      case 'h':
+        timeout*=3600;
+        endptr++;
+        break;
+      };
+
+      if (*endptr != '\0') {
+        badarg = 1; // extra character after parameter
+        break;
+      };
+      
+      cfg.autoofflinetestperiod = (int)timeout;
     } else if (!strcmp(arg, "off")) {
       cfg.autoofflinetest = 1;
     } else {
diff --git a/smartmontools/utility.cpp b/smartmontools/utility.cpp
index 134bf3349ad853bdcb70aa2da7c09e1ae6074b8d..c9cbe6c04a2e9edbffcc98423308e675adf2a855 100644
--- a/smartmontools/utility.cpp
+++ b/smartmontools/utility.cpp
@@ -778,3 +778,62 @@ int safe_snprintf(char *buf, int size, const char *fmt, ...)
 }
 
 #endif
+
+// Convert seconds to ata timer scale and vice versa
+// 
+// +---------------------+------------------------------+
+// | Sector Count        | Corresponding                |
+// | Register contents   | Timeout Period               |
+// +---------------------+------------------------------+
+// |   0       (00h)     | Timeout Disabled             |
+// |   1 - 240 (01h-F0h) | (value * 5) seconds          |
+// | 241 - 251 (F1h-FBh) | ((value - 240) * 30) minutes |
+// |       252 (FCh)     | 21 minutes                   |
+// |       253 (FDh)     | Vendor unique period between |
+// |                     | 8 and 12 hours               |
+// |       254 (FEh)     | Reserved                     |
+// |       255 (FFh)     | 21 minutes 15 seconds        |
+// +---------------------+------------------------------+
+// (Table taken from X3T10/0948D Revision 4c)
+unsigned int 
+secs_to_atatimer(unsigned int tmo) {
+
+  if (tmo == 0)
+    return 0;
+  if (tmo < 5)
+    return 1;
+
+  if (tmo<=1200) 
+    return tmo / 5;
+  if (tmo<1200+60)
+    return 240;
+  if (tmo<1200+75)
+    return 252;
+  if (tmo<1800)
+    return 255;
+  if (tmo <19800+1800 )
+    return (tmo / 1800)+240;
+
+  if (tmo < 8*3600)
+    return 251;
+
+  return 253;
+};
+
+unsigned int 
+atatimer_to_secs(unsigned int atat) {
+
+  switch (atat) {
+  case   0: return 0;
+  case 252: return 21*60;
+  case 253: return 8*3600;
+  case 254: return -1;
+  case 255: return 21*60+15;
+  };
+  
+  if (atat<=240)
+    return(atat*5);
+
+  return((atat-240)*1800);
+
+};
diff --git a/smartmontools/utility.h b/smartmontools/utility.h
index 215e9d2aa0c35e87ced0f947f359f2adf7cceb66..b62faf1faa8dab30f1d55eb15db3599222457a58 100644
--- a/smartmontools/utility.h
+++ b/smartmontools/utility.h
@@ -335,3 +335,7 @@ private:
 #endif
 
 #endif
+
+unsigned int secs_to_atatimer(unsigned int tmo);
+unsigned int atatimer_to_secs(unsigned int atat);
+