Thu Oct 28 15:55:05 2010 UTC ()
Install EC space handler and pass everything to acpiec(4).
Should fix PR # 43659.


(jruoho)
diff -r1.10 -r1.11 src/sys/dev/acpi/wmi/wmi_acpi.c
diff -r1.4 -r1.5 src/sys/dev/acpi/wmi/wmi_acpivar.h

cvs diff -r1.10 -r1.11 src/sys/dev/acpi/wmi/wmi_acpi.c (expand / switch to context diff)
--- src/sys/dev/acpi/wmi/wmi_acpi.c 2010/10/25 15:38:05 1.10
+++ src/sys/dev/acpi/wmi/wmi_acpi.c 2010/10/28 15:55:04 1.11
@@ -1,4 +1,4 @@
-/*	$NetBSD: wmi_acpi.c,v 1.10 2010/10/25 15:38:05 jruoho Exp $	*/
+/*	$NetBSD: wmi_acpi.c,v 1.11 2010/10/28 15:55:04 jruoho Exp $	*/
 
 /*-
  * Copyright (c) 2009, 2010 Jukka Ruohonen <jruohonen@iki.fi>
@@ -27,7 +27,7 @@
  * SUCH DAMAGE.
  */
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: wmi_acpi.c,v 1.10 2010/10/25 15:38:05 jruoho Exp $");
+__KERNEL_RCSID(0, "$NetBSD: wmi_acpi.c,v 1.11 2010/10/28 15:55:04 jruoho Exp $");
 
 #include <sys/param.h>
 #include <sys/device.h>
@@ -38,6 +38,7 @@
 
 #include <dev/acpi/acpireg.h>
 #include <dev/acpi/acpivar.h>
+#include <dev/acpi/acpi_ecvar.h>
 #include <dev/acpi/wmi/wmi_acpivar.h>
 
 #define _COMPONENT          ACPI_RESOURCE_COMPONENT
@@ -52,27 +53,29 @@
  * (Obtained on Thu Feb 12 18:21:44 EET 2009.)
  */
 
-static int         acpi_wmi_match(device_t, cfdata_t, void *);
-static void        acpi_wmi_attach(device_t, device_t, void *);
-static int         acpi_wmi_detach(device_t, int);
-static int         acpi_wmi_rescan(device_t, const char *, const int *);
-static void        acpi_wmi_childdet(device_t, device_t);
-static int         acpi_wmi_print(void *, const char *);
-static bool        acpi_wmi_init(struct acpi_wmi_softc *);
-static bool        acpi_wmi_add(struct acpi_wmi_softc *, ACPI_OBJECT *);
-static void        acpi_wmi_del(struct acpi_wmi_softc *);
-static void	   acpi_wmi_dump(struct acpi_wmi_softc *);
+static int		acpi_wmi_match(device_t, cfdata_t, void *);
+static void		acpi_wmi_attach(device_t, device_t, void *);
+static int		acpi_wmi_detach(device_t, int);
+static int		acpi_wmi_rescan(device_t, const char *, const int *);
+static void		acpi_wmi_childdet(device_t, device_t);
+static int		acpi_wmi_print(void *, const char *);
+static bool		acpi_wmi_init(struct acpi_wmi_softc *);
+static void		acpi_wmi_init_ec(struct acpi_wmi_softc *);
+static bool		acpi_wmi_add(struct acpi_wmi_softc *, ACPI_OBJECT *);
+static void		acpi_wmi_del(struct acpi_wmi_softc *);
+static void		acpi_wmi_dump(struct acpi_wmi_softc *);
+static ACPI_STATUS	acpi_wmi_guid_get(struct acpi_wmi_softc *,
+				const char *, struct wmi_t **);
+static void		acpi_wmi_event_add(struct acpi_wmi_softc *);
+static void		acpi_wmi_event_del(struct acpi_wmi_softc *);
+static void		acpi_wmi_event_handler(ACPI_HANDLE, uint32_t, void *);
+static ACPI_STATUS	acpi_wmi_ec_handler(uint32_t, ACPI_PHYSICAL_ADDRESS,
+				uint32_t, ACPI_INTEGER *, void *, void *);
+static bool		acpi_wmi_suspend(device_t, const pmf_qual_t *);
+static bool		acpi_wmi_resume(device_t, const pmf_qual_t *);
+static ACPI_STATUS	acpi_wmi_enable(ACPI_HANDLE, const char *, bool, bool);
+static bool		acpi_wmi_input(struct wmi_t *, uint8_t, uint8_t);
 
-static ACPI_STATUS acpi_wmi_guid_get(struct acpi_wmi_softc *,
-                                     const char *, struct wmi_t **);
-static void	   acpi_wmi_event_add(struct acpi_wmi_softc *);
-static void	   acpi_wmi_event_del(struct acpi_wmi_softc *);
-static void        acpi_wmi_event_handler(ACPI_HANDLE, uint32_t, void *);
-static bool        acpi_wmi_suspend(device_t, const pmf_qual_t *);
-static bool        acpi_wmi_resume(device_t, const pmf_qual_t *);
-static ACPI_STATUS acpi_wmi_enable(ACPI_HANDLE, const char *, bool, bool);
-static bool        acpi_wmi_input(struct wmi_t *, uint8_t, uint8_t);
-
 const char * const acpi_wmi_ids[] = {
 	"PNP0C14",
 	"pnp0c14",
@@ -104,6 +107,7 @@
 	sc->sc_node = aa->aa_node;
 
 	sc->sc_child = NULL;
+	sc->sc_ecdev = NULL;
 	sc->sc_handler = NULL;
 
 	aprint_naive("\n");
@@ -113,8 +117,8 @@
 		return;
 
 	acpi_wmi_dump(sc);
+	acpi_wmi_init_ec(sc);
 	acpi_wmi_event_add(sc);
-
 	acpi_wmi_rescan(self, NULL, NULL);
 
 	(void)pmf_device_register(self, acpi_wmi_suspend, acpi_wmi_resume);
@@ -127,6 +131,12 @@
 
 	acpi_wmi_event_del(sc);
 
+	if (sc->sc_ecdev != NULL) {
+
+		(void)AcpiRemoveAddressSpaceHandler(sc->sc_node->ad_handle,
+		    ACPI_ADR_SPACE_EC, acpi_wmi_ec_handler);
+	}
+
 	if (sc->sc_child != NULL)
 		(void)config_detach(sc->sc_child, flags);
 
@@ -291,6 +301,36 @@
 	}
 }
 
+static void
+acpi_wmi_init_ec(struct acpi_wmi_softc *sc)
+{
+	ACPI_STATUS rv;
+	deviter_t i;
+	device_t d;
+
+	d = deviter_first(&i, DEVITER_F_ROOT_FIRST);
+
+	for (; d != NULL; d = deviter_next(&i)) {
+
+		if (device_is_a(d, "acpiec") != false ||
+		    device_is_a(d, "acpiecdt") != false) {
+			sc->sc_ecdev = d;
+			break;
+		}
+	}
+
+	deviter_release(&i);
+
+	if (sc->sc_ecdev == NULL)
+		return;
+
+	rv = AcpiInstallAddressSpaceHandler(sc->sc_node->ad_handle,
+	    ACPI_ADR_SPACE_EC, acpi_wmi_ec_handler, NULL, sc);
+
+	if (ACPI_FAILURE(rv))
+		sc->sc_ecdev = NULL;
+}
+
 static ACPI_STATUS
 acpi_wmi_guid_get(struct acpi_wmi_softc *sc,
     const char *src, struct wmi_t **out)
@@ -507,6 +547,38 @@
 acpi_wmi_event_deregister(device_t self)
 {
 	return acpi_wmi_event_register(self, NULL);
+}
+
+/*
+ * Handler for EC regions, which may be embedded in WMI.
+ */
+static ACPI_STATUS
+acpi_wmi_ec_handler(uint32_t func, ACPI_PHYSICAL_ADDRESS addr,
+    uint32_t width, ACPI_INTEGER *val, void *setup, void *aux)
+{
+	struct acpi_wmi_softc *sc = aux;
+
+	if (aux == NULL || val == NULL)
+		return AE_BAD_PARAMETER;
+
+	if (addr > 0xFF || width % 8 != 0)
+		return AE_BAD_ADDRESS;
+
+	switch (func) {
+
+	case ACPI_READ:
+		(void)acpiec_bus_read(sc->sc_ecdev, addr, val, width);
+		break;
+
+	case ACPI_WRITE:
+		(void)acpiec_bus_write(sc->sc_ecdev, addr, *val, width);
+		break;
+
+	default:
+		return AE_BAD_PARAMETER;
+	}
+
+	return AE_OK;
 }
 
 /*

cvs diff -r1.4 -r1.5 src/sys/dev/acpi/wmi/wmi_acpivar.h (expand / switch to context diff)
--- src/sys/dev/acpi/wmi/wmi_acpivar.h 2010/06/05 06:07:12 1.4
+++ src/sys/dev/acpi/wmi/wmi_acpivar.h 2010/10/28 15:55:04 1.5
@@ -1,4 +1,4 @@
-/*	$NetBSD: wmi_acpivar.h,v 1.4 2010/06/05 06:07:12 jruoho Exp $	*/
+/*	$NetBSD: wmi_acpivar.h,v 1.5 2010/10/28 15:55:04 jruoho Exp $	*/
 
 /*-
  * Copyright (c) 2009, 2010 Jukka Ruohonen <jruohonen@iki.fi>
@@ -31,7 +31,7 @@
 #define _SYS_DEV_ACPI_WMI_WMI_ACPIVAR_H
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: wmi_acpivar.h,v 1.4 2010/06/05 06:07:12 jruoho Exp $");
+__KERNEL_RCSID(0, "$NetBSD: wmi_acpivar.h,v 1.5 2010/10/28 15:55:04 jruoho Exp $");
 
 ACPI_STATUS	acpi_wmi_event_register(device_t, ACPI_NOTIFY_HANDLER);
 ACPI_STATUS	acpi_wmi_event_deregister(device_t);
@@ -91,10 +91,11 @@
 };
 
 struct acpi_wmi_softc {
-	device_t		sc_dev;
-	device_t		sc_child;
-	ACPI_NOTIFY_HANDLER	sc_handler;
+	device_t		 sc_dev;
+	device_t		 sc_child;
+	device_t		 sc_ecdev;
 	struct acpi_devnode	*sc_node;
+	ACPI_NOTIFY_HANDLER	 sc_handler;
 
 	SIMPLEQ_HEAD(, wmi_t)	wmi_head;
 };