Filip Navara wrote:
Oh, this time with the right patch...
The patch works for me with a little modification. One test condition must be changed in HalpCopyBufferMap.
- Hartmut
Index: hal/halx86/generic/dma.c =================================================================== --- hal/halx86/generic/dma.c (Revision 17704) +++ hal/halx86/generic/dma.c (Arbeitskopie) @@ -1556,6 +1556,9 @@ { BOOLEAN SlaveDma = FALSE; PMAP_REGISTER_ENTRY RealMapRegisterBase; + PHYSICAL_ADDRESS HighestAcceptableAddress; + PHYSICAL_ADDRESS PhysicalAddress; + PPFN_NUMBER MdlPagesPtr;
ASSERT_IRQL(DISPATCH_LEVEL);
@@ -1588,18 +1591,27 @@ { if ((ULONG_PTR)MapRegisterBase & MAP_BASE_SW_SG) { - if (RealMapRegisterBase->Counter != ~0) + if (RealMapRegisterBase->Counter == ~0) { if (SlaveDma && !AdapterObject->IgnoreCount) Length -= HalReadDmaCounter(AdapterObject); + HalpCopyBufferMap(Mdl, RealMapRegisterBase, CurrentVa, Length, FALSE); } - - HalpCopyBufferMap(Mdl, RealMapRegisterBase, CurrentVa, Length, FALSE); } else { - /* FIXME: Unimplemented case */ - ASSERT(FALSE); + MdlPagesPtr = MmGetMdlPfnArray(Mdl); + MdlPagesPtr += ((ULONG_PTR)CurrentVa - (ULONG_PTR)Mdl->StartVa) >> PAGE_SHIFT; + + PhysicalAddress.QuadPart = *MdlPagesPtr << PAGE_SHIFT; + PhysicalAddress.QuadPart += BYTE_OFFSET(CurrentVa); + + HighestAcceptableAddress = HalpGetAdapterMaximumPhysicalAddress(AdapterObject); + if (PhysicalAddress.QuadPart + Length > + HighestAcceptableAddress.QuadPart) + { + HalpCopyBufferMap(Mdl, RealMapRegisterBase, CurrentVa, Length, FALSE); + } } }
@@ -1729,7 +1741,6 @@ * pages that are physically contiguous and that don't cross the * 64Kb boundary (this limitation applies only for ISA controllers). */ - while (TransferLength < *Length) { MdlPage1 = *MdlPagesPtr; @@ -1784,11 +1795,12 @@ HighestAcceptableAddress.QuadPart) { UseMapRegisters = TRUE; - PhysicalAddress = RealMapRegisterBase->PhysicalAddress; + PhysicalAddress = RealMapRegisterBase[Counter].PhysicalAddress; PhysicalAddress.QuadPart += ByteOffset; if ((ULONG_PTR)MapRegisterBase & MAP_BASE_SW_SG) { RealMapRegisterBase->Counter = ~0; + Counter = 0; } } }