Index: sys/conf/Makefile.i386 =================================================================== RCS file: /usr/cvs/src/sys/conf/Makefile.i386,v retrieving revision 1.179.2.15 diff -u -r1.179.2.15 Makefile.i386 --- sys/conf/Makefile.i386 7 Aug 2002 16:31:53 -0000 1.179.2.15 +++ sys/conf/Makefile.i386 16 Oct 2002 19:43:59 -0000 @@ -47,6 +47,10 @@ INCLUDES+= -I/usr/include .endif +# This hack lets us use the Intel ACPICA code without spamming a new +# include path into 100+ source files. +INCLUDES+= -I$S/contrib/dev/acpica + # This hack lets us use the ipfilter code without spamming a new # include path into 100+ source files. INCLUDES+= -I$S/contrib/ipfilter Index: sys/conf/files =================================================================== RCS file: /usr/cvs/src/sys/conf/files,v retrieving revision 1.340.2.115 diff -u -r1.340.2.115 files --- sys/conf/files 1 Sep 2002 02:21:04 -0000 1.340.2.115 +++ sys/conf/files 16 Oct 2002 19:43:59 -0000 @@ -88,6 +88,123 @@ cam/scsi/scsi_ses.c optional ses cam/scsi/scsi_target.c optional targ cam/scsi/scsi_targ_bh.c optional targbh +contrib/dev/acpica/dbcmds.c optional acpica acpi_debug +contrib/dev/acpica/dbdisply.c optional acpica acpi_debug +contrib/dev/acpica/dbexec.c optional acpica acpi_debug +contrib/dev/acpica/dbfileio.c optional acpica acpi_debug +contrib/dev/acpica/dbhistry.c optional acpica acpi_debug +contrib/dev/acpica/dbinput.c optional acpica acpi_debug +contrib/dev/acpica/dbstats.c optional acpica acpi_debug +contrib/dev/acpica/dbutils.c optional acpica acpi_debug +contrib/dev/acpica/dbxface.c optional acpica acpi_debug +contrib/dev/acpica/dmbuffer.c optional acpica acpi_debug +contrib/dev/acpica/dmnames.c optional acpica acpi_debug +contrib/dev/acpica/dmopcode.c optional acpica acpi_debug +contrib/dev/acpica/dmresrc.c optional acpica acpi_debug +contrib/dev/acpica/dmresrcl.c optional acpica acpi_debug +contrib/dev/acpica/dmresrcs.c optional acpica acpi_debug +contrib/dev/acpica/dmutils.c optional acpica acpi_debug +contrib/dev/acpica/dmwalk.c optional acpica acpi_debug +contrib/dev/acpica/dsfield.c optional acpica +contrib/dev/acpica/dsmethod.c optional acpica +contrib/dev/acpica/dsmthdat.c optional acpica +contrib/dev/acpica/dsobject.c optional acpica +contrib/dev/acpica/dsopcode.c optional acpica +contrib/dev/acpica/dsutils.c optional acpica +contrib/dev/acpica/dswexec.c optional acpica +contrib/dev/acpica/dswload.c optional acpica +contrib/dev/acpica/dswscope.c optional acpica +contrib/dev/acpica/dswstate.c optional acpica +contrib/dev/acpica/evevent.c optional acpica +contrib/dev/acpica/evmisc.c optional acpica +contrib/dev/acpica/evregion.c optional acpica +contrib/dev/acpica/evrgnini.c optional acpica +contrib/dev/acpica/evsci.c optional acpica +contrib/dev/acpica/evxface.c optional acpica +contrib/dev/acpica/evxfevnt.c optional acpica +contrib/dev/acpica/evxfregn.c optional acpica +contrib/dev/acpica/exconfig.c optional acpica +contrib/dev/acpica/exconvrt.c optional acpica +contrib/dev/acpica/excreate.c optional acpica +contrib/dev/acpica/exdump.c optional acpica +contrib/dev/acpica/exfield.c optional acpica +contrib/dev/acpica/exfldio.c optional acpica +contrib/dev/acpica/exmisc.c optional acpica +contrib/dev/acpica/exmutex.c optional acpica +contrib/dev/acpica/exnames.c optional acpica +contrib/dev/acpica/exoparg1.c optional acpica +contrib/dev/acpica/exoparg2.c optional acpica +contrib/dev/acpica/exoparg3.c optional acpica +contrib/dev/acpica/exoparg6.c optional acpica +contrib/dev/acpica/exprep.c optional acpica +contrib/dev/acpica/exregion.c optional acpica +contrib/dev/acpica/exresnte.c optional acpica +contrib/dev/acpica/exresolv.c optional acpica +contrib/dev/acpica/exresop.c optional acpica +contrib/dev/acpica/exstore.c optional acpica +contrib/dev/acpica/exstoren.c optional acpica +contrib/dev/acpica/exstorob.c optional acpica +contrib/dev/acpica/exsystem.c optional acpica +contrib/dev/acpica/exutils.c optional acpica +contrib/dev/acpica/hwacpi.c optional acpica +contrib/dev/acpica/hwgpe.c optional acpica +contrib/dev/acpica/hwregs.c optional acpica +contrib/dev/acpica/hwsleep.c optional acpica +contrib/dev/acpica/hwtimer.c optional acpica +contrib/dev/acpica/nsaccess.c optional acpica +contrib/dev/acpica/nsalloc.c optional acpica +contrib/dev/acpica/nsdump.c optional acpica +contrib/dev/acpica/nseval.c optional acpica +contrib/dev/acpica/nsinit.c optional acpica +contrib/dev/acpica/nsload.c optional acpica +contrib/dev/acpica/nsnames.c optional acpica +contrib/dev/acpica/nsobject.c optional acpica +contrib/dev/acpica/nssearch.c optional acpica +contrib/dev/acpica/nsutils.c optional acpica +contrib/dev/acpica/nswalk.c optional acpica +contrib/dev/acpica/nsxfeval.c optional acpica +contrib/dev/acpica/nsxfname.c optional acpica +contrib/dev/acpica/nsxfobj.c optional acpica +contrib/dev/acpica/psargs.c optional acpica +contrib/dev/acpica/psfind.c optional acpica +contrib/dev/acpica/psopcode.c optional acpica +contrib/dev/acpica/psparse.c optional acpica +contrib/dev/acpica/psscope.c optional acpica +contrib/dev/acpica/pstree.c optional acpica +contrib/dev/acpica/psutils.c optional acpica +contrib/dev/acpica/pswalk.c optional acpica +contrib/dev/acpica/psxface.c optional acpica +contrib/dev/acpica/rsaddr.c optional acpica +contrib/dev/acpica/rscalc.c optional acpica +contrib/dev/acpica/rscreate.c optional acpica +contrib/dev/acpica/rsdump.c optional acpica +contrib/dev/acpica/rsio.c optional acpica +contrib/dev/acpica/rsirq.c optional acpica +contrib/dev/acpica/rslist.c optional acpica +contrib/dev/acpica/rsmemory.c optional acpica +contrib/dev/acpica/rsmisc.c optional acpica +contrib/dev/acpica/rsutils.c optional acpica +contrib/dev/acpica/rsxface.c optional acpica +contrib/dev/acpica/tbconvrt.c optional acpica +contrib/dev/acpica/tbget.c optional acpica +contrib/dev/acpica/tbgetall.c optional acpica +contrib/dev/acpica/tbinstal.c optional acpica +contrib/dev/acpica/tbrsdt.c optional acpica +contrib/dev/acpica/tbutils.c optional acpica +contrib/dev/acpica/tbxface.c optional acpica +contrib/dev/acpica/tbxfroot.c optional acpica +contrib/dev/acpica/utalloc.c optional acpica +contrib/dev/acpica/utclib.c optional acpica +contrib/dev/acpica/utcopy.c optional acpica +contrib/dev/acpica/utdebug.c optional acpica +contrib/dev/acpica/utdelete.c optional acpica +contrib/dev/acpica/uteval.c optional acpica +contrib/dev/acpica/utglobal.c optional acpica +contrib/dev/acpica/utinit.c optional acpica +contrib/dev/acpica/utmath.c optional acpica +contrib/dev/acpica/utmisc.c optional acpica +contrib/dev/acpica/utobject.c optional acpica +contrib/dev/acpica/utxface.c optional acpica contrib/ipfilter/netinet/fil.c optional ipfilter inet contrib/ipfilter/netinet/ip_auth.c optional ipfilter inet contrib/ipfilter/netinet/ip_fil.c optional ipfilter inet @@ -128,6 +245,28 @@ dev/aac/aac_disk.c optional aac dev/aac/aac_pci.c optional aac pci dev/aac/aac_cam.c optional aacp aac +dev/acpica/acpi.c optional acpica +dev/acpica/acpica_support.c optional acpica +dev/acpica/acpi_acad.c optional acpica +dev/acpica/acpi_battery.c optional acpica +dev/acpica/acpi_button.c optional acpica +dev/acpica/acpi_cmbat.c optional acpica +dev/acpica/acpi_cpu.c optional acpica +dev/acpica/acpi_ec.c optional acpica +dev/acpica/acpi_lid.c optional acpica +#dev/acpica/acpi_pcib.c optional acpica pci +dev/acpica/acpi_powerres.c optional acpica +dev/acpica/acpi_resource.c optional acpica +dev/acpica/acpi_thermal.c optional acpica +dev/acpica/acpi_timer.c optional acpica +dev/acpica/Osd/OsdDebug.c optional acpica +dev/acpica/Osd/OsdHardware.c optional acpica +dev/acpica/Osd/OsdInterrupt.c optional acpica +dev/acpica/Osd/OsdMemory.c optional acpica +dev/acpica/Osd/OsdSchedule.c optional acpica +dev/acpica/Osd/OsdStream.c optional acpica +dev/acpica/Osd/OsdSynch.c optional acpica +dev/acpica/Osd/OsdTable.c optional acpica dev/advansys/adv_eisa.c optional adv eisa dev/advansys/adv_pci.c optional adv pci dev/advansys/advansys.c optional adv @@ -628,6 +767,7 @@ kern/subr_mchain.c optional libmchain kern/subr_module.c standard kern/subr_param.c standard +kern/subr_power.c standard kern/subr_prf.c standard kern/subr_prof.c standard kern/subr_blist.c standard Index: sys/conf/files.i386 =================================================================== RCS file: /usr/cvs/src/sys/conf/files.i386,v retrieving revision 1.307.2.35 diff -u -r1.307.2.35 files.i386 --- sys/conf/files.i386 5 Oct 2002 18:31:47 -0000 1.307.2.35 +++ sys/conf/files.i386 16 Oct 2002 19:43:59 -0000 @@ -160,6 +160,15 @@ gnu/i386/fpemul/reg_u_sub.s optional gpl_math_emulate gnu/i386/fpemul/wm_shrx.s optional gpl_math_emulate gnu/i386/fpemul/wm_sqrt.s optional gpl_math_emulate +i386/acpica/OsdEnvironment.c optional acpica +i386/acpica/acpi_machdep.c optional acpica +i386/acpica/acpi_wakeup.c optional acpica +acpi_wakecode.h optional acpica \ + dependency "$S/i386/acpica/acpi_wakecode.S" \ + compile-with "${MAKE} -f $S/i386/acpica/Makefile MAKESRCPATH=$S/i386/acpica" \ + no-obj no-implicit-rule before-depend \ + clean "acpi_wakecode.h acpi_wakecode.o acpi_wakecode.bin" +# gnu/i386/isa/dgb.c optional dgb gnu/i386/isa/sound/awe_wave.c optional awe i386/apm/apm.c optional apm @@ -268,6 +277,7 @@ i386/isa/pcvt/pcvt_out.c optional vt i386/isa/pcvt/pcvt_sup.c optional vt i386/isa/pcvt/pcvt_vtf.c optional vt +i386/isa/pmtimer.c optional pmtimer i386/isa/prof_machdep.c optional profiling-routine i386/isa/rc.c optional rc i386/isa/rp.c optional rp Index: sys/conf/options =================================================================== RCS file: /usr/cvs/src/sys/conf/options,v retrieving revision 1.191.2.44 diff -u -r1.191.2.44 options --- sys/conf/options 1 Sep 2002 07:18:21 -0000 1.191.2.44 +++ sys/conf/options 16 Oct 2002 19:43:59 -0000 @@ -73,6 +73,11 @@ ADW_ALLOW_MEMIO opt_adw.h # Allow PCI devices to use memory # mapped I/O +# options for ACPI support +ACPI_DEBUG opt_acpi.h +ACPI_NO_SEMAPHORES opt_acpi.h +ACPI_MAX_THREADS opt_acpi.h + # Miscellaneous options. COMPAT_43 opt_compat.h COMPAT_SUNOS opt_compat.h Index: sys/i386/apm/apm.c =================================================================== RCS file: /usr/cvs/src/sys/i386/apm/apm.c,v retrieving revision 1.114.2.3 diff -u -r1.114.2.3 apm.c --- sys/i386/apm/apm.c 12 Apr 2002 16:47:00 -0000 1.114.2.3 +++ sys/i386/apm/apm.c 16 Oct 2002 19:43:59 -0000 @@ -29,13 +29,14 @@ #include #include #include -#include #include #include #include +#include #include #include #include +#include #include #include #include @@ -54,6 +55,8 @@ static int apm_bioscall(void); static int apm_check_function_supported __P((u_int version, u_int func)); +static int apm_pm_func __P((u_long, void*, ...)); + static u_long apm_version; int apm_evindex; @@ -103,9 +106,17 @@ static int apm_suspend_delay = 1; static int apm_standby_delay = 1; +static int apm_debug = 0; + +#define APM_DPRINT(args...) do { \ + if (apm_debug) { \ + printf(args); \ + } \ +} while (0) SYSCTL_INT(_machdep, OID_AUTO, apm_suspend_delay, CTLFLAG_RW, &apm_suspend_delay, 1, ""); SYSCTL_INT(_machdep, OID_AUTO, apm_standby_delay, CTLFLAG_RW, &apm_standby_delay, 1, ""); +SYSCTL_INT(_debug, OID_AUTO, apm_debug, CTLFLAG_RW, &apm_debug, 0, ""); /* * return 0 if the function successfull, @@ -120,10 +131,8 @@ 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 + APM_DPRINT("apm_bioscall: function 0x%x is not supported in v%d.%d\n", + apm_func, sc->majorversion, sc->minorversion); return (-1); } @@ -318,9 +327,7 @@ int s; struct apmhook *p, *prev; -#ifdef APM_DEBUG - printf("Add hook \"%s\"\n", ah->ah_name); -#endif + APM_DPRINT("Add hook \"%s\"\n", ah->ah_name); s = splhigh(); if (ah == NULL) @@ -371,9 +378,7 @@ struct apmhook *p; for (p = list; p != NULL; p = p->ah_next) { -#ifdef APM_DEBUG - printf("Execute APM hook \"%s.\"\n", p->ah_name); -#endif + APM_DPRINT("Execute APM hook \"%s.\"\n", p->ah_name); if ((*(p->ah_fun))(p->ah_arg)) printf("Warning: APM hook \"%s\" failed", p->ah_name); } @@ -400,69 +405,6 @@ apm_del_hook(&hook[apmh], ah); } - -static struct timeval suspend_time; -static struct timeval diff_time; - -static int -apm_default_resume(void *arg) -{ - int pl; - u_int second, minute, hour; - struct timeval resume_time, tmp_time; - - /* modified for adjkerntz */ - pl = splsoftclock(); - i8254_restore(); /* restore timer_freq and hz */ - inittodr(0); /* adjust time to RTC */ - microtime(&resume_time); - getmicrotime(&tmp_time); - timevaladd(&tmp_time, &diff_time); - -#ifdef FIXME - /* XXX THIS DOESN'T WORK!!! */ - time = tmp_time; -#endif - -#ifdef APM_FIXUP_CALLTODO - /* Calculate the delta time suspended */ - timevalsub(&resume_time, &suspend_time); - /* Fixup the calltodo list with the delta time. */ - adjust_timeout_calltodo(&resume_time); -#endif /* APM_FIXUP_CALLTODOK */ - splx(pl); -#ifndef APM_FIXUP_CALLTODO - second = resume_time.tv_sec - suspend_time.tv_sec; -#else /* APM_FIXUP_CALLTODO */ - /* - * We've already calculated resume_time to be the delta between - * the suspend and the resume. - */ - second = resume_time.tv_sec; -#endif /* APM_FIXUP_CALLTODO */ - hour = second / 3600; - second %= 3600; - minute = second / 60; - second %= 60; - log(LOG_NOTICE, "resumed from suspended mode (slept %02d:%02d:%02d)\n", - hour, minute, second); - return 0; -} - -static int -apm_default_suspend(void *arg) -{ - int pl; - - pl = splsoftclock(); - microtime(&diff_time); - inittodr(0); - microtime(&suspend_time); - timevalsub(&diff_time, &suspend_time); - splx(pl); - return 0; -} - static int apm_record_event __P((struct apm_softc *, u_int)); static void apm_processevent(void); @@ -487,6 +429,7 @@ } else { apm_execute_hook(hook[APM_HOOK_SUSPEND]); if (apm_suspend_system(PMST_SUSPEND) == 0) { + sc->suspending = 1; apm_processevent(); } else { /* Failure, 'resume' the system again */ @@ -513,7 +456,6 @@ * As far as standby, we don't need to execute * all of suspend hooks. */ - apm_default_suspend(&apm_softc); if (apm_suspend_system(PMST_STANDBY) == 0) apm_processevent(); } @@ -546,9 +488,7 @@ sc->bios.r.edx = 0; if (apm_bioscall()) { -#ifdef APM_DEBUG - printf("apm_lastreq_rejected: failed\n"); -#endif + APM_DPRINT("apm_lastreq_rejected: failed\n"); return 1; } apm_op_inprog = 0; @@ -600,6 +540,10 @@ if (!sc) return; + if (sc->suspending == 0) + return; + + sc->suspending = 0; if (sc->initialized) { apm_execute_hook(hook[APM_HOOK_RESUME]); DEVICE_RESUME(root_bus); @@ -751,7 +695,7 @@ if (sc->active == 1) /* Run slightly more oftan than 1 Hz */ - apm_timeout_ch = timeout(apm_timeout, NULL, hz - 1 ); + apm_timeout_ch = timeout(apm_timeout, NULL, hz - 1); } /* enable APM BIOS */ @@ -760,9 +704,7 @@ { struct apm_softc *sc = &apm_softc; -#ifdef APM_DEBUG - printf("called apm_event_enable()\n"); -#endif + APM_DPRINT("called apm_event_enable()\n"); if (sc->initialized) { sc->active = 1; apm_timeout(sc); @@ -775,9 +717,7 @@ { struct apm_softc *sc = &apm_softc; -#ifdef APM_DEBUG - printf("called apm_event_disable()\n"); -#endif + APM_DPRINT("called apm_event_disable()\n"); if (sc->initialized) { untimeout(apm_timeout, NULL, apm_timeout_ch); sc->active = 0; @@ -807,6 +747,30 @@ /* device driver definitions */ /* + * Module event + */ + +static int +apm_modevent(struct module *mod, int event, void *junk) +{ + + switch (event) { + case MOD_LOAD: + if (!cold) + return (EPERM); + break; + case MOD_UNLOAD: + if (!cold && power_pm_get_type() == POWER_PM_TYPE_APM) + return (EBUSY); + break; + default: + break; + } + + return (0); +} + +/* * Create "connection point" */ static void @@ -814,6 +778,11 @@ { device_t child; + if (!cold) { + printf("Don't load this driver from userland!!\n"); + return; + } + child = BUS_ADD_CHILD(parent, 0, "apm", 0); if (child == NULL) panic("apm_identify"); @@ -830,17 +799,24 @@ struct apm_softc *sc = &apm_softc; int disabled, flags; - if (resource_int_value("apm", 0, "disabled", &disabled) == 0 - && disabled != 0) - return ENXIO; - device_set_desc(dev, "APM BIOS"); - if ( device_get_unit(dev) > 0 ) { + if (resource_int_value("apm", 0, "disabled", &disabled) != 0) + disabled = 0; + if (disabled) + return ENXIO; + + if (device_get_unit(dev) > 0) { printf("apm: Only one APM driver supported.\n"); return ENXIO; } + if (power_pm_get_type() != POWER_PM_TYPE_NONE && + power_pm_get_type() != POWER_PM_TYPE_APM) { + printf("apm: Other PM system enabled.\n"); + return ENXIO; + } + if (resource_int_value("apm", 0, "flags", &flags) != 0) flags = 0; @@ -931,6 +907,24 @@ return (sc->sc_flags & SCFLAG_OCTL) ? 0 : 1; /* user may handle */ } +/* Power profile */ +static void +apm_power_profile(struct apm_softc *sc) +{ + int state; + struct apm_info info; + static int apm_acline = 0; + + if (apm_get_info(&info)) + return; + + if (apm_acline != info.ai_acline) { + apm_acline = info.ai_acline; + state = apm_acline ? POWER_PROFILE_PERFORMANCE : POWER_PROFILE_ECONOMY; + power_profile_set_state(state); + } +} + /* Process APM event */ static void apm_processevent(void) @@ -938,12 +932,9 @@ int apm_event; struct apm_softc *sc = &apm_softc; -#ifdef APM_DEBUG -# define OPMEV_DEBUGMESSAGE(symbol) case symbol: \ - printf("Received APM Event: " #symbol "\n"); -#else -# define OPMEV_DEBUGMESSAGE(symbol) case symbol: -#endif +#define OPMEV_DEBUGMESSAGE(symbol) case symbol: \ + APM_DPRINT("Received APM Event: " #symbol "\n"); + do { apm_event = apm_getevent(); switch (apm_event) { @@ -994,7 +985,6 @@ break; OPMEV_DEBUGMESSAGE(PMEV_STANDBYRESUME); apm_record_event(sc, apm_event); - apm_resume(); break; OPMEV_DEBUGMESSAGE(PMEV_BATTERYLOW); if (apm_record_event(sc, apm_event)) { @@ -1004,6 +994,7 @@ break; OPMEV_DEBUGMESSAGE(PMEV_POWERSTATECHANGE); apm_record_event(sc, apm_event); + apm_power_profile(sc); break; OPMEV_DEBUGMESSAGE(PMEV_UPDATETIME); apm_record_event(sc, apm_event); @@ -1011,6 +1002,7 @@ break; OPMEV_DEBUGMESSAGE(PMEV_CAPABILITIESCHANGE); apm_record_event(sc, apm_event); + apm_power_profile(sc); break; case PMEV_NOEVENT: break; @@ -1048,17 +1040,17 @@ /* Always call HLT in idle loop */ sc->always_halt_cpu = 1; + getenv_int("debug.apm_debug", &apm_debug); + /* print bootstrap messages */ -#ifdef APM_DEBUG - printf("apm: APM BIOS version %04x\n", apm_version); - printf("apm: Code16 0x%08x, Data 0x%08x\n", - sc->bios.seg.code16.base, sc->bios.seg.data.base); - printf("apm: Code entry 0x%08x, Idling CPU %s, Management %s\n", - sc->bios.entry, is_enabled(sc->slow_idle_cpu), - is_enabled(!sc->disabled)); - printf("apm: CS_limit=0x%x, DS_limit=0x%x\n", - sc->bios.seg.code16.limit, sc->bios.seg.data.limit); -#endif /* APM_DEBUG */ + APM_DPRINT("apm: APM BIOS version %04lx\n", apm_version); + APM_DPRINT("apm: Code16 0x%08x, Data 0x%08x\n", + sc->bios.seg.code16.base, sc->bios.seg.data.base); + APM_DPRINT("apm: Code entry 0x%08x, Idling CPU %s, Management %s\n", + sc->bios.entry, is_enabled(sc->slow_idle_cpu), + is_enabled(!sc->disabled)); + APM_DPRINT("apm: CS_limit=0x%x, DS_limit=0x%x\n", + sc->bios.seg.code16.limit, sc->bios.seg.data.limit); /* * In one test, apm bios version was 1.02; an attempt to register @@ -1076,63 +1068,43 @@ sc->intversion = INTVERSION(sc->majorversion, sc->minorversion); -#ifdef APM_DEBUG if (sc->intversion >= INTVERSION(1, 1)) - printf("apm: Engaged control %s\n", is_enabled(!sc->disengaged)); -#endif - - printf("apm: found APM BIOS v%ld.%ld, connected at v%d.%d\n", + APM_DPRINT("apm: Engaged control %s\n", is_enabled(!sc->disengaged)); + device_printf(dev, "found APM BIOS v%ld.%ld, connected at v%d.%d\n", ((apm_version & 0xf000) >> 12) * 10 + ((apm_version & 0x0f00) >> 8), ((apm_version & 0x00f0) >> 4) * 10 + ((apm_version & 0x000f) >> 0), sc->majorversion, sc->minorversion); -#ifdef APM_DEBUG - printf("apm: Slow Idling CPU %s\n", is_enabled(sc->slow_idle_cpu)); -#endif + APM_DPRINT("apm: Slow Idling CPU %s\n", is_enabled(sc->slow_idle_cpu)); /* enable power management */ if (sc->disabled) { if (apm_enable_disable_pm(1)) { -#ifdef APM_DEBUG - printf("apm: *Warning* enable function failed! [%x]\n", - (sc->bios.r.eax >> 8) & 0xff); -#endif + APM_DPRINT("apm: *Warning* enable function failed! [%x]\n", + (sc->bios.r.eax >> 8) & 0xff); } } /* engage power managment (APM 1.1 or later) */ if (sc->intversion >= INTVERSION(1, 1) && sc->disengaged) { if (apm_engage_disengage_pm(1)) { -#ifdef APM_DEBUG - printf("apm: *Warning* engage function failed err=[%x]", - (sc->bios.r.eax >> 8) & 0xff); - printf(" (Docked or using external power?).\n"); -#endif + APM_DPRINT("apm: *Warning* engage function failed err=[%x]", + (sc->bios.r.eax >> 8) & 0xff); + APM_DPRINT(" (Docked or using external power?).\n"); } } - /* default suspend hook */ - sc->sc_suspend.ah_fun = apm_default_suspend; - sc->sc_suspend.ah_arg = sc; - sc->sc_suspend.ah_name = "default suspend"; - sc->sc_suspend.ah_order = APM_MAX_ORDER; - - /* default resume hook */ - sc->sc_resume.ah_fun = apm_default_resume; - sc->sc_resume.ah_arg = sc; - sc->sc_resume.ah_name = "default resume"; - sc->sc_resume.ah_order = APM_MIN_ORDER; - - apm_hook_establish(APM_HOOK_SUSPEND, &sc->sc_suspend); - apm_hook_establish(APM_HOOK_RESUME , &sc->sc_resume); - /* Power the system off using APM */ EVENTHANDLER_REGISTER(shutdown_final, apm_power_off, NULL, SHUTDOWN_PRI_LAST); + /* Register APM again to pass the correct argument of pm_func. */ + power_pm_register(POWER_PM_TYPE_APM, apm_pm_func, sc); + sc->initialized = 1; + sc->suspending = 0; - make_dev(&apm_cdevsw, 0, 0, 5, 0660, "apm"); + make_dev(&apm_cdevsw, 0, 0, 5, 0664, "apm"); make_dev(&apm_cdevsw, 8, 0, 5, 0660, "apmctl"); return 0; } @@ -1199,9 +1171,7 @@ if (!sc->initialized) return (ENXIO); -#ifdef APM_DEBUG - printf("APM ioctl: cmd = 0x%x\n", cmd); -#endif + APM_DPRINT("APM ioctl: cmd = 0x%lx\n", cmd); switch (cmd) { case APMIO_SUSPEND: if (!(flag & FWRITE)) @@ -1369,9 +1339,7 @@ enabled = 0; } sc->event_filter[event_type] = enabled; -#ifdef APM_DEBUG - printf("apmwrite: event 0x%x %s\n", event_type, is_enabled(enabled)); -#endif + APM_DPRINT("apmwrite: event 0x%x %s\n", event_type, is_enabled(enabled)); return uio->uio_resid; } @@ -1410,4 +1378,56 @@ static devclass_t apm_devclass; -DRIVER_MODULE(apm, nexus, apm_driver, apm_devclass, 0, 0); +DRIVER_MODULE(apm, nexus, apm_driver, apm_devclass, apm_modevent, 0); +MODULE_VERSION(apm, 1); + +static int +apm_pm_func(u_long cmd, void *arg, ...) +{ + int state, apm_state; + int error; + va_list ap; + + error = 0; + switch (cmd) { + case POWER_CMD_SUSPEND: + va_start(ap, arg); + state = va_arg(ap, int); + va_end(ap); + + switch (state) { + case POWER_SLEEP_STATE_STANDBY: + apm_state = PMST_STANDBY; + break; + case POWER_SLEEP_STATE_SUSPEND: + case POWER_SLEEP_STATE_HIBERNATE: + apm_state = PMST_SUSPEND; + break; + default: + error = EINVAL; + goto out; + } + + apm_suspend(apm_state); + break; + + default: + error = EINVAL; + goto out; + } + +out: + return (error); +} + +static void +apm_pm_register(void *arg) +{ + int disabled = 0; + + resource_int_value("apm", 0, "disabled", &disabled); + if (disabled == 0) + power_pm_register(POWER_PM_TYPE_APM, apm_pm_func, NULL); +} + +SYSINIT(power, SI_SUB_KLD, SI_ORDER_ANY, apm_pm_register, 0); Index: sys/i386/apm/apm.h =================================================================== RCS file: /usr/cvs/src/sys/i386/apm/apm.h,v retrieving revision 1.1 diff -u -r1.1 apm.h --- sys/i386/apm/apm.h 2 Oct 1999 03:34:15 -0000 1.1 +++ sys/i386/apm/apm.h 16 Oct 2002 19:43:59 -0000 @@ -26,6 +26,7 @@ int initialized, active, bios_busy; int always_halt_cpu, slow_idle_cpu; int disabled, disengaged; + int suspending; int standby_countdown, suspend_countdown; u_int minorversion, majorversion; u_int intversion, connectmode; Index: sys/i386/i386/nexus.c =================================================================== RCS file: /usr/cvs/src/sys/i386/i386/nexus.c,v retrieving revision 1.26.2.6 diff -u -r1.26.2.6 nexus.c --- sys/i386/i386/nexus.c 3 Mar 2002 05:42:49 -0000 1.26.2.6 +++ sys/i386/i386/nexus.c 16 Oct 2002 19:44:53 -0000 @@ -46,9 +46,7 @@ #include #include #include -#ifdef PC98 #include -#endif #include #include #include @@ -71,10 +69,18 @@ #endif #include +static MALLOC_DEFINE(M_NEXUSDEV, "nexusdev", "Nexus device"); +struct nexus_device { + struct resource_list nx_resources; +}; + +#define DEVTONX(dev) ((struct nexus_device *)device_get_ivars(dev)) + static struct rman irq_rman, drq_rman, port_rman, mem_rman; static int nexus_probe(device_t); static int nexus_attach(device_t); +static int nexus_print_all_resources(device_t dev); static int nexus_print_child(device_t, device_t); static device_t nexus_add_child(device_t bus, int order, const char *name, int unit); @@ -90,6 +96,9 @@ void (*)(void *), void *, void **); static int nexus_teardown_intr(device_t, device_t, struct resource *, void *); +static int nexus_set_resource(device_t, device_t, int, int, u_long, u_long); +static int nexus_get_resource(device_t, device_t, int, int, u_long *, u_long *); +static void nexus_delete_resource(device_t, device_t, int, int); static device_method_t nexus_methods[] = { /* Device interface */ @@ -111,6 +120,9 @@ DEVMETHOD(bus_deactivate_resource, nexus_deactivate_resource), DEVMETHOD(bus_setup_intr, nexus_setup_intr), DEVMETHOD(bus_teardown_intr, nexus_teardown_intr), + DEVMETHOD(bus_set_resource, nexus_set_resource), + DEVMETHOD(bus_get_resource, nexus_get_resource), + DEVMETHOD(bus_delete_resource, nexus_delete_resource), { 0, 0 } }; @@ -219,21 +231,21 @@ * connection points now so they show up "on motherboard". */ if (!devclass_get_device(devclass_find("eisa"), 0)) { - child = device_add_child(dev, "eisa", 0); + child = BUS_ADD_CHILD(dev, 0, "eisa", 0); if (child == NULL) panic("nexus_attach eisa"); device_probe_and_attach(child); } #if NMCA > 0 if (!devclass_get_device(devclass_find("mca"), 0)) { - child = device_add_child(dev, "mca", 0); - if (child == 0) + child = BUS_ADD_CHILD(dev, 0, "mca", 0); + if (child == NULL) panic("nexus_probe mca"); device_probe_and_attach(child); } #endif if (!devclass_get_device(devclass_find("isa"), 0)) { - child = device_add_child(dev, "isa", 0); + child = BUS_ADD_CHILD(dev, 0, "isa", 0); if (child == NULL) panic("nexus_attach isa"); device_probe_and_attach(child); @@ -243,11 +255,29 @@ } static int +nexus_print_all_resources(device_t dev) +{ + struct nexus_device *ndev = DEVTONX(dev); + struct resource_list *rl = &ndev->nx_resources; + int retval = 0; + + if (SLIST_FIRST(rl)) + retval += printf(" at"); + + retval += resource_list_print_type(rl, "port", SYS_RES_IOPORT, "%#lx"); + retval += resource_list_print_type(rl, "iomem", SYS_RES_MEMORY, "%#lx"); + retval += resource_list_print_type(rl, "irq", SYS_RES_IRQ, "%ld"); + + return retval; +} + +static int nexus_print_child(device_t bus, device_t child) { int retval = 0; retval += bus_print_child_header(bus, child); + retval += nexus_print_all_resources(child); retval += printf(" on motherboard\n"); return (retval); @@ -256,7 +286,20 @@ static device_t nexus_add_child(device_t bus, int order, const char *name, int unit) { - return device_add_child_ordered(bus, order, name, unit); + device_t child; + struct nexus_device *ndev; + + ndev = malloc(sizeof(struct nexus_device), M_NEXUSDEV, M_NOWAIT|M_ZERO); + if (!ndev) + return(0); + resource_list_init(&ndev->nx_resources); + + child = device_add_child_ordered(bus, order, name, unit); + + /* should we free this in nexus_child_detached? */ + device_set_ivars(child, ndev); + + return(child); } /* @@ -268,10 +311,28 @@ nexus_alloc_resource(device_t bus, device_t child, int type, int *rid, u_long start, u_long end, u_long count, u_int flags) { + struct nexus_device *ndev = DEVTONX(child); struct resource *rv; + struct resource_list_entry *rle; struct rman *rm; int needactivate = flags & RF_ACTIVE; + /* + * If this is an allocation of the "default" range for a given RID, and + * we know what the resources for this device are (ie. they aren't maintained + * by a child bus), then work out the start/end values. + */ + if ((start == 0UL) && (end == ~0UL) && (count == 1)) { + if (ndev == NULL) + return(NULL); + rle = resource_list_find(&ndev->nx_resources, type, *rid); + if (rle == NULL) + return(NULL); + start = rle->start; + end = rle->end; + count = rle->count; + } + flags &= ~RF_ACTIVE; switch (type) { @@ -474,4 +535,43 @@ nexus_teardown_intr(device_t dev, device_t child, struct resource *r, void *ih) { return (inthand_remove(ih)); +} + +static int +nexus_set_resource(device_t dev, device_t child, int type, int rid, u_long start, u_long count) +{ + struct nexus_device *ndev = DEVTONX(child); + struct resource_list *rl = &ndev->nx_resources; + + /* XXX this should return a success/failure indicator */ + resource_list_add(rl, type, rid, start, start + count - 1, count); + return(0); +} + +static int +nexus_get_resource(device_t dev, device_t child, int type, int rid, u_long *startp, u_long *countp) +{ + struct nexus_device *ndev = DEVTONX(child); + struct resource_list *rl = &ndev->nx_resources; + struct resource_list_entry *rle; + + rle = resource_list_find(rl, type, rid); + device_printf(child, "type %d rid %d startp %p countp %p - got %p\n", + type, rid, startp, countp, rle); + if (!rle) + return(ENOENT); + if (startp) + *startp = rle->start; + if (countp) + *countp = rle->count; + return(0); +} + +static void +nexus_delete_resource(device_t dev, device_t child, int type, int rid) +{ + struct nexus_device *ndev = DEVTONX(child); + struct resource_list *rl = &ndev->nx_resources; + + resource_list_delete(rl, type, rid); } Index: sys/i386/include/clock.h =================================================================== RCS file: /usr/cvs/src/sys/i386/include/clock.h,v retrieving revision 1.38 diff -u -r1.38 clock.h --- sys/i386/include/clock.h 29 Dec 1999 04:32:58 -0000 1.38 +++ sys/i386/include/clock.h 16 Oct 2002 19:43:59 -0000 @@ -44,7 +44,7 @@ int release_timer1 __P((void)); #endif int sysbeep __P((int pitch, int period)); -void i8254_restore __P((void)); +void timer_restore __P((void)); #endif /* _KERNEL */ Index: sys/i386/isa/clock.c =================================================================== RCS file: /usr/cvs/src/sys/i386/isa/clock.c,v retrieving revision 1.149.2.5 diff -u -r1.149.2.5 clock.c --- sys/i386/isa/clock.c 30 Jun 2002 07:56:49 -0000 1.149.2.5 +++ sys/i386/isa/clock.c 16 Oct 2002 19:43:59 -0000 @@ -705,7 +705,7 @@ * when it happnes, it messes up the hardclock interval and system clock, * which leads to the infamous "calcru: negative time" problem. */ -void +static void i8254_restore(void) { u_long ef; @@ -717,6 +717,28 @@ outb(TIMER_CNTR0, timer0_max_count >> 8); CLOCK_UNLOCK(); write_eflags(ef); +} + +static void +rtc_restore(void) +{ + + /* Reenable RTC updates and interrupts. */ + /* XXX locking is needed for RTC access? */ + writertc(RTC_STATUSA, rtc_statusa); + writertc(RTC_STATUSB, RTCSB_HALT | RTCSB_24HR); + writertc(RTC_STATUSB, rtc_statusb); +} + +/* + * Restore all the timers atomically. + */ +void +timer_restore(void) +{ + + i8254_restore(); /* restore timer_freq and hz */ + rtc_restore(); /* reenable RTC interrupts */ } /* Index: sys/i386/isa/intr_machdep.c =================================================================== RCS file: /usr/cvs/src/sys/i386/isa/intr_machdep.c,v retrieving revision 1.29.2.5 diff -u -r1.29.2.5 intr_machdep.c --- sys/i386/isa/intr_machdep.c 14 Oct 2001 06:54:27 -0000 1.29.2.5 +++ sys/i386/isa/intr_machdep.c 16 Oct 2002 19:43:59 -0000 @@ -44,6 +44,7 @@ */ #include "opt_auto_eoi.h" +#include "opt_ddb.h" #include "isa.h" @@ -87,6 +88,10 @@ #if NMCA > 0 #include #endif +#ifdef DDB +#include +#include +#endif /* XXX should be in suitable include files */ #ifdef PC98 @@ -142,6 +147,7 @@ }; static inthand2_t isa_strayintr; +static void init_i8259(void); #ifdef PC98 #define NMI_PARITY 0x04 @@ -225,6 +231,18 @@ } /* + * ICU reinitialize when ICU configuration has lost. + */ +void icu_reinit() +{ + int i; + + init_i8259(); + for(i=0;i 0 if (MCA_system) @@ -635,7 +675,8 @@ if (idesc->maskptr != NULL) { /* our copy of *maskptr may be stale, refresh */ idesc->mask = *idesc->maskptr; - } + } else + idesc->mask = intr_mask[irq]; idesc = idesc->next; } } Index: sys/i386/isa/intr_machdep.h =================================================================== RCS file: /usr/cvs/src/sys/i386/isa/intr_machdep.h,v retrieving revision 1.19.2.2 diff -u -r1.19.2.2 intr_machdep.h --- sys/i386/isa/intr_machdep.h 14 Oct 2001 20:05:50 -0000 1.19.2.2 +++ sys/i386/isa/intr_machdep.h 16 Oct 2002 19:43:59 -0000 @@ -192,6 +192,7 @@ int icu_setup __P((int intr, inthand2_t *func, void *arg, u_int *maskptr, int flags)); int icu_unset __P((int intr, inthand2_t *handler)); +void icu_reinit(void); int update_intr_masks __P((void)); intrmask_t splq __P((intrmask_t mask)); Index: sys/kern/subr_bus.c =================================================================== RCS file: /usr/cvs/src/sys/kern/subr_bus.c,v retrieving revision 1.54.2.8 diff -u -r1.54.2.8 subr_bus.c --- sys/kern/subr_bus.c 18 Jan 2001 00:19:50 -0000 1.54.2.8 +++ sys/kern/subr_bus.c 16 Oct 2002 19:43:59 -0000 @@ -1850,6 +1850,34 @@ return 0; } +int +resource_list_print_type(struct resource_list *rl, const char *name, int type, + const char *format) +{ + struct resource_list_entry *rle; + int printed, retval; + + printed = 0; + retval = 0; + /* Yes, this is kinda cheating */ + SLIST_FOREACH(rle, rl, link) { + if (rle->type == type) { + if (printed == 0) + retval += printf(" %s ", name); + else + retval += printf(","); + printed++; + retval += printf(format, rle->start); + if (rle->count > 1) { + retval += printf("-"); + retval += printf(format, rle->start + + rle->count - 1); + } + } + } + return (retval); +} + /* * Call DEVICE_IDENTIFY for each driver. */ Index: sys/sys/bus.h =================================================================== RCS file: /usr/cvs/src/sys/sys/bus.h,v retrieving revision 1.30.2.3 diff -u -r1.30.2.3 bus.h --- sys/sys/bus.h 16 Jun 2001 23:05:02 -0000 1.30.2.3 +++ sys/sys/bus.h 16 Oct 2002 19:43:59 -0000 @@ -156,6 +156,15 @@ int type, int rid, struct resource *res); /* + * Print all resources of a specified type, for use in bus_print_child. + * The name is printed if at least one resource of the given type is available. + * The format ist used to print resource start and end. + */ +int resource_list_print_type(struct resource_list *rl, + const char *name, int type, + const char *format); + +/* * The root bus, to which all top-level busses are attached. */ extern device_t root_bus;