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 #ifndef YDEBUG
12 #define NDEBUG
13 #endif
14 
15 #include <debug.h>
16 
17 NTSTATUS
18 NTAPI
19 PcRegisterAdapterPowerManagement(
20     IN  PUNKNOWN pUnknown,
21     IN  PVOID pvContext)
22 {
23     NTSTATUS Status;
24     PDEVICE_OBJECT pDeviceObject;
25     PPCLASS_DEVICE_EXTENSION DeviceExt;
26     IAdapterPowerManagement * pPower;
27 
28     DPRINT("PcRegisterAdapterPowerManagement pUnknown %p pvContext %p\n", pUnknown, pvContext);
29     PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL);
30 
31     if (!pUnknown || !pvContext)
32         return STATUS_INVALID_PARAMETER;
33 
34 
35     pDeviceObject = (PDEVICE_OBJECT)pvContext;
36     DeviceExt = (PPCLASS_DEVICE_EXTENSION)pDeviceObject->DeviceExtension;
37 
38     Status = pUnknown->QueryInterface(IID_IAdapterPowerManagement, (PVOID*)&pPower);
39     if (!NT_SUCCESS(Status))
40     {
41         DPRINT1("PcRegisterAdapterPowerManagement no IAdapterPowerManagement interface %x\n", Status);
42         DeviceExt->AdapterPowerManagement = NULL;
43         return STATUS_SUCCESS;
44     }
45 
46     DeviceExt->AdapterPowerManagement = pPower;
47     DPRINT("PcRegisterAdapterPowerManagement success %x\n", Status);
48     return STATUS_SUCCESS;
49 }
50 
51 NTSTATUS
52 NTAPI
53 PcUnregisterAdapterPowerManagement(
54     IN PDEVICE_OBJECT DeviceObject)
55 {
56     PPCLASS_DEVICE_EXTENSION DeviceExt;
57 
58     DPRINT("PcUnregisterAdapterPowerManagement pUnknown %p pvContext %p\n", DeviceObject);
59     PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL);
60 
61     if (!DeviceObject)
62         return STATUS_INVALID_PARAMETER;
63 
64     DeviceExt = (PPCLASS_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
65 
66     if (DeviceExt->AdapterPowerManagement)
67     {
68         DeviceExt->AdapterPowerManagement->Release();
69     }
70     DeviceExt->AdapterPowerManagement = NULL;
71     return STATUS_SUCCESS;
72 }
73 
74 
75 
76 static
77 VOID
78 NTAPI
79 PwrCompletionCallback(
80     IN PDEVICE_OBJECT DeviceObject,
81     IN UCHAR MinorFunction,
82     IN POWER_STATE PowerState,
83     IN PVOID Context,
84     IN PIO_STATUS_BLOCK IoStatus)
85 {
86     KeSetEvent((PRKEVENT)Context, IO_NO_INCREMENT, FALSE);
87 }
88 
89 NTSTATUS
90 NTAPI
91 PcRequestNewPowerState(
92     IN  PDEVICE_OBJECT DeviceObject,
93     IN  DEVICE_POWER_STATE RequestedNewState)
94 {
95     KEVENT Event;
96     NTSTATUS Status;
97     POWER_STATE PowerState;
98     PPCLASS_DEVICE_EXTENSION DeviceExt;
99 
100     PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL);
101 
102     if (!DeviceObject || !RequestedNewState)
103         return STATUS_INVALID_PARAMETER;
104 
105     DeviceExt = (PPCLASS_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
106     KeInitializeEvent(&Event, SynchronizationEvent, FALSE);
107 
108     PowerState.DeviceState = RequestedNewState;
109     PowerState.SystemState = PowerSystemUnspecified;
110 
111     Status = PoRequestPowerIrp(DeviceExt->PhysicalDeviceObject, IRP_MN_SET_POWER, PowerState, PwrCompletionCallback, (PVOID)&Event, NULL);
112     if (NT_SUCCESS(Status))
113     {
114         KeWaitForSingleObject((PVOID)&Event, Executive, KernelMode, FALSE, NULL);
115     }
116 
117 
118     return Status;
119 }
120 
121