📄 dispatch.c
字号:
// 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 + -