1 /*++
2 
3 Copyright (c) Microsoft Corporation.  All rights reserved.
4 
5 _WdfVersionBuild_
6 
7 Module Name:
8 
9     WdfDmaEnabler.h
10 
11 Abstract:
12 
13     WDF DMA Enabler support
14 
15 Environment:
16 
17     Kernel mode only.
18 
19 Notes:
20 
21 Revision History:
22 
23 --*/
24 
25 //
26 // NOTE: This header is generated by stubwork.  Please make any
27 //       modifications to the corresponding template files
28 //       (.x or .y) and use stubwork to regenerate the header
29 //
30 
31 #ifndef _WDFDMAENABLER_H_
32 #define _WDFDMAENABLER_H_
33 
34 #ifndef WDF_EXTERN_C
35   #ifdef __cplusplus
36     #define WDF_EXTERN_C       extern "C"
37     #define WDF_EXTERN_C_START extern "C" {
38     #define WDF_EXTERN_C_END   }
39   #else
40     #define WDF_EXTERN_C
41     #define WDF_EXTERN_C_START
42     #define WDF_EXTERN_C_END
43   #endif
44 #endif
45 
46 WDF_EXTERN_C_START
47 
48 
49 
50 #if (NTDDI_VERSION >= NTDDI_WIN2K)
51 
52 typedef enum _WDF_DMA_PROFILE {
53     WdfDmaProfileInvalid = 0,
54     WdfDmaProfilePacket,
55     WdfDmaProfileScatterGather,
56     WdfDmaProfilePacket64,
57     WdfDmaProfileScatterGather64,
58     WdfDmaProfileScatterGatherDuplex,
59     WdfDmaProfileScatterGather64Duplex,
60     WdfDmaProfileSystem,
61     WdfDmaProfileSystemDuplex,
62 } WDF_DMA_PROFILE;
63 
64 typedef enum _WDF_DMA_DIRECTION {
65     WdfDmaDirectionReadFromDevice = FALSE,
66     WdfDmaDirectionWriteToDevice = TRUE,
67 } WDF_DMA_DIRECTION;
68 
69 
70 
71 //
72 // DMA power event callbacks
73 //
74 typedef
75 _Function_class_(EVT_WDF_DMA_ENABLER_FILL)
76 _IRQL_requires_same_
77 _IRQL_requires_max_(PASSIVE_LEVEL)
78 NTSTATUS
79 STDCALL
80 EVT_WDF_DMA_ENABLER_FILL(
81     _In_
82     WDFDMAENABLER DmaEnabler
83     );
84 
85 typedef EVT_WDF_DMA_ENABLER_FILL *PFN_WDF_DMA_ENABLER_FILL;
86 
87 typedef
88 _Function_class_(EVT_WDF_DMA_ENABLER_FLUSH)
89 _IRQL_requires_same_
90 _IRQL_requires_max_(PASSIVE_LEVEL)
91 NTSTATUS
92 STDCALL
93 EVT_WDF_DMA_ENABLER_FLUSH(
94     _In_
95     WDFDMAENABLER DmaEnabler
96     );
97 
98 typedef EVT_WDF_DMA_ENABLER_FLUSH *PFN_WDF_DMA_ENABLER_FLUSH;
99 
100 typedef
101 _Function_class_(EVT_WDF_DMA_ENABLER_ENABLE)
102 _IRQL_requires_same_
103 _IRQL_requires_max_(PASSIVE_LEVEL)
104 NTSTATUS
105 STDCALL
106 EVT_WDF_DMA_ENABLER_ENABLE(
107     _In_
108     WDFDMAENABLER DmaEnabler
109     );
110 
111 typedef EVT_WDF_DMA_ENABLER_ENABLE *PFN_WDF_DMA_ENABLER_ENABLE;
112 
113 typedef
114 _Function_class_(EVT_WDF_DMA_ENABLER_DISABLE)
115 _IRQL_requires_same_
116 _IRQL_requires_max_(PASSIVE_LEVEL)
117 NTSTATUS
118 STDCALL
119 EVT_WDF_DMA_ENABLER_DISABLE(
120     _In_
121     WDFDMAENABLER DmaEnabler
122     );
123 
124 typedef EVT_WDF_DMA_ENABLER_DISABLE *PFN_WDF_DMA_ENABLER_DISABLE;
125 
126 typedef
127 _Function_class_(EVT_WDF_DMA_ENABLER_SELFMANAGED_IO_START)
128 _IRQL_requires_same_
129 _IRQL_requires_max_(PASSIVE_LEVEL)
130 NTSTATUS
131 STDCALL
132 EVT_WDF_DMA_ENABLER_SELFMANAGED_IO_START(
133     _In_
134     WDFDMAENABLER DmaEnabler
135     );
136 
137 typedef EVT_WDF_DMA_ENABLER_SELFMANAGED_IO_START *PFN_WDF_DMA_ENABLER_SELFMANAGED_IO_START;
138 
139 typedef
140 _Function_class_(EVT_WDF_DMA_ENABLER_SELFMANAGED_IO_STOP)
141 _IRQL_requires_same_
142 _IRQL_requires_max_(PASSIVE_LEVEL)
143 NTSTATUS
144 STDCALL
145 EVT_WDF_DMA_ENABLER_SELFMANAGED_IO_STOP(
146     _In_
147     WDFDMAENABLER DmaEnabler
148     );
149 
150 typedef EVT_WDF_DMA_ENABLER_SELFMANAGED_IO_STOP *PFN_WDF_DMA_ENABLER_SELFMANAGED_IO_STOP;
151 
152 
153 #define  WDF_DMA_ENABLER_UNLIMITED_FRAGMENTS ((ULONG) -1)
154 
155 typedef enum _WDF_DMA_ENABLER_CONFIG_FLAGS {
156     //
157     // This flag only applies to the following DMA profiles:
158     //  WdfDmaProfileScatterGather,
159     //  WdfDmaProfileScatterGather64,
160     //  WdfDmaProfileScatterGatherDuplex and
161     //  WdfDmaProfileScatterGather64Duplex
162     //
163     // When this flag is not set and the profile is one of the above, WDF
164     // creates a SGLookasideList used by this DMA adapter's transaction
165     // objects. The SGLookasideList is initialized to allow the max specified
166     // transfer length. When the transaction is executed, WDF calls the WDM
167     // DMA's BuildScatterGatherList entry function. Forward progress drivers
168     // must use this option. This is the default option.
169     //
170     // When this flag is set and the profile is one of the above, WDF
171     // does not create a SGLookasideList. When the transaction is executed,
172     // WDF calls the WDM DMA's GetScatterGatherList entry function.
173     //
174     WDF_DMA_ENABLER_CONFIG_NO_SGLIST_PREALLOCATION  = 0x00000001,
175 } WDF_DMA_ENABLER_CONFIG_FLAGS;
176 
177 
178 typedef struct _WDF_DMA_ENABLER_CONFIG {
179     //
180     // Size of this structure in bytes
181     //
182     ULONG                Size;
183 
184     //
185     // One of the above WDF_DMA_PROFILES
186     //
187     WDF_DMA_PROFILE      Profile;
188 
189     //
190     // Maximum DMA Transfer handled in bytes.
191     //
192     size_t               MaximumLength;
193 
194     //
195     // The various DMA PnP/Power event callbacks
196     //
197     PFN_WDF_DMA_ENABLER_FILL                  EvtDmaEnablerFill;
198     PFN_WDF_DMA_ENABLER_FLUSH                 EvtDmaEnablerFlush;
199     PFN_WDF_DMA_ENABLER_DISABLE               EvtDmaEnablerDisable;
200     PFN_WDF_DMA_ENABLER_ENABLE                EvtDmaEnablerEnable;
201     PFN_WDF_DMA_ENABLER_SELFMANAGED_IO_START  EvtDmaEnablerSelfManagedIoStart;
202     PFN_WDF_DMA_ENABLER_SELFMANAGED_IO_STOP   EvtDmaEnablerSelfManagedIoStop;
203 
204     //
205     // Overrides the address width specified by the DMA profile.
206     //
207     ULONG               AddressWidthOverride;
208 
209     //
210     // Overrides the version of the WDM DMA interfaces that WDF uses
211     // (0 for default).
212     //
213     ULONG               WdmDmaVersionOverride;
214 
215     //
216     // Bit field combination of values from the WDF_DMA_ENABLER_CONFIG_FLAGS
217     // enumeration
218     //
219     ULONG               Flags;
220 } WDF_DMA_ENABLER_CONFIG, *PWDF_DMA_ENABLER_CONFIG;
221 
222 FORCEINLINE
223 VOID
224 WDF_DMA_ENABLER_CONFIG_INIT(
225     _Out_ PWDF_DMA_ENABLER_CONFIG Config,
226     _In_  WDF_DMA_PROFILE    Profile,
227     _In_  size_t             MaximumLength
228     )
229 {
230     RtlZeroMemory(Config, sizeof(WDF_DMA_ENABLER_CONFIG));
231 
232     Config->Size = sizeof(WDF_DMA_ENABLER_CONFIG);
233     Config->Profile = Profile;
234     Config->MaximumLength = MaximumLength;
235 }
236 
237 typedef struct _WDF_DMA_SYSTEM_PROFILE_CONFIG {
238 
239     //
240     // The size of this structure in bytes
241     //
242     ULONG                 Size;
243 
244     //
245     // Specifies that the transfer is controlled by the device's DMA
246     // request line.
247     //
248 
249     BOOLEAN               DemandMode;
250 
251     //
252     // Specifies that the DMA engine will loop back to the beginning
253     // of the buffer once it reaches the end.
254     //
255 
256     BOOLEAN               LoopedTransfer;
257 
258     //
259     // Width of the register to DMA to/from
260     //
261 
262     DMA_WIDTH             DmaWidth;
263 
264     //
265     // The adress at which to write to the device
266     //
267     PHYSICAL_ADDRESS      DeviceAddress;
268 
269     //
270     // The translated resource descriptor for the DMA channel assigned
271     // the device during EvtDevicePrepareHardware
272     //
273     PCM_PARTIAL_RESOURCE_DESCRIPTOR DmaDescriptor;
274 
275 } WDF_DMA_SYSTEM_PROFILE_CONFIG, *PWDF_DMA_SYSTEM_PROFILE_CONFIG;
276 
277 FORCEINLINE
278 VOID
279 WDF_DMA_SYSTEM_PROFILE_CONFIG_INIT(
280     _Out_ PWDF_DMA_SYSTEM_PROFILE_CONFIG  DmaConfig,
281     _In_  PHYSICAL_ADDRESS                Address,
282     _In_  DMA_WIDTH                       DmaWidth,
283     _In_  PCM_PARTIAL_RESOURCE_DESCRIPTOR DmaDescriptor
284     )
285 {
286     RtlZeroMemory(DmaConfig, sizeof(WDF_DMA_SYSTEM_PROFILE_CONFIG));
287 
288     DmaConfig->Size = sizeof(WDF_DMA_SYSTEM_PROFILE_CONFIG);
289     DmaConfig->DeviceAddress = Address;
290     DmaConfig->DmaWidth = DmaWidth;
291     DmaConfig->DmaDescriptor = DmaDescriptor;
292 }
293 
294 //
295 // WDF Function: WdfDmaEnablerCreate
296 //
297 typedef
298 _Must_inspect_result_
299 _IRQL_requires_max_(PASSIVE_LEVEL)
300 WDFAPI
301 NTSTATUS
302 (STDCALL *PFN_WDFDMAENABLERCREATE)(
303     _In_
304     PWDF_DRIVER_GLOBALS DriverGlobals,
305     _In_
306     WDFDEVICE Device,
307     _In_
308     PWDF_DMA_ENABLER_CONFIG Config,
309     _In_opt_
310     PWDF_OBJECT_ATTRIBUTES Attributes,
311     _Out_
312     WDFDMAENABLER* DmaEnablerHandle
313     );
314 
315 _Must_inspect_result_
316 _IRQL_requires_max_(PASSIVE_LEVEL)
317 FORCEINLINE
318 NTSTATUS
319 WdfDmaEnablerCreate(
320     _In_
321     WDFDEVICE Device,
322     _In_
323     PWDF_DMA_ENABLER_CONFIG Config,
324     _In_opt_
325     PWDF_OBJECT_ATTRIBUTES Attributes,
326     _Out_
327     WDFDMAENABLER* DmaEnablerHandle
328     )
329 {
330     return ((PFN_WDFDMAENABLERCREATE) WdfFunctions[WdfDmaEnablerCreateTableIndex])(WdfDriverGlobals, Device, Config, Attributes, DmaEnablerHandle);
331 }
332 
333 //
334 // WDF Function: WdfDmaEnablerConfigureSystemProfile
335 //
336 typedef
337 _Must_inspect_result_
338 _IRQL_requires_max_(PASSIVE_LEVEL)
339 WDFAPI
340 NTSTATUS
341 (STDCALL *PFN_WDFDMAENABLERCONFIGURESYSTEMPROFILE)(
342     _In_
343     PWDF_DRIVER_GLOBALS DriverGlobals,
344     _In_
345     WDFDMAENABLER DmaEnabler,
346     _In_
347     PWDF_DMA_SYSTEM_PROFILE_CONFIG ProfileConfig,
348     _In_
349     WDF_DMA_DIRECTION ConfigDirection
350     );
351 
352 _Must_inspect_result_
353 _IRQL_requires_max_(PASSIVE_LEVEL)
354 FORCEINLINE
355 NTSTATUS
356 WdfDmaEnablerConfigureSystemProfile(
357     _In_
358     WDFDMAENABLER DmaEnabler,
359     _In_
360     PWDF_DMA_SYSTEM_PROFILE_CONFIG ProfileConfig,
361     _In_
362     WDF_DMA_DIRECTION ConfigDirection
363     )
364 {
365     return ((PFN_WDFDMAENABLERCONFIGURESYSTEMPROFILE) WdfFunctions[WdfDmaEnablerConfigureSystemProfileTableIndex])(WdfDriverGlobals, DmaEnabler, ProfileConfig, ConfigDirection);
366 }
367 
368 //
369 // WDF Function: WdfDmaEnablerGetMaximumLength
370 //
371 typedef
372 _IRQL_requires_max_(DISPATCH_LEVEL)
373 WDFAPI
374 size_t
375 (STDCALL *PFN_WDFDMAENABLERGETMAXIMUMLENGTH)(
376     _In_
377     PWDF_DRIVER_GLOBALS DriverGlobals,
378     _In_
379     WDFDMAENABLER DmaEnabler
380     );
381 
382 _IRQL_requires_max_(DISPATCH_LEVEL)
383 FORCEINLINE
384 size_t
385 WdfDmaEnablerGetMaximumLength(
386     _In_
387     WDFDMAENABLER DmaEnabler
388     )
389 {
390     return ((PFN_WDFDMAENABLERGETMAXIMUMLENGTH) WdfFunctions[WdfDmaEnablerGetMaximumLengthTableIndex])(WdfDriverGlobals, DmaEnabler);
391 }
392 
393 //
394 // WDF Function: WdfDmaEnablerGetMaximumScatterGatherElements
395 //
396 typedef
397 _IRQL_requires_max_(DISPATCH_LEVEL)
398 WDFAPI
399 size_t
400 (STDCALL *PFN_WDFDMAENABLERGETMAXIMUMSCATTERGATHERELEMENTS)(
401     _In_
402     PWDF_DRIVER_GLOBALS DriverGlobals,
403     _In_
404     WDFDMAENABLER DmaEnabler
405     );
406 
407 _IRQL_requires_max_(DISPATCH_LEVEL)
408 FORCEINLINE
409 size_t
410 WdfDmaEnablerGetMaximumScatterGatherElements(
411     _In_
412     WDFDMAENABLER DmaEnabler
413     )
414 {
415     return ((PFN_WDFDMAENABLERGETMAXIMUMSCATTERGATHERELEMENTS) WdfFunctions[WdfDmaEnablerGetMaximumScatterGatherElementsTableIndex])(WdfDriverGlobals, DmaEnabler);
416 }
417 
418 //
419 // WDF Function: WdfDmaEnablerSetMaximumScatterGatherElements
420 //
421 typedef
422 _IRQL_requires_max_(PASSIVE_LEVEL)
423 WDFAPI
424 VOID
425 (STDCALL *PFN_WDFDMAENABLERSETMAXIMUMSCATTERGATHERELEMENTS)(
426     _In_
427     PWDF_DRIVER_GLOBALS DriverGlobals,
428     _In_
429     WDFDMAENABLER DmaEnabler,
430     _In_
431     _When_(MaximumFragments == 0, __drv_reportError(MaximumFragments cannot be zero))
432     size_t MaximumFragments
433     );
434 
435 _IRQL_requires_max_(PASSIVE_LEVEL)
436 FORCEINLINE
437 VOID
438 WdfDmaEnablerSetMaximumScatterGatherElements(
439     _In_
440     WDFDMAENABLER DmaEnabler,
441     _In_
442     _When_(MaximumFragments == 0, __drv_reportError(MaximumFragments cannot be zero))
443     size_t MaximumFragments
444     )
445 {
446     ((PFN_WDFDMAENABLERSETMAXIMUMSCATTERGATHERELEMENTS) WdfFunctions[WdfDmaEnablerSetMaximumScatterGatherElementsTableIndex])(WdfDriverGlobals, DmaEnabler, MaximumFragments);
447 }
448 
449 //
450 // WDF Function: WdfDmaEnablerGetFragmentLength
451 //
452 typedef
453 _IRQL_requires_max_(DISPATCH_LEVEL)
454 WDFAPI
455 size_t
456 (STDCALL *PFN_WDFDMAENABLERGETFRAGMENTLENGTH)(
457     _In_
458     PWDF_DRIVER_GLOBALS DriverGlobals,
459     _In_
460     WDFDMAENABLER DmaEnabler,
461     _In_
462     WDF_DMA_DIRECTION DmaDirection
463     );
464 
465 _IRQL_requires_max_(DISPATCH_LEVEL)
466 FORCEINLINE
467 size_t
468 WdfDmaEnablerGetFragmentLength(
469     _In_
470     WDFDMAENABLER DmaEnabler,
471     _In_
472     WDF_DMA_DIRECTION DmaDirection
473     )
474 {
475     return ((PFN_WDFDMAENABLERGETFRAGMENTLENGTH) WdfFunctions[WdfDmaEnablerGetFragmentLengthTableIndex])(WdfDriverGlobals, DmaEnabler, DmaDirection);
476 }
477 
478 //
479 // WDF Function: WdfDmaEnablerWdmGetDmaAdapter
480 //
481 typedef
482 _IRQL_requires_max_(DISPATCH_LEVEL)
483 WDFAPI
484 PDMA_ADAPTER
485 (STDCALL *PFN_WDFDMAENABLERWDMGETDMAADAPTER)(
486     _In_
487     PWDF_DRIVER_GLOBALS DriverGlobals,
488     _In_
489     WDFDMAENABLER DmaEnabler,
490     _In_
491     WDF_DMA_DIRECTION DmaDirection
492     );
493 
494 _IRQL_requires_max_(DISPATCH_LEVEL)
495 FORCEINLINE
496 PDMA_ADAPTER
497 WdfDmaEnablerWdmGetDmaAdapter(
498     _In_
499     WDFDMAENABLER DmaEnabler,
500     _In_
501     WDF_DMA_DIRECTION DmaDirection
502     )
503 {
504     return ((PFN_WDFDMAENABLERWDMGETDMAADAPTER) WdfFunctions[WdfDmaEnablerWdmGetDmaAdapterTableIndex])(WdfDriverGlobals, DmaEnabler, DmaDirection);
505 }
506 
507 
508 
509 #endif // (NTDDI_VERSION >= NTDDI_WIN2K)
510 
511 
512 WDF_EXTERN_C_END
513 
514 #endif // _WDFDMAENABLER_H_
515 
516