Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 10 Jan 2018 17:35:00 +0000 (UTC)
From:      Andriy Gapon <avg@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r327775 - head/sys/dev/amdsbwd
Message-ID:  <201801101735.w0AHZ02v024903@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: avg
Date: Wed Jan 10 17:35:00 2018
New Revision: 327775
URL: https://svnweb.freebsd.org/changeset/base/327775

Log:
  amdsbwd: fix handling of timeout values beyond the supported range
  
  The driver now fully observes watchdog(9) protocol.
  Previously a too large timeout was silently clamped while the correct
  behavior is to disable the watchdog and leave the error as is
  (i.e. to not report success).
  
  Also, previously a too small value caused the timer to stop while the
  correct behavior is to use the minimal supported value.
  
  MFC after:	2 weeks

Modified:
  head/sys/dev/amdsbwd/amdsbwd.c

Modified: head/sys/dev/amdsbwd/amdsbwd.c
==============================================================================
--- head/sys/dev/amdsbwd/amdsbwd.c	Wed Jan 10 17:25:08 2018	(r327774)
+++ head/sys/dev/amdsbwd/amdsbwd.c	Wed Jan 10 17:35:00 2018	(r327775)
@@ -210,21 +210,30 @@ static void
 amdsbwd_event(void *arg, unsigned int cmd, int *error)
 {
 	struct amdsbwd_softc *sc = arg;
-	unsigned int timeout;
+	uint64_t timeout;
 
-	/* convert from power-of-two-ns to WDT ticks */
-	cmd &= WD_INTERVAL;
-	if (cmd < WD_TO_1SEC)
-		cmd = 0;
-	if (cmd) {
-		timeout = ((uint64_t)1 << (cmd - WD_TO_1MS)) / sc->ms_per_tick;
+	if (cmd != 0) {
+		timeout = 0;
+		cmd &= WD_INTERVAL;
+		if (cmd >= WD_TO_1MS) {
+			timeout = (uint64_t)1 << (cmd - WD_TO_1MS);
+			timeout = timeout / sc->ms_per_tick;
+		}
+		/* For a too short timeout use 1 tick. */
+		if (timeout == 0)
+			timeout = 1;
+		/* For a too long timeout stop the timer. */
 		if (timeout > sc->max_ticks)
-			timeout = sc->max_ticks;
-		if (timeout != sc->timeout) {
+			timeout = 0;
+	} else {
+		timeout = 0;
+	}
+
+	if (timeout != 0) {
+		if (timeout != sc->timeout)
 			amdsbwd_tmr_set(sc, timeout);
-			if (!sc->active)
-				amdsbwd_tmr_enable(sc);
-		}
+		if (!sc->active)
+			amdsbwd_tmr_enable(sc);
 		amdsbwd_tmr_reload(sc);
 		*error = 0;
 	} else {



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201801101735.w0AHZ02v024903>