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