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... ============================================================================== --- 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... ============================================================================== --- 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... ============================================================================== --- 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... ============================================================================== --- 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