00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
#ifndef _ARBITER_
00025
#define _ARBITER_
00026
00027
#if !defined(MAXULONGLONG)
00028 #define MAXULONGLONG ((ULONGLONG)-1)
00029
#endif
00030
00031
00032
#if ARB_DBG
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
extern LONG
ArbDebugLevel;
00043
00044
#define ARB_PRINT(Level, Message) \
00045
if (Level <= ArbDebugLevel) DbgPrint Message
00046
00047
#define ARB_INDENT(Level, Count) \
00048
if (Level < ArbDebugLevel) ArbpIndent(Count)
00049
00050
#else
00051
00052 #define ARB_PRINT(Level, Message)
00053 #define ARB_INDENT(Level, Count)
00054
00055
#endif // ARB_DBG
00056
00057
00058
00059
00060
00061
00062 typedef struct _ARBITER_ORDERING {
00063 ULONGLONG
Start;
00064 ULONGLONG
End;
00065 }
ARBITER_ORDERING, *
PARBITER_ORDERING;
00066
00067
00068 typedef struct _ARBITER_ORDERING_LIST {
00069
00070
00071
00072
00073 USHORT Count;
00074
00075
00076
00077
00078 USHORT Maximum;
00079
00080
00081
00082
00083 PARBITER_ORDERING Orderings;
00084
00085 }
ARBITER_ORDERING_LIST, *
PARBITER_ORDERING_LIST;
00086
00087
00088
NTSTATUS
00089
ArbInitializeOrderingList(
00090 IN OUT PARBITER_ORDERING_LIST List
00091 );
00092
00093
VOID
00094
ArbFreeOrderingList(
00095 IN OUT PARBITER_ORDERING_LIST List
00096 );
00097
00098
NTSTATUS
00099
ArbCopyOrderingList(
00100 OUT PARBITER_ORDERING_LIST Destination,
00101 IN PARBITER_ORDERING_LIST Source
00102 );
00103
00104
NTSTATUS
00105
ArbAddOrdering(
00106 OUT PARBITER_ORDERING_LIST List,
00107 IN ULONGLONG Start,
00108 IN ULONGLONG End
00109 );
00110
00111
NTSTATUS
00112
ArbPruneOrdering(
00113 IN OUT PARBITER_ORDERING_LIST OrderingList,
00114 IN ULONGLONG Start,
00115 IN ULONGLONG End
00116 );
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127 #define ALIGN_ADDRESS_DOWN(address, alignment) \
00128
((address) & ~((ULONGLONG)alignment - 1))
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139 #define ALIGN_ADDRESS_UP(address, alignment) \
00140
(ALIGN_ADDRESS_DOWN( (address + alignment - 1), alignment))
00141
00142
00143 #define LENGTH_OF(_start, _end) \
00144
((_end) - (_start) + 1)
00145
00146
00147
00148
00149
00150 #define ARBITER_ALTERNATIVE_FLAG_SHARED 0x00000001
00151
00152
00153
00154
00155
00156 #define ARBITER_ALTERNATIVE_FLAG_FIXED 0x00000002
00157
00158
00159
00160
00161 #define ARBITER_ALTERNATIVE_FLAG_INVALID 0x00000004
00162
00163 typedef struct _ARBITER_ALTERNATIVE {
00164
00165
00166
00167
00168 ULONGLONG
Minimum;
00169
00170
00171
00172
00173 ULONGLONG
Maximum;
00174
00175
00176
00177
00178 ULONG
Length;
00179
00180
00181
00182
00183 ULONG
Alignment;
00184
00185
00186
00187
00188
00189 LONG
Priority;
00190
00191
00192
00193
00194
00195
00196
00197
00198 ULONG
Flags;
00199
00200
00201
00202
00203 PIO_RESOURCE_DESCRIPTOR
Descriptor;
00204
00205
00206
00207
00208 ULONG
Reserved[3];
00209
00210 }
ARBITER_ALTERNATIVE, *
PARBITER_ALTERNATIVE;
00211
00212
00213
00214
00215
00216
00217 #define ARBITER_STATE_FLAG_RETEST 0x0001
00218 #define ARBITER_STATE_FLAG_BOOT 0x0002
00219 #define ARBITER_STATE_FLAG_CONFLICT 0x0004
00220 #define ARBITER_STATE_FLAG_NULL_CONFLICT_OK 0x0008
00221
00222 typedef struct _ARBITER_ALLOCATION_STATE {
00223
00224
00225
00226
00227 ULONGLONG
Start;
00228
00229
00230
00231
00232 ULONGLONG
End;
00233
00234
00235
00236
00237
00238
00239 ULONGLONG
CurrentMinimum;
00240 ULONGLONG
CurrentMaximum;
00241
00242
00243
00244
00245 PARBITER_LIST_ENTRY Entry;
00246
00247
00248
00249
00250 PARBITER_ALTERNATIVE CurrentAlternative;
00251
00252
00253
00254
00255 ULONG
AlternativeCount;
00256
00257
00258
00259
00260 PARBITER_ALTERNATIVE Alternatives;
00261
00262
00263
00264
00265
00266
00267
00268 USHORT Flags;
00269
00270
00271
00272
00273
00274 UCHAR
RangeAttributes;
00275
00276
00277
00278
00279 UCHAR
RangeAvailableAttributes;
00280
00281
00282
00283
00284 ULONG_PTR
WorkSpace;
00285
00286 }
ARBITER_ALLOCATION_STATE, *
PARBITER_ALLOCATION_STATE;
00287
00288 typedef struct _ARBITER_INSTANCE ARBITER_INSTANCE, *
PARBITER_INSTANCE;
00289
00290
typedef
00291
NTSTATUS
00292 (*PARBITER_UNPACK_REQUIREMENT) (
00293 IN PIO_RESOURCE_DESCRIPTOR Descriptor,
00294 OUT PULONGLONG Minimum,
00295 OUT PULONGLONG Maximum,
00296 OUT PULONG Length,
00297 OUT PULONG Alignment
00298 );
00299
00300
typedef
00301
NTSTATUS
00302 (*PARBITER_PACK_RESOURCE) (
00303 IN PIO_RESOURCE_DESCRIPTOR Requirement,
00304 IN ULONGLONG
Start,
00305 OUT PCM_PARTIAL_RESOURCE_DESCRIPTOR Descriptor
00306 );
00307
00308
typedef
00309
NTSTATUS
00310 (*PARBITER_UNPACK_RESOURCE) (
00311 IN PCM_PARTIAL_RESOURCE_DESCRIPTOR Descriptor,
00312 OUT PULONGLONG
Start,
00313 OUT PULONG Length
00314 );
00315
00316
typedef
00317 LONG
00318 (*PARBITER_SCORE_REQUIREMENT) (
00319 IN PIO_RESOURCE_DESCRIPTOR Descriptor
00320 );
00321
00322
typedef
00323
NTSTATUS
00324 (*PARBITER_PREPROCESS_ENTRY)(
00325 IN
PARBITER_INSTANCE Arbiter,
00326 IN
PARBITER_ALLOCATION_STATE Entry
00327 );
00328
00329
typedef
00330
NTSTATUS
00331 (*PARBITER_ALLOCATE_ENTRY)(
00332 IN
PARBITER_INSTANCE Arbiter,
00333 IN
PARBITER_ALLOCATION_STATE Entry
00334 );
00335
00336
typedef
00337
NTSTATUS
00338 (*PARBITER_TEST_ALLOCATION)(
00339 IN
PARBITER_INSTANCE Arbiter,
00340 IN OUT PLIST_ENTRY ArbitrationList
00341 );
00342
00343
typedef
00344
NTSTATUS
00345 (*PARBITER_COMMIT_ALLOCATION)(
00346 IN
PARBITER_INSTANCE Arbiter
00347 );
00348
00349
typedef
00350
NTSTATUS
00351 (*PARBITER_ROLLBACK_ALLOCATION)(
00352 IN
PARBITER_INSTANCE Arbiter
00353 );
00354
00355
typedef
00356
NTSTATUS
00357 (*PARBITER_RETEST_ALLOCATION)(
00358 IN
PARBITER_INSTANCE Arbiter,
00359 IN OUT PLIST_ENTRY ArbitrationList
00360 );
00361
00362
typedef
00363
NTSTATUS
00364 (*PARBITER_BOOT_ALLOCATION)(
00365 IN
PARBITER_INSTANCE Arbiter,
00366 IN OUT PLIST_ENTRY ArbitrationList
00367 );
00368
00369
typedef
00370
NTSTATUS
00371 (*PARBITER_ADD_RESERVED)(
00372 IN
PARBITER_INSTANCE Arbiter,
00373 IN PIO_RESOURCE_DESCRIPTOR Requirement OPTIONAL,
00374 IN PCM_PARTIAL_RESOURCE_DESCRIPTOR
Resource OPTIONAL
00375 );
00376
00377
typedef
00378 BOOLEAN
00379 (*PARBITER_GET_NEXT_ALLOCATION_RANGE)(
00380
PARBITER_INSTANCE Arbiter,
00381
PARBITER_ALLOCATION_STATE State
00382 );
00383
00384
typedef
00385 BOOLEAN
00386 (*PARBITER_FIND_SUITABLE_RANGE)(
00387 IN
PARBITER_INSTANCE Arbiter,
00388 IN
PARBITER_ALLOCATION_STATE State
00389 );
00390
00391
typedef
00392
VOID
00393 (*PARBITER_ADD_ALLOCATION)(
00394 IN
PARBITER_INSTANCE Arbiter,
00395 IN
PARBITER_ALLOCATION_STATE State
00396 );
00397
00398
typedef
00399
VOID
00400 (*PARBITER_BACKTRACK_ALLOCATION)(
00401 IN
PARBITER_INSTANCE Arbiter,
00402 IN
PARBITER_ALLOCATION_STATE State
00403 );
00404
00405
typedef
00406 BOOLEAN
00407 (*PARBITER_OVERRIDE_CONFLICT)(
00408 IN
PARBITER_INSTANCE Arbiter,
00409 IN
PARBITER_ALLOCATION_STATE State
00410 );
00411
00412
typedef
00413
NTSTATUS
00414 (*PARBITER_QUERY_ARBITRATE)(
00415 IN
PARBITER_INSTANCE Arbiter,
00416 IN PLIST_ENTRY ArbitrationList
00417 );
00418
00419
typedef
00420
NTSTATUS
00421 (*PARBITER_QUERY_CONFLICT)(
00422 IN
PARBITER_INSTANCE Arbiter,
00423 IN
PDEVICE_OBJECT PhysicalDeviceObject,
00424 IN PIO_RESOURCE_DESCRIPTOR ConflictingResource,
00425 OUT PULONG ConflictCount,
00426 OUT
PARBITER_CONFLICT_INFO *Conflicts
00427 );
00428
00429
typedef
00430
NTSTATUS
00431 (*PARBITER_START_ARBITER)(
00432 IN
PARBITER_INSTANCE Arbiter,
00433 IN PCM_RESOURCE_LIST StartResources
00434 );
00435
00436
00437
00438
00439
00440 #define ARBITER_RANGE_BOOT_ALLOCATED 0x01
00441
00442 #define ARBITER_RANGE_ALIAS 0x10
00443 #define ARBITER_RANGE_POSITIVE_DECODE 0x20
00444
00445 #define INITIAL_ALLOCATION_STATE_SIZE PAGE_SIZE
00446
00447 #define ARBITER_INSTANCE_SIGNATURE 'sbrA'
00448
00449
00450 typedef struct _ARBITER_INSTANCE {
00451
00452
00453
00454 ULONG
Signature;
00455
00456
00457
00458
00459 PKEVENT MutexEvent;
00460
00461
00462
00463
00464 PWSTR
Name;
00465
00466
00467
00468
00469 CM_RESOURCE_TYPE
ResourceType;
00470
00471
00472
00473
00474
00475 PRTL_RANGE_LIST
Allocation;
00476
00477
00478
00479
00480
00481 PRTL_RANGE_LIST
PossibleAllocation;
00482
00483
00484
00485
00486
00487
00488 ARBITER_ORDERING_LIST OrderingList;
00489
00490
00491
00492
00493
00494 ARBITER_ORDERING_LIST ReservedList;
00495
00496
00497
00498
00499
00500 LONG
ReferenceCount;
00501
00502
00503
00504
00505 PARBITER_INTERFACE Interface;
00506
00507
00508
00509
00510 ULONG
AllocationStackMaxSize;
00511
00512
00513
00514
00515
00516 PARBITER_ALLOCATION_STATE AllocationStack;
00517
00518
00519
00520
00521
00522
00523
00524 PARBITER_UNPACK_REQUIREMENT UnpackRequirement;
00525 PARBITER_PACK_RESOURCE PackResource;
00526 PARBITER_UNPACK_RESOURCE UnpackResource;
00527 PARBITER_SCORE_REQUIREMENT ScoreRequirement;
00528
00529
00530
00531
00532
00533 PARBITER_TEST_ALLOCATION TestAllocation; OPTIONAL
00534 PARBITER_RETEST_ALLOCATION RetestAllocation; OPTIONAL
00535 PARBITER_COMMIT_ALLOCATION CommitAllocation; OPTIONAL
00536 PARBITER_ROLLBACK_ALLOCATION RollbackAllocation; OPTIONAL
00537 PARBITER_BOOT_ALLOCATION BootAllocation; OPTIONAL
00538 PARBITER_QUERY_ARBITRATE QueryArbitrate; OPTIONAL
00539 PARBITER_QUERY_CONFLICT QueryConflict; OPTIONAL
00540 PARBITER_ADD_RESERVED AddReserved; OPTIONAL
00541 PARBITER_START_ARBITER StartArbiter; OPTIONAL
00542
00543
00544
00545 PARBITER_PREPROCESS_ENTRY PreprocessEntry; OPTIONAL
00546 PARBITER_ALLOCATE_ENTRY AllocateEntry; OPTIONAL
00547 PARBITER_GET_NEXT_ALLOCATION_RANGE GetNextAllocationRange; OPTIONAL
00548 PARBITER_FIND_SUITABLE_RANGE FindSuitableRange; OPTIONAL
00549 PARBITER_ADD_ALLOCATION AddAllocation; OPTIONAL
00550 PARBITER_BACKTRACK_ALLOCATION BacktrackAllocation; OPTIONAL
00551 PARBITER_OVERRIDE_CONFLICT OverrideConflict; OPTIONAL
00552
00553
00554
00555
00556 BOOLEAN
TransactionInProgress;
00557
00558
00559
00560
00561
00562 PVOID
Extension;
00563
00564
00565
00566
00567 PDEVICE_OBJECT BusDeviceObject;
00568
00569
00570
00571
00572
00573 PVOID
ConflictCallbackContext;
00574 PRTL_CONFLICT_RANGE_CALLBACK
ConflictCallback;
00575
00576 }
ARBITER_INSTANCE, *
PARBITER_INSTANCE;
00577
00578
00579
00580
00581
00582
00583
00584
00585 #define ArbAcquireArbiterLock(_Arbiter) \
00586
KeWaitForSingleObject( (_Arbiter)->MutexEvent, Executive, KernelMode, FALSE, NULL )
00587
00588 #define ArbReleaseArbiterLock(_Arbiter) \
00589
KeSetEvent( (_Arbiter)->MutexEvent, 0, FALSE )
00590
00591
00592
00593
00594
00595
00596
00597
00598
00599
00600
00601
00602 #define FOR_ALL_IN_LIST(Type, Head, Current) \
00603
for((Current) = CONTAINING_RECORD((Head)->Flink, Type, ListEntry); \
00604
(Head) != &(Current)->ListEntry; \
00605
(Current) = CONTAINING_RECORD((Current)->ListEntry.Flink, \
00606
Type, \
00607
ListEntry) \
00608
)
00609
00610
00611
00612 #define FOR_ALL_IN_ARRAY(_Array, _Size, _Current) \
00613
for ( (_Current) = (_Array); \
00614
(_Current) < (_Array) + (_Size); \
00615
(_Current)++ )
00616
00617
00618
00619
00620 #define FOR_REST_IN_ARRAY(_Array, _Size, _Current) \
00621
for ( ; \
00622
(_Current) < (_Array) + (_Size); \
00623
(_Current)++ )
00624
00625
00626
00627
00628
00629
00630
00631
00632
00633
00634
00635
00636 #define INTERSECT(s1,e1,s2,e2) \
00637
!( ((s1) < (s2) && (e1) < (s2)) \
00638
||((s2) < (s1) && (e2) < (s1)) )
00639
00640
00641
00642
00643
00644
00645
00646
00647
00648
00649
00650
00651
00652
00653 #define INTERSECT_SIZE(s1,e1,s2,e2) \
00654
( __min((e1),(e2)) - __max((s1),(s2)) + 1)
00655
00656
00657 #define LEGACY_REQUEST(_Entry) \
00658
((_Entry)->RequestSource == ArbiterRequestLegacyReported || \
00659
(_Entry)->RequestSource == ArbiterRequestLegacyAssigned)
00660
00661 #define PNP_REQUEST(_Entry) \
00662
((_Entry)->RequestSource == ArbiterRequestPnpDetected || \
00663
(_Entry)->RequestSource == ArbiterRequestPnpEnumerated)
00664
00665
00666
00667
00668
00669 #define ARBITER_PRIORITY_NULL 0
00670 #define ARBITER_PRIORITY_PREFERRED_RESERVED (MAXLONG-2)
00671 #define ARBITER_PRIORITY_RESERVED (MAXLONG-1)
00672 #define ARBITER_PRIORITY_EXHAUSTED (MAXLONG)
00673
00674
00675
typedef
00676
NTSTATUS
00677 (*PARBITER_TRANSLATE_ALLOCATION_ORDER)(
00678 OUT PIO_RESOURCE_DESCRIPTOR TranslatedDescriptor,
00679 IN PIO_RESOURCE_DESCRIPTOR RawDescriptor
00680 );
00681
00682
00683
00684
00685
00686
NTSTATUS
00687
ArbInitializeArbiterInstance(
00688 OUT PARBITER_INSTANCE Arbiter,
00689 IN
PDEVICE_OBJECT BusDevice,
00690 IN CM_RESOURCE_TYPE ResourceType,
00691 IN PWSTR Name,
00692 IN PWSTR OrderingName,
00693 IN PARBITER_TRANSLATE_ALLOCATION_ORDER TranslateOrdering
00694 );
00695
00696
VOID
00697
ArbDeleteArbiterInstance(
00698 IN PARBITER_INSTANCE Arbiter
00699 );
00700
00701
NTSTATUS
00702
ArbArbiterHandler(
00703 IN PVOID Context,
00704 IN ARBITER_ACTION Action,
00705 IN OUT
PARBITER_PARAMETERS Params
00706 );
00707
00708
NTSTATUS
00709
ArbTestAllocation(
00710 IN PARBITER_INSTANCE Arbiter,
00711 IN OUT PLIST_ENTRY ArbitrationList
00712 );
00713
00714
NTSTATUS
00715
ArbRetestAllocation(
00716 IN PARBITER_INSTANCE Arbiter,
00717 IN OUT PLIST_ENTRY ArbitrationList
00718 );
00719
00720
NTSTATUS
00721
ArbCommitAllocation(
00722 PARBITER_INSTANCE Arbiter
00723 );
00724
00725
NTSTATUS
00726
ArbRollbackAllocation(
00727 PARBITER_INSTANCE Arbiter
00728 );
00729
00730
NTSTATUS
00731
ArbAddReserved(
00732 IN PARBITER_INSTANCE Arbiter,
00733 IN PIO_RESOURCE_DESCRIPTOR Requirement OPTIONAL,
00734 IN PCM_PARTIAL_RESOURCE_DESCRIPTOR Resource OPTIONAL
00735 );
00736
00737
NTSTATUS
00738
ArbPreprocessEntry(
00739 IN PARBITER_INSTANCE Arbiter,
00740 IN PARBITER_ALLOCATION_STATE State
00741 );
00742
00743
NTSTATUS
00744
ArbAllocateEntry(
00745 IN PARBITER_INSTANCE Arbiter,
00746 IN PARBITER_ALLOCATION_STATE State
00747 );
00748
00749
NTSTATUS
00750
ArbSortArbitrationList(
00751 IN OUT PLIST_ENTRY ArbitrationList
00752 );
00753
00754
VOID
00755
ArbConfirmAllocation(
00756 IN PARBITER_INSTANCE Arbiter,
00757 IN PARBITER_ALLOCATION_STATE State
00758 );
00759
00760 BOOLEAN
00761
ArbOverrideConflict(
00762 IN PARBITER_INSTANCE Arbiter,
00763 IN PARBITER_ALLOCATION_STATE State
00764 );
00765
00766
00767
NTSTATUS
00768
ArbQueryConflict(
00769 IN PARBITER_INSTANCE Arbiter,
00770 IN
PDEVICE_OBJECT PhysicalDeviceObject,
00771 IN PIO_RESOURCE_DESCRIPTOR ConflictingResource,
00772 OUT PULONG ConflictCount,
00773 OUT
PARBITER_CONFLICT_INFO *Conflicts
00774 );
00775
00776
VOID
00777
ArbBacktrackAllocation(
00778 IN PARBITER_INSTANCE Arbiter,
00779 IN PARBITER_ALLOCATION_STATE State
00780 );
00781
00782 BOOLEAN
00783
ArbGetNextAllocationRange(
00784 PARBITER_INSTANCE Arbiter,
00785 PARBITER_ALLOCATION_STATE State
00786 );
00787
00788 BOOLEAN
00789
ArbFindSuitableRange(
00790 PARBITER_INSTANCE Arbiter,
00791 PARBITER_ALLOCATION_STATE State
00792 );
00793
00794
VOID
00795
ArbAddAllocation(
00796 IN PARBITER_INSTANCE Arbiter,
00797 IN PARBITER_ALLOCATION_STATE State
00798 );
00799
00800
NTSTATUS
00801
ArbBootAllocation(
00802 IN PARBITER_INSTANCE Arbiter,
00803 IN OUT PLIST_ENTRY ArbitrationList
00804 );
00805
00806
NTSTATUS
00807
ArbStartArbiter(
00808 IN PARBITER_INSTANCE Arbiter,
00809 IN PCM_RESOURCE_LIST StartResources
00810 );
00811
00812
NTSTATUS
00813
ArbBuildAssignmentOrdering(
00814 IN OUT PARBITER_INSTANCE Arbiter,
00815 IN PWSTR AllocationOrderName,
00816 IN PWSTR ReservedResourcesName,
00817 IN PARBITER_TRANSLATE_ALLOCATION_ORDER Translate OPTIONAL
00818 );
00819
00820
00821
#if ARB_DBG
00822
00823
VOID
00824
ArbpIndent(
00825 ULONG Count
00826 );
00827
00828
#endif // DBG
00829
00830
00831
#endif
00832
00833