Author: vmikayelyan
Date: Fri Aug 19 16:46:18 2016
New Revision: 72388

URL: http://svn.reactos.org/svn/reactos?rev=72388&view=rev
Log:
usb: HUB: Add PnP state tracking

Added PDO/FDO PnP state tracking, which is done according MSDN's
"State Transitions for PnP Devices" topic.

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
    branches/GSoC_2016/USB/drivers/usb/usbhub/usbhub.h

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=72388&r1=72387&r2=72388&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:46:18 2016
@@ -1322,7 +1322,7 @@
     RtlCopyMemory(&UsbChildExtension->DeviceInterface, 
&HubDeviceExtension->UsbDInterface, sizeof(USB_BUS_INTERFACE_USBDI_V2));
     
UsbChildExtension->DeviceInterface.InterfaceReference(UsbChildExtension->DeviceInterface.BusContext);
 
-    UsbChildExtension->IsRemovePending = FALSE;
+    INITIALIZE_PNP_STATE(UsbChildExtension->Common);
 
     KeAcquireGuardedMutex(&HubDeviceExtension->HubMutexLock);
 
@@ -2053,6 +2053,8 @@
                 Status = USBHUB_ParentFDOStartDevice(DeviceObject, Irp);
             }
 
+            SET_NEW_PNP_STATE(HubDeviceExtension->Common, Started);
+
             Irp->IoStatus.Status = Status;
             IoCompleteRequest(Irp, IO_NO_INCREMENT);
             return Status;
@@ -2116,6 +2118,18 @@
             // No action is required from FDO because it have nothing to free.
             DPRINT("IRP_MN_QUERY_REMOVE_DEVICE\n");
 
+            SET_NEW_PNP_STATE(HubDeviceExtension->Common, RemovePending);
+
+            Irp->IoStatus.Status = STATUS_SUCCESS;
+            break;
+        }
+        case IRP_MN_CANCEL_REMOVE_DEVICE:
+        {
+            DPRINT("IRP_MN_CANCEL_REMOVE_DEVICE\n");
+
+            if (HubDeviceExtension->Common.PnPState == RemovePending)
+                RESTORE_PREVIOUS_PNP_STATE(HubDeviceExtension->Common);
+
             Irp->IoStatus.Status = STATUS_SUCCESS;
             break;
         }
@@ -2127,6 +2141,7 @@
             // our children that their parent is removed and on next removal
             // they also can be removed.
             //
+            SET_NEW_PNP_STATE(HubDeviceExtension->Common, 
SurpriseRemovePending);
 
             KeAcquireGuardedMutex(&HubDeviceExtension->HubMutexLock);
 

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=72388&r1=72387&r2=72388&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:46:18 2016
@@ -200,7 +200,9 @@
     ChildDeviceExtension = 
(PHUB_CHILDDEVICE_EXTENSION)DeviceObject->DeviceExtension;
     ASSERT(ChildDeviceExtension->Common.IsFDO == FALSE);
 
-    if (ChildDeviceExtension->IsRemovePending || !IsValidPDO(DeviceObject))
+    if (ChildDeviceExtension->Common.PnPState == SurpriseRemovePending ||
+        ChildDeviceExtension->Common.PnPState == RemovePending ||
+        !IsValidPDO(DeviceObject))
     {
         // Parent or child device was surprise removed.
         DPRINT1("[USBHUB] Request for removed device object %p\n", 
DeviceObject);
@@ -431,6 +433,8 @@
     //
     IoRegisterDeviceInterface(DeviceObject, &GUID_DEVINTERFACE_USB_DEVICE, 
NULL, &ChildDeviceExtension->SymbolicLinkName);
     IoSetDeviceInterfaceState(&ChildDeviceExtension->SymbolicLinkName, TRUE);
+
+    SET_NEW_PNP_STATE(ChildDeviceExtension->Common, Started);
 
     UNIMPLEMENTED
     return STATUS_SUCCESS;
@@ -668,9 +672,15 @@
 
             DPRINT("IRP_MJ_PNP / IRP_MN_REMOVE_DEVICE\n");
 
+            ASSERT((UsbChildExtension->Common.PnPState == RemovePending) ||
+                   (UsbChildExtension->Common.PnPState == 
SurpriseRemovePending));
+
+            SET_NEW_PNP_STATE(UsbChildExtension->Common, NotStarted);
+
             if (!IsValidPDO(DeviceObject))
             {
                 // Parent or child device was surprise removed, freeing 
resources allocated for child device.
+                SET_NEW_PNP_STATE(UsbChildExtension->Common, Deleted);
 
                 // Remove the usb device
                 if (UsbChildExtension->UsbDeviceHandle)
@@ -699,8 +709,7 @@
                 IoDeleteDevice(DeviceObject);
             }
 
-            // Device is physically presented, so we leave its PDO undeleted.
-            ASSERT(UsbChildExtension->IsRemovePending == TRUE);
+            // If device is physically presented, we leave its PDO undeleted.
 
             /* Complete the IRP */
             Irp->IoStatus.Status = STATUS_SUCCESS;
@@ -760,7 +769,7 @@
             //
             
UsbChildExtension->DeviceInterface.InterfaceDereference(UsbChildExtension->DeviceInterface.BusContext);
 
-            UsbChildExtension->IsRemovePending = TRUE;
+            SET_NEW_PNP_STATE(UsbChildExtension->Common, RemovePending);
 
             /* Sure, no problem */
             Status = STATUS_SUCCESS;
@@ -770,9 +779,9 @@
         case IRP_MN_CANCEL_REMOVE_DEVICE:
         {
             // Check to see have we received query-remove before
-            if (UsbChildExtension->IsRemovePending == TRUE)
-            {
-                UsbChildExtension->IsRemovePending = FALSE;
+            if (UsbChildExtension->Common.PnPState == RemovePending)
+            {
+                RESTORE_PREVIOUS_PNP_STATE(UsbChildExtension->Common);
                 
UsbChildExtension->DeviceInterface.InterfaceReference(UsbChildExtension->DeviceInterface.BusContext);
             }
 
@@ -804,7 +813,7 @@
             // the flag and do further clean-up in subsequent 
IRP_MN_REMOVE_DEVICE
             // We can receive this IRP when device is physically connected (on 
stop/start fail).
             //
-            UsbChildExtension->IsRemovePending = TRUE;
+            SET_NEW_PNP_STATE(UsbChildExtension->Common, 
SurpriseRemovePending);
 
             Status = STATUS_SUCCESS;
             break;

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=72388&r1=72387&r2=72388&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:46:18 2016
@@ -86,6 +86,8 @@
     HubDeviceExtension = (PHUB_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
     RtlZeroMemory(HubDeviceExtension, sizeof(HUB_DEVICE_EXTENSION));
 
+    INITIALIZE_PNP_STATE(HubDeviceExtension->Common);
+
     //
     // Set this to Fdo
     //

Modified: branches/GSoC_2016/USB/drivers/usb/usbhub/usbhub.h
URL: 
http://svn.reactos.org/svn/reactos/branches/GSoC_2016/USB/drivers/usb/usbhub/usbhub.h?rev=72388&r1=72387&r2=72388&view=diff
==============================================================================
--- branches/GSoC_2016/USB/drivers/usb/usbhub/usbhub.h  [iso-8859-1] (original)
+++ branches/GSoC_2016/USB/drivers/usb/usbhub/usbhub.h  [iso-8859-1] Fri Aug 19 
16:46:18 2016
@@ -39,9 +39,43 @@
     PVOID Context;
 } WORK_ITEM_DATA, *PWORK_ITEM_DATA;
 
+
+//
+// Definitions for device's PnP state tracking, all this states are described
+// in PnP Device States diagram of DDK documentation.
+//
+typedef enum _DEVICE_PNP_STATE {
+
+    NotStarted = 0,         // Not started
+    Started,                // After handling of START_DEVICE IRP
+    StopPending,            // After handling of QUERY_STOP IRP
+    Stopped,                // After handling of STOP_DEVICE IRP
+    RemovePending,          // After handling of QUERY_REMOVE IRP
+    SurpriseRemovePending,  // After handling of SURPRISE_REMOVE IRP
+    Deleted,                // After handling of REMOVE_DEVICE IRP
+    UnKnown                 // Unknown state
+
+} DEVICE_PNP_STATE;
+
+#define INITIALIZE_PNP_STATE(Data) \
+(Data).PnPState = NotStarted;\
+(Data).PreviousPnPState = NotStarted;
+
+#define SET_NEW_PNP_STATE(Data, state) \
+(Data).PnPState = (Data).PnPState;\
+(Data).PnPState = (state);
+
+#define RESTORE_PREVIOUS_PNP_STATE(Data) \
+(Data).PnPState = (Data).PreviousPnPState;
+
 typedef struct
 {
     BOOLEAN IsFDO;
+    // We'll track device PnP state via this variables
+    DEVICE_PNP_STATE PnPState;
+    DEVICE_PNP_STATE PreviousPnPState;
+    // Remove lock
+    IO_REMOVE_LOCK RemoveLock;
 } COMMON_DEVICE_EXTENSION, *PCOMMON_DEVICE_EXTENSION;
 
 typedef struct _HUB_CHILDDEVICE_EXTENSION
@@ -61,7 +95,6 @@
     UNICODE_STRING SymbolicLinkName;
     USB_BUS_INTERFACE_USBDI_V2 DeviceInterface;
     USB_DEVICE_INFORMATION_0 DeviceInformation;
-    BOOLEAN IsRemovePending;
 } HUB_CHILDDEVICE_EXTENSION, *PHUB_CHILDDEVICE_EXTENSION;
 
 typedef struct _HUB_DEVICE_EXTENSION


Reply via email to