1 /*
2  * COPYRIGHT:       See COPYING in the top level directory
3  * PROJECT:         ReactOS Kernel Streaming
4  * FILE:            drivers/wdm/audio/backpln/portcls/power.cpp
5  * PURPOSE:         Power support functions
6  * PROGRAMMER:      Johannes Anderwald
7  */
8 
9 #include "private.hpp"
10 
11 #define NDEBUG
12 #include <debug.h>
13 
14 NTSTATUS
15 NTAPI
16 PcRegisterAdapterPowerManagement(
17     IN  PUNKNOWN pUnknown,
18     IN  PVOID pvContext)
19 {
20     NTSTATUS Status;
21     PDEVICE_OBJECT pDeviceObject;
22     PPCLASS_DEVICE_EXTENSION DeviceExt;
23     IAdapterPowerManagement * pPower;
24 
25     DPRINT("PcRegisterAdapterPowerManagement pUnknown %p pvContext %p\n", pUnknown, pvContext);
26     PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL);
27 
28     if (!pUnknown || !pvContext)
29         return STATUS_INVALID_PARAMETER;
30 
31     pDeviceObject = (PDEVICE_OBJECT)pvContext;
32     DeviceExt = (PPCLASS_DEVICE_EXTENSION)pDeviceObject->DeviceExtension;
33 
34     Status = pUnknown->QueryInterface(IID_IAdapterPowerManagement, (PVOID*)&pPower);
35     if (!NT_SUCCESS(Status))
36     {
37         DPRINT1("PcRegisterAdapterPowerManagement no IAdapterPowerManagement interface %x\n", Status);
38         DeviceExt->AdapterPowerManagement = NULL;
39         return STATUS_SUCCESS;
40     }
41 
42     DeviceExt->AdapterPowerManagement = pPower;
43     DPRINT("PcRegisterAdapterPowerManagement success %x\n", Status);
44     return STATUS_SUCCESS;
45 }
46 
47 NTSTATUS
48 NTAPI
49 PcUnregisterAdapterPowerManagement(
50     IN PDEVICE_OBJECT DeviceObject)
51 {
52     PPCLASS_DEVICE_EXTENSION DeviceExt;
53 
54     DPRINT("PcUnregisterAdapterPowerManagement pUnknown %p pvContext %p\n", DeviceObject);
55     PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL);
56 
57     if (!DeviceObject)
58         return STATUS_INVALID_PARAMETER;
59 
60     DeviceExt = (PPCLASS_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
61 
62     if (DeviceExt->AdapterPowerManagement)
63     {
64         DeviceExt->AdapterPowerManagement->Release();
65     }
66     DeviceExt->AdapterPowerManagement = NULL;
67     return STATUS_SUCCESS;
68 }
69 
70 static
71 VOID
72 NTAPI
73 PwrCompletionCallback(
74     IN PDEVICE_OBJECT DeviceObject,
75     IN UCHAR MinorFunction,
76     IN POWER_STATE PowerState,
77     IN PVOID Context,
78     IN PIO_STATUS_BLOCK IoStatus)
79 {
80     KeSetEvent((PRKEVENT)Context, IO_NO_INCREMENT, FALSE);
81 }
82 
83 NTSTATUS
84 NTAPI
85 PcRequestNewPowerState(
86     IN  PDEVICE_OBJECT DeviceObject,
87     IN  DEVICE_POWER_STATE RequestedNewState)
88 {
89     KEVENT Event;
90     NTSTATUS Status;
91     POWER_STATE PowerState;
92     PPCLASS_DEVICE_EXTENSION DeviceExt;
93 
94     PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL);
95 
96     if (!DeviceObject || !RequestedNewState)
97         return STATUS_INVALID_PARAMETER;
98 
99     DeviceExt = (PPCLASS_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
100     KeInitializeEvent(&Event, SynchronizationEvent, FALSE);
101 
102     PowerState.DeviceState = RequestedNewState;
103     PowerState.SystemState = PowerSystemUnspecified;
104 
105     Status = PoRequestPowerIrp(DeviceExt->PhysicalDeviceObject, IRP_MN_SET_POWER, PowerState, PwrCompletionCallback, (PVOID)&Event, NULL);
106     if (NT_SUCCESS(Status))
107     {
108         KeWaitForSingleObject((PVOID)&Event, Executive, KernelMode, FALSE, NULL);
109     }
110 
111     return Status;
112 }
113