📄 resource.c
字号:
/*++
Copyright (c) 1997 Microsoft Corporation
Module Name:
resource.c
Abstract:
Common routines for handling resource requirements
Author:
John Vert (jvert) 10/25/1997
Revision History:
--*/
#include "agplib.h"
PCM_RESOURCE_LIST
ApSplitResourceList(
IN PCM_RESOURCE_LIST ResourceList,
OUT PCM_RESOURCE_LIST *NewResourceList
);
#ifdef ALLOC_PRAGMA
#pragma alloc_text(PAGE, AgpFilterResourceRequirements)
#pragma alloc_text(PAGE, AgpStartTarget)
#pragma alloc_text(PAGE, ApSplitResourceList)
#endif
static BOOLEAN ResourceConflict = FALSE;
NTSTATUS
AgpFilterResourceRequirements(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN PTARGET_EXTENSION Extension
)
/*++
Routine Description:
Completion routine for IRP_MN_QUERY_RESOURCE_REQUIREMENTS. This adds on the
AGP resource requirements.
Arguments:
DeviceObject - Supplies the device object
Irp - Supplies the IRP_MN_QUERY_RESOURCE_REQUIREMENTS Irp
Extension - Supplies the device extension
Return Value:
NTSTATUS
--*/
{
BOOLEAN SwapDescriptor;
ULONG SwapLength;
ULONG ApertureSize;
NTSTATUS Status;
ULONG AddCount;
PHYSICAL_ADDRESS CurrentBase;
PHYSICAL_ADDRESS MaxAddr;
ULONG CurrentSizeInPages;
PIO_RESOURCE_REQUIREMENTS_LIST OldRequirements;
PIO_RESOURCE_REQUIREMENTS_LIST NewRequirements;
ULONG NewSize;
ULONG Alternative;
PIO_RESOURCE_LIST OldResourceList;
PIO_RESOURCE_LIST NewResourceList;
PIO_RESOURCE_DESCRIPTOR Descriptor;
PIO_STACK_LOCATION IrpSp;
PIO_RESOURCE_LIST ApertureRequirements = NULL;
ULONG i;
PAGED_CODE();
AGPLOG(AGP_NOISE,
("AgpQueryResourceRequirements - IRP %08lx, resource %08lx\n",
Irp,
Irp->IoStatus.Information));
IrpSp = IoGetCurrentIrpStackLocation(Irp);
//
// Create a new resource requirements list with our current aperture
// settings tacked on the end.
//
OldRequirements = IrpSp->Parameters.FilterResourceRequirements.IoResourceRequirementList;
if (OldRequirements == NULL) {
//STATUS_INVALID_DEVICE_REQUEST
// PNP helpfully passes us a NULL pointer instead of an empty resource list
// when the bridge is disabled. In this case we will ignore this irp and not
// add on our requirements since they are not going to be used anyway.
//
return(STATUS_SUCCESS);
}
//
// Get the current GART aperture.
//
Status = AgpQueryAperture(GET_AGP_CONTEXT(Extension),
&CurrentBase,
&CurrentSizeInPages,
&ApertureRequirements);
if (!NT_SUCCESS(Status)) {
AGPLOG(AGP_CRITICAL,
("AgpQueryResourceRequirements - AgpQueryAperture %08lx failed %08lx\n",
Extension,
Status));
return(Status);
}
#if !defined(_IA64_)
ASSERT(ApertureRequirements != NULL);
#endif
ApertureSize = (CurrentSizeInPages * PAGE_SIZE);
MaxAddr.QuadPart = CurrentBase.QuadPart + ApertureSize - 1;
AGPLOG(AGP_NOISE,
("AgpQueryResourceRequirements - aperture at %I64x, length %08lx pages, Requirements %08lx\n",
CurrentBase.QuadPart,
CurrentSizeInPages,
ApertureRequirements));
//
// We will add IO_RESOURCE_DESCRIPTORs to each alternative.
//
// The first one is a private data type marked with our signature. This is
// a marker so that we know which descriptors are ours so we can remove
// them later.
//
// The second is the actual descriptor for the current aperture settings.
// This is marked as preferred.
//
// Following this is the requirements returned from AgpQueryAperture. These
// get marked as alternatives.
//
AddCount = 2;
//
// Enumerate the old list looking for any preferred descriptor that
// conflicts with our preferred settings; if we find one, then the BIOS
// is whack, and we will throw out our preferred descriptor, and let PnP
// choose from our alternates
//
ResourceConflict = FALSE;
OldResourceList = &OldRequirements->List[0];
for (Alternative = 0; Alternative < OldRequirements->AlternativeLists;
Alternative++) {
for (i = 0; i < OldResourceList->Count; i++) {
Descriptor = &OldResourceList->Descriptors[i];
if ((Descriptor->Option == IO_RESOURCE_PREFERRED) &&
(Descriptor->Type == CmResourceTypeMemory)) {
if (((Descriptor->u.Memory.MinimumAddress.QuadPart >=
CurrentBase.QuadPart) &&
(Descriptor->u.Memory.MinimumAddress.QuadPart <=
MaxAddr.QuadPart)) ||
((Descriptor->u.Memory.MaximumAddress.QuadPart >=
CurrentBase.QuadPart) &&
(Descriptor->u.Memory.MaximumAddress.QuadPart <=
MaxAddr.QuadPart)) ||
((Descriptor->u.Memory.MinimumAddress.QuadPart <
CurrentBase.QuadPart) &&
(Descriptor->u.Memory.MaximumAddress.QuadPart >
MaxAddr.QuadPart))) {
AGPLOG(AGP_CRITICAL,
("AgpQueryResourceRequirements - Conflicted "
"resource detected: %I64X - %I64X\n",
Descriptor->u.Memory.MinimumAddress.QuadPart,
Descriptor->u.Memory.MaximumAddress.QuadPart));
//
// This preferred descriptor is in conflic with our AGP
// preferred setting
//
#if defined(_IA64_)
AGPLOG(AGP_CRITICAL, ("Please contact system manufacturer "
"for a BIOS upgrade.\n"));
#else // _IA64_
AddCount = 1;
ResourceConflict = TRUE;
#endif // _IA64_
break;
}
}
}
OldResourceList = (PIO_RESOURCE_LIST)(OldResourceList->Descriptors +
OldResourceList->Count);
}
//
//
// For IA64, PnP cannot reassign the aperture base, so we can only use
// the "preferred" descriptor
//
#if !defined(_IA64_)
AddCount += ApertureRequirements->Count;
#endif // _IA64_
NewSize = OldRequirements->ListSize;
NewSize += sizeof(IO_RESOURCE_DESCRIPTOR) *
(AddCount * OldRequirements->AlternativeLists);
NewRequirements = ExAllocatePool(PagedPool, NewSize);
if (NewRequirements == NULL) {
ExFreePool(ApertureRequirements);
return(STATUS_INSUFFICIENT_RESOURCES);
}
NewRequirements->ListSize = NewSize;
NewRequirements->InterfaceType = OldRequirements->InterfaceType;
NewRequirements->BusNumber = OldRequirements->BusNumber;
NewRequirements->SlotNumber = OldRequirements->SlotNumber;
NewRequirements->AlternativeLists = OldRequirements->AlternativeLists;
//
// Append our requirement to each alternative resource list.
//
NewResourceList = &NewRequirements->List[0];
OldResourceList = &OldRequirements->List[0];
for (Alternative = 0; Alternative < OldRequirements->AlternativeLists; Alternative++) {
//
// Copy the old resource list into the new one.
//
NewResourceList->Version = OldResourceList->Version;
NewResourceList->Revision = OldResourceList->Revision;
NewResourceList->Count = OldResourceList->Count + AddCount;
RtlCopyMemory(&NewResourceList->Descriptors[0],
&OldResourceList->Descriptors[0],
OldResourceList->Count * sizeof(IO_RESOURCE_DESCRIPTOR));
Descriptor = &NewResourceList->Descriptors[OldResourceList->Count];
//
// Append the marker descriptor
//
Descriptor->Option = 0;
Descriptor->Flags = 0;
Descriptor->Type = CmResourceTypeDevicePrivate;
Descriptor->ShareDisposition = CmResourceShareDeviceExclusive;
Descriptor->u.DevicePrivate.Data[0] = AgpPrivateResource;
Descriptor->u.DevicePrivate.Data[1] = 1;
++Descriptor;
//
// Append the new descriptor
//
if (!ResourceConflict) {
Descriptor->Option = IO_RESOURCE_PREFERRED;
Descriptor->Flags = CM_RESOURCE_MEMORY_READ_WRITE |
CM_RESOURCE_MEMORY_PREFETCHABLE;
Descriptor->Type = CmResourceTypeMemory;
Descriptor->ShareDisposition = CmResourceShareDeviceExclusive;
Descriptor->u.Memory.Length = CurrentSizeInPages * PAGE_SIZE;
Descriptor->u.Memory.Alignment = CurrentSizeInPages * PAGE_SIZE;
Descriptor->u.Memory.MinimumAddress = CurrentBase;
Descriptor->u.Memory.MaximumAddress = MaxAddr;
++Descriptor;
}
//
// Append the alternatives
//
#if !defined(_IA64_)
SwapDescriptor = FALSE;
for (i = 0; i < ApertureRequirements->Count; i++) {
//
// Make sure this descriptor makes sense
//
ASSERT(ApertureRequirements->Descriptors[i].Flags ==
(CM_RESOURCE_MEMORY_READ_WRITE |
CM_RESOURCE_MEMORY_PREFETCHABLE));
ASSERT(ApertureRequirements->Descriptors[i].Type ==
CmResourceTypeMemory);
ASSERT(ApertureRequirements->Descriptors[i].ShareDisposition ==
CmResourceShareDeviceExclusive);
*Descriptor = ApertureRequirements->Descriptors[i];
//
// In this case we nuked our preferred descriptor so mark the
// first alternate as preferred
//
if ((i == 0) && ResourceConflict) {
Descriptor->Option = IO_RESOURCE_PREFERRED;
if (Descriptor->u.Memory.Length != ApertureSize) {
SwapLength = Descriptor->u.Memory.Length;
Descriptor->u.Memory.Length = ApertureSize;
Descriptor->u.Memory.Alignment = ApertureSize;
SwapDescriptor = TRUE;
}
} else {
Descriptor->Option = IO_RESOURCE_ALTERNATIVE;
if (SwapDescriptor) {
if (Descriptor->u.Memory.Length == ApertureSize) {
Descriptor->u.Memory.Length = SwapLength;
Descriptor->u.Memory.Alignment = SwapLength;
SwapDescriptor = FALSE;
}
}
}
++Descriptor;
}
#endif // _IA64_
//
// Advance to next resource list
//
NewResourceList = (PIO_RESOURCE_LIST)(NewResourceList->Descriptors + NewResourceList->Count);
OldResourceList = (PIO_RESOURCE_LIST)(OldResourceList->Descriptors + OldResourceList->Count);
}
AGPLOG(AGP_NOISE,
("AgpQueryResourceRequirements - IRP %p, old resources %p, new resources %p\n",
Irp,
OldRequirements,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -