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
WDF_DMA_ENABLER_CONFIG_INIT(_Out_ PWDF_DMA_ENABLER_CONFIG Config,_In_ WDF_DMA_PROFILE Profile,_In_ size_t MaximumLength)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
WDF_DMA_SYSTEM_PROFILE_CONFIG_INIT(_Out_ PWDF_DMA_SYSTEM_PROFILE_CONFIG DmaConfig,_In_ PHYSICAL_ADDRESS Address,_In_ DMA_WIDTH DmaWidth,_In_ PCM_PARTIAL_RESOURCE_DESCRIPTOR DmaDescriptor)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_
_IRQL_requires_max_(PASSIVE_LEVEL)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_
_IRQL_requires_max_(PASSIVE_LEVEL)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
_IRQL_requires_max_(DISPATCH_LEVEL)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
_IRQL_requires_max_(DISPATCH_LEVEL)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
_IRQL_requires_max_(PASSIVE_LEVEL)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
_IRQL_requires_max_(DISPATCH_LEVEL)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
_IRQL_requires_max_(DISPATCH_LEVEL)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