Author: akhaldi
Date: Fri Jan 27 11:09:36 2017
New Revision: 73605
URL:
http://svn.reactos.org/svn/reactos?rev=73605&view=rev
Log:
[HIDPARSE][HIDPARSER][LIBUSB][USBHUB] Merge USB stack improvements by Vardan Mikayelyan in
GSoC.
Modified:
trunk/reactos/ (props changed)
trunk/reactos/drivers/hid/hidparse/ (props changed)
trunk/reactos/drivers/hid/hidparse/hidparse.c
trunk/reactos/drivers/usb/usbhub/ (props changed)
trunk/reactos/drivers/usb/usbhub/CMakeLists.txt
trunk/reactos/drivers/usb/usbhub/fdo.c
trunk/reactos/drivers/usb/usbhub/misc.c
trunk/reactos/drivers/usb/usbhub/pdo.c
trunk/reactos/drivers/usb/usbhub/usbhub.c
trunk/reactos/drivers/usb/usbhub/usbhub.h
trunk/reactos/sdk/lib/drivers/hidparser/context.c
trunk/reactos/sdk/lib/drivers/hidparser/hidparser.c
trunk/reactos/sdk/lib/drivers/hidparser/parser.c
trunk/reactos/sdk/lib/drivers/libusb/hub_controller.cpp (contents, props changed)
Propchange: trunk/reactos/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Fri Jan 27 11:09:36 2017
@@ -2,7 +2,7 @@
/branches/GSoC_2011/GSoC_TcpIpDriver:51550
/branches/GSoC_2011/TcpIpDriver:51551-53074,53076-53119
/branches/GSoC_2016/AHCI:71203-73603
-/branches/GSoC_2016/USB:72366,72376
+/branches/GSoC_2016/USB:72365-73604
/branches/GSoC_Network:51545-51546
/branches/cmake-bringup:50484,50693,50719,51544-52564
/branches/colins-printing-for-freedom/reactos:67543-68405,68407-68414,68417-70595
Propchange: trunk/reactos/drivers/hid/hidparse/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Fri Jan 27 11:09:36 2017
@@ -1,6 +1,7 @@
/branches/GSoC_2011/GSoC_Network/drivers/hid/hidparse:51548
/branches/GSoC_2011/GSoC_TcpIpDriver/drivers/hid/hidparse:51550
/branches/GSoC_2011/TcpIpDriver/drivers/hid/hidparse:51551-53074,53076-53119
+/branches/GSoC_2016/USB/drivers/hid/hidparse:72365-73604
/branches/GSoC_Network/drivers/hid/hidparse:51545-51546
/branches/cmake-bringup/drivers/hid/hidparse:50484,50693,50719,51544-52564
/branches/condrv_restructure/drivers/hid/hidparse:63104-64101
Modified: trunk/reactos/drivers/hid/hidparse/hidparse.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/hid/hidparse/hidpa…
==============================================================================
--- trunk/reactos/drivers/hid/hidparse/hidparse.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/hid/hidparse/hidparse.c [iso-8859-1] Fri Jan 27 11:09:36 2017
@@ -126,6 +126,29 @@
}
NTSTATUS
+TranslateStatusForUpperLayer(
+ IN HIDPARSER_STATUS Status)
+{
+ //
+ // now we are handling only this values, for others just return
+ // status as it is.
+ //
+ switch (Status)
+ {
+ case HIDPARSER_STATUS_INSUFFICIENT_RESOURCES:
+ return STATUS_INSUFFICIENT_RESOURCES;
+ case HIDPARSER_STATUS_INVALID_REPORT_TYPE:
+ return HIDP_STATUS_INVALID_REPORT_TYPE;
+ case HIDPARSER_STATUS_BUFFER_TOO_SMALL:
+ return STATUS_BUFFER_TOO_SMALL;
+ case HIDPARSER_STATUS_COLLECTION_NOT_FOUND:
+ return STATUS_NO_DATA_DETECTED;
+ default:
+ return Status;
+ }
+}
+
+NTSTATUS
NTAPI
HidP_GetCollectionDescription(
IN PHIDP_REPORT_DESCRIPTOR ReportDesc,
@@ -134,6 +157,7 @@
OUT PHIDP_DEVICE_DESC DeviceDescription)
{
HID_PARSER Parser;
+ NTSTATUS Status;
//
// init parser
@@ -143,7 +167,8 @@
//
// get description;
//
- return HidParser_GetCollectionDescription(&Parser, ReportDesc, DescLength,
PoolType, DeviceDescription);
+ Status = HidParser_GetCollectionDescription(&Parser, ReportDesc, DescLength,
PoolType, DeviceDescription);
+ return TranslateStatusForUpperLayer(Status);
}
HIDAPI
Propchange: trunk/reactos/drivers/usb/usbhub/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Fri Jan 27 11:09:36 2017
@@ -4,7 +4,7 @@
/branches/GSoC_2011/GSoC_TcpIpDriver/drivers/usb/usbhub_new:51550
/branches/GSoC_2011/TcpIpDriver/drivers/usb/usbhub:51551-53074,53076-53119
/branches/GSoC_2011/TcpIpDriver/drivers/usb/usbhub_new:51551-53074,53076-53119
-/branches/GSoC_2016/USB/drivers/usb/usbhub:72366,72376
+/branches/GSoC_2016/USB/drivers/usb/usbhub:72365-73604
/branches/GSoC_Network/drivers/usb/usbhub:51545-51546
/branches/GSoC_Network/drivers/usb/usbhub_new:51545-51546
/branches/cmake-bringup/drivers/usb/usbhub:50484,50693,50719,51544-52564
Modified: trunk/reactos/drivers/usb/usbhub/CMakeLists.txt
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/usb/usbhub/CMakeLi…
==============================================================================
--- trunk/reactos/drivers/usb/usbhub/CMakeLists.txt [iso-8859-1] (original)
+++ trunk/reactos/drivers/usb/usbhub/CMakeLists.txt [iso-8859-1] Fri Jan 27 11:09:36 2017
@@ -1,5 +1,6 @@
add_definitions(-DDEBUG_MODE)
+add_definitions(-DNTDDI_VERSION=0x05020400)
include_directories(${REACTOS_SOURCE_DIR}/ntoskrnl/include)
list(APPEND SOURCE
Modified: trunk/reactos/drivers/usb/usbhub/fdo.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/usb/usbhub/fdo.c?r…
==============================================================================
--- trunk/reactos/drivers/usb/usbhub/fdo.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/usb/usbhub/fdo.c [iso-8859-1] Fri Jan 27 11:09:36 2017
@@ -568,6 +568,11 @@
Stack->Parameters.QueryInterface.Version = Version;
Stack->Parameters.QueryInterface.Interface = Interface;
Stack->Parameters.QueryInterface.InterfaceSpecificData = NULL;
+
+ //
+ // Initialize the status block before sending the IRP
+ //
+ Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
Status = IoCallDriver(DeviceObject, Irp);
@@ -1089,8 +1094,7 @@
PDEVICE_OBJECT ChildDeviceObject = NULL;
ULONG Index = 0;
- DPRINT("Removing device on port %d (Child index: %d)\n", PortId, Index);
-
+ KeAcquireGuardedMutex(&HubDeviceExtension->HubMutexLock);
for (Index = 0; Index < USB_MAXCHILDREN; Index++)
{
if (HubDeviceExtension->ChildDeviceObject[Index])
@@ -1111,11 +1115,16 @@
if (!ChildDeviceObject)
{
DPRINT1("Removal request for non-existant device!\n");
+ KeReleaseGuardedMutex(&HubDeviceExtension->HubMutexLock);
return STATUS_UNSUCCESSFUL;
}
+
+ DPRINT("Removing device on port %d (Child index: %d)\n", PortId, Index);
/* Remove the device from the table */
HubDeviceExtension->ChildDeviceObject[Index] = NULL;
+
+ KeReleaseGuardedMutex(&HubDeviceExtension->HubMutexLock);
/* Invalidate device relations for the root hub */
IoInvalidateDeviceRelations(HubDeviceExtension->RootHubPhysicalDeviceObject,
BusRelations);
@@ -1147,26 +1156,6 @@
HubInterface = &HubDeviceExtension->HubInterface;
RootHubDeviceObject = HubDeviceExtension->RootHubPhysicalDeviceObject;
HubInterfaceBusContext = HubDeviceExtension->UsbDInterface.BusContext;
- //
- // Find an empty slot in the child device array
- //
- for (ChildDeviceCount = 0; ChildDeviceCount < USB_MAXCHILDREN;
ChildDeviceCount++)
- {
- if (HubDeviceExtension->ChildDeviceObject[ChildDeviceCount] == NULL)
- {
- DPRINT("Found unused entry at %d\n", ChildDeviceCount);
- break;
- }
- }
-
- //
- // Check if the limit has been reached for maximum usb devices
- //
- if (ChildDeviceCount == USB_MAXCHILDREN)
- {
- DPRINT1("USBHUB: Too many child devices!\n");
- return STATUS_UNSUCCESSFUL;
- }
while (TRUE)
{
@@ -1226,10 +1215,6 @@
UsbChildExtension->ParentDeviceObject = UsbHubDeviceObject;
UsbChildExtension->PortNumber = PortId;
- // copy device interface
- RtlCopyMemory(&UsbChildExtension->DeviceInterface,
&HubDeviceExtension->DeviceInterface, sizeof(USB_BUS_INTERFACE_USBDI_V2));
-
-
//
// Create the UsbDeviceObject
//
@@ -1243,12 +1228,6 @@
DPRINT1("USBHUB: CreateUsbDevice failed with status %x\n", Status);
goto Cleanup;
}
-
- // copy device interface
- RtlCopyMemory(&UsbChildExtension->DeviceInterface,
&HubDeviceExtension->DeviceInterface, sizeof(USB_BUS_INTERFACE_USBDI_V2));
-
- // FIXME replace buscontext
- UsbChildExtension->DeviceInterface.BusContext =
UsbChildExtension->UsbDeviceHandle;
//
// Initialize UsbDevice
@@ -1339,8 +1318,43 @@
goto Cleanup;
}
+ // copy device interface
+ RtlCopyMemory(&UsbChildExtension->DeviceInterface,
&HubDeviceExtension->UsbDInterface, sizeof(USB_BUS_INTERFACE_USBDI_V2));
+
UsbChildExtension->DeviceInterface.InterfaceReference(UsbChildExtension->DeviceInterface.BusContext);
+
+ INITIALIZE_PNP_STATE(UsbChildExtension->Common);
+
+ IoInitializeRemoveLock(&UsbChildExtension->Common.RemoveLock, 'pbuH',
0, 0);
+
+ KeAcquireGuardedMutex(&HubDeviceExtension->HubMutexLock);
+
+ //
+ // Find an empty slot in the child device array
+ //
+ for (ChildDeviceCount = 0; ChildDeviceCount < USB_MAXCHILDREN;
ChildDeviceCount++)
+ {
+ if (HubDeviceExtension->ChildDeviceObject[ChildDeviceCount] == NULL)
+ {
+ DPRINT("Found unused entry at %d\n", ChildDeviceCount);
+ break;
+ }
+ }
+
+ //
+ // Check if the limit has been reached for maximum usb devices
+ //
+ if (ChildDeviceCount == USB_MAXCHILDREN)
+ {
+ DPRINT1("USBHUB: Too many child devices!\n");
+ Status = STATUS_UNSUCCESSFUL;
+ KeReleaseGuardedMutex(&HubDeviceExtension->HubMutexLock);
+
UsbChildExtension->DeviceInterface.InterfaceDereference(UsbChildExtension->DeviceInterface.BusContext);
+ goto Cleanup;
+ }
+
HubDeviceExtension->ChildDeviceObject[ChildDeviceCount] = NewChildDeviceObject;
HubDeviceExtension->InstanceCount++;
+ KeReleaseGuardedMutex(&HubDeviceExtension->HubMutexLock);
IoInvalidateDeviceRelations(RootHubDeviceObject, BusRelations);
return STATUS_SUCCESS;
@@ -1384,16 +1398,20 @@
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;
HubDeviceExtension = (PHUB_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+ KeAcquireGuardedMutex(&HubDeviceExtension->HubMutexLock);
+
//
// Count the number of children
//
@@ -1407,9 +1425,19 @@
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;
+ KeReleaseGuardedMutex(&HubDeviceExtension->HubMutexLock);
+ return STATUS_SUCCESS;
+ }
+ }
+
+ NeededSize = sizeof(DEVICE_RELATIONS) + (Children + ChildrenFromTop - 1) *
sizeof(PDEVICE_OBJECT);
//
// Allocate DeviceRelations
@@ -1418,9 +1446,22 @@
NeededSize);
if (!DeviceRelations)
- return STATUS_INSUFFICIENT_RESOURCES;
- DeviceRelations->Count = Children;
- Children = 0;
+ {
+ KeReleaseGuardedMutex(&HubDeviceExtension->HubMutexLock);
+ 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
@@ -1429,11 +1470,18 @@
{
if (HubDeviceExtension->ChildDeviceObject[i])
{
+ // The PnP Manager removes the reference when appropriate.
ObReferenceObject(HubDeviceExtension->ChildDeviceObject[i]);
HubDeviceExtension->ChildDeviceObject[i]->Flags &=
~DO_DEVICE_INITIALIZING;
DeviceRelations->Objects[Children++] =
HubDeviceExtension->ChildDeviceObject[i];
}
}
+
+ KeReleaseGuardedMutex(&HubDeviceExtension->HubMutexLock);
+
+ // We should do this, because replaced this with our's one
+ if (RelationsFromTop)
+ ExFreePool(RelationsFromTop);
ASSERT(Children == DeviceRelations->Count);
*pDeviceRelations = DeviceRelations;
@@ -1551,7 +1599,8 @@
if (!Urb)
{
// no memory
- return STATUS_INSUFFICIENT_RESOURCES;
+ Status = STATUS_INSUFFICIENT_RESOURCES;
+ goto cleanup;
}
// zero urb
@@ -1566,8 +1615,7 @@
{
// failed to obtain hub pdo
DPRINT1("IOCTL_INTERNAL_USB_GET_ROOTHUB_PDO failed with %x\n",
Status);
- ExFreePool(Urb);
- return Status;
+ goto cleanup;
}
// sanity checks
@@ -1578,14 +1626,13 @@
RootHubDeviceObject = HubDeviceExtension->RootHubPhysicalDeviceObject;
// Send the StartDevice to RootHub
- Status = ForwardIrpAndWait(RootHubDeviceObject, Irp);
+ Status = ForwardIrpAndWait(HubDeviceExtension->LowerDeviceObject, Irp);
if (!NT_SUCCESS(Status))
{
// failed to start pdo
DPRINT1("Failed to start the RootHub PDO\n");
- ExFreePool(Urb);
- return Status;
+ goto cleanup;
}
// Get the current number of hubs
@@ -1596,8 +1643,7 @@
{
// failed to get number of hubs
DPRINT1("IOCTL_INTERNAL_USB_GET_HUB_COUNT failed with %x\n", Status);
- ExFreePool(Urb);
- return Status;
+ goto cleanup;
}
// Get the Hub Interface
@@ -1611,8 +1657,7 @@
{
// failed to get root hub interface
DPRINT1("Failed to get HUB_GUID interface with status 0x%08lx\n",
Status);
- ExFreePool(Urb);
- return Status;
+ goto cleanup;
}
HubInterfaceBusContext = HubDeviceExtension->HubInterface.BusContext;
@@ -1628,8 +1673,7 @@
{
// failed to get usbdi interface
DPRINT1("Failed to get USBDI_GUID interface with status 0x%08lx\n",
Status);
- ExFreePool(Urb);
- return Status;
+ goto cleanup;
}
// Get Root Hub Device Handle
@@ -1642,8 +1686,7 @@
{
// failed
DPRINT1("IOCTL_INTERNAL_USB_GET_DEVICE_HANDLE failed with status
0x%08lx\n", Status);
- ExFreePool(Urb);
- return Status;
+ goto cleanup;
}
//
@@ -1687,8 +1730,7 @@
{
// failed to get device descriptor of hub
DPRINT1("Failed to get HubDeviceDescriptor!\n");
- ExFreePool(Urb);
- return Status;
+ goto cleanup;
}
// build configuration request
@@ -1715,8 +1757,7 @@
{
// failed to get configuration descriptor
DPRINT1("Failed to get RootHub Configuration with status %x\n",
Status);
- ExFreePool(Urb);
- return Status;
+ goto cleanup;
}
// sanity checks
@@ -1742,16 +1783,15 @@
{
// failed to get hub information
DPRINT1("Failed to extended hub information. Unable to determine the number
of ports!\n");
- ExFreePool(Urb);
- return Status;
+ goto cleanup;
}
if (!HubDeviceExtension->UsbExtHubInfo.NumberOfPorts)
{
// bogus port driver
DPRINT1("Failed to retrieve the number of ports\n");
- ExFreePool(Urb);
- return STATUS_UNSUCCESSFUL;
+ Status = STATUS_UNSUCCESSFUL;
+ goto cleanup;
}
DPRINT("HubDeviceExtension->UsbExtHubInfo.NumberOfPorts %x\n",
HubDeviceExtension->UsbExtHubInfo.NumberOfPorts);
@@ -1782,8 +1822,8 @@
if (!NT_SUCCESS(Status))
{
DPRINT1("Failed to get Hub Descriptor!\n");
- ExFreePool(Urb);
- return STATUS_UNSUCCESSFUL;
+ Status = STATUS_UNSUCCESSFUL;
+ goto cleanup;
}
// sanity checks
@@ -1811,14 +1851,21 @@
{
// failed to get hub status
DPRINT1("Failed to get Hub Status!\n");
- ExFreePool(Urb);
- return STATUS_UNSUCCESSFUL;
+ Status = STATUS_UNSUCCESSFUL;
+ goto cleanup;
}
// Allocate memory for PortStatusChange to hold 2 USHORTs for each port on hub
HubDeviceExtension->PortStatusChange = ExAllocatePoolWithTag(NonPagedPool,
sizeof(ULONG) *
HubDeviceExtension->UsbExtHubInfo.NumberOfPorts,
USB_HUB_TAG);
+
+ if (!HubDeviceExtension->PortStatusChange)
+ {
+ DPRINT1("Failed to allocate pool for PortStatusChange!\n");
+ Status = STATUS_INSUFFICIENT_RESOURCES;
+ goto cleanup;
+ }
// Get the first Configuration Descriptor
Pid =
USBD_ParseConfigurationDescriptorEx(&HubDeviceExtension->HubConfigDescriptor,
@@ -1828,8 +1875,8 @@
{
// failed parse hub descriptor
DPRINT1("Failed to parse configuration descriptor\n");
- ExFreePool(Urb);
- return STATUS_UNSUCCESSFUL;
+ Status = STATUS_UNSUCCESSFUL;
+ goto cleanup;
}
// create configuration request
@@ -1840,8 +1887,8 @@
{
// failed to build urb
DPRINT1("Failed to allocate urb\n");
- ExFreePool(Urb);
- return STATUS_INSUFFICIENT_RESOURCES;
+ Status = STATUS_INSUFFICIENT_RESOURCES;
+ goto cleanup;
}
// send request
@@ -1853,9 +1900,7 @@
{
// failed to select configuration
DPRINT1("Failed to select configuration with %x\n", Status);
- ExFreePool(Urb);
- ExFreePool(ConfigUrb);
- return Status;
+ goto cleanup;
}
// store configuration & pipe handle
@@ -1863,12 +1908,6 @@
HubDeviceExtension->PipeHandle =
ConfigUrb->UrbSelectConfiguration.Interface.Pipes[0].PipeHandle;
DPRINT("Configuration Handle %x\n",
HubDeviceExtension->ConfigurationHandle);
- FDO_QueryInterface(DeviceObject, &HubDeviceExtension->DeviceInterface);
-
-
- // free urb
- ExFreePool(ConfigUrb);
-
// check if function is available
if (HubDeviceExtension->UsbDInterface.IsDeviceHighSpeed)
{
@@ -1908,8 +1947,7 @@
if (!NT_SUCCESS(Status))
{
DPRINT1("Failed to set callback\n");
- ExFreePool(Urb);
- return Status;
+ goto cleanup;
}
}
else
@@ -1961,7 +1999,29 @@
// free urb
ExFreePool(Urb);
+ // free ConfigUrb
+ ExFreePool(ConfigUrb);
+
// done
+ return Status;
+
+cleanup:
+ if (Urb)
+ ExFreePool(Urb);
+
+ // Dereference interfaces
+ if (HubDeviceExtension->HubInterface.Size)
+
HubDeviceExtension->HubInterface.InterfaceDereference(HubDeviceExtension->HubInterface.BusContext);
+
+ if (HubDeviceExtension->UsbDInterface.Size)
+
HubDeviceExtension->UsbDInterface.InterfaceDereference(HubDeviceExtension->UsbDInterface.BusContext);
+
+ if (HubDeviceExtension->PortStatusChange)
+ ExFreePool(HubDeviceExtension->PortStatusChange);
+
+ if (ConfigUrb)
+ ExFreePool(ConfigUrb);
+
return Status;
}
@@ -1972,17 +2032,31 @@
{
PIO_STACK_LOCATION Stack;
NTSTATUS Status = STATUS_SUCCESS;
- ULONG_PTR Information = 0;
+ PDEVICE_OBJECT ChildDeviceObject;
PHUB_DEVICE_EXTENSION HubDeviceExtension;
+ PUSB_BUS_INTERFACE_HUB_V5 HubInterface;
+ PHUB_CHILDDEVICE_EXTENSION ChildDeviceExtension;
HubDeviceExtension = (PHUB_DEVICE_EXTENSION) DeviceObject->DeviceExtension;
+ HubInterface = &HubDeviceExtension->HubInterface;
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)
{
+ int i;
+
case IRP_MN_START_DEVICE:
{
+ DPRINT("IRP_MN_START_DEVICE\n");
if (USBHUB_IsRootHubFDO(DeviceObject))
{
// start root hub fdo
@@ -1992,7 +2066,13 @@
{
Status = USBHUB_ParentFDOStartDevice(DeviceObject, Irp);
}
- break;
+
+ SET_NEW_PNP_STATE(HubDeviceExtension->Common, Started);
+
+ Irp->IoStatus.Status = Status;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ IoReleaseRemoveLock(&HubDeviceExtension->Common.RemoveLock, Irp);
+ return Status;
}
case IRP_MN_QUERY_DEVICE_RELATIONS:
@@ -2002,66 +2082,197 @@
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;
+ 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);
+
IoReleaseRemoveLock(&HubDeviceExtension->Common.RemoveLock, Irp);
+ return Status;
+ }
+
+ Irp->IoStatus.Information = (ULONG_PTR)DeviceRelations;
+ Irp->IoStatus.Status = Status;
break;
}
case RemovalRelations:
{
DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS /
RemovalRelations\n");
- return ForwardIrpAndForget(DeviceObject, Irp);
+ break;
}
default:
DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / Unknown
type 0x%lx\n",
Stack->Parameters.QueryDeviceRelations.Type);
- return ForwardIrpAndForget(DeviceObject, Irp);
+ break;
}
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
+ // PnP manager rebalances resources.
+ //
+ Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ return STATUS_NOT_SUPPORTED;
+ }
case IRP_MN_QUERY_REMOVE_DEVICE:
- case IRP_MN_QUERY_STOP_DEVICE:
- {
+ {
+ // 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;
- return ForwardIrpAndForget(DeviceObject, Irp);
+ 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;
+ }
+ case IRP_MN_SURPRISE_REMOVAL:
+ {
+ //
+ // We'll receive this IRP on HUB unexpected removal, or on USB
+ // controller removal from PCI port. Here we should "let know" all
+ // 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);
+
+ for (i = 0; i < USB_MAXCHILDREN; i++)
+ {
+ ChildDeviceObject = HubDeviceExtension->ChildDeviceObject[i];
+ if (ChildDeviceObject)
+ {
+ ChildDeviceExtension =
(PHUB_CHILDDEVICE_EXTENSION)ChildDeviceObject->DeviceObjectExtension;
+ ChildDeviceExtension->ParentDeviceObject = NULL;
+ }
+ }
+
+ KeReleaseGuardedMutex(&HubDeviceExtension->HubMutexLock);
+
+ // This IRP can't be failed
+ Irp->IoStatus.Status = STATUS_SUCCESS;
+ break;
}
case IRP_MN_REMOVE_DEVICE:
{
+ DPRINT("IRP_MN_REMOVE_DEVICE\n");
+
+ SET_NEW_PNP_STATE(HubDeviceExtension->Common, Deleted);
+
+ IoReleaseRemoveLockAndWait(&HubDeviceExtension->Common.RemoveLock,
Irp);
+
+ //
+ // Here we should remove all child PDOs. At this point all children
+ // received and returned from IRP_MN_REMOVE so remove synchronization
+ // isn't needed here
+ //
+
+ KeAcquireGuardedMutex(&HubDeviceExtension->HubMutexLock);
+
+ for (i = 0; i < USB_MAXCHILDREN; i++)
+ {
+ ChildDeviceObject = HubDeviceExtension->ChildDeviceObject[i];
+ if (ChildDeviceObject)
+ {
+ PHUB_CHILDDEVICE_EXTENSION UsbChildExtension =
(PHUB_CHILDDEVICE_EXTENSION)ChildDeviceObject->DeviceExtension;
+
+ SET_NEW_PNP_STATE(UsbChildExtension->Common, Deleted);
+
+ // Remove the usb device
+ if (UsbChildExtension->UsbDeviceHandle)
+ {
+ Status =
HubInterface->RemoveUsbDevice(HubInterface->BusContext,
UsbChildExtension->UsbDeviceHandle, 0);
+ ASSERT(Status == STATUS_SUCCESS);
+ }
+
+ // Free full configuration descriptor
+ if (UsbChildExtension->FullConfigDesc)
+ ExFreePool(UsbChildExtension->FullConfigDesc);
+
+ // Free ID buffers
+ if (UsbChildExtension->usCompatibleIds.Buffer)
+ ExFreePool(UsbChildExtension->usCompatibleIds.Buffer);
+
+ if (UsbChildExtension->usDeviceId.Buffer)
+ ExFreePool(UsbChildExtension->usDeviceId.Buffer);
+
+ if (UsbChildExtension->usHardwareIds.Buffer)
+ ExFreePool(UsbChildExtension->usHardwareIds.Buffer);
+
+ if (UsbChildExtension->usInstanceId.Buffer)
+ ExFreePool(UsbChildExtension->usInstanceId.Buffer);
+
+ DPRINT("Deleting child PDO\n");
+ IoDeleteDevice(DeviceObject);
+ ChildDeviceObject = NULL;
+ }
+ }
+
+ KeReleaseGuardedMutex(&HubDeviceExtension->HubMutexLock);
+
Irp->IoStatus.Status = STATUS_SUCCESS;
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ Status = ForwardIrpAndForget(DeviceObject, Irp);
IoDetachDevice(HubDeviceExtension->LowerDeviceObject);
+ DPRINT("Deleting FDO 0x%p\n", DeviceObject);
IoDeleteDevice(DeviceObject);
- return STATUS_SUCCESS;
+ return Status;
}
case IRP_MN_QUERY_BUS_INFORMATION:
{
+ // Function drivers and filter drivers do not handle this IRP.
DPRINT("IRP_MN_QUERY_BUS_INFORMATION\n");
break;
}
case IRP_MN_QUERY_ID:
{
DPRINT("IRP_MN_QUERY_ID\n");
+ // Function drivers and filter drivers do not handle this IRP.
break;
}
case IRP_MN_QUERY_CAPABILITIES:
{
+ //
+ // If a function or filter driver does not handle this IRP, it
+ // should pass that down.
+ //
DPRINT("IRP_MN_QUERY_CAPABILITIES\n");
break;
}
default:
{
DPRINT(" IRP_MJ_PNP / unknown minor function 0x%lx\n",
Stack->MinorFunction);
- return ForwardIrpAndForget(DeviceObject, Irp);
- }
- }
-
- Irp->IoStatus.Information = Information;
- Irp->IoStatus.Status = Status;
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ break;
+ }
+ }
+
+ Status = ForwardIrpAndForget(DeviceObject, Irp);
+ IoReleaseRemoveLock(&HubDeviceExtension->Common.RemoveLock, Irp);
return Status;
}
@@ -2086,6 +2297,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
@@ -2131,6 +2361,7 @@
// sanity checks
ASSERT(NodeConnectionInfo);
+ KeAcquireGuardedMutex(&HubDeviceExtension->HubMutexLock);
for(Index = 0; Index < USB_MAXCHILDREN; Index++)
{
if (HubDeviceExtension->ChildDeviceObject[Index] == NULL)
@@ -2157,6 +2388,7 @@
}
break;
}
+ KeReleaseGuardedMutex(&HubDeviceExtension->HubMutexLock);
// done
Irp->IoStatus.Information = sizeof(USB_NODE_INFORMATION);
Status = STATUS_SUCCESS;
@@ -2177,6 +2409,7 @@
// sanity checks
ASSERT(NodeKey);
+ KeAcquireGuardedMutex(&HubDeviceExtension->HubMutexLock);
for(Index = 0; Index < USB_MAXCHILDREN; Index++)
{
if (HubDeviceExtension->ChildDeviceObject[Index] == NULL)
@@ -2216,6 +2449,7 @@
NodeKey->ActualLength = Length +
sizeof(USB_NODE_CONNECTION_DRIVERKEY_NAME);
break;
}
+ KeReleaseGuardedMutex(&HubDeviceExtension->HubMutexLock);
}
}
else if (IoStack->Parameters.DeviceIoControl.IoControlCode ==
IOCTL_USB_GET_NODE_CONNECTION_NAME)
@@ -2247,6 +2481,7 @@
Irp->IoStatus.Status = Status;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ IoReleaseRemoveLock(&HubDeviceExtension->Common.RemoveLock, Irp);
return Status;
}
Modified: trunk/reactos/drivers/usb/usbhub/misc.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/usb/usbhub/misc.c?…
==============================================================================
--- trunk/reactos/drivers/usb/usbhub/misc.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/usb/usbhub/misc.c [iso-8859-1] Fri Jan 27 11:09:36 2017
@@ -211,84 +211,3 @@
return Status;
}
-
-NTSTATUS
-NTAPI
-FDO_QueryInterfaceCompletionRoutine(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp,
- IN PVOID Context)
-{
- /* Set event */
- KeSetEvent((PRKEVENT)Context, 0, FALSE);
-
- /* Completion is done in the HidClassFDO_QueryCapabilities routine */
- return STATUS_MORE_PROCESSING_REQUIRED;
-}
-
-NTSTATUS
-FDO_QueryInterface(
- IN PDEVICE_OBJECT DeviceObject,
- IN OUT PUSB_BUS_INTERFACE_USBDI_V2 Interface)
-{
- PIRP Irp;
- KEVENT Event;
- NTSTATUS Status;
- PIO_STACK_LOCATION IoStack;
- PHUB_DEVICE_EXTENSION HubDeviceExtension;
-
- /* Get device extension */
- HubDeviceExtension = (PHUB_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
- ASSERT(HubDeviceExtension->Common.IsFDO);
-
- /* Init event */
- KeInitializeEvent(&Event, NotificationEvent, FALSE);
-
- /* Now allocate the irp */
- Irp = IoAllocateIrp(DeviceObject->StackSize, FALSE);
- if (!Irp)
- {
- /* No memory */
- return STATUS_INSUFFICIENT_RESOURCES;
- }
-
- /* Get next stack location */
- IoStack = IoGetNextIrpStackLocation(Irp);
-
- /* Init stack location */
- IoStack->MajorFunction = IRP_MJ_PNP;
- IoStack->MinorFunction = IRP_MN_QUERY_INTERFACE;
- IoStack->Parameters.QueryInterface.Interface = (PINTERFACE)Interface;
- IoStack->Parameters.QueryInterface.InterfaceType =
&USB_BUS_INTERFACE_USBDI_GUID;
- IoStack->Parameters.QueryInterface.Version = USB_BUSIF_USBDI_VERSION_2;
- IoStack->Parameters.QueryInterface.Size = sizeof(USB_BUS_INTERFACE_USBDI_V2);
-
-
- /* Set completion routine */
- IoSetCompletionRoutine(Irp,
- FDO_QueryInterfaceCompletionRoutine,
- (PVOID)&Event,
- TRUE,
- TRUE,
- TRUE);
-
- /* Pnp irps have default completion code */
- Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
-
- /* Call lower device */
- Status = IoCallDriver(HubDeviceExtension->LowerDeviceObject, Irp);
- if (Status == STATUS_PENDING)
- {
- /* Wait for completion */
- KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
- }
-
- /* Get status */
- Status = Irp->IoStatus.Status;
-
- /* Complete request */
- IoFreeIrp(Irp);
-
- /* Done */
- return Status;
-}
Modified: trunk/reactos/drivers/usb/usbhub/pdo.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/usb/usbhub/pdo.c?r…
==============================================================================
--- trunk/reactos/drivers/usb/usbhub/pdo.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/usb/usbhub/pdo.c [iso-8859-1] Fri Jan 27 11:09:36 2017
@@ -146,16 +146,25 @@
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;
+ KeAcquireGuardedMutex(&HubDeviceExtension->HubMutexLock);
for(Index = 0; Index < USB_MAXCHILDREN; Index++)
{
if (HubDeviceExtension->ChildDeviceObject[Index] == DeviceObject)
{
+ KeReleaseGuardedMutex(&HubDeviceExtension->HubMutexLock);
+
/* PDO exists */
return TRUE;
}
}
+ KeReleaseGuardedMutex(&HubDeviceExtension->HubMutexLock);
/* invalid pdo */
return FALSE;
@@ -190,17 +199,30 @@
ChildDeviceExtension = (PHUB_CHILDDEVICE_EXTENSION)DeviceObject->DeviceExtension;
ASSERT(ChildDeviceExtension->Common.IsFDO == FALSE);
- HubDeviceExtension =
(PHUB_DEVICE_EXTENSION)ChildDeviceExtension->ParentDeviceObject->DeviceExtension;
- RootHubDeviceObject = HubDeviceExtension->RootHubPhysicalDeviceObject;
-
- if(!IsValidPDO(DeviceObject))
- {
+
+ 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 ||
+ ChildDeviceExtension->ParentDeviceObject == NULL)
+ {
+ // 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);
+ IoReleaseRemoveLock(&ChildDeviceExtension->Common.RemoveLock, Irp);
return STATUS_DEVICE_NOT_CONNECTED;
}
+
+ HubDeviceExtension =
(PHUB_DEVICE_EXTENSION)ChildDeviceExtension->ParentDeviceObject->DeviceExtension;
+ RootHubDeviceObject = HubDeviceExtension->RootHubPhysicalDeviceObject;
switch (Stack->Parameters.DeviceIoControl.IoControlCode)
{
@@ -301,6 +323,7 @@
// Send the request to RootHub
//
Status = ForwardUrbToRootHub(RootHubDeviceObject,
IOCTL_INTERNAL_USB_SUBMIT_URB, Irp, Urb, NULL);
+ IoReleaseRemoveLock(&ChildDeviceExtension->Common.RemoveLock, Irp);
return Status;
}
//
@@ -397,6 +420,7 @@
Irp->IoStatus.Status = Status;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
}
+ IoReleaseRemoveLock(&ChildDeviceExtension->Common.RemoveLock, Irp);
return Status;
}
@@ -420,6 +444,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;
@@ -563,14 +589,19 @@
PIO_STACK_LOCATION Stack;
ULONG_PTR Information = 0;
PHUB_CHILDDEVICE_EXTENSION UsbChildExtension;
- ULONG Index;
- ULONG bFound;
PDEVICE_RELATIONS DeviceRelation;
- PDEVICE_OBJECT ParentDevice;
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)
{
@@ -628,17 +659,20 @@
}
case IRP_MN_QUERY_DEVICE_TEXT:
{
+ DPRINT("IRP_MN_QUERY_DEVICE_TEXT\n");
Status = USBHUB_PdoQueryDeviceText(DeviceObject, Irp, &Information);
break;
}
case IRP_MN_QUERY_ID:
{
+ DPRINT("IRP_MN_QUERY_ID\n");
Status = USBHUB_PdoQueryId(DeviceObject, Irp, &Information);
break;
}
case IRP_MN_QUERY_BUS_INFORMATION:
{
PPNP_BUS_INFORMATION BusInfo;
+ DPRINT("IRP_MN_QUERY_BUS_INFORMATION\n");
BusInfo = (PPNP_BUS_INFORMATION)ExAllocatePool(PagedPool,
sizeof(PNP_BUS_INFORMATION));
RtlCopyMemory(&BusInfo->BusTypeGuid,
&GUID_BUS_TYPE_USB,
@@ -654,42 +688,58 @@
{
PHUB_DEVICE_EXTENSION HubDeviceExtension =
(PHUB_DEVICE_EXTENSION)UsbChildExtension->ParentDeviceObject->DeviceExtension;
PUSB_BUS_INTERFACE_HUB_V5 HubInterface =
&HubDeviceExtension->HubInterface;
- ParentDevice = UsbChildExtension->ParentDeviceObject;
DPRINT("IRP_MJ_PNP / IRP_MN_REMOVE_DEVICE\n");
- /* remove us from pdo list */
- bFound = FALSE;
- for(Index = 0; Index < USB_MAXCHILDREN; Index++)
- {
- if (HubDeviceExtension->ChildDeviceObject[Index] == DeviceObject)
+ 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);
+
+ IoReleaseRemoveLockAndWait(&UsbChildExtension->Common.RemoveLock,
Irp);
+
+ // Remove the usb device
+ if (UsbChildExtension->UsbDeviceHandle)
{
- /* Remove the device */
- Status =
HubInterface->RemoveUsbDevice(HubDeviceExtension->UsbDInterface.BusContext,
UsbChildExtension->UsbDeviceHandle, 0);
-
- /* FIXME handle error */
- ASSERT(Status == STATUS_SUCCESS);
-
- /* remove us */
- HubDeviceExtension->ChildDeviceObject[Index] = NULL;
- bFound = TRUE;
- break;
+ Status =
HubInterface->RemoveUsbDevice(HubInterface->BusContext,
UsbChildExtension->UsbDeviceHandle, 0);
+ ASSERT(Status == STATUS_SUCCESS);
}
- }
+ // Free full configuration descriptor
+ if (UsbChildExtension->FullConfigDesc)
+ ExFreePool(UsbChildExtension->FullConfigDesc);
+
+ // Free ID buffers
+ if (UsbChildExtension->usCompatibleIds.Buffer)
+ ExFreePool(UsbChildExtension->usCompatibleIds.Buffer);
+
+ if (UsbChildExtension->usDeviceId.Buffer)
+ ExFreePool(UsbChildExtension->usDeviceId.Buffer);
+
+ if (UsbChildExtension->usHardwareIds.Buffer)
+ ExFreePool(UsbChildExtension->usHardwareIds.Buffer);
+
+ if (UsbChildExtension->usInstanceId.Buffer)
+ ExFreePool(UsbChildExtension->usInstanceId.Buffer);
+
+ DPRINT("Deleting child PDO\n");
+ IoDeleteDevice(DeviceObject);
+ }
+ else
+ {
+ IoReleaseRemoveLock(&UsbChildExtension->Common.RemoveLock, Irp);
+ }
+
+ // If device is physically presented, we leave its PDO undeleted.
/* Complete the IRP */
Irp->IoStatus.Status = STATUS_SUCCESS;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
- /* delete device */
- IoDeleteDevice(DeviceObject);
-
- if (bFound)
- {
- /* invalidate device relations */
- IoInvalidateDeviceRelations(ParentDevice, BusRelations);
- }
-
return STATUS_SUCCESS;
}
case IRP_MN_QUERY_DEVICE_RELATIONS:
@@ -699,6 +749,7 @@
{
/* not supported */
Status = Irp->IoStatus.Status;
+ Information = Irp->IoStatus.Information;
break;
}
@@ -722,13 +773,46 @@
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:
{
+ //
+ // Free interface obtained from bottom, according MSDN we should
+ // check interfaces provided to top, but here we are not checking.
+ // All checking will be performed in roothub driver's
+ // IRP_MN_QUERY_REMOVE_DEVICE handler. This will make problems when
+ // buggy driver is loaded on top of us. But we decided to keep source
+ // simpler, because in any case buggy driver will prevent removing of
+ // whole stack.
+ //
+
UsbChildExtension->DeviceInterface.InterfaceDereference(UsbChildExtension->DeviceInterface.BusContext);
+
+ SET_NEW_PNP_STATE(UsbChildExtension->Common, RemovePending);
+
/* Sure, no problem */
Status = STATUS_SUCCESS;
Information = 0;
break;
}
+ case IRP_MN_CANCEL_REMOVE_DEVICE:
+ {
+ // Check to see have we received query-remove before
+ if (UsbChildExtension->Common.PnPState == RemovePending)
+ {
+ RESTORE_PREVIOUS_PNP_STATE(UsbChildExtension->Common);
+
UsbChildExtension->DeviceInterface.InterfaceReference(UsbChildExtension->DeviceInterface.BusContext);
+ }
+
+ Status = STATUS_SUCCESS;
+ break;
+ }
case IRP_MN_QUERY_INTERFACE:
{
DPRINT1("IRP_MN_QUERY_INTERFACE\n");
@@ -736,17 +820,28 @@
{
DPRINT1("USB_BUS_INTERFACE_USBDI_GUID\n");
RtlCopyMemory(Stack->Parameters.QueryInterface.Interface,
&UsbChildExtension->DeviceInterface, Stack->Parameters.QueryInterface.Size);
+
UsbChildExtension->DeviceInterface.InterfaceReference(UsbChildExtension->DeviceInterface.BusContext);
Status = STATUS_SUCCESS;
break;
}
// 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:
{
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).
+ //
+ SET_NEW_PNP_STATE(UsbChildExtension->Common, SurpriseRemovePending);
+
Status = STATUS_SUCCESS;
break;
}
@@ -757,6 +852,8 @@
Status = Irp->IoStatus.Status;
}
}
+
+ IoReleaseRemoveLock(&UsbChildExtension->Common.RemoveLock, Irp);
Irp->IoStatus.Information = Information;
Irp->IoStatus.Status = Status;
Modified: trunk/reactos/drivers/usb/usbhub/usbhub.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/usb/usbhub/usbhub.…
==============================================================================
--- trunk/reactos/drivers/usb/usbhub/usbhub.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/usb/usbhub/usbhub.c [iso-8859-1] Fri Jan 27 11:09:36 2017
@@ -62,7 +62,7 @@
PDEVICE_OBJECT DeviceObject;
PHUB_DEVICE_EXTENSION HubDeviceExtension;
NTSTATUS Status;
- DPRINT("USBHUB: AddDevice\n");
+ DPRINT("USBHUB: AddDevice (%p)\n", PhysicalDeviceObject);
//
// Create the Device Object
//
@@ -86,11 +86,19 @@
HubDeviceExtension = (PHUB_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
RtlZeroMemory(HubDeviceExtension, sizeof(HUB_DEVICE_EXTENSION));
+ INITIALIZE_PNP_STATE(HubDeviceExtension->Common);
+
//
// Set this to Fdo
//
HubDeviceExtension->Common.IsFDO = TRUE;
DeviceObject->Flags |= DO_POWER_PAGABLE;
+
+ // initialize mutex
+ KeInitializeGuardedMutex(&HubDeviceExtension->HubMutexLock);
+
+ // initialize remove lock
+ IoInitializeRemoveLock(&HubDeviceExtension->Common.RemoveLock, 'buH',
0, 0);
//
// initialize reset complete event
@@ -159,6 +167,18 @@
}
NTSTATUS NTAPI
+USBHUB_DispatchSystemControl(
+ PDEVICE_OBJECT DeviceObject,
+ PIRP Irp)
+{
+ DPRINT("Usbhub: DispatchSystemControl\n");
+ if (((PHUB_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->Common.IsFDO)
+ return USBHUB_IrpStub(DeviceObject, Irp);
+ else
+ return USBHUB_IrpStub(DeviceObject, Irp);
+}
+
+NTSTATUS NTAPI
USBHUB_DispatchInternalDeviceControl(
PDEVICE_OBJECT DeviceObject,
PIRP Irp)
@@ -188,37 +208,59 @@
PIRP Irp)
{
PIO_STACK_LOCATION IoStack;
-
+ PHUB_DEVICE_EXTENSION DeviceExtension;
+ NTSTATUS Status;
IoStack = IoGetCurrentIrpStackLocation(Irp);
+ DeviceExtension = DeviceObject->DeviceExtension;
+
+ Status = IoAcquireRemoveLock(&DeviceExtension->Common.RemoveLock, Irp);
+ if (!NT_SUCCESS(Status))
+ {
+ Irp->IoStatus.Status = Status;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ return Status;
+ }
+
DPRINT1("Power Function %x\n", IoStack->MinorFunction);
- if (IoStack->MinorFunction == IRP_MN_SET_POWER)
+ if (DeviceExtension->Common.IsFDO)
{
PoStartNextPowerIrp(Irp);
- Irp->IoStatus.Status = STATUS_SUCCESS;
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
- return STATUS_SUCCESS;
-
- }
- else if (IoStack->MinorFunction == IRP_MN_QUERY_POWER)
- {
- PoStartNextPowerIrp(Irp);
- Irp->IoStatus.Status = STATUS_SUCCESS;
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
- return STATUS_SUCCESS;
-
- }
- else if (IoStack->MinorFunction == IRP_MN_WAIT_WAKE)
- {
- PoStartNextPowerIrp(Irp);
- Irp->IoStatus.Status = STATUS_SUCCESS;
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
- return STATUS_SUCCESS;
+ IoSkipCurrentIrpStackLocation(Irp);
+ Status = PoCallDriver(DeviceExtension->LowerDeviceObject, Irp);
+ IoReleaseRemoveLock(&DeviceExtension->Common.RemoveLock, Irp);
+ return Status;
+ }
+
+ switch (IoStack->MinorFunction)
+ {
+ case IRP_MN_SET_POWER:
+ {
+ DPRINT("IRP_MN_SET_POWER\n");
+ break;
+ }
+ case IRP_MN_QUERY_POWER:
+ {
+ DPRINT("IRP_MN_QUERY_POWER\n");
+ break;
+ }
+ case IRP_MN_WAIT_WAKE:
+ {
+ DPRINT("IRP_MN_WAIT_WAKE\n");
+ break;
+ }
+ default:
+ {
+ DPRINT1("PDO IRP_MJ_POWER / unknown minor function 0x%lx\n",
IoStack->MinorFunction);
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ return Irp->IoStatus.Status;
+ }
}
PoStartNextPowerIrp(Irp);
Irp->IoStatus.Status = STATUS_SUCCESS;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ IoReleaseRemoveLock(&DeviceExtension->Common.RemoveLock, Irp);
return STATUS_SUCCESS;
}
@@ -245,6 +287,7 @@
DriverObject->MajorFunction[IRP_MJ_CLOSE] = USBHUB_Close;
DriverObject->MajorFunction[IRP_MJ_CLEANUP] = USBHUB_Cleanup;
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] =
USBHUB_DispatchDeviceControl;
+ DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] =
USBHUB_DispatchSystemControl;
DriverObject->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] =
USBHUB_DispatchInternalDeviceControl;
DriverObject->MajorFunction[IRP_MJ_PNP] = USBHUB_DispatchPnp;
DriverObject->MajorFunction[IRP_MJ_POWER] =USBHUB_DispatchPower;
Modified: trunk/reactos/drivers/usb/usbhub/usbhub.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/usb/usbhub/usbhub.…
==============================================================================
--- trunk/reactos/drivers/usb/usbhub/usbhub.h [iso-8859-1] (original)
+++ trunk/reactos/drivers/usb/usbhub/usbhub.h [iso-8859-1] Fri Jan 27 11:09:36 2017
@@ -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).PreviousPnPState = (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
@@ -72,6 +106,8 @@
PDEVICE_OBJECT RootHubPhysicalDeviceObject;
PDEVICE_OBJECT RootHubFunctionalDeviceObject;
+ KGUARDED_MUTEX HubMutexLock;
+
ULONG NumberOfHubs;
KEVENT ResetComplete;
@@ -94,7 +130,6 @@
USBD_CONFIGURATION_HANDLE ConfigurationHandle;
USBD_PIPE_HANDLE PipeHandle;
PVOID RootHubHandle;
- USB_BUS_INTERFACE_USBDI_V2 DeviceInterface;
UNICODE_STRING SymbolicLinkName;
ULONG InstanceCount;
Modified: trunk/reactos/sdk/lib/drivers/hidparser/context.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/sdk/lib/drivers/hidparser/…
==============================================================================
--- trunk/reactos/sdk/lib/drivers/hidparser/context.c [iso-8859-1] (original)
+++ trunk/reactos/sdk/lib/drivers/hidparser/context.c [iso-8859-1] Fri Jan 27 11:09:36
2017
@@ -163,7 +163,7 @@
//
// store offset
//
- TargetCollection->Offsets[Collection->NodeCount + Index] = CurrentOffset;
+ TargetCollection->Offsets[Collection->ReportCount + Index] =
CurrentOffset;
//
// store sub collections
@@ -254,7 +254,7 @@
//
// get collection
//
- SubCollection = (PHID_COLLECTION)(CollectionContext->RawData +
Collection->Offsets[Collection->NodeCount + Index]);
+ SubCollection = (PHID_COLLECTION)(CollectionContext->RawData +
Collection->Offsets[Collection->ReportCount + Index]);
//
// recursively search collection
@@ -314,7 +314,7 @@
//
// get offset to sub collection
//
- SubCollection = (PHID_COLLECTION)(CollectionContext->RawData +
Collection->Offsets[Collection->NodeCount + Index]);
+ SubCollection = (PHID_COLLECTION)(CollectionContext->RawData +
Collection->Offsets[Collection->ReportCount + Index]);
//
// count collection for sub nodes
Modified: trunk/reactos/sdk/lib/drivers/hidparser/hidparser.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/sdk/lib/drivers/hidparser/…
==============================================================================
--- trunk/reactos/sdk/lib/drivers/hidparser/hidparser.c [iso-8859-1] (original)
+++ trunk/reactos/sdk/lib/drivers/hidparser/hidparser.c [iso-8859-1] Fri Jan 27 11:09:36
2017
@@ -68,7 +68,7 @@
// failed to parse report descriptor
//
Parser->Debug("[HIDPARSER] Failed to parse report descriptor with
%x\n", ParserStatus);
- return TranslateHidParserStatus(ParserStatus);
+ return ParserStatus;
}
//
@@ -126,7 +126,9 @@
//
// no memory
//
- return TranslateHidParserStatus(ParserStatus);
+ Parser->Free(DeviceDescription->CollectionDesc);
+ Parser->Free(DeviceDescription->ReportIDs);
+ return ParserStatus;
}
//
@@ -153,6 +155,13 @@
// get collection usage page
//
ParserStatus =
HidParser_GetCollectionUsagePage((PVOID)DeviceDescription->CollectionDesc[Index].PreparsedData,
&DeviceDescription->CollectionDesc[Index].Usage,
&DeviceDescription->CollectionDesc[Index].UsagePage);
+ if (ParserStatus != HIDPARSER_STATUS_SUCCESS)
+ {
+ // collection not found
+ Parser->Free(DeviceDescription->CollectionDesc);
+ Parser->Free(DeviceDescription->ReportIDs);
+ return ParserStatus;
+ }
//
// windows seems to prepend the report id, regardless if it is required
Modified: trunk/reactos/sdk/lib/drivers/hidparser/parser.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/sdk/lib/drivers/hidparser/…
==============================================================================
--- trunk/reactos/sdk/lib/drivers/hidparser/parser.c [iso-8859-1] (original)
+++ trunk/reactos/sdk/lib/drivers/hidparser/parser.c [iso-8859-1] Fri Jan 27 11:09:36
2017
@@ -712,30 +712,6 @@
//
return HIDPARSER_STATUS_SUCCESS;
}
-
-HIDPARSER_STATUS
-AllocateParserContext(
- IN PHID_PARSER Parser,
- OUT PHID_PARSER_CONTEXT *OutParserContext)
-{
- PHID_PARSER_CONTEXT ParserContext;
-
- ParserContext = Parser->Alloc(sizeof(HID_PARSER_CONTEXT));
- if (!ParserContext)
- {
- //
- // failed
- //
- return HIDPARSER_STATUS_INSUFFICIENT_RESOURCES;
- }
-
- //
- // store result
- //
- *OutParserContext = ParserContext;
- return HIDPARSER_STATUS_SUCCESS;
-}
-
HIDPARSER_STATUS
HidParser_ParseReportDescriptor(
@@ -760,12 +736,18 @@
PMAIN_ITEM_DATA MainItemData;
PHID_PARSER_CONTEXT ParserContext;
+ CurrentOffset = ReportDescriptor;
+ ReportEnd = ReportDescriptor + ReportLength;
+
+ if (ReportDescriptor >= ReportEnd)
+ return HIDPARSER_STATUS_COLLECTION_NOT_FOUND;
+
//
// allocate parser
//
- Status = AllocateParserContext(Parser, &ParserContext);
- if (Status != HIDPARSER_STATUS_SUCCESS)
- return Status;
+ ParserContext = Parser->Alloc(sizeof(HID_PARSER_CONTEXT));;
+ if (!ParserContext)
+ return HIDPARSER_STATUS_INSUFFICIENT_RESOURCES;
//
@@ -778,6 +760,7 @@
//
// no memory
//
+ Parser->Free(ParserContext);
return HIDPARSER_STATUS_INSUFFICIENT_RESOURCES;
}
@@ -792,6 +775,7 @@
//
Parser->Free(ParserContext->LocalItemState.UsageStack);
ParserContext->LocalItemState.UsageStack = NULL;
+ Parser->Free(ParserContext);
return HIDPARSER_STATUS_INSUFFICIENT_RESOURCES;
}
@@ -799,8 +783,6 @@
// start parsing
//
CurrentCollection = ParserContext->RootCollection;
- CurrentOffset = ReportDescriptor;
- ReportEnd = ReportDescriptor + ReportLength;
do
{
@@ -1230,8 +1212,7 @@
//
CurrentOffset += CurrentItemSize + sizeof(ITEM_PREFIX);
-
- }while(CurrentOffset < ReportEnd);
+ }while (CurrentOffset < ReportEnd);
//
Modified: trunk/reactos/sdk/lib/drivers/libusb/hub_controller.cpp
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/sdk/lib/drivers/libusb/hub…
==============================================================================
--- trunk/reactos/sdk/lib/drivers/libusb/hub_controller.cpp [iso-8859-1] (original)
+++ trunk/reactos/sdk/lib/drivers/libusb/hub_controller.cpp [iso-8859-1] Fri Jan 27
11:09:36 2017
@@ -568,7 +568,8 @@
break;
}
}
- Status = STATUS_SUCCESS;
+ // Here we should leave Status as is.
+ Status = Irp->IoStatus.Status;
break;
}
case IRP_MN_QUERY_CAPABILITIES:
@@ -611,6 +612,14 @@
// handle device interface requests
//
Status = HandleQueryInterface(IoStack);
+
+ //
+ // If a bus driver does not export the requested interface, it
+ // should leave Status as is.
+ //
+ if (Status == STATUS_NOT_SUPPORTED)
+ Status = Irp->IoStatus.Status;
+
break;
}
case IRP_MN_REMOVE_DEVICE:
@@ -3736,6 +3745,7 @@
InterfaceHub->SetDeviceHandleData = USBHI_SetDeviceHandleData;
}
+ InterfaceHub->InterfaceReference(InterfaceHub->BusContext);
//
// request completed
//
@@ -3790,6 +3800,7 @@
InterfaceDI->EnumLogEntry = USBDI_EnumLogEntry;
}
+ InterfaceDI->InterfaceReference(InterfaceDI->BusContext);
//
// request completed
//
Propchange: trunk/reactos/sdk/lib/drivers/libusb/hub_controller.cpp
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Fri Jan 27 11:09:36 2017
@@ -4,6 +4,7 @@
/branches/GSoC_2011/GSoC_TcpIpDriver/drivers/usb/usbehci_new/hub_controller.cpp:51550
/branches/GSoC_2011/TcpIpDriver/drivers/usb/usbehci/hub_controller.cpp:51551-53074,53076-53119
/branches/GSoC_2011/TcpIpDriver/drivers/usb/usbehci_new/hub_controller.cpp:51551-53074,53076-53119
+/branches/GSoC_2016/USB/sdk/lib/drivers/libusb/hub_controller.cpp:72365-73604
/branches/GSoC_Network/drivers/usb/usbehci/hub_controller.cpp:51545-51546
/branches/GSoC_Network/drivers/usb/usbehci_new/hub_controller.cpp:51545-51546
/branches/cmake-bringup/drivers/usb/usbehci/hub_controller.cpp:50484,50693,50719,51544-52564