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
00027
00028
#include "iop.h"
00029
00030
#if _PNP_POWER_
00031
00032
typedef struct _NRParams {
00033 PIO_RESOURCE_DESCRIPTOR InDesc;
00034 PIO_RESOURCE_DESCRIPTOR OutDesc;
00035
PSUPPORTED_RANGE CurrentPosition;
00036 LONGLONG Base;
00037 LONGLONG Limit;
00038 UCHAR DescOpt;
00039 BOOLEAN AnotherListPending;
00040 } NRPARAMS, *PNRPARAMS;
00041
00042 PIO_RESOURCE_REQUIREMENTS_LIST
00043
IopCmResourcesToIoResources (
00044 IN ULONG SlotNumber,
00045 IN PCM_RESOURCE_LIST CmResourceList
00046 );
00047
00048
NTSTATUS
00049 IopAdjustResourceListRange (
00050 IN
PSUPPORTED_RANGES SupportedRanges,
00051 IN
PSUPPORTED_RANGE InterruptRange,
00052 IN PIO_RESOURCE_REQUIREMENTS_LIST IoResourceList,
00053 IN OUT PIO_RESOURCE_REQUIREMENTS_LIST *ReturnedList
00054 );
00055
00056
NTSTATUS
00057 IopGetNextSupportedRange (
00058 IN LONGLONG MinimumAddress,
00059 IN LONGLONG MaximumAddress,
00060 IN OUT PNRPARAMS PNRParams,
00061 OUT PIO_RESOURCE_DESCRIPTOR *IoDescriptor
00062 );
00063
00064 ULONG
00065 IopSortRanges (
00066 IN
PSUPPORTED_RANGE RangeList
00067 );
00068
00069
#ifdef ALLOC_PRAGMA
00070
#pragma alloc_text(PAGE,IopAdjustResourceListRange)
00071
#pragma alloc_text(PAGE,IopSortRanges)
00072
#pragma alloc_text(PAGE,IopGetNextSupportedRange)
00073
#pragma alloc_text(PAGE,IopAddDefaultResourceList)
00074
#pragma alloc_text(PAGE,IopCmResourcesToIoResources)
00075
#endif
00076
00077 PIO_RESOURCE_REQUIREMENTS_LIST
00078 IopAddDefaultResourceList (
00079 IN PIO_RESOURCE_REQUIREMENTS_LIST IoResourceList,
00080 IN PCM_RESOURCE_LIST CmResourceList
00081 )
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106 {
00107 PIO_RESOURCE_REQUIREMENTS_LIST ioResReqList, combinedList =
NULL;
00108
SUPPORTED_RANGES supportRanges;
00109
SUPPORTED_RANGE interruptRange;
00110
PSUPPORTED_RANGE range, tmpRange;
00111
PSUPPORTED_RANGE intRange =
NULL, ioRange =
NULL, memRange =
NULL, dmaRange =
NULL;
00112 ULONG size, i, j, addressSpace = 0;
00113 PCM_FULL_RESOURCE_DESCRIPTOR cmFullDesc;
00114 PCM_PARTIAL_RESOURCE_DESCRIPTOR cmPartDesc;
00115
NTSTATUS status;
00116
00117
if (!IoResourceList) {
00118
00119
00120
00121
00122
00123
return NULL;
00124 }
else if (IoResourceList->List[0].Count == 0) {
00125
00126
00127
00128
00129
00130
00131 ioResReqList =
IopCmResourcesToIoResources(IoResourceList->SlotNumber,
00132 CmResourceList);
00133
return ioResReqList;
00134 }
00135
00136
00137
00138
00139
00140
00141 RtlZeroMemory(&supportRanges,
sizeof(supportRanges));
00142 supportRanges.
Version =
BUS_SUPPORTED_RANGE_VERSION;
00143 supportRanges.
Sorted =
FALSE;
00144 ioResReqList =
NULL;
00145
00146 cmFullDesc = &CmResourceList->List[0];
00147
for (i = 0; i < CmResourceList->Count; i++) {
00148 cmPartDesc = &cmFullDesc->PartialResourceList.PartialDescriptors[0];
00149
for (j = 0; j < cmFullDesc->PartialResourceList.Count; j++) {
00150 size = 0;
00151 range =
NULL;
00152
switch (cmPartDesc->Type) {
00153
case CmResourceTypePort:
00154
if (!ioRange) {
00155 range = &supportRanges.
IO;
00156 }
else {
00157 range = (
PSUPPORTED_RANGE)
ExAllocatePool(PagedPool,
sizeof(
SUPPORTED_RANGE));
00158 ioRange->
Next = range;
00159 }
00160 range->
SystemAddressSpace = 1;
00161 range->
SystemBase = 0;
00162 range->
Base = cmPartDesc->u.Port.Start.QuadPart;
00163 range->
Limit = cmPartDesc->u.Port.Start.QuadPart +
00164 cmPartDesc->u.Port.Length - 1;
00165 range->
Next =
NULL;
00166 ioRange = range;
00167 supportRanges.
NoIO++;
00168
break;
00169
case CmResourceTypeInterrupt:
00170
if (!intRange) {
00171 range = &interruptRange;
00172 }
else {
00173 range = (
PSUPPORTED_RANGE)
ExAllocatePool(PagedPool,
sizeof(
SUPPORTED_RANGE));
00174 intRange->
Next = range;
00175 }
00176 range->
SystemAddressSpace = 0;
00177 range->SystemBase = 0;
00178 range->Base = cmPartDesc->u.Interrupt.Vector;
00179 range->Limit = cmPartDesc->u.Interrupt.Vector;
00180 range->Next =
NULL;
00181 intRange = range;
00182
break;
00183
case CmResourceTypeMemory:
00184
if (!memRange) {
00185 range = &supportRanges.
Memory;
00186 }
else {
00187 range = (
PSUPPORTED_RANGE)
ExAllocatePool(PagedPool,
sizeof(
SUPPORTED_RANGE));
00188 memRange->
Next = range;
00189 }
00190 range->
SystemAddressSpace = 0;
00191 range->SystemBase = 0;
00192 range->Base = cmPartDesc->u.Memory.Start.QuadPart;
00193 range->Limit = cmPartDesc->u.Memory.Start.QuadPart +
00194 cmPartDesc->u.Memory.Length - 1;
00195 range->Next =
NULL;
00196 memRange = range;
00197 supportRanges.
NoMemory++;
00198
break;
00199
case CmResourceTypeDma:
00200
if (!dmaRange) {
00201 range = &supportRanges.
Dma;
00202 }
else {
00203 range = (
PSUPPORTED_RANGE)
ExAllocatePool(PagedPool,
sizeof(
SUPPORTED_RANGE));
00204 dmaRange->
Next = range;
00205 }
00206 range->
SystemAddressSpace = 0;
00207 range->SystemBase = 0;
00208 range->Base = cmPartDesc->u.Dma.Channel;
00209 range->Limit = cmPartDesc->u.Dma.Channel;
00210 range->Next =
NULL;
00211 dmaRange = range;
00212 supportRanges.
NoDma++;
00213
break;
00214
case CmResourceTypeDeviceSpecific:
00215 size = cmPartDesc->u.DeviceSpecificData.DataSize;
00216
break;
00217 }
00218 cmPartDesc++;
00219 cmPartDesc = (PCM_PARTIAL_RESOURCE_DESCRIPTOR) ((PUCHAR)cmPartDesc + size);
00220 }
00221 cmFullDesc = (PCM_FULL_RESOURCE_DESCRIPTOR)cmPartDesc;
00222 }
00223
00224
00225
00226
00227
00228 status = IopAdjustResourceListRange (
00229 &supportRanges,
00230 &interruptRange,
00231 IoResourceList,
00232 &ioResReqList
00233 );
00234
00235
if (!
NT_SUCCESS(status)) {
00236
goto exit0;
00237 }
00238
00239
00240
00241
00242
00243
00244 size = ioResReqList->ListSize + IoResourceList->ListSize -
00245 FIELD_OFFSET(IO_RESOURCE_REQUIREMENTS_LIST, List);
00246 combinedList = (PIO_RESOURCE_REQUIREMENTS_LIST)
ExAllocatePool(PagedPool, size);
00247
if (combinedList) {
00248 RtlMoveMemory(combinedList, ioResReqList, ioResReqList->ListSize);
00249 combinedList->ListSize = size;
00250 combinedList->AlternativeLists += IoResourceList->AlternativeLists;
00251 RtlMoveMemory((PUCHAR)combinedList + ioResReqList->ListSize,
00252 (PUCHAR)IoResourceList->List,
00253 IoResourceList->ListSize - FIELD_OFFSET(IO_RESOURCE_REQUIREMENTS_LIST, List)
00254 );
00255 }
00256
ExFreePool(ioResReqList);
00257 exit0:
00258
00259
00260
00261
00262
00263 range = interruptRange.
Next;
00264
while (range) {
00265 tmpRange = range;
00266 range = range->
Next;
00267
ExFreePool(tmpRange);
00268 }
00269 range = supportRanges.
IO.
Next;
00270
while (range) {
00271 tmpRange = range;
00272 range = range->
Next;
00273
ExFreePool(tmpRange);
00274 }
00275 range = supportRanges.
Memory.
Next;
00276
while (range) {
00277 tmpRange = range;
00278 range = range->
Next;
00279
ExFreePool(tmpRange);
00280 }
00281 range = supportRanges.
Dma.
Next;
00282
while (range) {
00283 tmpRange = range;
00284 range = range->
Next;
00285
ExFreePool(tmpRange);
00286 }
00287
return combinedList;
00288 }
00289
00290 PIO_RESOURCE_REQUIREMENTS_LIST
00291
IopCmResourcesToIoResources (
00292 IN ULONG SlotNumber,
00293 IN PCM_RESOURCE_LIST CmResourceList
00294 )
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316 {
00317 PIO_RESOURCE_REQUIREMENTS_LIST ioResReqList;
00318 ULONG count = 0, size, i, j;
00319 PCM_FULL_RESOURCE_DESCRIPTOR cmFullDesc;
00320 PCM_PARTIAL_RESOURCE_DESCRIPTOR cmPartDesc;
00321 PIO_RESOURCE_DESCRIPTOR ioDesc;
00322
00323
00324
00325
00326
00327 cmFullDesc = &CmResourceList->List[0];
00328
for (i = 0; i < CmResourceList->Count; i++) {
00329 count += cmFullDesc->PartialResourceList.Count;
00330 cmPartDesc = &cmFullDesc->PartialResourceList.PartialDescriptors[0];
00331
for (j = 0; j < cmFullDesc->PartialResourceList.Count; j++) {
00332 size = 0;
00333
switch (cmPartDesc->Type) {
00334
case CmResourceTypeDeviceSpecific:
00335 size = cmPartDesc->u.DeviceSpecificData.DataSize;
00336
break;
00337 }
00338 cmPartDesc++;
00339 cmPartDesc = (PCM_PARTIAL_RESOURCE_DESCRIPTOR) ((PUCHAR)cmPartDesc + size);
00340 }
00341 cmFullDesc = (PCM_FULL_RESOURCE_DESCRIPTOR)cmPartDesc;
00342 }
00343
00344
00345
00346
00347
00348 ioResReqList = (PIO_RESOURCE_REQUIREMENTS_LIST)
ExAllocatePool(
00349 PagedPool,
00350
sizeof(IO_RESOURCE_REQUIREMENTS_LIST) +
00351 count *
sizeof(IO_RESOURCE_DESCRIPTOR)
00352 );
00353
if (!ioResReqList) {
00354
return NULL;
00355 }
00356
00357
00358
00359
00360
00361 ioResReqList->InterfaceType = CmResourceList->List[0].InterfaceType;
00362 ioResReqList->BusNumber = CmResourceList->List[0].BusNumber;
00363 ioResReqList->SlotNumber = SlotNumber;
00364 ioResReqList->Reserved[0] = 0;
00365 ioResReqList->Reserved[1] = 0;
00366 ioResReqList->Reserved[2] = 0;
00367 ioResReqList->AlternativeLists = 1;
00368 ioResReqList->List[0].Version = 1;
00369 ioResReqList->List[0].Revision = 1;
00370 ioResReqList->List[0].Count = count;
00371
00372 ioDesc = &ioResReqList->List[0].Descriptors[0];
00373 cmFullDesc = &CmResourceList->List[0];
00374
for (i = 0; i < CmResourceList->Count; i++) {
00375 cmPartDesc = &cmFullDesc->PartialResourceList.PartialDescriptors[0];
00376
for (j = 0; j < cmFullDesc->PartialResourceList.Count; j++) {
00377 ioDesc->Option = IO_RESOURCE_PREFERRED;
00378 ioDesc->Type = cmPartDesc->Type;
00379 ioDesc->ShareDisposition = cmPartDesc->ShareDisposition;
00380 ioDesc->Flags = cmPartDesc->Flags;
00381 ioDesc->Spare1 = 0;
00382 ioDesc->Spare2 = 0;
00383
00384 size = 0;
00385
switch (cmPartDesc->Type) {
00386
case CmResourceTypePort:
00387 ioDesc->u.Port.MinimumAddress = cmPartDesc->u.Port.Start;
00388 ioDesc->u.Port.MaximumAddress.QuadPart = cmPartDesc->u.Port.Start.QuadPart +
00389 cmPartDesc->u.Port.Length - 1;
00390 ioDesc->u.Port.Alignment = 1;
00391 ioDesc->u.Port.Length = cmPartDesc->u.Port.Length;
00392 ioDesc++;
00393
break;
00394
case CmResourceTypeInterrupt:
00395 ioDesc->u.Interrupt.MinimumVector = cmPartDesc->u.Interrupt.Vector;
00396 ioDesc->u.Interrupt.MaximumVector = cmPartDesc->u.Interrupt.Vector;
00397 ioDesc++;
00398
break;
00399
case CmResourceTypeMemory:
00400 ioDesc->u.Memory.MinimumAddress = cmPartDesc->u.Memory.Start;
00401 ioDesc->u.Memory.MaximumAddress.QuadPart = cmPartDesc->u.Memory.Start.QuadPart +
00402 cmPartDesc->u.Memory.Length - 1;
00403 ioDesc->u.Memory.Alignment = 1;
00404 ioDesc->u.Memory.Length = cmPartDesc->u.Memory.Length;
00405 ioDesc++;
00406
break;
00407
case CmResourceTypeDma:
00408 ioDesc->u.Dma.MinimumChannel = cmPartDesc->u.Dma.Channel;
00409 ioDesc->u.Dma.MaximumChannel = cmPartDesc->u.Dma.Channel;
00410 ioDesc++;
00411
break;
00412
case CmResourceTypeDeviceSpecific:
00413 size = cmPartDesc->u.DeviceSpecificData.DataSize;
00414
break;
00415 }
00416 cmPartDesc++;
00417 cmPartDesc = (PCM_PARTIAL_RESOURCE_DESCRIPTOR) ((PUCHAR)cmPartDesc + size);
00418 }
00419 cmFullDesc = (PCM_FULL_RESOURCE_DESCRIPTOR)cmPartDesc;
00420 }
00421 ioResReqList->ListSize = (ULONG)ioDesc - (ULONG)ioResReqList;
00422
return ioResReqList;
00423 }
00424
00425
NTSTATUS
00426 IopAdjustResourceListRange (
00427 IN
PSUPPORTED_RANGES SupportedRanges,
00428 IN
PSUPPORTED_RANGE InterruptRange,
00429 IN PIO_RESOURCE_REQUIREMENTS_LIST IoResourceList,
00430 IN OUT PIO_RESOURCE_REQUIREMENTS_LIST *ReturnedList
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 PIO_RESOURCE_REQUIREMENTS_LIST InCompleteList, OutCompleteList;
00460 PIO_RESOURCE_LIST InResourceList, OutResourceList;
00461 PIO_RESOURCE_DESCRIPTOR HeadOutDesc, SetDesc;
00462 NRPARAMS Pos;
00463 ULONG len, alt, cnt, i;
00464 ULONG icnt, ListCount;
00465
NTSTATUS status;
00466
00467
00468
00469
00470
00471
if (!SupportedRanges || SupportedRanges->Version !=
BUS_SUPPORTED_RANGE_VERSION) {
00472
return STATUS_INVALID_PARAMETER;
00473 }
00474
00475
00476
00477
00478
00479
00480
if (!SupportedRanges->Sorted) {
00481 SupportedRanges->NoIO = IopSortRanges (&SupportedRanges->IO);
00482 SupportedRanges->NoMemory = IopSortRanges (&SupportedRanges->Memory);
00483 SupportedRanges->NoPrefetchMemory = IopSortRanges (&SupportedRanges->PrefetchMemory);
00484 SupportedRanges->NoDma = IopSortRanges (&SupportedRanges->Dma);
00485 SupportedRanges->Sorted =
TRUE;
00486 }
00487
00488 icnt = IopSortRanges (InterruptRange);
00489
00490 InCompleteList = IoResourceList;
00491 len = InCompleteList->ListSize;
00492
00493
00494
00495
00496
00497
00498 i = 0;
00499 InResourceList = InCompleteList->List;
00500
for (alt=0; alt < InCompleteList->AlternativeLists; alt++) {
00501
if (InResourceList->Version != 1 || InResourceList->Revision < 1) {
00502
return STATUS_INVALID_PARAMETER;
00503 }
00504
00505 Pos.InDesc = InResourceList->Descriptors;
00506
for (cnt = InResourceList->Count; cnt; cnt--) {
00507
switch (Pos.InDesc->Type) {
00508
case CmResourceTypeInterrupt: i += icnt;
break;
00509
case CmResourceTypePort: i += SupportedRanges->NoIO;
break;
00510
case CmResourceTypeDma: i += SupportedRanges->NoDma;
break;
00511
00512
case CmResourceTypeMemory:
00513 i += SupportedRanges->NoMemory;
00514
if (Pos.InDesc->Flags & CM_RESOURCE_MEMORY_PREFETCHABLE) {
00515 i += SupportedRanges->NoPrefetchMemory;
00516 }
00517
break;
00518
00519
default:
00520
return STATUS_INVALID_PARAMETER;
00521 }
00522
00523
00524 i -= 1;
00525
00526
00527 Pos.InDesc++;
00528 }
00529
00530
00531 InResourceList = (PIO_RESOURCE_LIST) Pos.InDesc;
00532 }
00533 len += i *
sizeof (IO_RESOURCE_DESCRIPTOR);
00534
00535
00536
00537
00538
00539 OutCompleteList = (PIO_RESOURCE_REQUIREMENTS_LIST)
00540
ExAllocatePool (PagedPool, len);
00541
00542
if (!OutCompleteList) {
00543
return STATUS_INSUFFICIENT_RESOURCES;
00544 }
00545
00546 RtlZeroMemory (OutCompleteList, len);
00547
00548
00549
00550
00551
00552 InResourceList = InCompleteList->List;
00553 *OutCompleteList = *InCompleteList;
00554 OutResourceList = OutCompleteList->List;
00555 ListCount = InCompleteList->AlternativeLists;
00556
00557
for (alt=0; alt < InCompleteList->AlternativeLists; alt++) {
00558 OutResourceList->Version = 1;
00559 OutResourceList->Revision = 1;
00560
00561 Pos.InDesc = InResourceList->Descriptors;
00562 Pos.OutDesc = OutResourceList->Descriptors;
00563 HeadOutDesc = Pos.OutDesc;
00564
00565
for (cnt = InResourceList->Count; cnt; cnt--) {
00566
00567
00568
00569
00570
00571 Pos.DescOpt = Pos.InDesc->Option | IO_RESOURCE_PREFERRED;
00572 Pos.AnotherListPending =
FALSE;
00573
00574
switch (Pos.InDesc->Type) {
00575
case CmResourceTypePort:
00576
00577
00578
00579
00580
00581 Pos.CurrentPosition = &SupportedRanges->IO;
00582
do {
00583 status = IopGetNextSupportedRange (
00584 Pos.InDesc->u.Port.MinimumAddress.QuadPart,
00585 Pos.InDesc->u.Port.MaximumAddress.QuadPart,
00586 &Pos,
00587 &SetDesc
00588 );
00589
if (
NT_SUCCESS(status)) {
00590
if (SetDesc) {
00591 SetDesc->u.Port.MinimumAddress.QuadPart = Pos.Base;
00592 SetDesc->u.Port.MaximumAddress.QuadPart = Pos.Limit;
00593 }
00594 }
else {
00595
goto skipCurrentList;
00596 }
00597 }
while (SetDesc) ;
00598
break;
00599
00600
case CmResourceTypeInterrupt:
00601
00602
00603
00604
00605 Pos.CurrentPosition = InterruptRange;
00606
do {
00607 status = IopGetNextSupportedRange (
00608 Pos.InDesc->u.Interrupt.MinimumVector,
00609 Pos.InDesc->u.Interrupt.MaximumVector,
00610 &Pos,
00611 &SetDesc
00612 );
00613
00614
if (
NT_SUCCESS(status)) {
00615
if (SetDesc) {
00616 SetDesc->u.Interrupt.MinimumVector = (ULONG) Pos.Base;
00617 SetDesc->u.Interrupt.MaximumVector = (ULONG) Pos.Limit;
00618 }
00619 }
else {
00620
goto skipCurrentList;
00621 }
00622 }
while (SetDesc) ;
00623
break;
00624
00625
case CmResourceTypeMemory:
00626
00627
00628
00629
00630
if (Pos.InDesc->Flags & CM_RESOURCE_MEMORY_PREFETCHABLE) {
00631
00632
00633
00634
00635
00636
00637
00638 Pos.AnotherListPending =
TRUE;
00639 Pos.CurrentPosition = &SupportedRanges->PrefetchMemory;
00640
00641
do {
00642 status = IopGetNextSupportedRange (
00643 Pos.InDesc->u.Memory.MinimumAddress.QuadPart,
00644 Pos.InDesc->u.Memory.MaximumAddress.QuadPart,
00645 &Pos,
00646 &SetDesc
00647 );
00648
00649
if (
NT_SUCCESS(status)) {
00650
if (SetDesc) {
00651 SetDesc->u.Memory.MinimumAddress.QuadPart = Pos.Base;
00652 SetDesc->u.Memory.MaximumAddress.QuadPart = Pos.Limit;
00653 SetDesc->Option |= IO_RESOURCE_PREFERRED;
00654 }
00655 }
else {
00656
goto skipCurrentList;
00657 }
00658 }
while (SetDesc) ;
00659
00660 Pos.AnotherListPending =
FALSE;
00661 }
00662
00663
00664
00665
00666
00667 Pos.CurrentPosition = &SupportedRanges->Memory;
00668
do {
00669 status = IopGetNextSupportedRange (
00670 Pos.InDesc->u.Memory.MinimumAddress.QuadPart,
00671 Pos.InDesc->u.Memory.MaximumAddress.QuadPart,
00672 &Pos,
00673 &SetDesc
00674 );
00675
if (
NT_SUCCESS(status)) {
00676
if (SetDesc) {
00677 SetDesc->u.Memory.MinimumAddress.QuadPart = Pos.Base;
00678 SetDesc->u.Memory.MaximumAddress.QuadPart = Pos.Limit;
00679 }
00680 }
else {
00681
goto skipCurrentList;
00682 }
00683 }
while (SetDesc);
00684
break;
00685
00686
case CmResourceTypeDma:
00687
00688
00689
00690
00691 Pos.CurrentPosition = &SupportedRanges->Dma;
00692
do {
00693 status = IopGetNextSupportedRange (
00694 Pos.InDesc->u.Dma.MinimumChannel,
00695 Pos.InDesc->u.Dma.MaximumChannel,
00696 &Pos,
00697 &SetDesc
00698 );
00699
00700
if (
NT_SUCCESS(status)) {
00701
if (SetDesc) {
00702 SetDesc->u.Dma.MinimumChannel = (ULONG) Pos.Base;
00703 SetDesc->u.Dma.MaximumChannel = (ULONG) Pos.Limit;
00704 }
00705 }
else {
00706
goto skipCurrentList;
00707 }
00708 }
while (SetDesc) ;
00709
break;
00710
00711
#if DBG
00712
default:
00713
DbgPrint (
"HalAdjustResourceList: Unkown resource type\n");
00714
break;
00715
#endif
00716
}
00717
00718
00719
00720
00721
00722 Pos.InDesc++;
00723 }
00724
00725 OutResourceList->Count = Pos.OutDesc - HeadOutDesc;
00726
00727
00728
00729
00730
00731 InResourceList = (PIO_RESOURCE_LIST) Pos.InDesc;
00732 OutResourceList = (PIO_RESOURCE_LIST) Pos.OutDesc;
00733
continue;
00734
00735 skipCurrentList:
00736 InResourceList = (PIO_RESOURCE_LIST) (InResourceList->Descriptors + InResourceList->Count);
00737 ListCount--;
00738 }
00739
00740
00741
00742
00743
00744
if (ListCount == 0) {
00745
ExFreePool(OutCompleteList);
00746
return STATUS_UNSUCCESSFUL;
00747 }
else {
00748 OutCompleteList->ListSize = (ULONG) ((PUCHAR) OutResourceList - (PUCHAR) OutCompleteList);
00749 OutCompleteList->AlternativeLists = ListCount;
00750 *ReturnedList = OutCompleteList;
00751
return STATUS_SUCCESS;
00752 }
00753 }
00754
00755
NTSTATUS
00756 IopGetNextSupportedRange (
00757 IN LONGLONG MinimumAddress,
00758 IN LONGLONG MaximumAddress,
00759 IN OUT PNRPARAMS Pos,
00760 OUT PIO_RESOURCE_DESCRIPTOR *IoDescriptor
00761 )
00762
00763
00764
00765
00766
00767
00768
00769
00770
00771
00772
00773
00774
00775
00776
00777
00778
00779
00780
00781
00782
00783
00784
00785
00786
00787 {
00788 LONGLONG Base, Limit;
00789
00790
00791
00792
00793
00794 Base = MinimumAddress;
00795 Limit = MaximumAddress;
00796
00797
while (Pos->CurrentPosition) {
00798 Pos->Base = Base;
00799 Pos->Limit = Limit;
00800
00801
00802
00803
00804
00805
if (Pos->Base < Pos->CurrentPosition->Base) {
00806 Pos->Base = Pos->CurrentPosition->Base;
00807 }
00808
00809
if (Pos->Limit > Pos->CurrentPosition->Limit) {
00810 Pos->Limit = Pos->CurrentPosition->Limit;
00811 }
00812
00813
00814
00815
00816
00817 Pos->CurrentPosition = Pos->CurrentPosition->Next;
00818
00819
00820
00821
00822
00823
if (Pos->Base <= Pos->Limit) {
00824 *Pos->OutDesc = *Pos->InDesc;
00825 Pos->OutDesc->Option = Pos->DescOpt;
00826
00827
00828
00829
00830
00831
00832 Pos->OutDesc += 1;
00833 Pos->DescOpt |= IO_RESOURCE_ALTERNATIVE;
00834 *IoDescriptor = Pos->OutDesc - 1;
00835
return STATUS_SUCCESS;
00836 }
00837 }
00838
00839
00840
00841
00842
00843
00844
00845
00846
if (!(Pos->DescOpt & IO_RESOURCE_ALTERNATIVE) &&
00847 Pos->AnotherListPending ==
FALSE) {
00848
00849
00850
00851
00852
00853 Pos->Base = MinimumAddress;
00854 Pos->Limit = Pos->Base - 1;
00855
if (Pos->Base == 0) {
00856 Pos->Base = 1;
00857 Pos->Limit = 0;
00858 }
00859
00860 *Pos->OutDesc = *Pos->InDesc;
00861 Pos->OutDesc->Option = Pos->DescOpt;
00862
00863 Pos->OutDesc += 1;
00864 Pos->DescOpt |= IO_RESOURCE_ALTERNATIVE;
00865 *IoDescriptor = Pos->OutDesc - 1;
00866
return STATUS_SUCCESS;
00867 }
00868
00869
00870
00871
00872
00873 *IoDescriptor =
NULL;
00874
return STATUS_SUCCESS;
00875 }
00876
00877 ULONG
00878 IopSortRanges (
00879 IN
PSUPPORTED_RANGE RangeList
00880 )
00881
00882
00883
00884
00885
00886
00887
00888
00889
00890
00891
00892
00893
00894
00895 {
00896 ULONG cnt;
00897 LONGLONG hldBase, hldLimit;
00898
PSUPPORTED_RANGE Range1, Range2;
00899
00900
00901
00902
00903
00904
for (Range1 = RangeList; Range1; Range1 = Range1->
Next) {
00905
for (Range2 = Range1->
Next; Range2; Range2 = Range2->
Next) {
00906
00907
if (Range2->
Base > Range1->
Base) {
00908 hldBase = Range1->
Base;
00909 hldLimit = Range1->
Limit;
00910
00911 Range1->
Base = Range2->
Base;
00912 Range1->
Limit = Range2->
Limit;
00913
00914 Range2->
Base = hldBase;
00915 Range2->
Limit = hldLimit;
00916 }
00917 }
00918 }
00919
00920
00921
00922
00923
00924 cnt = 0;
00925
for (Range1 = RangeList; Range1; Range1 = Range1->
Next) {
00926 cnt += 1;
00927 }
00928
00929
return cnt;
00930 }
00931
#endif // _PNP_POWER_