From owner-acpi-jp@jp.freebsd.org  Sat Oct  7 04:21:56 2000
Received: (from daemon@localhost)
	by castle.jp.freebsd.org (8.9.3+3.2W/8.7.3) id EAA64552;
	Sat, 7 Oct 2000 04:21:56 +0900 (JST)
	(envelope-from owner-acpi-jp@jp.FreeBSD.org)
Received: from tasogare.imasy.or.jp (daemon@tasogare.imasy.or.jp [202.227.24.5])
	by castle.jp.freebsd.org (8.9.3+3.2W/8.7.3) with ESMTP id EAA64546
	for <acpi-jp@jp.freebsd.org>; Sat, 7 Oct 2000 04:21:56 +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.10.2+3.3W/3.7W-tasogare/smtpfeed 1.07) with ESMTP id e96JLrr68464
	for <acpi-jp@jp.freebsd.org>; Sat, 7 Oct 2000 04:21:54 +0900 (JST)
	(envelope-from iwasaki@jp.FreeBSD.org)
To: acpi-jp@jp.freebsd.org
In-Reply-To: <200010061900.e96J0Uh06929@mass.osd.bsdi.com>
References: <20001006235205R.iwasaki@jp.FreeBSD.org>
	<200010061900.e96J0Uh06929@mass.osd.bsdi.com>
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: <20001007042124G.iwasaki@jp.FreeBSD.org>
Date: Sat, 07 Oct 2000 04:21:24 +0900
From: Mitsuru IWASAKI <iwasaki@jp.freebsd.org>
X-Dispatcher: imput version 20000228(IM140)
Lines: 156
Reply-To: acpi-jp@jp.freebsd.org
Precedence: list
X-Distribute: distribute version 2.1 (Alpha) patchlevel 24e+000315
X-Sequence: acpi-jp 808
Subject: [acpi-jp 808] Re: acpi_lid patch 
Errors-To: owner-acpi-jp@jp.freebsd.org
Sender: owner-acpi-jp@jp.freebsd.org
X-Originator: iwasaki@jp.freebsd.org

> > BTW, does anybody woking on Power/Sleep button driver?  If no, I'm
> > going to try it.
> 
> Nobody has said anything to me about it, so I assume not.

OK, I'll try it tomorrow.

Here is the patch for AcpiSetSystemSxState.  With this patch, my main
machine (Chandra2) can transit to S1/S5 perfectly :-)
 - Remove memory allocation code for _WAK result code, not that we use
   auto variable for it.
 - Support S0 (for testing purpose).
 - Add timeout to waiting for WAK_STS bit.  We know we get infinity loop w/o
   this hack on some BIOS.
 - Add _WAK result code checking.

Thanks

Index: hwxface.c
===================================================================
RCS file: /home/iwasaki/cvs/acpica-bsd/contrib/dev/acpica/Subsystem/Hardware/hwxface.c,v
retrieving revision 1.1.1.2
diff -u -r1.1.1.2 hwxface.c
--- hwxface.c	2000/10/05 12:30:40	1.1.1.2
+++ hwxface.c	2000/10/06 18:40:00
@@ -743,16 +743,18 @@
     UINT8                   SleepState)
 {
     UINT8                   Slp_TypA, Slp_TypB;
+    UINT16                  Count;
     ACPI_STATUS             Status;
     ACPI_OBJECT_LIST        Arg_list;
     ACPI_OBJECT             Arg;
+    ACPI_OBJECT             Objects[3];	/* package plus 2 number objects */
     ACPI_BUFFER             ReturnBuffer;
 
     FUNCTION_TRACE ("AcpiSetSystemSxState");
 
     Slp_TypA = Slp_TypB = 0;
 
-    if ((SleepState != ACPI_STATE_S1) && (SleepState != ACPI_STATE_S5))
+    if (SleepState > ACPI_STATE_S5)
     {
         return_ACPI_STATUS (AE_BAD_PARAMETER);
     }
@@ -763,15 +765,6 @@
         return_ACPI_STATUS (Status);
     }
 
-    /* 
-     * _WAK result code is 2 Dword package (48 bytes)
-     */
-    ReturnBuffer.Length = 48;
-    if ((ReturnBuffer.Pointer = AcpiCmAllocate (ReturnBuffer.Length)) == NULL) 
-    {
-        return_ACPI_STATUS (AE_NO_MEMORY);
-    }
-
     /*
      * The value for ACPI_STATE_S5 is not 5 actually, so adjust it.
      */
@@ -805,16 +798,34 @@
     AcpiHwRegisterAccess (ACPI_WRITE, ACPI_MTX_DO_NOT_LOCK, SLP_TYPE_B, Slp_TypB);
     AcpiHwRegisterAccess (ACPI_WRITE, ACPI_MTX_DO_NOT_LOCK, SLP_EN, 1);
 
+    /* if S0, we don't wait for WAK_STS bit. */
+    if (SleepState == ACPI_STATE_S0)
+    {
+        goto wakeup;
+    }
+
     /*
      * Wait for WAK_STS bit
      */
+    Count = 0;
     while (!(AcpiHwRegisterAccess (ACPI_READ, ACPI_MTX_DO_NOT_LOCK, WAK_STS)))
     {
 #if 1
         AcpiOsSleepUsec(1000);	/* should we have OsdFunc for sleep or halt? */
 #endif
+        /*
+         * Some BIOSes doesn't set WAK_STS at all,
+         * give up waiting for wakeup if timeout...
+         */
+        if (Count > 1000)
+        {
+            break;		/* giving up */
+        }
+        Count++;
     }
 
+wakeup:
+
     /*
      * Evaluate the _WAK method
      */
@@ -826,11 +837,57 @@
     Arg.Type = ACPI_TYPE_NUMBER;
     Arg.Number.Value = SleepState;
 
+    /* Set up _WAK result code buffer */
+    MEMSET(Objects, 0, sizeof(Objects));
+    ReturnBuffer.Length = sizeof(Objects);
+    ReturnBuffer.Pointer = Objects;
+
     AcpiEvaluateObject (NULL, "\\_WAK", &Arg_list, &ReturnBuffer);
 
-    /* TODO: check result code here */
+    Status = AE_OK;
+    /* Check result code fo _WAK */
+    if (Objects[0].Type != ACPI_TYPE_PACKAGE ||
+        Objects[1].Type != ACPI_TYPE_NUMBER  ||
+        Objects[2].Type != ACPI_TYPE_NUMBER)
+    {
+        /*
+         * In many BIOSes, _WAK don't have result code actually.
+         * We don't need to warry about it too much :-).
+         */
+        DEBUG_PRINT (ACPI_INFO,
+            ("AcpiSetSystemSleepState: _WAK result code is corrupted, "
+             "but should be OK.\n"));
+    }
 
-    AcpiCmFree(ReturnBuffer.Pointer);
+    else
+    {
+        /* evaluate status code */
+        switch (Objects[1].Number.Value)
+        {
+        case 0x00000001:
+            DEBUG_PRINT (ACPI_ERROR,
+                ("AcpiSetSystemSleepState: Wake was signaled but failed "
+                 "due to lack of power.\n"));
+            Status = AE_ERROR;
+            break;
+
+        case 0x00000002:
+            DEBUG_PRINT (ACPI_ERROR,
+                ("AcpiSetSystemSleepState: Wake was signaled but failed "
+                 "due to thermal condition.\n"));
+            Status = AE_ERROR;
+            break;
+        }
+        /* evaluate PSS code */
+        if (Objects[2].Number.Value == 0)
+        {
+            DEBUG_PRINT (ACPI_ERROR,
+                ("AcpiSetSystemSleepState: The targeted S-state was not "
+                 "entered because of too much current being drawn from "
+                 "the power supply.\n"));
+            Status = AE_ERROR;
+        }
+    }
 
     return_ACPI_STATUS (Status);
 }
