summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorimp <imp@FreeBSD.org>1998-07-06 06:29:07 +0000
committerimp <imp@FreeBSD.org>1998-07-06 06:29:07 +0000
commitd1c7cd559fde7fd681b94ef7ab61b27a78d40bd0 (patch)
treed830b5d5eaf1867a83baf416172d0ae784546c19
parent3b5d08a30e5213746fe169860aaa6a77bfd9aee3 (diff)
downloadFreeBSD-src-d1c7cd559fde7fd681b94ef7ab61b27a78d40bd0.zip
FreeBSD-src-d1c7cd559fde7fd681b94ef7ab61b27a78d40bd0.tar.gz
Add the ability to suspend as well as hibernate to the system. This
is the kernel part of my commits, the userlevel stuff will be done in a separate commit. Add the ability to suspend as well as hibernate to syscons. Create a new virtual key like hibernate for suspend. Update apm_bios.h to define more apm bios goodies.
-rw-r--r--sys/alpha/include/console.h4
-rw-r--r--sys/dev/syscons/syscons.c23
-rw-r--r--sys/i386/apm/apm.c51
-rw-r--r--sys/i386/bios/apm.c51
-rw-r--r--sys/i386/include/apm_bios.h24
-rw-r--r--sys/i386/include/console.h4
-rw-r--r--sys/i386/isa/syscons.c23
-rw-r--r--sys/isa/syscons.c23
8 files changed, 157 insertions, 46 deletions
diff --git a/sys/alpha/include/console.h b/sys/alpha/include/console.h
index 2d05be0..9406441 100644
--- a/sys/alpha/include/console.h
+++ b/sys/alpha/include/console.h
@@ -25,7 +25,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * $Id: console.h,v 1.35 1998/02/03 19:57:45 bde Exp $
+ * $Id: console.h,v 1.36 1998/02/12 20:47:39 phk Exp $
*/
#ifndef _MACHINE_CONSOLE_H_
@@ -313,6 +313,8 @@ typedef struct ssaver ssaver_t;
#define DCAR 0x97 /* caron */
#define L_ACC DCAR /* last accent key */
+#define STBY 0x98 /* Go into standby mode (apm) */
+
#define F(x) ((x)+F_FN-1)
#define S(x) ((x)+F_SCR-1)
#define ACC(x) ((x)+F_ACC)
diff --git a/sys/dev/syscons/syscons.c b/sys/dev/syscons/syscons.c
index de7e370..8f11058 100644
--- a/sys/dev/syscons/syscons.c
+++ b/sys/dev/syscons/syscons.c
@@ -25,7 +25,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * $Id: syscons.c,v 1.263 1998/06/13 18:53:22 steve Exp $
+ * $Id: syscons.c,v 1.264 1998/06/24 10:21:30 yokota Exp $
*/
#include "sc.h"
@@ -528,6 +528,7 @@ sckbdprobe(int unit, int flags)
int codeset;
int c = -1;
int m;
+ int res, id;
sc_kbdc = kbdc_open(sc_port);
@@ -664,6 +665,17 @@ sckbdprobe(int unit, int flags)
printf("sc%d: unable to enable the keyboard port and intr.\n", unit);
goto fail;
}
+
+ /* Get the ID of the keyboard, if any */
+ empty_kbd_buffer(sc_kbdc, 5);
+ res = send_kbd_command(sc_kbdc, KBDC_SEND_DEV_ID);
+ if (res == KBD_ACK) {
+ /* 10ms delay */
+ DELAY(10000);
+ id = (read_kbd_data(sc_kbdc) << 8) | read_kbd_data(sc_kbdc);
+ if (bootverbose)
+ printf("sc%d: keyboard device ID: %04x\n", unit, id);
+ }
kbdc_set_device_mask(sc_kbdc, m | KBD_KBD_CONTROL_BITS),
kbdc_lock(sc_kbdc, FALSE);
@@ -3980,7 +3992,14 @@ next_code:
case SUSP:
#if NAPM > 0
accents = 0;
- apm_suspend();
+ apm_suspend(PMST_SUSPEND);
+#endif
+ break;
+
+ case STBY:
+#if NAPM > 0
+ accents = 0;
+ apm_suspend(PMST_STANDBY);
#endif
break;
diff --git a/sys/i386/apm/apm.c b/sys/i386/apm/apm.c
index 89e127f..7018f1d 100644
--- a/sys/i386/apm/apm.c
+++ b/sys/i386/apm/apm.c
@@ -15,7 +15,7 @@
*
* Sep, 1994 Implemented on FreeBSD 1.1.5.1R (Toshiba AVS001WD)
*
- * $Id: apm.c,v 1.71 1998/06/03 01:59:32 msmith Exp $
+ * $Id: apm.c,v 1.72 1998/06/07 17:09:55 dfr Exp $
*/
#include "opt_devfs.h"
@@ -202,13 +202,13 @@ apm_getevent(void)
/* suspend entire system */
static int
-apm_suspend_system(void)
+apm_suspend_system(int state)
{
u_long eax, ebx, ecx, edx;
eax = (APM_BIOS << 8) | APM_SETPWSTATE;
ebx = PMDV_ALLDEV;
- ecx = PMST_SUSPEND;
+ ecx = state;
edx = 0;
if (apm_int(&eax, &ebx, &ecx, &edx)) {
@@ -427,7 +427,7 @@ static void apm_processevent(void);
*/
void
-apm_suspend(void)
+apm_suspend(int state)
{
struct apm_softc *sc = &apm_softc;
@@ -436,7 +436,7 @@ apm_suspend(void)
if (sc->initialized) {
apm_execute_hook(hook[APM_HOOK_SUSPEND]);
- if (apm_suspend_system() == 0)
+ if (apm_suspend_system(state) == 0)
apm_processevent();
else
/* Failure, 'resume' the system again */
@@ -472,7 +472,7 @@ apm_get_info(apm_info_t aip)
if (apm_int(&eax, &ebx, &ecx, &edx))
return 1;
- aip->ai_infoversion = 0;
+ aip->ai_infoversion = 1;
aip->ai_acline = (ebx >> 8) & 0xff;
aip->ai_batt_stat = ebx & 0xff;
aip->ai_batt_life = ecx & 0xff;
@@ -486,6 +486,19 @@ apm_get_info(apm_info_t aip)
aip->ai_batt_time = (edx & 0x7fff) * 60;
else /* Time is in seconds */
aip->ai_batt_time = edx;
+
+ eax = (APM_BIOS << 8) | APM_GETCAPABILITIES;
+ ebx = 0;
+ ecx = 0;
+ edx = 0;
+ if (apm_int(&eax, &ebx, &ecx, &edx)) {
+ aip->ai_batteries = -1; /* Unknown */
+ aip->ai_capabilities = 0xff00; /* Unknown, with no bits set */
+ } else {
+ aip->ai_batteries = ebx & 0xff;
+ aip->ai_capabilities = ecx & 0xf;
+ }
+
bzero(aip->ai_spare, sizeof aip->ai_spare);
return 0;
@@ -719,16 +732,16 @@ apm_processevent(void)
apm_event = apm_getevent();
switch (apm_event) {
OPMEV_DEBUGMESSAGE(PMEV_STANDBYREQ);
- apm_suspend();
+ apm_suspend(PMST_STANDBY);
break;
OPMEV_DEBUGMESSAGE(PMEV_SUSPENDREQ);
- apm_suspend();
+ apm_suspend(PMST_SUSPEND);
break;
OPMEV_DEBUGMESSAGE(PMEV_USERSUSPENDREQ);
- apm_suspend();
+ apm_suspend(PMST_SUSPEND);
break;
OPMEV_DEBUGMESSAGE(PMEV_CRITSUSPEND);
- apm_suspend();
+ apm_suspend(PMST_SUSPEND);
break;
OPMEV_DEBUGMESSAGE(PMEV_NORMRESUME);
apm_resume();
@@ -741,7 +754,7 @@ apm_processevent(void)
break;
OPMEV_DEBUGMESSAGE(PMEV_BATTERYLOW);
apm_battery_low();
- apm_suspend();
+ apm_suspend(PMST_SUSPEND);
break;
OPMEV_DEBUGMESSAGE(PMEV_POWERSTATECHANGE);
break;
@@ -930,11 +943,19 @@ apmioctl(dev_t dev, u_long cmd, caddr_t addr, int flag, struct proc *p)
#endif
switch (cmd) {
case APMIO_SUSPEND:
- if ( sc->active)
- apm_suspend();
+ if (sc->active)
+ apm_suspend(PMST_SUSPEND);
+ else
+ error = EINVAL;
+ break;
+
+ case APMIO_STANDBY:
+ if (sc->active)
+ apm_suspend(PMST_STANDBY);
else
error = EINVAL;
break;
+
case APMIO_GETINFO_OLD:
{
struct apm_info info;
@@ -973,8 +994,8 @@ apmioctl(dev_t dev, u_long cmd, caddr_t addr, int flag, struct proc *p)
error = ENXIO;
break;
case APMIO_BIOS:
- if (apm_bios_call((struct apm_bios_arg*)addr))
- error = EIO;
+ if (apm_bios_call((struct apm_bios_arg*)addr) == 0)
+ ((struct apm_bios_arg*)addr)->eax &= 0xff;
break;
default:
error = EINVAL;
diff --git a/sys/i386/bios/apm.c b/sys/i386/bios/apm.c
index 89e127f..7018f1d 100644
--- a/sys/i386/bios/apm.c
+++ b/sys/i386/bios/apm.c
@@ -15,7 +15,7 @@
*
* Sep, 1994 Implemented on FreeBSD 1.1.5.1R (Toshiba AVS001WD)
*
- * $Id: apm.c,v 1.71 1998/06/03 01:59:32 msmith Exp $
+ * $Id: apm.c,v 1.72 1998/06/07 17:09:55 dfr Exp $
*/
#include "opt_devfs.h"
@@ -202,13 +202,13 @@ apm_getevent(void)
/* suspend entire system */
static int
-apm_suspend_system(void)
+apm_suspend_system(int state)
{
u_long eax, ebx, ecx, edx;
eax = (APM_BIOS << 8) | APM_SETPWSTATE;
ebx = PMDV_ALLDEV;
- ecx = PMST_SUSPEND;
+ ecx = state;
edx = 0;
if (apm_int(&eax, &ebx, &ecx, &edx)) {
@@ -427,7 +427,7 @@ static void apm_processevent(void);
*/
void
-apm_suspend(void)
+apm_suspend(int state)
{
struct apm_softc *sc = &apm_softc;
@@ -436,7 +436,7 @@ apm_suspend(void)
if (sc->initialized) {
apm_execute_hook(hook[APM_HOOK_SUSPEND]);
- if (apm_suspend_system() == 0)
+ if (apm_suspend_system(state) == 0)
apm_processevent();
else
/* Failure, 'resume' the system again */
@@ -472,7 +472,7 @@ apm_get_info(apm_info_t aip)
if (apm_int(&eax, &ebx, &ecx, &edx))
return 1;
- aip->ai_infoversion = 0;
+ aip->ai_infoversion = 1;
aip->ai_acline = (ebx >> 8) & 0xff;
aip->ai_batt_stat = ebx & 0xff;
aip->ai_batt_life = ecx & 0xff;
@@ -486,6 +486,19 @@ apm_get_info(apm_info_t aip)
aip->ai_batt_time = (edx & 0x7fff) * 60;
else /* Time is in seconds */
aip->ai_batt_time = edx;
+
+ eax = (APM_BIOS << 8) | APM_GETCAPABILITIES;
+ ebx = 0;
+ ecx = 0;
+ edx = 0;
+ if (apm_int(&eax, &ebx, &ecx, &edx)) {
+ aip->ai_batteries = -1; /* Unknown */
+ aip->ai_capabilities = 0xff00; /* Unknown, with no bits set */
+ } else {
+ aip->ai_batteries = ebx & 0xff;
+ aip->ai_capabilities = ecx & 0xf;
+ }
+
bzero(aip->ai_spare, sizeof aip->ai_spare);
return 0;
@@ -719,16 +732,16 @@ apm_processevent(void)
apm_event = apm_getevent();
switch (apm_event) {
OPMEV_DEBUGMESSAGE(PMEV_STANDBYREQ);
- apm_suspend();
+ apm_suspend(PMST_STANDBY);
break;
OPMEV_DEBUGMESSAGE(PMEV_SUSPENDREQ);
- apm_suspend();
+ apm_suspend(PMST_SUSPEND);
break;
OPMEV_DEBUGMESSAGE(PMEV_USERSUSPENDREQ);
- apm_suspend();
+ apm_suspend(PMST_SUSPEND);
break;
OPMEV_DEBUGMESSAGE(PMEV_CRITSUSPEND);
- apm_suspend();
+ apm_suspend(PMST_SUSPEND);
break;
OPMEV_DEBUGMESSAGE(PMEV_NORMRESUME);
apm_resume();
@@ -741,7 +754,7 @@ apm_processevent(void)
break;
OPMEV_DEBUGMESSAGE(PMEV_BATTERYLOW);
apm_battery_low();
- apm_suspend();
+ apm_suspend(PMST_SUSPEND);
break;
OPMEV_DEBUGMESSAGE(PMEV_POWERSTATECHANGE);
break;
@@ -930,11 +943,19 @@ apmioctl(dev_t dev, u_long cmd, caddr_t addr, int flag, struct proc *p)
#endif
switch (cmd) {
case APMIO_SUSPEND:
- if ( sc->active)
- apm_suspend();
+ if (sc->active)
+ apm_suspend(PMST_SUSPEND);
+ else
+ error = EINVAL;
+ break;
+
+ case APMIO_STANDBY:
+ if (sc->active)
+ apm_suspend(PMST_STANDBY);
else
error = EINVAL;
break;
+
case APMIO_GETINFO_OLD:
{
struct apm_info info;
@@ -973,8 +994,8 @@ apmioctl(dev_t dev, u_long cmd, caddr_t addr, int flag, struct proc *p)
error = ENXIO;
break;
case APMIO_BIOS:
- if (apm_bios_call((struct apm_bios_arg*)addr))
- error = EIO;
+ if (apm_bios_call((struct apm_bios_arg*)addr) == 0)
+ ((struct apm_bios_arg*)addr)->eax &= 0xff;
break;
default:
error = EINVAL;
diff --git a/sys/i386/include/apm_bios.h b/sys/i386/include/apm_bios.h
index 9ea25d1..616e36a 100644
--- a/sys/i386/include/apm_bios.h
+++ b/sys/i386/include/apm_bios.h
@@ -12,7 +12,7 @@
*
* Aug, 1994 Implemented on FreeBSD 1.1.5.1R (Toshiba AVS001WD)
*
- * $Id: apm_bios.h,v 1.18 1997/06/15 02:02:53 wollman Exp $
+ * $Id: apm_bios.h,v 1.19 1997/11/12 04:12:51 jdp Exp $
*/
#ifndef _MACHINE_APM_BIOS_H_
@@ -23,8 +23,6 @@
#endif
#include <sys/ioccom.h>
-#ifdef KERNEL
-
/* BIOS id */
#ifdef PC98
#define APM_BIOS 0x9a
@@ -74,6 +72,10 @@
#define APM_DRVVERSION 0x0e
#endif
#define APM_ENGAGEDISENGAGEPM 0x0f
+#define APM_GETCAPABILITIES 0x10
+#define APM_RESUMETIMER 0x11
+#define APM_RESUMEONRING 0x12
+#define APM_TIMERREQUESTS 0x13
#define APM_OEMFUNC 0x80
/* error code */
@@ -151,21 +153,23 @@ struct apmhook {
#define APM_HOOK_RESUME 1
#define NAPM_HOOK 2
-void apm_suspend(void);
+#ifdef KERNEL
+
+void apm_suspend(int state);
struct apmhook *apm_hook_establish (int apmh, struct apmhook *);
void apm_hook_disestablish (int apmh, struct apmhook *);
void apm_cpu_idle(void);
void apm_cpu_busy(void);
void apm_power_off(void);
+#endif /* KERNEL */
+
#endif /* !ASSEMBLER && !INITIALIZER */
#define APM_MIN_ORDER 0x00
#define APM_MID_ORDER 0x80
#define APM_MAX_ORDER 0xff
-#endif /* KERNEL */
-
/* power management event code */
#define PMEV_NOEVENT 0x0000
#define PMEV_STANDBYREQ 0x0001
@@ -179,7 +183,8 @@ void apm_power_off(void);
#define PMEV_USERSTANDBYREQ 0x0009
#define PMEV_USERSUSPENDREQ 0x000a
#define PMEV_STANDBYRESUME 0x000b
-/* 0x000c - 0x00ff Reserved system events */
+#define PMEV_CAPABILITIESCHANGE 0x000c
+/* 0x000d - 0x00ff Reserved system events */
/* 0x0100 - 0x01ff Reserved device events */
/* 0x0200 - 0x02ff OEM-defined APM events */
/* 0x0300 - 0xffff Reserved */
@@ -215,7 +220,9 @@ typedef struct apm_info {
u_int ai_batt_life; /* Remaining battery life in percent (0) */
int ai_batt_time; /* Remaining battery time in seconds (0) */
u_int ai_status; /* True if enabled (0) */
- u_int ai_spare[8]; /* For future expansion */
+ u_int ai_batteries; /* Number of batteries (1) */
+ u_int ai_capabilities;/* APM Capabilities (1) */
+ u_int ai_spare[6]; /* For future expansion */
} *apm_info_t;
struct apm_bios_arg {
@@ -236,6 +243,7 @@ struct apm_bios_arg {
#define APMIO_DISPLAY _IOW('P', 9, int)
#define APMIO_BIOS _IOWR('P', 10, struct apm_bios_arg)
#define APMIO_GETINFO _IOR('P', 11, struct apm_info)
+#define APMIO_STANDBY _IO('P', 12)
#endif /* !ASSEMBLER && !INITIALIZER */
diff --git a/sys/i386/include/console.h b/sys/i386/include/console.h
index 2d05be0..9406441 100644
--- a/sys/i386/include/console.h
+++ b/sys/i386/include/console.h
@@ -25,7 +25,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * $Id: console.h,v 1.35 1998/02/03 19:57:45 bde Exp $
+ * $Id: console.h,v 1.36 1998/02/12 20:47:39 phk Exp $
*/
#ifndef _MACHINE_CONSOLE_H_
@@ -313,6 +313,8 @@ typedef struct ssaver ssaver_t;
#define DCAR 0x97 /* caron */
#define L_ACC DCAR /* last accent key */
+#define STBY 0x98 /* Go into standby mode (apm) */
+
#define F(x) ((x)+F_FN-1)
#define S(x) ((x)+F_SCR-1)
#define ACC(x) ((x)+F_ACC)
diff --git a/sys/i386/isa/syscons.c b/sys/i386/isa/syscons.c
index de7e370..8f11058 100644
--- a/sys/i386/isa/syscons.c
+++ b/sys/i386/isa/syscons.c
@@ -25,7 +25,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * $Id: syscons.c,v 1.263 1998/06/13 18:53:22 steve Exp $
+ * $Id: syscons.c,v 1.264 1998/06/24 10:21:30 yokota Exp $
*/
#include "sc.h"
@@ -528,6 +528,7 @@ sckbdprobe(int unit, int flags)
int codeset;
int c = -1;
int m;
+ int res, id;
sc_kbdc = kbdc_open(sc_port);
@@ -664,6 +665,17 @@ sckbdprobe(int unit, int flags)
printf("sc%d: unable to enable the keyboard port and intr.\n", unit);
goto fail;
}
+
+ /* Get the ID of the keyboard, if any */
+ empty_kbd_buffer(sc_kbdc, 5);
+ res = send_kbd_command(sc_kbdc, KBDC_SEND_DEV_ID);
+ if (res == KBD_ACK) {
+ /* 10ms delay */
+ DELAY(10000);
+ id = (read_kbd_data(sc_kbdc) << 8) | read_kbd_data(sc_kbdc);
+ if (bootverbose)
+ printf("sc%d: keyboard device ID: %04x\n", unit, id);
+ }
kbdc_set_device_mask(sc_kbdc, m | KBD_KBD_CONTROL_BITS),
kbdc_lock(sc_kbdc, FALSE);
@@ -3980,7 +3992,14 @@ next_code:
case SUSP:
#if NAPM > 0
accents = 0;
- apm_suspend();
+ apm_suspend(PMST_SUSPEND);
+#endif
+ break;
+
+ case STBY:
+#if NAPM > 0
+ accents = 0;
+ apm_suspend(PMST_STANDBY);
#endif
break;
diff --git a/sys/isa/syscons.c b/sys/isa/syscons.c
index de7e370..8f11058 100644
--- a/sys/isa/syscons.c
+++ b/sys/isa/syscons.c
@@ -25,7 +25,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * $Id: syscons.c,v 1.263 1998/06/13 18:53:22 steve Exp $
+ * $Id: syscons.c,v 1.264 1998/06/24 10:21:30 yokota Exp $
*/
#include "sc.h"
@@ -528,6 +528,7 @@ sckbdprobe(int unit, int flags)
int codeset;
int c = -1;
int m;
+ int res, id;
sc_kbdc = kbdc_open(sc_port);
@@ -664,6 +665,17 @@ sckbdprobe(int unit, int flags)
printf("sc%d: unable to enable the keyboard port and intr.\n", unit);
goto fail;
}
+
+ /* Get the ID of the keyboard, if any */
+ empty_kbd_buffer(sc_kbdc, 5);
+ res = send_kbd_command(sc_kbdc, KBDC_SEND_DEV_ID);
+ if (res == KBD_ACK) {
+ /* 10ms delay */
+ DELAY(10000);
+ id = (read_kbd_data(sc_kbdc) << 8) | read_kbd_data(sc_kbdc);
+ if (bootverbose)
+ printf("sc%d: keyboard device ID: %04x\n", unit, id);
+ }
kbdc_set_device_mask(sc_kbdc, m | KBD_KBD_CONTROL_BITS),
kbdc_lock(sc_kbdc, FALSE);
@@ -3980,7 +3992,14 @@ next_code:
case SUSP:
#if NAPM > 0
accents = 0;
- apm_suspend();
+ apm_suspend(PMST_SUSPEND);
+#endif
+ break;
+
+ case STBY:
+#if NAPM > 0
+ accents = 0;
+ apm_suspend(PMST_STANDBY);
#endif
break;
OpenPOWER on IntegriCloud