Add powerhooks, i.e., the ability to register a function that will be

called when the machine does a suspend or resume.
XXX Will go away when Jason's kevents come to life.
This commit is contained in:
augustss 1999-06-26 08:25:25 +00:00
parent fe0ddd929f
commit 94b815050e
3 changed files with 97 additions and 11 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: apm.c,v 1.38 1999/03/19 04:58:46 cgd Exp $ */
/* $NetBSD: apm.c,v 1.39 1999/06/26 08:25:25 augustss Exp $ */
/*-
* Copyright (c) 1996, 1997 The NetBSD Foundation, Inc.
@ -142,6 +142,7 @@ static void apm_set_ver __P((struct apm_softc *));
static void apm_standby __P((void));
static const char *apm_strerror __P((int));
static void apm_suspend __P((void));
static void apm_resume __P((struct apm_softc *, struct bioscallregs *));
cdev_decl(apm);
@ -348,6 +349,7 @@ apm_get_powstate(dev)
static void
apm_suspend()
{
dopowerhooks(PWR_SUSPEND);
/* XXX cgd */
(void)apm_set_powstate(APM_DEV_ALLDEVS, APM_SYS_SUSPEND);
@ -356,11 +358,22 @@ apm_suspend()
static void
apm_standby()
{
dopowerhooks(PWR_STANDBY);
/* XXX cgd */
(void)apm_set_powstate(APM_DEV_ALLDEVS, APM_SYS_STANDBY);
}
static void
apm_resume(sc, regs)
struct apm_softc *sc;
struct bioscallregs *regs;
{
inittodr(time.tv_sec);
dopowerhooks(PWR_RESUME);
apm_record_event(sc, regs->BX);
}
/*
* return 0 if the user will notice and handle the event,
* return 1 if the kernel driver should do so.
@ -467,26 +480,22 @@ apm_event_handle(sc, regs)
case APM_NORMAL_RESUME:
DPRINTF(APMDEBUG_EVENTS, ("apmev: resume system\n"));
inittodr(time.tv_sec);
apm_record_event(sc, regs->BX);
apm_resume(sc, regs);
break;
case APM_CRIT_RESUME:
DPRINTF(APMDEBUG_EVENTS, ("apmev: critical resume system"));
inittodr(time.tv_sec);
apm_record_event(sc, regs->BX);
apm_resume(sc, regs);
break;
case APM_SYS_STANDBY_RESUME:
DPRINTF(APMDEBUG_EVENTS, ("apmev: system standby resume\n"));
inittodr(time.tv_sec);
apm_record_event(sc, regs->BX);
apm_resume(sc, regs);
break;
case APM_UPDATE_TIME:
DPRINTF(APMDEBUG_EVENTS, ("apmev: update time\n"));
inittodr(time.tv_sec);
apm_record_event(sc, regs->BX);
apm_resume(sc, regs);
break;
case APM_CRIT_SUSPEND_REQ:
@ -604,6 +613,7 @@ apm_set_powstate(dev, state)
struct bioscallregs regs;
if (!apm_inited || (apm_minver == 0 && state > APM_SYS_OFF))
return EINVAL;
regs.BX = dev;
regs.CX = state;
if (apmcall(APM_SET_PWR_STATE, &regs) != 0) {

View File

@ -1,4 +1,4 @@
/* $NetBSD: kern_subr.c,v 1.51 1999/06/07 20:16:09 thorpej Exp $ */
/* $NetBSD: kern_subr.c,v 1.52 1999/06/26 08:25:25 augustss Exp $ */
/*-
* Copyright (c) 1997, 1998, 1999 The NetBSD Foundation, Inc.
@ -314,6 +314,72 @@ doshutdownhooks()
}
}
/*
* "Power hook" types, functions, and variables.
*/
struct powerhook_desc {
LIST_ENTRY(powerhook_desc) sfd_list;
void (*sfd_fn) __P((int, void *));
void *sfd_arg;
};
LIST_HEAD(, powerhook_desc) powerhook_list;
void *
powerhook_establish(fn, arg)
void (*fn) __P((int, void *));
void *arg;
{
struct powerhook_desc *ndp;
ndp = (struct powerhook_desc *)
malloc(sizeof(*ndp), M_DEVBUF, M_NOWAIT);
if (ndp == NULL)
return NULL;
ndp->sfd_fn = fn;
ndp->sfd_arg = arg;
LIST_INSERT_HEAD(&powerhook_list, ndp, sfd_list);
return (ndp);
}
void
powerhook_disestablish(vhook)
void *vhook;
{
#ifdef DIAGNOSTIC
struct powerhook_desc *dp;
for (dp = powerhook_list.lh_first; dp != NULL;
dp = dp->sfd_list.le_next)
if (dp == vhook)
break;
if (dp == NULL)
panic("powerhook_disestablish: hook not established");
#endif
LIST_REMOVE((struct powerhook_desc *)vhook, sfd_list);
free(vhook, M_DEVBUF);
}
/*
* Run power hooks.
*/
void
dopowerhooks(why)
int why;
{
struct powerhook_desc *dp;
for (dp = LIST_FIRST(&powerhook_list);
dp != NULL;
dp = LIST_NEXT(dp, sfd_list)) {
(*dp->sfd_fn)(why, dp->sfd_arg);
}
}
/*
* "Mountroot hook" types, functions, and variables.
*/

View File

@ -1,4 +1,4 @@
/* $NetBSD: systm.h,v 1.91 1999/05/20 05:53:34 lukem Exp $ */
/* $NetBSD: systm.h,v 1.92 1999/06/26 08:25:26 augustss Exp $ */
/*-
* Copyright (c) 1982, 1988, 1991, 1993
@ -266,6 +266,16 @@ void *shutdownhook_establish __P((void (*)(void *), void *));
void shutdownhook_disestablish __P((void *));
void doshutdownhooks __P((void));
/*
* Power managment hooks.
*/
void *powerhook_establish __P((void (*)(int, void *), void *));
void powerhook_disestablish __P((void *));
void dopowerhooks __P((int));
#define PWR_RESUME 0
#define PWR_SUSPEND 1
#define PWR_STANDBY 2
/*
* Mountroot hooks. Device drivers establish these to be executed
* just before (*mountroot)() if the passed device is selected