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_