#include <acpi_bus.h>
#include <acpi_drivers.h>
+#include <initguid.h>
+#include <poclass.h>
+
#define NDEBUG
#include <debug.h>
{
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
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.
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;
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.
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;
#include <acpi_drivers.h>
#include <acpiioct.h>
+#include <poclass.h>
#define NDEBUG
#include <debug.h>
#endif
-
-
NTSTATUS
NTAPI
Bus_AddDevice(
PIO_STACK_LOCATION irpStack;
NTSTATUS status = STATUS_NOT_SUPPORTED;
PCOMMON_DEVICE_DATA commonData;
+ ULONG Caps = 0;
PAGED_CODE ();
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: