]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Bus/Pci/XhciDxe/XhciReg.c
MdeModulePkg: Apply uncrustify changes
[mirror_edk2.git] / MdeModulePkg / Bus / Pci / XhciDxe / XhciReg.c
index 9d50ef824261acc357812e33a911eec017bea09b..80be3311d49c1758117e6f32155e7d5bec1b4a44 100644 (file)
@@ -2,14 +2,8 @@
 \r
   The XHCI register operation routines.\r
 \r
-Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>\r
-This program and the accompanying materials\r
-are licensed and made available under the terms and conditions of the BSD License\r
-which accompanies this distribution.  The full text of the license may be found at\r
-http://opensource.org/licenses/bsd-license.php\r
-\r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+Copyright (c) 2011 - 2017, Intel Corporation. All rights reserved.<BR>\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
 \r
 **/\r
 \r
@@ -27,24 +21,24 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 **/\r
 UINT8\r
 XhcReadCapReg8 (\r
-  IN  USB_XHCI_INSTANCE   *Xhc,\r
-  IN  UINT32              Offset\r
+  IN  USB_XHCI_INSTANCE  *Xhc,\r
+  IN  UINT32             Offset\r
   )\r
 {\r
-  UINT8                   Data;\r
-  EFI_STATUS              Status;\r
+  UINT8       Data;\r
+  EFI_STATUS  Status;\r
 \r
   Status = Xhc->PciIo->Mem.Read (\r
                              Xhc->PciIo,\r
                              EfiPciIoWidthUint8,\r
                              XHC_BAR_INDEX,\r
-                             (UINT64) Offset,\r
+                             (UINT64)Offset,\r
                              1,\r
                              &Data\r
                              );\r
 \r
   if (EFI_ERROR (Status)) {\r
-    DEBUG ((EFI_D_ERROR, "XhcReadCapReg: Pci Io read error - %r at %d\n", Status, Offset));\r
+    DEBUG ((DEBUG_ERROR, "XhcReadCapReg: Pci Io read error - %r at %d\n", Status, Offset));\r
     Data = 0xFF;\r
   }\r
 \r
@@ -63,24 +57,24 @@ XhcReadCapReg8 (
 **/\r
 UINT32\r
 XhcReadCapReg (\r
-  IN  USB_XHCI_INSTANCE   *Xhc,\r
-  IN  UINT32              Offset\r
+  IN  USB_XHCI_INSTANCE  *Xhc,\r
+  IN  UINT32             Offset\r
   )\r
 {\r
-  UINT32                  Data;\r
-  EFI_STATUS              Status;\r
+  UINT32      Data;\r
+  EFI_STATUS  Status;\r
 \r
   Status = Xhc->PciIo->Mem.Read (\r
                              Xhc->PciIo,\r
                              EfiPciIoWidthUint32,\r
                              XHC_BAR_INDEX,\r
-                             (UINT64) Offset,\r
+                             (UINT64)Offset,\r
                              1,\r
                              &Data\r
                              );\r
 \r
   if (EFI_ERROR (Status)) {\r
-    DEBUG ((EFI_D_ERROR, "XhcReadCapReg: Pci Io read error - %r at %d\n", Status, Offset));\r
+    DEBUG ((DEBUG_ERROR, "XhcReadCapReg: Pci Io read error - %r at %d\n", Status, Offset));\r
     Data = 0xFFFFFFFF;\r
   }\r
 \r
@@ -99,12 +93,12 @@ XhcReadCapReg (
 **/\r
 UINT32\r
 XhcReadOpReg (\r
-  IN  USB_XHCI_INSTANCE   *Xhc,\r
-  IN  UINT32              Offset\r
+  IN  USB_XHCI_INSTANCE  *Xhc,\r
+  IN  UINT32             Offset\r
   )\r
 {\r
-  UINT32                  Data;\r
-  EFI_STATUS              Status;\r
+  UINT32      Data;\r
+  EFI_STATUS  Status;\r
 \r
   ASSERT (Xhc->CapLength != 0);\r
 \r
@@ -112,13 +106,13 @@ XhcReadOpReg (
                              Xhc->PciIo,\r
                              EfiPciIoWidthUint32,\r
                              XHC_BAR_INDEX,\r
-                             (UINT64) (Xhc->CapLength + Offset),\r
+                             Xhc->CapLength + Offset,\r
                              1,\r
                              &Data\r
                              );\r
 \r
   if (EFI_ERROR (Status)) {\r
-    DEBUG ((EFI_D_ERROR, "XhcReadOpReg: Pci Io Read error - %r at %d\n", Status, Offset));\r
+    DEBUG ((DEBUG_ERROR, "XhcReadOpReg: Pci Io Read error - %r at %d\n", Status, Offset));\r
     Data = 0xFFFFFFFF;\r
   }\r
 \r
@@ -135,12 +129,12 @@ XhcReadOpReg (
 **/\r
 VOID\r
 XhcWriteOpReg (\r
-  IN USB_XHCI_INSTANCE    *Xhc,\r
-  IN UINT32               Offset,\r
-  IN UINT32               Data\r
+  IN USB_XHCI_INSTANCE  *Xhc,\r
+  IN UINT32             Offset,\r
+  IN UINT32             Data\r
   )\r
 {\r
-  EFI_STATUS              Status;\r
+  EFI_STATUS  Status;\r
 \r
   ASSERT (Xhc->CapLength != 0);\r
 \r
@@ -148,86 +142,16 @@ XhcWriteOpReg (
                              Xhc->PciIo,\r
                              EfiPciIoWidthUint32,\r
                              XHC_BAR_INDEX,\r
-                             (UINT64) (Xhc->CapLength + Offset),\r
+                             Xhc->CapLength + Offset,\r
                              1,\r
                              &Data\r
                              );\r
 \r
   if (EFI_ERROR (Status)) {\r
-    DEBUG ((EFI_D_ERROR, "XhcWriteOpReg: Pci Io Write error: %r at %d\n", Status, Offset));\r
+    DEBUG ((DEBUG_ERROR, "XhcWriteOpReg: Pci Io Write error: %r at %d\n", Status, Offset));\r
   }\r
 }\r
 \r
-/**\r
-  Write the data to the 2-bytes width XHCI operational register.\r
-\r
-  @param  Xhc          The XHCI Instance.\r
-  @param  Offset       The offset of the 2-bytes width operational register.\r
-  @param  Data         The data to write.\r
-\r
-**/\r
-VOID\r
-XhcWriteOpReg16 (\r
-  IN USB_XHCI_INSTANCE    *Xhc,\r
-  IN UINT32               Offset,\r
-  IN UINT16               Data\r
-  )\r
-{\r
-  EFI_STATUS              Status;\r
-\r
-  ASSERT (Xhc->CapLength != 0);\r
-\r
-  Status = Xhc->PciIo->Mem.Write (\r
-                             Xhc->PciIo,\r
-                             EfiPciIoWidthUint16,\r
-                             XHC_BAR_INDEX,\r
-                             (UINT64) (Xhc->CapLength + Offset),\r
-                             1,\r
-                             &Data\r
-                             );\r
-\r
-  if (EFI_ERROR (Status)) {\r
-    DEBUG ((EFI_D_ERROR, "XhcWriteOpReg16: Pci Io Write error: %r at %d\n", Status, Offset));\r
-  }\r
-}\r
-\r
-/**\r
-  Read XHCI door bell register.\r
-\r
-  @param  Xhc          The XHCI Instance.\r
-  @param  Offset       The offset of the door bell register.\r
-\r
-  @return The register content read\r
-\r
-**/\r
-UINT32\r
-XhcReadDoorBellReg (\r
-  IN  USB_XHCI_INSTANCE   *Xhc,\r
-  IN  UINT32              Offset\r
-  )\r
-{\r
-  UINT32                  Data;\r
-  EFI_STATUS              Status;\r
-\r
-  ASSERT (Xhc->DBOff != 0);\r
-\r
-  Status = Xhc->PciIo->Mem.Read (\r
-                             Xhc->PciIo,\r
-                             EfiPciIoWidthUint32,\r
-                             XHC_BAR_INDEX,\r
-                             (UINT64) (Xhc->DBOff + Offset),\r
-                             1,\r
-                             &Data\r
-                             );\r
-\r
-  if (EFI_ERROR (Status)) {\r
-    DEBUG ((EFI_D_ERROR, "XhcReadDoorBellReg: Pci Io Read error - %r at %d\n", Status, Offset));\r
-    Data = 0xFFFFFFFF;\r
-  }\r
-\r
-  return Data;\r
-}\r
-\r
 /**\r
   Write the data to the XHCI door bell register.\r
 \r
@@ -238,12 +162,12 @@ XhcReadDoorBellReg (
 **/\r
 VOID\r
 XhcWriteDoorBellReg (\r
-  IN USB_XHCI_INSTANCE    *Xhc,\r
-  IN UINT32               Offset,\r
-  IN UINT32               Data\r
+  IN USB_XHCI_INSTANCE  *Xhc,\r
+  IN UINT32             Offset,\r
+  IN UINT32             Data\r
   )\r
 {\r
-  EFI_STATUS              Status;\r
+  EFI_STATUS  Status;\r
 \r
   ASSERT (Xhc->DBOff != 0);\r
 \r
@@ -251,13 +175,13 @@ XhcWriteDoorBellReg (
                              Xhc->PciIo,\r
                              EfiPciIoWidthUint32,\r
                              XHC_BAR_INDEX,\r
-                             (UINT64) (Xhc->DBOff + Offset),\r
+                             Xhc->DBOff + Offset,\r
                              1,\r
                              &Data\r
                              );\r
 \r
   if (EFI_ERROR (Status)) {\r
-    DEBUG ((EFI_D_ERROR, "XhcWriteOpReg: Pci Io Write error: %r at %d\n", Status, Offset));\r
+    DEBUG ((DEBUG_ERROR, "XhcWriteOpReg: Pci Io Write error: %r at %d\n", Status, Offset));\r
   }\r
 }\r
 \r
@@ -272,12 +196,12 @@ XhcWriteDoorBellReg (
 **/\r
 UINT32\r
 XhcReadRuntimeReg (\r
-  IN  USB_XHCI_INSTANCE   *Xhc,\r
-  IN  UINT32              Offset\r
+  IN  USB_XHCI_INSTANCE  *Xhc,\r
+  IN  UINT32             Offset\r
   )\r
 {\r
-  UINT32                  Data;\r
-  EFI_STATUS              Status;\r
+  UINT32      Data;\r
+  EFI_STATUS  Status;\r
 \r
   ASSERT (Xhc->RTSOff != 0);\r
 \r
@@ -285,13 +209,13 @@ XhcReadRuntimeReg (
                              Xhc->PciIo,\r
                              EfiPciIoWidthUint32,\r
                              XHC_BAR_INDEX,\r
-                             (UINT64) (Xhc->RTSOff + Offset),\r
+                             Xhc->RTSOff + Offset,\r
                              1,\r
                              &Data\r
                              );\r
 \r
   if (EFI_ERROR (Status)) {\r
-    DEBUG ((EFI_D_ERROR, "XhcReadRuntimeReg: Pci Io Read error - %r at %d\n", Status, Offset));\r
+    DEBUG ((DEBUG_ERROR, "XhcReadRuntimeReg: Pci Io Read error - %r at %d\n", Status, Offset));\r
     Data = 0xFFFFFFFF;\r
   }\r
 \r
@@ -308,12 +232,12 @@ XhcReadRuntimeReg (
 **/\r
 VOID\r
 XhcWriteRuntimeReg (\r
-  IN USB_XHCI_INSTANCE    *Xhc,\r
-  IN UINT32               Offset,\r
-  IN UINT32               Data\r
+  IN USB_XHCI_INSTANCE  *Xhc,\r
+  IN UINT32             Offset,\r
+  IN UINT32             Data\r
   )\r
 {\r
-  EFI_STATUS              Status;\r
+  EFI_STATUS  Status;\r
 \r
   ASSERT (Xhc->RTSOff != 0);\r
 \r
@@ -321,13 +245,13 @@ XhcWriteRuntimeReg (
                              Xhc->PciIo,\r
                              EfiPciIoWidthUint32,\r
                              XHC_BAR_INDEX,\r
-                             (UINT64) (Xhc->RTSOff + Offset),\r
+                             Xhc->RTSOff + Offset,\r
                              1,\r
                              &Data\r
                              );\r
 \r
   if (EFI_ERROR (Status)) {\r
-    DEBUG ((EFI_D_ERROR, "XhcWriteRuntimeReg: Pci Io Write error: %r at %d\n", Status, Offset));\r
+    DEBUG ((DEBUG_ERROR, "XhcWriteRuntimeReg: Pci Io Write error: %r at %d\n", Status, Offset));\r
   }\r
 }\r
 \r
@@ -342,12 +266,12 @@ XhcWriteRuntimeReg (
 **/\r
 UINT32\r
 XhcReadExtCapReg (\r
-  IN  USB_XHCI_INSTANCE   *Xhc,\r
-  IN  UINT32              Offset\r
+  IN  USB_XHCI_INSTANCE  *Xhc,\r
+  IN  UINT32             Offset\r
   )\r
 {\r
-  UINT32                  Data;\r
-  EFI_STATUS              Status;\r
+  UINT32      Data;\r
+  EFI_STATUS  Status;\r
 \r
   ASSERT (Xhc->ExtCapRegBase != 0);\r
 \r
@@ -355,13 +279,13 @@ XhcReadExtCapReg (
                              Xhc->PciIo,\r
                              EfiPciIoWidthUint32,\r
                              XHC_BAR_INDEX,\r
-                             (UINT64) (Xhc->ExtCapRegBase + Offset),\r
+                             Xhc->ExtCapRegBase + Offset,\r
                              1,\r
                              &Data\r
                              );\r
 \r
   if (EFI_ERROR (Status)) {\r
-    DEBUG ((EFI_D_ERROR, "XhcReadExtCapReg: Pci Io Read error - %r at %d\n", Status, Offset));\r
+    DEBUG ((DEBUG_ERROR, "XhcReadExtCapReg: Pci Io Read error - %r at %d\n", Status, Offset));\r
     Data = 0xFFFFFFFF;\r
   }\r
 \r
@@ -378,12 +302,12 @@ XhcReadExtCapReg (
 **/\r
 VOID\r
 XhcWriteExtCapReg (\r
-  IN USB_XHCI_INSTANCE    *Xhc,\r
-  IN UINT32               Offset,\r
-  IN UINT32               Data\r
+  IN USB_XHCI_INSTANCE  *Xhc,\r
+  IN UINT32             Offset,\r
+  IN UINT32             Data\r
   )\r
 {\r
-  EFI_STATUS              Status;\r
+  EFI_STATUS  Status;\r
 \r
   ASSERT (Xhc->ExtCapRegBase != 0);\r
 \r
@@ -391,17 +315,16 @@ XhcWriteExtCapReg (
                              Xhc->PciIo,\r
                              EfiPciIoWidthUint32,\r
                              XHC_BAR_INDEX,\r
-                             (UINT64) (Xhc->ExtCapRegBase + Offset),\r
+                             Xhc->ExtCapRegBase + Offset,\r
                              1,\r
                              &Data\r
                              );\r
 \r
   if (EFI_ERROR (Status)) {\r
-    DEBUG ((EFI_D_ERROR, "XhcWriteExtCapReg: Pci Io Write error: %r at %d\n", Status, Offset));\r
+    DEBUG ((DEBUG_ERROR, "XhcWriteExtCapReg: Pci Io Write error: %r at %d\n", Status, Offset));\r
   }\r
 }\r
 \r
-\r
 /**\r
   Set one bit of the runtime register while keeping other bits.\r
 \r
@@ -412,12 +335,12 @@ XhcWriteExtCapReg (
 **/\r
 VOID\r
 XhcSetRuntimeRegBit (\r
-  IN USB_XHCI_INSTANCE    *Xhc,\r
-  IN UINT32               Offset,\r
-  IN UINT32               Bit\r
+  IN USB_XHCI_INSTANCE  *Xhc,\r
+  IN UINT32             Offset,\r
+  IN UINT32             Bit\r
   )\r
 {\r
-  UINT32                  Data;\r
+  UINT32  Data;\r
 \r
   Data  = XhcReadRuntimeReg (Xhc, Offset);\r
   Data |= Bit;\r
@@ -434,12 +357,12 @@ XhcSetRuntimeRegBit (
 **/\r
 VOID\r
 XhcClearRuntimeRegBit (\r
-  IN USB_XHCI_INSTANCE    *Xhc,\r
-  IN UINT32               Offset,\r
-  IN UINT32               Bit\r
+  IN USB_XHCI_INSTANCE  *Xhc,\r
+  IN UINT32             Offset,\r
+  IN UINT32             Bit\r
   )\r
 {\r
-  UINT32                  Data;\r
+  UINT32  Data;\r
 \r
   Data  = XhcReadRuntimeReg (Xhc, Offset);\r
   Data &= ~Bit;\r
@@ -456,19 +379,18 @@ XhcClearRuntimeRegBit (
 **/\r
 VOID\r
 XhcSetOpRegBit (\r
-  IN USB_XHCI_INSTANCE    *Xhc,\r
-  IN UINT32               Offset,\r
-  IN UINT32               Bit\r
+  IN USB_XHCI_INSTANCE  *Xhc,\r
+  IN UINT32             Offset,\r
+  IN UINT32             Bit\r
   )\r
 {\r
-  UINT32                  Data;\r
+  UINT32  Data;\r
 \r
   Data  = XhcReadOpReg (Xhc, Offset);\r
   Data |= Bit;\r
   XhcWriteOpReg (Xhc, Offset, Data);\r
 }\r
 \r
-\r
 /**\r
   Clear one bit of the operational register while keeping other bits.\r
 \r
@@ -479,12 +401,12 @@ XhcSetOpRegBit (
 **/\r
 VOID\r
 XhcClearOpRegBit (\r
-  IN USB_XHCI_INSTANCE    *Xhc,\r
-  IN UINT32               Offset,\r
-  IN UINT32               Bit\r
+  IN USB_XHCI_INSTANCE  *Xhc,\r
+  IN UINT32             Offset,\r
+  IN UINT32             Bit\r
   )\r
 {\r
-  UINT32                  Data;\r
+  UINT32  Data;\r
 \r
   Data  = XhcReadOpReg (Xhc, Offset);\r
   Data &= ~Bit;\r
@@ -495,39 +417,74 @@ XhcClearOpRegBit (
   Wait the operation register's bit as specified by Bit\r
   to become set (or clear).\r
 \r
-  @param  Xhc          The XHCI Instance.\r
-  @param  Offset       The offset of the operation register.\r
-  @param  Bit          The bit of the register to wait for.\r
-  @param  WaitToSet    Wait the bit to set or clear.\r
-  @param  Timeout      The time to wait before abort (in millisecond, ms).\r
+  @param  Xhc                    The XHCI Instance.\r
+  @param  Offset                 The offset of the operation register.\r
+  @param  Bit                    The bit of the register to wait for.\r
+  @param  WaitToSet              Wait the bit to set or clear.\r
+  @param  Timeout                The time to wait before abort (in millisecond, ms).\r
 \r
-  @retval EFI_SUCCESS  The bit successfully changed by host controller.\r
-  @retval EFI_TIMEOUT  The time out occurred.\r
+  @retval EFI_SUCCESS            The bit successfully changed by host controller.\r
+  @retval EFI_TIMEOUT            The time out occurred.\r
+  @retval EFI_OUT_OF_RESOURCES   Memory for the timer event could not be allocated.\r
 \r
 **/\r
 EFI_STATUS\r
 XhcWaitOpRegBit (\r
-  IN USB_XHCI_INSTANCE    *Xhc,\r
-  IN UINT32               Offset,\r
-  IN UINT32               Bit,\r
-  IN BOOLEAN              WaitToSet,\r
-  IN UINT32               Timeout\r
+  IN USB_XHCI_INSTANCE  *Xhc,\r
+  IN UINT32             Offset,\r
+  IN UINT32             Bit,\r
+  IN BOOLEAN            WaitToSet,\r
+  IN UINT32             Timeout\r
   )\r
 {\r
-  UINT32                  Index;\r
-  UINTN                   Loop;\r
+  EFI_STATUS  Status;\r
+  EFI_EVENT   TimeoutEvent;\r
+\r
+  TimeoutEvent = NULL;\r
+\r
+  if (Timeout == 0) {\r
+    return EFI_TIMEOUT;\r
+  }\r
+\r
+  Status = gBS->CreateEvent (\r
+                  EVT_TIMER,\r
+                  TPL_CALLBACK,\r
+                  NULL,\r
+                  NULL,\r
+                  &TimeoutEvent\r
+                  );\r
+\r
+  if (EFI_ERROR (Status)) {\r
+    goto DONE;\r
+  }\r
+\r
+  Status = gBS->SetTimer (\r
+                  TimeoutEvent,\r
+                  TimerRelative,\r
+                  EFI_TIMER_PERIOD_MILLISECONDS (Timeout)\r
+                  );\r
 \r
-  Loop   = (Timeout * XHC_1_MILLISECOND / XHC_POLL_DELAY) + 1;\r
+  if (EFI_ERROR (Status)) {\r
+    goto DONE;\r
+  }\r
 \r
-  for (Index = 0; Index < Loop; Index++) {\r
+  do {\r
     if (XHC_REG_BIT_IS_SET (Xhc, Offset, Bit) == WaitToSet) {\r
-      return EFI_SUCCESS;\r
+      Status = EFI_SUCCESS;\r
+      goto DONE;\r
     }\r
 \r
-    gBS->Stall (XHC_POLL_DELAY);\r
+    gBS->Stall (XHC_1_MICROSECOND);\r
+  } while (EFI_ERROR (gBS->CheckEvent (TimeoutEvent)));\r
+\r
+  Status = EFI_TIMEOUT;\r
+\r
+DONE:\r
+  if (TimeoutEvent != NULL) {\r
+    gBS->CloseEvent (TimeoutEvent);\r
   }\r
 \r
-  return EFI_TIMEOUT;\r
+  return Status;\r
 }\r
 \r
 /**\r
@@ -538,12 +495,16 @@ XhcWaitOpRegBit (
 **/\r
 VOID\r
 XhcSetBiosOwnership (\r
-  IN USB_XHCI_INSTANCE    *Xhc\r
+  IN USB_XHCI_INSTANCE  *Xhc\r
   )\r
 {\r
-  UINT32                    Buffer;\r
+  UINT32  Buffer;\r
 \r
-  DEBUG ((EFI_D_INFO, "XhcSetBiosOwnership: called to set BIOS ownership\n"));\r
+  if (Xhc->UsbLegSupOffset == 0xFFFFFFFF) {\r
+    return;\r
+  }\r
+\r
+  DEBUG ((DEBUG_INFO, "XhcSetBiosOwnership: called to set BIOS ownership\n"));\r
 \r
   Buffer = XhcReadExtCapReg (Xhc, Xhc->UsbLegSupOffset);\r
   Buffer = ((Buffer & (~USBLEGSP_OS_SEMAPHORE)) | USBLEGSP_BIOS_SEMAPHORE);\r
@@ -558,12 +519,16 @@ XhcSetBiosOwnership (
 **/\r
 VOID\r
 XhcClearBiosOwnership (\r
-  IN USB_XHCI_INSTANCE    *Xhc\r
+  IN USB_XHCI_INSTANCE  *Xhc\r
   )\r
 {\r
-  UINT32                    Buffer;\r
+  UINT32  Buffer;\r
+\r
+  if (Xhc->UsbLegSupOffset == 0xFFFFFFFF) {\r
+    return;\r
+  }\r
 \r
-  DEBUG ((EFI_D_INFO, "XhcClearBiosOwnership: called to clear BIOS ownership\n"));\r
+  DEBUG ((DEBUG_INFO, "XhcClearBiosOwnership: called to clear BIOS ownership\n"));\r
 \r
   Buffer = XhcReadExtCapReg (Xhc, Xhc->UsbLegSupOffset);\r
   Buffer = ((Buffer & (~USBLEGSP_BIOS_SEMAPHORE)) | USBLEGSP_OS_SEMAPHORE);\r
@@ -571,21 +536,23 @@ XhcClearBiosOwnership (
 }\r
 \r
 /**\r
-  Calculate the XHCI legacy support capability register offset.\r
+  Calculate the offset of the XHCI capability.\r
 \r
   @param  Xhc     The XHCI Instance.\r
+  @param  CapId   The XHCI Capability ID.\r
 \r
   @return The offset of XHCI legacy support capability register.\r
 \r
 **/\r
 UINT32\r
-XhcGetLegSupCapAddr (\r
-  IN USB_XHCI_INSTANCE    *Xhc\r
+XhcGetCapabilityAddr (\r
+  IN USB_XHCI_INSTANCE  *Xhc,\r
+  IN UINT8              CapId\r
   )\r
 {\r
-  UINT32 ExtCapOffset;\r
-  UINT8  NextExtCapReg;\r
-  UINT32 Data;\r
+  UINT32  ExtCapOffset;\r
+  UINT8   NextExtCapReg;\r
+  UINT32  Data;\r
 \r
   ExtCapOffset = 0;\r
 \r
@@ -594,9 +561,10 @@ XhcGetLegSupCapAddr (
     // Check if the extended capability register's capability id is USB Legacy Support.\r
     //\r
     Data = XhcReadExtCapReg (Xhc, ExtCapOffset);\r
-    if ((Data & 0xFF) == 0x1) {\r
+    if ((Data & 0xFF) == CapId) {\r
       return ExtCapOffset;\r
     }\r
+\r
     //\r
     // If not, then traverse all of the ext capability registers till finding out it.\r
     //\r
@@ -604,7 +572,7 @@ XhcGetLegSupCapAddr (
     ExtCapOffset += (NextExtCapReg << 2);\r
   } while (NextExtCapReg != 0);\r
 \r
-  return 0;\r
+  return 0xFFFFFFFF;\r
 }\r
 \r
 /**\r
@@ -618,13 +586,12 @@ XhcGetLegSupCapAddr (
 **/\r
 BOOLEAN\r
 XhcIsHalt (\r
-  IN USB_XHCI_INSTANCE    *Xhc\r
+  IN USB_XHCI_INSTANCE  *Xhc\r
   )\r
 {\r
   return XHC_REG_BIT_IS_SET (Xhc, XHC_USBSTS_OFFSET, XHC_USBSTS_HALT);\r
 }\r
 \r
-\r
 /**\r
   Whether system error occurred.\r
 \r
@@ -636,12 +603,45 @@ XhcIsHalt (
 **/\r
 BOOLEAN\r
 XhcIsSysError (\r
-  IN USB_XHCI_INSTANCE    *Xhc\r
+  IN USB_XHCI_INSTANCE  *Xhc\r
   )\r
 {\r
   return XHC_REG_BIT_IS_SET (Xhc, XHC_USBSTS_OFFSET, XHC_USBSTS_HSE);\r
 }\r
 \r
+/**\r
+  Set USBCMD Host System Error Enable(HSEE) Bit if PCICMD SERR# Enable Bit is set.\r
+\r
+  The USBCMD HSEE Bit will be reset to default 0 by USBCMD Host Controller Reset(HCRST).\r
+  This function is to set USBCMD HSEE Bit if PCICMD SERR# Enable Bit is set.\r
+\r
+  @param Xhc            The XHCI Instance.\r
+\r
+**/\r
+VOID\r
+XhcSetHsee (\r
+  IN USB_XHCI_INSTANCE  *Xhc\r
+  )\r
+{\r
+  EFI_STATUS           Status;\r
+  EFI_PCI_IO_PROTOCOL  *PciIo;\r
+  UINT16               XhciCmd;\r
+\r
+  PciIo  = Xhc->PciIo;\r
+  Status = PciIo->Pci.Read (\r
+                        PciIo,\r
+                        EfiPciIoWidthUint16,\r
+                        PCI_COMMAND_OFFSET,\r
+                        sizeof (XhciCmd) / sizeof (UINT16),\r
+                        &XhciCmd\r
+                        );\r
+  if (!EFI_ERROR (Status)) {\r
+    if ((XhciCmd & EFI_PCI_COMMAND_SERR) != 0) {\r
+      XhcSetOpRegBit (Xhc, XHC_USBCMD_OFFSET, XHC_USBCMD_HSEE);\r
+    }\r
+  }\r
+}\r
+\r
 /**\r
   Reset the XHCI host controller.\r
 \r
@@ -654,13 +654,15 @@ XhcIsSysError (
 **/\r
 EFI_STATUS\r
 XhcResetHC (\r
-  IN USB_XHCI_INSTANCE    *Xhc,\r
-  IN UINT32               Timeout\r
+  IN USB_XHCI_INSTANCE  *Xhc,\r
+  IN UINT32             Timeout\r
   )\r
 {\r
-  EFI_STATUS              Status;\r
+  EFI_STATUS  Status;\r
 \r
-  DEBUG ((EFI_D_INFO, "XhcResetHC!\n"));\r
+  Status = EFI_SUCCESS;\r
+\r
+  DEBUG ((DEBUG_INFO, "XhcResetHC!\n"));\r
   //\r
   // Host can only be reset when it is halt. If not so, halt it\r
   //\r
@@ -672,12 +674,30 @@ XhcResetHC (
     }\r
   }\r
 \r
-  XhcSetOpRegBit (Xhc, XHC_USBCMD_OFFSET, XHC_USBCMD_RESET);\r
-  Status = XhcWaitOpRegBit (Xhc, XHC_USBCMD_OFFSET, XHC_USBCMD_RESET, FALSE, Timeout);\r
+  if ((Xhc->DebugCapSupOffset == 0xFFFFFFFF) || ((XhcReadExtCapReg (Xhc, Xhc->DebugCapSupOffset) & 0xFF) != XHC_CAP_USB_DEBUG) ||\r
+      ((XhcReadExtCapReg (Xhc, Xhc->DebugCapSupOffset + XHC_DC_DCCTRL) & BIT0) == 0))\r
+  {\r
+    XhcSetOpRegBit (Xhc, XHC_USBCMD_OFFSET, XHC_USBCMD_RESET);\r
+    //\r
+    // Some XHCI host controllers require to have extra 1ms delay before accessing any MMIO register during reset.\r
+    // Otherwise there may have the timeout case happened.\r
+    // The below is a workaround to solve such problem.\r
+    //\r
+    gBS->Stall (XHC_1_MILLISECOND);\r
+    Status = XhcWaitOpRegBit (Xhc, XHC_USBCMD_OFFSET, XHC_USBCMD_RESET, FALSE, Timeout);\r
+\r
+    if (!EFI_ERROR (Status)) {\r
+      //\r
+      // The USBCMD HSEE Bit will be reset to default 0 by USBCMD HCRST.\r
+      // Set USBCMD HSEE Bit if PCICMD SERR# Enable Bit is set.\r
+      //\r
+      XhcSetHsee (Xhc);\r
+    }\r
+  }\r
+\r
   return Status;\r
 }\r
 \r
-\r
 /**\r
   Halt the XHCI host controller.\r
 \r
@@ -690,18 +710,17 @@ XhcResetHC (
 **/\r
 EFI_STATUS\r
 XhcHaltHC (\r
-  IN USB_XHCI_INSTANCE   *Xhc,\r
-  IN UINT32              Timeout\r
+  IN USB_XHCI_INSTANCE  *Xhc,\r
+  IN UINT32             Timeout\r
   )\r
 {\r
-  EFI_STATUS              Status;\r
+  EFI_STATUS  Status;\r
 \r
   XhcClearOpRegBit (Xhc, XHC_USBCMD_OFFSET, XHC_USBCMD_RUN);\r
   Status = XhcWaitOpRegBit (Xhc, XHC_USBSTS_OFFSET, XHC_USBSTS_HALT, TRUE, Timeout);\r
   return Status;\r
 }\r
 \r
-\r
 /**\r
   Set the XHCI host controller to run.\r
 \r
@@ -714,14 +733,13 @@ XhcHaltHC (
 **/\r
 EFI_STATUS\r
 XhcRunHC (\r
-  IN USB_XHCI_INSTANCE    *Xhc,\r
-  IN UINT32               Timeout\r
+  IN USB_XHCI_INSTANCE  *Xhc,\r
+  IN UINT32             Timeout\r
   )\r
 {\r
-  EFI_STATUS              Status;\r
+  EFI_STATUS  Status;\r
 \r
   XhcSetOpRegBit (Xhc, XHC_USBCMD_OFFSET, XHC_USBCMD_RUN);\r
   Status = XhcWaitOpRegBit (Xhc, XHC_USBSTS_OFFSET, XHC_USBSTS_HALT, FALSE, Timeout);\r
   return Status;\r
 }\r
-\r