ReactOS  0.4.13-dev-257-gfabbd7c
dma.c
Go to the documentation of this file.
1 /*
2  * COPYRIGHT: See COPYING in the top level directory
3  * PROJECT: ReactOS kernel
4  * FILE: hal/halppc/generic/dma.c
5  * PURPOSE: DMA functions
6  * PROGRAMMERS: David Welch (welch@mcmail.com)
7  * Filip Navara (navaraf@reactos.com)
8  * UPDATE HISTORY:
9  * Created 22/05/98
10  */
11 
71 /* INCLUDES *****************************************************************/
72 
73 #include <hal.h>
74 #define NDEBUG
75 #include <debug.h>
76 
82 
83 static const ULONG_PTR HalpEisaPortPage[8] = {
84  FIELD_OFFSET(DMA_PAGE, Channel0),
85  FIELD_OFFSET(DMA_PAGE, Channel1),
86  FIELD_OFFSET(DMA_PAGE, Channel2),
87  FIELD_OFFSET(DMA_PAGE, Channel3),
88  0,
89  FIELD_OFFSET(DMA_PAGE, Channel5),
90  FIELD_OFFSET(DMA_PAGE, Channel6),
91  FIELD_OFFSET(DMA_PAGE, Channel7)
92 };
93 
95  sizeof(DMA_OPERATIONS),
99  NULL, /* Initialized in HalpInitDma() */
100  NULL, /* Initialized in HalpInitDma() */
101  NULL, /* Initialized in HalpInitDma() */
102  NULL, /* Initialized in HalpInitDma() */
103  NULL, /* Initialized in HalpInitDma() */
106  /* FIXME: Implement the S/G funtions. */
107  NULL /*(PGET_SCATTER_GATHER_LIST)HalGetScatterGatherList*/,
108  NULL /*(PPUT_SCATTER_GATHER_LIST)HalPutScatterGatherList*/,
109  NULL /*(PCALCULATE_SCATTER_GATHER_LIST_SIZE)HalCalculateScatterGatherListSize*/,
110  NULL /*(PBUILD_SCATTER_GATHER_LIST)HalBuildScatterGatherList*/,
111  NULL /*(PBUILD_MDL_FROM_SCATTER_GATHER_LIST)HalBuildMdlFromScatterGatherList*/
112 };
113 
114 #define MAX_MAP_REGISTERS 64
115 
116 #define TAG_DMA ' AMD'
117 
118 /* FUNCTIONS *****************************************************************/
119 
120 VOID
122 {
123  /*
124  * Initialize the DMA Operation table
125  */
131 
132  /*
133  * Check if Extended DMA is available. We're just going to do a random
134  * read and write.
135  */
136 
137  WRITE_PORT_UCHAR((PUCHAR)FIELD_OFFSET(EISA_CONTROL, DmaController2Pages.Channel2), 0x2A);
138  if (READ_PORT_UCHAR((PUCHAR)FIELD_OFFSET(EISA_CONTROL, DmaController2Pages.Channel2)) == 0x2A)
139  HalpEisaDma = TRUE;
140 
141  /*
142  * Intialize all the global variables and allocate master adapter with
143  * first map buffers.
144  */
145 
148 
150 
151  /*
152  * Setup the HalDispatchTable callback for creating PnP DMA adapters. It's
153  * used by IoGetDmaAdapter in the kernel.
154  */
155 
157 }
158 
168  IN PADAPTER_OBJECT AdapterObject)
169 {
170  PHYSICAL_ADDRESS HighestAddress;
171 
172  if (AdapterObject->MasterDevice)
173  {
174  if (AdapterObject->Dma64BitAddresses)
175  {
176  HighestAddress.QuadPart = 0xFFFFFFFFFFFFFFFFULL;
177  return HighestAddress;
178  }
179  else if (AdapterObject->Dma32BitAddresses)
180  {
181  HighestAddress.QuadPart = 0xFFFFFFFF;
182  return HighestAddress;
183  }
184  }
185 
186  HighestAddress.QuadPart = 0xFFFFFF;
187  return HighestAddress;
188 }
189 
204  IN PADAPTER_OBJECT AdapterObject,
205  IN ULONG SizeOfMapBuffers)
206 {
211  PHYSICAL_ADDRESS BoundryAddressMultiple;
212  KIRQL OldIrql;
213  ULONG MapRegisterCount;
214 
215  /* FIXME: Check if enough map register slots are available. */
216 
217  MapRegisterCount = BYTES_TO_PAGES(SizeOfMapBuffers);
218 
219  /*
220  * Allocate memory for the new map registers. For 32-bit adapters we use
221  * two passes in order not to waste scare resource (low memory).
222  */
223 
228  HighestAcceptableAddress.LowPart == 0xFFFFFFFF ? 0x1000000 : 0;
229  BoundryAddressMultiple.QuadPart = 0;
230 
232  MapRegisterCount << PAGE_SHIFT, LowestAcceptableAddress,
233  HighestAcceptableAddress, BoundryAddressMultiple, MmNonCached);
234 
236  {
239  MapRegisterCount << PAGE_SHIFT, LowestAcceptableAddress,
240  HighestAcceptableAddress, BoundryAddressMultiple, MmNonCached);
241  }
242 
243  if (VirtualAddress == NULL)
244  return FALSE;
245 
247 
248  /*
249  * All the following must be done with the master adapter lock held
250  * to prevent corruption.
251  */
252 
253  OldIrql = KfAcquireSpinLock(&AdapterObject->SpinLock);
254 
255  /*
256  * Setup map register entries for the buffer allocated. Each entry has
257  * a virtual and physical address and corresponds to PAGE_SIZE large
258  * buffer.
259  */
260 
261  if (MapRegisterCount > 0)
262  {
263  PROS_MAP_REGISTER_ENTRY CurrentEntry, PreviousEntry;
264 
265  CurrentEntry = AdapterObject->MapRegisterBase +
266  AdapterObject->NumberOfMapRegisters;
267  do
268  {
269  /*
270  * Leave one entry free for every non-contiguous memory region
271  * in the map register bitmap. This ensures that we can search
272  * using RtlFindClearBits for contiguous map register regions.
273  *
274  * Also for non-EISA DMA leave one free entry for every 64Kb
275  * break, because the DMA controller can handle only coniguous
276  * 64Kb regions.
277  */
278 
279  if (CurrentEntry != AdapterObject->MapRegisterBase)
280  {
281  PreviousEntry = CurrentEntry - 1;
282  if (PreviousEntry->PhysicalAddress.LowPart + PAGE_SIZE ==
284  {
285  if (!HalpEisaDma)
286  {
287  if ((PreviousEntry->PhysicalAddress.LowPart ^
288  PhysicalAddress.LowPart) & 0xFFFF0000)
289  {
290  CurrentEntry++;
291  AdapterObject->NumberOfMapRegisters++;
292  }
293  }
294  }
295  else
296  {
297  CurrentEntry++;
298  AdapterObject->NumberOfMapRegisters++;
299  }
300  }
301 
302  RtlClearBit(AdapterObject->MapRegisters,
303  CurrentEntry - AdapterObject->MapRegisterBase);
304  CurrentEntry->VirtualAddress = VirtualAddress;
305  CurrentEntry->PhysicalAddress = PhysicalAddress;
306 
309 
310  CurrentEntry++;
311  AdapterObject->NumberOfMapRegisters++;
312  MapRegisterCount--;
313  }
314  while (MapRegisterCount != 0);
315  }
316 
317  KfReleaseSpinLock(&AdapterObject->SpinLock, OldIrql);
318 
319  return TRUE;
320 }
321 
333 {
334  PADAPTER_OBJECT MasterAdapter;
335  ULONG Size, SizeOfBitmap;
336 
337  SizeOfBitmap = MAX_MAP_REGISTERS;
338  Size = sizeof(ADAPTER_OBJECT);
339  Size += sizeof(RTL_BITMAP);
340  Size += (SizeOfBitmap + 7) >> 3;
341 
342  MasterAdapter = ExAllocatePoolWithTag(NonPagedPool, Size, TAG_DMA);
343  if (MasterAdapter == NULL)
344  return NULL;
345 
346  RtlZeroMemory(MasterAdapter, Size);
347 
348  KeInitializeSpinLock(&MasterAdapter->SpinLock);
349  InitializeListHead(&MasterAdapter->AdapterQueue);
350 
351  MasterAdapter->MapRegisters = (PVOID)(MasterAdapter + 1);
353  MasterAdapter->MapRegisters,
354  (PULONG)(MasterAdapter->MapRegisters + 1),
355  SizeOfBitmap);
356  RtlSetAllBits(MasterAdapter->MapRegisters);
357  MasterAdapter->NumberOfMapRegisters = 0;
358  MasterAdapter->CommittedMapRegisters = 0;
359 
360  MasterAdapter->MapRegisterBase = ExAllocatePoolWithTag(
361  NonPagedPool,
362  SizeOfBitmap * sizeof(ROS_MAP_REGISTER_ENTRY),
363  TAG_DMA);
364  if (MasterAdapter->MapRegisterBase == NULL)
365  {
366  ExFreePool(MasterAdapter);
367  return NULL;
368  }
369 
370  RtlZeroMemory(MasterAdapter->MapRegisterBase,
371  SizeOfBitmap * sizeof(ROS_MAP_REGISTER_ENTRY));
372  if (!HalpGrowMapBuffers(MasterAdapter, 0x10000))
373  {
374  ExFreePool(MasterAdapter);
375  return NULL;
376  }
377 
378  return MasterAdapter;
379 }
380 
394 {
395  PADAPTER_OBJECT AdapterObject;
398  HANDLE Handle;
399 
402  NULL,
404  NULL,
405  NULL);
406 
408  KernelMode,
411  KernelMode,
412  NULL,
413  sizeof(ADAPTER_OBJECT),
414  0,
415  0,
416  (PVOID)&AdapterObject);
417  if (!NT_SUCCESS(Status))
418  return NULL;
419 
421  AdapterObject,
424  KernelMode);
425  if (!NT_SUCCESS(Status))
426  return NULL;
427 
428  RtlZeroMemory(AdapterObject, sizeof(ADAPTER_OBJECT));
429 
431  AdapterObject,
432  NULL,
434  0,
435  NULL,
436  &Handle);
437  if (!NT_SUCCESS(Status))
438  return NULL;
439 
440  ZwClose(Handle);
441 
442  AdapterObject->DmaHeader.Version = (USHORT)DeviceDescription->Version;
443  AdapterObject->DmaHeader.Size = sizeof(ADAPTER_OBJECT);
444  AdapterObject->DmaHeader.DmaOperations = &HalpDmaOperations;
445  AdapterObject->MapRegistersPerChannel = 1;
446  AdapterObject->Dma32BitAddresses = DeviceDescription->Dma32BitAddresses;
447  AdapterObject->ChannelNumber = 0xFF;
448  AdapterObject->MasterAdapter = HalpMasterAdapter;
449  KeInitializeDeviceQueue(&AdapterObject->ChannelWaitQueue);
450 
451  return AdapterObject;
452 }
453 
462  PADAPTER_OBJECT AdapterObject,
464 {
465  UCHAR Controller;
466  DMA_MODE DmaMode = {{0 }};
467  DMA_EXTENDED_MODE ExtendedMode = {{ 0 }};
468  PVOID AdapterBaseVa;
469 
470  Controller = (DeviceDescription->DmaChannel & 4) ? 2 : 1;
471 
472  if (Controller == 1)
473  AdapterBaseVa = (PVOID)FIELD_OFFSET(EISA_CONTROL, DmaController1);
474  else
475  AdapterBaseVa = (PVOID)FIELD_OFFSET(EISA_CONTROL, DmaController2);
476 
477  AdapterObject->AdapterNumber = Controller;
478  AdapterObject->ChannelNumber = (UCHAR)(DeviceDescription->DmaChannel & 3);
479  AdapterObject->PagePort = (PUCHAR)HalpEisaPortPage[DeviceDescription->DmaChannel];
480  AdapterObject->Width16Bits = FALSE;
481  AdapterObject->AdapterBaseVa = AdapterBaseVa;
482 
483  if (HalpEisaDma)
484  {
485  ExtendedMode.ChannelNumber = AdapterObject->ChannelNumber;
486 
487  switch (DeviceDescription->DmaSpeed)
488  {
489  case Compatible: ExtendedMode.TimingMode = COMPATIBLE_TIMING; break;
490  case TypeA: ExtendedMode.TimingMode = TYPE_A_TIMING; break;
491  case TypeB: ExtendedMode.TimingMode = TYPE_B_TIMING; break;
492  case TypeC: ExtendedMode.TimingMode = BURST_TIMING; break;
493  default:
494  return FALSE;
495  }
496 
497  switch (DeviceDescription->DmaWidth)
498  {
499  case Width8Bits: ExtendedMode.TransferSize = B_8BITS; break;
500  case Width16Bits: ExtendedMode.TransferSize = B_16BITS; break;
501  case Width32Bits: ExtendedMode.TransferSize = B_32BITS; break;
502  default:
503  return FALSE;
504  }
505 
506  if (Controller == 1)
507  WRITE_PORT_UCHAR((PUCHAR)FIELD_OFFSET(EISA_CONTROL, DmaExtendedMode1),
508  ExtendedMode.Byte);
509  else
510  WRITE_PORT_UCHAR((PUCHAR)FIELD_OFFSET(EISA_CONTROL, DmaExtendedMode2),
511  ExtendedMode.Byte);
512  }
513  else
514  {
515  /*
516  * Validate setup for non-busmaster DMA adapter. Secondary controller
517  * supports only 16-bit transfers and main controller supports only
518  * 8-bit transfers. Anything else is invalid.
519  */
520 
522  {
523  if (Controller == 2 && DeviceDescription->DmaWidth == Width16Bits)
524  AdapterObject->Width16Bits = TRUE;
525  else if (Controller != 1 || DeviceDescription->DmaWidth != Width8Bits)
526  return FALSE;
527  }
528  }
529 
530  DmaMode.Channel = AdapterObject->ChannelNumber;
532 
533  /*
534  * Set the DMA request mode.
535  *
536  * For (E)ISA bus master devices just unmask (enable) the DMA channel
537  * and set it to cascade mode. Otherwise just select the right one
538  * bases on the passed device description.
539  */
540 
542  {
544  if (Controller == 1)
545  {
546  /* Set the Request Data */
547  WRITE_PORT_UCHAR(&((PDMA1_CONTROL)AdapterBaseVa)->Mode,
548  DmaMode.Byte);
549  /* Unmask DMA Channel */
550  WRITE_PORT_UCHAR(&((PDMA1_CONTROL)AdapterBaseVa)->SingleMask,
551  AdapterObject->ChannelNumber | DMA_CLEARMASK);
552  } else {
553  /* Set the Request Data */
554  WRITE_PORT_UCHAR(&((PDMA2_CONTROL)AdapterBaseVa)->Mode,
555  DmaMode.Byte);
556  /* Unmask DMA Channel */
557  WRITE_PORT_UCHAR(&((PDMA2_CONTROL)AdapterBaseVa)->SingleMask,
558  AdapterObject->ChannelNumber | DMA_CLEARMASK);
559  }
560  }
561  else
562  {
565  else
567  }
568 
569  AdapterObject->AdapterMode = DmaMode;
570 
571  return TRUE;
572 }
573 
594 {
595  PADAPTER_OBJECT AdapterObject = NULL;
596  PADAPTER_OBJECT MasterAdapter;
598  ULONG MapRegisters;
600 
601  /* Validate parameters in device description */
603  return NULL;
604 
605  /*
606  * See if we're going to use ISA/EISA DMA adapter. These adapters are
607  * special since they're reused.
608  *
609  * Also note that we check for channel number since there are only 8 DMA
610  * channels on ISA, so any request above this requires new adapter.
611  */
612 
614  {
617  EisaAdapter = FALSE;
618  else
619  EisaAdapter = TRUE;
620  }
621  else
622  {
623  EisaAdapter = FALSE;
624  }
625 
626  /*
627  * Disallow creating adapter for ISA/EISA DMA channel 4 since it's used
628  * for cascading the controllers and it's not available for software use.
629  */
630 
632  return NULL;
633 
634  /*
635  * Calculate the number of map registers.
636  *
637  * - For EISA and PCI scatter/gather no map registers are needed.
638  * - For ISA slave scatter/gather one map register is needed.
639  * - For all other cases the number of map registers depends on
640  * DeviceDescription->MaximumLength.
641  */
642 
647  {
648  MapRegisters = 0;
649  }
650  else if (DeviceDescription->ScatterGather &&
652  {
653  MapRegisters = 1;
654  }
655  else
656  {
657  /*
658  * In the equation below the additional map register added by
659  * the "+1" accounts for the case when a transfer does not start
660  * at a page-aligned address.
661  */
662  MapRegisters = BYTES_TO_PAGES(MaximumLength) + 1;
663  if (MapRegisters > 16)
664  MapRegisters = 16;
665  }
666 
667  /*
668  * Acquire the DMA lock that is used to protect adapter lists and
669  * EISA adapter array.
670  */
671 
673  FALSE, NULL);
674 
675  /*
676  * Now we must get ahold of the adapter object. For first eight ISA/EISA
677  * channels there are static adapter objects that are reused and updated
678  * on succesive HalGetAdapter calls. In other cases a new adapter object
679  * is always created and it's to the DMA adapter list (HalpDmaAdapterList).
680  */
681 
682  if (EisaAdapter)
683  {
684  AdapterObject = HalpEisaAdapter[DeviceDescription->DmaChannel];
685  if (AdapterObject != NULL)
686  {
687  if (AdapterObject->NeedsMapRegisters &&
688  MapRegisters > AdapterObject->MapRegistersPerChannel)
689  AdapterObject->MapRegistersPerChannel = MapRegisters;
690  }
691  }
692 
693  if (AdapterObject == NULL)
694  {
695  AdapterObject = HalpDmaAllocateChildAdapter(
696  MapRegisters, DeviceDescription);
697  if (AdapterObject == NULL)
698  {
699  KeSetEvent(&HalpDmaLock, 0, 0);
700  return NULL;
701  }
702 
703  if (EisaAdapter)
704  {
705  HalpEisaAdapter[DeviceDescription->DmaChannel] = AdapterObject;
706  }
707 
708  if (MapRegisters > 0)
709  {
710  AdapterObject->NeedsMapRegisters = TRUE;
711  MasterAdapter = HalpMasterAdapter;
712  AdapterObject->MapRegistersPerChannel = MapRegisters;
713 
714  /*
715  * FIXME: Verify that the following makes sense. Actually
716  * MasterAdapter->NumberOfMapRegisters contains even the number
717  * of gaps, so this will not work correctly all the time. It
718  * doesn't matter much since it's only optimization to avoid
719  * queuing work items in HalAllocateAdapterChannel.
720  */
721 
722  MasterAdapter->CommittedMapRegisters += MapRegisters;
723  if (MasterAdapter->CommittedMapRegisters > MasterAdapter->NumberOfMapRegisters)
724  HalpGrowMapBuffers(MasterAdapter, 0x10000);
725  }
726  else
727  {
728  AdapterObject->NeedsMapRegisters = FALSE;
730  AdapterObject->MapRegistersPerChannel = BYTES_TO_PAGES(MaximumLength) + 1;
731  else
732  AdapterObject->MapRegistersPerChannel = 1;
733  }
734  }
735 
736  if (!EisaAdapter)
737  InsertTailList(&HalpDmaAdapterList, &AdapterObject->AdapterList);
738 
739  /*
740  * Release the DMA lock. HalpDmaAdapterList and HalpEisaAdapter will
741  * no longer be touched, so we don't need it.
742  */
743 
744  KeSetEvent(&HalpDmaLock, 0, 0);
745 
746  /*
747  * Setup the values in the adapter object that are common for all
748  * types of buses.
749  */
750 
752  AdapterObject->IgnoreCount = DeviceDescription->IgnoreCount;
753  else
754  AdapterObject->IgnoreCount = 0;
755 
756  AdapterObject->Dma32BitAddresses = DeviceDescription->Dma32BitAddresses;
757  AdapterObject->Dma64BitAddresses = DeviceDescription->Dma64BitAddresses;
758  AdapterObject->ScatterGather = DeviceDescription->ScatterGather;
759  AdapterObject->MasterDevice = DeviceDescription->Master;
760  *NumberOfMapRegisters = AdapterObject->MapRegistersPerChannel;
761 
762  /*
763  * For non-(E)ISA adapters we have already done all the work. On the
764  * other hand for (E)ISA adapters we must still setup the DMA modes
765  * and prepare the controller.
766  */
767 
768  if (EisaAdapter)
769  {
770  if (!HalpDmaInitializeEisaAdapter(AdapterObject, DeviceDescription))
771  {
772  ObDereferenceObject(AdapterObject);
773  return NULL;
774  }
775  }
776 
777  return AdapterObject;
778 }
779 
791  IN PVOID Context,
794 {
796 }
797 
807 VOID NTAPI
809  PADAPTER_OBJECT AdapterObject)
810 {
811  if (AdapterObject->ChannelNumber == 0xFF)
812  {
814  FALSE, NULL);
815  RemoveEntryList(&AdapterObject->AdapterList);
816  KeSetEvent(&HalpDmaLock, 0, 0);
817  }
818 
819  ObDereferenceObject(AdapterObject);
820 }
821 
848 PVOID NTAPI
850  PADAPTER_OBJECT AdapterObject,
851  ULONG Length,
852  PPHYSICAL_ADDRESS LogicalAddress,
853  BOOLEAN CacheEnabled)
854 {
857  PHYSICAL_ADDRESS BoundryAddressMultiple;
859 
863  BoundryAddressMultiple.QuadPart = 0;
864 
865  /*
866  * For bus-master DMA devices the buffer mustn't cross 4Gb boundary. For
867  * slave DMA devices the 64Kb boundary mustn't be crossed since the
868  * controller wouldn't be able to handle it.
869  */
870 
871  if (AdapterObject->MasterDevice)
872  BoundryAddressMultiple.HighPart = 1;
873  else
874  BoundryAddressMultiple.LowPart = 0x10000;
875 
878  BoundryAddressMultiple, CacheEnabled ? MmCached : MmNonCached);
879  if (VirtualAddress == NULL)
880  return NULL;
881 
882  *LogicalAddress = MmGetPhysicalAddress(VirtualAddress);
883 
884  return VirtualAddress;
885 }
886 
897 VOID NTAPI
899  PADAPTER_OBJECT AdapterObject,
900  ULONG Length,
901  PHYSICAL_ADDRESS LogicalAddress,
903  BOOLEAN CacheEnabled)
904 {
906 }
907 
917 ULONG NTAPI
919  PADAPTER_OBJECT AdapterObject)
920 {
921  return 1;
922 }
923 
924 /*
925  * @name HalReadDmaCounter
926  *
927  * Read DMA operation progress counter.
928  *
929  * @implemented
930  */
931 
932 ULONG NTAPI
934  PADAPTER_OBJECT AdapterObject)
935 {
936  KIRQL OldIrql;
937  ULONG Count, OldCount;
938 
939  ASSERT(!AdapterObject->MasterDevice);
940 
941  /*
942  * Acquire the master adapter lock since we're going to mess with the
943  * system DMA controller registers and we really don't want anyone
944  * to do the same at the same time.
945  */
946 
947  KeAcquireSpinLock(&AdapterObject->MasterAdapter->SpinLock, &OldIrql);
948 
949  /* Send the request to the specific controller. */
950  if (AdapterObject->AdapterNumber == 1)
951  {
952  PDMA1_CONTROL DmaControl1 = AdapterObject->AdapterBaseVa;
953 
954  Count = 0xffff00;
955  do
956  {
957  OldCount = Count;
958  /* Send Reset */
959  WRITE_PORT_UCHAR(&DmaControl1->ClearBytePointer, 0);
960  /* Read Count */
961  Count = READ_PORT_UCHAR(&DmaControl1->DmaAddressCount
962  [AdapterObject->ChannelNumber].DmaBaseCount);
963  Count |= READ_PORT_UCHAR(&DmaControl1->DmaAddressCount
964  [AdapterObject->ChannelNumber].DmaBaseCount) << 8;
965  }
966  while (0xffff00 & (OldCount ^ Count));
967  }
968  else
969  {
970  PDMA2_CONTROL DmaControl2 = AdapterObject->AdapterBaseVa;
971 
972  Count = 0xffff00;
973  do
974  {
975  OldCount = Count;
976  /* Send Reset */
977  WRITE_PORT_UCHAR(&DmaControl2->ClearBytePointer, 0);
978  /* Read Count */
979  Count = READ_PORT_UCHAR(&DmaControl2->DmaAddressCount
980  [AdapterObject->ChannelNumber].DmaBaseCount);
981  Count |= READ_PORT_UCHAR(&DmaControl2->DmaAddressCount
982  [AdapterObject->ChannelNumber].DmaBaseCount) << 8;
983  }
984  while (0xffff00 & (OldCount ^ Count));
985  }
986 
987  KeReleaseSpinLock(&AdapterObject->MasterAdapter->SpinLock, OldIrql);
988 
989  Count++;
990  Count &= 0xffff;
991  if (AdapterObject->Width16Bits)
992  Count *= 2;
993 
994  return Count;
995 }
996 
1004 VOID NTAPI
1006 {
1008  KIRQL OldIrql;
1009  BOOLEAN Succeeded;
1010 
1011  /*
1012  * Try to allocate new map registers for the adapter.
1013  *
1014  * NOTE: The NT implementation actually tries to allocate more map
1015  * registers than needed as an optimization.
1016  */
1017 
1019  FALSE, NULL);
1020  Succeeded = HalpGrowMapBuffers(WorkItem->AdapterObject->MasterAdapter,
1021  WorkItem->NumberOfMapRegisters);
1022  KeSetEvent(&HalpDmaLock, 0, 0);
1023 
1024  if (Succeeded)
1025  {
1026  /*
1027  * Flush the adapter queue now that new map registers are ready. The
1028  * easiest way to do that is to call IoFreeMapRegisters to not free
1029  * any registers. Note that we use the magic (PVOID)2 map register
1030  * base to bypass the parameter checking.
1031  */
1032 
1034  IoFreeMapRegisters(WorkItem->AdapterObject, (PVOID)2, 0);
1036  }
1037 
1038  ExFreePool(WorkItem);
1039 }
1040 
1068  PADAPTER_OBJECT AdapterObject,
1069  PWAIT_CONTEXT_BLOCK WaitContextBlock,
1072 {
1073  PADAPTER_OBJECT MasterAdapter;
1074  PGROW_WORK_ITEM WorkItem;
1075  ULONG Index = MAXULONG;
1076  ULONG Result;
1077  KIRQL OldIrql;
1078 
1080 
1081  /* Set up the wait context block in case we can't run right away. */
1082  WaitContextBlock->DeviceRoutine = ExecutionRoutine;
1083  WaitContextBlock->NumberOfMapRegisters = NumberOfMapRegisters;
1084 
1085  /* Returns true if queued, else returns false and sets the queue to busy */
1086  if (KeInsertDeviceQueue(&AdapterObject->ChannelWaitQueue, &WaitContextBlock->WaitQueueEntry))
1087  return STATUS_SUCCESS;
1088 
1089  MasterAdapter = AdapterObject->MasterAdapter;
1090 
1091  AdapterObject->NumberOfMapRegisters = NumberOfMapRegisters;
1092  AdapterObject->CurrentWcb = WaitContextBlock;
1093 
1094  if (NumberOfMapRegisters && AdapterObject->NeedsMapRegisters)
1095  {
1096  if (NumberOfMapRegisters > AdapterObject->MapRegistersPerChannel)
1097  {
1098  AdapterObject->NumberOfMapRegisters = 0;
1099  IoFreeAdapterChannel(AdapterObject);
1101  }
1102 
1103  /*
1104  * Get the map registers. This is partly complicated by the fact
1105  * that new map registers can only be allocated at PASSIVE_LEVEL
1106  * and we're currently at DISPATCH_LEVEL. The following code has
1107  * two code paths:
1108  *
1109  * - If there is no adapter queued for map register allocation,
1110  * try to see if enough contiguous map registers are present.
1111  * In case they're we can just get them and proceed further.
1112  *
1113  * - If some adapter is already present in the queue we must
1114  * respect the order of adapters asking for map registers and
1115  * so the fast case described above can't take place.
1116  * This case is also entered if not enough coniguous map
1117  * registers are present.
1118  *
1119  * A work queue item is allocated and queued, the adapter is
1120  * also queued into the master adapter queue. The worker
1121  * routine does the job of allocating the map registers at
1122  * PASSIVE_LEVEL and calling the ExecutionRoutine.
1123  */
1124 
1125  OldIrql = KfAcquireSpinLock(&MasterAdapter->SpinLock);
1126 
1127  if (IsListEmpty(&MasterAdapter->AdapterQueue))
1128  {
1130  MasterAdapter->MapRegisters, NumberOfMapRegisters, 0);
1131  if (Index != MAXULONG)
1132  {
1133  AdapterObject->MapRegisterBase =
1134  MasterAdapter->MapRegisterBase + Index;
1135  if (!AdapterObject->ScatterGather)
1136  {
1137  AdapterObject->MapRegisterBase =
1139  (ULONG_PTR)AdapterObject->MapRegisterBase |
1140  MAP_BASE_SW_SG);
1141  }
1142  }
1143  }
1144 
1145  if (Index == MAXULONG)
1146  {
1147  WorkItem = ExAllocatePoolWithTag(
1148  NonPagedPool, sizeof(GROW_WORK_ITEM), TAG_DMA);
1149  if (WorkItem == NULL)
1150  {
1151  KfReleaseSpinLock(&MasterAdapter->SpinLock, OldIrql);
1152  AdapterObject->NumberOfMapRegisters = 0;
1153  IoFreeAdapterChannel(AdapterObject);
1155  }
1156 
1157  InsertTailList(&MasterAdapter->AdapterQueue, &AdapterObject->AdapterQueue);
1158 
1160  &WorkItem->WorkQueueItem, HalpGrowMapBufferWorker, WorkItem);
1161  WorkItem->AdapterObject = AdapterObject;
1163 
1165 
1166  KfReleaseSpinLock(&MasterAdapter->SpinLock, OldIrql);
1167 
1168  return STATUS_SUCCESS;
1169  }
1170 
1171  KfReleaseSpinLock(&MasterAdapter->SpinLock, OldIrql);
1172  }
1173  else
1174  {
1175  AdapterObject->MapRegisterBase = NULL;
1176  AdapterObject->NumberOfMapRegisters = 0;
1177  }
1178 
1179  AdapterObject->CurrentWcb = WaitContextBlock;
1180 
1182  WaitContextBlock->DeviceObject, WaitContextBlock->CurrentIrp,
1183  AdapterObject->MapRegisterBase, WaitContextBlock->DeviceContext);
1184 
1185  /*
1186  * Possible return values:
1187  *
1188  * - KeepObject
1189  * Don't free any resources, the ADAPTER_OBJECT is still in use and
1190  * the caller will call IoFreeAdapterChannel later.
1191  *
1192  * - DeallocateObject
1193  * Deallocate the map registers and release the ADAPTER_OBJECT, so
1194  * someone else can use it.
1195  *
1196  * - DeallocateObjectKeepRegisters
1197  * Release the ADAPTER_OBJECT, but hang on to the map registers. The
1198  * client will later call IoFreeMapRegisters.
1199  *
1200  * NOTE:
1201  * IoFreeAdapterChannel runs the queue, so it must be called unless
1202  * the adapter object is not to be freed.
1203  */
1204 
1205  if (Result == DeallocateObject)
1206  {
1207  IoFreeAdapterChannel(AdapterObject);
1208  }
1210  {
1211  AdapterObject->NumberOfMapRegisters = 0;
1212  IoFreeAdapterChannel(AdapterObject);
1213  }
1214 
1215  return STATUS_SUCCESS;
1216 }
1217 
1237 VOID NTAPI
1239  PADAPTER_OBJECT AdapterObject)
1240 {
1241  PADAPTER_OBJECT MasterAdapter;
1243  PWAIT_CONTEXT_BLOCK WaitContextBlock;
1244  ULONG Index = MAXULONG;
1245  ULONG Result;
1246  KIRQL OldIrql;
1247 
1248  MasterAdapter = AdapterObject->MasterAdapter;
1249 
1250  for (;;)
1251  {
1252  /*
1253  * To keep map registers, call here with AdapterObject->
1254  * NumberOfMapRegisters set to zero. This trick is used in
1255  * HalAllocateAdapterChannel for example.
1256  */
1257  if (AdapterObject->NumberOfMapRegisters)
1258  {
1260  AdapterObject,
1261  AdapterObject->MapRegisterBase,
1262  AdapterObject->NumberOfMapRegisters);
1263  }
1264 
1265  DeviceQueueEntry = KeRemoveDeviceQueue(&AdapterObject->ChannelWaitQueue);
1266  if (DeviceQueueEntry == NULL)
1267  {
1268  break;
1269  }
1270 
1271  WaitContextBlock = CONTAINING_RECORD(
1274  WaitQueueEntry);
1275 
1276  AdapterObject->CurrentWcb = WaitContextBlock;
1277  AdapterObject->NumberOfMapRegisters = WaitContextBlock->NumberOfMapRegisters;
1278 
1279  if (WaitContextBlock->NumberOfMapRegisters &&
1280  AdapterObject->MasterAdapter)
1281  {
1282  OldIrql = KfAcquireSpinLock(&MasterAdapter->SpinLock);
1283 
1284  if (IsListEmpty(&MasterAdapter->AdapterQueue))
1285  {
1287  MasterAdapter->MapRegisters,
1288  WaitContextBlock->NumberOfMapRegisters, 0);
1289  if (Index != MAXULONG)
1290  {
1291  AdapterObject->MapRegisterBase =
1292  MasterAdapter->MapRegisterBase + Index;
1293  if (!AdapterObject->ScatterGather)
1294  {
1295  AdapterObject->MapRegisterBase =
1297  (ULONG_PTR)AdapterObject->MapRegisterBase |
1298  MAP_BASE_SW_SG);
1299  }
1300  }
1301  }
1302 
1303  if (Index == MAXULONG)
1304  {
1305  InsertTailList(&MasterAdapter->AdapterQueue, &AdapterObject->AdapterQueue);
1306  KfReleaseSpinLock(&MasterAdapter->SpinLock, OldIrql);
1307  break;
1308  }
1309 
1310  KfReleaseSpinLock(&MasterAdapter->SpinLock, OldIrql);
1311  }
1312  else
1313  {
1314  AdapterObject->MapRegisterBase = NULL;
1315  AdapterObject->NumberOfMapRegisters = 0;
1316  }
1317 
1318  /* Call the adapter control routine. */
1319  Result = ((PDRIVER_CONTROL)WaitContextBlock->DeviceRoutine)(
1320  WaitContextBlock->DeviceObject, WaitContextBlock->CurrentIrp,
1321  AdapterObject->MapRegisterBase, WaitContextBlock->DeviceContext);
1322 
1323  switch (Result)
1324  {
1325  case KeepObject:
1326  /*
1327  * We're done until the caller manually calls IoFreeAdapterChannel
1328  * or IoFreeMapRegisters.
1329  */
1330  return;
1331 
1333  /*
1334  * Hide the map registers so they aren't deallocated next time
1335  * around.
1336  */
1337  AdapterObject->NumberOfMapRegisters = 0;
1338  break;
1339 
1340  default:
1341  break;
1342  }
1343  }
1344 }
1345 
1361 VOID NTAPI
1363  IN PADAPTER_OBJECT AdapterObject,
1366 {
1367  PADAPTER_OBJECT MasterAdapter = AdapterObject->MasterAdapter;
1368  PLIST_ENTRY ListEntry;
1369  KIRQL OldIrql;
1370  ULONG Index;
1371  ULONG Result;
1372 
1374 
1375  if (MasterAdapter == NULL || MapRegisterBase == NULL)
1376  return;
1377 
1378  OldIrql = KfAcquireSpinLock(&MasterAdapter->SpinLock);
1379 
1380  if (NumberOfMapRegisters != 0)
1381  {
1382  PROS_MAP_REGISTER_ENTRY RealMapRegisterBase;
1383 
1384  RealMapRegisterBase =
1386  RtlClearBits(MasterAdapter->MapRegisters,
1387  RealMapRegisterBase - MasterAdapter->MapRegisterBase,
1389  }
1390 
1391  /*
1392  * Now that we freed few map registers it's time to look at the master
1393  * adapter queue and see if there is someone waiting for map registers.
1394  */
1395 
1396  while (!IsListEmpty(&MasterAdapter->AdapterQueue))
1397  {
1398  ListEntry = RemoveHeadList(&MasterAdapter->AdapterQueue);
1399  AdapterObject = CONTAINING_RECORD(
1400  ListEntry, struct _ADAPTER_OBJECT, AdapterQueue);
1401 
1403  MasterAdapter->MapRegisters,
1404  AdapterObject->NumberOfMapRegisters,
1405  MasterAdapter->NumberOfMapRegisters);
1406  if (Index == MAXULONG)
1407  {
1408  InsertHeadList(&MasterAdapter->AdapterQueue, ListEntry);
1409  break;
1410  }
1411 
1412  KfReleaseSpinLock(&MasterAdapter->SpinLock, OldIrql);
1413 
1414  AdapterObject->MapRegisterBase =
1415  MasterAdapter->MapRegisterBase + Index;
1416  if (!AdapterObject->ScatterGather)
1417  {
1418  AdapterObject->MapRegisterBase =
1420  (ULONG_PTR)AdapterObject->MapRegisterBase |
1421  MAP_BASE_SW_SG);
1422  }
1423 
1424  Result = ((PDRIVER_CONTROL)AdapterObject->CurrentWcb->DeviceRoutine)(
1425  AdapterObject->CurrentWcb->DeviceObject,
1426  AdapterObject->CurrentWcb->CurrentIrp,
1427  AdapterObject->MapRegisterBase,
1428  AdapterObject->CurrentWcb->DeviceContext);
1429 
1430  switch (Result)
1431  {
1433  AdapterObject->NumberOfMapRegisters = 0;
1434  /* fall through */
1435 
1436  case DeallocateObject:
1437  if (AdapterObject->NumberOfMapRegisters)
1438  {
1439  OldIrql = KfAcquireSpinLock(&MasterAdapter->SpinLock);
1440  RtlClearBits(MasterAdapter->MapRegisters,
1441  AdapterObject->MapRegisterBase -
1442  MasterAdapter->MapRegisterBase,
1443  AdapterObject->NumberOfMapRegisters);
1444  KfReleaseSpinLock(&MasterAdapter->SpinLock, OldIrql);
1445  }
1446  IoFreeAdapterChannel(AdapterObject);
1447  break;
1448 
1449  default:
1450  break;
1451  }
1452 
1453  OldIrql = KfAcquireSpinLock(&MasterAdapter->SpinLock);
1454  }
1455 
1456  KfReleaseSpinLock(&MasterAdapter->SpinLock, OldIrql);
1457 }
1458 
1467 VOID NTAPI
1469  PMDL Mdl,
1471  PVOID CurrentVa,
1472  ULONG Length,
1473  BOOLEAN WriteToDevice)
1474 {
1475  ULONG CurrentLength;
1476  ULONG_PTR CurrentAddress;
1477  ULONG ByteOffset;
1479 
1481  if (VirtualAddress == NULL)
1482  {
1483  /*
1484  * NOTE: On real NT a mechanism with reserved pages is implemented
1485  * to handle this case in a slow, but graceful non-fatal way.
1486  */
1487  KeBugCheckEx(HAL_MEMORY_ALLOCATION, PAGE_SIZE, 0, (ULONG_PTR)__FILE__, 0);
1488  }
1489 
1490  CurrentAddress = (ULONG_PTR)VirtualAddress +
1491  (ULONG_PTR)CurrentVa -
1493 
1494  while (Length > 0)
1495  {
1496  ByteOffset = BYTE_OFFSET(CurrentAddress);
1497  CurrentLength = PAGE_SIZE - ByteOffset;
1498  if (CurrentLength > Length)
1499  CurrentLength = Length;
1500 
1501  if (WriteToDevice)
1502  {
1503  RtlCopyMemory(
1504  (PVOID)((ULONG_PTR)MapRegisterBase->VirtualAddress + ByteOffset),
1505  (PVOID)CurrentAddress,
1506  CurrentLength);
1507  }
1508  else
1509  {
1510  RtlCopyMemory(
1511  (PVOID)CurrentAddress,
1512  (PVOID)((ULONG_PTR)MapRegisterBase->VirtualAddress + ByteOffset),
1513  CurrentLength);
1514  }
1515 
1516  Length -= CurrentLength;
1517  CurrentAddress += CurrentLength;
1518  MapRegisterBase++;
1519  }
1520 }
1521 
1554 BOOLEAN NTAPI
1556  PADAPTER_OBJECT AdapterObject,
1557  PMDL Mdl,
1559  PVOID CurrentVa,
1560  ULONG Length,
1561  BOOLEAN WriteToDevice)
1562 {
1563  BOOLEAN SlaveDma = FALSE;
1564  PROS_MAP_REGISTER_ENTRY RealMapRegisterBase;
1567  PPFN_NUMBER MdlPagesPtr;
1568 
1570 
1571  if (AdapterObject != NULL && !AdapterObject->MasterDevice)
1572  {
1573  /* Mask out (disable) the DMA channel. */
1574  if (AdapterObject->AdapterNumber == 1)
1575  {
1576  PDMA1_CONTROL DmaControl1 = AdapterObject->AdapterBaseVa;
1577  WRITE_PORT_UCHAR(&DmaControl1->SingleMask,
1578  AdapterObject->ChannelNumber | DMA_SETMASK);
1579  }
1580  else
1581  {
1582  PDMA2_CONTROL DmaControl2 = AdapterObject->AdapterBaseVa;
1583  WRITE_PORT_UCHAR(&DmaControl2->SingleMask,
1584  AdapterObject->ChannelNumber | DMA_SETMASK);
1585  }
1586  SlaveDma = TRUE;
1587  }
1588 
1589  /* This can happen if the device supports hardware scatter/gather. */
1590  if (MapRegisterBase == NULL)
1591  return TRUE;
1592 
1593  RealMapRegisterBase =
1595 
1596  if (!WriteToDevice)
1597  {
1599  {
1600  if (RealMapRegisterBase->Counter != MAXULONG)
1601  {
1602  if (SlaveDma && !AdapterObject->IgnoreCount)
1603  Length -= HalReadDmaCounter(AdapterObject);
1604  HalpCopyBufferMap(Mdl, RealMapRegisterBase, CurrentVa, Length, FALSE);
1605  }
1606  }
1607  else
1608  {
1609  MdlPagesPtr = MmGetMdlPfnArray(Mdl);
1610  MdlPagesPtr += ((ULONG_PTR)CurrentVa - (ULONG_PTR)Mdl->StartVa) >> PAGE_SHIFT;
1611 
1612  PhysicalAddress.QuadPart = *MdlPagesPtr << PAGE_SHIFT;
1613  PhysicalAddress.QuadPart += BYTE_OFFSET(CurrentVa);
1614 
1617  HighestAcceptableAddress.QuadPart)
1618  {
1619  HalpCopyBufferMap(Mdl, RealMapRegisterBase, CurrentVa, Length, FALSE);
1620  }
1621  }
1622  }
1623 
1624  RealMapRegisterBase->Counter = 0;
1625 
1626  return TRUE;
1627 }
1628 
1663  IN PADAPTER_OBJECT AdapterObject,
1664  IN PMDL Mdl,
1666  IN PVOID CurrentVa,
1667  IN OUT PULONG Length,
1668  IN BOOLEAN WriteToDevice)
1669 {
1670  PPFN_NUMBER MdlPagesPtr;
1671  PFN_NUMBER MdlPage1, MdlPage2;
1672  ULONG ByteOffset;
1673  ULONG TransferOffset;
1674  ULONG TransferLength;
1675  BOOLEAN UseMapRegisters;
1676  PROS_MAP_REGISTER_ENTRY RealMapRegisterBase;
1679  ULONG Counter;
1680  DMA_MODE AdapterMode;
1681  KIRQL OldIrql;
1682 
1683  /*
1684  * Precalculate some values that are used in all cases.
1685  *
1686  * ByteOffset is offset inside the page at which the transfer starts.
1687  * MdlPagesPtr is pointer inside the MDL page chain at the page where the
1688  * transfer start.
1689  * PhysicalAddress is physical address corresponding to the transfer
1690  * start page and offset.
1691  * TransferLength is the initial length of the transfer, which is reminder
1692  * of the first page. The actual value is calculated below.
1693  *
1694  * Note that all the variables can change during the processing which
1695  * takes place below. These are just initial values.
1696  */
1697 
1698  ByteOffset = BYTE_OFFSET(CurrentVa);
1699 
1700  MdlPagesPtr = MmGetMdlPfnArray(Mdl);
1701  MdlPagesPtr += ((ULONG_PTR)CurrentVa - (ULONG_PTR)Mdl->StartVa) >> PAGE_SHIFT;
1702 
1703  PhysicalAddress.QuadPart = *MdlPagesPtr << PAGE_SHIFT;
1705 
1706  TransferLength = PAGE_SIZE - ByteOffset;
1707 
1708  /*
1709  * Special case for bus master adapters with S/G support. We can directly
1710  * use the buffer specified by the MDL, so not much work has to be done.
1711  *
1712  * Just return the passed VA's corresponding physical address and update
1713  * length to the number of physically contiguous bytes found. Also
1714  * pages crossing the 4Gb boundary aren't considered physically contiguous.
1715  */
1716 
1717  if (MapRegisterBase == NULL)
1718  {
1719  while (TransferLength < *Length)
1720  {
1721  MdlPage1 = *MdlPagesPtr;
1722  MdlPage2 = *(MdlPagesPtr + 1);
1723  if (MdlPage1 + 1 != MdlPage2)
1724  break;
1725  if ((MdlPage1 ^ MdlPage2) & ~0xFFFFF)
1726  break;
1727  TransferLength += PAGE_SIZE;
1728  MdlPagesPtr++;
1729  }
1730 
1731  if (TransferLength < *Length)
1732  *Length = TransferLength;
1733 
1734  return PhysicalAddress;
1735  }
1736 
1737  /*
1738  * The code below applies to slave DMA adapters and bus master adapters
1739  * without hardward S/G support.
1740  */
1741 
1742  RealMapRegisterBase =
1744 
1745  /*
1746  * Try to calculate the size of the transfer. We can only transfer
1747  * pages that are physically contiguous and that don't cross the
1748  * 64Kb boundary (this limitation applies only for ISA controllers).
1749  */
1750 
1751  while (TransferLength < *Length)
1752  {
1753  MdlPage1 = *MdlPagesPtr;
1754  MdlPage2 = *(MdlPagesPtr + 1);
1755  if (MdlPage1 + 1 != MdlPage2)
1756  break;
1757  if (!HalpEisaDma && ((MdlPage1 ^ MdlPage2) & ~0xF))
1758  break;
1759  TransferLength += PAGE_SIZE;
1760  MdlPagesPtr++;
1761  }
1762 
1763  if (TransferLength > *Length)
1764  TransferLength = *Length;
1765 
1766  /*
1767  * If we're about to simulate software S/G and not all the pages are
1768  * physically contiguous then we must use the map registers to store
1769  * the data and allow the whole transfer to proceed at once.
1770  */
1771 
1773  TransferLength < *Length)
1774  {
1775  UseMapRegisters = TRUE;
1776  PhysicalAddress = RealMapRegisterBase->PhysicalAddress;
1778  TransferLength = *Length;
1779  RealMapRegisterBase->Counter = MAXULONG;
1780  Counter = 0;
1781  }
1782  else
1783  {
1784  /*
1785  * This is ordinary DMA transfer, so just update the progress
1786  * counters. These are used by IoFlushAdapterBuffers to track
1787  * the transfer progress.
1788  */
1789 
1790  UseMapRegisters = FALSE;
1791  Counter = RealMapRegisterBase->Counter;
1792  RealMapRegisterBase->Counter += BYTES_TO_PAGES(ByteOffset + TransferLength);
1793 
1794  /*
1795  * Check if the buffer doesn't exceed the highest physical address
1796  * limit of the device. In that case we must use the map registers to
1797  * store the data.
1798  */
1799 
1801  if (PhysicalAddress.QuadPart + TransferLength >
1802  HighestAcceptableAddress.QuadPart)
1803  {
1804  UseMapRegisters = TRUE;
1805  PhysicalAddress = RealMapRegisterBase[Counter].PhysicalAddress;
1808  {
1809  RealMapRegisterBase->Counter = MAXULONG;
1810  Counter = 0;
1811  }
1812  }
1813  }
1814 
1815  /*
1816  * If we decided to use the map registers (see above) and we're about
1817  * to transfer data to the device then copy the buffers into the map
1818  * register memory.
1819  */
1820 
1821  if (UseMapRegisters && WriteToDevice)
1822  {
1823  HalpCopyBufferMap(Mdl, RealMapRegisterBase + Counter,
1824  CurrentVa, TransferLength, WriteToDevice);
1825  }
1826 
1827  /*
1828  * Return the length of transfer that actually takes place.
1829  */
1830 
1831  *Length = TransferLength;
1832 
1833  /*
1834  * If we're doing slave (system) DMA then program the (E)ISA controller
1835  * to actually start the transfer.
1836  */
1837 
1838  if (AdapterObject != NULL && !AdapterObject->MasterDevice)
1839  {
1840  AdapterMode = AdapterObject->AdapterMode;
1841 
1842  if (WriteToDevice)
1843  {
1844  AdapterMode.TransferType = WRITE_TRANSFER;
1845  }
1846  else
1847  {
1848  AdapterMode.TransferType = READ_TRANSFER;
1849  if (AdapterObject->IgnoreCount)
1850  {
1851  RtlZeroMemory((PUCHAR)RealMapRegisterBase[Counter].VirtualAddress +
1852  ByteOffset, TransferLength);
1853  }
1854  }
1855 
1856  TransferOffset = PhysicalAddress.LowPart & 0xFFFF;
1857  if (AdapterObject->Width16Bits)
1858  {
1859  TransferLength >>= 1;
1860  TransferOffset >>= 1;
1861  }
1862 
1863  OldIrql = KfAcquireSpinLock(&AdapterObject->MasterAdapter->SpinLock);
1864 
1865  if (AdapterObject->AdapterNumber == 1)
1866  {
1867  PDMA1_CONTROL DmaControl1 = AdapterObject->AdapterBaseVa;
1868 
1869  /* Reset Register */
1870  WRITE_PORT_UCHAR(&DmaControl1->ClearBytePointer, 0);
1871  /* Set the Mode */
1872  WRITE_PORT_UCHAR(&DmaControl1->Mode, AdapterMode.Byte);
1873  /* Set the Offset Register */
1874  WRITE_PORT_UCHAR(&DmaControl1->DmaAddressCount[AdapterObject->ChannelNumber].DmaBaseAddress,
1875  (UCHAR)(TransferOffset));
1876  WRITE_PORT_UCHAR(&DmaControl1->DmaAddressCount[AdapterObject->ChannelNumber].DmaBaseAddress,
1877  (UCHAR)(TransferOffset >> 8));
1878  /* Set the Page Register */
1879  WRITE_PORT_UCHAR(AdapterObject->PagePort +
1880  FIELD_OFFSET(EISA_CONTROL, DmaController1Pages),
1881  (UCHAR)(PhysicalAddress.LowPart >> 16));
1882  if (HalpEisaDma)
1883  {
1884  WRITE_PORT_UCHAR(AdapterObject->PagePort +
1885  FIELD_OFFSET(EISA_CONTROL, DmaController2Pages),
1886  0);
1887  }
1888  /* Set the Length */
1889  WRITE_PORT_UCHAR(&DmaControl1->DmaAddressCount[AdapterObject->ChannelNumber].DmaBaseCount,
1890  (UCHAR)(TransferLength - 1));
1891  WRITE_PORT_UCHAR(&DmaControl1->DmaAddressCount[AdapterObject->ChannelNumber].DmaBaseCount,
1892  (UCHAR)((TransferLength - 1) >> 8));
1893  /* Unmask the Channel */
1894  WRITE_PORT_UCHAR(&DmaControl1->SingleMask,
1895  AdapterObject->ChannelNumber | DMA_CLEARMASK);
1896  }
1897  else
1898  {
1899  PDMA2_CONTROL DmaControl2 = AdapterObject->AdapterBaseVa;
1900 
1901  /* Reset Register */
1902  WRITE_PORT_UCHAR(&DmaControl2->ClearBytePointer, 0);
1903  /* Set the Mode */
1904  WRITE_PORT_UCHAR(&DmaControl2->Mode, AdapterMode.Byte);
1905  /* Set the Offset Register */
1906  WRITE_PORT_UCHAR(&DmaControl2->DmaAddressCount[AdapterObject->ChannelNumber].DmaBaseAddress,
1907  (UCHAR)(TransferOffset));
1908  WRITE_PORT_UCHAR(&DmaControl2->DmaAddressCount[AdapterObject->ChannelNumber].DmaBaseAddress,
1909  (UCHAR)(TransferOffset >> 8));
1910  /* Set the Page Register */
1911  WRITE_PORT_UCHAR(AdapterObject->PagePort +
1912  FIELD_OFFSET(EISA_CONTROL, DmaController1Pages),
1913  (UCHAR)(PhysicalAddress.u.LowPart >> 16));
1914  if (HalpEisaDma)
1915  {
1916  WRITE_PORT_UCHAR(AdapterObject->PagePort +
1917  FIELD_OFFSET(EISA_CONTROL, DmaController2Pages),
1918  0);
1919  }
1920  /* Set the Length */
1921  WRITE_PORT_UCHAR(&DmaControl2->DmaAddressCount[AdapterObject->ChannelNumber].DmaBaseCount,
1922  (UCHAR)(TransferLength - 1));
1923  WRITE_PORT_UCHAR(&DmaControl2->DmaAddressCount[AdapterObject->ChannelNumber].DmaBaseCount,
1924  (UCHAR)((TransferLength - 1) >> 8));
1925  /* Unmask the Channel */
1926  WRITE_PORT_UCHAR(&DmaControl2->SingleMask,
1927  AdapterObject->ChannelNumber | DMA_CLEARMASK);
1928  }
1929 
1930  KfReleaseSpinLock(&AdapterObject->MasterAdapter->SpinLock, OldIrql);
1931  }
1932 
1933  /*
1934  * Return physical address of the buffer with data that is used for the
1935  * transfer. It can either point inside the Mdl that was passed by the
1936  * caller or into the map registers if the Mdl buffer can't be used
1937  * directly.
1938  */
1939 
1940  return PhysicalAddress;
1941 }
1942 
1948 BOOLEAN
1949 NTAPI
1951  IN ULONG Length,
1952  IN PHYSICAL_ADDRESS LogicalAddress,
1954 {
1955  /* Function always returns true */
1956  return TRUE;
1957 }
1958 
1959 /*
1960  * @implemented
1961  */
1962 PVOID
1963 NTAPI
1966 {
1967  PADAPTER_OBJECT MasterAdapter = AdapterObject->MasterAdapter;
1968  ULONG MapRegisterNumber;
1969 
1970  /* Check if it needs map registers */
1971  if (AdapterObject->NeedsMapRegisters)
1972  {
1973  /* Check if we have enough */
1974  if (*NumberOfMapRegisters > AdapterObject->MapRegistersPerChannel)
1975  {
1976  /* We don't, fail */
1977  AdapterObject->NumberOfMapRegisters = 0;
1978  return NULL;
1979  }
1980 
1981  /* Try to find free map registers */
1982  MapRegisterNumber = MAXULONG;
1983  MapRegisterNumber = RtlFindClearBitsAndSet(MasterAdapter->MapRegisters,
1985  0);
1986 
1987  /* Check if nothing was found */
1988  if (MapRegisterNumber == MAXULONG)
1989  {
1990  /* No free registers found, so use the base registers */
1991  RtlSetBits(MasterAdapter->MapRegisters,
1992  0,
1994  MapRegisterNumber = 0;
1995  }
1996 
1997  /* Calculate the new base */
1998  AdapterObject->MapRegisterBase =
1999  (PROS_MAP_REGISTER_ENTRY)(MasterAdapter->MapRegisterBase +
2000  MapRegisterNumber);
2001 
2002  /* Check if scatter gather isn't supported */
2003  if (!AdapterObject->ScatterGather)
2004  {
2005  /* Set the flag */
2006  AdapterObject->MapRegisterBase =
2008  ((ULONG_PTR)AdapterObject->MapRegisterBase | MAP_BASE_SW_SG);
2009  }
2010  }
2011  else
2012  {
2013  AdapterObject->MapRegisterBase = NULL;
2014  AdapterObject->NumberOfMapRegisters = 0;
2015  }
2016 
2017  /* Return the base */
2018  return AdapterObject->MapRegisterBase;
2019 }
2020 
2021 /* EOF */
#define DMA_SETMASK
Definition: haldma.h:174
UCHAR DmaBaseCount
Definition: haldma.h:184
#define KeGetCurrentIrql()
Definition: env_spec_w32.h:706
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
static LIST_ENTRY HalpDmaAdapterList
Definition: dma.c:78
#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:2194
#define PAGE_SHIFT
Definition: env_spec_w32.h:45
#define HalGetDmaAdapter
Definition: haltypes.h:291
#define IN
Definition: typedefs.h:38
NTSYSAPI void WINAPI RtlClearBits(PRTL_BITMAP, ULONG, ULONG)
#define TYPE_A_TIMING
Definition: haldma.h:150
UCHAR AutoInitialize
Definition: haldma.h:95
#define KeRaiseIrql(irql, oldIrql)
Definition: env_spec_w32.h:597
UCHAR DmaBaseAddress
Definition: haldma.h:183
DMA1_ADDRESS_COUNT DmaAddressCount[4]
Definition: haldma.h:197
#define TRUE
Definition: types.h:120
#define B_32BITS
Definition: haldma.h:145
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
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:717
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
NTSYSAPI void WINAPI RtlInitializeBitMap(PRTL_BITMAP, PULONG, ULONG)
#define KeLowerIrql(oldIrql)
Definition: env_spec_w32.h:602
struct _RTL_BITMAP RTL_BITMAP
_Out_ PULONG NumberOfMapRegisters
Definition: halfuncs.h:209
#define MmGetMdlPfnArray(_Mdl)
UCHAR SingleMask
Definition: haldma.h:215
_In_ ULONG Mode
Definition: hubbusif.h:303
#define MAXLONG
Definition: umtypes.h:116
#define MmGetMdlVirtualAddress(_Mdl)
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
PFREE_MAP_REGISTERS FreeMapRegisters
Definition: iotypes.h:2316
ULONG NTAPI HalpDmaGetDmaAlignment(PADAPTER_OBJECT AdapterObject)
Definition: dma.c:918
unsigned char * PUCHAR
Definition: retypes.h:3
UCHAR NTAPI READ_PORT_UCHAR(PUCHAR Address)
Definition: mach.c:535
UCHAR DmaBaseAddress
Definition: haldma.h:189
struct _ADAPTER_OBJECT ADAPTER_OBJECT
LONG NTSTATUS
Definition: precomp.h:26
DMA_SPEED DmaSpeed
Definition: iotypes.h:2037
Definition: haldma.h:312
DMA2_ADDRESS_COUNT DmaAddressCount[4]
Definition: haldma.h:210
static DMA_OPERATIONS HalpDmaOperations
Definition: dma.c:94
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:2217
PVOID VirtualAddress
Definition: haldma.h:314
VOID NTAPI KeInitializeDeviceQueue(IN PKDEVICE_QUEUE DeviceQueue)
Definition: devqueue.c:22
#define TypeA
Definition: nslookup.h:13
_Inout_ __drv_aliasesMem PSLIST_ENTRY _Inout_ PSLIST_ENTRY _In_ ULONG Count
Definition: exfuncs.h:1015
PDRIVER_CONTROL DeviceRoutine
Definition: iotypes.h:196
#define OBJ_PERMANENT
Definition: winternl.h:226
#define BURST_TIMING
Definition: haldma.h:152
VOID NTAPI ObDereferenceObject(IN PVOID Object)
Definition: obref.c:375
#define DMA_CLEARMASK
Definition: haldma.h:175
UCHAR Byte
Definition: haldma.h:99
#define InsertTailList(ListHead, Entry)
#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
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 MmFreeContiguousMemory(IN PVOID BaseAddress)
Definition: contmem.c:648
VOID NTAPI HalpCopyBufferMap(PMDL Mdl, PROS_MAP_REGISTER_ENTRY MapRegisterBase, PVOID CurrentVa, ULONG Length, BOOLEAN WriteToDevice)
Definition: dma.c:1468
VOID(NTAPI * PFREE_ADAPTER_CHANNEL)(_In_ PDMA_ADAPTER DmaAdapter)
Definition: iotypes.h:2226
static PADAPTER_OBJECT HalpEisaAdapter[8]
Definition: dma.c:79
WORK_QUEUE_ITEM WorkQueueItem
Definition: haldma.h:362
uint32_t ULONG_PTR
Definition: typedefs.h:63
FORCEINLINE BOOLEAN RemoveEntryList(_In_ PLIST_ENTRY Entry)
Definition: rtlfuncs.h:105
UCHAR KIRQL
Definition: env_spec_w32.h:591
ULONG * PPFN_NUMBER
Definition: ke.h:8
ULONG(NTAPI * PGET_DMA_ALIGNMENT)(_In_ PDMA_ADAPTER DmaAdapter)
Definition: iotypes.h:2245
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:2209
UCHAR SingleMask
Definition: haldma.h:200
PADAPTER_OBJECT AdapterObject
Definition: haldma.h:363
PVOID NTAPI HalAllocateCrashDumpRegisters(IN PADAPTER_OBJECT AdapterObject, IN OUT PULONG NumberOfMapRegisters)
Definition: dma.c:180
ULONG PFN_NUMBER
Definition: ke.h:8
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
struct _GROW_WORK_ITEM * PGROW_WORK_ITEM
NTSTATUS NTAPI HalAllocateAdapterChannel(IN PADAPTER_OBJECT AdapterObject, IN PWAIT_CONTEXT_BLOCK WaitContextBlock, IN ULONG NumberOfMapRegisters, IN PDRIVER_CONTROL ExecutionRoutine)
Definition: dma.c:88
UCHAR Channel
Definition: haldma.h:93
PMAP_TRANSFER MapTransfer
Definition: iotypes.h:2317
PHYSICAL_ADDRESS NTAPI HalpGetAdapterMaximumPhysicalAddress(IN PADAPTER_OBJECT AdapterObject)
Definition: dma.c:167
BOOLEAN NTAPI HalpGrowMapBuffers(IN PADAPTER_OBJECT AdapterObject, IN ULONG SizeOfMapBuffers)
Definition: dma.c:203
#define FILE_READ_DATA
Definition: nt_native.h:628
BOOLEAN IgnoreCount
Definition: iotypes.h:2030
VOID HalpInitDma(VOID)
Definition: dma.c:121
FORCEINLINE VOID KeInitializeSpinLock(_Out_ PKSPIN_LOCK SpinLock)
Definition: kefuncs.h:251
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
_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
FORCEINLINE PLIST_ENTRY RemoveHeadList(_Inout_ PLIST_ENTRY ListHead)
Definition: rtlfuncs.h:128
struct _ROS_MAP_REGISTER_ENTRY * PROS_MAP_REGISTER_ENTRY
static BOOLEAN HalpEisaDma
Definition: dma.c:80
NTSTATUS NTAPI ObReferenceObjectByPointer(IN PVOID Object, IN ACCESS_MASK DesiredAccess, IN POBJECT_TYPE ObjectType, IN KPROCESSOR_MODE AccessMode)
Definition: obref.c:383
UCHAR ClearBytePointer
Definition: haldma.h:219
void * PVOID
Definition: retypes.h:9
#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
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:952
BOOLEAN Dma32BitAddresses
Definition: iotypes.h:2029
VOID NTAPI HalpGrowMapBufferWorker(PVOID DeferredContext)
Definition: dma.c:1005
#define B_16BITS
Definition: haldma.h:146
PFLUSH_ADAPTER_BUFFERS FlushAdapterBuffers
Definition: iotypes.h:2314
BOOLEAN Dma64BitAddresses
Definition: iotypes.h:2032
_Must_inspect_result_ _In_ PDEVICE_DESCRIPTION DeviceDescription
Definition: iofuncs.h:1015
_In_ HANDLE Handle
Definition: extypes.h:390
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:2236
#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
PFREE_ADAPTER_CHANNEL FreeAdapterChannel
Definition: iotypes.h:2315
#define COMPATIBLE_TIMING
Definition: haldma.h:149
if(!(yy_init))
Definition: macro.lex.yy.c:714
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
BOOLEAN DemandMode
Definition: iotypes.h:2027
VOID FASTCALL KfReleaseSpinLock(PKSPIN_LOCK SpinLock, KIRQL OldIrql)
Definition: spinlock.c:96
BOOLEAN ScatterGather
Definition: iotypes.h:2026
#define KeAcquireSpinLock(sl, irql)
Definition: env_spec_w32.h:609
static const UCHAR Index[8]
Definition: usbohci.c:18
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
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
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
DMA_WIDTH DmaWidth
Definition: iotypes.h:2036
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#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:1060
unsigned char UCHAR
Definition: xmlstorage.h:181
#define TAG_DMA
Definition: dma.c:116
UCHAR TransferType
Definition: haldma.h:94
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:803
UCHAR DmaBaseCount
Definition: haldma.h:191
POBJECT_TYPE IoAdapterObjectType
Definition: adapter.c:18
PHYSICAL_ADDRESS PhysicalAddress
Definition: haldma.h:315
UCHAR ChannelNumber
Definition: haldma.h:133
_Out_ PNDIS_HANDLE _Out_ PUINT _In_ PNDIS_STRING _In_ NDIS_PHYSICAL_ADDRESS HighestAcceptableAddress
Definition: ndis.h:3227
ULONG LowPart
Definition: typedefs.h:104
KDEVICE_QUEUE_ENTRY WaitQueueEntry
Definition: iotypes.h:195
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:2201
#define PAGE_SIZE
Definition: env_spec_w32.h:49
Definition: typedefs.h:117
_In_ ULONG _In_ BOOLEAN _Must_inspect_result_ PVOID * VirtualAddress
Definition: ndis.h:3791
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:359
NTSYSAPI ULONG WINAPI RtlFindClearBitsAndSet(PRTL_BITMAP, ULONG, ULONG)
#define READ_TRANSFER
Definition: haldma.h:165
_Must_inspect_result_ _In_ PHYSICAL_ADDRESS LowestAcceptableAddress
Definition: mmfuncs.h:214
#define MAX_MAP_REGISTERS
Definition: dma.c:114
VOID(NTAPI * PPUT_DMA_ADAPTER)(PDMA_ADAPTER DmaAdapter)
Definition: iotypes.h:2190
BOOLEAN NTAPI HalpDmaInitializeEisaAdapter(PADAPTER_OBJECT AdapterObject, PDEVICE_DESCRIPTION DeviceDescription)
Definition: dma.c:461
Status
Definition: gdiplustypes.h:24
struct _DMA_OPERATIONS DMA_OPERATIONS
VOID NTAPI HalPutDmaAdapter(IN PADAPTER_OBJECT AdapterObject)
Definition: dma.c:35
#define MAXULONG
Definition: typedefs.h:250
#define DISPATCH_LEVEL
Definition: env_spec_w32.h:696
UnicodeString MaximumLength
Definition: rtlfuncs.h:2982
UCHAR RequestMode
Definition: haldma.h:97
_Inout_ struct _IRP _In_ PVOID MapRegisterBase
Definition: iotypes.h:189
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:2932
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
PALLOCATE_ADAPTER_CHANNEL AllocateAdapterChannel
Definition: iotypes.h:2313
PDMA_ADAPTER NTAPI HalpGetDmaAdapter(IN PVOID Context, IN PDEVICE_DESCRIPTION DeviceDescription, OUT PULONG NumberOfMapRegisters)
Definition: dma.c:790
UCHAR TransferSize
Definition: haldma.h:134
Definition: ketypes.h:566
unsigned short USHORT
Definition: pedump.c:61
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
ULONG(NTAPI * PREAD_DMA_COUNTER)(_In_ PDMA_ADAPTER DmaAdapter)
Definition: iotypes.h:2249
PKDEVICE_QUEUE_ENTRY NTAPI KeRemoveDeviceQueue(IN PKDEVICE_QUEUE DeviceQueue)
Definition: devqueue.c:153
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:254
static KEVENT HalpDmaLock
Definition: dma.c:77
unsigned int * PULONG
Definition: retypes.h:1
VOID(NTAPI * PFREE_MAP_REGISTERS)(_In_ PDMA_ADAPTER DmaAdapter, PVOID MapRegisterBase, ULONG NumberOfMapRegisters)
Definition: iotypes.h:2230
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
static const ULONG_PTR HalpEisaPortPage[8]
Definition: dma.c:83
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:2021
NTSYSAPI void WINAPI RtlSetAllBits(PRTL_BITMAP)
struct _LARGE_INTEGER::@2192 u
#define SINGLE_REQUEST_MODE
Definition: haldma.h:170
#define OUT
Definition: typedefs.h:39
INTERFACE_TYPE InterfaceType
Definition: iotypes.h:2035
_In_ PDEVICE_OBJECT _In_ ULONG _In_ PDRIVER_CONTROL ExecutionRoutine
Definition: iofuncs.h:1393
KIRQL FASTCALL KfAcquireSpinLock(PKSPIN_LOCK SpinLock)
Definition: spinlock.c:85
#define TYPE_B_TIMING
Definition: haldma.h:151
unsigned int ULONG
Definition: retypes.h:1
#define DEMAND_REQUEST_MODE
Definition: haldma.h:169
void WRITE_PORT_UCHAR(PUCHAR Address, UCHAR Value)
Definition: mach.c:539
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
static PADAPTER_OBJECT HalpMasterAdapter
Definition: dma.c:81
#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:682
DRIVER_CONTROL * PDRIVER_CONTROL
Definition: iotypes.h:192
UCHAR Mode
Definition: haldma.h:201
PADAPTER_OBJECT NTAPI HalpDmaAllocateChildAdapter(ULONG NumberOfMapRegisters, PDEVICE_DESCRIPTION DeviceDescription)
Definition: dma.c:391
NTSYSAPI void WINAPI RtlSetBits(PRTL_BITMAP, ULONG, ULONG)
#define WRITE_TRANSFER
Definition: haldma.h:166
_Inout_ PKDEVICE_QUEUE_ENTRY DeviceQueueEntry
Definition: kefuncs.h:352
#define DEVICE_DESCRIPTION_VERSION1
Definition: iotypes.h:2020
ULONG NumberOfMapRegisters
Definition: haldma.h:364
#define B_8BITS
Definition: haldma.h:143
#define MAP_BASE_SW_SG
Definition: haldma.h:367
PVOID NTAPI HalAllocateCommonBuffer(IN PADAPTER_OBJECT AdapterObject, IN ULONG Length, IN PPHYSICAL_ADDRESS LogicalAddress, IN BOOLEAN CacheEnabled)
Definition: dma.c:46
return STATUS_SUCCESS
Definition: btrfs.c:2745
#define CASCADE_REQUEST_MODE
Definition: haldma.h:172
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
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:107
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 ExFreePool(addr)
Definition: env_spec_w32.h:352
PADAPTER_OBJECT NTAPI HalpDmaAllocateMasterAdapter(VOID)
Definition: dma.c:332
BOOLEAN AutoInitialize
Definition: iotypes.h:2028
LONGLONG QuadPart
Definition: typedefs.h:112
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:716
ULONG NumberOfMapRegisters
Definition: iotypes.h:198
PADAPTER_OBJECT NTAPI HalGetAdapter(IN PDEVICE_DESCRIPTION DeviceDescription, OUT PULONG NumberOfMapRegisters)
Definition: dma.c:22
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:569
UCHAR TimingMode
Definition: haldma.h:135
_In_opt_ PVOID DeferredContext
Definition: ketypes.h:675