Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

1004 lines
29 KiB

/*++
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
//
AgpWmiDeRegistration(Extension);
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);
//
// Return AGP info for target device
//
if (Extension->Type == AgpTargetFilter) {
return AgpSystemControl(DeviceObject, Irp);
}
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;
//
// 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;
}