Author: cgutman Date: Thu Mar 25 06:11:24 2010 New Revision: 46429
URL: http://svn.reactos.org/svn/reactos?rev=46429&view=rev Log: [ACPI] - Implement IOCTL_GET_SYS_BUTTON_CAPS - Register and maintain PnP interfaces for thermal zones, buttons, lids, and processors
Modified: trunk/reactos/drivers/bus/acpi/buspdo.c trunk/reactos/drivers/bus/acpi/include/acpisys.h trunk/reactos/drivers/bus/acpi/main.c
Modified: trunk/reactos/drivers/bus/acpi/buspdo.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/bus/acpi/buspdo.c?r... ============================================================================== --- trunk/reactos/drivers/bus/acpi/buspdo.c [iso-8859-1] (original) +++ trunk/reactos/drivers/bus/acpi/buspdo.c [iso-8859-1] Thu Mar 25 06:11:24 2010 @@ -7,6 +7,9 @@
#include <acpi_bus.h> #include <acpi_drivers.h> + +#include <initguid.h> +#include <poclass.h>
#define NDEBUG #include <debug.h> @@ -33,8 +36,12 @@ { 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 @@ -45,7 +52,6 @@ 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 @@ 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; @@ -67,6 +110,9 @@ break;
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 @@ -331,20 +377,17 @@ 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;
Modified: trunk/reactos/drivers/bus/acpi/include/acpisys.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/bus/acpi/include/ac... ============================================================================== --- trunk/reactos/drivers/bus/acpi/include/acpisys.h [iso-8859-1] (original) +++ trunk/reactos/drivers/bus/acpi/include/acpisys.h [iso-8859-1] Thu Mar 25 06:11:24 2010 @@ -39,6 +39,7 @@ // 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;
@@ -63,10 +64,6 @@
// 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;
Modified: trunk/reactos/drivers/bus/acpi/main.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/bus/acpi/main.c?rev... ============================================================================== --- trunk/reactos/drivers/bus/acpi/main.c [iso-8859-1] (original) +++ trunk/reactos/drivers/bus/acpi/main.c [iso-8859-1] Thu Mar 25 06:11:24 2010 @@ -7,6 +7,7 @@ #include <acpi_drivers.h>
#include <acpiioct.h> +#include <poclass.h>
#define NDEBUG #include <debug.h> @@ -16,8 +17,6 @@ #pragma alloc_text (PAGE, Bus_AddDevice)
#endif - -
NTSTATUS NTAPI @@ -189,6 +188,7 @@ PIO_STACK_LOCATION irpStack; NTSTATUS status = STATUS_NOT_SUPPORTED; PCOMMON_DEVICE_DATA commonData; + ULONG Caps = 0;
PAGED_CODE ();
@@ -208,6 +208,44 @@ 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: