From owner-acpi-jp@jp.freebsd.org  Fri Oct 13 00:49:55 2000
Received: (from daemon@localhost)
	by castle.jp.freebsd.org (8.9.3+3.2W/8.7.3) id AAA51646;
	Fri, 13 Oct 2000 00:49:55 +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 AAA51641
	for <acpi-jp@jp.freebsd.org>; Fri, 13 Oct 2000 00:49:53 +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 e9CFnlr13604;
	Fri, 13 Oct 2000 00:49:47 +0900 (JST)
	(envelope-from iwasaki@jp.FreeBSD.org)
To: andrew.grover@intel.com
Cc: 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: <20001013004946N.iwasaki@jp.FreeBSD.org>
Date: Fri, 13 Oct 2000 00:49:46 +0900
From: Mitsuru IWASAKI <iwasaki@jp.freebsd.org>
X-Dispatcher: imput version 20000228(IM140)
Lines: 489
Reply-To: acpi-jp@jp.freebsd.org
Precedence: list
X-Distribute: distribute version 2.1 (Alpha) patchlevel 24e+000315
X-Sequence: acpi-jp 855
Subject: [acpi-jp 855] ACPICA proposal: new OSI functions
Errors-To: owner-acpi-jp@jp.freebsd.org
Sender: owner-acpi-jp@jp.freebsd.org
X-Originator: iwasaki@jp.freebsd.org

Hi, Andrew

I wrote new ACPICA OSI functions for controlling ACPI events generation
and system mode.  I'd like to propose that these are incorporated into
ACPICA APIs.

Mike wrote:
> > Calling acpi_Disable() from acpi_shutdown_pre_sync() is mandatory for
> > some machines.  We know that GPE events prevent the system from power off,
> > I have one machine which have this problem.  Without this code, the
> > system is immediately turned on again and start booting :-(  The older
> > driver has this work around.  Also we probably need event handler cleanup
> > around here.
> 
> I'm no so sure about this.  I think that the shutdown_final handler 
> should probably just mask all the GPE's at the last moment.  It would be 
> interesting to know, however, what other people (I'm thinking Windows 
> here) are doing...

To solve this problem, I'm going to stop ACPI evnet (especially GPE)
generation at the last moment.  For now there is no way to obtain the
list of events which are currently enabled.  we can record fixed-event 
when we enable it, but GPE.  So I create two functions for this purpose.

AcpiGetFixedEventsEnabled():	Obtains and returns the current enabled fixed-events
AcpiGetGpeEventsEnabled():	Obtains and returns the current enabled GPE events

The following is for controlling multiple ACPI events.  These
functions will call existing Acpi{Enable|Disable}Event and can make
driver side code in minimum.

AcpiEnableFixedEvents():	Enable an ACPI fixed events
AcpiDisableFixedEvents():	Disable ACPI fixed events
AcpiEnableGpeEvents():		Enable ACPI GPE events
AcpiDisableGpeEvents():		Disable ACPI GPE events


And some more;
> > >	- apm (probe and suspend)	NG
> > >		apm was not probed at boot time :-<
> > 
> > Shall we change probe order : apm then acpi and if apm is probed,
> > disable apm and don't enable until acpi is disabled.
> 
> Hmmm, I'm sure we were able to co-exist apm and acpi with older code.

It seems that ACPI initialization prevent apm device drivers from
probing during boot process, so we want to set the system mode to
LEGACY mode explicitly.  Please note that it's not original mode
(means we cannot use AcpiDisable() to initialize APM).
I wrote wrapper functions of AcpiHw[SG]etMode().

AcpiSetMode():			Transitions the system into the requested mode
AcpiGetMode():			Return current operating state of system

How about my proposal above?  Is it reasonable?

Regards,

Index: Subsystem/Events/evxfevnt.c
===================================================================
RCS file: /home/iwasaki/cvs/acpica-bsd/contrib/dev/acpica/Subsystem/Events/evxfevnt.c,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 evxfevnt.c
--- Subsystem/Events/evxfevnt.c	2000/10/04 03:00:39	1.1.1.1
+++ Subsystem/Events/evxfevnt.c	2000/10/11 14:33:27
@@ -320,6 +320,98 @@
 
 /******************************************************************************
  *
+ * FUNCTION:    AcpiEnableFixedEvents
+ *
+ * PARAMETERS:  Events          - The bitmap of fixed events to be enabled
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Enable an ACPI fixed events
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiEnableFixedEvents (
+    UINT32                  Events)
+{
+    UINT32                  Event;
+
+
+    FUNCTION_TRACE ("AcpiEnableFixedEvents");
+
+    /* Ensure that we have valid fxied-events */
+    if ((Events >> ACPI_EVENT_NOT_USED) & 0x00000001 ||
+        (Events >> ACPI_EVENT_GENERAL) & 0x00000001)
+    {
+        return_ACPI_STATUS (AE_BAD_PARAMETER);
+    }
+
+    /* Decode the Fixed AcpiEvents */
+    for (Event = 0; Event < NUM_FIXED_EVENTS; Event++)
+    {
+        if ((Events >> Event) & 0x00000001)
+        {
+            if (ACPI_FAILURE(AcpiEnableEvent(Event, ACPI_EVENT_FIXED)))
+            {
+                return_ACPI_STATUS (AE_ERROR);
+            }
+        }
+    }
+
+    return_ACPI_STATUS (AE_OK);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION:    AcpiEnableGpeEvents
+ *
+ * PARAMETERS:  GpeEvents       - The array of GPE events to be enabled
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Enable ACPI GPE events
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiEnableGpeEvents (
+    UINT8                   GpeEvents[])
+{
+    UINT32                  Event;
+
+    FUNCTION_TRACE ("AcpiEnableGpeEvents");
+
+    /* Ensure that we have valid GPE numbers */
+    for (Event = 0; Event < NUM_GPE; Event++)
+    {
+        
+        if (GpeEvents[Event] == 1 && AcpiGbl_GpeValid[Event] == ACPI_GPE_INVALID)
+        {
+            return_ACPI_STATUS (AE_BAD_PARAMETER);
+        }
+    }
+
+    /* Decode the GPE AcpiEvents */
+    for (Event = 0; Event < NUM_GPE; Event++)
+    {
+        if (GpeEvents[Event] == 0)
+        {
+            continue;
+        }
+
+        if (ACPI_FAILURE(AcpiEnableEvent(Event, ACPI_EVENT_GPE)))
+        {
+            return_ACPI_STATUS (AE_ERROR);
+        }
+    }
+
+    return_ACPI_STATUS (AE_OK);
+}
+
+
+/******************************************************************************
+ *
  * FUNCTION:    AcpiDisableEvent
  *
  * PARAMETERS:  Event           - The fixed event or GPE to be enabled
@@ -414,6 +506,97 @@
 
 /******************************************************************************
  *
+ * FUNCTION:    AcpiDisableFixedEvents
+ *
+ * PARAMETERS:  Events          - The bitmap of fixed events to be disabled
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Disable ACPI fixed events
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiDisableFixedEvents (
+    UINT32                  Events)
+{
+    UINT32                  Event;
+
+
+    FUNCTION_TRACE ("AcpiDisableFixedEvents");
+
+    /* Ensure that we have valid fxied-events */
+    if ((Events >> ACPI_EVENT_NOT_USED) & 0x00000001 ||
+        (Events >> ACPI_EVENT_GENERAL) & 0x00000001)
+    {
+        return_ACPI_STATUS (AE_BAD_PARAMETER);
+    }
+
+    /* Decode the Fixed AcpiEvents */
+    for (Event = 0; Event < NUM_FIXED_EVENTS; Event++)
+    {
+        if ((Events >> Event) & 0x00000001)
+        {
+            if (ACPI_FAILURE(AcpiDisableEvent(Event, ACPI_EVENT_FIXED)))
+            {
+                return_ACPI_STATUS (AE_ERROR);
+            }
+        }
+    }
+
+    return_ACPI_STATUS (AE_OK);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION:    AcpiDisableGpeEvents
+ *
+ * PARAMETERS:  GpeEvents       - The array of GPE events to be enabled
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Disable ACPI GPE events
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiDisableGpeEvents (
+    UINT8                   GpeEvents[])
+{
+    UINT32                  Event;
+
+    FUNCTION_TRACE ("AcpiDisableGpeEvents");
+
+    /* Ensure that we have valid GPE numbers */
+    for (Event = 0; Event < NUM_GPE; Event++)
+    {
+        
+        if (GpeEvents[Event] == 1 && AcpiGbl_GpeValid[Event] == ACPI_GPE_INVALID)
+        {
+            return_ACPI_STATUS (AE_BAD_PARAMETER);
+        }
+    }
+
+    /* Decode the GPE AcpiEvents */
+    for (Event = 0; Event < NUM_GPE; Event++)
+    {
+        if (GpeEvents[Event] == 0)
+        {
+            continue;
+        }
+
+        if (ACPI_FAILURE(AcpiDisableEvent(Event, ACPI_EVENT_GPE)))
+        {
+            return_ACPI_STATUS (AE_ERROR);
+        }
+    }
+
+    return_ACPI_STATUS (AE_OK);
+}
+
+/******************************************************************************
+ *
  * FUNCTION:    AcpiClearEvent
  *
  * PARAMETERS:  Event           - The fixed event or GPE to be cleared
@@ -606,5 +789,96 @@
 
 
     return_ACPI_STATUS (Status);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION:    AcpiGetFixedEventsEnabled
+ *
+ * PARAMETERS:  Events          - The bitmap of fixed events to be returned
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Obtains and returns the current enabled fixed-events
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiGetFixedEventsEnabled (
+    UINT32                  *Events)
+{
+    UINT32                  Event;
+    ACPI_EVENT_STATUS       EventStatus;
+
+
+    FUNCTION_TRACE ("AcpiGetFixedEventsEnabled");
+
+
+    *Events = 0;
+    for (Event = 0; Event < NUM_FIXED_EVENTS; Event++)
+    {
+        /* Skip invalid fixed event */
+        if (Event == ACPI_EVENT_NOT_USED || Event == ACPI_EVENT_GENERAL)
+        {
+            continue;
+        }
+
+        if (ACPI_FAILURE(AcpiGetEventStatus(Event, ACPI_EVENT_FIXED, &EventStatus)))
+        {
+            return_ACPI_STATUS (AE_ERROR);
+        }
+
+        if (EventStatus & ACPI_EVENT_FLAG_ENABLED)
+        {
+            *Events |= 1 << Event;
+        }
+    }
+
+    return_ACPI_STATUS (AE_OK);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION:    AcpiGetGpeEventsEnabled
+ *
+ * PARAMETERS:  GpeEvents       - The array of GPE events to be returned
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Obtains and returns the current enabled GPE events
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiGetGpeEventsEnabled (
+    UINT8                   GpeEvents[])
+{
+    UINT32                  Event;
+    ACPI_EVENT_STATUS       EventStatus;
+
+    FUNCTION_TRACE ("AcpiGetGpeEventsEnabled");
+
+    for (Event = 0; Event < NUM_GPE; Event++)
+    {
+        /* Clear the element of the GPE events array */
+        GpeEvents[Event] = 0;
+
+        /* Skip invalid GPE numbers */
+        if (AcpiGbl_GpeValid[Event] == ACPI_GPE_INVALID)
+        {
+            continue;
+        }
+
+        if (ACPI_FAILURE(AcpiGetEventStatus(Event, ACPI_EVENT_GPE, &EventStatus)))
+        {
+            return_ACPI_STATUS (AE_ERROR);
+        }
+
+        GpeEvents[Event] = EventStatus & ACPI_EVENT_FLAG_ENABLED;
+    }
+
+    return_ACPI_STATUS (AE_OK);
 }
 
Index: Subsystem/Hardware/hwxface.c
===================================================================
RCS file: /home/iwasaki/cvs/acpica-bsd/contrib/dev/acpica/Subsystem/Hardware/hwxface.c,v
retrieving revision 1.1.1.3
diff -u -r1.1.1.3 hwxface.c
--- Subsystem/Hardware/hwxface.c	2000/10/08 13:50:14	1.1.1.3
+++ Subsystem/Hardware/hwxface.c	2000/10/11 17:17:35
@@ -894,3 +894,57 @@
     return_ACPI_STATUS (Status);
 }
 
+/******************************************************************************
+ *
+ * FUNCTION:    AcpiSetMode
+ *
+ * PARAMETERS:  Mode            - SYS_MODE_ACPI or SYS_MODE_LEGACY
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Transitions the system into the requested mode or does nothing
+ *              if the system is already in that mode.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiSetMode (
+    UINT32                  Mode)
+{
+
+    ACPI_STATUS             Status = AE_OK;
+
+    FUNCTION_TRACE ("AcpiSetMode");
+
+    if (AcpiHwGetMode () != Mode)
+    {
+        Status = AcpiHwSetMode (Mode);
+    }
+
+    return_ACPI_STATUS (Status);
+}
+
+
+/******************************************************************************
+ *
+ * FUNCTION:    AcpiGetMode
+ *
+ * PARAMETERS:  none
+ *
+ * RETURN:      SYS_MODE_ACPI or SYS_MODE_LEGACY
+ *
+ * DESCRIPTION: Return current operating state of system.  Determined by
+ *              querying the SCI_EN bit.
+ *
+ ******************************************************************************/
+
+UINT32
+AcpiGetMode (void)
+{
+
+    FUNCTION_TRACE ("AcpiGetMode");
+
+
+    return_VALUE (AcpiHwGetMode());
+}
+
Index: Subsystem/Include/acpixf.h
===================================================================
RCS file: /home/iwasaki/cvs/acpica-bsd/contrib/dev/acpica/Subsystem/Include/acpixf.h,v
retrieving revision 1.1.1.3
diff -u -r1.1.1.3 acpixf.h
--- Subsystem/Include/acpixf.h	2000/10/05 12:30:41	1.1.1.3
+++ Subsystem/Include/acpixf.h	2000/10/11 17:17:09
@@ -308,11 +308,27 @@
     UINT32                  Type);
 
 ACPI_STATUS
+AcpiEnableFixedEvents (
+    UINT32                  Events);
+
+ACPI_STATUS
+AcpiEnableGpeEvents (
+    UINT8                   GpeEvents[]);
+
+ACPI_STATUS
 AcpiDisableEvent (
     UINT32                  AcpiEvent,
     UINT32                  Type);
 
 ACPI_STATUS
+AcpiDisableFixedEvents (
+    UINT32                  Events);
+
+ACPI_STATUS
+AcpiDisableGpeEvents (
+    UINT8                   GpeEvents[]);
+
+ACPI_STATUS
 AcpiClearEvent (
     UINT32                  AcpiEvent,
     UINT32                  Type);
@@ -323,6 +339,14 @@
     UINT32                  Type,
     ACPI_EVENT_STATUS       *EventStatus);
 
+ACPI_STATUS
+AcpiGetFixedEventsEnabled (
+    UINT32                  *Events);
+
+ACPI_STATUS
+AcpiGetGpeEventsEnabled (
+    UINT8                   GpeEvents[]);
+
 /*
  * Resource interfaces
  */
@@ -393,5 +417,13 @@
 ACPI_STATUS
 AcpiSetSystemSleepState (
     UINT8                   SleepState);
+
+ACPI_STATUS
+AcpiSetMode (
+    UINT32                  Mode);
+
+UINT32
+AcpiGetMode (
+    void);
 
 #endif /* __ACXFACE_H__ */
