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>
next in thread | previous in thread | raw e-mail | index | archive | help
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
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199908100826.RAA01149>