Sanitize APM a bit. Convert various #ifdef to id_flags instead.

You may want to add "flags 0x31" to apm0 if you have a lousy
implementation.  Read LINT.
This commit is contained in:
Poul-Henning Kamp 1997-03-29 11:07:12 +00:00
parent 958a83b970
commit 3d4d8fe94d
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=24372
12 changed files with 191 additions and 123 deletions

View File

@ -11,7 +11,7 @@
# device lines is present in the ./LINT configuration file. If you are
# in doubt as to the purpose or necessity of a line, check first in LINT.
#
# $Id: GENERIC,v 1.87 1997/03/12 19:59:58 se Exp $
# $Id: GENERIC,v 1.88 1997/03/13 19:03:58 bde Exp $
machine "i386"
cpu "I386_CPU"
@ -107,8 +107,8 @@ device npx0 at isa? port "IO_NPX" irq 13 vector npxintr
#
# Laptop support (see LINT for more options)
#
device apm0 at isa? disable # Advanced Power Management
options APM_BROKEN_STATCLOCK # Workaround some buggy APM BIOS
device apm0 at isa? disable flags 0x31 # Advanced Power Management
# PCCARD (PCMCIA) support
#controller crd0
#device pcic0 at crd?

View File

@ -2,7 +2,7 @@
# LINT -- config file for checking all the sources, tries to pull in
# as much of the source tree as it can.
#
# $Id: LINT,v 1.323 1997/03/26 17:20:24 ache Exp $
# $Id: LINT,v 1.324 1997/03/26 17:46:03 ache Exp $
#
# NB: You probably don't want to try running a kernel built from this
# file. Instead, you should start from GENERIC, and add options from
@ -881,14 +881,11 @@ device pca0 at isa? port IO_TIMER1 tty
#
# Notes on APM
# Some APM implementations will not work with the `statistics clock'
# enabled, so it's disabled by default if the APM driver is enabled.
# However, this is not true for all laptops. Try removing the option
# APM_BROKEN_STATCLOCK and see if suspend/resume work
# The flags takes the following meaning for apm0:
# 0x0020 Statclock is broken.
# 0x0011 Limit APM protocol to 1.1 or 1.0
# 0x0010 Limit APM protocol to 1.0
#
options APM_IDLE_CPU # Tell APM to idle rather than halt'ing the cpu
#
# Notes on the spigot:
# The video spigot is at 0xad6. This port address can not be changed.
@ -939,8 +936,7 @@ device wt0 at isa? port 0x300 bio irq 5 drq 1 vector wtintr
device ctx0 at isa? port 0x230 iomem 0xd0000
device spigot0 at isa? port 0xad6 irq 15 iomem 0xee000 vector spigintr
device qcam0 at isa? port "IO_LPT3" tty
device apm0 at isa?
options APM_BROKEN_STATCLOCK
device apm0 at isa?
device gp0 at isa? port 0x2c0 tty
device gsc0 at isa? port "IO_GSC1" tty drq 3
device joy0 at isa? port "IO_GAME"

View File

@ -4,6 +4,7 @@
* Copyright (c) 1994 UKAI, Fumitoshi.
* Copyright (c) 1994-1995 by HOSOKAWA, Tatsumi <hosokawa@jp.FreeBSD.org>
* Copyright (c) 1996 Nate Williams <nate@FreeBSD.org>
* Copyright (c) 1997 Poul-Henning Kamp <phk@FreeBSD.org>
*
* This software may be used, modified, copied, and distributed, in
* both source and binary form provided that the above copyright and
@ -14,7 +15,7 @@
*
* Sep, 1994 Implemented on FreeBSD 1.1.5.1R (Toshiba AVS001WD)
*
* $Id: apm.c,v 1.53 1997/02/22 09:29:49 peter Exp $
* $Id: apm.c,v 1.54 1997/03/28 18:38:19 phk Exp $
*/
#include <sys/param.h>
@ -98,32 +99,26 @@ setup_apm_gdt(u_int code32_base, u_int code16_base, u_int data_base, u_int code_
}
/* 48bit far pointer */
static struct addr48 {
struct addr48 {
u_long offset;
u_short segment;
} apm_addr;
static int apm_errno;
inline
int
apm_int(u_long *eax, u_long *ebx, u_long *ecx)
{
u_long cf;
__asm __volatile("
pushfl
cli
lcall _apm_addr
movl $0, %3
jnc 1f
incl %3
1:
popfl
"
: "=a" (*eax), "=b" (*ebx), "=c" (*ecx), "=D" (cf)
: "0" (*eax), "1" (*ebx), "2" (*ecx)
: "dx", "si", "memory"
);
struct apm_bios_arg apa;
int cf;
apa.eax = *eax;
apa.ebx = *ebx;
apa.ecx = *ecx;
cf = apm_bios_call(&apa);
*eax = apa.eax;
*ebx = apa.ebx;
*ecx = apa.ecx;
apm_errno = ((*eax) >> 8) & 0xff;
return cf;
}
@ -147,21 +142,16 @@ apm_enable_disable_pm(int enable)
return apm_int(&eax, &ebx, &ecx);
}
/* Tell APM-BIOS that WE will do 1.2 and see what they say... */
static void
apm_driver_version(void)
apm_driver_version(int version)
{
u_long eax, ebx, ecx;
/* First try APM 1.2 */
eax = (APM_BIOS << 8) | APM_DRVVERSION;
ebx = 0x0;
/* First try APM 1.2 */
ecx = 0x0102;
if(!apm_int(&eax, &ebx, &ecx))
apm_version = eax & 0xffff;
/* Then try APM 1.1 */
ecx = 0x0101;
if(!apm_int(&eax, &ebx, &ecx))
ecx = version;
if(!apm_int(&eax, &ebx, &ecx))
apm_version = eax & 0xffff;
}
@ -583,9 +573,8 @@ apmprobe(struct isa_device *dvp)
printf("apm: 32-bit connection error.\n");
return 0;
}
#ifdef APM_BROKEN_STATCLOCK
statclock_disable = 1;
#endif
if (dvp->id_flags & 0x20)
statclock_disable = 1;
return -1;
}
@ -635,7 +624,7 @@ apm_processevent(void)
OPMEV_DEBUGMESSAGE(PMEV_UPDATETIME);
inittodr(0); /* adjust time to RTC */
break;
OPMEV_DEBUGMESSAGE(PMEV_NOEVENT);
case PMEV_NOEVENT:
break;
default:
printf("Unknown Original APM Event 0x%x\n", apm_event);
@ -702,15 +691,21 @@ apmattach(struct isa_device *dvp)
apm_addr.segment = GSEL(GAPMCODE32_SEL, SEL_KPL);
apm_addr.offset = sc->cs_entry;
#ifdef FORCE_APM10
apm_version = 0x100;
sc->majorversion = 1;
sc->minorversion = 0;
sc->intversion = INTVERSION(sc->majorversion, sc->minorversion);
printf("apm: running in APM 1.0 compatible mode\n");
#else
/* Try to kick bios into 1.1 or greater mode */
apm_driver_version();
if ((dvp->id_flags & 0x10)) {
if ((dvp->id_flags & 0xf) => 0x2) {
apm_driver_version(0x102);
}
if (!apm_version && (dvp->id_flags & 0xf) => 0x1) {
apm_driver_version(0x101);
}
} else {
apm_driver_version(0x102);
if (!apm_version)
apm_driver_version(0x101);
}
if (!apm_version)
apm_version = 0x100;
sc->minorversion = ((apm_version & 0x00f0) >> 4) * 10 +
((apm_version & 0x000f) >> 0);
sc->majorversion = ((apm_version & 0xf000) >> 12) * 10 +
@ -725,7 +720,6 @@ apmattach(struct isa_device *dvp)
printf("apm: found APM BIOS version %d.%d\n",
sc->majorversion, sc->minorversion);
#endif /* FORCE_APM10 */
#ifdef APM_DEBUG
printf("apm: Slow Idling CPU %s\n", is_enabled(sc->slow_idle_cpu));
@ -835,6 +829,10 @@ apmioctl(dev_t dev, int cmd, caddr_t addr, int flag, struct proc *p)
if (apm_display(newstate))
error = ENXIO;
break;
case APMIO_BIOS:
if (apm_bios_call((struct apm_bios_arg*)addr))
error = EIO;
break;
default:
error = EINVAL;
break;

View File

@ -10,7 +10,7 @@
*
* Sep., 1994 Implemented on FreeBSD 1.1.5.1R (Toshiba AVS001WD)
*
* $Id$
* $Id: apm_setup.h,v 1.7 1997/02/22 09:29:49 peter Exp $
*/
extern u_long apm_version;
@ -22,3 +22,5 @@ extern u_short apm_cs_limit;
extern u_short apm_ds_limit;
extern u_short apm_flags;
extern u_short kernelbase;
int apm_bios_call __P((struct apm_bios_arg *));

View File

@ -1,5 +1,6 @@
/*
* Copyright (C) 1994 by HOSOKAWA, Tatsumi <hosokawa@jp.FreeBSD.org>
* Copyright (C) 1997 by Poul-Henning Kamp <phk@FreeBSD.org>
*
* This software may be used, modified, copied, distributed, and sold,
* in both source and binary form provided that the above copyright and
@ -10,7 +11,7 @@
*
* Sep., 1994 Implemented on FreeBSD 1.1.5.1R (Toshiba AVS001WD)
*
* $Id$
* $Id: apm_setup.s,v 1.10 1997/02/22 09:29:50 peter Exp $
*/
#include "apm.h"
@ -174,4 +175,38 @@ _apm_setup:
movw %di, PADDR(_apm_flags)
ret
.text
.align 2
.globl _apm_bios_call
_apm_bios_call:
pushl %ebp
movl 8(%esp),%ebp
pushl %esi
pushl %edi
pushl %ebx
movl 20(%ebp),%edi
movl 16(%ebp),%esi
movl 12(%ebp),%edx
movl 8(%ebp),%ecx
movl 4(%ebp),%ebx
movl 0(%ebp),%eax
pushl %ebp
lcall _apm_addr
popl %ebp
movl %eax,0(%ebp)
jc 1f
xorl %eax,%eax
jz 2f
1: movl $1, %eax
2: movl %ebx,4(%ebp)
movl %ecx,8(%ebp)
movl %edx,12(%ebp)
movl %esi,16(%ebp)
movl %edi,20(%ebp)
popl %ebx
popl %edi
popl %esi
popl %ebp
ret
#endif NAPM > 0

View File

@ -4,6 +4,7 @@
* Copyright (c) 1994 UKAI, Fumitoshi.
* Copyright (c) 1994-1995 by HOSOKAWA, Tatsumi <hosokawa@jp.FreeBSD.org>
* Copyright (c) 1996 Nate Williams <nate@FreeBSD.org>
* Copyright (c) 1997 Poul-Henning Kamp <phk@FreeBSD.org>
*
* This software may be used, modified, copied, and distributed, in
* both source and binary form provided that the above copyright and
@ -14,7 +15,7 @@
*
* Sep, 1994 Implemented on FreeBSD 1.1.5.1R (Toshiba AVS001WD)
*
* $Id: apm.c,v 1.53 1997/02/22 09:29:49 peter Exp $
* $Id: apm.c,v 1.54 1997/03/28 18:38:19 phk Exp $
*/
#include <sys/param.h>
@ -98,32 +99,26 @@ setup_apm_gdt(u_int code32_base, u_int code16_base, u_int data_base, u_int code_
}
/* 48bit far pointer */
static struct addr48 {
struct addr48 {
u_long offset;
u_short segment;
} apm_addr;
static int apm_errno;
inline
int
apm_int(u_long *eax, u_long *ebx, u_long *ecx)
{
u_long cf;
__asm __volatile("
pushfl
cli
lcall _apm_addr
movl $0, %3
jnc 1f
incl %3
1:
popfl
"
: "=a" (*eax), "=b" (*ebx), "=c" (*ecx), "=D" (cf)
: "0" (*eax), "1" (*ebx), "2" (*ecx)
: "dx", "si", "memory"
);
struct apm_bios_arg apa;
int cf;
apa.eax = *eax;
apa.ebx = *ebx;
apa.ecx = *ecx;
cf = apm_bios_call(&apa);
*eax = apa.eax;
*ebx = apa.ebx;
*ecx = apa.ecx;
apm_errno = ((*eax) >> 8) & 0xff;
return cf;
}
@ -147,21 +142,16 @@ apm_enable_disable_pm(int enable)
return apm_int(&eax, &ebx, &ecx);
}
/* Tell APM-BIOS that WE will do 1.2 and see what they say... */
static void
apm_driver_version(void)
apm_driver_version(int version)
{
u_long eax, ebx, ecx;
/* First try APM 1.2 */
eax = (APM_BIOS << 8) | APM_DRVVERSION;
ebx = 0x0;
/* First try APM 1.2 */
ecx = 0x0102;
if(!apm_int(&eax, &ebx, &ecx))
apm_version = eax & 0xffff;
/* Then try APM 1.1 */
ecx = 0x0101;
if(!apm_int(&eax, &ebx, &ecx))
ecx = version;
if(!apm_int(&eax, &ebx, &ecx))
apm_version = eax & 0xffff;
}
@ -583,9 +573,8 @@ apmprobe(struct isa_device *dvp)
printf("apm: 32-bit connection error.\n");
return 0;
}
#ifdef APM_BROKEN_STATCLOCK
statclock_disable = 1;
#endif
if (dvp->id_flags & 0x20)
statclock_disable = 1;
return -1;
}
@ -635,7 +624,7 @@ apm_processevent(void)
OPMEV_DEBUGMESSAGE(PMEV_UPDATETIME);
inittodr(0); /* adjust time to RTC */
break;
OPMEV_DEBUGMESSAGE(PMEV_NOEVENT);
case PMEV_NOEVENT:
break;
default:
printf("Unknown Original APM Event 0x%x\n", apm_event);
@ -702,15 +691,21 @@ apmattach(struct isa_device *dvp)
apm_addr.segment = GSEL(GAPMCODE32_SEL, SEL_KPL);
apm_addr.offset = sc->cs_entry;
#ifdef FORCE_APM10
apm_version = 0x100;
sc->majorversion = 1;
sc->minorversion = 0;
sc->intversion = INTVERSION(sc->majorversion, sc->minorversion);
printf("apm: running in APM 1.0 compatible mode\n");
#else
/* Try to kick bios into 1.1 or greater mode */
apm_driver_version();
if ((dvp->id_flags & 0x10)) {
if ((dvp->id_flags & 0xf) => 0x2) {
apm_driver_version(0x102);
}
if (!apm_version && (dvp->id_flags & 0xf) => 0x1) {
apm_driver_version(0x101);
}
} else {
apm_driver_version(0x102);
if (!apm_version)
apm_driver_version(0x101);
}
if (!apm_version)
apm_version = 0x100;
sc->minorversion = ((apm_version & 0x00f0) >> 4) * 10 +
((apm_version & 0x000f) >> 0);
sc->majorversion = ((apm_version & 0xf000) >> 12) * 10 +
@ -725,7 +720,6 @@ apmattach(struct isa_device *dvp)
printf("apm: found APM BIOS version %d.%d\n",
sc->majorversion, sc->minorversion);
#endif /* FORCE_APM10 */
#ifdef APM_DEBUG
printf("apm: Slow Idling CPU %s\n", is_enabled(sc->slow_idle_cpu));
@ -835,6 +829,10 @@ apmioctl(dev_t dev, int cmd, caddr_t addr, int flag, struct proc *p)
if (apm_display(newstate))
error = ENXIO;
break;
case APMIO_BIOS:
if (apm_bios_call((struct apm_bios_arg*)addr))
error = EIO;
break;
default:
error = EINVAL;
break;

View File

@ -10,7 +10,7 @@
*
* Sep., 1994 Implemented on FreeBSD 1.1.5.1R (Toshiba AVS001WD)
*
* $Id$
* $Id: apm_setup.h,v 1.7 1997/02/22 09:29:49 peter Exp $
*/
extern u_long apm_version;
@ -22,3 +22,5 @@ extern u_short apm_cs_limit;
extern u_short apm_ds_limit;
extern u_short apm_flags;
extern u_short kernelbase;
int apm_bios_call __P((struct apm_bios_arg *));

View File

@ -1,5 +1,6 @@
/*
* Copyright (C) 1994 by HOSOKAWA, Tatsumi <hosokawa@jp.FreeBSD.org>
* Copyright (C) 1997 by Poul-Henning Kamp <phk@FreeBSD.org>
*
* This software may be used, modified, copied, distributed, and sold,
* in both source and binary form provided that the above copyright and
@ -10,7 +11,7 @@
*
* Sep., 1994 Implemented on FreeBSD 1.1.5.1R (Toshiba AVS001WD)
*
* $Id$
* $Id: apm_setup.s,v 1.10 1997/02/22 09:29:50 peter Exp $
*/
#include "apm.h"
@ -174,4 +175,38 @@ _apm_setup:
movw %di, PADDR(_apm_flags)
ret
.text
.align 2
.globl _apm_bios_call
_apm_bios_call:
pushl %ebp
movl 8(%esp),%ebp
pushl %esi
pushl %edi
pushl %ebx
movl 20(%ebp),%edi
movl 16(%ebp),%esi
movl 12(%ebp),%edx
movl 8(%ebp),%ecx
movl 4(%ebp),%ebx
movl 0(%ebp),%eax
pushl %ebp
lcall _apm_addr
popl %ebp
movl %eax,0(%ebp)
jc 1f
xorl %eax,%eax
jz 2f
1: movl $1, %eax
2: movl %ebx,4(%ebp)
movl %ecx,8(%ebp)
movl %edx,12(%ebp)
movl %esi,16(%ebp)
movl %edi,20(%ebp)
popl %ebx
popl %edi
popl %esi
popl %ebp
ret
#endif NAPM > 0

View File

@ -11,7 +11,7 @@
# device lines is present in the ./LINT configuration file. If you are
# in doubt as to the purpose or necessity of a line, check first in LINT.
#
# $Id: GENERIC,v 1.87 1997/03/12 19:59:58 se Exp $
# $Id: GENERIC,v 1.88 1997/03/13 19:03:58 bde Exp $
machine "i386"
cpu "I386_CPU"
@ -107,8 +107,8 @@ device npx0 at isa? port "IO_NPX" irq 13 vector npxintr
#
# Laptop support (see LINT for more options)
#
device apm0 at isa? disable # Advanced Power Management
options APM_BROKEN_STATCLOCK # Workaround some buggy APM BIOS
device apm0 at isa? disable flags 0x31 # Advanced Power Management
# PCCARD (PCMCIA) support
#controller crd0
#device pcic0 at crd?

View File

@ -2,7 +2,7 @@
# LINT -- config file for checking all the sources, tries to pull in
# as much of the source tree as it can.
#
# $Id: LINT,v 1.323 1997/03/26 17:20:24 ache Exp $
# $Id: LINT,v 1.324 1997/03/26 17:46:03 ache Exp $
#
# NB: You probably don't want to try running a kernel built from this
# file. Instead, you should start from GENERIC, and add options from
@ -881,14 +881,11 @@ device pca0 at isa? port IO_TIMER1 tty
#
# Notes on APM
# Some APM implementations will not work with the `statistics clock'
# enabled, so it's disabled by default if the APM driver is enabled.
# However, this is not true for all laptops. Try removing the option
# APM_BROKEN_STATCLOCK and see if suspend/resume work
# The flags takes the following meaning for apm0:
# 0x0020 Statclock is broken.
# 0x0011 Limit APM protocol to 1.1 or 1.0
# 0x0010 Limit APM protocol to 1.0
#
options APM_IDLE_CPU # Tell APM to idle rather than halt'ing the cpu
#
# Notes on the spigot:
# The video spigot is at 0xad6. This port address can not be changed.
@ -939,8 +936,7 @@ device wt0 at isa? port 0x300 bio irq 5 drq 1 vector wtintr
device ctx0 at isa? port 0x230 iomem 0xd0000
device spigot0 at isa? port 0xad6 irq 15 iomem 0xee000 vector spigintr
device qcam0 at isa? port "IO_LPT3" tty
device apm0 at isa?
options APM_BROKEN_STATCLOCK
device apm0 at isa?
device gp0 at isa? port 0x2c0 tty
device gsc0 at isa? port "IO_GSC1" tty drq 3
device joy0 at isa? port "IO_GAME"

View File

@ -2,7 +2,7 @@
# LINT -- config file for checking all the sources, tries to pull in
# as much of the source tree as it can.
#
# $Id: LINT,v 1.323 1997/03/26 17:20:24 ache Exp $
# $Id: LINT,v 1.324 1997/03/26 17:46:03 ache Exp $
#
# NB: You probably don't want to try running a kernel built from this
# file. Instead, you should start from GENERIC, and add options from
@ -881,14 +881,11 @@ device pca0 at isa? port IO_TIMER1 tty
#
# Notes on APM
# Some APM implementations will not work with the `statistics clock'
# enabled, so it's disabled by default if the APM driver is enabled.
# However, this is not true for all laptops. Try removing the option
# APM_BROKEN_STATCLOCK and see if suspend/resume work
# The flags takes the following meaning for apm0:
# 0x0020 Statclock is broken.
# 0x0011 Limit APM protocol to 1.1 or 1.0
# 0x0010 Limit APM protocol to 1.0
#
options APM_IDLE_CPU # Tell APM to idle rather than halt'ing the cpu
#
# Notes on the spigot:
# The video spigot is at 0xad6. This port address can not be changed.
@ -939,8 +936,7 @@ device wt0 at isa? port 0x300 bio irq 5 drq 1 vector wtintr
device ctx0 at isa? port 0x230 iomem 0xd0000
device spigot0 at isa? port 0xad6 irq 15 iomem 0xee000 vector spigintr
device qcam0 at isa? port "IO_LPT3" tty
device apm0 at isa?
options APM_BROKEN_STATCLOCK
device apm0 at isa?
device gp0 at isa? port 0x2c0 tty
device gsc0 at isa? port "IO_GSC1" tty drq 3
device joy0 at isa? port "IO_GAME"

View File

@ -12,7 +12,7 @@
*
* Aug, 1994 Implemented on FreeBSD 1.1.5.1R (Toshiba AVS001WD)
*
* $Id: apm_bios.h,v 1.15 1997/02/22 09:33:54 peter Exp $
* $Id: apm_bios.h,v 1.16 1997/03/09 16:40:13 kato Exp $
*/
#ifndef _MACHINE_APM_BIOS_H_
@ -195,6 +195,15 @@ typedef struct apm_info {
u_int ai_status; /* Status of APM support (enabled/disabled) */
} *apm_info_t;
struct apm_bios_arg {
u_long eax;
u_long ebx;
u_long ecx;
u_long edx;
u_long esi;
u_long edi;
};
#define APMIO_SUSPEND _IO('P', 1)
#define APMIO_GETINFO _IOR('P', 2, struct apm_info)
#define APMIO_ENABLE _IO('P', 5)
@ -202,6 +211,7 @@ typedef struct apm_info {
#define APMIO_HALTCPU _IO('P', 7)
#define APMIO_NOTHALTCPU _IO('P', 8)
#define APMIO_DISPLAY _IOW('P', 9, int)
#define APMIO_BIOS _IOWR('P', 10, struct apm_bios_arg)
#endif /* !ASSEMBLER && !INITIALIZER */