⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 resource.c

📁 agp windows驱动WDM,WINDDK开发
💻 C
📖 第 1 页 / 共 2 页
字号:
/*++

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 + -