Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/dev/sysmon Update attach/detach routines and provide MOD...



details:   https://anonhg.NetBSD.org/src/rev/0af663260764
branches:  trunk
changeset: 807666:0af663260764
user:      pgoyette <pgoyette%NetBSD.org@localhost>
date:      Sat Apr 18 10:49:31 2015 +0000

description:
Update attach/detach routines and provide MODULE interface.

Confirmed that atf tests (which run via rump) still pass, and also
confirmed that panic/reboot work in both monolithic kernel and
loaded module.

diffstat:

 sys/dev/sysmon/swwdog.c |  198 ++++++++++++++++++++++++++++++++++++++---------
 1 files changed, 160 insertions(+), 38 deletions(-)

diffs (truncated from 316 to 300 lines):

diff -r 0d7c6a99034c -r 0af663260764 sys/dev/sysmon/swwdog.c
--- a/sys/dev/sysmon/swwdog.c   Sat Apr 18 09:47:13 2015 +0000
+++ b/sys/dev/sysmon/swwdog.c   Sat Apr 18 10:49:31 2015 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: swwdog.c,v 1.13 2014/04/13 13:19:50 pgoyette Exp $     */
+/*     $NetBSD: swwdog.c,v 1.14 2015/04/18 10:49:31 pgoyette Exp $     */
 
 /*
  * Copyright (c) 2004, 2005 Steven M. Bellovin
@@ -33,7 +33,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: swwdog.c,v 1.13 2014/04/13 13:19:50 pgoyette Exp $");
+__KERNEL_RCSID(0, "$NetBSD: swwdog.c,v 1.14 2015/04/18 10:49:31 pgoyette Exp $");
 
 /*
  *
@@ -41,8 +41,8 @@
  *
  */
 #include <sys/param.h>
+#include <sys/device.h>
 #include <sys/callout.h>
-#include <sys/device.h>
 #include <sys/kernel.h>
 #include <sys/kmem.h>
 #include <sys/reboot.h>
@@ -50,41 +50,58 @@
 #include <sys/sysctl.h>
 #include <sys/wdog.h>
 #include <sys/workqueue.h>
+#include <sys/module.h>
 #include <dev/sysmon/sysmonvar.h>
 
-#include "ioconf.h"
+#ifndef _MODULE
+#include "opt_modular.h"
+#endif
 
 struct swwdog_softc {
-       device_t sc_dev;
-       struct sysmon_wdog sc_smw;
-       struct callout sc_c;
-       int sc_wdog_armed;
+       device_t                sc_dev;
+       struct sysmon_wdog      sc_smw;
+       struct callout          sc_c;
+       int                     sc_armed;
 };
 
-void           swwdogattach(int);
+bool   swwdog_reboot = false;  /* false --> panic , true  --> reboot */
+
+static struct workqueue *wq;
+static device_t                swwdog_dev;
+
+MODULE(MODULE_CLASS_DRIVER, swwdog, NULL);
+
+#ifdef _LKM
+CFDRIVER_DECL(swwdog, DV_DULL, NULL);
+#endif
+
+int swwdogattach(int);
+
+static int     swwdog_setmode(struct sysmon_wdog *);
+static int     swwdog_tickle(struct sysmon_wdog *);
+static bool    swwdog_suspend(device_t, const pmf_qual_t *);
+static int     swwdog_arm(struct swwdog_softc *);
+static int     swwdog_disarm(struct swwdog_softc *);
+
+static void    swwdog_panic(void *);
+
+static void    swwdog_sysctl_setup(void);
+static struct sysctllog *swwdog_sysctllog = NULL;
 
 static int     swwdog_match(device_t, cfdata_t, void *);
 static void    swwdog_attach(device_t, device_t, void *);
 static int     swwdog_detach(device_t, int);
 static bool    swwdog_suspend(device_t, const pmf_qual_t *);
 
-static int swwdog_setmode(struct sysmon_wdog *);
-static int swwdog_tickle(struct sysmon_wdog *);
-
-static int swwdog_arm(struct swwdog_softc *);
-static int swwdog_disarm(struct swwdog_softc *);
-
-static void swwdog_panic(void *);
-
-bool swwdog_reboot = false;            /* set for panic instead of reboot */
-
-#define        SWDOG_DEFAULT   60              /* 60-second default period */
+static int     swwdog_init(void *);
+static int     swwdog_fini(void *);
+static int     swwdog_modcmd(modcmd_t, void *);
 
 CFATTACH_DECL_NEW(swwdog, sizeof(struct swwdog_softc),
        swwdog_match, swwdog_attach, swwdog_detach, NULL);
+extern struct cfdriver swwdog_cd;
 
-static void swwdog_sysctl_setup(void);
-static struct sysctllog *swwdog_sysctllog;
+#define        SWDOG_DEFAULT   60              /* 60-second default period */
 
 static void
 doreboot(struct work *wrkwrkwrk, void *p)
@@ -93,41 +110,51 @@
        cpu_reboot(0, NULL);
 }
 
-static struct workqueue *wq;
-
-void
+int
 swwdogattach(int n __unused)
 {
-       int err;
+       int error;
        static struct cfdata cf;
 
+printf("%s: entered\n", __func__); /* XXX PRG */
        if (workqueue_create(&wq, "swwreboot", doreboot, NULL,
            PRI_NONE, IPL_NONE, 0) != 0) {
                aprint_error("failed to create swwdog reboot wq");
+               return 1;
        }
 
-       err = config_cfattach_attach(swwdog_cd.cd_name, &swwdog_ca);
-       if (err) {
-               aprint_error("%s: couldn't register cfattach: %d\n",
-                   swwdog_cd.cd_name, err);
-               config_cfdriver_detach(&swwdog_cd);
+       error = config_cfattach_attach(swwdog_cd.cd_name, &swwdog_ca);
+       if (error) {
+               aprint_error("%s: unable to attach cfattach\n",
+                   swwdog_cd.cd_name);
                workqueue_destroy(wq);
-               return;
+               return error;
        }
 
        cf.cf_name = swwdog_cd.cd_name;
        cf.cf_atname = swwdog_cd.cd_name;
        cf.cf_unit = 0;
        cf.cf_fstate = FSTATE_STAR;
+       cf.cf_pspec = NULL;
+       cf.cf_loc = NULL;
+       cf.cf_flags = 0;
 
-       (void)config_attach_pseudo(&cf);
+       swwdog_dev = config_attach_pseudo(&cf);
 
-       return;
+printf("%s: swwdog_dev = 0x%p\n", __func__, swwdog_dev); /* XXX PRG */
+       if (swwdog_dev == NULL) {
+               config_cfattach_detach(swwdog_cd.cd_name, &swwdog_ca);
+               workqueue_destroy(wq);
+               return 1;
+       }
+       return 0;
 }
 
 static int
 swwdog_match(device_t parent, cfdata_t data, void *aux)
 {
+
+printf("%s: entered\n", __func__); /* XXX PRG */
        return 1;
 }
 
@@ -136,20 +163,31 @@
 {
        struct swwdog_softc *sc = device_private(self);
 
+printf("%s: entered\n", __func__); /* XXX PRG */
+       if (workqueue_create(&wq, "swwreboot", doreboot, NULL,
+           PRI_NONE, IPL_NONE, 0) != 0) {
+               aprint_error_dev(self, "failed to create reboot workqueue");
+       }
+
        sc->sc_dev = self;
        sc->sc_smw.smw_name = device_xname(self);
        sc->sc_smw.smw_cookie = sc;
        sc->sc_smw.smw_setmode = swwdog_setmode;
        sc->sc_smw.smw_tickle = swwdog_tickle;
        sc->sc_smw.smw_period = SWDOG_DEFAULT;
+
        callout_init(&sc->sc_c, 0);
        callout_setfunc(&sc->sc_c, swwdog_panic, sc);
 
        if (sysmon_wdog_register(&sc->sc_smw) == 0)
                aprint_normal_dev(self, "software watchdog initialized\n");
-       else
+       else {
                aprint_error_dev(self, "unable to register software "
                    "watchdog with sysmon\n");
+               callout_destroy(&sc->sc_c);
+               workqueue_destroy(wq);
+               return;
+       }
 
        if (!pmf_device_register(self, swwdog_suspend, NULL))
                aprint_error_dev(self, "couldn't establish power handler\n");
@@ -162,13 +200,15 @@
 {
        struct swwdog_softc *sc = device_private(self);
 
+printf("%s: entered\n", __func__); /* XXX PRG */
        pmf_device_deregister(self);
        swwdog_disarm(sc);
+       sysctl_teardown(&swwdog_sysctllog);
+       sysmon_wdog_unregister(&sc->sc_smw);
        callout_destroy(&sc->sc_c);
-       sysctl_teardown(&swwdog_sysctllog);
        workqueue_destroy(wq);
 
-       return 1;
+       return 0;
 }
 
 static bool
@@ -236,7 +276,7 @@
        swwdog_reboot = false;
        callout_schedule(&sc->sc_c, 60 * hz);   /* deliberate double-panic */
 
-       printf("%s: %d second timer expired\n", device_xname(sc->sc_dev),
+       printf("%s: %d second timer expired\n", "swwdog",
            sc->sc_smw.smw_period);
 
        if (do_panic)
@@ -261,3 +301,85 @@
            NULL, 0, &swwdog_reboot, sizeof(bool),
            CTL_HW, me->sysctl_num, CTL_CREATE, CTL_EOL);
 }
+
+/*
+ * Module management
+ */
+
+static
+int
+swwdog_init(void *arg)
+{
+#ifdef _LKM
+       /*
+        * Merge the driver info into the kernel tables and attach the
+        * pseudo-device
+        */
+       int error;
+
+       error = config_cfdriver_attach(&swwdog_cd);
+       if (error) {
+               aprint_error("%s: unable to attach cfdriver\n",
+                   swwdog_cd.cd_name);
+               return error;
+       }
+       error = swwdogattach(1);
+       if (error) {
+               aprint_error("%s: device attach failed\n", swwdog_cd.cd_name);
+               config_cfdriver_detach(&swwdog_cd);
+       }
+
+       return error;
+#else
+
+       return 0;
+#endif
+}
+
+static
+int
+swwdog_fini(void *arg)
+{
+       int error;
+
+       error = config_detach(swwdog_dev, 0);
+
+       error = config_cfattach_detach(swwdog_cd.cd_name, &swwdog_ca);
+       if (error)
+               aprint_error("%s: error detaching cfattach: %d\n",
+                   swwdog_cd.cd_name, error);
+
+#ifdef _LKM
+       error = config_cfdriver_detach(&swwdog_cd);
+       if (error)
+               aprint_error("%s: error detaching cfdriver: %d\n",
+                   swwdog_cd.cd_name, error);
+#endif
+
+        return error;
+}
+
+static
+int
+swwdog_modcmd(modcmd_t cmd, void *arg)
+{
+       int ret;
+ 
+printf("%s: cmd %d\n", __func__, cmd); /* XXX PRG */
+       switch (cmd) {



Home | Main Index | Thread Index | Old Index