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.
|
|
/*++
Copyright (c) 1997 Microsoft Corporation
Module Name:
extlist.c
Abstract:
This module contains routines for managing ACPI extension lists
Author:
Adrian J. Oney (AdriaO)
Environment:
NT Kernel Model Driver only
These routines are meant to be used as a for loop, ie:
Iterate over the list using:
ACPIExtListSetupEnum(...);
for( ACPIExtListStartEnum(...); ACPIExtListTestElement(...); ACPIExtListEnumNext(...) ) {
if (GoingToBreak) {
ACPIExtListExitEnumEarly(...); break ; } }
Revision History:
Feb 11, 1998 - Authored
--*/
#include "pch.h"
BOOLEAN ACPIExtListIsFinished( IN PEXTENSIONLIST_ENUMDATA PExtList_EnumData ) /*++
Routine Description:
Arguments:
Return Value:
--*/ { ACPIDebugEnter( "ACPIExtListIsFinished" );
if (CONTAINING_LIST(PExtList_EnumData->pDevExtCurrent, PExtList_EnumData->ExtOffset) == PExtList_EnumData->pListHead) {
return TRUE ; } return FALSE ;
ACPIDebugExit( "ACPIExtListIsFinished" ); }
PDEVICE_EXTENSION EXPORT ACPIExtListStartEnum( IN OUT PEXTENSIONLIST_ENUMDATA PExtList_EnumData ) /*++
Routine Description:
Arguments:
Return Value:
--*/ { ACPIDebugEnter( "ACPIExtListStartEnum" );
//
// We must walk the tree at dispatch level <sigh>
//
if (PExtList_EnumData->WalkScheme != WALKSCHEME_NO_PROTECTION) { KeAcquireSpinLock( PExtList_EnumData->pSpinLock, &PExtList_EnumData->oldIrql ); }
//
// Grab the first element
//
PExtList_EnumData->pDevExtCurrent = CONTAINING_EXTENSION( PExtList_EnumData->pListHead->Flink, PExtList_EnumData->ExtOffset );
//
// Return null if the list is empty (leave the internal pointer alone
// though...
//
if (ACPIExtListIsFinished(PExtList_EnumData)) { return NULL ; }
return PExtList_EnumData->pDevExtCurrent ;
ACPIDebugExit( "ACPIExtListStartEnum" ); }
BOOLEAN EXPORT ACPIExtListTestElement( IN OUT PEXTENSIONLIST_ENUMDATA PExtList_EnumData, IN BOOLEAN ContinueEnumeration ) /*++
Routine Description:
Arguments:
Return Value:
--*/ { ACPIDebugEnter( "ACPIExtListTestElement" ); //
// If finished or stopping, simply release the spinlock
//
if (ACPIExtListIsFinished(PExtList_EnumData)||(!ContinueEnumeration)) {
if (PExtList_EnumData->WalkScheme != WALKSCHEME_NO_PROTECTION) { KeReleaseSpinLock( PExtList_EnumData->pSpinLock, PExtList_EnumData->oldIrql ); }
return FALSE ; }
if (PExtList_EnumData->WalkScheme == WALKSCHEME_REFERENCE_ENTRIES) {
//
// Always update the reference count to make sure that no one will
// ever delete the node while our spinlock is down
//
InterlockedIncrement( &(PExtList_EnumData->pDevExtCurrent->ReferenceCount) );
//
// Relinquish the spin lock
//
KeReleaseSpinLock( PExtList_EnumData->pSpinLock, PExtList_EnumData->oldIrql ); }
return TRUE ;
ACPIDebugExit( "ACPIExtListTestElement" ); }
PDEVICE_EXTENSION EXPORT ACPIExtListEnumNext( IN OUT PEXTENSIONLIST_ENUMDATA PExtList_EnumData ) /*++
Routine Description:
Arguments:
Return Value:
--*/ { LONG oldReferenceCount ; PDEVICE_EXTENSION nextExtension ; BOOLEAN enumComplete ; PLIST_ENTRY listEntry ;
ACPIDebugEnter( "ACPIExtListEnumNext" );
if (PExtList_EnumData->WalkScheme != WALKSCHEME_REFERENCE_ENTRIES) {
PExtList_EnumData->pDevExtCurrent = CONTAINING_EXTENSION( CONTAINING_LIST(PExtList_EnumData->pDevExtCurrent, PExtList_EnumData->ExtOffset)->Flink, PExtList_EnumData->ExtOffset );
enumComplete = ACPIExtListIsFinished(PExtList_EnumData) ;
return enumComplete ? NULL : PExtList_EnumData->pDevExtCurrent ; }
//
// Reacquire the spin lock
//
KeAcquireSpinLock( PExtList_EnumData->pSpinLock, &PExtList_EnumData->oldIrql );
//
// Decrement the reference count on the node
//
oldReferenceCount = InterlockedDecrement( &(PExtList_EnumData->pDevExtCurrent->ReferenceCount) );
ASSERT(!ACPIExtListIsFinished(PExtList_EnumData)) ;
//
// Next element
//
nextExtension = CONTAINING_EXTENSION( CONTAINING_LIST(PExtList_EnumData->pDevExtCurrent, PExtList_EnumData->ExtOffset)->Flink, PExtList_EnumData->ExtOffset );
//
// Remove the node, if necessary
//
if (oldReferenceCount == 0) {
//
// Deleted the old extension
//
ACPIInitDeleteDeviceExtension( PExtList_EnumData->pDevExtCurrent ); }
PExtList_EnumData->pDevExtCurrent = nextExtension ;
enumComplete = ACPIExtListIsFinished(PExtList_EnumData) ;
return enumComplete ? NULL : PExtList_EnumData->pDevExtCurrent ; ACPIDebugExit( "ACPIExtListEnumNext" ); }
VOID EXPORT ACPIExtListExitEnumEarly( IN OUT PEXTENSIONLIST_ENUMDATA PExtList_EnumData ) /*++
Routine Description:
Arguments:
Return Value:
--*/ { ACPIDebugEnter( "ACPIExtListExitEnumEarly" );
//
// Relinquish the spin lock
//
if (PExtList_EnumData->WalkScheme == WALKSCHEME_HOLD_SPINLOCK) {
KeReleaseSpinLock( PExtList_EnumData->pSpinLock, PExtList_EnumData->oldIrql ); }
return ; ACPIDebugExit( "ACPIExtListExitEnumEarly" ); }
BOOLEAN EXPORT ACPIExtListIsMemberOfRelation( IN PDEVICE_OBJECT DeviceObject, IN PDEVICE_RELATIONS DeviceRelations ) /*++
Routine Description:
This routine takes a given device object and a set of relations and checks to see if the object is already in the relation list.
Arguments:
DeviceObject - Device object to look for DeviceRelations - Relations we should examine
Return Value:
BOOLEAN - TRUE if DeviceObject is a member of the relation.
--*/ { ULONG index = 0;
ACPIDebugEnter( "ACPIExtListIsMemberOfRelation" );
//
// If the list is empty, the answer is obvious...
//
if (DeviceRelations == NULL) return FALSE ;
for (index = 0; index < DeviceRelations->Count; index++) {
if (DeviceRelations->Objects[index] == DeviceObject) {
return TRUE ; } }
return FALSE ;
ACPIDebugExit( "ACPIExtListIsMemberOfRelation" ); }
|