use correct wait mode when checking alertability in
KeDelayExecuteThread. thanks to gunnar for noticing the bug
Modified: trunk/reactos/ntoskrnl/ke/wait.c
_____
Modified: trunk/reactos/ntoskrnl/ke/wait.c
--- trunk/reactos/ntoskrnl/ke/wait.c 2005-08-22 21:35:41 UTC (rev
17478)
+++ trunk/reactos/ntoskrnl/ke/wait.c 2005-08-22 23:33:51 UTC (rev
17479)
@@ -111,7 +111,7 @@
do {
/* We are going to wait no matter what (that's the point), so
test Alertability */
- if (KiCheckAlertability(Alertable, CurrentThread, KernelMode,
&Status))
+ if (KiCheckAlertability(Alertable, CurrentThread, WaitMode,
&Status))
break;
/* Set Timer */
Actually break out of the wait loops if we got alerted.
Modified: trunk/reactos/ntoskrnl/ke/wait.c
_____
Modified: trunk/reactos/ntoskrnl/ke/wait.c
--- trunk/reactos/ntoskrnl/ke/wait.c 2005-08-22 15:20:49 UTC (rev
17477)
+++ trunk/reactos/ntoskrnl/ke/wait.c 2005-08-22 21:35:41 UTC (rev
17478)
@@ -27,7 +27,7 @@
/* FUNCTIONS
*****************************************************************/
-VOID
+BOOLEAN
inline
FASTCALL
KiCheckAlertability(BOOLEAN Alertable,
@@ -44,6 +44,7 @@
CurrentThread->Alerted[(int)WaitMode] = FALSE;
DPRINT("Thread was Alerted\n");
*Status = STATUS_ALERTED;
+ return TRUE;
/* If there are User APCs Pending, then we can't really be
alertable */
} else if
((!IsListEmpty(&CurrentThread->ApcState.ApcListHead[UserMode])) &&
@@ -52,13 +53,17 @@
DPRINT("APCs are Pending\n");
CurrentThread->ApcState.UserApcPending = TRUE;
*Status = STATUS_USER_APC;
+ return TRUE;
}
/* If there are User APCs Pending and we are waiting in usermode,
then we must notify the caller */
} else if ((CurrentThread->ApcState.UserApcPending) && (WaitMode !=
KernelMode)) {
DPRINT("APCs are Pending\n");
*Status = STATUS_USER_APC;
+ return TRUE;
}
+
+ return FALSE;
}
/*
@@ -106,7 +111,8 @@
do {
/* We are going to wait no matter what (that's the point), so
test Alertability */
- KiCheckAlertability(Alertable, CurrentThread, KernelMode,
&Status);
+ if (KiCheckAlertability(Alertable, CurrentThread, KernelMode,
&Status))
+ break;
/* Set Timer */
ThreadTimer = &CurrentThread->Timer;
@@ -256,7 +262,8 @@
WaitBlock->NextWaitBlock = WaitBlock;
/* Make sure we can satisfy the Alertable request */
- KiCheckAlertability(Alertable, CurrentThread, WaitMode,
&Status);
+ if (KiCheckAlertability(Alertable, CurrentThread, WaitMode,
&Status))
+ break;
/* Set the Wait Status */
CurrentThread->WaitStatus = Status;
@@ -485,7 +492,8 @@
}
/* Make sure we can satisfy the Alertable request */
- KiCheckAlertability(Alertable, CurrentThread, WaitMode,
&Status);
+ if (KiCheckAlertability(Alertable, CurrentThread, WaitMode,
&Status))
+ break;
/* Set the Wait Status */
CurrentThread->WaitStatus = Status;
rename IsKernelPointer to IsPointerOffset
Modified: trunk/reactos/ntoskrnl/include/internal/ntoskrnl.h
Modified: trunk/reactos/ntoskrnl/ob/wait.c
_____
Modified: trunk/reactos/ntoskrnl/include/internal/ntoskrnl.h
--- trunk/reactos/ntoskrnl/include/internal/ntoskrnl.h 2005-08-22
14:39:10 UTC (rev 17476)
+++ trunk/reactos/ntoskrnl/include/internal/ntoskrnl.h 2005-08-22
15:20:49 UTC (rev 17477)
@@ -148,22 +148,22 @@
#define ProbeForReadUlargeInteger(Ptr)
((ULARGE_INTEGER)ProbeForReadGenericType(&(Ptr)->QuadPart, ULONGLONG,
0))
/*
- * Use IsKernelPointer to test whether a pointer points to the kernel
address
- * space
+ * Use IsPointerOffset to test whether a pointer should be interpreted
as an offset
+ * or as a pointer
*/
#if defined(_X86_) || defined(_M_AMD64)
/* for x86 and x86-64 the MSB is 1 so we can simply test on that */
-#define IsKernelPointer(Ptr) ((LONG_PTR)(Ptr) < 0)
+#define IsPointerOffset(Ptr) ((LONG_PTR)(Ptr) >= 0)
#elif defined(_IA64_)
/* on Itanium if the 24 most significant bits are set, we're not
dealing with
- user mode pointers. */
-#define IsKernelPointer(Ptr) (((ULONG_PTR)(Ptr) &
0xFFFFFF0000000000ULL) != 0)
+ offsets anymore. */
+#define IsPointerOffset(Ptr) (((ULONG_PTR)(Ptr) &
0xFFFFFF0000000000ULL) == 0)
#else
-#error IsKernelPointer() needs to be defined for this architecture
+#error IsPointerOffset() needs to be defined for this architecture
#endif
#endif
_____
Modified: trunk/reactos/ntoskrnl/ob/wait.c
--- trunk/reactos/ntoskrnl/ob/wait.c 2005-08-22 14:39:10 UTC (rev
17476)
+++ trunk/reactos/ntoskrnl/ob/wait.c 2005-08-22 15:20:49 UTC (rev
17477)
@@ -149,7 +149,7 @@
DefaultObject = ObjectHeader->Type->DefaultObject;
/* Check if it's the internal offset */
- if (!IsKernelPointer(DefaultObject))
+ if (IsPointerOffset(DefaultObject))
{
/* Increase reference count */
InterlockedIncrement(&ObjectHeader->PointerCount);
@@ -295,7 +295,7 @@
WaitableObject = BODY_TO_HEADER(Object)->Type->DefaultObject;
/* Is it an offset for internal objects? */
- if (!IsKernelPointer(WaitableObject))
+ if (IsPointerOffset(WaitableObject))
{
/* Turn it into a pointer */
WaitableObject = (PVOID)((ULONG_PTR)Object +
@@ -389,7 +389,7 @@
WaitableObject = BODY_TO_HEADER(WaitObj)->Type->DefaultObject;
/* Handle internal offset */
- if (!IsKernelPointer(WaitableObject))
+ if (IsPointerOffset(WaitableObject))
{
/* Get real pointer */
WaitableObject = (PVOID)((ULONG_PTR)WaitObj +
prepare move old cruft
Added: trunk/reactos/lib/crtdll/old cruft/
Added: trunk/reactos/lib/crtdll/old cruft/readme.txt
_____
Added: trunk/reactos/lib/crtdll/old cruft/readme.txt
--- trunk/reactos/lib/crtdll/old cruft/readme.txt 2005-08-22
13:38:30 UTC (rev 17474)
+++ trunk/reactos/lib/crtdll/old cruft/readme.txt 2005-08-22
14:26:37 UTC (rev 17475)
@@ -0,0 +1,2 @@
+When merging msvcrt and crtdll into crt, mostly msvcrt stuff were used.
All files in crtdll that was equal to files in msvcrt were deleted but
those who were not are still here, possibly containing changes that we
might want to merge into crt, thou its very likely that the changes are
worthless. Someone should go thru it and either delete or merge
sometime...
+-Gunnar
added a macro IsKernelPointer() to test whether a pointer value points
to the kernel address space. This is needed because on IA-64 the MSB is
not necessarily set for pointers to the kernel address space.
Modified: trunk/reactos/ntoskrnl/include/internal/ntoskrnl.h
Modified: trunk/reactos/ntoskrnl/ob/wait.c
_____
Modified: trunk/reactos/ntoskrnl/include/internal/ntoskrnl.h
--- trunk/reactos/ntoskrnl/include/internal/ntoskrnl.h 2005-08-22
10:51:05 UTC (rev 17473)
+++ trunk/reactos/ntoskrnl/include/internal/ntoskrnl.h 2005-08-22
13:38:30 UTC (rev 17474)
@@ -147,8 +147,26 @@
#define ProbeForReadLargeInteger(Ptr)
((LARGE_INTEGER)ProbeForReadGenericType(&(Ptr)->QuadPart, LONGLONG, 0))
#define ProbeForReadUlargeInteger(Ptr)
((ULARGE_INTEGER)ProbeForReadGenericType(&(Ptr)->QuadPart, ULONGLONG,
0))
+/*
+ * Use IsKernelPointer to test whether a pointer points to the kernel
address
+ * space
+ */
+#if defined(_X86_) || defined(_M_AMD64)
+/* for x86 and x86-64 the MSB is 1 so we can simply test on that */
+#define IsKernelPointer(Ptr) ((LONG_PTR)(Ptr) < 0)
+
+#elif defined(_IA64_)
+
+/* on Itanium if the 24 most significant bits are set, we're not
dealing with
+ user mode pointers. */
+#define IsKernelPointer(Ptr) (((ULONG_PTR)(Ptr) &
0xFFFFFF0000000000ULL) != 0)
+
+#else
+#error IsKernelPointer() needs to be defined for this architecture
#endif
+
+#endif
/*
*
*/
_____
Modified: trunk/reactos/ntoskrnl/ob/wait.c
--- trunk/reactos/ntoskrnl/ob/wait.c 2005-08-22 10:51:05 UTC (rev
17473)
+++ trunk/reactos/ntoskrnl/ob/wait.c 2005-08-22 13:38:30 UTC (rev
17474)
@@ -149,7 +149,7 @@
DefaultObject = ObjectHeader->Type->DefaultObject;
/* Check if it's the internal offset */
- if ((LONG_PTR)DefaultObject >= 0)
+ if (!IsKernelPointer(DefaultObject))
{
/* Increase reference count */
InterlockedIncrement(&ObjectHeader->PointerCount);
@@ -295,7 +295,7 @@
WaitableObject = BODY_TO_HEADER(Object)->Type->DefaultObject;
/* Is it an offset for internal objects? */
- if ((LONG_PTR)WaitableObject >= 0)
+ if (!IsKernelPointer(WaitableObject))
{
/* Turn it into a pointer */
WaitableObject = (PVOID)((ULONG_PTR)Object +
@@ -389,7 +389,7 @@
WaitableObject = BODY_TO_HEADER(WaitObj)->Type->DefaultObject;
/* Handle internal offset */
- if ((LONG_PTR)WaitableObject >= 0)
+ if (!IsKernelPointer(WaitableObject))
{
/* Get real pointer */
WaitableObject = (PVOID)((ULONG_PTR)WaitObj +
Complete reimplementation of HAL DMA routines.
The key changes are
* Proper support for bus-master device adapters.
* Real implementation of map registers.
* Basic support for emulating scatter/gather DMA on
devices that don't support it in hardware.
* Support for transfers that aren't page aligned.
* Proper detection and support of EISA DMA controllers.
* Fixed prototype for HalFlushCommonBuffer.
Modified: trunk/reactos/hal/hal/hal.c
Modified: trunk/reactos/hal/hal/hal.def
Deleted: trunk/reactos/hal/halx86/generic/adapter.c
Modified: trunk/reactos/hal/halx86/generic/dma.c
Modified: trunk/reactos/hal/halx86/generic/generic.xml
Modified: trunk/reactos/hal/halx86/include/hal.h
Added: trunk/reactos/hal/halx86/include/haldma.h
Modified: trunk/reactos/hal/halx86/include/halp.h
_____
Modified: trunk/reactos/hal/hal/hal.c
--- trunk/reactos/hal/hal/hal.c 2005-08-21 20:44:47 UTC (rev 17469)
+++ trunk/reactos/hal/hal/hal.c 2005-08-22 08:39:42 UTC (rev 17470)
@@ -211,10 +211,7 @@
ULONG Unknown2,
ULONG Unknown3,
ULONG Unknown4,
- ULONG Unknown5,
- ULONG Unknown6,
- ULONG Unknown7,
- ULONG Unknown8)
+ ULONG Unknown5)
{
UNIMPLEMENTED;
_____
Modified: trunk/reactos/hal/hal/hal.def
--- trunk/reactos/hal/hal/hal.def 2005-08-21 20:44:47 UTC (rev
17469)
+++ trunk/reactos/hal/hal/hal.def 2005-08-22 08:39:42 UTC (rev
17470)
@@ -20,7 +20,7 @@
HalDisplayString@4
HalEnableSystemInterrupt@12
HalEndSystemInterrupt@8
-HalFlushCommonBuffer@32
+HalFlushCommonBuffer@20
HalFreeCommonBuffer@24
HalGetAdapter@8
HalGetBusData@20
_____
Deleted: trunk/reactos/hal/halx86/generic/adapter.c
--- trunk/reactos/hal/halx86/generic/adapter.c 2005-08-21 20:44:47 UTC
(rev 17469)
+++ trunk/reactos/hal/halx86/generic/adapter.c 2005-08-22 08:39:42 UTC
(rev 17470)
@@ -1,717 +0,0 @@
-/* $Id$
- *
- * COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS kernel
- * FILE: hal/x86/adapter.c (from ntoskrnl/io/adapter.c)
- * PURPOSE: DMA handling
- * PROGRAMMERS: David Welch (welch(a)mcmail.com)
- * Vizzini (vizzini(a)plasmic.com)
- * UPDATE HISTORY:
- * Created 22/05/98
- * 18-Oct-2003 Vizzini DMA support modifications
- */
-
-/* INCLUDES
*****************************************************************/
-
-#include <hal.h>
-#define NDEBUG
-#include <debug.h>
-
-/* FUNCTIONS
*****************************************************************/
-
-/* NOTE: IoAllocateAdapterChannel in NTOSKRNL.EXE */
-
-
-NTSTATUS STDCALL
-HalAllocateAdapterChannel(
- PADAPTER_OBJECT AdapterObject,
- PWAIT_CONTEXT_BLOCK WaitContextBlock,
- ULONG NumberOfMapRegisters,
- PDRIVER_CONTROL ExecutionRoutine)
-/*
- * FUNCTION: Sets up an ADAPTER_OBJECT with map registers
- * ARGUMENTS:
- * - AdapterObject: pointer to an ADAPTER_OBJECT to set up
- * - WaitContextBlock: Context block to be used with
ExecutionRoutine
- * - NumberOfMapRegisters: number of map registers requested
- * - ExecutionRoutine: callback to call when map registers are
allocated
- * RETURNS:
- * STATUS_INSUFFICIENT_RESOURCES if map registers cannot be
allocated
- * STATUS_SUCCESS in all other cases, including if the callbacak
had
- * to be queued for later delivery
- * NOTES:
- * - the ADAPTER_OBJECT struct is undocumented; please make copious
- * notes in hal.h if anything is changed or improved since there
is
- * no other documentation for this data structure
- * BUGS:
- * - it's possible that some of this code is in the wrong place
- * - there are many unhandled cases
- */
-{
- LARGE_INTEGER MinAddress;
- LARGE_INTEGER MaxAddress;
- LARGE_INTEGER BoundryAddressMultiple;
- IO_ALLOCATION_ACTION Retval;
-
- ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);
-
- /*
- FIXME: return STATUS_INSUFFICIENT_RESOURCES if the
NumberOfMapRegisters
- requested is larger than the value returned by IoGetDmaAdapter.
- */
-
- /* set up the wait context block in case we can't run right away */
- WaitContextBlock->DeviceRoutine = ExecutionRoutine;
- WaitContextBlock->NumberOfMapRegisters = NumberOfMapRegisters;
-
- /* returns true if queued, else returns false and sets the queue to
busy */
- if(KeInsertDeviceQueue(&AdapterObject->ChannelWaitQueue,
&WaitContextBlock->WaitQueueEntry))
- return STATUS_SUCCESS;
-
- /* why 64K alignment? */
- /*
- * X86 lacks map registers, so for now, we allocate a contiguous
- * block of physical memory <16MB and copy all DMA buffers into
- * that. This can be optimized.
- *
- * FIXME: We propably shouldn't allocate the memory here for common
- * buffer transfers. See a comment in IoMapTransfer about common
buffer
- * support.
- */
-
- MinAddress.QuadPart = 0;
- BoundryAddressMultiple.QuadPart = 0;
- if ((AdapterObject->Dma64BitAddresses) &&
(AdapterObject->MasterDevice))
- {
- MaxAddress.QuadPart = 0xFFFFFFFFFFFFFFFFLL; /* 64Bit: >4GB
address range */
- }
- else if ((AdapterObject->Dma32BitAddresses) &&
(AdapterObject->MasterDevice))
- {
- MaxAddress.QuadPart = 0xFFFFFFFF; /* 32Bit: 4GB address range */
- }
- else
- {
- MaxAddress.QuadPart = 0x00FFFFFF; /* 24Bit: 16MB address range */
- if (AdapterObject->Width16Bits)
- {
- BoundryAddressMultiple.QuadPart = 0x20000; /* 128k boundary
*/
- }
- else
- {
- BoundryAddressMultiple.QuadPart = 0x10000; /* 64k boundary
*/
- }
- }
- AdapterObject->MapRegisterBase =
MmAllocateContiguousMemorySpecifyCache(
- NumberOfMapRegisters * PAGE_SIZE,
- MinAddress,
- MaxAddress,
- BoundryAddressMultiple,
- MmCached);
-
- if(!AdapterObject->MapRegisterBase)
- return STATUS_INSUFFICIENT_RESOURCES;
-
- AdapterObject->CommittedMapRegisters = NumberOfMapRegisters;
-
- /* call the client's AdapterControl callback with its map registers
and context */
- Retval = ExecutionRoutine(WaitContextBlock->DeviceObject,
WaitContextBlock->CurrentIrp,
- AdapterObject->MapRegisterBase, WaitContextBlock->DeviceContext);
-
- /*
- * KeepObject: don't free any resources; the ADAPTER_OBJECT is still
in use
- * and the caller will call IoFreeAdapterChannel later
- *
- * DeallocateObject: Deallocate the map registers and release the
ADAPTER_OBJECT
- * so someone else can use it
- *
- * DeallocateObjectKeepRegisters: release the ADAPTER_OBJECT but hang
on to
- * the map registers. The client will later call
IoFreeMapRegisters.
- *
- * NOTE - IoFreeAdapterChannel runs the queue, so it must be called
- * unless the adapter object is not to be freed.
- */
- if( Retval == DeallocateObject )
- IoFreeAdapterChannel(AdapterObject);
- else if(Retval == DeallocateObjectKeepRegisters)
- {
- /* don't free the allocated map registers - this is what
IoFreeAdapterChannel checks */
- AdapterObject->CommittedMapRegisters = 0;
- IoFreeAdapterChannel(AdapterObject);
- }
-
- /*
- * if we don't call IoFreeAdapterChannel, the next device won't get
de-queued,
- * which is what we want.
- */
-
- return STATUS_SUCCESS;
-}
-
-
-BOOLEAN
-HalpGrowMapBuffers(
- IN PADAPTER_OBJECT AdapterObject,
- IN ULONG SizeOfMapBuffers)
-/*
- * FUNCTION: Allocate initial, or additional, map buffers for IO
adapters.
- * ARGUMENTS:
- * AdapterObject: DMA adapter to allocate buffers for.
- * SizeOfMapBuffers: Size of the map buffers to allocate
- * NOTES:
- * - Needs to be tested...
- */
-{
- //ULONG PagesToAllocate = BYTES_TO_PAGES(SizeOfMapBuffers);
-
- /* TODO: Allocation */
-
- return TRUE;
-}
-
-PADAPTER_OBJECT STDCALL
-HalpAllocateAdapterEx(
- ULONG NumberOfMapRegisters,
- BOOLEAN IsMaster,
- BOOLEAN Dma32BitAddresses)
-/*
- * FUNCTION: Allocates an ADAPTER_OBJECT, optionally creates the Master
Adapter.
- * ARGUMENTS:
- * - NumberOfMapRegisters: Number of map registers to allocate
- * - IsMaster: Wether this is a Master Device or not
- * - Dma32BitAddresses: Wether 32-bit Addresses are supported
- * RETURNS:
- * - Pointer to Adapter Object, or NULL if failure.
- * BUGS:
- * - Some stuff is unhandled/incomplete
- */
-{
- OBJECT_ATTRIBUTES ObjectAttributes;
- ULONG ObjectSize;
- ULONG BitmapSize;
- NTSTATUS Status;
- ULONG AllowedMapRegisters = 64;
- PADAPTER_OBJECT AdapterObject;
- HANDLE Handle;
-
- /* Allocate the Master Adapter if we haven't already
- but make sure we're not asked to do it now, and also check if
we need it */
- if ((MasterAdapter == NULL) && (!IsMaster) &&
(NumberOfMapRegisters)) {
-
- /* Allocate and Save */
- DPRINT("Allocating the Master Adapter Object\n");
- MasterAdapter =
HalpAllocateAdapterEx(NumberOfMapRegisters,
- TRUE,
- Dma32BitAddresses);
-
- /* Cancel on Failure */
- DPRINT("Checking if Master Adapter was allocated
properly\n");
- if (!MasterAdapter) return NULL;
- }
-
- /* Initialize the Object Attributes for the Adapter Object */
- InitializeObjectAttributes(&ObjectAttributes,
- NULL,
- OBJ_PERMANENT,
- NULL,
- NULL);
-
- /* Check if this is the Master Adapter, in which case we need to
allocate the bitmap */
- if (IsMaster) {
- /* Size due to the Bitmap + Bytes in the Bitmap Buffer
(8 bytes, 64 bits)*/
- BitmapSize = sizeof(RTL_BITMAP) + (AllowedMapRegisters +
7) / 8;
-
- /* We will put the Bitmap Buffer after the Adapter
Object for simplicity */
- ObjectSize = sizeof(ADAPTER_OBJECT) + BitmapSize;
- } else {
- ObjectSize = sizeof(ADAPTER_OBJECT);
- }
-
- /* Create and Allocate the Object */
- DPRINT("Creating the Object\n");
- Status = ObCreateObject(KernelMode,
- IoAdapterObjectType,
- &ObjectAttributes,
- KernelMode,
- NULL,
- ObjectSize,
- 0,
- 0,
- (PVOID)&AdapterObject);
-
- if (!NT_SUCCESS(Status)) return NULL;
-
- /* Add a Reference */
- DPRINT("Referencing the Object\n");
- Status = ObReferenceObjectByPointer(AdapterObject,
- FILE_READ_DATA |
FILE_WRITE_DATA,
- IoAdapterObjectType,
- KernelMode);
-
- if (!NT_SUCCESS(Status)) return NULL;
-
- /* It's a Valid Object, so now we can play with the memory */
- RtlZeroMemory(AdapterObject, sizeof(ADAPTER_OBJECT));
-
- /* Insert it into the Object Table */
- DPRINT("Inserting the Object\n");
- Status = ObInsertObject(AdapterObject,
- NULL,
- FILE_READ_DATA | FILE_WRITE_DATA,
- 0,
- NULL,
- &Handle);
-
- if (!NT_SUCCESS(Status)) return NULL;
-
- /* We don't want the handle */
- NtClose(Handle);
-
- /* Set up the Adapter Object fields */
- AdapterObject->MapRegistersPerChannel = 1;
-
- /* Set the Master if needed (master only needed if we use Map
Registers) */
- if (NumberOfMapRegisters) AdapterObject->MasterAdapter =
MasterAdapter;
-
- /* Initalize the Channel Wait queue, which every adapter has */
- DPRINT("Initializing the Device Queue of the Object\n");
- KeInitializeDeviceQueue(&AdapterObject->ChannelWaitQueue);
-
- /* Initialize the SpinLock, Queue and Bitmap, which are kept in
the Master Adapter only */
- if (IsMaster) {
-
- DPRINT("Initializing the Master Adapter Stuff\n");
- KeInitializeSpinLock(&AdapterObject->SpinLock);
- InitializeListHead(&AdapterObject->AdapterQueue);
-
- /* As said previously, we put them here for simplicity
*/
- AdapterObject->MapRegisters = (PVOID)(AdapterObject +
1);
-
- /* Set up Bitmap */
- RtlInitializeBitMap(AdapterObject->MapRegisters,
- (PULONG)(AdapterObject->MapRegisters
+ 1),
- AllowedMapRegisters);
-
- /* Reset the Bitmap */
- RtlSetAllBits(AdapterObject->MapRegisters);
- AdapterObject->NumberOfMapRegisters = 0;
- AdapterObject->CommittedMapRegisters = 0;
-
- /* Allocate Memory for the Map Registers */
- AdapterObject->MapRegisterBase =
ExAllocatePool(NonPagedPool,
-
AllowedMapRegisters * sizeof(DWORD));
-
- /* Clear them */
- RtlZeroMemory(AdapterObject->MapRegisterBase,
AllowedMapRegisters * sizeof(DWORD));
-
- /* Allocate the contigous memory */
- DPRINT("Allocating Buffers\n");
- HalpGrowMapBuffers(AdapterObject, 0x1000000);
- }
-
- DPRINT("Adapter Object allocated\n");
- return AdapterObject;
-}
-
-
-BOOLEAN STDCALL
-IoFlushAdapterBuffers (
- PADAPTER_OBJECT AdapterObject,
- PMDL Mdl,
- PVOID MapRegisterBase,
- PVOID CurrentVa,
- ULONG Length,
- BOOLEAN WriteToDevice)
-/*
- * FUNCTION: flush any data remaining in the dma controller's memory
into the host memory
- * ARGUMENTS:
- * AdapterObject: the adapter object to flush
- * Mdl: original MDL to flush data into
- * MapRegisterBase: map register base that was just used by
IoMapTransfer, etc
- * CurrentVa: offset into Mdl to be flushed into, same as was
passed to IoMapTransfer
- * Length: length of the buffer to be flushed into
- * WriteToDevice: True if it's a write, False if it's a read
- * RETURNS:
- * TRUE in all cases
- * NOTES:
- * - This copies data from the map register-backed buffer to the
user's target buffer.
- * Data is not in the user buffer until this is called.
- * - This is only meaningful on a read operation. Return
immediately for a write.
- */
-{
- ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);
-
- /* this can happen if the card supports scatter/gather */
- if(!MapRegisterBase)
- return TRUE;
-
- /* mask out (disable) the dma channel */
- if (AdapterObject->AdapterNumber == 1) {
-
- /* Set this for Ease */
- PDMA1_CONTROL DmaControl1 =
AdapterObject->AdapterBaseVa;
-
- /* Set Channel */
- WRITE_PORT_UCHAR(&DmaControl1->SingleMask,
AdapterObject->ChannelNumber | DMA_SETMASK);
- } else {
- /* Set this for Ease */
- PDMA2_CONTROL DmaControl2 =
AdapterObject->AdapterBaseVa;
-
- /* Set Channel */
- WRITE_PORT_UCHAR(&DmaControl2->SingleMask,
(AdapterObject->ChannelNumber - 4) | DMA_SETMASK);
- }
-
- if(WriteToDevice)
- return TRUE;
-
- memcpy(
- (PVOID)((DWORD)MmGetSystemAddressForMdl( Mdl ) +
(DWORD)CurrentVa - (DWORD)MmGetMdlVirtualAddress( Mdl )),
- MapRegisterBase, Length );
-
- return TRUE;
-}
-
-
-VOID STDCALL
-IoFreeAdapterChannel (PADAPTER_OBJECT AdapterObject)
-/*
- * FUNCTION: frees DMA resources allocated by IoAllocateAdapterChannel
- * ARGUMENTS:
- * AdapterObject: Adapter object with resources to free
- * NOTES:
- * - This function releases the DMA adapter and optionally the map
registers
- * - After releasing the adapter, it checks the adapter's queue and
runs
- * each queued device object in series until the queue is empty
- * - This is the only way the device queue is emptied.
- */
-{
- LARGE_INTEGER MaxAddress;
- LARGE_INTEGER MinAddress;
- LARGE_INTEGER BoundryAddressMultiple;
- PWAIT_CONTEXT_BLOCK WaitContextBlock;
- IO_ALLOCATION_ACTION Retval;
-
- while(1)
- {
- /* To keep map registers, call here with the following set to 0
*/
- if(AdapterObject->CommittedMapRegisters)
- IoFreeMapRegisters(AdapterObject,
AdapterObject->MapRegisterBase, AdapterObject->CommittedMapRegisters);
-
- if(!(WaitContextBlock =
(PWAIT_CONTEXT_BLOCK)KeRemoveDeviceQueue(&AdapterObject->ChannelWaitQueu
e)))
- break;
-
- /*
- * the following should really be done elsewhere since this
- * function really can't return an error code. FIXME.
- */
-
- MinAddress.QuadPart = 0;
- BoundryAddressMultiple.QuadPart = 0;
- if ((AdapterObject->Dma64BitAddresses) &&
(AdapterObject->MasterDevice))
- {
- MaxAddress.QuadPart = 0xFFFFFFFFFFFFFFFFLL; /* 64Bit: >4GB
address range */
- }
- else if ((AdapterObject->Dma32BitAddresses) &&
(AdapterObject->MasterDevice))
- {
- MaxAddress.QuadPart = 0xFFFFFFFF; /* 32Bit: 4GB address range
*/
- }
- else
- {
- MaxAddress.QuadPart = 0x00FFFFFF; /* 24Bit: 16MB address
range */
- if (AdapterObject->Width16Bits)
- {
- BoundryAddressMultiple.QuadPart = 0x20000; /* 128k
boundary */
- }
- else
- {
- BoundryAddressMultiple.QuadPart = 0x10000; /* 64k
boundary */
- }
- }
-
- AdapterObject->MapRegisterBase =
MmAllocateContiguousMemorySpecifyCache(
- WaitContextBlock->NumberOfMapRegisters * PAGE_SIZE,
- MinAddress,
- MaxAddress,
- BoundryAddressMultiple,
- MmCached);
-
- if(!AdapterObject->MapRegisterBase)
- return;
-
- /* call the adapter control routine */
- Retval =
((PDRIVER_CONTROL)WaitContextBlock->DeviceRoutine)(WaitContextBlock->Dev
iceObject, WaitContextBlock->CurrentIrp,
- AdapterObject->MapRegisterBase,
WaitContextBlock->DeviceContext);
-
- if(Retval == KeepObject)
- {
- /* we're done until the caller manually calls
IoFreeAdapterChannel */
- break;
- }
- else if(Retval == DeallocateObjectKeepRegisters)
- {
- /* hide the map registers so they aren't deallocated next
time around */
- AdapterObject->CommittedMapRegisters = 0;
- }
- }
-}
-
-
-VOID STDCALL
-IoFreeMapRegisters (
- IN PADAPTER_OBJECT AdapterObject,
- IN PVOID MapRegisterBase,
- IN ULONG NumberOfMapRegisters)
-/*
- * FUNCTION: free map registers reserved by the system for a DMA
- * ARGUMENTS:
- * AdapterObject: dma adapter to free map registers on
- * MapRegisterBase: hadle to map registers to free
- * NumberOfRegisters: number of map registers to be freed
- * NOTES:
- * - XXX real windows has a funky interdependence between
IoFreeMapRegisters
- * and IoFreeAdapterChannel
- * BUGS:
- * - needs to be improved to use a real map register implementation
- */
-{
- if( AdapterObject->CommittedMapRegisters )
- {
- MmFreeContiguousMemory(AdapterObject->MapRegisterBase);
- AdapterObject->MapRegisterBase = 0;
- }
-}
-
-
-PHYSICAL_ADDRESS STDCALL
-IoMapTransfer (
- IN PADAPTER_OBJECT AdapterObject,
- IN PMDL Mdl,
- IN PVOID MapRegisterBase,
- IN PVOID CurrentVa,
- IN OUT PULONG Length,
- IN BOOLEAN WriteToDevice)
-/*
- * FUNCTION: map a dma for transfer and do the dma if it's a slave
- * ARGUMENTS:
- * AdapterObject: adapter object to do the dma on. busmaster may
pass NULL.
- * Mdl: locked-down user buffer to DMA in to or out of
- * MapRegisterBase: handle to map registers to use for this dma.
allways NULL
- * when doing s/g.
- * CurrentVa: index into Mdl to transfer into/out of
- * Length: length of transfer in/out. Only modified on out when
doing s/g.
- * WriteToDevice: TRUE if it's an output dma, FALSE otherwise
- * RETURNS:
- * If a busmaster: A logical address that can be used to program a
dma controller
- * Otherwise: nothing meaningful
- * NOTES:
- * - This function does a copyover to contiguous memory <16MB
- * - If it's a slave transfer, this function actually performs it.
- * BUGS:
- * - If the controller supports scatter/gather, the copyover should
not happen
- */
-{
- PHYSICAL_ADDRESS Address;
- KIRQL OldIrql;
- ULONG LengthShift = 0;
-
- Address.QuadPart = 0;
-
- /* Isa System (slave) DMA? */
- if (MapRegisterBase && !AdapterObject->MasterDevice)
- {
- KeAcquireSpinLock(&AdapterObject->SpinLock, &OldIrql);
-
- /*
- * FIXME: Handle case when doing common-buffer System DMA. In this
case,
- * the buffer described by MDL is already phys. contiguous and
below
- * 16 mega. Driver makes a one-shot call to IoMapTransfer during
init.
- * to program controller with the common-buffer.
- *
- * UPDATE: Common buffer support is in place, but it's not done in
a
- * clean way. We use the buffer passed by the MDL in case that the
- * adapter object is marked as auto initialize. I'm not sure if
this
- * is correct and if not, how to do it properly. Note that it's
also
- * possible to allocate the common buffer with different adapter
object
- * and IoMapTransfer must still work in this case. Eventually this
should
- * be cleaned up somehow or at least this comment modified to
reflect
- * the reality.
- * -- Filip Navara, 19/07/2004
- */
-
- /* if it is a write to the device, copy the caller buffer to the
low buffer */
- if (WriteToDevice && !AdapterObject->AdapterMode.AutoInitialize)
- {
- memcpy(MapRegisterBase,
- (char*)MmGetSystemAddressForMdl(Mdl) + ((ULONG)CurrentVa -
(ULONG)MmGetMdlVirtualAddress(Mdl)),
- *Length );
- }
-
- /* Writer Adapter Mode, transfer type */
- AdapterObject->AdapterMode.TransferType = (WriteToDevice ?
WRITE_TRANSFER : READ_TRANSFER);
-
- /* 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) {
- 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,
AdapterObject->AdapterModeByte);
-
- /* 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->ChannelNum
ber].DmaBaseAddress, 0);
-
WRITE_PORT_UCHAR(&DmaControl1->DmaAddressCount[AdapterObject->ChannelNum
ber].DmaBaseAddress, 0);
-
- /* Set the Length */
-
WRITE_PORT_UCHAR(&DmaControl1->DmaAddressCount[AdapterObject->ChannelNum
ber].DmaBaseCount,
- (UCHAR)((*Length >> LengthShift) - 1));
-
WRITE_PORT_UCHAR(&DmaControl1->DmaAddressCount[AdapterObject->ChannelNum
ber].DmaBaseCount,
- (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,
AdapterObject->AdapterModeByte);
-
- /* 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->ChannelNum
ber].DmaBaseAddress, 0);
-
WRITE_PORT_UCHAR(&DmaControl2->DmaAddressCount[AdapterObject->ChannelNum
ber].DmaBaseAddress, 0);
-
- /* Set the Length */
-
WRITE_PORT_UCHAR(&DmaControl2->DmaAddressCount[AdapterObject->ChannelNum
ber].DmaBaseCount,
- (UCHAR)((*Length >> LengthShift) - 1));
-
WRITE_PORT_UCHAR(&DmaControl2->DmaAddressCount[AdapterObject->ChannelNum
ber].DmaBaseCount,
- (UCHAR)(((*Length >> LengthShift) - 1) >> 8));
-
- /* Unmask the Channel */
- WRITE_PORT_UCHAR(&DmaControl2->SingleMask,
AdapterObject->ChannelNumber | DMA_CLEARMASK);
- }
-
- /* Release Spinlock */
- KeReleaseSpinLock(&AdapterObject->SpinLock, OldIrql);
-
- /*
- NOTE: Return value should be ignored when doing System DMA.
- Maybe return some more obvious invalid address here (thou returning
- MapRegisterBase is also wrong;-)to catch invalid use?
- */
- Address.QuadPart = (ULONG)MapRegisterBase;
- return Address;
- }
-
-
- /*
- Busmaster with s/g support?
- NOTE: old docs allowed busmasters to pass a NULL Adapter. In this
case, MapRegisterBase
- being NULL is used to detect a s/g busmaster.
- */
- if ((!AdapterObject && !MapRegisterBase) ||
- (AdapterObject && AdapterObject->MasterDevice &&
AdapterObject->ScatterGather))
- {
- /*
- Just return the passed VA's corresponding phys. address.
- Update length to the number of phys. contiguous bytes found.
- */
-
- PULONG MdlPages;
- ULONG MdlPageIndex, PhysContiguousLen;
- ULONG PhysAddress;
-
- MdlPages = (PULONG)(Mdl + 1);
-
- /* Get VA's corresponding mdl phys. page index */
- MdlPageIndex = ((ULONG)CurrentVa - (ULONG)Mdl->StartVa) /
PAGE_SIZE;
-
- /* Get phys. page containing the VA */
- PhysAddress = MdlPages[MdlPageIndex];
-
- PhysContiguousLen = PAGE_SIZE - BYTE_OFFSET(CurrentVa);
-
- /* VA to map may span several contiguous phys. pages (unlikely) */
- while (PhysContiguousLen < *Length &&
- MdlPages[MdlPageIndex++] + PAGE_SIZE ==
MdlPages[MdlPageIndex])
- {
- /*
- Note that allways adding PAGE_SIZE may make PhysContiguousLen
greater
- than Length if buffer doesn't end on page boundary. Take this
- into consideration below.
- */
- PhysContiguousLen += PAGE_SIZE;
- }
-
- if (PhysContiguousLen < *Length)
- {
- *Length = PhysContiguousLen;
- }
-
- //add offset to phys. page address
- Address.QuadPart = PhysAddress + BYTE_OFFSET(CurrentVa);
- return Address;
- }
-
-
- /*
- Busmaster without s/g support?
- NOTE: old docs allowed busmasters to pass a NULL Adapter. In this
case, MapRegisterBase
- not being NULL is used to detect a non s/g busmaster.
- */
- if ((!AdapterObject && MapRegisterBase) ||
- (AdapterObject && AdapterObject->MasterDevice &&
!AdapterObject->ScatterGather))
- {
- /*
- NOTE: Busmasters doing common-buffer DMA shouldn't call
IoMapTransfer, but I don't
- know if it's illegal... Maybe figure out what to do in this case...
- */
-
- if( WriteToDevice )
- {
- memcpy(MapRegisterBase,
- (char*)MmGetSystemAddressForMdl(Mdl) + ((ULONG)CurrentVa -
(ULONG)MmGetMdlVirtualAddress(Mdl)),
- *Length );
- }
-
- return MmGetPhysicalAddress(MapRegisterBase);
- }
-
- DPRINT("IoMapTransfer: Unsupported operation\n");
- KEBUGCHECK(0);
- return Address;
-}
-
-
-/* EOF */
-
-
-
-
_____
Modified: trunk/reactos/hal/halx86/generic/dma.c
--- trunk/reactos/hal/halx86/generic/dma.c 2005-08-21 20:44:47 UTC
(rev 17469)
+++ trunk/reactos/hal/halx86/generic/dma.c 2005-08-22 08:39:42 UTC
(rev 17470)
@@ -5,459 +5,1898 @@
* FILE: ntoskrnl/hal/x86/dma.c
* PURPOSE: DMA functions
* PROGRAMMERS: David Welch (welch(a)mcmail.com)
+ * Filip Navara (navaraf(a)reactos.com)
* UPDATE HISTORY:
* Created 22/05/98
*/
+/**
+ * @page DMA Implementation Notes
+ *
+ * Concepts:
+ *
+ * - Map register
+ *
+ * Abstract encapsulation of physically contiguous buffer that
resides
+ * in memory accessible by both the DMA device / controller and the
system.
+ * The map registers are allocated and distributed on demand and are
+ * scarce resource.
+ *
+ * The actual use of map registers is to allow transfers from/to
buffer
+ * located in physical memory at address inaccessible by the DMA
device /
+ * controller directly. For such transfers the map register buffers
+ * are used as intermediate data storage.
+ *
+ * - Master adapter
+ *
+ * A container for map registers (typically corresponding to one
physical
+ * bus connection type). There can be master adapters for 24-bit
address
+ * ranges, 32-bit address ranges, etc. Every time a new DMA adapter
is
+ * created it's associated with a corresponding master adapter that
+ * is used for any map register allocation requests.
+ *
+ * - Bus-master / Slave DMA
+ *
+ * Slave DMA is term used for DMA transfers done by the system (E)ISA
+ * controller as opposed to transfers mastered by the device itself
+ * (hence the name).
+ *
+ * For slave DMA special care is taken to actually access the system
+ * controller and handle the transfers. The relevant code is in
+ * HalpDmaInitializeEisaAdapter, HalReadDmaCounter,
IoFlushAdapterBuffers
+ * and IoMapTransfer.
+ *
+ * Implementation:
+ *
+ * - Allocation of map registers
+ *
+ * Initial set of map registers is allocated on the system start to
+ * ensure that low memory won't get filled up later. Additional map
+ * registers are allocated as needed by HalpGrowMapBuffers. This
+ * routine is called on two places:
+ *
+ * - HalGetAdapter, since we're at PASSIVE_LEVEL and it's known that
+ * more map registers will probably be needed.
+ * - IoAllocateAdapterChannel (indirectly using
HalpGrowMapBufferWorker
+ * since we're at DISPATCH_LEVEL and call HalpGrowMapBuffers
directly)
+ * when no more map registers are free.
+ *
+ * Note that even if no more map registers can be allocated it's not
+ * the end of the world. The adapters waiting for free map registers
+ * are queued in the master adapter's queue and once one driver hands
+ * back it's map registers (using IoFreeMapRegisters or indirectly
using
+ * the execution routine callback in IoAllocateAdapterChannel) the
+ * queue gets processed and the map registers are reassigned.
+ */
+
/* INCLUDES
*****************************************************************/
#include <hal.h>
#define NDEBUG
#include <debug.h>
-/* Adapters for each channel */
-PADAPTER_OBJECT HalpEisaAdapter[8];
+static KEVENT HalpDmaLock;
+static LIST_ENTRY HalpDmaAdapterList;
+static PADAPTER_OBJECT HalpEisaAdapter[8];
+static BOOLEAN HalpEisaDma;
+static PADAPTER_OBJECT HalpMasterAdapter;
+static const ULONG_PTR HalpEisaPortPage[8] = {
+ FIELD_OFFSET(DMA_PAGE, Channel0),
+ FIELD_OFFSET(DMA_PAGE, Channel1),
+ FIELD_OFFSET(DMA_PAGE, Channel2),
+ FIELD_OFFSET(DMA_PAGE, Channel3),
+ 0,
+ FIELD_OFFSET(DMA_PAGE, Channel5),
+ FIELD_OFFSET(DMA_PAGE, Channel6),
+ FIELD_OFFSET(DMA_PAGE, Channel7)
+};
+
+static DMA_OPERATIONS HalpDmaOperations = {
+ sizeof(DMA_OPERATIONS),
+ (PPUT_DMA_ADAPTER)HalPutDmaAdapter,
+ (PALLOCATE_COMMON_BUFFER)HalAllocateCommonBuffer,
+ (PFREE_COMMON_BUFFER)HalFreeCommonBuffer,
+ (PALLOCATE_ADAPTER_CHANNEL)IoAllocateAdapterChannel,
+ (PFLUSH_ADAPTER_BUFFERS)IoFlushAdapterBuffers,
+ (PFREE_ADAPTER_CHANNEL)IoFreeAdapterChannel,
+ (PFREE_MAP_REGISTERS)IoFreeMapRegisters,
+ (PMAP_TRANSFER)IoMapTransfer,
+ (PGET_DMA_ALIGNMENT)HalpDmaGetDmaAlignment,
+ (PREAD_DMA_COUNTER)HalReadDmaCounter,
+ /* FIXME: Implement the S/G funtions. */
+ NULL /*(PGET_SCATTER_GATHER_LIST)HalGetScatterGatherList*/,
+ NULL /*(PPUT_SCATTER_GATHER_LIST)HalPutScatterGatherList*/,
+ NULL
/*(PCALCULATE_SCATTER_GATHER_LIST_SIZE)HalCalculateScatterGatherListSize
*/,
+ NULL /*(PBUILD_SCATTER_GATHER_LIST)HalBuildScatterGatherList*/,
+ NULL
/*(PBUILD_MDL_FROM_SCATTER_GATHER_LIST)HalBuildMdlFromScatterGatherList*
/
+};
+
+#define MAX_MAP_REGISTERS 64
+
+#define TAG_DMA TAG('D','M','A',' ')
+
/* FUNCTIONS
*****************************************************************/
VOID
-HalpInitDma (VOID)
+HalpInitDma(VOID)
{
- /* TODO: Initialize the first Map Buffer */
+ /*
+ * Check if Extended DMA is available. We're just going to do a
random
+ * read and write.
+ */
+
+ WRITE_PORT_UCHAR((PUCHAR)FIELD_OFFSET(EISA_CONTROL,
DmaController2Pages.Channel2), 0x2A);
+ if (READ_PORT_UCHAR((PUCHAR)FIELD_OFFSET(EISA_CONTROL,
DmaController2Pages.Channel2)) == 0x2A)
+ HalpEisaDma = TRUE;
+
+ /*
+ * Intialize all the global variables and allocate master adapter
with
+ * first map buffers.
+ */
+
+ InitializeListHead(&HalpDmaAdapterList);
+ KeInitializeEvent(&HalpDmaLock, NotificationEvent, TRUE);
+
+ HalpMasterAdapter = HalpDmaAllocateMasterAdapter();
}
-PVOID STDCALL
-HalAllocateCommonBuffer (PADAPTER_OBJECT AdapterObject,
- ULONG Length,
- PPHYSICAL_ADDRESS LogicalAddress,
- BOOLEAN CacheEnabled)
-/*
- * FUNCTION: Allocates memory that is visible to both the processor(s)
and
- * a dma device
- * ARGUMENTS:
- * AdapterObject = Adapter object representing the bus master
or
- * system dma controller
- * Length = Number of bytes to allocate
- * LogicalAddress = Logical address the driver can use to
access the
- * buffer
- * CacheEnabled = Specifies if the memory can be cached
- * RETURNS: The base virtual address of the memory allocated
- * NULL on failure
- * NOTES:
- * CacheEnabled is ignored - it's all cache-disabled (like in NT)
- * UPDATE: It's not ignored now. If that's wrong just modify the
- * CacheEnabled comparsion below.
+/**
+ * @name HalpGetAdapterMaximumPhysicalAddress
+ *
+ * Get the maximum physical address acceptable by the device
represented
+ * by the passed DMA adapter.
*/
+
+PHYSICAL_ADDRESS STDCALL
+HalpGetAdapterMaximumPhysicalAddress(
+ IN PADAPTER_OBJECT AdapterObject)
{
- PHYSICAL_ADDRESS LowestAddress, HighestAddress,
BoundryAddressMultiple;
- PVOID BaseAddress;
+ PHYSICAL_ADDRESS HighestAddress;
- LowestAddress.QuadPart = 0;
- BoundryAddressMultiple.QuadPart = 0;
- if ((AdapterObject->Dma64BitAddresses) &&
(AdapterObject->MasterDevice)) {
- HighestAddress.QuadPart = 0xFFFFFFFFFFFFFFFFLL; /* 64Bit: >4GB
address range */
-
- } else if ((AdapterObject->Dma32BitAddresses) &&
(AdapterObject->MasterDevice)) {
- HighestAddress.QuadPart = 0xFFFFFFFF; /* 32Bit: 4GB address range
*/
- } else {
- HighestAddress.QuadPart = 0x00FFFFFF; /* 24Bit: 16MB address
range */
- if (AdapterObject->Width16Bits)
+ if (AdapterObject->MasterDevice)
+ {
+ if (AdapterObject->Dma64BitAddresses)
{
- BoundryAddressMultiple.QuadPart = 0x20000; /* 128k boundary
*/
+ HighestAddress.QuadPart = 0xFFFFFFFFFFFFFFFFULL;
+ return HighestAddress;
}
- else
+ else if (AdapterObject->Dma32BitAddresses)
{
- BoundryAddressMultiple.QuadPart = 0x10000; /* 64k boundary */
+ HighestAddress.QuadPart = 0xFFFFFFFF;
+ return HighestAddress;
}
- }
+ }
- BaseAddress = MmAllocateContiguousMemorySpecifyCache(
- Length,
- LowestAddress,
- HighestAddress,
- BoundryAddressMultiple,
- CacheEnabled ? MmCached : MmNonCached);
- if (!BaseAddress)
- return 0;
+ HighestAddress.QuadPart = 0xFFFFFF;
+ return HighestAddress;
+}
- *LogicalAddress = MmGetPhysicalAddress(BaseAddress);
+/**
+ * @name HalpGrowMapBuffers
+ *
+ * Allocate initial, or additional, map buffers for DMA master adapter.
+ *
+ * @param MasterAdapter
+ * DMA master adapter to allocate buffers for.
+ * @param SizeOfMapBuffers
+ * Size of the map buffers to allocate (not including the size
+ * already allocated).
+ */
- return BaseAddress;
+BOOLEAN STDCALL
+HalpGrowMapBuffers(
+ IN PADAPTER_OBJECT AdapterObject,
+ IN ULONG SizeOfMapBuffers)
+{
+ PVOID VirtualAddress;
+ PHYSICAL_ADDRESS PhysicalAddress;
+ PHYSICAL_ADDRESS HighestAcceptableAddress;
+ PHYSICAL_ADDRESS LowestAcceptableAddress;
+ PHYSICAL_ADDRESS BoundryAddressMultiple;
+ KIRQL OldIrql;
[truncated at 1000 lines; 2839 more skipped]