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/usbhu…
==============================================================================
--- 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/usbhu…
==============================================================================
--- 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/usbhu…
==============================================================================
--- 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
//