ReactOS  0.4.15-dev-3331-g8ebe441
supportkm.cpp
Go to the documentation of this file.
1 /*++
2 
3 Copyright (c) Microsoft Corporation
4 
5 Module Name:
6 
7  supportKM.cpp
8 
9 Abstract:
10 
11  This module implements the pnp support routines.
12 
13 Author:
14 
15 
16 Environment:
17 
18  kernel mode only
19 
20 Revision 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 
31 VOID
33  __in PPOWER_THREAD_INTERFACE PowerThreadInterface,
34  __in FxIrp* Irp
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;
56  FxAutoIrp irp;
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 
135  for (i = PowerSystemWorking; i <= PowerSystemHibernate; i++) {
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 
163 Done:
164  if (DeviceInStack->GetObject() != NULL) {
165  DeviceInStack->DereferenceObject();
166  }
167 
168  return status;
169 }
170 
171 VOID
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 
188 PVOID
190  VOID
191  )
192 /*++
193 Routine description:
194  Returns an IO manager object that can be passed in to IoAllocateWorkItem
195 
196 Arguments:
197  None
198 
199 Return 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 
210 BOOLEAN
212  VOID
213  )
214 {
216 }
217 
219 NTSTATUS
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,
256  OriginalIrp,
257  Revert);
258  }
259 
260  return status;
261 }
262 
263 NTSTATUS
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 
297 VOID
298 STDCALL
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 
return STATUS_NOT_SUPPORTED
NTSTATUS SendDeviceUsageNotificationWorker(__in MxDeviceObject *RelatedDevice, __inout FxIrp *RelatedIrp, __in FxIrp *OriginalIrp, __in BOOLEAN Revert)
Definition: supportkm.cpp:264
VOID SetMajorFunction(__in UCHAR MajorFunction)
Definition: fxirpum.cpp:905
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
VOID SetStatus(__in NTSTATUS Status)
Definition: fxirpum.cpp:457
#define __in_opt
Definition: dbghelp.h:38
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
PFN_POX_REGISTER_DEVICE PoxRegisterDevice
Definition: fxglobals.h:742
static BOOLEAN _SystemManagedIdleTimeoutAvailable(VOID)
Definition: supportkm.cpp:211
#define IRP_MJ_PNP
Definition: cdrw_usr.h:52
LONG NTSTATUS
Definition: precomp.h:26
Definition: fxirp.hpp:28
VOID CopyQueryInterfaceToIrpStack(__in PPOWER_THREAD_INTERFACE PowerThreadInterface, __in FxIrp *Irp)
Definition: supportkm.cpp:32
DEVICE_CAPABILITIES
Definition: iotypes.h:965
static stack_node_t * stack
Definition: rpn_ieee.c:37
DriverGlobals
enum _SYSTEM_POWER_STATE SYSTEM_POWER_STATE
enum _DEVICE_WAKE_DEPTH DEVICE_WAKE_DEPTH
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
_In_ PIRP Irp
Definition: csq.h:116
CHECK_RETURN_IF_USER_MODE NTSTATUS SendIrpSynchronously(__in MdDeviceObject DeviceObject)
Definition: fxirpum.cpp:151
_Must_inspect_result_ typedef _Out_ PHIDP_CAPS Capabilities
Definition: hidclass.h:103
FxDriver * Driver
Definition: fxglobals.h:374
_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
_Must_inspect_result_ NTSTATUS SendDeviceUsageNotification(__in MxDeviceObject *RelatedDevice, __inout FxIrp *RelatedIrp, __in MxWorkItem *Workitem, __in FxIrp *OriginalIrp, __in BOOLEAN Revert)
Definition: supportkm.cpp:220
#define __out
Definition: dbghelp.h:62
unsigned char BOOLEAN
VOID STDCALL _DeviceUsageNotificationWorkItem(__in MdDeviceObject DeviceObject, __in PVOID Context)
Definition: supportkm.cpp:299
Definition: _stack.h:47
PWDF_DRIVER_GLOBALS WdfDriverGlobals
#define STDCALL
Definition: wdf.h:45
#define ASSERT(a)
Definition: mode.c:44
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define ARGUMENT_PRESENT(ArgumentPointer)
GLfloat param
Definition: glext.h:5796
VOID SetD3ColdSupport(__in PFX_DRIVER_GLOBALS DriverGlobals, __in MxDeviceObject *DeviceInStack, __in PD3COLD_SUPPORT_INTERFACE D3ColdInterface, __in BOOLEAN UseD3Cold)
Definition: supportkm.cpp:172
static _Must_inspect_result_ MdIrp AllocateIrp(_In_ CCHAR StackSize, _In_opt_ FxDevice *Device=NULL)
Definition: fxirpum.cpp:1089
#define __inout
Definition: dbghelp.h:50
_In_ PTRANSFER_PACKET _In_ ULONG _In_ PIRP OriginalIrp
Definition: classp.h:1757
#define _Must_inspect_result_
Definition: ms_sal.h:558
FxLibraryGlobalsType FxLibraryGlobals
Definition: globals.cpp:95
#define TRACE_LEVEL_ERROR
Definition: storswtr.h:27
__inline MdDriverObject GetDriverObject(VOID)
Definition: fxdriver.hpp:252
#define TRACINGPNP
Definition: dbgtrace.h:67
__inline MdDeviceObject GetObject(VOID)
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
MdIrp GetIrp(VOID)
Definition: fxirpum.cpp:15
PFX_DRIVER_GLOBALS fxDriverGlobals
__inline VOID SetObject(__in_opt MdDeviceObject DeviceObject)
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGPNP, "Enter, WDFDEVICE %p", Device)
VOID DereferenceObject()
#define NULL
Definition: types.h:112
_Must_inspect_result_ PVOID GetIoMgrObjectForWorkItemAllocation(VOID)
Definition: supportkm.cpp:189
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
VOID ClearNextStack(VOID)
Definition: fxirpum.cpp:1183
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
VOID SetMinorFunction(__in UCHAR MinorFunction)
Definition: fxirpum.cpp:967
#define STATUS_SUCCESS
Definition: shellext.h:65
__inline PFX_DRIVER_GLOBALS GetFxDriverGlobals(__in PWDF_DRIVER_GLOBALS DriverGlobals)
Definition: fxglobals.h:597
MdIrp SetIrp(MdIrp irp)
Definition: fxirpkm.hpp:71
#define __in
Definition: dbghelp.h:35
static SERVICE_STATUS status
Definition: service.c:31
VOID SetParameterDeviceCapabilities(__in PDEVICE_CAPABILITIES DeviceCapabilities)
Definition: fxirpum.cpp:1145
FxIrp * irp
#define IRP_MN_QUERY_CAPABILITIES
Definition: ps.c:97