Index: boot/freeldr/freeldr/arch/i386/winldr.c =================================================================== --- boot/freeldr/freeldr/arch/i386/winldr.c (revision 68595) +++ boot/freeldr/freeldr/arch/i386/winldr.c (working copy) @@ -348,6 +348,20 @@ } } +ULONG +WinLdrDetectMachineType() +{ + /* MCA machines are not supported yet */ + if (*(PULONG)0xfffd9 == 'ASIE') + { + return MACHINE_TYPE_EISA; + } + else + { + return MACHINE_TYPE_ISA; + } +} + void WinLdrSetupMachineDependent(PLOADER_PARAMETER_BLOCK LoaderBlock) { ULONG TssSize; @@ -357,7 +371,7 @@ ULONG BlockSize, NumPages; LoaderBlock->u.I386.CommonDataArea = NULL; // Force No ABIOS support - LoaderBlock->u.I386.MachineType = MACHINE_TYPE_ISA; + LoaderBlock->u.I386.MachineType = WinLdrDetectMachineType(); /* Allocate 2 pages for PCR */ Pcr = (ULONG_PTR)MmAllocateMemoryWithType(2 * MM_PAGE_SIZE, LoaderStartupPcrPage); Index: hal/halx86/apic/halinit_apic.c =================================================================== --- hal/halx86/apic/halinit_apic.c (revision 68595) +++ hal/halx86/apic/halinit_apic.c (working copy) @@ -53,8 +53,6 @@ VOID HalpInitPhase1(VOID) { - /* Initialize DMA. NT does this in Phase 0 */ - HalpInitDma(); } /* EOF */ Index: hal/halx86/generic/cmos.c =================================================================== --- hal/halx86/generic/cmos.c (revision 68595) +++ hal/halx86/generic/cmos.c (working copy) @@ -157,9 +157,6 @@ { /* Set default century offset byte */ HalpCmosCenturyOffset = 50; - - /* No support for EISA or MCA */ - ASSERT(HalpBusType == MACHINE_TYPE_ISA); } /* PUBLIC FUNCTIONS **********************************************************/ Index: hal/halx86/generic/dma.c =================================================================== --- hal/halx86/generic/dma.c (revision 68595) +++ hal/halx86/generic/dma.c (working copy) @@ -6,6 +6,7 @@ * PURPOSE: DMA functions * PROGRAMMERS: David Welch (welch@mcmail.com) * Filip Navara (navaraf@reactos.com) + * Andrey Kudravets (andrey220822@mail.ru) * UPDATE HISTORY: * Created 22/05/98 */ @@ -77,8 +78,6 @@ #define NDEBUG #include -#define MAX_SG_ELEMENTS 0x10 - #ifndef _MINIHAL_ static KEVENT HalpDmaLock; static LIST_ENTRY HalpDmaAdapterList; @@ -86,7 +85,8 @@ #endif static BOOLEAN HalpEisaDma; #ifndef _MINIHAL_ -static PADAPTER_OBJECT HalpMasterAdapter; +static MASTER_ADAPTER HalpMasterAdapter; +LONG HalpOutstandingScatterGatherCount; /* using later */ #endif static const ULONG_PTR HalpEisaPortPage[8] = { @@ -106,19 +106,18 @@ (PPUT_DMA_ADAPTER)HalPutDmaAdapter, (PALLOCATE_COMMON_BUFFER)HalAllocateCommonBuffer, (PFREE_COMMON_BUFFER)HalFreeCommonBuffer, - NULL, /* Initialized in HalpInitDma() */ - NULL, /* Initialized in HalpInitDma() */ - NULL, /* Initialized in HalpInitDma() */ - NULL, /* Initialized in HalpInitDma() */ - NULL, /* Initialized in HalpInitDma() */ + (PALLOCATE_ADAPTER_CHANNEL)IoAllocateAdapterChannel, + (PFLUSH_ADAPTER_BUFFERS)IoFlushAdapterBuffers, + (PFREE_ADAPTER_CHANNEL)IoFreeAdapterChannel, + (PFREE_MAP_REGISTERS)IoFreeMapRegisters, + (PMAP_TRANSFER)IoMapTransfer, (PGET_DMA_ALIGNMENT)HalpDmaGetDmaAlignment, (PREAD_DMA_COUNTER)HalReadDmaCounter, - /* FIXME: Implement the S/G funtions. */ (PGET_SCATTER_GATHER_LIST)HalGetScatterGatherList, (PPUT_SCATTER_GATHER_LIST)HalPutScatterGatherList, - NULL /*(PCALCULATE_SCATTER_GATHER_LIST_SIZE)HalCalculateScatterGatherListSize*/, - NULL /*(PBUILD_SCATTER_GATHER_LIST)HalBuildScatterGatherList*/, - NULL /*(PBUILD_MDL_FROM_SCATTER_GATHER_LIST)HalBuildMdlFromScatterGatherList*/ + (PCALCULATE_SCATTER_GATHER_LIST_SIZE)HalCalculateScatterGatherListSize, + (PBUILD_SCATTER_GATHER_LIST)HalBuildScatterGatherList, + (PBUILD_MDL_FROM_SCATTER_GATHER_LIST)HalBuildMdlFromScatterGatherList }; #endif @@ -129,28 +128,28 @@ /* FUNCTIONS *****************************************************************/ #ifndef _MINIHAL_ +/* + * called at phase 0 + */ VOID INIT_FUNCTION -HalpInitDma(VOID) +HalpInitDma(IN PLOADER_PARAMETER_BLOCK LoaderBlock) { - /* - * Initialize the DMA Operation table - */ - HalpDmaOperations.AllocateAdapterChannel = (PALLOCATE_ADAPTER_CHANNEL)IoAllocateAdapterChannel; - HalpDmaOperations.FlushAdapterBuffers = (PFLUSH_ADAPTER_BUFFERS)IoFlushAdapterBuffers; - HalpDmaOperations.FreeAdapterChannel = (PFREE_ADAPTER_CHANNEL)IoFreeAdapterChannel; - HalpDmaOperations.FreeMapRegisters = (PFREE_MAP_REGISTERS)IoFreeMapRegisters; - HalpDmaOperations.MapTransfer = (PMAP_TRANSFER)IoMapTransfer; + ULONG_PTR InitialMapRegisters; - /* - * Check if Extended DMA is available. We're just going to do a random - * read and write. - */ - WRITE_PORT_UCHAR((PUCHAR)FIELD_OFFSET(EISA_CONTROL, DmaController2Pages.Channel2), 0x2A); - if (READ_PORT_UCHAR((PUCHAR)FIELD_OFFSET(EISA_CONTROL, DmaController2Pages.Channel2)) == 0x2A) - { - HalpEisaDma = TRUE; - } + if (HalpBusType == MACHINE_TYPE_EISA) + { + /* + * Check if Extended DMA is available. We're just going to do a random + * read and write. + */ + + WRITE_PORT_UCHAR((PUCHAR)FIELD_OFFSET(EISA_CONTROL, DmaController2Pages.Channel2), 0x2A); + if (READ_PORT_UCHAR((PUCHAR)FIELD_OFFSET(EISA_CONTROL, DmaController2Pages.Channel2)) == 0x2A) + { + HalpEisaDma = TRUE; + } + } /* * Intialize all the global variables and allocate master adapter with @@ -158,8 +157,19 @@ */ InitializeListHead(&HalpDmaAdapterList); KeInitializeEvent(&HalpDmaLock, NotificationEvent, TRUE); - HalpMasterAdapter = HalpDmaAllocateMasterAdapter(); + /* + * Try to allocate initial set of map registers on the system start to + * ensure that low memory won't get filled up later. + */ + HalpMasterAdapter.MaxMapRegisters = MAX_MAP_REGISTERS; + InitialMapRegisters = HalpAllocPhysicalMemory(LoaderBlock, 0x1000000, 0x10, TRUE); + if (InitialMapRegisters != 0) + { + HalpMasterAdapter.InitialMapRegistersBuffer.QuadPart = (ULONGLONG)InitialMapRegisters; + HalpMasterAdapter.InitialMapRegistersBufferLength = 0x10000; + } + /* * Setup the HalDispatchTable callback for creating PnP DMA adapters. It's * used by IoGetDmaAdapter in the kernel. @@ -180,7 +190,7 @@ { PHYSICAL_ADDRESS HighestAddress; - if (AdapterObject->MasterDevice) + if (AdapterObject != NULL && AdapterObject->MasterDevice) { if (AdapterObject->Dma64BitAddresses) { @@ -202,7 +212,8 @@ /** * @name HalpGrowMapBuffers * - * Allocate initial, or additional, map buffers for DMA master adapter. + * Allocate additional, or use the initial, map buffers for DMA master adapter. + * The initial buffer was been allocated at phase 0 of the system boot. See HalpInitDma. * * @param MasterAdapter * DMA master adapter to allocate buffers for. @@ -223,45 +234,68 @@ KIRQL OldIrql; ULONG MapRegisterCount; - /* Check if enough map register slots are available. */ - MapRegisterCount = BYTES_TO_PAGES(SizeOfMapBuffers); - if (MapRegisterCount + AdapterObject->NumberOfMapRegisters > MAX_MAP_REGISTERS) - { - DPRINT("No more map register slots available! (Current: %d | Requested: %d | Limit: %d)\n", - AdapterObject->NumberOfMapRegisters, - MapRegisterCount, - MAX_MAP_REGISTERS); - return FALSE; - } + if (AdapterObject->NumberOfMapRegisters == 0 && HalpMasterAdapter.InitialMapRegistersBufferLength) + { + /* + * in this case we use MapRegisters which were allocated at the system startup + */ + MapRegisterCount = BYTES_TO_PAGES(HalpMasterAdapter.InitialMapRegistersBufferLength); + PhysicalAddress = HalpMasterAdapter.InitialMapRegistersBuffer; - /* - * Allocate memory for the new map registers. For 32-bit adapters we use - * two passes in order not to waste scare resource (low memory). - */ - HighestAcceptableAddress = HalpGetAdapterMaximumPhysicalAddress(AdapterObject); - LowestAcceptableAddress.HighPart = 0; - LowestAcceptableAddress.LowPart = HighestAcceptableAddress.LowPart == 0xFFFFFFFF ? 0x1000000 : 0; - BoundryAddressMultiple.QuadPart = 0; + VirtualAddress = MmMapIoSpace(PhysicalAddress, + HalpMasterAdapter.InitialMapRegistersBufferLength, + MmNonCached); - VirtualAddress = MmAllocateContiguousMemorySpecifyCache(MapRegisterCount << PAGE_SHIFT, - LowestAcceptableAddress, - HighestAcceptableAddress, - BoundryAddressMultiple, - MmNonCached); - if (!(VirtualAddress) && (LowestAcceptableAddress.LowPart)) - { - LowestAcceptableAddress.LowPart = 0; - VirtualAddress = MmAllocateContiguousMemorySpecifyCache(MapRegisterCount << PAGE_SHIFT, - LowestAcceptableAddress, - HighestAcceptableAddress, - BoundryAddressMultiple, - MmNonCached); - } + if (VirtualAddress == NULL) + { + /* if an error occurred, we no longer use the initial buffer */ + HalpMasterAdapter.InitialMapRegistersBufferLength = 0; + return FALSE; + } + } + else + { + /* Check if enough map register slots are available. */ + MapRegisterCount = BYTES_TO_PAGES(SizeOfMapBuffers); + if (MapRegisterCount + AdapterObject->NumberOfMapRegisters + (MapRegisterCount * PAGE_SIZE / 0x10000) + > HalpMasterAdapter.MaxMapRegisters) + { + DPRINT("No more map register slots available! (Current: %d | Requested: %d | Limit: %d)\n", + AdapterObject->NumberOfMapRegisters, + MapRegisterCount, + MAX_MAP_REGISTERS); + return FALSE; + } - if (!VirtualAddress) return FALSE; + /* + * Allocate memory for the new map registers. For 32-bit adapters we use + * two passes in order not to waste scare resource (low memory). + */ + HighestAcceptableAddress = HalpGetAdapterMaximumPhysicalAddress(AdapterObject); + LowestAcceptableAddress.HighPart = 0; + LowestAcceptableAddress.LowPart = HighestAcceptableAddress.LowPart == 0xFFFFFFFF ? 0x1000000 : 0; + BoundryAddressMultiple.QuadPart = 0; - PhysicalAddress = MmGetPhysicalAddress(VirtualAddress); + VirtualAddress = MmAllocateContiguousMemorySpecifyCache(MapRegisterCount << PAGE_SHIFT, + LowestAcceptableAddress, + HighestAcceptableAddress, + BoundryAddressMultiple, + MmNonCached); + if (!(VirtualAddress) && (LowestAcceptableAddress.LowPart)) + { + LowestAcceptableAddress.LowPart = 0; + VirtualAddress = MmAllocateContiguousMemorySpecifyCache(MapRegisterCount << PAGE_SHIFT, + LowestAcceptableAddress, + HighestAcceptableAddress, + BoundryAddressMultiple, + MmNonCached); + } + if (!VirtualAddress) return FALSE; + + PhysicalAddress = MmGetPhysicalAddress(VirtualAddress); + } + /* * All the following must be done with the master adapter lock held * to prevent corruption. @@ -329,81 +363,59 @@ return TRUE; } -/** - * @name HalpDmaAllocateMasterAdapter - * - * Helper routine to allocate and initialize master adapter object and it's - * associated map register buffers. - * - * @see HalpInitDma - */ -PADAPTER_OBJECT -NTAPI -HalpDmaAllocateMasterAdapter(VOID) -{ - PADAPTER_OBJECT MasterAdapter; - ULONG Size, SizeOfBitmap; - SizeOfBitmap = MAX_MAP_REGISTERS; - Size = sizeof(ADAPTER_OBJECT); - Size += sizeof(RTL_BITMAP); - Size += (SizeOfBitmap + 7) >> 3; - MasterAdapter = ExAllocatePoolWithTag(NonPagedPool, Size, TAG_DMA); - if (!MasterAdapter) return NULL; - - RtlZeroMemory(MasterAdapter, Size); - - KeInitializeSpinLock(&MasterAdapter->SpinLock); - InitializeListHead(&MasterAdapter->AdapterQueue); - - MasterAdapter->MapRegisters = (PVOID)(MasterAdapter + 1); - RtlInitializeBitMap(MasterAdapter->MapRegisters, - (PULONG)(MasterAdapter->MapRegisters + 1), - SizeOfBitmap); - RtlSetAllBits(MasterAdapter->MapRegisters); - MasterAdapter->NumberOfMapRegisters = 0; - MasterAdapter->CommittedMapRegisters = 0; - - MasterAdapter->MapRegisterBase = ExAllocatePoolWithTag(NonPagedPool, - SizeOfBitmap * - sizeof(ROS_MAP_REGISTER_ENTRY), - TAG_DMA); - if (!MasterAdapter->MapRegisterBase) - { - ExFreePool(MasterAdapter); - return NULL; - } - - RtlZeroMemory(MasterAdapter->MapRegisterBase, - SizeOfBitmap * sizeof(ROS_MAP_REGISTER_ENTRY)); - if (!HalpGrowMapBuffers(MasterAdapter, 0x10000)) - { - ExFreePool(MasterAdapter); - return NULL; - } - - return MasterAdapter; -} - /** - * @name HalpDmaAllocateChildAdapter + * @name HalpAllocateAdapter * - * Helper routine of HalGetAdapter. Allocate child adapter object and + * Helper routine of HalGetAdapter. Allocate child adapter object and master adapter, if not allocated yet, and * fill out some basic fields. * * @see HalGetAdapter */ +static PADAPTER_OBJECT NTAPI -HalpDmaAllocateChildAdapter(IN ULONG NumberOfMapRegisters, - IN PDEVICE_DESCRIPTION DeviceDescription) +HalpAllocateAdapter(IN ULONG NumberOfMapRegisters, + IN PDEVICE_DESCRIPTION DeviceDescription, + IN BOOLEAN AllocateMasterAdapter) { PADAPTER_OBJECT AdapterObject; OBJECT_ATTRIBUTES ObjectAttributes; NTSTATUS Status; HANDLE Handle; + ULONG ObjectSize, SizeOfBitmap; + /* + * Allocate MasterAdapter if it has not been allocated yet. + * We do it only when NumberOfMapRegisters != 0, because + * AdapterObjects that do not have MapRegisters, doesn't link to MasterAdapter and don't need it. + */ + if (!AllocateMasterAdapter && NumberOfMapRegisters != 0 && HalpMasterAdapter.AdapterObject == NULL) + { + /* call recursively for allocate master adapter */ + AdapterObject = HalpAllocateAdapter(NumberOfMapRegisters, DeviceDescription, TRUE); + if (!AdapterObject) return NULL; + + AdapterObject->Dma32BitAddresses = DeviceDescription->Dma32BitAddresses; + AdapterObject->MasterDevice = DeviceDescription->Master; + + HalpMasterAdapter.AdapterObject = AdapterObject; + } + + /* calculate the size of the bitmap, and total size of the AdapterObject */ + if (AllocateMasterAdapter) + { + /* For the master adapter, Compute the size, including RTL_BITMAP and bitmap bits */ + SizeOfBitmap = HalpMasterAdapter.MaxMapRegisters; + ObjectSize = sizeof(ADAPTER_OBJECT) + sizeof(RTL_BITMAP) + ((SizeOfBitmap + 7) >> 3); + ObjectSize = (ObjectSize + 3) & ~3; + } + else + { + ObjectSize = sizeof(ADAPTER_OBJECT); + } + InitializeObjectAttributes(&ObjectAttributes, NULL, OBJ_KERNEL_HANDLE | OBJ_PERMANENT, @@ -415,7 +427,7 @@ &ObjectAttributes, KernelMode, NULL, - sizeof(ADAPTER_OBJECT), + ObjectSize, 0, 0, (PVOID)&AdapterObject); @@ -427,7 +439,7 @@ KernelMode); if (!NT_SUCCESS(Status)) return NULL; - RtlZeroMemory(AdapterObject, sizeof(ADAPTER_OBJECT)); + RtlZeroMemory(AdapterObject, ObjectSize); Status = ObInsertObject(AdapterObject, NULL, @@ -439,15 +451,55 @@ ZwClose(Handle); - AdapterObject->DmaHeader.Version = (USHORT)DeviceDescription->Version; - AdapterObject->DmaHeader.Size = sizeof(ADAPTER_OBJECT); + /* + * we always set DmaHeader version is 1 + * see https://msdn.microsoft.com/en-us/library/windows/hardware/ff544062(v=vs.85).aspx + */ + AdapterObject->DmaHeader.Version = 1; + AdapterObject->DmaHeader.Size = ObjectSize; AdapterObject->DmaHeader.DmaOperations = &HalpDmaOperations; AdapterObject->MapRegistersPerChannel = 1; AdapterObject->Dma32BitAddresses = DeviceDescription->Dma32BitAddresses; AdapterObject->ChannelNumber = 0xFF; - AdapterObject->MasterAdapter = HalpMasterAdapter; - KeInitializeDeviceQueue(&AdapterObject->ChannelWaitQueue); + /* we link adapter object to the master adapter only when NumberOfMapRegisters != 0 */ + AdapterObject->MasterAdapter = (NumberOfMapRegisters != 0) ? HalpMasterAdapter.AdapterObject : NULL; + + KeInitializeDeviceQueue(&AdapterObject->ChannelWaitQueue); + + /* setup the MasterAdapter if allocate it. */ + if (AllocateMasterAdapter) + { + KeInitializeSpinLock(&AdapterObject->SpinLock); + InitializeListHead(&AdapterObject->AdapterQueue); + + AdapterObject->MapRegisters = (PVOID)(AdapterObject + 1); + RtlInitializeBitMap(AdapterObject->MapRegisters, + (PULONG)(AdapterObject->MapRegisters + 1), + SizeOfBitmap); + RtlSetAllBits(AdapterObject->MapRegisters); + AdapterObject->NumberOfMapRegisters = 0; + AdapterObject->CommittedMapRegisters = 0; + + AdapterObject->MapRegisterBase = ExAllocatePoolWithTag(NonPagedPool, + SizeOfBitmap * + sizeof(ROS_MAP_REGISTER_ENTRY), + TAG_DMA); + if (!AdapterObject->MapRegisterBase) + { + ObDereferenceObject(AdapterObject); + return NULL; + } + + RtlZeroMemory(AdapterObject->MapRegisterBase, + SizeOfBitmap * sizeof(ROS_MAP_REGISTER_ENTRY)); + if (!HalpGrowMapBuffers(AdapterObject, 0x10000)) + { + ObDereferenceObject(AdapterObject); + return NULL; + } + } + return AdapterObject; } #endif @@ -649,6 +701,15 @@ */ if ((EisaAdapter) && (DeviceDescription->DmaChannel == 4)) return NULL; + /* + * for pci bus master devices that require scatter-gather, 32 bit addressing, we set automatically + */ + if ((DeviceDescription->InterfaceType == PCIBus) && (DeviceDescription->Master) && + (DeviceDescription->ScatterGather)) + { + DeviceDescription->Dma32BitAddresses = TRUE; + } + /* * Calculate the number of map registers. * @@ -677,6 +738,14 @@ */ MapRegisters = BYTES_TO_PAGES(MaximumLength) + 1; if (MapRegisters > 16) MapRegisters = 16; + + if (!HalpEisaDma) + { + if (MapRegisters > ((HalpMasterAdapter.InitialMapRegistersBufferLength / PAGE_SIZE) / 2)) + { + MapRegisters = (HalpMasterAdapter.InitialMapRegistersBufferLength / PAGE_SIZE) / 2; + } + } } /* @@ -706,7 +775,7 @@ if (AdapterObject == NULL) { - AdapterObject = HalpDmaAllocateChildAdapter(MapRegisters, DeviceDescription); + AdapterObject = HalpAllocateAdapter(MapRegisters, DeviceDescription, FALSE); if (AdapterObject == NULL) { KeSetEvent(&HalpDmaLock, 0, 0); @@ -722,6 +791,21 @@ { AdapterObject->NeedsMapRegisters = TRUE; AdapterObject->MapRegistersPerChannel = MapRegisters; + + if (DeviceDescription->Master) + { + HalpMasterAdapter.AdapterObject->CommittedMapRegisters += (MapRegisters * 2); + } + else + { + HalpMasterAdapter.AdapterObject->CommittedMapRegisters += MapRegisters; + } + + if (HalpMasterAdapter.AdapterObject->CommittedMapRegisters > + HalpMasterAdapter.AdapterObject->NumberOfMapRegisters) + { + HalpGrowMapBuffers(HalpMasterAdapter.AdapterObject, 0x10000); + } } else { @@ -866,7 +950,7 @@ * slave DMA devices the 64Kb boundary mustn't be crossed since the * controller wouldn't be able to handle it. */ - if (AdapterObject->MasterDevice) + if (AdapterObject->MasterDevice || HalpBusType == MACHINE_TYPE_EISA) { BoundryAddressMultiple.HighPart = 1; } @@ -911,18 +995,33 @@ } typedef struct _SCATTER_GATHER_CONTEXT { - PADAPTER_OBJECT AdapterObject; + BOOLEAN UsingUserBuffer; PMDL Mdl; + PMDL DerivedMdl; + PVOID MapRegisterBase; PUCHAR CurrentVa; ULONG Length; - PDRIVER_LIST_CONTROL AdapterListControlRoutine; - PVOID AdapterListControlContext, MapRegisterBase; ULONG MapRegisterCount; - BOOLEAN WriteToDevice; - WAIT_CONTEXT_BLOCK Wcb; + ULONG Reserved; + union + { + struct + { + WAIT_CONTEXT_BLOCK Wcb; + PDRIVER_LIST_CONTROL AdapterListControlRoutine; + PVOID AdapterListControlContext; + ULONG Reserved2; + PADAPTER_OBJECT AdapterObject; + BOOLEAN WriteToDevice; + ULONG Reserved3; + }; + SCATTER_GATHER_LIST ScatterGatherList; + }; } SCATTER_GATHER_CONTEXT, *PSCATTER_GATHER_CONTEXT; - +/* + * Called for the non bus-master dma adapter only + */ IO_ALLOCATION_ACTION NTAPI HalpScatterGatherAdapterControl(IN PDEVICE_OBJECT DeviceObject, @@ -931,61 +1030,82 @@ IN PVOID Context) { PSCATTER_GATHER_CONTEXT AdapterControlContext = Context; - PADAPTER_OBJECT AdapterObject = AdapterControlContext->AdapterObject; + PADAPTER_OBJECT AdapterObject; PSCATTER_GATHER_LIST ScatterGatherList; - SCATTER_GATHER_ELEMENT TempElements[MAX_SG_ELEMENTS]; - ULONG ElementCount = 0, RemainingLength = AdapterControlContext->Length; - PUCHAR CurrentVa = AdapterControlContext->CurrentVa; + PSCATTER_GATHER_ELEMENT Element; + ULONG RemainingLength; + PUCHAR CurrentVa; + BOOLEAN WriteToDevice; + PDRIVER_LIST_CONTROL AdapterListControlRoutine; + PVOID AdapterListControlContext; + PMDL Mdl; + LONG ByteCount; /* Store the map register base for later in HalPutScatterGatherList */ AdapterControlContext->MapRegisterBase = MapRegisterBase; - while (RemainingLength > 0 && ElementCount < MAX_SG_ELEMENTS) + AdapterListControlRoutine = AdapterControlContext->AdapterListControlRoutine; + AdapterListControlContext = AdapterControlContext->AdapterListControlContext; + AdapterObject = AdapterControlContext->AdapterObject; + WriteToDevice = AdapterControlContext->WriteToDevice; + + ScatterGatherList = &AdapterControlContext->ScatterGatherList; + ScatterGatherList->Reserved = (ULONG_PTR)AdapterControlContext; + CurrentVa = AdapterControlContext->CurrentVa; + Mdl = AdapterControlContext->Mdl; + RemainingLength = AdapterControlContext->Length; + + ByteCount = (PUCHAR)MmGetMdlVirtualAddress(Mdl) + Mdl->ByteCount - CurrentVa; + Element = ScatterGatherList->Elements; + + while (RemainingLength) { - TempElements[ElementCount].Length = RemainingLength; - TempElements[ElementCount].Reserved = 0; - TempElements[ElementCount].Address = IoMapTransfer(AdapterObject, - AdapterControlContext->Mdl, - MapRegisterBase, - CurrentVa + (AdapterControlContext->Length - RemainingLength), - &TempElements[ElementCount].Length, - AdapterControlContext->WriteToDevice); - if (TempElements[ElementCount].Length == 0) - break; + if (ByteCount > RemainingLength) + ByteCount = RemainingLength; + RemainingLength -= ByteCount; - DPRINT("Allocated one S/G element: 0x%I64u with length: 0x%x\n", - TempElements[ElementCount].Address.QuadPart, - TempElements[ElementCount].Length); + while (ByteCount > 0) + { + Element->Length = ByteCount; + Element->Reserved = 0; + Element->Address = IoMapTransfer(AdapterObject, + Mdl, + MapRegisterBase, + CurrentVa, + &Element->Length, + WriteToDevice); - ASSERT(TempElements[ElementCount].Length <= RemainingLength); - RemainingLength -= TempElements[ElementCount].Length; - ElementCount++; - } + DPRINT("Allocated one S/G element: 0x%I64u with length: 0x%x\n", + Element->Address.QuadPart, + Element->Length); - if (RemainingLength > 0) - { - DPRINT1("Scatter/gather list construction failed!\n"); - return DeallocateObject; + ASSERT(Element->Length <= ByteCount); + + CurrentVa += Element->Length; + ByteCount -= Element->Length; + ++Element; + } + + Mdl = Mdl->Next; + if (!Mdl) + { + /* add the remaining length at the last element */ + Element[-1].Length += RemainingLength; + break; + } + CurrentVa = (PUCHAR)MmGetMdlVirtualAddress(Mdl);; + ByteCount = Mdl->ByteCount; } - ScatterGatherList = ExAllocatePoolWithTag(NonPagedPool, - sizeof(SCATTER_GATHER_LIST) + sizeof(SCATTER_GATHER_ELEMENT) * ElementCount, - TAG_DMA); - ASSERT(ScatterGatherList); + ScatterGatherList->NumberOfElements = Element - ScatterGatherList->Elements; - ScatterGatherList->NumberOfElements = ElementCount; - ScatterGatherList->Reserved = (ULONG_PTR)AdapterControlContext; - RtlCopyMemory(ScatterGatherList->Elements, - TempElements, - sizeof(SCATTER_GATHER_ELEMENT) * ElementCount); + DPRINT("Initiating S/G DMA with %d element(s)\n", ScatterGatherList->NumberOfElements); - DPRINT("Initiating S/G DMA with %d element(s)\n", ElementCount); + AdapterListControlRoutine(DeviceObject, + Irp, + ScatterGatherList, + AdapterListControlContext); - AdapterControlContext->AdapterListControlRoutine(DeviceObject, - Irp, - ScatterGatherList, - AdapterControlContext->AdapterListControlContext); - return DeallocateObjectKeepRegisters; } @@ -1013,8 +1133,6 @@ * * @return The status of the operation. * - * @see HalPutScatterGatherList - * * @implemented */ NTSTATUS @@ -1028,34 +1146,22 @@ IN PVOID Context, IN BOOLEAN WriteToDevice) { - PSCATTER_GATHER_CONTEXT AdapterControlContext; - - AdapterControlContext = ExAllocatePoolWithTag(NonPagedPool, sizeof(SCATTER_GATHER_CONTEXT), TAG_DMA); - if (!AdapterControlContext) return STATUS_INSUFFICIENT_RESOURCES; - - AdapterControlContext->AdapterObject = AdapterObject; - AdapterControlContext->Mdl = Mdl; - AdapterControlContext->CurrentVa = CurrentVa; - AdapterControlContext->Length = Length; - AdapterControlContext->MapRegisterCount = PAGE_ROUND_UP(Length) >> PAGE_SHIFT; - AdapterControlContext->AdapterListControlRoutine = ExecutionRoutine; - AdapterControlContext->AdapterListControlContext = Context; - AdapterControlContext->WriteToDevice = WriteToDevice; - - AdapterControlContext->Wcb.DeviceObject = DeviceObject; - AdapterControlContext->Wcb.DeviceContext = AdapterControlContext; - AdapterControlContext->Wcb.CurrentIrp = DeviceObject->CurrentIrp; - - return HalAllocateAdapterChannel(AdapterObject, - &AdapterControlContext->Wcb, - AdapterControlContext->MapRegisterCount, - HalpScatterGatherAdapterControl); + return HalBuildScatterGatherList(AdapterObject, + DeviceObject, + Mdl, + CurrentVa, + Length, + ExecutionRoutine, + Context, + WriteToDevice, + NULL, + 0); } /** * @name HalPutScatterGatherList * - * Frees a scatter-gather list allocated from HalGetScatterGatherList + * Frees a scatter-gather list allocated from HalBuildScatterGatherList * * @param AdapterObject * Adapter object representing the bus master or system dma controller. @@ -1066,7 +1172,7 @@ * * @return None * - * @see HalGetScatterGatherList + * @see HalBuildScatterGatherList * * @implemented */ @@ -1076,32 +1182,490 @@ IN PSCATTER_GATHER_LIST ScatterGather, IN BOOLEAN WriteToDevice) { - PSCATTER_GATHER_CONTEXT AdapterControlContext = (PSCATTER_GATHER_CONTEXT)ScatterGather->Reserved; - ULONG i; + PSCATTER_GATHER_CONTEXT AdapterControlContext; + ULONG ByteCount; + PMDL Mdl; + PUCHAR CurrentVa; + ULONG RemainingLength; + PROS_MAP_REGISTER_ENTRY MapRegisterBase; - for (i = 0; i < ScatterGather->NumberOfElements; i++) + InterlockedDecrement(&HalpOutstandingScatterGatherCount); + + /* + * The field 'SCATTER_GATHER_LIST::Reserved' can be in three States: + * - (== 0) - for bus-master scatter-gather, which allocated from our buffer + * - (== 1) - for bus-master scatter-gather, which allocated from user buffer + * - (== AdapterControlContext) - for slave scatter-gather. + */ + if (ScatterGather->Reserved == 0) { - IoFlushAdapterBuffers(AdapterObject, - AdapterControlContext->Mdl, - AdapterControlContext->MapRegisterBase, - AdapterControlContext->CurrentVa, - ScatterGather->Elements[i].Length, - AdapterControlContext->WriteToDevice); - AdapterControlContext->CurrentVa += ScatterGather->Elements[i].Length; + /* Our buffer */ + ExFreePoolWithTag(ScatterGather, TAG_DMA); + return; } + else if (ScatterGather->Reserved == 1) + { + /* User allocated buffer- simply return */ + return; + } + /* for the slave dma, we are flush the map buffers and free map registers */ + + AdapterControlContext = (PSCATTER_GATHER_CONTEXT)ScatterGather->Reserved; + Mdl = AdapterControlContext->Mdl; + CurrentVa = AdapterControlContext->CurrentVa; + RemainingLength = AdapterControlContext->Length; + MapRegisterBase = (PROS_MAP_REGISTER_ENTRY)AdapterControlContext->MapRegisterBase; + + ByteCount = (ULONG_PTR)MmGetMdlVirtualAddress(Mdl) + Mdl->ByteCount - (ULONG_PTR)CurrentVa; + + while (RemainingLength) + { + if (ByteCount) + { + if (ByteCount > RemainingLength) + ByteCount = RemainingLength; + RemainingLength -= ByteCount; + + IoFlushAdapterBuffers(AdapterObject, + Mdl, + (PVOID)MapRegisterBase, + (PVOID)CurrentVa, + ByteCount, + WriteToDevice); + + MapRegisterBase += ADDRESS_AND_SIZE_TO_SPAN_PAGES(CurrentVa, ByteCount); + } + + Mdl = Mdl->Next; + if (!Mdl) + break; + CurrentVa = MmGetMdlVirtualAddress(Mdl); + ByteCount = Mdl->ByteCount; + } + IoFreeMapRegisters(AdapterObject, AdapterControlContext->MapRegisterBase, AdapterControlContext->MapRegisterCount); + /* if you have a built mdl, then free it */ + Mdl = AdapterControlContext->DerivedMdl; + + while (Mdl) + { + if (Mdl->MdlFlags & MDL_MAPPED_TO_SYSTEM_VA) + MmUnmapLockedPages(Mdl->MappedSystemVa, Mdl); + IoFreeMdl(Mdl); + + Mdl = Mdl->Next; + } + + /* if this is our buffer, release it */ + if (!AdapterControlContext->UsingUserBuffer) + ExFreePoolWithTag(AdapterControlContext, TAG_DMA); + DPRINT("S/G DMA has finished!\n"); +} - ExFreePoolWithTag(AdapterControlContext, TAG_DMA); - ExFreePoolWithTag(ScatterGather, TAG_DMA); +/* + * @Implemented + */ +NTSTATUS +NTAPI +HalCalculateScatterGatherListSize(IN PADAPTER_OBJECT AdapterObject, + IN PMDL Mdl OPTIONAL, + IN PVOID CurrentVa, + IN ULONG Length, + OUT PULONG ScatterGatherListSize, + OUT OPTIONAL PULONG pNumberOfMapRegisters) +{ + ULONG TotalBytes, ByteCount, ByteOffset; + ULONG NumberOfMapRegisters = 0; + ULONG SgSize; + + if (Mdl) + { + ByteCount = (ULONG_PTR)MmGetMdlVirtualAddress(Mdl) + Mdl->ByteCount - (ULONG_PTR)CurrentVa; + ByteOffset = BYTE_OFFSET(CurrentVa); + TotalBytes = ByteCount; + + while (TotalBytes < Length) + { + Mdl = Mdl->Next; + if (Mdl == NULL) break; + + NumberOfMapRegisters += BYTES_TO_PAGES(ByteOffset + ByteCount); + ByteCount = Mdl->ByteCount; + ByteOffset = Mdl->ByteOffset; + + TotalBytes += ByteCount; + } + + if (TotalBytes + PAGE_SIZE < ByteOffset + Length) + return STATUS_BUFFER_TOO_SMALL; + + NumberOfMapRegisters += BYTES_TO_PAGES(ByteOffset + ByteCount - (TotalBytes - Length)); + + if (NumberOfMapRegisters > AdapterObject->MapRegistersPerChannel) + return STATUS_INSUFFICIENT_RESOURCES; + } + else + { + NumberOfMapRegisters = ADDRESS_AND_SIZE_TO_SPAN_PAGES(CurrentVa, Length); + } + + SgSize = NumberOfMapRegisters * sizeof(SCATTER_GATHER_ELEMENT) + FIELD_OFFSET(SCATTER_GATHER_LIST, Elements); + + if (AdapterObject->NeedsMapRegisters) + { + /* + * for the slave dma, SCATTER_GATHER_LIST within the SCATTER_GATHER_CONTEXT + */ + SgSize += FIELD_OFFSET(SCATTER_GATHER_CONTEXT, ScatterGatherList); + + if (SgSize < sizeof(SCATTER_GATHER_CONTEXT)) + SgSize = sizeof(SCATTER_GATHER_CONTEXT); + } + + *ScatterGatherListSize = SgSize; + if (pNumberOfMapRegisters) *pNumberOfMapRegisters = NumberOfMapRegisters; + + return STATUS_SUCCESS; } -#endif /** + * @name HalBuildScatterGatherList + * + * Creates a scatter-gather list to be using in scatter/gather DMA + * + * @param AdapterObject + * Adapter object representing the bus master or system dma controller. + * @param DeviceObject + * The device target for DMA. + * @param Mdl + * The MDL that describes the buffer to be mapped. + * @param CurrentVa + * The current VA in the buffer to be mapped for transfer. + * @param Length + * Specifies the length of data in bytes to be mapped. + * @param ExecutionRoutine + * A caller supplied AdapterListControl routine to be called when DMA is available. + * @param Context + * Context passed to the AdapterListControl routine. + * @param WriteToDevice + * Indicates direction of DMA operation. + * + * @param ScatterGatherBuffer + * User buffer for the scatter-gather list + * + * @param ScatterGatherBufferLength + * Buffer length + * + * @return The status of the operation. + * + * @see HalPutScatterGatherList + * + * @implemented + */ +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 ScatterGatherBufferLength) +{ + NTSTATUS Status; + ULONG SgSize, NumberOfMapRegisters; + ULONG ByteCount, ByteOffset; + PPFN_NUMBER MdlPages; + PSCATTER_GATHER_ELEMENT Element; + PSCATTER_GATHER_LIST ScatterGatherList; + PSCATTER_GATHER_CONTEXT ScatterGatherContext; + BOOLEAN UsingUserBuffer; + + if (!Mdl) return STATUS_INVALID_PARAMETER; + + Status = HalCalculateScatterGatherListSize(AdapterObject, + Mdl, + CurrentVa, + Length, + &SgSize, + &NumberOfMapRegisters); + if (!NT_SUCCESS(Status)) return Status; + + InterlockedIncrement(&HalpOutstandingScatterGatherCount); + + if (ScatterGatherBuffer) + { + /* checking is user buffer are enough */ + if (ScatterGatherBufferLength < SgSize) + { + InterlockedDecrement(&HalpOutstandingScatterGatherCount); + return STATUS_BUFFER_TOO_SMALL; + } + UsingUserBuffer = TRUE; + } + else + { + ScatterGatherBuffer = ExAllocatePoolWithTag(NonPagedPool, SgSize, TAG_DMA); + if (!ScatterGatherBuffer) + { + InterlockedDecrement(&HalpOutstandingScatterGatherCount); + return STATUS_INSUFFICIENT_RESOURCES; + } + UsingUserBuffer = FALSE; + } + + if (!AdapterObject->NeedsMapRegisters) + { + /* + * this is bus-master adapter + */ + + ScatterGatherList = (PSCATTER_GATHER_LIST)ScatterGatherBuffer; + ScatterGatherList->Reserved = UsingUserBuffer; + Element = ScatterGatherList->Elements; + + ByteCount = (PUCHAR)MmGetMdlVirtualAddress(Mdl) + Mdl->ByteCount - (PUCHAR)CurrentVa; + MdlPages = MmGetMdlPfnArray(Mdl); + MdlPages += ((ULONG_PTR)CurrentVa - (ULONG_PTR)PAGE_ROUND_DOWN(MmGetMdlVirtualAddress(Mdl))) >> PAGE_SHIFT; + ByteOffset = BYTE_OFFSET(CurrentVa); + + while (Length) + { + if (ByteCount > Length) + ByteCount = Length; + Length -= ByteCount; + + while (ByteCount) + { + Element->Address.QuadPart = ((ULONGLONG)*MdlPages << PAGE_SHIFT) + ByteOffset; + Element->Length = PAGE_SIZE - ByteOffset; + if (Element->Length > ByteCount) + Element->Length = ByteCount; + ByteCount -= Element->Length; + + /* + * if this element is comtiguously with previous element, + * we are concatenate them. + */ + if (Element != ScatterGatherList->Elements) + { + if (Element[-1].Address.QuadPart + Element[-1].Length == + Element->Address.QuadPart) + { + Element[-1].Length += Element->Length; + --Element; + } + } + + ByteOffset = 0; + ++Element; + ++MdlPages; + } + + Mdl = Mdl->Next; + if (!Mdl) break; + + ByteCount = Mdl->ByteCount; + ByteOffset = Mdl->ByteOffset; + MdlPages = MmGetMdlPfnArray(Mdl); + } + + /* Add a remaining length to the last element */ + if (Length) Element[-1].Length += Length; + + ScatterGatherList->NumberOfElements = Element - ScatterGatherList->Elements; + + ExecutionRoutine(DeviceObject, + DeviceObject->CurrentIrp, + ScatterGatherList, + Context); + } + else + { + /* + * this is a slave dma adapter + */ + + ScatterGatherContext = (PSCATTER_GATHER_CONTEXT)ScatterGatherBuffer; + + /* fill the scatter-gather context */ + ScatterGatherContext->UsingUserBuffer = UsingUserBuffer; + ScatterGatherContext->Mdl = Mdl; + ScatterGatherContext->DerivedMdl = NULL; + ScatterGatherContext->Length = Length; + ScatterGatherContext->CurrentVa = CurrentVa; + ScatterGatherContext->MapRegisterCount = NumberOfMapRegisters; + ScatterGatherContext->AdapterObject = AdapterObject; + ScatterGatherContext->WriteToDevice = WriteToDevice; + ScatterGatherContext->AdapterListControlRoutine = ExecutionRoutine; + ScatterGatherContext->AdapterListControlContext = Context; + + ScatterGatherContext->Wcb.DeviceObject = DeviceObject; + ScatterGatherContext->Wcb.DeviceContext = (PVOID)ScatterGatherContext; + ScatterGatherContext->Wcb.CurrentIrp = DeviceObject->CurrentIrp; + + Status = HalAllocateAdapterChannel(AdapterObject, + &ScatterGatherContext->Wcb, + NumberOfMapRegisters, + HalpScatterGatherAdapterControl); + + if (!NT_SUCCESS(Status)) + { + InterlockedDecrement(&HalpOutstandingScatterGatherCount); + if (!UsingUserBuffer) + ExFreePoolWithTag(ScatterGatherBuffer, TAG_DMA); + return Status; + } + } + + return STATUS_SUCCESS; +} + +/* + * @Implemented + */ +NTSTATUS +NTAPI +HalBuildMdlFromScatterGatherList(IN PADAPTER_OBJECT AdapterObject, + IN PSCATTER_GATHER_LIST ScatterGather, + IN PMDL OriginalMdl, + OUT PMDL *TargetMdl) +{ + PSCATTER_GATHER_CONTEXT AdapterControlContext = (PSCATTER_GATHER_CONTEXT)ScatterGather->Reserved; + PMDL Mdl; + PMDL NewMdl = NULL, PrevMdl = NULL; + PUCHAR MdlVa; + PPFN_NUMBER MdlPages; + PSCATTER_GATHER_ELEMENT Element; + ULONG i; + ULONG_PTR BRound, ERound; + ULONG ByteCount, PageCount; + PFN_NUMBER PfnNumber; + BOOLEAN FirstPass; + + if (!OriginalMdl) + return STATUS_INVALID_PARAMETER; + + if (!AdapterObject->NeedsMapRegisters) + { + /* + * for the bus-master scatter-gather, we are return a same Mdl + */ + *TargetMdl = OriginalMdl; + return STATUS_SUCCESS; + } + + if (AdapterControlContext && AdapterControlContext->DerivedMdl) + return STATUS_NONE_MAPPED; + + ERound = 0; + MdlVa = 0; + ByteCount = 0; + FirstPass = TRUE; + Element = ScatterGather->Elements; + + /* Allocate a new chain of mdls */ + for (i = 0; i < ScatterGather->NumberOfElements; i++, Element++) + { + BRound = BYTE_OFFSET(Element->Address.LowPart); + if (!FirstPass && (BRound || ERound)) + { + Mdl = IoAllocateMdl(MdlVa, ByteCount, FALSE, FALSE, NULL); + if (!Mdl) goto AllocFail; + + Mdl->MdlFlags |= (MDL_PAGES_LOCKED | MDL_IO_SPACE | MDL_MAPPING_CAN_FAIL); + + if (NewMdl) + { + PrevMdl->Next = Mdl; + } + else + { + NewMdl = Mdl; + } + PrevMdl = Mdl; + + ByteCount = 0; + } + FirstPass = FALSE; + + if (ByteCount == 0) + MdlVa = (PUCHAR)BRound; + ByteCount += Element->Length; + ERound = BYTE_OFFSET(Element->Address.LowPart + Element->Length); + } + + if (ByteCount != 0) + { + Mdl = IoAllocateMdl(MdlVa, ByteCount, FALSE, FALSE, NULL); + if (!Mdl) goto AllocFail; + + Mdl->MdlFlags |= (MDL_PAGES_LOCKED | MDL_IO_SPACE | MDL_MAPPING_CAN_FAIL); + + if (NewMdl) + { + PrevMdl->Next = Mdl; + } + else + { + NewMdl = Mdl; + } + } + + Mdl = NewMdl; + Element = ScatterGather->Elements; + MdlPages = MmGetMdlPfnArray(Mdl); + FirstPass = TRUE; + ERound = 0; + + /* fill the new mdls */ + for (i = 0; i < ScatterGather->NumberOfElements; i++, Element++) + { + BRound = BYTE_OFFSET(Element->Address.LowPart); + + if (!FirstPass && (BRound || ERound)) + { + Mdl = Mdl->Next; + MdlPages = MmGetMdlPfnArray(Mdl); + } + + PageCount = ADDRESS_AND_SIZE_TO_SPAN_PAGES(Element->Address.LowPart, Element->Length); + PfnNumber = (PFN_NUMBER)(Element->Address.QuadPart >> PAGE_SHIFT); + + while (PageCount--) + { + *MdlPages++ = PfnNumber++; + } + + ERound = BYTE_OFFSET(Element->Address.LowPart + Element->Length); + FirstPass = FALSE; + } + + *TargetMdl = NewMdl; + if (AdapterControlContext) + AdapterControlContext->DerivedMdl = NewMdl; + + return STATUS_SUCCESS; + +AllocFail: + while ((Mdl = NewMdl)) + { + NewMdl = Mdl->Next; + IoFreeMdl(Mdl); + } + return STATUS_INSUFFICIENT_RESOURCES; +} +#endif /* _MINIHAL_ */ + +/** * @name HalpDmaGetDmaAlignment * * Internal routine to return the DMA alignment requirement. It's exported Index: hal/halx86/generic/halinit.c =================================================================== --- hal/halx86/generic/halinit.c (revision 68595) +++ hal/halx86/generic/halinit.c (working copy) @@ -121,6 +121,10 @@ /* Setup I/O space */ HalpDefaultIoSpace.Next = HalpAddressUsageList; HalpAddressUsageList = &HalpDefaultIoSpace; + if (HalpBusType == MACHINE_TYPE_EISA) { + HalpEisaIoSpace.Next = HalpAddressUsageList; + HalpAddressUsageList = &HalpEisaIoSpace; + } /* Setup busy waiting */ HalpCalibrateStallExecution(); @@ -134,6 +138,8 @@ */ HalStopProfileInterrupt(ProfileTime); + HalpInitDma(LoaderBlock); + /* Do some HAL-specific initialization */ HalpInitPhase0(LoaderBlock); } Index: hal/halx86/generic/usage.c =================================================================== --- hal/halx86/generic/usage.c (revision 68595) +++ hal/halx86/generic/usage.c (working copy) @@ -58,6 +58,23 @@ } }; +ADDRESS_USAGE HalpEisaIoSpace = +{ + NULL, CmResourceTypePort, IDT_INTERNAL, + { + {0xD0, 0x10}, + {0x400, 0x10}, + {0x480, 0x10}, + {0x4C2, 0x0E}, + {0x4D4, 0x2C}, + {0x461, 0x02}, + {0x464, 0x02}, + {0x4D0, 0x02}, + {0xC84, 0x01}, + {0,0}, + } +}; + /* FUNCTIONS ******************************************************************/ #ifndef _MINIHAL_ Index: hal/halx86/include/haldma.h =================================================================== --- hal/halx86/include/haldma.h (revision 68595) +++ hal/halx86/include/haldma.h (working copy) @@ -358,6 +358,13 @@ LIST_ENTRY AdapterList; } ADAPTER_OBJECT; +typedef struct _MASTER_ADAPTER { + PADAPTER_OBJECT AdapterObject; + ULONG MaxMapRegisters; + ULONG InitialMapRegistersBufferLength; + PHYSICAL_ADDRESS InitialMapRegistersBuffer; +} MASTER_ADAPTER, *PMASTER_ADAPTER; + typedef struct _GROW_WORK_ITEM { WORK_QUEUE_ITEM WorkQueueItem; PADAPTER_OBJECT AdapterObject; @@ -366,9 +373,6 @@ #define MAP_BASE_SW_SG 1 -PADAPTER_OBJECT NTAPI -HalpDmaAllocateMasterAdapter(VOID); - PDMA_ADAPTER NTAPI HalpGetDmaAdapter( IN PVOID Context, @@ -378,3 +382,34 @@ ULONG NTAPI HalpDmaGetDmaAlignment( PADAPTER_OBJECT AdapterObject); + +NTSTATUS +NTAPI +HalCalculateScatterGatherListSize(IN PADAPTER_OBJECT AdapterObject, + IN PMDL Mdl OPTIONAL, + IN PVOID CurrentVa, + IN ULONG Length, + OUT PULONG ScatterGatherListSize, + OUT OPTIONAL PULONG pNumberOfMapRegisters); + +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 ScatterGatherBufferLength); + +NTSTATUS +NTAPI +HalBuildMdlFromScatterGatherList(IN PADAPTER_OBJECT AdapterObject, + IN PSCATTER_GATHER_LIST ScatterGather, + IN PMDL OriginalMdl, + OUT PMDL *TargetMdl); + + Index: hal/halx86/include/halp.h =================================================================== --- hal/halx86/include/halp.h (revision 68595) +++ hal/halx86/include/halp.h (working copy) @@ -598,7 +598,7 @@ VOID HalpInitPciBus (VOID); /* dma.c */ -VOID HalpInitDma (VOID); +VOID HalpInitDma (IN PLOADER_PARAMETER_BLOCK LoaderBlock); /* Non-generic initialization */ VOID HalpInitPhase0 (PLOADER_PARAMETER_BLOCK LoaderBlock); @@ -859,6 +859,7 @@ extern BOOLEAN HalpNMIInProgress; extern ADDRESS_USAGE HalpDefaultIoSpace; +extern ADDRESS_USAGE HalpEisaIoSpace; extern KSPIN_LOCK HalpSystemHardwareLock; Index: hal/halx86/up/halinit_up.c =================================================================== --- hal/halx86/up/halinit_up.c (revision 68595) +++ hal/halx86/up/halinit_up.c (working copy) @@ -54,9 +54,6 @@ PROFILE_LEVEL, HalpProfileInterrupt, Latched); - - /* Initialize DMA. NT does this in Phase 0 */ - HalpInitDma(); } /* EOF */