mirror of
https://github.com/reactos/reactos.git
synced 2025-05-25 04:03:56 +00:00
[USBHUB]
- Don't wait for the work item to complete in the SCE completion handler - Use an event to signal the completion of a reset and wait for that event during IRP_MN_START_DEVICE handling so devices are enumerated synchronously which allows USB boot devices to be enumerated svn path=/branches/usb-bringup-trunk/; revision=55493
This commit is contained in:
parent
0913187636
commit
4b30c8402f
3 changed files with 57 additions and 17 deletions
|
@ -1,4 +1,4 @@
|
|||
/*
|
||||
/*
|
||||
* PROJECT: ReactOS Universal Serial Bus Hub Driver
|
||||
* LICENSE: GPL - See COPYING in the top level directory
|
||||
* FILE: drivers/usb/usbhub/fdo.c
|
||||
|
@ -260,6 +260,7 @@ DeviceStatusChangeThread(
|
|||
PWORK_ITEM_DATA WorkItemData;
|
||||
PORT_STATUS_CHANGE PortStatus;
|
||||
LONG PortId;
|
||||
BOOLEAN SignalResetComplete = FALSE;
|
||||
|
||||
DPRINT1("Entered DeviceStatusChangeThread, Context %x\n", Context);
|
||||
|
||||
|
@ -404,16 +405,32 @@ DeviceStatusChangeThread(
|
|||
// This is a new device
|
||||
//
|
||||
Status = CreateUsbChildDeviceObject(DeviceObject, PortId, NULL, PortStatus.Status);
|
||||
|
||||
//
|
||||
// Request event signalling later
|
||||
//
|
||||
SignalResetComplete = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
KeSetEvent(&WorkItemData->Event, IO_NO_INCREMENT, FALSE);
|
||||
ExFreePool(WorkItemData);
|
||||
|
||||
//
|
||||
// Send another SCE Request
|
||||
//
|
||||
DPRINT1("Sending another SCE!\n");
|
||||
QueryStatusChangeEndpoint(DeviceObject);
|
||||
|
||||
//
|
||||
// Check if a reset event was satisfied
|
||||
//
|
||||
if (SignalResetComplete)
|
||||
{
|
||||
//
|
||||
// Signal anyone waiting on it
|
||||
//
|
||||
KeSetEvent(&HubDeviceExtension->ResetComplete, IO_NO_INCREMENT, FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
|
@ -446,25 +463,15 @@ StatusChangeEndpointCompletion(
|
|||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
WorkItemData->Context = RealDeviceObject;
|
||||
KeInitializeEvent(&WorkItemData->Event, NotificationEvent, FALSE);
|
||||
DPRINT1("Initialize work item\n");
|
||||
ExInitializeWorkItem(&WorkItemData->WorkItem, DeviceStatusChangeThread, (PVOID)WorkItemData);
|
||||
|
||||
DPRINT1("Queuing work item\n");
|
||||
|
||||
//
|
||||
// Queue the work item to handle initializing the device
|
||||
//
|
||||
ExInitializeWorkItem(&WorkItemData->WorkItem, DeviceStatusChangeThread, (PVOID)WorkItemData);
|
||||
ExQueueWorkItem(&WorkItemData->WorkItem, DelayedWorkQueue);
|
||||
|
||||
//
|
||||
// Wait for the work item
|
||||
//
|
||||
KeWaitForSingleObject(&WorkItemData->Event,
|
||||
Executive,
|
||||
KernelMode,
|
||||
FALSE,
|
||||
NULL);
|
||||
ExFreePool(WorkItemData);
|
||||
|
||||
//
|
||||
// Return more processing required so the IO Manger doesn’t try to mess with IRP just freed
|
||||
//
|
||||
|
@ -1467,7 +1474,21 @@ RootHubInitCallbackFunction(
|
|||
//
|
||||
Status = SetPortFeature(HubDeviceExtension->RootHubPhysicalDeviceObject, PortId, PORT_RESET);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("Failed to reset on port %d\n", PortId);
|
||||
}
|
||||
else
|
||||
{
|
||||
//
|
||||
// wait for the reset to be handled since we want to enumerate synchronously
|
||||
//
|
||||
KeWaitForSingleObject(&HubDeviceExtension->ResetComplete,
|
||||
Executive,
|
||||
KernelMode,
|
||||
FALSE,
|
||||
NULL);
|
||||
KeClearEvent(&HubDeviceExtension->ResetComplete);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1807,7 +1828,7 @@ USBHUB_FdoHandlePnp(
|
|||
DPRINT1("RootHubInitNotification %x\n", HubDeviceExtension->HubInterface.RootHubInitNotification);
|
||||
|
||||
//
|
||||
// init roo hub notification
|
||||
// init root hub notification
|
||||
//
|
||||
if (HubDeviceExtension->HubInterface.RootHubInitNotification)
|
||||
{
|
||||
|
@ -1847,7 +1868,21 @@ USBHUB_FdoHandlePnp(
|
|||
//
|
||||
Status = SetPortFeature(HubDeviceExtension->RootHubPhysicalDeviceObject, PortId, PORT_RESET);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("Failed to reset on port %d\n", PortId);
|
||||
}
|
||||
else
|
||||
{
|
||||
//
|
||||
// wait for the reset to be handled since we want to enumerate synchronously
|
||||
//
|
||||
KeWaitForSingleObject(&HubDeviceExtension->ResetComplete,
|
||||
Executive,
|
||||
KernelMode,
|
||||
FALSE,
|
||||
NULL);
|
||||
KeClearEvent(&HubDeviceExtension->ResetComplete);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -89,6 +89,11 @@ USBHUB_AddDevice(
|
|||
HubDeviceExtension->Common.IsFDO = TRUE;
|
||||
DeviceObject->Flags |= DO_POWER_PAGABLE;
|
||||
|
||||
//
|
||||
// initialize reset complete event
|
||||
//
|
||||
KeInitializeEvent(&HubDeviceExtension->ResetComplete, NotificationEvent, FALSE);
|
||||
|
||||
//
|
||||
// Attached to lower device
|
||||
//
|
||||
|
|
|
@ -44,7 +44,6 @@ typedef struct _PORT_STATUS_CHANGE
|
|||
typedef struct _WORK_ITEM_DATA
|
||||
{
|
||||
WORK_QUEUE_ITEM WorkItem;
|
||||
KEVENT Event;
|
||||
PVOID Context;
|
||||
} WORK_ITEM_DATA, *PWORK_ITEM_DATA;
|
||||
|
||||
|
@ -80,6 +79,7 @@ typedef struct _HUB_DEVICE_EXTENSION
|
|||
PDEVICE_OBJECT RootHubFunctionalDeviceObject;
|
||||
|
||||
ULONG NumberOfHubs;
|
||||
KEVENT ResetComplete;
|
||||
|
||||
PORT_STATUS_CHANGE *PortStatusChange;
|
||||
URB PendingSCEUrb;
|
||||
|
|
Loading…
Reference in a new issue