]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Bus/Pci/XhciDxe/XhciSched.c
MdeModulePkg/XhciDxe: Retry device slot init on failure
[mirror_edk2.git] / MdeModulePkg / Bus / Pci / XhciDxe / XhciSched.c
index 00e9cc63d63e4abdda00e65059afd1b324e03d29..dc36945962a0d02bebc46b6ab0066c0b37e4720d 100644 (file)
@@ -1717,9 +1717,11 @@ XhcPollPortStatusChange (
   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
@@ -1761,17 +1763,29 @@ XhcPollPortStatusChange (
     } 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