BUGFIX: SigmarionII can't resume.
Added config_hook_call_reverse() to call the hardpower hook of CMU (Vr clock mask unit) before the hardpower hook of MQ200 video controller.
This commit is contained in:
parent
3b2e959dfc
commit
9373835df6
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: config_hook.c,v 1.3 2002/01/13 14:00:39 takemura Exp $ */
|
||||
/* $NetBSD: config_hook.c,v 1.4 2002/05/12 07:41:22 takemura Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1999-2001
|
||||
|
@ -43,7 +43,7 @@
|
|||
#include <machine/config_hook.h>
|
||||
|
||||
struct hook_rec {
|
||||
LIST_ENTRY(hook_rec) hr_link;
|
||||
CIRCLEQ_ENTRY(hook_rec) hr_link;
|
||||
void *hr_ctx;
|
||||
int hr_type;
|
||||
long hr_id;
|
||||
|
@ -51,7 +51,7 @@ struct hook_rec {
|
|||
int (*hr_func)(void *, int, long, void *);
|
||||
};
|
||||
|
||||
LIST_HEAD(hook_list, hook_rec);
|
||||
CIRCLEQ_HEAD(hook_list, hook_rec);
|
||||
struct hook_list hook_lists[CONFIG_HOOK_NTYPES];
|
||||
struct hook_list call_list;
|
||||
|
||||
|
@ -61,9 +61,9 @@ config_hook_init()
|
|||
int i;
|
||||
|
||||
for (i = 0; i < CONFIG_HOOK_NTYPES; i++) {
|
||||
LIST_INIT(&hook_lists[i]);
|
||||
CIRCLEQ_INIT(&hook_lists[i]);
|
||||
}
|
||||
LIST_INIT(&call_list);
|
||||
CIRCLEQ_INIT(&call_list);
|
||||
}
|
||||
|
||||
config_hook_tag
|
||||
|
@ -80,8 +80,7 @@ config_hook(int type, long id, enum config_hook_mode mode,
|
|||
|
||||
/* check mode compatibility */
|
||||
prev_hr = NULL;
|
||||
for (hr = LIST_FIRST(&hook_lists[type]); hr != NULL;
|
||||
hr = LIST_NEXT(hr, hr_link)) {
|
||||
CIRCLEQ_FOREACH(hr, &hook_lists[type], hr_link) {
|
||||
if (hr->hr_id == id) {
|
||||
if (hr->hr_mode != mode) {
|
||||
panic("config_hook: incompatible mode on "
|
||||
|
@ -100,8 +99,8 @@ config_hook(int type, long id, enum config_hook_mode mode,
|
|||
printf("config_hook: type=%d/id=%ld is replaced",
|
||||
type, id);
|
||||
s = splhigh();
|
||||
LIST_REMOVE(prev_hr, hr_link);
|
||||
prev_hr->hr_link.le_next = NULL;
|
||||
CIRCLEQ_REMOVE(&hook_lists[type], prev_hr, hr_link);
|
||||
prev_hr->hr_link.cqe_next = NULL;
|
||||
splx(s);
|
||||
}
|
||||
break;
|
||||
|
@ -127,11 +126,10 @@ config_hook(int type, long id, enum config_hook_mode mode,
|
|||
hr->hr_mode = mode;
|
||||
|
||||
s = splhigh();
|
||||
LIST_INSERT_HEAD(&hook_lists[type], hr, hr_link);
|
||||
CIRCLEQ_INSERT_HEAD(&hook_lists[type], hr, hr_link);
|
||||
|
||||
/* update call list */
|
||||
for (cr = LIST_FIRST(&call_list); cr != NULL;
|
||||
cr = LIST_NEXT(cr, hr_link)) {
|
||||
CIRCLEQ_FOREACH(cr, &call_list, hr_link) {
|
||||
if (cr->hr_type == type && cr->hr_id == id) {
|
||||
if (cr->hr_func != NULL &&
|
||||
cr->hr_mode != mode) {
|
||||
|
@ -155,13 +153,12 @@ config_unhook(config_hook_tag hrx)
|
|||
int s;
|
||||
struct hook_rec *hr = (struct hook_rec*)hrx, *cr;
|
||||
|
||||
if (hr->hr_link.le_next != NULL) {
|
||||
if (hr->hr_link.cqe_next != NULL) {
|
||||
s = splhigh();
|
||||
LIST_REMOVE(hr, hr_link);
|
||||
hr->hr_link.le_next = NULL;
|
||||
CIRCLEQ_REMOVE(&hook_lists[hr->hr_type], hr, hr_link);
|
||||
hr->hr_link.cqe_next = NULL;
|
||||
/* update call list */
|
||||
for (cr = LIST_FIRST(&call_list); cr != NULL;
|
||||
cr = LIST_NEXT(cr, hr_link)) {
|
||||
CIRCLEQ_FOREACH(cr, &call_list, hr_link) {
|
||||
if (cr->hr_type == hr->hr_type &&
|
||||
cr->hr_id == hr->hr_id)
|
||||
cr->hr_func = NULL;
|
||||
|
@ -172,7 +169,7 @@ config_unhook(config_hook_tag hrx)
|
|||
}
|
||||
|
||||
int
|
||||
config_hook_call(int type, long id, void *msg)
|
||||
__config_hook_call(int type, long id, void *msg, int reverse)
|
||||
{
|
||||
int res;
|
||||
struct hook_rec *hr;
|
||||
|
@ -183,10 +180,15 @@ config_hook_call(int type, long id, void *msg)
|
|||
}
|
||||
|
||||
res = -1;
|
||||
for (hr = LIST_FIRST(&hook_lists[type]); hr != NULL;
|
||||
hr = LIST_NEXT(hr, hr_link)) {
|
||||
if (hr->hr_id == id) {
|
||||
res = (*hr->hr_func)(hr->hr_ctx, type, id, msg);
|
||||
if (reverse) {
|
||||
CIRCLEQ_FOREACH_REVERSE(hr, &hook_lists[type], hr_link) {
|
||||
if (hr->hr_id == id)
|
||||
res = (*hr->hr_func)(hr->hr_ctx, type, id,msg);
|
||||
}
|
||||
} else {
|
||||
CIRCLEQ_FOREACH(hr, &hook_lists[type], hr_link) {
|
||||
if (hr->hr_id == id)
|
||||
res = (*hr->hr_func)(hr->hr_ctx, type, id,msg);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -215,11 +217,10 @@ config_connect(int type, long id)
|
|||
|
||||
s = splhigh();
|
||||
/* insert the record into the call list */
|
||||
LIST_INSERT_HEAD(&call_list, cr, hr_link);
|
||||
CIRCLEQ_INSERT_HEAD(&call_list, cr, hr_link);
|
||||
|
||||
/* scan hook list */
|
||||
for (hr = LIST_FIRST(&hook_lists[type]); hr != NULL;
|
||||
hr = LIST_NEXT(hr, hr_link)) {
|
||||
CIRCLEQ_FOREACH(hr, &hook_lists[type], hr_link) {
|
||||
if (hr->hr_id == id) {
|
||||
if (hr->hr_mode == CONFIG_HOOK_SHARE)
|
||||
panic("config_connect: can't connect with "
|
||||
|
@ -241,7 +242,7 @@ config_disconnect(config_call_tag crx)
|
|||
struct hook_rec *cr = (struct hook_rec*)crx;
|
||||
|
||||
s = splhigh();
|
||||
LIST_REMOVE(cr, hr_link);
|
||||
CIRCLEQ_REMOVE(&call_list, cr, hr_link);
|
||||
splx(s);
|
||||
|
||||
free(cr, M_DEVBUF);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: config_hook.h,v 1.3 2002/03/22 09:18:07 takemura Exp $ */
|
||||
/* $NetBSD: config_hook.h,v 1.4 2002/05/12 07:41:23 takemura Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1999-2001
|
||||
|
@ -50,11 +50,23 @@ void config_hook_init(void);
|
|||
config_hook_tag config_hook(int, long, enum config_hook_mode,
|
||||
int (*func)(void *, int, long, void *), void *);
|
||||
void config_unhook(config_hook_tag);
|
||||
int config_hook_call(int, long, void *);
|
||||
int __config_hook_call(int, long, void *, int);
|
||||
config_call_tag config_connect(int, long);
|
||||
void config_disconnect(config_call_tag crx);
|
||||
int config_connected_call(config_call_tag, void *);
|
||||
|
||||
static inline int
|
||||
config_hook_call(int type, long id, void *msg)
|
||||
{
|
||||
return __config_hook_call(type, id, msg, 0);
|
||||
}
|
||||
|
||||
static inline int
|
||||
config_hook_call_reverse(int type, long id, void *msg)
|
||||
{
|
||||
return __config_hook_call(type, id, msg, 1);
|
||||
}
|
||||
|
||||
/*
|
||||
* hook types and IDs
|
||||
*/
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: hpcapm.c,v 1.11 2002/02/11 09:21:47 takemura Exp $ */
|
||||
/* $NetBSD: hpcapm.c,v 1.12 2002/05/12 07:41:23 takemura Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2000 Takemura Shin
|
||||
|
@ -365,7 +365,7 @@ hpcapm_set_powstate(void *scx, u_int devid, u_int powstat)
|
|||
delay(1000); /* 1msec */
|
||||
}
|
||||
#endif
|
||||
config_hook_call(CONFIG_HOOK_PMEVENT,
|
||||
config_hook_call_reverse(CONFIG_HOOK_PMEVENT,
|
||||
CONFIG_HOOK_PMEVENT_HARDPOWER,
|
||||
(void *)PWR_RESUME);
|
||||
DPRINTF(("hpcapm: resume\n"));
|
||||
|
@ -410,7 +410,7 @@ hpcapm_set_powstate(void *scx, u_int devid, u_int powstat)
|
|||
tx39power_suspend_cpu();
|
||||
}
|
||||
#endif
|
||||
config_hook_call(CONFIG_HOOK_PMEVENT,
|
||||
config_hook_call_reverse(CONFIG_HOOK_PMEVENT,
|
||||
CONFIG_HOOK_PMEVENT_HARDPOWER,
|
||||
(void *)PWR_RESUME);
|
||||
DPRINTF(("hpcapm: resume\n"));
|
||||
|
|
Loading…
Reference in New Issue