]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Bus/Pci/EhciDxe/Ehci.c
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[mirror_edk2.git] / MdeModulePkg / Bus / Pci / EhciDxe / Ehci.c
index 9d181351a2fedd37a8020d74fe965ff04ea9f0bf..e903593b0198f5a48f9d78e62fc5bdcb1ff7ac66 100644 (file)
@@ -1,26 +1,21 @@
 /** @file\r
+  The Ehci controller driver.\r
 \r
-Copyright (c) 2006 - 2007, Intel Corporation\r
-All rights reserved. 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
+  EhciDxe driver is responsible for managing the behavior of EHCI controller.\r
+  It implements the interfaces of monitoring the status of all ports and transferring\r
+  Control, Bulk, Interrupt and Isochronous requests to Usb2.0 device.\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
+  Note that EhciDxe driver is enhanced to guarantee that the EHCI controller get attached\r
+  to the EHCI controller before a UHCI or OHCI driver attaches to the companion UHCI or\r
+  OHCI controller.  This way avoids the control transfer on a shared port between EHCI\r
+  and companion host controller when UHCI or OHCI gets attached earlier than EHCI and a\r
+  USB 2.0 device inserts.\r
 \r
-Module Name:\r
-\r
-    Ehci.c\r
-\r
-Abstract:\r
-\r
-\r
-Revision History\r
+Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
 \r
 **/\r
 \r
-\r
 #include "Ehci.h"\r
 \r
 //\r
@@ -28,36 +23,44 @@ Revision History
 // to the UEFI protocol's port state (change).\r
 //\r
 USB_PORT_STATE_MAP  mUsbPortStateMap[] = {\r
-  {PORTSC_CONN,     USB_PORT_STAT_CONNECTION},\r
-  {PORTSC_ENABLED,  USB_PORT_STAT_ENABLE},\r
-  {PORTSC_SUSPEND,  USB_PORT_STAT_SUSPEND},\r
-  {PORTSC_OVERCUR,  USB_PORT_STAT_OVERCURRENT},\r
-  {PORTSC_RESET,    USB_PORT_STAT_RESET},\r
-  {PORTSC_POWER,    USB_PORT_STAT_POWER},\r
-  {PORTSC_OWNER,    USB_PORT_STAT_OWNER}\r
+  { PORTSC_CONN,    USB_PORT_STAT_CONNECTION  },\r
+  { PORTSC_ENABLED, USB_PORT_STAT_ENABLE      },\r
+  { PORTSC_SUSPEND, USB_PORT_STAT_SUSPEND     },\r
+  { PORTSC_OVERCUR, USB_PORT_STAT_OVERCURRENT },\r
+  { PORTSC_RESET,   USB_PORT_STAT_RESET       },\r
+  { PORTSC_POWER,   USB_PORT_STAT_POWER       },\r
+  { PORTSC_OWNER,   USB_PORT_STAT_OWNER       }\r
 };\r
 \r
 USB_PORT_STATE_MAP  mUsbPortChangeMap[] = {\r
-  {PORTSC_CONN_CHANGE,    USB_PORT_STAT_C_CONNECTION},\r
-  {PORTSC_ENABLE_CHANGE,  USB_PORT_STAT_C_ENABLE},\r
-  {PORTSC_OVERCUR_CHANGE, USB_PORT_STAT_C_OVERCURRENT}\r
+  { PORTSC_CONN_CHANGE,    USB_PORT_STAT_C_CONNECTION  },\r
+  { PORTSC_ENABLE_CHANGE,  USB_PORT_STAT_C_ENABLE      },\r
+  { PORTSC_OVERCUR_CHANGE, USB_PORT_STAT_C_OVERCURRENT }\r
 };\r
 \r
+EFI_DRIVER_BINDING_PROTOCOL\r
+  gEhciDriverBinding = {\r
+  EhcDriverBindingSupported,\r
+  EhcDriverBindingStart,\r
+  EhcDriverBindingStop,\r
+  0x30,\r
+  NULL,\r
+  NULL\r
+};\r
 \r
 /**\r
-  Retrieves the capablility of root hub ports.\r
+  Retrieves the capability of root hub ports.\r
 \r
-  @param  This                 This EFI_USB_HC_PROTOCOL instance.\r
-  @param  MaxSpeed             Max speed supported by the controller\r
-  @param  PortNumber           Number of the root hub ports.\r
-  @param  Is64BitCapable       Whether the controller supports 64-bit memory\r
-                               addressing.\r
+  @param  This                  This EFI_USB_HC_PROTOCOL instance.\r
+  @param  MaxSpeed              Max speed supported by the controller.\r
+  @param  PortNumber            Number of the root hub ports.\r
+  @param  Is64BitCapable        Whether the controller supports 64-bit memory\r
+                                addressing.\r
 \r
-  @return EFI_SUCCESS           : host controller capability were retrieved successfully.\r
-  @return EFI_INVALID_PARAMETER : Either of the three capability pointer is NULL\r
+  @retval EFI_SUCCESS           Host controller capability were retrieved successfully.\r
+  @retval EFI_INVALID_PARAMETER Either of the three capability pointer is NULL.\r
 \r
 **/\r
-STATIC\r
 EFI_STATUS\r
 EFIAPI\r
 EhcGetCapability (\r
@@ -67,136 +70,149 @@ EhcGetCapability (
   OUT UINT8                 *Is64BitCapable\r
   )\r
 {\r
-  USB2_HC_DEV             *Ehc;\r
-  EFI_TPL                 OldTpl;\r
+  USB2_HC_DEV  *Ehc;\r
+  EFI_TPL      OldTpl;\r
 \r
   if ((MaxSpeed == NULL) || (PortNumber == NULL) || (Is64BitCapable == NULL)) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
-  OldTpl          = gBS->RaiseTPL (EHC_TPL);\r
-  Ehc             = EHC_FROM_THIS (This);\r
+  OldTpl = gBS->RaiseTPL (EHC_TPL);\r
+  Ehc    = EHC_FROM_THIS (This);\r
 \r
   *MaxSpeed       = EFI_USB_SPEED_HIGH;\r
-  *PortNumber     = (UINT8) (Ehc->HcStructParams & HCSP_NPORTS);\r
-  *Is64BitCapable = (UINT8) (Ehc->HcCapParams & HCCP_64BIT);\r
+  *PortNumber     = (UINT8)(Ehc->HcStructParams & HCSP_NPORTS);\r
+  *Is64BitCapable = (UINT8)Ehc->Support64BitDma;\r
 \r
-  DEBUG ((EFI_D_INFO, "EhcGetCapability: %d ports, 64 bit %d\n", *PortNumber, *Is64BitCapable));\r
+  DEBUG ((DEBUG_INFO, "EhcGetCapability: %d ports, 64 bit %d\n", *PortNumber, *Is64BitCapable));\r
 \r
   gBS->RestoreTPL (OldTpl);\r
   return EFI_SUCCESS;\r
 }\r
 \r
-\r
 /**\r
   Provides software reset for the USB host controller.\r
 \r
-  @param  This                 This EFI_USB2_HC_PROTOCOL instance.\r
-  @param  Attributes           A bit mask of the reset operation to perform.\r
+  @param  This                  This EFI_USB2_HC_PROTOCOL instance.\r
+  @param  Attributes            A bit mask of the reset operation to perform.\r
 \r
-  @return EFI_SUCCESS           : The reset operation succeeded.\r
-  @return EFI_INVALID_PARAMETER : Attributes is not valid.\r
-  @return EFI_UNSUPPOURTED      : The type of reset specified by Attributes is\r
-  @return not currently supported by the host controller.\r
-  @return EFI_DEVICE_ERROR      : Host controller isn't halted to reset.\r
+  @retval EFI_SUCCESS           The reset operation succeeded.\r
+  @retval EFI_INVALID_PARAMETER Attributes is not valid.\r
+  @retval EFI_UNSUPPOURTED      The type of reset specified by Attributes is\r
+                                not currently supported by the host controller.\r
+  @retval EFI_DEVICE_ERROR      Host controller isn't halted to reset.\r
 \r
 **/\r
-STATIC\r
 EFI_STATUS\r
 EFIAPI\r
 EhcReset (\r
-  IN EFI_USB2_HC_PROTOCOL *This,\r
-  IN UINT16               Attributes\r
+  IN EFI_USB2_HC_PROTOCOL  *This,\r
+  IN UINT16                Attributes\r
   )\r
 {\r
-  USB2_HC_DEV             *Ehc;\r
-  EFI_TPL                 OldTpl;\r
-  EFI_STATUS              Status;\r
+  USB2_HC_DEV  *Ehc;\r
+  EFI_TPL      OldTpl;\r
+  EFI_STATUS   Status;\r
 \r
-  OldTpl  = gBS->RaiseTPL (EHC_TPL);\r
-  Ehc     = EHC_FROM_THIS (This);\r
+  Ehc = EHC_FROM_THIS (This);\r
 \r
-  switch (Attributes) {\r
-  case EFI_USB_HC_RESET_GLOBAL:\r
-  //\r
-  // Flow through, same behavior as Host Controller Reset\r
-  //\r
-  case EFI_USB_HC_RESET_HOST_CONTROLLER:\r
+  if (Ehc->DevicePath != NULL) {\r
     //\r
-    // Host Controller must be Halt when Reset it\r
+    // Report Status Code to indicate reset happens\r
     //\r
-    if (!EhcIsHalt (Ehc)) {\r
-      Status = EhcHaltHC (Ehc, EHC_GENERIC_TIMEOUT);\r
+    REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
+      EFI_PROGRESS_CODE,\r
+      (EFI_IO_BUS_USB | EFI_IOB_PC_RESET),\r
+      Ehc->DevicePath\r
+      );\r
+  }\r
 \r
-      if (EFI_ERROR (Status)) {\r
-        Status = EFI_DEVICE_ERROR;\r
-        goto ON_EXIT;\r
-      }\r
-    }\r
+  OldTpl = gBS->RaiseTPL (EHC_TPL);\r
 \r
+  switch (Attributes) {\r
+    case EFI_USB_HC_RESET_GLOBAL:\r
     //\r
-    // Clean up the asynchronous transfers, currently only\r
-    // interrupt supports asynchronous operation.\r
+    // Flow through, same behavior as Host Controller Reset\r
     //\r
-    EhciDelAllAsyncIntTransfers (Ehc);\r
-    EhcAckAllInterrupt (Ehc);\r
-    EhcFreeSched (Ehc);\r
+    case EFI_USB_HC_RESET_HOST_CONTROLLER:\r
+      //\r
+      // Host Controller must be Halt when Reset it\r
+      //\r
+      if (EhcIsDebugPortInUse (Ehc, NULL)) {\r
+        Status = EFI_SUCCESS;\r
+        goto ON_EXIT;\r
+      }\r
 \r
-    Status = EhcResetHC (Ehc, EHC_RESET_TIMEOUT);\r
+      if (!EhcIsHalt (Ehc)) {\r
+        Status = EhcHaltHC (Ehc, EHC_GENERIC_TIMEOUT);\r
 \r
-    if (EFI_ERROR (Status)) {\r
-      goto ON_EXIT;\r
-    }\r
+        if (EFI_ERROR (Status)) {\r
+          Status = EFI_DEVICE_ERROR;\r
+          goto ON_EXIT;\r
+        }\r
+      }\r
 \r
-    Status = EhcInitHC (Ehc);\r
-    break;\r
+      //\r
+      // Clean up the asynchronous transfers, currently only\r
+      // interrupt supports asynchronous operation.\r
+      //\r
+      EhciDelAllAsyncIntTransfers (Ehc);\r
+      EhcAckAllInterrupt (Ehc);\r
+      EhcFreeSched (Ehc);\r
 \r
-  case EFI_USB_HC_RESET_GLOBAL_WITH_DEBUG:\r
-  case EFI_USB_HC_RESET_HOST_WITH_DEBUG:\r
-    Status = EFI_UNSUPPORTED;\r
-    break;\r
+      Status = EhcResetHC (Ehc, EHC_RESET_TIMEOUT);\r
 \r
-  default:\r
-    Status = EFI_INVALID_PARAMETER;\r
+      if (EFI_ERROR (Status)) {\r
+        goto ON_EXIT;\r
+      }\r
+\r
+      Status = EhcInitHC (Ehc);\r
+      break;\r
+\r
+    case EFI_USB_HC_RESET_GLOBAL_WITH_DEBUG:\r
+    case EFI_USB_HC_RESET_HOST_WITH_DEBUG:\r
+      Status = EFI_UNSUPPORTED;\r
+      break;\r
+\r
+    default:\r
+      Status = EFI_INVALID_PARAMETER;\r
   }\r
 \r
 ON_EXIT:\r
-  DEBUG ((EFI_D_INFO, "EhcReset: exit status %r\n", Status));\r
+  DEBUG ((DEBUG_INFO, "EhcReset: exit status %r\n", Status));\r
   gBS->RestoreTPL (OldTpl);\r
   return Status;\r
 }\r
 \r
-\r
 /**\r
   Retrieve the current state of the USB host controller.\r
 \r
-  @param  This                 This EFI_USB2_HC_PROTOCOL instance.\r
-  @param  State                Variable to return the current host controller\r
-                               state.\r
+  @param  This                   This EFI_USB2_HC_PROTOCOL instance.\r
+  @param  State                  Variable to return the current host controller\r
+                                 state.\r
 \r
-  @return EFI_SUCCESS           : Host controller state was returned in State.\r
-  @return EFI_INVALID_PARAMETER : State is NULL.\r
-  @return EFI_DEVICE_ERROR      : An error was encountered while attempting to\r
-  @return retrieve the host controller's current state.\r
+  @retval EFI_SUCCESS            Host controller state was returned in State.\r
+  @retval EFI_INVALID_PARAMETER  State is NULL.\r
+  @retval EFI_DEVICE_ERROR       An error was encountered while attempting to\r
+                                 retrieve the host controller's current state.\r
 \r
 **/\r
-STATIC\r
 EFI_STATUS\r
 EFIAPI\r
 EhcGetState (\r
-  IN  CONST EFI_USB2_HC_PROTOCOL  *This,\r
-  OUT       EFI_USB_HC_STATE      *State\r
+  IN   EFI_USB2_HC_PROTOCOL  *This,\r
+  OUT  EFI_USB_HC_STATE      *State\r
   )\r
 {\r
-  EFI_TPL                 OldTpl;\r
-  USB2_HC_DEV             *Ehc;\r
+  EFI_TPL      OldTpl;\r
+  USB2_HC_DEV  *Ehc;\r
 \r
   if (State == NULL) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
-  OldTpl  = gBS->RaiseTPL (EHC_TPL);\r
-  Ehc     = EHC_FROM_THIS (This);\r
+  OldTpl = gBS->RaiseTPL (EHC_TPL);\r
+  Ehc    = EHC_FROM_THIS (This);\r
 \r
   if (EHC_REG_BIT_IS_SET (Ehc, EHC_USBSTS_OFFSET, USBSTS_HALT)) {\r
     *State = EfiUsbHcStateHalt;\r
@@ -206,35 +222,33 @@ EhcGetState (
 \r
   gBS->RestoreTPL (OldTpl);\r
 \r
-  DEBUG ((EFI_D_INFO, "EhcGetState: current state %d\n", *State));\r
+  DEBUG ((DEBUG_INFO, "EhcGetState: current state %d\n", *State));\r
   return EFI_SUCCESS;\r
 }\r
 \r
-\r
 /**\r
   Sets the USB host controller to a specific state.\r
 \r
-  @param  This                 This EFI_USB2_HC_PROTOCOL instance.\r
-  @param  State                The state of the host controller that will be set.\r
+  @param  This                  This EFI_USB2_HC_PROTOCOL instance.\r
+  @param  State                 The state of the host controller that will be set.\r
 \r
-  @return EFI_SUCCESS           : The USB host controller was successfully placed\r
-  @return in the state specified by State.\r
-  @return EFI_INVALID_PARAMETER : State is invalid.\r
-  @return EFI_DEVICE_ERROR      : Failed to set the state due to device error.\r
+  @retval EFI_SUCCESS           The USB host controller was successfully placed\r
+                                in the state specified by State.\r
+  @retval EFI_INVALID_PARAMETER State is invalid.\r
+  @retval EFI_DEVICE_ERROR      Failed to set the state due to device error.\r
 \r
 **/\r
-STATIC\r
 EFI_STATUS\r
 EFIAPI\r
 EhcSetState (\r
-  IN EFI_USB2_HC_PROTOCOL *This,\r
-  IN EFI_USB_HC_STATE     State\r
+  IN EFI_USB2_HC_PROTOCOL  *This,\r
+  IN EFI_USB_HC_STATE      State\r
   )\r
 {\r
-  USB2_HC_DEV             *Ehc;\r
-  EFI_TPL                 OldTpl;\r
-  EFI_STATUS              Status;\r
-  EFI_USB_HC_STATE        CurState;\r
+  USB2_HC_DEV       *Ehc;\r
+  EFI_TPL           OldTpl;\r
+  EFI_STATUS        Status;\r
+  EFI_USB_HC_STATE  CurState;\r
 \r
   Status = EhcGetState (This, &CurState);\r
 \r
@@ -246,87 +260,85 @@ EhcSetState (
     return EFI_SUCCESS;\r
   }\r
 \r
-  OldTpl  = gBS->RaiseTPL (EHC_TPL);\r
-  Ehc     = EHC_FROM_THIS (This);\r
+  OldTpl = gBS->RaiseTPL (EHC_TPL);\r
+  Ehc    = EHC_FROM_THIS (This);\r
 \r
   switch (State) {\r
-  case EfiUsbHcStateHalt:\r
-    Status = EhcHaltHC (Ehc, EHC_GENERIC_TIMEOUT);\r
-    break;\r
-\r
-  case EfiUsbHcStateOperational:\r
-    if (EHC_REG_BIT_IS_SET (Ehc, EHC_USBSTS_OFFSET, USBSTS_SYS_ERROR)) {\r
-      Status = EFI_DEVICE_ERROR;\r
+    case EfiUsbHcStateHalt:\r
+      Status = EhcHaltHC (Ehc, EHC_GENERIC_TIMEOUT);\r
       break;\r
-    }\r
 \r
-    //\r
-    // Software must not write a one to this field unless the host controller\r
-    // is in the Halted state. Doing so will yield undefined results.\r
-    // refers to Spec[EHCI1.0-2.3.1]\r
-    //\r
-    if (!EHC_REG_BIT_IS_SET (Ehc, EHC_USBSTS_OFFSET, USBSTS_HALT)) {\r
-      Status = EFI_DEVICE_ERROR;\r
-      break;\r
-    }\r
+    case EfiUsbHcStateOperational:\r
+      if (EHC_REG_BIT_IS_SET (Ehc, EHC_USBSTS_OFFSET, USBSTS_SYS_ERROR)) {\r
+        Status = EFI_DEVICE_ERROR;\r
+        break;\r
+      }\r
 \r
-    Status = EhcRunHC (Ehc, EHC_GENERIC_TIMEOUT);\r
-    break;\r
+      //\r
+      // Software must not write a one to this field unless the host controller\r
+      // is in the Halted state. Doing so will yield undefined results.\r
+      // refers to Spec[EHCI1.0-2.3.1]\r
+      //\r
+      if (!EHC_REG_BIT_IS_SET (Ehc, EHC_USBSTS_OFFSET, USBSTS_HALT)) {\r
+        Status = EFI_DEVICE_ERROR;\r
+        break;\r
+      }\r
 \r
-  case EfiUsbHcStateSuspend:\r
-    Status = EFI_UNSUPPORTED;\r
-    break;\r
+      Status = EhcRunHC (Ehc, EHC_GENERIC_TIMEOUT);\r
+      break;\r
 \r
-  default:\r
-    Status = EFI_INVALID_PARAMETER;\r
+    case EfiUsbHcStateSuspend:\r
+      Status = EFI_UNSUPPORTED;\r
+      break;\r
+\r
+    default:\r
+      Status = EFI_INVALID_PARAMETER;\r
   }\r
 \r
-  DEBUG ((EFI_D_INFO, "EhcSetState: exit status %r\n", Status));\r
+  DEBUG ((DEBUG_INFO, "EhcSetState: exit status %r\n", Status));\r
   gBS->RestoreTPL (OldTpl);\r
   return Status;\r
 }\r
 \r
-\r
 /**\r
   Retrieves the current status of a USB root hub port.\r
 \r
-  @param  This                 This EFI_USB2_HC_PROTOCOL instance.\r
-  @param  PortNumber           The root hub port to retrieve the state from.   This\r
-                               value is zero-based.\r
-  @param  PortStatus           Variable to receive the port state\r
+  @param  This                  This EFI_USB2_HC_PROTOCOL instance.\r
+  @param  PortNumber            The root hub port to retrieve the state from.\r
+                                This value is zero-based.\r
+  @param  PortStatus            Variable to receive the port state.\r
 \r
-  @return EFI_SUCCESS           : The status of the USB root hub port specified\r
-  @return by PortNumber was returned in PortStatus.\r
-  @return EFI_INVALID_PARAMETER : PortNumber is invalid.\r
-  @return EFI_DEVICE_ERROR      : Can't read register\r
+  @retval EFI_SUCCESS           The status of the USB root hub port specified.\r
+                                by PortNumber was returned in PortStatus.\r
+  @retval EFI_INVALID_PARAMETER PortNumber is invalid.\r
+  @retval EFI_DEVICE_ERROR      Can't read register.\r
 \r
 **/\r
-STATIC\r
 EFI_STATUS\r
 EFIAPI\r
 EhcGetRootHubPortStatus (\r
-  IN  CONST EFI_USB2_HC_PROTOCOL  *This,\r
-  IN  CONST UINT8                 PortNumber,\r
-  OUT       EFI_USB_PORT_STATUS   *PortStatus\r
+  IN   EFI_USB2_HC_PROTOCOL  *This,\r
+  IN   UINT8                 PortNumber,\r
+  OUT  EFI_USB_PORT_STATUS   *PortStatus\r
   )\r
 {\r
-  USB2_HC_DEV             *Ehc;\r
-  EFI_TPL                 OldTpl;\r
-  UINT32                  Offset;\r
-  UINT32                  State;\r
-  UINT32                  TotalPort;\r
-  UINTN                   Index;\r
-  UINTN                   MapSize;\r
-  EFI_STATUS              Status;\r
+  USB2_HC_DEV  *Ehc;\r
+  EFI_TPL      OldTpl;\r
+  UINT32       Offset;\r
+  UINT32       State;\r
+  UINT32       TotalPort;\r
+  UINTN        Index;\r
+  UINTN        MapSize;\r
+  EFI_STATUS   Status;\r
 \r
   if (PortStatus == NULL) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
-  OldTpl    = gBS->RaiseTPL (EHC_TPL);\r
+  OldTpl = gBS->RaiseTPL (EHC_TPL);\r
 \r
-  Ehc       = EHC_FROM_THIS (This);\r
-  Status    = EFI_SUCCESS;\r
+  Ehc    = EHC_FROM_THIS (This);\r
+  Status = EFI_SUCCESS;\r
 \r
   TotalPort = (Ehc->HcStructParams & HCSP_NPORTS);\r
 \r
@@ -335,11 +347,15 @@ EhcGetRootHubPortStatus (
     goto ON_EXIT;\r
   }\r
 \r
-  Offset                        = (UINT32) (EHC_PORT_STAT_OFFSET + (4 * PortNumber));\r
-  PortStatus->PortStatus        = 0;\r
-  PortStatus->PortChangeStatus  = 0;\r
+  Offset                       = (UINT32)(EHC_PORT_STAT_OFFSET + (4 * PortNumber));\r
+  PortStatus->PortStatus       = 0;\r
+  PortStatus->PortChangeStatus = 0;\r
+\r
+  if (EhcIsDebugPortInUse (Ehc, &PortNumber)) {\r
+    goto ON_EXIT;\r
+  }\r
 \r
-  State                         = EhcReadOpReg (Ehc, Offset);\r
+  State = EhcReadOpReg (Ehc, Offset);\r
 \r
   //\r
   // Identify device speed. If in K state, it is low speed.\r
@@ -349,7 +365,6 @@ EhcGetRootHubPortStatus (
   //\r
   if (EHC_BIT_IS_SET (State, PORTSC_LINESTATE_K)) {\r
     PortStatus->PortStatus |= USB_PORT_STAT_LOW_SPEED;\r
-\r
   } else if (EHC_BIT_IS_SET (State, PORTSC_ENABLED)) {\r
     PortStatus->PortStatus |= USB_PORT_STAT_HIGH_SPEED;\r
   }\r
@@ -361,7 +376,7 @@ EhcGetRootHubPortStatus (
 \r
   for (Index = 0; Index < MapSize; Index++) {\r
     if (EHC_BIT_IS_SET (State, mUsbPortStateMap[Index].HwState)) {\r
-      PortStatus->PortStatus = (UINT16) (PortStatus->PortStatus | mUsbPortStateMap[Index].UefiState);\r
+      PortStatus->PortStatus = (UINT16)(PortStatus->PortStatus | mUsbPortStateMap[Index].UefiState);\r
     }\r
   }\r
 \r
@@ -369,7 +384,7 @@ EhcGetRootHubPortStatus (
 \r
   for (Index = 0; Index < MapSize; Index++) {\r
     if (EHC_BIT_IS_SET (State, mUsbPortChangeMap[Index].HwState)) {\r
-      PortStatus->PortChangeStatus = (UINT16) (PortStatus->PortChangeStatus | mUsbPortChangeMap[Index].UefiState);\r
+      PortStatus->PortChangeStatus = (UINT16)(PortStatus->PortChangeStatus | mUsbPortChangeMap[Index].UefiState);\r
     }\r
   }\r
 \r
@@ -378,20 +393,18 @@ ON_EXIT:
   return Status;\r
 }\r
 \r
-\r
 /**\r
   Sets a feature for the specified root hub port.\r
 \r
-  @param  This                 This EFI_USB2_HC_PROTOCOL instance.\r
-  @param  PortNumber           Root hub port to set.\r
-  @param  PortFeature          Feature to set\r
+  @param  This                  This EFI_USB2_HC_PROTOCOL instance.\r
+  @param  PortNumber            Root hub port to set.\r
+  @param  PortFeature           Feature to set.\r
 \r
-  @return EFI_SUCCESS           : The feature specified by PortFeature was set\r
-  @return EFI_INVALID_PARAMETER : PortNumber is invalid or PortFeature is invalid.\r
-  @return EFI_DEVICE_ERROR      : Can't read register\r
+  @retval EFI_SUCCESS           The feature specified by PortFeature was set.\r
+  @retval EFI_INVALID_PARAMETER PortNumber is invalid or PortFeature is invalid.\r
+  @retval EFI_DEVICE_ERROR      Can't read register.\r
 \r
 **/\r
-STATIC\r
 EFI_STATUS\r
 EFIAPI\r
 EhcSetRootHubPortFeature (\r
@@ -400,16 +413,16 @@ EhcSetRootHubPortFeature (
   IN  EFI_USB_PORT_FEATURE  PortFeature\r
   )\r
 {\r
-  USB2_HC_DEV             *Ehc;\r
-  EFI_TPL                 OldTpl;\r
-  UINT32                  Offset;\r
-  UINT32                  State;\r
-  UINT32                  TotalPort;\r
-  EFI_STATUS              Status;\r
-\r
-  OldTpl    = gBS->RaiseTPL (EHC_TPL);\r
-  Ehc       = EHC_FROM_THIS (This);\r
-  Status    = EFI_SUCCESS;\r
+  USB2_HC_DEV  *Ehc;\r
+  EFI_TPL      OldTpl;\r
+  UINT32       Offset;\r
+  UINT32       State;\r
+  UINT32       TotalPort;\r
+  EFI_STATUS   Status;\r
+\r
+  OldTpl = gBS->RaiseTPL (EHC_TPL);\r
+  Ehc    = EHC_FROM_THIS (This);\r
+  Status = EFI_SUCCESS;\r
 \r
   TotalPort = (Ehc->HcStructParams & HCSP_NPORTS);\r
 \r
@@ -418,8 +431,8 @@ EhcSetRootHubPortFeature (
     goto ON_EXIT;\r
   }\r
 \r
-  Offset  = (UINT32) (EHC_PORT_STAT_OFFSET + (4 * PortNumber));\r
-  State   = EhcReadOpReg (Ehc, Offset);\r
+  Offset = (UINT32)(EHC_PORT_STAT_OFFSET + (4 * PortNumber));\r
+  State  = EhcReadOpReg (Ehc, Offset);\r
 \r
   //\r
   // Mask off the port status change bits, these bits are\r
@@ -428,81 +441,83 @@ EhcSetRootHubPortFeature (
   State &= ~PORTSC_CHANGE_MASK;\r
 \r
   switch (PortFeature) {\r
-  case EfiUsbPortEnable:\r
-    //\r
-    // Sofeware can't set this bit, Port can only be enable by\r
-    // EHCI as a part of the reset and enable\r
-    //\r
-    State |= PORTSC_ENABLED;\r
-    EhcWriteOpReg (Ehc, Offset, State);\r
-    break;\r
-\r
-  case EfiUsbPortSuspend:\r
-    State |= PORTSC_SUSPEND;\r
-    EhcWriteOpReg (Ehc, Offset, State);\r
-    break;\r
+    case EfiUsbPortEnable:\r
+      //\r
+      // Sofeware can't set this bit, Port can only be enable by\r
+      // EHCI as a part of the reset and enable\r
+      //\r
+      State |= PORTSC_ENABLED;\r
+      EhcWriteOpReg (Ehc, Offset, State);\r
+      break;\r
 \r
-  case EfiUsbPortReset:\r
-    //\r
-    // Make sure Host Controller not halt before reset it\r
-    //\r
-    if (EhcIsHalt (Ehc)) {\r
-      Status = EhcRunHC (Ehc, EHC_GENERIC_TIMEOUT);\r
+    case EfiUsbPortSuspend:\r
+      State |= PORTSC_SUSPEND;\r
+      EhcWriteOpReg (Ehc, Offset, State);\r
+      break;\r
 \r
-      if (EFI_ERROR (Status)) {\r
-        DEBUG ((EFI_D_INFO, "EhcSetRootHubPortFeature :failed to start HC - %r\n", Status));\r
-        break;\r
+    case EfiUsbPortReset:\r
+      //\r
+      // Make sure Host Controller not halt before reset it\r
+      //\r
+      if (EhcIsHalt (Ehc)) {\r
+        Status = EhcRunHC (Ehc, EHC_GENERIC_TIMEOUT);\r
+\r
+        if (EFI_ERROR (Status)) {\r
+          DEBUG ((DEBUG_INFO, "EhcSetRootHubPortFeature :failed to start HC - %r\n", Status));\r
+          break;\r
+        }\r
       }\r
-    }\r
 \r
-    //\r
-    // Set one to PortReset bit must also set zero to PortEnable bit\r
-    //\r
-    State |= PORTSC_RESET;\r
-    State &= ~PORTSC_ENABLED;\r
-    EhcWriteOpReg (Ehc, Offset, State);\r
-    break;\r
+      //\r
+      // Set one to PortReset bit must also set zero to PortEnable bit\r
+      //\r
+      State |= PORTSC_RESET;\r
+      State &= ~PORTSC_ENABLED;\r
+      EhcWriteOpReg (Ehc, Offset, State);\r
+      break;\r
 \r
-  case EfiUsbPortPower:\r
-    //\r
-    // Not supported, ignore the operation\r
-    //\r
-    Status = EFI_SUCCESS;\r
-    break;\r
+    case EfiUsbPortPower:\r
+      //\r
+      // Set port power bit when PPC is 1\r
+      //\r
+      if ((Ehc->HcCapParams & HCSP_PPC) == HCSP_PPC) {\r
+        State |= PORTSC_POWER;\r
+        EhcWriteOpReg (Ehc, Offset, State);\r
+      }\r
+\r
+      break;\r
 \r
-  case EfiUsbPortOwner:\r
-    State |= PORTSC_OWNER;\r
-    EhcWriteOpReg (Ehc, Offset, State);\r
-    break;\r
+    case EfiUsbPortOwner:\r
+      State |= PORTSC_OWNER;\r
+      EhcWriteOpReg (Ehc, Offset, State);\r
+      break;\r
 \r
-  default:\r
-    Status = EFI_INVALID_PARAMETER;\r
+    default:\r
+      Status = EFI_INVALID_PARAMETER;\r
   }\r
 \r
 ON_EXIT:\r
-  DEBUG ((EFI_D_INFO, "EhcSetRootHubPortFeature: exit status %r\n", Status));\r
+  DEBUG ((DEBUG_INFO, "EhcSetRootHubPortFeature: exit status %r\n", Status));\r
 \r
   gBS->RestoreTPL (OldTpl);\r
   return Status;\r
 }\r
 \r
-\r
 /**\r
   Clears a feature for the specified root hub port.\r
 \r
-  @param  This                 A pointer to the EFI_USB2_HC_PROTOCOL instance.\r
-  @param  PortNumber           Specifies the root hub port whose feature is\r
-                               requested to be cleared.\r
-  @param  PortFeature          Indicates the feature selector associated with the\r
-                               feature clear request.\r
+  @param  This                  A pointer to the EFI_USB2_HC_PROTOCOL instance.\r
+  @param  PortNumber            Specifies the root hub port whose feature is\r
+                                requested to be cleared.\r
+  @param  PortFeature           Indicates the feature selector associated with the\r
+                                feature clear request.\r
 \r
-  @return EFI_SUCCESS           : The feature specified by PortFeature was cleared\r
-  @return for the USB root hub port specified by PortNumber.\r
-  @return EFI_INVALID_PARAMETER : PortNumber is invalid or PortFeature is invalid.\r
-  @return EFI_DEVICE_ERROR      : Can't read register\r
+  @retval EFI_SUCCESS           The feature specified by PortFeature was cleared\r
+                                for the USB root hub port specified by PortNumber.\r
+  @retval EFI_INVALID_PARAMETER PortNumber is invalid or PortFeature is invalid.\r
+  @retval EFI_DEVICE_ERROR      Can't read register.\r
 \r
 **/\r
-STATIC\r
 EFI_STATUS\r
 EFIAPI\r
 EhcClearRootHubPortFeature (\r
@@ -511,16 +526,16 @@ EhcClearRootHubPortFeature (
   IN  EFI_USB_PORT_FEATURE  PortFeature\r
   )\r
 {\r
-  USB2_HC_DEV             *Ehc;\r
-  EFI_TPL                 OldTpl;\r
-  UINT32                  Offset;\r
-  UINT32                  State;\r
-  UINT32                  TotalPort;\r
-  EFI_STATUS              Status;\r
-\r
-  OldTpl    = gBS->RaiseTPL (EHC_TPL);\r
-  Ehc       = EHC_FROM_THIS (This);\r
-  Status    = EFI_SUCCESS;\r
+  USB2_HC_DEV  *Ehc;\r
+  EFI_TPL      OldTpl;\r
+  UINT32       Offset;\r
+  UINT32       State;\r
+  UINT32       TotalPort;\r
+  EFI_STATUS   Status;\r
+\r
+  OldTpl = gBS->RaiseTPL (EHC_TPL);\r
+  Ehc    = EHC_FROM_THIS (This);\r
+  Status = EFI_SUCCESS;\r
 \r
   TotalPort = (Ehc->HcStructParams & HCSP_NPORTS);\r
 \r
@@ -529,116 +544,123 @@ EhcClearRootHubPortFeature (
     goto ON_EXIT;\r
   }\r
 \r
-  Offset  = EHC_PORT_STAT_OFFSET + (4 * PortNumber);\r
-  State   = EhcReadOpReg (Ehc, Offset);\r
+  Offset = EHC_PORT_STAT_OFFSET + (4 * PortNumber);\r
+  State  = EhcReadOpReg (Ehc, Offset);\r
   State &= ~PORTSC_CHANGE_MASK;\r
 \r
   switch (PortFeature) {\r
-  case EfiUsbPortEnable:\r
-    //\r
-    // Clear PORT_ENABLE feature means disable port.\r
-    //\r
-    State &= ~PORTSC_ENABLED;\r
-    EhcWriteOpReg (Ehc, Offset, State);\r
-    break;\r
+    case EfiUsbPortEnable:\r
+      //\r
+      // Clear PORT_ENABLE feature means disable port.\r
+      //\r
+      State &= ~PORTSC_ENABLED;\r
+      EhcWriteOpReg (Ehc, Offset, State);\r
+      break;\r
 \r
-  case EfiUsbPortSuspend:\r
-    //\r
-    // A write of zero to this bit is ignored by the host\r
-    // controller. The host controller will unconditionally\r
-    // set this bit to a zero when:\r
-    //   1. software sets the Forct Port Resume bit to a zero from a one.\r
-    //   2. software sets the Port Reset bit to a one frome a zero.\r
-    //\r
-    State &= ~PORSTSC_RESUME;\r
-    EhcWriteOpReg (Ehc, Offset, State);\r
-    break;\r
+    case EfiUsbPortSuspend:\r
+      //\r
+      // A write of zero to this bit is ignored by the host\r
+      // controller. The host controller will unconditionally\r
+      // set this bit to a zero when:\r
+      //   1. software sets the Forct Port Resume bit to a zero from a one.\r
+      //   2. software sets the Port Reset bit to a one frome a zero.\r
+      //\r
+      State &= ~PORSTSC_RESUME;\r
+      EhcWriteOpReg (Ehc, Offset, State);\r
+      break;\r
 \r
-  case EfiUsbPortReset:\r
-    //\r
-    // Clear PORT_RESET means clear the reset signal.\r
-    //\r
-    State &= ~PORTSC_RESET;\r
-    EhcWriteOpReg (Ehc, Offset, State);\r
-    break;\r
+    case EfiUsbPortReset:\r
+      //\r
+      // Clear PORT_RESET means clear the reset signal.\r
+      //\r
+      State &= ~PORTSC_RESET;\r
+      EhcWriteOpReg (Ehc, Offset, State);\r
+      break;\r
 \r
-  case EfiUsbPortOwner:\r
-    //\r
-    // Clear port owner means this port owned by EHC\r
-    //\r
-    State &= ~PORTSC_OWNER;\r
-    EhcWriteOpReg (Ehc, Offset, State);\r
-    break;\r
+    case EfiUsbPortOwner:\r
+      //\r
+      // Clear port owner means this port owned by EHC\r
+      //\r
+      State &= ~PORTSC_OWNER;\r
+      EhcWriteOpReg (Ehc, Offset, State);\r
+      break;\r
 \r
-  case EfiUsbPortConnectChange:\r
-    //\r
-    // Clear connect status change\r
-    //\r
-    State |= PORTSC_CONN_CHANGE;\r
-    EhcWriteOpReg (Ehc, Offset, State);\r
-    break;\r
+    case EfiUsbPortConnectChange:\r
+      //\r
+      // Clear connect status change\r
+      //\r
+      State |= PORTSC_CONN_CHANGE;\r
+      EhcWriteOpReg (Ehc, Offset, State);\r
+      break;\r
 \r
-  case EfiUsbPortEnableChange:\r
-    //\r
-    // Clear enable status change\r
-    //\r
-    State |= PORTSC_ENABLE_CHANGE;\r
-    EhcWriteOpReg (Ehc, Offset, State);\r
-    break;\r
+    case EfiUsbPortEnableChange:\r
+      //\r
+      // Clear enable status change\r
+      //\r
+      State |= PORTSC_ENABLE_CHANGE;\r
+      EhcWriteOpReg (Ehc, Offset, State);\r
+      break;\r
 \r
-  case EfiUsbPortOverCurrentChange:\r
-    //\r
-    // Clear PortOverCurrent change\r
-    //\r
-    State |= PORTSC_OVERCUR_CHANGE;\r
-    EhcWriteOpReg (Ehc, Offset, State);\r
-    break;\r
+    case EfiUsbPortOverCurrentChange:\r
+      //\r
+      // Clear PortOverCurrent change\r
+      //\r
+      State |= PORTSC_OVERCUR_CHANGE;\r
+      EhcWriteOpReg (Ehc, Offset, State);\r
+      break;\r
 \r
-  case EfiUsbPortPower:\r
-  case EfiUsbPortSuspendChange:\r
-  case EfiUsbPortResetChange:\r
-    //\r
-    // Not supported or not related operation\r
-    //\r
-    break;\r
+    case EfiUsbPortPower:\r
+      //\r
+      // Clear port power bit when PPC is 1\r
+      //\r
+      if ((Ehc->HcCapParams & HCSP_PPC) == HCSP_PPC) {\r
+        State &= ~PORTSC_POWER;\r
+        EhcWriteOpReg (Ehc, Offset, State);\r
+      }\r
 \r
-  default:\r
-    Status = EFI_INVALID_PARAMETER;\r
-    break;\r
+      break;\r
+    case EfiUsbPortSuspendChange:\r
+    case EfiUsbPortResetChange:\r
+      //\r
+      // Not supported or not related operation\r
+      //\r
+      break;\r
+\r
+    default:\r
+      Status = EFI_INVALID_PARAMETER;\r
+      break;\r
   }\r
 \r
 ON_EXIT:\r
-  DEBUG ((EFI_D_INFO, "EhcClearRootHubPortFeature: exit status %r\n", Status));\r
+  DEBUG ((DEBUG_INFO, "EhcClearRootHubPortFeature: exit status %r\n", Status));\r
   gBS->RestoreTPL (OldTpl);\r
   return Status;\r
 }\r
 \r
-\r
 /**\r
   Submits control transfer to a target USB device.\r
 \r
-  @param  This                 This EFI_USB2_HC_PROTOCOL instance.\r
-  @param  DeviceAddress        The target device address\r
-  @param  DeviceSpeed          Target device speed.\r
-  @param  MaximumPacketLength  Maximum packet size the default control transfer\r
-                               endpoint is capable of sending or receiving.\r
-  @param  Request              USB device request to send\r
-  @param  TransferDirection    Specifies the data direction for the data stage\r
-  @param  Data                 Data buffer to be transmitted or received from USB\r
-                               device.\r
-  @param  DataLength           The size (in bytes) of the data buffer\r
-  @param  TimeOut              Indicates the maximum timeout, in millisecond,\r
-  @param  Translator           Transaction translator to be used by this device.\r
-  @param  TransferResult       Return the result of this control transfer.\r
-\r
-  @return EFI_SUCCESS           : Transfer was completed successfully.\r
-  @return EFI_OUT_OF_RESOURCES  : The transfer failed due to lack of resources.\r
-  @return EFI_INVALID_PARAMETER : Some parameters are invalid.\r
-  @return EFI_TIMEOUT           : Transfer failed due to timeout.\r
-  @return EFI_DEVICE_ERROR      : Transfer failed due to host controller or device error.\r
+  @param  This                  This EFI_USB2_HC_PROTOCOL instance.\r
+  @param  DeviceAddress         The target device address.\r
+  @param  DeviceSpeed           Target device speed.\r
+  @param  MaximumPacketLength   Maximum packet size the default control transfer\r
+                                endpoint is capable of sending or receiving.\r
+  @param  Request               USB device request to send.\r
+  @param  TransferDirection     Specifies the data direction for the data stage\r
+  @param  Data                  Data buffer to be transmitted or received from USB\r
+                                device.\r
+  @param  DataLength            The size (in bytes) of the data buffer.\r
+  @param  TimeOut               Indicates the maximum timeout, in millisecond.\r
+  @param  Translator            Transaction translator to be used by this device.\r
+  @param  TransferResult        Return the result of this control transfer.\r
+\r
+  @retval EFI_SUCCESS           Transfer was completed successfully.\r
+  @retval EFI_OUT_OF_RESOURCES  The transfer failed due to lack of resources.\r
+  @retval EFI_INVALID_PARAMETER Some parameters are invalid.\r
+  @retval EFI_TIMEOUT           Transfer failed due to timeout.\r
+  @retval EFI_DEVICE_ERROR      Transfer failed due to host controller or device error.\r
 \r
 **/\r
-STATIC\r
 EFI_STATUS\r
 EFIAPI\r
 EhcControlTransfer (\r
@@ -655,11 +677,11 @@ EhcControlTransfer (
   OUT UINT32                              *TransferResult\r
   )\r
 {\r
-  USB2_HC_DEV             *Ehc;\r
-  URB                     *Urb;\r
-  EFI_TPL                 OldTpl;\r
-  UINT8                   Endpoint;\r
-  EFI_STATUS              Status;\r
+  USB2_HC_DEV  *Ehc;\r
+  URB          *Urb;\r
+  EFI_TPL      OldTpl;\r
+  UINT8        Endpoint;\r
+  EFI_STATUS   Status;\r
 \r
   //\r
   // Validate parameters\r
@@ -670,22 +692,26 @@ EhcControlTransfer (
 \r
   if ((TransferDirection != EfiUsbDataIn) &&\r
       (TransferDirection != EfiUsbDataOut) &&\r
-      (TransferDirection != EfiUsbNoData)) {\r
+      (TransferDirection != EfiUsbNoData))\r
+  {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
   if ((TransferDirection == EfiUsbNoData) &&\r
-      ((Data != NULL) || (*DataLength != 0))) {\r
+      ((Data != NULL) || (*DataLength != 0)))\r
+  {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
   if ((TransferDirection != EfiUsbNoData) &&\r
-     ((Data == NULL) || (*DataLength == 0))) {\r
+      ((Data == NULL) || (*DataLength == 0)))\r
+  {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
   if ((MaximumPacketLength != 8)  && (MaximumPacketLength != 16) &&\r
-      (MaximumPacketLength != 32) && (MaximumPacketLength != 64)) {\r
+      (MaximumPacketLength != 32) && (MaximumPacketLength != 64))\r
+  {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
@@ -693,14 +719,14 @@ EhcControlTransfer (
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
-  OldTpl          = gBS->RaiseTPL (EHC_TPL);\r
-  Ehc             = EHC_FROM_THIS (This);\r
+  OldTpl = gBS->RaiseTPL (EHC_TPL);\r
+  Ehc    = EHC_FROM_THIS (This);\r
 \r
   Status          = EFI_DEVICE_ERROR;\r
   *TransferResult = EFI_USB_ERR_SYSTEM;\r
 \r
   if (EhcIsHalt (Ehc) || EhcIsSysError (Ehc)) {\r
-    DEBUG ((EFI_D_ERROR, "EhcControlTransfer: HC halted at entrance\n"));\r
+    DEBUG ((DEBUG_ERROR, "EhcControlTransfer: HC halted at entrance\n"));\r
 \r
     EhcAckAllInterrupt (Ehc);\r
     goto ON_EXIT;\r
@@ -717,26 +743,26 @@ EhcControlTransfer (
   // endpoint is bidirectional. EhcCreateUrb expects this\r
   // combination of Ep addr and its direction.\r
   //\r
-  Endpoint = (UINT8) (0 | ((TransferDirection == EfiUsbDataIn) ? 0x80 : 0));\r
-  Urb = EhcCreateUrb (\r
-          Ehc,\r
-          DeviceAddress,\r
-          Endpoint,\r
-          DeviceSpeed,\r
-          0,\r
-          MaximumPacketLength,\r
-          Translator,\r
-          EHC_CTRL_TRANSFER,\r
-          Request,\r
-          Data,\r
-          *DataLength,\r
-          NULL,\r
-          NULL,\r
-          1\r
-          );\r
+  Endpoint = (UINT8)(0 | ((TransferDirection == EfiUsbDataIn) ? 0x80 : 0));\r
+  Urb      = EhcCreateUrb (\r
+               Ehc,\r
+               DeviceAddress,\r
+               Endpoint,\r
+               DeviceSpeed,\r
+               0,\r
+               MaximumPacketLength,\r
+               Translator,\r
+               EHC_CTRL_TRANSFER,\r
+               Request,\r
+               Data,\r
+               *DataLength,\r
+               NULL,\r
+               NULL,\r
+               1\r
+               );\r
 \r
   if (Urb == NULL) {\r
-    DEBUG ((EFI_D_ERROR, "EhcControlTransfer: failed to create URB"));\r
+    DEBUG ((DEBUG_ERROR, "EhcControlTransfer: failed to create URB"));\r
 \r
     Status = EFI_OUT_OF_RESOURCES;\r
     goto ON_EXIT;\r
@@ -765,45 +791,42 @@ ON_EXIT:
   gBS->RestoreTPL (OldTpl);\r
 \r
   if (EFI_ERROR (Status)) {\r
-    DEBUG ((EFI_D_ERROR, "EhcControlTransfer: error - %r, transfer - %x\n", Status, *TransferResult));\r
+    DEBUG ((DEBUG_ERROR, "EhcControlTransfer: error - %r, transfer - %x\n", Status, *TransferResult));\r
   }\r
 \r
   return Status;\r
 }\r
 \r
-\r
 /**\r
   Submits bulk transfer to a bulk endpoint of a USB device.\r
 \r
-  @param  This                 This EFI_USB2_HC_PROTOCOL instance.\r
-  @param  DeviceAddress        Target device address\r
-  @param  EndPointAddress      Endpoint number and its direction in bit 7. .\r
-  @param  DeviceSpeed          Device speed, Low speed device doesn't support  bulk\r
-                               transfer.\r
-  @param  MaximumPacketLength  Maximum packet size the endpoint is capable of\r
-                               sending or receiving.\r
-  @param  DataBuffersNumber    Number of data buffers prepared for the transfer.\r
-  @param  Data                 Array of pointers to the buffers of data to transmit\r
+  @param  This                  This EFI_USB2_HC_PROTOCOL instance.\r
+  @param  DeviceAddress         Target device address.\r
+  @param  EndPointAddress       Endpoint number and its direction in bit 7.\r
+  @param  DeviceSpeed           Device speed, Low speed device doesn't support bulk\r
+                                transfer.\r
+  @param  MaximumPacketLength   Maximum packet size the endpoint is capable of\r
+                                sending or receiving.\r
+  @param  DataBuffersNumber     Number of data buffers prepared for the transfer.\r
+  @param  Data                  Array of pointers to the buffers of data to transmit\r
                                 from or receive into.\r
-  @param  DataLength           The lenght of the data buffer\r
-  @param  DataToggle           On input, the initial data toggle for the transfer;\r
-                               On output, it is updated to to next data toggle to\r
-                               use                        of the subsequent bulk\r
-                               transfer.\r
-  @param  Translator           A pointr to the transaction translator data.\r
-  @param  TimeOut              Indicates the maximum time, in millisecond, which\r
-                               the transfer is allowed to complete.\r
-  @param  TransferResult       A pointer to the detailed result information of the\r
-                               bulk transfer.\r
-\r
-  @return EFI_SUCCESS           : The transfer was completed successfully.\r
-  @return EFI_OUT_OF_RESOURCES  : The transfer failed due to lack of resource.\r
-  @return EFI_INVALID_PARAMETER : Some parameters are invalid.\r
-  @return EFI_TIMEOUT           : The transfer failed due to timeout.\r
-  @return EFI_DEVICE_ERROR      : The transfer failed due to host controller error.\r
+  @param  DataLength            The lenght of the data buffer.\r
+  @param  DataToggle            On input, the initial data toggle for the transfer;\r
+                                On output, it is updated to to next data toggle to\r
+                                use of the subsequent bulk transfer.\r
+  @param  TimeOut               Indicates the maximum time, in millisecond, which\r
+                                the transfer is allowed to complete.\r
+  @param  Translator            A pointr to the transaction translator data.\r
+  @param  TransferResult        A pointer to the detailed result information of the\r
+                                bulk transfer.\r
+\r
+  @retval EFI_SUCCESS           The transfer was completed successfully.\r
+  @retval EFI_OUT_OF_RESOURCES  The transfer failed due to lack of resource.\r
+  @retval EFI_INVALID_PARAMETER Some parameters are invalid.\r
+  @retval EFI_TIMEOUT           The transfer failed due to timeout.\r
+  @retval EFI_DEVICE_ERROR      The transfer failed due to host controller error.\r
 \r
 **/\r
-STATIC\r
 EFI_STATUS\r
 EFIAPI\r
 EhcBulkTransfer (\r
@@ -821,16 +844,18 @@ EhcBulkTransfer (
   OUT UINT32                              *TransferResult\r
   )\r
 {\r
-  USB2_HC_DEV             *Ehc;\r
-  URB                     *Urb;\r
-  EFI_TPL                 OldTpl;\r
-  EFI_STATUS              Status;\r
+  USB2_HC_DEV  *Ehc;\r
+  URB          *Urb;\r
+  EFI_TPL      OldTpl;\r
+  EFI_STATUS   Status;\r
+  UINTN        DebugErrorLevel;\r
 \r
   //\r
   // Validate the parameters\r
   //\r
   if ((DataLength == NULL) || (*DataLength == 0) ||\r
-      (Data == NULL) || (Data[0] == NULL) || (TransferResult == NULL)) {\r
+      (Data == NULL) || (Data[0] == NULL) || (TransferResult == NULL))\r
+  {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
@@ -840,18 +865,19 @@ EhcBulkTransfer (
 \r
   if ((DeviceSpeed == EFI_USB_SPEED_LOW) ||\r
       ((DeviceSpeed == EFI_USB_SPEED_FULL) && (MaximumPacketLength > 64)) ||\r
-      ((EFI_USB_SPEED_HIGH == DeviceSpeed) && (MaximumPacketLength > 512))) {\r
+      ((EFI_USB_SPEED_HIGH == DeviceSpeed) && (MaximumPacketLength > 512)))\r
+  {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
-  OldTpl          = gBS->RaiseTPL (EHC_TPL);\r
-  Ehc             = EHC_FROM_THIS (This);\r
+  OldTpl = gBS->RaiseTPL (EHC_TPL);\r
+  Ehc    = EHC_FROM_THIS (This);\r
 \r
   *TransferResult = EFI_USB_ERR_SYSTEM;\r
   Status          = EFI_DEVICE_ERROR;\r
 \r
   if (EhcIsHalt (Ehc) || EhcIsSysError (Ehc)) {\r
-    DEBUG ((EFI_D_ERROR, "EhcBulkTransfer: HC is halted\n"));\r
+    DEBUG ((DEBUG_ERROR, "EhcBulkTransfer: HC is halted\n"));\r
 \r
     EhcAckAllInterrupt (Ehc);\r
     goto ON_EXIT;\r
@@ -881,7 +907,7 @@ EhcBulkTransfer (
           );\r
 \r
   if (Urb == NULL) {\r
-    DEBUG ((EFI_D_ERROR, "EhcBulkTransfer: failed to create URB\n"));\r
+    DEBUG ((DEBUG_ERROR, "EhcBulkTransfer: failed to create URB\n"));\r
 \r
     Status = EFI_OUT_OF_RESOURCES;\r
     goto ON_EXIT;\r
@@ -907,65 +933,68 @@ ON_EXIT:
   gBS->RestoreTPL (OldTpl);\r
 \r
   if (EFI_ERROR (Status)) {\r
-    DEBUG ((EFI_D_ERROR, "EhcBulkTransfer: error - %r, transfer - %x\n", Status, *TransferResult));\r
+    if (Status == EFI_TIMEOUT) {\r
+      DebugErrorLevel = DEBUG_VERBOSE;\r
+    } else {\r
+      DebugErrorLevel = DEBUG_ERROR;\r
+    }\r
+\r
+    DEBUG ((DebugErrorLevel, "EhcBulkTransfer: error - %r, transfer - %x\n", Status, *TransferResult));\r
   }\r
 \r
   return Status;\r
 }\r
 \r
-\r
 /**\r
   Submits an asynchronous interrupt transfer to an\r
   interrupt endpoint of a USB device.\r
 \r
-  @param  This                 This EFI_USB2_HC_PROTOCOL instance.\r
-  @param  DeviceAddress        Target device address\r
-  @param  EndPointAddress      Endpoint number and its direction encoded in bit 7\r
-  @param  DeviceSpeed          Indicates device speed.\r
-  @param  MaximumPacketLength  Maximum packet size the target endpoint is capable\r
-  @param  IsNewTransfer        If TRUE, to submit an new asynchronous interrupt\r
-                               transfer If FALSE, to remove the specified\r
-                               asynchronous interrupt\r
-  @param  DataToggle           On input, the initial data toggle to use; on output,\r
-                               it is updated to indicate the next data toggle\r
-  @param  PollingInterval      The he interval, in milliseconds, that the transfer\r
-                               is polled.\r
-  @param  DataLength           The length of data to receive at the rate specified\r
-                               by  PollingInterval.\r
-  @param  Translator           Transaction translator to use.\r
-  @param  CallBackFunction     Function to call at the rate specified by\r
-                               PollingInterval\r
-  @param  Context              Context to CallBackFunction.\r
-\r
-  @return EFI_SUCCESS           : The request has been successfully submitted or canceled.\r
-  @return EFI_INVALID_PARAMETER : Some parameters are invalid.\r
-  @return EFI_OUT_OF_RESOURCES  : The request failed due to a lack of resources.\r
-  @return EFI_DEVICE_ERROR      : The transfer failed due to host controller error.\r
+  @param  This                  This EFI_USB2_HC_PROTOCOL instance.\r
+  @param  DeviceAddress         Target device address.\r
+  @param  EndPointAddress       Endpoint number and its direction encoded in bit 7\r
+  @param  DeviceSpeed           Indicates device speed.\r
+  @param  MaximumPacketLength   Maximum packet size the target endpoint is capable\r
+  @param  IsNewTransfer         If TRUE, to submit an new asynchronous interrupt\r
+                                transfer If FALSE, to remove the specified\r
+                                asynchronous interrupt.\r
+  @param  DataToggle            On input, the initial data toggle to use; on output,\r
+                                it is updated to indicate the next data toggle.\r
+  @param  PollingInterval       The he interval, in milliseconds, that the transfer\r
+                                is polled.\r
+  @param  DataLength            The length of data to receive at the rate specified\r
+                                by  PollingInterval.\r
+  @param  Translator            Transaction translator to use.\r
+  @param  CallBackFunction      Function to call at the rate specified by\r
+                                PollingInterval.\r
+  @param  Context               Context to CallBackFunction.\r
+\r
+  @retval EFI_SUCCESS           The request has been successfully submitted or canceled.\r
+  @retval EFI_INVALID_PARAMETER Some parameters are invalid.\r
+  @retval EFI_OUT_OF_RESOURCES  The request failed due to a lack of resources.\r
+  @retval EFI_DEVICE_ERROR      The transfer failed due to host controller error.\r
 \r
 **/\r
-STATIC\r
 EFI_STATUS\r
 EFIAPI\r
 EhcAsyncInterruptTransfer (\r
-  IN  EFI_USB2_HC_PROTOCOL                  * This,\r
-  IN  UINT8                                 DeviceAddress,\r
-  IN  UINT8                                 EndPointAddress,\r
-  IN  UINT8                                 DeviceSpeed,\r
-  IN  UINTN                                 MaximumPacketLength,\r
-  IN  BOOLEAN                               IsNewTransfer,\r
-  IN  OUT UINT8                             *DataToggle,\r
-  IN  UINTN                                 PollingInterval,\r
-  IN  UINTN                                 DataLength,\r
-  IN  EFI_USB2_HC_TRANSACTION_TRANSLATOR    * Translator,\r
-  IN  EFI_ASYNC_USB_TRANSFER_CALLBACK       CallBackFunction,\r
-  IN  VOID                                  *Context OPTIONAL\r
+  IN  EFI_USB2_HC_PROTOCOL                *This,\r
+  IN  UINT8                               DeviceAddress,\r
+  IN  UINT8                               EndPointAddress,\r
+  IN  UINT8                               DeviceSpeed,\r
+  IN  UINTN                               MaximumPacketLength,\r
+  IN  BOOLEAN                             IsNewTransfer,\r
+  IN  OUT UINT8                           *DataToggle,\r
+  IN  UINTN                               PollingInterval,\r
+  IN  UINTN                               DataLength,\r
+  IN  EFI_USB2_HC_TRANSACTION_TRANSLATOR  *Translator,\r
+  IN  EFI_ASYNC_USB_TRANSFER_CALLBACK     CallBackFunction,\r
+  IN  VOID                                *Context OPTIONAL\r
   )\r
 {\r
-  USB2_HC_DEV             *Ehc;\r
-  URB                     *Urb;\r
-  EFI_TPL                 OldTpl;\r
-  EFI_STATUS              Status;\r
-  UINT8                   *Data;\r
+  USB2_HC_DEV  *Ehc;\r
+  URB          *Urb;\r
+  EFI_TPL      OldTpl;\r
+  EFI_STATUS   Status;\r
 \r
   //\r
   // Validate parameters\r
@@ -988,8 +1017,8 @@ EhcAsyncInterruptTransfer (
     }\r
   }\r
 \r
-  OldTpl  = gBS->RaiseTPL (EHC_TPL);\r
-  Ehc     = EHC_FROM_THIS (This);\r
+  OldTpl = gBS->RaiseTPL (EHC_TPL);\r
+  Ehc    = EHC_FROM_THIS (This);\r
 \r
   //\r
   // Delete Async interrupt transfer request. DataToggle will return\r
@@ -998,14 +1027,14 @@ EhcAsyncInterruptTransfer (
   if (!IsNewTransfer) {\r
     Status = EhciDelAsyncIntTransfer (Ehc, DeviceAddress, EndPointAddress, DataToggle);\r
 \r
-    DEBUG ((EFI_D_INFO, "EhcAsyncInterruptTransfer: remove old transfer - %r\n", Status));\r
+    DEBUG ((DEBUG_INFO, "EhcAsyncInterruptTransfer: remove old transfer - %r\n", Status));\r
     goto ON_EXIT;\r
   }\r
 \r
   Status = EFI_SUCCESS;\r
 \r
   if (EhcIsHalt (Ehc) || EhcIsSysError (Ehc)) {\r
-    DEBUG ((EFI_D_ERROR, "EhcAsyncInterruptTransfer: HC is halt\n"));\r
+    DEBUG ((DEBUG_ERROR, "EhcAsyncInterruptTransfer: HC is halt\n"));\r
     EhcAckAllInterrupt (Ehc);\r
 \r
     Status = EFI_DEVICE_ERROR;\r
@@ -1014,16 +1043,7 @@ EhcAsyncInterruptTransfer (
 \r
   EhcAckAllInterrupt (Ehc);\r
 \r
-  Data = AllocatePool (DataLength);\r
-\r
-  if (Data == NULL) {\r
-    DEBUG ((EFI_D_ERROR, "EhcAsyncInterruptTransfer: failed to allocate buffer\n"));\r
-\r
-    Status = EFI_OUT_OF_RESOURCES;\r
-    goto ON_EXIT;\r
-  }\r
-\r
-  Urb = EhcCreateUrb (\r
+  Urb = EhciInsertAsyncIntTransfer (\r
           Ehc,\r
           DeviceAddress,\r
           EndPointAddress,\r
@@ -1031,9 +1051,6 @@ EhcAsyncInterruptTransfer (
           *DataToggle,\r
           MaximumPacketLength,\r
           Translator,\r
-          EHC_INT_TRANSFER_ASYNC,\r
-          NULL,\r
-          Data,\r
           DataLength,\r
           CallBackFunction,\r
           Context,\r
@@ -1041,20 +1058,10 @@ EhcAsyncInterruptTransfer (
           );\r
 \r
   if (Urb == NULL) {\r
-    DEBUG ((EFI_D_ERROR, "EhcAsyncInterruptTransfer: failed to create URB\n"));\r
-\r
-    gBS->FreePool (Data);\r
     Status = EFI_OUT_OF_RESOURCES;\r
     goto ON_EXIT;\r
   }\r
 \r
-  //\r
-  // New asynchronous transfer must inserted to the head.\r
-  // Check the comments in EhcMoniteAsyncRequests\r
-  //\r
-  EhcLinkQhToPeriod (Ehc, Urb->Qh);\r
-  InsertHeadList (&Ehc->AsyncIntTransfers, &Urb->UrbList);\r
-\r
 ON_EXIT:\r
   Ehc->PciIo->Flush (Ehc->PciIo);\r
   gBS->RestoreTPL (OldTpl);\r
@@ -1062,35 +1069,33 @@ ON_EXIT:
   return Status;\r
 }\r
 \r
-\r
 /**\r
   Submits synchronous interrupt transfer to an interrupt endpoint\r
   of a USB device.\r
 \r
-  @param  This                 This EFI_USB2_HC_PROTOCOL instance.\r
-  @param  DeviceAddress        Target device address\r
-  @param  EndPointAddress      Endpoint number and its direction encoded in bit 7\r
-  @param  DeviceSpeed          Indicates device speed.\r
-  @param  MaximumPacketLength  Maximum packet size the target endpoint is capable\r
-                               of sending or receiving.\r
-  @param  Data                 Buffer of data that will be transmitted to  USB\r
-                               device or received from USB device.\r
-  @param  DataLength           On input, the size, in bytes, of the data buffer; On\r
-                               output, the number of bytes transferred.\r
-  @param  DataToggle           On input, the initial data toggle to use; on output,\r
-                               it is updated to indicate the next data toggle\r
-  @param  TimeOut              Maximum time, in second, to complete\r
-  @param  Translator           Transaction translator to use.\r
-  @param  TransferResult       Variable to receive the transfer result\r
-\r
-  @return EFI_SUCCESS           The transfer was completed successfully.\r
-  @return EFI_OUT_OF_RESOURCES  The transfer failed due to lack of resource.\r
-  @return EFI_INVALID_PARAMETER Some parameters are invalid.\r
-  @return EFI_TIMEOUT           The transfer failed due to timeout.\r
-  @return EFI_DEVICE_ERROR      The failed due to host controller or device error\r
+  @param  This                  This EFI_USB2_HC_PROTOCOL instance.\r
+  @param  DeviceAddress         Target device address.\r
+  @param  EndPointAddress       Endpoint number and its direction encoded in bit 7\r
+  @param  DeviceSpeed           Indicates device speed.\r
+  @param  MaximumPacketLength   Maximum packet size the target endpoint is capable\r
+                                of sending or receiving.\r
+  @param  Data                  Buffer of data that will be transmitted to  USB\r
+                                device or received from USB device.\r
+  @param  DataLength            On input, the size, in bytes, of the data buffer; On\r
+                                output, the number of bytes transferred.\r
+  @param  DataToggle            On input, the initial data toggle to use; on output,\r
+                                it is updated to indicate the next data toggle.\r
+  @param  TimeOut               Maximum time, in second, to complete.\r
+  @param  Translator            Transaction translator to use.\r
+  @param  TransferResult        Variable to receive the transfer result.\r
+\r
+  @return EFI_SUCCESS           The transfer was completed successfully.\r
+  @return EFI_OUT_OF_RESOURCES  The transfer failed due to lack of resource.\r
+  @return EFI_INVALID_PARAMETER Some parameters are invalid.\r
+  @return EFI_TIMEOUT           The transfer failed due to timeout.\r
+  @return EFI_DEVICE_ERROR      The failed due to host controller or device error\r
 \r
 **/\r
-STATIC\r
 EFI_STATUS\r
 EFIAPI\r
 EhcSyncInterruptTransfer (\r
@@ -1107,20 +1112,17 @@ EhcSyncInterruptTransfer (
   OUT UINT32                              *TransferResult\r
   )\r
 {\r
-  USB2_HC_DEV             *Ehc;\r
-  EFI_TPL                 OldTpl;\r
-  URB                     *Urb;\r
-  EFI_STATUS              Status;\r
+  USB2_HC_DEV  *Ehc;\r
+  EFI_TPL      OldTpl;\r
+  URB          *Urb;\r
+  EFI_STATUS   Status;\r
 \r
   //\r
   // Validates parameters\r
   //\r
   if ((DataLength == NULL) || (*DataLength == 0) ||\r
-      (Data == NULL) || (TransferResult == NULL)) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  if (!EHCI_IS_DATAIN (EndPointAddress)) {\r
+      (Data == NULL) || (TransferResult == NULL))\r
+  {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
@@ -1130,18 +1132,19 @@ EhcSyncInterruptTransfer (
 \r
   if (((DeviceSpeed == EFI_USB_SPEED_LOW) && (MaximumPacketLength != 8))  ||\r
       ((DeviceSpeed == EFI_USB_SPEED_FULL) && (MaximumPacketLength > 64)) ||\r
-      ((DeviceSpeed == EFI_USB_SPEED_HIGH) && (MaximumPacketLength > 3072))) {\r
+      ((DeviceSpeed == EFI_USB_SPEED_HIGH) && (MaximumPacketLength > 3072)))\r
+  {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
-  OldTpl          = gBS->RaiseTPL (EHC_TPL);\r
-  Ehc             = EHC_FROM_THIS (This);\r
+  OldTpl = gBS->RaiseTPL (EHC_TPL);\r
+  Ehc    = EHC_FROM_THIS (This);\r
 \r
   *TransferResult = EFI_USB_ERR_SYSTEM;\r
   Status          = EFI_DEVICE_ERROR;\r
 \r
   if (EhcIsHalt (Ehc) || EhcIsSysError (Ehc)) {\r
-    DEBUG ((EFI_D_ERROR, "EhcSyncInterruptTransfer: HC is halt\n"));\r
+    DEBUG ((DEBUG_ERROR, "EhcSyncInterruptTransfer: HC is halt\n"));\r
 \r
     EhcAckAllInterrupt (Ehc);\r
     goto ON_EXIT;\r
@@ -1167,7 +1170,7 @@ EhcSyncInterruptTransfer (
           );\r
 \r
   if (Urb == NULL) {\r
-    DEBUG ((EFI_D_ERROR, "EhcSyncInterruptTransfer: failed to create URB\n"));\r
+    DEBUG ((DEBUG_ERROR, "EhcSyncInterruptTransfer: failed to create URB\n"));\r
 \r
     Status = EFI_OUT_OF_RESOURCES;\r
     goto ON_EXIT;\r
@@ -1185,24 +1188,24 @@ EhcSyncInterruptTransfer (
     Status = EFI_SUCCESS;\r
   }\r
 \r
+  EhcFreeUrb (Ehc, Urb);\r
 ON_EXIT:\r
   Ehc->PciIo->Flush (Ehc->PciIo);\r
   gBS->RestoreTPL (OldTpl);\r
 \r
   if (EFI_ERROR (Status)) {\r
-    DEBUG ((EFI_D_ERROR, "EhcSyncInterruptTransfer: error - %r, transfer - %x\n", Status, *TransferResult));\r
+    DEBUG ((DEBUG_ERROR, "EhcSyncInterruptTransfer: error - %r, transfer - %x\n", Status, *TransferResult));\r
   }\r
 \r
   return Status;\r
 }\r
 \r
-\r
 /**\r
   Submits isochronous transfer to a target USB device.\r
 \r
   @param  This                 This EFI_USB2_HC_PROTOCOL instance.\r
-  @param  DeviceAddress        Target device address\r
-  @param  EndPointAddress      End point address with its direction\r
+  @param  DeviceAddress        Target device address.\r
+  @param  EndPointAddress      End point address with its direction.\r
   @param  DeviceSpeed          Device speed, Low speed device doesn't support this\r
                                type.\r
   @param  MaximumPacketLength  Maximum packet size that the endpoint is capable of\r
@@ -1211,14 +1214,13 @@ ON_EXIT:
   @param  Data                 Array of pointers to the buffers of data that will\r
                                be transmitted to USB device or received from USB\r
                                device.\r
-  @param  DataLength           The size, in bytes, of the data buffer\r
+  @param  DataLength           The size, in bytes, of the data buffer.\r
   @param  Translator           Transaction translator to use.\r
-  @param  TransferResult       Variable to receive the transfer result\r
+  @param  TransferResult       Variable to receive the transfer result.\r
 \r
-  @return EFI_UNSUPPORTED : Isochronous transfer is unsupported.\r
+  @return EFI_UNSUPPORTED      Isochronous transfer is unsupported.\r
 \r
 **/\r
-STATIC\r
 EFI_STATUS\r
 EFIAPI\r
 EhcIsochronousTransfer (\r
@@ -1237,13 +1239,12 @@ EhcIsochronousTransfer (
   return EFI_UNSUPPORTED;\r
 }\r
 \r
-\r
 /**\r
   Submits Async isochronous transfer to a target USB device.\r
 \r
   @param  This                 This EFI_USB2_HC_PROTOCOL instance.\r
-  @param  DeviceAddress        Target device address\r
-  @param  EndPointAddress      End point address with its direction\r
+  @param  DeviceAddress        Target device address.\r
+  @param  EndPointAddress      End point address with its direction.\r
   @param  DeviceSpeed          Device speed, Low speed device doesn't support this\r
                                type.\r
   @param  MaximumPacketLength  Maximum packet size that the endpoint is capable of\r
@@ -1252,16 +1253,15 @@ EhcIsochronousTransfer (
   @param  Data                 Array of pointers to the buffers of data that will\r
                                be transmitted to USB device or received from USB\r
                                device.\r
-  @param  DataLength           The size, in bytes, of the data buffer\r
+  @param  DataLength           The size, in bytes, of the data buffer.\r
   @param  Translator           Transaction translator to use.\r
-  @param  IsochronousCallBack  Function to be called when the transfer complete\r
+  @param  IsochronousCallBack  Function to be called when the transfer complete.\r
   @param  Context              Context passed to the call back function as\r
-                               parameter\r
+                               parameter.\r
 \r
-  @return EFI_UNSUPPORTED : Isochronous transfer isn't supported\r
+  @return EFI_UNSUPPORTED      Isochronous transfer isn't supported.\r
 \r
 **/\r
-STATIC\r
 EFI_STATUS\r
 EFIAPI\r
 EhcAsyncIsochronousTransfer (\r
@@ -1281,29 +1281,22 @@ EhcAsyncIsochronousTransfer (
   return EFI_UNSUPPORTED;\r
 }\r
 \r
-EFI_STATUS\r
-EFIAPI\r
-EhcDriverEntryPoint (\r
-  IN EFI_HANDLE           ImageHandle,\r
-  IN EFI_SYSTEM_TABLE     *SystemTable\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
-\r
+/**\r
   Entry point for EFI drivers.\r
 \r
-Arguments:\r
-\r
-  ImageHandle - EFI_HANDLE\r
-  SystemTable - EFI_SYSTEM_TABLE\r
+  @param  ImageHandle       EFI_HANDLE.\r
+  @param  SystemTable       EFI_SYSTEM_TABLE.\r
 \r
-Returns:\r
+  @return EFI_SUCCESS       Success.\r
+          EFI_DEVICE_ERROR  Fail.\r
 \r
-  EFI_SUCCESS         Success\r
-  EFI_DEVICE_ERROR    Fail\r
-\r
---*/\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+EhcDriverEntryPoint (\r
+  IN EFI_HANDLE        ImageHandle,\r
+  IN EFI_SYSTEM_TABLE  *SystemTable\r
+  )\r
 {\r
   return EfiLibInstallDriverBindingComponentName2 (\r
            ImageHandle,\r
@@ -1315,31 +1308,30 @@ Returns:
            );\r
 }\r
 \r
-\r
 /**\r
   Test to see if this driver supports ControllerHandle. Any\r
   ControllerHandle that has Usb2HcProtocol installed will\r
   be supported.\r
 \r
   @param  This                 Protocol instance pointer.\r
-  @param  Controlle            Handle of device to test\r
-  @param  RemainingDevicePath  Not used\r
+  @param  Controller           Handle of device to test.\r
+  @param  RemainingDevicePath  Not used.\r
 \r
-  @return EFI_SUCCESS         : This driver supports this device.\r
-  @return EFI_UNSUPPORTED     : This driver does not support this device.\r
+  @return EFI_SUCCESS          This driver supports this device.\r
+  @return EFI_UNSUPPORTED      This driver does not support this device.\r
 \r
 **/\r
 EFI_STATUS\r
 EFIAPI\r
 EhcDriverBindingSupported (\r
-  IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
-  IN EFI_HANDLE                  Controller,\r
-  IN EFI_DEVICE_PATH_PROTOCOL    *RemainingDevicePath\r
+  IN EFI_DRIVER_BINDING_PROTOCOL  *This,\r
+  IN EFI_HANDLE                   Controller,\r
+  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath\r
   )\r
 {\r
-  EFI_STATUS              Status;\r
-  EFI_PCI_IO_PROTOCOL     *PciIo;\r
-  USB_CLASSC              UsbClassCReg;\r
+  EFI_STATUS           Status;\r
+  EFI_PCI_IO_PROTOCOL  *PciIo;\r
+  USB_CLASSC           UsbClassCReg;\r
 \r
   //\r
   // Test whether there is PCI IO Protocol attached on the controller handle.\r
@@ -1347,7 +1339,7 @@ EhcDriverBindingSupported (
   Status = gBS->OpenProtocol (\r
                   Controller,\r
                   &gEfiPciIoProtocolGuid,\r
-                  (VOID **) &PciIo,\r
+                  (VOID **)&PciIo,\r
                   This->DriverBindingHandle,\r
                   Controller,\r
                   EFI_OPEN_PROTOCOL_BY_DRIVER\r
@@ -1360,7 +1352,7 @@ EhcDriverBindingSupported (
   Status = PciIo->Pci.Read (\r
                         PciIo,\r
                         EfiPciIoWidthUint8,\r
-                        EHC_PCI_CLASSC,\r
+                        PCI_CLASSCODE_OFFSET,\r
                         sizeof (USB_CLASSC) / sizeof (UINT8),\r
                         &UsbClassCReg\r
                         );\r
@@ -1373,10 +1365,9 @@ EhcDriverBindingSupported (
   //\r
   // Test whether the controller belongs to Ehci type\r
   //\r
-  if ((UsbClassCReg.BaseCode     != PCI_CLASS_SERIAL) ||\r
-      (UsbClassCReg.SubClassCode != PCI_CLASS_SERIAL_USB) ||\r
-      (UsbClassCReg.PI           != EHC_PCI_CLASSC_PI)) {\r
-\r
+  if (  (UsbClassCReg.BaseCode != PCI_CLASS_SERIAL) || (UsbClassCReg.SubClassCode != PCI_CLASS_SERIAL_USB)\r
+     || ((UsbClassCReg.ProgInterface != PCI_IF_EHCI) && (UsbClassCReg.ProgInterface != PCI_IF_UHCI) && (UsbClassCReg.ProgInterface != PCI_IF_OHCI)))\r
+  {\r
     Status = EFI_UNSUPPORTED;\r
   }\r
 \r
@@ -1391,26 +1382,149 @@ ON_EXIT:
   return Status;\r
 }\r
 \r
+/**\r
+  Get the usb debug port related information.\r
+\r
+  @param  Ehc                The EHCI device.\r
+\r
+  @retval RETURN_SUCCESS     Get debug port number, bar and offset successfully.\r
+  @retval Others             The usb host controller does not supported usb debug port capability.\r
+\r
+**/\r
+EFI_STATUS\r
+EhcGetUsbDebugPortInfo (\r
+  IN  USB2_HC_DEV  *Ehc\r
+  )\r
+{\r
+  EFI_PCI_IO_PROTOCOL  *PciIo;\r
+  UINT16               PciStatus;\r
+  UINT8                CapabilityPtr;\r
+  UINT8                CapabilityId;\r
+  UINT16               DebugPort;\r
+  EFI_STATUS           Status;\r
+\r
+  ASSERT (Ehc->PciIo != NULL);\r
+  PciIo = Ehc->PciIo;\r
+\r
+  //\r
+  // Detect if the EHCI host controller support Capaility Pointer.\r
+  //\r
+  Status = PciIo->Pci.Read (\r
+                        PciIo,\r
+                        EfiPciIoWidthUint8,\r
+                        PCI_PRIMARY_STATUS_OFFSET,\r
+                        sizeof (UINT16),\r
+                        &PciStatus\r
+                        );\r
+\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  if ((PciStatus & EFI_PCI_STATUS_CAPABILITY) == 0) {\r
+    //\r
+    // The Pci Device Doesn't Support Capability Pointer.\r
+    //\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  //\r
+  // Get Pointer To Capability List\r
+  //\r
+  Status = PciIo->Pci.Read (\r
+                        PciIo,\r
+                        EfiPciIoWidthUint8,\r
+                        PCI_CAPBILITY_POINTER_OFFSET,\r
+                        1,\r
+                        &CapabilityPtr\r
+                        );\r
+\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  //\r
+  // Find Capability ID 0xA, Which Is For Debug Port\r
+  //\r
+  while (CapabilityPtr != 0) {\r
+    Status = PciIo->Pci.Read (\r
+                          PciIo,\r
+                          EfiPciIoWidthUint8,\r
+                          CapabilityPtr,\r
+                          1,\r
+                          &CapabilityId\r
+                          );\r
+\r
+    if (EFI_ERROR (Status)) {\r
+      return Status;\r
+    }\r
+\r
+    if (CapabilityId == EHC_DEBUG_PORT_CAP_ID) {\r
+      break;\r
+    }\r
+\r
+    Status = PciIo->Pci.Read (\r
+                          PciIo,\r
+                          EfiPciIoWidthUint8,\r
+                          CapabilityPtr + 1,\r
+                          1,\r
+                          &CapabilityPtr\r
+                          );\r
+\r
+    if (EFI_ERROR (Status)) {\r
+      return Status;\r
+    }\r
+  }\r
+\r
+  //\r
+  // No Debug Port Capability Found\r
+  //\r
+  if (CapabilityPtr == 0) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  //\r
+  // Get The Base Address Of Debug Port Register In Debug Port Capability Register\r
+  //\r
+  Status = PciIo->Pci.Read (\r
+                        Ehc->PciIo,\r
+                        EfiPciIoWidthUint8,\r
+                        CapabilityPtr + 2,\r
+                        sizeof (UINT16),\r
+                        &DebugPort\r
+                        );\r
+\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  Ehc->DebugPortOffset = DebugPort & 0x1FFF;\r
+  Ehc->DebugPortBarNum = (UINT8)((DebugPort >> 13) - 1);\r
+  Ehc->DebugPortNum    = (UINT8)((Ehc->HcStructParams & 0x00F00000) >> 20);\r
+\r
+  return EFI_SUCCESS;\r
+}\r
 \r
 /**\r
-  Create and initialize a USB2_HC_DEV\r
+  Create and initialize a USB2_HC_DEV.\r
 \r
-  @param  PciIo                  The PciIo on this device\r
-  @param  OriginalPciAttributes  Original PCI attributes\r
+  @param  PciIo                  The PciIo on this device.\r
+  @param  DevicePath             The device path of host controller.\r
+  @param  OriginalPciAttributes  Original PCI attributes.\r
 \r
-  @return The allocated and initialized USB2_HC_DEV structure\r
-  @return if created, otherwise NULL.\r
+  @return  The allocated and initialized USB2_HC_DEV structure if created,\r
+           otherwise NULL.\r
 \r
 **/\r
-STATIC\r
 USB2_HC_DEV *\r
 EhcCreateUsb2Hc (\r
-  IN EFI_PCI_IO_PROTOCOL  *PciIo,\r
-  IN UINT64               OriginalPciAttributes\r
+  IN EFI_PCI_IO_PROTOCOL       *PciIo,\r
+  IN EFI_DEVICE_PATH_PROTOCOL  *DevicePath,\r
+  IN UINT64                    OriginalPciAttributes\r
   )\r
 {\r
-  USB2_HC_DEV             *Ehc;\r
-  EFI_STATUS              Status;\r
+  USB2_HC_DEV  *Ehc;\r
+  EFI_STATUS   Status;\r
 \r
   Ehc = AllocateZeroPool (sizeof (USB2_HC_DEV));\r
 \r
@@ -1421,25 +1535,26 @@ EhcCreateUsb2Hc (
   //\r
   // Init EFI_USB2_HC_PROTOCOL interface and private data structure\r
   //\r
-  Ehc->Signature                        = USB2_HC_DEV_SIGNATURE;\r
-\r
-  Ehc->Usb2Hc.GetCapability             = EhcGetCapability;\r
-  Ehc->Usb2Hc.Reset                     = EhcReset;\r
-  Ehc->Usb2Hc.GetState                  = EhcGetState;\r
-  Ehc->Usb2Hc.SetState                  = EhcSetState;\r
-  Ehc->Usb2Hc.ControlTransfer           = EhcControlTransfer;\r
-  Ehc->Usb2Hc.BulkTransfer              = EhcBulkTransfer;\r
-  Ehc->Usb2Hc.AsyncInterruptTransfer    = EhcAsyncInterruptTransfer;\r
-  Ehc->Usb2Hc.SyncInterruptTransfer     = EhcSyncInterruptTransfer;\r
-  Ehc->Usb2Hc.IsochronousTransfer       = EhcIsochronousTransfer;\r
-  Ehc->Usb2Hc.AsyncIsochronousTransfer  = EhcAsyncIsochronousTransfer;\r
-  Ehc->Usb2Hc.GetRootHubPortStatus      = EhcGetRootHubPortStatus;\r
-  Ehc->Usb2Hc.SetRootHubPortFeature     = EhcSetRootHubPortFeature;\r
-  Ehc->Usb2Hc.ClearRootHubPortFeature   = EhcClearRootHubPortFeature;\r
-  Ehc->Usb2Hc.MajorRevision             = 0x1;\r
-  Ehc->Usb2Hc.MinorRevision             = 0x1;\r
+  Ehc->Signature = USB2_HC_DEV_SIGNATURE;\r
+\r
+  Ehc->Usb2Hc.GetCapability            = EhcGetCapability;\r
+  Ehc->Usb2Hc.Reset                    = EhcReset;\r
+  Ehc->Usb2Hc.GetState                 = EhcGetState;\r
+  Ehc->Usb2Hc.SetState                 = EhcSetState;\r
+  Ehc->Usb2Hc.ControlTransfer          = EhcControlTransfer;\r
+  Ehc->Usb2Hc.BulkTransfer             = EhcBulkTransfer;\r
+  Ehc->Usb2Hc.AsyncInterruptTransfer   = EhcAsyncInterruptTransfer;\r
+  Ehc->Usb2Hc.SyncInterruptTransfer    = EhcSyncInterruptTransfer;\r
+  Ehc->Usb2Hc.IsochronousTransfer      = EhcIsochronousTransfer;\r
+  Ehc->Usb2Hc.AsyncIsochronousTransfer = EhcAsyncIsochronousTransfer;\r
+  Ehc->Usb2Hc.GetRootHubPortStatus     = EhcGetRootHubPortStatus;\r
+  Ehc->Usb2Hc.SetRootHubPortFeature    = EhcSetRootHubPortFeature;\r
+  Ehc->Usb2Hc.ClearRootHubPortFeature  = EhcClearRootHubPortFeature;\r
+  Ehc->Usb2Hc.MajorRevision            = 0x2;\r
+  Ehc->Usb2Hc.MinorRevision            = 0x0;\r
 \r
   Ehc->PciIo                 = PciIo;\r
+  Ehc->DevicePath            = DevicePath;\r
   Ehc->OriginalPciAttributes = OriginalPciAttributes;\r
 \r
   InitializeListHead (&Ehc->AsyncIntTransfers);\r
@@ -1448,15 +1563,25 @@ EhcCreateUsb2Hc (
   Ehc->HcCapParams    = EhcReadCapRegister (Ehc, EHC_HCCPARAMS_OFFSET);\r
   Ehc->CapLen         = EhcReadCapRegister (Ehc, EHC_CAPLENGTH_OFFSET) & 0x0FF;\r
 \r
-  DEBUG ((EFI_D_INFO, "EhcCreateUsb2Hc: capability length %d\n", Ehc->CapLen));\r
+  DEBUG ((DEBUG_INFO, "EhcCreateUsb2Hc: capability length %d\n", Ehc->CapLen));\r
+\r
+  //\r
+  // EHCI Controllers with a CapLen of 0 are ignored.\r
+  //\r
+  if (Ehc->CapLen == 0) {\r
+    gBS->FreePool (Ehc);\r
+    return NULL;\r
+  }\r
+\r
+  EhcGetUsbDebugPortInfo (Ehc);\r
 \r
   //\r
   // Create AsyncRequest Polling Timer\r
   //\r
   Status = gBS->CreateEvent (\r
                   EVT_TIMER | EVT_NOTIFY_SIGNAL,\r
-                  TPL_CALLBACK,\r
-                  EhcMoniteAsyncRequests,\r
+                  TPL_NOTIFY,\r
+                  EhcMonitorAsyncRequests,\r
                   Ehc,\r
                   &Ehc->PollTimer\r
                   );\r
@@ -1469,34 +1594,72 @@ EhcCreateUsb2Hc (
   return Ehc;\r
 }\r
 \r
+/**\r
+  One notified function to stop the Host Controller when gBS->ExitBootServices() called.\r
+\r
+  @param  Event                   Pointer to this event\r
+  @param  Context                 Event handler private data\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+EhcExitBootService (\r
+  EFI_EVENT  Event,\r
+  VOID       *Context\r
+  )\r
+\r
+{\r
+  USB2_HC_DEV  *Ehc;\r
+\r
+  Ehc = (USB2_HC_DEV *)Context;\r
+\r
+  //\r
+  // Reset the Host Controller\r
+  //\r
+  EhcResetHC (Ehc, EHC_RESET_TIMEOUT);\r
+}\r
 \r
 /**\r
-  Starting the Usb EHCI Driver\r
+  Starting the Usb EHCI Driver.\r
 \r
   @param  This                 Protocol instance pointer.\r
-  @param  Controller           Handle of device to test\r
-  @param  RemainingDevicePath  Not used\r
+  @param  Controller           Handle of device to test.\r
+  @param  RemainingDevicePath  Not used.\r
 \r
-  @return EFI_SUCCESS          supports this device.\r
-  @return EFI_UNSUPPORTED      do not support this device.\r
-  @return EFI_DEVICE_ERROR     : cannot be started due to device Error\r
-  @return EFI_OUT_OF_RESOURCES : cannot allocate resources\r
+  @return EFI_SUCCESS          supports this device.\r
+  @return EFI_UNSUPPORTED      do not support this device.\r
+  @return EFI_DEVICE_ERROR     cannot be started due to device Error.\r
+  @return EFI_OUT_OF_RESOURCES cannot allocate resources.\r
 \r
 **/\r
 EFI_STATUS\r
 EFIAPI\r
 EhcDriverBindingStart (\r
-  IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
-  IN EFI_HANDLE                  Controller,\r
-  IN EFI_DEVICE_PATH_PROTOCOL    *RemainingDevicePath\r
+  IN EFI_DRIVER_BINDING_PROTOCOL  *This,\r
+  IN EFI_HANDLE                   Controller,\r
+  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath\r
   )\r
 {\r
-  EFI_STATUS              Status;\r
-  USB2_HC_DEV             *Ehc;\r
-  EFI_PCI_IO_PROTOCOL     *PciIo;\r
-  UINT64                  Supports;\r
-  UINT64                  OriginalPciAttributes;\r
-  BOOLEAN                 PciAttributesSaved;\r
+  EFI_STATUS                Status;\r
+  USB2_HC_DEV               *Ehc;\r
+  EFI_PCI_IO_PROTOCOL       *PciIo;\r
+  EFI_PCI_IO_PROTOCOL       *Instance;\r
+  UINT64                    Supports;\r
+  UINT64                    OriginalPciAttributes;\r
+  BOOLEAN                   PciAttributesSaved;\r
+  USB_CLASSC                UsbClassCReg;\r
+  EFI_HANDLE                *HandleBuffer;\r
+  UINTN                     NumberOfHandles;\r
+  UINTN                     Index;\r
+  UINTN                     CompanionSegmentNumber;\r
+  UINTN                     CompanionBusNumber;\r
+  UINTN                     CompanionDeviceNumber;\r
+  UINTN                     CompanionFunctionNumber;\r
+  UINTN                     EhciSegmentNumber;\r
+  UINTN                     EhciBusNumber;\r
+  UINTN                     EhciDeviceNumber;\r
+  UINTN                     EhciFunctionNumber;\r
+  EFI_DEVICE_PATH_PROTOCOL  *HcDevicePath;\r
 \r
   //\r
   // Open the PciIo Protocol, then enable the USB host controller\r
@@ -1504,17 +1667,29 @@ EhcDriverBindingStart (
   Status = gBS->OpenProtocol (\r
                   Controller,\r
                   &gEfiPciIoProtocolGuid,\r
-                  (VOID **) &PciIo,\r
+                  (VOID **)&PciIo,\r
                   This->DriverBindingHandle,\r
                   Controller,\r
                   EFI_OPEN_PROTOCOL_BY_DRIVER\r
                   );\r
 \r
   if (EFI_ERROR (Status)) {\r
-    DEBUG ((EFI_D_ERROR, "EhcDriverBindingStart: failed to open PCI_IO\n"));\r
-    return EFI_DEVICE_ERROR;\r
+    return Status;\r
   }\r
 \r
+  //\r
+  // Open Device Path Protocol for on USB host controller\r
+  //\r
+  HcDevicePath = NULL;\r
+  Status       = gBS->OpenProtocol (\r
+                        Controller,\r
+                        &gEfiDevicePathProtocolGuid,\r
+                        (VOID **)&HcDevicePath,\r
+                        This->DriverBindingHandle,\r
+                        Controller,\r
+                        EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
+                        );\r
+\r
   PciAttributesSaved = FALSE;\r
   //\r
   // Save original PCI attributes\r
@@ -1529,6 +1704,7 @@ EhcDriverBindingStart (
   if (EFI_ERROR (Status)) {\r
     goto CLOSE_PCIIO;\r
   }\r
+\r
   PciAttributesSaved = TRUE;\r
 \r
   Status = PciIo->Attributes (\r
@@ -1538,32 +1714,162 @@ EhcDriverBindingStart (
                     &Supports\r
                     );\r
   if (!EFI_ERROR (Status)) {\r
-    Supports &= EFI_PCI_DEVICE_ENABLE;\r
-    Status = PciIo->Attributes (\r
-                      PciIo,\r
-                      EfiPciIoAttributeOperationEnable,\r
-                      Supports,\r
-                      NULL\r
-                      );\r
+    Supports &= (UINT64)EFI_PCI_DEVICE_ENABLE;\r
+    Status    = PciIo->Attributes (\r
+                         PciIo,\r
+                         EfiPciIoAttributeOperationEnable,\r
+                         Supports,\r
+                         NULL\r
+                         );\r
   }\r
 \r
   if (EFI_ERROR (Status)) {\r
-    DEBUG ((EFI_D_ERROR, "EhcDriverBindingStart: failed to enable controller\n"));\r
+    DEBUG ((DEBUG_ERROR, "EhcDriverBindingStart: failed to enable controller\n"));\r
+    goto CLOSE_PCIIO;\r
+  }\r
+\r
+  //\r
+  // Get the Pci device class code.\r
+  //\r
+  Status = PciIo->Pci.Read (\r
+                        PciIo,\r
+                        EfiPciIoWidthUint8,\r
+                        PCI_CLASSCODE_OFFSET,\r
+                        sizeof (USB_CLASSC) / sizeof (UINT8),\r
+                        &UsbClassCReg\r
+                        );\r
+\r
+  if (EFI_ERROR (Status)) {\r
+    Status = EFI_UNSUPPORTED;\r
+    goto CLOSE_PCIIO;\r
+  }\r
+\r
+  //\r
+  // Determine if the device is UHCI or OHCI host controller or not. If yes, then find out the\r
+  // companion usb ehci host controller and force EHCI driver get attached to it before\r
+  // UHCI or OHCI driver attaches to UHCI or OHCI host controller.\r
+  //\r
+  if (((UsbClassCReg.ProgInterface == PCI_IF_UHCI) || (UsbClassCReg.ProgInterface == PCI_IF_OHCI)) &&\r
+      (UsbClassCReg.BaseCode == PCI_CLASS_SERIAL) &&\r
+      (UsbClassCReg.SubClassCode == PCI_CLASS_SERIAL_USB))\r
+  {\r
+    Status = PciIo->GetLocation (\r
+                      PciIo,\r
+                      &CompanionSegmentNumber,\r
+                      &CompanionBusNumber,\r
+                      &CompanionDeviceNumber,\r
+                      &CompanionFunctionNumber\r
+                      );\r
+    if (EFI_ERROR (Status)) {\r
+      goto CLOSE_PCIIO;\r
+    }\r
+\r
+    Status = gBS->LocateHandleBuffer (\r
+                    ByProtocol,\r
+                    &gEfiPciIoProtocolGuid,\r
+                    NULL,\r
+                    &NumberOfHandles,\r
+                    &HandleBuffer\r
+                    );\r
+    if (EFI_ERROR (Status)) {\r
+      goto CLOSE_PCIIO;\r
+    }\r
+\r
+    for (Index = 0; Index < NumberOfHandles; Index++) {\r
+      //\r
+      // Get the device path on this handle\r
+      //\r
+      Status = gBS->HandleProtocol (\r
+                      HandleBuffer[Index],\r
+                      &gEfiPciIoProtocolGuid,\r
+                      (VOID **)&Instance\r
+                      );\r
+      ASSERT_EFI_ERROR (Status);\r
+\r
+      Status = Instance->Pci.Read (\r
+                               Instance,\r
+                               EfiPciIoWidthUint8,\r
+                               PCI_CLASSCODE_OFFSET,\r
+                               sizeof (USB_CLASSC) / sizeof (UINT8),\r
+                               &UsbClassCReg\r
+                               );\r
+\r
+      if (EFI_ERROR (Status)) {\r
+        Status = EFI_UNSUPPORTED;\r
+        goto CLOSE_PCIIO;\r
+      }\r
+\r
+      if ((UsbClassCReg.ProgInterface == PCI_IF_EHCI) &&\r
+          (UsbClassCReg.BaseCode == PCI_CLASS_SERIAL) &&\r
+          (UsbClassCReg.SubClassCode == PCI_CLASS_SERIAL_USB))\r
+      {\r
+        Status = Instance->GetLocation (\r
+                             Instance,\r
+                             &EhciSegmentNumber,\r
+                             &EhciBusNumber,\r
+                             &EhciDeviceNumber,\r
+                             &EhciFunctionNumber\r
+                             );\r
+        if (EFI_ERROR (Status)) {\r
+          goto CLOSE_PCIIO;\r
+        }\r
+\r
+        //\r
+        // Currently, the judgment on the companion usb host controller is through the\r
+        // same bus number, which may vary on different platform.\r
+        //\r
+        if (EhciBusNumber == CompanionBusNumber) {\r
+          gBS->CloseProtocol (\r
+                 Controller,\r
+                 &gEfiPciIoProtocolGuid,\r
+                 This->DriverBindingHandle,\r
+                 Controller\r
+                 );\r
+          EhcDriverBindingStart (This, HandleBuffer[Index], NULL);\r
+        }\r
+      }\r
+    }\r
+\r
+    Status = EFI_NOT_FOUND;\r
     goto CLOSE_PCIIO;\r
   }\r
 \r
   //\r
   // Create then install USB2_HC_PROTOCOL\r
   //\r
-  Ehc = EhcCreateUsb2Hc (PciIo, OriginalPciAttributes);\r
+  Ehc = EhcCreateUsb2Hc (PciIo, HcDevicePath, OriginalPciAttributes);\r
 \r
   if (Ehc == NULL) {\r
-    DEBUG ((EFI_D_ERROR, "EhcDriverBindingStart: failed to create USB2_HC\n"));\r
+    DEBUG ((DEBUG_ERROR, "EhcDriverBindingStart: failed to create USB2_HC\n"));\r
 \r
     Status = EFI_OUT_OF_RESOURCES;\r
     goto CLOSE_PCIIO;\r
   }\r
 \r
+  //\r
+  // Enable 64-bit DMA support in the PCI layer if this controller\r
+  // supports it.\r
+  //\r
+  if (EHC_BIT_IS_SET (Ehc->HcCapParams, HCCP_64BIT)) {\r
+    Status = PciIo->Attributes (\r
+                      PciIo,\r
+                      EfiPciIoAttributeOperationEnable,\r
+                      EFI_PCI_IO_ATTRIBUTE_DUAL_ADDRESS_CYCLE,\r
+                      NULL\r
+                      );\r
+    if (!EFI_ERROR (Status)) {\r
+      Ehc->Support64BitDma = TRUE;\r
+    } else {\r
+      DEBUG ((\r
+        DEBUG_WARN,\r
+        "%a: failed to enable 64-bit DMA on 64-bit capable controller @ %p (%r)\n",\r
+        __FUNCTION__,\r
+        Controller,\r
+        Status\r
+        ));\r
+    }\r
+  }\r
+\r
   Status = gBS->InstallProtocolInterface (\r
                   &Controller,\r
                   &gEfiUsb2HcProtocolGuid,\r
@@ -1572,23 +1878,26 @@ EhcDriverBindingStart (
                   );\r
 \r
   if (EFI_ERROR (Status)) {\r
-    DEBUG ((EFI_D_ERROR, "EhcDriverBindingStart: failed to install USB2_HC Protocol\n"));\r
+    DEBUG ((DEBUG_ERROR, "EhcDriverBindingStart: failed to install USB2_HC Protocol\n"));\r
     goto FREE_POOL;\r
   }\r
 \r
   //\r
-  // Robustnesss improvement such as for UoL\r
+  // Robustnesss improvement such as for Duet platform\r
   // Default is not required.\r
   //\r
   if (FeaturePcdGet (PcdTurnOffUsbLegacySupport)) {\r
     EhcClearLegacySupport (Ehc);\r
   }\r
-  EhcResetHC (Ehc, EHC_RESET_TIMEOUT);\r
+\r
+  if (!EhcIsDebugPortInUse (Ehc, NULL)) {\r
+    EhcResetHC (Ehc, EHC_RESET_TIMEOUT);\r
+  }\r
 \r
   Status = EhcInitHC (Ehc);\r
 \r
   if (EFI_ERROR (Status)) {\r
-    DEBUG ((EFI_D_ERROR, "EhcDriverBindingStart: failed to init host controller\n"));\r
+    DEBUG ((DEBUG_ERROR, "EhcDriverBindingStart: failed to init host controller\n"));\r
     goto UNINSTALL_USBHC;\r
   }\r
 \r
@@ -1598,12 +1907,27 @@ EhcDriverBindingStart (
   Status = gBS->SetTimer (Ehc->PollTimer, TimerPeriodic, EHC_ASYNC_POLL_INTERVAL);\r
 \r
   if (EFI_ERROR (Status)) {\r
-    DEBUG ((EFI_D_ERROR, "EhcDriverBindingStart: failed to start async interrupt monitor\n"));\r
+    DEBUG ((DEBUG_ERROR, "EhcDriverBindingStart: failed to start async interrupt monitor\n"));\r
 \r
     EhcHaltHC (Ehc, EHC_GENERIC_TIMEOUT);\r
     goto UNINSTALL_USBHC;\r
   }\r
 \r
+  //\r
+  // Create event to stop the HC when exit boot service.\r
+  //\r
+  Status = gBS->CreateEventEx (\r
+                  EVT_NOTIFY_SIGNAL,\r
+                  TPL_NOTIFY,\r
+                  EhcExitBootService,\r
+                  Ehc,\r
+                  &gEfiEventExitBootServicesGuid,\r
+                  &Ehc->ExitBootServiceEvent\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    goto UNINSTALL_USBHC;\r
+  }\r
+\r
   //\r
   // Install the component name protocol, don't fail the start\r
   // because of something for display.\r
@@ -1623,8 +1947,7 @@ EhcDriverBindingStart (
     FALSE\r
     );\r
 \r
-\r
-  DEBUG ((EFI_D_INFO, "EhcDriverBindingStart: EHCI started for controller @ %x\n", Controller));\r
+  DEBUG ((DEBUG_INFO, "EhcDriverBindingStart: EHCI started for controller @ %p\n", Controller));\r
   return EFI_SUCCESS;\r
 \r
 UNINSTALL_USBHC:\r
@@ -1640,16 +1963,16 @@ FREE_POOL:
   gBS->FreePool (Ehc);\r
 \r
 CLOSE_PCIIO:\r
-  if (PciAttributesSaved == TRUE) {\r
+  if (PciAttributesSaved) {\r
     //\r
     // Restore original PCI attributes\r
     //\r
     PciIo->Attributes (\r
-                    PciIo,\r
-                    EfiPciIoAttributeOperationSet,\r
-                    OriginalPciAttributes,\r
-                    NULL\r
-                    );\r
+             PciIo,\r
+             EfiPciIoAttributeOperationSet,\r
+             OriginalPciAttributes,\r
+             NULL\r
+             );\r
   }\r
 \r
   gBS->CloseProtocol (\r
@@ -1662,27 +1985,26 @@ CLOSE_PCIIO:
   return Status;\r
 }\r
 \r
-\r
 /**\r
-  Stop this driver on ControllerHandle. Support stoping any child handles\r
+  Stop this driver on ControllerHandle. Support stopping any child handles\r
   created by this driver.\r
 \r
   @param  This                 Protocol instance pointer.\r
-  @param  Controller           Handle of device to stop driver on\r
-  @param  NumberOfChildren     Number of Children in the ChildHandleBuffer\r
+  @param  Controller           Handle of device to stop driver on.\r
+  @param  NumberOfChildren     Number of Children in the ChildHandleBuffer.\r
   @param  ChildHandleBuffer    List of handles for the children we need to stop.\r
 \r
-  @return EFI_SUCCESS         Success\r
-  @return EFI_DEVICE_ERROR    Fail\r
+  @return EFI_SUCCESS          Success.\r
+  @return EFI_DEVICE_ERROR     Fail.\r
 \r
 **/\r
 EFI_STATUS\r
 EFIAPI\r
 EhcDriverBindingStop (\r
-  IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
-  IN EFI_HANDLE                  Controller,\r
-  IN UINTN                       NumberOfChildren,\r
-  IN EFI_HANDLE                  *ChildHandleBuffer\r
+  IN EFI_DRIVER_BINDING_PROTOCOL  *This,\r
+  IN EFI_HANDLE                   Controller,\r
+  IN UINTN                        NumberOfChildren,\r
+  IN EFI_HANDLE                   *ChildHandleBuffer\r
   )\r
 {\r
   EFI_STATUS            Status;\r
@@ -1698,7 +2020,7 @@ EhcDriverBindingStop (
   Status = gBS->OpenProtocol (\r
                   Controller,\r
                   &gEfiUsb2HcProtocolGuid,\r
-                  (VOID **) &Usb2Hc,\r
+                  (VOID **)&Usb2Hc,\r
                   This->DriverBindingHandle,\r
                   Controller,\r
                   EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
@@ -1711,13 +2033,6 @@ EhcDriverBindingStop (
   Ehc   = EHC_FROM_THIS (Usb2Hc);\r
   PciIo = Ehc->PciIo;\r
 \r
-  //\r
-  // Stop AsyncRequest Polling timer then stop the EHCI driver\r
-  // and uninstall the EHCI protocl.\r
-  //\r
-  gBS->SetTimer (Ehc->PollTimer, TimerCancel, EHC_ASYNC_POLL_INTERVAL);\r
-  EhcHaltHC (Ehc, EHC_GENERIC_TIMEOUT);\r
-\r
   Status = gBS->UninstallProtocolInterface (\r
                   Controller,\r
                   &gEfiUsb2HcProtocolGuid,\r
@@ -1728,25 +2043,42 @@ EhcDriverBindingStop (
     return Status;\r
   }\r
 \r
+  //\r
+  // Stop AsyncRequest Polling timer then stop the EHCI driver\r
+  // and uninstall the EHCI protocl.\r
+  //\r
+  gBS->SetTimer (Ehc->PollTimer, TimerCancel, EHC_ASYNC_POLL_INTERVAL);\r
+  EhcHaltHC (Ehc, EHC_GENERIC_TIMEOUT);\r
+\r
   if (Ehc->PollTimer != NULL) {\r
     gBS->CloseEvent (Ehc->PollTimer);\r
   }\r
 \r
+  if (Ehc->ExitBootServiceEvent != NULL) {\r
+    gBS->CloseEvent (Ehc->ExitBootServiceEvent);\r
+  }\r
+\r
   EhcFreeSched (Ehc);\r
 \r
-  if (Ehc->ControllerNameTable) {\r
+  if (Ehc->ControllerNameTable != NULL) {\r
     FreeUnicodeStringTable (Ehc->ControllerNameTable);\r
   }\r
 \r
+  //\r
+  // Disable routing of all ports to EHCI controller, so all ports are\r
+  // routed back to the UHCI or OHCI controller.\r
+  //\r
+  EhcClearOpRegBit (Ehc, EHC_CONFIG_FLAG_OFFSET, CONFIGFLAG_ROUTE_EHC);\r
+\r
   //\r
   // Restore original PCI attributes\r
   //\r
   PciIo->Attributes (\r
-                  PciIo,\r
-                  EfiPciIoAttributeOperationSet,\r
-                  Ehc->OriginalPciAttributes,\r
-                  NULL\r
-                  );\r
+           PciIo,\r
+           EfiPciIoAttributeOperationSet,\r
+           Ehc->OriginalPciAttributes,\r
+           NULL\r
+           );\r
 \r
   gBS->CloseProtocol (\r
          Controller,\r
@@ -1759,13 +2091,3 @@ EhcDriverBindingStop (
 \r
   return EFI_SUCCESS;\r
 }\r
-\r
-EFI_DRIVER_BINDING_PROTOCOL\r
-gEhciDriverBinding = {\r
-  EhcDriverBindingSupported,\r
-  EhcDriverBindingStart,\r
-  EhcDriverBindingStop,\r
-  0x10,\r
-  NULL,\r
-  NULL\r
-};\r