]> git.proxmox.com Git - mirror_edk2.git/blobdiff - EdkModulePkg/Bus/Usb/UsbBus/Dxe/usbbus.c
Add DevicePathUtilities DevicePathToText DevciePathFromText USB2HostController protocols
[mirror_edk2.git] / EdkModulePkg / Bus / Usb / UsbBus / Dxe / usbbus.c
index f4ac69e13f13b6dd7211e3ea22fdf6bd7647a4aa..1d1f44d63874e30f8cba948cb31ad857be97f808 100644 (file)
@@ -23,10 +23,9 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 \r
 #include "usbbus.h"\r
 \r
-//#ifdef EFI_DEBUG\r
-UINTN                       gUSBDebugLevel  = EFI_D_ERROR;\r
+UINTN                       gUSBDebugLevel  = EFI_D_INFO;\r
 UINTN                       gUSBErrorLevel  = EFI_D_ERROR;\r
-//#endif\r
+\r
 //\r
 // The UsbBusProtocol is just used to locate USB_BUS_CONTROLLER\r
 // structure in the UsbBusDriverControllerDriverStop(). Then we can\r
@@ -121,17 +120,52 @@ UsbDeviceConfiguration (
 //\r
 STATIC\r
 VOID\r
-EFIAPI\r
-UsbEnumeration (\r
+RootHubEnumeration (\r
+  IN EFI_EVENT     Event,\r
+  IN VOID          *Context\r
+  );\r
+\r
+STATIC\r
+VOID\r
+HubEnumeration (\r
   IN EFI_EVENT     Event,\r
   IN VOID          *Context\r
   );\r
 \r
+STATIC\r
+EFI_STATUS\r
+UsbSetTransactionTranslator (\r
+  IN USB_IO_CONTROLLER_DEVICE     *ParentHubController,\r
+  IN UINT8                        ParentPort,\r
+  IN OUT USB_IO_DEVICE            *Device\r
+  );\r
+\r
+STATIC\r
+EFI_STATUS\r
+UsbUnsetTransactionTranslator (\r
+  USB_IO_DEVICE *Device\r
+  );\r
+\r
+STATIC\r
+EFI_STATUS\r
+IdentifyDeviceSpeed (\r
+  USB_BUS_CONTROLLER_DEVICE *UsbBusDev,\r
+  USB_IO_DEVICE             *NewDevice,\r
+  UINT8                     Index\r
+  );\r
+\r
+STATIC\r
+EFI_STATUS\r
+ReleasePortToCHC (\r
+  USB_BUS_CONTROLLER_DEVICE *UsbBusDev,\r
+  UINT8                     PortNum\r
+  );\r
+\r
 EFI_STATUS\r
 ResetRootPort (\r
-  IN EFI_USB_HC_PROTOCOL     *UsbHCInterface,\r
-  IN UINT8                   PortNum,\r
-  IN UINT8                   RetryTimes\r
+  IN USB_BUS_CONTROLLER_DEVICE *UsbBusDev,\r
+  IN UINT8                     PortNum,\r
+  IN UINT8                     RetryTimes\r
   );\r
 \r
 EFI_STATUS\r
@@ -140,12 +174,6 @@ ResetHubPort (
   IN UINT8                       PortIndex\r
   );\r
 \r
-EFI_STATUS\r
-ClearRootPortConnectionChangeStatus (\r
-  IN UINT8                   PortNum,\r
-  IN EFI_USB_HC_PROTOCOL     *UsbHCInterface\r
-  );\r
-\r
 STATIC\r
 EFI_STATUS\r
 ParentPortReset (\r
@@ -162,6 +190,18 @@ UINT8
 UsbAllocateAddress (\r
   IN UINT8    *AddressPool\r
   )\r
+/*++\r
+\r
+  Routine Description:\r
+    Allocate address for usb device\r
+\r
+  Arguments:\r
+   AddressPool - Pool of usb device address\r
+\r
+  Returns:\r
+   Usb device address\r
+\r
+--*/\r
 {\r
   UINT8 ByteIndex;\r
   UINT8 BitIndex;\r
@@ -188,6 +228,19 @@ UsbFreeAddress (
   IN UINT8     DevAddress,\r
   IN UINT8     *AddressPool\r
   )\r
+/*++\r
+\r
+  Routine Description:\r
+    Free address for usb device\r
+\r
+  Arguments:\r
+   DevAddress  - Usb device address\r
+   AddressPool - Pool of usb device address\r
+   \r
+  Returns:\r
+   VOID\r
+\r
+--*/\r
 {\r
   UINT8 WhichByte;\r
   UINT8 WhichBit;\r
@@ -215,8 +268,8 @@ UsbBusControllerDriverSupported (
 \r
   Arguments:\r
     This                - Protocol instance pointer.\r
-    Controller         - Handle of device to test\r
-    RemainingDevicePath - Not used\r
+    Controller          - Handle of device to test\r
+    RemainingDevicePath - Device Path Protocol instance pointer\r
 \r
   Returns:\r
     EFI_SUCCESS         - This driver supports this device.\r
@@ -224,30 +277,103 @@ UsbBusControllerDriverSupported (
 \r
 --*/\r
 {\r
-  EFI_STATUS  OpenStatus;\r
+  EFI_STATUS                 Status;\r
+  EFI_DEVICE_PATH_PROTOCOL   *ParentDevicePath;\r
+  EFI_USB2_HC_PROTOCOL       *Usb2Hc;\r
+  EFI_USB_HC_PROTOCOL        *UsbHc;\r
+  EFI_DEV_PATH_PTR           Node;\r
+\r
+  //\r
+  // Check Device Path\r
+  //\r
+  if (RemainingDevicePath != NULL) {\r
+    Node.DevPath = RemainingDevicePath;\r
+    if (Node.DevPath->Type != MESSAGING_DEVICE_PATH ||\r
+        Node.DevPath->SubType != MSG_USB_DP         ||\r
+        DevicePathNodeLength(Node.DevPath) != sizeof(USB_DEVICE_PATH)) {\r
+      return EFI_UNSUPPORTED;\r
+    }\r
+  }\r
+  \r
+  //\r
+  // Open the IO Abstraction(s) needed to perform the supported test\r
+  //\r
+  Status = gBS->OpenProtocol (\r
+                  Controller,\r
+                  &gEfiDevicePathProtocolGuid,\r
+                  (VOID **) &ParentDevicePath,\r
+                  This->DriverBindingHandle,\r
+                  Controller,\r
+                  EFI_OPEN_PROTOCOL_BY_DRIVER\r
+                  );\r
+  if (Status == EFI_ALREADY_STARTED) {\r
+    return EFI_SUCCESS;\r
+  }\r
 \r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  gBS->CloseProtocol (\r
+         Controller,\r
+         &gEfiDevicePathProtocolGuid,\r
+         This->DriverBindingHandle,\r
+         Controller\r
+         );\r
+  \r
   //\r
   // Check whether USB Host Controller Protocol is already\r
   // installed on this handle. If it is installed, we can start\r
   // USB Bus Driver now.\r
   //\r
-  OpenStatus = gBS->OpenProtocol (\r
-                      Controller,\r
-                      &gEfiUsbHcProtocolGuid,\r
-                      NULL,\r
-                      This->DriverBindingHandle,\r
-                      Controller,\r
-                      EFI_OPEN_PROTOCOL_TEST_PROTOCOL\r
-                      );\r
+  Status = gBS->OpenProtocol (\r
+                  Controller,\r
+                  &gEfiUsb2HcProtocolGuid,\r
+                  (VOID **) &Usb2Hc,\r
+                  This->DriverBindingHandle,\r
+                  Controller,\r
+                  EFI_OPEN_PROTOCOL_BY_DRIVER\r
+                  );\r
+  if (Status == EFI_ALREADY_STARTED) {\r
+    return EFI_SUCCESS;\r
+  }\r
+  \r
+  if (EFI_ERROR (Status)) {\r
+    Status = gBS->OpenProtocol (\r
+                    Controller,\r
+                    &gEfiUsbHcProtocolGuid,\r
+                    (VOID **) &UsbHc,\r
+                    This->DriverBindingHandle,\r
+                    Controller,\r
+                    EFI_OPEN_PROTOCOL_BY_DRIVER\r
+                    );\r
+    if (Status == EFI_ALREADY_STARTED) {\r
+      return EFI_SUCCESS;\r
+    }\r
+\r
+    if (EFI_ERROR (Status)) {\r
+      return Status;\r
+    }\r
 \r
-  if (EFI_ERROR (OpenStatus) && (OpenStatus != EFI_ALREADY_STARTED)) {\r
-    return EFI_UNSUPPORTED;\r
+    gBS->CloseProtocol (\r
+      Controller,\r
+      &gEfiUsbHcProtocolGuid,\r
+      This->DriverBindingHandle,\r
+      Controller\r
+      );\r
+    return EFI_SUCCESS;\r
   }\r
+  \r
+  gBS->CloseProtocol (\r
+    Controller,\r
+    &gEfiUsb2HcProtocolGuid,\r
+    This->DriverBindingHandle,\r
+    Controller\r
+    );\r
 \r
-  return OpenStatus;\r
+  return EFI_SUCCESS;\r
 }\r
 \r
-\r
 EFI_STATUS\r
 EFIAPI\r
 UsbBusControllerDriverStart (\r
@@ -270,11 +396,8 @@ UsbBusControllerDriverStart (
   Returns:\r
 \r
     EFI_SUCCESS         - This driver supports this device.\r
-    EFI_UNSUPPORTED     - This driver does not support this device.\r
     EFI_DEVICE_ERROR    - This driver cannot be started due to device\r
-                          Error\r
     EFI_OUT_OF_RESOURCES- Can't allocate memory resources\r
-    EFI_ALREADY_STARTED - This driver has been started\r
 \r
 --*/\r
 {\r
@@ -283,7 +406,9 @@ UsbBusControllerDriverStart (
   USB_BUS_CONTROLLER_DEVICE *UsbBusDev;\r
   USB_IO_DEVICE             *RootHub;\r
   USB_IO_CONTROLLER_DEVICE  *RootHubController;\r
-  EFI_USB_HC_PROTOCOL       *UsbHCInterface;\r
+  UINT8                     MaxSpeed;\r
+  UINT8                     PortNumber;\r
+  UINT8                     Is64BitCapable;\r
 \r
   //\r
   // Allocate USB_BUS_CONTROLLER_DEVICE structure\r
@@ -311,54 +436,56 @@ UsbBusControllerDriverStart (
 \r
   if (EFI_ERROR (OpenStatus)) {\r
     gBS->FreePool (UsbBusDev);\r
-    return EFI_UNSUPPORTED;\r
+    return OpenStatus;\r
   }\r
   //\r
   // Locate the Host Controller Interface\r
   //\r
   OpenStatus = gBS->OpenProtocol (\r
                       Controller,\r
-                      &gEfiUsbHcProtocolGuid,\r
-                      (VOID **) &UsbHCInterface,\r
+                      &gEfiUsb2HcProtocolGuid,\r
+                      (VOID **) &(UsbBusDev->Usb2HCInterface),\r
                       This->DriverBindingHandle,\r
                       Controller,\r
                       EFI_OPEN_PROTOCOL_BY_DRIVER\r
                       );\r
+  if (EFI_ERROR (OpenStatus)) {\r
 \r
-  if (EFI_ERROR (OpenStatus) && (OpenStatus != EFI_ALREADY_STARTED)) {\r
-    \r
-    //\r
-    // Report Status Code here since we will reset the host controller\r
-    //\r
-    REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
-      EFI_ERROR_CODE | EFI_ERROR_MINOR,\r
-      EFI_IO_BUS_USB | EFI_IOB_EC_CONTROLLER_ERROR,\r
-      UsbBusDev->DevicePath\r
-      );\r
+    UsbBusDev->Hc2ProtocolSupported = FALSE;\r
+    OpenStatus = gBS->OpenProtocol (\r
+                        Controller,\r
+                        &gEfiUsbHcProtocolGuid,\r
+                        (VOID **) &(UsbBusDev->UsbHCInterface),\r
+                        This->DriverBindingHandle,\r
+                        Controller,\r
+                        EFI_OPEN_PROTOCOL_BY_DRIVER\r
+                        );\r
+    if (EFI_ERROR (OpenStatus)) {\r
+      //\r
+      // Report Status Code here since we will reset the host controller\r
+      //\r
+      REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
+        EFI_ERROR_CODE | EFI_ERROR_MINOR,\r
+        EFI_IO_BUS_USB | EFI_IOB_EC_CONTROLLER_ERROR,\r
+        UsbBusDev->DevicePath\r
+        );\r
 \r
-    gBS->CloseProtocol (\r
-           Controller,\r
-           &gEfiDevicePathProtocolGuid,\r
-           This->DriverBindingHandle,\r
-           Controller\r
-           );\r
-    gBS->FreePool (UsbBusDev);\r
-    return EFI_UNSUPPORTED;\r
-  }\r
+      gBS->CloseProtocol (\r
+             Controller,\r
+             &gEfiDevicePathProtocolGuid,\r
+             This->DriverBindingHandle,\r
+             Controller\r
+             );\r
+      gBS->FreePool (UsbBusDev);\r
+      return OpenStatus;\r
+    }\r
 \r
-  if (OpenStatus == EFI_ALREADY_STARTED) {\r
-    gBS->CloseProtocol (\r
-           Controller,\r
-           &gEfiDevicePathProtocolGuid,\r
-           This->DriverBindingHandle,\r
-           Controller\r
-           );\r
-    gBS->FreePool (UsbBusDev);\r
-    return EFI_ALREADY_STARTED;\r
+    DEBUG ((gUSBDebugLevel, "UsbHcProtocol Opened.\n"));\r
+  } else {\r
+    DEBUG ((gUSBDebugLevel, "Usb2HcProtocol Opened.\n"));\r
+    UsbBusDev->Hc2ProtocolSupported = TRUE;\r
   }\r
 \r
-  UsbBusDev->UsbHCInterface = UsbHCInterface;\r
-\r
   //\r
   // Attach EFI_USB_BUS_PROTOCOL to controller handle,\r
   // for locate UsbBusDev later\r
@@ -378,12 +505,22 @@ UsbBusControllerDriverStart (
            This->DriverBindingHandle,\r
            Controller\r
            );\r
-    gBS->CloseProtocol (\r
-           Controller,\r
-           &gEfiUsbHcProtocolGuid,\r
-           This->DriverBindingHandle,\r
-           Controller\r
-           );\r
+    if (UsbBusDev->Hc2ProtocolSupported) {\r
+      gBS->CloseProtocol (\r
+             Controller,\r
+             &gEfiUsb2HcProtocolGuid,\r
+             This->DriverBindingHandle,\r
+             Controller\r
+             );\r
+    } else {\r
+      gBS->CloseProtocol (\r
+             Controller,\r
+             &gEfiUsbHcProtocolGuid,\r
+             This->DriverBindingHandle,\r
+             Controller\r
+             );\r
+    }\r
+\r
     gBS->FreePool (UsbBusDev);\r
     return Status;\r
   }\r
@@ -404,12 +541,22 @@ UsbBusControllerDriverStart (
            This->DriverBindingHandle,\r
            Controller\r
            );\r
-    gBS->CloseProtocol (\r
-           Controller,\r
-           &gEfiUsbHcProtocolGuid,\r
-           This->DriverBindingHandle,\r
-           Controller\r
-           );\r
+    if (UsbBusDev->Hc2ProtocolSupported) {\r
+      gBS->CloseProtocol (\r
+             Controller,\r
+             &gEfiUsb2HcProtocolGuid,\r
+             This->DriverBindingHandle,\r
+             Controller\r
+             );\r
+    } else {\r
+      gBS->CloseProtocol (\r
+             Controller,\r
+             &gEfiUsbHcProtocolGuid,\r
+             This->DriverBindingHandle,\r
+             Controller\r
+             );\r
+    }\r
+\r
     gBS->FreePool (UsbBusDev);\r
     return EFI_OUT_OF_RESOURCES;\r
   }\r
@@ -435,28 +582,41 @@ UsbBusControllerDriverStart (
            This->DriverBindingHandle,\r
            Controller\r
            );\r
-    gBS->CloseProtocol (\r
-           Controller,\r
-           &gEfiUsbHcProtocolGuid,\r
-           This->DriverBindingHandle,\r
-           Controller\r
-           );\r
+    if (UsbBusDev->Hc2ProtocolSupported) {\r
+      gBS->CloseProtocol (\r
+             Controller,\r
+             &gEfiUsb2HcProtocolGuid,\r
+             This->DriverBindingHandle,\r
+             Controller\r
+             );\r
+    } else {\r
+      gBS->CloseProtocol (\r
+             Controller,\r
+             &gEfiUsbHcProtocolGuid,\r
+             This->DriverBindingHandle,\r
+             Controller\r
+             );\r
+    }\r
     gBS->FreePool (UsbBusDev);\r
     gBS->FreePool (RootHub);\r
     return EFI_OUT_OF_RESOURCES;\r
   }\r
 \r
-  UsbHCInterface->GetRootHubPortNumber (\r
-                    UsbHCInterface,\r
-                    &RootHubController->DownstreamPorts\r
-                    );\r
-  RootHubController->UsbDevice      = RootHub;\r
-  RootHubController->IsUsbHub       = TRUE;\r
-  RootHubController->DevicePath     = UsbBusDev->DevicePath;\r
-  RootHubController->HostController = Controller;\r
+  UsbVirtualHcGetCapability (\r
+    UsbBusDev,\r
+    &MaxSpeed,\r
+    &PortNumber,\r
+    &Is64BitCapable\r
+    );\r
+  RootHubController->DownstreamPorts  = PortNumber;\r
+  RootHubController->UsbDevice        = RootHub;\r
+  RootHubController->IsUsbHub         = TRUE;\r
+  RootHubController->DevicePath       = UsbBusDev->DevicePath;\r
+  RootHubController->HostController   = Controller;\r
 \r
-  RootHub->NumOfControllers         = 1;\r
-  RootHub->UsbController[0]         = RootHubController;\r
+  RootHub->NumOfControllers           = 1;\r
+  RootHub->UsbController[0]           = RootHubController;\r
+  RootHub->DeviceSpeed                = MaxSpeed;\r
 \r
   //\r
   // Report Status Code here since we will reset the host controller\r
@@ -470,10 +630,10 @@ UsbBusControllerDriverStart (
   //\r
   // Reset USB Host Controller\r
   //\r
-  UsbHCInterface->Reset (\r
-                    UsbHCInterface,\r
-                    EFI_USB_HC_RESET_GLOBAL\r
-                    );\r
+  UsbVirtualHcReset (\r
+    UsbBusDev,\r
+    EFI_USB_HC_RESET_GLOBAL\r
+    );\r
 \r
   //\r
   // Report Status Code while we are going to bring up the Host Controller\r
@@ -488,10 +648,10 @@ UsbBusControllerDriverStart (
   //\r
   // Start USB Host Controller\r
   //\r
-  UsbHCInterface->SetState (\r
-                    UsbHCInterface,\r
-                    EfiUsbHcStateOperational\r
-                    );\r
+  UsbVirtualHcSetState (\r
+    UsbBusDev,\r
+    EfiUsbHcStateOperational\r
+    );\r
 \r
   //\r
   // Create a timer to query root ports periodically\r
@@ -499,7 +659,7 @@ UsbBusControllerDriverStart (
   Status = gBS->CreateEvent (\r
                   EFI_EVENT_TIMER | EFI_EVENT_NOTIFY_SIGNAL,\r
                   EFI_TPL_CALLBACK,\r
-                  UsbEnumeration,\r
+                  RootHubEnumeration,\r
                   RootHubController,\r
                   &RootHubController->HubNotify\r
                   );\r
@@ -517,17 +677,26 @@ UsbBusControllerDriverStart (
            Controller\r
            );\r
 \r
-    gBS->CloseProtocol (\r
-           Controller,\r
-           &gEfiUsbHcProtocolGuid,\r
-           This->DriverBindingHandle,\r
-           Controller\r
-           );\r
+    if (UsbBusDev->Hc2ProtocolSupported) {\r
+      gBS->CloseProtocol (\r
+             Controller,\r
+             &gEfiUsb2HcProtocolGuid,\r
+             This->DriverBindingHandle,\r
+             Controller\r
+             );\r
+    } else {\r
+      gBS->CloseProtocol (\r
+             Controller,\r
+             &gEfiUsbHcProtocolGuid,\r
+             This->DriverBindingHandle,\r
+             Controller\r
+             );\r
+    }\r
 \r
     gBS->FreePool (RootHubController);\r
     gBS->FreePool (RootHub);\r
     gBS->FreePool (UsbBusDev);\r
-    return EFI_UNSUPPORTED;\r
+    return EFI_OUT_OF_RESOURCES;\r
   }\r
 \r
   //\r
@@ -556,22 +725,32 @@ UsbBusControllerDriverStart (
            Controller\r
            );\r
 \r
-    gBS->CloseProtocol (\r
-           Controller,\r
-           &gEfiUsbHcProtocolGuid,\r
-           This->DriverBindingHandle,\r
-           Controller\r
-           );\r
+    if (UsbBusDev->Hc2ProtocolSupported) {\r
+      gBS->CloseProtocol (\r
+             Controller,\r
+             &gEfiUsb2HcProtocolGuid,\r
+             This->DriverBindingHandle,\r
+             Controller\r
+             );\r
+    } else {\r
+      gBS->CloseProtocol (\r
+             Controller,\r
+             &gEfiUsbHcProtocolGuid,\r
+             This->DriverBindingHandle,\r
+             Controller\r
+             );\r
+    }\r
 \r
     gBS->CloseEvent (RootHubController->HubNotify);\r
     gBS->FreePool (RootHubController);\r
     gBS->FreePool (RootHub);\r
     gBS->FreePool (UsbBusDev);\r
-    return EFI_UNSUPPORTED;\r
+    return EFI_DEVICE_ERROR;\r
   }\r
 \r
   return EFI_SUCCESS;\r
 }\r
+\r
 //\r
 // Stop the bus controller\r
 //\r
@@ -608,7 +787,6 @@ UsbBusControllerDriverStop (
   USB_BUS_CONTROLLER_DEVICE *UsbBusController;\r
   EFI_USB_BUS_PROTOCOL      *UsbIdentifier;\r
   UINT8                     Index2;\r
-  EFI_USB_HC_PROTOCOL       *UsbHCInterface;\r
   USB_IO_CONTROLLER_DEVICE  *UsbController;\r
   USB_IO_DEVICE             *UsbIoDevice;\r
   USB_IO_CONTROLLER_DEVICE  *HubController;\r
@@ -678,7 +856,6 @@ UsbBusControllerDriverStop (
   //\r
   // Stop USB Host Controller\r
   //\r
-  UsbHCInterface = UsbBusController->UsbHCInterface;\r
 \r
   //\r
   // Report Status Code here since we will reset the host controller\r
@@ -689,10 +866,10 @@ UsbBusControllerDriverStop (
     EFI_IO_BUS_USB | EFI_IOB_PC_RESET\r
     );\r
 \r
-  UsbHCInterface->SetState (\r
-                    UsbHCInterface,\r
-                    EfiUsbHcStateHalt\r
-                    );\r
+  UsbVirtualHcSetState (\r
+    UsbBusController,\r
+    EfiUsbHcStateHalt\r
+    );\r
 \r
   //\r
   // Deconfiguration all its devices\r
@@ -725,12 +902,21 @@ UsbBusControllerDriverStop (
   // Close USB_HC_PROTOCOL & DEVICE_PATH_PROTOCOL\r
   // Opened by this Controller\r
   //\r
-  gBS->CloseProtocol (\r
-        Controller,\r
-        &gEfiUsbHcProtocolGuid,\r
-        This->DriverBindingHandle,\r
-        Controller\r
-        );\r
+  if (UsbBusController->Hc2ProtocolSupported) {\r
+    gBS->CloseProtocol (\r
+          Controller,\r
+          &gEfiUsb2HcProtocolGuid,\r
+          This->DriverBindingHandle,\r
+          Controller\r
+          );\r
+  } else {\r
+    gBS->CloseProtocol (\r
+          Controller,\r
+          &gEfiUsbHcProtocolGuid,\r
+          This->DriverBindingHandle,\r
+          Controller\r
+          );\r
+  }\r
 \r
   gBS->CloseProtocol (\r
         Controller,\r
@@ -786,6 +972,13 @@ UsbDeviceConfiguration (
   USB_IO_CONTROLLER_DEVICE  *UsbIoController;\r
 \r
   UsbBusDev = UsbIoDevice->BusController;\r
+\r
+  UsbSetTransactionTranslator (\r
+    ParentHubController,\r
+    ParentPort,\r
+    UsbIoDevice\r
+    );\r
+\r
   //\r
   // Since a USB device must have at least on interface,\r
   // so create this instance first\r
@@ -807,6 +1000,8 @@ UsbDeviceConfiguration (
   //\r
   UsbIo = &FirstController->UsbIo;\r
 \r
+  ParentPortReset (FirstController, FALSE, 0);\r
+\r
   //\r
   // First retrieve the 1st 8 bytes of\r
   // in order to get the MaxPacketSize for Endpoint 0\r
@@ -815,7 +1010,7 @@ UsbDeviceConfiguration (
 \r
     UsbIoDevice->DeviceDescriptor.MaxPacketSize0 = 8;\r
 \r
-    ParentPortReset (FirstController, FALSE, Index);\r
+    gBS->Stall (100 * 1000);\r
 \r
     Result = UsbGetDescriptor (\r
               UsbIo,\r
@@ -826,7 +1021,8 @@ UsbDeviceConfiguration (
               &Status\r
               );\r
     if (!EFI_ERROR (Result)) {\r
-      DEBUG ((gUSBDebugLevel,\r
+      DEBUG (\r
+        (gUSBDebugLevel,\r
         "Get Device Descriptor Success, MaxPacketSize0 = 0x%x\n",\r
         UsbIoDevice->DeviceDescriptor.MaxPacketSize0)\r
         );\r
@@ -874,6 +1070,11 @@ UsbDeviceConfiguration (
 \r
   UsbIoDevice->DeviceAddress = DevAddress;\r
 \r
+  //\r
+  // SetAddress Complete Time by Spec, Max 50ms\r
+  //\r
+  gBS->Stall (10 * 1000);\r
+\r
   //\r
   // Get the whole device descriptor\r
   //\r
@@ -1049,7 +1250,6 @@ UsbDeviceConfiguration (
 //\r
 // USB Device DeConfiguration\r
 //\r
-\r
 EFI_STATUS\r
 UsbDeviceDeConfiguration (\r
   IN USB_IO_DEVICE     *UsbIoDevice\r
@@ -1074,8 +1274,6 @@ UsbDeviceDeConfiguration (
   UINT8                     Index;\r
   EFI_USB_IO_PROTOCOL       *UsbIo;\r
 \r
-  DEBUG ((gUSBDebugLevel, "Enter Usb Device Deconfiguration\n"));\r
-\r
   //\r
   // Double check UsbIoDevice exists\r
   //\r
@@ -1083,6 +1281,8 @@ UsbDeviceDeConfiguration (
     return EFI_SUCCESS;\r
   }\r
 \r
+  UsbUnsetTransactionTranslator (UsbIoDevice);\r
+\r
   for (index = 0; index < UsbIoDevice->NumOfControllers; index++) {\r
     //\r
     // Check if it is a hub, if so, de configuration all its\r
@@ -1143,13 +1343,21 @@ UsbDeviceDeConfiguration (
     //\r
     // remove child handle reference to the USB_HC_PROTOCOL\r
     //\r
-    gBS->CloseProtocol (\r
-          UsbController->HostController,\r
-          &gEfiUsbHcProtocolGuid,\r
-          gUsbBusDriverBinding.DriverBindingHandle,\r
-          UsbController->Handle\r
-          );\r
-\r
+    if (UsbIoDevice->BusController->Hc2ProtocolSupported) {\r
+      gBS->CloseProtocol (\r
+            UsbController->HostController,\r
+            &gEfiUsb2HcProtocolGuid,\r
+            gUsbBusDriverBinding.DriverBindingHandle,\r
+            UsbController->Handle\r
+            );\r
+    } else {\r
+      gBS->CloseProtocol (\r
+            UsbController->HostController,\r
+            &gEfiUsbHcProtocolGuid,\r
+            gUsbBusDriverBinding.DriverBindingHandle,\r
+            UsbController->Handle\r
+            );\r
+    }\r
     //\r
     // Uninstall EFI_USB_IO_PROTOCOL & DEVICE_PATH_PROTOCOL\r
     // installed on this handle\r
@@ -1314,30 +1522,31 @@ OnHubInterruptComplete (
 STATIC\r
 VOID\r
 EFIAPI\r
-UsbEnumeration (\r
+RootHubEnumeration (\r
   IN EFI_EVENT     Event,\r
   IN VOID          *Context\r
   )\r
 /*++\r
 \r
   Routine Description:\r
-    This is USB enumerator\r
+  \r
+    This is USB RootHub enumerator\r
 \r
   Arguments:\r
+  \r
     Event   -   Indicating which event is signaled\r
     Context -  actually it is a USB_IO_DEVICE\r
 \r
   Returns:\r
-    EFI_SUCCESS\r
-    Others\r
-\r
+  \r
+    VOID\r
+    \r
 --*/\r
 {\r
   USB_IO_CONTROLLER_DEVICE  *HubController;\r
   EFI_USB_PORT_STATUS       HubPortStatus;\r
   EFI_STATUS                Status;\r
   UINT8                     Index;\r
-  EFI_USB_HC_PROTOCOL       *UsbHCInterface;\r
   USB_IO_DEVICE             *UsbIoDev;\r
   USB_BUS_CONTROLLER_DEVICE *UsbBusDev;\r
   EFI_HANDLE                HostController;\r
@@ -1346,476 +1555,561 @@ UsbEnumeration (
   USB_IO_CONTROLLER_DEVICE  *NewController;\r
   UINT8                     Index2;\r
   EFI_USB_IO_PROTOCOL       *UsbIo;\r
-  UINT8                     StatusChangePort;\r
 \r
   HubController   = (USB_IO_CONTROLLER_DEVICE *) Context;\r
   HostController  = HubController->HostController;\r
   UsbBusDev       = HubController->UsbDevice->BusController;\r
 \r
-  if (HubController->UsbDevice->DeviceAddress == 1) {\r
+  //\r
+  // Root hub has the address 1\r
+  //\r
+  UsbIoDev = HubController->UsbDevice;\r
+\r
+  for (Index = 0; Index < HubController->DownstreamPorts; Index++) {\r
+\r
+    UsbVirtualHcGetRootHubPortStatus (\r
+      UsbBusDev,\r
+      Index,\r
+      (EFI_USB_PORT_STATUS *) &HubPortStatus\r
+      );\r
+\r
+    if (!IsPortConnectChange (HubPortStatus.PortChangeStatus)) {\r
+      continue;\r
+    }\r
     //\r
-    // Root hub has the address 1\r
+    // Clear root hub status change status\r
     //\r
-    UsbIoDev        = HubController->UsbDevice;\r
-    UsbHCInterface  = UsbIoDev->BusController->UsbHCInterface;\r
-\r
-    for (Index = 0; Index < HubController->DownstreamPorts; Index++) {\r
-      UsbHCInterface->GetRootHubPortStatus (\r
-                        UsbHCInterface,\r
-                        Index,\r
-                        (EFI_USB_PORT_STATUS *) &HubPortStatus\r
-                        );\r
+    UsbVirtualHcClearRootHubPortFeature (\r
+      UsbBusDev,\r
+      Index,\r
+      EfiUsbPortConnectChange\r
+      );\r
 \r
-      if (!IsPortConnectChange (HubPortStatus.PortChangeStatus)) {\r
-        continue;\r
-      }\r
+    gBS->Stall (100 * 1000);\r
+\r
+    UsbVirtualHcGetRootHubPortStatus (\r
+      UsbBusDev,\r
+      Index,\r
+      (EFI_USB_PORT_STATUS *) &HubPortStatus\r
+      );\r
+\r
+    if (IsPortConnect (HubPortStatus.PortStatus)) {\r
+        \r
       //\r
-      // Clear root hub status change status\r
+      // There is something connected to this port\r
       //\r
-      ClearRootPortConnectionChangeStatus (\r
-        Index,\r
-        UsbHCInterface\r
+      DEBUG ((gUSBDebugLevel, "Something connected to Root Hub at Port0x%x\n", Index));\r
+\r
+      ReportUsbStatusCode (\r
+        UsbBusDev,\r
+        EFI_PROGRESS_CODE,\r
+        EFI_IO_BUS_USB | EFI_IOB_PC_HOTPLUG\r
         );\r
+      //\r
+      // if there is something physically detached, but still logically\r
+      // attached...\r
+      //\r
+      OldUsbIoDevice = HubController->Children[Index];\r
 \r
-      gBS->Stall (100 * 1000);\r
+      if (NULL != OldUsbIoDevice) {\r
+        UsbDeviceDeConfiguration (OldUsbIoDevice);\r
+        HubController->Children[Index] = NULL;\r
+      }\r
 \r
-      UsbHCInterface->GetRootHubPortStatus (\r
-                        UsbHCInterface,\r
-                        Index,\r
-                        (EFI_USB_PORT_STATUS *) &HubPortStatus\r
-                        );\r
+      NewDevice = AllocateZeroPool (sizeof (USB_IO_DEVICE));\r
+      if (NewDevice == NULL) {\r
+        return ;\r
+      }\r
+      //\r
+      // Initialize some fields by copying data from\r
+      // its parents\r
+      //\r
+      NewDevice->DeviceDescriptor.MaxPacketSize0  = 8;\r
+      NewDevice->BusController                    = UsbIoDev->BusController;\r
 \r
-      if (IsPortConnect (HubPortStatus.PortStatus)) {\r
-        \r
+      //\r
+      // Process of identify device speed\r
+      //\r
+      Status = IdentifyDeviceSpeed (\r
+                 UsbBusDev, \r
+                 NewDevice, \r
+                 Index\r
+                 );\r
+      if (EFI_ERROR (Status)) {\r
+        gBS->FreePool (NewDevice);\r
+        continue;\r
+      }\r
+\r
+      //\r
+      // Configure that device\r
+      //\r
+      Status = UsbDeviceConfiguration (\r
+                HubController,\r
+                HostController,\r
+                Index,\r
+                NewDevice\r
+                );\r
+      if (EFI_ERROR (Status)) {\r
+        gBS->FreePool (NewDevice);\r
+        return ;\r
+      }\r
+      //\r
+      // Add this device to the usb bus tree\r
+      //\r
+      HubController->Children[Index] = NewDevice;\r
+\r
+      for (Index2 = 0; Index2 < NewDevice->NumOfControllers; Index2++) {\r
         //\r
-        // There is something connected to this port\r
+        // If this device is hub, add to the hub index\r
         //\r
-        DEBUG ((gUSBDebugLevel, "Something attached from Root Hub in 0x%x\n", Index));\r
+        NewController = NewDevice->UsbController[Index2];\r
 \r
-        ReportUsbStatusCode (\r
-          UsbBusDev,\r
-          EFI_PROGRESS_CODE,\r
-          EFI_IO_BUS_USB | EFI_IOB_PC_HOTPLUG\r
-          );\r
-        //\r
-        // if there is something physically detached, but still logically\r
-        // attached...\r
-        //\r
-        OldUsbIoDevice = HubController->Children[Index];\r
-\r
-        if (NULL != OldUsbIoDevice) {\r
-          UsbDeviceDeConfiguration (OldUsbIoDevice);\r
-          HubController->Children[Index] = NULL;\r
-        }\r
-\r
-        NewDevice = AllocateZeroPool (sizeof (USB_IO_DEVICE));\r
-        if (NewDevice == NULL) {\r
-          return ;\r
-        }\r
+        Status = gBS->ConnectController (\r
+                        NewController->Handle,\r
+                        NULL,\r
+                        NULL,\r
+                        TRUE\r
+                        );\r
         //\r
-        // Initialize some fields by copying data from\r
-        // its parents\r
+        // If connect success, we need to disconnect when\r
+        // stop the controller, otherwise we need not call\r
+        // gBS->DisconnectController ()\r
+        // This is used by those usb devices we don't plan\r
+        // to support. We can allocate\r
+        // controller handles for them, but we don't have\r
+        // device drivers to manage them.\r
         //\r
-        NewDevice->IsSlowDevice = IsPortLowSpeedDeviceAttached (HubPortStatus.PortStatus);\r
-\r
-        DEBUG ((gUSBDebugLevel, "DeviceSpeed 0x%x\n", NewDevice->IsSlowDevice));\r
+        NewController->IsManagedByDriver = (BOOLEAN) (!EFI_ERROR (Status));\r
 \r
-        NewDevice->BusController = UsbIoDev->BusController;\r
+        if (IsHub (NewController)) {\r
 \r
-        //\r
-        // Configure that device\r
-        //\r
-        Status = UsbDeviceConfiguration (\r
-                  HubController,\r
-                  HostController,\r
-                  Index,\r
-                  NewDevice\r
-                  );\r
-        if (EFI_ERROR (Status)) {\r
-          gBS->FreePool (NewDevice);\r
-          return ;\r
-        }\r
-        //\r
-        // Add this device to the usb bus tree\r
-        //\r
-        HubController->Children[Index] = NewDevice;\r
+          NewController->IsUsbHub = TRUE;\r
 \r
-        for (Index2 = 0; Index2 < NewDevice->NumOfControllers; Index2++) {\r
           //\r
-          // If this device is hub, add to the hub index\r
+          // Configure Hub Controller\r
           //\r
-          NewController = NewDevice->UsbController[Index2];\r
-\r
-          Status = gBS->ConnectController (\r
-                          NewController->Handle,\r
-                          NULL,\r
-                          NULL,\r
-                          TRUE\r
-                          );\r
+          Status = DoHubConfig (NewController);\r
+          if (EFI_ERROR (Status)) {\r
+            continue;\r
+          }\r
           //\r
-          // If connect success, we need to disconnect when\r
-          // stop the controller, otherwise we need not call\r
-          // gBS->DisconnectController ()\r
-          // This is used by those usb devices we don't plan\r
-          // to support. We can allocate\r
-          // controller handles for them, but we don't have\r
-          // device drivers to manage them.\r
+          // Create an event to do hub enumeration\r
           //\r
-          NewController->IsManagedByDriver = (BOOLEAN) (!EFI_ERROR (Status));\r
-\r
-          if (IsHub (NewController)) {\r
-\r
-            NewController->IsUsbHub = TRUE;\r
-\r
-            //\r
-            // Configure Hub Controller\r
-            //\r
-            Status = DoHubConfig (NewController);\r
-            if (EFI_ERROR (Status)) {\r
-              continue;\r
-            }\r
-            //\r
-            // Create an event to do hub enumeration\r
-            //\r
-            gBS->CreateEvent (\r
-                  EFI_EVENT_NOTIFY_SIGNAL,\r
-                  EFI_TPL_CALLBACK,\r
-                  UsbEnumeration,\r
-                  NewController,\r
-                  &NewController->HubNotify\r
-                  );\r
+          gBS->CreateEvent (\r
+                EFI_EVENT_NOTIFY_SIGNAL,\r
+                EFI_TPL_CALLBACK,\r
+                HubEnumeration,\r
+                NewController,\r
+                &NewController->HubNotify\r
+                );\r
 \r
-            //\r
-            // Add request to do query hub status\r
-            // change endpoint\r
-            // Hub ports < 7\r
-            //\r
-            UsbIo = &NewController->UsbIo;\r
-            UsbIo->UsbAsyncInterruptTransfer (\r
-                    UsbIo,\r
-                    NewController->HubEndpointAddress,\r
-                    TRUE,\r
-                    100,\r
-                    1,\r
-                    OnHubInterruptComplete,\r
-                    NewController\r
-                    );\r
+          //\r
+          // Add request to do query hub status\r
+          // change endpoint\r
+          // Hub ports < 7\r
+          //\r
+          UsbIo = &NewController->UsbIo;\r
+          UsbIo->UsbAsyncInterruptTransfer (\r
+                  UsbIo,\r
+                  NewController->HubEndpointAddress,\r
+                  TRUE,\r
+                  100,\r
+                  1,\r
+                  OnHubInterruptComplete,\r
+                  NewController\r
+                  );\r
 \r
-          }\r
         }\r
-      } else {\r
-        //\r
-        // Something disconnected from USB root hub\r
-        //\r
-        DEBUG ((gUSBDebugLevel, "Something deteached from Root Hub\n"));\r
+      }\r
+    } else {\r
+      //\r
+      // Something disconnected from USB root hub\r
+      //\r
+      DEBUG ((gUSBDebugLevel, "Something disconnected from Root Hub at Port0x%x\n", Index));\r
 \r
-        OldUsbIoDevice = HubController->Children[Index];\r
+      OldUsbIoDevice = HubController->Children[Index];\r
 \r
-        UsbDeviceDeConfiguration (OldUsbIoDevice);\r
+      UsbDeviceDeConfiguration (OldUsbIoDevice);\r
 \r
-        HubController->Children[Index] = NULL;\r
+      HubController->Children[Index] = NULL;\r
+\r
+      UsbVirtualHcClearRootHubPortFeature (\r
+        UsbBusDev,\r
+        Index,\r
+        EfiUsbPortEnableChange\r
+        );\r
+    }\r
+  }\r
+\r
+  return ;\r
+}\r
+//\r
+// USB Root Hub Enumerator\r
+//\r
+STATIC\r
+VOID\r
+EFIAPI\r
+HubEnumeration (\r
+  IN EFI_EVENT     Event,\r
+  IN VOID          *Context\r
+  )\r
+/*++\r
 \r
-        UsbHCInterface->ClearRootHubPortFeature (\r
-                          UsbHCInterface,\r
-                          Index,\r
-                          EfiUsbPortEnableChange\r
-                          );\r
+  Routine Description:\r
+  \r
+    This is Usb Hub enumerator\r
 \r
-        UsbHCInterface->GetRootHubPortStatus (\r
-                          UsbHCInterface,\r
-                          Index,\r
-                          (EFI_USB_PORT_STATUS *) &HubPortStatus\r
-                          );\r
+  Arguments:\r
+  \r
+    Event    -   Indicating which event is signaled\r
+    Context  -  actually it is a USB_IO_DEVICE\r
 \r
-      }\r
-    }\r
+  Returns:\r
 \r
-    return ;\r
-  } else {\r
+    VOID\r
+\r
+--*/\r
+{\r
+  USB_IO_CONTROLLER_DEVICE  *HubController;\r
+  EFI_USB_PORT_STATUS       HubPortStatus;\r
+  EFI_STATUS                Status;\r
+  USB_BUS_CONTROLLER_DEVICE *UsbBusDev;\r
+  EFI_HANDLE                HostController;\r
+  USB_IO_DEVICE             *OldUsbIoDevice;\r
+  USB_IO_DEVICE             *NewDevice;\r
+  USB_IO_CONTROLLER_DEVICE  *NewController;\r
+  UINT8                     Index2;\r
+  EFI_USB_IO_PROTOCOL       *UsbIo;\r
+  UINT8                     StatusChangePort;\r
+  UINT8                     Number;\r
+\r
+  HubController   = (USB_IO_CONTROLLER_DEVICE *) Context;\r
+  HostController  = HubController->HostController;\r
+  UsbBusDev       = HubController->UsbDevice->BusController;\r
+\r
+  //\r
+  // Event from Hub, Get the hub controller handle\r
+  //\r
+  //\r
+  // Get the status change endpoint\r
+  //\r
+  StatusChangePort = HubController->StatusChangePort;\r
+\r
+  //\r
+  // Clear HubController Status Change Bit\r
+  //\r
+  HubController->StatusChangePort = 0;\r
+\r
+  if (StatusChangePort == 0) {\r
     //\r
-    // Event from Hub, Get the hub controller handle\r
+    // Hub changes, we don't handle here\r
     //\r
+    return ;\r
+  }\r
+  //\r
+  // Check which event took place at that port\r
+  //\r
+  UsbIo = &HubController->UsbIo;\r
+  Status = HubGetPortStatus (\r
+            UsbIo,\r
+            StatusChangePort,\r
+            (UINT32 *) &HubPortStatus\r
+            );\r
+\r
+  if (EFI_ERROR (Status)) {\r
+    return ;\r
+  }\r
+  //\r
+  // Clear some change status\r
+  //\r
+  if (HubPortStatus.PortChangeStatus & USB_PORT_STAT_C_ENABLE) {\r
     //\r
-    // Get the status change endpoint\r
+    // Clear Hub port enable change\r
     //\r
-    StatusChangePort = HubController->StatusChangePort;\r
+    DEBUG ((gUSBDebugLevel, "Port Enable Change\n"));\r
+    HubClearPortFeature (\r
+      UsbIo,\r
+      StatusChangePort,\r
+      EfiUsbPortEnableChange\r
+      );\r
+\r
+    HubGetPortStatus (\r
+      UsbIo,\r
+      StatusChangePort,\r
+      (UINT32 *) &HubPortStatus\r
+      );\r
+  }\r
 \r
+  if (HubPortStatus.PortChangeStatus & USB_PORT_STAT_C_RESET) {\r
     //\r
-    // Clear HubController Status Change Bit\r
+    // Clear Hub reset change\r
     //\r
-    HubController->StatusChangePort = 0;\r
+    DEBUG ((gUSBDebugLevel, "Port Reset Change\n"));\r
+    HubClearPortFeature (\r
+      UsbIo,\r
+      StatusChangePort,\r
+      EfiUsbPortResetChange\r
+      );\r
 \r
-    if (StatusChangePort == 0) {\r
-      //\r
-      // Hub changes, we don't handle here\r
-      //\r
-      return ;\r
-    }\r
+    HubGetPortStatus (\r
+      UsbIo,\r
+      StatusChangePort,\r
+      (UINT32 *) &HubPortStatus\r
+      );\r
+  }\r
+\r
+  if (HubPortStatus.PortChangeStatus & USB_PORT_STAT_C_OVERCURRENT) {\r
     //\r
-    // Check which event took place at that port\r
+    // Clear Hub overcurrent change\r
     //\r
-    UsbIo = &HubController->UsbIo;\r
-    Status = HubGetPortStatus (\r
-              UsbIo,\r
-              StatusChangePort,\r
-              (UINT32 *) &HubPortStatus\r
-              );\r
+    DEBUG ((gUSBDebugLevel, "Port Overcurrent Change\n"));\r
+    HubClearPortFeature (\r
+      UsbIo,\r
+      StatusChangePort,\r
+      EfiUsbPortOverCurrentChange\r
+      );\r
 \r
-    if (EFI_ERROR (Status)) {\r
-      return ;\r
-    }\r
+    HubGetPortStatus (\r
+      UsbIo,\r
+      StatusChangePort,\r
+      (UINT32 *) &HubPortStatus\r
+      );\r
+  }\r
+\r
+  if (IsPortConnectChange (HubPortStatus.PortChangeStatus)) {\r
     //\r
-    // Clear some change status\r
+    // First clear port connection change\r
     //\r
-    if (HubPortStatus.PortChangeStatus & USB_PORT_STAT_C_ENABLE) {\r
-      //\r
-      // Clear Hub port enable change\r
-      //\r
-      DEBUG ((gUSBDebugLevel, "Port Enable Change\n"));\r
-      HubClearPortFeature (\r
-        UsbIo,\r
-        StatusChangePort,\r
-        EfiUsbPortEnableChange\r
-        );\r
+    DEBUG ((gUSBDebugLevel, "Port Connection Change\n"));\r
+    HubClearPortFeature (\r
+      UsbIo,\r
+      StatusChangePort,\r
+      EfiUsbPortConnectChange\r
+      );\r
 \r
-      HubGetPortStatus (\r
-        UsbIo,\r
-        StatusChangePort,\r
-        (UINT32 *) &HubPortStatus\r
+    HubGetPortStatus (\r
+      UsbIo,\r
+      StatusChangePort,\r
+      (UINT32 *) &HubPortStatus\r
+      );\r
+\r
+    if (IsPortConnect (HubPortStatus.PortStatus)) {\r
+\r
+      DEBUG ((gUSBDebugLevel, "New Device Connect on Hub port \n"));\r
+\r
+      ReportUsbStatusCode (\r
+        UsbBusDev,\r
+        EFI_PROGRESS_CODE,\r
+        EFI_IO_BUS_USB | EFI_IOB_PC_HOTPLUG\r
         );\r
-    }\r
 \r
-    if (HubPortStatus.PortChangeStatus & USB_PORT_STAT_C_RESET) {\r
       //\r
-      // Clear Hub reset change\r
+      // if there is something physically detached, but still logically\r
+      // attached...\r
       //\r
-      DEBUG ((gUSBDebugLevel, "Port Reset Change\n"));\r
-      HubClearPortFeature (\r
-        UsbIo,\r
-        StatusChangePort,\r
-        EfiUsbPortResetChange\r
-        );\r
+      OldUsbIoDevice = HubController->Children[StatusChangePort - 1];\r
 \r
-      HubGetPortStatus (\r
-        UsbIo,\r
-        StatusChangePort,\r
-        (UINT32 *) &HubPortStatus\r
-        );\r
-    }\r
+      if (NULL != OldUsbIoDevice) {\r
+        UsbDeviceDeConfiguration (OldUsbIoDevice);\r
+        HubController->Children[StatusChangePort - 1] = NULL;\r
+      }\r
 \r
-    if (HubPortStatus.PortChangeStatus & USB_PORT_STAT_C_OVERCURRENT) {\r
+      NewDevice = AllocateZeroPool (sizeof (USB_IO_DEVICE));\r
+      if (NewDevice == NULL) {\r
+        return ;\r
+      }\r
       //\r
-      // Clear Hub overcurrent change\r
+      // Initialize some fields\r
       //\r
-      DEBUG ((gUSBDebugLevel, "Port Overcurrent Change\n"));\r
-      HubClearPortFeature (\r
-        UsbIo,\r
-        StatusChangePort,\r
-        EfiUsbPortOverCurrentChange\r
-        );\r
+      NewDevice->DeviceDescriptor.MaxPacketSize0  = 8;\r
+      NewDevice->BusController                    = HubController->UsbDevice->BusController;\r
 \r
-      HubGetPortStatus (\r
-        UsbIo,\r
-        StatusChangePort,\r
-        (UINT32 *) &HubPortStatus\r
-        );\r
-    }\r
-\r
-    if (IsPortConnectChange (HubPortStatus.PortChangeStatus)) {\r
       //\r
-      // First clear port connection change\r
+      // There is something connected to this port,\r
+      // reset that port\r
+      //\r
+      // Disable the enable bit in port status\r
       //\r
-      DEBUG ((gUSBDebugLevel, "Port Connection Change\n"));\r
       HubClearPortFeature (\r
         UsbIo,\r
         StatusChangePort,\r
-        EfiUsbPortConnectChange\r
-        );\r
-\r
-      HubGetPortStatus (\r
-        UsbIo,\r
-        StatusChangePort,\r
-        (UINT32 *) &HubPortStatus\r
+        EfiUsbPortEnable\r
         );\r
 \r
-      if (IsPortConnect (HubPortStatus.PortStatus)) {\r
+      gBS->Stall (50 * 1000);\r
 \r
-        DEBUG ((gUSBDebugLevel, "New Device Connect on Hub port \n"));\r
-\r
-        ReportUsbStatusCode (\r
-          UsbBusDev,\r
-          EFI_PROGRESS_CODE,\r
-          EFI_IO_BUS_USB | EFI_IOB_PC_HOTPLUG\r
+      //\r
+      // Wait for bit change\r
+      //\r
+      Number = 10;\r
+      do {\r
+        HubGetPortStatus (\r
+          UsbIo,\r
+          StatusChangePort,\r
+          (UINT32 *) &HubPortStatus\r
           );\r
+        gBS->Stall (10 * 1000);\r
+        Number -= 1;\r
+      } while ((HubPortStatus.PortStatus & USB_PORT_STAT_ENABLE) == 1 && Number > 0);\r
 \r
+      if (Number == 0) {\r
         //\r
-        // if there is something physically detached, but still logically\r
-        // attached...\r
+        // Cannot disable port, return error\r
         //\r
-        OldUsbIoDevice = HubController->Children[StatusChangePort - 1];\r
-\r
-        if (NULL != OldUsbIoDevice) {\r
-          UsbDeviceDeConfiguration (OldUsbIoDevice);\r
-          HubController->Children[StatusChangePort - 1] = NULL;\r
-        }\r
+        DEBUG ((gUSBErrorLevel, "Disable Port Failed\n"));\r
+        gBS->FreePool (NewDevice);\r
+        return ;\r
+      }\r
 \r
-        NewDevice = AllocateZeroPool (sizeof (USB_IO_DEVICE));\r
-        if (NewDevice == NULL) {\r
-          return ;\r
-        }\r
+      HubSetPortFeature (\r
+        UsbIo,\r
+        StatusChangePort,\r
+        EfiUsbPortReset\r
+        );\r
 \r
-        ResetHubPort (HubController, StatusChangePort);\r
+      gBS->Stall (50 * 1000);\r
 \r
+      //\r
+      // Wait for port reset complete\r
+      //\r
+      Number = 10;\r
+      do {\r
         HubGetPortStatus (\r
           UsbIo,\r
           StatusChangePort,\r
           (UINT32 *) &HubPortStatus\r
           );\r
+        gBS->Stall (10 * 1000);\r
+        Number -= 1;\r
+      } while ((HubPortStatus.PortStatus & USB_PORT_STAT_RESET) == 1 && Number > 0);\r
 \r
+      if (Number == 0) {\r
         //\r
-        // Initialize some fields\r
+        // Cannot reset port, return error\r
         //\r
-        NewDevice->IsSlowDevice   = IsPortLowSpeedDeviceAttached (HubPortStatus.PortStatus);\r
+        DEBUG ((gUSBErrorLevel, "Reset Port Failed\n"));\r
+        gBS->FreePool (NewDevice);\r
+        return ;\r
+      }\r
+      //\r
+      // Check high speed or full speed device\r
+      //\r
+      if (HubPortStatus.PortStatus & USB_PORT_STAT_LOW_SPEED) {\r
+        DEBUG ((gUSBDebugLevel, "Low Speed Device Attached to Hub\n"));\r
+        NewDevice->DeviceSpeed = EFI_USB_SPEED_LOW;\r
+      } else if (HubPortStatus.PortStatus & USB_PORT_STAT_HIGH_SPEED) {\r
+        DEBUG ((gUSBDebugLevel, "High Speed Device Attached to Hub\n"));\r
+        NewDevice->DeviceSpeed = EFI_USB_SPEED_HIGH;\r
+      } else {\r
+        DEBUG ((gUSBDebugLevel, "Full Speed Device Attached to Hub\n"));\r
+        NewDevice->DeviceSpeed = EFI_USB_SPEED_FULL;\r
+      }\r
+      //\r
+      // Configure that device\r
+      //\r
+      Status = UsbDeviceConfiguration (\r
+                HubController,\r
+                HostController,\r
+                (UINT8) (StatusChangePort - 1),\r
+                NewDevice\r
+                );\r
 \r
-        NewDevice->BusController  = HubController->UsbDevice->BusController;\r
+      if (EFI_ERROR (Status)) {\r
+        gBS->FreePool (NewDevice);\r
+        return ;\r
+      }\r
+      //\r
+      // Add this device to the usb bus tree\r
+      // StatusChangePort is begin from 1,\r
+      //\r
+      HubController->Children[StatusChangePort - 1] = NewDevice;\r
 \r
+      for (Index2 = 0; Index2 < NewDevice->NumOfControllers; Index2++) {\r
         //\r
-        // Configure that device\r
+        // If this device is hub, add to the hub index\r
         //\r
-        Status = UsbDeviceConfiguration (\r
-                  HubController,\r
-                  HostController,\r
-                  (UINT8) (StatusChangePort - 1),\r
-                  NewDevice\r
-                  );\r
+        NewController = NewDevice->UsbController[Index2];\r
 \r
-        if (EFI_ERROR (Status)) {\r
-          gBS->FreePool (NewDevice);\r
-          return ;\r
-        }\r
         //\r
-        // Add this device to the usb bus tree\r
-        // StatusChangePort is begin from 1,\r
+        // Connect the controller to the driver image\r
+        //\r
+        Status = gBS->ConnectController (\r
+                        NewController->Handle,\r
+                        NULL,\r
+                        NULL,\r
+                        TRUE\r
+                        );\r
+        //\r
+        // If connect success, we need to disconnect when\r
+        // stop the controller, otherwise we need not call\r
+        // gBS->DisconnectController ()\r
+        // This is used by those usb devices we don't plan\r
+        // to support. We can allocate\r
+        // controller handles for them, but we don't have\r
+        // device drivers to manage them.\r
         //\r
-        HubController->Children[StatusChangePort - 1] = NewDevice;\r
+        NewController->IsManagedByDriver = (BOOLEAN) (!EFI_ERROR (Status));\r
 \r
-        for (Index2 = 0; Index2 < NewDevice->NumOfControllers; Index2++) {\r
-          //\r
-          // If this device is hub, add to the hub index\r
-          //\r
-          NewController = NewDevice->UsbController[Index2];\r
+        //\r
+        // If this device is hub, add to the hub index\r
+        //\r
+        if (IsHub (NewController)) {\r
+\r
+          NewController->IsUsbHub = TRUE;\r
 \r
           //\r
-          // Connect the controller to the driver image\r
+          // Configure Hub\r
           //\r
-          Status = gBS->ConnectController (\r
-                          NewController->Handle,\r
-                          NULL,\r
-                          NULL,\r
-                          TRUE\r
-                          );\r
+          Status = DoHubConfig (NewController);\r
+\r
+          if (EFI_ERROR (Status)) {\r
+            continue;\r
+          }\r
           //\r
-          // If connect success, we need to disconnect when\r
-          // stop the controller, otherwise we need not call\r
-          // gBS->DisconnectController ()\r
-          // This is used by those usb devices we don't plan\r
-          // to support. We can allocate\r
-          // controller handles for them, but we don't have\r
-          // device drivers to manage them.\r
+          // Create an event to do hub enumeration\r
           //\r
-          NewController->IsManagedByDriver = (BOOLEAN) (!EFI_ERROR (Status));\r
+          gBS->CreateEvent (\r
+                EFI_EVENT_NOTIFY_SIGNAL,\r
+                EFI_TPL_CALLBACK,\r
+                HubEnumeration,\r
+                NewController,\r
+                &NewController->HubNotify\r
+                );\r
 \r
           //\r
-          // If this device is hub, add to the hub index\r
+          // Add request to do query hub status\r
+          // change endpoint\r
           //\r
-          if (IsHub (NewController)) {\r
-\r
-            NewController->IsUsbHub = TRUE;\r
-\r
-            //\r
-            // Configure Hub\r
-            //\r
-            Status = DoHubConfig (NewController);\r
-\r
-            if (EFI_ERROR (Status)) {\r
-              continue;\r
-            }\r
-            //\r
-            // Create an event to do hub enumeration\r
-            //\r
-            gBS->CreateEvent (\r
-                  EFI_EVENT_NOTIFY_SIGNAL,\r
-                  EFI_TPL_CALLBACK,\r
-                  UsbEnumeration,\r
-                  NewController,\r
-                  &NewController->HubNotify\r
+          UsbIo = &NewController->UsbIo;\r
+          UsbIo->UsbAsyncInterruptTransfer (\r
+                  UsbIo,\r
+                  NewController->HubEndpointAddress,  // Hub endpoint address\r
+                  TRUE,\r
+                  100,\r
+                  1,                                  // Hub ports < 7\r
+                  OnHubInterruptComplete,\r
+                  NewController\r
                   );\r
-\r
-            //\r
-            // Add request to do query hub status\r
-            // change endpoint\r
-            //\r
-            UsbIo = &NewController->UsbIo;\r
-            UsbIo->UsbAsyncInterruptTransfer (\r
-                    UsbIo,\r
-                    NewController->HubEndpointAddress,  // Hub endpoint address\r
-                    TRUE,\r
-                    100,\r
-                    1,                                  // Hub ports < 7\r
-                    OnHubInterruptComplete,\r
-                    NewController\r
-                    );\r
-          }\r
         }\r
-      } else {\r
-        //\r
-        // Something disconnected from USB hub\r
-        //\r
-        DEBUG ((gUSBDebugLevel, "Something Device Detached on Hub port\n"));\r
-\r
-        OldUsbIoDevice = HubController->Children[StatusChangePort - 1];\r
+      }\r
+    } else {\r
+      //\r
+      // Something disconnected from USB hub\r
+      //\r
+      DEBUG ((gUSBDebugLevel, "Something Device Detached on Hub port\n"));\r
 \r
-        UsbDeviceDeConfiguration (OldUsbIoDevice);\r
+      OldUsbIoDevice = HubController->Children[StatusChangePort - 1];\r
 \r
-        HubController->Children[StatusChangePort - 1] = NULL;\r
+      UsbDeviceDeConfiguration (OldUsbIoDevice);\r
 \r
-      }\r
+      HubController->Children[StatusChangePort - 1] = NULL;\r
 \r
-      return ;\r
     }\r
 \r
     return ;\r
   }\r
-}\r
-//\r
-// Clear port connection change status over a given root hub port\r
-//\r
-EFI_STATUS\r
-ClearRootPortConnectionChangeStatus (\r
-  UINT8                   PortNum,\r
-  EFI_USB_HC_PROTOCOL     *UsbHCInterface\r
-  )\r
-/*++\r
-\r
-  Routine Description:\r
-    Clear port connection change status over a given root hub port\r
-\r
-  Arguments:\r
-    PortNum         -   The given port.\r
-    UsbHCInterface  -   The EFI_USB_HC_PROTOCOL instance.\r
-\r
-  Returns:\r
-     EFI_SUCCESS\r
 \r
---*/\r
-{\r
-  EFI_STATUS  Status;\r
-  Status = UsbHCInterface->ClearRootHubPortFeature (\r
-                            UsbHCInterface,\r
-                            PortNum,\r
-                            EfiUsbPortConnectChange\r
-                            );\r
-  return Status;\r
+  return ;\r
 }\r
 \r
 STATIC\r
@@ -1877,6 +2171,7 @@ InitUsbIoController (
   EFI_STATUS                Status;\r
   EFI_DEVICE_PATH_PROTOCOL  *ParentDevicePath;\r
   EFI_USB_HC_PROTOCOL       *UsbHcProtocol;\r
+  EFI_USB2_HC_PROTOCOL      *Usb2HcProtocol;\r
 \r
   //\r
   // Build the child device path for each new USB_IO device\r
@@ -1908,14 +2203,25 @@ InitUsbIoController (
     return Status;\r
   }\r
 \r
-  Status = gBS->OpenProtocol (\r
-                  UsbIoController->HostController,\r
-                  &gEfiUsbHcProtocolGuid,\r
-                  (VOID **) &UsbHcProtocol,\r
-                  gUsbBusDriverBinding.DriverBindingHandle,\r
-                  UsbIoController->Handle,\r
-                  EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
-                  );\r
+  if (UsbIoController->UsbDevice->BusController->Hc2ProtocolSupported) {\r
+    Status = gBS->OpenProtocol (\r
+                    UsbIoController->HostController,\r
+                    &gEfiUsb2HcProtocolGuid,\r
+                    (VOID **)&Usb2HcProtocol,\r
+                    gUsbBusDriverBinding.DriverBindingHandle,\r
+                    UsbIoController->Handle,\r
+                    EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
+                    );\r
+  } else {\r
+    Status = gBS->OpenProtocol (\r
+                    UsbIoController->HostController,\r
+                    &gEfiUsbHcProtocolGuid,\r
+                    (VOID **)&UsbHcProtocol,\r
+                    gUsbBusDriverBinding.DriverBindingHandle,\r
+                    UsbIoController->Handle,\r
+                    EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
+                    );\r
+  }\r
 \r
   return Status;\r
 }\r
@@ -1934,8 +2240,9 @@ ParentPortReset (
 \r
   Arguments:\r
     UsbIoController   - Indicating the Usb Controller Device.\r
-    Reconfigure       - Do we need to reconfigure it.\r
+    ReConfigure       - Do we need to reconfigure it.\r
     RetryTimes        - Retry Times when failed\r
+    \r
   Returns:\r
     EFI_SUCCESS\r
     EFI_DEVICE_ERROR\r
@@ -1960,7 +2267,7 @@ ParentPortReset (
 \r
   if (ParentIoDev->DeviceAddress == 1) {\r
     DEBUG ((gUSBDebugLevel, "Reset from Root Hub 0x%x\n", HubPort));\r
-    ResetRootPort (ParentIoDev->BusController->UsbHCInterface, HubPort, RetryTimes);\r
+    ResetRootPort (ParentIoDev->BusController, HubPort, RetryTimes);\r
   } else {\r
     DEBUG ((gUSBDebugLevel, "Reset from Hub, Addr 0x%x\n", ParentIoDev->DeviceAddress));\r
     ResetHubPort (ParentController, HubPort + 1);\r
@@ -2036,9 +2343,9 @@ UsbPortReset (
 \r
 EFI_STATUS\r
 ResetRootPort (\r
-  IN EFI_USB_HC_PROTOCOL     *UsbHCInterface,\r
-  IN UINT8                   PortNum,\r
-  IN UINT8                   RetryTimes\r
+  IN USB_BUS_CONTROLLER_DEVICE *UsbBusDev,\r
+  IN UINT8                     PortNum,\r
+  IN UINT8                     RetryTimes\r
   )\r
 /*++\r
 \r
@@ -2046,25 +2353,27 @@ ResetRootPort (
     Reset Root Hub port.\r
 \r
   Arguments:\r
-    UsbHCInterface  -   The EFI_USB_HC_PROTOCOL instance.\r
-    PortNum         -   The given port to be reset.\r
-    RetryTimes      -   RetryTimes when failed\r
+    UsbBusDev       - Bus controller of the device.\r
+    PortNum         - The given port to be reset.\r
+    RetryTimes      - RetryTimes when failed\r
+    \r
   Returns:\r
-    N/A\r
+    EFI_SUCCESS\r
+    EFI_DEVICE_ERROR\r
 \r
 --*/\r
 {\r
-  EFI_STATUS  Status;\r
+  EFI_STATUS          Status;\r
+  EFI_USB_PORT_STATUS PortStatus;\r
 \r
   //\r
   // reset root port\r
   //\r
-  Status = UsbHCInterface->SetRootHubPortFeature (\r
-                            UsbHCInterface,\r
-                            PortNum,\r
-                            EfiUsbPortReset\r
-                            );\r
-\r
+  Status = UsbVirtualHcSetRootHubPortFeature (\r
+            UsbBusDev,\r
+            PortNum,\r
+            EfiUsbPortReset\r
+            );\r
   if (EFI_ERROR (Status)) {\r
     return EFI_DEVICE_ERROR;\r
   }\r
@@ -2074,46 +2383,56 @@ ResetRootPort (
   //\r
   // clear reset root port\r
   //\r
-  Status = UsbHCInterface->ClearRootHubPortFeature (\r
-                            UsbHCInterface,\r
-                            PortNum,\r
-                            EfiUsbPortReset\r
-                            );\r
-\r
+  Status = UsbVirtualHcClearRootHubPortFeature (\r
+            UsbBusDev,\r
+            PortNum,\r
+            EfiUsbPortReset\r
+            );\r
   if (EFI_ERROR (Status)) {\r
     return EFI_DEVICE_ERROR;\r
   }\r
 \r
   gBS->Stall (1000);\r
 \r
-  Status = ClearRootPortConnectionChangeStatus (PortNum, UsbHCInterface);\r
-\r
+  Status = UsbVirtualHcClearRootHubPortFeature (\r
+            UsbBusDev,\r
+            PortNum,\r
+            EfiUsbPortConnectChange\r
+            );\r
   if (EFI_ERROR (Status)) {\r
     return EFI_DEVICE_ERROR;\r
   }\r
-  //\r
-  // Set port enable\r
-  //\r
-  Status = UsbHCInterface->SetRootHubPortFeature (\r
-                            UsbHCInterface,\r
-                            PortNum,\r
-                            EfiUsbPortEnable\r
-                            );\r
-  if (EFI_ERROR (Status)) {\r
-    return EFI_DEVICE_ERROR;\r
+\r
+  UsbVirtualHcGetRootHubPortStatus (\r
+    UsbBusDev,\r
+    PortNum,\r
+    &PortStatus\r
+    );\r
+  if (PortStatus.PortStatus & USB_PORT_STAT_OWNER) {\r
+    //\r
+    // Set port enable\r
+    //\r
+    Status = UsbVirtualHcSetRootHubPortFeature (\r
+              UsbBusDev,\r
+              PortNum,\r
+              EfiUsbPortEnable\r
+              );\r
+    if (EFI_ERROR (Status)) {\r
+      return EFI_DEVICE_ERROR;\r
+    }\r
+\r
+    Status = UsbVirtualHcClearRootHubPortFeature (\r
+              UsbBusDev,\r
+              PortNum,\r
+              EfiUsbPortEnableChange\r
+              );\r
   }\r
 \r
-  Status = UsbHCInterface->ClearRootHubPortFeature (\r
-                            UsbHCInterface,\r
-                            PortNum,\r
-                            EfiUsbPortEnableChange\r
-                            );\r
   gBS->Stall ((1 + RetryTimes) * 50 * 1000);\r
 \r
   return EFI_SUCCESS;\r
 }\r
 \r
-\r
 EFI_STATUS\r
 ResetHubPort (\r
   IN USB_IO_CONTROLLER_DEVICE    *UsbIoController,\r
@@ -2202,10 +2521,6 @@ ResetHubPort (
   return EFI_SUCCESS;\r
 }\r
 \r
-\r
-\r
-\r
-\r
 STATIC\r
 EFI_STATUS\r
 ReportUsbStatusCode (\r
@@ -2236,7 +2551,6 @@ Routine Description:
           );\r
 }\r
 \r
-\r
 EFI_STATUS\r
 IsDeviceDisconnected (\r
   IN USB_IO_CONTROLLER_DEVICE    *UsbIoController,\r
@@ -2264,7 +2578,6 @@ IsDeviceDisconnected (
   EFI_STATUS                Status;\r
   EFI_USB_IO_PROTOCOL       *UsbIo;\r
   EFI_USB_PORT_STATUS       PortStatus;\r
-  EFI_USB_HC_PROTOCOL       *UsbHCInterface;\r
 \r
   ParentController  = UsbIoController->Parent;\r
   ParentIoDev       = ParentController->UsbDevice;\r
@@ -2275,12 +2588,11 @@ IsDeviceDisconnected (
     //\r
     // Connected to the root hub\r
     //\r
-    UsbHCInterface = ParentIoDev->BusController->UsbHCInterface;\r
-    Status = UsbHCInterface->GetRootHubPortStatus (\r
-                              UsbHCInterface,\r
-                              HubPort,\r
-                              &PortStatus\r
-                              );\r
+    UsbVirtualHcGetRootHubPortStatus (\r
+      ParentIoDev->BusController,\r
+      HubPort,\r
+      &PortStatus\r
+      );\r
 \r
   } else {\r
     UsbIo = &UsbIoController->UsbIo;\r
@@ -2303,3 +2615,1135 @@ IsDeviceDisconnected (
 \r
   return EFI_SUCCESS;\r
 }\r
+\r
+STATIC\r
+EFI_STATUS\r
+UsbSetTransactionTranslator (\r
+  IN USB_IO_CONTROLLER_DEVICE     *ParentHubController,\r
+  IN UINT8                        ParentPort,\r
+  IN OUT USB_IO_DEVICE            *Device\r
+  )\r
+/*++\r
+  \r
+  Routine Description:\r
+  \r
+    Set Transaction Translator parameter\r
+  \r
+  Arguments:\r
+  \r
+    ParentHubController  - Controller structure of the parent Hub device\r
+    ParentPort           - Number of parent port\r
+    Device               - Structure of the device\r
+    \r
+  Returns:\r
+  \r
+    EFI_SUCCESS            Success\r
+    EFI_OUT_OF_RESOURCES   Cannot allocate resources\r
+    \r
+--*/\r
+{\r
+  USB_IO_CONTROLLER_DEVICE  *AncestorHubController;\r
+\r
+  AncestorHubController = ParentHubController;\r
+  Device->Translator    = NULL;\r
+\r
+  if (EFI_USB_SPEED_HIGH == Device->DeviceSpeed) {\r
+    return EFI_SUCCESS;\r
+  }\r
+\r
+  do {\r
+    if (EFI_USB_SPEED_HIGH == AncestorHubController->UsbDevice->DeviceSpeed) {\r
+      break;\r
+    }\r
+\r
+    if (NULL == AncestorHubController->Parent) {\r
+      return EFI_SUCCESS;\r
+    }\r
+\r
+    AncestorHubController = AncestorHubController->Parent;\r
+  } while (1);\r
+\r
+  Device->Translator = AllocatePool (sizeof (EFI_USB2_HC_TRANSACTION_TRANSLATOR));\r
+  if (NULL == Device->Translator) {\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
+\r
+  Device->Translator->TranslatorHubAddress  = AncestorHubController->UsbDevice->DeviceAddress;\r
+  Device->Translator->TranslatorPortNumber  = ParentPort;\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+STATIC\r
+EFI_STATUS\r
+UsbUnsetTransactionTranslator (\r
+  USB_IO_DEVICE *Device\r
+  )\r
+/*++\r
+  \r
+  Routine Description:\r
+  \r
+    Unset Transaction Translator parameter\r
+  \r
+  Arguments:\r
+    \r
+    Device - Structure of the device\r
+    \r
+  Returns:\r
+  \r
+    EFI_SUCCESS    Success\r
+    \r
+--*/\r
+{\r
+  if (Device->Translator) {\r
+    gBS->FreePool (Device->Translator);\r
+    Device->Translator = NULL;\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+STATIC\r
+EFI_STATUS\r
+IdentifyDeviceSpeed (\r
+  USB_BUS_CONTROLLER_DEVICE *UsbBusDev,\r
+  USB_IO_DEVICE             *NewDevice,\r
+  UINT8                     Index\r
+  )\r
+/*++\r
+  \r
+  Routine Description:\r
+  \r
+    Identify speed of USB device\r
+  \r
+  Arguments:\r
+    \r
+    UsbBusDev  - UsbBus controller structure of the device\r
+    NewDevice  - Devcie controller structure\r
+    Index      - Number of the port\r
+    \r
+  Returns:\r
+  \r
+    EFI_SUCCESS        Success\r
+    EFI_NOT_FOUND      Device release to CHC or can't be found\r
+    \r
+--*/\r
+{\r
+  EFI_STATUS             Status;\r
+  EFI_USB_PORT_STATUS    HubPortStatus;\r
+\r
+  UsbVirtualHcGetRootHubPortStatus (\r
+    UsbBusDev,\r
+    Index,\r
+    (EFI_USB_PORT_STATUS *) &HubPortStatus\r
+    );\r
+  \r
+  //\r
+  // Check device device\r
+  //\r
+  if (!(HubPortStatus.PortStatus & USB_PORT_STAT_OWNER)) {\r
+    //\r
+    // EHC Port Owner\r
+    //\r
+    if (HubPortStatus.PortStatus & USB_PORT_STAT_HIGH_SPEED) {\r
+      DEBUG ((gUSBDebugLevel, "High Speed Device attached to EHC\n"));\r
+      NewDevice->DeviceSpeed = EFI_USB_SPEED_HIGH; \r
+    } else {\r
+      Status = ReleasePortToCHC (UsbBusDev, Index);\r
+      if (EFI_ERROR (Status)) {\r
+        DEBUG ((gUSBErrorLevel, "Fail to release port to CHC\n"));\r
+      } else {\r
+        DEBUG ((gUSBDebugLevel, "Success to release port to CHC\n"));\r
+      }\r
+      return EFI_DEVICE_ERROR;\r
+    }\r
+  } else {\r
+    //\r
+    // CHC Port Owner\r
+    //\r
+    if (HubPortStatus.PortStatus & USB_PORT_STAT_LOW_SPEED) {\r
+      DEBUG ((gUSBDebugLevel, "Low Speed Device attached to CHC\n"));\r
+      NewDevice->DeviceSpeed = EFI_USB_SPEED_LOW; \r
+    } else {\r
+      DEBUG ((gUSBDebugLevel, "FULL Speed Device attached to CHC\n"));\r
+      NewDevice->DeviceSpeed = EFI_USB_SPEED_FULL; \r
+    }\r
+  }\r
+  \r
+  return EFI_SUCCESS;\r
+}\r
+\r
+STATIC\r
+EFI_STATUS\r
+ReleasePortToCHC (\r
+  USB_BUS_CONTROLLER_DEVICE *UsbBusDev,\r
+  UINT8                     PortNum\r
+  )\r
+/*++\r
+  \r
+  Routine Description:\r
+  \r
+    Set bit to release the port owner to CHC\r
+  \r
+  Arguments:\r
+    \r
+    UsbBusDev  - UsbBus controller structure of the device\r
+    PortNum    - Number of the port\r
+    \r
+  Returns:\r
+  \r
+    EFI_SUCCESS        Success\r
+    EFI_DEVICE_ERROR   Fail\r
+    \r
+--*/\r
+{\r
+  EFI_STATUS  Status;\r
+\r
+  Status = UsbVirtualHcSetRootHubPortFeature (\r
+            UsbBusDev,\r
+            PortNum,\r
+            EfiUsbPortOwner\r
+            );\r
+\r
+  gBS->Stall (100 * 1000);\r
+\r
+  return Status;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+UsbVirtualHcGetCapability (\r
+  IN  USB_BUS_CONTROLLER_DEVICE *UsbBusDev,\r
+  OUT UINT8                     *MaxSpeed,\r
+  OUT UINT8                     *PortNumber,\r
+  OUT UINT8                     *Is64BitCapable\r
+  )\r
+/*++\r
+  \r
+  Routine Description:\r
+  \r
+    Virtual interface to Retrieves the capablility of root hub ports \r
+    for both Hc2 and Hc protocol.\r
+    \r
+  Arguments:\r
+  \r
+    UsbBusDev       - A pointer to bus controller of the device.\r
+    MaxSpeed        - A pointer to the number of the host controller.\r
+    PortNumber      - A pointer to the number of the root hub ports.\r
+    Is64BitCapable  - A pointer to the flag for whether controller supports \r
+                      64-bit memory addressing.\r
+    \r
+  Returns:\r
+  \r
+    EFI_SUCCESS \r
+          The host controller capability were retrieved successfully.\r
+    EFI_INVALID_PARAMETER \r
+          MaxSpeed or PortNumber or Is64BitCapable is NULL.\r
+    EFI_DEVICE_ERROR  \r
+          An error was encountered while attempting to retrieve the capabilities.  \r
+          \r
+--*/\r
+{\r
+  EFI_STATUS  Status;\r
+\r
+  Status = EFI_SUCCESS;\r
+\r
+  if (UsbBusDev->Hc2ProtocolSupported) {\r
+    Status = UsbBusDev->Usb2HCInterface->GetCapability (\r
+                                          UsbBusDev->Usb2HCInterface,\r
+                                          MaxSpeed,\r
+                                          PortNumber,\r
+                                          Is64BitCapable\r
+                                          );\r
+  } else {\r
+    Status = UsbBusDev->UsbHCInterface->GetRootHubPortNumber (\r
+                                          UsbBusDev->UsbHCInterface,\r
+                                          PortNumber\r
+                                          );\r
+    *MaxSpeed       = EFI_USB_SPEED_FULL;\r
+    *Is64BitCapable = (UINT8) FALSE;\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+UsbVirtualHcReset (\r
+  IN  USB_BUS_CONTROLLER_DEVICE *UsbBusDev,\r
+  IN UINT16                     Attributes\r
+  )\r
+/*++\r
+  \r
+  Routine Description:\r
+  \r
+    Virtual interface to provides software reset for the USB host controller\r
+    for both Hc2 and Hc protocol.\r
+  \r
+  Arguments:\r
+  \r
+    UsbBusDev   - A pointer to bus controller of the device.\r
+    Attributes  - A bit mask of the reset operation to perform. \r
+                See below for a list of the supported bit mask values.\r
+  \r
+  #define EFI_USB_HC_RESET_GLOBAL  0x0001               // Hc2 and Hc\r
+  #define EFI_USB_HC_RESET_HOST_CONTROLLER  0x0002      // Hc2 and Hc\r
+  #define EFI_USB_HC_RESET_GLOBAL_WITH_DEBUG  0x0004    // Hc2\r
+  #define EFI_USB_HC_RESET_HOST_WITH_DEBUG  0x0008      // Hc2\r
+\r
+  EFI_USB_HC_RESET_GLOBAL \r
+        If this bit is set, a global reset signal will be sent to the USB bus.\r
+        This resets all of the USB bus logic, including the USB host \r
+        controller hardware and all the devices attached on the USB bus.\r
+  EFI_USB_HC_RESET_HOST_CONTROLLER  \r
+        If this bit is set, the USB host controller hardware will be reset. \r
+        No reset signal will be sent to the USB bus.\r
+  EFI_USB_HC_RESET_GLOBAL_WITH_DEBUG\r
+        If this bit is set, a global reset signal will be sent to the USB bus.\r
+        This resets all of the USB bus logic, including the USB host \r
+        controller hardware and all the devices attached on the USB bus. \r
+        If this is an EHCI controller and the debug port has configured, then \r
+        this is will still reset the host controller.\r
+  EFI_USB_HC_RESET_HOST_WITH_DEBUG\r
+        If this bit is set, the USB host controller hardware will be reset. \r
+        If this is an EHCI controller and the debug port has been configured,\r
+        then this will still reset the host controller.\r
+        \r
+  Returns:\r
+  \r
+    EFI_SUCCESS \r
+        The reset operation succeeded.\r
+    EFI_INVALID_PARAMETER \r
+        Attributes is not valid.\r
+    EFI_UNSUPPOURTED\r
+        The type of reset specified by Attributes is not currently supported by\r
+        the host controller hardware.\r
+    EFI_ACCESS_DENIED\r
+        Reset operation is rejected due to the debug port being configured and \r
+        active; only EFI_USB_HC_RESET_GLOBAL_WITH_DEBUG or \r
+        EFI_USB_HC_RESET_HOST_WITH_DEBUG reset Atrributes can be used to\r
+        perform reset operation for this host controller.\r
+    EFI_DEVICE_ERROR  \r
+        An error was encountered while attempting to perform \r
+        the reset operation.\r
+        \r
+--*/\r
+{\r
+  EFI_STATUS  Status;\r
+\r
+  Status = EFI_SUCCESS;\r
+\r
+  if (UsbBusDev->Hc2ProtocolSupported) {\r
+    Status = UsbBusDev->Usb2HCInterface->Reset (\r
+                                          UsbBusDev->Usb2HCInterface,\r
+                                          EFI_USB_HC_RESET_GLOBAL\r
+                                          );\r
+  } else {\r
+    Status = UsbBusDev->UsbHCInterface->Reset (\r
+                                          UsbBusDev->UsbHCInterface,\r
+                                          EFI_USB_HC_RESET_GLOBAL\r
+                                          );\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+UsbVirtualHcGetState (\r
+  IN  USB_BUS_CONTROLLER_DEVICE *UsbBusDev,\r
+  OUT EFI_USB_HC_STATE          *State\r
+  )\r
+/*++\r
+  \r
+  Routine Description:\r
+  \r
+    Virtual interface to retrieves current state of the USB host controller\r
+    for both Hc2 and Hc protocol.\r
+  \r
+  Arguments:\r
+    \r
+    UsbBusDev - A pointer to bus controller of the device.\r
+    State     - A pointer to the EFI_USB_HC_STATE data structure that \r
+              indicates current state of the USB host controller.  \r
+              Type EFI_USB_HC_STATE is defined below.\r
+              \r
+    typedef enum {\r
+      EfiUsbHcStateHalt,\r
+      EfiUsbHcStateOperational,\r
+      EfiUsbHcStateSuspend,\r
+      EfiUsbHcStateMaximum\r
+    } EFI_USB_HC_STATE;\r
+  \r
+  Returns:\r
+  \r
+    EFI_SUCCESS \r
+            The state information of the host controller was returned in State.\r
+    EFI_INVALID_PARAMETER \r
+            State is NULL.\r
+    EFI_DEVICE_ERROR  \r
+            An error was encountered while attempting to retrieve the \r
+            host controller's current state.  \r
+            \r
+--*/\r
+{\r
+  EFI_STATUS  Status;\r
+\r
+  Status = EFI_SUCCESS;\r
+\r
+  if (UsbBusDev->Hc2ProtocolSupported) {\r
+    Status = UsbBusDev->Usb2HCInterface->GetState (\r
+                                          UsbBusDev->Usb2HCInterface,\r
+                                          State\r
+                                          );\r
+  } else {\r
+    Status = UsbBusDev->UsbHCInterface->GetState (\r
+                                          UsbBusDev->UsbHCInterface,\r
+                                          State\r
+                                          );\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+UsbVirtualHcSetState (\r
+  IN  USB_BUS_CONTROLLER_DEVICE *UsbBusDev,\r
+  IN EFI_USB_HC_STATE           State\r
+  )\r
+/*++\r
+  \r
+  Routine Description:\r
+  \r
+    Virtual interface to sets the USB host controller to a specific state\r
+    for both Hc2 and Hc protocol.\r
+  \r
+  Arguments:\r
+    \r
+    UsbBusDev   - A pointer to bus controller of the device.\r
+    State       - Indicates the state of the host controller that will be set.\r
+  \r
+  Returns:\r
+  \r
+    EFI_SUCCESS \r
+          The USB host controller was successfully placed in the state \r
+          specified by State.\r
+    EFI_INVALID_PARAMETER \r
+          State is invalid.\r
+    EFI_DEVICE_ERROR  \r
+          Failed to set the state specified by State due to device error.  \r
+          \r
+--*/\r
+{\r
+  EFI_STATUS  Status;\r
+\r
+  Status = EFI_SUCCESS;\r
+\r
+  if (UsbBusDev->Hc2ProtocolSupported) {\r
+    Status = UsbBusDev->Usb2HCInterface->SetState (\r
+                                          UsbBusDev->Usb2HCInterface,\r
+                                          State\r
+                                          );\r
+  } else {\r
+    Status = UsbBusDev->UsbHCInterface->SetState (\r
+                                          UsbBusDev->UsbHCInterface,\r
+                                          State\r
+                                          );\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+UsbVirtualHcGetRootHubPortStatus (\r
+  IN  USB_BUS_CONTROLLER_DEVICE *UsbBusDev,\r
+  IN  UINT8                     PortNumber,\r
+  OUT EFI_USB_PORT_STATUS       *PortStatus\r
+  )\r
+/*++\r
+  \r
+  Routine Description:\r
+  \r
+    Virtual interface to retrieves the current status of a USB root hub port\r
+    both for Hc2 and Hc protocol.\r
+  \r
+  Arguments:\r
+  \r
+    UsbBusDev   - A pointer to bus controller of the device.\r
+    PortNumber  - Specifies the root hub port from which the status \r
+                is to be retrieved.  This value is zero-based. For example, \r
+                if a root hub has two ports, then the first port is numbered 0,\r
+                and the second port is numbered 1.\r
+    PortStatus  - A pointer to the current port status bits and \r
+                port status change bits.  \r
+  \r
+  Returns:\r
+  \r
+    EFI_SUCCESS  The status of the USB root hub port specified by PortNumber \r
+                 was returned in PortStatus.\r
+    EFI_INVALID_PARAMETER PortNumber is invalid. \r
+    EFI_DEVICE_ERROR      Can't read register     \r
+    \r
+--*/\r
+{\r
+  EFI_STATUS  Status;\r
+\r
+  Status = EFI_SUCCESS;\r
+\r
+  if (UsbBusDev->Hc2ProtocolSupported) {\r
+    Status = UsbBusDev->Usb2HCInterface->GetRootHubPortStatus (\r
+                                          UsbBusDev->Usb2HCInterface,\r
+                                          PortNumber,\r
+                                          PortStatus\r
+                                          );\r
+  } else {\r
+    Status = UsbBusDev->UsbHCInterface->GetRootHubPortStatus (\r
+                                          UsbBusDev->UsbHCInterface,\r
+                                          PortNumber,\r
+                                          PortStatus\r
+                                          );\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+UsbVirtualHcSetRootHubPortFeature (\r
+  IN  USB_BUS_CONTROLLER_DEVICE *UsbBusDev,\r
+  IN  UINT8                     PortNumber,\r
+  IN  EFI_USB_PORT_FEATURE      PortFeature\r
+  )\r
+/*++\r
+  \r
+  Routine Description:\r
+    Virual interface to sets a feature for the specified root hub port\r
+    for both Hc2 and Hc protocol.\r
+  \r
+  Arguments:\r
+  \r
+    UsbBusDev   - A pointer to bus controller of the device.\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
+  \r
+  Returns:\r
+  \r
+    EFI_SUCCESS \r
+        The feature specified by PortFeature was set for the \r
+        USB root hub port specified by PortNumber.\r
+    EFI_INVALID_PARAMETER \r
+        PortNumber is invalid or PortFeature is invalid.\r
+    EFI_DEVICE_ERROR\r
+        Can't read register\r
+        \r
+--*/\r
+{\r
+  EFI_STATUS  Status;\r
+\r
+  Status = EFI_SUCCESS;\r
+\r
+  if (UsbBusDev->Hc2ProtocolSupported) {\r
+    Status = UsbBusDev->Usb2HCInterface->SetRootHubPortFeature (\r
+                                          UsbBusDev->Usb2HCInterface,\r
+                                          PortNumber,\r
+                                          PortFeature\r
+                                          );\r
+  } else {\r
+    Status = UsbBusDev->UsbHCInterface->SetRootHubPortFeature (\r
+                                          UsbBusDev->UsbHCInterface,\r
+                                          PortNumber,\r
+                                          PortFeature\r
+                                          );\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+UsbVirtualHcClearRootHubPortFeature (\r
+  IN  USB_BUS_CONTROLLER_DEVICE *UsbBusDev,\r
+  IN  UINT8                     PortNumber,\r
+  IN  EFI_USB_PORT_FEATURE      PortFeature\r
+  )\r
+/*++\r
+  \r
+  Routine Description:\r
+  \r
+    Virtual interface to clears a feature for the specified root hub port\r
+    for both Hc2 and Hc protocol.\r
+  \r
+  Arguments:\r
+  \r
+    UsbBusDev   - A pointer to bus controller of the device.\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
+                  \r
+  Returns:\r
+  \r
+    EFI_SUCCESS \r
+        The feature specified by PortFeature was cleared for the \r
+        USB root hub port specified by PortNumber.\r
+    EFI_INVALID_PARAMETER \r
+        PortNumber is invalid or PortFeature is invalid.\r
+    EFI_DEVICE_ERROR\r
+        Can't read register\r
+        \r
+--*/\r
+{\r
+  EFI_STATUS  Status;\r
+\r
+  Status = EFI_SUCCESS;\r
+\r
+  if (UsbBusDev->Hc2ProtocolSupported) {\r
+    Status = UsbBusDev->Usb2HCInterface->ClearRootHubPortFeature (\r
+                                          UsbBusDev->Usb2HCInterface,\r
+                                          PortNumber,\r
+                                          PortFeature\r
+                                          );\r
+  } else {\r
+    Status = UsbBusDev->UsbHCInterface->ClearRootHubPortFeature (\r
+                                          UsbBusDev->UsbHCInterface,\r
+                                          PortNumber,\r
+                                          PortFeature\r
+                                          );\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+UsbVirtualHcControlTransfer (\r
+  IN  USB_BUS_CONTROLLER_DEVICE            *UsbBusDev,\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
+  \r
+  Routine Description:\r
+  \r
+    Virtual interface to submits control transfer to a target USB device\r
+    for both Hc2 and Hc protocol.\r
+  \r
+  Arguments:\r
+    \r
+    UsbBusDev     - A pointer to bus controller of the device.\r
+    DeviceAddress - Represents the address of the target device on the USB,\r
+                  which is assigned during USB enumeration.\r
+    DeviceSpeed   - Indicates target device speed.\r
+    MaximumPacketLength - Indicates the maximum packet size that the \r
+                        default control transfer endpoint is capable of \r
+                        sending or receiving.\r
+    Request       - A pointer to the USB device request that will be sent \r
+                  to the USB device. \r
+    TransferDirection - Specifies the data direction for the transfer.\r
+                      There are three values available, DataIn, DataOut \r
+                      and NoData.\r
+    Data          - A pointer to the buffer of data that will be transmitted \r
+                  to USB device or received from USB device.\r
+    DataLength    - Indicates the size, in bytes, of the data buffer \r
+                  specified by Data.\r
+    TimeOut       - Indicates the maximum time, in microseconds, \r
+                  which the transfer is allowed to complete.\r
+    Translator      - A pointr to the transaction translator data.\r
+    TransferResult  - A pointer to the detailed result information generated \r
+                    by this control transfer.\r
+                    \r
+  Returns:\r
+  \r
+    EFI_SUCCESS \r
+        The control transfer was completed successfully.\r
+    EFI_OUT_OF_RESOURCES  \r
+        The control transfer could not be completed due to a lack of resources.\r
+    EFI_INVALID_PARAMETER \r
+        Some parameters are invalid.\r
+    EFI_TIMEOUT \r
+        The control transfer failed due to timeout.\r
+    EFI_DEVICE_ERROR  \r
+        The control transfer failed due to host controller or device error. \r
+        Caller should check TranferResult for detailed error information.\r
+\r
+--*/\r
+{\r
+  EFI_STATUS  Status;\r
+  BOOLEAN     IsSlowDevice;\r
+\r
+  Status = EFI_SUCCESS;\r
+\r
+  if (UsbBusDev->Hc2ProtocolSupported) {\r
+    Status = UsbBusDev->Usb2HCInterface->ControlTransfer (\r
+                                          UsbBusDev->Usb2HCInterface,\r
+                                          DeviceAddress,\r
+                                          DeviceSpeed,\r
+                                          MaximumPacketLength,\r
+                                          Request,\r
+                                          TransferDirection,\r
+                                          Data,\r
+                                          DataLength,\r
+                                          TimeOut,\r
+                                          Translator,\r
+                                          TransferResult\r
+                                          );\r
+  } else {\r
+    IsSlowDevice = (EFI_USB_SPEED_LOW == DeviceSpeed) ? TRUE : FALSE;\r
+    Status = UsbBusDev->UsbHCInterface->ControlTransfer (\r
+                                          UsbBusDev->UsbHCInterface,\r
+                                          DeviceAddress,\r
+                                          IsSlowDevice,\r
+                                          (UINT8) MaximumPacketLength,\r
+                                          Request,\r
+                                          TransferDirection,\r
+                                          Data,\r
+                                          DataLength,\r
+                                          TimeOut,\r
+                                          TransferResult\r
+                                          );\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+UsbVirtualHcBulkTransfer (\r
+  IN  USB_BUS_CONTROLLER_DEVICE           *UsbBusDev,\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
+  \r
+  Routine Description:\r
+  \r
+    Virtual interface to submits bulk transfer to a bulk endpoint of a USB device\r
+    both for Hc2 and Hc protocol.\r
+    \r
+  Arguments:\r
+    \r
+    UsbBusDev         - A pointer to bus controller of the device.\r
+    DeviceAddress     - Represents the address of the target device on the USB,\r
+                      which is assigned during USB enumeration.               \r
+    EndPointAddress   - The combination of an endpoint number and an \r
+                      endpoint direction of the target USB device. \r
+                      Each endpoint address supports data transfer in \r
+                      one direction except the control endpoint \r
+                      (whose default endpoint address is 0). \r
+                      It is the caller's responsibility to make sure that \r
+                      the EndPointAddress represents a bulk endpoint.                  \r
+    DeviceSpeed       - Indicates device speed. The supported values are EFI_USB_SPEED_FULL\r
+                      and EFI_USB_SPEED_HIGH.\r
+    MaximumPacketLength - Indicates the maximum packet size the target endpoint\r
+                        is capable of sending or receiving.                 \r
+    DataBuffersNumber - Number of data buffers prepared for the transfer.\r
+    Data              - Array of pointers to the buffers of data that will be transmitted \r
+                      to USB device or received from USB device.              \r
+    DataLength        - When input, indicates the size, in bytes, of the data buffer\r
+                      specified by Data. When output, indicates the actually \r
+                      transferred data size.              \r
+    DataToggle        - A pointer to the data toggle value. On input, it indicates \r
+                      the initial data toggle value the bulk transfer should adopt;\r
+                      on output, it is updated to indicate the data toggle value \r
+                      of the subsequent bulk transfer. \r
+    Translator        - A pointr to the transaction translator data. \r
+    TimeOut           - Indicates the maximum time, in microseconds, which the \r
+                      transfer is allowed to complete.              \r
+    TransferResult    - A pointer to the detailed result information of the \r
+                      bulk transfer.\r
+\r
+  Returns:\r
+  \r
+    EFI_SUCCESS \r
+        The bulk transfer was completed successfully.\r
+    EFI_OUT_OF_RESOURCES  \r
+        The bulk transfer could not be submitted due to lack of resource.\r
+    EFI_INVALID_PARAMETER \r
+        Some parameters are invalid.\r
+    EFI_TIMEOUT \r
+        The bulk transfer failed due to timeout.\r
+    EFI_DEVICE_ERROR  \r
+        The bulk transfer failed due to host controller or device error.\r
+        Caller should check TranferResult for detailed error information.\r
+\r
+--*/\r
+{\r
+  EFI_STATUS  Status;\r
+\r
+  Status = EFI_SUCCESS;\r
+\r
+  if (UsbBusDev->Hc2ProtocolSupported) {\r
+    Status = UsbBusDev->Usb2HCInterface->BulkTransfer (\r
+                                          UsbBusDev->Usb2HCInterface,\r
+                                          DeviceAddress,\r
+                                          EndPointAddress,\r
+                                          DeviceSpeed,\r
+                                          MaximumPacketLength,\r
+                                          DataBuffersNumber,\r
+                                          Data,\r
+                                          DataLength,\r
+                                          DataToggle,\r
+                                          TimeOut,\r
+                                          Translator,\r
+                                          TransferResult\r
+                                          );\r
+  } else {\r
+    Status = UsbBusDev->UsbHCInterface->BulkTransfer (\r
+                                          UsbBusDev->UsbHCInterface,\r
+                                          DeviceAddress,\r
+                                          EndPointAddress,\r
+                                          (UINT8) MaximumPacketLength,\r
+                                          *Data,\r
+                                          DataLength,\r
+                                          DataToggle,\r
+                                          TimeOut,\r
+                                          TransferResult\r
+                                          );\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+UsbVirtualHcAsyncInterruptTransfer (\r
+  IN  USB_BUS_CONTROLLER_DEVICE             * UsbBusDev,\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
+  \r
+  Routine Description:\r
+  \r
+    Virtual interface to submits an asynchronous interrupt transfer to an \r
+    interrupt endpoint of a USB device for both Hc2 and Hc protocol.\r
+  \r
+  Arguments:\r
+    \r
+    UsbBusDev       - A pointer to bus controller of the device.\r
+    DeviceAddress   - Represents the address of the target device on the USB,\r
+                    which is assigned during USB enumeration.                \r
+    EndPointAddress - The combination of an endpoint number and an endpoint \r
+                    direction of the target USB device. Each endpoint address \r
+                    supports data transfer in one direction except the \r
+                    control endpoint (whose default endpoint address is 0). \r
+                    It is the caller's responsibility to make sure that \r
+                    the EndPointAddress represents an interrupt endpoint.              \r
+    DeviceSpeed     - Indicates device speed.\r
+    MaximumPacketLength  - Indicates the maximum packet size the target endpoint\r
+                         is capable of sending or receiving.                   \r
+    IsNewTransfer   - If TRUE, an asynchronous interrupt pipe is built between\r
+                    the host and the target interrupt endpoint. \r
+                    If FALSE, the specified asynchronous interrupt pipe \r
+                    is canceled.               \r
+    DataToggle      - A pointer to the data toggle value.  On input, it is valid \r
+                    when IsNewTransfer is TRUE, and it indicates the initial \r
+                    data toggle value the asynchronous interrupt transfer \r
+                    should adopt.  \r
+                    On output, it is valid when IsNewTransfer is FALSE, \r
+                    and it is updated to indicate the data toggle value of \r
+                    the subsequent asynchronous interrupt transfer.              \r
+    PollingInterval - Indicates the interval, in milliseconds, that the \r
+                    asynchronous interrupt transfer is polled.  \r
+                    This parameter is required when IsNewTransfer is TRUE.               \r
+    DataLength      - Indicates the length of data to be received at the \r
+                    rate specified by PollingInterval from the target \r
+                    asynchronous interrupt endpoint.  This parameter \r
+                    is only required when IsNewTransfer is TRUE.             \r
+    Translator      - A pointr to the transaction translator data.\r
+    CallBackFunction  - The Callback function.This function is called at the \r
+                      rate specified by PollingInterval.This parameter is \r
+                      only required when IsNewTransfer is TRUE.               \r
+    Context         - The context that is passed to the CallBackFunction.\r
+                    - This is an optional parameter and may be NULL.\r
+  \r
+  Returns:\r
+  \r
+    EFI_SUCCESS \r
+        The asynchronous interrupt transfer request has been successfully \r
+        submitted or canceled.\r
+    EFI_INVALID_PARAMETER \r
+        Some parameters are invalid.\r
+    EFI_OUT_OF_RESOURCES  \r
+        The request could not be completed due to a lack of resources.  \r
+    EFI_DEVICE_ERROR\r
+        Can't read register\r
+        \r
+--*/\r
+{\r
+  EFI_STATUS  Status;\r
+  BOOLEAN     IsSlowDevice;\r
+\r
+  Status = EFI_SUCCESS;\r
+\r
+  if (UsbBusDev->Hc2ProtocolSupported) {\r
+    Status = UsbBusDev->Usb2HCInterface->AsyncInterruptTransfer (\r
+                                          UsbBusDev->Usb2HCInterface,\r
+                                          DeviceAddress,\r
+                                          EndPointAddress,\r
+                                          DeviceSpeed,\r
+                                          MaximumPacketLength,\r
+                                          IsNewTransfer,\r
+                                          DataToggle,\r
+                                          PollingInterval,\r
+                                          DataLength,\r
+                                          Translator,\r
+                                          CallBackFunction,\r
+                                          Context\r
+                                          );\r
+  } else {\r
+    IsSlowDevice = (EFI_USB_SPEED_LOW == DeviceSpeed) ? TRUE : FALSE;\r
+    Status = UsbBusDev->UsbHCInterface->AsyncInterruptTransfer (\r
+                                          UsbBusDev->UsbHCInterface,\r
+                                          DeviceAddress,\r
+                                          EndPointAddress,\r
+                                          IsSlowDevice,\r
+                                          (UINT8) MaximumPacketLength,\r
+                                          IsNewTransfer,\r
+                                          DataToggle,\r
+                                          PollingInterval,\r
+                                          DataLength,\r
+                                          CallBackFunction,\r
+                                          Context\r
+                                          );\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+UsbVirtualHcSyncInterruptTransfer (\r
+  IN  USB_BUS_CONTROLLER_DEVICE             *UsbBusDev,\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
+  \r
+  Routine Description:\r
+  \r
+    Vitual interface to submits synchronous interrupt transfer to an interrupt endpoint \r
+    of a USB device for both Hc2 and Hc protocol.\r
+  \r
+  Arguments:\r
+    \r
+    UsbBusDev       - A pointer to bus controller of the device.\r
+    DeviceAddress   - Represents the address of the target device on the USB, \r
+                    which is assigned during USB enumeration.\r
+    EndPointAddress   - The combination of an endpoint number and an endpoint \r
+                      direction of the target USB device. Each endpoint \r
+                      address supports data transfer in one direction \r
+                      except the control endpoint (whose default \r
+                      endpoint address is 0). It is the caller's responsibility\r
+                      to make sure that the EndPointAddress represents \r
+                      an interrupt endpoint. \r
+    DeviceSpeed     - Indicates device speed.\r
+    MaximumPacketLength - Indicates the maximum packet size the target endpoint \r
+                        is capable of sending or receiving.\r
+    Data            - A pointer to the buffer of data that will be transmitted \r
+                    to USB device or received from USB device.\r
+    DataLength      - On input, the size, in bytes, of the data buffer specified \r
+                    by Data. On output, the number of bytes transferred.\r
+    DataToggle      - A pointer to the data toggle value. On input, it indicates\r
+                    the initial data toggle value the synchronous interrupt \r
+                    transfer should adopt; \r
+                    on output, it is updated to indicate the data toggle value \r
+                    of the subsequent synchronous interrupt transfer. \r
+    TimeOut         - Indicates the maximum time, in microseconds, which the \r
+                    transfer is allowed to complete.\r
+    Translator      - A pointr to the transaction translator data.\r
+    TransferResult  - A pointer to the detailed result information from \r
+                    the synchronous interrupt transfer.  \r
+\r
+  Returns:\r
+  \r
+    EFI_SUCCESS \r
+        The synchronous interrupt transfer was completed successfully.\r
+    EFI_OUT_OF_RESOURCES  \r
+        The synchronous interrupt transfer could not be submitted due \r
+        to lack of resource.\r
+    EFI_INVALID_PARAMETER \r
+        Some parameters are invalid.\r
+    EFI_TIMEOUT \r
+        The synchronous interrupt transfer failed due to timeout.\r
+    EFI_DEVICE_ERROR  \r
+        The synchronous interrupt transfer failed due to host controller \r
+        or device error. Caller should check TranferResult for detailed \r
+        error information.  \r
+        \r
+--*/\r
+{\r
+  EFI_STATUS  Status;\r
+  BOOLEAN     IsSlowDevice;\r
+\r
+  Status = EFI_SUCCESS;\r
+\r
+  if (UsbBusDev->Hc2ProtocolSupported) {\r
+    Status = UsbBusDev->Usb2HCInterface->SyncInterruptTransfer (\r
+                                          UsbBusDev->Usb2HCInterface,\r
+                                          DeviceAddress,\r
+                                          EndPointAddress,\r
+                                          DeviceSpeed,\r
+                                          MaximumPacketLength,\r
+                                          Data,\r
+                                          DataLength,\r
+                                          DataToggle,\r
+                                          TimeOut,\r
+                                          Translator,\r
+                                          TransferResult\r
+                                          );\r
+  } else {\r
+    IsSlowDevice = (EFI_USB_SPEED_LOW == DeviceSpeed) ? TRUE : FALSE;\r
+    Status = UsbBusDev->UsbHCInterface->SyncInterruptTransfer (\r
+                                          UsbBusDev->UsbHCInterface,\r
+                                          DeviceAddress,\r
+                                          EndPointAddress,\r
+                                          IsSlowDevice,\r
+                                          (UINT8) MaximumPacketLength,\r
+                                          Data,\r
+                                          DataLength,\r
+                                          DataToggle,\r
+                                          TimeOut,\r
+                                          TransferResult\r
+                                          );\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+UsbVirtualHcIsochronousTransfer (\r
+  IN  USB_BUS_CONTROLLER_DEVICE             *UsbBusDev,\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
+  \r
+  Routine Description:\r
+  \r
+    Virtual interface to submits isochronous transfer to a target USB device\r
+    for both Hc2 and Hc protocol.\r
+  \r
+  Arguments:\r
+    \r
+    UsbBusDev        - A pointer to bus controller of the device.\r
+    DeviceAddress    - Represents the address of the target device on the USB,\r
+                     which is assigned during USB enumeration.\r
+    EndPointAddress  - End point address\r
+    DeviceSpeed      - Indicates device speed.\r
+    MaximumPacketLength    - Indicates the maximum packet size that the \r
+                           default control transfer endpoint is capable of \r
+                           sending or receiving.\r
+    DataBuffersNumber - Number of data buffers prepared for the transfer.\r
+    Data              - Array of pointers to the buffers of data that will be \r
+                      transmitted to USB device or received from USB device.\r
+    DataLength        - Indicates the size, in bytes, of the data buffer \r
+                      specified by Data.\r
+    Translator        - A pointr to the transaction translator data.\r
+    TransferResult    - A pointer to the detailed result information generated \r
+                      by this control transfer.               \r
+                      \r
+  Returns:\r
+  \r
+    EFI_UNSUPPORTED \r
+\r
+--*/\r
+{\r
+  return EFI_UNSUPPORTED;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+UsbVirtualHcAsyncIsochronousTransfer (\r
+  IN  USB_BUS_CONTROLLER_DEVICE           *UsbBusDev,\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
+  \r
+  Routine Description:\r
+  \r
+    Vitual interface to submits Async isochronous transfer to a target USB device\r
+    for both Hc2 and Hc protocol.\r
+  \r
+  Arguments:\r
+  \r
+    UsbBusDev           - A pointer to bus controller of the device.\r
+    DeviceAddress       - Represents the address of the target device on the USB,\r
+                        which is assigned during USB enumeration.\r
+    EndPointAddress     - End point address\r
+    DeviceSpeed         - Indicates device speed.\r
+    MaximumPacketLength - Indicates the maximum packet size that the \r
+                        default control transfer endpoint is capable of \r
+                        sending or receiving.\r
+    DataBuffersNumber   - Number of data buffers prepared for the transfer.\r
+    Data                - Array of pointers to the buffers of data that will be transmitted \r
+                        to USB device or received from USB device.\r
+    DataLength          - Indicates the size, in bytes, of the data buffer \r
+                        specified by Data.\r
+    Translator          - A pointr to the transaction translator data.\r
+    IsochronousCallBack - When the transfer complete, the call back function will be called\r
+    Context             - Pass to the call back function as parameter\r
+                    \r
+  Returns:\r
+  \r
+    EFI_UNSUPPORTED \r
+\r
+--*/\r
+{\r
+  return EFI_UNSUPPORTED;\r
+}\r