Date: Tue, 10 Aug 1999 17:30:30 +0900 From: Mitsuru IWASAKI <iwasaki@jp.FreeBSD.org> To: sanpei@sanpei.org Cc: mobile@freebsd.org, iwasaki@jp.FreeBSD.org Subject: Re: [APM] kernel panic with apm command(Sotec WinBookPro). Message-ID: <199908100826.RAA01149@tasogare.imasy.or.jp> In-Reply-To: Your message of "Tue, 10 Aug 1999 01:02:23 %2B0900" <199908091602.BAA01757@lavender.yy.cs.keio.ac.jp> References: <199908091602.BAA01757@lavender.yy.cs.keio.ac.jp>
index | next in thread | previous in thread | raw e-mail
Hi,
I made new patch, please try this one.
sanpei> I applied Iwasaki-san's patch to my sys/i386/apm/apm.c.
sanpei>
sanpei> And I execute apm, kernel does not panic. But I think
sanpei> /usr/sbin/apm needs some additional code(?).
Maybe yes. It should continue here even getting error from BIOS call,
I think. How about this?
--- apm.c.org Tue Aug 10 11:08:01 1999
+++ apm.c Tue Aug 10 12:16:48 1999
@@ -165,7 +165,7 @@
args.ebx = PMDV_APMBIOS;
args.ecx = 0x0001;
if (ioctl(fd, APMIO_BIOS, &args)) {
- err(1,"Get resume timer");
+ printf("Resume timer: unkown\n");
} else {
apmerr = APMERR(args.eax);
if (apmerr == 0x0d || apmerr == 0x86)
sanpei> >> apm: found APM BIOS v1.1, connected at v1.0
sanpei> >
sanpei> >Odd. Why it connected at v1.0???
sanpei>
sanpei> I added some debug code.
sanpei> I think my NOTE-PC has buggy BIOS. If it call ``APM_DRVVERSION'',
sanpei> BIOS return 0x530e of APM driver version, not 0x010x(1.0?). 0x530e
sanpei> is eax value for APM_DRVVERSION...... BIOS of MY NOTE-PC does not
sanpei> recognize DRVVERSION CALL.........
Ahhh, I heard this problem from you before :)
0x530e is ((APM_BIOS << 8) | APM_DRVVERSION), that mean your BIOS
didn't touch %ax at all. Attached patch includes this fix.
sanpei> @@ -1176,7 +1182,7 @@
sanpei> sc->bios.r.edi = args->edi;
sanpei> if ((ret = apm_bioscall())) {
sanpei> if (ret == -1) {
sanpei> - error = ENOSYS;
sanpei> + error = EINVAL;
sanpei> } else {
sanpei> sc->bios.r.eax &= 0xff;
sanpei> }
Ummm, I found another bug in here. We can discard %ah only in case of
success, right?
--- apm.c.org Tue Aug 10 12:35:01 1999
+++ apm.c Tue Aug 10 16:19:07 1999
@@ -50,6 +50,7 @@
static int apm_display __P((int newstate));
static void apm_resume __P((void));
static int apm_bioscall(void);
+static int apm_check_function_supported __P((u_int version, u_int func));
static u_long apm_version;
@@ -132,6 +133,15 @@
{
struct apm_softc *sc = &apm_softc;
int errno = 0;
+ 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
+ return (-1);
+ }
sc->bios_busy = 1;
if (sc->connectmode == APM_PROT32CONNECT) {
@@ -146,6 +156,34 @@
return (errno);
}
+/* check whether APM function is supported (1) or not (0). */
+static int
+apm_check_function_supported(u_int version, u_int func)
+{
+ /* except driver version */
+ if (func == APM_DRVVERSION) {
+ return (1);
+ }
+
+ switch (version) {
+ case INTVERSION(1, 0):
+ if (func > APM_GETPMEVENT) {
+ return (0); /* not supported */
+ }
+ break;
+ case INTVERSION(1, 1):
+ if (func > APM_ENGAGEDISENGAGEPM &&
+ func < APM_OEMFUNC) {
+ return (0); /* not supported */
+ }
+ break;
+ case INTVERSION(1, 2):
+ break;
+ }
+
+ return (1); /* supported */
+}
+
/* enable/disable power management */
static int
apm_enable_disable_pm(int enable)
@@ -176,6 +214,11 @@
if (apm_bioscall() == 0 && sc->bios.r.eax == version)
return (0);
+
+ /* Some old BIOSes don't return the connection version in %ax. */
+ if (sc->bios.r.eax == ((APM_BIOS << 8) | APM_DRVVERSION))
+ return (0);
+
return (1);
}
@@ -1067,6 +1110,7 @@
struct apm_softc *sc = &apm_softc;
struct apm_bios_arg *args;
int error = 0;
+ int ret;
int newstate;
if (!sc->initialized)
@@ -1135,8 +1179,23 @@
sc->bios.r.edx = args->edx;
sc->bios.r.esi = args->esi;
sc->bios.r.edi = args->edi;
- if (apm_bioscall())
+ if ((ret = apm_bioscall())) {
+ /*
+ * Return code 1 means bios call was unsuccessful.
+ * Error code is stored in %ah.
+ * Return code -1 means bios call was unsupported
+ * in the APM BIOS version.
+ */
+ if (ret == -1) {
+ error = EINVAL;
+ }
+ } else {
+ /*
+ * Return code 0 means bios call was successful.
+ * We need only %al and can discard %ah.
+ */
sc->bios.r.eax &= 0xff;
+ }
args->eax = sc->bios.r.eax;
args->ebx = sc->bios.r.ebx;
args->ecx = sc->bios.r.ecx;
To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-mobile" in the body of the message
help
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199908100826.RAA01149>
