UINTN Index;\r
EFI_STATUS Status;\r
\r
+ Status = UsbHubGetPortStatus (HubIf, Port, &PortState);\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ } else if (USB_BIT_IS_SET (PortState.PortChangeStatus, USB_PORT_STAT_C_RESET)) {\r
+ DEBUG (( EFI_D_INFO, "UsbHubResetPort: skip reset on hub %p port %d\n", HubIf, Port));\r
+ return EFI_SUCCESS;\r
+ }\r
+\r
Status = UsbHubSetPortFeature (HubIf, Port, (EFI_USB_PORT_FEATURE) USB_HUB_PORT_RESET);\r
\r
if (EFI_ERROR (Status)) {\r
}\r
\r
//\r
- // Drive the reset signal for at least 10ms. Check USB 2.0 Spec\r
+ // Drive the reset signal for worst 20ms. Check USB 2.0 Spec\r
// section 7.1.7.5 for timing requirements.\r
//\r
gBS->Stall (USB_SET_PORT_RESET_STALL);\r
\r
//\r
- // USB hub will clear RESET bit if reset is actually finished.\r
+ // Check USB_PORT_STAT_C_RESET bit to see if the resetting state is done.\r
//\r
ZeroMem (&PortState, sizeof (EFI_USB_PORT_STATUS));\r
\r
for (Index = 0; Index < USB_WAIT_PORT_STS_CHANGE_LOOP; Index++) {\r
Status = UsbHubGetPortStatus (HubIf, Port, &PortState);\r
\r
- if (!EFI_ERROR (Status) &&\r
- !USB_BIT_IS_SET (PortState.PortStatus, USB_PORT_STAT_RESET)) {\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
\r
+ if (!EFI_ERROR (Status) &&\r
+ USB_BIT_IS_SET (PortState.PortChangeStatus, USB_PORT_STAT_C_RESET)) {\r
+ gBS->Stall (USB_SET_PORT_RECOVERY_STALL);\r
return EFI_SUCCESS;\r
}\r
\r
// should be handled in the EHCI driver.\r
//\r
Bus = RootIf->Device->Bus;\r
+\r
+ Status = UsbHcGetRootHubPortStatus (Bus, Port, &PortState);\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ } else if (USB_BIT_IS_SET (PortState.PortChangeStatus, USB_PORT_STAT_C_RESET)) {\r
+ DEBUG (( EFI_D_INFO, "UsbRootHubResetPort: skip reset on root port %d\n", Port));\r
+ return EFI_SUCCESS;\r
+ }\r
+\r
Status = UsbHcSetRootHubPortFeature (Bus, Port, EfiUsbPortReset);\r
\r
if (EFI_ERROR (Status)) {\r