From 0bd14e99b46c575d3bfd0c40d3f8cc9effaec87f Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Thu, 25 Mar 2010 05:11:24 +0000 Subject: [PATCH] [ACPI] - Implement IOCTL_GET_SYS_BUTTON_CAPS - Register and maintain PnP interfaces for thermal zones, buttons, lids, and processors svn path=/trunk/; revision=46429 --- reactos/drivers/bus/acpi/buspdo.c | 69 ++++++++++++++++++---- reactos/drivers/bus/acpi/include/acpisys.h | 5 +- reactos/drivers/bus/acpi/main.c | 42 ++++++++++++- 3 files changed, 97 insertions(+), 19 deletions(-) diff --git a/reactos/drivers/bus/acpi/buspdo.c b/reactos/drivers/bus/acpi/buspdo.c index ed6439d60a5..84bd1d8fe11 100644 --- a/reactos/drivers/bus/acpi/buspdo.c +++ b/reactos/drivers/bus/acpi/buspdo.c @@ -8,6 +8,9 @@ #include #include +#include +#include + #define NDEBUG #include @@ -33,9 +36,13 @@ Bus_PDO_PnP ( { NTSTATUS status; POWER_STATE state; + struct acpi_device *device = NULL; PAGED_CODE (); + if (DeviceData->AcpiHandle) + acpi_bus_get_device(DeviceData->AcpiHandle, &device); + // // NB: Because we are a bus enumerator, we have no one to whom we could // defer these irps. Therefore we do not pass them down but merely @@ -45,7 +52,6 @@ Bus_PDO_PnP ( switch (IrpStack->MinorFunction) { case IRP_MN_START_DEVICE: - // // Here we do what ever initialization and ``turning on'' that is // required to allow others to access this device. @@ -59,6 +65,43 @@ Bus_PDO_PnP ( break; } + DeviceData->InterfaceName.Length = 0; + + if (!device) + { + IoRegisterDeviceInterface(DeviceData->Common.Self, + &GUID_DEVICE_SYS_BUTTON, + NULL, + &DeviceData->InterfaceName); + } + else if (device->flags.hardware_id && + strstr(device->pnp.hardware_id, ACPI_THERMAL_HID)) + { + IoRegisterDeviceInterface(DeviceData->Common.Self, + &GUID_DEVICE_THERMAL_ZONE, + NULL, + &DeviceData->InterfaceName); + } + else if (device->flags.hardware_id && + strstr(device->pnp.hardware_id, ACPI_BUTTON_HID_LID)) + { + IoRegisterDeviceInterface(DeviceData->Common.Self, + &GUID_DEVICE_LID, + NULL, + &DeviceData->InterfaceName); + } + else if (device->flags.hardware_id && + strstr(device->pnp.hardware_id, ACPI_PROCESSOR_HID)) + { + IoRegisterDeviceInterface(DeviceData->Common.Self, + &GUID_DEVICE_PROCESSOR, + NULL, + &DeviceData->InterfaceName); + } + + if (DeviceData->InterfaceName.Length != 0) + IoSetDeviceInterfaceState(&DeviceData->InterfaceName, TRUE); + state.DeviceState = PowerDeviceD0; PoSetPowerState(DeviceData->Common.Self, DevicePowerState, state); DeviceData->Common.DevicePowerState = PowerDeviceD0; @@ -68,6 +111,9 @@ Bus_PDO_PnP ( case IRP_MN_STOP_DEVICE: + if (DeviceData->InterfaceName.Length != 0) + IoSetDeviceInterfaceState(&DeviceData->InterfaceName, FALSE); + // // Here we shut down the device and give up and unmap any resources // we acquired for the device. @@ -331,20 +377,17 @@ Bus_PDO_QueryDeviceCaps( deviceCapabilities->UniqueID = device->flags.unique_id; deviceCapabilities->NoDisplayInUI = !device->status.show_in_ui; deviceCapabilities->Address = device->pnp.bus_address; - deviceCapabilities->RawDeviceOK = FALSE; } - else + + if (!device || + (device->flags.hardware_id && + (strstr(device->pnp.hardware_id, ACPI_BUTTON_HID_LID) || + strstr(device->pnp.hardware_id, ACPI_THERMAL_HID) || + strstr(device->pnp.hardware_id, ACPI_PROCESSOR_HID)))) { - deviceCapabilities->EjectSupported = FALSE; - deviceCapabilities->HardwareDisabled = FALSE; - deviceCapabilities->Removable = FALSE; - deviceCapabilities->SurpriseRemovalOK = FALSE; - deviceCapabilities->UniqueID = FALSE; - deviceCapabilities->NoDisplayInUI = FALSE; - deviceCapabilities->Address = 0; - - /* The ACPI driver will run fixed buttons */ - deviceCapabilities->RawDeviceOK = TRUE; + /* Allow ACPI to control the device if it is a lid button, + * a thermal zone, a processor, or a fixed feature button */ + deviceCapabilities->RawDeviceOK = TRUE; } deviceCapabilities->SilentInstall = FALSE; diff --git a/reactos/drivers/bus/acpi/include/acpisys.h b/reactos/drivers/bus/acpi/include/acpisys.h index bf3c65ee0f8..adf2a0c592a 100644 --- a/reactos/drivers/bus/acpi/include/acpisys.h +++ b/reactos/drivers/bus/acpi/include/acpisys.h @@ -39,6 +39,7 @@ typedef struct _PDO_DEVICE_DATA // Link point to hold all the PDOs for a single bus together LIST_ENTRY Link; ULONG InterfaceRefCount; + UNICODE_STRING InterfaceName; } PDO_DEVICE_DATA, *PPDO_DEVICE_DATA; @@ -64,10 +65,6 @@ typedef struct _FDO_DEVICE_DATA // A synchronization for access to the device extension. FAST_MUTEX Mutex; - // The name returned from IoRegisterDeviceInterface, - // which is used as a handle for IoSetDeviceInterfaceState. - UNICODE_STRING InterfaceName; - } FDO_DEVICE_DATA, *PFDO_DEVICE_DATA; #define FDO_FROM_PDO(pdoData) \ diff --git a/reactos/drivers/bus/acpi/main.c b/reactos/drivers/bus/acpi/main.c index 46667b9b5de..22946cd5a52 100644 --- a/reactos/drivers/bus/acpi/main.c +++ b/reactos/drivers/bus/acpi/main.c @@ -7,6 +7,7 @@ #include #include +#include #define NDEBUG #include @@ -17,8 +18,6 @@ #endif - - NTSTATUS NTAPI Bus_AddDevice( @@ -189,6 +188,7 @@ ACPIDispatchDeviceControl( PIO_STACK_LOCATION irpStack; NTSTATUS status = STATUS_NOT_SUPPORTED; PCOMMON_DEVICE_DATA commonData; + ULONG Caps = 0; PAGED_CODE (); @@ -208,6 +208,44 @@ ACPIDispatchDeviceControl( Irp); break; + case IOCTL_GET_SYS_BUTTON_CAPS: + if (irpStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(ULONG)) + { + status = STATUS_BUFFER_TOO_SMALL; + 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")) + { + DPRINT1("Lid button reported to power manager\n"); + Caps |= SYS_BUTTON_LID; + } + else + { + DPRINT1("IOCTL_GET_SYS_BUTTON_CAPS sent to a non-button device\n"); + status = STATUS_INVALID_PARAMETER; + } + + if (Caps != 0) + { + RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer, &Caps, sizeof(Caps)); + Irp->IoStatus.Information = sizeof(Caps); + status = STATUS_SUCCESS; + } + break; + /* TODO: Implement other IOCTLs */ default: -- 2.17.1