EFI_STATUS Status;\r
UINT8 Speed;\r
UINT8 SlotId;\r
+ UINT8 Retries;\r
USB_DEV_ROUTE RouteChart;\r
\r
Status = EFI_SUCCESS;\r
+ Retries = XHC_INIT_DEVICE_SLOT_RETRIES;\r
\r
if ((PortState->PortChangeStatus & (USB_PORT_STAT_C_CONNECTION | USB_PORT_STAT_C_ENABLE | USB_PORT_STAT_C_OVERCURRENT | USB_PORT_STAT_C_RESET)) == 0) {\r
return EFI_SUCCESS;\r
} else if ((PortState->PortStatus & USB_PORT_STAT_SUPER_SPEED) != 0) {\r
Speed = EFI_USB_SPEED_SUPER;\r
}\r
- //\r
- // Execute Enable_Slot cmd for attached device, initialize device context and assign device address.\r
- //\r
- SlotId = XhcRouteStringToSlotId (Xhc, RouteChart);\r
- if ((SlotId == 0) && ((PortState->PortChangeStatus & USB_PORT_STAT_C_RESET) != 0)) {\r
- if (Xhc->HcCParams.Data.Csz == 0) {\r
- Status = XhcInitializeDeviceSlot (Xhc, ParentRouteChart, Port, RouteChart, Speed);\r
- } else {\r
- Status = XhcInitializeDeviceSlot64 (Xhc, ParentRouteChart, Port, RouteChart, Speed);\r
+\r
+ do {\r
+ //\r
+ // Execute Enable_Slot cmd for attached device, initialize device context and assign device address.\r
+ //\r
+ SlotId = XhcRouteStringToSlotId (Xhc, RouteChart);\r
+ if ((SlotId == 0) && ((PortState->PortChangeStatus & USB_PORT_STAT_C_RESET) != 0)) {\r
+ if (Xhc->HcCParams.Data.Csz == 0) {\r
+ Status = XhcInitializeDeviceSlot (Xhc, ParentRouteChart, Port, RouteChart, Speed);\r
+ } else {\r
+ Status = XhcInitializeDeviceSlot64 (Xhc, ParentRouteChart, Port, RouteChart, Speed);\r
+ }\r
}\r
- }\r
+\r
+ //\r
+ // According to the xHCI specification (section 4.6.5), "a USB Transaction\r
+ // Error Completion Code for an Address Device Command may be due to a Stall\r
+ // response from a device. Software should issue a Disable Slot Command for\r
+ // the Device Slot then an Enable Slot Command to recover from this error."\r
+ // Therefore, retry the device slot initialization if it fails due to a\r
+ // device error.\r
+ //\r
+ } while ((Status == EFI_DEVICE_ERROR) && (Retries-- != 0));\r
}\r
\r
return Status;\r