From owner-acpi-jp@jp.freebsd.org  Wed Mar  7 00:38:24 2001
Received: (from daemon@localhost)
	by castle.jp.freebsd.org (8.9.3+3.2W/8.7.3) id AAA27610;
	Wed, 7 Mar 2001 00:38:24 +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 AAA27605
	for <acpi-jp@jp.freebsd.org>; Wed, 7 Mar 2001 00:38:24 +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.2+3.4W/3.7W-tasogare/smtpfeed 1.10) with ESMTP id f26FcJW01230
	for <acpi-jp@jp.freebsd.org>; Wed, 7 Mar 2001 00:38:19 +0900 (JST)
	(envelope-from iwasaki@jp.FreeBSD.org)
To: acpi-jp@jp.freebsd.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: <20010307003818M.iwasaki@jp.FreeBSD.org>
Date: Wed, 07 Mar 2001 00:38:18 +0900
From: Mitsuru IWASAKI <iwasaki@jp.freebsd.org>
X-Dispatcher: imput version 20000228(IM140)
Lines: 116
Reply-To: acpi-jp@jp.freebsd.org
Precedence: list
X-Distribute: distribute version 2.1 (Alpha) patchlevel 24e+000315
X-Sequence: acpi-jp 1086
Subject: [acpi-jp 1086] fix for sys/dev/acpica/acpi.c (AcpiEnterSleepState related)
Errors-To: owner-acpi-jp@jp.freebsd.org
Sender: owner-acpi-jp@jp.freebsd.org
X-Originator: iwasaki@jp.freebsd.org

I've noticed that our recent acpi driver doesn't evaluate \_WAK when
the system wakeup from sleep state.  I guess that we forgot to move
our local hack on this when AcpiEnterSleepState() added to ACPICA.

Here is the patch for it.  I'll commit this at tomorrow night.

Index: acpi.c
===================================================================
RCS file: /home/ncvs/src/sys/dev/acpica/acpi.c,v
retrieving revision 1.12
diff -u -r1.12 acpi.c
--- acpi.c	2001/01/31 09:30:57	1.12
+++ acpi.c	2001/03/05 22:09:05
@@ -765,6 +765,92 @@
     return(buf);
 }
 
+static ACPI_STATUS __inline
+acpi_wakeup(UINT8 state)
+{
+	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_U32(__FUNCTION__, state);
+
+	/* wait for the WAK_STS bit */
+	Count = 0;
+	while (!(AcpiHwRegisterBitAccess(ACPI_READ, ACPI_MTX_LOCK, WAK_STS))) {
+		AcpiOsSleepUsec(1000);
+		/*
+		 * Some BIOSes don't set WAK_STS at all,
+		 * give up waiting for wakeup if we time out.
+		 */
+		if (Count > 1000) {
+			break;	/* giving up */
+		}
+		Count++;
+	}
+
+	/*
+	 * Evaluate the _WAK method
+	 */
+	MEMSET(&Arg_list, 0, sizeof(Arg_list));
+	Arg_list.Count = 1;
+	Arg_list.Pointer = &Arg;
+
+	MEMSET(&Arg, 0, sizeof(Arg));
+	Arg.Type = ACPI_TYPE_INTEGER;
+	Arg.Integer.Value = state;
+
+	/* Set up _WAK result code buffer */
+	MEMSET(Objects, 0, sizeof(Objects));
+	ReturnBuffer.Length = sizeof(Objects);
+	ReturnBuffer.Pointer = Objects;
+
+	AcpiEvaluateObject (NULL, "\\_WAK", &Arg_list, &ReturnBuffer);
+
+	Status = AE_OK;
+	/* Check result code for _WAK */
+	if (Objects[0].Type != ACPI_TYPE_PACKAGE ||
+	    Objects[1].Type != ACPI_TYPE_INTEGER  ||
+	    Objects[2].Type != ACPI_TYPE_INTEGER) {
+		/*
+		 * In many BIOSes, _WAK doesn't return a result code.
+		 * We don't need to worry about it too much :-).
+		 */
+		DEBUG_PRINT (ACPI_INFO,
+		    ("acpi_wakeup: _WAK result code is corrupted, "
+		     "but should be OK.\n"));
+	} else {
+		/* evaluate status code */
+		switch (Objects[1].Integer.Value) {
+		case 0x00000001:
+			DEBUG_PRINT (ACPI_ERROR,
+			    ("acpi_wakeup: Wake was signaled "
+			     "but failed due to lack of power.\n"));
+			Status = AE_ERROR;
+			break;
+
+		case 0x00000002:
+			DEBUG_PRINT (ACPI_ERROR,
+			    ("acpi_wakeup: Wake was signaled "
+			     "but failed due to thermal condition.\n"));
+			Status = AE_ERROR;
+			break;
+		}
+		/* evaluate PSS code */
+		if (Objects[2].Integer.Value == 0) {
+			DEBUG_PRINT (ACPI_ERROR,
+			    ("acpi_wakeup: 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);
+}
+
 /*
  * Set the system sleep state
  *
@@ -804,7 +890,9 @@
 	status = AcpiEnterSleepState((UINT8)state);
 	if (status != AE_OK) {
 	    device_printf(sc->acpi_dev, "AcpiEnterSleepState failed - %s\n", acpi_strerror(status));
+	    break;
 	}
+	acpi_wakeup((UINT8)state);
 	DEVICE_RESUME(root_bus);
 	sc->acpi_sstate = ACPI_STATE_S0;
 	acpi_enable_fixed_events(sc);
