ReactOS  0.4.15-dev-2153-g62b4c61
fxdmatransaction.hpp
Go to the documentation of this file.
1 //
2 // Copyright (C) Microsoft. All rights reserved.
3 //
4 #ifndef _FXDMATRANSACTION_HPP_
5 #define _FXDMATRANSACTION_HPP_
6 
7 extern "C" {
8 // #include "FxDmaTransaction.hpp.tmh"
9 }
10 
12 
13 //
14 // This type is used to allocate scatter-gather list of 1 element on the stack.
15 //
16 typedef DECLSPEC_ALIGN(MEMORY_ALLOCATION_ALIGNMENT) UCHAR UCHAR_MEMORY_ALIGNED;
17 
18 // begin_wpp enum
19 
20 //
21 // FxDmaTransactionStateCreated when the object is created.
22 // FxDmaTransactionStateInitialized when object is initialized using with
23 // Mdl/VA/Length.
24 // FxDmaTransactionStateReserved when driver calls AllocateResources until
25 // the adapter control routine returns
26 // FxDmaTransactionStateTransfer is called when the driver call Execute
27 // to start the DMA transfer.
28 // FxDmaTransactionStateTransferCompleted is when transfer is completed or
29 // aborted
30 // FxDmaTransactionStateTransferFailed is set if the framework is not able
31 // to start the transfer due to error.
32 // FxDmaTransactionStateReleased is set when the object is reinitailized for reuse
33 // FxDmaTransactionStateDeleted is set in the Dipose due to WdfObjectDelete
34 //
45 };
46 
47 //
48 // FxDmaCompletionTypeFull is used when the driver calls WdfDmaTransactionDmaComplete
49 // to indicate that last framgement has been transmitted fully and to initiate
50 // the transfer of next fragment.
51 // FxDmaCompletionTypePartial is used when the driver completes the transfer and
52 // specifies a amount of bytes it has transfered, and to initiate the next transfer
53 // from the untransmitted portion of the buffer.
54 // FxDmaCompletionTypeAbort i used when the driver calls DmaCompleteFinal to indicate
55 // that's the final transfer and not initiate anymore transfers for the remaining
56 // data.
57 //
62 };
63 
64 // end_wpp
65 
66 //
67 // This tag is used to track whether the request pointer in the transaction
68 // has a reference taken on it. Since the pointer is guaranteed to be
69 // 4-byte aligned this can be set and cleared without destroying the pointer.
70 //
71 #define FX_STRONG_REF_TAG 0x1
72 
73 //
74 // Simple set of macros to encode and decode tagged pointers.
75 //
76 #define FX_ENCODE_POINTER(T,p,tag) ((T*) ((ULONG_PTR) p | (ULONG_PTR) tag))
77 #define FX_DECODE_POINTER(T,p,tag) ((T*) ((ULONG_PTR) p & ~(ULONG_PTR) tag))
78 #define FX_IS_POINTER_ENCODED(p,tag) ((((ULONG_PTR) p & (ULONG_PTR) tag) == tag) ? TRUE : FALSE)
79 
80 //
81 // An uninitialized value for Dma completion status
82 //
83 
84 #define UNDEFINED_DMA_COMPLETION_STATUS ((DMA_COMPLETION_STATUS) -1)
85 
87 
88  friend class FxDmaEnabler;
89 
90 public:
91 
93  __in PFX_DRIVER_GLOBALS FxDriverGlobals,
94  __in USHORT ObjectSize,
95  __in USHORT ExtraSize,
97  );
98 
99  static
100  VOID
103  __in size_t CurrentOffset,
104  __in ULONG Transferred,
105  __deref_out PMDL *NextMdl,
106  __out size_t *NextOffset
107  );
108 
110  static
111  NTSTATUS
113  __in PMDL Mdl,
114  __in size_t CurrentOffset,
115  __in ULONG Length,
116  __in ULONG AvailableMapRegisters,
117  __out_opt PULONG PossibleTransferLength,
118  __out PULONG MapRegistersRequired
119  );
120 
121  virtual
122  BOOLEAN
123  Dispose(
124  VOID
125  );
126 
128  NTSTATUS
129  Initialize(
130  __in PFN_WDF_PROGRAM_DMA ProgramDmaFunction,
132  __in PMDL Mdl,
133  __in size_t Offset,
135  );
136 
138  virtual
139  NTSTATUS
141  VOID
142  )=0;
143 
145  NTSTATUS
146  Execute(
148  );
149 
151  virtual
152  NTSTATUS
154  VOID
155  )=0;
156 
158  virtual
159  NTSTATUS
161  VOID
162  )=0;
163 
164  BOOLEAN
165  DmaCompleted(
166  __in size_t TransferredLength,
167  __out NTSTATUS * ReturnStatus,
168  __in FxDmaCompletionType CompletionType
169  );
170 
172  virtual
173  NTSTATUS
175  VOID
176  )=0;
177 
178  VOID
180  __in BOOLEAN ForceRelease
181  );
182 
183  virtual
184  VOID
186  __in BOOLEAN ForceRelease
187  )=0;
188 
189  VOID
193  );
194 
195  __forceinline
196  size_t
198  VOID
199  )
200  {
201  return m_Transferred;
202  }
203 
204  __forceinline
205  FxDmaEnabler *
207  VOID
208  )
209  {
210  return m_DmaEnabler;
211  }
212 
213  __forceinline
214  FxRequest *
216  VOID
217  )
218  {
219  //
220  // Strip out the strong reference tag if it's set
221  //
225  }
226 
227  __forceinline
228  BOOLEAN
230  VOID
231  )
232  {
234  }
235 
236  __forceinline
237  VOID
240  )
241  {
243 
244  //
245  // Make sure the pointer doesn't have the strong ref flag set already
246  //
248 
250  }
251 
252  __forceinline
253  VOID
255  VOID
256  )
257  {
259  ASSERT(IsRequestReferenced() == false);
260 
261  //
262  // Take a reference on the irp to catch completion of request
263  // when there is a pending DMA transaction.
264  // While there is no need to take a reference on request itself,
265  // I'm keeping it to avoid regression as we are so close to
266  // shipping this.
267  //
269 
270  //
271  // Increment reference to this Request.
272  // See complementary section in WdfDmaTransactionDelete
273  // and WdfDmaTransactionRelease.
274  //
275  m_EncodedRequest->ADDREF( this );
276 
280  }
281 
282  __forceinline
283  VOID
285  VOID
286  )
287  {
290 
291  //
292  // Clear the referenced bit on the encoded request.
293  //
297 
298  //
299  // Release this reference to the Irp and FxRequest.
300  //
302 
303  m_EncodedRequest->RELEASE( this );
304  }
305 
306  __forceinline
307  VOID
309  VOID
310  )
311  {
312  if (IsRequestReferenced()) {
314  }
316  }
317 
318  __forceinline
319  size_t
321  VOID
322  )
323  {
324  return m_MaxFragmentLength;
325  }
326 
327  __forceinline
328  VOID
330  size_t MaximumFragmentLength
331  )
332  {
333  if (MaximumFragmentLength < m_AdapterInfo->MaximumFragmentLength) {
334  m_MaxFragmentLength = MaximumFragmentLength;
335  }
336  }
337 
338  __forceinline
339  size_t
341  VOID
342  )
343  {
345  }
346 
347  __forceinline
348  WDFDMATRANSACTION
350  VOID
351  )
352  {
353  return (WDFDMATRANSACTION) GetObjectHandle();
354  }
355 
356  PVOID
358  VOID
359  )
360  {
361  return m_TransferContext;
362  }
363 
364  VOID
367  );
368 
369  BOOLEAN
371  VOID
372  );
373 
376  VOID
377  )
378  {
379  return m_State;
380  }
381 
382 protected:
383 
385 
387 
389 
390  //
391  // Depending on the direction of the transfer, this one
392  // points to either m_ReadAdapterInfo or m_WriteAdapterInfo
393  // structure of the DMA enabler.
394  //
396 
397  //
398  // Request associated with this transfer. Encoding uses the
399  // FX_[EN|DE]CODE_POINTER macros with the FX_STRONG_REF_TAG
400  // to indicate whether the reference has been taken or not
401  //
403 
404  //
405  // Callback and context for ProgramDma function
406  //
407  // The callback is overloaded to also hold the callback for
408  // Packet & System transfer's Reserve callback (to save space.)
409  // This is possible because the driver may not call execute
410  // and reserve in parallel on the same transaction. Disambiguate
411  // using the state of the transaction.
412  //
415 
416  //
417  // The DMA transfer context (when using V3 DMA)
418  //
420 
421  //
422  // This is the first MDL of the transaction.
423  //
425 
426  //
427  // This is the MDL where the current transfer is being executed.
428  // If the data spans multiple MDL then this would be different
429  // from the startMDL when we stage large transfers and also
430  // if the driver performs partial transfers.
431  //
433 
434  //
435  // Starting offset in the first m_StartMdl. This might be same as
436  // m_StartMdl->StartVA.
437  //
439 
440  //
441  // Points to address where the next transfer will begin.
442  //
444 
445  //
446  // This is maximum length of transfer that can be made. This is
447  // computed based on the available map registers and driver
448  // configuration.
449  //
451 
452  //
453  // Length of the whole transaction.
454  //
456 
457  //
458  // Number of bytes pending to be transfered.
459  //
460  size_t m_Remaining;
461 
462  //
463  // Total number of bytes transfered.
464  //
466 
467  //
468  // Number of bytes transfered in the last transaction.
469  //
471 
472  //
473  // DMA flags for passing to GetScatterGatherListEx &
474  // AllocateAdapterChannelEx
475  //
476 
478 
479  static
480  PVOID
482  __in PMDL Mdl,
483  __in size_t Offset
484  )
485  {
486  return ((PUCHAR) MmGetMdlVirtualAddress(Mdl)) + Offset;
487  }
488 
489  virtual
490  VOID
492  VOID
493  )
494  {
495  return;
496  }
497 
498 };
499 
501 
502 public:
503 
505  __in PFX_DRIVER_GLOBALS FxDriverGlobals,
506  __in USHORT ExtraSize,
508  );
509 
510  virtual
511  BOOLEAN
512  Dispose(
513  VOID
514  );
515 
517  virtual
518  NTSTATUS
520  VOID
521  );
522 
524  virtual
525  NTSTATUS
527  VOID
528  );
529 
531  virtual
532  NTSTATUS
534  VOID
535  );
536 
538  virtual
539  NTSTATUS
541  VOID
542  );
543 
544  virtual
545  VOID
547  __in BOOLEAN ForceRelease
548  );
549 
551  static
552  NTSTATUS
553  _Create(
554  __in PFX_DRIVER_GLOBALS FxDriverGlobals,
557  __out WDFDMATRANSACTION* Transaction
558  );
559 
560 protected:
561 
562  //
563  // Scatter-Gather list provided by the system.
564  //
566 
567  //
568  // Preallocated memory from lookaside buffer for the
569  // scatter-gather list when running on XP and later OSes.
570  //
572 
573 
574 private:
575 
576  static
577  VOID
580  __in IRP * Irp,
582  __in VOID * Context
583  );
584 
586  NTSTATUS
588  __in PMDL Mdl,
589  __in size_t CurrentOffset,
590  __in ULONG Length,
593  )
594  {
596  KIRQL irql;
597 
599 
600  if (m_DmaEnabler->UsesDmaV3())
601  {
602  PDMA_OPERATIONS dmaOperations =
604 
605  status = dmaOperations->GetScatterGatherListEx(
609  Mdl,
610  CurrentOffset,
611  Length,
612  m_Flags,
614  Context,
616  NULL,
617  NULL,
618  NULL
619  );
620  }
621  else
622  {
626  Mdl,
627  GetStartVaFromOffset(Mdl, CurrentOffset),
628  Length,
630  Context,
632  }
633 
634  KeLowerIrql(irql);
635 
636  return status;
637  }
638 
639  VOID
642  )
643  {
644  KIRQL irql;
645 
647 
652  KeLowerIrql(irql);
653 
654  return;
655  }
656 
658  NTSTATUS
660  __in PMDL Mdl,
661  __in size_t CurrentOffset,
662  __in ULONG Length,
665  __in PVOID ScatterGatherBuffer,
666  __in ULONG ScatterGatherBufferLength
667  )
668  {
670  KIRQL irql;
671 
673 
674  if (m_DmaEnabler->UsesDmaV3()) {
675 
676  PDMA_OPERATIONS dmaOperations =
678  ULONG flags = 0;
679 
681  //
682  // Though the correct behavior is to pass the m_Flags to the
683  // BuildScatterGatherListEx function, the code was not doing it
684  // for versions <= 1.13. To reduce any chance of regression,
685  // the m_Flags is honored for drivers that are 1.15
686  // or newer.
687  //
688  flags = m_Flags;
689  }
690 
691  status = dmaOperations->BuildScatterGatherListEx(
695  Mdl,
696  CurrentOffset,
697  Length,
698  flags,
700  Context,
702  ScatterGatherBuffer,
703  ScatterGatherBufferLength,
704  NULL,
705  NULL,
706  NULL
707  );
708  }
709  else {
710 
714  Mdl,
715  GetStartVaFromOffset(Mdl, CurrentOffset),
716  Length,
718  Context,
720  ScatterGatherBuffer,
721  ScatterGatherBufferLength);
722  }
723 
724 
725  KeLowerIrql(irql);
726 
727  return status;
728  }
729 };
730 
732 
733 protected:
735  __in PFX_DRIVER_GLOBALS FxDriverGlobals,
736  __in USHORT ObjectSize,
737  __in USHORT ExtraSize,
739  );
740 
741 public:
742 
744  virtual
745  NTSTATUS
747  VOID
748  );
749 
751  NTSTATUS
757  );
758 
759  VOID
761  VOID
762  );
763 
765  virtual
766  NTSTATUS
768  VOID
769  );
770 
772  virtual
773  NTSTATUS
775  VOID
776  );
777 
779  virtual
780  NTSTATUS
782  VOID
783  );
784 
785  virtual
786  VOID
788  __in BOOLEAN ForceRelease
789  );
790 
792  static
793  NTSTATUS
794  _Create(
795  __in PFX_DRIVER_GLOBALS FxDriverGlobals,
798  __out WDFDMATRANSACTION* Transaction
799  );
800 
801  VOID
804  )
805  {
807  }
808 
809 protected:
810 
811  //
812  // Number of map registers to be used in this transfer.
813  // This value is the least of the number of map registers
814  // needed to satisfy the current transfer request, and the
815  // number of available map registers returned by IoGetDmaAdapter.
816  //
818 
819  //
820  // Opaque-value represents the map registers that the system has
821  // assigned for this transfer operation. We pass this value in
822  // FlushAdapterBuffers, FreeMapRegisters, and MapTransfer.
823  //
825 
826  //
827  // TRUE when the map register base above is valid. The HAL can give
828  // us a NULL map register base when double buffering isn't required,
829  // so we can't just do a NULL test on m_MapRegisterBase to know if
830  // the DMA channel is allocated.
831  //
833 
834  //
835  // For system-DMA this provides the offset from the original
836  // DeviceAddress used to compute the device register to or from which
837  // DMA should occur.
838  //
840 
841  //
842  // 0 if the transaction has not reserved the enabler. Otherwise
843  // this is the number of map registers requested for the reservation.
844  // This value persists across a reuse and reinitialization of the
845  // transaction, and is only cleared when the enabler is released.
846  //
848 
849  //
850  // These fields are used to defer completion or staging while another
851  // thread/CPU is already staging. They are protected by the
852  // transfer state lock.
853  //
854  // These values are cleared when checked, not in InitializeResources.
855  // It's possible for a transaction being staged to complete on another
856  // CPU, get reused and reinitialized. Clearing these values in
857  // InitializeResources would destroy the state the prior call to
858  // StageTransfer depends on.
859  //
860  struct {
861 
862  //
863  // Non-null when a staging operation is in progress on some CPU.
864  // When set any attempt to call the DMA completion routine or
865  // stage the transfer again (due to a call to TransferComplete)
866  // will be deferred to this thread.
867  //
869 
870  //
871  // Indicates that a nested or concurrent attempt to stage
872  // the transaction was deferred. The CurrentStagingThread
873  // will restage the transaction.
874  //
876 
877  //
878  // Indicates that a nested or concurrent attempt to call the
879  // DMA completion routine occurred. The CurrentStagingThread
880  // will call the DMA completion routine when it unwinds providing
881  // the saved CompletionStatus
882  //
885 
886  } m_TransferState;
887 
888  //
889  // Indicates that the DMA transfer has been cancelled.
890  // Set during StopTransfer and cleared during InitializeResources
891  // Checked during StageTransfer. Stop and Initialize should never
892  // race (it's not valid for the driver to stop an uninitialized
893  // transaction). Stop and Stage can race but in that case Stop
894  // will mark the transaction context such that MapTransfer fails
895  // (and that's protected by a HAL lock).
896  //
897  // So this field does not need to be volatile or interlocked, but
898  // it needs to be sized to allow atomic writes.
899  //
901 
902 
903  virtual
904  VOID
906  VOID
907  )
908  {
909  return;
910  }
911 
912 protected:
913 
914  inline
915  void
918  )
919  {
920  NT_ASSERTMSG("Map register base is already set",
922 
925  }
926 
927  inline
928  void
930  VOID
931  )
932  {
933  NT_ASSERTMSG("Map register base was not set",
936  }
937 
938  inline
939  BOOLEAN
941  VOID
942  )
943  {
944  return m_MapRegisterBaseSet;
945  }
946 
947  inline
948  PVOID
950  VOID
951  )
952  {
953  NT_ASSERTMSG("Map register base is not set",
955  return m_MapRegisterBase;
956  }
957 
958  virtual
961  VOID
962  )
963  {
965  }
966 
967  virtual
968  BOOLEAN
970  VOID
971  )
972  {
973  return TRUE;
974  }
975 
977  VOID
979 #pragma prefast(suppress:__WARNING_FAILING_TO_ACQUIRE_MEDIUM_CONFIDENCE, "transferring lock name to 'this->TransferStateLock'")
980 #pragma prefast(suppress:__WARNING_FAILING_TO_RELEASE_MEDIUM_CONFIDENCE, "transferring lock name to 'this->TransferStateLock'")
981  LockTransferState(
983  )
984  {
985  Lock(OldIrql);
986  }
987 
989  _Releases_lock_(this)
990  VOID
991 #pragma prefast(suppress:__WARNING_FAILING_TO_RELEASE_MEDIUM_CONFIDENCE, "transferring lock name from 'this->TransferStateLock'")
992  UnlockTransferState(
994  )
995  {
996 #pragma prefast(suppress:__WARNING_CALLER_FAILING_TO_HOLD, "transferring lock name from 'this->TransferStateLock'")
997  Unlock(OldIrql);
998  }
999 
1000  virtual
1003  VOID
1004  )
1005  {
1006  return NULL;
1007  }
1008 
1009  static
1011  STDCALL
1014  __in PIRP Irp,
1017  );
1018 
1020  NTSTATUS
1022  VOID
1023  )
1024  {
1025  if (m_DmaEnabler->UsesDmaV3() == FALSE)
1026  {
1028  }
1029  else
1030  {
1031  return STATUS_SUCCESS;
1032  }
1033  }
1034 
1035  FORCEINLINE
1036  VOID
1038  VOID
1039  )
1040  {
1041  if (m_DmaEnabler->UsesDmaV3() == FALSE)
1042  {
1044  }
1045  }
1046 
1048  NTSTATUS
1050  __in BOOLEAN MapRegistersReserved
1051  )
1052  {
1053  NTSTATUS status;
1054  KIRQL irql;
1055 
1057 
1058  if (GetDriverGlobals()->FxVerifierOn) {
1059 
1060  if (MapRegistersReserved == FALSE) {
1063  "Allocating %d map registers for "
1064  "WDFDMATRANSACTION %p",
1066  GetHandle()
1067  );
1068  }
1069  else {
1072  "Using %d reserved map registers for "
1073  "WDFDMATRANSACTION %p",
1075  GetHandle()
1076  );
1077  }
1078  }
1079 
1080  if (m_DmaEnabler->UsesDmaV3()) {
1081  PDMA_OPERATIONS dmaOperations =
1083 
1084  if (MapRegistersReserved == FALSE)
1085  {
1086  status = dmaOperations->AllocateAdapterChannelEx(
1091  m_Flags,
1092 #pragma prefast(suppress: __WARNING_CLASS_MISMATCH_NONE, "This warning requires a wrapper class for the DRIVER_CONTROL type.")
1094  this,
1095  NULL
1096  );
1097  }
1098  else {
1099 #pragma prefast(suppress:__WARNING_PASSING_FUNCTION_UNEXPECTED_NULL, "_AdapterControl does not actually use the IRP parameter.");
1101  NULL,
1103  this);
1105  }
1106  }
1107  else {
1108 
1109  ASSERTMSG("Prereserved map registers are not compatible with DMA V2",
1110  MapRegistersReserved == FALSE);
1111 
1116 #pragma prefast(suppress: __WARNING_CLASS_MISMATCH_NONE, "This warning requires a wrapper class for the DRIVER_CONTROL type.")
1118  this);
1119  }
1120 
1121  KeLowerIrql(irql);
1122 
1123  if (!NT_SUCCESS(status))
1124  {
1127  "Allocating DMA resources (%d map registers) for WDFDMATRANSACTION %p "
1128  "returned %!STATUS!",
1130  GetHandle(),
1131  status
1132  );
1133  }
1134 
1135  return status;
1136  }
1137 
1138  FORCEINLINE
1139  NTSTATUS
1141  __out_bcount_opt(ScatterGatherListCb)
1142  PSCATTER_GATHER_LIST ScatterGatherList,
1143  __in ULONG ScatterGatherListCb,
1146  __out ULONG *TransferLength
1147  )
1148  {
1149  //
1150  // Cache globals & object handle since call to MapTransferEx could
1151  // result in a DmaComplete callback before returning.
1152  //
1154  WDFDMATRANSACTION handle = GetHandle();
1155 #if DBG
1156  ULONG_PTR mapRegistersRequired;
1157 
1158  mapRegistersRequired = ADDRESS_AND_SIZE_TO_SPAN_PAGES(
1162  );
1163  NT_ASSERTMSG("Mapping requires too many map registers",
1164  mapRegistersRequired <= m_MapRegistersNeeded);
1165 #endif
1166 
1167  NTSTATUS status;
1168 
1169  //
1170  // Assume we're going to transfer the entire current fragment.
1171  // MapTransfer may say otherwise.
1172  //
1173 
1174  *TransferLength = (ULONG) m_CurrentFragmentLength;
1175 
1176  //
1177  // Map the transfer.
1178  //
1179 
1182  "Mapping transfer for WDFDMATRANSACTION %p. "
1183  "MDL %p, Offset %I64x, Length %x, MapRegisterBase %p",
1184  handle,
1187  *TransferLength,
1188  GetMapRegisterBase());
1189  }
1190 
1191  if (m_DmaEnabler->UsesDmaV3()) {
1192 
1193  PDMA_OPERATIONS dmaOperations =
1195 
1196  status = dmaOperations->MapTransferEx(
1202  TransferLength,
1204  ScatterGatherList,
1205  ScatterGatherListCb,
1208  );
1209 
1210  NT_ASSERTMSG(
1211  "With these parameters, MapTransferEx should never fail",
1213  );
1214  }
1215  else {
1216  NT_ASSERTMSG("cannot use DMA completion routine with DMAv2",
1217  CompletionRoutine == NULL);
1218 
1219  NT_ASSERTMSG(
1220  "scatter gather list length must be large enough for at least one element",
1221  (ScatterGatherListCb >= (sizeof(SCATTER_GATHER_LIST) +
1222  sizeof(SCATTER_GATHER_ELEMENT)))
1223  );
1224 
1225  //
1226  // This matches the assertion above. There's no way to explain to
1227  // prefast that this code path requires the caller to provide a buffer
1228  // of sufficient size to store the SGL. The only case which doesn't
1229  // provide any buffer is system-mode DMA and that uses DMA v3 and so
1230  // won't go through this path.
1231  //
1232 
1233  __assume((ScatterGatherListCb >= (sizeof(SCATTER_GATHER_LIST) +
1234  sizeof(SCATTER_GATHER_ELEMENT))));
1235 
1236  ScatterGatherList->NumberOfElements = 1;
1237  ScatterGatherList->Reserved = 0;
1238  ScatterGatherList->Elements[0].Address =
1245  TransferLength,
1247  ScatterGatherList->Elements[0].Length = *TransferLength;
1248 
1250  }
1251 
1254  "MapTransfer mapped next %d bytes of "
1255  "WDFDMATRANSACTION %p - status %!STATUS!",
1256  *TransferLength,
1257  handle,
1258  status);
1259  }
1260 
1261  return status;
1262  }
1263 
1264  FORCEINLINE
1265  NTSTATUS
1267  VOID
1268  )
1269  {
1270  PDMA_OPERATIONS dmaOperations =
1272 
1273  NTSTATUS status;
1274 
1275 #if DBG
1276  ULONG_PTR mapRegistersRequired;
1277 
1278  mapRegistersRequired = ADDRESS_AND_SIZE_TO_SPAN_PAGES(
1282  );
1283  NT_ASSERTMSG("Mapping requires too many map registers",
1284  mapRegistersRequired <= m_MapRegistersNeeded);
1285 #endif
1286 
1287  if (GetDriverGlobals()->FxVerifierOn) {
1289  "Flushing DMA buffers for WDFDMATRANSACTION %p. "
1290  "MDL %p, Offset %I64x, Length %I64x",
1291  GetHandle(),
1295  }
1296 
1297  if (m_DmaEnabler->UsesDmaV3()) {
1298  status = dmaOperations->FlushAdapterBuffersEx(
1305  );
1306  }
1307  else if (dmaOperations->FlushAdapterBuffers(
1314  (BOOLEAN) m_DmaDirection) == FALSE) {
1316  }
1317  else {
1319  }
1320 
1321  if (!NT_SUCCESS(status)) {
1323  "Flushing DMA buffers for WDFDMATRANSACTION %p ("
1324  "MDL %p, Offset %I64x, Length %I64x)"
1325  "completed with %!STATUS!",
1326  GetHandle(),
1330  status);
1331  }
1332 
1333  return status;
1334  }
1335 
1336  virtual
1337  VOID
1339  VOID
1340  )
1341  {
1342  KIRQL irql;
1343 
1344  PVOID mapRegisterBase = GetMapRegisterBase();
1345 
1346  //
1347  // It's illegal to free a NULL map register base, even if the HAL gave it
1348  // to us.
1349  //
1350  if (mapRegisterBase == NULL) {
1351  if (GetDriverGlobals()->FxVerifierOn) {
1353  "Skipping free of %d map registers for WDFDMATRANSACTION %p "
1354  "because base was NULL",
1356  GetHandle());
1357  }
1358 
1359  return;
1360  }
1361 
1362  //
1363  // Free the map registers
1364  //
1366 
1367  if (GetDriverGlobals()->FxVerifierOn) {
1369  "Freeing %d map registers for WDFDMATRANSACTION %p "
1370  "(base %p)",
1372  GetHandle(),
1373  mapRegisterBase);
1374  }
1375 
1376  //
1377  // If we pre-reserved map registers then Reserved contains
1378  // the number to free. Otherwise Needed is the number allocated
1379  // for the last transaction, which is the number to free.
1380  //
1382  FreeMapRegisters(m_AdapterInfo->AdapterObject,
1383  mapRegisterBase,
1384  (m_MapRegistersReserved > 0 ?
1387  KeLowerIrql(irql);
1388 
1389  return;
1390  }
1391 
1392  virtual
1393  VOID
1395  __in DMA_COMPLETION_STATUS /* Status */
1396  )
1397  {
1398  //
1399  // Packet mode DMA doesn't support cancellation or
1400  // completion routines. So this should never run.
1401  //
1402  ASSERTMSG("EvtDmaCompleted is not a valid callback for "
1403  "a packet-mode transaction",
1404  FALSE);
1405  return;
1406  }
1407 
1408 };
1409 
1411 
1413 
1414 public:
1415 
1417  __in PFX_DRIVER_GLOBALS FxDriverGlobals,
1418  __in USHORT ExtraSize,
1420  );
1421 
1423  static
1424  NTSTATUS
1425  _Create(
1426  __in PFX_DRIVER_GLOBALS FxDriverGlobals,
1429  __out WDFDMATRANSACTION* Transaction
1430  );
1431 
1432  VOID
1436  )
1437  {
1440  }
1441 
1442  VOID
1446  )
1447  {
1450  }
1451 
1452  VOID
1453  StopTransfer(
1454  VOID
1455  );
1456 
1457 protected:
1458 
1459  //
1460  // Callback and context for configure channel callback
1461  //
1464 
1465  //
1466  // Callback and context for DMA completion callback
1467  //
1470 
1473  VOID
1474  )
1475  {
1476  return KeepObject;
1477  }
1478 
1479  VOID
1481  VOID
1482  )
1483  {
1485  KIRQL irql;
1486 
1488 
1491  "Freeing adapter channel for WDFDMATRANSACTION %p",
1492  GetHandle());
1493  }
1494 
1496  FreeAdapterChannel(m_AdapterInfo->AdapterObject);
1497  KeLowerIrql(irql);
1498 
1499  return;
1500  }
1501 
1502  BOOLEAN
1504  VOID
1505  )
1506  {
1507  NTSTATUS status;
1508 
1510 
1511  //
1512  // Cancel the transfer. if it's not yet mapped this will mark the
1513  // TC so that mapping will fail. If it's running this will invoke the
1514  // DMA completion routine.
1515  //
1516  status =
1517  m_AdapterInfo->AdapterObject->DmaOperations->CancelMappedTransfer(
1520  );
1521 
1523  "Stopping WDFDMATRANSACTION %p returned status %!STATUS!",
1524  GetHandle(),
1525  status);
1526 
1527  return NT_SUCCESS(status);
1528  }
1529 
1530  VOID
1532  VOID
1533  )
1534  {
1535  FxDmaPacketTransaction::Reuse(); // __super call
1538 
1541  }
1542 
1543  VOID
1546  );
1547 
1548  virtual
1549  BOOLEAN
1551  VOID
1552  );
1553 
1554  virtual
1557  VOID
1558  );
1559 
1560  static DMA_COMPLETION_ROUTINE _SystemDmaCompletion;
1561 };
1562 
1563 #endif // _FXDMATRANSACTION_HPP_
#define FX_IS_POINTER_ENCODED(p, tag)
BOOLEAN CancelMappedTransfer(VOID)
#define FX_STRONG_REF_TAG
VOID AddIrpReference(VOID)
Definition: fxrequest.cpp:2470
__drv_restoresIRQL KIRQL __in BOOLEAN Unlock
Definition: fxobject.hpp:1474
enum _IO_ALLOCATION_ACTION IO_ALLOCATION_ACTION
#define NT_ASSERTMSG
Definition: rtlfuncs.h:3313
FORCEINLINE VOID ReleaseDevice(VOID)
virtual _Must_inspect_result_ NTSTATUS StageTransfer(VOID)=0
#define _Must_inspect_result_
Definition: no_sal2.h:62
#define KeRaiseIrql(irql, oldIrql)
Definition: env_spec_w32.h:597
boolean suppress
Definition: jpeglib.h:1006
__forceinline VOID SetMaximumFragmentLength(size_t MaximumFragmentLength)
BOOLEAN FxVerifierOn
Definition: fxglobals.h:420
#define KeLowerIrql(oldIrql)
Definition: env_spec_w32.h:602
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
virtual _Must_inspect_result_ NTSTATUS StartTransfer(VOID)
EVT_WDF_DMA_TRANSACTION_DMA_TRANSFER_COMPLETE * PFN_WDF_DMA_TRANSACTION_DMA_TRANSFER_COMPLETE
static VOID _ComputeNextTransferAddress(__in PMDL CurrentMdl, __in size_t CurrentOffset, __in ULONG Transferred, __deref_out PMDL *NextMdl, __out size_t *NextOffset)
struct FxDmaPacketTransaction::@4125 m_TransferState
_Out_ PULONG NumberOfMapRegisters
Definition: halfuncs.h:209
FxDmaTransactionConfigureChannel m_ConfigureChannelFunction
DMA_COMPLETION_STATUS CompletionStatus
_In_ WDFREQUEST _In_opt_ PFN_WDF_REQUEST_COMPLETION_ROUTINE _In_opt_ __drv_aliasesMem WDFCONTEXT CompletionContext
Definition: wdfrequest.h:893
static VOID _AdapterListControl(__in DEVICE_OBJECT *DeviceObject, __in IRP *Irp, __in SCATTER_GATHER_LIST *SgList, __in VOID *Context)
WDF_EXTERN_C_START typedef _In_ WDFDEVICE _In_ WDFCONTEXT _In_ WDF_DMA_DIRECTION Direction
#define MmGetMdlVirtualAddress(_Mdl)
virtual VOID Reuse(VOID)
#define __in_opt
Definition: dbghelp.h:38
#define TRUE
Definition: types.h:120
__forceinline VOID ClearRequest(VOID)
#define __drv_restoresIRQL
Definition: driverspecs.h:304
BOOLEAN UsesDmaV3(VOID)
static PMDL CurrentMdl
unsigned char * PUCHAR
Definition: retypes.h:3
virtual _Must_inspect_result_ NTSTATUS StageTransfer(VOID)
LONG NTSTATUS
Definition: precomp.h:26
virtual PDMA_COMPLETION_ROUTINE GetTransferCompletionRoutine(VOID)
__forceinline size_t GetBytesTransferred(VOID)
VOID SetImmediateExecution(__in BOOLEAN Value)
__forceinline FxRequest * GetRequest(VOID)
_In_ WDFREQUEST Request
Definition: wdfdevice.h:547
virtual _Must_inspect_result_ NTSTATUS InitializeResources(VOID)=0
FORCEINLINE NTSTATUS FlushAdapterBuffers(VOID)
PGET_SCATTER_GATHER_LIST_EX GetScatterGatherListEx
Definition: iotypes.h:2654
KIRQL irql
Definition: wave.h:1
VOID SetDeviceAddressOffset(__in ULONG Offset)
FxDmaTransactionTransferComplete m_TransferCompleteFunction
_Requires_lock_held_(this) _Releases_lock_(this) VOID UnlockTransferState(__in __drv_restoresIRQL KIRQL OldIrql)
BOOLEAN IsMapRegisterBaseSet(VOID)
PMAP_TRANSFER_EX MapTransferEx
Definition: iotypes.h:2653
_In_ WDFDMATRANSACTION _Out_opt_ ULONG * MapRegisterCount
struct _DMA_OPERATIONS * DmaOperations
Definition: iotypes.h:2292
virtual BOOLEAN Dispose(VOID)
PFLUSH_ADAPTER_BUFFERS_EX FlushAdapterBuffersEx
Definition: iotypes.h:2656
uint32_t ULONG_PTR
Definition: typedefs.h:65
FxDmaDescription * m_AdapterInfo
UCHAR KIRQL
Definition: env_spec_w32.h:591
virtual _Must_inspect_result_ NTSTATUS TransferCompleted(VOID)
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
virtual _Must_inspect_result_ NTSTATUS TransferCompleted(VOID)
static IO_ALLOCATION_ACTION STDCALL _AdapterControl(__in PDEVICE_OBJECT DeviceObject, __in PIRP Irp, __in PVOID MapRegisterBase, __in PVOID Context)
#define __out_opt
Definition: dbghelp.h:65
_Must_inspect_result_ NTSTATUS ReserveAdapter(__in ULONG NumberOfMapRegisters, __in WDF_DMA_DIRECTION Direction, __in PFN_WDF_RESERVE_DMA Callback, __in_opt PVOID Context)
#define FALSE
Definition: types.h:117
#define __drv_raisesIRQL(irql)
Definition: driverspecs.h:294
_In_ PIRP Irp
Definition: csq.h:116
#define TRACE_LEVEL_VERBOSE
Definition: storswtr.h:30
#define TRACINGDMA
Definition: dbgtrace.h:71
FxDmaCompletionType
#define ASSERTMSG(msg, exp)
Definition: nt_native.h:431
_Must_inspect_result_ NTSTATUS GetScatterGatherList(__in PMDL Mdl, __in size_t CurrentOffset, __in ULONG Length, __in PDRIVER_LIST_CONTROL ExecutionRoutine, __in PVOID Context)
_Must_inspect_result_ NTSTATUS BuildScatterGatherList(__in PMDL Mdl, __in size_t CurrentOffset, __in ULONG Length, __in PDRIVER_LIST_CONTROL ExecutionRoutine, __in PVOID Context, __in PVOID ScatterGatherBuffer, __in ULONG ScatterGatherBufferLength)
PVOID __inline GetObjectHandle(VOID)
Definition: fxobject.hpp:603
#define __out
Definition: dbghelp.h:62
VOID SetTransferCompleteCallback(__in_opt PFN_WDF_DMA_TRANSACTION_DMA_TRANSFER_COMPLETE Callback, __in_opt PVOID Context)
__forceinline BOOLEAN IsRequestReferenced(VOID)
unsigned char BOOLEAN
_Must_inspect_result_ BOOLEAN IsVersionGreaterThanOrEqualTo(__in ULONG Major, __in ULONG Minor)
Definition: globalskm.cpp:92
EVT_WDF_RESERVE_DMA * PFN_WDF_RESERVE_DMA
BOOLEAN DmaCompleted(__in size_t TransferredLength, __out NTSTATUS *ReturnStatus, __in FxDmaCompletionType CompletionType)
EVT_WDF_DMA_TRANSACTION_CONFIGURE_DMA_CHANNEL * PFN_WDF_DMA_TRANSACTION_CONFIGURE_DMA_CHANNEL
PBUILD_SCATTER_GATHER_LIST_EX BuildScatterGatherListEx
Definition: iotypes.h:2655
struct _SCATTER_GATHER_LIST SCATTER_GATHER_LIST
Definition: iotypes.h:2201
virtual VOID Reuse(VOID)
__forceinline WDFDMATRANSACTION GetHandle(VOID)
virtual IO_ALLOCATION_ACTION GetAdapterControlReturnValue(VOID)
virtual _Must_inspect_result_ NTSTATUS TransferCompleted(VOID)=0
_In_ WDFDMAENABLER _In_ WDF_DMA_DIRECTION DmaDirection
PDEVICE_OBJECT m_FDO
#define ADDRESS_AND_SIZE_TO_SPAN_PAGES(_Va, _Size)
typedef DECLSPEC_ALIGN(MEMORY_ALLOCATION_ALIGNMENT) UCHAR UCHAR_MEMORY_ALIGNED
Definition: iotypes.h:2758
virtual _Must_inspect_result_ NTSTATUS StageTransfer(VOID)
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _Out_opt_ PUSHORT _Inout_opt_ PUNICODE_STRING Value
Definition: wdfregistry.h:406
PFLUSH_ADAPTER_BUFFERS FlushAdapterBuffers
Definition: iotypes.h:2635
#define FX_ENCODE_POINTER(T, p, tag)
DMA_COMPLETION_ROUTINE * PDMA_COMPLETION_ROUTINE
Definition: iotypes.h:2485
Status
Definition: gdiplustypes.h:24
PFN_WDF_DMA_TRANSACTION_CONFIGURE_DMA_CHANNEL Method
_Acquires_lock_(this) VOID __drv_raisesIRQL(DISPATCH_LEVEL) LockTransferState(__out __drv_deref(__drv_savesIRQL) KIRQL *OldIrql)
__in __drv_restoresIRQL KIRQL OldIrql
Definition: fxobject.hpp:1465
PFX_DRIVER_GLOBALS pFxDriverGlobals
BOOLEAN CancelResourceAllocation(VOID)
#define STDCALL
Definition: wdf.h:45
DMA_COMPLETION_STATUS
Definition: iotypes.h:2295
_In_ WDFDMATRANSACTION _In_ size_t TransferredLength
#define ASSERT(a)
Definition: mode.c:45
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
VOID ReleaseForReuse(__in BOOLEAN ForceRelease)
__forceinline FxDmaEnabler * GetDmaEnabler(VOID)
#define __WARNING_CLASS_MISMATCH_NONE
Definition: suppress.h:563
#define STATUS_CANCELLED
Definition: udferr_usr.h:170
__forceinline VOID ReleaseButRetainRequest(VOID)
__forceinline VOID SetRequest(__in FxRequest *Request)
static DMA_COMPLETION_ROUTINE _SystemDmaCompletion
virtual _Must_inspect_result_ NTSTATUS InitializeResources(VOID)
GLbitfield flags
Definition: glext.h:7161
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
static _Must_inspect_result_ NTSTATUS _Create(__in PFX_DRIVER_GLOBALS FxDriverGlobals, __in PWDF_OBJECT_ATTRIBUTES Attributes, __in FxDmaEnabler *DmaEnabler, __out WDFDMATRANSACTION *Transaction)
unsigned char UCHAR
Definition: xmlstorage.h:181
WDF_EXTERN_C_START typedef _In_ WDFDEVICE _In_ WDFCONTEXT _In_ WDF_DMA_DIRECTION _In_ PSCATTER_GATHER_LIST SgList
virtual VOID ReleaseResources(__in BOOLEAN ForceRelease)
#define __drv_deref(annotes)
Definition: driverspecs.h:247
static PVOID GetStartVaFromOffset(__in PMDL Mdl, __in size_t Offset)
_Must_inspect_result_ NTSTATUS Initialize(__in PFN_WDF_PROGRAM_DMA ProgramDmaFunction, __in WDF_DMA_DIRECTION DmaDirection, __in PMDL Mdl, __in size_t Offset, __in ULONG Length)
__forceinline size_t GetCurrentFragmentLength(VOID)
FORCEINLINE NTSTATUS MapTransfer(__out_bcount_opt(ScatterGatherListCb) PSCATTER_GATHER_LIST ScatterGatherList, __in ULONG ScatterGatherListCb, __in_opt PDMA_COMPLETION_ROUTINE CompletionRoutine, __in_opt PVOID CompletionContext, __out ULONG *TransferLength)
virtual VOID ReleaseResources(__in BOOLEAN ForceRelease)=0
virtual VOID CallEvtDmaCompleted(__in DMA_COMPLETION_STATUS)
CfxDevice * GetDevice(VOID)
Definition: fxobject.hpp:781
_Must_inspect_result_ __in WDFKEY __in PCUNICODE_STRING __in ULONG __out_bcount_opt(ValueLength) PVOID Value
__forceinline VOID ReferenceRequest(VOID)
#define TRACE_LEVEL_ERROR
Definition: storswtr.h:27
_In_ WDFINTERRUPT _In_ PFN_WDF_INTERRUPT_SYNCHRONIZE Callback
Definition: wdfinterrupt.h:456
#define DISPATCH_LEVEL
Definition: env_spec_w32.h:696
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
static _Must_inspect_result_ NTSTATUS _Create(__in PFX_DRIVER_GLOBALS FxDriverGlobals, __in PWDF_OBJECT_ATTRIBUTES Attributes, __in FxDmaEnabler *DmaEnabler, __out WDFDMATRANSACTION *Transaction)
WDF_DMA_DIRECTION m_DmaDirection
_Inout_ struct _IRP _In_ PVOID MapRegisterBase
Definition: iotypes.h:212
__inline PFX_DRIVER_GLOBALS GetDriverGlobals(VOID)
Definition: fxobject.hpp:734
PDMA_ADAPTER AdapterObject
_Must_inspect_result_ NTSTATUS Execute(__in PVOID Context)
virtual PDMA_COMPLETION_ROUTINE GetTransferCompletionRoutine(VOID)
VOID ReleaseIrpReference(VOID)
Definition: fxrequest.cpp:2512
unsigned short USHORT
Definition: pedump.c:61
EVT_WDF_PROGRAM_DMA * PFN_WDF_PROGRAM_DMA
IO_ALLOCATION_ACTION GetAdapterControlReturnValue(VOID)
DRIVER_LIST_CONTROL * PDRIVER_LIST_CONTROL
Definition: iotypes.h:2374
__inline _Must_inspect_result_ NTSTATUS AcquireDmaPacketTransaction(VOID)
Definition: fxdevice.hpp:354
#define FORCEINLINE
Definition: wdftypes.h:67
_In_ WDFREQUEST _In_opt_ PFN_WDF_REQUEST_COMPLETION_ROUTINE CompletionRoutine
Definition: wdfrequest.h:893
FxDmaTransactionState GetTransactionState(VOID)
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGPNP, "Enter, WDFDEVICE %p", Device)
virtual BOOLEAN PreMapTransfer(VOID)
virtual _Must_inspect_result_ NTSTATUS StartTransfer(VOID)
unsigned int * PULONG
Definition: retypes.h:1
#define __drv_savesIRQL
Definition: driverspecs.h:308
_In_ struct _IRP _In_ struct _SCATTER_GATHER_LIST * ScatterGather
Definition: iotypes.h:2372
#define NULL
Definition: types.h:112
FxDmaTransactionProgramOrReserveDma m_DmaAcquiredFunction
VOID GetTransferInfo(__out_opt ULONG *MapRegisterCount, __out_opt ULONG *ScatterGatherElementCount)
_In_ WDFDEVICE _In_ PVOID _In_opt_ PMDL Mdl
__forceinline size_t GetMaximumFragmentLength(VOID)
#define FX_DECODE_POINTER(T, p, tag)
PFN_WDF_DMA_TRANSACTION_DMA_TRANSFER_COMPLETE Method
virtual BOOLEAN PreMapTransfer(VOID)
_Must_inspect_result_ _In_ WDFDMAENABLER DmaEnabler
VOID CallEvtDmaCompleted(__in DMA_COMPLETION_STATUS Status)
_Releases_lock_(this->m_NPLock.m_Lock) __drv_requiresIRQL(DISPATCH_LEVEL) __inline VOID Unlock(__in __drv_restoresIRQL KIRQL PreviousIrql)
struct tagContext Context
Definition: acpixf.h:1034
virtual VOID ReleaseResources(__in BOOLEAN ForceRelease)
#define __deref_out
Definition: dbghelp.h:26
_Must_inspect_result_ _In_opt_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFWAITLOCK * Lock
Definition: wdfsync.h:124
_In_ PDEVICE_OBJECT _In_ ULONG _In_ PDRIVER_CONTROL ExecutionRoutine
Definition: iofuncs.h:1393
FxDmaTransactionState m_State
struct _SCATTER_GATHER_LIST * PSCATTER_GATHER_LIST
Definition: iotypes.h:2201
enum _WDF_DMA_DIRECTION WDF_DMA_DIRECTION
unsigned int ULONG
Definition: retypes.h:1
_Must_inspect_result_ NTSTATUS AllocateAdapterChannel(__in BOOLEAN MapRegistersReserved)
void SetMapRegisterBase(__in PVOID Value)
VOID SetConfigureChannelCallback(__in_opt PFN_WDF_DMA_TRANSACTION_CONFIGURE_DMA_CHANNEL Callback, __in_opt PVOID Context)
#define STATUS_SUCCESS
Definition: shellext.h:65
FxDmaTransactionBase(__in PFX_DRIVER_GLOBALS FxDriverGlobals, __in USHORT ObjectSize, __in USHORT ExtraSize, __in FxDmaEnabler *DmaEnabler)
static _Must_inspect_result_ NTSTATUS _Create(__in PFX_DRIVER_GLOBALS FxDriverGlobals, __in PWDF_OBJECT_ATTRIBUTES Attributes, __in FxDmaEnabler *DmaEnabler, __out WDFDMATRANSACTION *Transaction)
static _Must_inspect_result_ NTSTATUS _CalculateRequiredMapRegisters(__in PMDL Mdl, __in size_t CurrentOffset, __in ULONG Length, __in ULONG AvailableMapRegisters, __out_opt PULONG PossibleTransferLength, __out PULONG MapRegistersRequired)
VOID PutScatterGatherList(__in PSCATTER_GATHER_LIST ScatterGather)
virtual VOID FreeMapRegistersAndAdapter(VOID)
virtual _Must_inspect_result_ NTSTATUS StartTransfer(VOID)=0
__inline VOID ReleaseDmaPacketTransaction(VOID)
Definition: fxdevice.hpp:373
#define __in
Definition: dbghelp.h:35
FxDmaSystemTransaction(__in PFX_DRIVER_GLOBALS FxDriverGlobals, __in USHORT ExtraSize, __in FxDmaEnabler *DmaEnabler)
FxDmaPacketTransaction(__in PFX_DRIVER_GLOBALS FxDriverGlobals, __in USHORT ObjectSize, __in USHORT ExtraSize, __in FxDmaEnabler *DmaEnabler)
static SERVICE_STATUS status
Definition: service.c:31
_Must_inspect_result_ NTSTATUS AcquireDevice(VOID)
FxDmaScatterGatherTransaction(__in PFX_DRIVER_GLOBALS FxDriverGlobals, __in USHORT ExtraSize, __in FxDmaEnabler *DmaEnabler)
#define MEMORY_ALLOCATION_ALIGNMENT
Definition: ntbasedef.h:90
PALLOCATE_ADAPTER_CHANNEL_EX AllocateAdapterChannelEx
Definition: iotypes.h:2650
virtual _Must_inspect_result_ NTSTATUS InitializeResources(VOID)
FxDmaEnabler * m_DmaEnabler
FxDmaTransactionState
_Must_inspect_result_ _In_ WDFDMAENABLER _In_ _In_opt_ PWDF_OBJECT_ATTRIBUTES Attributes
_In_ WDFDMATRANSACTION _Out_opt_ ULONG _Out_opt_ ULONG * ScatterGatherElementCount
Definition: ps.c:97