From 6947ecd9767c9762570c62ed9ce8e2727b84f6e9 Mon Sep 17 00:00:00 2001 From: Filip Navara Date: Sun, 9 Jan 2005 14:11:25 +0000 Subject: [PATCH] - Output correct length and page to the controller on DMA transfers. - Fix the value of AdapterObject->PagePort. - Don't modify variables we're not supposed to modify in IoMapTransfer. svn path=/trunk/; revision=12906 --- reactos/hal/halx86/generic/adapter.c | 50 ++++++++++++++++------------ reactos/hal/halx86/generic/dma.c | 42 ++++++++++++++--------- reactos/hal/halx86/include/hal.h | 7 ++-- 3 files changed, 59 insertions(+), 40 deletions(-) diff --git a/reactos/hal/halx86/generic/adapter.c b/reactos/hal/halx86/generic/adapter.c index 6fb678392c2..5debe5d853c 100644 --- a/reactos/hal/halx86/generic/adapter.c +++ b/reactos/hal/halx86/generic/adapter.c @@ -479,18 +479,13 @@ IoMapTransfer ( { PHYSICAL_ADDRESS Address; KIRQL OldIrql; - UCHAR Mode; + ULONG LengthShift = 0; -#if defined(__GNUC__) - Address.QuadPart = 0ULL; -#else Address.QuadPart = 0; -#endif /* Isa System (slave) DMA? */ if (MapRegisterBase && !AdapterObject->MasterDevice) { - KeAcquireSpinLock(&AdapterObject->SpinLock, &OldIrql); /* @@ -510,11 +505,8 @@ IoMapTransfer ( * -- Filip Navara, 19/07/2004 */ - /* Get the mode for easier coding */ - Mode = AdapterObject->AdapterMode; - /* if it is a write to the device, copy the caller buffer to the low buffer */ - if ((WriteToDevice) && !((PDMA_MODE)&Mode)->AutoInitialize) + if (WriteToDevice && !AdapterObject->AdapterMode.AutoInitialize) { memcpy(MapRegisterBase, (char*)MmGetSystemAddressForMdl(Mdl) + ((ULONG)CurrentVa - (ULONG)MmGetMdlVirtualAddress(Mdl)), @@ -522,59 +514,73 @@ IoMapTransfer ( } /* Writer Adapter Mode, transfer type */ - ((PDMA_MODE)&Mode)->TransferType = (WriteToDevice ? WRITE_TRANSFER : READ_TRANSFER); + AdapterObject->AdapterMode.TransferType = (WriteToDevice ? WRITE_TRANSFER : READ_TRANSFER); - // program up the dma controller, and return - if (!((PDMA_MODE)&Mode)->AutoInitialize) { + /* program up the dma controller, and return */ + if (!AdapterObject->AdapterMode.AutoInitialize) { Address = MmGetPhysicalAddress( MapRegisterBase ); } else { Address = MmGetPhysicalAddress( CurrentVa ); } /* 16-bit DMA has a shifted length */ - if (AdapterObject->Width16Bits) *Length = (*Length >> 1); + if (AdapterObject->Width16Bits) { + LengthShift = 1; + } /* Make the Transfer */ if (AdapterObject->AdapterNumber == 1) { PDMA1_CONTROL DmaControl1 = AdapterObject->AdapterBaseVa; /* For Writing Less Code */ + /* Mask the Channel */ + WRITE_PORT_UCHAR(&DmaControl1->SingleMask, AdapterObject->ChannelNumber | DMA_SETMASK); + /* Reset Register */ WRITE_PORT_UCHAR(&DmaControl1->ClearBytePointer, 0); /* Set the Mode */ - WRITE_PORT_UCHAR(&DmaControl1->Mode, (UCHAR)(Mode)); + WRITE_PORT_UCHAR(&DmaControl1->Mode, AdapterObject->AdapterModeByte); - /* Set the Page Register (apparently always 0 for us if I trust the previous comment) */ + /* Set the Page Register */ + WRITE_PORT_UCHAR(AdapterObject->PagePort, (UCHAR)(Address.u.LowPart >> 16)); + + /* Set the Offset Register (apparently always 0 for us if I trust the previous comment) */ WRITE_PORT_UCHAR(&DmaControl1->DmaAddressCount[AdapterObject->ChannelNumber].DmaBaseAddress, 0); WRITE_PORT_UCHAR(&DmaControl1->DmaAddressCount[AdapterObject->ChannelNumber].DmaBaseAddress, 0); /* Set the Length */ WRITE_PORT_UCHAR(&DmaControl1->DmaAddressCount[AdapterObject->ChannelNumber].DmaBaseCount, - (UCHAR)((*Length) - 1)); + (UCHAR)((*Length >> LengthShift) - 1)); WRITE_PORT_UCHAR(&DmaControl1->DmaAddressCount[AdapterObject->ChannelNumber].DmaBaseCount, - (UCHAR)((*Length) - 1) >> 8); + (UCHAR)(((*Length >> LengthShift) - 1) >> 8)); /* Unmask the Channel */ WRITE_PORT_UCHAR(&DmaControl1->SingleMask, AdapterObject->ChannelNumber | DMA_CLEARMASK); } else { PDMA2_CONTROL DmaControl2 = AdapterObject->AdapterBaseVa; /* For Writing Less Code */ + /* Mask the Channel */ + WRITE_PORT_UCHAR(&DmaControl2->SingleMask, AdapterObject->ChannelNumber | DMA_SETMASK); + /* Reset Register */ WRITE_PORT_UCHAR(&DmaControl2->ClearBytePointer, 0); /* Set the Mode */ - WRITE_PORT_UCHAR(&DmaControl2->Mode, (UCHAR)(Mode)); + WRITE_PORT_UCHAR(&DmaControl2->Mode, AdapterObject->AdapterModeByte); - /* Set the Page Register (apparently always 0 for us if I trust the previous comment) */ + /* Set the Page Register */ + WRITE_PORT_UCHAR(AdapterObject->PagePort, (UCHAR)(Address.u.LowPart >> 16)); + + /* Set the Offset Register (apparently always 0 for us if I trust the previous comment) */ WRITE_PORT_UCHAR(&DmaControl2->DmaAddressCount[AdapterObject->ChannelNumber].DmaBaseAddress, 0); WRITE_PORT_UCHAR(&DmaControl2->DmaAddressCount[AdapterObject->ChannelNumber].DmaBaseAddress, 0); /* Set the Length */ WRITE_PORT_UCHAR(&DmaControl2->DmaAddressCount[AdapterObject->ChannelNumber].DmaBaseCount, - (UCHAR)((*Length) - 1)); + (UCHAR)((*Length >> LengthShift) - 1)); WRITE_PORT_UCHAR(&DmaControl2->DmaAddressCount[AdapterObject->ChannelNumber].DmaBaseCount, - (UCHAR)((*Length) - 1) >> 8); + (UCHAR)(((*Length >> LengthShift) - 1) >> 8)); /* Unmask the Channel */ WRITE_PORT_UCHAR(&DmaControl2->SingleMask, AdapterObject->ChannelNumber | DMA_CLEARMASK); diff --git a/reactos/hal/halx86/generic/dma.c b/reactos/hal/halx86/generic/dma.c index 02793ffcb79..ddf474fc8ff 100644 --- a/reactos/hal/halx86/generic/dma.c +++ b/reactos/hal/halx86/generic/dma.c @@ -122,6 +122,7 @@ HalGetAdapter (PDEVICE_DESCRIPTION DeviceDescription, DWORD Controller; ULONG MaximumLength; BOOLEAN ChannelSetup; + DMA_MODE DmaMode; DPRINT("Entered Function\n"); @@ -254,16 +255,20 @@ HalGetAdapter (PDEVICE_DESCRIPTION DeviceDescription, switch (ChannelSelect) { case 0: - AdapterObject->PagePort = (PUCHAR)(FIELD_OFFSET(DMA_PAGE, Channel0)); + AdapterObject->PagePort = (PUCHAR)(FIELD_OFFSET(DMA_PAGE, Channel0) + + FIELD_OFFSET(EISA_CONTROL, DmaController1Pages)); break; case 1: - AdapterObject->PagePort = (PUCHAR)(FIELD_OFFSET(DMA_PAGE, Channel1)); + AdapterObject->PagePort = (PUCHAR)(FIELD_OFFSET(DMA_PAGE, Channel1) + + FIELD_OFFSET(EISA_CONTROL, DmaController1Pages)); break; case 2: - AdapterObject->PagePort = (PUCHAR)(FIELD_OFFSET(DMA_PAGE, Channel2)); + AdapterObject->PagePort = (PUCHAR)(FIELD_OFFSET(DMA_PAGE, Channel2) + + FIELD_OFFSET(EISA_CONTROL, DmaController1Pages)); break; case 3: - AdapterObject->PagePort = (PUCHAR)(FIELD_OFFSET(DMA_PAGE, Channel3)); + AdapterObject->PagePort = (PUCHAR)(FIELD_OFFSET(DMA_PAGE, Channel3) + + FIELD_OFFSET(EISA_CONTROL, DmaController1Pages)); break; } @@ -273,13 +278,16 @@ HalGetAdapter (PDEVICE_DESCRIPTION DeviceDescription, switch (ChannelSelect) { case 1: - AdapterObject->PagePort = (PUCHAR)(FIELD_OFFSET(DMA_PAGE, Channel5)); + AdapterObject->PagePort = (PUCHAR)(FIELD_OFFSET(DMA_PAGE, Channel5) + + FIELD_OFFSET(EISA_CONTROL, DmaController1Pages)); break; case 2: - AdapterObject->PagePort = (PUCHAR)(FIELD_OFFSET(DMA_PAGE, Channel6)); + AdapterObject->PagePort = (PUCHAR)(FIELD_OFFSET(DMA_PAGE, Channel6) + + FIELD_OFFSET(EISA_CONTROL, DmaController1Pages)); break; case 3: - AdapterObject->PagePort = (PUCHAR)(FIELD_OFFSET(DMA_PAGE, Channel7)); + AdapterObject->PagePort = (PUCHAR)(FIELD_OFFSET(DMA_PAGE, Channel7) + + FIELD_OFFSET(EISA_CONTROL, DmaController1Pages)); break; } @@ -341,7 +349,8 @@ HalGetAdapter (PDEVICE_DESCRIPTION DeviceDescription, *((PUCHAR)&ExtendedMode)); } } - /* Do 8/16-bit validation */ + + /* Do 8/16-bit validation */ DPRINT("Validating an Adapter Object\n"); if (!DeviceDescription->Master) { if ((DeviceDescription->DmaWidth == Width8Bits) && (Controller != 1)) { @@ -354,18 +363,19 @@ HalGetAdapter (PDEVICE_DESCRIPTION DeviceDescription, } } } - UCHAR DmaMode; - DPRINT("Final DMA Request Mode Setting of the Adapter Object\n"); + + DPRINT("Final DMA Request Mode Setting of the Adapter Object\n"); + /* Set the DMA Request Modes */ if (DeviceDescription->Master) { /* This is a cascade request */ - ((PDMA_MODE)&DmaMode)->RequestMode = CASCADE_REQUEST_MODE; + DmaMode.RequestMode = CASCADE_REQUEST_MODE; /* Send the request */ if (AdapterObject->AdapterNumber == 1) { /* Set the Request Data */ WRITE_PORT_UCHAR(&((PDMA1_CONTROL)AdapterObject->AdapterBaseVa)->Mode, - AdapterObject->AdapterMode); + AdapterObject->AdapterModeByte); /* Unmask DMA Channel */ WRITE_PORT_UCHAR(&((PDMA1_CONTROL)AdapterObject->AdapterBaseVa)->SingleMask, @@ -373,7 +383,7 @@ HalGetAdapter (PDEVICE_DESCRIPTION DeviceDescription, } else { /* Set the Request Data */ WRITE_PORT_UCHAR(&((PDMA2_CONTROL)AdapterObject->AdapterBaseVa)->Mode, - AdapterObject->AdapterMode); + AdapterObject->AdapterModeByte); /* Unmask DMA Channel */ WRITE_PORT_UCHAR(&((PDMA2_CONTROL)AdapterObject->AdapterBaseVa)->SingleMask, @@ -381,14 +391,14 @@ HalGetAdapter (PDEVICE_DESCRIPTION DeviceDescription, } } else if (DeviceDescription->DemandMode) { /* This is a Demand request */ - ((PDMA_MODE)&DmaMode)->RequestMode = DEMAND_REQUEST_MODE; + DmaMode.RequestMode = DEMAND_REQUEST_MODE; } else { /* Normal Request */ - ((PDMA_MODE)&DmaMode)->RequestMode = SINGLE_REQUEST_MODE; + DmaMode.RequestMode = SINGLE_REQUEST_MODE; } /* Auto Initialize Enabled or Not*/ - ((PDMA_MODE)&DmaMode)->AutoInitialize = DeviceDescription->AutoInitialize; + DmaMode.AutoInitialize = DeviceDescription->AutoInitialize; AdapterObject->AdapterMode = DmaMode; return AdapterObject; } diff --git a/reactos/hal/halx86/include/hal.h b/reactos/hal/halx86/include/hal.h index f63247ef768..dbd54385860 100644 --- a/reactos/hal/halx86/include/hal.h +++ b/reactos/hal/halx86/include/hal.h @@ -354,8 +354,11 @@ struct _ADAPTER_OBJECT { UCHAR ChannelNumber; UCHAR AdapterNumber; USHORT DmaPortAddress; - UCHAR AdapterMode; - BOOLEAN NeedsMapRegisters; + union { + DMA_MODE AdapterMode; + UCHAR AdapterModeByte; + }; + BOOLEAN NeedsMapRegisters; BOOLEAN MasterDevice; UCHAR Width16Bits; UCHAR ScatterGather;