--- acpi.c.old	Thu Sep 23 23:45:50 1999
+++ acpi.c	Tue Sep 28 08:13:11 1999
@@ -30,6 +30,7 @@
 #include <sys/param.h>
 #include <sys/proc.h>
 #include <sys/systm.h>
+#include <sys/sysctl.h>
 #include <sys/kernel.h>
 #include <sys/malloc.h>
 #include <vm/vm.h>
@@ -99,19 +100,14 @@
 	 /* read */ noread,
 	 /* write */ nowrite,
 	 /* ioctl */ acpiioctl,
-	 /* stop */ nostop,
-	 /* reset */ noreset,
-	 /* devtotty */ nodevtotty,
 	 /* poll */ nopoll,
 	 /* mmap */ acpimmap,
 	 /* strategy */ nostrategy,
 	 /* name */ "acpi",
-	 /* parms */ noparms,
 	 /* maj */ CDEV_MAJOR,
 	 /* dump */ nodump,
 	 /* psize */ nopsize,
 	 /* flags */ 0,
-	 /* maxio */ 0,
 	 /* bmaj */ -1
 };
 
@@ -124,11 +120,18 @@
 static void     acpi_enable_disable(device_t dev, boolean_t enable);
 static void     acpi_io_pm1_status(device_t dev, boolean_t io, u_int32_t *a, u_int32_t *b);
 static void     acpi_io_pm1_enable(device_t dev, boolean_t io, u_int32_t *a, u_int32_t *b);
+static void     acpi_io_pm1_control(device_t dev, boolean_t io, u_int32_t *a, u_int32_t *b);
+static void     acpi_io_pm2_control(device_t dev, boolean_t io, u_int32_t *val);
+static void     acpi_io_pm_timer(device_t dev, boolean_t io, u_int32_t *val);
 static void     acpi_io_gpe0_status(device_t dev, boolean_t io, u_int32_t *val);
 static void     acpi_io_gpe0_enable(device_t dev, boolean_t io, u_int32_t *val);
 static void     acpi_io_gpe1_status(device_t dev, boolean_t io, u_int32_t *val);
 static void     acpi_io_gpe1_enable(device_t dev, boolean_t io, u_int32_t *val);
 
+/* for debugging */
+static	int	acpi_debug = 0;
+SYSCTL_INT(_debug, OID_AUTO, acpi_debug, CTLFLAG_RW, &acpi_debug, 1, "");
+
 void
 acpi_init_addr_range()
 {
@@ -278,7 +281,13 @@
 	}
 }
 
+/* XXX should be moved to acpi.h */
 #define	ACPI_PM1_ALL_ENABLE_BITS	0x0721	/* 0000 0111 0010 0001 */
+#define	ACPI_PM1_TMR_EN			0x0001
+#define	ACPI_PM1_GBL_EN			0x0020
+#define	ACPI_PM1_PWRBTN_EN		0x0100
+#define	ACPI_PM1_SLPBTN_EN		0x0200
+#define	ACPI_PM1_RTC_EN			0x0400
 
 static void
 acpi_intr(void *data)
@@ -287,13 +296,18 @@
 	u_int32_t       enable_a, enable_b, enable_0, enable_1;
 	u_int32_t       status_a, status_b, status_0, status_1;
 	u_int32_t       val_a, val_b;
+	int		debug = acpi_debug;	/* Save debug level */
+
+	acpi_debug = 0;	/* Shut up */
 
 	/* Power Management 1 Status Registers */
+	status_a = status_b = enable_a = enable_b = 0;
 	acpi_io_pm1_status(sc->dev, ACPI_REGISTERS_INPUT, &status_a, &status_b);
 	/* Get Current Intrrupt Mask */
 	acpi_io_pm1_enable(sc->dev, ACPI_REGISTERS_INPUT, &enable_a, &enable_b);
 	/* Disable events and re-enable again */
 	if ((status_a & enable_a) != 0 || (status_b & enable_b) != 0) {
+		acpi_debug = debug;	/* OK, you can speak */
 
 		printf("ACPI: pm1_status intr CALLED\n");
 
@@ -308,18 +322,36 @@
 		val_b = enable_b & ACPI_PM1_ALL_ENABLE_BITS;
 		acpi_io_pm1_status(sc->dev, ACPI_REGISTERS_OUTPUT,
 				   &val_a, &val_b);
-
 		/* Re-enable intrrupt */
 		acpi_io_pm1_enable(sc->dev, ACPI_REGISTERS_OUTPUT,
 				   &enable_a, &enable_b);
+
+#if 0
+		/* set sleep type */
+		disable_intr();
+		/* _S0_ = 4, _S1_ = 7, _S5_ = 6 on P2B */
+		val_a = 0x7 << 10;	/* SLP_TYPx */
+		val_b = 0x7 << 10;	/* SLP_TYPx */
+		acpi_io_pm1_control(sc->dev, ACPI_REGISTERS_OUTPUT,
+				   &val_a, &val_b);
+		/* enter sleeing state */
+		val_a = 0x1 << 13;	/* SLP_EN */
+		val_b = 0x1 << 13;	/* SLP_EN */
+		acpi_io_pm1_control(sc->dev, ACPI_REGISTERS_OUTPUT,
+				   &val_a, &val_b);
+		enable_intr();
+#endif
+		acpi_debug = 0;	/* Shut up again */
 	}
 
 	/* General-Purpose Events 0 Status Registers */
+	status_0 = enable_0 = 0;
 	acpi_io_gpe0_status(sc->dev, ACPI_REGISTERS_INPUT, &status_0);
 	/* Get Current Intrrupt Mask */
 	acpi_io_gpe0_enable(sc->dev, ACPI_REGISTERS_INPUT, &enable_0);
 	/* Disable events and re-enable again */
 	if ((status_0 & enable_0) != 0) {
+		acpi_debug = debug;	/* OK, you can speak */
 
 		printf("ACPI: gpe0_status intr CALLED\n");
 
@@ -337,14 +369,18 @@
 
 		/* Re-enable intrrupt */
 		acpi_io_gpe0_enable(sc->dev, ACPI_REGISTERS_OUTPUT, &enable_0);
+
+		acpi_debug = 0;	/* Shut up again */
 	}
 
 	/* General-Purpose Events 1 Status Registers */
+	status_1 = enable_1 = 0;
 	acpi_io_gpe1_status(sc->dev, ACPI_REGISTERS_INPUT, &status_1);
 	/* Get Current Intrrupt Mask */
 	acpi_io_gpe1_enable(sc->dev, ACPI_REGISTERS_INPUT, &enable_1);
 	/* Disable events and re-enable again */
 	if ((status_1 & enable_1) != 0) {
+		acpi_debug = debug;	/* OK, you can speak */
 
 		printf("ACPI: gpe1_status intr CALLED\n");
 
@@ -362,10 +398,14 @@
 
 		/* Re-enable intrrupt */
 		acpi_io_gpe1_enable(sc->dev, ACPI_REGISTERS_OUTPUT, &enable_1);
+
+		acpi_debug = 0;	/* Shut up again */
 	}
 
 	/* do something to handle the events... */
 	DELAY(1000);	/* :-) */
+
+	acpi_debug = debug;	/* Restore debug level */
 }
 
 static void
@@ -394,6 +434,9 @@
 	       acpi_rsdp, oemstring, acpi_rsdp->addr);
 
 	device_set_desc(dev, oemstring);
+#ifdef ACPI_DEBUG
+	acpi_debug = 1;
+#endif
 	return (0);
 }
 
@@ -475,6 +518,14 @@
 	acpi_enable_disable(dev, 1);
 	device_printf(dev, "at 0x%x irq %d\n", port, irq);
 
+#if 0
+	/* try to enable PWRBTN_EN and SLPBTN_EN bit */
+	acpi_io_pm1_enable(dev, ACPI_REGISTERS_INPUT, &status_a, &status_b);
+	status_a |= ACPI_PM1_PWRBTN_EN | ACPI_PM1_SLPBTN_EN;
+	status_b |= ACPI_PM1_PWRBTN_EN | ACPI_PM1_SLPBTN_EN;
+	acpi_io_pm1_enable(dev, ACPI_REGISTERS_OUTPUT, &status_a, &status_b);
+#endif
+
 	/* print all event status for debugging */
 	acpi_io_pm1_status(dev, ACPI_REGISTERS_INPUT, &status_a, &status_b);
 	acpi_io_pm1_enable(dev, ACPI_REGISTERS_INPUT,  &status_a, &status_b);
@@ -482,6 +533,9 @@
 	acpi_io_gpe0_enable(dev, ACPI_REGISTERS_INPUT, &status_a);
 	acpi_io_gpe1_status(dev, ACPI_REGISTERS_INPUT, &status_a);
 	acpi_io_gpe1_enable(dev, ACPI_REGISTERS_INPUT, &status_a);
+	acpi_io_pm1_control(dev, ACPI_REGISTERS_INPUT,  &status_a, &status_b);
+	acpi_io_pm2_control(dev, ACPI_REGISTERS_INPUT,  &status_a);
+	acpi_io_pm_timer(dev, ACPI_REGISTERS_INPUT,  &status_a);
 
 	acpi_pmap_release(dev);
 	sc->dev = dev;
@@ -553,9 +607,9 @@
 
 	outb(ioaddr, val);
 
-#ifdef ACPI_DEBUG
-	device_printf(dev, "acpi_enable_disable(%d) = (%x)\n", enable, val);
-#endif
+	if (acpi_debug) {
+		device_printf(dev, "acpi_enable_disable(%d) = (%x)\n", enable, val);
+	}
 }
 
 static void
@@ -580,10 +634,10 @@
 		}
 	}
 
-#ifdef ACPI_DEBUG
-	device_printf(dev, "acpi_io_pm1_status(%d) = (%x, %x)\n",
-			io, *status_a, *status_b);
-#endif
+	if (acpi_debug) {
+		device_printf(dev, "acpi_io_pm1_status(%d) = (%x, %x)\n",
+				io, *status_a, *status_b);
+	}
 
 	return;
 }
@@ -610,10 +664,86 @@
 		}
 	}
 
-#ifdef ACPI_DEBUG
-	device_printf(dev, "acpi_io_pm1_enable(%d) = (%x, %x)\n",
-			io, *status_a, *status_b);
-#endif
+	if (acpi_debug) {
+		device_printf(dev, "acpi_io_pm1_enable(%d) = (%x, %x)\n",
+				io, *status_a, *status_b);
+	}
+
+	return;
+}
+
+static void
+acpi_io_pm1_control(device_t dev, boolean_t io, u_int32_t *value_a, u_int32_t *value_b)
+{
+	struct acpi_softc *sc = device_get_softc(dev);
+	struct FACPbody *facp = sc->facp_body;
+	int		size = facp->pm1_cnt_len;
+
+	if (io == ACPI_REGISTERS_INPUT) {
+		acpi_registers_input(facp->pm1a_cnt_blk + size, value_a, size);
+
+		*value_b = 0;
+		if (facp->pm1b_evt_blk) {
+			acpi_registers_input(facp->pm1b_cnt_blk + size, value_b, size);
+		}
+	} else {
+		acpi_registers_output(facp->pm1a_cnt_blk + size, value_a, size);
+
+		if (facp->pm1b_evt_blk) {
+			acpi_registers_output(facp->pm1b_cnt_blk + size, value_b, size);
+		}
+	}
+
+	if (acpi_debug) {
+		device_printf(dev, "acpi_io_pm1_control(%d) = (%x, %x)\n",
+				io, *value_a, *value_b);
+	}
+
+	return;
+}
+
+static void
+acpi_io_pm2_control(device_t dev, boolean_t io, u_int32_t *val)
+{
+	struct acpi_softc *sc = device_get_softc(dev);
+	struct FACPbody *facp = sc->facp_body;
+	int		size = facp->pm2_cnt_len;
+
+	if (!facp->pm2_cnt_blk) {
+		return;	/* optional */
+	}
+
+	if (io == ACPI_REGISTERS_INPUT) {
+		acpi_registers_input(facp->pm2_cnt_blk, val, size);
+	} else {
+		acpi_registers_output(facp->pm2_cnt_blk, val, size);
+	}
+
+	if (acpi_debug) {
+		device_printf(dev, "acpi_io_gpe0_status(%d) = (%x)\n",
+				io, *val);
+	}
+
+	return;
+}
+
+static void
+acpi_io_pm_timer(device_t dev, boolean_t io, u_int32_t *val)
+{
+	struct acpi_softc *sc = device_get_softc(dev);
+	struct FACPbody *facp = sc->facp_body;
+	int		size = 0x4;	/* 32-bits */
+
+	if (io == ACPI_REGISTERS_INPUT) {
+		acpi_registers_input(facp->pm_tmr_blk, val, size);
+	} else {
+		return;	/* XXX read-only */
+	}
+
+	if (acpi_debug) {
+		device_printf(dev, "acpi_io_pm_timer(%d) = (%x)\n",
+				io, *val);
+	}
 
 	return;
 }
@@ -625,16 +755,20 @@
 	struct FACPbody *facp = sc->facp_body;
 	int		size = facp->gpe0_len / 2;
 
+	if (!facp->gpe0_blk) {
+		return;	/* optional */
+	}
+
 	if (io == ACPI_REGISTERS_INPUT) {
 		acpi_registers_input(facp->gpe0_blk, val, size);
 	} else {
 		acpi_registers_output(facp->gpe0_blk, val, size);
 	}
 
-#ifdef ACPI_DEBUG
-	device_printf(dev, "acpi_io_gpe0_status(%d) = (%x)\n",
-			io, *val);
-#endif
+	if (acpi_debug) {
+		device_printf(dev, "acpi_io_gpe0_status(%d) = (%x)\n",
+				io, *val);
+	}
 
 	return;
 }
@@ -646,16 +780,20 @@
 	struct FACPbody *facp = sc->facp_body;
 	int		size = facp->gpe0_len / 2;
 
+	if (!facp->gpe0_blk) {
+		return;	/* optional */
+	}
+
 	if (io == ACPI_REGISTERS_INPUT) {
 		acpi_registers_input(facp->gpe0_blk + size, val, size);
 	} else {
 		acpi_registers_output(facp->gpe0_blk + size, val, size);
 	}
 
-#ifdef ACPI_DEBUG
-	device_printf(dev, "acpi_io_gpe0_enable(%d) = (%x)\n",
-			io, *val);
-#endif
+	if (acpi_debug) {
+		device_printf(dev, "acpi_io_gpe0_enable(%d) = (%x)\n",
+				io, *val);
+	}
 
 	return;
 }
@@ -667,16 +805,20 @@
 	struct FACPbody *facp = sc->facp_body;
 	int		size = facp->gpe1_len / 2;
 
+	if (!facp->gpe1_blk) {
+		return;	/* optional */
+	}
+
 	if (io == ACPI_REGISTERS_INPUT) {
 		acpi_registers_input(facp->gpe1_blk, val, size);
 	} else {
 		acpi_registers_output(facp->gpe1_blk, val, size);
 	}
 
-#ifdef ACPI_DEBUG
-	device_printf(dev, "acpi_io_gpe1_status(%d) = (%x)\n",
-			io, *val);
-#endif
+	if (acpi_debug) {
+		device_printf(dev, "acpi_io_gpe1_status(%d) = (%x)\n",
+				io, *val);
+	}
 
 	return;
 }
@@ -688,16 +830,20 @@
 	struct FACPbody *facp = sc->facp_body;
 	int		size = facp->gpe1_len / 2;
 
+	if (!facp->gpe1_blk) {
+		return;	/* optional */
+	}
+
 	if (io == ACPI_REGISTERS_INPUT) {
 		acpi_registers_input(facp->gpe1_blk + size, val, size);
 	} else {
 		acpi_registers_output(facp->gpe1_blk + size, val, size);
 	}
 
-#ifdef ACPI_DEBUG
-	device_printf(dev, "acpi_io_gpe1_enable(%d) = (%x)\n",
-			io, *val);
-#endif
+	if (acpi_debug) {
+		device_printf(dev, "acpi_io_gpe1_enable(%d) = (%x)\n",
+				io, *val);
+	}
 
 	return;
 }
@@ -721,10 +867,11 @@
 acpimmap(dev_t dev, vm_offset_t offset, int nprot)
 {
 	struct acpi_softc *sc = devclass_get_softc(acpi_devclass, minor(dev));
+	device_t d=devclass_get_device(acpi_devclass,minor(dev));
 	if (sc == NULL) {
 		return EINVAL;
 	}
-	return i386_btop(vtophys(sc->dsdt + offset));
+	return i386_btop(acpi_pmap_vtp(d,sc->dsdt + offset));
 }
 
 

