The branch main has been updated by jhibbits:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=69f7d6912a24d3caab4957a33e07529275cf4d09

commit 69f7d6912a24d3caab4957a33e07529275cf4d09
Author:     Justin Hibbits <jhibb...@freebsd.org>
AuthorDate: 2025-02-26 20:17:24 +0000
Commit:     Justin Hibbits <jhibb...@freebsd.org>
CommitDate: 2025-08-14 19:02:46 +0000

    watchdog: Add a new "Control" ioctl
    
    Summary:
    In preparation for a new watchdog timeout interface using sbintime_t,
    add a new control ioctl to arm, pat, and disarm the watchdog.
    
    Reviewed by:    jhb, phk
    Sponsored by:   Juniper Networks, Inc.
    Differential Revision: https://reviews.freebsd.org/D49182
---
 sys/dev/watchdog/watchdog.c    | 20 ++++++++++++++++++++
 sys/sys/watchdog.h             |  8 ++++++++
 usr.sbin/watchdogd/watchdogd.c | 13 +++++++++++--
 3 files changed, 39 insertions(+), 2 deletions(-)

diff --git a/sys/dev/watchdog/watchdog.c b/sys/dev/watchdog/watchdog.c
index e6b6dc1eac70..c0babef1b29b 100644
--- a/sys/dev/watchdog/watchdog.c
+++ b/sys/dev/watchdog/watchdog.c
@@ -117,6 +117,23 @@ seconds_to_pow2ns(int seconds)
        return (power);
 }
 
+int
+wdog_control(int ctrl)
+{
+       /* Disable takes precedence */
+       if (ctrl == WD_CTRL_DISABLE) {
+               wdog_kern_pat(0);
+       }
+
+       if ((ctrl & WD_CTRL_RESET) != 0) {
+               wdog_kern_pat(WD_ACTIVE | WD_LASTVAL);
+       } else if ((ctrl & WD_CTRL_ENABLE) != 0) {
+               wdog_kern_pat(WD_ACTIVE | WD_LASTVAL);
+       }
+
+       return (0);
+}
+
 int
 wdog_kern_pat(u_int utim)
 {
@@ -374,6 +391,9 @@ wd_ioctl(struct cdev *dev __unused, u_long cmd, caddr_t 
data,
        case WDIOCPATPAT:
                error = wd_ioctl_patpat(data);
                break;
+       case WDIOC_CONTROL:
+               wdog_control(*(int *)data);
+               break;
        default:
                error = ENOIOCTL;
                break;
diff --git a/sys/sys/watchdog.h b/sys/sys/watchdog.h
index 4a16b18509f5..3c9d31eb577b 100644
--- a/sys/sys/watchdog.h
+++ b/sys/sys/watchdog.h
@@ -48,6 +48,8 @@
 #define WDIOC_SETSOFT  _IOW('W', 49, int)
 #define WDIOC_SETSOFTTIMEOUTACT        _IOW('W', 50, int)
 
+#define        WDIOC_CONTROL           _IOW('W', 51, int)      /* configure 
watchdog */
+
 #define WD_ACTIVE      0x8000000
        /* 
         * Watchdog reset, timeout set to value in WD_INTERVAL field.
@@ -93,6 +95,11 @@
 #define WD_TO_64SEC    36
 #define WD_TO_128SEC   37
 
+/* Control options for WDIOC_CONTROL */
+#define        WD_CTRL_DISABLE 0x00000000
+#define        WD_CTRL_ENABLE  0x00000001
+#define        WD_CTRL_RESET   0x00000002
+
 /* action on pre-timeout trigger */
 #define        WD_SOFT_PANIC   0x01    /* panic */
 #define        WD_SOFT_DDB     0x02    /* enter debugger */
@@ -110,6 +117,7 @@ EVENTHANDLER_DECLARE(watchdog_list, watchdog_fn);
 
 u_int  wdog_kern_last_timeout(void);
 int    wdog_kern_pat(u_int utim);
+int            wdog_control(int ctrl);
 
 /*
  * The following function pointer is used to attach a software watchdog
diff --git a/usr.sbin/watchdogd/watchdogd.c b/usr.sbin/watchdogd/watchdogd.c
index 88b467486da1..228438955006 100644
--- a/usr.sbin/watchdogd/watchdogd.c
+++ b/usr.sbin/watchdogd/watchdogd.c
@@ -396,6 +396,15 @@ watchdog_patpat(u_int t)
        return ioctl(fd, WDIOCPATPAT, &t);
 }
 
+static int
+watchdog_control(u_int control)
+{
+       if (is_dry_run)
+               return (0);
+
+       return ioctl(fd, WDIOC_CONTROL, &control);
+}
+
 /*
  * Toggle the kernel's watchdog. This routine is used to enable and
  * disable the watchdog.
@@ -454,10 +463,10 @@ watchdog_onoff(int onoff)
                /* pat one more time for good measure */
                return watchdog_patpat((timeout|WD_ACTIVE));
         } else {
-               return watchdog_patpat(exit_timeout);
+               return watchdog_control(WD_CTRL_DISABLE);
         }
 failsafe:
-       watchdog_patpat(exit_timeout);
+       watchdog_control(WD_CTRL_DISABLE);
        return (error);
 }
 

Reply via email to