1.enlarge the recovery time from 10ms to 20ms after port reset to make set address request success for better device compatibility.
2.another enhancement is to use RESET_C bit rather than RESET bit to judge if hub reset port operation is done.
Signed-off-by: Feng Tian <feng.tian@intel.com>
Reviewed-by: Elvin Li <elvin.li@intel.com>
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@14227
6f19259b-4bc3-4df7-8a09-
765794883524
USB_DEVICE *Dev;\r
EFI_TPL OldTpl;\r
EFI_STATUS Status;\r
+ UINT8 DevAddress;\r
\r
OldTpl = gBS->RaiseTPL (USB_BUS_TPL);\r
\r
goto ON_EXIT;\r
}\r
\r
+ HubIf->HubApi->ClearPortChange (HubIf, Dev->ParentPort);\r
+\r
//\r
// Reset the device to its current address. The device now has an address\r
// of ZERO after port reset, so need to set Dev->Address to the device again for\r
// host to communicate with it.\r
//\r
- Status = UsbSetAddress (Dev, Dev->Address);\r
+ DevAddress = Dev->Address;\r
+ Dev->Address = 0;\r
+ Status = UsbSetAddress (Dev, DevAddress);\r
+ Dev->Address = DevAddress;\r
\r
gBS->Stall (USB_SET_DEVICE_ADDRESS_STALL);\r
\r
// [USB20-7.1.7.5, it says 10ms for hub and 50ms for\r
// root hub]\r
//\r
-#define USB_SET_PORT_RESET_STALL (10 * USB_BUS_1_MILLISECOND)\r
+// According to USB2.0, Chapter 11.5.1.5 Resetting,\r
+// the worst case for TDRST is 20ms\r
+//\r
+#define USB_SET_PORT_RESET_STALL (20 * USB_BUS_1_MILLISECOND)\r
#define USB_SET_ROOT_PORT_RESET_STALL (50 * USB_BUS_1_MILLISECOND)\r
\r
+//\r
+// Wait for port recovery to accept SetAddress, refers to specification\r
+// [USB20-7.1.7.5, it says 10 ms for TRSTRCY]\r
+//\r
+#define USB_SET_PORT_RECOVERY_STALL (10 * USB_BUS_1_MILLISECOND)\r
+\r
//\r
// Wait for clear roothub port reset, set by experience\r
//\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
Status = UsbHubGetPortStatus (HubIf, Port, &PortState);\r
\r
if (!EFI_ERROR (Status) &&\r
- !USB_BIT_IS_SET (PortState.PortStatus, USB_PORT_STAT_RESET)) {\r
-\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