[ros-diffs] [cgutman] 52358: [NTOSKRNL] - Send IRP_MN_QUERY_POWER and IRP_MN_SET_POWER to all enumerated devices prior to a system power state change - We don't mind failure right now since our drivers suck

cgutman at svn.reactos.org cgutman at svn.reactos.org
Sun Jun 19 04:25:33 UTC 2011


Author: cgutman
Date: Sun Jun 19 04:25:33 2011
New Revision: 52358

URL: http://svn.reactos.org/svn/reactos?rev=52358&view=rev
Log:
[NTOSKRNL]
- Send IRP_MN_QUERY_POWER and IRP_MN_SET_POWER to all enumerated devices prior to a system power state change
- We don't mind failure right now since our drivers suck

Modified:
    trunk/reactos/ntoskrnl/include/internal/io.h
    trunk/reactos/ntoskrnl/include/internal/po.h
    trunk/reactos/ntoskrnl/po/poshtdwn.c
    trunk/reactos/ntoskrnl/po/power.c

Modified: trunk/reactos/ntoskrnl/include/internal/io.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/include/internal/io.h?rev=52358&r1=52357&r2=52358&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/include/internal/io.h [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/include/internal/io.h [iso-8859-1] Sun Jun 19 04:25:33 2011
@@ -696,6 +696,11 @@
     OUT PULONG Disposition OPTIONAL
 );
 
+
+NTSTATUS
+IopTraverseDeviceTree(
+    PDEVICETREE_TRAVERSE_CONTEXT Context);
+
 //
 // PnP Routines
 //

Modified: trunk/reactos/ntoskrnl/include/internal/po.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/include/internal/po.h?rev=52358&r1=52357&r2=52358&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/include/internal/po.h [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/include/internal/po.h [iso-8859-1] Sun Jun 19 04:25:33 2011
@@ -291,7 +291,8 @@
 NTSTATUS
 NTAPI
 PopSetSystemPowerState(
-    SYSTEM_POWER_STATE PowerState
+    SYSTEM_POWER_STATE PowerState,
+    POWER_ACTION PowerAction
 );
 
 VOID

Modified: trunk/reactos/ntoskrnl/po/poshtdwn.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/po/poshtdwn.c?rev=52358&r1=52357&r2=52358&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/po/poshtdwn.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/po/poshtdwn.c [iso-8859-1] Sun Jun 19 04:25:33 2011
@@ -84,6 +84,7 @@
 
             /* Try platform driver first, then legacy */
             //PopInvokeSystemStateHandler(PowerStateShutdownReset, NULL);
+            PopSetSystemPowerState(PowerSystemShutdown, SystemAction);
             HalReturnToFirmware(HalRebootRoutine);
             break;
 
@@ -102,7 +103,7 @@
             //PopInvokeSystemStateHandler(PowerStateShutdownOff, NULL);
             
             /* ReactOS Hack */
-            PopSetSystemPowerState(PowerSystemShutdown);
+            PopSetSystemPowerState(PowerSystemShutdown, SystemAction);
             PopShutdownHandler();
 
             /* If that didn't work, call the HAL */

Modified: trunk/reactos/ntoskrnl/po/power.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/po/power.c?rev=52358&r1=52357&r2=52358&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/po/power.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/po/power.c [iso-8859-1] Sun Jun 19 04:25:33 2011
@@ -23,6 +23,13 @@
     PVOID Context;
 } REQUEST_POWER_ITEM, *PREQUEST_POWER_ITEM;
 
+typedef struct _POWER_STATE_TRAVERSE_CONTEXT
+{
+    SYSTEM_POWER_STATE SystemPowerState;
+    POWER_ACTION PowerAction;
+    PDEVICE_OBJECT PowerDevice;
+} POWER_STATE_TRAVERSE_CONTEXT, *PPOWER_STATE_TRAVERSE_CONTEXT;
+
 PDEVICE_NODE PopSystemPowerDeviceNode = NULL;
 BOOLEAN PopAcpiPresent = FALSE;
 POP_POWER_ACTION PopAction;
@@ -64,53 +71,33 @@
 }
 
 NTSTATUS
-NTAPI
-PopSetSystemPowerState(SYSTEM_POWER_STATE PowerState)
-{
+PopSendQuerySystemPowerState(PDEVICE_OBJECT DeviceObject, SYSTEM_POWER_STATE SystemState, POWER_ACTION PowerAction)
+{
+    KEVENT Event;
     IO_STATUS_BLOCK IoStatusBlock;
-    PDEVICE_OBJECT DeviceObject;
     PIO_STACK_LOCATION IrpSp;
-    PDEVICE_OBJECT Fdo;
+    PIRP Irp;
     NTSTATUS Status;
-    KEVENT Event;
-    PIRP Irp;
-
-    if (!PopAcpiPresent) return STATUS_NOT_IMPLEMENTED;
-
-    Status = IopGetSystemPowerDeviceObject(&DeviceObject);
-    if (!NT_SUCCESS(Status)) 
-    {
-        DPRINT1("No system power driver available\n");
-        return STATUS_UNSUCCESSFUL;
-    }
-
-    Fdo = IoGetAttachedDeviceReference(DeviceObject);
-
-    if (Fdo == DeviceObject)
-    {
-        DPRINT("An FDO was not attached\n");
-        return STATUS_UNSUCCESSFUL;
-    }
-
+    
     KeInitializeEvent(&Event,
                       NotificationEvent,
                       FALSE);
-
+    
     Irp = IoBuildSynchronousFsdRequest(IRP_MJ_POWER,
-                                       Fdo,
+                                       DeviceObject,
                                        NULL,
                                        0,
                                        NULL,
                                        &Event,
                                        &IoStatusBlock);
-
+    
     IrpSp = IoGetNextIrpStackLocation(Irp);
-    IrpSp->MinorFunction = IRP_MN_SET_POWER;
+    IrpSp->MinorFunction = IRP_MN_QUERY_POWER;
     IrpSp->Parameters.Power.Type = SystemPowerState;
-    IrpSp->Parameters.Power.State.SystemState = PowerState;
-
-    DPRINT("Calling ACPI driver");
-    Status = PoCallDriver(Fdo, Irp);
+    IrpSp->Parameters.Power.State.SystemState = SystemState;
+    IrpSp->Parameters.Power.ShutdownType = PowerAction;
+    
+    Status = PoCallDriver(DeviceObject, Irp);
     if (Status == STATUS_PENDING)
     {
         KeWaitForSingleObject(&Event,
@@ -118,10 +105,176 @@
                               KernelMode,
                               FALSE,
                               NULL);
-      Status = IoStatusBlock.Status;
-    }
-
-    ObDereferenceObject(Fdo);
+        Status = IoStatusBlock.Status;
+    }
+    
+    return Status;
+}
+
+NTSTATUS
+PopSendSetSystemPowerState(PDEVICE_OBJECT DeviceObject, SYSTEM_POWER_STATE SystemState, POWER_ACTION PowerAction)
+{
+    KEVENT Event;
+    IO_STATUS_BLOCK IoStatusBlock;
+    PIO_STACK_LOCATION IrpSp;
+    PIRP Irp;
+    NTSTATUS Status;
+    
+    KeInitializeEvent(&Event,
+                      NotificationEvent,
+                      FALSE);
+    
+    Irp = IoBuildSynchronousFsdRequest(IRP_MJ_POWER,
+                                       DeviceObject,
+                                       NULL,
+                                       0,
+                                       NULL,
+                                       &Event,
+                                       &IoStatusBlock);
+    
+    IrpSp = IoGetNextIrpStackLocation(Irp);
+    IrpSp->MinorFunction = IRP_MN_SET_POWER;
+    IrpSp->Parameters.Power.Type = SystemPowerState;
+    IrpSp->Parameters.Power.State.SystemState = SystemState;
+    IrpSp->Parameters.Power.ShutdownType = PowerAction;
+    
+    Status = PoCallDriver(DeviceObject, Irp);
+    if (Status == STATUS_PENDING)
+    {
+        KeWaitForSingleObject(&Event,
+                              Executive,
+                              KernelMode,
+                              FALSE,
+                              NULL);
+        Status = IoStatusBlock.Status;
+    }
+    
+    return Status;
+}
+
+NTSTATUS
+PopQuerySystemPowerStateTraverse(PDEVICE_NODE DeviceNode,
+                                 PVOID Context)
+{
+    PPOWER_STATE_TRAVERSE_CONTEXT PowerStateContext = Context;
+    NTSTATUS Status;
+    
+    DPRINT("PopQuerySystemPowerStateTraverse(%p, %p)\n", DeviceNode, Context);
+    
+    if (DeviceNode == IopRootDeviceNode)
+        return STATUS_SUCCESS;
+    
+    if (DeviceNode->Flags & DNF_LEGACY_DRIVER)
+        return STATUS_SUCCESS;
+
+    Status = PopSendQuerySystemPowerState(DeviceNode->PhysicalDeviceObject,
+                                          PowerStateContext->SystemPowerState,
+                                          PowerStateContext->PowerAction);
+    if (!NT_SUCCESS(Status))
+    {
+        DPRINT1("Device '%wZ' failed IRP_MN_QUERY_POWER\n", &DeviceNode->InstancePath);
+    }
+    
+#if 0
+    return Status;
+#else
+    return STATUS_SUCCESS;
+#endif
+}
+
+NTSTATUS
+PopSetSystemPowerStateTraverse(PDEVICE_NODE DeviceNode,
+                               PVOID Context)
+{
+    PPOWER_STATE_TRAVERSE_CONTEXT PowerStateContext = Context;
+    NTSTATUS Status;
+    
+    DPRINT("PopSetSystemPowerStateTraverse(%p, %p)\n", DeviceNode, Context);
+    
+    if (DeviceNode == IopRootDeviceNode)
+        return STATUS_SUCCESS;
+    
+    if (DeviceNode->PhysicalDeviceObject == PowerStateContext->PowerDevice)
+        return STATUS_SUCCESS;
+    
+    if (DeviceNode->Flags & DNF_LEGACY_DRIVER)
+        return STATUS_SUCCESS;
+
+    Status = PopSendSetSystemPowerState(DeviceNode->PhysicalDeviceObject,
+                                        PowerStateContext->SystemPowerState,
+                                        PowerStateContext->PowerAction);
+    if (!NT_SUCCESS(Status))
+    {
+        DPRINT1("Device '%wZ' failed IRP_MN_SET_POWER\n", &DeviceNode->InstancePath);
+    }
+    
+#if 0
+    return Status;
+#else
+    return STATUS_SUCCESS;
+#endif
+}
+
+NTSTATUS
+NTAPI
+PopSetSystemPowerState(SYSTEM_POWER_STATE PowerState, POWER_ACTION PowerAction)
+{
+    PDEVICE_OBJECT DeviceObject;
+    PDEVICE_OBJECT Fdo;
+    NTSTATUS Status;
+    DEVICETREE_TRAVERSE_CONTEXT Context;
+    POWER_STATE_TRAVERSE_CONTEXT PowerContext;
+    
+    Status = IopGetSystemPowerDeviceObject(&DeviceObject);
+    if (!NT_SUCCESS(Status)) 
+    {
+        DPRINT1("No system power driver available\n");
+        Fdo = NULL;
+    }
+    else
+    {
+        Fdo = IoGetAttachedDeviceReference(DeviceObject);
+        if (Fdo == DeviceObject)
+        {
+            DPRINT("An FDO was not attached\n");
+            return STATUS_UNSUCCESSFUL;
+        }
+    }
+    
+    /* Set up context */
+    PowerContext.PowerAction = PowerAction;
+    PowerContext.SystemPowerState = PowerState;
+    PowerContext.PowerDevice = Fdo;
+    
+    /* Query for system power change */
+    IopInitDeviceTreeTraverseContext(&Context,
+                                     IopRootDeviceNode,
+                                     PopQuerySystemPowerStateTraverse,
+                                     &PowerContext);
+    
+    Status = IopTraverseDeviceTree(&Context);
+    if (!NT_SUCCESS(Status))
+    {
+        DPRINT1("Query system power state failed; changing state anyway\n");
+    }
+    
+    /* Set system power change */
+    IopInitDeviceTreeTraverseContext(&Context,
+                                     IopRootDeviceNode,
+                                     PopSetSystemPowerStateTraverse,
+                                     &PowerContext);
+    
+    IopTraverseDeviceTree(&Context);
+
+    if (!PopAcpiPresent) return STATUS_NOT_IMPLEMENTED;
+    
+    if (Fdo != NULL)
+    {
+        if (PowerAction != PowerActionShutdownReset)
+            PopSendSetSystemPowerState(Fdo, PowerState, PowerAction);
+
+        ObDereferenceObject(Fdo);
+    }
 
     return Status;
 }




More information about the Ros-diffs mailing list