Index: sys/dev/acpica/acpi.c =================================================================== RCS file: /home/ncvs/src/sys/dev/acpica/acpi.c,v retrieving revision 1.198 diff -u -r1.198 acpi.c --- sys/dev/acpica/acpi.c 8 Jan 2005 09:10:20 -0000 1.198 +++ sys/dev/acpica/acpi.c 27 Jan 2005 23:30:27 -0000 @@ -402,6 +402,7 @@ sc = device_get_softc(dev); sc->acpi_dev = dev; + knlist_init(&sc->sel_read.si_note, &acpi_mutex); /* Initialize resource manager. */ acpi_rman_io.rm_type = RMAN_ARRAY; @@ -2461,11 +2462,18 @@ static void acpi_system_eventhandler_sleep(void *arg, int state) { + struct acpi_softc *sc; ACPI_FUNCTION_TRACE_U32((char *)(uintptr_t)__func__, state); - if (state >= ACPI_STATE_S0 && state <= ACPI_S_STATES_MAX) - acpi_SetSleepState((struct acpi_softc *)arg, state); + sc = (struct acpi_softc *)arg; + if (state >= ACPI_STATE_S0 && state <= ACPI_S_STATES_MAX) { + //acpi_SetSleepState((struct acpi_softc *)arg, state); + printf("acpi ev got %d, waking\n", state); + sc->apm_next_sstate = state; + selwakeuppri(&sc->sel_read, PZERO); + KNOTE_UNLOCKED(&sc->sel_read.si_note, 0); + } return_VOID; } Index: sys/dev/acpica/acpivar.h =================================================================== RCS file: /home/ncvs/src/sys/dev/acpica/acpivar.h,v retrieving revision 1.85 diff -u -r1.85 acpivar.h --- sys/dev/acpica/acpivar.h 13 Dec 2004 23:31:45 -0000 1.85 +++ sys/dev/acpica/acpivar.h 27 Jan 2005 23:30:43 -0000 @@ -31,6 +31,7 @@ #include "acpi_if.h" #include "bus_if.h" #include +#include #include #include #include @@ -41,7 +42,9 @@ struct acpi_softc { device_t acpi_dev; - struct cdev *acpi_dev_t; + struct cdev *acpi_dev_t; + struct selinfo sel_read; + int apm_next_sstate; struct resource *acpi_irq; int acpi_irq_rid; Index: sys/i386/acpica/acpi_machdep.c =================================================================== RCS file: /home/ncvs/src/sys/i386/acpica/acpi_machdep.c,v retrieving revision 1.28 diff -u -r1.28 acpi_machdep.c --- sys/i386/acpica/acpi_machdep.c 22 Oct 2004 17:17:12 -0000 1.28 +++ sys/i386/acpica/acpi_machdep.c 27 Jan 2005 23:31:45 -0000 @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include @@ -45,8 +46,6 @@ * APM driver emulation */ -#include - #include #include @@ -58,11 +57,16 @@ static int intr_model = ACPI_INTR_PIC; static int apm_active; -static d_open_t apmopen; -static d_close_t apmclose; -static d_write_t apmwrite; -static d_ioctl_t apmioctl; -static d_poll_t apmpoll; +static d_open_t apmopen; +static d_close_t apmclose; +static d_write_t apmwrite; +static d_ioctl_t apmioctl; +static d_poll_t apmpoll; +static d_kqfilter_t apmkqfilter; +static void apmreadfiltdetach(struct knote *kn); +static int apmreadfilt(struct knote *kn, long hint); +static struct filterops apm_readfiltops = + { 1, NULL, apmreadfiltdetach, apmreadfilt }; static struct cdevsw apm_cdevsw = { .d_version = D_VERSION, @@ -72,6 +76,7 @@ .d_ioctl = apmioctl, .d_poll = apmpoll, .d_name = "apm", + .d_kqfilter = apmkqfilter }; static int @@ -205,11 +210,13 @@ static int apmioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag, d_thread_t *td) { - int error = 0; + int error; struct acpi_softc *acpi_sc; - struct apm_info info; + struct apm_info info; + struct apm_event_info *ev_info; apm_info_old_t aiop; + error = 0; acpi_sc = devclass_get_softc(devclass_find("acpi"), 0); switch (cmd) { @@ -229,6 +236,27 @@ else error = EINVAL; break; + case APMIO_NEXTEVENT: + if ((flag & FWRITE) == 0) + return (EPERM); + if (!apm_active) + return (EINVAL); + printf("apm nextevent start\n"); + ACPI_LOCK(acpi); + if (acpi_sc->apm_next_sstate) { + ev_info = (struct apm_event_info *)addr; + if (acpi_sc->apm_next_sstate <= ACPI_STATE_S3) + ev_info->type = PMEV_STANDBYREQ; + else + ev_info->type = PMEV_SUSPENDREQ; + ev_info->index = 0; + acpi_sc->apm_next_sstate = 0; + printf("apm event returning %d\n", ev_info->type); + } else + error = EAGAIN; + ACPI_UNLOCK(acpi); + printf("apm nextevent done\n"); + break; case APMIO_GETINFO_OLD: if (acpi_capm_get_info(&info)) error = ENXIO; @@ -288,10 +316,50 @@ static int apmpoll(struct cdev *dev, int events, d_thread_t *td) { + struct acpi_softc *sc; + int revents; + + sc = (struct acpi_softc *)dev->si_drv1; + revents = 0; + if (sc->apm_next_sstate) + revents |= events & (POLLIN | POLLRDNORM); + else + selrecord(td, &sc->sel_read); + printf("apm poll returning %x\n", revents); + return (revents); +} + +static int +apmkqfilter(struct cdev *dev, struct knote *kn) +{ + struct acpi_softc *sc; + + sc = (struct acpi_softc *)dev->si_drv1; + kn->kn_hook = (caddr_t)sc; + kn->kn_fop = &apm_readfiltops; + knlist_add(&sc->sel_read.si_note, kn, 0); return (0); } static void +apmreadfiltdetach(struct knote *kn) +{ + struct acpi_softc *sc; + + sc = (struct acpi_softc *)kn->kn_hook; + knlist_remove(&sc->sel_read.si_note, kn, 0); +} + +static int +apmreadfilt(struct knote *kn, long hint) +{ + struct acpi_softc *sc; + + sc = (struct acpi_softc *)kn->kn_hook; + return (sc->apm_next_sstate ? 1 : 0); +} + +static void acpi_capm_init(struct acpi_softc *sc) { make_dev(&apm_cdevsw, 0, 0, 5, 0664, "apm");