From owner-acpi-jp@jp.freebsd.org  Sun Aug 12 15:58:33 2001
Received: (from daemon@localhost)
	by castle.jp.freebsd.org (8.9.3+3.2W/8.7.3) id PAA91580;
	Sun, 12 Aug 2001 15:58:33 +0900 (JST)
	(envelope-from owner-acpi-jp@jp.FreeBSD.org)
Received: from tasogare.imasy.or.jp (root@tasogare.imasy.or.jp [202.227.24.5])
	by castle.jp.freebsd.org (8.9.3+3.2W/8.7.3) with ESMTP id PAA91575
	for <acpi-jp@jp.freebsd.org>; Sun, 12 Aug 2001 15:58:32 +0900 (JST)
	(envelope-from iwasaki@jp.FreeBSD.org)
Received: from localhost (iwasaki.imasy.or.jp [202.227.24.92])
	by tasogare.imasy.or.jp (8.11.3+3.4W/8.11.3/tasogare) with ESMTP/inet id f7C6wUI33224
	for <acpi-jp@jp.freebsd.org>; Sun, 12 Aug 2001 15:58:30 +0900 (JST)
	(envelope-from iwasaki@jp.FreeBSD.org)
To: acpi-jp@jp.freebsd.org
In-Reply-To: <200108081011.f78ABeZ02383@mass.dis.org>
References: <20010808011912H.iwasaki@jp.FreeBSD.org>
	<200108081011.f78ABeZ02383@mass.dis.org>
X-Mailer: Mew version 1.94.1 on Emacs 19.34 / Mule 2.3 (SUETSUMUHANA)
Mime-Version: 1.0
Content-Type: Text/Plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
Message-Id: <20010812155830A.iwasaki@jp.FreeBSD.org>
Date: Sun, 12 Aug 2001 15:58:30 +0900
From: Mitsuru IWASAKI <iwasaki@jp.freebsd.org>
X-Dispatcher: imput version 20000228(IM140)
Lines: 97
Reply-To: acpi-jp@jp.freebsd.org
Precedence: list
X-Distribute: distribute version 2.1 (Alpha) patchlevel 24e+010328
X-Sequence: acpi-jp 1223
Subject: [acpi-jp 1223] Re: ACPICA 20010717: S1 causes power-off 
Errors-To: owner-acpi-jp@jp.freebsd.org
Sender: owner-acpi-jp@jp.freebsd.org
X-Originator: iwasaki@jp.freebsd.org

Hi, mike.

> > One of my laptops needs this patch.
> 
> This is no good; my logic is wrong.  It is OK to not have _PR3/_PS3 if we 
> have _PR0 - we can turn off the resources listed in _PR0 to go to D3.
> 
> I think something like:
> 
>      if ((reslist_handle == NULL) && (method_handle == NULL)) {
>          if (state == ACPI_STATE_D0) {
>              pc->ac_state = ACPI_STATE_D0;
>              return_ACPI_STATUS(AE_OK);
>          }
>      if ((state != ACPI_STATE_D3) ||
>          (TAILQ_FIRST(&pc->ac_references) != NULL)) {
>          DEBUG_PRINT(TRACE_OBJECTS, ("attempt to set unsupported state D%d\n", 
>                                      state));
>          return_ACPI_STATUS(AE_BAD_PARAMETER);
>      }
> 
> This still isn't perfect, as it will fail if the device is already off.
> Better code would check for _PR0 rather than looking at the head of the
> references list.  If you could, I'd prefer you to commit something that 
> did that...

OK, I've made diffs based on your comment, and will commit this within
a few days.

Thanks

Index: acpi_powerres.c
===================================================================
RCS file: /home/ncvs/src/sys/dev/acpica/acpi_powerres.c,v
retrieving revision 1.5
diff -u -r1.5 acpi_powerres.c
--- acpi_powerres.c	2001/07/21 10:24:32	1.5
+++ acpi_powerres.c	2001/08/12 06:04:24
@@ -299,7 +300,7 @@
 {
     struct acpi_powerconsumer	*pc;
     struct acpi_powerreference	*pr;
-    ACPI_HANDLE			method_handle, reslist_handle;
+    ACPI_HANDLE			method_handle, reslist_handle, pr0_handle;
     ACPI_BUFFER			reslist_buffer;
     ACPI_OBJECT			*reslist_object;
     ACPI_STATUS			status;
@@ -355,6 +356,7 @@
      * support D0 and D3.  It's never an error to try to go to
      * D0.
      */
+    reslist_object = NULL;
     if (AcpiGetHandle(consumer, method_name, &method_handle) != AE_OK)
 	method_handle = NULL;
     if (AcpiGetHandle(consumer, reslist_name, &reslist_handle) != AE_OK)
@@ -364,9 +366,24 @@
 	    pc->ac_state = ACPI_STATE_D0;
 	    return_ACPI_STATUS(AE_OK);
 	}
-	DEBUG_PRINT(TRACE_OBJECTS, ("attempt to set unsupported state D%d\n", 
-				    state));
-	return_ACPI_STATUS(AE_BAD_PARAMETER);
+	if (state != ACPI_STATE_D3) {
+	    goto bad;
+	}
+
+	/* turn off the resources listed in _PR0 to go to D3. */
+	if (AcpiGetHandle(consumer, "_PR0", &pr0_handle) != AE_OK) {
+	    goto bad;
+	}
+	status = acpi_EvaluateIntoBuffer(pr0_handle, NULL, NULL, &reslist_buffer);
+	if (status != AE_OK) {
+	    goto bad;
+	}
+	reslist_object = (ACPI_OBJECT *)reslist_buffer.Pointer;
+	if ((reslist_object->Type != ACPI_TYPE_PACKAGE) ||
+	    (reslist_object->Package.Count == 0)) {
+	    goto bad;
+	}
+	AcpiOsFree(reslist_object);
     }
 
     /*
@@ -434,6 +451,13 @@
     /* transition was successful */
     pc->ac_state = state;
     return_ACPI_STATUS(AE_OK);
+
+ bad:
+    DEBUG_PRINT(TRACE_OBJECTS, ("attempt to set unsupported state D%d\n", 
+		state));
+    if (reslist_object)
+	AcpiOsFree(reslist_object);
+    return_ACPI_STATUS(AE_BAD_PARAMETER);
 }
 
 /*
