Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

261 lines
7.5 KiB

/******************************Module*Header**********************************\
*
* ***************
* * SAMPLE CODE *
* ***************
*
* Module Name: mini.c
*
* Content:
*
* Copyright (c) 1994-1998 3Dlabs Inc. Ltd. All rights reserved.
* Copyright (c) 1995-1999 Microsoft Corporation. All rights reserved.
\*****************************************************************************/
#include "precomp.h"
//-----------------------------------------------------------------------------
//
// AllocateDMABuffer
//
// Allocate physical continous memory for DMA operation. This function returns
// a pointer to a previously allocated DMA buffer if there is still an unfreed
// allocation left. That way the reallocation of continous memory can be
// avoided when a new ppdev is created on lets say a mode switch, since
// allocation of continous memory cannot be guaranteed. The memory is only
// physically freed after all allocations have called a FreeDMABuffer.
//
// Calls to AllocateDMABuffer and FreeDMABuffer should be paired, otherwise
// the usage count logic in the miniport driver gets confused!
//
// The VideoPort currently restricts the size of a DMA buffer to 256kb.
//
// hDriver-------videoport driver handle
// plSize--------pointer to LONG size of requested DMA buffer. Returns size
// of allocated DMA buffer
// (return value can be smaller than requested size)
// ppVirtAddr----returns virtual address of requested DMA buffer.
// pPhysAddr-----returns physical address of DMA buffer as seen from graphics
// device.
//
// return TRUE, allocation successful
// FALSE, allocation failed
//
//-----------------------------------------------------------------------------
BOOL
AllocateDMABuffer( HANDLE hDriver,
PLONG plSize,
PULONG *ppVirtAddr,
LARGE_INTEGER *pPhysAddr)
{
LINE_DMA_BUFFER ldb;
ldb.size = *plSize;
ldb.virtAddr = 0;
ldb.cacheEnabled = TRUE;
*ppVirtAddr=0;
pPhysAddr->HighPart=
pPhysAddr->LowPart=0;
ULONG ulLength = sizeof(LINE_DMA_BUFFER);
if (EngDeviceIoControl( hDriver,
IOCTL_VIDEO_QUERY_LINE_DMA_BUFFER,
(PVOID)&ldb,
ulLength,
(PVOID)&ldb,
ulLength,
&ulLength))
{
return(FALSE);
}
*ppVirtAddr=(PULONG)ldb.virtAddr;
if (ldb.virtAddr!=NULL)
{
*pPhysAddr=ldb.physAddr;
*plSize=ldb.size;
return TRUE;
}
return FALSE;
}
//-----------------------------------------------------------------------------
//
// FreeDMABuffer
//
// free continous buffer previously allocated by AllocateDMABuffer.
//
//-----------------------------------------------------------------------------
BOOL
FreeDMABuffer( HANDLE hDriver,
PVOID pVirtAddr)
{
LINE_DMA_BUFFER ldb;
ldb.size = 0;
ldb.virtAddr = pVirtAddr;
ULONG ulLength = sizeof(LINE_DMA_BUFFER);
if (EngDeviceIoControl( hDriver,
IOCTL_VIDEO_QUERY_LINE_DMA_BUFFER,
(PVOID)&ldb,
ulLength,
NULL,
0,
&ulLength))
{
return FALSE;
}
return TRUE;
}
//-----------------------------------------------------------------------------
//
// AllocateEmulatedDMABuffer
//
// Allocate memory for emulated DMA operation.
//
// hDriver-------videoport driver handle
// ulSize--------ULONG size of requested DMA buffer
// ulTag---------ULONG tag to mark allocation
//
// return NULL, allocation failed
// otherwise, virtual address of emulated DMA buffer
//
//-----------------------------------------------------------------------------
PULONG
AllocateEmulatedDMABuffer(
HANDLE hDriver,
ULONG ulSize,
ULONG ulTag
)
{
EMULATED_DMA_BUFFER edb;
edb.virtAddr = NULL;
edb.size = ulSize;
edb.tag = ulTag;
ULONG ulLength = sizeof(edb);
if (EngDeviceIoControl( hDriver,
IOCTL_VIDEO_QUERY_EMULATED_DMA_BUFFER,
(PVOID)&edb,
ulLength,
(PVOID)&edb,
ulLength,
&ulLength))
{
return (NULL);
}
return (PULONG)(edb.virtAddr);
}
//-----------------------------------------------------------------------------
//
// FreeEmulatedDMABuffer
//
// free buffer previously allocated by AllocateEmulatedDMABuffer.
//
//-----------------------------------------------------------------------------
BOOL
FreeEmulatedDMABuffer(
HANDLE hDriver,
PVOID pVirtAddr
)
{
EMULATED_DMA_BUFFER edb;
edb.virtAddr = pVirtAddr;
ULONG ulLength = sizeof(edb);
if (EngDeviceIoControl( hDriver,
IOCTL_VIDEO_QUERY_EMULATED_DMA_BUFFER,
(PVOID)&edb,
ulLength,
NULL,
0,
&ulLength))
{
return FALSE;
}
return TRUE;
}
//-----------------------------------------------------------------------------
//
// StallExecution
//
// calls VideoPortStallExecution in the miniport for defined delay when
// polling Permedia registers. VideoPortStallexecution does not yield
// to another process and should only be used in rare cases.
//
// hDriver--------handle to videoport
// ulMicroSeconds-number of microseconds to stall CPU execution
//
//-----------------------------------------------------------------------------
VOID
StallExecution( HANDLE hDriver, ULONG ulMicroSeconds)
{
ULONG Length = 0;
EngDeviceIoControl(hDriver,
IOCTL_VIDEO_STALL_EXECUTION,
&ulMicroSeconds,
sizeof(ULONG),
NULL,
0,
&Length);
}
//-----------------------------------------------------------------------------
//
// GetPInterlockedExchange
//
// We need to call the same InterlockedExchange function from the display
// driver and the miniport to make sure they work properly. The miniport
// will give us a pointer to the function which we will call directly...
// On Alpha and Risc machines, InterlockedExchange compiles as inline and
// we don't need to call in the kernel.
//
// note: the InterlockedExchange function exported from ntoskrnl has calling
// convention __fastcall.
//
//-----------------------------------------------------------------------------
#if defined(_X86_)
PVOID
GetPInterlockedExchange( HANDLE hDriver)
{
ULONG Length = 0;
PVOID pWorkPtr=NULL;
if (EngDeviceIoControl( hDriver,
IOCTL_VIDEO_QUERY_INTERLOCKEDEXCHANGE,
NULL,
0,
&pWorkPtr,
sizeof(pWorkPtr),
&Length))
{
return NULL;
}
return pWorkPtr;
}
#endif