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.
This commit is contained in:
Warner Losh 1998-07-06 06:29:07 +00:00
parent 1f7e052c16
commit f71f5262b1
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=37414
8 changed files with 157 additions and 46 deletions

View File

@ -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)

View File

@ -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 @@ scgetc(u_int flags)
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;

View File

@ -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;

View File

@ -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;

View File

@ -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 */

View File

@ -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)

View File

@ -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 @@ scgetc(u_int flags)
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;

View File

@ -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 @@ scgetc(u_int flags)
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;