Author: cgutman
Date: Thu Mar 25 15:19:54 2010
New Revision: 46442
URL: http://svn.reactos.org/svn/reactos?rev=46442&view=rev
Log:
[ACPI]
- Add support for fixed power buttons
- Cleanup some extra junk
- Add a hack to prevent acquiring the mutex while in an ISR or DPC
- Button events are received now and "acpi_bus_generate_event" will appear in the debug log when a power/sleep button is pressed
- TODO: Implement IOCTL_GET_SYS_BUTTON_EVENT support so the power manager can recognize our button presses
Modified:
trunk/reactos/drivers/bus/acpi/busmgr/bus.c
trunk/reactos/drivers/bus/acpi/busmgr/button.c
trunk/reactos/drivers/bus/acpi/include/acpi_bus.h
trunk/reactos/drivers/bus/acpi/main.c
trunk/reactos/drivers/bus/acpi/osl.c
Modified: trunk/reactos/drivers/bus/acpi/busmgr/bus.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/bus/acpi/busmgr/bu…
==============================================================================
--- trunk/reactos/drivers/bus/acpi/busmgr/bus.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/bus/acpi/busmgr/bus.c [iso-8859-1] Thu Mar 25 15:19:54 2010
@@ -1262,9 +1262,15 @@
hid = ACPI_THERMAL_HID;
break;
case ACPI_BUS_TYPE_POWER_BUTTON:
+ hid = ACPI_BUTTON_HID_POWER;
+ break;
+ case ACPI_BUS_TYPE_POWER_BUTTONF:
hid = ACPI_BUTTON_HID_POWERF;
break;
case ACPI_BUS_TYPE_SLEEP_BUTTON:
+ hid = ACPI_BUTTON_HID_SLEEP;
+ break;
+ case ACPI_BUS_TYPE_SLEEP_BUTTONF:
hid = ACPI_BUTTON_HID_SLEEPF;
break;
}
@@ -1326,7 +1332,9 @@
*/
switch (type) {
case ACPI_BUS_TYPE_POWER_BUTTON:
+ case ACPI_BUS_TYPE_POWER_BUTTONF:
case ACPI_BUS_TYPE_SLEEP_BUTTON:
+ case ACPI_BUS_TYPE_SLEEP_BUTTONF:
break;
default:
status = AcpiAttachData(device->handle,
@@ -1530,16 +1538,40 @@
if (!root)
return_VALUE(AE_NOT_FOUND);
- /*
- * Enumerate all fixed-feature devices.
+ /* If ACPI_FADT_POWER_BUTTON is set, then a control
+ * method power button is present. Otherwise, a fixed
+ * power button is present.
*/
if (AcpiGbl_FADT.Flags & ACPI_FADT_POWER_BUTTON)
result = acpi_bus_add(&device, acpi_root,
NULL, ACPI_BUS_TYPE_POWER_BUTTON);
-
+ else
+ {
+ /* Enable the fixed power button so we get notified if it is pressed */
+ AcpiWriteBitRegister(ACPI_BITREG_POWER_BUTTON_ENABLE, 1);
+
+ result = acpi_bus_add(&device, acpi_root,
+ NULL, ACPI_BUS_TYPE_POWER_BUTTONF);
+ }
+
+ /* This one is a bit more complicated and we do it wrong
+ * right now. If ACPI_FADT_SLEEP_BUTTON is set but no
+ * device object is present then no sleep button is present, but
+ * if the flags is clear and there is no device object then it is
+ * a fixed sleep button. If the flag is set and there is a device object
+ * the we have a control method button just like above.
+ */
if (AcpiGbl_FADT.Flags & ACPI_FADT_SLEEP_BUTTON)
result = acpi_bus_add(&device, acpi_root,
NULL, ACPI_BUS_TYPE_SLEEP_BUTTON);
+ else
+ {
+ /* Enable the fixed sleep button so we get notified if it is pressed */
+ AcpiWriteBitRegister(ACPI_BITREG_SLEEP_BUTTON_ENABLE, 1);
+
+ result = acpi_bus_add(&device, acpi_root,
+ NULL, ACPI_BUS_TYPE_SLEEP_BUTTONF);
+ }
return_VALUE(result);
}
@@ -1548,120 +1580,6 @@
/* --------------------------------------------------------------------------
Initialization/Cleanup
-------------------------------------------------------------------------- */
-
-static int
-acpi_bus_init_irq (void)
-{
- ACPI_STATUS status = AE_OK;
- ACPI_OBJECT arg = {ACPI_TYPE_INTEGER};
- ACPI_OBJECT_LIST arg_list = {1, &arg};
- //char *message = NULL;
-
- DPRINT("acpi_bus_init_irq");
-
- /*
- * Let the system know what interrupt model we are using by
- * evaluating the \_PIC object, if exists.
- */
-
- //switch (acpi_irq_model) {
- //case ACPI_IRQ_MODEL_PIC:
- // message = "PIC";
- // break;
- //case ACPI_IRQ_MODEL_IOAPIC:
- // message = "IOAPIC";
- // break;
- //case ACPI_IRQ_MODEL_IOSAPIC:
- // message = "IOSAPIC";
- // break;
- //default:
- // DPRINT1("Unknown interrupt routing model\n");
- // return_VALUE(AE_NOT_FOUND);
- //}
-
- //DPRINT("Using %s for interrupt routing\n", message);
-
- //arg.Integer.Value = acpi_irq_model;
-
- //status = AcpiEvaluateObject(NULL, "\\_PIC", &arg_list, NULL);
- //if (ACPI_FAILURE(status) && (status != AE_NOT_FOUND)) {
- // ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error evaluating _PIC\n"));
- // return_VALUE(AE_NOT_FOUND);
- //}
-
- return_VALUE(0);
-}
-
-
-//void
-//acpi_early_init (void)
-//{
-// ACPI_STATUS status = AE_OK;
-//
-// DPRINT("acpi_early_init");
-//
-// if (acpi_disabled)
-// return_VOID;
-//
- /* enable workarounds, unless strict ACPI spec. compliance */
-// if (!acpi_strict)
-// acpi_gbl_enable_interpreter_slack = TRUE;
-//
-// status = acpi_reallocate_root_table();
-// if (ACPI_FAILURE(status)) {
-// printk(KERN_ERR PREFIX
-// "Unable to reallocate ACPI tables\n");
-// goto error0;
-// }
-//
-// status = acpi_initialize_subsystem();
-// if (ACPI_FAILURE(status)) {
-// printk(KERN_ERR PREFIX
-// "Unable to initialize the ACPI Interpreter\n");
-// goto error0;
-// }
-//
-// status = acpi_load_tables();
-// if (ACPI_FAILURE(status)) {
-// printk(KERN_ERR PREFIX
-// "Unable to load the System Description Tables\n");
-// goto error0;
-// }
-//
-//#ifdef CONFIG_X86
-// if (!acpi_ioapic) {
-// /* compatible (0) means level (3) */
-// if (!(acpi_sci_flags & ACPI_MADT_TRIGGER_MASK)) {
-// acpi_sci_flags &= ~ACPI_MADT_TRIGGER_MASK;
-// acpi_sci_flags |= ACPI_MADT_TRIGGER_LEVEL;
-// }
-// /* Set PIC-mode SCI trigger type */
-// acpi_pic_sci_set_trigger(acpi_gbl_FADT.sci_interrupt,
-// (acpi_sci_flags & ACPI_MADT_TRIGGER_MASK) >> 2);
-// } else {
-// /*
-// * now that acpi_gbl_FADT is initialized,
-// * update it with result from INT_SRC_OVR parsing
-// */
-// acpi_gbl_FADT.sci_interrupt = acpi_sci_override_gsi;
-// }
-//#endif
-//
-// status =
-// acpi_enable_subsystem(~
-// (ACPI_NO_HARDWARE_INIT |
-// ACPI_NO_ACPI_ENABLE));
-// if (ACPI_FAILURE(status)) {
-// printk(KERN_ERR PREFIX "Unable to enable ACPI\n");
-// goto error0;
-// }
-//
-// return;
-//
-// error0:
-// disable_acpi();
-// return;
-//}
int
acpi_bus_init (void)
@@ -1700,13 +1618,6 @@
/* Initialize sleep structures */
//acpi_sleep_init();
-
- /*
- * Get the system interrupt model and evaluate \_PIC.
- */
- result = acpi_bus_init_irq();
- if (result)
- goto error1;
/*
* Register the for all standard device notifications.
@@ -1725,6 +1636,7 @@
ACPI_BUS_TYPE_SYSTEM);
if (result)
goto error2;
+
/*
* Enumerate devices in the ACPI namespace.
@@ -1736,7 +1648,6 @@
if (result)
DPRINT1("acpi_bus_scan failed\n");
- //acpi_motherboard_init();
return_VALUE(0);
/* Mimic structured exception handling */
Modified: trunk/reactos/drivers/bus/acpi/busmgr/button.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/bus/acpi/busmgr/bu…
==============================================================================
--- trunk/reactos/drivers/bus/acpi/busmgr/button.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/bus/acpi/busmgr/button.c [iso-8859-1] Thu Mar 25 15:19:54 2010
@@ -57,6 +57,11 @@
UINT8 type;
unsigned long pushed;
};
+
+struct acpi_device *power_button;
+struct acpi_device *sleep_button;
+struct acpi_device *lid_button;
+
/* --------------------------------------------------------------------------
Driver Interface
-------------------------------------------------------------------------- */
@@ -112,10 +117,6 @@
int result = 0;
ACPI_STATUS status = AE_OK;
struct acpi_button *button = NULL;
-
- static struct acpi_device *power_button;
- static struct acpi_device *sleep_button;
- static struct acpi_device *lid_button;
ACPI_FUNCTION_TRACE("acpi_button_add");
Modified: trunk/reactos/drivers/bus/acpi/include/acpi_bus.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/bus/acpi/include/a…
==============================================================================
--- trunk/reactos/drivers/bus/acpi/include/acpi_bus.h [iso-8859-1] (original)
+++ trunk/reactos/drivers/bus/acpi/include/acpi_bus.h [iso-8859-1] Thu Mar 25 15:19:54 2010
@@ -73,6 +73,8 @@
ACPI_BUS_TYPE_SYSTEM,
ACPI_BUS_TYPE_POWER_BUTTON,
ACPI_BUS_TYPE_SLEEP_BUTTON,
+ ACPI_BUS_TYPE_POWER_BUTTONF,
+ ACPI_BUS_TYPE_SLEEP_BUTTONF,
ACPI_BUS_DEVICE_TYPE_COUNT
};
Modified: trunk/reactos/drivers/bus/acpi/main.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/bus/acpi/main.c?re…
==============================================================================
--- trunk/reactos/drivers/bus/acpi/main.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/bus/acpi/main.c [iso-8859-1] Thu Mar 25 15:19:54 2010
@@ -17,6 +17,9 @@
#pragma alloc_text (PAGE, Bus_AddDevice)
#endif
+
+extern struct acpi_device *sleep_button;
+extern struct acpi_device *power_button;
NTSTATUS
NTAPI
@@ -215,22 +218,37 @@
break;
}
- if (wcsstr(((PPDO_DEVICE_DATA)commonData)->HardwareIDs, L"PNP0C0C") ||
- wcsstr(((PPDO_DEVICE_DATA)commonData)->HardwareIDs, L"ACPI_FPB"))
- {
- DPRINT1("Power button reported to power manager\n");
- Caps |= SYS_BUTTON_POWER;
- }
- else if (wcsstr(((PPDO_DEVICE_DATA)commonData)->HardwareIDs, L"PNP0C0E") ||
- wcsstr(((PPDO_DEVICE_DATA)commonData)->HardwareIDs, L"ACPI_FSB"))
- {
- DPRINT1("Sleep button reported to power manager\n");
- Caps |= SYS_BUTTON_SLEEP;
- }
- else if (wcsstr(((PPDO_DEVICE_DATA)commonData)->HardwareIDs, L"PNP0C0D"))
+ if (wcsstr(((PPDO_DEVICE_DATA)commonData)->HardwareIDs, L"PNP0C0D"))
{
DPRINT1("Lid button reported to power manager\n");
Caps |= SYS_BUTTON_LID;
+ }
+ else if (((PPDO_DEVICE_DATA)commonData)->AcpiHandle == NULL)
+ {
+ /* We have to return both at the same time because since we
+ * have a NULL handle we are the fixed feature DO and we will
+ * only be called once (not once per device)
+ */
+ if (power_button)
+ {
+ DPRINT1("Fixed power button reported to power manager\n");
+ Caps |= SYS_BUTTON_POWER;
+ }
+ if (sleep_button)
+ {
+ DPRINT1("Fixed sleep button reported to power manager\n");
+ Caps |= SYS_BUTTON_SLEEP;
+ }
+ }
+ if (wcsstr(((PPDO_DEVICE_DATA)commonData)->HardwareIDs, L"PNP0C0C"))
+ {
+ DPRINT1("Control method power button reported to power manager\n");
+ Caps |= SYS_BUTTON_POWER;
+ }
+ else if (wcsstr(((PPDO_DEVICE_DATA)commonData)->HardwareIDs, L"PNP0C0E"))
+ {
+ DPRINT1("Control method sleep reported to power manager\n");
+ Caps |= SYS_BUTTON_SLEEP;
}
else
{
Modified: trunk/reactos/drivers/bus/acpi/osl.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/bus/acpi/osl.c?rev…
==============================================================================
--- trunk/reactos/drivers/bus/acpi/osl.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/bus/acpi/osl.c [iso-8859-1] Thu Mar 25 15:19:54 2010
@@ -576,7 +576,12 @@
DPRINT("Waiting for semaphore %p\n", Handle);
ASSERT(Mutex);
- ExAcquireFastMutex(Mutex);
+ /* HACK: We enter here at a high IRQL sometimes
+ * because we get called from DPCs and ISRs and
+ * we can't use a fast mutex at that IRQL */
+ if (KeGetCurrentIrql() <= APC_LEVEL)
+ ExAcquireFastMutex(Mutex);
+
return AE_OK;
}
@@ -590,7 +595,12 @@
DPRINT("AcpiOsSignalSemaphore %p\n",Handle);
ASSERT(Mutex);
- ExReleaseFastMutex(Mutex);
+ /* HACK: We enter here at a high IRQL sometimes
+ * because we get called from DPCs and ISRs and
+ * we can't use a fast mutex at that IRQL */
+ if (KeGetCurrentIrql() <= APC_LEVEL)
+ ExReleaseFastMutex(Mutex);
+
return AE_OK;
}