Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

arbiter.h File Reference

Go to the source code of this file.

Classes

struct  _ARBITER_ORDERING
struct  _ARBITER_ORDERING_LIST
struct  _ARBITER_ALTERNATIVE
struct  _ARBITER_ALLOCATION_STATE
struct  _ARBITER_INSTANCE

Defines

#define MAXULONGLONG   ((ULONGLONG)-1)
#define ARB_PRINT(Level, Message)
#define ARB_INDENT(Level, Count)
#define ALIGN_ADDRESS_DOWN(address, alignment)   ((address) & ~((ULONGLONG)alignment - 1))
#define ALIGN_ADDRESS_UP(address, alignment)   (ALIGN_ADDRESS_DOWN( (address + alignment - 1), alignment))
#define LENGTH_OF(_start, _end)   ((_end) - (_start) + 1)
#define ARBITER_ALTERNATIVE_FLAG_SHARED   0x00000001
#define ARBITER_ALTERNATIVE_FLAG_FIXED   0x00000002
#define ARBITER_ALTERNATIVE_FLAG_INVALID   0x00000004
#define ARBITER_STATE_FLAG_RETEST   0x0001
#define ARBITER_STATE_FLAG_BOOT   0x0002
#define ARBITER_STATE_FLAG_CONFLICT   0x0004
#define ARBITER_STATE_FLAG_NULL_CONFLICT_OK   0x0008
#define ARBITER_RANGE_BOOT_ALLOCATED   0x01
#define ARBITER_RANGE_ALIAS   0x10
#define ARBITER_RANGE_POSITIVE_DECODE   0x20
#define INITIAL_ALLOCATION_STATE_SIZE   PAGE_SIZE
#define ARBITER_INSTANCE_SIGNATURE   'sbrA'
#define ArbAcquireArbiterLock(_Arbiter)   KeWaitForSingleObject( (_Arbiter)->MutexEvent, Executive, KernelMode, FALSE, NULL )
#define ArbReleaseArbiterLock(_Arbiter)   KeSetEvent( (_Arbiter)->MutexEvent, 0, FALSE )
#define FOR_ALL_IN_LIST(Type, Head, Current)
#define FOR_ALL_IN_ARRAY(_Array, _Size, _Current)
#define FOR_REST_IN_ARRAY(_Array, _Size, _Current)
#define INTERSECT(s1, e1, s2, e2)
#define INTERSECT_SIZE(s1, e1, s2, e2)   ( __min((e1),(e2)) - __max((s1),(s2)) + 1)
#define LEGACY_REQUEST(_Entry)
#define PNP_REQUEST(_Entry)
#define ARBITER_PRIORITY_NULL   0
#define ARBITER_PRIORITY_PREFERRED_RESERVED   (MAXLONG-2)
#define ARBITER_PRIORITY_RESERVED   (MAXLONG-1)
#define ARBITER_PRIORITY_EXHAUSTED   (MAXLONG)

Typedefs

typedef _ARBITER_ORDERING ARBITER_ORDERING
typedef _ARBITER_ORDERINGPARBITER_ORDERING
typedef _ARBITER_ORDERING_LIST ARBITER_ORDERING_LIST
typedef _ARBITER_ORDERING_LISTPARBITER_ORDERING_LIST
typedef _ARBITER_ALTERNATIVE ARBITER_ALTERNATIVE
typedef _ARBITER_ALTERNATIVEPARBITER_ALTERNATIVE
typedef _ARBITER_ALLOCATION_STATE ARBITER_ALLOCATION_STATE
typedef _ARBITER_ALLOCATION_STATEPARBITER_ALLOCATION_STATE
typedef _ARBITER_INSTANCE
ARBITER_INSTANCE
PARBITER_INSTANCE
typedef NTSTATUS(* PARBITER_UNPACK_REQUIREMENT )(IN PIO_RESOURCE_DESCRIPTOR Descriptor, OUT PULONGLONG Minimum, OUT PULONGLONG Maximum, OUT PULONG Length, OUT PULONG Alignment)
typedef NTSTATUS(* PARBITER_PACK_RESOURCE )(IN PIO_RESOURCE_DESCRIPTOR Requirement, IN ULONGLONG Start, OUT PCM_PARTIAL_RESOURCE_DESCRIPTOR Descriptor)
typedef NTSTATUS(* PARBITER_UNPACK_RESOURCE )(IN PCM_PARTIAL_RESOURCE_DESCRIPTOR Descriptor, OUT PULONGLONG Start, OUT PULONG Length)
typedef LONG(* PARBITER_SCORE_REQUIREMENT )(IN PIO_RESOURCE_DESCRIPTOR Descriptor)
typedef NTSTATUS(* PARBITER_PREPROCESS_ENTRY )(IN PARBITER_INSTANCE Arbiter, IN PARBITER_ALLOCATION_STATE Entry)
typedef NTSTATUS(* PARBITER_ALLOCATE_ENTRY )(IN PARBITER_INSTANCE Arbiter, IN PARBITER_ALLOCATION_STATE Entry)
typedef NTSTATUS(* PARBITER_TEST_ALLOCATION )(IN PARBITER_INSTANCE Arbiter, IN OUT PLIST_ENTRY ArbitrationList)
typedef NTSTATUS(* PARBITER_COMMIT_ALLOCATION )(IN PARBITER_INSTANCE Arbiter)
typedef NTSTATUS(* PARBITER_ROLLBACK_ALLOCATION )(IN PARBITER_INSTANCE Arbiter)
typedef NTSTATUS(* PARBITER_RETEST_ALLOCATION )(IN PARBITER_INSTANCE Arbiter, IN OUT PLIST_ENTRY ArbitrationList)
typedef NTSTATUS(* PARBITER_BOOT_ALLOCATION )(IN PARBITER_INSTANCE Arbiter, IN OUT PLIST_ENTRY ArbitrationList)
typedef NTSTATUS(* PARBITER_ADD_RESERVED )(IN PARBITER_INSTANCE Arbiter, IN PIO_RESOURCE_DESCRIPTOR Requirement OPTIONAL, IN PCM_PARTIAL_RESOURCE_DESCRIPTOR Resource OPTIONAL)
typedef BOOLEAN(* PARBITER_GET_NEXT_ALLOCATION_RANGE )(PARBITER_INSTANCE Arbiter, PARBITER_ALLOCATION_STATE State)
typedef BOOLEAN(* PARBITER_FIND_SUITABLE_RANGE )(IN PARBITER_INSTANCE Arbiter, IN PARBITER_ALLOCATION_STATE State)
typedef VOID(* PARBITER_ADD_ALLOCATION )(IN PARBITER_INSTANCE Arbiter, IN PARBITER_ALLOCATION_STATE State)
typedef VOID(* PARBITER_BACKTRACK_ALLOCATION )(IN PARBITER_INSTANCE Arbiter, IN PARBITER_ALLOCATION_STATE State)
typedef BOOLEAN(* PARBITER_OVERRIDE_CONFLICT )(IN PARBITER_INSTANCE Arbiter, IN PARBITER_ALLOCATION_STATE State)
typedef NTSTATUS(* PARBITER_QUERY_ARBITRATE )(IN PARBITER_INSTANCE Arbiter, IN PLIST_ENTRY ArbitrationList)
typedef NTSTATUS(* PARBITER_QUERY_CONFLICT )(IN PARBITER_INSTANCE Arbiter, IN PDEVICE_OBJECT PhysicalDeviceObject, IN PIO_RESOURCE_DESCRIPTOR ConflictingResource, OUT PULONG ConflictCount, OUT PARBITER_CONFLICT_INFO *Conflicts)
typedef NTSTATUS(* PARBITER_START_ARBITER )(IN PARBITER_INSTANCE Arbiter, IN PCM_RESOURCE_LIST StartResources)
typedef _ARBITER_INSTANCE ARBITER_INSTANCE
typedef NTSTATUS(* PARBITER_TRANSLATE_ALLOCATION_ORDER )(OUT PIO_RESOURCE_DESCRIPTOR TranslatedDescriptor, IN PIO_RESOURCE_DESCRIPTOR RawDescriptor)

Functions

NTSTATUS ArbInitializeOrderingList (IN OUT PARBITER_ORDERING_LIST List)
VOID ArbFreeOrderingList (IN OUT PARBITER_ORDERING_LIST List)
NTSTATUS ArbCopyOrderingList (OUT PARBITER_ORDERING_LIST Destination, IN PARBITER_ORDERING_LIST Source)
NTSTATUS ArbAddOrdering (OUT PARBITER_ORDERING_LIST List, IN ULONGLONG Start, IN ULONGLONG End)
NTSTATUS ArbPruneOrdering (IN OUT PARBITER_ORDERING_LIST OrderingList, IN ULONGLONG Start, IN ULONGLONG End)
NTSTATUS ArbInitializeArbiterInstance (OUT PARBITER_INSTANCE Arbiter, IN PDEVICE_OBJECT BusDevice, IN CM_RESOURCE_TYPE ResourceType, IN PWSTR Name, IN PWSTR OrderingName, IN PARBITER_TRANSLATE_ALLOCATION_ORDER TranslateOrdering)
VOID ArbDeleteArbiterInstance (IN PARBITER_INSTANCE Arbiter)
NTSTATUS ArbArbiterHandler (IN PVOID Context, IN ARBITER_ACTION Action, IN OUT PARBITER_PARAMETERS Params)
NTSTATUS ArbTestAllocation (IN PARBITER_INSTANCE Arbiter, IN OUT PLIST_ENTRY ArbitrationList)
NTSTATUS ArbRetestAllocation (IN PARBITER_INSTANCE Arbiter, IN OUT PLIST_ENTRY ArbitrationList)
NTSTATUS ArbCommitAllocation (PARBITER_INSTANCE Arbiter)
NTSTATUS ArbRollbackAllocation (PARBITER_INSTANCE Arbiter)
NTSTATUS ArbAddReserved (IN PARBITER_INSTANCE Arbiter, IN PIO_RESOURCE_DESCRIPTOR Requirement OPTIONAL, IN PCM_PARTIAL_RESOURCE_DESCRIPTOR Resource OPTIONAL)
NTSTATUS ArbPreprocessEntry (IN PARBITER_INSTANCE Arbiter, IN PARBITER_ALLOCATION_STATE State)
NTSTATUS ArbAllocateEntry (IN PARBITER_INSTANCE Arbiter, IN PARBITER_ALLOCATION_STATE State)
NTSTATUS ArbSortArbitrationList (IN OUT PLIST_ENTRY ArbitrationList)
VOID ArbConfirmAllocation (IN PARBITER_INSTANCE Arbiter, IN PARBITER_ALLOCATION_STATE State)
BOOLEAN ArbOverrideConflict (IN PARBITER_INSTANCE Arbiter, IN PARBITER_ALLOCATION_STATE State)
NTSTATUS ArbQueryConflict (IN PARBITER_INSTANCE Arbiter, IN PDEVICE_OBJECT PhysicalDeviceObject, IN PIO_RESOURCE_DESCRIPTOR ConflictingResource, OUT PULONG ConflictCount, OUT PARBITER_CONFLICT_INFO *Conflicts)
VOID ArbBacktrackAllocation (IN PARBITER_INSTANCE Arbiter, IN PARBITER_ALLOCATION_STATE State)
BOOLEAN ArbGetNextAllocationRange (PARBITER_INSTANCE Arbiter, PARBITER_ALLOCATION_STATE State)
BOOLEAN ArbFindSuitableRange (PARBITER_INSTANCE Arbiter, PARBITER_ALLOCATION_STATE State)
VOID ArbAddAllocation (IN PARBITER_INSTANCE Arbiter, IN PARBITER_ALLOCATION_STATE State)
NTSTATUS ArbBootAllocation (IN PARBITER_INSTANCE Arbiter, IN OUT PLIST_ENTRY ArbitrationList)
NTSTATUS ArbStartArbiter (IN PARBITER_INSTANCE Arbiter, IN PCM_RESOURCE_LIST StartResources)
NTSTATUS ArbBuildAssignmentOrdering (IN OUT PARBITER_INSTANCE Arbiter, IN PWSTR AllocationOrderName, IN PWSTR ReservedResourcesName, IN PARBITER_TRANSLATE_ALLOCATION_ORDER Translate OPTIONAL)


Define Documentation

#define ALIGN_ADDRESS_DOWN address,
alignment   )     ((address) & ~((ULONGLONG)alignment - 1))
 

Definition at line 127 of file arbiter.h.

#define ALIGN_ADDRESS_UP address,
alignment   )     (ALIGN_ADDRESS_DOWN( (address + alignment - 1), alignment))
 

Definition at line 139 of file arbiter.h.

Referenced by ArbpBuildAlternative(), and IopGenericScoreRequirement().

#define ARB_INDENT Level,
Count   ) 
 

Definition at line 53 of file arbiter.h.

Referenced by ArbAllocateEntry(), and ArbGetNextAllocationRange().

#define ARB_PRINT Level,
Message   ) 
 

Definition at line 52 of file arbiter.h.

Referenced by ArbAllocateEntry(), ArbArbiterHandler(), ArbBacktrackAllocation(), ArbBootAllocation(), ArbBuildAssignmentOrdering(), ArbDumpArbiterInstance(), ArbDumpArbiterRange(), ArbDumpArbitrationList(), ArbGetNextAllocationRange(), ArbInitializeArbiterInstance(), ArbpQueryConflictCallback(), ArbQueryConflict(), ArbRetestAllocation(), ArbSortArbitrationList(), ArbTestAllocation(), IopBusNumberPackResource(), IopBusNumberScoreRequirement(), IopBusNumberUnpackRequirement(), IopBusNumberUnpackResource(), IopDmaPackResource(), IopDmaScoreRequirement(), IopDmaUnpackRequirement(), IopDmaUnpackResource(), IopGenericPackResource(), IopGenericScoreRequirement(), IopGenericUnpackRequirement(), IopGenericUnpackResource(), IopIrqPackResource(), IopIrqScoreRequirement(), IopIrqTranslateOrdering(), IopIrqUnpackRequirement(), IopIrqUnpackResource(), IopPortAddAllocation(), IopPortBacktrackAllocation(), IopPortIsAliasedRangeAvailable(), and IopTranslateBusAddress().

#define ArbAcquireArbiterLock _Arbiter   )     KeWaitForSingleObject( (_Arbiter)->MutexEvent, Executive, KernelMode, FALSE, NULL )
 

Definition at line 585 of file arbiter.h.

Referenced by ArbArbiterHandler(), and ArbBuildAssignmentOrdering().

#define ARBITER_ALTERNATIVE_FLAG_FIXED   0x00000002
 

Definition at line 156 of file arbiter.h.

Referenced by ArbBootAllocation(), ArbGetNextAllocationRange(), ArbOverrideConflict(), ArbpBuildAlternative(), and ArbpUpdatePriority().

#define ARBITER_ALTERNATIVE_FLAG_INVALID   0x00000004
 

Definition at line 161 of file arbiter.h.

Referenced by ArbBootAllocation(), and ArbpBuildAlternative().

#define ARBITER_ALTERNATIVE_FLAG_SHARED   0x00000001
 

Definition at line 150 of file arbiter.h.

Referenced by ArbAddAllocation(), ArbAllocateEntry(), ArbBootAllocation(), ArbFindSuitableRange(), ArbpBuildAlternative(), IopPortAddAllocation(), IopPortFindSuitableRange(), and IopPortIsAliasedRangeAvailable().

#define ARBITER_INSTANCE_SIGNATURE   'sbrA'
 

Definition at line 447 of file arbiter.h.

Referenced by ArbArbiterHandler(), and ArbInitializeArbiterInstance().

#define ARBITER_PRIORITY_EXHAUSTED   (MAXLONG)
 

Definition at line 672 of file arbiter.h.

Referenced by ArbGetNextAllocationRange(), and ArbpUpdatePriority().

#define ARBITER_PRIORITY_NULL   0
 

Definition at line 669 of file arbiter.h.

Referenced by ArbGetNextAllocationRange(), ArbpBuildAllocationStack(), and ArbpUpdatePriority().

#define ARBITER_PRIORITY_PREFERRED_RESERVED   (MAXLONG-2)
 

Definition at line 670 of file arbiter.h.

Referenced by ArbGetNextAllocationRange(), and ArbpUpdatePriority().

#define ARBITER_PRIORITY_RESERVED   (MAXLONG-1)
 

Definition at line 671 of file arbiter.h.

Referenced by ArbGetNextAllocationRange(), and ArbpUpdatePriority().

#define ARBITER_RANGE_ALIAS   0x10
 

Definition at line 442 of file arbiter.h.

Referenced by IopPortAddAllocation().

#define ARBITER_RANGE_BOOT_ALLOCATED   0x01
 

Definition at line 440 of file arbiter.h.

Referenced by ArbBootAllocation(), ArbFindSuitableRange(), IopMemFindSuitableRange(), IopPortFindSuitableRange(), and IopPortIsAliasedRangeAvailable().

#define ARBITER_RANGE_POSITIVE_DECODE   0x20
 

Definition at line 443 of file arbiter.h.

#define ARBITER_STATE_FLAG_BOOT   0x0002
 

Definition at line 218 of file arbiter.h.

Referenced by ArbBootAllocation().

#define ARBITER_STATE_FLAG_CONFLICT   0x0004
 

Definition at line 219 of file arbiter.h.

Referenced by ArbQueryConflict().

#define ARBITER_STATE_FLAG_NULL_CONFLICT_OK   0x0008
 

Definition at line 220 of file arbiter.h.

Referenced by ArbFindSuitableRange().

#define ARBITER_STATE_FLAG_RETEST   0x0001
 

Definition at line 217 of file arbiter.h.

Referenced by ArbRetestAllocation().

#define ArbReleaseArbiterLock _Arbiter   )     KeSetEvent( (_Arbiter)->MutexEvent, 0, FALSE )
 

Definition at line 588 of file arbiter.h.

Referenced by ArbArbiterHandler(), and ArbBuildAssignmentOrdering().

#define FOR_ALL_IN_ARRAY _Array,
_Size,
_Current   ) 
 

Value:

for ( (_Current) = (_Array); \ (_Current) < (_Array) + (_Size); \ (_Current)++ )

Definition at line 612 of file arbiter.h.

#define FOR_ALL_IN_LIST Type,
Head,
Current   ) 
 

Value:

for((Current) = CONTAINING_RECORD((Head)->Flink, Type, ListEntry); \ (Head) != &(Current)->ListEntry; \ (Current) = CONTAINING_RECORD((Current)->ListEntry.Flink, \ Type, \ ListEntry) \ )

Definition at line 602 of file arbiter.h.

#define FOR_REST_IN_ARRAY _Array,
_Size,
_Current   ) 
 

Value:

for ( ; \ (_Current) < (_Array) + (_Size); \ (_Current)++ )

Definition at line 620 of file arbiter.h.

#define INITIAL_ALLOCATION_STATE_SIZE   PAGE_SIZE
 

Definition at line 445 of file arbiter.h.

Referenced by ArbInitializeArbiterInstance().

#define INTERSECT s1,
e1,
s2,
e2   ) 
 

Value:

!( ((s1) < (s2) && (e1) < (s2)) \ ||((s2) < (s1) && (e2) < (s1)) )

Definition at line 636 of file arbiter.h.

Referenced by ArbGetNextAllocationRange(), ArbOverrideConflict(), and ArbpUpdatePriority().

#define INTERSECT_SIZE s1,
e1,
s2,
e2   )     ( __min((e1),(e2)) - __max((s1),(s2)) + 1)
 

Definition at line 653 of file arbiter.h.

Referenced by ArbGetNextAllocationRange(), and ArbpUpdatePriority().

#define LEGACY_REQUEST _Entry   ) 
 

Value:

((_Entry)->RequestSource == ArbiterRequestLegacyReported || \ (_Entry)->RequestSource == ArbiterRequestLegacyAssigned)

Definition at line 657 of file arbiter.h.

#define LENGTH_OF _start,
_end   )     ((_end) - (_start) + 1)
 

Definition at line 143 of file arbiter.h.

Referenced by ArbBootAllocation().

#define MAXULONGLONG   ((ULONGLONG)-1)
 

Definition at line 28 of file arbiter.h.

#define PNP_REQUEST _Entry   ) 
 

Value:

((_Entry)->RequestSource == ArbiterRequestPnpDetected || \ (_Entry)->RequestSource == ArbiterRequestPnpEnumerated)

Definition at line 661 of file arbiter.h.


Typedef Documentation

typedef struct _ARBITER_ALLOCATION_STATE ARBITER_ALLOCATION_STATE
 

Referenced by ArbpBuildAllocationStack(), and IopPortIsAliasedRangeAvailable().

typedef struct _ARBITER_ALTERNATIVE ARBITER_ALTERNATIVE
 

Referenced by ArbpBuildAllocationStack().

typedef struct _ARBITER_INSTANCE ARBITER_INSTANCE
 

Referenced by ArbDeleteArbiterInstance().

typedef struct _ARBITER_ORDERING ARBITER_ORDERING
 

Referenced by ArbAddOrdering(), ArbCopyOrderingList(), ArbInitializeOrderingList(), and ArbPruneOrdering().

typedef struct _ARBITER_ORDERING_LIST ARBITER_ORDERING_LIST
 

typedef VOID(* PARBITER_ADD_ALLOCATION)(IN PARBITER_INSTANCE Arbiter, IN PARBITER_ALLOCATION_STATE State)
 

Definition at line 393 of file arbiter.h.

typedef NTSTATUS(* PARBITER_ADD_RESERVED)(IN PARBITER_INSTANCE Arbiter, IN PIO_RESOURCE_DESCRIPTOR Requirement OPTIONAL, IN PCM_PARTIAL_RESOURCE_DESCRIPTOR Resource OPTIONAL)
 

Definition at line 371 of file arbiter.h.

typedef NTSTATUS(* PARBITER_ALLOCATE_ENTRY)(IN PARBITER_INSTANCE Arbiter, IN PARBITER_ALLOCATION_STATE Entry)
 

Definition at line 331 of file arbiter.h.

typedef struct _ARBITER_ALLOCATION_STATE * PARBITER_ALLOCATION_STATE
 

Referenced by ArbpBuildAllocationStack().

typedef struct _ARBITER_ALTERNATIVE * PARBITER_ALTERNATIVE
 

typedef VOID(* PARBITER_BACKTRACK_ALLOCATION)(IN PARBITER_INSTANCE Arbiter, IN PARBITER_ALLOCATION_STATE State)
 

Definition at line 400 of file arbiter.h.

typedef NTSTATUS(* PARBITER_BOOT_ALLOCATION)(IN PARBITER_INSTANCE Arbiter, IN OUT PLIST_ENTRY ArbitrationList)
 

Definition at line 364 of file arbiter.h.

typedef NTSTATUS(* PARBITER_COMMIT_ALLOCATION)(IN PARBITER_INSTANCE Arbiter)
 

Definition at line 345 of file arbiter.h.

typedef BOOLEAN(* PARBITER_FIND_SUITABLE_RANGE)(IN PARBITER_INSTANCE Arbiter, IN PARBITER_ALLOCATION_STATE State)
 

Definition at line 386 of file arbiter.h.

typedef BOOLEAN(* PARBITER_GET_NEXT_ALLOCATION_RANGE)(PARBITER_INSTANCE Arbiter, PARBITER_ALLOCATION_STATE State)
 

Definition at line 379 of file arbiter.h.

typedef struct _ARBITER_INSTANCE * PARBITER_INSTANCE
 

Definition at line 288 of file arbiter.h.

Referenced by ArbArbiterHandler().

typedef struct _ARBITER_ORDERING * PARBITER_ORDERING
 

Referenced by ArbBuildAssignmentOrdering().

typedef struct _ARBITER_ORDERING_LIST * PARBITER_ORDERING_LIST
 

Referenced by ArbInitializeOrderingList().

typedef BOOLEAN(* PARBITER_OVERRIDE_CONFLICT)(IN PARBITER_INSTANCE Arbiter, IN PARBITER_ALLOCATION_STATE State)
 

Definition at line 407 of file arbiter.h.

typedef NTSTATUS(* PARBITER_PACK_RESOURCE)(IN PIO_RESOURCE_DESCRIPTOR Requirement, IN ULONGLONG Start, OUT PCM_PARTIAL_RESOURCE_DESCRIPTOR Descriptor)
 

Definition at line 302 of file arbiter.h.

typedef NTSTATUS(* PARBITER_PREPROCESS_ENTRY)(IN PARBITER_INSTANCE Arbiter, IN PARBITER_ALLOCATION_STATE Entry)
 

Definition at line 324 of file arbiter.h.

typedef NTSTATUS(* PARBITER_QUERY_ARBITRATE)(IN PARBITER_INSTANCE Arbiter, IN PLIST_ENTRY ArbitrationList)
 

Definition at line 414 of file arbiter.h.

typedef NTSTATUS(* PARBITER_QUERY_CONFLICT)(IN PARBITER_INSTANCE Arbiter, IN PDEVICE_OBJECT PhysicalDeviceObject, IN PIO_RESOURCE_DESCRIPTOR ConflictingResource, OUT PULONG ConflictCount, OUT PARBITER_CONFLICT_INFO *Conflicts)
 

Definition at line 421 of file arbiter.h.

typedef NTSTATUS(* PARBITER_RETEST_ALLOCATION)(IN PARBITER_INSTANCE Arbiter, IN OUT PLIST_ENTRY ArbitrationList)
 

Definition at line 357 of file arbiter.h.

typedef NTSTATUS(* PARBITER_ROLLBACK_ALLOCATION)(IN PARBITER_INSTANCE Arbiter)
 

Definition at line 351 of file arbiter.h.

typedef LONG(* PARBITER_SCORE_REQUIREMENT)(IN PIO_RESOURCE_DESCRIPTOR Descriptor)
 

Definition at line 318 of file arbiter.h.

typedef NTSTATUS(* PARBITER_START_ARBITER)(IN PARBITER_INSTANCE Arbiter, IN PCM_RESOURCE_LIST StartResources)
 

Definition at line 431 of file arbiter.h.

typedef NTSTATUS(* PARBITER_TEST_ALLOCATION)(IN PARBITER_INSTANCE Arbiter, IN OUT PLIST_ENTRY ArbitrationList)
 

Definition at line 338 of file arbiter.h.

typedef NTSTATUS(* PARBITER_TRANSLATE_ALLOCATION_ORDER)(OUT PIO_RESOURCE_DESCRIPTOR TranslatedDescriptor, IN PIO_RESOURCE_DESCRIPTOR RawDescriptor)
 

Definition at line 677 of file arbiter.h.

Referenced by ArbInitializeArbiterInstance().

typedef NTSTATUS(* PARBITER_UNPACK_REQUIREMENT)(IN PIO_RESOURCE_DESCRIPTOR Descriptor, OUT PULONGLONG Minimum, OUT PULONGLONG Maximum, OUT PULONG Length, OUT PULONG Alignment)
 

Definition at line 292 of file arbiter.h.

typedef NTSTATUS(* PARBITER_UNPACK_RESOURCE)(IN PCM_PARTIAL_RESOURCE_DESCRIPTOR Descriptor, OUT PULONGLONG Start, OUT PULONG Length)
 

Definition at line 310 of file arbiter.h.


Function Documentation

VOID ArbAddAllocation IN PARBITER_INSTANCE  Arbiter,
IN PARBITER_ALLOCATION_STATE  State
 

Definition at line 2189 of file arbiter.c.

References ARBITER_ALTERNATIVE_FLAG_SHARED, ASSERT, NT_SUCCESS, NTSTATUS(), NULL, PAGED_CODE, and RtlAddRange().

Referenced by ArbInitializeArbiterInstance().

02196 : 02197 02198 This routine is called from AllocateEntry once we have found a possible 02199 solution (State->Start - State->End). It adds the ranges that will not be 02200 available if we commit to this solution to Arbiter->PossibleAllocation. 02201 02202 Arguments: 02203 02204 Arbiter - The instance data of the arbiter who was called. 02205 02206 State - The state of the current arbitration. 02207 02208 Return Value: 02209 02210 None. 02211 02212 --*/ 02213 02214 { 02215 02216 NTSTATUS status; 02217 02218 PAGED_CODE(); 02219 02220 status = RtlAddRange( 02221 Arbiter->PossibleAllocation, 02222 State->Start, 02223 State->End, 02224 State->RangeAttributes, 02225 RTL_RANGE_LIST_ADD_IF_CONFLICT + 02226 (State->CurrentAlternative->Flags & ARBITER_ALTERNATIVE_FLAG_SHARED 02227 ? RTL_RANGE_LIST_ADD_SHARED : 0), 02228 NULL, 02229 State->Entry->PhysicalDeviceObject 02230 ); 02231 02232 ASSERT(NT_SUCCESS(status)); 02233 02234 }

NTSTATUS ArbAddOrdering OUT PARBITER_ORDERING_LIST  List,
IN ULONGLONG  Start,
IN ULONGLONG  End
 

Definition at line 3028 of file arbiter.c.

References ARBITER_ORDERING, ARBITER_ORDERING_GROW_SIZE, ARBITER_ORDERING_LIST_TAG, ASSERT, End, ExAllocatePoolWithTag, ExFreePool(), List, PagedPool, and Start.

Referenced by ArbBuildAssignmentOrdering().

03036 : 03037 03038 This routine adds the range Start-End to the end of the ordering list. No 03039 checking for overlaps or pruning is done (see ArbpPruneOrdering) 03040 03041 Arguments: 03042 03043 OrderingList - The list where the range should be added. 03044 03045 Start - The start of the range to be added. 03046 03047 End - The end of the range to be added. 03048 03049 Return Value: 03050 03051 Status code that indicates whether or not the function was successful. 03052 03053 --*/ 03054 03055 { 03056 03057 // 03058 // Validate parameters 03059 // 03060 03061 if (End < Start) { 03062 return STATUS_INVALID_PARAMETER; 03063 } 03064 03065 // 03066 // Check if the buffer is full 03067 // 03068 03069 if (List->Count == List->Maximum) { 03070 03071 PARBITER_ORDERING temp; 03072 03073 // 03074 // Out of space - grow the buffer 03075 // 03076 03077 temp = ExAllocatePoolWithTag(PagedPool, 03078 (List->Count + ARBITER_ORDERING_GROW_SIZE) * 03079 sizeof(ARBITER_ORDERING), 03080 ARBITER_ORDERING_LIST_TAG 03081 ); 03082 03083 if (!temp) { 03084 return STATUS_INSUFFICIENT_RESOURCES; 03085 } 03086 03087 // 03088 // If we had any orderings copy them 03089 // 03090 03091 if (List->Orderings) { 03092 03093 RtlCopyMemory(temp, 03094 List->Orderings, 03095 List->Count * sizeof(ARBITER_ORDERING) 03096 ); 03097 03098 ExFreePool(List->Orderings); 03099 } 03100 03101 List->Maximum += ARBITER_ORDERING_GROW_SIZE; 03102 List->Orderings = temp; 03103 03104 } 03105 03106 // 03107 // Add the entry to the list 03108 // 03109 03110 List->Orderings[List->Count].Start = Start; 03111 List->Orderings[List->Count].End = End; 03112 List->Count++; 03113 03114 ASSERT(List->Count <= List->Maximum); 03115 03116 return STATUS_SUCCESS; 03117 }

NTSTATUS ArbAddReserved IN PARBITER_INSTANCE  Arbiter,
IN PIO_RESOURCE_DESCRIPTOR Requirement  OPTIONAL,
IN PCM_PARTIAL_RESOURCE_DESCRIPTOR Resource  OPTIONAL
 

Definition at line 3630 of file arbiter.c.

References PAGED_CODE.

Referenced by ArbInitializeArbiterInstance().

03635 { 03636 PAGED_CODE(); 03637 03638 return STATUS_NOT_SUPPORTED; 03639 }

NTSTATUS ArbAllocateEntry IN PARBITER_INSTANCE  Arbiter,
IN PARBITER_ALLOCATION_STATE  State
 

Definition at line 2325 of file arbiter.c.

References ARB_INDENT, ARB_PRINT, ARBITER_ALTERNATIVE_FLAG_SHARED, ArbiterResultNullRequest, ASSERT, _ARBITER_LIST_ENTRY::Assignment, _ARBITER_ALLOCATION_STATE::CurrentAlternative, _ARBITER_ALLOCATION_STATE::CurrentMaximum, _ARBITER_ALLOCATION_STATE::CurrentMinimum, _ARBITER_ALTERNATIVE::Descriptor, _ARBITER_ALLOCATION_STATE::End, _ARBITER_ALLOCATION_STATE::Entry, FALSE, _ARBITER_ALTERNATIVE::Flags, _ARBITER_ALTERNATIVE::Length, _ARBITER_ALTERNATIVE::Minimum, NT_SUCCESS, NTSTATUS(), NULL, PAGED_CODE, _ARBITER_LIST_ENTRY::PhysicalDeviceObject, _ARBITER_LIST_ENTRY::Result, _ARBITER_LIST_ENTRY::SelectedAlternative, _ARBITER_ALLOCATION_STATE::Start, and TRUE.

Referenced by ArbInitializeArbiterInstance().

02331 : 02332 02333 This is the core arbitration routine and is called from TestAllocation 02334 to allocate resources for all of the entries in the allocation stack. 02335 It calls off to various helper routines (described above) to perform this 02336 task. 02337 02338 Arguments: 02339 02340 Arbiter - The instance data of the arbiter who was called. 02341 02342 State - The state of the current arbitration. 02343 02344 Return Value: 02345 02346 None. 02347 02348 --*/ 02349 02350 02351 02352 { 02353 02354 NTSTATUS status; 02355 PARBITER_ALLOCATION_STATE currentState = State; 02356 BOOLEAN backtracking = FALSE; 02357 02358 PAGED_CODE(); 02359 02360 // 02361 // Have we reached the end of the list? If so then we have a working 02362 // allocation. 02363 // 02364 02365 tryAllocation: 02366 02367 while(currentState >= State && currentState->Entry != NULL) { 02368 02369 // 02370 // Do any preprocessing that is required 02371 // 02372 02373 status = Arbiter->PreprocessEntry(Arbiter,currentState); 02374 02375 if (!NT_SUCCESS(status)) { 02376 return status; 02377 } 02378 02379 // 02380 // If we need to backtrack do so! 02381 // 02382 02383 if (backtracking) { 02384 02385 ULONGLONG possibleCurrentMinimum; 02386 02387 backtracking = FALSE; 02388 02389 // 02390 // Clear the CurrentAlternative of the *next* alternative - this will 02391 // cause the priorities to be recalculated next time through so we 02392 // will attempt to explore the search space again 02393 // 02394 // The currentState+1 is guaranteed to be safe because the only way 02395 // we can get here is from where we currentState-- below. 02396 // 02397 02398 (currentState + 1)->CurrentAlternative = NULL; 02399 02400 // 02401 // We can't backtrack length 0 requests because there is nothing to 02402 // backtrack so we would get stuck in an inifinite loop... 02403 // 02404 02405 if (currentState->CurrentAlternative->Length == 0) { 02406 goto failAllocation; 02407 } 02408 02409 // 02410 // Backtrack 02411 // 02412 02413 Arbiter->BacktrackAllocation(Arbiter, currentState); 02414 02415 // 02416 // Reduce allocation window to not include the range we backtracked 02417 // and check that that doesn't underflow the minimum or wrap 02418 // 02419 02420 possibleCurrentMinimum = currentState->Start - 1; 02421 02422 if (possibleCurrentMinimum > currentState->CurrentMinimum // wrapped 02423 || possibleCurrentMinimum < currentState->CurrentAlternative->Minimum) { 02424 02425 // 02426 // We have run out space in this alternative move on to the next 02427 // 02428 02429 goto continueWithNextAllocationRange; 02430 02431 } else { 02432 02433 currentState->CurrentMaximum = possibleCurrentMinimum; 02434 02435 // 02436 // Get back into arbitrating at the right point 02437 // 02438 02439 goto continueWithNextSuitableRange; 02440 } 02441 } 02442 02443 // 02444 // Try to allocate for this entry 02445 // 02446 02447 continueWithNextAllocationRange: 02448 02449 while (Arbiter->GetNextAllocationRange(Arbiter, currentState)) { 02450 02451 ARB_INDENT(2, (ULONG)(currentState - State)); 02452 02453 ARB_PRINT(2, 02454 ("Testing 0x%I64x-0x%I64x %s\n", 02455 currentState->CurrentMinimum, 02456 currentState->CurrentMaximum, 02457 currentState->CurrentAlternative->Flags & ARBITER_ALTERNATIVE_FLAG_SHARED ? 02458 "shared" : "non-shared" 02459 )); 02460 02461 continueWithNextSuitableRange: 02462 02463 while (Arbiter->FindSuitableRange(Arbiter, currentState)) { 02464 02465 // 02466 // We found a possible solution 02467 // 02468 02469 ARB_INDENT(2, (ULONG)(currentState - State)); 02470 02471 if (currentState->CurrentAlternative->Length != 0) { 02472 02473 ARB_PRINT(2, 02474 ("Possible solution for %p = 0x%I64x-0x%I64x, %s\n", 02475 currentState->Entry->PhysicalDeviceObject, 02476 currentState->Start, 02477 currentState->End, 02478 currentState->CurrentAlternative->Flags & ARBITER_ALTERNATIVE_FLAG_SHARED ? 02479 "shared" : "non-shared" 02480 )); 02481 02482 // 02483 // Update the arbiter with the possible allocation 02484 // 02485 02486 Arbiter->AddAllocation(Arbiter, currentState); 02487 02488 } else { 02489 02490 ARB_PRINT(2, 02491 ("Zero length solution solution for %p = 0x%I64x-0x%I64x, %s\n", 02492 currentState->Entry->PhysicalDeviceObject, 02493 currentState->Start, 02494 currentState->End, 02495 currentState->CurrentAlternative->Flags & ARBITER_ALTERNATIVE_FLAG_SHARED ? 02496 "shared" : "non-shared" 02497 )); 02498 02499 // 02500 // Set the result in the arbiter appropriatley so that we 02501 // don't try and translate this zero requirement - it won't! 02502 // 02503 02504 currentState->Entry->Result = ArbiterResultNullRequest; 02505 } 02506 02507 // 02508 // Move on to the next entry 02509 // 02510 02511 currentState++; 02512 goto tryAllocation; 02513 } 02514 } 02515 02516 failAllocation: 02517 02518 // 02519 // We couldn't allocate for this device 02520 // 02521 02522 if (currentState == State) { 02523 02524 // 02525 // We are at the top of the allocation stack to we can't backtrack - 02526 // *** GAME OVER *** 02527 // 02528 02529 return STATUS_UNSUCCESSFUL; 02530 02531 } else { 02532 02533 // 02534 // Backtrack and try again 02535 // 02536 02537 ARB_INDENT(2, (ULONG)(currentState - State)); 02538 02539 ARB_PRINT(2, 02540 ("Allocation failed for %p - backtracking\n", 02541 currentState->Entry->PhysicalDeviceObject 02542 )); 02543 02544 backtracking = TRUE; 02545 02546 // 02547 // Pop the last state off the stack and try a different path 02548 // 02549 02550 currentState--; 02551 goto tryAllocation; 02552 } 02553 } 02554 02555 // 02556 // We have successfully allocated for all ranges so fill in the allocation 02557 // 02558 02559 currentState = State; 02560 02561 while (currentState->Entry != NULL) { 02562 02563 status = Arbiter->PackResource( 02564 currentState->CurrentAlternative->Descriptor, 02565 currentState->Start, 02566 currentState->Entry->Assignment 02567 ); 02568 02569 ASSERT(NT_SUCCESS(status)); 02570 02571 // 02572 // Remember the alternative we chose from so we can retrieve it during retest 02573 // 02574 02575 currentState->Entry->SelectedAlternative 02576 = currentState->CurrentAlternative->Descriptor; 02577 02578 ARB_PRINT(2, 02579 ("Assigned - 0x%I64x-0x%I64x\n", 02580 currentState->Start, 02581 currentState->End 02582 )); 02583 02584 currentState++; 02585 } 02586 02587 return STATUS_SUCCESS; 02588 02589 }

NTSTATUS ArbArbiterHandler IN PVOID  Context,
IN ARBITER_ACTION  Action,
IN OUT PARBITER_PARAMETERS  Params
 

Definition at line 1414 of file arbiter.c.

References Action, ARB_PRINT, ArbAcquireArbiterLock, ARBITER_ACTION, ARBITER_INSTANCE_SIGNATURE, ArbiterActionAddReserved, ArbiterActionBootAllocation, ArbiterActionCommitAllocation, ArbiterActionQueryAllocatedResources, ArbiterActionQueryArbitrate, ArbiterActionQueryConflict, ArbiterActionRetestAllocation, ArbiterActionRollbackAllocation, ArbiterActionTestAllocation, ArbiterActionWriteReservedResources, ArbpActionStrings, ArbReleaseArbiterLock, ArbReplayOnError, ArbStopOnError, ASSERT, FALSE, NT_SUCCESS, NTSTATUS(), NULL, PAGED_CODE, PARBITER_INSTANCE, PARBITER_PARAMETERS, and TRUE.

Referenced by IopPnPDispatch().

01422 : 01423 01424 This provides the default entry point to an arbiter. 01425 01426 Parameters: 01427 01428 Context - The context provided in the interface where this function was 01429 called from. This is converted to an ARBITER_INSTANCE using the 01430 ARBITER_CONTEXT_TO_INSTANCE macro which should be defined. 01431 01432 Action - The action the arbiter should perform. 01433 01434 Params - The parameters for the action. 01435 01436 Return Value: 01437 01438 Status code that indicates whether or not the function was successful. 01439 01440 Note: 01441 01442 The routines which implement each action are determined from the dispatch 01443 table in the arbiter instance. 01444 01445 --*/ 01446 01447 { 01448 01449 NTSTATUS status; 01450 PARBITER_INSTANCE arbiter = Context; 01451 01452 PAGED_CODE(); 01453 ASSERT(Context); 01454 ASSERT(Action >= 0 && Action <= ArbiterActionBootAllocation); 01455 ASSERT(arbiter->Signature == ARBITER_INSTANCE_SIGNATURE); 01456 01457 // 01458 // Acquire the state lock 01459 // 01460 01461 ArbAcquireArbiterLock(arbiter); 01462 01463 // 01464 // Announce ourselves 01465 // 01466 01467 ARB_PRINT(2, 01468 ("%s %S\n", 01469 ArbpActionStrings[Action], 01470 arbiter->Name 01471 )); 01472 01473 // 01474 // Check the transaction flag 01475 // 01476 01477 if (Action == ArbiterActionTestAllocation 01478 || Action == ArbiterActionRetestAllocation 01479 || Action == ArbiterActionBootAllocation) { 01480 01481 ASSERT(!arbiter->TransactionInProgress); 01482 01483 } else if (Action == ArbiterActionCommitAllocation 01484 || Action == ArbiterActionRollbackAllocation) { 01485 01486 ASSERT(arbiter->TransactionInProgress); 01487 } 01488 01489 #if ARB_DBG 01490 01491 replay: 01492 01493 #endif 01494 01495 // 01496 // Do the appropriate thing 01497 // 01498 01499 switch (Action) { 01500 01501 case ArbiterActionTestAllocation: 01502 01503 // 01504 // Suballocation can not occur for a root arbiter 01505 // BUGBUG - this should be generalised 01506 // 01507 ASSERT(Params->Parameters.TestAllocation.AllocateFromCount == 0); 01508 ASSERT(Params->Parameters.TestAllocation.AllocateFrom == NULL); 01509 01510 status = arbiter->TestAllocation( 01511 arbiter, 01512 Params->Parameters.TestAllocation.ArbitrationList 01513 ); 01514 break; 01515 01516 case ArbiterActionRetestAllocation: 01517 01518 // 01519 // Suballocation can not occur for a root arbiter 01520 // BUGBUG - this should be generalised 01521 // 01522 ASSERT(Params->Parameters.TestAllocation.AllocateFromCount == 0); 01523 ASSERT(Params->Parameters.TestAllocation.AllocateFrom == NULL); 01524 01525 status = arbiter->RetestAllocation( 01526 arbiter, 01527 Params->Parameters.TestAllocation.ArbitrationList 01528 ); 01529 break; 01530 01531 case ArbiterActionCommitAllocation: 01532 01533 status = arbiter->CommitAllocation(arbiter); 01534 01535 break; 01536 01537 case ArbiterActionRollbackAllocation: 01538 01539 status = arbiter->RollbackAllocation(arbiter); 01540 01541 break; 01542 01543 case ArbiterActionBootAllocation: 01544 01545 status = arbiter->BootAllocation( 01546 arbiter, 01547 Params->Parameters.BootAllocation.ArbitrationList 01548 ); 01549 break; 01550 01551 case ArbiterActionQueryConflict: 01552 01553 status = arbiter->QueryConflict( 01554 arbiter, 01555 Params->Parameters.QueryConflict.PhysicalDeviceObject, 01556 Params->Parameters.QueryConflict.ConflictingResource, 01557 Params->Parameters.QueryConflict.ConflictCount, 01558 Params->Parameters.QueryConflict.Conflicts 01559 ); 01560 break; 01561 01562 case ArbiterActionQueryArbitrate: 01563 case ArbiterActionQueryAllocatedResources: 01564 case ArbiterActionWriteReservedResources: 01565 case ArbiterActionAddReserved: 01566 01567 status = STATUS_NOT_IMPLEMENTED; 01568 break; 01569 01570 default: 01571 status = STATUS_INVALID_PARAMETER; 01572 break; 01573 } 01574 01575 #if ARB_DBG 01576 01577 // 01578 // Check if we failed and want to stop or replay on errors 01579 // 01580 01581 if (!NT_SUCCESS(status)) { 01582 01583 ARB_PRINT(1, 01584 ("*** %s for %S FAILED status = %08x\n", 01585 ArbpActionStrings[Action], 01586 arbiter->Name, 01587 status 01588 )); 01589 01590 if (ArbStopOnError) { 01591 DbgBreakPoint(); 01592 } 01593 01594 if (ArbReplayOnError) { 01595 goto replay; 01596 } 01597 } 01598 01599 #endif // ARB_DBG 01600 01601 if (NT_SUCCESS(status)) { 01602 01603 if (Action == ArbiterActionTestAllocation 01604 || Action == ArbiterActionRetestAllocation) { 01605 01606 arbiter->TransactionInProgress = TRUE; 01607 01608 } else if (Action == ArbiterActionCommitAllocation 01609 || Action == ArbiterActionRollbackAllocation) { 01610 01611 arbiter->TransactionInProgress = FALSE; 01612 } 01613 } 01614 01615 ArbReleaseArbiterLock(arbiter); 01616 01617 return status; 01618 01619 }

VOID ArbBacktrackAllocation IN PARBITER_INSTANCE  Arbiter,
IN PARBITER_ALLOCATION_STATE  State
 

Definition at line 2238 of file arbiter.c.

References ARB_PRINT, ASSERT, NT_SUCCESS, NTSTATUS(), PAGED_CODE, and RtlDeleteRange().

Referenced by ArbInitializeArbiterInstance(), and IopPortBacktrackAllocation().

02245 : 02246 02247 This routine is called from AllocateEntry if the possible solution 02248 (State->Start - State->End) does not allow us to allocate resources to 02249 the rest of the devices being considered. It deletes the ranges that were 02250 added to Arbiter->PossibleAllocation by AddAllocation. 02251 02252 Arguments: 02253 02254 Arbiter - The instance data of the arbiter who was called. 02255 02256 State - The state of the current arbitration. 02257 02258 Return Value: 02259 02260 None. 02261 02262 --*/ 02263 02264 02265 { 02266 NTSTATUS status; 02267 02268 PAGED_CODE(); 02269 02270 // 02271 // We couldn't allocate for the rest of the ranges then 02272 // backtrack 02273 // 02274 02275 status = RtlDeleteRange( 02276 Arbiter->PossibleAllocation, 02277 State->Start, 02278 State->End, 02279 State->Entry->PhysicalDeviceObject 02280 ); 02281 02282 ASSERT(NT_SUCCESS(status)); 02283 02284 ARB_PRINT(2, 02285 ("\t\tBacktracking on 0x%I64x-0x%I64x for %p\n", 02286 State->Start, 02287 State->End, 02288 State->Entry->PhysicalDeviceObject 02289 )); 02290 02291 }

NTSTATUS ArbBootAllocation IN PARBITER_INSTANCE  Arbiter,
IN OUT PLIST_ENTRY  ArbitrationList
 

Definition at line 1252 of file arbiter.c.

References _ARBITER_ALTERNATIVE::Alignment, _ARBITER_LIST_ENTRY::AlternativeCount, _ARBITER_ALLOCATION_STATE::AlternativeCount, _ARBITER_LIST_ENTRY::Alternatives, _ARBITER_ALLOCATION_STATE::Alternatives, ARB_PRINT, ARBITER_ALTERNATIVE_FLAG_FIXED, ARBITER_ALTERNATIVE_FLAG_INVALID, ARBITER_ALTERNATIVE_FLAG_SHARED, ARBITER_RANGE_BOOT_ALLOCATED, ARBITER_STATE_FLAG_BOOT, ArbpBuildAlternative(), ASSERT, _ARBITER_ALLOCATION_STATE::CurrentAlternative, _ARBITER_ALLOCATION_STATE::End, _ARBITER_ALLOCATION_STATE::Entry, _ARBITER_ALTERNATIVE::Flags, _ARBITER_ALLOCATION_STATE::Flags, FOR_ALL_IN_LIST, _ARBITER_ALTERNATIVE::Length, LENGTH_OF, _ARBITER_ALTERNATIVE::Maximum, _ARBITER_ALTERNATIVE::Minimum, NT_SUCCESS, NTSTATUS(), _ARBITER_LIST_ENTRY::PhysicalDeviceObject, _ARBITER_ALLOCATION_STATE::RangeAttributes, _ARBITER_ALLOCATION_STATE::RangeAvailableAttributes, RtlCopyRangeList(), RtlFreeRangeList(), _ARBITER_ALLOCATION_STATE::Start, and _ARBITER_ALLOCATION_STATE::WorkSpace.

Referenced by ArbInitializeArbiterInstance().

01258 : 01259 01260 This provides the default implementation of the BootAllocation action. 01261 It walks the arbitration list and updates the allocation to reflect the fact 01262 that the allocation entries in the list are in use. 01263 01264 Parameters: 01265 01266 Arbiter - The arbiter instance data for the arbiter being called. 01267 01268 ArbitrationList - A list of ARBITER_LIST_ENTRY entries which contain the 01269 requirements and associated devices. Each device should have one and 01270 only one requirement reflecting the resources it is currently consuming. 01271 01272 Return Value: 01273 01274 Status code that indicates whether or not the function was successful. 01275 01276 --*/ 01277 01278 { 01279 01280 NTSTATUS status; 01281 PARBITER_LIST_ENTRY current; 01282 PRTL_RANGE_LIST temp; 01283 ARBITER_ALLOCATION_STATE state; 01284 ARBITER_ALTERNATIVE alternative; 01285 01286 // 01287 // Initialize the state 01288 // 01289 01290 RtlZeroMemory(&state, sizeof(ARBITER_ALLOCATION_STATE)); 01291 RtlZeroMemory(&alternative, sizeof(ARBITER_ALTERNATIVE)); 01292 state.AlternativeCount = 1; 01293 state.Alternatives = &alternative; 01294 state.CurrentAlternative = &alternative; 01295 state.Flags = ARBITER_STATE_FLAG_BOOT; 01296 state.RangeAttributes = ARBITER_RANGE_BOOT_ALLOCATED; 01297 01298 // 01299 // Work on the possible allocation list 01300 // 01301 01302 status = RtlCopyRangeList(Arbiter->PossibleAllocation, Arbiter->Allocation); 01303 01304 FOR_ALL_IN_LIST(ARBITER_LIST_ENTRY, ArbitrationList, current) { 01305 01306 ASSERT(current->AlternativeCount == 1); 01307 ASSERT(current->PhysicalDeviceObject); 01308 01309 // 01310 // Build an alternative and state structure for this allocation and 01311 // add it to the range list 01312 // 01313 01314 state.Entry = current; 01315 01316 // 01317 // Initialize the alternative 01318 // 01319 01320 status = ArbpBuildAlternative(Arbiter, 01321 &current->Alternatives[0], 01322 &alternative 01323 ); 01324 01325 ASSERT(NT_SUCCESS(status)); 01326 ASSERT(alternative.Flags & 01327 (ARBITER_ALTERNATIVE_FLAG_FIXED | ARBITER_ALTERNATIVE_FLAG_INVALID) 01328 ); 01329 01330 state.Start = alternative.Minimum; 01331 state.End = alternative.Maximum; 01332 01333 // 01334 // Blow away the old workspace and masks 01335 // 01336 01337 state.WorkSpace = 0; 01338 state.RangeAvailableAttributes = 0; 01339 01340 // 01341 // Validate the requirement 01342 // 01343 01344 if (alternative.Length == 0 01345 || alternative.Alignment == 0 01346 || state.End < state.Start 01347 || state.Start % alternative.Alignment != 0 01348 || LENGTH_OF(state.Start, state.End) != alternative.Length) { 01349 01350 ARB_PRINT(1, 01351 ("Skipping invalid boot allocation 0x%I64x-0x%I64x L 0x%x A 0x%x for 0x%08x\n", 01352 state.Start, 01353 state.End, 01354 alternative.Length, 01355 alternative.Alignment, 01356 current->PhysicalDeviceObject 01357 )); 01358 01359 continue; 01360 } 01361 01362 #if PLUG_FEST_HACKS 01363 01364 if (alternative.Flags & ARBITER_ALTERNATIVE_FLAG_SHARED) { 01365 01366 ARB_PRINT(1, 01367 ("Skipping shared boot allocation 0x%I64x-0x%I64x L 0x%x A 0x%x for 0x%08x\n", 01368 state.Start, 01369 state.End, 01370 alternative.Length, 01371 alternative.Alignment, 01372 current->PhysicalDeviceObject 01373 )); 01374 01375 continue; 01376 } 01377 #endif 01378 01379 01380 // 01381 // Do any preprocessing that is required 01382 // 01383 01384 status = Arbiter->PreprocessEntry(Arbiter,&state); 01385 01386 if (!NT_SUCCESS(status)) { 01387 goto cleanup;; 01388 } 01389 01390 Arbiter->AddAllocation(Arbiter, &state); 01391 01392 } 01393 01394 // 01395 // Everything went OK so make this our allocated range 01396 // 01397 01398 RtlFreeRangeList(Arbiter->Allocation); 01399 temp = Arbiter->Allocation; 01400 Arbiter->Allocation = Arbiter->PossibleAllocation; 01401 Arbiter->PossibleAllocation = temp; 01402 01403 return STATUS_SUCCESS; 01404 01405 cleanup: 01406 01407 RtlFreeRangeList(Arbiter->PossibleAllocation); 01408 return status; 01409 01410 }

NTSTATUS ArbBuildAssignmentOrdering IN OUT PARBITER_INSTANCE  Arbiter,
IN PWSTR  AllocationOrderName,
IN PWSTR  ReservedResourcesName,
IN PARBITER_TRANSLATE_ALLOCATION_ORDER Translate  OPTIONAL
 

Definition at line 1622 of file arbiter.c.

References ARB_PRINT, ArbAcquireArbiterLock, ArbAddOrdering(), ArbFreeOrderingList(), ArbInitializeOrderingList(), ArbpGetRegistryValue(), ArbPruneOrdering(), ArbpWstrToUnicodeString, ArbReleaseArbiterLock, ASSERT, dummy(), _ARBITER_ORDERING::End, ExFreePool(), FOR_ALL_IN_ARRAY, FULL_INFO_DATA, KEY_ALLOCATIONORDER, KEY_RESERVEDRESOURCES, NT_SUCCESS, NTSTATUS(), NULL, PAGED_CODE, PARBITER_ORDERING, PATH_ARBITERS, and _ARBITER_ORDERING::Start.

Referenced by ArbInitializeArbiterInstance().

01631 : 01632 01633 This is called as part of arbiter initialization and extracts the allocation 01634 ordering and reserved information from the registry and combines them into 01635 an ordering list. The reserved ranges are put in Arbiter->ReservedList 01636 and the initial ordering in Arbiter->OrderingList. 01637 01638 Parameters: 01639 01640 Arbiter - The instance data of the arbiter to be initialized. 01641 01642 AllocationOrderName - The name of the key under HKLM\System\ 01643 CurrentControlSet\Control\Arbiters\AllocationOrder the ordering 01644 information should be taken from. 01645 01646 ReservedResourcesName - The name of the key under HKLM\System\ 01647 CurrentControlSet\Control\Arbiters\ReservedResources the reserved ranges 01648 information should be taken from. 01649 01650 Translate - A function to be called for each range that will perform system 01651 dependant translations required for this system. 01652 01653 Return Value: 01654 01655 Status code that indicates whether or not the function was successful. 01656 01657 --*/ 01658 01659 { 01660 NTSTATUS status; 01661 HANDLE arbitersHandle = NULL, tempHandle = NULL; 01662 UNICODE_STRING unicodeString; 01663 PKEY_VALUE_FULL_INFORMATION info = NULL; 01664 ULONG dummy; 01665 PIO_RESOURCE_LIST resourceList; 01666 PIO_RESOURCE_DESCRIPTOR current; 01667 ULONGLONG start, end; 01668 OBJECT_ATTRIBUTES attributes; 01669 IO_RESOURCE_DESCRIPTOR translated; 01670 01671 PAGED_CODE(); 01672 01673 ArbAcquireArbiterLock(Arbiter); 01674 01675 // 01676 // If we are reinitializing the orderings free the old ones 01677 // 01678 01679 ArbFreeOrderingList(&Arbiter->OrderingList); 01680 ArbFreeOrderingList(&Arbiter->ReservedList); 01681 01682 // 01683 // Initialize the orderings 01684 // 01685 01686 status = ArbInitializeOrderingList(&Arbiter->OrderingList); 01687 01688 if (!NT_SUCCESS(status)) { 01689 goto cleanup; 01690 } 01691 01692 status = ArbInitializeOrderingList(&Arbiter->ReservedList); 01693 01694 if (!NT_SUCCESS(status)) { 01695 goto cleanup; 01696 } 01697 01698 // 01699 // Open HKLM\System\CurrentControlSet\Control\Arbiters 01700 // 01701 01702 ArbpWstrToUnicodeString(&unicodeString, PATH_ARBITERS); 01703 InitializeObjectAttributes(&attributes, 01704 &unicodeString, 01705 OBJ_CASE_INSENSITIVE, 01706 NULL, 01707 (PSECURITY_DESCRIPTOR) NULL 01708 ); 01709 01710 01711 status = ZwOpenKey(&arbitersHandle, 01712 KEY_READ, 01713 &attributes 01714 ); 01715 01716 if (!NT_SUCCESS(status)) { 01717 goto cleanup; 01718 } 01719 01720 // 01721 // Open AllocationOrder 01722 // 01723 01724 ArbpWstrToUnicodeString(&unicodeString, KEY_ALLOCATIONORDER); 01725 InitializeObjectAttributes(&attributes, 01726 &unicodeString, 01727 OBJ_CASE_INSENSITIVE, 01728 arbitersHandle, 01729 (PSECURITY_DESCRIPTOR) NULL 01730 ); 01731 01732 01733 status = ZwOpenKey(&tempHandle, 01734 KEY_READ, 01735 &attributes 01736 ); 01737 01738 if (!NT_SUCCESS(status)) { 01739 goto cleanup; 01740 } 01741 01742 // 01743 // Extract the value the user asked for 01744 // 01745 01746 status = ArbpGetRegistryValue(tempHandle, 01747 AllocationOrderName, 01748 &info 01749 ); 01750 01751 if (!NT_SUCCESS(status)) { 01752 goto cleanup; 01753 } 01754 01755 // 01756 // Check if the value we retrieved was a string and if so then it was a 01757 // short cut to a value of that name - open it. 01758 // 01759 01760 if (info->Type == REG_SZ) { 01761 01762 PKEY_VALUE_FULL_INFORMATION tempInfo; 01763 01764 // BUGBUG - check this is a valid string... 01765 01766 status = ArbpGetRegistryValue(tempHandle, 01767 (PWSTR) FULL_INFO_DATA(info), 01768 &tempInfo 01769 ); 01770 01771 if (!NT_SUCCESS(status)) { 01772 goto cleanup; 01773 } 01774 01775 ExFreePool(info); 01776 info = tempInfo; 01777 01778 } 01779 01780 ZwClose(tempHandle); 01781 01782 // 01783 // We only support one level of short cuts so this should be a 01784 // REG_RESOURCE_REQUIREMENTS_LIST 01785 // 01786 01787 if (info->Type != REG_RESOURCE_REQUIREMENTS_LIST) { 01788 status = STATUS_INVALID_PARAMETER; 01789 goto cleanup; 01790 } 01791 01792 // 01793 // Extract the resource list 01794 // 01795 01796 ASSERT(((PIO_RESOURCE_REQUIREMENTS_LIST) FULL_INFO_DATA(info)) 01797 ->AlternativeLists == 1); 01798 01799 resourceList = (PIO_RESOURCE_LIST) &((PIO_RESOURCE_REQUIREMENTS_LIST) 01800 FULL_INFO_DATA(info))->List[0]; 01801 01802 // 01803 // Convert the resource list into an ordering list 01804 // 01805 01806 FOR_ALL_IN_ARRAY(resourceList->Descriptors, 01807 resourceList->Count, 01808 current) { 01809 01810 // 01811 // Perform any translation that is necessary on the resources 01812 // 01813 01814 if (ARGUMENT_PRESENT(Translate)) { 01815 01816 status = (Translate)(&translated, current); 01817 01818 if (!NT_SUCCESS(status)) { 01819 goto cleanup; 01820 } 01821 } else { 01822 translated = *current; 01823 } 01824 01825 if (translated.Type == Arbiter->ResourceType) { 01826 01827 status = Arbiter->UnpackRequirement(&translated, 01828 &start, 01829 &end, 01830 &dummy, //length 01831 &dummy //alignment 01832 ); 01833 01834 if (!NT_SUCCESS(status)) { 01835 goto cleanup; 01836 } 01837 01838 status = ArbAddOrdering(&Arbiter->OrderingList, 01839 start, 01840 end 01841 ); 01842 01843 if (!NT_SUCCESS(status)) { 01844 goto cleanup; 01845 } 01846 } 01847 } 01848 01849 // 01850 // We're finished with info... 01851 // 01852 01853 ExFreePool(info); 01854 info = NULL; 01855 01856 // 01857 // Open ReservedResources 01858 // 01859 01860 ArbpWstrToUnicodeString(&unicodeString, KEY_RESERVEDRESOURCES); 01861 InitializeObjectAttributes(&attributes, 01862 &unicodeString, 01863 OBJ_CASE_INSENSITIVE, 01864 arbitersHandle, 01865 (PSECURITY_DESCRIPTOR) NULL 01866 ); 01867 01868 01869 status = ZwCreateKey(&tempHandle, 01870 KEY_READ, 01871 &attributes, 01872 0, 01873 (PUNICODE_STRING) NULL, 01874 REG_OPTION_NON_VOLATILE, 01875 NULL 01876 ); 01877 01878 if (!NT_SUCCESS(status)) { 01879 goto cleanup; 01880 } 01881 01882 // 01883 // Extract the arbiter's reserved resources 01884 // 01885 01886 status = ArbpGetRegistryValue(tempHandle, 01887 ReservedResourcesName, 01888 &info 01889 ); 01890 01891 if (!NT_SUCCESS(status)) { 01892 goto cleanup; 01893 } 01894 01895 // 01896 // Check if the value we retrieved was a string and if so then it was a 01897 // short cut to a value of that name - open it. 01898 // 01899 01900 if (info->Type == REG_SZ) { 01901 01902 PKEY_VALUE_FULL_INFORMATION tempInfo; 01903 01904 // BUGBUG - check this is a valid string... 01905 01906 status = ArbpGetRegistryValue(tempHandle, 01907 (PWSTR) FULL_INFO_DATA(info), 01908 &tempInfo 01909 ); 01910 01911 if (!NT_SUCCESS(status)) { 01912 goto cleanup; 01913 } 01914 01915 ExFreePool(info); 01916 info = tempInfo; 01917 01918 } 01919 01920 ZwClose(tempHandle); 01921 01922 if (NT_SUCCESS(status)) { 01923 01924 ASSERT(((PIO_RESOURCE_REQUIREMENTS_LIST) FULL_INFO_DATA(info)) 01925 ->AlternativeLists == 1); 01926 01927 resourceList = (PIO_RESOURCE_LIST) &((PIO_RESOURCE_REQUIREMENTS_LIST) 01928 FULL_INFO_DATA(info))->List[0]; 01929 01930 // 01931 // Apply the reserved ranges to the ordering 01932 // 01933 01934 FOR_ALL_IN_ARRAY(resourceList->Descriptors, 01935 resourceList->Count, 01936 current) { 01937 01938 // 01939 // Perform any translation that is necessary on the resources 01940 // 01941 01942 if (ARGUMENT_PRESENT(Translate)) { 01943 01944 status = (Translate)(&translated, current); 01945 01946 if (!NT_SUCCESS(status)) { 01947 goto cleanup; 01948 } 01949 } else { 01950 translated = *current; 01951 } 01952 01953 if (translated.Type == Arbiter->ResourceType) { 01954 01955 status = Arbiter->UnpackRequirement(&translated, 01956 &start, 01957 &end, 01958 &dummy, //length 01959 &dummy //alignment 01960 ); 01961 01962 if (!NT_SUCCESS(status)) { 01963 goto cleanup; 01964 } 01965 01966 // 01967 // Add the reserved range to the reserved ordering 01968 // 01969 01970 status = ArbAddOrdering(&Arbiter->ReservedList, start, end); 01971 01972 if (!NT_SUCCESS(status)) { 01973 goto cleanup; 01974 } 01975 01976 // 01977 // Prune the reserved range from the current ordering 01978 // 01979 01980 status = ArbPruneOrdering(&Arbiter->OrderingList, start, end); 01981 01982 if (!NT_SUCCESS(status)) { 01983 goto cleanup; 01984 } 01985 01986 } 01987 } 01988 01989 ExFreePool(info); 01990 } 01991 01992 // 01993 // All done! 01994 // 01995 01996 ZwClose(arbitersHandle); 01997 01998 #if ARB_DBG 01999 02000 { 02001 PARBITER_ORDERING current; 02002 02003 FOR_ALL_IN_ARRAY(Arbiter->OrderingList.Orderings, 02004 Arbiter->OrderingList.Count, 02005 current) { 02006 ARB_PRINT(2, 02007 ("Ordering: 0x%I64x-0x%I64x\n", 02008 current->Start, 02009 current->End 02010 )); 02011 } 02012 02013 ARB_PRINT(2, ("\n")); 02014 02015 FOR_ALL_IN_ARRAY(Arbiter->ReservedList.Orderings, 02016 Arbiter->ReservedList.Count, 02017 current) { 02018 ARB_PRINT(2, 02019 ("Reserved: 0x%I64x-0x%I64x\n", 02020 current->Start, 02021 current->End 02022 )); 02023 } 02024 02025 } 02026 02027 #endif 02028 02029 ArbReleaseArbiterLock(Arbiter); 02030 02031 return STATUS_SUCCESS; 02032 02033 cleanup: 02034 02035 if (arbitersHandle) { 02036 ZwClose(arbitersHandle); 02037 } 02038 02039 if (tempHandle) { 02040 ZwClose(tempHandle); 02041 } 02042 02043 if (info) { 02044 ExFreePool(info); 02045 } 02046 02047 if (Arbiter->OrderingList.Orderings) { 02048 ExFreePool(Arbiter->OrderingList.Orderings); 02049 Arbiter->OrderingList.Count = 0; 02050 Arbiter->OrderingList.Maximum = 0; 02051 } 02052 02053 if (Arbiter->ReservedList.Orderings) { 02054 ExFreePool(Arbiter->ReservedList.Orderings); 02055 Arbiter->ReservedList.Count = 0; 02056 Arbiter->ReservedList.Maximum = 0; 02057 } 02058 02059 ArbReleaseArbiterLock(Arbiter); 02060 02061 return status; 02062 }

NTSTATUS ArbCommitAllocation PARBITER_INSTANCE  Arbiter  ) 
 

Definition at line 1026 of file arbiter.c.

References PAGED_CODE, and RtlFreeRangeList().

Referenced by ArbInitializeArbiterInstance().

01032 : 01033 01034 This provides the default implementation of the CommitAllocation action. 01035 It frees the old allocation and replaces it with the new allocation. 01036 01037 Parameters: 01038 01039 Arbiter - The arbiter instance data for the arbiter being called. 01040 01041 Return Value: 01042 01043 Status code that indicates whether or not the function was successful. 01044 01045 --*/ 01046 01047 { 01048 PRTL_RANGE_LIST temp; 01049 01050 PAGED_CODE(); 01051 01052 // 01053 // Free up the current allocation 01054 // 01055 01056 RtlFreeRangeList(Arbiter->Allocation); 01057 01058 // 01059 // Swap the allocated and duplicate lists 01060 // 01061 01062 temp = Arbiter->Allocation; 01063 Arbiter->Allocation = Arbiter->PossibleAllocation; 01064 Arbiter->PossibleAllocation = temp; 01065 01066 return STATUS_SUCCESS; 01067 }

VOID ArbConfirmAllocation IN PARBITER_INSTANCE  Arbiter,
IN PARBITER_ALLOCATION_STATE  State
 

NTSTATUS ArbCopyOrderingList OUT PARBITER_ORDERING_LIST  Destination,
IN PARBITER_ORDERING_LIST  Source
 

Definition at line 2971 of file arbiter.c.

References ARBITER_ORDERING, ARBITER_ORDERING_LIST_TAG, ASSERT, ExAllocatePoolWithTag, NULL, PAGED_CODE, and PagedPool.

02978 : 02979 02980 This routine copies an arbiter ordering list. 02981 02982 Arguments: 02983 02984 Destination - An uninitialized arbiter ordering list where the data 02985 should be copied from 02986 02987 Source - Arbiter ordering list to be copied 02988 Return Value: 02989 02990 Status code that indicates whether or not the function was successful. 02991 02992 --*/ 02993 02994 02995 { 02996 02997 PAGED_CODE() 02998 02999 ASSERT(Source->Count <= Source->Maximum); 03000 ASSERT(Source->Maximum > 0); 03001 03002 Destination->Orderings = 03003 ExAllocatePoolWithTag(PagedPool, 03004 Source->Maximum * sizeof(ARBITER_ORDERING), 03005 ARBITER_ORDERING_LIST_TAG 03006 ); 03007 03008 if (Destination->Orderings == NULL) { 03009 return STATUS_INSUFFICIENT_RESOURCES; 03010 } 03011 03012 Destination->Count = Source->Count; 03013 Destination->Maximum = Source->Maximum; 03014 03015 if (Source->Count > 0) { 03016 03017 RtlCopyMemory(Destination->Orderings, 03018 Source->Orderings, 03019 Source->Count * sizeof(ARBITER_ORDERING) 03020 ); 03021 } 03022 03023 return STATUS_SUCCESS; 03024 }

VOID ArbDeleteArbiterInstance IN PARBITER_INSTANCE  Arbiter  ) 
 

Definition at line 469 of file arbiter.c.

References ArbFreeOrderingList(), ARBITER_INSTANCE, ExFreePool(), PAGED_CODE, and RtlFreeRangeList().

Referenced by ArbDereferenceArbiterInstance().

00472 { 00473 00474 PAGED_CODE(); 00475 00476 if (Arbiter->MutexEvent) { 00477 ExFreePool(Arbiter->MutexEvent); 00478 } 00479 00480 if (Arbiter->Allocation) { 00481 RtlFreeRangeList(Arbiter->Allocation); 00482 ExFreePool(Arbiter->Allocation); 00483 } 00484 00485 if (Arbiter->PossibleAllocation) { 00486 RtlFreeRangeList(Arbiter->PossibleAllocation); 00487 ExFreePool(Arbiter->PossibleAllocation); 00488 } 00489 00490 if (Arbiter->AllocationStack) { 00491 ExFreePool(Arbiter->AllocationStack); 00492 } 00493 00494 ArbFreeOrderingList(&Arbiter->OrderingList); 00495 ArbFreeOrderingList(&Arbiter->ReservedList); 00496 00497 #if ARB_DBG 00498 00499 RtlFillMemory(Arbiter, sizeof(ARBITER_INSTANCE), 'A'); 00500 00501 #endif 00502 00503 }

BOOLEAN ArbFindSuitableRange PARBITER_INSTANCE  Arbiter,
PARBITER_ALLOCATION_STATE  State
 

Definition at line 2065 of file arbiter.c.

References _ARBITER_ALTERNATIVE::Alignment, ARBITER_ALTERNATIVE_FLAG_SHARED, ARBITER_RANGE_BOOT_ALLOCATED, ARBITER_STATE_FLAG_NULL_CONFLICT_OK, ArbiterRequestLegacyAssigned, ArbiterRequestLegacyReported, ASSERT, _ARBITER_ALLOCATION_STATE::CurrentAlternative, _ARBITER_ALLOCATION_STATE::CurrentMaximum, _ARBITER_ALLOCATION_STATE::CurrentMinimum, _ARBITER_ALLOCATION_STATE::End, _ARBITER_ALLOCATION_STATE::Entry, FALSE, _ARBITER_ALTERNATIVE::Flags, _ARBITER_ALLOCATION_STATE::Flags, _ARBITER_ALTERNATIVE::Length, NT_SUCCESS, NTSTATUS(), PAGED_CODE, _ARBITER_ALLOCATION_STATE::RangeAvailableAttributes, _ARBITER_LIST_ENTRY::RequestSource, RtlFindRange(), _ARBITER_ALLOCATION_STATE::Start, and TRUE.

Referenced by ArbInitializeArbiterInstance(), and IopMemFindSuitableRange().

02072 : 02073 02074 This routine is called from AllocateEntry once we have decided where we want 02075 to allocate from. It tries to find a free range that matches the 02076 requirements in State while restricting its possible solutions to the range 02077 State->CurrentMinimum to State->CurrentMaximum. On success State->Start and 02078 State->End represent this range. 02079 02080 Arguments: 02081 02082 Arbiter - The instance data of the arbiter who was called. 02083 02084 State - The state of the current arbitration. 02085 02086 Return Value: 02087 02088 TRUE if we found a range, FALSE otherwise. 02089 02090 --*/ 02091 02092 { 02093 02094 NTSTATUS status; 02095 ULONG findRangeFlags = 0; 02096 02097 PAGED_CODE(); 02098 02099 ASSERT(State->CurrentAlternative); 02100 02101 // 02102 // Catch the case where we backtrack and advance past the maximum 02103 // 02104 02105 if (State->CurrentMinimum > State->CurrentMaximum) { 02106 return FALSE; 02107 } 02108 02109 // 02110 // If we are asking for zero ports then trivially succeed with the minimum 02111 // value and remember that backtracking this is a recipe for infinite loops 02112 // 02113 02114 if (State->CurrentAlternative->Length == 0) { 02115 State->End = State->Start = State->CurrentMinimum; 02116 return TRUE; 02117 } 02118 02119 // 02120 // For legacy requests from IoAssignResources (directly or by way of 02121 // HalAssignSlotResources) or IoReportResourceUsage we consider preallocated 02122 // resources to be available for backward compatibility reasons. 02123 // 02124 // If we are allocating a devices boot config then we consider all other 02125 // boot configs to be available. BUGBUG(andrewth) - this behavior is bad! 02126 // 02127 02128 if (State->Entry->RequestSource == ArbiterRequestLegacyReported 02129 || State->Entry->RequestSource == ArbiterRequestLegacyAssigned) { 02130 02131 State->RangeAvailableAttributes |= ARBITER_RANGE_BOOT_ALLOCATED; 02132 } 02133 02134 // 02135 // Check if null conflicts are OK... 02136 // 02137 02138 if (State->Flags & ARBITER_STATE_FLAG_NULL_CONFLICT_OK) { 02139 findRangeFlags |= RTL_RANGE_LIST_NULL_CONFLICT_OK; 02140 } 02141 02142 // 02143 // ...or we are shareable... 02144 // 02145 02146 if (State->CurrentAlternative->Flags & ARBITER_ALTERNATIVE_FLAG_SHARED) { 02147 findRangeFlags |= RTL_RANGE_LIST_SHARED_OK; 02148 } 02149 02150 // 02151 // Select the first free alternative from the current alternative 02152 // 02153 02154 status = RtlFindRange( 02155 Arbiter->PossibleAllocation, 02156 State->CurrentMinimum, 02157 State->CurrentMaximum, 02158 State->CurrentAlternative->Length, 02159 State->CurrentAlternative->Alignment, 02160 findRangeFlags, 02161 State->RangeAvailableAttributes, 02162 Arbiter->ConflictCallbackContext, 02163 Arbiter->ConflictCallback, 02164 &State->Start 02165 ); 02166 02167 02168 if (NT_SUCCESS(status)) { 02169 02170 // 02171 // We found a suitable range 02172 // 02173 State->End = State->Start + State->CurrentAlternative->Length - 1; 02174 02175 return TRUE; 02176 02177 } else { 02178 02179 // 02180 // We couldn't find any range so check if we will allow this conflict 02181 // - if so don'd fail! 02182 // 02183 02184 return Arbiter->OverrideConflict(Arbiter, State); 02185 } 02186 }

VOID ArbFreeOrderingList IN OUT PARBITER_ORDERING_LIST  List  ) 
 

Referenced by ArbBuildAssignmentOrdering(), and ArbDeleteArbiterInstance().

BOOLEAN ArbGetNextAllocationRange PARBITER_INSTANCE  Arbiter,
PARBITER_ALLOCATION_STATE  State
 

NTSTATUS ArbInitializeArbiterInstance OUT PARBITER_INSTANCE  Arbiter,
IN PDEVICE_OBJECT  BusDevice,
IN CM_RESOURCE_TYPE  ResourceType,
IN PWSTR  Name,
IN PWSTR  OrderingName,
IN PARBITER_TRANSLATE_ALLOCATION_ORDER  TranslateOrdering
 

Definition at line 192 of file arbiter.c.

References ARB_PRINT, ArbAddAllocation(), ArbAddReserved(), ArbAllocateEntry(), ArbBacktrackAllocation(), ArbBootAllocation(), ArbBuildAssignmentOrdering(), ArbCommitAllocation(), ArbFindSuitableRange(), ArbGetNextAllocationRange(), ARBITER_ALLOCATION_STATE_TAG, ARBITER_INSTANCE_SIGNATURE, ARBITER_MISC_TAG, ARBITER_RANGE_LIST_TAG, ArbOverrideConflict(), ArbPreprocessEntry(), ArbQueryConflict(), ArbRetestAllocation(), ArbRollbackAllocation(), ArbStartArbiter(), ArbTestAllocation(), ASSERT, ExAllocatePoolWithTag, ExFreePool(), FALSE, INITIAL_ALLOCATION_STATE_SIZE, KeInitializeEvent, Name, NonPagedPool, NT_SUCCESS, NTSTATUS(), NULL, PAGED_CODE, PagedPool, PARBITER_TRANSLATE_ALLOCATION_ORDER, RtlInitializeRangeList(), and TRUE.

Referenced by IopBusNumberInitialize(), IopDmaInitialize(), IopIrqInitialize(), IopMemInitialize(), and IopPortInitialize().

00203 : 00204 00205 This routine initializes an arbiter instance and fills in any optional NULL 00206 dispatch table entries with system default functions. 00207 00208 Parameters: 00209 00210 Arbiter - A caller allocated arbiter instance structure. 00211 The UnpackRequirement, PackResource, UnpackResource and ScoreRequirement 00212 entries should be initialized with the appropriate routines as should 00213 any other entries if the default system routines are not sufficient. 00214 00215 BusDeviceObject - The device object that exposes this arbiter - normally an 00216 FDO. 00217 00218 ResourceType - The resource type this arbiter arbitrates. 00219 00220 Name - A string used to identify the arbiter, used in debug messages and 00221 for registry storage 00222 00223 OrderingName - The name of the preferred assignment ordering list under 00224 HKLM\System\CurrentControlSet\Control\SystemResources\AssignmentOrdering 00225 00226 00227 TranslateOrdering - Function that, if present, will be called to translate 00228 each descriptor from the ordering list 00229 00230 Return Value: 00231 00232 Status code that indicates whether or not the function was successful. 00233 00234 Notes: 00235 00236 00237 --*/ 00238 00239 { 00240 NTSTATUS status; 00241 00242 PAGED_CODE(); 00243 00244 ASSERT(Arbiter->UnpackRequirement); 00245 ASSERT(Arbiter->PackResource); 00246 ASSERT(Arbiter->UnpackResource); 00247 00248 ARB_PRINT(2,("Initializing %S Arbiter...\n", Name)); 00249 00250 // 00251 // Initialize all pool allocation pointers to NULL so we can cleanup 00252 // 00253 00254 ASSERT(Arbiter->MutexEvent == NULL 00255 && Arbiter->Allocation == NULL 00256 && Arbiter->PossibleAllocation == NULL 00257 && Arbiter->AllocationStack == NULL 00258 ); 00259 00260 // 00261 // We are an arbiter 00262 // 00263 00264 Arbiter->Signature = ARBITER_INSTANCE_SIGNATURE; 00265 00266 // 00267 // Remember the bus that produced us 00268 // 00269 00270 Arbiter->BusDeviceObject = BusDeviceObject; 00271 00272 // 00273 // Initialize state lock (KEVENT must be non-paged) 00274 // 00275 00276 Arbiter->MutexEvent = ExAllocatePoolWithTag(NonPagedPool, 00277 sizeof(KEVENT), 00278 ARBITER_MISC_TAG 00279 ); 00280 00281 if (!Arbiter->MutexEvent) { 00282 status = STATUS_INSUFFICIENT_RESOURCES; 00283 goto cleanup; 00284 } 00285 00286 KeInitializeEvent(Arbiter->MutexEvent, SynchronizationEvent, TRUE); 00287 00288 // 00289 // Initialize the allocation stack to a reasonable size 00290 // 00291 00292 Arbiter->AllocationStack = ExAllocatePoolWithTag(PagedPool, 00293 INITIAL_ALLOCATION_STATE_SIZE, 00294 ARBITER_ALLOCATION_STATE_TAG 00295 ); 00296 00297 if (!Arbiter->AllocationStack) { 00298 status = STATUS_INSUFFICIENT_RESOURCES; 00299 goto cleanup; 00300 } 00301 00302 Arbiter->AllocationStackMaxSize = INITIAL_ALLOCATION_STATE_SIZE; 00303 00304 00305 // 00306 // Allocate buffers to hold the range lists 00307 // 00308 00309 Arbiter->Allocation = ExAllocatePoolWithTag(PagedPool, 00310 sizeof(RTL_RANGE_LIST), 00311 ARBITER_RANGE_LIST_TAG 00312 ); 00313 00314 if (!Arbiter->Allocation) { 00315 status = STATUS_INSUFFICIENT_RESOURCES; 00316 goto cleanup; 00317 } 00318 00319 Arbiter->PossibleAllocation = ExAllocatePoolWithTag(PagedPool, 00320 sizeof(RTL_RANGE_LIST), 00321 ARBITER_RANGE_LIST_TAG 00322 ); 00323 00324 if (!Arbiter->PossibleAllocation) { 00325 status = STATUS_INSUFFICIENT_RESOURCES; 00326 goto cleanup; 00327 } 00328 00329 // 00330 // Initialize the range lists 00331 // 00332 00333 RtlInitializeRangeList(Arbiter->Allocation); 00334 RtlInitializeRangeList(Arbiter->PossibleAllocation); 00335 00336 // 00337 // Initialize the data fields 00338 // 00339 Arbiter->TransactionInProgress = FALSE; 00340 Arbiter->Name = Name; 00341 Arbiter->ResourceType = ResourceType; 00342 00343 // 00344 // If the caller has not supplied the optional functions set them to the 00345 // defaults (If this were C++ we'd just inherit this loit but seeing as its 00346 // not we'll do it the old fashioned way...) 00347 // 00348 00349 if (!Arbiter->TestAllocation) { 00350 Arbiter->TestAllocation = ArbTestAllocation; 00351 } 00352 00353 if (!Arbiter->RetestAllocation) { 00354 Arbiter->RetestAllocation = ArbRetestAllocation; 00355 } 00356 00357 if (!Arbiter->CommitAllocation) { 00358 Arbiter->CommitAllocation = ArbCommitAllocation; 00359 } 00360 00361 if (!Arbiter->RollbackAllocation) { 00362 Arbiter->RollbackAllocation = ArbRollbackAllocation; 00363 } 00364 00365 if (!Arbiter->AddReserved) { 00366 Arbiter->AddReserved = ArbAddReserved; 00367 } 00368 00369 if (!Arbiter->PreprocessEntry) { 00370 Arbiter->PreprocessEntry = ArbPreprocessEntry; 00371 } 00372 00373 if (!Arbiter->AllocateEntry) { 00374 Arbiter->AllocateEntry = ArbAllocateEntry; 00375 } 00376 00377 if (!Arbiter->GetNextAllocationRange) { 00378 Arbiter->GetNextAllocationRange = ArbGetNextAllocationRange; 00379 } 00380 00381 if (!Arbiter->FindSuitableRange) { 00382 Arbiter->FindSuitableRange = ArbFindSuitableRange; 00383 } 00384 00385 if (!Arbiter->AddAllocation) { 00386 Arbiter->AddAllocation = ArbAddAllocation; 00387 } 00388 00389 if (!Arbiter->BacktrackAllocation) { 00390 Arbiter->BacktrackAllocation = ArbBacktrackAllocation; 00391 } 00392 00393 if (!Arbiter->OverrideConflict) { 00394 Arbiter->OverrideConflict = ArbOverrideConflict; 00395 } 00396 00397 if (!Arbiter->BootAllocation) { 00398 Arbiter->BootAllocation = ArbBootAllocation; 00399 } 00400 00401 if (!Arbiter->QueryConflict) { 00402 Arbiter->QueryConflict = ArbQueryConflict; 00403 } 00404 00405 if (!Arbiter->StartArbiter) { 00406 Arbiter->StartArbiter = ArbStartArbiter; 00407 } 00408 00409 // 00410 // Build the prefered assignment ordering - we assume that the reserved 00411 // ranges have the same name as the assignment ordering 00412 // 00413 00414 status = ArbBuildAssignmentOrdering(Arbiter, 00415 OrderingName, 00416 OrderingName, 00417 TranslateOrdering 00418 ); 00419 00420 if (!NT_SUCCESS(status)) { 00421 goto cleanup; 00422 } 00423 00424 return STATUS_SUCCESS; 00425 00426 cleanup: 00427 00428 if (Arbiter->MutexEvent) { 00429 ExFreePool(Arbiter->MutexEvent); 00430 } 00431 00432 if (Arbiter->Allocation) { 00433 ExFreePool(Arbiter->Allocation); 00434 } 00435 00436 if (Arbiter->PossibleAllocation) { 00437 ExFreePool(Arbiter->PossibleAllocation); 00438 } 00439 00440 if (Arbiter->AllocationStack) { 00441 ExFreePool(Arbiter->AllocationStack); 00442 } 00443 00444 return status; 00445 00446 }

NTSTATUS ArbInitializeOrderingList IN OUT PARBITER_ORDERING_LIST  List  ) 
 

Definition at line 2927 of file arbiter.c.

References ARBITER_ORDERING, ARBITER_ORDERING_LIST_INITIAL_SIZE, ARBITER_ORDERING_LIST_TAG, ASSERT, ExAllocatePoolWithTag, List, PAGED_CODE, PagedPool, and PARBITER_ORDERING_LIST.

Referenced by ArbBuildAssignmentOrdering().

02933 : 02934 02935 This routine inititialize an arbiter ordering list. 02936 02937 Arguments: 02938 02939 List - The list to be initialized 02940 02941 Return Value: 02942 02943 Status code that indicates whether or not the function was successful. 02944 02945 --*/ 02946 02947 { 02948 PAGED_CODE(); 02949 02950 ASSERT(List); 02951 02952 List->Orderings = ExAllocatePoolWithTag(PagedPool, 02953 ARBITER_ORDERING_LIST_INITIAL_SIZE * 02954 sizeof(ARBITER_ORDERING), 02955 ARBITER_ORDERING_LIST_TAG 02956 ); 02957 02958 if (!List->Orderings) { 02959 List->Maximum = 0; 02960 List->Count = 0; 02961 return STATUS_INSUFFICIENT_RESOURCES; 02962 } 02963 02964 List->Count = 0; 02965 List->Maximum = ARBITER_ORDERING_LIST_INITIAL_SIZE; 02966 02967 return STATUS_SUCCESS; 02968 }

BOOLEAN ArbOverrideConflict IN PARBITER_INSTANCE  Arbiter,
IN PARBITER_ALLOCATION_STATE  State
 

Definition at line 3383 of file arbiter.c.

References ARBITER_ALTERNATIVE_FLAG_FIXED, FALSE, INTERSECT, PAGED_CODE, and TRUE.

Referenced by ArbInitializeArbiterInstance().

03390 : 03391 03392 This is the default implementation of override conflict which 03393 03394 Arguments: 03395 03396 Arbiter - The instance data of the arbiter who was called. 03397 03398 State - The state of the current arbitration. 03399 03400 Return Value: 03401 03402 TRUE if the conflict is allowable, false otherwise 03403 03404 --*/ 03405 03406 { 03407 03408 PRTL_RANGE current; 03409 RTL_RANGE_LIST_ITERATOR iterator; 03410 BOOLEAN ok = FALSE; 03411 03412 PAGED_CODE(); 03413 03414 if (!(State->CurrentAlternative->Flags & ARBITER_ALTERNATIVE_FLAG_FIXED)) { 03415 return FALSE; 03416 } 03417 03418 FOR_ALL_RANGES(Arbiter->PossibleAllocation, &iterator, current) { 03419 03420 // 03421 // Only test the overlapping ones 03422 // 03423 03424 if (INTERSECT(current->Start, current->End, State->CurrentMinimum, State->CurrentMaximum)) { 03425 03426 03427 // 03428 // Check if we should ignore the range because of its attributes 03429 // 03430 03431 if (current->Attributes & State->RangeAvailableAttributes) { 03432 03433 // 03434 // We DON'T set ok to true because we are just ignoring the range, 03435 // as RtlFindRange would have and thus it can't be the cause of 03436 // RtlFindRange failing, so ignoring it can't fix the conflict. 03437 // 03438 03439 continue; 03440 } 03441 03442 // 03443 // Check if we are conflicting with ourselves AND the conflicting range 03444 // is a fixed requirement 03445 // 03446 03447 if (current->Owner == State->Entry->PhysicalDeviceObject 03448 && State->CurrentAlternative->Flags & ARBITER_ALTERNATIVE_FLAG_FIXED) { 03449 03450 State->Start=State->CurrentMinimum; 03451 State->End=State->CurrentMaximum; 03452 03453 ok = TRUE; 03454 continue; 03455 } 03456 03457 // 03458 // The conflict is still valid 03459 // 03460 03461 return FALSE; 03462 } 03463 } 03464 return ok; 03465 }

NTSTATUS ArbPreprocessEntry IN PARBITER_INSTANCE  Arbiter,
IN PARBITER_ALLOCATION_STATE  State
 

Definition at line 2295 of file arbiter.c.

References PAGED_CODE.

Referenced by ArbInitializeArbiterInstance().

02301 : 02302 02303 This routine is called from AllocateEntry to allow preprocessing of 02304 entries 02305 02306 Arguments: 02307 02308 Arbiter - The instance data of the arbiter who was called. 02309 02310 State - The state of the current arbitration. 02311 02312 Return Value: 02313 02314 None. 02315 02316 --*/ 02317 { 02318 02319 PAGED_CODE(); 02320 02321 return STATUS_SUCCESS; 02322 }

NTSTATUS ArbPruneOrdering IN OUT PARBITER_ORDERING_LIST  OrderingList,
IN ULONGLONG  Start,
IN ULONGLONG  End
 

Definition at line 3120 of file arbiter.c.

References ARBITER_ORDERING, ARBITER_ORDERING_LIST_TAG, ASSERT, _ARBITER_ORDERING::End, End, ExAllocatePoolWithTag, ExFreePool(), FOR_ALL_IN_ARRAY, NTSTATUS(), NULL, PagedPool, _ARBITER_ORDERING::Start, Start, and USHORT.

Referenced by ArbBuildAssignmentOrdering().

03128 : 03129 03130 This routine removes the range Start-End from all entries in the ordering 03131 list, splitting ranges into two or deleting them as necessary. 03132 03133 Arguments: 03134 03135 OrderingList - The list to be pruned. 03136 03137 Start - The start of the range to be deleted. 03138 03139 End - The end of the range to be deleted. 03140 03141 Return Value: 03142 03143 Status code that indicates whether or not the function was successful. 03144 03145 Note: 03146 03147 In the comments below *** represents the range Start - End and --- the range 03148 current->Start - current->End. 03149 03150 --*/ 03151 03152 { 03153 03154 NTSTATUS status; 03155 PARBITER_ORDERING current, currentInsert, newOrdering = NULL, temp = NULL; 03156 USHORT count; 03157 03158 ASSERT(OrderingList); 03159 ASSERT(OrderingList->Orderings); 03160 03161 // 03162 // Validate parameters 03163 // 03164 03165 if (End < Start) { 03166 status = STATUS_INVALID_PARAMETER; 03167 goto cleanup; 03168 } 03169 03170 // 03171 // Allocate a buffer big enough for all eventualities 03172 // 03173 03174 newOrdering = ExAllocatePoolWithTag(PagedPool, 03175 (OrderingList->Count * 2 + 1) * 03176 sizeof(ARBITER_ORDERING), 03177 ARBITER_ORDERING_LIST_TAG 03178 ); 03179 03180 if (!newOrdering) { 03181 status = STATUS_INSUFFICIENT_RESOURCES; 03182 goto cleanup; 03183 } 03184 03185 currentInsert = newOrdering; 03186 03187 // 03188 // Do we have a current ordering? 03189 // 03190 03191 if (OrderingList->Count > 0) { 03192 03193 // 03194 // Iterate through the current ordering and prune accordingly 03195 // 03196 03197 FOR_ALL_IN_ARRAY(OrderingList->Orderings, OrderingList->Count, current) { 03198 03199 if (End < current->Start || Start > current->End) { 03200 03201 // 03202 // **** or **** 03203 // ---- ---- 03204 // 03205 // We don't overlap so copy the range unchanged 03206 // 03207 03208 *currentInsert++ = *current; 03209 03210 } else if (Start > current->Start) { 03211 03212 if (End < current->End) { 03213 03214 // 03215 // **** 03216 // -------- 03217 // 03218 // Split the range into two 03219 // 03220 03221 currentInsert->Start = End + 1; 03222 currentInsert->End = current->End; 03223 currentInsert++; 03224 03225 currentInsert->Start = current->Start; 03226 currentInsert->End = Start - 1; 03227 currentInsert++; 03228 03229 03230 } else { 03231 03232 // 03233 // **** or **** 03234 // -------- -------- 03235 // 03236 // Prune the end of the range 03237 // 03238 03239 ASSERT(End >= current->End); 03240 03241 currentInsert->Start = current->Start; 03242 currentInsert->End = Start - 1; 03243 currentInsert++; 03244 } 03245 } else { 03246 03247 ASSERT(Start <= current->Start); 03248 03249 if (End < current->End) { 03250 03251 // 03252 // **** or **** 03253 // -------- -------- 03254 // 03255 // Prune the start of the range 03256 // 03257 03258 currentInsert->Start = End + 1; 03259 currentInsert->End = current->End; 03260 currentInsert++; 03261 03262 } else { 03263 03264 ASSERT(End >= current->End); 03265 03266 // 03267 // ******** or ******** 03268 // ---- -------- 03269 // 03270 // Don't copy the range (ie. Delete it) 03271 // 03272 03273 } 03274 } 03275 } 03276 } 03277 03278 03279 ASSERT(currentInsert - newOrdering >= 0); 03280 03281 count = (USHORT)(currentInsert - newOrdering); 03282 03283 // 03284 // Check if we have any orderings left 03285 // 03286 03287 if (count > 0) { 03288 03289 if (count > OrderingList->Maximum) { 03290 03291 // 03292 // There isn't enough space so allocate a new buffer 03293 // 03294 03295 temp = 03296 ExAllocatePoolWithTag(PagedPool, 03297 count * sizeof(ARBITER_ORDERING), 03298 ARBITER_ORDERING_LIST_TAG 03299 ); 03300 03301 if (!temp) { 03302 status = STATUS_INSUFFICIENT_RESOURCES; 03303 goto cleanup; 03304 } 03305 03306 if (OrderingList->Orderings) { 03307 ExFreePool(OrderingList->Orderings); 03308 } 03309 03310 OrderingList->Orderings = temp; 03311 OrderingList->Maximum = count; 03312 03313 } 03314 03315 03316 // 03317 // Copy the new ordering 03318 // 03319 03320 RtlCopyMemory(OrderingList->Orderings, 03321 newOrdering, 03322 count * sizeof(ARBITER_ORDERING) 03323 ); 03324 } 03325 03326 // 03327 // Free our temporary buffer 03328 // 03329 03330 ExFreePool(newOrdering); 03331 03332 OrderingList->Count = count; 03333 03334 return STATUS_SUCCESS; 03335 03336 cleanup: 03337 03338 if (newOrdering) { 03339 ExFreePool(newOrdering); 03340 } 03341 03342 if (temp) { 03343 ExFreePool(temp); 03344 } 03345 03346 return status; 03347 03348 } VOID

NTSTATUS ArbQueryConflict IN PARBITER_INSTANCE  Arbiter,
IN PDEVICE_OBJECT  PhysicalDeviceObject,
IN PIO_RESOURCE_DESCRIPTOR  ConflictingResource,
OUT PULONG  ConflictCount,
OUT PARBITER_CONFLICT_INFO Conflicts
 

Definition at line 3695 of file arbiter.c.

References _ARBITER_ALLOCATION_STATE::AlternativeCount, _ARBITER_ALLOCATION_STATE::Alternatives, ARB_PRINT, ARBITER_CONFLICT_INFO, ARBITER_CONFLICT_INFO_TAG, ARBITER_STATE_FLAG_CONFLICT, ArbiterRequestPnpEnumerated, ArbpBuildAlternative(), ArbpQueryConflictCallback(), ASSERT, _ARBITER_LIST_ENTRY::BusNumber, _ARBITER_ALLOCATION_STATE::CurrentAlternative, _ARBITER_ALLOCATION_STATE::CurrentMaximum, _ARBITER_ALLOCATION_STATE::CurrentMinimum, DevicePropertyBusNumber, DevicePropertyLegacyBusType, _ARBITER_CONFLICT_INFO::End, _ARBITER_ALLOCATION_STATE::End, _ARBITER_ALLOCATION_STATE::Entry, ExAllocatePoolWithTag, ExFreePool(), FALSE, _ARBITER_ALLOCATION_STATE::Flags, _ARBITER_LIST_ENTRY::InterfaceType, IoGetDeviceProperty(), _ARBITER_ALTERNATIVE::Maximum, _ARBITER_ALTERNATIVE::Minimum, NT_SUCCESS, NTSTATUS(), NULL, _ARBITER_CONFLICT_INFO::OwningObject, PAGED_CODE, PagedPool, PARBITER_CONFLICT_INFO, _ARBITER_LIST_ENTRY::PhysicalDeviceObject, _ARBITER_LIST_ENTRY::RequestSource, RtlCopyRangeList(), RtlDeleteOwnersRanges(), RtlDeleteRange(), RtlFreeRangeList(), RtlInitializeRangeList(), _ARBITER_CONFLICT_INFO::Start, _ARBITER_ALLOCATION_STATE::Start, and TRUE.

Referenced by ArbInitializeArbiterInstance().

03705 : 03706 03707 This routine examines the arbiter state and returns a list of devices that 03708 conflict with ConflictingResource 03709 03710 Arguments: 03711 03712 Arbiter - The arbiter to examine conflicts in 03713 03714 ConflictingResource - The resource we want to know the conflicts with 03715 03716 ConflictCount - On success contains the number of conflicts detected 03717 03718 ConflictList - On success contains a pointer to an array of conflicting 03719 devices 03720 03721 Return Value: 03722 03723 Status code that indicates whether or not the function was successful. 03724 03725 --*/ 03726 { 03727 NTSTATUS status; 03728 RTL_RANGE_LIST backupAllocation; 03729 BOOLEAN backedUp = FALSE; 03730 ARBITER_LIST_ENTRY entry; 03731 ARBITER_ALLOCATION_STATE state; 03732 ARBITER_ALTERNATIVE alternative; 03733 ULONG count = 0, size = 10; 03734 PRTL_RANGE conflictingRange; 03735 PARBITER_CONFLICT_INFO conflictInfo = NULL; 03736 PVOID savedContext; 03737 PRTL_CONFLICT_RANGE_CALLBACK savedCallback; 03738 ULONG sz; 03739 03740 PAGED_CODE(); 03741 03742 ASSERT(PhysicalDeviceObject); 03743 ASSERT(ConflictingResource); 03744 ASSERT(ConflictCount); 03745 ASSERT(Conflicts); 03746 // 03747 // Set up our conflict callback 03748 // 03749 savedCallback = Arbiter->ConflictCallback; 03750 savedContext = Arbiter->ConflictCallbackContext; 03751 Arbiter->ConflictCallback = ArbpQueryConflictCallback; 03752 Arbiter->ConflictCallbackContext = &conflictingRange; 03753 03754 // 03755 // If there is a transaction in progress then we need to backup the 03756 // the possible allocation so we can restore it when we are done. 03757 // 03758 03759 if (Arbiter->TransactionInProgress) { 03760 03761 RtlInitializeRangeList(&backupAllocation); 03762 03763 status = RtlCopyRangeList(&backupAllocation, Arbiter->PossibleAllocation); 03764 03765 if (!NT_SUCCESS(status)) { 03766 goto cleanup; 03767 } 03768 03769 RtlFreeRangeList(Arbiter->PossibleAllocation); 03770 03771 backedUp = TRUE; 03772 } 03773 03774 // 03775 // Fake up the allocation state 03776 // 03777 03778 03779 status = RtlCopyRangeList(Arbiter->PossibleAllocation, Arbiter->Allocation); 03780 03781 if (!NT_SUCCESS(status)) { 03782 goto cleanup; 03783 } 03784 03785 status = ArbpBuildAlternative(Arbiter, ConflictingResource, &alternative); 03786 03787 if (!NT_SUCCESS(status)) { 03788 goto cleanup; 03789 } 03790 03791 RtlZeroMemory(&state, sizeof(ARBITER_ALLOCATION_STATE)); 03792 03793 state.Start = alternative.Minimum; 03794 state.End = alternative.Maximum; 03795 state.CurrentMinimum = state.Start; 03796 state.CurrentMaximum = state.End; 03797 state.CurrentAlternative = &alternative; 03798 state.AlternativeCount = 1; 03799 state.Alternatives = &alternative; 03800 state.Flags = ARBITER_STATE_FLAG_CONFLICT; 03801 state.Entry = &entry; 03802 03803 // 03804 // BUGBUG(andrewth) - need to fill in more of this false entry 03805 // 03806 RtlZeroMemory(&entry, sizeof(ARBITER_LIST_ENTRY)); 03807 entry.RequestSource = ArbiterRequestPnpEnumerated; 03808 entry.PhysicalDeviceObject = PhysicalDeviceObject; 03809 // 03810 // BUGBUG(jamiehun) - we didn't allow for passing interface type 03811 // now we have to live with the decision 03812 // this really only comes into being for PCI Translator AFAIK 03813 // upshot of not doing this is we get false conflicts when PCI Boot alloc 03814 // maps over top of ISA alias 03815 // IoGetDeviceProperty generally does the right thing for the times we have to use this info 03816 // 03817 if (!NT_SUCCESS(IoGetDeviceProperty(PhysicalDeviceObject,DevicePropertyLegacyBusType,sizeof(entry.InterfaceType),&entry.InterfaceType,&sz))) { 03818 entry.InterfaceType = Isa; // not what I want to do! However this has the right effect - good enough for conflict detection 03819 } 03820 if (!NT_SUCCESS(IoGetDeviceProperty(PhysicalDeviceObject,DevicePropertyBusNumber,sizeof(entry.InterfaceType),&entry.BusNumber,&sz))) { 03821 entry.BusNumber = 0; // not what I want to do! However this has the right effect - good enough for conflict detection 03822 } 03823 03824 // 03825 // Initialize the return buffers 03826 // 03827 03828 conflictInfo = ExAllocatePoolWithTag(PagedPool, 03829 size * sizeof(ARBITER_CONFLICT_INFO), 03830 ARBITER_CONFLICT_INFO_TAG 03831 ); 03832 03833 if (!conflictInfo) { 03834 status = STATUS_INSUFFICIENT_RESOURCES; 03835 goto cleanup; 03836 } 03837 03838 // 03839 // Perform any necessary preprocessing 03840 // 03841 03842 status = Arbiter->PreprocessEntry(Arbiter, &state); 03843 03844 if (!NT_SUCCESS(status)) { 03845 goto cleanup; 03846 } 03847 03848 // 03849 // Remove self from list of possible allocations 03850 // status may be set, but can be ignored 03851 // we take ourself out of test completely, so that a user can 03852 // pick new values in context of rest of the world 03853 // if we decide to use RtlDeleteRange instead 03854 // make sure we do it for every alias formed in PreprocessEntry 03855 // 03856 03857 status = RtlDeleteOwnersRanges(Arbiter->PossibleAllocation, 03858 state.Entry->PhysicalDeviceObject 03859 ); 03860 03861 // 03862 // Keep trying to find a suitable range and each time we fail remember why. 03863 // 03864 conflictingRange = NULL; 03865 state.CurrentMinimum = state.Start; 03866 state.CurrentMaximum = state.End; 03867 03868 while (!Arbiter->FindSuitableRange(Arbiter, &state)) { 03869 03870 if (count == size) { 03871 03872 // 03873 // We need to resize the return buffer 03874 // 03875 03876 PARBITER_CONFLICT_INFO temp = conflictInfo; 03877 03878 size += 5; 03879 03880 conflictInfo = 03881 ExAllocatePoolWithTag(PagedPool, 03882 size * sizeof(ARBITER_CONFLICT_INFO), 03883 ARBITER_CONFLICT_INFO_TAG 03884 ); 03885 03886 if (!conflictInfo) { 03887 status = STATUS_INSUFFICIENT_RESOURCES; 03888 conflictInfo = temp; 03889 goto cleanup; 03890 } 03891 03892 RtlCopyMemory(conflictInfo, 03893 temp, 03894 count * sizeof(ARBITER_CONFLICT_INFO) 03895 ); 03896 03897 ExFreePool(temp); 03898 03899 } 03900 03901 if (conflictingRange != NULL) { 03902 conflictInfo[count].OwningObject = conflictingRange->Owner; 03903 conflictInfo[count].Start = conflictingRange->Start; 03904 conflictInfo[count].End = conflictingRange->End; 03905 // BUGBUG - maybe need some more info... 03906 count++; 03907 03908 // 03909 // Delete the range we conflicted with so we don't loop forever 03910 // 03911 #if 0 03912 status = RtlDeleteRange(Arbiter->PossibleAllocation, 03913 conflictingRange->Start, 03914 conflictingRange->End, 03915 conflictingRange->Owner 03916 ); 03917 #endif 03918 status = RtlDeleteOwnersRanges(Arbiter->PossibleAllocation, 03919 conflictingRange->Owner 03920 ); 03921 03922 if (!NT_SUCCESS(status)) { 03923 goto cleanup; 03924 } 03925 03926 } else { 03927 // 03928 // someone isn't playing by the rules (such as ACPI!) 03929 // 03930 ARB_PRINT(0,("Conflict detected - but someone hasn't set conflicting info\n")); 03931 03932 conflictInfo[count].OwningObject = NULL; 03933 conflictInfo[count].Start = (ULONGLONG)0; 03934 conflictInfo[count].End = (ULONGLONG)(-1); 03935 // BUGBUG - maybe need some more info... 03936 count++; 03937 03938 // 03939 // we daren't continue at risk of looping forever 03940 // 03941 break; 03942 } 03943 03944 // 03945 // reset for next round 03946 // 03947 conflictingRange = NULL; 03948 state.CurrentMinimum = state.Start; 03949 state.CurrentMaximum = state.End; 03950 } 03951 03952 RtlFreeRangeList(Arbiter->PossibleAllocation); 03953 03954 if (Arbiter->TransactionInProgress) { 03955 03956 status = RtlCopyRangeList(Arbiter->PossibleAllocation, &backupAllocation); 03957 03958 if (!NT_SUCCESS(status)) { 03959 goto cleanup; 03960 } 03961 03962 RtlFreeRangeList(&backupAllocation); 03963 } 03964 03965 Arbiter->ConflictCallback = savedCallback; 03966 Arbiter->ConflictCallbackContext = savedContext; 03967 03968 *Conflicts = conflictInfo; 03969 *ConflictCount = count; 03970 03971 return STATUS_SUCCESS; 03972 03973 cleanup: 03974 03975 if (conflictInfo) { 03976 ExFreePool(conflictInfo); 03977 } 03978 03979 RtlFreeRangeList(Arbiter->PossibleAllocation); 03980 03981 if (Arbiter->TransactionInProgress && backedUp) { 03982 status = RtlCopyRangeList(Arbiter->PossibleAllocation, &backupAllocation); 03983 RtlFreeRangeList(&backupAllocation); 03984 } 03985 03986 Arbiter->ConflictCallback = savedCallback; 03987 Arbiter->ConflictCallbackContext = savedContext; 03988 03989 *Conflicts = NULL; 03990 03991 return status; 03992 }

NTSTATUS ArbRetestAllocation IN PARBITER_INSTANCE  Arbiter,
IN OUT PLIST_ENTRY  ArbitrationList
 

Definition at line 1105 of file arbiter.c.

References _ARBITER_ALLOCATION_STATE::AlternativeCount, _ARBITER_ALLOCATION_STATE::Alternatives, ARB_PRINT, ARBITER_STATE_FLAG_RETEST, ArbpBuildAlternative(), ASSERT, _ARBITER_LIST_ENTRY::Assignment, _ARBITER_ALLOCATION_STATE::CurrentAlternative, _ARBITER_ALLOCATION_STATE::End, _ARBITER_ALLOCATION_STATE::Entry, _ARBITER_ALLOCATION_STATE::Flags, FOR_ALL_IN_LIST, NT_SUCCESS, NTSTATUS(), PAGED_CODE, _ARBITER_LIST_ENTRY::PhysicalDeviceObject, RtlCopyRangeList(), RtlDeleteOwnersRanges(), RtlFreeRangeList(), _ARBITER_LIST_ENTRY::SelectedAlternative, _ARBITER_ALLOCATION_STATE::Start, and _ARBITER_ALLOCATION_STATE::WorkSpace.

Referenced by ArbInitializeArbiterInstance().

01112 : 01113 01114 This provides the default implementation of the RetestAllocation action. 01115 It walks the arbitration list and updates the possible allocation to reflect 01116 the allocation entries of the list. For these entries to be valid 01117 TestAllocation must have been performed on this arbitration list. 01118 01119 Parameters: 01120 01121 Arbiter - The arbiter instance data for the arbiter being called. 01122 01123 ArbitrationList - A list of ARBITER_LIST_ENTRY entries which contain the 01124 requirements and associated devices. TestAllocation for this arbiter 01125 should have been called on this list. 01126 01127 Return Value: 01128 01129 Status code that indicates whether or not the function was successful. 01130 01131 --*/ 01132 01133 { 01134 NTSTATUS status; 01135 PARBITER_LIST_ENTRY current; 01136 ARBITER_ALLOCATION_STATE state; 01137 ARBITER_ALTERNATIVE alternative; 01138 ULONG length; 01139 01140 PAGED_CODE(); 01141 01142 // 01143 // Initialize the state 01144 // 01145 01146 RtlZeroMemory(&state, sizeof(ARBITER_ALLOCATION_STATE)); 01147 RtlZeroMemory(&alternative, sizeof(ARBITER_ALTERNATIVE)); 01148 state.AlternativeCount = 1; 01149 state.Alternatives = &alternative; 01150 state.CurrentAlternative = &alternative; 01151 state.Flags = ARBITER_STATE_FLAG_RETEST; 01152 01153 // 01154 // Copy the current allocation and reserved 01155 // 01156 01157 ARB_PRINT(2, ("Retest: Copy current allocation\n")); 01158 status = RtlCopyRangeList(Arbiter->PossibleAllocation, Arbiter->Allocation); 01159 01160 if (!NT_SUCCESS(status)) { 01161 goto cleanup; 01162 } 01163 01164 // 01165 // Free all the resources currently allocated to all the devices we 01166 // are arbitrating for 01167 // 01168 01169 FOR_ALL_IN_LIST(ARBITER_LIST_ENTRY, ArbitrationList, current) { 01170 01171 ARB_PRINT(3, 01172 ("Retest: Delete 0x%08x's resources\n", 01173 current->PhysicalDeviceObject 01174 )); 01175 01176 status = RtlDeleteOwnersRanges(Arbiter->PossibleAllocation, 01177 (PVOID) current->PhysicalDeviceObject 01178 ); 01179 01180 if (!NT_SUCCESS(status)) { 01181 goto cleanup; 01182 } 01183 } 01184 01185 // 01186 // Build an allocation state for the allocation and call AddAllocation to 01187 // update the range lists accordingly 01188 // 01189 01190 FOR_ALL_IN_LIST(ARBITER_LIST_ENTRY, ArbitrationList, current) { 01191 01192 ASSERT(current->Assignment && current->SelectedAlternative); 01193 01194 state.WorkSpace = 0; 01195 state.Entry = current; 01196 01197 // 01198 // Initialize the alternative 01199 // 01200 01201 status = ArbpBuildAlternative(Arbiter, 01202 current->SelectedAlternative, 01203 &alternative 01204 ); 01205 01206 ASSERT(NT_SUCCESS(status)); 01207 01208 // 01209 // Update it with our allocation 01210 // 01211 01212 status = Arbiter->UnpackResource(current->Assignment, 01213 &state.Start, 01214 &length 01215 ); 01216 01217 ASSERT(NT_SUCCESS(status)); 01218 01219 state.End = state.Start + length - 1; 01220 01221 // 01222 // Do any preprocessing that is required 01223 // 01224 01225 status = Arbiter->PreprocessEntry(Arbiter,&state); 01226 01227 if (!NT_SUCCESS(status)) { 01228 goto cleanup; 01229 } 01230 01231 // 01232 // If we had a requirement for length 0 then don't attemp to add the 01233 // range - it will fail! 01234 // 01235 01236 if (length != 0) { 01237 01238 Arbiter->AddAllocation(Arbiter, &state); 01239 01240 } 01241 } 01242 01243 return status; 01244 01245 cleanup: 01246 01247 RtlFreeRangeList(Arbiter->PossibleAllocation); 01248 return status; 01249 }

NTSTATUS ArbRollbackAllocation PARBITER_INSTANCE  Arbiter  ) 
 

NTSTATUS ArbSortArbitrationList IN OUT PLIST_ENTRY  ArbitrationList  ) 
 

Definition at line 955 of file arbiter.c.

References ARB_PRINT, FALSE, _ARBITER_LIST_ENTRY::ListEntry, PAGED_CODE, TRUE, and _ARBITER_LIST_ENTRY::WorkSpace.

Referenced by ArbTestAllocation().

00961 : 00962 00963 This routine sorts the arbitration list in order of each entry's 00964 WorkSpace value. 00965 00966 Parameters: 00967 00968 ArbitrationList - The list to be sorted. 00969 00970 Return Value: 00971 00972 Status code that indicates whether or not the function was successful. 00973 00974 --*/ 00975 00976 { 00977 // 00978 // BUGBUG - maybe should use a get next type thing or a better sort! 00979 // 00980 BOOLEAN sorted = FALSE; 00981 PARBITER_LIST_ENTRY current, next; 00982 00983 PAGED_CODE(); 00984 00985 ARB_PRINT(3, ("IoSortArbiterList(%p)\n", ArbitrationList)); 00986 00987 while (!sorted) { 00988 00989 sorted = TRUE; 00990 00991 for (current=(PARBITER_LIST_ENTRY) ArbitrationList->Flink, 00992 next=(PARBITER_LIST_ENTRY) current->ListEntry.Flink; 00993 00994 (PLIST_ENTRY) current != ArbitrationList 00995 && (PLIST_ENTRY) next != ArbitrationList; 00996 00997 current = (PARBITER_LIST_ENTRY) current->ListEntry.Flink, 00998 next = (PARBITER_LIST_ENTRY)current->ListEntry.Flink) { 00999 01000 01001 if (current->WorkSpace > next->WorkSpace) { 01002 01003 PLIST_ENTRY before = current->ListEntry.Blink; 01004 PLIST_ENTRY after = next->ListEntry.Flink; 01005 01006 // 01007 // Swap the locations of current and next 01008 // 01009 01010 before->Flink = (PLIST_ENTRY) next; 01011 after->Blink = (PLIST_ENTRY) current; 01012 current->ListEntry.Flink = after; 01013 current->ListEntry.Blink = (PLIST_ENTRY) next; 01014 next->ListEntry.Flink = (PLIST_ENTRY) current; 01015 next->ListEntry.Blink = before; 01016 01017 sorted = FALSE; 01018 } 01019 } 01020 } 01021 01022 return STATUS_SUCCESS; 01023 }

NTSTATUS ArbStartArbiter IN PARBITER_INSTANCE  Arbiter,
IN PCM_RESOURCE_LIST  StartResources
 

Definition at line 3996 of file arbiter.c.

References PAGED_CODE.

Referenced by ArbInitializeArbiterInstance().

04003 : 04004 04005 This function is called by the driver that implements the arbiter once 04006 it has been started and knowns what resources it can allocate to its 04007 children. 04008 04009 BUGBUG - It will eventually initialize the range lists correctly but for 04010 now it is just an overloadable place holder as that work is done elsewhere. 04011 04012 Parameters: 04013 04014 Arbiter - The instance of the arbiter being called. 04015 04016 04017 Return Value: 04018 04019 Status code that indicates whether or not the function was successful. 04020 04021 --*/ 04022 04023 { 04024 PAGED_CODE(); 04025 04026 return STATUS_SUCCESS; 04027 }

NTSTATUS ArbTestAllocation IN PARBITER_INSTANCE  Arbiter,
IN OUT PLIST_ENTRY  ArbitrationList
 

Definition at line 506 of file arbiter.c.

References _ARBITER_LIST_ENTRY::AlternativeCount, _ARBITER_LIST_ENTRY::Alternatives, ARB_PRINT, ARBITER_LIST_ENTRY, ArbpBuildAllocationStack(), ArbSortArbitrationList(), ASSERT, FOR_ALL_IN_ARRAY, FOR_ALL_IN_LIST, NT_SUCCESS, NTSTATUS(), NULL, PAGED_CODE, PARBITER_LIST_ENTRY, _ARBITER_LIST_ENTRY::PhysicalDeviceObject, RtlCopyRangeList(), RtlDeleteOwnersRanges(), RtlFreeRangeList(), and _ARBITER_LIST_ENTRY::WorkSpace.

Referenced by ArbInitializeArbiterInstance().

00513 : 00514 00515 This is the default implementation of the arbiter Test Allocation action. 00516 It takes a list of requests for resources for particular devices and attempts 00517 to satisfy them. 00518 00519 Parameters: 00520 00521 Arbiter - The instance of the arbiter being called. 00522 00523 ArbitrationList - A list of ARBITER_LIST_ENTRY entries which contain the 00524 requirements and associated devices. 00525 00526 Return Value: 00527 00528 Status code that indicates whether or not the function was successful. 00529 These include: 00530 00531 STATUS_SUCCESSFUL - Arbitration suceeded and an allocation has been made for 00532 all the entries in the arbitration list. 00533 00534 STATUS_UNSUCCESSFUL - Arbitration failed to find an allocation for all 00535 entries. 00536 00537 STATUS_ARBITRATION_UNHANDLED - If returning this error the arbiter is 00538 partial (and therefore must have set the ARBITER_PARTIAL flag in its 00539 interface.) This status indicates that this arbiter doesn't handle the 00540 resources requested and the next arbiter towards the root of the device 00541 tree should be asked instead. 00542 00543 --*/ 00544 00545 { 00546 00547 NTSTATUS status; 00548 PARBITER_LIST_ENTRY current; 00549 PIO_RESOURCE_DESCRIPTOR alternative; 00550 ULONG count; 00551 PDEVICE_OBJECT previousOwner; 00552 PDEVICE_OBJECT currentOwner; 00553 LONG score; 00554 BOOLEAN performScoring; 00555 00556 PAGED_CODE(); 00557 ASSERT(Arbiter); 00558 00559 // 00560 // Copy the current allocation 00561 // 00562 00563 ARB_PRINT(3, ("Copy current allocation\n")); 00564 status = RtlCopyRangeList(Arbiter->PossibleAllocation, Arbiter->Allocation); 00565 00566 if (!NT_SUCCESS(status)) { 00567 goto cleanup; 00568 } 00569 00570 // 00571 // Free all the resources currently allocated to all the devices we 00572 // are arbitrating for 00573 // 00574 00575 count = 0; 00576 previousOwner = NULL; 00577 00578 FOR_ALL_IN_LIST(ARBITER_LIST_ENTRY, ArbitrationList, current) { 00579 00580 count++; 00581 00582 currentOwner = current->PhysicalDeviceObject; 00583 00584 if (previousOwner != currentOwner) { 00585 00586 previousOwner = currentOwner; 00587 00588 ARB_PRINT(3, 00589 ("Delete 0x%08x's resources\n", 00590 currentOwner 00591 )); 00592 00593 status = RtlDeleteOwnersRanges(Arbiter->PossibleAllocation, 00594 (PVOID)currentOwner 00595 ); 00596 00597 if (!NT_SUCCESS(status)) { 00598 goto cleanup; 00599 } 00600 } 00601 00602 // 00603 // Score the entries in the arbitration list if a scoring function was 00604 // provided and this is not a legacy request (which is guaranteed to be 00605 // made of all fixed requests so sorting is pointless) 00606 // 00607 00608 performScoring = Arbiter->ScoreRequirement != NULL; 00609 // BUGBUG - fix for rebalance being broken and not passing in flags... 00610 // && !LEGACY_REQUEST(current); 00611 current->WorkSpace = 0; 00612 00613 if (performScoring) { 00614 00615 FOR_ALL_IN_ARRAY(current->Alternatives, 00616 current->AlternativeCount, 00617 alternative) { 00618 00619 ARB_PRINT(3, 00620 ("Scoring entry %p\n", 00621 currentOwner 00622 )); 00623 00624 00625 00626 score = Arbiter->ScoreRequirement(alternative); 00627 00628 // 00629 // Ensure the score is valid 00630 // 00631 00632 if (score < 0) { 00633 status = STATUS_DEVICE_CONFIGURATION_ERROR; 00634 goto cleanup; 00635 } 00636 00637 current->WorkSpace += score; 00638 } 00639 } 00640 } 00641 00642 status = ArbSortArbitrationList(ArbitrationList); 00643 00644 if (!NT_SUCCESS(status)) { 00645 goto cleanup; 00646 } 00647 00648 // 00649 // Build the arbitration stack 00650 // 00651 00652 status = ArbpBuildAllocationStack(Arbiter, 00653 ArbitrationList, 00654 count 00655 ); 00656 00657 if (!NT_SUCCESS(status)) { 00658 goto cleanup; 00659 } 00660 00661 // 00662 // Attempt allocation 00663 // 00664 00665 status = Arbiter->AllocateEntry(Arbiter, Arbiter->AllocationStack); 00666 00667 if (NT_SUCCESS(status)) { 00668 00669 // 00670 // Success. 00671 // 00672 00673 return status; 00674 } 00675 00676 cleanup: 00677 00678 // 00679 // We didn't succeed so empty the possible allocation list... 00680 // 00681 00682 RtlFreeRangeList(Arbiter->PossibleAllocation); 00683 00684 return status; 00685 }


Generated on Sat May 15 19:42:54 2004 for test by doxygen 1.3.7