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 <sys/eventhandler.h>
+#include <sys/selinfo.h>
 #include <sys/sysctl.h>
 #include <sys/lock.h>
 #include <sys/mutex.h>
@@ -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 <sys/conf.h>
 #include <sys/fcntl.h>
 #include <sys/kernel.h>
+#include <sys/poll.h>
 #include <sys/sysctl.h>
 #include <sys/uio.h>
 #include <vm/vm.h>
@@ -45,8 +46,6 @@
  * APM driver emulation 
  */
 
-#include <sys/selinfo.h>
-
 #include <machine/apm_bios.h>
 #include <machine/pc/bios.h>
 
@@ -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");
