Author: vmikayelyan Date: Fri Aug 19 16:47:45 2016 New Revision: 72389
URL: http://svn.reactos.org/svn/reactos?rev=72389&view=rev Log: usb: hub: Add remove synchronization
Added PDO/FDO remove synchronization to prevent device removal while another IRP is in process.
As guidelines used ch6 of Walter Oney's "Programming the Microsoft Windows Driver Model 2ed"
Modified: branches/GSoC_2016/USB/drivers/usb/usbhub/fdo.c branches/GSoC_2016/USB/drivers/usb/usbhub/pdo.c branches/GSoC_2016/USB/drivers/usb/usbhub/usbhub.c
Modified: branches/GSoC_2016/USB/drivers/usb/usbhub/fdo.c URL: http://svn.reactos.org/svn/reactos/branches/GSoC_2016/USB/drivers/usb/usbhub... ============================================================================== --- branches/GSoC_2016/USB/drivers/usb/usbhub/fdo.c [iso-8859-1] (original) +++ branches/GSoC_2016/USB/drivers/usb/usbhub/fdo.c [iso-8859-1] Fri Aug 19 16:47:45 2016 @@ -1323,6 +1323,8 @@ UsbChildExtension->DeviceInterface.InterfaceReference(UsbChildExtension->DeviceInterface.BusContext);
INITIALIZE_PNP_STATE(UsbChildExtension->Common); + + IoInitializeRemoveLock(&UsbChildExtension->Common.RemoveLock, 'pbuH', 0, 0);
KeAcquireGuardedMutex(&HubDeviceExtension->HubMutexLock);
@@ -2038,6 +2040,14 @@
Stack = IoGetCurrentIrpStackLocation(Irp);
+ Status = IoAcquireRemoveLock(&HubDeviceExtension->Common.RemoveLock, Irp); + if (!NT_SUCCESS(Status)) + { + Irp->IoStatus.Status = Status; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return Status; + } + switch (Stack->MinorFunction) { case IRP_MN_START_DEVICE: @@ -2057,6 +2067,7 @@
Irp->IoStatus.Status = Status; IoCompleteRequest(Irp, IO_NO_INCREMENT); + IoReleaseRemoveLock(&HubDeviceExtension->Common.RemoveLock, Irp); return Status; }
@@ -2083,6 +2094,7 @@ // We should fail an IRP Irp->IoStatus.Status = Status; IoCompleteRequest(Irp, IO_NO_INCREMENT); + IoReleaseRemoveLock(&HubDeviceExtension->Common.RemoveLock, Irp); return Status; }
@@ -2201,7 +2213,9 @@ } }
- return ForwardIrpAndForget(DeviceObject, Irp); + Status = ForwardIrpAndForget(DeviceObject, Irp); + IoReleaseRemoveLock(&HubDeviceExtension->Common.RemoveLock, Irp); + return Status; }
NTSTATUS @@ -2225,6 +2239,25 @@ // get device extension HubDeviceExtension = (PHUB_DEVICE_EXTENSION) DeviceObject->DeviceExtension;
+ Status = IoAcquireRemoveLock(&HubDeviceExtension->Common.RemoveLock, Irp); + if (!NT_SUCCESS(Status)) + { + Irp->IoStatus.Status = Status; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return Status; + } + + // Prevent handling of control requests in remove pending state + if (HubDeviceExtension->Common.PnPState == RemovePending) + { + DPRINT1("[USBHUB] Request for removed device object %p\n", DeviceObject); + Irp->IoStatus.Status = STATUS_DEVICE_NOT_CONNECTED; + Irp->IoStatus.Information = 0; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + IoReleaseRemoveLock(&HubDeviceExtension->Common.RemoveLock, Irp); + return STATUS_DEVICE_NOT_CONNECTED; + } + if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_USB_GET_NODE_INFORMATION) { // is the buffer big enough @@ -2390,6 +2423,7 @@ Irp->IoStatus.Status = Status; IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ IoReleaseRemoveLock(&HubDeviceExtension->Common.RemoveLock, Irp); return Status; }
Modified: branches/GSoC_2016/USB/drivers/usb/usbhub/pdo.c URL: http://svn.reactos.org/svn/reactos/branches/GSoC_2016/USB/drivers/usb/usbhub... ============================================================================== --- branches/GSoC_2016/USB/drivers/usb/usbhub/pdo.c [iso-8859-1] (original) +++ branches/GSoC_2016/USB/drivers/usb/usbhub/pdo.c [iso-8859-1] Fri Aug 19 16:47:45 2016 @@ -200,6 +200,14 @@ ChildDeviceExtension = (PHUB_CHILDDEVICE_EXTENSION)DeviceObject->DeviceExtension; ASSERT(ChildDeviceExtension->Common.IsFDO == FALSE);
+ Status = IoAcquireRemoveLock(&ChildDeviceExtension->Common.RemoveLock, Irp); + if (!NT_SUCCESS(Status)) + { + Irp->IoStatus.Status = Status; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return Status; + } + if (ChildDeviceExtension->Common.PnPState == SurpriseRemovePending || ChildDeviceExtension->Common.PnPState == RemovePending || !IsValidPDO(DeviceObject)) @@ -209,6 +217,7 @@ Irp->IoStatus.Status = STATUS_DEVICE_NOT_CONNECTED; Irp->IoStatus.Information = 0; IoCompleteRequest(Irp, IO_NO_INCREMENT); + IoReleaseRemoveLock(&ChildDeviceExtension->Common.RemoveLock, Irp); return STATUS_DEVICE_NOT_CONNECTED; }
@@ -314,6 +323,7 @@ // Send the request to RootHub // Status = FowardUrbToRootHub(RootHubDeviceObject, IOCTL_INTERNAL_USB_SUBMIT_URB, Irp, Urb, NULL); + IoReleaseRemoveLock(&ChildDeviceExtension->Common.RemoveLock, Irp); return Status; } // @@ -410,6 +420,7 @@ Irp->IoStatus.Status = Status; IoCompleteRequest(Irp, IO_NO_INCREMENT); } + IoReleaseRemoveLock(&ChildDeviceExtension->Common.RemoveLock, Irp); return Status; }
@@ -583,6 +594,14 @@ UsbChildExtension = (PHUB_CHILDDEVICE_EXTENSION)DeviceObject->DeviceExtension; Stack = IoGetCurrentIrpStackLocation(Irp); MinorFunction = Stack->MinorFunction; + + Status = IoAcquireRemoveLock(&UsbChildExtension->Common.RemoveLock, Irp); + if (!NT_SUCCESS(Status)) + { + Irp->IoStatus.Status = Status; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return Status; + }
switch (MinorFunction) { @@ -682,6 +701,8 @@ // Parent or child device was surprise removed, freeing resources allocated for child device. SET_NEW_PNP_STATE(UsbChildExtension->Common, Deleted);
+ IoReleaseRemoveLockAndWait(&UsbChildExtension->Common.RemoveLock, Irp); + // Remove the usb device if (UsbChildExtension->UsbDeviceHandle) { @@ -705,8 +726,12 @@ if (UsbChildExtension->usInstanceId.Buffer) ExFreePool(UsbChildExtension->usInstanceId.Buffer);
- // Delete child PDO + DPRINT("Deleting child PDO\n"); IoDeleteDevice(DeviceObject); + } + else + { + IoReleaseRemoveLock(&UsbChildExtension->Common.RemoveLock, Irp); }
// If device is physically presented, we leave its PDO undeleted. @@ -802,7 +827,9 @@
// pass irp down IoSkipCurrentIrpStackLocation(Irp); - return IoCallDriver(UsbChildExtension->ParentDeviceObject, Irp); + Status = IoCallDriver(UsbChildExtension->ParentDeviceObject, Irp); + IoReleaseRemoveLock(&UsbChildExtension->Common.RemoveLock, Irp); + return Status; } case IRP_MN_SURPRISE_REMOVAL: { @@ -825,6 +852,8 @@ Status = Irp->IoStatus.Status; } } + + IoReleaseRemoveLock(&UsbChildExtension->Common.RemoveLock, Irp);
Irp->IoStatus.Information = Information; Irp->IoStatus.Status = Status;
Modified: branches/GSoC_2016/USB/drivers/usb/usbhub/usbhub.c URL: http://svn.reactos.org/svn/reactos/branches/GSoC_2016/USB/drivers/usb/usbhub... ============================================================================== --- branches/GSoC_2016/USB/drivers/usb/usbhub/usbhub.c [iso-8859-1] (original) +++ branches/GSoC_2016/USB/drivers/usb/usbhub/usbhub.c [iso-8859-1] Fri Aug 19 16:47:45 2016 @@ -97,6 +97,9 @@ // initialize mutex KeInitializeGuardedMutex(&HubDeviceExtension->HubMutexLock);
+ // initialize remove lock + IoInitializeRemoveLock(&HubDeviceExtension->Common.RemoveLock, 'buH', 0, 0); + // // initialize reset complete event //