windows-nt/Source/XPSP1/NT/drivers/video/ms/port/sync.c

407 lines
6.9 KiB
C
Raw Normal View History

2020-09-26 03:20:57 -05:00
/*++
Copyright (c) 1990-2000 Microsoft Corporation
Module Name:
sync.c
Abstract:
This file contains code for the video port synchronization routines.
Environment:
kernel mode only
--*/
#include "videoprt.h"
#ifdef ALLOC_PRAGMA
#pragma alloc_text(PAGE, VideoPortCreateEvent)
#pragma alloc_text(PAGE, VideoPortCreateSpinLock)
#endif
VP_STATUS
VideoPortCreateSpinLock(
IN PVOID HwDeviceExtension,
OUT PSPIN_LOCK *SpinLock
)
/*++
Routine Description:
Creates a spin lock object
Arguments:
HwDeviceExtension - pointer to the miniports device extension
SpinLock - Location in which to store the pointer to the newly
acquired spin lock.
Returns:
NO_ERROR if the spin lock was created successfully, otherwise
an appropriate error message is returned.
Notes:
none
--*/
{
PAGED_CODE();
ASSERT(HwDeviceExtension != NULL);
*SpinLock = ExAllocatePoolWithTag(NonPagedPool,
sizeof(VIDEO_PORT_SPIN_LOCK),
VP_TAG);
if (*SpinLock) {
KeInitializeSpinLock(&(*SpinLock)->Lock);
return NO_ERROR;
} else {
return ERROR_NOT_ENOUGH_MEMORY;
}
}
VP_STATUS
VideoPortDeleteSpinLock(
IN PVOID HwDeviceExtension,
IN PSPIN_LOCK SpinLock
)
/*++
Routine Description:
Deletes the given spin lock
Arguments:
HwDeviceExtension - pointer to the miniports device extension
SpinLock - A pointer to the spin lock being deleted.
Returns:
NO_ERROR if the spin lock is deleted successfully.
Notes:
--*/
{
ASSERT(HwDeviceExtension != NULL);
ASSERT(SpinLock != NULL);
ExFreePool(SpinLock);
return NO_ERROR;
}
VOID
VideoPortAcquireSpinLock(
IN PVOID HwDeviceExtension,
IN PSPIN_LOCK SpinLock,
OUT PUCHAR OldIrql
)
/*++
Routine Description:
Acquires the given spin lock
Arguments:
HwDeviceExtension - pointer to the miniports device extension
SpinLock - The spin lock being acquired
OldIrql - location in which to store the old IRQL level
Returns:
none
Notes:
--*/
{
ASSERT(HwDeviceExtension != NULL);
ASSERT(SpinLock != NULL);
KeAcquireSpinLock(&SpinLock->Lock, OldIrql);
}
VOID
VideoPortAcquireSpinLockAtDpcLevel(
IN PVOID HwDeviceExtension,
IN PSPIN_LOCK SpinLock
)
/*++
Routine Description:
Acquires the given spin lock.
Arguments:
HwDeviceExtension - pointer to the miniports device extension
SpinLock - The spin lock being acquired
Returns:
none
Notes:
This routine can only be called inside a DPC.
--*/
{
ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);
ASSERT(HwDeviceExtension != NULL);
ASSERT(SpinLock != NULL);
KeAcquireSpinLockAtDpcLevel(&SpinLock->Lock);
}
VOID
VideoPortReleaseSpinLock(
IN PVOID HwDeviceExtension,
IN PSPIN_LOCK SpinLock,
IN UCHAR NewIrql
)
/*++
Routine Description:
Releases ownership of a given spin lock
Arguments:
HwDeviceExtension - pointer to the miniports device extension
SpinLock - the spin lock being released
NewIrql - Irql level to restore to.
Returns:
none
Notes:
--*/
{
ASSERT(HwDeviceExtension != NULL);
ASSERT(SpinLock != NULL);
KeReleaseSpinLock(&SpinLock->Lock, NewIrql);
}
VOID
VideoPortReleaseSpinLockFromDpcLevel(
IN PVOID HwDeviceExtension,
IN PSPIN_LOCK SpinLock
)
/*++
Routine Description:
Releases ownership of a given spin lock
Arguments:
HwDeviceExtension - pointer to the miniports device extension
SpinLock - the spin lock being released
Returns:
none
Notes:
This routine can only be called inside a DPC.
--*/
{
ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);
ASSERT(HwDeviceExtension != NULL);
ASSERT(SpinLock != NULL);
KeReleaseSpinLockFromDpcLevel(&SpinLock->Lock);
}
VP_STATUS
VideoPortCreateEvent(
IN PVOID HwDeviceExtension,
IN ULONG EventFlag,
PVOID Unused,
OUT PEVENT *ppEvent
)
{
ULONG size;
PEVENT p;
EVENT_TYPE EventType;
size = sizeof(VIDEO_PORT_EVENT);
//
// Align size to next higher multiple of 8.
//
size = (size + 7) & ~7;
p = (PEVENT) ExAllocatePoolWithTag( NonPagedPool,
size + sizeof(KEVENT),
VP_TAG );
if ( p ) {
p->fFlags = 0;
p->pKEvent = (PUCHAR) p + size;
if( (EventFlag & EVENT_TYPE_MASK) == NOTIFICATION_EVENT ) {
EventType = NotificationEvent;
} else {
EventType = SynchronizationEvent;
}
KeInitializeEvent( p->pKEvent,
EventType,
(BOOLEAN) (EventFlag & INITIAL_EVENT_STATE_MASK ) );
*ppEvent = p;
return NO_ERROR;
} else {
return ERROR_NOT_ENOUGH_MEMORY;
}
}
VP_STATUS
VideoPortDeleteEvent(
IN PVOID HwDeviceExtension,
IN PEVENT pEvent
)
{
if ( pEvent == NULL ) {
pVideoDebugPrint((Error, "VideoPortDeleteEvent: Can't delete NULL event\n"));
ASSERT(FALSE);
return ERROR_INVALID_PARAMETER;
}
if ( pEvent->fFlags & ENG_EVENT_FLAG_IS_MAPPED_USER ) {
pVideoDebugPrint((Error, "VideoPortDeleteEvent: Can't delete mapped user event\n"));
ASSERT(FALSE);
return ERROR_INVALID_PARAMETER;
}
if( pEvent->pKEvent == NULL ) {
pVideoDebugPrint((Error, "VideoPortDeleteEvent: pKEvent is NULL\n"));
ASSERT(FALSE);
return ERROR_INVALID_PARAMETER;
}
ExFreePool( (PVOID) pEvent );
return NO_ERROR;
}
LONG
VideoPortSetEvent(
IN PVOID HwDeviceExtension,
IN PEVENT pEvent
)
{
return( KeSetEvent(pEvent->pKEvent, 0, FALSE) );
}
VOID
VideoPortClearEvent(
IN PVOID HwDeviceExtension,
IN PEVENT pEvent
)
{
KeClearEvent(pEvent->pKEvent);
}
LONG
VideoPortReadStateEvent(
IN PVOID HwDeviceExtension,
IN PEVENT pEvent
)
{
return ( KeReadStateEvent(pEvent->pKEvent) );
}
VP_STATUS
VideoPortWaitForSingleObject(
IN PVOID HwDeviceExtension,
IN PVOID pEvent,
IN PLARGE_INTEGER Timeout
)
{
NTSTATUS status;
if ( pEvent == NULL ) {
return ERROR_INVALID_PARAMETER;
}
if( ((PEVENT) pEvent)->pKEvent == NULL) {
return ERROR_INVALID_PARAMETER;
}
if (( (PEVENT) pEvent)->fFlags & ENG_EVENT_FLAG_IS_MAPPED_USER ) {
pVideoDebugPrint((Error, "VideoPortVideoPortWaitForSingleObject: No wait ing on mapped user event\n")) ;
ASSERT(FALSE);
return ERROR_INVALID_PARAMETER;
}
status = KeWaitForSingleObject( ((PEVENT) pEvent)->pKEvent,
Executive,
KernelMode,
FALSE,
Timeout );
if (status == STATUS_TIMEOUT) {
return WAIT_TIMEOUT;
} else if (NT_SUCCESS(status)) {
return NO_ERROR;
} else {
return ERROR_INVALID_PARAMETER;
}
}