- 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;
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);

View file

@ -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;
}

View file

@ -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;