Module Name:    src
Committed By:   jruoho
Date:           Tue Jan 12 12:21:04 UTC 2010

Modified Files:
        src/sys/dev/acpi: acpi.c

Log Message:
Properly evaluate the _PRW object in case we have a package inside a
package.

ok jmcneill@


To generate a diff of this commit:
cvs rdiff -u -r1.143 -r1.144 src/sys/dev/acpi/acpi.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/dev/acpi/acpi.c
diff -u src/sys/dev/acpi/acpi.c:1.143 src/sys/dev/acpi/acpi.c:1.144
--- src/sys/dev/acpi/acpi.c:1.143	Sat Jan  9 15:43:12 2010
+++ src/sys/dev/acpi/acpi.c	Tue Jan 12 12:21:04 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: acpi.c,v 1.143 2010/01/09 15:43:12 jruoho Exp $	*/
+/*	$NetBSD: acpi.c,v 1.144 2010/01/12 12:21:04 jruoho Exp $	*/
 
 /*-
  * Copyright (c) 2003, 2007 The NetBSD Foundation, Inc.
@@ -70,7 +70,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: acpi.c,v 1.143 2010/01/09 15:43:12 jruoho Exp $");
+__KERNEL_RCSID(0, "$NetBSD: acpi.c,v 1.144 2010/01/12 12:21:04 jruoho Exp $");
 
 #include "opt_acpi.h"
 #include "opt_pcifixup.h"
@@ -1333,29 +1333,61 @@
 static void
 acpi_wake_gpe_helper(ACPI_HANDLE handle, bool enable)
 {
+	ACPI_OBJECT *elm, *obj;
+	ACPI_INTEGER val;
 	ACPI_BUFFER buf;
 	ACPI_STATUS rv;
-	ACPI_OBJECT *p, *elt;
 
 	rv = acpi_eval_struct(handle, METHOD_NAME__PRW, &buf);
+
 	if (ACPI_FAILURE(rv))
-		return;			/* just ignore */
+		return;
+
+	obj = buf.Pointer;
+
+	if (obj->Type != ACPI_TYPE_PACKAGE || obj->Package.Count < 2)
+		goto out;
+
+	/*
+	 * As noted in ACPI 3.0 (section 7.2.10), the _PRW object is
+	 * a package in which the first element is either an integer
+	 * or again a package. In the latter case the package inside
+	 * the package element has two elements, a reference handle
+	 * and the GPE number.
+	 */
+	elm = &obj->Package.Elements[0];
+
+	switch (elm->Type) {
+
+	case ACPI_TYPE_INTEGER:
+		val = elm->Integer.Value;
+		break;
+
+	case ACPI_TYPE_PACKAGE:
+
+		if (elm->Package.Count < 2)
+			goto out;
+
+		if (elm->Package.Elements[0].Type != ACPI_TYPE_LOCAL_REFERENCE)
+			goto out;
+
+		if (elm->Package.Elements[1].Type != ACPI_TYPE_INTEGER)
+			goto out;
 
-	p = buf.Pointer;
-	if (p->Type != ACPI_TYPE_PACKAGE || p->Package.Count < 2)
-		goto out;		/* just ignore */
+		val = elm->Package.Elements[1].Integer.Value;
+		break;
 
-	elt = p->Package.Elements;
+	default:
+		goto out;
+	}
 
-	/* TBD: package support */
 	if (enable) {
-		AcpiSetGpeType(NULL, elt[0].Integer.Value,
-		    ACPI_GPE_TYPE_WAKE_RUN);
-		AcpiEnableGpe(NULL, elt[0].Integer.Value, ACPI_NOT_ISR);
+		(void)AcpiSetGpeType(NULL, val, ACPI_GPE_TYPE_WAKE_RUN);
+		(void)AcpiEnableGpe(NULL, val, ACPI_NOT_ISR);
 	} else
-		AcpiDisableGpe(NULL, elt[0].Integer.Value, ACPI_NOT_ISR);
+		(void)AcpiDisableGpe(NULL, val, ACPI_NOT_ISR);
 
- out:
+out:
 	ACPI_FREE(buf.Pointer);
 }
 

Reply via email to