Modularize sysmon and its components
This commit is contained in:
parent
ac0dac8111
commit
8061eede6f
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: sysmon.c,v 1.19 2014/07/25 08:10:39 dholland Exp $ */
|
||||
/* $NetBSD: sysmon.c,v 1.20 2015/04/23 23:22:03 pgoyette Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2000 Zembu Labs, Inc.
|
||||
@ -39,7 +39,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: sysmon.c,v 1.19 2014/07/25 08:10:39 dholland Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: sysmon.c,v 1.20 2015/04/23 23:22:03 pgoyette Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/conf.h>
|
||||
@ -49,9 +49,11 @@ __KERNEL_RCSID(0, "$NetBSD: sysmon.c,v 1.19 2014/07/25 08:10:39 dholland Exp $")
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/module.h>
|
||||
#include <sys/mutex.h>
|
||||
#include <sys/device.h>
|
||||
|
||||
#include <dev/sysmon/sysmonvar.h>
|
||||
#include <dev/sysmon/sysmonconf.h>
|
||||
|
||||
dev_type_open(sysmonopen);
|
||||
dev_type_close(sysmonclose);
|
||||
@ -75,6 +77,97 @@ const struct cdevsw sysmon_cdevsw = {
|
||||
.d_flag = D_OTHER | D_MPSAFE
|
||||
};
|
||||
|
||||
static int sysmon_match(device_t, cfdata_t, void *);
|
||||
static void sysmon_attach(device_t, device_t, void *);
|
||||
static int sysmon_detach(device_t, int);
|
||||
|
||||
static int sysmon_modcmd(modcmd_t, void *);
|
||||
|
||||
CFDRIVER_DECL(sysmon, DV_DULL, NULL);
|
||||
|
||||
/*
|
||||
* Info about our minor "devices"
|
||||
*/
|
||||
static struct sysmon_opvec *sysmon_opvec_table[] = { NULL, NULL, NULL };
|
||||
static int sysmon_refcnt[] = { 0, 0, 0 };
|
||||
static const char *sysmon_mod[] = { "sysmon_envsys",
|
||||
"sysmon_wdog",
|
||||
"sysmon_power" };
|
||||
|
||||
struct sysmon_softc {
|
||||
device_t sc_dev;
|
||||
kmutex_t sc_minor_mtx;
|
||||
};
|
||||
|
||||
static device_t sysmon_dev = NULL;
|
||||
|
||||
CFATTACH_DECL_NEW(sysmon, sizeof(struct sysmon_softc),
|
||||
sysmon_match, sysmon_attach, sysmon_detach, NULL);
|
||||
extern struct cfdriver sysmon_cd;
|
||||
|
||||
static int
|
||||
sysmon_match(device_t parent, cfdata_t data, void *aux)
|
||||
{
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void
|
||||
sysmon_attach(device_t parent, device_t self, void *aux)
|
||||
{
|
||||
|
||||
struct sysmon_softc *sc = device_private(self);
|
||||
|
||||
sc->sc_dev = self;
|
||||
|
||||
mutex_init(&sc->sc_minor_mtx, MUTEX_DEFAULT, IPL_NONE);
|
||||
}
|
||||
|
||||
static int
|
||||
sysmon_detach(device_t self, int flags)
|
||||
{
|
||||
struct sysmon_softc *sc = device_private(self);
|
||||
|
||||
mutex_destroy(&sc->sc_minor_mtx);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* sysmon_attach_minor
|
||||
*
|
||||
* Attach a minor device for wdog, power, or envsys. Manage a
|
||||
* reference count so we can prevent the device from being
|
||||
* detached if there are still users with the minor device opened.
|
||||
*
|
||||
* If the opvec argument is NULL, this is a request to detach the
|
||||
* minor device - make sure the refcnt is zero!
|
||||
*/
|
||||
int
|
||||
sysmon_attach_minor(int minor, struct sysmon_opvec *opvec)
|
||||
{
|
||||
struct sysmon_softc *sc = device_private(sysmon_dev);
|
||||
int ret;
|
||||
|
||||
mutex_enter(&sc->sc_minor_mtx);
|
||||
if (opvec) {
|
||||
if (sysmon_opvec_table[minor] == NULL) {
|
||||
sysmon_refcnt[minor] = 0;
|
||||
sysmon_opvec_table[minor] = opvec;
|
||||
ret = 0;
|
||||
} else
|
||||
ret = EEXIST;
|
||||
} else {
|
||||
if (sysmon_refcnt[minor] == 0) {
|
||||
sysmon_opvec_table[minor] = NULL;
|
||||
ret = 0;
|
||||
} else
|
||||
ret = EBUSY;
|
||||
}
|
||||
|
||||
mutex_exit(&sc->sc_minor_mtx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* sysmonopen:
|
||||
*
|
||||
@ -83,28 +176,33 @@ const struct cdevsw sysmon_cdevsw = {
|
||||
int
|
||||
sysmonopen(dev_t dev, int flag, int mode, struct lwp *l)
|
||||
{
|
||||
struct sysmon_softc *sc = device_private(sysmon_dev);
|
||||
int error;
|
||||
|
||||
mutex_enter(&sc->sc_minor_mtx);
|
||||
|
||||
switch (minor(dev)) {
|
||||
#if NSYSMON_ENVSYS > 0
|
||||
case SYSMON_MINOR_ENVSYS:
|
||||
error = sysmonopen_envsys(dev, flag, mode, l);
|
||||
break;
|
||||
#endif
|
||||
#if NSYSMON_WDOG > 0
|
||||
case SYSMON_MINOR_WDOG:
|
||||
error = sysmonopen_wdog(dev, flag, mode, l);
|
||||
break;
|
||||
#endif
|
||||
#if NSYSMON_POWER > 0
|
||||
case SYSMON_MINOR_POWER:
|
||||
error = sysmonopen_power(dev, flag, mode, l);
|
||||
if (sysmon_opvec_table[minor(dev)] == NULL) {
|
||||
mutex_exit(&sc->sc_minor_mtx);
|
||||
error = module_autoload(sysmon_mod[minor(dev)],
|
||||
MODULE_CLASS_MISC);
|
||||
mutex_enter(&sc->sc_minor_mtx);
|
||||
if (sysmon_opvec_table[minor(dev)] == NULL)
|
||||
error = ENODEV;
|
||||
}
|
||||
error = (sysmon_opvec_table[minor(dev)]->so_open)(dev, flag,
|
||||
mode, l);
|
||||
if (error == 0)
|
||||
sysmon_refcnt[minor(dev)]++;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
error = ENODEV;
|
||||
}
|
||||
|
||||
mutex_exit(&sc->sc_minor_mtx);
|
||||
return (error);
|
||||
}
|
||||
|
||||
@ -119,21 +217,20 @@ sysmonclose(dev_t dev, int flag, int mode, struct lwp *l)
|
||||
int error;
|
||||
|
||||
switch (minor(dev)) {
|
||||
#if NSYSMON_ENVSYS > 0
|
||||
case SYSMON_MINOR_ENVSYS:
|
||||
error = sysmonclose_envsys(dev, flag, mode, l);
|
||||
break;
|
||||
#endif
|
||||
#if NSYSMON_WDOG > 0
|
||||
case SYSMON_MINOR_WDOG:
|
||||
error = sysmonclose_wdog(dev, flag, mode, l);
|
||||
break;
|
||||
#endif
|
||||
#if NSYSMON_POWER > 0
|
||||
case SYSMON_MINOR_POWER:
|
||||
error = sysmonclose_power(dev, flag, mode, l);
|
||||
if (sysmon_opvec_table[minor(dev)] == NULL)
|
||||
error = ENODEV;
|
||||
else {
|
||||
error = (sysmon_opvec_table[minor(dev)]->so_close)(dev,
|
||||
flag, mode, l);
|
||||
if (error == 0) {
|
||||
sysmon_refcnt[minor(dev)]--;
|
||||
KASSERT(sysmon_refcnt[minor(dev)] >= 0);
|
||||
}
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
error = ENODEV;
|
||||
}
|
||||
@ -152,21 +249,15 @@ sysmonioctl(dev_t dev, u_long cmd, void *data, int flag, struct lwp *l)
|
||||
int error;
|
||||
|
||||
switch (minor(dev)) {
|
||||
#if NSYSMON_ENVSYS > 0
|
||||
case SYSMON_MINOR_ENVSYS:
|
||||
error = sysmonioctl_envsys(dev, cmd, data, flag, l);
|
||||
break;
|
||||
#endif
|
||||
#if NSYSMON_WDOG > 0
|
||||
case SYSMON_MINOR_WDOG:
|
||||
error = sysmonioctl_wdog(dev, cmd, data, flag, l);
|
||||
break;
|
||||
#endif
|
||||
#if NSYSMON_POWER > 0
|
||||
case SYSMON_MINOR_POWER:
|
||||
error = sysmonioctl_power(dev, cmd, data, flag, l);
|
||||
if (sysmon_opvec_table[minor(dev)] == NULL)
|
||||
error = ENODEV;
|
||||
else
|
||||
error = (sysmon_opvec_table[minor(dev)]->so_ioctl)(dev,
|
||||
cmd, data, flag, l);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
error = ENODEV;
|
||||
}
|
||||
@ -185,11 +276,13 @@ sysmonread(dev_t dev, struct uio *uio, int flags)
|
||||
int error;
|
||||
|
||||
switch (minor(dev)) {
|
||||
#if NSYSMON_POWER > 0
|
||||
case SYSMON_MINOR_POWER:
|
||||
error = sysmonread_power(dev, uio, flags);
|
||||
if (sysmon_opvec_table[minor(dev)] == NULL)
|
||||
error = ENODEV;
|
||||
else
|
||||
error = (sysmon_opvec_table[minor(dev)]->so_read)(dev,
|
||||
uio, flags);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
error = ENODEV;
|
||||
}
|
||||
@ -208,11 +301,13 @@ sysmonpoll(dev_t dev, int events, struct lwp *l)
|
||||
int rv;
|
||||
|
||||
switch (minor(dev)) {
|
||||
#if NSYSMON_POWER > 0
|
||||
case SYSMON_MINOR_POWER:
|
||||
rv = sysmonpoll_power(dev, events, l);
|
||||
if (sysmon_opvec_table[minor(dev)] == NULL)
|
||||
rv = events;
|
||||
else
|
||||
rv = (sysmon_opvec_table[minor(dev)]->so_poll)(dev,
|
||||
events, l);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
rv = events;
|
||||
}
|
||||
@ -231,14 +326,119 @@ sysmonkqfilter(dev_t dev, struct knote *kn)
|
||||
int error;
|
||||
|
||||
switch (minor(dev)) {
|
||||
#if NSYSMON_POWER > 0
|
||||
case SYSMON_MINOR_POWER:
|
||||
error = sysmonkqfilter_power(dev, kn);
|
||||
if (sysmon_opvec_table[minor(dev)] == NULL)
|
||||
error = ENODEV;
|
||||
else
|
||||
error = (sysmon_opvec_table[minor(dev)]->so_filter)(dev,
|
||||
kn);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
error = 1;
|
||||
}
|
||||
|
||||
return (error);
|
||||
}
|
||||
|
||||
MODULE(MODULE_CLASS_DRIVER, sysmon, "");
|
||||
|
||||
int
|
||||
sysmon_init(void)
|
||||
{
|
||||
devmajor_t bmajor, cmajor;
|
||||
static struct cfdata cf;
|
||||
int error = 0;
|
||||
|
||||
if (sysmon_dev != NULL) {
|
||||
return EEXIST;
|
||||
}
|
||||
|
||||
error = config_cfdriver_attach(&sysmon_cd);
|
||||
if (error) {
|
||||
aprint_error("%s: unable to attach cfdriver\n",
|
||||
sysmon_cd.cd_name);
|
||||
return error;
|
||||
}
|
||||
error = config_cfattach_attach(sysmon_cd.cd_name, &sysmon_ca);
|
||||
if (error) {
|
||||
config_cfdriver_detach(&sysmon_cd);
|
||||
aprint_error("%s: unable to attach cfattach\n",
|
||||
sysmon_cd.cd_name);
|
||||
return error;
|
||||
}
|
||||
|
||||
bmajor = cmajor = -1;
|
||||
error = devsw_attach("sysmon", NULL, &bmajor,
|
||||
&sysmon_cdevsw, &cmajor);
|
||||
if (error) {
|
||||
config_cfattach_detach(sysmon_cd.cd_name, &sysmon_ca);
|
||||
config_cfdriver_detach(&sysmon_cd);
|
||||
aprint_error("%s: unable to attach devsw\n",
|
||||
sysmon_cd.cd_name);
|
||||
return error;
|
||||
}
|
||||
|
||||
cf.cf_name = sysmon_cd.cd_name;
|
||||
cf.cf_atname = sysmon_cd.cd_name;
|
||||
cf.cf_unit = 0;
|
||||
cf.cf_fstate = FSTATE_STAR;
|
||||
cf.cf_pspec = NULL;
|
||||
cf.cf_loc = NULL;
|
||||
cf.cf_flags = 0;
|
||||
|
||||
sysmon_dev = config_attach_pseudo(&cf);
|
||||
if (sysmon_dev == NULL) {
|
||||
aprint_error("%s: failed to attach pseudo device\n",
|
||||
sysmon_cd.cd_name);
|
||||
error = ENODEV;
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
int
|
||||
sysmon_fini(void)
|
||||
{
|
||||
int error = 0;
|
||||
|
||||
if (sysmon_opvec_table[SYSMON_MINOR_ENVSYS] != NULL)
|
||||
error = EBUSY;
|
||||
else if (sysmon_opvec_table[SYSMON_MINOR_WDOG] != NULL)
|
||||
error = EBUSY;
|
||||
else if (sysmon_opvec_table[SYSMON_MINOR_POWER] != NULL)
|
||||
error = EBUSY;
|
||||
|
||||
else {
|
||||
config_detach(sysmon_dev, 0);
|
||||
devsw_detach(NULL, &sysmon_cdevsw);
|
||||
config_cfattach_detach(sysmon_cd.cd_name, &sysmon_ca);
|
||||
config_cfdriver_detach(&sysmon_cd);
|
||||
}
|
||||
if (error == 0)
|
||||
sysmon_dev = NULL;
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
static
|
||||
int
|
||||
sysmon_modcmd(modcmd_t cmd, void *arg)
|
||||
{
|
||||
int ret;
|
||||
|
||||
switch (cmd) {
|
||||
case MODULE_CMD_INIT:
|
||||
ret = sysmon_init();
|
||||
break;
|
||||
|
||||
case MODULE_CMD_FINI:
|
||||
ret = sysmon_fini();
|
||||
break;
|
||||
|
||||
case MODULE_CMD_STAT:
|
||||
default:
|
||||
ret = ENOTTY;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: sysmon_envsys.c,v 1.130 2015/04/13 16:33:25 riastradh Exp $ */
|
||||
/* $NetBSD: sysmon_envsys.c,v 1.131 2015/04/23 23:22:03 pgoyette Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2007, 2008 Juan Romero Pardines.
|
||||
@ -64,7 +64,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: sysmon_envsys.c,v 1.130 2015/04/13 16:33:25 riastradh Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: sysmon_envsys.c,v 1.131 2015/04/23 23:22:03 pgoyette Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/types.h>
|
||||
@ -77,6 +77,7 @@ __KERNEL_RCSID(0, "$NetBSD: sysmon_envsys.c,v 1.130 2015/04/13 16:33:25 riastrad
|
||||
#include <sys/mutex.h>
|
||||
#include <sys/kmem.h>
|
||||
#include <sys/rndsource.h>
|
||||
#include <sys/module.h>
|
||||
|
||||
#include <dev/sysmon/sysmonvar.h>
|
||||
#include <dev/sysmon/sysmon_envsysvar.h>
|
||||
@ -101,17 +102,46 @@ static void sme_initial_refresh(void *);
|
||||
static uint32_t sme_get_max_value(struct sysmon_envsys *,
|
||||
bool (*)(const envsys_data_t*), bool);
|
||||
|
||||
MODULE(MODULE_CLASS_MISC, sysmon_envsys, "sysmon,sysmon_taskq");
|
||||
|
||||
static struct sysmon_opvec sysmon_envsys_opvec = {
|
||||
sysmonopen_envsys, sysmonclose_envsys, sysmonioctl_envsys,
|
||||
NULL, NULL, NULL
|
||||
};
|
||||
|
||||
/*
|
||||
* sysmon_envsys_init:
|
||||
*
|
||||
* + Initialize global mutex, dictionary and the linked list.
|
||||
*/
|
||||
void
|
||||
int
|
||||
sysmon_envsys_init(void)
|
||||
{
|
||||
int error;
|
||||
|
||||
LIST_INIT(&sysmon_envsys_list);
|
||||
mutex_init(&sme_global_mtx, MUTEX_DEFAULT, IPL_NONE);
|
||||
sme_propd = prop_dictionary_create();
|
||||
|
||||
error = sysmon_attach_minor(SYSMON_MINOR_ENVSYS, &sysmon_envsys_opvec);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
int
|
||||
sysmon_envsys_fini(void)
|
||||
{
|
||||
int error;
|
||||
|
||||
if ( ! LIST_EMPTY(&sysmon_envsys_list))
|
||||
error = EBUSY;
|
||||
else
|
||||
error = sysmon_attach_minor(SYSMON_MINOR_ENVSYS, NULL);
|
||||
|
||||
if (error == 0)
|
||||
mutex_destroy(&sme_global_mtx);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -771,7 +801,6 @@ out:
|
||||
*/
|
||||
if (error == 0) {
|
||||
nevent = 0;
|
||||
sysmon_task_queue_init();
|
||||
|
||||
if (sme->sme_flags & SME_INIT_REFRESH) {
|
||||
sysmon_task_queue_sched(0, sme_initial_refresh, sme);
|
||||
@ -848,6 +877,7 @@ out2:
|
||||
SLIST_REMOVE_HEAD(&sme_evdrv_list, evdrv_head);
|
||||
kmem_free(evdv, sizeof(*evdv));
|
||||
}
|
||||
printf("%s: finished, error %d\n", __func__, error);
|
||||
if (!error)
|
||||
return 0;
|
||||
|
||||
@ -2034,3 +2064,26 @@ sysmon_envsys_refresh_sensor(struct sysmon_envsys *sme, envsys_data_t *edata)
|
||||
rnd_add_uint32(&edata->rnd_src, edata->value_cur);
|
||||
edata->value_prev = edata->value_cur;
|
||||
}
|
||||
|
||||
static
|
||||
int
|
||||
sysmon_envsys_modcmd(modcmd_t cmd, void *arg)
|
||||
{
|
||||
int ret;
|
||||
|
||||
switch (cmd) {
|
||||
case MODULE_CMD_INIT:
|
||||
ret = sysmon_envsys_init();
|
||||
break;
|
||||
|
||||
case MODULE_CMD_FINI:
|
||||
ret = sysmon_envsys_fini();
|
||||
break;
|
||||
|
||||
case MODULE_CMD_STAT:
|
||||
default:
|
||||
ret = ENOTTY;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: sysmon_power.c,v 1.53 2015/04/13 16:33:25 riastradh Exp $ */
|
||||
/* $NetBSD: sysmon_power.c,v 1.54 2015/04/23 23:22:03 pgoyette Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2007 Juan Romero Pardines.
|
||||
@ -69,9 +69,12 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: sysmon_power.c,v 1.53 2015/04/13 16:33:25 riastradh Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: sysmon_power.c,v 1.54 2015/04/23 23:22:03 pgoyette Exp $");
|
||||
|
||||
#ifndef _LKM
|
||||
#include "opt_compat_netbsd.h"
|
||||
#endif
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/reboot.h>
|
||||
#include <sys/systm.h>
|
||||
@ -84,10 +87,13 @@ __KERNEL_RCSID(0, "$NetBSD: sysmon_power.c,v 1.53 2015/04/13 16:33:25 riastradh
|
||||
#include <sys/proc.h>
|
||||
#include <sys/device.h>
|
||||
#include <sys/rndsource.h>
|
||||
#include <sys/module.h>
|
||||
|
||||
#include <dev/sysmon/sysmonvar.h>
|
||||
#include <prop/proplib.h>
|
||||
|
||||
MODULE(MODULE_CLASS_MISC, sysmon_power, "sysmon");
|
||||
|
||||
/*
|
||||
* Singly linked list for dictionaries to be stored/sent.
|
||||
*/
|
||||
@ -186,17 +192,24 @@ static int sysmon_power_daemon_task(struct power_event_dictionary *,
|
||||
void *, int);
|
||||
static void sysmon_power_destroy_dictionary(struct power_event_dictionary *);
|
||||
|
||||
static struct sysmon_opvec sysmon_power_opvec = {
|
||||
sysmonopen_power, sysmonclose_power, sysmonioctl_power,
|
||||
sysmonread_power, sysmonpoll_power, sysmonkqfilter_power
|
||||
};
|
||||
|
||||
#define SYSMON_NEXT_EVENT(x) (((x) + 1) % SYSMON_MAX_POWER_EVENTS)
|
||||
|
||||
/*
|
||||
* sysmon_power_init:
|
||||
*
|
||||
* Initializes the mutexes and condition variables in the
|
||||
* boot process via init_main.c.
|
||||
* boot process via module initialization process.
|
||||
*/
|
||||
void
|
||||
int
|
||||
sysmon_power_init(void)
|
||||
{
|
||||
int error;
|
||||
|
||||
mutex_init(&sysmon_power_event_queue_mtx, MUTEX_DEFAULT, IPL_NONE);
|
||||
cv_init(&sysmon_power_event_queue_cv, "smpower");
|
||||
selinit(&sysmon_power_event_queue_selinfo);
|
||||
@ -204,6 +217,29 @@ sysmon_power_init(void)
|
||||
rnd_attach_source(&sysmon_rndsource, "system-power",
|
||||
RND_TYPE_POWER, RND_FLAG_DEFAULT);
|
||||
|
||||
error = sysmon_attach_minor(SYSMON_MINOR_POWER, &sysmon_power_opvec);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
int
|
||||
sysmon_power_fini(void)
|
||||
{
|
||||
int error;
|
||||
|
||||
if (sysmon_power_daemon != NULL)
|
||||
error = EBUSY;
|
||||
else
|
||||
error = sysmon_attach_minor(SYSMON_MINOR_POWER, NULL);
|
||||
|
||||
if (error == 0) {
|
||||
rnd_detach_source(&sysmon_rndsource);
|
||||
seldestroy(&sysmon_power_event_queue_selinfo);
|
||||
cv_destroy(&sysmon_power_event_queue_cv);
|
||||
mutex_destroy(&sysmon_power_event_queue_mtx);
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1059,3 +1095,27 @@ sysmon_pswitch_event(struct sysmon_pswitch *smpsw, int event)
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
static
|
||||
int
|
||||
sysmon_power_modcmd(modcmd_t cmd, void *arg)
|
||||
{
|
||||
int ret;
|
||||
|
||||
switch (cmd) {
|
||||
case MODULE_CMD_INIT:
|
||||
ret = sysmon_power_init();
|
||||
break;
|
||||
|
||||
case MODULE_CMD_FINI:
|
||||
ret = sysmon_power_fini();
|
||||
break;
|
||||
|
||||
case MODULE_CMD_STAT:
|
||||
default:
|
||||
ret = ENOTTY;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: sysmon_taskq.c,v 1.14 2008/09/05 22:06:52 gmcgarry Exp $ */
|
||||
/* $NetBSD: sysmon_taskq.c,v 1.15 2015/04/23 23:22:03 pgoyette Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2001, 2003 Wasabi Systems, Inc.
|
||||
@ -41,7 +41,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: sysmon_taskq.c,v 1.14 2008/09/05 22:06:52 gmcgarry Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: sysmon_taskq.c,v 1.15 2015/04/23 23:22:03 pgoyette Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/malloc.h>
|
||||
@ -49,6 +49,7 @@ __KERNEL_RCSID(0, "$NetBSD: sysmon_taskq.c,v 1.14 2008/09/05 22:06:52 gmcgarry E
|
||||
#include <sys/proc.h>
|
||||
#include <sys/kthread.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/module.h>
|
||||
|
||||
#include <dev/sysmon/sysmon_taskq.h>
|
||||
|
||||
@ -71,15 +72,36 @@ static int sysmon_task_queue_cleanup_sem;
|
||||
static struct lwp *sysmon_task_queue_lwp;
|
||||
static void sysmon_task_queue_thread(void *);
|
||||
|
||||
MODULE(MODULE_CLASS_MISC, sysmon_taskq, NULL);
|
||||
|
||||
/*
|
||||
* XXX Normally, all initialization would be handled as part of
|
||||
* the module(9) framework. However, there are a number of
|
||||
* users of the sysmon_taskq facility that are not modular,
|
||||
* and these can directly call sysmon_task_queue_init()
|
||||
* directly. To accomodate these non-standard users, we
|
||||
* make sure that sysmon_task_queue_init() handles multiple
|
||||
* invocations. And we also ensure that, if any non-module
|
||||
* user exists, we don't allow the module to be unloaded.
|
||||
* (We can't use module_hold() for this, since the module(9)
|
||||
* framework itself isn't necessarily initialized yet.)
|
||||
*/
|
||||
|
||||
/*
|
||||
* sysmon_task_queue_preinit:
|
||||
*
|
||||
* Early one-time initialization of task-queue
|
||||
*/
|
||||
void
|
||||
sysmon_task_queue_preinit(void)
|
||||
{
|
||||
|
||||
mutex_init(&sysmon_task_queue_mtx, MUTEX_DEFAULT, IPL_VM);
|
||||
mutex_init(&sysmon_task_queue_init_mtx, MUTEX_DEFAULT, IPL_NONE);
|
||||
cv_init(&sysmon_task_queue_cv, "smtaskq");
|
||||
sysmon_task_queue_initialized = 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* sysmon_task_queue_init:
|
||||
*
|
||||
@ -91,12 +113,11 @@ sysmon_task_queue_init(void)
|
||||
int error;
|
||||
|
||||
mutex_enter(&sysmon_task_queue_init_mtx);
|
||||
if (sysmon_task_queue_initialized) {
|
||||
if (sysmon_task_queue_initialized++) {
|
||||
mutex_exit(&sysmon_task_queue_init_mtx);
|
||||
return;
|
||||
}
|
||||
|
||||
sysmon_task_queue_initialized = 1;
|
||||
mutex_exit(&sysmon_task_queue_init_mtx);
|
||||
|
||||
error = kthread_create(PRI_NONE, KTHREAD_MPSAFE, NULL,
|
||||
@ -117,6 +138,9 @@ void
|
||||
sysmon_task_queue_fini(void)
|
||||
{
|
||||
|
||||
if (sysmon_task_queue_initialized > 1)
|
||||
return EBUSY;
|
||||
|
||||
mutex_enter(&sysmon_task_queue_mtx);
|
||||
|
||||
sysmon_task_queue_cleanup_sem = 1;
|
||||
@ -209,3 +233,31 @@ sysmon_task_queue_sched(u_int pri, void (*func)(void *), void *arg)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static
|
||||
int
|
||||
sysmon_taskq_modcmd(modcmd_t cmd, void *arg)
|
||||
{
|
||||
int ret;
|
||||
|
||||
switch (cmd) {
|
||||
case MODULE_CMD_INIT:
|
||||
#ifdef _MODULE
|
||||
sysmon_task_queue_preinit();
|
||||
#endif
|
||||
sysmon_task_queue_init();
|
||||
ret = 0;
|
||||
break;
|
||||
|
||||
case MODULE_CMD_FINI:
|
||||
sysmon_task_queue_fini();
|
||||
ret = 0;
|
||||
break;
|
||||
|
||||
case MODULE_CMD_STAT:
|
||||
default:
|
||||
ret = ENOTTY;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: sysmon_wdog.c,v 1.25 2011/01/04 01:51:06 matt Exp $ */
|
||||
/* $NetBSD: sysmon_wdog.c,v 1.26 2015/04/23 23:22:03 pgoyette Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2000 Zembu Labs, Inc.
|
||||
@ -41,7 +41,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: sysmon_wdog.c,v 1.25 2011/01/04 01:51:06 matt Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: sysmon_wdog.c,v 1.26 2015/04/23 23:22:03 pgoyette Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/conf.h>
|
||||
@ -53,6 +53,7 @@ __KERNEL_RCSID(0, "$NetBSD: sysmon_wdog.c,v 1.25 2011/01/04 01:51:06 matt Exp $"
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/module.h>
|
||||
|
||||
#include <dev/sysmon/sysmonvar.h>
|
||||
|
||||
@ -74,9 +75,18 @@ void sysmon_wdog_critpoll(void *);
|
||||
void sysmon_wdog_shutdown(void *);
|
||||
void sysmon_wdog_ref(struct sysmon_wdog *);
|
||||
|
||||
void
|
||||
static struct sysmon_opvec sysmon_wdog_opvec = {
|
||||
sysmonopen_wdog, sysmonclose_wdog, sysmonioctl_wdog,
|
||||
NULL, NULL, NULL
|
||||
};
|
||||
|
||||
MODULE(MODULE_CLASS_MISC, sysmon_wdog, "sysmon");
|
||||
|
||||
int
|
||||
sysmon_wdog_init(void)
|
||||
{
|
||||
int error;
|
||||
|
||||
mutex_init(&sysmon_wdog_list_mtx, MUTEX_DEFAULT, IPL_NONE);
|
||||
mutex_init(&sysmon_wdog_mtx, MUTEX_DEFAULT, IPL_SOFTCLOCK);
|
||||
cv_init(&sysmon_wdog_cv, "wdogref");
|
||||
@ -87,6 +97,32 @@ sysmon_wdog_init(void)
|
||||
if (sysmon_wdog_cphook == NULL)
|
||||
printf("WARNING: unable to register watchdog critpoll hook\n");
|
||||
callout_init(&sysmon_wdog_callout, 0);
|
||||
|
||||
error = sysmon_attach_minor(SYSMON_MINOR_WDOG, &sysmon_wdog_opvec);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
int
|
||||
sysmon_wdog_fini(void)
|
||||
{
|
||||
int error;
|
||||
|
||||
if ( ! LIST_EMPTY(&sysmon_wdog_list))
|
||||
return EBUSY;
|
||||
|
||||
error = sysmon_attach_minor(SYSMON_MINOR_WDOG, NULL);
|
||||
|
||||
if (error == 0) {
|
||||
callout_destroy(&sysmon_wdog_callout);
|
||||
critpollhook_disestablish(sysmon_wdog_cphook);
|
||||
shutdownhook_disestablish(sysmon_wdog_sdhook);
|
||||
cv_destroy(&sysmon_wdog_cv);
|
||||
mutex_destroy(&sysmon_wdog_mtx);
|
||||
mutex_destroy(&sysmon_wdog_list_mtx);
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -500,3 +536,25 @@ sysmon_wdog_shutdown(void *arg)
|
||||
smw->smw_name);
|
||||
}
|
||||
}
|
||||
static
|
||||
int
|
||||
sysmon_wdog_modcmd(modcmd_t cmd, void *arg)
|
||||
{
|
||||
int ret;
|
||||
|
||||
switch (cmd) {
|
||||
case MODULE_CMD_INIT:
|
||||
ret = sysmon_wdog_init();
|
||||
break;
|
||||
|
||||
case MODULE_CMD_FINI:
|
||||
ret = sysmon_wdog_fini();
|
||||
break;
|
||||
|
||||
case MODULE_CMD_STAT:
|
||||
default:
|
||||
ret = ENOTTY;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -1,43 +0,0 @@
|
||||
/* $NetBSD: sysmonconf.h,v 1.3 2003/04/18 01:31:35 thorpej Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2000 Zembu Labs, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Author: Jason R. Thorpe <thorpej@zembu.com>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by Zembu Labs, Inc.
|
||||
* 4. Neither the name of Zembu Labs nor the names of its employees may
|
||||
* be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ZEMBU LABS, INC. ``AS IS'' AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WAR-
|
||||
* RANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DIS-
|
||||
* CLAIMED. IN NO EVENT SHALL ZEMBU LABS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _DEV_SYSMON_SYSMONCONF_H_
|
||||
#define _DEV_SYSMON_SYSMONCONF_H_
|
||||
|
||||
#include "sysmon_envsys.h"
|
||||
#include "sysmon_wdog.h"
|
||||
#include "sysmon_power.h"
|
||||
|
||||
#endif /* _DEV_SYSMON_SYSMONCONF_H_ */
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: sysmonvar.h,v 1.48 2015/04/18 14:44:44 mlelstv Exp $ */
|
||||
/* $NetBSD: sysmonvar.h,v 1.49 2015/04/23 23:22:03 pgoyette Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2000 Zembu Labs, Inc.
|
||||
@ -242,7 +242,8 @@ void sysmon_envsys_foreach_sensor(sysmon_envsys_callback_t, void *, bool);
|
||||
|
||||
int sysmon_envsys_update_limits(struct sysmon_envsys *, envsys_data_t *);
|
||||
|
||||
void sysmon_envsys_init(void);
|
||||
int sysmon_envsys_init(void);
|
||||
int sysmon_envsys_fini(void);
|
||||
|
||||
/*****************************************************************************
|
||||
* Watchdog timer support
|
||||
@ -270,7 +271,8 @@ int sysmon_wdog_setmode(struct sysmon_wdog *, int, u_int);
|
||||
int sysmon_wdog_register(struct sysmon_wdog *);
|
||||
int sysmon_wdog_unregister(struct sysmon_wdog *);
|
||||
|
||||
void sysmon_wdog_init(void);
|
||||
int sysmon_wdog_init(void);
|
||||
int sysmon_wdog_fini(void);
|
||||
|
||||
/*****************************************************************************
|
||||
* Power management support
|
||||
@ -298,6 +300,23 @@ void sysmon_pswitch_unregister(struct sysmon_pswitch *);
|
||||
void sysmon_pswitch_event(struct sysmon_pswitch *, int);
|
||||
void sysmon_penvsys_event(struct penvsys_state *, int);
|
||||
|
||||
void sysmon_power_init(void);
|
||||
int sysmon_power_init(void);
|
||||
int sysmon_power_fini(void);
|
||||
|
||||
/*
|
||||
* Interface to sysmon common code used for autoloading
|
||||
*/
|
||||
struct sysmon_opvec {
|
||||
int (*so_open)(dev_t, int, int, struct lwp*);
|
||||
int (*so_close)(dev_t, int, int, struct lwp*);
|
||||
int (*so_ioctl)(dev_t, u_long, void *, int, struct lwp*);
|
||||
int (*so_read)(dev_t, struct uio*, int);
|
||||
int (*so_poll)(dev_t, int, struct lwp*);
|
||||
int (*so_filter)(dev_t, struct knote*);
|
||||
};
|
||||
|
||||
int sysmon_init(void);
|
||||
int sysmon_fini(void);
|
||||
int sysmon_attach_minor(int, struct sysmon_opvec*);
|
||||
|
||||
#endif /* _DEV_SYSMON_SYSMONVAR_H_ */
|
||||
|
Loading…
Reference in New Issue
Block a user