- 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
This commit is contained in:
Filip Navara 2005-01-09 14:11:25 +00:00
parent df756bcc24
commit 6947ecd976
3 changed files with 59 additions and 40 deletions

View file

@ -479,18 +479,13 @@ IoMapTransfer (
{ {
PHYSICAL_ADDRESS Address; PHYSICAL_ADDRESS Address;
KIRQL OldIrql; KIRQL OldIrql;
UCHAR Mode; ULONG LengthShift = 0;
#if defined(__GNUC__)
Address.QuadPart = 0ULL;
#else
Address.QuadPart = 0; Address.QuadPart = 0;
#endif
/* Isa System (slave) DMA? */ /* Isa System (slave) DMA? */
if (MapRegisterBase && !AdapterObject->MasterDevice) if (MapRegisterBase && !AdapterObject->MasterDevice)
{ {
KeAcquireSpinLock(&AdapterObject->SpinLock, &OldIrql); KeAcquireSpinLock(&AdapterObject->SpinLock, &OldIrql);
/* /*
@ -510,11 +505,8 @@ IoMapTransfer (
* -- Filip Navara, 19/07/2004 * -- 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 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, memcpy(MapRegisterBase,
(char*)MmGetSystemAddressForMdl(Mdl) + ((ULONG)CurrentVa - (ULONG)MmGetMdlVirtualAddress(Mdl)), (char*)MmGetSystemAddressForMdl(Mdl) + ((ULONG)CurrentVa - (ULONG)MmGetMdlVirtualAddress(Mdl)),
@ -522,59 +514,73 @@ IoMapTransfer (
} }
/* Writer Adapter Mode, transfer type */ /* 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 /* program up the dma controller, and return */
if (!((PDMA_MODE)&Mode)->AutoInitialize) { if (!AdapterObject->AdapterMode.AutoInitialize) {
Address = MmGetPhysicalAddress( MapRegisterBase ); Address = MmGetPhysicalAddress( MapRegisterBase );
} else { } else {
Address = MmGetPhysicalAddress( CurrentVa ); Address = MmGetPhysicalAddress( CurrentVa );
} }
/* 16-bit DMA has a shifted length */ /* 16-bit DMA has a shifted length */
if (AdapterObject->Width16Bits) *Length = (*Length >> 1); if (AdapterObject->Width16Bits) {
LengthShift = 1;
}
/* Make the Transfer */ /* Make the Transfer */
if (AdapterObject->AdapterNumber == 1) { if (AdapterObject->AdapterNumber == 1) {
PDMA1_CONTROL DmaControl1 = AdapterObject->AdapterBaseVa; /* For Writing Less Code */ PDMA1_CONTROL DmaControl1 = AdapterObject->AdapterBaseVa; /* For Writing Less Code */
/* Mask the Channel */
WRITE_PORT_UCHAR(&DmaControl1->SingleMask, AdapterObject->ChannelNumber | DMA_SETMASK);
/* Reset Register */ /* Reset Register */
WRITE_PORT_UCHAR(&DmaControl1->ClearBytePointer, 0); WRITE_PORT_UCHAR(&DmaControl1->ClearBytePointer, 0);
/* Set the Mode */ /* 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);
WRITE_PORT_UCHAR(&DmaControl1->DmaAddressCount[AdapterObject->ChannelNumber].DmaBaseAddress, 0); WRITE_PORT_UCHAR(&DmaControl1->DmaAddressCount[AdapterObject->ChannelNumber].DmaBaseAddress, 0);
/* Set the Length */ /* Set the Length */
WRITE_PORT_UCHAR(&DmaControl1->DmaAddressCount[AdapterObject->ChannelNumber].DmaBaseCount, WRITE_PORT_UCHAR(&DmaControl1->DmaAddressCount[AdapterObject->ChannelNumber].DmaBaseCount,
(UCHAR)((*Length) - 1)); (UCHAR)((*Length >> LengthShift) - 1));
WRITE_PORT_UCHAR(&DmaControl1->DmaAddressCount[AdapterObject->ChannelNumber].DmaBaseCount, WRITE_PORT_UCHAR(&DmaControl1->DmaAddressCount[AdapterObject->ChannelNumber].DmaBaseCount,
(UCHAR)((*Length) - 1) >> 8); (UCHAR)(((*Length >> LengthShift) - 1) >> 8));
/* Unmask the Channel */ /* Unmask the Channel */
WRITE_PORT_UCHAR(&DmaControl1->SingleMask, AdapterObject->ChannelNumber | DMA_CLEARMASK); WRITE_PORT_UCHAR(&DmaControl1->SingleMask, AdapterObject->ChannelNumber | DMA_CLEARMASK);
} else { } else {
PDMA2_CONTROL DmaControl2 = AdapterObject->AdapterBaseVa; /* For Writing Less Code */ PDMA2_CONTROL DmaControl2 = AdapterObject->AdapterBaseVa; /* For Writing Less Code */
/* Mask the Channel */
WRITE_PORT_UCHAR(&DmaControl2->SingleMask, AdapterObject->ChannelNumber | DMA_SETMASK);
/* Reset Register */ /* Reset Register */
WRITE_PORT_UCHAR(&DmaControl2->ClearBytePointer, 0); WRITE_PORT_UCHAR(&DmaControl2->ClearBytePointer, 0);
/* Set the Mode */ /* 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);
WRITE_PORT_UCHAR(&DmaControl2->DmaAddressCount[AdapterObject->ChannelNumber].DmaBaseAddress, 0); WRITE_PORT_UCHAR(&DmaControl2->DmaAddressCount[AdapterObject->ChannelNumber].DmaBaseAddress, 0);
/* Set the Length */ /* Set the Length */
WRITE_PORT_UCHAR(&DmaControl2->DmaAddressCount[AdapterObject->ChannelNumber].DmaBaseCount, WRITE_PORT_UCHAR(&DmaControl2->DmaAddressCount[AdapterObject->ChannelNumber].DmaBaseCount,
(UCHAR)((*Length) - 1)); (UCHAR)((*Length >> LengthShift) - 1));
WRITE_PORT_UCHAR(&DmaControl2->DmaAddressCount[AdapterObject->ChannelNumber].DmaBaseCount, WRITE_PORT_UCHAR(&DmaControl2->DmaAddressCount[AdapterObject->ChannelNumber].DmaBaseCount,
(UCHAR)((*Length) - 1) >> 8); (UCHAR)(((*Length >> LengthShift) - 1) >> 8));
/* Unmask the Channel */ /* Unmask the Channel */
WRITE_PORT_UCHAR(&DmaControl2->SingleMask, AdapterObject->ChannelNumber | DMA_CLEARMASK); WRITE_PORT_UCHAR(&DmaControl2->SingleMask, AdapterObject->ChannelNumber | DMA_CLEARMASK);

View file

@ -122,6 +122,7 @@ HalGetAdapter (PDEVICE_DESCRIPTION DeviceDescription,
DWORD Controller; DWORD Controller;
ULONG MaximumLength; ULONG MaximumLength;
BOOLEAN ChannelSetup; BOOLEAN ChannelSetup;
DMA_MODE DmaMode;
DPRINT("Entered Function\n"); DPRINT("Entered Function\n");
@ -254,16 +255,20 @@ HalGetAdapter (PDEVICE_DESCRIPTION DeviceDescription,
switch (ChannelSelect) { switch (ChannelSelect) {
case 0: case 0:
AdapterObject->PagePort = (PUCHAR)(FIELD_OFFSET(DMA_PAGE, Channel0)); AdapterObject->PagePort = (PUCHAR)(FIELD_OFFSET(DMA_PAGE, Channel0) +
FIELD_OFFSET(EISA_CONTROL, DmaController1Pages));
break; break;
case 1: case 1:
AdapterObject->PagePort = (PUCHAR)(FIELD_OFFSET(DMA_PAGE, Channel1)); AdapterObject->PagePort = (PUCHAR)(FIELD_OFFSET(DMA_PAGE, Channel1) +
FIELD_OFFSET(EISA_CONTROL, DmaController1Pages));
break; break;
case 2: case 2:
AdapterObject->PagePort = (PUCHAR)(FIELD_OFFSET(DMA_PAGE, Channel2)); AdapterObject->PagePort = (PUCHAR)(FIELD_OFFSET(DMA_PAGE, Channel2) +
FIELD_OFFSET(EISA_CONTROL, DmaController1Pages));
break; break;
case 3: case 3:
AdapterObject->PagePort = (PUCHAR)(FIELD_OFFSET(DMA_PAGE, Channel3)); AdapterObject->PagePort = (PUCHAR)(FIELD_OFFSET(DMA_PAGE, Channel3) +
FIELD_OFFSET(EISA_CONTROL, DmaController1Pages));
break; break;
} }
@ -273,13 +278,16 @@ HalGetAdapter (PDEVICE_DESCRIPTION DeviceDescription,
switch (ChannelSelect) { switch (ChannelSelect) {
case 1: case 1:
AdapterObject->PagePort = (PUCHAR)(FIELD_OFFSET(DMA_PAGE, Channel5)); AdapterObject->PagePort = (PUCHAR)(FIELD_OFFSET(DMA_PAGE, Channel5) +
FIELD_OFFSET(EISA_CONTROL, DmaController1Pages));
break; break;
case 2: case 2:
AdapterObject->PagePort = (PUCHAR)(FIELD_OFFSET(DMA_PAGE, Channel6)); AdapterObject->PagePort = (PUCHAR)(FIELD_OFFSET(DMA_PAGE, Channel6) +
FIELD_OFFSET(EISA_CONTROL, DmaController1Pages));
break; break;
case 3: case 3:
AdapterObject->PagePort = (PUCHAR)(FIELD_OFFSET(DMA_PAGE, Channel7)); AdapterObject->PagePort = (PUCHAR)(FIELD_OFFSET(DMA_PAGE, Channel7) +
FIELD_OFFSET(EISA_CONTROL, DmaController1Pages));
break; break;
} }
@ -341,7 +349,8 @@ HalGetAdapter (PDEVICE_DESCRIPTION DeviceDescription,
*((PUCHAR)&ExtendedMode)); *((PUCHAR)&ExtendedMode));
} }
} }
/* Do 8/16-bit validation */
/* Do 8/16-bit validation */
DPRINT("Validating an Adapter Object\n"); DPRINT("Validating an Adapter Object\n");
if (!DeviceDescription->Master) { if (!DeviceDescription->Master) {
if ((DeviceDescription->DmaWidth == Width8Bits) && (Controller != 1)) { 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 */ /* Set the DMA Request Modes */
if (DeviceDescription->Master) { if (DeviceDescription->Master) {
/* This is a cascade request */ /* This is a cascade request */
((PDMA_MODE)&DmaMode)->RequestMode = CASCADE_REQUEST_MODE; DmaMode.RequestMode = CASCADE_REQUEST_MODE;
/* Send the request */ /* Send the request */
if (AdapterObject->AdapterNumber == 1) { if (AdapterObject->AdapterNumber == 1) {
/* Set the Request Data */ /* Set the Request Data */
WRITE_PORT_UCHAR(&((PDMA1_CONTROL)AdapterObject->AdapterBaseVa)->Mode, WRITE_PORT_UCHAR(&((PDMA1_CONTROL)AdapterObject->AdapterBaseVa)->Mode,
AdapterObject->AdapterMode); AdapterObject->AdapterModeByte);
/* Unmask DMA Channel */ /* Unmask DMA Channel */
WRITE_PORT_UCHAR(&((PDMA1_CONTROL)AdapterObject->AdapterBaseVa)->SingleMask, WRITE_PORT_UCHAR(&((PDMA1_CONTROL)AdapterObject->AdapterBaseVa)->SingleMask,
@ -373,7 +383,7 @@ HalGetAdapter (PDEVICE_DESCRIPTION DeviceDescription,
} else { } else {
/* Set the Request Data */ /* Set the Request Data */
WRITE_PORT_UCHAR(&((PDMA2_CONTROL)AdapterObject->AdapterBaseVa)->Mode, WRITE_PORT_UCHAR(&((PDMA2_CONTROL)AdapterObject->AdapterBaseVa)->Mode,
AdapterObject->AdapterMode); AdapterObject->AdapterModeByte);
/* Unmask DMA Channel */ /* Unmask DMA Channel */
WRITE_PORT_UCHAR(&((PDMA2_CONTROL)AdapterObject->AdapterBaseVa)->SingleMask, WRITE_PORT_UCHAR(&((PDMA2_CONTROL)AdapterObject->AdapterBaseVa)->SingleMask,
@ -381,14 +391,14 @@ HalGetAdapter (PDEVICE_DESCRIPTION DeviceDescription,
} }
} else if (DeviceDescription->DemandMode) { } else if (DeviceDescription->DemandMode) {
/* This is a Demand request */ /* This is a Demand request */
((PDMA_MODE)&DmaMode)->RequestMode = DEMAND_REQUEST_MODE; DmaMode.RequestMode = DEMAND_REQUEST_MODE;
} else { } else {
/* Normal Request */ /* Normal Request */
((PDMA_MODE)&DmaMode)->RequestMode = SINGLE_REQUEST_MODE; DmaMode.RequestMode = SINGLE_REQUEST_MODE;
} }
/* Auto Initialize Enabled or Not*/ /* Auto Initialize Enabled or Not*/
((PDMA_MODE)&DmaMode)->AutoInitialize = DeviceDescription->AutoInitialize; DmaMode.AutoInitialize = DeviceDescription->AutoInitialize;
AdapterObject->AdapterMode = DmaMode; AdapterObject->AdapterMode = DmaMode;
return AdapterObject; return AdapterObject;
} }

View file

@ -354,8 +354,11 @@ struct _ADAPTER_OBJECT {
UCHAR ChannelNumber; UCHAR ChannelNumber;
UCHAR AdapterNumber; UCHAR AdapterNumber;
USHORT DmaPortAddress; USHORT DmaPortAddress;
UCHAR AdapterMode; union {
BOOLEAN NeedsMapRegisters; DMA_MODE AdapterMode;
UCHAR AdapterModeByte;
};
BOOLEAN NeedsMapRegisters;
BOOLEAN MasterDevice; BOOLEAN MasterDevice;
UCHAR Width16Bits; UCHAR Width16Bits;
UCHAR ScatterGather; UCHAR ScatterGather;