ReactOS 0.4.16-dev-340-g0540c21
supportkm.cpp
Go to the documentation of this file.
1/*++
2
3Copyright (c) Microsoft Corporation
4
5Module Name:
6
7 supportKM.cpp
8
9Abstract:
10
11 This module implements the pnp support routines.
12
13Author:
14
15
16Environment:
17
18 kernel mode only
19
20Revision History:
21
22--*/
23
24#include "../pnppriv.hpp"
25#include <wdmguid.h>
26
27#if defined(EVENT_TRACING)
28#include "supportKM.tmh"
29#endif
30
31VOID
33 __in PPOWER_THREAD_INTERFACE PowerThreadInterface,
35 )
36{
38
39 stack = Irp->GetCurrentIrpStackLocation();
40
41 RtlCopyMemory(stack->Parameters.QueryInterface.Interface,
42 PowerThreadInterface,
43 PowerThreadInterface->Interface.Size);
44}
45
50 __in MxDeviceObject* DeviceInStack,
51 __in_opt PD3COLD_SUPPORT_INTERFACE D3ColdInterface,
53 )
54{
55 ULONG i;
58
60
62
63 //
64 // Normally this would be assigned to a local variable on the stack. Since
65 // query caps iteratively moves down the device's tree until it hits the
66 // root. As such, stack usage is consumed quickly. While this is only one
67 // pointer value we are saving, it does eventually add up on very deep stacks.
68 //
69 DeviceInStack->SetObject(DeviceInStack->GetAttachedDeviceReference());
70 if (DeviceInStack->GetObject() == NULL) {
71 goto Done;
72 }
73
74 irp.SetIrp(FxIrp::AllocateIrp(DeviceInStack->GetStackSize()));
75 if (irp.GetIrp() == NULL) {
76 goto Done;
77 }
78
79 //
80 // Initialize device capabilities.
81 //
83 Capabilities->DeviceCaps.Size = sizeof(DEVICE_CAPABILITIES);
84 Capabilities->DeviceCaps.Version = 1;
85 Capabilities->DeviceCaps.Address = (ULONG) -1;
86 Capabilities->DeviceCaps.UINumber = (ULONG) -1;
87
88 //
89 // Initialize the Irp.
90 //
92
97
98 status = irp.SendIrpSynchronously(DeviceInStack->GetObject());
99
100 if (!NT_SUCCESS(status)) {
103 "Failed to get DEVICE_CAPABILITIES from !devobj %p, %!STATUS!",
104 DeviceInStack->GetObject(), status);
105 goto Done;
106 }
107
108 //
109 // Invoke the D3cold support interface. If present, it will tell
110 // us specifically which D-states will work for generating wake signals
111 // from specific S-states.
112 //
113 // Earlier versions of WDF didn't make this query, so for compatibility,
114 // we only make it now if the driver was built against WDF 1.11 or
115 // later. In truth, this just shifts the failure from initialization
116 // time to run time, because the information that we're presumably
117 // getting from the BIOS with this interrogation is saying that the
118 // code in earlier verisions of WDF would have blindly enabled a device
119 // for wake which simply wasn't capable of generating its wake signal
120 // from the chosen D-state. Thus the device would have been put into
121 // a low power state and then failed to resume in response to its wake
122 // signal.
123 //
124
125 for (i = 0; i <= PowerSystemHibernate; i++) {
126 Capabilities->DeepestWakeableDstate[i] = DeviceWakeDepthMaximum;
127 }
128
129 if (ARGUMENT_PRESENT(D3ColdInterface) &&
130 (D3ColdInterface->GetIdleWakeInfo != NULL) &&
131 DriverGlobals->IsVersionGreaterThanOrEqualTo(1,11)) {
132
133 DEVICE_WAKE_DEPTH deepestWakeableDstate;
134
136
137 //
138 // Failure from D3ColdInterface->GetIdleWakeInfo just means that
139 // the bus drivers didn't have any information beyond what can
140 // gleaned from the older Query-Capabilities code path.
141 //
142 // In specific ACPI terms, ACPI will respond to this function with
143 // success whenever there is an _SxW object (where x is the sleep
144 // state, a value from 0 to 4.)
145 //
146 // PCI will respond to this interface if ACPI doesn't override its
147 // answer and if a parent bus is capable of leaving D0 in S0, and
148 // if the PCI device has
149 status = D3ColdInterface->GetIdleWakeInfo(
150 D3ColdInterface->Context,
152 &deepestWakeableDstate
153 );
154
155 if (NT_SUCCESS(status)) {
156 Capabilities->DeepestWakeableDstate[i] = deepestWakeableDstate;
157 }
158 }
159 }
160
162
163Done:
164 if (DeviceInStack->GetObject() != NULL) {
165 DeviceInStack->DereferenceObject();
166 }
167
168 return status;
169}
170
171VOID
174 __in MxDeviceObject* DeviceInStack,
175 __in PD3COLD_SUPPORT_INTERFACE D3ColdInterface,
176 __in BOOLEAN UseD3Cold
177 )
178{
180 UNREFERENCED_PARAMETER(DeviceInStack);
181
182 if (D3ColdInterface->SetD3ColdSupport != NULL) {
183 D3ColdInterface->SetD3ColdSupport(D3ColdInterface->Context, UseD3Cold);
184 }
185}
186
188PVOID
190 VOID
191 )
192/*++
193Routine description:
194 Returns an IO manager object that can be passed in to IoAllocateWorkItem
195
196Arguments:
197 None
198
199Return value:
200 Pointer to the object that can be passed in to IoAllocateWorkItem
201--*/
202{
203 // return (PVOID) FxLibraryGlobals.DriverObject;
204 // __REACTOS__ : we don't have a WDF driver object here, use a child one
205
208}
209
212 VOID
213 )
214{
216}
217
221 __in MxDeviceObject* RelatedDevice,
222 __inout FxIrp* RelatedIrp,
223 __in MxWorkItem* Workitem,
225 __in BOOLEAN Revert
226 )
227{
229
230 //
231 // use workitem if available
232 //
233 if (Workitem->GetWorkItem() != NULL) {
235
236 param.RelatedDevice = RelatedDevice;
237 param.RelatedIrp = RelatedIrp;
238 param.OriginalIrp = OriginalIrp;
239 param.Revert = Revert;
240
241 //
242 // Kick off to another thread
243 //
244 Workitem->Enqueue(_DeviceUsageNotificationWorkItem, &param);
245
246 //
247 // wait for the workitem to finish
248 //
249 param.Event.EnterCRAndWaitAndLeave();
250
251 status = param.Status;
252 }
253 else {
255 RelatedIrp,
257 Revert);
258 }
259
260 return status;
261}
262
265 __in MxDeviceObject* RelatedDevice,
266 __inout FxIrp* RelatedIrp,
268 __in BOOLEAN Revert
269 )
270{
271 MxDeviceObject relatedTopOfStack;
273
274 relatedTopOfStack.SetObject(RelatedDevice->GetAttachedDeviceReference());
275 ASSERT(relatedTopOfStack.GetObject() != NULL);
276
277 //
278 // Initialize the new IRP with the stack data from the current IRP and
279 // and send it to the parent stack.
280 //
281 RelatedIrp->InitNextStackUsingStack(OriginalIrp);
282
283 if (Revert) {
284 RelatedIrp->SetParameterUsageNotificationInPath(
285 !RelatedIrp->GetNextStackParameterUsageNotificationInPath());
286 }
287
288 RelatedIrp->SetStatus(STATUS_NOT_SUPPORTED);
289
290 status = RelatedIrp->SendIrpSynchronously(relatedTopOfStack.GetObject());
291
292 relatedTopOfStack.DereferenceObject();
293
294 return status;
295}
296
297VOID
302 )
303{
306
308
310
312 param->RelatedIrp,
313 param->OriginalIrp,
314 param->Revert);
315
316 //
317 // capture status in notification object
318 //
319 param->Status = status;
320
321 //
322 // set event to allow the origial notifcation thread to proceed
323 //
324 param->Event.Set();
325}
326
unsigned char BOOLEAN
LONG NTSTATUS
Definition: precomp.h:26
#define IRP_MJ_PNP
Definition: cdrw_usr.h:52
__inline MdDriverObject GetDriverObject(VOID)
Definition: fxdriver.hpp:252
Definition: fxirp.hpp:28
CHECK_RETURN_IF_USER_MODE NTSTATUS SendIrpSynchronously(__in MdDeviceObject DeviceObject)
Definition: fxirpum.cpp:151
VOID SetMinorFunction(__in UCHAR MinorFunction)
Definition: fxirpum.cpp:967
static _Must_inspect_result_ MdIrp AllocateIrp(_In_ CCHAR StackSize, _In_opt_ FxDevice *Device=NULL)
Definition: fxirpum.cpp:1089
VOID ClearNextStack(VOID)
Definition: fxirpum.cpp:1183
VOID SetMajorFunction(__in UCHAR MajorFunction)
Definition: fxirpum.cpp:905
VOID SetStatus(__in NTSTATUS Status)
Definition: fxirpum.cpp:457
MdIrp GetIrp(VOID)
Definition: fxirpum.cpp:15
MdIrp SetIrp(MdIrp irp)
Definition: fxirpkm.hpp:71
VOID SetParameterDeviceCapabilities(__in PDEVICE_CAPABILITIES DeviceCapabilities)
Definition: fxirpum.cpp:1145
static BOOLEAN _SystemManagedIdleTimeoutAvailable(VOID)
Definition: supportkm.cpp:211
__inline VOID SetObject(__in_opt MdDeviceObject DeviceObject)
VOID DereferenceObject()
__inline MdDeviceObject GetObject(VOID)
_In_ PTRANSFER_PACKET _In_ ULONG _In_ PIRP OriginalIrp
Definition: classp.h:1757
_In_ PIRP Irp
Definition: csq.h:116
#define STATUS_NOT_SUPPORTED
Definition: d3dkmdt.h:48
#define __in
Definition: dbghelp.h:35
#define __inout
Definition: dbghelp.h:50
#define __in_opt
Definition: dbghelp.h:38
#define __out
Definition: dbghelp.h:62
#define TRACINGPNP
Definition: dbgtrace.h:67
#define NULL
Definition: types.h:112
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGPNP, "Enter, WDFDEVICE %p", Device)
PFX_DRIVER_GLOBALS fxDriverGlobals
DriverGlobals
__inline PFX_DRIVER_GLOBALS GetFxDriverGlobals(__in PWDF_DRIVER_GLOBALS DriverGlobals)
Definition: fxglobals.h:597
FxIrp * irp
GLfloat param
Definition: glext.h:5796
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
_Must_inspect_result_ typedef _Out_ PHIDP_CAPS Capabilities
Definition: hidclass.h:103
#define ASSERT(a)
Definition: mode.c:44
#define _Must_inspect_result_
Definition: no_sal2.h:62
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:325
#define ARGUMENT_PRESENT(ArgumentPointer)
@ PowerSystemWorking
Definition: ntpoapi.h:36
@ PowerSystemHibernate
Definition: ntpoapi.h:40
enum _SYSTEM_POWER_STATE SYSTEM_POWER_STATE
IO_WORKITEM_ROUTINE _DeviceUsageNotificationWorkItem
Definition: pnpprivkm.hpp:75
FxLibraryGlobalsType FxLibraryGlobals
Definition: globals.cpp:95
#define STATUS_SUCCESS
Definition: shellext.h:65
#define TRACE_LEVEL_ERROR
Definition: storswtr.h:27
PFN_POX_REGISTER_DEVICE PoxRegisterDevice
Definition: fxglobals.h:742
FxDriver * Driver
Definition: fxglobals.h:374
Definition: format.c:80
Definition: ps.c:97
NTSTATUS SendDeviceUsageNotificationWorker(__in MxDeviceObject *RelatedDevice, __inout FxIrp *RelatedIrp, __in FxIrp *OriginalIrp, __in BOOLEAN Revert)
Definition: supportkm.cpp:264
_Must_inspect_result_ NTSTATUS GetStackCapabilities(__in PFX_DRIVER_GLOBALS DriverGlobals, __in MxDeviceObject *DeviceInStack, __in_opt PD3COLD_SUPPORT_INTERFACE D3ColdInterface, __out PSTACK_DEVICE_CAPABILITIES Capabilities)
Definition: supportkm.cpp:48
VOID CopyQueryInterfaceToIrpStack(__in PPOWER_THREAD_INTERFACE PowerThreadInterface, __in FxIrp *Irp)
Definition: supportkm.cpp:32
VOID SetD3ColdSupport(__in PFX_DRIVER_GLOBALS DriverGlobals, __in MxDeviceObject *DeviceInStack, __in PD3COLD_SUPPORT_INTERFACE D3ColdInterface, __in BOOLEAN UseD3Cold)
Definition: supportkm.cpp:172
_Must_inspect_result_ NTSTATUS SendDeviceUsageNotification(__in MxDeviceObject *RelatedDevice, __inout FxIrp *RelatedIrp, __in MxWorkItem *Workitem, __in FxIrp *OriginalIrp, __in BOOLEAN Revert)
Definition: supportkm.cpp:220
PVOID GetIoMgrObjectForWorkItemAllocation(VOID)
Definition: supportum.cpp:98
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
uint32_t ULONG
Definition: typedefs.h:59
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define STDCALL
Definition: wdf.h:45
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
PWDF_DRIVER_GLOBALS WdfDriverGlobals
enum _DEVICE_WAKE_DEPTH DEVICE_WAKE_DEPTH
DEVICE_CAPABILITIES
Definition: iotypes.h:965
#define IRP_MN_QUERY_CAPABILITIES
@ DeviceWakeDepthMaximum
Definition: iotypes.h:7485