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

📄 dispatch.c

📁 agp windows驱动WDM,WINDDK开发
💻 C
📖 第 1 页 / 共 2 页
字号:
        // We need to reinitialize the target when this IRP has been completed
        // by the lower drivers. Set up our completion handler to finish this.
        //
        IoCopyCurrentIrpStackLocationToNext(Irp);
        IoSetCompletionRoutine(Irp,
                               AgpTargetPowerUpCompletion,
                               Extension,
                               TRUE,
                               FALSE,
                               FALSE);

        IoMarkIrpPending(Irp);
        PoStartNextPowerIrp(Irp);
        Status = PoCallDriver(Extension->CommonExtension.AttachedDevice, Irp);
        return STATUS_PENDING;
    }
    //
    // Just forward to target device
    //
    PoStartNextPowerIrp(Irp);
    IoSkipCurrentIrpStackLocation(Irp);
    return(PoCallDriver(Extension->CommonExtension.AttachedDevice, Irp));
}


NTSTATUS
AgpMasterDispatchPnp(
    IN PDEVICE_OBJECT DeviceObject,
    IN OUT PIRP Irp,
    IN PMASTER_EXTENSION Extension
    )
/*++

Routine Description:

    Dispatch routine for PNP irps sent to the AGP bus filter driver
    attached to the device PDOs.

Arguments:

    DeviceObject - Supplies the AGP device object

    Irp - Supplies the PNP Irp.

    Extension - Supplies the AGP bridge device extension

Return Value:

    NTSTATUS

--*/

{
    PIO_STACK_LOCATION  irpStack        = IoGetCurrentIrpStackLocation( Irp );
    PAGP_BUS_INTERFACE_STANDARD Interface;
    NTSTATUS Status;

    PAGED_CODE();

    AGPLOG(AGP_IRPTRACE,
           ("AgpMasterDispatchPnp: IRP 0x%x\n", irpStack->MinorFunction));

    switch (irpStack->MinorFunction) {
        case IRP_MN_QUERY_INTERFACE:

#if 0
            AGPLOG(AGP_IRPTRACE,
                   ("\tSize=0x%x, Version=%d\n"
                    "\tGUID=0x%08x-0x%04x-0x%04x-0x%02x-"
                    "0x%02x-0x%02x-0x%02x-0x%02x-0x%02x-0x%02x-0x%02x\n",
                    irpStack->Parameters.QueryInterface.Size,
                    irpStack->Parameters.QueryInterface.Version,
                    *(PULONG)irpStack->Parameters.QueryInterface.InterfaceType,
                    *((PUSHORT)irpStack->Parameters.QueryInterface.InterfaceType + 2),
                    *((PUSHORT)irpStack->Parameters.QueryInterface.InterfaceType + 3),
                    *((PUCHAR)irpStack->Parameters.QueryInterface.InterfaceType + 8),
                    *((PUCHAR)irpStack->Parameters.QueryInterface.InterfaceType + 9),
                    *((PUCHAR)irpStack->Parameters.QueryInterface.InterfaceType + 10),

                    *((PUCHAR)irpStack->Parameters.QueryInterface.InterfaceType + 11),
                    *((PUCHAR)irpStack->Parameters.QueryInterface.InterfaceType + 12),
                    *((PUCHAR)irpStack->Parameters.QueryInterface.InterfaceType + 13),
                    *((PUCHAR)irpStack->Parameters.QueryInterface.InterfaceType + 14),
                    *((PUCHAR)irpStack->Parameters.QueryInterface.InterfaceType + 15)));

#endif

            //
            // The only IRP we look for here is IRP_MN_QUERY_INTERFACE for
            // GUID_AGP_BUS_INTERFACE_STANDARD.
            //
            if ((RtlEqualMemory(
                irpStack->Parameters.QueryInterface.InterfaceType,
                &GUID_AGP_BUS_INTERFACE_STANDARD,
                sizeof(GUID))) &&
                (((irpStack->Parameters.QueryInterface.Size >=
                   sizeof(AGP_BUS_INTERFACE_STANDARD)) &&
                  (irpStack->Parameters.QueryInterface.Version ==
                   AGP_BUS_INTERFACE_V2)) ||
                 ((irpStack->Parameters.QueryInterface.Size >=
                   AGP_BUS_INTERFACE_V1_SIZE) &&
                  (irpStack->Parameters.QueryInterface.Version ==
                   AGP_BUS_INTERFACE_V1)))) {

                Interface = (PAGP_BUS_INTERFACE_STANDARD)irpStack->Parameters.QueryInterface.Interface;

                Interface->Version =
                    irpStack->Parameters.QueryInterface.Version;
                Interface->AgpContext = Extension;
                Interface->InterfaceReference = AgpInterfaceReference;
                Interface->InterfaceDereference = AgpInterfaceDereference;
                Interface->ReserveMemory = AgpInterfaceReserveMemory;
                Interface->ReleaseMemory = AgpInterfaceReleaseMemory;
                Interface->CommitMemory = AgpInterfaceCommitMemory;
                Interface->FreeMemory = AgpInterfaceFreeMemory;
                Interface->GetMappedPages = AgpInterfaceGetMappedPages;

                if (Interface->Version < AGP_BUS_INTERFACE_V2) {
                    Interface->Size = AGP_BUS_INTERFACE_V1_SIZE;
                } else {
                    Interface->Size = sizeof(AGP_BUS_INTERFACE_STANDARD);
                    Interface->SetRate = AgpInterfaceSetRate;
                }

                Interface->Capabilities = Extension->Capabilities;

                //
                // Complete the IRP successfully
                //
                Irp->IoStatus.Status = STATUS_SUCCESS;

                // AGPLOG(AGP_IRPTRACE, ("\tOK.\n"));
            } // else { AGPLOG(AGP_IRPTRACE, ("\tNO!\n")); }
            break;

        case IRP_MN_QUERY_REMOVE_DEVICE:
        case IRP_MN_QUERY_STOP_DEVICE:
            if (irpStack->MinorFunction == IRP_MN_QUERY_REMOVE_DEVICE) {
                Extension->RemovePending = TRUE;
            } else {
                Extension->StopPending = TRUE;
            }
            //
            // If we have given out any interfaces or there are some reserved
            // pages, we cannot stop.
            //
            if ((Extension->InterfaceCount > 0) ||
                (Extension->ReservedPages > 0)) {
                AGPLOG(AGP_NOISE,
                       ("AgpMasterDispatchPnp: failing %s due to outstanding interfaces\n",
                        (irpStack->MinorFunction == IRP_MN_QUERY_REMOVE_DEVICE)
                            ? "IRP_MN_QUERY_REMOVE_DEVICE"
                            : "IRP_MN_QUERY_STOP_DEVICE"
                       ));

                Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
                IoCompleteRequest(Irp, IO_NO_INCREMENT);
                return(STATUS_UNSUCCESSFUL);
            } else {
                //
                // We can succeed this, mark our extension as being in limbo so we do
                // not give out any interfaces or anything until we get removed or
                // get a cancel.
                //
                InterlockedIncrement(&Extension->DisableCount);
                break;  // forward irp down the stack
            }

        case IRP_MN_CANCEL_REMOVE_DEVICE:
            //
            // This IRP must be handled on the way back up the stack.
            // Set a completion routine to reenable the device.
            //
            if (Extension->RemovePending) {
                Extension->RemovePending = FALSE;
                IoCopyCurrentIrpStackLocationToNext(Irp);
                IoSetCompletionRoutine(Irp,
                                       AgpCancelMasterRemove,
                                       Extension,
                                       TRUE,
                                       FALSE,
                                       FALSE);
                return(IoCallDriver(Extension->CommonExtension.AttachedDevice, Irp));
            } else {
                //
                // This is a cancel-remove for a query-remove IRP we never saw.
                // Ignore it.
                //
                break;
            }

        case IRP_MN_CANCEL_STOP_DEVICE:
            //
            // This IRP must be handled on the way back up the stack.
            // Set a completion routine to reenable the device.
            //
            if (Extension->StopPending) {
                Extension->StopPending = FALSE;
                IoCopyCurrentIrpStackLocationToNext(Irp);
                IoSetCompletionRoutine(Irp,
                                       AgpCancelMasterRemove,
                                       Extension,
                                       TRUE,
                                       FALSE,
                                       FALSE);
                return(IoCallDriver(Extension->CommonExtension.AttachedDevice, Irp));
            } else {
                //
                // This is a cancel-stop for a query-stop IRP we never saw.
                // Ignore it.
                //
                break;
            }

        case IRP_MN_REMOVE_DEVICE:
            AGPLOG(AGP_NOISE,
                   ("AgpMasterDispatchPnp: removing device due to IRP_MN_REMOVE_DEVICE\n"));

            //
            // PNP is supposed to send us a QUERY_REMOVE before any REMOVE. That is
            // when we check that we are actually in a state where we can be removed.
            // Like all PNP rules, there is an exception - if the START is failed
            // after we have succeeded it, then we get a REMOVE without a QUERY_REMOVE.
            // Obviously this is totally fatal if we have given out interfaces or
            // have pages mapped in the GART. Not much we can do about it then.
            //
            ASSERT(Extension->InterfaceCount == 0);
            ASSERT(Extension->ReservedPages == 0);

            //
            // Pass the IRP down.
            //
            IoSkipCurrentIrpStackLocation(Irp);
            Status = IoCallDriver(Extension->CommonExtension.AttachedDevice, Irp);

            //
            // Clean up and delete ourselves
            //
            Extension->Target->ChildDevice = NULL;
            Extension->CommonExtension.Deleted = TRUE;
            IoDetachDevice(Extension->CommonExtension.AttachedDevice);
            Extension->CommonExtension.AttachedDevice = NULL;
            RELEASE_BUS_INTERFACE(Extension);
            IoDeleteDevice(DeviceObject);
            return(Status);

        case IRP_MN_STOP_DEVICE:
            AGPLOG(AGP_NOISE,
                   ("AgpMasterDispatchPnp: stopping device due to IRP_MN_STOP_DEVICE\n"));
            ASSERT(Extension->DisableCount);

            //
            // Just pass the IRP on down
            //
            break;

        case IRP_MN_START_DEVICE:
            AGPLOG(AGP_NOISE,
                   ("AgpMasterDispatchPnp: starting device due to IRP_MN_START_DEVICE\n"));
            ASSERT(Extension->DisableCount);
            InterlockedDecrement(&Extension->DisableCount);
            break;  // forward IRP down the stack
    }

    //
    // Just forward to target device
    //
    IoSkipCurrentIrpStackLocation(Irp);
    return(IoCallDriver(Extension->CommonExtension.AttachedDevice, Irp));
}

NTSTATUS
AgpMasterDispatchPower(
    IN PDEVICE_OBJECT DeviceObject,
    IN OUT PIRP Irp,
    IN PMASTER_EXTENSION Extension
    )
{
    PIO_STACK_LOCATION  irpStack        = IoGetCurrentIrpStackLocation( Irp );

    AGPLOG(AGP_IRPTRACE,
           ("AgpMasterDispatchPower: IRP 0x%x\n", irpStack->MinorFunction));

    //
    // All we keep track of are Dx states. Videoport is responsible for mapping
    // S-states into D states.
    //
    if ((irpStack->MinorFunction == IRP_MN_SET_POWER) &&
        (irpStack->Parameters.Power.Type == DevicePowerState) &&
        (irpStack->Parameters.Power.State.DeviceState == PowerDeviceD0)) {

        NTSTATUS Status;

        //
        // We need to reinitialize the master when this IRP has been completed
        // by the lower drivers. Set up a completion routine.
        //
        IoCopyCurrentIrpStackLocationToNext(Irp);
        IoSetCompletionRoutine(Irp,
                               AgpMasterPowerUpCompletion,
                               Extension,
                               TRUE,
                               FALSE,
                               FALSE);

        IoMarkIrpPending(Irp);
        PoStartNextPowerIrp(Irp);
        Status = PoCallDriver(Extension->CommonExtension.AttachedDevice, Irp);
        return STATUS_PENDING;
    }

    //
    // Just forward to target device
    //
    PoStartNextPowerIrp(Irp);
    IoSkipCurrentIrpStackLocation(Irp);
    return(PoCallDriver(Extension->CommonExtension.AttachedDevice, Irp));
}


NTSTATUS
AgpMasterPowerUpCompletion(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp,
    IN PMASTER_EXTENSION Extension
    )
/*++

Routine Description:

    Powerup completion routine for the master device. It reinitializes the
    master registers.

Arguments:

    DeviceObject - supplies the master device object.

    Irp - Supplies the IRP_MN_SET_POWER irp.

    Extension - Supplies the master extension

Return Value:

    Status

--*/

{
    NTSTATUS Status;
    ULONG CurrentCapabilities;

    if (Irp->PendingReturned) {
        IoMarkIrpPending(Irp);
    }

    Status = AgpInitializeMaster(GET_AGP_CONTEXT_FROM_MASTER(Extension),
                                 &CurrentCapabilities);
    ASSERT(CurrentCapabilities == Extension->Capabilities);
    if (!NT_SUCCESS(Status)) {
        Irp->IoStatus.Status = Status;
    }

    return STATUS_SUCCESS;
}


NTSTATUS
AgpTargetPowerUpCompletion(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp,
    IN PTARGET_EXTENSION Extension
    )
/*++

Routine Description:

    Powerup completion routine for the target device. It reinitializes the
    GART aperture

Arguments:

    DeviceObject - supplies the master device object.

    Irp - Supplies the IRP_MN_SET_POWER irp.

    Extension - Supplies the target extension

Return Value:

    Status

--*/

{
    NTSTATUS Status;

    if (Irp->PendingReturned) {
        IoMarkIrpPending(Irp);
    }

    //
    // Now it is safe to reinitialize the target. All we do here
    // is reset the aperture
    //
    if (Extension->GartLengthInPages != 0) {
        Status = AgpSetAperture(GET_AGP_CONTEXT(Extension),
                                Extension->GartBase,
                                Extension->GartLengthInPages);
        if (!NT_SUCCESS(Status)) {
            Irp->IoStatus.Status = Status;
        }
    }

    return STATUS_SUCCESS;
}


NTSTATUS
AgpCancelMasterRemove(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp,
    IN PMASTER_EXTENSION Extension
    )
/*++

Routine Description:

    Completion routine for IRP_MN_CANCEL_REMOVE_DEVICE. This is required
    since we cannot reenable AGP until the lower levels have completed their
    CANCEL_REMOVE processing.

Arguments:

    DeviceObject - Supplies the device object

    Irp - Supplies the IRP

    Extension - Supplies the master extension

Return Value:

    NTSTATUS

--*/

{
    if (Irp->PendingReturned) {
        IoMarkIrpPending(Irp);
    }

    ASSERT(Extension->DisableCount > 0);
    InterlockedDecrement(&Extension->DisableCount);
    return(STATUS_SUCCESS);
}


NTSTATUS
AgpSetEventCompletion(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp,
    IN PKEVENT Event
    )
/*++

Routine Description:

    This routine is used as a completion routine when an IRP is passed
    down the stack but more processing must be done on the way back up.
    The effect of using this as a completion routine is that the IRP
    will not be destroyed in IoCompleteRequest as called by the lower
    level object.  The event which is a KEVENT is signaled to allow
    processing to continue

Arguments:

    DeviceObject - Supplies the device object

    Irp - The IRP we are processing

    Event - Supplies the event to be signaled

Return Value:

    STATUS_MORE_PROCESSING_REQUIRED

--*/

{
    ASSERT(Event);

    //
    // This can be called at DISPATCH_LEVEL so must not be paged
    //
    KeSetEvent(Event, IO_NO_INCREMENT, FALSE);

    return STATUS_MORE_PROCESSING_REQUIRED;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -