Author: vmikayelyan
Date: Fri Aug 19 15:47:45 2016
New Revision: 72372
URL: http://svn.reactos.org/svn/reactos?rev=72372&view=rev
Log:
usb: hub: FDO: Rework IRP_MN_QUERY_DEVICE_RELATIONS
First of all we should keep in account that there might be device
relations below and above this FDO, so we should save previous relations
coming from top object and shuld pass this IRP down to stack after
adding our relations. In case of success query devcie relations must be
completed in the PDO.
As MSDN requires, if the upper layer provided this IRP with initialized
DeviceRelation, then we should replace that relation with another one
which will contain our child PDOs too. And after replacement we should
free the recources allocated for previous relation structure.
If there is relations coming from upper layer, we shuldn't complete this
IRP with fail, because that will bring upper layer into unstabile state,
it will 'think' that succesfully reported it's relations.
Modified:
branches/GSoC_2016/USB/drivers/usb/usbhub/fdo.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 15:47:45 2016
@@ -1387,11 +1387,13 @@
NTSTATUS
USBHUB_FdoQueryBusRelations(
IN PDEVICE_OBJECT DeviceObject,
+ IN PDEVICE_RELATIONS RelationsFromTop,
OUT PDEVICE_RELATIONS* pDeviceRelations)
{
PHUB_DEVICE_EXTENSION HubDeviceExtension;
PDEVICE_RELATIONS DeviceRelations;
ULONG i;
+ ULONG ChildrenFromTop = 0;
ULONG Children = 0;
ULONG NeededSize;
@@ -1410,9 +1412,18 @@
Children++;
}
- NeededSize = sizeof(DEVICE_RELATIONS);
- if (Children > 1)
- NeededSize += (Children - 1) * sizeof(PDEVICE_OBJECT);
+ if (RelationsFromTop)
+ {
+ ChildrenFromTop = RelationsFromTop->Count;
+ if (!Children)
+ {
+ // We have nothing to add
+ *pDeviceRelations = RelationsFromTop;
+ return STATUS_SUCCESS;
+ }
+ }
+
+ NeededSize = sizeof(DEVICE_RELATIONS) + (Children + ChildrenFromTop - 1) * sizeof(PDEVICE_OBJECT);
//
// Allocate DeviceRelations
@@ -1421,9 +1432,21 @@
NeededSize);
if (!DeviceRelations)
- return STATUS_INSUFFICIENT_RESOURCES;
- DeviceRelations->Count = Children;
- Children = 0;
+ {
+ if (!RelationsFromTop)
+ return STATUS_INSUFFICIENT_RESOURCES;
+ else
+ return STATUS_NOT_SUPPORTED;
+ }
+ // Copy the objects coming from top
+ if (ChildrenFromTop)
+ {
+ RtlCopyMemory(DeviceRelations->Objects, RelationsFromTop->Objects,
+ ChildrenFromTop * sizeof(PDEVICE_OBJECT));
+ }
+
+ DeviceRelations->Count = Children + ChildrenFromTop;
+ Children = ChildrenFromTop;
//
// Fill in return structure
@@ -1438,6 +1461,10 @@
DeviceRelations->Objects[Children++] = HubDeviceExtension->ChildDeviceObject[i];
}
}
+
+ // We should do this, because replaced this with our's one
+ if (RelationsFromTop)
+ ExFreePool(RelationsFromTop);
ASSERT(Children == DeviceRelations->Count);
*pDeviceRelations = DeviceRelations;
@@ -1976,7 +2003,6 @@
{
PIO_STACK_LOCATION Stack;
NTSTATUS Status = STATUS_SUCCESS;
- ULONG_PTR Information = 0;
PHUB_DEVICE_EXTENSION HubDeviceExtension;
HubDeviceExtension = (PHUB_DEVICE_EXTENSION) DeviceObject->DeviceExtension;
@@ -2007,12 +2033,28 @@
case BusRelations:
{
PDEVICE_RELATIONS DeviceRelations = NULL;
+ PDEVICE_RELATIONS RelationsFromTop = (PDEVICE_RELATIONS)Irp->IoStatus.Information;
DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / BusRelations\n");
- Status = USBHUB_FdoQueryBusRelations(DeviceObject, &DeviceRelations);
-
- Information = (ULONG_PTR)DeviceRelations;
- break;
+ Status = USBHUB_FdoQueryBusRelations(DeviceObject, RelationsFromTop, &DeviceRelations);
+
+ if (!NT_SUCCESS(Status))
+ {
+ if (Status == STATUS_NOT_SUPPORTED)
+ {
+ // We should process this to not lose relations from top.
+ Irp->IoStatus.Status = STATUS_SUCCESS;
+ break;
+ }
+ // We should fail an IRP
+ Irp->IoStatus.Status = Status;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ return Status;
+ }
+
+ Irp->IoStatus.Information = (ULONG_PTR)DeviceRelations;
+ Irp->IoStatus.Status = Status;
+ return ForwardIrpAndForget(DeviceObject, Irp);
}
case RemovalRelations:
{
@@ -2066,7 +2108,6 @@
}
}
- Irp->IoStatus.Information = Information;
Irp->IoStatus.Status = Status;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return Status;
Author: vmikayelyan
Date: Fri Aug 19 15:37:57 2016
New Revision: 72369
URL: http://svn.reactos.org/svn/reactos?rev=72369&view=rev
Log:
usb: hub: PDO: Fail IRP_MN_QUERY_STOP_DEVICE.
We should fail this request, because we're not handling
IRP_MN_STOP_DEVICE for now. On systems above win2000 we'll
receive this IRP ONLY when the PnP manager rebalances resources.
Modified:
branches/GSoC_2016/USB/drivers/usb/usbhub/pdo.c
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 15:37:57 2016
@@ -729,6 +729,14 @@
break;
}
case IRP_MN_QUERY_STOP_DEVICE:
+ {
+ //
+ // We should fail this request, because we're not handling IRP_MN_STOP_DEVICE for now.
+ // We'll receive this IRP ONLY when the PnP manager rebalances resources.
+ //
+ Status = STATUS_NOT_SUPPORTED;
+ break;
+ }
case IRP_MN_QUERY_REMOVE_DEVICE:
{
// HERE SHOULD BE CHECKED INTERFACE COUNT PROVIED TO UPPER LAYER TO BE ZERO, AS WE ARE HANDLING
Author: vmikayelyan
Date: Fri Aug 19 15:34:48 2016
New Revision: 72368
URL: http://svn.reactos.org/svn/reactos?rev=72368&view=rev
Log:
usb: hub: PDO: New checking in IsValidPDO()
As child's parent FDO at any moment can receive surprise removal,
Before being it should notify it's childs by setting their parents to NULL.
So if we see PDO with parent==NULL then we can consider it as physically
removed, i.e. invalid.
Modified:
branches/GSoC_2016/USB/drivers/usb/usbhub/pdo.c
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 15:34:48 2016
@@ -146,6 +146,11 @@
ChildDeviceExtension = (PHUB_CHILDDEVICE_EXTENSION)DeviceObject->DeviceExtension;
ASSERT(ChildDeviceExtension->Common.IsFDO == FALSE);
+
+ // This can happen when parent device was surprise removed.
+ if (ChildDeviceExtension->ParentDeviceObject == NULL)
+ return FALSE;
+
HubDeviceExtension = (PHUB_DEVICE_EXTENSION)ChildDeviceExtension->ParentDeviceObject->DeviceExtension;
for(Index = 0; Index < USB_MAXCHILDREN; Index++)
Author: vmikayelyan
Date: Fri Aug 19 15:31:15 2016
New Revision: 72367
URL: http://svn.reactos.org/svn/reactos?rev=72367&view=rev
Log:
usb: hub: PDO: Add IsRemovePending flag to HUB_CHILDDEVICE_EXTENSION
This flag is set in IRP_MN_QUERY_REMOVE_DEVICE and IRP_MN_SURPRISE_REMOVAL,
and then checked in PDO's IRP dispatch routines to prevent starting of
any operation which can prevent device removal.
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.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 15:31:15 2016
@@ -1339,6 +1339,8 @@
DPRINT1("Failed to create strings needed to describe device to PNP.\n");
goto Cleanup;
}
+
+ UsbChildExtension->IsRemovePending = FALSE;
HubDeviceExtension->ChildDeviceObject[ChildDeviceCount] = NewChildDeviceObject;
HubDeviceExtension->InstanceCount++;
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 15:31:15 2016
@@ -190,17 +190,19 @@
ChildDeviceExtension = (PHUB_CHILDDEVICE_EXTENSION)DeviceObject->DeviceExtension;
ASSERT(ChildDeviceExtension->Common.IsFDO == FALSE);
- HubDeviceExtension = (PHUB_DEVICE_EXTENSION)ChildDeviceExtension->ParentDeviceObject->DeviceExtension;
- RootHubDeviceObject = HubDeviceExtension->RootHubPhysicalDeviceObject;
-
- if(!IsValidPDO(DeviceObject))
- {
+
+ if (ChildDeviceExtension->IsRemovePending || !IsValidPDO(DeviceObject))
+ {
+ // Parent or child device was surprise removed.
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);
return STATUS_DEVICE_NOT_CONNECTED;
}
+
+ HubDeviceExtension = (PHUB_DEVICE_EXTENSION)ChildDeviceExtension->ParentDeviceObject->DeviceExtension;
+ RootHubDeviceObject = HubDeviceExtension->RootHubPhysicalDeviceObject;
switch (Stack->Parameters.DeviceIoControl.IoControlCode)
{
@@ -724,6 +726,11 @@
case IRP_MN_QUERY_STOP_DEVICE:
case IRP_MN_QUERY_REMOVE_DEVICE:
{
+ // HERE SHOULD BE CHECKED INTERFACE COUNT PROVIED TO UPPER LAYER TO BE ZERO, AS WE ARE HANDLING
+ // IRP_MN_QUERY_INTERFACE IN WRONG WAY, THAT WILL BE DONE LATER. SEE MSDN "IRP_MN_QUERY_INTERFACE"
+
+ UsbChildExtension->IsRemovePending = TRUE;
+
/* Sure, no problem */
Status = STATUS_SUCCESS;
Information = 0;
@@ -747,6 +754,14 @@
case IRP_MN_SURPRISE_REMOVAL:
{
DPRINT("[USBHUB] HandlePnp IRP_MN_SURPRISE_REMOVAL\n");
+
+ //
+ // Here we should free all resources and stop all access, lets just set
+ // 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;
+
Status = STATUS_SUCCESS;
break;
}
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 15:31:15 2016
@@ -61,6 +61,7 @@
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