|
|
/*++
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; } }
|