]> git.proxmox.com Git - mirror_edk2.git/commitdiff
Add DevicePathUtilities DevicePathToText DevciePathFromText USB2HostController protocols
authorljin6 <ljin6@6f19259b-4bc3-4df7-8a09-765794883524>
Tue, 18 Jul 2006 04:13:40 +0000 (04:13 +0000)
committerljin6 <ljin6@6f19259b-4bc3-4df7-8a09-765794883524>
Tue, 18 Jul 2006 04:13:40 +0000 (04:13 +0000)
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@1037 6f19259b-4bc3-4df7-8a09-765794883524

30 files changed:
EdkModulePkg/Bus/Pci/Ehci/Dxe/ComponentName.c [new file with mode: 0644]
EdkModulePkg/Bus/Pci/Ehci/Dxe/Ehci.c [new file with mode: 0644]
EdkModulePkg/Bus/Pci/Ehci/Dxe/Ehci.h [new file with mode: 0644]
EdkModulePkg/Bus/Pci/Ehci/Dxe/Ehci.msa [new file with mode: 0644]
EdkModulePkg/Bus/Pci/Ehci/Dxe/EhciMem.c [new file with mode: 0644]
EdkModulePkg/Bus/Pci/Ehci/Dxe/EhciReg.c [new file with mode: 0644]
EdkModulePkg/Bus/Pci/Ehci/Dxe/EhciSched.c [new file with mode: 0644]
EdkModulePkg/Bus/Pci/Uhci/Dxe/Uhci.msa
EdkModulePkg/Bus/Pci/Uhci/Dxe/uhchlp.c
EdkModulePkg/Bus/Pci/Uhci/Dxe/uhci.c
EdkModulePkg/Bus/Pci/Uhci/Dxe/uhci.h
EdkModulePkg/Bus/Usb/UsbBot/Dxe/bot.c
EdkModulePkg/Bus/Usb/UsbBus/Dxe/UsbBus.msa
EdkModulePkg/Bus/Usb/UsbBus/Dxe/usbbus.c
EdkModulePkg/Bus/Usb/UsbBus/Dxe/usbbus.h
EdkModulePkg/Bus/Usb/UsbBus/Dxe/usbio.c
EdkModulePkg/Bus/Usb/UsbBus/Dxe/usbutil.c
EdkModulePkg/EdkModulePkg.spd
EdkModulePkg/Universal/DevicePath/Dxe/DevicePath.c [new file with mode: 0644]
EdkModulePkg/Universal/DevicePath/Dxe/DevicePath.h [new file with mode: 0644]
EdkModulePkg/Universal/DevicePath/Dxe/DevicePath.msa [new file with mode: 0644]
EdkModulePkg/Universal/DevicePath/Dxe/DevicePathFromText.c [new file with mode: 0644]
EdkModulePkg/Universal/DevicePath/Dxe/DevicePathToText.c [new file with mode: 0644]
EdkModulePkg/Universal/DevicePath/Dxe/DevicePathUtilities.c [new file with mode: 0644]
EdkNt32Pkg/Nt32.fpd
MdePkg/Include/Guid/PcAnsi.h
MdePkg/Include/IndustryStandard/Usb.h
MdePkg/Include/Protocol/DevicePathFromText.h
MdePkg/Include/Protocol/Usb2HostController.h
MdePkg/Include/Uefi/UefiSpec.h

diff --git a/EdkModulePkg/Bus/Pci/Ehci/Dxe/ComponentName.c b/EdkModulePkg/Bus/Pci/Ehci/Dxe/ComponentName.c
new file mode 100644 (file)
index 0000000..e0d2010
--- /dev/null
@@ -0,0 +1,189 @@
+/*++\r
+\r
+Copyright 2006, Intel Corporation                                                         \r
+All rights reserved. This program and the accompanying materials                          \r
+are licensed and made available under the terms and conditions of the BSD License         \r
+which accompanies this distribution.  The full text of the license may be found at        \r
+http://opensource.org/licenses/bsd-license.php                                            \r
+                                                                                          \r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     \r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             \r
+\r
+Module Name:\r
+\r
+  ComponentName.c\r
+\r
+Abstract:\r
+\r
+--*/\r
+\r
+#include "Ehci.h"\r
+\r
+//\r
+// EFI Component Name Functions\r
+//\r
+EFI_STATUS\r
+EFIAPI\r
+EhciComponentNameGetDriverName (\r
+  IN  EFI_COMPONENT_NAME_PROTOCOL     *This,\r
+  IN  CHAR8                           *Language,\r
+  OUT CHAR16                          **DriverName\r
+  );\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+EhciComponentNameGetControllerName (\r
+  IN  EFI_COMPONENT_NAME_PROTOCOL     *This,\r
+  IN  EFI_HANDLE                      ControllerHandle,\r
+  IN  EFI_HANDLE                      ChildHandle, OPTIONAL\r
+  IN  CHAR8                           *Language,\r
+  OUT CHAR16                          **ControllerName\r
+  );\r
+\r
+//\r
+// EFI Component Name Protocol\r
+//\r
+EFI_COMPONENT_NAME_PROTOCOL     gEhciComponentName     = {\r
+  EhciComponentNameGetDriverName,\r
+  EhciComponentNameGetControllerName,\r
+  "eng"\r
+};\r
+\r
+static EFI_UNICODE_STRING_TABLE mEhciDriverNameTable[] = {\r
+  { "eng", L"UEFI Usb Ehci Driver" },\r
+  { NULL , NULL }\r
+};\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+EhciComponentNameGetDriverName (\r
+  IN  EFI_COMPONENT_NAME_PROTOCOL     *This,\r
+  IN  CHAR8                           *Language,\r
+  OUT CHAR16                          **DriverName\r
+  )\r
+/*++\r
+\r
+  Routine Description:\r
+    Retrieves a Unicode string that is the user readable name of the EFI Driver.\r
+\r
+  Arguments:\r
+    This       - A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.\r
+    Language   - A pointer to a three character ISO 639-2 language identifier.\r
+                 This is the language of the driver name that that the caller \r
+                 is requesting, and it must match one of the languages specified\r
+                 in SupportedLanguages.  The number of languages supported by a \r
+                 driver is up to the driver writer.\r
+    DriverName - A pointer to the Unicode string to return.  This Unicode string\r
+                 is the name of the driver specified by This in the language \r
+                 specified by Language.\r
+\r
+  Returns:\r
+    EFI_SUCCESS           - The Unicode string for the Driver specified by This\r
+                            and the language specified by Language was returned \r
+                            in DriverName.\r
+    EFI_INVALID_PARAMETER - Language is NULL.\r
+    EFI_INVALID_PARAMETER - DriverName is NULL.\r
+    EFI_UNSUPPORTED       - The driver specified by This does not support the \r
+                            language specified by Language.\r
+\r
+--*/\r
+{\r
+  return LookupUnicodeString (\r
+           Language,\r
+           gEhciComponentName.SupportedLanguages,\r
+           mEhciDriverNameTable,\r
+           DriverName\r
+           );\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+EhciComponentNameGetControllerName (\r
+  IN  EFI_COMPONENT_NAME_PROTOCOL     *This,\r
+  IN  EFI_HANDLE                      ControllerHandle,\r
+  IN  EFI_HANDLE                      ChildHandle, OPTIONAL\r
+  IN  CHAR8                           *Language,\r
+  OUT CHAR16                          **ControllerName\r
+  )\r
+/*++\r
+\r
+  Routine Description:\r
+    Retrieves a Unicode string that is the user readable name of the controller\r
+    that is being managed by an EFI Driver.\r
+\r
+  Arguments:\r
+    This             - A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.\r
+    ControllerHandle - The handle of a controller that the driver specified by \r
+                       This is managing.  This handle specifies the controller \r
+                       whose name is to be returned.\r
+    ChildHandle      - The handle of the child controller to retrieve the name \r
+                       of.  This is an optional parameter that may be NULL.  It \r
+                       will be NULL for device drivers.  It will also be NULL \r
+                       for a bus drivers that wish to retrieve the name of the \r
+                       bus controller.  It will not be NULL for a bus driver \r
+                       that wishes to retrieve the name of a child controller.\r
+    Language         - A pointer to a three character ISO 639-2 language \r
+                       identifier.  This is the language of the controller name \r
+                       that that the caller is requesting, and it must match one\r
+                       of the languages specified in SupportedLanguages.  The \r
+                       number of languages supported by a driver is up to the \r
+                       driver writer.\r
+    ControllerName   - A pointer to the Unicode string to return.  This Unicode\r
+                       string is the name of the controller specified by \r
+                       ControllerHandle and ChildHandle in the language \r
+                       specified by Language from the point of view of the \r
+                       driver specified by This. \r
+\r
+  Returns:\r
+    EFI_SUCCESS           - The Unicode string for the user readable name in the \r
+                            language specified by Language for the driver \r
+                            specified by This was returned in DriverName.\r
+    EFI_INVALID_PARAMETER - ControllerHandle is not a valid EFI_HANDLE.\r
+    EFI_INVALID_PARAMETER - ChildHandle is not NULL and it is not a valid \r
+                            EFI_HANDLE.\r
+    EFI_INVALID_PARAMETER - Language is NULL.\r
+    EFI_INVALID_PARAMETER - ControllerName is NULL.\r
+    EFI_UNSUPPORTED       - The driver specified by This is not currently \r
+                            managing the controller specified by \r
+                            ControllerHandle and ChildHandle.\r
+    EFI_UNSUPPORTED       - The driver specified by This does not support the \r
+                            language specified by Language.\r
+\r
+--*/\r
+{\r
+  EFI_STATUS           Status;\r
+  USB2_HC_DEV          *EhciDev;\r
+  EFI_USB2_HC_PROTOCOL  *Usb2Hc;\r
+\r
+  //\r
+  // This is a device driver, so ChildHandle must be NULL.\r
+  //\r
+  if (ChildHandle != NULL) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+  //\r
+  // Get the device context\r
+  //\r
+  Status = gBS->OpenProtocol (\r
+                  ControllerHandle,\r
+                  &gEfiUsb2HcProtocolGuid,\r
+                  (VOID **) &Usb2Hc,\r
+                  gEhciDriverBinding.DriverBindingHandle,\r
+                  ControllerHandle,\r
+                  EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
+                  );\r
+\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  EhciDev = USB2_HC_DEV_FROM_THIS (Usb2Hc);\r
+\r
+  return LookupUnicodeString (\r
+           Language,\r
+           gEhciComponentName.SupportedLanguages,\r
+           EhciDev->ControllerNameTable,\r
+           ControllerName\r
+           );\r
+\r
+}\r
diff --git a/EdkModulePkg/Bus/Pci/Ehci/Dxe/Ehci.c b/EdkModulePkg/Bus/Pci/Ehci/Dxe/Ehci.c
new file mode 100644 (file)
index 0000000..e7d359e
--- /dev/null
@@ -0,0 +1,2821 @@
+/*++\r
+\r
+Copyright (c) 2006, Intel Corporation                                                         \r
+All rights reserved. This program and the accompanying materials                          \r
+are licensed and made available under the terms and conditions of the BSD License         \r
+which accompanies this distribution.  The full text of the license may be found at        \r
+http://opensource.org/licenses/bsd-license.php                                            \r
+                                                                                          \r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     \r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             \r
+\r
+Module Name:\r
+\r
+    Ehci.c\r
+    \r
+Abstract: \r
+    \r
+\r
+Revision History\r
+--*/\r
+\r
+\r
+#include "Ehci.h"\r
+\r
+UINTN                       gEHCDebugLevel  = EFI_D_INFO;\r
+UINTN                       gEHCErrorLevel  = EFI_D_ERROR;\r
+\r
+//\r
+// Prototypes\r
+// Driver model protocol interface\r
+//\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+EhciDriverBindingSupported (\r
+  IN EFI_DRIVER_BINDING_PROTOCOL     *This,\r
+  IN EFI_HANDLE                      Controller,\r
+  IN EFI_DEVICE_PATH_PROTOCOL        *RemainingDevicePath\r
+  );\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+EhciDriverBindingStart (\r
+  IN EFI_DRIVER_BINDING_PROTOCOL     *This,\r
+  IN EFI_HANDLE                      Controller,\r
+  IN EFI_DEVICE_PATH_PROTOCOL        *RemainingDevicePath\r
+  );\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+EhciDriverBindingStop (\r
+  IN  EFI_DRIVER_BINDING_PROTOCOL     *This,\r
+  IN  EFI_HANDLE                      Controller,\r
+  IN  UINTN                           NumberOfChildren,\r
+  IN  EFI_HANDLE                      *ChildHandleBuffer\r
+  );\r
+\r
+//\r
+// Ehci protocol interface\r
+//\r
+EFI_STATUS\r
+EFIAPI\r
+EhciGetCapability (\r
+  IN  EFI_USB2_HC_PROTOCOL   *This,\r
+  OUT UINT8                  *MaxSpeed,\r
+  OUT UINT8                  *PortNumber,\r
+  OUT UINT8                  *Is64BitCapable\r
+  );\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+EhciReset (\r
+  IN  EFI_USB2_HC_PROTOCOL     *This,\r
+  IN  UINT16                   Attributes\r
+  );\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+EhciGetState (\r
+  IN  EFI_USB2_HC_PROTOCOL     *This,\r
+  OUT EFI_USB_HC_STATE         *State\r
+  );\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+EhciSetState (\r
+  IN  EFI_USB2_HC_PROTOCOL     *This,\r
+  IN  EFI_USB_HC_STATE         State\r
+  );\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+EhciControlTransfer (\r
+  IN  EFI_USB2_HC_PROTOCOL                 *This,\r
+  IN  UINT8                                DeviceAddress,\r
+  IN  UINT8                                DeviceSpeed,\r
+  IN  UINTN                                MaximumPacketLength,\r
+  IN  EFI_USB_DEVICE_REQUEST               *Request,\r
+  IN  EFI_USB_DATA_DIRECTION               TransferDirection,\r
+  IN  OUT VOID                             *Data,\r
+  IN  OUT UINTN                            *DataLength,\r
+  IN  UINTN                                TimeOut,\r
+  IN  EFI_USB2_HC_TRANSACTION_TRANSLATOR   *Translator,\r
+  OUT UINT32                               *TransferResult\r
+  );\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+EhciBulkTransfer (\r
+  IN  EFI_USB2_HC_PROTOCOL                *This,\r
+  IN  UINT8                               DeviceAddress,\r
+  IN  UINT8                               EndPointAddress,\r
+  IN  UINT8                               DeviceSpeed,\r
+  IN  UINTN                               MaximumPacketLength,\r
+  IN  UINT8                               DataBuffersNumber,\r
+  IN  OUT VOID                            *Data[EFI_USB_MAX_BULK_BUFFER_NUM],\r
+  IN  OUT UINTN                           *DataLength,\r
+  IN  OUT UINT8                           *DataToggle,\r
+  IN  UINTN                               TimeOut,\r
+  IN  EFI_USB2_HC_TRANSACTION_TRANSLATOR  *Translator,\r
+  OUT UINT32                              *TransferResult\r
+  );\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+EhciAsyncInterruptTransfer (\r
+  IN  EFI_USB2_HC_PROTOCOL                  * This,\r
+  IN  UINT8                                 DeviceAddress,\r
+  IN  UINT8                                 EndPointAddress,\r
+  IN  UINT8                                 DeviceSpeed,\r
+  IN  UINTN                                 MaxiumPacketLength,\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
+EFI_STATUS\r
+EFIAPI\r
+EhciSyncInterruptTransfer (\r
+  IN  EFI_USB2_HC_PROTOCOL                  *This,\r
+  IN  UINT8                                 DeviceAddress,\r
+  IN  UINT8                                 EndPointAddress,\r
+  IN  UINT8                                 DeviceSpeed,\r
+  IN  UINTN                                 MaximumPacketLength,\r
+  IN  OUT VOID                              *Data,\r
+  IN  OUT UINTN                             *DataLength,\r
+  IN  OUT UINT8                             *DataToggle,\r
+  IN  UINTN                                 TimeOut,\r
+  IN  EFI_USB2_HC_TRANSACTION_TRANSLATOR    *Translator,\r
+  OUT UINT32                                *TransferResult\r
+  );\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+EhciIsochronousTransfer (\r
+  IN  EFI_USB2_HC_PROTOCOL                  *This,\r
+  IN  UINT8                                 DeviceAddress,\r
+  IN  UINT8                                 EndPointAddress,\r
+  IN  UINT8                                 DeviceSpeed,\r
+  IN  UINTN                                 MaximumPacketLength,\r
+  IN  UINT8                                 DataBuffersNumber,\r
+  IN  OUT VOID                              *Data[EFI_USB_MAX_ISO_BUFFER_NUM],\r
+  IN  UINTN                                 DataLength,\r
+  IN  EFI_USB2_HC_TRANSACTION_TRANSLATOR    *Translator,\r
+  OUT UINT32                                *TransferResult\r
+  );\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+EhciAsyncIsochronousTransfer (\r
+  IN  EFI_USB2_HC_PROTOCOL                *This,\r
+  IN  UINT8                               DeviceAddress,\r
+  IN  UINT8                               EndPointAddress,\r
+  IN  UINT8                               DeviceSpeed,\r
+  IN  UINTN                               MaximumPacketLength,\r
+  IN  UINT8                               DataBuffersNumber,\r
+  IN  OUT VOID                            *Data[EFI_USB_MAX_ISO_BUFFER_NUM],\r
+  IN  UINTN                               DataLength,\r
+  IN  EFI_USB2_HC_TRANSACTION_TRANSLATOR  *Translator,\r
+  IN  EFI_ASYNC_USB_TRANSFER_CALLBACK     IsochronousCallBack,\r
+  IN  VOID                                *Context\r
+  );\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+EhciGetRootHubPortStatus (\r
+  IN  EFI_USB2_HC_PROTOCOL     *This,\r
+  IN  UINT8                    PortNumber,\r
+  OUT EFI_USB_PORT_STATUS      *PortStatus\r
+  );\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+EhciSetRootHubPortFeature (\r
+  IN  EFI_USB2_HC_PROTOCOL     *This,\r
+  IN  UINT8                    PortNumber,\r
+  IN  EFI_USB_PORT_FEATURE     PortFeature\r
+  );\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+EhciClearRootHubPortFeature (\r
+  IN  EFI_USB2_HC_PROTOCOL     *This,\r
+  IN  UINT8                    PortNumber,\r
+  IN  EFI_USB_PORT_FEATURE     PortFeature\r
+  );\r
+\r
+//\r
+// Ehci Driver Global Variables\r
+//\r
+EFI_DRIVER_BINDING_PROTOCOL gEhciDriverBinding = {\r
+  EhciDriverBindingSupported,\r
+  EhciDriverBindingStart,\r
+  EhciDriverBindingStop,\r
+  0x10,\r
+  NULL,\r
+  NULL\r
+};\r
+\r
+UINT32                      mUsbCapabilityLen;\r
+UINT32                      mDeviceSpeed[16];\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+EhciDriverBindingSupported (\r
+  IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
+  IN EFI_HANDLE                  Controller,\r
+  IN EFI_DEVICE_PATH_PROTOCOL    *RemainingDevicePath\r
+  )\r
+/*++\r
+\r
+  Routine Description:\r
+  \r
+    Test to see if this driver supports ControllerHandle. Any ControllerHandle\r
+    that has Usb2HcProtocol installed will be supported.\r
+\r
+  Arguments:\r
+  \r
+    This                - Protocol instance pointer.\r
+    Controlle           - Handle of device to test\r
+    RemainingDevicePath - Not used\r
+\r
+  Returns:\r
+  \r
+    EFI_SUCCESS       This driver supports this device.\r
+    EFI_UNSUPPORTED   This driver does not support this device.\r
+\r
+--*/\r
+{\r
+  EFI_STATUS          Status;\r
+  EFI_PCI_IO_PROTOCOL *PciIo;\r
+  USB_CLASSC          UsbClassCReg;\r
+\r
+  \r
+  //\r
+  // Test whether there is PCI IO Protocol attached on the controller handle.\r
+  //\r
+  Status = gBS->OpenProtocol (\r
+                  Controller,\r
+                  &gEfiPciIoProtocolGuid,\r
+                  (VOID **) &PciIo,\r
+                  This->DriverBindingHandle,\r
+                  Controller,\r
+                  EFI_OPEN_PROTOCOL_BY_DRIVER\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    goto exit;\r
+  }\r
+\r
+  Status = PciIo->Pci.Read (\r
+                        PciIo,\r
+                        EfiPciIoWidthUint8,\r
+                        CLASSC,\r
+                        sizeof (USB_CLASSC) / sizeof (UINT8),\r
+                        &UsbClassCReg\r
+                        );\r
+  if (EFI_ERROR (Status)) {\r
+    gBS->CloseProtocol (\r
+          Controller,\r
+          &gEfiPciIoProtocolGuid,\r
+          This->DriverBindingHandle,\r
+          Controller\r
+          );\r
+    Status = EFI_UNSUPPORTED;\r
+    goto exit;\r
+  }\r
+  \r
+  //\r
+  // Test whether the controller belongs to Ehci type\r
+  //\r
+  if ((UsbClassCReg.BaseCode != PCI_CLASS_SERIAL) ||\r
+      (UsbClassCReg.SubClassCode != PCI_CLASS_SERIAL_USB) ||\r
+      (UsbClassCReg.PI != PCI_CLASSC_PI_EHCI)\r
+      ) {\r
+\r
+    gBS->CloseProtocol (\r
+           Controller,\r
+           &gEfiPciIoProtocolGuid,\r
+           This->DriverBindingHandle,\r
+           Controller\r
+           );\r
+\r
+    Status = EFI_UNSUPPORTED;\r
+    goto exit;\r
+  }\r
+\r
+  gBS->CloseProtocol (\r
+         Controller,\r
+         &gEfiPciIoProtocolGuid,\r
+         This->DriverBindingHandle,\r
+         Controller\r
+         );\r
+\r
+exit:\r
+  return Status;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+EhciDriverBindingStart (\r
+  IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
+  IN EFI_HANDLE                  Controller,\r
+  IN EFI_DEVICE_PATH_PROTOCOL    *RemainingDevicePath\r
+  )\r
+/*++\r
+\r
+  Routine Description:\r
+  \r
+    Starting the Usb EHCI Driver\r
+\r
+  Arguments:\r
+  \r
+    This                - Protocol instance pointer.\r
+    Controller          - Handle of device to test\r
+    RemainingDevicePath - Not used\r
+\r
+  Returns:\r
+  \r
+    EFI_SUCCESS           supports this device.\r
+    EFI_UNSUPPORTED       do not support this device.\r
+    EFI_DEVICE_ERROR      cannot be started due to device Error\r
+    EFI_OUT_OF_RESOURCES  cannot allocate resources\r
+\r
+--*/\r
+{\r
+  EFI_STATUS            Status;\r
+  USB2_HC_DEV           *HcDev;\r
+  EFI_PCI_IO_PROTOCOL   *PciIo;\r
+  UINT8                 MaxSpeed;\r
+  UINT8                 PortNumber;\r
+  UINT8                 Is64BitCapable;\r
+  \r
+  //\r
+  // Open the PciIo Protocol\r
+  //\r
+  Status = gBS->OpenProtocol (\r
+                  Controller,\r
+                  &gEfiPciIoProtocolGuid,\r
+                  (VOID **) &PciIo,\r
+                  This->DriverBindingHandle,\r
+                  Controller,\r
+                  EFI_OPEN_PROTOCOL_BY_DRIVER\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    Status = EFI_OUT_OF_RESOURCES;\r
+    goto exit;\r
+  }\r
+  \r
+  //\r
+  // Enable the USB Host Controller\r
+  //\r
+  Status = PciIo->Attributes (\r
+                    PciIo,\r
+                    EfiPciIoAttributeOperationEnable,\r
+                    EFI_PCI_DEVICE_ENABLE,\r
+                    NULL\r
+                    );\r
+  if (EFI_ERROR (Status)) {\r
+    Status = EFI_OUT_OF_RESOURCES;\r
+    goto close_pciio_protocol;\r
+  }\r
+  \r
+  //\r
+  // Allocate memory for EHC private data structure\r
+  //\r
+  HcDev = AllocateZeroPool (sizeof (USB2_HC_DEV));\r
+  if (NULL == HcDev) {\r
+    Status = EFI_OUT_OF_RESOURCES;\r
+    goto close_pciio_protocol;\r
+  }\r
+  \r
+  //\r
+  // Init EFI_USB2_HC_PROTOCOL interface and private data structure\r
+  //\r
+  HcDev->Usb2Hc.GetCapability             = EhciGetCapability;\r
+  HcDev->Usb2Hc.Reset                     = EhciReset;\r
+  HcDev->Usb2Hc.GetState                  = EhciGetState;\r
+  HcDev->Usb2Hc.SetState                  = EhciSetState;\r
+  HcDev->Usb2Hc.ControlTransfer           = EhciControlTransfer;\r
+  HcDev->Usb2Hc.BulkTransfer              = EhciBulkTransfer;\r
+  HcDev->Usb2Hc.AsyncInterruptTransfer    = EhciAsyncInterruptTransfer;\r
+  HcDev->Usb2Hc.SyncInterruptTransfer     = EhciSyncInterruptTransfer;\r
+  HcDev->Usb2Hc.IsochronousTransfer       = EhciIsochronousTransfer;\r
+  HcDev->Usb2Hc.AsyncIsochronousTransfer  = EhciAsyncIsochronousTransfer;\r
+  HcDev->Usb2Hc.GetRootHubPortStatus      = EhciGetRootHubPortStatus;\r
+  HcDev->Usb2Hc.SetRootHubPortFeature     = EhciSetRootHubPortFeature;\r
+  HcDev->Usb2Hc.ClearRootHubPortFeature   = EhciClearRootHubPortFeature;\r
+  HcDev->Usb2Hc.MajorRevision             = 0x1;\r
+  HcDev->Usb2Hc.MinorRevision             = 0x1;\r
+\r
+  HcDev->AsyncRequestList                 = NULL;\r
+  HcDev->ControllerNameTable              = NULL;\r
+  HcDev->Signature                        = USB2_HC_DEV_SIGNATURE;\r
+  HcDev->PciIo = PciIo;\r
+\r
+  //\r
+  // Install USB2_HC_PROTOCOL\r
+  //\r
+  Status = gBS->InstallProtocolInterface (\r
+                  &Controller,\r
+                  &gEfiUsb2HcProtocolGuid,\r
+                  EFI_NATIVE_INTERFACE,\r
+                  &HcDev->Usb2Hc\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    Status = EFI_OUT_OF_RESOURCES;\r
+    goto free_pool;\r
+  }\r
+  \r
+  //\r
+  // Get Capability Register Length\r
+  //\r
+  Status = GetCapabilityLen (HcDev);\r
+  if (EFI_ERROR (Status)) {\r
+    Status = EFI_DEVICE_ERROR;\r
+    goto uninstall_usb2hc_protocol;\r
+  }\r
+  \r
+  //\r
+  // Create and Init Perodic Frame List\r
+  //\r
+  Status = EhciGetCapability (\r
+             &HcDev->Usb2Hc, \r
+             &MaxSpeed, \r
+             &PortNumber, \r
+             &Is64BitCapable\r
+             );\r
+  if (EFI_ERROR (Status)) {\r
+    Status = EFI_OUT_OF_RESOURCES;\r
+    goto uninstall_usb2hc_protocol;\r
+  }\r
+  HcDev->Is64BitCapable = Is64BitCapable;\r
+  \r
+  //\r
+  // Create and Init Perodic Frame List\r
+  //\r
+  Status = InitialPeriodicFrameList (\r
+             HcDev, \r
+             EHCI_MAX_FRAME_LIST_LENGTH\r
+             );\r
+  if (EFI_ERROR (Status)) {\r
+    Status = EFI_OUT_OF_RESOURCES;\r
+    goto uninstall_usb2hc_protocol;\r
+  }\r
+  \r
+  //\r
+  // Init memory pool management\r
+  //\r
+  Status = InitialMemoryManagement (HcDev);\r
+  if (EFI_ERROR (Status)) {\r
+    Status = EFI_OUT_OF_RESOURCES;\r
+    goto deinit_perodic_frame_list;\r
+  }\r
+  \r
+  //\r
+  // Create AsyncRequest Polling Timer\r
+  //\r
+  Status = CreatePollingTimer (HcDev, AsyncRequestMoniter);\r
+  if (EFI_ERROR (Status)) {\r
+    Status = EFI_OUT_OF_RESOURCES;\r
+    goto deinit_memory_management;\r
+  }\r
+  \r
+  //\r
+  // Default Maxximum Interrupt Interval is 8, \r
+  // it means that 8 micro frame = 1ms\r
+  //\r
+  \r
+  //\r
+  // Start the Host Controller\r
+  //\r
+  if (IsEhcHalted (HcDev)) {\r
+    Status = StartScheduleExecution (HcDev);\r
+    if (EFI_ERROR (Status)) {\r
+      Status = EFI_DEVICE_ERROR;\r
+      goto deinit_timer;\r
+    }\r
+  }\r
+  \r
+  //\r
+  // Set all ports routing to EHC\r
+  //\r
+  Status = SetPortRoutingEhc (HcDev);\r
+  if (EFI_ERROR (Status)) {\r
+    Status = EFI_DEVICE_ERROR;\r
+    goto deinit_timer;\r
+  }\r
+  \r
+  //\r
+  // Component name protocol\r
+  //\r
+  Status = AddUnicodeString (\r
+             "eng",\r
+             gEhciComponentName.SupportedLanguages,\r
+             &HcDev->ControllerNameTable,\r
+             L"Usb Enhanced Host Controller"\r
+             );\r
+  if (EFI_ERROR (Status)) {\r
+    Status = EFI_OUT_OF_RESOURCES;\r
+    goto deinit_timer;\r
+  }\r
+\r
+  goto exit;\r
+\r
+  //\r
+  // Error handle process\r
+  //\r
+deinit_timer:\r
+  DestoryPollingTimer (HcDev);\r
+deinit_memory_management:\r
+  DeinitialMemoryManagement (HcDev);\r
+deinit_perodic_frame_list:\r
+  DeinitialPeriodicFrameList (HcDev);\r
+uninstall_usb2hc_protocol:\r
+  gBS->UninstallProtocolInterface (\r
+         Controller,\r
+         &gEfiUsb2HcProtocolGuid,\r
+         &HcDev->Usb2Hc\r
+         );\r
+free_pool:\r
+  gBS->FreePool (HcDev);\r
+close_pciio_protocol:\r
+  gBS->CloseProtocol (\r
+         Controller,\r
+         &gEfiPciIoProtocolGuid,\r
+         This->DriverBindingHandle,\r
+         Controller\r
+         );\r
+\r
+exit:\r
+  return Status;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+EhciDriverBindingStop (\r
+  IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
+  IN EFI_HANDLE                  Controller,\r
+  IN UINTN                       NumberOfChildren,\r
+  IN EFI_HANDLE                  *ChildHandleBuffer\r
+  )\r
+/*++\r
+\r
+  Routine Description:\r
+  \r
+    Stop this driver on ControllerHandle. Support stoping any child handles\r
+    created by this driver.\r
+\r
+  Arguments:\r
+  \r
+    This              - Protocol instance pointer.\r
+    Controller        - Handle of device to stop driver on\r
+    NumberOfChildren  - Number of Children in the ChildHandleBuffer\r
+    ChildHandleBuffer - List of handles for the children we need to stop.\r
+\r
+  Returns:\r
+  \r
+    EFI_SUCCESS         Success\r
+    EFI_DEVICE_ERROR    Fail\r
+--*/\r
+{\r
+  EFI_STATUS            Status;\r
+  EFI_USB2_HC_PROTOCOL  *Usb2Hc;\r
+  USB2_HC_DEV           *HcDev;\r
+\r
+  //\r
+  // Test whether the Controller handler passed in is a valid\r
+  // Usb controller handle that should be supported, if not,\r
+  // return the error status directly\r
+  //\r
+  Status = gBS->OpenProtocol (\r
+                  Controller,\r
+                  &gEfiUsb2HcProtocolGuid,\r
+                  (VOID **) &Usb2Hc,\r
+                  This->DriverBindingHandle,\r
+                  Controller,\r
+                  EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    Status = EFI_DEVICE_ERROR;\r
+    goto exit;\r
+  }\r
+\r
+  HcDev = USB2_HC_DEV_FROM_THIS (Usb2Hc);\r
+\r
+  //\r
+  // free all the controller related memory and uninstall UHCI Protocol.\r
+  //\r
+  Status = gBS->UninstallProtocolInterface (\r
+                  Controller,\r
+                  &gEfiUsb2HcProtocolGuid,\r
+                  Usb2Hc\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    Status = EFI_DEVICE_ERROR;\r
+    goto exit;\r
+  }\r
+  \r
+  //\r
+  // Set Host Controller state as halt\r
+  //\r
+  Status = Usb2Hc->SetState (\r
+                     Usb2Hc, \r
+                     EfiUsbHcStateHalt\r
+                     );\r
+  if (EFI_ERROR (Status)) {\r
+    Status = EFI_DEVICE_ERROR;\r
+    goto exit;\r
+  }\r
+  \r
+  //\r
+  // Stop AsyncRequest Polling Timer\r
+  //\r
+  Status = StopPollingTimer (HcDev);\r
+  if (EFI_ERROR (Status)) {\r
+    Status = EFI_DEVICE_ERROR;\r
+    goto exit;\r
+  }\r
+  \r
+  //\r
+  // Destroy Asynchronous Request Event\r
+  //\r
+  DestoryPollingTimer (HcDev);\r
+\r
+  //\r
+  // Destroy Perodic Frame List\r
+  //\r
+  DeinitialPeriodicFrameList (HcDev);\r
+\r
+  //\r
+  // Deinit Ehci pool memory management\r
+  //\r
+  DeinitialMemoryManagement (HcDev);\r
+\r
+  //\r
+  // Denint Unicode String Table\r
+  //\r
+  FreeUnicodeStringTable (HcDev->ControllerNameTable);\r
+\r
+  //\r
+  // Disable the USB Host Controller\r
+  //\r
+  Status = HcDev->PciIo->Attributes (\r
+                           HcDev->PciIo,\r
+                           EfiPciIoAttributeOperationDisable,\r
+                           EFI_PCI_DEVICE_ENABLE,\r
+                           NULL\r
+                           );\r
+  if (EFI_ERROR (Status)) {\r
+    Status = EFI_DEVICE_ERROR;\r
+    goto exit;\r
+  }\r
+\r
+  gBS->FreePool (HcDev);\r
+\r
+  gBS->CloseProtocol (\r
+        Controller,\r
+        &gEfiPciIoProtocolGuid,\r
+        This->DriverBindingHandle,\r
+        Controller\r
+        );\r
+\r
+exit:\r
+  return Status;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+EhciGetCapability (\r
+  IN  EFI_USB2_HC_PROTOCOL *This,\r
+  OUT UINT8                *MaxSpeed,\r
+  OUT UINT8                *PortNumber,\r
+  OUT UINT8                *Is64BitCapable\r
+  )\r
+/*++\r
+  \r
+  Routine Description:\r
+  \r
+    Retrieves the capablility of root hub ports.\r
+    \r
+  Arguments:\r
+  \r
+    This            - A pointer to the EFI_USB_HC_PROTOCOL instance.\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            host controller capability were retrieved successfully.\r
+    EFI_INVALID_PARAMETER  MaxSpeed or PortNumber or Is64BitCapable is NULL.\r
+    EFI_DEVICE_ERROR       An error was encountered while attempting to retrieve the capabilities.  \r
+          \r
+--*/\r
+{\r
+  EFI_STATUS  Status;\r
+  USB2_HC_DEV *HcDev;\r
+  UINT32      HcStructParamsAddr;\r
+  UINT32      HcStructParamsReg;\r
+  UINT32      HcCapParamsAddr;\r
+  UINT32      HcCapParamsReg;\r
+\r
+  if (MaxSpeed == NULL || PortNumber == NULL || Is64BitCapable == NULL) {\r
+    Status = EFI_INVALID_PARAMETER;\r
+    goto exit;\r
+  }\r
+\r
+  HcStructParamsAddr  = HCSPARAMS;\r
+  HcCapParamsAddr     = HCCPARAMS;\r
+  HcDev               = USB2_HC_DEV_FROM_THIS (This);\r
+\r
+  Status = ReadEhcCapabiltiyReg (\r
+             HcDev,\r
+             HcStructParamsAddr,\r
+             &HcStructParamsReg\r
+             );\r
+  if (EFI_ERROR (Status)) {\r
+    Status = EFI_DEVICE_ERROR;\r
+    goto exit;\r
+  }\r
+\r
+  Status = ReadEhcCapabiltiyReg (\r
+             HcDev,\r
+             HcCapParamsAddr,\r
+             &HcCapParamsReg\r
+             );\r
+  if (EFI_ERROR (Status)) {\r
+    Status = EFI_DEVICE_ERROR;\r
+    goto exit;\r
+  }\r
+\r
+  *MaxSpeed       = EFI_USB_SPEED_HIGH;\r
+  *PortNumber     = (UINT8) (HcStructParamsReg & HCSP_NPORTS);\r
+  *Is64BitCapable = (UINT8) (HcCapParamsReg & HCCP_64BIT);\r
+\r
+exit:\r
+  return Status;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+EhciReset (\r
+  IN EFI_USB2_HC_PROTOCOL *This,\r
+  IN UINT16               Attributes\r
+  )\r
+/*++\r
+  \r
+  Routine Description:\r
+  \r
+    Provides software reset for the USB host controller.\r
+  \r
+  Arguments:\r
+  \r
+  This        - A pointer to the EFI_USB2_HC_PROTOCOL instance.  \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\r
+  #define EFI_USB_HC_RESET_HOST_CONTROLLER  0x0002\r
+  #define EFI_USB_HC_RESET_GLOBAL_WITH_DEBUG  0x0004\r
+  #define EFI_USB_HC_RESET_HOST_WITH_DEBUG  0x0008\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
+  USB2_HC_DEV       *HcDev;\r
+  UINTN             FrameIndex;\r
+  FRAME_LIST_ENTRY  *FrameEntryPtr;\r
+\r
+  HcDev = USB2_HC_DEV_FROM_THIS (This);\r
+\r
+  switch (Attributes) {\r
+\r
+  case EFI_USB_HC_RESET_GLOBAL:\r
+    \r
+    //\r
+    // Same behavior as Host Controller Reset\r
+    //\r
+\r
+  case EFI_USB_HC_RESET_HOST_CONTROLLER:\r
+       \r
+    //\r
+    // Host Controller must be Halt when Reset it\r
+    //\r
+    if (IsEhcHalted (HcDev)) {\r
+      Status = ResetEhc (HcDev);\r
+      if (EFI_ERROR (Status)) {\r
+        Status = EFI_DEVICE_ERROR;\r
+        goto exit;\r
+      }\r
+      //\r
+      // Set to zero by Host Controller when reset process completes\r
+      //\r
+      Status = WaitForEhcReset (HcDev, EHCI_GENERIC_TIMEOUT);\r
+      if (EFI_ERROR (Status)) {\r
+        Status = EFI_TIMEOUT;\r
+        goto exit;\r
+      }\r
+    } else {\r
+      Status = EFI_DEVICE_ERROR;\r
+      goto exit;\r
+    }\r
+\r
+    //\r
+    // only asynchronous interrupt transfers are always alive on the bus, need to cleanup\r
+    //\r
+    CleanUpAllAsyncRequestTransfer (HcDev);\r
+    Status = ClearEhcAllStatus (HcDev);\r
+    if (EFI_ERROR (Status)) {\r
+      Status = EFI_DEVICE_ERROR;\r
+      goto exit;\r
+    }\r
+\r
+    //\r
+    // Set appropriate 4G Segment Selector\r
+    //\r
+    Status = SetCtrlDataStructSeg (HcDev);\r
+    if (EFI_ERROR (Status)) {\r
+      Status = EFI_DEVICE_ERROR;\r
+      goto exit;\r
+    }\r
+\r
+    //\r
+    // Init Perodic List Base Addr and Frame List\r
+    //\r
+    Status = SetFrameListBaseAddr (\r
+               HcDev, \r
+               (UINT32) GET_0B_TO_31B (HcDev->PeriodicFrameListBuffer)\r
+               );\r
+    if (EFI_ERROR (Status)) {\r
+      Status = EFI_DEVICE_ERROR;\r
+      goto exit;\r
+    }\r
+    FrameEntryPtr = (FRAME_LIST_ENTRY *) HcDev->PeriodicFrameListBuffer;\r
+    for (FrameIndex = 0; FrameIndex < HcDev->PeriodicFrameListLength; FrameIndex++) {\r
+      FrameEntryPtr->LinkTerminate = TRUE;\r
+      FrameEntryPtr++;\r
+    }\r
+\r
+    //\r
+    // Start the Host Controller\r
+    //\r
+    if (IsEhcHalted (HcDev)) {\r
+      Status = StartScheduleExecution (HcDev);\r
+      if (EFI_ERROR (Status)) {\r
+        Status = EFI_DEVICE_ERROR;\r
+        goto exit;\r
+      }\r
+    }\r
+\r
+    //\r
+    // Set all ports routing to EHC\r
+    //\r
+    Status = SetPortRoutingEhc (HcDev);\r
+    if (EFI_ERROR (Status)) {\r
+      Status = EFI_DEVICE_ERROR;\r
+      goto exit;\r
+    }\r
+    break;\r
+\r
+  case EFI_USB_HC_RESET_GLOBAL_WITH_DEBUG:\r
+       \r
+    Status = EFI_UNSUPPORTED;\r
+    break;\r
+\r
+  case EFI_USB_HC_RESET_HOST_WITH_DEBUG:\r
+       \r
+    Status = EFI_UNSUPPORTED;\r
+    break;\r
+\r
+  default:\r
+    Status = EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+exit:\r
+  return Status;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+EhciGetState (\r
+  IN  EFI_USB2_HC_PROTOCOL *This,\r
+  OUT EFI_USB_HC_STATE     *State\r
+  )\r
+/*++\r
+  \r
+  Routine Description:\r
+  \r
+    Retrieves current state of the USB host controller.\r
+  \r
+  Arguments:\r
+    \r
+    This      A pointer to the EFI_USB2_HC_PROTOCOL instance.\r
+    State     A pointer to the EFI_USB_HC_STATE data structure that \r
+              indicates current state of the USB host controller.  \r
+              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
+  EFI_STATUS  Status;\r
+  USB2_HC_DEV *HcDev;\r
+  UINT32      UsbStatusAddr;\r
+  UINT32      UsbStatusReg;\r
+\r
+  if (State == NULL) {\r
+    Status = EFI_INVALID_PARAMETER;\r
+    goto exit;\r
+  }\r
+\r
+  UsbStatusAddr = USBSTS;\r
+  HcDev         = USB2_HC_DEV_FROM_THIS (This);\r
+\r
+  Status = ReadEhcOperationalReg (\r
+             HcDev,\r
+             UsbStatusAddr,\r
+             &UsbStatusReg\r
+             );\r
+  if (EFI_ERROR (Status)) {\r
+    Status = EFI_DEVICE_ERROR;\r
+    goto exit;\r
+  }\r
+\r
+  if (UsbStatusReg & USBSTS_HCH) {\r
+    *State = EfiUsbHcStateHalt;\r
+  } else {\r
+    *State = EfiUsbHcStateOperational;\r
+  }\r
+\r
+exit:\r
+  return Status;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+EhciSetState (\r
+  IN EFI_USB2_HC_PROTOCOL *This,\r
+  IN EFI_USB_HC_STATE     State\r
+  )\r
+/*++\r
+  \r
+  Routine Description:\r
+  \r
+    Sets the USB host controller to a specific state.\r
+  \r
+  Arguments:\r
+    \r
+    This     - A pointer to the EFI_USB2_HC_PROTOCOL instance.\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
+  USB2_HC_DEV       *HcDev;\r
+  UINT32            UsbCommandAddr;\r
+  UINT32            UsbCommandReg;\r
+  EFI_USB_HC_STATE  CurrentState;\r
+\r
+  UsbCommandAddr  = USBCMD;\r
+  HcDev           = USB2_HC_DEV_FROM_THIS (This);\r
+\r
+  Status          = EhciGetState (This, &CurrentState);\r
+  if (EFI_ERROR (Status)) {\r
+    Status = EFI_DEVICE_ERROR;\r
+    goto exit;\r
+  }\r
+\r
+  switch (State) {\r
+\r
+  case EfiUsbHcStateHalt:\r
+\r
+    if (EfiUsbHcStateHalt == CurrentState) {\r
+      Status = EFI_SUCCESS;\r
+      goto exit;\r
+    } else if (EfiUsbHcStateOperational == CurrentState) {\r
+      Status = ReadEhcOperationalReg (\r
+                 HcDev,\r
+                 UsbCommandAddr,\r
+                 &UsbCommandReg\r
+                 );\r
+      if (EFI_ERROR (Status)) {\r
+        Status = EFI_DEVICE_ERROR;\r
+        goto exit;\r
+      }\r
+\r
+      UsbCommandReg &= ~USBCMD_RS;\r
+      Status = WriteEhcOperationalReg (\r
+                 HcDev,\r
+                 UsbCommandAddr,\r
+                 UsbCommandReg\r
+                 );\r
+      if (EFI_ERROR (Status)) {\r
+        Status = EFI_DEVICE_ERROR;\r
+        goto exit;\r
+      }\r
+      //\r
+      // Ensure the HC is in halt status after send the stop command\r
+      //\r
+      Status = WaitForEhcHalt (HcDev, EHCI_GENERIC_TIMEOUT);\r
+      if (EFI_ERROR (Status)) {\r
+        Status = EFI_TIMEOUT;\r
+        goto exit;\r
+      }\r
+    }\r
+    break;\r
+\r
+  case EfiUsbHcStateOperational:\r
+       \r
+    if (IsEhcSysError (HcDev)) {\r
+      Status = EFI_DEVICE_ERROR;\r
+      goto exit;\r
+    }\r
+    if (EfiUsbHcStateOperational == CurrentState) {\r
+      Status = EFI_SUCCESS;\r
+      goto exit;\r
+    } else if (EfiUsbHcStateHalt == CurrentState) {\r
+      //\r
+      // Set Host Controller Run\r
+      //\r
+      Status = ReadEhcOperationalReg (\r
+                 HcDev,\r
+                 UsbCommandAddr,\r
+                 &UsbCommandReg\r
+                 );\r
+      if (EFI_ERROR (Status)) {\r
+        return EFI_DEVICE_ERROR;\r
+      }\r
+\r
+      UsbCommandReg |= USBCMD_RS;\r
+      Status = WriteEhcOperationalReg (\r
+                 HcDev,\r
+                 UsbCommandAddr,\r
+                 UsbCommandReg\r
+                 );\r
+      if (EFI_ERROR (Status)) {\r
+        Status = EFI_DEVICE_ERROR;\r
+        goto exit;\r
+      }\r
+    }\r
+    break;\r
+\r
+  case EfiUsbHcStateSuspend:\r
+       \r
+    Status = EFI_UNSUPPORTED;\r
+    break;\r
+\r
+  default:\r
+       \r
+    Status = EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+exit:\r
+  return Status;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+EhciGetRootHubPortStatus (\r
+  IN  EFI_USB2_HC_PROTOCOL *This,\r
+  IN  UINT8                PortNumber,\r
+  OUT EFI_USB_PORT_STATUS  *PortStatus\r
+  )\r
+/*++\r
+  \r
+  Routine Description:\r
+  \r
+    Retrieves the current status of a USB root hub port.\r
+  \r
+  Arguments:\r
+  \r
+    This        - A pointer to the EFI_USB2_HC_PROTOCOL.\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 \r
+                          by PortNumber 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
+  USB2_HC_DEV *HcDev;\r
+  UINT32      PortStatusControlAddr;\r
+  UINT32      PortStatusControlReg;\r
+  UINT8       MaxSpeed;\r
+  UINT8       TotalPortNumber;\r
+  UINT8       Is64BitCapable;\r
+\r
+  if (PortStatus == NULL) {\r
+    Status = EFI_INVALID_PARAMETER;\r
+    goto exit;\r
+  }\r
+\r
+  EhciGetCapability (\r
+    This, \r
+    &MaxSpeed, \r
+    &TotalPortNumber, \r
+    &Is64BitCapable\r
+    );\r
+  \r
+  if (PortNumber >= TotalPortNumber) {\r
+    Status = EFI_INVALID_PARAMETER;\r
+    goto exit;\r
+  }\r
+\r
+  HcDev                 = USB2_HC_DEV_FROM_THIS (This);\r
+  PortStatusControlAddr = (UINT32) (PORTSC + (4 * PortNumber));\r
+\r
+  //\r
+  // Clear port status\r
+  //\r
+  PortStatus->PortStatus        = 0;\r
+  PortStatus->PortChangeStatus  = 0;\r
+\r
+  Status = ReadEhcOperationalReg (\r
+             HcDev,\r
+             PortStatusControlAddr,\r
+             &PortStatusControlReg\r
+             );\r
+  if (EFI_ERROR (Status)) {\r
+    Status = EFI_DEVICE_ERROR;\r
+    goto exit;\r
+  }\r
+  \r
+  //\r
+  //    Fill Port Status bits\r
+  //\r
+  \r
+  //\r
+  // Current Connect Status\r
+  //\r
+  if (PORTSC_CCS & PortStatusControlReg) {\r
+    PortStatus->PortStatus |= USB_PORT_STAT_CONNECTION;\r
+  }\r
+  //\r
+  // Port Enabled/Disabled\r
+  //\r
+  if (PORTSC_PED & PortStatusControlReg) {\r
+    PortStatus->PortStatus |= USB_PORT_STAT_ENABLE;\r
+  }\r
+  //\r
+  // Port Suspend\r
+  //\r
+  if (PORTSC_SUSP & PortStatusControlReg) {\r
+    PortStatus->PortStatus |= USB_PORT_STAT_SUSPEND;\r
+  }\r
+  //\r
+  // Over-current Active\r
+  //\r
+  if (PORTSC_OCA & PortStatusControlReg) {\r
+    PortStatus->PortStatus |= USB_PORT_STAT_OVERCURRENT;\r
+  }\r
+  //\r
+  // Port Reset\r
+  //\r
+  if (PORTSC_PR & PortStatusControlReg) {\r
+    PortStatus->PortStatus |= USB_PORT_STAT_RESET;\r
+  }\r
+  //\r
+  // Port Power\r
+  //\r
+  if (PORTSC_PP & PortStatusControlReg) {\r
+    PortStatus->PortStatus |= USB_PORT_STAT_POWER;\r
+  }\r
+  //\r
+  // Port Owner\r
+  //\r
+  if (PORTSC_PO & PortStatusControlReg) {\r
+    PortStatus->PortStatus |= USB_PORT_STAT_OWNER;\r
+  }\r
+  //\r
+  // Identify device speed\r
+  //\r
+  if (PORTSC_LS_KSTATE & PortStatusControlReg) {\r
+    //\r
+    // Low Speed Device Attached\r
+    //\r
+    PortStatus->PortStatus |= USB_PORT_STAT_LOW_SPEED;\r
+  } else {\r
+    //\r
+    // Not Low Speed Device Attached\r
+    //\r
+    if ((PORTSC_CCS & PortStatusControlReg) && (PORTSC_CSC & PortStatusControlReg)) {\r
+      mDeviceSpeed[PortNumber] = IsHighSpeedDevice (This, PortNumber) ? USB_PORT_STAT_HIGH_SPEED : 0;\r
+    }\r
+    PortStatus->PortStatus |= mDeviceSpeed[PortNumber];\r
+  }\r
+  //\r
+  // Fill Port Status Change bits\r
+  //\r
+  //\r
+  // Connect Status Change\r
+  //\r
+  if (PORTSC_CSC & PortStatusControlReg) {\r
+    PortStatus->PortChangeStatus |= USB_PORT_STAT_C_CONNECTION;\r
+  }\r
+  //\r
+  // Port Enabled/Disabled Change\r
+  //\r
+  if (PORTSC_PEDC & PortStatusControlReg) {\r
+    PortStatus->PortChangeStatus |= USB_PORT_STAT_C_ENABLE;\r
+  }\r
+  //\r
+  // Port Over Current Change\r
+  //\r
+  if (PORTSC_OCC & PortStatusControlReg) {\r
+    PortStatus->PortChangeStatus |= USB_PORT_STAT_C_OVERCURRENT;\r
+  }\r
+\r
+exit:\r
+  return Status;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+EhciSetRootHubPortFeature (\r
+  IN  EFI_USB2_HC_PROTOCOL     *This,\r
+  IN  UINT8                    PortNumber,\r
+  IN  EFI_USB_PORT_FEATURE     PortFeature\r
+  )\r
+/*++\r
+  \r
+  Routine Description:\r
+  \r
+    Sets a feature for the specified root hub port.\r
+  \r
+  Arguments:\r
+  \r
+    This        - A pointer to the EFI_USB2_HC_PROTOCOL.\r
+    PortNumber  - Specifies the root hub port whose feature \r
+                  is requested to be set.\r
+    PortFeature - Indicates the feature selector associated \r
+                  with the feature set request. \r
+  \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
+  USB2_HC_DEV *HcDev;\r
+  UINT32      PortStatusControlAddr;\r
+  UINT32      PortStatusControlReg;\r
+  UINT8       MaxSpeed;\r
+  UINT8       TotalPortNumber;\r
+  UINT8       Is64BitCapable;\r
+\r
+  EhciGetCapability (\r
+    This, \r
+    &MaxSpeed, \r
+    &TotalPortNumber, \r
+    &Is64BitCapable\r
+    );\r
+\r
+  if (PortNumber >= TotalPortNumber) {\r
+    Status = EFI_INVALID_PARAMETER;\r
+    goto exit;\r
+  }\r
+\r
+  HcDev                 = USB2_HC_DEV_FROM_THIS (This);\r
+  PortStatusControlAddr = (UINT32) (PORTSC + (4 * PortNumber));\r
+\r
+  Status = ReadEhcOperationalReg (\r
+             HcDev,\r
+             PortStatusControlAddr,\r
+             &PortStatusControlReg\r
+             );\r
+  if (EFI_ERROR (Status)) {\r
+    Status = EFI_DEVICE_ERROR;\r
+    goto exit;\r
+  }\r
+\r
+  switch (PortFeature) {\r
+\r
+  case EfiUsbPortEnable:\r
+  \r
+    //\r
+    // Sofeware can't set this bit, Port can only be enable by the Host Controller\r
+    // as a part of the reset and enable\r
+    //\r
+    PortStatusControlReg &= 0xffffffd5;\r
+    PortStatusControlReg |= PORTSC_PED;\r
+    break;\r
+\r
+  case EfiUsbPortSuspend:\r
+  \r
+    PortStatusControlReg &= 0xffffffd5;\r
+    PortStatusControlReg |= PORTSC_SUSP;\r
+    break;\r
+\r
+  case EfiUsbPortReset:\r
+  \r
+    //\r
+    // Make sure Host Controller not halt before reset it\r
+    //\r
+    if (IsEhcHalted (HcDev)) {\r
+      Status = StartScheduleExecution (HcDev);\r
+      if (EFI_ERROR (Status)) {\r
+        Status = EFI_DEVICE_ERROR;\r
+        goto exit;\r
+      }\r
+      Status = WaitForEhcNotHalt (HcDev, EHCI_GENERIC_TIMEOUT);\r
+      if (EFI_ERROR (Status)) {\r
+        DEBUG ((gEHCDebugLevel, "WaitForEhcNotHalt TimeOut\n"));\r
+        Status = EFI_DEVICE_ERROR;\r
+        goto exit;\r
+      }\r
+    }\r
+    PortStatusControlReg &= 0xffffffd5;\r
+    PortStatusControlReg |= PORTSC_PR;\r
+    //\r
+    // Set one to PortReset bit must also set zero to PortEnable bit\r
+    //\r
+    PortStatusControlReg &= ~PORTSC_PED;\r
+    break;\r
+\r
+  case EfiUsbPortPower:\r
+    \r
+    //\r
+    // No support, no operation\r
+    //\r
+    goto exit;\r
+\r
+  case EfiUsbPortOwner:\r
+  \r
+    PortStatusControlReg &= 0xffffffd5;\r
+    PortStatusControlReg |= PORTSC_PO;\r
+    break;\r
+\r
+  default:\r
+       \r
+    Status = EFI_INVALID_PARAMETER;\r
+    goto exit;\r
+  }\r
+\r
+  Status = WriteEhcOperationalReg (\r
+             HcDev,\r
+             PortStatusControlAddr,\r
+             PortStatusControlReg\r
+             );\r
+  if (EFI_ERROR (Status)) {\r
+    Status = EFI_DEVICE_ERROR;\r
+  }\r
+\r
+exit:\r
+  return Status;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+EhciClearRootHubPortFeature (\r
+  IN  EFI_USB2_HC_PROTOCOL     *This,\r
+  IN  UINT8                    PortNumber,\r
+  IN  EFI_USB_PORT_FEATURE     PortFeature\r
+  )\r
+/*++\r
+  \r
+  Routine Description:\r
+  \r
+    Clears a feature for the specified root hub port.\r
+  \r
+  Arguments:\r
+  \r
+    This        - A pointer to the EFI_USB2_HC_PROTOCOL instance. \r
+    PortNumber  - Specifies the root hub port whose feature \r
+                  is requested to be cleared.\r
+    PortFeature - Indicates the feature selector associated with the \r
+                  feature clear request.\r
+                  \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
+  USB2_HC_DEV *HcDev;\r
+  UINT32      PortStatusControlAddr;\r
+  UINT32      PortStatusControlReg;\r
+  UINT8       MaxSpeed;\r
+  UINT8       TotalPortNumber;\r
+  UINT8       Is64BitCapable;\r
+\r
+  EhciGetCapability (\r
+    This, \r
+    &MaxSpeed, \r
+    &TotalPortNumber, \r
+    &Is64BitCapable\r
+    );\r
+\r
+  if (PortNumber >= TotalPortNumber) {\r
+    Status = EFI_INVALID_PARAMETER;\r
+    goto exit;\r
+  }\r
+\r
+  HcDev                 = USB2_HC_DEV_FROM_THIS (This);\r
+  PortStatusControlAddr = (UINT32) (PORTSC + (4 * PortNumber));\r
+\r
+  Status = ReadEhcOperationalReg (\r
+             HcDev,\r
+             PortStatusControlAddr,\r
+             &PortStatusControlReg\r
+             );\r
+  if (EFI_ERROR (Status)) {\r
+    Status = EFI_DEVICE_ERROR;\r
+    goto exit;\r
+  }\r
+\r
+  switch (PortFeature) {\r
+\r
+  case EfiUsbPortEnable:\r
+  \r
+    //\r
+    // Clear PORT_ENABLE feature means disable port.\r
+    //\r
+    PortStatusControlReg &= 0xffffffd5;\r
+    PortStatusControlReg &= ~PORTSC_PED;\r
+    break;\r
+\r
+  case EfiUsbPortSuspend:\r
+  \r
+    //\r
+    // A write of zero to this bit is ignored by the host controller.\r
+    // The host controller will unconditionally set this bit to a zero when:\r
+    //   1. software sets the Forct Port Resume bit to a zero from a one.\r
+    //   2. software sets the Port Reset bit to a one frome a zero.\r
+    //\r
+    PortStatusControlReg &= 0xffffffd5;\r
+    PortStatusControlReg &= ~PORTSC_FPR;\r
+    break;\r
+\r
+  case EfiUsbPortReset:\r
+  \r
+    //\r
+    // Clear PORT_RESET means clear the reset signal.\r
+    //\r
+    PortStatusControlReg &= 0xffffffd5;\r
+    PortStatusControlReg &= ~PORTSC_PR;\r
+    break;\r
+\r
+  case EfiUsbPortPower:\r
+  \r
+    //\r
+    // No support, no operation\r
+    //\r
+    goto exit;\r
+\r
+  case EfiUsbPortOwner:\r
+  \r
+    //\r
+    // Clear port owner means this port owned by EHC\r
+    //\r
+    PortStatusControlReg &= 0xffffffd5;\r
+    PortStatusControlReg &= ~PORTSC_PO;\r
+    break;\r
+\r
+  case EfiUsbPortConnectChange:\r
+  \r
+    //\r
+    // Clear connect status change\r
+    //\r
+    PortStatusControlReg &= 0xffffffd5;\r
+    PortStatusControlReg |= PORTSC_CSC;\r
+    break;\r
+\r
+  case EfiUsbPortEnableChange:\r
+  \r
+    //\r
+    // Clear enable status change\r
+    //\r
+    PortStatusControlReg &= 0xffffffd5;\r
+    PortStatusControlReg |= PORTSC_PEDC;\r
+    break;\r
+\r
+  case EfiUsbPortSuspendChange:\r
+  \r
+    //\r
+    // No related bit, no operation\r
+    //\r
+    goto exit;\r
+\r
+  case EfiUsbPortOverCurrentChange:\r
+  \r
+    //\r
+    // Clear PortOverCurrent change\r
+    //\r
+    PortStatusControlReg &= 0xffffffd5;\r
+    PortStatusControlReg |= PORTSC_OCC;\r
+    break;\r
+\r
+  case EfiUsbPortResetChange:\r
+  \r
+    //\r
+    // No related bit, no operation\r
+    //\r
+    goto exit;\r
+\r
+  default:\r
+       \r
+    Status = EFI_INVALID_PARAMETER;\r
+    goto exit;\r
+  }\r
+\r
+  Status = WriteEhcOperationalReg (\r
+             HcDev,\r
+             PortStatusControlAddr,\r
+             PortStatusControlReg\r
+             );\r
+  if (EFI_ERROR (Status)) {\r
+    Status = EFI_DEVICE_ERROR;\r
+    goto exit;\r
+  }\r
+\r
+exit:\r
+  return Status;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+EhciControlTransfer (\r
+  IN  EFI_USB2_HC_PROTOCOL                 *This,\r
+  IN  UINT8                                DeviceAddress,\r
+  IN  UINT8                                DeviceSpeed,\r
+  IN  UINTN                                MaximumPacketLength,\r
+  IN  EFI_USB_DEVICE_REQUEST               *Request,\r
+  IN  EFI_USB_DATA_DIRECTION               TransferDirection,\r
+  IN  OUT VOID                             *Data,\r
+  IN  OUT UINTN                            *DataLength,\r
+  IN  UINTN                                TimeOut,\r
+  IN  EFI_USB2_HC_TRANSACTION_TRANSLATOR   *Translator,\r
+  OUT UINT32                               *TransferResult\r
+  )\r
+/*++\r
+  \r
+  Routine Description:\r
+  \r
+    Submits control transfer to a target USB device.\r
+  \r
+  Arguments:\r
+    \r
+    This            - A pointer to the EFI_USB2_HC_PROTOCOL instance.\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
+  USB2_HC_DEV     *HcDev;\r
+  UINT8           PktId;\r
+  EHCI_QH_ENTITY  *QhPtr;\r
+  EHCI_QTD_ENTITY *ControlQtdsPtr;\r
+  UINT8           *DataCursor;\r
+  VOID            *DataMap;\r
+  UINT8           *RequestCursor;\r
+  VOID            *RequestMap;\r
+\r
+  QhPtr           = NULL;\r
+  ControlQtdsPtr  = NULL;\r
+  DataCursor      = NULL;\r
+  DataMap         = NULL;\r
+  RequestCursor   = NULL;\r
+  RequestMap      = NULL;\r
+  HcDev           = USB2_HC_DEV_FROM_THIS (This);\r
+\r
+  //\r
+  // Parameters Checking\r
+  //\r
+  if (TransferDirection != EfiUsbDataIn &&\r
+       TransferDirection != EfiUsbDataOut &&\r
+       TransferDirection != EfiUsbNoData\r
+       ) {\r
+    Status = EFI_INVALID_PARAMETER;\r
+    goto exit;\r
+  }\r
+\r
+  if (EfiUsbNoData == TransferDirection) {\r
+    if (NULL != Data || 0 != *DataLength) {\r
+      Status = EFI_INVALID_PARAMETER;\r
+      goto exit;\r
+    }\r
+  } else {\r
+    if (NULL == Data || 0 == *DataLength) {\r
+      Status = EFI_INVALID_PARAMETER;\r
+      goto exit;\r
+    }\r
+  }\r
+\r
+  if (Request == NULL || TransferResult == NULL) {\r
+    Status = EFI_INVALID_PARAMETER;\r
+    goto exit;\r
+  }\r
+\r
+  if (EFI_USB_SPEED_LOW == DeviceSpeed) {\r
+    if (MaximumPacketLength != 8) {\r
+      Status = EFI_INVALID_PARAMETER;\r
+      goto exit;\r
+    }\r
+  } else if (MaximumPacketLength != 8 &&\r
+           MaximumPacketLength != 16 &&\r
+           MaximumPacketLength != 32 &&\r
+           MaximumPacketLength != 64\r
+          ) {\r
+    Status = EFI_INVALID_PARAMETER;\r
+    goto exit;\r
+  }\r
+  \r
+  //\r
+  // If errors exist that cause host controller halt,\r
+  // then return EFI_DEVICE_ERROR.\r
+  //\r
+  if (IsEhcHalted (HcDev) || IsEhcSysError (HcDev)) {\r
+    ClearEhcAllStatus (HcDev);\r
+    *TransferResult = EFI_USB_ERR_SYSTEM;\r
+    Status          = EFI_DEVICE_ERROR;\r
+    goto exit;\r
+  }\r
+  \r
+  //\r
+  // Map the Request for bus master access.\r
+  // BusMasterRead means cpu write\r
+  //\r
+  Status = MapRequestBuffer (\r
+             HcDev,\r
+             Request,\r
+             &RequestCursor,\r
+             &RequestMap\r
+             );\r
+  if (EFI_ERROR (Status)) {\r
+    *TransferResult = EFI_USB_ERR_SYSTEM;\r
+    Status          = EFI_DEVICE_ERROR;\r
+    goto exit;\r
+  }\r
+  \r
+  //\r
+  // Map the source data buffer for bus master access.\r
+  //\r
+  Status = MapDataBuffer (\r
+             HcDev,\r
+             TransferDirection,\r
+             Data,\r
+             DataLength,\r
+             &PktId,\r
+             &DataCursor,\r
+             &DataMap\r
+             );\r
+  if (EFI_ERROR (Status)) {\r
+    *TransferResult = EFI_USB_ERR_SYSTEM;\r
+    Status          = EFI_DEVICE_ERROR;\r
+    goto unmap_request;\r
+  }\r
+  \r
+  //\r
+  // Create and init control Qh\r
+  //\r
+  Status = CreateControlQh (\r
+             HcDev,\r
+             DeviceAddress,\r
+             DeviceSpeed,\r
+             MaximumPacketLength,\r
+             Translator,\r
+             &QhPtr\r
+             );\r
+  if (EFI_ERROR (Status)) {\r
+    *TransferResult = EFI_USB_ERR_SYSTEM;\r
+    Status          = EFI_OUT_OF_RESOURCES;\r
+    goto unmap_data;\r
+  }\r
+  \r
+  //\r
+  // Create and init control Qtds\r
+  //\r
+  Status = CreateControlQtds (\r
+             HcDev,\r
+             PktId,\r
+             RequestCursor,\r
+             DataCursor,\r
+             *DataLength,\r
+             Translator,\r
+             &ControlQtdsPtr\r
+             );\r
+  if (EFI_ERROR (Status)) {\r
+    *TransferResult = EFI_USB_ERR_SYSTEM;\r
+    Status          = EFI_OUT_OF_RESOURCES;\r
+    goto destory_qh;\r
+  }\r
+  \r
+  //\r
+  // Link Qtds to Qh\r
+  //\r
+  LinkQtdToQh (QhPtr, ControlQtdsPtr);\r
+\r
+  ClearEhcAllStatus (HcDev);\r
+\r
+  //\r
+  // Link Qh and Qtds to Async Schedule List\r
+  //\r
+  Status = LinkQhToAsyncList (HcDev, QhPtr);\r
+  if (EFI_ERROR (Status)) {\r
+    *TransferResult = EFI_USB_ERR_SYSTEM;\r
+    Status          = EFI_DEVICE_ERROR;\r
+    goto destory_qtds;\r
+  }\r
+  \r
+  //\r
+  // Poll Qh-Qtds execution and get result.\r
+  // detail status is returned\r
+  //\r
+  Status = ExecuteTransfer (\r
+             HcDev,\r
+             TRUE,\r
+             QhPtr,\r
+             DataLength,\r
+             0,\r
+             TimeOut,\r
+             TransferResult\r
+             );\r
+  if (EFI_ERROR (Status)) {\r
+    goto destory_qtds;\r
+  }\r
+  \r
+  //\r
+  // If has errors that cause host controller halt,\r
+  // then return EFI_DEVICE_ERROR directly.\r
+  //\r
+  if (IsEhcHalted (HcDev) || IsEhcSysError (HcDev)) {\r
+    *TransferResult |= EFI_USB_ERR_SYSTEM;\r
+  }\r
+\r
+  ClearEhcAllStatus (HcDev);\r
+\r
+destory_qtds:\r
+  UnlinkQhFromAsyncList (HcDev, QhPtr);\r
+  DestoryQtds (HcDev, ControlQtdsPtr);\r
+destory_qh:\r
+  DestoryQh (HcDev, QhPtr);\r
+unmap_data:\r
+  HcDev->PciIo->Unmap (HcDev->PciIo, DataMap);\r
+unmap_request:\r
+  HcDev->PciIo->Unmap (HcDev->PciIo, RequestMap);\r
+exit:\r
+  HcDev->PciIo->Flush (HcDev->PciIo);\r
+  return Status;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+EhciBulkTransfer (\r
+  IN  EFI_USB2_HC_PROTOCOL                *This,\r
+  IN  UINT8                               DeviceAddress,\r
+  IN  UINT8                               EndPointAddress,\r
+  IN  UINT8                               DeviceSpeed,\r
+  IN  UINTN                               MaximumPacketLength,\r
+  IN  UINT8                               DataBuffersNumber,\r
+  IN  OUT VOID                            *Data[EFI_USB_MAX_BULK_BUFFER_NUM],\r
+  IN  OUT UINTN                           *DataLength,\r
+  IN  OUT UINT8                           *DataToggle,\r
+  IN  UINTN                               TimeOut,\r
+  IN  EFI_USB2_HC_TRANSACTION_TRANSLATOR  *Translator,\r
+  OUT UINT32                              *TransferResult\r
+  )\r
+/*++\r
+  \r
+  Routine Description:\r
+  \r
+    Submits bulk transfer to a bulk endpoint of a USB device.\r
+    \r
+  Arguments:\r
+    \r
+    This              - A pointer to the EFI_USB2_HC_PROTOCOL instance.\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
+  USB2_HC_DEV             *HcDev;\r
+  UINT8                   PktId;\r
+  EHCI_QH_ENTITY          *QhPtr;\r
+  EHCI_QTD_ENTITY         *BulkQtdsPtr;\r
+  UINT8                   *DataCursor;\r
+  VOID                    *DataMap;\r
+  EFI_USB_DATA_DIRECTION  TransferDirection;\r
+\r
+  QhPtr       = NULL;\r
+  BulkQtdsPtr = NULL;\r
+  DataCursor  = NULL;\r
+  DataMap     = NULL;\r
+  HcDev       = USB2_HC_DEV_FROM_THIS (This);\r
+\r
+  //\r
+  // Parameters Checking\r
+  //\r
+  if (NULL == DataLength ||\r
+       NULL == Data || \r
+       NULL == Data[0] || \r
+       NULL == TransferResult\r
+       ) {\r
+    Status = EFI_INVALID_PARAMETER;\r
+    goto exit;\r
+  }\r
+\r
+  if (*DataLength == 0) {\r
+    Status = EFI_INVALID_PARAMETER;\r
+    goto exit;\r
+  }\r
+\r
+  if (1 != *DataToggle && 0 != *DataToggle) {\r
+    Status = EFI_INVALID_PARAMETER;\r
+    goto exit;\r
+  }\r
+\r
+  if (EFI_USB_SPEED_LOW == DeviceSpeed) {\r
+    Status = EFI_INVALID_PARAMETER;\r
+    goto exit;\r
+  }\r
+\r
+  if (EFI_USB_SPEED_FULL == DeviceSpeed) {\r
+    if (MaximumPacketLength > 64) {\r
+      Status = EFI_INVALID_PARAMETER;\r
+      goto exit;\r
+    }\r
+  }\r
+\r
+  if (EFI_USB_SPEED_HIGH == DeviceSpeed) {\r
+    if (MaximumPacketLength > 512) {\r
+      Status = EFI_INVALID_PARAMETER;\r
+      goto exit;\r
+    }\r
+  }\r
+  \r
+  //\r
+  // if has errors that cause host controller halt,\r
+  // then return EFI_DEVICE_ERROR directly.\r
+  //\r
+  if (IsEhcHalted (HcDev) || IsEhcSysError (HcDev)) {\r
+    ClearEhcAllStatus (HcDev);\r
+    *TransferResult = EFI_USB_ERR_SYSTEM;\r
+    Status          = EFI_DEVICE_ERROR;\r
+    goto exit;\r
+  }\r
+\r
+  Status = ClearEhcAllStatus (HcDev);\r
+  if (EFI_ERROR (Status)) {\r
+    Status = EFI_DEVICE_ERROR;\r
+    goto exit;\r
+  }\r
+  \r
+  //\r
+  // construct QH and TD data structures,\r
+  // and link them together\r
+  //\r
+  if (EndPointAddress & 0x80) {\r
+    TransferDirection = EfiUsbDataIn;\r
+  } else {\r
+    TransferDirection = EfiUsbDataOut;\r
+  }\r
+\r
+  Status = MapDataBuffer (\r
+             HcDev,\r
+             TransferDirection,\r
+             Data[0],\r
+             DataLength,\r
+             &PktId,\r
+             &DataCursor,\r
+             &DataMap\r
+             );\r
+  if (EFI_ERROR (Status)) {\r
+    *TransferResult = EFI_USB_ERR_SYSTEM;\r
+    Status          = EFI_DEVICE_ERROR;\r
+    goto exit;\r
+  }\r
+  \r
+  //\r
+  // Create and init Bulk Qh\r
+  //\r
+  Status = CreateBulkQh (\r
+             HcDev,\r
+             DeviceAddress,\r
+             EndPointAddress,\r
+             DeviceSpeed,\r
+             *DataToggle,\r
+             MaximumPacketLength,\r
+             Translator,\r
+             &QhPtr\r
+             );\r
+  if (EFI_ERROR (Status)) {\r
+    *TransferResult = EFI_USB_ERR_SYSTEM;\r
+    Status          = EFI_OUT_OF_RESOURCES;\r
+    goto unmap_data;\r
+  }\r
+  \r
+  //\r
+  // Create and init Bulk Qtds\r
+  //\r
+  Status = CreateBulkOrInterruptQtds (\r
+             HcDev,\r
+             PktId,\r
+             DataCursor,\r
+             *DataLength,\r
+             Translator,\r
+             &BulkQtdsPtr\r
+             );\r
+  if (EFI_ERROR (Status)) {\r
+    *TransferResult = EFI_USB_ERR_SYSTEM;\r
+    Status          = EFI_OUT_OF_RESOURCES;\r
+    goto destory_qh;\r
+  }\r
+  \r
+  //\r
+  // Link Qtds to Qh\r
+  //\r
+  LinkQtdToQh (QhPtr, BulkQtdsPtr);\r
+\r
+  ClearEhcAllStatus (HcDev);\r
+\r
+  //\r
+  // Link Qh and qtds to Async Schedule List\r
+  //\r
+  Status = LinkQhToAsyncList (HcDev, QhPtr);\r
+  if (EFI_ERROR (Status)) {\r
+    *TransferResult = EFI_USB_ERR_SYSTEM;\r
+    Status          = EFI_DEVICE_ERROR;\r
+    goto destory_qtds;\r
+  }\r
+  \r
+  //\r
+  // Poll QH-TDs execution and get result.\r
+  // detail status is returned\r
+  //\r
+  Status = ExecuteTransfer (\r
+             HcDev,\r
+             FALSE,\r
+             QhPtr,\r
+             DataLength,\r
+             DataToggle,\r
+             TimeOut,\r
+             TransferResult\r
+             );\r
+  if (EFI_ERROR (Status)) {\r
+    goto destory_qtds;\r
+  }\r
+  \r
+  //\r
+  // if has errors that cause host controller halt,\r
+  // then return EFI_DEVICE_ERROR directly.\r
+  //\r
+  if (IsEhcHalted (HcDev) || IsEhcSysError (HcDev)) {\r
+    *TransferResult |= EFI_USB_ERR_SYSTEM;\r
+  }\r
+\r
+  ClearEhcAllStatus (HcDev);\r
+\r
+destory_qtds:\r
+  UnlinkQhFromAsyncList (HcDev, QhPtr);\r
+  DestoryQtds (HcDev, BulkQtdsPtr);\r
+destory_qh:\r
+  DestoryQh (HcDev, QhPtr);\r
+unmap_data:\r
+  HcDev->PciIo->Unmap (HcDev->PciIo, DataMap);\r
+exit:\r
+  HcDev->PciIo->Flush (HcDev->PciIo);\r
+  return Status;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+EhciAsyncInterruptTransfer (\r
+  IN  EFI_USB2_HC_PROTOCOL                  * This,\r
+  IN  UINT8                                 DeviceAddress,\r
+  IN  UINT8                                 EndPointAddress,\r
+  IN  UINT8                                 DeviceSpeed,\r
+  IN  UINTN                                 MaximumPacketLength,\r
+  IN  BOOLEAN                               IsNewTransfer,\r
+  IN  OUT UINT8                             *DataToggle,\r
+  IN  UINTN                                 PollingInterval,\r
+  IN  UINTN                                 DataLength,\r
+  IN  EFI_USB2_HC_TRANSACTION_TRANSLATOR    * Translator,\r
+  IN  EFI_ASYNC_USB_TRANSFER_CALLBACK       CallBackFunction,\r
+  IN  VOID                                  *Context OPTIONAL\r
+  )\r
+/*++\r
+  \r
+  Routine Description:\r
+  \r
+    Submits an asynchronous interrupt transfer to an \r
+    interrupt endpoint of a USB device.\r
+  \r
+  Arguments:\r
+    \r
+    This            - A pointer to the EFI_USB2_HC_PROTOCOL instance.\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
+  USB2_HC_DEV         *HcDev;\r
+  UINT8               PktId;\r
+  EHCI_QH_ENTITY      *QhPtr;\r
+  EHCI_QTD_ENTITY     *InterruptQtdsPtr;\r
+  UINT8               *DataPtr;\r
+  UINT8               *DataCursor;\r
+  VOID                *DataMap;\r
+  UINTN               MappedLength;\r
+  EHCI_ASYNC_REQUEST  *AsyncRequestPtr;\r
+  EFI_TPL             OldTpl;\r
+\r
+  QhPtr             = NULL;\r
+  InterruptQtdsPtr  = NULL;\r
+  DataPtr           = NULL;\r
+  DataCursor        = NULL;\r
+  DataMap           = NULL;\r
+  AsyncRequestPtr   = NULL;\r
+  HcDev             = USB2_HC_DEV_FROM_THIS (This);\r
+\r
+  //\r
+  // Parameters Checking\r
+  //\r
+  if (!IsDataInTransfer (EndPointAddress)) {\r
+    Status = EFI_INVALID_PARAMETER;\r
+    goto exit;\r
+  }\r
+\r
+  if (IsNewTransfer) {\r
+    if (0 == DataLength) {\r
+      Status = EFI_INVALID_PARAMETER;\r
+      goto exit;\r
+    }\r
+\r
+    if (*DataToggle != 1 && *DataToggle != 0) {\r
+      Status = EFI_INVALID_PARAMETER;\r
+      goto exit;\r
+    }\r
+\r
+    if (PollingInterval > 255 || PollingInterval < 1) {\r
+      Status = EFI_INVALID_PARAMETER;\r
+      goto exit;\r
+    }\r
+  }\r
+  \r
+  //\r
+  // if has errors that cause host controller halt,\r
+  // then return EFI_DEVICE_ERROR directly.\r
+  //\r
+  if (IsEhcHalted (HcDev) || IsEhcSysError (HcDev)) {\r
+    ClearEhcAllStatus (HcDev);\r
+    Status = EFI_DEVICE_ERROR;\r
+    goto exit;\r
+  }\r
+\r
+  Status = ClearEhcAllStatus (HcDev);\r
+  if (EFI_ERROR (Status)) {\r
+    Status = EFI_DEVICE_ERROR;\r
+    goto exit;\r
+  }\r
+  \r
+  //\r
+  // Delete Async interrupt transfer request\r
+  //\r
+  if (!IsNewTransfer) {\r
+\r
+    OldTpl = gBS->RaiseTPL (EFI_TPL_NOTIFY);\r
+\r
+    Status = DeleteAsyncRequestTransfer (\r
+               HcDev,\r
+               DeviceAddress,\r
+               EndPointAddress,\r
+               DataToggle\r
+               );\r
+\r
+    gBS->RestoreTPL (OldTpl);\r
+\r
+    goto exit;\r
+  }\r
+\r
+  Status = EhciAllocatePool (\r
+                HcDev, \r
+                (UINT8 **) &AsyncRequestPtr, \r
+                sizeof (EHCI_ASYNC_REQUEST)\r
+                );\r
+  if (EFI_ERROR (Status)) {\r
+    Status = EFI_OUT_OF_RESOURCES;\r
+    goto exit;\r
+  }\r
+\r
+  Status = EhciAllocatePool (HcDev, &DataPtr, DataLength);\r
+  if (EFI_ERROR (Status)) {\r
+    Status = EFI_OUT_OF_RESOURCES;\r
+    goto free_request;\r
+  }\r
+\r
+  MappedLength = DataLength;\r
+  Status = MapDataBuffer (\r
+             HcDev,\r
+             EfiUsbDataIn,\r
+             DataPtr,\r
+             &MappedLength,\r
+             &PktId,\r
+             &DataCursor,\r
+             &DataMap\r
+             );\r
+  if (EFI_ERROR (Status)) {\r
+    Status = EFI_DEVICE_ERROR;\r
+    goto free_data;\r
+  }\r
+  \r
+  //\r
+  // Create and init Interrupt Qh\r
+  //\r
+  Status = CreateInterruptQh (\r
+             HcDev,\r
+             DeviceAddress,\r
+             EndPointAddress,\r
+             DeviceSpeed,\r
+             *DataToggle,\r
+             MaximumPacketLength,\r
+             PollingInterval,\r
+             Translator,\r
+             &QhPtr\r
+             );\r
+  if (EFI_ERROR (Status)) {\r
+    Status = EFI_OUT_OF_RESOURCES;\r
+    goto unmap_data;\r
+  }\r
+  \r
+  //\r
+  // Create and init Interrupt Qtds\r
+  //\r
+  Status = CreateBulkOrInterruptQtds (\r
+             HcDev,\r
+             PktId,\r
+             DataCursor,\r
+             MappedLength,\r
+             Translator,\r
+             &InterruptQtdsPtr\r
+             );\r
+  if (EFI_ERROR (Status)) {\r
+    Status = EFI_OUT_OF_RESOURCES;\r
+    goto destory_qh;\r
+  }\r
+  \r
+  //\r
+  // Link Qtds to Qh\r
+  //\r
+  LinkQtdToQh (QhPtr, InterruptQtdsPtr);\r
+\r
+  //\r
+  // Init AsyncRequest Entry\r
+  //\r
+  AsyncRequestPtr->Context      = Context;\r
+  AsyncRequestPtr->CallBackFunc = CallBackFunction;\r
+  AsyncRequestPtr->TransferType = ASYNC_INTERRUPT_TRANSFER;\r
+  AsyncRequestPtr->QhPtr        = QhPtr;\r
+  AsyncRequestPtr->Prev         = NULL;\r
+  AsyncRequestPtr->Next         = NULL;\r
+\r
+  if (NULL == HcDev->AsyncRequestList) {\r
+    Status = StartPollingTimer (HcDev);\r
+    if (EFI_ERROR (Status)) {\r
+      Status = EFI_DEVICE_ERROR;\r
+      CleanUpAllAsyncRequestTransfer (HcDev);\r
+      goto exit;\r
+    }\r
+  }\r
+  \r
+  //\r
+  // Link Entry to AsyncRequest List\r
+  //\r
+  LinkToAsyncReqeust (HcDev, AsyncRequestPtr);\r
+\r
+  ClearEhcAllStatus (HcDev);\r
+\r
+  Status = DisablePeriodicSchedule (HcDev);\r
+  if (EFI_ERROR (Status)) {\r
+    Status = EFI_DEVICE_ERROR;\r
+    goto exit;\r
+  }\r
+\r
+  Status = WaitForPeriodicScheduleDisable (HcDev, EHCI_GENERIC_TIMEOUT);\r
+  if (EFI_ERROR (Status)) {\r
+    Status = EFI_TIMEOUT;\r
+    goto exit;\r
+  }\r
+  \r
+  //\r
+  // Link Qh and Qtds to Periodic Schedule List\r
+  //\r
+  LinkQhToPeriodicList (HcDev, QhPtr);\r
+\r
+  Status = EnablePeriodicSchedule (HcDev);\r
+  if (EFI_ERROR (Status)) {\r
+    Status = EFI_DEVICE_ERROR;\r
+    goto exit;\r
+  }\r
+\r
+  Status = WaitForPeriodicScheduleEnable (HcDev, EHCI_GENERIC_TIMEOUT);\r
+  if (EFI_ERROR (Status)) {\r
+    Status = EFI_TIMEOUT;\r
+    goto exit;\r
+  }\r
+\r
+  if (IsEhcHalted (HcDev)) {\r
+    Status = StartScheduleExecution (HcDev);\r
+    if (EFI_ERROR (Status)) {\r
+      Status = EFI_DEVICE_ERROR;\r
+      goto exit;\r
+    }\r
+  }\r
+\r
+  HcDev->PciIo->Flush (HcDev->PciIo);\r
+  goto exit;\r
+\r
+destory_qh:\r
+  DestoryQh (HcDev, QhPtr);\r
+free_data:\r
+  EhciFreePool (HcDev, DataPtr, DataLength);\r
+free_request:\r
+  EhciFreePool (\r
+       HcDev, \r
+       (UINT8 *) AsyncRequestPtr, \r
+       sizeof (EHCI_ASYNC_REQUEST)\r
+       );\r
+unmap_data:\r
+  HcDev->PciIo->Unmap (HcDev->PciIo, DataMap);\r
+exit:\r
+  return Status;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+EhciSyncInterruptTransfer (\r
+  IN  EFI_USB2_HC_PROTOCOL                  *This,\r
+  IN  UINT8                                 DeviceAddress,\r
+  IN  UINT8                                 EndPointAddress,\r
+  IN  UINT8                                 DeviceSpeed,\r
+  IN  UINTN                                 MaximumPacketLength,\r
+  IN  OUT VOID                              *Data,\r
+  IN  OUT UINTN                             *DataLength,\r
+  IN  OUT UINT8                             *DataToggle,\r
+  IN  UINTN                                 TimeOut,\r
+  IN  EFI_USB2_HC_TRANSACTION_TRANSLATOR    *Translator,\r
+  OUT UINT32                                *TransferResult\r
+  )\r
+/*++\r
+  \r
+  Routine Description:\r
+  \r
+    Submits synchronous interrupt transfer to an interrupt endpoint \r
+    of a USB device.\r
+  \r
+  Arguments:\r
+    \r
+    This            - A pointer to the EFI_USB2_HC_PROTOCOL instance.\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
+  USB2_HC_DEV     *HcDev;\r
+  UINT8           PktId;\r
+  EHCI_QH_ENTITY  *QhPtr;\r
+  EHCI_QTD_ENTITY *InterruptQtdsPtr;\r
+  UINT8           *DataCursor;\r
+  VOID            *DataMap;\r
+\r
+  QhPtr             = NULL;\r
+  InterruptQtdsPtr  = NULL;\r
+  DataCursor        = NULL;\r
+  DataMap           = NULL;\r
+  HcDev             = USB2_HC_DEV_FROM_THIS (This);\r
+\r
+  //\r
+  // Parameters Checking\r
+  //\r
+  if (DataLength == NULL ||\r
+       Data == NULL || \r
+       TransferResult == NULL\r
+       ) {\r
+    Status = EFI_INVALID_PARAMETER;\r
+    goto exit;\r
+  }\r
+\r
+  if (!IsDataInTransfer (EndPointAddress)) {\r
+    Status = EFI_INVALID_PARAMETER;\r
+    goto exit;\r
+  }\r
+\r
+  if (0 == *DataLength) {\r
+    Status = EFI_INVALID_PARAMETER;\r
+    goto exit;\r
+  }\r
+\r
+  if (*DataToggle != 1 && *DataToggle != 0) {\r
+    Status = EFI_INVALID_PARAMETER;\r
+    goto exit;\r
+  }\r
+\r
+  if (EFI_USB_SPEED_LOW == DeviceSpeed && 8 != MaximumPacketLength) {\r
+    Status = EFI_INVALID_PARAMETER;\r
+    goto exit;\r
+  }\r
+\r
+  if (EFI_USB_SPEED_FULL == DeviceSpeed && MaximumPacketLength > 64) {\r
+    Status = EFI_INVALID_PARAMETER;\r
+    goto exit;\r
+  }\r
+\r
+  if (EFI_USB_SPEED_HIGH == DeviceSpeed && MaximumPacketLength > 3072) {\r
+    Status = EFI_INVALID_PARAMETER;\r
+    goto exit;\r
+  }\r
+  \r
+  //\r
+  // if has errors that cause host controller halt,\r
+  // then return EFI_DEVICE_ERROR directly.\r
+  //\r
+  if (IsEhcHalted (HcDev) || IsEhcSysError (HcDev)) {\r
+    ClearEhcAllStatus (HcDev);\r
+    *TransferResult = EFI_USB_ERR_SYSTEM;\r
+    Status          = EFI_DEVICE_ERROR;\r
+    goto exit;\r
+  }\r
+\r
+  Status = ClearEhcAllStatus (HcDev);\r
+  if (EFI_ERROR (Status)) {\r
+    Status = EFI_DEVICE_ERROR;\r
+    goto exit;\r
+  }\r
+\r
+  Status = MapDataBuffer (\r
+             HcDev,\r
+             EfiUsbDataIn,\r
+             Data,\r
+             DataLength,\r
+             &PktId,\r
+             &DataCursor,\r
+             &DataMap\r
+             );\r
+  if (EFI_ERROR (Status)) {\r
+    *TransferResult = EFI_USB_ERR_SYSTEM;\r
+    Status          = EFI_DEVICE_ERROR;\r
+    goto exit;\r
+  }\r
+  \r
+  //\r
+  // Create and init Interrupt Qh\r
+  //\r
+  Status = CreateInterruptQh (\r
+             HcDev,\r
+             DeviceAddress,\r
+             EndPointAddress,\r
+             DeviceSpeed,\r
+             *DataToggle,\r
+             MaximumPacketLength,\r
+             0,\r
+             Translator,\r
+             &QhPtr\r
+             );\r
+  if (EFI_ERROR (Status)) {\r
+    Status = EFI_OUT_OF_RESOURCES;\r
+    goto unmap_data;\r
+  }\r
+  \r
+  //\r
+  // Create and init Interrupt Qtds\r
+  //\r
+  Status = CreateBulkOrInterruptQtds (\r
+             HcDev,\r
+             PktId,\r
+             DataCursor,\r
+             *DataLength,\r
+             Translator,\r
+             &InterruptQtdsPtr\r
+             );\r
+  if (EFI_ERROR (Status)) {\r
+    *TransferResult = EFI_USB_ERR_SYSTEM;\r
+    Status          = EFI_OUT_OF_RESOURCES;\r
+    goto destory_qh;\r
+  }\r
+  \r
+  //\r
+  // Link Qtds to Qh\r
+  //\r
+  LinkQtdToQh (QhPtr, InterruptQtdsPtr);\r
+\r
+  ClearEhcAllStatus (HcDev);\r
+\r
+  Status = DisablePeriodicSchedule (HcDev);\r
+  if (EFI_ERROR (Status)) {\r
+    Status = EFI_DEVICE_ERROR;\r
+    goto exit;\r
+  }\r
+\r
+  Status = WaitForPeriodicScheduleDisable (HcDev, EHCI_GENERIC_TIMEOUT);\r
+  if (EFI_ERROR (Status)) {\r
+    Status = EFI_TIMEOUT;\r
+    goto exit;\r
+  }\r
+  \r
+  //\r
+  // Link Qh and Qtds to Periodic Schedule List\r
+  //\r
+  LinkQhToPeriodicList (HcDev, QhPtr);\r
+\r
+  Status = EnablePeriodicSchedule (HcDev);\r
+  if (EFI_ERROR (Status)) {\r
+    Status = EFI_DEVICE_ERROR;\r
+    goto exit;\r
+  }\r
+\r
+  Status = WaitForPeriodicScheduleEnable (HcDev, EHCI_GENERIC_TIMEOUT);\r
+  if (EFI_ERROR (Status)) {\r
+    Status = EFI_TIMEOUT;\r
+    goto exit;\r
+  }\r
+\r
+  if (IsEhcHalted (HcDev)) {\r
+    Status = StartScheduleExecution (HcDev);\r
+    if (EFI_ERROR (Status)) {\r
+      Status = EFI_DEVICE_ERROR;\r
+      goto exit;\r
+    }\r
+  }\r
+  \r
+  //\r
+  // Poll QH-TDs execution and get result.\r
+  // detail status is returned\r
+  //\r
+  Status = ExecuteTransfer (\r
+             HcDev,\r
+             FALSE,\r
+             QhPtr,\r
+             DataLength,\r
+             DataToggle,\r
+             TimeOut,\r
+             TransferResult\r
+             );\r
+  if (EFI_ERROR (Status)) {\r
+    goto destory_qtds;\r
+  }\r
+  \r
+  //\r
+  // if has errors that cause host controller halt,\r
+  // then return EFI_DEVICE_ERROR directly.\r
+  //\r
+  if (IsEhcHalted (HcDev) || IsEhcSysError (HcDev)) {\r
+    *TransferResult |= EFI_USB_ERR_SYSTEM;\r
+  }\r
+\r
+  ClearEhcAllStatus (HcDev);\r
+\r
+destory_qtds:\r
+  UnlinkQhFromPeriodicList (HcDev, QhPtr, 0);\r
+  DestoryQtds (HcDev, InterruptQtdsPtr);\r
+destory_qh:\r
+  DestoryQh (HcDev, QhPtr);\r
+unmap_data:\r
+  HcDev->PciIo->Unmap (HcDev->PciIo, DataMap);\r
+exit:\r
+  HcDev->PciIo->Flush (HcDev->PciIo);\r
+  return Status;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+EhciIsochronousTransfer (\r
+  IN  EFI_USB2_HC_PROTOCOL                  *This,\r
+  IN  UINT8                                 DeviceAddress,\r
+  IN  UINT8                                 EndPointAddress,\r
+  IN  UINT8                                 DeviceSpeed,\r
+  IN  UINTN                                 MaximumPacketLength,\r
+  IN  UINT8                                 DataBuffersNumber,\r
+  IN  OUT VOID                              *Data[EFI_USB_MAX_ISO_BUFFER_NUM],\r
+  IN  UINTN                                 DataLength,\r
+  IN  EFI_USB2_HC_TRANSACTION_TRANSLATOR    *Translator,\r
+  OUT UINT32                                *TransferResult\r
+  )\r
+/*++\r
+  \r
+  Routine Description:\r
+  \r
+    Submits isochronous transfer to a target USB device.\r
+  \r
+  Arguments:\r
+    \r
+    This             - A pointer to the EFI_USB2_HC_PROTOCOL instance.\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
+EhciAsyncIsochronousTransfer (\r
+  IN  EFI_USB2_HC_PROTOCOL                *This,\r
+  IN  UINT8                               DeviceAddress,\r
+  IN  UINT8                               EndPointAddress,\r
+  IN  UINT8                               DeviceSpeed,\r
+  IN  UINTN                               MaximumPacketLength,\r
+  IN  UINT8                               DataBuffersNumber,\r
+  IN  OUT VOID                            *Data[EFI_USB_MAX_ISO_BUFFER_NUM],\r
+  IN  UINTN                               DataLength,\r
+  IN  EFI_USB2_HC_TRANSACTION_TRANSLATOR  *Translator,\r
+  IN  EFI_ASYNC_USB_TRANSFER_CALLBACK     IsochronousCallBack,\r
+  IN  VOID                                *Context\r
+  )\r
+/*++\r
+  \r
+  Routine Description:\r
+  \r
+    Submits Async isochronous transfer to a target USB device.\r
+  \r
+  Arguments:\r
+    \r
+    This                - A pointer to the EFI_USB2_HC_PROTOCOL instance.\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
+    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
diff --git a/EdkModulePkg/Bus/Pci/Ehci/Dxe/Ehci.h b/EdkModulePkg/Bus/Pci/Ehci/Dxe/Ehci.h
new file mode 100644 (file)
index 0000000..a5fa2be
--- /dev/null
@@ -0,0 +1,2689 @@
+/*++\r
+\r
+Copyright (c) 2006, Intel Corporation                                                         \r
+All rights reserved. This program and the accompanying materials                          \r
+are licensed and made available under the terms and conditions of the BSD License         \r
+which accompanies this distribution.  The full text of the license may be found at        \r
+http://opensource.org/licenses/bsd-license.php                                            \r
+                                                                                          \r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     \r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             \r
+\r
+Module Name:\r
+\r
+    Ehci.h\r
+    \r
+Abstract: \r
+    \r
+\r
+Revision History\r
+--*/\r
+\r
+#ifndef _EHCI_H\r
+#define _EHCI_H\r
+\r
+//\r
+// Universal Host Controller Interface data structures and defines\r
+//\r
+#include <IndustryStandard/pci22.h>\r
+\r
+#ifdef EFI_DEBUG\r
+extern UINTN  gEHCDebugLevel;\r
+extern UINTN  gEHCErrorLevel;\r
+#endif\r
+\r
+#define STALL_1_MACRO_SECOND              1\r
+#define STALL_1_MILLI_SECOND              1000 * STALL_1_MACRO_SECOND\r
+#define STALL_1_SECOND                    1000 * STALL_1_MILLI_SECOND\r
+\r
+#define SETUP_PACKET_PID_CODE             0x02\r
+#define INPUT_PACKET_PID_CODE             0x01\r
+#define OUTPUT_PACKET_PID_CODE            0x0\r
+\r
+#define ITD_SELECT_TYPE                   0x0\r
+#define QH_SELECT_TYPE                    0x01\r
+#define SITD_SELECT_TYPE                  0x02\r
+#define FSTN_SELECT_TYPE                  0x03\r
+\r
+#define EHCI_SET_PORT_RESET_RECOVERY_TIME     50 * STALL_1_MILLI_SECOND\r
+#define EHCI_CLEAR_PORT_RESET_RECOVERY_TIME   STALL_1_MILLI_SECOND\r
+#define EHCI_GENERIC_TIMEOUT                  50 * STALL_1_MILLI_SECOND\r
+#define EHCI_GENERIC_RECOVERY_TIME            50 * STALL_1_MACRO_SECOND\r
+#define EHCI_SYNC_REQUEST_POLLING_TIME        50 * STALL_1_MACRO_SECOND\r
+#define EHCI_ASYNC_REQUEST_POLLING_TIME       50 * STALL_1_MILLI_SECOND\r
+\r
+#define USB_BAR_INDEX                     0 /* how many bytes away from USB_BASE to 0x10 */\r
+\r
+#define NORMAL_MEMORY_BLOCK_UNIT_IN_PAGES 1\r
+\r
+#define EHCI_MIN_PACKET_SIZE              8\r
+#define EHCI_MAX_PACKET_SIZE              1024\r
+#define EHCI_MAX_FRAME_LIST_LENGTH        1024\r
+#define EHCI_BLOCK_SIZE_WITH_TT           64\r
+#define EHCI_BLOCK_SIZE                   512\r
+#define EHCI_MAX_QTD_CAPACITY             (EFI_PAGE_SIZE * 5)\r
+\r
+#define NAK_COUNT_RELOAD                  3\r
+#define QTD_ERROR_COUNTER                 1\r
+#define HIGH_BANDWIDTH_PIPE_MULTIPLIER    1\r
+\r
+#define QTD_STATUS_ACTIVE                 0x80\r
+#define QTD_STATUS_HALTED                 0x40\r
+#define QTD_STATUS_BUFFER_ERR             0x20\r
+#define QTD_STATUS_BABBLE_ERR             0x10\r
+#define QTD_STATUS_TRANSACTION_ERR        0x08\r
+#define QTD_STATUS_DO_STOP_SPLIT          0x02\r
+#define QTD_STATUS_DO_START_SPLIT         0\r
+#define QTD_STATUS_DO_PING                0x01\r
+#define QTD_STATUS_DO_OUT                 0\r
+\r
+#define DATA0                             0\r
+#define DATA1                             1\r
+\r
+#define MICRO_FRAME_0_CHANNEL             0x01\r
+#define MICRO_FRAME_1_CHANNEL             0x02\r
+#define MICRO_FRAME_2_CHANNEL             0x04\r
+#define MICRO_FRAME_3_CHANNEL             0x08\r
+#define MICRO_FRAME_4_CHANNEL             0x10\r
+#define MICRO_FRAME_5_CHANNEL             0x20\r
+#define MICRO_FRAME_6_CHANNEL             0x40\r
+#define MICRO_FRAME_7_CHANNEL             0x80\r
+\r
+#define CONTROL_TRANSFER                  0x01\r
+#define BULK_TRANSFER                     0x02\r
+#define SYNC_INTERRUPT_TRANSFER           0x04\r
+#define ASYNC_INTERRUPT_TRANSFER          0x08\r
+#define SYNC_ISOCHRONOUS_TRANSFER         0x10\r
+#define ASYNC_ISOCHRONOUS_TRANSFER        0x20\r
+\r
+\r
+//\r
+// Enhanced Host Controller Registers definitions\r
+//\r
+extern UINT32                       mUsbCapabilityLen;\r
+extern EFI_DRIVER_BINDING_PROTOCOL  gEhciDriverBinding;\r
+extern EFI_COMPONENT_NAME_PROTOCOL  gEhciComponentName;\r
+\r
+#define USBCMD            0x0     /* Command Register Offset 00-03h */\r
+#define USBCMD_RS         0x01    /* Run / Stop */\r
+#define USBCMD_HCRESET    0x02    /* Host controller reset */\r
+#define USBCMD_FLS_512    0x04    /* 512 elements (2048bytes) in Frame List */\r
+#define USBCMD_FLS_256    0x08    /* 256 elements (1024bytes) in Frame List */\r
+#define USBCMD_PSE        0x10    /* Periodic schedule enable */\r
+#define USBCMD_ASE        0x20    /* Asynchronous schedule enable */\r
+#define USBCMD_IAAD       0x40    /* Interrupt on async advance doorbell */\r
+\r
+#define USBSTS            0x04    /* Statue Register Offset 04-07h */\r
+#define USBSTS_HSE        0x10    /* Host system error */\r
+#define USBSTS_IAA        0x20    /* Interrupt on async advance */\r
+#define USBSTS_HCH        0x1000  /* Host controller halted */\r
+#define USBSTS_PSS        0x4000  /* Periodic schedule status */\r
+#define USBSTS_ASS        0x8000  /* Asynchronous schedule status */\r
+\r
+#define USBINTR           0x08    /* Command Register Offset 08-0bh */\r
+\r
+#define FRINDEX           0x0c    /* Frame Index Offset 0c-0fh */\r
+\r
+#define CTRLDSSGMENT      0x10    /* 4G Segment Selector Offset 10-13h */\r
+\r
+#define PERIODICLISTBASE  0x14    /* Frame List Base Address Offset 14-17h */\r
+\r
+#define ASYNCLISTADDR     0x18    /* Next Asynchronous List Address Offset 18-1bh */\r
+\r
+#define CONFIGFLAG        0x40    /* Configured Flag Register Offset 40-43h */\r
+#define CONFIGFLAG_CF     0x01    /* Configure Flag */\r
+\r
+#define PORTSC            0x44    /* Port Status/Control Offset 44-47h */\r
+#define PORTSC_CCS        0x01    /* Current Connect Status*/\r
+#define PORTSC_CSC        0x02    /* Connect Status Change */\r
+#define PORTSC_PED        0x04    /* Port Enable / Disable */\r
+#define PORTSC_PEDC       0x08    /* Port Enable / Disable Change */\r
+#define PORTSC_OCA        0x10    /* Over current Active */\r
+#define PORTSC_OCC        0x20    /* Over current Change */\r
+#define PORTSC_FPR        0x40    /* Force Port Resume */\r
+#define PORTSC_SUSP       0x80    /* Port Suspend State */\r
+#define PORTSC_PR         0x100   /* Port Reset */\r
+#define PORTSC_LS_KSTATE  0x400   /* Line Status K-state */\r
+#define PORTSC_LS_JSTATE  0x800   /* Line Status J-state */\r
+#define PORTSC_PP         0x1000  /* Port Power */\r
+#define PORTSC_PO         0x2000  /* Port Owner */\r
+\r
+#define CAPLENGTH         0       /* Capability Register Length 00h */\r
+\r
+#define HCIVERSION        0x02    /* Interface Version Number  02-03h */\r
+\r
+#define HCSPARAMS         0x04    /* Structural Parameters 04-07h */\r
+#define HCSP_NPORTS       0x0f    /* Number of physical downstream ports on host controller */\r
+\r
+#define HCCPARAMS         0x08    /* Capability Parameters 08-0bh */\r
+#define HCCP_64BIT        0x01    /* 64-bit Addressing Capability */\r
+#define HCCP_PFLF         0x02    /* Programmable Frame List Flag */\r
+#define HCCP_EECP         0xff00  /* EHCI Extemded Capabilities Pointer */\r
+\r
+#define HCSPPORTROUTE     0x0c    /* Companion Port Route Description 60b */\r
+\r
+#define CLASSC            0x09    /* Class Code 09-0bh */\r
+\r
+#define USBBASE           0x10    /* Base Address to Memory-mapped Host Controller Register Space 10-13h */\r
+\r
+#define SBRN              0x60    /* Serial Bus Release Number 60h */\r
+\r
+#define FLADJ             0x61    /* Frame Length Adjustment Register 61h */\r
+\r
+#define PORTWAKECAP       0x62    /* Port wake capablilities register(OPIONAL)  61-62h */\r
+\r
+//\r
+// PCI Configuration Registers\r
+//\r
+#define EHCI_PCI_CLASSC         0x09\r
+#define EHCI_PCI_MEMORY_BASE    0x10\r
+\r
+//\r
+// Memory Offset Registers\r
+//\r
+#define EHCI_MEMORY_CAPLENGTH   0x0\r
+#define EHCI_MEMORY_CONFIGFLAG  0x40\r
+\r
+//\r
+// USB Base Class Code,Sub-Class Code and Programming Interface\r
+//\r
+#define PCI_CLASSC_PI_EHCI      0x20\r
+\r
+#define SETUP_PACKET_ID         0x2D\r
+#define INPUT_PACKET_ID         0x69\r
+#define OUTPUT_PACKET_ID        0xE1\r
+#define ERROR_PACKET_ID         0x55\r
+\r
+#define bit(a)                1 << (a)\r
+\r
+#define GET_0B_TO_31B(Addr)   (((UINTN) Addr) & (0xffffffff))\r
+#define GET_32B_TO_63B(Addr)  ((((UINTN) Addr) >> 32) & (0xffffffff))\r
+\r
+\r
+//\r
+// Ehci Data and Ctrl Structures\r
+//\r
+#pragma pack(1)\r
+\r
+typedef struct {\r
+  UINT8 PI;\r
+  UINT8 SubClassCode;\r
+  UINT8 BaseCode;\r
+} USB_CLASSC;\r
+\r
+typedef struct {\r
+  UINT32  NextQtdTerminate : 1;\r
+  UINT32  Rsvd1 : 4;\r
+  UINT32  NextQtdPointer : 27;\r
+\r
+  UINT32  AltNextQtdTerminate : 1;\r
+  UINT32  Rsvd2 : 4;\r
+  UINT32  AltNextQtdPointer : 27;\r
+\r
+  UINT32  Status : 8;\r
+  UINT32  PidCode : 2;\r
+  UINT32  ErrorCount : 2;\r
+  UINT32  CurrentPage : 3;\r
+  UINT32  InterruptOnComplete : 1;\r
+  UINT32  TotalBytes : 15;\r
+  UINT32  DataToggle : 1;\r
+\r
+  UINT32  CurrentOffset : 12;\r
+  UINT32  BufferPointer0 : 20;\r
+\r
+  UINT32  Rsvd3 : 12;\r
+  UINT32  BufferPointer1 : 20;\r
+\r
+  UINT32  Rsvd4 : 12;\r
+  UINT32  BufferPointer2 : 20;\r
+\r
+  UINT32  Rsvd5 : 12;\r
+  UINT32  BufferPointer3 : 20;\r
+\r
+  UINT32  Rsvd6 : 12;\r
+  UINT32  BufferPointer4 : 20;\r
+\r
+  UINT32  ExtBufferPointer0;\r
+  UINT32  ExtBufferPointer1;\r
+  UINT32  ExtBufferPointer2;\r
+  UINT32  ExtBufferPointer3;\r
+  UINT32  ExtBufferPointer4;\r
+} EHCI_QTD_HW;\r
+\r
+typedef struct {\r
+  UINT32  QhTerminate : 1;\r
+  UINT32  SelectType : 2;\r
+  UINT32  Rsvd1 : 2;\r
+  UINT32  QhHorizontalPointer : 27;\r
+\r
+  UINT32  DeviceAddr : 7;\r
+  UINT32  Inactive : 1;\r
+  UINT32  EndpointNum : 4;\r
+  UINT32  EndpointSpeed : 2;\r
+  UINT32  DataToggleControl : 1;\r
+  UINT32  HeadReclamationFlag : 1;\r
+  UINT32  MaxPacketLen : 11;\r
+  UINT32  ControlEndpointFlag : 1;\r
+  UINT32  NakCountReload : 4;\r
+\r
+  UINT32  InerruptScheduleMask : 8;\r
+  UINT32  SplitComletionMask : 8;\r
+  UINT32  HubAddr : 7;\r
+  UINT32  PortNum : 7;\r
+  UINT32  Multiplier : 2;\r
+\r
+  UINT32  Rsvd2 : 5;\r
+  UINT32  CurrentQtdPointer : 27;\r
+\r
+  UINT32  NextQtdTerminate : 1;\r
+  UINT32  Rsvd3 : 4;\r
+  UINT32  NextQtdPointer : 27;\r
+\r
+  UINT32  AltNextQtdTerminate : 1;\r
+  UINT32  NakCount : 4;\r
+  UINT32  AltNextQtdPointer : 27;\r
+\r
+  UINT32  Status : 8;\r
+  UINT32  PidCode : 2;\r
+  UINT32  ErrorCount : 2;\r
+  UINT32  CurrentPage : 3;\r
+  UINT32  InterruptOnComplete : 1;\r
+  UINT32  TotalBytes : 15;\r
+  UINT32  DataToggle : 1;\r
+\r
+  UINT32  CurrentOffset : 12;\r
+  UINT32  BufferPointer0 : 20;\r
+\r
+  UINT32  CompleteSplitMask : 8;\r
+  UINT32  Rsvd4 : 4;\r
+  UINT32  BufferPointer1 : 20;\r
+\r
+  UINT32  FrameTag : 5;\r
+  UINT32  SplitBytes : 7;\r
+  UINT32  BufferPointer2 : 20;\r
+\r
+  UINT32  Rsvd5 : 12;\r
+  UINT32  BufferPointer3 : 20;\r
+\r
+  UINT32  Rsvd6 : 12;\r
+  UINT32  BufferPointer4 : 20;\r
+\r
+  UINT32  ExtBufferPointer0;\r
+  UINT32  ExtBufferPointer1;\r
+  UINT32  ExtBufferPointer2;\r
+  UINT32  ExtBufferPointer3;\r
+  UINT32  ExtBufferPointer4;\r
+} EHCI_QH_HW;\r
+\r
+typedef struct {\r
+  UINT32  LinkTerminate : 1;\r
+  UINT32  SelectType : 2;\r
+  UINT32  Rsvd : 2;\r
+  UINT32  LinkPointer : 27;\r
+} FRAME_LIST_ENTRY;\r
+\r
+#pragma pack()\r
+\r
+typedef struct _EHCI_QTD_ENTITY     EHCI_QTD_ENTITY;\r
+typedef struct _EHCI_QH_ENTITY      EHCI_QH_ENTITY;\r
+typedef struct _EHCI_ASYNC_REQUEST  EHCI_ASYNC_REQUEST;\r
+\r
+typedef struct _EHCI_QTD_ENTITY {\r
+  EHCI_QTD_HW     Qtd;\r
+  UINT32          TotalBytes;\r
+  UINT32          StaticTotalBytes;\r
+  UINT32          StaticCurrentOffset;\r
+  EHCI_QTD_ENTITY *Prev;\r
+  EHCI_QTD_ENTITY *Next;\r
+  EHCI_QTD_ENTITY *AltNext;\r
+  EHCI_QH_ENTITY  *SelfQh;\r
+} EHCI_QTD_ENTITY;\r
+\r
+typedef struct _EHCI_QH_ENTITY {\r
+  EHCI_QH_HW      Qh;\r
+  EHCI_QH_ENTITY  *Next;\r
+  EHCI_QH_ENTITY  *Prev;\r
+  EHCI_QTD_ENTITY *FirstQtdPtr;\r
+  EHCI_QTD_ENTITY *LastQtdPtr;\r
+  EHCI_QTD_ENTITY *AltQtdPtr;\r
+  UINTN           Interval;\r
+  UINT8           TransferType;\r
+} EHCI_QH_ENTITY;\r
+\r
+#define GET_QH_ENTITY_ADDR(a)   ((EHCI_QH_ENTITY *) a)\r
+#define GET_QTD_ENTITY_ADDR(a)  ((EHCI_QTD_ENTITY *) a)\r
+\r
+\r
+//\r
+// Ehci Managment Structures\r
+//\r
+#define USB2_HC_DEV_FROM_THIS(a)  CR (a, USB2_HC_DEV, Usb2Hc, USB2_HC_DEV_SIGNATURE)\r
+\r
+#define USB2_HC_DEV_SIGNATURE     EFI_SIGNATURE_32 ('e', 'h', 'c', 'i')\r
+\r
+typedef struct _LIST_HEAD {\r
+  struct _LIST_HEAD *pre;\r
+  struct _LIST_HEAD *next;\r
+} LIST_HEAD;\r
+\r
+typedef struct _EHCI_ASYNC_REQUEST {\r
+  UINT8                           TransferType;\r
+  EFI_ASYNC_USB_TRANSFER_CALLBACK CallBackFunc;\r
+  VOID                            *Context;\r
+  EHCI_ASYNC_REQUEST              *Prev;\r
+  EHCI_ASYNC_REQUEST              *Next;\r
+  EHCI_QH_ENTITY                  *QhPtr;\r
+} EHCI_ASYNC_REQUEST;\r
+\r
+typedef struct _MEMORY_MANAGE_HEADER {\r
+  UINT8                         *BitArrayPtr;\r
+  UINTN                         BitArraySizeInBytes;\r
+  UINT8                         *MemoryBlockPtr;\r
+  UINTN                         MemoryBlockSizeInBytes;\r
+  VOID                          *Mapping;\r
+  struct _MEMORY_MANAGE_HEADER  *Next;\r
+} MEMORY_MANAGE_HEADER;\r
+\r
+typedef struct _USB2_HC_DEV {\r
+  UINTN                     Signature;\r
+  EFI_PCI_IO_PROTOCOL       *PciIo;\r
+  EFI_USB2_HC_PROTOCOL      Usb2Hc;\r
+  UINTN                     PeriodicFrameListLength;\r
+  VOID                      *PeriodicFrameListBuffer;\r
+  VOID                      *PeriodicFrameListMap;\r
+  VOID                      *AsyncList;\r
+  EHCI_ASYNC_REQUEST        *AsyncRequestList;\r
+  EFI_EVENT                 AsyncRequestEvent;\r
+  EFI_UNICODE_STRING_TABLE  *ControllerNameTable;\r
+  MEMORY_MANAGE_HEADER      *MemoryHeader;\r
+  UINT8                                                Is64BitCapable;\r
+  UINT32                    High32BitAddr;\r
+} USB2_HC_DEV;\r
+\r
+\r
+//\r
+// Internal Functions Declaration\r
+//\r
+\r
+//\r
+// EhciMem Functions\r
+//\r
+EFI_STATUS\r
+CreateMemoryBlock (\r
+  IN  USB2_HC_DEV               *HcDev,\r
+  OUT MEMORY_MANAGE_HEADER      **MemoryHeader,\r
+  IN  UINTN                     MemoryBlockSizeInPages\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Use PciIo->AllocateBuffer to allocate common buffer for the memory block,\r
+  and use PciIo->Map to map the common buffer for Bus Master Read/Write.\r
+\r
+Arguments:\r
+\r
+  HcDev                  - USB2_HC_DEV\r
+  MemoryHeader           - MEMORY_MANAGE_HEADER to output\r
+  MemoryBlockSizeInPages - MemoryBlockSizeInPages\r
+  \r
+Returns:\r
+\r
+  EFI_SUCCESS           Success\r
+  EFI_OUT_OF_RESOURCES  Fail for no resources\r
+  EFI_UNSUPPORTED       Unsupported currently\r
+  \r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+FreeMemoryHeader (\r
+  IN USB2_HC_DEV               *HcDev,\r
+  IN MEMORY_MANAGE_HEADER      *MemoryHeader\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Free Memory Header\r
+\r
+Arguments:\r
+\r
+  HcDev         - USB2_HC_DEV\r
+  MemoryHeader  - MemoryHeader to be freed\r
+\r
+Returns:\r
+\r
+  EFI_SUCCESS            Success\r
+  EFI_INVALID_PARAMETER  Parameter is error\r
+\r
+--*/\r
+;\r
+\r
+VOID\r
+InsertMemoryHeaderToList (\r
+  IN MEMORY_MANAGE_HEADER     *MemoryHeader,\r
+  IN MEMORY_MANAGE_HEADER     *NewMemoryHeader\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Insert Memory Header To List\r
+\r
+Arguments:\r
+\r
+  MemoryHeader    - MEMORY_MANAGE_HEADER\r
+  NewMemoryHeader - MEMORY_MANAGE_HEADER\r
+\r
+Returns:\r
+\r
+  VOID\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+AllocMemInMemoryBlock (\r
+  IN  MEMORY_MANAGE_HEADER     *MemoryHeader,\r
+  OUT VOID                     **Pool,\r
+  IN  UINTN                    NumberOfMemoryUnit\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Alloc Memory In MemoryBlock\r
+\r
+Arguments:\r
+\r
+  MemoryHeader        - MEMORY_MANAGE_HEADER\r
+  Pool                - Place to store pointer to memory\r
+  NumberOfMemoryUnit  - Number Of Memory Unit\r
+\r
+Returns:\r
+\r
+  EFI_SUCCESS    Success\r
+  EFI_NOT_FOUND  Can't find the free memory \r
+\r
+--*/\r
+;\r
+\r
+BOOLEAN\r
+IsMemoryBlockEmptied (\r
+  IN MEMORY_MANAGE_HEADER     *MemoryHeaderPtr\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Is Memory Block Emptied\r
+\r
+Arguments:\r
+\r
+  MemoryHeaderPtr - MEMORY_MANAGE_HEADER\r
+\r
+Returns:\r
+\r
+  TRUE    Empty\r
+  FALSE   Not Empty \r
+\r
+--*/\r
+;\r
+\r
+VOID\r
+DelinkMemoryBlock (\r
+  IN MEMORY_MANAGE_HEADER     *FirstMemoryHeader,\r
+  IN MEMORY_MANAGE_HEADER     *NeedFreeMemoryHeader\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Delink Memory Block\r
+\r
+Arguments:\r
+\r
+  FirstMemoryHeader     - MEMORY_MANAGE_HEADER\r
+  NeedFreeMemoryHeader  - MEMORY_MANAGE_HEADER\r
+\r
+Returns:\r
+\r
+  VOID\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+InitialMemoryManagement (\r
+  IN USB2_HC_DEV     *HcDev\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Initialize Memory Management\r
+\r
+Arguments:\r
+\r
+  HcDev - USB2_HC_DEV\r
+\r
+Returns:\r
+\r
+  EFI_SUCCESS        Success\r
+  EFI_DEVICE_ERROR   Fail\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+DeinitialMemoryManagement (\r
+  IN USB2_HC_DEV     *HcDev\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Deinitialize Memory Management\r
+\r
+Arguments:\r
+\r
+  HcDev - USB2_HC_DEV\r
+\r
+Returns:\r
+\r
+  EFI_SUCCESS        Success\r
+  EFI_DEVICE_ERROR   Fail\r
+  \r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+EhciAllocatePool (\r
+  IN  USB2_HC_DEV     *HcDev,\r
+  OUT UINT8           **Pool,\r
+  IN  UINTN           AllocSize\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Ehci Allocate Pool\r
+\r
+Arguments:\r
+\r
+  HcDev     - USB2_HC_DEV\r
+  Pool      - Place to store pointer to the memory buffer\r
+  AllocSize - Alloc Size\r
+\r
+Returns:\r
+\r
+  EFI_SUCCESS        Success\r
+  EFI_DEVICE_ERROR   Fail\r
+  \r
+--*/\r
+;\r
+\r
+VOID\r
+EhciFreePool (\r
+  IN USB2_HC_DEV     *HcDev,\r
+  IN UINT8           *Pool,\r
+  IN UINTN           AllocSize\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Uhci Free Pool\r
+\r
+Arguments:\r
+\r
+  HcDev     - USB_HC_DEV\r
+  Pool      - Pool to free\r
+  AllocSize - Pool size\r
+\r
+Returns:\r
+\r
+  VOID\r
+\r
+--*/\r
+;\r
+\r
+//\r
+// EhciReg Functions\r
+//\r
+EFI_STATUS\r
+ReadEhcCapabiltiyReg (\r
+  IN USB2_HC_DEV             *HcDev,\r
+  IN UINT32                  CapabiltiyRegAddr,\r
+  IN OUT UINT32              *Data\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Read  Ehc Capabitlity register\r
+  \r
+Arguments:\r
+\r
+  HcDev             - USB2_HC_DEV \r
+  CapabiltiyRegAddr - Ehc Capability register address\r
+  Data              - A pointer to data read from register\r
+  \r
+Returns:\r
+\r
+  EFI_SUCCESS        Success\r
+  EFI_DEVICE_ERROR   Fail\r
+  \r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+ReadEhcOperationalReg (\r
+  IN USB2_HC_DEV             *HcDev,\r
+  IN UINT32                  OperationalRegAddr,\r
+  IN OUT UINT32              *Data\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Read  Ehc Operation register\r
+  \r
+Arguments:\r
+\r
+  HcDev                - USB2_HC_DEV \r
+  OperationalRegAddr   - Ehc Operation register address\r
+  Data                 - A pointer to data read from register\r
+  \r
+Returns:\r
+\r
+  EFI_SUCCESS        Success\r
+  EFI_DEVICE_ERROR   Fail\r
+  \r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+WriteEhcOperationalReg (\r
+  IN USB2_HC_DEV             *HcDev,\r
+  IN UINT32                  OperationalRegAddr,\r
+  IN UINT32                  Data\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Write  Ehc Operation register\r
+  \r
+Arguments:\r
+\r
+  HcDev                - USB2_HC_DEV \r
+  OperationalRegAddr   - Ehc Operation register address\r
+  Data                 - 32bit write to register\r
+  \r
+Returns:\r
+\r
+  EFI_SUCCESS        Success\r
+  EFI_DEVICE_ERROR   Fail\r
+  \r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+SetEhcDoorbell (\r
+  IN  USB2_HC_DEV     *HcDev\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Set Ehc door bell bit\r
+  \r
+Arguments:\r
+\r
+  HcDev - USB2_HC_DEV \r
+  \r
+Returns:\r
+\r
+  EFI_SUCCESS       Success\r
+  EFI_DEVICE_ERROR  Fail\r
+     \r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+SetFrameListLen (\r
+  IN USB2_HC_DEV     *HcDev,\r
+  IN UINTN           Length\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Set the length of Frame List\r
+  \r
+Arguments:\r
+\r
+  HcDev    - USB2_HC_DEV \r
+  Length   - the required length of frame list\r
+  \r
+Returns:\r
+\r
+  EFI_SUCCESS            Success\r
+  EFI_INVALID_PARAMETER  Invalid parameter\r
+  EFI_DEVICE_ERROR       Fail\r
+  \r
+--*/\r
+;\r
+\r
+BOOLEAN\r
+IsFrameListProgrammable (\r
+  IN  USB2_HC_DEV     *HcDev\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Whether frame list is programmable\r
+  \r
+Arguments:\r
+\r
+  HcDev - USB2_HC_DEV \r
+  \r
+Returns:\r
+\r
+  TRUE   Programmable\r
+  FALSE  Unprogrammable\r
+  \r
+--*/\r
+;\r
+\r
+BOOLEAN\r
+IsPeriodicScheduleEnabled (\r
+  IN  USB2_HC_DEV     *HcDev\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Whether periodic schedule is enabled\r
+  \r
+Arguments:\r
+\r
+  HcDev - USB2_HC_DEV \r
+  \r
+Returns:\r
+\r
+  TRUE   Enabled\r
+  FALSE  Disabled\r
+   \r
+--*/\r
+;\r
+\r
+BOOLEAN\r
+IsAsyncScheduleEnabled (\r
+  IN  USB2_HC_DEV     *HcDev\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Whether asynchronous schedule is enabled\r
+  \r
+Arguments:\r
+\r
+  HcDev - USB2_HC_DEV \r
+  \r
+Returns:\r
+\r
+  TRUE   Enabled\r
+  FALSE  Disabled\r
+    \r
+--*/\r
+;\r
+\r
+BOOLEAN\r
+IsEhcPortEnabled (\r
+  IN  USB2_HC_DEV     *HcDev,\r
+  IN  UINT8           PortNum\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Whether port is enabled\r
+  \r
+Arguments:\r
+\r
+  HcDev - USB2_HC_DEV \r
+  \r
+Returns:\r
+\r
+  TRUE   Enabled\r
+  FALSE  Disabled\r
+  \r
+--*/\r
+;\r
+\r
+BOOLEAN\r
+IsEhcReseted (\r
+  IN  USB2_HC_DEV     *HcDev\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Whether Ehc is halted\r
+  \r
+Arguments:\r
+\r
+  HcDev - USB2_HC_DEV \r
+  \r
+Returns:\r
+\r
+  TRUE   Reseted\r
+  FALSE  Unreseted\r
+    \r
+--*/\r
+;\r
+\r
+BOOLEAN\r
+IsEhcHalted (\r
+  IN  USB2_HC_DEV     *HcDev\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Whether Ehc is halted\r
+  \r
+Arguments:\r
+\r
+  HcDev  - USB2_HC_DEV \r
+  \r
+Returns:\r
+\r
+  TRUE   Halted\r
+  FALSE  Not halted\r
+    \r
+--*/\r
+;\r
+\r
+BOOLEAN\r
+IsEhcSysError (\r
+  IN  USB2_HC_DEV     *HcDev\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Whether Ehc is system error\r
+  \r
+Arguments:\r
+\r
+  HcDev  - USB2_HC_DEV \r
+  \r
+Returns:\r
+\r
+  TRUE   System error\r
+  FALSE  No system error\r
+    \r
+--*/\r
+;\r
+\r
+BOOLEAN\r
+IsHighSpeedDevice (\r
+  IN EFI_USB2_HC_PROTOCOL *This,\r
+  IN UINT8                PortNum \r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Whether high speed device attached\r
+  \r
+Arguments:\r
+\r
+  HcDev - USB2_HC_DEV \r
+  \r
+Returns:\r
+\r
+  TRUE   High speed\r
+  FALSE  Full speed\r
+  \r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+WaitForEhcReset (\r
+  IN USB2_HC_DEV             *HcDev,\r
+  IN UINTN                   Timeout\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  wait for Ehc reset or timeout\r
+  \r
+Arguments:\r
+\r
+  HcDev   - USB2_HC_DEV \r
+  Timeout - timeout threshold\r
+  \r
+Returns:\r
+\r
+  EFI_SUCCESS    Success\r
+  EFI_TIMEOUT    Timeout\r
+  \r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+WaitForEhcHalt (\r
+  IN USB2_HC_DEV             *HcDev,\r
+  IN UINTN                   Timeout\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  wait for Ehc halt or timeout\r
+  \r
+Arguments:\r
+\r
+  HcDev   - USB2_HC_DEV \r
+  Timeout - timeout threshold\r
+  \r
+Returns:\r
+\r
+  EFI_SUCCESS    Success\r
+  EFI_TIMEOUT    Timeout\r
+  \r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+WaitForEhcNotHalt (\r
+  IN USB2_HC_DEV             *HcDev,\r
+  IN UINTN                   Timeout\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  wait for Ehc not halt or timeout\r
+  \r
+Arguments:\r
+\r
+  HcDev   - USB2_HC_DEV \r
+  Timeout - timeout threshold\r
+  \r
+Returns:\r
+\r
+  EFI_SUCCESS    Success\r
+  EFI_TIMEOUT    Timeout\r
+  \r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+WaitForEhcDoorbell (\r
+  IN  USB2_HC_DEV            *HcDev,\r
+  IN UINTN                   Timeout\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Wait for periodic schedule disable or timeout\r
+\r
+Arguments:\r
+\r
+  HcDev   - USB2_HC_DEV \r
+  Timeout - timeout threshold\r
+\r
+Returns:\r
+\r
+  EFI_SUCCESS    Success\r
+  EFI_TIMEOUT    Timeout\r
+  \r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+WaitForAsyncScheduleEnable (\r
+  IN USB2_HC_DEV             *HcDev,\r
+  IN UINTN                   Timeout\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Wait for Ehc asynchronous schedule enable or timeout\r
+  \r
+Arguments:\r
+\r
+  HcDev   - USB2_HC_DEV \r
+  Timeout - timeout threshold\r
+  \r
+Returns:\r
+\r
+  EFI_SUCCESS    Success\r
+  EFI_TIMEOUT    Timeout\r
+  \r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+WaitForAsyncScheduleDisable (\r
+  IN USB2_HC_DEV             *HcDev,\r
+  IN UINTN                   Timeout\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Wait for Ehc asynchronous schedule disable or timeout\r
+  \r
+Arguments:\r
+\r
+  HcDev   - USB2_HC_DEV \r
+  Timeout - timeout threshold\r
+  \r
+Returns:\r
+\r
+  EFI_SUCCESS    Success\r
+  EFI_TIMEOUT    Timeout\r
+  \r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+WaitForPeriodicScheduleEnable (\r
+  IN USB2_HC_DEV             *HcDev,\r
+  IN UINTN                   Timeout\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Wait for Ehc periodic schedule enable or timeout\r
+  \r
+Arguments:\r
+\r
+  HcDev   - USB2_HC_DEV \r
+  Timeout - timeout threshold\r
+  \r
+Returns:\r
+\r
+  EFI_SUCCESS    Success\r
+  EFI_TIMEOUT    Timeout\r
+  \r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+WaitForPeriodicScheduleDisable (\r
+  IN USB2_HC_DEV             *HcDev,\r
+  IN UINTN                   Timeout\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Wait for periodic schedule disable or timeout\r
+  \r
+Arguments:\r
+\r
+  HcDev   - USB2_HC_DEV \r
+  Timeout - timeout threshold\r
+  \r
+Returns:\r
+\r
+  EFI_SUCCESS    Success\r
+  EFI_TIMEOUT    Timeout\r
+  \r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+GetCapabilityLen (\r
+  IN USB2_HC_DEV     *HcDev\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Get the length of capability register\r
+  \r
+Arguments:\r
+\r
+  HcDev - USB2_HC_DEV \r
+  \r
+Returns:\r
+\r
+  EFI_SUCCESS       Success\r
+  EFI_DEVICE_ERROR  Fail\r
+  \r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+SetFrameListBaseAddr (\r
+  IN USB2_HC_DEV     *HcDev,\r
+  IN UINT32          FrameBuffer\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Set base address of frame list first entry\r
+  \r
+Arguments:\r
+\r
+  HcDev       - USB2_HC_DEV \r
+  FrameBuffer - base address of first entry of frame list\r
+  \r
+Returns:\r
+\r
+  EFI_SUCCESS       Success\r
+  EFI_DEVICE_ERROR  Fail\r
+  \r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+SetAsyncListAddr (\r
+  IN USB2_HC_DEV        *HcDev,\r
+  IN EHCI_QH_ENTITY     *QhPtr\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Set address of first Async schedule Qh\r
+  \r
+Arguments:\r
+\r
+  HcDev    - USB2_HC_DEV \r
+  QhPtr    - A pointer to first Qh in the Async schedule\r
+  \r
+Returns:\r
+\r
+  EFI_SUCCESS       Success\r
+  EFI_DEVICE_ERROR  Fail\r
+  \r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+SetCtrlDataStructSeg (\r
+  IN USB2_HC_DEV     *HcDev\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Set address of first Async schedule Qh\r
+  \r
+Arguments:\r
+\r
+  HcDev    - USB2_HC_DEV \r
+  QhPtr    - A pointer to first Qh in the Async schedule\r
+  \r
+Returns:\r
+\r
+  EFI_SUCCESS       Success\r
+  EFI_DEVICE_ERROR  Fail\r
+  \r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+SetPortRoutingEhc (\r
+  IN USB2_HC_DEV     *HcDev\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Set Ehc port routing bit\r
+  \r
+Arguments:\r
+\r
+  HcDev - USB2_HC_DEV \r
+  \r
+Returns:\r
+\r
+  EFI_SUCCESS       Success\r
+  EFI_DEVICE_ERROR  Fail\r
+  \r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+EnablePeriodicSchedule (\r
+  IN  USB2_HC_DEV     *HcDev\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Enable periodic schedule\r
+  \r
+Arguments:\r
+\r
+  HcDev - USB2_HC_DEV \r
+  \r
+Returns:\r
+\r
+  EFI_SUCCESS       Success\r
+  EFI_DEVICE_ERROR  Fail\r
+  \r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+DisablePeriodicSchedule (\r
+  IN  USB2_HC_DEV     *HcDev\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Disable periodic schedule\r
+  \r
+Arguments:\r
+\r
+  HcDev - USB2_HC_DEV \r
+  \r
+Returns:\r
+\r
+  EFI_SUCCESS       Success\r
+  EFI_DEVICE_ERROR  Fail\r
+  \r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+EnableAsynchronousSchedule (\r
+  IN  USB2_HC_DEV     *HcDev\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Enable asynchrounous schedule\r
+  \r
+Arguments:\r
+\r
+  HcDev - USB2_HC_DEV \r
+  \r
+Returns:\r\r
+\r
+  EFI_SUCCESS       Success\r
+  EFI_DEVICE_ERROR  Fail\r
+  \r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+DisableAsynchronousSchedule (\r
+  IN  USB2_HC_DEV     *HcDev\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Disable asynchrounous schedule\r
+  \r
+Arguments:\r
+\r
+  HcDev - USB2_HC_DEV \r
+  \r
+Returns:\r
+\r
+  EFI_SUCCESS       Success\r
+  EFI_DEVICE_ERROR  Fail\r
+  \r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+StartScheduleExecution (\r
+  IN  USB2_HC_DEV     *HcDev\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Start Ehc schedule execution\r
+  \r
+Arguments:\r
+\r
+  HcDev - USB2_HC_DEV \r
+  \r
+Returns:\r
+\r
+  EFI_SUCCESS       Success\r
+  EFI_DEVICE_ERROR  Fail\r
+  \r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+ResetEhc (\r
+  IN  USB2_HC_DEV     *HcDev\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Reset Ehc\r
+  \r
+Arguments:\r
+\r
+  HcDev - USB2_HC_DEV \r
+  \r
+Returns:\r
+\r
+  EFI_SUCCESS       Success\r
+  EFI_DEVICE_ERROR  Fail\r
+  \r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+ClearEhcAllStatus (\r
+  IN  USB2_HC_DEV     *HcDev\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Clear Ehc all status bits\r
+  \r
+Arguments:\r
+\r
+  HcDev - USB2_HC_DEV \r
+  \r
+Returns:\r
+\r
+  EFI_SUCCESS        Success\r
+  EFI_DEVICE_ERROR   Fail\r
+  \r
+--*/\r
+;\r
+\r
+//\r
+// EhciSched Functions\r
+//\r
+EFI_STATUS\r
+InitialPeriodicFrameList (\r
+  IN USB2_HC_DEV      *HcDev,\r
+  IN UINTN            Length\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Initialize Periodic Schedule Frame List\r
+\r
+Arguments:\r
+\r
+  HcDev   - USB2_HC_DEV\r
+  Length  - Frame List Length\r
+  \r
+Returns:\r
+\r
+  EFI_SUCCESS        Success\r
+  EFI_DEVICE_ERROR   Fail\r
+  \r
+--*/\r
+;\r
+\r
+VOID\r
+DeinitialPeriodicFrameList (\r
+  IN  USB2_HC_DEV     *HcDev\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Deinitialize Periodic Schedule Frame List\r
+\r
+Arguments:\r
+\r
+  HcDev - USB2_HC_DEV\r
+\r
+Returns:\r
+\r
+  VOID\r
+  \r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+CreatePollingTimer (\r
+  IN  USB2_HC_DEV      *HcDev,\r
+  IN  EFI_EVENT_NOTIFY NotifyFunction\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Create Async Request Polling Timer\r
+\r
+Arguments:\r
+\r
+  HcDev          - USB2_HC_DEV\r
+  NotifyFunction - Timer Notify Function\r
+  \r
+Returns:\r
+\r
+  EFI_SUCCESS        Success\r
+  EFI_DEVICE_ERROR   Fail\r
+  \r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+DestoryPollingTimer (\r
+  IN  USB2_HC_DEV *HcDev\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Destory Async Request Polling Timer\r
+\r
+Arguments:\r
+\r
+  HcDev - USB2_HC_DEV\r
+  \r
+Returns:\r
+\r
+  EFI_SUCCESS        Success\r
+  EFI_DEVICE_ERROR   Fail\r
+  \r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+StartPollingTimer (\r
+  IN  USB2_HC_DEV *HcDev\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Start Async Request Polling Timer\r
+\r
+Arguments:\r
+\r
+  HcDev - USB2_HC_DEV\r
+  \r
+Returns:\r
+\r
+  EFI_SUCCESS        Success\r
+  EFI_DEVICE_ERROR   Fail\r
+  \r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+StopPollingTimer (\r
+  IN  USB2_HC_DEV *HcDev\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Stop Async Request Polling Timer\r
+\r
+Arguments:\r
+\r
+  HcDev - USB2_HC_DEV\r
+  \r
+Returns:\r
+\r
+  EFI_SUCCESS        Success\r
+  EFI_DEVICE_ERROR   Fail\r
+  \r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+CreateQh (\r
+  IN  USB2_HC_DEV         *HcDev,\r
+  IN  UINT8               DeviceAddr,\r
+  IN  UINT8               Endpoint,\r
+  IN  UINT8               DeviceSpeed,\r
+  IN  UINTN               MaxPacketLen,\r
+  OUT EHCI_QH_ENTITY      **QhPtrPtr\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Create Qh Structure and Pre-Initialize\r
+\r
+Arguments:\r
+\r
+  HcDev          - USB2_HC_DEV \r
+  DeviceAddr     - Address of Device\r
+  Endpoint       - Endpoint Number\r
+  DeviceSpeed    - Device Speed\r
+  MaxPacketLen   - Max Length of one Packet\r
+  QhPtrPtr       - A pointer of pointer to Qh for return\r
+  \r
+Returns:\r
+\r
+  EFI_SUCCESS       Success\r
+  EFI_DEVICE_ERROR  Fail\r
+  \r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+CreateControlQh (\r
+  IN  USB2_HC_DEV                       *HcDev,\r
+  IN  UINT8                             DeviceAddr,\r
+  IN  UINT8                             DeviceSpeed,\r
+  IN UINTN                              MaxPacketLen,\r
+  IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,\r
+  OUT EHCI_QH_ENTITY                    **QhPtrPtr\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Create Qh for Control Transfer\r
+\r
+Arguments:\r
+\r
+  HcDev         - USB2_HC_DEV \r
+  DeviceAddr    - Address of Device\r
+  DeviceSpeed   - Device Speed\r
+  MaxPacketLen  - Max Length of one Packet\r
+  Translator    - Translator Transaction for SplitX\r
+  QhPtrPtr      - A pointer of pointer to Qh for return\r
+  \r
+Returns:\r
+\r
+  EFI_SUCCESS       Success\r
+  EFI_DEVICE_ERROR  Fail\r
+  \r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+CreateBulkQh (\r
+  IN  USB2_HC_DEV                         *HcDev,\r
+  IN  UINT8                               DeviceAddr,\r
+  IN  UINT8                               EndPointAddr,\r
+  IN  UINT8                               DeviceSpeed,\r
+  IN  UINT8                               DataToggle,\r
+  IN  UINTN                               MaxPacketLen,\r
+  IN  EFI_USB2_HC_TRANSACTION_TRANSLATOR  *Translator,\r
+  OUT EHCI_QH_ENTITY                      **QhPtrPtr\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Create Qh for Bulk Transfer\r
+\r
+Arguments:\r
+\r
+  HcDev         - USB2_HC_DEV \r
+  DeviceAddr    - Address of Device\r
+  EndPointAddr  - Address of Endpoint\r
+  DeviceSpeed   - Device Speed\r
+  MaxPacketLen  - Max Length of one Packet\r
+  Translator    - Translator Transaction for SplitX\r
+  QhPtrPtr      - A pointer of pointer to Qh for return\r
+  \r
+Returns:\r
+\r
+  EFI_SUCCESS       Success\r
+  EFI_DEVICE_ERROR  Fail\r
+  \r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+CreateInterruptQh (\r
+  IN  USB2_HC_DEV                        *HcDev,\r
+  IN  UINT8                              DeviceAddr,\r
+  IN  UINT8                              EndPointAddr,\r
+  IN  UINT8                              DeviceSpeed,\r
+  IN  UINT8                              DataToggle,\r
+  IN  UINTN                              MaxPacketLen,\r
+  IN  UINTN                              Interval,\r
+  IN  EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,\r
+  OUT EHCI_QH_ENTITY                     **QhPtrPtr\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Create Qh for Control Transfer\r
+\r
+Arguments:\r
+\r
+  HcDev        - USB2_HC_DEV \r
+  DeviceAddr   - Address of Device\r
+  EndPointAddr - Address of Endpoint\r
+  DeviceSpeed  - Device Speed\r
+  MaxPacketLen - Max Length of one Packet\r
+  Interval     - value of interval\r
+  Translator   - Translator Transaction for SplitX\r
+  QhPtrPtr     - A pointer of pointer to Qh for return\r
+  \r
+Returns:\r
+\r
+  EFI_SUCCESS       Success\r
+  EFI_DEVICE_ERROR  Fail\r
+  \r
+--*/\r
+;\r
+\r
+VOID\r
+DestoryQh (\r
+  IN  USB2_HC_DEV        *HcDev,\r
+  IN EHCI_QH_ENTITY      *QhPtr\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Destory Qh Structure \r
+  \r
+Arguments:\r
+\r
+  HcDev - USB2_HC_DEV \r
+  QhPtr - A pointer to Qh\r
+  \r
+Returns:\r
+\r
+  VOID\r
+  \r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+CreateQtd (\r
+  IN  USB2_HC_DEV          *HcDev,\r
+  IN  UINT8                *DataPtr,\r
+  IN  UINTN                DataLen,\r
+  IN  UINT8                PktId,\r
+  IN  UINT8                Toggle,\r
+  IN  UINT8                QtdStatus,\r
+  OUT EHCI_QTD_ENTITY      **QtdPtrPtr\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Create Qtd Structure and Pre-Initialize it\r
+\r
+Arguments:\r
+\r
+  HcDev       - USB2_HC_DEV \r
+  DataPtr     - A pointer to user data buffer to transfer\r
+  DataLen     - Length of user data to transfer\r
+  PktId       - Packet Identification of this Qtd\r
+  Toggle      - Data Toggle of this Qtd\r
+  QtdStatus   - Default value of status of this Qtd\r
+  QtdPtrPtr   - A pointer of pointer to Qtd for return\r
+  \r
+Returns:\r
+\r
+  EFI_SUCCESS            Success\r
+  EFI_OUT_OF_RESOURCES   Cannot allocate resources\r
+  \r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+CreateSetupQtd (\r
+  IN  USB2_HC_DEV          *HcDev,\r
+  IN  UINT8                *DevReqPtr,\r
+  OUT EHCI_QTD_ENTITY      **QtdPtrPtr\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Create Qtd Structure for Setup \r
+\r
+Arguments:\r
+\r
+  HcDev      - USB2_HC_DEV \r
+  DevReqPtr  - A pointer to Device Request Data\r
+  QtdPtrPtr  - A pointer of pointer to Qtd for return\r
+  \r
+Returns:\r
+\r
+  EFI_SUCCESS            Success\r
+  EFI_OUT_OF_RESOURCES   Cannot allocate resources\r
+  \r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+CreateDataQtd (\r
+  IN  USB2_HC_DEV           *HcDev,\r
+  IN  UINT8                 *DataPtr,\r
+  IN  UINTN                 DataLen,\r
+  IN  UINT8                 PktId,\r
+  IN  UINT8                 Toggle,\r
+  OUT EHCI_QTD_ENTITY       **QtdPtrPtr\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Create Qtd Structure for data \r
+\r
+Arguments:\r
+\r
+  HcDev       - USB2_HC_DEV \r
+  DataPtr     - A pointer to user data buffer to transfer\r
+  DataLen     - Length of user data to transfer\r
+  PktId       - Packet Identification of this Qtd\r
+  Toggle      - Data Toggle of this Qtd\r
+  QtdPtrPtr   - A pointer of pointer to Qtd for return\r
+  \r
+Returns:\r
+\r
+  EFI_SUCCESS            Success\r
+  EFI_OUT_OF_RESOURCES   Cannot allocate resources\r
+  \r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+CreateStatusQtd (\r
+  IN  USB2_HC_DEV           *HcDev,\r
+  IN  UINT8                 PktId,\r
+  OUT EHCI_QTD_ENTITY       **QtdPtrPtr\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Create Qtd Structure for status \r
+\r
+Arguments:\r
+\r
+  HcDev       - USB2_HC_DEV \r
+  PktId       - Packet Identification of this Qtd\r
+  QtdPtrPtr   - A pointer of pointer to Qtd for return\r
+  \r
+Returns:\r
+\r
+  EFI_SUCCESS            Success\r
+  EFI_OUT_OF_RESOURCES   Cannot allocate resources\r
+  \r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+CreateAltQtd (\r
+  IN  USB2_HC_DEV           *HcDev,\r
+  IN  UINT8                 PktId,\r
+  OUT EHCI_QTD_ENTITY       **QtdPtrPtr\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Create Qtd Structure for Alternative \r
+\r
+Arguments:\r
+\r
+  HcDev      - USB2_HC_DEV \r
+  PktId      - Packet Identification of this Qtd\r
+  QtdPtrPtr  - A pointer of pointer to Qtd for return\r
+  \r
+Returns:\r
+\r
+  EFI_SUCCESS            Success\r
+  EFI_OUT_OF_RESOURCES   Cannot allocate resources\r
+  \r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+CreateControlQtds (\r
+  IN  USB2_HC_DEV                         *HcDev,\r
+  IN UINT8                                DataPktId,\r
+  IN UINT8                                *RequestCursor,\r
+  IN UINT8                                *DataCursor,\r
+  IN UINTN                                DataLen,\r
+  IN  EFI_USB2_HC_TRANSACTION_TRANSLATOR  *Translator,\r
+  OUT EHCI_QTD_ENTITY                     **ControlQtdsHead\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Create Qtds list for Control Transfer \r
+\r
+Arguments:\r
+\r
+  HcDev           - USB2_HC_DEV \r
+  DataPktId       - Packet Identification of Data Qtds\r
+  RequestCursor   - A pointer to request structure buffer to transfer\r
+  DataCursor      - A pointer to user data buffer to transfer\r
+  DataLen         - Length of user data to transfer\r
+  ControlQtdsHead - A pointer of pointer to first Qtd for control tranfer for return\r
+  \r
+Returns:\r
+\r
+  EFI_SUCCESS       Success\r
+  EFI_DEVICE_ERROR  Fail\r
+  \r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+CreateBulkOrInterruptQtds (\r
+  IN  USB2_HC_DEV                          *HcDev,\r
+  IN  UINT8                                PktId,\r
+  IN  UINT8                                *DataCursor,\r
+  IN  UINTN                                DataLen,\r
+  IN  EFI_USB2_HC_TRANSACTION_TRANSLATOR   *Translator,\r
+  OUT EHCI_QTD_ENTITY                      **QtdsHead\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Create Qtds list for Bulk or Interrupt Transfer \r
+\r
+Arguments:\r
+\r
+  HcDev        - USB2_HC_DEV \r
+  PktId        - Packet Identification of Qtds\r
+  DataCursor   - A pointer to user data buffer to transfer\r
+  DataLen      - Length of user data to transfer\r
+  DataToggle   - Data Toggle to start\r
+  Translator   - Translator Transaction for SplitX\r
+  QtdsHead     - A pointer of pointer to first Qtd for control tranfer for return\r
+  \r
+Returns:\r
+\r
+  EFI_SUCCESS       Success\r
+  EFI_DEVICE_ERROR  Fail\r
+  \r
+--*/\r
+;\r
+\r
+VOID\r
+DestoryQtds (\r
+  IN USB2_HC_DEV          *HcDev,\r
+  IN EHCI_QTD_ENTITY      *FirstQtdPtr\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Destory all Qtds in the list\r
+\r
+Arguments:\r
+\r
+  HcDev        - USB2_HC_DEV \r
+  FirstQtdPtr  - A pointer to first Qtd in the list \r
+    \r
+Returns:\r
+\r
+  VOID\r
+\r
+--*/\r
+;\r
+\r
+VOID\r
+LinkQtdToQtd (\r
+  IN EHCI_QTD_ENTITY     *PreQtdPtr,\r
+  IN EHCI_QTD_ENTITY     *QtdPtr\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Link Qtds together\r
+  \r
+Arguments:\r
+\r
+  PreQtdPtr  - A pointer to pre Qtd\r
+  QtdPtr     - A pointer to next Qtd\r
+    \r
+Returns:\r
+\r
+  VOID\r
+\r
+--*/\r
+;\r
+\r
+VOID\r
+LinkQtdsToAltQtd (\r
+  IN EHCI_QTD_ENTITY     *FirstQtdPtr,\r
+  IN EHCI_QTD_ENTITY     *AltQtdPtr\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Link AlterQtds together\r
+  \r
+Arguments:\r
+\r
+  FirstQtdPtr - A pointer to first Qtd in the list\r
+  AltQtdPtr - A pointer to alternative Qtd\r
+    \r
+Returns:\r
+  VOID\r
+\r
+--*/\r
+;\r
+\r
+VOID\r
+LinkQtdToQh (\r
+  IN EHCI_QH_ENTITY      *QhPtr,\r
+  IN EHCI_QTD_ENTITY     *QtdEntryPtr\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Link Qtds list to Qh\r
+  \r
+Arguments:\r
+\r
+  QhPtr   - A pointer to Qh\r
+  QtdPtr  - A pointer to first Qtd in the list\r
+  \r
+Returns:\r
+\r
+  VOID\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+LinkQhToAsyncList (\r
+  IN  USB2_HC_DEV       *HcDev,\r
+  IN EHCI_QH_ENTITY     *QhPtr\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Link Qh to Async Schedule List\r
+  \r
+Arguments:\r
+\r
+  HcDev - USB2_HC_DEV \r
+  QhPtr - A pointer to Qh\r
+  \r
+Returns:\r
+\r
+  EFI_SUCCESS       Success\r
+  EFI_DEVICE_ERROR  Fail\r
+  \r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+UnlinkQhFromAsyncList (\r
+  IN USB2_HC_DEV         *HcDev,\r
+  IN EHCI_QH_ENTITY      *QhPtr\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Unlink Qh from Async Schedule List\r
+  \r
+Arguments:\r
+\r
+  HcDev   - USB2_HC_DEV \r
+  QhPtr   - A pointer to Qh\r
+  \r
+Returns:\r
+\r
+  EFI_SUCCESS       Success\r
+  EFI_DEVICE_ERROR  Fail\r
+  \r
+--*/\r
+;\r
+\r
+VOID\r
+LinkQhToPeriodicList (\r
+  IN USB2_HC_DEV        *HcDev,\r
+  IN EHCI_QH_ENTITY     *QhPtr\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Link Qh to Periodic Schedule List\r
+  \r
+Arguments:\r
+\r
+  HcDev   - USB2_HC_DEV \r
+  QhPtr   - A pointer to Qh\r
+  \r
+Returns:\r
+\r
+  VOID\r
+\r
+--*/\r
+;\r
+\r
+VOID\r
+UnlinkQhFromPeriodicList (\r
+  IN USB2_HC_DEV         *HcDev,\r
+  IN EHCI_QH_ENTITY      *QhPtr,\r
+  IN UINTN                Interval\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Unlink Qh from Periodic Schedule List\r
+  \r
+Arguments:\r
+\r
+  HcDev     - USB2_HC_DEV \r
+  QhPtr     - A pointer to Qh\r
+  Interval  - Interval of this periodic transfer\r
+  \r
+Returns:\r
+\r
+  VOID\r
+  \r
+--*/\r
+;\r
+\r
+VOID\r
+LinkToAsyncReqeust (\r
+  IN  USB2_HC_DEV        *HcDev,\r
+  IN  EHCI_ASYNC_REQUEST *AsyncRequestPtr\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Llink AsyncRequest Entry to Async Request List\r
+  \r
+Arguments:\r
+\r
+  HcDev           - USB2_HC_DEV \r
+  AsyncRequestPtr - A pointer to Async Request Entry\r
+  \r
+Returns:\r
+\r
+  VOID\r
+  \r
+--*/\r
+;\r
+\r
+VOID\r
+UnlinkFromAsyncReqeust (\r
+  IN  USB2_HC_DEV        *HcDev,\r
+  IN  EHCI_ASYNC_REQUEST *AsyncRequestPtr\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Unlink AsyncRequest Entry from Async Request List\r
+  \r
+Arguments:\r
+\r
+  HcDev           - USB2_HC_DEV \r
+  AsyncRequestPtr - A pointer to Async Request Entry\r
+  \r
+Returns:\r
+\r
+  VOID\r
+  \r
+--*/\r
+;\r
+\r
+UINTN\r
+GetNumberOfQtd (\r
+  IN EHCI_QTD_ENTITY    *FirstQtdPtr\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Number of Qtds in the list\r
+  \r
+Arguments:\r
+\r
+  FirstQtdPtr - A pointer to first Qtd in the list\r
+    \r
+Returns:\r
+\r
+  Number of Qtds in the list\r
+\r
+--*/\r
+;\r
+\r
+UINTN\r
+GetNumberOfTransaction (\r
+  IN UINTN    SizeOfData,\r
+  IN UINTN    SizeOfTransaction\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Number of Transactions in one Qtd\r
+  \r
+Arguments:\r
+\r
+  SizeOfData           - Size of one Qtd\r
+  SizeOfTransaction    - Size of one Transaction\r
+   \r
+Returns:\r
+\r
+  Number of Transactions in this Qtd\r
+\r
+--*/\r
+;\r
+\r
+UINTN\r
+GetCapacityOfQtd (\r
+  IN UINT8    *BufferCursor\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Get Capacity of Qtd\r
+  \r
+Arguments:\r
+\r
+  BufferCursor  - BufferCursor of the Qtd\r
+   \r
+Returns:\r
+\r
+  Capacity of Qtd\r
+\r
+--*/\r
+;\r
+\r
+UINTN\r
+GetApproxiOfInterval (\r
+  IN UINTN  Interval\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Get the approximate value in the 2 index sequence\r
+  \r
+Arguments:\r
+\r
+  Interval - the value of interval\r
+  \r
+Returns:\r
+\r
+  approximate value of interval in the 2 index sequence\r
+  \r
+--*/\r
+;\r
+\r
+EHCI_QTD_HW *\r
+GetQtdNextPointer (\r
+  IN EHCI_QTD_HW *HwQtdPtr\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Get Qtd next pointer field\r
+  \r
+Arguments:\r
+\r
+  HwQtdPtr - A pointer to hardware Qtd structure\r
+  \r
+Returns:\r
+\r
+  A pointer to next hardware Qtd structure\r
+  \r
+--*/\r
+;\r
+\r
+BOOLEAN\r
+IsQtdStatusActive (\r
+  IN EHCI_QTD_HW *HwQtdPtr\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Whether Qtd status is active or not\r
+  \r
+Arguments:\r
+\r
+  HwQtdPtr - A pointer to hardware Qtd structure\r
+  \r
+Returns:\r
+\r
+  TRUE    Active\r
+  FALSE   Inactive\r
+  \r
+--*/\r
+;\r
+\r
+BOOLEAN\r
+IsQtdStatusHalted (\r
+  IN EHCI_QTD_HW *HwQtdPtr\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Whether Qtd status is halted or not\r
+  \r
+Arguments:\r
+\r
+  HwQtdPtr - A pointer to hardware Qtd structure\r
+  \r
+Returns:\r\r
+\r
+  TRUE    Halted\r
+  FALSE   Not halted\r
+  \r
+--*/\r
+;\r
+\r
+BOOLEAN\r
+IsQtdStatusBufferError (\r
+  IN EHCI_QTD_HW *HwQtdPtr\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Whether Qtd status is buffer error or not\r
+  \r
+Arguments:\r
+\r
+  HwQtdPtr - A pointer to hardware Qtd structure\r
+  \r
+Returns:\r
+\r
+  TRUE    Buffer error\r
+  FALSE   No buffer error\r
+  \r
+--*/\r
+;\r
+\r
+BOOLEAN\r
+IsQtdStatusBabbleError (\r
+  IN EHCI_QTD_HW *HwQtdPtr\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Whether Qtd status is babble error or not\r
+  \r
+Arguments:\r
+\r
+  HwQtdPtr - A pointer to hardware Qtd structure\r
+  \r
+Returns:\r
+\r
+  TRUE    Babble error\r
+  FALSE   No babble error\r
+  \r
+--*/\r
+;\r
+\r
+BOOLEAN\r
+IsQtdStatusTransactionError (\r
+  IN EHCI_QTD_HW *HwQtdPtr\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Whether Qtd status is transaction error or not\r
+  \r
+Arguments:\r
+\r
+  HwQtdPtr - A pointer to hardware Qtd structure\r
+  \r
+Returns:\r
+\r
+  TRUE    Transaction error\r
+  FALSE   No transaction error\r
+  \r
+--*/\r
+;\r
+\r
+BOOLEAN\r
+IsDataInTransfer (\r
+  IN  UINT8     EndPointAddress\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Whether is a DataIn direction transfer\r
+  \r
+Arguments:\r
+\r
+  EndPointAddress - address of the endpoint \r
+  \r
+Returns:\r
+\r
+  TRUE    DataIn\r
+  FALSE   DataOut\r
+  \r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+MapDataBuffer (\r
+  IN  USB2_HC_DEV             *HcDev,\r
+  IN  EFI_USB_DATA_DIRECTION  TransferDirection,\r
+  IN  OUT VOID                *Data,\r
+  IN  OUT UINTN               *DataLength,\r
+  OUT UINT8                   *PktId,\r
+  OUT UINT8                   **DataCursor,\r
+  OUT VOID                    **DataMap\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Map address of user data buffer\r
+  \r
+Arguments:\r
+\r
+  HcDev             - USB2_HC_DEV \r
+  TransferDirection - direction of transfer\r
+  Data              - A pointer to user data buffer \r
+  DataLength        - length of user data\r
+  PktId             - Packte Identificaion\r
+  DataCursor        - mapped address to return\r
+  DataMap           - identificaion of this mapping to return\r
+  \r
+Returns:\r
+\r
+  EFI_SUCCESS        Success\r
+  EFI_DEVICE_ERROR   Fail\r
+  \r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+MapRequestBuffer (\r
+  IN  USB2_HC_DEV             *HcDev,\r
+  IN  OUT VOID                *Request,\r
+  OUT UINT8                   **RequestCursor,\r
+  OUT VOID                    **RequestMap\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Map address of request structure buffer\r
+  \r
+Arguments:\r
+\r
+  HcDev           - USB2_HC_DEV \r
+  Request         - A pointer to request structure\r
+  RequestCursor   - Mapped address of request structure to return\r
+  RequestMap      - Identificaion of this mapping to return\r
+  \r
+Returns:\r
+\r
+  EFI_SUCCESS        Success\r
+  EFI_DEVICE_ERROR   Fail\r
+  \r
+--*/\r
+;\r
+\r
+VOID\r
+SetQtdBufferPointer (\r
+  IN EHCI_QTD_HW *QtdHwPtr,\r
+  IN VOID        *DataPtr,\r
+  IN UINTN       DataLen\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Set data buffer pointers in Qtd\r
+\r
+Arguments:\r
+\r
+  QtdHwPtr  - A pointer to Qtd hardware structure \r
+  DataPtr   - A pointer to user data buffer\r
+  DataLen   - Length of the user data buffer\r
+    \r
+Returns:\r
+\r
+  VOID\r
+\r
+--*/\r
+;\r
+\r
+EHCI_QTD_HW *\r
+GetQtdAlternateNextPointer (\r
+  IN EHCI_QTD_HW *HwQtdPtr\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Get Qtd alternate next pointer field\r
+  \r
+Arguments:\r
+\r
+  HwQtdPtr - A pointer to hardware Qtd structure\r
+  \r
+Returns:\r
+\r
+  A pointer to hardware alternate Qtd\r
+  \r
+--*/\r
+;\r
+\r
+VOID\r
+ZeroOutQhOverlay (\r
+  IN EHCI_QH_ENTITY *QhPtr\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Zero out the fields in Qh structure\r
+  \r
+Arguments:\r
+\r
+  QhPtr - A pointer to Qh structure\r
+  \r
+Returns:\r
+\r
+  VOID\r
+  \r
+--*/\r
+;\r
+\r
+VOID\r
+UpdateAsyncRequestTransfer (\r
+  IN EHCI_ASYNC_REQUEST *AsyncRequestPtr,\r
+  IN UINT32             TransferResult,\r
+  IN UINTN              ErrTDPos\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Update asynchronous request transfer\r
+  \r
+Arguments:\r
+\r
+  AsyncRequestPtr  - A pointer to async request  \r
+  TransferResult   - transfer result \r
+  ErrQtdPos        - postion of error Qtd\r
+  \r
+Returns:\r
+\r
+  VOID\r
+  \r
+--*/\r
+;\r
+\r
+\r
+EFI_STATUS\r
+DeleteAsyncRequestTransfer (\r
+  IN  USB2_HC_DEV     *HcDev,\r
+  IN  UINT8           DeviceAddress,\r
+  IN  UINT8           EndPointAddress,\r
+  OUT UINT8           *DataToggle\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Delete all asynchronous request transfer\r
+  \r
+Arguments:\r
+\r
+  HcDev           - USB2_HC_DEV \r
+  DeviceAddress   - address of usb device\r
+  EndPointAddress - address of endpoint\r
+  DataToggle      - stored data toggle\r
+  \r
+Returns:\r
+\r
+  EFI_SUCCESS        Success\r
+  EFI_DEVICE_ERROR   Fail\r
+\r
+--*/\r
+;\r
+\r
+VOID\r
+CleanUpAllAsyncRequestTransfer (\r
+  IN  USB2_HC_DEV *HcDev\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Clean up all asynchronous request transfer\r
+  \r
+Arguments:\r
+\r
+  HcDev - USB2_HC_DEV \r
+  \r
+Returns:\r
+  VOID\r
+  \r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+ExecuteTransfer (\r
+  IN  USB2_HC_DEV         *HcDev,\r
+  IN BOOLEAN              IsControl,\r
+  IN  EHCI_QH_ENTITY      *QhPtr,\r
+  IN OUT UINTN            *ActualLen,\r
+  OUT UINT8               *DataToggle,\r
+  IN  UINTN               TimeOut,\r
+  OUT UINT32              *TransferResult\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Execute Bulk or SyncInterrupt Transfer\r
+\r
+Arguments:\r
+\r
+  HcDev            - USB2_HC_DEV\r
+  IsControl        - Is control transfer or not\r
+  QhPtr            - A pointer to Qh\r
+  ActualLen        - Actual transfered Len \r
+  DataToggle       - Data Toggle\r
+  TimeOut          - TimeOut threshold\r
+  TransferResult   - Transfer result\r
+  \r
+Returns:\r
+\r
+  EFI_SUCCESS        Sucess\r
+  EFI_DEVICE_ERROR   Error\r
+  \r
+--*/\r
+;\r
+\r
+BOOLEAN\r
+CheckQtdsTransferResult (\r
+  IN BOOLEAN             IsControl,\r
+  IN  EHCI_QH_ENTITY     *QhPtr,\r
+  OUT UINT32             *Result,\r
+  OUT UINTN              *ErrQtdPos,\r
+  OUT UINTN              *ActualLen\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Check transfer result of Qtds\r
+\r
+Arguments:\r
+\r
+  IsControl     - Is control transfer or not\r
+  QhPtr         - A pointer to Qh\r
+  Result        - Transfer result\r
+  ErrQtdPos     - Error TD Position\r
+  ActualLen     - Actual Transfer Size\r
+\r
+Returns:\r
+\r
+  TRUE    Qtds finished\r
+  FALSE   Not finish\r
+  \r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+AsyncRequestMoniter (\r
+  IN EFI_EVENT     Event,\r
+  IN VOID          *Context\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+  \r
+  Interrupt transfer periodic check handler\r
+    \r
+Arguments:\r
+\r
+  Event     - Interrupt event\r
+  Context   - Pointer to USB2_HC_DEV\r
+    \r
+Returns:\r
+  \r
+  EFI_SUCCESS        Success\r
+  EFI_DEVICE_ERROR   Fail\r
+    \r
+--*/\r
+;\r
+\r
+#endif\r
diff --git a/EdkModulePkg/Bus/Pci/Ehci/Dxe/Ehci.msa b/EdkModulePkg/Bus/Pci/Ehci/Dxe/Ehci.msa
new file mode 100644 (file)
index 0000000..a44b5a4
--- /dev/null
@@ -0,0 +1,87 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<!--Copyright (c) 2006, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution.  The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.-->\r
+<ModuleSurfaceArea  xmlns="http://www.TianoCore.org/2006/Edk2.0">\r
+  <MsaHeader>\r
+    <ModuleName>Ehci</ModuleName>\r
+    <ModuleType>UEFI_DRIVER</ModuleType>\r
+    <GuidValue>BDFE430E-8F2A-4db0-9991-6F856594777E</GuidValue>\r
+    <Version>1.0</Version>\r
+    <Abstract>Component description file for Ehci module</Abstract>\r
+    <Description>This module provides USB2 Host Controller Protocol implementation for Enhanced Host Controller Interface</Description>\r
+    <Copyright>Copyright (c) 2006, Intel Corporation</Copyright>\r
+    <License>All rights reserved. This program and the accompanying materials
+      are licensed and made available under the terms and conditions of the BSD License
+      which accompanies this distribution.  The full text of the license may be found at
+      http://opensource.org/licenses/bsd-license.php
+      THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+      WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.</License>\r
+    <Specification>FRAMEWORK_BUILD_PACKAGING_SPECIFICATION   0x00000052</Specification>\r
+  </MsaHeader>\r
+  <ModuleDefinitions>\r
+    <SupportedArchitectures>IA32 X64 IPF EBC</SupportedArchitectures>\r
+    <BinaryModule>false</BinaryModule>\r
+    <OutputFileBasename>Ehci</OutputFileBasename>\r
+  </ModuleDefinitions>\r
+  <LibraryClassDefinitions>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>DebugLib</Keyword>\r
+    </LibraryClass>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>UefiDriverModelLib</Keyword>\r
+    </LibraryClass>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>UefiDriverEntryPoint</Keyword>\r
+    </LibraryClass>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>BaseLib</Keyword>\r
+    </LibraryClass>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>UefiLib</Keyword>\r
+    </LibraryClass>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>BaseMemoryLib</Keyword>\r
+    </LibraryClass>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>MemoryAllocationLib</Keyword>\r
+    </LibraryClass>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>UefiBootServicesTableLib</Keyword>\r
+    </LibraryClass>\r
+  </LibraryClassDefinitions>\r
+  <SourceFiles>\r
+    <Filename>Ehci.c</Filename>\r
+    <Filename>EhciMem.c</Filename>\r
+    <Filename>EhciReg.c</Filename>\r
+    <Filename>EhciSched.c</Filename>\r
+    <Filename>ComponentName.c</Filename>\r
+    <Filename>Ehci.h</Filename>\r
+  </SourceFiles>\r
+  <PackageDependencies>\r
+    <Package PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>\r
+  </PackageDependencies>\r
+  <Protocols>\r
+    <Protocol Usage="TO_START">\r
+      <ProtocolCName>gEfiPciIoProtocolGuid</ProtocolCName>\r
+    </Protocol>\r
+    <Protocol Usage="BY_START">\r
+      <ProtocolCName>gEfiUsb2HcProtocolGuid</ProtocolCName>\r
+    </Protocol>\r
+  </Protocols>\r
+  <Externs>\r
+    <Specification>EFI_SPECIFICATION_VERSION 0x00020000</Specification>\r
+    <Specification>EDK_RELEASE_VERSION 0x00020000</Specification>\r
+    <Extern>\r
+      <DriverBinding>gEhciDriverBinding</DriverBinding>\r
+    </Extern>\r
+    <Extern>\r
+      <ComponentName>gEhciComponentName</ComponentName>\r
+    </Extern>\r
+  </Externs>\r
+</ModuleSurfaceArea>
\ No newline at end of file
diff --git a/EdkModulePkg/Bus/Pci/Ehci/Dxe/EhciMem.c b/EdkModulePkg/Bus/Pci/Ehci/Dxe/EhciMem.c
new file mode 100644 (file)
index 0000000..2f35f77
--- /dev/null
@@ -0,0 +1,761 @@
+/*++\r
+\r
+Copyright (c) 2006, Intel Corporation                                                     \r
+All rights reserved. This program and the accompanying materials                          \r
+are licensed and made available under the terms and conditions of the BSD License         \r
+which accompanies this distribution.  The full text of the license may be found at        \r
+http://opensource.org/licenses/bsd-license.php                                            \r
+                                                                                          \r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     \r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             \r
+\r
+Module Name:\r
+\r
+    EhciMem.c\r
+    \r
+Abstract: \r
+    \r
+\r
+Revision History\r
+--*/\r
+\r
+#include "Ehci.h"\r
+\r
+\r
+EFI_STATUS\r
+CreateMemoryBlock (\r
+  IN  USB2_HC_DEV               *HcDev,\r
+  OUT MEMORY_MANAGE_HEADER      **MemoryHeader,\r
+  IN  UINTN                     MemoryBlockSizeInPages\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Use PciIo->AllocateBuffer to allocate common buffer for the memory block,\r
+  and use PciIo->Map to map the common buffer for Bus Master Read/Write.\r
+\r
+Arguments:\r
+\r
+  HcDev                  - USB2_HC_DEV\r
+  MemoryHeader           - MEMORY_MANAGE_HEADER to output\r
+  MemoryBlockSizeInPages - MemoryBlockSizeInPages\r
+  \r
+Returns:\r
+\r
+  EFI_SUCCESS           Success\r
+  EFI_OUT_OF_RESOURCES  Fail for no resources\r
+  EFI_UNSUPPORTED       Unsupported currently\r
+  \r
+--*/\r
+{\r
+  EFI_STATUS            Status;\r
+  VOID                  *CommonBuffer;\r
+  EFI_PHYSICAL_ADDRESS  MappedAddress;\r
+  UINTN                 MemoryBlockSizeInBytes;\r
+  VOID                  *Mapping;\r
+\r
+  //\r
+  // Allocate memory for MemoryHeader\r
+  //\r
+  *MemoryHeader = AllocateZeroPool (sizeof (MEMORY_MANAGE_HEADER));\r
+  if (*MemoryHeader == NULL) {\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
+\r
+  (*MemoryHeader)->Next = NULL;\r
+\r
+  //\r
+  // set Memory block size\r
+  //\r
+  (*MemoryHeader)->MemoryBlockSizeInBytes = EFI_PAGES_TO_SIZE (MemoryBlockSizeInPages);\r
+\r
+  //\r
+  // each bit in Bit Array will manage 32 bytes memory in memory block\r
+  //\r
+  (*MemoryHeader)->BitArraySizeInBytes = ((*MemoryHeader)->MemoryBlockSizeInBytes / 32) / 8;\r
+\r
+  //\r
+  // Allocate memory for BitArray\r
+  //\r
+  (*MemoryHeader)->BitArrayPtr = AllocateZeroPool ((*MemoryHeader)->BitArraySizeInBytes);\r
+  if ((*MemoryHeader)->BitArrayPtr == NULL) {\r
+    gBS->FreePool (*MemoryHeader);\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
+  \r
+  //\r
+  // Memory Block uses MemoryBlockSizeInPages pages,\r
+  // and it is allocated as common buffer use.\r
+  //\r
+  Status = HcDev->PciIo->AllocateBuffer (\r
+                           HcDev->PciIo,\r
+                           AllocateAnyPages,\r
+                           EfiBootServicesData,\r
+                           MemoryBlockSizeInPages,\r
+                           &CommonBuffer,\r
+                           0\r
+                           );\r
+  if (EFI_ERROR (Status)) {\r
+    gBS->FreePool ((*MemoryHeader)->BitArrayPtr);\r
+    gBS->FreePool (*MemoryHeader);\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
+\r
+  MemoryBlockSizeInBytes = EFI_PAGES_TO_SIZE (MemoryBlockSizeInPages);\r
+  Status = HcDev->PciIo->Map (\r
+                           HcDev->PciIo,\r
+                           EfiPciIoOperationBusMasterCommonBuffer,\r
+                           CommonBuffer,\r
+                           &MemoryBlockSizeInBytes,\r
+                           &MappedAddress,\r
+                           &Mapping\r
+                           );\r
+  //\r
+  // If returned Mapped size is less than the size \r
+  // we request,do not support.\r
+  //\r
+  if (EFI_ERROR (Status) || (MemoryBlockSizeInBytes != EFI_PAGES_TO_SIZE (MemoryBlockSizeInPages))) {\r
+    HcDev->PciIo->FreeBuffer (HcDev->PciIo, MemoryBlockSizeInPages, CommonBuffer);\r
+    gBS->FreePool ((*MemoryHeader)->BitArrayPtr);\r
+    gBS->FreePool (*MemoryHeader);\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+  \r
+  //\r
+  // Data structure involved by host controller \r
+  // should be restricted into the same 4G\r
+  //\r
+  if (HcDev->Is64BitCapable != 0) {\r
+       if (HcDev->High32BitAddr != GET_32B_TO_63B (MappedAddress)) {\r
+         HcDev->PciIo->Unmap (HcDev->PciIo, Mapping);\r
+      HcDev->PciIo->FreeBuffer (HcDev->PciIo, MemoryBlockSizeInPages, CommonBuffer);\r
+      gBS->FreePool ((*MemoryHeader)->BitArrayPtr);\r
+      gBS->FreePool (*MemoryHeader);\r
+      return EFI_UNSUPPORTED;\r
+       }\r
+  }\r
+  \r
+  //\r
+  // Set Memory block initial address\r
+  //\r
+  (*MemoryHeader)->MemoryBlockPtr = (UINT8 *) ((UINTN) MappedAddress);\r
+  (*MemoryHeader)->Mapping        = Mapping;\r
+\r
+  ZeroMem (\r
+    (*MemoryHeader)->MemoryBlockPtr,\r
+    EFI_PAGES_TO_SIZE (MemoryBlockSizeInPages)\r
+    );\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+FreeMemoryHeader (\r
+  IN USB2_HC_DEV               *HcDev,\r
+  IN MEMORY_MANAGE_HEADER      *MemoryHeader\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Free Memory Header\r
+\r
+Arguments:\r
+\r
+  HcDev         - USB2_HC_DEV\r
+  MemoryHeader  - MemoryHeader to be freed\r
+\r
+Returns:\r
+\r
+  EFI_SUCCESS            Success\r
+  EFI_INVALID_PARAMETER  Parameter is error\r
+\r
+--*/\r
+{\r
+  if ((MemoryHeader == NULL) || (HcDev == NULL)) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+  //\r
+  // unmap the common buffer used by the memory block\r
+  //\r
+  HcDev->PciIo->Unmap (HcDev->PciIo, MemoryHeader->Mapping);\r
+\r
+  //\r
+  // free common buffer\r
+  //\r
+  HcDev->PciIo->FreeBuffer (\r
+                  HcDev->PciIo,\r
+                  EFI_SIZE_TO_PAGES (MemoryHeader->MemoryBlockSizeInBytes),\r
+                  MemoryHeader->MemoryBlockPtr\r
+                  );\r
+  //\r
+  // free bit array\r
+  //\r
+  gBS->FreePool (MemoryHeader->BitArrayPtr);\r
+  //\r
+  // free memory header\r
+  //\r
+  gBS->FreePool (MemoryHeader);\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+EhciAllocatePool (\r
+  IN  USB2_HC_DEV     *HcDev,\r
+  OUT UINT8           **Pool,\r
+  IN  UINTN           AllocSize\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Ehci Allocate Pool\r
+\r
+Arguments:\r
+\r
+  HcDev     - USB2_HC_DEV\r
+  Pool      - Place to store pointer to the memory buffer\r
+  AllocSize - Alloc Size\r
+\r
+Returns:\r
+\r
+  EFI_SUCCESS        Success\r
+  EFI_DEVICE_ERROR   Fail\r
+\r
+--*/\r
+{\r
+  MEMORY_MANAGE_HEADER  *MemoryHeader;\r
+  MEMORY_MANAGE_HEADER  *TempHeaderPtr;\r
+  MEMORY_MANAGE_HEADER  *NewMemoryHeader;\r
+  UINTN                 RealAllocSize;\r
+  UINTN                 MemoryBlockSizeInPages;\r
+  EFI_STATUS            Status;\r
+  EFI_TPL               OldTpl;\r
+\r
+  *Pool         = NULL;\r
+\r
+  MemoryHeader  = HcDev->MemoryHeader;\r
+  ASSERT (MemoryHeader != NULL);\r
+\r
+  OldTpl = gBS->RaiseTPL (EFI_TPL_NOTIFY + 1);\r
+  \r
+  //\r
+  // allocate unit is 32 bytes (align on 32 byte)\r
+  //\r
+  if (AllocSize & 0x1F) {\r
+    RealAllocSize = (AllocSize / 32 + 1) * 32;\r
+  } else {\r
+    RealAllocSize = AllocSize;\r
+  }\r
+  \r
+  //\r
+  // There may be linked MemoryHeaders.\r
+  // To allocate a free pool in Memory blocks,\r
+  // must search in the MemoryHeader link list\r
+  // until enough free pool is found.\r
+  //\r
+  Status = EFI_NOT_FOUND;\r
+  for (TempHeaderPtr = MemoryHeader; TempHeaderPtr != NULL; TempHeaderPtr = TempHeaderPtr->Next) {\r
+\r
+    Status = AllocMemInMemoryBlock (\r
+              TempHeaderPtr,\r
+              Pool,\r
+              RealAllocSize / 32\r
+              );\r
+    if (!EFI_ERROR (Status)) {\r
+      ZeroMem (*Pool, AllocSize);\r
+      gBS->RestoreTPL (OldTpl);\r
+      return EFI_SUCCESS;\r
+    }\r
+  }\r
+\r
+  gBS->RestoreTPL (OldTpl);\r
+  \r
+  //\r
+  // There is no enough memory,\r
+  // Create a new Memory Block\r
+  //\r
+  \r
+  //\r
+  // if pool size is larger than NORMAL_MEMORY_BLOCK_UNIT_IN_PAGES,\r
+  // just allocate a large enough memory block.\r
+  //\r
+  if (RealAllocSize > EFI_PAGES_TO_SIZE (NORMAL_MEMORY_BLOCK_UNIT_IN_PAGES)) {\r
+    MemoryBlockSizeInPages = EFI_SIZE_TO_PAGES (RealAllocSize) + 1;\r
+  } else {\r
+    MemoryBlockSizeInPages = NORMAL_MEMORY_BLOCK_UNIT_IN_PAGES;\r
+  }\r
+\r
+  Status = CreateMemoryBlock (HcDev, &NewMemoryHeader, MemoryBlockSizeInPages);\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  OldTpl = gBS->RaiseTPL (EFI_TPL_NOTIFY + 1);\r\r
+       \r
+  //\r
+  // Link the new Memory Block to the Memory Header list\r
+  //\r
+  InsertMemoryHeaderToList (MemoryHeader, NewMemoryHeader);\r
+\r
+  Status = AllocMemInMemoryBlock (\r
+             NewMemoryHeader,\r
+             Pool,\r
+             RealAllocSize / 32\r
+             );\r
+  if (!EFI_ERROR (Status)) {\r
+    ZeroMem (*Pool, AllocSize);\r
+  }\r
+\r
+  gBS->RestoreTPL (OldTpl);\r
+  return Status;\r
+}\r
+\r
+VOID\r
+EhciFreePool (\r
+  IN USB2_HC_DEV     *HcDev,\r
+  IN UINT8           *Pool,\r
+  IN UINTN           AllocSize\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Uhci Free Pool\r
+\r
+Arguments:\r
+\r
+  HcDev     - USB_HC_DEV\r
+  Pool      - Pool to free\r
+  AllocSize - Pool size\r
+\r
+Returns:\r
+\r
+  VOID\r
+\r
+--*/\r
+{\r
+  MEMORY_MANAGE_HEADER  *MemoryHeader;\r
+  MEMORY_MANAGE_HEADER  *TempHeaderPtr;\r
+  UINTN                 StartBytePos;\r
+  UINTN                 Index;\r
+  UINT8                 StartBitPos;\r
+  UINT8                 Index2;\r
+  UINTN                 Count;\r
+  UINTN                 RealAllocSize;\r
+  EFI_TPL               OldTpl;\r
+\r
+  OldTpl        = gBS->RaiseTPL (EFI_TPL_NOTIFY + 1);\r
+\r
+  MemoryHeader  = HcDev->MemoryHeader;\r
+\r
+  //\r
+  // allocate unit is 32 byte (align on 32 byte)\r
+  //\r
+  if (AllocSize & 0x1F) {\r
+    RealAllocSize = (AllocSize / 32 + 1) * 32;\r
+  } else {\r
+    RealAllocSize = AllocSize;\r
+  }\r
+  \r
+  //\r
+  // scan the memory header linked list for\r
+  // the asigned memory to free.\r
+  //\r
+  for (TempHeaderPtr = MemoryHeader; TempHeaderPtr != NULL; TempHeaderPtr = TempHeaderPtr->Next) {\r
+\r
+    if ((Pool >= TempHeaderPtr->MemoryBlockPtr) &&\r
+        ((Pool + RealAllocSize) <= (TempHeaderPtr->MemoryBlockPtr + TempHeaderPtr->MemoryBlockSizeInBytes))\r
+        ) {\r
+      //\r
+      // Pool is in the Memory Block area,\r
+      // find the start byte and bit in the bit array\r
+      //\r
+      StartBytePos  = ((Pool - TempHeaderPtr->MemoryBlockPtr) / 32) / 8;\r
+      StartBitPos   = (UINT8) (((Pool - TempHeaderPtr->MemoryBlockPtr) / 32) & 0x7);\r
+\r
+      //\r
+      // reset associated bits in bit arry\r
+      //\r
+      for (Index = StartBytePos, Index2 = StartBitPos, Count = 0; Count < (RealAllocSize / 32); Count++) {\r
+        TempHeaderPtr->BitArrayPtr[Index] ^= (UINT8) (bit (Index2));\r
+        Index2++;\r
+        if (Index2 == 8) {\r
+          Index += 1;\r
+          Index2 = 0;\r
+        }\r
+      }\r
+      //\r
+      // break the loop\r
+      //\r
+      break;\r
+    }\r
+  }\r
+  \r
+  //\r
+  // Release emptied memory blocks (only if the memory block is not\r
+  // the first one in the memory header list\r
+  //\r
+  for (TempHeaderPtr = MemoryHeader->Next; TempHeaderPtr != NULL;) {\r
+\r
+    ASSERT (MemoryHeader->Next != NULL);\r
+\r
+    if (IsMemoryBlockEmptied (TempHeaderPtr)) {\r
+\r
+      DelinkMemoryBlock (MemoryHeader, TempHeaderPtr);\r
+      //\r
+      // when the TempHeaderPtr is freed in FreeMemoryHeader(),\r
+      // the TempHeaderPtr is pointing to nonsense content.\r
+      //\r
+      gBS->RestoreTPL (OldTpl);\r
+      FreeMemoryHeader (HcDev, TempHeaderPtr);\r
+      OldTpl = gBS->RaiseTPL (EFI_TPL_NOTIFY + 1);\r
+      //\r
+      // reset the TempHeaderPtr, continue search for\r
+      // another empty memory block.\r
+      //\r
+      TempHeaderPtr = MemoryHeader->Next;\r
+      continue;\r
+    }\r
+\r
+    TempHeaderPtr = TempHeaderPtr->Next;\r
+  }\r
+\r
+  gBS->RestoreTPL (OldTpl);\r
+}\r
+\r
+VOID\r
+InsertMemoryHeaderToList (\r
+  IN MEMORY_MANAGE_HEADER     *MemoryHeader,\r
+  IN MEMORY_MANAGE_HEADER     *NewMemoryHeader\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Insert Memory Header To List\r
+\r
+Arguments:\r
+\r
+  MemoryHeader    - MEMORY_MANAGE_HEADER\r
+  NewMemoryHeader - MEMORY_MANAGE_HEADER\r
+\r
+Returns:\r
+\r
+  VOID\r
+\r
+--*/\r
+{\r
+  MEMORY_MANAGE_HEADER  *TempHeaderPtr;\r
+\r
+  for (TempHeaderPtr = MemoryHeader; TempHeaderPtr != NULL; TempHeaderPtr = TempHeaderPtr->Next) {\r
+    if (TempHeaderPtr->Next == NULL) {\r
+      TempHeaderPtr->Next = NewMemoryHeader;\r
+      break;\r
+    }\r
+  }\r
+}\r
+\r
+EFI_STATUS\r
+AllocMemInMemoryBlock (\r
+  IN  MEMORY_MANAGE_HEADER     *MemoryHeader,\r
+  OUT VOID                     **Pool,\r
+  IN  UINTN                    NumberOfMemoryUnit\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Alloc Memory In MemoryBlock\r
+\r
+Arguments:\r
+\r
+  MemoryHeader        - MEMORY_MANAGE_HEADER\r
+  Pool                - Place to store pointer to memory\r
+  NumberOfMemoryUnit  - Number Of Memory Unit\r
+\r
+Returns:\r
+\r
+  EFI_SUCCESS    Success\r
+  EFI_NOT_FOUND  Can't find the free memory \r
+\r
+--*/\r
+{\r
+  UINTN TempBytePos;\r
+  UINTN FoundBytePos;\r
+  UINT8 Index;\r
+  UINT8 FoundBitPos;\r
+  UINT8 ByteValue;\r
+  UINT8 BitValue;\r
+  UINTN NumberOfZeros;\r
+  UINTN Count;\r
+\r
+  FoundBytePos  = 0;\r
+  FoundBitPos   = 0;\r
+  ByteValue     = MemoryHeader->BitArrayPtr[0];\r
+  NumberOfZeros = 0;\r
+  Index         = 0;\r
+\r
+  for (TempBytePos = 0; TempBytePos < MemoryHeader->BitArraySizeInBytes;) {\r
+       \r
+    //\r
+    // Pop out BitValue from a byte in TempBytePos.\r
+    //\r
+    BitValue = (UINT8) (ByteValue & 0x1);\r
+       \r
+    //\r
+    // right shift the byte\r
+    //\r
+    ByteValue /= 2;\r
+\r
+    if (BitValue == 0) {\r
+      //\r
+      // Found a free bit, the NumberOfZeros only record the number\r
+      // of those consecutive zeros\r
+      //\r
+      NumberOfZeros++;\r
+      //\r
+      // Found enough consecutive free space, break the loop\r
+      //\r
+      if (NumberOfZeros >= NumberOfMemoryUnit) {\r
+        break;\r
+      }\r
+    } else {\r
+      //\r
+      // Encountering a '1', meant the bit is ocupied.\r
+      //\r
+      if (NumberOfZeros >= NumberOfMemoryUnit) {\r
+        //\r
+        // Found enough consecutive free space,break the loop\r
+        //\r
+        break;\r
+      } else {\r
+        //\r
+        // the NumberOfZeros only record the number of those consecutive zeros,\r
+        // so reset the NumberOfZeros to 0 when encountering '1' before finding\r
+        // enough consecutive '0's\r
+        //\r
+        NumberOfZeros = 0;\r
+        //\r
+        // reset the (FoundBytePos,FoundBitPos) to the position of '1'\r
+        //\r
+        FoundBytePos  = TempBytePos;\r
+        FoundBitPos   = Index;\r
+      }\r
+    }\r
+       \r
+    //\r
+    // step forward a bit\r
+    //\r
+    Index++;\r
+    if (Index == 8) {\r
+      //\r
+      // step forward a byte, getting the byte value,\r
+      // and reset the bit pos.\r
+      //\r
+      TempBytePos += 1;\r
+      ByteValue = MemoryHeader->BitArrayPtr[TempBytePos];\r
+      Index     = 0;\r
+    }\r
+  }\r
+\r
+  if (NumberOfZeros < NumberOfMemoryUnit) {\r
+    return EFI_NOT_FOUND;\r
+  }\r
+  \r
+  //\r
+  // Found enough free space.\r
+  //\r
+  \r
+  //\r
+  // The values recorded in (FoundBytePos,FoundBitPos) have two conditions:\r
+  //  1)(FoundBytePos,FoundBitPos) record the position\r
+  //    of the last '1' before the consecutive '0's, it must\r
+  //    be adjusted to the start position of the consecutive '0's.\r
+  //  2)the start address of the consecutive '0's is just the start of\r
+  //    the bitarray. so no need to adjust the values of\r
+  //    (FoundBytePos,FoundBitPos).\r
+  //\r
+  if ((MemoryHeader->BitArrayPtr[FoundBytePos] & bit (FoundBitPos)) != 0) {\r
+    FoundBitPos += 1;\r
+  }\r
+  \r
+  //\r
+  // Have the (FoundBytePos,FoundBitPos) make sense.\r
+  //\r
+  if (FoundBitPos > 7) {\r
+    FoundBytePos += 1;\r
+    FoundBitPos -= 8;\r
+  }\r
+  \r
+  //\r
+  // Set the memory as allocated\r
+  //\r
+  for (TempBytePos = FoundBytePos, Index = FoundBitPos, Count = 0; Count < NumberOfMemoryUnit; Count++) {\r
+\r
+    MemoryHeader->BitArrayPtr[TempBytePos] |= bit (Index);\r
+    Index++;\r
+    if (Index == 8) {\r
+      TempBytePos += 1;\r
+      Index = 0;\r
+    }\r
+  }\r
+\r
+  *Pool = MemoryHeader->MemoryBlockPtr + (FoundBytePos * 8 + FoundBitPos) * 32;\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+BOOLEAN\r
+IsMemoryBlockEmptied (\r
+  IN MEMORY_MANAGE_HEADER     *MemoryHeaderPtr\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Is Memory Block Emptied\r
+\r
+Arguments:\r
+\r
+  MemoryHeaderPtr - MEMORY_MANAGE_HEADER\r
+\r
+Returns:\r
+\r
+  TRUE    Empty\r
+  FALSE   Not Empty \r
+\r
+--*/\r
+{\r
+  UINTN Index;\r
+\r
+  for (Index = 0; Index < MemoryHeaderPtr->BitArraySizeInBytes; Index++) {\r
+    if (MemoryHeaderPtr->BitArrayPtr[Index] != 0) {\r
+      return FALSE;\r
+    }\r
+  }\r
+\r
+  return TRUE;\r
+}\r
+\r
+VOID\r
+DelinkMemoryBlock (\r
+  IN MEMORY_MANAGE_HEADER     *FirstMemoryHeader,\r
+  IN MEMORY_MANAGE_HEADER     *NeedFreeMemoryHeader\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Delink Memory Block\r
+\r
+Arguments:\r
+\r
+  FirstMemoryHeader     - MEMORY_MANAGE_HEADER\r
+  NeedFreeMemoryHeader  - MEMORY_MANAGE_HEADER\r
+\r
+Returns:\r
+\r
+  VOID\r
+\r
+--*/\r
+{\r
+  MEMORY_MANAGE_HEADER  *TempHeaderPtr;\r
+\r
+  if ((FirstMemoryHeader == NULL) || (NeedFreeMemoryHeader == NULL)) {\r
+    return ;\r
+  }\r
+\r
+  for (TempHeaderPtr = FirstMemoryHeader; TempHeaderPtr != NULL; TempHeaderPtr = TempHeaderPtr->Next) {\r
+\r
+    if (TempHeaderPtr->Next == NeedFreeMemoryHeader) {\r
+      //\r
+      // Link the before and after\r
+      //\r
+      TempHeaderPtr->Next = NeedFreeMemoryHeader->Next;\r
+      break;\r
+    }\r
+  }\r
+}\r
+\r
+EFI_STATUS\r
+InitialMemoryManagement (\r
+  IN USB2_HC_DEV     *HcDev\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Initialize Memory Management\r
+\r
+Arguments:\r
+\r
+  HcDev  - USB2_HC_DEV\r
+\r
+Returns:\r
+\r
+  EFI_SUCCESS        Success\r
+  EFI_DEVICE_ERROR   Fail\r
+  \r
+--*/\r
+{\r
+  EFI_STATUS            Status;\r
+  MEMORY_MANAGE_HEADER  *MemoryHeader;\r
+  UINTN                 MemPages;\r
+\r
+  MemPages  = NORMAL_MEMORY_BLOCK_UNIT_IN_PAGES;\r
+  Status    = CreateMemoryBlock (HcDev, &MemoryHeader, MemPages);\r
+  if (EFI_ERROR (Status)) {\r
+    Status = EFI_OUT_OF_RESOURCES;\r
+    goto exit;\r
+  }\r
+\r
+  HcDev->MemoryHeader = MemoryHeader;\r
+\r
+exit:\r
+  return Status;\r
+}\r
+\r
+EFI_STATUS\r
+DeinitialMemoryManagement (\r
+  IN USB2_HC_DEV     *HcDev\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Deinitialize Memory Management\r
+\r
+Arguments:\r
+\r
+  HcDev   - USB2_HC_DEV\r
+\r
+Returns:\r
+\r
+  EFI_SUCCESS        Success\r
+  EFI_DEVICE_ERROR   Fail\r
+  \r
+--*/\r
+{\r
+  MEMORY_MANAGE_HEADER  *TempHeaderPtr;\r
+\r
+  for (TempHeaderPtr = HcDev->MemoryHeader->Next; TempHeaderPtr != NULL;) {\r
+\r
+    DelinkMemoryBlock (HcDev->MemoryHeader, TempHeaderPtr);\r
+    //\r
+    // when the TempHeaderPtr is freed in FreeMemoryHeader(),\r
+    // the TempHeaderPtr is pointing to nonsense content.\r
+    //\r
+    FreeMemoryHeader (HcDev, TempHeaderPtr);\r
+    //\r
+    // reset the TempHeaderPtr,continue free another memory block.\r
+    //\r
+    TempHeaderPtr = HcDev->MemoryHeader->Next;\r
+  }\r
+\r
+  FreeMemoryHeader (HcDev, HcDev->MemoryHeader);\r
+\r
+  return EFI_SUCCESS;\r
+}\r
diff --git a/EdkModulePkg/Bus/Pci/Ehci/Dxe/EhciReg.c b/EdkModulePkg/Bus/Pci/Ehci/Dxe/EhciReg.c
new file mode 100644 (file)
index 0000000..9ce816e
--- /dev/null
@@ -0,0 +1,1539 @@
+/*++\r
+\r
+Copyright (c) 2006, Intel Corporation                                                     \r
+All rights reserved. This program and the accompanying materials                          \r
+are licensed and made available under the terms and conditions of the BSD License         \r
+which accompanies this distribution.  The full text of the license may be found at        \r
+http://opensource.org/licenses/bsd-license.php                                            \r
+                                                                                          \r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     \r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             \r
+\r
+Module Name:\r
+\r
+    Ehchlp.c\r
+    \r
+Abstract: \r
+    \r
+\r
+Revision History\r
+--*/\r
+\r
+#include "Ehci.h"\r
+\r
+\r
+EFI_STATUS\r
+ReadEhcCapabiltiyReg (\r
+  IN USB2_HC_DEV             *HcDev,\r
+  IN UINT32                  CapabiltiyRegAddr,\r
+  IN OUT UINT32              *Data\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Read  Ehc Capabitlity register\r
+  \r
+Arguments:\r
+\r
+  HcDev              - USB2_HC_DEV \r
+  CapabiltiyRegAddr  - Ehc Capability register address\r
+  Data               - A pointer to data read from register\r
+  \r
+Returns:\r
+\r
+  EFI_SUCCESS        Success\r
+  EFI_DEVICE_ERROR   Fail\r
+    \r
+--*/\r
+{\r
+  return HcDev->PciIo->Mem.Read (\r
+                             HcDev->PciIo,\r
+                             EfiPciIoWidthUint32,\r
+                             USB_BAR_INDEX,\r
+                             (UINT64) CapabiltiyRegAddr,\r
+                             1,\r
+                             Data\r
+                             );\r
+}\r
+\r
+EFI_STATUS\r
+ReadEhcOperationalReg (\r
+  IN USB2_HC_DEV             *HcDev,\r
+  IN UINT32                  OperationalRegAddr,\r
+  IN OUT UINT32              *Data\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Read  Ehc Operation register\r
+  \r
+Arguments:\r
+\r
+  HcDev                - USB2_HC_DEV \r
+  OperationalRegAddr   - Ehc Operation register address\r
+  Data                 - A pointer to data read from register\r
+  \r
+Returns:\r
+\r
+  EFI_SUCCESS        Success\r
+  EFI_DEVICE_ERROR   Fail\r
+    \r
+--*/\r
+{\r
+  ASSERT (mUsbCapabilityLen);\r
+  return HcDev->PciIo->Mem.Read (\r
+                             HcDev->PciIo,\r
+                             EfiPciIoWidthUint32,\r
+                             USB_BAR_INDEX,\r
+                             (UINT64) (OperationalRegAddr + mUsbCapabilityLen),\r
+                             1,\r
+                             Data\r
+                             );\r
+}\r
+\r
+EFI_STATUS\r
+WriteEhcOperationalReg (\r
+  IN USB2_HC_DEV             *HcDev,\r
+  IN UINT32                  OperationalRegAddr,\r
+  IN UINT32                  Data\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Write  Ehc Operation register\r
+  \r
+Arguments:\r
+\r
+  HcDev                - USB2_HC_DEV \r
+  OperationalRegAddr   - Ehc Operation register address\r
+  Data                 - 32bit write to register\r
+  \r
+Returns:\r
+\r
+  EFI_SUCCESS        Success\r
+  EFI_DEVICE_ERROR   Fail\r
+  \r
+--*/\r
+{\r
+  ASSERT (mUsbCapabilityLen);\r
+  return HcDev->PciIo->Mem.Write (\r
+                             HcDev->PciIo,\r
+                             EfiPciIoWidthUint32,\r
+                             USB_BAR_INDEX,\r
+                             (UINT64) (OperationalRegAddr + mUsbCapabilityLen),\r
+                             1,\r
+                             &Data\r
+                             );\r
+}\r
+\r
+EFI_STATUS\r
+GetCapabilityLen (\r
+  IN USB2_HC_DEV     *HcDev\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Get the length of capability register\r
+  \r
+Arguments:\r
+\r
+  HcDev - USB2_HC_DEV \r
+  \r
+Returns:\r
+\r
+  EFI_SUCCESS       Success\r
+  EFI_DEVICE_ERROR  Fail\r
+    \r
+--*/\r
+{\r
+  EFI_STATUS  Status;\r
+  UINT32      CapabilityLenAddr;\r
+\r
+  CapabilityLenAddr = CAPLENGTH;\r
+\r
+  Status = ReadEhcCapabiltiyReg (\r
+             HcDev,\r
+             CapabilityLenAddr,\r
+             &mUsbCapabilityLen\r
+             );\r
+  mUsbCapabilityLen = (UINT8) mUsbCapabilityLen;\r
+\r
+  return Status;\r
+}\r
+\r
+EFI_STATUS\r
+SetFrameListLen (\r
+  IN USB2_HC_DEV     *HcDev,\r
+  IN UINTN           Length\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Set the length of Frame List\r
+  \r
+Arguments:\r
+\r
+  HcDev    - USB2_HC_DEV \r
+  Length   - the required length of frame list\r
+  \r
+Returns:\r
+\r
+  EFI_SUCCESS            Success\r
+  EFI_INVALID_PARAMETER  Invalid parameter\r
+  EFI_DEVICE_ERROR       Fail\r
+  \r
+--*/\r
+{\r
+  EFI_STATUS  Status;\r
+  UINT32      UsbCommandAddr;\r
+  UINT32      UsbCommandReg;\r
+\r
+  UsbCommandAddr = USBCMD;\r
+\r
+  if (256 != Length && 512 != Length) {\r
+    Status = EFI_INVALID_PARAMETER;\r
+    goto exit;\r
+  }\r
+\r
+  Status = ReadEhcOperationalReg (\r
+             HcDev,\r
+             UsbCommandAddr,\r
+             &UsbCommandReg\r
+             );\r
+  if (EFI_ERROR (Status)) {\r
+    Status = EFI_DEVICE_ERROR;\r
+    goto exit;\r
+  }\r
+\r
+  if (256 == Length) {\r
+    UsbCommandReg |= USBCMD_FLS_256;\r
+  } else {\r
+    UsbCommandReg |= USBCMD_FLS_512;\r
+  }\r
+\r
+  Status = WriteEhcOperationalReg (\r
+             HcDev,\r
+             UsbCommandAddr,\r
+             UsbCommandReg\r
+             );\r
+  if (EFI_ERROR (Status)) {\r
+    Status = EFI_DEVICE_ERROR;\r
+  }\r
+\r
+exit:\r
+  return Status;\r
+}\r
+\r
+EFI_STATUS\r
+SetFrameListBaseAddr (\r
+  IN USB2_HC_DEV     *HcDev,\r
+  IN UINT32          FrameBuffer\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Set base address of frame list first entry\r
+  \r
+Arguments:\r
+\r
+  HcDev        - USB2_HC_DEV \r
+  FrameBuffer  - base address of first entry of frame list\r
+  \r
+Returns:\r
+  \r
+--*/\r
+{\r
+  EFI_STATUS  Status;\r
+  UINT32      PeriodicListBaseAddr;\r
+  UINT32      PeriodicListBaseReg;\r
+\r
+  Status                = EFI_SUCCESS;\r
+  PeriodicListBaseAddr  = PERIODICLISTBASE;\r
+  PeriodicListBaseReg   = FrameBuffer & 0xfffff000;\r
+\r
+  if (IsEhcHalted (HcDev)) {\r
+\r
+    Status = WriteEhcOperationalReg (\r
+               HcDev,\r
+               PeriodicListBaseAddr,\r
+               PeriodicListBaseReg\r
+               );\r
+    if (EFI_ERROR (Status)) {\r
+      Status = EFI_DEVICE_ERROR;\r
+      goto exit;\r
+    }\r
+\r
+  }\r
+\r
+exit:\r
+  return Status;\r
+}\r
+\r
+EFI_STATUS\r
+SetAsyncListAddr (\r
+  IN USB2_HC_DEV        *HcDev,\r
+  IN EHCI_QH_ENTITY     *QhPtr\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Set address of first Async schedule Qh\r
+  \r
+Arguments:\r
+\r
+  HcDev   - USB2_HC_DEV \r
+  QhPtr   - A pointer to first Qh in the Async schedule\r
+  \r
+Returns:\r
+\r
+  EFI_SUCCESS       Success\r
+  EFI_DEVICE_ERROR  Fail\r
+    \r
+--*/\r
+{\r
+  EFI_STATUS  Status;\r
+  UINT32      AsyncListAddr;\r
+  UINT32      AsyncListReg;\r
+\r
+  AsyncListAddr = ASYNCLISTADDR;\r
+  AsyncListReg  = (UINT32) GET_0B_TO_31B (&(QhPtr->Qh));\r
+\r
+  Status = WriteEhcOperationalReg (\r
+             HcDev,\r
+             AsyncListAddr,\r
+             AsyncListReg\r
+             );\r
+\r
+  return Status;\r
+}\r
+\r
+EFI_STATUS\r
+SetCtrlDataStructSeg (\r
+  IN USB2_HC_DEV     *HcDev\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Set register of control and data structure segment\r
+  \r
+Arguments:\r
+\r
+  HcDev  - USB2_HC_DEV \r
+  \r
+Returns:\r
+\r
+  EFI_SUCCESS       Success\r
+  EFI_DEVICE_ERROR  Fail\r
+  \r
+\r
+--*/\r
+{\r
+  EFI_STATUS  Status;\r
+  UINT32      CtrlDsSegmentAddr;\r
+  UINT32      CtrlDsSegmentReg;\r
+\r
+  CtrlDsSegmentAddr = CTRLDSSGMENT;\r
+  CtrlDsSegmentReg  = HcDev->High32BitAddr;\r
+\r
+  Status = WriteEhcOperationalReg (\r
+             HcDev,\r
+             CtrlDsSegmentAddr,\r
+             CtrlDsSegmentReg\r
+             );\r
+\r
+  return Status;\r
+}\r
+\r
+EFI_STATUS\r
+SetPortRoutingEhc (\r
+  IN USB2_HC_DEV     *HcDev\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Set Ehc port routing bit\r
+  \r
+Arguments:\r
+\r
+  HcDev - USB2_HC_DEV \r
+  \r
+Returns:\r
+\r
+  EFI_SUCCESS       Success\r
+  EFI_DEVICE_ERROR  Fail\r
+    \r
+--*/\r
+{\r
+  EFI_STATUS  Status;\r
+  UINT32      ConfigFlagAddr;\r
+  UINT32      ConfigFlagReg;\r
+\r
+  ConfigFlagAddr = CONFIGFLAG;\r
+\r
+  Status = ReadEhcOperationalReg (\r
+             HcDev,\r
+             ConfigFlagAddr,\r
+             &ConfigFlagReg\r
+             );\r
+  if (EFI_ERROR (Status)) {\r
+    Status = EFI_DEVICE_ERROR;\r
+    goto exit;\r
+  }\r
+\r
+  ConfigFlagReg |= CONFIGFLAG_CF;\r
+  Status = WriteEhcOperationalReg (\r
+             HcDev,\r
+             ConfigFlagAddr,\r
+             ConfigFlagReg\r
+             );\r
+  if (EFI_ERROR (Status)) {\r
+    Status = EFI_DEVICE_ERROR;\r
+  }\r
+\r
+exit:\r
+  return Status;\r
+}\r
+\r
+EFI_STATUS\r
+SetEhcDoorbell (\r
+  IN  USB2_HC_DEV     *HcDev\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Set Ehc door bell bit\r
+  \r
+Arguments:\r
+\r
+  HcDev - USB2_HC_DEV \r
+  \r
+Returns:\r
+\r
+  EFI_SUCCESS       Success\r
+  EFI_DEVICE_ERROR  Fail\r
+     \r
+--*/\r
+{\r
+  EFI_STATUS  Status;\r
+  UINT32      UsbCommandAddr;\r
+  UINT32      UsbCommandReg;\r
+\r
+  UsbCommandAddr = USBCMD;\r
+\r
+  Status = ReadEhcOperationalReg (\r
+             HcDev,\r
+             UsbCommandAddr,\r
+             &UsbCommandReg\r
+             );\r
+  if (EFI_ERROR (Status)) {\r
+    Status = EFI_DEVICE_ERROR;\r
+    goto exit;\r
+  }\r
+\r
+  UsbCommandReg |= USBCMD_IAAD;\r
+  Status = WriteEhcOperationalReg (\r
+             HcDev,\r
+             UsbCommandAddr,\r
+             UsbCommandReg\r
+             );\r
+  if (EFI_ERROR (Status)) {\r
+    Status = EFI_DEVICE_ERROR;\r
+  }\r
+\r
+exit:\r
+  return Status;\r
+}\r
+\r
+EFI_STATUS\r
+ClearEhcAllStatus (\r
+  IN  USB2_HC_DEV     *HcDev\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Clear Ehc all status bits\r
+  \r
+Arguments:\r
+\r
+  HcDev - USB2_HC_DEV \r
+  \r
+Returns:\r
+\r
+  EFI_SUCCESS       Success\r
+  EFI_DEVICE_ERROR  Fail\r
+     \r
+--*/\r
+{\r
+  UINT32  UsbStatusAddr;\r
+\r
+  UsbStatusAddr = USBSTS;\r
+\r
+  return WriteEhcOperationalReg (\r
+           HcDev,\r
+           UsbStatusAddr,\r
+           0x003F\r
+           );\r
+}\r
+\r
+EFI_STATUS\r
+EnablePeriodicSchedule (\r
+  IN  USB2_HC_DEV     *HcDev\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Enable periodic schedule\r
+  \r
+Arguments:\r
+\r
+  HcDev - USB2_HC_DEV \r
+  \r
+Returns:\r
+\r
+  EFI_SUCCESS       Success\r
+  EFI_DEVICE_ERROR  Fail\r
+   \r
+--*/\r
+{\r
+  EFI_STATUS  Status;\r
+  UINT32      UsbCommandAddr;\r
+  UINT32      UsbCommandReg;\r
+\r
+  UsbCommandAddr = USBCMD;\r
+\r
+  Status = ReadEhcOperationalReg (\r
+             HcDev,\r
+             UsbCommandAddr,\r
+             &UsbCommandReg\r
+             );\r
+  if (EFI_ERROR (Status)) {\r
+    Status = EFI_DEVICE_ERROR;\r
+    goto exit;\r
+  }\r
+\r
+  UsbCommandReg |= USBCMD_PSE;\r
+  Status = WriteEhcOperationalReg (\r
+             HcDev,\r
+             UsbCommandAddr,\r
+             UsbCommandReg\r
+             );\r
+  if (EFI_ERROR (Status)) {\r
+    Status = EFI_DEVICE_ERROR;\r
+  }\r
+\r
+exit:\r
+  return Status;\r
+}\r
+\r
+EFI_STATUS\r
+DisablePeriodicSchedule (\r
+  IN  USB2_HC_DEV     *HcDev\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Disable periodic schedule\r
+  \r
+Arguments:\r
+\r
+  HcDev - USB2_HC_DEV \r
+  \r
+Returns:\r
+\r
+  EFI_SUCCESS       Success\r
+  EFI_DEVICE_ERROR  Fail\r
+   \r
+--*/\r
+{\r
+  EFI_STATUS  Status;\r
+  UINT32      UsbCommandAddr;\r
+  UINT32      UsbCommandReg;\r
+\r
+  UsbCommandAddr = USBCMD;\r
+\r
+  Status = ReadEhcOperationalReg (\r
+             HcDev,\r
+             UsbCommandAddr,\r
+             &UsbCommandReg\r
+             );\r
+  if (EFI_ERROR (Status)) {\r
+    return EFI_DEVICE_ERROR;\r
+  }\r
+\r
+  UsbCommandReg &= ~USBCMD_PSE;\r
+  Status = WriteEhcOperationalReg (\r
+             HcDev,\r
+             UsbCommandAddr,\r
+             UsbCommandReg\r
+             );\r
+  if (EFI_ERROR (Status)) {\r
+    return EFI_DEVICE_ERROR;\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+EFI_STATUS\r
+EnableAsynchronousSchedule (\r
+  IN  USB2_HC_DEV     *HcDev\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Enable asynchrounous schedule\r
+  \r
+Arguments:\r
+\r
+  HcDev - USB2_HC_DEV \r
+  \r
+Returns:\r
+\r
+  EFI_SUCCESS       Success\r
+  EFI_DEVICE_ERROR  Fail\r
+    \r
+--*/\r
+{\r
+  EFI_STATUS  Status;\r
+  UINT32      UsbCommandAddr;\r
+  UINT32      UsbCommandReg;\r
+\r
+  UsbCommandAddr = USBCMD;\r
+\r
+  Status = ReadEhcOperationalReg (\r
+             HcDev,\r
+             UsbCommandAddr,\r
+             &UsbCommandReg\r
+             );\r
+  if (EFI_ERROR (Status)) {\r
+    Status = EFI_DEVICE_ERROR;\r
+    goto exit;\r
+  }\r
+\r
+  UsbCommandReg |= USBCMD_ASE;\r
+  Status = WriteEhcOperationalReg (\r
+             HcDev,\r
+             UsbCommandAddr,\r
+             UsbCommandReg\r
+             );\r
+  if (EFI_ERROR (Status)) {\r
+    Status = EFI_DEVICE_ERROR;\r
+  }\r
+\r
+exit:\r
+  return Status;\r
+}\r
+\r
+EFI_STATUS\r
+DisableAsynchronousSchedule (\r
+  IN  USB2_HC_DEV     *HcDev\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Disable asynchrounous schedule\r
+  \r
+Arguments:\r
+\r
+  HcDev - USB2_HC_DEV \r
+  \r
+Returns:\r
+\r
+  EFI_SUCCESS       Success\r
+  EFI_DEVICE_ERROR  Fail\r
+   \r
+--*/\r
+{\r
+  EFI_STATUS  Status;\r
+  UINT32      UsbCommandAddr;\r
+  UINT32      UsbCommandReg;\r
+\r
+  UsbCommandAddr = USBCMD;\r
+\r
+  Status = ReadEhcOperationalReg (\r
+             HcDev,\r
+             UsbCommandAddr,\r
+             &UsbCommandReg\r
+             );\r
+  if (EFI_ERROR (Status)) {\r
+    return EFI_DEVICE_ERROR;\r
+  }\r
+\r
+  UsbCommandReg &= ~USBCMD_ASE;\r
+  Status = WriteEhcOperationalReg (\r
+             HcDev,\r
+             UsbCommandAddr,\r
+             UsbCommandReg\r
+             );\r
+  if (EFI_ERROR (Status)) {\r
+    return EFI_DEVICE_ERROR;\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+EFI_STATUS\r
+ResetEhc (\r
+  IN  USB2_HC_DEV     *HcDev\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Reset Ehc\r
+  \r
+Arguments:\r
+\r
+  HcDev - USB2_HC_DEV \r
+  \r
+Returns:\r
+\r
+  EFI_SUCCESS       Success\r
+  EFI_DEVICE_ERROR  Fail\r
+   \r
+--*/\r
+{\r
+  EFI_STATUS  Status;\r
+  UINT32      UsbCommandAddr;\r
+  UINT32      UsbCommandReg;\r
+\r
+  UsbCommandAddr = USBCMD;\r
+\r
+  Status = ReadEhcOperationalReg (\r
+             HcDev,\r
+             UsbCommandAddr,\r
+             &UsbCommandReg\r
+             );\r
+  if (EFI_ERROR (Status)) {\r
+    Status = EFI_DEVICE_ERROR;\r
+    goto exit;\r
+  }\r
+\r
+  UsbCommandReg |= USBCMD_HCRESET;\r
+  Status = WriteEhcOperationalReg (\r
+             HcDev,\r
+             UsbCommandAddr,\r
+             UsbCommandReg\r
+             );\r
+  if (EFI_ERROR (Status)) {\r
+    Status = EFI_DEVICE_ERROR;\r
+  }\r
+\r
+exit:\r
+  return Status;\r
+}\r
+\r
+EFI_STATUS\r
+StartScheduleExecution (\r
+  IN  USB2_HC_DEV     *HcDev\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Start Ehc schedule execution\r
+  \r
+Arguments:\r
+\r
+  HcDev - USB2_HC_DEV \r
+  \r
+Returns:\r
+\r
+  EFI_SUCCESS       Success\r
+  EFI_DEVICE_ERROR  Fail\r
+   \r
+--*/\r
+{\r
+  EFI_STATUS  Status;\r
+  UINT32      UsbCommandAddr;\r
+  UINT32      UsbCommandReg;\r
+\r
+  UsbCommandAddr = USBCMD;\r
+\r
+  Status = ReadEhcOperationalReg (\r
+             HcDev,\r
+             UsbCommandAddr,\r
+             &UsbCommandReg\r
+             );\r
+  if (EFI_ERROR (Status)) {\r
+    Status = EFI_DEVICE_ERROR;\r
+    goto exit;\r
+  }\r
+\r
+  UsbCommandReg |= USBCMD_RS;\r
+  Status = WriteEhcOperationalReg (\r
+             HcDev,\r
+             UsbCommandAddr,\r
+             UsbCommandReg\r
+             );\r
+  if (EFI_ERROR (Status)) {\r
+    Status = EFI_DEVICE_ERROR;\r
+  }\r
+\r
+exit:\r
+  return Status;\r
+}\r
+\r
+BOOLEAN\r
+IsFrameListProgrammable (\r
+  IN  USB2_HC_DEV     *HcDev\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Whether frame list is programmable\r
+  \r
+Arguments:\r
+\r
+  HcDev - USB2_HC_DEV \r
+  \r
+Returns:\r
+\r
+  TRUE   Programmable\r
+  FALSE  Unprogrammable\r
+  \r
+--*/\r
+{\r
+  BOOLEAN Value;\r
+  UINT32  HcCapParamsAddr;\r
+  UINT32  HcCapParamsReg;\r
+\r
+  HcCapParamsAddr = HCCPARAMS;\r
+\r
+  ReadEhcOperationalReg (\r
+    HcDev,\r
+    HcCapParamsAddr,\r
+    &HcCapParamsReg\r
+    );\r
+\r
+  if (HcCapParamsReg & HCCP_PFLF) {\r
+    Value = TRUE;\r
+  } else {\r
+    Value = FALSE;\r
+  }\r
+\r
+  return Value;\r
+}\r
+\r
+BOOLEAN\r
+IsPeriodicScheduleEnabled (\r
+  IN  USB2_HC_DEV     *HcDev\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Whether periodic schedule is enabled\r
+  \r
+Arguments:\r
+\r
+  HcDev - USB2_HC_DEV \r
+  \r
+Returns:\r
+\r
+  TRUE    Enabled\r
+  FALSE   Disabled\r
+  \r
+--*/\r
+{\r
+  BOOLEAN Value;\r
+  UINT32  UsbStatusAddr;\r
+  UINT32  UsbStatusReg;\r
+\r
+  UsbStatusAddr = USBSTS;\r
+\r
+  ReadEhcOperationalReg (\r
+    HcDev,\r
+    UsbStatusAddr,\r
+    &UsbStatusReg\r
+    );\r
+\r
+  if (UsbStatusReg & USBSTS_PSS) {\r
+    Value = TRUE;\r
+  } else {\r
+    Value = FALSE;\r
+  }\r
+\r
+  return Value;\r
+}\r
+\r
+BOOLEAN\r
+IsAsyncScheduleEnabled (\r
+  IN  USB2_HC_DEV     *HcDev\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Whether asynchronous schedule is enabled\r
+  \r
+Arguments:\r
+\r
+  HcDev - USB2_HC_DEV \r
+  \r
+Returns:\r
+\r
+  TRUE   Enabled\r
+  FALSE  Disabled\r
+  \r
+--*/\r
+{\r
+  BOOLEAN Value;\r
+  UINT32  UsbStatusAddr;\r
+  UINT32  UsbStatusReg;\r
+\r
+  UsbStatusAddr = USBSTS;\r
+\r
+  ReadEhcOperationalReg (\r
+    HcDev,\r
+    UsbStatusAddr,\r
+    &UsbStatusReg\r
+    );\r
+\r
+  if (UsbStatusReg & USBSTS_ASS) {\r
+    Value = TRUE;\r
+  } else {\r
+    Value = FALSE;\r
+  }\r
+\r
+  return Value;\r
+}\r
+\r
+BOOLEAN\r
+IsEhcPortEnabled (\r
+  IN  USB2_HC_DEV     *HcDev,\r
+  IN  UINT8           PortNum\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Whether port is enabled\r
+  \r
+Arguments:\r
+\r
+  HcDev - USB2_HC_DEV \r
+  \r
+Returns:\r
+\r
+  TRUE   Enabled\r
+  FALSE  Disabled\r
+  \r
+--*/\r
+{\r
+  UINT32  PortStatusControlAddr;\r
+  UINT32  PortStatusControlReg;\r
+\r
+  PortStatusControlAddr = (UINT32) (PORTSC + (4 * PortNum));\r
+\r
+  ReadEhcOperationalReg (\r
+    HcDev,\r
+    PortStatusControlAddr,\r
+    &PortStatusControlReg\r
+    );\r
+\r
+  return ((PortStatusControlReg & PORTSC_PED) ? TRUE : FALSE);\r
+}\r
+\r
+BOOLEAN\r
+IsEhcReseted (\r
+  IN  USB2_HC_DEV     *HcDev\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Whether Ehc is reseted\r
+  \r
+Arguments:\r
+\r
+  HcDev - USB2_HC_DEV \r
+  \r
+Returns:\r
+\r
+  TRUE   Reseted\r
+  FALSE  Unreseted\r
+  \r
+--*/\r
+{\r
+  BOOLEAN Value;\r
+  UINT32  UsbCommandAddr;\r
+  UINT32  UsbCommandReg;\r
+\r
+  UsbCommandAddr = USBCMD;\r
+\r
+  ReadEhcOperationalReg (\r
+    HcDev,\r
+    UsbCommandAddr,\r
+    &UsbCommandReg\r
+    );\r
+\r
+  if (UsbCommandReg & USBCMD_HCRESET) {\r
+    Value = FALSE;\r
+  } else {\r
+    Value = TRUE;\r
+  }\r
+\r
+  return Value;\r
+}\r
+\r
+BOOLEAN\r
+IsEhcHalted (\r
+  IN  USB2_HC_DEV     *HcDev\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Whether Ehc is halted\r
+  \r
+Arguments:\r
+\r
+  HcDev - USB2_HC_DEV \r
+  \r
+Returns:\r
+\r
+  TRUE   Halted\r
+  FALSE  Not halted\r
+  \r
+--*/\r
+{\r
+  BOOLEAN Value;\r
+  UINT32  UsbStatusAddr;\r
+  UINT32  UsbStatusReg;\r
+\r
+  UsbStatusAddr = USBSTS;\r
+\r
+  ReadEhcOperationalReg (\r
+    HcDev,\r
+    UsbStatusAddr,\r
+    &UsbStatusReg\r
+    );\r
+\r
+  if (UsbStatusReg & USBSTS_HCH) {\r
+    Value = TRUE;\r
+  } else {\r
+    Value = FALSE;\r
+  }\r
+\r
+  return Value;\r
+}\r
+\r
+BOOLEAN\r
+IsEhcSysError (\r
+  IN  USB2_HC_DEV     *HcDev\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Whether Ehc is system error\r
+  \r
+Arguments:\r
+\r
+  HcDev - USB2_HC_DEV \r
+  \r
+Returns:\r
+\r
+  TRUE   System error\r
+  FALSE  No system error\r
+  \r
+--*/\r
+{\r
+  BOOLEAN Value;\r
+  UINT32  UsbStatusAddr;\r
+  UINT32  UsbStatusReg;\r
+\r
+  UsbStatusAddr = USBSTS;\r
+\r
+  ReadEhcOperationalReg (\r
+    HcDev,\r
+    UsbStatusAddr,\r
+    &UsbStatusReg\r
+    );\r
+\r
+  if (UsbStatusReg & USBSTS_HSE) {\r
+    Value = TRUE;\r
+  } else {\r
+    Value = FALSE;\r
+  }\r
+\r
+  return Value;\r
+}\r
+\r
+BOOLEAN\r
+IsHighSpeedDevice (\r
+  IN EFI_USB2_HC_PROTOCOL *This,\r
+  IN UINT8                PortNum \r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Whether high speed device attached\r
+  \r
+Arguments:\r
+\r
+  HcDev - USB2_HC_DEV \r
+  \r
+Returns:\r
+\r
+  TRUE   High speed\r
+  FALSE  Full speed\r
+  \r
+--*/\r
+{\r
+  USB2_HC_DEV          *HcDev;\r
+  UINT32               PortStatusControlAddr;\r
+  UINT32               PortStatusControlReg;\r
+  \r
+  HcDev = USB2_HC_DEV_FROM_THIS (This);\r
+  PortStatusControlAddr = (UINT32) (PORTSC + (4 * PortNum));\r
+\r
+  //\r
+  // Set port reset bit\r
+  //\r
+  ReadEhcOperationalReg (\r
+    HcDev,\r
+    PortStatusControlAddr,\r
+    &PortStatusControlReg\r
+    );\r
+  //\r
+  // Make sure Host Controller not halt before reset it\r
+  //\r
+  if (IsEhcHalted (HcDev)) {\r
+    StartScheduleExecution (HcDev);\r
+    WaitForEhcNotHalt (HcDev, EHCI_GENERIC_TIMEOUT);\r
+  }\r
+  PortStatusControlReg &= 0xffffffd5;\r
+  PortStatusControlReg |= PORTSC_PR;\r
+  //\r
+  // Set one to PortReset bit must also set zero to PortEnable bit\r
+  //\r
+  PortStatusControlReg &= ~PORTSC_PED;\r
+  WriteEhcOperationalReg (\r
+    HcDev,\r
+    PortStatusControlAddr,\r
+    PortStatusControlReg\r
+    );\r
+\r
+  //\r
+  // Set Port reset recovery time\r
+  //\r
+  gBS->Stall (EHCI_SET_PORT_RESET_RECOVERY_TIME);\r
+\r
+  //\r
+  // Clear port reset bit\r
+  //\r
+  ReadEhcOperationalReg (\r
+    HcDev,\r
+    PortStatusControlAddr,\r
+    &PortStatusControlReg\r
+    );\r
+  PortStatusControlReg &= 0xffffffd5;\r
+  PortStatusControlReg &= ~PORTSC_PR;\r
+  WriteEhcOperationalReg (\r
+    HcDev,\r
+    PortStatusControlAddr,\r
+    PortStatusControlReg\r
+    );\r
+\r
+  //\r
+  // Clear port reset recovery time\r
+  //\r
+  gBS->Stall (EHCI_CLEAR_PORT_RESET_RECOVERY_TIME);\r
+\r
+  return (IsEhcPortEnabled (HcDev, PortNum) ? TRUE : FALSE);\r
+}\r
+\r
+EFI_STATUS\r
+WaitForEhcReset (\r
+  IN USB2_HC_DEV             *HcDev,\r
+  IN UINTN                   Timeout\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  wait for Ehc reset or timeout\r
+  \r
+Arguments:\r
+\r
+  HcDev   - USB2_HC_DEV \r
+  Timeout - timeout threshold\r
+  \r
+Returns:\r
+\r
+  EFI_SUCCESS    Success\r
+  EFI_TIMEOUT    Timeout\r
+  \r
+--*/\r
+{\r
+  EFI_STATUS  Status;\r
+  UINTN       Delay;\r
+\r
+  //\r
+  // Timeout is in US unit\r
+  //\r
+  Delay = (Timeout / 50) + 1;\r
+  do {\r
+\r
+    if (IsEhcReseted (HcDev)) {\r
+      Status = EFI_SUCCESS;\r
+      goto exit;\r
+    }\r
+    gBS->Stall (EHCI_GENERIC_RECOVERY_TIME);\r
+\r
+  } while (Delay--);\r
+\r
+  Status = EFI_TIMEOUT;\r
+\r
+exit:\r
+  return Status;\r
+}\r
+\r
+EFI_STATUS\r
+WaitForEhcHalt (\r
+  IN USB2_HC_DEV             *HcDev,\r
+  IN UINTN                   Timeout\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  wait for Ehc halt or timeout\r
+  \r
+Arguments:\r
+\r
+  HcDev   - USB2_HC_DEV \r
+  Timeout - timeout threshold\r
+  \r
+Returns:\r
+\r
+  EFI_SUCCESS    Success\r
+  EFI_TIMEOUT    Timeout\r
+  \r
+--*/\r
+{\r
+  EFI_STATUS  Status;\r
+  UINTN       Delay;\r
+\r
+  //\r
+  // Timeout is in US unit\r
+  //\r
+  Delay = (Timeout / 50) + 1;\r
+  do {\r
+\r
+    if (IsEhcHalted (HcDev)) {\r
+      Status = EFI_SUCCESS;\r
+      goto exit;\r
+    }\r
+    gBS->Stall (EHCI_GENERIC_RECOVERY_TIME);\r
+\r
+  } while (Delay--);\r
+\r
+  Status = EFI_TIMEOUT;\r
+\r
+exit:\r
+  return Status;\r
+}\r
+\r
+EFI_STATUS\r
+WaitForEhcNotHalt (\r
+  IN USB2_HC_DEV             *HcDev,\r
+  IN UINTN                   Timeout\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  wait for Ehc not halt or timeout\r
+  \r
+Arguments:\r
+\r
+  HcDev   - USB2_HC_DEV \r
+  Timeout - timeout threshold\r
+  \r
+Returns:\r
+\r
+  EFI_SUCCESS    Success\r
+  EFI_TIMEOUT    Timeout\r
+  \r
+--*/\r
+{\r
+  EFI_STATUS  Status;\r
+  UINTN       Delay;\r
+\r
+  //\r
+  // Timeout is in US unit\r
+  //\r
+  Delay = (Timeout / 50) + 1;\r
+  do {\r
+\r
+    if (!IsEhcHalted (HcDev)) {\r
+      Status = EFI_SUCCESS;\r
+      goto exit;\r
+    }\r
+    gBS->Stall (EHCI_GENERIC_RECOVERY_TIME);\r
+\r
+  } while (Delay--);\r
+\r
+  Status = EFI_TIMEOUT;\r
+\r
+exit:\r
+  return Status;\r
+}\r
+\r
+EFI_STATUS\r
+WaitForAsyncScheduleEnable (\r
+  IN  USB2_HC_DEV            *HcDev,\r
+  IN UINTN                   Timeout\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Wait for Ehc asynchronous schedule enable or timeout\r
+  \r
+Arguments:\r
+\r
+  HcDev   - USB2_HC_DEV \r
+  Timeout - timeout threshold\r
+  \r
+Returns:\r
+\r
+  EFI_SUCCESS    Success\r
+  EFI_TIMEOUT    Timeout\r
+  \r
+--*/\r
+{\r
+  EFI_STATUS  Status;\r
+  UINTN       Delay;\r
+\r
+  //\r
+  // Timeout is in US unit\r
+  //\r
+  Delay = (Timeout / 50) + 1;\r
+  do {\r
+\r
+    if (IsAsyncScheduleEnabled (HcDev)) {\r
+      Status = EFI_SUCCESS;\r
+      goto exit;\r
+    }\r
+    gBS->Stall (EHCI_GENERIC_RECOVERY_TIME);\r
+\r
+  } while (Delay--);\r
+\r
+  Status = EFI_TIMEOUT;\r
+\r
+exit:\r
+  return Status;\r
+}\r
+\r
+EFI_STATUS\r
+WaitForAsyncScheduleDisable (\r
+  IN USB2_HC_DEV             *HcDev,\r
+  IN UINTN                   Timeout\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Wait for Ehc asynchronous schedule disable or timeout\r
+  \r
+Arguments:\r
+\r
+  HcDev   - USB2_HC_DEV \r
+  Timeout - timeout threshold\r
+  \r
+Returns:\r
+\r
+  EFI_SUCCESS    Success\r
+  EFI_TIMEOUT    Timeout\r
+  \r
+--*/\r
+{\r
+  EFI_STATUS  Status;\r
+  UINTN       Delay;\r
+\r
+  //\r
+  // Timeout is in US unit\r
+  //\r
+  Delay = (Timeout / 50) + 1;\r
+  do {\r
+\r
+    if (!IsAsyncScheduleEnabled (HcDev)) {\r
+      Status = EFI_SUCCESS;\r
+      goto exit;\r
+    }\r
+    gBS->Stall (EHCI_GENERIC_RECOVERY_TIME);\r
+\r
+  } while (Delay--);\r
+\r
+  Status = EFI_TIMEOUT;\r
+\r
+exit:\r
+  return Status;\r
+}\r
+\r
+EFI_STATUS\r
+WaitForPeriodicScheduleEnable (\r
+  IN USB2_HC_DEV             *HcDev,\r
+  IN UINTN                   Timeout\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Wait for Ehc periodic schedule enable or timeout\r
+  \r
+Arguments:\r
+\r
+  HcDev   - USB2_HC_DEV \r
+  Timeout - timeout threshold\r
+  \r
+Returns:\r
+\r
+  EFI_SUCCESS    Success\r
+  EFI_TIMEOUT    Timeout\r
+  \r
+--*/\r
+{\r
+  EFI_STATUS  Status;\r
+  UINTN       Delay;\r
+\r
+  //\r
+  // Timeout is in US unit\r
+  //\r
+  Delay = (Timeout / 50) + 1;\r
+  do {\r
+\r
+    if (IsPeriodicScheduleEnabled (HcDev)) {\r
+      Status = EFI_SUCCESS;\r
+      goto exit;\r
+    }\r
+    gBS->Stall (EHCI_GENERIC_RECOVERY_TIME);\r
+\r
+  } while (Delay--);\r
+\r
+  Status = EFI_TIMEOUT;\r
+\r
+exit:\r
+  return Status;\r
+}\r
+\r
+EFI_STATUS\r
+WaitForPeriodicScheduleDisable (\r
+  IN USB2_HC_DEV             *HcDev,\r
+  IN UINTN                   Timeout\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Wait for periodic schedule disable or timeout\r
+  \r
+Arguments:\r
+\r
+  HcDev   - USB2_HC_DEV \r
+  Timeout - timeout threshold\r
+  \r
+Returns:\r
+\r
+  EFI_SUCCESS    Success\r
+  EFI_TIMEOUT    Timeout\r
+  \r
+--*/\r
+{\r
+  EFI_STATUS  Status;\r
+  UINTN       Delay;\r
+\r
+  //\r
+  // Timeout is in US unit\r
+  //\r
+  Delay = (Timeout / 50) + 1;\r
+  do {\r
+\r
+    if (!IsPeriodicScheduleEnabled (HcDev)) {\r
+      Status = EFI_SUCCESS;\r
+      goto exit;\r
+    }\r
+    gBS->Stall (EHCI_GENERIC_RECOVERY_TIME);\r
+\r
+  } while (Delay--);\r
+\r
+  Status = EFI_TIMEOUT;\r
+\r
+exit:\r
+  return Status;\r
+}\r
+\r
+EFI_STATUS\r
+WaitForEhcDoorbell (\r
+  IN USB2_HC_DEV             *HcDev,\r
+  IN UINTN                   Timeout\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Wait for periodic schedule disable or timeout\r
+\r
+Arguments:\r
+\r
+  HcDev   - USB2_HC_DEV \r
+  Timeout - timeout threshold\r
+\r
+Returns:\r
+\r
+  EFI_SUCCESS    Success\r
+  EFI_TIMEOUT    Timeout\r
+  \r
+--*/\r
+{\r
+  EFI_STATUS  Status;\r
+  UINT32      UsbCommandAddr;\r
+  UINT32      UsbCommandReg;\r
+  UINTN       Delay;\r
+\r
+  UsbCommandAddr  = USBCMD;\r
+  Delay           = (Timeout / 50) + 1;\r
+  \r
+  do {\r
+    Status = ReadEhcOperationalReg (\r
+               HcDev,\r
+               UsbCommandAddr,\r
+               &UsbCommandReg\r
+               );\r
+    if (EFI_ERROR (Status)) {\r
+      Status = EFI_DEVICE_ERROR;\r
+      goto exit;\r
+    }\r
+    if (!(UsbCommandReg & USBCMD_IAAD)) {\r
+      break;\r
+    }\r
+       \r
+  } while (--Delay);\r
+\r
+  if (0 == Delay) {\r
+    Status = EFI_TIMEOUT;\r
+  }\r
+\r
+exit:\r
+  return Status;\r
+}\r
diff --git a/EdkModulePkg/Bus/Pci/Ehci/Dxe/EhciSched.c b/EdkModulePkg/Bus/Pci/Ehci/Dxe/EhciSched.c
new file mode 100644 (file)
index 0000000..3dc1ff7
--- /dev/null
@@ -0,0 +1,3072 @@
+/*++\r
+\r
+Copyright (c) 2006, Intel Corporation                                                     \r
+All rights reserved. This program and the accompanying materials                          \r
+are licensed and made available under the terms and conditions of the BSD License         \r
+which accompanies this distribution.  The full text of the license may be found at        \r
+http://opensource.org/licenses/bsd-license.php                                            \r
+                                                                                          \r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     \r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             \r
+\r
+Module Name:\r
+\r
+    EhciSched.c\r
+    \r
+Abstract: \r
+    \r
+\r
+Revision History\r
+--*/\r
+\r
+#include "Ehci.h"\r
+\r
+EFI_STATUS\r
+InitialPeriodicFrameList (\r
+  IN  USB2_HC_DEV     *HcDev,\r
+  IN  UINTN           Length\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Initialize Periodic Schedule Frame List\r
+\r
+Arguments:\r
+\r
+  HcDev   - USB2_HC_DEV\r
+  Length  - Frame List Length\r
+  \r
+Returns:\r
+\r
+  EFI_SUCCESS        Success\r
+  EFI_DEVICE_ERROR   Fail\r
+\r
+--*/\r
+{\r
+  EFI_STATUS            Status;\r
+  VOID                  *CommonBuffer;\r
+  EFI_PHYSICAL_ADDRESS  FrameBuffer;\r
+  VOID                  *Map;\r
+  UINTN                 BufferSizeInPages;\r
+  UINTN                 BufferSizeInBytes;\r
+  UINTN                 FrameIndex;\r
+  FRAME_LIST_ENTRY      *FrameEntryPtr;\r
+  \r
+  //\r
+  // The Frame List is a common buffer that will be\r
+  // accessed by both the cpu and the usb bus master\r
+  // at the same time.\r
+  // The Frame List ocupies 4K bytes,\r
+  // and must be aligned on 4-Kbyte boundaries.\r
+  //\r
+  if (EHCI_MAX_FRAME_LIST_LENGTH != Length && IsFrameListProgrammable (HcDev)) {\r
+    Status = SetFrameListLen (HcDev, Length);\r
+    if (EFI_ERROR (Status)) {\r
+      Status = EFI_INVALID_PARAMETER;\r
+      goto exit;\r
+    }\r
+  }\r
+\r
+  BufferSizeInBytes = EFI_PAGE_SIZE;\r
+  BufferSizeInPages = EFI_SIZE_TO_PAGES (BufferSizeInBytes);\r
+  Status = HcDev->PciIo->AllocateBuffer (\r
+                          HcDev->PciIo,\r
+                          AllocateAnyPages,\r
+                          EfiBootServicesData,\r
+                          BufferSizeInPages,\r
+                          &CommonBuffer,\r
+                          0\r
+                          );\r
+  if (EFI_ERROR (Status)) {\r
+    DEBUG ((gEHCErrorLevel, "PciIo->AllocateBuffer Failed\n"));\r
+    Status = EFI_OUT_OF_RESOURCES;\r
+    goto exit;\r
+  }\r
+\r
+  Status = HcDev->PciIo->Map (\r
+                          HcDev->PciIo,\r
+                          EfiPciIoOperationBusMasterCommonBuffer,\r
+                          CommonBuffer,\r
+                          &BufferSizeInBytes,\r
+                          &FrameBuffer,\r
+                          &Map\r
+                          );\r
+  if (EFI_ERROR (Status) || (BufferSizeInBytes != EFI_PAGE_SIZE)) {\r
+    DEBUG ((gEHCErrorLevel, "PciIo->MapBuffer Failed\n"));\r
+    Status = EFI_OUT_OF_RESOURCES;\r
+    goto free_buffer;\r
+  }\r
+\r
+  //\r
+  // Put high 32bit into CtrlDataStructSeg reg \r
+  // when 64bit addressing range capability\r
+  //\r
+  if (HcDev->Is64BitCapable != 0) {\r
+       HcDev->High32BitAddr = (UINT32) GET_32B_TO_63B (FrameBuffer);\r
+       \r
+       Status = SetCtrlDataStructSeg (HcDev);\r
+    if (EFI_ERROR (Status)) {\r
+      DEBUG ((gEHCErrorLevel, "SetCtrlDataStructSeg Failed\n"));\r
+      Status = EFI_DEVICE_ERROR;\r
+      goto unmap_buffer;\r
+    }\r
+  }\r
+  \r
+  //\r
+  // Tell the Host Controller where the Frame List lies,\r
+  // by set the Frame List Base Address Register.\r
+  //\r
+  Status = SetFrameListBaseAddr (HcDev, (UINT32) FrameBuffer);\r
+  if (EFI_ERROR (Status)) {\r
+    Status = EFI_DEVICE_ERROR;\r
+    goto unmap_buffer;\r
+  }\r
+\r
+  HcDev->PeriodicFrameListLength  = Length;\r
+  HcDev->PeriodicFrameListBuffer  = (VOID *) ((UINTN) FrameBuffer);\r
+  HcDev->PeriodicFrameListMap     = Map;\r
+\r
+  //\r
+  // Init Frame List Array fields\r
+  //\r
+  FrameEntryPtr = (FRAME_LIST_ENTRY *) HcDev->PeriodicFrameListBuffer;\r
+  for (FrameIndex = 0; FrameIndex < HcDev->PeriodicFrameListLength; FrameIndex++) {\r
+    FrameEntryPtr->LinkPointer    = 0;\r
+    FrameEntryPtr->Rsvd           = 0;\r
+    FrameEntryPtr->SelectType     = 0;\r
+    FrameEntryPtr->LinkTerminate  = TRUE;\r
+    FrameEntryPtr++;\r
+  }\r
+\r
+  goto exit;\r
+\r
+unmap_buffer:\r
+  HcDev->PciIo->Unmap (HcDev->PciIo, Map);\r
+free_buffer:\r
+  HcDev->PciIo->FreeBuffer (HcDev->PciIo, BufferSizeInPages, CommonBuffer);\r
+exit:\r
+  return Status;\r
+}\r
+\r
+VOID\r
+DeinitialPeriodicFrameList (\r
+  IN  USB2_HC_DEV     *HcDev\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Deinitialize Periodic Schedule Frame List\r
+\r
+Arguments:\r
+\r
+  HcDev - USB2_HC_DEV\r
+\r
+Returns:\r
+\r
+  VOID\r
+  \r
+--*/\r
+{\r
+  HcDev->PciIo->Unmap (HcDev->PciIo, HcDev->PeriodicFrameListMap);\r
+  HcDev->PciIo->FreeBuffer (HcDev->PciIo, EFI_SIZE_TO_PAGES (EFI_PAGE_SIZE), HcDev->PeriodicFrameListBuffer);\r
+  return ;\r
+}\r
+\r
+EFI_STATUS\r
+CreatePollingTimer (\r
+  IN  USB2_HC_DEV      *HcDev,\r
+  IN  EFI_EVENT_NOTIFY NotifyFunction\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Create Async Request Polling Timer\r
+\r
+Arguments:\r
+\r
+  HcDev          - USB2_HC_DEV\r
+  NotifyFunction - Timer Notify Function\r
+  \r
+Returns:\r
+  \r
+  EFI_SUCCESS        Success\r
+  EFI_DEVICE_ERROR   Fail\r
+  \r
+--*/\r
+{\r
+  return gBS->CreateEvent (\r
+                EFI_EVENT_TIMER | EFI_EVENT_NOTIFY_SIGNAL,\r
+                EFI_TPL_NOTIFY,\r
+                NotifyFunction,\r
+                HcDev,\r
+                &HcDev->AsyncRequestEvent\r
+                );\r
+}\r
+\r
+EFI_STATUS\r
+DestoryPollingTimer (\r
+  IN  USB2_HC_DEV *HcDev\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Destory Async Request Polling Timer\r
+\r
+Arguments:\r
+\r
+  HcDev - USB2_HC_DEV\r
+  \r
+Returns:\r
+\r
+  EFI_SUCCESS        Success\r
+  EFI_DEVICE_ERROR   Fail\r
+  \r
+--*/\r
+{\r
+  return gBS->CloseEvent (HcDev->AsyncRequestEvent);\r
+}\r
+\r
+EFI_STATUS\r
+StartPollingTimer (\r
+  IN  USB2_HC_DEV *HcDev\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Start Async Request Polling Timer\r
+\r
+Arguments:\r
+\r
+  HcDev - USB2_HC_DEV\r
+  \r
+Returns:\r
+\r
+  EFI_SUCCESS        Success\r
+  EFI_DEVICE_ERROR   Fail\r
+  \r
+--*/\r
+{\r
+  return gBS->SetTimer (\r
+                HcDev->AsyncRequestEvent,\r
+                TimerPeriodic,\r
+                EHCI_ASYNC_REQUEST_POLLING_TIME\r
+                );\r
+}\r
+\r
+EFI_STATUS\r
+StopPollingTimer (\r
+  IN  USB2_HC_DEV *HcDev\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Stop Async Request Polling Timer\r
+\r
+Arguments:\r
+\r
+  HcDev - USB2_HC_DEV\r
+  \r
+Returns:\r
+\r
+  EFI_SUCCESS        Success\r
+  EFI_DEVICE_ERROR   Fail\r
+  \r
+--*/\r
+{\r
+  return gBS->SetTimer (\r
+                HcDev->AsyncRequestEvent,\r
+                TimerCancel,\r
+                EHCI_ASYNC_REQUEST_POLLING_TIME\r
+                );\r
+}\r
+\r
+EFI_STATUS\r
+CreateQh (\r
+  IN  USB2_HC_DEV         *HcDev,\r
+  IN  UINT8               DeviceAddr,\r
+  IN  UINT8               Endpoint,\r
+  IN  UINT8               DeviceSpeed,\r
+  IN  UINTN               MaxPacketLen,\r
+  OUT EHCI_QH_ENTITY      **QhPtrPtr\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Create Qh Structure and Pre-Initialize\r
+\r
+Arguments:\r
+\r
+  HcDev        - USB2_HC_DEV \r
+  DeviceAddr   - Address of Device\r
+  Endpoint     - Endpoint Number\r
+  DeviceSpeed  - Device Speed\r
+  MaxPacketLen - Max Length of one Packet\r
+  QhPtrPtr     - A pointer of pointer to Qh for return\r
+  \r
+Returns:\r
+\r
+  EFI_SUCCESS            Success\r
+  EFI_OUT_OF_RESOURCES   Cannot allocate resources\r
+  \r
+--*/\r
+{\r
+  EFI_STATUS  Status;\r
+  EHCI_QH_HW  *QhHwPtr;\r
+\r
+  ASSERT (HcDev);\r
+  ASSERT (QhPtrPtr);\r
+\r
+  *QhPtrPtr = NULL;\r
+\r
+  //\r
+  // Allocate  memory for Qh structure\r
+  //\r
+  Status = EhciAllocatePool (\r
+             HcDev,\r
+             (UINT8 **) QhPtrPtr,\r
+             sizeof (EHCI_QH_ENTITY)\r
+             );\r
+  if (EFI_ERROR (Status)) {\r
+    Status = EFI_OUT_OF_RESOURCES;\r
+    goto exit;\r
+  }\r
+  //\r
+  // Init fields in Qh\r
+  //\r
+  gBS->SetMem (*QhPtrPtr, sizeof (EHCI_QH_ENTITY), 0);\r
+\r
+  //\r
+  // Software field\r
+  //\r
+  (*QhPtrPtr)->Next         = NULL;\r
+  (*QhPtrPtr)->Prev         = NULL;\r
+  (*QhPtrPtr)->FirstQtdPtr  = NULL;\r
+  (*QhPtrPtr)->AltQtdPtr    = NULL;\r
+  (*QhPtrPtr)->LastQtdPtr   = NULL;\r
+\r
+  //\r
+  // Hardware field\r
+  //\r
+  QhHwPtr                       = &((*QhPtrPtr)->Qh);\r
+  QhHwPtr->QhHorizontalPointer  = 0;\r
+  QhHwPtr->SelectType           = 0;\r
+  QhHwPtr->MaxPacketLen         = (UINT32) MaxPacketLen;\r
+  QhHwPtr->EndpointSpeed        = (DeviceSpeed & 0x3);\r
+  QhHwPtr->EndpointNum          = (Endpoint & 0x0f);\r
+  QhHwPtr->DeviceAddr           = (DeviceAddr & 0x7f);\r
+  QhHwPtr->Multiplier           = HIGH_BANDWIDTH_PIPE_MULTIPLIER;\r
+  QhHwPtr->Rsvd1                = 0;\r
+  QhHwPtr->Rsvd2                = 0;\r
+  QhHwPtr->Rsvd3                = 0;\r
+  QhHwPtr->Rsvd4                = 0;\r
+  QhHwPtr->Rsvd5                = 0;\r
+  QhHwPtr->Rsvd6                = 0;\r
+\r
+exit:\r
+  return Status;\r
+}\r
+\r
+VOID\r
+DestoryQh (\r
+  IN USB2_HC_DEV         *HcDev,\r
+  IN EHCI_QH_ENTITY      *QhPtr\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Destory Qh Structure \r
+  \r
+Arguments:\r
+\r
+  HcDev - USB2_HC_DEV \r
+  QhPtr - A pointer to Qh\r
+  \r
+Returns:\r
+\r
+  EFI_SUCCESS        Success\r
+  EFI_DEVICE_ERROR   Fail\r
+  \r
+--*/\r
+{\r
+  ASSERT (HcDev);\r
+  ASSERT (QhPtr);\r
+\r
+  EhciFreePool (HcDev, (UINT8 *) QhPtr, sizeof (EHCI_QH_ENTITY));\r
+  return ;\r
+}\r
+\r
+EFI_STATUS\r
+CreateControlQh (\r
+  IN  USB2_HC_DEV                         *HcDev,\r
+  IN  UINT8                               DeviceAddr,\r
+  IN  UINT8                               DeviceSpeed,\r
+  IN  UINTN                               MaxPacketLen,\r
+  IN  EFI_USB2_HC_TRANSACTION_TRANSLATOR  *Translator,\r
+  OUT EHCI_QH_ENTITY                      **QhPtrPtr\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Create Qh for Control Transfer\r
+\r
+Arguments:\r
+\r
+  HcDev        - USB2_HC_DEV \r
+  DeviceAddr   - Address of Device\r
+  DeviceSpeed  - Device Speed\r
+  MaxPacketLen - Max Length of one Packet\r
+  Translator   - Translator Transaction for SplitX\r
+  QhPtrPtr     - A pointer of pointer to Qh for return\r
+  \r
+Returns:\r
+\r
+  EFI_SUCCESS            Success\r
+  EFI_OUT_OF_RESOURCES   Cannot allocate resources\r
+  \r
+--*/\r
+{\r
+  EFI_STATUS  Status;\r
+\r
+  //\r
+  // Create and init Control Qh\r
+  //\r
+  Status = CreateQh (\r
+             HcDev,\r
+             DeviceAddr,\r
+             0,\r
+             DeviceSpeed,\r
+             MaxPacketLen,\r
+             QhPtrPtr\r
+             );\r
+  if (EFI_ERROR (Status)) {\r
+    Status = EFI_OUT_OF_RESOURCES;\r
+    goto exit;\r
+  }\r
+  //\r
+  // Software field\r
+  //\r
+  (*QhPtrPtr)->Next         = (*QhPtrPtr);\r
+  (*QhPtrPtr)->Prev         = (*QhPtrPtr);\r
+  (*QhPtrPtr)->TransferType = CONTROL_TRANSFER;\r
+\r
+  //\r
+  // Hardware field\r
+  //\r
+  // Control Transfer use DataToggleControl\r
+  //\r
+  (*QhPtrPtr)->Qh.DataToggleControl   = TRUE;\r
+  (*QhPtrPtr)->Qh.QhHorizontalPointer = (UINT32) (GET_0B_TO_31B (&((*QhPtrPtr)->Qh)) >> 5);\r
+  (*QhPtrPtr)->Qh.SelectType          = QH_SELECT_TYPE;\r
+  (*QhPtrPtr)->Qh.QhTerminate         = FALSE;\r
+  (*QhPtrPtr)->Qh.ControlEndpointFlag = TRUE;\r
+  (*QhPtrPtr)->Qh.NakCountReload      = NAK_COUNT_RELOAD;\r
+  if (NULL != Translator) {\r
+    (*QhPtrPtr)->Qh.PortNum = Translator->TranslatorPortNumber;\r
+    (*QhPtrPtr)->Qh.HubAddr = Translator->TranslatorHubAddress;\r
+    (*QhPtrPtr)->Qh.Status |= QTD_STATUS_DO_START_SPLIT;\r
+  }\r
+\r
+exit:\r
+  return Status;\r
+}\r
+\r
+EFI_STATUS\r
+CreateBulkQh (\r
+  IN  USB2_HC_DEV                         *HcDev,\r
+  IN  UINT8                               DeviceAddr,\r
+  IN  UINT8                               EndPointAddr,\r
+  IN  UINT8                               DeviceSpeed,\r
+  IN  UINT8                               DataToggle,\r
+  IN  UINTN                               MaxPacketLen,\r
+  IN  EFI_USB2_HC_TRANSACTION_TRANSLATOR  *Translator,\r
+  OUT EHCI_QH_ENTITY                      **QhPtrPtr\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Create Qh for Bulk Transfer\r
+\r
+Arguments:\r
+\r
+  HcDev        - USB2_HC_DEV \r
+  DeviceAddr   - Address of Device\r
+  EndPointAddr - Address of Endpoint\r
+  DeviceSpeed  - Device Speed\r
+  MaxPacketLen - Max Length of one Packet\r
+  Translator   - Translator Transaction for SplitX\r
+  QhPtrPtr     - A pointer of pointer to Qh for return\r
+  \r
+Returns:\r
+\r
+  EFI_SUCCESS            Success\r
+  EFI_OUT_OF_RESOURCES   Cannot allocate resources\r
+  \r
+--*/\r
+{\r
+  EFI_STATUS  Status;\r
+\r
+  //\r
+  // Create and init Bulk Qh\r
+  //\r
+  Status = CreateQh (\r
+             HcDev,\r
+             DeviceAddr,\r
+             EndPointAddr,\r
+             DeviceSpeed,\r
+             MaxPacketLen,\r
+             QhPtrPtr\r
+             );\r
+  if (EFI_ERROR (Status)) {\r
+    Status = EFI_OUT_OF_RESOURCES;\r
+    goto exit;\r
+  }\r
+  \r
+  //\r
+  // Software fields\r
+  //\r
+  (*QhPtrPtr)->Next         = (*QhPtrPtr);\r
+  (*QhPtrPtr)->Prev         = (*QhPtrPtr);\r
+  (*QhPtrPtr)->TransferType = BULK_TRANSFER;\r
+\r
+  //\r
+  // Hardware fields\r
+  //\r
+  // BulkTransfer don't use DataToggleControl\r
+  //\r
+  (*QhPtrPtr)->Qh.DataToggleControl   = FALSE;  \r
+  (*QhPtrPtr)->Qh.QhHorizontalPointer = (UINT32) (GET_0B_TO_31B (&((*QhPtrPtr)->Qh)) >> 5);\r
+  (*QhPtrPtr)->Qh.SelectType          = QH_SELECT_TYPE;\r
+  (*QhPtrPtr)->Qh.QhTerminate         = FALSE;\r
+  (*QhPtrPtr)->Qh.NakCountReload      = NAK_COUNT_RELOAD;\r
+  (*QhPtrPtr)->Qh.DataToggle          = DataToggle;\r
+  if (NULL != Translator) {\r
+    (*QhPtrPtr)->Qh.PortNum = Translator->TranslatorPortNumber;\r
+    (*QhPtrPtr)->Qh.HubAddr = Translator->TranslatorHubAddress;\r
+    (*QhPtrPtr)->Qh.Status |= QTD_STATUS_DO_START_SPLIT;\r
+  }\r
+\r
+exit:\r
+  return Status;\r
+}\r
+\r
+EFI_STATUS\r
+CreateInterruptQh (\r
+  IN  USB2_HC_DEV                         *HcDev,\r
+  IN  UINT8                               DeviceAddr,\r
+  IN  UINT8                               EndPointAddr,\r
+  IN  UINT8                               DeviceSpeed,\r
+  IN  UINT8                               DataToggle,\r
+  IN  UINTN                               MaxPacketLen,\r
+  IN  UINTN                               Interval,\r
+  IN  EFI_USB2_HC_TRANSACTION_TRANSLATOR  *Translator,\r
+  OUT EHCI_QH_ENTITY                      **QhPtrPtr\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Create Qh for Control Transfer\r
+\r
+Arguments:\r
+\r
+  HcDev        - USB2_HC_DEV \r
+  DeviceAddr   - Address of Device\r
+  EndPointAddr - Address of Endpoint\r
+  DeviceSpeed  - Device Speed\r
+  MaxPacketLen - Max Length of one Packet\r
+  Interval     - value of interval\r
+  Translator   - Translator Transaction for SplitX\r
+  QhPtrPtr     - A pointer of pointer to Qh for return\r
+  \r
+Returns:\r
+\r
+  EFI_SUCCESS            Success\r
+  EFI_OUT_OF_RESOURCES   Cannot allocate resources\r
+  \r
+--*/\r
+{\r
+  EFI_STATUS  Status;\r
+\r
+  //\r
+  // Create and init InterruptQh\r
+  //\r
+  Status = CreateQh (\r
+             HcDev,\r
+             DeviceAddr,\r
+             EndPointAddr,\r
+             DeviceSpeed,\r
+             MaxPacketLen,\r
+             QhPtrPtr\r
+             );\r
+  if (EFI_ERROR (Status)) {\r
+    Status = EFI_OUT_OF_RESOURCES;\r
+    goto exit;\r
+  }\r
+  \r
+  //\r
+  // Software fields\r
+  //\r
+  if (Interval == 0) {\r
+    (*QhPtrPtr)->TransferType = SYNC_INTERRUPT_TRANSFER;\r
+  } else {\r
+    (*QhPtrPtr)->TransferType = ASYNC_INTERRUPT_TRANSFER;\r
+  }\r
+  (*QhPtrPtr)->Interval = GetApproxiOfInterval (Interval);\r
+\r
+  //\r
+  // Hardware fields\r
+  //\r
+  // InterruptTranfer don't use DataToggleControl\r
+  //\r
+  (*QhPtrPtr)->Qh.DataToggleControl     = FALSE;\r
+  (*QhPtrPtr)->Qh.QhHorizontalPointer   = 0;\r
+  (*QhPtrPtr)->Qh.QhTerminate           = TRUE;\r
+  (*QhPtrPtr)->Qh.NakCountReload        = 0;\r
+  (*QhPtrPtr)->Qh.InerruptScheduleMask  = MICRO_FRAME_0_CHANNEL;\r
+  (*QhPtrPtr)->Qh.SplitComletionMask    = (MICRO_FRAME_2_CHANNEL | MICRO_FRAME_3_CHANNEL | MICRO_FRAME_4_CHANNEL);\r
+  (*QhPtrPtr)->Qh.DataToggle            = DataToggle;\r
+  if (NULL != Translator) {\r
+    (*QhPtrPtr)->Qh.PortNum = Translator->TranslatorPortNumber;\r
+    (*QhPtrPtr)->Qh.HubAddr = Translator->TranslatorHubAddress;\r
+    (*QhPtrPtr)->Qh.Status |= QTD_STATUS_DO_START_SPLIT;\r
+  }\r
+\r
+exit:\r
+  return Status;\r
+}\r
+\r
+EFI_STATUS\r
+CreateQtd (\r
+  IN  USB2_HC_DEV          *HcDev,\r
+  IN  UINT8                *DataPtr,\r
+  IN  UINTN                DataLen,\r
+  IN  UINT8                PktId,\r
+  IN  UINT8                Toggle,\r
+  IN  UINT8                QtdStatus,\r
+  OUT EHCI_QTD_ENTITY      **QtdPtrPtr\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Create Qtd Structure and Pre-Initialize it\r
+\r
+Arguments:\r
+\r
+  HcDev       - USB2_HC_DEV \r
+  DataPtr     - A pointer to user data buffer to transfer\r
+  DataLen     - Length of user data to transfer\r
+  PktId       - Packet Identification of this Qtd\r
+  Toggle      - Data Toggle of this Qtd\r
+  QtdStatus   - Default value of status of this Qtd\r
+  QtdPtrPtr   - A pointer of pointer to Qtd for return\r
+  \r
+Returns:\r
+\r
+  EFI_SUCCESS            Success\r
+  EFI_OUT_OF_RESOURCES   Cannot allocate resources\r
+  \r
+--*/\r
+{\r
+  EFI_STATUS  Status;\r
+  EHCI_QTD_HW *QtdHwPtr;\r
+\r
+  ASSERT (HcDev);\r
+  ASSERT (QtdPtrPtr);\r
+\r
+  //\r
+  // Create memory for Qtd structure\r
+  //\r
+  Status = EhciAllocatePool (\r
+             HcDev,\r
+             (UINT8 **) QtdPtrPtr,\r
+             sizeof (EHCI_QTD_ENTITY)\r
+             );\r
+  if (EFI_ERROR (Status)) {\r
+    Status = EFI_OUT_OF_RESOURCES;\r
+    goto exit;\r
+  }\r
+  //\r
+  // Init fields in Qtd\r
+  //\r
+  gBS->SetMem (*QtdPtrPtr, sizeof (EHCI_QTD_ENTITY), 0);\r
+\r
+  //\r
+  // Software field\r
+  //\r
+  (*QtdPtrPtr)->TotalBytes        = (UINT32) DataLen;\r
+  (*QtdPtrPtr)->StaticTotalBytes  = (UINT32) DataLen;\r
+  (*QtdPtrPtr)->Prev              = NULL;\r
+  (*QtdPtrPtr)->Next              = NULL;\r
+\r
+  //\r
+  // Hardware field\r
+  //\r
+  QtdHwPtr                      = &((*QtdPtrPtr)->Qtd);\r
+  QtdHwPtr->NextQtdPointer      = 0;\r
+  QtdHwPtr->NextQtdTerminate    = TRUE;\r
+  QtdHwPtr->AltNextQtdPointer   = 0;\r
+  QtdHwPtr->AltNextQtdTerminate = TRUE;\r
+  QtdHwPtr->DataToggle          = Toggle;\r
+  QtdHwPtr->TotalBytes          = (UINT32) DataLen;\r
+  QtdHwPtr->CurrentPage         = 0;\r
+  QtdHwPtr->ErrorCount          = QTD_ERROR_COUNTER;\r
+  QtdHwPtr->Status              = QtdStatus;\r
+  QtdHwPtr->Rsvd1               = 0;\r
+  QtdHwPtr->Rsvd2               = 0;\r
+  QtdHwPtr->Rsvd3               = 0;\r
+  QtdHwPtr->Rsvd4               = 0;\r
+  QtdHwPtr->Rsvd5               = 0;\r
+  QtdHwPtr->Rsvd6               = 0;\r
+\r
+  //\r
+  // Set PacketID [Setup/Data/Status]\r
+  //\r
+  switch (PktId) {\r
+  case SETUP_PACKET_ID:\r
+    QtdHwPtr->PidCode = SETUP_PACKET_PID_CODE;\r
+    break;\r
+\r
+  case INPUT_PACKET_ID:\r
+    QtdHwPtr->PidCode = INPUT_PACKET_PID_CODE;\r
+    break;\r
+\r
+  case OUTPUT_PACKET_ID:\r
+    QtdHwPtr->PidCode = OUTPUT_PACKET_PID_CODE;\r
+    break;\r
+\r
+  default:\r
+    Status = EFI_INVALID_PARAMETER;\r
+    goto exit;\r
+  }\r
+  \r
+  //\r
+  // Set Data Buffer Pointers\r
+  //\r
+  if (NULL != DataPtr) {\r
+    SetQtdBufferPointer (\r
+      QtdHwPtr,\r
+      DataPtr,\r
+      DataLen\r
+      );\r
+    (*QtdPtrPtr)->StaticCurrentOffset = QtdHwPtr->CurrentOffset;\r
+  }\r
+\r
+exit:\r
+  return Status;\r
+}\r
+\r
+EFI_STATUS\r
+CreateSetupQtd (\r
+  IN  USB2_HC_DEV          *HcDev,\r
+  IN  UINT8                *DevReqPtr,\r
+  OUT EHCI_QTD_ENTITY      **QtdPtrPtr\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Create Qtd Structure for Setup \r
+\r
+Arguments:\r
+\r
+  HcDev      - USB2_HC_DEV \r
+  DevReqPtr  - A pointer to Device Request Data\r
+  QtdPtrPtr  - A pointer of pointer to Qtd for return\r
+  \r
+Returns:\r
+\r
+  EFI_SUCCESS            Success\r
+  EFI_OUT_OF_RESOURCES   Cannot allocate resources\r
+  \r
+--*/\r
+{\r
+  return CreateQtd (\r
+           HcDev,\r
+           DevReqPtr,\r
+           sizeof (EFI_USB_DEVICE_REQUEST),\r
+           SETUP_PACKET_ID,\r
+           DATA0,\r
+           QTD_STATUS_ACTIVE,\r
+           QtdPtrPtr\r
+           );\r
+}\r
+\r
+EFI_STATUS\r
+CreateDataQtd (\r
+  IN  USB2_HC_DEV           *HcDev,\r
+  IN  UINT8                 *DataPtr,\r
+  IN  UINTN                 DataLen,\r
+  IN  UINT8                 PktId,\r
+  IN  UINT8                 Toggle,\r
+  OUT EHCI_QTD_ENTITY       **QtdPtrPtr\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Create Qtd Structure for data \r
+\r
+Arguments:\r
+\r
+  HcDev       - USB2_HC_DEV \r
+  DataPtr     - A pointer to user data buffer to transfer\r
+  DataLen     - Length of user data to transfer\r
+  PktId       - Packet Identification of this Qtd\r
+  Toggle      - Data Toggle of this Qtd\r
+  QtdPtrPtr   - A pointer of pointer to Qtd for return\r
+  \r
+Returns:\r
+\r
+  EFI_SUCCESS            Success\r
+  EFI_OUT_OF_RESOURCES   Cannot allocate resources\r
+  \r
+--*/\r
+{\r
+  return CreateQtd (\r
+           HcDev,\r
+           DataPtr,\r
+           DataLen,\r
+           PktId,\r
+           Toggle,\r
+           QTD_STATUS_ACTIVE,\r
+           QtdPtrPtr\r
+           );\r
+}\r
+\r
+EFI_STATUS\r
+CreateAltQtd (\r
+  IN  USB2_HC_DEV           *HcDev,\r
+  IN  UINT8                 PktId,\r
+  OUT EHCI_QTD_ENTITY       **QtdPtrPtr\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Create Qtd Structure for Alternative \r
+\r
+Arguments:\r
+\r
+  HcDev      - USB2_HC_DEV \r
+  PktId      - Packet Identification of this Qtd\r
+  QtdPtrPtr  - A pointer of pointer to Qtd for return\r
+  \r
+Returns:\r
+\r
+  EFI_SUCCESS            Success\r
+  EFI_OUT_OF_RESOURCES   Cannot allocate resources\r
+  \r
+--*/\r
+{\r
+  return CreateQtd (\r
+           HcDev,\r
+           NULL,\r
+           0,\r
+           PktId,\r
+           0,\r
+           QTD_STATUS_ACTIVE,\r
+           QtdPtrPtr\r
+           );\r
+}\r
+\r
+EFI_STATUS\r
+CreateStatusQtd (\r
+  IN  USB2_HC_DEV           *HcDev,\r
+  IN  UINT8                 PktId,\r
+  OUT EHCI_QTD_ENTITY       **QtdPtrPtr\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Create Qtd Structure for status \r
+\r
+Arguments:\r
+\r
+  HcDev       - USB2_HC_DEV \r
+  PktId       - Packet Identification of this Qtd\r
+  QtdPtrPtr   - A pointer of pointer to Qtd for return\r
+  \r
+Returns:\r
+\r
+  EFI_SUCCESS            Success\r
+  EFI_OUT_OF_RESOURCES   Cannot allocate resources\r
+  \r
+--*/\r
+{\r
+  return CreateQtd (\r
+           HcDev,\r
+           NULL,\r
+           0,\r
+           PktId,\r
+           DATA1,\r
+           QTD_STATUS_ACTIVE,\r
+           QtdPtrPtr\r
+           );\r
+}\r
+\r
+EFI_STATUS\r
+CreateControlQtds (\r
+  IN  USB2_HC_DEV                         *HcDev,\r
+  IN UINT8                                DataPktId,\r
+  IN UINT8                                *RequestCursor,\r
+  IN UINT8                                *DataCursor,\r
+  IN UINTN                                DataLen,\r
+  IN  EFI_USB2_HC_TRANSACTION_TRANSLATOR  *Translator,\r
+  OUT EHCI_QTD_ENTITY                     **ControlQtdsHead\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Create Qtds list for Control Transfer \r
+\r
+Arguments:\r
+\r
+  HcDev           - USB2_HC_DEV \r
+  DataPktId       - Packet Identification of Data Qtds\r
+  RequestCursor   - A pointer to request structure buffer to transfer\r
+  DataCursor      - A pointer to user data buffer to transfer\r
+  DataLen         - Length of user data to transfer\r
+  ControlQtdsHead - A pointer of pointer to first Qtd for control tranfer for return\r
+  \r
+Returns:\r
+\r
+  EFI_SUCCESS            Success\r
+  EFI_OUT_OF_RESOURCES   Cannot allocate resources\r
+  \r
+--*/\r
+{\r
+  EFI_STATUS      Status;\r
+  EHCI_QTD_ENTITY *QtdPtr;\r
+  EHCI_QTD_ENTITY *PreQtdPtr;\r
+  EHCI_QTD_ENTITY *SetupQtdPtr;\r
+  EHCI_QTD_ENTITY *FirstDataQtdPtr;\r
+  EHCI_QTD_ENTITY *LastDataQtdPtr;\r
+  EHCI_QTD_ENTITY *StatusQtdPtr;\r
+  UINT8           DataToggle;\r
+  UINT8           StatusPktId;\r
+  UINTN           CapacityOfQtd;\r
+  UINTN           SizePerQtd;\r
+  UINTN           DataCount;\r
+  UINTN           Xnum;\r
+  \r
+  QtdPtr          = NULL;\r
+  PreQtdPtr       = NULL;\r
+  SetupQtdPtr     = NULL;\r
+  FirstDataQtdPtr = NULL;\r
+  LastDataQtdPtr  = NULL;\r
+  StatusQtdPtr    = NULL;\r
+  CapacityOfQtd = 0;\r
+\r
+  //\r
+  //  Setup Stage of Control Transfer\r
+  //\r
+  Status = CreateSetupQtd (\r
+             HcDev,\r
+             RequestCursor,\r
+             &SetupQtdPtr\r
+             );\r
+  if (EFI_ERROR (Status)) {\r
+    Status = EFI_OUT_OF_RESOURCES;\r
+    goto exit;\r
+  }\r
+  \r
+  //\r
+  //  Data Stage of Control Transfer\r
+  //\r
+  DataToggle  = 1;\r
+  DataCount   = DataLen;\r
+\r
+  //\r
+  // Create Qtd structure and link together\r
+  //\r
+  while (DataCount > 0) {\r
+    //\r
+    // PktSize is the data load size that each Qtd.\r
+    //\r
+    CapacityOfQtd = GetCapacityOfQtd (DataCursor);\r
+    SizePerQtd    = DataCount;\r
+    if (DataCount > CapacityOfQtd) {\r
+      SizePerQtd = CapacityOfQtd;\r
+    }\r
+\r
+    Status = CreateDataQtd (\r
+               HcDev,\r
+               DataCursor,\r
+               SizePerQtd,\r
+               DataPktId,\r
+               DataToggle,\r
+               &QtdPtr\r
+               );\r
+    if (EFI_ERROR (Status)) {\r
+      Status = EFI_OUT_OF_RESOURCES;\r
+      if (NULL == FirstDataQtdPtr) {\r
+        goto destory_setup_qtd;\r
+      } else {\r
+        goto destory_qtds;\r
+      }\r
+    }\r
+\r
+    if (NULL == FirstDataQtdPtr) {\r
+      FirstDataQtdPtr = QtdPtr;\r
+    } else {\r
+      LinkQtdToQtd (PreQtdPtr, QtdPtr);\r
+    }\r
+\r
+    //\r
+    // Reverse Data Toggle or not determined by parity of transactions of one qtd\r
+    //\r
+    Xnum = Translator ? GetNumberOfTransaction (SizePerQtd, EHCI_BLOCK_SIZE_WITH_TT) : GetNumberOfTransaction (SizePerQtd, EHCI_BLOCK_SIZE);\r
+    if (Xnum % 2 != 0) {\r
+      DataToggle ^= 1;\r
+    }\r
+    \r
+    PreQtdPtr = QtdPtr;\r
+    DataCursor += SizePerQtd;\r
+    DataCount -= SizePerQtd;\r
+  }\r
+\r
+  LastDataQtdPtr = QtdPtr;\r
+\r
+  //\r
+  // Status Stage of Control Transfer\r
+  //\r
+  if (OUTPUT_PACKET_ID == DataPktId) {\r
+    StatusPktId = INPUT_PACKET_ID;\r
+  } else {\r
+    StatusPktId = OUTPUT_PACKET_ID;\r
+  }\r
+\r
+  Status = CreateStatusQtd (\r
+            HcDev,\r
+            StatusPktId,\r
+            &StatusQtdPtr\r
+            );\r
+  if (EFI_ERROR (Status)) {\r
+    Status = EFI_OUT_OF_RESOURCES;\r
+    goto destory_qtds;\r
+  }\r
+  \r
+  //\r
+  // Link setup Qtd -> data Qtds -> status Qtd\r
+  //\r
+  if (FirstDataQtdPtr != NULL) {\r
+    LinkQtdToQtd (SetupQtdPtr, FirstDataQtdPtr);\r
+    LinkQtdToQtd (LastDataQtdPtr, StatusQtdPtr);\r
+  } else {\r
+    LinkQtdToQtd (SetupQtdPtr, StatusQtdPtr);\r
+  }\r
+\r
+  *ControlQtdsHead = SetupQtdPtr;\r
+\r
+  goto exit;\r
+\r
+destory_qtds:\r
+  DestoryQtds (HcDev, FirstDataQtdPtr);\r
+destory_setup_qtd:\r
+  DestoryQtds (HcDev, SetupQtdPtr);\r
+exit:\r
+  return Status;\r
+}\r
+\r
+EFI_STATUS\r
+CreateBulkOrInterruptQtds (\r
+  IN  USB2_HC_DEV                         *HcDev,\r
+  IN  UINT8                               PktId,\r
+  IN  UINT8                               *DataCursor,\r
+  IN  UINTN                               DataLen,\r
+  IN  EFI_USB2_HC_TRANSACTION_TRANSLATOR  *Translator,\r
+  OUT EHCI_QTD_ENTITY                     **QtdsHead\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Create Qtds list for Bulk or Interrupt Transfer \r
+\r
+Arguments:\r
+\r
+  HcDev        - USB2_HC_DEV \r
+  PktId        - Packet Identification of Qtds\r
+  DataCursor   - A pointer to user data buffer to transfer\r
+  DataLen      - Length of user data to transfer\r
+  DataToggle   - Data Toggle to start\r
+  Translator   - Translator Transaction for SplitX\r
+  QtdsHead     - A pointer of pointer to first Qtd for control tranfer for return\r
+  \r
+Returns:\r
+\r
+  EFI_SUCCESS            Success\r
+  EFI_OUT_OF_RESOURCES   Cannot allocate resources\r
+  \r
+--*/\r
+{\r
+  EFI_STATUS      Status;\r
+  EHCI_QTD_ENTITY *QtdPtr;\r
+  EHCI_QTD_ENTITY *PreQtdPtr;\r
+  EHCI_QTD_ENTITY *FirstQtdPtr;\r
+  EHCI_QTD_ENTITY *AltQtdPtr;\r
+  UINTN           DataCount;\r
+  UINTN           CapacityOfQtd;\r
+  UINTN           SizePerQtd;\r
+\r
+  Status        = EFI_SUCCESS;\r
+  QtdPtr        = NULL;\r
+  PreQtdPtr     = NULL;\r
+  FirstQtdPtr   = NULL;\r
+  AltQtdPtr     = NULL;\r
+  CapacityOfQtd = 0;\r
+\r
+  DataCount   = DataLen;\r
+  while (DataCount > 0) {\r
+\r
+    CapacityOfQtd = GetCapacityOfQtd (DataCursor);\r
+    SizePerQtd    = DataCount;\r
+    if (DataCount > CapacityOfQtd) {\r
+      SizePerQtd = CapacityOfQtd;\r
+    }\r
+\r
+    Status = CreateDataQtd (\r
+              HcDev,\r
+              DataCursor,\r
+              SizePerQtd,\r
+              PktId,\r
+              0,\r
+              &QtdPtr\r
+              );\r
+    if (EFI_ERROR (Status)) {\r
+      Status = EFI_OUT_OF_RESOURCES;\r
+      if (NULL == FirstQtdPtr) {\r
+        goto exit;\r
+      } else {\r
+        goto destory_qtds;\r
+      }\r
+    }\r
+\r
+    if (NULL == FirstQtdPtr) {\r
+      FirstQtdPtr = QtdPtr;\r
+    } else {\r
+      LinkQtdToQtd (PreQtdPtr, QtdPtr);\r
+    }\r
+\r
+    PreQtdPtr = QtdPtr;\r
+    DataCursor += SizePerQtd;\r
+    DataCount -= SizePerQtd;\r
+  }\r
+  \r
+  //\r
+  // Set Alternate Qtd\r
+  //\r
+  if (INPUT_PACKET_ID == PktId && 1 < GetNumberOfQtd (FirstQtdPtr)) {\r
+    Status = CreateAltQtd (\r
+              HcDev,\r
+              PktId,\r
+              &AltQtdPtr\r
+              );\r
+    if (EFI_ERROR (Status)) {\r
+      Status = EFI_OUT_OF_RESOURCES;\r
+      goto destory_qtds;\r
+    }\r
+\r
+    LinkQtdsToAltQtd (FirstQtdPtr, AltQtdPtr);\r
+  }\r
+\r
+  *QtdsHead = FirstQtdPtr;\r
+  goto exit;\r
+\r
+destory_qtds:\r
+  DestoryQtds (HcDev, FirstQtdPtr);\r
+exit:\r
+  return Status;\r
+}\r
+\r
+VOID\r
+DestoryQtds (\r
+  IN USB2_HC_DEV          *HcDev,\r
+  IN EHCI_QTD_ENTITY      *FirstQtdPtr\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Destory all Qtds in the list\r
+\r
+Arguments:\r
+\r
+  HcDev         - USB2_HC_DEV \r
+  FirstQtdPtr   - A pointer to first Qtd in the list \r
+    \r
+Returns:\r
+\r
+  VOID\r
+\r
+--*/\r
+{\r
+  EHCI_QTD_ENTITY *PrevQtd;\r
+  EHCI_QTD_ENTITY *NextQtd;\r
+\r
+  if (!FirstQtdPtr) {\r
+    goto exit;\r
+  }\r
+\r
+  PrevQtd = FirstQtdPtr;\r
+\r
+  //\r
+  // Delete all the Qtds.\r
+  //\r
+  do {\r
+    NextQtd = PrevQtd->Next;\r
+    EhciFreePool (HcDev, (UINT8 *) PrevQtd, sizeof (EHCI_QTD_ENTITY));\r
+    PrevQtd = NextQtd;\r
+  } while (NULL != PrevQtd);\r
+\r
+exit:\r
+  return ;\r
+}\r
+\r
+UINTN\r
+GetNumberOfQtd (\r
+  IN EHCI_QTD_ENTITY    *FirstQtdPtr\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Number of Qtds in the list\r
+  \r
+Arguments:\r
+\r
+  FirstQtdPtr - A pointer to first Qtd in the list\r
+    \r
+Returns:\r
+\r
+  Number of Qtds in the list\r
+\r
+--*/\r
+{\r
+  UINTN           Count;\r
+  EHCI_QTD_ENTITY *QtdPtr;\r
+  Count   = 0;\r
+  QtdPtr  = FirstQtdPtr;\r
+\r
+  ;\r
+\r
+  while (NULL != QtdPtr) {\r
+    Count++;\r
+    QtdPtr = QtdPtr->Next;\r
+  }\r
+\r
+  return Count;\r
+}\r
+\r
+UINTN\r
+GetNumberOfTransaction (\r
+  IN UINTN    SizeOfData,\r
+  IN UINTN    SizeOfTransaction\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Number of Transactions in one Qtd\r
+  \r
+Arguments:\r
+\r
+  SizeOfData           - Size of one Qtd\r
+  SizeOfTransaction    - Size of one Transaction\r
+   \r
+Returns:\r
+\r
+  Number of Transactions in this Qtd\r
+\r
+--*/\r
+{\r
+\r
+  return ((SizeOfData & (SizeOfTransaction - 1)) ? SizeOfData / SizeOfTransaction + 1 : SizeOfData / SizeOfTransaction);\r
+\r
+}\r
+\r
+UINTN\r
+GetCapacityOfQtd (\r
+  IN UINT8    *BufferCursor\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Get Size of First Qtd\r
+  \r
+Arguments:\r
+\r
+  BufferCursor       - BufferCursor of the Qtd\r
+   \r
+Returns:\r
+\r
+  Size of First Qtd\r
+\r
+--*/\r
+{\r
+\r
+  return (EHCI_MAX_QTD_CAPACITY - (EHCI_BLOCK_SIZE * GetNumberOfTransaction (EFI_PAGE_MASK & GET_0B_TO_31B (BufferCursor), EHCI_BLOCK_SIZE)));\r
+\r
+}\r
+\r
+UINTN\r
+GetApproxiOfInterval (\r
+  IN UINTN  Interval\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Get the approximate value in the 2 index sequence\r
+  \r
+Arguments:\r
+\r
+  Interval  - the value of interval\r
+  \r
+Returns:\r
+\r
+  approximate value of interval in the 2 index sequence\r
+  \r
+--*/\r
+{\r
+  UINTN Orignate;\r
+  UINTN Approxi;\r
+\r
+  Orignate  = Interval;\r
+  Approxi   = 1;\r
+\r
+  while (Orignate != 1 && Orignate != 0) {\r
+    Orignate  = Orignate >> 1;\r
+    Approxi   = Approxi << 1;\r
+  }\r
+\r
+  if (Interval & (Approxi >> 1)) {\r
+    Approxi = Approxi << 1;\r
+  }\r
+\r
+  return Approxi;\r
+}\r
+\r
+EHCI_QTD_HW *\r
+GetQtdAlternateNextPointer (\r
+  IN EHCI_QTD_HW  *HwQtdPtr\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Get Qtd alternate next pointer field\r
+  \r
+Arguments:\r
+\r
+  HwQtdPtr - A pointer to hardware Qtd structure\r
+  \r
+Returns:\r
+\r
+  A pointer to hardware alternate Qtd\r
+  \r
+--*/\r
+{\r
+  EHCI_QTD_HW *Value;\r
+\r
+  Value = NULL;\r
+\r
+  if (!HwQtdPtr->AltNextQtdTerminate) {\r
+    Value = (EHCI_QTD_HW *) GET_0B_TO_31B (HwQtdPtr->AltNextQtdPointer << 5);\r
+  }\r
+\r
+  return Value;\r
+}\r
+\r
+EHCI_QTD_HW *\r
+GetQtdNextPointer (\r
+  IN EHCI_QTD_HW  *HwQtdPtr\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Get Qtd next pointer field\r
+  \r
+Arguments:\r
+\r
+  HwQtdPtr - A pointer to hardware Qtd structure\r
+  \r
+Returns:\r
+\r
+  A pointer to next hardware Qtd structure\r
+  \r
+--*/\r
+{\r
+  EHCI_QTD_HW *Value;\r
+\r
+  Value = NULL;\r
+\r
+  if (!HwQtdPtr->NextQtdTerminate) {\r
+    Value = (EHCI_QTD_HW *) GET_0B_TO_31B (HwQtdPtr->NextQtdPointer << 5);\r
+  }\r
+\r
+  return Value;\r
+}\r
+\r
+VOID LinkQtdToQtd (\r
+  IN EHCI_QTD_ENTITY * PreQtdPtr, \r
+  IN EHCI_QTD_ENTITY * QtdPtr\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Link Qtds together\r
+  \r
+Arguments:\r
+\r
+  PreQtdPtr   - A pointer to pre Qtd\r
+  QtdPtr      - A pointer to next Qtd\r
+    \r
+Returns:\r
+\r
+  VOID\r
+\r
+--*/\r
+{\r
+  EHCI_QTD_HW *QtdHwPtr;\r
+\r
+  ASSERT(PreQtdPtr);\r
+  ASSERT(QtdPtr);\r
+\r
+  //\r
+  // Software link\r
+  //\r
+  PreQtdPtr->Next = QtdPtr;\r
+  QtdPtr->Prev    = PreQtdPtr;\r
+\r
+  //\r
+  // Hardware link\r
+  //\r
+  QtdHwPtr                        = &(QtdPtr->Qtd);\r
+  PreQtdPtr->Qtd.NextQtdPointer   = (UINT32) (GET_0B_TO_31B(QtdHwPtr) >> 5);\r
+  PreQtdPtr->Qtd.NextQtdTerminate = FALSE;\r
+\r
+  return ;\r
+}\r
+\r\r
+\r
+VOID LinkQtdsToAltQtd (\r
+  IN EHCI_QTD_ENTITY  * FirstQtdPtr, \r
+  IN EHCI_QTD_ENTITY  * AltQtdPtr\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Link AlterQtds together\r
+  \r
+Arguments:\r
+\r
+  FirstQtdPtr  - A pointer to first Qtd in the list\r
+  AltQtdPtr    - A pointer to alternative Qtd\r
+    \r
+Returns:\r
+\r
+  VOID\r
+\r
+--*/\r
+{\r
+  EHCI_QTD_ENTITY *QtdPtr;\r
+  EHCI_QTD_HW     *AltQtdHwPtr;\r
+\r
+  ASSERT(FirstQtdPtr);\r
+  ASSERT(AltQtdPtr);\r
+\r
+  AltQtdHwPtr = &(AltQtdPtr->Qtd);\r
+  QtdPtr      = FirstQtdPtr;\r
+  \r
+  while (NULL != QtdPtr) {\r
+    //\r
+    // Software link\r
+    //\r
+    QtdPtr->AltNext = AltQtdPtr;\r
+    //\r
+    // Hardware link\r
+    //\r
+    QtdPtr->Qtd.AltNextQtdPointer   = (UINT32) (GET_0B_TO_31B(AltQtdHwPtr) >> 5);\r
+    QtdPtr->Qtd.AltNextQtdTerminate = FALSE;\r
+    QtdPtr                          = QtdPtr->Next;\r
+  }\r
+\r
+  return ;\r
+}\r
+\r
+VOID\r
+LinkQtdToQh (\r
+  IN EHCI_QH_ENTITY      *QhPtr,\r
+  IN EHCI_QTD_ENTITY     *QtdPtr\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Link Qtds list to Qh\r
+  \r
+Arguments:\r
+\r
+  QhPtr    - A pointer to Qh\r
+  QtdPtr   - A pointer to first Qtd in the list\r
+  \r
+Returns:\r
+\r
+  VOID\r
+\r
+--*/\r
+{\r
+  EHCI_QTD_ENTITY *Cursor;\r
+  EHCI_QTD_HW     *QtdHwPtr;\r
+\r
+  ASSERT (QhPtr);\r
+  ASSERT (QtdPtr);\r
+\r
+  QhPtr->FirstQtdPtr = QtdPtr;\r
+  if (NULL != QtdPtr->AltNext) {\r
+    QhPtr->AltQtdPtr = QtdPtr->AltNext;\r
+  }\r
+\r
+  Cursor = QtdPtr;\r
+  while (NULL != Cursor) {\r
+    Cursor->SelfQh = QhPtr;\r
+    if (NULL == Cursor->Next) {\r
+      QhPtr->LastQtdPtr = Cursor;\r
+    }\r
+\r
+    Cursor = Cursor->Next;\r
+  }\r
+\r
+  QtdHwPtr                    = &(QtdPtr->Qtd);\r
+  QhPtr->Qh.NextQtdPointer    = (UINT32) (GET_0B_TO_31B (QtdHwPtr) >> 5);\r
+  QhPtr->Qh.NextQtdTerminate  = FALSE;\r
+\r
+  return ;\r
+}\r
+\r
+EFI_STATUS\r
+LinkQhToAsyncList (\r
+  IN  USB2_HC_DEV       *HcDev,\r
+  IN EHCI_QH_ENTITY     *QhPtr\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Link Qh to Async Schedule List\r
+  \r
+Arguments:\r
+\r
+  HcDev  - USB2_HC_DEV \r
+  QhPtr  - A pointer to Qh\r
+  \r
+Returns:\r
+\r
+  EFI_SUCCESS       Success\r
+  EFI_DEVICE_ERROR  Fail\r
+  \r
+--*/\r
+{\r
+  EFI_STATUS  Status;\r
+\r
+  ASSERT (HcDev);\r
+  ASSERT (QhPtr);\r
+\r
+  QhPtr->Qh.HeadReclamationFlag = TRUE;\r
+\r
+  Status                        = SetAsyncListAddr (HcDev, QhPtr);\r
+  if (EFI_ERROR (Status)) {\r
+    Status = EFI_DEVICE_ERROR;\r
+    goto exit;\r
+  }\r
+\r
+  if (!IsAsyncScheduleEnabled (HcDev)) {\r
+\r
+    Status = EnableAsynchronousSchedule (HcDev);\r
+    if (EFI_ERROR (Status)) {\r
+      Status = EFI_DEVICE_ERROR;\r
+      goto exit;\r
+    }\r
+\r
+    Status = WaitForAsyncScheduleEnable (HcDev, EHCI_GENERIC_TIMEOUT);\r
+    if (EFI_ERROR (Status)) {\r
+      DEBUG ((gEHCDebugLevel, "WaitForAsyncScheduleEnable TimeOut"));\r
+      Status = EFI_TIMEOUT;\r
+      goto exit;\r
+    }\r
+\r
+    if (IsEhcHalted (HcDev)) {\r
+      Status = StartScheduleExecution (HcDev);\r
+      if (EFI_ERROR (Status)) {\r
+        Status = EFI_DEVICE_ERROR;\r
+      }\r
+    }\r
+\r
+  }\r
+\r
+exit:\r
+  return Status;\r
+}\r
+\r
+EFI_STATUS\r
+UnlinkQhFromAsyncList (\r
+  IN USB2_HC_DEV        *HcDev,\r
+  IN EHCI_QH_ENTITY     *QhPtr\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Unlink Qh from Async Schedule List\r
+  \r
+Arguments:\r
+\r
+  HcDev  - USB2_HC_DEV \r
+  QhPtr  - A pointer to Qh\r
+  \r
+Returns:\r
+\r
+  EFI_SUCCESS       Success\r
+  EFI_DEVICE_ERROR  Fail\r
+  \r
+--*/\r
+{\r
+  EFI_STATUS  Status;\r
+\r
+  Status = EFI_SUCCESS;\r
+\r
+  ASSERT (HcDev);\r
+  ASSERT (QhPtr);\r
+\r
+  if (QhPtr == QhPtr->Next) {\r
+\r
+    Status = DisableAsynchronousSchedule (HcDev);\r
+    if (EFI_ERROR (Status)) {\r
+      Status = EFI_DEVICE_ERROR;\r
+      goto exit;\r
+    }\r
+\r
+    Status = WaitForAsyncScheduleDisable (HcDev, EHCI_GENERIC_TIMEOUT);\r
+    if (EFI_ERROR (Status)) {\r
+      DEBUG ((gEHCErrorLevel, "WaitForAsyncScheduleDisable TimeOut\n"));\r
+      Status = EFI_TIMEOUT;\r
+      goto exit;\r
+    }\r
+\r
+  }\r
+\r
+exit:\r
+  return Status;\r
+}\r
+\r
+VOID\r
+LinkQhToPeriodicList (\r
+  IN USB2_HC_DEV        *HcDev,\r
+  IN EHCI_QH_ENTITY     *QhPtr\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Link Qh to Periodic Schedule List\r
+  \r
+Arguments:\r
+\r
+  HcDev  - USB2_HC_DEV \r
+  QhPtr  - A pointer to Qh\r
+  \r
+Returns:\r
+\r
+  VOID\r
+  \r
+--*/\r
+{\r
+  FRAME_LIST_ENTRY  *FrameEntryPtr;\r
+  EHCI_QH_ENTITY    *FindQhPtr;\r
+  EHCI_QH_HW        *FindQhHwPtr;\r
+  UINTN             FrameIndex;\r
+\r
+  ASSERT (HcDev);\r
+  ASSERT (QhPtr);\r
+\r
+  FindQhPtr                     = NULL;\r
+  FindQhHwPtr                   = NULL;\r
+  FrameIndex                    = 0;\r
+  FrameEntryPtr                 = (FRAME_LIST_ENTRY *) HcDev->PeriodicFrameListBuffer;\r
+\r
+  QhPtr->Qh.HeadReclamationFlag = FALSE;\r
+\r
+  if (QhPtr->TransferType == ASYNC_INTERRUPT_TRANSFER) {\r
+       \r
+    //\r
+    // AsyncInterruptTransfer Qh\r
+    //\r
+    \r
+    //\r
+    // Link to Frame[0] List\r
+    //\r
+    if (!FrameEntryPtr->LinkTerminate) {\r
+      //\r
+      // Not Null FrameList\r
+      //\r
+      FindQhHwPtr = (EHCI_QH_HW *) GET_0B_TO_31B (FrameEntryPtr->LinkPointer << 5);\r
+      FindQhPtr   = (EHCI_QH_ENTITY *) GET_QH_ENTITY_ADDR (FindQhHwPtr);\r
+      //\r
+      // FindQh is Left/Right to Qh\r
+      //\r
+      while ((NULL != FindQhPtr->Next) && (FindQhPtr->Interval > QhPtr->Interval)) {\r
+        FindQhPtr = FindQhPtr->Next;\r
+      }\r
+\r
+      if (FindQhPtr->Interval == QhPtr->Interval) {\r
+        //\r
+        // Link Qh after FindQh\r
+        //\r
+        if (NULL != FindQhPtr->Next) {\r
+          FindQhPtr->Next->Prev         = QhPtr;\r
+          QhPtr->Qh.QhHorizontalPointer = (UINT32) GET_0B_TO_31B (&(FindQhPtr->Next->Qh) >> 5);\r
+          QhPtr->Qh.SelectType          = QH_SELECT_TYPE;\r
+          QhPtr->Qh.QhTerminate         = FALSE;\r
+        }\r
+\r
+        FindQhPtr->Qh.QhHorizontalPointer = (UINT32) GET_0B_TO_31B (&(QhPtr->Qh) >> 5);\r
+        FindQhPtr->Qh.SelectType          = QH_SELECT_TYPE;\r
+        FindQhPtr->Qh.QhTerminate         = FALSE;\r
+\r
+        QhPtr->Prev                       = FindQhPtr;\r
+        QhPtr->Next                       = FindQhPtr->Next;\r
+        FindQhPtr->Next                   = QhPtr;\r
+      } else if (FindQhPtr->Interval < QhPtr->Interval) {\r
+        //\r
+        // Link Qh before FindQh\r
+        //\r
+        if (NULL == FindQhPtr->Prev) {\r
+          //\r
+          // Qh is the First one in Frame[0] List\r
+          //\r
+          FrameEntryPtr->LinkPointer    = (UINT32) GET_0B_TO_31B (&(QhPtr->Qh) >> 5);\r
+          FrameEntryPtr->SelectType     = QH_SELECT_TYPE;\r
+          FrameEntryPtr->LinkTerminate  = FALSE;\r
+        } else {\r
+          //\r
+          // Qh is not the First one in Frame[0] List\r
+          //\r
+          FindQhPtr->Prev->Next                   = QhPtr;\r
+          FindQhPtr->Prev->Qh.QhHorizontalPointer = (UINT32) GET_0B_TO_31B (&(QhPtr->Qh) >> 5);\r
+          FindQhPtr->Prev->Qh.SelectType          = QH_SELECT_TYPE;\r
+          FindQhPtr->Prev->Qh.QhTerminate         = FALSE;\r
+        }\r
+\r
+        QhPtr->Qh.QhHorizontalPointer = (UINT32) GET_0B_TO_31B (&(FindQhPtr->Qh) >> 5);\r
+        QhPtr->Qh.SelectType          = QH_SELECT_TYPE;\r
+        QhPtr->Qh.QhTerminate         = FALSE;\r
+\r
+        QhPtr->Next                   = FindQhPtr;\r
+        QhPtr->Prev                   = FindQhPtr->Prev;\r
+        FindQhPtr->Prev               = QhPtr;\r
+      } else {\r
+        //\r
+        // Link Qh after FindQh, Qh is the Last one\r
+        //\r
+        FindQhPtr->Qh.QhHorizontalPointer = (UINT32) GET_0B_TO_31B (&(QhPtr->Qh) >> 5);\r
+        FindQhPtr->Prev->Qh.SelectType    = QH_SELECT_TYPE;\r
+        FindQhPtr->Qh.QhTerminate         = FALSE;\r
+\r
+        QhPtr->Prev                       = FindQhPtr;\r
+        QhPtr->Next                       = NULL;\r
+        FindQhPtr->Next                   = QhPtr;\r
+      }\r
+    } else {\r
+      //\r
+      // Null FrameList\r
+      //\r
+      FrameEntryPtr->LinkPointer    = (UINT32) GET_0B_TO_31B (&(QhPtr->Qh) >> 5);\r
+      FrameEntryPtr->SelectType     = QH_SELECT_TYPE;\r
+      FrameEntryPtr->LinkTerminate  = FALSE;\r
+    }\r
+    //\r
+    // Other Frame[X]\r
+    //\r
+    if (NULL == QhPtr->Prev) {\r
+      //\r
+      // Qh is the First one in Frame[0] List\r
+      //\r
+      FrameIndex += QhPtr->Interval;\r
+      while (FrameIndex < HcDev->PeriodicFrameListLength) {\r
+        FrameEntryPtr                 = (FRAME_LIST_ENTRY *) (FrameEntryPtr + QhPtr->Interval);\r
+        FrameEntryPtr->LinkPointer    = (UINT32) GET_0B_TO_31B (&(QhPtr->Qh) >> 5);\r
+        FrameEntryPtr->SelectType     = QH_SELECT_TYPE;\r
+        FrameEntryPtr->LinkTerminate  = FALSE;\r
+        FrameIndex += QhPtr->Interval;\r
+      }\r
+    } else if (QhPtr->Interval < QhPtr->Prev->Interval) {\r
+      //\r
+      // Qh is not the First one in Frame[0] List, and Prev.interval > Qh.interval\r
+      //\r
+      FrameIndex += QhPtr->Interval;\r
+      while (FrameIndex < HcDev->PeriodicFrameListLength) {\r
+        FrameEntryPtr = (FRAME_LIST_ENTRY *) (FrameEntryPtr + QhPtr->Interval);\r
+        if ((FrameIndex % QhPtr->Prev->Interval) != 0) {\r
+          FrameEntryPtr->LinkPointer    = (UINT32) GET_0B_TO_31B (&(QhPtr->Qh) >> 5);\r
+          FrameEntryPtr->SelectType     = QH_SELECT_TYPE;\r
+          FrameEntryPtr->LinkTerminate  = FALSE;\r
+        }\r
+\r
+        FrameIndex += QhPtr->Interval;\r
+      }\r
+    }\r
+  } else {\r
+  \r
+    //\r
+    // SyncInterruptTransfer Qh\r
+    //\r
+    \r
+    if (!FrameEntryPtr->LinkTerminate) {\r
+      //\r
+      // Not Null FrameList\r
+      //\r
+      FindQhHwPtr = (EHCI_QH_HW *) GET_0B_TO_31B (FrameEntryPtr->LinkPointer << 5);\r
+      FindQhPtr   = (EHCI_QH_ENTITY *) GET_QH_ENTITY_ADDR (FindQhHwPtr);\r
+      //\r
+      // FindQh is Last Qh in the Asynchronous List, Link Qh after FindQh\r
+      //\r
+      while (NULL != FindQhPtr->Next) {\r
+        FindQhPtr = FindQhPtr->Next;\r
+      }\r
+\r
+      FindQhPtr->Qh.QhHorizontalPointer = (UINT32) GET_0B_TO_31B (&(QhPtr->Qh) >> 5);\r
+      FindQhPtr->Qh.SelectType          = QH_SELECT_TYPE;\r
+      FindQhPtr->Qh.QhTerminate         = FALSE;\r
+\r
+      FindQhPtr->Next                   = QhPtr;\r
+      QhPtr->Prev                       = FindQhPtr;\r
+    } else {\r
+      //\r
+      // Null FrameList\r
+      //\r
+      FrameEntryPtr->LinkPointer    = (UINT32) GET_0B_TO_31B (&(QhPtr->Qh) >> 5);\r
+      FrameEntryPtr->SelectType     = QH_SELECT_TYPE;\r
+      FrameEntryPtr->LinkTerminate  = FALSE;\r
+    }\r
+  }\r
+\r
+  return ;\r
+}\r
+\r
+VOID\r
+UnlinkQhFromPeriodicList (\r
+  IN USB2_HC_DEV        *HcDev,\r
+  IN EHCI_QH_ENTITY     *QhPtr,\r
+  IN UINTN              Interval\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Unlink Qh from Periodic Schedule List\r
+  \r
+Arguments:\r
+\r
+  HcDev     - USB2_HC_DEV \r
+  QhPtr     - A pointer to Qh\r
+  Interval  - Interval of this periodic transfer\r
+  \r
+Returns:\r
+\r
+  VOID\r
+  \r
+--*/\r
+{\r
+  FRAME_LIST_ENTRY  *FrameEntryPtr;\r
+  UINTN             FrameIndex;\r
+\r
+  FrameIndex = 0;\r
+\r
+  ASSERT (HcDev);\r
+  ASSERT (QhPtr);\r
+\r
+  FrameIndex    = 0;\r
+  FrameEntryPtr = (FRAME_LIST_ENTRY *) HcDev->PeriodicFrameListBuffer;\r
+\r
+  if (QhPtr->TransferType == ASYNC_INTERRUPT_TRANSFER) {\r
+  \r
+    //\r
+    // AsyncInterruptTransfer Qh\r
+    //\r
+    \r
+    if (NULL == QhPtr->Prev) {\r
+      //\r
+      // Qh is the First one on  Frame[0] List\r
+      //\r
+      if (NULL == QhPtr->Next) {\r
+        //\r
+        // Only one on  Frame[0] List\r
+        //\r
+        while (FrameIndex < HcDev->PeriodicFrameListLength) {\r
+          FrameEntryPtr->LinkPointer    = 0;\r
+          FrameEntryPtr->SelectType     = 0;\r
+          FrameEntryPtr->LinkTerminate  = TRUE;\r
+          FrameEntryPtr                += Interval;\r
+          FrameIndex                   += Interval;\r
+        }\r
+      } else {\r
+        while (FrameIndex < HcDev->PeriodicFrameListLength) {\r
+          FrameEntryPtr->LinkPointer    = (UINT32) GET_0B_TO_31B (&(QhPtr->Next->Qh) >> 5);\r
+          FrameEntryPtr->SelectType     = QH_SELECT_TYPE;\r
+          FrameEntryPtr->LinkTerminate  = FALSE;\r
+          FrameEntryPtr += Interval;\r
+          FrameIndex += Interval;\r
+        }\r
+      }\r
+    } else {\r
+    \r
+      //\r
+      // Not First one on  Frame[0] List\r
+      //\r
+      if (NULL == QhPtr->Next) {\r
+        //\r
+        // Qh is the Last one on  Frame[0] List\r
+        //\r
+        QhPtr->Prev->Qh.QhHorizontalPointer = 0;\r
+        QhPtr->Prev->Qh.SelectType          = 0;\r
+        QhPtr->Prev->Qh.QhTerminate         = TRUE;\r
+      } else {\r
+        QhPtr->Prev->Qh.QhHorizontalPointer = (UINT32) GET_0B_TO_31B (&(QhPtr->Next->Qh) >> 5);\r
+        QhPtr->Prev->Qh.SelectType          = QH_SELECT_TYPE;\r
+        QhPtr->Prev->Qh.QhTerminate         = FALSE;\r
+      }\r
+\r
+      if (Interval == QhPtr->Prev->Interval) {\r
+        //\r
+        // Interval is the same as Prev\r
+        // Not involed Frame[X]\r
+        //\r
+      } else {\r
+        //\r
+        // Other Frame[X]\r
+        //\r
+        while (FrameIndex < HcDev->PeriodicFrameListLength) {\r
+          if ((FrameIndex % QhPtr->Prev->Interval) != 0) {\r
+            FrameEntryPtr->LinkPointer    = QhPtr->Prev->Qh.QhHorizontalPointer;\r
+            FrameEntryPtr->SelectType     = QhPtr->Prev->Qh.SelectType;\r
+            FrameEntryPtr->LinkTerminate  = QhPtr->Prev->Qh.QhTerminate;\r
+          }\r
+          FrameEntryPtr += Interval;\r
+          FrameIndex += Interval;\r
+        }\r
+      }\r
+    }\r
+\r
+    if (NULL != QhPtr->Next) {\r
+      QhPtr->Next->Prev = QhPtr->Prev;\r
+    }\r
+\r
+    if (NULL != QhPtr->Prev) {\r
+      QhPtr->Prev->Next = QhPtr->Next;\r
+    }\r
+  } else {\r
+    //\r
+    // SyncInterruptTransfer Qh\r
+    //\r
+    if (NULL == QhPtr->Prev) {\r
+      //\r
+      // Qh is the only one Qh on  Frame[0] List\r
+      //\r
+      FrameEntryPtr->LinkPointer    = 0;\r
+      FrameEntryPtr->SelectType     = 0;\r
+      FrameEntryPtr->LinkTerminate  = TRUE;\r
+    } else {\r
+      QhPtr->Prev->Qh.QhHorizontalPointer = 0;\r
+      QhPtr->Prev->Qh.SelectType          = 0;\r
+      QhPtr->Prev->Qh.QhTerminate         = TRUE;\r
+    }\r
+\r
+    if (NULL != QhPtr->Prev) {\r
+      QhPtr->Prev->Next = NULL;\r
+    }\r
+  }\r
+\r
+  return ;\r
+}\r
+\r
+VOID\r
+LinkToAsyncReqeust (\r
+  IN  USB2_HC_DEV        *HcDev,\r
+  IN  EHCI_ASYNC_REQUEST *AsyncRequestPtr\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Llink AsyncRequest Entry to Async Request List\r
+  \r
+Arguments:\r
+\r
+  HcDev             - USB2_HC_DEV \r
+  AsyncRequestPtr   - A pointer to Async Request Entry\r
+  \r
+Returns:\r
+\r
+  VOID\r
+  \r
+--*/\r
+{\r
+  EHCI_ASYNC_REQUEST  *CurrentPtr;\r
+\r
+  CurrentPtr              = HcDev->AsyncRequestList;\r
+  HcDev->AsyncRequestList = AsyncRequestPtr;\r
+  AsyncRequestPtr->Prev   = NULL;\r
+  AsyncRequestPtr->Next   = CurrentPtr;\r
+\r
+  if (NULL != CurrentPtr) {\r
+    CurrentPtr->Prev = AsyncRequestPtr;\r
+  }\r
+\r
+  return ;\r
+}\r
+\r
+VOID\r
+UnlinkFromAsyncReqeust (\r
+  IN  USB2_HC_DEV        *HcDev,\r
+  IN  EHCI_ASYNC_REQUEST *AsyncRequestPtr\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Unlink AsyncRequest Entry from Async Request List\r
+  \r
+Arguments:\r
+\r
+  HcDev            - USB2_HC_DEV \r
+  AsyncRequestPtr  - A pointer to Async Request Entry\r
+  \r
+Returns:\r
+\r
+  VOID\r
+  \r
+--*/\r
+{\r
+  if (NULL == AsyncRequestPtr->Prev) {\r
+    HcDev->AsyncRequestList = AsyncRequestPtr->Next;\r
+    if (NULL != AsyncRequestPtr->Next) {\r
+      AsyncRequestPtr->Next->Prev = NULL;\r
+    }\r
+  } else {\r
+    AsyncRequestPtr->Prev->Next = AsyncRequestPtr->Next;\r
+    if (NULL != AsyncRequestPtr->Next) {\r
+      AsyncRequestPtr->Next->Prev = AsyncRequestPtr->Prev;\r
+    }\r
+  }\r
+\r
+  return ;\r
+}\r
+\r
+VOID\r
+SetQtdBufferPointer (\r
+  IN EHCI_QTD_HW  *QtdHwPtr,\r
+  IN VOID         *DataPtr,\r
+  IN UINTN        DataLen\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Set data buffer pointers in Qtd\r
+\r
+Arguments:\r
+\r
+  QtdHwPtr  - A pointer to Qtd hardware structure \r
+  DataPtr   - A pointer to user data buffer\r
+  DataLen   - Length of the user data buffer\r
+    \r
+Returns:\r
+\r
+  VOID\r
+\r
+--*/\r
+{\r
+  UINTN RemainLen;\r
+\r
+  RemainLen = DataLen;\r
+  ASSERT (QtdHwPtr);\r
+\r
+  //\r
+  // Set BufferPointer0, ExtBufferPointer0 and Offset\r
+  //\r
+  QtdHwPtr->BufferPointer0    = (UINT32) (GET_0B_TO_31B (DataPtr) >> 12);\r
+  QtdHwPtr->CurrentOffset     = (UINT32) (GET_0B_TO_31B (DataPtr) & EFI_PAGE_MASK);\r
+  QtdHwPtr->ExtBufferPointer0 = (UINT32) GET_32B_TO_63B (DataPtr);\r
+\r
+  //\r
+  // Set BufferPointer1 and ExtBufferPointer1\r
+  //\r
+  RemainLen = RemainLen > (EFI_PAGE_SIZE - QtdHwPtr->CurrentOffset) ? (RemainLen - (EFI_PAGE_SIZE - QtdHwPtr->CurrentOffset)) : 0;\r
+  if (RemainLen == 0) {\r
+    goto exit;\r
+  }\r
+\r
+  QtdHwPtr->BufferPointer1    = QtdHwPtr->BufferPointer0 + 1;\r
+  QtdHwPtr->ExtBufferPointer1 = QtdHwPtr->ExtBufferPointer0;\r
+\r
+  //\r
+  // Set BufferPointer2 and ExtBufferPointer2\r
+  //\r
+  RemainLen = RemainLen > EFI_PAGE_SIZE ? (RemainLen - EFI_PAGE_SIZE) : 0;\r
+  if (RemainLen == 0) {\r
+    goto exit;\r
+  }\r
+\r
+  QtdHwPtr->BufferPointer2    = QtdHwPtr->BufferPointer1 + 1;\r
+  QtdHwPtr->ExtBufferPointer2 = QtdHwPtr->ExtBufferPointer0;\r
+\r
+  //\r
+  // Set BufferPointer3 and ExtBufferPointer3\r
+  //\r
+  RemainLen = RemainLen > EFI_PAGE_SIZE ? (RemainLen - EFI_PAGE_SIZE) : 0;\r
+  if (RemainLen == 0) {\r
+    goto exit;\r
+  }\r
+\r
+  QtdHwPtr->BufferPointer3    = QtdHwPtr->BufferPointer2 + 1;\r
+  QtdHwPtr->ExtBufferPointer3 = QtdHwPtr->ExtBufferPointer0;\r
+\r
+  //\r
+  // Set BufferPointer4 and ExtBufferPointer4\r
+  //\r
+  RemainLen = RemainLen > EFI_PAGE_SIZE ? (RemainLen - EFI_PAGE_SIZE) : 0;\r
+  if (RemainLen == 0) {\r
+    goto exit;\r
+  }\r
+\r
+  QtdHwPtr->BufferPointer4    = QtdHwPtr->BufferPointer3 + 1;\r
+  QtdHwPtr->ExtBufferPointer4 = QtdHwPtr->ExtBufferPointer0;\r
+\r
+exit:\r
+  return ;\r
+}\r
+\r
+BOOLEAN\r
+IsQtdStatusActive (\r
+  IN EHCI_QTD_HW  *HwQtdPtr\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Whether Qtd status is active or not\r
+  \r
+Arguments:\r
+\r
+  HwQtdPtr - A pointer to hardware Qtd structure\r
+  \r
+Returns:\r
+\r
+  TRUE    Active\r
+  FALSE   Inactive\r
+  \r
+--*/\r
+{\r
+  UINT8   QtdStatus;\r
+  BOOLEAN Value;\r
+\r
+  QtdStatus = (UINT8) (HwQtdPtr->Status);\r
+  Value     = (BOOLEAN) (QtdStatus & QTD_STATUS_ACTIVE);\r
+\r
+  return Value;\r
+}\r
+\r
+BOOLEAN\r
+IsQtdStatusHalted (\r
+  IN EHCI_QTD_HW  *HwQtdPtr\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Whether Qtd status is halted or not\r
+  \r
+Arguments:\r
+\r
+  HwQtdPtr - A pointer to hardware Qtd structure\r
+  \r
+Returns:\r
+\r
+  TRUE    Halted\r
+  FALSE   Not halted\r
+  \r
+--*/\r
+{\r
+  UINT8   QtdStatus;\r
+  BOOLEAN Value;\r
+\r
+  QtdStatus = (UINT8) (HwQtdPtr->Status);\r
+  Value     = (BOOLEAN) (QtdStatus & QTD_STATUS_HALTED);\r
+\r
+  return Value;\r
+}\r
+\r
+BOOLEAN\r
+IsQtdStatusBufferError (\r
+  IN EHCI_QTD_HW  *HwQtdPtr\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Whether Qtd status is buffer error or not\r
+  \r
+Arguments:\r
+\r
+  HwQtdPtr - A pointer to hardware Qtd structure\r
+  \r
+Returns:\r
+\r
+  TRUE    Buffer error\r
+  FALSE   No buffer error\r
+  \r
+--*/\r
+{\r
+  UINT8   QtdStatus;\r
+  BOOLEAN Value;\r
+\r
+  QtdStatus = (UINT8) (HwQtdPtr->Status);\r
+  Value     = (BOOLEAN) (QtdStatus & QTD_STATUS_BUFFER_ERR);\r
+\r
+  return Value;\r
+}\r
+\r
+BOOLEAN\r
+IsQtdStatusBabbleError (\r
+  IN EHCI_QTD_HW  *HwQtdPtr\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Whether Qtd status is babble error or not\r
+  \r
+Arguments:\r
+\r
+  HwQtdPtr - A pointer to hardware Qtd structure\r
+  \r
+Returns:\r
+\r
+  TRUE    Babble error\r
+  FALSE   No babble error\r
+  \r
+--*/\r
+{\r
+  UINT8   QtdStatus;\r
+  BOOLEAN Value;\r
+\r
+  QtdStatus = (UINT8) (HwQtdPtr->Status);\r
+  Value     = (BOOLEAN) (QtdStatus & QTD_STATUS_BABBLE_ERR);\r
+\r
+  return Value;\r
+}\r
+\r
+BOOLEAN\r
+IsQtdStatusTransactionError (\r
+  IN EHCI_QTD_HW  *HwQtdPtr\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Whether Qtd status is transaction error or not\r
+  \r
+Arguments:\r
+\r
+  HwQtdPtr - A pointer to hardware Qtd structure\r
+  \r
+Returns:\r
+\r
+  TRUE    Transaction error\r
+  FALSE   No transaction error\r
+  \r
+--*/\r
+{\r
+  UINT8   QtdStatus;\r
+  BOOLEAN Value;\r
+\r
+  QtdStatus = (UINT8) (HwQtdPtr->Status);\r
+  Value     = (BOOLEAN) (QtdStatus & QTD_STATUS_TRANSACTION_ERR);\r
+\r
+  return Value;\r
+}\r
+\r
+BOOLEAN\r
+IsDataInTransfer (\r
+  IN UINT8     EndPointAddress\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Whether is a DataIn direction transfer\r
+  \r
+Arguments:\r
+\r
+  EndPointAddress - address of the endpoint \r
+  \r
+Returns:\r
+\r
+  TRUE    DataIn\r
+  FALSE   DataOut\r
+  \r
+--*/\r
+{\r
+  BOOLEAN Value;\r
+\r
+  if (EndPointAddress & 0x80) {\r
+    Value = TRUE;\r
+  } else {\r
+    Value = FALSE;\r
+  }\r
+\r
+  return Value;\r
+}\r
+\r
+EFI_STATUS\r
+MapDataBuffer (\r
+  IN  USB2_HC_DEV             *HcDev,\r
+  IN  EFI_USB_DATA_DIRECTION  TransferDirection,\r
+  IN  VOID                    *Data,\r
+  IN  OUT UINTN               *DataLength,\r
+  OUT UINT8                   *PktId,\r
+  OUT UINT8                   **DataCursor,\r
+  OUT VOID                    **DataMap\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Map address of user data buffer\r
+  \r
+Arguments:\r
+\r
+  HcDev              - USB2_HC_DEV \r
+  TransferDirection  - direction of transfer\r
+  Data               - A pointer to user data buffer \r
+  DataLength         - length of user data\r
+  PktId              - Packte Identificaion\r
+  DataCursor         - mapped address to return\r
+  DataMap            - identificaion of this mapping to return\r
+  \r
+Returns:\r
+\r
+  EFI_SUCCESS        Success\r
+  EFI_DEVICE_ERROR   Fail\r
+    \r
+--*/\r
+{\r
+  EFI_STATUS            Status;\r
+  EFI_PHYSICAL_ADDRESS  TempPhysicalAddr;\r
+\r
+  Status = EFI_SUCCESS;\r
+\r
+  switch (TransferDirection) {\r
+\r
+  case EfiUsbDataIn:\r
+\r
+    *PktId = INPUT_PACKET_ID;\r
+    //\r
+    // BusMasterWrite means cpu read\r
+    //\r
+    Status = HcDev->PciIo->Map (\r
+                            HcDev->PciIo,\r
+                            EfiPciIoOperationBusMasterWrite,\r
+                            Data,\r
+                            DataLength,\r
+                            &TempPhysicalAddr,\r
+                            DataMap\r
+                            );\r
+    if (EFI_ERROR (Status)) {\r
+      DEBUG ((gEHCDebugLevel, "MapDataBuffer Failed\n"));\r
+      Status = EFI_DEVICE_ERROR;\r
+      goto exit;\r
+    }\r
+\r
+    *DataCursor = (UINT8 *) ((UINTN) TempPhysicalAddr);\r
+    break;\r
+\r
+  case EfiUsbDataOut:\r
+\r
+    *PktId = OUTPUT_PACKET_ID;\r
+    //\r
+    // BusMasterRead means cpu write\r
+    //\r
+    Status = HcDev->PciIo->Map (\r
+                            HcDev->PciIo,\r
+                            EfiPciIoOperationBusMasterRead,\r
+                            Data,\r
+                            DataLength,\r
+                            &TempPhysicalAddr,\r
+                            DataMap\r
+                            );\r
+    if (EFI_ERROR (Status)) {\r
+      Status = EFI_DEVICE_ERROR;\r
+      goto exit;\r
+    }\r
+\r
+    *DataCursor = (UINT8 *) ((UINTN) TempPhysicalAddr);\r
+    break;\r
+\r
+  case EfiUsbNoData:\r
+\r
+    *PktId      = OUTPUT_PACKET_ID;\r
+    Data        = NULL;\r
+    *DataLength = 0;\r
+    *DataCursor = NULL;\r
+    *DataMap    = NULL;\r
+    break;\r
+\r
+  default:\r
+       \r
+    Status = EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+exit:\r
+  return Status;\r
+}\r
+\r
+EFI_STATUS\r
+MapRequestBuffer (\r
+  IN  USB2_HC_DEV             *HcDev,\r
+  IN  OUT VOID                *Request,\r
+  OUT UINT8                   **RequestCursor,\r
+  OUT VOID                    **RequestMap\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Map address of request structure buffer\r
+  \r
+Arguments:\r
+\r
+  HcDev           - USB2_HC_DEV \r
+  Request         - A pointer to request structure\r
+  RequestCursor   - Mapped address of request structure to return\r
+  RequestMap      - Identificaion of this mapping to return\r
+  \r
+Returns:\r
+\r
+  EFI_SUCCESS        Success\r
+  EFI_DEVICE_ERROR   Fail\r
+    \r
+--*/\r
+{\r
+  EFI_STATUS            Status;\r
+  UINTN                 RequestLen;\r
+  EFI_PHYSICAL_ADDRESS  TempPhysicalAddr;\r
+\r
+  RequestLen = sizeof (EFI_USB_DEVICE_REQUEST);\r
+  Status = HcDev->PciIo->Map (\r
+                           HcDev->PciIo,\r
+                           EfiPciIoOperationBusMasterRead,\r
+                           (UINT8 *) Request,\r
+                           (UINTN *) &RequestLen,\r
+                           &TempPhysicalAddr,\r
+                           RequestMap\r
+                           );\r
+  if (EFI_ERROR (Status)) {\r
+    Status = EFI_DEVICE_ERROR;\r
+    goto exit;\r
+  }\r
+\r
+  *RequestCursor = (UINT8 *) ((UINTN) TempPhysicalAddr);\r
+\r
+exit:\r
+  return Status;\r
+}\r
+\r
+EFI_STATUS\r
+DeleteAsyncRequestTransfer (\r
+  IN  USB2_HC_DEV     *HcDev,\r
+  IN  UINT8           DeviceAddress,\r
+  IN  UINT8           EndPointAddress,\r
+  OUT UINT8           *DataToggle\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Delete all asynchronous request transfer\r
+  \r
+Arguments:\r
+\r
+  HcDev           - USB2_HC_DEV \r
+  DeviceAddress   - address of usb device\r
+  EndPointAddress - address of endpoint\r
+  DataToggle      - stored data toggle\r
+  \r
+Returns:\r
+\r
+  EFI_SUCCESS        Success\r
+  EFI_DEVICE_ERROR   Fail\r
+    \r
+--*/\r
+{\r
+  EFI_STATUS          Status;\r
+  EHCI_ASYNC_REQUEST  *AsyncRequestPtr;\r
+  EHCI_ASYNC_REQUEST  *MatchPtr;\r
+  EHCI_QH_HW          *QhHwPtr;\r
+  UINT8               EndPointNum;\r
+\r
+  if (NULL == HcDev->AsyncRequestList) {\r
+    Status = EFI_INVALID_PARAMETER;\r
+    goto exit;\r
+  }\r
+\r
+  MatchPtr        = NULL;\r
+  QhHwPtr         = NULL;\r
+  EndPointNum     = EndPointAddress & 0x0f;\r
+  AsyncRequestPtr = HcDev->AsyncRequestList;\r
+\r
+  //\r
+  // Find QH of AsyncRequest by DeviceAddress and EndPointNum\r
+  //\r
+  do {\r
+\r
+    QhHwPtr = &(AsyncRequestPtr->QhPtr->Qh);\r
+    if (QhHwPtr->DeviceAddr == DeviceAddress && QhHwPtr->EndpointNum == EndPointNum) {\r
+      MatchPtr = AsyncRequestPtr;\r
+      break;\r
+    }\r
+\r
+    AsyncRequestPtr = AsyncRequestPtr->Next;\r
+\r
+  } while (NULL != AsyncRequestPtr);\r
+\r
+  if (NULL == MatchPtr) {\r
+    Status = EFI_INVALID_PARAMETER;\r
+    goto exit;\r
+  }\r
+\r
+  Status = DisablePeriodicSchedule (HcDev);\r
+  if (EFI_ERROR (Status)) {\r
+    Status = EFI_DEVICE_ERROR;\r
+    goto exit;\r
+  }\r
+\r
+  Status = WaitForPeriodicScheduleDisable (HcDev, EHCI_GENERIC_TIMEOUT);\r
+  if (EFI_ERROR (Status)) {\r
+    DEBUG ((gEHCErrorLevel, "WaitForPeriodicScheduleDisable TimeOut\n"));\r
+    Status = EFI_TIMEOUT;\r
+    goto exit;\r
+  }\r
+\r
+  *DataToggle = (UINT8) MatchPtr->QhPtr->Qh.DataToggle;\r
+  UnlinkQhFromPeriodicList (HcDev, MatchPtr->QhPtr, MatchPtr->QhPtr->Interval);\r
+  UnlinkFromAsyncReqeust (HcDev, MatchPtr);\r
+\r
+  if (NULL == HcDev->AsyncRequestList) {\r
+\r
+    Status = StopPollingTimer (HcDev);\r
+    if (EFI_ERROR (Status)) {\r
+      Status = EFI_DEVICE_ERROR;\r
+      goto exit;\r
+    }\r
+\r
+  } else {\r
+\r
+    Status = EnablePeriodicSchedule (HcDev);\r
+    if (EFI_ERROR (Status)) {\r
+      Status = EFI_DEVICE_ERROR;\r
+      goto exit;\r
+    }\r
+\r
+    Status = WaitForPeriodicScheduleEnable (HcDev, EHCI_GENERIC_TIMEOUT);\r
+    if (EFI_ERROR (Status)) {\r
+      DEBUG ((gEHCErrorLevel, "WaitForPeriodicScheduleEnable TimeOut\n"));\r
+      Status = EFI_TIMEOUT;\r
+      goto exit;\r
+    }\r
+\r
+    if (IsEhcHalted (HcDev)) {\r
+      Status = StartScheduleExecution (HcDev);\r
+      if (EFI_ERROR (Status)) {\r
+        Status = EFI_DEVICE_ERROR;\r
+        goto exit;\r
+      }\r
+    }\r
+\r
+  }\r
+\r
+  DestoryQtds (HcDev, MatchPtr->QhPtr->FirstQtdPtr);\r
+  DestoryQh (HcDev, MatchPtr->QhPtr);\r
+  EhciFreePool (HcDev, (UINT8 *) MatchPtr, sizeof (EHCI_ASYNC_REQUEST));\r
+\r
+exit:\r
+  return Status;\r
+}\r
+\r
+VOID\r
+CleanUpAllAsyncRequestTransfer (\r
+  IN USB2_HC_DEV  *HcDev\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Clean up all asynchronous request transfer\r
+  \r
+Arguments:\r
+\r
+  HcDev - USB2_HC_DEV \r
+  \r
+Returns:\r
+\r
+  VOID\r
+  \r
+--*/\r
+{\r
+  EHCI_ASYNC_REQUEST  *AsyncRequestPtr;\r
+  EHCI_ASYNC_REQUEST  *FreePtr;\r
+\r
+  AsyncRequestPtr = NULL;\r
+  FreePtr         = NULL;\r
+\r
+  StopPollingTimer (HcDev);\r
+\r
+  AsyncRequestPtr = HcDev->AsyncRequestList;\r
+  while (NULL != AsyncRequestPtr) {\r
+\r
+    FreePtr         = AsyncRequestPtr;\r
+    AsyncRequestPtr = AsyncRequestPtr->Next;\r
+    UnlinkFromAsyncReqeust (HcDev, FreePtr);\r
+    UnlinkQhFromPeriodicList (HcDev, FreePtr->QhPtr, FreePtr->QhPtr->Interval);\r
+    DestoryQtds (HcDev, FreePtr->QhPtr->FirstQtdPtr);\r
+    DestoryQh (HcDev, FreePtr->QhPtr);\r
+    EhciFreePool (HcDev, (UINT8 *) FreePtr, sizeof (EHCI_ASYNC_REQUEST));\r
+\r
+  }\r
+\r
+  return ;\r
+}\r
+\r
+VOID\r
+ZeroOutQhOverlay (\r
+  IN EHCI_QH_ENTITY  *QhPtr\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Zero out the fields in Qh structure\r
+  \r
+Arguments:\r
+\r
+  QhPtr - A pointer to Qh structure\r
+  \r
+Returns:\r
+\r
+  VOID\r
+  \r
+--*/\r
+{\r
+  QhPtr->Qh.CurrentQtdPointer   = 0;\r
+  QhPtr->Qh.AltNextQtdPointer   = 0;\r
+  QhPtr->Qh.NakCount            = 0;\r
+  QhPtr->Qh.AltNextQtdTerminate = 0;\r
+  QhPtr->Qh.TotalBytes          = 0;\r
+  QhPtr->Qh.InterruptOnComplete = 0;\r
+  QhPtr->Qh.CurrentPage         = 0;\r
+  QhPtr->Qh.ErrorCount          = 0;\r
+  QhPtr->Qh.PidCode             = 0;\r
+  QhPtr->Qh.Status              = 0;\r
+  QhPtr->Qh.BufferPointer0      = 0;\r
+  QhPtr->Qh.CurrentOffset       = 0;\r
+  QhPtr->Qh.BufferPointer1      = 0;\r
+  QhPtr->Qh.CompleteSplitMask   = 0;\r
+  QhPtr->Qh.BufferPointer2      = 0;\r
+  QhPtr->Qh.SplitBytes          = 0;\r
+  QhPtr->Qh.FrameTag            = 0;\r
+  QhPtr->Qh.BufferPointer3      = 0;\r
+  QhPtr->Qh.BufferPointer4      = 0;\r
+  QhPtr->Qh.ExtBufferPointer0   = 0;\r
+  QhPtr->Qh.ExtBufferPointer1   = 0;\r
+  QhPtr->Qh.ExtBufferPointer2   = 0;\r
+  QhPtr->Qh.ExtBufferPointer3   = 0;\r
+  QhPtr->Qh.ExtBufferPointer4   = 0;\r
+}\r
+\r
+VOID\r
+UpdateAsyncRequestTransfer (\r
+  IN EHCI_ASYNC_REQUEST *AsyncRequestPtr,\r
+  IN UINT32             TransferResult,\r
+  IN UINTN              ErrQtdPos\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Update asynchronous request transfer\r
+  \r
+Arguments:\r
+\r
+  AsyncRequestPtr  - A pointer to async request  \r
+  TransferResult   - transfer result \r
+  ErrQtdPos        - postion of error Qtd\r
+  \r
+Returns:\r
+\r
+  VOID\r
+  \r
+--*/\r
+{\r
+  EHCI_QTD_ENTITY *QtdPtr;\r
+\r
+  QtdPtr      = NULL;\r
+\r
+  if (EFI_USB_NOERROR == TransferResult) {\r
+  \r
+    //\r
+    // Update Qh for next trigger\r
+    //\r
+\r
+    QtdPtr = AsyncRequestPtr->QhPtr->FirstQtdPtr;\r
+\r
+    //\r
+    // Update fields in Qh\r
+    //\r
+\r
+    //\r
+    // Get DataToggle from Overlay in Qh\r
+    //\r
+    // ZeroOut Overlay in Qh except DataToggle, HostController will update this field\r
+    //\r
+    ZeroOutQhOverlay (AsyncRequestPtr->QhPtr);\r
+    AsyncRequestPtr->QhPtr->Qh.NextQtdPointer   = (UINT32) (GET_0B_TO_31B (&(QtdPtr->Qtd)) >> 5);\r
+    AsyncRequestPtr->QhPtr->Qh.NextQtdTerminate = FALSE;\r
+\r
+    //\r
+    // Update fields in Qtd\r
+    //\r
+    while (NULL != QtdPtr) {\r
+      QtdPtr->Qtd.TotalBytes    = QtdPtr->StaticTotalBytes;\r
+      QtdPtr->Qtd.CurrentOffset = QtdPtr->StaticCurrentOffset;\r
+      QtdPtr->Qtd.CurrentPage   = 0;\r
+      QtdPtr->Qtd.ErrorCount    = QTD_ERROR_COUNTER;\r
+      QtdPtr->Qtd.Status        = QTD_STATUS_ACTIVE;\r
+\r
+      QtdPtr->TotalBytes        = QtdPtr->StaticTotalBytes;\r
+      QtdPtr                    = QtdPtr->Next;\r
+    }\r
+  }\r
+\r
+  return ;\r
+}\r
+\r
+BOOLEAN\r
+CheckQtdsTransferResult (\r
+  IN  BOOLEAN            IsControl,\r
+  IN  EHCI_QH_ENTITY     *QhPtr,\r
+  OUT UINT32             *Result,\r
+  OUT UINTN              *ErrQtdPos,\r
+  OUT UINTN              *ActualLen\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Check transfer result of Qtds\r
+\r
+Arguments:\r
+\r
+  IsControl    - Is control transfer or not\r
+  QhPtr        - A pointer to Qh\r
+  Result       - Transfer result\r
+  ErrQtdPos    - Error TD Position\r
+  ActualLen    - Actual Transfer Size\r
+\r
+Returns:\r
+\r
+  TRUE    Qtds finished\r
+  FALSE   Not finish\r
+  \r
+--*/\r
+{\r
+  UINTN           ActualLenPerQtd;\r
+  EHCI_QTD_ENTITY *QtdPtr;\r
+  EHCI_QTD_HW     *QtdHwPtr;\r
+  BOOLEAN         Value;\r
+\r
+  ASSERT (QhPtr);\r
+  ASSERT (Result);\r
+  ASSERT (ErrQtdPos);\r
+  ASSERT (ActualLen);\r
+\r
+  Value     = TRUE;\r
+  QtdPtr    = QhPtr->FirstQtdPtr;\r
+  QtdHwPtr  = &(QtdPtr->Qtd);\r
+\r
+  while (NULL != QtdHwPtr) {\r
+\r
+    if (IsQtdStatusActive (QtdHwPtr)) {\r
+      *Result |= EFI_USB_ERR_NOTEXECUTE;\r
+    }\r
+\r
+    if (IsQtdStatusHalted (QtdHwPtr)) {\r
+      *Result |= EFI_USB_ERR_STALL;\r
+    }\r
+\r
+    if (IsQtdStatusBufferError (QtdHwPtr)) {\r
+      *Result |= EFI_USB_ERR_BUFFER;\r
+    }\r
+\r
+    if (IsQtdStatusBabbleError (QtdHwPtr)) {\r
+      *Result |= EFI_USB_ERR_BABBLE;\r
+    }\r
+\r
+    if (IsQtdStatusTransactionError (QtdHwPtr)) {\r
+      *Result |= EFI_USB_ERR_TIMEOUT;\r
+    }\r
+\r
+    ActualLenPerQtd     = QtdPtr->TotalBytes - QtdHwPtr->TotalBytes;\r
+    QtdPtr->TotalBytes  = QtdHwPtr->TotalBytes;\r
+    //\r
+    // Accumulate actual transferred data length in each DataQtd.\r\r
+    //\r
+    if (SETUP_PACKET_PID_CODE != QtdHwPtr->PidCode) {\r
+      *ActualLen += ActualLenPerQtd;\r
+    }\r
+\r
+    if (*Result) {\r
+      Value = FALSE;\r
+      break;\r
+    }\r
+\r
+    if ((!IsControl) && (QtdPtr->TotalBytes > 0)) {\r
+      //\r
+      // Did something, but isn't full workload\r
+      //\r
+      break;\r
+    }\r
+\r
+    (*ErrQtdPos)++;\r
+    QtdHwPtr = GetQtdNextPointer (QtdHwPtr);\r
+    QtdPtr = (EHCI_QTD_ENTITY *) GET_QTD_ENTITY_ADDR (QtdHwPtr);\r
+\r
+  }\r
+\r
+  return Value;\r
+}\r
+\r
+EFI_STATUS\r
+ExecuteTransfer (\r
+  IN  USB2_HC_DEV         *HcDev,\r
+  IN  BOOLEAN             IsControl,\r
+  IN  EHCI_QH_ENTITY      *QhPtr,\r
+  IN  OUT UINTN           *ActualLen,\r
+  OUT UINT8               *DataToggle,\r
+  IN  UINTN               TimeOut,\r
+  OUT UINT32              *TransferResult\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Execute Bulk or SyncInterrupt Transfer\r
+\r
+Arguments:\r
+\r
+  HcDev            - USB2_HC_DEV\r
+  IsControl        - Is control transfer or not\r
+  QhPtr            - A pointer to Qh\r
+  ActualLen        - Actual transfered Len \r
+  DataToggle       - Data Toggle\r
+  TimeOut          - TimeOut threshold\r
+  TransferResult   - Transfer result\r
+  \r
+Returns:\r
+\r
+  EFI_SUCCESS      Sucess\r
+  EFI_DEVICE_ERROR Fail\r
+  \r
+--*/\r
+{\r
+  EFI_STATUS  Status;\r
+  UINTN       ErrQtdPos;\r
+  UINTN       Delay;\r
+  UINTN       RequireLen;\r
+  BOOLEAN     Finished;\r
+\r
+  Status          = EFI_SUCCESS;\r
+  ErrQtdPos       = 0;\r
+  *TransferResult = EFI_USB_NOERROR;\r
+  RequireLen      = *ActualLen;\r
+  *ActualLen      = 0;\r
+  Finished        = FALSE;\r
+\r
+  Delay           = (TimeOut * STALL_1_MILLI_SECOND / 50) + 1;\r
+\r
+  do {\r
+    *TransferResult = 0;\r
+    Finished = CheckQtdsTransferResult (\r
+                 IsControl,\r
+                 QhPtr,\r
+                 TransferResult,\r
+                 &ErrQtdPos,\r
+                 ActualLen\r
+                 );\r
+    if (Finished) {\r
+      break;\r
+    }\r
+    //\r
+    // Qtd is inactive, which means bulk or interrupt transfer's end.\r
+    //\r
+    if (!(*TransferResult & EFI_USB_ERR_NOTEXECUTE)) {\r
+      break;\r
+    }\r
+\r
+    gBS->Stall (EHCI_SYNC_REQUEST_POLLING_TIME);\r
+\r
+  } while (--Delay);\r
+\r
+  if (EFI_USB_NOERROR != *TransferResult) {\r
+    if (0 == Delay) {\r
+      Status = EFI_TIMEOUT;\r
+    } else {\r
+      Status = EFI_DEVICE_ERROR;\r
+    }\r
+  }\r
+\r
+  //\r
+  // Special for Bulk and Interrupt Transfer\r
+  //\r
+  *DataToggle = (UINT8) QhPtr->Qh.DataToggle;\r
+  \r
+  return Status;\r
+}\r
+\r
+EFI_STATUS\r
+AsyncRequestMoniter (\r
+  IN EFI_EVENT     Event,\r
+  IN VOID          *Context\r
+  )\r
+/*++\r
+Routine Description:\r
+  \r
+  Interrupt transfer periodic check handler\r
+    \r
+Arguments:\r
+  Event    - Interrupt event\r
+  Context  - Pointer to USB2_HC_DEV\r
+    \r
+Returns:\r
+\r
+  EFI_SUCCESS        Success\r
+  EFI_DEVICE_ERROR   Fail\r
+  \r
+--*/\r
+{\r
+  EFI_STATUS          Status;\r
+  USB2_HC_DEV         *HcDev;\r
+  EHCI_ASYNC_REQUEST  *AsyncRequestPtr;\r
+  EHCI_QTD_HW         *QtdHwPtr;\r
+  UINTN               ErrQtdPos;\r
+  UINTN               ActualLen;\r
+  UINT32              TransferResult;\r
+  UINT8               *ReceiveBuffer;\r
+  UINT8               *ProcessBuffer;\r
+\r
+  Status          = EFI_SUCCESS;\r
+  QtdHwPtr        = NULL;\r
+  ReceiveBuffer   = NULL;\r
+  ProcessBuffer   = NULL;\r
+  HcDev           = (USB2_HC_DEV *) Context;\r
+  AsyncRequestPtr = HcDev->AsyncRequestList;\r
+\r
+  while (NULL != AsyncRequestPtr) {\r
+\r
+    TransferResult  = 0;\r
+    ErrQtdPos       = 0;\r
+    ActualLen       = 0;\r
+\r
+    CheckQtdsTransferResult (\r
+      FALSE, \r
+      AsyncRequestPtr->QhPtr, \r
+      &TransferResult, \r
+      &ErrQtdPos, \r
+      &ActualLen\r
+      );\r
+\r
+    if ((TransferResult & EFI_USB_ERR_NAK) || (TransferResult & EFI_USB_ERR_NOTEXECUTE)) {\r
+      AsyncRequestPtr = AsyncRequestPtr->Next;\r
+      continue;\r
+    }\r
+    //\r
+    // Allocate memory for EHC private data structure\r
+    //\r
+    ProcessBuffer = AllocateZeroPool (ActualLen);\r
+    if (NULL == ProcessBuffer) {\r
+      Status = EFI_OUT_OF_RESOURCES;\r
+      goto exit;\r
+    }\r
+\r
+    QtdHwPtr = &(AsyncRequestPtr->QhPtr->FirstQtdPtr->Qtd);\r
+    ReceiveBuffer = (UINT8 *) GET_0B_TO_31B ((QtdHwPtr->BufferPointer0 << 12) | AsyncRequestPtr->QhPtr->FirstQtdPtr->StaticCurrentOffset);\r
+    CopyMem (\r
+      ProcessBuffer,\r
+      ReceiveBuffer,\r
+      ActualLen\r
+      );\r
+\r
+    UpdateAsyncRequestTransfer (AsyncRequestPtr, TransferResult, ErrQtdPos);\r
+\r
+    if (EFI_USB_NOERROR == TransferResult) {\r
+\r
+      if (AsyncRequestPtr->CallBackFunc != NULL) {\r
+        (AsyncRequestPtr->CallBackFunc) (ProcessBuffer, ActualLen, AsyncRequestPtr->Context, TransferResult);\r
+      }\r
+\r
+    } else {\r
+\r
+      //\r
+      // leave error recovery to its related device driver. A common case of \r
+      // the error recovery is to re-submit the interrupt transfer.\r
+      // When an interrupt transfer is re-submitted, its position in the linked\r
+      // list is changed. It is inserted to the head of the linked list, while\r
+      // this function scans the whole list from head to tail. Thus, the\r
+      // re-submitted interrupt transfer's callback function will not be called\r
+      // again in this round.\r
+      //\r
+      if (AsyncRequestPtr->CallBackFunc != NULL) {\r
+        (AsyncRequestPtr->CallBackFunc) (NULL, 0, AsyncRequestPtr->Context, TransferResult);\r
+      }\r
+\r
+    }\r
+\r
+    if (NULL != ProcessBuffer) {\r
+      gBS->FreePool (ProcessBuffer);\r
+    }\r
+\r
+    AsyncRequestPtr = AsyncRequestPtr->Next;\r
+\r
+  }\r
+\r
+exit:\r
+  return Status;\r
+}\r
+\r
index 66a41d931916bc78bbe5a08eb220ecd98fff9e00..3d24744f1262d269f855fc21857895d2b72818b9 100644 (file)
@@ -71,6 +71,9 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.-->
     <Protocol Usage="BY_START">\r
       <ProtocolCName>gEfiUsbHcProtocolGuid</ProtocolCName>\r
     </Protocol>\r
+    <Protocol Usage="BY_START">\r
+      <ProtocolCName>gEfiUsb2HcProtocolGuid</ProtocolCName>\r
+    </Protocol>\r
   </Protocols>\r
   <Externs>\r
     <Specification>EFI_SPECIFICATION_VERSION 0x00020000</Specification>\r
index 62d58eed789dc5105a5e2208ad4f54313d521930..74ddc6bb125c40c0646e915669839b05c39839f3 100644 (file)
@@ -49,13 +49,13 @@ Returns:
   // Perform 16bit Read in PCI IO Space\r
   //\r
   return PciIo->Io.Read (\r
-                    PciIo,\r
-                    EfiPciIoWidthUint16,\r
-                    USB_BAR_INDEX,\r
-                    (UINT64) PortOffset,\r
-                    1,\r
-                    Data\r
-                    );\r
+                     PciIo,\r
+                     EfiPciIoWidthUint16,\r
+                     USB_BAR_INDEX,\r
+                     (UINT64) PortOffset,\r
+                     1,\r
+                     Data\r
+                     );\r
 }\r
 \r
 EFI_STATUS\r
@@ -86,13 +86,13 @@ Returns:
   // Perform 32bit Read in PCI IO Space\r
   //\r
   return PciIo->Io.Read (\r
-                    PciIo,\r
-                    EfiPciIoWidthUint32,\r
-                    USB_BAR_INDEX,\r
-                    (UINT64) PortOffset,\r
-                    1,\r
-                    Data\r
-                    );\r
+                     PciIo,\r
+                     EfiPciIoWidthUint32,\r
+                     USB_BAR_INDEX,\r
+                     (UINT64) PortOffset,\r
+                     1,\r
+                     Data\r
+                     );\r
 }\r
 \r
 EFI_STATUS\r
@@ -123,13 +123,13 @@ Returns:
   // Perform 16bit Write in PCI IO Space\r
   //\r
   return PciIo->Io.Write (\r
-                    PciIo,\r
-                    EfiPciIoWidthUint16,\r
-                    USB_BAR_INDEX,\r
-                    (UINT64) PortOffset,\r
-                    1,\r
-                    &Data\r
-                    );\r
+                     PciIo,\r
+                     EfiPciIoWidthUint16,\r
+                     USB_BAR_INDEX,\r
+                     (UINT64) PortOffset,\r
+                     1,\r
+                     &Data\r
+                     );\r
 }\r
 \r
 EFI_STATUS\r
@@ -160,13 +160,13 @@ Returns:
   // Perform 32bit Write in PCI IO Space\r
   //\r
   return PciIo->Io.Write (\r
-                    PciIo,\r
-                    EfiPciIoWidthUint32,\r
-                    USB_BAR_INDEX,\r
-                    (UINT64) PortOffset,\r
-                    1,\r
-                    &Data\r
-                    );\r
+                     PciIo,\r
+                     EfiPciIoWidthUint32,\r
+                     USB_BAR_INDEX,\r
+                     (UINT64) PortOffset,\r
+                     1,\r
+                     &Data\r
+                     );\r
 }\r
 //\r
 //  USB register-base helper functions\r
@@ -657,10 +657,10 @@ Returns:
   EFI_STATUS  Status;\r
 \r
   Status = ReadUHCCommandReg (\r
-            HcDev->PciIo,\r
-            (UINT32) (USBCMD),\r
-            &CommandContent\r
-            );\r
+             HcDev->PciIo,\r
+             (UINT32) (USBCMD),\r
+             &CommandContent\r
+             );\r
 \r
   if ((CommandContent & USBCMD_MAXP) != USBCMD_MAXP) {\r
     CommandContent |= USBCMD_MAXP;\r
@@ -715,25 +715,25 @@ Returns:
   BufferSizeInBytes = 4096;\r
   BufferSizeInPages = EFI_SIZE_TO_PAGES (BufferSizeInBytes);\r
   Status = HcDev->PciIo->AllocateBuffer (\r
-                          HcDev->PciIo,\r
-                          AllocateAnyPages,\r
-                          EfiBootServicesData,\r
-                          BufferSizeInPages,\r
-                          &CommonBuffer,\r
-                          0\r
-                          );\r
+                           HcDev->PciIo,\r
+                           AllocateAnyPages,\r
+                           EfiBootServicesData,\r
+                           BufferSizeInPages,\r
+                           &CommonBuffer,\r
+                           0\r
+                           );\r
   if (EFI_ERROR (Status)) {\r
     return EFI_OUT_OF_RESOURCES;\r
   }\r
 \r
   Status = HcDev->PciIo->Map (\r
-                          HcDev->PciIo,\r
-                          EfiPciIoOperationBusMasterCommonBuffer,\r
-                          CommonBuffer,\r
-                          &BufferSizeInBytes,\r
-                          &MappedAddress,\r
-                          &Mapping\r
-                          );\r
+                           HcDev->PciIo,\r
+                           EfiPciIoOperationBusMasterCommonBuffer,\r
+                           CommonBuffer,\r
+                           &BufferSizeInBytes,\r
+                           &MappedAddress,\r
+                           &Mapping\r
+                           );\r
   if (EFI_ERROR (Status) || (BufferSizeInBytes != 4096)) {\r
     HcDev->PciIo->FreeBuffer (HcDev->PciIo, BufferSizeInPages, CommonBuffer);\r
     return EFI_UNSUPPORTED;\r
@@ -3589,13 +3589,13 @@ Returns:
   // and it is allocated as common buffer use.\r
   //\r
   Status = HcDev->PciIo->AllocateBuffer (\r
-                          HcDev->PciIo,\r
-                          AllocateAnyPages,\r
-                          EfiBootServicesData,\r
-                          MemoryBlockSizeInPages,\r
-                          &CommonBuffer,\r
-                          0\r
-                          );\r
+                           HcDev->PciIo,\r
+                           AllocateAnyPages,\r
+                           EfiBootServicesData,\r
+                           MemoryBlockSizeInPages,\r
+                           &CommonBuffer,\r
+                           0\r
+                           );\r
   if (EFI_ERROR (Status)) {\r
     gBS->FreePool ((*MemoryHeader)->BitArrayPtr);\r
     gBS->FreePool (*MemoryHeader);\r
@@ -3604,13 +3604,13 @@ Returns:
 \r
   MemoryBlockSizeInBytes = EFI_PAGES_TO_SIZE (MemoryBlockSizeInPages);\r
   Status = HcDev->PciIo->Map (\r
-                          HcDev->PciIo,\r
-                          EfiPciIoOperationBusMasterCommonBuffer,\r
-                          CommonBuffer,\r
-                          &MemoryBlockSizeInBytes,\r
-                          &MappedAddress,\r
-                          &Mapping\r
-                          );\r
+                           HcDev->PciIo,\r
+                           EfiPciIoOperationBusMasterCommonBuffer,\r
+                           CommonBuffer,\r
+                           &MemoryBlockSizeInBytes,\r
+                           &MappedAddress,\r
+                           &Mapping\r
+                           );\r
   //\r
   // if returned Mapped size is less than the size we request,do not support.\r
   //\r
@@ -3741,10 +3741,10 @@ Returns:
        TempHeaderPtr = TempHeaderPtr->Next) {\r
 \r
     Status = AllocMemInMemoryBlock (\r
-              TempHeaderPtr,\r
-              (VOID **) Pool,\r
-              RealAllocSize / 32\r
-              );\r
+               TempHeaderPtr,\r
+               (VOID **) Pool,\r
+               RealAllocSize / 32\r
+               );\r
     if (!EFI_ERROR (Status)) {\r
       ZeroMem (*Pool, AllocSize);\r
       return EFI_SUCCESS;\r
@@ -3777,10 +3777,10 @@ Returns:
   InsertMemoryHeaderToList (MemoryHeader, NewMemoryHeader);\r
 \r
   Status = AllocMemInMemoryBlock (\r
-            NewMemoryHeader,\r
-            (VOID **) Pool,\r
-            RealAllocSize / 32\r
-            );\r
+             NewMemoryHeader,\r
+             (VOID **) Pool,\r
+             RealAllocSize / 32\r
+             );\r
 \r
   if (!EFI_ERROR (Status)) {\r
     ZeroMem (*Pool, AllocSize);\r
@@ -4226,12 +4226,12 @@ TurnOffUSBEmulation (
   //\r
   Command = 0;\r
   PciIo->Pci.Write (\r
-              PciIo,\r
-              EfiPciIoWidthUint16,\r
-              USB_EMULATION,\r
-              1,\r
-              &Command\r
-              );\r
+               PciIo,\r
+               EfiPciIoWidthUint16,\r
+               USB_EMULATION,\r
+               1,\r
+               &Command\r
+               );\r
 \r
   return ;\r
 }\r
index 1eba8bed5b1f36a02229ed71a3ca3b55f3196c47..14f8bf27902de98fab4ce3d9be6cd6bed4267809 100644 (file)
@@ -26,13 +26,6 @@ Revision History
 // Driver model protocol interface\r
 //\r
 \r
-EFI_STATUS\r
-EFIAPI\r
-UHCIDriverEntryPoint (\r
-  IN EFI_HANDLE           ImageHandle,\r
-  IN EFI_SYSTEM_TABLE     *SystemTable\r
-  );\r
-\r
 EFI_STATUS\r
 EFIAPI\r
 UHCIDriverBindingSupported (\r
@@ -119,7 +112,7 @@ UHCIAsyncInterruptTransfer (
   IN       UINT8                              DeviceAddress,\r
   IN       UINT8                              EndPointAddress,\r
   IN       BOOLEAN                            IsSlowDevice,\r
-  IN       UINT8                              MaxiumPacketLength,\r
+  IN       UINT8                              MaximumPacketLength,\r
   IN       BOOLEAN                            IsNewTransfer,\r
   IN OUT   UINT8                              *DataToggle,\r
   IN       UINTN                              PollingInterval, OPTIONAL\r
@@ -199,6 +192,161 @@ UHCIClearRootHubPortFeature (
   IN  EFI_USB_PORT_FEATURE    PortFeature\r
   );\r
 \r
+//\r
+// UEFI 2.0 Protocol\r
+//\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+UHCI2GetCapability(\r
+  IN  EFI_USB2_HC_PROTOCOL  * This,\r
+  OUT UINT8                 *MaxSpeed,\r
+  OUT UINT8                 *PortNumber,\r
+  OUT UINT8                 *Is64BitCapable\r
+  );\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+UHCI2Reset (\r
+  IN EFI_USB2_HC_PROTOCOL   * This,\r
+  IN UINT16                 Attributes\r
+  );\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+UHCI2GetState (\r
+  IN  EFI_USB2_HC_PROTOCOL   * This,\r
+  OUT EFI_USB_HC_STATE       * State\r
+  );\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+UHCI2SetState (\r
+  IN EFI_USB2_HC_PROTOCOL   * This,\r
+  IN EFI_USB_HC_STATE       State\r
+  );\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+UHCI2ControlTransfer (\r
+  IN     EFI_USB2_HC_PROTOCOL      * This,\r
+  IN     UINT8                     DeviceAddress,\r
+  IN     UINT8                     DeviceSpeed,\r
+  IN     UINTN                     MaximumPacketLength,\r
+  IN     EFI_USB_DEVICE_REQUEST    * Request,\r
+  IN     EFI_USB_DATA_DIRECTION    TransferDirection,\r
+  IN OUT VOID                      *Data, OPTIONAL\r
+  IN OUT UINTN                     *DataLength, OPTIONAL\r
+  IN     UINTN                     TimeOut,\r
+  IN     EFI_USB2_HC_TRANSACTION_TRANSLATOR            *Translator,\r
+  OUT    UINT32                    *TransferResult\r
+  );\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+UHCI2BulkTransfer (\r
+  IN     EFI_USB2_HC_PROTOCOL   * This,\r
+  IN     UINT8                  DeviceAddress,\r
+  IN     UINT8                  EndPointAddress,\r
+  IN     UINT8                  DeviceSpeed,\r
+  IN     UINTN                  MaximumPacketLength,\r
+  IN     UINT8                  DataBuffersNumber,\r
+  IN OUT VOID                   *Data[EFI_USB_MAX_BULK_BUFFER_NUM],\r
+  IN OUT UINTN                  *DataLength,\r
+  IN OUT UINT8                  *DataToggle,\r
+  IN     UINTN                  TimeOut,\r
+  IN     EFI_USB2_HC_TRANSACTION_TRANSLATOR            *Translator,\r
+  OUT    UINT32                 *TransferResult\r
+  );\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+UHCI2AsyncInterruptTransfer (\r
+  IN     EFI_USB2_HC_PROTOCOL   * This,\r
+  IN     UINT8                  DeviceAddress,\r
+  IN     UINT8                  EndPointAddress,\r
+  IN     UINT8                  DeviceSpeed,\r
+  IN     UINTN                  MaximumPacketLength,\r
+  IN     BOOLEAN                IsNewTransfer,\r
+  IN OUT UINT8                  *DataToggle,\r
+  IN     UINTN                  PollingInterval, OPTIONAL\r
+  IN     UINTN                  DataLength, OPTIONAL\r
+  IN     EFI_USB2_HC_TRANSACTION_TRANSLATOR            *Translator,\r
+  IN     EFI_ASYNC_USB_TRANSFER_CALLBACK               CallBackFunction, OPTIONAL\r
+  IN     VOID                   *Context OPTIONAL\r
+  );\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+UHCI2SyncInterruptTransfer (\r
+  IN     EFI_USB2_HC_PROTOCOL   * This,\r
+  IN     UINT8                  DeviceAddress,\r
+  IN     UINT8                  EndPointAddress,\r
+  IN     UINT8                  DeviceSpeed,\r
+  IN     UINTN                  MaximumPacketLength,\r
+  IN OUT VOID                   *Data,\r
+  IN OUT UINTN                  *DataLength,\r
+  IN OUT UINT8                  *DataToggle,\r
+  IN     UINTN                  TimeOut,\r
+  IN     EFI_USB2_HC_TRANSACTION_TRANSLATOR           *Translator,\r
+  OUT    UINT32                 *TransferResult\r
+  );\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+UHCI2IsochronousTransfer (\r
+  IN     EFI_USB2_HC_PROTOCOL   * This,\r
+  IN     UINT8                  DeviceAddress,\r
+  IN     UINT8                  EndPointAddress,\r
+  IN     UINT8                  DeviceSpeed,\r
+  IN     UINTN                  MaximumPacketLength,\r
+  IN     UINT8                  DataBuffersNumber,\r
+  IN OUT VOID                   *Data[EFI_USB_MAX_ISO_BUFFER_NUM],\r
+  IN     UINTN                  DataLength,\r
+  IN     EFI_USB2_HC_TRANSACTION_TRANSLATOR           *Translator,\r
+  OUT    UINT32                 *TransferResult\r
+  );\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+UHCI2AsyncIsochronousTransfer (\r
+  IN     EFI_USB2_HC_PROTOCOL   * This,\r
+  IN     UINT8                  DeviceAddress,\r
+  IN     UINT8                  EndPointAddress,\r
+  IN     UINT8                  DeviceSpeed,\r
+  IN     UINTN                  MaximumPacketLength,\r
+  IN     UINT8                  DataBuffersNumber,\r
+  IN OUT VOID                   *Data[EFI_USB_MAX_ISO_BUFFER_NUM],\r
+  IN     UINTN                  DataLength,\r
+  IN     EFI_USB2_HC_TRANSACTION_TRANSLATOR           *Translator,\r
+  IN     EFI_ASYNC_USB_TRANSFER_CALLBACK              IsochronousCallBack,\r
+  IN     VOID                   *Context OPTIONAL\r
+  );\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+UHCI2GetRootHubPortStatus (\r
+  IN  EFI_USB2_HC_PROTOCOL   * This,\r
+  IN  UINT8                  PortNumber,\r
+  OUT EFI_USB_PORT_STATUS    * PortStatus\r
+  );\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+UHCI2SetRootHubPortFeature (\r
+  IN EFI_USB2_HC_PROTOCOL    * This,\r
+  IN UINT8                   PortNumber,\r
+  IN EFI_USB_PORT_FEATURE    PortFeature\r
+  );\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+UHCI2ClearRootHubPortFeature (\r
+  IN EFI_USB2_HC_PROTOCOL    * This,\r
+  IN UINT8                   PortNumber,\r
+  IN EFI_USB_PORT_FEATURE    PortFeature\r
+  );\r
+\r
 //\r
 // Asynchronous interrupt transfer monitor function\r
 //\r
@@ -236,7 +384,7 @@ UHCIDriverBindingSupported (
 \r
   Arguments:\r
     This                - Protocol instance pointer.\r
-    Controller,         - Handle of device to test\r
+    Controller          - Handle of device to test\r
     RemainingDevicePath - Not used\r
 \r
   Returns:\r
@@ -289,20 +437,20 @@ UHCIDriverBindingSupported (
       (UsbClassCReg.PI != PCI_CLASSC_PI_UHCI)) {\r
 \r
     gBS->CloseProtocol (\r
-          Controller,\r
-          &gEfiPciIoProtocolGuid,\r
-          This->DriverBindingHandle,\r
-          Controller\r
-          );\r
+           Controller,\r
+           &gEfiPciIoProtocolGuid,\r
+           This->DriverBindingHandle,\r
+           Controller\r
+           );\r
 \r
     return EFI_UNSUPPORTED;\r
   }\r
   gBS->CloseProtocol (\r
-        Controller,\r
-        &gEfiPciIoProtocolGuid,\r
-        This->DriverBindingHandle,\r
-        Controller\r
-        );\r
+         Controller,\r
+         &gEfiPciIoProtocolGuid,\r
+         This->DriverBindingHandle,\r
+         Controller\r
+         );\r
   return EFI_SUCCESS;\r
 \r
 }\r
@@ -351,6 +499,7 @@ UHCIDriverBindingStart (
   if (EFI_ERROR (Status)) {\r
     return Status;\r
   }\r
+\r
   //\r
   // Turn off USB emulation\r
   //\r
@@ -367,11 +516,11 @@ UHCIDriverBindingStart (
                     );\r
   if (EFI_ERROR (Status)) {\r
     gBS->CloseProtocol (\r
-          Controller,\r
-          &gEfiPciIoProtocolGuid,\r
-          This->DriverBindingHandle,\r
-          Controller\r
-          );\r
+           Controller,\r
+           &gEfiPciIoProtocolGuid,\r
+           This->DriverBindingHandle,\r
+           Controller\r
+           );\r
     return EFI_UNSUPPORTED;\r
   }\r
 \r
@@ -381,14 +530,14 @@ UHCIDriverBindingStart (
   HcDev = AllocateZeroPool (sizeof (USB_HC_DEV));\r
   if (HcDev == NULL) {\r
     gBS->CloseProtocol (\r
-          Controller,\r
-          &gEfiPciIoProtocolGuid,\r
-          This->DriverBindingHandle,\r
-          Controller\r
-          );\r
+           Controller,\r
+           &gEfiPciIoProtocolGuid,\r
+           This->DriverBindingHandle,\r
+           Controller\r
+           );\r
     return EFI_OUT_OF_RESOURCES;\r
   }\r
-  \r
+\r
   //\r
   // init EFI_USB_HC_PROTOCOL protocol interface and install the protocol\r
   //\r
@@ -409,6 +558,27 @@ UHCIDriverBindingStart (
   HcDev->UsbHc.MajorRevision            = 0x1;\r
   HcDev->UsbHc.MinorRevision            = 0x1;\r
 \r
+  //\r
+  //\r
+  // init EFI_USB2_HC_PROTOCOL protocol interface and install the protocol\r
+  //\r
+  HcDev->Usb2Hc.GetCapability            = UHCI2GetCapability;\r
+  HcDev->Usb2Hc.Reset                    = UHCI2Reset;\r
+  HcDev->Usb2Hc.GetState                 = UHCI2GetState;\r
+  HcDev->Usb2Hc.SetState                 = UHCI2SetState;\r
+  HcDev->Usb2Hc.ControlTransfer          = UHCI2ControlTransfer;\r
+  HcDev->Usb2Hc.BulkTransfer             = UHCI2BulkTransfer;\r
+  HcDev->Usb2Hc.AsyncInterruptTransfer   = UHCI2AsyncInterruptTransfer;\r
+  HcDev->Usb2Hc.SyncInterruptTransfer    = UHCI2SyncInterruptTransfer;\r
+  HcDev->Usb2Hc.IsochronousTransfer      = UHCI2IsochronousTransfer;\r
+  HcDev->Usb2Hc.AsyncIsochronousTransfer = UHCI2AsyncIsochronousTransfer;\r
+  HcDev->Usb2Hc.GetRootHubPortStatus     = UHCI2GetRootHubPortStatus;\r
+  HcDev->Usb2Hc.SetRootHubPortFeature    = UHCI2SetRootHubPortFeature;\r
+  HcDev->Usb2Hc.ClearRootHubPortFeature  = UHCI2ClearRootHubPortFeature;\r
+  \r
+  HcDev->Usb2Hc.MajorRevision            = 0x1;\r
+  HcDev->Usb2Hc.MinorRevision            = 0x1;\r
+  \r
   //\r
   //  Init UHCI private data structures\r
   //\r
@@ -428,14 +598,14 @@ UHCIDriverBindingStart (
     }\r
 \r
     gBS->CloseProtocol (\r
-          Controller,\r
-          &gEfiPciIoProtocolGuid,\r
-          This->DriverBindingHandle,\r
-          Controller\r
-          );\r
+           Controller,\r
+           &gEfiPciIoProtocolGuid,\r
+           This->DriverBindingHandle,\r
+           Controller\r
+           );\r
     return EFI_OUT_OF_RESOURCES;\r
   }\r
-  \r
+\r
   //\r
   //  Init interrupt list head in the HcDev structure.\r
   //\r
@@ -460,11 +630,11 @@ UHCIDriverBindingStart (
     }\r
 \r
     gBS->CloseProtocol (\r
-          Controller,\r
-          &gEfiPciIoProtocolGuid,\r
-          This->DriverBindingHandle,\r
-          Controller\r
-          );\r
+           Controller,\r
+           &gEfiPciIoProtocolGuid,\r
+           This->DriverBindingHandle,\r
+           Controller\r
+           );\r
     return EFI_UNSUPPORTED;\r
   }\r
 \r
@@ -486,11 +656,11 @@ UHCIDriverBindingStart (
     }\r
 \r
     gBS->CloseProtocol (\r
-          Controller,\r
-          &gEfiPciIoProtocolGuid,\r
-          This->DriverBindingHandle,\r
-          Controller\r
-          );\r
+           Controller,\r
+           &gEfiPciIoProtocolGuid,\r
+           This->DriverBindingHandle,\r
+           Controller\r
+           );\r
     return EFI_UNSUPPORTED;\r
   }\r
   \r
@@ -518,7 +688,7 @@ UHCIDriverBindingStart (
            );\r
     return Status;\r
   }\r
-  \r
+\r
   //\r
   // Install Host Controller Protocol\r
   //\r
@@ -538,17 +708,46 @@ UHCIDriverBindingStart (
     }\r
 \r
     gBS->CloseProtocol (\r
-          Controller,\r
-          &gEfiPciIoProtocolGuid,\r
-          This->DriverBindingHandle,\r
-          Controller\r
-          );\r
+           Controller,\r
+           &gEfiPciIoProtocolGuid,\r
+           This->DriverBindingHandle,\r
+           Controller\r
+           );\r
+    return Status;\r
+  }\r
+\r
+  //\r
+  // Install USB2.0 Host Controller Protocol\r
+  //\r
+  Status = gBS->InstallProtocolInterface (\r
+                  &Controller,\r
+                  &gEfiUsb2HcProtocolGuid,\r
+                  EFI_NATIVE_INTERFACE,\r
+                  &HcDev->Usb2Hc\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    gBS->CloseEvent (HcDev->InterruptTransTimer);\r
+    FreeFrameListEntry (HcDev);\r
+    DelMemoryManagement (HcDev);\r
+\r
+    if (HcDev != NULL) {\r
+      gBS->FreePool (HcDev);\r
+    }\r
+\r
+    gBS->CloseProtocol (\r
+           Controller,\r
+           &gEfiPciIoProtocolGuid,\r
+           This->DriverBindingHandle,\r
+           Controller\r
+           );\r
+\r
     return Status;\r
   }\r
   \r
   //\r
   // component name protocol.\r
   //\r
+\r
   HcDev->ControllerNameTable = NULL;\r
   AddUnicodeString (\r
     "eng",\r
@@ -582,12 +781,17 @@ UnInstallUHCInterface (
   HcDev = USB_HC_DEV_FROM_THIS (This);\r
 \r
   gBS->UninstallProtocolInterface (\r
-        Controller,\r
-        &gEfiUsbHcProtocolGuid,\r
-        &HcDev->UsbHc\r
-        );\r
-\r
-  //\r
+         Controller,\r
+         &gEfiUsbHcProtocolGuid,\r
+         &HcDev->UsbHc\r
+         );\r
+         \r
+  gBS->UninstallProtocolInterface (\r
+         Controller,\r
+         &gEfiUsb2HcProtocolGuid,\r
+         &HcDev->Usb2Hc\r
+         );\r
+  //     \r
   // first stop USB Host Controller\r
   //\r
   This->SetState (This, EfiUsbHcStateHalt);\r
@@ -659,12 +863,31 @@ UHCIDriverBindingStop (
 --*/\r
 {\r
   EFI_USB_HC_PROTOCOL *UsbHc;\r
+  EFI_USB2_HC_PROTOCOL *Usb2Hc;\r
   EFI_STATUS          OpenStatus;\r
 \r
   OpenStatus = gBS->OpenProtocol (\r
                       Controller,\r
                       &gEfiUsbHcProtocolGuid,\r
-                      (VOID **) &UsbHc,\r
+                      (VOID **)&UsbHc,\r
+                      This->DriverBindingHandle,\r
+                      Controller,\r
+                      EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
+                      );\r
+\r
+  //\r
+  // Test whether the Controller handler passed in is a valid\r
+  // Usb controller handle that should be supported, if not,\r
+  // return the error status directly\r
+  //\r
+  if (EFI_ERROR (OpenStatus)) {\r
+    return OpenStatus;\r
+  }\r
+\r
+  OpenStatus = gBS->OpenProtocol (\r
+                      Controller,\r
+                      &gEfiUsb2HcProtocolGuid,\r
+                      (VOID **) &Usb2Hc,\r
                       This->DriverBindingHandle,\r
                       Controller,\r
                       EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
@@ -684,11 +907,11 @@ UHCIDriverBindingStop (
   UnInstallUHCInterface (Controller, UsbHc);\r
 \r
   gBS->CloseProtocol (\r
-        Controller,\r
-        &gEfiPciIoProtocolGuid,\r
-        This->DriverBindingHandle,\r
-        Controller\r
-        );\r
+         Controller,\r
+         &gEfiPciIoProtocolGuid,\r
+         This->DriverBindingHandle,\r
+         Controller\r
+         );\r
 \r
   return EFI_SUCCESS;\r
 \r
@@ -753,20 +976,20 @@ UHCIReset (
     // set the Global Reset bit in the command register\r
     //\r
     Status = ReadUHCCommandReg (\r
-              HcDev->PciIo,\r
-              CommandRegAddr,\r
-              &Command\r
-              );\r
+               HcDev->PciIo,\r
+               CommandRegAddr,\r
+               &Command\r
+               );\r
     if (EFI_ERROR (Status)) {\r
       return EFI_DEVICE_ERROR;\r
     }\r
 \r
     Command |= USBCMD_GRESET;\r
     Status = WriteUHCCommandReg (\r
-              HcDev->PciIo,\r
-              CommandRegAddr,\r
-              Command\r
-              );\r
+               HcDev->PciIo,\r
+               CommandRegAddr,\r
+               Command\r
+               );\r
     if (EFI_ERROR (Status)) {\r
       return EFI_DEVICE_ERROR;\r
     }\r
@@ -782,10 +1005,10 @@ UHCIReset (
     //\r
     Command &= ~USBCMD_GRESET;\r
     Status = WriteUHCCommandReg (\r
-              HcDev->PciIo,\r
-              CommandRegAddr,\r
-              Command\r
-              );\r
+               HcDev->PciIo,\r
+               CommandRegAddr,\r
+               Command\r
+               );\r
     if (EFI_ERROR (Status)) {\r
       return EFI_DEVICE_ERROR;\r
     }\r
@@ -801,20 +1024,20 @@ UHCIReset (
     // set Host Controller Reset bit to 1\r
     //\r
     Status = ReadUHCCommandReg (\r
-              HcDev->PciIo,\r
-              CommandRegAddr,\r
-              &Command\r
-              );\r
+               HcDev->PciIo,\r
+               CommandRegAddr,\r
+               &Command\r
+               );\r
     if (EFI_ERROR (Status)) {\r
       return EFI_DEVICE_ERROR;\r
     }\r
 \r
     Command |= USBCMD_HCRESET;\r
     Status = WriteUHCCommandReg (\r
-              HcDev->PciIo,\r
-              CommandRegAddr,\r
-              Command\r
-              );\r
+               HcDev->PciIo,\r
+               CommandRegAddr,\r
+               Command\r
+               );\r
     if (EFI_ERROR (Status)) {\r
       return EFI_DEVICE_ERROR;\r
     }\r
@@ -905,20 +1128,20 @@ UHCIGetState (
   StatusRegAddr   = (UINT32) (USBSTS);\r
 \r
   Status = ReadUHCCommandReg (\r
-            HcDev->PciIo,\r
-            CommandRegAddr,\r
-            &UhcCommand\r
-            );\r
+             HcDev->PciIo,\r
+             CommandRegAddr,\r
+             &UhcCommand\r
+             );\r
 \r
   if (EFI_ERROR (Status)) {\r
     return EFI_DEVICE_ERROR;\r
   }\r
 \r
   Status = ReadUHCCommandReg (\r
-            HcDev->PciIo,\r
-            StatusRegAddr,\r
-            &UhcStatus\r
-            );\r
+             HcDev->PciIo,\r
+             StatusRegAddr,\r
+             &UhcStatus\r
+             );\r
   if (EFI_ERROR (Status)) {\r
     return EFI_DEVICE_ERROR;\r
   }\r
@@ -990,10 +1213,10 @@ UHCISetState (
     }\r
 \r
     Status = ReadUHCCommandReg (\r
-              HcDev->PciIo,\r
-              CommandRegAddr,\r
-              &Command\r
-              );\r
+               HcDev->PciIo,\r
+               CommandRegAddr,\r
+               &Command\r
+               );\r
     if (EFI_ERROR (Status)) {\r
       return EFI_DEVICE_ERROR;\r
     }\r
@@ -1001,10 +1224,10 @@ UHCISetState (
     Command &= ~USBCMD_RS;\r
 \r
     Status = WriteUHCCommandReg (\r
-              HcDev->PciIo,\r
-              CommandRegAddr,\r
-              Command\r
-              );\r
+               HcDev->PciIo,\r
+               CommandRegAddr,\r
+               Command\r
+               );\r
     if (EFI_ERROR (Status)) {\r
       return EFI_DEVICE_ERROR;\r
     }\r
@@ -1033,20 +1256,20 @@ UHCISetState (
       // Set Run/Stop bit to 1.\r
       //\r
       Status = ReadUHCCommandReg (\r
-                HcDev->PciIo,\r
-                CommandRegAddr,\r
-                &Command\r
-                );\r
+                 HcDev->PciIo,\r
+                 CommandRegAddr,\r
+                 &Command\r
+                 );\r
       if (EFI_ERROR (Status)) {\r
         return EFI_DEVICE_ERROR;\r
       }\r
 \r
       Command |= USBCMD_RS | USBCMD_MAXP;\r
       Status = WriteUHCCommandReg (\r
-                HcDev->PciIo,\r
-                CommandRegAddr,\r
-                Command\r
-                );\r
+                 HcDev->PciIo,\r
+                 CommandRegAddr,\r
+                 Command\r
+                 );\r
       if (EFI_ERROR (Status)) {\r
         return EFI_DEVICE_ERROR;\r
       }\r
@@ -1055,10 +1278,10 @@ UHCISetState (
 \r
     case EfiUsbHcStateSuspend:\r
       Status = ReadUHCCommandReg (\r
-                HcDev->PciIo,\r
-                CommandRegAddr,\r
-                &Command\r
-                );\r
+                 HcDev->PciIo,\r
+                 CommandRegAddr,\r
+                 &Command\r
+                 );\r
       if (EFI_ERROR (Status)) {\r
         return EFI_DEVICE_ERROR;\r
       }\r
@@ -1115,20 +1338,20 @@ UHCISetState (
     // Set Enter Global Suspend Mode bit to 1.\r
     //\r
     Status = ReadUHCCommandReg (\r
-              HcDev->PciIo,\r
-              CommandRegAddr,\r
-              &Command\r
-              );\r
+               HcDev->PciIo,\r
+               CommandRegAddr,\r
+               &Command\r
+               );\r
     if (EFI_ERROR (Status)) {\r
       return EFI_DEVICE_ERROR;\r
     }\r
 \r
     Command |= USBCMD_EGSM;\r
     Status = WriteUHCCommandReg (\r
-              HcDev->PciIo,\r
-              CommandRegAddr,\r
-              Command\r
-              );\r
+               HcDev->PciIo,\r
+               CommandRegAddr,\r
+               Command\r
+               );\r
     if (EFI_ERROR (Status)) {\r
       return EFI_DEVICE_ERROR;\r
     }\r
@@ -1185,10 +1408,10 @@ UHCIGetRootHubPortNumber (
   for (Index = 0; Index < 2; Index++) {\r
     PSAddr = (UINT32) (USBPORTSC1 + Index * 2);\r
     Status = ReadRootPortReg (\r
-              HcDev->PciIo,\r
-              PSAddr,\r
-              &RHPortControl\r
-              );\r
+               HcDev->PciIo,\r
+               PSAddr,\r
+               &RHPortControl\r
+               );\r
     if (EFI_ERROR (Status)) {\r
       return EFI_DEVICE_ERROR;\r
     }\r
@@ -1261,10 +1484,10 @@ UHCIGetRootHubPortStatus (
   PortStatus->PortChangeStatus  = 0;\r
 \r
   Status = ReadRootPortReg (\r
-            HcDev->PciIo,\r
-            PSAddr,\r
-            &RHPortStatus\r
-            );\r
+             HcDev->PciIo,\r
+             PSAddr,\r
+             &RHPortStatus\r
+             );\r
 \r
   if (EFI_ERROR (Status)) {\r
     return EFI_DEVICE_ERROR;\r
@@ -1307,6 +1530,10 @@ UHCIGetRootHubPortStatus (
     PortStatus->PortStatus |= USB_PORT_STAT_LOW_SPEED;\r
   }\r
   //\r
+  // CHC will always return one in this bit\r
+  //\r
+  PortStatus->PortStatus |= USB_PORT_STAT_OWNER;\r
+  //\r
   //   Fill Port Status Change bits\r
   //\r
   \r
@@ -1393,10 +1620,10 @@ UHCISetRootHubPortFeature (
 \r
   case EfiUsbPortSuspend:\r
     Status = ReadUHCCommandReg (\r
-              HcDev->PciIo,\r
-              CommandRegAddr,\r
-              &Command\r
-              );\r
+               HcDev->PciIo,\r
+               CommandRegAddr,\r
+               &Command\r
+               );\r
     if (EFI_ERROR (Status)) {\r
       return EFI_DEVICE_ERROR;\r
     }\r
@@ -1487,10 +1714,10 @@ UHCIClearRootHubPortFeature (
   PSAddr  = (UINT32) (USBPORTSC1 + PortNumber * 2);\r
 \r
   Status = ReadRootPortReg (\r
-            HcDev->PciIo,\r
-            PSAddr,\r
-            &RHPortControl\r
-            );\r
+             HcDev->PciIo,\r
+             PSAddr,\r
+             &RHPortControl\r
+             );\r
   if (EFI_ERROR (Status)) {\r
     return EFI_DEVICE_ERROR;\r
   }\r
@@ -1733,13 +1960,13 @@ UHCIControlTransfer (
     // BusMasterWrite means cpu read\r
     //\r
     Status = HcDev->PciIo->Map (\r
-                            HcDev->PciIo,\r
-                            EfiPciIoOperationBusMasterWrite,\r
-                            PtrDataSource,\r
-                            &DataLen,\r
-                            &TempPtr,\r
-                            &Mapping\r
-                            );\r
+                             HcDev->PciIo,\r
+                             EfiPciIoOperationBusMasterWrite,\r
+                             PtrDataSource,\r
+                             &DataLen,\r
+                             &TempPtr,\r
+                             &Mapping\r
+                             );\r
     if (EFI_ERROR (Status)) {\r
       return Status;\r
     }\r
@@ -1757,13 +1984,13 @@ UHCIControlTransfer (
     // BusMasterRead means cpu write\r
     //\r
     Status = HcDev->PciIo->Map (\r
-                            HcDev->PciIo,\r
-                            EfiPciIoOperationBusMasterRead,\r
-                            PtrDataSource,\r
-                            &DataLen,\r
-                            &TempPtr,\r
-                            &Mapping\r
-                            );\r
+                             HcDev->PciIo,\r
+                             EfiPciIoOperationBusMasterRead,\r
+                             PtrDataSource,\r
+                             &DataLen,\r
+                             &TempPtr,\r
+                             &Mapping\r
+                             );\r
     if (EFI_ERROR (Status)) {\r
       return Status;\r
     }\r
@@ -1809,13 +2036,13 @@ UHCIControlTransfer (
   //\r
   RequestLen = sizeof (EFI_USB_DEVICE_REQUEST);\r
   Status = HcDev->PciIo->Map (\r
-                          HcDev->PciIo,\r
-                          EfiPciIoOperationBusMasterRead,\r
-                          (UINT8 *) Request,\r
-                          &RequestLen,\r
-                          &TempPtr,\r
-                          &RequestMapping\r
-                          );\r
+                           HcDev->PciIo,\r
+                           EfiPciIoOperationBusMasterRead,\r
+                           (UINT8 *) Request,\r
+                           &RequestLen,\r
+                           &TempPtr,\r
+                           &RequestMapping\r
+                           );\r
 \r
   if (EFI_ERROR (Status)) {\r
     HcDev->PciIo->Unmap (HcDev->PciIo, Mapping);\r
@@ -1829,14 +2056,14 @@ UHCIControlTransfer (
   // generate Setup Stage TD\r
   //\r
   Status = GenSetupStageTD (\r
-            HcDev,\r
-            DeviceAddress,\r
-            0,\r
-            IsSlowDevice,\r
-            (UINT8 *) RequestMappedAddress,\r
-            sizeof (EFI_USB_DEVICE_REQUEST),\r
-            &PtrSetupTD\r
-            );\r
+             HcDev,\r
+             DeviceAddress,\r
+             0,\r
+             IsSlowDevice,\r
+             (UINT8 *) RequestMappedAddress,\r
+             sizeof (EFI_USB_DEVICE_REQUEST),\r
+             &PtrSetupTD\r
+             );\r
 \r
   if (EFI_ERROR (Status)) {\r
     HcDev->PciIo->Unmap (HcDev->PciIo, Mapping);\r
@@ -1864,16 +2091,16 @@ UHCIControlTransfer (
     }\r
 \r
     Status = GenDataTD (\r
-              HcDev,\r
-              DeviceAddress,\r
-              0,\r
-              Ptr,\r
-              PktSize,\r
-              PktID,\r
-              DataToggle,\r
-              IsSlowDevice,\r
-              &PtrTD\r
-              );\r
+               HcDev,\r
+               DeviceAddress,\r
+               0,\r
+               Ptr,\r
+               PktSize,\r
+               PktID,\r
+               DataToggle,\r
+               IsSlowDevice,\r
+               &PtrTD\r
+               );\r
 \r
     if (EFI_ERROR (Status)) {\r
       //\r
@@ -1920,13 +2147,13 @@ UHCIControlTransfer (
   // create Status Stage TD structure\r
   //\r
   Status = CreateStatusTD (\r
-            HcDev,\r
-            DeviceAddress,\r
-            0,\r
-            PktID,\r
-            IsSlowDevice,\r
-            &PtrStatusTD\r
-            );\r
+             HcDev,\r
+             DeviceAddress,\r
+             0,\r
+             PktID,\r
+             IsSlowDevice,\r
+             &PtrStatusTD\r
+             );\r
 \r
   if (EFI_ERROR (Status)) {\r
     HcDev->PciIo->Unmap (HcDev->PciIo, Mapping);\r
@@ -2009,13 +2236,13 @@ UHCIControlTransfer (
       }\r
 \r
       Status = ExecuteControlTransfer (\r
-                HcDev,\r
-                PtrFirstDataTD,\r
-                LoadFrameListIndex,\r
-                DataLength,\r
-                TimeOut,\r
-                TransferResult\r
-                );\r
+                 HcDev,\r
+                 PtrFirstDataTD,\r
+                 LoadFrameListIndex,\r
+                 DataLength,\r
+                 TimeOut,\r
+                 TransferResult\r
+                 );\r
 \r
       for (Index = 0; Index < 500; Index++) {\r
         DelLinkSingleQH (\r
@@ -2060,13 +2287,13 @@ UHCIControlTransfer (
     // detail status is returned\r
     //\r
     Status = ExecuteControlTransfer (\r
-              HcDev,\r
-              PtrStatusTD,\r
-              LoadFrameListIndex,\r
-              DataLength,\r
-              TimeOut,\r
-              TransferResult\r
-              );\r
+               HcDev,\r
+               PtrStatusTD,\r
+               LoadFrameListIndex,\r
+               DataLength,\r
+               TimeOut,\r
+               TransferResult\r
+               );\r
 \r
     //\r
     // Delete Control Transfer QH-TDs structure\r
@@ -2123,13 +2350,13 @@ UHCIControlTransfer (
     // detail status is returned\r
     //\r
     Status = ExecuteControlTransfer (\r
-              HcDev,\r
-              PtrSetupTD,\r
-              LoadFrameListIndex,\r
-              DataLength,\r
-              TimeOut,\r
-              TransferResult\r
-              );\r
+               HcDev,\r
+               PtrSetupTD,\r
+               LoadFrameListIndex,\r
+               DataLength,\r
+               TimeOut,\r
+               TransferResult\r
+               );\r
     //\r
     // Remove Control Transfer QH-TDs structure from the frame list\r
     // and update the pointers in the Frame List\r
@@ -2354,13 +2581,13 @@ UHCIBulkTransfer (
     // BusMasterWrite means cpu read\r
     //\r
     Status = HcDev->PciIo->Map (\r
-                            HcDev->PciIo,\r
-                            EfiPciIoOperationBusMasterWrite,\r
-                            PtrDataSource,\r
-                            &DataLen,\r
-                            &TempPtr,\r
-                            &Mapping\r
-                            );\r
+                             HcDev->PciIo,\r
+                             EfiPciIoOperationBusMasterWrite,\r
+                             PtrDataSource,\r
+                             &DataLen,\r
+                             &TempPtr,\r
+                             &Mapping\r
+                             );\r
     if (EFI_ERROR (Status)) {\r
       return Status;\r
     }\r
@@ -2377,13 +2604,13 @@ UHCIBulkTransfer (
     // BusMasterRead means cpu write\r
     //\r
     Status = HcDev->PciIo->Map (\r
-                            HcDev->PciIo,\r
-                            EfiPciIoOperationBusMasterRead,\r
-                            PtrDataSource,\r
-                            &DataLen,\r
-                            &TempPtr,\r
-                            &Mapping\r
-                            );\r
+                             HcDev->PciIo,\r
+                             EfiPciIoOperationBusMasterRead,\r
+                             PtrDataSource,\r
+                             &DataLen,\r
+                             &TempPtr,\r
+                             &Mapping\r
+                             );\r
     if (EFI_ERROR (Status)) {\r
       return Status;\r
     }\r
@@ -2422,16 +2649,16 @@ UHCIBulkTransfer (
     }\r
 \r
     Status = GenDataTD (\r
-              HcDev,\r
-              DeviceAddress,\r
-              EndPointAddress,\r
-              Ptr,\r
-              PktSize,\r
-              PktID,\r
-              *DataToggle,\r
-              FALSE,\r
-              &PtrTD\r
-              );\r
+               HcDev,\r
+               DeviceAddress,\r
+               EndPointAddress,\r
+               Ptr,\r
+               PktSize,\r
+               PktID,\r
+               *DataToggle,\r
+               FALSE,\r
+               &PtrTD\r
+               );\r
 \r
     if (EFI_ERROR (Status)) {\r
       HcDev->PciIo->Unmap (HcDev->PciIo, Mapping);\r
@@ -2526,14 +2753,14 @@ UHCIBulkTransfer (
   // of the last successful TD\r
   //\r
   Status = ExecBulkorSyncInterruptTransfer (\r
-            HcDev,\r
-            PtrFirstTD,\r
-            LoadFrameListIndex,\r
-            DataLength,\r
-            DataToggle,\r
-            TimeOut,\r
-            TransferResult\r
-            );\r
+             HcDev,\r
+             PtrFirstTD,\r
+             LoadFrameListIndex,\r
+             DataLength,\r
+             DataToggle,\r
+             TimeOut,\r
+             TransferResult\r
+             );\r
 \r
   //\r
   // Delete Bulk transfer QH-TD structure\r
@@ -2587,7 +2814,7 @@ UHCIAsyncInterruptTransfer (
   IN     UINT8                              DeviceAddress,\r
   IN     UINT8                              EndPointAddress,\r
   IN     BOOLEAN                            IsSlowDevice,\r
-  IN     UINT8                              MaxiumPacketLength,\r
+  IN     UINT8                              MaximumPacketLength,\r
   IN     BOOLEAN                            IsNewTransfer,\r
   IN OUT UINT8                              *DataToggle,\r
   IN     UINTN                              PollingInterval, OPTIONAL\r
@@ -2618,7 +2845,7 @@ UHCIAsyncInterruptTransfer (
     IsSlowDevice    Indicates whether the target device is slow device \r
                     or full-speed device.\r
                     \r
-    MaxiumPacketLength  Indicates the maximum packet size the target endpoint\r
+    MaximumPacketLength  Indicates the maximum packet size the target endpoint\r
                         is capable of sending or receiving.\r
                         \r
     IsNewTransfer   If TRUE, an asynchronous interrupt pipe is built between\r
@@ -2715,11 +2942,11 @@ UHCIAsyncInterruptTransfer (
     OldTpl = gBS->RaiseTPL (EFI_TPL_NOTIFY);\r
 \r
     Status = DeleteAsyncINTQHTDs (\r
-              HcDev,\r
-              DeviceAddress,\r
-              EndPointAddress,\r
-              DataToggle\r
-              );\r
+               HcDev,\r
+               DeviceAddress,\r
+               EndPointAddress,\r
+               DataToggle\r
+               );\r
 \r
     gBS->RestoreTPL (OldTpl);\r
 \r
@@ -2764,13 +2991,13 @@ UHCIAsyncInterruptTransfer (
   // BusMasterWrite means cpu read\r
   //\r
   Status = HcDev->PciIo->Map (\r
-                          HcDev->PciIo,\r
-                          EfiPciIoOperationBusMasterWrite,\r
-                          Ptr,\r
-                          &DataLen,\r
-                          &TempPtr,\r
-                          &Mapping\r
-                          );\r
+                           HcDev->PciIo,\r
+                           EfiPciIoOperationBusMasterWrite,\r
+                           Ptr,\r
+                           &DataLen,\r
+                           &TempPtr,\r
+                           &Mapping\r
+                           );\r
   if (EFI_ERROR (Status)) {\r
     gBS->FreePool (Ptr);\r
     return Status;\r
@@ -2788,23 +3015,23 @@ UHCIAsyncInterruptTransfer (
     //\r
         \r
     PktSize = (UINT8) DataLen;\r
-    if (DataLen > MaxiumPacketLength) {\r
-      PktSize = MaxiumPacketLength;\r
+    if (DataLen > MaximumPacketLength) {\r
+      PktSize = MaximumPacketLength;\r
     }\r
 \r
     Status = GenDataTD (\r
-              HcDev,\r
-              DeviceAddress,\r
-              EndPointAddress,\r
-              MappedPtr,\r
-              PktSize,\r
-              PktID,\r
-              CurrentDataToggle,\r
-              IsSlowDevice,\r
-              &PtrTD\r
-              );\r
-    if (EFI_ERROR (Status)) {\r
-      gBS->FreePool (Ptr);\r
+               HcDev,\r
+               DeviceAddress,\r
+               EndPointAddress,\r
+               MappedPtr,\r
+               PktSize,\r
+               PktID,\r
+               CurrentDataToggle,\r
+               IsSlowDevice,\r
+               &PtrTD\r
+               );\r
+    if (EFI_ERROR (Status)) {\r
+      gBS->FreePool (Ptr);\r
       HcDev->PciIo->Unmap (HcDev->PciIo, Mapping);\r
       DeleteQueuedTDs (HcDev, PtrFirstTD);\r
       return Status;\r
@@ -3084,6 +3311,10 @@ UHCISyncInterruptTransfer (
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
+  if (TransferResult == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
   ClearStatusReg (HcDev->PciIo, StatusReg);\r
 \r
   //\r
@@ -3357,6 +3588,830 @@ UHCIAsyncIsochronousTransfer (
   return EFI_UNSUPPORTED;\r
 }\r
 \r
+//\r
+// UEFI 2.0 Protocol\r
+//\r
+EFI_STATUS\r
+EFIAPI\r
+UHCI2GetCapability(\r
+  IN  EFI_USB2_HC_PROTOCOL  * This,\r
+  OUT UINT8                 *MaxSpeed,\r
+  OUT UINT8                 *PortNumber,\r
+  OUT UINT8                 *Is64BitCapable\r
+  )\r
+/*++\r
+\r
+  Routine Description:\r
+    Retrieves capabilities of USB host controller according to UEFI 2.0 spec.\r
+\r
+  Arguments:\r
+    This                      - A pointer to the EFI_USB2_HC_PROTOCOL instance.\r
+    \r
+    MaxSpeed             - A pointer to the max speed USB host controller supports.\r
+    \r
+    PortNumber           - A pointer to the number of root hub ports.\r
+    \r
+    Is64BitCapable      - A pointer to an integer to show whether USB host controller\r
+                                  supports 64-bit memory addressing.\r
+  Returns:\r
+    EFI_SUCCESS \r
+        The host controller capabilities 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
+  USB_HC_DEV *HcDev;\r
+\r
+  HcDev = USB2_HC_DEV_FROM_THIS (This);\r
+  \r
+  if ((NULL == MaxSpeed) \r
+       ||(NULL == PortNumber)\r
+       || (NULL == Is64BitCapable))\r
+  {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+  \r
+  *MaxSpeed = EFI_USB_SPEED_FULL;\r
+  *Is64BitCapable = (UINT8)FALSE;\r
+  return  UHCIGetRootHubPortNumber(&HcDev->UsbHc, PortNumber);\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+UHCI2Reset (\r
+  IN EFI_USB2_HC_PROTOCOL   * This,\r
+  IN UINT16                 Attributes\r
+  )\r
+/*++\r
+\r
+  Routine Description:\r
+    Provides software reset for the USB host controller according to UEFI 2.0 spec.\r
+\r
+  Arguments:\r
+    This           - A pointer to the EFI_USB2_HC_PROTOCOL instance.\r
+    \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\r
+  #define EFI_USB_HC_RESET_HOST_CONTROLLER             0x0002\r
+  #define EFI_USB_HC_RESET_GLOBAL _WITH_DEBUG          0x0004\r
+  #define EFI_USB_HC_RESET_HOST_WITH_DEBUG             0x0008\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
+  \r
+  Returns:\r
+    EFI_SUCCESS \r
+        The reset operation succeeded.\r
+    EFI_INVALID_PARAMETER \r
+        Attributes is not valid.\r
+    EFI_UNSUPPORTED\r
+        The type of reset specified by Attributes is not currently supported by the host controller hardware.\r
+    EFI_ACCESS_DENIED\r
+        Reset operation is rejected due to the debug port being configured and active.\r
+    EFI_DEVICE_ERROR  \r
+        An error was encountered while attempting to perform \r
+        the reset operation.\r
+--*/\r
+{\r
+  USB_HC_DEV *HcDev;\r
+\r
+  HcDev = USB2_HC_DEV_FROM_THIS (This);\r
+  \r
+  if (Attributes==EFI_USB_HC_RESET_GLOBAL_WITH_DEBUG || Attributes==EFI_USB_HC_RESET_HOST_WITH_DEBUG)\r
+       return EFI_UNSUPPORTED;\r
+  \r
+  return UHCIReset(\r
+       &HcDev->UsbHc, \r
+       Attributes\r
+       );\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+UHCI2GetState (\r
+  IN  EFI_USB2_HC_PROTOCOL   * This,\r
+  OUT EFI_USB_HC_STATE       * State\r
+  )\r
+/*++\r
+  \r
+  Routine Description:\r
+    Retrieves current state of the USB host controller according to UEFI 2.0 spec.\r
+  \r
+  Arguments:\r
+    \r
+    This     - A pointer to the EFI_USB_HC_PROTOCOL instance.\r
+    \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
+    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
+  USB_HC_DEV *HcDev;\r
+\r
+  HcDev = USB2_HC_DEV_FROM_THIS (This);\r
+  return UHCIGetState(\r
+       &HcDev->UsbHc, \r
+       State\r
+       );\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+UHCI2SetState (\r
+  IN EFI_USB2_HC_PROTOCOL    * This,\r
+  IN EFI_USB_HC_STATE        State\r
+  )\r
+/*++\r
+  \r
+  Routine Description:\r
+    Sets the USB host controller to a specific state according to UEFI 2.0 spec.\r
+  \r
+  Arguments:\r
+    \r
+    This     - A pointer to the EFI_USB_HC_PROTOCOL instance.\r
+\r
+    State    - Indicates the state of the host controller that will be set.\r
+  \r
+  Returns:\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
+  USB_HC_DEV *HcDev;\r
+\r
+  HcDev = USB2_HC_DEV_FROM_THIS (This);\r
+  return UHCISetState(\r
+       &HcDev->UsbHc, \r
+       State\r
+       );\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+UHCI2ControlTransfer (\r
+  IN     EFI_USB2_HC_PROTOCOL                           * This,\r
+  IN     UINT8                                          DeviceAddress,\r
+  IN     UINT8                                          DeviceSpeed,\r
+  IN     UINTN                                          MaximumPacketLength,\r
+  IN     EFI_USB_DEVICE_REQUEST                         * Request,\r
+  IN     EFI_USB_DATA_DIRECTION                         TransferDirection,\r
+  IN OUT VOID                                           *Data,\r
+  IN OUT UINTN                                          *DataLength,\r
+  IN     UINTN                                          TimeOut,\r
+  IN     EFI_USB2_HC_TRANSACTION_TRANSLATOR             *Translator,\r
+  OUT    UINT32                                         *TransferResult\r
+  )\r
+/*++\r
+  \r
+  Routine Description:\r
+    Submits control transfer to a target USB device accroding to UEFI 2.0 spec..\r
+  \r
+  Arguments:\r
+    \r
+    This         - A pointer to the EFI_USB_HC_PROTOCOL instance.\r
+\r
+    DeviceAddress -Represents the address of the target device on the USB,\r
+                  which is assigned during USB enumeration.\r
+\r
+    DeviceSpeed  - Indicates transfer speed of device.\r
+    \r
+    MaximumPacketLength - Indicates the maximum packet size that the \r
+                        default control transfer endpoint is capable of \r
+                        sending or receiving.\r
+    \r
+    Request      - A pointer to the USB device request that will be sent \r
+                  to the USB device. \r
+    \r
+    TransferDirection - Specifies the data direction for the transfer.\r
+                      There are three values available, DataIn, DataOut \r
+                      and NoData.\r
+    \r
+    Data          -A pointer to the buffer of data that will be transmitted \r
+                  to USB device or received from USB device.\r
+    \r
+    DataLength    - Indicates the size, in bytes, of the data buffer \r
+                  specified by Data.\r
+    \r
+    TimeOut       - Indicates the maximum time, in microseconds, \r
+                  which the transfer is allowed to complete.\r
+    \r
+    TransferResult  - A pointer to the detailed result information generated \r
+                    by this control transfer.\r
+                    \r
+  Returns:\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
+  USB_HC_DEV *HcDev;\r
+  BOOLEAN IsSlowDevice = (EFI_USB_SPEED_LOW == DeviceSpeed) ? TRUE : FALSE;\r
+\r
+  HcDev = USB2_HC_DEV_FROM_THIS (This);\r
+  \r
+  return UHCIControlTransfer(\r
+       &HcDev->UsbHc, \r
+       DeviceAddress, \r
+       IsSlowDevice, \r
+       (UINT8) MaximumPacketLength, \r
+       Request, \r
+       TransferDirection, \r
+       Data, \r
+       DataLength,\r
+       TimeOut,\r
+       TransferResult\r
+       );      \r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+UHCI2BulkTransfer (\r
+  IN     EFI_USB2_HC_PROTOCOL                            * This,\r
+  IN     UINT8                                           DeviceAddress,\r
+  IN     UINT8                                           EndPointAddress,\r
+  IN     UINT8                                           DeviceSpeed,\r
+  IN     UINTN                                           MaximumPacketLength,\r
+  IN     UINT8                                           DataBuffersNumber,\r
+  IN OUT VOID                                            *Data[EFI_USB_MAX_BULK_BUFFER_NUM],\r
+  IN OUT UINTN                                           *DataLength,\r
+  IN OUT UINT8                                           *DataToggle,\r
+  IN     UINTN                                           TimeOut,\r
+  IN     EFI_USB2_HC_TRANSACTION_TRANSLATOR              *Translator,\r
+  OUT    UINT32                                          *TransferResult\r
+  )                                                  \r
+/*++\r
+  \r
+  Routine Description:\r
+    Submits bulk transfer to a bulk endpoint of a USB device according to UEFI 2.0 spec.\r
+    \r
+  Arguments:\r
+    \r
+    This          A pointer to the EFI_USB2_HC_PROTOCOL instance.\r
+    \r
+    DeviceAddress Represents the address of the target device on the USB,\r
+                  which is assigned during USB enumeration.\r
+                  \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
+                      \r
+    DeviceSpeed  Indicates device speed. The supported values are EFI_USB_SPEED_FULL\r
+                          and EFI_USB_SPEED_HIGH.\r
+                          \r
+    MaximumPacketLength Indicates the maximum packet size the target endpoint\r
+                        is capable of sending or receiving.\r
+                        \r
+    DataBuffersNumber  Number of data buffers prepared for the transfer.\r
+    \r
+    Data          Array of pointers to the buffers of data that will be transmitted \r
+                  to USB device or received from USB device.\r
+                  \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
+                  \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
+                  \r
+    Translator  A pointr to the transaction translator data.\r
+    \r
+    TimeOut       Indicates the maximum time, in microseconds, which the \r
+                  transfer is allowed to complete.\r
+                  \r
+    TransferResult  A pointer to the detailed result information of the \r
+                    bulk transfer.\r
+\r
+  Returns:\r
+    EFI_SUCCESS \r
+        The bulk transfer was completed successfully.\r
+        \r
+    EFI_OUT_OF_RESOURCES  \r
+        The bulk transfer could not be submitted due to lack of resource.\r
+        \r
+    EFI_INVALID_PARAMETER \r
+        Some parameters are invalid.\r
+        \r
+    EFI_TIMEOUT \r
+        The bulk transfer failed due to timeout.\r
+        \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
+  USB_HC_DEV *HcDev;\r
+\r
+  HcDev = USB2_HC_DEV_FROM_THIS (This);\r
+  \r
+  if( Data == NULL || DeviceSpeed==EFI_USB_SPEED_LOW)\r
+       return EFI_INVALID_PARAMETER;\r
+  /* For full-speed bulk transfers only the data pointed by Data[0] shall be used */\r
+\r
+  return UHCIBulkTransfer (\r
+       &HcDev->UsbHc, \r
+       DeviceAddress, \r
+       EndPointAddress, \r
+       (UINT8) MaximumPacketLength, \r
+       *Data, \r
+       DataLength, \r
+       DataToggle, \r
+       TimeOut, \r
+       TransferResult\r
+       );\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+UHCI2AsyncInterruptTransfer (\r
+  IN     EFI_USB2_HC_PROTOCOL                        * This,\r
+  IN     UINT8                                       DeviceAddress,\r
+  IN     UINT8                                       EndPointAddress,\r
+  IN     UINT8                                       DeviceSpeed,\r
+  IN     UINTN                                       MaximumPacketLength,\r
+  IN     BOOLEAN                                     IsNewTransfer,\r
+  IN OUT UINT8                                       *DataToggle,\r
+  IN     UINTN                                       PollingInterval,\r
+  IN     UINTN                                       DataLength,\r
+  IN     EFI_USB2_HC_TRANSACTION_TRANSLATOR          *Translator,\r
+  IN     EFI_ASYNC_USB_TRANSFER_CALLBACK             CallBackFunction,\r
+  IN     VOID                                        *Context\r
+  )\r
+/*++\r
+  \r
+  Routine Description:\r
+    Submits an asynchronous interrupt transfer to an \r
+    interrupt endpoint of a USB device according to UEFI 2.0 spec.\r
+  \r
+  Arguments:\r
+    \r
+    This            A pointer to the EFI_USB2_HC_PROTOCOL instance.\r
+    \r
+    DeviceAddress   Represents the address of the target device on the USB,\r
+                    which is assigned during USB enumeration.\r
+                    \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
+                    \r
+    DeviceSpeed     Indicates device speed.\r
+    \r
+    MaximumPacketLength  Indicates the maximum packet size the target endpoint\r
+                        is capable of sending or receiving.\r
+                        \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
+                    \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
+                    \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
+                    \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
+                    \r
+    Translator  A pointr to the transaction translator data.\r
+    \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
+                      \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
+        \r
+    EFI_INVALID_PARAMETER \r
+        Some parameters are invalid.\r
+        \r
+    EFI_OUT_OF_RESOURCES  \r
+        The request could not be completed due to a lack of resources.  \r
+        \r
+    EFI_DEVICE_ERROR\r
+        Can't read register\r
+--*/  \r
+{\r
+  USB_HC_DEV *HcDev;\r
+  BOOLEAN IsSlowDevice = (EFI_USB_SPEED_LOW == DeviceSpeed) ? TRUE : FALSE;\r
+   \r
+  HcDev = USB2_HC_DEV_FROM_THIS (This);\r
+  return UHCIAsyncInterruptTransfer(\r
+       &HcDev->UsbHc, \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
+EFI_STATUS\r
+EFIAPI\r
+UHCI2SyncInterruptTransfer (\r
+  IN     EFI_USB2_HC_PROTOCOL                      * This,\r
+  IN     UINT8                                     DeviceAddress,\r
+  IN     UINT8                                     EndPointAddress,\r
+  IN     UINT8                                     DeviceSpeed,\r
+  IN     UINTN                                     MaximumPacketLength,\r
+  IN OUT VOID                                      *Data,\r
+  IN OUT UINTN                                     *DataLength,\r
+  IN OUT UINT8                                     *DataToggle,\r
+  IN     UINTN                                     TimeOut,\r
+  IN     EFI_USB2_HC_TRANSACTION_TRANSLATOR        *Translator,\r
+  OUT    UINT32                                    *TransferResult\r
+  )\r
+/*++\r
+  \r
+  Routine Description:\r
+    Submits synchronous interrupt transfer to an interrupt endpoint \r
+    of a USB device according to UEFI 2.0 spec.\r
+  \r
+  Arguments:\r
+    \r
+    This            A pointer to the EFI_USB2_HC_PROTOCOL instance.\r
+    \r
+    DeviceAddress   Represents the address of the target device on the USB, \r
+                    which is assigned during USB enumeration.\r
+                    \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
+                      \r
+    DeviceSpeed  Indicates device speed.\r
+                    \r
+    MaximumPacketLength Indicates the maximum packet size the target endpoint \r
+                        is capable of sending or receiving.\r
+                        \r
+    Data            A pointer to the buffer of data that will be transmitted \r
+                    to USB device or received from USB device.\r
+                    \r
+    DataLength      On input, the size, in bytes, of the data buffer specified \r
+                    by Data. On output, the number of bytes transferred.\r
+                    \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
+                    \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
+    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
+  USB_HC_DEV *HcDev;\r
+  BOOLEAN IsSlowDevice;\r
+  \r
+  if(DeviceSpeed==EFI_USB_SPEED_HIGH)\r
+       return EFI_INVALID_PARAMETER;\r
+  \r
+  IsSlowDevice = (EFI_USB_SPEED_LOW == DeviceSpeed) ? TRUE : FALSE;  \r
+  HcDev = USB2_HC_DEV_FROM_THIS (This);\r
+  \r
+  return UHCISyncInterruptTransfer(\r
+       &HcDev->UsbHc, \r
+       DeviceAddress, \r
+       EndPointAddress, \r
+       IsSlowDevice, \r
+       (UINT8) MaximumPacketLength, \r
+       Data, \r
+       DataLength, \r
+       DataToggle,\r
+       TimeOut,\r
+       TransferResult\r
+       );\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+UHCI2IsochronousTransfer (\r
+  IN     EFI_USB2_HC_PROTOCOL                       * This,\r
+  IN     UINT8                                      DeviceAddress,\r
+  IN     UINT8                                      EndPointAddress,\r
+  IN     UINT8                                      DeviceSpeed,\r
+  IN     UINTN                                      MaximumPacketLength,\r
+  IN     UINT8                                      DataBuffersNumber,\r
+  IN OUT VOID                                       *Data[EFI_USB_MAX_ISO_BUFFER_NUM],\r
+  IN     UINTN                                      DataLength,\r
+  IN     EFI_USB2_HC_TRANSACTION_TRANSLATOR         *Translator,\r
+  OUT    UINT32                                     *TransferResult\r
+  )\r
+/*++\r
+  \r
+  Routine Description:\r
+  \r
+    Submits isochronous transfer to a target USB device according to UEFI 2.0 spec.\r
+  \r
+  Arguments:\r
+    \r
+    This             A pointer to the EFI_USB2_HC_PROTOCOL instance.\r
+    \r
+    DeviceAddress    Represents the address of the target device on the USB,\r
+                           which is assigned during USB enumeration.\r
+                           \r
+    EndPointAddress  End point address\r
+    \r
+    DeviceSpeed      Indicates device speed.\r
+    \r
+    MaximumPacketLength    Indicates the maximum packet size that the \r
+                           default control transfer endpoint is capable of \r
+                           sending or receiving.\r
+                           \r
+    DataBuffersNumber Number of data buffers prepared for the transfer.\r
+    \r
+    Data              Array of pointers to the buffers of data that will be \r
+                      transmitted to USB device or received from USB device.\r
+                  \r
+    DataLength        Indicates the size, in bytes, of the data buffer \r
+                      specified by Data.\r
+                           \r
+    Translator        A pointr to the transaction translator data.\r
+    \r
+    TransferResult    A pointer to the detailed result information generated \r
+                      by this control transfer.               \r
+  Returns:\r
+  \r
+    EFI_UNSUPPORTED \r
+\r
+--*/  \r
+{\r
+  return EFI_UNSUPPORTED;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+UHCI2AsyncIsochronousTransfer (\r
+  IN     EFI_USB2_HC_PROTOCOL                         * This,\r
+  IN     UINT8                                        DeviceAddress,\r
+  IN     UINT8                                        EndPointAddress,\r
+  IN     UINT8                                        DeviceSpeed,\r
+  IN     UINTN                                        MaximumPacketLength,\r
+  IN     UINT8                                        DataBuffersNumber,\r
+  IN OUT VOID                                         *Data[EFI_USB_MAX_ISO_BUFFER_NUM],\r
+  IN     UINTN                                        DataLength,\r
+  IN     EFI_USB2_HC_TRANSACTION_TRANSLATOR           *Translator,\r
+  IN     EFI_ASYNC_USB_TRANSFER_CALLBACK              IsochronousCallBack,\r
+  IN     VOID                                         *Context\r
+  )\r
+/*++\r
+  \r
+  Routine Description:\r
+  \r
+    Submits Async isochronous transfer to a target USB device according to UEFI 2.0 spec.\r
+  \r
+  Arguments:\r
+    \r
+    This                A pointer to the EFI_USB2_HC_PROTOCOL instance.\r
+    \r
+    DeviceAddress       Represents the address of the target device on the USB,\r
+                           which is assigned during USB enumeration.\r
+\r
+    EndPointAddress     End point address\r
+    \r
+    DeviceSpeed         Indicates device speed.\r
+    \r
+    MaximumPacketLength Indicates the maximum packet size that the \r
+                        default control transfer endpoint is capable of \r
+                        sending or receiving.\r
+                        \r
+    DataBuffersNumber   Number of data buffers prepared for the transfer.\r
+    \r
+    Data                Array of pointers to the buffers of data that will be transmitted \r
+                        to USB device or received from USB device.\r
+                        \r
+    Translator          A pointr to the transaction translator data.\r
+    \r
+    IsochronousCallBack When the transfer complete, the call back function will be called\r
+    \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
+\r
+EFI_STATUS\r
+EFIAPI\r
+UHCI2GetRootHubPortStatus (\r
+  IN  EFI_USB2_HC_PROTOCOL   * This,\r
+  IN  UINT8                  PortNumber,\r
+  OUT EFI_USB_PORT_STATUS    * PortStatus\r
+  )\r
+/*++\r
+  \r
+  Routine Description:\r
+    Retrieves the current status of a USB root hub port according to UEFI 2.0 spec.\r
+  \r
+  Arguments:\r
+  \r
+    This        A pointer to the EFI_USB2_HC_PROTOCOL.\r
+    \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
+    \r
+    PortStatus  A pointer to the current port status bits and \r
+                port status change bits.  \r
+  \r
+  Returns:\r
+    EFI_SUCCESS \r
+        The status of the USB root hub port specified by PortNumber \r
+        was returned in PortStatus.\r
+    EFI_INVALID_PARAMETER \r
+        PortNumber is invalid. \r
+    EFI_DEVICE_ERROR - Can't read register      \r
+--*/     \r
+{\r
+  USB_HC_DEV *HcDev;\r
+\r
+  HcDev = USB2_HC_DEV_FROM_THIS (This);\r
+  \r
+  return UHCIGetRootHubPortStatus(\r
+       &HcDev->UsbHc, \r
+       PortNumber, \r
+       PortStatus\r
+       );\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+UHCI2SetRootHubPortFeature (\r
+  IN EFI_USB2_HC_PROTOCOL     * This,\r
+  IN UINT8                   PortNumber,\r
+  IN EFI_USB_PORT_FEATURE    PortFeature\r
+  )\r
+/*++\r
+  \r
+  Routine Description:\r
+    Sets a feature for the specified root hub port according to UEFI 2.0 spec.\r
+  \r
+  Arguments:\r
+  \r
+    This        A pointer to the EFI_USB2_HC_PROTOCOL.\r
+    \r
+    PortNumber  Specifies the root hub port whose feature \r
+                is requested to be set.\r
+    \r
+    PortFeature Indicates the feature selector associated \r
+                with the feature set request. \r
+  \r
+  Returns:\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
+  USB_HC_DEV *HcDev;\r
+\r
+  HcDev = USB2_HC_DEV_FROM_THIS (This);\r
+  return UHCISetRootHubPortFeature(\r
+       &HcDev->UsbHc, \r
+       PortNumber, \r
+       PortFeature\r
+       );\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+UHCI2ClearRootHubPortFeature (\r
+  IN EFI_USB2_HC_PROTOCOL    * This,\r
+  IN UINT8                   PortNumber,\r
+  IN EFI_USB_PORT_FEATURE    PortFeature\r
+  )\r
+/*++\r
+  \r
+  Routine Description:\r
+    Clears a feature for the specified root hub port according to Uefi 2.0 spec.\r
+  \r
+  Arguments:\r
+  \r
+    This        A pointer to the EFI_USB2_HC_PROTOCOL instance.\r
+    \r
+    PortNumber  Specifies the root hub port whose feature \r
+                is requested to be cleared.\r
+    \r
+    PortFeature Indicates the feature selector associated with the \r
+                feature clear request.\r
+                  \r
+  Returns:\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
+  USB_HC_DEV *HcDev;\r
+\r
+  HcDev = USB2_HC_DEV_FROM_THIS (This);\r
+  return UHCIClearRootHubPortFeature(\r
+       &HcDev->UsbHc, \r
+       PortNumber, \r
+       PortFeature\r
+       );\r
+}\r
+\r
 VOID\r
 EFIAPI\r
 MonitorInterruptTrans (\r
index d6f841bf40dd36ff8cd56dc080b2724c782a8d78..c5ae155f9091740ba47110a73cb8a81149eb086e 100644 (file)
@@ -28,7 +28,7 @@ Revision History
 \r
 #include <IndustryStandard/pci22.h>\r
 \r
-#define EFI_D_UHCI  EFI_D_INFO\r
+#define EFI_D_UHCI                EFI_D_INFO\r
 \r
 //\r
 // stall time\r
@@ -45,21 +45,20 @@ Revision History
 //\r
 // 50 ms\r
 //\r
-#define INTERRUPT_POLLING_TIME  50 * 1000 * 10\r
+#define INTERRUPT_POLLING_TIME    50 * 1000 * 10\r
 \r
 //\r
 // UHCI IO Space Address Register Register locates at\r
 // offset 20 ~ 23h of PCI Configuration Space (UHCI spec, Revision 1.1),\r
 // so, its BAR Index is 4.\r
 //\r
-#define USB_BAR_INDEX 4\r
+#define USB_BAR_INDEX             4\r
 \r
 //\r
 // One memory block uses 1 page (common buffer for QH,TD use.)\r
 //\r
 #define NORMAL_MEMORY_BLOCK_UNIT_IN_PAGES 1\r
 \r
-\r
 #define bit(a)                            1 << (a)\r
 \r
 //\r
@@ -82,13 +81,13 @@ extern UINT16 USBBaseAddr;
 #define USBCMD_MAXP     bit (7) /* Max Packet (0 = 32, 1 = 64) */\r
 \r
 /* Status register */\r
-#define USBSTS        2       /* Status Register Offset 02-03h */\r
-#define USBSTS_USBINT bit (0) /* Interrupt due to IOC */\r
-#define USBSTS_ERROR  bit (1) /* Interrupt due to error */\r
-#define USBSTS_RD     bit (2) /* Resume Detect */\r
-#define USBSTS_HSE    bit (3) /* Host System Error*/\r
-#define USBSTS_HCPE   bit (4) /* Host Controller Process Error*/\r
-#define USBSTS_HCH    bit (5) /* HC Halted */\r
+#define USBSTS          2       /* Status Register Offset 02-03h */\r
+#define USBSTS_USBINT   bit (0) /* Interrupt due to IOC */\r
+#define USBSTS_ERROR    bit (1) /* Interrupt due to error */\r
+#define USBSTS_RD       bit (2) /* Resume Detect */\r
+#define USBSTS_HSE      bit (3) /* Host System Error*/\r
+#define USBSTS_HCPE     bit (4) /* Host Controller Process Error*/\r
+#define USBSTS_HCH      bit (5) /* HC Halted */\r
 \r
 /* Interrupt enable register */\r
 #define USBINTR         4       /* Interrupt Enable Register 04-05h */\r
@@ -98,13 +97,13 @@ extern UINT16 USBBaseAddr;
 #define USBINTR_SP      bit (3) /* Short packet interrupt enable */\r
 \r
 /* Frame Number Register Offset 06-08h */\r
-#define USBFRNUM  6\r
+#define USBFRNUM       6\r
 \r
 /* Frame List Base Address Register Offset 08-0Bh */\r
-#define USBFLBASEADD  8\r
+#define USBFLBASEADD   8\r
 \r
 /* Start of Frame Modify Register Offset 0Ch */\r
-#define USBSOF  0x0c\r
+#define USBSOF         0x0c\r
 \r
 /* USB port status and control registers */\r
 #define USBPORTSC1      0x10      /*Port 1 offset 10-11h */\r
@@ -126,16 +125,16 @@ extern UINT16 USBBaseAddr;
 //\r
 // Class Code Register offset\r
 //\r
-#define CLASSC  0x09\r
+#define CLASSC          0x09\r
 //\r
 // USB IO Space Base Address Register offset\r
 //\r
-#define USBBASE 0x20\r
+#define USBBASE         0x20\r
 \r
 //\r
 // USB legacy Support\r
 //\r
-#define USB_EMULATION 0xc0\r
+#define USB_EMULATION   0xc0\r
 \r
 //\r
 // USB Base Class Code,Sub-Class Code and Programming Interface.\r
@@ -224,6 +223,7 @@ typedef struct {
 //\r
 //////////////////////////////////////////////////////////////////////////\r
 #define USB_HC_DEV_FROM_THIS(a)   CR (a, USB_HC_DEV, UsbHc, USB_HC_DEV_SIGNATURE)\r
+#define USB2_HC_DEV_FROM_THIS(a)  CR (a, USB_HC_DEV, Usb2Hc, USB_HC_DEV_SIGNATURE)\r
 \r
 #define USB_HC_DEV_SIGNATURE      EFI_SIGNATURE_32 ('u', 'h', 'c', 'i')\r
 #define INTERRUPT_LIST_SIGNATURE  EFI_SIGNATURE_32 ('i', 'n', 't', 's')\r
@@ -267,6 +267,7 @@ typedef struct _MEMORY_MANAGE_HEADER {
 typedef struct {\r
   UINTN                     Signature;\r
   EFI_USB_HC_PROTOCOL       UsbHc;\r
+  EFI_USB2_HC_PROTOCOL      Usb2Hc;\r
   EFI_PCI_IO_PROTOCOL       *PciIo;\r
 \r
   //\r
@@ -289,234 +290,723 @@ WriteUHCCommandReg (
   IN EFI_PCI_IO_PROTOCOL     *PciIo,\r
   IN UINT32                  CmdAddrOffset,\r
   IN UINT16                  UsbCmd\r
-  );\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Write UHCI Command Register\r
+\r
+Arguments:\r
+\r
+  PciIo         - EFI_PCI_IO_PROTOCOL\r
+  CmdAddrOffset - Command address offset\r
+  UsbCmd        - Data to write\r
+\r
+Returns:\r
+\r
+  EFI_SUCCESS\r
+\r
+--*/\r
+;\r
 \r
 EFI_STATUS\r
 ReadUHCCommandReg (\r
   IN       EFI_PCI_IO_PROTOCOL     *PciIo,\r
   IN       UINT32                  CmdAddrOffset,\r
   IN OUT   UINT16                  *Data\r
-  );\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Read UHCI Command Register\r
+\r
+Arguments:\r
+\r
+  PciIo         - EFI_PCI_IO_PROTOCOL\r
+  CmdAddrOffset - Command address offset\r
+  Data          - Data to return\r
+\r
+Returns:\r
+\r
+  EFI_SUCCESS\r
+\r
+--*/\r
+;\r
 \r
 EFI_STATUS\r
 WriteUHCStatusReg (\r
   IN EFI_PCI_IO_PROTOCOL     *PciIo,\r
   IN UINT32                  StatusAddrOffset,\r
   IN UINT16                  UsbSts\r
-  );\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Write UHCI Staus Register\r
+\r
+Arguments:\r
+\r
+  PciIo            - EFI_PCI_IO_PROTOCOL\r
+  StatusAddrOffset - Status address offset\r
+  UsbSts           - Data to write\r
+\r
+Returns:\r
+\r
+  EFI_SUCCESS\r
+\r
+--*/\r
+;\r
 \r
 EFI_STATUS\r
 ReadUHCStatusReg (\r
   IN       EFI_PCI_IO_PROTOCOL     *PciIo,\r
   IN       UINT32                  StatusAddrOffset,\r
   IN OUT   UINT16                  *Data\r
-  );\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Read UHCI Staus Register\r
+\r
+Arguments:\r
+\r
+  PciIo            - EFI_PCI_IO_PROTOCOL\r
+  StatusAddrOffset - Status address offset\r
+  UsbSts           - Data to return\r
+\r
+Returns:\r
+\r
+  EFI_SUCCESS\r
+\r
+--*/\r
+;\r
 \r
 EFI_STATUS\r
 ClearStatusReg (\r
   IN EFI_PCI_IO_PROTOCOL     *PciIo,\r
   IN UINT32                  StatusAddrOffset\r
-  );\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Clear the content of UHC's Status Register\r
+\r
+Arguments:\r
+\r
+  PciIo             - EFI_PCI_IO_PROTOCOL\r
+  StatusAddrOffset  - Status address offset\r
+  \r
+Returns:\r
+\r
+  EFI_SUCCESS\r
+\r
+--*/\r
+;\r
 \r
 EFI_STATUS\r
 ReadUHCFrameNumberReg (\r
   IN       EFI_PCI_IO_PROTOCOL     *PciIo,\r
   IN       UINT32                  FrameNumAddrOffset,\r
   IN OUT   UINT16                  *Data\r
-  );\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Read from UHC's Frame Number Register\r
+\r
+Arguments:\r
+\r
+  PciIo              - EFI_PCI_IO_PROTOCOL\r
+  FrameNumAddrOffset - Frame number register offset\r
+  Data               - Data to return \r
+Returns:\r
+\r
+  EFI_SUCCESS\r
+\r
+--*/\r
+;\r
 \r
 EFI_STATUS\r
 WriteUHCFrameListBaseReg (\r
   IN EFI_PCI_IO_PROTOCOL     *PciIo,\r
   IN UINT32                  FlBaseAddrOffset,\r
   IN UINT32                  UsbFrameListBaseAddr\r
-  );\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Write to UHC's Frame List Base Register\r
+\r
+Arguments:\r
+\r
+  PciIo                - EFI_PCI_IO_PROTOCOL\r
+  FlBaseAddrOffset     - Frame Base address register\r
+  UsbFrameListBaseAddr - Address to write\r
+\r
+Returns:\r
+\r
+  EFI_SUCCESS\r
+\r
+--*/\r
+;\r
 \r
 EFI_STATUS\r
 ReadRootPortReg (\r
   IN       EFI_PCI_IO_PROTOCOL     *PciIo,\r
   IN       UINT32                  PortAddrOffset,\r
   IN OUT   UINT16                  *Data\r
-  );\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Read from UHC's Root Port Register\r
+\r
+Arguments:\r
+\r
+  PciIo           - EFI_PCI_IO_PROTOCOL\r
+  PortAddrOffset  - Port Addrress Offset,\r
+  Data            - Data to return\r
+Returns:\r
+\r
+  EFI_SUCCESS\r
+\r
+--*/\r
+;\r
 \r
 EFI_STATUS\r
 WriteRootPortReg (\r
   IN EFI_PCI_IO_PROTOCOL     *PciIo,\r
   IN UINT32                  PortAddrOffset,\r
   IN UINT16                  ControlBits\r
-  );\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+   Write to UHC's Root Port Register\r
+\r
+Arguments:\r
+\r
+  PciIo           - EFI_PCI_IO_PROTOCOL\r
+  PortAddrOffset  - Port Addrress Offset,\r
+  ControlBits     - Data to write\r
+Returns:\r
+\r
+  EFI_SUCCESS\r
+\r
+--*/\r
+;\r
 \r
 EFI_STATUS\r
 WaitForUHCHalt (\r
   IN EFI_PCI_IO_PROTOCOL      *PciIo,\r
   IN UINT32                   StatusRegAddr,\r
   IN UINTN                    Timeout\r
-  );\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Wait until UHCI halt or timeout\r
+\r
+Arguments:\r
+\r
+  PciIo         - EFI_PCI_IO_PROTOCOL\r
+  StatusRegAddr - Status Register Address\r
+  Timeout       - Time out value in us\r
+\r
+Returns:\r
+\r
+  EFI_DEVICE_ERROR - Unable to read the status register\r
+  EFI_TIMEOUT      - Time out\r
+  EFI_SUCCESS      - Success\r
+\r
+--*/\r
+;\r
 \r
 BOOLEAN\r
 IsStatusOK (\r
   IN EFI_PCI_IO_PROTOCOL     *PciIo,\r
   IN UINT32                  StatusRegAddr\r
-  );\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Judge whether the host controller operates well\r
+\r
+Arguments:\r
+\r
+  PciIo         - EFI_PCI_IO_PROTOCOL\r
+  StatusRegAddr - Status register address\r
+\r
+Returns:\r
+\r
+   TRUE  -  Status is good\r
+   FALSE -  Status is bad\r
+\r
+--*/\r
+;\r
 \r
 BOOLEAN\r
 IsHostSysOrProcessErr (\r
   IN EFI_PCI_IO_PROTOCOL     *PciIo,\r
   IN UINT32                  StatusRegAddr\r
-  );\r
+  )\r
+/*++\r
 \r
-//\r
-// This routine programs the USB frame number register. We assume that the\r
-// HC schedule execution is stopped.\r
-//\r
-EFI_STATUS\r
-SetFrameNumberReg (\r
-  IN EFI_PCI_IO_PROTOCOL     *PciIo,\r
-  IN UINT32                  FRNUMAddr,\r
-  IN UINT16                  Index\r
-  );\r
+Routine Description:\r
+\r
+  Judge the status is HostSys,ProcessErr error or good\r
+\r
+Arguments:\r
+\r
+  PciIo         - EFI_PCI_IO_PROTOCOL\r
+  StatusRegAddr - Status register address\r
+\r
+Returns:\r
+\r
+   TRUE  -  Status is good\r
+   FALSE -  Status is bad\r
+\r
+--*/\r
+;\r
 \r
 UINT16\r
 GetCurrentFrameNumber (\r
   IN EFI_PCI_IO_PROTOCOL     *PciIo,\r
-  IN UINT32                  FRNUMAddr\r
-  );\r
+  IN UINT32                  FrameNumAddrOffset\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Get Current Frame Number\r
+\r
+Arguments:\r
+\r
+  PciIo               - EFI_PCI_IO_PROTOCOL\r
+  FrameNumAddrOffset  - FrameNum register AddrOffset\r
+\r
+Returns:\r
+\r
+  Frame number \r
+\r
+--*/\r
+;\r
 \r
 EFI_STATUS\r
 SetFrameListBaseAddress (\r
   IN EFI_PCI_IO_PROTOCOL     *PciIo,\r
   IN UINT32                  FLBASEADDRReg,\r
   IN UINT32                  Addr\r
-  );\r
-\r
-UINT32\r
-GetFrameListBaseAddress (\r
-  IN EFI_PCI_IO_PROTOCOL     *PciIo,\r
-  IN UINT32                  FLBAddr\r
-  );\r
+  )\r
+/*++\r
 \r
-EFI_STATUS\r
-CreateFrameList (\r
-  IN USB_HC_DEV     *HcDev,\r
-  IN UINT32         FLBASEADDRReg\r
-  );\r
+Routine Description:\r
 \r
-EFI_STATUS\r
-FreeFrameListEntry (\r
-  IN USB_HC_DEV     *UhcDev\r
-  );\r
+  Set FrameListBase Address\r
 \r
-VOID\r
-InitFrameList (\r
-  IN USB_HC_DEV     *HcDev\r
-  );\r
+Arguments:\r
 \r
+  PciIo         - EFI_PCI_IO_PROTOCOL\r
+  FlBaseAddrReg - FrameListBase register\r
+  Addr          - Address to set\r
 \r
-EFI_STATUS\r
-CreateQH (\r
-  IN  USB_HC_DEV     *HcDev,\r
-  OUT QH_STRUCT      **pptrQH\r
-  );\r
+Returns:\r
 \r
-VOID\r
-SetQHHorizontalLinkPtr (\r
-  IN QH_STRUCT     *ptrQH,\r
-  IN VOID          *ptrNext\r
-  );\r
+  EFI_SUCCESS\r
 \r
-VOID *\r
-GetQHHorizontalLinkPtr (\r
-  IN QH_STRUCT     *ptrQH\r
-  );\r
+--*/\r
+;\r
 \r
-VOID\r
-SetQHHorizontalQHorTDSelect (\r
-  IN QH_STRUCT     *ptrQH,\r
-  IN BOOLEAN       bQH\r
-  );\r
+UINT32\r
+GetFrameListBaseAddress (\r
+  IN EFI_PCI_IO_PROTOCOL     *PciIo,\r
+  IN UINT32                  FLBAddr\r
+  )\r
+/*++\r
 \r
-VOID\r
-SetQHHorizontalValidorInvalid (\r
-  IN QH_STRUCT     *ptrQH,\r
-  IN BOOLEAN       bValid\r
-  );\r
+Routine Description:\r
 \r
-VOID\r
-SetQHVerticalLinkPtr (\r
-  IN QH_STRUCT     *ptrQH,\r
-  IN VOID          *ptrNext\r
-  );\r
+  Get Current Frame Number\r
 \r
-VOID * \r
-GetQHVerticalLinkPtr (\r
-  IN QH_STRUCT     *ptrQH\r
-  );\r
+Arguments:\r
 \r
-VOID\r
-SetQHVerticalQHorTDSelect (\r
-  IN QH_STRUCT     *ptrQH,\r
-  IN BOOLEAN       bQH\r
-  );\r
+  PciIo               - EFI_PCI_IO_PROTOCOL\r
+  FrameNumAddrOffset  - FrameNum register AddrOffset\r
 \r
-BOOLEAN\r
-IsQHHorizontalQHSelect (\r
-  IN QH_STRUCT     *ptrQH\r
-  );\r
+Returns:\r
 \r
-VOID\r
-SetQHVerticalValidorInvalid (\r
-  IN QH_STRUCT     *ptrQH,\r
-  IN BOOLEAN       bValid\r
-  );\r
+  Frame number \r
 \r
-BOOLEAN\r
-GetQHVerticalValidorInvalid (\r
-  IN QH_STRUCT     *ptrQH\r
-  );\r
+--*/\r
+;\r
 \r
 EFI_STATUS\r
-AllocateTDStruct (\r
-  IN  USB_HC_DEV     *HcDev,\r
-  OUT TD_STRUCT      **ppTDStruct\r
-  );\r
+CreateFrameList (\r
+  IN USB_HC_DEV     *HcDev,\r
+  IN UINT32         FLBASEADDRReg\r
+  )\r
 /*++\r
 \r
 Routine Description:\r
 \r
-  Allocate TD Struct\r
+  CreateFrameList\r
 \r
 Arguments:\r
 \r
-  HcDev       - USB_HC_DEV\r
-  ppTDStruct  - place to store TD_STRUCT pointer\r
+  HcDev         - USB_HC_DEV\r
+  FlBaseAddrReg - Frame List register\r
+\r
 Returns:\r
 \r
-  EFI_SUCCESS\r
+  EFI_OUT_OF_RESOURCES - Can't allocate memory resources\r
+  EFI_UNSUPPORTED      - Map memory fail\r
+  EFI_SUCCESS          - Success\r
 \r
 --*/\r
+;\r
 \r
 EFI_STATUS\r
-CreateTD (\r
-  IN  USB_HC_DEV     *HcDev,\r
-  OUT TD_STRUCT      **pptrTD\r
-  );\r
+FreeFrameListEntry (\r
+  IN USB_HC_DEV     *UhcDev\r
+  )\r
 /*++\r
 \r
 Routine Description:\r
 \r
-  Create TD\r
+  Free FrameList buffer\r
 \r
 Arguments:\r
 \r
-  HcDev   - USB_HC_DEV\r
-  pptrTD  - TD_STRUCT pointer to store\r
+  HcDev - USB_HC_DEV\r
 \r
 Returns:\r
 \r
-  EFI_OUT_OF_RESOURCES - Can't allocate resources\r
-  EFI_SUCCESS          - Success\r
+  EFI_SUCCESS - success\r
 \r
 --*/\r
+;\r
+\r
+VOID\r
+InitFrameList (\r
+  IN USB_HC_DEV     *HcDev\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Initialize FrameList\r
+\r
+Arguments:\r
+\r
+  HcDev - USB_HC_DEV\r
+\r
+Returns:\r
+   VOID\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+CreateQH (\r
+  IN  USB_HC_DEV     *HcDev,\r
+  OUT QH_STRUCT      **pptrQH\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  CreateQH\r
+\r
+Arguments:\r
+\r
+  HcDev       - USB_HC_DEV\r
+  pptrQH      - QH_STRUCT content to return\r
+Returns:\r
+\r
+  EFI_SUCCESS          - Success\r
+  EFI_OUT_OF_RESOURCES - Can't allocate memory\r
+  \r
+--*/\r
+;\r
+\r
+VOID\r
+SetQHHorizontalLinkPtr (\r
+  IN QH_STRUCT     *ptrQH,\r
+  IN VOID          *ptrNext\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Set QH Horizontal Link Pointer\r
+\r
+Arguments:\r
+\r
+  PtrQH   - QH_STRUCT\r
+  ptrNext - Data to write \r
+\r
+Returns:\r
+\r
+  VOID\r
+\r
+--*/\r
+;\r
+\r
+VOID                                *\r
+GetQHHorizontalLinkPtr (\r
+  IN QH_STRUCT     *ptrQH\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Get QH Horizontal Link Pointer\r
+\r
+Arguments:\r
+\r
+  PtrQH   - QH_STRUCT\r
+  \r
+\r
+Returns:\r
+\r
+  Data to return \r
+\r
+--*/\r
+;\r
+\r
+VOID\r
+SetQHHorizontalQHorTDSelect (\r
+  IN QH_STRUCT     *ptrQH,\r
+  IN BOOLEAN       bQH\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Set QH Horizontal QH or TD \r
+\r
+Arguments:\r
+\r
+  PtrQH - QH_STRUCT\r
+  bQH   - TRUE is QH FALSE is TD\r
+\r
+Returns:\r
+  VOID\r
+\r
+--*/\r
+;\r
+\r
+VOID\r
+SetQHHorizontalValidorInvalid (\r
+  IN QH_STRUCT     *ptrQH,\r
+  IN BOOLEAN       bValid\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Set QH Horizontal Valid or Invalid\r
+\r
+Arguments:\r
+\r
+  PtrQH  - QH_STRUCT\r
+  bValid - TRUE is Valid FALSE is Invalid\r
+\r
+Returns:\r
+  VOID\r
+\r
+--*/\r
+;\r
+\r
+VOID\r
+SetQHVerticalLinkPtr (\r
+  IN QH_STRUCT     *ptrQH,\r
+  IN VOID          *ptrNext\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Set QH Vertical Link Pointer\r
+  \r
+Arguments:\r
+\r
+  PtrQH   - QH_STRUCT\r
+  ptrNext - Data to write\r
+Returns:\r
+\r
+  VOID\r
+\r
+--*/\r
+;\r
+\r
+VOID                                *\r
+GetQHVerticalLinkPtr (\r
+  IN QH_STRUCT     *ptrQH\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Get QH Vertical Link Pointer\r
+  \r
+Arguments:\r
+\r
+  PtrQH   - QH_STRUCT\r
\r
+Returns:\r
+\r
+   Data to return\r
+\r
+--*/\r
+;\r
+\r
+VOID\r
+SetQHVerticalQHorTDSelect (\r
+  IN QH_STRUCT     *ptrQH,\r
+  IN BOOLEAN       bQH\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Set QH Vertical QH or TD\r
+\r
+Arguments:\r
+\r
+  PtrQH - QH_STRUCT\r
+  bQH   - TRUE is QH FALSE is TD\r
+\r
+Returns:\r
+\r
+  VOID\r
+\r
+--*/\r
+;\r
+\r
+BOOLEAN\r
+IsQHHorizontalQHSelect (\r
+  IN QH_STRUCT     *ptrQH\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Is QH Horizontal QH Select\r
+\r
+Arguments:\r
+\r
+  PtrQH - QH_STRUCT\r
\r
+Returns:\r
+\r
+  TRUE  - QH\r
+  FALSE - TD\r
+\r
+--*/\r
+;\r
+\r
+VOID\r
+SetQHVerticalValidorInvalid (\r
+  IN QH_STRUCT     *ptrQH,\r
+  IN BOOLEAN       bValid\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Set QH Vertical Valid or Invalid\r
+\r
+Arguments:\r
+\r
+  PtrQH   - QH_STRUCT\r
+  IsValid - TRUE is valid FALSE is invalid\r
+\r
+Returns:\r
+\r
+  VOID\r
+\r
+--*/\r
+;\r
+\r
+BOOLEAN\r
+GetQHVerticalValidorInvalid (\r
+  IN QH_STRUCT     *ptrQH\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Get QH Vertical Valid or Invalid\r
+\r
+Arguments:\r
+\r
+  PtrQH - QH_STRUCT\r
+\r
+Returns:\r
+\r
+  TRUE  - Valid\r
+  FALSE - Invalid\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+AllocateTDStruct (\r
+  IN  USB_HC_DEV     *HcDev,\r
+  OUT TD_STRUCT      **ppTDStruct\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Allocate TD Struct\r
+\r
+Arguments:\r
+\r
+  HcDev       - USB_HC_DEV\r
+  ppTDStruct  - place to store TD_STRUCT pointer\r
+Returns:\r
+\r
+  EFI_SUCCESS\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+CreateTD (\r
+  IN  USB_HC_DEV     *HcDev,\r
+  OUT TD_STRUCT      **pptrTD\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Create TD\r
+\r
+Arguments:\r
+\r
+  HcDev   - USB_HC_DEV\r
+  pptrTD  - TD_STRUCT pointer to store\r
+\r
+Returns:\r
+\r
+  EFI_OUT_OF_RESOURCES - Can't allocate resources\r
+  EFI_SUCCESS          - Success\r
+\r
+--*/\r
+;\r
 \r
 \r
 EFI_STATUS\r
@@ -528,7 +1018,7 @@ GenSetupStageTD (
   IN  UINT8          *pDevReq,\r
   IN  UINT8          RequestLen,\r
   OUT TD_STRUCT      **ppTD\r
-  );\r
+  )\r
 /*++\r
 \r
 Routine Description:\r
@@ -550,6 +1040,7 @@ Returns:
   EFI_SUCCESS          - Success\r
 \r
 --*/\r
+;\r
 \r
 EFI_STATUS\r
 GenDataTD (\r
@@ -562,7 +1053,7 @@ GenDataTD (
   IN  UINT8          Toggle,\r
   IN  BOOLEAN        bSlow,\r
   OUT TD_STRUCT      **ppTD\r
-  );\r
+  )\r
 /*++\r
 \r
 Routine Description:\r
@@ -586,6 +1077,7 @@ Returns:
   EFI_SUCCESS          - Success\r
 \r
 --*/\r
+;\r
 \r
 EFI_STATUS\r
 CreateStatusTD (\r
@@ -595,7 +1087,7 @@ CreateStatusTD (
   IN  UINT8          PktID,\r
   IN  BOOLEAN        bSlow,\r
   OUT TD_STRUCT      **ppTD\r
-  );\r
+  )\r
 /*++\r
 \r
 Routine Description:\r
@@ -617,237 +1109,918 @@ Returns:
   EFI_SUCCESS          - Success\r
 \r
 --*/\r
+;\r
 \r
 VOID\r
 SetTDLinkPtrValidorInvalid (\r
   IN TD_STRUCT     *ptrTDStruct,\r
   IN BOOLEAN       bValid\r
-  );\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Set TD Link Pointer Valid or Invalid\r
+\r
+Arguments:\r
+\r
+  ptrTDStruct - TD_STRUCT\r
+  bValid      - TRUE is valid FALSE is invalid\r
+\r
+Returns:\r
+\r
+  VOID\r
+\r
+--*/\r
+;\r
 \r
 VOID\r
 SetTDLinkPtrQHorTDSelect (\r
   IN TD_STRUCT     *ptrTDStruct,\r
   IN BOOLEAN       bQH\r
-  );\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Set TD Link Pointer QH or TD Select\r
+\r
+Arguments:\r
+\r
+  ptrTDStruct - TD_STRUCT\r
+  bQH         -  TRUE is QH FALSE is TD\r
+  \r
+Returns:\r
+\r
+  VOID\r
+\r
+--*/\r
+;\r
 \r
 VOID\r
 SetTDLinkPtrDepthorBreadth (\r
   IN TD_STRUCT     *ptrTDStruct,\r
   IN BOOLEAN       bDepth\r
-  );\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Set TD Link Pointer depth or bread priority\r
+\r
+Arguments:\r
+\r
+  ptrTDStruct - TD_STRUCT\r
+  bDepth      -  TRUE is Depth  FALSE is Breadth\r
+  \r
+Returns:\r
+\r
+  VOID\r
+\r
+--*/\r
+;\r
 \r
 VOID\r
 SetTDLinkPtr (\r
   IN TD_STRUCT     *ptrTDStruct,\r
   IN VOID          *ptrNext\r
-  );\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Set TD Link Pointer\r
 \r
-VOID *\r
+Arguments:\r
+\r
+  ptrTDStruct - TD_STRUCT\r
+  ptrNext     - Pointer to set\r
+  \r
+Returns:\r
+\r
+  VOID\r
+\r
+--*/\r
+;\r
+\r
+VOID                                *\r
 GetTDLinkPtr (\r
   IN TD_STRUCT   *ptrTDStruct\r
-  );\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Get TD Link Pointer\r
+\r
+Arguments:\r
+\r
+  ptrTDStruct - TD_STRUCT\r
+   \r
+Returns:\r
+\r
+  Pointer to get\r
+\r
+--*/\r
+;\r
 \r
 VOID\r
 EnableorDisableTDShortPacket (\r
   IN TD_STRUCT   *ptrTDStruct,\r
   IN BOOLEAN     bEnable\r
-  );\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Enable or Disable TD ShortPacket\r
+\r
+Arguments:\r
+\r
+  ptrTDStruct - TD_STRUCT\r
+  bEnable     - TRUE is Enanble FALSE is Disable\r
+\r
+Returns:\r
+\r
+  VOID\r
+\r
+--*/\r
+;\r
 \r
 VOID\r
 SetTDControlErrorCounter (\r
   IN TD_STRUCT     *ptrTDStruct,\r
   IN UINT8         nMaxErrors\r
-  );\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Set TD Control ErrorCounter\r
+\r
+Arguments:\r
+\r
+  ptrTDStruct - TD_STRUCT\r
+  nMaxErrors  - Error counter number\r
+  \r
+Returns:\r
+\r
+  VOID\r
+\r
+--*/\r
+;\r
 \r
 VOID\r
 SetTDLoworFullSpeedDevice (\r
   IN TD_STRUCT     *ptrTDStruct,\r
   IN BOOLEAN       bLowSpeedDevice\r
-  );\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Set TD status low speed or full speed\r
+\r
+Arguments:\r
+\r
+  ptrTDStruct     - A point to TD_STRUCT\r
+  bLowSpeedDevice - Show low speed or full speed\r
+\r
+Returns:\r
+\r
+  VOID\r
+\r
+--*/\r
+;\r
 \r
 VOID\r
 SetTDControlIsochronousorNot (\r
   IN TD_STRUCT     *ptrTDStruct,\r
   IN BOOLEAN       bIsochronous\r
-  );\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Set TD status Isochronous or not\r
+  \r
+Arguments:\r
+\r
+  ptrTDStruct   - A point to TD_STRUCT\r
+  IsIsochronous - Show Isochronous or not\r
+\r
+Returns:\r
+\r
+  VOID\r
+\r
+--*/\r
+;\r
 \r
 VOID\r
 SetorClearTDControlIOC (\r
   IN TD_STRUCT     *ptrTDStruct,\r
   IN BOOLEAN       bSet\r
-  );\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Set TD status IOC IsSet\r
+\r
+Arguments:\r
+\r
+  ptrTDStruct - A point to TD_STRUCT\r
+  IsSet       - Show IOC set or not\r
+\r
+Returns:\r
+\r
+  VOID\r
+\r
+--*/\r
+;\r
 \r
 VOID\r
 SetTDStatusActiveorInactive (\r
   IN TD_STRUCT     *ptrTDStruct,\r
   IN BOOLEAN       bActive\r
-  );\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Set TD status active or not\r
+Arguments:\r
+\r
+  ptrTDStruct - A point to TD_STRUCT\r
+  IsActive    - Active or not\r
+\r
+Returns:\r
+\r
+  VOID\r
+\r
+--*/\r
+;\r
 \r
 UINT16\r
 SetTDTokenMaxLength (\r
   IN TD_STRUCT     *ptrTDStruct,\r
   IN UINT16        nMaxLen\r
-  );\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Set TD Token maxlength\r
+\r
+Arguments:\r
+\r
+  ptrTDStruct   - A point to TD_STRUCT\r
+  MaximumLength - Maximum length of TD Token\r
+\r
+Returns:\r
+\r
+  Real maximum length set to TD Token\r
+\r
+--*/\r
+;\r
 \r
 VOID\r
 SetTDTokenDataToggle1 (\r
   IN TD_STRUCT    *ptrTDStruct\r
-  );\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Set TD Token data toggle1\r
+\r
+Arguments:\r
+\r
+  ptrTDStruct - A point to TD_STRUCT\r
+\r
+Returns:\r
+\r
+  VOID\r
+\r
+--*/\r
+;\r
 \r
 VOID\r
 SetTDTokenDataToggle0 (\r
   IN TD_STRUCT    *ptrTDStruct\r
-  );\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Set TD Token data toggle0\r
+\r
+Arguments:\r
+\r
+  ptrTDStruct - A point to TD_STRUCT\r
+\r
+Returns:\r
+\r
+  VOID\r
+\r
+--*/\r
+;\r
 \r
 UINT8\r
 GetTDTokenDataToggle (\r
   IN TD_STRUCT     *ptrTDStruct\r
-  );\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Get TD Token data toggle\r
+\r
+Arguments:\r
+\r
+  ptrTDStruct - A point to TD_STRUCT\r
+\r
+Returns:\r
+\r
+  data toggle value\r
+\r
+--*/\r
+;\r
 \r
 VOID\r
 SetTDTokenEndPoint (\r
   IN TD_STRUCT     *ptrTDStruct,\r
   IN UINTN         nEndPoint\r
-  );\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Set Data Token endpoint number\r
+\r
+Arguments:\r
+\r
+  ptrTDStruct - A point to TD_STRUCT\r
+  EndPoint    - End point number\r
+\r
+Returns:\r
+\r
+  VOID\r
+\r
+--*/\r
+;\r
 \r
 VOID\r
 SetTDTokenDeviceAddress (\r
   IN TD_STRUCT     *ptrTDStruct,\r
   IN UINTN         nDevAddr\r
-  );\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Set TD Token device address\r
+\r
+Arguments:\r
+\r
+  ptrTDStruct   - A point to TD_STRUCT\r
+  DeviceAddress - Device address\r
+\r
+Returns:\r
+\r
+  VOID\r
+  \r
+--*/\r
+;\r
 \r
 VOID\r
 SetTDTokenPacketID (\r
   IN TD_STRUCT     *ptrTDStruct,\r
   IN UINT8         nPID\r
-  );\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Set TD Token packet ID\r
+\r
+Arguments:\r
+\r
+  ptrTDStruct - A point to TD_STRUCT\r
+  PID         - Packet ID\r
+\r
+Returns:\r
+\r
+  VOID\r
+\r
+--*/\r
+;\r
 \r
 VOID\r
 SetTDDataBuffer (\r
   IN TD_STRUCT     *ptrTDStruct\r
-  );\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Set TD data buffer\r
+\r
+Arguments:\r
+\r
+  ptrTDStruct - A point to TD_STRUCT\r
+\r
+Returns:\r
+\r
+  VOID\r
+\r
+--*/\r
+;\r
 \r
 BOOLEAN\r
 IsTDStatusActive (\r
   IN TD_STRUCT     *ptrTDStruct\r
-  );\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Indicate whether TD status active or not\r
+\r
+Arguments:\r
+\r
+  ptrTDStruct - A point to TD_STRUCT\r
+\r
+Returns:\r
+\r
+  TRUE  - Active\r
+  FALSE - Inactive \r
+\r
+--*/\r
+;\r
 \r
 BOOLEAN\r
 IsTDStatusStalled (\r
   IN TD_STRUCT     *ptrTDStruct\r
-  );\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Indicate whether TD status stalled or not\r
+\r
+Arguments:\r
+\r
+  ptrTDStruct - A point to TD_STRUCT\r
+\r
+Returns:\r
+\r
+  TRUE  - Stalled\r
+  FALSE - not stalled\r
+\r
+--*/\r
+;\r
 \r
 BOOLEAN\r
 IsTDStatusBufferError (\r
   IN TD_STRUCT     *ptrTDStruct\r
-  );\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Indicate whether TD status buffer error or not\r
+\r
+Arguments:\r
+\r
+  ptrTDStruct - A point to TD_STRUCT\r
+\r
+Returns:\r
+\r
+  TRUE  - Buffer error\r
+  FALSE - No error\r
+\r
+--*/\r
+;\r
 \r
 BOOLEAN\r
 IsTDStatusBabbleError (\r
   IN TD_STRUCT     *ptrTDStruct\r
-  );\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Indicate whether TD status babble error or not\r
+\r
+Arguments:\r
+\r
+  ptrTDStruct - A point to TD_STRUCT\r
+\r
+Returns:\r
+\r
+  TRUE  - Babble error\r
+  FALSE - No error\r
+\r
+--*/\r
+;\r
 \r
 BOOLEAN\r
 IsTDStatusNAKReceived (\r
   IN TD_STRUCT     *ptrTDStruct\r
-  );\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Indicate whether TD status NAK received\r
+Arguments:\r
+\r
+  ptrTDStruct - A point to TD_STRUCT\r
+\r
+Returns:\r
+\r
+  TRUE  - NAK received\r
+  FALSE - NAK not received\r
+\r
+--*/\r
+;\r
 \r
 BOOLEAN\r
 IsTDStatusCRCTimeOutError (\r
   IN TD_STRUCT     *ptrTDStruct\r
-  );\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Indicate whether TD status CRC timeout error or not\r
+\r
+Arguments:\r
+\r
+  ptrTDStruct - A point to TD_STRUCT\r
+  \r
+Returns:\r
+\r
+  TRUE  - CRC timeout error\r
+  FALSE - CRC timeout no error\r
+\r
+--*/\r
+;\r
 \r
 BOOLEAN\r
 IsTDStatusBitStuffError (\r
   IN TD_STRUCT     *ptrTDStruct\r
-  );\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Indicate whether TD status bit stuff error or not\r
+\r
+Arguments:\r
+\r
+  ptrTDStruct - A point to TD_STRUCT\r
+\r
+Returns:\r
+\r
+  TRUE  - Bit stuff error\r
+  FALSE - Bit stuff no error\r
+\r
+--*/\r
+;\r
 \r
 UINT16\r
 GetTDStatusActualLength (\r
   IN TD_STRUCT     *ptrTDStruct\r
-  );\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Get TD status length\r
+\r
+Arguments:\r
+\r
+  ptrTDStruct - A point to TD_STRUCT\r
+\r
+Returns:\r
+\r
+  Return Td status length\r
+\r
+--*/\r
+;\r
 \r
 UINT16\r
 GetTDTokenMaxLength (\r
   IN TD_STRUCT     *ptrTDStruct\r
-  );\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Get TD Token maximum length\r
+\r
+Arguments:\r
+\r
+  ptrTDStruct - A point to TD_STRUCT\r
+\r
+Returns:\r
+\r
+  Return TD token maximum length\r
+\r
+--*/\r
+;\r
 \r
 UINT8\r
 GetTDTokenEndPoint (\r
   IN TD_STRUCT     *ptrTDStruct\r
-  );\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Get TD Token endpoint number\r
+\r
+Arguments:\r
+\r
+  ptrTDStruct - A point to TD_STRUCT\r
+\r
+Returns:\r
+\r
+  Return TD Token endpoint number\r
+\r
+--*/\r
+;\r
 \r
 UINT8\r
 GetTDTokenDeviceAddress (\r
   IN TD_STRUCT     *ptrTDStruct\r
-  );\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Get TD Token device address\r
+\r
+Arguments:\r
+\r
+  ptrTDStruct - A point to TD_STRUCT\r
+\r
+Returns:\r
+\r
+  Return TD Token device address\r
+\r
+--*/\r
+;\r
 \r
 UINT8\r
 GetTDTokenPacketID (\r
   IN TD_STRUCT     *ptrTDStruct\r
-  );\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Get TD Token packet ID\r
+\r
+Arguments:\r
+\r
+  ptrTDStruct - A point to TD_STRUCT\r
 \r
-UINT8 *\r
+Returns:\r
+\r
+  Return TD Token packet ID\r
+\r
+--*/\r
+;\r
+\r
+UINT8                               *\r
 GetTDDataBuffer (\r
   IN TD_STRUCT     *ptrTDStruct\r
-  );\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Get the point to TD data buffer\r
+\r
+Arguments:\r
+\r
+  ptrTDStruct - A point to TD_STRUCT\r
+\r
+Returns:\r
+\r
+  Return a point to TD data buffer\r
+\r
+--*/\r
+;\r
 \r
 BOOLEAN\r
 GetTDLinkPtrValidorInvalid (\r
   IN TD_STRUCT     *ptrTDStruct\r
-  );\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Get TD LinkPtr valid or not\r
+\r
+Arguments:\r
+\r
+  ptrTDStruct - A point to TD_STRUCT\r
+\r
+Returns:\r
+\r
+  TRUE  - Invalid\r
+  FALSE - Valid\r
+\r
+--*/\r
+;\r
 \r
 UINTN\r
 CountTDsNumber (\r
   IN TD_STRUCT     *ptrFirstTD\r
-  );\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Get the number of TDs\r
+\r
+Arguments:\r
+\r
+  PtrFirstTD  - A point to the first TD_STRUCT\r
+\r
+Returns:\r
+\r
+  Return the number of TDs\r
+\r
+--*/\r
+;\r
 \r
 VOID\r
 LinkTDToQH (\r
   IN QH_STRUCT     *ptrQH,\r
   IN TD_STRUCT     *ptrTD\r
-  );\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Link TD To QH\r
+\r
+Arguments:\r
+\r
+  PtrQH - QH_STRUCT\r
+  PtrTD - TD_STRUCT\r
+Returns:\r
+\r
+  VOID\r
+\r
+--*/\r
+;\r
 \r
 VOID\r
 LinkTDToTD (\r
   IN TD_STRUCT     *ptrPreTD,\r
   IN TD_STRUCT     *ptrTD\r
-  );\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Link TD To TD\r
+\r
+Arguments:\r
+\r
+  ptrPreTD - Previous TD_STRUCT to be linked\r
+  PtrTD    - TD_STRUCT to link\r
+Returns:\r
+\r
+  VOID\r
+\r
+--*/\r
+;\r
 \r
 VOID\r
 SetorClearCurFrameListTerminate (\r
   IN FRAMELIST_ENTRY     *pCurEntry,\r
   IN BOOLEAN             bSet\r
-  );\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Set or clear current framelist terminate\r
+\r
+Arguments:\r
+\r
+  pCurEntry - A point to FRAMELIST_ENTITY\r
+  IsSet     - TRUE to empty the frame and indicate the Pointer field is valid\r
+\r
+Returns:\r
+\r
+  VOID\r
+\r
+--*/\r
+;\r
+\r
+VOID\r
+SetCurFrameListQHorTD (\r
+  IN FRAMELIST_ENTRY        *pCurEntry,\r
+  IN BOOLEAN                bQH\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Set current framelist QH or TD\r
+\r
+Arguments:\r
+\r
+  pCurEntry - A point to FRAMELIST_ENTITY\r
+  IsQH      - TRUE to set QH and FALSE to set TD\r
+\r
+Returns:\r
 \r
-VOID\r
-SetCurFrameListQHorTD (\r
-  IN FRAMELIST_ENTRY        *pCurEntry,\r
-  IN BOOLEAN                bQH\r
-  );\r
+  VOID\r
+\r
+--*/\r
+;\r
 \r
 BOOLEAN\r
 GetCurFrameListTerminate (\r
   IN FRAMELIST_ENTRY     *pCurEntry\r
-  );\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Get current framelist terminate\r
+\r
+Arguments:\r
+\r
+  pCurEntry - A point to FRAMELIST_ENTITY\r
+\r
+Returns:\r
+\r
+  TRUE  - Terminate\r
+  FALSE - Not terminate\r
+\r
+--*/\r
+;\r
 \r
 VOID\r
 SetCurFrameListPointer (\r
   IN FRAMELIST_ENTRY     *pCurEntry,\r
   IN UINT8               *ptr\r
-  );\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Set current framelist pointer\r
+\r
+Arguments:\r
+\r
+  pCurEntry - A point to FRAMELIST_ENTITY\r
+  ptr       - A point to FrameListPtr point to\r
+\r
+Returns:\r
+\r
+  VOID\r
+  \r
+--*/\r
+;\r
 \r
-VOID *\r
+VOID                                *\r
 GetCurFrameListPointer (\r
   IN FRAMELIST_ENTRY     *pCurEntry\r
-  );\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Get current framelist pointer\r
+\r
+Arguments:\r
+\r
+  pCurEntry - A point to FRAMELIST_ENTITY\r
+\r
+Returns:\r
+\r
+  A point FrameListPtr point to\r
+\r
+--*/\r
+;\r
 \r
 VOID\r
 LinkQHToFrameList (\r
   IN FRAMELIST_ENTRY   *pEntry,\r
   IN UINT16            FrameListIndex,\r
   IN QH_STRUCT         *ptrQH\r
-  );\r
+  )\r
 /*++\r
 \r
 Routine Description:\r
@@ -864,14 +2037,7 @@ Returns:
   VOID\r
 \r
 --*/\r
-VOID\r
-DeleteQHTDs (\r
-  IN FRAMELIST_ENTRY *pEntry,\r
-  IN QH_STRUCT       *ptrQH,\r
-  IN TD_STRUCT       *ptrFirstTD,\r
-  IN UINT16          FrameListIndex,\r
-  IN BOOLEAN         SearchOther\r
-  );\r
+;\r
 \r
 VOID\r
 DelLinkSingleQH (\r
@@ -880,13 +2046,50 @@ DelLinkSingleQH (
   IN UINT16          FrameListIndex,\r
   IN BOOLEAN         SearchOther,\r
   IN BOOLEAN         Delete\r
-  );\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Unlink from frame list and delete single QH\r
+  \r
+Arguments:\r
+\r
+  HcDev            - USB_HC_DEV\r
+  PtrQH            - QH_STRUCT\r
+  FrameListIndex   - Frame List Index\r
+  SearchOther      - Search Other QH\r
+  Delete           - TRUE is to delete the QH\r
+  \r
+Returns:\r
+\r
+  VOID\r
+  \r
+--*/\r
+;\r
 \r
 VOID\r
 DeleteQueuedTDs (\r
   IN USB_HC_DEV      *HcDev,\r
   IN TD_STRUCT       *ptrFirstTD\r
-  );\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Delete Queued TDs\r
+  \r
+Arguments:\r
+\r
+  HcDev       - USB_HC_DEV\r
+  PtrFirstTD  - TD link list head\r
+\r
+Returns:\r
+\r
+  VOID\r
+\r
+--*/\r
+;\r
 \r
 VOID\r
 InsertQHTDToINTList (\r
@@ -902,10 +2105,12 @@ InsertQHTDToINTList (
   IN UINT8                             *DataBuffer,\r
   IN EFI_ASYNC_USB_TRANSFER_CALLBACK   CallBackFunction,\r
   IN VOID                              *Context\r
-  );\r
+  )\r
 /*++\r
 Routine Description:\r
+\r
   Insert QH and TD To Interrupt List\r
+\r
 Arguments:\r
 \r
   HcDev           - USB_HC_DEV\r
@@ -920,11 +2125,14 @@ Arguments:
   DataBuffer      - Data buffer\r
   CallBackFunction- CallBackFunction after interrupt transfeer\r
   Context         - CallBackFunction Context passed as function parameter\r
+\r
 Returns:\r
+\r
   EFI_SUCCESS            - Sucess\r
   EFI_INVALID_PARAMETER  - Paremeter is error \r
 \r
 --*/\r
+;\r
 \r
 EFI_STATUS\r
 DeleteAsyncINTQHTDs (\r
@@ -932,11 +2140,12 @@ DeleteAsyncINTQHTDs (
   IN  UINT8       DeviceAddress,\r
   IN  UINT8       EndPointAddress,\r
   OUT UINT8       *DataToggle\r
-  );\r
+  )\r
 /*++\r
 Routine Description:\r
 \r
   Delete Async INT QH and TDs\r
+  \r
 Arguments:\r
 \r
   HcDev           - USB_HC_DEV\r
@@ -945,10 +2154,13 @@ Arguments:
   DataToggle      - Data Toggle\r
 \r
 Returns:\r
+\r
   EFI_SUCCESS            - Sucess\r
   EFI_INVALID_PARAMETER  - Paremeter is error \r
 \r
 --*/\r
+;\r
+\r
 BOOLEAN\r
 CheckTDsResults (\r
   IN  TD_STRUCT               *ptrTD,\r
@@ -956,7 +2168,7 @@ CheckTDsResults (
   OUT UINT32                  *Result,\r
   OUT UINTN                   *ErrTDPos,\r
   OUT UINTN                   *ActualTransferSize\r
-  );\r
+  )\r
 /*++\r
 \r
 Routine Description:\r
@@ -977,6 +2189,8 @@ Returns:
   FALSE - Fail\r
 \r
 --*/\r
+;\r
+\r
 VOID\r
 ExecuteAsyncINTTDs (\r
   IN  USB_HC_DEV      *HcDev,\r
@@ -984,7 +2198,7 @@ ExecuteAsyncINTTDs (
   OUT UINT32          *Result,\r
   OUT UINTN           *ErrTDPos,\r
   OUT UINTN           *ActualLen\r
-  ) ;\r
+  )\r
 /*++\r
 \r
 Routine Description:\r
@@ -1004,12 +2218,14 @@ Returns:
   VOID\r
 \r
 --*/\r
+;\r
+\r
 VOID\r
 UpdateAsyncINTQHTDs (\r
   IN INTERRUPT_LIST  *ptrList,\r
   IN UINT32          Result,\r
   IN UINT32          ErrTDPos\r
-  );\r
+  )\r
 /*++\r
 \r
 Routine Description:\r
@@ -1027,16 +2243,19 @@ Returns:
   VOID\r
 \r
 --*/\r
+;\r
+\r
 VOID\r
 ReleaseInterruptList (\r
   IN USB_HC_DEV      *HcDev,\r
   IN LIST_ENTRY      *ListHead\r
-  );\r
+  )\r
 /*++\r
 \r
 Routine Description:\r
 \r
   Release Interrupt List\r
+  \r
 Arguments:\r
 \r
   HcDev     - USB_HC_DEV\r
@@ -1047,6 +2266,8 @@ Returns:
   VOID\r
 \r
 --*/\r
+;\r
+\r
 EFI_STATUS\r
 ExecuteControlTransfer (\r
   IN  USB_HC_DEV  *HcDev,\r
@@ -1055,7 +2276,7 @@ ExecuteControlTransfer (
   OUT UINTN       *ActualLen,\r
   IN  UINTN       TimeOut,\r
   OUT UINT32      *TransferResult\r
-  );\r
+  )\r
 /*++\r
 \r
 Routine Description:\r
@@ -1077,6 +2298,8 @@ Returns:
   \r
 \r
 --*/\r
+;\r
+\r
 EFI_STATUS\r
 ExecBulkorSyncInterruptTransfer (\r
   IN  USB_HC_DEV  *HcDev,\r
@@ -1086,7 +2309,7 @@ ExecBulkorSyncInterruptTransfer (
   OUT UINT8       *DataToggle,\r
   IN  UINTN       TimeOut,\r
   OUT UINT32      *TransferResult\r
-  );\r
+  )\r
 /*++\r
 \r
 Routine Description:\r
@@ -1107,81 +2330,311 @@ Returns:
   EFI_SUCCESS      - Sucess\r
   EFI_DEVICE_ERROR - Error\r
 --*/\r
+;\r
 \r
 EFI_STATUS\r
 InitializeMemoryManagement (\r
   IN USB_HC_DEV           *HcDev\r
-  );\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Initialize Memory Management\r
+\r
+Arguments:\r
+\r
+  HcDev - USB_HC_DEV\r
+\r
+Returns:\r
+\r
+  EFI_SUCCESS -  Success\r
+  \r
+--*/\r
+;\r
 \r
 EFI_STATUS\r
 CreateMemoryBlock (\r
   IN USB_HC_DEV            *HcDev,\r
   IN MEMORY_MANAGE_HEADER  **MemoryHeader,\r
   IN UINTN                 MemoryBlockSizeInPages\r
-  );\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Use PciIo->AllocateBuffer to allocate common buffer for the memory block,\r
+  and use PciIo->Map to map the common buffer for Bus Master Read/Write.\r
+\r
+\r
+Arguments:\r
+\r
+  HcDev        - USB_HC_DEV\r
+  MemoryHeader - MEMORY_MANAGE_HEADER to output\r
+  MemoryBlockSizeInPages - MemoryBlockSizeInPages\r
+  \r
+Returns:\r
+\r
+  EFI_SUCCESS            - Success\r
+  EFI_OUT_OF_RESOURCES   - Out of resources\r
+  EFI_UNSUPPORTED        - Unsupported\r
+\r
+--*/\r
+;\r
 \r
 EFI_STATUS\r
 FreeMemoryHeader (\r
   IN USB_HC_DEV            *HcDev,\r
   IN MEMORY_MANAGE_HEADER  *MemoryHeader\r
-  );\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Free Memory Header\r
+\r
+Arguments:\r
+\r
+  HcDev         - USB_HC_DEV\r
+  MemoryHeader  - MemoryHeader to be freed\r
+\r
+Returns:\r
+\r
+  EFI_INVALID_PARAMETER - Parameter is error\r
+  EFI_SUCCESS           - Success\r
+\r
+--*/\r
+;\r
 \r
 EFI_STATUS\r
 UhciAllocatePool (\r
   IN USB_HC_DEV      *UhcDev,\r
   IN UINT8           **Pool,\r
   IN UINTN           AllocSize\r
-  );\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Uhci Allocate Pool\r
+\r
+Arguments:\r
+\r
+  HcDev     - USB_HC_DEV\r
+  Pool      - Place to store pointer to the memory buffer\r
+  AllocSize - Alloc Size\r
+\r
+Returns:\r
+\r
+  EFI_SUCCESS - Success\r
+\r
+--*/\r
+;\r
 \r
 VOID\r
 UhciFreePool (\r
   IN USB_HC_DEV      *HcDev,\r
   IN UINT8           *Pool,\r
   IN UINTN           AllocSize\r
-  );\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Uhci Free Pool\r
+\r
+Arguments:\r
+\r
+  HcDev     - USB_HC_DEV\r
+  Pool      - Pool to free\r
+  AllocSize - Pool size\r
+\r
+Returns:\r
+\r
+  VOID\r
+\r
+--*/\r
+;\r
 \r
 VOID\r
 InsertMemoryHeaderToList (\r
   IN MEMORY_MANAGE_HEADER  *MemoryHeader,\r
   IN MEMORY_MANAGE_HEADER  *NewMemoryHeader\r
-  );\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Insert Memory Header To List\r
+\r
+Arguments:\r
+\r
+  MemoryHeader    - MEMORY_MANAGE_HEADER\r
+  NewMemoryHeader - MEMORY_MANAGE_HEADER\r
+\r
+Returns:\r
+\r
+  VOID\r
+\r
+--*/\r
+;\r
 \r
 EFI_STATUS\r
 AllocMemInMemoryBlock (\r
   IN MEMORY_MANAGE_HEADER  *MemoryHeader,\r
   IN VOID                  **Pool,\r
   IN UINTN                 NumberOfMemoryUnit\r
-  );\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Alloc Memory In MemoryBlock\r
+\r
+Arguments:\r
+\r
+  MemoryHeader        - MEMORY_MANAGE_HEADER\r
+  Pool                - Place to store pointer to memory\r
+  NumberOfMemoryUnit  - Number Of Memory Unit\r
+\r
+Returns:\r
+\r
+  EFI_NOT_FOUND  - Can't find the free memory \r
+  EFI_SUCCESS    - Success\r
+\r
+--*/\r
+;\r
 \r
 BOOLEAN\r
 IsMemoryBlockEmptied (\r
   IN MEMORY_MANAGE_HEADER  *MemoryHeaderPtr\r
-  );\r
+  )\r
+/*++\r
+\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Is Memory Block Emptied\r
+\r
+Arguments:\r
+\r
+  MemoryHeaderPtr - MEMORY_MANAGE_HEADER\r
+\r
+Returns:\r
+\r
+  TRUE  - Empty\r
+  FALSE - Not Empty \r
+\r
+--*/\r
+;\r
 \r
 VOID\r
 DelinkMemoryBlock (\r
   IN MEMORY_MANAGE_HEADER    *FirstMemoryHeader,\r
   IN MEMORY_MANAGE_HEADER    *FreeMemoryHeader\r
-  );\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Delink Memory Block\r
+\r
+Arguments:\r
+\r
+  FirstMemoryHeader     - MEMORY_MANAGE_HEADER\r
+  NeedFreeMemoryHeader  - MEMORY_MANAGE_HEADER\r
+\r
+Returns:\r
+\r
+  VOID\r
+\r
+--*/\r
+;\r
 \r
 EFI_STATUS\r
 DelMemoryManagement (\r
   IN USB_HC_DEV      *HcDev\r
-  );\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Delete Memory Management\r
+\r
+Arguments:\r
+\r
+  HcDev - USB_HC_DEV\r
+\r
+Returns:\r
+\r
+  EFI_SUCCESS - Success\r
+\r
+--*/\r
+;\r
 \r
 VOID\r
 EnableMaxPacketSize (\r
   IN USB_HC_DEV          *HcDev\r
-  );\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Enable Max Packet Size\r
+\r
+Arguments:\r
+\r
+  HcDev - USB_HC_DEV\r
+\r
+Returns:\r
+\r
+  VOID\r
+\r
+--*/\r
+;\r
 \r
 VOID\r
 CleanUsbTransactions (\r
   IN USB_HC_DEV    *HcDev\r
-  );\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Clean USB Transactions\r
+\r
+Arguments:\r
+\r
+  HcDev - A point to USB_HC_DEV\r
+\r
+Returns:\r
+\r
+  VOID\r
+\r
+--*/\r
+;\r
 \r
 VOID\r
 TurnOffUSBEmulation (\r
   IN EFI_PCI_IO_PROTOCOL  *PciIo\r
-  );\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Set current framelist QH or TD\r
+\r
+Arguments:\r
+\r
+  pCurEntry - A point to FRAMELIST_ENTITY\r
+  IsQH      - TRUE to set QH and FALSE to set TD\r
+\r
+Returns:\r
+\r
+  VOID\r
+\r
+--*/\r
+;\r
 \r
 #endif\r
index 0aa0507c2ad8813f173f468bc5921f93d35a687e..8cd6b8e6f6bf2651e32f0961cfb749a2726a3454 100644 (file)
@@ -710,7 +710,7 @@ BotDataPhase (
   BufferPtr       = (UINT8 *) DataBuffer;\r
   TransferredSize = 0;\r
   MaxRetry        = 10;\r
-  PackageNum      = 15;\r
+  PackageNum      = 128;\r
 \r
   //\r
   // retrieve the the max packet length of the given endpoint\r
index 54a79ecd9a5bcbe6867741c3f38bd9ada0fda841..d7101dce0e8f609b7337cea6a9fdbf9c2d92a94d 100644 (file)
@@ -83,7 +83,10 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.-->
     <Protocol Usage="BY_START">\r
       <ProtocolCName>gEfiUsbIoProtocolGuid</ProtocolCName>\r
     </Protocol>\r
-    <Protocol Usage="TO_START">\r
+    <Protocol Usage="SOMETIMES_CONSUMED">\r
+      <ProtocolCName>gEfiUsb2HcProtocolGuid</ProtocolCName>\r
+    </Protocol>\r
+    <Protocol Usage="SOMETIMES_CONSUMED">\r
       <ProtocolCName>gEfiUsbHcProtocolGuid</ProtocolCName>\r
     </Protocol>\r
     <Protocol Usage="TO_START">\r
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
index 036f4dfe5099321df5a24690628f16e2f36ccae2..47f0fd804fb8c5ede0a9dc16f86ecd46f2b98bc9 100644 (file)
@@ -30,13 +30,11 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 #include "hub.h"\r
 #include "usbutil.h"\r
 \r
-//#ifdef EFI_DEBUG\r
 extern UINTN  gUSBDebugLevel;\r
 extern UINTN  gUSBErrorLevel;\r
-//#endif\r
 \r
-#define MICROSECOND 10000\r
-#define ONESECOND   (1000 * MICROSECOND)\r
+#define MICROSECOND       10000\r
+#define ONESECOND         (1000 * MICROSECOND)\r
 #define BUSPOLLING_PERIOD ONESECOND\r
 //\r
 // We define some maximun value here\r
@@ -120,21 +118,23 @@ typedef struct usb_io_controller_device {
 struct _usb_bus_controller_device;\r
 \r
 typedef struct usb_io_device {\r
-  UINT8                             DeviceAddress;\r
-  BOOLEAN                           IsConfigured;\r
-  BOOLEAN                           IsSlowDevice;\r
-  EFI_USB_DEVICE_DESCRIPTOR         DeviceDescriptor;\r
-  LIST_ENTRY                        ConfigDescListHead;\r
-  CONFIG_DESC_LIST_ENTRY            *ActiveConfig;\r
-  UINT16                            LangID[USB_MAXLANID];\r
+  UINT8                               DeviceAddress;\r
+  BOOLEAN                             IsConfigured;\r
+  BOOLEAN                             IsSlowDevice;\r
+  UINT8                               DeviceSpeed;\r
+  EFI_USB2_HC_TRANSACTION_TRANSLATOR  *Translator;\r
+  EFI_USB_DEVICE_DESCRIPTOR           DeviceDescriptor;\r
+  LIST_ENTRY                          ConfigDescListHead;\r
+  CONFIG_DESC_LIST_ENTRY              *ActiveConfig;\r
+  UINT16                              LangID[USB_MAXLANID];\r
 \r
-  struct _usb_bus_controller_device *BusController;\r
+  struct _usb_bus_controller_device   *BusController;\r
 \r
   //\r
   // Track the controller handle\r
   //\r
-  UINT8                             NumOfControllers;\r
-  USB_IO_CONTROLLER_DEVICE          *UsbController[USB_MAXCONTROLLERS];\r
+  UINT8                               NumOfControllers;\r
+  USB_IO_CONTROLLER_DEVICE            *UsbController[USB_MAXCONTROLLERS];\r
 \r
 } USB_IO_DEVICE;\r
 \r
@@ -154,10 +154,12 @@ typedef struct _usb_bus_controller_device {
   UINTN                     Signature;\r
 \r
   EFI_USB_BUS_PROTOCOL      BusIdentify;\r
+  EFI_USB2_HC_PROTOCOL      *Usb2HCInterface;\r
   EFI_USB_HC_PROTOCOL       *UsbHCInterface;\r
   EFI_DEVICE_PATH_PROTOCOL  *DevicePath;\r
   UINT8                     AddressPool[16];\r
   USB_IO_DEVICE             *Root;\r
+  BOOLEAN                   Hc2ProtocolSupported;\r
 } USB_BUS_CONTROLLER_DEVICE;\r
 \r
 #define USB_BUS_CONTROLLER_DEVICE_FROM_THIS(a) \\r
@@ -177,28 +179,99 @@ extern EFI_GUID                     gUSBBusDriverGuid;
 BOOLEAN\r
 IsHub (\r
   IN USB_IO_CONTROLLER_DEVICE     *Dev\r
-  );\r
+  )\r
+/*++\r
+  \r
+  Routine Description:\r
+    Tell if a usb controller is a hub controller.\r
+    \r
+  Arguments:\r
+    Dev - UsbIoController device structure.\r
+    \r
+  Returns:\r
+    TRUE/FALSE\r
+--*/\r
+;\r
 \r
 EFI_STATUS\r
 UsbGetStringtable (\r
   IN  USB_IO_DEVICE     *UsbIoDevice\r
-  );\r
+  )\r
+/*++\r
+  \r
+  Routine Description:\r
+    Get the string table stored in a usb device.\r
+    \r
+  Arguments:\r
+    Dev     -     UsbIoController device structure.\r
+    \r
+  Returns:\r
+    EFI_SUCCESS\r
+    EFI_UNSUPPORTED\r
+    EFI_OUT_OF_RESOURCES\r
+    \r
+--*/\r
+;\r
 \r
 EFI_STATUS\r
 UsbGetAllConfigurations (\r
   IN  USB_IO_DEVICE     *UsbIoDevice\r
-  );\r
+  )\r
+/*++\r
+\r
+  Routine Description:\r
+    This function is to parse all the configuration descriptor.\r
+    \r
+  Arguments:\r
+    UsbIoDevice  -  USB_IO_DEVICE device structure.\r
+    \r
+  Returns:\r
+    EFI_SUCCESS\r
+    EFI_DEVICE_ERROR\r
+    EFI_OUT_OF_RESOURCES  \r
+\r
+--*/\r
+;\r
 \r
 EFI_STATUS\r
 UsbSetConfiguration (\r
   IN  USB_IO_DEVICE     *Dev,\r
   IN  UINTN             ConfigurationValue\r
-  );\r
+  )\r
+/*++\r
+\r
+  Routine Description:\r
+    Set the device to a configuration value.\r
+    \r
+  Arguments:\r
+    UsbIoDev            -   USB_IO_DEVICE to be set configuration\r
+    ConfigrationValue   -   The configuration value to be set to that device\r
+    \r
+  Returns:\r
+    EFI_SUCCESS\r
+    EFI_DEVICE_ERROR\r
+    \r
+--*/\r
+;\r
 \r
 EFI_STATUS\r
 UsbSetDefaultConfiguration (\r
   IN  USB_IO_DEVICE     *Dev\r
-  );\r
+  )\r
+/*++\r
+\r
+  Routine Description:\r
+    Set the device to a default configuration value.\r
+    \r
+  Arguments:\r
+    UsbIoDev       -    USB_IO_DEVICE to be set configuration\r
+    \r
+  Returns\r
+    EFI_SUCCESS\r
+    EFI_DEVICE_ERROR\r
+    \r
+--*/\r
+;\r
 \r
 //\r
 // Device Deconfiguration functions\r
@@ -206,56 +279,834 @@ UsbSetDefaultConfiguration (
 VOID\r
 UsbDestroyAllConfiguration (\r
   IN USB_IO_DEVICE     *UsbIoDevice\r
-  );\r
+  )\r
+/*++\r
+\r
+  Routine Description:\r
+    Delete all configuration data when device is not used.\r
+    \r
+  Arguments:\r
+    UsbIoDevice  - USB_IO_DEVICE to be set configuration\r
+  \r
+  Returns:\r
+    VOID\r
+    \r
+--*/\r
+;\r
 \r
 EFI_STATUS\r
 DoHubConfig (\r
   IN USB_IO_CONTROLLER_DEVICE     *HubIoDevice\r
-  );\r
+  )\r
+/*++\r
+  \r
+  Routine Description:\r
+    Configure the hub\r
+  \r
+  Arguments:\r
+    HubController         -   Indicating the hub controller device that\r
+                              will be configured\r
+                                \r
+  Returns:\r
+    EFI_SUCCESS\r
+    EFI_DEVICE_ERROR\r
+    \r
+--*/\r
+\r
+;\r
 \r
 VOID\r
 GetDeviceEndPointMaxPacketLength (\r
   IN EFI_USB_IO_PROTOCOL    *UsbIo,\r
   IN  UINT8                 EndpointAddr,\r
-  OUT UINT8                 *MaxPacketLength\r
-  );\r
+  OUT UINTN                 *MaxPacketLength\r
+  )\r
+/*++\r
+\r
+  Routine Description:\r
+    Get the Max Packet Length of the speified Endpoint.\r
+\r
+  Arguments:\r
+    UsbIo           -     Given Usb Controller device.\r
+    EndpointAddr    -     Given Endpoint address.\r
+    MaxPacketLength -     The max packet length of that endpoint\r
+\r
+  Returns:\r
+    N/A\r
+\r
+--*/\r
+;\r
 \r
 VOID\r
 GetDataToggleBit (\r
   IN EFI_USB_IO_PROTOCOL    *UsbIo,\r
   IN  UINT8                 EndpointAddr,\r
   OUT UINT8                 *DataToggle\r
-  );\r
+  )\r
+/*++\r
+\r
+  Routine Description:\r
+    Get the datatoggle of a specified endpoint.\r
+\r
+  Arguments:\r
+    UsbIo         -     Given Usb Controller device.\r
+    EndpointAddr  -     Given Endpoint address.\r
+    DataToggle    -     The current data toggle of that endpoint\r
+\r
+  Returns:\r
+    VOID\r
+    \r
+--*/\r
+;\r
 \r
 VOID\r
 SetDataToggleBit (\r
   IN EFI_USB_IO_PROTOCOL    *UsbIo,\r
   IN UINT8                  EndpointAddr,\r
   IN UINT8                  DataToggle\r
-  );\r
+  )\r
+/*++\r
+\r
+  Routine Description:\r
+    Set the datatoggle of a specified endpoint\r
+\r
+  Arguments:\r
+    UsbIo         -     Given Usb Controller device.\r
+    EndpointAddr  -     Given Endpoint address.\r
+    DataToggle    -     The current data toggle of that endpoint to be set\r
+\r
+  Returns:\r
+    VOID\r
+\r
+--*/\r
+;\r
 \r
-INTERFACE_DESC_LIST_ENTRY *\r
+INTERFACE_DESC_LIST_ENTRY           *\r
 FindInterfaceListEntry (\r
   IN EFI_USB_IO_PROTOCOL    *This\r
-  );\r
+  )\r
+/*++\r
+\r
+  Routine Description:\r
+    Find Interface ListEntry.\r
 \r
-ENDPOINT_DESC_LIST_ENTRY *\r
+  Arguments:\r
+    This         -  EFI_USB_IO_PROTOCOL   \r
+  \r
+  Returns:\r
+    INTERFACE_DESC_LIST_ENTRY pointer\r
+\r
+--*/\r
+;\r
+\r
+ENDPOINT_DESC_LIST_ENTRY            *\r
 FindEndPointListEntry (\r
   IN EFI_USB_IO_PROTOCOL    *This,\r
   IN UINT8                  EndPointAddress\r
-  );\r
+  )\r
+/*++\r
+\r
+  Routine Description:\r
+    Find EndPoint ListEntry.\r
 \r
+  Arguments:\r
+    This         -  EFI_USB_IO_PROTOCOL   \r
+    EndpointAddr -  Endpoint address.\r
\r
+  Returns:\r
+    ENDPOINT_DESC_LIST_ENTRY pointer\r
+\r
+--*/\r
+;\r
 \r
 EFI_STATUS\r
 IsDeviceDisconnected (\r
   IN USB_IO_CONTROLLER_DEVICE    *UsbIoController,\r
   IN OUT BOOLEAN                 *Disconnected\r
-  );\r
+  )\r
+/*++\r
+\r
+  Routine Description:\r
+    Reset if the device is disconencted or not\r
+\r
+  Arguments:\r
+    UsbIoController   -   Indicating the Usb Controller Device.\r
+    Disconnected      -   Indicate whether the device is disconencted or not\r
+\r
+  Returns:\r
+    EFI_SUCCESS\r
+    EFI_DEVICE_ERROR\r
+\r
+--*/\r
+;\r
 \r
 EFI_STATUS\r
 UsbDeviceDeConfiguration (\r
   IN USB_IO_DEVICE     *UsbIoDevice\r
-  );\r
+  )\r
+/*++\r
+\r
+  Routine Description:\r
+    Remove Device, Device Handles, Uninstall Protocols.\r
+\r
+  Arguments:\r
+    UsbIoDevice     -   The device to be deconfigured.\r
+\r
+  Returns: \r
+    EFI_SUCCESS\r
+    EFI_DEVICE_ERROR\r
+\r
+--*/\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
+\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
+\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
+\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
+\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
+\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
+\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
+\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
+\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
+\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
+\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
+\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
+\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
 \r
 #endif\r
index bd87c5ca2e6c45a04e313e2a46f81a6011cf1049..eb563b8e8b175471f1127b5df6655870b8d3d1b5 100644 (file)
@@ -233,9 +233,9 @@ UsbControlTransfer (
 --*/\r
 {\r
   USB_IO_CONTROLLER_DEVICE  *UsbIoController;\r
-  EFI_USB_HC_PROTOCOL       *UsbHCInterface;\r
+\r
   EFI_STATUS                RetStatus;\r
-  USB_IO_DEVICE             *UsbIoDevice;\r
+  USB_IO_DEVICE             *UsbIoDev;\r
   UINT8                     MaxPacketLength;\r
   UINT32                    TransferResult;\r
   BOOLEAN                   Disconnected;\r
@@ -251,9 +251,9 @@ UsbControlTransfer (
   // to perform other parameters checking\r
   //\r
   UsbIoController = USB_IO_CONTROLLER_DEVICE_FROM_USB_IO_THIS (This);\r
-  UsbIoDevice     = UsbIoController->UsbDevice;\r
-  UsbHCInterface  = UsbIoDevice->BusController->UsbHCInterface;\r
-  MaxPacketLength = UsbIoDevice->DeviceDescriptor.MaxPacketSize0;\r
+  UsbIoDev        = UsbIoController->UsbDevice;\r
+\r
+  MaxPacketLength = UsbIoDev->DeviceDescriptor.MaxPacketSize0;\r
 \r
  \r
   if (Request->Request     == USB_DEV_CLEAR_FEATURE && \r
@@ -268,24 +268,23 @@ UsbControlTransfer (
       return EFI_DEVICE_ERROR;\r
     }\r
   }\r
-\r
-\r
-\r
   //\r
   // using HostController's ControlTransfer to complete the request\r
   //\r
-  RetStatus = UsbHCInterface->ControlTransfer (\r
-                                UsbHCInterface,\r
-                                UsbIoDevice->DeviceAddress,\r
-                                UsbIoDevice->IsSlowDevice,\r
-                                MaxPacketLength,\r
-                                Request,\r
-                                Direction,\r
-                                Data,\r
-                                &DataLength,\r
-                                (UINTN) Timeout,\r
-                                &TransferResult\r
-                                );\r
+  RetStatus = UsbVirtualHcControlTransfer (\r
+                UsbIoDev->BusController,\r
+                UsbIoDev->DeviceAddress,\r
+                UsbIoDev->DeviceSpeed,\r
+                MaxPacketLength,\r
+                Request,\r
+                Direction,\r
+                Data,\r
+                &DataLength,\r
+                (UINTN) Timeout,\r
+                UsbIoDev->Translator,\r
+                &TransferResult\r
+                );\r
+\r
   *Status = TransferResult;\r
 \r
   if (Request->Request     == USB_DEV_CLEAR_FEATURE && \r
@@ -346,18 +345,19 @@ UsbBulkTransfer (
 --*/\r
 {\r
   USB_IO_DEVICE               *UsbIoDev;\r
-  UINT8                       MaxPacketLength;\r
+  UINTN                       MaxPacketLength;\r
   UINT8                       DataToggle;\r
   UINT8                       OldToggle;\r
   EFI_STATUS                  RetStatus;\r
-  EFI_USB_HC_PROTOCOL         *UsbHCInterface;\r
+\r
   USB_IO_CONTROLLER_DEVICE    *UsbIoController;\r
   ENDPOINT_DESC_LIST_ENTRY    *EndPointListEntry;\r
   UINT32                      TransferResult;\r
-\r
-  UsbIoController = USB_IO_CONTROLLER_DEVICE_FROM_USB_IO_THIS (This);\r
-  UsbIoDev        = UsbIoController->UsbDevice;\r
-  UsbHCInterface  = UsbIoDev->BusController->UsbHCInterface;\r
+  UINT8                       DataBuffersNumber;\r
+  \r
+  DataBuffersNumber = 1;\r
+  UsbIoController   = USB_IO_CONTROLLER_DEVICE_FROM_USB_IO_THIS (This);\r
+  UsbIoDev          = UsbIoController->UsbDevice;\r
 \r
   //\r
   // Parameters Checking\r
@@ -408,17 +408,20 @@ UsbBulkTransfer (
   //\r
   // using HostController's BulkTransfer to complete the request\r
   //\r
-  RetStatus = UsbHCInterface->BulkTransfer (\r
-                                UsbHCInterface,\r
-                                UsbIoDev->DeviceAddress,\r
-                                DeviceEndpoint,\r
-                                MaxPacketLength,\r
-                                Data,\r
-                                DataLength,\r
-                                &DataToggle,\r
-                                Timeout,\r
-                                &TransferResult\r
-                                );\r
+  RetStatus = UsbVirtualHcBulkTransfer (\r
+                UsbIoDev->BusController,\r
+                UsbIoDev->DeviceAddress,\r
+                DeviceEndpoint,\r
+                UsbIoDev->DeviceSpeed,\r
+                MaxPacketLength,\r
+                DataBuffersNumber,\r
+                &Data,\r
+                DataLength,\r
+                &DataToggle,\r
+                Timeout,\r
+                UsbIoDev->Translator,\r
+                &TransferResult\r
+                );\r
 \r
   if (OldToggle != DataToggle) {\r
     //\r
@@ -474,14 +477,13 @@ UsbSyncInterruptTransfer (
 \r
 --*/\r
 {\r
-  USB_IO_DEVICE               *UsbIoDev;\r
-  UINT8                       MaxPacketLength;\r
-  UINT8                       DataToggle;\r
-  UINT8                       OldToggle;\r
-  EFI_STATUS                  RetStatus;\r
-  EFI_USB_HC_PROTOCOL         *UsbHCInterface;\r
-  USB_IO_CONTROLLER_DEVICE    *UsbIoController;\r
-  ENDPOINT_DESC_LIST_ENTRY    *EndPointListEntry;\r
+  USB_IO_DEVICE             *UsbIoDev;\r
+  UINTN                     MaxPacketLength;\r
+  UINT8                     DataToggle;\r
+  UINT8                     OldToggle;\r
+  EFI_STATUS                RetStatus;\r
+  USB_IO_CONTROLLER_DEVICE  *UsbIoController;\r
+  ENDPOINT_DESC_LIST_ENTRY  *EndPointListEntry;\r
 \r
   //\r
   // Parameters Checking\r
@@ -517,8 +519,6 @@ UsbSyncInterruptTransfer (
   //\r
   UsbIoController = USB_IO_CONTROLLER_DEVICE_FROM_USB_IO_THIS (This);\r
   UsbIoDev        = UsbIoController->UsbDevice;\r
-  UsbHCInterface  = UsbIoDev->BusController->UsbHCInterface;\r
-\r
   GetDeviceEndPointMaxPacketLength (\r
     This,\r
     DeviceEndpoint,\r
@@ -535,18 +535,19 @@ UsbSyncInterruptTransfer (
   //\r
   // using HostController's SyncInterruptTransfer to complete the request\r
   //\r
-  RetStatus = UsbHCInterface->SyncInterruptTransfer (\r
-                                UsbHCInterface,\r
-                                UsbIoDev->DeviceAddress,\r
-                                DeviceEndpoint,\r
-                                UsbIoDev->IsSlowDevice,\r
-                                MaxPacketLength,\r
-                                Data,\r
-                                DataLength,\r
-                                &DataToggle,\r
-                                Timeout,\r
-                                Status\r
-                                );\r
+  RetStatus = UsbVirtualHcSyncInterruptTransfer (\r
+                UsbIoDev->BusController,\r
+                UsbIoDev->DeviceAddress,\r
+                DeviceEndpoint,\r
+                UsbIoDev->DeviceSpeed,\r
+                MaxPacketLength,\r
+                Data,\r
+                DataLength,\r
+                &DataToggle,\r
+                Timeout,\r
+                UsbIoDev->Translator,\r
+                Status\r
+                );\r
 \r
   if (OldToggle != DataToggle) {\r
     //\r
@@ -590,7 +591,7 @@ UsbAsyncInterruptTransfer (
                           the transfer is to be executed.\r
     DataLength        -   Specifies the length, in bytes, of the data to be\r
                           received from the USB device.\r
-    InterruptCallback -   The Callback function.  This function is called if\r
+    InterruptCallBack -   The Callback function.  This function is called if\r
                           the asynchronous interrupt transfer is completed.\r
     Context           -   Passed to InterruptCallback \r
   Returns:\r
@@ -600,13 +601,12 @@ UsbAsyncInterruptTransfer (
 \r
 --*/\r
 {\r
-  USB_IO_DEVICE               *UsbIoDev;\r
-  UINT8                       MaxPacketLength;\r
-  UINT8                       DataToggle;\r
-  EFI_USB_HC_PROTOCOL         *UsbHCInterface;\r
-  EFI_STATUS                  RetStatus;\r
-  USB_IO_CONTROLLER_DEVICE    *UsbIoController;\r
-  ENDPOINT_DESC_LIST_ENTRY    *EndpointListEntry;\r
+  USB_IO_DEVICE             *UsbIoDev;\r
+  UINTN                     MaxPacketLength;\r
+  UINT8                     DataToggle;\r
+  EFI_STATUS                RetStatus;\r
+  USB_IO_CONTROLLER_DEVICE  *UsbIoController;\r
+  ENDPOINT_DESC_LIST_ENTRY  *EndpointListEntry;\r
 \r
   //\r
   // Check endpoint\r
@@ -634,25 +634,25 @@ UsbAsyncInterruptTransfer (
 \r
   UsbIoController = USB_IO_CONTROLLER_DEVICE_FROM_USB_IO_THIS (This);\r
   UsbIoDev        = UsbIoController->UsbDevice;\r
-  UsbHCInterface  = UsbIoDev->BusController->UsbHCInterface;\r
 \r
   if (!IsNewTransfer) {\r
     //\r
     // Delete this transfer\r
     //\r
-    UsbHCInterface->AsyncInterruptTransfer (\r
-                      UsbHCInterface,\r
-                      UsbIoDev->DeviceAddress,\r
-                      DeviceEndpoint,\r
-                      UsbIoDev->IsSlowDevice,\r
-                      0,\r
-                      FALSE,\r
-                      &DataToggle,\r
-                      PollingInterval,\r
-                      DataLength,\r
-                      NULL,\r
-                      NULL\r
-                      );\r
+    UsbVirtualHcAsyncInterruptTransfer (\r
+      UsbIoDev->BusController,\r
+      UsbIoDev->DeviceAddress,\r
+      DeviceEndpoint,\r
+      UsbIoDev->DeviceSpeed,\r
+      0,\r
+      FALSE,\r
+      &DataToggle,\r
+      PollingInterval,\r
+      DataLength,\r
+      UsbIoDev->Translator,\r
+      NULL,\r
+      NULL\r
+      );\r
 \r
     //\r
     // We need to store the toggle value\r
@@ -678,19 +678,20 @@ UsbAsyncInterruptTransfer (
     &DataToggle\r
     );\r
 \r
-  RetStatus = UsbHCInterface->AsyncInterruptTransfer (\r
-                                UsbHCInterface,\r
-                                UsbIoDev->DeviceAddress,\r
-                                DeviceEndpoint,\r
-                                UsbIoDev->IsSlowDevice,\r
-                                MaxPacketLength,\r
-                                TRUE,\r
-                                &DataToggle,\r
-                                PollingInterval,\r
-                                DataLength,\r
-                                InterruptCallBack,\r
-                                Context\r
-                                );\r
+  RetStatus = UsbVirtualHcAsyncInterruptTransfer (\r
+                UsbIoDev->BusController,\r
+                UsbIoDev->DeviceAddress,\r
+                DeviceEndpoint,\r
+                UsbIoDev->DeviceSpeed,\r
+                MaxPacketLength,\r
+                TRUE,\r
+                &DataToggle,\r
+                PollingInterval,\r
+                DataLength,\r
+                UsbIoDev->Translator,\r
+                InterruptCallBack,\r
+                Context\r
+                );\r
 \r
   return RetStatus;\r
 }\r
@@ -1070,6 +1071,7 @@ UsbGetStringDescriptor (
     EFI_SUCCESS\r
     EFI_NOT_FOUND\r
     EFI_OUT_OF_RESOURCES\r
+    EFI_UNSUPPORTED\r
 \r
 --*/\r
 {\r
index 07eb5805e97adc00148a74dca3abeb91ebcf80e4..e3380856bfd1f6ac538459839409cfc79ff63a95 100644 (file)
@@ -35,10 +35,10 @@ IsPortConnect (
     Tell if there is a device connected to that port according to\r
     the Port Status.\r
 \r
-  Parameters:\r
+  Arguments:\r
     PortStatus  -   The status value of that port.\r
 \r
-  Return Value:\r
+  Returns:\r
     TRUE\r
     FALSE\r
 \r
@@ -280,7 +280,6 @@ IsPortResetChange (
   }\r
 }\r
 \r
-\r
 BOOLEAN\r
 IsPortSuspendChange (\r
   IN UINT16  PortChangeStatus\r
@@ -309,8 +308,7 @@ IsPortSuspendChange (
   }\r
 }\r
 \r
-\r
-INTERFACE_DESC_LIST_ENTRY* \r
+INTERFACE_DESC_LIST_ENTRY *\r
 FindInterfaceListEntry (\r
   IN EFI_USB_IO_PROTOCOL    *This\r
   )\r
@@ -329,7 +327,7 @@ FindInterfaceListEntry (
 {\r
   USB_IO_CONTROLLER_DEVICE  *UsbIoController;\r
   USB_IO_DEVICE             *UsbIoDev;\r
-  LIST_ENTRY            *InterfaceListHead;\r
+  LIST_ENTRY                *InterfaceListHead;\r
   INTERFACE_DESC_LIST_ENTRY *InterfaceListEntry;\r
 \r
   UsbIoController = USB_IO_CONTROLLER_DEVICE_FROM_USB_IO_THIS (This);\r
@@ -367,8 +365,8 @@ FindEndPointListEntry (
     Find EndPoint ListEntry.\r
 \r
   Arguments:\r
-    This         -  EFI_USB_IO_PROTOCOL   \r
-    EndpointAddr -  Endpoint address.\r
+    This            -  EFI_USB_IO_PROTOCOL   \r
+    EndPointAddress -  Endpoint address.\r
  \r
   Returns:\r
     ENDPOINT_DESC_LIST_ENTRY pointer\r
@@ -471,7 +469,7 @@ VOID
 GetDeviceEndPointMaxPacketLength (\r
   IN  EFI_USB_IO_PROTOCOL    *UsbIo,\r
   IN  UINT8                  EndpointAddr,\r
-  OUT UINT8                  *MaxPacketLength\r
+  OUT UINTN                  *MaxPacketLength\r
   )\r
 /*++\r
 \r
@@ -498,7 +496,7 @@ GetDeviceEndPointMaxPacketLength (
     return ;\r
   }\r
 \r
-  *MaxPacketLength = (UINT8) (EndpointListEntry->EndpointDescriptor.MaxPacketSize);\r
+  *MaxPacketLength = (UINTN) (EndpointListEntry->EndpointDescriptor.MaxPacketSize);\r
 \r
   return ;\r
 }\r
index b6efc6934f9421682813c8073ee8e58d163f2739..6c7da5bd2232fbde60fe818fa418c8bbe24e5094 100644 (file)
     <Filename>Bus/Pci/IdeBus/Dxe/idebus.msa</Filename>\r
     <Filename>Bus/Pci/PciBus/Dxe/PciBus.msa</Filename>\r
     <Filename>Bus/Pci/Uhci/Dxe/Uhci.msa</Filename>\r
+    <Filename>Bus/Pci/Ehci/Dxe/Ehci.msa</Filename>\r
     <Filename>Bus/Pci/Undi/RuntimeDxe/Undi.msa</Filename>\r
     <Filename>Bus/Scsi/ScsiBus/Dxe/ScsiBus.msa</Filename>\r
     <Filename>Bus/Scsi/ScsiDisk/Dxe/ScsiDisk.msa</Filename>\r
     <Filename>Universal/Console/Terminal/Dxe/Terminal.msa</Filename>\r
     <Filename>Universal/DataHub/DataHub/Dxe/DataHub.msa</Filename>\r
     <Filename>Universal/DataHub/DataHubStdErr/Dxe/DataHubStdErr.msa</Filename>\r
+    <Filename>Universal/DevicePath/Dxe/DevicePath.msa</Filename>\r
     <Filename>Universal/Debugger/Debugport/Dxe/DebugPort.msa</Filename>\r
     <Filename>Universal/DebugSupport/Dxe/DebugSupport.msa</Filename>\r
     <Filename>Universal/Disk/DiskIo/Dxe/DiskIo.msa</Filename>\r
diff --git a/EdkModulePkg/Universal/DevicePath/Dxe/DevicePath.c b/EdkModulePkg/Universal/DevicePath/Dxe/DevicePath.c
new file mode 100644 (file)
index 0000000..79741a4
--- /dev/null
@@ -0,0 +1,107 @@
+/*++
+
+Copyright (c) 2006, Intel Corporation                                                         
+All rights reserved. This program and the accompanying materials                          
+are licensed and made available under the terms and conditions of the BSD License         
+which accompanies this distribution.  The full text of the license may be found at        
+http://opensource.org/licenses/bsd-license.php                                            
+                                                                                          
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             
+
+Module Name:
+
+  DevicePathDriver.c
+
+Abstract:
+
+  Device Path Driver to produce DevPathUtilities Protocol, DevPathFromText Protocol
+  and DevPathToText Protocol.
+
+--*/
+
+#include <Uefi/UefiSpec.h>
+#include <Protocol/DevicePath.h>
+#include "DevicePath.h"
+
+DEVICE_PATH_DRIVER_PRIVATE_DATA mPrivateData;
+
+EFI_GUID mEfiDevicePathMessagingUartFlowControlGuid = DEVICE_PATH_MESSAGING_UART_FLOW_CONTROL;
+EFI_GUID mEfiDevicePathMessagingSASGuid             = DEVICE_PATH_MESSAGING_SAS;
+
+STATIC EFI_DEVICE_PATH_UTILITIES_PROTOCOL mDevicePathUtilitiesProtocol = {
+  GetDevicePathSize,
+  DuplicateDevicePath,
+  AppendDevicePath,
+  AppendDeviceNode,
+  AppendDevicePathInstance,
+  GetNextDevicePathInstance,
+  IsDevicePathMultiInstance,
+  CreateDeviceNode
+};
+
+STATIC EFI_DEVICE_PATH_TO_TEXT_PROTOCOL   mDevicePathToTextProtocol = {
+  ConvertDeviceNodeToText,
+  ConvertDevicePathToText
+};
+
+STATIC EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL mDevicePathFromTextProtocol = {
+  ConvertTextToDeviceNode,
+  ConvertTextToDevicePath
+};
+
+EFI_STATUS
+EFIAPI
+DevicePathEntryPoint (
+  IN EFI_HANDLE           ImageHandle,
+  IN EFI_SYSTEM_TABLE     *SystemTable
+  )
+/*++
+
+  Routine Description:
+    Entry point for EFI drivers.
+
+  Arguments:
+   ImageHandle - EFI_HANDLE
+   SystemTable - EFI_SYSTEM_TABLE
+
+  Returns:
+    EFI_SUCCESS
+    others
+
+--*/
+{
+  EFI_STATUS  Status;
+
+  mPrivateData.Signature = DEVICE_PATH_DRIVER_SIGNATURE;
+
+  mPrivateData.DevicePathUtilities.GetDevicePathSize         = GetDevicePathSize;
+  mPrivateData.DevicePathUtilities.DuplicateDevicePath       = DuplicateDevicePath;
+  mPrivateData.DevicePathUtilities.AppendDevicePath          = AppendDevicePath;
+  mPrivateData.DevicePathUtilities.AppendDeviceNode          = AppendDeviceNode;
+  mPrivateData.DevicePathUtilities.AppendDevicePathInstance  = AppendDevicePathInstance;
+  mPrivateData.DevicePathUtilities.GetNextDevicePathInstance = GetNextDevicePathInstance;
+  mPrivateData.DevicePathUtilities.IsDevicePathMultiInstance = IsDevicePathMultiInstance;
+  mPrivateData.DevicePathUtilities.CreateDeviceNode          = CreateDeviceNode;
+
+  mPrivateData.DevicePathToText.ConvertDeviceNodeToText      = ConvertDeviceNodeToText;
+  mPrivateData.DevicePathToText.ConvertDevicePathToText      = ConvertDevicePathToText;
+
+  mPrivateData.DevicePathFromText.ConvertTextToDeviceNode    = ConvertTextToDeviceNode;
+  mPrivateData.DevicePathFromText.ConvertTextToDevicePath    = ConvertTextToDevicePath;
+
+  mPrivateData.Handle                                        = NULL;
+  
+  Status = gBS->InstallMultipleProtocolInterfaces (
+                  &mPrivateData.Handle,
+                  &gEfiDevicePathUtilitiesProtocolGuid,
+                  &mPrivateData.DevicePathUtilities,
+                  &gEfiDevicePathToTextProtocolGuid,
+                  &mPrivateData.DevicePathToText,
+                  &gEfiDevicePathFromTextProtocolGuid,
+                  &mPrivateData.DevicePathFromText,
+                  NULL
+                  );
+
+  return Status;
+}
diff --git a/EdkModulePkg/Universal/DevicePath/Dxe/DevicePath.h b/EdkModulePkg/Universal/DevicePath/Dxe/DevicePath.h
new file mode 100644 (file)
index 0000000..aa33345
--- /dev/null
@@ -0,0 +1,422 @@
+/*++\r
+\r
+Copyright (c) 2006, Intel Corporation                                                         \r
+All rights reserved. This program and the accompanying materials                          \r
+are licensed and made available under the terms and conditions of the BSD License         \r
+which accompanies this distribution.  The full text of the license may be found at        \r
+http://opensource.org/licenses/bsd-license.php                                            \r
+                                                                                          \r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     \r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             \r
+\r
+Module Name:\r
+\r
+  DevicePathDriver.h\r
+  \r
+Abstract:\r
+  Definition for Device Path Utilities driver\r
+\r
+--*/\r
+\r
+#ifndef _DEVICE_PATH_DRIVER_H\r
+#define _DEVICE_PATH_DRIVER_H\r
+\r
+extern EFI_GUID mEfiDevicePathMessagingUartFlowControlGuid;\r
+extern EFI_GUID mEfiDevicePathMessagingSASGuid;\r
+\r
+#define DEVICE_PATH_DRIVER_SIGNATURE EFI_SIGNATURE_32 ('D', 'P', 'D', 'V')\r
+\r
+typedef struct {\r
+\r
+  UINT32                             Signature;\r
+  EFI_HANDLE                         Handle;\r
+  //\r
+  // Produced protocols\r
+  //\r
+  EFI_DEVICE_PATH_UTILITIES_PROTOCOL DevicePathUtilities;\r
+  EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL DevicePathFromText;\r
+  EFI_DEVICE_PATH_TO_TEXT_PROTOCOL   DevicePathToText;\r
+\r
+} DEVICE_PATH_DRIVER_PRIVATE_DATA;\r
+\r
+#define MAX_CHAR                   480\r
+\r
+#define MIN_ALIGNMENT_SIZE         sizeof(UINTN)\r
+#define ALIGN_SIZE(a)              ((a % MIN_ALIGNMENT_SIZE) ? MIN_ALIGNMENT_SIZE - (a % MIN_ALIGNMENT_SIZE) : 0)\r
+\r
+#define IS_COMMA(a)                ((a) == L',')\r
+#define IS_HYPHEN(a)               ((a) == L'-')\r
+#define IS_DOT(a)                  ((a) == L'.')\r
+#define IS_LEFT_PARENTH(a)         ((a) == L'(')\r
+#define IS_RIGHT_PARENTH(a)        ((a) == L')')\r
+#define IS_SLASH(a)                ((a) == L'/')\r
+#define IS_NULL(a)                 ((a) == L'\0')\r
+\r
+#define DEVICE_NODE_END            1\r
+#define DEVICE_PATH_INSTANCE_END   2\r
+#define DEVICE_PATH_END            3\r
+\r
+#define SetDevicePathInstanceEndNode(a) {                \\r
+    (a)->Type       = END_DEVICE_PATH_TYPE;              \\r
+    (a)->SubType    = END_INSTANCE_DEVICE_PATH_SUBTYPE;  \\r
+    (a)->Length[0]  = sizeof (EFI_DEVICE_PATH_PROTOCOL); \\r
+    (a)->Length[1]  = 0;                                 \\r
+  }\r
+\r
+//\r
+// Private Data structure\r
+//\r
+typedef struct {\r
+  CHAR16  *Str;\r
+  UINTN   Len;\r
+  UINTN   MaxLen;\r
+} POOL_PRINT;\r
+\r
+typedef struct {\r
+  UINT8   Type;\r
+  UINT8   SubType;\r
+  VOID    (*Function) (POOL_PRINT *, VOID *, BOOLEAN, BOOLEAN);\r
+} DEVICE_PATH_TO_TEXT_TABLE;\r
+\r
+typedef struct {\r
+  CHAR16                    *DevicePathNodeText;\r
+  EFI_DEVICE_PATH_PROTOCOL  * (*Function) (CHAR16 *);\r
+} DEVICE_PATH_FROM_TEXT_TABLE;\r
+\r
+typedef struct {\r
+  BOOLEAN ClassExist;\r
+  UINT8   Class;\r
+  BOOLEAN SubClassExist;\r
+  UINT8   SubClass;\r
+} USB_CLASS_TEXT;\r
+\r
+#define USB_CLASS_AUDIO            1\r
+#define USB_CLASS_CDCCONTROL       2\r
+#define USB_CLASS_HID              3\r
+#define USB_CLASS_IMAGE            6\r
+#define USB_CLASS_PRINTER          7\r
+#define USB_CLASS_MASS_STORAGE     8\r
+#define USB_CLASS_HUB              9\r
+#define USB_CLASS_CDCDATA          10\r
+#define USB_CLASS_SMART_CARD       11\r
+#define USB_CLASS_VIDEO            14\r
+#define USB_CLASS_DIAGNOSTIC       220\r
+#define USB_CLASS_WIRELESS         224\r
+\r
+#define USB_CLASS_RESERVE          254\r
+#define USB_SUBCLASS_FW_UPDATE     1\r
+#define USB_SUBCLASS_IRDA_BRIDGE   2\r
+#define USB_SUBCLASS_TEST          3\r
+\r
+typedef struct {\r
+  EFI_DEVICE_PATH_PROTOCOL  Header;\r
+  EFI_GUID                  Guid;\r
+  UINT8                     VendorDefinedData[1];\r
+} VENDOR_DEFINED_HARDWARE_DEVICE_PATH;\r
+\r
+typedef struct {\r
+  EFI_DEVICE_PATH_PROTOCOL  Header;\r
+  EFI_GUID                  Guid;\r
+  UINT8                     VendorDefinedData[1];\r
+} VENDOR_DEFINED_MESSAGING_DEVICE_PATH;\r
+\r
+typedef struct {\r
+  EFI_DEVICE_PATH_PROTOCOL  Header;\r
+  EFI_GUID                  Guid;\r
+  UINT8                     VendorDefinedData[1];\r
+} VENDOR_DEFINED_MEDIA_DEVICE_PATH;\r
+\r
+typedef struct {\r
+  EFI_DEVICE_PATH_PROTOCOL  Header;\r
+  UINT32                    HID;\r
+  UINT32                    UID;\r
+  UINT32                    CID;\r
+  CHAR8                     HidUidCidStr[3];\r
+} ACPI_EXTENDED_HID_DEVICE_PATH_WITH_STR;\r
+\r
+typedef struct {\r
+  EFI_DEVICE_PATH_PROTOCOL  Header;\r
+  UINT16                    NetworkProtocol;\r
+  UINT16                    LoginOption;\r
+  UINT16                    Reserved;\r
+  UINT16                    TargetPortalGroupTag;\r
+  UINT64                    Lun;\r
+  CHAR16                    iSCSITargetName[1];\r
+} ISCSI_DEVICE_PATH_WITH_NAME;\r
+\r
+typedef struct {\r
+  EFI_DEVICE_PATH_PROTOCOL  Header;\r
+  EFI_GUID                  Guid;\r
+  UINT8                     VendorDefinedData[1];\r
+} VENDOR_DEVICE_PATH_WITH_DATA;\r
+\r
+CHAR16 *\r
+ConvertDeviceNodeToText (\r
+  IN CONST EFI_DEVICE_PATH_PROTOCOL  *DeviceNode,\r
+  IN BOOLEAN                         DisplayOnly,\r
+  IN BOOLEAN                         AllowShortcuts\r
+  )\r
+/*++\r
+\r
+  Routine Description:\r
+    Convert a device node to its text representation.\r
+\r
+  Arguments:\r
+    DeviceNode       -   Points to the device node to be converted.\r
+    DisplayOnly      -   If DisplayOnly is TRUE, then the shorter text representation\r
+                         of the display node is used, where applicable. If DisplayOnly\r
+                         is FALSE, then the longer text representation of the display node\r
+                         is used.\r
+    AllowShortcuts   -   If AllowShortcuts is TRUE, then the shortcut forms of text\r
+                         representation for a device node can be used, where applicable.\r
+\r
+  Returns:\r
+    A pointer        -   a pointer to the allocated text representation of the device node.\r
+    NULL             -   if DeviceNode is NULL or there was insufficient memory.\r
+\r
+--*/\r
+;\r
+\r
+CHAR16 *\r
+ConvertDevicePathToText (\r
+  IN CONST EFI_DEVICE_PATH_PROTOCOL  *DeviceNode,\r
+  IN BOOLEAN                         DisplayOnly,\r
+  IN BOOLEAN                         AllowShortcuts\r
+  )\r
+/*++\r
+\r
+  Routine Description:\r
+    Convert a device path to its text representation.\r
+\r
+  Arguments:\r
+    DeviceNode       -   Points to the device path to be converted.\r
+    DisplayOnly      -   If DisplayOnly is TRUE, then the shorter text representation\r
+                         of the display node is used, where applicable. If DisplayOnly\r
+                         is FALSE, then the longer text representation of the display node\r
+                         is used.\r
+    AllowShortcuts   -   If AllowShortcuts is TRUE, then the shortcut forms of text\r
+                         representation for a device node can be used, where applicable.\r
+\r
+  Returns:\r
+    A pointer        -   a pointer to the allocated text representation of the device path.\r
+    NULL             -   if DeviceNode is NULL or there was insufficient memory.\r
+\r
+--*/\r
+;\r
+\r
+EFI_DEVICE_PATH_PROTOCOL *\r
+ConvertTextToDeviceNode (\r
+  IN CONST CHAR16 *TextDeviceNode\r
+  )\r
+/*++\r
+\r
+  Routine Description:\r
+    Convert text to the binary representation of a device node.\r
+\r
+  Arguments:\r
+    TextDeviceNode   -   TextDeviceNode points to the text representation of a device\r
+                         node. Conversion starts with the first character and continues\r
+                         until the first non-device node character.\r
+\r
+  Returns:\r
+    A pointer        -   Pointer to the EFI device node.\r
+    NULL             -   if TextDeviceNode is NULL or there was insufficient memory.\r
+\r
+--*/\r
+;\r
+\r
+EFI_DEVICE_PATH_PROTOCOL *\r
+ConvertTextToDevicePath (\r
+  IN CONST CHAR16 *TextDevicePath\r
+  )\r
+/*++\r
+\r
+  Routine Description:\r
+    Convert text to the binary representation of a device path.\r
+\r
+  Arguments:\r
+    TextDevicePath   -   TextDevicePath points to the text representation of a device\r
+                         path. Conversion starts with the first character and continues\r
+                         until the first non-device node character.\r
+\r
+  Returns:\r
+    A pointer        -   Pointer to the allocated device path.\r
+    NULL             -   if TextDeviceNode is NULL or there was insufficient memory.\r
+\r
+--*/\r
+;\r
+\r
+UINTN\r
+GetDevicePathSize (\r
+  IN CONST EFI_DEVICE_PATH_PROTOCOL  *DevicePath\r
+  )\r
+/*++\r
+\r
+  Routine Description:\r
+    Returns the size of the device path, in bytes.\r
+\r
+  Arguments:\r
+    DevicePath  -   Points to the start of the EFI device path.\r
+\r
+  Returns:\r
+    Size        -   Size of the specified device path, in bytes, including the end-of-path tag.\r
+\r
+--*/\r
+;\r
+\r
+EFI_DEVICE_PATH_PROTOCOL *\r
+DuplicateDevicePath (\r
+  IN CONST EFI_DEVICE_PATH_PROTOCOL  *DevicePath\r
+  )\r
+/*++\r
+\r
+  Routine Description:\r
+    Create a duplicate of the specified path.\r
+\r
+  Arguments:\r
+    DevicePath  -   Points to the source EFI device path.\r
+\r
+  Returns:\r
+    Pointer     -   A pointer to the duplicate device path.\r
+    NULL        -   Insufficient memory.\r
+\r
+--*/\r
+;\r
+\r
+EFI_DEVICE_PATH_PROTOCOL *\r
+AppendDevicePath (\r
+  IN CONST EFI_DEVICE_PATH_PROTOCOL *Src1,\r
+  IN CONST EFI_DEVICE_PATH_PROTOCOL *Src2\r
+  )\r
+/*++\r
+\r
+  Routine Description:\r
+    Create a new path by appending the second device path to the first.\r
+\r
+  Arguments:\r
+    Src1      -   Points to the first device path. If NULL, then it is ignored.\r
+    Src2      -   Points to the second device path. If NULL, then it is ignored.\r
+\r
+  Returns:\r
+    Pointer   -   A pointer to the newly created device path.\r
+    NULL      -   Memory could not be allocated\r
+                  or either DevicePath or DeviceNode is NULL.\r
+\r
+--*/\r
+;\r
+\r
+EFI_DEVICE_PATH_PROTOCOL *\r
+AppendDeviceNode (\r
+  IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath,\r
+  IN CONST EFI_DEVICE_PATH_PROTOCOL *DeviceNode\r
+  )\r
+/*++\r
+\r
+  Routine Description:\r
+    Creates a new path by appending the device node to the device path.\r
+\r
+  Arguments:\r
+    DevicePath   -   Points to the device path.\r
+    DeviceNode   -   Points to the device node.\r
+\r
+  Returns:\r
+    Pointer      -   A pointer to the allocated device node.\r
+    NULL         -   Memory could not be allocated\r
+                     or either DevicePath or DeviceNode is NULL.\r
+\r
+--*/\r
+;\r
+\r
+EFI_DEVICE_PATH_PROTOCOL *\r
+AppendDevicePathInstance (\r
+  IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath,\r
+  IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePathInstance\r
+  )\r
+/*++\r
+\r
+  Routine Description:\r
+    Creates a new path by appending the specified device path instance to the specified device path.\r
+\r
+  Arguments:\r
+    DevicePath           -   Points to the device path. If NULL, then ignored.\r
+    DevicePathInstance   -   Points to the device path instance.\r
+\r
+  Returns:\r
+    Pointer              -   A pointer to the newly created device path\r
+    NULL                 -   Memory could not be allocated or DevicePathInstance is NULL.\r
+\r
+--*/\r
+;\r
+\r
+EFI_DEVICE_PATH_PROTOCOL *\r
+GetNextDevicePathInstance (\r
+  IN OUT EFI_DEVICE_PATH_PROTOCOL   **DevicePathInstance,\r
+  OUT UINTN                         *DevicePathInstanceSize\r
+  )\r
+/*++\r
+\r
+  Routine Description:\r
+    Creates a copy of the current device path instance and returns a pointer to the next device path instance.\r
+\r
+  Arguments:\r
+    DevicePathInstance       -   On input, this holds the pointer to the current device path\r
+                                 instance. On output, this holds the pointer to the next\r
+                                 device path instance or NULL if there are no more device\r
+                                 path instances in the device path.\r
+    DevicePathInstanceSize   -   On output, this holds the size of the device path instance,\r
+                                 in bytes or zero, if DevicePathInstance is zero.\r
+\r
+  Returns:\r
+    Pointer                  -   A pointer to the copy of the current device path instance.\r
+    NULL                     -   DevicePathInstace was NULL on entry or there was insufficient memory.\r
+\r
+--*/\r
+;\r
+\r
+BOOLEAN\r
+IsDevicePathMultiInstance (\r
+  IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath\r
+  )\r
+/*++\r
+\r
+  Routine Description:\r
+    Returns whether a device path is multi-instance.\r
+\r
+  Arguments:\r
+    DevicePath  -   Points to the device path. If NULL, then ignored.\r
+\r
+  Returns:\r
+    TRUE        -   The device path has more than one instance\r
+    FALSE       -   The device path is empty or contains only a single instance.\r
+\r
+--*/\r
+;\r
+\r
+EFI_DEVICE_PATH_PROTOCOL *\r
+CreateDeviceNode (\r
+  IN UINT8  NodeType,\r
+  IN UINT8  NodeSubType,\r
+  IN UINT16 NodeLength\r
+  )\r
+/*++\r
+\r
+  Routine Description:\r
+    Creates a device node\r
+\r
+  Arguments:\r
+    NodeType     -    NodeType is the device node type (EFI_DEVICE_PATH.Type) for\r
+                      the new device node.\r
+    NodeSubType  -    NodeSubType is the device node sub-type\r
+                      EFI_DEVICE_PATH.SubType) for the new device node.\r
+    NodeLength   -    NodeLength is the length of the device node\r
+                      (EFI_DEVICE_PATH.Length) for the new device node.\r
+\r
+  Returns:\r
+    Pointer      -    A pointer to the newly created device node.\r
+    NULL         -    NodeLength is less than\r
+                      the size of the header or there was insufficient memory.\r
+\r
+--*/\r
+;\r
+\r
+#endif\r
diff --git a/EdkModulePkg/Universal/DevicePath/Dxe/DevicePath.msa b/EdkModulePkg/Universal/DevicePath/Dxe/DevicePath.msa
new file mode 100644 (file)
index 0000000..20dd598
--- /dev/null
@@ -0,0 +1,109 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+\r
+<!--Copyright (c) 2006, Intel Corporation\r
+All rights reserved. This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.-->\r
+<ModuleSurfaceArea  xmlns="http://www.TianoCore.org/2006/Edk2.0">\r
+\r
+  <MsaHeader>\r
+    <ModuleName>DevicePath</ModuleName>\r
+    <ModuleType>DXE_DRIVER</ModuleType>\r
+    <GuidValue>9B680FCE-AD6B-4F3A-B60B-F59899003443</GuidValue>\r
+    <Version>1.0</Version>\r
+    <Abstract>Component description file for Device Path Driver.</Abstract>\r
+    <Description>This driver is for DevicePathUtilities, DevicePahtToText and DevicePathFromText</Description>\r
+    <Copyright>Copyright (c) 2006, Intel Corporation</Copyright>\r
+    <License>All rights reserved. This program and the accompanying materials\r
+      are licensed and made available under the terms and conditions of the BSD License\r
+      which accompanies this distribution.  The full text of the license may be found at\r
+      http://opensource.org/licenses/bsd-license.php\r
+      THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+      WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.</License>\r
+    <Specification>FRAMEWORK_BUILD_PACKAGING_SPECIFICATION   0x00000052</Specification>\r
+  </MsaHeader>\r
+  <ModuleDefinitions>\r
+    <SupportedArchitectures>IA32 X64 IPF EBC</SupportedArchitectures>\r
+    <BinaryModule>false</BinaryModule>\r
+    <OutputFileBasename>DevicePath</OutputFileBasename>\r
+  </ModuleDefinitions>\r
+  <LibraryClassDefinitions>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>DebugLib</Keyword>\r
+    </LibraryClass>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>PrintLib</Keyword>\r
+    </LibraryClass>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>UefiDriverEntryPoint</Keyword>\r
+    </LibraryClass>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>UefiLib</Keyword>\r
+    </LibraryClass>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>BaseLib</Keyword>\r
+    </LibraryClass>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>BaseMemoryLib</Keyword>\r
+    </LibraryClass>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>MemoryAllocationLib</Keyword>\r
+    </LibraryClass>\r
+    <LibraryClass Usage="ALWAYS_CONSUMED">\r
+      <Keyword>UefiBootServicesTableLib</Keyword>\r
+    </LibraryClass>\r
+  </LibraryClassDefinitions>\r
+  <SourceFiles>\r
+    <Filename>DevicePath.c</Filename>\r
+    <Filename>DevicePath.h</Filename>\r
+    <Filename>DevicePathFromText.c</Filename>\r
+    <Filename>DevicePathToText.c</Filename>\r
+    <Filename>DevicePathUtilities.c</Filename>\r
+  </SourceFiles>\r
+  <PackageDependencies>\r
+    <Package PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>\r
+    <Package PackageGuid="B6EC423C-21D2-490D-85C6-DD5864EAA674"/>\r
+  </PackageDependencies>\r
+  <Protocols>    \r
+    <Protocol Usage="ALWAYS_CONSUMED">\r
+      <ProtocolCName>gEfiDebugPortProtocolGuid</ProtocolCName>\r
+    </Protocol>\r
+    <Protocol Usage="ALWAYS_CONSUMED">\r
+      <ProtocolCName>gEfiDevicePathProtocolGuid</ProtocolCName>\r
+    </Protocol>\r
+    <Protocol Usage="ALWAYS_PRODUCED">\r
+      <ProtocolCName>gEfiDevicePathUtilitiesProtocolGuid</ProtocolCName>\r
+    </Protocol>\r
+    <Protocol Usage="ALWAYS_PRODUCED">\r
+      <ProtocolCName>gEfiDevicePathFromTextProtocolGuid</ProtocolCName>\r
+    </Protocol>\r
+    <Protocol Usage="ALWAYS_PRODUCED">\r
+      <ProtocolCName>gEfiDevicePathToTextProtocolGuid</ProtocolCName>\r
+    </Protocol>\r
+  </Protocols>\r
+  <Guids>\r
+    <GuidCNames Usage="ALWAYS_CONSUMED">\r
+      <GuidCName>gEfiPcAnsiGuid</GuidCName>\r
+    </GuidCNames>\r
+    <GuidCNames Usage="ALWAYS_CONSUMED">\r
+      <GuidCName>gEfiVT100PlusGuid</GuidCName>\r
+    </GuidCNames>\r
+    <GuidCNames Usage="ALWAYS_CONSUMED">\r
+      <GuidCName>gEfiVT100Guid</GuidCName>\r
+    </GuidCNames>\r
+    <GuidCNames Usage="ALWAYS_CONSUMED">\r
+      <GuidCName>gEfiVTUTF8Guid</GuidCName>\r
+    </GuidCNames>\r
+  </Guids>\r
+  <Externs>\r
+    <Specification>EFI_SPECIFICATION_VERSION 0x00020000</Specification>\r
+    <Specification>EDK_RELEASE_VERSION 0x00090000</Specification>\r
+    <Extern>\r
+      <ModuleEntryPoint>DevicePathEntryPoint</ModuleEntryPoint>\r
+    </Extern>\r
+  </Externs>\r
+</ModuleSurfaceArea>\r
diff --git a/EdkModulePkg/Universal/DevicePath/Dxe/DevicePathFromText.c b/EdkModulePkg/Universal/DevicePath/Dxe/DevicePathFromText.c
new file mode 100644 (file)
index 0000000..e0864da
--- /dev/null
@@ -0,0 +1,2434 @@
+/*++
+
+Copyright (c) 2006, Intel Corporation                                                         
+All rights reserved. This program and the accompanying materials                          
+are licensed and made available under the terms and conditions of the BSD License         
+which accompanies this distribution.  The full text of the license may be found at        
+http://opensource.org/licenses/bsd-license.php                                            
+                                                                                          
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             
+
+Module Name:
+
+  DevicePathFromText.c
+
+Abstract:
+
+  DevicePathFromText protocol as defined in the UEFI 2.0 specification.
+
+--*/
+
+#include <protocol/DevicePathFromText.h>
+#include "DevicePath.h"
+
+CHAR16 *
+StrDuplicate (
+  IN CONST CHAR16  *Src
+  )
+/*++
+
+  Routine Description:
+    Duplicate a string
+
+  Arguments:
+    Src - Source string
+
+  Returns:
+    Duplicated string
+
+--*/
+{
+  UINTN   Length;
+  CHAR16  *ReturnStr;
+
+  Length = StrLen ((CHAR16 *) Src);
+
+  ReturnStr = AllocateCopyPool ((Length + 1) * sizeof (CHAR16), (VOID *) Src);
+
+  return ReturnStr;
+}
+
+CHAR16 *
+GetParamByNodeName (
+  IN CHAR16 *Str,
+  IN CHAR16 *NodeName
+  )
+/*++
+
+  Routine Description:
+    Get parameter in a pair of parentheses follow the given node name.
+    For example, given the "Pci(0,1)" and NodeName "Pci", it returns "0,1".
+
+  Arguments:
+    Str      - Device Path Text
+    NodeName - Name of the node
+
+  Returns:
+    Parameter text for the node
+
+--*/
+{
+  CHAR16  *ParamStr;
+  CHAR16  *StrPointer;
+  UINTN   NodeNameLength;
+  UINTN   ParameterLength;
+
+  //
+  // Check whether the node name matchs
+  //
+  NodeNameLength = StrLen (NodeName);
+  if (CompareMem (Str, NodeName, NodeNameLength * sizeof (CHAR16)) != 0) {
+    return NULL;
+  }
+
+  ParamStr = Str + NodeNameLength;
+  if (!IS_LEFT_PARENTH (*ParamStr)) {
+    return NULL;
+  }
+
+  //
+  // Skip the found '(' and find first occurrence of ')'
+  //
+  ParamStr++;
+  ParameterLength = 0;
+  StrPointer = ParamStr;
+  while (!IS_NULL (*StrPointer)) {
+    if (IS_RIGHT_PARENTH (*StrPointer)) {
+      break;
+    }
+    StrPointer++;
+    ParameterLength++;
+  }
+  if (IS_NULL (*StrPointer)) {
+    //
+    // ')' not found
+    //
+    return NULL;
+  }
+
+  ParamStr = AllocateCopyPool ((ParameterLength + 1) * sizeof (CHAR16), ParamStr);
+  if (ParamStr == NULL) {
+    return NULL;
+  }
+  //
+  // Terminate the parameter string
+  //
+  ParamStr[ParameterLength] = L'\0';
+
+  return ParamStr;
+}
+
+CHAR16 *
+SplitStr (
+  IN OUT CHAR16 **List,
+  IN     CHAR16 Separator
+  )
+/*++
+
+  Routine Description:
+    Get current sub-string from a string list, before return
+    the list header is moved to next sub-string. The sub-string is separated
+    by the specified character. For example, the separator is ',', the string
+    list is "2,0,3", it returns "2", the remain list move to "2,3"
+
+  Arguments:
+    List       - A string list separated by the specified separator
+    Separator  - The separator character
+
+  Returns:
+    pointer    - The current sub-string
+
+--*/
+{
+  CHAR16  *Str;
+  CHAR16  *ReturnStr;
+
+  Str = *List;
+  ReturnStr = Str;
+
+  if (IS_NULL (*Str)) {
+    return ReturnStr;
+  }
+
+  //
+  // Find first occurrence of the separator
+  //
+  while (!IS_NULL (*Str)) {
+    if (*Str == Separator) {
+      break;
+    }
+    Str++;
+  }
+
+  if (*Str == Separator) {
+    //
+    // Find a sub-string, terminate it
+    //
+    *Str = L'\0';
+    Str++;
+  }
+
+  //
+  // Move to next sub-string
+  //
+  *List = Str;
+
+  return ReturnStr;
+}
+
+CHAR16 *
+GetNextParamStr (
+  IN OUT CHAR16 **List
+  )
+{
+  //
+  // The separator is comma
+  //
+  return SplitStr (List, L',');
+}
+
+CHAR16 *
+GetNextDeviceNodeStr (
+  IN OUT CHAR16   **DevicePath,
+  OUT    BOOLEAN  *IsInstanceEnd
+  )
+/*++
+
+  Routine Description:
+    Get one device node from entire device path text.
+
+  Arguments:
+    Str           - The entire device path text string
+    IsInstanceEnd - This node is the end of a device path instance
+
+  Returns:
+    a pointer     - A device node text
+    NULL          - No more device node available
+
+--*/
+{
+  CHAR16  *Str;
+  CHAR16  *ReturnStr;
+  UINTN   ParenthesesStack;
+
+  Str = *DevicePath;
+  if (IS_NULL (*Str)) {
+    return NULL;
+  }
+
+  //
+  // Skip the leading '/', '(', ')' and ','
+  //
+  while (!IS_NULL (*Str)) {
+    if (!IS_SLASH (*Str) &&
+        !IS_COMMA (*Str) &&
+        !IS_LEFT_PARENTH (*Str) &&
+        !IS_RIGHT_PARENTH (*Str)) {
+      break;
+    }
+    Str++;
+  }
+
+  ReturnStr = Str;
+
+  //
+  // Scan for the separator of this device node, '/' or ','
+  //
+  ParenthesesStack = 0;
+  while (!IS_NULL (*Str)) {
+    if ((IS_COMMA (*Str) || IS_SLASH (*Str)) && (ParenthesesStack == 0)) {
+      break;
+    }
+
+    if (IS_LEFT_PARENTH (*Str)) {
+      ParenthesesStack++;
+    } else if (IS_RIGHT_PARENTH (*Str)) {
+      ParenthesesStack--;
+    }
+
+    Str++;
+  }
+
+  if (ParenthesesStack != 0) {
+    //
+    // The '(' doesn't pair with ')', invalid device path text
+    //
+    return NULL;
+  }
+
+  if (IS_COMMA (*Str)) {
+    *IsInstanceEnd = TRUE;
+    *Str = L'\0';
+    Str++;
+  } else {
+    *IsInstanceEnd = FALSE;
+    if (!IS_NULL (*Str)) {
+      *Str = L'\0';
+      Str++;
+    }
+  }
+
+  *DevicePath = Str;
+
+  return ReturnStr;
+}
+
+BOOLEAN
+IsHexDigit (
+  OUT UINT8      *Digit,
+  IN  CHAR16      Char
+  )
+/*++
+
+  Routine Description:
+    Determines if a Unicode character is a hexadecimal digit.
+    The test is case insensitive.
+
+  Arguments:
+    Digit - Pointer to byte that receives the value of the hex character.
+    Char  - Unicode character to test.
+
+  Returns:
+    TRUE  - If the character is a hexadecimal digit.
+    FALSE - Otherwise.
+
+--*/
+{
+  if ((Char >= L'0') && (Char <= L'9')) {
+    *Digit = (UINT8) (Char - L'0');
+    return TRUE;
+  }
+
+  if ((Char >= L'A') && (Char <= L'F')) {
+    *Digit = (UINT8) (Char - L'A' + 0x0A);
+    return TRUE;
+  }
+
+  if ((Char >= L'a') && (Char <= L'f')) {
+    *Digit = (UINT8) (Char - L'a' + 0x0A);
+    return TRUE;
+  }
+
+  return FALSE;
+}
+
+CHAR16
+NibbleToHexChar (
+  IN UINT8      Nibble
+  )
+/*++
+
+  Routine Description:
+    Converts the low nibble of a byte  to hex unicode character.
+
+  Arguments:
+    Nibble - lower nibble of a byte.
+
+  Returns:
+    Hex unicode character.
+
+--*/
+{
+  Nibble &= 0x0F;
+  if (Nibble <= 0x9) {
+    return (CHAR16)(Nibble + L'0');
+  }
+
+  return (CHAR16)(Nibble - 0xA + L'A');
+}
+
+EFI_STATUS
+HexStringToBuf (
+  IN OUT UINT8                     *Buf,   
+  IN OUT UINTN                     *Len,
+  IN     CHAR16                    *Str,
+  OUT    UINTN                     *ConvertedStrLen  OPTIONAL
+  )
+/*++
+
+  Routine Description:
+    Converts Unicode string to binary buffer.
+    The conversion may be partial.
+    The first character in the string that is not hex digit stops the conversion.
+    At a minimum, any blob of data could be represented as a hex string.
+
+  Arguments:
+    Buf    - Pointer to buffer that receives the data.
+    Len    - Length in bytes of the buffer to hold converted data.
+                If routine return with EFI_SUCCESS, containing length of converted data.
+                If routine return with EFI_BUFFER_TOO_SMALL, containg length of buffer desired.
+    Str    - String to be converted from.
+    ConvertedStrLen - Length of the Hex String consumed.
+
+  Returns:
+    EFI_SUCCESS: Routine Success.
+    EFI_BUFFER_TOO_SMALL: The buffer is too small to hold converted data.
+    EFI_
+
+--*/
+{
+  UINTN       HexCnt;
+  UINTN       Idx;
+  UINTN       BufferLength;
+  UINT8       Digit;
+  UINT8       Byte;
+
+  //
+  // Find out how many hex characters the string has.
+  //
+  for (Idx = 0, HexCnt = 0; IsHexDigit (&Digit, Str[Idx]); Idx++, HexCnt++);
+
+  if (HexCnt == 0) {
+    *Len = 0;
+    return EFI_SUCCESS;
+  }
+  //
+  // Two Unicode characters make up 1 buffer byte. Round up.
+  //
+  BufferLength = (HexCnt + 1) / 2; 
+
+  //
+  // Test if  buffer is passed enough.
+  //
+  if (BufferLength > (*Len)) {
+    *Len = BufferLength;
+    return EFI_BUFFER_TOO_SMALL;
+  }
+
+  *Len = BufferLength;
+
+  for (Idx = 0; Idx < HexCnt; Idx++) {
+
+    IsHexDigit (&Digit, Str[HexCnt - 1 - Idx]);
+
+    //
+    // For odd charaters, write the lower nibble for each buffer byte,
+    // and for even characters, the upper nibble.
+    //
+    if ((Idx & 1) == 0) {
+      Byte = Digit;
+    } else {
+      Byte = Buf[Idx / 2];
+      Byte &= 0x0F;
+      Byte |= Digit << 4;
+    }
+
+    Buf[Idx / 2] = Byte;
+  }
+
+  if (ConvertedStrLen != NULL) {
+    *ConvertedStrLen = HexCnt;
+  }
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+BufToHexString (
+  IN OUT CHAR16                    *Str,
+  IN OUT UINTN                     *HexStringBufferLength,
+  IN     UINT8                     *Buf,
+  IN     UINTN                     Len
+  )
+/*++
+
+  Routine Description:
+    Converts binary buffer to Unicode string.
+    At a minimum, any blob of data could be represented as a hex string.
+
+  Arguments:
+    Str - Pointer to the string.
+    HexStringBufferLength - Length in bytes of buffer to hold the hex string. Includes tailing '\0' character.
+                                        If routine return with EFI_SUCCESS, containing length of hex string buffer.
+                                        If routine return with EFI_BUFFER_TOO_SMALL, containg length of hex string buffer desired.
+    Buf - Buffer to be converted from.
+    Len - Length in bytes of the buffer to be converted.
+
+  Returns:
+    EFI_SUCCESS: Routine success.
+    EFI_BUFFER_TOO_SMALL: The hex string buffer is too small.
+
+--*/
+{
+  UINTN       Idx;
+  UINT8       Byte;
+  UINTN       StrLen;
+
+  //
+  // Make sure string is either passed or allocate enough.
+  // It takes 2 Unicode characters (4 bytes) to represent 1 byte of the binary buffer.
+  // Plus the Unicode termination character.
+  //
+  StrLen = Len * 2;
+  if (StrLen > ((*HexStringBufferLength) - 1)) {
+    *HexStringBufferLength = StrLen + 1;
+    return EFI_BUFFER_TOO_SMALL;
+  }
+
+  *HexStringBufferLength = StrLen + 1;
+  //
+  // Ends the string.
+  //
+  Str[StrLen] = L'\0'; 
+
+  for (Idx = 0; Idx < Len; Idx++) {
+
+    Byte = Buf[Idx];
+    Str[StrLen - 1 - Idx * 2] = NibbleToHexChar (Byte);
+    Str[StrLen - 2 - Idx * 2] = NibbleToHexChar ((UINT8)(Byte >> 4));
+  }
+
+  return EFI_SUCCESS;
+}
+
+CHAR16 *
+TrimHexStr (
+  IN CHAR16  *Str
+  )
+/*++
+
+  Routine Description:
+    Skip the leading white space and '0x' or '0X' of a hex string
+
+  Arguments:
+    Str  -  The hex string
+
+  Returns:
+
+--*/
+{
+  //
+  // skip preceeding white space
+  //
+  while (*Str && *Str == ' ') {
+    Str += 1;
+  }
+  //
+  // skip preceeding zeros
+  //
+  while (*Str && *Str == '0') {
+    Str += 1;
+  }
+  //
+  // skip preceeding white space
+  //
+  if (*Str && (*Str == 'x' || *Str == 'X')) {
+    Str += 1;
+  }
+
+  return Str;
+}
+
+UINTN
+Xtoi (
+  IN CHAR16  *Str
+  )
+/*++
+
+Routine Description:
+
+  Convert hex string to uint
+
+Arguments:
+
+  Str  -  The string
+  
+Returns:
+
+--*/
+{
+  UINTN   Rvalue;
+  UINTN   Length;
+
+  ASSERT (Str != NULL);
+
+  //
+  // convert hex digits
+  //
+  Rvalue = 0;
+  Length = sizeof (UINTN);
+  HexStringToBuf ((UINT8 *) &Rvalue, &Length, TrimHexStr (Str), NULL);
+
+  return Rvalue;
+}
+
+VOID
+Xtoi64 (
+  IN CHAR16  *Str,
+  IN UINT64  *Data
+  )
+/*++
+
+Routine Description:
+
+  Convert hex string to 64 bit data.
+
+Arguments:
+
+  Str  -  The string
+  
+Returns:
+
+--*/
+{
+  UINTN  Length;
+
+  Length = sizeof (UINT64);
+  HexStringToBuf ((UINT8 *) Data, &Length, TrimHexStr (Str), NULL);
+}
+
+UINTN
+Atoi (
+  IN CHAR16  *str
+  )
+/*++
+
+Routine Description:
+
+  Convert decimal string to uint
+
+Arguments:
+
+  Str  -  The string
+  
+Returns:
+
+--*/
+{
+  UINTN   Rvalue;
+  CHAR16  Char;
+  UINTN   High;
+  UINTN   Low;
+
+  ASSERT (str != NULL);
+
+  High = (UINTN) -1 / 10;
+  Low  = (UINTN) -1 % 10;
+  //
+  // skip preceeding white space
+  //
+  while (*str && *str == ' ') {
+    str += 1;
+  }
+  //
+  // convert digits
+  //
+  Rvalue = 0;
+  Char = *(str++);
+  while (Char) {
+    if (Char >= '0' && Char <= '9') {
+      if (Rvalue > High || Rvalue == High && Char - '0' > (INTN) Low) {
+        return (UINTN) -1;
+      }
+
+      Rvalue = (Rvalue * 10) + Char - '0';
+    } else {
+      break;
+    }
+
+    Char = *(str++);
+  }
+
+  return Rvalue;
+}
+
+EFI_STATUS 
+StrToBuf (
+  OUT UINT8    *Buf,
+  IN  UINTN    BufferLength,
+  IN  CHAR16   *Str
+  )
+{
+  UINTN       Index;
+  UINTN       StrLength;
+  UINT8       Digit;
+  UINT8       Byte;
+
+  //
+  // Two hex char make up one byte
+  //
+  StrLength = BufferLength * sizeof (CHAR16);
+
+  for(Index = 0; Index < StrLength; Index++, Str++) {
+
+    IsHexDigit (&Digit, *Str);
+
+    //
+    // For odd charaters, write the upper nibble for each buffer byte,
+    // and for even characters, the lower nibble.
+    //
+    if ((Index & 1) == 0) {
+      Byte = Digit << 4;
+    } else {
+      Byte = Buf[Index / 2];
+      Byte &= 0xF0;
+      Byte |= Digit;
+    }
+
+    Buf[Index / 2] = Byte;
+  }
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+StrToGuid (
+  IN  CHAR16   *Str,
+  OUT EFI_GUID *Guid
+  )
+{
+  UINTN       BufferLength;
+  UINTN       ConvertedStrLen;
+  EFI_STATUS  Status;
+
+  BufferLength = sizeof (Guid->Data1);
+  Status = HexStringToBuf ((UINT8 *) &Guid->Data1, &BufferLength, Str, &ConvertedStrLen);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+  Str += ConvertedStrLen;
+  if (IS_HYPHEN (*Str)) {
+    Str++;   
+  } else {
+    return EFI_UNSUPPORTED;
+  }
+
+  BufferLength = sizeof (Guid->Data2);
+  Status = HexStringToBuf ((UINT8 *) &Guid->Data2, &BufferLength, Str, &ConvertedStrLen);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+  Str += ConvertedStrLen;
+  if (IS_HYPHEN (*Str)) {
+    Str++;
+  } else {
+    return EFI_UNSUPPORTED;
+  }
+
+  BufferLength = sizeof (Guid->Data3);
+  Status = HexStringToBuf ((UINT8 *) &Guid->Data3, &BufferLength, Str, &ConvertedStrLen);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+  Str += ConvertedStrLen;
+  if (IS_HYPHEN (*Str)) {
+    Str++;
+  } else {
+    return EFI_UNSUPPORTED;
+  }
+
+  StrToBuf (&Guid->Data4[0], 2, Str);
+  //
+  // Skip 2 byte hex chars
+  //
+  Str += 2 * 2;
+
+  if (IS_HYPHEN (*Str)) {
+    Str++;
+  } else {
+    return EFI_UNSUPPORTED;
+  }
+  StrToBuf (&Guid->Data4[2], 6, Str);
+
+  return EFI_SUCCESS;
+}
+
+VOID
+StrToIPv4Addr (
+  IN OUT CHAR16           **Str,
+  OUT    EFI_IPv4_ADDRESS *IPv4Addr
+  )
+{
+  UINTN  Index;
+
+  for (Index = 0; Index < 4; Index++) {
+    IPv4Addr->Addr[Index] = (UINT8) Atoi (SplitStr (Str, L'.'));
+  }
+}
+
+VOID
+StrToIPv6Addr (
+  IN OUT CHAR16           **Str,
+  OUT    EFI_IPv6_ADDRESS *IPv6Addr
+  )
+{
+  UINTN  Index;
+  UINT16 Data;
+
+  for (Index = 0; Index < 8; Index++) {
+    Data = (UINT16) Xtoi (SplitStr (Str, L':'));
+    IPv6Addr->Addr[Index * 2] = (UINT8) (Data >> 8);
+    IPv6Addr->Addr[Index * 2 + 1] = (UINT8) (Data & 0xff);
+  }
+}
+
+VOID
+StrToAscii (
+  IN     CHAR16 *Str,
+  IN OUT CHAR8  **AsciiStr
+  )
+{
+  CHAR8 *Dest;
+
+  Dest = *AsciiStr;
+  while (!IS_NULL (*Str)) {
+    *(Dest++) = (CHAR8) *(Str++);
+  }
+  *Dest = 0;
+
+  //
+  // Return the string next to it
+  //
+  *AsciiStr = Dest + 1;
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextPci (
+  IN CHAR16 *TextDeviceNode
+  )
+{
+  CHAR16          *FunctionStr;
+  CHAR16          *DeviceStr;
+  PCI_DEVICE_PATH *Pci;
+
+  FunctionStr = GetNextParamStr (&TextDeviceNode);
+  DeviceStr   = GetNextParamStr (&TextDeviceNode);
+  Pci         = (PCI_DEVICE_PATH *) CreateDeviceNode (
+                                      HARDWARE_DEVICE_PATH,
+                                      HW_PCI_DP,
+                                      sizeof (PCI_DEVICE_PATH)
+                                      );
+
+  Pci->Function = (UINT8) Xtoi (FunctionStr);
+  Pci->Device   = (UINT8) Xtoi (DeviceStr);
+
+  return (EFI_DEVICE_PATH_PROTOCOL *) Pci;
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextPcCard (
+  IN CHAR16 *TextDeviceNode
+  )
+{
+  CHAR16              *FunctionNumberStr;
+  PCCARD_DEVICE_PATH  *Pccard;
+
+  FunctionNumberStr = GetNextParamStr (&TextDeviceNode);
+  Pccard            = (PCCARD_DEVICE_PATH *) CreateDeviceNode (
+                                               HARDWARE_DEVICE_PATH,
+                                               HW_PCCARD_DP,
+                                               sizeof (PCCARD_DEVICE_PATH)
+                                               );
+
+  Pccard->FunctionNumber  = (UINT8) Xtoi (FunctionNumberStr);
+
+  return (EFI_DEVICE_PATH_PROTOCOL *) Pccard;
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextMemoryMapped (
+  IN CHAR16 *TextDeviceNode
+  )
+{
+  CHAR16              *StartingAddressStr;
+  CHAR16              *EndingAddressStr;
+  MEMMAP_DEVICE_PATH  *MemMap;
+
+  StartingAddressStr = GetNextParamStr (&TextDeviceNode);
+  EndingAddressStr   = GetNextParamStr (&TextDeviceNode);
+  MemMap             = (MEMMAP_DEVICE_PATH *) CreateDeviceNode (
+                                               HARDWARE_DEVICE_PATH,
+                                               HW_MEMMAP_DP,
+                                               sizeof (MEMMAP_DEVICE_PATH)
+                                               );
+
+  MemMap->MemoryType  = 0;
+
+  Xtoi64 (StartingAddressStr, &MemMap->StartingAddress);
+  Xtoi64 (EndingAddressStr, &MemMap->EndingAddress);
+
+  return (EFI_DEVICE_PATH_PROTOCOL *) MemMap;
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+ConvertFromTextVendor (
+  IN CHAR16 *TextDeviceNode,
+  IN UINT8  Type,
+  IN UINT8  SubType
+  )
+{
+  CHAR16              *GuidStr;
+  CHAR16              *DataStr;
+  UINTN               Length;
+  VENDOR_DEVICE_PATH  *Vendor;
+
+  GuidStr = GetNextParamStr (&TextDeviceNode);
+
+  DataStr = GetNextParamStr (&TextDeviceNode);
+  Length  = StrLen (DataStr);
+  //
+  // Two hex characters make up 1 buffer byte
+  //
+  Length  = (Length + 1) / 2;
+
+  Vendor  = (VENDOR_DEVICE_PATH *) CreateDeviceNode (
+                                     Type,
+                                     SubType,
+                                     sizeof (VENDOR_DEVICE_PATH) + (UINT16) Length
+                                     );
+
+  StrToGuid (GuidStr, &Vendor->Guid);
+  StrToBuf (((UINT8 *) Vendor) + sizeof (VENDOR_DEVICE_PATH), Length, DataStr);
+
+  return (EFI_DEVICE_PATH_PROTOCOL *) Vendor;
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextVenHw (
+  IN CHAR16 *TextDeviceNode
+  )
+{
+  return ConvertFromTextVendor (
+           TextDeviceNode,
+           HARDWARE_DEVICE_PATH,
+           HW_VENDOR_DP
+           );
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextCtrl (
+  IN CHAR16 *TextDeviceNode
+  )
+{
+  CHAR16                  *ControllerStr;
+  CONTROLLER_DEVICE_PATH  *Controller;
+
+  ControllerStr = GetNextParamStr (&TextDeviceNode);
+  Controller    = (CONTROLLER_DEVICE_PATH *) CreateDeviceNode (
+                                               HARDWARE_DEVICE_PATH,
+                                               HW_CONTROLLER_DP,
+                                               sizeof (CONTROLLER_DEVICE_PATH)
+                                               );
+  Controller->ControllerNumber = (UINT32) Xtoi (ControllerStr);
+
+  return (EFI_DEVICE_PATH_PROTOCOL *) Controller;
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextAcpi (
+  IN CHAR16 *TextDeviceNode
+  )
+{
+  CHAR16                *HIDStr;
+  CHAR16                *UIDStr;
+  ACPI_HID_DEVICE_PATH  *Acpi;
+
+  HIDStr = GetNextParamStr (&TextDeviceNode);
+  UIDStr = GetNextParamStr (&TextDeviceNode);
+  Acpi   = (ACPI_HID_DEVICE_PATH *) CreateDeviceNode (
+                                      ACPI_DEVICE_PATH,
+                                      ACPI_DP,
+                                      sizeof (ACPI_HID_DEVICE_PATH)
+                                      );
+
+  if ((HIDStr[0] == L'P') && (HIDStr[1] == L'N') && (HIDStr[2] == L'P')) {
+    HIDStr += 3;
+  }
+
+  Acpi->HID = EISA_PNP_ID (Xtoi (HIDStr));
+  Acpi->UID = (UINT32) Xtoi (UIDStr);
+
+  return (EFI_DEVICE_PATH_PROTOCOL *) Acpi;
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+ConvertFromTextAcpi (
+  IN CHAR16 *TextDeviceNode,
+  IN UINT32  Hid
+  )
+{
+  CHAR16                *UIDStr;
+  ACPI_HID_DEVICE_PATH  *Acpi;
+
+  UIDStr = GetNextParamStr (&TextDeviceNode);
+  Acpi   = (ACPI_HID_DEVICE_PATH *) CreateDeviceNode (
+                                      ACPI_DEVICE_PATH,
+                                      ACPI_DP,
+                                      sizeof (ACPI_HID_DEVICE_PATH)
+                                      );
+
+  Acpi->HID = Hid;
+  Acpi->UID = (UINT32) Xtoi (UIDStr);
+
+  return (EFI_DEVICE_PATH_PROTOCOL *) Acpi;
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextPciRoot (
+  IN CHAR16 *TextDeviceNode
+  )
+{
+  return ConvertFromTextAcpi (TextDeviceNode, 0x0a0341d0);
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextFloppy (
+  IN CHAR16 *TextDeviceNode
+  )
+{
+  return ConvertFromTextAcpi (TextDeviceNode, 0x060441d0);
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextKeyboard (
+  IN CHAR16 *TextDeviceNode
+  )
+{
+  return ConvertFromTextAcpi (TextDeviceNode, 0x030141d0);
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextSerial (
+  IN CHAR16 *TextDeviceNode
+  )
+{
+  return ConvertFromTextAcpi (TextDeviceNode, 0x050141d0);
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextParallelPort (
+  IN CHAR16 *TextDeviceNode
+  )
+{
+  return ConvertFromTextAcpi (TextDeviceNode, 0x040141d0);
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextAcpiEx (
+  IN CHAR16 *TextDeviceNode
+  )
+{
+  CHAR16                                  *HIDStr;
+  CHAR16                                  *CIDStr;
+  CHAR16                                  *UIDStr;
+  CHAR16                                  *HIDSTRStr;
+  CHAR16                                  *CIDSTRStr;
+  CHAR16                                  *UIDSTRStr;
+  CHAR8                                   *AsciiStr;
+  UINT16                                  Length;
+  ACPI_EXTENDED_HID_DEVICE_PATH_WITH_STR  *AcpiExt;
+
+  HIDStr    = GetNextParamStr (&TextDeviceNode);
+  CIDStr    = GetNextParamStr (&TextDeviceNode);
+  UIDStr    = GetNextParamStr (&TextDeviceNode);
+  HIDSTRStr = GetNextParamStr (&TextDeviceNode);
+  CIDSTRStr = GetNextParamStr (&TextDeviceNode);
+  UIDSTRStr = GetNextParamStr (&TextDeviceNode);
+  Length    = sizeof (ACPI_EXTENDED_HID_DEVICE_PATH) + 
+                  (UINT16) StrLen (HIDSTRStr) + 1 +
+                  (UINT16) StrLen (UIDSTRStr) + 1 +
+                  (UINT16) StrLen (CIDSTRStr) + 1;
+  AcpiExt = (ACPI_EXTENDED_HID_DEVICE_PATH_WITH_STR *) CreateDeviceNode (
+                                                         ACPI_DEVICE_PATH,
+                                                         ACPI_EXTENDED_DP,
+                                                         Length
+                                                         );
+
+  if ((HIDStr[0] == L'P') && (HIDStr[1] == L'N') && (HIDStr[2] == L'P')) {
+    HIDStr += 3;
+    AcpiExt->HID = EISA_PNP_ID (Xtoi (HIDStr));
+  } else {
+    AcpiExt->HID = (UINT32) Xtoi (HIDStr);
+  }
+
+  AcpiExt->UID  = (UINT32) Xtoi (UIDStr);
+  AcpiExt->CID  = (UINT32) Xtoi (CIDStr);
+
+  AsciiStr = AcpiExt->HidUidCidStr;
+  StrToAscii (HIDSTRStr, &AsciiStr);
+  StrToAscii (UIDSTRStr, &AsciiStr);
+  StrToAscii (CIDSTRStr, &AsciiStr);
+  
+  return (EFI_DEVICE_PATH_PROTOCOL *) AcpiExt;
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextAcpiExp (
+  IN CHAR16 *TextDeviceNode
+  )
+{
+  CHAR16                                  *HIDStr;
+  CHAR16                                  *CIDStr;
+  CHAR16                                  *UIDSTRStr;
+  CHAR8                                   *AsciiStr;
+  UINT16                                  Length;
+  ACPI_EXTENDED_HID_DEVICE_PATH_WITH_STR  *AcpiExt;
+
+  HIDStr    = GetNextParamStr (&TextDeviceNode);
+  CIDStr    = GetNextParamStr (&TextDeviceNode);
+  UIDSTRStr = GetNextParamStr (&TextDeviceNode);
+  Length    = sizeof (ACPI_EXTENDED_HID_DEVICE_PATH) + (UINT16) StrLen (UIDSTRStr) + 3;
+  AcpiExt   = (ACPI_EXTENDED_HID_DEVICE_PATH_WITH_STR *) CreateDeviceNode (
+                                                           ACPI_DEVICE_PATH,
+                                                           ACPI_EXTENDED_DP,
+                                                           Length
+                                                           );
+
+  if ((HIDStr[0] == L'P') && (HIDStr[1] == L'N') && (HIDStr[2] == L'P')) {
+    HIDStr += 3;
+    AcpiExt->HID = EISA_PNP_ID (Xtoi (HIDStr));
+  } else {
+    AcpiExt->HID = (UINT32) Xtoi (HIDStr);
+  }
+
+  AcpiExt->UID = 0;
+  AcpiExt->CID = (UINT32) Xtoi (CIDStr);
+
+  AsciiStr = AcpiExt->HidUidCidStr;
+  //
+  // HID string is NULL
+  //
+  *AsciiStr = 0;
+  //
+  // Convert UID string
+  //
+  AsciiStr++;
+  StrToAscii (UIDSTRStr, &AsciiStr);
+  //
+  // CID string is NULL
+  //
+  *AsciiStr = 0;
+
+  return (EFI_DEVICE_PATH_PROTOCOL *) AcpiExt;
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextAta (
+  IN CHAR16 *TextDeviceNode
+  )
+{
+  CHAR16            *PrimarySecondaryStr;
+  CHAR16            *SlaveMasterStr;
+  CHAR16            *LunStr;
+  ATAPI_DEVICE_PATH *Atapi;
+
+  Atapi = (ATAPI_DEVICE_PATH *) CreateDeviceNode (
+                                  MESSAGING_DEVICE_PATH,
+                                  MSG_ATAPI_DP,
+                                  sizeof (ATAPI_DEVICE_PATH)
+                                  );
+
+  PrimarySecondaryStr     = GetNextParamStr (&TextDeviceNode);
+  SlaveMasterStr          = GetNextParamStr (&TextDeviceNode);
+  LunStr                  = GetNextParamStr (&TextDeviceNode);
+
+  Atapi->PrimarySecondary = (StrCmp (PrimarySecondaryStr, L"Primary") == 0) ? (UINT8) 0 : (UINT8) 1;
+  Atapi->SlaveMaster      = (StrCmp (SlaveMasterStr, L"Master") == 0) ? (UINT8) 0 : (UINT8) 1;
+  Atapi->Lun              = (UINT16) Xtoi (LunStr);
+
+  return (EFI_DEVICE_PATH_PROTOCOL *) Atapi;
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextScsi (
+  IN CHAR16 *TextDeviceNode
+  )
+{
+  CHAR16            *PunStr;
+  CHAR16            *LunStr;
+  SCSI_DEVICE_PATH  *Scsi;
+
+  PunStr = GetNextParamStr (&TextDeviceNode);
+  LunStr = GetNextParamStr (&TextDeviceNode);
+  Scsi   = (SCSI_DEVICE_PATH *) CreateDeviceNode (
+                                   MESSAGING_DEVICE_PATH,
+                                   MSG_SCSI_DP,
+                                   sizeof (SCSI_DEVICE_PATH)
+                                   );
+
+  Scsi->Pun = (UINT16) Xtoi (PunStr);
+  Scsi->Lun = (UINT16) Xtoi (LunStr);
+
+  return (EFI_DEVICE_PATH_PROTOCOL *) Scsi;
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextFibre (
+  IN CHAR16 *TextDeviceNode
+  )
+{
+  CHAR16                    *WWNStr;
+  CHAR16                    *LunStr;
+  FIBRECHANNEL_DEVICE_PATH  *Fibre;
+
+  WWNStr = GetNextParamStr (&TextDeviceNode);
+  LunStr = GetNextParamStr (&TextDeviceNode);
+  Fibre  = (FIBRECHANNEL_DEVICE_PATH *) CreateDeviceNode (
+                                          MESSAGING_DEVICE_PATH,
+                                          MSG_FIBRECHANNEL_DP,
+                                          sizeof (FIBRECHANNEL_DEVICE_PATH)
+                                          );
+
+  Fibre->Reserved = 0;
+  Xtoi64 (WWNStr, &Fibre->WWN);
+  Xtoi64 (LunStr, &Fibre->Lun);
+
+  return (EFI_DEVICE_PATH_PROTOCOL *) Fibre;
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromText1394 (
+  IN CHAR16 *TextDeviceNode
+  )
+{
+  CHAR16            *GuidStr;
+  F1394_DEVICE_PATH *F1394;
+
+  GuidStr = GetNextParamStr (&TextDeviceNode);
+  F1394  = (F1394_DEVICE_PATH *) CreateDeviceNode (
+                                   MESSAGING_DEVICE_PATH,
+                                   MSG_1394_DP,
+                                   sizeof (F1394_DEVICE_PATH)
+                                   );
+
+  F1394->Reserved = 0;
+  Xtoi64 (GuidStr, &F1394->Guid);
+
+  return (EFI_DEVICE_PATH_PROTOCOL *) F1394;
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextUsb (
+  IN CHAR16 *TextDeviceNode
+  )
+{
+  CHAR16          *PortStr;
+  CHAR16          *InterfaceStr;
+  USB_DEVICE_PATH *Usb;
+
+  PortStr               = GetNextParamStr (&TextDeviceNode);
+  InterfaceStr          = GetNextParamStr (&TextDeviceNode);
+  Usb                   = (USB_DEVICE_PATH *) CreateDeviceNode (
+                                                MESSAGING_DEVICE_PATH,
+                                                MSG_USB_DP,
+                                                sizeof (USB_DEVICE_PATH)
+                                                );
+
+  Usb->ParentPortNumber = (UINT8) Xtoi (PortStr);
+  Usb->InterfaceNumber  = (UINT8) Xtoi (InterfaceStr);
+
+  return (EFI_DEVICE_PATH_PROTOCOL *) Usb;
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextI2O (
+  IN CHAR16 *TextDeviceNode
+  )
+{
+  CHAR16          *TIDStr;
+  I2O_DEVICE_PATH *I2O;
+
+  TIDStr    = GetNextParamStr (&TextDeviceNode);
+  I2O       = (I2O_DEVICE_PATH *) CreateDeviceNode (
+                                    MESSAGING_DEVICE_PATH,
+                                    MSG_I2O_DP,
+                                    sizeof (I2O_DEVICE_PATH)
+                                    );
+
+  I2O->Tid  = (UINT32) Xtoi (TIDStr);
+
+  return (EFI_DEVICE_PATH_PROTOCOL *) I2O;
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextInfiniband (
+  IN CHAR16 *TextDeviceNode
+  )
+{
+  CHAR16                  *FlagsStr;
+  CHAR16                  *GuidStr;
+  CHAR16                  *SidStr;
+  CHAR16                  *TidStr;
+  CHAR16                  *DidStr;
+  EFI_GUID                PortGid;
+  INFINIBAND_DEVICE_PATH  *InfiniBand;
+
+  FlagsStr   = GetNextParamStr (&TextDeviceNode);
+  GuidStr    = GetNextParamStr (&TextDeviceNode);
+  SidStr     = GetNextParamStr (&TextDeviceNode);
+  TidStr     = GetNextParamStr (&TextDeviceNode);
+  DidStr     = GetNextParamStr (&TextDeviceNode);
+  InfiniBand = (INFINIBAND_DEVICE_PATH *) CreateDeviceNode (
+                                            MESSAGING_DEVICE_PATH,
+                                            MSG_INFINIBAND_DP,
+                                            sizeof (INFINIBAND_DEVICE_PATH)
+                                            );
+
+  InfiniBand->ResourceFlags = (UINT32) Xtoi (FlagsStr);
+  StrToGuid (GuidStr, &PortGid);
+  CopyMem (InfiniBand->PortGid, &PortGid, sizeof (EFI_GUID));
+  Xtoi64 (SidStr, &InfiniBand->ServiceId);
+  Xtoi64 (TidStr, &InfiniBand->TargetPortId);
+  Xtoi64 (DidStr, &InfiniBand->DeviceId);
+
+  return (EFI_DEVICE_PATH_PROTOCOL *) InfiniBand;
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextVenMsg (
+  IN CHAR16 *TextDeviceNode
+  )
+{
+  return ConvertFromTextVendor (
+            TextDeviceNode,
+            MESSAGING_DEVICE_PATH,
+            MSG_VENDOR_DP
+            );
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextVenPcAnsi (
+  IN CHAR16 *TextDeviceNode
+  )
+{
+  VENDOR_DEVICE_PATH  *Vendor;
+
+  Vendor = (VENDOR_DEVICE_PATH *) CreateDeviceNode (
+                                    MESSAGING_DEVICE_PATH,
+                                    MSG_VENDOR_DP,
+                                    sizeof (VENDOR_DEVICE_PATH));
+  Vendor->Guid = gEfiPcAnsiGuid;
+
+  return (EFI_DEVICE_PATH_PROTOCOL *) Vendor;
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextVenVt100 (
+  IN CHAR16 *TextDeviceNode
+  )
+{
+  VENDOR_DEVICE_PATH  *Vendor;
+
+  Vendor = (VENDOR_DEVICE_PATH *) CreateDeviceNode (
+                                    MESSAGING_DEVICE_PATH,
+                                    MSG_VENDOR_DP,
+                                    sizeof (VENDOR_DEVICE_PATH));
+  Vendor->Guid = gEfiVT100Guid;
+
+  return (EFI_DEVICE_PATH_PROTOCOL *) Vendor;
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextVenVt100Plus (
+  IN CHAR16 *TextDeviceNode
+  )
+{
+  VENDOR_DEVICE_PATH  *Vendor;
+
+  Vendor = (VENDOR_DEVICE_PATH *) CreateDeviceNode (
+                                    MESSAGING_DEVICE_PATH,
+                                    MSG_VENDOR_DP,
+                                    sizeof (VENDOR_DEVICE_PATH));
+  Vendor->Guid = gEfiVT100PlusGuid;
+
+  return (EFI_DEVICE_PATH_PROTOCOL *) Vendor;
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextVenUtf8 (
+  IN CHAR16 *TextDeviceNode
+  )
+{
+  VENDOR_DEVICE_PATH  *Vendor;
+
+  Vendor = (VENDOR_DEVICE_PATH *) CreateDeviceNode (
+                                    MESSAGING_DEVICE_PATH,
+                                    MSG_VENDOR_DP,
+                                    sizeof (VENDOR_DEVICE_PATH));
+  Vendor->Guid = gEfiVTUTF8Guid;
+
+  return (EFI_DEVICE_PATH_PROTOCOL *) Vendor;
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextUartFlowCtrl (
+  IN CHAR16 *TextDeviceNode
+  )
+{
+  CHAR16                        *ValueStr;
+  UART_FLOW_CONTROL_DEVICE_PATH *UartFlowControl;
+
+  ValueStr        = GetNextParamStr (&TextDeviceNode);
+  UartFlowControl = (UART_FLOW_CONTROL_DEVICE_PATH *) CreateDeviceNode (
+                                                        MESSAGING_DEVICE_PATH,
+                                                        MSG_VENDOR_DP,
+                                                        sizeof (UART_FLOW_CONTROL_DEVICE_PATH)
+                                                        );
+
+  UartFlowControl->Guid = mEfiDevicePathMessagingUartFlowControlGuid;
+  if (StrCmp (ValueStr, L"XonXoff") == 0) {
+    UartFlowControl->FlowControlMap = 2;
+  } else if (StrCmp (ValueStr, L"Hardware") == 0) {
+    UartFlowControl->FlowControlMap = 1;
+  } else {
+    UartFlowControl->FlowControlMap = 0;
+  }
+
+  return (EFI_DEVICE_PATH_PROTOCOL *) UartFlowControl;
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextSAS (
+  IN CHAR16 *TextDeviceNode
+  )
+{
+  CHAR16          *AddressStr;
+  CHAR16          *LunStr;
+  CHAR16          *RTPStr;
+  CHAR16          *SASSATAStr;
+  CHAR16          *LocationStr;
+  CHAR16          *ConnectStr;
+  CHAR16          *DriveBayStr;
+  CHAR16          *ReservedStr;
+  UINT16          Info;
+  SAS_DEVICE_PATH *Sas;
+
+  AddressStr  = GetNextParamStr (&TextDeviceNode);
+  LunStr      = GetNextParamStr (&TextDeviceNode);
+  RTPStr      = GetNextParamStr (&TextDeviceNode);
+  SASSATAStr  = GetNextParamStr (&TextDeviceNode);
+  LocationStr = GetNextParamStr (&TextDeviceNode);
+  ConnectStr  = GetNextParamStr (&TextDeviceNode);
+  DriveBayStr = GetNextParamStr (&TextDeviceNode);
+  ReservedStr = GetNextParamStr (&TextDeviceNode);
+  Info        = 0x0000;
+  Sas         = (SAS_DEVICE_PATH *) CreateDeviceNode (
+                                       MESSAGING_DEVICE_PATH,
+                                       MSG_VENDOR_DP,
+                                       sizeof (SAS_DEVICE_PATH)
+                                       );
+
+  Sas->Guid   = mEfiDevicePathMessagingSASGuid;
+  Xtoi64 (AddressStr, &Sas->SasAddress);
+  Xtoi64 (LunStr, &Sas->Lun);
+  Sas->RelativeTargetPort = (UINT16) Xtoi (RTPStr);
+  if (StrCmp (SASSATAStr, L"NoTopology") == 0)
+    ;
+  else {
+    if (StrCmp (DriveBayStr, L"0") == 0) {
+      Info |= 0x0001;
+    } else {
+      Info |= 0x0002;
+      Info |= (Xtoi (DriveBayStr) << 8);
+    }
+
+    if (StrCmp (SASSATAStr, L"SATA") == 0) {
+      Info |= 0x0010;
+    }
+
+    if (StrCmp (LocationStr, L"External") == 0) {
+      Info |= 0x0020;
+    }
+
+    if (StrCmp (ConnectStr, L"Expanded") == 0) {
+      Info |= 0x0040;
+    }
+  }
+
+  Sas->DeviceTopology = Info;
+  Sas->Reserved       = (UINT32) Xtoi (ReservedStr);
+
+  return (EFI_DEVICE_PATH_PROTOCOL *) Sas;
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextDebugPort (
+  IN CHAR16 *TextDeviceNode
+  )
+{
+  VENDOR_DEFINED_MESSAGING_DEVICE_PATH  *Vend;
+
+  Vend = (VENDOR_DEFINED_MESSAGING_DEVICE_PATH *) CreateDeviceNode (
+                                                    MESSAGING_DEVICE_PATH,
+                                                    MSG_VENDOR_DP,
+                                                    sizeof (VENDOR_DEFINED_MESSAGING_DEVICE_PATH)
+                                                    );
+
+  Vend->Guid = gEfiDebugPortProtocolGuid;
+
+  return (EFI_DEVICE_PATH_PROTOCOL *) Vend;
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextMAC (
+  IN CHAR16 *TextDeviceNode
+  )
+{
+  CHAR16                *AddressStr;
+  CHAR16                *IfTypeStr;
+  UINTN                 Length;
+  MAC_ADDR_DEVICE_PATH  *MAC;
+
+  AddressStr    = GetNextParamStr (&TextDeviceNode);
+  IfTypeStr     = GetNextParamStr (&TextDeviceNode);
+  MAC           = (MAC_ADDR_DEVICE_PATH *) CreateDeviceNode (
+                                              MESSAGING_DEVICE_PATH,
+                                              MSG_MAC_ADDR_DP,
+                                              sizeof (MAC_ADDR_DEVICE_PATH)
+                                              );
+
+  MAC->IfType   = (UINT8) Xtoi (IfTypeStr);
+
+  Length = sizeof (EFI_MAC_ADDRESS);
+  StrToBuf (&MAC->MacAddress.Addr[0], Length, AddressStr);
+
+  return (EFI_DEVICE_PATH_PROTOCOL *) MAC;
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextIPv4 (
+  IN CHAR16 *TextDeviceNode
+  )
+{
+  CHAR16            *RemoteIPStr;
+  CHAR16            *ProtocolStr;
+  CHAR16            *TypeStr;
+  CHAR16            *LocalIPStr;
+  IPv4_DEVICE_PATH  *IPv4;
+
+  RemoteIPStr           = GetNextParamStr (&TextDeviceNode);
+  ProtocolStr           = GetNextParamStr (&TextDeviceNode);
+  TypeStr               = GetNextParamStr (&TextDeviceNode);
+  LocalIPStr            = GetNextParamStr (&TextDeviceNode);
+  IPv4                  = (IPv4_DEVICE_PATH *) CreateDeviceNode (
+                                                 MESSAGING_DEVICE_PATH,
+                                                 MSG_IPv4_DP,
+                                                 sizeof (IPv4_DEVICE_PATH)
+                                                 );
+
+  StrToIPv4Addr (&RemoteIPStr, &IPv4->RemoteIpAddress);
+  IPv4->Protocol = (StrCmp (ProtocolStr, L"UDP") == 0) ? (UINT16) 0 : (UINT16) 1;
+  if (StrCmp (TypeStr, L"Static") == 0) {
+    IPv4->StaticIpAddress = TRUE;
+  } else {
+    IPv4->StaticIpAddress = FALSE;
+  }
+
+  StrToIPv4Addr (&LocalIPStr, &IPv4->LocalIpAddress);
+
+  IPv4->LocalPort      = 0;
+  IPv4->RemotePort     = 0;
+
+  return (EFI_DEVICE_PATH_PROTOCOL *) IPv4;
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextIPv6 (
+  IN CHAR16 *TextDeviceNode
+  )
+{
+  CHAR16            *RemoteIPStr;
+  CHAR16            *ProtocolStr;
+  CHAR16            *TypeStr;
+  CHAR16            *LocalIPStr;
+  IPv6_DEVICE_PATH  *IPv6;
+
+  RemoteIPStr           = GetNextParamStr (&TextDeviceNode);
+  ProtocolStr           = GetNextParamStr (&TextDeviceNode);
+  TypeStr               = GetNextParamStr (&TextDeviceNode);
+  LocalIPStr            = GetNextParamStr (&TextDeviceNode);
+  IPv6                  = (IPv6_DEVICE_PATH *) CreateDeviceNode (
+                                                 MESSAGING_DEVICE_PATH,
+                                                 MSG_IPv6_DP,
+                                                 sizeof (IPv6_DEVICE_PATH)
+                                                 );
+
+  StrToIPv6Addr (&RemoteIPStr, &IPv6->RemoteIpAddress);
+  IPv6->Protocol        = (StrCmp (ProtocolStr, L"UDP") == 0) ? (UINT16) 0 : (UINT16) 1;
+  if (StrCmp (TypeStr, L"Static") == 0) {
+    IPv6->StaticIpAddress = TRUE;
+  } else {
+    IPv6->StaticIpAddress = FALSE;
+  }
+
+  StrToIPv6Addr (&LocalIPStr, &IPv6->LocalIpAddress);
+
+  IPv6->LocalPort       = 0;
+  IPv6->RemotePort      = 0;
+
+  return (EFI_DEVICE_PATH_PROTOCOL *) IPv6;
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextUart (
+  IN CHAR16 *TextDeviceNode
+  )
+{
+  CHAR16            *BaudStr;
+  CHAR16            *DataBitsStr;
+  CHAR16            *ParityStr;
+  CHAR16            *StopBitsStr;
+  UART_DEVICE_PATH  *Uart;
+
+  BaudStr         = GetNextParamStr (&TextDeviceNode);
+  DataBitsStr     = GetNextParamStr (&TextDeviceNode);
+  ParityStr       = GetNextParamStr (&TextDeviceNode);
+  StopBitsStr     = GetNextParamStr (&TextDeviceNode);
+  Uart            = (UART_DEVICE_PATH *) CreateDeviceNode (
+                                           MESSAGING_DEVICE_PATH,
+                                           MSG_UART_DP,
+                                           sizeof (UART_DEVICE_PATH)
+                                           );
+
+  Uart->BaudRate  = (StrCmp (BaudStr, L"DEFAULT") == 0) ? 115200 : Atoi (BaudStr);
+  Uart->DataBits  = (StrCmp (DataBitsStr, L"DEFAULT") == 0) ? (UINT8) 8 : (UINT8) Atoi (DataBitsStr);
+  switch (*ParityStr) {
+  case L'D':
+    Uart->Parity = 0;
+    break;
+
+  case L'N':
+    Uart->Parity = 1;
+    break;
+
+  case L'E':
+    Uart->Parity = 2;
+    break;
+
+  case L'O':
+    Uart->Parity = 3;
+    break;
+
+  case L'M':
+    Uart->Parity = 4;
+    break;
+
+  case L'S':
+    Uart->Parity = 5;
+
+  default:
+    Uart->Parity = 0xff;
+  }
+
+  if (StrCmp (StopBitsStr, L"D") == 0) {
+    Uart->StopBits = (UINT8) 0;
+  } else if (StrCmp (StopBitsStr, L"1") == 0) {
+    Uart->StopBits = (UINT8) 1;
+  } else if (StrCmp (StopBitsStr, L"1.5") == 0) {
+    Uart->StopBits = (UINT8) 2;
+  } else if (StrCmp (StopBitsStr, L"2") == 0) {
+    Uart->StopBits = (UINT8) 3;
+  } else {
+    Uart->StopBits = 0xff;
+  }
+
+  return (EFI_DEVICE_PATH_PROTOCOL *) Uart;
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+ConvertFromTextUsbClass (
+  IN CHAR16         *TextDeviceNode,
+  IN USB_CLASS_TEXT *UsbClassText
+  )
+{
+  CHAR16                *VIDStr;
+  CHAR16                *PIDStr;
+  CHAR16                *ClassStr;
+  CHAR16                *SubClassStr;
+  CHAR16                *ProtocolStr;
+  USB_CLASS_DEVICE_PATH *UsbClass;
+
+  UsbClass    = (USB_CLASS_DEVICE_PATH *) CreateDeviceNode (
+                                            MESSAGING_DEVICE_PATH,
+                                            MSG_USB_CLASS_DP,
+                                            sizeof (USB_CLASS_DEVICE_PATH)
+                                            );
+
+  VIDStr      = GetNextParamStr (&TextDeviceNode);
+  PIDStr      = GetNextParamStr (&TextDeviceNode);
+  if (UsbClassText->ClassExist) {
+    ClassStr = GetNextParamStr (&TextDeviceNode);
+    UsbClass->DeviceClass = (UINT8) Xtoi (ClassStr);
+  } else {
+    UsbClass->DeviceClass = UsbClassText->Class;
+  }
+  if (UsbClassText->SubClassExist) {
+    SubClassStr = GetNextParamStr (&TextDeviceNode);
+    UsbClass->DeviceSubClass = (UINT8) Xtoi (SubClassStr);
+  } else {
+    UsbClass->DeviceSubClass = UsbClassText->SubClass;
+  }  
+
+  ProtocolStr = GetNextParamStr (&TextDeviceNode);
+
+  UsbClass->VendorId        = (UINT16) Xtoi (VIDStr);
+  UsbClass->ProductId       = (UINT16) Xtoi (PIDStr);
+  UsbClass->DeviceProtocol  = (UINT8) Xtoi (ProtocolStr);
+
+  return (EFI_DEVICE_PATH_PROTOCOL *) UsbClass;
+}
+
+
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextUsbClass (
+  IN CHAR16 *TextDeviceNode
+  )
+{
+  USB_CLASS_TEXT  UsbClassText;
+
+  UsbClassText.ClassExist    = TRUE;
+  UsbClassText.SubClassExist = TRUE;
+
+  return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText);
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextUsbAudio (
+  IN CHAR16 *TextDeviceNode
+  )
+{
+  USB_CLASS_TEXT  UsbClassText;
+
+  UsbClassText.ClassExist    = FALSE;
+  UsbClassText.Class         = USB_CLASS_AUDIO;
+  UsbClassText.SubClassExist = TRUE;
+
+  return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText);
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextUsbCDCControl (
+  IN CHAR16 *TextDeviceNode
+  )
+{
+  USB_CLASS_TEXT  UsbClassText;
+
+  UsbClassText.ClassExist    = FALSE;
+  UsbClassText.Class         = USB_CLASS_CDCCONTROL;
+  UsbClassText.SubClassExist = TRUE;
+
+  return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText);
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextUsbHID (
+  IN CHAR16 *TextDeviceNode
+  )
+{
+  USB_CLASS_TEXT  UsbClassText;
+
+  UsbClassText.ClassExist    = FALSE;
+  UsbClassText.Class         = USB_CLASS_HID;
+  UsbClassText.SubClassExist = TRUE;
+
+  return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText);
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextUsbImage (
+  IN CHAR16 *TextDeviceNode
+  )
+{
+  USB_CLASS_TEXT  UsbClassText;
+
+  UsbClassText.ClassExist    = FALSE;
+  UsbClassText.Class         = USB_CLASS_IMAGE;
+  UsbClassText.SubClassExist = TRUE;
+
+  return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText);
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextUsbPrinter (
+  IN CHAR16 *TextDeviceNode
+  )
+{
+  USB_CLASS_TEXT  UsbClassText;
+
+  UsbClassText.ClassExist    = FALSE;
+  UsbClassText.Class         = USB_CLASS_PRINTER;
+  UsbClassText.SubClassExist = TRUE;
+
+  return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText);
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextUsbMassStorage (
+  IN CHAR16 *TextDeviceNode
+  )
+{
+  USB_CLASS_TEXT  UsbClassText;
+
+  UsbClassText.ClassExist    = FALSE;
+  UsbClassText.Class         = USB_CLASS_MASS_STORAGE;
+  UsbClassText.SubClassExist = TRUE;
+
+  return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText);
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextUsbHub (
+  IN CHAR16 *TextDeviceNode
+  )
+{
+  USB_CLASS_TEXT  UsbClassText;
+
+  UsbClassText.ClassExist    = FALSE;
+  UsbClassText.Class         = USB_CLASS_HUB;
+  UsbClassText.SubClassExist = TRUE;
+
+  return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText);
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextUsbCDCData (
+  IN CHAR16 *TextDeviceNode
+  )
+{
+  USB_CLASS_TEXT  UsbClassText;
+
+  UsbClassText.ClassExist    = FALSE;
+  UsbClassText.Class         = USB_CLASS_CDCDATA;
+  UsbClassText.SubClassExist = TRUE;
+
+  return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText);
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextUsbSmartCard (
+  IN CHAR16 *TextDeviceNode
+  )
+{
+  USB_CLASS_TEXT  UsbClassText;
+
+  UsbClassText.ClassExist    = FALSE;
+  UsbClassText.Class         = USB_CLASS_SMART_CARD;
+  UsbClassText.SubClassExist = TRUE;
+
+  return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText);
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextUsbVideo (
+  IN CHAR16 *TextDeviceNode
+  )
+{
+  USB_CLASS_TEXT  UsbClassText;
+
+  UsbClassText.ClassExist    = FALSE;
+  UsbClassText.Class         = USB_CLASS_VIDEO;
+  UsbClassText.SubClassExist = TRUE;
+
+  return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText);
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextUsbDiagnostic (
+  IN CHAR16 *TextDeviceNode
+  )
+{
+  USB_CLASS_TEXT  UsbClassText;
+
+  UsbClassText.ClassExist    = FALSE;
+  UsbClassText.Class         = USB_CLASS_DIAGNOSTIC;
+  UsbClassText.SubClassExist = TRUE;
+
+  return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText);
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextUsbWireless (
+  IN CHAR16 *TextDeviceNode
+  )
+{
+  USB_CLASS_TEXT  UsbClassText;
+
+  UsbClassText.ClassExist    = FALSE;
+  UsbClassText.Class         = USB_CLASS_WIRELESS;
+  UsbClassText.SubClassExist = TRUE;
+
+  return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText);
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextUsbDeviceFirmwareUpdate (
+  IN CHAR16 *TextDeviceNode
+  )
+{
+  USB_CLASS_TEXT  UsbClassText;
+
+  UsbClassText.ClassExist    = FALSE;
+  UsbClassText.Class         = USB_CLASS_RESERVE;
+  UsbClassText.SubClassExist = FALSE;
+  UsbClassText.SubClass      = USB_SUBCLASS_FW_UPDATE;
+
+  return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText);
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextUsbIrdaBridge (
+  IN CHAR16 *TextDeviceNode
+  )
+{
+  USB_CLASS_TEXT  UsbClassText;
+
+  UsbClassText.ClassExist    = FALSE;
+  UsbClassText.Class         = USB_CLASS_RESERVE;
+  UsbClassText.SubClassExist = FALSE;
+  UsbClassText.SubClass      = USB_SUBCLASS_IRDA_BRIDGE;
+
+  return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText);
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextUsbTestAndMeasurement (
+  IN CHAR16 *TextDeviceNode
+  )
+{
+  USB_CLASS_TEXT  UsbClassText;
+
+  UsbClassText.ClassExist    = FALSE;
+  UsbClassText.Class         = USB_CLASS_RESERVE;
+  UsbClassText.SubClassExist = FALSE;
+  UsbClassText.SubClass      = USB_SUBCLASS_TEST;
+
+  return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText);
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextUsbWwid (
+  IN CHAR16 *TextDeviceNode
+  )
+{
+  CHAR16                *VIDStr;
+  CHAR16                *PIDStr;
+  CHAR16                *InterfaceNumStr;
+  USB_WWID_DEVICE_PATH  *UsbWwid;
+
+  VIDStr                    = GetNextParamStr (&TextDeviceNode);
+  PIDStr                    = GetNextParamStr (&TextDeviceNode);
+  InterfaceNumStr           = GetNextParamStr (&TextDeviceNode);
+  UsbWwid                   = (USB_WWID_DEVICE_PATH *) CreateDeviceNode (
+                                                         MESSAGING_DEVICE_PATH,
+                                                         MSG_USB_WWID_DP,
+                                                         sizeof (USB_WWID_DEVICE_PATH)
+                                                         );
+
+  UsbWwid->VendorId         = (UINT16) Xtoi (VIDStr);
+  UsbWwid->ProductId        = (UINT16) Xtoi (PIDStr);
+  UsbWwid->InterfaceNumber  = (UINT16) Xtoi (InterfaceNumStr);
+
+  return (EFI_DEVICE_PATH_PROTOCOL *) UsbWwid;
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextUnit (
+  IN CHAR16 *TextDeviceNode
+  )
+{
+  CHAR16                          *LunStr;
+  DEVICE_LOGICAL_UNIT_DEVICE_PATH *LogicalUnit;
+
+  LunStr      = GetNextParamStr (&TextDeviceNode);
+  LogicalUnit = (DEVICE_LOGICAL_UNIT_DEVICE_PATH *) CreateDeviceNode (
+                                                      MESSAGING_DEVICE_PATH,
+                                                      MSG_DEVICE_LOGICAL_UNIT_DP,
+                                                      sizeof (DEVICE_LOGICAL_UNIT_DEVICE_PATH)
+                                                      );
+
+  LogicalUnit->Lun  = (UINT8) Xtoi (LunStr);
+
+  return (EFI_DEVICE_PATH_PROTOCOL *) LogicalUnit;
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextiSCSI (
+  IN CHAR16 *TextDeviceNode
+  )
+{
+  UINT16                      Options;
+  CHAR16                      *NameStr;
+  CHAR16                      *PortalGroupStr;
+  CHAR16                      *LunStr;
+  CHAR16                      *HeaderDigestStr;
+  CHAR16                      *DataDigestStr;
+  CHAR16                      *AuthenticationStr;
+  CHAR16                      *ProtocolStr;
+  ISCSI_DEVICE_PATH_WITH_NAME *iSCSI;
+
+  NameStr           = GetNextParamStr (&TextDeviceNode);
+  PortalGroupStr    = GetNextParamStr (&TextDeviceNode);
+  LunStr            = GetNextParamStr (&TextDeviceNode);
+  HeaderDigestStr   = GetNextParamStr (&TextDeviceNode);
+  DataDigestStr     = GetNextParamStr (&TextDeviceNode);
+  AuthenticationStr = GetNextParamStr (&TextDeviceNode);
+  ProtocolStr       = GetNextParamStr (&TextDeviceNode);
+  iSCSI             = (ISCSI_DEVICE_PATH_WITH_NAME *) CreateDeviceNode (
+                                                        MESSAGING_DEVICE_PATH,
+                                                        MSG_ISCSI_DP,
+                                                        sizeof (ISCSI_DEVICE_PATH_WITH_NAME) + (UINT16) (StrLen (NameStr) * 2)
+                                                        );
+
+  StrCpy (iSCSI->iSCSITargetName, NameStr);
+  iSCSI->TargetPortalGroupTag = (UINT16) Xtoi (PortalGroupStr);
+  Xtoi64 (LunStr, &iSCSI->Lun);
+
+  Options = 0x0000;
+  if (StrCmp (HeaderDigestStr, L"CRC32C") == 0) {
+    Options |= 0x0002;
+  }
+
+  if (StrCmp (DataDigestStr, L"CRC32C") == 0) {
+    Options |= 0x0008;
+  }
+
+  if (StrCmp (AuthenticationStr, L"None") == 0) {
+    Options |= 0x0800;
+  }
+
+  if (StrCmp (AuthenticationStr, L"CHAP_UNI") == 0) {
+    Options |= 0x1000;
+  }
+
+  iSCSI->LoginOption      = (UINT16) Options;
+
+  iSCSI->NetworkProtocol  = (UINT16) StrCmp (ProtocolStr, L"TCP");
+  iSCSI->Reserved         = (UINT16) 0;
+
+  return (EFI_DEVICE_PATH_PROTOCOL *) iSCSI;
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextHD (
+  IN CHAR16 *TextDeviceNode
+  )
+{
+  CHAR16                *PartitionStr;
+  CHAR16                *TypeStr;
+  CHAR16                *SignatureStr;
+  CHAR16                *StartStr;
+  CHAR16                *SizeStr;
+  UINT32                Signature32;
+  EFI_GUID              SignatureGuid;
+  HARDDRIVE_DEVICE_PATH *Hd;
+
+  PartitionStr        = GetNextParamStr (&TextDeviceNode);
+  TypeStr             = GetNextParamStr (&TextDeviceNode);
+  SignatureStr        = GetNextParamStr (&TextDeviceNode);
+  StartStr            = GetNextParamStr (&TextDeviceNode);
+  SizeStr             = GetNextParamStr (&TextDeviceNode);
+  Hd                  = (HARDDRIVE_DEVICE_PATH *) CreateDeviceNode (
+                                                    MEDIA_DEVICE_PATH,
+                                                    MEDIA_HARDDRIVE_DP,
+                                                    sizeof (HARDDRIVE_DEVICE_PATH)
+                                                    );
+
+  Hd->PartitionNumber = (UINT32) Atoi (PartitionStr);
+
+  ZeroMem (Hd->Signature, 16);
+  Hd->MBRType = (UINT8) 0;
+
+  if (StrCmp (TypeStr, L"None") == 0) {
+    Hd->SignatureType = (UINT8) 0;
+  } else if (StrCmp (TypeStr, L"MBR") == 0) {
+    Hd->SignatureType = SIGNATURE_TYPE_MBR;
+    Hd->MBRType       = 0x01;
+
+    Signature32       = (UINT32) Xtoi (SignatureStr);
+    CopyMem (Hd->Signature, &Signature32, sizeof (UINT32));
+  } else if (StrCmp (TypeStr, L"GUID") == 0) {
+    Hd->SignatureType = SIGNATURE_TYPE_GUID;
+    Hd->MBRType       = 0x02;
+
+    StrToGuid (SignatureStr, &SignatureGuid);
+    CopyMem (Hd->Signature, &SignatureGuid, sizeof (EFI_GUID));
+  } else {
+    Hd->SignatureType = 0xff;
+
+  }
+
+  Xtoi64 (StartStr, &Hd->PartitionStart);
+  Xtoi64 (SizeStr, &Hd->PartitionSize);
+
+  return (EFI_DEVICE_PATH_PROTOCOL *) Hd;
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextCDROM (
+  IN CHAR16 *TextDeviceNode
+  )
+{
+  CHAR16            *EntryStr;
+  CHAR16            *StartStr;
+  CHAR16            *SizeStr;
+  CDROM_DEVICE_PATH *CDROM;
+
+  EntryStr              = GetNextParamStr (&TextDeviceNode);
+  StartStr              = GetNextParamStr (&TextDeviceNode);
+  SizeStr               = GetNextParamStr (&TextDeviceNode);
+  CDROM                 = (CDROM_DEVICE_PATH *) CreateDeviceNode (
+                                                  MEDIA_DEVICE_PATH,
+                                                  MEDIA_CDROM_DP,
+                                                  sizeof (CDROM_DEVICE_PATH)
+                                                  );
+
+  CDROM->BootEntry      = (UINT32) Xtoi (EntryStr);
+  Xtoi64 (StartStr, &CDROM->PartitionStart);
+  Xtoi64 (SizeStr, &CDROM->PartitionSize);
+
+  return (EFI_DEVICE_PATH_PROTOCOL *) CDROM;
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextVenMEDIA (
+  IN CHAR16 *TextDeviceNode
+  )
+{
+  return ConvertFromTextVendor (
+           TextDeviceNode,
+           MEDIA_DEVICE_PATH,
+           MEDIA_VENDOR_DP
+           );
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextFilePath (
+  IN CHAR16 *TextDeviceNode
+  )
+{
+  FILEPATH_DEVICE_PATH  *File;
+
+  File = (FILEPATH_DEVICE_PATH *) CreateDeviceNode (
+                                    MEDIA_DEVICE_PATH,
+                                    MEDIA_FILEPATH_DP,
+                                    sizeof (FILEPATH_DEVICE_PATH) + (UINT16) (StrLen (TextDeviceNode) * 2)
+                                    );
+
+  StrCpy (File->PathName, TextDeviceNode);
+
+  return (EFI_DEVICE_PATH_PROTOCOL *) File;
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextMedia (
+  IN CHAR16 *TextDeviceNode
+  )
+{
+  CHAR16                      *GuidStr;
+  MEDIA_PROTOCOL_DEVICE_PATH  *Media;
+
+  GuidStr = GetNextParamStr (&TextDeviceNode);
+  Media   = (MEDIA_PROTOCOL_DEVICE_PATH *) CreateDeviceNode (
+                                             MEDIA_DEVICE_PATH,
+                                             MEDIA_PROTOCOL_DP,
+                                             sizeof (MEDIA_PROTOCOL_DEVICE_PATH)
+                                             );
+
+  StrToGuid (GuidStr, &Media->Protocol);
+
+  return (EFI_DEVICE_PATH_PROTOCOL *) Media;
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextBBS (
+  IN CHAR16 *TextDeviceNode
+  )
+{
+  CHAR16              *TypeStr;
+  CHAR16              *IdStr;
+  CHAR16              *FlagsStr;
+  UINT8               *AsciiStr;
+  BBS_BBS_DEVICE_PATH *Bbs;
+
+  TypeStr   = GetNextParamStr (&TextDeviceNode);
+  IdStr     = GetNextParamStr (&TextDeviceNode);
+  FlagsStr  = GetNextParamStr (&TextDeviceNode);
+  Bbs       = (BBS_BBS_DEVICE_PATH *) CreateDeviceNode (
+                                        BBS_DEVICE_PATH,
+                                        BBS_BBS_DP,
+                                        sizeof (BBS_BBS_DEVICE_PATH) + (UINT16) (StrLen (IdStr))
+                                        );
+
+  if (StrCmp (TypeStr, L"Floppy") == 0) {
+    Bbs->DeviceType = BBS_TYPE_FLOPPY;
+  } else if (StrCmp (TypeStr, L"HD") == 0) {
+    Bbs->DeviceType = BBS_TYPE_HARDDRIVE;
+  } else if (StrCmp (TypeStr, L"CDROM") == 0) {
+    Bbs->DeviceType = BBS_TYPE_CDROM;
+  } else if (StrCmp (TypeStr, L"PCMCIA") == 0) {
+    Bbs->DeviceType = BBS_TYPE_PCMCIA;
+  } else if (StrCmp (TypeStr, L"USB") == 0) {
+    Bbs->DeviceType = BBS_TYPE_USB;
+  } else if (StrCmp (TypeStr, L"Network") == 0) {
+    Bbs->DeviceType = BBS_TYPE_EMBEDDED_NETWORK;
+  } else {
+    Bbs->DeviceType = BBS_TYPE_UNKNOWN;
+  }
+
+  AsciiStr = Bbs->String;
+  StrToAscii (IdStr, &AsciiStr);
+
+  Bbs->StatusFlag = (UINT16) Xtoi (FlagsStr);
+
+  return (EFI_DEVICE_PATH_PROTOCOL *) Bbs;
+}
+
+DEVICE_PATH_FROM_TEXT_TABLE DevPathFromTextTable[] = {
+  L"Pci",
+  DevPathFromTextPci,
+  L"PcCard",
+  DevPathFromTextPcCard,
+  L"MemoryMapped",
+  DevPathFromTextMemoryMapped,
+  L"VenHw",
+  DevPathFromTextVenHw,
+  L"Ctrl",
+  DevPathFromTextCtrl,
+  L"Acpi",
+  DevPathFromTextAcpi,
+  L"PciRoot",
+  DevPathFromTextPciRoot,
+  L"Floppy",
+  DevPathFromTextFloppy,
+  L"Keyboard",
+  DevPathFromTextKeyboard,
+  L"Serial",
+  DevPathFromTextSerial,
+  L"ParallelPort",
+  DevPathFromTextParallelPort,
+  L"AcpiEx",
+  DevPathFromTextAcpiEx,
+  L"AcpiExp",
+  DevPathFromTextAcpiExp,
+  L"Ata",
+  DevPathFromTextAta,
+  L"Scsi",
+  DevPathFromTextScsi,
+  L"Fibre",
+  DevPathFromTextFibre,
+  L"I1394",
+  DevPathFromText1394,
+  L"USB",
+  DevPathFromTextUsb,
+  L"I2O",
+  DevPathFromTextI2O,
+  L"Infiniband",
+  DevPathFromTextInfiniband,
+  L"VenMsg",
+  DevPathFromTextVenMsg,
+  L"VenPcAnsi",
+  DevPathFromTextVenPcAnsi,
+  L"VenVt100",
+  DevPathFromTextVenVt100,
+  L"VenVt100Plus",
+  DevPathFromTextVenVt100Plus,
+  L"VenUtf8",
+  DevPathFromTextVenUtf8,
+  L"UartFlowCtrl",
+  DevPathFromTextUartFlowCtrl,
+  L"SAS",
+  DevPathFromTextSAS,
+  L"DebugPort",
+  DevPathFromTextDebugPort,
+  L"MAC",
+  DevPathFromTextMAC,
+  L"IPv4",
+  DevPathFromTextIPv4,
+  L"IPv6",
+  DevPathFromTextIPv6,
+  L"Uart",
+  DevPathFromTextUart,
+  L"UsbClass",
+  DevPathFromTextUsbClass,
+  L"UsbAudio",
+  DevPathFromTextUsbAudio,
+  L"UsbCDCControl",
+  DevPathFromTextUsbCDCControl,
+  L"UsbHID",
+  DevPathFromTextUsbHID,
+  L"UsbImage",
+  DevPathFromTextUsbImage,
+  L"UsbPrinter",
+  DevPathFromTextUsbPrinter,
+  L"UsbMassStorage",
+  DevPathFromTextUsbMassStorage,
+  L"UsbHub",
+  DevPathFromTextUsbHub,
+  L"UsbCDCData",
+  DevPathFromTextUsbCDCData,
+  L"UsbSmartCard",
+  DevPathFromTextUsbSmartCard,
+  L"UsbVideo",
+  DevPathFromTextUsbVideo,
+  L"UsbDiagnostic",
+  DevPathFromTextUsbDiagnostic,
+  L"UsbWireless",
+  DevPathFromTextUsbWireless,
+  L"UsbDeviceFirmwareUpdate",
+  DevPathFromTextUsbDeviceFirmwareUpdate,
+  L"UsbIrdaBridge",
+  DevPathFromTextUsbIrdaBridge,
+  L"UsbTestAndMeasurement",
+  DevPathFromTextUsbTestAndMeasurement,
+  L"UsbWwid",
+  DevPathFromTextUsbWwid,
+  L"Unit",
+  DevPathFromTextUnit,
+  L"iSCSI",
+  DevPathFromTextiSCSI,
+  L"HD",
+  DevPathFromTextHD,
+  L"CDROM",
+  DevPathFromTextCDROM,
+  L"VenMEDIA",
+  DevPathFromTextVenMEDIA,
+  L"Media",
+  DevPathFromTextMedia,
+  L"BBS",
+  DevPathFromTextBBS,
+  NULL,
+  NULL
+};
+
+EFI_DEVICE_PATH_PROTOCOL *
+ConvertTextToDeviceNode (
+  IN CONST CHAR16 *TextDeviceNode
+  )
+/*++
+
+  Routine Description:
+    Convert text to the binary representation of a device node.
+
+  Arguments:
+    TextDeviceNode   -   TextDeviceNode points to the text representation of a device
+                         node. Conversion starts with the first character and continues
+                         until the first non-device node character.
+
+  Returns:
+    A pointer        -   Pointer to the EFI device node.
+    NULL             -   If TextDeviceNode is NULL or there was insufficient memory or text unsupported.
+
+--*/
+{
+  EFI_DEVICE_PATH_PROTOCOL * (*DumpNode) (CHAR16 *);
+  CHAR16                   *ParamStr;
+  EFI_DEVICE_PATH_PROTOCOL *DeviceNode;
+  CHAR16                   *DeviceNodeStr;
+  UINTN                    Index;
+
+  if ((TextDeviceNode == NULL) || (IS_NULL (*TextDeviceNode))) {
+    return NULL;
+  }
+
+  ParamStr      = NULL;
+  DumpNode      = NULL;
+  DeviceNodeStr = StrDuplicate (TextDeviceNode);
+
+  for (Index = 0; DevPathFromTextTable[Index].Function; Index++) {
+    ParamStr = GetParamByNodeName (DeviceNodeStr, DevPathFromTextTable[Index].DevicePathNodeText);
+    if (ParamStr != NULL) {
+      DumpNode = DevPathFromTextTable[Index].Function;
+      break;
+    }
+  }
+
+  if (DumpNode == NULL) {
+    //
+    // A file path
+    //
+    DumpNode = DevPathFromTextFilePath;
+    DeviceNode = DumpNode (DeviceNodeStr);
+  } else {
+    DeviceNode = DumpNode (ParamStr);
+    gBS->FreePool (ParamStr);
+  }
+
+  gBS->FreePool (DeviceNodeStr);
+
+  return DeviceNode;
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+ConvertTextToDevicePath (
+  IN CONST CHAR16 *TextDevicePath
+  )
+/*++
+
+  Routine Description:
+    Convert text to the binary representation of a device path.
+
+  Arguments:
+    TextDevicePath   -   TextDevicePath points to the text representation of a device
+                         path. Conversion starts with the first character and continues
+                         until the first non-device node character.
+
+  Returns:
+    A pointer        -   Pointer to the allocated device path.
+    NULL             -   If TextDeviceNode is NULL or there was insufficient memory.
+
+--*/
+{
+  EFI_DEVICE_PATH_PROTOCOL * (*DumpNode) (CHAR16 *);
+  CHAR16                   *ParamStr;
+  EFI_DEVICE_PATH_PROTOCOL *DeviceNode;
+  UINTN                    Index;
+  EFI_DEVICE_PATH_PROTOCOL *NewDevicePath;
+  CHAR16                   *DevicePathStr;
+  CHAR16                   *Str;
+  CHAR16                   *DeviceNodeStr;
+  UINT8                    IsInstanceEnd;
+  EFI_DEVICE_PATH_PROTOCOL *DevicePath;
+
+  if ((TextDevicePath == NULL) || (IS_NULL (*TextDevicePath))) {
+    return NULL;
+  }
+
+  DevicePath = (EFI_DEVICE_PATH_PROTOCOL *) AllocatePool (END_DEVICE_PATH_LENGTH);
+  SetDevicePathEndNode (DevicePath);
+
+  ParamStr            = NULL;
+  DeviceNodeStr       = NULL;
+  DevicePathStr       = StrDuplicate (TextDevicePath);
+
+  Str                 = DevicePathStr;
+  while ((DeviceNodeStr = GetNextDeviceNodeStr (&Str, &IsInstanceEnd)) != NULL) {
+    DumpNode = NULL;
+    for (Index = 0; DevPathFromTextTable[Index].Function; Index++) {
+      ParamStr = GetParamByNodeName (DeviceNodeStr, DevPathFromTextTable[Index].DevicePathNodeText);
+      if (ParamStr != NULL) {
+        DumpNode = DevPathFromTextTable[Index].Function;
+        break;
+      }
+    }
+
+    if (DumpNode == NULL) {
+      //
+      // A file path
+      //
+      DumpNode  = DevPathFromTextFilePath;
+      DeviceNode = DumpNode (DeviceNodeStr);
+    } else {
+      DeviceNode = DumpNode (ParamStr);
+      gBS->FreePool (ParamStr);
+    }
+
+    NewDevicePath = AppendDeviceNode (DevicePath, DeviceNode);
+    gBS->FreePool (DevicePath);
+    gBS->FreePool (DeviceNode);
+    DevicePath = NewDevicePath;
+
+    if (IsInstanceEnd) {
+      DeviceNode = (EFI_DEVICE_PATH_PROTOCOL *) AllocatePool (END_DEVICE_PATH_LENGTH);
+      SetDevicePathInstanceEndNode (DeviceNode);
+
+      NewDevicePath = AppendDeviceNode (DevicePath, DeviceNode);
+      gBS->FreePool (DevicePath);
+      gBS->FreePool (DeviceNode);
+      DevicePath = NewDevicePath;
+    }
+  }
+
+  gBS->FreePool (DevicePathStr);
+  return DevicePath;
+}
diff --git a/EdkModulePkg/Universal/DevicePath/Dxe/DevicePathToText.c b/EdkModulePkg/Universal/DevicePath/Dxe/DevicePathToText.c
new file mode 100644 (file)
index 0000000..64fd565
--- /dev/null
@@ -0,0 +1,1526 @@
+/*++\r
+\r
+Copyright (c) 2006, Intel Corporation                                                         \r
+All rights reserved. This program and the accompanying materials                          \r
+are licensed and made available under the terms and conditions of the BSD License         \r
+which accompanies this distribution.  The full text of the license may be found at        \r
+http://opensource.org/licenses/bsd-license.php                                            \r
+                                                                                          \r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     \r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             \r
+\r
+Module Name:\r
+\r
+  DevicePathToText.c\r
+\r
+Abstract:\r
+\r
+  DevicePathToText protocol as defined in the UEFI 2.0 specification.\r
+\r
+--*/\r
+\r
+#include <protocol/DevicePathToText.h>\r
+#include "DevicePath.h"\r
+\r
+EFI_DEVICE_PATH_PROTOCOL *\r
+UnpackDevicePath (\r
+  IN EFI_DEVICE_PATH_PROTOCOL  *DevPath\r
+  )\r
+/*++\r
+\r
+  Routine Description:\r
+    Function unpacks a device path data structure so that all the nodes of a device path \r
+    are naturally aligned.\r
+\r
+  Arguments:\r
+    DevPath        - A pointer to a device path data structure\r
+\r
+  Returns:\r
+    If the memory for the device path is successfully allocated, then a pointer to the \r
+    new device path is returned.  Otherwise, NULL is returned.\r
+\r
+--*/\r
+{\r
+  EFI_DEVICE_PATH_PROTOCOL  *Src;\r
+  EFI_DEVICE_PATH_PROTOCOL  *Dest;\r
+  EFI_DEVICE_PATH_PROTOCOL  *NewPath;\r
+  UINTN                     Size;\r
+\r
+  if (DevPath == NULL) {\r
+    return NULL;\r
+  }\r
+  //\r
+  // Walk device path and round sizes to valid boundries\r
+  //\r
+  Src   = DevPath;\r
+  Size  = 0;\r
+  for (;;) {\r
+    Size += DevicePathNodeLength (Src);\r
+    Size += ALIGN_SIZE (Size);\r
+\r
+    if (IsDevicePathEnd (Src)) {\r
+      break;\r
+    }\r
+\r
+    Src = (EFI_DEVICE_PATH_PROTOCOL *) NextDevicePathNode (Src);\r
+  }\r
+  //\r
+  // Allocate space for the unpacked path\r
+  //\r
+  NewPath = AllocateZeroPool (Size);\r
+  if (NewPath != NULL) {\r
+\r
+    ASSERT (((UINTN) NewPath) % MIN_ALIGNMENT_SIZE == 0);\r
+\r
+    //\r
+    // Copy each node\r
+    //\r
+    Src   = DevPath;\r
+    Dest  = NewPath;\r
+    for (;;) {\r
+      Size = DevicePathNodeLength (Src);\r
+      CopyMem (Dest, Src, Size);\r
+      Size += ALIGN_SIZE (Size);\r
+      SetDevicePathNodeLength (Dest, Size);\r
+      Dest->Type |= EFI_DP_TYPE_UNPACKED;\r
+      Dest = (EFI_DEVICE_PATH_PROTOCOL *) (((UINT8 *) Dest) + Size);\r
+\r
+      if (IsDevicePathEnd (Src)) {\r
+        break;\r
+      }\r
+\r
+      Src = (EFI_DEVICE_PATH_PROTOCOL *) NextDevicePathNode (Src);\r
+    }\r
+  }\r
+\r
+  return NewPath;\r
+}\r
+\r
+VOID *\r
+ReallocatePool (\r
+  IN VOID                 *OldPool,\r
+  IN UINTN                OldSize,\r
+  IN UINTN                NewSize\r
+  )\r
+/*++\r
+\r
+  Routine Description:\r
+    Adjusts the size of a previously allocated buffer.\r
+\r
+  Arguments:\r
+    OldPool               - A pointer to the buffer whose size is being adjusted.\r
+    OldSize               - The size of the current buffer.\r
+    NewSize               - The size of the new buffer.\r
+\r
+  Returns:\r
+    EFI_SUCEESS           - The requested number of bytes were allocated.\r
+    EFI_OUT_OF_RESOURCES  - The pool requested could not be allocated.\r
+    EFI_INVALID_PARAMETER - The buffer was invalid.\r
+\r
+--*/\r
+{\r
+  VOID  *NewPool;\r
+\r
+  NewPool = NULL;\r
+  if (NewSize) {\r
+    NewPool = AllocateZeroPool (NewSize);\r
+  }\r
+\r
+  if (OldPool) {\r
+    if (NewPool) {\r
+      CopyMem (NewPool, OldPool, OldSize < NewSize ? OldSize : NewSize);\r
+    }\r
+\r
+    gBS->FreePool (OldPool);\r
+  }\r
+\r
+  return NewPool;\r
+}\r
+\r
+CHAR16 *\r
+CatPrint (\r
+  IN OUT POOL_PRINT   *Str,\r
+  IN CHAR16           *Fmt,\r
+  ...\r
+  )\r
+/*++\r
+\r
+  Routine Description:\r
+    Concatenates a formatted unicode string to allocated pool.  \r
+    The caller must free the resulting buffer.\r
+\r
+  Arguments:\r
+    Str         - Tracks the allocated pool, size in use, and \r
+                  amount of pool allocated.\r
+    Fmt         - The format string\r
+\r
+  Returns:\r
+    Allocated buffer with the formatted string printed in it.  \r
+    The caller must free the allocated buffer.   The buffer\r
+    allocation is not packed.\r
+\r
+--*/\r
+{\r
+  UINT16  *AppendStr;\r
+  VA_LIST Args;\r
+  UINTN   Size;\r
+\r
+  AppendStr = AllocateZeroPool (0x1000);\r
+  if (AppendStr == NULL) {\r
+    return Str->Str;\r
+  }\r
+\r
+  VA_START (Args, Fmt);\r
+  UnicodeVSPrint (AppendStr, 0x1000, Fmt, Args);\r
+  VA_END (Args);\r
+  if (NULL == Str->Str) {\r
+    Size   = StrSize (AppendStr);\r
+    Str->Str  = AllocateZeroPool (Size);\r
+    ASSERT (Str->Str != NULL);\r
+  } else {\r
+    Size = StrSize (AppendStr) + StrSize (Str->Str) - sizeof (UINT16);\r
+    Str->Str = ReallocatePool (\r
+                Str->Str,\r
+                StrSize (Str->Str),\r
+                Size\r
+                );\r
+    ASSERT (Str->Str != NULL);\r
+  }\r
+\r
+  Str->MaxLen = MAX_CHAR * sizeof (UINT16);\r
+  if (Size < Str->MaxLen) {\r
+    StrCat (Str->Str, AppendStr);\r
+    Str->Len = Size - sizeof (UINT16);\r
+  }\r
+\r
+  gBS->FreePool (AppendStr);\r
+  return Str->Str;\r
+}\r
+\r
+VOID\r
+DevPathToTextPci (\r
+  IN OUT POOL_PRINT  *Str,\r
+  IN VOID            *DevPath,\r
+  IN BOOLEAN         DisplayOnly,\r
+  IN BOOLEAN         AllowShortcuts\r
+  )\r
+{\r
+  PCI_DEVICE_PATH *Pci;\r
+\r
+  Pci = DevPath;\r
+  CatPrint (Str, L"Pci(%x,%x)", Pci->Function, Pci->Device);\r
+}\r
+\r
+VOID\r
+DevPathToTextPccard (\r
+  IN OUT POOL_PRINT  *Str,\r
+  IN VOID            *DevPath,\r
+  IN BOOLEAN         DisplayOnly,\r
+  IN BOOLEAN         AllowShortcuts\r
+  )\r
+{\r
+  PCCARD_DEVICE_PATH  *Pccard;\r
+\r
+  Pccard = DevPath;\r
+  CatPrint (Str, L"PcCard(%x)", Pccard->FunctionNumber);\r
+}\r
+\r
+VOID\r
+DevPathToTextMemMap (\r
+  IN OUT POOL_PRINT  *Str,\r
+  IN VOID            *DevPath,\r
+  IN BOOLEAN         DisplayOnly,\r
+  IN BOOLEAN         AllowShortcuts\r
+  )\r
+{\r
+  MEMMAP_DEVICE_PATH  *MemMap;\r
+\r
+  MemMap = DevPath;\r
+  CatPrint (\r
+    Str,\r
+    L"MemoryMapped(%lx,%lx)",\r
+    MemMap->StartingAddress,\r
+    MemMap->EndingAddress\r
+    );\r
+}\r
+\r
+VOID\r
+DevPathToTextVendor (\r
+  IN OUT POOL_PRINT  *Str,\r
+  IN VOID            *DevPath,\r
+  IN BOOLEAN         DisplayOnly,\r
+  IN BOOLEAN         AllowShortcuts\r
+  )\r
+{\r
+  VENDOR_DEVICE_PATH  *Vendor;\r
+  CHAR16              *Type;\r
+  UINTN               Index;\r
+  UINT32              FlowControlMap;\r
+  UINT16              Info;\r
+\r
+  Vendor = (VENDOR_DEVICE_PATH *) DevPath;\r
+  switch (DevicePathType (&Vendor->Header)) {\r
+  case HARDWARE_DEVICE_PATH:\r
+    Type = L"Hw";\r
+    break;\r
+\r
+  case MESSAGING_DEVICE_PATH:\r
+    Type = L"Msg";\r
+    if (AllowShortcuts) {\r
+      if (CompareGuid (&Vendor->Guid, &gEfiPcAnsiGuid)) {\r
+        CatPrint (Str, L"VenPcAnsi()");\r
+        return ;\r
+      } else if (CompareGuid (&Vendor->Guid, &gEfiVT100Guid)) {\r
+        CatPrint (Str, L"VenVt100()");\r
+        return ;\r
+      } else if (CompareGuid (&Vendor->Guid, &gEfiVT100PlusGuid)) {\r
+        CatPrint (Str, L"VenVt100Plus()");\r
+        return ;\r
+      } else if (CompareGuid (&Vendor->Guid, &gEfiVTUTF8Guid)) {\r
+        CatPrint (Str, L"VenUft8()");\r
+        return ;\r
+      } else if (CompareGuid (&Vendor->Guid, &mEfiDevicePathMessagingUartFlowControlGuid)) {\r
+        FlowControlMap = (((UART_FLOW_CONTROL_DEVICE_PATH *) Vendor)->FlowControlMap);\r
+        switch (FlowControlMap & 0x00000003) {\r
+        case 0:\r
+          CatPrint (Str, L"UartFlowCtrl(%s)", L"None");\r
+          break;\r
+\r
+        case 1:\r
+          CatPrint (Str, L"UartFlowCtrl(%s)", L"Hardware");\r
+          break;\r
+\r
+        case 2:\r
+          CatPrint (Str, L"UartFlowCtrl(%s)", L"XonXoff");\r
+          break;\r
+\r
+        default:\r
+          break;\r
+        }\r
+\r
+        return ;\r
+      } else if (CompareGuid (&Vendor->Guid, &mEfiDevicePathMessagingSASGuid)) {\r
+        CatPrint (\r
+          Str,\r
+          L"SAS(%lx,%lx,%x,",\r
+          ((SAS_DEVICE_PATH *) Vendor)->SasAddress,\r
+          ((SAS_DEVICE_PATH *) Vendor)->Lun,\r
+          ((SAS_DEVICE_PATH *) Vendor)->RelativeTargetPort\r
+          );\r
+        Info = (((SAS_DEVICE_PATH *) Vendor)->DeviceTopology);\r
+        if ((Info & 0x0f) == 0) {\r
+          CatPrint (Str, L"NoTopology,0,0,0,");\r
+        } else if (((Info & 0x0f) == 1) || ((Info & 0x0f) == 2)) {\r
+          CatPrint (\r
+            Str,\r
+            L"%s,%s,%s,",\r
+            (Info & (0x1 << 4)) ? L"SATA" : L"SAS",\r
+            (Info & (0x1 << 5)) ? L"External" : L"Internal",\r
+            (Info & (0x1 << 6)) ? L"Expanded" : L"Direct"\r
+            );\r
+          if ((Info & 0x0f) == 1) {\r
+            CatPrint (Str, L"0,");\r
+          } else {\r
+            CatPrint (Str, L"%x,", (Info >> 8) & 0xff);\r
+          }\r
+        } else {\r
+          CatPrint (Str, L"0,0,0,0,");\r
+        }\r
+\r
+        CatPrint (Str, L"%x)", ((SAS_DEVICE_PATH *) Vendor)->Reserved);\r
+        return ;\r
+      } else if (CompareGuid (&Vendor->Guid, &gEfiDebugPortProtocolGuid)) {\r
+        CatPrint (Str, L"DebugPort()");\r
+        return ;\r
+      } else {\r
+        return ;\r
+        //\r
+        // reserved\r
+        //\r
+      }\r
+    }\r
+    break;\r
+\r
+  case MEDIA_DEVICE_PATH:\r
+    Type = L"Media";\r
+    break;\r
+\r
+  default:\r
+    Type = L"?";\r
+    break;\r
+  }\r
+\r
+  CatPrint (Str, L"Ven%s(%g,", Type, &Vendor->Guid);\r
+  for (Index = 0; Index < DevicePathNodeLength (&Vendor->Header) - sizeof (VENDOR_DEVICE_PATH); Index++) {\r
+    CatPrint (Str, L"%02x", ((VENDOR_DEVICE_PATH_WITH_DATA *) Vendor)->VendorDefinedData[Index]);\r
+  }\r
+\r
+  CatPrint (Str, L")");\r
+}\r
+\r
+VOID\r
+DevPathToTextController (\r
+  IN OUT POOL_PRINT  *Str,\r
+  IN VOID            *DevPath,\r
+  IN BOOLEAN         DisplayOnly,\r
+  IN BOOLEAN         AllowShortcuts\r
+  )\r
+{\r
+  CONTROLLER_DEVICE_PATH  *Controller;\r
+\r
+  Controller = DevPath;\r
+  CatPrint (\r
+    Str,\r
+    L"Ctrl(%x)",\r
+    (UINT16 *)Controller->ControllerNumber\r
+    );\r
+}\r
+\r
+VOID\r
+DevPathToTextAcpi (\r
+  IN OUT POOL_PRINT  *Str,\r
+  IN VOID            *DevPath,\r
+  IN BOOLEAN         DisplayOnly,\r
+  IN BOOLEAN         AllowShortcuts\r
+  )\r
+{\r
+  ACPI_HID_DEVICE_PATH  *Acpi;\r
+\r
+  Acpi = DevPath;\r
+  if ((Acpi->HID & PNP_EISA_ID_MASK) == PNP_EISA_ID_CONST) {\r
+    if (AllowShortcuts) {\r
+      switch (EISA_ID_TO_NUM (Acpi->HID)) {\r
+      case 0x0a03:\r
+        CatPrint (Str, L"PciRoot(%x)", Acpi->UID);\r
+        break;\r
+\r
+      case 0x0604:\r
+        CatPrint (Str, L"Floppy(%x)", Acpi->UID);\r
+        break;\r
+\r
+      case 0x0301:\r
+        CatPrint (Str, L"Keyboard(%x)", Acpi->UID);\r
+        break;\r
+\r
+      case 0x0501:\r
+        CatPrint (Str, L"Serial(%x)", Acpi->UID);\r
+        break;\r
+\r
+      case 0x0401:\r
+        CatPrint (Str, L"ParallelPort(%x)", Acpi->UID);\r
+        break;\r
+\r
+      default:\r
+        break;\r
+      }\r
+\r
+      return ;\r
+    }\r
+\r
+    CatPrint (Str, L"Acpi(PNP%04x,%x)", EISA_ID_TO_NUM (Acpi->HID), Acpi->UID);\r
+  } else {\r
+    CatPrint (Str, L"Acpi(%08x,%x)", Acpi->HID, Acpi->UID);\r
+  }\r
+}\r
+\r
+#define NextStrA(a) ((UINT8 *) (((UINT8 *) (a)) + AsciiStrLen (a) + 1))\r
+\r
+VOID\r
+DevPathToTextExtAcpi (\r
+  IN OUT POOL_PRINT  *Str,\r
+  IN VOID            *DevPath,\r
+  IN BOOLEAN         DisplayOnly,\r
+  IN BOOLEAN         AllowShortcuts\r
+  )\r
+{\r
+  ACPI_EXTENDED_HID_DEVICE_PATH_WITH_STR  *AcpiExt;\r
+\r
+  AcpiExt = DevPath;\r
+\r
+  if (AllowShortcuts) {\r
+    if ((*(AcpiExt->HidUidCidStr) == '\0') &&\r
+        (*(NextStrA (NextStrA (AcpiExt->HidUidCidStr))) == '\0') &&\r
+        (AcpiExt->UID == 0)\r
+        ) {\r
+      if ((AcpiExt->HID & PNP_EISA_ID_MASK) == PNP_EISA_ID_CONST) {\r
+        CatPrint (\r
+          Str,\r
+          L"AcpiExp(PNP%04x,%x,%a)",\r
+          EISA_ID_TO_NUM (AcpiExt->HID),\r
+          AcpiExt->CID,\r
+          NextStrA (AcpiExt->HidUidCidStr)\r
+          );\r
+      } else {\r
+        CatPrint (\r
+          Str,\r
+          L"AcpiExp(%08x,%x,%a)",\r
+          AcpiExt->HID,\r
+          AcpiExt->CID,\r
+          NextStrA (AcpiExt->HidUidCidStr)\r
+          );\r
+      }\r
+    }\r
+    return ;\r
+  }\r
+\r
+  if ((AcpiExt->HID & PNP_EISA_ID_MASK) == PNP_EISA_ID_CONST) {\r
+    CatPrint (\r
+      Str,\r
+      L"AcpiEx(PNP%04x,%x,%x,%a,%a,%a)",\r
+      EISA_ID_TO_NUM (AcpiExt->HID),\r
+      AcpiExt->CID,\r
+      AcpiExt->UID,\r
+      AcpiExt->HidUidCidStr,\r
+      NextStrA (NextStrA (AcpiExt->HidUidCidStr)),\r
+      NextStrA (AcpiExt->HidUidCidStr)\r
+      );\r
+  } else {\r
+    CatPrint (\r
+      Str,\r
+      L"AcpiEx(%08x,%x,%x,%a,%a,%a)",\r
+      AcpiExt->HID,\r
+      AcpiExt->CID,\r
+      AcpiExt->UID,\r
+      AcpiExt->HidUidCidStr,\r
+      NextStrA (NextStrA (AcpiExt->HidUidCidStr)),\r
+      NextStrA (AcpiExt->HidUidCidStr)\r
+      );\r
+  }\r
+}\r
+\r
+VOID\r
+DevPathToTextAtapi (\r
+  IN OUT POOL_PRINT  *Str,\r
+  IN VOID            *DevPath,\r
+  IN BOOLEAN         DisplayOnly,\r
+  IN BOOLEAN         AllowShortcuts\r
+  )\r
+{\r
+  ATAPI_DEVICE_PATH *Atapi;\r
+\r
+  Atapi = DevPath;\r
+\r
+  if (DisplayOnly) {\r
+    CatPrint (Str, L"Ata(%x)", Atapi->Lun);\r
+  } else {\r
+    CatPrint (\r
+      Str,\r
+      L"Ata(%s,%s,%x)",\r
+      Atapi->PrimarySecondary ? L"Secondary" : L"Primary",\r
+      Atapi->SlaveMaster ? L"Slave" : L"Master",\r
+      Atapi->Lun\r
+      );\r
+  }\r
+}\r
+\r
+VOID\r
+DevPathToTextScsi (\r
+  IN OUT POOL_PRINT  *Str,\r
+  IN VOID            *DevPath,\r
+  IN BOOLEAN         DisplayOnly,\r
+  IN BOOLEAN         AllowShortcuts\r
+  )\r
+{\r
+  SCSI_DEVICE_PATH  *Scsi;\r
+\r
+  Scsi = DevPath;\r
+  CatPrint (Str, L"Scsi(%x,%x)", Scsi->Pun, Scsi->Lun);\r
+}\r
+\r
+VOID\r
+DevPathToTextFibre (\r
+  IN OUT POOL_PRINT  *Str,\r
+  IN VOID            *DevPath,\r
+  IN BOOLEAN         DisplayOnly,\r
+  IN BOOLEAN         AllowShortcuts\r
+  )\r
+{\r
+  FIBRECHANNEL_DEVICE_PATH  *Fibre;\r
+\r
+  Fibre = DevPath;\r
+  CatPrint (Str, L"Fibre(%lx,%lx)", Fibre->WWN, Fibre->Lun);\r
+}\r
+\r
+VOID\r
+DevPathToText1394 (\r
+  IN OUT POOL_PRINT  *Str,\r
+  IN VOID            *DevPath,\r
+  IN BOOLEAN         DisplayOnly,\r
+  IN BOOLEAN         AllowShortcuts\r
+  )\r
+{\r
+  F1394_DEVICE_PATH *F1394;\r
+\r
+  F1394 = DevPath;\r
+  CatPrint (Str, L"I1394(%lx)", F1394->Guid);\r
+}\r
+\r
+VOID\r
+DevPathToTextUsb (\r
+  IN OUT POOL_PRINT  *Str,\r
+  IN VOID            *DevPath,\r
+  IN BOOLEAN         DisplayOnly,\r
+  IN BOOLEAN         AllowShortcuts\r
+  )\r
+{\r
+  USB_DEVICE_PATH *Usb;\r
+\r
+  Usb = DevPath;\r
+  CatPrint (Str, L"USB(%x,%x)", Usb->ParentPortNumber, Usb->InterfaceNumber);\r
+}\r
+\r
+VOID\r
+DevPathToTextUsbWWID (\r
+  IN OUT POOL_PRINT  *Str,\r
+  IN VOID            *DevPath,\r
+  IN BOOLEAN         DisplayOnly,\r
+  IN BOOLEAN         AllowShortcuts\r
+  )\r
+{\r
+  USB_WWID_DEVICE_PATH  *UsbWWId;\r
+\r
+  UsbWWId = DevPath;\r
+  CatPrint (\r
+    Str,\r
+    L"UsbWwid(%x,%x,%x,\"WWID\")",\r
+    UsbWWId->VendorId,\r
+    UsbWWId->ProductId,\r
+    UsbWWId->InterfaceNumber\r
+    );\r
+}\r
+\r
+VOID\r
+DevPathToTextLogicalUnit (\r
+  IN OUT POOL_PRINT  *Str,\r
+  IN VOID            *DevPath,\r
+  IN BOOLEAN         DisplayOnly,\r
+  IN BOOLEAN         AllowShortcuts\r
+  )\r
+{\r
+  DEVICE_LOGICAL_UNIT_DEVICE_PATH *LogicalUnit;\r
+\r
+  LogicalUnit = DevPath;\r
+  CatPrint (Str, L"Unit(%x)", LogicalUnit->Lun);\r
+}\r
+\r
+VOID\r
+DevPathToTextUsbClass (\r
+  IN OUT POOL_PRINT  *Str,\r
+  IN VOID            *DevPath,\r
+  IN BOOLEAN         DisplayOnly,\r
+  IN BOOLEAN         AllowShortcuts\r
+  )\r
+{\r
+  USB_CLASS_DEVICE_PATH *UsbClass;\r
+\r
+  UsbClass = DevPath;\r
+\r
+  if (AllowShortcuts == TRUE) {\r
+    switch (UsbClass->DeviceClass) {\r
+    case 1:\r
+      CatPrint (\r
+        Str,\r
+        L"UsbAudio(%x,%x,%x,%x)",\r
+        UsbClass->VendorId,\r
+        UsbClass->ProductId,\r
+        UsbClass->DeviceSubClass,\r
+        UsbClass->DeviceProtocol\r
+        );\r
+      break;\r
+\r
+    case 2:\r
+      CatPrint (\r
+        Str,\r
+        L"UsbCDCControl(%x,%x,%x,%x)",\r
+        UsbClass->VendorId,\r
+        UsbClass->ProductId,\r
+        UsbClass->DeviceSubClass,\r
+        UsbClass->DeviceProtocol\r
+        );\r
+      break;\r
+\r
+    case 3:\r
+      CatPrint (\r
+        Str,\r
+        L"UsbHID(%x,%x,%x,%x)",\r
+        UsbClass->VendorId,\r
+        UsbClass->ProductId,\r
+        UsbClass->DeviceSubClass,\r
+        UsbClass->DeviceProtocol\r
+        );\r
+      break;\r
+\r
+    case 6:\r
+      CatPrint (\r
+        Str,\r
+        L"UsbImage(%x,%x,%x,%x)",\r
+        UsbClass->VendorId,\r
+        UsbClass->ProductId,\r
+        UsbClass->DeviceSubClass,\r
+        UsbClass->DeviceProtocol\r
+        );\r
+      break;\r
+\r
+    case 7:\r
+      CatPrint (\r
+        Str,\r
+        L"UsbPrinter(%x,%x,%x,%x)",\r
+        UsbClass->VendorId,\r
+        UsbClass->ProductId,\r
+        UsbClass->DeviceSubClass,\r
+        UsbClass->DeviceProtocol\r
+        );\r
+      break;\r
+\r
+    case 8:\r
+      CatPrint (\r
+        Str,\r
+        L"UsbMassStorage(%x,%x,%x,%x)",\r
+        UsbClass->VendorId,\r
+        UsbClass->ProductId,\r
+        UsbClass->DeviceSubClass,\r
+        UsbClass->DeviceProtocol\r
+        );\r
+      break;\r
+\r
+    case 9:\r
+      CatPrint (\r
+        Str,\r
+        L"UsbHub(%x,%x,%x,%x)",\r
+        UsbClass->VendorId,\r
+        UsbClass->ProductId,\r
+        UsbClass->DeviceSubClass,\r
+        UsbClass->DeviceProtocol\r
+        );\r
+      break;\r
+\r
+    case 10:\r
+      CatPrint (\r
+        Str,\r
+        L"UsbCDCData(%x,%x,%x,%x)",\r
+        UsbClass->VendorId,\r
+        UsbClass->ProductId,\r
+        UsbClass->DeviceSubClass,\r
+        UsbClass->DeviceProtocol\r
+        );\r
+      break;\r
+\r
+    case 11:\r
+      CatPrint (\r
+        Str,\r
+        L"UsbSmartCard(%x,%x,%x,%x)",\r
+        UsbClass->VendorId,\r
+        UsbClass->ProductId,\r
+        UsbClass->DeviceSubClass,\r
+        UsbClass->DeviceProtocol\r
+        );\r
+      break;\r
+\r
+    case 14:\r
+      CatPrint (\r
+        Str,\r
+        L"UsbVideo(%x,%x,%x,%x)",\r
+        UsbClass->VendorId,\r
+        UsbClass->ProductId,\r
+        UsbClass->DeviceSubClass,\r
+        UsbClass->DeviceProtocol\r
+        );\r
+      break;\r
+\r
+    case 220:\r
+      CatPrint (\r
+        Str,\r
+        L"UsbDiagnostic(%x,%x,%x,%x)",\r
+        UsbClass->VendorId,\r
+        UsbClass->ProductId,\r
+        UsbClass->DeviceSubClass,\r
+        UsbClass->DeviceProtocol\r
+        );\r
+      break;\r
+\r
+    case 224:\r
+      CatPrint (\r
+        Str,\r
+        L"UsbWireless(%x,%x,%x,%x)",\r
+        UsbClass->VendorId,\r
+        UsbClass->ProductId,\r
+        UsbClass->DeviceSubClass,\r
+        UsbClass->DeviceProtocol\r
+        );\r
+      break;\r
+\r
+    case 254:\r
+      if (UsbClass->DeviceSubClass == 1) {\r
+        CatPrint (\r
+          Str,\r
+          L"UsbDeviceFirmwareUpdate(%x,%x,%x)",\r
+          UsbClass->VendorId,\r
+          UsbClass->ProductId,\r
+          UsbClass->DeviceProtocol\r
+          );\r
+      } else if (UsbClass->DeviceSubClass == 2) {\r
+        CatPrint (\r
+          Str,\r
+          L"UsbIrdaBridge(%x,%x,%x)",\r
+          UsbClass->VendorId,\r
+          UsbClass->ProductId,\r
+          UsbClass->DeviceProtocol\r
+          );\r
+      } else if (UsbClass->DeviceSubClass == 3) {\r
+        CatPrint (\r
+          Str,\r
+          L"UsbTestAndMeasurement(%x,%x,%x)",\r
+          UsbClass->VendorId,\r
+          UsbClass->ProductId,\r
+          UsbClass->DeviceProtocol\r
+          );\r
+      }\r
+      break;\r
+\r
+    default:\r
+      break;\r
+    }\r
+\r
+    return ;\r
+  }\r
+\r
+  CatPrint (\r
+    Str,\r
+    L"UsbClass(%x,%x,%x,%x,%x)",\r
+    UsbClass->VendorId,\r
+    UsbClass->ProductId,\r
+    UsbClass->DeviceClass,\r
+    UsbClass->DeviceSubClass,\r
+    UsbClass->DeviceProtocol\r
+    );\r
+}\r
+\r
+VOID\r
+DevPathToTextI2O (\r
+  IN OUT POOL_PRINT  *Str,\r
+  IN VOID            *DevPath,\r
+  IN BOOLEAN         DisplayOnly,\r
+  IN BOOLEAN         AllowShortcuts\r
+  )\r
+{\r
+  I2O_DEVICE_PATH *I2O;\r
+\r
+  I2O = DevPath;\r
+  CatPrint (Str, L"I2O(%x)", I2O->Tid);\r
+}\r
+\r
+VOID\r
+DevPathToTextMacAddr (\r
+  IN OUT POOL_PRINT  *Str,\r
+  IN VOID            *DevPath,\r
+  IN BOOLEAN         DisplayOnly,\r
+  IN BOOLEAN         AllowShortcuts\r
+  )\r
+{\r
+  MAC_ADDR_DEVICE_PATH  *MAC;\r
+  UINTN                 HwAddressSize;\r
+  UINTN                 Index;\r
+\r
+  MAC           = DevPath;\r
+\r
+  HwAddressSize = sizeof (EFI_MAC_ADDRESS);\r
+  if (MAC->IfType == 0x01 || MAC->IfType == 0x00) {\r
+    HwAddressSize = 6;\r
+  }\r
+\r
+  CatPrint (Str, L"MAC(");\r
+\r
+  for (Index = 0; Index < HwAddressSize; Index++) {\r
+    CatPrint (Str, L"%02x", MAC->MacAddress.Addr[Index]);\r
+  }\r
+\r
+  CatPrint (Str, L",%x)", MAC->IfType);\r
+}\r
+\r
+VOID\r
+DevPathToTextIPv4 (\r
+  IN OUT POOL_PRINT  *Str,\r
+  IN VOID            *DevPath,\r
+  IN BOOLEAN         DisplayOnly,\r
+  IN BOOLEAN         AllowShortcuts\r
+  )\r
+{\r
+  IPv4_DEVICE_PATH  *IP;\r
+\r
+  IP = DevPath;\r
+  if (DisplayOnly == TRUE) {\r
+    CatPrint (\r
+      Str,\r
+      L"IPv4(%d.%d.%d.%d)",\r
+      IP->RemoteIpAddress.Addr[0],\r
+      IP->RemoteIpAddress.Addr[1],\r
+      IP->RemoteIpAddress.Addr[2],\r
+      IP->RemoteIpAddress.Addr[3]\r
+      );\r
+    return ;\r
+  }\r
+\r
+  CatPrint (\r
+    Str,\r
+    L"IPv4(%d.%d.%d.%d,%s,%s,%d.%d.%d.%d)",\r
+    IP->RemoteIpAddress.Addr[0],\r
+    IP->RemoteIpAddress.Addr[1],\r
+    IP->RemoteIpAddress.Addr[2],\r
+    IP->RemoteIpAddress.Addr[3],\r
+    IP->Protocol ? L"TCP" : L"UDP",\r
+    (IP->StaticIpAddress == TRUE) ? L"Static" : L"DHCP",\r
+    IP->LocalIpAddress.Addr[0],\r
+    IP->LocalIpAddress.Addr[1],\r
+    IP->LocalIpAddress.Addr[2],\r
+    IP->LocalIpAddress.Addr[3]\r
+    );\r
+}\r
+\r
+VOID\r
+DevPathToTextIPv6 (\r
+  IN OUT POOL_PRINT  *Str,\r
+  IN VOID            *DevPath,\r
+  IN BOOLEAN         DisplayOnly,\r
+  IN BOOLEAN         AllowShortcuts\r
+  )\r
+{\r
+  IPv6_DEVICE_PATH  *IP;\r
+\r
+  IP = DevPath;\r
+  if (DisplayOnly == TRUE) {\r
+    CatPrint (\r
+      Str,\r
+      L"IPv6(%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x)",\r
+      IP->RemoteIpAddress.Addr[0],\r
+      IP->RemoteIpAddress.Addr[1],\r
+      IP->RemoteIpAddress.Addr[2],\r
+      IP->RemoteIpAddress.Addr[3],\r
+      IP->RemoteIpAddress.Addr[4],\r
+      IP->RemoteIpAddress.Addr[5],\r
+      IP->RemoteIpAddress.Addr[6],\r
+      IP->RemoteIpAddress.Addr[7],\r
+      IP->RemoteIpAddress.Addr[8],\r
+      IP->RemoteIpAddress.Addr[9],\r
+      IP->RemoteIpAddress.Addr[10],\r
+      IP->RemoteIpAddress.Addr[11],\r
+      IP->RemoteIpAddress.Addr[12],\r
+      IP->RemoteIpAddress.Addr[13],\r
+      IP->RemoteIpAddress.Addr[14],\r
+      IP->RemoteIpAddress.Addr[15]\r
+      );\r
+    return ;\r
+  }\r
+\r
+  CatPrint (\r
+    Str,\r
+    L"IPv6(%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x,%s,%s,%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x)",\r
+    IP->RemoteIpAddress.Addr[0],\r
+    IP->RemoteIpAddress.Addr[1],\r
+    IP->RemoteIpAddress.Addr[2],\r
+    IP->RemoteIpAddress.Addr[3],\r
+    IP->RemoteIpAddress.Addr[4],\r
+    IP->RemoteIpAddress.Addr[5],\r
+    IP->RemoteIpAddress.Addr[6],\r
+    IP->RemoteIpAddress.Addr[7],\r
+    IP->RemoteIpAddress.Addr[8],\r
+    IP->RemoteIpAddress.Addr[9],\r
+    IP->RemoteIpAddress.Addr[10],\r
+    IP->RemoteIpAddress.Addr[11],\r
+    IP->RemoteIpAddress.Addr[12],\r
+    IP->RemoteIpAddress.Addr[13],\r
+    IP->RemoteIpAddress.Addr[14],\r
+    IP->RemoteIpAddress.Addr[15],\r
+    IP->Protocol ? L"TCP" : L"UDP",\r
+    (IP->StaticIpAddress == TRUE) ? L"Static" : L"DHCP",\r
+    IP->LocalIpAddress.Addr[0],\r
+    IP->LocalIpAddress.Addr[1],\r
+    IP->LocalIpAddress.Addr[2],\r
+    IP->LocalIpAddress.Addr[3],\r
+    IP->LocalIpAddress.Addr[4],\r
+    IP->LocalIpAddress.Addr[5],\r
+    IP->LocalIpAddress.Addr[6],\r
+    IP->LocalIpAddress.Addr[7],\r
+    IP->LocalIpAddress.Addr[8],\r
+    IP->LocalIpAddress.Addr[9],\r
+    IP->LocalIpAddress.Addr[10],\r
+    IP->LocalIpAddress.Addr[11],\r
+    IP->LocalIpAddress.Addr[12],\r
+    IP->LocalIpAddress.Addr[13],\r
+    IP->LocalIpAddress.Addr[14],\r
+    IP->LocalIpAddress.Addr[15]\r
+    );\r
+}\r
+\r
+VOID\r
+DevPathToTextInfiniBand (\r
+  IN OUT POOL_PRINT  *Str,\r
+  IN VOID            *DevPath,\r
+  IN BOOLEAN         DisplayOnly,\r
+  IN BOOLEAN         AllowShortcuts\r
+  )\r
+{\r
+  INFINIBAND_DEVICE_PATH  *InfiniBand;\r
+\r
+  InfiniBand = DevPath;\r
+  CatPrint (\r
+    Str,\r
+    L"Infiniband(%x,%g,%lx,%lx,%lx)",\r
+    InfiniBand->ResourceFlags,\r
+    InfiniBand->PortGid,\r
+    InfiniBand->ServiceId,\r
+    InfiniBand->TargetPortId,\r
+    InfiniBand->DeviceId\r
+    );\r
+}\r
+\r
+VOID\r
+DevPathToTextUart (\r
+  IN OUT POOL_PRINT  *Str,\r
+  IN VOID            *DevPath,\r
+  IN BOOLEAN         DisplayOnly,\r
+  IN BOOLEAN         AllowShortcuts\r
+  )\r
+{\r
+  UART_DEVICE_PATH  *Uart;\r
+  CHAR8             Parity;\r
+\r
+  Uart = DevPath;\r
+  switch (Uart->Parity) {\r
+  case 0:\r
+    Parity = 'D';\r
+    break;\r
+\r
+  case 1:\r
+    Parity = 'N';\r
+    break;\r
+\r
+  case 2:\r
+    Parity = 'E';\r
+    break;\r
+\r
+  case 3:\r
+    Parity = 'O';\r
+    break;\r
+\r
+  case 4:\r
+    Parity = 'M';\r
+    break;\r
+\r
+  case 5:\r
+    Parity = 'S';\r
+    break;\r
+\r
+  default:\r
+    Parity = 'x';\r
+    break;\r
+  }\r
+\r
+  if (Uart->BaudRate == 0) {\r
+    CatPrint (Str, L"Uart(DEFAULT,");\r
+  } else {\r
+    CatPrint (Str, L"Uart(%ld,", Uart->BaudRate);\r
+  }\r
+\r
+  if (Uart->DataBits == 0) {\r
+    CatPrint (Str, L"DEFAULT,");\r
+  } else {\r
+    CatPrint (Str, L"%d,", Uart->DataBits);\r
+  }\r
+\r
+  CatPrint (Str, L"%c,", Parity);\r
+\r
+  switch (Uart->StopBits) {\r
+  case 0:\r
+    CatPrint (Str, L"D)");\r
+    break;\r
+\r
+  case 1:\r
+    CatPrint (Str, L"1)");\r
+    break;\r
+\r
+  case 2:\r
+    CatPrint (Str, L"1.5)");\r
+    break;\r
+\r
+  case 3:\r
+    CatPrint (Str, L"2)");\r
+    break;\r
+\r
+  default:\r
+    CatPrint (Str, L"x)");\r
+    break;\r
+  }\r
+}\r
+\r
+VOID\r
+DevPathToTextiSCSI (\r
+  IN OUT POOL_PRINT  *Str,\r
+  IN VOID            *DevPath,\r
+  IN BOOLEAN         DisplayOnly,\r
+  IN BOOLEAN         AllowShortcuts\r
+  )\r
+{\r
+  ISCSI_DEVICE_PATH_WITH_NAME *iSCSI;\r
+  UINT16                      Options;\r
+\r
+  iSCSI = DevPath;\r
+  CatPrint (\r
+    Str,\r
+    L"iSCSI(%s,%x,%lx,",\r
+    iSCSI->iSCSITargetName,\r
+    iSCSI->TargetPortalGroupTag,\r
+    iSCSI->Lun\r
+    );\r
+\r
+  Options = iSCSI->LoginOption;\r
+  CatPrint (Str, L"%s,", ((Options >> 1) & 0x0001) ? L"CRC32C" : L"None");\r
+  CatPrint (Str, L"%s,", ((Options >> 3) & 0x0001) ? L"CRC32C" : L"None");\r
+  if ((Options >> 11) & 0x0001) {\r
+    CatPrint (Str, L"%s,", L"None");\r
+  } else if ((Options >> 12) & 0x0001) {\r
+    CatPrint (Str, L"%s,", L"CHAP_UNI");\r
+  } else {\r
+    CatPrint (Str, L"%s,", L"CHAP_BI");\r
+\r
+  }\r
+\r
+  CatPrint (Str, L"%s)", (iSCSI->NetworkProtocol == 0) ? L"TCP" : L"reserved");\r
+}\r
+\r
+VOID\r
+DevPathToTextHardDrive (\r
+  IN OUT POOL_PRINT  *Str,\r
+  IN VOID            *DevPath,\r
+  IN BOOLEAN         DisplayOnly,\r
+  IN BOOLEAN         AllowShortcuts\r
+  )\r
+{\r
+  HARDDRIVE_DEVICE_PATH *Hd;\r
+\r
+  Hd = DevPath;\r
+  switch (Hd->SignatureType) {\r
+  case 0:\r
+    CatPrint (\r
+      Str,\r
+      L"HD(%d,%s,0,",\r
+      Hd->PartitionNumber,\r
+      L"None"\r
+      );\r
+    break;\r
+\r
+  case SIGNATURE_TYPE_MBR:\r
+    CatPrint (\r
+      Str,\r
+      L"HD(%d,%s,%08x,",\r
+      Hd->PartitionNumber,\r
+      L"MBR",\r
+      *((UINT32 *) (&(Hd->Signature[0])))\r
+      );\r
+    break;\r
+\r
+  case SIGNATURE_TYPE_GUID:\r
+    CatPrint (\r
+      Str,\r
+      L"HD(%d,%s,%g,",\r
+      Hd->PartitionNumber,\r
+      L"GUID",\r
+      (EFI_GUID *) &(Hd->Signature[0])\r
+      );\r
+    break;\r
+\r
+  default:\r
+    break;\r
+  }\r
+\r
+  CatPrint (Str, L"%lx,%lx)", Hd->PartitionStart, Hd->PartitionSize);\r
+}\r
+\r
+VOID\r
+DevPathToTextCDROM (\r
+  IN OUT POOL_PRINT  *Str,\r
+  IN VOID            *DevPath,\r
+  IN BOOLEAN         DisplayOnly,\r
+  IN BOOLEAN         AllowShortcuts\r
+  )\r
+{\r
+  CDROM_DEVICE_PATH *Cd;\r
+\r
+  Cd = DevPath;\r
+  if (DisplayOnly == TRUE) {\r
+    CatPrint (Str, L"CDROM(%x)", Cd->BootEntry);\r
+    return ;\r
+  }\r
+\r
+  CatPrint (Str, L"CDROM(%x,%lx,%lx)", Cd->BootEntry, Cd->PartitionStart, Cd->PartitionSize);\r
+}\r
+\r
+VOID\r
+DevPathToTextFilePath (\r
+  IN OUT POOL_PRINT  *Str,\r
+  IN VOID            *DevPath,\r
+  IN BOOLEAN         DisplayOnly,\r
+  IN BOOLEAN         AllowShortcuts\r
+  )\r
+{\r
+  FILEPATH_DEVICE_PATH  *Fp;\r
+\r
+  Fp = DevPath;\r
+  CatPrint (Str, L"%s", Fp->PathName);\r
+}\r
+\r
+VOID\r
+DevPathToTextMediaProtocol (\r
+  IN OUT POOL_PRINT  *Str,\r
+  IN VOID            *DevPath,\r
+  IN BOOLEAN         DisplayOnly,\r
+  IN BOOLEAN         AllowShortcuts\r
+  )\r
+{\r
+  MEDIA_PROTOCOL_DEVICE_PATH  *MediaProt;\r
+\r
+  MediaProt = DevPath;\r
+  CatPrint (Str, L"Media(%g)", &MediaProt->Protocol);\r
+}\r
+\r
+VOID\r
+DevPathToTextBBS (\r
+  IN OUT POOL_PRINT  *Str,\r
+  IN VOID            *DevPath,\r
+  IN BOOLEAN         DisplayOnly,\r
+  IN BOOLEAN         AllowShortcuts\r
+  )\r
+{\r
+  BBS_BBS_DEVICE_PATH *Bbs;\r
+  CHAR16              *Type;\r
+\r
+  Bbs = DevPath;\r
+  switch (Bbs->DeviceType) {\r
+  case BBS_TYPE_FLOPPY:\r
+    Type = L"Floppy";\r
+    break;\r
+\r
+  case BBS_TYPE_HARDDRIVE:\r
+    Type = L"HD";\r
+    break;\r
+\r
+  case BBS_TYPE_CDROM:\r
+    Type = L"CDROM";\r
+    break;\r
+\r
+  case BBS_TYPE_PCMCIA:\r
+    Type = L"PCMCIA";\r
+    break;\r
+\r
+  case BBS_TYPE_USB:\r
+    Type = L"USB";\r
+    break;\r
+\r
+  case BBS_TYPE_EMBEDDED_NETWORK:\r
+    Type = L"Network";\r
+    break;\r
+\r
+  default:\r
+    Type = L"?";\r
+    break;\r
+  }\r
+\r
+  CatPrint (Str, L"BBS(%s,%a", Type, Bbs->String);\r
+\r
+  if (DisplayOnly == TRUE) {\r
+    CatPrint (Str, L")");\r
+    return ;\r
+  }\r
+\r
+  CatPrint (Str, L",%x)", Bbs->StatusFlag);\r
+}\r
+\r
+VOID\r
+DevPathToTextEndInstance (\r
+  IN OUT POOL_PRINT  *Str,\r
+  IN VOID            *DevPath,\r
+  IN BOOLEAN         DisplayOnly,\r
+  IN BOOLEAN         AllowShortcuts\r
+  )\r
+{\r
+  CatPrint (Str, L",");\r
+}\r
+\r
+VOID\r
+DevPathToTextNodeUnknown (\r
+  IN OUT POOL_PRINT  *Str,\r
+  IN VOID            *DevPath,\r
+  IN BOOLEAN         DisplayOnly,\r
+  IN BOOLEAN         AllowShortcuts\r
+  )\r
+{\r
+  CatPrint (Str, L"?");\r
+}\r
+\r
+DEVICE_PATH_TO_TEXT_TABLE DevPathToTextTable[] = {\r
+  HARDWARE_DEVICE_PATH,\r
+  HW_PCI_DP,\r
+  DevPathToTextPci,\r
+  HARDWARE_DEVICE_PATH,\r
+  HW_PCCARD_DP,\r
+  DevPathToTextPccard,\r
+  HARDWARE_DEVICE_PATH,\r
+  HW_MEMMAP_DP,\r
+  DevPathToTextMemMap,\r
+  HARDWARE_DEVICE_PATH,\r
+  HW_VENDOR_DP,\r
+  DevPathToTextVendor,\r
+  HARDWARE_DEVICE_PATH,\r
+  HW_CONTROLLER_DP,\r
+  DevPathToTextController,\r
+  ACPI_DEVICE_PATH,\r
+  ACPI_DP,\r
+  DevPathToTextAcpi,\r
+  ACPI_DEVICE_PATH,\r
+  ACPI_EXTENDED_DP,\r
+  DevPathToTextExtAcpi,\r
+  MESSAGING_DEVICE_PATH,\r
+  MSG_ATAPI_DP,\r
+  DevPathToTextAtapi,\r
+  MESSAGING_DEVICE_PATH,\r
+  MSG_SCSI_DP,\r
+  DevPathToTextScsi,\r
+  MESSAGING_DEVICE_PATH,\r
+  MSG_FIBRECHANNEL_DP,\r
+  DevPathToTextFibre,\r
+  MESSAGING_DEVICE_PATH,\r
+  MSG_1394_DP,\r
+  DevPathToText1394,\r
+  MESSAGING_DEVICE_PATH,\r
+  MSG_USB_DP,\r
+  DevPathToTextUsb,\r
+  MESSAGING_DEVICE_PATH,\r
+  MSG_USB_WWID_DP,\r
+  DevPathToTextUsbWWID,\r
+  MESSAGING_DEVICE_PATH,\r
+  MSG_DEVICE_LOGICAL_UNIT_DP,\r
+  DevPathToTextLogicalUnit,\r
+  MESSAGING_DEVICE_PATH,\r
+  MSG_USB_CLASS_DP,\r
+  DevPathToTextUsbClass,\r
+  MESSAGING_DEVICE_PATH,\r
+  MSG_I2O_DP,\r
+  DevPathToTextI2O,\r
+  MESSAGING_DEVICE_PATH,\r
+  MSG_MAC_ADDR_DP,\r
+  DevPathToTextMacAddr,\r
+  MESSAGING_DEVICE_PATH,\r
+  MSG_IPv4_DP,\r
+  DevPathToTextIPv4,\r
+  MESSAGING_DEVICE_PATH,\r
+  MSG_IPv6_DP,\r
+  DevPathToTextIPv6,\r
+  MESSAGING_DEVICE_PATH,\r
+  MSG_INFINIBAND_DP,\r
+  DevPathToTextInfiniBand,\r
+  MESSAGING_DEVICE_PATH,\r
+  MSG_UART_DP,\r
+  DevPathToTextUart,\r
+  MESSAGING_DEVICE_PATH,\r
+  MSG_VENDOR_DP,\r
+  DevPathToTextVendor,\r
+  MESSAGING_DEVICE_PATH,\r
+  MSG_ISCSI_DP,\r
+  DevPathToTextiSCSI,\r
+  MEDIA_DEVICE_PATH,\r
+  MEDIA_HARDDRIVE_DP,\r
+  DevPathToTextHardDrive,\r
+  MEDIA_DEVICE_PATH,\r
+  MEDIA_CDROM_DP,\r
+  DevPathToTextCDROM,\r
+  MEDIA_DEVICE_PATH,\r
+  MEDIA_VENDOR_DP,\r
+  DevPathToTextVendor,\r
+  MEDIA_DEVICE_PATH,\r
+  MEDIA_FILEPATH_DP,\r
+  DevPathToTextFilePath,\r
+  MEDIA_DEVICE_PATH,\r
+  MEDIA_PROTOCOL_DP,\r
+  DevPathToTextMediaProtocol,\r
+  MEDIA_DEVICE_PATH,\r
+  MEDIA_FILEPATH_DP,\r
+  DevPathToTextFilePath,\r
+  BBS_DEVICE_PATH,\r
+  BBS_BBS_DP,\r
+  DevPathToTextBBS,\r
+  END_DEVICE_PATH_TYPE,\r
+  END_INSTANCE_DEVICE_PATH_SUBTYPE,\r
+  DevPathToTextEndInstance,\r
+  0,\r
+  0,\r
+  NULL\r
+};\r
+\r
+CHAR16 *\r
+ConvertDeviceNodeToText (\r
+  IN CONST EFI_DEVICE_PATH_PROTOCOL  *DeviceNode,\r
+  IN BOOLEAN                         DisplayOnly,\r
+  IN BOOLEAN                         AllowShortcuts\r
+  )\r
+/*++\r
+\r
+  Routine Description:\r
+    Convert a device node to its text representation.\r
+\r
+  Arguments:\r
+    DeviceNode       -   Points to the device node to be converted.\r
+    DisplayOnly      -   If DisplayOnly is TRUE, then the shorter text representation\r
+                         of the display node is used, where applicable. If DisplayOnly\r
+                         is FALSE, then the longer text representation of the display node\r
+                         is used.\r
+    AllowShortcuts   -   If AllowShortcuts is TRUE, then the shortcut forms of text\r
+                         representation for a device node can be used, where applicable.\r
+\r
+  Returns:\r
+    A pointer        -   a pointer to the allocated text representation of the device node.\r
+    NULL             -   if DeviceNode is NULL or there was insufficient memory.\r
+\r
+--*/\r
+{\r
+  POOL_PRINT  Str;\r
+  UINTN       Index;\r
+  UINTN       NewSize;\r
+  VOID        (*DumpNode)(POOL_PRINT *, VOID *, BOOLEAN, BOOLEAN);\r
+\r
+  if (DeviceNode == NULL) {\r
+    return NULL;\r
+  }\r
+\r
+  ZeroMem (&Str, sizeof (Str));\r
+\r
+  //\r
+  // Process the device path node\r
+  //\r
+  DumpNode = NULL;\r
+  for (Index = 0; DevPathToTextTable[Index].Function != NULL; Index++) {\r
+    if (DevicePathType (DeviceNode) == DevPathToTextTable[Index].Type &&\r
+        DevicePathSubType (DeviceNode) == DevPathToTextTable[Index].SubType\r
+        ) {\r
+      DumpNode = DevPathToTextTable[Index].Function;\r
+      break;\r
+    }\r
+  }\r
+  //\r
+  // If not found, use a generic function\r
+  //\r
+  if (DumpNode == NULL) {\r
+    DumpNode = DevPathToTextNodeUnknown;\r
+  }\r
+\r
+  //\r
+  // Print this node\r
+  //\r
+  DumpNode (&Str, (VOID *) DeviceNode, DisplayOnly, AllowShortcuts);\r
+\r
+  //\r
+  // Shrink pool used for string allocation\r
+  //\r
+  NewSize = (Str.Len + 1) * sizeof (CHAR16);\r
+  Str.Str = ReallocatePool (Str.Str, NewSize, NewSize);\r
+  ASSERT (Str.Str != NULL);\r
+  Str.Str[Str.Len] = 0;\r
+  return Str.Str;\r
+}\r
+\r
+CHAR16 *\r
+ConvertDevicePathToText (\r
+  IN CONST EFI_DEVICE_PATH_PROTOCOL   *DevicePath,\r
+  IN BOOLEAN                          DisplayOnly,\r
+  IN BOOLEAN                          AllowShortcuts\r
+  )\r
+/*++\r
+\r
+  Routine Description:\r
+    Convert a device path to its text representation.\r
+\r
+  Arguments:\r
+    DeviceNode       -   Points to the device path to be converted.\r
+    DisplayOnly      -   If DisplayOnly is TRUE, then the shorter text representation\r
+                         of the display node is used, where applicable. If DisplayOnly\r
+                         is FALSE, then the longer text representation of the display node\r
+                         is used.\r
+    AllowShortcuts   -   If AllowShortcuts is TRUE, then the shortcut forms of text\r
+                         representation for a device node can be used, where applicable.\r
+\r
+  Returns:\r
+    A pointer        -   a pointer to the allocated text representation of the device path.\r
+    NULL             -   if DeviceNode is NULL or there was insufficient memory.\r
+\r
+--*/\r
+{\r
+  POOL_PRINT                Str;\r
+  EFI_DEVICE_PATH_PROTOCOL  *DevPathNode;\r
+  EFI_DEVICE_PATH_PROTOCOL  *UnpackDevPath;\r
+  UINTN                     Index;\r
+  UINTN                     NewSize;\r
+  VOID                      (*DumpNode) (POOL_PRINT *, VOID *, BOOLEAN, BOOLEAN);\r
+\r
+  if (DevicePath == NULL) {\r
+    return NULL;\r
+  }\r
+\r
+  ZeroMem (&Str, sizeof (Str));\r
+\r
+  //\r
+  // Unpacked the device path\r
+  //\r
+  UnpackDevPath = UnpackDevicePath ((EFI_DEVICE_PATH_PROTOCOL *) DevicePath);\r
+  ASSERT (UnpackDevPath != NULL);\r
+\r
+  //\r
+  // Process each device path node\r
+  //\r
+  DevPathNode = UnpackDevPath;\r
+  while (!IsDevicePathEnd (DevPathNode)) {\r
+    //\r
+    // Find the handler to dump this device path node\r
+    //\r
+    DumpNode = NULL;\r
+    for (Index = 0; DevPathToTextTable[Index].Function; Index += 1) {\r
+\r
+      if (DevicePathType (DevPathNode) == DevPathToTextTable[Index].Type &&\r
+          DevicePathSubType (DevPathNode) == DevPathToTextTable[Index].SubType\r
+          ) {\r
+        DumpNode = DevPathToTextTable[Index].Function;\r
+        break;\r
+      }\r
+    }\r
+    //\r
+    // If not found, use a generic function\r
+    //\r
+    if (!DumpNode) {\r
+      DumpNode = DevPathToTextNodeUnknown;\r
+    }\r
+    //\r
+    //  Put a path seperator in if needed\r
+    //\r
+    if (Str.Len && DumpNode != DevPathToTextEndInstance) {\r
+      if (*(Str.Str + Str.Len / sizeof (CHAR16) - 1) != L',') {        \r
+        CatPrint (&Str, L"/");\r
+      }          \r
+    }\r
+    //\r
+    // Print this node of the device path\r
+    //\r
+    DumpNode (&Str, DevPathNode, DisplayOnly, AllowShortcuts);\r
+\r
+    //\r
+    // Next device path node\r
+    //\r
+    DevPathNode = NextDevicePathNode (DevPathNode);\r
+  }\r
+  //\r
+  // Shrink pool used for string allocation\r
+  //\r
+  gBS->FreePool (UnpackDevPath);\r
+\r
+  NewSize = (Str.Len + 1) * sizeof (CHAR16);\r
+  Str.Str = ReallocatePool (Str.Str, NewSize, NewSize);\r
+  ASSERT (Str.Str != NULL);\r
+  Str.Str[Str.Len] = 0;\r
+  return Str.Str;\r
+}\r
diff --git a/EdkModulePkg/Universal/DevicePath/Dxe/DevicePathUtilities.c b/EdkModulePkg/Universal/DevicePath/Dxe/DevicePathUtilities.c
new file mode 100644 (file)
index 0000000..2b54c76
--- /dev/null
@@ -0,0 +1,421 @@
+/*++
+
+Copyright (c) 2006, Intel Corporation                                                     
+All rights reserved. This program and the accompanying materials                          
+are licensed and made available under the terms and conditions of the BSD License         
+which accompanies this distribution.  The full text of the license may be found at        
+http://opensource.org/licenses/bsd-license.php                                            
+                                                                                          
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             
+
+Module Name:
+
+  DevicePathUtilities.c
+
+Abstract:
+
+  Implementation file for Device Path Utilities Protocol
+
+--*/
+
+#include <protocol/DevicePathUtilities.h>
+#include <protocol/DevicePath.h>
+#include "DevicePath.h"
+
+UINTN
+GetDevicePathSize (
+  IN CONST EFI_DEVICE_PATH_PROTOCOL  *DevicePath
+  )
+/*++
+
+  Routine Description:
+    Returns the size of the device path, in bytes.
+
+  Arguments:
+    DevicePath  -   Points to the start of the EFI device path.
+
+  Returns:
+    Size        -   Size of the specified device path, in bytes, including the end-of-path tag.
+
+--*/
+{
+  CONST EFI_DEVICE_PATH_PROTOCOL  *Start;
+
+  if (DevicePath == NULL) {
+    return 0;
+  }
+
+  //
+  // Search for the end of the device path structure
+  //
+  Start = (EFI_DEVICE_PATH_PROTOCOL *) DevicePath;
+  while (!IsDevicePathEnd (DevicePath)) {
+    DevicePath = NextDevicePathNode (DevicePath);
+  }
+
+  //
+  // Compute the size and add back in the size of the end device path structure
+  //
+  return ((UINTN) DevicePath - (UINTN) Start) + sizeof (EFI_DEVICE_PATH_PROTOCOL);
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+DuplicateDevicePath (
+  IN CONST EFI_DEVICE_PATH_PROTOCOL  *DevicePath
+  )
+/*++
+
+  Routine Description:
+    Create a duplicate of the specified path.
+
+  Arguments:
+    DevicePath  -   Points to the source EFI device path.
+
+  Returns:
+    Pointer     -   A pointer to the duplicate device path.
+    NULL        -   Insufficient memory.
+
+--*/
+{
+  EFI_DEVICE_PATH_PROTOCOL  *NewDevicePath;
+  UINTN                     Size;
+
+  if (DevicePath == NULL) {
+    return NULL;
+  }
+
+  //
+  // Compute the size
+  //
+  Size = GetDevicePathSize (DevicePath);
+  if (Size == 0) {
+    return NULL;
+  }
+
+  //
+  // Allocate space for duplicate device path
+  //
+  NewDevicePath = AllocateCopyPool (Size, (VOID *) DevicePath);
+
+  return NewDevicePath;
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+AppendDevicePath (
+  IN CONST EFI_DEVICE_PATH_PROTOCOL *Src1,
+  IN CONST EFI_DEVICE_PATH_PROTOCOL *Src2
+  )
+/*++
+
+  Routine Description:
+    Create a new path by appending the second device path to the first.
+
+  Arguments:
+    Src1      -   Points to the first device path. If NULL, then it is ignored.
+    Src2      -   Points to the second device path. If NULL, then it is ignored.
+
+  Returns:
+    Pointer   -   A pointer to the newly created device path.
+    NULL      -   Memory could not be allocated
+                  or either DevicePath or DeviceNode is NULL.
+
+--*/
+{
+  UINTN                     Size;
+  UINTN                     Size1;
+  UINTN                     Size2;
+  EFI_DEVICE_PATH_PROTOCOL  *NewDevicePath;
+  EFI_DEVICE_PATH_PROTOCOL  *SecondDevicePath;
+
+  //
+  // If there's only 1 path, just duplicate it
+  //
+  if (Src1 == NULL) {
+    ASSERT (!IsDevicePathUnpacked (Src2));
+    return DuplicateDevicePath (Src2);
+  }
+
+  if (Src2 == NULL) {
+    ASSERT (!IsDevicePathUnpacked (Src1));
+    return DuplicateDevicePath (Src1);
+  }
+
+  //
+  // Allocate space for the combined device path. It only has one end node of
+  // length EFI_DEVICE_PATH_PROTOCOL
+  //
+  Size1         = GetDevicePathSize (Src1);
+  Size2         = GetDevicePathSize (Src2);
+  Size          = Size1 + Size2 - sizeof (EFI_DEVICE_PATH_PROTOCOL);
+
+  NewDevicePath = AllocateCopyPool (Size, (VOID *) Src1);
+
+  if (NewDevicePath != NULL) {
+    //
+    // Over write Src1 EndNode and do the copy
+    //
+    SecondDevicePath = (EFI_DEVICE_PATH_PROTOCOL *) ((CHAR8 *) NewDevicePath + (Size1 - sizeof (EFI_DEVICE_PATH_PROTOCOL)));
+    CopyMem (SecondDevicePath, (VOID *) Src2, Size2);
+  }
+
+  return NewDevicePath;
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+AppendDeviceNode (
+  IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath,
+  IN CONST EFI_DEVICE_PATH_PROTOCOL *DeviceNode
+  )
+/*++
+
+  Routine Description:
+    Creates a new path by appending the device node to the device path.
+
+  Arguments:
+    DevicePath   -   Points to the device path.
+    DeviceNode   -   Points to the device node.
+
+  Returns:
+    Pointer      -   A pointer to the allocated device node.
+    NULL         -   Memory could not be allocated
+                     or either DevicePath or DeviceNode is NULL.
+
+--*/
+{
+  EFI_DEVICE_PATH_PROTOCOL  *Temp;
+  EFI_DEVICE_PATH_PROTOCOL  *NextNode;
+  EFI_DEVICE_PATH_PROTOCOL  *NewDevicePath;
+  UINTN                     NodeLength;
+
+  if ((DevicePath == NULL) || (DeviceNode == NULL)) {
+    return NULL;
+  }
+
+  //
+  // Build a Node that has a terminator on it
+  //
+  NodeLength  = DevicePathNodeLength (DeviceNode);
+
+  Temp        = AllocateCopyPool (NodeLength + sizeof (EFI_DEVICE_PATH_PROTOCOL), (VOID *) DeviceNode);
+  if (Temp == NULL) {
+    return NULL;
+  }
+
+  //
+  // Add and end device path node to convert Node to device path
+  //
+  NextNode = NextDevicePathNode (Temp);
+  SetDevicePathEndNode (NextNode);
+
+  //
+  // Append device paths
+  //
+  NewDevicePath = AppendDevicePath (DevicePath, Temp);
+  gBS->FreePool (Temp);
+  return NewDevicePath;
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+AppendDevicePathInstance (
+  IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath,
+  IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePathInstance
+  )
+/*++
+
+  Routine Description:
+    Creates a new path by appending the specified device path instance to the specified device path.
+
+  Arguments:
+    DevicePath           -   Points to the device path. If NULL, then ignored.
+    DevicePathInstance   -   Points to the device path instance.
+
+  Returns:
+    Pointer              -   A pointer to the newly created device path
+    NULL                 -   Memory could not be allocated or DevicePathInstance is NULL.
+
+--*/
+{
+  UINT8                     *Ptr;
+  EFI_DEVICE_PATH_PROTOCOL  *DevPath;
+  UINTN                     SrcSize;
+  UINTN                     InstanceSize;
+
+  if (DevicePathInstance == NULL) {
+    return NULL;
+  }
+
+  if (DevicePath == NULL) {
+    return DuplicateDevicePath (DevicePathInstance);
+  }
+
+  SrcSize       = GetDevicePathSize (DevicePath);
+  InstanceSize  = GetDevicePathSize (DevicePathInstance);
+
+  Ptr           = AllocateCopyPool (SrcSize + InstanceSize, (VOID *) DevicePath);
+  if (Ptr != NULL) {
+
+    DevPath = (EFI_DEVICE_PATH_PROTOCOL *) (Ptr + (SrcSize - sizeof (EFI_DEVICE_PATH_PROTOCOL)));
+    //
+    // Convert the End to an End Instance, since we are
+    //  appending another instacne after this one its a good
+    //  idea.
+    //
+    DevPath->SubType  = END_INSTANCE_DEVICE_PATH_SUBTYPE;
+
+    DevPath           = NextDevicePathNode (DevPath);
+    CopyMem (DevPath, (VOID *) DevicePathInstance, InstanceSize);
+  }
+
+  return (EFI_DEVICE_PATH_PROTOCOL *) Ptr;
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+GetNextDevicePathInstance (
+  IN OUT EFI_DEVICE_PATH_PROTOCOL   **DevicePathInstance,
+  OUT UINTN                         *DevicePathInstanceSize
+  )
+/*++
+
+  Routine Description:
+    Creates a copy of the current device path instance and returns a pointer to the next device path instance.
+
+  Arguments:
+    DevicePathInstance       -   On input, this holds the pointer to the current device path
+                                 instance. On output, this holds the pointer to the next
+                                 device path instance or NULL if there are no more device
+                                 path instances in the device path.
+    DevicePathInstanceSize   -   On output, this holds the size of the device path instance,
+                                 in bytes or zero, if DevicePathInstance is zero.
+
+  Returns:
+    Pointer                  -   A pointer to the copy of the current device path instance.
+    NULL                     -   DevicePathInstace was NULL on entry or there was insufficient memory.
+
+--*/
+{
+  EFI_DEVICE_PATH_PROTOCOL  *DevPath;
+  EFI_DEVICE_PATH_PROTOCOL  *ReturnValue;
+  UINT8                     Temp;
+
+  if (*DevicePathInstance == NULL) {
+    if (DevicePathInstanceSize != NULL) {
+      *DevicePathInstanceSize = 0;
+    }
+
+    return NULL;
+  }
+
+  //
+  // Find the end of the device path instance
+  //
+  DevPath = *DevicePathInstance;
+  while (!IsDevicePathEndType (DevPath)) {
+    DevPath = NextDevicePathNode (DevPath);
+  }
+
+  //
+  // Compute the size of the device path instance
+  //
+  if (DevicePathInstanceSize != NULL) {
+    *DevicePathInstanceSize = ((UINTN) DevPath - (UINTN) (*DevicePathInstance)) + sizeof (EFI_DEVICE_PATH_PROTOCOL);
+  }
+
+  //
+  // Make a copy and return the device path instance
+  //
+  Temp              = DevPath->SubType;
+  DevPath->SubType  = END_ENTIRE_DEVICE_PATH_SUBTYPE;
+  ReturnValue       = DuplicateDevicePath (*DevicePathInstance);
+  DevPath->SubType  = Temp;
+
+  //
+  // If DevPath is the end of an entire device path, then another instance
+  // does not follow, so *DevicePath is set to NULL.
+  //
+  if (DevicePathSubType (DevPath) == END_ENTIRE_DEVICE_PATH_SUBTYPE) {
+    *DevicePathInstance = NULL;
+  } else {
+    *DevicePathInstance = NextDevicePathNode (DevPath);
+  }
+
+  return ReturnValue;
+}
+
+BOOLEAN
+IsDevicePathMultiInstance (
+  IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath
+  )
+/*++
+
+  Routine Description:
+    Returns whether a device path is multi-instance.
+
+  Arguments:
+    DevicePath  -   Points to the device path. If NULL, then ignored.
+
+  Returns:
+    TRUE        -   The device path has more than one instance
+    FALSE       -   The device path is empty or contains only a single instance.
+
+--*/
+{
+  CONST EFI_DEVICE_PATH_PROTOCOL  *Node;
+
+  if (DevicePath == NULL) {
+    return FALSE;
+  }
+
+  Node = DevicePath;
+  while (!IsDevicePathEnd (Node)) {
+    if (EfiIsDevicePathEndInstance (Node)) {
+      return TRUE;
+    }
+
+    Node = NextDevicePathNode (Node);
+  }
+
+  return FALSE;
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+CreateDeviceNode (
+  IN UINT8  NodeType,
+  IN UINT8  NodeSubType,
+  IN UINT16 NodeLength
+  )
+/*++
+
+  Routine Description:
+    Creates a device node
+
+  Arguments:
+    NodeType     -    NodeType is the device node type (EFI_DEVICE_PATH.Type) for
+                      the new device node.
+    NodeSubType  -    NodeSubType is the device node sub-type
+                      EFI_DEVICE_PATH.SubType) for the new device node.
+    NodeLength   -    NodeLength is the length of the device node
+                      (EFI_DEVICE_PATH.Length) for the new device node.
+
+  Returns:
+    Pointer      -    A pointer to the newly created device node.
+    NULL         -    NodeLength is less than
+                      the size of the header or there was insufficient memory.
+
+--*/
+{
+  EFI_DEVICE_PATH_PROTOCOL  *Node;
+
+  if (NodeLength < sizeof (EFI_DEVICE_PATH_PROTOCOL)) {
+    return NULL;
+  }
+
+  Node = (EFI_DEVICE_PATH_PROTOCOL *) AllocateZeroPool ((UINTN) NodeLength);
+  if (Node != NULL) {
+    Node->Type    = NodeType;
+    Node->SubType = NodeSubType;
+    SetDevicePathNodeLength (Node, NodeLength);
+  }
+
+  return Node;
+}
index 50b6c855b6af203593ab84fca588d3827955703f..62a0f6116bed4030b5a37e4a32aa19768cfd1d91 100644 (file)
@@ -3473,6 +3473,73 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
         <FfsFormatKey>BS_DRIVER</FfsFormatKey>
       </ModuleSaBuildOptions>
     </ModuleSA>
+    <ModuleSA SupArchList="IA32" PackageGuid="B6EC423C-21D2-490D-85C6-DD5864EAA674" ModuleGuid="9B680FCE-AD6B-4F3A-B60B-F59899003443">
+      <Libraries>
+        <Instance ModuleGuid="ff5c7a2c-ab7a-4366-8616-11c6e53247b6" PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>
+        <Instance ModuleGuid="f1bbe03d-2f28-4dee-bec7-d98d7a30c36a" PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>
+        <Instance ModuleGuid="3a004ba5-efe0-4a61-9f1a-267a46ae5ba9" PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>
+        <Instance ModuleGuid="331deb15-454b-48d8-9b74-70d01f3f3556" PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>
+        <Instance ModuleGuid="3ddc3b12-99ea-4364-b315-6310a2050be5" PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>
+        <Instance ModuleGuid="bda39d3a-451b-4350-8266-81ab10fa0523" PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>
+        <Instance ModuleGuid="27d67720-ea68-48ae-93da-a3a074c90e30" PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>
+        <Instance ModuleGuid="4674739d-3195-4fb2-8094-ac1d22d00194" PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>
+        <Instance ModuleGuid="a86fbfca-0183-4eeb-aa8a-762e3b7da1f3" PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>
+      </Libraries>
+      <PcdBuildDefinition>
+        <PcdData ItemType="FIXED_AT_BUILD">
+          <C_Name>PcdMaximumUnicodeStringLength</C_Name>
+          <Token>0x00000001</Token>
+          <TokenSpaceGuidCName>gEfiMdePkgTokenSpaceGuid</TokenSpaceGuidCName>
+          <DatumType>UINT32</DatumType>
+          <MaxDatumSize>4</MaxDatumSize>
+          <Value>1000000</Value>
+        </PcdData>
+        <PcdData ItemType="FIXED_AT_BUILD">
+          <C_Name>PcdMaximumAsciiStringLength</C_Name>
+          <Token>0x00000002</Token>
+          <TokenSpaceGuidCName>gEfiMdePkgTokenSpaceGuid</TokenSpaceGuidCName>
+          <DatumType>UINT32</DatumType>
+          <MaxDatumSize>4</MaxDatumSize>
+          <Value>1000000</Value>
+        </PcdData>
+        <PcdData ItemType="FIXED_AT_BUILD">
+          <C_Name>PcdDebugPropertyMask</C_Name>
+          <Token>0x00000005</Token>
+          <TokenSpaceGuidCName>gEfiMdePkgTokenSpaceGuid</TokenSpaceGuidCName>
+          <DatumType>UINT8</DatumType>
+          <MaxDatumSize>1</MaxDatumSize>
+          <Value>0x0f</Value>
+        </PcdData>
+        <PcdData ItemType="PATCHABLE_IN_MODULE">
+          <C_Name>PcdDebugPrintErrorLevel</C_Name>
+          <Token>0x00000006</Token>
+          <TokenSpaceGuidCName>gEfiMdePkgTokenSpaceGuid</TokenSpaceGuidCName>
+          <DatumType>UINT32</DatumType>
+          <MaxDatumSize>4</MaxDatumSize>
+          <Value>0x80000000</Value>
+        </PcdData>
+        <PcdData ItemType="FIXED_AT_BUILD">
+          <C_Name>PcdReportStatusCodePropertyMask</C_Name>
+          <Token>0x00000007</Token>
+          <TokenSpaceGuidCName>gEfiMdePkgTokenSpaceGuid</TokenSpaceGuidCName>
+          <DatumType>UINT8</DatumType>
+          <MaxDatumSize>1</MaxDatumSize>
+          <Value>0x07</Value>
+        </PcdData>
+        <PcdData ItemType="FIXED_AT_BUILD">
+          <C_Name>PcdDebugClearMemoryValue</C_Name>
+          <Token>0x00000008</Token>
+          <TokenSpaceGuidCName>gEfiMdePkgTokenSpaceGuid</TokenSpaceGuidCName>
+          <DatumType>UINT8</DatumType>
+          <MaxDatumSize>1</MaxDatumSize>
+          <Value>0xAF</Value>
+        </PcdData>
+      </PcdBuildDefinition>
+      <ModuleSaBuildOptions>
+        <FvBinding>FV_RECOVERY</FvBinding>
+        <FfsFormatKey>BS_DRIVER</FfsFormatKey>
+      </ModuleSaBuildOptions>
+    </ModuleSA>
     <ModuleSA SupArchList="IA32" PackageGuid="B6EC423C-21D2-490D-85C6-DD5864EAA674" ModuleGuid="6B38F7B4-AD98-40e9-9093-ACA2B5A253C4">
       <Libraries>
         <Instance ModuleGuid="ff5c7a2c-ab7a-4366-8616-11c6e53247b6" PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>
@@ -4579,6 +4646,98 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
         <FfsFormatKey>BS_DRIVER</FfsFormatKey>
       </ModuleSaBuildOptions>
     </ModuleSA>
+    <ModuleSA SupArchList="IA32" PackageGuid="B6EC423C-21D2-490D-85C6-DD5864EAA674" ModuleGuid="BDFE430E-8F2A-4db0-9991-6F856594777E">\r
+      <Libraries>\r
+        <Instance ModuleGuid="ff5c7a2c-ab7a-4366-8616-11c6e53247b6" PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>\r
+        <Instance ModuleGuid="f1bbe03d-2f28-4dee-bec7-d98d7a30c36a" PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>\r
+        <Instance ModuleGuid="3a004ba5-efe0-4a61-9f1a-267a46ae5ba9" PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>\r
+        <Instance ModuleGuid="331deb15-454b-48d8-9b74-70d01f3f3556" PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>\r
+        <Instance ModuleGuid="52af22ae-9901-4484-8cdc-622dd5838b09" PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>\r
+        <Instance ModuleGuid="3ddc3b12-99ea-4364-b315-6310a2050be5" PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>\r
+        <Instance ModuleGuid="bda39d3a-451b-4350-8266-81ab10fa0523" PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>\r
+        <Instance ModuleGuid="50bcb105-6634-441d-b403-659110a03ad2" PackageGuid="B6EC423C-21D2-490D-85C6-DD5864EAA674"/>\r
+        <Instance ModuleGuid="27d67720-ea68-48ae-93da-a3a074c90e30" PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>\r
+        <Instance ModuleGuid="4674739d-3195-4fb2-8094-ac1d22d00194" PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>\r
+      </Libraries>\r
+      <PcdBuildDefinition>\r
+        <PcdData ItemType="FIXED_AT_BUILD">\r
+          <C_Name>PcdMaximumUnicodeStringLength</C_Name>\r
+          <Token>0x00000001</Token>\r
+          <TokenSpaceGuidCName>gEfiMdePkgTokenSpaceGuid</TokenSpaceGuidCName>\r
+          <DatumType>UINT32</DatumType>\r
+          <MaxDatumSize>4</MaxDatumSize>\r
+          <Value>1000000</Value>\r
+        </PcdData>\r
+        <PcdData ItemType="FIXED_AT_BUILD">\r
+          <C_Name>PcdMaximumAsciiStringLength</C_Name>\r
+          <Token>0x00000002</Token>\r
+          <TokenSpaceGuidCName>gEfiMdePkgTokenSpaceGuid</TokenSpaceGuidCName>\r
+          <DatumType>UINT32</DatumType>\r
+          <MaxDatumSize>4</MaxDatumSize>\r
+          <Value>1000000</Value>\r
+        </PcdData>\r
+        <PcdData ItemType="FIXED_AT_BUILD">\r
+          <C_Name>PcdSpinLockTimeout</C_Name>\r
+          <Token>0x00000004</Token>\r
+          <TokenSpaceGuidCName>gEfiMdePkgTokenSpaceGuid</TokenSpaceGuidCName>\r
+          <DatumType>UINT32</DatumType>\r
+          <MaxDatumSize>4</MaxDatumSize>\r
+          <Value>10000000</Value>\r
+        </PcdData>\r
+        <PcdData ItemType="FIXED_AT_BUILD">\r
+          <C_Name>PcdMaximumLinkedListLength</C_Name>\r
+          <Token>0x00000003</Token>\r
+          <TokenSpaceGuidCName>gEfiMdePkgTokenSpaceGuid</TokenSpaceGuidCName>\r
+          <DatumType>UINT32</DatumType>\r
+          <MaxDatumSize>4</MaxDatumSize>\r
+          <Value>1000000</Value>\r
+        </PcdData>\r
+        <PcdData ItemType="FIXED_AT_BUILD">\r
+          <C_Name>PcdReportStatusCodePropertyMask</C_Name>\r
+          <Token>0x00000007</Token>\r
+          <TokenSpaceGuidCName>gEfiMdePkgTokenSpaceGuid</TokenSpaceGuidCName>\r
+          <DatumType>UINT8</DatumType>\r
+          <MaxDatumSize>1</MaxDatumSize>\r
+          <Value>0x07</Value>\r
+        </PcdData>\r
+        <PcdData ItemType="FIXED_AT_BUILD">\r
+          <C_Name>PcdDebugPropertyMask</C_Name>\r
+          <Token>0x00000005</Token>\r
+          <TokenSpaceGuidCName>gEfiMdePkgTokenSpaceGuid</TokenSpaceGuidCName>\r
+          <DatumType>UINT8</DatumType>\r
+          <MaxDatumSize>1</MaxDatumSize>\r
+          <Value>0x0f</Value>\r
+        </PcdData>\r
+        <PcdData ItemType="PATCHABLE_IN_MODULE">\r
+          <C_Name>PcdDebugPrintErrorLevel</C_Name>\r
+          <Token>0x00000006</Token>\r
+          <TokenSpaceGuidCName>gEfiMdePkgTokenSpaceGuid</TokenSpaceGuidCName>\r
+          <DatumType>UINT32</DatumType>\r
+          <MaxDatumSize>4</MaxDatumSize>\r
+          <Value>0x80000000</Value>\r
+        </PcdData>\r
+        <PcdData ItemType="FIXED_AT_BUILD">\r
+          <C_Name>PcdDebugClearMemoryValue</C_Name>\r
+          <Token>0x00000008</Token>\r
+          <TokenSpaceGuidCName>gEfiMdePkgTokenSpaceGuid</TokenSpaceGuidCName>\r
+          <DatumType>UINT8</DatumType>\r
+          <MaxDatumSize>1</MaxDatumSize>\r
+          <Value>0xAF</Value>\r
+        </PcdData>\r
+        <PcdData ItemType="FIXED_AT_BUILD">\r
+          <C_Name>PcdPerformanceLibraryPropertyMask</C_Name>\r
+          <Token>0x00000009</Token>\r
+          <TokenSpaceGuidCName>gEfiMdePkgTokenSpaceGuid</TokenSpaceGuidCName>\r
+          <DatumType>UINT8</DatumType>\r
+          <MaxDatumSize>1</MaxDatumSize>\r
+          <Value>0</Value>\r
+        </PcdData>\r
+      </PcdBuildDefinition>\r
+      <ModuleSaBuildOptions>\r
+        <FvBinding>FV_MAIN</FvBinding>\r
+        <FfsFormatKey>BS_DRIVER</FfsFormatKey>\r
+      </ModuleSaBuildOptions>\r
+    </ModuleSA>
     <ModuleSA SupArchList="IA32" PackageGuid="B6EC423C-21D2-490D-85C6-DD5864EAA674" ModuleGuid="0167CCC4-D0F7-4f21-A3EF-9E64B7CDCE8B">
       <Libraries>
         <Instance ModuleGuid="ff5c7a2c-ab7a-4366-8616-11c6e53247b6" PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>
index c9b74ab03e54ed744692e40c21a2bd2eba48ebcf..afbfc73bab82b8a87088f853298d801c7b4e358b 100644 (file)
     0xad15a0d6, 0x8bec, 0x4acf, {0xa0, 0x73, 0xd0, 0x1d, 0xe7, 0x7e, 0x2d, 0x88 } \\r
   }\r
 \r
+#define EFI_UART_DEVICE_PATH_GUID \\r
+  { \\r
+    0x37499a9d, 0x542f, 0x4c89, {0xa0, 0x26, 0x35, 0xda, 0x14, 0x20, 0x94, 0xe4 } \\r
+  }\r
+  \r
+#define EFI_SAS_DEVICE_PATH_GUID \\r
+  { \\r
+    0xb4dd87d4, 0x8b00, 0xd911, {0xaf, 0xdc, 0x00, 0x10, 0x83, 0xff, 0xca, 0x4d } \\r
+  }\r
+\r
 extern EFI_GUID gEfiPcAnsiGuid;\r
 extern EFI_GUID gEfiVT100Guid;\r
 extern EFI_GUID gEfiVT100PlusGuid;\r
index dca7351ff12940fbd0dff0065aaf6f67a5885fe8..d3328a5461743373ae220b70f6749fe1d33d0b1f 100644 (file)
@@ -255,6 +255,8 @@ typedef struct {
 #define USB_PORT_STAT_RESET         0x0010\r
 #define USB_PORT_STAT_POWER         0x0100\r
 #define USB_PORT_STAT_LOW_SPEED     0x0200\r
+#define USB_PORT_STAT_HIGH_SPEED    0x0400\r
+#define USB_PORT_STAT_OWNER         0x0800\r
 \r
 #define USB_PORT_STAT_C_CONNECTION  0x0001\r
 #define USB_PORT_STAT_C_ENABLE      0x0002\r
@@ -270,6 +272,7 @@ typedef enum {
   EfiUsbPortSuspend           = 2,\r
   EfiUsbPortReset             = 4,\r
   EfiUsbPortPower             = 8,\r
+  EfiUsbPortOwner             = 13,\r
   EfiUsbPortConnectChange     = 16,\r
   EfiUsbPortEnableChange      = 17,\r
   EfiUsbPortSuspendChange     = 18,\r
index a3a6c431ca88668f4b14f930de48a23c15204e3f..0d1ce3208aaf1fe404431c6de138e333795e8a16 100644 (file)
@@ -64,8 +64,8 @@ EFI_DEVICE_PATH_PROTOCOL*
 ;  \r
   \r
 typedef struct {\r
-  EFI_DEVICE_PATH_FROM_TEXT_NODE  ConvertDeviceNodeFromText;\r
-  EFI_DEVICE_PATH_FROM_TEXT_PATH  ConvertDevicePathFromText;\r
+  EFI_DEVICE_PATH_FROM_TEXT_NODE  ConvertTextToDeviceNode;\r
+  EFI_DEVICE_PATH_FROM_TEXT_PATH  ConvertTextToDevicePath;\r
 } EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL;\r
 \r
 extern EFI_GUID gEfiDevicePathFromTextProtocolGuid;\r
index 5326d5b6237ec05918f83d9843664eaf57644891..2a9d02da07ab94009628f51bf46f6a5a067c431e 100644 (file)
@@ -269,6 +269,7 @@ EFI_STATUS
   IN OUT UINT8                                               *DataToggle,\r
   IN     UINTN                                               PollingInterval  OPTIONAL,\r
   IN     UINTN                                               DataLength       OPTIONAL,\r
+  IN     EFI_USB2_HC_TRANSACTION_TRANSLATOR                  *Translator      OPTIONAL,\r
   IN     EFI_ASYNC_USB_TRANSFER_CALLBACK                     CallBackFunction OPTIONAL,\r
   IN     VOID                                                *Context         OPTIONAL\r
   )\r
@@ -305,16 +306,17 @@ EFI_STATUS
 typedef\r
 EFI_STATUS\r
 (EFIAPI *EFI_USB2_HC_PROTOCOL_SYNC_INTERRUPT_TRANSFER) (\r
-  IN     EFI_USB2_HC_PROTOCOL   *This,\r
-  IN     UINT8                  DeviceAddress,\r
-  IN     UINT8                  EndPointAddress,\r
-  IN     UINT8                  DeviceSpeed,\r
-  IN     UINTN                  MaximumPacketLength,\r
-  IN OUT VOID                   *Data,\r
-  IN OUT UINTN                  *DataLength,\r
-  IN OUT UINT8                  *DataToggle,\r
-  IN     UINTN                  TimeOut,\r
-  OUT    UINT32                 *TransferResult\r
+  IN     EFI_USB2_HC_PROTOCOL                        *This,\r
+  IN     UINT8                                       DeviceAddress,\r
+  IN     UINT8                                       EndPointAddress,\r
+  IN     UINT8                                       DeviceSpeed,\r
+  IN     UINTN                                       MaximumPacketLength,\r
+  IN OUT VOID                                        *Data,\r
+  IN OUT UINTN                                       *DataLength,\r
+  IN OUT UINT8                                       *DataToggle,\r
+  IN     UINTN                                       TimeOut,\r
+  IN     EFI_USB2_HC_TRANSACTION_TRANSLATOR          *Translator,\r
+  OUT    UINT32                                      *TransferResult\r
   )\r
 ;\r
 \r
index 9993cd44e7d2aea7afb9e35290902bddf7d25dca..3410ad2821137beb677dcea9df49c62f04add1a8 100644 (file)
@@ -1839,11 +1839,7 @@ typedef struct {
 #define HW_CONTROLLER_DP          0x05\r
 typedef struct {\r
   EFI_DEVICE_PATH_PROTOCOL        Header;\r
-#if EDK_RELEASE_VERSION >= 0x00020000\r
   UINT32                          ControllerNumber;\r
-#else\r
-  UINT32                          Controller;\r
-#endif\r
 } CONTROLLER_DEVICE_PATH;\r
 \r
 //\r
@@ -1945,6 +1941,7 @@ typedef struct {
     UINT8                         DeviceProtocol;\r
 } USB_CLASS_DEVICE_PATH;\r
 \r
+#if (EFI_SPECIFICATION_VERSION >= 0x00020000)\r
 #define MSG_USB_WWID_DP           0x10\r
 typedef struct {\r
     EFI_DEVICE_PATH_PROTOCOL      Header;\r
@@ -1957,8 +1954,9 @@ typedef struct {
 #define MSG_DEVICE_LOGICAL_UNIT_DP  0x11\r
 typedef struct {\r
     EFI_DEVICE_PATH_PROTOCOL      Header;\r
-    UINT8                         LUN;\r
+    UINT8                         Lun;\r
 } DEVICE_LOGICAL_UNIT_DEVICE_PATH;\r
+#endif\r
 \r
 #define MSG_I2O_DP                0x06\r
 typedef struct {\r
@@ -2030,8 +2028,27 @@ typedef struct {
 #define DEVICE_PATH_MESSAGING_VT_100      EFI_VT_100_GUID\r
 #define DEVICE_PATH_MESSAGING_VT_100_PLUS EFI_VT_100_PLUS_GUID\r
 #define DEVICE_PATH_MESSAGING_VT_UTF8     EFI_VT_UTF8_GUID\r
-#define DEVICE_PATH_MESSAGING_SAS         EFI_SAS_DEVICE_PATH_GUID\r
 \r
+#if (EFI_SPECIFICATION_VERSION >= 0x00020000)\r
+\r
+#define DEVICE_PATH_MESSAGING_UART_FLOW_CONTROL   EFI_UART_DEVICE_PATH_GUID\r
+#define DEVICE_PATH_MESSAGING_SAS                 EFI_SAS_DEVICE_PATH_GUID\r
+\r
+typedef struct {\r
+  EFI_DEVICE_PATH_PROTOCOL        Header;\r
+  EFI_GUID                        Guid;\r
+  UINT32                          FlowControlMap;\r
+} UART_FLOW_CONTROL_DEVICE_PATH;\r
+\r
+typedef struct {\r
+  EFI_DEVICE_PATH_PROTOCOL        Header;\r
+  EFI_GUID                        Guid;\r
+  UINT32                          Reserved;\r
+  UINT64                          SasAddress;\r
+  UINT64                          Lun;\r
+  UINT16                          DeviceTopology;\r
+  UINT16                          RelativeTargetPort;\r
+} SAS_DEVICE_PATH;\r
 \r
 #define MSG_ISCSI_DP              0x13\r
 typedef struct {\r
@@ -2053,6 +2070,7 @@ typedef struct {
 #define ISCSI_LOGIN_OPTION_CHAP_BI                      0x0000\r
 #define ISCSI_LOGIN_OPTION_CHAP_UNI                     0x2000\r
 \r
+#endif\r
 \r
 //\r
 // Media Device Path\r