summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/i386/apm/apm.c115
-rw-r--r--sys/i386/bios/apm.c115
-rw-r--r--sys/i386/include/apm_bios.h1
3 files changed, 105 insertions, 126 deletions
diff --git a/sys/i386/apm/apm.c b/sys/i386/apm/apm.c
index 6b00464..d62b70b 100644
--- a/sys/i386/apm/apm.c
+++ b/sys/i386/apm/apm.c
@@ -103,9 +103,17 @@ static struct cdevsw apm_cdevsw = {
static int apm_suspend_delay = 1;
static int apm_standby_delay = 1;
+static int apm_debug = 0;
+
+#define APM_DPRINT(args...) do { \
+ if (apm_debug) { \
+ printf(args); \
+ } \
+} while (0)
SYSCTL_INT(_machdep, OID_AUTO, apm_suspend_delay, CTLFLAG_RW, &apm_suspend_delay, 1, "");
SYSCTL_INT(_machdep, OID_AUTO, apm_standby_delay, CTLFLAG_RW, &apm_standby_delay, 1, "");
+SYSCTL_INT(_debug, OID_AUTO, apm_debug, CTLFLAG_RW, &apm_debug, 0, "");
/*
* return 0 if the function successfull,
@@ -120,10 +128,8 @@ apm_bioscall(void)
u_int apm_func = sc->bios.r.eax & 0xff;
if (!apm_check_function_supported(sc->intversion, apm_func)) {
-#ifdef APM_DEBUG
- printf("apm_bioscall: function 0x%x is not supported in v%d.%d\n",
- apm_func, sc->majorversion, sc->minorversion);
-#endif
+ APM_DPRINT("apm_bioscall: function 0x%x is not supported in v%d.%d\n",
+ apm_func, sc->majorversion, sc->minorversion);
return (-1);
}
@@ -269,12 +275,21 @@ apm_display(int newstate)
sc->bios.r.ebx = PMDV_DISP0;
sc->bios.r.ecx = newstate ? PMST_APMENABLED:PMST_SUSPEND;
sc->bios.r.edx = 0;
- if (apm_bioscall()) {
- printf("Display off failure: errcode = %d\n",
- 0xff & (sc->bios.r.eax >> 8));
- return 1;
+ if (apm_bioscall() == 0) {
+ return 0;
}
- return 0;
+
+ /* If failed, then try to blank all display devices instead. */
+ sc->bios.r.eax = (APM_BIOS << 8) | APM_SETPWSTATE;
+ sc->bios.r.ebx = PMDV_DISPALL; /* all display devices */
+ sc->bios.r.ecx = newstate ? PMST_APMENABLED:PMST_SUSPEND;
+ sc->bios.r.edx = 0;
+ if (apm_bioscall() == 0) {
+ return 0;
+ }
+ printf("Display off failure: errcode = %d\n",
+ 0xff & (sc->bios.r.eax >> 8));
+ return 1;
}
/*
@@ -309,9 +324,7 @@ apm_add_hook(struct apmhook **list, struct apmhook *ah)
int s;
struct apmhook *p, *prev;
-#ifdef APM_DEBUG
- printf("Add hook \"%s\"\n", ah->ah_name);
-#endif
+ APM_DPRINT("Add hook \"%s\"\n", ah->ah_name);
s = splhigh();
if (ah == NULL)
@@ -362,9 +375,7 @@ apm_execute_hook(struct apmhook *list)
struct apmhook *p;
for (p = list; p != NULL; p = p->ah_next) {
-#ifdef APM_DEBUG
- printf("Execute APM hook \"%s.\"\n", p->ah_name);
-#endif
+ APM_DPRINT("Execute APM hook \"%s.\"\n", p->ah_name);
if ((*(p->ah_fun))(p->ah_arg))
printf("Warning: APM hook \"%s\" failed", p->ah_name);
}
@@ -537,9 +548,7 @@ apm_lastreq_rejected(void)
sc->bios.r.edx = 0;
if (apm_bioscall()) {
-#ifdef APM_DEBUG
- printf("apm_lastreq_rejected: failed\n");
-#endif
+ APM_DPRINT("apm_lastreq_rejected: failed\n");
return 1;
}
apm_op_inprog = 0;
@@ -725,9 +734,7 @@ apm_event_enable(void)
{
struct apm_softc *sc = &apm_softc;
-#ifdef APM_DEBUG
- printf("called apm_event_enable()\n");
-#endif
+ APM_DPRINT("called apm_event_enable()\n");
if (sc->initialized) {
sc->active = 1;
apm_timeout(sc);
@@ -740,9 +747,7 @@ apm_event_disable(void)
{
struct apm_softc *sc = &apm_softc;
-#ifdef APM_DEBUG
- printf("called apm_event_disable()\n");
-#endif
+ APM_DPRINT("called apm_event_disable()\n");
if (sc->initialized) {
untimeout(apm_timeout, NULL, apm_timeout_ch);
sc->active = 0;
@@ -903,12 +908,9 @@ apm_processevent(void)
int apm_event;
struct apm_softc *sc = &apm_softc;
-#ifdef APM_DEBUG
-# define OPMEV_DEBUGMESSAGE(symbol) case symbol: \
- printf("Received APM Event: " #symbol "\n");
-#else
-# define OPMEV_DEBUGMESSAGE(symbol) case symbol:
-#endif
+#define OPMEV_DEBUGMESSAGE(symbol) case symbol: \
+ APM_DPRINT("Received APM Event: " #symbol "\n");
+
do {
apm_event = apm_getevent();
switch (apm_event) {
@@ -1013,17 +1015,17 @@ apm_attach(device_t dev)
/* Always call HLT in idle loop */
sc->always_halt_cpu = 1;
+ getenv_int("debug.apm_debug", &apm_debug);
+
/* print bootstrap messages */
-#ifdef APM_DEBUG
- printf("apm: APM BIOS version %04x\n", apm_version);
- printf("apm: Code16 0x%08x, Data 0x%08x\n",
- sc->bios.seg.code16.base, sc->bios.seg.data.base);
- printf("apm: Code entry 0x%08x, Idling CPU %s, Management %s\n",
- sc->bios.entry, is_enabled(sc->slow_idle_cpu),
- is_enabled(!sc->disabled));
- printf("apm: CS_limit=0x%x, DS_limit=0x%x\n",
- sc->bios.seg.code16.limit, sc->bios.seg.data.limit);
-#endif /* APM_DEBUG */
+ APM_DPRINT("apm: APM BIOS version %04lx\n", apm_version);
+ APM_DPRINT("apm: Code16 0x%08x, Data 0x%08x\n",
+ sc->bios.seg.code16.base, sc->bios.seg.data.base);
+ APM_DPRINT("apm: Code entry 0x%08x, Idling CPU %s, Management %s\n",
+ sc->bios.entry, is_enabled(sc->slow_idle_cpu),
+ is_enabled(!sc->disabled));
+ APM_DPRINT("apm: CS_limit=0x%x, DS_limit=0x%x\n",
+ sc->bios.seg.code16.limit, sc->bios.seg.data.limit);
/*
* In one test, apm bios version was 1.02; an attempt to register
@@ -1041,38 +1043,29 @@ apm_attach(device_t dev)
sc->intversion = INTVERSION(sc->majorversion, sc->minorversion);
-#ifdef APM_DEBUG
if (sc->intversion >= INTVERSION(1, 1))
- printf("apm: Engaged control %s\n", is_enabled(!sc->disengaged));
-#endif
-
- printf("apm: found APM BIOS v%ld.%ld, connected at v%d.%d\n",
+ APM_DPRINT("apm: Engaged control %s\n", is_enabled(!sc->disengaged));
+ device_printf(dev, "found APM BIOS v%ld.%ld, connected at v%d.%d\n",
((apm_version & 0xf000) >> 12) * 10 + ((apm_version & 0x0f00) >> 8),
((apm_version & 0x00f0) >> 4) * 10 + ((apm_version & 0x000f) >> 0),
sc->majorversion, sc->minorversion);
-#ifdef APM_DEBUG
- printf("apm: Slow Idling CPU %s\n", is_enabled(sc->slow_idle_cpu));
-#endif
+ APM_DPRINT("apm: Slow Idling CPU %s\n", is_enabled(sc->slow_idle_cpu));
/* enable power management */
if (sc->disabled) {
if (apm_enable_disable_pm(1)) {
-#ifdef APM_DEBUG
- printf("apm: *Warning* enable function failed! [%x]\n",
- (sc->bios.r.eax >> 8) & 0xff);
-#endif
+ APM_DPRINT("apm: *Warning* enable function failed! [%x]\n",
+ (sc->bios.r.eax >> 8) & 0xff);
}
}
/* engage power managment (APM 1.1 or later) */
if (sc->intversion >= INTVERSION(1, 1) && sc->disengaged) {
if (apm_engage_disengage_pm(1)) {
-#ifdef APM_DEBUG
- printf("apm: *Warning* engage function failed err=[%x]",
- (sc->bios.r.eax >> 8) & 0xff);
- printf(" (Docked or using external power?).\n");
-#endif
+ APM_DPRINT("apm: *Warning* engage function failed err=[%x]",
+ (sc->bios.r.eax >> 8) & 0xff);
+ APM_DPRINT(" (Docked or using external power?).\n");
}
}
@@ -1164,9 +1157,7 @@ apmioctl(dev_t dev, u_long cmd, caddr_t addr, int flag, struct proc *p)
if (!sc->initialized)
return (ENXIO);
-#ifdef APM_DEBUG
- printf("APM ioctl: cmd = 0x%x\n", cmd);
-#endif
+ APM_DPRINT("APM ioctl: cmd = 0x%lx\n", cmd);
switch (cmd) {
case APMIO_SUSPEND:
if (!(flag & FWRITE))
@@ -1330,9 +1321,7 @@ apmwrite(dev_t dev, struct uio *uio, int ioflag)
enabled = 0;
}
sc->event_filter[event_type] = enabled;
-#ifdef APM_DEBUG
- printf("apmwrite: event 0x%x %s\n", event_type, is_enabled(enabled));
-#endif
+ APM_DPRINT("apmwrite: event 0x%x %s\n", event_type, is_enabled(enabled));
return uio->uio_resid;
}
diff --git a/sys/i386/bios/apm.c b/sys/i386/bios/apm.c
index 6b00464..d62b70b 100644
--- a/sys/i386/bios/apm.c
+++ b/sys/i386/bios/apm.c
@@ -103,9 +103,17 @@ static struct cdevsw apm_cdevsw = {
static int apm_suspend_delay = 1;
static int apm_standby_delay = 1;
+static int apm_debug = 0;
+
+#define APM_DPRINT(args...) do { \
+ if (apm_debug) { \
+ printf(args); \
+ } \
+} while (0)
SYSCTL_INT(_machdep, OID_AUTO, apm_suspend_delay, CTLFLAG_RW, &apm_suspend_delay, 1, "");
SYSCTL_INT(_machdep, OID_AUTO, apm_standby_delay, CTLFLAG_RW, &apm_standby_delay, 1, "");
+SYSCTL_INT(_debug, OID_AUTO, apm_debug, CTLFLAG_RW, &apm_debug, 0, "");
/*
* return 0 if the function successfull,
@@ -120,10 +128,8 @@ apm_bioscall(void)
u_int apm_func = sc->bios.r.eax & 0xff;
if (!apm_check_function_supported(sc->intversion, apm_func)) {
-#ifdef APM_DEBUG
- printf("apm_bioscall: function 0x%x is not supported in v%d.%d\n",
- apm_func, sc->majorversion, sc->minorversion);
-#endif
+ APM_DPRINT("apm_bioscall: function 0x%x is not supported in v%d.%d\n",
+ apm_func, sc->majorversion, sc->minorversion);
return (-1);
}
@@ -269,12 +275,21 @@ apm_display(int newstate)
sc->bios.r.ebx = PMDV_DISP0;
sc->bios.r.ecx = newstate ? PMST_APMENABLED:PMST_SUSPEND;
sc->bios.r.edx = 0;
- if (apm_bioscall()) {
- printf("Display off failure: errcode = %d\n",
- 0xff & (sc->bios.r.eax >> 8));
- return 1;
+ if (apm_bioscall() == 0) {
+ return 0;
}
- return 0;
+
+ /* If failed, then try to blank all display devices instead. */
+ sc->bios.r.eax = (APM_BIOS << 8) | APM_SETPWSTATE;
+ sc->bios.r.ebx = PMDV_DISPALL; /* all display devices */
+ sc->bios.r.ecx = newstate ? PMST_APMENABLED:PMST_SUSPEND;
+ sc->bios.r.edx = 0;
+ if (apm_bioscall() == 0) {
+ return 0;
+ }
+ printf("Display off failure: errcode = %d\n",
+ 0xff & (sc->bios.r.eax >> 8));
+ return 1;
}
/*
@@ -309,9 +324,7 @@ apm_add_hook(struct apmhook **list, struct apmhook *ah)
int s;
struct apmhook *p, *prev;
-#ifdef APM_DEBUG
- printf("Add hook \"%s\"\n", ah->ah_name);
-#endif
+ APM_DPRINT("Add hook \"%s\"\n", ah->ah_name);
s = splhigh();
if (ah == NULL)
@@ -362,9 +375,7 @@ apm_execute_hook(struct apmhook *list)
struct apmhook *p;
for (p = list; p != NULL; p = p->ah_next) {
-#ifdef APM_DEBUG
- printf("Execute APM hook \"%s.\"\n", p->ah_name);
-#endif
+ APM_DPRINT("Execute APM hook \"%s.\"\n", p->ah_name);
if ((*(p->ah_fun))(p->ah_arg))
printf("Warning: APM hook \"%s\" failed", p->ah_name);
}
@@ -537,9 +548,7 @@ apm_lastreq_rejected(void)
sc->bios.r.edx = 0;
if (apm_bioscall()) {
-#ifdef APM_DEBUG
- printf("apm_lastreq_rejected: failed\n");
-#endif
+ APM_DPRINT("apm_lastreq_rejected: failed\n");
return 1;
}
apm_op_inprog = 0;
@@ -725,9 +734,7 @@ apm_event_enable(void)
{
struct apm_softc *sc = &apm_softc;
-#ifdef APM_DEBUG
- printf("called apm_event_enable()\n");
-#endif
+ APM_DPRINT("called apm_event_enable()\n");
if (sc->initialized) {
sc->active = 1;
apm_timeout(sc);
@@ -740,9 +747,7 @@ apm_event_disable(void)
{
struct apm_softc *sc = &apm_softc;
-#ifdef APM_DEBUG
- printf("called apm_event_disable()\n");
-#endif
+ APM_DPRINT("called apm_event_disable()\n");
if (sc->initialized) {
untimeout(apm_timeout, NULL, apm_timeout_ch);
sc->active = 0;
@@ -903,12 +908,9 @@ apm_processevent(void)
int apm_event;
struct apm_softc *sc = &apm_softc;
-#ifdef APM_DEBUG
-# define OPMEV_DEBUGMESSAGE(symbol) case symbol: \
- printf("Received APM Event: " #symbol "\n");
-#else
-# define OPMEV_DEBUGMESSAGE(symbol) case symbol:
-#endif
+#define OPMEV_DEBUGMESSAGE(symbol) case symbol: \
+ APM_DPRINT("Received APM Event: " #symbol "\n");
+
do {
apm_event = apm_getevent();
switch (apm_event) {
@@ -1013,17 +1015,17 @@ apm_attach(device_t dev)
/* Always call HLT in idle loop */
sc->always_halt_cpu = 1;
+ getenv_int("debug.apm_debug", &apm_debug);
+
/* print bootstrap messages */
-#ifdef APM_DEBUG
- printf("apm: APM BIOS version %04x\n", apm_version);
- printf("apm: Code16 0x%08x, Data 0x%08x\n",
- sc->bios.seg.code16.base, sc->bios.seg.data.base);
- printf("apm: Code entry 0x%08x, Idling CPU %s, Management %s\n",
- sc->bios.entry, is_enabled(sc->slow_idle_cpu),
- is_enabled(!sc->disabled));
- printf("apm: CS_limit=0x%x, DS_limit=0x%x\n",
- sc->bios.seg.code16.limit, sc->bios.seg.data.limit);
-#endif /* APM_DEBUG */
+ APM_DPRINT("apm: APM BIOS version %04lx\n", apm_version);
+ APM_DPRINT("apm: Code16 0x%08x, Data 0x%08x\n",
+ sc->bios.seg.code16.base, sc->bios.seg.data.base);
+ APM_DPRINT("apm: Code entry 0x%08x, Idling CPU %s, Management %s\n",
+ sc->bios.entry, is_enabled(sc->slow_idle_cpu),
+ is_enabled(!sc->disabled));
+ APM_DPRINT("apm: CS_limit=0x%x, DS_limit=0x%x\n",
+ sc->bios.seg.code16.limit, sc->bios.seg.data.limit);
/*
* In one test, apm bios version was 1.02; an attempt to register
@@ -1041,38 +1043,29 @@ apm_attach(device_t dev)
sc->intversion = INTVERSION(sc->majorversion, sc->minorversion);
-#ifdef APM_DEBUG
if (sc->intversion >= INTVERSION(1, 1))
- printf("apm: Engaged control %s\n", is_enabled(!sc->disengaged));
-#endif
-
- printf("apm: found APM BIOS v%ld.%ld, connected at v%d.%d\n",
+ APM_DPRINT("apm: Engaged control %s\n", is_enabled(!sc->disengaged));
+ device_printf(dev, "found APM BIOS v%ld.%ld, connected at v%d.%d\n",
((apm_version & 0xf000) >> 12) * 10 + ((apm_version & 0x0f00) >> 8),
((apm_version & 0x00f0) >> 4) * 10 + ((apm_version & 0x000f) >> 0),
sc->majorversion, sc->minorversion);
-#ifdef APM_DEBUG
- printf("apm: Slow Idling CPU %s\n", is_enabled(sc->slow_idle_cpu));
-#endif
+ APM_DPRINT("apm: Slow Idling CPU %s\n", is_enabled(sc->slow_idle_cpu));
/* enable power management */
if (sc->disabled) {
if (apm_enable_disable_pm(1)) {
-#ifdef APM_DEBUG
- printf("apm: *Warning* enable function failed! [%x]\n",
- (sc->bios.r.eax >> 8) & 0xff);
-#endif
+ APM_DPRINT("apm: *Warning* enable function failed! [%x]\n",
+ (sc->bios.r.eax >> 8) & 0xff);
}
}
/* engage power managment (APM 1.1 or later) */
if (sc->intversion >= INTVERSION(1, 1) && sc->disengaged) {
if (apm_engage_disengage_pm(1)) {
-#ifdef APM_DEBUG
- printf("apm: *Warning* engage function failed err=[%x]",
- (sc->bios.r.eax >> 8) & 0xff);
- printf(" (Docked or using external power?).\n");
-#endif
+ APM_DPRINT("apm: *Warning* engage function failed err=[%x]",
+ (sc->bios.r.eax >> 8) & 0xff);
+ APM_DPRINT(" (Docked or using external power?).\n");
}
}
@@ -1164,9 +1157,7 @@ apmioctl(dev_t dev, u_long cmd, caddr_t addr, int flag, struct proc *p)
if (!sc->initialized)
return (ENXIO);
-#ifdef APM_DEBUG
- printf("APM ioctl: cmd = 0x%x\n", cmd);
-#endif
+ APM_DPRINT("APM ioctl: cmd = 0x%lx\n", cmd);
switch (cmd) {
case APMIO_SUSPEND:
if (!(flag & FWRITE))
@@ -1330,9 +1321,7 @@ apmwrite(dev_t dev, struct uio *uio, int ioflag)
enabled = 0;
}
sc->event_filter[event_type] = enabled;
-#ifdef APM_DEBUG
- printf("apmwrite: event 0x%x %s\n", event_type, is_enabled(enabled));
-#endif
+ APM_DPRINT("apmwrite: event 0x%x %s\n", event_type, is_enabled(enabled));
return uio->uio_resid;
}
diff --git a/sys/i386/include/apm_bios.h b/sys/i386/include/apm_bios.h
index 2ebffdf..768d0d7 100644
--- a/sys/i386/include/apm_bios.h
+++ b/sys/i386/include/apm_bios.h
@@ -95,6 +95,7 @@
#define PMDV_ALLDEV 0x0001
#define PMDV_DISP0 0x0100
#define PMDV_DISP1 0x0101
+#define PMDV_DISPALL 0x01ff
#define PMDV_2NDSTORAGE0 0x0200
#define PMDV_2NDSTORAGE1 0x0201
#define PMDV_2NDSTORAGE2 0x0202
OpenPOWER on IntegriCloud