From c0d168b15aeb3a5de1d71bc39d3f523fd71b18b7 Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Thu, 22 Apr 2010 20:35:58 +0000 Subject: [PATCH 1/1] [PCI] - 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 --- reactos/drivers/bus/pci/fdo.c | 86 ++++++++++++++++++++++++++--------- 1 file changed, 65 insertions(+), 21 deletions(-) diff --git a/reactos/drivers/bus/pci/fdo.c b/reactos/drivers/bus/pci/fdo.c index 8072a89b455..b6753e10a5e 100644 --- a/reactos/drivers/bus/pci/fdo.c +++ b/reactos/drivers/bus/pci/fdo.c @@ -16,6 +16,46 @@ /*** 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 FdoLocateChildDevice( PPCI_DEVICE *Device, @@ -466,7 +506,7 @@ FdoPnpControl( { PFDO_DEVICE_EXTENSION DeviceExtension; PIO_STACK_LOCATION IrpSp; - NTSTATUS Status; + NTSTATUS Status = Irp->IoStatus.Status; DPRINT("Called\n"); @@ -492,8 +532,13 @@ FdoPnpControl( break; #endif case IRP_MN_QUERY_DEVICE_RELATIONS: + if (IrpSp->Parameters.QueryDeviceRelations.Type != BusRelations) + break; + Status = FdoQueryBusRelations(DeviceObject, Irp, IrpSp); - break; + Irp->IoStatus.Status = Status; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return Status; #if 0 case IRP_MN_QUERY_PNP_DEVICE_STATE: Status = STATUS_NOT_IMPLEMENTED; @@ -513,38 +558,37 @@ FdoPnpControl( #endif case IRP_MN_START_DEVICE: DPRINT("IRP_MN_START_DEVICE received\n"); - Status = FdoStartDevice(DeviceObject, Irp); - break; + Status = ForwardIrpAndWait(DeviceObject, Irp); + if (NT_SUCCESS(Status)) + Status = FdoStartDevice(DeviceObject, Irp); + + Irp->IoStatus.Status = Status; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return Status; case IRP_MN_STOP_DEVICE: /* Currently not supported */ Status = STATUS_UNSUCCESSFUL; - break; + Irp->IoStatus.Status = Status; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return Status; #if 0 case IRP_MN_SURPRISE_REMOVAL: Status = STATUS_NOT_IMPLEMENTED; break; #endif + case IRP_MN_FILTER_RESOURCE_REQUIREMENTS: + break; + case IRP_MN_REMOVE_DEVICE: + DPRINT1("IRP_MN_REMOVE_DEVICE is UNIMPLEMENTED!\n"); + break; default: 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; } - - if (Status != STATUS_PENDING) { - if (Status != STATUS_NOT_IMPLEMENTED) - Irp->IoStatus.Status = Status; - IoCompleteRequest(Irp, IO_NO_INCREMENT); - } + Irp->IoStatus.Status = Status; + IoSkipCurrentIrpStackLocation(Irp); + Status = IoCallDriver(DeviceExtension->Ldo, Irp); DPRINT("Leaving. Status 0x%X\n", Status); -- 2.17.1