- Forward IRPs to our PDO instead of just completing them
- Handle IRP_MN_START_DEVICE on the way back up the stack (allows the PDO code to assign resources to the bus)
- Add some synchronous IRP forwarding copied from i8042prt

svn path=/trunk/; revision=46996
This commit is contained in:
Cameron Gutman 2010-04-22 20:35:58 +00:00
parent af6172876c
commit c0d168b15a

View file

@ -16,6 +16,46 @@
/*** PRIVATE *****************************************************************/ /*** PRIVATE *****************************************************************/
static IO_COMPLETION_ROUTINE ForwardIrpAndWaitCompletion;
static NTSTATUS NTAPI
ForwardIrpAndWaitCompletion(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN PVOID Context)
{
UNREFERENCED_PARAMETER(DeviceObject);
if (Irp->PendingReturned)
KeSetEvent((PKEVENT)Context, IO_NO_INCREMENT, FALSE);
return STATUS_MORE_PROCESSING_REQUIRED;
}
NTSTATUS NTAPI
ForwardIrpAndWait(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
{
KEVENT Event;
NTSTATUS Status;
PDEVICE_OBJECT LowerDevice = ((PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->Ldo;
ASSERT(LowerDevice);
KeInitializeEvent(&Event, NotificationEvent, FALSE);
IoCopyCurrentIrpStackLocationToNext(Irp);
IoSetCompletionRoutine(Irp, ForwardIrpAndWaitCompletion, &Event, TRUE, TRUE, TRUE);
Status = IoCallDriver(LowerDevice, Irp);
if (Status == STATUS_PENDING)
{
Status = KeWaitForSingleObject(&Event, Suspended, KernelMode, FALSE, NULL);
if (NT_SUCCESS(Status))
Status = Irp->IoStatus.Status;
}
return Status;
}
static NTSTATUS static NTSTATUS
FdoLocateChildDevice( FdoLocateChildDevice(
PPCI_DEVICE *Device, PPCI_DEVICE *Device,
@ -466,7 +506,7 @@ FdoPnpControl(
{ {
PFDO_DEVICE_EXTENSION DeviceExtension; PFDO_DEVICE_EXTENSION DeviceExtension;
PIO_STACK_LOCATION IrpSp; PIO_STACK_LOCATION IrpSp;
NTSTATUS Status; NTSTATUS Status = Irp->IoStatus.Status;
DPRINT("Called\n"); DPRINT("Called\n");
@ -492,8 +532,13 @@ FdoPnpControl(
break; break;
#endif #endif
case IRP_MN_QUERY_DEVICE_RELATIONS: case IRP_MN_QUERY_DEVICE_RELATIONS:
Status = FdoQueryBusRelations(DeviceObject, Irp, IrpSp); if (IrpSp->Parameters.QueryDeviceRelations.Type != BusRelations)
break; break;
Status = FdoQueryBusRelations(DeviceObject, Irp, IrpSp);
Irp->IoStatus.Status = Status;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return Status;
#if 0 #if 0
case IRP_MN_QUERY_PNP_DEVICE_STATE: case IRP_MN_QUERY_PNP_DEVICE_STATE:
Status = STATUS_NOT_IMPLEMENTED; Status = STATUS_NOT_IMPLEMENTED;
@ -513,38 +558,37 @@ FdoPnpControl(
#endif #endif
case IRP_MN_START_DEVICE: case IRP_MN_START_DEVICE:
DPRINT("IRP_MN_START_DEVICE received\n"); DPRINT("IRP_MN_START_DEVICE received\n");
Status = ForwardIrpAndWait(DeviceObject, Irp);
if (NT_SUCCESS(Status))
Status = FdoStartDevice(DeviceObject, Irp); Status = FdoStartDevice(DeviceObject, Irp);
break;
Irp->IoStatus.Status = Status;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return Status;
case IRP_MN_STOP_DEVICE: case IRP_MN_STOP_DEVICE:
/* Currently not supported */ /* Currently not supported */
Status = STATUS_UNSUCCESSFUL; Status = STATUS_UNSUCCESSFUL;
break; Irp->IoStatus.Status = Status;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return Status;
#if 0 #if 0
case IRP_MN_SURPRISE_REMOVAL: case IRP_MN_SURPRISE_REMOVAL:
Status = STATUS_NOT_IMPLEMENTED; Status = STATUS_NOT_IMPLEMENTED;
break; break;
#endif #endif
case IRP_MN_FILTER_RESOURCE_REQUIREMENTS:
break;
case IRP_MN_REMOVE_DEVICE:
DPRINT1("IRP_MN_REMOVE_DEVICE is UNIMPLEMENTED!\n");
break;
default: default:
DPRINT1("Unknown IOCTL 0x%lx\n", IrpSp->MinorFunction); DPRINT1("Unknown IOCTL 0x%lx\n", IrpSp->MinorFunction);
/* fall through */
case IRP_MN_FILTER_RESOURCE_REQUIREMENTS:
/*
* Do NOT complete the IRP as it will be processed by the lower
* device object, which will complete the IRP
*/
IoSkipCurrentIrpStackLocation(Irp);
Status = IoCallDriver(DeviceExtension->Ldo, Irp);
return Status;
break; break;
} }
if (Status != STATUS_PENDING) {
if (Status != STATUS_NOT_IMPLEMENTED)
Irp->IoStatus.Status = Status; Irp->IoStatus.Status = Status;
IoCompleteRequest(Irp, IO_NO_INCREMENT); IoSkipCurrentIrpStackLocation(Irp);
} Status = IoCallDriver(DeviceExtension->Ldo, Irp);
DPRINT("Leaving. Status 0x%X\n", Status); DPRINT("Leaving. Status 0x%X\n", Status);