00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
#include "iop.h"
00027
00028 #define IDBG DBG
00029 #define PAGED 1
00030 #define INLINE __inline
00031 #define STATIC static
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049 extern WCHAR
IopWstrOtherDrivers[];
00050 extern WCHAR
IopWstrAssignedResources[];
00051 extern WCHAR
IopWstrRequestedResources[];
00052 extern WCHAR
IopWstrSystemResources[];
00053 extern WCHAR
IopWstrReservedResources[];
00054 extern WCHAR
IopWstrAssignmentOrdering[];
00055 extern WCHAR
IopWstrBusValues[];
00056 extern WCHAR
IopWstrTranslated[];
00057 extern WCHAR
IopWstrBusTranslated[];
00058
00059 #define HRESOURCE_MAP 0
00060 #define HDEVICE_STORAGE 1
00061 #define HCURRENT_CONTROL_SET 2
00062 #define HSYSTEMRESOURCES 3
00063 #define HORDERING 4
00064 #define HRESERVEDRESOURCES 5
00065 #define HBUSVALUES 6
00066 #define HOWNER_MAP 7
00067 #define MAX_REG_HANDLES 8
00068
00069 #define INVALID_HANDLE (HANDLE) -1
00070
00071 #define BUFFERSIZE (2048 + sizeof( KEY_FULL_INFORMATION ))
00072 #define MAX_ENTRIES 50
00073 #define SCONFLICT 5
00074
00075
00076
00077
00078
00079
00080 typedef struct {
00081 LIST_ENTRY InConflict;
00082 UNICODE_STRING
KeyName;
00083 UNICODE_STRING DeviceName;
00084 WCHAR UnicodeBuffer[1];
00085 } *
POWNER;
00086
00087
00088 typedef struct {
00089 LONGLONG BAddr;
00090 LONGLONG EAddr;
00091 KAFFINITY Affinity;
00092 POWNER Owner;
00093
#if IDBG
00094
ULONG na[2];
00095
#endif
00096
}
TENTRY, *
PTENTRY;
00097
00098 #define DoesTEntryCollide(a,b) \
00099
( (a).EAddr >= (b).BAddr && (a).BAddr <= (b).EAddr && ((a).Affinity & (b).Affinity) )
00100
00101
00102
00103 typedef struct _LTENTRY {
00104 struct _LTENTRY *
Next;
00105 ULONG
CurEntries;
00106 ULONG
na[2];
00107 TENTRY Table[
MAX_ENTRIES];
00108 }
LTENTRY, *
PLTENTRY;
00109
00110
00111 typedef struct {
00112 PLTENTRY ByType[CmResourceTypeMaximum];
00113 }
TENTRIESBYTYPE, *
PTENTRIESBYTYPE;
00114
00115
00116 typedef struct {
00117 ULONG NoConflicts;
00118
struct {
00119 UCHAR Type;
00120 LONGLONG BAddr;
00121 POWNER Owner;
00122 } EasyConflict[
SCONFLICT];
00123
00124 LIST_ENTRY OtherConflicts;
00125 }
IO_TRACK_CONFLICT, *
PIO_TRACK_CONFLICT;
00126
00127
00128 typedef struct {
00129
00130 ULONG CurLoc;
00131 ULONG RunLen;
00132 ULONG PassNo;
00133
00134
00135 ULONG CurBusLoc;
00136 LONGLONG CurBusMin;
00137 LONGLONG CurBusMax;
00138
00139
00140 UCHAR Type;
00141 ULONG CurBLoc;
00142 LONGLONG CurBAddr;
00143
00144
00145 UCHAR TType;
00146 TENTRY Trans;
00147
00148 LONG BestPref;
00149 LONG CurPref;
00150
00151
00152 ULONG PrefCnt;
00153 ULONG Pass2HoldCurLoc;
00154 LONGLONG Pass2HoldBAddr;
00155
00156
00157 ULONG NoAlternatives;
00158 PIO_RESOURCE_DESCRIPTOR IoResourceDescriptor[1];
00159 }
DIR_REQUIRED_RESOURCE, *
PDIR_REQUIRED_RESOURCE;
00160
00161
00162 typedef struct _DIR_RESOURCE_LIST {
00163 struct _DIR_RESOURCE_LIST *
Next;
00164 PDIR_REQUIRED_RESOURCE ResourceByType[CmResourceTypeMaximum];
00165 LONG
CurPref;
00166 ULONG
LastLevel;
00167 ULONG
FailedLevel;
00168 IO_TRACK_CONFLICT Conflict;
00169 PIO_RESOURCE_LIST
IoResourceList;
00170 ULONG
NoRequiredResources;
00171 PDIR_REQUIRED_RESOURCE RequiredResource[1];
00172 }
DIR_RESOURCE_LIST, *
PDIR_RESOURCE_LIST;
00173
00174
00175 typedef struct _DIR_RESREQ_LIST {
00176 HANDLE
RegHandle[
MAX_REG_HANDLES];
00177 struct _DIR_RESREQ_LIST *
UserDir;
00178 struct _DIR_RESREQ_LIST *
BusDir;
00179 struct _DIR_RESREQ_LIST *
FreeResReqList;
00180 SINGLE_LIST_ENTRY
AllocatedHeap;
00181 TENTRIESBYTYPE InUseResources;
00182 TENTRIESBYTYPE InUseSharableResources;
00183 TENTRIESBYTYPE ReservedSharableResources;
00184 PIO_RESOURCE_REQUIREMENTS_LIST
IoResourceReq;
00185 PDIR_RESOURCE_LIST Alternative;
00186 PWCHAR
Buffer;
00187 }
DIR_RESREQ_LIST, *
PDIR_RESREQ_LIST;
00188
00189
00190 typedef struct {
00191 SINGLE_LIST_ENTRY FreeLink;
00192 PVOID FreeHeap;
00193 }
USED_HEAP, *
PUSED_HEAP;
00194
00195
00196
00197
00198
00199 PIO_RESOURCE_REQUIREMENTS_LIST
00200
IopGetResourceReqRegistryValue (
00201 IN PDIR_RESREQ_LIST Dir,
00202 IN HANDLE KeyHandle,
00203 IN PWSTR ValueName
00204 );
00205
00206
NTSTATUS
00207
IopAssignResourcesPhase1 (
00208 IN PIO_RESOURCE_REQUIREMENTS_LIST IoResources,
00209 IN PIO_RESOURCE_REQUIREMENTS_LIST *CopiedList
00210 );
00211
00212
NTSTATUS
00213
IopAssignResourcesPhase2 (
00214 IN PDIR_RESREQ_LIST Dir,
00215 IN PUNICODE_STRING DriverClassName,
00216 IN
PDRIVER_OBJECT DriverObject,
00217 IN
PDEVICE_OBJECT DeviceObject
00218 );
00219
00220
PDIR_RESOURCE_LIST
00221
IopAssignResourcesPhase3 (
00222 IN PDIR_RESREQ_LIST Dir
00223 );
00224
00225 PCM_RESOURCE_LIST
00226
IopAssignResourcesPhase4 (
00227 IN PDIR_RESREQ_LIST Dir,
00228 IN PDIR_RESOURCE_LIST CurList,
00229 OUT PULONG Length
00230 );
00231
00232
STATIC VOID
00233
IopLogConflict (
00234 IN
PDRIVER_OBJECT DriverObject,
00235 IN PDIR_RESREQ_LIST Dir,
00236 IN NTSTATUS FinalStatus
00237 );
00238
00239
STATIC PVOID
00240
IopAllocateDirPool (
00241 IN PDIR_RESREQ_LIST Dir,
00242 IN ULONG Length
00243 );
00244
00245
INLINE PTENTRY
00246
IopNewTransEntry (
00247 IN PDIR_RESREQ_LIST Dir,
00248 IN PTENTRIESBYTYPE pTypes,
00249 IN ULONG Type
00250 );
00251
00252
STATIC NTSTATUS
00253
IopAddCmDescriptorToInUseList (
00254 IN PDIR_RESREQ_LIST Dir,
00255 IN PTENTRIESBYTYPE pTypes,
00256 IN PCM_PARTIAL_RESOURCE_DESCRIPTOR CmDesc,
00257 IN
POWNER Owner
00258 );
00259
00260 ULONG
00261
IopFindCollisionInTList (
00262 IN PTENTRY SEntry,
00263 IN PLTENTRY List
00264 );
00265
00266
VOID
00267
IopPickupCollisionInTList (
00268 IN PDIR_RESOURCE_LIST CurList,
00269 IN UCHAR Type,
00270 IN LONGLONG BAddr,
00271 IN PTENTRY SEntry,
00272 IN PLTENTRY List
00273 );
00274
00275
NTSTATUS
00276
IopBuildResourceDir (
00277 IN PDIR_RESREQ_LIST ParentDir,
00278 IN PDIR_RESREQ_LIST *DirResourceList,
00279 IN PIO_RESOURCE_REQUIREMENTS_LIST IoResources
00280 );
00281
00282
VOID
00283
IopFreeResourceDir (
00284 IN PDIR_RESREQ_LIST DirResourceList
00285 );
00286
00287
VOID
00288
IopSortDescriptors (
00289 IN OUT PDIR_RESREQ_LIST Dir
00290 );
00291
00292
NTSTATUS
00293
IopCatagorizeDescriptors (
00294 IN OUT PDIR_RESREQ_LIST Dir
00295 );
00296
00297 ULONG
00298
IopDescriptorSortingWeight (
00299 IN PIO_RESOURCE_DESCRIPTOR Descriptor
00300 );
00301
00302 BOOLEAN
00303
IopGenNextValidResourceList (
00304 IN ULONG level,
00305 IN PDIR_RESOURCE_LIST CurList,
00306 IN PDIR_RESREQ_LIST Dir
00307 );
00308
00309 BOOLEAN
00310
IopGenNextValidDescriptor (
00311 IN ULONG level,
00312 IN PDIR_RESOURCE_LIST CurList,
00313 IN PDIR_RESREQ_LIST Dir,
00314 IN PULONG collisionlevel
00315 );
00316
00317 BOOLEAN
00318
IopSlotResourceOwner (
00319 IN PDIR_RESREQ_LIST Dir,
00320 IN
PDRIVER_OBJECT DriverObject,
00321 IN
PDEVICE_OBJECT DeviceObject OPTIONAL,
00322 IN PIO_RESOURCE_REQUIREMENTS_LIST IoResources,
00323 IN BOOLEAN AddOwner
00324 );
00325
00326
#if IDBG
00327
VOID
00328 IopDumpIoResourceDir (
00329 IN PDIR_RESREQ_LIST Dir
00330 );
00331
00332
VOID
00333 IopDumpIoResourceDescriptor (
00334 IN PUCHAR Indent,
00335 IN PIO_RESOURCE_DESCRIPTOR Desc
00336 );
00337
#endif
00338
00339
#if DBG
00340
#define CHECK_STATUS(a,b) { if(!NT_SUCCESS(a)) { DebugString = b; goto Exit; } }
00341
#else
00342 #define CHECK_STATUS(a,b) { if(!NT_SUCCESS(a)) goto Exit; }
00343
#endif
00344
00345
#if DBG
00346
#define DBGMSG(a) DbgPrint(a)
00347
#else
00348 #define DBGMSG(a)
00349
#endif
00350
00351
#if IDBG
00352
#define IDBGMSG(a) DbgPrint(a)
00353
#else
00354 #define IDBGMSG(a)
00355
#endif
00356
00357
#ifdef PAGED
00358
#ifdef ALLOC_PRAGMA
00359
00360
#pragma alloc_text(PAGE,IoAssignResources)
00361
#pragma alloc_text(PAGE,IopAssignResourcesPhase1)
00362
#pragma alloc_text(PAGE,IopAssignResourcesPhase2)
00363
#pragma alloc_text(PAGE,IopAssignResourcesPhase3)
00364
#pragma alloc_text(PAGE,IopAssignResourcesPhase4)
00365
#pragma alloc_text(PAGE,IopLogConflict)
00366
#pragma alloc_text(PAGE,IopGenNextValidResourceList)
00367
#pragma alloc_text(PAGE,IopGenNextValidDescriptor)
00368
#pragma alloc_text(PAGE,IopFindCollisionInTList)
00369
#pragma alloc_text(PAGE,IopPickupCollisionInTList)
00370
#pragma alloc_text(PAGE,IopAllocateDirPool)
00371
#pragma alloc_text(PAGE,IopGetResourceReqRegistryValue)
00372
#pragma alloc_text(PAGE,IopBuildResourceDir)
00373
#pragma alloc_text(PAGE,IopFreeResourceDir)
00374
#pragma alloc_text(PAGE,IopCatagorizeDescriptors)
00375
#pragma alloc_text(PAGE,IopSortDescriptors)
00376
#pragma alloc_text(PAGE,IopAddCmDescriptorToInUseList)
00377
#pragma alloc_text(PAGE,IopSlotResourceOwner)
00378
#if IDBG
00379
#pragma alloc_text(PAGE,IopDumpIoResourceDir)
00380
#pragma alloc_text(PAGE,IopDumpIoResourceDescriptor)
00381
#endif
00382
00383
#ifndef INLINE
00384
#pragma alloc_text(PAGE,IO_DESC_MIN)
00385
#pragma alloc_text(PAGE,IO_DESC_MAX)
00386
#pragma alloc_text(PAGE,IopDescriptorSortingWeight)
00387
#pragma alloc_text(PAGE,IopNewTransEntry)
00388
#endif // INLINE
00389
00390
#endif // ALLOC_PRAGMA
00391
#endif // PAGED
00392
00393
NTSTATUS
00394 IoAssignResources (
00395 IN PUNICODE_STRING RegistryPath,
00396 IN PUNICODE_STRING DriverClassName OPTIONAL,
00397 IN
PDRIVER_OBJECT DriverObject,
00398 IN
PDEVICE_OBJECT DeviceObject OPTIONAL,
00399 IN PIO_RESOURCE_REQUIREMENTS_LIST RequestedResources,
00400 IN OUT PCM_RESOURCE_LIST *pAllocatedResources
00401 )
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465 {
00466
if (DeviceObject) {
00467
00468
if ( DeviceObject->DeviceObjectExtension->DeviceNode &&
00469 !(((
PDEVICE_NODE)DeviceObject->DeviceObjectExtension->DeviceNode)->Flags &
DNF_LEGACY_RESOURCE_DEVICENODE)) {
00470
00471
KeBugCheckEx(PNP_DETECTED_FATAL_ERROR,
PNP_ERR_INVALID_PDO, (ULONG_PTR)DeviceObject, 0, 0);
00472
00473 }
00474
00475 }
00476
00477
if (RequestedResources) {
00478
00479
if (RequestedResources->AlternativeLists == 0 ||
00480 RequestedResources->List[0].Count == 0) {
00481
00482 RequestedResources =
NULL;
00483
00484 }
00485 }
00486
00487
if (pAllocatedResources) {
00488
00489 *pAllocatedResources =
NULL;
00490
00491 }
00492
00493
return IopLegacyResourceAllocation (
ArbiterRequestLegacyAssigned,
00494 DriverObject,
00495 DeviceObject,
00496 RequestedResources,
00497 pAllocatedResources);
00498 }
00499
#if 0
00500
BOOLEAN
00501
IopSlotResourceOwner (
00502 IN PDIR_RESREQ_LIST Dir,
00503 IN
PDRIVER_OBJECT DriverObject,
00504 IN
PDEVICE_OBJECT DeviceObject OPTIONAL,
00505 IN PIO_RESOURCE_REQUIREMENTS_LIST IoResources,
00506 IN BOOLEAN AddOwner
00507 )
00508 {
00509 ULONG busflags, len, i;
00510 PWCHAR
KeyName;
00511 UNICODE_STRING KeyString, ValueString;
00512 POBJECT_NAME_INFORMATION ObjectName;
00513 PKEY_VALUE_PARTIAL_INFORMATION PartInf;
00514 BOOLEAN Match;
00515
NTSTATUS status;
00516
00517
PAGED_CODE();
00518
00519
KeyName =
ExAllocatePool (PagedPool, BUFFERSIZE * 2);
00520
if (!
KeyName) {
00521
return FALSE;
00522 }
00523
00524 ObjectName = (POBJECT_NAME_INFORMATION) ((PCHAR)
KeyName +
BUFFERSIZE);
00525 Match =
TRUE;
00526
00527
00528
00529
00530
00531 status =
IopLookupBusStringFromID (
00532 Dir->RegHandle[HBUSVALUES],
00533 IoResources->InterfaceType,
00534 KeyName,
00535 BUFFERSIZE-40,
00536 &busflags
00537 );
00538
00539
00540
00541
00542
00543
if (
NT_SUCCESS(status) && (busflags & 0x1)) {
00544
00545
00546
00547
00548
00549
for (i=0;
KeyName[i]; i++) ;
00550 swprintf (KeyName+i, L
"_%d_%x", IoResources->BusNumber, IoResources->SlotNumber);
00551
RtlInitUnicodeString( &KeyString, KeyName );
00552
00553
00554
00555
00556
00557 status =
ObQueryNameString(
00558 DeviceObject ? (PVOID) DeviceObject : (PVOID) DriverObject,
00559 ObjectName,
00560 BUFFERSIZE,
00561 &len
00562 );
00563
00564
if (
NT_SUCCESS(status)) {
00565
00566
00567
00568
00569
00570 PartInf = (PKEY_VALUE_PARTIAL_INFORMATION) Dir->Buffer;
00571 status = ZwQueryValueKey (
00572 Dir->RegHandle[HOWNER_MAP],
00573 &KeyString,
00574 KeyValuePartialInformation,
00575 Dir->Buffer,
00576 BUFFERSIZE,
00577 &len
00578 );
00579
00580
if (!
NT_SUCCESS(status)) {
00581
00582
00583
00584
00585
00586
if (AddOwner) {
00587
00588
00589
00590
00591 ZwSetValueKey (
00592 Dir->RegHandle[HOWNER_MAP],
00593 &KeyString,
00594 0L,
00595 REG_SZ,
00596 ObjectName->Name.Buffer,
00597 ObjectName->Name.Length
00598 );
00599 }
00600
00601 }
else {
00602
00603
00604
00605
00606
00607 ValueString.Buffer = (PWCHAR) PartInf->Data;
00608 ValueString.Length = (
USHORT) len - (
USHORT) FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data);
00609 ValueString.MaximumLength = ValueString.Length;
00610
00611 Match =
RtlEqualUnicodeString (&ObjectName->Name, &ValueString, TRUE);
00612
if (Match && !AddOwner) {
00613
00614
00615
00616
00617
00618 ZwDeleteValueKey( Dir->RegHandle[HOWNER_MAP], &KeyString);
00619 }
00620 }
00621 }
00622 }
00623
00624
ExFreePool (KeyName);
00625
return Match;
00626 }
00627
00628
00629
00630
00631
00632
00633
00634
00635
00636
00637
INLINE LONGLONG
00638 IO_DESC_MIN (
00639 IN PIO_RESOURCE_DESCRIPTOR Desc
00640 )
00641 {
00642 LONGLONG li;
00643
00644
switch (Desc->Type) {
00645
case CmResourceTypePort:
00646 li = Desc->u.Port.MinimumAddress.QuadPart;
00647
break;
00648
00649
case CmResourceTypeMemory:
00650 li = Desc->u.Memory.MinimumAddress.QuadPart;
00651
break;
00652
00653
case CmResourceTypeInterrupt:
00654 li = Desc->u.Interrupt.MinimumVector;
00655
break;
00656
00657
case CmResourceTypeDma:
00658 li = Desc->u.Dma.MinimumChannel;
00659
break;
00660 }
00661
00662
return li;
00663 }
00664
00665
INLINE LONGLONG
00666 IO_DESC_MAX (
00667 IN PIO_RESOURCE_DESCRIPTOR Desc
00668 )
00669
00670
00671
00672
00673
00674
00675
00676 {
00677 LONGLONG li;
00678
00679
switch (Desc->Type) {
00680
case CmResourceTypePort:
00681 li = Desc->u.Port.MaximumAddress.QuadPart;
00682
break;
00683
00684
case CmResourceTypeMemory:
00685 li = Desc->u.Memory.MaximumAddress.QuadPart;
00686
break;
00687
00688
case CmResourceTypeInterrupt:
00689 li = Desc->u.Interrupt.MaximumVector;
00690
break;
00691
00692
case CmResourceTypeDma:
00693 li = Desc->u.Dma.MaximumChannel;
00694
break;
00695 }
00696
00697
return li;
00698 }
00699
00700
00701 BOOLEAN
00702
IopGenNextValidResourceList (
00703 IN ULONG level,
00704 IN PDIR_RESOURCE_LIST CurList,
00705 IN PDIR_RESREQ_LIST Dir
00706 )
00707
00708
00709
00710
00711
00712
00713
00714
00715
00716
00717
00718
00719
00720
00721
00722
00723
00724
00725
00726
00727
00728 {
00729 ULONG collisionlevel;
00730 BOOLEAN flag;
00731
00732
do {
00733
if (level > CurList->LastLevel) {
00734 CurList->LastLevel = level;
00735 }
00736
00737 flag =
IopGenNextValidDescriptor (
00738 level,
00739 CurList,
00740 Dir,
00741 &collisionlevel
00742 );
00743
00744
if (flag ==
FALSE) {
00745
00746
00747
00748
00749
if (level == 0 || collisionlevel == -1) {
00750
00751
00752
00753
00754 CurList->FailedLevel = level;
00755
return FALSE;
00756 }
00757
00758
00759
00760
00761
00762
while (level > collisionlevel) {
00763 CurList->RequiredResource[level]->CurLoc = 0;
00764 CurList->RequiredResource[level]->RunLen = 0;
00765 level--;
00766 }
00767
continue;
00768 }
00769
00770
if (CurList->RequiredResource[level]->PassNo == 1 &&
00771 CurList->RequiredResource[level]->CurPref <
00772 CurList->RequiredResource[level]->BestPref) {
00773
00774
00775
00776
00777
00778
00779
continue;
00780 }
00781
00782
00783
00784
00785
00786 level++;
00787 }
while (level < CurList->NoRequiredResources);
00788
00789
00790
00791
00792
00793
00794
00795 CurList->CurPref = 0;
00796
for (level = 0; level < CurList->NoRequiredResources; level++) {
00797 CurList->CurPref += CurList->RequiredResource[level]->CurPref;
00798 }
00799
00800
00801
00802
00803
00804
return TRUE;
00805 }
00806
00807
00808
00809 BOOLEAN
00810
IopGenNextValidDescriptor (
00811 IN ULONG level,
00812 IN PDIR_RESOURCE_LIST CurList,
00813 IN PDIR_RESREQ_LIST Dir,
00814 OUT PULONG collisionlevel
00815 )
00816
00817
00818
00819
00820
00821
00822
00823
00824
00825
00826
00827
00828 {
00829
PDIR_REQUIRED_RESOURCE Res, CRes;
00830 PIO_RESOURCE_DESCRIPTOR *Desc, DescTmp;
00831 LONGLONG BAddr, EAddr;
00832 LONGLONG NBAddr;
00833 LONGLONG DescMax, MinAddr, LiILen, LiELen, LiTmp;
00834 LONGLONG NAddr, BusMax, BusMin, PBAddr;
00835 ULONG indx, j, k, NBLoc;
00836 ULONG DescLen, Align, len;
00837 BOOLEAN NBSet, flag, flag2;
00838 LONG Preference, NPref;
00839 UCHAR TType, NTType;
00840
TENTRY Trans, NTrans;
00841
00842 Res = CurList->RequiredResource[level];
00843
00844 *collisionlevel = (ULONG) -1;
00845 NBSet =
FALSE;
00846
00847
do {
00848 Desc = &Res->IoResourceDescriptor[Res->CurLoc];
00849
00850
if (!Res->RunLen) {
00851
00852
if (Res->CurLoc >= Res->NoAlternatives) {
00853
00854
00855
00856
return FALSE;
00857 }
00858
00859
00860
00861
00862
00863
00864 Res->Type = Desc[0]->Type;
00865
for (j=Res->CurLoc; j < Res->NoAlternatives; j++) {
00866
if (Res->Type != Res->IoResourceDescriptor[j]->Type) {
00867
break;
00868 }
00869 }
00870
00871 Res->RunLen = j - Res->CurLoc;
00872
if (!Res->RunLen) {
00873
00874
00875
00876
00877
return FALSE;
00878 }
00879
00880
00881
00882
00883
00884 Res->CurBusLoc = 0;
00885
00886 DescTmp = Dir->BusDir->Alternative->ResourceByType[Res->Type]->IoResourceDescriptor[0];
00887
00888
if (!DescTmp) {
00889
00890
00891
00892
00893
return FALSE;
00894 }
00895
00896 Res->CurBusMin = IO_DESC_MIN (DescTmp);
00897 Res->CurBusMax = IO_DESC_MAX (DescTmp);
00898 NAddr = Res->CurBusMax;
00899
00900 }
else {
00901
00902
00903
00904
00905
00906
00907 NAddr = Res->CurBAddr - 1;
00908 }
00909
00910
00911
00912
00913
00914 DescLen = Res->RunLen;
00915 BusMax = Res->CurBusMax;
00916 BusMin = Res->CurBusMin;
00917
00918 NBAddr = 0;
00919
00920
for (; ;) {
00921
00922
00923
00924
00925
00926
00927
for (indx=0; indx < DescLen ; indx++) {
00928
00929
00930
00931
00932
00933 DescTmp = Desc[indx];
00934
switch (DescTmp->Type) {
00935
case CmResourceTypePort:
00936 len = DescTmp->u.Port.Length;
00937 Align = DescTmp->u.Port.Alignment;
00938 MinAddr = DescTmp->u.Port.MinimumAddress.QuadPart;
00939 DescMax = DescTmp->u.Port.MaximumAddress.QuadPart;
00940
break;
00941
00942
case CmResourceTypeMemory:
00943 len = DescTmp->u.Memory.Length;
00944 Align = DescTmp->u.Memory.Alignment;
00945 MinAddr = DescTmp->u.Memory.MinimumAddress.QuadPart;
00946 DescMax = DescTmp->u.Memory.MaximumAddress.QuadPart;
00947
break;
00948
00949
case CmResourceTypeInterrupt:
00950 len = 1;
00951 Align = 1;
00952 MinAddr = DescTmp->u.Interrupt.MinimumVector;
00953 DescMax = DescTmp->u.Interrupt.MaximumVector;
00954
break;
00955
00956
case CmResourceTypeDma:
00957 len = 1;
00958 Align = 1;
00959 MinAddr = DescTmp->u.Dma.MinimumChannel;
00960 DescMax = DescTmp->u.Dma.MaximumChannel;
00961
break;
00962
00963 }
00964
00965
00966
00967
00968
00969
00970
00971
if (BusMin > MinAddr) {
00972 MinAddr = BusMin;
00973 }
00974
00975
if (NBAddr > MinAddr) {
00976 MinAddr = NBAddr;
00977 }
00978
00979 BAddr = NAddr;
00980 LiELen = len;
00981 LiILen = len - 1;
00982
00983
00984
00985
00986
00987 Preference = 0;
00988
if (Res->PassNo == 1) {
00989
if (DescTmp->Option & IO_RESOURCE_PREFERRED) {
00990
00991 Preference = 1;
00992
00993 }
else if (Res->BestPref) {
00994
00995
00996
continue;
00997 }
00998 }
00999
01000
01001
01002
01003
01004
01005
while (BAddr >= MinAddr) {
01006
01007 EAddr = BAddr + LiILen;
01008
if (EAddr > DescMax) {
01009
01010
01011
01012
01013
01014 BAddr = DescMax - LiILen;
01015
continue;
01016 }
01017
01018
if (EAddr > BusMax) {
01019
01020
01021
01022
01023
01024 BAddr = BusMax - LiILen;
01025
continue;
01026 }
01027
01028
01029
01030
01031
01032
01033
if (Dir->UserDir) {
01034 CRes = Dir->UserDir->Alternative->ResourceByType[Res->Type];
01035 flag =
FALSE;
01036 PBAddr = -1;
01037
01038
for (j=0; j < CRes->NoAlternatives; j++) {
01039 LiTmp = IO_DESC_MIN (CRes->IoResourceDescriptor[j]);
01040
01041
if (BAddr < LiTmp) {
01042
01043
01044
01045
01046
01047
continue;
01048 }
01049
01050 LiTmp = IO_DESC_MAX (CRes->IoResourceDescriptor[j]);
01051
if (EAddr > LiTmp) {
01052
01053
01054
01055
01056
01057
01058 LiTmp = LiTmp - LiILen;
01059
if (LiTmp > PBAddr && LiTmp < BAddr) {
01060
01061
01062
01063
01064
01065 PBAddr = LiTmp;
01066 }
01067
continue;
01068 }
01069
01070
01071
01072
01073
01074 flag =
TRUE;
01075
break;
01076 }
01077
01078
if (!flag) {
01079 BAddr = PBAddr;
01080
continue;
01081 }
01082 }
01083
01084
01085
01086
01087
01088
01089 LiTmp = 0;
01090
switch (Res->Type) {
01091
case CmResourceTypePort:
01092
case CmResourceTypeMemory:
01093 j = k = Res->Type == CmResourceTypePort ? 1 : 0;
01094 flag =
HalTranslateBusAddress (
01095 Dir->IoResourceReq->InterfaceType,
01096 Dir->IoResourceReq->BusNumber,
01097 *((PPHYSICAL_ADDRESS) &BAddr),
01098 &j,
01099 (PPHYSICAL_ADDRESS) &Trans.
BAddr
01100 );
01101
01102
01103
if (Align > 1 && (Trans.
BAddr & 0xffffffff00000000) == 0) {
01104 RtlEnlargedUnsignedDivide (
01105 *((PULARGE_INTEGER) &Trans.
BAddr), Align, (PULONG) &LiTmp);
01106
01107
if (LiTmp & 0xffffffff) {
01108
break;
01109 }
01110 }
01111
01112 flag2 =
HalTranslateBusAddress (
01113 Dir->IoResourceReq->InterfaceType,
01114 Dir->IoResourceReq->BusNumber,
01115 *((PPHYSICAL_ADDRESS) &EAddr),
01116 &k,
01117 (PPHYSICAL_ADDRESS) &Trans.
EAddr
01118 );
01119
01120 TType = j == 1 ? CmResourceTypePort : CmResourceTypeMemory;
01121 Trans.
Affinity = (KAFFINITY) -1;
01122
01123
if (flag ==
FALSE || flag2 ==
FALSE || j != k) {
01124
01125
01126
01127
01128
DBGMSG (
"IopGenNextValidDescriptor: Error return for HalTranslateBusAddress\n");
01129
return FALSE;
01130 }
01131
break;
01132
01133
case CmResourceTypeInterrupt:
01134 TType = CmResourceTypeInterrupt;
01135
01136 Trans.
Affinity = 0;
01137 Trans.
BAddr =
HalGetInterruptVector (
01138 Dir->IoResourceReq->InterfaceType,
01139 Dir->IoResourceReq->BusNumber,
01140 (ULONG) BAddr,
01141 (ULONG) BAddr,
01142 (PKIRQL) &j,
01143 &Trans.
Affinity
01144 );
01145
01146 Trans.
EAddr = Trans.
BAddr;
01147
01148
if (Trans.
Affinity == 0) {
01149
01150 LiTmp = 1;
01151 }
01152
break;
01153
01154
case CmResourceTypeDma:
01155 TType = CmResourceTypeDma;
01156 Trans.
BAddr = BAddr;
01157 Trans.
EAddr = EAddr;
01158 Trans.
Affinity = (KAFFINITY) -1;
01159
break;
01160
01161
default:
01162
DBGMSG (
"IopGenNextValidDescriptor: Invalid resource type\n");
01163
return FALSE;
01164 }
01165
01166
01167
01168
01169
01170
if (LiTmp != 0) {
01171
01172
01173 BAddr = BAddr - LiTmp;
01174
continue;
01175 }
01176
01177
01178
01179
01180
01181
if (Align > 1) {
01182
if ((Trans.
BAddr & 0xffffffff00000000) == 0) {
01183 RtlEnlargedUnsignedDivide (
01184 *((PULARGE_INTEGER) &Trans.
BAddr), Align, (PULONG) &LiTmp);
01185 }
else {
01186
RtlExtendedLargeIntegerDivide (
01187 *((PLARGE_INTEGER) &Trans.
BAddr), Align, (PULONG) &LiTmp);
01188
01189 }
01190
01191
if (LiTmp != 0) {
01192
01193
01194
01195
01196
01197 BAddr = BAddr - LiTmp;
01198
continue;
01199 }
01200 }
01201
01202
01203
01204
01205
01206
for (j=0; j < level; j++) {
01207
if (CurList->RequiredResource[j]->TType == TType) {
01208 CRes = CurList->RequiredResource[j];
01209
if (
DoesTEntryCollide (Trans, CRes->Trans)) {
01210
01211
break;
01212 }
01213 }
01214 }
01215
01216
if (j < level) {
01217
01218
01219
01220
01221
if (j < *collisionlevel) {
01222
01223
01224
01225
01226
01227 *collisionlevel = j;
01228 }
01229
01230
01231
01232
01233
01234 BAddr = CRes->CurBAddr - LiELen;
01235
continue;
01236 }
01237
01238
01239
01240
01241
01242 j =
IopFindCollisionInTList (&Trans, Dir->InUseResources.ByType[TType]);
01243
if (j) {
01244
if (Res->PassNo == 3) {
01245
01246
01247
01248
01249
IopPickupCollisionInTList (
01250 CurList,
01251 Res->Type,
01252 BAddr,
01253 &Trans,
01254 Dir->InUseResources.ByType[TType]
01255 );
01256 }
01257
01258
01259
01260
01261
01262
01263 BAddr = BAddr - j;
01264
continue;
01265 }
01266
01267
01268
01269
01270
01271 j =
IopFindCollisionInTList (&Trans, Dir->InUseSharableResources.ByType[TType]);
01272
if (j) {
01273
01274
01275
01276
01277
01278
01279
if (Res->PassNo == 1 || Desc[indx]->ShareDisposition != CmResourceShareShared) {
01280
if (Res->PassNo == 3) {
01281
01282
01283
01284
01285
IopPickupCollisionInTList (
01286 CurList,
01287 Res->Type,
01288 BAddr,
01289 &Trans,
01290 Dir->InUseSharableResources.ByType[TType]
01291 );
01292 }
01293
01294
01295
01296
01297 BAddr = BAddr - j;
01298
continue;
01299 }
01300
01301 Preference -= 4;
01302 }
01303
01304
01305
01306
01307
01308 j =
IopFindCollisionInTList (&Trans, Dir->ReservedSharableResources.ByType[TType]);
01309
if (j) {
01310
01311
01312
01313
01314
01315
01316
if (Res->PassNo == 1) {
01317
01318
01319 BAddr = BAddr - j;
01320
continue;
01321 }
01322
01323 Preference -= 2;
01324 }
01325
01326
01327
01328
01329
01330
01331 NBSet =
TRUE;
01332 NBAddr = BAddr;
01333
01334 NTType = TType;
01335 NTrans = Trans;
01336 NPref = Preference;
01337 NBLoc = Res->CurLoc + indx;
01338
break;
01339
01340 }
01341 }
01342
01343
if (NBSet) {
01344
01345
break;
01346 }
01347
01348
01349
01350
01351
01352 Res->CurBusLoc++;
01353 CRes = Dir->BusDir->Alternative->ResourceByType[Res->Type];
01354
01355
if (Res->CurBusLoc >= CRes->NoAlternatives) {
01356
01357
01358
01359
01360 Res->CurLoc += Res->RunLen;
01361 Res->RunLen = 0;
01362
break;
01363 }
01364
01365 DescTmp = CRes->IoResourceDescriptor[Res->CurBusLoc];
01366 Res->CurBusMin = IO_DESC_MIN (DescTmp);
01367 Res->CurBusMax = IO_DESC_MAX (DescTmp);
01368 BusMin = Res->CurBusMin;
01369 BusMax = Res->CurBusMax;
01370 NAddr = Res->CurBusMax;
01371 }
01372
01373 }
while (!NBSet);
01374
01375
01376
01377
01378
01379 Res->TType = NTType;
01380 Res->Trans = NTrans;
01381
01382 Res->CurPref = NPref;
01383 Res->CurBAddr = NBAddr;
01384 Res->CurBLoc = NBLoc;
01385
return TRUE;
01386 }
01387
01388
01389 ULONG
01390
IopFindCollisionInTList (
01391 IN PTENTRY SEntry,
01392 IN PLTENTRY List
01393 )
01394
01395
01396
01397
01398
01399
01400
01401
01402
01403
01404
01405
01406
01407
01408
01409
01410 {
01411 LONGLONG LiTmp;
01412
TENTRY Source;
01413 ULONG i, j;
01414
01415 Source = *SEntry;
01416
while (
List) {
01417 j =
List->CurEntries;
01418
for (i=0; i < j; i++) {
01419 SEntry =
List->Table+i;
01420
if (
DoesTEntryCollide (Source, *SEntry)) {
01421
01422 LiTmp = Source.
EAddr - SEntry->BAddr;
01423
return (ULONG) LiTmp + 1;
01424 }
01425 }
01426
List =
List->Next;
01427 }
01428
return 0;
01429 }
01430
01431
VOID
01432
IopPickupCollisionInTList (
01433 IN PDIR_RESOURCE_LIST CurList,
01434 IN UCHAR Type,
01435 IN LONGLONG BAddr,
01436 IN PTENTRY SEntry,
01437 IN PLTENTRY List
01438 )
01439 {
01440
TENTRY Source;
01441 ULONG i, j, conflicts;
01442
01443 Source = *SEntry;
01444
01445
01446
01447
01448
01449 j = CurList->Conflict.NoConflicts;
01450
if (j >
SCONFLICT) {
01451 j =
SCONFLICT;
01452 }
01453
01454
for (i=0; i < j; i++) {
01455
if (CurList->Conflict.EasyConflict[i].BAddr == BAddr &&
01456 CurList->Conflict.EasyConflict[i].Type == Type) {
01457
return ;
01458 }
01459 }
01460
01461
01462
01463
01464
01465 conflicts = CurList->Conflict.NoConflicts;
01466
if (conflicts <
SCONFLICT) {
01467 CurList->Conflict.EasyConflict[conflicts].Type = Type;
01468 CurList->Conflict.EasyConflict[conflicts].BAddr = BAddr;
01469 }
01470
01471
01472
01473
01474
01475
while (
List) {
01476 j =
List->CurEntries;
01477
for (i=0; i < j; i++) {
01478 SEntry =
List->Table+i;
01479
if (
DoesTEntryCollide (Source, *SEntry)) {
01480
01481
if (SEntry->Owner) {
01482
if (conflicts <
SCONFLICT) {
01483 CurList->Conflict.EasyConflict[conflicts].Owner = SEntry->Owner;
01484 SEntry->Owner->InConflict.Flink = (PVOID) -1;
01485 }
01486
01487
if (SEntry->Owner->InConflict.Flink ==
NULL) {
01488
01489
01490
01491
01492 InsertTailList (&CurList->Conflict.OtherConflicts, &SEntry->Owner->InConflict);
01493 }
01494
01495 }
01496
01497 CurList->Conflict.NoConflicts += 1;
01498
return ;
01499 }
01500 }
01501
List =
List->Next;
01502 }
01503 }
01504
01505
01506
STATIC PVOID
01507
IopAllocateDirPool (
01508 IN PDIR_RESREQ_LIST Dir,
01509 IN ULONG Length
01510 )
01511
01512
01513
01514
01515
01516
01517
01518
01519
01520
01521
01522 {
01523
PUSED_HEAP ph;
01524
01525 ph = (
PUSED_HEAP)
ExAllocatePool (PagedPool, Length+
sizeof(
USED_HEAP));
01526
if (!ph) {
01527
return NULL;
01528 }
01529
01530 ph->FreeHeap = (PVOID) ph;
01531 PushEntryList (&Dir->AllocatedHeap, &ph->FreeLink);
01532
return (PVOID) (ph+1);
01533 }
01534
01535
01536
01537 PIO_RESOURCE_REQUIREMENTS_LIST
01538
IopGetResourceReqRegistryValue (
01539 IN PDIR_RESREQ_LIST Dir,
01540 IN HANDLE KeyHandle,
01541 IN PWSTR ValueName
01542 )
01543
01544
01545
01546
01547
01548
01549
01550
01551
01552
01553
01554
01555 {
01556 PKEY_VALUE_FULL_INFORMATION KeyInformation;
01557
NTSTATUS status;
01558 PUCHAR Data;
01559 ULONG DataLength, Type;
01560 PIO_RESOURCE_REQUIREMENTS_LIST p;
01561
01562
for (; ;) {
01563 status =
IopGetRegistryValue (KeyHandle, ValueName, &KeyInformation);
01564
if (!
NT_SUCCESS(status)) {
01565
return NULL;
01566 }
01567
01568
01569
01570
01571
01572 Type = KeyInformation->Type;
01573 Data = ((PUCHAR) KeyInformation + KeyInformation->DataOffset);
01574 DataLength = KeyInformation->DataLength;
01575
01576
01577
01578
01579
01580 p = (PIO_RESOURCE_REQUIREMENTS_LIST)
IopAllocateDirPool (Dir, DataLength +
sizeof (WCHAR));
01581
if (!p) {
01582
ExFreePool (KeyInformation);
01583
return NULL;
01584 }
01585
01586 RtlCopyMemory (p, Data, DataLength);
01587
ExFreePool (KeyInformation);
01588
01589
if (Type == REG_SZ) {
01590
01591
01592
01593
01594
01595
ValueName = (PWSTR) p;
01596
ValueName [DataLength /
sizeof (WCHAR)] = 0;
01597
continue;
01598 }
01599
01600
01601
if (Type != REG_RESOURCE_REQUIREMENTS_LIST) {
01602
return NULL;
01603 }
01604
01605 p->ListSize = DataLength;
01606
return p;
01607 }
01608 }
01609
01610
#endif
01611
01612
#if 0
01613
NTSTATUS
01614
IopAssignResourcesPhase1 (
01615 IN PIO_RESOURCE_REQUIREMENTS_LIST IoResources,
01616 IN PIO_RESOURCE_REQUIREMENTS_LIST *pCopiedList
01617 )
01618
01619
01620
01621
01622
01623
01624
01625
01626
01627
01628
01629
01630
01631
01632 {
01633 PIO_RESOURCE_LIST ResourceList;
01634
NTSTATUS status;
01635 ULONG cnt, length;
01636 PUCHAR FirstAddress, LastAddress;
01637
01638
PAGED_CODE();
01639
01640
01641
01642
01643
01644
01645
if (IoResources->AlternativeLists == 0 ||
01646 IoResources->Reserved[0] != 0 ||
01647 IoResources->Reserved[1] != 0 ||
01648 IoResources->Reserved[2] != 0) {
01649
DBGMSG (
"IopAssignResourcesPhase1: Bad structure format\n");
01650
return STATUS_INVALID_PARAMETER;
01651 }
01652
01653
01654
01655
01656
01657
01658
01659
01660
01661 ResourceList = IoResources->List;
01662 FirstAddress = (PUCHAR) ResourceList;
01663 LastAddress = (PUCHAR) IoResources + IoResources->ListSize;
01664
01665
for (cnt=0; cnt < IoResources->AlternativeLists; cnt++) {
01666
if (ResourceList->Version != 1 || ResourceList->Revision < 1) {
01667
DBGMSG (
"IopAssignResourcesPhase1: Invalid version #\n");
01668
return STATUS_INVALID_PARAMETER;
01669 }
01670
01671 ResourceList = (PIO_RESOURCE_LIST)
01672 (&ResourceList->Descriptors[ResourceList->Count]);
01673
01674
01675
if ((PUCHAR) ResourceList < FirstAddress ||
01676 (PUCHAR) ResourceList > LastAddress) {
01677
DBGMSG (
"IopAssignResourcesPhase1: IO_RESOURCE_LIST.ListSize too small\n");
01678
return STATUS_INVALID_PARAMETER;
01679 }
01680 }
01681
01682 length = (ULONG) ((PUCHAR) ResourceList - (PUCHAR) IoResources);
01683
01684
01685
01686
01687
01688 *pCopiedList = (PIO_RESOURCE_REQUIREMENTS_LIST)
ExAllocatePool (PagedPool, length);
01689
01690
if (!*pCopiedList) {
01691
return STATUS_INSUFFICIENT_RESOURCES;
01692 }
01693
01694 RtlCopyMemory (*pCopiedList, IoResources, length);
01695 (*pCopiedList)->ListSize = length;
01696
01697
01698
01699
01700
01701 status =
HalAdjustResourceList (pCopiedList);
01702
if (!
NT_SUCCESS(status)) {
01703
DBGMSG (
"IopAssignResourcesPhase1: HalAdjustResourceList failed\n");
01704
ExFreePool (*pCopiedList);
01705
return status;
01706 }
01707
01708
return STATUS_SUCCESS;
01709 }
01710
01711
01712
NTSTATUS
01713
IopAssignResourcesPhase2 (
01714 IN PDIR_RESREQ_LIST Dir,
01715 IN PUNICODE_STRING DriverClassName,
01716 IN
PDRIVER_OBJECT DriverObject,
01717 IN
PDEVICE_OBJECT DeviceObject
01718 )
01719
01720
01721
01722
01723
01724
01725
01726
01727
01728
01729
01730
01731 {
01732 HANDLE ResourceMap, ClassKeyHandle, DriverKeyHandle;
01733 ULONG ClassKeyIndex, DriverKeyIndex, DriverValueIndex,
Index;
01734 POBJECT_NAME_INFORMATION ObNameInfo;
01735 PCM_RESOURCE_LIST CmResList;
01736 PCM_FULL_RESOURCE_DESCRIPTOR CmFResDesc;
01737 PCM_PARTIAL_RESOURCE_DESCRIPTOR CmDesc;
01738 UNICODE_STRING unicodeString;
01739 UNICODE_STRING
KeyName, TranslatedName, DriverName, DClassName;
01740 PVOID p2;
01741 ULONG
BufferSize;
01742
union {
01743 PVOID
Buffer;
01744 PKEY_BASIC_INFORMATION KeyBInf;
01745 PKEY_FULL_INFORMATION KeyFInf;
01746 PKEY_VALUE_FULL_INFORMATION VKeyFInf;
01747 } U;
01748 PUCHAR LastAddr;
01749 ULONG junk, Length, i, j, TranslatedStrLen, BusTranslatedStrLen;
01750 PWSTR pw;
01751
NTSTATUS status;
01752 BOOLEAN sameClass, sameDriver;
01753 BOOLEAN flag;
01754
POWNER Owner;
01755 LONGLONG li;
01756
01757
PAGED_CODE();
01758
01759
01760
01761
01762
01763
01764 U.Buffer = Dir->Buffer;
01765 U.KeyFInf->MaxValueNameLen = U.KeyFInf->MaxValueDataLen = 0;
01766 ZwQueryKey( Dir->RegHandle[HRESERVEDRESOURCES],
01767 KeyFullInformation,
01768 U.KeyFInf,
01769 BUFFERSIZE,
01770 &junk );
01771
01772 Length =
sizeof( KEY_VALUE_FULL_INFORMATION ) +
01773 U.KeyFInf->MaxValueNameLen + U.KeyFInf->MaxValueDataLen +
sizeof(UNICODE_NULL);
01774
01775
BufferSize = Length >
BUFFERSIZE ? Length :
BUFFERSIZE;
01776 U.Buffer =
ExAllocatePool (PagedPool, BufferSize);
01777
if (!U.Buffer) {
01778
return STATUS_INSUFFICIENT_RESOURCES;
01779 }
01780
01781
01782
01783
01784
01785 ObNameInfo = (POBJECT_NAME_INFORMATION) Dir->Buffer;
01786
if (DeviceObject) {
01787 status =
ObQueryNameString (DeviceObject, ObNameInfo, BUFFERSIZE, &Length);
01788
if (!
NT_SUCCESS(status)) {
01789
return status;
01790 }
01791 }
else {
01792 ObNameInfo->Name.Length = 0;
01793 ObNameInfo->Name.Buffer = (PVOID) ((PUCHAR) Dir->Buffer +
sizeof(OBJECT_NAME_INFORMATION));
01794 }
01795
01796
01797
01798
01799
01800
if (ObNameInfo->Name.Buffer ==
NULL) {
01801 ObNameInfo->Name.Length = 0;
01802 ObNameInfo->Name.Buffer = (PVOID) ((PUCHAR) Dir->Buffer +
sizeof(OBJECT_NAME_INFORMATION));
01803 }
01804
01805 ObNameInfo->Name.MaximumLength =
BUFFERSIZE -
sizeof(OBJECT_NAME_INFORMATION);
01806
RtlAppendUnicodeToString (&ObNameInfo->Name, IopWstrTranslated);
01807
01808 TranslatedName.Length = ObNameInfo->Name.Length;
01809 TranslatedName.MaximumLength = ObNameInfo->Name.Length;
01810 TranslatedName.Buffer =
IopAllocateDirPool (Dir, TranslatedName.Length);
01811
if (!TranslatedName.Buffer) {
01812
return STATUS_INSUFFICIENT_RESOURCES;
01813 }
01814 RtlCopyMemory (TranslatedName.Buffer, ObNameInfo->Name.Buffer, TranslatedName.Length);
01815
for (TranslatedStrLen=0;
IopWstrTranslated[TranslatedStrLen]; TranslatedStrLen++) ;
01816
for (BusTranslatedStrLen=0;
IopWstrBusTranslated[BusTranslatedStrLen]; BusTranslatedStrLen++) ;
01817 TranslatedStrLen *=
sizeof (WCHAR);
01818 BusTranslatedStrLen *=
sizeof (WCHAR);
01819
01820
01821
01822
01823
01824 status =
ObQueryNameString (DriverObject, ObNameInfo, BUFFERSIZE, &Length);
01825
if (!
NT_SUCCESS(status)) {
01826
return status;
01827 }
01828
01829 i = 0;
01830 pw = ObNameInfo->Name.Buffer;
01831
while (*pw) {
01832
if (*pw++ == OBJ_NAME_PATH_SEPARATOR) {
01833 i = pw - ObNameInfo->Name.Buffer;
01834 }
01835 }
01836
01837 Length = ObNameInfo->Name.Length - i *
sizeof (WCHAR);
01838 DriverName.Length = (
USHORT) Length;
01839 DriverName.MaximumLength = (
USHORT) Length;
01840 DriverName.Buffer =
IopAllocateDirPool (Dir, Length);
01841
if (!DriverName.Buffer) {
01842
return STATUS_INSUFFICIENT_RESOURCES;
01843 }
01844 RtlCopyMemory (DriverName.Buffer, ObNameInfo->Name.Buffer + i, Length);
01845
01846
01847
01848
01849
01850
if (!DriverClassName) {
01851
RtlInitUnicodeString( &DClassName, IopWstrOtherDrivers );
01852 DriverClassName = &DClassName;
01853 }
01854
01855
01856
01857
01858
01859 ResourceMap = Dir->RegHandle[
HRESOURCE_MAP];
01860 ClassKeyIndex = 0;
01861
01862 ClassKeyHandle =
INVALID_HANDLE;
01863 DriverKeyHandle =
INVALID_HANDLE;
01864
01865
while (
NT_SUCCESS(status)) {
01866
01867
01868
01869
01870
01871 status = ZwEnumerateKey( ResourceMap,
01872 ClassKeyIndex++,
01873 KeyBasicInformation,
01874 U.KeyBInf,
01875 BufferSize,
01876 &junk );
01877
01878
if (!
NT_SUCCESS( status )) {
01879
break;
01880 }
01881
01882
01883
01884
01885
01886
01887
01888
KeyName.Buffer = (PWSTR) U.KeyBInf->Name;
01889
KeyName.Length = (
USHORT) U.KeyBInf->NameLength;
01890
KeyName.MaximumLength = (
USHORT) U.KeyBInf->NameLength;
01891
01892 status =
IopOpenRegistryKey( &ClassKeyHandle,
01893 ResourceMap,
01894 &KeyName,
01895 KEY_READ,
01896 FALSE );
01897
01898
if (!
NT_SUCCESS( status )) {
01899
break;
01900 }
01901
01902
01903
01904
01905
01906 sameClass =
RtlEqualUnicodeString( DriverClassName, &KeyName, TRUE );
01907
01908 DriverKeyIndex = 0;
01909
while (
NT_SUCCESS (status)) {
01910
01911
01912
01913
01914
01915 status = ZwEnumerateKey( ClassKeyHandle,
01916 DriverKeyIndex++,
01917 KeyBasicInformation,
01918 U.KeyBInf,
01919 BufferSize,
01920 &junk );
01921
01922
if (!
NT_SUCCESS( status )) {
01923
break;
01924 }
01925
01926
01927
01928
01929
01930
01931
01932
01933
01934
KeyName.Buffer = (PWSTR)
IopAllocateDirPool (Dir, U.KeyBInf->NameLength);
01935
if (!
KeyName.Buffer) {
01936 status = STATUS_INSUFFICIENT_RESOURCES;
01937
break;
01938 }
01939
01940 RtlCopyMemory (
KeyName.Buffer, U.KeyBInf->Name, U.KeyBInf->NameLength);
01941
KeyName.Length = (
USHORT) U.KeyBInf->NameLength;
01942
KeyName.MaximumLength = (
USHORT) U.KeyBInf->NameLength;
01943
01944 status =
IopOpenRegistryKey( &DriverKeyHandle,
01945 ClassKeyHandle,
01946 &KeyName,
01947 KEY_READ,
01948 FALSE );
01949
01950
if (!
NT_SUCCESS( status )) {
01951
break;
01952 }
01953
01954
01955
01956
01957 sameDriver = sameClass &&
RtlEqualUnicodeString( &DriverName, &KeyName, TRUE );
01958
01959
01960
01961
01962
01963
01964 status = ZwQueryKey( DriverKeyHandle,
01965 KeyFullInformation,
01966 U.KeyFInf,
01967 BufferSize,
01968 &junk );
01969
01970
if (!
NT_SUCCESS( status )) {
01971
break;
01972 }
01973
01974 Length =
sizeof( KEY_VALUE_FULL_INFORMATION ) +
01975 U.KeyFInf->MaxValueNameLen + U.KeyFInf->MaxValueDataLen +
sizeof(UNICODE_NULL);
01976
01977
if (Length >
BufferSize) {
01978
01979
01980
01981
01982
01983 p2 =
ExAllocatePool (PagedPool, Length);
01984
if (!p2) {
01985 status = STATUS_INSUFFICIENT_RESOURCES;
01986
break;
01987 }
01988
01989
ExFreePool (U.Buffer);
01990 U.Buffer = p2;
01991
BufferSize = Length;
01992 }
01993
01994 DriverValueIndex = 0;
01995
for (; ;) {
01996 status = ZwEnumerateValueKey( DriverKeyHandle,
01997 DriverValueIndex++,
01998 KeyValueFullInformation,
01999 U.VKeyFInf,
02000 BufferSize,
02001 &junk );
02002
02003
if (!
NT_SUCCESS( status )) {
02004
break;
02005 }
02006
02007
02008
02009
02010
02011 i = U.VKeyFInf->NameLength;
02012
if (i < TranslatedStrLen ||
02013 RtlCompareMemory (
02014 ((PUCHAR) U.VKeyFInf->Name) + i - TranslatedStrLen,
02015 IopWstrTranslated,
02016 TranslatedStrLen
02017 ) != TranslatedStrLen
02018 ) {
02019
02020
continue;
02021 }
02022
02023
02024
02025
02026
02027
if (i >= BusTranslatedStrLen &&
02028 RtlCompareMemory (
02029 ((PUCHAR) U.VKeyFInf->Name) + i - BusTranslatedStrLen,
02030 IopWstrBusTranslated,
02031 BusTranslatedStrLen
02032 ) == BusTranslatedStrLen
02033 ) {
02034
02035
02036
continue;
02037 }
02038
02039
02040
02041
02042
02043
if (sameDriver) {
02044 unicodeString.Buffer = (PWSTR) U.VKeyFInf->Name;
02045 unicodeString.Length = (
USHORT) U.VKeyFInf->NameLength;
02046 unicodeString.MaximumLength = (
USHORT) U.VKeyFInf->NameLength;
02047
if (
RtlEqualUnicodeString (&unicodeString, &TranslatedName, TRUE)) {
02048
02049
02050
continue;
02051 }
02052 }
02053
02054
02055
02056
02057
02058
Owner =
IopAllocateDirPool (Dir,
sizeof (*Owner) + U.VKeyFInf->NameLength);
02059
if (!
Owner) {
02060 status = STATUS_INSUFFICIENT_RESOURCES;
02061
break;
02062 }
02063
02064
Owner->InConflict.Flink =
NULL;
02065
Owner->DeviceName.Buffer =
NULL;
02066
02067
Owner->KeyName.Buffer =
KeyName.Buffer;
02068
Owner->KeyName.Length =
KeyName.Length;
02069
Owner->KeyName.MaximumLength =
KeyName.MaximumLength;
02070
02071
if (U.VKeyFInf->Name[0] !=
L'.') {
02072
02073 U.VKeyFInf->NameLength -= TranslatedStrLen;
02074
02075
Owner->DeviceName.Buffer =
Owner->UnicodeBuffer;
02076
Owner->DeviceName.Length = (
USHORT) U.VKeyFInf->NameLength;
02077
Owner->DeviceName.MaximumLength = (
USHORT) U.VKeyFInf->NameLength;
02078 RtlCopyMemory (
Owner->UnicodeBuffer, U.VKeyFInf->Name, U.VKeyFInf->NameLength);
02079 }
02080
02081
02082
02083
02084
02085 CmResList = (PCM_RESOURCE_LIST) ( (PUCHAR) U.VKeyFInf + U.VKeyFInf->DataOffset);
02086 LastAddr = (PUCHAR) CmResList + U.VKeyFInf->DataLength;
02087
02088 CmFResDesc = CmResList->List;
02089
for (i=0; i < CmResList->Count &&
NT_SUCCESS(status) ; i++) {
02090 CmDesc = CmFResDesc->PartialResourceList.PartialDescriptors;
02091
if ((PUCHAR) (CmDesc+1) > LastAddr) {
02092
if (i) {
02093
DBGMSG (
"IopAssignResourcesPhase2: a. CmResourceList in regitry too short\n");
02094 }
02095
break;
02096 }
02097
02098
for (j=0; j < CmFResDesc->PartialResourceList.Count &&
NT_SUCCESS(status); j++) {
02099
if ((PUCHAR) (CmDesc+1) > LastAddr) {
02100 i = CmResList->Count;
02101
DBGMSG (
"IopAssignResourcesPhase2: b. CmResourceList in regitry too short\n");
02102
break;
02103 }
02104
02105
02106
02107
02108
02109
if (CmDesc->ShareDisposition == CmResourceShareShared) {
02110 status =
IopAddCmDescriptorToInUseList (
02111 Dir,
02112 &Dir->InUseSharableResources,
02113 CmDesc,
02114 Owner
02115 );
02116 }
else {
02117 status =
IopAddCmDescriptorToInUseList (
02118 Dir,
02119 &Dir->InUseResources,
02120 CmDesc,
02121 Owner
02122 );
02123
02124 }
02125 CmDesc++;
02126 }
02127
02128 CmFResDesc = (PCM_FULL_RESOURCE_DESCRIPTOR) CmDesc;
02129 }
02130
02131 }
02132
02133
if (DriverKeyHandle !=
INVALID_HANDLE) {
02134 ZwClose (DriverKeyHandle);
02135 DriverKeyHandle =
INVALID_HANDLE;
02136 }
02137
02138
if (status == STATUS_NO_MORE_ENTRIES) {
02139 status = STATUS_SUCCESS;
02140 }
02141
02142
if (!
NT_SUCCESS(status)) {
02143
break;
02144 }
02145 }
02146
02147
if (ClassKeyHandle !=
INVALID_HANDLE) {
02148 ZwClose (ClassKeyHandle);
02149 ClassKeyHandle =
INVALID_HANDLE;
02150 }
02151
02152
if (status == STATUS_NO_MORE_ENTRIES) {
02153 status = STATUS_SUCCESS;
02154 }
02155
02156 }
02157
02158
if (status == STATUS_NO_MORE_ENTRIES) {
02159 status = STATUS_SUCCESS;
02160 }
02161
02162
02163
02164
02165
02166
02167
02168
02169
02170
02171
02172
02173
Owner =
IopAllocateDirPool (Dir,
sizeof (*Owner) + U.VKeyFInf->NameLength);
02174
if (
Owner) {
02175
Owner->InConflict.Flink =
NULL;
02176
Owner->DeviceName.Buffer =
NULL;
02177
RtlInitUnicodeString (&
Owner->KeyName, IopWstrReservedResources);
02178 }
02179
02180
Index = 0;
02181
while (
NT_SUCCESS (status)) {
02182 status = ZwEnumerateValueKey( Dir->RegHandle[HRESERVEDRESOURCES],
02183 Index++,
02184 KeyValueFullInformation,
02185 U.VKeyFInf,
02186 BufferSize,
02187 &junk );
02188
02189
if (!
NT_SUCCESS( status )) {
02190
break;
02191 }
02192
02193
02194
02195
02196
02197 CmResList = (PCM_RESOURCE_LIST) ( (PUCHAR) U.VKeyFInf + U.VKeyFInf->DataOffset);
02198 LastAddr = (PUCHAR) CmResList + U.VKeyFInf->DataLength;
02199
02200 CmFResDesc = CmResList->List;
02201
for (i=0; i < CmResList->Count &&
NT_SUCCESS(status) ; i++) {
02202 CmDesc = CmFResDesc->PartialResourceList.PartialDescriptors;
02203
if ((PUCHAR) (CmDesc+1) > LastAddr) {
02204
DBGMSG (
"IopAssignResourcesPhase2: c. CmResourceList in regitry too short\n");
02205
break;
02206 }
02207
02208
for (j=0; j < CmFResDesc->PartialResourceList.Count &&
NT_SUCCESS(status); j++) {
02209
if ((PUCHAR) (CmDesc+1) > LastAddr) {
02210 i = CmResList->Count;
02211
DBGMSG (
"IopAssignResourcesPhase2: d. CmResourceList in regitry too short\n");
02212
break;
02213 }
02214
02215
02216
02217
02218
02219
switch (CmDesc->Type) {
02220
case CmResourceTypePort:
02221
case CmResourceTypeMemory:
02222 junk = CmDesc->Type == CmResourceTypePort ? 1 : 0;
02223 li = *((LONGLONG UNALIGNED *) &CmDesc->u.Port.Start);
02224 flag =
HalTranslateBusAddress (
02225 CmFResDesc->InterfaceType,
02226 CmFResDesc->BusNumber,
02227 *((PPHYSICAL_ADDRESS) &li),
02228 &junk,
02229 (PPHYSICAL_ADDRESS) &li
02230 );
02231 *((LONGLONG UNALIGNED *) &CmDesc->u.Port.Start) = li;
02232 CmDesc->Type = junk == 1 ? CmResourceTypePort : CmResourceTypeMemory;
02233
break;
02234
02235
case CmResourceTypeInterrupt:
02236 CmDesc->u.Interrupt.Vector =
HalGetInterruptVector (
02237 CmFResDesc->InterfaceType,
02238 CmFResDesc->BusNumber,
02239 CmDesc->u.Interrupt.Vector,
02240 CmDesc->u.Interrupt.Vector,
02241 (PKIRQL) &junk,
02242 &CmDesc->u.Interrupt.Affinity
02243 );
02244 flag = CmDesc->u.Interrupt.Affinity == 0 ?
FALSE :
TRUE;
02245
break;
02246
02247
case CmResourceTypeDma:
02248
02249 flag =
TRUE;
02250
break;
02251
02252
default:
02253 flag =
FALSE;
02254
break;
02255 }
02256
02257
if (flag) {
02258
02259
02260
02261
02262
02263
if (CmDesc->ShareDisposition == CmResourceShareShared) {
02264 status =
IopAddCmDescriptorToInUseList (
02265 Dir,
02266 &Dir->ReservedSharableResources,
02267 CmDesc,
02268 Owner
02269 );
02270 }
else {
02271 status =
IopAddCmDescriptorToInUseList (
02272 Dir,
02273 &Dir->InUseResources,
02274 CmDesc,
02275 Owner
02276 );
02277 }
02278 }
02279
02280 CmDesc++;
02281 }
02282
02283 CmFResDesc = (PCM_FULL_RESOURCE_DESCRIPTOR) CmDesc;
02284 }
02285
02286 }
02287
02288
if (status == STATUS_NO_MORE_ENTRIES) {
02289 status = STATUS_SUCCESS;
02290 }
02291
02292
ExFreePool (U.Buffer);
02293
return status;
02294 }
02295
02296
#if 0
02297
PDIR_RESOURCE_LIST
02298
IopAssignResourcesPhase3 (
02299 IN PDIR_RESREQ_LIST Dir
02300 )
02301
02302
02303
02304
02305
02306
02307
02308
02309
02310
02311 {
02312
PDIR_RESOURCE_LIST CurList, BestList;
02313
PDIR_REQUIRED_RESOURCE ReqRes;
02314 ULONG level, i, j;
02315 LONG BestPref, Pref;
02316
02317
02318
02319
02320
02321
PAGED_CODE();
02322
02323
for (CurList = Dir->Alternative; CurList; CurList = CurList->
Next) {
02324
02325
02326
for (i=0; i < CurList->
NoRequiredResources; i++) {
02327 CurList->
RequiredResource[i]->PassNo = 1;
02328 }
02329
02330
02331
if (
IopGenNextValidResourceList (0, CurList, Dir)) {
02332
02333
02334
return CurList;
02335 }
02336 }
02337
02338
02339
02340
02341
02342
02343
IDBGMSG (
"First pass attempt at resource settings failed\n");
02344
02345
for (CurList = Dir->Alternative; CurList; CurList = CurList->
Next) {
02346
for (; ;) {
02347
02348
02349
02350
02351 level = CurList->
LastLevel;
02352 ReqRes = CurList->
RequiredResource[level];
02353
if (ReqRes->PassNo != 1) {
02354
02355
break;
02356 }
02357
02358 ReqRes->PassNo = 2;
02359
for (j=0; j < ReqRes->NoAlternatives; j++) {
02360 ReqRes->IoResourceDescriptor[j]->Option &= ~IO_RESOURCE_PREFERRED;
02361 }
02362
02363
02364
02365
02366
02367 level = CurList->
NoRequiredResources;
02368
while (level > CurList->
FailedLevel) {
02369 level--;
02370 CurList->
RequiredResource[level]->CurLoc = 0;
02371 CurList->
RequiredResource[level]->RunLen = 0;
02372 }
02373
02374
if (
IopGenNextValidResourceList (level, CurList, Dir)) {
02375
02376
return CurList;
02377 }
02378
02379 }
02380 }
02381
02382
02383
02384
02385
02386
02387
IDBGMSG (
"Pass 2 attempt at resource settings failed\n");
02388
02389
for (CurList = Dir->Alternative; CurList; CurList = CurList->
Next) {
02390
for (i=0; i < CurList->
NoRequiredResources; i++) {
02391 ReqRes = CurList->
RequiredResource[i];
02392 ReqRes->CurLoc = 0;
02393 ReqRes->RunLen = 0;
02394 ReqRes->PassNo = 2;
02395
02396
for (j=0; j < ReqRes->NoAlternatives; j++) {
02397 ReqRes->IoResourceDescriptor[j]->Option &= ~IO_RESOURCE_PREFERRED;
02398 }
02399 }
02400 }
02401
02402 BestPref = -999999;
02403 BestList =
NULL;
02404 CurList = Dir->Alternative;
02405 level = 0;
02406
02407
while (CurList) {
02408
02409
02410
if (
IopGenNextValidResourceList (level, CurList, Dir)) {
02411
02412
02413
02414
02415
02416
if (CurList->
CurPref >= 0) {
02417
02418
02419
02420
02421
IDBGMSG (
"Pass3: Good hit\n");
02422
return CurList;
02423 }
02424
02425
if (CurList->
CurPref > BestPref) {
02426
02427
02428
02429
02430
02431 BestPref = CurList->
CurPref;
02432 BestList = CurList;
02433
02434
for (i = 0; i < CurList->NoRequiredResources; i++) {
02435 ReqRes = CurList->
RequiredResource[i];
02436 ReqRes->Pass2HoldCurLoc = ReqRes->CurBLoc;
02437 ReqRes->Pass2HoldBAddr = ReqRes->CurBAddr;
02438 }
02439 }
02440
02441
02442
02443
02444
02445 Pref = CurList->
CurPref;
02446 level = CurList->
NoRequiredResources;
02447
while (level && Pref <= BestPref) {
02448 level--;
02449 Pref -= CurList->
RequiredResource[level]->CurPref;
02450 CurList->
RequiredResource[level]->CurLoc = 0;
02451 CurList->
RequiredResource[level]->RunLen = 0;
02452 }
02453
02454
if (CurList->
RequiredResource[level]->PrefCnt > 16) {
02455
while (level && CurList->
RequiredResource[level]->PrefCnt > 16) {
02456 level--;
02457 Pref -= CurList->
RequiredResource[level]->CurPref;
02458 CurList->
RequiredResource[level]->CurLoc = 0;
02459 CurList->
RequiredResource[level]->RunLen = 0;
02460 }
02461
02462
if (level == 0) {
02463
02464
break;
02465 }
02466 }
02467
02468 CurList->
RequiredResource[level]->PrefCnt++;
02469
continue ;
02470 }
02471
02472
02473 CurList = CurList->
Next;
02474 level = 0;
02475 }
02476
02477
if (!BestList) {
02478
02479
IDBGMSG (
"Pass3: No settings found\n");
02480
return NULL;
02481 }
02482
02483
02484
02485
02486
02487
for (i = 0; i < BestList->
NoRequiredResources; i++) {
02488 ReqRes = BestList->
RequiredResource[i];
02489 ReqRes->CurBLoc = ReqRes->Pass2HoldCurLoc;
02490 ReqRes->CurBAddr = ReqRes->Pass2HoldBAddr;
02491 }
02492
02493
return BestList;
02494 }
02495
02496 PCM_RESOURCE_LIST
02497
IopAssignResourcesPhase4 (
02498 IN PDIR_RESREQ_LIST Dir,
02499 IN PDIR_RESOURCE_LIST CurList,
02500 OUT PULONG Length
02501 )
02502
02503
02504
02505
02506
02507
02508
02509
02510
02511
02512
02513
02514 {
02515 PCM_RESOURCE_LIST CmRes;
02516 PCM_PARTIAL_RESOURCE_DESCRIPTOR CmDesc;
02517
PDIR_REQUIRED_RESOURCE DirDesc, *pDirDesc;
02518 PIO_RESOURCE_DESCRIPTOR IoDesc;
02519 ULONG i, cnt, len;
02520
02521
PAGED_CODE();
02522
02523 cnt = CurList->NoRequiredResources;
02524 len =
sizeof (CM_RESOURCE_LIST) + cnt *
sizeof (CM_PARTIAL_RESOURCE_DESCRIPTOR);
02525 *Length = len;
02526
02527 CmRes = (PCM_RESOURCE_LIST)
ExAllocatePool (PagedPool, len);
02528
if (!CmRes) {
02529
return NULL;
02530 }
02531
02532 RtlZeroMemory (CmRes, len);
02533
02534 CmRes->Count = 1;
02535 CmRes->List[0].InterfaceType = Dir->IoResourceReq->InterfaceType;
02536 CmRes->List[0].BusNumber = Dir->IoResourceReq->BusNumber;
02537 CmRes->List[0].PartialResourceList.Count = CurList->NoRequiredResources;
02538
02539 CmDesc = CmRes->List[0].PartialResourceList.PartialDescriptors;
02540 pDirDesc = CurList->RequiredResource;
02541
02542
#if IDBG
02543
DbgPrint (
"Acquired Resourses - %d\n", CurList->NoRequiredResources);
02544
#endif
02545
02546
for (i=0; i < cnt; i++, CmDesc++, pDirDesc++) {
02547 DirDesc = *pDirDesc;
02548 IoDesc = DirDesc->IoResourceDescriptor[DirDesc->CurBLoc];
02549
02550 CmDesc->Type = IoDesc->Type;
02551 CmDesc->ShareDisposition = IoDesc->ShareDisposition;
02552 CmDesc->Flags = IoDesc->Flags;
02553
02554
switch (CmDesc->Type) {
02555
case CmResourceTypePort:
02556 CmDesc->u.Port.Start.QuadPart = DirDesc->CurBAddr;
02557 CmDesc->u.Port.Length = IoDesc->u.Port.Length;
02558
#if IDBG
02559
DbgPrint (
" IO Start %x:%08x, Len %x\n",
02560 CmDesc->u.Port.Start.HighPart, CmDesc->u.Port.Start.LowPart,
02561 CmDesc->u.Port.Length );
02562
#endif
02563
break;
02564
02565
case CmResourceTypeMemory:
02566 CmDesc->u.Memory.Start.QuadPart = DirDesc->CurBAddr;
02567 CmDesc->u.Memory.Length = IoDesc->u.Memory.Length;
02568
#if IDBG
02569
DbgPrint (
" MEM Start %x:%08x, Len %x\n",
02570 CmDesc->u.Memory.Start.HighPart, CmDesc->u.Memory.Start.LowPart,
02571 CmDesc->u.Memory.Length );
02572
#endif
02573
break;
02574
02575
case CmResourceTypeInterrupt:
02576 CmDesc->u.Interrupt.Level = (ULONG) DirDesc->CurBAddr;
02577 CmDesc->u.Interrupt.Vector = (ULONG) DirDesc->CurBAddr;
02578
#if IDBG
02579
DbgPrint (
" INT Level %x, Vector %x\n",
02580 CmDesc->u.Interrupt.Level, CmDesc->u.Interrupt.Vector );
02581
#endif
02582
break;
02583
02584
case CmResourceTypeDma:
02585 CmDesc->u.Dma.Channel = (ULONG) DirDesc->CurBAddr;
02586
#if IDBG
02587
DbgPrint (
" DMA Channel %x\n", CmDesc->u.Dma.Channel);
02588
#endif
02589
break;
02590
02591
default:
02592
ExFreePool (CmRes);
02593
return NULL;
02594 }
02595 }
02596
02597
return CmRes;
02598 }
02599
02600
STATIC VOID
02601
IopLogConflict (
02602 IN
PDRIVER_OBJECT DriverObject,
02603 IN PDIR_RESREQ_LIST Dir,
02604 IN NTSTATUS FinalStatus
02605 )
02606
02607
02608
02609
02610
02611
02612
02613
02614
02615
02616 {
02617 PIO_ERROR_LOG_PACKET ErrLog;
02618
PDIR_RESOURCE_LIST CurList;
02619
PDIR_REQUIRED_RESOURCE ReqRes;
02620 ULONG i, j;
02621 ULONG len, ErrorLogNumber, ErrLogBufferLeft;
02622 ULONG ConflictLevel;
02623 UCHAR s[8];
02624 PWCHAR pLog;
02625
POWNER Owner;
02626
02627
PAGED_CODE();
02628
02629
IDBGMSG (
"\n****\n");
02630
IDBGMSG (
"Failed to satisfy the following required resource\n");
02631
02632 ErrLog =
NULL;
02633 ErrorLogNumber = 0;
02634
02635
02636
02637
02638
02639
for (CurList = Dir->Alternative; CurList; CurList = CurList->
Next) {
02640
02641
02642
02643
02644
02645
for (i=0; i < CurList->
NoRequiredResources; i++) {
02646 CurList->
RequiredResource[i]->CurLoc = 0;
02647 CurList->
RequiredResource[i]->RunLen = 0;
02648 CurList->
RequiredResource[i]->PassNo = 2;
02649 }
02650
02651
02652
02653
02654
02655 ConflictLevel = CurList->
FailedLevel;
02656 CurList->
RequiredResource[ConflictLevel]->PassNo = 3;
02657
02658 InitializeListHead (&CurList->
Conflict.
OtherConflicts);
02659
02660
if (
IopGenNextValidResourceList (0, CurList, Dir)) {
02661
IDBGMSG (
"IopLogConflict: internal error\n");
02662
continue ;
02663 }
02664
02665
#if IDBG
02666
if (CurList != Dir->Alternative) {
02667
DbgPrint (
"the following alternate resource also failed\n");
02668 }
02669
02670 s[0] = s[1] = s[2] = s[3] =
' ';
02671 s[4] = 0;
02672
02673 ReqRes = CurList->
RequiredResource[ConflictLevel];
02674
for (j=0; j < ReqRes->NoAlternatives; j++) {
02675 IopDumpIoResourceDescriptor (s, ReqRes->IoResourceDescriptor[j]);
02676 }
02677
02678
02679 i = CurList->
Conflict.
NoConflicts;
02680
if (i >
SCONFLICT) {
02681 i =
SCONFLICT;
02682 }
02683
for (j=0; j < i; j++) {
02684
DbgPrint (
" Conflict # %d. ", j+1);
02685
switch (CurList->
Conflict.
EasyConflict[j].Type) {
02686
case CmResourceTypePort:
02687
DbgPrint (
"IO Base %08x", (ULONG) CurList->
Conflict.
EasyConflict[j].BAddr);
02688
break;
02689
02690
case CmResourceTypeMemory:
02691
DbgPrint (
"MEM Base %08x", (ULONG) CurList->
Conflict.
EasyConflict[j].BAddr);
02692
break;
02693
02694
case CmResourceTypeInterrupt:
02695
DbgPrint (
"INT Line %x", (ULONG) CurList->
Conflict.
EasyConflict[j].BAddr);
02696
break;
02697
02698
case CmResourceTypeDma:
02699
DbgPrint (
"DMA Channel %x", (ULONG) CurList->
Conflict.
EasyConflict[j].BAddr);
02700
break;
02701 }
02702
02703
DbgPrint (
" with '%wZ' ", &CurList->
Conflict.
EasyConflict[j].Owner->KeyName);
02704
if (CurList->
Conflict.
EasyConflict[j].Owner->DeviceName.Buffer) {
02705
DbgPrint (
"'%wZ'", &CurList->
Conflict.
EasyConflict[j].Owner->DeviceName);
02706 }
02707
DbgPrint (
"\n");
02708 }
02709
02710
if (CurList->
Conflict.
NoConflicts >
SCONFLICT) {
02711
DbgPrint (
" ...\n");
02712
DbgPrint (
"Total Conflicts = %d\n", CurList->
Conflict.
NoConflicts);
02713 }
02714
02715
if (!IsListEmpty (&CurList->
Conflict.
OtherConflicts)) {
02716
DbgPrint (
"Possible settings also conflicts with the following list\n");
02717
02718 }
02719
#endif
02720
02721
02722
02723
02724
02725 i = CurList->
Conflict.
NoConflicts;
02726
if (i >
SCONFLICT) {
02727 i =
SCONFLICT;
02728 }
02729
02730
for (j=0; j < i; j++) {
02731
if (ErrorLogNumber >= 3) {
02732
02733
02734
02735
break;
02736 }
02737
02738
02739
02740
02741
02742 ErrorLogNumber += 1;
02743 ErrLog =
IoAllocateErrorLogEntry (DriverObject, ERROR_LOG_MAXIMUM_SIZE);
02744
if (!ErrLog) {
02745
break;
02746 }
02747
02748
02749
02750
02751
02752 RtlZeroMemory (ErrLog,
sizeof (*ErrLog));
02753 ErrLog->FinalStatus = FinalStatus;
02754 ErrLog->UniqueErrorValue = ErrorLogNumber;
02755 ErrLog->NumberOfStrings = 2;
02756 pLog = (PWCHAR) ErrLog->DumpData;
02757 ErrLog->StringOffset = (
USHORT) ( ((PUCHAR) pLog) - ((PUCHAR) ErrLog) );
02758 ErrLogBufferLeft = (ERROR_LOG_MAXIMUM_SIZE - ErrLog->StringOffset) /
sizeof(WCHAR);
02759
02760
switch (CurList->
Conflict.
EasyConflict[j].Type) {
02761
case CmResourceTypePort:
02762 ErrLog->ErrorCode = IO_ERR_PORT_RESOURCE_CONFLICT;
02763
break;
02764
02765
case CmResourceTypeMemory:
02766 ErrLog->ErrorCode = IO_ERR_MEMORY_RESOURCE_CONFLICT;
02767
break;
02768
02769
case CmResourceTypeInterrupt:
02770 ErrLog->ErrorCode = IO_ERR_INTERRUPT_RESOURCE_CONFLICT;
02771
break;
02772
02773
case CmResourceTypeDma:
02774 ErrLog->ErrorCode = IO_ERR_DMA_RESOURCE_CONFLICT;
02775
break;
02776 }
02777
02778
if (CurList->
Conflict.
EasyConflict[j].BAddr & 0xffffffff00000000) {
02779 len = swprintf (pLog, L
"%X:%08X",
02780 (ULONG) (CurList->
Conflict.
EasyConflict[j].BAddr >> 32),
02781 (ULONG) CurList->
Conflict.
EasyConflict[j].BAddr
02782 );
02783 }
else {
02784 len = swprintf (pLog, L
"%X", (ULONG) CurList->
Conflict.
EasyConflict[j].BAddr);
02785 }
02786
02787 len += 1;
02788 pLog += len;
02789 ErrLogBufferLeft -= len;
02790
02791
Owner = CurList->
Conflict.
EasyConflict[j].Owner;
02792
02793 len =
Owner->KeyName.Length /
sizeof(WCHAR);
02794
if (len > ErrLogBufferLeft) {
02795 len = ErrLogBufferLeft;
02796 }
02797
02798 RtlCopyMemory (pLog,
Owner->KeyName.Buffer, len *
sizeof(WCHAR) );
02799 pLog += len;
02800 ErrLogBufferLeft -= len;
02801
02802
if (
Owner->DeviceName.Buffer && ErrLogBufferLeft > 11) {
02803 len =
Owner->DeviceName.Length /
sizeof(WCHAR);
02804
if (len > ErrLogBufferLeft) {
02805 len = ErrLogBufferLeft;
02806 }
02807
02808 *(pLog++) =
' ';
02809 RtlCopyMemory (pLog,
Owner->DeviceName.Buffer, len *
sizeof(WCHAR));
02810 pLog += len;
02811 ErrLogBufferLeft -= len;
02812 }
02813
02814 *(pLog++) = 0;
02815
02816
IoWriteErrorLogEntry ( ErrLog );
02817 }
02818 }
02819
02820
IDBGMSG (
"****\n");
02821 }
02822
#endif
02823
02824
02825
STATIC PTENTRY
02826
IopNewTransEntry (
02827 IN PDIR_RESREQ_LIST Dir,
02828 IN PTENTRIESBYTYPE pTypes,
02829 IN ULONG Type
02830 )
02831 {
02832
PLTENTRY LEntry, NewTable;
02833
02834 LEntry = pTypes->ByType[Type];
02835
02836
if (!LEntry || LEntry->
CurEntries ==
MAX_ENTRIES) {
02837
02838
02839
02840
02841 NewTable =
IopAllocateDirPool (Dir,
sizeof (
LTENTRY));
02842
02843
if (!NewTable) {
02844
return NULL;
02845 }
02846
02847 pTypes->ByType[Type] = NewTable;
02848 NewTable->
Next = LEntry;
02849 NewTable->
CurEntries = 0;
02850
02851 LEntry = NewTable;
02852 }
02853
02854
return LEntry->
Table + (LEntry->
CurEntries++);
02855 }
02856
02857
02858
STATIC NTSTATUS
02859
IopAddCmDescriptorToInUseList (
02860 IN PDIR_RESREQ_LIST Dir,
02861 IN PTENTRIESBYTYPE pTypes,
02862 IN PCM_PARTIAL_RESOURCE_DESCRIPTOR CmDesc,
02863 IN
POWNER Owner
02864 )
02865
02866
02867
02868
02869
02870
02871
02872
02873
02874
02875
02876 {
02877
PTENTRY Trans;
02878 LONGLONG li;
02879
02880
if ((CmDesc->Type == CmResourceTypePort && CmDesc->u.Port.Length == 0) ||
02881 (CmDesc->Type == CmResourceTypeMemory && CmDesc->u.Memory.Length == 0)) {
02882
02883
IDBGMSG (
"IopAddCmDescriptor: Skipping zero length descriptor\n");
02884
return STATUS_SUCCESS;
02885 }
02886
02887
02888
02889
02890
02891
02892 Trans =
IopNewTransEntry (Dir, pTypes, CmDesc->Type);
02893
if (!Trans) {
02894
return STATUS_INSUFFICIENT_RESOURCES;
02895 }
02896
02897
02898
02899
02900
02901
02902
02903
02904 Trans->Owner =
Owner;
02905
switch (CmDesc->Type) {
02906
case CmResourceTypePort:
02907 li = CmDesc->u.Port.Length - 1;
02908 Trans->BAddr = *((LONGLONG UNALIGNED *) &CmDesc->u.Port.Start);
02909 Trans->EAddr = Trans->BAddr + li;
02910 Trans->Affinity = (KAFFINITY) -1;
02911
break;
02912
02913
case CmResourceTypeMemory:
02914 li = CmDesc->u.Memory.Length - 1;
02915 Trans->BAddr = *((LONGLONG UNALIGNED *) &CmDesc->u.Memory.Start);
02916 Trans->EAddr = Trans->BAddr + li;
02917 Trans->Affinity = (KAFFINITY) -1;
02918
break;
02919
02920
case CmResourceTypeInterrupt:
02921 Trans->BAddr = CmDesc->u.Interrupt.Vector;
02922 Trans->EAddr = CmDesc->u.Interrupt.Vector;
02923 Trans->Affinity = CmDesc->u.Interrupt.Affinity;
02924
break;
02925
02926
case CmResourceTypeDma:
02927 Trans->BAddr = CmDesc->u.Dma.Channel;
02928 Trans->EAddr = CmDesc->u.Dma.Channel;
02929 Trans->Affinity = (KAFFINITY) -1;
02930
break;
02931 }
02932
return STATUS_SUCCESS;
02933 }
02934
02935
NTSTATUS
02936
IopBuildResourceDir (
02937 IN PDIR_RESREQ_LIST ParentDir,
02938 IN PDIR_RESREQ_LIST *pDir,
02939 IN PIO_RESOURCE_REQUIREMENTS_LIST IoResources
02940 )
02941
02942
02943
02944
02945
02946
02947
02948
02949
02950
02951
02952
02953 {
02954
PDIR_RESREQ_LIST Dir;
02955 PIO_RESOURCE_LIST ResourceList;
02956 PIO_RESOURCE_DESCRIPTOR Descriptor, ADescriptor;
02957
PDIR_RESOURCE_LIST DirResourceList, *AltListTail;
02958
PDIR_REQUIRED_RESOURCE ReqRes;
02959 ULONG i, j, alt, cnt, acnt;
02960 PUCHAR FirstAddress, LastAddress;
02961
02962
02963
02964
02965
02966 Dir = (
PDIR_RESREQ_LIST)
ExAllocatePool (PagedPool,
sizeof(
DIR_RESREQ_LIST));
02967 *pDir = Dir;
02968
if (!Dir) {
02969
return STATUS_INSUFFICIENT_RESOURCES;
02970 }
02971
02972 RtlZeroMemory (Dir,
sizeof (
DIR_RESREQ_LIST));
02973
for (i=0; i <
MAX_REG_HANDLES; i++) {
02974 Dir->RegHandle[i] =
INVALID_HANDLE;
02975 }
02976
02977
if (ParentDir) {
02978 Dir->FreeResReqList = ParentDir->FreeResReqList;
02979 ParentDir->FreeResReqList = Dir;
02980 }
02981
02982
02983
02984
02985
02986
if (!IoResources) {
02987
return STATUS_SUCCESS;
02988 }
02989
02990
02991
02992
02993
02994 ResourceList = IoResources->List;
02995 FirstAddress = (PUCHAR) ResourceList;
02996 LastAddress = (PUCHAR) IoResources + IoResources->ListSize;
02997
for (cnt=0; cnt < IoResources->AlternativeLists; cnt++) {
02998 ResourceList = (PIO_RESOURCE_LIST)
02999 (&ResourceList->Descriptors[ResourceList->Count]);
03000
03001
if ((PUCHAR) ResourceList < FirstAddress ||
03002 (PUCHAR) ResourceList > LastAddress) {
03003
DBGMSG (
"IopBuildResourceDir: IO_RESOURCE_LIST.ListSize too small\n");
03004
return STATUS_INVALID_PARAMETER;
03005 }
03006 }
03007
03008
03009
03010
03011
03012 Dir->IoResourceReq = IoResources;
03013 AltListTail = &Dir->Alternative;
03014 ResourceList = IoResources->List;
03015
03016
for (alt=0; alt < IoResources->AlternativeLists; alt++) {
03017
03018
03019
03020
03021
03022
03023 cnt = 0;
03024 Descriptor = ResourceList->Descriptors;
03025
for (i = ResourceList->Count; i; i--) {
03026
if (!(Descriptor->Option & IO_RESOURCE_ALTERNATIVE)) {
03027 cnt++;
03028 }
03029 Descriptor++;
03030 }
03031
03032
03033
03034
03035
03036 i =
sizeof (
DIR_RESOURCE_LIST) + cnt *
sizeof(PVOID) * 2;
03037 DirResourceList = (
PDIR_RESOURCE_LIST)
IopAllocateDirPool (Dir, i);
03038
03039
if (!DirResourceList) {
03040
return STATUS_INSUFFICIENT_RESOURCES;
03041 }
03042
03043
03044
03045
03046
03047 RtlZeroMemory (DirResourceList, i);
03048 DirResourceList->
IoResourceList = ResourceList;
03049
03050
03051 *(AltListTail) = DirResourceList;
03052 AltListTail = &DirResourceList->
Next;
03053
03054 Descriptor = ResourceList->Descriptors;
03055
for (i = ResourceList->Count; i; i--) {
03056
if (!(Descriptor->Option & IO_RESOURCE_ALTERNATIVE)) {
03057
03058
03059
03060
03061 acnt = 1;
03062 ADescriptor = Descriptor + 1;
03063
while (acnt < i && ADescriptor->Option & IO_RESOURCE_ALTERNATIVE) {
03064 ADescriptor++;
03065 acnt++;
03066 }
03067
03068
03069
03070
03071
03072 ReqRes = (
PDIR_REQUIRED_RESOURCE)
IopAllocateDirPool (Dir,
03073
sizeof (
DIR_REQUIRED_RESOURCE) + acnt *
sizeof(PVOID));
03074
03075
if (!ReqRes) {
03076
return STATUS_INSUFFICIENT_RESOURCES;
03077 }
03078
03079 RtlZeroMemory (ReqRes,
sizeof (DIR_REQUIRED_RESOURCE));
03080 DirResourceList->
RequiredResource[DirResourceList->
NoRequiredResources] = ReqRes;
03081 DirResourceList->
NoRequiredResources++;
03082
03083
03084
03085
03086
03087 ReqRes->NoAlternatives = acnt;
03088 ADescriptor = Descriptor;
03089
for (j=0; j < acnt; j++) {
03090 ReqRes->IoResourceDescriptor[j] = ADescriptor;
03091
if (ADescriptor->Option & IO_RESOURCE_PREFERRED) {
03092 ReqRes->BestPref = 1;
03093 }
03094 ADescriptor++;
03095 }
03096 }
03097
03098
03099
03100
03101 Descriptor++;
03102 }
03103
03104
03105
03106
03107
03108
03109 ResourceList = (PIO_RESOURCE_LIST) Descriptor;
03110 }
03111
return STATUS_SUCCESS;
03112 }
03113
03114
VOID
03115
IopFreeResourceDir (
03116 IN PDIR_RESREQ_LIST DirResourceList
03117 )
03118
03119
03120
03121
03122
03123
03124
03125
03126
03127
03128
03129
03130
03131 {
03132
PDIR_RESREQ_LIST NextResourceList;
03133 ULONG i;
03134 PSINGLE_LIST_ENTRY pe;
03135
PUSED_HEAP ph;
03136
03137
03138
03139
03140
03141
while (DirResourceList) {
03142 NextResourceList = DirResourceList->
FreeResReqList;
03143
03144
03145
03146
03147
03148
while (DirResourceList->AllocatedHeap.Next) {
03149 pe = PopEntryList (&DirResourceList->AllocatedHeap);
03150 ph = CONTAINING_RECORD(pe,
USED_HEAP, FreeLink);
03151
ExFreePool (ph->FreeHeap);
03152 }
03153
03154
03155
03156
03157
03158
for (i=0; i<
MAX_REG_HANDLES; i++) {
03159
if (DirResourceList->RegHandle[i] !=
INVALID_HANDLE) {
03160 ZwClose (DirResourceList->RegHandle[i]);
03161 }
03162 }
03163
03164
03165
03166
03167
03168
03169
ExFreePool (DirResourceList);
03170
03171
03172
03173
03174
03175 DirResourceList = NextResourceList;
03176 }
03177 }
03178
03179
#if IDBG
03180
VOID
03181 IopDumpIoResourceDir (
03182 IN PDIR_RESREQ_LIST Dir
03183 )
03184 {
03185
PDIR_RESOURCE_LIST ResourceList;
03186 PIO_RESOURCE_DESCRIPTOR Desc;
03187
PDIR_REQUIRED_RESOURCE ReqRes;
03188 ULONG alt, i, j;
03189 UCHAR s[10];
03190
03191
03192 alt = 0;
03193
for (ResourceList = Dir->Alternative; ResourceList; ResourceList = ResourceList->
Next) {
03194
DbgPrint (
"Alternative #%d - %d required resources\n",
03195 alt++, ResourceList->
NoRequiredResources );
03196
03197
for (i=0; i < ResourceList->
NoRequiredResources; i++) {
03198 ReqRes = ResourceList->
RequiredResource[i];
03199
for (j=0; j < ReqRes->NoAlternatives; j++) {
03200 Desc = ReqRes->IoResourceDescriptor[j];
03201
if (j == 0) {
03202 s[0] = s[1] = s[2] =
'*';
03203 s[3] =
' ';
03204 }
else {
03205 s[0] = s[1] = s[2] = s[3] =
' ';
03206 }
03207
03208 s[4] = Desc->Option & IO_RESOURCE_PREFERRED ?
'P' :
' ';
03209 s[5] =
' ';
03210 s[6] = 0;
03211
03212 IopDumpIoResourceDescriptor (s, Desc);
03213 }
03214 }
03215 }
03216 }
03217
03218
VOID
03219 IopDumpIoResourceDescriptor (
03220 IN PUCHAR Indent,
03221 IN PIO_RESOURCE_DESCRIPTOR Desc
03222 )
03223 {
03224
switch (Desc->Type) {
03225
case CmResourceTypePort:
03226
DbgPrint (
"%sIO Min: %x:%08x, Max: %x:%08x, Algn: %x, Len %x\n",
03227 Indent,
03228 Desc->u.Port.MinimumAddress.HighPart, Desc->u.Port.MinimumAddress.LowPart,
03229 Desc->u.Port.MaximumAddress.HighPart, Desc->u.Port.MaximumAddress.LowPart,
03230 Desc->u.Port.Alignment,
03231 Desc->u.Port.Length
03232 );
03233
break;
03234
03235
case CmResourceTypeMemory:
03236
DbgPrint (
"%sMEM Min: %x:%08x, Max: %x:%08x, Algn: %x, Len %x\n",
03237 Indent,
03238 Desc->u.Memory.MinimumAddress.HighPart, Desc->u.Memory.MinimumAddress.LowPart,
03239 Desc->u.Memory.MaximumAddress.HighPart, Desc->u.Memory.MaximumAddress.LowPart,
03240 Desc->u.Memory.Alignment,
03241 Desc->u.Memory.Length
03242 );
03243
break;
03244
03245
case CmResourceTypeInterrupt:
03246
DbgPrint (
"%sINT Min: %x, Max: %x\n",
03247 Indent,
03248 Desc->u.Interrupt.MinimumVector,
03249 Desc->u.Interrupt.MaximumVector
03250 );
03251
break;
03252
03253
case CmResourceTypeDma:
03254
DbgPrint (
"%sDMA Min: %x, Max: %x\n",
03255 Indent,
03256 Desc->u.Dma.MinimumChannel,
03257 Desc->u.Dma.MaximumChannel
03258 );
03259
break;
03260 }
03261 }
03262
03263
03264
#endif
03265
03266
NTSTATUS
03267
IopCatagorizeDescriptors (
03268 IN OUT PDIR_RESREQ_LIST Dir
03269 )
03270
03271
03272
03273
03274
03275
03276
03277
03278
03279
03280
03281
03282
03283 {
03284
PDIR_RESOURCE_LIST DirResourceList;
03285
PDIR_REQUIRED_RESOURCE ReqRes;
03286 ULONG i, j, acnt;
03287 CM_RESOURCE_TYPE
type;
03288
03289
if (!Dir->Alternative || Dir->Alternative->Next) {
03290
03291
DBGMSG (
"IopCatagorizeDescriptors: too many altenative lists\n");
03292
return STATUS_INVALID_PARAMETER_MIX;
03293 }
03294
03295 DirResourceList = Dir->Alternative;
03296
for (i=0; i < DirResourceList->
NoRequiredResources; i++) {
03297 ReqRes = DirResourceList->
RequiredResource[i];
03298
03299 acnt = ReqRes->NoAlternatives;
03300
if (!acnt) {
03301
03302
DBGMSG (
"IopCatagorizeDescriptors: no entries\n");
03303
return STATUS_INVALID_PARAMETER_MIX;
03304 }
03305
03306
type = ReqRes->IoResourceDescriptor[0]->Type;
03307
03308
03309
for (j=1; j < acnt; j++) {
03310
if (ReqRes->IoResourceDescriptor[j]->Type !=
type) {
03311
DBGMSG (
"IopCatagorizeDescriptors: mixed types in alternatives\n");
03312
return STATUS_INVALID_PARAMETER_MIX;
03313 }
03314 }
03315
03316
if (
type >= CmResourceTypeMaximum) {
03317
03318
continue;
03319 }
03320
03321
if (DirResourceList->
ResourceByType[
type]) {
03322
03323
DBGMSG (
"IopCatagorizeDescriptors: multiple lists per resource type\n");
03324
return STATUS_INVALID_PARAMETER_MIX;
03325 }
03326
03327 DirResourceList->
ResourceByType[
type] = ReqRes;
03328 }
03329
03330
return STATUS_SUCCESS;
03331 }
03332
03333
03334
03335
INLINE ULONG
03336
IopDescriptorSortingWeight (
03337 IN PIO_RESOURCE_DESCRIPTOR Descriptor
03338 )
03339
03340
03341
03342
03343
03344
03345 {
03346 ULONG w;
03347
03348
switch (Descriptor->Type) {
03349
case CmResourceTypeMemory: w = 4;
break;
03350
case CmResourceTypeInterrupt: w = 3;
break;
03351
case CmResourceTypeDma: w = 2;
break;
03352
case CmResourceTypePort: w = 1;
break;
03353
default: w = 0;
break;
03354 }
03355
03356
return w;
03357 }
03358
03359
03360
VOID
03361
IopSortDescriptors (
03362 IN OUT PDIR_RESREQ_LIST Dir
03363 )
03364
03365
03366
03367
03368
03369
03370
03371
03372
03373
03374
03375
03376 {
03377 PIO_RESOURCE_DESCRIPTOR Descriptor;
03378
PDIR_RESOURCE_LIST DirResourceList;
03379
PDIR_REQUIRED_RESOURCE ReqRes;
03380 ULONG i, j, k, acnt;
03381 ULONG w1, w2;
03382
03383
03384
03385
03386
03387
for (DirResourceList = Dir->Alternative; DirResourceList; DirResourceList = DirResourceList->
Next) {
03388
03389
03390
03391
03392
03393
for (k=0; k < DirResourceList->
NoRequiredResources; k++) {
03394 ReqRes = DirResourceList->
RequiredResource[k];
03395
03396 acnt = ReqRes->NoAlternatives;
03397
for (i=0; i < acnt; i++) {
03398 w1 =
IopDescriptorSortingWeight (ReqRes->IoResourceDescriptor[i]);
03399
03400
for (j = i+1; j < acnt; j++) {
03401 w2 =
IopDescriptorSortingWeight (ReqRes->IoResourceDescriptor[j]);
03402
03403
if (w2 > w1) {
03404 Descriptor = ReqRes->IoResourceDescriptor[i];
03405 ReqRes->IoResourceDescriptor[i] = ReqRes->IoResourceDescriptor[j];
03406 ReqRes->IoResourceDescriptor[j] = Descriptor;
03407 w1 = w2;
03408 }
03409 }
03410 }
03411 }
03412 }
03413 }
03414
#endif