[ACPI]
authorCameron Gutman <aicommander@gmail.com>
Thu, 25 Mar 2010 05:11:24 +0000 (05:11 +0000)
committerCameron Gutman <aicommander@gmail.com>
Thu, 25 Mar 2010 05:11:24 +0000 (05:11 +0000)
- 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
reactos/drivers/bus/acpi/include/acpisys.h
reactos/drivers/bus/acpi/main.c

index ed6439d..84bd1d8 100644 (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
+
+    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;
index bf3c65e..adf2a0c 100644 (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) \
index 46667b9..22946cd 100644 (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: