ReactOS  0.4.15-dev-3739-gff9301e
dma.c
Go to the documentation of this file.
1 /*
2  *
3  * COPYRIGHT: See COPYING in the top level directory
4  * PROJECT: ReactOS kernel
5  * FILE: hal/halx86/generic/dma.c
6  * PURPOSE: DMA functions
7  * PROGRAMMERS: David Welch (welch@mcmail.com)
8  * Filip Navara (navaraf@reactos.com)
9  * UPDATE HISTORY:
10  * Created 22/05/98
11  */
12 
72 /* INCLUDES *****************************************************************/
73 
74 #include <hal.h>
75 #include <suppress.h>
76 
77 #define NDEBUG
78 #include <debug.h>
79 
80 #define MAX_SG_ELEMENTS 0x10
81 
82 #ifndef _MINIHAL_
87 #endif
89 #ifndef _MINIHAL_
91 #endif
92 
93 static const ULONG_PTR HalpEisaPortPage[8] = {
94  FIELD_OFFSET(DMA_PAGE, Channel0),
95  FIELD_OFFSET(DMA_PAGE, Channel1),
96  FIELD_OFFSET(DMA_PAGE, Channel2),
97  FIELD_OFFSET(DMA_PAGE, Channel3),
98  0,
99  FIELD_OFFSET(DMA_PAGE, Channel5),
100  FIELD_OFFSET(DMA_PAGE, Channel6),
101  FIELD_OFFSET(DMA_PAGE, Channel7)
102 };
103 
104 #ifndef _MINIHAL_
105 NTSTATUS
106 NTAPI
108  IN PADAPTER_OBJECT AdapterObject,
110  IN PVOID CurrentVa,
111  IN ULONG Length,
112  OUT PULONG ScatterGatherListSize,
113  OUT PULONG pNumberOfMapRegisters);
114 
115 NTSTATUS
116 NTAPI
118  IN PADAPTER_OBJECT AdapterObject,
120  IN PMDL Mdl,
121  IN PVOID CurrentVa,
122  IN ULONG Length,
124  IN PVOID Context,
126  IN PVOID ScatterGatherBuffer,
127  IN ULONG ScatterGatherLength);
128 
129 NTSTATUS
130 NTAPI
132  IN PDMA_ADAPTER DmaAdapter,
134  IN PMDL OriginalMdl,
135  OUT PMDL *TargetMdl);
136 
137 
139  sizeof(DMA_OPERATIONS),
143  NULL, /* Initialized in HalpInitDma() */
144  NULL, /* Initialized in HalpInitDma() */
145  NULL, /* Initialized in HalpInitDma() */
146  NULL, /* Initialized in HalpInitDma() */
147  NULL, /* Initialized in HalpInitDma() */
155 };
156 #endif
157 
158 #define MAX_MAP_REGISTERS 64
159 
160 #define TAG_DMA ' AMD'
161 
162 /* FUNCTIONS *****************************************************************/
163 
164 #if defined(SARCH_PC98)
165 /*
166  * Disable I/O for safety.
167  * FIXME: Add support for PC-98 DMA controllers.
168  */
169 #undef WRITE_PORT_UCHAR
170 #undef READ_PORT_UCHAR
171 
172 #define WRITE_PORT_UCHAR(Port, Data) \
173  do { \
174  UNIMPLEMENTED; \
175  (Port); \
176  (Data); \
177  } while (0)
178 
179 #define READ_PORT_UCHAR(Port) 0x00
180 #endif
181 
182 #ifndef _MINIHAL_
183 CODE_SEG("INIT")
184 VOID
186 {
187  /*
188  * Initialize the DMA Operation table
189  */
195 
197  {
198  /*
199  * Check if Extended DMA is available. We're just going to do a random
200  * read and write.
201  */
202  WRITE_PORT_UCHAR(UlongToPtr(FIELD_OFFSET(EISA_CONTROL, DmaController2Pages.Channel2)), 0x2A);
203  if (READ_PORT_UCHAR(UlongToPtr(FIELD_OFFSET(EISA_CONTROL, DmaController2Pages.Channel2))) == 0x2A)
204  {
205  DPRINT1("Machine supports EISA DMA. Bus type: %lu\n", HalpBusType);
206  HalpEisaDma = TRUE;
207  }
208  }
209 
210  /*
211  * Intialize all the global variables and allocate master adapter with
212  * first map buffers.
213  */
218 
219  /*
220  * Setup the HalDispatchTable callback for creating PnP DMA adapters. It's
221  * used by IoGetDmaAdapter in the kernel.
222  */
224 }
225 #endif
226 
234 NTAPI
236 {
237  PHYSICAL_ADDRESS HighestAddress;
238 
239  if (AdapterObject->MasterDevice)
240  {
241  if (AdapterObject->Dma64BitAddresses)
242  {
243  HighestAddress.QuadPart = 0xFFFFFFFFFFFFFFFFULL;
244  return HighestAddress;
245  }
246  else if (AdapterObject->Dma32BitAddresses)
247  {
248  HighestAddress.QuadPart = 0xFFFFFFFF;
249  return HighestAddress;
250  }
251  }
252 
253  HighestAddress.QuadPart = 0xFFFFFF;
254  return HighestAddress;
255 }
256 
257 #ifndef _MINIHAL_
258 
269 BOOLEAN
270 NTAPI
272  IN ULONG SizeOfMapBuffers)
273 {
278  PHYSICAL_ADDRESS BoundryAddressMultiple;
279  KIRQL OldIrql;
281 
282  /* Check if enough map register slots are available. */
283  MapRegisterCount = BYTES_TO_PAGES(SizeOfMapBuffers);
284  if (MapRegisterCount + AdapterObject->NumberOfMapRegisters > MAX_MAP_REGISTERS)
285  {
286  DPRINT("No more map register slots available! (Current: %d | Requested: %d | Limit: %d)\n",
287  AdapterObject->NumberOfMapRegisters,
290  return FALSE;
291  }
292 
293  /*
294  * Allocate memory for the new map registers. For 32-bit adapters we use
295  * two passes in order not to waste scare resource (low memory).
296  */
299  LowestAcceptableAddress.LowPart = HighestAcceptableAddress.LowPart == 0xFFFFFFFF ? 0x1000000 : 0;
300  BoundryAddressMultiple.QuadPart = 0;
301 
305  BoundryAddressMultiple,
306  MmNonCached);
308  {
313  BoundryAddressMultiple,
314  MmNonCached);
315  }
316 
317  if (!VirtualAddress) return FALSE;
318 
320 
321  /*
322  * All the following must be done with the master adapter lock held
323  * to prevent corruption.
324  */
325  KeAcquireSpinLock(&AdapterObject->SpinLock, &OldIrql);
326 
327  /*
328  * Setup map register entries for the buffer allocated. Each entry has
329  * a virtual and physical address and corresponds to PAGE_SIZE large
330  * buffer.
331  */
332  if (MapRegisterCount > 0)
333  {
334  PROS_MAP_REGISTER_ENTRY CurrentEntry, PreviousEntry;
335 
336  CurrentEntry = AdapterObject->MapRegisterBase + AdapterObject->NumberOfMapRegisters;
337  do
338  {
339  /*
340  * Leave one entry free for every non-contiguous memory region
341  * in the map register bitmap. This ensures that we can search
342  * using RtlFindClearBits for contiguous map register regions.
343  *
344  * Also for non-EISA DMA leave one free entry for every 64Kb
345  * break, because the DMA controller can handle only coniguous
346  * 64Kb regions.
347  */
348  if (CurrentEntry != AdapterObject->MapRegisterBase)
349  {
350  PreviousEntry = CurrentEntry - 1;
351  if ((PreviousEntry->PhysicalAddress.LowPart + PAGE_SIZE) == PhysicalAddress.LowPart)
352  {
353  if (!HalpEisaDma)
354  {
355  if ((PreviousEntry->PhysicalAddress.LowPart ^ PhysicalAddress.LowPart) & 0xFFFF0000)
356  {
357  CurrentEntry++;
358  AdapterObject->NumberOfMapRegisters++;
359  }
360  }
361  }
362  else
363  {
364  CurrentEntry++;
365  AdapterObject->NumberOfMapRegisters++;
366  }
367  }
368 
369  RtlClearBit(AdapterObject->MapRegisters,
370  (ULONG)(CurrentEntry - AdapterObject->MapRegisterBase));
371  CurrentEntry->VirtualAddress = VirtualAddress;
372  CurrentEntry->PhysicalAddress = PhysicalAddress;
373 
376 
377  CurrentEntry++;
378  AdapterObject->NumberOfMapRegisters++;
380  } while (MapRegisterCount);
381  }
382 
383  KeReleaseSpinLock(&AdapterObject->SpinLock, OldIrql);
384 
385  return TRUE;
386 }
387 
397 NTAPI
399 {
400  PADAPTER_OBJECT MasterAdapter;
401  ULONG Size, SizeOfBitmap;
402 
403  SizeOfBitmap = MAX_MAP_REGISTERS;
404  Size = sizeof(ADAPTER_OBJECT);
405  Size += sizeof(RTL_BITMAP);
406  Size += (SizeOfBitmap + 7) >> 3;
407 
408  MasterAdapter = ExAllocatePoolWithTag(NonPagedPool, Size, TAG_DMA);
409  if (!MasterAdapter) return NULL;
410 
411  RtlZeroMemory(MasterAdapter, Size);
412 
413  KeInitializeSpinLock(&MasterAdapter->SpinLock);
414  InitializeListHead(&MasterAdapter->AdapterQueue);
415 
416  MasterAdapter->MapRegisters = (PVOID)(MasterAdapter + 1);
417  RtlInitializeBitMap(MasterAdapter->MapRegisters,
418  (PULONG)(MasterAdapter->MapRegisters + 1),
419  SizeOfBitmap);
420  RtlSetAllBits(MasterAdapter->MapRegisters);
421  MasterAdapter->NumberOfMapRegisters = 0;
422  MasterAdapter->CommittedMapRegisters = 0;
423 
424  MasterAdapter->MapRegisterBase = ExAllocatePoolWithTag(NonPagedPool,
425  SizeOfBitmap *
426  sizeof(ROS_MAP_REGISTER_ENTRY),
427  TAG_DMA);
428  if (!MasterAdapter->MapRegisterBase)
429  {
430  ExFreePool(MasterAdapter);
431  return NULL;
432  }
433 
434  RtlZeroMemory(MasterAdapter->MapRegisterBase,
435  SizeOfBitmap * sizeof(ROS_MAP_REGISTER_ENTRY));
436  if (!HalpGrowMapBuffers(MasterAdapter, 0x10000))
437  {
438  ExFreePool(MasterAdapter);
439  return NULL;
440  }
441 
442  return MasterAdapter;
443 }
444 
454 NTAPI
457 {
458  PADAPTER_OBJECT AdapterObject;
461  HANDLE Handle;
462 
464  NULL,
466  NULL,
467  NULL);
468 
472  KernelMode,
473  NULL,
474  sizeof(ADAPTER_OBJECT),
475  0,
476  0,
477  (PVOID)&AdapterObject);
478  if (!NT_SUCCESS(Status)) return NULL;
479 
480  RtlZeroMemory(AdapterObject, sizeof(ADAPTER_OBJECT));
481 
482  Status = ObInsertObject(AdapterObject,
483  NULL,
485  0,
486  NULL,
487  &Handle);
488  if (!NT_SUCCESS(Status)) return NULL;
489 
490  ObReferenceObject(AdapterObject);
491 
492  ZwClose(Handle);
493 
494  AdapterObject->DmaHeader.Version = (USHORT)DeviceDescription->Version;
495  AdapterObject->DmaHeader.Size = sizeof(ADAPTER_OBJECT);
496  AdapterObject->DmaHeader.DmaOperations = &HalpDmaOperations;
497  AdapterObject->MapRegistersPerChannel = 1;
498  AdapterObject->Dma32BitAddresses = DeviceDescription->Dma32BitAddresses;
499  AdapterObject->ChannelNumber = 0xFF;
500  AdapterObject->MasterAdapter = HalpMasterAdapter;
501  KeInitializeDeviceQueue(&AdapterObject->ChannelWaitQueue);
502 
503  return AdapterObject;
504 }
505 #endif
506 
512 BOOLEAN
513 NTAPI
516 {
517  UCHAR Controller;
518  DMA_MODE DmaMode = {{0 }};
519  DMA_EXTENDED_MODE ExtendedMode = {{ 0 }};
520  PVOID AdapterBaseVa;
521 
522  Controller = (DeviceDescription->DmaChannel & 4) ? 2 : 1;
523 
524  if (Controller == 1)
525  {
526  AdapterBaseVa = UlongToPtr(FIELD_OFFSET(EISA_CONTROL, DmaController1));
527  }
528  else
529  {
530  AdapterBaseVa = UlongToPtr(FIELD_OFFSET(EISA_CONTROL, DmaController2));
531  }
532 
533  AdapterObject->AdapterNumber = Controller;
534  AdapterObject->ChannelNumber = (UCHAR)(DeviceDescription->DmaChannel & 3);
535  AdapterObject->PagePort = (PUCHAR)HalpEisaPortPage[DeviceDescription->DmaChannel];
536  AdapterObject->Width16Bits = FALSE;
537  AdapterObject->AdapterBaseVa = AdapterBaseVa;
538 
539  if (HalpEisaDma)
540  {
541  ExtendedMode.ChannelNumber = AdapterObject->ChannelNumber;
542 
543  switch (DeviceDescription->DmaSpeed)
544  {
545  case Compatible: ExtendedMode.TimingMode = COMPATIBLE_TIMING; break;
546  case TypeA: ExtendedMode.TimingMode = TYPE_A_TIMING; break;
547  case TypeB: ExtendedMode.TimingMode = TYPE_B_TIMING; break;
548  case TypeC: ExtendedMode.TimingMode = BURST_TIMING; break;
549  default:
550  return FALSE;
551  }
552 
553  switch (DeviceDescription->DmaWidth)
554  {
555  case Width8Bits: ExtendedMode.TransferSize = B_8BITS; break;
556  case Width16Bits: ExtendedMode.TransferSize = B_16BITS; break;
557  case Width32Bits: ExtendedMode.TransferSize = B_32BITS; break;
558  default:
559  return FALSE;
560  }
561 
562  if (Controller == 1)
563  {
565  ExtendedMode.Byte);
566  }
567  else
568  {
570  ExtendedMode.Byte);
571  }
572  }
573  else
574  {
575  /*
576  * Validate setup for non-busmaster DMA adapter. Secondary controller
577  * supports only 16-bit transfers and main controller supports only
578  * 8-bit transfers. Anything else is invalid.
579  */
580  if (!DeviceDescription->Master)
581  {
582  if ((Controller == 2) && (DeviceDescription->DmaWidth == Width16Bits))
583  {
584  AdapterObject->Width16Bits = TRUE;
585  }
586  else if ((Controller != 1) || (DeviceDescription->DmaWidth != Width8Bits))
587  {
588  return FALSE;
589  }
590  }
591  }
592 
593  DmaMode.Channel = AdapterObject->ChannelNumber;
594  DmaMode.AutoInitialize = DeviceDescription->AutoInitialize;
595 
596  /*
597  * Set the DMA request mode.
598  *
599  * For (E)ISA bus master devices just unmask (enable) the DMA channel
600  * and set it to cascade mode. Otherwise just select the right one
601  * bases on the passed device description.
602  */
603  if (DeviceDescription->Master)
604  {
606  if (Controller == 1)
607  {
608  /* Set the Request Data */
610  WRITE_PORT_UCHAR(&((PDMA1_CONTROL)AdapterBaseVa)->Mode, DmaMode.Byte);
611 
612  /* Unmask DMA Channel */
613  WRITE_PORT_UCHAR(&((PDMA1_CONTROL)AdapterBaseVa)->SingleMask,
614  AdapterObject->ChannelNumber | DMA_CLEARMASK);
615  }
616  else
617  {
618  /* Set the Request Data */
619  WRITE_PORT_UCHAR(&((PDMA2_CONTROL)AdapterBaseVa)->Mode, DmaMode.Byte);
620 
621  /* Unmask DMA Channel */
622  WRITE_PORT_UCHAR(&((PDMA2_CONTROL)AdapterBaseVa)->SingleMask,
623  AdapterObject->ChannelNumber | DMA_CLEARMASK);
624  }
625  }
626  else
627  {
628  if (DeviceDescription->DemandMode)
629  {
631  }
632  else
633  {
635  }
636  }
637 
638  AdapterObject->AdapterMode = DmaMode;
639 
640  return TRUE;
641 }
642 
643 #ifndef _MINIHAL_
644 
660 NTAPI
663 {
664  PADAPTER_OBJECT AdapterObject = NULL;
666  ULONG MapRegisters;
668  KIRQL OldIrql;
669 
670  /* Validate parameters in device description */
671  if (DeviceDescription->Version > DEVICE_DESCRIPTION_VERSION2) return NULL;
672 
673  /*
674  * See if we're going to use ISA/EISA DMA adapter. These adapters are
675  * special since they're reused.
676  *
677  * Also note that we check for channel number since there are only 8 DMA
678  * channels on ISA, so any request above this requires new adapter.
679  */
680  if (((DeviceDescription->InterfaceType == Eisa) ||
681  (DeviceDescription->InterfaceType == Isa)) || !(DeviceDescription->Master))
682  {
683  if (((DeviceDescription->InterfaceType == Isa) ||
684  (DeviceDescription->InterfaceType == Eisa)) &&
685  (DeviceDescription->DmaChannel >= 8))
686  {
687  EisaAdapter = FALSE;
688  }
689  else
690  {
691  EisaAdapter = TRUE;
692  }
693  }
694  else
695  {
696  EisaAdapter = FALSE;
697  }
698 
699  /*
700  * Disallow creating adapter for ISA/EISA DMA channel 4 since it's used
701  * for cascading the controllers and it's not available for software use.
702  */
703  if ((EisaAdapter) && (DeviceDescription->DmaChannel == 4)) return NULL;
704 
705  /*
706  * Calculate the number of map registers.
707  *
708  * - For EISA and PCI scatter/gather no map registers are needed.
709  * - For ISA slave scatter/gather one map register is needed.
710  * - For all other cases the number of map registers depends on
711  * DeviceDescription->MaximumLength.
712  */
713  MaximumLength = DeviceDescription->MaximumLength & MAXLONG;
714  if ((DeviceDescription->ScatterGather) &&
715  ((DeviceDescription->InterfaceType == Eisa) ||
716  (DeviceDescription->InterfaceType == PCIBus)))
717  {
718  MapRegisters = 0;
719  }
720  else if ((DeviceDescription->ScatterGather) && !(DeviceDescription->Master))
721  {
722  MapRegisters = 1;
723  }
724  else
725  {
726  /*
727  * In the equation below the additional map register added by
728  * the "+1" accounts for the case when a transfer does not start
729  * at a page-aligned address.
730  */
731  MapRegisters = BYTES_TO_PAGES(MaximumLength) + 1;
732  if (MapRegisters > 16) MapRegisters = 16;
733  }
734 
735  /*
736  * Acquire the DMA lock that is used to protect the EISA adapter array.
737  */
739 
740  /*
741  * Now we must get ahold of the adapter object. For first eight ISA/EISA
742  * channels there are static adapter objects that are reused and updated
743  * on succesive HalGetAdapter calls. In other cases a new adapter object
744  * is always created and it's to the DMA adapter list (HalpDmaAdapterList).
745  */
746  if (EisaAdapter)
747  {
748  AdapterObject = HalpEisaAdapter[DeviceDescription->DmaChannel];
749  if (AdapterObject)
750  {
751  if ((AdapterObject->NeedsMapRegisters) &&
752  (MapRegisters > AdapterObject->MapRegistersPerChannel))
753  {
754  AdapterObject->MapRegistersPerChannel = MapRegisters;
755  }
756  }
757  }
758 
759  if (AdapterObject == NULL)
760  {
761  AdapterObject = HalpDmaAllocateChildAdapter(MapRegisters, DeviceDescription);
762  if (AdapterObject == NULL)
763  {
764  KeSetEvent(&HalpDmaLock, 0, 0);
765  return NULL;
766  }
767 
768  if (EisaAdapter)
769  {
770  HalpEisaAdapter[DeviceDescription->DmaChannel] = AdapterObject;
771  }
772 
773  if (MapRegisters > 0)
774  {
775  AdapterObject->NeedsMapRegisters = TRUE;
776  AdapterObject->MapRegistersPerChannel = MapRegisters;
777  }
778  else
779  {
780  AdapterObject->NeedsMapRegisters = FALSE;
781  if (DeviceDescription->Master)
782  {
783  AdapterObject->MapRegistersPerChannel = BYTES_TO_PAGES(MaximumLength) + 1;
784  }
785  else
786  {
787  AdapterObject->MapRegistersPerChannel = 1;
788  }
789  }
790  }
791 
792  /*
793  * Release the DMA lock. HalpEisaAdapter will no longer be touched,
794  * so we don't need it.
795  */
796  KeSetEvent(&HalpDmaLock, 0, 0);
797 
798  if (!EisaAdapter)
799  {
800  /* If it's not one of the static adapters, add it to the list */
802  InsertTailList(&HalpDmaAdapterList, &AdapterObject->AdapterList);
804  }
805 
806  /*
807  * Setup the values in the adapter object that are common for all
808  * types of buses.
809  */
811  {
812  AdapterObject->IgnoreCount = DeviceDescription->IgnoreCount;
813  }
814  else
815  {
816  AdapterObject->IgnoreCount = 0;
817  }
818 
819  AdapterObject->Dma32BitAddresses = DeviceDescription->Dma32BitAddresses;
820  AdapterObject->Dma64BitAddresses = DeviceDescription->Dma64BitAddresses;
821  AdapterObject->ScatterGather = DeviceDescription->ScatterGather;
822  AdapterObject->MasterDevice = DeviceDescription->Master;
823  *NumberOfMapRegisters = AdapterObject->MapRegistersPerChannel;
824 
825  /*
826  * For non-(E)ISA adapters we have already done all the work. On the
827  * other hand for (E)ISA adapters we must still setup the DMA modes
828  * and prepare the controller.
829  */
830  if (EisaAdapter)
831  {
832  if (!HalpDmaInitializeEisaAdapter(AdapterObject, DeviceDescription))
833  {
834  ObDereferenceObject(AdapterObject);
835  return NULL;
836  }
837  }
838 
839  return AdapterObject;
840 }
841 
851 NTAPI
855 {
857 }
858 
867 VOID
868 NTAPI
870 {
871  KIRQL OldIrql;
872  if (AdapterObject->ChannelNumber == 0xFF)
873  {
875  RemoveEntryList(&AdapterObject->AdapterList);
877  }
878 
879  ObDereferenceObject(AdapterObject);
880 }
881 
907 PVOID
908 NTAPI
910  IN ULONG Length,
911  IN PPHYSICAL_ADDRESS LogicalAddress,
912  IN BOOLEAN CacheEnabled)
913 {
916  PHYSICAL_ADDRESS BoundryAddressMultiple;
918 
921  BoundryAddressMultiple.QuadPart = 0;
922 
923  /*
924  * For bus-master DMA devices the buffer mustn't cross 4Gb boundary. For
925  * slave DMA devices the 64Kb boundary mustn't be crossed since the
926  * controller wouldn't be able to handle it.
927  */
928  if (AdapterObject->MasterDevice)
929  {
930  BoundryAddressMultiple.HighPart = 1;
931  }
932  else
933  {
934  BoundryAddressMultiple.LowPart = 0x10000;
935  }
936 
940  BoundryAddressMultiple,
941  CacheEnabled ? MmCached :
942  MmNonCached);
943  if (VirtualAddress == NULL) return NULL;
944 
945  *LogicalAddress = MmGetPhysicalAddress(VirtualAddress);
946 
947  return VirtualAddress;
948 }
949 
959 VOID
960 NTAPI
962  IN ULONG Length,
963  IN PHYSICAL_ADDRESS LogicalAddress,
965  IN BOOLEAN CacheEnabled)
966 {
968  Length,
969  CacheEnabled ? MmCached : MmNonCached);
970 }
971 
972 typedef struct _SCATTER_GATHER_CONTEXT {
984 
985 
987 NTAPI
989  IN PIRP Irp,
991  IN PVOID Context)
992 {
993  PSCATTER_GATHER_CONTEXT AdapterControlContext = Context;
994  PADAPTER_OBJECT AdapterObject = AdapterControlContext->AdapterObject;
995  PSCATTER_GATHER_LIST ScatterGatherList;
997  ULONG ElementCount = 0, RemainingLength = AdapterControlContext->Length;
998  PUCHAR CurrentVa = AdapterControlContext->CurrentVa;
999 
1000  /* Store the map register base for later in HalPutScatterGatherList */
1001  AdapterControlContext->MapRegisterBase = MapRegisterBase;
1002 
1003  while (RemainingLength > 0 && ElementCount < MAX_SG_ELEMENTS)
1004  {
1005  TempElements[ElementCount].Length = RemainingLength;
1006  TempElements[ElementCount].Reserved = 0;
1007  TempElements[ElementCount].Address = IoMapTransfer(AdapterObject,
1008  AdapterControlContext->Mdl,
1010  CurrentVa + (AdapterControlContext->Length - RemainingLength),
1011  &TempElements[ElementCount].Length,
1012  AdapterControlContext->WriteToDevice);
1013  if (TempElements[ElementCount].Length == 0)
1014  break;
1015 
1016  DPRINT("Allocated one S/G element: 0x%I64u with length: 0x%x\n",
1017  TempElements[ElementCount].Address.QuadPart,
1018  TempElements[ElementCount].Length);
1019 
1020  ASSERT(TempElements[ElementCount].Length <= RemainingLength);
1021  RemainingLength -= TempElements[ElementCount].Length;
1022  ElementCount++;
1023  }
1024 
1025  if (RemainingLength > 0)
1026  {
1027  DPRINT1("Scatter/gather list construction failed!\n");
1028  return DeallocateObject;
1029  }
1030 
1031  ScatterGatherList = ExAllocatePoolWithTag(NonPagedPool,
1032  sizeof(SCATTER_GATHER_LIST) + sizeof(SCATTER_GATHER_ELEMENT) * ElementCount,
1033  TAG_DMA);
1034  ASSERT(ScatterGatherList);
1035 
1036  ScatterGatherList->NumberOfElements = ElementCount;
1037  ScatterGatherList->Reserved = (ULONG_PTR)AdapterControlContext;
1038  RtlCopyMemory(ScatterGatherList->Elements,
1039  TempElements,
1040  sizeof(SCATTER_GATHER_ELEMENT) * ElementCount);
1041 
1042  DPRINT("Initiating S/G DMA with %d element(s)\n", ElementCount);
1043 
1044  AdapterControlContext->AdapterListControlRoutine(DeviceObject,
1045  Irp,
1046  ScatterGatherList,
1047  AdapterControlContext->AdapterListControlContext);
1048 
1050 }
1051 
1080  NTSTATUS
1081  NTAPI
1084  IN PMDL Mdl,
1085  IN PVOID CurrentVa,
1086  IN ULONG Length,
1088  IN PVOID Context,
1090 {
1091  return HalBuildScatterGatherList(AdapterObject,
1092  DeviceObject,
1093  Mdl,
1094  CurrentVa,
1095  Length,
1097  Context,
1098  WriteToDevice,
1099  NULL,
1100  0);
1101 }
1102 
1121  VOID
1122  NTAPI
1126 {
1127  PSCATTER_GATHER_CONTEXT AdapterControlContext = (PSCATTER_GATHER_CONTEXT)ScatterGather->Reserved;
1128  ULONG i;
1129 
1130  for (i = 0; i < ScatterGather->NumberOfElements; i++)
1131  {
1132  IoFlushAdapterBuffers(AdapterObject,
1133  AdapterControlContext->Mdl,
1134  AdapterControlContext->MapRegisterBase,
1135  AdapterControlContext->CurrentVa,
1136  ScatterGather->Elements[i].Length,
1137  AdapterControlContext->WriteToDevice);
1138  AdapterControlContext->CurrentVa += ScatterGather->Elements[i].Length;
1139  }
1140 
1141  IoFreeMapRegisters(AdapterObject,
1142  AdapterControlContext->MapRegisterBase,
1143  AdapterControlContext->MapRegisterCount);
1144 
1145 
1147 
1148  /* If this is our buffer, release it */
1149  if (!AdapterControlContext->UsingUserBuffer)
1150  ExFreePoolWithTag(AdapterControlContext, TAG_DMA);
1151 
1152  DPRINT("S/G DMA has finished!\n");
1153 }
1154 
1155 NTSTATUS
1156 NTAPI
1158  IN PADAPTER_OBJECT AdapterObject,
1159  IN PMDL Mdl OPTIONAL,
1160  IN PVOID CurrentVa,
1161  IN ULONG Length,
1162  OUT PULONG ScatterGatherListSize,
1163  OUT PULONG pNumberOfMapRegisters)
1164 {
1166  ULONG SgSize;
1167 
1169 
1171  SgSize = sizeof(SCATTER_GATHER_CONTEXT);
1172 
1173  *ScatterGatherListSize = SgSize;
1174  if (pNumberOfMapRegisters) *pNumberOfMapRegisters = NumberOfMapRegisters;
1175 
1176  return STATUS_SUCCESS;
1177 }
1178 
1213 NTSTATUS
1214 NTAPI
1216  IN PADAPTER_OBJECT AdapterObject,
1218  IN PMDL Mdl,
1219  IN PVOID CurrentVa,
1220  IN ULONG Length,
1222  IN PVOID Context,
1224  IN PVOID ScatterGatherBuffer,
1225  IN ULONG ScatterGatherBufferLength)
1226 {
1227  NTSTATUS Status;
1228  ULONG SgSize, NumberOfMapRegisters;
1229  PSCATTER_GATHER_CONTEXT ScatterGatherContext;
1230  BOOLEAN UsingUserBuffer;
1231 
1232  Status = HalCalculateScatterGatherListSize(AdapterObject,
1233  Mdl,
1234  CurrentVa,
1235  Length,
1236  &SgSize,
1238  if (!NT_SUCCESS(Status)) return Status;
1239 
1240  if (ScatterGatherBuffer)
1241  {
1242  /* Checking if user buffer is enough */
1243  if (ScatterGatherBufferLength < SgSize)
1244  {
1245  return STATUS_BUFFER_TOO_SMALL;
1246  }
1247  UsingUserBuffer = TRUE;
1248  }
1249  else
1250  {
1251  ScatterGatherBuffer = ExAllocatePoolWithTag(NonPagedPool, SgSize, TAG_DMA);
1252  if (!ScatterGatherBuffer)
1253  {
1255  }
1256  UsingUserBuffer = FALSE;
1257  }
1258 
1259  {
1260  ScatterGatherContext = (PSCATTER_GATHER_CONTEXT)ScatterGatherBuffer;
1261 
1262  /* Fill the scatter-gather context */
1263  ScatterGatherContext->UsingUserBuffer = UsingUserBuffer;
1264  ScatterGatherContext->AdapterObject = AdapterObject;
1265  ScatterGatherContext->Mdl = Mdl;
1266  ScatterGatherContext->CurrentVa = CurrentVa;
1267  ScatterGatherContext->Length = Length;
1268  ScatterGatherContext->MapRegisterCount = NumberOfMapRegisters;
1269  ScatterGatherContext->AdapterListControlRoutine = ExecutionRoutine;
1270  ScatterGatherContext->AdapterListControlContext = Context;
1271  ScatterGatherContext->WriteToDevice = WriteToDevice;
1272 
1273  ScatterGatherContext->Wcb.DeviceObject = DeviceObject;
1274  ScatterGatherContext->Wcb.DeviceContext = (PVOID)ScatterGatherContext;
1275  ScatterGatherContext->Wcb.CurrentIrp = DeviceObject->CurrentIrp;
1276 
1277  Status = HalAllocateAdapterChannel(AdapterObject,
1278  &ScatterGatherContext->Wcb,
1281 
1282  if (!NT_SUCCESS(Status))
1283  {
1284  if (!UsingUserBuffer)
1285  ExFreePoolWithTag(ScatterGatherBuffer, TAG_DMA);
1286  return Status;
1287  }
1288  }
1289 
1290  return STATUS_SUCCESS;
1291 }
1292 
1293 NTSTATUS
1294 NTAPI
1296  IN PDMA_ADAPTER DmaAdapter,
1298  IN PMDL OriginalMdl,
1299  OUT PMDL *TargetMdl)
1300 {
1301  UNIMPLEMENTED;
1302  return STATUS_NOT_IMPLEMENTED;
1303 }
1304 #endif
1305 
1314 ULONG
1315 NTAPI
1317 {
1318  return 1;
1319 }
1320 
1321 /*
1322  * @name HalReadDmaCounter
1323  *
1324  * Read DMA operation progress counter.
1325  *
1326  * @implemented
1327  */
1328 ULONG
1329 NTAPI
1331 {
1332  KIRQL OldIrql;
1333  ULONG Count, OldCount;
1334 
1335  ASSERT(!AdapterObject->MasterDevice);
1336 
1337  /*
1338  * Acquire the master adapter lock since we're going to mess with the
1339  * system DMA controller registers and we really don't want anyone
1340  * to do the same at the same time.
1341  */
1342  KeAcquireSpinLock(&AdapterObject->MasterAdapter->SpinLock, &OldIrql);
1343 
1344  /* Send the request to the specific controller. */
1345  if (AdapterObject->AdapterNumber == 1)
1346  {
1347  PDMA1_CONTROL DmaControl1 = AdapterObject->AdapterBaseVa;
1348 
1349  Count = 0xffff00;
1350  do
1351  {
1352  OldCount = Count;
1353 
1354  /* Send Reset */
1355  WRITE_PORT_UCHAR(&DmaControl1->ClearBytePointer, 0);
1356 
1357  /* Read Count */
1358  Count = READ_PORT_UCHAR(&DmaControl1->DmaAddressCount
1359  [AdapterObject->ChannelNumber].DmaBaseCount);
1360  Count |= READ_PORT_UCHAR(&DmaControl1->DmaAddressCount
1361  [AdapterObject->ChannelNumber].DmaBaseCount) << 8;
1362  } while (0xffff00 & (OldCount ^ Count));
1363  }
1364  else
1365  {
1366  PDMA2_CONTROL DmaControl2 = AdapterObject->AdapterBaseVa;
1367 
1368  Count = 0xffff00;
1369  do
1370  {
1371  OldCount = Count;
1372 
1373  /* Send Reset */
1374  WRITE_PORT_UCHAR(&DmaControl2->ClearBytePointer, 0);
1375 
1376  /* Read Count */
1377  Count = READ_PORT_UCHAR(&DmaControl2->DmaAddressCount
1378  [AdapterObject->ChannelNumber].DmaBaseCount);
1379  Count |= READ_PORT_UCHAR(&DmaControl2->DmaAddressCount
1380  [AdapterObject->ChannelNumber].DmaBaseCount) << 8;
1381  } while (0xffff00 & (OldCount ^ Count));
1382  }
1383 
1384  KeReleaseSpinLock(&AdapterObject->MasterAdapter->SpinLock, OldIrql);
1385 
1386  Count++;
1387  Count &= 0xffff;
1388  if (AdapterObject->Width16Bits) Count *= 2;
1389 
1390  return Count;
1391 }
1392 
1393 #ifndef _MINIHAL_
1394 
1400 VOID
1401 NTAPI
1403 {
1405  KIRQL OldIrql;
1406  BOOLEAN Succeeded;
1407 
1408  /*
1409  * Try to allocate new map registers for the adapter.
1410  *
1411  * NOTE: The NT implementation actually tries to allocate more map
1412  * registers than needed as an optimization.
1413  */
1415  Succeeded = HalpGrowMapBuffers(WorkItem->AdapterObject->MasterAdapter,
1416  WorkItem->NumberOfMapRegisters << PAGE_SHIFT);
1417  KeSetEvent(&HalpDmaLock, 0, 0);
1418 
1419  if (Succeeded)
1420  {
1421  /*
1422  * Flush the adapter queue now that new map registers are ready. The
1423  * easiest way to do that is to call IoFreeMapRegisters to not free
1424  * any registers. Note that we use the magic (PVOID)2 map register
1425  * base to bypass the parameter checking.
1426  */
1428  IoFreeMapRegisters(WorkItem->AdapterObject, (PVOID)2, 0);
1430  }
1431 
1433 }
1434 
1459 NTSTATUS
1460 NTAPI
1462  IN PWAIT_CONTEXT_BLOCK WaitContextBlock,
1465 {
1466  PADAPTER_OBJECT MasterAdapter;
1468  ULONG Index = MAXULONG;
1469  ULONG Result;
1470  KIRQL OldIrql;
1471 
1473 
1474  /* Set up the wait context block in case we can't run right away. */
1475  WaitContextBlock->DeviceRoutine = ExecutionRoutine;
1476  WaitContextBlock->NumberOfMapRegisters = NumberOfMapRegisters;
1477 
1478  /* Returns true if queued, else returns false and sets the queue to busy */
1479  if (KeInsertDeviceQueue(&AdapterObject->ChannelWaitQueue,
1480  &WaitContextBlock->WaitQueueEntry))
1481  {
1482  return STATUS_SUCCESS;
1483  }
1484 
1485  MasterAdapter = AdapterObject->MasterAdapter;
1486 
1487  AdapterObject->NumberOfMapRegisters = NumberOfMapRegisters;
1488  AdapterObject->CurrentWcb = WaitContextBlock;
1489 
1490  if ((NumberOfMapRegisters) && (AdapterObject->NeedsMapRegisters))
1491  {
1492  if (NumberOfMapRegisters > AdapterObject->MapRegistersPerChannel)
1493  {
1494  AdapterObject->NumberOfMapRegisters = 0;
1495  IoFreeAdapterChannel(AdapterObject);
1497  }
1498 
1499  /*
1500  * Get the map registers. This is partly complicated by the fact
1501  * that new map registers can only be allocated at PASSIVE_LEVEL
1502  * and we're currently at DISPATCH_LEVEL. The following code has
1503  * two code paths:
1504  *
1505  * - If there is no adapter queued for map register allocation,
1506  * try to see if enough contiguous map registers are present.
1507  * In case they're we can just get them and proceed further.
1508  *
1509  * - If some adapter is already present in the queue we must
1510  * respect the order of adapters asking for map registers and
1511  * so the fast case described above can't take place.
1512  * This case is also entered if not enough coniguous map
1513  * registers are present.
1514  *
1515  * A work queue item is allocated and queued, the adapter is
1516  * also queued into the master adapter queue. The worker
1517  * routine does the job of allocating the map registers at
1518  * PASSIVE_LEVEL and calling the ExecutionRoutine.
1519  */
1520 
1521  KeAcquireSpinLock(&MasterAdapter->SpinLock, &OldIrql);
1522 
1523  if (IsListEmpty(&MasterAdapter->AdapterQueue))
1524  {
1525  Index = RtlFindClearBitsAndSet(MasterAdapter->MapRegisters, NumberOfMapRegisters, 0);
1526  if (Index != MAXULONG)
1527  {
1528  AdapterObject->MapRegisterBase = MasterAdapter->MapRegisterBase + Index;
1529  if (!AdapterObject->ScatterGather)
1530  {
1531  AdapterObject->MapRegisterBase = (PROS_MAP_REGISTER_ENTRY)((ULONG_PTR)AdapterObject->MapRegisterBase | MAP_BASE_SW_SG);
1532  }
1533  }
1534  }
1535 
1536  if (Index == MAXULONG)
1537  {
1538  InsertTailList(&MasterAdapter->AdapterQueue, &AdapterObject->AdapterQueue);
1539 
1541  sizeof(GROW_WORK_ITEM),
1542  TAG_DMA);
1543  if (WorkItem)
1544  {
1546  WorkItem->AdapterObject = AdapterObject;
1547  WorkItem->NumberOfMapRegisters = NumberOfMapRegisters;
1548 
1549  ExQueueWorkItem(&WorkItem->WorkQueueItem, DelayedWorkQueue);
1550  }
1551 
1552  KeReleaseSpinLock(&MasterAdapter->SpinLock, OldIrql);
1553 
1554  return STATUS_SUCCESS;
1555  }
1556 
1557  KeReleaseSpinLock(&MasterAdapter->SpinLock, OldIrql);
1558  }
1559  else
1560  {
1561  AdapterObject->MapRegisterBase = NULL;
1562  AdapterObject->NumberOfMapRegisters = 0;
1563  }
1564 
1565  AdapterObject->CurrentWcb = WaitContextBlock;
1566 
1567  Result = ExecutionRoutine(WaitContextBlock->DeviceObject,
1568  WaitContextBlock->CurrentIrp,
1569  AdapterObject->MapRegisterBase,
1570  WaitContextBlock->DeviceContext);
1571 
1572  /*
1573  * Possible return values:
1574  *
1575  * - KeepObject
1576  * Don't free any resources, the ADAPTER_OBJECT is still in use and
1577  * the caller will call IoFreeAdapterChannel later.
1578  *
1579  * - DeallocateObject
1580  * Deallocate the map registers and release the ADAPTER_OBJECT, so
1581  * someone else can use it.
1582  *
1583  * - DeallocateObjectKeepRegisters
1584  * Release the ADAPTER_OBJECT, but hang on to the map registers. The
1585  * client will later call IoFreeMapRegisters.
1586  *
1587  * NOTE:
1588  * IoFreeAdapterChannel runs the queue, so it must be called unless
1589  * the adapter object is not to be freed.
1590  */
1591  if (Result == DeallocateObject)
1592  {
1593  IoFreeAdapterChannel(AdapterObject);
1594  }
1596  {
1597  AdapterObject->NumberOfMapRegisters = 0;
1598  IoFreeAdapterChannel(AdapterObject);
1599  }
1600 
1601  return STATUS_SUCCESS;
1602 }
1603 
1622 VOID
1623 NTAPI
1625 {
1626  PADAPTER_OBJECT MasterAdapter;
1628  PWAIT_CONTEXT_BLOCK WaitContextBlock;
1629  ULONG Index = MAXULONG;
1630  ULONG Result;
1631  KIRQL OldIrql;
1632 
1633  MasterAdapter = AdapterObject->MasterAdapter;
1634 
1635  for (;;)
1636  {
1637  /*
1638  * To keep map registers, call here with AdapterObject->
1639  * NumberOfMapRegisters set to zero. This trick is used in
1640  * HalAllocateAdapterChannel for example.
1641  */
1642  if (AdapterObject->NumberOfMapRegisters)
1643  {
1644  IoFreeMapRegisters(AdapterObject,
1645  AdapterObject->MapRegisterBase,
1646  AdapterObject->NumberOfMapRegisters);
1647  }
1648 
1649  DeviceQueueEntry = KeRemoveDeviceQueue(&AdapterObject->ChannelWaitQueue);
1650  if (!DeviceQueueEntry) break;
1651 
1652  WaitContextBlock = CONTAINING_RECORD(DeviceQueueEntry,
1654  WaitQueueEntry);
1655 
1656  AdapterObject->CurrentWcb = WaitContextBlock;
1657  AdapterObject->NumberOfMapRegisters = WaitContextBlock->NumberOfMapRegisters;
1658 
1659  if ((WaitContextBlock->NumberOfMapRegisters) && (AdapterObject->MasterAdapter))
1660  {
1661  KeAcquireSpinLock(&MasterAdapter->SpinLock, &OldIrql);
1662 
1663  if (IsListEmpty(&MasterAdapter->AdapterQueue))
1664  {
1665  Index = RtlFindClearBitsAndSet(MasterAdapter->MapRegisters,
1666  WaitContextBlock->NumberOfMapRegisters,
1667  0);
1668  if (Index != MAXULONG)
1669  {
1670  AdapterObject->MapRegisterBase = MasterAdapter->MapRegisterBase + Index;
1671  if (!AdapterObject->ScatterGather)
1672  {
1673  AdapterObject->MapRegisterBase =(PROS_MAP_REGISTER_ENTRY)((ULONG_PTR)AdapterObject->MapRegisterBase | MAP_BASE_SW_SG);
1674  }
1675  }
1676  }
1677 
1678  if (Index == MAXULONG)
1679  {
1680  InsertTailList(&MasterAdapter->AdapterQueue, &AdapterObject->AdapterQueue);
1681  KeReleaseSpinLock(&MasterAdapter->SpinLock, OldIrql);
1682  break;
1683  }
1684 
1685  KeReleaseSpinLock(&MasterAdapter->SpinLock, OldIrql);
1686  }
1687  else
1688  {
1689  AdapterObject->MapRegisterBase = NULL;
1690  AdapterObject->NumberOfMapRegisters = 0;
1691  }
1692 
1693  /* Call the adapter control routine. */
1694  Result = ((PDRIVER_CONTROL)WaitContextBlock->DeviceRoutine)(WaitContextBlock->DeviceObject,
1695  WaitContextBlock->CurrentIrp,
1696  AdapterObject->MapRegisterBase,
1697  WaitContextBlock->DeviceContext);
1698  switch (Result)
1699  {
1700  case KeepObject:
1701  /*
1702  * We're done until the caller manually calls IoFreeAdapterChannel
1703  * or IoFreeMapRegisters.
1704  */
1705  return;
1706 
1708  /*
1709  * Hide the map registers so they aren't deallocated next time
1710  * around.
1711  */
1712  AdapterObject->NumberOfMapRegisters = 0;
1713  break;
1714 
1715  default:
1716  break;
1717  }
1718  }
1719 }
1720 
1735 VOID
1736 NTAPI
1740 {
1741  PADAPTER_OBJECT MasterAdapter = AdapterObject->MasterAdapter;
1742  PLIST_ENTRY ListEntry;
1743  KIRQL OldIrql;
1744  ULONG Index;
1745  ULONG Result;
1746 
1748 
1749  if (!(MasterAdapter) || !(MapRegisterBase)) return;
1750 
1751  KeAcquireSpinLock(&MasterAdapter->SpinLock, &OldIrql);
1752 
1753  if (NumberOfMapRegisters != 0)
1754  {
1755  PROS_MAP_REGISTER_ENTRY RealMapRegisterBase;
1756 
1757  RealMapRegisterBase = (PROS_MAP_REGISTER_ENTRY)((ULONG_PTR)MapRegisterBase & ~MAP_BASE_SW_SG);
1758  RtlClearBits(MasterAdapter->MapRegisters,
1759  (ULONG)(RealMapRegisterBase - MasterAdapter->MapRegisterBase),
1761  }
1762 
1763  /*
1764  * Now that we freed few map registers it's time to look at the master
1765  * adapter queue and see if there is someone waiting for map registers.
1766  */
1767  while (!IsListEmpty(&MasterAdapter->AdapterQueue))
1768  {
1769  ListEntry = RemoveHeadList(&MasterAdapter->AdapterQueue);
1770  AdapterObject = CONTAINING_RECORD(ListEntry, struct _ADAPTER_OBJECT, AdapterQueue);
1771 
1772  Index = RtlFindClearBitsAndSet(MasterAdapter->MapRegisters,
1773  AdapterObject->NumberOfMapRegisters,
1774  0);
1775  if (Index == MAXULONG)
1776  {
1777  InsertHeadList(&MasterAdapter->AdapterQueue, ListEntry);
1778  break;
1779  }
1780 
1781  KeReleaseSpinLock(&MasterAdapter->SpinLock, OldIrql);
1782 
1783  AdapterObject->MapRegisterBase = MasterAdapter->MapRegisterBase + Index;
1784  if (!AdapterObject->ScatterGather)
1785  {
1786  AdapterObject->MapRegisterBase =
1787  (PROS_MAP_REGISTER_ENTRY)((ULONG_PTR)AdapterObject->MapRegisterBase | MAP_BASE_SW_SG);
1788  }
1789 
1790  Result = ((PDRIVER_CONTROL)AdapterObject->CurrentWcb->DeviceRoutine)(AdapterObject->CurrentWcb->DeviceObject,
1791  AdapterObject->CurrentWcb->CurrentIrp,
1792  AdapterObject->MapRegisterBase,
1793  AdapterObject->CurrentWcb->DeviceContext);
1794  switch (Result)
1795  {
1797  AdapterObject->NumberOfMapRegisters = 0;
1798  /* fall through */
1799 
1800  case DeallocateObject:
1801  if (AdapterObject->NumberOfMapRegisters)
1802  {
1803  KeAcquireSpinLock(&MasterAdapter->SpinLock, &OldIrql);
1804  RtlClearBits(MasterAdapter->MapRegisters,
1805  (ULONG)(AdapterObject->MapRegisterBase -
1806  MasterAdapter->MapRegisterBase),
1807  AdapterObject->NumberOfMapRegisters);
1808  KeReleaseSpinLock(&MasterAdapter->SpinLock, OldIrql);
1809  }
1810 
1811  IoFreeAdapterChannel(AdapterObject);
1812  break;
1813 
1814  default:
1815  break;
1816  }
1817 
1818  KeAcquireSpinLock(&MasterAdapter->SpinLock, &OldIrql);
1819  }
1820 
1821  KeReleaseSpinLock(&MasterAdapter->SpinLock, OldIrql);
1822 }
1823 
1831 VOID
1832 NTAPI
1835  IN PVOID CurrentVa,
1836  IN ULONG Length,
1838 {
1839  ULONG CurrentLength;
1840  ULONG_PTR CurrentAddress;
1841  ULONG ByteOffset;
1843 
1845  if (!VirtualAddress)
1846  {
1847  /*
1848  * NOTE: On real NT a mechanism with reserved pages is implemented
1849  * to handle this case in a slow, but graceful non-fatal way.
1850  */
1851  KeBugCheckEx(HAL_MEMORY_ALLOCATION, PAGE_SIZE, 0, (ULONG_PTR)__FILE__, 0);
1852  }
1853 
1854  CurrentAddress = (ULONG_PTR)VirtualAddress +
1855  (ULONG_PTR)CurrentVa -
1857 
1858  while (Length > 0)
1859  {
1860  ByteOffset = BYTE_OFFSET(CurrentAddress);
1861  CurrentLength = PAGE_SIZE - ByteOffset;
1862  if (CurrentLength > Length) CurrentLength = Length;
1863 
1864  if (WriteToDevice)
1865  {
1866  RtlCopyMemory((PVOID)((ULONG_PTR)MapRegisterBase->VirtualAddress + ByteOffset),
1867  (PVOID)CurrentAddress,
1868  CurrentLength);
1869  }
1870  else
1871  {
1872  RtlCopyMemory((PVOID)CurrentAddress,
1873  (PVOID)((ULONG_PTR)MapRegisterBase->VirtualAddress + ByteOffset),
1874  CurrentLength);
1875  }
1876 
1877  Length -= CurrentLength;
1878  CurrentAddress += CurrentLength;
1879  MapRegisterBase++;
1880  }
1881 }
1882 
1914 BOOLEAN
1915 NTAPI
1917  IN PMDL Mdl,
1919  IN PVOID CurrentVa,
1920  IN ULONG Length,
1922 {
1923  BOOLEAN SlaveDma = FALSE;
1924  PROS_MAP_REGISTER_ENTRY RealMapRegisterBase;
1927  PPFN_NUMBER MdlPagesPtr;
1928 
1929  /* Sanity checks */
1931  ASSERT(AdapterObject);
1932 
1933  if (!AdapterObject->MasterDevice)
1934  {
1935  /* Mask out (disable) the DMA channel. */
1936  if (AdapterObject->AdapterNumber == 1)
1937  {
1938  PDMA1_CONTROL DmaControl1 = AdapterObject->AdapterBaseVa;
1939  WRITE_PORT_UCHAR(&DmaControl1->SingleMask,
1940  AdapterObject->ChannelNumber | DMA_SETMASK);
1941  }
1942  else
1943  {
1944  PDMA2_CONTROL DmaControl2 = AdapterObject->AdapterBaseVa;
1945  WRITE_PORT_UCHAR(&DmaControl2->SingleMask,
1946  AdapterObject->ChannelNumber | DMA_SETMASK);
1947  }
1948  SlaveDma = TRUE;
1949  }
1950 
1951  /* This can happen if the device supports hardware scatter/gather. */
1952  if (MapRegisterBase == NULL) return TRUE;
1953 
1954  RealMapRegisterBase = (PROS_MAP_REGISTER_ENTRY)((ULONG_PTR)MapRegisterBase & ~MAP_BASE_SW_SG);
1955 
1956  if (!WriteToDevice)
1957  {
1959  {
1960  if (RealMapRegisterBase->Counter != MAXULONG)
1961  {
1962  if ((SlaveDma) && !(AdapterObject->IgnoreCount))
1963  {
1964  Length -= HalReadDmaCounter(AdapterObject);
1965  }
1966  }
1968  RealMapRegisterBase,
1969  CurrentVa,
1970  Length,
1971  FALSE);
1972  }
1973  else
1974  {
1975  MdlPagesPtr = MmGetMdlPfnArray(Mdl);
1976  MdlPagesPtr += ((ULONG_PTR)CurrentVa - (ULONG_PTR)Mdl->StartVa) >> PAGE_SHIFT;
1977 
1978  PhysicalAddress.QuadPart = *MdlPagesPtr << PAGE_SHIFT;
1979  PhysicalAddress.QuadPart += BYTE_OFFSET(CurrentVa);
1980 
1983  {
1985  RealMapRegisterBase,
1986  CurrentVa,
1987  Length,
1988  FALSE);
1989  }
1990  }
1991  }
1992 
1993  RealMapRegisterBase->Counter = 0;
1994 
1995  return TRUE;
1996 }
1997 
2030 NTAPI
2032  IN PMDL Mdl,
2034  IN PVOID CurrentVa,
2035  IN OUT PULONG Length,
2037 {
2038  PPFN_NUMBER MdlPagesPtr;
2039  PFN_NUMBER MdlPage1, MdlPage2;
2040  ULONG ByteOffset;
2042  ULONG TransferLength;
2043  BOOLEAN UseMapRegisters;
2044  PROS_MAP_REGISTER_ENTRY RealMapRegisterBase;
2047  ULONG Counter;
2048  DMA_MODE AdapterMode;
2049  KIRQL OldIrql;
2050 
2051  /*
2052  * Precalculate some values that are used in all cases.
2053  *
2054  * ByteOffset is offset inside the page at which the transfer starts.
2055  * MdlPagesPtr is pointer inside the MDL page chain at the page where the
2056  * transfer start.
2057  * PhysicalAddress is physical address corresponding to the transfer
2058  * start page and offset.
2059  * TransferLength is the initial length of the transfer, which is reminder
2060  * of the first page. The actual value is calculated below.
2061  *
2062  * Note that all the variables can change during the processing which
2063  * takes place below. These are just initial values.
2064  */
2065  ByteOffset = BYTE_OFFSET(CurrentVa);
2066 
2067  MdlPagesPtr = MmGetMdlPfnArray(Mdl);
2068  MdlPagesPtr += ((ULONG_PTR)CurrentVa - (ULONG_PTR)Mdl->StartVa) >> PAGE_SHIFT;
2069 
2070  PhysicalAddress.QuadPart = *MdlPagesPtr << PAGE_SHIFT;
2072 
2073  TransferLength = PAGE_SIZE - ByteOffset;
2074 
2075  /*
2076  * Special case for bus master adapters with S/G support. We can directly
2077  * use the buffer specified by the MDL, so not much work has to be done.
2078  *
2079  * Just return the passed VA's corresponding physical address and update
2080  * length to the number of physically contiguous bytes found. Also
2081  * pages crossing the 4Gb boundary aren't considered physically contiguous.
2082  */
2083  if (MapRegisterBase == NULL)
2084  {
2085  while (TransferLength < *Length)
2086  {
2087  MdlPage1 = *MdlPagesPtr;
2088  MdlPage2 = *(MdlPagesPtr + 1);
2089  if (MdlPage1 + 1 != MdlPage2) break;
2090  if ((MdlPage1 ^ MdlPage2) & ~0xFFFFF) break;
2091  TransferLength += PAGE_SIZE;
2092  MdlPagesPtr++;
2093  }
2094 
2095  if (TransferLength < *Length) *Length = TransferLength;
2096 
2097  return PhysicalAddress;
2098  }
2099 
2100  /*
2101  * The code below applies to slave DMA adapters and bus master adapters
2102  * without hardward S/G support.
2103  */
2104  RealMapRegisterBase = (PROS_MAP_REGISTER_ENTRY)((ULONG_PTR)MapRegisterBase & ~MAP_BASE_SW_SG);
2105 
2106  /*
2107  * Try to calculate the size of the transfer. We can only transfer
2108  * pages that are physically contiguous and that don't cross the
2109  * 64Kb boundary (this limitation applies only for ISA controllers).
2110  */
2111  while (TransferLength < *Length)
2112  {
2113  MdlPage1 = *MdlPagesPtr;
2114  MdlPage2 = *(MdlPagesPtr + 1);
2115  if (MdlPage1 + 1 != MdlPage2) break;
2116  if (!HalpEisaDma && ((MdlPage1 ^ MdlPage2) & ~0xF)) break;
2117  TransferLength += PAGE_SIZE;
2118  MdlPagesPtr++;
2119  }
2120 
2121  if (TransferLength > *Length) TransferLength = *Length;
2122 
2123  /*
2124  * If we're about to simulate software S/G and not all the pages are
2125  * physically contiguous then we must use the map registers to store
2126  * the data and allow the whole transfer to proceed at once.
2127  */
2128  if (((ULONG_PTR)MapRegisterBase & MAP_BASE_SW_SG) && (TransferLength < *Length))
2129  {
2130  UseMapRegisters = TRUE;
2131  PhysicalAddress = RealMapRegisterBase->PhysicalAddress;
2133  TransferLength = *Length;
2134  RealMapRegisterBase->Counter = MAXULONG;
2135  Counter = 0;
2136  }
2137  else
2138  {
2139  /*
2140  * This is ordinary DMA transfer, so just update the progress
2141  * counters. These are used by IoFlushAdapterBuffers to track
2142  * the transfer progress.
2143  */
2144  UseMapRegisters = FALSE;
2145  Counter = RealMapRegisterBase->Counter;
2146  RealMapRegisterBase->Counter += BYTES_TO_PAGES(ByteOffset + TransferLength);
2147 
2148  /*
2149  * Check if the buffer doesn't exceed the highest physical address
2150  * limit of the device. In that case we must use the map registers to
2151  * store the data.
2152  */
2154  if ((PhysicalAddress.QuadPart + TransferLength) > HighestAcceptableAddress.QuadPart)
2155  {
2156  UseMapRegisters = TRUE;
2157  PhysicalAddress = RealMapRegisterBase[Counter].PhysicalAddress;
2160  {
2161  RealMapRegisterBase->Counter = MAXULONG;
2162  Counter = 0;
2163  }
2164  }
2165  }
2166 
2167  /*
2168  * If we decided to use the map registers (see above) and we're about
2169  * to transfer data to the device then copy the buffers into the map
2170  * register memory.
2171  */
2172  if ((UseMapRegisters) && (WriteToDevice))
2173  {
2175  RealMapRegisterBase + Counter,
2176  CurrentVa,
2177  TransferLength,
2178  WriteToDevice);
2179  }
2180 
2181  /*
2182  * Return the length of transfer that actually takes place.
2183  */
2184  *Length = TransferLength;
2185 
2186  /*
2187  * If we're doing slave (system) DMA then program the (E)ISA controller
2188  * to actually start the transfer.
2189  */
2190  if ((AdapterObject) && !(AdapterObject->MasterDevice))
2191  {
2192  AdapterMode = AdapterObject->AdapterMode;
2193 
2194  if (WriteToDevice)
2195  {
2196  AdapterMode.TransferType = WRITE_TRANSFER;
2197  }
2198  else
2199  {
2200  AdapterMode.TransferType = READ_TRANSFER;
2201  if (AdapterObject->IgnoreCount)
2202  {
2203  RtlZeroMemory((PUCHAR)RealMapRegisterBase[Counter].VirtualAddress + ByteOffset,
2204  TransferLength);
2205  }
2206  }
2207 
2209  if (AdapterObject->Width16Bits)
2210  {
2211  TransferLength >>= 1;
2212  TransferOffset >>= 1;
2213  }
2214 
2215  KeAcquireSpinLock(&AdapterObject->MasterAdapter->SpinLock, &OldIrql);
2216 
2217  if (AdapterObject->AdapterNumber == 1)
2218  {
2219  PDMA1_CONTROL DmaControl1 = AdapterObject->AdapterBaseVa;
2220 
2221  /* Reset Register */
2222  WRITE_PORT_UCHAR(&DmaControl1->ClearBytePointer, 0);
2223 
2224  /* Set the Mode */
2225  WRITE_PORT_UCHAR(&DmaControl1->Mode, AdapterMode.Byte);
2226 
2227  /* Set the Offset Register */
2228  WRITE_PORT_UCHAR(&DmaControl1->DmaAddressCount[AdapterObject->ChannelNumber].DmaBaseAddress,
2229  (UCHAR)(TransferOffset));
2230  WRITE_PORT_UCHAR(&DmaControl1->DmaAddressCount[AdapterObject->ChannelNumber].DmaBaseAddress,
2231  (UCHAR)(TransferOffset >> 8));
2232 
2233  /* Set the Page Register */
2234  WRITE_PORT_UCHAR(AdapterObject->PagePort + FIELD_OFFSET(EISA_CONTROL, DmaController1Pages),
2235  (UCHAR)(PhysicalAddress.LowPart >> 16));
2236  if (HalpEisaDma)
2237  {
2238  WRITE_PORT_UCHAR(AdapterObject->PagePort + FIELD_OFFSET(EISA_CONTROL, DmaController2Pages),
2239  0);
2240  }
2241 
2242  /* Set the Length */
2243  WRITE_PORT_UCHAR(&DmaControl1->DmaAddressCount[AdapterObject->ChannelNumber].DmaBaseCount,
2244  (UCHAR)(TransferLength - 1));
2245  WRITE_PORT_UCHAR(&DmaControl1->DmaAddressCount[AdapterObject->ChannelNumber].DmaBaseCount,
2246  (UCHAR)((TransferLength - 1) >> 8));
2247 
2248  /* Unmask the Channel */
2249  WRITE_PORT_UCHAR(&DmaControl1->SingleMask, AdapterObject->ChannelNumber | DMA_CLEARMASK);
2250  }
2251  else
2252  {
2253  PDMA2_CONTROL DmaControl2 = AdapterObject->AdapterBaseVa;
2254 
2255  /* Reset Register */
2256  WRITE_PORT_UCHAR(&DmaControl2->ClearBytePointer, 0);
2257 
2258  /* Set the Mode */
2259  WRITE_PORT_UCHAR(&DmaControl2->Mode, AdapterMode.Byte);
2260 
2261  /* Set the Offset Register */
2262  WRITE_PORT_UCHAR(&DmaControl2->DmaAddressCount[AdapterObject->ChannelNumber].DmaBaseAddress,
2263  (UCHAR)(TransferOffset));
2264  WRITE_PORT_UCHAR(&DmaControl2->DmaAddressCount[AdapterObject->ChannelNumber].DmaBaseAddress,
2265  (UCHAR)(TransferOffset >> 8));
2266 
2267  /* Set the Page Register */
2268  WRITE_PORT_UCHAR(AdapterObject->PagePort + FIELD_OFFSET(EISA_CONTROL, DmaController1Pages),
2269  (UCHAR)(PhysicalAddress.u.LowPart >> 16));
2270  if (HalpEisaDma)
2271  {
2272  WRITE_PORT_UCHAR(AdapterObject->PagePort + FIELD_OFFSET(EISA_CONTROL, DmaController2Pages),
2273  0);
2274  }
2275 
2276  /* Set the Length */
2277  WRITE_PORT_UCHAR(&DmaControl2->DmaAddressCount[AdapterObject->ChannelNumber].DmaBaseCount,
2278  (UCHAR)(TransferLength - 1));
2279  WRITE_PORT_UCHAR(&DmaControl2->DmaAddressCount[AdapterObject->ChannelNumber].DmaBaseCount,
2280  (UCHAR)((TransferLength - 1) >> 8));
2281 
2282  /* Unmask the Channel */
2283  WRITE_PORT_UCHAR(&DmaControl2->SingleMask,
2284  AdapterObject->ChannelNumber | DMA_CLEARMASK);
2285  }
2286 
2287  KeReleaseSpinLock(&AdapterObject->MasterAdapter->SpinLock, OldIrql);
2288  }
2289 
2290  /*
2291  * Return physical address of the buffer with data that is used for the
2292  * transfer. It can either point inside the Mdl that was passed by the
2293  * caller or into the map registers if the Mdl buffer can't be used
2294  * directly.
2295  */
2296  return PhysicalAddress;
2297 }
2298 #endif
2299 
2305 BOOLEAN
2306 NTAPI
2308  IN ULONG Length,
2309  IN PHYSICAL_ADDRESS LogicalAddress,
2311 {
2312  /* Function always returns true */
2313  return TRUE;
2314 }
2315 
2316 /*
2317  * @implemented
2318  */
2319 PVOID
2320 NTAPI
2323 {
2324  PADAPTER_OBJECT MasterAdapter = AdapterObject->MasterAdapter;
2325  ULONG MapRegisterNumber;
2326 
2327  /* Check if it needs map registers */
2328  if (AdapterObject->NeedsMapRegisters)
2329  {
2330  /* Check if we have enough */
2331  if (*NumberOfMapRegisters > AdapterObject->MapRegistersPerChannel)
2332  {
2333  /* We don't, fail */
2334  AdapterObject->NumberOfMapRegisters = 0;
2335  return NULL;
2336  }
2337 
2338  /* Try to find free map registers */
2339  MapRegisterNumber = RtlFindClearBitsAndSet(MasterAdapter->MapRegisters,
2341  0);
2342 
2343  /* Check if nothing was found */
2344  if (MapRegisterNumber == MAXULONG)
2345  {
2346  /* No free registers found, so use the base registers */
2347  RtlSetBits(MasterAdapter->MapRegisters,
2348  0,
2350  MapRegisterNumber = 0;
2351  }
2352 
2353  /* Calculate the new base */
2354  AdapterObject->MapRegisterBase =
2355  (PROS_MAP_REGISTER_ENTRY)(MasterAdapter->MapRegisterBase +
2356  MapRegisterNumber);
2357 
2358  /* Check if scatter gather isn't supported */
2359  if (!AdapterObject->ScatterGather)
2360  {
2361  /* Set the flag */
2362  AdapterObject->MapRegisterBase =
2364  ((ULONG_PTR)AdapterObject->MapRegisterBase | MAP_BASE_SW_SG);
2365  }
2366  }
2367  else
2368  {
2369  AdapterObject->MapRegisterBase = NULL;
2370  AdapterObject->NumberOfMapRegisters = 0;
2371  }
2372 
2373  /* Return the base */
2374  return AdapterObject->MapRegisterBase;
2375 }
2376 
2377 /* EOF */
UCHAR DmaBaseCount
Definition: haldma.h:184
#define KeGetCurrentIrql()
Definition: env_spec_w32.h:706
#define WRITE_TRANSFER
Definition: haldma.h:166
_Inout_ PMDL TargetMdl
Definition: iofuncs.h:730
enum _IO_ALLOCATION_ACTION IO_ALLOCATION_ACTION
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
#define ASSERT_IRQL_LESS_OR_EQUAL(x)
Definition: debug.h:251
PVOID(NTAPI * PALLOCATE_COMMON_BUFFER)(_In_ PDMA_ADAPTER DmaAdapter, _In_ ULONG Length, _Out_ PPHYSICAL_ADDRESS LogicalAddress, _In_ BOOLEAN CacheEnabled)
Definition: iotypes.h:2311
#define PAGE_SHIFT
Definition: env_spec_w32.h:45
#define HalGetDmaAdapter
Definition: haltypes.h:291
#define IN
Definition: typedefs.h:39
UCHAR AutoInitialize
Definition: haldma.h:95
PDRIVER_LIST_CONTROL AdapterListControlRoutine
Definition: dma.c:978
#define MAX_SG_ELEMENTS
Definition: dma.c:80
UCHAR DmaBaseAddress
Definition: haldma.h:183
ULONG NTAPI HalReadDmaCounter(IN PADAPTER_OBJECT AdapterObject)
Definition: dma.c:76
VOID NTAPI ExQueueWorkItem(IN PWORK_QUEUE_ITEM WorkItem, IN WORK_QUEUE_TYPE QueueType)
Definition: work.c:723
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
#define B_32BITS
Definition: haldma.h:145
VOID(NTAPI * PPUT_SCATTER_GATHER_LIST)(_In_ PDMA_ADAPTER DmaAdapter, _In_ PSCATTER_GATHER_LIST ScatterGather, _In_ BOOLEAN WriteToDevice)
Definition: iotypes.h:2391
struct _RTL_BITMAP RTL_BITMAP
_Out_ PULONG NumberOfMapRegisters
Definition: halfuncs.h:209
#define MmGetMdlPfnArray(_Mdl)
UCHAR SingleMask
Definition: haldma.h:215
VOID NTAPI HalpCopyBufferMap(IN PMDL Mdl, IN PROS_MAP_REGISTER_ENTRY MapRegisterBase, IN PVOID CurrentVa, IN ULONG Length, IN BOOLEAN WriteToDevice)
Definition: dma.c:1833
DMA1_ADDRESS_COUNT DmaAddressCount[4]
Definition: haldma.h:197
_In_ ULONG Mode
Definition: hubbusif.h:303
#define MAXLONG
Definition: umtypes.h:116
#define MmGetMdlVirtualAddress(_Mdl)
static PADAPTER_OBJECT HalpEisaAdapter[8]
Definition: dma.c:86
#define READ_PORT_UCHAR(p)
Definition: pc98vid.h:22
PADAPTER_OBJECT NTAPI HalpDmaAllocateMasterAdapter(VOID)
Definition: dma.c:398
#define TRUE
Definition: types.h:120
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
FORCEINLINE VOID InsertHeadList(_Inout_ PLIST_ENTRY ListHead, _Inout_ __drv_aliasesMem PLIST_ENTRY Entry)
Definition: rtlfuncs.h:201
PHYSICAL_ADDRESS NTAPI IoMapTransfer(IN PADAPTER_OBJECT AdapterObject, IN PMDL Mdl, IN PVOID MapRegisterBase, IN PVOID CurrentVa, IN OUT PULONG Length, IN BOOLEAN WriteToDevice)
Definition: dma.c:144
UCHAR Mode
Definition: haldma.h:217
_Must_inspect_result_ _In_ WDFUSBDEVICE _In_ WDFREQUEST _In_ PWDF_USB_CONTROL_SETUP_PACKET _In_opt_ WDFMEMORY _In_opt_ PWDFMEMORY_OFFSET TransferOffset
Definition: wdfusb.h:1378
PFREE_MAP_REGISTERS FreeMapRegisters
Definition: iotypes.h:2640
unsigned char * PUCHAR
Definition: retypes.h:3
BOOLEAN NTAPI HalpDmaInitializeEisaAdapter(IN PADAPTER_OBJECT AdapterObject, IN PDEVICE_DESCRIPTION DeviceDescription)
Definition: dma.c:514
UCHAR DmaBaseAddress
Definition: haldma.h:189
NTSYSAPI void WINAPI RtlInitializeBitMap(PRTL_BITMAP, PULONG, ULONG)
LONG NTSTATUS
Definition: precomp.h:26
PADAPTER_OBJECT NTAPI HalpDmaAllocateChildAdapter(IN ULONG NumberOfMapRegisters, IN PDEVICE_DESCRIPTION DeviceDescription)
Definition: dma.c:455
Definition: haldma.h:312
BOOLEAN(NTAPI * PFLUSH_ADAPTER_BUFFERS)(_In_ PDMA_ADAPTER DmaAdapter, _In_ PMDL Mdl, _In_ PVOID MapRegisterBase, _In_ PVOID CurrentVa, _In_ ULONG Length, _In_ BOOLEAN WriteToDevice)
Definition: iotypes.h:2334
PVOID VirtualAddress
Definition: haldma.h:314
PHYSICAL_ADDRESS Address
Definition: iotypes.h:2173
#define B_16BITS
Definition: haldma.h:146
VOID NTAPI KeInitializeDeviceQueue(IN PKDEVICE_QUEUE DeviceQueue)
Definition: devqueue.c:22
VOID NTAPI KeAcquireSpinLock(PKSPIN_LOCK SpinLock, PKIRQL OldIrql)
Definition: spinlock.c:50
#define TypeA
Definition: nslookup.h:13
PDMA_ADAPTER NTAPI HalpGetDmaAdapter(IN PVOID Context, IN PDEVICE_DESCRIPTION DeviceDescription, OUT PULONG NumberOfMapRegisters)
Definition: dma.c:852
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:361
PDRIVER_CONTROL DeviceRoutine
Definition: iotypes.h:219
static const ULONG_PTR HalpEisaPortPage[8]
Definition: dma.c:93
PHYSICAL_ADDRESS NTAPI HalpGetAdapterMaximumPhysicalAddress(IN PADAPTER_OBJECT AdapterObject)
Definition: dma.c:235
UCHAR Byte
Definition: haldma.h:99
#define InsertTailList(ListHead, Entry)
if(dx==0 &&dy==0)
Definition: linetemp.h:174
ULONG MapRegisterCount
Definition: dma.c:980
static DMA_OPERATIONS HalpDmaOperations
Definition: dma.c:138
#define MmGetSystemAddressForMdlSafe(_Mdl, _Priority)
LONG NTAPI KeSetEvent(IN PKEVENT Event, IN KPRIORITY Increment, IN BOOLEAN Wait)
Definition: eventobj.c:159
NTSTATUS NTAPI KeWaitForSingleObject(IN PVOID Object, IN KWAIT_REASON WaitReason, IN KPROCESSOR_MODE WaitMode, IN BOOLEAN Alertable, IN PLARGE_INTEGER Timeout OPTIONAL)
Definition: wait.c:416
#define BURST_TIMING
Definition: haldma.h:152
_In_ WDFDMATRANSACTION _Out_opt_ ULONG * MapRegisterCount
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
VOID NTAPI IoFreeMapRegisters(IN PADAPTER_OBJECT AdapterObject, IN PVOID MapRegisterBase, IN ULONG NumberOfMapRegisters)
Definition: dma.c:114
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
VOID(NTAPI * PFREE_ADAPTER_CHANNEL)(_In_ PDMA_ADAPTER DmaAdapter)
Definition: iotypes.h:2343
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
static KEVENT HalpDmaLock
Definition: dma.c:83
uint32_t ULONG_PTR
Definition: typedefs.h:65
FORCEINLINE BOOLEAN RemoveEntryList(_In_ PLIST_ENTRY Entry)
Definition: rtlfuncs.h:105
VOID NTAPI HalPutScatterGatherList(IN PADAPTER_OBJECT AdapterObject, IN PSCATTER_GATHER_LIST ScatterGather, IN BOOLEAN WriteToDevice)
Definition: dma.c:1123
struct _SCATTER_GATHER_CONTEXT SCATTER_GATHER_CONTEXT
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define __WARNING_DEREF_NULL_PTR
Definition: suppress.h:32
ULONG * PPFN_NUMBER
Definition: ke.h:9
struct _ADAPTER_OBJECT ADAPTER_OBJECT
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
ULONG(NTAPI * PGET_DMA_ALIGNMENT)(_In_ PDMA_ADAPTER DmaAdapter)
Definition: iotypes.h:2362
return STATUS_NOT_IMPLEMENTED
NTSTATUS(NTAPI * PALLOCATE_ADAPTER_CHANNEL)(_In_ PDMA_ADAPTER DmaAdapter, _In_ PDEVICE_OBJECT DeviceObject, _In_ ULONG NumberOfMapRegisters, _In_ PDRIVER_CONTROL ExecutionRoutine, _In_ PVOID Context)
Definition: iotypes.h:2326
struct _ROS_MAP_REGISTER_ENTRY * PROS_MAP_REGISTER_ENTRY
UCHAR SingleMask
Definition: haldma.h:200
_Must_inspect_result_ _In_ PWDFDEVICE_INIT _In_ PCUNICODE_STRING DeviceDescription
Definition: wdfpdo.h:430
PVOID NTAPI HalAllocateCrashDumpRegisters(IN PADAPTER_OBJECT AdapterObject, IN OUT PULONG NumberOfMapRegisters)
Definition: dma.c:180
ULONG PFN_NUMBER
Definition: ke.h:9
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
#define FALSE
Definition: types.h:117
#define TYPE_A_TIMING
Definition: haldma.h:150
NTSTATUS NTAPI HalAllocateAdapterChannel(IN PADAPTER_OBJECT AdapterObject, IN PWAIT_CONTEXT_BLOCK WaitContextBlock, IN ULONG NumberOfMapRegisters, IN PDRIVER_CONTROL ExecutionRoutine)
Definition: dma.c:88
_In_ PIRP Irp
Definition: csq.h:116
ULONG HalpBusType
Definition: pcibus.c:18
UCHAR Channel
Definition: haldma.h:93
PMAP_TRANSFER MapTransfer
Definition: iotypes.h:2641
ULONG NTAPI HalpDmaGetDmaAlignment(IN PADAPTER_OBJECT AdapterObject)
Definition: dma.c:1316
#define FILE_READ_DATA
Definition: nt_native.h:628
NTSYSAPI void WINAPI RtlSetAllBits(PRTL_BITMAP)
FORCEINLINE VOID KeInitializeSpinLock(_Out_ PKSPIN_LOCK SpinLock)
Definition: kefuncs.h:238
unsigned char BOOLEAN
static WCHAR Address[46]
Definition: ping.c:68
static KSPIN_LOCK HalpDmaAdapterListLock
Definition: dma.c:84
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:426
NTSYSAPI ULONG WINAPI RtlFindClearBitsAndSet(PRTL_BITMAP, ULONG, ULONG)
FORCEINLINE PLIST_ENTRY RemoveHeadList(_Inout_ PLIST_ENTRY ListHead)
Definition: rtlfuncs.h:128
VOID HalpInitDma(VOID)
Definition: dma.c:185
UCHAR ClearBytePointer
Definition: haldma.h:219
_Must_inspect_result_ _In_ WDFDMATRANSACTION _In_ PFN_WDF_PROGRAM_DMA _In_ WDF_DMA_DIRECTION _In_ PMDL _In_ PVOID VirtualAddress
void * PVOID
Definition: retypes.h:9
struct _SCATTER_GATHER_LIST SCATTER_GATHER_LIST
Definition: iotypes.h:2204
#define COMPATIBLE_TIMING
Definition: haldma.h:149
#define READ_TRANSFER
Definition: haldma.h:165
#define FILE_WRITE_DATA
Definition: nt_native.h:631
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
#define ULL(a, b)
Definition: format_msg.c:27
#define UlongToPtr(u)
Definition: config.h:106
VOID NTAPI IoFreeAdapterChannel(IN PADAPTER_OBJECT AdapterObject)
Definition: dma.c:103
NTSTATUS NTAPI ObCreateObject(IN KPROCESSOR_MODE ProbeMode OPTIONAL, IN POBJECT_TYPE Type, IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, IN KPROCESSOR_MODE AccessMode, IN OUT PVOID ParseContext OPTIONAL, IN ULONG ObjectSize, IN ULONG PagedPoolCharge OPTIONAL, IN ULONG NonPagedPoolCharge OPTIONAL, OUT PVOID *Object)
Definition: oblife.c:951
PFLUSH_ADAPTER_BUFFERS FlushAdapterBuffers
Definition: iotypes.h:2638
KIRQL FASTCALL KfRaiseIrql(IN KIRQL NewIrql)
Definition: pic.c:187
Status
Definition: gdiplustypes.h:24
NTSTATUS NTAPI HalGetScatterGatherList(IN PADAPTER_OBJECT AdapterObject, IN PDEVICE_OBJECT DeviceObject, IN PMDL Mdl, IN PVOID CurrentVa, IN ULONG Length, IN PDRIVER_LIST_CONTROL ExecutionRoutine, IN PVOID Context, IN BOOLEAN WriteToDevice)
Definition: dma.c:1082
PHYSICAL_ADDRESS(NTAPI * PMAP_TRANSFER)(_In_ PDMA_ADAPTER DmaAdapter, _In_ PMDL Mdl, _In_ PVOID MapRegisterBase, _In_ PVOID CurrentVa, _Inout_ PULONG Length, _In_ BOOLEAN WriteToDevice)
Definition: iotypes.h:2353
int Count
Definition: noreturn.cpp:7
PADAPTER_OBJECT AdapterObject
Definition: dma.c:974
#define ExInitializeWorkItem(Item, Routine, Context)
Definition: exfuncs.h:265
NTSTATUS NTAPI IoAllocateAdapterChannel(IN PADAPTER_OBJECT AdapterObject, IN PDEVICE_OBJECT DeviceObject, IN ULONG NumberOfMapRegisters, IN PDRIVER_CONTROL ExecutionRoutine, IN PVOID Context)
Definition: adapter.c:30
NTSTATUS(NTAPI * PCALCULATE_SCATTER_GATHER_LIST_SIZE)(_In_ PDMA_ADAPTER DmaAdapter, _In_ PMDL Mdl OPTIONAL, _In_ PVOID CurrentVa, _In_ ULONG Length, _Out_ PULONG ScatterGatherListSize, _Out_ OPTIONAL PULONG pNumberOfMapRegisters)
Definition: iotypes.h:2397
#define SINGLE_REQUEST_MODE
Definition: haldma.h:170
_In_ WDFDMATRANSACTION _In_ size_t MaximumLength
PFREE_ADAPTER_CHANNEL FreeAdapterChannel
Definition: iotypes.h:2639
#define ASSERT(a)
Definition: mode.c:44
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
_In_ WDFCOLLECTION _In_ ULONG Index
VOID NTAPI HalpGrowMapBufferWorker(IN PVOID DeferredContext)
Definition: dma.c:1402
#define ObDereferenceObject
Definition: obfuncs.h:203
#define CASCADE_REQUEST_MODE
Definition: haldma.h:172
BOOLEAN NTAPI KeInsertDeviceQueue(IN PKDEVICE_QUEUE DeviceQueue, IN PKDEVICE_QUEUE_ENTRY DeviceQueueEntry)
Definition: devqueue.c:41
VOID NTAPI RtlClearBit(_In_ PRTL_BITMAP BitMapHeader, _In_ BITMAP_INDEX BitNumber)
Definition: bitmap.c:294
#define for
Definition: utility.h:88
BOOLEAN NTAPI IoFlushAdapterBuffers(IN PADAPTER_OBJECT AdapterObject, IN PMDL Mdl, IN PVOID MapRegisterBase, IN PVOID CurrentVa, IN ULONG Length, IN BOOLEAN WriteToDevice)
Definition: dma.c:127
BOOLEAN UsingUserBuffer
Definition: dma.c:973
DMA2_ADDRESS_COUNT DmaAddressCount[4]
Definition: haldma.h:210
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define BYTES_TO_PAGES(Size)
_Must_inspect_result_ typedef _In_ PHYSICAL_ADDRESS PhysicalAddress
Definition: iotypes.h:1098
unsigned char UCHAR
Definition: xmlstorage.h:181
UCHAR TransferType
Definition: haldma.h:94
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:790
UCHAR DmaBaseCount
Definition: haldma.h:191
#define WRITE_PORT_UCHAR(p, d)
Definition: pc98vid.h:21
POBJECT_TYPE IoAdapterObjectType
Definition: adapter.c:18
PHYSICAL_ADDRESS PhysicalAddress
Definition: haldma.h:315
NTSTATUS NTAPI HalBuildMdlFromScatterGatherList(IN PDMA_ADAPTER DmaAdapter, IN PSCATTER_GATHER_LIST ScatterGather, IN PMDL OriginalMdl, OUT PMDL *TargetMdl)
Definition: dma.c:1295
UCHAR ChannelNumber
Definition: haldma.h:133
#define OBJ_PERMANENT
Definition: winternl.h:226
_Out_ PNDIS_HANDLE _Out_ PUINT _In_ PNDIS_STRING _In_ NDIS_PHYSICAL_ADDRESS HighestAcceptableAddress
Definition: ndis.h:3227
ULONG LowPart
Definition: typedefs.h:106
VOID(NTAPI * PFREE_COMMON_BUFFER)(_In_ PDMA_ADAPTER DmaAdapter, _In_ ULONG Length, _In_ PHYSICAL_ADDRESS LogicalAddress, _In_ PVOID VirtualAddress, _In_ BOOLEAN CacheEnabled)
Definition: iotypes.h:2318
#define PAGE_SIZE
Definition: env_spec_w32.h:49
Definition: typedefs.h:119
static PADAPTER_OBJECT HalpMasterAdapter
Definition: dma.c:90
#define B_8BITS
Definition: haldma.h:143
#define TAG_DMA
Definition: dma.c:160
_Must_inspect_result_ _In_ PHYSICAL_ADDRESS LowestAcceptableAddress
Definition: mmfuncs.h:214
VOID(NTAPI * PPUT_DMA_ADAPTER)(PDMA_ADAPTER DmaAdapter)
Definition: iotypes.h:2307
WAIT_CONTEXT_BLOCK Wcb
Definition: dma.c:982
static LIST_ENTRY HalpDmaAdapterList
Definition: dma.c:85
#define TYPE_B_TIMING
Definition: haldma.h:151
struct _DMA_OPERATIONS DMA_OPERATIONS
VOID NTAPI HalPutDmaAdapter(IN PADAPTER_OBJECT AdapterObject)
Definition: dma.c:35
_In_ PSCSI_REQUEST_BLOCK _In_opt_ PVOID _In_ ULONG _In_ BOOLEAN WriteToDevice
Definition: cdrom.h:989
#define MAXULONG
Definition: typedefs.h:251
#define DISPATCH_LEVEL
Definition: env_spec_w32.h:696
NTSYSAPI void WINAPI RtlClearBits(PRTL_BITMAP, ULONG, ULONG)
PVOID MapRegisterBase
Definition: dma.c:979
NTSTATUS(NTAPI * PBUILD_MDL_FROM_SCATTER_GATHER_LIST)(_In_ PDMA_ADAPTER DmaAdapter, _In_ PSCATTER_GATHER_LIST ScatterGather, _In_ PMDL OriginalMdl, _Out_ PMDL *TargetMdl)
Definition: iotypes.h:2419
UCHAR RequestMode
Definition: haldma.h:97
VOID FASTCALL KfLowerIrql(IN KIRQL NewIrql)
Definition: pic.c:232
_Inout_ struct _IRP _In_ PVOID MapRegisterBase
Definition: iotypes.h:212
NTSTATUS NTAPI ObInsertObject(IN PVOID Object, IN PACCESS_STATE AccessState OPTIONAL, IN ACCESS_MASK DesiredAccess, IN ULONG ObjectPointerBias, OUT PVOID *NewObject OPTIONAL, OUT PHANDLE Handle)
Definition: obhandle.c:2934
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
NTSTATUS(NTAPI * PBUILD_SCATTER_GATHER_LIST)(_In_ PDMA_ADAPTER DmaAdapter, _In_ PDEVICE_OBJECT DeviceObject, _In_ PMDL Mdl, _In_ PVOID CurrentVa, _In_ ULONG Length, _In_ PDRIVER_LIST_CONTROL ExecutionRoutine, _In_ PVOID Context, _In_ BOOLEAN WriteToDevice, _In_ PVOID ScatterGatherBuffer, _In_ ULONG ScatterGatherLength)
Definition: iotypes.h:2406
PALLOCATE_ADAPTER_CHANNEL AllocateAdapterChannel
Definition: iotypes.h:2637
#define MAX_MAP_REGISTERS
Definition: dma.c:158
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
UCHAR TransferSize
Definition: haldma.h:134
Definition: ketypes.h:566
unsigned short USHORT
Definition: pedump.c:61
#define MAP_BASE_SW_SG
Definition: haldma.h:367
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
DRIVER_LIST_CONTROL * PDRIVER_LIST_CONTROL
Definition: iotypes.h:2377
ULONG(NTAPI * PREAD_DMA_COUNTER)(_In_ PDMA_ADAPTER DmaAdapter)
Definition: iotypes.h:2366
ULONG KSPIN_LOCK
Definition: env_spec_w32.h:72
PKDEVICE_QUEUE_ENTRY NTAPI KeRemoveDeviceQueue(IN PKDEVICE_QUEUE DeviceQueue)
Definition: devqueue.c:153
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
NTSYSAPI void WINAPI RtlSetBits(PRTL_BITMAP, ULONG, ULONG)
unsigned int * PULONG
Definition: retypes.h:1
_In_ struct _IRP _In_ struct _SCATTER_GATHER_LIST * ScatterGather
Definition: iotypes.h:2375
#define NULL
Definition: types.h:112
VOID(NTAPI * PFREE_MAP_REGISTERS)(_In_ PDMA_ADAPTER DmaAdapter, PVOID MapRegisterBase, ULONG NumberOfMapRegisters)
Definition: iotypes.h:2347
#define PAGE_ROUND_UP(x)
Definition: mmtypes.h:38
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
BOOLEAN NTAPI HalpGrowMapBuffers(IN PADAPTER_OBJECT AdapterObject, IN ULONG SizeOfMapBuffers)
Definition: dma.c:271
_In_ WDFDEVICE _In_ PVOID _In_opt_ PMDL Mdl
#define DPRINT1
Definition: precomp.h:8
BOOLEAN NTAPI HalFlushCommonBuffer(IN PADAPTER_OBJECT AdapterObject, IN ULONG Length, IN PHYSICAL_ADDRESS LogicalAddress, IN PVOID VirtualAddress)
Definition: dma.c:165
static LARGE_INTEGER Counter
Definition: clock.c:43
#define DEVICE_DESCRIPTION_VERSION2
Definition: iotypes.h:2065
VOID NTAPI MmFreeContiguousMemorySpecifyCache(IN PVOID BaseAddress, IN SIZE_T NumberOfBytes, IN MEMORY_CACHING_TYPE CacheType)
Definition: contmem.c:666
_In_ HANDLE Handle
Definition: extypes.h:390
struct tagContext Context
Definition: acpixf.h:1034
#define OUT
Definition: typedefs.h:40
#define ObReferenceObject
Definition: obfuncs.h:204
_In_ PDEVICE_OBJECT _In_ ULONG _In_ PDRIVER_CONTROL ExecutionRoutine
Definition: iofuncs.h:1397
struct _LARGE_INTEGER::@2237 u
PVOID AdapterListControlContext
Definition: dma.c:979
struct _SCATTER_GATHER_LIST * PSCATTER_GATHER_LIST
Definition: iotypes.h:2204
unsigned int ULONG
Definition: retypes.h:1
#define UNIMPLEMENTED
Definition: debug.h:115
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define ULONG_PTR
Definition: config.h:101
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
PHYSICAL_ADDRESS NTAPI MmGetPhysicalAddress(IN PVOID Address)
Definition: stubs.c:685
DRIVER_CONTROL * PDRIVER_CONTROL
Definition: iotypes.h:215
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
UCHAR Mode
Definition: haldma.h:201
IO_ALLOCATION_ACTION NTAPI HalpScatterGatherAdapterControl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID MapRegisterBase, IN PVOID Context)
Definition: dma.c:988
#define DMA_SETMASK
Definition: haldma.h:174
#define STATUS_SUCCESS
Definition: shellext.h:65
_Must_inspect_result_ _In_ PWDF_WORKITEM_CONFIG _In_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFWORKITEM * WorkItem
Definition: wdfworkitem.h:110
#define DPRINT
Definition: sndvol32.h:71
_Inout_ PKDEVICE_QUEUE_ENTRY DeviceQueueEntry
Definition: kefuncs.h:339
#define DEVICE_DESCRIPTION_VERSION1
Definition: iotypes.h:2064
#define UNIMPLEMENTED_ONCE
Definition: typedefs.h:30
PVOID NTAPI HalAllocateCommonBuffer(IN PADAPTER_OBJECT AdapterObject, IN ULONG Length, IN PPHYSICAL_ADDRESS LogicalAddress, IN BOOLEAN CacheEnabled)
Definition: dma.c:46
#define DMA_CLEARMASK
Definition: haldma.h:175
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
struct _GROW_WORK_ITEM * PGROW_WORK_ITEM
static CODE_SEG("PAGE")
Definition: isapnp.c:1482
static BOOLEAN HalpEisaDma
Definition: dma.c:88
#define DEMAND_REQUEST_MODE
Definition: haldma.h:169
UCHAR ClearBytePointer
Definition: haldma.h:202
#define BYTE_OFFSET(Va)
VOID NTAPI KeBugCheckEx(_In_ ULONG BugCheckCode, _In_ ULONG_PTR BugCheckParameter1, _In_ ULONG_PTR BugCheckParameter2, _In_ ULONG_PTR BugCheckParameter3, _In_ ULONG_PTR BugCheckParameter4)
Definition: rtlcompat.c:108
VOID NTAPI HalFreeCommonBuffer(IN PADAPTER_OBJECT AdapterObject, IN ULONG Length, IN PHYSICAL_ADDRESS LogicalAddress, IN PVOID VirtualAddress, IN BOOLEAN CacheEnabled)
Definition: dma.c:61
#define MACHINE_TYPE_EISA
Definition: ketypes.h:53
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
NTSTATUS(NTAPI * PGET_SCATTER_GATHER_LIST)(_In_ PDMA_ADAPTER DmaAdapter, _In_ PDEVICE_OBJECT DeviceObject, _In_ PMDL Mdl, _In_ PVOID CurrentVa, _In_ ULONG Length, _In_ PDRIVER_LIST_CONTROL ExecutionRoutine, _In_ PVOID Context, _In_ BOOLEAN WriteToDevice)
Definition: iotypes.h:2380
struct _SCATTER_GATHER_CONTEXT * PSCATTER_GATHER_CONTEXT
LONGLONG QuadPart
Definition: typedefs.h:114
ULONG Counter
Definition: haldma.h:316
IN PDCB IN PCCB IN VBO IN OUT PULONG OUT PDIRENT OUT PBCB OUT PVBO ByteOffset
Definition: fatprocs.h:725
ULONG NumberOfMapRegisters
Definition: iotypes.h:221
PADAPTER_OBJECT NTAPI HalGetAdapter(IN PDEVICE_DESCRIPTION DeviceDescription, OUT PULONG NumberOfMapRegisters)
Definition: dma.c:22
NTSTATUS NTAPI HalBuildScatterGatherList(IN PADAPTER_OBJECT AdapterObject, IN PDEVICE_OBJECT DeviceObject, IN PMDL Mdl, IN PVOID CurrentVa, IN ULONG Length, IN PDRIVER_LIST_CONTROL ExecutionRoutine, IN PVOID Context, IN BOOLEAN WriteToDevice, IN PVOID ScatterGatherBuffer, IN ULONG ScatterGatherLength)
Definition: dma.c:1215
#define _PRAGMA_WARNING_SUPPRESS(x)
Definition: suppress.h:28
BOOLEAN WriteToDevice
Definition: dma.c:981
PVOID NTAPI MmAllocateContiguousMemorySpecifyCache(IN SIZE_T NumberOfBytes, IN PHYSICAL_ADDRESS LowestAcceptableAddress OPTIONAL, IN PHYSICAL_ADDRESS HighestAcceptableAddress, IN PHYSICAL_ADDRESS BoundaryAddressMultiple OPTIONAL, IN MEMORY_CACHING_TYPE CacheType OPTIONAL)
Definition: contmem.c:574
UCHAR TimingMode
Definition: haldma.h:135
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68
NTSTATUS NTAPI HalCalculateScatterGatherListSize(IN PADAPTER_OBJECT AdapterObject, IN PMDL Mdl OPTIONAL, IN PVOID CurrentVa, IN ULONG Length, OUT PULONG ScatterGatherListSize, OUT PULONG pNumberOfMapRegisters)
Definition: dma.c:1157
_In_opt_ PVOID DeferredContext
Definition: ketypes.h:675