}
else
{
- MapRegisters = BYTES_TO_PAGES(MaximumLength);
+ /*
+ * In the equation below the additional map register added by
+ * the "+1" accounts for the case when a transfer does not start
+ * at a page-aligned address.
+ */
+ MapRegisters = BYTES_TO_PAGES(MaximumLength) + 1;
if (MapRegisters > 16)
MapRegisters = 16;
}
{
ULONG CurrentLength;
ULONG_PTR CurrentAddress;
+ ULONG ByteOffset;
PVOID VirtualAddress;
VirtualAddress = MmGetSystemAddressForMdlSafe(Mdl, HighPagePriority);
while (Length > 0)
{
- CurrentLength = min(PAGE_SIZE, Length);
+ ByteOffset = BYTE_OFFSET(CurrentAddress);
+ CurrentLength = PAGE_SIZE - ByteOffset;
+ if (CurrentLength > Length)
+ CurrentLength = Length;
+
if (WriteToDevice)
{
RtlCopyMemory(
- MapRegisterBase->VirtualAddress,
+ (PVOID)((ULONG_PTR)MapRegisterBase->VirtualAddress + ByteOffset),
(PVOID)CurrentAddress,
CurrentLength);
}
{
RtlCopyMemory(
(PVOID)CurrentAddress,
- MapRegisterBase->VirtualAddress,
+ (PVOID)((ULONG_PTR)MapRegisterBase->VirtualAddress + ByteOffset),
CurrentLength);
}
RealMapRegisterBase =
(PMAP_REGISTER_ENTRY)((ULONG_PTR)MapRegisterBase & ~MAP_BASE_SW_SG);
- if (!WriteToDevice && RealMapRegisterBase->UseMapRegisters)
+ if (!WriteToDevice)
{
if ((ULONG_PTR)MapRegisterBase & MAP_BASE_SW_SG)
{
ULONG ByteOffset;
ULONG TransferOffset;
ULONG TransferLength;
+ BOOLEAN UseMapRegisters;
PMAP_REGISTER_ENTRY RealMapRegisterBase;
PHYSICAL_ADDRESS PhysicalAddress;
PHYSICAL_ADDRESS HighestAcceptableAddress;
if ((ULONG_PTR)MapRegisterBase & MAP_BASE_SW_SG &&
TransferLength < *Length)
{
- RealMapRegisterBase->UseMapRegisters = TRUE;
+ UseMapRegisters = TRUE;
PhysicalAddress = RealMapRegisterBase->PhysicalAddress;
+ PhysicalAddress.QuadPart += ByteOffset;
TransferLength = *Length;
RealMapRegisterBase->Counter = ~0;
Counter = 0;
* the transfer progress.
*/
- RealMapRegisterBase->UseMapRegisters = FALSE;
+ UseMapRegisters = FALSE;
Counter = RealMapRegisterBase->Counter;
RealMapRegisterBase->Counter += BYTES_TO_PAGES(ByteOffset + TransferLength);
if (PhysicalAddress.QuadPart + TransferLength >
HighestAcceptableAddress.QuadPart)
{
- RealMapRegisterBase->UseMapRegisters = TRUE;
+ UseMapRegisters = TRUE;
PhysicalAddress = RealMapRegisterBase->PhysicalAddress;
+ PhysicalAddress.QuadPart += ByteOffset;
if ((ULONG_PTR)MapRegisterBase & MAP_BASE_SW_SG)
{
RealMapRegisterBase->Counter = ~0;
* register memory.
*/
- if (RealMapRegisterBase->UseMapRegisters && WriteToDevice)
+ if (UseMapRegisters && WriteToDevice)
{
HalpCopyBufferMap(Mdl, RealMapRegisterBase + Counter,
CurrentVa, TransferLength, WriteToDevice);