mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 10:04:49 +00:00
- 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:
parent
df756bcc24
commit
6947ecd976
3 changed files with 59 additions and 40 deletions
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in a new issue