📄 dispatch.c
字号:
/*++
Copyright (c) 1997 Microsoft Corporation
Module Name:
dispatch.c
Abstract:
IRP dispatching routines for the common AGPLIB library
Author:
John Vert (jvert) 10/25/1997
Revision History:
Elliot Shmukler (elliots) 3/24/1999 - Added support for "favored" memory
ranges for AGP physical memory allocation,
fixed some bugs.
--*/
#include "agplib.h"
//
// Two flavors of each dispatch routine, one for the target (AGP bridge) filter and
// one for the master (video card) filter.
//
NTSTATUS
AgpTargetDispatchPnp(
IN PDEVICE_OBJECT DeviceObject,
IN OUT PIRP Irp,
IN PTARGET_EXTENSION Extension
);
NTSTATUS
AgpMasterDispatchPnp(
IN PDEVICE_OBJECT DeviceObject,
IN OUT PIRP Irp,
IN PMASTER_EXTENSION Extension
);
NTSTATUS
AgpTargetDispatchPower(
IN PDEVICE_OBJECT DeviceObject,
IN OUT PIRP Irp,
IN PTARGET_EXTENSION Extension
);
NTSTATUS
AgpMasterDispatchPower(
IN PDEVICE_OBJECT DeviceObject,
IN OUT PIRP Irp,
IN PMASTER_EXTENSION Extension
);
NTSTATUS
AgpCancelMasterRemove(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN PMASTER_EXTENSION Extension
);
NTSTATUS
AgpMasterPowerUpCompletion(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN PMASTER_EXTENSION Extension
);
NTSTATUS
AgpTargetPowerUpCompletion(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN PTARGET_EXTENSION Extension
);
#ifdef ALLOC_PRAGMA
#pragma alloc_text(PAGE, AgpDispatchPnp)
#pragma alloc_text(PAGE, AgpDispatchDeviceControl)
#pragma alloc_text(PAGE, AgpDispatchWmi)
#pragma alloc_text(PAGE, AgpTargetDispatchPnp)
#pragma alloc_text(PAGE, AgpMasterDispatchPnp)
#pragma alloc_text(PAGE, AgpCancelMasterRemove)
#endif
NTSTATUS
AgpDispatchPnp(
IN PDEVICE_OBJECT DeviceObject,
IN OUT PIRP Irp
)
/*++
Routine Description:
Main dispatch routine for PNP irps sent to the AGP bus filter driver
Arguments:
DeviceObject - Supplies the AGP device object
Irp - Supplies the PNP Irp.
Return Value:
NTSTATUS
--*/
{
PCOMMON_EXTENSION Extension = DeviceObject->DeviceExtension;
PAGED_CODE();
//
// We're deleted, fail the irp
//
if (Extension->Deleted == TRUE) {
Irp->IoStatus.Status = STATUS_DELETE_PENDING;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_DELETE_PENDING;
}
ASSERT(Extension->AttachedDevice != NULL);
if (Extension->Type == AgpTargetFilter) {
return(AgpTargetDispatchPnp(DeviceObject,
Irp,
DeviceObject->DeviceExtension));
} else {
ASSERT(Extension->Type == AgpMasterFilter);
return(AgpMasterDispatchPnp(DeviceObject,
Irp,
DeviceObject->DeviceExtension));
}
}
NTSTATUS
AgpDispatchPower(
IN PDEVICE_OBJECT DeviceObject,
IN OUT PIRP Irp
)
/*++
Routine Description:
Main dispatch routine for power irps sent to the AGP bus filter driver
Arguments:
DeviceObject - Supplies the AGP device object
Irp - Supplies the power Irp.
Return Value:
NTSTATUS
--*/
{
PCOMMON_EXTENSION Extension = DeviceObject->DeviceExtension;
//
// We're deleted, fail the irp
//
if (Extension->Deleted == TRUE) {
Irp->IoStatus.Status = STATUS_DELETE_PENDING;
PoStartNextPowerIrp(Irp);
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_DELETE_PENDING;
}
ASSERT(Extension->AttachedDevice != NULL);
if (Extension->Type == AgpTargetFilter) {
return(AgpTargetDispatchPower(DeviceObject,
Irp,
DeviceObject->DeviceExtension));
} else {
ASSERT(Extension->Type == AgpMasterFilter);
return(AgpMasterDispatchPower(DeviceObject,
Irp,
DeviceObject->DeviceExtension));
}
}
NTSTATUS
AgpTargetDispatchPnp(
IN PDEVICE_OBJECT DeviceObject,
IN OUT PIRP Irp,
IN PTARGET_EXTENSION Extension
)
/*++
Routine Description:
Dispatch routine for PNP irps sent to the AGP bus filter driver
attached to the target (AGP bridge) PDO.
Arguments:
DeviceObject - Supplies the AGP target device object
Irp - Supplies the PNP Irp.
Extension - Supplies the AGP target device extension
Return Value:
NTSTATUS
--*/
{
NTSTATUS Status = STATUS_NOT_SUPPORTED;
PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation( Irp );
PAGED_CODE();
// AGPLOG(AGP_IRPTRACE,
// ("AgpTargetDispatchPnp: IRP 0x%x\n", irpStack->MinorFunction));
switch (irpStack->MinorFunction) {
case IRP_MN_FILTER_RESOURCE_REQUIREMENTS:
AGPLOG(AGP_NOISE,
("AgpTargetDispatchPnp: IRP_MN_FILTER_RESOURCE_REQUIREMENTS to %08lx\n",
DeviceObject));
Status = AgpFilterResourceRequirements(DeviceObject, Irp, Extension);
break;
case IRP_MN_QUERY_RESOURCES:
AGPLOG(AGP_NOISE,
("AgpTargetDispatchPnp: IRP_MN_QUERY_RESOURCES to %08lx\n",
DeviceObject));
//
// We must handle this IRP on the way back so we can add the AGP
// resources on to it. Set a completion routine.
//
IoCopyCurrentIrpStackLocationToNext(Irp);
IoSetCompletionRoutine(Irp,
AgpQueryResources,
Extension,
TRUE,
FALSE,
FALSE);
Status = IoCallDriver(Extension->CommonExtension.AttachedDevice, Irp);
return Status ;
case IRP_MN_QUERY_DEVICE_RELATIONS:
if (irpStack->Parameters.QueryDeviceRelations.Type == BusRelations) {
KEVENT event;
KeInitializeEvent(&event, NotificationEvent, FALSE);
//
// We must handle this IRP on the way back so that we can attach
// a filter to any child PDOs of our PCI-PCI bridge.
//
IoCopyCurrentIrpStackLocationToNext(Irp);
IoSetCompletionRoutine(Irp,
AgpSetEventCompletion,
&event,
TRUE,
TRUE,
TRUE);
Status = IoCallDriver(Extension->CommonExtension.AttachedDevice, Irp);
//
// If we did things asynchronously then wait on our event
//
if (Status == STATUS_PENDING) {
//
// We do a KernelMode wait so that our stack where the
// event is doesn't get paged out!
//
KeWaitForSingleObject(&event,
Executive,
KernelMode,
FALSE,
NULL);
Status = Irp->IoStatus.Status;
}
if (NT_SUCCESS(Status)) {
Status = AgpAttachDeviceRelations(DeviceObject,
Irp,
Extension);
Irp->IoStatus.Status = Status;
}
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return Status;
} else {
break;
}
case IRP_MN_START_DEVICE:
//
// We need to hook this in order to filter out any AGP
// resources that have been added.
//
return(AgpStartTarget(Irp, Extension));
case IRP_MN_QUERY_REMOVE_DEVICE:
case IRP_MN_QUERY_STOP_DEVICE:
case IRP_MN_CANCEL_REMOVE_DEVICE:
//
// We can always succeed this.
//
Status = STATUS_SUCCESS;
break;
case IRP_MN_REMOVE_DEVICE:
AgpDisableAperture(GET_AGP_CONTEXT(Extension));
//
// Pass the irp down
//
IoSkipCurrentIrpStackLocation(Irp);
Status = IoCallDriver(Extension->CommonExtension.AttachedDevice, Irp);
//
// Clean up and delete ourselves
//
Extension->CommonExtension.Deleted = TRUE;
IoDetachDevice(Extension->CommonExtension.AttachedDevice);
Extension->CommonExtension.AttachedDevice = NULL;
RELEASE_BUS_INTERFACE(Extension);
if (Extension->FavoredMemory.Ranges) {
ExFreePool(Extension->FavoredMemory.Ranges);
}
if (Extension->Resources) {
ExFreePool(Extension->Resources);
}
if (Extension->ResourcesTranslated) {
ExFreePool(Extension->ResourcesTranslated);
}
ExFreePool(Extension->Lock);;
IoDeleteDevice(DeviceObject);
return(Status);
case IRP_MN_STOP_DEVICE:
AgpDisableAperture(GET_AGP_CONTEXT(Extension));
Status = STATUS_SUCCESS;
break; // forward irp down the stack
}
ASSERT(Status != STATUS_PENDING);
if (Status != STATUS_NOT_SUPPORTED) {
Irp->IoStatus.Status = Status;
}
if (NT_SUCCESS(Status) || (Status == STATUS_NOT_SUPPORTED)) {
//
// Forward IRP to PCI driver
//
IoSkipCurrentIrpStackLocation(Irp);
return(IoCallDriver(Extension->CommonExtension.AttachedDevice, Irp));
} else {
Status = Irp->IoStatus.Status;
IoCompleteRequest(Irp, IO_NO_INCREMENT) ;
return Status ;
}
}
NTSTATUS
AgpDispatchDeviceControl(
IN PDEVICE_OBJECT DeviceObject,
IN OUT PIRP Irp
)
/*++
Routine Description:
Main dispatch routine for device control irps sent to the AGP bus filter driver
AGP currently does not support any device controls. So we just pass everything
down and hope the PDO knows what to do with it.
Arguments:
DeviceObject - Supplies the AGP device object
Irp - Supplies the power Irp.
Return Value:
NTSTATUS
--*/
{
PCOMMON_EXTENSION Extension = DeviceObject->DeviceExtension;
PAGED_CODE();
//
// We're deleted, fail the irp
//
if (Extension->Deleted == TRUE) {
Irp->IoStatus.Status = STATUS_DELETE_PENDING;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_DELETE_PENDING;
}
ASSERT(Extension->AttachedDevice != NULL);
IoSkipCurrentIrpStackLocation(Irp);
return(IoCallDriver(Extension->AttachedDevice, Irp));
}
NTSTATUS
AgpDispatchWmi(
IN PDEVICE_OBJECT DeviceObject,
IN OUT PIRP Irp
)
/*++
Routine Description:
Main dispatch routine for system control irps sent to the AGP bus filter
driver.
AGP currently does not support any WMI IRPs, so we just pass everything
down and hope the PDO knows what to do with it.
Arguments:
DeviceObject - Supplies the AGP device object
Irp - Supplies the power Irp.
Return Value:
NTSTATUS
--*/
{
PCOMMON_EXTENSION Extension = DeviceObject->DeviceExtension;
PAGED_CODE();
//
// We're deleted, fail the irp
//
if (Extension->Deleted == TRUE) {
Irp->IoStatus.Status = STATUS_DELETE_PENDING;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_DELETE_PENDING;
}
ASSERT(Extension->AttachedDevice != NULL);
IoSkipCurrentIrpStackLocation(Irp);
return(IoCallDriver(Extension->AttachedDevice, Irp));
}
NTSTATUS
AgpTargetDispatchPower(
IN PDEVICE_OBJECT DeviceObject,
IN OUT PIRP Irp,
IN PTARGET_EXTENSION Extension
)
{
PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation( Irp );
AGPLOG(AGP_IRPTRACE,
("AgpTargetDispatchPower: IRP 0x%x\n", irpStack->MinorFunction));
//
// All we keep track of are Dx states. PCI 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;
//
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -