648 lines
14 KiB
C
648 lines
14 KiB
C
|
/*++
|
|||
|
|
|||
|
Copyright (c) 1991 Microsoft Corporation
|
|||
|
|
|||
|
Module Name:
|
|||
|
|
|||
|
iousage.c
|
|||
|
|
|||
|
Abstract:
|
|||
|
|
|||
|
Author:
|
|||
|
|
|||
|
Ken Reneris (kenr)
|
|||
|
|
|||
|
Environment:
|
|||
|
|
|||
|
Kernel mode only.
|
|||
|
|
|||
|
Revision History:
|
|||
|
|
|||
|
Chao Chen 1-25-1995
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
#include "halp.h"
|
|||
|
#include "iousage.h"
|
|||
|
|
|||
|
//
|
|||
|
// Externals.
|
|||
|
//
|
|||
|
|
|||
|
extern KAFFINITY HalpActiveProcessors;
|
|||
|
|
|||
|
//
|
|||
|
// Private resource list.
|
|||
|
//
|
|||
|
|
|||
|
static PBUS_USAGE HalpBusUsageList = NULL;
|
|||
|
static PRESOURCE_USAGE HalpResourceUsageList = NULL;
|
|||
|
|
|||
|
//
|
|||
|
// Default HAL name.
|
|||
|
//
|
|||
|
|
|||
|
#define MAX_NAME_LENGTH 256
|
|||
|
UCHAR HalRegisteredName[MAX_NAME_LENGTH] = "Alpha Compatible PCI/EISA/ISA HAL";
|
|||
|
|
|||
|
//
|
|||
|
// Function prototype.
|
|||
|
//
|
|||
|
|
|||
|
VOID
|
|||
|
HalpReportResourceUsage (
|
|||
|
IN PUNICODE_STRING HalName
|
|||
|
);
|
|||
|
|
|||
|
VOID
|
|||
|
HalpGetResourceSortValue (
|
|||
|
IN PCM_PARTIAL_RESOURCE_DESCRIPTOR pRCurLoc,
|
|||
|
OUT PULONG sortscale,
|
|||
|
OUT PLARGE_INTEGER sortvalue
|
|||
|
);
|
|||
|
|
|||
|
//
|
|||
|
// Pragma stuff.
|
|||
|
//
|
|||
|
|
|||
|
#ifdef ALLOC_PRAGMA
|
|||
|
#pragma alloc_text(INIT,HalpRegisterHalName)
|
|||
|
#pragma alloc_text(INIT,HalpRegisterBusUsage)
|
|||
|
#pragma alloc_text(INIT,HalpRegisterResourceUsage)
|
|||
|
#pragma alloc_text(INIT,HalReportResourceUsage)
|
|||
|
#pragma alloc_text(INIT,HalpReportResourceUsage)
|
|||
|
#pragma alloc_text(INIT,HalpGetResourceSortValue)
|
|||
|
#endif
|
|||
|
|
|||
|
//
|
|||
|
// Function definitions.
|
|||
|
//
|
|||
|
|
|||
|
|
|||
|
VOID
|
|||
|
HalpRegisterHalName(
|
|||
|
IN PUCHAR NewHalName
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Allow the HAL to register a name string.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
HalName - Supplies a pointer to the HAL name to register.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
None.
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
|
|||
|
strncpy( HalRegisteredName, NewHalName, MAX_NAME_LENGTH );
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
VOID
|
|||
|
HalpRegisterBusUsage (
|
|||
|
IN INTERFACE_TYPE BusType
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Register the different bus types in the system.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
BusType - bus type that requires registering.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
None.
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
PBUS_USAGE Temp;
|
|||
|
|
|||
|
//
|
|||
|
// Allocate the buffer to store the bus information.
|
|||
|
//
|
|||
|
|
|||
|
Temp = (PBUS_USAGE)ExAllocatePool(NonPagedPool, sizeof(BUS_USAGE));
|
|||
|
|
|||
|
//
|
|||
|
// Save the bus type.
|
|||
|
//
|
|||
|
|
|||
|
Temp->BusType = BusType;
|
|||
|
|
|||
|
//
|
|||
|
// Add the bus type to the head of the list.
|
|||
|
//
|
|||
|
|
|||
|
Temp->Next = HalpBusUsageList;
|
|||
|
HalpBusUsageList = Temp;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
VOID
|
|||
|
HalpRegisterResourceUsage (
|
|||
|
IN PRESOURCE_USAGE Resource
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Register the resources used internally by the HAL to the I/O system.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
Resource - resource that requires registering.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
None.
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
PRESOURCE_USAGE Temp;
|
|||
|
|
|||
|
//
|
|||
|
// Allocate the buffer to store the resource information.
|
|||
|
//
|
|||
|
|
|||
|
Temp = (PRESOURCE_USAGE)ExAllocatePool(NonPagedPool, sizeof(RESOURCE_USAGE));
|
|||
|
|
|||
|
//
|
|||
|
// Copy the resource to the buffer we allocated.
|
|||
|
//
|
|||
|
|
|||
|
RtlCopyMemory(Temp, Resource, sizeof(RESOURCE_USAGE));
|
|||
|
|
|||
|
//
|
|||
|
// Add the resource to the head of the resource list.
|
|||
|
//
|
|||
|
|
|||
|
Temp->Next = HalpResourceUsageList;
|
|||
|
HalpResourceUsageList = Temp;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
VOID
|
|||
|
HalReportResourceUsage (
|
|||
|
VOID
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Report the resources used internally by the HAL to the I/O system.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
None.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
None.
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
ANSI_STRING AHalName;
|
|||
|
UNICODE_STRING UHalName;
|
|||
|
|
|||
|
//
|
|||
|
// Convert the string.
|
|||
|
//
|
|||
|
|
|||
|
RtlInitAnsiString (&AHalName, HalRegisteredName);
|
|||
|
RtlAnsiStringToUnicodeString (&UHalName, &AHalName, TRUE);
|
|||
|
|
|||
|
//
|
|||
|
// Report the resources registered as in use by the HAL.
|
|||
|
//
|
|||
|
|
|||
|
HalpReportResourceUsage(&UHalName);
|
|||
|
|
|||
|
RtlFreeUnicodeString(&UHalName);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
VOID
|
|||
|
HalpGetResourceSortValue (
|
|||
|
IN PCM_PARTIAL_RESOURCE_DESCRIPTOR pRCurLoc,
|
|||
|
OUT PULONG sortscale,
|
|||
|
OUT PLARGE_INTEGER sortvalue
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Used by HalpReportResourceUsage in order to properly sort
|
|||
|
partial_resource_descriptors.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
pRCurLoc - resource descriptor
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
sortscale - scaling of resource descriptor for sorting
|
|||
|
sortvalue - value to sort on
|
|||
|
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
|
|||
|
switch (pRCurLoc->Type) {
|
|||
|
case CmResourceTypeInterrupt:
|
|||
|
*sortscale = 0;
|
|||
|
sortvalue->QuadPart = pRCurLoc->u.Interrupt.Level;
|
|||
|
break;
|
|||
|
|
|||
|
case CmResourceTypePort:
|
|||
|
*sortscale = 1;
|
|||
|
*sortvalue = pRCurLoc->u.Port.Start;
|
|||
|
break;
|
|||
|
|
|||
|
case CmResourceTypeMemory:
|
|||
|
*sortscale = 2;
|
|||
|
*sortvalue = pRCurLoc->u.Memory.Start;
|
|||
|
break;
|
|||
|
|
|||
|
case CmResourceTypeDma:
|
|||
|
*sortscale = 3;
|
|||
|
sortvalue->QuadPart = pRCurLoc->u.Dma.Channel;
|
|||
|
break;
|
|||
|
|
|||
|
default:
|
|||
|
*sortscale = 4;
|
|||
|
sortvalue->QuadPart = 0;
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
VOID
|
|||
|
HalpReportResourceUsage (
|
|||
|
IN PUNICODE_STRING HalName
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
This routine registers the resources for the hal.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
HalName - the name of the hal to be registered.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
None.
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
PCM_RESOURCE_LIST RawResourceList, TranslatedResourceList;
|
|||
|
PCM_FULL_RESOURCE_DESCRIPTOR pRFullDesc, pTFullDesc;
|
|||
|
PCM_PARTIAL_RESOURCE_LIST pRPartList, pTPartList;
|
|||
|
PCM_PARTIAL_RESOURCE_DESCRIPTOR pRCurLoc, pTCurLoc;
|
|||
|
PCM_PARTIAL_RESOURCE_DESCRIPTOR pRSortLoc, pTSortLoc;
|
|||
|
CM_PARTIAL_RESOURCE_DESCRIPTOR RPartialDesc, TPartialDesc;
|
|||
|
ULONG i, j, k, ListSize, Count;
|
|||
|
ULONG curscale, sortscale;
|
|||
|
LARGE_INTEGER curvalue, sortvalue;
|
|||
|
PHYSICAL_ADDRESS PhyAddress;
|
|||
|
PBUS_USAGE CurrentBus;
|
|||
|
PRESOURCE_USAGE CurrentResource;
|
|||
|
|
|||
|
//
|
|||
|
// Allocate some space to build the resource structure.
|
|||
|
//
|
|||
|
|
|||
|
RawResourceList=
|
|||
|
(PCM_RESOURCE_LIST)ExAllocatePool(NonPagedPool, PAGE_SIZE*2);
|
|||
|
TranslatedResourceList=
|
|||
|
(PCM_RESOURCE_LIST)ExAllocatePool(NonPagedPool, PAGE_SIZE*2);
|
|||
|
|
|||
|
//
|
|||
|
// This functions assumes unset fields are zero.
|
|||
|
//
|
|||
|
|
|||
|
RtlZeroMemory (RawResourceList, PAGE_SIZE*2);
|
|||
|
RtlZeroMemory (TranslatedResourceList, PAGE_SIZE*2);
|
|||
|
|
|||
|
//
|
|||
|
// Initialize the lists
|
|||
|
//
|
|||
|
|
|||
|
RawResourceList->List[0].InterfaceType = (INTERFACE_TYPE) -1;
|
|||
|
pRFullDesc = RawResourceList->List;
|
|||
|
pRCurLoc = (PCM_PARTIAL_RESOURCE_DESCRIPTOR) RawResourceList->List;
|
|||
|
pTCurLoc = (PCM_PARTIAL_RESOURCE_DESCRIPTOR) TranslatedResourceList->List;
|
|||
|
|
|||
|
//
|
|||
|
// Report all the HAL resources.
|
|||
|
//
|
|||
|
|
|||
|
CurrentBus = HalpBusUsageList;
|
|||
|
|
|||
|
while (CurrentBus) {
|
|||
|
|
|||
|
//
|
|||
|
// Start at the head of the resource list for each bus type.
|
|||
|
//
|
|||
|
|
|||
|
CurrentResource = HalpResourceUsageList;
|
|||
|
|
|||
|
while (CurrentResource) {
|
|||
|
|
|||
|
//
|
|||
|
// Register the resources for a particular bus.
|
|||
|
//
|
|||
|
|
|||
|
if (CurrentBus->BusType == CurrentResource->BusType) {
|
|||
|
|
|||
|
switch (CurrentResource->ResourceType) {
|
|||
|
|
|||
|
case CmResourceTypeInterrupt:
|
|||
|
|
|||
|
//
|
|||
|
// Process interrupt resources.
|
|||
|
//
|
|||
|
|
|||
|
RPartialDesc.Type = CmResourceTypeInterrupt;
|
|||
|
RPartialDesc.ShareDisposition = CmResourceShareDriverExclusive;
|
|||
|
|
|||
|
if (CurrentResource->u.InterruptMode == Latched)
|
|||
|
RPartialDesc.Flags = CM_RESOURCE_INTERRUPT_LATCHED;
|
|||
|
else
|
|||
|
RPartialDesc.Flags = CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE;
|
|||
|
|
|||
|
RPartialDesc.u.Interrupt.Vector =
|
|||
|
CurrentResource->u.BusInterruptVector;
|
|||
|
RPartialDesc.u.Interrupt.Level =
|
|||
|
CurrentResource->u.BusInterruptVector;
|
|||
|
RPartialDesc.u.Interrupt.Affinity = HalpActiveProcessors;
|
|||
|
|
|||
|
RtlCopyMemory(&TPartialDesc, &RPartialDesc, sizeof(TPartialDesc));
|
|||
|
TPartialDesc.u.Interrupt.Vector =
|
|||
|
CurrentResource->u.SystemInterruptVector;
|
|||
|
TPartialDesc.u.Interrupt.Level =
|
|||
|
CurrentResource->u.SystemIrql;
|
|||
|
|
|||
|
break;
|
|||
|
|
|||
|
case CmResourceTypePort:
|
|||
|
case CmResourceTypeMemory:
|
|||
|
|
|||
|
//
|
|||
|
// Process port and memory resources.
|
|||
|
//
|
|||
|
|
|||
|
RPartialDesc.Type = CurrentResource->ResourceType;
|
|||
|
RPartialDesc.ShareDisposition = CmResourceShareDriverExclusive;
|
|||
|
|
|||
|
if (RPartialDesc.Type == CmResourceTypePort) {
|
|||
|
|
|||
|
//
|
|||
|
// In IO space.
|
|||
|
//
|
|||
|
|
|||
|
i = 1;
|
|||
|
RPartialDesc.Flags = CM_RESOURCE_PORT_IO;
|
|||
|
|
|||
|
} else {
|
|||
|
|
|||
|
//
|
|||
|
// In memory space.
|
|||
|
//
|
|||
|
|
|||
|
i = 0;
|
|||
|
RPartialDesc.Flags = CM_RESOURCE_MEMORY_READ_WRITE;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Notice: assume u.Memory and u.Port have the same layout.
|
|||
|
//
|
|||
|
|
|||
|
RPartialDesc.u.Memory.Start.HighPart = 0;
|
|||
|
RPartialDesc.u.Memory.Start.LowPart = CurrentResource->u.Start;
|
|||
|
RPartialDesc.u.Memory.Length = CurrentResource->u.Length;
|
|||
|
|
|||
|
RtlCopyMemory(&TPartialDesc, &RPartialDesc, sizeof(TPartialDesc));
|
|||
|
|
|||
|
//
|
|||
|
// Translate the address.
|
|||
|
//
|
|||
|
|
|||
|
HalTranslateBusAddress(CurrentResource->BusType,
|
|||
|
CurrentResource->BusNumber,
|
|||
|
RPartialDesc.u.Memory.Start,
|
|||
|
&i,
|
|||
|
&PhyAddress );
|
|||
|
|
|||
|
TPartialDesc.u.Memory.Start = PhyAddress;
|
|||
|
|
|||
|
if ((RPartialDesc.Type == CmResourceTypePort) && (i == 0))
|
|||
|
TPartialDesc.Flags = CM_RESOURCE_PORT_MEMORY;
|
|||
|
|
|||
|
break;
|
|||
|
|
|||
|
case CmResourceTypeDma:
|
|||
|
|
|||
|
//
|
|||
|
// Process dma resources.
|
|||
|
//
|
|||
|
|
|||
|
RPartialDesc.Type = CmResourceTypeDma;
|
|||
|
RPartialDesc.ShareDisposition = CmResourceShareDriverExclusive;
|
|||
|
|
|||
|
RPartialDesc.u.Dma.Channel = CurrentResource->u.DmaChannel;
|
|||
|
RPartialDesc.u.Dma.Port = CurrentResource->u.DmaPort;
|
|||
|
|
|||
|
RtlCopyMemory(&TPartialDesc, &RPartialDesc, sizeof(TPartialDesc));
|
|||
|
TPartialDesc.u.Dma.Channel = CurrentResource->u.DmaChannel;
|
|||
|
TPartialDesc.u.Dma.Port = CurrentResource->u.DmaPort;
|
|||
|
|
|||
|
break;
|
|||
|
|
|||
|
default:
|
|||
|
|
|||
|
//
|
|||
|
// Got a resource we don't know. Bail out!
|
|||
|
//
|
|||
|
|
|||
|
goto NextResource;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Include the current resource in the HAL list.
|
|||
|
//
|
|||
|
|
|||
|
if (pRFullDesc->InterfaceType != CurrentBus->BusType) {
|
|||
|
|
|||
|
//
|
|||
|
// Interface type changed, add another full section
|
|||
|
//
|
|||
|
|
|||
|
RawResourceList->Count++;
|
|||
|
TranslatedResourceList->Count++;
|
|||
|
|
|||
|
pRFullDesc = (PCM_FULL_RESOURCE_DESCRIPTOR)pRCurLoc;
|
|||
|
pTFullDesc = (PCM_FULL_RESOURCE_DESCRIPTOR)pTCurLoc;
|
|||
|
|
|||
|
pRFullDesc->InterfaceType = CurrentBus->BusType;
|
|||
|
pTFullDesc->InterfaceType = CurrentBus->BusType;
|
|||
|
|
|||
|
pRPartList = &pRFullDesc->PartialResourceList;
|
|||
|
pTPartList = &pTFullDesc->PartialResourceList;
|
|||
|
|
|||
|
//
|
|||
|
// Bump current location pointers up
|
|||
|
//
|
|||
|
|
|||
|
pRCurLoc = pRFullDesc->PartialResourceList.PartialDescriptors;
|
|||
|
pTCurLoc = pTFullDesc->PartialResourceList.PartialDescriptors;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Add current resource in.
|
|||
|
//
|
|||
|
|
|||
|
pRPartList->Count++;
|
|||
|
pTPartList->Count++;
|
|||
|
RtlCopyMemory(pRCurLoc, &RPartialDesc, sizeof(RPartialDesc));
|
|||
|
RtlCopyMemory(pTCurLoc, &TPartialDesc, sizeof(TPartialDesc));
|
|||
|
|
|||
|
pRCurLoc++;
|
|||
|
pTCurLoc++;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Finished with this resource, move to the next one.
|
|||
|
//
|
|||
|
|
|||
|
NextResource:
|
|||
|
CurrentResource = CurrentResource->Next;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Finished with this bus, move to the next one.
|
|||
|
//
|
|||
|
|
|||
|
CurrentBus = CurrentBus->Next;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Do the actual reporting.
|
|||
|
//
|
|||
|
|
|||
|
ListSize = (ULONG)(((PUCHAR)pRCurLoc) - ((PUCHAR)RawResourceList));
|
|||
|
|
|||
|
//
|
|||
|
// The HAL's resource usage structures have been built
|
|||
|
// Sort the partial lists based on the Raw resource values.
|
|||
|
//
|
|||
|
|
|||
|
pRFullDesc = RawResourceList->List;
|
|||
|
pTFullDesc = TranslatedResourceList->List;
|
|||
|
|
|||
|
for (i=0; i < RawResourceList->Count; i++) {
|
|||
|
|
|||
|
pRCurLoc = pRFullDesc->PartialResourceList.PartialDescriptors;
|
|||
|
pTCurLoc = pTFullDesc->PartialResourceList.PartialDescriptors;
|
|||
|
Count = pRFullDesc->PartialResourceList.Count;
|
|||
|
|
|||
|
for (j=0; j < Count; j++) {
|
|||
|
HalpGetResourceSortValue (pRCurLoc, &curscale, &curvalue);
|
|||
|
|
|||
|
pRSortLoc = pRCurLoc;
|
|||
|
pTSortLoc = pTCurLoc;
|
|||
|
|
|||
|
for (k=j; k < Count; k++) {
|
|||
|
HalpGetResourceSortValue (pRSortLoc, &sortscale, &sortvalue);
|
|||
|
|
|||
|
if (sortscale < curscale ||
|
|||
|
(sortscale == curscale &&
|
|||
|
(sortvalue.QuadPart < curvalue.QuadPart)) ){
|
|||
|
|
|||
|
//
|
|||
|
// Swap the elements.
|
|||
|
//
|
|||
|
|
|||
|
RtlCopyMemory (&RPartialDesc, pRCurLoc, sizeof RPartialDesc);
|
|||
|
RtlCopyMemory (pRCurLoc, pRSortLoc, sizeof RPartialDesc);
|
|||
|
RtlCopyMemory (pRSortLoc, &RPartialDesc, sizeof RPartialDesc);
|
|||
|
|
|||
|
//
|
|||
|
// Swap translated descriptor as well.
|
|||
|
//
|
|||
|
|
|||
|
RtlCopyMemory (&TPartialDesc, pTCurLoc, sizeof TPartialDesc);
|
|||
|
RtlCopyMemory (pTCurLoc, pTSortLoc, sizeof TPartialDesc);
|
|||
|
RtlCopyMemory (pTSortLoc, &TPartialDesc, sizeof TPartialDesc);
|
|||
|
|
|||
|
//
|
|||
|
// Get new curscale & curvalue.
|
|||
|
//
|
|||
|
|
|||
|
HalpGetResourceSortValue (pRCurLoc, &curscale, &curvalue);
|
|||
|
}
|
|||
|
|
|||
|
pRSortLoc++;
|
|||
|
pTSortLoc++;
|
|||
|
}
|
|||
|
|
|||
|
pRCurLoc++;
|
|||
|
pTCurLoc++;
|
|||
|
}
|
|||
|
|
|||
|
pRFullDesc = (PCM_FULL_RESOURCE_DESCRIPTOR) pRCurLoc;
|
|||
|
pTFullDesc = (PCM_FULL_RESOURCE_DESCRIPTOR) pTCurLoc;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Inform the IO system of our resources.
|
|||
|
//
|
|||
|
|
|||
|
IoReportHalResourceUsage(HalName,
|
|||
|
RawResourceList,
|
|||
|
TranslatedResourceList,
|
|||
|
ListSize);
|
|||
|
|
|||
|
ExFreePool (RawResourceList);
|
|||
|
ExFreePool (TranslatedResourceList);
|
|||
|
|
|||
|
//
|
|||
|
// Free all registered buses.
|
|||
|
//
|
|||
|
|
|||
|
while (HalpBusUsageList) {
|
|||
|
|
|||
|
CurrentBus = HalpBusUsageList;
|
|||
|
HalpBusUsageList = HalpBusUsageList->Next;
|
|||
|
ExFreePool(CurrentBus);
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Free all registered resources.
|
|||
|
//
|
|||
|
|
|||
|
while (HalpResourceUsageList) {
|
|||
|
|
|||
|
CurrentResource = HalpResourceUsageList;
|
|||
|
HalpResourceUsageList = HalpResourceUsageList->Next;
|
|||
|
ExFreePool(CurrentResource);
|
|||
|
}
|
|||
|
}
|
|||
|
|