ReactOS 0.4.16-dev-1946-g52006dd
fxdmaenabler.cpp
Go to the documentation of this file.
1/*++
2
3Copyright (c) Microsoft Corporation
4
5Module Name:
6
7 FxDmaEnabler.cpp
8
9Abstract:
10
11 Base for WDF DMA Enabler object
12
13Environment:
14
15 Kernel mode only.
16
17Notes:
18
19
20Revision History:
21
22--*/
23
24#include "fxdmapch.hpp"
25
26extern "C" {
27// #include "FxDmaEnabler.tmh"
28#ifdef __REACTOS__
29#define RtlSizeTToULong RtlULongPtrToULong
30#endif
31}
32
34 __in PFX_DRIVER_GLOBALS FxDriverGlobals
35 ) :
37{
40
41 //
42 // Transaction link into list of FxDmaEnabler pointers maintained by
43 // FxDevice's pnp package.
44 //
46
47 m_FDO = NULL;
48 m_PDO = NULL;
54 m_SGListSize = 0;
55
57
64
68
70
72}
73
75{
78 //
79 // Scatter Gather profile - cleanup the lookaside list
80 //
81 ExDeleteNPagedLookasideList(&m_SGList.ScatterGatherProfile.Lookaside);
82
83 } else if (!m_IsBusMaster) {
84 //
85 // System profile (not busmastering) - cleanup the preallocated
86 // SG list
87 //
88 ExFreePool(m_SGList.SystemProfile.List);
89
90 } else {
91 //
92 // Packet profile. No special cleanup to do.
93 //
94
95 }
96
97#if DBG
99#endif
101 }
102}
103
104
107{
109
110 if (m_IsAdded) {
113 }
114
115 return TRUE;
116}
117
123 )
124{
126 DEVICE_DESCRIPTION deviceDescription;
128
129#ifndef __REACTOS__
130 ULONG mapRegistersAllocated;
131#endif
132 RtlZeroMemory(&deviceDescription, sizeof(DEVICE_DESCRIPTION));
133
134 //
135 // Default to version 2 description (except on ARM platforms)
136 //
137
138#ifdef _ARM_
139 deviceDescription.Version = DEVICE_DESCRIPTION_VERSION3;
140#else
141 deviceDescription.Version = DEVICE_DESCRIPTION_VERSION2;
142#endif
143
144 //
145 // Make sure the device's list of enablers has been created.
146 //
147
148 status = Device->AllocateDmaEnablerList();
149 if (!NT_SUCCESS(status)) {
151 "Unable to allocate DmaEnablerList for "
152 "WDFDEVICE %p, %!STATUS!",
153 Device->GetHandle(), status);
154 return status;
155 }
156
157 //
158 // Retain parent FxDeviceBase object
159 //
161
162 //
163 // Save the profile.
164 //
165 m_Profile = Config->Profile;
166
167 //
168 // Invariant parameters vis-a-vis kernel-mode bus-mastering DMA APIs
169 // (overrided below if using system-DMA
170 //
171 deviceDescription.Master = TRUE;
172 deviceDescription.Dma32BitAddresses = TRUE;
173 deviceDescription.InterfaceType = PCIBus;
174
175 //
176 // Assume enabler is a bus-master
177 //
179
180 //
181 // Expand the profile into settings.
182 //
183 switch (m_Profile) {
184 //
185 // Packet based profiles.
186 //
187
189 deviceDescription.ScatterGather = FALSE;
190 deviceDescription.Dma64BitAddresses = FALSE;
191 break;
193 deviceDescription.ScatterGather = FALSE;
194 deviceDescription.Dma64BitAddresses = TRUE;
195 break;
196
197 //
198 // Scatter-gather profiles
199 //
200
202 deviceDescription.ScatterGather = TRUE;
203 deviceDescription.Dma64BitAddresses = FALSE;
205 break;
207 deviceDescription.ScatterGather = TRUE;
208 deviceDescription.Dma64BitAddresses = FALSE;
211 break;
213 deviceDescription.ScatterGather = TRUE;
214 deviceDescription.Dma64BitAddresses = TRUE;
216 break;
218 deviceDescription.ScatterGather = TRUE;
219 deviceDescription.Dma64BitAddresses = TRUE;
222 break;
223
224 //
225 // Non-PC System-mode (non-bus-mastering) profiles. These
226 // require DMA v3.
227 //
228
230 deviceDescription.ScatterGather = FALSE;
231 deviceDescription.Master = FALSE;
232 deviceDescription.Dma32BitAddresses = FALSE;
233 deviceDescription.Dma64BitAddresses = FALSE;
234 deviceDescription.Version = DEVICE_DESCRIPTION_VERSION3;
237 break;
239 deviceDescription.ScatterGather = FALSE;
240 deviceDescription.Master = FALSE;
241 deviceDescription.Dma32BitAddresses = FALSE;
242 deviceDescription.Dma64BitAddresses = FALSE;
243 deviceDescription.Version = DEVICE_DESCRIPTION_VERSION3;
247 break;
248
249 //
250 // Unknown profile.
251 //
252
253 default:
254 //
255 // Just do quick exit as no resource have been allocated.
256 //
258 }
259
260 //
261 // Save the maximum length.
262 //
263 m_MaximumLength = (ULONG) Config->MaximumLength;
264
265 //
266 // An override of address width requires the DMA v3 engine. it also requires
267 // that we explicitly specify the DMA width the controller can support, but
268 // we do that down below.
269 //
270 if (Config->AddressWidthOverride != 0) {
271
272 //
273 // Address width override is not supported for system mode DMA, since
274 // the HAL runs the DMA controller in that case and it knows the
275 // controller's address limitations better than the driver does.
276 //
277 if (m_IsBusMaster == FALSE) {
281 "AddressWidthOverride set to %d. AddressWidthOverride "
282 "must be zero when using a system DMA profile "
283 "(%!WDF_DMA_PROFILE!) - %!STATUS!",
284 Config->AddressWidthOverride,
285 Config->Profile,
286 status
287 );
289 return status;
290 }
291
292 if ((deviceDescription.Dma64BitAddresses == FALSE) &&
293 (Config->AddressWidthOverride > 32)) {
297 "AddressWidthOverride set to %d. AddressWidthOverride "
298 "must be <= 32 when using a 32-bit DMA profile "
299 "(%!WDF_DMA_PROFILE!) - %!STATUS!",
300 Config->AddressWidthOverride,
301 Config->Profile,
302 status
303 );
305 return status;
306 }
307
308 //
309 // Handle the AddressWidthOverride. For Win8 use DMA v3 and pass the
310 // value through to the HAL. For Win7 downgrade to the next lower
311 // address width.
312 //
314 deviceDescription.Version = DEVICE_DESCRIPTION_VERSION3;
315 deviceDescription.DmaAddressWidth = Config->AddressWidthOverride;
316 }
317 else {
318
319 NT_ASSERTMSGW(L"Ensure driver is not doing something earlier that "
320 L"would require DMA v3 before we downgrade them to "
321 L"DMA v2",
322 (deviceDescription.Version == DEVICE_DESCRIPTION_VERSION2));
323
324 if (Config->AddressWidthOverride < 64) {
325 deviceDescription.Dma64BitAddresses = FALSE;
326 }
327
328 if (Config->AddressWidthOverride < 32) {
329 deviceDescription.Dma32BitAddresses = FALSE;
330 }
331
332 //
333 // DMA V2 can't handle an address width restriction smaller than
334 // 24 bits (ISA DMA). DMA V3 will fail that also - return the same
335 // error here that DMA V3 would have.
336 //
337 if (Config->AddressWidthOverride < 24) {
340 "AddressWidthOverride of less than 24 bits is not supported"
341 );
342 return STATUS_UNSUCCESSFUL;
343 }
344 else if ((Config->AddressWidthOverride != 64) &&
345 (Config->AddressWidthOverride != 32)) {
346
347 //
348 // Log a warning about downgrading DMA if we are actually
349 // downgrading. if the caller uses a 64-bit DMA
350 // profile with an override of 64, or 32-bit with an override
351 // of 32 then silently let it go through.
352 //
353
356 "DMA AddressWidthOverride requires Windows version 6.2 or "
357 "higher. Windows cannot support %d bit DMA is falling back to "
358 "the next lower supported width (%d-bit)",
359 Config->AddressWidthOverride,
360 (deviceDescription.Dma32BitAddresses ? 32 : 24)
361 );
362 }
363 }
364 }
365
366 //
367 // Allow for a specific version override (and fail if
368 // that override is inconsistent with the settings). On Win7 this will
369 // fail when we get the DMA adapter.
370 //
371 if (Config->WdmDmaVersionOverride != 0) {
372
373 if (Config->WdmDmaVersionOverride < deviceDescription.Version) {
375
376 //
377 // Driver is asking for a lower version of the DMA engine than the
378 // config settings imply it needs. Fail with invalid parameter.
379 //
380
382 "WdmDmaVersionOverride set to %d, conflicts with required version of %d, "
383 "%!STATUS!",
384 Config->WdmDmaVersionOverride,
385 deviceDescription.Version,
386 status
387 );
388
390 return status;
391 }
392
393 deviceDescription.Version = Config->WdmDmaVersionOverride;
394 }
395
396 //
397 // Propagate some settings from the old engine's location to the new ones.
398 //
399 if (deviceDescription.Version >= DEVICE_DESCRIPTION_VERSION3) {
400
401 if (deviceDescription.DmaAddressWidth == 0) {
402
403 if (deviceDescription.Dma64BitAddresses) {
404 deviceDescription.DmaAddressWidth = 64;
405 } else if (deviceDescription.Dma32BitAddresses) {
406 deviceDescription.DmaAddressWidth = 32;
407 } else {
408 //
409 // Assume ISA access width.
410 //
411
412 deviceDescription.DmaAddressWidth = 24;
413 }
414 }
415 }
416
417 //
418 // Get the FDO
419 //
421 ASSERT(m_FDO != NULL);
422
423 //
424 // Get the PDO. PDO may be NULL in the miniport case, but on
425 // x86 that will still allow for DMA (IoGetDmaAdapter special
426 // cases that on x86). On amd64 the attempt to get the DMA
427 // adapter later will fail cleanly.
428 //
430#ifndef __REACTOS__
431 mapRegistersAllocated = 0;
432#endif
433 //
434 // If this device is a bus-master then configure the profile
435 // right now, since we don't need to wait for PrepareHardware
436 // to find out the DMA resource.
437 //
438 if (m_IsBusMaster) {
439 status = ConfigureBusMasterAdapters(&deviceDescription, Config);
440 if (!NT_SUCCESS(status)) {
441 goto End;
442 }
443 }
444
445 //
446 // Retain the Power event callbacks.
447 //
448 m_EvtDmaEnablerFill.m_Method = Config->EvtDmaEnablerFill;
449 m_EvtDmaEnablerFlush.m_Method = Config->EvtDmaEnablerFlush;
450 m_EvtDmaEnablerEnable.m_Method = Config->EvtDmaEnablerEnable;
451 m_EvtDmaEnablerDisable.m_Method = Config->EvtDmaEnablerDisable;
452 m_EvtDmaEnablerSelfManagedIoStart.m_Method = Config->EvtDmaEnablerSelfManagedIoStart;
453 m_EvtDmaEnablerSelfManagedIoStop.m_Method = Config->EvtDmaEnablerSelfManagedIoStop;
454
455 //
456 // Add this DmaEnabler to the parent device's list of dma enablers.
457 //
459 m_IsAdded = TRUE;
460
461 //
462 // update hardware info for Telemetry
463 //
464 if (m_IsBusMaster) {
466 }
467
468 //
469 // Success:
470 //
472
473End:
474 //
475 // If errors then clean-up resources accumulated.
476 //
477 if (!NT_SUCCESS(status)) {
479 }
480
481 return status;
482}
483
489 )
490{
491 DEVICE_DESCRIPTION deviceDescription;
492
494
495 //
496 // Check to make sure this direction isn't currently configured.
497 //
498 if (GetDmaDescription(ConfigDirection)->AdapterObject != NULL) {
500
502 "WDFDMAENABLER %p, profile %!WDF_DMA_PROFILE! "
503 "Enabler has already been configured for %!WDF_DMA_DIRECTION!, %!STATUS!",
506 status
507 );
508
510
511 return status;
512 }
513
514 //
515 // Initialize the adapter info from scratch given the Config structure
516 // then copy it to the appropriate channel and do the allocation.
517 //
518 RtlZeroMemory(&deviceDescription, sizeof(DEVICE_DESCRIPTION));
519
520 deviceDescription.Version = DEVICE_DESCRIPTION_VERSION3;
521 deviceDescription.MaximumLength = m_MaximumLength;
522
523 deviceDescription.DemandMode = Config->DemandMode;
524 deviceDescription.AutoInitialize = Config->LoopedTransfer;
525
526 deviceDescription.DmaWidth = Config->DmaWidth;
527
528 deviceDescription.DeviceAddress = Config->DeviceAddress;
529
530 //
531 // Pull the remainder of the description from the provided resource.
532 //
533 deviceDescription.InterfaceType = Internal;
534 deviceDescription.DmaChannel = Config->DmaDescriptor->u.Dma.Channel;
535 deviceDescription.DmaRequestLine = Config->DmaDescriptor->u.Dma.Port;
536
537
538 //
539 // Run the common adapter configuration.
540 //
542 &deviceDescription,
544 );
545
546 if (!NT_SUCCESS(status)) {
547 goto End;
548 }
549
550 //
551 // Allocate a single SGList to pass to MapTransferEx. Since we
552 // only run a single system transfer at a time we can use the same
553 // list for each transfer
554 //
555
556 {
557 size_t systemSGListSize = 0;
558
559 if (m_IsDuplexTransfer) {
560
561 systemSGListSize = max(GetReadDmaDescription()->PreallocatedSGListSize,
562 GetWriteDmaDescription()->PreallocatedSGListSize);
563 } else {
564
566 }
567
568 //
569 // Allocate the SG list.
570 //
571 m_SGList.SystemProfile.List =
573 systemSGListSize,
575
576 if (m_SGList.SystemProfile.List == NULL) {
580 "Unable to allocate scatter gather list for system DMA "
581 "enabler %p, %!STATUS!",
583 );
584 goto End;
585 }
586
588 m_SGListSize = systemSGListSize;
589 }
590
591 //
592 // For a simple enabler, both of these calls will return the same
593 // DMA description entry.
594 //
597 )->AdapterObject != NULL) &&
600 )->AdapterObject != NULL)) {
602 }
603
604End:
605
606 return status;
607}
608
614 )
615{
618
619 //
620 // Initialize map register management
621 //
622 DeviceDescription->MaximumLength = m_MaximumLength;
623
624 if (m_IsDuplexTransfer) {
627
628 if (!NT_SUCCESS(status)) {
629 goto End;
630 }
631
634 } else {
635 //
636 // Direction is ignored in this case.
637 //
638
641 }
642
643 if (!NT_SUCCESS(status)) {
644 goto End;
645 }
646
647 //
648 // Allocate a scatter gather lookaside list if we need one.
649 //
650
651 if (m_IsScatterGather) {
652 size_t sgLookasideListSize;
653
654 sgLookasideListSize = 0;
655
656 if (m_IsDuplexTransfer) {
659
660 alignment = readDmaDesc->AdapterObject->DmaOperations->
661 GetDmaAlignment(readDmaDesc->AdapterObject);
662
663 //
664 // GetDmaAlignment returns alignment in terms of bytes
665 // while we treat alignment as a mask (which is how it is set
666 // in _DEVICE_OBJECT as well.
667 // For example, for byte alignment GetDmaAlignment returns 1 while
668 // the alignment mask is 0x00000000
669 //
670 // For < 1.11 drivers we keep the same behaviour as before for
671 // compatibility.
672 //
673 if (GetDriverGlobals()->IsVersionGreaterThanOrEqualTo(1, 11) &&
674 alignment > 0) {
675 alignment -= 1;
676 }
677
679 alignment);
680
681 //
682 // We will create a lookaside list based on the larger of the read &
683 // write SGListSize. It's done this way so that we can allocate
684 // sglist buffer when the dma-transaction object is created, where
685 // we don't know the direction of DMA transfer, and make the
686 // transaction initialize call fail-proof.
687 //
688 sgLookasideListSize = FxSizeTMax(
689 readDmaDesc->PreallocatedSGListSize,
690 writeDmaDesc->PreallocatedSGListSize
691 );
692 } else {
693
694 FxDmaDescription *simplexDmaDesc = &m_SimplexAdapterInfo;
695
696 alignment = simplexDmaDesc->AdapterObject->DmaOperations->
697 GetDmaAlignment(simplexDmaDesc->AdapterObject);
698
699 //
700 // GetDmaAlignment returns alignment in terms of bytes
701 // while we treat alignment as a mask (which is how it is set
702 // in _DEVICE_OBJECT as well.
703 // For example, for byte alignment GetDmaAlignment returns 1 while
704 // the alignment mask is 0x00000000
705 //
706 // For < 1.11 drivers we keep the same behaviour as before for
707 // compatibility.
708 //
709 if (GetDriverGlobals()->IsVersionGreaterThanOrEqualTo(1, 11) &&
710 alignment > 0) {
711 alignment -= 1;
712 }
713
715 alignment);
716
717 sgLookasideListSize = simplexDmaDesc->PreallocatedSGListSize;
718 }
719
720 //
721 // Initialize a LookasideList for ScatterGather list
722 //
725
726 m_SGListSize = sgLookasideListSize;
727
728 ExInitializeNPagedLookasideList( &m_SGList.ScatterGatherProfile.Lookaside,
729 NULL, // Allocate OPTIONAL
730 NULL, // Free OPTIONAL
731 0, // Flag - Reserved. Must be zero.
734 0 ); // Depth - Reserved. Must be zero.
735
737 }
738 }
739
740 //
741 // The DMA enabler is configured now.
742 //
743
745
746End:
747
748 return status;
749}
750
756 )
757{
758 FxDmaDescription *dmaDesc;
760
761 //
762 // Select the adapter to configure.
763 //
764
766
767 //
768 // Copy the device-description we have built up so far
769 // into the read and write dma description field. These
770 // settings are common to both channels.
771 //
774 sizeof(DEVICE_DESCRIPTION));
775
776 //
777 // Then initialize resources that are private to read and write.
778 //
779
780 status = InitializeResources(dmaDesc);
781 return status;
782}
783
787 __inout FxDmaDescription *AdapterInfo
788 )
789{
792
793 NT_ASSERTMSG("expected caller to set DMA version",
794 AdapterInfo->DeviceDescription.Version != 0);
795
796 //
797 // Submit IoGetDmaAdapter and retain the DmaAdapter pointer.
798 //
799 AdapterInfo->AdapterObject =
801 &AdapterInfo->DeviceDescription,
802 (PULONG)&AdapterInfo->NumberOfMapRegisters);
803
804 if (AdapterInfo->AdapterObject == NULL) {
807 "Unable to allocate DmaAdapter object for "
808 "WDFDMAENABLER %p, %!STATUS!",
809 GetHandle(), status);
810 return status;
811 }
812
813 //
814 // Calculate the size of the SGList.
815 //
816 if (m_IsScatterGather) {
817
818 //
819 // For scatter gather DMA we ask the HAL how many bytes it needs for
820 // each SGList. The HAL allocates some scratch space of its own in
821 // each SGList, which BuildScatterGatherList depends on.
822 //
823 ULONG mapRegistersCount;
824
825 status = AdapterInfo->AdapterObject->DmaOperations->
826 CalculateScatterGatherList( AdapterInfo->AdapterObject,
827 NULL, // Optional MDL
828 NULL, // CurrentVa
829 AdapterInfo->NumberOfMapRegisters * PAGE_SIZE,
830 (PULONG) &AdapterInfo->PreallocatedSGListSize,
831 &mapRegistersCount);
832
833 if (!NT_SUCCESS(status)) {
836 "CalculateScatterGatherList failed for "
837 "WDFDMAENABLER %p, %!STATUS!", GetHandle(), status);
838 return status;
839 }
840
841 ASSERT(AdapterInfo->NumberOfMapRegisters == mapRegistersCount);
842
843 } else if (m_IsBusMaster) {
844
845 //
846 // For packet based DMA we only need a single SGList entry because
847 // the HAL moves all of the data into a single continguous buffer
848 //
849 AdapterInfo->PreallocatedSGListSize = sizeof(SCATTER_GATHER_LIST) +
851
852 } else {
853
854 //
855 // For system DMA we need a single SGList entry per map-register
856 //
857 AdapterInfo->PreallocatedSGListSize = sizeof(SCATTER_GATHER_LIST) +
858 (sizeof(SCATTER_GATHER_ELEMENT) *
859 AdapterInfo->NumberOfMapRegisters);
860 }
861
862 ASSERT(AdapterInfo->NumberOfMapRegisters > 1);
863
864 AdapterInfo->MaximumFragmentLength = FxSizeTMin(m_MaximumLength,
865 ((size_t) (AdapterInfo->NumberOfMapRegisters - 1)) << PAGE_SHIFT);
866
868 "WDFDMAENABLER %p, profile %!WDF_DMA_PROFILE! "
869 "DmaAdapterObject %p, MapRegisters %d, "
870 "MaximumFragmentLength %I64d ", GetHandle(), m_Profile,
871 AdapterInfo->AdapterObject,
872 AdapterInfo->NumberOfMapRegisters,
873 AdapterInfo->MaximumFragmentLength);
874
875 if (AdapterInfo->MaximumFragmentLength < m_MaximumLength) {
877 "The maximum transfer length for WDFDMAENABLER %p "
878 "is reduced to %I64d from %I64d due to mapregisters limit",
880 AdapterInfo->MaximumFragmentLength);
881 }
882
883 return STATUS_SUCCESS;
884}
885
886VOID
888 __inout FxDmaDescription *AdapterInfo
889 )
890{
891 if (AdapterInfo->AdapterObject != NULL) {
892 AdapterInfo->AdapterObject->DmaOperations->PutDmaAdapter(AdapterInfo->AdapterObject);
893 AdapterInfo->AdapterObject = NULL;
894 }
895}
896
897VOID
899 VOID
900 )
901{
904
906
907}
908
909VOID
911 VOID
912 )
913{
914 //
915 // Give back any system DMA resources allocated for this device
916 //
917
918 if (m_IsBusMaster == FALSE)
919 {
920
921
922
923
924
925 }
926}
927
928// ----------------------------------------------------------------------------
929// ------------------------ Pnp/Power notification -----------------------------
930// ----------------------------------------------------------------------------
931
935 VOID
936 )
937{
940 WDFDMAENABLER handle = GetHandle();
942
944 "WDFDMAENABLER %p: PowerUp notification", GetHandle());
945
946 do {
948
950
951 if (!NT_SUCCESS(status)) {
954 break;
955 }
956 }
957
959
961
962 if (!NT_SUCCESS(status)) {
965 break;
966 }
967 }
968
970
972
973 if (!NT_SUCCESS(status)) {
976 break;
977 }
978 }
979
980 } WHILE (0);
981
982 if (!NT_SUCCESS(status)) {
984 "WDFDMAENABLER %p: PowerUp: "
985 "%!WdfDmaEnablerCallback! failed %!STATUS!",
986 GetHandle(), tag, status);
987 }
988 return status;
989}
990
994 VOID
995 )
996{
998 NTSTATUS localStatus;
1000 WDFDMAENABLER handle = GetHandle();
1002
1004 "WDFDMAENABLER %p: PowerDown notification", GetHandle());
1005
1006 do {
1007
1009
1011
1012 if (!NT_SUCCESS(localStatus)) {
1014 status = (NT_SUCCESS(status)) ? localStatus : status;
1015 }
1016 }
1017
1020 {
1021 localStatus = m_EvtDmaEnablerDisable.Invoke( handle );
1022
1023 if (!NT_SUCCESS(localStatus)) {
1025 status = (NT_SUCCESS(status)) ? localStatus : status;
1026 }
1027 }
1028
1032 {
1033 localStatus = m_EvtDmaEnablerFlush.Invoke( handle );
1034
1035 if (!NT_SUCCESS(localStatus)) {
1037 status = (NT_SUCCESS(status)) ? localStatus : status;
1038 }
1039 }
1040
1041 } WHILE (0);
1042
1043 if (!NT_SUCCESS(status)) {
1045 "WDFDMAENABLER %p: PowerDown: "
1046 "%!WdfDmaEnablerCallback! failed %!STATUS!",
1047 GetHandle(), tag, status);
1048 }
1049
1050 return status;
1051}
1052
1053// ----------------------------------------------------------------------------
1054// ------------------------ COMMON BUFFER SECTION -----------------------------
1055// ----------------------------------------------------------------------------
1056
1057VOID
1059 __in size_t Length,
1060 __deref_out_opt PVOID * BufferVA,
1061 __out PHYSICAL_ADDRESS * BufferPA
1062 )
1063{
1064 ULONG result;
1065 PDMA_ADAPTER adapterObject;
1067
1068 *BufferVA = NULL;
1069 BufferPA->QuadPart = 0;
1070
1073 "WDFDMAENABLER %p AllocateCommonBuffer: could cast value %I64d to a "
1074 "ULONG", GetHandle(), Length);
1076 return;
1077 }
1078
1079 //
1080 // It doesn't matter which channel we use for allocating common buffers
1081 // because the addressing capability of all the channels of this DMA enablers
1082 // are same.
1083 //
1084 adapterObject = GetReadDmaDescription()->AdapterObject;
1085
1086 *BufferVA = adapterObject->DmaOperations->
1087 AllocateCommonBuffer( adapterObject,
1088 result,
1089 BufferPA,
1090 TRUE /* CacheEnabled */ );
1091}
1092
1093
1094VOID
1096 __in size_t Length,
1097 __in PVOID BufferVA,
1098 __in PHYSICAL_ADDRESS BufferPA
1099 )
1100{
1101 PDMA_ADAPTER adapterObject;
1102
1103 adapterObject = GetReadDmaDescription()->AdapterObject;
1104
1105 adapterObject->DmaOperations->
1106 FreeCommonBuffer( adapterObject,
1107 (ULONG) Length,
1108 BufferPA,
1109 BufferVA,
1110 TRUE /* CacheEnabled */ );
1111}
1112
1113VOID
1117 )
1118{
1120
1122 "should not call this routine if enabler is not using DMAv3",
1123 UsesDmaV3()
1124 );
1125
1126 PDMA_OPERATIONS dmaOperations =
1127 adapter->DmaOperations;
1128
1130}
unsigned char BOOLEAN
_Check_return_ _Ret_maybenull_ _In_ size_t alignment
Definition: align.cpp:48
LONG NTSTATUS
Definition: precomp.h:26
virtual VOID RemoveDmaEnabler(__inout FxDmaEnabler *Enabler)
Definition: fxdevice.hpp:329
virtual VOID SetDeviceTelemetryInfoFlags(_In_ FxDeviceInfoFlags Flag)
Definition: fxdevice.hpp:341
MdDeviceObject __inline GetPhysicalDevice(VOID)
Definition: fxdevice.hpp:228
MdDeviceObject __inline GetDeviceObject(VOID)
Definition: fxdevice.hpp:174
virtual VOID AddDmaEnabler(__inout FxDmaEnabler *Enabler)
Definition: fxdevice.hpp:317
BOOLEAN m_IsSGListAllocated
FxDmaDescription m_SimplexAdapterInfo
BOOLEAN m_DmaEnablerFillFailed
VOID InitializeTransferContext(__out PVOID Context, __in WDF_DMA_DIRECTION Direction)
BOOLEAN m_IsBusMaster
ULONG m_MaximumLength
BOOLEAN UsesDmaV3(VOID)
WDF_DMA_PROFILE m_Profile
_Must_inspect_result_ NTSTATUS ConfigureSystemAdapter(__in PWDF_DMA_SYSTEM_PROFILE_CONFIG Config, __in WDF_DMA_DIRECTION ConfigDirection)
BOOLEAN m_IsDuplexTransfer
BOOLEAN m_IsAdded
_Must_inspect_result_ NTSTATUS PowerDown(VOID)
__inline FxDmaDescription * GetWriteDmaDescription(VOID)
size_t m_SGListSize
FxDmaDescription m_DuplexAdapterInfo[FxDuplexDmaDescriptionTypeMax]
FxTransactionedEntry m_TransactionLink
_Must_inspect_result_ NTSTATUS ConfigureDmaAdapter(__in PDEVICE_DESCRIPTION DeviceDescription, __in WDF_DMA_DIRECTION ConfigDirection)
__inline FxDmaDescription * GetReadDmaDescription(VOID)
PDEVICE_OBJECT m_PDO
VOID AllocateCommonBuffer(__in size_t Length, __deref_out_opt PVOID *BufferVA, __out PHYSICAL_ADDRESS *BufferPA)
FxEvtDmaEnablerSelfManagedIoStopCallback m_EvtDmaEnablerSelfManagedIoStop
FxEvtDmaEnablerEnableCallback m_EvtDmaEnablerEnable
_Must_inspect_result_ NTSTATUS Initialize(__in PWDF_DMA_ENABLER_CONFIG Config, __inout FxDeviceBase *Device)
VOID RevokeResources(VOID)
_Must_inspect_result_ NTSTATUS InitializeResources(__inout FxDmaDescription *AdapterInfo)
FxEvtDmaEnablerDisableCallback m_EvtDmaEnablerDisable
FxEvtDmaEnablerSelfManagedIoStartCallback m_EvtDmaEnablerSelfManagedIoStart
FxEvtDmaEnablerFillCallback m_EvtDmaEnablerFill
BOOLEAN m_IsConfigured
virtual BOOLEAN Dispose(VOID)
BOOLEAN m_IsScatterGather
__inline FxDmaDescription * GetDmaDescription(__in WDF_DMA_DIRECTION Direction)
_Must_inspect_result_ NTSTATUS ConfigureBusMasterAdapters(__in PDEVICE_DESCRIPTION DeviceDescription, __in PWDF_DMA_ENABLER_CONFIG Config)
FxEvtDmaEnablerFlushCallback m_EvtDmaEnablerFlush
VOID FreeCommonBuffer(__in size_t Length, __in PVOID BufferVA, __in PHYSICAL_ADDRESS BufferPA)
_Must_inspect_result_ NTSTATUS PowerUp(VOID)
BOOLEAN m_DmaEnablerEnableFailed
BOOLEAN m_DmaEnablerSelfManagedIoStartFailed
PDEVICE_OBJECT m_FDO
ULONG m_MaxSGElements
ULONG m_CommonBufferAlignment
union FxDmaEnabler::@5118 m_SGList
VOID FreeResources(__inout FxDmaDescription *AdapterInfo)
FxDmaEnabler(__in PFX_DRIVER_GLOBALS FxDriverGlobals)
VOID ReleaseResources(VOID)
PFN_WDF_DMA_ENABLER_DISABLE m_Method
NTSTATUS Invoke(__in WDFDMAENABLER Handle)
PFN_WDF_DMA_ENABLER_ENABLE m_Method
NTSTATUS Invoke(__in WDFDMAENABLER Handle)
PFN_WDF_DMA_ENABLER_FILL m_Method
NTSTATUS Invoke(__in WDFDMAENABLER Handle)
PFN_WDF_DMA_ENABLER_FLUSH m_Method
NTSTATUS Invoke(__in WDFDMAENABLER Handle)
NTSTATUS Invoke(__in WDFDMAENABLER Handle)
PFN_WDF_DMA_ENABLER_SELFMANAGED_IO_START m_Method
PFN_WDF_DMA_ENABLER_SELFMANAGED_IO_STOP m_Method
NTSTATUS Invoke(__in WDFDMAENABLER Handle)
__inline PFX_DRIVER_GLOBALS GetDriverGlobals(VOID)
Definition: fxobject.hpp:734
CfxDeviceBase * m_DeviceBase
Definition: fxobject.hpp:328
VOID MarkDisposeOverride(__in FxObjectLockState State=ObjectLock)
Definition: fxobject.hpp:1101
#define __in
Definition: dbghelp.h:35
#define __inout
Definition: dbghelp.h:50
#define __out
Definition: dbghelp.h:62
#define __deref_out_opt
Definition: dbghelp.h:29
#define TRACINGDMA
Definition: dbgtrace.h:71
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
#define L(x)
Definition: resources.c:13
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define PAGE_SIZE
Definition: env_spec_w32.h:49
#define PAGE_SHIFT
Definition: env_spec_w32.h:45
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
#define NonPagedPool
Definition: env_spec_w32.h:307
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGPNP, "Enter, WDFDEVICE %p", Device)
PFX_DRIVER_GLOBALS pFxDriverGlobals
FxVerifierDbgBreakPoint(pFxDriverGlobals)
return adapter
FxDmaEnablerCallbacks
@ FxEvtDmaEnablerDisable
@ FxEvtDmaEnablerSelfManagedIoStart
@ FxEvtDmaEnablerFlush
@ FxEvtDmaEnablerEnable
@ FxEvtDmaEnablerSelfManagedIoStop
@ FxEvtDmaEnablerInvalid
@ FxEvtDmaEnablerFill
__inline _Must_inspect_result_ BOOLEAN IsOsVersionGreaterThanOrEqualTo(__in ULONG Major, __in ULONG Minor)
Definition: fxglobals.h:1094
__inline size_t FxSizeTMax(__in size_t A, __in size_t B)
Definition: fxglobals.h:987
__inline size_t FxSizeTMin(__in size_t A, __in size_t B)
Definition: fxglobals.h:997
#define WHILE(constant)
Definition: fxmacros.hpp:226
@ ObjectDoNotLock
Definition: fxobject.hpp:128
#define RtlSizeTToULong
@ DeviceInfoDmaBusMaster
@ DeviceInfoDmaSystem
@ DeviceInfoDmaSystemDuplex
@ FX_TYPE_DMA_ENABLER
Definition: fxtypes.h:107
GLuint64EXT * result
Definition: glext.h:11304
if(dx< 0)
Definition: linetemp.h:194
VOID NTAPI ExDeleteNPagedLookasideList(IN PNPAGED_LOOKASIDE_LIST Lookaside)
Definition: lookas.c:170
VOID NTAPI ExInitializeNPagedLookasideList(IN PNPAGED_LOOKASIDE_LIST Lookaside, IN PALLOCATE_FUNCTION Allocate OPTIONAL, IN PFREE_FUNCTION Free OPTIONAL, IN ULONG Flags, IN SIZE_T Size, IN ULONG Tag, IN USHORT Depth)
Definition: lookas.c:218
#define ASSERT(a)
Definition: mode.c:44
#define _Must_inspect_result_
Definition: no_sal2.h:62
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
PDMA_ADAPTER NTAPI IoGetDmaAdapter(IN PDEVICE_OBJECT PhysicalDeviceObject, IN PDEVICE_DESCRIPTION DeviceDescription, IN OUT PULONG NumberOfMapRegisters)
Definition: pnpdma.c:23
@ PCIBus
Definition: restypes.h:126
@ Internal
Definition: restypes.h:121
#define STATUS_SUCCESS
Definition: shellext.h:65
#define TRACE_LEVEL_WARNING
Definition: storswtr.h:28
#define TRACE_LEVEL_VERBOSE
Definition: storswtr.h:30
#define TRACE_LEVEL_ERROR
Definition: storswtr.h:27
VOID SetTransactionedObject(__in FxObject *Object)
BOOLEAN Dma64BitAddresses
Definition: iotypes.h:2077
PHYSICAL_ADDRESS DeviceAddress
Definition: iotypes.h:2089
BOOLEAN ScatterGather
Definition: iotypes.h:2071
BOOLEAN AutoInitialize
Definition: iotypes.h:2073
DMA_WIDTH DmaWidth
Definition: iotypes.h:2081
INTERFACE_TYPE InterfaceType
Definition: iotypes.h:2080
BOOLEAN Dma32BitAddresses
Definition: iotypes.h:2074
BOOLEAN DemandMode
Definition: iotypes.h:2072
ULONG AlignmentRequirement
Definition: env_spec_w32.h:420
struct _DMA_OPERATIONS * DmaOperations
Definition: iotypes.h:2297
PINITIALIZE_DMA_TRANSFER_CONTEXT InitializeDmaTransferContext
Definition: iotypes.h:2653
PDMA_ADAPTER AdapterObject
DEVICE_DESCRIPTION DeviceDescription
size_t PreallocatedSGListSize
Definition: ps.c:97
Definition: ecma_167.h:138
#define max(a, b)
Definition: svc.c:63
#define GetHandle(h)
Definition: treelist.c:116
uint32_t * PULONG
Definition: typedefs.h:59
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
uint32_t ULONG
Definition: typedefs.h:59
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
_Must_inspect_result_ _In_ WDFDEVICE Device
Definition: wdfchildlist.h:474
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_CHILD_LIST_CONFIG Config
Definition: wdfchildlist.h:476
_Must_inspect_result_ _In_ WDFDEVICE _In_ BOOLEAN _In_opt_ PVOID Tag
Definition: wdfdevice.h:4071
@ WDF_DMA_ENABLER_CONFIG_NO_SGLIST_PREALLOCATION
@ WdfDmaProfileScatterGather
Definition: wdfdmaenabler.h:55
@ WdfDmaProfilePacket
Definition: wdfdmaenabler.h:54
@ WdfDmaProfileScatterGatherDuplex
Definition: wdfdmaenabler.h:58
@ WdfDmaProfileSystem
Definition: wdfdmaenabler.h:60
@ WdfDmaProfileSystemDuplex
Definition: wdfdmaenabler.h:61
@ WdfDmaProfilePacket64
Definition: wdfdmaenabler.h:56
@ WdfDmaProfileScatterGather64Duplex
Definition: wdfdmaenabler.h:59
@ WdfDmaProfileScatterGather64
Definition: wdfdmaenabler.h:57
#define WDF_DMA_ENABLER_UNLIMITED_FRAGMENTS
enum _WDF_DMA_DIRECTION WDF_DMA_DIRECTION
_Must_inspect_result_ _In_ WDFDMAENABLER _In_ PWDF_DMA_SYSTEM_PROFILE_CONFIG _In_ WDF_DMA_DIRECTION ConfigDirection
@ WdfDmaDirectionReadFromDevice
Definition: wdfdmaenabler.h:65
@ WdfDmaDirectionWriteToDevice
Definition: wdfdmaenabler.h:66
WDF_EXTERN_C_START typedef _In_ WDFDEVICE _In_ WDFCONTEXT _In_ WDF_DMA_DIRECTION Direction
_Must_inspect_result_ _In_ PWDFDEVICE_INIT _In_ PCUNICODE_STRING DeviceDescription
Definition: wdfpdo.h:432
ActualNumberDriverObjects * sizeof(PDRIVER_OBJECT)) PDRIVER_OBJECT *DriverObjectList
struct _SCATTER_GATHER_LIST SCATTER_GATHER_LIST
Definition: iotypes.h:2206
struct _SCATTER_GATHER_LIST * PSCATTER_GATHER_LIST
Definition: iotypes.h:2206
#define DEVICE_DESCRIPTION_VERSION2
Definition: iotypes.h:2065
#define DEVICE_DESCRIPTION_VERSION3
Definition: iotypes.h:2066
#define NT_ASSERTMSG
Definition: rtlfuncs.h:3328
#define NT_ASSERTMSGW
Definition: rtlfuncs.h:3329