From: Cameron Gutman Date: Thu, 25 Mar 2010 14:19:54 +0000 (+0000) Subject: [ACPI] X-Git-Tag: backups/header-work@57446~86^2~1 X-Git-Url: https://git.reactos.org/?p=reactos.git;a=commitdiff_plain;h=da0c0103071b65dfcd031ec29d03e72439f2233e [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 svn path=/trunk/; revision=46442 --- diff --git a/reactos/drivers/bus/acpi/busmgr/bus.c b/reactos/drivers/bus/acpi/busmgr/bus.c index 34aa0766c04..6309f20cfdb 100644 --- a/reactos/drivers/bus/acpi/busmgr/bus.c +++ b/reactos/drivers/bus/acpi/busmgr/bus.c @@ -1262,9 +1262,15 @@ acpi_bus_add ( 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 @@ acpi_bus_add ( */ 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 @@ acpi_bus_scan_fixed ( 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); } @@ -1549,120 +1581,6 @@ acpi_bus_scan_fixed ( 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) { @@ -1701,13 +1619,6 @@ acpi_bus_init (void) /* 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. */ @@ -1726,6 +1637,7 @@ acpi_bus_init (void) if (result) goto error2; + /* * Enumerate devices in the ACPI namespace. */ @@ -1736,7 +1648,6 @@ acpi_bus_init (void) if (result) DPRINT1("acpi_bus_scan failed\n"); - //acpi_motherboard_init(); return_VALUE(0); /* Mimic structured exception handling */ diff --git a/reactos/drivers/bus/acpi/busmgr/button.c b/reactos/drivers/bus/acpi/busmgr/button.c index 5e3eb2b5f0f..9344a5f1f7d 100644 --- a/reactos/drivers/bus/acpi/busmgr/button.c +++ b/reactos/drivers/bus/acpi/busmgr/button.c @@ -57,6 +57,11 @@ struct acpi_button { UINT8 type; unsigned long pushed; }; + +struct acpi_device *power_button; +struct acpi_device *sleep_button; +struct acpi_device *lid_button; + /* -------------------------------------------------------------------------- Driver Interface -------------------------------------------------------------------------- */ @@ -113,10 +118,6 @@ acpi_button_add ( 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"); if (!device) diff --git a/reactos/drivers/bus/acpi/include/acpi_bus.h b/reactos/drivers/bus/acpi/include/acpi_bus.h index d5fe9efccc6..d2dc22d02a9 100644 --- a/reactos/drivers/bus/acpi/include/acpi_bus.h +++ b/reactos/drivers/bus/acpi/include/acpi_bus.h @@ -73,6 +73,8 @@ enum acpi_bus_device_type { 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 }; diff --git a/reactos/drivers/bus/acpi/main.c b/reactos/drivers/bus/acpi/main.c index 22946cd5a52..4cbdfda4468 100644 --- a/reactos/drivers/bus/acpi/main.c +++ b/reactos/drivers/bus/acpi/main.c @@ -18,6 +18,9 @@ #endif +extern struct acpi_device *sleep_button; +extern struct acpi_device *power_button; + NTSTATUS NTAPI Bus_AddDevice( @@ -215,22 +218,37 @@ ACPIDispatchDeviceControl( break; } - if (wcsstr(((PPDO_DEVICE_DATA)commonData)->HardwareIDs, L"PNP0C0C") || - wcsstr(((PPDO_DEVICE_DATA)commonData)->HardwareIDs, L"ACPI_FPB")) + if (wcsstr(((PPDO_DEVICE_DATA)commonData)->HardwareIDs, L"PNP0C0D")) { - DPRINT1("Power button reported to power manager\n"); - Caps |= SYS_BUTTON_POWER; + DPRINT1("Lid button reported to power manager\n"); + Caps |= SYS_BUTTON_LID; } - else if (wcsstr(((PPDO_DEVICE_DATA)commonData)->HardwareIDs, L"PNP0C0E") || - wcsstr(((PPDO_DEVICE_DATA)commonData)->HardwareIDs, L"ACPI_FSB")) + else if (((PPDO_DEVICE_DATA)commonData)->AcpiHandle == NULL) { - DPRINT1("Sleep button reported to power manager\n"); - Caps |= SYS_BUTTON_SLEEP; + /* 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; + } } - else if (wcsstr(((PPDO_DEVICE_DATA)commonData)->HardwareIDs, L"PNP0C0D")) + if (wcsstr(((PPDO_DEVICE_DATA)commonData)->HardwareIDs, L"PNP0C0C")) { - DPRINT1("Lid button reported to power manager\n"); - Caps |= SYS_BUTTON_LID; + 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 { diff --git a/reactos/drivers/bus/acpi/osl.c b/reactos/drivers/bus/acpi/osl.c index f2549951e7e..a5df0c0d620 100644 --- a/reactos/drivers/bus/acpi/osl.c +++ b/reactos/drivers/bus/acpi/osl.c @@ -576,7 +576,12 @@ AcpiOsWaitSemaphore( 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 @@ AcpiOsSignalSemaphore ( 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; }