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) {