]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Bus/Pci/UhciDxe/Uhci.c
Update the copyright notice format
[mirror_edk2.git] / MdeModulePkg / Bus / Pci / UhciDxe / Uhci.c
index 1c3e37a7bc377b643c137d08e7ece8411f64d065..92567f93e48d565bd626fbfa84b1bfd68fa8af40 100644 (file)
@@ -1,7 +1,9 @@
 /** @file\r
 \r
-Copyright (c) 2004 - 2007, Intel Corporation\r
-All rights reserved. This program and the accompanying materials\r
+  The UHCI driver model and HC protocol routines.\r
+\r
+Copyright (c) 2004 - 2010, 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
@@ -9,85 +11,78 @@ http://opensource.org/licenses/bsd-license.php
 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
 \r
-Module Name:\r
-\r
-  Uhci.c\r
-\r
-Abstract:\r
-\r
-  The UHCI driver model and HC protocol routines.\r
-\r
-Revision History\r
-\r
-\r
 **/\r
 \r
 #include "Uhci.h"\r
 \r
 \r
+EFI_DRIVER_BINDING_PROTOCOL gUhciDriverBinding = {\r
+  UhciDriverBindingSupported,\r
+  UhciDriverBindingStart,\r
+  UhciDriverBindingStop,\r
+  0x20,\r
+  NULL,\r
+  NULL\r
+};\r
+\r
 /**\r
-  Provides software reset for the USB host controller.\r
+  Provides software reset for the USB host controller according to UEFI 2.0 spec.\r
 \r
-  This      : A pointer to the EFI_USB_HC_PROTOCOL instance.\r
-  Attributes: A bit mask of the reset operation to perform.\r
+  @param  This                   A pointer to the EFI_USB2_HC_PROTOCOL instance.\r
+  @param  Attributes             A bit mask of the reset operation to perform.  See\r
+                                 below for a list of the supported bit mask values.\r
 \r
-  @return EFI_SUCCESS           : The reset operation succeeded.\r
-  @return EFI_INVALID_PARAMETER : Attributes is not valid.\r
-  @return EFI_DEVICE_ERROR      : An error was encountered while attempting\r
-  @return to perform the reset operation.\r
+  @return EFI_SUCCESS            The reset operation succeeded.\r
+  @return EFI_INVALID_PARAMETER  Attributes is not valid.\r
+  @return EFI_UNSUPPORTED        This type of reset is not currently supported.\r
+  @return EFI_DEVICE_ERROR       Other errors.\r
 \r
 **/\r
-STATIC\r
 EFI_STATUS\r
 EFIAPI\r
-UhciReset (\r
-  IN EFI_USB_HC_PROTOCOL     *This,\r
-  IN UINT16                  Attributes\r
+Uhci2Reset (\r
+  IN EFI_USB2_HC_PROTOCOL   *This,\r
+  IN UINT16                 Attributes\r
   )\r
 {\r
   USB_HC_DEV          *Uhc;\r
   EFI_TPL             OldTpl;\r
 \r
+  if ((Attributes == EFI_USB_HC_RESET_GLOBAL_WITH_DEBUG) ||\r
+      (Attributes == EFI_USB_HC_RESET_HOST_WITH_DEBUG)) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  Uhc     = UHC_FROM_USB2_HC_PROTO (This);\r
+\r
   OldTpl  = gBS->RaiseTPL (UHCI_TPL);\r
-  Uhc     = UHC_FROM_USB_HC_PROTO (This);\r
 \r
   switch (Attributes) {\r
   case EFI_USB_HC_RESET_GLOBAL:\r
     //\r
     // Stop schedule and set the Global Reset bit in the command register\r
     //\r
-    UhciStopHc (Uhc, STALL_1_SECOND);\r
+    UhciStopHc (Uhc, UHC_GENERIC_TIMEOUT);\r
     UhciSetRegBit (Uhc->PciIo, USBCMD_OFFSET, USBCMD_GRESET);\r
 \r
-    //\r
-    // Wait 50ms for root port to let reset complete\r
-    // See UHCI spec page122 Reset signaling\r
-    //\r
-    gBS->Stall (ROOT_PORT_REST_TIME);\r
+    gBS->Stall (UHC_ROOT_PORT_RESET_STALL);\r
 \r
     //\r
     // Clear the Global Reset bit to zero.\r
     //\r
     UhciClearRegBit (Uhc->PciIo, USBCMD_OFFSET, USBCMD_GRESET);\r
 \r
-    //\r
-    // UHCI spec page120 reset recovery time\r
-    //\r
-    gBS->Stall (PORT_RESET_RECOVERY_TIME);\r
+    gBS->Stall (UHC_ROOT_PORT_RECOVERY_STALL);\r
     break;\r
 \r
   case EFI_USB_HC_RESET_HOST_CONTROLLER:\r
     //\r
     // Stop schedule and set Host Controller Reset bit to 1\r
     //\r
-    UhciStopHc (Uhc, STALL_1_SECOND);\r
+    UhciStopHc (Uhc, UHC_GENERIC_TIMEOUT);\r
     UhciSetRegBit (Uhc->PciIo, USBCMD_OFFSET, USBCMD_HCRESET);\r
 \r
-    //\r
-    // this bit will be reset by Host Controller when reset is completed.\r
-    // wait 10ms to let reset complete\r
-    //\r
-    gBS->Stall (PORT_RESET_RECOVERY_TIME);\r
+    gBS->Stall (UHC_ROOT_PORT_RECOVERY_STALL);\r
     break;\r
 \r
   default:\r
@@ -115,23 +110,21 @@ ON_INVAILD_PARAMETER:
 \r
 \r
 /**\r
-  Retrieves current state of the USB host controller.\r
+  Retrieves current state of the USB host controller according to UEFI 2.0 spec.\r
 \r
-  This    :  A pointer to the EFI_USB_HC_PROTOCOL instance.\r
-  State   :  A pointer to the EFI_USB_HC_STATE data structure that\r
-  indicates current state of the USB host controller.\r
+  @param  This                   A pointer to the EFI_USB2_HC_PROTOCOL instance.\r
+  @param  State                  Variable to receive current device state.\r
 \r
-  @return EFI_SUCCESS           : State was returned\r
-  @return EFI_INVALID_PARAMETER : State is NULL.\r
-  @return EFI_DEVICE_ERROR      : An error was encountered\r
+  @return EFI_SUCCESS            The state is returned.\r
+  @return EFI_INVALID_PARAMETER  State is not valid.\r
+  @return EFI_DEVICE_ERROR       Other errors.\r
 \r
 **/\r
-STATIC\r
 EFI_STATUS\r
 EFIAPI\r
-UhciGetState (\r
-  IN  EFI_USB_HC_PROTOCOL     *This,\r
-  OUT EFI_USB_HC_STATE        *State\r
+Uhci2GetState (\r
+  IN CONST EFI_USB2_HC_PROTOCOL   *This,\r
+  OUT      EFI_USB_HC_STATE       *State\r
   )\r
 {\r
   USB_HC_DEV          *Uhc;\r
@@ -142,12 +135,12 @@ UhciGetState (
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
-  Uhc     = UHC_FROM_USB_HC_PROTO (This);\r
+  Uhc     = UHC_FROM_USB2_HC_PROTO (This);\r
 \r
   UsbCmd  = UhciReadReg (Uhc->PciIo, USBCMD_OFFSET);\r
   UsbSts  = UhciReadReg (Uhc->PciIo, USBSTS_OFFSET);\r
 \r
-  if (UsbCmd & USBCMD_EGSM) {\r
+  if ((UsbCmd & USBCMD_EGSM) !=0 ) {\r
     *State = EfiUsbHcStateSuspend;\r
 \r
   } else if ((UsbSts & USBSTS_HCH) != 0) {\r
@@ -162,21 +155,21 @@ UhciGetState (
 \r
 \r
 /**\r
-  Sets the USB host controller to a specific state.\r
+  Sets the USB host controller to a specific state according to UEFI 2.0 spec.\r
 \r
-  This     : A pointer to the EFI_USB_HC_PROTOCOL instance.\r
-  State    : Indicates the state of the host controller that will be set.\r
+  @param  This                   A pointer to the EFI_USB2_HC_PROTOCOL instance.\r
+  @param  State                  Indicates the state of the host controller that will\r
+                                 be set.\r
 \r
-  @return EFI_SUCCESS           : The USB host controller was successfully set\r
-  @return EFI_INVALID_PARAMETER : State is invalid.\r
-  @return EFI_DEVICE_ERROR      : Failed to set the state specified\r
+  @return EFI_SUCCESS            Host controller was successfully placed in the state.\r
+  @return EFI_INVALID_PARAMETER  State is invalid.\r
+  @return EFI_DEVICE_ERROR       Failed to set the state.\r
 \r
 **/\r
-STATIC\r
 EFI_STATUS\r
 EFIAPI\r
-UhciSetState (\r
-  IN EFI_USB_HC_PROTOCOL     *This,\r
+Uhci2SetState (\r
+  IN EFI_USB2_HC_PROTOCOL    *This,\r
   IN EFI_USB_HC_STATE        State\r
   )\r
 {\r
@@ -186,8 +179,8 @@ UhciSetState (
   EFI_STATUS          Status;\r
   UINT16              UsbCmd;\r
 \r
-  Uhc     = UHC_FROM_USB_HC_PROTO (This);\r
-  Status  = UhciGetState (This, &CurState);\r
+  Uhc     = UHC_FROM_USB2_HC_PROTO (This);\r
+  Status  = Uhci2GetState (This, &CurState);\r
 \r
   if (EFI_ERROR (Status)) {\r
     return EFI_DEVICE_ERROR;\r
@@ -202,7 +195,7 @@ UhciSetState (
 \r
   switch (State) {\r
   case EfiUsbHcStateHalt:\r
-    Status = UhciStopHc (Uhc, STALL_1_SECOND);\r
+    Status = UhciStopHc (Uhc, UHC_GENERIC_TIMEOUT);\r
     break;\r
 \r
   case EfiUsbHcStateOperational:\r
@@ -228,7 +221,7 @@ UhciSetState (
       //\r
       // wait 20ms to let resume complete (20ms is specified by UHCI spec)\r
       //\r
-      gBS->Stall (FORCE_GLOBAL_RESUME_TIME);\r
+      gBS->Stall (UHC_FORCE_GLOBAL_RESUME_STALL);\r
 \r
       //\r
       // Write FGR bit to 0 and EGSM(Enter Global Suspend Mode) bit to 0\r
@@ -242,7 +235,7 @@ UhciSetState (
     break;\r
 \r
   case EfiUsbHcStateSuspend:\r
-    Status = UhciSetState (This, EfiUsbHcStateHalt);\r
+    Status = Uhci2SetState (This, EfiUsbHcStateHalt);\r
 \r
     if (EFI_ERROR (Status)) {\r
       Status = EFI_DEVICE_ERROR;\r
@@ -267,24 +260,28 @@ ON_EXIT:
   return Status;\r
 }\r
 \r
-\r
 /**\r
-  Retrieves the number of root hub ports.\r
+  Retrieves capabilities of USB host controller according to UEFI 2.0 spec.\r
 \r
-  This       : A pointer to the EFI_USB_HC_PROTOCOL instance.\r
-  PortNumber : A pointer to the number of the root hub ports.\r
+  @param  This                   A pointer to the EFI_USB2_HC_PROTOCOL instance.\r
+  @param  MaxSpeed               A pointer to the max speed USB host controller\r
+                                 supports.\r
+  @param  PortNumber             A pointer to the number of root hub ports.\r
+  @param  Is64BitCapable         A pointer to an integer to show whether USB host\r
+                                 controller supports 64-bit memory addressing.\r
 \r
-  @return EFI_SUCCESS           : The port number was retrieved successfully.\r
-  @return EFI_INVALID_PARAMETER : PortNumber is NULL.\r
-  @return EFI_DEVICE_ERROR      : An error was encountered\r
+  @return EFI_SUCCESS            capabilities were retrieved successfully.\r
+  @return EFI_INVALID_PARAMETER  MaxSpeed or PortNumber or Is64BitCapable is NULL.\r
+  @return EFI_DEVICE_ERROR       An error was encountered.\r
 \r
 **/\r
-STATIC\r
 EFI_STATUS\r
 EFIAPI\r
-UhciGetRootHubPortNumber (\r
-  IN  EFI_USB_HC_PROTOCOL     *This,\r
-  OUT UINT8                   *PortNumber\r
+Uhci2GetCapability (\r
+  IN  EFI_USB2_HC_PROTOCOL  *This,\r
+  OUT UINT8                 *MaxSpeed,\r
+  OUT UINT8                 *PortNumber,\r
+  OUT UINT8                 *Is64BitCapable\r
   )\r
 {\r
   USB_HC_DEV          *Uhc;\r
@@ -292,12 +289,15 @@ UhciGetRootHubPortNumber (
   UINT16              PortSC;\r
   UINT32              Index;\r
 \r
-  Uhc = UHC_FROM_USB_HC_PROTO (This);\r
+  Uhc = UHC_FROM_USB2_HC_PROTO (This);\r
 \r
-  if (PortNumber == NULL) {\r
+  if ((NULL == MaxSpeed) || (NULL == PortNumber) || (NULL == Is64BitCapable)) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
+  *MaxSpeed       = EFI_USB_SPEED_FULL;\r
+  *Is64BitCapable = (UINT8) FALSE;\r
+\r
   *PortNumber = 0;\r
 \r
   for (Index = 0; Index < USB_MAX_ROOTHUB_PORT; Index++) {\r
@@ -310,43 +310,45 @@ UhciGetRootHubPortNumber (
     // returns 0 in this bit if port number is invalid. Also, if\r
     // PciIo IoRead returns error, 0xFFFF is returned to caller.\r
     //\r
-    if (((PortSC & 0x80) != 0) && (PortSC != 0xFFFF)) {\r
-      (*PortNumber)++;\r
+    if (((PortSC & 0x80) == 0) || (PortSC == 0xFFFF)) {\r
+      break;\r
     }\r
+    (*PortNumber)++;\r
   }\r
 \r
   Uhc->RootPorts = *PortNumber;\r
 \r
-  UHCI_DEBUG (("UhciGetRootHubPortNumber: %d ports\n", Uhc->RootPorts));\r
+  DEBUG ((EFI_D_INFO, "Uhci2GetCapability: %d ports\n", (UINT32)Uhc->RootPorts));\r
   return EFI_SUCCESS;\r
 }\r
 \r
 \r
 /**\r
-  Retrieves the current status of a USB root hub port.\r
+  Retrieves the current status of a USB root hub port according to UEFI 2.0 spec.\r
 \r
-  This        : A pointer to the EFI_USB_HC_PROTOCOL.\r
-  PortNumber  : Specifies the root hub port. This value is zero-based.\r
-  PortStatus  : A pointer to the current port status bits and port status change bits.\r
+  @param  This                    A pointer to the EFI_USB2_HC_PROTOCOL.\r
+  @param  PortNumber              The port to get status.\r
+  @param  PortStatus              A pointer to the current port status bits and  port\r
+                                  status change bits.\r
 \r
-  @return EFI_SUCCESS           : The port status was returned in PortStatus.\r
-  @return EFI_INVALID_PARAMETER : PortNumber is invalid.\r
-  @return EFI_DEVICE_ERROR      : Can't read register\r
+  @return EFI_SUCCESS             status of the USB root hub port was returned in PortStatus.\r
+  @return EFI_INVALID_PARAMETER   PortNumber is invalid.\r
+  @return EFI_DEVICE_ERROR        Can't read register.\r
 \r
 **/\r
 EFI_STATUS\r
 EFIAPI\r
-UhciGetRootHubPortStatus (\r
-  IN  EFI_USB_HC_PROTOCOL     *This,\r
-  IN  UINT8                   PortNumber,\r
-  OUT EFI_USB_PORT_STATUS     *PortStatus\r
+Uhci2GetRootHubPortStatus (\r
+  IN  CONST EFI_USB2_HC_PROTOCOL   *This,\r
+  IN  CONST UINT8                  PortNumber,\r
+  OUT       EFI_USB_PORT_STATUS    *PortStatus\r
   )\r
 {\r
   USB_HC_DEV          *Uhc;\r
   UINT32              Offset;\r
   UINT16              PortSC;\r
 \r
-  Uhc = UHC_FROM_USB_HC_PROTO (This);\r
+  Uhc = UHC_FROM_USB2_HC_PROTO (This);\r
 \r
   if (PortStatus == NULL) {\r
     return EFI_INVALID_PARAMETER;\r
@@ -362,24 +364,24 @@ UhciGetRootHubPortStatus (
 \r
   PortSC                        = UhciReadReg (Uhc->PciIo, Offset);\r
 \r
-  if (PortSC & USBPORTSC_CCS) {\r
+  if ((PortSC & USBPORTSC_CCS) != 0) {\r
     PortStatus->PortStatus |= USB_PORT_STAT_CONNECTION;\r
   }\r
 \r
-  if (PortSC & USBPORTSC_PED) {\r
+  if ((PortSC & USBPORTSC_PED) != 0) {\r
     PortStatus->PortStatus |= USB_PORT_STAT_ENABLE;\r
   }\r
 \r
-  if (PortSC & USBPORTSC_SUSP) {\r
-    UHCI_DEBUG (("UhciGetRootHubPortStatus: port %d is suspended\n", PortNumber));\r
+  if ((PortSC & USBPORTSC_SUSP) != 0) {\r
+    DEBUG ((EFI_D_INFO, "Uhci2GetRootHubPortStatus: port %d is suspended\n", PortNumber));\r
     PortStatus->PortStatus |= USB_PORT_STAT_SUSPEND;\r
   }\r
 \r
-  if (PortSC & USBPORTSC_PR) {\r
+  if ((PortSC & USBPORTSC_PR) != 0) {\r
     PortStatus->PortStatus |= USB_PORT_STAT_RESET;\r
   }\r
 \r
-  if (PortSC & USBPORTSC_LSDA) {\r
+  if ((PortSC & USBPORTSC_LSDA) != 0) {\r
     PortStatus->PortStatus |= USB_PORT_STAT_LOW_SPEED;\r
   }\r
 \r
@@ -388,11 +390,11 @@ UhciGetRootHubPortStatus (
   //\r
   PortStatus->PortStatus |= USB_PORT_STAT_OWNER;\r
 \r
-  if (PortSC & USBPORTSC_CSC) {\r
+  if ((PortSC & USBPORTSC_CSC) != 0) {\r
     PortStatus->PortChangeStatus |= USB_PORT_STAT_C_CONNECTION;\r
   }\r
 \r
-  if (PortSC & USBPORTSC_PEDC) {\r
+  if ((PortSC & USBPORTSC_PEDC) != 0) {\r
     PortStatus->PortChangeStatus |= USB_PORT_STAT_C_ENABLE;\r
   }\r
 \r
@@ -401,26 +403,25 @@ UhciGetRootHubPortStatus (
 \r
 \r
 /**\r
-  Sets a feature for the specified root hub port.\r
+  Sets a feature for the specified root hub port according to UEFI 2.0 spec.\r
 \r
-  This        : A pointer to the EFI_USB_HC_PROTOCOL.\r
-  PortNumber  : Specifies the root hub port whose feature\r
-  is requested to be set.\r
-  PortFeature : Indicates the feature selector associated\r
-  with the feature set request.\r
+  @param  This                   A pointer to the EFI_USB2_HC_PROTOCOL.\r
+  @param  PortNumber             Specifies the root hub port whose feature  is\r
+                                 requested to be set.\r
+  @param  PortFeature            Indicates the feature selector associated  with the\r
+                                 feature set request.\r
 \r
-  @return EFI_SUCCESS           : The feature was set for the port.\r
-  @return EFI_INVALID_PARAMETER : PortNumber is invalid or PortFeature is invalid.\r
-  @return EFI_DEVICE_ERROR      : Can't read register\r
+  @return EFI_SUCCESS            PortFeature was set for the root port.\r
+  @return EFI_INVALID_PARAMETER  PortNumber is invalid or PortFeature is invalid.\r
+  @return EFI_DEVICE_ERROR       Can't read register.\r
 \r
 **/\r
-STATIC\r
 EFI_STATUS\r
 EFIAPI\r
-UhciSetRootHubPortFeature (\r
-  IN  EFI_USB_HC_PROTOCOL     *This,\r
-  IN  UINT8                   PortNumber,\r
-  IN  EFI_USB_PORT_FEATURE    PortFeature\r
+Uhci2SetRootHubPortFeature (\r
+  IN EFI_USB2_HC_PROTOCOL    *This,\r
+  IN UINT8                   PortNumber,\r
+  IN EFI_USB_PORT_FEATURE    PortFeature\r
   )\r
 {\r
   USB_HC_DEV          *Uhc;\r
@@ -429,7 +430,7 @@ UhciSetRootHubPortFeature (
   UINT16              PortSC;\r
   UINT16              Command;\r
 \r
-  Uhc = UHC_FROM_USB_HC_PROTO (This);\r
+  Uhc = UHC_FROM_USB2_HC_PROTO (This);\r
 \r
   if (PortNumber >= Uhc->RootPorts) {\r
     return EFI_INVALID_PARAMETER;\r
@@ -443,7 +444,7 @@ UhciSetRootHubPortFeature (
   switch (PortFeature) {\r
   case EfiUsbPortSuspend:\r
     Command = UhciReadReg (Uhc->PciIo, USBCMD_OFFSET);\r
-    if (!(Command & USBCMD_EGSM)) {\r
+    if ((Command & USBCMD_EGSM) == 0) {\r
       //\r
       // if global suspend is not active, can set port suspend\r
       //\r
@@ -481,26 +482,25 @@ UhciSetRootHubPortFeature (
 \r
 \r
 /**\r
-  Clears a feature for the specified root hub port.\r
+  Clears a feature for the specified root hub port according to Uefi 2.0 spec.\r
 \r
-  This        : A pointer to the EFI_USB_HC_PROTOCOL instance.\r
-  PortNumber  : Specifies the root hub port whose feature\r
-  is requested to be cleared.\r
-  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 was cleared for the port.\r
-  @return EFI_INVALID_PARAMETER : PortNumber is invalid or PortFeature is invalid.\r
-  @return EFI_DEVICE_ERROR      : Can't read register\r
+  @return EFI_SUCCESS            PortFeature was cleared for the USB root hub port.\r
+  @return EFI_INVALID_PARAMETER  PortNumber is invalid or PortFeature is invalid.\r
+  @return EFI_DEVICE_ERROR       Can't read register.\r
 \r
 **/\r
-STATIC\r
 EFI_STATUS\r
 EFIAPI\r
-UhciClearRootHubPortFeature (\r
-  IN  EFI_USB_HC_PROTOCOL     *This,\r
-  IN  UINT8                   PortNumber,\r
-  IN  EFI_USB_PORT_FEATURE    PortFeature\r
+Uhci2ClearRootHubPortFeature (\r
+  IN EFI_USB2_HC_PROTOCOL    *This,\r
+  IN UINT8                   PortNumber,\r
+  IN EFI_USB_PORT_FEATURE    PortFeature\r
   )\r
 {\r
   USB_HC_DEV          *Uhc;\r
@@ -508,7 +508,7 @@ UhciClearRootHubPortFeature (
   UINT32              Offset;\r
   UINT16              PortSC;\r
 \r
-  Uhc = UHC_FROM_USB_HC_PROTO (This);\r
+  Uhc = UHC_FROM_USB2_HC_PROTO (This);\r
 \r
   if (PortNumber >= Uhc->RootPorts) {\r
     return EFI_INVALID_PARAMETER;\r
@@ -585,40 +585,41 @@ UhciClearRootHubPortFeature (
 \r
 \r
 /**\r
-  Submits control transfer to a target USB device.\r
-\r
-  This                : A pointer to the EFI_USB_HC_PROTOCOL instance.\r
-  DeviceAddress       : Usb device address\r
-  IsSlowDevice        : Whether the device is of slow speed or full speed\r
-  MaximumPacketLength : maximum packet size of the default control endpoint\r
-  Request             : USB device request to send\r
-  TransferDirection   : Specifies the data direction for the transfer.\r
-  Data                : Data buffer to transmit from or receive into\r
-  DataLength          : Number of bytes of the data\r
-  TimeOut             : Maximum time, in microseconds\r
-  TransferResult      : Return result in this\r
-\r
-  @return EFI_SUCCESS           : Transfer was completed successfully.\r
-  @return EFI_OUT_OF_RESOURCES  : Failed due to a lack of resources.\r
-  @return EFI_INVALID_PARAMETER : Some parameters are invalid.\r
-  @return EFI_TIMEOUT           : Failed due to timeout.\r
-  @return EFI_DEVICE_ERROR      : Failed due to host controller or device error.\r
+  Submits control transfer to a target USB device accroding to UEFI 2.0 spec.\r
+\r
+  @param  This                   A pointer to the EFI_USB2_HC_PROTOCOL instance.\r
+  @param  DeviceAddress          Target device address.\r
+  @param  DeviceSpeed            Device speed.\r
+  @param  MaximumPacketLength    Maximum packet size of the target endpoint.\r
+  @param  Request                USB device request to send.\r
+  @param  TransferDirection      Data direction of the Data stage in control transfer.\r
+  @param  Data                   Data to transmit/receive in data stage.\r
+  @param  DataLength             Length of the data.\r
+  @param  TimeOut                Maximum time, in microseconds, for transfer to complete.\r
+  @param  Translator             Transaction translator to be used by this device.\r
+  @param  TransferResult         Variable to receive the transfer result.\r
+\r
+  @return EFI_SUCCESS            The control transfer was completed successfully.\r
+  @return EFI_OUT_OF_RESOURCES   Failed due to lack of resource.\r
+  @return EFI_INVALID_PARAMETER  Some parameters are invalid.\r
+  @return EFI_TIMEOUT            Failed due to timeout.\r
+  @return EFI_DEVICE_ERROR       Failed due to host controller or device error.\r
 \r
 **/\r
-STATIC\r
 EFI_STATUS\r
 EFIAPI\r
-UhciControlTransfer (\r
-  IN       EFI_USB_HC_PROTOCOL        *This,\r
-  IN       UINT8                      DeviceAddress,\r
-  IN       BOOLEAN                    IsSlowDevice,\r
-  IN       UINT8                      MaximumPacketLength,\r
-  IN       EFI_USB_DEVICE_REQUEST     *Request,\r
-  IN       EFI_USB_DATA_DIRECTION     TransferDirection,\r
-  IN OUT   VOID                       *Data,              OPTIONAL\r
-  IN OUT   UINTN                      *DataLength,        OPTIONAL\r
-  IN       UINTN                      TimeOut,\r
-  OUT      UINT32                     *TransferResult\r
+Uhci2ControlTransfer (\r
+  IN     EFI_USB2_HC_PROTOCOL                 *This,\r
+  IN     UINT8                                DeviceAddress,\r
+  IN     UINT8                                DeviceSpeed,\r
+  IN     UINTN                                MaximumPacketLength,\r
+  IN     EFI_USB_DEVICE_REQUEST               *Request,\r
+  IN     EFI_USB_DATA_DIRECTION               TransferDirection,\r
+  IN OUT VOID                                 *Data,\r
+  IN OUT UINTN                                *DataLength,\r
+  IN     UINTN                                TimeOut,\r
+  IN     EFI_USB2_HC_TRANSACTION_TRANSLATOR   *Translator,\r
+  OUT    UINT32                               *TransferResult\r
   )\r
 {\r
   USB_HC_DEV              *Uhc;\r
@@ -631,14 +632,18 @@ UhciControlTransfer (
   VOID                    *RequestMap;\r
   UINT8                   *DataPhy;\r
   VOID                    *DataMap;\r
+  BOOLEAN                 IsSlowDevice;\r
+  UINTN                   TransferDataLength;\r
 \r
-  Uhc         = UHC_FROM_USB_HC_PROTO (This);\r
+  Uhc         = UHC_FROM_USB2_HC_PROTO (This);\r
   TDs         = NULL;\r
   DataPhy     = NULL;\r
   DataMap     = NULL;\r
   RequestPhy  = NULL;\r
   RequestMap  = NULL;\r
 \r
+  IsSlowDevice  = (BOOLEAN) ((EFI_USB_SPEED_LOW == DeviceSpeed) ? TRUE : FALSE);\r
+\r
   //\r
   // Parameters Checking\r
   //\r
@@ -656,10 +661,16 @@ UhciControlTransfer (
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
-  if ((TransferDirection != EfiUsbNoData) && (DataLength == NULL)) {\r
+  if ((TransferDirection != EfiUsbNoData) && (Data == NULL || DataLength == NULL)) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
+  if (TransferDirection == EfiUsbNoData) {\r
+    TransferDataLength = 0;\r
+  } else {\r
+    TransferDataLength = *DataLength;\r
+  }\r
+\r
   *TransferResult = EFI_USB_ERR_SYSTEM;\r
   Status          = EFI_DEVICE_ERROR;\r
 \r
@@ -696,10 +707,12 @@ UhciControlTransfer (
           Uhc,\r
           DeviceAddress,\r
           PktId,\r
+          (UINT8*)Request,\r
           RequestPhy,\r
+          (UINT8*)Data,\r
           DataPhy,\r
-          *DataLength,\r
-          MaximumPacketLength,\r
+          TransferDataLength,\r
+          (UINT8) MaximumPacketLength,\r
           IsSlowDevice\r
           );\r
 \r
@@ -713,7 +726,7 @@ UhciControlTransfer (
   // the TD to corrosponding queue head, then check\r
   // the execution result\r
   //\r
-  UhciLinkTdToQh (Uhc->CtrlQh, TDs);\r
+  UhciLinkTdToQh (Uhc, Uhc->CtrlQh, TDs);\r
   Status = UhciExecuteTransfer (Uhc, Uhc->CtrlQh, TDs, TimeOut, IsSlowDevice, &QhResult);\r
   UhciUnlinkTdFromQh (Uhc->CtrlQh, TDs);\r
 \r
@@ -740,36 +753,42 @@ ON_EXIT:
 /**\r
   Submits bulk transfer to a bulk endpoint of a USB device.\r
 \r
-  This                :A pointer to the EFI_USB_HC_PROTOCOL instance.\r
-  DeviceAddress       : Usb device address\r
-  EndPointAddress     : Endpoint number and endpoint direction\r
-  MaximumPacketLength : Maximum packet size of the target endpoint\r
-  Data                : Data buffer to transmit from or receive into\r
-  DataLength          : Length of the data buffer\r
-  DataToggle          : On input, data toggle to use, on output, the next toggle\r
-  TimeOut             : Indicates the maximum time\r
-  TransferResult      : Variable to receive the transfer result\r
-\r
-  @return EFI_SUCCESS           : The bulk transfer was completed successfully.\r
-  @return EFI_OUT_OF_RESOURCES  : Failed due to lack of resource.\r
-  @return EFI_INVALID_PARAMETER : Some parameters are invalid.\r
-  @return EFI_TIMEOUT           : Failed due to timeout.\r
-  @return EFI_DEVICE_ERROR      : Failed due to host controller or device error.\r
+  @param  This                   A pointer to the EFI_USB2_HC_PROTOCOL instance.\r
+  @param  DeviceAddress          Target device address.\r
+  @param  EndPointAddress        Endpoint number and direction.\r
+  @param  DeviceSpeed            Device speed.\r
+  @param  MaximumPacketLength    Maximum packet size of the target endpoint.\r
+  @param  DataBuffersNumber      Number of data buffers prepared for the transfer.\r
+  @param  Data                   Array of pointers to the buffers of data.\r
+  @param  DataLength             On input, size of the data buffer, On output,\r
+                                 actually transferred data size.\r
+  @param  DataToggle             On input, data toggle to use; On output, next data toggle.\r
+  @param  TimeOut                Maximum time out, in microseconds.\r
+  @param  Translator             A pointr to the transaction translator data.\r
+  @param  TransferResult         Variable to receive transfer result.\r
+\r
+  @return EFI_SUCCESS            The bulk transfer was completed successfully.\r
+  @return EFI_OUT_OF_RESOURCES   Failed due to lack of resource.\r
+  @return EFI_INVALID_PARAMETER  Some parameters are invalid.\r
+  @return EFI_TIMEOUT            Failed due to timeout.\r
+  @return EFI_DEVICE_ERROR       Failed due to host controller or device error.\r
 \r
 **/\r
-STATIC\r
 EFI_STATUS\r
 EFIAPI\r
-UhciBulkTransfer (\r
-  IN       EFI_USB_HC_PROTOCOL     *This,\r
-  IN       UINT8                   DeviceAddress,\r
-  IN       UINT8                   EndPointAddress,\r
-  IN       UINT8                   MaximumPacketLength,\r
-  IN OUT   VOID                    *Data,\r
-  IN OUT   UINTN                   *DataLength,\r
-  IN OUT   UINT8                   *DataToggle,\r
-  IN       UINTN                   TimeOut,\r
-  OUT      UINT32                  *TransferResult\r
+Uhci2BulkTransfer (\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     UINT8                              DataBuffersNumber,\r
+  IN OUT VOID                               *Data[EFI_USB_MAX_BULK_BUFFER_NUM],\r
+  IN OUT UINTN                              *DataLength,\r
+  IN OUT UINT8                              *DataToggle,\r
+  IN     UINTN                              TimeOut,\r
+  IN     EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,\r
+  OUT    UINT32                             *TransferResult\r
   )\r
 {\r
   EFI_USB_DATA_DIRECTION  Direction;\r
@@ -783,15 +802,15 @@ UhciBulkTransfer (
   UINT8                   *DataPhy;\r
   VOID                    *DataMap;\r
 \r
-  Uhc     = UHC_FROM_USB_HC_PROTO (This);\r
+  Uhc     = UHC_FROM_USB2_HC_PROTO (This);\r
   DataPhy = NULL;\r
   DataMap = NULL;\r
 \r
-  if ((DataLength == NULL) || (Data == NULL) || (TransferResult == NULL)) {\r
+  if (DeviceSpeed == EFI_USB_SPEED_LOW) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
-  if (*DataLength == 0) {\r
+  if ((DataLength == NULL) || (*DataLength == 0) || (Data == NULL) || (TransferResult == NULL)) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
@@ -823,13 +842,13 @@ UhciBulkTransfer (
   // Map the source data buffer for bus master access,\r
   // then create a list of TDs\r
   //\r
-  if (EndPointAddress & 0x80) {\r
+  if ((EndPointAddress & 0x80) != 0) {\r
     Direction = EfiUsbDataIn;\r
   } else {\r
     Direction = EfiUsbDataOut;\r
   }\r
 \r
-  Status = UhciMapUserData (Uhc, Direction, Data, DataLength, &PktId, &DataPhy, &DataMap);\r
+  Status = UhciMapUserData (Uhc, Direction, *Data, DataLength, &PktId, &DataPhy, &DataMap);\r
 \r
   if (EFI_ERROR (Status)) {\r
     goto ON_EXIT;\r
@@ -841,10 +860,11 @@ UhciBulkTransfer (
              DeviceAddress,\r
              EndPointAddress,\r
              PktId,\r
+             (UINT8 *)*Data,\r
              DataPhy,\r
              *DataLength,\r
              DataToggle,\r
-             MaximumPacketLength,\r
+             (UINT8) MaximumPacketLength,\r
              FALSE\r
              );\r
 \r
@@ -861,7 +881,7 @@ UhciBulkTransfer (
   //\r
   BulkQh = Uhc->BulkQh;\r
 \r
-  UhciLinkTdToQh (BulkQh, TDs);\r
+  UhciLinkTdToQh (Uhc, BulkQh, TDs);\r
   Status = UhciExecuteTransfer (Uhc, BulkQh, TDs, TimeOut, FALSE, &QhResult);\r
   UhciUnlinkTdFromQh (BulkQh, TDs);\r
 \r
@@ -881,60 +901,63 @@ ON_EXIT:
 \r
 \r
 /**\r
-  Submits an asynchronous interrupt transfer to an interrupt endpoint of a USB device.\r
-\r
-  This                : A pointer to the EFI_USB_HC_PROTOCOL instance.\r
-  DeviceAddress       : Target device address\r
-  EndPointAddress     : Endpoint number with direction\r
-  IsSlowDevice        : Whether the target device is slow device or full-speed device.\r
-  MaximumPacketLength : Maximum packet size of the target endpoint\r
-  IsNewTransfer       : If TRUE, submit a new async interrupt transfer, otherwise\r
-  cancel an existed one\r
-  DataToggle          : On input, the data toggle to use; On output, next data toggle\r
-  PollingInterval     : Interrupt poll rate in milliseconds\r
-  DataLength          : Length of data to receive\r
-  CallBackFunction    : Function to call periodically\r
-  Context             : User context\r
-\r
-  @return EFI_SUCCESS           : Request is submitted or cancelled\r
-  @return EFI_INVALID_PARAMETER : Some parameters are invalid.\r
-  @return EFI_OUT_OF_RESOURCES  : Failed due to a lack of resources.\r
-  @return EFI_DEVICE_ERROR      : Failed to due to device error\r
+  Submits an asynchronous interrupt transfer to an\r
+  interrupt endpoint of a USB device according to UEFI 2.0 spec.\r
+\r
+  @param  This                   A pointer to the EFI_USB2_HC_PROTOCOL instance.\r
+  @param  DeviceAddress          Target device address.\r
+  @param  EndPointAddress        Endpoint number and direction.\r
+  @param  DeviceSpeed            Device speed.\r
+  @param  MaximumPacketLength    Maximum packet size of the target endpoint.\r
+  @param  IsNewTransfer          If TRUE, submit a new transfer, if FALSE cancel old transfer.\r
+  @param  DataToggle             On input, data toggle to use; On output, next data toggle.\r
+  @param  PollingInterval        Interrupt poll rate in milliseconds.\r
+  @param  DataLength             On input, size of the data buffer, On output,\r
+                                 actually transferred data size.\r
+  @param  Translator             A pointr to the transaction translator data.\r
+  @param  CallBackFunction       Function to call periodically.\r
+  @param  Context                User context.\r
+\r
+  @return EFI_SUCCESS            Transfer was submitted.\r
+  @return EFI_INVALID_PARAMETER  Some parameters are invalid.\r
+  @return EFI_OUT_OF_RESOURCES   Failed due to a lack of resources.\r
+  @return EFI_DEVICE_ERROR       Can't read register.\r
 \r
 **/\r
-STATIC\r
 EFI_STATUS\r
 EFIAPI\r
-UhciAsyncInterruptTransfer (\r
-  IN     EFI_USB_HC_PROTOCOL                * This,\r
+Uhci2AsyncInterruptTransfer (\r
+  IN     EFI_USB2_HC_PROTOCOL               *This,\r
   IN     UINT8                              DeviceAddress,\r
   IN     UINT8                              EndPointAddress,\r
-  IN     BOOLEAN                            IsSlowDevice,\r
-  IN     UINT8                              MaximumPacketLength,\r
+  IN     UINT8                              DeviceSpeed,\r
+  IN     UINTN                              MaximumPacketLength,\r
   IN     BOOLEAN                            IsNewTransfer,\r
   IN OUT UINT8                              *DataToggle,\r
-  IN     UINTN                              PollingInterval,    OPTIONAL\r
-  IN     UINTN                              DataLength,         OPTIONAL\r
-  IN     EFI_ASYNC_USB_TRANSFER_CALLBACK    CallBackFunction,   OPTIONAL\r
-  IN     VOID                               *Context OPTIONAL\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\r
   )\r
 {\r
   USB_HC_DEV          *Uhc;\r
+  BOOLEAN             IsSlowDevice;\r
   UHCI_QH_SW          *Qh;\r
   UHCI_TD_SW          *IntTds;\r
   EFI_TPL             OldTpl;\r
   EFI_STATUS          Status;\r
   UINT8               *DataPtr;\r
   UINT8               *DataPhy;\r
-  VOID                *DataMap;\r
   UINT8               PktId;\r
 \r
-  Uhc       = UHC_FROM_USB_HC_PROTO (This);\r
+  Uhc       = UHC_FROM_USB2_HC_PROTO (This);\r
   Qh        = NULL;\r
   IntTds    = NULL;\r
   DataPtr   = NULL;\r
   DataPhy   = NULL;\r
-  DataMap   = NULL;\r
+\r
+  IsSlowDevice  = (BOOLEAN) ((EFI_USB_SPEED_LOW == DeviceSpeed) ? TRUE : FALSE);\r
 \r
   if ((EndPointAddress & 0x80) == 0) {\r
     return EFI_INVALID_PARAMETER;\r
@@ -973,40 +996,30 @@ UhciAsyncInterruptTransfer (
     return EFI_DEVICE_ERROR;\r
   }\r
 \r
+  if ((EndPointAddress & 0x80) == 0) {\r
+    PktId = OUTPUT_PACKET_ID;\r
+  } else {\r
+    PktId = INPUT_PACKET_ID;\r
+  }\r
+\r
   //\r
   // Allocate and map source data buffer for bus master access.\r
   //\r
-  DataPtr = AllocatePool (DataLength);\r
+  DataPtr = UsbHcAllocateMem (Uhc->MemPool, DataLength);\r
 \r
   if (DataPtr == NULL) {\r
     return EFI_OUT_OF_RESOURCES;\r
   }\r
 \r
-  OldTpl = gBS->RaiseTPL (UHCI_TPL);\r
-\r
-  //\r
-  // Map the user data then create a queue head and\r
-  // list of TD for it.\r
-  //\r
-  Status = UhciMapUserData (\r
-             Uhc,\r
-             EfiUsbDataIn,\r
-             DataPtr,\r
-             &DataLength,\r
-             &PktId,\r
-             &DataPhy,\r
-             &DataMap\r
-             );\r
+  DataPhy = (UINT8 *) (UINTN) UsbHcGetPciAddressForHostMem (Uhc->MemPool, DataPtr, DataLength);\r
 \r
-  if (EFI_ERROR (Status)) {\r
-    goto FREE_DATA;\r
-  }\r
+  OldTpl = gBS->RaiseTPL (UHCI_TPL);\r
 \r
   Qh = UhciCreateQh (Uhc, PollingInterval);\r
 \r
   if (Qh == NULL) {\r
     Status = EFI_OUT_OF_RESOURCES;\r
-    goto UNMAP_DATA;\r
+    goto FREE_DATA;\r
   }\r
 \r
   IntTds = UhciCreateBulkOrIntTds (\r
@@ -1014,10 +1027,11 @@ UhciAsyncInterruptTransfer (
              DeviceAddress,\r
              EndPointAddress,\r
              PktId,\r
+             DataPtr,\r
              DataPhy,\r
              DataLength,\r
              DataToggle,\r
-             MaximumPacketLength,\r
+             (UINT8) MaximumPacketLength,\r
              IsSlowDevice\r
              );\r
 \r
@@ -1026,7 +1040,7 @@ UhciAsyncInterruptTransfer (
     goto DESTORY_QH;\r
   }\r
 \r
-  UhciLinkTdToQh (Qh, IntTds);\r
+  UhciLinkTdToQh (Uhc, Qh, IntTds);\r
 \r
   //\r
   // Save QH-TD structures to async Interrupt transfer list,\r
@@ -1040,7 +1054,6 @@ UhciAsyncInterruptTransfer (
              EndPointAddress,\r
              DataLength,\r
              PollingInterval,\r
-             DataMap,\r
              DataPtr,\r
              CallBackFunction,\r
              Context,\r
@@ -1051,7 +1064,7 @@ UhciAsyncInterruptTransfer (
     goto DESTORY_QH;\r
   }\r
 \r
-  UhciLinkQhToFrameList (Uhc->FrameBase, Qh);\r
+  UhciLinkQhToFrameList (Uhc, Qh);\r
 \r
   gBS->RestoreTPL (OldTpl);\r
   return EFI_SUCCESS;\r
@@ -1059,54 +1072,53 @@ UhciAsyncInterruptTransfer (
 DESTORY_QH:\r
   UsbHcFreeMem (Uhc->MemPool, Qh, sizeof (UHCI_QH_SW));\r
 \r
-UNMAP_DATA:\r
-  Uhc->PciIo->Unmap (Uhc->PciIo, DataMap);\r
-\r
 FREE_DATA:\r
-  gBS->FreePool (DataPtr);\r
+  UsbHcFreeMem (Uhc->MemPool, DataPtr, DataLength);\r
   Uhc->PciIo->Flush (Uhc->PciIo);\r
 \r
   gBS->RestoreTPL (OldTpl);\r
   return Status;\r
 }\r
 \r
-\r
 /**\r
-  Submits synchronous interrupt transfer to an interrupt endpoint of a USB device.\r
-\r
-  This                : A pointer to the EFI_USB_HC_PROTOCOL instance.\r
-  DeviceAddress       : Device address of the target USB device\r
-  EndPointAddress     : Endpoint number and direction\r
-  IsSlowDevice        : Whether the target device is of slow speed or full speed\r
-  MaximumPacketLength : Maximum packet size of target endpoint\r
-  Data                : Data to transmit or receive\r
-  DataLength          : On input, data length to transmit or buffer size.\r
-  On output, the number of bytes transferred.\r
-  DataToggle          : On input, data toggle to use; On output, next data toggle\r
-  TimeOut             : Maximum time, in microseconds, transfer is allowed to complete.\r
-  TransferResult      : Variable to receive transfer result\r
-\r
-  @return EFI_SUCCESS           : Transfer was completed successfully.\r
-  @return EFI_OUT_OF_RESOURCES  : Failed due to lack of resource.\r
-  @return EFI_INVALID_PARAMETER : Some parameters are invalid.\r
-  @return EFI_TIMEOUT           : Failed due to timeout.\r
-  @return EFI_DEVICE_ERROR      : Failed due to host controller or device error\r
+  Submits synchronous interrupt transfer to an interrupt endpoint\r
+  of a USB device according to UEFI 2.0 spec.\r
+\r
+\r
+  @param  This                   A pointer to the EFI_USB2_HC_PROTOCOL instance.\r
+  @param  DeviceAddress          Target device address.\r
+  @param  EndPointAddress        Endpoint number and direction.\r
+  @param  DeviceSpeed            Device speed.\r
+  @param  MaximumPacketLength    Maximum packet size of the target endpoint.\r
+  @param  Data                   Array of pointers to the buffers of data.\r
+  @param  DataLength             On input, size of the data buffer, On output,\r
+                                 actually transferred data size.\r
+  @param  DataToggle             On input, data toggle to use; On output, next data toggle.\r
+  @param  TimeOut                Maximum time out, in microseconds.\r
+  @param  Translator             A pointr to the transaction translator data.\r
+  @param  TransferResult         Variable to receive transfer result.\r
+\r
+  @return EFI_SUCCESS            The transfer was completed successfully.\r
+  @return EFI_OUT_OF_RESOURCES   Failed due to lack of resource.\r
+  @return EFI_INVALID_PARAMETER  Some parameters are invalid.\r
+  @return EFI_TIMEOUT            Failed due to timeout.\r
+  @return EFI_DEVICE_ERROR       Failed due to host controller or device error.\r
 \r
 **/\r
-STATIC\r
 EFI_STATUS\r
 EFIAPI\r
-UhciSyncInterruptTransfer (\r
-  IN       EFI_USB_HC_PROTOCOL     *This,\r
-  IN       UINT8                   DeviceAddress,\r
-  IN       UINT8                   EndPointAddress,\r
-  IN       BOOLEAN                 IsSlowDevice,\r
-  IN       UINT8                   MaximumPacketLength,\r
-  IN OUT   VOID                    *Data,\r
-  IN OUT   UINTN                   *DataLength,\r
-  IN OUT   UINT8                   *DataToggle,\r
-  IN       UINTN                   TimeOut,\r
-  OUT      UINT32                  *TransferResult\r
+Uhci2SyncInterruptTransfer (\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 OUT VOID                                      *Data,\r
+  IN OUT UINTN                                     *DataLength,\r
+  IN OUT UINT8                                     *DataToggle,\r
+  IN     UINTN                                     TimeOut,\r
+  IN     EFI_USB2_HC_TRANSACTION_TRANSLATOR        *Translator,\r
+  OUT    UINT32                                    *TransferResult\r
   )\r
 {\r
   EFI_STATUS          Status;\r
@@ -1117,12 +1129,19 @@ UhciSyncInterruptTransfer (
   UINT8               *DataPhy;\r
   VOID                *DataMap;\r
   UINT8               PktId;\r
+  BOOLEAN             IsSlowDevice;\r
 \r
-  Uhc     = UHC_FROM_USB_HC_PROTO (This);\r
+  Uhc     = UHC_FROM_USB2_HC_PROTO (This);\r
   DataPhy = NULL;\r
   DataMap = NULL;\r
   TDs     = NULL;\r
 \r
+  if (DeviceSpeed == EFI_USB_SPEED_HIGH) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  IsSlowDevice  = (BOOLEAN) ((EFI_USB_SPEED_LOW == DeviceSpeed) ? TRUE : FALSE);\r
+\r
   if ((DataLength == NULL) || (Data == NULL) || (TransferResult == NULL)) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
@@ -1178,10 +1197,11 @@ UhciSyncInterruptTransfer (
           DeviceAddress,\r
           EndPointAddress,\r
           PktId,\r
+          (UINT8 *)Data,\r
           DataPhy,\r
           *DataLength,\r
           DataToggle,\r
-          MaximumPacketLength,\r
+          (UINT8) MaximumPacketLength,\r
           IsSlowDevice\r
           );\r
 \r
@@ -1193,7 +1213,7 @@ UhciSyncInterruptTransfer (
   }\r
 \r
 \r
-  UhciLinkTdToQh (Uhc->SyncIntQh, TDs);\r
+  UhciLinkTdToQh (Uhc, Uhc->SyncIntQh, TDs);\r
 \r
   Status = UhciExecuteTransfer (Uhc, Uhc->SyncIntQh, TDs, TimeOut, IsSlowDevice, &QhResult);\r
 \r
@@ -1214,30 +1234,36 @@ ON_EXIT:
 \r
 \r
 /**\r
-  Submits isochronous transfer to a target USB device.\r
+  Submits isochronous transfer to a target USB device according to UEFI 2.0 spec.\r
 \r
-  This                : A pointer to the EFI_USB_HC_PROTOCOL instance.\r
-  DeviceAddress       : Target device address\r
-  EndPointAddress     : End point address withdirection\r
-  MaximumPacketLength : Maximum packet size of the endpoint\r
-  Data                : Data to transmit or receive\r
-  DataLength          : Bytes of the data\r
-  TransferResult      : Variable to receive the result\r
+  @param  This                  A pointer to the EFI_USB2_HC_PROTOCOL instance.\r
+  @param  DeviceAddress         Target device address.\r
+  @param  EndPointAddress       Endpoint number and direction.\r
+  @param  DeviceSpeed           Device speed.\r
+  @param  MaximumPacketLength   Maximum packet size of the target endpoint.\r
+  @param  DataBuffersNumber     Number of data buffers prepared for the transfer.\r
+  @param  Data                  Array of pointers to the buffers of data.\r
+  @param  DataLength            On input, size of the data buffer, On output,\r
+                                actually transferred data size.\r
+  @param  Translator            A pointr to the transaction translator data.\r
+  @param  TransferResult        Variable to receive transfer result.\r
 \r
   @return EFI_UNSUPPORTED\r
 \r
 **/\r
-STATIC\r
 EFI_STATUS\r
 EFIAPI\r
-UhciIsochronousTransfer (\r
-  IN       EFI_USB_HC_PROTOCOL     *This,\r
-  IN       UINT8                   DeviceAddress,\r
-  IN       UINT8                   EndPointAddress,\r
-  IN       UINT8                   MaximumPacketLength,\r
-  IN OUT   VOID                    *Data,\r
-  IN       UINTN                   DataLength,\r
-  OUT      UINT32                  *TransferResult\r
+Uhci2IsochronousTransfer (\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     UINT8                              DataBuffersNumber,\r
+  IN OUT VOID                               *Data[EFI_USB_MAX_ISO_BUFFER_NUM],\r
+  IN     UINTN                              DataLength,\r
+  IN     EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,\r
+  OUT    UINT32                             *TransferResult\r
   )\r
 {\r
   return EFI_UNSUPPORTED;\r
@@ -1245,675 +1271,119 @@ UhciIsochronousTransfer (
 \r
 \r
 /**\r
-  Submits Async isochronous transfer to a target USB device.\r
+  Submits Async isochronous transfer to a target USB device according to UEFI 2.0 spec.\r
 \r
-  This                : A pointer to the EFI_USB_HC_PROTOCOL instance.\r
-  DeviceAddress       : Target device address\r
-  EndPointAddress     : End point address withdirection\r
-  MaximumPacketLength : Maximum packet size of the endpoint\r
-  Data                : Data to transmit or receive\r
-  IsochronousCallBack : Function to call when the transfer completes\r
-  Context             : User context\r
+  @param  This                  A pointer to the EFI_USB2_HC_PROTOCOL instance.\r
+  @param  DeviceAddress         Target device address.\r
+  @param  EndPointAddress       Endpoint number and direction.\r
+  @param  DeviceSpeed           Device speed.\r
+  @param  MaximumPacketLength   Maximum packet size of the target endpoint.\r
+  @param  DataBuffersNumber     Number of data buffers prepared for the transfer.\r
+  @param  Data                  Array of pointers to the buffers of data.\r
+  @param  DataLength            On input, size of the data buffer, On output,\r
+                                actually transferred data size.\r
+  @param  Translator            A pointr to the transaction translator data.\r
+  @param  IsochronousCallBack   Function to call when the transfer complete.\r
+  @param  Context               Pass to the call back function as parameter.\r
 \r
   @return EFI_UNSUPPORTED\r
 \r
 **/\r
-STATIC\r
 EFI_STATUS\r
 EFIAPI\r
-UhciAsyncIsochronousTransfer (\r
-  IN       EFI_USB_HC_PROTOCOL                 * This,\r
-  IN       UINT8                               DeviceAddress,\r
-  IN       UINT8                               EndPointAddress,\r
-  IN       UINT8                               MaximumPacketLength,\r
-  IN OUT   VOID                                *Data,\r
-  IN       UINTN                               DataLength,\r
-  IN       EFI_ASYNC_USB_TRANSFER_CALLBACK     IsochronousCallBack,\r
-  IN       VOID                                *Context OPTIONAL\r
+Uhci2AsyncIsochronousTransfer (\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     UINT8                               DataBuffersNumber,\r
+  IN OUT VOID                                *Data[EFI_USB_MAX_ISO_BUFFER_NUM],\r
+  IN     UINTN                               DataLength,\r
+  IN     EFI_USB2_HC_TRANSACTION_TRANSLATOR  *Translator,\r
+  IN     EFI_ASYNC_USB_TRANSFER_CALLBACK     IsochronousCallBack,\r
+  IN     VOID                                *Context\r
   )\r
 {\r
   return EFI_UNSUPPORTED;\r
 }\r
 \r
-\r
-\r
 /**\r
-  Provides software reset for the USB host controller according to UEFI 2.0 spec.\r
+  Entry point for EFI drivers.\r
 \r
-  @param  This                 A pointer to the EFI_USB2_HC_PROTOCOL instance.\r
-  @param  Attributes           A bit mask of the reset operation to perform.  See\r
-                               below for a list of the supported bit mask values.\r
+  @param  ImageHandle      EFI_HANDLE.\r
+  @param  SystemTable      EFI_SYSTEM_TABLE.\r
 \r
-  @return EFI_SUCCESS           : The reset operation succeeded.\r
-  @return EFI_INVALID_PARAMETER : Attributes is not valid.\r
-  @return EFI_UNSUPPORTED       : This type of reset is not currently supported\r
-  @return EFI_DEVICE_ERROR      : Other errors\r
+  @retval EFI_SUCCESS      Driver is successfully loaded.\r
+  @return Others           Failed.\r
 \r
 **/\r
-STATIC\r
 EFI_STATUS\r
 EFIAPI\r
-Uhci2Reset (\r
-  IN EFI_USB2_HC_PROTOCOL   *This,\r
-  IN UINT16                 Attributes\r
+UhciDriverEntryPoint (\r
+  IN EFI_HANDLE           ImageHandle,\r
+  IN EFI_SYSTEM_TABLE     *SystemTable\r
   )\r
 {\r
-  USB_HC_DEV          *UhciDev;\r
-\r
-  UhciDev = UHC_FROM_USB2_HC_PROTO (This);\r
-\r
-  if ((Attributes == EFI_USB_HC_RESET_GLOBAL_WITH_DEBUG) ||\r
-      (Attributes == EFI_USB_HC_RESET_HOST_WITH_DEBUG)) {\r
-    return EFI_UNSUPPORTED;\r
-  }\r
-\r
-  return UhciReset (&UhciDev->UsbHc, Attributes);\r
+  return EfiLibInstallDriverBindingComponentName2 (\r
+           ImageHandle,\r
+           SystemTable,\r
+           &gUhciDriverBinding,\r
+           ImageHandle,\r
+           &gUhciComponentName,\r
+           &gUhciComponentName2\r
+           );\r
 }\r
 \r
 \r
 /**\r
-  Retrieves current state of the USB host controller according to UEFI 2.0 spec.\r
+  Test to see if this driver supports ControllerHandle. Any\r
+  ControllerHandle that has UsbHcProtocol installed will be supported.\r
 \r
-  @param  This                 A pointer to the EFI_USB_HC_PROTOCOL instance.\r
-  @param  State                Variable to receive current device state\r
+  @param  This                 Protocol instance pointer.\r
+  @param  Controller           Handle of device to test.\r
+  @param  RemainingDevicePath  Not used.\r
 \r
-  @return EFI_SUCCESS           : The state is returned\r
-  @return EFI_INVALID_PARAMETER : State is not valid.\r
-  @return EFI_DEVICE_ERROR      : Other errors2006\r
+  @return EFI_SUCCESS          This driver supports this device.\r
+  @return EFI_UNSUPPORTED      This driver does not support this device.\r
 \r
 **/\r
-STATIC\r
 EFI_STATUS\r
 EFIAPI\r
-Uhci2GetState (\r
-  IN CONST EFI_USB2_HC_PROTOCOL   *This,\r
-  OUT      EFI_USB_HC_STATE       *State\r
+UhciDriverBindingSupported (\r
+  IN EFI_DRIVER_BINDING_PROTOCOL     *This,\r
+  IN EFI_HANDLE                      Controller,\r
+  IN EFI_DEVICE_PATH_PROTOCOL        *RemainingDevicePath\r
   )\r
 {\r
-  USB_HC_DEV          *Uhc;\r
-\r
-  Uhc = UHC_FROM_USB2_HC_PROTO (This);\r
-  return UhciGetState (&Uhc->UsbHc, State);\r
-}\r
+  EFI_STATUS            OpenStatus;\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
+  //\r
+  OpenStatus = gBS->OpenProtocol (\r
+                      Controller,\r
+                      &gEfiPciIoProtocolGuid,\r
+                      (VOID **) &PciIo,\r
+                      This->DriverBindingHandle,\r
+                      Controller,\r
+                      EFI_OPEN_PROTOCOL_BY_DRIVER\r
+                      );\r
 \r
-/**\r
-  Sets the USB host controller to a specific state according to UEFI 2.0 spec.\r
+  if (EFI_ERROR (OpenStatus)) {\r
+    return OpenStatus;\r
+  }\r
 \r
-  @param  This                 A pointer to the EFI_USB_HC_PROTOCOL instance.\r
-  @param  State                Indicates the state of the host controller that will\r
-                               be set.\r
-\r
-  @return EFI_SUCCESS           : Host controller was successfully placed in the state\r
-  @return EFI_INVALID_PARAMETER : State is invalid.\r
-  @return EFI_DEVICE_ERROR      : Failed to set the state\r
-\r
-**/\r
-STATIC\r
-EFI_STATUS\r
-EFIAPI\r
-Uhci2SetState (\r
-  IN EFI_USB2_HC_PROTOCOL    *This,\r
-  IN EFI_USB_HC_STATE        State\r
-  )\r
-{\r
-  USB_HC_DEV          *Uhc;\r
-\r
-  Uhc = UHC_FROM_USB2_HC_PROTO (This);\r
-  return UhciSetState (&Uhc->UsbHc, State);\r
-}\r
-\r
-\r
-/**\r
-  Retrieves capabilities of USB host controller according to UEFI 2.0 spec.\r
-\r
-  @param  This                 A pointer to the EFI_USB2_HC_PROTOCOL instance\r
-  @param  MaxSpeed             A pointer to the max speed USB host controller\r
-                               supports.\r
-  @param  PortNumber           A pointer to the number of root hub ports.\r
-  @param  Is64BitCapable       A pointer to an integer to show whether USB host\r
-                               controller supports 64-bit memory addressing.\r
-\r
-  @return EFI_SUCCESS           : capabilities were retrieved successfully.\r
-  @return EFI_INVALID_PARAMETER : MaxSpeed or PortNumber or Is64BitCapable is NULL.\r
-  @return EFI_DEVICE_ERROR      : An error was encountered\r
-\r
-**/\r
-STATIC\r
-EFI_STATUS\r
-EFIAPI\r
-Uhci2GetCapability (\r
-  IN  EFI_USB2_HC_PROTOCOL  *This,\r
-  OUT UINT8                 *MaxSpeed,\r
-  OUT UINT8                 *PortNumber,\r
-  OUT UINT8                 *Is64BitCapable\r
-  )\r
-{\r
-  USB_HC_DEV          *Uhc;\r
-\r
-  Uhc = UHC_FROM_USB2_HC_PROTO (This);\r
-\r
-  if ((NULL == MaxSpeed) || (NULL == PortNumber) || (NULL == Is64BitCapable)) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  *MaxSpeed       = EFI_USB_SPEED_FULL;\r
-  *Is64BitCapable = (UINT8) FALSE;\r
-\r
-  return UhciGetRootHubPortNumber (&Uhc->UsbHc, PortNumber);\r
-}\r
-\r
-\r
-/**\r
-  Retrieves the current status of a USB root hub port according to UEFI 2.0 spec.\r
-\r
-  @param  This                 A pointer to the EFI_USB2_HC_PROTOCOL.\r
-  @param  PortNumber           The port to get status\r
-  @param  PortStatus           A pointer to the current port status bits and  port\r
-                               status change bits.\r
-\r
-  @return EFI_SUCCESS           : status of the USB root hub port was returned in PortStatus.\r
-  @return EFI_INVALID_PARAMETER : PortNumber is invalid.\r
-  @return EFI_DEVICE_ERROR      : Can't read register\r
-\r
-**/\r
-STATIC\r
-EFI_STATUS\r
-EFIAPI\r
-Uhci2GetRootHubPortStatus (\r
-  IN  CONST EFI_USB2_HC_PROTOCOL   *This,\r
-  IN  CONST UINT8                  PortNumber,\r
-  OUT       EFI_USB_PORT_STATUS    *PortStatus\r
-  )\r
-{\r
-  USB_HC_DEV          *Uhc;\r
-\r
-  Uhc = UHC_FROM_USB2_HC_PROTO (This);\r
-\r
-  return UhciGetRootHubPortStatus (&Uhc->UsbHc, PortNumber, PortStatus);\r
-}\r
-\r
-\r
-/**\r
-  Sets a feature for the specified root hub port according to UEFI 2.0 spec.\r
-\r
-  @param  This                 A pointer to the EFI_USB2_HC_PROTOCOL.\r
-  @param  PortNumber           Specifies the root hub port whose feature  is\r
-                               requested to be set.\r
-  @param  PortFeature          Indicates the feature selector associated  with the\r
-                               feature set request.\r
-\r
-  @return EFI_SUCCESS           : PortFeature was set for the root port\r
-  @return EFI_INVALID_PARAMETER : PortNumber is invalid or PortFeature is invalid.\r
-  @return EFI_DEVICE_ERROR      : Can't read register\r
-\r
-**/\r
-STATIC\r
-EFI_STATUS\r
-EFIAPI\r
-Uhci2SetRootHubPortFeature (\r
-  IN EFI_USB2_HC_PROTOCOL    *This,\r
-  IN UINT8                   PortNumber,\r
-  IN EFI_USB_PORT_FEATURE    PortFeature\r
-  )\r
-{\r
-  USB_HC_DEV          *Uhc;\r
-\r
-  Uhc = UHC_FROM_USB2_HC_PROTO (This);\r
-\r
-  return UhciSetRootHubPortFeature (&Uhc->UsbHc, PortNumber, PortFeature);\r
-}\r
-\r
-\r
-/**\r
-  Clears a feature for the specified root hub port according to Uefi 2.0 spec.\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
-\r
-  @return EFI_SUCCESS           : PortFeature was cleared for the USB root hub port\r
-  @return EFI_INVALID_PARAMETER : PortNumber is invalid or PortFeature is invalid.\r
-  @return EFI_DEVICE_ERROR      : Can't read register\r
-\r
-**/\r
-STATIC\r
-EFI_STATUS\r
-EFIAPI\r
-Uhci2ClearRootHubPortFeature (\r
-  IN EFI_USB2_HC_PROTOCOL    *This,\r
-  IN UINT8                   PortNumber,\r
-  IN EFI_USB_PORT_FEATURE    PortFeature\r
-  )\r
-{\r
-  USB_HC_DEV          *Uhc;\r
-\r
-  Uhc = UHC_FROM_USB2_HC_PROTO (This);\r
-\r
-  return UhciClearRootHubPortFeature (&Uhc->UsbHc, PortNumber, PortFeature);\r
-}\r
-\r
-\r
-/**\r
-  Submits control transfer to a target USB device accroding to UEFI 2.0 spec..\r
-\r
-  This                : A pointer to the EFI_USB2_HC_PROTOCOL instance.\r
-  DeviceAddress       : Target device address\r
-  DeviceSpeed         : Device speed\r
-  MaximumPacketLength : Maximum packet size of the target endpoint\r
-  Request             : USB device request to send\r
-  TransferDirection   : Data direction of the Data stage in control transfer\r
-  Data                : Data to transmit/receive in data stage\r
-  DataLength          : Length of the data\r
-  TimeOut             : Maximum time, in microseconds, for transfer to complete.\r
-  TransferResult      : Variable to receive the transfer result\r
-\r
-  @return EFI_SUCCESS           : The control transfer was completed successfully.\r
-  @return EFI_OUT_OF_RESOURCES  : Failed due to lack of resource.\r
-  @return EFI_INVALID_PARAMETER : Some parameters are invalid.\r
-  @return EFI_TIMEOUT           : Failed due to timeout.\r
-  @return EFI_DEVICE_ERROR      : Failed due to host controller or device error.\r
-\r
-**/\r
-STATIC\r
-EFI_STATUS\r
-EFIAPI\r
-Uhci2ControlTransfer (\r
-  IN     EFI_USB2_HC_PROTOCOL                 *This,\r
-  IN     UINT8                                DeviceAddress,\r
-  IN     UINT8                                DeviceSpeed,\r
-  IN     UINTN                                MaximumPacketLength,\r
-  IN     EFI_USB_DEVICE_REQUEST               *Request,\r
-  IN     EFI_USB_DATA_DIRECTION               TransferDirection,\r
-  IN OUT VOID                                 *Data,\r
-  IN OUT UINTN                                *DataLength,\r
-  IN     UINTN                                TimeOut,\r
-  IN     EFI_USB2_HC_TRANSACTION_TRANSLATOR   *Translator,\r
-  OUT    UINT32                               *TransferResult\r
-  )\r
-{\r
-  USB_HC_DEV          *Uhc;\r
-  BOOLEAN             IsSlow;\r
-\r
-  Uhc     = UHC_FROM_USB2_HC_PROTO (This);\r
-  IsSlow  = (EFI_USB_SPEED_LOW == DeviceSpeed) ? TRUE : FALSE;\r
-\r
-  return UhciControlTransfer (\r
-           &Uhc->UsbHc,\r
-           DeviceAddress,\r
-           IsSlow,\r
-           (UINT8) MaximumPacketLength,\r
-           Request,\r
-           TransferDirection,\r
-           Data,\r
-           DataLength,\r
-           TimeOut,\r
-           TransferResult\r
-           );\r
-}\r
-\r
-\r
-/**\r
-  Submits bulk transfer to a bulk endpoint of a USB device\r
-\r
-  This                : A pointer to the EFI_USB2_HC_PROTOCOL instance.\r
-  DeviceAddress       : Target device address\r
-  EndPointAddress     : Endpoint number and direction\r
-  DeviceSpeed         : Device speed\r
-  MaximumPacketLength : Maximum packet size of the target endpoint\r
-  DataBuffersNumber   : Number of data buffers prepared for the transfer.\r
-  Data                : Array of pointers to the buffers of data\r
-  DataLength          : On input, size of the data buffer, On output,\r
-  actually transferred data size.\r
-  DataToggle          : On input, data toggle to use; On output, next data toggle\r
-  Translator          : A pointr to the transaction translator data.\r
-  TimeOut             : Maximum time out, in microseconds\r
-  TransferResult      : Variable to receive transfer result\r
-\r
-  @return EFI_SUCCESS           : The bulk transfer was completed successfully.\r
-  @return EFI_OUT_OF_RESOURCES  : Failed due to lack of resource.\r
-  @return EFI_INVALID_PARAMETER : Some parameters are invalid.\r
-  @return EFI_TIMEOUT           : Failed due to timeout.\r
-  @return EFI_DEVICE_ERROR      : Failed due to host controller or device error.\r
-\r
-**/\r
-STATIC\r
-EFI_STATUS\r
-EFIAPI\r
-Uhci2BulkTransfer (\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     UINT8                              DataBuffersNumber,\r
-  IN OUT VOID                               *Data[EFI_USB_MAX_BULK_BUFFER_NUM],\r
-  IN OUT UINTN                              *DataLength,\r
-  IN OUT UINT8                              *DataToggle,\r
-  IN     UINTN                              TimeOut,\r
-  IN     EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,\r
-  OUT    UINT32                             *TransferResult\r
-  )\r
-{\r
-  USB_HC_DEV          *Uhc;\r
-\r
-  Uhc = UHC_FROM_USB2_HC_PROTO (This);\r
-\r
-  if (Data == NULL || DeviceSpeed == EFI_USB_SPEED_LOW) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  //\r
-  // For full-speed bulk transfers only the data pointed by Data[0] shall be used\r
-  //\r
-  return UhciBulkTransfer (\r
-           &Uhc->UsbHc,\r
-           DeviceAddress,\r
-           EndPointAddress,\r
-           (UINT8) MaximumPacketLength,\r
-           *Data,\r
-           DataLength,\r
-           DataToggle,\r
-           TimeOut,\r
-           TransferResult\r
-           );\r
-}\r
-\r
-\r
-/**\r
-  Submits an asynchronous interrupt transfer to an\r
-  interrupt endpoint of a USB device according to UEFI 2.0 spec.\r
-\r
-  This                : A pointer to the EFI_USB2_HC_PROTOCOL instance.\r
-  DeviceAddress       : Target device address\r
-  EndPointAddress     : Endpoint number and direction\r
-  DeviceSpeed         : Device speed\r
-  MaximumPacketLength : Maximum packet size of the target endpoint\r
-  IsNewTransfer       : If TRUE, submit a new transfer, if FALSE cancel old transfer\r
-  DataToggle          : On input, data toggle to use; On output, next data toggle\r
-  PollingInterval     : Interrupt poll rate in milliseconds\r
-  DataLength          : On input, size of the data buffer, On output,\r
-  actually transferred data size.\r
-  Translator          : A pointr to the transaction translator data.\r
-  CallBackFunction    : Function to call periodically\r
-  Context             : User context\r
-\r
-  @return EFI_SUCCESS           : Transfer was submitted\r
-  @return EFI_INVALID_PARAMETER : Some parameters are invalid.\r
-  @return EFI_OUT_OF_RESOURCES  : Failed due to a lack of resources.\r
-  @return EFI_DEVICE_ERROR      : Can't read register\r
-\r
-**/\r
-STATIC\r
-EFI_STATUS\r
-EFIAPI\r
-Uhci2AsyncInterruptTransfer (\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\r
-  )\r
-{\r
-  USB_HC_DEV          *Uhc;\r
-  BOOLEAN             IsSlow;\r
-\r
-  Uhc     = UHC_FROM_USB2_HC_PROTO (This);\r
-  IsSlow  = (EFI_USB_SPEED_LOW == DeviceSpeed) ? TRUE : FALSE;\r
-\r
-  return UhciAsyncInterruptTransfer (\r
-           &Uhc->UsbHc,\r
-           DeviceAddress,\r
-           EndPointAddress,\r
-           IsSlow,\r
-           (UINT8) MaximumPacketLength,\r
-           IsNewTransfer,\r
-           DataToggle,\r
-           PollingInterval,\r
-           DataLength,\r
-           CallBackFunction,\r
-           Context\r
-           );\r
-}\r
-\r
-\r
-/**\r
-  Submits synchronous interrupt transfer to an interrupt endpoint\r
-  of a USB device according to UEFI 2.0 spec.\r
-\r
-  This                : A pointer to the EFI_USB2_HC_PROTOCOL instance.\r
-  DeviceAddress       : Target device address\r
-  EndPointAddress     : Endpoint number and direction\r
-  DeviceSpeed         : Device speed\r
-  MaximumPacketLength : Maximum packet size of the target endpoint\r
-  DataBuffersNumber   : Number of data buffers prepared for the transfer.\r
-  Data                : Array of pointers to the buffers of data\r
-  DataLength          : On input, size of the data buffer, On output,\r
-  actually transferred data size.\r
-  DataToggle          : On input, data toggle to use; On output, next data toggle\r
-  TimeOut             : Maximum time out, in microseconds\r
-  Translator          : A pointr to the transaction translator data.\r
-  TransferResult      : Variable to receive transfer result\r
-\r
-  @return EFI_SUCCESS           : The transfer was completed successfully.\r
-  @return EFI_OUT_OF_RESOURCES  : Failed due to lack of resource.\r
-  @return EFI_INVALID_PARAMETER : Some parameters are invalid.\r
-  @return EFI_TIMEOUT           : Failed due to timeout.\r
-  @return EFI_DEVICE_ERROR      : Failed due to host controller or device error.\r
-\r
-**/\r
-STATIC\r
-EFI_STATUS\r
-EFIAPI\r
-Uhci2SyncInterruptTransfer (\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 OUT VOID                                      *Data,\r
-  IN OUT UINTN                                     *DataLength,\r
-  IN OUT UINT8                                     *DataToggle,\r
-  IN     UINTN                                     TimeOut,\r
-  IN     EFI_USB2_HC_TRANSACTION_TRANSLATOR        *Translator,\r
-  OUT    UINT32                                    *TransferResult\r
-  )\r
-{\r
-  USB_HC_DEV          *Uhc;\r
-  BOOLEAN             IsSlow;\r
-\r
-  if (DeviceSpeed == EFI_USB_SPEED_HIGH) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  Uhc     = UHC_FROM_USB2_HC_PROTO (This);\r
-  IsSlow  = (EFI_USB_SPEED_LOW == DeviceSpeed) ? TRUE : FALSE;\r
-\r
-  return UhciSyncInterruptTransfer (\r
-           &Uhc->UsbHc,\r
-           DeviceAddress,\r
-           EndPointAddress,\r
-           IsSlow,\r
-           (UINT8) MaximumPacketLength,\r
-           Data,\r
-           DataLength,\r
-           DataToggle,\r
-           TimeOut,\r
-           TransferResult\r
-           );\r
-}\r
-\r
-\r
-/**\r
-  Submits isochronous transfer to a target USB device according to UEFI 2.0 spec.\r
-\r
-  This                : A pointer to the EFI_USB2_HC_PROTOCOL instance.\r
-  DeviceAddress       : Target device address\r
-  EndPointAddress     : Endpoint number and direction\r
-  DeviceSpeed         : Device speed\r
-  MaximumPacketLength : Maximum packet size of the target endpoint\r
-  DataBuffersNumber   : Number of data buffers prepared for the transfer.\r
-  Data                : Array of pointers to the buffers of data\r
-  DataLength          : On input, size of the data buffer, On output,\r
-  actually transferred data size.\r
-  Translator          : A pointr to the transaction translator data.\r
-  TransferResult      : Variable to receive transfer result\r
-\r
-  @return EFI_UNSUPPORTED\r
-\r
-**/\r
-STATIC\r
-EFI_STATUS\r
-EFIAPI\r
-Uhci2IsochronousTransfer (\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     UINT8                              DataBuffersNumber,\r
-  IN OUT VOID                               *Data[EFI_USB_MAX_ISO_BUFFER_NUM],\r
-  IN     UINTN                              DataLength,\r
-  IN     EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,\r
-  OUT    UINT32                             *TransferResult\r
-  )\r
-{\r
-  return EFI_UNSUPPORTED;\r
-}\r
-\r
-\r
-/**\r
-  Submits Async isochronous transfer to a target USB device according to UEFI 2.0 spec.\r
-\r
-  This                : A pointer to the EFI_USB2_HC_PROTOCOL instance.\r
-  DeviceAddress       : Target device address\r
-  EndPointAddress     : Endpoint number and direction\r
-  DeviceSpeed         : Device speed\r
-  MaximumPacketLength : Maximum packet size of the target endpoint\r
-  DataBuffersNumber   : Number of data buffers prepared for the transfer.\r
-  Data                : Array of pointers to the buffers of data\r
-  Translator          : A pointr to the transaction translator data.\r
-  IsochronousCallBack : Function to call when the transfer complete\r
-  Context             : Pass to the call back function as parameter\r
-\r
-  @return EFI_UNSUPPORTED\r
-\r
-**/\r
-STATIC\r
-EFI_STATUS\r
-EFIAPI\r
-Uhci2AsyncIsochronousTransfer (\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     UINT8                               DataBuffersNumber,\r
-  IN OUT VOID                                *Data[EFI_USB_MAX_ISO_BUFFER_NUM],\r
-  IN     UINTN                               DataLength,\r
-  IN     EFI_USB2_HC_TRANSACTION_TRANSLATOR  *Translator,\r
-  IN     EFI_ASYNC_USB_TRANSFER_CALLBACK     IsochronousCallBack,\r
-  IN     VOID                                *Context\r
-  )\r
-{\r
-  return EFI_UNSUPPORTED;\r
-}\r
-\r
-//@MT: EFI_DRIVER_ENTRY_POINT (UhciDriverEntryPoint)\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-UhciDriverEntryPoint (\r
-  IN EFI_HANDLE           ImageHandle,\r
-  IN EFI_SYSTEM_TABLE     *SystemTable\r
-  )\r
-/*++\r
-\r
-  Routine Description:\r
-\r
-    Entry point for EFI drivers.\r
-\r
-  Arguments:\r
-\r
-    ImageHandle - EFI_HANDLE\r
-    SystemTable - EFI_SYSTEM_TABLE\r
-\r
-  Returns:\r
-\r
-    EFI_SUCCESS : Driver is successfully loaded\r
-    Others      : Failed\r
-\r
---*/\r
-{\r
-  return EfiLibInstallAllDriverProtocols (\r
-           ImageHandle,\r
-           SystemTable,\r
-           &gUhciDriverBinding,\r
-           ImageHandle,\r
-           &gUhciComponentName,\r
-           NULL,\r
-           NULL\r
-           );\r
-}\r
-\r
-\r
-/**\r
-  Test to see if this driver supports ControllerHandle. Any\r
-  ControllerHandle that has UsbHcProtocol installed will be supported.\r
-\r
-  @param  This                 Protocol instance pointer.\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
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-UhciDriverBindingSupported (\r
-  IN EFI_DRIVER_BINDING_PROTOCOL     *This,\r
-  IN EFI_HANDLE                      Controller,\r
-  IN EFI_DEVICE_PATH_PROTOCOL        *RemainingDevicePath\r
-  )\r
-{\r
-  EFI_STATUS            OpenStatus;\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
-  //\r
-  OpenStatus = gBS->OpenProtocol (\r
-                      Controller,\r
-                      &gEfiPciIoProtocolGuid,\r
-                      &PciIo,\r
-                      This->DriverBindingHandle,\r
-                      Controller,\r
-                      EFI_OPEN_PROTOCOL_BY_DRIVER\r
-                      );\r
-\r
-  if (EFI_ERROR (OpenStatus)) {\r
-    return OpenStatus;\r
-  }\r
-\r
-  Status = PciIo->Pci.Read (\r
-                        PciIo,\r
-                        EfiPciIoWidthUint8,\r
-                        CLASSC_OFFSET,\r
-                        sizeof (USB_CLASSC) / sizeof (UINT8),\r
-                        &UsbClassCReg\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
@@ -1925,7 +1395,7 @@ UhciDriverBindingSupported (
   //\r
   if ((UsbClassCReg.BaseCode != PCI_CLASS_SERIAL) ||\r
       (UsbClassCReg.SubClassCode != PCI_CLASS_SERIAL_USB) ||\r
-      (UsbClassCReg.PI != PCI_CLASSC_PI_UHCI)\r
+      (UsbClassCReg.ProgInterface != PCI_IF_UHCI)\r
       ) {\r
 \r
     Status = EFI_UNSUPPORTED;\r
@@ -1945,17 +1415,18 @@ ON_EXIT:
 \r
 \r
 /**\r
-  Allocate and initialize the empty UHCI device\r
+  Allocate and initialize the empty UHCI device.\r
 \r
-  @param  PciIo                The PCIIO to use\r
+  @param  PciIo                  The PCIIO to use.\r
+  @param  OriginalPciAttributes  The original PCI attributes.\r
 \r
-  @return Allocated UHCI device\r
+  @return Allocated UHCI device. If err, return NULL.\r
 \r
 **/\r
-STATIC\r
 USB_HC_DEV *\r
 UhciAllocateDev (\r
-  IN EFI_PCI_IO_PROTOCOL    *PciIo\r
+  IN EFI_PCI_IO_PROTOCOL    *PciIo,\r
+  IN UINT64                 OriginalPciAttributes\r
   )\r
 {\r
   USB_HC_DEV  *Uhc;\r
@@ -1972,22 +1443,6 @@ UhciAllocateDev (
   // USB_HC_PROTOCOL is for EFI 1.1 backward compability.\r
   //\r
   Uhc->Signature                        = USB_HC_DEV_SIGNATURE;\r
-  Uhc->UsbHc.Reset                      = UhciReset;\r
-  Uhc->UsbHc.GetState                   = UhciGetState;\r
-  Uhc->UsbHc.SetState                   = UhciSetState;\r
-  Uhc->UsbHc.ControlTransfer            = UhciControlTransfer;\r
-  Uhc->UsbHc.BulkTransfer               = UhciBulkTransfer;\r
-  Uhc->UsbHc.AsyncInterruptTransfer     = UhciAsyncInterruptTransfer;\r
-  Uhc->UsbHc.SyncInterruptTransfer      = UhciSyncInterruptTransfer;\r
-  Uhc->UsbHc.IsochronousTransfer        = UhciIsochronousTransfer;\r
-  Uhc->UsbHc.AsyncIsochronousTransfer   = UhciAsyncIsochronousTransfer;\r
-  Uhc->UsbHc.GetRootHubPortNumber       = UhciGetRootHubPortNumber;\r
-  Uhc->UsbHc.GetRootHubPortStatus       = UhciGetRootHubPortStatus;\r
-  Uhc->UsbHc.SetRootHubPortFeature      = UhciSetRootHubPortFeature;\r
-  Uhc->UsbHc.ClearRootHubPortFeature    = UhciClearRootHubPortFeature;\r
-  Uhc->UsbHc.MajorRevision              = 0x1;\r
-  Uhc->UsbHc.MinorRevision              = 0x1;\r
-\r
   Uhc->Usb2Hc.GetCapability             = Uhci2GetCapability;\r
   Uhc->Usb2Hc.Reset                     = Uhci2Reset;\r
   Uhc->Usb2Hc.GetState                  = Uhci2GetState;\r
@@ -2004,8 +1459,9 @@ UhciAllocateDev (
   Uhc->Usb2Hc.MajorRevision             = 0x1;\r
   Uhc->Usb2Hc.MinorRevision             = 0x1;\r
 \r
-  Uhc->PciIo   = PciIo;\r
-  Uhc->MemPool = UsbHcInitMemPool (PciIo, TRUE, 0);\r
+  Uhc->PciIo                 = PciIo;\r
+  Uhc->OriginalPciAttributes = OriginalPciAttributes;\r
+  Uhc->MemPool               = UsbHcInitMemPool (PciIo, TRUE, 0);\r
 \r
   if (Uhc->MemPool == NULL) {\r
     Status = EFI_OUT_OF_RESOURCES;\r
@@ -2030,20 +1486,17 @@ UhciAllocateDev (
   return Uhc;\r
 \r
 ON_ERROR:\r
-  gBS->FreePool (Uhc);\r
+  FreePool (Uhc);\r
   return NULL;\r
 }\r
 \r
 \r
 /**\r
-  Free the UHCI device and release its associated resources\r
-\r
-  @param  Uhc                  The UHCI device to release\r
+  Free the UHCI device and release its associated resources.\r
 \r
-  @return None\r
+  @param  Uhc     The UHCI device to release.\r
 \r
 **/\r
-STATIC\r
 VOID\r
 UhciFreeDev (\r
   IN USB_HC_DEV           *Uhc\r
@@ -2053,32 +1506,33 @@ UhciFreeDev (
     gBS->CloseEvent (Uhc->AsyncIntMonitor);\r
   }\r
 \r
+  if (Uhc->ExitBootServiceEvent != NULL) {\r
+    gBS->CloseEvent (Uhc->ExitBootServiceEvent);\r
+  }\r
+  \r
   if (Uhc->MemPool != NULL) {\r
     UsbHcFreeMemPool (Uhc->MemPool);\r
   }\r
 \r
-  if (Uhc->CtrlNameTable) {\r
+  if (Uhc->CtrlNameTable != NULL) {\r
     FreeUnicodeStringTable (Uhc->CtrlNameTable);\r
   }\r
 \r
-  gBS->FreePool (Uhc);\r
+  FreePool (Uhc);\r
 }\r
 \r
 \r
 /**\r
-  Uninstall all Uhci Interface\r
+  Uninstall all Uhci Interface.\r
 \r
-  @param  Controller           Controller handle\r
+  @param  Controller           Controller handle.\r
   @param  This                 Protocol instance pointer.\r
 \r
-  @return VOID\r
-\r
 **/\r
-STATIC\r
 VOID\r
 UhciCleanDevUp (\r
-  IN  EFI_HANDLE          Controller,\r
-  IN  EFI_USB_HC_PROTOCOL *This\r
+  IN  EFI_HANDLE           Controller,\r
+  IN  EFI_USB2_HC_PROTOCOL *This\r
   )\r
 {\r
   USB_HC_DEV          *Uhc;\r
@@ -2086,14 +1540,8 @@ UhciCleanDevUp (
   //\r
   // Uninstall the USB_HC and USB_HC2 protocol, then disable the controller\r
   //\r
-  Uhc = UHC_FROM_USB_HC_PROTO (This);\r
-  UhciStopHc (Uhc, STALL_1_SECOND);\r
-\r
-  gBS->UninstallProtocolInterface (\r
-        Controller,\r
-        &gEfiUsbHcProtocolGuid,\r
-        &Uhc->UsbHc\r
-        );\r
+  Uhc = UHC_FROM_USB2_HC_PROTO (This);\r
+  UhciStopHc (Uhc, UHC_GENERIC_TIMEOUT);\r
 \r
   gBS->UninstallProtocolInterface (\r
         Controller,\r
@@ -2104,29 +1552,56 @@ UhciCleanDevUp (
   UhciFreeAllAsyncReq (Uhc);\r
   UhciDestoryFrameList (Uhc);\r
 \r
+  //\r
+  // Restore original PCI attributes\r
+  //\r
   Uhc->PciIo->Attributes (\r
-                Uhc->PciIo,\r
-                EfiPciIoAttributeOperationDisable,\r
-                EFI_PCI_DEVICE_ENABLE,\r
-                NULL\r
-                );\r
+                  Uhc->PciIo,\r
+                  EfiPciIoAttributeOperationSet,\r
+                  Uhc->OriginalPciAttributes,\r
+                  NULL\r
+                  );\r
 \r
   UhciFreeDev (Uhc);\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 hanlder private data\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+UhcExitBootService (\r
+  EFI_EVENT                      Event,\r
+  VOID                           *Context\r
+  )\r
+{\r
+  USB_HC_DEV   *Uhc;\r
+\r
+  Uhc = (USB_HC_DEV *) Context;\r
+\r
+  //\r
+  // Stop the Host Controller\r
+  //\r
+  UhciStopHc (Uhc, UHC_GENERIC_TIMEOUT);\r
+\r
+  return;\r
+}\r
 \r
 /**\r
-  Starting the Usb UHCI Driver\r
+  Starting the Usb UHCI 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
   @retval EFI_SUCCESS          This driver supports this device.\r
   @retval EFI_UNSUPPORTED      This driver does not support this device.\r
-  @retval EFI_DEVICE_ERROR     This driver cannot be started due to device Error\r
-                               EFI_OUT_OF_RESOURCES- Failed due to resource\r
-                               shortage\r
+  @retval EFI_DEVICE_ERROR     This driver cannot be started due to device Error.\r
+                               EFI_OUT_OF_RESOURCES- Failed due to resource shortage.\r
 \r
 **/\r
 EFI_STATUS\r
@@ -2140,6 +1615,9 @@ UhciDriverBindingStart (
   EFI_STATUS          Status;\r
   EFI_PCI_IO_PROTOCOL *PciIo;\r
   USB_HC_DEV          *Uhc;\r
+  UINT64              Supports;\r
+  UINT64              OriginalPciAttributes;\r
+  BOOLEAN             PciAttributesSaved;\r
 \r
   //\r
   // Open PCIIO, then enable the EHC device and turn off emulation\r
@@ -2148,7 +1626,7 @@ UhciDriverBindingStart (
   Status = gBS->OpenProtocol (\r
                   Controller,\r
                   &gEfiPciIoProtocolGuid,\r
-                  &PciIo,\r
+                  (VOID **) &PciIo,\r
                   This->DriverBindingHandle,\r
                   Controller,\r
                   EFI_OPEN_PROTOCOL_BY_DRIVER\r
@@ -2158,20 +1636,51 @@ UhciDriverBindingStart (
     return Status;\r
   }\r
 \r
-  UhciTurnOffUsbEmulation (PciIo);\r
+  PciAttributesSaved = FALSE;\r
+  //\r
+  // Save original PCI attributes\r
+  //\r
+  Status = PciIo->Attributes (\r
+                    PciIo,\r
+                    EfiPciIoAttributeOperationGet,\r
+                    0,\r
+                    &OriginalPciAttributes\r
+                    );\r
+\r
+  if (EFI_ERROR (Status)) {\r
+    goto CLOSE_PCIIO;\r
+  }\r
+  PciAttributesSaved = TRUE;\r
+\r
+  //\r
+  // Robustnesss improvement such as for UoL\r
+  // Default is not required.\r
+  //\r
+  if (FeaturePcdGet (PcdTurnOffUsbLegacySupport)) {\r
+    UhciTurnOffUsbEmulation (PciIo);\r
+  }\r
 \r
   Status = PciIo->Attributes (\r
                     PciIo,\r
-                    EfiPciIoAttributeOperationEnable,\r
-                    EFI_PCI_DEVICE_ENABLE,\r
-                    NULL\r
+                    EfiPciIoAttributeOperationSupported,\r
+                    0,\r
+                    &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
+  }\r
 \r
   if (EFI_ERROR (Status)) {\r
     goto CLOSE_PCIIO;\r
   }\r
 \r
-  Uhc = UhciAllocateDev (PciIo);\r
+  Uhc = UhciAllocateDev (PciIo, OriginalPciAttributes);\r
 \r
   if (Uhc == NULL) {\r
     Status = EFI_OUT_OF_RESOURCES;\r
@@ -2191,7 +1700,7 @@ UhciDriverBindingStart (
   Status = gBS->SetTimer (\r
                   Uhc->AsyncIntMonitor,\r
                   TimerPeriodic,\r
-                  INTERRUPT_POLLING_TIME\r
+                  UHC_ASYNC_POLL_INTERVAL\r
                   );\r
 \r
   if (EFI_ERROR (Status)) {\r
@@ -2199,12 +1708,10 @@ UhciDriverBindingStart (
   }\r
 \r
   //\r
-  // Install both USB_HC_PROTOCOL and USB2_HC_PROTOCOL\r
+  // Install USB2_HC_PROTOCOL\r
   //\r
   Status = gBS->InstallMultipleProtocolInterfaces (\r
                   &Controller,\r
-                  &gEfiUsbHcProtocolGuid,\r
-                  &Uhc->UsbHc,\r
                   &gEfiUsb2HcProtocolGuid,\r
                   &Uhc->Usb2Hc,\r
                   NULL\r
@@ -2214,17 +1721,41 @@ UhciDriverBindingStart (
     goto FREE_UHC;\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
+                  UhcExitBootService,\r
+                  Uhc,\r
+                  &gEfiEventExitBootServicesGuid,\r
+                  &Uhc->ExitBootServiceEvent\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    goto UNINSTALL_USBHC;\r
+  }\r
+\r
   //\r
   // Install the component name protocol\r
   //\r
   Uhc->CtrlNameTable = NULL;\r
 \r
-  AddUnicodeString (\r
+  AddUnicodeString2 (\r
     "eng",\r
     gUhciComponentName.SupportedLanguages,\r
     &Uhc->CtrlNameTable,\r
-    L"Usb Universal Host Controller"\r
+    L"Usb Universal Host Controller",\r
+    TRUE\r
     );\r
+  AddUnicodeString2 (\r
+    "en",\r
+    gUhciComponentName2.SupportedLanguages,\r
+    &Uhc->CtrlNameTable,\r
+    L"Usb Universal Host Controller",\r
+    FALSE\r
+    );\r
+\r
 \r
   //\r
   // Start the UHCI hardware, also set its reclamation point to 64 bytes\r
@@ -2232,11 +1763,31 @@ UhciDriverBindingStart (
   UhciWriteReg (Uhc->PciIo, USBCMD_OFFSET, USBCMD_RS | USBCMD_MAXP);\r
 \r
   return EFI_SUCCESS;\r
+  \r
+UNINSTALL_USBHC:\r
+  gBS->UninstallMultipleProtocolInterfaces (\r
+         Controller,\r
+         &gEfiUsb2HcProtocolGuid,\r
+         &Uhc->Usb2Hc,\r
+         NULL\r
+         );\r
 \r
 FREE_UHC:\r
   UhciFreeDev (Uhc);\r
 \r
 CLOSE_PCIIO:\r
+  if (PciAttributesSaved) {\r
+    //\r
+    // Restore original PCI attributes\r
+    //\r
+    PciIo->Attributes (\r
+                    PciIo,\r
+                    EfiPciIoAttributeOperationSet,\r
+                    OriginalPciAttributes,\r
+                    NULL\r
+                    );\r
+  }\r
+\r
   gBS->CloseProtocol (\r
         Controller,\r
         &gEfiPciIoProtocolGuid,\r
@@ -2253,8 +1804,8 @@ CLOSE_PCIIO:
   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\r
@@ -2270,31 +1821,13 @@ UhciDriverBindingStop (
   IN EFI_HANDLE                      *ChildHandleBuffer\r
   )\r
 {\r
-  EFI_USB_HC_PROTOCOL   *UsbHc;\r
   EFI_USB2_HC_PROTOCOL  *Usb2Hc;\r
   EFI_STATUS            Status;\r
 \r
-  Status = gBS->OpenProtocol (\r
-                  Controller,\r
-                  &gEfiUsbHcProtocolGuid,\r
-                  &UsbHc,\r
-                  This->DriverBindingHandle,\r
-                  Controller,\r
-                  EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
-                  );\r
-  //\r
-  // Test whether the Controller handler passed in is a valid\r
-  // Usb controller handle that should be supported, if not,\r
-  // return the error status directly\r
-  //\r
-  if (EFI_ERROR (Status)) {\r
-    return Status;\r
-  }\r
-\r
-  Status = gBS->OpenProtocol (\r
+   Status = gBS->OpenProtocol (\r
                   Controller,\r
                   &gEfiUsb2HcProtocolGuid,\r
-                  &Usb2Hc,\r
+                  (VOID **) &Usb2Hc,\r
                   This->DriverBindingHandle,\r
                   Controller,\r
                   EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
@@ -2309,7 +1842,7 @@ UhciDriverBindingStop (
     return Status;\r
   }\r
 \r
-  UhciCleanDevUp (Controller, UsbHc);\r
+  UhciCleanDevUp (Controller, Usb2Hc);\r
 \r
   gBS->CloseProtocol (\r
         Controller,\r
@@ -2321,11 +1854,3 @@ UhciDriverBindingStop (
   return EFI_SUCCESS;\r
 }\r
 \r
-EFI_DRIVER_BINDING_PROTOCOL gUhciDriverBinding = {\r
-  UhciDriverBindingSupported,\r
-  UhciDriverBindingStart,\r
-  UhciDriverBindingStop,\r
-  0x20,\r
-  NULL,\r
-  NULL\r
-};\r