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/fdo.c?rev=72389&r1=72388&r2=72389&view=diff
==============================================================================
--- 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/pdo.c?rev=72389&r1=72388&r2=72389&view=diff
==============================================================================
--- 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/usbhub.c?rev=72389&r1=72388&r2=72389&view=diff
==============================================================================
--- 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
     //


Reply via email to