- Implement IOCTL_GET_SYS_BUTTON_CAPS
- Register and maintain PnP interfaces for thermal zones, buttons, lids, and processors

svn path=/trunk/; revision=46429
This commit is contained in:
Cameron Gutman
2010-03-25 05:11:24 +00:00
parent fe68057a58
commit 0bd14e99b4
3 changed files with 97 additions and 19 deletions
+56 -13
View File
@@ -8,6 +8,9 @@
#include <acpi_bus.h>
#include <acpi_drivers.h>
#include <initguid.h>
#include <poclass.h>
#define NDEBUG
#include <debug.h>
@@ -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
{
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;
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))))
{
/* 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;
+1 -4
View File
@@ -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) \
+40 -2
View File
@@ -7,6 +7,7 @@
#include <acpi_drivers.h>
#include <acpiioct.h>
#include <poclass.h>
#define NDEBUG
#include <debug.h>
@@ -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: