ReactOS 0.4.17-dev-116-ga4b6fe9
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#ifndef _MINIHAL_
85#endif
87#ifndef _MINIHAL_
89#endif
90
91static const ULONG_PTR HalpEisaPortPage[8] = {
92 FIELD_OFFSET(DMA_PAGE, Channel0),
93 FIELD_OFFSET(DMA_PAGE, Channel1),
94 FIELD_OFFSET(DMA_PAGE, Channel2),
95 FIELD_OFFSET(DMA_PAGE, Channel3),
96 0,
97 FIELD_OFFSET(DMA_PAGE, Channel5),
98 FIELD_OFFSET(DMA_PAGE, Channel6),
99 FIELD_OFFSET(DMA_PAGE, Channel7)
100};
101
102#ifndef _MINIHAL_
104NTAPI
106 IN PADAPTER_OBJECT AdapterObject,
108 IN PVOID CurrentVa,
110 OUT PULONG ScatterGatherListSize,
111 OUT PULONG pNumberOfMapRegisters);
112
114NTAPI
116 IN PADAPTER_OBJECT AdapterObject,
118 IN PMDL Mdl,
119 IN PVOID CurrentVa,
124 IN PVOID ScatterGatherBuffer,
125 IN ULONG ScatterGatherLength);
126
128NTAPI
130 IN PDMA_ADAPTER DmaAdapter,
132 IN PMDL OriginalMdl,
134
135
137 sizeof(DMA_OPERATIONS),
141 NULL, /* Initialized in HalpInitDma() */
142 NULL, /* Initialized in HalpInitDma() */
143 NULL, /* Initialized in HalpInitDma() */
144 NULL, /* Initialized in HalpInitDma() */
145 NULL, /* Initialized in HalpInitDma() */
153};
154#endif
155
156#define MAX_MAP_REGISTERS 64
157
158#define TAG_DMA ' AMD'
159
160/* FUNCTIONS *****************************************************************/
161
162#if defined(SARCH_PC98)
163/*
164 * Disable I/O for safety.
165 * FIXME: Add support for PC-98 DMA controllers.
166 */
167#undef WRITE_PORT_UCHAR
168#undef READ_PORT_UCHAR
169
170#define WRITE_PORT_UCHAR(Port, Data) \
171 do { \
172 UNIMPLEMENTED; \
173 (Port); \
174 (Data); \
175 } while (0)
176
177#define READ_PORT_UCHAR(Port) 0x00
178#endif
179
180#ifndef _MINIHAL_
181CODE_SEG("INIT")
182VOID
184{
185 /*
186 * Initialize the DMA Operation table
187 */
193
195 {
196 /*
197 * Check if Extended DMA is available. We're just going to do a random
198 * read and write.
199 */
200 WRITE_PORT_UCHAR(UlongToPtr(FIELD_OFFSET(EISA_CONTROL, DmaController2Pages.Channel2)), 0x2A);
201 if (READ_PORT_UCHAR(UlongToPtr(FIELD_OFFSET(EISA_CONTROL, DmaController2Pages.Channel2))) == 0x2A)
202 {
203 DPRINT1("Machine supports EISA DMA. Bus type: %lu\n", HalpBusType);
205 }
206 }
207
208 /*
209 * Intialize all the global variables and allocate master adapter with
210 * first map buffers.
211 */
216
217 /*
218 * Setup the HalDispatchTable callback for creating PnP DMA adapters. It's
219 * used by IoGetDmaAdapter in the kernel.
220 */
222}
223#endif
224
232NTAPI
234{
235 PHYSICAL_ADDRESS HighestAddress;
236
237 if (AdapterObject->MasterDevice)
238 {
239 if (AdapterObject->Dma64BitAddresses)
240 {
241 HighestAddress.QuadPart = 0xFFFFFFFFFFFFFFFFULL;
242 return HighestAddress;
243 }
244 else if (AdapterObject->Dma32BitAddresses)
245 {
246 HighestAddress.QuadPart = 0xFFFFFFFF;
247 return HighestAddress;
248 }
249 }
250
251 HighestAddress.QuadPart = 0xFFFFFF;
252 return HighestAddress;
253}
254
255#ifndef _MINIHAL_
268NTAPI
270 IN ULONG SizeOfMapBuffers)
271{
276 PHYSICAL_ADDRESS BoundryAddressMultiple;
279
280 /* Check if enough map register slots are available. */
281 MapRegisterCount = BYTES_TO_PAGES(SizeOfMapBuffers);
282 if (MapRegisterCount + AdapterObject->NumberOfMapRegisters > MAX_MAP_REGISTERS)
283 {
284 DPRINT("No more map register slots available! (Current: %d | Requested: %d | Limit: %d)\n",
285 AdapterObject->NumberOfMapRegisters,
288 return FALSE;
289 }
290
291 /*
292 * Allocate memory for the new map registers. For 32-bit adapters we use
293 * two passes in order not to waste scare resource (low memory).
294 */
297 LowestAcceptableAddress.LowPart = HighestAcceptableAddress.LowPart == 0xFFFFFFFF ? 0x1000000 : 0;
298 BoundryAddressMultiple.QuadPart = 0;
299
303 BoundryAddressMultiple,
306 {
311 BoundryAddressMultiple,
313 }
314
315 if (!VirtualAddress) return FALSE;
316
318
319 /*
320 * All the following must be done with the master adapter lock held
321 * to prevent corruption.
322 */
323 KeAcquireSpinLock(&AdapterObject->SpinLock, &OldIrql);
324
325 /*
326 * Setup map register entries for the buffer allocated. Each entry has
327 * a virtual and physical address and corresponds to PAGE_SIZE large
328 * buffer.
329 */
330 if (MapRegisterCount > 0)
331 {
332 PROS_MAP_REGISTER_ENTRY CurrentEntry, PreviousEntry;
333
334 CurrentEntry = AdapterObject->MapRegisterBase + AdapterObject->NumberOfMapRegisters;
335 do
336 {
337 /*
338 * Leave one entry free for every non-contiguous memory region
339 * in the map register bitmap. This ensures that we can search
340 * using RtlFindClearBits for contiguous map register regions.
341 *
342 * Also for non-EISA DMA leave one free entry for every 64Kb
343 * break, because the DMA controller can handle only coniguous
344 * 64Kb regions.
345 */
346 if (CurrentEntry != AdapterObject->MapRegisterBase)
347 {
348 PreviousEntry = CurrentEntry - 1;
349 if ((PreviousEntry->PhysicalAddress.LowPart + PAGE_SIZE) == PhysicalAddress.LowPart)
350 {
351 if (!HalpEisaDma)
352 {
353 if ((PreviousEntry->PhysicalAddress.LowPart ^ PhysicalAddress.LowPart) & 0xFFFF0000)
354 {
355 CurrentEntry++;
356 AdapterObject->NumberOfMapRegisters++;
357 }
358 }
359 }
360 else
361 {
362 CurrentEntry++;
363 AdapterObject->NumberOfMapRegisters++;
364 }
365 }
366
367 RtlClearBit(AdapterObject->MapRegisters,
368 (ULONG)(CurrentEntry - AdapterObject->MapRegisterBase));
369 CurrentEntry->VirtualAddress = VirtualAddress;
370 CurrentEntry->PhysicalAddress = PhysicalAddress;
371
374
375 CurrentEntry++;
376 AdapterObject->NumberOfMapRegisters++;
378 } while (MapRegisterCount);
379 }
380
381 KeReleaseSpinLock(&AdapterObject->SpinLock, OldIrql);
382
383 return TRUE;
384}
385
395NTAPI
397{
398 PADAPTER_OBJECT MasterAdapter;
399 ULONG Size, SizeOfBitmap;
400
401 SizeOfBitmap = MAX_MAP_REGISTERS;
402 Size = sizeof(ADAPTER_OBJECT);
403 Size += sizeof(RTL_BITMAP);
404 Size += (SizeOfBitmap + 7) >> 3;
405
407 if (!MasterAdapter) return NULL;
408
409 RtlZeroMemory(MasterAdapter, Size);
410
411 KeInitializeSpinLock(&MasterAdapter->SpinLock);
412 InitializeListHead(&MasterAdapter->AdapterQueue);
413
414 MasterAdapter->MapRegisters = (PVOID)(MasterAdapter + 1);
415 RtlInitializeBitMap(MasterAdapter->MapRegisters,
416 (PULONG)(MasterAdapter->MapRegisters + 1),
417 SizeOfBitmap);
418 RtlSetAllBits(MasterAdapter->MapRegisters);
419 MasterAdapter->NumberOfMapRegisters = 0;
420 MasterAdapter->CommittedMapRegisters = 0;
421
422 MasterAdapter->MapRegisterBase = ExAllocatePoolWithTag(NonPagedPool,
423 SizeOfBitmap *
425 TAG_DMA);
426 if (!MasterAdapter->MapRegisterBase)
427 {
428 ExFreePool(MasterAdapter);
429 return NULL;
430 }
431
432 RtlZeroMemory(MasterAdapter->MapRegisterBase,
433 SizeOfBitmap * sizeof(ROS_MAP_REGISTER_ENTRY));
434 if (!HalpGrowMapBuffers(MasterAdapter, 0x10000))
435 {
436 ExFreePool(MasterAdapter);
437 return NULL;
438 }
439
440 return MasterAdapter;
441}
442
452NTAPI
455{
456 PADAPTER_OBJECT AdapterObject;
460
462 NULL,
464 NULL,
465 NULL);
466
471 NULL,
472 sizeof(ADAPTER_OBJECT),
473 0,
474 0,
475 (PVOID)&AdapterObject);
476 if (!NT_SUCCESS(Status)) return NULL;
477
478 RtlZeroMemory(AdapterObject, sizeof(ADAPTER_OBJECT));
479
480 Status = ObInsertObject(AdapterObject,
481 NULL,
483 0,
484 NULL,
485 &Handle);
486 if (!NT_SUCCESS(Status)) return NULL;
487
488 ObReferenceObject(AdapterObject);
489
491
492 AdapterObject->DmaHeader.Version = (USHORT)DeviceDescription->Version;
493 AdapterObject->DmaHeader.Size = sizeof(ADAPTER_OBJECT);
494 AdapterObject->DmaHeader.DmaOperations = &HalpDmaOperations;
495 AdapterObject->MapRegistersPerChannel = 1;
496 AdapterObject->Dma32BitAddresses = DeviceDescription->Dma32BitAddresses;
497 AdapterObject->ChannelNumber = 0xFF;
498 AdapterObject->MasterAdapter = HalpMasterAdapter;
499 KeInitializeDeviceQueue(&AdapterObject->ChannelWaitQueue);
500
501 return AdapterObject;
502}
503#endif
504
511NTAPI
514{
515 UCHAR Controller;
516 DMA_MODE DmaMode = {{0 }};
517 DMA_EXTENDED_MODE ExtendedMode = {{ 0 }};
518 PVOID AdapterBaseVa;
519
520 Controller = (DeviceDescription->DmaChannel & 4) ? 2 : 1;
521
522 if (Controller == 1)
523 {
524 AdapterBaseVa = UlongToPtr(FIELD_OFFSET(EISA_CONTROL, DmaController1));
525 }
526 else
527 {
528 AdapterBaseVa = UlongToPtr(FIELD_OFFSET(EISA_CONTROL, DmaController2));
529 }
530
531 AdapterObject->AdapterNumber = Controller;
532 AdapterObject->ChannelNumber = (UCHAR)(DeviceDescription->DmaChannel & 3);
533 AdapterObject->PagePort = (PUCHAR)HalpEisaPortPage[DeviceDescription->DmaChannel];
534 AdapterObject->Width16Bits = FALSE;
535 AdapterObject->AdapterBaseVa = AdapterBaseVa;
536
538 {
539 ExtendedMode.ChannelNumber = AdapterObject->ChannelNumber;
540
541 switch (DeviceDescription->DmaSpeed)
542 {
543 case Compatible: ExtendedMode.TimingMode = COMPATIBLE_TIMING; break;
544 case TypeA: ExtendedMode.TimingMode = TYPE_A_TIMING; break;
545 case TypeB: ExtendedMode.TimingMode = TYPE_B_TIMING; break;
546 case TypeC: ExtendedMode.TimingMode = BURST_TIMING; break;
547 default:
548 return FALSE;
549 }
550
551 switch (DeviceDescription->DmaWidth)
552 {
553 case Width8Bits: ExtendedMode.TransferSize = B_8BITS; break;
554 case Width16Bits: ExtendedMode.TransferSize = B_16BITS; break;
555 case Width32Bits: ExtendedMode.TransferSize = B_32BITS; break;
556 default:
557 return FALSE;
558 }
559
560 if (Controller == 1)
561 {
563 ExtendedMode.Byte);
564 }
565 else
566 {
568 ExtendedMode.Byte);
569 }
570 }
571 else
572 {
573 /*
574 * Validate setup for non-busmaster DMA adapter. Secondary controller
575 * supports only 16-bit transfers and main controller supports only
576 * 8-bit transfers. Anything else is invalid.
577 */
578 if (!DeviceDescription->Master)
579 {
580 if ((Controller == 2) && (DeviceDescription->DmaWidth == Width16Bits))
581 {
582 AdapterObject->Width16Bits = TRUE;
583 }
584 else if ((Controller != 1) || (DeviceDescription->DmaWidth != Width8Bits))
585 {
586 return FALSE;
587 }
588 }
589 }
590
591 DmaMode.Channel = AdapterObject->ChannelNumber;
592 DmaMode.AutoInitialize = DeviceDescription->AutoInitialize;
593
594 /*
595 * Set the DMA request mode.
596 *
597 * For (E)ISA bus master devices just unmask (enable) the DMA channel
598 * and set it to cascade mode. Otherwise just select the right one
599 * bases on the passed device description.
600 */
601 if (DeviceDescription->Master)
602 {
604 if (Controller == 1)
605 {
606 /* Set the Request Data */
608 WRITE_PORT_UCHAR(&((PDMA1_CONTROL)AdapterBaseVa)->Mode, DmaMode.Byte);
609
610 /* Unmask DMA Channel */
611 WRITE_PORT_UCHAR(&((PDMA1_CONTROL)AdapterBaseVa)->SingleMask,
612 AdapterObject->ChannelNumber | DMA_CLEARMASK);
613 }
614 else
615 {
616 /* Set the Request Data */
617 WRITE_PORT_UCHAR(&((PDMA2_CONTROL)AdapterBaseVa)->Mode, DmaMode.Byte);
618
619 /* Unmask DMA Channel */
620 WRITE_PORT_UCHAR(&((PDMA2_CONTROL)AdapterBaseVa)->SingleMask,
621 AdapterObject->ChannelNumber | DMA_CLEARMASK);
622 }
623 }
624 else
625 {
626 if (DeviceDescription->DemandMode)
627 {
629 }
630 else
631 {
633 }
634 }
635
636 AdapterObject->AdapterMode = DmaMode;
637
638 return TRUE;
639}
640
641#ifndef _MINIHAL_
658NTAPI
661{
662 PADAPTER_OBJECT AdapterObject = NULL;
664 ULONG MapRegisters;
667
668 /* Validate parameters in device description */
670
671 /*
672 * See if we're going to use ISA/EISA DMA adapter. These adapters are
673 * special since they're reused.
674 *
675 * Also note that we check for channel number since there are only 8 DMA
676 * channels on ISA, so any request above this requires new adapter.
677 */
678 if (((DeviceDescription->InterfaceType == Eisa) ||
679 (DeviceDescription->InterfaceType == Isa)) || !(DeviceDescription->Master))
680 {
681 if (((DeviceDescription->InterfaceType == Isa) ||
682 (DeviceDescription->InterfaceType == Eisa)) &&
683 (DeviceDescription->DmaChannel >= 8))
684 {
686 }
687 else
688 {
690 }
691 }
692 else
693 {
695 }
696
697 /*
698 * Disallow creating adapter for ISA/EISA DMA channel 4 since it's used
699 * for cascading the controllers and it's not available for software use.
700 */
701 if ((EisaAdapter) && (DeviceDescription->DmaChannel == 4)) return NULL;
702
703 /*
704 * Calculate the number of map registers.
705 *
706 * - For EISA and PCI scatter/gather no map registers are needed.
707 * - For ISA slave scatter/gather one map register is needed.
708 * - For all other cases the number of map registers depends on
709 * DeviceDescription->MaximumLength.
710 */
711 MaximumLength = DeviceDescription->MaximumLength & MAXLONG;
712 if ((DeviceDescription->ScatterGather) &&
713 ((DeviceDescription->InterfaceType == Eisa) ||
714 (DeviceDescription->InterfaceType == PCIBus)))
715 {
716 MapRegisters = 0;
717 }
718 else if ((DeviceDescription->ScatterGather) && !(DeviceDescription->Master))
719 {
720 MapRegisters = 1;
721 }
722 else
723 {
724 /*
725 * In the equation below the additional map register added by
726 * the "+1" accounts for the case when a transfer does not start
727 * at a page-aligned address.
728 */
729 MapRegisters = BYTES_TO_PAGES(MaximumLength) + 1;
730 if (MapRegisters > 16) MapRegisters = 16;
731 }
732
733 /*
734 * Acquire the DMA lock that is used to protect the EISA adapter array.
735 */
737
738 /*
739 * Now we must get ahold of the adapter object. For first eight ISA/EISA
740 * channels there are static adapter objects that are reused and updated
741 * on succesive HalGetAdapter calls. In other cases a new adapter object
742 * is always created and it's to the DMA adapter list (HalpDmaAdapterList).
743 */
744 if (EisaAdapter)
745 {
746 AdapterObject = HalpEisaAdapter[DeviceDescription->DmaChannel];
747 if (AdapterObject)
748 {
749 if ((AdapterObject->NeedsMapRegisters) &&
750 (MapRegisters > AdapterObject->MapRegistersPerChannel))
751 {
752 AdapterObject->MapRegistersPerChannel = MapRegisters;
753 }
754 }
755 }
756
757 if (AdapterObject == NULL)
758 {
759 AdapterObject = HalpDmaAllocateChildAdapter(MapRegisters, DeviceDescription);
760 if (AdapterObject == NULL)
761 {
762 KeSetEvent(&HalpDmaLock, 0, 0);
763 return NULL;
764 }
765
766 if (EisaAdapter)
767 {
768 HalpEisaAdapter[DeviceDescription->DmaChannel] = AdapterObject;
769 }
770
771 if (MapRegisters > 0)
772 {
773 AdapterObject->NeedsMapRegisters = TRUE;
774 AdapterObject->MapRegistersPerChannel = MapRegisters;
775 }
776 else
777 {
778 AdapterObject->NeedsMapRegisters = FALSE;
779 if (DeviceDescription->Master)
780 {
781 AdapterObject->MapRegistersPerChannel = BYTES_TO_PAGES(MaximumLength) + 1;
782 }
783 else
784 {
785 AdapterObject->MapRegistersPerChannel = 1;
786 }
787 }
788 }
789
790 /*
791 * Release the DMA lock. HalpEisaAdapter will no longer be touched,
792 * so we don't need it.
793 */
794 KeSetEvent(&HalpDmaLock, 0, 0);
795
796 if (!EisaAdapter)
797 {
798 /* If it's not one of the static adapters, add it to the list */
800 InsertTailList(&HalpDmaAdapterList, &AdapterObject->AdapterList);
802 }
803
804 /*
805 * Setup the values in the adapter object that are common for all
806 * types of buses.
807 */
809 {
810 AdapterObject->IgnoreCount = DeviceDescription->IgnoreCount;
811 }
812 else
813 {
814 AdapterObject->IgnoreCount = 0;
815 }
816
817 AdapterObject->Dma32BitAddresses = DeviceDescription->Dma32BitAddresses;
818 AdapterObject->Dma64BitAddresses = DeviceDescription->Dma64BitAddresses;
819 AdapterObject->ScatterGather = DeviceDescription->ScatterGather;
820 AdapterObject->MasterDevice = DeviceDescription->Master;
821 *NumberOfMapRegisters = AdapterObject->MapRegistersPerChannel;
822
823 /*
824 * For non-(E)ISA adapters we have already done all the work. On the
825 * other hand for (E)ISA adapters we must still setup the DMA modes
826 * and prepare the controller.
827 */
828 if (EisaAdapter)
829 {
831 {
832 ObDereferenceObject(AdapterObject);
833 return NULL;
834 }
835 }
836
837 return AdapterObject;
838}
839
849NTAPI
853{
855}
856
865VOID
866NTAPI
868{
870 if (AdapterObject->ChannelNumber == 0xFF)
871 {
873 RemoveEntryList(&AdapterObject->AdapterList);
875 }
876
877 ObDereferenceObject(AdapterObject);
878}
879
905PVOID
906NTAPI
909 IN PPHYSICAL_ADDRESS LogicalAddress,
910 IN BOOLEAN CacheEnabled)
911{
914 PHYSICAL_ADDRESS BoundryAddressMultiple;
916
919 BoundryAddressMultiple.QuadPart = 0;
920
921 /*
922 * For bus-master DMA devices the buffer mustn't cross 4Gb boundary. For
923 * slave DMA devices the 64Kb boundary mustn't be crossed since the
924 * controller wouldn't be able to handle it.
925 */
926 if (AdapterObject->MasterDevice)
927 {
928 BoundryAddressMultiple.HighPart = 1;
929 }
930 else
931 {
932 BoundryAddressMultiple.LowPart = 0x10000;
933 }
934
938 BoundryAddressMultiple,
939 CacheEnabled ? MmCached :
941 if (VirtualAddress == NULL) return NULL;
942
943 *LogicalAddress = MmGetPhysicalAddress(VirtualAddress);
944
945 return VirtualAddress;
946}
947
957VOID
958NTAPI
961 IN PHYSICAL_ADDRESS LogicalAddress,
963 IN BOOLEAN CacheEnabled)
964{
966 Length,
967 CacheEnabled ? MmCached : MmNonCached);
968}
969
982
983// FIXME: This value needs to be calculated at runtime
984#define MAX_SG_ELEMENTS 0x30
985
987NTAPI
989 IN PIRP Irp,
992{
993 PSCATTER_GATHER_CONTEXT AdapterControlContext = Context;
994 PADAPTER_OBJECT AdapterObject = AdapterControlContext->AdapterObject;
995 PSCATTER_GATHER_LIST ScatterGatherList;
996 PSCATTER_GATHER_ELEMENT TempElements;
997 ULONG ElementCount = 0, RemainingLength = AdapterControlContext->Length;
998 PUCHAR CurrentVa = AdapterControlContext->CurrentVa;
999 // RemainingLength / PAGE_SIZE + 1 for the remainder of our division
1000 // + 1 for a safety cushion gives a good safe value. Using the
1001 // min function with MAX_SG_ELEMENTS keeps us from getting too large.
1002 ULONG Est_SG_Elements = min(RemainingLength / PAGE_SIZE + 2, MAX_SG_ELEMENTS);
1003
1004 /* Store the map register base for later in HalPutScatterGatherList */
1005 AdapterControlContext->MapRegisterBase = MapRegisterBase;
1006
1007 // FIXME: HACK Allocate TempElements from pool to minimize stack usage.
1008 // A more efficient algorithm should be found to avoid allocations during S/G I/O operations.
1010 sizeof(*TempElements) * Est_SG_Elements,
1011 TAG_DMA);
1012 if (!TempElements)
1013 {
1014 DPRINT1("Scatter/gather list construction failed!\n");
1015 return DeallocateObject;
1016 }
1017
1018 while (RemainingLength > 0 && ElementCount < MAX_SG_ELEMENTS)
1019 {
1020 TempElements[ElementCount].Length = RemainingLength;
1021 TempElements[ElementCount].Reserved = 0;
1022 TempElements[ElementCount].Address = IoMapTransfer(AdapterObject,
1023 AdapterControlContext->Mdl,
1025 CurrentVa + (AdapterControlContext->Length - RemainingLength),
1026 &TempElements[ElementCount].Length,
1027 AdapterControlContext->WriteToDevice);
1028 if (TempElements[ElementCount].Length == 0)
1029 break;
1030
1031 DPRINT("Allocated one S/G element: 0x%I64u with length: 0x%x\n",
1032 TempElements[ElementCount].Address.QuadPart,
1033 TempElements[ElementCount].Length);
1034
1035 ASSERT(TempElements[ElementCount].Length <= RemainingLength);
1036 RemainingLength -= TempElements[ElementCount].Length;
1037 ElementCount++;
1038 }
1039
1040 DPRINT("Est_SG_Elements %d\n", Est_SG_Elements);
1041 DPRINT("ElementCount is %d\n", ElementCount);
1042
1043 if (RemainingLength > 0)
1044 {
1045 DPRINT1("Scatter/gather list construction failed!\n");
1046 ExFreePoolWithTag(TempElements, TAG_DMA);
1047 return DeallocateObject;
1048 }
1049
1050 ScatterGatherList = ExAllocatePoolWithTag(NonPagedPool,
1051 sizeof(SCATTER_GATHER_LIST) + sizeof(SCATTER_GATHER_ELEMENT) * ElementCount,
1052 TAG_DMA);
1053 ASSERT(ScatterGatherList);
1054
1055 ScatterGatherList->NumberOfElements = ElementCount;
1056 ScatterGatherList->Reserved = (ULONG_PTR)AdapterControlContext;
1057 RtlCopyMemory(ScatterGatherList->Elements,
1058 TempElements,
1059 sizeof(SCATTER_GATHER_ELEMENT) * ElementCount);
1060
1061 ExFreePoolWithTag(TempElements, TAG_DMA);
1062
1063 DPRINT("Initiating S/G DMA with %d element(s)\n", ElementCount);
1064
1065 AdapterControlContext->AdapterListControlRoutine(DeviceObject,
1066 Irp,
1067 ScatterGatherList,
1068 AdapterControlContext->AdapterListControlContext);
1069
1071}
1072
1101 NTSTATUS
1102 NTAPI
1105 IN PMDL Mdl,
1106 IN PVOID CurrentVa,
1107 IN ULONG Length,
1111{
1112 return HalBuildScatterGatherList(AdapterObject,
1114 Mdl,
1115 CurrentVa,
1116 Length,
1118 Context,
1120 NULL,
1121 0);
1122}
1123
1142 VOID
1143 NTAPI
1147{
1148 PSCATTER_GATHER_CONTEXT AdapterControlContext = (PSCATTER_GATHER_CONTEXT)ScatterGather->Reserved;
1149 ULONG i;
1150
1151 for (i = 0; i < ScatterGather->NumberOfElements; i++)
1152 {
1153 IoFlushAdapterBuffers(AdapterObject,
1154 AdapterControlContext->Mdl,
1155 AdapterControlContext->MapRegisterBase,
1156 AdapterControlContext->CurrentVa,
1157 ScatterGather->Elements[i].Length,
1158 AdapterControlContext->WriteToDevice);
1159 AdapterControlContext->CurrentVa += ScatterGather->Elements[i].Length;
1160 }
1161
1162 IoFreeMapRegisters(AdapterObject,
1163 AdapterControlContext->MapRegisterBase,
1164 AdapterControlContext->MapRegisterCount);
1165
1166
1168
1169 /* If this is our buffer, release it */
1170 if (!AdapterControlContext->UsingUserBuffer)
1171 ExFreePoolWithTag(AdapterControlContext, TAG_DMA);
1172
1173 DPRINT("S/G DMA has finished!\n");
1174}
1175
1177NTAPI
1179 IN PADAPTER_OBJECT AdapterObject,
1181 IN PVOID CurrentVa,
1182 IN ULONG Length,
1183 OUT PULONG ScatterGatherListSize,
1184 OUT PULONG pNumberOfMapRegisters)
1185{
1187 ULONG SgSize;
1188
1190
1192 SgSize = sizeof(SCATTER_GATHER_CONTEXT);
1193
1194 *ScatterGatherListSize = SgSize;
1195 if (pNumberOfMapRegisters) *pNumberOfMapRegisters = NumberOfMapRegisters;
1196
1197 return STATUS_SUCCESS;
1198}
1199
1235NTAPI
1237 IN PADAPTER_OBJECT AdapterObject,
1239 IN PMDL Mdl,
1240 IN PVOID CurrentVa,
1241 IN ULONG Length,
1245 IN PVOID ScatterGatherBuffer,
1246 IN ULONG ScatterGatherBufferLength)
1247{
1250 PSCATTER_GATHER_CONTEXT ScatterGatherContext;
1251 BOOLEAN UsingUserBuffer;
1252
1254 Mdl,
1255 CurrentVa,
1256 Length,
1257 &SgSize,
1259 if (!NT_SUCCESS(Status)) return Status;
1260
1261 if (ScatterGatherBuffer)
1262 {
1263 /* Checking if user buffer is enough */
1264 if (ScatterGatherBufferLength < SgSize)
1265 {
1267 }
1268 UsingUserBuffer = TRUE;
1269 }
1270 else
1271 {
1272 ScatterGatherBuffer = ExAllocatePoolWithTag(NonPagedPool, SgSize, TAG_DMA);
1273 if (!ScatterGatherBuffer)
1274 {
1276 }
1277 UsingUserBuffer = FALSE;
1278 }
1279
1280 {
1281 ScatterGatherContext = (PSCATTER_GATHER_CONTEXT)ScatterGatherBuffer;
1282
1283 /* Fill the scatter-gather context */
1284 ScatterGatherContext->UsingUserBuffer = UsingUserBuffer;
1285 ScatterGatherContext->AdapterObject = AdapterObject;
1286 ScatterGatherContext->Mdl = Mdl;
1287 ScatterGatherContext->CurrentVa = CurrentVa;
1288 ScatterGatherContext->Length = Length;
1289 ScatterGatherContext->MapRegisterCount = NumberOfMapRegisters;
1290 ScatterGatherContext->AdapterListControlRoutine = ExecutionRoutine;
1291 ScatterGatherContext->AdapterListControlContext = Context;
1292 ScatterGatherContext->WriteToDevice = WriteToDevice;
1293
1294 ScatterGatherContext->Wcb.DeviceObject = DeviceObject;
1295 ScatterGatherContext->Wcb.DeviceContext = (PVOID)ScatterGatherContext;
1296 ScatterGatherContext->Wcb.CurrentIrp = DeviceObject->CurrentIrp;
1297
1298 Status = HalAllocateAdapterChannel(AdapterObject,
1299 &ScatterGatherContext->Wcb,
1302
1303 if (!NT_SUCCESS(Status))
1304 {
1305 if (!UsingUserBuffer)
1306 ExFreePoolWithTag(ScatterGatherBuffer, TAG_DMA);
1307 return Status;
1308 }
1309 }
1310
1311 return STATUS_SUCCESS;
1312}
1313
1315NTAPI
1317 IN PDMA_ADAPTER DmaAdapter,
1319 IN PMDL OriginalMdl,
1321{
1324}
1325#endif
1326
1335ULONG
1336NTAPI
1338{
1339 return 1;
1340}
1341
1342/*
1343 * @name HalReadDmaCounter
1344 *
1345 * Read DMA operation progress counter.
1346 *
1347 * @implemented
1348 */
1349ULONG
1350NTAPI
1352{
1353 KIRQL OldIrql;
1354 ULONG Count, OldCount;
1355
1356 ASSERT(!AdapterObject->MasterDevice);
1357
1358 /*
1359 * Acquire the master adapter lock since we're going to mess with the
1360 * system DMA controller registers and we really don't want anyone
1361 * to do the same at the same time.
1362 */
1363 KeAcquireSpinLock(&AdapterObject->MasterAdapter->SpinLock, &OldIrql);
1364
1365 /* Send the request to the specific controller. */
1366 if (AdapterObject->AdapterNumber == 1)
1367 {
1368 PDMA1_CONTROL DmaControl1 = AdapterObject->AdapterBaseVa;
1369
1370 Count = 0xffff00;
1371 do
1372 {
1373 OldCount = Count;
1374
1375 /* Send Reset */
1376 WRITE_PORT_UCHAR(&DmaControl1->ClearBytePointer, 0);
1377
1378 /* Read Count */
1379 Count = READ_PORT_UCHAR(&DmaControl1->DmaAddressCount
1380 [AdapterObject->ChannelNumber].DmaBaseCount);
1381 Count |= READ_PORT_UCHAR(&DmaControl1->DmaAddressCount
1382 [AdapterObject->ChannelNumber].DmaBaseCount) << 8;
1383 } while (0xffff00 & (OldCount ^ Count));
1384 }
1385 else
1386 {
1387 PDMA2_CONTROL DmaControl2 = AdapterObject->AdapterBaseVa;
1388
1389 Count = 0xffff00;
1390 do
1391 {
1392 OldCount = Count;
1393
1394 /* Send Reset */
1395 WRITE_PORT_UCHAR(&DmaControl2->ClearBytePointer, 0);
1396
1397 /* Read Count */
1398 Count = READ_PORT_UCHAR(&DmaControl2->DmaAddressCount
1399 [AdapterObject->ChannelNumber].DmaBaseCount);
1400 Count |= READ_PORT_UCHAR(&DmaControl2->DmaAddressCount
1401 [AdapterObject->ChannelNumber].DmaBaseCount) << 8;
1402 } while (0xffff00 & (OldCount ^ Count));
1403 }
1404
1405 KeReleaseSpinLock(&AdapterObject->MasterAdapter->SpinLock, OldIrql);
1406
1407 Count++;
1408 Count &= 0xffff;
1409 if (AdapterObject->Width16Bits) Count *= 2;
1410
1411 return Count;
1412}
1413
1414#ifndef _MINIHAL_
1421VOID
1422NTAPI
1424{
1426 KIRQL OldIrql;
1427 BOOLEAN Succeeded;
1428
1429 /*
1430 * Try to allocate new map registers for the adapter.
1431 *
1432 * NOTE: The NT implementation actually tries to allocate more map
1433 * registers than needed as an optimization.
1434 */
1436 Succeeded = HalpGrowMapBuffers(WorkItem->AdapterObject->MasterAdapter,
1437 WorkItem->NumberOfMapRegisters << PAGE_SHIFT);
1438 KeSetEvent(&HalpDmaLock, 0, 0);
1439
1440 if (Succeeded)
1441 {
1442 /*
1443 * Flush the adapter queue now that new map registers are ready. The
1444 * easiest way to do that is to call IoFreeMapRegisters to not free
1445 * any registers. Note that we use the magic (PVOID)2 map register
1446 * base to bypass the parameter checking.
1447 */
1449 IoFreeMapRegisters(WorkItem->AdapterObject, (PVOID)2, 0);
1451 }
1452
1454}
1455
1481NTAPI
1483 IN PWAIT_CONTEXT_BLOCK WaitContextBlock,
1486{
1487 PADAPTER_OBJECT MasterAdapter;
1490 ULONG Result;
1491 KIRQL OldIrql;
1492
1494
1495 /* Set up the wait context block in case we can't run right away. */
1496 WaitContextBlock->DeviceRoutine = ExecutionRoutine;
1497 WaitContextBlock->NumberOfMapRegisters = NumberOfMapRegisters;
1498
1499 /* Returns true if queued, else returns false and sets the queue to busy */
1500 if (KeInsertDeviceQueue(&AdapterObject->ChannelWaitQueue,
1501 &WaitContextBlock->WaitQueueEntry))
1502 {
1503 return STATUS_SUCCESS;
1504 }
1505
1506 MasterAdapter = AdapterObject->MasterAdapter;
1507
1508 AdapterObject->NumberOfMapRegisters = NumberOfMapRegisters;
1509 AdapterObject->CurrentWcb = WaitContextBlock;
1510
1511 if ((NumberOfMapRegisters) && (AdapterObject->NeedsMapRegisters))
1512 {
1513 if (NumberOfMapRegisters > AdapterObject->MapRegistersPerChannel)
1514 {
1515 AdapterObject->NumberOfMapRegisters = 0;
1516 IoFreeAdapterChannel(AdapterObject);
1518 }
1519
1520 /*
1521 * Get the map registers. This is partly complicated by the fact
1522 * that new map registers can only be allocated at PASSIVE_LEVEL
1523 * and we're currently at DISPATCH_LEVEL. The following code has
1524 * two code paths:
1525 *
1526 * - If there is no adapter queued for map register allocation,
1527 * try to see if enough contiguous map registers are present.
1528 * In case they're we can just get them and proceed further.
1529 *
1530 * - If some adapter is already present in the queue we must
1531 * respect the order of adapters asking for map registers and
1532 * so the fast case described above can't take place.
1533 * This case is also entered if not enough coniguous map
1534 * registers are present.
1535 *
1536 * A work queue item is allocated and queued, the adapter is
1537 * also queued into the master adapter queue. The worker
1538 * routine does the job of allocating the map registers at
1539 * PASSIVE_LEVEL and calling the ExecutionRoutine.
1540 */
1541
1542 KeAcquireSpinLock(&MasterAdapter->SpinLock, &OldIrql);
1543
1544 if (IsListEmpty(&MasterAdapter->AdapterQueue))
1545 {
1546 Index = RtlFindClearBitsAndSet(MasterAdapter->MapRegisters, NumberOfMapRegisters, 0);
1547 if (Index != MAXULONG)
1548 {
1549 AdapterObject->MapRegisterBase = MasterAdapter->MapRegisterBase + Index;
1550 if (!AdapterObject->ScatterGather)
1551 {
1552 AdapterObject->MapRegisterBase = (PROS_MAP_REGISTER_ENTRY)((ULONG_PTR)AdapterObject->MapRegisterBase | MAP_BASE_SW_SG);
1553 }
1554 }
1555 }
1556
1557 if (Index == MAXULONG)
1558 {
1559 InsertTailList(&MasterAdapter->AdapterQueue, &AdapterObject->AdapterQueue);
1560
1562 sizeof(GROW_WORK_ITEM),
1563 TAG_DMA);
1564 if (WorkItem)
1565 {
1567 WorkItem->AdapterObject = AdapterObject;
1568 WorkItem->NumberOfMapRegisters = NumberOfMapRegisters;
1569
1570 ExQueueWorkItem(&WorkItem->WorkQueueItem, DelayedWorkQueue);
1571 }
1572
1573 KeReleaseSpinLock(&MasterAdapter->SpinLock, OldIrql);
1574
1575 return STATUS_SUCCESS;
1576 }
1577
1578 KeReleaseSpinLock(&MasterAdapter->SpinLock, OldIrql);
1579 }
1580 else
1581 {
1582 AdapterObject->MapRegisterBase = NULL;
1583 AdapterObject->NumberOfMapRegisters = 0;
1584 }
1585
1586 AdapterObject->CurrentWcb = WaitContextBlock;
1587
1588 Result = ExecutionRoutine(WaitContextBlock->DeviceObject,
1589 WaitContextBlock->CurrentIrp,
1590 AdapterObject->MapRegisterBase,
1591 WaitContextBlock->DeviceContext);
1592
1593 /*
1594 * Possible return values:
1595 *
1596 * - KeepObject
1597 * Don't free any resources, the ADAPTER_OBJECT is still in use and
1598 * the caller will call IoFreeAdapterChannel later.
1599 *
1600 * - DeallocateObject
1601 * Deallocate the map registers and release the ADAPTER_OBJECT, so
1602 * someone else can use it.
1603 *
1604 * - DeallocateObjectKeepRegisters
1605 * Release the ADAPTER_OBJECT, but hang on to the map registers. The
1606 * client will later call IoFreeMapRegisters.
1607 *
1608 * NOTE:
1609 * IoFreeAdapterChannel runs the queue, so it must be called unless
1610 * the adapter object is not to be freed.
1611 */
1612 if (Result == DeallocateObject)
1613 {
1614 IoFreeAdapterChannel(AdapterObject);
1615 }
1617 {
1618 AdapterObject->NumberOfMapRegisters = 0;
1619 IoFreeAdapterChannel(AdapterObject);
1620 }
1621
1622 return STATUS_SUCCESS;
1623}
1624
1643VOID
1644NTAPI
1646{
1647 PADAPTER_OBJECT MasterAdapter;
1649 PWAIT_CONTEXT_BLOCK WaitContextBlock;
1651 ULONG Result;
1652 KIRQL OldIrql;
1653
1654 MasterAdapter = AdapterObject->MasterAdapter;
1655
1656 for (;;)
1657 {
1658 /*
1659 * To keep map registers, call here with AdapterObject->
1660 * NumberOfMapRegisters set to zero. This trick is used in
1661 * HalAllocateAdapterChannel for example.
1662 */
1663 if (AdapterObject->NumberOfMapRegisters)
1664 {
1665 IoFreeMapRegisters(AdapterObject,
1666 AdapterObject->MapRegisterBase,
1667 AdapterObject->NumberOfMapRegisters);
1668 }
1669
1670 DeviceQueueEntry = KeRemoveDeviceQueue(&AdapterObject->ChannelWaitQueue);
1671 if (!DeviceQueueEntry) break;
1672
1673 WaitContextBlock = CONTAINING_RECORD(DeviceQueueEntry,
1675 WaitQueueEntry);
1676
1677 AdapterObject->CurrentWcb = WaitContextBlock;
1678 AdapterObject->NumberOfMapRegisters = WaitContextBlock->NumberOfMapRegisters;
1679
1680 if ((WaitContextBlock->NumberOfMapRegisters) && (AdapterObject->MasterAdapter))
1681 {
1682 KeAcquireSpinLock(&MasterAdapter->SpinLock, &OldIrql);
1683
1684 if (IsListEmpty(&MasterAdapter->AdapterQueue))
1685 {
1686 Index = RtlFindClearBitsAndSet(MasterAdapter->MapRegisters,
1687 WaitContextBlock->NumberOfMapRegisters,
1688 0);
1689 if (Index != MAXULONG)
1690 {
1691 AdapterObject->MapRegisterBase = MasterAdapter->MapRegisterBase + Index;
1692 if (!AdapterObject->ScatterGather)
1693 {
1694 AdapterObject->MapRegisterBase =(PROS_MAP_REGISTER_ENTRY)((ULONG_PTR)AdapterObject->MapRegisterBase | MAP_BASE_SW_SG);
1695 }
1696 }
1697 }
1698
1699 if (Index == MAXULONG)
1700 {
1701 InsertTailList(&MasterAdapter->AdapterQueue, &AdapterObject->AdapterQueue);
1702 KeReleaseSpinLock(&MasterAdapter->SpinLock, OldIrql);
1703 break;
1704 }
1705
1706 KeReleaseSpinLock(&MasterAdapter->SpinLock, OldIrql);
1707 }
1708 else
1709 {
1710 AdapterObject->MapRegisterBase = NULL;
1711 AdapterObject->NumberOfMapRegisters = 0;
1712 }
1713
1714 /* Call the adapter control routine. */
1715 Result = ((PDRIVER_CONTROL)WaitContextBlock->DeviceRoutine)(WaitContextBlock->DeviceObject,
1716 WaitContextBlock->CurrentIrp,
1717 AdapterObject->MapRegisterBase,
1718 WaitContextBlock->DeviceContext);
1719 switch (Result)
1720 {
1721 case KeepObject:
1722 /*
1723 * We're done until the caller manually calls IoFreeAdapterChannel
1724 * or IoFreeMapRegisters.
1725 */
1726 return;
1727
1729 /*
1730 * Hide the map registers so they aren't deallocated next time
1731 * around.
1732 */
1733 AdapterObject->NumberOfMapRegisters = 0;
1734 break;
1735
1736 default:
1737 break;
1738 }
1739 }
1740}
1741
1756VOID
1757NTAPI
1761{
1762 PADAPTER_OBJECT MasterAdapter = AdapterObject->MasterAdapter;
1763 PLIST_ENTRY ListEntry;
1764 KIRQL OldIrql;
1765 ULONG Index;
1766 ULONG Result;
1767
1769
1770 if (!(MasterAdapter) || !(MapRegisterBase)) return;
1771
1772 KeAcquireSpinLock(&MasterAdapter->SpinLock, &OldIrql);
1773
1774 if (NumberOfMapRegisters != 0)
1775 {
1776 PROS_MAP_REGISTER_ENTRY RealMapRegisterBase;
1777
1778 RealMapRegisterBase = (PROS_MAP_REGISTER_ENTRY)((ULONG_PTR)MapRegisterBase & ~MAP_BASE_SW_SG);
1779 RtlClearBits(MasterAdapter->MapRegisters,
1780 (ULONG)(RealMapRegisterBase - MasterAdapter->MapRegisterBase),
1782 }
1783
1784 /*
1785 * Now that we freed few map registers it's time to look at the master
1786 * adapter queue and see if there is someone waiting for map registers.
1787 */
1788 while (!IsListEmpty(&MasterAdapter->AdapterQueue))
1789 {
1790 ListEntry = RemoveHeadList(&MasterAdapter->AdapterQueue);
1791 AdapterObject = CONTAINING_RECORD(ListEntry, struct _ADAPTER_OBJECT, AdapterQueue);
1792
1793 Index = RtlFindClearBitsAndSet(MasterAdapter->MapRegisters,
1794 AdapterObject->NumberOfMapRegisters,
1795 0);
1796 if (Index == MAXULONG)
1797 {
1798 InsertHeadList(&MasterAdapter->AdapterQueue, ListEntry);
1799 break;
1800 }
1801
1802 KeReleaseSpinLock(&MasterAdapter->SpinLock, OldIrql);
1803
1804 AdapterObject->MapRegisterBase = MasterAdapter->MapRegisterBase + Index;
1805 if (!AdapterObject->ScatterGather)
1806 {
1807 AdapterObject->MapRegisterBase =
1808 (PROS_MAP_REGISTER_ENTRY)((ULONG_PTR)AdapterObject->MapRegisterBase | MAP_BASE_SW_SG);
1809 }
1810
1811 Result = ((PDRIVER_CONTROL)AdapterObject->CurrentWcb->DeviceRoutine)(AdapterObject->CurrentWcb->DeviceObject,
1812 AdapterObject->CurrentWcb->CurrentIrp,
1813 AdapterObject->MapRegisterBase,
1814 AdapterObject->CurrentWcb->DeviceContext);
1815 switch (Result)
1816 {
1818 AdapterObject->NumberOfMapRegisters = 0;
1819 /* fall through */
1820
1821 case DeallocateObject:
1822 if (AdapterObject->NumberOfMapRegisters)
1823 {
1824 KeAcquireSpinLock(&MasterAdapter->SpinLock, &OldIrql);
1825 RtlClearBits(MasterAdapter->MapRegisters,
1826 (ULONG)(AdapterObject->MapRegisterBase -
1827 MasterAdapter->MapRegisterBase),
1828 AdapterObject->NumberOfMapRegisters);
1829 KeReleaseSpinLock(&MasterAdapter->SpinLock, OldIrql);
1830 }
1831
1832 IoFreeAdapterChannel(AdapterObject);
1833 break;
1834
1835 default:
1836 break;
1837 }
1838
1839 KeAcquireSpinLock(&MasterAdapter->SpinLock, &OldIrql);
1840 }
1841
1842 KeReleaseSpinLock(&MasterAdapter->SpinLock, OldIrql);
1843}
1844
1852VOID
1853NTAPI
1856 IN PVOID CurrentVa,
1857 IN ULONG Length,
1859{
1860 ULONG CurrentLength;
1861 ULONG_PTR CurrentAddress;
1864
1866 if (!VirtualAddress)
1867 {
1868 /*
1869 * NOTE: On real NT a mechanism with reserved pages is implemented
1870 * to handle this case in a slow, but graceful non-fatal way.
1871 */
1872 KeBugCheckEx(HAL_MEMORY_ALLOCATION, PAGE_SIZE, 0, (ULONG_PTR)__FILE__, 0);
1873 }
1874
1875 CurrentAddress = (ULONG_PTR)VirtualAddress +
1876 (ULONG_PTR)CurrentVa -
1878
1879 while (Length > 0)
1880 {
1881 ByteOffset = BYTE_OFFSET(CurrentAddress);
1882 CurrentLength = PAGE_SIZE - ByteOffset;
1883 if (CurrentLength > Length) CurrentLength = Length;
1884
1885 if (WriteToDevice)
1886 {
1888 (PVOID)CurrentAddress,
1889 CurrentLength);
1890 }
1891 else
1892 {
1893 RtlCopyMemory((PVOID)CurrentAddress,
1894 (PVOID)((ULONG_PTR)MapRegisterBase->VirtualAddress + ByteOffset),
1895 CurrentLength);
1896 }
1897
1898 Length -= CurrentLength;
1899 CurrentAddress += CurrentLength;
1901 }
1902}
1903
1935BOOLEAN
1936NTAPI
1938 IN PMDL Mdl,
1940 IN PVOID CurrentVa,
1941 IN ULONG Length,
1943{
1944 BOOLEAN SlaveDma = FALSE;
1945 PROS_MAP_REGISTER_ENTRY RealMapRegisterBase;
1948 PPFN_NUMBER MdlPagesPtr;
1949
1950 /* Sanity checks */
1952 ASSERT(AdapterObject);
1953
1954 if (!AdapterObject->MasterDevice)
1955 {
1956 /* Mask out (disable) the DMA channel. */
1957 if (AdapterObject->AdapterNumber == 1)
1958 {
1959 PDMA1_CONTROL DmaControl1 = AdapterObject->AdapterBaseVa;
1960 WRITE_PORT_UCHAR(&DmaControl1->SingleMask,
1961 AdapterObject->ChannelNumber | DMA_SETMASK);
1962 }
1963 else
1964 {
1965 PDMA2_CONTROL DmaControl2 = AdapterObject->AdapterBaseVa;
1966 WRITE_PORT_UCHAR(&DmaControl2->SingleMask,
1967 AdapterObject->ChannelNumber | DMA_SETMASK);
1968 }
1969 SlaveDma = TRUE;
1970 }
1971
1972 /* This can happen if the device supports hardware scatter/gather. */
1973 if (MapRegisterBase == NULL) return TRUE;
1974
1975 RealMapRegisterBase = (PROS_MAP_REGISTER_ENTRY)((ULONG_PTR)MapRegisterBase & ~MAP_BASE_SW_SG);
1976
1977 if (!WriteToDevice)
1978 {
1980 {
1981 if (RealMapRegisterBase->Counter != MAXULONG)
1982 {
1983 if ((SlaveDma) && !(AdapterObject->IgnoreCount))
1984 {
1985 Length -= HalReadDmaCounter(AdapterObject);
1986 }
1987 }
1989 RealMapRegisterBase,
1990 CurrentVa,
1991 Length,
1992 FALSE);
1993 }
1994 else
1995 {
1996 MdlPagesPtr = MmGetMdlPfnArray(Mdl);
1997 MdlPagesPtr += ((ULONG_PTR)CurrentVa - (ULONG_PTR)Mdl->StartVa) >> PAGE_SHIFT;
1998
1999 PhysicalAddress.QuadPart = *MdlPagesPtr << PAGE_SHIFT;
2000 PhysicalAddress.QuadPart += BYTE_OFFSET(CurrentVa);
2001
2004 {
2006 RealMapRegisterBase,
2007 CurrentVa,
2008 Length,
2009 FALSE);
2010 }
2011 }
2012 }
2013
2014 RealMapRegisterBase->Counter = 0;
2015
2016 return TRUE;
2017}
2018
2051NTAPI
2053 IN PMDL Mdl,
2055 IN PVOID CurrentVa,
2058{
2059 PPFN_NUMBER MdlPagesPtr;
2060 PFN_NUMBER MdlPage1, MdlPage2;
2063 ULONG TransferLength;
2064 BOOLEAN UseMapRegisters;
2065 PROS_MAP_REGISTER_ENTRY RealMapRegisterBase;
2068 ULONG Counter;
2069 DMA_MODE AdapterMode;
2070 KIRQL OldIrql;
2071
2072 /*
2073 * Precalculate some values that are used in all cases.
2074 *
2075 * ByteOffset is offset inside the page at which the transfer starts.
2076 * MdlPagesPtr is pointer inside the MDL page chain at the page where the
2077 * transfer start.
2078 * PhysicalAddress is physical address corresponding to the transfer
2079 * start page and offset.
2080 * TransferLength is the initial length of the transfer, which is reminder
2081 * of the first page. The actual value is calculated below.
2082 *
2083 * Note that all the variables can change during the processing which
2084 * takes place below. These are just initial values.
2085 */
2086 ByteOffset = BYTE_OFFSET(CurrentVa);
2087
2088 MdlPagesPtr = MmGetMdlPfnArray(Mdl);
2089 MdlPagesPtr += ((ULONG_PTR)CurrentVa - (ULONG_PTR)Mdl->StartVa) >> PAGE_SHIFT;
2090
2091 PhysicalAddress.QuadPart = *MdlPagesPtr << PAGE_SHIFT;
2093
2094 TransferLength = PAGE_SIZE - ByteOffset;
2095
2096 /*
2097 * Special case for bus master adapters with S/G support. We can directly
2098 * use the buffer specified by the MDL, so not much work has to be done.
2099 *
2100 * Just return the passed VA's corresponding physical address and update
2101 * length to the number of physically contiguous bytes found. Also
2102 * pages crossing the 4Gb boundary aren't considered physically contiguous.
2103 */
2104 if (MapRegisterBase == NULL)
2105 {
2106 while (TransferLength < *Length)
2107 {
2108 MdlPage1 = *MdlPagesPtr;
2109 MdlPage2 = *(MdlPagesPtr + 1);
2110 if (MdlPage1 + 1 != MdlPage2) break;
2111 if ((MdlPage1 ^ MdlPage2) & ~0xFFFFF) break;
2112 TransferLength += PAGE_SIZE;
2113 MdlPagesPtr++;
2114 }
2115
2116 if (TransferLength < *Length) *Length = TransferLength;
2117
2118 return PhysicalAddress;
2119 }
2120
2121 /*
2122 * The code below applies to slave DMA adapters and bus master adapters
2123 * without hardward S/G support.
2124 */
2125 RealMapRegisterBase = (PROS_MAP_REGISTER_ENTRY)((ULONG_PTR)MapRegisterBase & ~MAP_BASE_SW_SG);
2126
2127 /*
2128 * Try to calculate the size of the transfer. We can only transfer
2129 * pages that are physically contiguous and that don't cross the
2130 * 64Kb boundary (this limitation applies only for ISA controllers).
2131 */
2132 while (TransferLength < *Length)
2133 {
2134 MdlPage1 = *MdlPagesPtr;
2135 MdlPage2 = *(MdlPagesPtr + 1);
2136 if (MdlPage1 + 1 != MdlPage2) break;
2137 if (!HalpEisaDma && ((MdlPage1 ^ MdlPage2) & ~0xF)) break;
2138 TransferLength += PAGE_SIZE;
2139 MdlPagesPtr++;
2140 }
2141
2142 if (TransferLength > *Length) TransferLength = *Length;
2143
2144 /*
2145 * If we're about to simulate software S/G and not all the pages are
2146 * physically contiguous then we must use the map registers to store
2147 * the data and allow the whole transfer to proceed at once.
2148 */
2149 if (((ULONG_PTR)MapRegisterBase & MAP_BASE_SW_SG) && (TransferLength < *Length))
2150 {
2151 UseMapRegisters = TRUE;
2152 PhysicalAddress = RealMapRegisterBase->PhysicalAddress;
2154 TransferLength = *Length;
2155 RealMapRegisterBase->Counter = MAXULONG;
2156 Counter = 0;
2157 }
2158 else
2159 {
2160 /*
2161 * This is ordinary DMA transfer, so just update the progress
2162 * counters. These are used by IoFlushAdapterBuffers to track
2163 * the transfer progress.
2164 */
2165 UseMapRegisters = FALSE;
2166 Counter = RealMapRegisterBase->Counter;
2167 RealMapRegisterBase->Counter += BYTES_TO_PAGES(ByteOffset + TransferLength);
2168
2169 /*
2170 * Check if the buffer doesn't exceed the highest physical address
2171 * limit of the device. In that case we must use the map registers to
2172 * store the data.
2173 */
2175 if ((PhysicalAddress.QuadPart + TransferLength) > HighestAcceptableAddress.QuadPart)
2176 {
2177 UseMapRegisters = TRUE;
2178 PhysicalAddress = RealMapRegisterBase[Counter].PhysicalAddress;
2181 {
2182 RealMapRegisterBase->Counter = MAXULONG;
2183 Counter = 0;
2184 }
2185 }
2186 }
2187
2188 /*
2189 * If we decided to use the map registers (see above) and we're about
2190 * to transfer data to the device then copy the buffers into the map
2191 * register memory.
2192 */
2193 if ((UseMapRegisters) && (WriteToDevice))
2194 {
2196 RealMapRegisterBase + Counter,
2197 CurrentVa,
2198 TransferLength,
2200 }
2201
2202 /*
2203 * Return the length of transfer that actually takes place.
2204 */
2205 *Length = TransferLength;
2206
2207 /*
2208 * If we're doing slave (system) DMA then program the (E)ISA controller
2209 * to actually start the transfer.
2210 */
2211 if ((AdapterObject) && !(AdapterObject->MasterDevice))
2212 {
2213 AdapterMode = AdapterObject->AdapterMode;
2214
2215 if (WriteToDevice)
2216 {
2217 AdapterMode.TransferType = WRITE_TRANSFER;
2218 }
2219 else
2220 {
2221 AdapterMode.TransferType = READ_TRANSFER;
2222 if (AdapterObject->IgnoreCount)
2223 {
2224 RtlZeroMemory((PUCHAR)RealMapRegisterBase[Counter].VirtualAddress + ByteOffset,
2225 TransferLength);
2226 }
2227 }
2228
2230 if (AdapterObject->Width16Bits)
2231 {
2232 TransferLength >>= 1;
2233 TransferOffset >>= 1;
2234 }
2235
2236 KeAcquireSpinLock(&AdapterObject->MasterAdapter->SpinLock, &OldIrql);
2237
2238 if (AdapterObject->AdapterNumber == 1)
2239 {
2240 PDMA1_CONTROL DmaControl1 = AdapterObject->AdapterBaseVa;
2241
2242 /* Reset Register */
2243 WRITE_PORT_UCHAR(&DmaControl1->ClearBytePointer, 0);
2244
2245 /* Set the Mode */
2246 WRITE_PORT_UCHAR(&DmaControl1->Mode, AdapterMode.Byte);
2247
2248 /* Set the Offset Register */
2249 WRITE_PORT_UCHAR(&DmaControl1->DmaAddressCount[AdapterObject->ChannelNumber].DmaBaseAddress,
2251 WRITE_PORT_UCHAR(&DmaControl1->DmaAddressCount[AdapterObject->ChannelNumber].DmaBaseAddress,
2252 (UCHAR)(TransferOffset >> 8));
2253
2254 /* Set the Page Register */
2255 WRITE_PORT_UCHAR(AdapterObject->PagePort + FIELD_OFFSET(EISA_CONTROL, DmaController1Pages),
2256 (UCHAR)(PhysicalAddress.LowPart >> 16));
2257 if (HalpEisaDma)
2258 {
2259 WRITE_PORT_UCHAR(AdapterObject->PagePort + FIELD_OFFSET(EISA_CONTROL, DmaController2Pages),
2260 0);
2261 }
2262
2263 /* Set the Length */
2264 WRITE_PORT_UCHAR(&DmaControl1->DmaAddressCount[AdapterObject->ChannelNumber].DmaBaseCount,
2265 (UCHAR)(TransferLength - 1));
2266 WRITE_PORT_UCHAR(&DmaControl1->DmaAddressCount[AdapterObject->ChannelNumber].DmaBaseCount,
2267 (UCHAR)((TransferLength - 1) >> 8));
2268
2269 /* Unmask the Channel */
2270 WRITE_PORT_UCHAR(&DmaControl1->SingleMask, AdapterObject->ChannelNumber | DMA_CLEARMASK);
2271 }
2272 else
2273 {
2274 PDMA2_CONTROL DmaControl2 = AdapterObject->AdapterBaseVa;
2275
2276 /* Reset Register */
2277 WRITE_PORT_UCHAR(&DmaControl2->ClearBytePointer, 0);
2278
2279 /* Set the Mode */
2280 WRITE_PORT_UCHAR(&DmaControl2->Mode, AdapterMode.Byte);
2281
2282 /* Set the Offset Register */
2283 WRITE_PORT_UCHAR(&DmaControl2->DmaAddressCount[AdapterObject->ChannelNumber].DmaBaseAddress,
2285 WRITE_PORT_UCHAR(&DmaControl2->DmaAddressCount[AdapterObject->ChannelNumber].DmaBaseAddress,
2286 (UCHAR)(TransferOffset >> 8));
2287
2288 /* Set the Page Register */
2289 WRITE_PORT_UCHAR(AdapterObject->PagePort + FIELD_OFFSET(EISA_CONTROL, DmaController1Pages),
2290 (UCHAR)(PhysicalAddress.u.LowPart >> 16));
2291 if (HalpEisaDma)
2292 {
2293 WRITE_PORT_UCHAR(AdapterObject->PagePort + FIELD_OFFSET(EISA_CONTROL, DmaController2Pages),
2294 0);
2295 }
2296
2297 /* Set the Length */
2298 WRITE_PORT_UCHAR(&DmaControl2->DmaAddressCount[AdapterObject->ChannelNumber].DmaBaseCount,
2299 (UCHAR)(TransferLength - 1));
2300 WRITE_PORT_UCHAR(&DmaControl2->DmaAddressCount[AdapterObject->ChannelNumber].DmaBaseCount,
2301 (UCHAR)((TransferLength - 1) >> 8));
2302
2303 /* Unmask the Channel */
2304 WRITE_PORT_UCHAR(&DmaControl2->SingleMask,
2305 AdapterObject->ChannelNumber | DMA_CLEARMASK);
2306 }
2307
2308 KeReleaseSpinLock(&AdapterObject->MasterAdapter->SpinLock, OldIrql);
2309 }
2310
2311 /*
2312 * Return physical address of the buffer with data that is used for the
2313 * transfer. It can either point inside the Mdl that was passed by the
2314 * caller or into the map registers if the Mdl buffer can't be used
2315 * directly.
2316 */
2317 return PhysicalAddress;
2318}
2319#endif
2320
2326BOOLEAN
2327NTAPI
2329 IN ULONG Length,
2330 IN PHYSICAL_ADDRESS LogicalAddress,
2332{
2333 /* Function always returns true */
2334 return TRUE;
2335}
2336
2337/*
2338 * @implemented
2339 */
2340PVOID
2341NTAPI
2344{
2345 PADAPTER_OBJECT MasterAdapter = AdapterObject->MasterAdapter;
2346 ULONG MapRegisterNumber;
2347
2348 /* Check if it needs map registers */
2349 if (AdapterObject->NeedsMapRegisters)
2350 {
2351 /* Check if we have enough */
2352 if (*NumberOfMapRegisters > AdapterObject->MapRegistersPerChannel)
2353 {
2354 /* We don't, fail */
2355 AdapterObject->NumberOfMapRegisters = 0;
2356 return NULL;
2357 }
2358
2359 /* Try to find free map registers */
2360 MapRegisterNumber = RtlFindClearBitsAndSet(MasterAdapter->MapRegisters,
2362 0);
2363
2364 /* Check if nothing was found */
2365 if (MapRegisterNumber == MAXULONG)
2366 {
2367 /* No free registers found, so use the base registers */
2368 RtlSetBits(MasterAdapter->MapRegisters,
2369 0,
2371 MapRegisterNumber = 0;
2372 }
2373
2374 /* Calculate the new base */
2375 AdapterObject->MapRegisterBase =
2376 (PROS_MAP_REGISTER_ENTRY)(MasterAdapter->MapRegisterBase +
2377 MapRegisterNumber);
2378
2379 /* Check if scatter gather isn't supported */
2380 if (!AdapterObject->ScatterGather)
2381 {
2382 /* Set the flag */
2383 AdapterObject->MapRegisterBase =
2385 ((ULONG_PTR)AdapterObject->MapRegisterBase | MAP_BASE_SW_SG);
2386 }
2387 }
2388 else
2389 {
2390 AdapterObject->MapRegisterBase = NULL;
2391 AdapterObject->NumberOfMapRegisters = 0;
2392 }
2393
2394 /* Return the base */
2395 return AdapterObject->MapRegisterBase;
2396}
2397
2398/* EOF */
#define ExAllocatePoolUninitialized
#define CODE_SEG(...)
ULONG_PTR PFN_NUMBER
unsigned char BOOLEAN
Definition: actypes.h:127
LONG NTSTATUS
Definition: precomp.h:26
#define DPRINT1
Definition: precomp.h:8
@ EisaAdapter
Definition: arcname.c:39
#define UNIMPLEMENTED
Definition: ntoskrnl.c:15
DECLSPEC_NORETURN VOID NTAPI KeBugCheckEx(IN ULONG BugCheckCode, IN ULONG_PTR BugCheckParameter1, IN ULONG_PTR BugCheckParameter2, IN ULONG_PTR BugCheckParameter3, IN ULONG_PTR BugCheckParameter4)
Definition: debug.c:485
ULONG HalpBusType
Definition: pcibus.c:18
_In_ PSCSI_REQUEST_BLOCK _In_opt_ PVOID _In_ ULONG _In_ BOOLEAN WriteToDevice
Definition: cdrom.h:992
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:36
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
VOID NTAPI MmFreeContiguousMemorySpecifyCache(IN PVOID BaseAddress, IN SIZE_T NumberOfBytes, IN MEMORY_CACHING_TYPE CacheType)
Definition: contmem.c:666
_In_ PIRP Irp
Definition: csq.h:116
#define STATUS_NOT_IMPLEMENTED
Definition: d3dkmdt.h:42
#define RtlClearBits
Definition: dbgbitmap.h:331
#define RtlInitializeBitMap
Definition: dbgbitmap.h:326
#define RtlClearBit
Definition: dbgbitmap.h:330
#define RtlFindClearBitsAndSet
Definition: dbgbitmap.h:333
#define RtlSetAllBits
Definition: dbgbitmap.h:346
#define RTL_BITMAP
Definition: dbgbitmap.h:323
#define RtlSetBits
Definition: dbgbitmap.h:345
PKDEVICE_QUEUE_ENTRY NTAPI KeRemoveDeviceQueue(IN PKDEVICE_QUEUE DeviceQueue)
Definition: devqueue.c:153
BOOLEAN NTAPI KeInsertDeviceQueue(IN PKDEVICE_QUEUE DeviceQueue, IN PKDEVICE_QUEUE_ENTRY DeviceQueueEntry)
Definition: devqueue.c:41
VOID NTAPI KeInitializeDeviceQueue(IN PKDEVICE_QUEUE DeviceQueue)
Definition: devqueue.c:22
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
#define UlongToPtr(u)
Definition: config.h:106
#define ULONG_PTR
Definition: config.h:101
#define RemoveEntryList(Entry)
Definition: env_spec_w32.h:986
#define InsertTailList(ListHead, Entry)
#define InsertHeadList(ListHead, Entry)
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define IsListEmpty(ListHead)
Definition: env_spec_w32.h:954
UCHAR KIRQL
Definition: env_spec_w32.h:591
ULONG KSPIN_LOCK
Definition: env_spec_w32.h:72
#define KeWaitForSingleObject(pEvt, foo, a, b, c)
Definition: env_spec_w32.h:478
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
#define PAGE_SIZE
Definition: env_spec_w32.h:49
#define PAGE_SHIFT
Definition: env_spec_w32.h:45
#define KeSetEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:476
#define KeAcquireSpinLock(sl, irql)
Definition: env_spec_w32.h:609
#define KeGetCurrentIrql()
Definition: env_spec_w32.h:706
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
#define RemoveHeadList(ListHead)
Definition: env_spec_w32.h:964
#define NonPagedPool
Definition: env_spec_w32.h:307
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
#define DISPATCH_LEVEL
Definition: env_spec_w32.h:696
#define KeInitializeSpinLock(sl)
Definition: env_spec_w32.h:604
IN PDCB IN PCCB IN VBO IN OUT PULONG OUT PDIRENT OUT PBCB OUT PVBO ByteOffset
Definition: fatprocs.h:732
for(i=0;i< ARRAY_SIZE(offsets);i++)
ULONG Handle
Definition: gdb_input.c:15
Status
Definition: gdiplustypes.h:25
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
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
VOID NTAPI HalPutDmaAdapter(IN PADAPTER_OBJECT AdapterObject)
Definition: dma.c:35
PVOID NTAPI HalAllocateCommonBuffer(IN PADAPTER_OBJECT AdapterObject, IN ULONG Length, IN PPHYSICAL_ADDRESS LogicalAddress, IN BOOLEAN CacheEnabled)
Definition: dma.c:46
VOID NTAPI IoFreeMapRegisters(IN PADAPTER_OBJECT AdapterObject, IN PVOID MapRegisterBase, IN ULONG NumberOfMapRegisters)
Definition: dma.c:114
PADAPTER_OBJECT NTAPI HalGetAdapter(IN PDEVICE_DESCRIPTION DeviceDescription, OUT PULONG NumberOfMapRegisters)
Definition: dma.c:22
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
NTSTATUS NTAPI HalAllocateAdapterChannel(IN PADAPTER_OBJECT AdapterObject, IN PWAIT_CONTEXT_BLOCK WaitContextBlock, IN ULONG NumberOfMapRegisters, IN PDRIVER_CONTROL ExecutionRoutine)
Definition: dma.c:88
VOID NTAPI IoFreeAdapterChannel(IN PADAPTER_OBJECT AdapterObject)
Definition: dma.c:103
VOID NTAPI HalFreeCommonBuffer(IN PADAPTER_OBJECT AdapterObject, IN ULONG Length, IN PHYSICAL_ADDRESS LogicalAddress, IN PVOID VirtualAddress, IN BOOLEAN CacheEnabled)
Definition: dma.c:61
BOOLEAN NTAPI HalFlushCommonBuffer(IN PADAPTER_OBJECT AdapterObject, IN ULONG Length, IN PHYSICAL_ADDRESS LogicalAddress, IN PVOID VirtualAddress)
Definition: dma.c:165
ULONG NTAPI HalReadDmaCounter(IN PADAPTER_OBJECT AdapterObject)
Definition: dma.c:76
PVOID NTAPI HalAllocateCrashDumpRegisters(IN PADAPTER_OBJECT AdapterObject, IN OUT PULONG NumberOfMapRegisters)
Definition: dma.c:180
VOID FASTCALL KfLowerIrql(IN KIRQL NewIrql)
Definition: pic.c:232
KIRQL FASTCALL KfRaiseIrql(IN KIRQL NewIrql)
Definition: pic.c:187
PADAPTER_OBJECT NTAPI HalpDmaAllocateMasterAdapter(VOID)
Definition: dma.c:396
static KEVENT HalpDmaLock
Definition: dma.c:81
static PADAPTER_OBJECT HalpMasterAdapter
Definition: dma.c:88
#define MAX_MAP_REGISTERS
Definition: dma.c:156
#define TAG_DMA
Definition: dma.c:158
VOID NTAPI HalpGrowMapBufferWorker(IN PVOID DeferredContext)
Definition: dma.c:1423
BOOLEAN NTAPI HalpGrowMapBuffers(IN PADAPTER_OBJECT AdapterObject, IN ULONG SizeOfMapBuffers)
Definition: dma.c:269
static DMA_OPERATIONS HalpDmaOperations
Definition: dma.c:136
NTSTATUS NTAPI HalBuildMdlFromScatterGatherList(IN PDMA_ADAPTER DmaAdapter, IN PSCATTER_GATHER_LIST ScatterGather, IN PMDL OriginalMdl, OUT PMDL *TargetMdl)
Definition: dma.c:1316
static BOOLEAN HalpEisaDma
Definition: dma.c:86
VOID NTAPI HalpCopyBufferMap(IN PMDL Mdl, IN PROS_MAP_REGISTER_ENTRY MapRegisterBase, IN PVOID CurrentVa, IN ULONG Length, IN BOOLEAN WriteToDevice)
Definition: dma.c:1854
static KSPIN_LOCK HalpDmaAdapterListLock
Definition: dma.c:82
IO_ALLOCATION_ACTION NTAPI HalpScatterGatherAdapterControl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID MapRegisterBase, IN PVOID Context)
Definition: dma.c:988
PHYSICAL_ADDRESS NTAPI HalpGetAdapterMaximumPhysicalAddress(IN PADAPTER_OBJECT AdapterObject)
Definition: dma.c:233
struct _SCATTER_GATHER_CONTEXT * PSCATTER_GATHER_CONTEXT
#define MAX_SG_ELEMENTS
Definition: dma.c:984
VOID HalpInitDma(VOID)
Definition: dma.c:183
PADAPTER_OBJECT NTAPI HalpDmaAllocateChildAdapter(IN ULONG NumberOfMapRegisters, IN PDEVICE_DESCRIPTION DeviceDescription)
Definition: dma.c:453
ULONG NTAPI HalpDmaGetDmaAlignment(IN PADAPTER_OBJECT AdapterObject)
Definition: dma.c:1337
struct _SCATTER_GATHER_CONTEXT SCATTER_GATHER_CONTEXT
VOID NTAPI HalPutScatterGatherList(IN PADAPTER_OBJECT AdapterObject, IN PSCATTER_GATHER_LIST ScatterGather, IN BOOLEAN WriteToDevice)
Definition: dma.c:1144
static const ULONG_PTR HalpEisaPortPage[8]
Definition: dma.c:91
static PADAPTER_OBJECT HalpEisaAdapter[8]
Definition: dma.c:84
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:1236
PDMA_ADAPTER NTAPI HalpGetDmaAdapter(IN PVOID Context, IN PDEVICE_DESCRIPTION DeviceDescription, OUT PULONG NumberOfMapRegisters)
Definition: dma.c:850
static LIST_ENTRY HalpDmaAdapterList
Definition: dma.c:83
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:1103
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:1178
BOOLEAN NTAPI HalpDmaInitializeEisaAdapter(IN PADAPTER_OBJECT AdapterObject, IN PDEVICE_DESCRIPTION DeviceDescription)
Definition: dma.c:512
#define TYPE_B_TIMING
Definition: haldma.h:151
#define COMPATIBLE_TIMING
Definition: haldma.h:149
#define DMA_CLEARMASK
Definition: haldma.h:175
#define B_16BITS
Definition: haldma.h:146
struct _ROS_MAP_REGISTER_ENTRY * PROS_MAP_REGISTER_ENTRY
#define DEMAND_REQUEST_MODE
Definition: haldma.h:169
#define WRITE_TRANSFER
Definition: haldma.h:166
#define SINGLE_REQUEST_MODE
Definition: haldma.h:170
struct _GROW_WORK_ITEM * PGROW_WORK_ITEM
#define DMA_SETMASK
Definition: haldma.h:174
#define B_32BITS
Definition: haldma.h:145
#define TYPE_A_TIMING
Definition: haldma.h:150
#define MAP_BASE_SW_SG
Definition: haldma.h:367
#define READ_TRANSFER
Definition: haldma.h:165
#define BURST_TIMING
Definition: haldma.h:152
#define B_8BITS
Definition: haldma.h:143
struct _ADAPTER_OBJECT ADAPTER_OBJECT
#define CASCADE_REQUEST_MODE
Definition: haldma.h:172
_In_ ULONG Mode
Definition: hubbusif.h:303
if(dx< 0)
Definition: linetemp.h:194
#define ASSERT(a)
Definition: mode.c:44
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
@ HighPagePriority
Definition: imports.h:55
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:115
#define min(a, b)
Definition: monoChain.cc:55
_Out_ PNDIS_HANDLE _Out_ PUINT _In_ PNDIS_STRING _In_ NDIS_PHYSICAL_ADDRESS HighestAcceptableAddress
Definition: ndis.h:3230
#define MACHINE_TYPE_EISA
Definition: ketypes.h:108
#define KernelMode
Definition: asm.h:38
#define PAGE_ROUND_UP(x)
Definition: mmtypes.h:38
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
int Count
Definition: noreturn.cpp:7
#define TypeA
Definition: nslookup.h:13
#define FILE_WRITE_DATA
Definition: nt_native.h:631
#define FILE_READ_DATA
Definition: nt_native.h:628
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
@ NotificationEvent
POBJECT_TYPE IoAdapterObjectType
Definition: adapter.c:18
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
PHYSICAL_ADDRESS NTAPI MmGetPhysicalAddress(IN PVOID Address)
Definition: stubs.c:685
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:2935
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:1039
#define READ_PORT_UCHAR(p)
Definition: pc98vid.h:22
#define WRITE_PORT_UCHAR(p, d)
Definition: pc98vid.h:21
unsigned short USHORT
Definition: pedump.c:61
static WCHAR Address[46]
Definition: ping.c:68
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
#define OBJ_PERMANENT
Definition: winternl.h:226
@ Eisa
Definition: restypes.h:123
@ PCIBus
Definition: restypes.h:126
@ Isa
Definition: restypes.h:122
@ Width16Bits
Definition: miniport.h:106
@ Width8Bits
Definition: miniport.h:105
@ Width32Bits
Definition: miniport.h:107
@ TypeB
Definition: miniport.h:114
@ Compatible
Definition: miniport.h:112
@ TypeC
Definition: miniport.h:115
#define ASSERT_IRQL_LESS_OR_EQUAL(x)
Definition: debug.h:251
ULONG * PPFN_NUMBER
Definition: ke.h:9
#define STATUS_SUCCESS
Definition: shellext.h:65
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
#define DPRINT
Definition: sndvol32.h:73
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68
_In_ PVOID Context
Definition: storport.h:2269
UCHAR DmaBaseAddress
Definition: haldma.h:183
UCHAR DmaBaseCount
Definition: haldma.h:184
UCHAR ClearBytePointer
Definition: haldma.h:202
UCHAR Mode
Definition: haldma.h:201
DMA1_ADDRESS_COUNT DmaAddressCount[4]
Definition: haldma.h:197
UCHAR SingleMask
Definition: haldma.h:200
UCHAR DmaBaseAddress
Definition: haldma.h:189
UCHAR DmaBaseCount
Definition: haldma.h:191
UCHAR ClearBytePointer
Definition: haldma.h:219
DMA2_ADDRESS_COUNT DmaAddressCount[4]
Definition: haldma.h:210
UCHAR Mode
Definition: haldma.h:217
UCHAR SingleMask
Definition: haldma.h:215
struct _DMA_OPERATIONS * DmaOperations
Definition: iotypes.h:2297
USHORT Size
Definition: iotypes.h:2296
USHORT Version
Definition: iotypes.h:2295
PFREE_ADAPTER_CHANNEL FreeAdapterChannel
Definition: iotypes.h:2641
PALLOCATE_ADAPTER_CHANNEL AllocateAdapterChannel
Definition: iotypes.h:2639
PFLUSH_ADAPTER_BUFFERS FlushAdapterBuffers
Definition: iotypes.h:2640
PFREE_MAP_REGISTERS FreeMapRegisters
Definition: iotypes.h:2642
PMAP_TRANSFER MapTransfer
Definition: iotypes.h:2643
Definition: ketypes.h:630
Definition: typedefs.h:120
Definition: haldma.h:313
PHYSICAL_ADDRESS PhysicalAddress
Definition: haldma.h:315
PVOID VirtualAddress
Definition: haldma.h:314
ULONG Counter
Definition: haldma.h:316
PVOID AdapterListControlContext
Definition: dma.c:977
ULONG MapRegisterCount
Definition: dma.c:978
WAIT_CONTEXT_BLOCK Wcb
Definition: dma.c:980
PADAPTER_OBJECT AdapterObject
Definition: dma.c:972
BOOLEAN UsingUserBuffer
Definition: dma.c:971
PVOID MapRegisterBase
Definition: dma.c:977
BOOLEAN WriteToDevice
Definition: dma.c:979
PDRIVER_LIST_CONTROL AdapterListControlRoutine
Definition: dma.c:976
PHYSICAL_ADDRESS Address
Definition: iotypes.h:2175
ULONG NumberOfMapRegisters
Definition: iotypes.h:221
PDRIVER_CONTROL DeviceRoutine
Definition: iotypes.h:219
static LARGE_INTEGER Counter
Definition: clock.c:43
#define __WARNING_DEREF_NULL_PTR
Definition: suppress.h:32
#define _PRAGMA_WARNING_SUPPRESS(x)
Definition: suppress.h:28
#define MAXULONG
Definition: typedefs.h:251
uint32_t * PULONG
Definition: typedefs.h:59
unsigned char UCHAR
Definition: typedefs.h:53
#define UNIMPLEMENTED_ONCE
Definition: typedefs.h:30
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
#define NTAPI
Definition: typedefs.h:36
void * PVOID
Definition: typedefs.h:50
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define IN
Definition: typedefs.h:39
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
unsigned char * PUCHAR
Definition: typedefs.h:53
uint32_t ULONG
Definition: typedefs.h:59
#define OUT
Definition: typedefs.h:40
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define MAXLONG
Definition: umtypes.h:116
UCHAR TimingMode
Definition: haldma.h:135
UCHAR TransferSize
Definition: haldma.h:134
UCHAR ChannelNumber
Definition: haldma.h:133
UCHAR RequestMode
Definition: haldma.h:97
UCHAR Byte
Definition: haldma.h:99
UCHAR TransferType
Definition: haldma.h:94
UCHAR Channel
Definition: haldma.h:93
UCHAR AutoInitialize
Definition: haldma.h:95
struct _LARGE_INTEGER::@2500 u
LONGLONG QuadPart
Definition: typedefs.h:114
ULONG LowPart
Definition: typedefs.h:106
_In_ WDFCOLLECTION _In_ ULONG Index
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2061
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4539
_Must_inspect_result_ _In_ WDFDMATRANSACTION _In_ PFN_WDF_PROGRAM_DMA _In_ WDF_DMA_DIRECTION _In_ PMDL _In_ PVOID VirtualAddress
_In_ WDFDEVICE _In_ PVOID _In_opt_ PMDL Mdl
_In_ WDFDMATRANSACTION _In_ size_t MaximumLength
_In_ WDFDMATRANSACTION _Out_opt_ ULONG * MapRegisterCount
_Must_inspect_result_ _In_ PWDFDEVICE_INIT _In_ PCUNICODE_STRING DeviceDescription
Definition: wdfpdo.h:432
_Must_inspect_result_ _In_ WDFUSBDEVICE _In_ WDFREQUEST _In_ PWDF_USB_CONTROL_SETUP_PACKET _In_opt_ WDFMEMORY _In_opt_ PWDFMEMORY_OFFSET TransferOffset
Definition: wdfusb.h:1387
_Must_inspect_result_ _In_ PWDF_WORKITEM_CONFIG _In_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFWORKITEM * WorkItem
Definition: wdfworkitem.h:115
VOID NTAPI ExQueueWorkItem(IN PWORK_QUEUE_ITEM WorkItem, IN WORK_QUEUE_TYPE QueueType)
Definition: work.c:723
_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:409
#define ExInitializeWorkItem(Item, Routine, Context)
Definition: exfuncs.h:265
@ DelayedWorkQueue
Definition: extypes.h:190
_Out_ PULONG NumberOfMapRegisters
Definition: halfuncs.h:209
#define HalGetDmaAdapter
Definition: haltypes.h:312
_In_ PDEVICE_OBJECT _In_ ULONG _In_ PDRIVER_CONTROL ExecutionRoutine
Definition: iofuncs.h:1399
_Inout_ PMDL TargetMdl
Definition: iofuncs.h:730
VOID(NTAPI * PFREE_ADAPTER_CHANNEL)(_In_ PDMA_ADAPTER DmaAdapter)
Definition: iotypes.h:2345
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:2408
VOID(NTAPI * PFREE_MAP_REGISTERS)(_In_ PDMA_ADAPTER DmaAdapter, PVOID MapRegisterBase, ULONG NumberOfMapRegisters)
Definition: iotypes.h:2349
struct _DMA_OPERATIONS DMA_OPERATIONS
struct _SCATTER_GATHER_LIST SCATTER_GATHER_LIST
Definition: iotypes.h:2206
_Must_inspect_result_ typedef _In_ PHYSICAL_ADDRESS PhysicalAddress
Definition: iotypes.h:1098
ULONG(NTAPI * PREAD_DMA_COUNTER)(_In_ PDMA_ADAPTER DmaAdapter)
Definition: iotypes.h:2368
struct _SCATTER_GATHER_LIST * PSCATTER_GATHER_LIST
Definition: iotypes.h:2206
_Inout_ struct _IRP _In_ PVOID MapRegisterBase
Definition: iotypes.h:213
enum _IO_ALLOCATION_ACTION IO_ALLOCATION_ACTION
@ DeallocateObject
Definition: iotypes.h:203
@ KeepObject
Definition: iotypes.h:202
@ DeallocateObjectKeepRegisters
Definition: iotypes.h:204
DRIVER_LIST_CONTROL * PDRIVER_LIST_CONTROL
Definition: iotypes.h:2379
#define DEVICE_DESCRIPTION_VERSION1
Definition: iotypes.h:2064
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:2355
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:2421
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:2336
#define DEVICE_DESCRIPTION_VERSION2
Definition: iotypes.h:2065
_In_ struct _IRP _In_ struct _SCATTER_GATHER_LIST * ScatterGather
Definition: iotypes.h:2377
DRIVER_CONTROL * PDRIVER_CONTROL
Definition: iotypes.h:215
PVOID(NTAPI * PALLOCATE_COMMON_BUFFER)(_In_ PDMA_ADAPTER DmaAdapter, _In_ ULONG Length, _Out_ PPHYSICAL_ADDRESS LogicalAddress, _In_ BOOLEAN CacheEnabled)
Definition: iotypes.h:2313
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:2382
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:2399
VOID(NTAPI * PPUT_SCATTER_GATHER_LIST)(_In_ PDMA_ADAPTER DmaAdapter, _In_ PSCATTER_GATHER_LIST ScatterGather, _In_ BOOLEAN WriteToDevice)
Definition: iotypes.h:2393
VOID(NTAPI * PPUT_DMA_ADAPTER)(PDMA_ADAPTER DmaAdapter)
Definition: iotypes.h:2309
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:2328
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:2320
ULONG(NTAPI * PGET_DMA_ALIGNMENT)(_In_ PDMA_ADAPTER DmaAdapter)
Definition: iotypes.h:2364
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:778
_Inout_ PKDEVICE_QUEUE_ENTRY DeviceQueueEntry
Definition: kefuncs.h:327
@ Executive
Definition: ketypes.h:467
_In_opt_ PVOID DeferredContext
Definition: ketypes.h:739
#define MmGetMdlVirtualAddress(_Mdl)
#define MmGetSystemAddressForMdlSafe(_Mdl, _Priority)
#define BYTE_OFFSET(Va)
#define BYTES_TO_PAGES(Size)
#define MmGetMdlPfnArray(_Mdl)
_Must_inspect_result_ _In_ PHYSICAL_ADDRESS LowestAcceptableAddress
Definition: mmfuncs.h:214
@ MmCached
Definition: mmtypes.h:130
@ MmNonCached
Definition: mmtypes.h:129
#define ObDereferenceObject
Definition: obfuncs.h:203
#define ObReferenceObject
Definition: obfuncs.h:204