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