diff --git a/sm5/CHANGELOG b/sm5/CHANGELOG
index 992580e6d0e12f7e6bb49b6bf569486d2e3cf482..a443d48668aa9735dfbfbfa3448065965afd2d5b 100644
--- a/sm5/CHANGELOG
+++ b/sm5/CHANGELOG
@@ -1,6 +1,6 @@
 CHANGELOG for smartmontools
 
-$Id: CHANGELOG,v 1.750 2008/11/02 01:33:26 manfred99 Exp $
+$Id: CHANGELOG,v 1.751 2008/11/04 19:28:42 chrfranke Exp $
 
 The most recent version of this file is:
 http://smartmontools.cvs.sourceforge.net/smartmontools/sm5/CHANGELOG?view=markup
@@ -40,6 +40,9 @@ NOTES FOR FUTURE RELEASES: see TODO file.
 
 <DEVELOPERS: ADDITIONS TO THE CHANGE LOG GO JUST BELOW HERE, PLEASE>
 
+  [CF] Add smartd '-n powermode,N' directive parameter to limit the
+       number of skipped checks. Thanks to Michal Hlavinka for the patch.
+
   [MS] knowndrives.cpp updates:
        - Added Hitachi Endurastar J4K30/N4K30
        - Added Hitachi Travelstar 4K120 series
diff --git a/sm5/smartd.8.in b/sm5/smartd.8.in
index bd2161b73b9466815120bfcbce210901d7f4677f..c84f505a18b6b86669a476b4108177a634b54581 100644
--- a/sm5/smartd.8.in
+++ b/sm5/smartd.8.in
@@ -1,7 +1,7 @@
 .ig
 Copyright (C) 2002-8 Bruce Allen <smartmontools-support@lists.sourceforge.net>
  
-$Id: smartd.8.in,v 1.132 2008/10/13 19:45:19 chrfranke Exp $
+$Id: smartd.8.in,v 1.133 2008/11/04 19:28:42 chrfranke Exp $
 
 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
@@ -824,7 +824,7 @@ behavior) if the device does not appear to be present when
 with the other \'\-d\' Directives.
 
 .TP
-.B \-n POWERMODE[,q]
+.B \-n POWERMODE[,N][,q]
 This \'nocheck\' Directive is used to prevent a disk from being
 spun-up when it is periodically polled by \fBsmartd\fP.
 
@@ -872,11 +872,18 @@ not what you want.
 When a self test is scheduled (see \'\-s\' Directive below), the
 \'\fB\-n\fP\' Directive is ignored, and all tests are carried out.
 
+Maximum number of skipped checks (in a row) can be specified by
+appending positive number \',N\' to POWERMODE (like \'\-n standby,15\').
+After N checks are skipped in a row, powermode is ignored and the
+check is performed anyway.
+
 When a periodic test is skipped, \fBsmartd\fP normally writes an
 informal log message. The message can be suppressed by appending
 the option \',q\' to POWERMODE (like \'\-n standby,q\').
 This prevents a laptop disk from spinning up due to this message.
 
+Both \',N\' and \',q\' can be specified together.
+
 .TP
 .B \-T TYPE
 Specifies how tolerant
@@ -2080,4 +2087,4 @@ smartmontools home page at \fBhttp://smartmontools.sourceforge.net/#references\f
 
 .SH
 CVS ID OF THIS PAGE:
-$Id: smartd.8.in,v 1.132 2008/10/13 19:45:19 chrfranke Exp $
+$Id: smartd.8.in,v 1.133 2008/11/04 19:28:42 chrfranke Exp $
diff --git a/sm5/smartd.conf.5.in b/sm5/smartd.conf.5.in
index 4c2a4c1d2f8220c7c1766775b293c7101257164a..3ca9e855201ff56588483c07f039bdb8003964a9 100644
--- a/sm5/smartd.conf.5.in
+++ b/sm5/smartd.conf.5.in
@@ -1,7 +1,7 @@
 .ig
 Copyright (C) 2002-8 Bruce Allen <smartmontools-support@lists.sourceforge.net>
 
-$Id: smartd.conf.5.in,v 1.96 2008/10/11 14:18:07 chrfranke Exp $
+$Id: smartd.conf.5.in,v 1.97 2008/11/04 19:28:42 chrfranke Exp $
 
 This program is free software; you can redistribute it and/or modify it
 under the terms of the GNU General Public License as published by the Free
@@ -409,7 +409,7 @@ behavior) if the device does not appear to be present when
 with the other \'\-d\' Directives.
 
 .TP
-.B \-n POWERMODE[,q]
+.B \-n POWERMODE[,N][,q]
 This \'nocheck\' Directive is used to prevent a disk from being
 spun-up when it is periodically polled by \fBsmartd\fP.
 
@@ -457,11 +457,18 @@ not what you want.
 When a self test is scheduled (see \'\-s\' Directive below), the
 \'\fB\-n\fP\' Directive is ignored, and all tests are carried out.
 
+Maximum number of skipped checks (in a row) can be specified by
+appending positive number \',N\' to POWERMODE (like \'\-n standby,15\').
+After N checks are skipped in a row, powermode is ignored and the
+check is performed anyway.
+
 When a periodic test is skipped, \fBsmartd\fP normally writes an
 informal log message. The message can be suppressed by appending
 the option \',q\' to POWERMODE (like \'\-n standby,q\').
 This prevents a laptop disk from spinning up due to this message.
 
+Both \',N\' and \',q\' can be specified together.
+
 .TP
 .B \-T TYPE
 Specifies how tolerant
@@ -1435,4 +1442,4 @@ SEE ALSO:
 
 .SH
 CVS ID OF THIS PAGE:
-$Id: smartd.conf.5.in,v 1.96 2008/10/11 14:18:07 chrfranke Exp $
+$Id: smartd.conf.5.in,v 1.97 2008/11/04 19:28:42 chrfranke Exp $
diff --git a/sm5/smartd.cpp b/sm5/smartd.cpp
index bd7559ddba7878e3e65677971d4fa8fc3cbc9fd1..e6fcad821bdb16a28fbae6837766997428c38987 100644
--- a/sm5/smartd.cpp
+++ b/sm5/smartd.cpp
@@ -138,7 +138,7 @@ extern const char *os_solaris_ata_s_cvsid;
 #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.432 2008/10/24 19:51:54 chrfranke Exp $"
+const char *smartd_c_cvsid="$Id: smartd.cpp,v 1.433 2008/11/04 19:28:42 chrfranke Exp $"
 ATACMDS_H_CVSID CONFIG_H_CVSID
 #ifdef DAEMON_WIN32_H_CVSID
 DAEMON_WIN32_H_CVSID
@@ -268,6 +268,7 @@ struct dev_config
   bool removable;                         // Device may disappear (not be present)
   char powermode;                         // skip check, if disk in idle or standby mode
   bool powerquiet;                        // skip powermode 'skipping checks' message
+  int powerskipmax;                       // how many times can be check skipped
   unsigned char tempdiff;                 // Track Temperature changes >= this limit
   unsigned char tempinfo, tempcrit;       // Track Temperatures >= these limits as LOG_INFO, LOG_CRIT+mail
   regular_expression test_regex;          // Regex for scheduled testing
@@ -314,6 +315,7 @@ dev_config::dev_config()
   removable(false),
   powermode(0),
   powerquiet(false),
+  powerskipmax(0),
   tempdiff(0),
   tempinfo(0), tempcrit(0),
   pending(0),
@@ -1424,7 +1426,7 @@ void Directives() {
            "  -T TYPE Set the tolerance to one of: normal, permissive\n"
            "  -o VAL  Enable/disable automatic offline tests (on/off)\n"
            "  -S VAL  Enable/disable attribute autosave (on/off)\n"
-           "  -n MODE No check if: never[,q], sleep[,q], standby[,q], idle[,q]\n"
+           "  -n MODE No check if: never, sleep[,N][,q], standby[,N][,q], idle[,N][,q]\n"
            "  -H      Monitor SMART Health Status, report if failed\n"
            "  -s REG  Do Self-Test at time(s) given by regular expression REG\n"
            "  -l TYPE Monitor SMART log.  Type is one of: error, selftest\n"
@@ -2626,14 +2628,21 @@ static int ATACheckDevice(const dev_config & cfg, dev_state & state, ata_device
     if (dontcheck){
       // but ignore powermode on scheduled selftest
       if (!testtype) {
-        CloseDevice(atadev, name);
-        if (!state.powerskipcnt && !cfg.powerquiet) // report first only and avoid waking up system disk
-          PrintOut(LOG_INFO, "Device: %s, is in %s mode, suspending checks\n", name, mode);
-        state.powerskipcnt++;
-        return 0;
+        // skip at most powerskipmax checks
+        if (!cfg.powerskipmax || state.powerskipcnt<cfg.powerskipmax) {
+          CloseDevice(atadev, name);
+          if (!state.powerskipcnt && !cfg.powerquiet) // report first only and avoid waking up system disk
+            PrintOut(LOG_INFO, "Device: %s, is in %s mode, suspending checks\n", name, mode);
+          state.powerskipcnt++;
+          return 0;
+        } else {
+          PrintOut(LOG_INFO, "Device: %s, %s mode ignored due to reached limit of skipped checks (%d check%s skipped)\n",
+            name, mode, state.powerskipcnt, (state.powerskipcnt==1?"":"s"));
+        }
+      } else {
+        PrintOut(LOG_INFO, "Device: %s, %s mode ignored due to scheduled self test (%d check%s skipped)\n",
+          name, mode, state.powerskipcnt, (state.powerskipcnt==1?"":"s"));
       }
-      PrintOut(LOG_INFO, "Device: %s, %s mode ignored due to scheduled self test (%d check%s skipped)\n",
-        name, mode, state.powerskipcnt, (state.powerskipcnt==1?"":"s"));
       state.powerskipcnt = 0;
       state.tempmin_delay = time(0) + CHECKTIME - 60; // Delay Min Temperature update
     }
@@ -3019,7 +3028,7 @@ void printoutvaliddirectiveargs(int priority, char d) {
 
   switch (d) {
   case 'n':
-    PrintOut(priority, "never[,q], sleep[,q], standby[,q], idle[,q]");
+    PrintOut(priority, "never[,N][,q], sleep[,N][,q], standby[,N][,q], idle[,N][,q]");
     break;
   case 's':
     PrintOut(priority, "valid_regular_expression");
@@ -3264,17 +3273,45 @@ static int ParseToken(char * token, dev_config & cfg)
     // skip disk check if in idle or standby mode
     if (!(arg = strtok(NULL, delim)))
       missingarg = 1;
-    else if (!strcmp(arg, "never")   || !strcmp(arg, "never,q"))
-      cfg.powermode = 0;
-    else if (!strcmp(arg, "sleep")   || !strcmp(arg, "sleep,q"))
-      cfg.powermode = 1;
-    else if (!strcmp(arg, "standby") || !strcmp(arg, "standby,q"))
-      cfg.powermode = 2;
-    else if (!strcmp(arg, "idle")    || !strcmp(arg, "idle,q"))
-      cfg.powermode = 3;
-    else
-      badarg = 1;
-    cfg.powerquiet = !!strchr(arg, ',');
+    else {
+      char *endptr = NULL;
+      char *next = index(arg,',');
+
+      cfg.powerquiet = false;
+      cfg.powerskipmax = 0;
+
+      if (next!=NULL) *next='\0';
+      if (!strcmp(arg, "never"))
+        cfg.powermode = 0;
+      else if (!strcmp(arg, "sleep"))
+        cfg.powermode = 1;
+      else if (!strcmp(arg, "standby"))
+        cfg.powermode = 2;
+      else if (!strcmp(arg, "idle"))
+        cfg.powermode = 3;
+      else
+        badarg = 1;
+
+      // if optional arguments are present
+      if (!badarg && next!=NULL) {
+        next++;
+        cfg.powerskipmax = strtol(next, &endptr, 10);
+        if (endptr == next)
+          cfg.powerskipmax = 0;
+        else {
+          next = endptr + (*endptr != '\0');
+          if (cfg.powerskipmax <= 0)
+            badarg = 1;
+        }
+        if (*next != '\0') {
+          if (!strcmp("q", next))
+            cfg.powerquiet = true;
+          else {
+            badarg = 1;
+          }
+        }
+      }
+    }
     break;
   case 'S':
     // automatic attribute autosave enable/disable