-/* $Id$
+/*
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
/* INCLUDES *****************************************************************/
#include <hal.h>
+#include <suppress.h>
+
#define NDEBUG
#include <debug.h>
KIRQL OldIrql;
ULONG MapRegisterCount;
- /* FIXME: Check if enough map register slots are available. */
+ /* Check if enough map register slots are available. */
MapRegisterCount = BYTES_TO_PAGES(SizeOfMapBuffers);
+ if (MapRegisterCount + AdapterObject->NumberOfMapRegisters > MAX_MAP_REGISTERS)
+ {
+ DPRINT("No more map register slots available! (Current: %d | Requested: %d | Limit: %d)\n",
+ AdapterObject->NumberOfMapRegisters,
+ MapRegisterCount,
+ MAX_MAP_REGISTERS);
+ return FALSE;
+ }
/*
* Allocate memory for the new map registers. For 32-bit adapters we use
}
RtlClearBit(AdapterObject->MapRegisters,
- CurrentEntry - AdapterObject->MapRegisterBase);
+ (ULONG)(CurrentEntry - AdapterObject->MapRegisterBase));
CurrentEntry->VirtualAddress = VirtualAddress;
CurrentEntry->PhysicalAddress = PhysicalAddress;
if (Controller == 1)
{
/* Set the Request Data */
+ _PRAGMA_WARNING_SUPPRESS(__WARNING_DEREF_NULL_PTR)
WRITE_PORT_UCHAR(&((PDMA1_CONTROL)AdapterBaseVa)->Mode, DmaMode.Byte);
-
+
/* Unmask DMA Channel */
WRITE_PORT_UCHAR(&((PDMA1_CONTROL)AdapterBaseVa)->SingleMask,
AdapterObject->ChannelNumber | DMA_CLEARMASK);
{
/* Set the Request Data */
WRITE_PORT_UCHAR(&((PDMA2_CONTROL)AdapterBaseVa)->Mode, DmaMode.Byte);
-
+
/* Unmask DMA Channel */
WRITE_PORT_UCHAR(&((PDMA2_CONTROL)AdapterBaseVa)->SingleMask,
AdapterObject->ChannelNumber | DMA_CLEARMASK);
OUT PULONG NumberOfMapRegisters)
{
PADAPTER_OBJECT AdapterObject = NULL;
- PADAPTER_OBJECT MasterAdapter;
BOOLEAN EisaAdapter;
ULONG MapRegisters;
ULONG MaximumLength;
* Also note that we check for channel number since there are only 8 DMA
* channels on ISA, so any request above this requires new adapter.
*/
- if ((DeviceDescription->InterfaceType == Isa) || !(DeviceDescription->Master))
+ if (((DeviceDescription->InterfaceType == Eisa) ||
+ (DeviceDescription->InterfaceType == Isa)) || !(DeviceDescription->Master))
{
- if ((DeviceDescription->InterfaceType == Isa) && (DeviceDescription->DmaChannel >= 8))
+ if (((DeviceDescription->InterfaceType == Isa) ||
+ (DeviceDescription->InterfaceType == Eisa)) &&
+ (DeviceDescription->DmaChannel >= 8))
{
EisaAdapter = FALSE;
}
if (MapRegisters > 0)
{
AdapterObject->NeedsMapRegisters = TRUE;
- MasterAdapter = HalpMasterAdapter;
AdapterObject->MapRegistersPerChannel = MapRegisters;
-
- /*
- * FIXME: Verify that the following makes sense. Actually
- * MasterAdapter->NumberOfMapRegisters contains even the number
- * of gaps, so this will not work correctly all the time. It
- * doesn't matter much since it's only optimization to avoid
- * queuing work items in HalAllocateAdapterChannel.
- */
- MasterAdapter->CommittedMapRegisters += MapRegisters;
- if (MasterAdapter->CommittedMapRegisters > MasterAdapter->NumberOfMapRegisters)
- {
- HalpGrowMapBuffers(MasterAdapter, 0x10000);
- }
}
else
{
ULONG MapRegisterCount;
BOOLEAN WriteToDevice;
} SCATTER_GATHER_CONTEXT, *PSCATTER_GATHER_CONTEXT;
-
+
IO_ALLOCATION_ACTION
NTAPI
SCATTER_GATHER_ELEMENT TempElements[MAX_SG_ELEMENTS];
ULONG ElementCount = 0, RemainingLength = AdapterControlContext->Length;
PUCHAR CurrentVa = AdapterControlContext->CurrentVa;
-
+
/* Store the map register base for later in HalPutScatterGatherList */
AdapterControlContext->MapRegisterBase = MapRegisterBase;
-
+
while (RemainingLength > 0 && ElementCount < MAX_SG_ELEMENTS)
{
TempElements[ElementCount].Length = RemainingLength;
AdapterControlContext->WriteToDevice);
if (TempElements[ElementCount].Length == 0)
break;
-
+
DPRINT("Allocated one S/G element: 0x%I64u with length: 0x%x\n",
TempElements[ElementCount].Address.QuadPart,
TempElements[ElementCount].Length);
-
+
ASSERT(TempElements[ElementCount].Length <= RemainingLength);
RemainingLength -= TempElements[ElementCount].Length;
ElementCount++;
}
-
+
if (RemainingLength > 0)
{
DPRINT1("Scatter/gather list construction failed!\n");
RtlCopyMemory(ScatterGatherList->Elements,
TempElements,
sizeof(SCATTER_GATHER_ELEMENT) * ElementCount);
-
+
DPRINT("Initiating S/G DMA with %d element(s)\n", ElementCount);
-
+
AdapterControlContext->AdapterListControlRoutine(DeviceObject,
Irp,
ScatterGatherList,
AdapterControlContext->AdapterListControlContext);
-
+
return DeallocateObjectKeepRegisters;
}
IN BOOLEAN WriteToDevice)
{
PSCATTER_GATHER_CONTEXT AdapterControlContext;
-
+
AdapterControlContext = ExAllocatePoolWithTag(NonPagedPool, sizeof(SCATTER_GATHER_CONTEXT), TAG_DMA);
if (!AdapterControlContext) return STATUS_INSUFFICIENT_RESOURCES;
-
+
AdapterControlContext->AdapterObject = AdapterObject;
AdapterControlContext->Mdl = Mdl;
AdapterControlContext->CurrentVa = CurrentVa;
AdapterControlContext->AdapterListControlRoutine = ExecutionRoutine;
AdapterControlContext->AdapterListControlContext = Context;
AdapterControlContext->WriteToDevice = WriteToDevice;
-
+
return IoAllocateAdapterChannel(AdapterObject,
DeviceObject,
AdapterControlContext->MapRegisterCount,
{
PSCATTER_GATHER_CONTEXT AdapterControlContext = (PSCATTER_GATHER_CONTEXT)ScatterGather->Reserved;
ULONG i;
-
+
for (i = 0; i < ScatterGather->NumberOfElements; i++)
{
IoFlushAdapterBuffers(AdapterObject,
IoFreeMapRegisters(AdapterObject,
AdapterControlContext->MapRegisterBase,
AdapterControlContext->MapRegisterCount);
-
+
DPRINT("S/G DMA has finished!\n");
-
+
ExFreePoolWithTag(AdapterControlContext, TAG_DMA);
ExFreePoolWithTag(ScatterGather, TAG_DMA);
}
do
{
OldCount = Count;
-
+
/* Send Reset */
WRITE_PORT_UCHAR(&DmaControl1->ClearBytePointer, 0);
-
+
/* Read Count */
Count = READ_PORT_UCHAR(&DmaControl1->DmaAddressCount
[AdapterObject->ChannelNumber].DmaBaseCount);
do
{
OldCount = Count;
-
+
/* Send Reset */
WRITE_PORT_UCHAR(&DmaControl2->ClearBytePointer, 0);
-
+
/* Read Count */
Count = READ_PORT_UCHAR(&DmaControl2->DmaAddressCount
[AdapterObject->ChannelNumber].DmaBaseCount);
*/
KeWaitForSingleObject(&HalpDmaLock, Executive, KernelMode, FALSE, NULL);
Succeeded = HalpGrowMapBuffers(WorkItem->AdapterObject->MasterAdapter,
- WorkItem->NumberOfMapRegisters);
+ WorkItem->NumberOfMapRegisters << PAGE_SHIFT);
KeSetEvent(&HalpDmaLock, 0, 0);
if (Succeeded)
if (Index == MAXULONG)
{
+ InsertTailList(&MasterAdapter->AdapterQueue, &AdapterObject->AdapterQueue);
+
WorkItem = ExAllocatePoolWithTag(NonPagedPool,
sizeof(GROW_WORK_ITEM),
TAG_DMA);
- if (!WorkItem)
+ if (WorkItem)
{
- KeReleaseSpinLock(&MasterAdapter->SpinLock, OldIrql);
- AdapterObject->NumberOfMapRegisters = 0;
- IoFreeAdapterChannel(AdapterObject);
- return STATUS_INSUFFICIENT_RESOURCES;
- }
-
- InsertTailList(&MasterAdapter->AdapterQueue, &AdapterObject->AdapterQueue);
-
- ExInitializeWorkItem(&WorkItem->WorkQueueItem, HalpGrowMapBufferWorker, WorkItem);
- WorkItem->AdapterObject = AdapterObject;
- WorkItem->NumberOfMapRegisters = NumberOfMapRegisters;
+ ExInitializeWorkItem(&WorkItem->WorkQueueItem, HalpGrowMapBufferWorker, WorkItem);
+ WorkItem->AdapterObject = AdapterObject;
+ WorkItem->NumberOfMapRegisters = NumberOfMapRegisters;
- ExQueueWorkItem(&WorkItem->WorkQueueItem, DelayedWorkQueue);
+ ExQueueWorkItem(&WorkItem->WorkQueueItem, DelayedWorkQueue);
+ }
KeReleaseSpinLock(&MasterAdapter->SpinLock, OldIrql);
DeviceQueueEntry = KeRemoveDeviceQueue(&AdapterObject->ChannelWaitQueue);
if (!DeviceQueueEntry) break;
-
+
WaitContextBlock = CONTAINING_RECORD(DeviceQueueEntry,
WAIT_CONTEXT_BLOCK,
WaitQueueEntry);
RealMapRegisterBase = (PROS_MAP_REGISTER_ENTRY)((ULONG_PTR)MapRegisterBase & ~MAP_BASE_SW_SG);
RtlClearBits(MasterAdapter->MapRegisters,
- RealMapRegisterBase - MasterAdapter->MapRegisterBase,
+ (ULONG)(RealMapRegisterBase - MasterAdapter->MapRegisterBase),
NumberOfMapRegisters);
}
Index = RtlFindClearBitsAndSet(MasterAdapter->MapRegisters,
AdapterObject->NumberOfMapRegisters,
- MasterAdapter->NumberOfMapRegisters);
+ 0);
if (Index == MAXULONG)
{
InsertHeadList(&MasterAdapter->AdapterQueue, ListEntry);
{
KeAcquireSpinLock(&MasterAdapter->SpinLock, &OldIrql);
RtlClearBits(MasterAdapter->MapRegisters,
- AdapterObject->MapRegisterBase -
- MasterAdapter->MapRegisterBase,
+ (ULONG)(AdapterObject->MapRegisterBase -
+ MasterAdapter->MapRegisterBase),
AdapterObject->NumberOfMapRegisters);
KeReleaseSpinLock(&MasterAdapter->SpinLock, OldIrql);
}
-
+
IoFreeAdapterChannel(AdapterObject);
break;
/* Reset Register */
WRITE_PORT_UCHAR(&DmaControl1->ClearBytePointer, 0);
-
+
/* Set the Mode */
WRITE_PORT_UCHAR(&DmaControl1->Mode, AdapterMode.Byte);
-
+
/* Set the Offset Register */
WRITE_PORT_UCHAR(&DmaControl1->DmaAddressCount[AdapterObject->ChannelNumber].DmaBaseAddress,
(UCHAR)(TransferOffset));
WRITE_PORT_UCHAR(&DmaControl1->DmaAddressCount[AdapterObject->ChannelNumber].DmaBaseAddress,
(UCHAR)(TransferOffset >> 8));
-
+
/* Set the Page Register */
WRITE_PORT_UCHAR(AdapterObject->PagePort + FIELD_OFFSET(EISA_CONTROL, DmaController1Pages),
(UCHAR)(PhysicalAddress.LowPart >> 16));
WRITE_PORT_UCHAR(AdapterObject->PagePort + FIELD_OFFSET(EISA_CONTROL, DmaController2Pages),
0);
}
-
+
/* Set the Length */
WRITE_PORT_UCHAR(&DmaControl1->DmaAddressCount[AdapterObject->ChannelNumber].DmaBaseCount,
(UCHAR)(TransferLength - 1));
WRITE_PORT_UCHAR(&DmaControl1->DmaAddressCount[AdapterObject->ChannelNumber].DmaBaseCount,
(UCHAR)((TransferLength - 1) >> 8));
-
+
/* Unmask the Channel */
WRITE_PORT_UCHAR(&DmaControl1->SingleMask, AdapterObject->ChannelNumber | DMA_CLEARMASK);
}
/* Reset Register */
WRITE_PORT_UCHAR(&DmaControl2->ClearBytePointer, 0);
-
+
/* Set the Mode */
WRITE_PORT_UCHAR(&DmaControl2->Mode, AdapterMode.Byte);
-
+
/* Set the Offset Register */
WRITE_PORT_UCHAR(&DmaControl2->DmaAddressCount[AdapterObject->ChannelNumber].DmaBaseAddress,
(UCHAR)(TransferOffset));
WRITE_PORT_UCHAR(&DmaControl2->DmaAddressCount[AdapterObject->ChannelNumber].DmaBaseAddress,
(UCHAR)(TransferOffset >> 8));
-
+
/* Set the Page Register */
WRITE_PORT_UCHAR(AdapterObject->PagePort + FIELD_OFFSET(EISA_CONTROL, DmaController1Pages),
(UCHAR)(PhysicalAddress.u.LowPart >> 16));
WRITE_PORT_UCHAR(AdapterObject->PagePort + FIELD_OFFSET(EISA_CONTROL, DmaController2Pages),
0);
}
-
+
/* Set the Length */
WRITE_PORT_UCHAR(&DmaControl2->DmaAddressCount[AdapterObject->ChannelNumber].DmaBaseCount,
(UCHAR)(TransferLength - 1));
WRITE_PORT_UCHAR(&DmaControl2->DmaAddressCount[AdapterObject->ChannelNumber].DmaBaseCount,
(UCHAR)((TransferLength - 1) >> 8));
-
+
/* Unmask the Channel */
WRITE_PORT_UCHAR(&DmaControl2->SingleMask,
AdapterObject->ChannelNumber | DMA_CLEARMASK);