Index: drivers/usb/usbhub/fdo.c =================================================================== --- drivers/usb/usbhub/fdo.c (revision 69880) +++ drivers/usb/usbhub/fdo.c (working copy) @@ -12,7 +12,7 @@ #include -#define NDEBUG +//#define NDEBUG #include NTSTATUS @@ -1523,7 +1523,9 @@ PDEVICE_OBJECT RootHubDeviceObject; PVOID HubInterfaceBusContext; PORT_STATUS_CHANGE StatusChange; + BOOLEAN DeviceHighSpeed; + // get hub device extension HubDeviceExtension = (PHUB_DEVICE_EXTENSION) DeviceObject->DeviceExtension; @@ -1858,6 +1860,8 @@ // is it high speed bus if (HubDeviceExtension->UsbDInterface.IsDeviceHighSpeed(HubInterfaceBusContext)) { + DeviceHighSpeed = TRUE; + // initialize usb 2.0 hub Status = HubDeviceExtension->HubInterface.Initialize20Hub(HubInterfaceBusContext, HubDeviceExtension->RootHubHandle, 1); @@ -1866,9 +1870,12 @@ // FIXME handle error ASSERT(Status == STATUS_SUCCESS); } + else + { + DeviceHighSpeed = FALSE; + } } - // Enable power on all ports DPRINT("Enabling PortPower on all ports!\n"); for (PortId = 1; PortId <= HubDeviceExtension->HubDescriptor.bNumberOfPorts; PortId++) @@ -1882,6 +1889,7 @@ DPRINT1("Failed to power on port %d\n", PortId); } + // init root hub notification if (HubDeviceExtension->HubInterface.RootHubInitNotification) { @@ -1888,6 +1896,7 @@ Status = HubDeviceExtension->HubInterface.RootHubInitNotification(HubInterfaceBusContext, DeviceObject, RootHubInitCallbackFunction); + if (!NT_SUCCESS(Status)) { DPRINT1("Failed to set callback\n"); @@ -1894,13 +1903,81 @@ ExFreePool(Urb); return Status; } + + //for usb 2.0 +1 reset ports (for boot from Usb), =experimental= + if (DeviceHighSpeed) + { + DPRINT("USBHUB_FdoStartDevice: reset ports\n"); + for (PortId = 1; PortId <= HubDeviceExtension->HubDescriptor.bNumberOfPorts; PortId++) + { + // + // get port status + // + Status = GetPortStatusAndChange(HubDeviceExtension->RootHubPhysicalDeviceObject, PortId, &StatusChange); + DPRINT("USBHUB_FdoStartDevice: GetPortStatusAndChange return Status - %x\n", Status); + + if (NT_SUCCESS(Status)) + { + // + // is there a device connected + // + if (StatusChange.Status & USB_PORT_STATUS_CONNECT) + { + // + // reset port + // + 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); + } + } + } + } + } + } else { - // Send the first SCE Request - QueryStatusChangeEndpoint(DeviceObject); + RootHubInitCallbackFunction(DeviceObject); + } + // + // delay 100 ms and reset ports (for boot from Usb), =experimental= + // + { + LARGE_INTEGER Timeout; + // + // delay is 100 ms + // + Timeout.QuadPart = 100; + DPRINT1("Waiting %lu milliseconds for port to recover after reset\n", Timeout.LowPart); + + // + // convert to 100 ns units (absolute) + // + Timeout.QuadPart *= -10000; + + // + // perform the wait + // + KeDelayExecutionThread(KernelMode, FALSE, &Timeout); + + // // reset ports // for (PortId = 1; PortId <= HubDeviceExtension->HubDescriptor.bNumberOfPorts; PortId++) @@ -1939,6 +2016,7 @@ } } } + } // free urb