ReactOS  0.4.15-dev-3187-ge372f2b
fxdmaenablerapi.cpp
Go to the documentation of this file.
1 /*++
2 
3 Copyright (c) Microsoft Corporation
4 
5 Module Name:
6 
7  FxDmaEnablerAPI.cpp
8 
9 Abstract:
10 
11  Base for WDF DMA Enabler object APIs
12 
13 Environment:
14 
15  Kernel mode only.
16 
17 Notes:
18 
19 
20 Revision History:
21 
22 --*/
23 
24 #include "fxdmapch.hpp"
25 
26 extern "C" {
27 // #include "FxDmaEnablerAPI.tmh"
28 }
29 
30 //
31 // Extern "C" the entire file
32 //
33 extern "C" {
34 
38 WDFEXPORT(WdfDmaEnablerCreate)(
39  __in
41  __in
42  WDFDEVICE Device,
43  __in
45  __in_opt
47  __out
48  WDFDMAENABLER * DmaEnablerHandle
49  )
50 {
54  WDFDMAENABLER handle;
58 
59  //
60  // Validate the Device handle
61  //
63  Device,
65  (PVOID *) &pDevice,
67 
69  if (!NT_SUCCESS(status)) {
70  return status;
71  }
72 
75 
77 
79 
80  if (!NT_SUCCESS(status)) {
81  return status;
82  }
83 
84  if (Attributes != NULL && Attributes->ParentObject != NULL) {
86  Attributes->ParentObject,
88  (PVOID*)&pParent);
89 
91  FxDeviceBase * pSearchDevice;
92 
93  //
94  // If a parent object is passed-in it must be descendent of device.
95  // DmaEnabler stores device and uses it during dispose
96  // (to remove it from dmaenabler list maintained at device level),
97  // so DmaEnabler cannot outlive device.
98  //
99 
100  pSearchDevice = FxDeviceBase::_SearchForDevice(pParent, NULL);
101 
102  if (pSearchDevice == NULL) {
104 
107  "Attributes->ParentObject 0x%p must have WDFDEVICE as an "
108  "eventual ancestor, %!STATUS!",
109  Attributes->ParentObject, status);
110 
111  return status;
112  }
113  else if (pSearchDevice != pDevice) {
115 
118  "Attributes->ParentObject 0x%p ancestor is WDFDEVICE %p, but "
119  "not the same WDFDEVICE 0x%p passed to WdfDmaEnablerCreate, "
120  "%!STATUS!",
121  Attributes->ParentObject, pSearchDevice->GetHandle(),
122  Device, status);
123 
124  return status;
125  }
126  }
127  else {
128  //
129  // For < 1.11 drivers we only allow pDevice to be the parent
130  // since that is what we were blindly setting the parent to.
131  //
132  // Using the passed-in parent for such drivers could cause
133  // side-effects such as earlier deletion of DmaEnabler object. So
134  // we don't do that.
135  //
136  // We cause this verifier breakpoint to warn downlevel drivers
137  // that the parent they passed in gets ignored.
138  //
139  if (pParent != pDevice) {
142  "For drivers bound to version <= 1.9 "
143  "WdfDmaEnablerCreate uses WDFDEVICE as the "
144  "parent object for the dma enabler object. "
145  "Attributes->ParentObject 0x%p, which is different from "
146  "WDFDEVICE 0x%p, gets ignored. Please note that DmaEnabler "
147  "would be disposed only when device is disposed.",
148  Attributes->ParentObject, Device);
149 
152  }
153  }
154 
155  pParent = pDevice;
156  }
157  }
158  else {
159  pParent = pDevice;
160  }
161 
162  {
164  sizeof(WDF_DMA_ENABLER_CONFIG) :
166 
167  if (Config->Size != expectedSize) {
169 
172  "WDF_DMA_ENABLER_CONFIG Size 0x%x, expected 0x%x, %!STATUS!",
173  Config->Size, expectedSize, status);
174 
175  return status;
176  }
177 
178 
179  //
180  // Normalize DMA config structure if necessary.
181  //
182  if (Config->Size < sizeof(WDF_DMA_ENABLER_CONFIG)) {
183  //
184  // Init new fields to default values.
185  //
187  Config->Profile,
188  Config->MaximumLength);
189  //
190  // Copy over existing fields and readjust the struct size.
191  //
193  dmaConfig.Size = sizeof(dmaConfig);
194 
195  //
196  // Use new config structure from now on.
197  //
198  Config = &dmaConfig;
199  }
200  }
201 
202  switch (Config->Profile) {
203  case WdfDmaProfilePacket:
209  case WdfDmaProfileSystem:
211  break;
212  default:
216  "DMA Profile value %d is unknown, %!STATUS!",
217  Config->Profile, status);
218  return status;
219  }
220 
221  if (Config->MaximumLength == 0) {
223 
226  "Config MaximumLength of zero is invalid, %!STATUS!",
227  status);
228 
229  return status;
230  }
231 
232  //
233  // Ok: create a new DmaEnabler
234  //
237 
238  if (pDmaEnabler == NULL) {
240 
242  "Could not allocate memory for a WDFDMAENABLER, "
243  "%!STATUS!", status);
244 
245  return status;
246  }
247 
248  //
249  // Assign this FxDmaEnabler to its parent FxDevice object.
250  //
252 
254  //
255  // Ok: start this DmaEnabler.
256  //
257  status = pDmaEnabler->Initialize( Config, pDevice );
258  }
259 
260  if (NT_SUCCESS(status)) {
261  //
262  // Only return a valid handle on success.
263  //
265  }
266  else {
267  pDmaEnabler->DeleteFromFailedCreate();
268  }
269 
270  return status;
271 }
272 
274 size_t
275 WDFEXPORT(WdfDmaEnablerGetMaximumLength)(
276  __in
278  __in
279  WDFDMAENABLER DmaEnabler
280  )
281 {
283 
285  DmaEnabler,
287  (PVOID *) &pDmaEnabler);
288 
289  return pDmaEnabler->GetMaximumLength();
290 }
291 
293 size_t
294 WDFEXPORT(WdfDmaEnablerGetMaximumScatterGatherElements)(
295  __in
297  __in
298  WDFDMAENABLER DmaEnabler
299  )
300 {
302 
304  DmaEnabler,
306  (PVOID *) &pDmaEnabler);
307 
308  return pDmaEnabler->GetMaxSGElements();
309 }
310 
311 
313 VOID
314 WDFEXPORT(WdfDmaEnablerSetMaximumScatterGatherElements)(
315  __in
317  __in
318  WDFDMAENABLER DmaEnabler,
319  __in
320  __drv_when(MaximumElements == 0, __drv_reportError(MaximumElements cannot be zero))
321  size_t MaximumElements
322  )
323 {
327 
329  DmaEnabler,
331  (PVOID *) &pDmaEnabler,
333 
335  if (!NT_SUCCESS(status)) {
336  return;
337  }
338 
339  if (MaximumElements == 0) {
342  "Cannot set MaximumElements of zero on WDFDMAENABLER %p",
343  DmaEnabler);
344  return;
345  }
346 
347  pDmaEnabler->SetMaxSGElements(MaximumElements);
348 }
349 
351 size_t
352 WDFEXPORT(WdfDmaEnablerGetFragmentLength)(
353  __in
355  __in
356  WDFDMAENABLER DmaEnabler,
357  __in
359  )
360 {
362  size_t length;
364 
366  DmaEnabler,
368  (PVOID *) &pDmaEnabler,
370 
371  switch (DmaDirection) {
372 
374  length = pDmaEnabler->GetReadDmaDescription()->MaximumFragmentLength;
375  break;
376 
378  length = pDmaEnabler->GetWriteDmaDescription()->MaximumFragmentLength;
379  break;
380 
381  default:
382  length = 0;
384  "Invalid value for Dma direction %d, %p",
387  break;
388  }
389 
390  return length;
391 }
392 
395 WDFEXPORT(WdfDmaEnablerWdmGetDmaAdapter)(
396  __in
398  __in
399  WDFDMAENABLER DmaEnabler,
400  __in
402  )
403 {
407 
409  DmaEnabler,
411  (PVOID *) &pDmaEnabler,
413 
414  switch (DmaDirection) {
415 
417  adapter = pDmaEnabler->GetReadDmaDescription()->AdapterObject;
418  break;
419 
421  adapter = pDmaEnabler->GetWriteDmaDescription()->AdapterObject;
422  break;
423 
424  default:
425  adapter = NULL;
427  "Invalid value for Dma direction %d, %p",
430  break;
431  }
432 
433  return adapter;
434 }
435 
438 NTSTATUS
439 WDFEXPORT(WdfDmaEnablerConfigureSystemProfile)(
440  __in
442  __in
443  WDFDMAENABLER DmaEnabler,
444  __in
446  __in
448  )
449 {
452 
454 
456  DmaEnabler,
458  (PVOID *) &pDmaEnabler,
460 
461  //
462  // Verify the DMA config
463  //
464 
466  {
469  "ProfileConfig must be non-null, %!STATUS!",
470  status);
472  return status;
473  }
474 
476  {
478 
480  "WDF_DMA_SYSTEM_PROFILE_CONFIG Size 0x%x, expected 0x%x, %!STATUS!",
482 
484 
485  return status;
486  }
487 
488  if (ProfileConfig->DmaDescriptor == NULL)
489  {
491 
493  "ProfileConfig (%p) may not have NULL DmaDescriptor, %!STATUS!",
495 
497 
498  return status;
499  }
500 
506  "ConfigDirection 0x%x is an invalid value, %!STATUS!",
508  return status;
509  }
510 
511  status = pDmaEnabler->ConfigureSystemAdapter(ProfileConfig,
513  return status;
514 }
515 
516 } // extern "C"
PFX_DRIVER_GLOBALS pFxDriverGlobals
__in WDFDMAENABLER DmaEnabler
_Must_inspect_result_ __in WDFDEVICE Device
pDmaEnabler
return adapter
_Must_inspect_result_ _In_ WDFDMAENABLER _In_ PWDF_DMA_SYSTEM_PROFILE_CONFIG ProfileConfig
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define __drv_reportError(why)
Definition: driverspecs.h:319
#define STATUS_INFO_LENGTH_MISMATCH
Definition: udferr_usr.h:133
#define __in_opt
Definition: dbghelp.h:38
WDFDEVICE __inline GetHandle(VOID)
Definition: fxdevice.hpp:237
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define STATUS_WDF_OBJECT_ATTRIBUTES_INVALID
Definition: wdfstatus.h:171
LONG NTSTATUS
Definition: precomp.h:26
WDF_DMA_PROFILE Profile
DriverGlobals
size_t length
struct _WDF_DMA_ENABLER_CONFIG WDF_DMA_ENABLER_CONFIG
__in WDFDMAENABLER __in WDF_DMA_DIRECTION DmaDirection
_Must_inspect_result_ __in WDFDMAENABLER __in PWDF_DMA_SYSTEM_PROFILE_CONFIG __in WDF_DMA_DIRECTION ConfigDirection
static FxDeviceBase * _SearchForDevice(__in FxObject *Object, __out_opt IFxHasCallbacks **Callbacks)
#define TRACINGDMA
Definition: dbgtrace.h:71
__inline _Must_inspect_result_ BOOLEAN IsDownlevelVerificationEnabled()
Definition: fxglobals.h:314
#define WDFEXPORT(a)
Definition: fxmacros.hpp:157
GLenum GLuint GLenum GLsizei length
Definition: glext.h:5579
#define __out
Definition: dbghelp.h:62
NTSTATUS status
WDFDMAENABLER handle
int zero
Definition: sehframes.cpp:29
_Must_inspect_result_ BOOLEAN IsVersionGreaterThanOrEqualTo(__in ULONG Major, __in ULONG Minor)
Definition: globalskm.cpp:92
__in WDFDMAENABLER __in __drv_when(MaximumElements==0, __drv_reportError(MaximumElements cannot be zero)) size_t MaximumElements)
_Must_inspect_result_ __in WDFDMAENABLER __in PWDF_DMA_SYSTEM_PROFILE_CONFIG ProfileConfig
_In_ WDFDMAENABLER _In_ WDF_DMA_DIRECTION DmaDirection
__inline NTSTATUS FxVerifierCheckIrqlLevel(__in PFX_DRIVER_GLOBALS FxDriverGlobals, __in KIRQL Irql)
Definition: fxverifier.h:158
FxDeviceBase * pDevice
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
WDF_DMA_ENABLER_CONFIG dmaConfig
_Must_inspect_result_ __in WDFDEVICE __in WDF_DMA_ENABLER_CONFIG __in_opt WDF_OBJECT_ATTRIBUTES __out WDFDMAENABLER * DmaEnablerHandle
FxObject * pParent
FxObjectHandleGetPtr(GetFxDriverGlobals(DriverGlobals), DmaEnabler, FX_TYPE_DMA_ENABLER,(PVOID *) &pDmaEnabler)
_Must_inspect_result_ NTSTATUS FxValidateObjectAttributes(__in PFX_DRIVER_GLOBALS FxDriverGlobals, __in PWDF_OBJECT_ATTRIBUTES Attributes, __in ULONG Flags=FX_VALIDATE_OPTION_NONE_SPECIFIED)
#define PASSIVE_LEVEL
Definition: env_spec_w32.h:693
#define _Must_inspect_result_
Definition: ms_sal.h:558
_Must_inspect_result_ _In_ WDFDEVICE Device
Definition: wdfchildlist.h:474
FxPointerNotNull(pFxDriverGlobals, DmaEnablerHandle)
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_CHILD_LIST_CONFIG Config
Definition: wdfchildlist.h:474
#define TRACE_LEVEL_ERROR
Definition: storswtr.h:27
#define TRACE_LEVEL_WARNING
Definition: storswtr.h:28
_Must_inspect_result_ __drv_maxIRQL(PASSIVE_LEVEL) NTSTATUS WDFEXPORT(WdfDmaEnablerCreate)(__in PWDF_DRIVER_GLOBALS DriverGlobals
#define DISPATCH_LEVEL
Definition: env_spec_w32.h:696
FxObjectHandleGetPtrAndGlobals(GetFxDriverGlobals(DriverGlobals), Device, FX_TYPE_DEVICE_BASE,(PVOID *) &pDevice, &pFxDriverGlobals)
_Must_inspect_result_ __in WDFDEVICE __in WDF_DMA_ENABLER_CONFIG * Config
_Must_inspect_result_ _In_ WDFDMAENABLER _In_ PWDF_DMA_SYSTEM_PROFILE_CONFIG _In_ WDF_DMA_DIRECTION ConfigDirection
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGPNP, "Enter, WDFDEVICE %p", Device)
#define NULL
Definition: types.h:112
_Must_inspect_result_ _In_ WDFDMAENABLER DmaEnabler
enum _WDF_DMA_DIRECTION WDF_DMA_DIRECTION
unsigned int ULONG
Definition: retypes.h:1
_Must_inspect_result_ __in WDFDEVICE __in WDF_DMA_ENABLER_CONFIG __in_opt WDF_OBJECT_ATTRIBUTES * Attributes
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
FORCEINLINE VOID WDF_DMA_ENABLER_CONFIG_INIT(_Out_ PWDF_DMA_ENABLER_CONFIG Config, _In_ WDF_DMA_PROFILE Profile, _In_ size_t MaximumLength)
__inline PFX_DRIVER_GLOBALS GetFxDriverGlobals(__in PWDF_DRIVER_GLOBALS DriverGlobals)
Definition: fxglobals.h:597
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DMA_ENABLER_CONFIG _In_opt_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFDMAENABLER * DmaEnablerHandle
#define __in
Definition: dbghelp.h:35
FxVerifierDbgBreakPoint(pFxDriverGlobals)
_Must_inspect_result_ _In_ WDFDMAENABLER _In_ _In_opt_ PWDF_OBJECT_ATTRIBUTES Attributes
Definition: ps.c:97