public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
* [edk2-platforms PATCH 1/5] Silicon/Synopsys/DesignWare: Import DesignWare USB3 peripheral driver
@ 2020-07-17 10:01 Vin Xue
  2020-07-20 17:43 ` Leif Lindholm
  0 siblings, 1 reply; 6+ messages in thread
From: Vin Xue @ 2020-07-17 10:01 UTC (permalink / raw)
  To: devel; +Cc: Vin Xue, Ard Biesheuvel, Leif Lindholm

Incorporate the driver for the DesignWare USB3 DRD controller device
mode (peripheral) that is defined in
edk2-platforms/devel-IntelAtomProcessorE3900 branch.

The driver is supported by Intel Atom series (Merrifield/BayTrail/
CherryTrail/Broxton/ApoloLake/GeminiLake etc.) and Core series
(6th Generation and newer).

The driver verified on AAEON UP Squared developer board (Intel
ApoloLake platform).

The driver supports Synopsys DesignWare DWC_usb3 and DWC_usb31 IP.

It is better if the driver can be ported to ARM silicon.

Cc: Ard Biesheuvel <ard.biesheuvel@arm.com>
Cc: Leif Lindholm <leif@nuviainc.com>
Signed-off-by: Vin Xue <vinxue@outlook.com>
---
 .../Drivers/UsbDeviceDxe/ComponentName.c      |  305 ++
 .../Drivers/UsbDeviceDxe/UsbDeviceDxe.c       |  395 ++
 .../Drivers/UsbDeviceDxe/UsbDeviceDxe.h       |  159 +
 .../Drivers/UsbDeviceDxe/UsbDeviceDxe.inf     |   74 +
 .../Drivers/UsbDeviceDxe/UsbDeviceMode.c      | 1489 ++++++
 .../Drivers/UsbDeviceDxe/UsbDeviceMode.h      |   39 +
 .../Drivers/UsbDeviceDxe/UsbFuncIo.c          | 2221 +++++++++
 .../Drivers/UsbDeviceDxe/UsbFuncIo.h          |  234 +
 .../Drivers/UsbDeviceDxe/UsbIoNode.c          |  177 +
 .../Drivers/UsbDeviceDxe/UsbIoNode.h          |   90 +
 .../Drivers/UsbDeviceDxe/XdciCommon.h         |  156 +
 .../DesignWare/Drivers/UsbDeviceDxe/XdciDWC.c | 4030 +++++++++++++++++
 .../DesignWare/Drivers/UsbDeviceDxe/XdciDWC.h |  741 +++
 .../Drivers/UsbDeviceDxe/XdciDevice.c         |  695 +++
 .../Drivers/UsbDeviceDxe/XdciDevice.h         |  184 +
 .../Drivers/UsbDeviceDxe/XdciInterface.h      |  241 +
 .../Drivers/UsbDeviceDxe/XdciTable.c          |   55 +
 .../Drivers/UsbDeviceDxe/XdciUtility.c        |  148 +
 .../Drivers/UsbDeviceDxe/XdciUtility.h        |   62 +
 .../DesignWare/Include/Library/UsbDeviceLib.h |  323 ++
 .../DesignWare/Include/Protocol/EfiUsbFnIo.h  |  430 ++
 .../Include/Protocol/UsbDeviceModeProtocol.h  |  104 +
 22 files changed, 12352 insertions(+)
 create mode 100644 Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/ComponentName.c
 create mode 100644 Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbDeviceDxe.c
 create mode 100644 Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbDeviceDxe.h
 create mode 100644 Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbDeviceDxe.inf
 create mode 100644 Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbDeviceMode.c
 create mode 100644 Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbDeviceMode.h
 create mode 100644 Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbFuncIo.c
 create mode 100644 Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbFuncIo.h
 create mode 100644 Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbIoNode.c
 create mode 100644 Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbIoNode.h
 create mode 100644 Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciCommon.h
 create mode 100644 Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciDWC.c
 create mode 100644 Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciDWC.h
 create mode 100644 Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciDevice.c
 create mode 100644 Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciDevice.h
 create mode 100644 Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciInterface.h
 create mode 100644 Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciTable.c
 create mode 100644 Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciUtility.c
 create mode 100644 Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciUtility.h
 create mode 100644 Silicon/Synopsys/DesignWare/Include/Library/UsbDeviceLib.h
 create mode 100644 Silicon/Synopsys/DesignWare/Include/Protocol/EfiUsbFnIo.h
 create mode 100644 Silicon/Synopsys/DesignWare/Include/Protocol/UsbDeviceModeProtocol.h

diff --git a/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/ComponentName.c b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/ComponentName.c
new file mode 100644
index 0000000000..acb4b6a23d
--- /dev/null
+++ b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/ComponentName.c
@@ -0,0 +1,305 @@
+/** @file
+  Copyright (c) 2004 - 2017, Intel Corporation. All rights reserved.<BR>
+
+  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.
+
+**/
+
+#include <Uefi.h>
+#include <Library/UefiLib.h>
+
+
+/**
+  Retrieves a Unicode string that is the user readable name of the driver.
+
+  This function retrieves the user readable name of a driver in the form of a
+  Unicode string. If the driver specified by This has a user readable name in
+  the language specified by Language, then a pointer to the driver name is
+  returned in DriverName, and EFI_SUCCESS is returned. If the driver specified
+  by This does not support the language specified by Language,
+  then EFI_UNSUPPORTED is returned.
+
+  @param  This[in]              A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
+                                EFI_COMPONENT_NAME_PROTOCOL instance.
+
+  @param  Language[in]          A pointer to a Null-terminated ASCII string
+                                array indicating the language. This is the
+                                language of the driver name that the caller is
+                                requesting, and it must match one of the
+                                languages specified in SupportedLanguages. The
+                                number of languages supported by a driver is up
+                                to the driver writer. Language is specified
+                                in RFC 4646 or ISO 639-2 language code format.
+
+  @param  DriverName[out]       A pointer to the Unicode string to return.
+                                This Unicode string is the name of the
+                                driver specified by This in the language
+                                specified by Language.
+
+  @retval EFI_SUCCESS           The Unicode string for the Driver specified by
+                                This and the language specified by Language was
+                                returned in DriverName.
+
+  @retval EFI_INVALID_PARAMETER Language is NULL.
+
+  @retval EFI_INVALID_PARAMETER DriverName is NULL.
+
+  @retval EFI_UNSUPPORTED       The driver specified by This does not support
+                                the language specified by Language.
+
+**/
+EFI_STATUS
+EFIAPI
+UsbDeviceDxeGetDriverName (
+  IN  EFI_COMPONENT_NAME_PROTOCOL  *This,
+  IN  CHAR8                        *Language,
+  OUT CHAR16                       **DriverName
+  );
+
+
+/**
+  Retrieves a Unicode string that is the user readable name of the controller
+  that is being managed by a driver.
+
+  This function retrieves the user readable name of the controller specified by
+  ControllerHandle and ChildHandle in the form of a Unicode string. If the
+  driver specified by This has a user readable name in the language specified by
+  Language, then a pointer to the controller name is returned in ControllerName,
+  and EFI_SUCCESS is returned.  If the driver specified by This is not currently
+  managing the controller specified by ControllerHandle and ChildHandle,
+  then EFI_UNSUPPORTED is returned.  If the driver specified by This does not
+  support the language specified by Language, then EFI_UNSUPPORTED is returned.
+
+  @param  This[in]              A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
+                                EFI_COMPONENT_NAME_PROTOCOL instance.
+
+  @param  ControllerHandle[in]  The handle of a controller that the driver
+                                specified by This is managing.  This handle
+                                specifies the controller whose name is to be
+                                returned.
+
+  @param  ChildHandle[in]       The handle of the child controller to retrieve
+                                the name of.  This is an optional parameter that
+                                may be NULL.  It will be NULL for device
+                                drivers.  It will also be NULL for a bus drivers
+                                that wish to retrieve the name of the bus
+                                controller.  It will not be NULL for a bus
+                                driver that wishes to retrieve the name of a
+                                child controller.
+
+  @param  Language[in]          A pointer to a Null-terminated ASCII string
+                                array indicating the language.  This is the
+                                language of the driver name that the caller is
+                                requesting, and it must match one of the
+                                languages specified in SupportedLanguages. The
+                                number of languages supported by a driver is up
+                                to the driver writer. Language is specified in
+                                RFC 4646 or ISO 639-2 language code format.
+
+  @param  ControllerName[out]   A pointer to the Unicode string to return.
+                                This Unicode string is the name of the
+                                controller specified by ControllerHandle and
+                                ChildHandle in the language specified by
+                                Language from the point of view of the driver
+                                specified by This.
+
+  @retval EFI_SUCCESS           The Unicode string for the user readable name in
+                                the language specified by Language for the
+                                driver specified by This was returned in
+                                DriverName.
+
+  @retval EFI_INVALID_PARAMETER ControllerHandle is NULL.
+
+  @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid
+                                EFI_HANDLE.
+
+  @retval EFI_INVALID_PARAMETER Language is NULL.
+
+  @retval EFI_INVALID_PARAMETER ControllerName is NULL.
+
+  @retval EFI_UNSUPPORTED       The driver specified by This is not currently
+                                managing the controller specified by
+                                ControllerHandle and ChildHandle.
+
+  @retval EFI_UNSUPPORTED       The driver specified by This does not support
+                                the language specified by Language.
+
+**/
+EFI_STATUS
+EFIAPI
+UsbDeviceDxeGetControllerName (
+  IN  EFI_COMPONENT_NAME_PROTOCOL                     *This,
+  IN  EFI_HANDLE                                      ControllerHandle,
+  IN  EFI_HANDLE                                      ChildHandle        OPTIONAL,
+  IN  CHAR8                                           *Language,
+  OUT CHAR16                                          **ControllerName
+  );
+
+
+//
+// EFI Component Name Protocol
+//
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME_PROTOCOL  mUsbDeviceDxeComponentName = {
+  UsbDeviceDxeGetDriverName,
+  UsbDeviceDxeGetControllerName,
+  "eng"
+};
+
+//
+// EFI Component Name 2 Protocol
+//
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME2_PROTOCOL mUsbDeviceDxeComponentName2 = {
+  (EFI_COMPONENT_NAME2_GET_DRIVER_NAME) UsbDeviceDxeGetDriverName,
+  (EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME) UsbDeviceDxeGetControllerName,
+  "en"
+};
+
+
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mUsbDeviceDxeDriverNameTable[] = {
+  { "eng;en", L"Usb Device Driver" },
+  { NULL , NULL }
+};
+
+/**
+  Retrieves a Unicode string that is the user readable name of the driver.
+
+  This function retrieves the user readable name of a driver in the form of a
+  Unicode string. If the driver specified by This has a user readable name in
+  the language specified by Language, then a pointer to the driver name is
+  returned in DriverName, and EFI_SUCCESS is returned. If the driver specified
+  by This does not support the language specified by Language,
+  then EFI_UNSUPPORTED is returned.
+
+  @param  This[in]              A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
+                                EFI_COMPONENT_NAME_PROTOCOL instance.
+
+  @param  Language[in]          A pointer to a Null-terminated ASCII string
+                                array indicating the language. This is the
+                                language of the driver name that the caller is
+                                requesting, and it must match one of the
+                                languages specified in SupportedLanguages. The
+                                number of languages supported by a driver is up
+                                to the driver writer. Language is specified
+                                in RFC 4646 or ISO 639-2 language code format.
+
+  @param  DriverName[out]       A pointer to the Unicode string to return.
+                                This Unicode string is the name of the
+                                driver specified by This in the language
+                                specified by Language.
+
+  @retval EFI_SUCCESS           The Unicode string for the Driver specified by
+                                This and the language specified by Language was
+                                returned in DriverName.
+
+  @retval EFI_INVALID_PARAMETER Language is NULL.
+
+  @retval EFI_INVALID_PARAMETER DriverName is NULL.
+
+  @retval EFI_UNSUPPORTED       The driver specified by This does not support
+                                the language specified by Language.
+
+**/
+EFI_STATUS
+EFIAPI
+UsbDeviceDxeGetDriverName (
+  IN  EFI_COMPONENT_NAME_PROTOCOL  *This,
+  IN  CHAR8                        *Language,
+  OUT CHAR16                       **DriverName
+  )
+{
+  return LookupUnicodeString2 (
+           Language,
+           This->SupportedLanguages,
+           mUsbDeviceDxeDriverNameTable,
+           DriverName,
+           (BOOLEAN)(This == &mUsbDeviceDxeComponentName)
+           );
+}
+
+/**
+  Retrieves a Unicode string that is the user readable name of the controller
+  that is being managed by a driver.
+
+  This function retrieves the user readable name of the controller specified by
+  ControllerHandle and ChildHandle in the form of a Unicode string. If the
+  driver specified by This has a user readable name in the language specified by
+  Language, then a pointer to the controller name is returned in ControllerName,
+  and EFI_SUCCESS is returned.  If the driver specified by This is not currently
+  managing the controller specified by ControllerHandle and ChildHandle,
+  then EFI_UNSUPPORTED is returned.  If the driver specified by This does not
+  support the language specified by Language, then EFI_UNSUPPORTED is returned.
+
+  @param  This[in]              A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
+                                EFI_COMPONENT_NAME_PROTOCOL instance.
+
+  @param  ControllerHandle[in]  The handle of a controller that the driver
+                                specified by This is managing.  This handle
+                                specifies the controller whose name is to be
+                                returned.
+
+  @param  ChildHandle[in]       The handle of the child controller to retrieve
+                                the name of.  This is an optional parameter that
+                                may be NULL.  It will be NULL for device
+                                drivers.  It will also be NULL for a bus drivers
+                                that wish to retrieve the name of the bus
+                                controller.  It will not be NULL for a bus
+                                driver that wishes to retrieve the name of a
+                                child controller.
+
+  @param  Language[in]          A pointer to a Null-terminated ASCII string
+                                array indicating the language.  This is the
+                                language of the driver name that the caller is
+                                requesting, and it must match one of the
+                                languages specified in SupportedLanguages. The
+                                number of languages supported by a driver is up
+                                to the driver writer. Language is specified in
+                                RFC 4646 or ISO 639-2 language code format.
+
+  @param  ControllerName[out]   A pointer to the Unicode string to return.
+                                This Unicode string is the name of the
+                                controller specified by ControllerHandle and
+                                ChildHandle in the language specified by
+                                Language from the point of view of the driver
+                                specified by This.
+
+  @retval EFI_SUCCESS           The Unicode string for the user readable name in
+                                the language specified by Language for the
+                                driver specified by This was returned in
+                                DriverName.
+
+  @retval EFI_INVALID_PARAMETER ControllerHandle is not a valid EFI_HANDLE.
+
+  @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid
+                                EFI_HANDLE.
+
+  @retval EFI_INVALID_PARAMETER Language is NULL.
+
+  @retval EFI_INVALID_PARAMETER ControllerName is NULL.
+
+  @retval EFI_UNSUPPORTED       The driver specified by This is not currently
+                                managing the controller specified by
+                                ControllerHandle and ChildHandle.
+
+  @retval EFI_UNSUPPORTED       The driver specified by This does not support
+                                the language specified by Language.
+
+**/
+EFI_STATUS
+EFIAPI
+UsbDeviceDxeGetControllerName (
+  IN  EFI_COMPONENT_NAME_PROTOCOL                     *This,
+  IN  EFI_HANDLE                                      ControllerHandle,
+  IN  EFI_HANDLE                                      ChildHandle        OPTIONAL,
+  IN  CHAR8                                           *Language,
+  OUT CHAR16                                          **ControllerName
+  )
+{
+  return EFI_UNSUPPORTED;
+}
+
diff --git a/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbDeviceDxe.c b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbDeviceDxe.c
new file mode 100644
index 0000000000..2732cc2e31
--- /dev/null
+++ b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbDeviceDxe.c
@@ -0,0 +1,395 @@
+/** @file
+  Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR>
+
+  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.
+
+**/
+
+#include "UsbDeviceDxe.h"
+#include <Guid/EventGroup.h>
+
+EFI_DRIVER_BINDING_PROTOCOL mUsbDeviceDxeDriverBinding = {
+  UsbDeviceDxeDriverSupported,
+  UsbDeviceDxeDriverStart,
+  UsbDeviceDxeDriverStop,
+  0x1,
+  NULL,
+  NULL
+};
+
+
+
+VOID
+EFIAPI
+PlatformSpecificInit (
+  VOID
+  )
+{
+  UINTN                 XhciPciMmBase;
+  EFI_PHYSICAL_ADDRESS  XhciMemBaseAddress;
+
+  XhciPciMmBase   = MmPciAddress (
+                      0,
+                      0,
+                      PCI_DEVICE_NUMBER_XHCI,
+                      PCI_FUNCTION_NUMBER_XHCI,
+                      0
+                      );
+
+
+  XhciMemBaseAddress = MmioRead32 ((UINTN) (XhciPciMmBase + R_XHCI_MEM_BASE)) & B_XHCI_MEM_BASE_BA;
+  DEBUG ((DEBUG_INFO, "XhciPciMmBase=%x, XhciMemBaseAddress=%x\n", XhciPciMmBase, XhciMemBaseAddress));
+
+  MmioWrite32 ((UINTN)(XhciMemBaseAddress + R_XHCI_MEM_DUAL_ROLE_CFG0), 0x1310800);
+
+  PmicUSBSwitchControl (TRUE);//conduction USB switch.
+  return;
+}
+
+
+VOID
+EFIAPI
+UsbDeviceDxeExitBootService (
+  EFI_EVENT  Event,
+  VOID       *Context
+  )
+{
+  USB_XDCI_DEV_CONTEXT  *UsbXdciDevContext;
+
+  UsbXdciDevContext = (USB_XDCI_DEV_CONTEXT *) Context;
+  DEBUG ((EFI_D_INFO, "UsbDeviceDxeExitBootService enter\n"));
+
+  if (UsbXdciDevContext->XdciPollTimer != NULL) {
+    gBS->SetTimer (UsbXdciDevContext->XdciPollTimer, TimerCancel, 0);
+    gBS->CloseEvent (UsbXdciDevContext->XdciPollTimer);
+    UsbXdciDevContext->XdciPollTimer = NULL;
+    }
+
+  return;
+}
+
+/**
+  The USB bus driver entry pointer.
+
+  @param ImageHandle       The driver image handle.
+  @param SystemTable       The system table.
+
+  @return EFI_SUCCESS      The component name protocol is installed.
+  @return Others           Failed to init the usb driver.
+
+**/
+EFI_STATUS
+EFIAPI
+UsbDeviceDxeEntryPoint (
+  IN EFI_HANDLE           ImageHandle,
+  IN EFI_SYSTEM_TABLE     *SystemTable
+  )
+{
+  return EfiLibInstallDriverBindingComponentName2 (
+           ImageHandle,
+           SystemTable,
+           &mUsbDeviceDxeDriverBinding,
+           ImageHandle,
+           &mUsbDeviceDxeComponentName,
+           &mUsbDeviceDxeComponentName2
+           );
+}
+
+/**
+  Check whether USB bus driver support this device.
+
+  @param  This                   The USB bus driver binding protocol.
+  @param  Controller             The controller handle to check.
+  @param  RemainingDevicePath    The remaining device path.
+
+  @retval EFI_SUCCESS            The bus supports this controller.
+  @retval EFI_UNSUPPORTED        This device isn't supported.
+
+**/
+EFI_STATUS
+EFIAPI
+UsbDeviceDxeDriverSupported (
+  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
+  IN EFI_HANDLE                   Controller,
+  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath
+  )
+{
+  EFI_STATUS                Status;
+  EFI_PCI_IO_PROTOCOL       *PciIo;
+  USB_CLASSC                UsbClassCReg;
+
+
+  Status = gBS->OpenProtocol (
+                  Controller,
+                  &gEfiPciIoProtocolGuid,
+                  (VOID **) &PciIo,
+                  This->DriverBindingHandle,
+                  Controller,
+                  EFI_OPEN_PROTOCOL_BY_DRIVER
+                  );
+
+  if (EFI_ERROR (Status)) {
+    return EFI_UNSUPPORTED;
+  }
+
+  Status = PciIo->Pci.Read (
+                        PciIo,
+                        EfiPciIoWidthUint8,
+                        PCI_CLASSCODE_OFFSET,
+                        sizeof (USB_CLASSC) / sizeof (UINT8),
+                        &UsbClassCReg
+                        );
+
+  if (EFI_ERROR (Status)) {
+    Status = EFI_UNSUPPORTED;
+    goto ON_EXIT;
+  }
+
+  //
+  // Test whether the controller belongs to USB device type
+  //
+  // 0x0C03FE / 0x0C0380
+  //
+  if ((UsbClassCReg.BaseCode != PCI_CLASS_SERIAL) ||
+      (UsbClassCReg.SubClassCode != PCI_CLASS_SERIAL_USB) ||
+      ((UsbClassCReg.ProgInterface != PCI_IF_USBDEV) && (UsbClassCReg.ProgInterface != 0x80))) {
+    Status = EFI_UNSUPPORTED;
+  }
+
+ON_EXIT:
+  gBS->CloseProtocol (
+         Controller,
+         &gEfiPciIoProtocolGuid,
+         This->DriverBindingHandle,
+         Controller
+         );
+
+  return Status;
+}
+
+
+/**
+  Start to process the controller.
+
+  @param  This                   The USB bus driver binding instance.
+  @param  Controller             The controller to check.
+  @param  RemainingDevicePath    The remaining device patch.
+
+  @retval EFI_SUCCESS            The controller is controlled by the usb bus.
+  @retval EFI_ALREADY_STARTED    The controller is already controlled by the usb
+                                 bus.
+  @retval EFI_OUT_OF_RESOURCES   Failed to allocate resources.
+
+**/
+EFI_STATUS
+EFIAPI
+UsbDeviceDxeDriverStart (
+  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
+  IN EFI_HANDLE                   Controller,
+  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath
+  )
+{
+  EFI_STATUS            Status;
+  USB_XDCI_DEV_CONTEXT  *UsbXdciDevContext;
+  EFI_PCI_IO_PROTOCOL   *PciIo;
+  EFI_EVENT             ExitBootServicesEvent;
+
+  DEBUG ((USB_FUIO_DEBUG_LOAD, "UsbFunIoEntryPoint - Entry\n"));
+
+  UsbXdciDevContext = NULL;
+
+  //
+  // Provide protocol interface
+  //
+  //
+  // Get the PCI I/O Protocol on PciHandle
+  //
+  Status = gBS->OpenProtocol (
+                  Controller,
+                  &gEfiPciIoProtocolGuid,
+                  (VOID **) &PciIo,
+                  This->DriverBindingHandle,
+                  Controller,
+                  EFI_OPEN_PROTOCOL_BY_DRIVER
+                  );
+
+  if (EFI_ERROR (Status)) {
+    goto ErrorExit;
+  }
+
+  UsbXdciDevContext = AllocateZeroPool (sizeof (USB_XDCI_DEV_CONTEXT));
+  if (UsbXdciDevContext == NULL) {
+    Status = EFI_OUT_OF_RESOURCES;
+    goto ErrorExit;
+  }
+
+  //
+  // Initialize the driver context
+  //
+  UsbXdciDevContext->StartUpController = FALSE;
+  UsbXdciDevContext->XdciHandle = Controller;
+  UsbXdciDevContext->FirstNodePtr = NULL;
+  UsbXdciDevContext->Signature = EFI_USB_DEV_SIGNATURE;
+
+  PciIo->Pci.Read (
+               PciIo,
+               EfiPciIoWidthUint32,
+               R_OTG_BAR0,
+               1,
+               &UsbXdciDevContext->XdciMmioBarAddr
+               );
+
+  UsbXdciDevContext->XdciMmioBarAddr &= B_OTG_BAR0_BA;
+  DEBUG ((USB_FUIO_DEBUG_INFO, "USB DEV mode IO addr 0x%08x\n", UsbXdciDevContext->XdciMmioBarAddr));
+
+  CopyMem (
+    &(UsbXdciDevContext->UsbFunIoProtocol),
+    &mUsbFunIoProtocol,
+    sizeof (EFI_USBFN_IO_PROTOCOL)
+    );
+
+  CopyMem (
+    &(UsbXdciDevContext->UsbDevModeProtocol),
+    &mUsbDeviceModeProtocol,
+    sizeof (EFI_USB_DEVICE_MODE_PROTOCOL)
+    );
+
+  Status = gBS->CreateEventEx (
+                  EVT_NOTIFY_SIGNAL,
+                  TPL_NOTIFY,
+                  UsbDeviceDxeExitBootService,
+                  UsbXdciDevContext,
+                  &gEfiEventExitBootServicesGuid,
+                  &ExitBootServicesEvent
+                  );
+  if (EFI_ERROR (Status)) {
+    goto ErrorExit;
+  }
+
+  Status = gBS->InstallMultipleProtocolInterfaces (
+                  &UsbXdciDevContext->XdciHandle,
+                  &gEfiUsbFnIoProtocolGuid,
+                  &UsbXdciDevContext->UsbFunIoProtocol,
+                  &gEfiUsbDeviceModeProtocolGuid,
+                  &UsbXdciDevContext->UsbDevModeProtocol,
+                  NULL
+                  );
+  if (EFI_ERROR (Status)) {
+    DEBUG ((USB_FUIO_DEBUG_ERROR, "ERROR - Failed to install upper protocol, Status: %r\n", Status));
+    goto ErrorExit;
+  }
+
+  DEBUG ((USB_FUIO_DEBUG_LOAD, "Done - install upper protocol complete\n"));
+  DEBUG ((USB_FUIO_DEBUG_LOAD, "UsbFunIoEntryPoint - Exit\n"));
+  return Status;
+
+ErrorExit:
+  gBS->CloseProtocol (
+         Controller,
+         &gEfiPciIoProtocolGuid,
+         This->DriverBindingHandle,
+         Controller
+         );
+
+  if (UsbXdciDevContext != NULL) {
+    if (UsbXdciDevContext->XdciPollTimer != NULL) {
+      gBS->CloseEvent (UsbXdciDevContext->XdciPollTimer);
+      UsbXdciDevContext->XdciPollTimer = NULL;
+    }
+    FreePool (UsbXdciDevContext);
+  }
+
+  DEBUG ((USB_FUIO_DEBUG_ERROR, "ERROR - UsbFunIoEntryPoint - Exit\n"));
+  return Status;
+}
+
+/**
+  Stop handle the controller by this USB bus driver.
+
+  @param  This                   The USB bus driver binding protocol.
+  @param  Controller             The controller to release.
+  @param  NumberOfChildren       The child of USB bus that opened controller
+                                 BY_CHILD.
+  @param  ChildHandleBuffer      The array of child handle.
+
+  @retval EFI_SUCCESS            The controller or children are stopped.
+  @retval EFI_DEVICE_ERROR       Failed to stop the driver.
+
+**/
+EFI_STATUS
+EFIAPI
+UsbDeviceDxeDriverStop (
+  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
+  IN EFI_HANDLE                   Controller,
+  IN UINTN                        NumberOfChildren,
+  IN EFI_HANDLE                   *ChildHandleBuffer
+  )
+{
+  EFI_USBFN_IO_PROTOCOL           *UsbFunIoProtocol;
+  EFI_STATUS                      Status;
+  USB_XDCI_DEV_CONTEXT            *UsbXdciDevContext;
+
+
+  //
+  // Locate USB_BUS for the current host controller
+  //
+  Status = gBS->OpenProtocol (
+                  Controller,
+                  &gEfiUsbFnIoProtocolGuid,
+                  (VOID **)&UsbFunIoProtocol,
+                  This->DriverBindingHandle,
+                  Controller,
+                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
+                  );
+
+
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  UsbXdciDevContext = USBFUIO_CONTEXT_FROM_PROTOCOL (UsbFunIoProtocol);
+
+  //
+  // free pool
+  //
+  while (UsbXdciDevContext->FirstNodePtr != NULL) {
+    RemoveNode (UsbFunIoProtocol, UsbXdciDevContext->FirstNodePtr);
+  }
+
+  Status = gBS->UninstallMultipleProtocolInterfaces (
+                  UsbXdciDevContext->XdciHandle,
+                  &gEfiUsbFnIoProtocolGuid,
+                  &UsbXdciDevContext->UsbFunIoProtocol,
+                  &gEfiUsbDeviceModeProtocolGuid,
+                  &UsbXdciDevContext->UsbDevModeProtocol,
+                  NULL
+                  );
+
+  if (UsbXdciDevContext->StartUpController == TRUE) {
+    Status = StopController (UsbFunIoProtocol);
+    DEBUG ((USB_FUIO_DEBUG_INFO, "USB DEV mode STOP UsbFnDeInitDevice %r\n", Status));
+  }
+
+  if (UsbXdciDevContext->XdciPollTimer != NULL) {
+    gBS->SetTimer (UsbXdciDevContext->XdciPollTimer, TimerCancel, 0);
+    gBS->CloseEvent (UsbXdciDevContext->XdciPollTimer);
+    UsbXdciDevContext->XdciPollTimer = NULL;
+  }
+
+  gBS->CloseProtocol (
+         Controller,
+         &gEfiPciIoProtocolGuid,
+         This->DriverBindingHandle,
+         Controller
+         );
+
+  FreePool (UsbXdciDevContext);
+  return EFI_SUCCESS;
+}
+
diff --git a/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbDeviceDxe.h b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbDeviceDxe.h
new file mode 100644
index 0000000000..36620f9b12
--- /dev/null
+++ b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbDeviceDxe.h
@@ -0,0 +1,159 @@
+/** @file
+  Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR>
+
+  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.
+
+**/
+
+#ifndef __USB_DEVICE_DXE_H__
+#define __USB_DEVICE_DXE_H__
+
+#include <Uefi.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/DriverLib.h>
+#include <Library/PcdLib.h>
+#include <Library/IoLib.h>
+#include <Protocol/EfiUsbFnIo.h>
+#include <Protocol/UsbDeviceModeProtocol.h>
+#include <PlatformBaseAddresses.h>
+#include <ScAccess.h>
+#include "UsbFuncIo.h"
+#include "UsbDeviceMode.h"
+
+
+#define PCI_IF_USBDEV                      0xFE
+
+#define EFI_USB_DEV_SIGNATURE              0x55534244 //"USBD"
+#define USBFUIO_CONTEXT_FROM_PROTOCOL(a)   CR (a, USB_XDCI_DEV_CONTEXT, UsbFunIoProtocol, EFI_USB_DEV_SIGNATURE)
+#define USBUSBD_CONTEXT_FROM_PROTOCOL(a)   CR (a, USB_XDCI_DEV_CONTEXT, UsbDevModeProtocol, EFI_USB_DEV_SIGNATURE)
+
+
+typedef struct _USB_FUIO_EVENT_NODE   USB_FUIO_EVENT_NODE;
+
+#pragma pack(1)
+struct _USB_FUIO_EVENT_NODE{
+  EFI_USBFN_MESSAGE            Message;
+  UINTN                        PayloadSize;
+  EFI_USBFN_MESSAGE_PAYLOAD    Payload;
+  USB_FUIO_EVENT_NODE          *Nextptr;
+};
+
+typedef struct {
+  UINTN                         Signature;
+  UINTN                         XdciMmioBarAddr;
+  EFI_HANDLE                    XdciHandle;
+  //
+  // Timer to handle EndPoint event periodically.
+  //
+  EFI_EVENT                     XdciPollTimer;
+  EFI_USB_DEVICE_MODE_PROTOCOL  UsbDevModeProtocol;
+  EFI_USBFN_IO_PROTOCOL         UsbFunIoProtocol;
+
+  //
+  // Structure members used by UsbFunIoProtocol.
+  //
+  USB_MEM_NODE                  *FirstNodePtr;
+  EFI_USB_DEVICE_INFO           *DevInfoPtr;
+  EFI_USB_CONFIG_INFO           IndexPtrConfig;
+  EFI_USB_INTERFACE_INFO        IndexPtrInteface;
+  USB_DEVICE_ENDPOINT_INFO      IndexPtrInEp;
+  USB_DEVICE_ENDPOINT_INFO      IndexPtrOutEp;
+  XDCI_CORE_HANDLE              *XdciDrvIfHandle;
+  USB_DEV_CORE                  *DrvCore;
+  UINT16                        VendorId;
+  UINT16                        DeviceId;
+  USBD_EP_XFER_REC              EndPointXferRec[DWC_XDCI_MAX_ENDPOINTS];
+  BOOLEAN                       StartUpController;
+  BOOLEAN                       DevReConnect;
+  BOOLEAN                       DevResetFlag;
+  EFI_EVENT                     TimerEvent;
+  USB_FUIO_EVENT_NODE           *EventNodePtr;
+  //
+  // Following structure members are used by UsbDevModeProtocol.
+  //
+
+} USB_XDCI_DEV_CONTEXT;
+#pragma pack()
+
+
+
+/**
+  Check whether USB bus driver support this device.
+
+  @param  This                   The USB bus driver binding protocol.
+  @param  Controller             The controller handle to check.
+  @param  RemainingDevicePath    The remaining device path.
+
+  @retval EFI_SUCCESS            The bus supports this controller.
+  @retval EFI_UNSUPPORTED        This device isn't supported.
+
+**/
+EFI_STATUS
+EFIAPI
+UsbDeviceDxeDriverSupported (
+  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
+  IN EFI_HANDLE                   Controller,
+  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath
+  );
+
+/**
+  Start to process the controller.
+
+  @param  This                   The USB bus driver binding instance.
+  @param  Controller             The controller to check.
+  @param  RemainingDevicePath    The remaining device patch.
+
+  @retval EFI_SUCCESS            The controller is controlled by the usb bus.
+  @retval EFI_ALREADY_STARTED    The controller is already controlled by the usb
+                                 bus.
+  @retval EFI_OUT_OF_RESOURCES   Failed to allocate resources.
+
+**/
+EFI_STATUS
+EFIAPI
+UsbDeviceDxeDriverStart (
+  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
+  IN EFI_HANDLE                   Controller,
+  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath
+  );
+
+/**
+  Stop handle the controller by this USB bus driver.
+
+  @param  This                   The USB bus driver binding protocol.
+  @param  Controller             The controller to release.
+  @param  NumberOfChildren       The child of USB bus that opened controller
+                                 BY_CHILD.
+  @param  ChildHandleBuffer      The array of child handle.
+
+  @retval EFI_SUCCESS            The controller or children are stopped.
+  @retval EFI_DEVICE_ERROR       Failed to stop the driver.
+
+**/
+EFI_STATUS
+EFIAPI
+UsbDeviceDxeDriverStop (
+  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
+  IN EFI_HANDLE                   Controller,
+  IN UINTN                        NumberOfChildren,
+  IN EFI_HANDLE                   *ChildHandleBuffer
+  );
+
+VOID
+EFIAPI
+PlatformSpecificInit (
+  VOID
+  );
+
+extern EFI_COMPONENT_NAME_PROTOCOL    mUsbDeviceDxeComponentName;
+extern EFI_COMPONENT_NAME2_PROTOCOL   mUsbDeviceDxeComponentName2;
+
+#endif
+
diff --git a/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbDeviceDxe.inf b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbDeviceDxe.inf
new file mode 100644
index 0000000000..acf5021327
--- /dev/null
+++ b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbDeviceDxe.inf
@@ -0,0 +1,74 @@
+## @file
+#
+#  Copyright (c) 2008 - 2017, Intel Corporation. All rights reserved.<BR>
+#
+#  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.
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = UsbDeviceDxe
+  FILE_GUID                      = 42CF2D4A-78B4-4B80-80F9-96A83A630D70
+  MODULE_TYPE                    = UEFI_DRIVER
+  VERSION_STRING                 = 1.0
+  ENTRY_POINT                    = UsbDeviceDxeEntryPoint
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = IA32 X64
+#
+
+[Sources.common]
+  UsbDeviceDxe.c
+  UsbFuncIo.c
+  UsbIoNode.c
+  ComponentName.c
+  UsbDeviceMode.c
+  XdciDevice.c
+  XdciDWC.c
+  XdciTable.c
+  XdciUtility.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  BroxtonSiPkg/BroxtonSiPkg.dec
+  BroxtonPlatformPkg/PlatformPkg.dec
+
+[LibraryClasses]
+  BaseMemoryLib
+  DebugLib
+  DevicePathLib
+  MemoryAllocationLib
+  TimerLib
+  PcdLib
+  UefiBootServicesTableLib
+  UefiDriverEntryPoint
+  UefiLib
+  PmicLib
+
+[Protocols]
+  gEfiUsbDeviceModeProtocolGuid
+  gEfiUsbFnIoProtocolGuid
+  gEfiPciIoProtocolGuid
+
+[Pcd]
+  gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress
+
+[Guids]
+  gEfiEventExitBootServicesGuid
+
+#[BuildOptions]
+#  MSFT:*_*_*_CC_FLAGS = /D SUPPORT_SUPER_SPEED
+#  GCC:*_*_*_CC_FLAGS = -DSUPPORT_SUPER_SPEED
+
+[Depex]
+  TRUE
+
diff --git a/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbDeviceMode.c b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbDeviceMode.c
new file mode 100644
index 0000000000..48a37a37fb
--- /dev/null
+++ b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbDeviceMode.c
@@ -0,0 +1,1489 @@
+/** @file
+  Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR>
+
+  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.
+
+**/
+
+#include <Base.h>
+#include <Library/BaseLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/IoLib.h>
+#include <PlatformBaseAddresses.h>
+#include <ScAccess.h>
+#include "XdciUtility.h"
+#include "UsbDeviceMode.h"
+#include "UsbDeviceDxe.h"
+
+//
+// Global USBD driver object. This is the main private driver object
+// that contains all data needed for this driver to operate.
+//
+USB_DEVICE_DRIVER_OBJ mDrvObj;
+
+//
+// Global data IO transaction request object
+//
+USB_DEVICE_IO_REQ  mCtrlIoReq = {
+  //
+  // IO information containing the Buffer and data size
+  //
+  {
+    NULL,
+    0,
+  },
+  //
+  // Note: This object is used for Control Ep transfers only
+  // therefore the endpoint info must always be NULL
+  //
+  {
+    NULL,
+    NULL,
+  }
+};
+
+//
+// global flag to signal device event processing loop to run/stop
+//
+BOOLEAN mXdciRun = FALSE;
+
+STATIC VOID
+XhciSwitchSwid(BOOLEAN enable)
+{
+  UINTN                             XhciPciMmBase;
+  EFI_PHYSICAL_ADDRESS              XhciMemBaseAddress;
+  UINT32                            DualRoleCfg0;
+  UINT32                            DualRoleCfg1;
+
+  XhciPciMmBase = MmPciAddress (0, 0, PCI_DEVICE_NUMBER_XHCI, PCI_FUNCTION_NUMBER_XHCI, 0);
+  XhciMemBaseAddress = MmioRead32 ((UINTN) (XhciPciMmBase + R_XHCI_MEM_BASE)) & B_XHCI_MEM_BASE_BA;
+  DEBUG ((DEBUG_INFO, "XhciPciMmBase=%x, XhciMemBaseAddress=%x\n", XhciPciMmBase, XhciMemBaseAddress));
+
+  DualRoleCfg0 = MmioRead32 ((UINTN)(XhciMemBaseAddress + R_XHCI_MEM_DUAL_ROLE_CFG0));
+  if (enable) {
+    DualRoleCfg0 = DualRoleCfg0 | (1 << 24) | (1 << 21) | (1 << 20);
+    DEBUG ((DEBUG_INFO, "DualRoleCfg0 : Set SW ID : 0x%x \n", DualRoleCfg0));
+  }
+  else {
+    DualRoleCfg0 = DualRoleCfg0 & ~(1 << 24) & ~(1 << 21) & ~(1 << 20);
+    DEBUG ((DEBUG_INFO, "DualRoleCfg0 : Clear SW ID : 0x%x \n", DualRoleCfg0));
+  }
+  MmioWrite32 ((UINTN)(XhciMemBaseAddress + R_XHCI_MEM_DUAL_ROLE_CFG0), DualRoleCfg0);
+
+  DualRoleCfg1 = MmioRead32 ((UINTN)(XhciMemBaseAddress + R_XHCI_MEM_DUAL_ROLE_CFG1));
+  DEBUG ((DEBUG_INFO, "DualRoleCfg1 : 0x%x \n", DualRoleCfg1));
+}
+
+VOID
+EFIAPI
+UsbdMonitorEvents (
+  IN EFI_EVENT            Event,
+  IN VOID                 *Context
+  )
+{
+  USB_XDCI_DEV_CONTEXT    *XdciDevContext;
+  UINT32                  EventCount;
+  UINT32                  PreEventCount;
+  UINT32                  LoopCount;
+
+  XdciDevContext = (USB_XDCI_DEV_CONTEXT *) Context;
+  EventCount = UsbRegRead ((UINT32)XdciDevContext->XdciMmioBarAddr, DWC_XDCI_EVNTCOUNT_REG (0));
+  if (EventCount == 0) {
+    return;
+  }
+
+  LoopCount = 0;
+  PreEventCount = EventCount;
+  while (EventCount != 0) {
+    if (UsbDeviceIsrRoutineTimerBased (mDrvObj.XdciDrvObj) != EFI_SUCCESS) {
+      DEBUG ((DEBUG_INFO, "UsbDeviceRun() - Failed to execute event ISR\n"));
+    }
+    EventCount = UsbRegRead ((UINT32)XdciDevContext->XdciMmioBarAddr, DWC_XDCI_EVNTCOUNT_REG (0));
+    if (PreEventCount == EventCount) {
+      LoopCount++;
+      if (LoopCount >= 5) {
+        DEBUG ((DEBUG_INFO, "USB is working on a long event...\n"));
+        break;
+      }
+    } else {
+      LoopCount = 0;
+    }
+  }
+
+  return;
+}
+
+/**
+  Initializes the XDCI core
+
+  @param MmioBar       Address of MMIO BAR
+  @param XdciHndl      Double pointer to for XDCI layer to set as an
+                       opaque handle to the driver to be used in subsequent
+                       interactions with the XDCI layer.
+
+  @return EFI_SUCCESS if successfully initialized XDCI, EFI_DEVICE_ERROR otherwise
+
+**/
+EFI_STATUS
+UsbdInit (
+  IN UINT32    MmioBar,
+  IN VOID      **XdciHndl
+  )
+{
+  EFI_STATUS               Status = EFI_DEVICE_ERROR;
+  USB_DEV_CONFIG_PARAMS    ConfigParams;
+
+  XhciSwitchSwid(TRUE);
+
+  DEBUG ((DEBUG_INFO, "UsbdInit start\n"));
+  ConfigParams.ControllerId = USB_ID_DWC_XDCI;
+  ConfigParams.BaseAddress  = MmioBar;
+  ConfigParams.Role = USB_ROLE_DEVICE;
+  ConfigParams.Speed = USB_SPEED_SUPER;
+
+  Status = UsbDeviceInit (&ConfigParams, XdciHndl);
+
+  DEBUG ((DEBUG_INFO, "UsbdInit status is %x\n", Status));
+  DEBUG ((DEBUG_INFO, "ConfigParams.BaseAddress 0x%x\n", ConfigParams.BaseAddress));
+
+  return Status;
+}
+
+
+/**
+  Copies relevant endpoint data from standard USB endpoint descriptors
+  to the usbEpInfo structure used by the XDCI
+
+  @param EpDest   destination structure
+  @param EpSrc    source structure
+
+  @return VOID
+
+**/
+VOID
+UsbdSetEpInfo (
+  IN USB_EP_INFO                 *EpDest,
+  IN USB_DEVICE_ENDPOINT_INFO    *EpSrc
+  )
+{
+  EFI_USB_ENDPOINT_DESCRIPTOR              *EpDesc = NULL;
+  EFI_USB_ENDPOINT_COMPANION_DESCRIPTOR    *EpCompDesc = NULL;
+
+  //
+  // start by clearing all data in the destination
+  //
+  SetMem (EpDest, sizeof(USB_EP_INFO), 0);
+  EpDesc = EpSrc->EndpointDesc;
+  EpCompDesc = EpSrc->EndpointCompDesc;
+
+  if (EpDesc != NULL) {
+    EpDest->EpNum = EpDesc->EndpointAddress & 0x0F; //Bits 0-3 are ep num
+    EpDest->EpDir = ((EpDesc->EndpointAddress & USB_ENDPOINT_DIR_IN) > 0) ? UsbEpDirIn : UsbEpDirOut;
+    EpDest->EpType = EpDesc->Attributes & USB_ENDPOINT_TYPE_MASK;
+    EpDest->MaxPktSize = EpDesc->MaxPacketSize;
+    EpDest->Interval = EpDesc->Interval;
+  }
+  if (EpCompDesc != NULL) {
+    EpDest->MaxStreams = EpCompDesc->Attributes & USB_EP_BULK_BM_ATTR_MASK;
+    EpDest->BurstSize = EpCompDesc->MaxBurst;
+    EpDest->Mult = EpCompDesc->BytesPerInterval;
+  }
+
+  return;
+}
+
+
+/**
+  Initializes the given endpoint
+
+  @param XdciHndl  Pointer (handle) to the XDCI driver object
+  @param DevEpInfo Pointer to endpoint info structure
+                   for the endpoint to initialize
+
+  @return EFI_SUCCESS if operation succeeded, EFI_DEVICE_ERROR otherwise
+
+**/
+EFI_STATUS
+UsbdInitEp (
+  IN VOID                      *XdciHndl,
+  IN USB_DEVICE_ENDPOINT_INFO  *DevEpInfo
+  )
+{
+  EFI_STATUS   Status = EFI_DEVICE_ERROR;
+  USB_EP_INFO  EpInfo;
+
+  UsbdSetEpInfo (&EpInfo, DevEpInfo);
+  Status = UsbDeviceInitEp (XdciHndl, &EpInfo);
+
+  return Status;
+}
+
+
+/**
+  Callback handler used when transfer operations complete. Calls
+  upper layer routine to handle the operation.
+
+  @param XdciHndl  Pointer (handle) to the XDCI driver object
+  @param XferReq   Pointer to the transfer request structure
+
+  @return VOID
+
+**/
+VOID
+EFIAPI
+UsbdXferDoneHndlr (
+  IN VOID                    *XdciHndl,
+  IN USB_XFER_REQUEST        *XferReq
+  )
+{
+  EFI_USB_DEVICE_XFER_INFO  XferInfo;
+
+  DEBUG ((DEBUG_INFO, "UsbdXferDoneHndlr\n"));
+
+  XferInfo.EndpointNum = (UINT8)XferReq->EpInfo.EpNum;
+  XferInfo.EndpointDir = XferReq->EpInfo.EpDir;
+  XferInfo.EndpointType = XferReq->EpInfo.EpType;
+  XferInfo.Buffer = XferReq->XferBuffer;
+  XferInfo.Length = XferReq->ActualXferLen;
+
+  //
+  // If this is a non-control transfer complete, notify the class driver
+  //
+  if (XferInfo.EndpointNum > 0) {
+    if (mDrvObj.UsbdDevObj->DataCallback != NULL) {
+      mDrvObj.UsbdDevObj->DataCallback (&XferInfo);
+    }
+  }
+
+  return;
+}
+
+
+/**
+  Queue a request to transmit data
+
+  @param XdciHndl  Pointer (handle) to the XDCI driver object
+  @param IoReq     Pointer to IO structure containing details of the
+                   transfer request
+
+  @return EFI_SUCCESS if operation succeeded, EFI_DEVICE_ERROR otherwise
+
+**/
+EFI_STATUS
+UsbdEpTxData (
+  IN VOID               *XdciHndl,
+  IN USB_DEVICE_IO_REQ  *IoReq
+  )
+{
+  EFI_STATUS        Status = EFI_DEVICE_ERROR;
+  USB_XFER_REQUEST  TxReq;
+
+  //
+  //set endpoint data
+  //
+  UsbdSetEpInfo (&(TxReq.EpInfo), &(IoReq->EndpointInfo)); // set endpoint data
+
+  //
+  //if this is a control endpoint, set the number and direction
+  //
+  if (IoReq->EndpointInfo.EndpointDesc == NULL) {
+    TxReq.EpInfo.EpNum = 0;
+    TxReq.EpInfo.EpDir = UsbEpDirIn;
+  }
+
+  //
+  // setup the trasfer request
+  //
+  TxReq.XferBuffer = IoReq->IoInfo.Buffer;
+  TxReq.XferLen = IoReq->IoInfo.Length;
+  TxReq.XferDone = UsbdXferDoneHndlr;
+
+  DEBUG ((DEBUG_INFO,  "TX REQUEST: EpNum: 0x%x, epDir: 0x%x, epType: 0x%x, MaxPktSize: 0x%x\n",\
+          TxReq.EpInfo.EpNum, TxReq.EpInfo.EpDir, TxReq.EpInfo.EpType, TxReq.EpInfo.MaxPktSize));
+
+  Status = UsbXdciDeviceEpTxData (XdciHndl, &TxReq);
+
+  return Status;
+}
+
+
+/**
+  Queue a request to receive data
+
+  @param XdciHndl  Pointer (handle) to the XDCI driver object
+  @param IoReq     Pointer to IO structure containing details of the
+                   receive request
+
+  @return EFI_SUCCESS if operation succeeded, EFI_DEVICE_ERROR otherwise
+
+**/
+EFI_STATUS
+UsbdEpRxData (
+  IN VOID               *XdciHndl,
+  IN USB_DEVICE_IO_REQ  *IoReq
+  )
+{
+  EFI_STATUS        Status = EFI_DEVICE_ERROR;
+  USB_XFER_REQUEST  RxReq;
+  UINT32            ReqPacket;
+
+  DEBUG ((DEBUG_INFO,  "RX REQUEST in: IoReq->IoInfo.Length: 0x%x\n", IoReq->IoInfo.Length));
+  DEBUG ((DEBUG_INFO,  "RX REQUEST in: MaxPacketSize: 0x%x\n", IoReq->EndpointInfo.EndpointDesc->MaxPacketSize));
+
+  if (IoReq->EndpointInfo.EndpointDesc->MaxPacketSize == 0) {
+    return EFI_DEVICE_ERROR;
+  }
+
+  //
+  // set endpoint data
+  //
+  UsbdSetEpInfo (&(RxReq.EpInfo), &(IoReq->EndpointInfo));
+
+  //
+  // setup the trasfer request
+  //
+  RxReq.XferBuffer = IoReq->IoInfo.Buffer;
+
+  //
+  // Transfer length should be multiple of USB packet size.
+  //
+  ReqPacket = IoReq->IoInfo.Length / IoReq->EndpointInfo.EndpointDesc->MaxPacketSize;
+  ReqPacket = ((IoReq->IoInfo.Length % IoReq->EndpointInfo.EndpointDesc->MaxPacketSize) == 0)? ReqPacket : ReqPacket + 1;
+  RxReq.XferLen = ReqPacket * IoReq->EndpointInfo.EndpointDesc->MaxPacketSize;
+
+  RxReq.XferDone = UsbdXferDoneHndlr;
+
+  DEBUG ((DEBUG_INFO,  "RX REQUEST: EpNum: 0x%x, epDir: 0x%x, epType: 0x%x\n",\
+          RxReq.EpInfo.EpNum, RxReq.EpInfo.EpDir, RxReq.EpInfo.EpType));
+  DEBUG ((DEBUG_INFO,  "RX REQUEST send: XferLen: 0x%x\n", RxReq.XferLen));
+
+  Status = UsbXdciDeviceEpRxData (XdciHndl, &RxReq);
+
+  return Status;
+}
+
+
+/**
+  Callback used to handle Reset events from the XDCI
+
+  @param Param Pointer to a generic callback parameter structure
+
+  @return XDCI usb status
+
+**/
+EFI_STATUS
+EFIAPI
+UsbdResetEvtHndlr (
+  IN USB_DEVICE_CALLBACK_PARAM  *Param
+  )
+{
+  EFI_STATUS    Status = EFI_DEVICE_ERROR;
+
+  DEBUG ((DEBUG_INFO, "UsbdResetEvtHndlr\n"));
+
+  //
+  // reset device address to 0
+  //
+  Status = UsbDeviceSetAddress (mDrvObj.XdciDrvObj, 0x0);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_INFO, "UsbdResetHdlr() - Failed to set address in XDCI\n"));
+  }
+
+  return Status;
+}
+
+
+/**
+  Callback used to handle Connection done events from the XDCI
+
+  @param Param Pointer to a generic callback parameter structure
+
+  @return XDCI usb status
+
+**/
+EFI_STATUS
+EFIAPI
+UsbdConnDoneEvtHndlr (
+  IN USB_DEVICE_CALLBACK_PARAM *Param
+  )
+{
+  EFI_STATUS    Status = EFI_DEVICE_ERROR;
+
+  DEBUG ((DEBUG_INFO, "UsbdConnDoneEvtHndlr\n"));
+
+  //
+  //reset device address to 0
+  //
+  Status = UsbDeviceSetAddress (mDrvObj.XdciDrvObj, 0x0);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_INFO, "UsbdConnDoneHdlr() - Failed to set address in XDCI\n"));
+  }
+
+  //
+  // set the device state to attached/connected
+  //
+  mDrvObj.State = UsbDevStateAttached;
+
+  return Status;
+}
+
+
+/**
+  Callback used to handle Control Endpoint Setup events from the XDCI
+
+  @param Param Pointer to a generic callback parameter structure
+
+  @return XDCI usb status
+
+**/
+EFI_STATUS
+EFIAPI
+UsbdSetupEvtHndlr (
+  IN USB_DEVICE_CALLBACK_PARAM *Param
+  )
+{
+  EFI_STATUS              Status = EFI_SUCCESS;
+  EFI_USB_DEVICE_REQUEST  Req;
+
+  DEBUG ((DEBUG_INFO, "UsbdSetupEvtHndlr\n"));
+
+  //
+  // Fill out request object from the incomming Buffer
+  //
+  CopyMem (&Req, Param->Buffer, sizeof(EFI_USB_DEVICE_REQUEST));
+
+  Status = UsbdSetupHdlr (&Req);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_INFO, "UsbdSetupEvtHndlr: EFI_DEVICE_ERROR\n"));
+  }
+
+  return Status;
+}
+
+
+/**
+ * Callback used to handle XferNotReady events from the XDCI
+ *
+ * @param Param Pointer to a generic callback parameter structure
+ *
+ * @return XDCI usb status
+ */
+EFI_STATUS
+EFIAPI
+UsbdNrdyEvtHndlr (
+  IN USB_DEVICE_CALLBACK_PARAM *Param
+  )
+{
+  DEBUG ((DEBUG_INFO, "UsbdNrdyEvtHndlr\n"));
+  return EFI_SUCCESS;
+}
+
+
+/**
+  Registers callbacks for event handlers with the XDCI layer.
+  The functions will be called as the registered events are triggered.
+
+  @param  XdciHndl to XDCI core driver
+  @return EFI_SUCCESS if successful, EFI_DEVICE_ERROR otherwise
+
+**/
+EFI_STATUS
+UsbdRegisterCallbacks (
+  IN VOID  *XdciHndl
+  )
+{
+  if (UsbDeviceRegisterCallback (XdciHndl, USB_DEVICE_RESET_EVENT, UsbdResetEvtHndlr) != EFI_SUCCESS) {
+    goto UdciRegCallbackError;
+  }
+
+  if (UsbDeviceRegisterCallback (XdciHndl, USB_DEVICE_CONNECTION_DONE, UsbdConnDoneEvtHndlr) != EFI_SUCCESS) {
+    goto UdciRegCallbackError;
+  }
+
+  if (UsbDeviceRegisterCallback (XdciHndl, USB_DEVICE_SETUP_PKT_RECEIVED, UsbdSetupEvtHndlr) != EFI_SUCCESS) {
+    goto UdciRegCallbackError;
+  }
+
+  if (UsbDeviceRegisterCallback (XdciHndl, USB_DEVICE_XFER_NRDY, UsbdNrdyEvtHndlr) != EFI_SUCCESS) {
+    goto UdciRegCallbackError;
+  }
+
+  return EFI_SUCCESS;
+
+UdciRegCallbackError:
+  return EFI_DEVICE_ERROR;
+}
+
+
+/**
+  Returns the configuration descriptor for this device. The data
+  Buffer returned will also contain all downstream interface and
+  endpoint Buffers.
+
+  @param Buffer    Pointer to destination Buffer to copy descriptor data to
+  @param DescIndex the index of the descriptor to return
+  @param ReqLen    the length in bytes of the request Buffer
+  @param DataLen   Pointer whos value is to be filled with the byte count of
+                   data copied to the output Buffer
+
+  @return EFI_SUCCESS if descritor successfully copied, EFI_DEVICE_ERROR otherwise
+
+**/
+EFI_STATUS
+UsbdGetConfigDesc (
+  IN VOID      *Buffer,
+  IN UINT8     DescIndex,
+  IN UINT32    ReqLen,
+  IN UINT32    *DataLen
+  )
+{
+  EFI_STATUS             Status = EFI_DEVICE_ERROR;
+  UINT8                  NumConfigs = 0;
+  UINT32                 ConfigLen = 0;
+  USB_DEVICE_CONFIG_OBJ  *ConfigObj = NULL;
+  VOID                   *Descriptor = 0;
+  UINT32                 Length = 0;
+
+  DEBUG ((DEBUG_INFO, "UsbdGetConfigDesc()\n"));
+
+  //
+  // For a CONFIGURATION request we send back all descriptors branching out
+  // from this descriptor including the INTERFACE and ENDPOINT descriptors
+  //
+  //
+  // Verify the requested configuration exists - check valid index
+  //
+  NumConfigs = mDrvObj.UsbdDevObj->DeviceDesc->NumConfigurations;
+
+  if (DescIndex < NumConfigs) {
+    //
+    // get the configuration object using the index Offset
+    //
+    ConfigObj = (mDrvObj.UsbdDevObj->ConfigObjs + DescIndex);
+    //
+    // get the complete configuration Buffer block including Interface and Endpoint data
+    //
+    Descriptor = ConfigObj->ConfigAll;
+    //
+    // The config descriptor TotalLength has the full value for all desc Buffers
+    //
+    ConfigLen = ConfigObj->ConfigDesc->TotalLength;
+    //
+    // copy the data to the output Buffer
+    //
+    Length = MIN (ReqLen, ConfigLen);
+    CopyMem (Buffer, Descriptor, Length);
+    *DataLen = Length;
+    Status = EFI_SUCCESS;
+  } else {
+    DEBUG ((DEBUG_INFO, "UsbdGetConfigDesc() - Invalid Config index: %i\n", DescIndex));
+  }
+
+  if (Status == EFI_SUCCESS) {
+    if (ConfigObj != NULL) {
+      PrintConfigDescriptor (ConfigObj->ConfigDesc);
+    }
+  }
+
+  return Status;
+}
+
+
+/**
+  Sets the active configuration to the selected configuration index if it exists
+
+  @param CfgValue  the configuration value to set
+
+  @return EFI_SUCCESS if the configuration was set, EFI_DEVICE_ERROR otherwise
+
+**/
+EFI_STATUS
+UsbdSetConfig (
+  UINT8  CfgValue
+  )
+{
+  EFI_STATUS                 Status = EFI_DEVICE_ERROR;
+  UINT8                      numConfigs = 0;
+  USB_DEVICE_CONFIG_OBJ      *pConfigObj = NULL;
+  USB_DEVICE_INTERFACE_OBJ   *pIfObj = NULL;
+  USB_DEVICE_ENDPOINT_OBJ    *pEpObj = NULL;
+  UINT8                      cfgItr = 0;
+  UINT8                      ifItr = 0;
+  UINT8                      epItr = 0;
+  USB_DEVICE_ENDPOINT_INFO   EpInfo;
+  USB_EP_INFO                UsbEpInfo;
+
+  DEBUG ((DEBUG_INFO, "UsbdSetConfig()\n"));
+  //
+  // Verify the requested configuration exists - check valid index
+  //
+  numConfigs = mDrvObj.UsbdDevObj->DeviceDesc->NumConfigurations;
+
+  if (CfgValue != 0) {
+    //
+    // Search for a matching configuration
+    //
+    for (cfgItr = 0; cfgItr < numConfigs; cfgItr++) {
+      pConfigObj = (mDrvObj.UsbdDevObj->ConfigObjs + cfgItr);
+      if (pConfigObj->ConfigDesc->ConfigurationValue == CfgValue) {
+
+        //
+        // Set the active configuration object
+        //
+        mDrvObj.ActiveConfigObj = pConfigObj;
+        //
+        // Find all interface objects for this configuration
+        //
+        for (ifItr = 0; ifItr < pConfigObj->ConfigDesc->NumInterfaces; ifItr++) {
+          pIfObj = (pConfigObj->InterfaceObjs + ifItr);
+          //
+          // Configure the Endpoints in the XDCI
+          //
+          for (epItr = 0; epItr < pIfObj->InterfaceDesc->NumEndpoints; epItr++) {
+            pEpObj = (pIfObj->EndpointObjs + epItr);
+
+            EpInfo.EndpointDesc = pEpObj->EndpointDesc;
+            EpInfo.EndpointCompDesc = pEpObj->EndpointCompDesc;
+
+            if (UsbdInitEp (mDrvObj.XdciDrvObj, &EpInfo) == EFI_SUCCESS) {
+              UsbdSetEpInfo(&UsbEpInfo, &EpInfo);
+              if (UsbDeviceEpEnable (mDrvObj.XdciDrvObj, &UsbEpInfo) == EFI_SUCCESS) {
+                Status = EFI_SUCCESS;
+              } else {
+                DEBUG ((DEBUG_INFO, "UsbdSetConfig() - Failed to enable endpoint\n"));
+              }
+            } else {
+              DEBUG ((DEBUG_INFO, "UsbdSetConfig() - Failed to initialize endpoint\n"));
+            }
+          }
+        }
+        //
+        // Let the class driver know it is configured
+        //
+        if (Status == EFI_SUCCESS) {
+          if (mDrvObj.UsbdDevObj->ConfigCallback != NULL) {
+            mDrvObj.UsbdDevObj->ConfigCallback (CfgValue);
+          }
+        }
+
+        mDrvObj.State = UsbDevStateConfigured; // we are now configured
+
+        break; // break from config search loop
+      }
+    }
+  }
+
+  if (EFI_ERROR (Status)) {
+   DEBUG ((DEBUG_INFO, "UsbdSetConfig() - Invalid requested configuration value: %i\n", CfgValue));
+  }
+
+  return Status;
+}
+
+
+/**
+  Returns the currently active configuration value
+
+  @param Buffer    Pointer to destination Buffer to copy configuration value to
+  @param ReqLen    the length in bytes of the request Buffer
+  @param DataLen   Pointer whos value is to be filled with the byte count of
+                   data copied to the output Buffer
+
+  @return EFI_SUCCESS if config value is successfully copied, EFI_DEVICE_ERROR otherwise
+
+**/
+EFI_STATUS
+UsbdGetConfig (
+  VOID      *Buffer,
+  UINT32    ReqLen,
+  UINT32    *DataLen
+  )
+{
+  EFI_STATUS    Status = EFI_DEVICE_ERROR;
+
+  DEBUG ((DEBUG_INFO, "UsbdGetConfig()\n"));
+
+  if (ReqLen >= 1) { // length of data expected must be 1
+    if (mDrvObj.ActiveConfigObj != NULL) { // assure we have a config active
+      *DataLen = 1; // one byte for ConfigurationValue
+      *(UINT8*)Buffer = mDrvObj.ActiveConfigObj->ConfigDesc->ConfigurationValue;
+
+      Status = EFI_SUCCESS;
+    } else {
+      DEBUG ((DEBUG_INFO, "UsbdGetConfig() - No active configuration available\n"));
+    }
+  } else {
+    DEBUG ((DEBUG_INFO, "UsbdGetConfig() - Invalid data length\n"));
+  }
+
+  return Status;
+}
+
+
+/**
+  Returns the requested string descriptor if it exists
+
+  @param Buffer    Pointer to destination Buffer to copy descriptor data to
+  @param DescIndex the index of the descriptor to return
+  @param LangId    the target language ID
+  @param ReqLen    the length in bytes of the request Buffer
+  @param DataLen   Pointer whos value is to be filled with the byte count of
+                   data copied to the output Buffer
+
+  @return EFI_SUCCESS if descritor successfully copied, EFI_DEVICE_ERROR otherwise
+
+**/
+EFI_STATUS
+UsbdGetStringDesc (
+  VOID      *Buffer,
+  UINT8     DescIndex,
+  UINT16    LangId,
+  UINT32    ReqLen,
+  UINT32    *DataLen
+  )
+{
+  EFI_STATUS             Status = EFI_DEVICE_ERROR;
+  UINT32                 Length = 0;
+  USB_STRING_DESCRIPTOR  *StringDesc;
+  UINT8                  Index = 0;
+  UINT8                  StrLangEntries = 0;
+  BOOLEAN                StrLangFound = FALSE;
+
+  DEBUG ((DEBUG_INFO, "UsbdGetStringDesc: Index: 0x%x, LangId: 0x%x, ReqLen: 0x%x\n", DescIndex, LangId, ReqLen));
+
+  //
+  // index zero of the string table contains the supported language codes
+  //
+  if (DescIndex == 0) {
+    StringDesc = (mDrvObj.UsbdDevObj->StringTable);
+    Length = MIN (ReqLen, StringDesc->Length);
+    CopyMem (Buffer, StringDesc, Length);
+    *DataLen = Length;
+    Status = EFI_SUCCESS;
+  } else {
+
+    //
+    // Verify the requested language ID is supported. String descriptor Zero
+    // (First entry in the string table) is expected to contain the language list.
+    // The requested language ID is specified in the Index member of the request.
+    //
+    StringDesc = mDrvObj.UsbdDevObj->StringTable; // get language string descriptor
+    StrLangEntries = ((StringDesc->Length - 2) >> 1);
+    DEBUG ((DEBUG_INFO, "StrLangEntries=%x\n", StrLangEntries));
+
+    DEBUG ((DEBUG_INFO, "Looking LangID: \n"));
+
+    for (Index = 0; Index < StrLangEntries; Index++) {
+      DEBUG ((DEBUG_INFO, "LangID [%x]= %x\n", Index, StringDesc->LangID [Index]));
+
+      if (StringDesc->LangID [Index] == LangId) {
+        DEBUG ((DEBUG_INFO, "Found it\n"));
+        StrLangFound = TRUE;
+      }
+    }
+
+    //
+    // If we found a matching language, attempt to get the string index requested
+    //
+    if (StrLangFound == TRUE) {
+      DEBUG ((DEBUG_INFO, "UsbdGetStringDesc: StrLangFound=Found, DescIndex=%x, StrTblEntries=%x\n", DescIndex, mDrvObj.UsbdDevObj->StrTblEntries));
+
+      if (DescIndex < mDrvObj.UsbdDevObj->StrTblEntries) {
+        //
+        // get the string descriptor for the requested index
+        //
+        StringDesc = (mDrvObj.UsbdDevObj->StringTable + DescIndex);
+
+        Length = MIN (ReqLen, StringDesc->Length);
+        DEBUG ((DEBUG_INFO, "ReqLen=%x, StringLength=%x, Length=%x\n", ReqLen, StringDesc->Length, Length));
+
+        CopyMem (Buffer, StringDesc, Length);
+        *DataLen = Length;
+        Status = EFI_SUCCESS;
+      } else {
+        DEBUG ((DEBUG_INFO, "UsbdGetStringDesc: Invalid String index in USB_REQ_GET_DESCRIPTOR request\n"));
+      }
+    } else {
+      DEBUG ((DEBUG_INFO, "UsbdGetStringDesc: Unsupported String Language ID for USB_REQ_GET_DESCRIPTOR request\n"));
+    }
+  }
+
+  if (Status == EFI_SUCCESS) {
+    PrintStringDescriptor (StringDesc);
+  }
+  return Status;
+}
+
+
+#ifdef SUPPORT_SUPER_SPEED
+/**
+  Returns the configuration descriptor for this device. The data
+  Buffer returned will also contain all downstream interface and
+  endpoint Buffers.
+
+  @param Buffer    Pointer to destination Buffer to copy descriptor data to
+  @param ReqLen    the length in bytes of the request Buffer
+  @param DataLen   Pointer whos value is to be filled with the byte count of
+                   data copied to the output Buffer
+
+  @return EFI_SUCCESS if descritor successfully copied, EFI_DEVICE_ERROR otherwise
+
+**/
+EFI_STATUS
+UsbdGetBOSDesc (
+  IN VOID      *Buffer,
+  IN UINT32    ReqLen,
+  IN UINT32    *DataLen
+  )
+{
+  EFI_USB_BOS_DESCRIPTOR  *BosDesc = 0;
+  UINT32                  Length = 0;
+
+  DEBUG ((DEBUG_INFO, "UsbdGetBOSDesc()\n"));
+
+  BosDesc = mDrvObj.UsbdDevObj->BosDesc;
+  Length = MIN (ReqLen, mDrvObj.UsbdDevObj->BosDesc->TotalLength);
+
+  CopyMem(Buffer, BosDesc, Length);
+  *DataLen = Length;
+
+  PrintBOSDescriptor (BosDesc);
+
+  return EFI_SUCCESS;
+}
+#endif
+
+/**
+  Returns the current status for Device/Interface/Endpoint
+
+  @param Buffer    Pointer to destination Buffer to copy descriptor data to
+  @param ReqType   The type of status to get
+  @param ReqLen    the length in bytes of the request Buffer
+  @param DataLen   Pointer whos value is to be filled with the byte count of
+                   data copied to the output Buffer
+
+  @return EFI_SUCCESS if status successfully copied, EFI_DEVICE_ERROR otherwise
+
+**/
+EFI_STATUS
+UsbdGetStatus (
+  VOID      *Buffer,
+  UINT8     ReqType,
+  UINT32    ReqLen,
+  UINT32    *DataLen
+  )
+{
+  EFI_STATUS  Status = EFI_DEVICE_ERROR;
+
+  DEBUG ((DEBUG_INFO, "UsbdGetStatus()\n"));
+
+  if (ReqLen >= 2) { // length of data must be at least 2 bytes
+    switch (ReqType & USB_TARGET_MASK) {
+      case USB_TARGET_DEVICE:
+        *DataLen = 2; // two byte for status
+        *(UINT16*)Buffer = USB_STATUS_SELFPOWERED;
+        Status = EFI_SUCCESS;
+        break;
+
+      case USB_TARGET_INTERFACE:
+        //
+        // No implementation needed at this time
+        //
+        break;
+
+      case USB_TARGET_ENDPOINT:
+        //
+        // No implementation needed at this time
+        // Should specify if endpoint is halted. Implement as necessary.
+        //
+        break;
+
+      case USB_TARGET_OTHER:
+        //
+        // No implementation needed at this time
+        //
+        break;
+
+      default:
+        break;
+    }
+  } else {
+    DEBUG ((DEBUG_INFO, "UsbdGetStatus() - Invalid data length\n"));
+  }
+
+  return Status;
+}
+
+
+/**
+  Sets the address of the device
+
+  @param address   the address value to set
+
+  @return EFI_SUCCESS if address was set, EFI_DEVICE_ERROR otherwise
+
+**/
+EFI_STATUS
+UsbdSetAddress (
+  UINT8    Address
+  )
+{
+  EFI_STATUS  Status = EFI_DEVICE_ERROR;
+
+  DEBUG ((DEBUG_INFO, "UsbdSetAddress: setting address: 0x%x\n", Address));
+
+  if (Address <= 0x7F) { // address must not be > 127
+    mDrvObj.Address = Address;
+
+    //
+    // Configure Address in the XDCI
+    //
+    Status = UsbDeviceSetAddress (mDrvObj.XdciDrvObj, mDrvObj.Address);
+    if (!EFI_ERROR (Status)) {
+      mDrvObj.State = UsbDevStateAddress;
+    } else {
+      DEBUG ((DEBUG_INFO, "UsbdSetAddress: Failed to set address in XDCI\n"));
+    }
+  } else {
+    DEBUG ((DEBUG_INFO, "UsbdSetAddress: Invalid address: 0x%x\n", Address));
+  }
+
+  return Status;
+}
+
+
+/**
+  Handles Setup device requests. Standard requests are immediately
+  handled here, and any Class/Vendor specific requests are forwarded
+  to the class driver
+
+  @param CtrlRequest  Pointer to a device request
+
+  @return EFI_SUCCESS if request successfully handled, FALSE otherwise
+
+**/
+EFI_STATUS
+UsbdSetupHdlr (
+  IN EFI_USB_DEVICE_REQUEST    *CtrlRequest
+  )
+{
+  EFI_STATUS              Status = EFI_DEVICE_ERROR;
+  UINT8                   DescIndex = 0;
+  USB_DEVICE_DESCRIPTOR   *DevDesc = 0;
+
+  //
+  // Initialize the IO object
+  //
+  mCtrlIoReq.IoInfo.Length = 0;
+
+  DEBUG ((DEBUG_INFO, "UsbdSetupHdlr start\n"));
+  PrintDeviceRequest (CtrlRequest);
+
+  //
+  // Handle Standard Device Requests
+  //
+  if ((CtrlRequest->RequestType & USB_REQ_TYPE_MASK) == USB_REQ_TYPE_STANDARD) {
+    switch (CtrlRequest->Request) {
+      case USB_REQ_GET_DESCRIPTOR:
+        DEBUG ((DEBUG_INFO, "UsbdSetupHdlr: Host requests get descriptor\n"));
+        if (CtrlRequest->RequestType == USB_RT_TX_DIR_D_TO_H) {
+          DescIndex = (CtrlRequest->Value & 0xff); // low byte is the index requested
+          switch (CtrlRequest->Value >> 8) { // high byte contains request type
+            case USB_DESC_TYPE_DEVICE:
+              DEBUG ((DEBUG_INFO, "Descriptor tyep: Device\n"));
+              DevDesc = mDrvObj.UsbdDevObj->DeviceDesc;
+              //
+              // copy the data to the output Buffer
+              //
+              mCtrlIoReq.IoInfo.Length = MIN (CtrlRequest->Length, DevDesc->Length);
+              CopyMem (mCtrlIoReq.IoInfo.Buffer, DevDesc, mCtrlIoReq.IoInfo.Length);
+              PrintDeviceDescriptor (DevDesc);
+              break;
+
+            case USB_DESC_TYPE_CONFIG:
+              DEBUG ((DEBUG_INFO, "Descriptor tyep: Configuration\n"));
+              Status = UsbdGetConfigDesc (
+                         mCtrlIoReq.IoInfo.Buffer,
+                         DescIndex,
+                         CtrlRequest->Length,
+                         &(mCtrlIoReq.IoInfo.Length)
+                         );
+              break;
+
+            case USB_DESC_TYPE_STRING:
+              DEBUG ((DEBUG_INFO, "Descriptor tyep: String\n"));
+              Status = UsbdGetStringDesc (
+                         mCtrlIoReq.IoInfo.Buffer,
+                         DescIndex,
+                         CtrlRequest->Index,
+                         CtrlRequest->Length,
+                         &(mCtrlIoReq.IoInfo.Length)
+                         );
+              break;
+
+#ifdef SUPPORT_SUPER_SPEED
+            case USB_DESC_TYPE_BOS:
+              DEBUG ((DEBUG_INFO, "Descriptor tyep: BOS\n"));
+              Status = UsbdGetBOSDesc (
+                         mCtrlIoReq.IoInfo.Buffer,
+                         CtrlRequest->Length,
+                         &(mCtrlIoReq.IoInfo.Length)
+                         );
+              break;
+
+            case USB_DESC_TYPE_SS_ENDPOINT_COMPANION:
+              DEBUG ((DEBUG_INFO, "Descriptor tyep: Endpoint Companion\n"));
+              break;
+#endif
+
+            default:
+              DEBUG ((DEBUG_INFO, "Descriptor tyep: Unsupported, USB_REQ_GET_DESCRIPTOR request: 0x%x\n", (CtrlRequest->Value >> 8)));
+              break;
+          }
+        } else {
+          DEBUG ((DEBUG_INFO, "UsbdSetupHdlr() - Invalid direction for USB_REQ_GET_DESCRIPTOR request\n"));
+        }
+        break;
+
+      case USB_REQ_GET_CONFIG:
+        DEBUG ((DEBUG_INFO, "USB_REQ_GET_CONFIG\n"));
+        if (CtrlRequest->RequestType == USB_RT_TX_DIR_D_TO_H) {
+          Status = UsbdGetConfig (mCtrlIoReq.IoInfo.Buffer, CtrlRequest->Length, &(mCtrlIoReq.IoInfo.Length));
+        } else {
+          DEBUG ((DEBUG_INFO, "UsbdSetupHdlr: Invalid direction for USB_REQ_GET_CONFIG request\n"));
+        }
+        break;
+
+      case USB_REQ_SET_CONFIG:
+        DEBUG ((DEBUG_INFO, "USB_REQ_SET_CONFIG\n"));
+        if (CtrlRequest->RequestType == USB_RT_TX_DIR_H_TO_D) {
+          Status = UsbdSetConfig ((UINT8)CtrlRequest->Value);
+        } else {
+          DEBUG ((DEBUG_INFO, "UsbdSetupHdlr: Invalid direction for USB_REQ_SET_CONFIG request\n"));
+        }
+        break;
+
+      case USB_REQ_SET_ADDRESS:
+        DEBUG ((DEBUG_INFO, "USB_REQ_SET_ADDRESS\n"));
+        if (CtrlRequest->RequestType == USB_RT_TX_DIR_H_TO_D) {
+          Status = UsbdSetAddress ((UINT8)CtrlRequest->Value);
+        } else {
+          DEBUG ((DEBUG_INFO, "UsbdSetupHdlr: Invalid direction for USB_REQ_SET_ADDRESS request\n"));
+        }
+        break;
+
+      case USB_REQ_GET_STATUS:
+        DEBUG ((DEBUG_INFO, "USB_REQ_GET_STATUS\n"));
+        if (CtrlRequest->RequestType & USB_RT_TX_DIR_D_TO_H) {
+          Status = UsbdGetStatus (mCtrlIoReq.IoInfo.Buffer, CtrlRequest->RequestType, CtrlRequest->Length, &(mCtrlIoReq.IoInfo.Length));
+        } else {
+          DEBUG ((DEBUG_INFO, "UsbdSetupHdlr: Invalid direction for USB_REQ_GET_STATUS request\n"));
+        }
+        break;
+#ifdef SUPPORT_SUPER_SPEED
+      case USB_REQ_CLEAR_FEATURE:
+      case USB_REQ_SET_FEATURE:
+      case USB_REQ_SET_DESCRIPTOR:
+      case USB_REQ_GET_INTERFACE:
+      case USB_REQ_SET_INTERFACE:
+      case USB_REQ_SYNCH_FRAME:
+#endif
+      default:
+         DEBUG ((DEBUG_INFO, "UsbdSetupHdlr: Unsupported Standard Request: 0x%x\n", CtrlRequest->Request));
+          break;
+    }
+  } else { // This is not a Standard request, it specifies Class/Vendor handling
+    //
+    // Forward request to class driver
+    //
+    DEBUG ((DEBUG_INFO, "UsbdSetupHdlr: Class/Vendor Request\n"));
+    if (mDrvObj.UsbdDevObj->SetupCallback != NULL) {
+      mDrvObj.UsbdDevObj->SetupCallback (CtrlRequest, &(mCtrlIoReq.IoInfo));
+    }
+  }
+
+  DEBUG ((DEBUG_INFO, "dataLen=%x\n", mCtrlIoReq.IoInfo.Length));
+  //
+  // Transfer data according to request if necessary
+  //
+  if (mCtrlIoReq.IoInfo.Length> 0) {
+    Status = UsbdEpTxData (mDrvObj.XdciDrvObj, &mCtrlIoReq);
+    if (EFI_ERROR (Status)) {
+      DEBUG ((DEBUG_INFO, "UsbdSetupHdlr: Failed to TX data\n"));
+    }
+  } else {
+    //
+    // If we are not responding with data, send control status
+    //
+    Status = UsbDeviceEp0TxStatus (mDrvObj.XdciDrvObj);
+    if (EFI_ERROR (Status)) {
+      DEBUG ((DEBUG_INFO, "UsbdSetupHdlr: Failed to Tx Ep0 Status\n"));
+    }
+  }
+
+  return Status;
+}
+
+
+/**
+  Handles Connection done events. Sets the device address to zero.
+
+  @return EFI_SUCCESS if able to set the address, EFI_DEVICE_ERROR otherwise
+
+**/
+EFI_STATUS
+UsbdConnDoneHdlr (
+  VOID
+  )
+{
+  EFI_STATUS    Status = EFI_DEVICE_ERROR;
+
+  DEBUG ((DEBUG_INFO, "UsbdConnDoneHdlr()\n"));
+
+  //
+  // reset device address to 0
+  //
+  Status = UsbDeviceSetAddress (mDrvObj.XdciDrvObj, 0x0);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_INFO, "UsbdConnDoneHdlr() - Failed to set address in XDCI\n"));
+  }
+
+  //
+  // set the device state to attached/connected
+  //
+  mDrvObj.State = UsbDevStateAttached;
+
+  return Status;
+}
+
+
+/**
+  Handles transmit/receive completion events. Directly handles
+  control endpoint events and forwards class/vendor specific events
+  to the class drivers.
+
+  @param   XferInfo   Pointer to Xfer structure
+
+  @return
+
+**/
+VOID
+UsbdXferDoneHdlr (
+  IN EFI_USB_DEVICE_XFER_INFO    *XferInfo
+  )
+{
+  //
+  // If this is a non-control transfer complete, notify the class driver
+  //
+  if (XferInfo->EndpointNum > 0) {
+    if (mDrvObj.UsbdDevObj->DataCallback != NULL) {
+      mDrvObj.UsbdDevObj->DataCallback (XferInfo);
+    }
+  }
+
+  return;
+}
+
+
+/**
+  Binds a USB class driver with this USB device driver core.
+  After calling this routine, the driver is ready to begin
+  USB processing.
+
+  @param  UsbdDevObj   Pointer to a usbd device object which contains
+                       all relevant information for the class driver device
+
+  @return TRUE if binding was successful, FALSE otherwise
+
+**/
+EFI_STATUS
+EFIAPI
+UsbDeviceBind (
+  IN EFI_USB_DEVICE_MODE_PROTOCOL               *This,
+  IN USB_DEVICE_OBJ                             *UsbdDevObj
+  )
+{
+  EFI_STATUS  Status = EFI_SUCCESS;
+
+  //
+  // allocate Tx Buffer
+  //
+  mCtrlIoReq.IoInfo.Buffer = AllocateZeroPool (USB_EPO_MAX_PKT_SIZE_ALL);
+  if (mCtrlIoReq.IoInfo.Buffer != NULL) {
+    mDrvObj.UsbdDevObj = UsbdDevObj;
+    mDrvObj.ActiveConfigObj = NULL;
+    mDrvObj.Address = 0;
+    mDrvObj.State = UsbDevStateInit;
+  } else {
+    DEBUG ((DEBUG_INFO, "UsbDeviceBind() - Failed to allocate IO Buffer\n"));
+    Status = EFI_DEVICE_ERROR;
+  }
+
+  return Status;
+}
+
+
+/**
+  Unbinds the USB class driver from this USB device driver core.
+
+  @return TRUE if successful, FALSE otherwise
+
+**/
+EFI_STATUS
+EFIAPI
+UsbDeviceUnbind (
+  IN EFI_USB_DEVICE_MODE_PROTOCOL               *This
+  )
+{
+  mDrvObj.UsbdDevObj = NULL;
+  mDrvObj.ActiveConfigObj = NULL;
+  mDrvObj.Address = 0;
+  mDrvObj.State = UsbDevStateOff;
+  mDrvObj.XdciInitialized = FALSE;
+
+  //
+  // release allocated Buffer data
+  //
+  if (mCtrlIoReq.IoInfo.Buffer) {
+    FreePool (mCtrlIoReq.IoInfo.Buffer);
+  }
+
+  return EFI_SUCCESS;
+}
+
+
+/**
+  Performs continual USB device event processing until a cancel
+  event occurs
+
+  @param   TimeoutMs   Connection timeout in ms. If 0, waits forever.
+  @return  TRUE if run executed normally, FALSE if error ocurred
+
+**/
+EFI_STATUS
+EFIAPI
+UsbDeviceRun (
+  IN EFI_USB_DEVICE_MODE_PROTOCOL               *This,
+  IN UINT32                                     TimeoutMs
+  )
+{
+  EFI_STATUS              Status = EFI_DEVICE_ERROR;
+  USB_XDCI_DEV_CONTEXT    *XdciDevContext;
+
+  XdciDevContext = USBUSBD_CONTEXT_FROM_PROTOCOL (This);
+
+  //
+  // can only run if XDCI is initialized
+  //
+  if ((mDrvObj.XdciInitialized == TRUE)) {
+
+    if ((mDrvObj.State == UsbDevStateConfigured) && (XdciDevContext->XdciPollTimer == NULL)) {
+      Status = gBS->CreateEvent (
+                      EVT_TIMER | EVT_NOTIFY_SIGNAL,
+                      TPL_NOTIFY,
+                      UsbdMonitorEvents,
+                      XdciDevContext,
+                      &XdciDevContext->XdciPollTimer
+                      );
+      if (!EFI_ERROR (Status)) {
+        Status = gBS->SetTimer (XdciDevContext->XdciPollTimer, TimerPeriodic, EFI_TIMER_PERIOD_MILLISECONDS (20));
+        DEBUG ((EFI_D_ERROR, "UsbDeviceRun Create Event\n"));
+      }
+    }
+
+    mXdciRun = TRUE; // set the run flag to active
+    Status = EFI_SUCCESS;
+
+    //
+    // start the Event processing loop
+    //
+    while (TRUE) {
+      if (XdciDevContext->XdciPollTimer == NULL) {
+        if (UsbDeviceIsrRoutine (mDrvObj.XdciDrvObj) != EFI_SUCCESS) {
+          DEBUG ((DEBUG_INFO, "UsbDeviceRun() - Failed to execute event ISR\n"));
+        }
+      }
+
+      //
+      // Check if a run cancel request exists, if so exit processing loop
+      //
+      if (mXdciRun == FALSE) {
+        if (XdciDevContext->XdciPollTimer != NULL) {
+          DEBUG ((EFI_D_ERROR, "UsbDeviceRun close Event\n"));
+          gBS->SetTimer (XdciDevContext->XdciPollTimer, TimerCancel, 0);
+          gBS->CloseEvent (XdciDevContext->XdciPollTimer);
+          XdciDevContext->XdciPollTimer = NULL;
+        }
+        Status = EFI_SUCCESS;
+        DEBUG ((DEBUG_INFO, "UsbDeviceRun() - processing was cancelled\n"));
+        break;
+      }
+
+      //
+      // check for timeout
+      //
+      if (TimeoutMs == 0)
+        return EFI_TIMEOUT;
+      gBS->Stall (50);
+      TimeoutMs--;
+    }
+  }
+
+  return Status;
+}
+
+
+/**
+  Sets a flag to stop the running device processing loop
+
+  @return TRUE always
+
+**/
+EFI_STATUS
+EFIAPI
+UsbDeviceStop (
+  IN EFI_USB_DEVICE_MODE_PROTOCOL               *This
+  )
+{
+  mXdciRun = FALSE; // set run flag to FALSE to stop processing
+  return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+EFIAPI
+UsbDeviceInitXdci (
+  IN EFI_USB_DEVICE_MODE_PROTOCOL               *This
+  )
+{
+  EFI_STATUS            Status = EFI_DEVICE_ERROR;
+  USB_XDCI_DEV_CONTEXT  *XdciDevContext;
+
+  XdciDevContext = USBUSBD_CONTEXT_FROM_PROTOCOL (This);
+
+  PlatformSpecificInit ();
+
+  if (mDrvObj.XdciInitialized == FALSE) {
+    if (XdciDevContext->XdciMmioBarAddr != 0) {
+
+      //
+      // Initialize device controller driver
+      //
+      DEBUG ((DEBUG_INFO, "UsbDeviceInitXdci() - Initializing Controller...\n"));
+
+      //
+      // Initialize the device controller interface
+      //
+      if (UsbdInit ((UINT32)XdciDevContext->XdciMmioBarAddr, &mDrvObj.XdciDrvObj) == EFI_SUCCESS) {
+
+        //
+        // Setup callbacks
+        //
+        if (UsbdRegisterCallbacks (mDrvObj.XdciDrvObj) == EFI_SUCCESS) {
+
+          mDrvObj.XdciInitialized = TRUE;
+          Status = EFI_SUCCESS;
+
+          DEBUG ((DEBUG_INFO, "UsbDeviceInitXdci() - Controller initialization complete\n"));
+        } else {
+          DEBUG ((DEBUG_INFO, "UsbDeviceInitXdci() - Failed to register UDCI callbacks\n"));
+        }
+      } else {
+        DEBUG ((DEBUG_INFO, "UsbDeviceInitXdci() - Failed to initialize UDCI\n"));
+      }
+    } else {
+      DEBUG ((DEBUG_INFO, "UsbDeviceInitXdci() - XDCI MMIO BAR not set\n"));
+    }
+  } else {
+    DEBUG ((DEBUG_INFO, "UsbDeviceInitXdci() - XDCI already initialized\n"));
+    Status = EFI_ALREADY_STARTED;
+  }
+
+  return Status;
+}
+
+
+EFI_STATUS
+EFIAPI
+UsbDeviceConnect(
+  IN EFI_USB_DEVICE_MODE_PROTOCOL               *This
+  )
+{
+  EFI_STATUS  Status = EFI_DEVICE_ERROR;
+
+  DEBUG ((DEBUG_INFO,  "UsbDeviceConnect \n"));
+  if (UsbXdciDeviceConnect (mDrvObj.XdciDrvObj) == EFI_SUCCESS) {
+    Status = EFI_SUCCESS;
+  }
+  return Status;
+}
+
+
+EFI_STATUS
+EFIAPI
+UsbDeviceDisConnect (
+  IN EFI_USB_DEVICE_MODE_PROTOCOL               *This
+  )
+{
+  EFI_STATUS  Status = EFI_DEVICE_ERROR;
+
+  DEBUG ((DEBUG_INFO,  "UsbDeviceDisConnect \n"));
+  if (UsbDeviceDisconnect (mDrvObj.XdciDrvObj) == EFI_SUCCESS) {
+    mDrvObj.State = UsbDevStateInit;
+    Status = EFI_SUCCESS;
+  }
+
+  XhciSwitchSwid(FALSE);
+  return Status;
+}
+
+
+EFI_STATUS
+EFIAPI
+UsbDeviceEpTxData(
+  IN EFI_USB_DEVICE_MODE_PROTOCOL               *This,
+  IN USB_DEVICE_IO_REQ                          *IoRequest
+  )
+{
+  EFI_STATUS  Status;
+
+  Status = UsbdEpTxData (mDrvObj.XdciDrvObj, IoRequest);
+  return Status;
+}
+
+
+EFI_STATUS
+EFIAPI
+UsbDeviceEpRxData(
+  IN EFI_USB_DEVICE_MODE_PROTOCOL               *This,
+  IN USB_DEVICE_IO_REQ                          *IoRequest
+  )
+{
+  EFI_STATUS  Status;
+
+  Status = UsbdEpRxData (mDrvObj.XdciDrvObj, IoRequest);
+  return Status;
+}
+
+
+//
+// The Runtime UsbDeviceMode Protocol instance produced by this driver
+//
+EFI_USB_DEVICE_MODE_PROTOCOL  mUsbDeviceModeProtocol = {
+  UsbDeviceInitXdci,
+  UsbDeviceConnect,
+  UsbDeviceDisConnect,
+  UsbDeviceEpTxData,
+  UsbDeviceEpRxData,
+  UsbDeviceBind,
+  UsbDeviceUnbind,
+  UsbDeviceRun,
+  UsbDeviceStop
+};
+
diff --git a/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbDeviceMode.h b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbDeviceMode.h
new file mode 100644
index 0000000000..ac9c89b2f1
--- /dev/null
+++ b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbDeviceMode.h
@@ -0,0 +1,39 @@
+/** @file
+  Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR>
+
+  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.
+
+**/
+
+#ifndef _USB_DEVICE_MODE_DXE_H_
+#define _USB_DEVICE_MODE_DXE_H_
+
+#include <Uefi.h>
+#include <PiDxe.h>
+#include <Library/DebugLib.h>
+#include <Library/UefiDriverEntryPoint.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UsbDeviceLib.h>
+#include <Protocol/UsbDeviceModeProtocol.h>
+#include "XdciCommon.h"
+#include "XdciDevice.h"
+
+
+///
+/// Function declaration
+///
+EFI_STATUS
+UsbdSetupHdlr (
+  IN EFI_USB_DEVICE_REQUEST    *CtrlRequest
+  );
+
+extern EFI_USB_DEVICE_MODE_PROTOCOL  mUsbDeviceModeProtocol;
+
+#endif
+
diff --git a/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbFuncIo.c b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbFuncIo.c
new file mode 100644
index 0000000000..a4138328fd
--- /dev/null
+++ b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbFuncIo.c
@@ -0,0 +1,2221 @@
+/** @file
+  Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR>
+
+  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.
+
+**/
+
+#include "UsbDeviceDxe.h"
+
+//
+// 16 bytes in a guid x 2 characters per byte, 4 chars for dashes and a NUL
+//
+#define CHARS_IN_GUID (sizeof(GUID) * 2 + 4 + 1)
+
+//
+// Strings that get sent with the USB Connection
+//
+static CHAR16 mUsbFnDxeMfgString[] = L"Intel Corporation";
+static CHAR16 mUsbFnDxeProductString[] = L"Broxton";
+static CHAR16 mUsbFnDxeSerialNumber[] = L"INT123456";
+
+//
+// Duplicated from MiscSystemManufacturerData.c Some parts of it will
+// replaced with device-specific unique values.
+//
+static GUID mSmBiosUniqueGuid = {
+        0x5e24fe9c, 0xc8d0, 0x45bd, 0xa7, 0x9f, 0x54, 0xea, 0x5f, 0xbd, 0x3d, 0x97
+    };
+
+EFI_USBFN_IO_PROTOCOL         mUsbFunIoProtocol = {
+  EFI_USBFN_IO_PROTOCOL_REVISION,
+  DetectPort,
+  ConfigureEnableEndpoints,
+  GetEndpointMaxPacketSize,
+  GetDeviceInfo,
+  GetVendorIdProductId,
+  AbortTransfer,
+  GetEndpointStallState,
+  SetEndpointStallState,
+  EventHandler,
+  Transfer,
+  GetMaxTransferSize,
+  AllocateTransferBuffer,
+  FreeTransferBuffer,
+  StartController,
+  StopController,
+  SetEndpointPolicy,
+  GetEndpointPolicy
+};
+
+
+EFI_STATUS
+PrintEventBuffer(
+  IN  EFI_USBFN_IO_PROTOCOL  *This
+  )
+{
+  UINT32                          EventCount;
+  USB_XDCI_DEV_CONTEXT            *UsbFuncIoDevPtr;
+  XDCI_CORE_HANDLE                *XdciCorePtr;
+  USB_DEV_CORE                    *UsbDeviceCorePtr;
+  UINT32                          Index;
+  UINT32                          *DbBufPtr;
+
+  UsbFuncIoDevPtr = USBFUIO_CONTEXT_FROM_PROTOCOL (This);
+
+  UsbDeviceCorePtr = UsbFuncIoDevPtr->DrvCore;
+  XdciCorePtr = UsbDeviceCorePtr->ControllerHandle;
+
+  EventCount = UsbRegRead ((UINT32)UsbFuncIoDevPtr->XdciMmioBarAddr, DWC_XDCI_EVNTCOUNT_REG(0));
+
+  DbBufPtr = (UINT32*)(UINTN)XdciCorePtr->CurrentEventBuffer;
+  XdciCorePtr = UsbDeviceCorePtr->ControllerHandle;
+  DEBUG ((USB_FUIO_DEBUG_EVENT_D, "FUEV:: XdciCorePtr->AlignedEventBuffers 0x%08x\n", (UINTN)XdciCorePtr->AlignedEventBuffers));
+  DEBUG ((USB_FUIO_DEBUG_EVENT_D, "FUEV:: DUMP BUF_S\n"));
+  for (Index = 0; Index < ((EventCount / 4) + 1); Index++) {
+    DEBUG ((USB_FUIO_DEBUG_EVENT_D, "0x%08x\n", DbBufPtr[Index]));
+  }
+  DEBUG ((USB_FUIO_DEBUG_EVENT_D, "FUEV:: DUMP BUF_E\n"));
+
+  return EFI_SUCCESS;
+}
+
+/**
+Debug End
+**/
+
+/**
+  Returns information about what type of device was attached.
+
+  @param[in]  This               A pointer to the EFI_USBFN_IO_PROTOCOL instance.
+  @param[out] PortType           Returns the USB port type.
+
+
+  @retval EFI_SUCCESS            The operation completed successfully.
+  @retval EFI_INVALID_PARAMETER  A parameter is invalid.
+  @retval EFI_DEVICE_ERROR       The physical device reported an error.
+  @retval EFI_NOT_READY          The physical device is busy or not ready to
+                                 process this request or the device is not
+                                 attached to the host.
+
+
+**/
+EFI_STATUS
+EFIAPI
+DetectPort (
+  IN  EFI_USBFN_IO_PROTOCOL  *This,
+  OUT EFI_USBFN_PORT_TYPE    *PortType
+  )
+{
+  USB_XDCI_DEV_CONTEXT  *UsbFuncIoDevPtr;
+  EFI_STATUS            Status;
+  UINT8                 Value8;
+
+  DEBUG ((USB_FUIO_DEBUG_INFO, "DetectPort - Entry\n"));
+
+  UsbFuncIoDevPtr = USBFUIO_CONTEXT_FROM_PROTOCOL (This);
+
+  //
+  // USBSRCDETRSLT Bit[5:2]
+  // Result of USB HW Source Detection algorithm
+  // Power-Domain: VRTC
+  // Result of USB HW Source Detection algorithm :
+  // 0000 = Not determined
+  // 0001 = SDP Attached
+  // 0010 = DCP Attached
+  // 0011 = CDP Attached
+  // 0100 = ACA Attached
+  // 0101 = SE1 Attached
+  // 0110 = MHL Attached
+  // 0111 = Floating D+/D- Attached
+  // 1000 = Other Attached
+  // 1001 = DCP detected by ext. USB PHY
+  // 1010-1111 = Rsvd
+  // Reset: 0000B
+  //
+
+  Value8 =PmicRead8 (0x5E, 0X29);
+  if ((Value8 & 0x03) != 0x02) {
+    *PortType = EfiUsbUnknownPort;
+    Status = EFI_NOT_READY;
+    goto out;
+  }
+
+  Value8 = Value8 >> 2 & 0x0f;
+  Status = EFI_SUCCESS;
+  switch (Value8) {
+    case 1:
+      *PortType = EfiUsbStandardDownstreamPort;
+      break;
+    case 2:
+      *PortType = EfiUsbDedicatedChargingPort;
+      break;
+    case 3:
+      *PortType = EfiUsbChargingDownstreamPort;
+      break;
+
+    case 4:
+    case 5:
+    case 6:
+    case 7:
+    case 8:
+    case 9:
+      *PortType = EfiUsbUnknownPort;
+      break;
+    case 0:
+    case 10:
+    case 11:
+    case 12:
+    case 13:
+    case 14:
+    case 15:
+      *PortType = EfiUsbUnknownPort;
+      Status = EFI_NOT_READY;
+     break;
+  }
+
+out:
+  DEBUG ((USB_FUIO_DEBUG_INFO, "DetectPort - Exit\n"));
+  return EFI_SUCCESS;
+}
+
+
+/**
+  The AllocateTransferBuffer function allocates a memory region of Size bytes
+  and returns the address of the allocated memory that satisfies underlying
+  controller requirements in the location referenced by Buffer.
+
+  @param[in] This               A pointer to the EFI_USBFN_IO_PROTOCOL instance.
+  @param[in] Size               The number of bytes to allocate for the transfer
+                                Buffer.
+  @param[in] Buffer             A pointer to a pointer to the allocated Buffer
+                                if the call succeeds; undefined otherwise.
+
+  @retval EFI_SUCCESS           The operation completed successfully.
+  @retval EFI_INVALID_PARAMETER A parameter is invalid.
+  @retval The requested transfer Buffer could not be allocated.
+
+**/
+EFI_STATUS
+EFIAPI
+AllocateTransferBuffer (
+  IN EFI_USBFN_IO_PROTOCOL    *This,
+  IN UINTN                    Size,
+  OUT VOID                    **Buffer
+  )
+{
+  EFI_STATUS            Status;
+  USB_XDCI_DEV_CONTEXT  *UsbFuncIoDevPtr;
+  VOID                  *AllocateBufferPtr;
+  USB_MEM_NODE          *NodePtr;
+
+  DEBUG ((USB_FUIO_DEBUG_INFO, "AllocateTransferBuffer - Entry\n"));
+
+  UsbFuncIoDevPtr = USBFUIO_CONTEXT_FROM_PROTOCOL (This);
+
+  if (Size == 0) {
+    Status = EFI_INVALID_PARAMETER;
+    goto ErrorExit;
+  }
+
+  AllocateBufferPtr = AllocateZeroPool (Size);
+
+  if (AllocateBufferPtr == NULL) {
+    Status = EFI_OUT_OF_RESOURCES;
+    goto ErrorExit;
+  }
+
+  //
+  // Create new node
+  //
+  Status = InsertNewNodeToHead (This, &NodePtr);
+  if (EFI_ERROR (Status)) {
+    Status = EFI_OUT_OF_RESOURCES;
+    goto ErrorExit;
+  }
+
+  NodePtr->Size = Size;
+  NodePtr->AllocatePtr = AllocateBufferPtr;
+
+  *Buffer = AllocateBufferPtr;
+
+  DEBUG ((USB_FUIO_DEBUG_INFO, "AllocateTransferBuffer addr 0x%08x\n", AllocateBufferPtr));
+  DEBUG ((USB_FUIO_DEBUG_INFO, "AllocateTransferBuffer - Exit\n"));
+  return EFI_SUCCESS;
+
+ErrorExit:
+
+  DEBUG ((USB_FUIO_DEBUG_ERROR, "AllocateTransferBuffer - ERRROR %r\n",Status));
+  return Status;
+}
+
+
+/**
+  Deallocates the memory allocated for the transfer Buffer by
+  AllocateTransferBuffer function.
+
+  @param[in] This               A pointer to the EFI_USBFN_IO_PROTOCOL instance.
+  @param[in] Buffer             Buffer Pointer to the transfer Buffer
+                                to deallocate.
+  @retval EFI_SUCCESS           The function returned successfully.
+  @retval EFI_INVALID_PARAMETER A parameter is invalid.
+
+**/
+EFI_STATUS
+EFIAPI
+FreeTransferBuffer (
+  IN EFI_USBFN_IO_PROTOCOL    *This,
+  IN VOID                     *Buffer
+  )
+{
+  EFI_STATUS            Status;
+  USB_XDCI_DEV_CONTEXT  *UsbFuncIoDevPtr;
+
+  UsbFuncIoDevPtr = USBFUIO_CONTEXT_FROM_PROTOCOL (This);
+  DEBUG ((USB_FUIO_DEBUG_LOAD, "FreeTransferBuffer - Entry\n"));
+
+  Status = RemoveNode (This, Buffer);
+  if (EFI_ERROR(Status)) {
+    DEBUG ((USB_FUIO_DEBUG_LOAD, "FreeTransferBuffer - ERROR\n"));
+    return EFI_INVALID_PARAMETER;
+  }
+
+  DEBUG ((USB_FUIO_DEBUG_LOAD, "FreeTransferBuffer - Exit\n"));
+  return EFI_SUCCESS;
+}
+
+/**
+  Configure endpoints Based on supplied device and configuration descriptors.
+
+  @param[in] This               A pointer to the EFI_USBFN_IO_PROTOCOL instance.
+  @param[in] DeviceInfo         A pointer to EFI_USBFN_DEVICE_INFO instance.
+
+  @retval EFI_SUCCESS           The function returned successfully.
+  @retval EFI_INVALID_PARAMETER A parameter is invalid.
+  @retval EFI_DEVICE_ERROR      The physical device reported an error.
+  @retval EFI_NOT_READY         The physical device is busy or not ready to
+                                process this request.
+  @retval EFI_OUT_OF_RESOURCES  The request could not be completed due to
+                                lack of resources.
+
+**/
+EFI_STATUS
+EFIAPI
+ConfigureEnableEndpoints (
+  IN EFI_USBFN_IO_PROTOCOL         *This,
+  IN EFI_USB_DEVICE_INFO           *DeviceInfo
+  )
+{
+  EFI_STATUS                        Status;
+  USB_XDCI_DEV_CONTEXT              *UsbFuncIoDevPtr;
+
+  UsbFuncIoDevPtr = USBFUIO_CONTEXT_FROM_PROTOCOL (This);
+  Status = EFI_SUCCESS;
+
+  DEBUG ((USB_FUIO_DEBUG_LOAD, "ConfigureEnableEndpoints - Entry\n"));
+  //
+  //Assuming that the hardware has already been initialized,
+  //this function configures the endpoints using supplied
+  //DeviceInfo, activates the port, and starts receiving USB events
+  //
+  Status = EFI_SUCCESS;
+  if (DeviceInfo == NULL) {
+    Status = EFI_INVALID_PARAMETER;
+    goto FUNC_EXIT;
+  }
+
+  UsbFuncIoDevPtr->DevInfoPtr->DeviceDescriptor = DeviceInfo->DeviceDescriptor;
+
+  //
+  // Set Configure table
+  //
+  if (DeviceInfo->DeviceDescriptor->NumConfigurations > 1) {
+    DEBUG ((EFI_D_ERROR, "!!!Error ConfigNum over '1' %d\n", DeviceInfo->DeviceDescriptor->NumConfigurations));
+  }
+  UsbFuncIoDevPtr->IndexPtrConfig.ConfigDescriptor = DeviceInfo->ConfigInfoTable[0]->ConfigDescriptor;
+  UsbFuncIoDevPtr->IndexPtrConfig.InterfaceInfoTable[0] = DeviceInfo->ConfigInfoTable[0]->InterfaceInfoTable[0];
+
+  //
+  // Set Interface
+  //
+  if (DeviceInfo->ConfigInfoTable[0]->ConfigDescriptor->NumInterfaces > 1) {
+    DEBUG ((EFI_D_ERROR, "!!!Error NumInterfaces[0] over '1' %d\n", DeviceInfo->ConfigInfoTable[0]->ConfigDescriptor->NumInterfaces));
+  }
+  UsbFuncIoDevPtr->IndexPtrInteface.InterfaceDescriptor = DeviceInfo->ConfigInfoTable[0]->InterfaceInfoTable[0]->InterfaceDescriptor;
+
+  //
+  // Set Endpoint
+  //
+  if (UsbFuncIoDevPtr->IndexPtrInteface.InterfaceDescriptor->NumEndpoints > 2) {
+    DEBUG ((EFI_D_ERROR, "!!!Error NumEndPoint[0] over '2' %d\n", UsbFuncIoDevPtr->IndexPtrInteface.InterfaceDescriptor->NumEndpoints));
+  }
+
+  UsbFuncIoDevPtr->IndexPtrInEp.EndpointCompDesc = NULL;
+  UsbFuncIoDevPtr->IndexPtrOutEp.EndpointCompDesc = NULL;
+
+  if ((DeviceInfo->ConfigInfoTable[0]->InterfaceInfoTable[0]->EndpointDescriptorTable[0]->EndpointAddress & USB_ENDPOINT_DIR_IN) != 0) {
+    UsbFuncIoDevPtr->IndexPtrInEp.EndpointDesc = DeviceInfo->ConfigInfoTable[0]->InterfaceInfoTable[0]->EndpointDescriptorTable[0];
+    UsbFuncIoDevPtr->IndexPtrOutEp.EndpointDesc = DeviceInfo->ConfigInfoTable[0]->InterfaceInfoTable[0]->EndpointDescriptorTable[1];
+  } else {
+    UsbFuncIoDevPtr->IndexPtrInEp.EndpointDesc = DeviceInfo->ConfigInfoTable[0]->InterfaceInfoTable[0]->EndpointDescriptorTable[1];
+    UsbFuncIoDevPtr->IndexPtrOutEp.EndpointDesc = DeviceInfo->ConfigInfoTable[0]->InterfaceInfoTable[0]->EndpointDescriptorTable[0];
+  }
+
+  DEBUG ((USB_FUIO_DEBUG_LOAD, " In Ep Num 0x%02x\n", UsbFuncIoDevPtr->IndexPtrInEp.EndpointDesc->EndpointAddress));
+
+  DEBUG ((USB_FUIO_DEBUG_LOAD, " Out Ep Num 0x%02x\n", UsbFuncIoDevPtr->IndexPtrOutEp.EndpointDesc->EndpointAddress));
+
+FUNC_EXIT:
+  DEBUG ((USB_FUIO_DEBUG_LOAD, "ConfigureEnableEndpoints - exit %r\n", Status));
+  return Status;
+}
+
+/**
+  Returns the maximum packet size of the specified endpoint type for
+  the supplied bus Speed.
+
+  @param[in] This               A pointer to the EFI_USBFN_IO_PROTOCOL instance.
+  @param[in] EndpointType       Endpoint type as defined as EFI_USB_ENDPOINT_TYPE.
+  @param[in] BusSpeed           Bus Speed as defined as EFI_USB_BUS_SPEED.
+  @param[in] MaxPacketSize      The maximum packet size, in bytes,
+                                of the specified endpoint type.
+
+  @retval EFI_SUCCESS           The function returned successfully.
+  @retval EFI_INVALID_PARAMETER A parameter is invalid.
+  @retval EFI_DEVICE_ERROR      The physical device reported an error.
+  @retval EFI_NOT_READY         The physical device is busy or not ready to
+                                process this request.
+**/
+EFI_STATUS
+EFIAPI
+GetEndpointMaxPacketSize (
+  IN EFI_USBFN_IO_PROTOCOL      *This,
+  IN EFI_USB_ENDPOINT_TYPE      EndpointType,
+  IN EFI_USB_BUS_SPEED          BusSpeed,
+  OUT UINT16                    *MaxPacketSize
+  )
+{
+  EFI_STATUS                        Status;
+  USB_XDCI_DEV_CONTEXT              *UsbFuncIoDevPtr;
+  USB_DEV_CORE                      *DevCorePtr;
+  XDCI_CORE_HANDLE                  *XdciCorePtr;
+
+  UsbFuncIoDevPtr = USBFUIO_CONTEXT_FROM_PROTOCOL (This);
+  DevCorePtr = UsbFuncIoDevPtr->DrvCore;
+  XdciCorePtr = DevCorePtr->ControllerHandle;
+  Status = EFI_SUCCESS;
+
+  DEBUG ((USB_FUIO_DEBUG_LOAD, "GetEndpointMaxPacketSize - Entry\n"));
+
+  switch (EndpointType) {
+    case UsbEndpointControl:
+#ifdef SUPPORT_SUPER_SPEED
+      *MaxPacketSize = USB_EP0_MAX_PKT_SIZE_SS; // Default to super Speed
+#else
+      *MaxPacketSize = USB_EP0_MAX_PKT_SIZE_HS; // Default to high Speed
+#endif
+      break;
+
+    case UsbEndpointBulk:
+#ifdef SUPPORT_SUPER_SPEED
+      *MaxPacketSize = USB_BULK_EP_PKT_SIZE_SS; // Default to super Speed
+#else
+      *MaxPacketSize = USB_BULK_EP_PKT_SIZE_HS; // Default to high Speed
+#endif
+      break;
+
+    case UsbEndpointInterrupt:
+      *MaxPacketSize = 1;
+      break;
+
+    case UsbEndpointIsochronous:
+    default:
+      Status = EFI_DEVICE_ERROR;
+      break;
+  }
+
+  DEBUG ((USB_FUIO_DEBUG_LOAD, "GetEndpointMaxPacketSize - Exit %r\n", Status));
+  return Status;
+}
+
+
+/**
+  Returns the maximum supported transfer size.
+
+  @param[in] This               A pointer to the EFI_USBFN_IO_PROTOCOL instance.
+  @param[in] MaxTransferSize    The maximum supported transfer size, in bytes.
+
+  @retval EFI_SUCCESS           The function returned successfully.
+  @retval EFI_INVALID_PARAMETER A parameter is invalid.
+  @retval EFI_DEVICE_ERROR      The physical device reported an error.
+  @retval EFI_NOT_READY         The physical device is busy or not ready to
+                                process this request.
+**/
+EFI_STATUS
+EFIAPI
+GetMaxTransferSize (
+  IN EFI_USBFN_IO_PROTOCOL     *This,
+  OUT UINTN                    *MaxTransferSize
+  )
+{
+  //
+  // Need to check, Make max transfer package to 8MB
+  //
+  *MaxTransferSize = MAX_TRANSFER_PACKET;
+  return EFI_SUCCESS;
+}
+
+
+/**
+  This function returns the unique device ID of the device--this matches
+  what is populated in the SMBIOS table.
+
+  @param[in/out] BufferSize     On input, the size of the Buffer in bytes.
+                                On output, the amount of data returned in Buffer
+                                in bytes.
+
+  @param[out] Buffer            A pointer to a Buffer to return the requested
+                                information as a Unicode string. What string are
+                                we talking about
+
+  @retval EFI_SUCCESS           The function returned successfully.
+  @retval EFI_BUFFER_TOO_SMALL  A parameter is invalid.
+
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+GetDeviceSerialNumber (
+    IN OUT UINTN *BufferSize,
+    OUT VOID *Buffer OPTIONAL
+  )
+{
+    EFI_STATUS Status = EFI_SUCCESS;
+    CHAR16 UuidString[CHARS_IN_GUID];
+    UINTN CharsCopied;
+
+    DEBUG ((USB_FUIO_DEBUG_LOAD, "+GetDeviceSerialNumber\n"));
+    //
+    // check bounds
+    //
+    if (*BufferSize < sizeof(UuidString)) {
+        Status = EFI_BUFFER_TOO_SMALL;
+        *BufferSize = 0;
+        goto Error;
+    }
+
+    //
+    // The rest of mSmBiosUniqueGuid will be same. Note that we cannot
+    // read the SMBIOS table directly, as it might not be ready by the time we
+    // are to read it. The population of the data from the eMMC is ready
+    // by the time we are here.
+    //
+
+    //
+    // Print to to a string, and copy it off
+    //
+    CharsCopied = UnicodeSPrint(UuidString, sizeof(UuidString), L"%g", &mSmBiosUniqueGuid);
+    if (CharsCopied != (CHARS_IN_GUID - 1))
+    {
+        Status = EFI_BUFFER_TOO_SMALL;
+        *BufferSize = 0;
+        goto Error;
+    }
+    CopyMem(Buffer, UuidString, sizeof(UuidString));
+    *BufferSize = sizeof(UuidString);
+
+Error:
+
+    DEBUG ((USB_FUIO_DEBUG_LOAD, "-GetDeviceSerialNumber, Status = 0x%08x\r\n", Status));
+
+    return Status;
+}
+
+
+/**
+  Returns device specific information Based on the supplied identifier as
+  a Unicode string
+
+  @param[in] This               A pointer to the EFI_USBFN_IO_PROTOCOL instance.
+  @param[in] Id                 Requested information id.
+  @param[in] BufferSize         On input, the size of the Buffer in bytes.
+                                On output, the amount of data returned in Buffer
+                                in bytes.
+  @param[in] Buffer             A pointer to a Buffer to return the requested
+                                information as a Unicode string. What string are
+                                we talking about
+
+  @retval EFI_SUCCESS           The function returned successfully.
+  @retval EFI_INVALID_PARAMETER A parameter is invalid.
+  @retval EFI_DEVICE_ERROR      The physical device reported an error.
+  @retval EFI_NOT_READY         The physical device is busy or not ready to
+                                process this request.
+**/
+EFI_STATUS
+EFIAPI
+GetDeviceInfo (
+  IN EFI_USBFN_IO_PROTOCOL      *This,
+  IN EFI_USBFN_DEVICE_INFO_ID   Id,
+  IN OUT UINTN                  *BufferSize,
+  OUT VOID                      *Buffer OPTIONAL
+  )
+{
+  EFI_STATUS                    Status;
+  USB_XDCI_DEV_CONTEXT          *UsbFuncIoDevPtr;
+
+  UsbFuncIoDevPtr = USBFUIO_CONTEXT_FROM_PROTOCOL (This);
+  Status = EFI_SUCCESS;
+
+  DEBUG ((USB_FUIO_DEBUG_LOAD, "GetDeviceInfo - Entry\n"));
+
+  if ((BufferSize == 0) || (Buffer == NULL)) {
+    Status = EFI_INVALID_PARAMETER;
+    goto FUN_EXIT;
+  }
+
+  switch (Id) {
+
+    //
+    // FIXME: Get real serial number of board
+    //
+    case EfiUsbDeviceInfoSerialNumber:
+        if (*BufferSize < sizeof(mUsbFnDxeSerialNumber)) {
+            Status = EFI_BUFFER_TOO_SMALL;
+            *BufferSize = 0;
+            goto FUN_EXIT;
+        }
+        CopyMem(Buffer, mUsbFnDxeSerialNumber, sizeof(mUsbFnDxeSerialNumber));
+        *BufferSize = sizeof(mUsbFnDxeSerialNumber);
+        break;
+
+    case EfiUsbDeviceInfoManufacturerName:
+        if (*BufferSize < sizeof(mUsbFnDxeMfgString)) {
+            Status = EFI_BUFFER_TOO_SMALL;
+            *BufferSize = 0;
+            goto FUN_EXIT;
+        }
+        CopyMem(Buffer, mUsbFnDxeMfgString, sizeof(mUsbFnDxeMfgString));
+        *BufferSize = sizeof(mUsbFnDxeMfgString);
+        break;
+
+    case EfiUsbDeviceInfoProductName:
+        if (*BufferSize < sizeof(mUsbFnDxeProductString)) {
+            Status = EFI_BUFFER_TOO_SMALL;
+            *BufferSize = 0;
+            goto FUN_EXIT;
+        }
+        CopyMem(Buffer, mUsbFnDxeProductString, sizeof(mUsbFnDxeProductString));
+        *BufferSize = sizeof(mUsbFnDxeProductString);
+        break;
+
+    case EfiUsbDeviceInfoUnknown:
+    default:
+      Status = EFI_UNSUPPORTED;
+      *BufferSize = 0;
+      DEBUG ((USB_FUIO_DEBUG_ERROR, "Unknown ID %d encountered.\r\n", Id));
+      break;
+  }
+
+FUN_EXIT:
+  DEBUG ((USB_FUIO_DEBUG_LOAD, "UsbSetconfigure - ConfigDescriptor addr 0x%08x \n", (UINTN)UsbFuncIoDevPtr->IndexPtrConfig.ConfigDescriptor));
+  DEBUG ((USB_FUIO_DEBUG_LOAD, "GetDeviceInfo - Exit %r\n", Status));
+  return Status;
+}
+
+
+/**
+  Returns vendor-id and product-id of the device.
+
+  @param[in]  This              A pointer to the EFI_USBFN_IO_PROTOCOL instance.
+  @param[out] Vid               Returned vendor-id of the device.
+  @param[out] Pid               Returned product-id of the device.
+
+  @retval EFI_SUCCESS           The function returned successfully.
+  @retval EFI_INVALID_PARAMETER A parameter is invalid.
+  @retval EFI_NOT_FOUND         Unable to return vid or pid.
+
+**/
+EFI_STATUS
+EFIAPI
+GetVendorIdProductId (
+  IN EFI_USBFN_IO_PROTOCOL      *This,
+  OUT UINT16                    *Vid,
+  OUT UINT16                    *Pid
+  )
+{
+  USB_XDCI_DEV_CONTEXT              *UsbFuncIoDevPtr;
+
+  UsbFuncIoDevPtr = USBFUIO_CONTEXT_FROM_PROTOCOL (This);
+  //
+  //   *Vid = 0x8086
+  //   *Pid = 0x0A65
+  //
+  *Vid = UsbFuncIoDevPtr->VendorId;
+  *Pid = UsbFuncIoDevPtr->DeviceId;
+  return EFI_SUCCESS;
+}
+
+/**
+  Aborts transfer on the specified endpoint.
+
+  @param[in]  This              A pointer to the EFI_USBFN_IO_PROTOCOL instance.
+  @param[in]  EndpointIndex     Indicates the endpoint on which the ongoing
+                                transfer needs to be canceled.
+  @param[in]  Direction         Direction of the endpoint.
+
+
+  @retval EFI_SUCCESS           The function returned successfully.
+  @retval EFI_INVALID_PARAMETER A parameter is invalid.
+  @retval EFI_DEVICE_ERROR      The physical device reported an error.
+  @retval EFI_NOT_READY         The physical device is busy or not ready to
+                                process this request.
+
+**/
+EFI_STATUS
+EFIAPI
+AbortTransfer (
+  IN EFI_USBFN_IO_PROTOCOL        *This,
+  IN UINT8                        EndpointIndex,
+  IN EFI_USBFN_ENDPOINT_DIRECTION Direction
+  )
+{
+  USB_XDCI_DEV_CONTEXT              *UsbFuncIoDevPtr;
+  XDCI_CORE_HANDLE                  *XdciCorePtr;
+  USB_DEV_CORE                      *UsbDeviceCorePtr;
+  USB_EP_INFO                       EpInfo;
+  EFI_STATUS                        Status;
+
+  DEBUG ((USB_FUIO_DEBUG_LOAD, "FU:AbortTransfer - Entry\n"));
+  UsbFuncIoDevPtr = USBFUIO_CONTEXT_FROM_PROTOCOL (This);
+  UsbDeviceCorePtr = UsbFuncIoDevPtr->DrvCore;
+  XdciCorePtr = UsbDeviceCorePtr->ControllerHandle;
+  Status = EFI_SUCCESS;
+
+  if (UsbFuncIoDevPtr->DevResetFlag == TRUE) {
+    return Status;
+  }
+
+  EpInfo.EpNum = EndpointIndex;
+  EpInfo.EpDir = Direction? UsbEpDirIn : UsbEpDirOut;
+
+  Status = UsbDeviceEpCancelTransfer (UsbFuncIoDevPtr->DrvCore, &EpInfo);
+
+  DEBUG ((USB_FUIO_DEBUG_LOAD, "FU:AbortTransfer - Exit %r\n", Status));
+  return Status;
+}
+
+/**
+  Returns the stall state on the specified endpoint.
+
+  @param[in]  This              A pointer to the EFI_USBFN_IO_PROTOCOL instance.
+  @param[in]  EndpointIndex     Indicates the endpoint on which the ongoing
+                                transfer needs to be canceled.
+  @param[in]  Direction         Direction of the endpoint.
+  @param[in]  State             Boolean, true value indicates that the endpoint
+                                is in a stalled state, false otherwise.
+
+  @retval EFI_SUCCESS           The function returned successfully.
+  @retval EFI_INVALID_PARAMETER A parameter is invalid.
+  @retval EFI_DEVICE_ERROR      The physical device reported an error.
+  @retval EFI_NOT_READY         The physical device is busy or not ready to
+                                process this request.
+
+**/
+EFI_STATUS
+EFIAPI
+GetEndpointStallState (
+  IN EFI_USBFN_IO_PROTOCOL        *This,
+  IN UINT8                        EndpointIndex,
+  IN EFI_USBFN_ENDPOINT_DIRECTION Direction,
+  IN OUT BOOLEAN                  *State
+  )
+{
+  USB_XDCI_DEV_CONTEXT              *UsbFuncIoDevPtr;
+  XDCI_CORE_HANDLE                  *XdciCorePtr;
+  UINT32                            EndPoint;
+
+  UsbFuncIoDevPtr = USBFUIO_CONTEXT_FROM_PROTOCOL (This);
+  DEBUG ((USB_FUIO_DEBUG_LOAD, "GetEndpointStallState - Entry\n"));
+
+  EndPoint = UsbGetPhysicalEpNum (EndpointIndex, Direction ? UsbEpDirIn : UsbEpDirOut);
+
+  XdciCorePtr = UsbFuncIoDevPtr->XdciDrvIfHandle;
+
+  if (XdciCorePtr->EpHandles[EndPoint].State == USB_EP_STATE_STALLED) {
+    *State = TRUE;
+  } else {
+    *State = FALSE;
+  }
+
+  DEBUG ((USB_FUIO_DEBUG_LOAD, "GetEndpointStallState - Exit\n"));
+  return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+UsbSetAddress (
+  IN EFI_USBFN_IO_PROTOCOL        *This,
+  IN UINT32                        Address
+  )
+{
+  EFI_STATUS                        Status;
+  USB_XDCI_DEV_CONTEXT              *UsbFuncIoDevPtr;
+  XDCI_CORE_HANDLE                  *XdciCorePtr;
+  USB_DEV_CORE                      *UsbDeviceCorePtr;
+
+  DEBUG ((USB_FUIO_DEBUG_LOAD, "UsbSetAddress - 0x%04x Entry\n", Address));
+
+  UsbFuncIoDevPtr = USBFUIO_CONTEXT_FROM_PROTOCOL (This);
+
+  UsbDeviceCorePtr = UsbFuncIoDevPtr->DrvCore;
+  XdciCorePtr = UsbDeviceCorePtr->ControllerHandle;
+  Status = EFI_SUCCESS;
+
+  Status = UsbDeviceSetAddress (UsbDeviceCorePtr, (UINT32)Address);
+
+  if (Status != EFI_SUCCESS) {
+    Status = EFI_DEVICE_ERROR;
+    goto EXIT_SET_ADDRESS;
+  }
+
+  Status = UsbDeviceEp0TxStatus (UsbDeviceCorePtr);
+
+  if (Status != EFI_SUCCESS) {
+    Status = EFI_NO_RESPONSE;
+    goto EXIT_SET_ADDRESS;
+  }
+
+EXIT_SET_ADDRESS:
+
+  DEBUG ((USB_FUIO_DEBUG_LOAD, "UsbSetAddress - Exit %r\n", Status));
+  return Status;
+}
+
+
+EFI_STATUS
+EFIAPI
+UsbSetconfigure (
+  IN EFI_USBFN_IO_PROTOCOL        *This,
+  IN UINT32                       InterFaceIndex
+  )
+{
+  EFI_STATUS                      Status;
+  USB_XDCI_DEV_CONTEXT            *UsbFuncIoDevPtr;
+  XDCI_CORE_HANDLE                *XdciCorePtr;
+  USB_DEV_CORE                    *UsbDeviceCorePtr;
+  UINT32                          InterfaceNum;
+  UINT32                          EndPointNum;
+  UINT32                          EndPointIndex;
+  EFI_USB_INTERFACE_INFO          *InterfaceInfoPtr;
+  USB_EP_INFO                     EpInfo;
+  USB_DEVICE_ENDPOINT_INFO        EpDescInfo;
+
+  DEBUG ((USB_FUIO_DEBUG_LOAD, "UsbSetconfigure - 0x%04x Entry\n", InterFaceIndex));
+
+  UsbFuncIoDevPtr = USBFUIO_CONTEXT_FROM_PROTOCOL (This);
+  UsbDeviceCorePtr = UsbFuncIoDevPtr->DrvCore;
+  XdciCorePtr = UsbDeviceCorePtr->ControllerHandle;
+  Status = EFI_SUCCESS;
+
+  InterfaceNum = UsbFuncIoDevPtr->IndexPtrConfig.ConfigDescriptor->NumInterfaces;
+  DEBUG ((USB_FUIO_DEBUG_LOAD, "UsbSetconfigure - ConfigDescriptor addr 0x%08x \n", (UINTN)UsbFuncIoDevPtr->IndexPtrConfig.ConfigDescriptor));
+
+  DEBUG ((USB_FUIO_DEBUG_LOAD, "UsbSetconfigure - DescriptorType 0x%04x ; ConfigurationValue 0x%04x\n",
+          UsbFuncIoDevPtr->IndexPtrConfig.ConfigDescriptor->DescriptorType,
+          UsbFuncIoDevPtr->IndexPtrConfig.ConfigDescriptor->ConfigurationValue
+          ));
+
+  DEBUG ((USB_FUIO_DEBUG_LOAD, "UsbSetconfigure - InterfaceNum 0x%04x \n", InterfaceNum));
+  if (InterfaceNum < InterFaceIndex) {
+    Status = EFI_INVALID_PARAMETER;
+    goto EXIT__SET_CONFIGURE;
+  }
+
+  //
+  // Arry strart form '0', Index start from '1'.
+  //
+  InterfaceInfoPtr = UsbFuncIoDevPtr->IndexPtrConfig.InterfaceInfoTable[InterFaceIndex - 1];
+  EndPointNum = InterfaceInfoPtr->InterfaceDescriptor->NumEndpoints;
+
+  DEBUG ((USB_FUIO_DEBUG_LOAD, "UsbSetconfigure - Total EP NUM 0x%04x \n", EndPointNum));
+
+  for (EndPointIndex = 0; EndPointIndex < EndPointNum; EndPointIndex++) {
+    EpDescInfo.EndpointDesc = InterfaceInfoPtr->EndpointDescriptorTable[EndPointIndex];
+    EpDescInfo.EndpointCompDesc = NULL;
+    UsbFnSetEpInfo (&EpInfo, &EpDescInfo);
+    DEBUG ((USB_FUIO_DEBUG_LOAD, "EndpointAddress 0x%02x\n", EpDescInfo.EndpointDesc->EndpointAddress));
+
+    if (UsbDeviceInitEp (UsbDeviceCorePtr, &EpInfo) == EFI_SUCCESS) {
+       if (UsbDeviceEpEnable (UsbDeviceCorePtr, &EpInfo) == EFI_SUCCESS) {
+       } else {
+         Status = EFI_DEVICE_ERROR;
+         DEBUG ((DEBUG_INFO, "UsbDeviceEpEnable() - Failed to enable endpoint\n"));
+       }
+    } else {
+       Status = EFI_DEVICE_ERROR;
+       DEBUG ((DEBUG_INFO, "UsbDeviceInitEp() - Failed to initialize endpoint\n"));
+    }
+  }
+
+  Status = UsbDeviceEp0TxStatus (UsbDeviceCorePtr);
+
+  if (Status != EFI_SUCCESS) {
+    Status = EFI_NO_RESPONSE;
+    goto EXIT__SET_CONFIGURE;
+  }
+
+
+EXIT__SET_CONFIGURE:
+  DEBUG ((USB_FUIO_DEBUG_LOAD, "UsbSetconfigure - Exit %r\n", Status));
+
+  return Status;
+}
+
+/**
+  Sets or clears the stall state on the specified endpoint.
+
+  @param[in]  This              A pointer to the EFI_USBFN_IO_PROTOCOL instance.
+  @param[in]  EndpointIndex     Indicates the endpoint on which the ongoing
+                                transfer needs to be canceled.
+  @param[in]  Direction         Direction of the endpoint.
+  @param[in]  State             Requested stall state on the specified endpoint.
+                                True value causes the endpoint to stall;
+                                false value clears an existing stall.
+
+  @retval EFI_SUCCESS           The function returned successfully.
+  @retval EFI_INVALID_PARAMETER A parameter is invalid.
+  @retval EFI_DEVICE_ERROR      The physical device reported an error.
+  @retval EFI_NOT_READY         The physical device is busy or not ready to
+                                process this request.
+
+**/
+EFI_STATUS
+EFIAPI
+SetEndpointStallState (
+  IN EFI_USBFN_IO_PROTOCOL        *This,
+  IN UINT8                        EndpointIndex,
+  IN EFI_USBFN_ENDPOINT_DIRECTION Direction,
+  IN BOOLEAN                      State
+  )
+{
+  EFI_STATUS                        Status;
+  USB_XDCI_DEV_CONTEXT              *UsbFuncIoDevPtr;
+  USB_EP_INFO                       pEpInfo;
+
+  UsbFuncIoDevPtr = USBFUIO_CONTEXT_FROM_PROTOCOL (This);
+
+  DEBUG ((USB_FUIO_DEBUG_LOAD, "SetEndpointStallState - Entry\n"));
+  Status = EFI_SUCCESS;
+
+  pEpInfo.EpNum = EndpointIndex;
+  pEpInfo.EpDir = Direction? UsbEpDirIn : UsbEpDirOut;
+
+  if (State == TRUE) {
+    Status = UsbDeviceEpStall (UsbFuncIoDevPtr->DrvCore, (VOID*)(UINTN) &pEpInfo);
+  } else {
+    Status = UsbDeviceEpClearStall (UsbFuncIoDevPtr->DrvCore, (VOID*)(UINTN) &pEpInfo);
+  }
+
+  if (Status != EFI_SUCCESS) {
+    Status = EFI_DEVICE_ERROR;
+  }
+
+  DEBUG ((USB_FUIO_DEBUG_LOAD, "SetEndpointStallState - Exit\n"));
+  return Status;
+}
+
+EFI_STATUS
+DeviceEventCheck(
+  IN  EFI_USBFN_IO_PROTOCOL       *This,
+  IN  USBD_EVENT_BUF              *EventIndex,
+  OUT UINT32                      *ProcessSize,
+  OUT EFI_USBFN_MESSAGE           *Message,
+  OUT BOOLEAN                     *EventFlag
+  )
+{
+  USB_XDCI_DEV_CONTEXT            *UsbFuncIoDevPtr;
+  UINT32                          EventReg;
+  USB_DEV_CORE                    *UsbDeviceCorePtr;
+  XDCI_CORE_HANDLE                *XdciCorePtr;
+
+  DEBUG ((USB_FUIO_DEBUG_EVENT_D, "\n FUEV::DeviceEvent entry....\n"));
+  UsbFuncIoDevPtr = USBFUIO_CONTEXT_FROM_PROTOCOL (This);
+  UsbDeviceCorePtr = UsbFuncIoDevPtr->DrvCore;
+  XdciCorePtr = UsbDeviceCorePtr->ControllerHandle;
+  EventReg = (EventIndex->Event & DWC_XDCI_EVENT_BUFF_DEV_EVT_MASK);
+  EventReg >>= DWC_XDCI_EVENT_BUFF_DEV_EVT_BIT_POS;
+  *EventFlag = FALSE;
+
+  //
+  // Assume default event size. Change it in switch case if
+  // different
+  //
+  *ProcessSize =  DWC_XDCI_DEV_EVENT_DEFAULT_SIZE_IN_BYTES;
+
+  switch (EventReg) {
+    case DWC_XDCI_EVENT_BUFF_DEV_DISCONN_EVENT:
+      DEBUG ((USB_FUIO_DEBUG_EVENT_D, "USBFU_Device DWC_XDCI_EVENT_BUFF_DEV_DISCONN_EVENT\n"));
+      *Message = EfiUsbMsgBusEventDetach;
+      break;
+
+    case DWC_XDCI_EVENT_BUFF_DEV_USB_RESET_EVENT:
+      DEBUG ((USB_FUIO_DEBUG_EVENT_D, "USBFU_Device DWC_XDCI_EVENT_BUFF_DEV_USB_RESET_EVENT\n"));
+      //
+      //  In resetDet will prepare setup Xfer package
+      //
+      UsbFuncIoDevPtr->DevReConnect = FALSE;
+      UsbFuncIoDevPtr->DevResetFlag = TRUE;
+
+      usbProcessDeviceResetDet (XdciCorePtr);
+      UsbDeviceSetAddress (UsbDeviceCorePtr, 0);
+      *Message = EfiUsbMsgBusEventReset;
+      *EventFlag = TRUE;
+      break;
+
+    case DWC_XDCI_EVENT_BUFF_DEV_CONN_DONE_EVENT:
+      DEBUG ((USB_FUIO_DEBUG_EVENT_D, "USBFU_Device DWC_XDCI_EVENT_BUFF_DEV_CONN_DONE_EVENT\n"));
+      usbProcessDeviceResetDone(XdciCorePtr);
+      UsbDeviceSetAddress(UsbDeviceCorePtr, 0);
+      UsbFuncIoDevPtr->DevReConnect = TRUE;
+      UsbFuncIoDevPtr->DevResetFlag = FALSE;
+      *EventFlag = TRUE;
+      *Message = EfiUsbMsgNone;
+      break;
+
+    case DWC_XDCI_EVENT_BUFF_DEV_HBRNTN_REQ_EVENT:
+      DEBUG ((USB_FUIO_DEBUG_EVENT_D, "USBFU_Device DWC_XDCI_EVENT_BUFF_DEV_HBRNTN_REQ_EVENT\n"));
+      *Message = EfiUsbMsgBusEventSuspend;
+      *EventFlag = TRUE;
+      break;
+
+    case DWC_XDCI_EVENT_BUFF_DEV_WKUP_EVENT:
+      DEBUG ((USB_FUIO_DEBUG_EVENT_D, "USBFU_Device DWC_XDCI_EVENT_BUFF_DEV_WKUP_EVENT\n"));
+      *Message = EfiUsbMsgBusEventResume;
+      break;
+
+    case DWC_XDCI_EVENT_BUFF_DEV_TST_LMP_RX_EVENT:
+      *ProcessSize = DWC_XDCI_DEV_EVENT_TST_LMP_SIZE_IN_BYTES;
+      *Message = EfiUsbMsgNone;
+      DEBUG ((USB_FUIO_DEBUG_EVENT_D, "USBFUDwcXdciProcessDeviceEvent: UNHANDLED device event: %x\n", EventReg));
+      break;
+
+    case DWC_XDCI_EVENT_BUFF_DEV_STATE_CHANGE_EVENT:
+      DEBUG ((USB_FUIO_DEBUG_EVENT_D, "USBFU_Device DWC_XDCI_EVENT_BUFF_DEV_STATE_CHANGE_EVENT\n"));
+      break;
+
+    case DWC_XDCI_EVENT_BUFF_DEV_SOF_EVENT:
+      DEBUG ((USB_FUIO_DEBUG_EVENT_D, "USBFU_Device DWC_XDCI_EVENT_BUFF_DEV_SOF_EVENT\n"));
+      break;
+
+    case DWC_XDCI_EVENT_BUFF_DEV_ERRATIC_ERR_EVENT:
+      DEBUG ((USB_FUIO_DEBUG_EVENT_D, "USBFU_Device DWC_XDCI_EVENT_BUFF_DEV_ERRATIC_ERR_EVENT\n"));
+      break;
+
+    case DWC_XDCI_EVENT_BUFF_DEV_CMD_CMPLT_EVENT:
+      DEBUG ((USB_FUIO_DEBUG_EVENT_D, "USBFU_Device DWC_XDCI_EVENT_BUFF_DEV_CMD_CMPLT_EVENT\n"));
+      break;
+
+    case DWC_XDCI_EVENT_BUFF_DEV_BUFF_OVFL_EVENT:
+      DEBUG ((USB_FUIO_DEBUG_EVENT_D, "USBFU_Device DWC_XDCI_EVENT_BUFF_DEV_BUFF_OVFL_EVENT\n"));
+      break;
+
+    default:
+      *EventFlag = FALSE;
+      *Message = EfiUsbMsgNone;
+      DEBUG ((USB_FUIO_DEBUG_EVENT_I, "USBFUWcXdciProcessDeviceEvent: UNHANDLED device event: %x\n", EventReg));
+      break;
+  }
+
+  DEBUG ((USB_FUIO_DEBUG_EVENT_D, "\n FUEV::DeviceEvent entry exit.... \n"));
+  return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+Ep0XferDone(
+  IN  EFI_USBFN_IO_PROTOCOL       *This,
+  IN  UINT32                      EndPointNum,
+  OUT EFI_USBFN_MESSAGE           *Message,
+  IN OUT UINTN                    *PayloadSize,
+  OUT EFI_USBFN_MESSAGE_PAYLOAD   *Payload
+  )
+{
+  USB_DEV_CORE                    *UsbDeviceCorePtr;
+  XDCI_CORE_HANDLE                *XdciCorePtr;
+  USB_XDCI_DEV_CONTEXT            *UsbFuncIoDevPtr;
+  DWC_XDCI_ENDPOINT               *EpHandle;
+  DWC_XDCI_TRB                    *Trb;
+  UINT32                          TrbCtrl;
+  UINT32                          TrbSts;
+  UINT32                          BufferLen;
+  EFI_STATUS                      DevStatus;
+  USB_EP_INFO                     EpInfo;
+
+  UsbFuncIoDevPtr = USBFUIO_CONTEXT_FROM_PROTOCOL (This);
+  UsbDeviceCorePtr = UsbFuncIoDevPtr->DrvCore;
+  XdciCorePtr = UsbDeviceCorePtr->ControllerHandle;
+  EpHandle = &XdciCorePtr->EpHandles[EndPointNum];
+  Trb = XdciCorePtr->Trbs + (EndPointNum * DWC_XDCI_TRB_NUM);
+
+  if (Trb->TrbCtrl & DWC_XDCI_TRB_CTRL_HWO_MASK) {
+    DEBUG ((USB_FUIO_DEBUG_EVENT_D, "Ep0XferDone. HW owns TRB: %x!!!\n", (UINT32)(UINTN)Trb));
+  }
+
+  DevStatus = EFI_SUCCESS;
+  BufferLen = 0;
+
+  DEBUG ((USB_FUIO_DEBUG_EVENT_D, "EndPointNum:%d, TRB: Addr 0x%08x!!!\n", EndPointNum, (UINTN)Trb));
+  DEBUG ((USB_FUIO_DEBUG_EVENT_D, "Ep0 done Trb->TrbCtrl: %x!!!\n", (UINT32)Trb->TrbCtrl));
+  DEBUG ((USB_FUIO_DEBUG_EVENT_D, "Ep0 done Trb->LenXferParams: %x!!!\n", (UINT32)Trb->LenXferParams));
+  DEBUG ((USB_FUIO_DEBUG_EVENT_D, "Ep0 done Trb->BuffPtrLow: %x!!!\n", (UINT32)Trb->BuffPtrLow));
+  DEBUG ((USB_FUIO_DEBUG_EVENT_D, "Ep0 done Trb->BuffPtrHigh: %x!!!\n", (UINT32)Trb->BuffPtrHigh));
+
+  //
+  // Set CheckFlag to FALSE for 'DwcXdciEpRxData' function
+  // check the RX request complete and continue next transfer request
+  //
+  EpHandle->CheckFlag = FALSE;
+  EpHandle->CurrentXferRscIdx = 0;
+
+  DEBUG ((USB_FUIO_DEBUG_EVENT_I, "Ep0 done D01!!\n"));
+  TrbCtrl = (Trb->TrbCtrl & DWC_XDCI_TRB_CTRL_TYPE_MASK) >> DWC_XDCI_TRB_CTRL_TYPE_BIT_POS;
+
+  DEBUG ((USB_FUIO_DEBUG_EVENT_I, "Ep0 done D02!!\n"));
+  TrbSts = (Trb->LenXferParams & DWC_XDCI_TRB_STATUS_MASK) >> DWC_XDCI_TRB_STATUS_BIT_POS;
+
+  DEBUG ((USB_FUIO_DEBUG_EVENT_I, "Ep0 done D03!!\n" ));
+  BufferLen = Trb->LenXferParams & DWC_XDCI_TRB_BUFF_SIZE_MASK;
+
+  DEBUG ((USB_FUIO_DEBUG_EVENT_I, "Ep0 done D04 TrbCtrl :: %x!!\n", TrbCtrl));
+  switch (TrbCtrl) {
+    case DWC_XDCI_TRB_CTRL_TYPE_SETUP:
+      DEBUG ((USB_FUIO_DEBUG_EVENT_D, "Ep0 done DWC_XDCI_TRB_CTRL_TYPE_SETUP!!\n"));
+      //
+      // This is delay for other host USB controller(none Intel), identify device get fail issue.
+      //
+      gBS->Stall(130);
+      BufferLen = 8;
+
+      DEBUG ((USB_FUIO_DEBUG_EVENT_D, "DWC_XDCI_TRB_CTRL_TYPE_SETUP!!\n"));
+      DEBUG ((USB_FUIO_DEBUG_EVENT_D, "AlignedSetupBuffer::0x%08x!!\n", XdciCorePtr->AlignedSetupBuffer));
+      DEBUG ((USB_FUIO_DEBUG_EVENT_D, "Payload::0x%08x!!\n", (UINTN)Payload));
+      DEBUG ((USB_FUIO_DEBUG_EVENT_D, "BufferLen::0x%08x!!\n", (UINTN)BufferLen));
+      *Message = EfiUsbMsgSetupPacket;
+      CopyMem (Payload, XdciCorePtr->AlignedSetupBuffer, BufferLen);
+
+      DEBUG ((USB_FUIO_DEBUG_EVENT_I, "Ep0 done D06!!\n"));
+      if (!(XdciCorePtr->AlignedSetupBuffer[0] & USB_SETUP_DATA_PHASE_DIRECTION_MASK)) {
+        if ((XdciCorePtr->AlignedSetupBuffer[0]  == 0x00) ) {
+          if ((XdciCorePtr->AlignedSetupBuffer[1]  == USB_DEV_SET_ADDRESS)) {
+            //
+            // set address
+            //
+            UsbSetAddress (
+              This,
+              (UINT32)(XdciCorePtr->AlignedSetupBuffer[3] << 8 | XdciCorePtr->AlignedSetupBuffer[2])
+              );
+
+            *Message = EfiUsbMsgNone;
+          } else if ((XdciCorePtr->AlignedSetupBuffer[1]  == USB_DEV_SET_CONFIGURATION)) {
+            DEBUG ((USB_FUIO_DEBUG_EVENT_I, "\n set configure !!!"));
+            UsbSetconfigure (
+              This,
+              (UINT32)(XdciCorePtr->AlignedSetupBuffer[3] << 8 | XdciCorePtr->AlignedSetupBuffer[2])
+              );
+            *Message = EfiUsbMsgNone;
+          }
+        }
+      }
+
+      DEBUG ((USB_FUIO_DEBUG_EVENT_I, "Ep0 done D07!!\n"));
+      break;
+
+    case DWC_XDCI_TRB_CTRL_TYPE_DATA:
+      DEBUG ((DEBUG_INFO, "Ep0 done DWC_XDCI_TRB_CTRL_TYPE_DATA!!\n"));
+	  //
+      // Notify upper layer of control transfer completion
+      // if a callback function was registerd
+      //
+      if ((EndPointNum & 0x01) == 0) {
+        *Message = EfiUsbMsgEndpointStatusChangedRx;
+      } else {
+        *Message = EfiUsbMsgEndpointStatusChangedTx;
+      }
+      Payload->utr.EndpointIndex = (UINT8)(EndPointNum >> 1);
+      Payload->utr.Direction = (UINT8)(EndPointNum & 0x01);
+      Payload->utr.Buffer = (VOID*)(UINTN)(Trb->BuffPtrLow);
+
+      DEBUG ((DEBUG_INFO, "Ep0 EndPointNum: %x!!!\n", (UINT32)EndPointNum));
+      DEBUG ((DEBUG_INFO, "Ep0 done XferLength: %x!!!\n", (UINT32)UsbFuncIoDevPtr->EndPointXferRec[EndPointNum].XferLength));
+      Payload->utr.Buffer = (VOID*)UsbFuncIoDevPtr->EndPointXferRec[EndPointNum].XferAddress;
+      Payload->utr.BytesTransferred = UsbFuncIoDevPtr->EndPointXferRec[EndPointNum].XferLength;
+
+      if (TrbSts == 0) {
+        if ((Trb->LenXferParams & DWC_XDCI_TRB_BUFF_SIZE_MASK) == 0) {
+          Payload->utr.TransferStatus = UsbTransferStatusComplete;
+        } else {
+          Payload->utr.TransferStatus = UsbTransferStatusActive;
+        }
+      } else if (TrbSts != 0) {
+        Trb->TrbCtrl |= DWC_XDCI_TRB_CTRL_HWO_MASK;
+        *Message = EfiUsbMsgNone;
+        Payload->utr.TransferStatus = UsbTransferStatusAborted;
+        DEBUG ((DEBUG_INFO, "Flush FIFO!!!\n" ));
+        EpInfo.EpNum = 0;
+        EpInfo.EpDir =UsbEpDirIn;
+        UsbXdciCoreFlushEpFifo(XdciCorePtr, &EpInfo);
+        EpInfo.EpNum = 0;
+        EpInfo.EpDir =UsbEpDirOut;
+        UsbXdciCoreFlushEpFifo(XdciCorePtr, &EpInfo);
+        DevStatus = UsbDeviceEp0RxSetup (UsbDeviceCorePtr, XdciCorePtr->AlignedSetupBuffer);
+      }
+
+      break;
+
+    case DWC_XDCI_TRB_CTRL_TYPE_STATUS2:
+    case DWC_XDCI_TRB_CTRL_TYPE_STATUS3:
+      Payload->utr.Buffer = (VOID*) UsbFuncIoDevPtr->EndPointXferRec[EndPointNum].XferAddress;
+      Payload->utr.BytesTransferred = 0;
+      Payload->utr.EndpointIndex = (UINT8)(EndPointNum >> 1);
+      if ((EndPointNum & 0x01) == 0) {
+        *Message = EfiUsbMsgEndpointStatusChangedRx;
+      } else {
+        *Message = EfiUsbMsgEndpointStatusChangedTx;
+      }
+
+      if (TrbSts == 0) {
+        if ((Trb->LenXferParams & DWC_XDCI_TRB_BUFF_SIZE_MASK) == 0) {
+          Payload->utr.TransferStatus = UsbTransferStatusComplete;
+        } else {
+          Payload->utr.TransferStatus = UsbTransferStatusActive;
+        }
+      } else if (TrbSts != 0) {
+        Payload->utr.TransferStatus = UsbTransferStatusAborted;
+      }
+
+      DevStatus = UsbDeviceEp0RxSetup (UsbDeviceCorePtr, XdciCorePtr->AlignedSetupBuffer);
+
+      if (DevStatus) {
+        DEBUG ((DEBUG_INFO, "DwcXdciProcessEp0XferPhaseDone: FAILED to queue SETUP\n"));
+      }
+      DEBUG ((DEBUG_INFO, "Status phase done. Queue next SETUP packet==>\n"));
+      break;
+
+    default:
+      *Message = EfiUsbMsgNone;
+      DEBUG ((DEBUG_INFO, "DwcXdciProcessEp0XferPhaseDone: UNHANDLED STATE in TRB\n"));
+      break;
+  }
+  return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+NoneEp0XferDone(
+  IN  EFI_USBFN_IO_PROTOCOL       *This,
+  IN  UINT32                      EndPointNum,
+  OUT EFI_USBFN_MESSAGE           *Message,
+  IN OUT UINTN                    *PayloadSize,
+  OUT EFI_USBFN_MESSAGE_PAYLOAD   *Payload
+  )
+{
+  USB_DEV_CORE                    *UsbDeviceCorePtr;
+  XDCI_CORE_HANDLE                *XdciCorePtr;
+  USB_XDCI_DEV_CONTEXT            *UsbFuncIoDevPtr;
+  DWC_XDCI_ENDPOINT               *EpHandle;
+  DWC_XDCI_TRB                    *Trb;
+  UINT32                          TrbCtrl;
+  UINT32                          TrbSts;
+
+  UsbFuncIoDevPtr = USBFUIO_CONTEXT_FROM_PROTOCOL (This);
+  UsbDeviceCorePtr = UsbFuncIoDevPtr->DrvCore;
+  XdciCorePtr = UsbDeviceCorePtr->ControllerHandle;
+  EpHandle = &XdciCorePtr->EpHandles[EndPointNum];
+  Trb = XdciCorePtr->Trbs + (EndPointNum * DWC_XDCI_TRB_NUM);
+
+  if (Trb->TrbCtrl & DWC_XDCI_TRB_CTRL_HWO_MASK) {
+    DEBUG ((USB_FUIO_DEBUG_EVENT_D, "NoneEp0XferDone. HW owns TRB: %x!!!, EndPointNum: %x\n", (UINT32)(UINTN)Trb, EndPointNum));
+  }
+
+  DEBUG ((USB_FUIO_DEBUG_EVENT_D, " TRB: Addr 0x%08x!!!\n", (UINTN)Trb));
+  DEBUG ((USB_FUIO_DEBUG_EVENT_D, " Xfer done Trb->BuffPtrLow: %x!!!\n", (UINT32)Trb->BuffPtrLow));
+  DEBUG ((USB_FUIO_DEBUG_EVENT_D, " Xfer done Trb->BuffPtrHigh: %x!!!\n", (UINT32)Trb->BuffPtrHigh));
+  DEBUG ((USB_FUIO_DEBUG_EVENT_D, " Xfer done Trb->LenXferParams: %x!!!\n", (UINT32)Trb->LenXferParams));
+  DEBUG ((USB_FUIO_DEBUG_EVENT_D, " Xfer done Trb->TrbCtrl: %x!!!\n", (UINT32)Trb->TrbCtrl));
+
+  //
+  // Set CheckFlag to FALSE for 'DwcXdciEpRxData' function
+  // check the RX request complete and continue next transfer request
+  //
+  EpHandle->CheckFlag = FALSE;
+  EpHandle->CurrentXferRscIdx = 0;
+  *Message = EfiUsbMsgNone;
+
+  TrbCtrl = (Trb->TrbCtrl & DWC_XDCI_TRB_CTRL_TYPE_MASK) >> DWC_XDCI_TRB_CTRL_TYPE_BIT_POS;
+  TrbSts = (Trb->LenXferParams & DWC_XDCI_TRB_STATUS_MASK) >> DWC_XDCI_TRB_STATUS_BIT_POS;
+
+  Payload->utr.BytesTransferred = UsbFuncIoDevPtr->EndPointXferRec[EndPointNum].XferLength;
+  Payload->utr.EndpointIndex = UsbFuncIoDevPtr->EndPointXferRec[EndPointNum].LogEpNum;
+  Payload->utr.Direction = UsbFuncIoDevPtr->EndPointXferRec[EndPointNum].Direction;
+  Payload->utr.Buffer = (VOID*)(UINTN)(Trb->BuffPtrLow);
+  UsbFuncIoDevPtr->EndPointXferRec[EndPointNum].Complete = TRUE;
+
+  DEBUG ((USB_FUIO_DEBUG_EVENT_D, "EndPointAddress = 0x%08x\n", Payload->utr.EndpointIndex));
+  if (Payload->utr.Direction == EfiUsbEndpointDirectionDeviceTx) {
+    DEBUG ((USB_FUIO_DEBUG_EVENT_D, " Direction::EfiUsbEndpointDirectionDeviceTx\n"));
+    *Message = EfiUsbMsgEndpointStatusChangedTx;
+  } else {
+    DEBUG ((USB_FUIO_DEBUG_EVENT_D, " Direction::EfiUsbEndpointDirectionDeviceRx\n"));
+    *Message = EfiUsbMsgEndpointStatusChangedRx;
+  }
+
+  if (TrbSts == 0) {
+    if ((Trb->LenXferParams & DWC_XDCI_TRB_BUFF_SIZE_MASK) == 0) {
+      Payload->utr.TransferStatus = UsbTransferStatusComplete;
+      DEBUG ((USB_FUIO_DEBUG_EVENT_D, "XferStatus::UsbTransferStatusComplete\n"));
+    } else {
+      Payload->utr.TransferStatus = UsbTransferStatusComplete;
+      Payload->utr.BytesTransferred -= (Trb->LenXferParams & DWC_XDCI_TRB_BUFF_SIZE_MASK);
+      DEBUG ((USB_FUIO_DEBUG_EVENT_D, "XferStatus::UsbTransferStatusComplete\n"));
+      DEBUG ((USB_FUIO_DEBUG_EVENT_D, "XferStatus::Length %d \n", Payload->utr.BytesTransferred ));
+    }
+  } else if (TrbSts != 0) {
+    Payload->utr.TransferStatus = UsbTransferStatusAborted;
+    DEBUG ((USB_FUIO_DEBUG_EVENT_D, "XferStatus::UsbTransferStatusAborted\n"));
+  }
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+Ep0XferNotReady(
+  IN  EFI_USBFN_IO_PROTOCOL       *This,
+  IN  UINT32                      EndPointNum,
+  OUT EFI_USBFN_MESSAGE           *Message,
+  IN OUT UINTN                    *PayloadSize,
+  OUT EFI_USBFN_MESSAGE_PAYLOAD   *Payload,
+  IN  UINT32                      EpStatus
+  )
+{
+  USB_DEV_CORE                    *UsbDeviceCorePtr;
+  XDCI_CORE_HANDLE                *XdciCorePtr;
+  USB_XDCI_DEV_CONTEXT            *UsbFuncIoDevPtr;
+
+  UsbFuncIoDevPtr = USBFUIO_CONTEXT_FROM_PROTOCOL(This);
+  UsbDeviceCorePtr = UsbFuncIoDevPtr->DrvCore;
+  XdciCorePtr = UsbDeviceCorePtr->ControllerHandle;
+
+  *Message = EfiUsbMsgNone;
+
+  return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+EpEventCheck(
+  IN  EFI_USBFN_IO_PROTOCOL       *This,
+  IN  USBD_EVENT_BUF              *EventIndex,
+  OUT UINT32                      *ProcessSize,
+  OUT EFI_USBFN_MESSAGE           *Message,
+  IN OUT UINTN                    *PayloadSize,
+  OUT EFI_USBFN_MESSAGE_PAYLOAD   *Payload,
+  OUT BOOLEAN                     *EventFlag
+  )
+{
+  USB_DEV_CORE                    *UsbDeviceCorePtr;
+  XDCI_CORE_HANDLE                *XdciCorePtr;
+  USB_XDCI_DEV_CONTEXT            *UsbFuncIoDevPtr;
+  UINT32                          EventReg;
+  UINT32                          EpEvent;
+  UINT32                          EndPointNumber;
+  UINT32                          EventStatus;
+  USB_EP_STATE                    Ep_State;
+  UINTN                           TmpBufferSize;
+
+  DEBUG ((USB_FUIO_DEBUG_EVENT_I, "FUEV::EndPoint Event....\n"));
+  UsbFuncIoDevPtr = USBFUIO_CONTEXT_FROM_PROTOCOL(This);
+
+  UsbDeviceCorePtr = UsbFuncIoDevPtr->DrvCore;
+  XdciCorePtr = UsbDeviceCorePtr->ControllerHandle;
+  EventReg = EventIndex->Event;
+  *ProcessSize = DWC_XDCI_DEV_EVENT_DEFAULT_SIZE_IN_BYTES;
+  *EventFlag = TRUE;
+  TmpBufferSize = 0;
+
+  //
+  // Get EP num
+  //
+  EndPointNumber = (EventReg & DWC_XDCI_EVENT_BUFF_EP_NUM_MASK) >> DWC_XDCI_EVENT_BUFF_EP_NUM_BIT_POS;
+
+  EventStatus = EventReg & DWC_XDCI_EVENT_BUFF_EP_EVENT_STATUS_MASK;
+
+  //
+  // Interpret event and handle transfer completion here
+  //
+  EpEvent = (EventReg & DWC_XDCI_EVENT_BUFF_EP_EVENT_MASK) >> DWC_XDCI_EVENT_BUFF_EP_EVENT_BIT_POS;
+
+  DEBUG ((USB_FUIO_DEBUG_EVENT_I, "USBFU_EP EventReg 0x%08x\n", EventReg));
+
+  switch (EpEvent) {
+    case DWC_XDCI_EVENT_BUFF_EP_XFER_CMPLT:
+      DEBUG ((USB_FUIO_DEBUG_EVENT_D, "USBFU_EP DWC_XDCI_EVENT_BUFF_EP_XFER_CMPLT\n"));
+      if (EndPointNumber > 1) {
+        DEBUG ((USB_FUIO_DEBUG_EVENT_D, "USBFU_EP None_Control transfer\n"));
+        NoneEp0XferDone (This, EndPointNumber, Message, PayloadSize, Payload);
+      } else {
+        //
+        // Control transfer
+        //
+        DEBUG ((USB_FUIO_DEBUG_EVENT_D, "USBFU_EP Control transfer\n"));
+        Ep0XferDone (This, EndPointNumber, Message, PayloadSize, Payload);
+      }
+      break;
+
+    case DWC_XDCI_EVENT_BUFF_EP_XFER_NOT_READY:
+      DEBUG ((USB_FUIO_DEBUG_EVENT_D, "DWC_XDCI_EVENT_BUFF_EP_XFER_NOT_READY\n"));
+      *Message = EfiUsbMsgNone;
+      if(EndPointNumber < (sizeof(UsbFuncIoDevPtr->EndPointXferRec) / sizeof(UsbFuncIoDevPtr->EndPointXferRec[0]))) {
+        if ((UsbFuncIoDevPtr->EndPointXferRec[EndPointNumber].ZlpFlag == TRUE) && \
+              (UsbFuncIoDevPtr->EndPointXferRec[EndPointNumber].Complete == TRUE)) {
+          DEBUG ((USB_FUIO_DEBUG_EVENT_D, "Request send ZLP\n"));
+          if ((EndPointNumber & 0x01) != 0) {
+            Transfer(This,
+                     UsbFuncIoDevPtr->IndexPtrInEp.EndpointDesc->EndpointAddress,
+                     EfiUsbEndpointDirectionDeviceTx,
+                     &TmpBufferSize,
+                     NULL
+                    );
+            UsbFuncIoDevPtr->EndPointXferRec[EndPointNumber].ZlpFlag = FALSE;
+          }
+
+        }
+      } else {
+        //
+        // Is it data stage or status stage
+        //
+        // Data Statge
+        //
+        Ep_State = USB_EP_STATE_DATA;
+        //
+        // Control transfer
+        //
+        DEBUG ((USB_FUIO_DEBUG_EVENT_D, "USBFU_EP Control transfer not ready\n"));
+        Ep0XferNotReady (This, EndPointNumber, Message, PayloadSize, Payload, EventStatus);
+        *EventFlag = FALSE;
+      }
+      break;
+
+    case DWC_XDCI_EVENT_BUFF_EP_XFER_IN_PROGRESS:
+      DEBUG ((USB_FUIO_DEBUG_EVENT_D, "DWC_XDCI_EVENT_BUFF_EP_XFER_IN_PROGRESS\n"));
+      break;
+
+    default:
+      DEBUG ((USB_FUIO_DEBUG_EVENT_I, "USBFUDwcXdciProcessEpEvent: UNKNOWN EP event\n"));
+      break;
+  }
+
+  DEBUG ((USB_FUIO_DEBUG_EVENT_D, "FUEV::EndPoint Event....exit\n"));
+  return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+ProcessIntLineEvents(
+  IN EFI_USBFN_IO_PROTOCOL        *This,
+  IN UINT32                       EventCount,
+  IN UINT32                       *ProceSsEvent,
+  OUT EFI_USBFN_MESSAGE           *Message,
+  IN OUT UINTN                    *PayloadSize,
+  OUT EFI_USBFN_MESSAGE_PAYLOAD   *Payload,
+  OUT BOOLEAN                     *EventFlag
+  )
+{
+  USB_DEV_CORE                    *UsbDeviceCorePtr;
+  XDCI_CORE_HANDLE                *XdciCorePtr;
+  USB_XDCI_DEV_CONTEXT            *UsbFuncIoDevPtr;
+  UINT32                          CurrentEventAddr;
+  UINT32                          ProceSsEventSize;
+  BOOLEAN                         EventReport;
+  BOOLEAN                         EpEventReport;
+
+  UsbFuncIoDevPtr = USBFUIO_CONTEXT_FROM_PROTOCOL (This);
+  UsbDeviceCorePtr = UsbFuncIoDevPtr->DrvCore;
+  XdciCorePtr = UsbDeviceCorePtr->ControllerHandle;
+  CurrentEventAddr = (UINT32)(UINTN)(XdciCorePtr->CurrentEventBuffer);
+  EventReport = FALSE;
+  EpEventReport = FALSE;
+  ProceSsEventSize = 0;
+   DEBUG ((USB_FUIO_DEBUG_EVENT_I, "FUEV:: ProcessIntLineEvents Entry\n"));
+
+   DEBUG ((USB_FUIO_DEBUG_EVENT_I, "FUEV:: XdciCorePtr->CurrentEventBuffer 0x%08x\n", XdciCorePtr->CurrentEventBuffer));
+   DEBUG ((USB_FUIO_DEBUG_EVENT_I, "FUEV::EventCount0x%08x\n", EventCount));
+   DEBUG ((USB_FUIO_DEBUG_EVENT_I, "FUEV::CurrentEventAddr 0x%08x\n", CurrentEventAddr));
+
+  while ((EventCount != 0) && (EventReport == FALSE)) {
+     DEBUG ((USB_FUIO_DEBUG_EVENT_D, "FUEV::event0x%08x\n", XdciCorePtr->CurrentEventBuffer->Event));
+     if ((XdciCorePtr->CurrentEventBuffer->Event & DWC_XDCI_EVENT_DEV_MASK) != 0) {
+       //
+       // Device event
+       //
+       DeviceEventCheck (
+         This,
+         (USBD_EVENT_BUF*)(UINTN)CurrentEventAddr,
+         &ProceSsEventSize,
+         Message,
+         &EventReport
+         );
+       if (EventReport == TRUE) {
+         *EventFlag = TRUE;
+       }
+
+     } else {
+       //
+       // EndPoint Event
+       //
+       EpEventCheck (
+         This,
+         (USBD_EVENT_BUF*)(UINTN)CurrentEventAddr,
+         &ProceSsEventSize,
+         Message,
+         PayloadSize,
+         Payload,
+         &EpEventReport
+         );
+     }
+
+     if ((*Message != EfiUsbMsgNone) || (EpEventReport == TRUE)) {
+       EventReport = TRUE;
+       *EventFlag = TRUE;
+     }
+
+     DEBUG ((USB_FUIO_DEBUG_EVENT_D, "FUEV:: CurrentEventAddr 0x%08x :: ProceSsEventSize 0x%08x\n", (UINTN)CurrentEventAddr,ProceSsEventSize));
+
+     EventCount -= ProceSsEventSize;
+     *ProceSsEvent += ProceSsEventSize;
+     if ((CurrentEventAddr + ProceSsEventSize) >= \
+         ((UINT32)(UINTN)(XdciCorePtr->AlignedEventBuffers) +
+          (sizeof(DWC_XDCI_EVENT_BUFFER) * DWC_XDCI_MAX_EVENTS_PER_BUFFER))) {
+       CurrentEventAddr = (UINT32)(UINTN)(XdciCorePtr->AlignedEventBuffers);
+    } else {
+      CurrentEventAddr += ProceSsEventSize;
+    }
+    DEBUG ((USB_FUIO_DEBUG_EVENT_D, "FUEV:: CurrentEventAddr Update 0x%08x :: ProceSsEventSize 0x%08x\n", CurrentEventAddr,ProceSsEventSize));
+
+    XdciCorePtr->CurrentEventBuffer = (DWC_XDCI_EVENT_BUFFER*)(UINTN)CurrentEventAddr;
+  }
+
+  DEBUG ((USB_FUIO_DEBUG_EVENT_I, "FUEV:: ProcessIntLineEvents Exit\n\n"));
+  return EFI_SUCCESS;
+}
+
+
+/**
+  ISR inokes Event Handler.  Look at which interrupt has happened and see
+  if there are event handler registerd and if so fire them 1 by one.
+
+  @param[in]  This              A pointer to the EFI_USBFN_IO_PROTOCOL instance.
+  @param[in]  Message           Indicates the event that initiated this
+                                notification.
+  @param[in]  PayloadSize       On input, the size of the memory pointed by Payload.
+                                On output, the amount of data returned in Payload.
+  @param[in]  Payload           A pointer to EFI_USBFN_MESSAGE_PAYLOAD instance to
+                                return additional payload for current message.
+
+
+
+
+  @retval EFI_SUCCESS           The function returned successfully.
+  @retval EFI_INVALID_PARAMETER A parameter is invalid.
+  @retval EFI_DEVICE_ERROR      The physical device reported an error.
+  @retval EFI_NOT_READY         The physical device is busy or not ready to
+                                process this request.
+  @retval EFI_BUFFER_TOO_SMALL  Supplied Buffer not large enough to hold
+                                the message payload.
+
+**/
+EFI_STATUS
+EFIAPI
+EventHandler(
+  IN EFI_USBFN_IO_PROTOCOL        *This,
+  OUT EFI_USBFN_MESSAGE           *Message,
+  IN OUT UINTN                    *PayloadSize,
+  OUT EFI_USBFN_MESSAGE_PAYLOAD   *Payload
+  )
+{
+  UINT32                          EventCount;
+  UINT32                          PeventCount;
+  USB_XDCI_DEV_CONTEXT            *UsbFuncIoDevPtr;
+  UINT32                          MaxIntNum;
+  UINT32                          IntIndex;
+  USB_DEV_CORE                    *UsbDeviceCorePtr;
+  XDCI_CORE_HANDLE                *XdciCorePtr;
+  BOOLEAN                         EventFlag;
+  EFI_TPL                         OriginalTpl;
+
+
+  DEBUG ((USB_FUIO_DEBUG_EVENT_I, "USBFU_ EventHandler Entry\n"));
+  UsbFuncIoDevPtr = USBFUIO_CONTEXT_FROM_PROTOCOL (This);
+
+  if (UsbFuncIoDevPtr->StartUpController == FALSE) {
+    UsbFnInitDevice (This);
+  }
+  OriginalTpl = gBS->RaiseTPL (TPL_HIGH_LEVEL);
+  *Message = EfiUsbMsgNone;
+  MaxIntNum = (UsbRegRead ((UINT32)UsbFuncIoDevPtr->XdciMmioBarAddr, DWC_XDCI_GHWPARAMS1_REG) &
+                 DWC_XDCI_GHWPARAMS1_NUM_INT_MASK) >>
+                 DWC_XDCI_GHWPARAMS1_NUM_INT_BIT_POS;
+
+  UsbDeviceCorePtr = UsbFuncIoDevPtr->DrvCore;
+  XdciCorePtr = UsbDeviceCorePtr->ControllerHandle;
+  EventFlag = TRUE;
+
+  DEBUG ((USB_FUIO_DEBUG_EVENT_I, "XdciCorePtr->MaxDevIntLines 0x%08x\n", XdciCorePtr->MaxDevIntLines));
+  EventCount = UsbRegRead ((UINT32)UsbFuncIoDevPtr->XdciMmioBarAddr, DWC_XDCI_EVNTCOUNT_REG(0));
+
+  for (IntIndex = 0; IntIndex < XdciCorePtr->MaxDevIntLines ; IntIndex++) {
+    //
+    // Get the number of events HW has written for this
+    //  interrupt line
+    //
+    EventCount = UsbRegRead ((UINT32)UsbFuncIoDevPtr->XdciMmioBarAddr, DWC_XDCI_EVNTCOUNT_REG(IntIndex));
+    EventCount &= DWC_XDCI_EVNTCOUNT_MASK;
+    PeventCount = 0;
+
+    //
+    // Process interrupt line Buffer only if count is non-zero
+    //
+    if (EventCount) {
+      //
+      // Process events in this Buffer
+      //
+      ProcessIntLineEvents (
+        This,
+        EventCount,
+        &PeventCount,
+        Message,
+        PayloadSize,
+        Payload,
+        &EventFlag
+        );
+
+      //
+      // Write back the Processed number of events so HW decrements it from current
+      // event count
+      //
+      UsbRegWrite ((UINT32)UsbFuncIoDevPtr->XdciMmioBarAddr, DWC_XDCI_EVNTCOUNT_REG(IntIndex), PeventCount);
+
+      //
+      // for debug
+      //
+      if (*Message != EfiUsbMsgNone) {
+        break;
+      }
+
+      if (EventFlag == TRUE) {
+        break;
+      }
+    }
+  }
+
+  gBS->RestoreTPL (OriginalTpl);
+  //
+  //EVENT_EXIT:
+  //
+  DEBUG ((USB_FUIO_DEBUG_EVENT_I, "USBFU_ EventHandler Exit\n"));
+  return EFI_SUCCESS;
+}
+
+
+
+/**
+  Copies relevant endpoint data from standard USB endpoint descriptors
+  to the usbEpInfo structure used by the XDCI
+
+  @param pEpDest   destination structure
+  @param pEpSrc    source structure
+
+  @return VOID
+
+**/
+VOID
+UsbFnSetEpInfo (
+  IN USB_EP_INFO                 *EpDest,
+  IN USB_DEVICE_ENDPOINT_INFO    *EpSrc
+  )
+{
+  EFI_USB_ENDPOINT_DESCRIPTOR              *EpDesc = NULL;
+  EFI_USB_ENDPOINT_COMPANION_DESCRIPTOR    *EpCompDesc = NULL;
+
+  //
+  // start by clearing all data in the destination
+  //
+  SetMem (EpDest, sizeof(USB_EP_INFO), 0);
+  EpDesc = EpSrc->EndpointDesc;
+  EpCompDesc = EpSrc->EndpointCompDesc;
+
+  if (EpDesc != NULL) {
+    EpDest->EpNum = EpDesc->EndpointAddress & 0x0F; // Bits 0-3 are ep num
+    EpDest->EpDir = ((EpDesc->EndpointAddress & USB_ENDPOINT_DIR_IN) > 0) ? UsbEpDirIn : UsbEpDirOut;
+    DEBUG ((DEBUG_INFO, "EpDest->EpNum 0x%02x\n", EpDest->EpNum));
+    DEBUG ((DEBUG_INFO, "EpDest->EpDir 0x%02x\n", EpDest->EpDir));
+    EpDest->EpType = EpDesc->Attributes & USB_ENDPOINT_TYPE_MASK;
+    EpDest->MaxPktSize = EpDesc->MaxPacketSize;
+    EpDest->Interval = EpDesc->Interval;
+  }
+  if (EpCompDesc != NULL) {
+    EpDest->MaxStreams = EpCompDesc->Attributes & USB_EP_BULK_BM_ATTR_MASK;
+    EpDest->BurstSize = EpCompDesc->MaxBurst;
+    EpDest->Mult = EpCompDesc->BytesPerInterval;
+  }
+
+  return;
+}
+
+
+EFI_STATUS
+SetFnIoReqInfo(
+  IN     EFI_USBFN_IO_PROTOCOL         *This,
+  IN     UINT8                         EndpointIndex,
+  IN     EFI_USBFN_ENDPOINT_DIRECTION  Direction,
+  IN OUT UINTN                         *BufferSize,
+  IN OUT VOID                          *Buffer,
+  IN OUT USB_XFER_REQUEST              *XfIoreq
+  )
+{
+  USB_XDCI_DEV_CONTEXT     *UsbFuncIoDevPtr;
+  EFI_STATUS               Status;
+  UINTN                    ReqPacket;
+
+  UsbFuncIoDevPtr = USBFUIO_CONTEXT_FROM_PROTOCOL (This);
+  Status = EFI_SUCCESS;
+  ReqPacket = 0;
+
+  switch (EndpointIndex) {
+    case 0: // Control endpoint
+      XfIoreq->EpInfo.EpNum = 0;
+      XfIoreq->EpInfo.EpDir = Direction? UsbEpDirIn : UsbEpDirOut;
+      break;
+
+
+    default:
+      if (Direction == EfiUsbEndpointDirectionDeviceTx) {
+        UsbFnSetEpInfo (&XfIoreq->EpInfo, &UsbFuncIoDevPtr->IndexPtrInEp);
+      } else {
+        UsbFnSetEpInfo (&XfIoreq->EpInfo, &UsbFuncIoDevPtr->IndexPtrOutEp);
+        //
+        // reference from "UsbDeviceMode.c", function UsbdEpRxData
+        //
+
+        //
+        // Transfer length should be multiple of USB packet size.
+        //
+        ReqPacket = *BufferSize/ XfIoreq->EpInfo.MaxPktSize;
+        ReqPacket = ((XfIoreq->XferLen % XfIoreq->EpInfo.MaxPktSize) == 0)? ReqPacket : ReqPacket + 1;
+        XfIoreq->XferLen = (UINT32)ReqPacket * XfIoreq->EpInfo.MaxPktSize;
+
+      }
+      break;
+  }
+
+  if (EFI_ERROR(Status)) {
+    return EFI_UNSUPPORTED;
+  }
+
+  XfIoreq->XferBuffer = Buffer;
+  XfIoreq->XferLen = (UINT32)(*BufferSize);
+  XfIoreq->XferDone = NULL;
+
+  return EFI_SUCCESS;
+}
+
+
+/**
+  Primary function to handle transfer in either direction Based on specified
+  direction and on the specified endpoint.
+
+  @param[in]  This              A pointer to the EFI_USBFN_IO_PROTOCOL instance.
+  @param[in]  EndpointIndex     Indicates the endpoint on which TX or RX transfer
+                                needs to take place.
+  @param[in]  Direction         Direction of the endpoint.
+  @param[in]  BufferSize        If Direction is EfiUsbEndpointDirectionDeviceRx:
+                                On input, the size of the Buffer in bytes.
+                                On output, the amount of data returned in Buffer in bytes.
+                                If Direction is EfiUsbEndpointDirectionDeviceTx:
+                                On input, the size of the Buffer in bytes.
+                                On output, the amount of data actually transmitted in bytes.
+  @param[in]  Buffer            If Direction is EfiUsbEndpointDirectionDeviceRx:
+                                The Buffer to return the received data.
+                                If Direction is EfiUsbEndpointDirectionDeviceTx:
+                                The Buffer that contains the data to be transmitted.
+
+  @retval EFI_SUCCESS           The function returned successfully.
+  @retval EFI_INVALID_PARAMETER A parameter is invalid.
+  @retval EFI_DEVICE_ERROR      The physical device reported an error.
+  @retval EFI_NOT_READY         The physical device is busy or not ready to
+                                process this request.
+
+**/
+EFI_STATUS
+EFIAPI
+Transfer (
+  IN EFI_USBFN_IO_PROTOCOL         *This,
+  IN UINT8                         EndpointIndex,
+  IN EFI_USBFN_ENDPOINT_DIRECTION  Direction,
+  IN OUT UINTN                     *BufferSize,
+  IN OUT VOID                      *Buffer
+  )
+{
+  USB_XDCI_DEV_CONTEXT              *UsbFuncIoDevPtr;
+  USB_DEV_CORE                      *UsbDeviceCorePtr;
+  XDCI_CORE_HANDLE                  *XdciCorePtr;
+  EFI_STATUS                        Status;
+  USB_XFER_REQUEST                  XferReq;
+  UINT32                            EndPoint;
+
+  DEBUG ((USB_FUIO_DEBUG_LOAD, "\n FU:Transfer - Entry\n"));
+  DEBUG ((USB_FUIO_DEBUG_LOAD, "\n FU:EndpointIndex 0x%02x\n", EndpointIndex));
+  DEBUG ((USB_FUIO_DEBUG_LOAD, "\n FU:Direction 0x%02x\n", Direction));
+
+  UsbFuncIoDevPtr = USBFUIO_CONTEXT_FROM_PROTOCOL (This);
+
+  UsbDeviceCorePtr = UsbFuncIoDevPtr->DrvCore;
+  XdciCorePtr = UsbDeviceCorePtr->ControllerHandle;
+  EndPoint = UsbGetPhysicalEpNum (EndpointIndex, Direction ? UsbEpDirIn : UsbEpDirOut);
+
+  Status = SetFnIoReqInfo (
+             This,
+             EndpointIndex,
+             Direction,
+             BufferSize,
+             Buffer,
+             &XferReq
+             );
+
+  if (EFI_ERROR(Status)) {
+    DEBUG ((USB_FUIO_DEBUG_LOAD, "Set SetFnIoReqInfo - Error Stop!!!\n"));
+    while(1);
+    Status = EFI_DEVICE_ERROR;
+    goto FUN_EXIT;
+  }
+
+  UsbFuncIoDevPtr->EndPointXferRec[EndPoint].EpNum = EndPoint;
+  UsbFuncIoDevPtr->EndPointXferRec[EndPoint].Direction = Direction;
+  UsbFuncIoDevPtr->EndPointXferRec[EndPoint].XferAddress = (UINTN)Buffer;
+  UsbFuncIoDevPtr->EndPointXferRec[EndPoint].XferLength = (UINT32)(*BufferSize);
+  UsbFuncIoDevPtr->EndPointXferRec[EndPoint].LogEpNum = EndpointIndex;
+  UsbFuncIoDevPtr->EndPointXferRec[EndPoint].Complete = FALSE;
+  UsbFuncIoDevPtr->EndPointXferRec[EndPoint].ZlpFlag = FALSE;
+
+  Status = EFI_DEVICE_ERROR;
+  switch (EndpointIndex) {
+    case 0: // Control endpoint
+      if (*BufferSize == 0) {
+        if (Direction == EfiUsbEndpointDirectionDeviceTx) {
+          Status = UsbDeviceEp0TxStatus(UsbDeviceCorePtr);
+        } else {
+          Status = UsbDeviceEp0RxStatus(UsbDeviceCorePtr);
+        }
+      } else if (Direction == EfiUsbEndpointDirectionDeviceTx) {
+        Status = UsbXdciDeviceEpTxData(UsbDeviceCorePtr, &XferReq);
+      } else if (Direction == EfiUsbEndpointDirectionDeviceRx) {
+        DEBUG ((USB_FUIO_DEBUG_LOAD, "\n Set Setup Package - ??? Stop!!!\n"));
+      }
+      break;
+
+    default:
+      Status = EFI_SUCCESS;
+      if (Direction == EfiUsbEndpointDirectionDeviceTx) {
+        DEBUG ((USB_FUIO_DEBUG_LOAD, "\n EfiUsbEndpointDirectionDeviceTx Size = %d\n",(*BufferSize) ));
+        XferReq.Zlp = TRUE;
+        if ((((*BufferSize) % 512) == 0) && ((*BufferSize) != 0)) {
+          UsbFuncIoDevPtr->EndPointXferRec[EndPoint].ZlpFlag = TRUE;
+          DEBUG ((USB_FUIO_DEBUG_LOAD, "\n Set Zlp flag\n"));
+        }
+        Status = UsbXdciDeviceEpTxData (UsbDeviceCorePtr, &XferReq);
+      } else {
+        DEBUG ((USB_FUIO_DEBUG_LOAD, "\n EfiUsbEndpointDirectionDeviceRx Size = %d\n",(*BufferSize) ));
+        Status = UsbXdciDeviceEpRxData (UsbDeviceCorePtr, &XferReq);
+      }
+      break;
+  }
+
+  if (EFI_ERROR(Status)) {
+    goto FUN_EXIT;
+  }
+
+  if (Status != EFI_SUCCESS) {
+    Status = EFI_DEVICE_ERROR;
+  }
+
+FUN_EXIT:
+
+  DEBUG ((USB_FUIO_DEBUG_LOAD, "FU:Transfer - Exit %r\n", Status));
+  return Status;
+}
+
+
+/**
+  This function supplies power to the USB controller if needed, initialize
+  hardware and internal data structures, and then return.
+  The port must not be activated by this function.
+
+  @param[in]  This              A pointer to the EFI_USBFN_IO_PROTOCOL instance.
+
+  @retval EFI_SUCCESS           The function returned successfully.
+  @retval EFI_INVALID_PARAMETER A parameter is invalid.
+  @retval EFI_DEVICE_ERROR      The physical device reported an error.
+**/
+EFI_STATUS
+EFIAPI
+StartXdciController (
+  IN EFI_USBFN_IO_PROTOCOL    *This
+  )
+{
+  USB_XDCI_DEV_CONTEXT         *UsbFuncIoDevPtr;
+  USB_DEV_CONFIG_PARAMS        ConfigParams;
+  EFI_STATUS                   Status;
+
+  Status = EFI_SUCCESS;
+  UsbFuncIoDevPtr = USBFUIO_CONTEXT_FROM_PROTOCOL (This);
+
+  if (UsbFuncIoDevPtr->StartUpController == TRUE) {
+    goto EXIT_START_CONTROLLER;
+  }
+
+  ConfigParams.ControllerId = USB_ID_DWC_XDCI;
+  ConfigParams.BaseAddress = (UINT32)UsbFuncIoDevPtr->XdciMmioBarAddr;
+  ConfigParams.Role = USB_ROLE_DEVICE;
+  ConfigParams.Speed = USB_SPEED_HIGH;
+
+  //
+  //*Vid = 0x8086
+  //*Pid = 0x0A65
+  //
+  UsbFuncIoDevPtr->VendorId = USBFU_VID;
+  UsbFuncIoDevPtr->DeviceId = USBFU_PID;
+  UsbFuncIoDevPtr->StartUpController = TRUE;
+
+  Status = UsbDeviceInit (&ConfigParams, (VOID **)&UsbFuncIoDevPtr->DrvCore);
+  if (Status != EFI_SUCCESS) {
+    Status = EFI_DEVICE_ERROR;
+    goto EXIT_START_CONTROLLER;
+  }
+
+  UsbFuncIoDevPtr->XdciDrvIfHandle = UsbFuncIoDevPtr->DrvCore->ControllerHandle;
+
+EXIT_START_CONTROLLER:
+
+  DEBUG ((USB_FUIO_DEBUG_LOAD, "StartXdciController - Exit :: %r\n", Status));
+  return Status;
+}
+
+
+/**
+  This function disables the hardware device by resetting the run/stop bit
+  and power off the USB controller if needed.
+
+  @param[in]  This              A pointer to the EFI_USBFN_IO_PROTOCOL instance.
+
+  @retval EFI_SUCCESS           The function returned successfully.
+  @retval EFI_INVALID_PARAMETER A parameter is invalid.
+  @retval EFI_DEVICE_ERROR      The physical device reported an error.
+**/
+EFI_STATUS
+EFIAPI
+StopXdciController (
+  IN EFI_USBFN_IO_PROTOCOL    *This
+  )
+{
+  USB_XDCI_DEV_CONTEXT  *UsbFuncIoDevPtr;
+  EFI_STATUS            DevStatus;
+
+  UsbFuncIoDevPtr = USBFUIO_CONTEXT_FROM_PROTOCOL (This);
+  DEBUG ((USB_FUIO_DEBUG_LOAD, "StopController - Entry\n"));
+
+  if (UsbFuncIoDevPtr->StartUpController == FALSE) {
+    DEBUG ((USB_FUIO_DEBUG_LOAD, "The Controller not yet start up skip deinit\n"));
+    return EFI_SUCCESS;
+  }
+
+  if (This == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  DevStatus = UsbDeviceDeinit (UsbFuncIoDevPtr->DrvCore, TRUE);
+
+  UsbFuncIoDevPtr->DrvCore = NULL;
+  UsbFuncIoDevPtr->XdciDrvIfHandle = NULL;
+  UsbFuncIoDevPtr->StartUpController = FALSE;
+
+  if (DevStatus != EFI_SUCCESS) {
+    return EFI_DEVICE_ERROR;
+  }
+
+  DEBUG ((USB_FUIO_DEBUG_LOAD, "StopController - Exit\n"));
+  return EFI_SUCCESS;
+}
+
+
+/**
+  This function sets the configuration policy for the specified non-control endpoint.
+  Refer to the description for calling restrictions
+
+  @param[in]  This              A pointer to the EFI_USBFN_IO_PROTOCOL instance.
+  @param[in]  EndpointIndex     Indicates the non-control endpoint for
+                                which the policy needs to be set.
+  @param[in]  Direction         Direction of the endpoint.
+  @param[in]  PolicyType        Policy type the user is trying to set for
+                                the specified non-control endpoint.
+  @param[in]  BufferSize        The size of the Buffer in bytes.
+  @param[in]  Buffer            The new value for the policy parameter that
+                                PolicyType specifies.
+
+
+  @retval EFI_SUCCESS           The function returned successfully.
+  @retval EFI_INVALID_PARAMETER A parameter is invalid.
+  @retval EFI_DEVICE_ERROR      The physical device reported an error.
+  @retval EFI_UNSUPPORTED       Changing this policy value is not supported.
+
+**/
+EFI_STATUS
+EFIAPI
+SetEndpointPolicy (
+  IN EFI_USBFN_IO_PROTOCOL        *This,
+  IN UINT8                        EndpointIndex,
+  IN EFI_USBFN_ENDPOINT_DIRECTION Direction,
+  IN EFI_USBFN_POLICY_TYPE        PolicyType,
+  IN UINTN                        BufferSize,
+  IN VOID                         *Buffer
+  )
+{
+  USB_XDCI_DEV_CONTEXT  *UsbFuncIoDevPtr;
+  EFI_STATUS            Status;
+  UINT32                EndPoint;
+  UINT8                 *FlagPtr;
+
+  UsbFuncIoDevPtr = USBFUIO_CONTEXT_FROM_PROTOCOL (This);
+  FlagPtr = NULL;
+
+  switch (PolicyType) {
+    case EfiUsbPolicyUndefined:
+    case EfiUsbPolicyMaxTransactionSize:
+    case EfiUsbPolicyZeroLengthTerminationSupport:
+
+     Status = EFI_UNSUPPORTED;
+     break;
+
+    default:
+     FlagPtr = Buffer;
+     Status = EFI_SUCCESS;
+     break;
+  }
+
+  if (BufferSize < 1) {
+    Status = EFI_INVALID_PARAMETER;
+  }
+
+  if (EFI_ERROR(Status)) {
+    DEBUG ((USB_FUIO_DEBUG_LOAD, "SetEndpointPolicy - ERROR %r\n", Status));
+    return Status;
+  }
+
+  EndPoint = UsbGetPhysicalEpNum (EndpointIndex, Direction ? UsbEpDirIn : UsbEpDirOut);
+
+  UsbFuncIoDevPtr->EndPointXferRec[EndPoint].ZlpFlag = *FlagPtr;
+
+  return Status;
+}
+
+
+/**
+  This function retrieves the configuration policy for the specified non-control
+  endpoint. There are no associated calling restrictions for this function.
+
+  @param[in]  This              A pointer to the EFI_USBFN_IO_PROTOCOL instance.
+  @param[in]  EndpointIndex     Indicates the non-control endpoint for
+                                which the policy needs to be set.
+  @param[in]  Direction         Direction of the endpoint.
+  @param[in]  PolicyType        Policy type the user is trying to set for
+                                the specified non-control endpoint.
+  @param[in]  BufferSize        The size of the Buffer in bytes.
+  @param[in]  Buffer            The new value for the policy parameter that
+                                PolicyType specifies.
+
+
+  @retval EFI_SUCCESS           The function returned successfully.
+  @retval EFI_INVALID_PARAMETER A parameter is invalid.
+  @retval EFI_DEVICE_ERROR      The physical device reported an error.
+  @retval EFI_UNSUPPORTED       Changing this policy value is not supported.
+  @retval EFI_BUFFER_TOO_SMALL  Supplied Buffer is not large enough to
+                                hold requested policy value.
+
+**/
+EFI_STATUS
+EFIAPI
+GetEndpointPolicy (
+  IN EFI_USBFN_IO_PROTOCOL        *This,
+  IN UINT8                        EndpointIndex,
+  IN EFI_USBFN_ENDPOINT_DIRECTION Direction,
+  IN EFI_USBFN_POLICY_TYPE        PolicyType,
+  IN OUT UINTN                    *BufferSize,
+  IN OUT VOID                     *Buffer
+  )
+{
+  USB_XDCI_DEV_CONTEXT  *UsbFuncIoDevPtr;
+  EFI_STATUS            Status;
+  UINT32                EndPoint;
+  UINT32                MaxPacketSize;
+  BOOLEAN               SetFlag;
+
+  UsbFuncIoDevPtr = USBFUIO_CONTEXT_FROM_PROTOCOL (This);
+  MaxPacketSize = 0;
+  SetFlag = FALSE;
+
+  switch (PolicyType) {
+    case EfiUsbPolicyUndefined:
+
+     Status = EFI_UNSUPPORTED;
+     break;
+
+    case EfiUsbPolicyMaxTransactionSize:
+    case EfiUsbPolicyZeroLengthTerminationSupport:
+    default:
+     if (Buffer == NULL) {
+       Status = EFI_INVALID_PARAMETER;
+     } else {
+       Status = EFI_SUCCESS;
+     }
+     break;
+  }
+
+  EndPoint = UsbGetPhysicalEpNum (EndpointIndex, Direction ? UsbEpDirIn : UsbEpDirOut);
+
+  if (EFI_ERROR(Status)) {
+    DEBUG ((USB_FUIO_DEBUG_LOAD, "GetEndpointPolicy - ERROR %r\n", Status));
+    return Status;
+  }
+
+  if (PolicyType == EfiUsbPolicyMaxTransactionSize) {
+
+    if (*BufferSize < sizeof(UINT32)) {
+       Status = EFI_INVALID_PARAMETER;
+    } else {
+      MaxPacketSize = MAX_TRANSFER_PACKET;
+      CopyMem (Buffer, &MaxPacketSize, sizeof(UINT32));
+    }
+
+  } else if (PolicyType == EfiUsbPolicyZeroLengthTerminationSupport) {
+    if (*BufferSize < sizeof(BOOLEAN)) {
+       Status = EFI_INVALID_PARAMETER;
+    } else {
+      SetFlag = TRUE;
+      CopyMem (Buffer, &SetFlag, sizeof(BOOLEAN));
+    }
+
+  } else if (PolicyType == EfiUsbPolicyZeroLengthTermination) {
+    if (*BufferSize < sizeof(BOOLEAN)) {
+       Status = EFI_INVALID_PARAMETER;
+    } else {
+      SetFlag =  UsbFuncIoDevPtr->EndPointXferRec[EndPoint].ZlpFlag;
+      CopyMem (Buffer, &SetFlag, sizeof(BOOLEAN));
+    }
+  } else {
+    Status = EFI_INVALID_PARAMETER;
+  }
+
+  return Status;
+}
+
+EFI_STATUS
+UsbFnInitDevice (
+  IN EFI_USBFN_IO_PROTOCOL        *This
+  )
+{
+  EFI_STATUS                   Status;
+  USB_XDCI_DEV_CONTEXT         *UsbFuncIoDevPtr;
+
+  Status = EFI_SUCCESS;
+  UsbFuncIoDevPtr = USBFUIO_CONTEXT_FROM_PROTOCOL (This);
+
+  PlatformSpecificInit ();
+
+  UsbFuncIoDevPtr->StartUpController = FALSE;
+  Status = StartXdciController (&UsbFuncIoDevPtr->UsbFunIoProtocol);
+  if (EFI_ERROR (Status)) {
+    Status = EFI_DEVICE_ERROR;
+    goto DEV_INIT_EXIT;
+  }
+
+  Status = UsbXdciDeviceConnect (UsbFuncIoDevPtr->DrvCore);
+  DEBUG ((USB_FUIO_DEBUG_LOAD, "UsbXdciDeviceConnect Status %x\n", Status));
+  if (Status != EFI_SUCCESS) {
+    Status = EFI_DEVICE_ERROR;
+    goto DEV_INIT_EXIT;
+  }
+
+
+DEV_INIT_EXIT:
+
+  return Status;
+}
+
+EFI_STATUS
+EFIAPI
+StartController (
+  IN EFI_USBFN_IO_PROTOCOL        *This
+  )
+{
+  return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+UsbFnDeInitDevice (
+  IN EFI_USBFN_IO_PROTOCOL        *This
+  )
+{
+  EFI_STATUS                   Status;
+  USB_XDCI_DEV_CONTEXT         *UsbFuncIoDevPtr;
+
+  UsbFuncIoDevPtr = USBFUIO_CONTEXT_FROM_PROTOCOL (This);
+
+  if (UsbFuncIoDevPtr->StartUpController == FALSE) {
+    DEBUG ((USB_FUIO_DEBUG_LOAD, "UsbFn:StopController:The Controller not yet start up force return EFI_SUCCESS\n"));
+    return EFI_SUCCESS;
+  }
+
+  //
+  // disconnect
+  //
+  Status = UsbDeviceDisconnect (UsbFuncIoDevPtr->DrvCore);
+  DEBUG ((USB_FUIO_DEBUG_LOAD, "UsbDeviceDisconnect Status %x\n", Status));
+  if (Status != EFI_SUCCESS) {
+    Status = EFI_DEVICE_ERROR;
+    goto DEV_DEINIT_EXIT;
+  }
+
+  //
+  // StopController
+  //
+  Status = StopXdciController (&UsbFuncIoDevPtr->UsbFunIoProtocol);
+  UsbFuncIoDevPtr->StartUpController = FALSE;
+
+DEV_DEINIT_EXIT:
+  return Status;
+}
+
+EFI_STATUS
+EFIAPI
+StopController (
+  IN EFI_USBFN_IO_PROTOCOL        *This
+  )
+{
+  return UsbFnDeInitDevice(This);
+}
+
diff --git a/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbFuncIo.h b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbFuncIo.h
new file mode 100644
index 0000000000..ad3d296db9
--- /dev/null
+++ b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbFuncIo.h
@@ -0,0 +1,234 @@
+/** @file
+  Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR>
+
+  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.
+
+**/
+
+#ifndef __EFI_USB_FUNCTION_IO_INTERFACE_H__
+#define __EFI_USB_FUNCTION_IO_INTERFACE_H__
+
+#include <Uefi.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/DriverLib.h>
+#include <Library/PcdLib.h>
+#include <Protocol/EfiUsbFnIo.h>
+#include <Library/PmicLib.h>
+#include <Library/UsbDeviceLib.h>
+#include <Library/PrintLib.h>
+#include "UsbIoNode.h"
+#include "XdciDWC.h"
+#include "UsbDeviceMode.h"
+
+//
+// Debug message setting
+//
+#define USB_FUIO_DEBUG_INFO              EFI_D_INFO
+#define USB_FUIO_DEBUG_LOAD              EFI_D_LOAD
+#define USB_FUIO_DEBUG_ERROR             EFI_D_ERROR
+#define USB_FUIO_DEBUG_EVENT_I           0 //DEBUG_INIT
+#define USB_FUIO_DEBUG_EVENT_D           EFI_D_ERROR
+#define USB_FUIO_DEBUG_EVENT_NOTREADY_D  EFI_D_ERROR
+#define USB_FUIO_DEBUG_EVENT_NOTREADY_I  0 //DEBUG_INIT
+
+#define MAX_TRANSFER_PACKET     (8 * 1024 * 1024)
+
+#define USBFU_VID     0x8086
+#define USBFU_PID     0x0A65
+
+#pragma pack(1)
+typedef struct {
+  UINT8                     ProgInterface;
+  UINT8                     SubClassCode;
+  UINT8                     BaseCode;
+} USB_CLASSC;
+
+//
+// Event Buffer Struct
+//
+typedef struct  {
+  UINT32 Event;
+  UINT32 DevTstLmp1;
+  UINT32 DevTstLmp2;
+  UINT32 Reserved;
+} USBD_EVENT_BUF;
+
+typedef struct  {
+  UINT32                        EpNum;
+  EFI_USBFN_ENDPOINT_DIRECTION  Direction;
+  UINTN                         XferAddress;
+  UINT32                        XferLength;
+  UINT8                         LogEpNum;
+  BOOLEAN                       Complete;
+  BOOLEAN                       ZlpFlag;
+} USBD_EP_XFER_REC;
+
+#pragma pack()
+
+EFI_STATUS
+UsbFnInitDevice (
+  IN EFI_USBFN_IO_PROTOCOL        *This
+  );
+
+EFI_STATUS
+UsbFnDeInitDevice (
+  IN EFI_USBFN_IO_PROTOCOL        *This
+  );
+
+EFI_STATUS
+EFIAPI
+DetectPort (
+  IN EFI_USBFN_IO_PROTOCOL         *This,
+  OUT EFI_USBFN_PORT_TYPE          *PortType
+  );
+
+EFI_STATUS
+EFIAPI
+AllocateTransferBuffer (
+  IN EFI_USBFN_IO_PROTOCOL         *This,
+  IN UINTN                         Size,
+  OUT VOID                         **Buffer
+  );
+
+EFI_STATUS
+EFIAPI
+FreeTransferBuffer (
+  IN EFI_USBFN_IO_PROTOCOL         *This,
+  IN VOID                          *Buffer
+  );
+
+EFI_STATUS
+EFIAPI
+ConfigureEnableEndpoints (
+  IN EFI_USBFN_IO_PROTOCOL         *This,
+  IN EFI_USB_DEVICE_INFO           *DeviceInfo
+ );
+
+EFI_STATUS
+EFIAPI
+GetEndpointMaxPacketSize (
+  IN EFI_USBFN_IO_PROTOCOL         *This,
+  IN EFI_USB_ENDPOINT_TYPE         EndpointType,
+  IN EFI_USB_BUS_SPEED             BusSpeed,
+  OUT UINT16                       *MaxPacketSize
+ );
+
+EFI_STATUS
+EFIAPI
+GetMaxTransferSize (
+  IN EFI_USBFN_IO_PROTOCOL         *This,
+  OUT UINTN                        *MaxTransferSize
+  );
+
+EFI_STATUS
+EFIAPI
+GetDeviceInfo (
+  IN EFI_USBFN_IO_PROTOCOL         *This,
+  IN EFI_USBFN_DEVICE_INFO_ID      Id,
+  IN OUT UINTN                     *BufferSize,
+  OUT VOID                         *Buffer OPTIONAL
+  );
+
+EFI_STATUS
+EFIAPI
+GetVendorIdProductId (
+  IN EFI_USBFN_IO_PROTOCOL         *This,
+  OUT UINT16                       *Vid,
+  OUT UINT16                       *Pid
+  );
+
+EFI_STATUS
+EFIAPI
+AbortTransfer (
+  IN EFI_USBFN_IO_PROTOCOL        *This,
+  IN UINT8                        EndpointIndex,
+  IN EFI_USBFN_ENDPOINT_DIRECTION Direction
+  );
+
+EFI_STATUS
+EFIAPI
+GetEndpointStallState (
+  IN EFI_USBFN_IO_PROTOCOL         *This,
+  IN UINT8                         EndpointIndex,
+  IN EFI_USBFN_ENDPOINT_DIRECTION  Direction,
+  IN OUT BOOLEAN                   *State
+  );
+
+EFI_STATUS
+EFIAPI
+SetEndpointStallState (
+  IN EFI_USBFN_IO_PROTOCOL         *This,
+  IN UINT8                         EndpointIndex,
+  IN EFI_USBFN_ENDPOINT_DIRECTION  Direction,
+  IN BOOLEAN                       State
+  );
+
+EFI_STATUS
+EFIAPI
+EventHandler (
+  IN EFI_USBFN_IO_PROTOCOL         *This,
+  OUT EFI_USBFN_MESSAGE            *Message,
+  IN OUT UINTN                     *PayloadSize,
+  OUT EFI_USBFN_MESSAGE_PAYLOAD    *Payload
+  );
+
+EFI_STATUS
+EFIAPI
+Transfer (
+  IN EFI_USBFN_IO_PROTOCOL         *This,
+  IN UINT8                         EndpointIndex,
+  IN EFI_USBFN_ENDPOINT_DIRECTION  Direction,
+  IN OUT UINTN                     *BufferSize,
+  IN OUT VOID                      *Buffer
+  );
+
+EFI_STATUS
+EFIAPI
+StartController (
+  IN EFI_USBFN_IO_PROTOCOL         *This
+  );
+
+EFI_STATUS
+EFIAPI
+StopController (
+  IN EFI_USBFN_IO_PROTOCOL         *This
+  );
+
+EFI_STATUS
+EFIAPI
+SetEndpointPolicy (
+  IN EFI_USBFN_IO_PROTOCOL         *This,
+  IN UINT8                         EndpointIndex,
+  IN EFI_USBFN_ENDPOINT_DIRECTION  Direction,
+  IN EFI_USBFN_POLICY_TYPE         PolicyType,
+  IN UINTN                         BufferSize,
+  IN VOID                          *Buffer
+  );
+
+EFI_STATUS
+EFIAPI
+GetEndpointPolicy (
+  IN EFI_USBFN_IO_PROTOCOL         *This,
+  IN UINT8                         EndpointIndex,
+  IN EFI_USBFN_ENDPOINT_DIRECTION  Direction,
+  IN EFI_USBFN_POLICY_TYPE         PolicyType,
+  IN OUT UINTN                     *BufferSize,
+  IN OUT VOID                      *Buffer
+  );
+
+VOID
+UsbFnSetEpInfo (
+  IN USB_EP_INFO                 *EpDest,
+  IN USB_DEVICE_ENDPOINT_INFO    *EpSrc
+  );
+
+extern EFI_USBFN_IO_PROTOCOL         mUsbFunIoProtocol;
+#endif
+
diff --git a/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbIoNode.c b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbIoNode.c
new file mode 100644
index 0000000000..8fc6e10046
--- /dev/null
+++ b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbIoNode.c
@@ -0,0 +1,177 @@
+/** @file
+  Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR>
+
+  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.
+
+**/
+
+#include "UsbDeviceDxe.h"
+
+
+/**
+  The SearchNode function search a memory address for record the driver allocate
+  memory region and the node to the head link list.
+
+  @param[in]  This              A pointer to the EFI_USBFN_IO_PROTOCOL instance.
+  @param[in]  Buffer            The driver alocate memory address.
+  @param[out] Node              The match node record of the driver aloocate
+                                memory region.
+  @param[out] PNode             The pervious match node record of the driver
+                                aloocate memory region.
+
+  @retval EFI_SUCCESS           The operation completed successfully.
+  @retval EFI_NOT_FOUND         The memory Buffer didn't find.
+**/
+EFI_STATUS
+SearchNode (
+  IN  EFI_USBFN_IO_PROTOCOL    *This,
+  IN  VOID                     *Buffer,
+  OUT USB_MEM_NODE             **Node,
+  OUT USB_MEM_NODE             **PNode
+  )
+{
+  USB_XDCI_DEV_CONTEXT *UsbFuncIoDevPtr;
+  USB_MEM_NODE         *NodeL;
+  USB_MEM_NODE         *PNodeL;
+  EFI_STATUS           Status;
+
+  DEBUG ((USB_DEBUG_MEM_NODE_INFO, "SearchNode - Entry\n"));
+
+  UsbFuncIoDevPtr = USBFUIO_CONTEXT_FROM_PROTOCOL(This);
+  NodeL = UsbFuncIoDevPtr->FirstNodePtr;
+  PNodeL = NULL;
+  Status = EFI_NOT_FOUND;
+
+  while (Node != NULL) {
+    if (NodeL->AllocatePtr == Buffer) {
+      break;
+    }
+
+    PNodeL = NodeL;
+    NodeL = NodeL->NextPtr;
+  }
+
+  if (NodeL != NULL && Node != NULL) {
+    *Node = NodeL;
+    *PNode = PNodeL;
+    Status = EFI_SUCCESS;
+  }
+
+  DEBUG ((USB_DEBUG_MEM_NODE_INFO, "SearchNode - Exit %r\n", Status));
+  return Status;
+}
+
+/**
+  The InsertNewNodeToHead function remove a memory for record the driver allocate
+  memory region and the node to the head link list.
+
+  @param[in]  This              A pointer to the EFI_USBFN_IO_PROTOCOL instance.
+  @param[in]  Buffer            The driver alocate memory address.
+
+  @retval EFI_SUCCESS           The operation completed successfully.
+  @retval EFI_NOT_FOUND         The memory Buffer didn't find.
+**/
+EFI_STATUS
+RemoveNode (
+  IN  EFI_USBFN_IO_PROTOCOL    *This,
+  IN  VOID                     *Buffer
+  )
+{
+  USB_XDCI_DEV_CONTEXT *UsbFuncIoDevPtr;
+  USB_MEM_NODE         *Node;
+  USB_MEM_NODE         *PNode;
+  EFI_STATUS           Status;
+
+  DEBUG ((USB_DEBUG_MEM_NODE_INFO, "RemoveNode - Entry\n"));
+
+  UsbFuncIoDevPtr = USBFUIO_CONTEXT_FROM_PROTOCOL (This);
+
+  Status = SearchNode (This, Buffer, &Node, &PNode);
+
+  if (EFI_ERROR(Status) || PNode == NULL) {
+    DEBUG ((USB_DEBUG_MEM_NODE_ERROR, "RemoveNode - Node Not Found\n"));
+    return EFI_NOT_FOUND;
+  }
+
+  if (Node != UsbFuncIoDevPtr->FirstNodePtr) {
+    PNode->NextPtr = Node->NextPtr;
+  } else {
+    UsbFuncIoDevPtr->FirstNodePtr = Node->NextPtr;
+  }
+
+  FreePool (Node->AllocatePtr);
+  FreePool (Node);
+  DEBUG ((USB_DEBUG_MEM_NODE_INFO, "RemoveNode - Exit\n"));
+  return EFI_SUCCESS;
+}
+
+/**
+  The InsertNewNodeToHead function allocates a memory for record the driver allocate
+  memory region and insert the node to the head link list.
+
+  @param[in]  This              A pointer to the EFI_USBFN_IO_PROTOCOL instance.
+  @param[out] USB_MEM_NODE      return the new node address.
+
+  @retval EFI_SUCCESS           The operation completed successfully.
+  @retval EFI_INVALID_PARAMETER A parameter is invalid.
+  @retval EFI_OUT_OF_RESOURCES  The requested transfer Buffer could not be allocated.
+
+**/
+EFI_STATUS
+InsertNewNodeToHead (
+  IN  EFI_USBFN_IO_PROTOCOL    *This,
+  OUT USB_MEM_NODE             **Node
+  )
+{
+  USB_MEM_NODE         *NewNodePtr;
+  USB_MEM_NODE         *CurrentNodePtr;
+  USB_XDCI_DEV_CONTEXT *UsbFuncIoDevPtr;
+  EFI_STATUS           Status;
+
+  DEBUG ((USB_DEBUG_MEM_NODE_INFO, "CreateNewNode - Entry\n"));
+
+  if (This == NULL) {
+    Status = EFI_INVALID_PARAMETER;
+    goto ErrorExit;
+  }
+
+  UsbFuncIoDevPtr = USBFUIO_CONTEXT_FROM_PROTOCOL(This);
+
+  //
+  // Create the new node
+  //
+  NewNodePtr = AllocateZeroPool (sizeof(USB_MEM_NODE));
+  DEBUG ((USB_DEBUG_MEM_NODE_INFO, "NewNodePtr - Addr = 0x%08x\n",(UINTN)NewNodePtr));
+
+  if (NewNodePtr == NULL) {
+    Status = EFI_OUT_OF_RESOURCES;
+    goto ErrorExit;
+  }
+
+  //
+  // insert the new node
+  //
+  CurrentNodePtr = UsbFuncIoDevPtr->FirstNodePtr;
+  UsbFuncIoDevPtr->FirstNodePtr = NewNodePtr;
+
+  if (CurrentNodePtr != NULL) {
+    NewNodePtr->NextPtr = CurrentNodePtr;
+  }
+
+  *Node = NewNodePtr;
+
+  DEBUG ((USB_DEBUG_MEM_NODE_INFO, "CreateNewNode - Exit\n"));
+  return EFI_SUCCESS;
+
+ErrorExit:
+
+  DEBUG ((USB_DEBUG_MEM_NODE_ERROR, "CreateNewNode - error %r\n",Status));
+  return Status;
+}
+
diff --git a/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbIoNode.h b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbIoNode.h
new file mode 100644
index 0000000000..ecedb2748b
--- /dev/null
+++ b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbIoNode.h
@@ -0,0 +1,90 @@
+/** @file
+  Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR>
+
+  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.
+
+**/
+
+#ifndef __EFI_USB_FUIO_MEM_NODE__
+#define __EFI_USB_FUIO_MEM_NODE__
+
+#include <Uefi.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/DriverLib.h>
+
+#define  USB_DEBUG_MEM_NODE_INFO  EFI_D_INIT
+#define  USB_DEBUG_MEM_NODE_ERROR EFI_D_ERROR
+
+
+typedef struct {
+  UINTN                         Size;
+  VOID                          *AllocatePtr;
+  VOID                          *NextPtr;
+} USB_MEM_NODE;
+
+/**
+  The SearchNode function search a memory address for record the driver allocate
+  memory region and the node to the head link list.
+
+  @param[in]  This              A pointer to the EFI_USBFN_IO_PROTOCOL instance.
+  @param[in]  Buffer            The driver alocate memory address.
+  @param[out] Node              The match node record of the driver aloocate
+                                memory region.
+  @param[out] PNode             The pervious match node record of the driver
+                                aloocate memory region.
+
+  @retval EFI_SUCCESS           The operation completed successfully.
+  @retval EFI_NOT_FOUND         The memory Buffer didn't find.
+**/
+EFI_STATUS
+SearchNode (
+  IN  EFI_USBFN_IO_PROTOCOL    *This,
+  IN  VOID                     *Buffer,
+  OUT USB_MEM_NODE             **Node,
+  OUT USB_MEM_NODE             **PNode
+  );
+
+/**
+  The InsertNewNodeToHead function remove a memory for record the driver allocate
+  memory region and the node to the head link list.
+
+  @param[in]  This              A pointer to the EFI_USBFN_IO_PROTOCOL instance.
+  @param[in]  Buffer            The driver alocate memory address.
+
+  @retval EFI_SUCCESS           The operation completed successfully.
+  @retval EFI_NOT_FOUND         The memory Buffer didn't find.
+**/
+EFI_STATUS
+RemoveNode (
+  IN  EFI_USBFN_IO_PROTOCOL    *This,
+  IN  VOID                     *Buffer
+  );
+
+/**
+  The InsertNewNodeToHead function allocates a memory for record the driver allocate
+  memory region and insert the node to the head link list.
+
+  @param[in]  This              A pointer to the EFI_USBFN_IO_PROTOCOL instance.
+  @param[out] USB_MEM_NODE      return the new node address.
+
+  @retval EFI_SUCCESS           The operation completed successfully.
+  @retval EFI_INVALID_PARAMETER A parameter is invalid.
+  @retval EFI_OUT_OF_RESOURCES  The requested transfer Buffer could not be allocated.
+
+**/
+EFI_STATUS
+InsertNewNodeToHead (
+  IN  EFI_USBFN_IO_PROTOCOL    *This,
+  OUT USB_MEM_NODE             **Node
+  );
+
+  #endif
+
+
diff --git a/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciCommon.h b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciCommon.h
new file mode 100644
index 0000000000..6a53068681
--- /dev/null
+++ b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciCommon.h
@@ -0,0 +1,156 @@
+/** @file
+  Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR>
+
+  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.
+
+**/
+
+#ifndef _XDCI_COMMON_H_
+#define _XDCI_COMMON_H_
+
+#define USB_SETUP_DATA_PHASE_DIRECTION_MASK  (0x80)
+
+//
+// EP direction
+//
+typedef enum {
+  UsbEpDirOut = 0,
+  UsbEpDirIn  = 1
+} USB_EP_DIR;
+
+//
+// USB Speeds
+//
+typedef enum {
+  USB_SPEED_HIGH  = 0,
+  USB_SPEED_FULL,
+  USB_SPEED_LOW,
+  USB_SPEED_SUPER = 4
+} USB_SPEED;
+
+typedef enum {
+  USB_ID_DWC_XDCI = 0,
+  USB_CORE_ID_MAX
+} USB_CONTROLLER_ID;
+
+typedef enum {
+  USB_ROLE_HOST = 1,
+  USB_ROLE_DEVICE,
+  USB_ROLE_OTG
+} USB_ROLE;
+
+typedef enum {
+  USB_XFER_QUEUED    = 0,
+  USB_XFER_SUCCESSFUL,
+  USB_XFER_STALL
+} USB_XFER_STATUS;
+
+typedef enum {
+  USB_DEVICE_DISCONNECT_EVENT       = 0,
+  USB_DEVICE_RESET_EVENT,
+  USB_DEVICE_CONNECTION_DONE,
+  USB_DEVICE_STATE_CHANGE_EVENT,
+  USB_DEVICE_WAKEUP_EVENT,
+  USB_DEVICE_HIBERNATION_REQ_EVENT,
+  USB_DEVICE_SOF_EVENT              = 7,
+  USB_DEVICE_ERRATIC_ERR_EVENT      = 9,
+  USB_DEVICE_CMD_CMPLT_EVENT,
+  USB_DEVICE_BUFF_OVERFLOW_EVENT,
+  USB_DEVICE_TEST_LMP_RX_EVENT,
+  USB_DEVICE_SETUP_PKT_RECEIVED,
+  USB_DEVICE_XFER_NRDY,
+  USB_DEVICE_XFER_DONE
+} USB_DEVICE_EVENT_ID;
+
+typedef enum {
+  U0 = 0,
+  U1,
+  U2,
+  U3,
+  SS_DIS,
+  RX_DET,
+  SS_INACT,
+  POLL,
+  RECOV,
+  HRESET,
+  CMPLY,
+  LPBK,
+  RESUME_RESET = 15
+} USB_DEVICE_SS_LINK_STATE;
+
+typedef enum {
+  CTRL_SETUP_PHASE,
+  CTRL_DATA_PHASE,
+  CTRL_STATUS_PHASE
+} USB_CONTROL_XFER_PHASE;
+
+typedef enum  {
+  USB_EP_STATE_DISABLED = 0,
+  USB_EP_STATE_ENABLED,
+  USB_EP_STATE_STALLED,
+  USB_EP_STATE_SETUP,
+  USB_EP_STATE_IN_DATA,
+  USB_EP_STATE_OUT_DATA,
+  USB_EP_STATE_DATA,
+  USB_EP_STATE_STATUS
+} USB_EP_STATE;
+
+typedef struct  {
+  VOID                      *ParentHandle;
+  UINT32                    Hird;
+  UINT32                    EpNum;
+  USB_SPEED                 Speed;
+  USB_EP_STATE              EpState;
+  USB_EP_DIR                EpDir;
+  UINT8                     EpType;
+  USB_DEVICE_SS_LINK_STATE  LinkState;
+  UINT8                     *Buffer;
+  BOOLEAN                   SsEvent;
+} USB_DEVICE_CALLBACK_PARAM;
+
+//
+// USB endpoint
+//
+typedef struct {
+  UINT32       EpNum;
+  USB_EP_DIR   EpDir;
+  UINT8        EpType;
+  UINT32       MaxPktSize;
+  UINT32       MaxStreams;
+  UINT32       BurstSize;
+  UINT32       Interval;
+  UINT32       Mult;
+} USB_EP_INFO;
+
+//
+// USB transfer request
+//
+typedef struct _USB_XFER_REQUEST USB_XFER_REQUEST;
+
+typedef
+VOID
+(EFIAPI *USB_XFER_DONE_CALLBACK) (
+  IN VOID                    *XdciHndl,
+  IN USB_XFER_REQUEST        *XferReq
+  );
+
+struct _USB_XFER_REQUEST {
+  VOID                      *XferBuffer;     // Buffer address. bus-width aligned
+  UINT32                    XferLen;         // Requested transfer length
+  UINT32                    ActualXferLen;  // Actual transfer length at completion callback stage
+  UINT32                    StreamId;        // Stream ID. Only relevant for bulk streaming
+  UINT32                    FrameNum;        // Only relevant for periodic transfer
+  USB_XFER_STATUS           XferStatus;      // Transfer status
+  USB_EP_INFO               EpInfo;          // EP info
+  USB_XFER_DONE_CALLBACK    XferDone;        // Transfer completion callback
+  BOOLEAN                   Zlp;              // Do zero-length transfer
+};
+
+#endif
+
diff --git a/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciDWC.c b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciDWC.c
new file mode 100644
index 0000000000..3569ba6975
--- /dev/null
+++ b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciDWC.c
@@ -0,0 +1,4030 @@
+/** @file
+  Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR>
+
+  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.
+
+**/
+
+#include "UsbDeviceMode.h"
+#include "XdciInterface.h"
+#include "XdciDWC.h"
+
+
+UINT32
+UsbRegRead (
+  IN UINT32    Base,
+  IN UINT32    Offset
+  )
+{
+  volatile UINT32 *addr = (volatile UINT32 *)((UINTN)(Base) + (UINTN)(Offset));
+  return *addr;
+}
+
+VOID
+UsbRegWrite (
+  IN UINT32    Base,
+  IN UINT32    Offset,
+  IN UINT32    val
+  )
+{
+  volatile UINT32 *addr = (volatile UINT32 *)((UINTN)(Base) + (UINTN)(Offset));
+  *addr = val;
+}
+
+
+/**
+  Internal utility function:
+  This function is used to obtain physical endpoint number
+  xDCI needs physical endpoint number for EP registers
+  We also use it to index into our EP array
+  Note: Certain data structures/commands use logical EP numbers
+  as opposed to physical endpoint numbers so one should be
+  careful when interpreting EP numbers
+  @EpNum: Logical endpoint number
+  @epDir: Direction for the endpoint
+
+**/
+STATIC
+UINT32
+DwcXdciGetPhysicalEpNum (
+  IN UINT32        EndpointNum,
+  IN USB_EP_DIR    EndpointDir
+  )
+{
+  return EndpointDir? ((EndpointNum << 1) | EndpointDir) : (EndpointNum << 1);
+}
+
+
+/**
+  Internal utility function:
+  This function is used to obtain the MPS for control transfers
+  Based on the Speed. If this is called before bus reset completes
+  then it returns MPS Based on desired Speed. If it is after bus
+  reset then MPS returned is Based on actual negotiated Speed
+  @CoreHandle: xDCI controller handle address
+  @mps: address of 32-bit variable to return the MPS
+
+**/
+STATIC
+EFI_STATUS
+DwcXdciCoreGetCtrlMps (
+  IN XDCI_CORE_HANDLE    *CoreHandle,
+  IN UINT32              *mps
+  )
+{
+  if (CoreHandle == NULL) {
+      DEBUG ((DEBUG_INFO, "ERROR: DwcXdciCoreGetCtrlMps: INVALID handle\n"));
+      return EFI_DEVICE_ERROR;
+  }
+
+  if (mps == NULL) {
+    DEBUG ((DEBUG_INFO, "ERROR: DwcXdciCoreGetCtrlMps: INVALID parameter\n"));
+    return EFI_INVALID_PARAMETER;
+  }
+
+  switch (CoreHandle->ActualSpeed) {
+    case USB_SPEED_HIGH:
+      *mps = DWC_XDCI_HS_CTRL_EP_MPS;
+      break;
+    case USB_SPEED_FULL:
+      *mps = DWC_XDCI_FS_CTRL_EP_MPS;
+      break;
+    case USB_SPEED_LOW:
+      *mps = DWC_XDCI_LS_CTRL_EP_MPS;
+      break;
+    case USB_SPEED_SUPER:
+      *mps = DWC_XDCI_SS_CTRL_EP_MPS;
+      break;
+    default:
+      *mps = 0;
+      DEBUG ((DEBUG_INFO, "ERROR: DwcXdciCoreGetCtrlMps: UNKNOWN Speed\n"));
+      break;
+  }
+
+  return EFI_SUCCESS;
+}
+
+
+/**
+  Internal utility function:
+  This function is used to initialize the parameters required
+  for executing endpoint command
+  @CoreHandle: xDCI controller handle address
+  @EpInfo: EP info address
+  @ConfigAction: Configuration action specific to EP command
+  @EpCmd: xDCI EP command for which parameters are initialized
+  @EpCmdParams: address of struct to return EP params
+
+**/
+STATIC
+EFI_STATUS
+DwcXdciCoreInitEpCmdParams (
+  IN XDCI_CORE_HANDLE                *CoreHandle,
+  IN USB_EP_INFO                     *EpInfo,
+  IN UINT32                          ConfigAction,
+  IN DWC_XDCI_ENDPOINT_CMD           EpCmd,
+  IN DWC_XDCI_ENDPOINT_CMD_PARAMS    *EpCmdParams
+  )
+{
+  EFI_STATUS  status = EFI_SUCCESS;
+
+  if (CoreHandle == NULL) {
+    DEBUG ((DEBUG_INFO, "ERROR: DwcXdciCoreInitEpCmdParams: INVALID handle\n"));
+    return EFI_DEVICE_ERROR;
+  }
+
+  //
+  // Reset params
+  //
+  EpCmdParams->Param0 = EpCmdParams->Param1 = EpCmdParams->Param2 = 0;
+
+  switch (EpCmd) {
+    case EPCMD_SET_EP_CONFIG:
+      //
+      // Issue DEPCFG command for EP
+      // Issue a DEPCFG (Command 1) command for endpoint
+      //
+      if (EpInfo->MaxStreams) {
+        EpCmdParams->Param1 = DWC_XDCI_PARAM1_SET_EP_CFG_STRM_CAP_MASK;
+      }
+
+      if (EpInfo->Interval) {
+        EpCmdParams->Param1 |= ((EpInfo->Interval-1) << DWC_XDCI_PARAM1_SET_EP_CFG_BINTM1_BIT_POS);
+      }
+
+      //
+      // Set EP num
+      //
+      EpCmdParams->Param1 |= (EpInfo->EpNum << DWC_XDCI_PARAM1_SET_EP_CFG_EP_NUM_BIT_POS);
+      //
+      // Set EP direction
+      //
+      EpCmdParams->Param1 |= (EpInfo->EpDir << DWC_XDCI_PARAM1_SET_EP_CFG_EP_DIR_BIT_POS);
+      //
+      // Set EP-specific Event enable for not ready and
+      // complete events
+      //
+      EpCmdParams->Param1 &= ~DWC_XDCI_PARAM1_SET_EP_CFG_EVT_EN_MASK;
+      //
+      // Setup the events we want enabled for this EP
+      //
+      EpCmdParams->Param1 |= (DWC_XDCI_PARAM1_SET_EP_CFG_EVT_XFER_NRDY_MASK |
+                                DWC_XDCI_PARAM1_SET_EP_CFG_EVT_XFER_IN_PRG_MASK |
+                                DWC_XDCI_PARAM1_SET_EP_CFG_EVT_XFER_CMPLT_MASK);
+
+      //
+      // We only have one interrupt line for this core.
+      // Set interrupt number to 0
+      //
+      EpCmdParams->Param1 &= ~DWC_XDCI_PARAM1_SET_EP_CFG_INTR_NUM_MASK;
+
+      //
+      // Set FIFOnum = 0 for control EP0
+      //
+      EpCmdParams->Param0 &= ~DWC_XDCI_PARAM0_SET_EP_CFG_FIFO_NUM_MASK;
+
+      //
+      // Program FIFOnum for non-EP0 EPs
+      //
+      if (EpInfo->EpNum && EpInfo->EpDir) {
+        EpCmdParams->Param0 |= (EpInfo->EpNum << DWC_XDCI_PARAM0_SET_EP_CFG_FIFO_NUM_BIT_POS);
+      }
+
+      //
+      // Program max packet size
+      //
+      EpCmdParams->Param0 &= ~DWC_XDCI_PARAM0_SET_EP_CFG_MPS_MASK;
+      EpCmdParams->Param0 |= (EpInfo->MaxPktSize << DWC_XDCI_PARAM0_SET_EP_CFG_MPS_BIT_POS);
+
+      //
+      // Set Burst size. 0 means burst size of 1
+      //
+      EpCmdParams->Param0 &= ~DWC_XDCI_PARAM0_SET_EP_CFG_BRST_SIZE_MASK;
+      EpCmdParams->Param0 |= (EpInfo->BurstSize << DWC_XDCI_PARAM0_SET_EP_CFG_BRST_SIZE_BIT_POS);
+
+      //
+      // Set EP type
+      //
+      EpCmdParams->Param0 &= ~DWC_XDCI_PARAM0_SET_EP_CFG_EP_TYPE_MASK;
+      EpCmdParams->Param0 |= (EpInfo->EpType << DWC_XDCI_PARAM0_SET_EP_CFG_EP_TYPE_BIT_POS);
+
+      //
+      // Set config action
+      //
+      EpCmdParams->Param0 &= ~DWC_XDCI_PARAM0_SET_EP_CFG_ACTN_MASK;
+      EpCmdParams->Param0 |= (ConfigAction << DWC_XDCI_PARAM0_SET_EP_CFG_ACTN_BIT_POS);
+      break;
+
+    case EPCMD_SET_EP_XFER_RES_CONFIG:
+      // Set Param0 to 1. Same for all EPs when resource
+      // configuration is done
+      //
+      EpCmdParams->Param0 = 1;
+      break;
+
+    case EPCMD_END_XFER:
+      //
+      // Nothing to set. Already reset params for all cmds
+      //
+      break;
+
+    case EPCMD_START_NEW_CONFIG:
+      //
+      // Nothing to set. Already reset params for all cmds
+      //
+      break;
+
+    default:
+      status = EFI_INVALID_PARAMETER;
+      DEBUG ((DEBUG_INFO, "\nDwcXdciCoreInitEpCmdParams: INVALID Parameter"));
+      break;
+  }
+
+  return status;
+}
+
+
+/**
+  Internal utility function:
+  This function is used to issue the xDCI endpoint command
+  @CoreHandle: xDCI controller handle address
+  @EpNum: Physical EP num
+  @EpCmd: xDCI EP command
+  @EpCmdParams: EP command parameters address
+
+**/
+STATIC
+EFI_STATUS
+DwcXdciCoreIssueEpCmd (
+  IN XDCI_CORE_HANDLE                *CoreHandle,
+  IN UINT32                          EpNum,
+  IN UINT32                          EpCmd,
+  IN DWC_XDCI_ENDPOINT_CMD_PARAMS    *EpCmdParams
+  )
+{
+  UINT32 BaseAddr;
+  UINT32 MaxDelayIter = 5000;//DWC_XDCI_MAX_DELAY_ITERATIONS;
+
+  if (CoreHandle == NULL) {
+    DEBUG ((DEBUG_INFO, "ERROR: DwcXdciCoreIssueEpCmd: INVALID handle\n"));
+    return EFI_DEVICE_ERROR;
+  }
+
+  BaseAddr = CoreHandle->BaseAddress;
+
+  //
+  // Set EP command parameter values
+  //
+  UsbRegWrite (
+    BaseAddr,
+    DWC_XDCI_EPCMD_PARAM2_REG(EpNum),
+    EpCmdParams->Param2
+    );
+
+  UsbRegWrite (
+    BaseAddr,
+    DWC_XDCI_EPCMD_PARAM1_REG(EpNum),
+    EpCmdParams->Param1
+    );
+
+  UsbRegWrite (
+    BaseAddr,
+    DWC_XDCI_EPCMD_PARAM0_REG(EpNum),
+    EpCmdParams->Param0
+    );
+
+  //
+  // Set the command code and activate it
+  //
+  UsbRegWrite (
+    BaseAddr,
+    DWC_XDCI_EPCMD_REG(EpNum),
+    EpCmd | DWC_XDCI_EPCMD_CMD_ACTIVE_MASK
+    );
+
+  //
+  // Wait until command completes
+  //
+  do {
+    if (!(UsbRegRead (BaseAddr, DWC_XDCI_EPCMD_REG(EpNum)) & DWC_XDCI_EPCMD_CMD_ACTIVE_MASK))
+      break;
+    else
+      gBS->Stall (DWC_XDCI_MAX_DELAY_ITERATIONS);
+  } while (--MaxDelayIter);
+
+  if (!MaxDelayIter) {
+    DEBUG ((DEBUG_INFO, "DwcXdciCoreIssueEpCmd. ERROR: Failed to issue Command\n"));
+    return EFI_DEVICE_ERROR;
+  }
+
+  return EFI_SUCCESS;
+}
+
+
+/**
+  Internal utility function:
+  This function is used to flush all FIFOs
+  @CoreHandle: xDCI controller handle address
+
+**/
+STATIC
+EFI_STATUS
+DwcXdciCoreFlushAllFifos (
+  IN XDCI_CORE_HANDLE    *CoreHandle
+  )
+{
+  UINT32 BaseAddr;
+  UINT32 MaxDelayIter = DWC_XDCI_MAX_DELAY_ITERATIONS;
+
+  if (CoreHandle == NULL) {
+    DEBUG ((DEBUG_INFO, "ERROR: DwcXdciCoreFlushAllFifos: INVALID handle\n"));
+    return EFI_DEVICE_ERROR;
+  }
+
+  BaseAddr = CoreHandle->BaseAddress;
+
+  //
+  // Write the command to flush all FIFOs
+  //
+  UsbRegWrite(
+    BaseAddr,
+    DWC_XDCI_DGCMD_REG,
+    (UsbRegRead (BaseAddr, DWC_XDCI_DGCMD_REG) | DWC_XDCI_DGCMD_CMD_ALL_FIFO_FLUSH | DWC_XDCI_DGCMD_CMD_ACTIVE_MASK)
+    );
+
+  //
+  // Wait until command completes
+  //
+  do {
+    if (!(UsbRegRead (BaseAddr, DWC_XDCI_DGCMD_REG) & DWC_XDCI_DGCMD_CMD_ACTIVE_MASK))
+      break;
+    else
+      gBS->Stall (DWC_XDCI_MAX_DELAY_ITERATIONS);
+  } while (--MaxDelayIter);
+
+  if (!MaxDelayIter) {
+    DEBUG ((DEBUG_INFO, "Failed to issue Command\n"));
+    return EFI_DEVICE_ERROR;
+  }
+
+  return EFI_SUCCESS;
+}
+
+
+/**
+  Internal utility function:
+  This function is used to flush Tx FIFO specific to an endpoint
+  @CoreHandle: xDCI controller handle address
+  @EpNum: Physical EP num
+
+**/
+STATIC
+EFI_STATUS
+DwcXdciCoreFlushEpTxFifo (
+  IN XDCI_CORE_HANDLE    *CoreHandle,
+  IN UINT32              EpNum
+  )
+{
+  UINT32 BaseAddr;
+  UINT32 MaxDelayIter = DWC_XDCI_MAX_DELAY_ITERATIONS;
+  UINT32 fifoNum;
+
+  if (CoreHandle == NULL) {
+    DEBUG ((DEBUG_INFO, "ERROR: DwcXdciCoreFlushEpTxFifo: INVALID handle\n"));
+    return EFI_DEVICE_ERROR;
+  }
+
+  BaseAddr = CoreHandle->BaseAddress;
+
+  //
+  // Translate to FIFOnum
+  // NOTE: Assuming this is a Tx EP
+  //
+  fifoNum = (EpNum >> 1);
+
+  //
+  // TODO: Currently we are only using TxFIFO 0. Later map these
+  // Write the FIFO num/dir param for the generic command.
+  //
+  UsbRegWrite (
+    BaseAddr,
+    DWC_XDCI_DGCMD_PARAM_REG,
+    ((UsbRegRead (BaseAddr, DWC_XDCI_DGCMD_PARAM_REG) & ~DWC_XDCI_DGCMD_PARAM_TX_FIFO_NUM_MASK) | DWC_XDCI_DGCMD_PARAM_TX_FIFO_DIR_MASK)
+    );
+
+  //
+  // Write the command to flush all FIFOs
+  //
+  UsbRegWrite (
+    BaseAddr,
+    DWC_XDCI_DGCMD_REG,
+    (UsbRegRead(BaseAddr, DWC_XDCI_DGCMD_REG) | DWC_XDCI_DGCMD_CMD_SEL_FIFO_FLUSH | DWC_XDCI_DGCMD_CMD_ACTIVE_MASK)
+    );
+
+
+  //
+  // Wait until command completes
+  //
+  do {
+    if (!(UsbRegRead(BaseAddr, DWC_XDCI_DGCMD_REG) & DWC_XDCI_DGCMD_CMD_ACTIVE_MASK))
+      break;
+    else
+      gBS->Stall (DWC_XDCI_MAX_DELAY_ITERATIONS);
+  } while (--MaxDelayIter);
+
+  if (!MaxDelayIter) {
+    DEBUG ((DEBUG_INFO, "Failed to issue Command\n"));
+    return EFI_DEVICE_ERROR;
+  }
+
+  return EFI_SUCCESS;
+}
+
+
+
+STATIC
+EFI_STATUS
+DwcXdciCorePrepareOneTrb (
+  IN DWC_XDCI_TRB            *Trb,
+  IN DWC_XDCI_TRB_CONTROL    TrbCtrl,
+  IN UINT32                  LastBit,
+  IN UINT32                  ChainBit,
+  IN UINT8                   *BufferPtr,
+  IN UINT32                  size
+  )
+{
+  DEBUG ((DEBUG_INFO, "Trb is 0x%x, BufferPtr is 0x%x, size is 0x%x\n", Trb, BufferPtr, size));
+
+  Trb->BuffPtrLow = (UINT32)(UINTN)BufferPtr;
+  Trb->BuffPtrHigh = 0;
+  Trb->LenXferParams = size;
+  Trb->TrbCtrl = TrbCtrl << DWC_XDCI_TRB_CTRL_TYPE_BIT_POS;
+
+  if (ChainBit)
+    Trb->TrbCtrl |= ChainBit << DWC_XDCI_TRB_CTRL_CHAIN_BUFF_BIT_POS;
+
+  if (LastBit)
+    Trb->TrbCtrl |= LastBit << DWC_XDCI_TRB_CTRL_LST_TRB_BIT_POS;
+
+  Trb->TrbCtrl |= DWC_XDCI_TRB_CTRL_IOSP_MISOCH_MASK| DWC_XDCI_TRB_CTRL_HWO_MASK;
+
+  DEBUG ((DEBUG_INFO, "(DwcXdciCorePrepareOneTrb) Trb->BuffPtrLow = 0x%x, Trb->LenXferParams is 0x%x, Trb->TrbCtrl is 0x%x\n",
+                                                       Trb->BuffPtrLow, Trb->LenXferParams, Trb->TrbCtrl));
+  return EFI_SUCCESS;
+}
+
+
+/**
+  Internal utility function:
+  This function is used to initialize transfer request block
+  @CoreHandle: xDCI controller handle address
+  @Trb: Address of TRB to initialize
+  @TrbCtrl: TRB control value
+  @buffPtr: Transfer Buffer address
+  @size: Size of the transfer
+
+**/
+STATIC
+EFI_STATUS
+DwcXdciCoreInitTrb (
+  IN XDCI_CORE_HANDLE        *CoreHandle,
+  IN DWC_XDCI_TRB            *Trb,
+  IN DWC_XDCI_TRB_CONTROL    TrbCtrl,
+  IN UINT8                   *BufferPtr,
+  IN UINT32                  size
+  )
+{
+#define ONE_TRB_SIZE      (DWC_XDCI_TRB_BUFF_SIZE_MASK & 0x00F00000)
+  UINT8                   *TrbBuffer;
+  UINT32                  TrbCtrlLast;
+  UINT32                  TrbCtrlChain;
+  UINT32                  TrbIndex;
+
+  if (CoreHandle == NULL) {
+    DEBUG ((DEBUG_INFO, "ERROR: DwcXdciCoreInitTrb: INVALID handle\n"));
+    return EFI_DEVICE_ERROR;
+  }
+
+  if (Trb == NULL) {
+    DEBUG ((DEBUG_INFO, "ERROR: DwcXdciCoreInitTrb: INVALID handle\n"));
+    return EFI_INVALID_PARAMETER;
+  }
+  
+   //
+   // Init TRB fields
+   // NOTE: Assuming we are only using 32-bit addresses
+   // TODO: update for 64-bit addresses
+   //
+  if (size <= DWC_XDCI_TRB_BUFF_SIZE_MASK) {
+    //
+    // Can transfer in one TRB
+    //
+    TrbCtrlChain = 0;
+    TrbCtrlLast = 1;
+    DwcXdciCorePrepareOneTrb (Trb, TrbCtrl, TrbCtrlLast, TrbCtrlChain, BufferPtr, size);
+    return EFI_SUCCESS;
+  }
+
+  //
+  // Can't transfer in one TRB.
+  // Seperate it in every ONE_TRB_SIZE of TRB
+  //
+  TrbBuffer = BufferPtr;
+  TrbIndex = 0;
+  while (size > ONE_TRB_SIZE) {
+    TrbCtrlChain = 1;
+    TrbCtrlLast = 0;
+    DwcXdciCorePrepareOneTrb (Trb, TrbCtrl, TrbCtrlLast, TrbCtrlChain, TrbBuffer, ONE_TRB_SIZE);
+    TrbBuffer += ONE_TRB_SIZE;
+    size -= ONE_TRB_SIZE;
+    Trb++;
+    TrbIndex++;
+    if (TrbIndex >= DWC_XDCI_TRB_NUM)
+      return EFI_OUT_OF_RESOURCES;
+  }
+  TrbCtrlChain = 0;
+  TrbCtrlLast = 1;
+  DwcXdciCorePrepareOneTrb (Trb, TrbCtrl, TrbCtrlLast, TrbCtrlChain, TrbBuffer, size);
+
+  return EFI_SUCCESS;
+}
+
+
+/**
+  Internal function:
+  This function is used to start a SETUP phase on control endpoint
+  @CoreHandle: xDCI controller handle address
+
+**/
+STATIC
+EFI_STATUS
+DwcXdciCoreStartEp0SetupXfer (
+  IN XDCI_CORE_HANDLE    *CoreHandle
+  )
+{
+  DWC_XDCI_ENDPOINT_CMD_PARAMS    EpCmdParams;
+  EFI_STATUS                      status = EFI_DEVICE_ERROR;
+  DWC_XDCI_TRB                    *Trb;
+
+  if (CoreHandle == NULL) {
+    DEBUG ((DEBUG_INFO, "ERROR: DwcXdciCoreStartEp0SetupXfer: INVALID handle\n"));
+    return EFI_DEVICE_ERROR;
+  }
+
+  if (CoreHandle->EpHandles[0].State == USB_EP_STATE_SETUP) {
+    DEBUG ((DEBUG_INFO, "EP0 was already in SETUP phase\n"));
+    return EFI_SUCCESS;
+  }
+
+  CoreHandle->EpHandles[0].State = USB_EP_STATE_SETUP;
+  Trb = CoreHandle->Trbs;
+  DEBUG ((DEBUG_INFO, "(DwcXdciCoreStartEp0SetupXfer)\n"));
+
+  status = DwcXdciCoreInitTrb (
+             CoreHandle,
+             Trb,
+             TRBCTL_SETUP,
+             CoreHandle->AlignedSetupBuffer,
+             8
+             );
+
+  if (status)
+    return status;
+
+  //
+  // Issue a DEPSTRTXFER for EP0
+  // Reset params
+  //
+  EpCmdParams.Param0 = EpCmdParams.Param1 = EpCmdParams.Param2 = 0;
+
+  //
+  // Init the lower re-bits for TRB address
+  //
+  EpCmdParams.Param1 = (UINT32)(UINTN)Trb;
+
+  //
+  // Issue the command to start transfer on physical
+  // endpoint 0
+  //
+  status = DwcXdciCoreIssueEpCmd (
+             CoreHandle,
+             0,
+             EPCMD_START_XFER,
+             &EpCmdParams
+             );
+
+  //
+  // Save new resource index for this transfer
+  //
+  CoreHandle->EpHandles[0].CurrentXferRscIdx = ((UsbRegRead (
+                                                     CoreHandle->BaseAddress,
+                                                     DWC_XDCI_EPCMD_REG(0)) & DWC_XDCI_EPCMD_RES_IDX_MASK) >> DWC_XDCI_EPCMD_RES_IDX_BIT_POS
+                                                     );
+
+  return status;
+}
+
+
+/**
+  Internal function:
+  This function is used to process the state change event
+  @CoreHandle: xDCI controller handle address
+  @event: device event dword
+
+**/
+STATIC
+EFI_STATUS
+DwcXdciProcessDeviceStateChangeEvent (
+  IN XDCI_CORE_HANDLE    *CoreHandle,
+  IN UINT32              Event
+  )
+{
+  if (CoreHandle == NULL) {
+    DEBUG ((DEBUG_INFO, "ERROR: DwcXdciProcessDeviceStateChangeEvent: INVALID handle\n"));
+    return EFI_DEVICE_ERROR;
+  }
+
+  CoreHandle->HirdVal = (Event & DWC_XDCI_EVENT_BUFF_DEV_HIRD_MASK) >> DWC_XDCI_EVENT_BUFF_DEV_HIRD_BIT_POS;
+
+  CoreHandle->LinkState = ((Event & DWC_XDCI_EVENT_BUFF_DEV_LINK_STATE_MASK) >> DWC_XDCI_EVENT_BUFF_DEV_LINK_STATE_BIT_POS);
+
+  if (CoreHandle->EventCallbacks.DevLinkStateCallback) {
+    CoreHandle->EventCallbacks.CbEventParams.ParentHandle = CoreHandle->ParentHandle;
+    CoreHandle->EventCallbacks.CbEventParams.LinkState = CoreHandle->LinkState;
+    CoreHandle->EventCallbacks.CbEventParams.Hird = CoreHandle->HirdVal;
+    CoreHandle->EventCallbacks.CbEventParams.SsEvent = (Event & DWC_XDCI_EVENT_BUFF_DEV_SS_EVENT_MASK) ? 1 : 0;
+    CoreHandle->EventCallbacks.DevLinkStateCallback (&CoreHandle->EventCallbacks.CbEventParams);
+  }
+
+  return EFI_SUCCESS;
+}
+
+
+/**
+  Internal function:
+  This function is used to issue a command to end transfer
+  @CoreHandle: xDCI controller handle address
+  @EpNum: Physical EP num for which transfer is to be ended
+
+**/
+STATIC
+EFI_STATUS
+DwcXdciEndXfer (
+  IN XDCI_CORE_HANDLE    *CoreHandle,
+  IN UINT32              EpNum
+  )
+{
+  EFI_STATUS                      status;
+  DWC_XDCI_ENDPOINT_CMD_PARAMS    EpCmdParams;
+  UINT32                          cmdParams;
+  DWC_XDCI_TRB                    *TrbPtr;
+
+  if (CoreHandle == NULL) {
+    DEBUG ((DEBUG_INFO, "ERROR: DwcXdciEndXfer: INVALID handle\n"));
+    return EFI_DEVICE_ERROR;
+  }
+
+  CoreHandle->EpHandles[EpNum].CheckFlag = FALSE;
+
+  //
+  // Issue a DEPENDXFER for EP
+  // Reset params
+  //
+  EpCmdParams.Param0 = EpCmdParams.Param1 = EpCmdParams.Param2 = 0;
+
+  cmdParams = ((CoreHandle->EpHandles[EpNum].CurrentXferRscIdx << DWC_XDCI_EPCMD_RES_IDX_BIT_POS) | DWC_XDCI_EPCMD_FORCE_RM_MASK);
+
+  if (CoreHandle->EpHandles[EpNum].CurrentXferRscIdx == 0) {
+    return EFI_SUCCESS;
+  }
+  //
+  // Issue the command
+  //
+  status = DwcXdciCoreIssueEpCmd(
+             CoreHandle,
+             EpNum,
+             cmdParams | DWC_XDCI_EPCMD_END_XFER,
+             &EpCmdParams
+             );
+
+  if (!status) {
+    CoreHandle->EpHandles[EpNum].CurrentXferRscIdx = 0;
+    TrbPtr = CoreHandle->Trbs + (EpNum * DWC_XDCI_TRB_NUM);
+    ZeroMem (TrbPtr, DWC_XDCI_TRB_NUM * sizeof (DWC_XDCI_TRB));
+  }
+
+  return status;
+}
+
+
+/**
+  Internal function:
+  This function is used to process bus reset detection event
+  @CoreHandle: xDCI controller handle address
+
+**/
+STATIC
+EFI_STATUS
+DwcXdciProcessDeviceResetDet (
+  IN XDCI_CORE_HANDLE    *CoreHandle
+  )
+{
+  EFI_STATUS  status = EFI_SUCCESS;
+
+  if (CoreHandle == NULL) {
+    return EFI_DEVICE_ERROR;
+  }
+
+  //
+  // Flush all FIFOs
+  //
+  status = DwcXdciCoreFlushAllFifos(CoreHandle);
+  if (status) {
+    DEBUG ((DEBUG_INFO, "DwcXdciProcessDeviceResetDet: Failed to flush FIFOs\n"));
+  }
+
+  //
+  // Start SETUP phase on EP0
+  //
+  status = DwcXdciCoreStartEp0SetupXfer(CoreHandle);
+
+  if (status) {
+    DEBUG ((DEBUG_INFO, "DwcXdciProcessDeviceResetDet: Failed to start SETUP phase for EP0\n"));
+    return status;
+  }
+
+  //
+  // Notify upper layer if a callback is registerd for
+  //  this event
+  //
+  if (CoreHandle->EventCallbacks.DevBusResetCallback) {
+    CoreHandle->EventCallbacks.CbEventParams.ParentHandle = CoreHandle->ParentHandle;
+    status = CoreHandle->EventCallbacks.DevBusResetCallback (&CoreHandle->EventCallbacks.CbEventParams);
+  }
+
+  return status;
+}
+
+
+/**
+  Internal function:
+  This function is used to process connection done (means reset
+  complete) event
+  @CoreHandle: xDCI controller handle address
+
+**/
+STATIC
+EFI_STATUS
+DwcXdciProcessDeviceResetDone (
+  IN XDCI_CORE_HANDLE    *CoreHandle
+  )
+{
+  DWC_XDCI_ENDPOINT_CMD_PARAMS    EpCmdParams;
+  UINT32                          BaseAddr;
+  EFI_STATUS                      status = EFI_SUCCESS;
+
+  if (CoreHandle == NULL) {
+    DEBUG ((DEBUG_INFO, "ERROR: DwcXdciProcessDeviceResetDone: INVALID handle\n"));
+    return EFI_DEVICE_ERROR;
+  }
+
+  BaseAddr = CoreHandle->BaseAddress;
+  CoreHandle->ActualSpeed = (UsbRegRead (BaseAddr, DWC_XDCI_DSTS_REG) & DWC_XDCI_DSTS_CONN_SPEED_MASK);
+  DEBUG ((DEBUG_INFO, "DwcXdciProcessDeviceResetDone CoreHandle->ActualSpeed is %x\n", CoreHandle->ActualSpeed));
+
+  //
+  // Program MPS Based on the negotiated Speed
+  //
+  DwcXdciCoreGetCtrlMps (CoreHandle, &CoreHandle->EpHandles[0].EpInfo.MaxPktSize);
+  DwcXdciCoreGetCtrlMps (CoreHandle, &CoreHandle->EpHandles[1].EpInfo.MaxPktSize);
+
+  //
+  // Init DEPCFG cmd params for EP0
+  //
+  status = DwcXdciCoreInitEpCmdParams (
+             CoreHandle,
+             &CoreHandle->EpHandles[0].EpInfo,
+             DWC_XDCI_PARAM0_SET_EP_CFG_ACTN_MDFY_STATE,
+             EPCMD_SET_EP_CONFIG,
+             &EpCmdParams
+             );
+
+  if (status) {
+    return status;
+  }
+
+  //
+  // Issue the command
+  //
+  status = DwcXdciCoreIssueEpCmd (
+             CoreHandle,
+             0,
+             EPCMD_SET_EP_CONFIG,
+             &EpCmdParams
+             );
+
+  if (status) {
+    return status;
+  }
+
+  //
+  // Init DEPCFG cmd params for EP1
+  //
+  status = DwcXdciCoreInitEpCmdParams (
+             CoreHandle,
+             &CoreHandle->EpHandles[1].EpInfo,
+             DWC_XDCI_PARAM0_SET_EP_CFG_ACTN_MDFY_STATE,
+             EPCMD_SET_EP_CONFIG,
+             &EpCmdParams
+             );
+
+  //
+  // Issue the command
+  //
+  status = DwcXdciCoreIssueEpCmd (
+             CoreHandle,
+             1,
+             EPCMD_SET_EP_CONFIG,
+             &EpCmdParams
+             );
+
+  //
+  // Put the other PHY into suspend
+  //
+  if (CoreHandle->ActualSpeed == USB_SPEED_SUPER) {
+    //
+    // Put HS PHY to suspend
+    //
+    UsbRegWrite (
+      BaseAddr,
+      DWC_XDCI_GUSB2PHYCFG_REG (0),
+      (UsbRegRead (BaseAddr, DWC_XDCI_GUSB2PHYCFG_REG(0)) | DWC_XDCI_GUSB2PHYCFG_SUSPEND_PHY_MASK)
+      );
+
+    //
+    // Clear SS PHY's suspend mask
+    //
+    UsbRegWrite (
+      BaseAddr,
+      DWC_XDCI_GUSB3PIPECTL_REG (0),
+      (UsbRegRead (BaseAddr, DWC_XDCI_GUSB3PIPECTL_REG(0)) & ~DWC_XDCI_GUSB3PIPECTL_SUSPEND_PHY_MASK)
+      );
+
+  } else {
+    //
+    // Put SS PHY to suspend
+    //
+    UsbRegWrite (
+      BaseAddr,
+      DWC_XDCI_GUSB3PIPECTL_REG(0),
+      (UsbRegRead(BaseAddr, DWC_XDCI_GUSB3PIPECTL_REG(0)) | DWC_XDCI_GUSB3PIPECTL_SUSPEND_PHY_MASK)
+      );
+
+    //
+    // Clear HS PHY's suspend mask
+    //
+    UsbRegWrite (
+      BaseAddr,
+      DWC_XDCI_GUSB2PHYCFG_REG(0),
+      (UsbRegRead(BaseAddr, DWC_XDCI_GUSB2PHYCFG_REG(0)) & ~DWC_XDCI_GUSB2PHYCFG_SUSPEND_PHY_MASK)
+      );
+  }
+
+  //
+  // Notify upper layer if callback is registered
+  //
+  if (CoreHandle->EventCallbacks.DevResetDoneCallback) {
+    CoreHandle->EventCallbacks.CbEventParams.ParentHandle = CoreHandle->ParentHandle;
+    CoreHandle->EventCallbacks.CbEventParams.Speed = CoreHandle->ActualSpeed;
+    CoreHandle->EventCallbacks.DevResetDoneCallback (&CoreHandle->EventCallbacks.CbEventParams);
+  }
+
+  return status;
+}
+
+
+/**
+  Internal function:
+  This function is used to process device event
+  @CoreHandle: xDCI controller handle address
+  @IntLineEventBuffer: event Buffer pointing to device event
+  @ProcessedEventSize: address of variable to save the size of
+  the event that was Processed
+
+**/
+STATIC
+EFI_STATUS
+DwcXdciProcessDeviceEvent (
+  IN XDCI_CORE_HANDLE         *CoreHandle,
+  IN DWC_XDCI_EVENT_BUFFER    *IntLineEventBuffer,
+  IN UINT32                   *ProcessedEventSize
+  )
+{
+  UINT32 event;
+
+  if (CoreHandle == NULL) {
+    DEBUG ((DEBUG_INFO, "ERROR: DwcXdciProcessDeviceEvent: INVALID handle\n"));
+    return EFI_DEVICE_ERROR;
+  }
+
+  //
+  // Extract device event
+  //
+  event = (IntLineEventBuffer->Event & DWC_XDCI_EVENT_BUFF_DEV_EVT_MASK);
+  event >>= DWC_XDCI_EVENT_BUFF_DEV_EVT_BIT_POS;
+
+  //
+  // Assume default event size. Change it in switch case if
+  //  different
+  //
+  *ProcessedEventSize = DWC_XDCI_DEV_EVENT_DEFAULT_SIZE_IN_BYTES;
+
+  switch (event) {
+    case DWC_XDCI_EVENT_BUFF_DEV_DISCONN_EVENT:
+      DEBUG ((DEBUG_INFO, "Device DWC_XDCI_EVENT_BUFF_DEV_DISCONN_EVENT\n"));
+      break;
+
+    case DWC_XDCI_EVENT_BUFF_DEV_USB_RESET_EVENT:
+      DEBUG ((DEBUG_INFO, "Device DWC_XDCI_EVENT_BUFF_DEV_USB_RESET_EVENT\n"));
+      DwcXdciProcessDeviceResetDet (CoreHandle);
+      break;
+
+    case DWC_XDCI_EVENT_BUFF_DEV_CONN_DONE_EVENT:
+      DEBUG ((DEBUG_INFO, "Device DWC_XDCI_EVENT_BUFF_DEV_CONN_DONE_EVENT\n"));
+      DwcXdciProcessDeviceResetDone (CoreHandle);
+      break;
+
+    case DWC_XDCI_EVENT_BUFF_DEV_STATE_CHANGE_EVENT:
+      DEBUG ((DEBUG_INFO, "Device DWC_XDCI_EVENT_BUFF_DEV_STATE_CHANGE_EVENT\n"));
+      DwcXdciProcessDeviceStateChangeEvent (CoreHandle, IntLineEventBuffer->Event);
+      break;
+
+    case DWC_XDCI_EVENT_BUFF_DEV_WKUP_EVENT:
+      DEBUG ((DEBUG_INFO, "Device DWC_XDCI_EVENT_BUFF_DEV_WKUP_EVENT\n"));
+      break;
+
+    case DWC_XDCI_EVENT_BUFF_DEV_HBRNTN_REQ_EVENT:
+      DEBUG ((DEBUG_INFO, "Device DWC_XDCI_EVENT_BUFF_DEV_HBRNTN_REQ_EVENT\n"));
+      break;
+
+    case DWC_XDCI_EVENT_BUFF_DEV_SOF_EVENT:
+      DEBUG ((DEBUG_INFO, "Device DWC_XDCI_EVENT_BUFF_DEV_SOF_EVENT\n"));
+      break;
+
+    case DWC_XDCI_EVENT_BUFF_DEV_ERRATIC_ERR_EVENT:
+      DEBUG ((DEBUG_INFO, "Device DWC_XDCI_EVENT_BUFF_DEV_ERRATIC_ERR_EVENT\n"));
+      break;
+
+    case DWC_XDCI_EVENT_BUFF_DEV_CMD_CMPLT_EVENT:
+      DEBUG ((DEBUG_INFO, "Device DWC_XDCI_EVENT_BUFF_DEV_CMD_CMPLT_EVENT\n"));
+      break;
+
+    case DWC_XDCI_EVENT_BUFF_DEV_BUFF_OVFL_EVENT:
+      DEBUG ((DEBUG_INFO, "Device DWC_XDCI_EVENT_BUFF_DEV_BUFF_OVFL_EVENT\n"));
+      break;
+
+    case DWC_XDCI_EVENT_BUFF_DEV_TST_LMP_RX_EVENT:
+      DEBUG ((DEBUG_INFO, "Device DWC_XDCI_EVENT_BUFF_DEV_TST_LMP_RX_EVENT\n"));
+      *ProcessedEventSize = DWC_XDCI_DEV_EVENT_TST_LMP_SIZE_IN_BYTES;
+      break;
+
+    default:
+      DEBUG ((DEBUG_INFO, "DwcXdciProcessDeviceEvent: UNHANDLED device event: %x\n", event));
+      break;
+  }
+
+  return EFI_SUCCESS;
+}
+
+
+/**
+  Internal function:
+  This function is used to process EP not ready for
+  non-control endpoints
+  @CoreHandle: xDCI controller handle address
+  @EpNum: Physical endpoint number
+
+**/
+STATIC
+EFI_STATUS
+DwcXdciProcessEpXferNotReady (
+  IN XDCI_CORE_HANDLE    *CoreHandle,
+  IN UINT32              EpNum
+  )
+{
+  //
+  // TODO: Not doing on-demand transfers
+  // Revisit if required for later use
+  //
+  return EFI_SUCCESS;
+}
+
+
+/**
+  Internal function:
+  This function is used to process EP not ready for
+  control endpoints
+  @CoreHandle: xDCI controller handle address
+  @EpNum: Physical endpoint number
+  @dataStage: EP not ready when data stage token was received
+  @statusStage: EP not ready when status stage token was received
+
+**/
+STATIC
+EFI_STATUS
+DwcXdciProcessEp0XferNotReady (
+  IN XDCI_CORE_HANDLE    *CoreHandle,
+  IN UINT32              EpNum,
+  IN UINT32              epEventStatus
+  )
+{
+  USB_EP_STATE        epState = USB_EP_STATE_SETUP;
+
+  if (CoreHandle == NULL) {
+    DEBUG ((DEBUG_INFO, "ERROR: DwcXdciProcessEp0XferNotReady: INVALID handle\n"));
+    return EFI_DEVICE_ERROR;
+  }
+  //
+  // Is it data stage or status stage
+  //
+  if (epEventStatus & DWC_XDCI_EVENT_BUFF_EP_CTRL_DATA_REQ_MASK) {
+    epState = USB_EP_STATE_DATA;
+  } else if (epEventStatus & DWC_XDCI_EVENT_BUFF_EP_CTRL_STATUS_REQ_MASK) {
+    epState = USB_EP_STATE_STATUS;
+  }
+
+  if ((EpNum == 0) && (epState == USB_EP_STATE_STATUS)) {
+    if (epEventStatus & DWC_XDCI_EVENT_BUFF_EP_XFER_ACTIVE_MASK) {
+      DEBUG ((DEBUG_INFO, "XFER_ACTIVE\n"));
+    } else {
+      DEBUG ((DEBUG_INFO, "XFER_NOT_ACTIVE\n"));
+    }
+    DwcXdciEp0ReceiveStatusPkt (CoreHandle);
+  }
+
+  //
+  // Notify upper layer if a callback is registered for
+  // this event
+  //
+  if (CoreHandle->EventCallbacks.DevXferNrdyCallback) {
+    CoreHandle->EventCallbacks.CbEventParams.ParentHandle = CoreHandle->ParentHandle;
+    CoreHandle->EventCallbacks.CbEventParams.EpState = epState;
+    CoreHandle->EventCallbacks.DevXferNrdyCallback (&CoreHandle->EventCallbacks.CbEventParams);
+  }
+
+  return EFI_SUCCESS;
+}
+
+
+/**
+  Internal function:
+  This function is used to process transfer phone done for EP0
+  @CoreHandle: xDCI controller handle address
+  @EpNum: Physical endpoint number (0 for OUT and 1 for IN)
+
+**/
+STATIC
+EFI_STATUS
+DwcXdciProcessEp0XferPhaseDone (
+  IN XDCI_CORE_HANDLE    *CoreHandle,
+  IN UINT32              EpNum
+  )
+{
+  DWC_XDCI_ENDPOINT    *epHandle;
+  DWC_XDCI_TRB         *Trb;
+  EFI_STATUS           status = EFI_SUCCESS;
+  UINT32               TrbSts;
+  UINT32               TrbCtrl;
+  UINT32               TrbBufsize;
+
+  if (CoreHandle == NULL) {
+    DEBUG ((DEBUG_INFO, "ERROR: DwcXdciProcessEp0XferPhaseDone: INVALID handle\n"));
+    return EFI_DEVICE_ERROR;
+  }
+
+  epHandle = &CoreHandle->EpHandles[EpNum];
+  Trb = CoreHandle->Trbs + (EpNum * DWC_XDCI_TRB_NUM);
+  DEBUG ((DEBUG_INFO, "(DwcXdciProcessEp0XferPhaseDone)EpNum is %d\n", EpNum));
+
+  if (Trb->TrbCtrl & DWC_XDCI_TRB_CTRL_HWO_MASK) {
+    DEBUG ((DEBUG_INFO, "DwcXdciProcessEp0XferPhaseDone. HW owns TRB: %x!!!\n", (UINT32)(UINTN)Trb));
+  }
+
+  epHandle->CurrentXferRscIdx = 0;
+  epHandle->State = USB_EP_STATE_ENABLED;
+  TrbCtrl = (Trb->TrbCtrl & DWC_XDCI_TRB_CTRL_TYPE_MASK) >> DWC_XDCI_TRB_CTRL_TYPE_BIT_POS;
+  TrbSts = (Trb->LenXferParams & DWC_XDCI_TRB_STATUS_MASK) >> DWC_XDCI_TRB_STATUS_BIT_POS;
+  TrbBufsize = Trb->LenXferParams & DWC_XDCI_TRB_BUFF_SIZE_MASK;
+
+  switch (TrbCtrl) {
+    case DWC_XDCI_TRB_CTRL_TYPE_SETUP:
+      DEBUG ((DEBUG_INFO, "SETUP\n"));
+      if (CoreHandle->EventCallbacks.DevSetupPktReceivedCallback) {
+        CoreHandle->EventCallbacks.CbEventParams.ParentHandle = CoreHandle->ParentHandle;
+        CoreHandle->EventCallbacks.CbEventParams.Buffer = CoreHandle->AlignedSetupBuffer;
+        status = CoreHandle->EventCallbacks.DevSetupPktReceivedCallback (&CoreHandle->EventCallbacks.CbEventParams);
+      }
+
+      if (!(CoreHandle->AlignedSetupBuffer[0] & USB_SETUP_DATA_PHASE_DIRECTION_MASK)) {
+        //
+        // Keep a Buffer ready for setup phase
+        //
+        DwcXdciCoreStartEp0SetupXfer (CoreHandle);
+      }
+
+      break;
+
+    case DWC_XDCI_TRB_CTRL_TYPE_STATUS2:
+      DEBUG ((DEBUG_INFO, "STATUS2\n"));
+      break;
+
+    case DWC_XDCI_TRB_CTRL_TYPE_STATUS3:
+      DEBUG ((DEBUG_INFO, "STATUS3\n"));
+      //
+      // Notify upper layer of control transfer completion
+      // if a callback function was registerd
+      //
+      if (CoreHandle->EventCallbacks.DevXferDoneCallback) {
+        CoreHandle->EventCallbacks.CbEventParams.ParentHandle = CoreHandle->ParentHandle;
+        CoreHandle->EventCallbacks.CbEventParams.EpNum = (EpNum >> 1);
+        CoreHandle->EventCallbacks.CbEventParams.EpDir = (EpNum & 1);
+        CoreHandle->EventCallbacks.CbEventParams.Buffer = (UINT8 *)(UINTN)(Trb->BuffPtrLow);
+        CoreHandle->EventCallbacks.DevXferDoneCallback (&CoreHandle->EventCallbacks.CbEventParams);
+      }
+
+      //
+      // Status phase done. Queue next SETUP packet
+      //
+      status = DwcXdciCoreStartEp0SetupXfer(CoreHandle);
+
+      if (status) {
+        DEBUG ((DEBUG_INFO, "DwcXdciProcessEp0XferPhaseDone: FAILED to queue SETUP\n"));
+      }
+      break;
+
+    case DWC_XDCI_TRB_CTRL_TYPE_DATA:
+      DEBUG ((DEBUG_INFO, "DATA\n"));
+      if (TrbSts == DWC_XDCI_TRB_STATUS_SETUP_PENDING || TrbBufsize != 0) {
+        DEBUG ((DEBUG_INFO, "ERROR: Control transfert aborted by host: Setup pending\n"));
+        DwcXdciCoreStartEp0SetupXfer (CoreHandle);
+      }
+
+      if (CoreHandle->EventCallbacks.DevXferDoneCallback) {
+        CoreHandle->EventCallbacks.CbEventParams.ParentHandle = CoreHandle->ParentHandle;
+        CoreHandle->EventCallbacks.CbEventParams.EpNum = (EpNum >> 1);
+        CoreHandle->EventCallbacks.CbEventParams.EpDir = (EpNum & 1);
+        CoreHandle->EventCallbacks.CbEventParams.Buffer = (UINT8 *)(UINTN)(Trb->BuffPtrLow);
+        CoreHandle->EventCallbacks.DevXferDoneCallback (&CoreHandle->EventCallbacks.CbEventParams);
+      }
+      break;
+
+    default:
+      DEBUG ((DEBUG_INFO, "DwcXdciProcessEp0XferPhaseDone: UNHANDLED STATE in TRB\n"));
+      break;
+  }
+
+  return status;
+}
+
+
+/**
+  Internal function:
+  This function is used to process transfer done for
+  non-control endpoints
+  @CoreHandle: xDCI controller handle address
+  @EpNum: Physical endpoint number
+
+**/
+STATIC
+EFI_STATUS
+DwcXdciProcessEpXferDone (
+  IN XDCI_CORE_HANDLE    *CoreHandle,
+  IN UINT32              EpNum
+  )
+{
+  DWC_XDCI_ENDPOINT    *epHandle;
+  DWC_XDCI_TRB         *Trb;
+  USB_XFER_REQUEST     *XferReq;
+  UINT32               remainingLen;
+
+  if (CoreHandle == NULL) {
+    DEBUG ((DEBUG_INFO, "ERROR: DwcXdciProcessEpXferDone: INVALID handle\n"));
+    return EFI_DEVICE_ERROR;
+  }
+
+  epHandle = &CoreHandle->EpHandles[EpNum];
+  epHandle->CurrentXferRscIdx = 0;
+  Trb = epHandle->Trb;
+  XferReq = &epHandle->XferHandle;
+
+  //
+  // if transfer done, set CheckFlag to FALSE for allow next transfer request.
+  //
+  epHandle->CheckFlag = FALSE;
+
+  if ((Trb == NULL) || (XferReq == NULL)) {
+    DEBUG ((DEBUG_INFO, "ERROR: DwcXdciProcessEpXferDone: INVALID parameter\n"));
+    return EFI_INVALID_PARAMETER;
+  }
+
+  //
+  // Compute the actual transfer length
+  //
+  XferReq->ActualXferLen = XferReq->XferLen;
+  remainingLen = (Trb->LenXferParams & DWC_XDCI_TRB_BUFF_SIZE_MASK);
+
+  if (remainingLen > XferReq->XferLen) {
+    //
+    // Buffer overrun? This should never happen
+    //
+    DEBUG ((DEBUG_INFO, "ERROR: DwcXdciProcessEpXferDone: Possible Buffer overrun\n"));
+  } else {
+    XferReq->ActualXferLen -= remainingLen;
+  }
+
+  //
+  // Notify upper layer of request-specific transfer completion
+  // if there is a callback specifically for this request
+  //
+  if (XferReq->XferDone) {
+    XferReq->XferDone(CoreHandle->ParentHandle, XferReq);
+  }
+
+  //
+  // Notify upper layer if a callback was registered
+  //
+  if (CoreHandle->EventCallbacks.DevXferDoneCallback) {
+    CoreHandle->EventCallbacks.CbEventParams.ParentHandle = CoreHandle->ParentHandle;
+    CoreHandle->EventCallbacks.CbEventParams.EpNum = (EpNum >> 1);
+    CoreHandle->EventCallbacks.CbEventParams.EpDir = (EpNum & 1);
+    CoreHandle->EventCallbacks.CbEventParams.EpType = epHandle->EpInfo.EpType;
+    CoreHandle->EventCallbacks.CbEventParams.Buffer = (UINT8 *)(UINTN)(epHandle->Trb->BuffPtrLow);
+    CoreHandle->EventCallbacks.DevXferDoneCallback (&CoreHandle->EventCallbacks.CbEventParams);
+  }
+
+  return EFI_SUCCESS;
+}
+
+
+/**
+  Internal function:
+  This function is used to process endpoint events
+  @CoreHandle: xDCI controller handle address
+  @IntLineEventBuffer:  address of Buffer containing event
+  to process
+  @ProcessedEventSize: address to save the size of event
+  Processed
+
+**/
+STATIC
+EFI_STATUS
+DwcXdciProcessEpEvent (
+  IN XDCI_CORE_HANDLE         *CoreHandle,
+  IN DWC_XDCI_EVENT_BUFFER    *IntLineEventBuffer,
+  IN UINT32                   *ProcessedEventSize
+  )
+{
+  UINT32          EpNum;
+  UINT32          epEvent;
+  UINT32          epEventStatus;
+
+  if (CoreHandle == NULL) {
+    DEBUG ((DEBUG_INFO, "ERROR: DwcXdciProcessEpEvent: INVALID handle\n"));
+    return EFI_DEVICE_ERROR;
+  }
+
+  epEvent = IntLineEventBuffer->Event;
+
+  *ProcessedEventSize = DWC_XDCI_DEV_EVENT_DEFAULT_SIZE_IN_BYTES;
+
+  //
+  // Get EP num
+  //
+  EpNum = ((epEvent & DWC_XDCI_EVENT_BUFF_EP_NUM_MASK) >> DWC_XDCI_EVENT_BUFF_EP_NUM_BIT_POS);
+  epEventStatus = (epEvent & DWC_XDCI_EVENT_BUFF_EP_EVENT_STATUS_MASK);
+
+  //
+  // Interpret event and handle transfer completion here
+  //
+  epEvent = ((epEvent & DWC_XDCI_EVENT_BUFF_EP_EVENT_MASK) >> DWC_XDCI_EVENT_BUFF_EP_EVENT_BIT_POS);
+
+  switch (epEvent) {
+    case DWC_XDCI_EVENT_BUFF_EP_XFER_CMPLT:
+      DEBUG ((DEBUG_INFO, "XFER_CMPLT ep %d\n", EpNum));
+      if (EpNum > 1) {
+        DwcXdciProcessEpXferDone (CoreHandle, EpNum);
+      } else {
+        DwcXdciProcessEp0XferPhaseDone (CoreHandle, EpNum);
+      }
+      break;
+
+    case DWC_XDCI_EVENT_BUFF_EP_XFER_IN_PROGRESS:
+      DEBUG ((DEBUG_INFO, "IN_PROGRESS\n"));
+      break;
+
+    case DWC_XDCI_EVENT_BUFF_EP_XFER_NOT_READY:
+      DEBUG ((DEBUG_INFO, "NOT_READY ep %d\n", EpNum));
+      if (EpNum > 1) {
+        //
+        // Endpoint transfer is not ready
+        //
+        DwcXdciProcessEpXferNotReady (CoreHandle, EpNum);
+      } else {
+        DwcXdciProcessEp0XferNotReady (CoreHandle, EpNum, epEventStatus);
+      }
+      break;
+
+    default:
+      DEBUG ((DEBUG_INFO, "DwcXdciProcessEpEvent: UNKNOWN EP event\n"));
+      break;
+  }
+
+  return EFI_SUCCESS;
+}
+
+
+/**
+  Internal function:
+  This function is used to process events on single interrupt line
+  @CoreHandle: xDCI controller handle address
+  @eventCount:  event bytes to process
+  @ProcessedEventCount: address to save the size
+  (in bytes) of event Processed
+  Processed
+
+**/
+STATIC
+EFI_STATUS
+DwcXdciProcessInterruptLineEvents (
+  IN XDCI_CORE_HANDLE    *CoreHandle,
+  IN UINT32              eventCount,
+  IN UINT32              *ProcessedEventCount
+  )
+{
+  UINT32    ProcessedEventSize = 0;
+  UINT32    currentEventAddr;
+
+  if (CoreHandle == NULL) {
+    DEBUG ((DEBUG_INFO, "ERROR: DwcXdciProcessInterruptLineEvents: INVALID handle\n"));
+    return EFI_DEVICE_ERROR;
+  }
+
+  if (CoreHandle->CurrentEventBuffer == NULL) {
+    DEBUG ((DEBUG_INFO, "ERROR: DwcXdciProcessInterruptLineEvents: INVALID event Buffer\n"));
+    return EFI_INVALID_PARAMETER;
+  }
+
+  currentEventAddr = (UINT32)(UINTN)(CoreHandle->CurrentEventBuffer);
+
+  //
+  // Process eventCount/eventSize number of events
+  // in this run
+  //
+  while (eventCount) {
+    if (CoreHandle->CurrentEventBuffer->Event & DWC_XDCI_EVENT_DEV_MASK) {
+      DwcXdciProcessDeviceEvent (
+        CoreHandle,
+        CoreHandle->CurrentEventBuffer,
+        &ProcessedEventSize
+        );
+    } else {
+      DwcXdciProcessEpEvent (
+        CoreHandle,
+        CoreHandle->CurrentEventBuffer,
+        &ProcessedEventSize);
+    }
+
+    eventCount -= ProcessedEventSize;
+    *ProcessedEventCount += ProcessedEventSize;
+    if ((currentEventAddr + ProcessedEventSize) >=
+        ((UINT32)(UINTN)(CoreHandle->AlignedEventBuffers) + (sizeof(DWC_XDCI_EVENT_BUFFER) * DWC_XDCI_MAX_EVENTS_PER_BUFFER))
+       ) {
+      currentEventAddr = (UINT32)(UINTN)(CoreHandle->AlignedEventBuffers);
+      DEBUG ((DEBUG_INFO, "DwcXdciProcessInterruptLineEvents: Event Buffer bound reached\n"));
+    } else {
+      currentEventAddr += ProcessedEventSize;
+    }
+
+    CoreHandle->CurrentEventBuffer = (DWC_XDCI_EVENT_BUFFER *)(UINTN)currentEventAddr;
+  }
+
+  return EFI_SUCCESS;
+}
+
+//
+// DWC XDCI APIs
+//
+
+/**
+  Interface:
+
+  This function is used to initialize the xDCI core
+  @configParams: Parameters from app to configure the core
+  @deviceCorePtr:  HW-independent APIs handle for device core
+  @CoreHandle: xDCI controller handle retured
+
+**/
+EFI_STATUS
+EFIAPI
+DwcXdciCoreInit (
+  IN USB_DEV_CONFIG_PARAMS    *ConfigParams,
+  IN VOID                     *deviceCorePtr,
+  IN VOID                     **CoreHandle
+  )
+{
+  EFI_STATUS                      status = EFI_DEVICE_ERROR;
+  UINT32                          BaseAddr;
+  XDCI_CORE_HANDLE                *LocalCoreHandle;
+  DWC_XDCI_ENDPOINT_CMD_PARAMS    EpCmdParams;
+  UINT32                          MaxDelayIter = DWC_XDCI_MAX_DELAY_ITERATIONS;
+  UINT8                           i;
+
+  LocalCoreHandle = (XDCI_CORE_HANDLE *)AllocateZeroPool (sizeof(XDCI_CORE_HANDLE));
+
+  if (CoreHandle == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (LocalCoreHandle == NULL) {
+    DEBUG ((DEBUG_INFO, "DwcXdciCoreInit: Failed to allocate handle for xDCI\n"));
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  ZeroMem (LocalCoreHandle, sizeof(XDCI_CORE_HANDLE));
+
+  LocalCoreHandle->ParentHandle = deviceCorePtr;
+
+  *CoreHandle = (VOID *)LocalCoreHandle;
+
+  LocalCoreHandle->Id = ConfigParams->ControllerId;
+  LocalCoreHandle->BaseAddress = BaseAddr = ConfigParams->BaseAddress;
+  LocalCoreHandle->Flags = ConfigParams->Flags;
+  LocalCoreHandle->DesiredSpeed = LocalCoreHandle->ActualSpeed = ConfigParams->Speed;
+  LocalCoreHandle->Role = ConfigParams->Role;
+
+  DEBUG ((DEBUG_INFO, "Resetting the USB core\n"));
+  UsbRegWrite (
+    BaseAddr,
+    DWC_XDCI_DCTL_REG,
+    UsbRegRead (BaseAddr, DWC_XDCI_DCTL_REG) | DWC_XDCI_DCTL_CSFTRST_MASK
+    );
+  //
+  // Wait until core soft reset completes
+  //
+  do {
+    if (!(UsbRegRead (BaseAddr, DWC_XDCI_DCTL_REG) & DWC_XDCI_DCTL_CSFTRST_MASK)) {
+      break;
+    } else {
+      gBS->Stall (DWC_XDCI_MAX_DELAY_ITERATIONS);
+    }
+  } while (--MaxDelayIter);
+
+  if (!MaxDelayIter) {
+    DEBUG ((DEBUG_INFO, "Failed to reset device controller\n"));
+    return EFI_DEVICE_ERROR;
+  }
+
+  DEBUG ((DEBUG_INFO, "USB core has been reset\n"));
+
+  //
+  // All FIFOs are flushed at this point
+  //
+  //
+  // Ensure we have EP0 Rx/Tx handles initialized
+  //
+  LocalCoreHandle->EpHandles[0].EpInfo.EpNum = 0;
+  LocalCoreHandle->EpHandles[0].EpInfo.EpDir = UsbEpDirOut;
+  LocalCoreHandle->EpHandles[0].EpInfo.EpType = USB_ENDPOINT_CONTROL;
+  LocalCoreHandle->EpHandles[0].EpInfo.MaxPktSize = DWC_XDCI_SS_CTRL_EP_MPS;
+  //
+  // 0 means burst size of 1
+  //
+  LocalCoreHandle->EpHandles[0].EpInfo.BurstSize = 0;
+
+  LocalCoreHandle->EpHandles[1].EpInfo.EpNum = 0;
+  LocalCoreHandle->EpHandles[1].EpInfo.EpDir = UsbEpDirIn;
+  LocalCoreHandle->EpHandles[1].EpInfo.EpType = USB_ENDPOINT_CONTROL;
+  LocalCoreHandle->EpHandles[1].EpInfo.MaxPktSize = DWC_XDCI_SS_CTRL_EP_MPS;
+  //
+  // 0 means burst size of 1
+  //
+  LocalCoreHandle->EpHandles[1].EpInfo.BurstSize = 0;
+
+  LocalCoreHandle->DevState = UsbDevStateDefault;
+
+  //
+  // Clear KeepConnect bit so we can allow disconnect and
+  // re-connect. Stay in RX_DETECT state
+  //
+  UsbRegWrite (
+    BaseAddr,
+    DWC_XDCI_DCTL_REG,
+    UsbRegRead (BaseAddr, DWC_XDCI_DCTL_REG) &
+    (~DWC_XDCI_DCTL_KEEP_CONNECT_MASK) &
+    ((~DWC_XDCI_DCTL_STATE_CHANGE_REQ_MASK) | (DWC_XDCI_DCTL_STATE_CHANGE_REQ_RX_DETECT << DWC_XDCI_DCTL_STATE_CHANGE_REQ_BIT_POS))
+    );
+
+  DEBUG ((DEBUG_INFO, "Device controller Synopsys ID: %x\n", UsbRegRead (BaseAddr, DWC_XDCI_GSNPSID_REG)));
+  DEBUG ((DEBUG_INFO, "Default value of xDCI GSBUSCFG0 and GSBUSCFG1: %x, %x\n",
+          UsbRegRead (BaseAddr, DWC_XDCI_GSBUSCFG0_REG),
+          UsbRegRead (BaseAddr, DWC_XDCI_GSBUSCFG1_REG)));
+
+  DEBUG ((DEBUG_INFO, "Default value of xDCI GTXTHRCFG and GRXTHRCFG: %x, %x\n",
+          UsbRegRead (BaseAddr, DWC_XDCI_GTXTHRCFG_REG),
+          UsbRegRead (BaseAddr, DWC_XDCI_GRXTHRCFG_REG)));
+
+  //
+  // Clear ULPI auto-resume bit
+  //
+  UsbRegWrite (
+    BaseAddr,
+    DWC_XDCI_GUSB2PHYCFG_REG (0),
+    (UsbRegRead (BaseAddr, DWC_XDCI_GUSB2PHYCFG_REG (0)) & ~DWC_XDCI_GUSB2PHYCFG_ULPI_AUTO_RESUME_MASK)
+    );
+
+  DEBUG ((DEBUG_INFO, "Default value of xDCI GUSB2PHYCFG and GUSB3PIPECTL: %x, %x\n",
+          UsbRegRead (BaseAddr, DWC_XDCI_GUSB2PHYCFG_REG (0)),
+          UsbRegRead (BaseAddr, DWC_XDCI_GUSB3PIPECTL_REG (0))));
+  //
+  // Only one RxFIFO
+  //
+  DEBUG ((DEBUG_INFO, "Default value of DWC_XDCI_GRXFIFOSIZ: %x\n",
+          UsbRegRead (BaseAddr, DWC_XDCI_GRXFIFOSIZ_REG (0))));
+
+  for (i = 0; i < DWC_XDCI_MAX_ENDPOINTS; i++) {
+    DEBUG ((DEBUG_INFO, "Default value of xDCI DWC_XDCI_GTXFIFOSIZ %d: %x\n",
+            i, UsbRegRead (BaseAddr, DWC_XDCI_GTXFIFOSIZ_REG (i))));
+  }
+
+  //
+  // TODO: Need to check if TxFIFO should start where RxFIFO ends
+  // or default is correct i.e. TxFIFO starts at 0 just like RxFIFO
+  //
+
+  //
+  // Allocate and Initialize Event Buffers
+  //
+  LocalCoreHandle->MaxDevIntLines = ((UsbRegRead (BaseAddr, DWC_XDCI_GHWPARAMS1_REG) &
+                                           DWC_XDCI_GHWPARAMS1_NUM_INT_MASK) >>
+                                           DWC_XDCI_GHWPARAMS1_NUM_INT_BIT_POS);
+
+  DEBUG ((DEBUG_INFO, "Max dev int lines: %d\n", LocalCoreHandle->MaxDevIntLines));
+  //
+  // One event Buffer per interrupt line.
+  //  Need to align it to size of event Buffer
+  //  Buffer needs to be big enough. Otherwise the core
+  //  won't operate
+  //
+  LocalCoreHandle->AlignedEventBuffers = (DWC_XDCI_EVENT_BUFFER *)
+                                             ((UINT32)(UINTN)(LocalCoreHandle->EventBuffers) +
+                                             ((sizeof (DWC_XDCI_EVENT_BUFFER) * DWC_XDCI_MAX_EVENTS_PER_BUFFER) -
+                                             (((UINT32)(UINTN)(LocalCoreHandle->EventBuffers)) %
+                                             (sizeof (DWC_XDCI_EVENT_BUFFER) * DWC_XDCI_MAX_EVENTS_PER_BUFFER))));
+
+  for (i = 0; i < LocalCoreHandle->MaxDevIntLines; i++) {
+    UsbRegWrite (
+      BaseAddr,
+      DWC_XDCI_GEVNTADR_REG (i),
+      (UINT32)(UINTN)(LocalCoreHandle->AlignedEventBuffers + i * sizeof(DWC_XDCI_EVENT_BUFFER) * DWC_XDCI_MAX_EVENTS_PER_BUFFER)
+      );
+
+    //
+    // Clear High 32bit address register, GEVNTADR register is 64-bit register
+    // default is 0xffffffffffffffff
+    //
+    UsbRegWrite (BaseAddr, DWC_XDCI_GEVNTADR_REG (i) + 4, 0x00000000);
+
+    LocalCoreHandle->CurrentEventBuffer = LocalCoreHandle->AlignedEventBuffers;
+    //
+    // Write size and clear the mask
+    //
+    UsbRegWrite (
+      BaseAddr,
+      DWC_XDCI_EVNTSIZ_REG (i),
+      sizeof (DWC_XDCI_EVENT_BUFFER) * DWC_XDCI_MAX_EVENTS_PER_BUFFER
+      );
+
+    //
+    // Write 0 to the event count register as the last step
+    //
+    //  for event configuration
+    //
+    UsbRegWrite (BaseAddr, DWC_XDCI_EVNTCOUNT_REG (i), 0);
+
+    DEBUG ((DEBUG_INFO, "Value of xDCI Event Buffer %d: %x, Size: %x, Count: %x\n",
+                        i,
+                        UsbRegRead (BaseAddr, DWC_XDCI_GEVNTADR_REG (i)),
+                        UsbRegRead (BaseAddr, DWC_XDCI_EVNTSIZ_REG (i)),
+                        UsbRegRead (BaseAddr, DWC_XDCI_EVNTCOUNT_REG (i))));
+  }
+
+    //
+    // Program Global Control Register to disable scaledown,
+    // disable clock gating
+    //
+    UsbRegWrite (
+      BaseAddr,
+      DWC_XDCI_GCTL_REG,
+      ((UsbRegRead(BaseAddr, DWC_XDCI_GCTL_REG) &
+                    ~(DWC_XDCI_GCTL_SCALE_DOWN_MODE_MASK + DWC_XDCI_GCTL_RAMCLKSEL_MASK + DWC_XDCI_GCTL_DISABLE_SCRAMB_MASK)) |
+                    DWC_XDCI_GCTL_DISABLE_CLK_GATING_MASK |
+                    (DWC_XDCI_GCTL_PRT_CAP_DEVICE << DWC_XDCI_GCTL_PRT_CAP_DIR_BIT_POS)));
+
+    DEBUG ((DEBUG_INFO, "Setup value of xDCI DWC_XDCI_GCTL_REG: 0x%x\n", UsbRegRead (BaseAddr, DWC_XDCI_GCTL_REG)));
+
+  //
+  // TODO: Program desired Speed and set LPM capable
+  // We will do this when SuperSpeed works. For now,
+  // force into High-Speed mode to aVOID anyone trying this
+  // on Super Speed port
+  //
+#ifdef SUPPORT_SUPER_SPEED
+  UsbRegWrite (
+    BaseAddr,
+    DWC_XDCI_DCFG_REG,
+    (UsbRegRead (BaseAddr, DWC_XDCI_DCFG_REG) & ~DWC_XDCI_DCFG_DESIRED_DEV_SPEED_MASK) | LocalCoreHandle->DesiredSpeed
+    );
+#else
+  UsbRegWrite (
+    BaseAddr,
+    DWC_XDCI_DCFG_REG,
+    (UsbRegRead (BaseAddr, DWC_XDCI_DCFG_REG) & ~DWC_XDCI_DCFG_DESIRED_DEV_SPEED_MASK) | DWC_XDCI_DCFG_DESIRED_HS_SPEED
+    );
+#endif
+
+  DEBUG ((DEBUG_INFO, "Setup value of xDCI DWC_XDCI_DCFG_REG: 0x%x\n", UsbRegRead (BaseAddr, DWC_XDCI_DCFG_REG)));
+  DEBUG ((DEBUG_INFO, "Setup value of xDCI DWC_XDCI_DSTS_REG: 0x%x\n", UsbRegRead (BaseAddr, DWC_XDCI_DSTS_REG)));
+
+  //
+  // Enable Device Interrupt Events
+  //
+  UsbRegWrite (
+    BaseAddr,
+    DWC_XDCI_DEVTEN_REG,
+    DWC_XDCI_DEVTEN_DEVICE_INTS
+    );
+  //
+  // Program the desired role
+  //
+  UsbRegWrite (
+    BaseAddr,
+    DWC_XDCI_GCTL_REG,
+    (UsbRegRead (BaseAddr, DWC_XDCI_GCTL_REG) & ~DWC_XDCI_GCTL_PRT_CAP_DIR_MASK) | (LocalCoreHandle->Role << DWC_XDCI_GCTL_PRT_CAP_DIR_BIT_POS)
+    );
+  //
+  // Clear USB2 suspend for start new config command
+  //
+  UsbRegWrite (
+    BaseAddr,
+    DWC_XDCI_GUSB2PHYCFG_REG (0),
+    (UsbRegRead (BaseAddr, DWC_XDCI_GUSB2PHYCFG_REG(0)) & ~DWC_XDCI_GUSB2PHYCFG_SUSPEND_PHY_MASK)
+    );
+
+  //
+  // Clear USB3 suspend for start new config command
+  //
+  UsbRegWrite (
+    BaseAddr,
+    DWC_XDCI_GUSB3PIPECTL_REG (0),
+    (UsbRegRead (BaseAddr, DWC_XDCI_GUSB3PIPECTL_REG(0)) & ~DWC_XDCI_GUSB3PIPECTL_SUSPEND_PHY_MASK)
+    );
+
+  //
+  // Issue DEPSTARTCFG command for EP0
+  //
+  status = DwcXdciCoreInitEpCmdParams (
+             LocalCoreHandle,
+             &LocalCoreHandle->EpHandles[0].EpInfo,
+             DWC_XDCI_PARAM0_SET_EP_CFG_ACTN_NONE,
+             EPCMD_START_NEW_CONFIG,
+             &EpCmdParams
+             );
+
+  if (status) {
+    DEBUG ((DEBUG_INFO, "DwcXdciCoreInit: Failed to init params for START_NEW_CONFIG EP command on xDCI\n"));
+    return status;
+  }
+
+  //
+  // Issue the command
+  //
+  status = DwcXdciCoreIssueEpCmd (
+             LocalCoreHandle,
+             0,
+             EPCMD_START_NEW_CONFIG,
+             &EpCmdParams
+             );
+
+  if (status) {
+    DEBUG ((DEBUG_INFO, "DwcXdciCoreInit: Failed to issue START_NEW_CONFIG EP command on xDCI\n"));
+    return status;
+  }
+
+  //
+  // Issue DEPCFG command for EP0
+  //
+  status = DwcXdciCoreInitEpCmdParams (
+             LocalCoreHandle,
+             &LocalCoreHandle->EpHandles[0].EpInfo,
+             DWC_XDCI_PARAM0_SET_EP_CFG_ACTN_INIT_STATE,
+             EPCMD_SET_EP_CONFIG,
+             &EpCmdParams
+             );
+
+  if (status) {
+    DEBUG ((DEBUG_INFO, "DwcXdciCoreInit: Failed to init params for SET_EP_CONFIG command on xDCI for EP0\n"));
+    return status;
+  }
+
+  //
+  // Issue the command
+  //
+  status = DwcXdciCoreIssueEpCmd (
+             LocalCoreHandle,
+             0,
+             EPCMD_SET_EP_CONFIG,
+             &EpCmdParams);
+
+  if (status) {
+    DEBUG ((DEBUG_INFO, "DwcXdciCoreInit: Failed to issue SET_EP_CONFIG command on xDCI for EP0\n"));
+    return status;
+  }
+
+  //
+  // Issue DEPCFG command for EP1
+  //
+  status = DwcXdciCoreInitEpCmdParams (
+             LocalCoreHandle,
+             &LocalCoreHandle->EpHandles[1].EpInfo,
+             DWC_XDCI_PARAM0_SET_EP_CFG_ACTN_INIT_STATE,
+             EPCMD_SET_EP_CONFIG,
+             &EpCmdParams
+             );
+
+  if (status) {
+    DEBUG ((DEBUG_INFO, "DwcXdciCoreInit: Failed to init params for SET_EP_CONFIG command on xDCI for EP1\n"));
+    return status;
+  }
+
+  //
+  // Issue the command
+  //
+  status = DwcXdciCoreIssueEpCmd (
+             LocalCoreHandle,
+             1,
+             EPCMD_SET_EP_CONFIG,
+             &EpCmdParams
+             );
+
+  if (status) {
+    DEBUG ((DEBUG_INFO, "DwcXdciCoreInit: Failed to issue SET_EP_CONFIG command on xDCI for EP1\n"));
+    return status;
+  }
+
+  //
+  // Issue DEPXFERCFG command for EP0
+  //
+  status = DwcXdciCoreInitEpCmdParams (
+             LocalCoreHandle,
+             &LocalCoreHandle->EpHandles[0].EpInfo,
+             DWC_XDCI_PARAM0_SET_EP_CFG_ACTN_NONE,
+             EPCMD_SET_EP_XFER_RES_CONFIG,
+             &EpCmdParams
+             );
+
+  if (status) {
+    DEBUG ((DEBUG_INFO, "DwcXdciCoreInit: Failed to init params for EPCMD_SET_EP_XFER_RES_CONFIG command on xDCI for EP0\n"));
+    return status;
+  }
+
+  //
+  // Issue the command
+  //
+  status = DwcXdciCoreIssueEpCmd (
+             LocalCoreHandle,
+             0,
+             EPCMD_SET_EP_XFER_RES_CONFIG,
+             &EpCmdParams
+             );
+
+  if (status) {
+    DEBUG ((DEBUG_INFO, "DwcXdciCoreInit: Failed to issue EPCMD_SET_EP_XFER_RES_CONFIG command on xDCI for EP0\n"));
+    return status;
+  }
+
+  //
+  // Issue DEPXFERCFG command for EP1
+  //
+  status = DwcXdciCoreInitEpCmdParams (
+             LocalCoreHandle,
+             &LocalCoreHandle->EpHandles[1].EpInfo,
+             DWC_XDCI_PARAM0_SET_EP_CFG_ACTN_NONE,
+             EPCMD_SET_EP_XFER_RES_CONFIG,
+             &EpCmdParams
+             );
+
+  if (status) {
+    DEBUG ((DEBUG_INFO, "DwcXdciCoreInit: Failed to init params for EPCMD_SET_EP_XFER_RES_CONFIG command on xDCI for EP1\n"));
+    return status;
+  }
+
+  //
+  // Issue the command
+  //
+  status = DwcXdciCoreIssueEpCmd (
+             LocalCoreHandle,
+             1,
+             EPCMD_SET_EP_XFER_RES_CONFIG,
+             &EpCmdParams
+             );
+
+  if (status) {
+    DEBUG ((DEBUG_INFO, "DwcXdciCoreInit: Failed to issue EPCMD_SET_EP_XFER_RES_CONFIG command on xDCI for EP1\n"));
+    return status;
+  }
+
+  //
+  // Prepare a Buffer for SETUP packet
+  //
+  LocalCoreHandle->Trbs = (DWC_XDCI_TRB *)((UINTN)
+                            LocalCoreHandle->UnalignedTrbs +
+                            (UINTN)(DWC_XDCI_TRB_BYTE_ALIGNMENT -
+                            ((UINT32)(UINTN)LocalCoreHandle->UnalignedTrbs %
+                            DWC_XDCI_TRB_BYTE_ALIGNMENT)));
+
+  DEBUG ((DEBUG_INFO, "(DwcXdciCoreInit)@@@@@@@@@ unalignedTrbs address is 0x%x\n", LocalCoreHandle->UnalignedTrbs));
+  DEBUG ((DEBUG_INFO, "(DwcXdciCoreInit)@@@@@@@@@ TRB address is 0x%x\n", LocalCoreHandle->Trbs));
+  //
+  // Allocate Setup Buffer that is 8-byte aligned
+  //
+  LocalCoreHandle->AlignedSetupBuffer = LocalCoreHandle->DefaultSetupBuffer +
+                                            (DWC_XDCI_SETUP_BUFF_SIZE -
+                                            ((UINT32)(UINTN)(LocalCoreHandle->DefaultSetupBuffer) % DWC_XDCI_SETUP_BUFF_SIZE));
+
+  //
+  // Aligned Buffer for status phase
+  //
+  LocalCoreHandle->AlignedMiscBuffer = LocalCoreHandle->MiscBuffer +
+                                           (DWC_XDCI_SETUP_BUFF_SIZE -
+                                           ((UINT32)(UINTN)(LocalCoreHandle->AlignedMiscBuffer) % DWC_XDCI_SETUP_BUFF_SIZE));
+
+
+  //
+  // Enable Physical Endpoints 0
+  //
+  UsbRegWrite (
+    BaseAddr,
+    DWC_XDCI_EP_DALEPENA_REG,
+    UsbRegRead (BaseAddr, DWC_XDCI_EP_DALEPENA_REG) | (1 << 0)
+    );
+  //
+  // Enable Physical Endpoints 1
+  //
+  UsbRegWrite (
+    BaseAddr,
+    DWC_XDCI_EP_DALEPENA_REG,
+    UsbRegRead (BaseAddr, DWC_XDCI_EP_DALEPENA_REG) | (1 << 1)
+    );
+
+  DEBUG ((DEBUG_INFO, "Default value of xDCI DWC_XDCI_DEVTEN_REG: 0x%x\n", UsbRegRead (BaseAddr, DWC_XDCI_DEVTEN_REG)));
+  return status;
+}
+
+
+/**
+  Interface:
+  This function is used to de-initialize the xDCI core
+  @CoreHandle: xDCI controller handle
+  @flags: Special flags for de-initializing the core in
+  particular way
+
+**/
+EFI_STATUS
+EFIAPI
+DwcXdciCoreDeinit (
+  IN VOID      *CoreHandle,
+  IN UINT32    flags
+  )
+{
+  FreePool (CoreHandle);
+  return EFI_SUCCESS;
+}
+
+
+/**
+  Interface:
+  This function is used to register event callback function
+  @CoreHandle: xDCI controller handle
+  @event: Event for which callback is to be registered
+  @callbackFn: Callback function to invoke after event occurs
+
+**/
+EFI_STATUS
+EFIAPI
+DwcXdciCoreRegisterCallback (
+  IN VOID                      *CoreHandle,
+  IN USB_DEVICE_EVENT_ID       Event,
+  IN USB_DEVICE_CALLBACK_FUNC  CallbackFunc
+  )
+{
+  XDCI_CORE_HANDLE  *LocalCoreHandle = (XDCI_CORE_HANDLE *)CoreHandle;
+
+  if (LocalCoreHandle == NULL) {
+    DEBUG ((DEBUG_INFO, "DwcXdciCoreRegisterCallback: INVALID handle\n"));
+    return EFI_DEVICE_ERROR;
+  }
+
+  DEBUG ((DEBUG_INFO, "DwcXdciCoreRegisterCallback: event is %d\n", Event));
+  switch (Event) {
+    case USB_DEVICE_DISCONNECT_EVENT:
+      LocalCoreHandle->EventCallbacks.DevDisconnectCallback = CallbackFunc;
+      break;
+
+    case USB_DEVICE_RESET_EVENT:
+      LocalCoreHandle->EventCallbacks.DevBusResetCallback = CallbackFunc;
+      break;
+
+    case USB_DEVICE_CONNECTION_DONE:
+      LocalCoreHandle->EventCallbacks.DevResetDoneCallback = CallbackFunc;
+      break;
+
+    case USB_DEVICE_STATE_CHANGE_EVENT:
+      LocalCoreHandle->EventCallbacks.DevLinkStateCallback = CallbackFunc;
+      break;
+
+    case USB_DEVICE_WAKEUP_EVENT:
+      LocalCoreHandle->EventCallbacks.DevWakeupCallback = CallbackFunc;
+      break;
+
+    case USB_DEVICE_HIBERNATION_REQ_EVENT:
+      LocalCoreHandle->EventCallbacks.DevHibernationCallback = CallbackFunc;
+      break;
+
+    case USB_DEVICE_SOF_EVENT:
+      LocalCoreHandle->EventCallbacks.DevSofCallback = CallbackFunc;
+      break;
+
+    case USB_DEVICE_ERRATIC_ERR_EVENT:
+      LocalCoreHandle->EventCallbacks.DevErraticErrCallback = CallbackFunc;
+      break;
+
+    case USB_DEVICE_CMD_CMPLT_EVENT:
+      LocalCoreHandle->EventCallbacks.DevCmdCmpltCallback = CallbackFunc;
+      break;
+
+    case USB_DEVICE_BUFF_OVERFLOW_EVENT:
+      LocalCoreHandle->EventCallbacks.DevBuffOvflwCallback = CallbackFunc;
+      break;
+
+    case USB_DEVICE_TEST_LMP_RX_EVENT:
+      LocalCoreHandle->EventCallbacks.DevTestLmpRxCallback = CallbackFunc;
+      break;
+
+    case USB_DEVICE_SETUP_PKT_RECEIVED:
+      LocalCoreHandle->EventCallbacks.DevSetupPktReceivedCallback = CallbackFunc;
+      break;
+
+    case USB_DEVICE_XFER_NRDY:
+      LocalCoreHandle->EventCallbacks.DevXferNrdyCallback = CallbackFunc;
+      break;
+
+    case USB_DEVICE_XFER_DONE:
+      LocalCoreHandle->EventCallbacks.DevXferDoneCallback = CallbackFunc;
+      break;
+
+    default:
+      break;
+  }
+
+  return EFI_SUCCESS;
+}
+
+
+/**
+  Interface:
+  This function is used to unregister event callback function
+  @CoreHandle: xDCI controller handle
+  @event: Event for which callback function is to be unregistered
+
+**/
+EFI_STATUS
+EFIAPI
+DwcXdciCoreUnregisterCallback (
+  IN VOID                   *CoreHandle,
+  IN USB_DEVICE_EVENT_ID    event
+  )
+{
+  XDCI_CORE_HANDLE  *LocalCoreHandle = (XDCI_CORE_HANDLE *)CoreHandle;
+
+  if (LocalCoreHandle == NULL) {
+    DEBUG ((DEBUG_INFO, "DwcXdciCoreUnregisterCallback: INVALID handle\n"));
+    return EFI_DEVICE_ERROR;
+  }
+
+  switch (event) {
+    case USB_DEVICE_DISCONNECT_EVENT:
+      LocalCoreHandle->EventCallbacks.DevDisconnectCallback = NULL;
+      break;
+
+    case USB_DEVICE_RESET_EVENT:
+      LocalCoreHandle->EventCallbacks.DevBusResetCallback = NULL;
+      break;
+
+    case USB_DEVICE_CONNECTION_DONE:
+      LocalCoreHandle->EventCallbacks.DevResetDoneCallback = NULL;
+      break;
+
+    case USB_DEVICE_STATE_CHANGE_EVENT:
+      LocalCoreHandle->EventCallbacks.DevLinkStateCallback = NULL;
+      break;
+
+    case USB_DEVICE_WAKEUP_EVENT:
+      LocalCoreHandle->EventCallbacks.DevWakeupCallback = NULL;
+      break;
+
+    case USB_DEVICE_HIBERNATION_REQ_EVENT:
+      LocalCoreHandle->EventCallbacks.DevHibernationCallback = NULL;
+      break;
+
+    case USB_DEVICE_SOF_EVENT:
+      LocalCoreHandle->EventCallbacks.DevSofCallback = NULL;
+      break;
+
+    case USB_DEVICE_ERRATIC_ERR_EVENT:
+      LocalCoreHandle->EventCallbacks.DevErraticErrCallback = NULL;
+      break;
+
+    case USB_DEVICE_CMD_CMPLT_EVENT:
+      LocalCoreHandle->EventCallbacks.DevCmdCmpltCallback = NULL;
+      break;
+
+    case USB_DEVICE_BUFF_OVERFLOW_EVENT:
+      LocalCoreHandle->EventCallbacks.DevBuffOvflwCallback = NULL;
+      break;
+
+    case USB_DEVICE_TEST_LMP_RX_EVENT:
+      LocalCoreHandle->EventCallbacks.DevTestLmpRxCallback = NULL;
+      break;
+
+    case USB_DEVICE_SETUP_PKT_RECEIVED:
+      LocalCoreHandle->EventCallbacks.DevSetupPktReceivedCallback = NULL;
+      break;
+
+    case USB_DEVICE_XFER_NRDY:
+      LocalCoreHandle->EventCallbacks.DevXferNrdyCallback = NULL;
+      break;
+
+    case USB_DEVICE_XFER_DONE:
+      LocalCoreHandle->EventCallbacks.DevXferDoneCallback = NULL;
+      break;
+
+    default:
+      break;
+  }
+
+  return EFI_SUCCESS;
+}
+
+
+/**
+  Interface:
+  This function is used as an interrupt service routine
+  @CoreHandle: xDCI controller handle
+
+**/
+EFI_STATUS
+EFIAPI
+DwcXdciCoreIsrRoutine (
+  IN VOID     *CoreHandle
+  )
+{
+  XDCI_CORE_HANDLE    *LocalCoreHandle = (XDCI_CORE_HANDLE *)CoreHandle;
+  UINT32              BaseAddr;
+  UINT32              eventCount;
+  UINT32              ProcessedEventCount;
+  UINT32              i;
+
+  if (CoreHandle == NULL) {
+    DEBUG ((DEBUG_INFO, "DwcXdciCoreIsrRoutine: INVALID handle\n"));
+    return EFI_DEVICE_ERROR;
+  }
+
+  if (LocalCoreHandle->InterrupProcessing == TRUE) {
+    DEBUG ((DEBUG_INFO, "interrupProcessing.........\n"));
+    return EFI_SUCCESS;
+  }
+
+  BaseAddr = LocalCoreHandle->BaseAddress;
+  //
+  // Event Buffer corresponding to each interrupt line needs
+  // to be Processed
+  //
+  LocalCoreHandle->InterrupProcessing = TRUE;
+  for (i = 0; i < LocalCoreHandle->MaxDevIntLines; i++) {
+    //
+    // Get the number of events HW has written for this
+    //  interrupt line
+    //
+    eventCount = UsbRegRead (BaseAddr, DWC_XDCI_EVNTCOUNT_REG (i));
+    eventCount &= DWC_XDCI_EVNTCOUNT_MASK;
+    ProcessedEventCount = 0;
+
+    //
+    // Process interrupt line Buffer only if count is non-zero
+    //
+    if (eventCount) {
+      //
+      // Process events in this Buffer
+      //
+      DwcXdciProcessInterruptLineEvents (LocalCoreHandle, eventCount, &ProcessedEventCount);
+      //
+      // Write back the Processed number of events so HW decrements it from current
+      // event count
+      //
+      UsbRegWrite (BaseAddr, DWC_XDCI_EVNTCOUNT_REG (i), ProcessedEventCount);
+    }
+  }
+  LocalCoreHandle->InterrupProcessing = FALSE;
+  return EFI_SUCCESS;
+}
+
+
+/**
+  Interface:
+  This function is used as an interrupt service routine and it processes only one event at a time.
+  @CoreHandle: xDCI controller handle
+
+**/
+EFI_STATUS
+EFIAPI
+DwcXdciCoreIsrRoutineTimerBased (
+  IN VOID     *CoreHandle
+  )
+{
+  XDCI_CORE_HANDLE    *LocalCoreHandle = (XDCI_CORE_HANDLE *)CoreHandle;
+  UINT32              BaseAddr;
+  UINT32              eventCount;
+  UINT32              ProcessedEventCount;
+  UINT32              currentEventAddr;
+  UINT32              ProcessedEventSize = 0;
+
+  if (CoreHandle == NULL) {
+    DEBUG ((DEBUG_INFO, "DwcXdciCoreIsrRoutineTimerBased: INVALID handle\n"));
+    return EFI_DEVICE_ERROR;
+  }
+
+  if (LocalCoreHandle->CurrentEventBuffer == NULL) {
+    DEBUG ((DEBUG_INFO, "ERROR: DwcXdciCoreIsrRoutineTimerBased: INVALID event Buffer\n"));
+    return EFI_INVALID_PARAMETER;
+  }
+
+  BaseAddr = LocalCoreHandle->BaseAddress;
+
+  eventCount = UsbRegRead (BaseAddr, DWC_XDCI_EVNTCOUNT_REG (0)) & DWC_XDCI_EVNTCOUNT_MASK;
+
+  if (LocalCoreHandle->InterrupProcessing == TRUE) {
+    DEBUG ((DEBUG_INFO, "interrupProcessing.........\n"));
+    return EFI_SUCCESS;
+  }
+
+  LocalCoreHandle->InterrupProcessing = TRUE;
+
+  ProcessedEventCount = 0;
+  currentEventAddr = (UINT32)(UINTN)(LocalCoreHandle->CurrentEventBuffer);
+
+  if (LocalCoreHandle->CurrentEventBuffer->Event & DWC_XDCI_EVENT_DEV_MASK) {
+    DwcXdciProcessDeviceEvent (
+      LocalCoreHandle,
+      LocalCoreHandle->CurrentEventBuffer,
+      &ProcessedEventSize
+      );
+  } else {
+    DwcXdciProcessEpEvent (
+      LocalCoreHandle,
+      LocalCoreHandle->CurrentEventBuffer,
+      &ProcessedEventSize);
+  }
+
+  eventCount -= ProcessedEventSize;
+  ProcessedEventCount += ProcessedEventSize;
+  if ((currentEventAddr + ProcessedEventSize) >=
+      ((UINT32)(UINTN)(LocalCoreHandle->AlignedEventBuffers) + (sizeof(DWC_XDCI_EVENT_BUFFER) * DWC_XDCI_MAX_EVENTS_PER_BUFFER))
+     ) {
+    currentEventAddr = (UINT32)(UINTN)(LocalCoreHandle->AlignedEventBuffers);
+    DEBUG ((DEBUG_INFO, "DwcXdciProcessInterruptLineEvents: Event Buffer bound reached\n"));
+  } else {
+    currentEventAddr += ProcessedEventSize;
+  }
+
+  LocalCoreHandle->CurrentEventBuffer = (DWC_XDCI_EVENT_BUFFER *)(UINTN)currentEventAddr;
+  UsbRegWrite (BaseAddr, DWC_XDCI_EVNTCOUNT_REG (0), ProcessedEventCount);
+  LocalCoreHandle->InterrupProcessing = FALSE;
+
+  return EFI_SUCCESS;
+}
+
+
+/**
+  Interface:
+  This function is used to enable xDCI to connect to the host
+  @CoreHandle: xDCI controller handle
+
+**/
+EFI_STATUS
+EFIAPI
+DwcXdciCoreConnect (
+  IN VOID     *CoreHandle
+  )
+{
+  XDCI_CORE_HANDLE    *LocalCoreHandle = (XDCI_CORE_HANDLE *)CoreHandle;
+  UINT32              MaxDelayIter = DWC_XDCI_MAX_DELAY_ITERATIONS;
+  UINT32              BaseAddr;
+
+  if (CoreHandle == NULL) {
+    DEBUG ((DEBUG_INFO, "DwcXdciCoreConnect: INVALID handle\n"));
+    return EFI_DEVICE_ERROR;
+  }
+
+  BaseAddr = LocalCoreHandle->BaseAddress;
+
+  //
+  // Clear KeepConnect bit so we can allow disconnect and re-connect
+  // Also issue No action on state change to aVOID any link change
+  //
+  UsbRegWrite (
+    BaseAddr,
+    DWC_XDCI_DCTL_REG,
+    (UsbRegRead(BaseAddr, DWC_XDCI_DCTL_REG) & ~DWC_XDCI_DCTL_KEEP_CONNECT_MASK) & ~DWC_XDCI_DCTL_STATE_CHANGE_REQ_MASK
+    );
+
+  //
+  // Set Run bit to connect to the host
+  //
+  UsbRegWrite (
+    BaseAddr,
+    DWC_XDCI_DCTL_REG,
+    UsbRegRead (BaseAddr, DWC_XDCI_DCTL_REG) | DWC_XDCI_DCTL_RUN_STOP_MASK
+    );
+
+  //
+  // Wait until core starts running
+  //
+  do {
+    if (!(UsbRegRead (BaseAddr, DWC_XDCI_DSTS_REG) & DWC_XDCI_DSTS_DEV_CTRL_HALTED_MASK)) {
+      break;
+    } else {
+      gBS->Stall (DWC_XDCI_MAX_DELAY_ITERATIONS);
+    }
+  } while (--MaxDelayIter);
+
+  if (!MaxDelayIter) {
+    DEBUG ((DEBUG_INFO, "Failed to run the device controller\n"));
+    return EFI_DEVICE_ERROR;
+  }
+
+  return EFI_SUCCESS;
+}
+
+
+/**
+  Interface:
+  This function is used to disconnect xDCI from the host
+  @CoreHandle: xDCI controller handle
+
+**/
+EFI_STATUS
+EFIAPI
+DwcXdciCoreDisconnect (
+  IN VOID    *CoreHandle
+  )
+{
+  XDCI_CORE_HANDLE  *LocalCoreHandle = (XDCI_CORE_HANDLE *)CoreHandle;
+  UINT32            MaxDelayIter = DWC_XDCI_MAX_DELAY_ITERATIONS;
+  UINT32            BaseAddr;
+  UINT32            eventCount;
+  UINT32            dsts;
+  UINT32            i;
+
+  if (CoreHandle == NULL) {
+    DEBUG ((DEBUG_INFO, "DwcXdciCoreDisconnect: INVALID handle\n"));
+    return EFI_DEVICE_ERROR;
+  }
+
+  BaseAddr = LocalCoreHandle->BaseAddress;
+
+  eventCount = UsbRegRead (BaseAddr, DWC_XDCI_EVNTCOUNT_REG (0));
+  eventCount &= DWC_XDCI_EVNTCOUNT_MASK;
+
+  DEBUG ((DEBUG_INFO, "DwcXdciCoreDisconnect: eventCount=%d\n", eventCount));
+  while (eventCount) {
+    DwcXdciCoreIsrRoutine(LocalCoreHandle);
+    eventCount = UsbRegRead (BaseAddr, DWC_XDCI_EVNTCOUNT_REG (0));
+    eventCount &= DWC_XDCI_EVNTCOUNT_MASK;
+    DEBUG ((DEBUG_INFO, "DwcXdciCoreDisconnect: eventCount=%d\n", eventCount));
+  }
+
+  //
+  // Issue DEPENDXFER for active transfers
+  //
+  for (i = 0; i < DWC_XDCI_MAX_ENDPOINTS; i++){
+    if (LocalCoreHandle->EpHandles[i].CurrentXferRscIdx){
+      DwcXdciEndXfer(LocalCoreHandle, i);
+    }
+  }
+  //
+  // Clear Run bit to disconnect from host
+  //
+  UsbRegWrite (
+    BaseAddr,
+    DWC_XDCI_DCTL_REG,
+    UsbRegRead(BaseAddr, DWC_XDCI_DCTL_REG) & ~DWC_XDCI_DCTL_RUN_STOP_MASK);
+
+  //
+  // Wait until core is halted
+  //
+  do {
+    dsts = UsbRegRead (BaseAddr, DWC_XDCI_DSTS_REG);
+    DEBUG ((DEBUG_INFO, "DwcXdciCoreDisconnect: waiting halt: DSTS=0x%x\n", dsts));
+    if ((dsts & DWC_XDCI_DSTS_DEV_CTRL_HALTED_MASK) != 0){
+      break;
+    } else {
+      gBS->Stall (DWC_XDCI_MAX_DELAY_ITERATIONS);
+    }
+  } while (--MaxDelayIter);
+
+  if (!MaxDelayIter) {
+    DEBUG ((DEBUG_INFO, "DwcXdciCoreDisconnect: Failed to halt the device controller\n"));
+    return EFI_DEVICE_ERROR;
+  }
+
+  return EFI_SUCCESS;
+}
+
+
+/**
+  Interface:
+  This function is used to obtain current USB bus Speed
+  @CoreHandle: xDCI controller handle
+  @Speed: Address of variable to save the Speed
+
+**/
+EFI_STATUS
+EFIAPI
+DwcXdciCoreGetSpeed (
+  IN VOID         *CoreHandle,
+  IN USB_SPEED    *Speed
+  )
+{
+  XDCI_CORE_HANDLE *LocalCoreHandle = (XDCI_CORE_HANDLE *)CoreHandle;
+
+  if (CoreHandle == NULL) {
+    DEBUG ((DEBUG_INFO, "DwcXdciCoreGetSpeed: INVALID handle\n"));
+    return EFI_DEVICE_ERROR;
+  }
+
+  if (Speed == NULL) {
+    DEBUG ((DEBUG_INFO, "DwcXdciCoreGetSpeed: INVALID parameter\n"));
+    return EFI_INVALID_PARAMETER;
+  }
+
+  *Speed = UsbRegRead (LocalCoreHandle->BaseAddress, DWC_XDCI_DSTS_REG) & DWC_XDCI_DSTS_CONN_SPEED_MASK;
+
+  return EFI_SUCCESS;
+}
+
+
+/**
+  Interface:
+  This function is used to obtain current USB bus Speed
+  @CoreHandle: xDCI controller handle
+  @address: USB address to set (assigned by USB host)
+
+**/
+EFI_STATUS
+EFIAPI
+DwcXdciCoreSetAddress (
+  IN VOID      *CoreHandle,
+  IN UINT32    address
+  )
+{
+  XDCI_CORE_HANDLE  *LocalCoreHandle = (XDCI_CORE_HANDLE *)CoreHandle;
+  UINT32            BaseAddr;
+
+  if (CoreHandle == NULL) {
+    DEBUG ((DEBUG_INFO, "DwcXdciCoreSetAddress: INVALID handle\n"));
+    return EFI_DEVICE_ERROR;
+  }
+
+  BaseAddr = LocalCoreHandle->BaseAddress;
+
+  DEBUG ((DEBUG_INFO, "DwcXdciCoreSetAddress is 0x%x \n", address));
+  //
+  // Program USB device address
+  //
+  UsbRegWrite (
+    BaseAddr,
+    DWC_XDCI_DCFG_REG,
+    (UsbRegRead(BaseAddr, DWC_XDCI_DCFG_REG) & ~DWC_XDCI_DCFG_DEV_ADDRESS_MASK) | (address << DWC_XDCI_DCFG_DEV_ADDRESS_BIT_POS)
+    );
+
+  LocalCoreHandle->DevState = UsbDevStateAddress;
+  DEBUG ((DEBUG_INFO, "Setup value of xDCI DWC_XDCI_GCTL_REG: 0x%x\n", UsbRegRead (BaseAddr, DWC_XDCI_GCTL_REG)));
+  DEBUG ((DEBUG_INFO, "Setup value of xDCI DWC_XDCI_DEVTEN_REG: 0x%x\n", UsbRegRead (BaseAddr, DWC_XDCI_DEVTEN_REG)));
+  DEBUG ((DEBUG_INFO, "Setup value of xDCI DWC_XDCI_DCFG_REG: 0x%x\n", UsbRegRead (BaseAddr, DWC_XDCI_DCFG_REG)));
+  DEBUG ((DEBUG_INFO, "Setup value of xDCI DWC_XDCI_DSTS_REG: 0x%x\n", UsbRegRead (BaseAddr, DWC_XDCI_DSTS_REG)));
+
+  return EFI_SUCCESS;
+}
+
+
+/**
+  Interface:
+  This function is used to set configuration
+  @CoreHandle: xDCI controller handle
+  @ConfigNum: config num to set (assigned by USB host)
+
+**/
+EFI_STATUS
+EFIAPI
+DwcXdciCoreSetConfig (
+  IN VOID      *CoreHandle,
+  IN UINT32    ConfigNum
+  )
+{
+  XDCI_CORE_HANDLE              *LocalCoreHandle = (XDCI_CORE_HANDLE *)CoreHandle;
+  DWC_XDCI_ENDPOINT_CMD_PARAMS  EpCmdParams;
+  EFI_STATUS                    status;
+
+  if (CoreHandle == NULL) {
+    DEBUG ((DEBUG_INFO, "DwcXdciCoreSetConfig: INVALID handle\n"));
+    return EFI_DEVICE_ERROR;
+  }
+
+  //
+  // Issue DEPSTARTCFG command on EP0 (new config for
+  // non-control EPs)
+  //
+  status = DwcXdciCoreInitEpCmdParams (
+            LocalCoreHandle,
+            &LocalCoreHandle->EpHandles[0].EpInfo,
+            DWC_XDCI_PARAM0_SET_EP_CFG_ACTN_NONE,
+            EPCMD_START_NEW_CONFIG,
+            &EpCmdParams
+            );
+
+  if (status) {
+    DEBUG ((DEBUG_INFO, "DwcXdciCoreSetConfig: Failed to init params for EPCMD_START_NEW_CONFIG command\n"));
+    return status;
+  }
+
+  //
+  // Issue the command
+  //
+  status = DwcXdciCoreIssueEpCmd (
+             LocalCoreHandle,
+             0,
+             (EPCMD_START_NEW_CONFIG | (2 << DWC_XDCI_EPCMD_RES_IDX_BIT_POS)),
+             &EpCmdParams
+             );
+
+  if (status) {
+    DEBUG ((DEBUG_INFO, "DwcXdciCoreSetConfig: Failed to issue EPCMD_START_NEW_CONFIG command\n"));
+    return status;
+  }
+
+  return status;
+}
+
+
+/**
+  Interface:
+  This function is used to set link state
+  @CoreHandle: xDCI controller handle
+  @state: Desired link state
+
+**/
+EFI_STATUS
+EFIAPI
+DwcXdciSetLinkState (
+  IN VOID                        *CoreHandle,
+  IN USB_DEVICE_SS_LINK_STATE    state
+  )
+{
+  XDCI_CORE_HANDLE  *LocalCoreHandle = (XDCI_CORE_HANDLE *)CoreHandle;
+  UINT32            BaseAddr;
+
+  if (CoreHandle == NULL) {
+    DEBUG ((DEBUG_INFO, "DwcXdciSetLinkState: INVALID handle\n"));
+    return EFI_DEVICE_ERROR;
+  }
+
+  BaseAddr = LocalCoreHandle->BaseAddress;
+
+  //
+  // Clear old mask
+  //
+  UsbRegWrite (
+    BaseAddr,
+    DWC_XDCI_DCTL_REG,
+    UsbRegRead (BaseAddr, DWC_XDCI_DCTL_REG) & ~DWC_XDCI_DCTL_STATE_CHANGE_REQ_MASK
+    );
+
+  //
+  // Request new state
+  //
+  UsbRegWrite (
+    BaseAddr,
+    DWC_XDCI_DCTL_REG,
+    UsbRegRead (BaseAddr, DWC_XDCI_DCTL_REG) | (state << DWC_XDCI_DCTL_STATE_CHANGE_REQ_BIT_POS)
+    );
+
+  return EFI_SUCCESS;
+}
+
+
+/**
+  Interface:
+  This function is used to initialize endpoint
+  @CoreHandle: xDCI controller handle
+  @EpInfo: Address of structure describing properties of EP
+  to be initialized
+
+**/
+EFI_STATUS
+EFIAPI
+DwcXdciInitEp (
+  IN VOID           *CoreHandle,
+  IN USB_EP_INFO    *EpInfo
+  )
+{
+  XDCI_CORE_HANDLE              *LocalCoreHandle = (XDCI_CORE_HANDLE *)CoreHandle;
+  DWC_XDCI_ENDPOINT_CMD_PARAMS  EpCmdParams;
+  EFI_STATUS                    status;
+  UINT32                        EpNum;
+
+  if (CoreHandle == NULL) {
+    DEBUG ((DEBUG_INFO, "DwcXdciInitEp: INVALID handle\n"));
+    return EFI_DEVICE_ERROR;
+  }
+
+  //
+  // Convert to physical endpoint
+  //
+  EpNum = DwcXdciGetPhysicalEpNum (EpInfo->EpNum, EpInfo->EpDir);
+
+  //
+  // Save EP properties
+  //
+  CopyMem (&(LocalCoreHandle->EpHandles[EpNum].EpInfo), EpInfo, sizeof (USB_EP_INFO));
+
+  //
+  // Init CheckFlag
+  //
+  LocalCoreHandle->EpHandles[EpNum].CheckFlag = FALSE;
+
+  //
+  // Init DEPCFG cmd params for EP
+  //
+  status = DwcXdciCoreInitEpCmdParams (
+             CoreHandle,
+             &LocalCoreHandle->EpHandles[EpNum].EpInfo,
+             DWC_XDCI_PARAM0_SET_EP_CFG_ACTN_INIT_STATE,
+             EPCMD_SET_EP_CONFIG,
+             &EpCmdParams
+             );
+
+  if (status) {
+    DEBUG ((DEBUG_INFO, "DwcXdciInitEp: Failed to init params for  EPCMD_SET_EP_CONFIG command\n"));
+    return status;
+  }
+
+  //
+  // Issue the command
+  //
+  status = DwcXdciCoreIssueEpCmd (
+             CoreHandle,
+             EpNum,
+             EPCMD_SET_EP_CONFIG,
+             &EpCmdParams
+             );
+
+  if (status) {
+    DEBUG ((DEBUG_INFO, "DwcXdciInitEp: Failed to issue  EPCMD_SET_EP_CONFIG command\n"));
+    return status;
+  }
+
+  //
+  // Issue a DEPXFERCFG command for endpoint
+  //
+  status = DwcXdciCoreInitEpCmdParams (
+             LocalCoreHandle,
+             &LocalCoreHandle->EpHandles[EpNum].EpInfo,
+             DWC_XDCI_PARAM0_SET_EP_CFG_ACTN_NONE,
+             EPCMD_SET_EP_XFER_RES_CONFIG,
+             &EpCmdParams
+             );
+
+  if (status) {
+    DEBUG ((DEBUG_INFO, "DwcXdciInitEp: Failed to init params for  EPCMD_SET_EP_XFER_RES_CONFIG command\n"));
+    return status;
+  }
+
+  //
+  // Issue the command
+  //
+  status = DwcXdciCoreIssueEpCmd (
+             LocalCoreHandle,
+             EpNum,
+             EPCMD_SET_EP_XFER_RES_CONFIG,
+             &EpCmdParams
+             );
+
+  if (status) {
+    DEBUG ((DEBUG_INFO, "DwcXdciInitEp: Failed to issue EPCMD_SET_EP_XFER_RES_CONFIG command\n"));
+  }
+
+  return status;
+}
+
+
+/**
+  Interface:
+  This function is used to enable non-Ep0 endpoint
+  @CoreHandle: xDCI controller handle
+  @EpInfo: Address of structure describing properties of EP
+  to be enabled
+
+**/
+EFI_STATUS
+EFIAPI
+DwcXdciEpEnable (
+  IN VOID           *CoreHandle,
+  IN USB_EP_INFO    *EpInfo
+  )
+{
+  XDCI_CORE_HANDLE  *LocalCoreHandle = (XDCI_CORE_HANDLE *)CoreHandle;
+  UINT32            EpNum;
+  UINT32            BaseAddr;
+
+  if (CoreHandle == NULL) {
+    DEBUG ((DEBUG_INFO, "DwcXdciEpEnable: INVALID handle\n"));
+    return EFI_DEVICE_ERROR;
+  }
+
+  BaseAddr = LocalCoreHandle->BaseAddress;
+
+  //
+  // Convert to physical endpoint
+  //
+  EpNum = DwcXdciGetPhysicalEpNum (EpInfo->EpNum, EpInfo->EpDir);
+
+  //
+  // Enable Physical Endpoint EpNum
+  //
+  UsbRegWrite (
+    BaseAddr,
+    DWC_XDCI_EP_DALEPENA_REG,
+    UsbRegRead (BaseAddr, DWC_XDCI_EP_DALEPENA_REG) | (1 << EpNum)
+    );
+
+  return EFI_SUCCESS;
+}
+
+
+/**
+  Interface:
+  This function is used to disable non-Ep0 endpoint
+  @CoreHandle: xDCI controller handle
+  @EpInfo: Address of structure describing properties of EP
+  to be enabled
+
+**/
+EFI_STATUS
+EFIAPI
+DwcXdciEpDisable (
+  IN VOID           *CoreHandle,
+  IN USB_EP_INFO    *EpInfo
+  )
+{
+  XDCI_CORE_HANDLE  *LocalCoreHandle = (XDCI_CORE_HANDLE *)CoreHandle;
+  UINT32            EpNum;
+  UINT32            BaseAddr;
+
+  if (CoreHandle == NULL) {
+    DEBUG ((DEBUG_INFO, "DwcXdciEpDisable: INVALID handle\n"));
+    return EFI_DEVICE_ERROR;
+  }
+
+  BaseAddr = LocalCoreHandle->BaseAddress;
+
+  //
+  // Convert to physical endpoint
+  //
+  EpNum = DwcXdciGetPhysicalEpNum (EpInfo->EpNum, EpInfo->EpDir);
+
+  //
+  // Disable Physical Endpoint EpNum
+  //
+  UsbRegWrite (
+    BaseAddr,
+    DWC_XDCI_EP_DALEPENA_REG,
+    UsbRegRead (BaseAddr, DWC_XDCI_EP_DALEPENA_REG) & ~(1 << EpNum)
+    );
+
+  return EFI_SUCCESS;
+}
+
+
+/**
+  Interface:
+  This function is used to STALL and endpoint
+  @CoreHandle: xDCI controller handle
+  @EpInfo: Address of structure describing properties of EP
+  to be enabled
+
+**/
+EFI_STATUS
+EFIAPI
+DwcXdciEpStall (
+  IN VOID           *CoreHandle,
+  IN USB_EP_INFO    *EpInfo
+  )
+{
+  XDCI_CORE_HANDLE              *LocalCoreHandle = (XDCI_CORE_HANDLE *)CoreHandle;
+  DWC_XDCI_ENDPOINT_CMD_PARAMS  EpCmdParams;
+  EFI_STATUS                    status;
+  UINT32                        EpNum;
+
+  if (CoreHandle == NULL) {
+    DEBUG ((DEBUG_INFO, "DwcXdciEpStall: INVALID handle\n"));
+    return EFI_DEVICE_ERROR;
+  }
+
+  //
+  // Convert to physical endpoint
+  //
+  EpNum = DwcXdciGetPhysicalEpNum (EpInfo->EpNum, EpInfo->EpDir);
+
+  //
+  // Set Ep State Info
+  //
+  if (LocalCoreHandle->EpHandles[EpNum].State != USB_EP_STATE_STALLED) {
+    LocalCoreHandle->EpHandles[EpNum].OrgState = LocalCoreHandle->EpHandles[EpNum].State;
+    LocalCoreHandle->EpHandles[EpNum].State = USB_EP_STATE_STALLED;
+  }
+  //
+  // Issue a DWC_XDCI_EPCMD_SET_STALL for EP
+  // Reset params
+  //
+  EpCmdParams.Param0 = EpCmdParams.Param1 = EpCmdParams.Param2 = 0;
+
+ //
+ // Issue the command
+ //
+ status = DwcXdciCoreIssueEpCmd (
+            LocalCoreHandle,
+            EpNum,
+            DWC_XDCI_EPCMD_SET_STALL,
+            &EpCmdParams
+            );
+
+ if (status) {
+   DEBUG ((DEBUG_INFO, "DwcXdciEpStall: Failed to issue EP stall command\n"));
+ }
+
+ return status;
+}
+
+
+/**
+  Interface:
+  This function is used to clear endpoint STALL
+  @CoreHandle: xDCI controller handle
+  @EpInfo: Address of structure describing properties of EP
+  to be enabled
+
+**/
+EFI_STATUS
+EFIAPI
+DwcXdciEpClearStall (
+  IN VOID           *CoreHandle,
+  IN USB_EP_INFO    *EpInfo
+  )
+{
+  XDCI_CORE_HANDLE              *LocalCoreHandle = (XDCI_CORE_HANDLE *)CoreHandle;
+  DWC_XDCI_ENDPOINT_CMD_PARAMS  EpCmdParams;
+  EFI_STATUS                    status;
+  UINT32                        EpNum;
+
+  if (CoreHandle == NULL) {
+    DEBUG ((DEBUG_INFO, "DwcXdciEpClearStall: INVALID handle\n"));
+    return EFI_DEVICE_ERROR;
+  }
+
+  //
+  // Convert to physical endpoint
+  //
+  EpNum = DwcXdciGetPhysicalEpNum (EpInfo->EpNum, EpInfo->EpDir);
+
+  //
+  // Set Ep State Info
+  //
+  LocalCoreHandle->EpHandles[EpNum].State = LocalCoreHandle->EpHandles[EpNum].OrgState;
+
+  //
+  // Issue a DWC_XDCI_EPCMD_CLEAR_STALL for EP
+  // Reset params
+  //
+  EpCmdParams.Param0 = EpCmdParams.Param1 = EpCmdParams.Param2 = 0;
+
+  //
+  // Issue the command
+  //
+ status = DwcXdciCoreIssueEpCmd (
+            LocalCoreHandle,
+            EpNum,
+            DWC_XDCI_EPCMD_CLEAR_STALL,
+            &EpCmdParams
+            );
+
+ if (status) {
+   DEBUG ((DEBUG_INFO, "DwcXdciEpStall: Failed to issue EP clea stall command\n"));
+ }
+
+ return status;
+}
+
+
+/**
+  Interface:
+  This function is used to set endpoint in NOT READY state
+  @CoreHandle: xDCI controller handle
+  @EpInfo: Address of structure describing properties of EP
+  to be enabled
+
+**/
+EFI_STATUS
+EFIAPI
+DwcXdciEpSetNrdy (
+  IN VOID           *CoreHandle,
+  IN USB_EP_INFO    *EpInfo
+  )
+{
+  XDCI_CORE_HANDLE  *LocalCoreHandle = (XDCI_CORE_HANDLE *)CoreHandle;
+  UINT32            EpNum;
+  UINT32            BaseAddr;
+  UINT32            MaxDelayIter = DWC_XDCI_MAX_DELAY_ITERATIONS;
+
+  if (CoreHandle == NULL) {
+    DEBUG ((DEBUG_INFO, "DwcXdciEpSetNrdy: INVALID handle\n"));
+    return EFI_DEVICE_ERROR;
+  }
+
+  BaseAddr = LocalCoreHandle->BaseAddress;
+
+  //
+  // Convert to physical endpoint
+  //
+  EpNum = DwcXdciGetPhysicalEpNum (EpInfo->EpNum, EpInfo->EpDir);
+
+  //
+  // Program the EP number in command's param reg
+  //
+  UsbRegWrite (BaseAddr, DWC_XDCI_DGCMD_PARAM_REG, EpNum);
+
+  //
+  // Issue EP not ready generic device command
+  //
+  UsbRegWrite (
+    BaseAddr,
+    DWC_XDCI_DGCMD_REG,
+    (UsbRegRead (BaseAddr, DWC_XDCI_DGCMD_REG) | DWC_XDCI_DGCMD_CMD_SET_EP_NRDY)
+    );
+
+  //
+  // Activate the command
+  //
+  UsbRegWrite (
+    BaseAddr,
+    DWC_XDCI_DGCMD_REG,
+    (UsbRegRead (BaseAddr, DWC_XDCI_DGCMD_REG) | DWC_XDCI_DGCMD_CMD_ACTIVE_MASK)
+    );
+
+  //
+  // Wait until command completes
+  //
+  do {
+    if (!(UsbRegRead (BaseAddr, DWC_XDCI_DGCMD_REG) & DWC_XDCI_DGCMD_CMD_ACTIVE_MASK))
+      break;
+    else
+      gBS->Stall (DWC_XDCI_MAX_DELAY_ITERATIONS);
+  } while (--MaxDelayIter);
+
+  if (!MaxDelayIter) {
+    DEBUG ((DEBUG_INFO, "Failed to issue Command\n"));
+    return EFI_DEVICE_ERROR;
+  }
+
+  return EFI_SUCCESS;
+}
+
+
+/**
+  Interface:
+  This function is used to queue receive SETUP packet request
+  @CoreHandle: xDCI controller handle
+  @Buffer: Address of Buffer to receive SETUP packet
+
+**/
+EFI_STATUS
+EFIAPI
+DwcXdciEp0ReceiveSetupPkt (
+  IN VOID     *CoreHandle,
+  IN UINT8    *Buffer
+  )
+{
+  XDCI_CORE_HANDLE                *LocalCoreHandle = (XDCI_CORE_HANDLE *)CoreHandle;
+  DWC_XDCI_ENDPOINT_CMD_PARAMS    EpCmdParams;
+  EFI_STATUS                      Status = EFI_DEVICE_ERROR;
+  DWC_XDCI_TRB                    *Trb;
+
+  if (CoreHandle == NULL) {
+    DEBUG ((DEBUG_INFO, "DwcXdciEp0ReceiveSetupPkt: INVALID handle\n"));
+    return EFI_DEVICE_ERROR;
+  }
+
+  LocalCoreHandle->EpHandles[0].EpInfo.EpNum = 0;
+  LocalCoreHandle->EpHandles[0].EpInfo.EpDir = 0;
+  LocalCoreHandle->EpHandles[0].State = USB_EP_STATE_SETUP;
+  Trb = LocalCoreHandle->Trbs;
+  DEBUG ((DEBUG_INFO, "(DwcXdciEp0ReceiveSetupPkt)\n"));
+
+  Status = DwcXdciCoreInitTrb (
+             LocalCoreHandle,
+             Trb,
+             TRBCTL_SETUP,
+             Buffer,
+             8
+             );
+
+  if (Status) {
+    DEBUG ((DEBUG_INFO, "DwcXdciEp0ReceiveSetupPkt: Init TRB Failed \n"));
+    return Status;
+  }
+
+  //
+  // Issue a DEPSTRTXFER for EP0
+  // Reset params
+  //
+  EpCmdParams.Param0 = EpCmdParams.Param1 = EpCmdParams.Param2 = 0;
+
+  //
+  // Init the lower re-bits for TRB address
+  //
+  EpCmdParams.Param1 = (UINT32)(UINTN)Trb;
+
+  //
+  // Issue the command
+  //
+  Status = DwcXdciCoreIssueEpCmd (
+             LocalCoreHandle,
+             0,
+             EPCMD_START_XFER,
+             &EpCmdParams
+             );
+
+  if (Status) {
+    DEBUG ((DEBUG_INFO, "\nDwcXdciEp0ReceiveSetupPkt: Failed to issue Start Transfer command"));
+  }
+
+  //
+  // Save new resource index for this transfer
+  //
+  LocalCoreHandle->EpHandles[0].CurrentXferRscIdx = ((UsbRegRead(LocalCoreHandle->BaseAddress, DWC_XDCI_EPCMD_REG(0)) &
+                                                         DWC_XDCI_EPCMD_RES_IDX_MASK) >> DWC_XDCI_EPCMD_RES_IDX_BIT_POS
+                                                         );
+
+  return Status;
+}
+
+
+/**
+  Interface:
+  This function is used to queue receive status packet on EP0
+  @CoreHandle: xDCI controller handle
+
+**/
+EFI_STATUS
+EFIAPI
+DwcXdciEp0ReceiveStatusPkt (
+  IN VOID    *CoreHandle
+  )
+{
+  XDCI_CORE_HANDLE                *LocalCoreHandle = (XDCI_CORE_HANDLE *)CoreHandle;
+  DWC_XDCI_TRB                    *Trb;
+  DWC_XDCI_TRB_CONTROL            TrbCtrl;
+  DWC_XDCI_ENDPOINT_CMD_PARAMS    EpCmdParams;
+  EFI_STATUS                      Status;
+  UINT32                          BaseAddr;
+
+  if (CoreHandle == NULL) {
+    DEBUG ((DEBUG_INFO, "DwcXdciEp0ReceiveStatusPkt: INVALID handle\n"));
+    return EFI_DEVICE_ERROR;
+  }
+
+  BaseAddr = LocalCoreHandle->BaseAddress;
+
+  //
+  // We are receiving on EP0 so physical EP is 0
+  //
+  Trb = LocalCoreHandle->Trbs;
+  DEBUG ((DEBUG_INFO, "(DwcXdciEp0ReceiveStatusPkt)\n"));
+  if (Trb->TrbCtrl & DWC_XDCI_TRB_CTRL_HWO_MASK) {
+    DEBUG ((DEBUG_INFO, "statusPkt still not transferred.\n"));
+    return EFI_SUCCESS;
+  }
+
+  LocalCoreHandle->EpHandles[0].EpInfo.EpNum = 0;
+  LocalCoreHandle->EpHandles[0].EpInfo.EpDir = 0;
+
+  //
+  // OUT data phase for 3-phased control transfer
+  //
+  TrbCtrl = TRBCTL_3_PHASE;
+
+  //
+  // Init TRB for the transfer
+  //
+  Status = DwcXdciCoreInitTrb (
+             LocalCoreHandle,
+             Trb,
+             TrbCtrl,
+             LocalCoreHandle->AlignedSetupBuffer,
+             0
+             );
+
+  if (!Status) {
+    //
+    // Issue a DEPSTRTXFER for EP0
+    // Reset params
+    //
+    EpCmdParams.Param0 = EpCmdParams.Param1 = EpCmdParams.Param2 = 0;
+
+    //
+    // Init the lower bits for TRB address
+    //
+    EpCmdParams.Param1 = (UINT32)(UINTN)Trb;
+
+    //
+    // Issue the command
+    //
+    Status = DwcXdciCoreIssueEpCmd (
+               LocalCoreHandle,
+               0,
+               EPCMD_START_XFER,
+               &EpCmdParams
+               );
+
+    if (Status) {
+      DEBUG ((DEBUG_INFO, "DwcXdciEp0ReceiveStatusPkt: Failed to issue Start Transfer command for EP0\n"));
+    }
+    //
+    // Save new resource index for this transfer
+    //
+    LocalCoreHandle->EpHandles[0].CurrentXferRscIdx = ((UsbRegRead(BaseAddr, DWC_XDCI_EPCMD_REG(0)) & DWC_XDCI_EPCMD_RES_IDX_MASK) >> DWC_XDCI_EPCMD_RES_IDX_BIT_POS);
+
+    //
+    // TODO: We are not using the EP state for control transfers
+    // right now simply because we're only supporting IN
+    // data phase. For the current use case, we don't
+    // need OUT data phase. We can add that later and we will
+    // add some of the state and SETUP packet awareness code
+    //
+    LocalCoreHandle->EpHandles[0].State = USB_EP_STATE_STATUS;
+  }
+
+  return Status;
+}
+
+
+/**
+  Interface:
+  This function is used to send status packet on EP0
+  @CoreHandle: xDCI controller handle
+
+**/
+EFI_STATUS
+EFIAPI
+DwcXdciEp0SendStatusPkt (
+  IN VOID    *CoreHandle
+  )
+{
+  XDCI_CORE_HANDLE                *LocalCoreHandle = (XDCI_CORE_HANDLE *)CoreHandle;
+  DWC_XDCI_TRB                    *Trb;
+  DWC_XDCI_ENDPOINT_CMD_PARAMS    EpCmdParams;
+  EFI_STATUS                      Status;
+  UINT32                          BaseAddr;
+
+  if (CoreHandle == NULL) {
+    DEBUG ((DEBUG_INFO, "DwcXdciEp0SendStatusPkt: INVALID handle\n"));
+    return EFI_DEVICE_ERROR;
+  }
+
+  BaseAddr = LocalCoreHandle->BaseAddress;
+
+  //
+  // We are sending on EP0 so physical EP is 1
+  //
+  Trb = (LocalCoreHandle->Trbs + (1 * DWC_XDCI_TRB_NUM));
+  DEBUG ((DEBUG_INFO, "(DwcXdciEp0SendStatusPkt)\n"));
+
+  LocalCoreHandle->EpHandles[0].State = USB_EP_STATE_STATUS;
+  Status = DwcXdciCoreInitTrb (
+             LocalCoreHandle,
+             Trb,
+             TRBCTL_2_PHASE,
+             LocalCoreHandle->AlignedMiscBuffer,
+             0
+             );
+
+  if (Status) {
+    DEBUG ((DEBUG_INFO, "DwcXdciEp0SendStatusPkt: TRB failed during status phase\n"));
+    return Status;
+  }
+
+  //
+  // Issue a DEPSTRTXFER for EP1
+  // Reset params
+  //
+  EpCmdParams.Param0 = EpCmdParams.Param1 = EpCmdParams.Param2 = 0;
+
+  //
+  // Init the lower re-bits for TRB address
+  //
+  EpCmdParams.Param1 = (UINT32)(UINTN)Trb;
+
+  //
+  // Issue the command
+  //
+  Status = DwcXdciCoreIssueEpCmd (
+             LocalCoreHandle,
+             1,
+             EPCMD_START_XFER,
+             &EpCmdParams
+             );
+
+  if (Status) {
+    DEBUG ((DEBUG_INFO, "DwcXdciEp0SendStatusPkt: Failed to issue Start Transfer on EP0\n"));
+  }
+
+  //
+  // Save new resource index for this transfer
+  //
+  LocalCoreHandle->EpHandles[1].CurrentXferRscIdx = ((UsbRegRead(BaseAddr, DWC_XDCI_EPCMD_REG(1)) & DWC_XDCI_EPCMD_RES_IDX_MASK) >> DWC_XDCI_EPCMD_RES_IDX_BIT_POS);
+  LocalCoreHandle->EpHandles[0].State = USB_EP_STATE_STATUS;
+
+  return Status;
+}
+
+
+/**
+  Interface:
+  This function is used to send data on non-EP0 endpoint
+  @CoreHandle: xDCI controller handle
+  @EpInfo: Address of structure describing properties of EP
+  @Buffer: Buffer containing data to transmit
+  @size: Size of transfer (in bytes)
+
+**/
+EFI_STATUS
+EFIAPI
+DwcXdciEpTxData (
+  IN VOID                *CoreHandle,
+  IN USB_XFER_REQUEST    *XferReq
+  )
+{
+  XDCI_CORE_HANDLE              *LocalCoreHandle = (XDCI_CORE_HANDLE *)CoreHandle;
+  DWC_XDCI_ENDPOINT_CMD_PARAMS  EpCmdParams;
+  DWC_XDCI_TRB                  *Trb;
+  DWC_XDCI_TRB_CONTROL          TrbCtrl;
+  EFI_STATUS                    Status;
+  UINT32                        EpNum;
+  UINT32                        BaseAddr;
+
+  if (CoreHandle == NULL) {
+    DEBUG ((DEBUG_INFO, "DwcXdciEpTxData: INVALID handle\n"));
+    return EFI_DEVICE_ERROR;
+  }
+
+  if (XferReq == NULL) {
+    DEBUG ((DEBUG_INFO, "DwcXdciEpTxData: INVALID transfer request\n"));
+    return EFI_INVALID_PARAMETER;
+  }
+
+  BaseAddr = LocalCoreHandle->BaseAddress;
+
+  //
+  // Convert to physical endpoint
+  //
+  EpNum = DwcXdciGetPhysicalEpNum (
+             XferReq->EpInfo.EpNum,
+             XferReq->EpInfo.EpDir
+             );
+
+  Trb = (LocalCoreHandle->Trbs + (EpNum * DWC_XDCI_TRB_NUM));
+  DEBUG ((DEBUG_INFO, "(DwcXdciEpTxData)EpNum is %d\n", EpNum));
+
+
+  if (EpNum > 1)
+    TrbCtrl = TRBCTL_NORMAL;
+  else
+    TrbCtrl = TRBCTL_CTRL_DATA_PHASE;
+
+  if (Trb->TrbCtrl & DWC_XDCI_TRB_CTRL_HWO_MASK) {
+    Status = DwcXdciEndXfer (LocalCoreHandle, EpNum);
+    if (Status) {
+      DEBUG ((DEBUG_INFO, "DwcXdciEpTxData: Failed to end previous transfer\n"));
+    }
+
+    Status = DwcXdciCoreFlushEpTxFifo (LocalCoreHandle, EpNum);
+    if (Status) {
+      DEBUG ((DEBUG_INFO, "DwcXdciEpTxData: Failed to end previous transfer\n"));
+    }
+  }
+
+  //
+  // Data phase
+  //
+  CopyMem (&(LocalCoreHandle->EpHandles[EpNum].XferHandle), XferReq, sizeof (USB_XFER_REQUEST));
+  LocalCoreHandle->EpHandles[EpNum].State = USB_EP_STATE_DATA;
+
+  LocalCoreHandle->EpHandles[EpNum].Trb = Trb;
+
+  Status = DwcXdciCoreInitTrb (
+             LocalCoreHandle,
+             Trb,
+             TrbCtrl,
+             XferReq->XferBuffer,
+             XferReq->XferLen
+             );
+
+  if (Status) {
+    DEBUG ((DEBUG_INFO, "DwcXdciEpTxData: TRB failed\n"));
+    return Status;
+  }
+
+  //
+  // Issue a DEPSTRTXFER for EP
+  // Reset params
+  //
+  EpCmdParams.Param0 = EpCmdParams.Param1 = EpCmdParams.Param2 = 0;
+
+  //
+  // Init the lower re-bits for TRB address
+  //
+  EpCmdParams.Param1 = (UINT32)(UINTN)Trb;
+
+  //
+  // Issue the command
+  //
+  Status = DwcXdciCoreIssueEpCmd (
+             LocalCoreHandle,
+             EpNum,
+             EPCMD_START_XFER,
+             &EpCmdParams
+             );
+
+  //
+  // Save new resource index for this transfer
+  //
+  LocalCoreHandle->EpHandles[EpNum].CurrentXferRscIdx = ((UsbRegRead (BaseAddr, DWC_XDCI_EPCMD_REG(EpNum)) & DWC_XDCI_EPCMD_RES_IDX_MASK) >> DWC_XDCI_EPCMD_RES_IDX_BIT_POS);
+
+  return Status;
+}
+
+
+/**
+  Interface:
+  This function is used to receive data on non-EP0 endpoint
+  @CoreHandle: xDCI controller handle
+  @EpInfo: Address of structure describing properties of EP
+  @Buffer: Buffer containing data to transmit
+  @size: Size of transfer (in bytes)
+
+**/
+EFI_STATUS
+EFIAPI
+DwcXdciEpRxData (
+  IN VOID                *CoreHandle,
+  IN USB_XFER_REQUEST    *XferReq
+  )
+{
+  XDCI_CORE_HANDLE              *LocalCoreHandle = (XDCI_CORE_HANDLE *)CoreHandle;
+  DWC_XDCI_ENDPOINT_CMD_PARAMS  EpCmdParams;
+  DWC_XDCI_TRB                  *Trb;
+  DWC_XDCI_TRB_CONTROL          TrbCtrl;
+  EFI_STATUS                    Status;
+  UINT32                        EpNum;
+  UINT32                        BaseAddr;
+
+  if (CoreHandle == NULL) {
+    DEBUG ((DEBUG_INFO, "DwcXdciEpRxData: INVALID handle\n"));
+    return EFI_DEVICE_ERROR;
+  }
+
+  if (XferReq == NULL) {
+    DEBUG ((DEBUG_INFO, "DwcXdciEpRxData: INVALID transfer request\n"));
+    return EFI_INVALID_PARAMETER;
+  }
+
+  BaseAddr = LocalCoreHandle->BaseAddress;
+
+  //
+  // Convert to physical endpoint
+  //
+  EpNum = DwcXdciGetPhysicalEpNum (XferReq->EpInfo.EpNum, XferReq->EpInfo.EpDir);
+
+  Trb = (LocalCoreHandle->Trbs + (EpNum * DWC_XDCI_TRB_NUM));
+  DEBUG ((DEBUG_INFO, "(DwcXdciEpRxData)EpNum is %d\n", EpNum));
+
+  if (EpNum > 1)
+    TrbCtrl = TRBCTL_NORMAL;
+  else
+    TrbCtrl = TRBCTL_CTRL_DATA_PHASE;
+
+  //
+  // If CheckFlag didn't set to FALSE, means the previous transfer request didn't complete,
+  // need to wait the previous request done.
+  //
+  if (LocalCoreHandle->EpHandles[EpNum].CheckFlag == TRUE) {
+    return EFI_NOT_READY;
+  }
+
+  LocalCoreHandle->EpHandles[EpNum].CheckFlag = TRUE;
+
+  //
+  // Data phase
+  //
+  CopyMem (&(LocalCoreHandle->EpHandles[EpNum].XferHandle), XferReq, sizeof (USB_XFER_REQUEST));
+
+  LocalCoreHandle->EpHandles[EpNum].State = USB_EP_STATE_DATA;
+
+  LocalCoreHandle->EpHandles[EpNum].Trb = Trb;
+
+  DEBUG ((DEBUG_INFO, "(DwcXdciEpRxData)XferReq->XferLen is 0x%x\n", XferReq->XferLen));
+
+  Status = DwcXdciCoreInitTrb (
+             LocalCoreHandle,
+             Trb,
+             TrbCtrl,
+             XferReq->XferBuffer,
+             XferReq->XferLen
+             );
+
+  if (Status) {
+    DEBUG ((DEBUG_INFO, "DwcXdciEpRxData: TRB failed\n"));
+    return Status;
+  }
+  //
+  // Issue a DEPSTRTXFER for EP
+  // Reset params
+  //
+  EpCmdParams.Param0 = EpCmdParams.Param1 = EpCmdParams.Param2 = 0;
+
+  //
+  // Init the lower re-bits for TRB address
+  //
+  EpCmdParams.Param1 = (UINT32)(UINTN)Trb;
+
+  //
+  // Issue the command
+  //
+  Status = DwcXdciCoreIssueEpCmd (
+             LocalCoreHandle,
+             EpNum,
+             EPCMD_START_XFER,
+             &EpCmdParams
+             );
+
+  if (Status) {
+    DEBUG ((DEBUG_INFO, "DwcXdciEpRxData: Failed to start transfer\n"));
+  }
+
+  //
+  // Save new resource index for this transfer
+  //
+  LocalCoreHandle->EpHandles[EpNum].CurrentXferRscIdx = ((UsbRegRead(BaseAddr, DWC_XDCI_EPCMD_REG(EpNum)) & DWC_XDCI_EPCMD_RES_IDX_MASK) >> DWC_XDCI_EPCMD_RES_IDX_BIT_POS);
+
+  return Status;
+}
+
+
+
+STATIC
+EFI_STATUS
+DwcXdciCoreFlushEpFifo (
+  IN XDCI_CORE_HANDLE    *CoreHandle,
+  IN UINT32              EpNum
+  )
+{
+  UINT32 BaseAddr;
+  UINT32 MaxDelayIter = DWC_XDCI_MAX_DELAY_ITERATIONS;
+  UINT32 fifoNum;
+  UINT32 Param;
+
+  if (CoreHandle == NULL) {
+    DEBUG ((DEBUG_INFO, "ERROR: DwcXdciCoreFlushEpTxFifo: INVALID handle\n"));
+    return EFI_DEVICE_ERROR;
+  }
+
+  BaseAddr = CoreHandle->BaseAddress;
+
+  //
+  // Translate to FIFOnum
+  // NOTE: Assuming this is a Tx EP
+  //
+  fifoNum = (EpNum >> 1);
+
+  //
+  // TODO: Currently we are only using TxFIFO 0. Later map these
+  // Write the FIFO num/dir param for the generic command.
+  //
+
+  Param = UsbRegRead (BaseAddr, DWC_XDCI_DGCMD_PARAM_REG);
+  Param &= ~(DWC_XDCI_DGCMD_PARAM_TX_FIFO_NUM_MASK | DWC_XDCI_DGCMD_PARAM_TX_FIFO_DIR_MASK);
+
+  if ((EpNum & 0x01) != 0) {
+    Param |= (fifoNum | DWC_XDCI_DGCMD_PARAM_TX_FIFO_DIR_MASK);
+  } else {
+    Param |= fifoNum;
+  }
+
+  DEBUG ((DEBUG_INFO, "USB FU Flash: CMD 0x%08x :: Param 0x%08x\n",
+        (UsbRegRead(BaseAddr, DWC_XDCI_DGCMD_REG) | DWC_XDCI_DGCMD_CMD_SEL_FIFO_FLUSH | DWC_XDCI_DGCMD_CMD_ACTIVE_MASK),
+        Param));
+
+  UsbRegWrite (
+    BaseAddr,
+    DWC_XDCI_DGCMD_PARAM_REG,
+    Param
+    );
+
+  //
+  // Write the command to flush all FIFOs
+  //
+  UsbRegWrite (
+    BaseAddr,
+    DWC_XDCI_DGCMD_REG,
+    (UsbRegRead(BaseAddr, DWC_XDCI_DGCMD_REG) | DWC_XDCI_DGCMD_CMD_SEL_FIFO_FLUSH | DWC_XDCI_DGCMD_CMD_ACTIVE_MASK)
+    );
+
+
+  //
+  // Wait until command completes
+  //
+  do {
+    if (!(UsbRegRead(BaseAddr, DWC_XDCI_DGCMD_REG) & DWC_XDCI_DGCMD_CMD_ACTIVE_MASK))
+      break;
+    else
+      gBS->Stall (DWC_XDCI_MAX_DELAY_ITERATIONS);
+  } while (--MaxDelayIter);
+
+  if (!MaxDelayIter) {
+    DEBUG ((DEBUG_INFO, "Failed to issue Command\n"));
+    return EFI_DEVICE_ERROR;
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Interface:
+  This function is used to cancel a transfer on non-EP0 endpoint
+  @CoreHandle: xDCI controller handle
+  @EpInfo: Address of structure describing properties of EP
+
+**/
+EFI_STATUS
+EFIAPI
+DwcXdciEpCancelTransfer (
+  IN VOID           *CoreHandle,
+  IN USB_EP_INFO    *EpInfo
+  )
+{
+  EFI_STATUS  Status = EFI_DEVICE_ERROR;
+  UINT32      EpNum;
+
+  if (CoreHandle == NULL) {
+    DEBUG ((DEBUG_INFO, "DwcXdciEpCancelTransfer: INVALID handle\n"));
+    return EFI_DEVICE_ERROR;
+  }
+
+  //
+  // Get physical EP num
+  //
+  EpNum = DwcXdciGetPhysicalEpNum (EpInfo->EpNum, EpInfo->EpDir);
+  Status = DwcXdciEndXfer(CoreHandle, EpNum);
+  DwcXdciCoreFlushEpFifo(CoreHandle, EpNum);
+
+  return Status;
+}
+
+
+EFI_STATUS
+usbProcessDeviceResetDet (
+  IN XDCI_CORE_HANDLE    *CoreHandle
+  )
+{
+   return DwcXdciProcessDeviceResetDet (CoreHandle);
+}
+
+EFI_STATUS
+usbProcessDeviceResetDone (
+  IN XDCI_CORE_HANDLE    *CoreHandle
+  )
+{
+  return DwcXdciProcessDeviceResetDone (CoreHandle);
+}
+
+UINT32
+UsbGetPhysicalEpNum (
+  IN UINT32        EndpointNum,
+  IN USB_EP_DIR    EndpointDir
+  )
+{
+  return DwcXdciGetPhysicalEpNum(
+                            EndpointNum,
+                            EndpointDir
+                            );
+}
+
+
+EFI_STATUS
+EFIAPI
+UsbXdciCoreReinit (
+  IN VOID                     *CoreHandle
+  )
+{
+  EFI_STATUS                      status = EFI_DEVICE_ERROR;
+  UINT32                          BaseAddr;
+  XDCI_CORE_HANDLE                *LocalCoreHandle;
+  DWC_XDCI_ENDPOINT_CMD_PARAMS    EpCmdParams;
+  UINT32                          MaxDelayIter = DWC_XDCI_MAX_DELAY_ITERATIONS;
+  UINT8                           i;
+
+  LocalCoreHandle = CoreHandle;
+
+  if (CoreHandle == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (LocalCoreHandle == NULL) {
+    DEBUG ((DEBUG_INFO, "DwcXdciCoreInit: Failed to allocate handle for xDCI\n"));
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  BaseAddr = LocalCoreHandle->BaseAddress;
+
+  DEBUG ((DEBUG_INFO, "Resetting the USB core\n"));
+  UsbRegWrite (
+    BaseAddr,
+    DWC_XDCI_DCTL_REG,
+    UsbRegRead (BaseAddr, DWC_XDCI_DCTL_REG) | DWC_XDCI_DCTL_CSFTRST_MASK
+    );
+
+  //
+  // Wait until core soft reset completes
+  //
+  do {
+    if (!(UsbRegRead (BaseAddr, DWC_XDCI_DCTL_REG) & DWC_XDCI_DCTL_CSFTRST_MASK)) {
+      break;
+    } else {
+      gBS->Stall (DWC_XDCI_MAX_DELAY_ITERATIONS);
+    }
+  } while (--MaxDelayIter);
+
+  if (!MaxDelayIter) {
+    DEBUG ((DEBUG_INFO, "Failed to reset device controller\n"));
+    return EFI_DEVICE_ERROR;
+  }
+
+  DEBUG ((DEBUG_INFO, "USB core has been reset\n"));
+
+  LocalCoreHandle->DevState = UsbDevStateDefault;
+
+  //
+  // Clear KeepConnect bit so we can allow disconnect and
+  // re-connect. Stay in RX_DETECT state
+  //
+  UsbRegWrite (
+    BaseAddr,
+    DWC_XDCI_DCTL_REG,
+    UsbRegRead (BaseAddr, DWC_XDCI_DCTL_REG) &
+    (~DWC_XDCI_DCTL_KEEP_CONNECT_MASK) &
+    ((~DWC_XDCI_DCTL_STATE_CHANGE_REQ_MASK) |
+    (DWC_XDCI_DCTL_STATE_CHANGE_REQ_RX_DETECT << DWC_XDCI_DCTL_STATE_CHANGE_REQ_BIT_POS))
+    );
+
+  DEBUG ((DEBUG_INFO, "Device controller Synopsys ID: %x\n", UsbRegRead (BaseAddr, DWC_XDCI_GSNPSID_REG)));
+  DEBUG ((DEBUG_INFO, "Default value of xDCI GSBUSCFG0 and GSBUSCFG1: %x, %x\n",
+          UsbRegRead (BaseAddr, DWC_XDCI_GSBUSCFG0_REG),
+          UsbRegRead (BaseAddr, DWC_XDCI_GSBUSCFG1_REG)));
+
+  DEBUG ((DEBUG_INFO, "Default value of xDCI GTXTHRCFG and GRXTHRCFG: %x, %x\n",
+          UsbRegRead (BaseAddr, DWC_XDCI_GTXTHRCFG_REG),
+          UsbRegRead (BaseAddr, DWC_XDCI_GRXTHRCFG_REG)));
+
+  //
+  // Clear ULPI auto-resume bit
+  //
+  UsbRegWrite (
+    BaseAddr,
+    DWC_XDCI_GUSB2PHYCFG_REG (0),
+    (UsbRegRead (BaseAddr, DWC_XDCI_GUSB2PHYCFG_REG (0)) & ~DWC_XDCI_GUSB2PHYCFG_ULPI_AUTO_RESUME_MASK)
+    );
+
+  DEBUG ((DEBUG_INFO, "Default value of xDCI GUSB2PHYCFG and GUSB3PIPECTL: %x, %x\n",
+          UsbRegRead (BaseAddr, DWC_XDCI_GUSB2PHYCFG_REG (0)),
+          UsbRegRead (BaseAddr, DWC_XDCI_GUSB3PIPECTL_REG (0))));
+
+  //
+  // Only one RxFIFO
+  //
+  DEBUG ((DEBUG_INFO, "Default value of DWC_XDCI_GRXFIFOSIZ: %x\n",
+          UsbRegRead (BaseAddr, DWC_XDCI_GRXFIFOSIZ_REG (0))));
+
+  for (i = 0; i < DWC_XDCI_MAX_ENDPOINTS; i++) {
+    DEBUG ((DEBUG_INFO, "Default value of xDCI DWC_XDCI_GTXFIFOSIZ %d: %x\n",
+            i, UsbRegRead (BaseAddr, DWC_XDCI_GTXFIFOSIZ_REG (i))));
+  }
+
+  //
+  // TODO: Need to check if TxFIFO should start where RxFIFO ends
+  // or default is correct i.e. TxFIFO starts at 0 just like RxFIFO
+  //
+
+  //
+  // Allocate and Initialize Event Buffers
+  //
+  LocalCoreHandle->MaxDevIntLines = ((UsbRegRead (BaseAddr, DWC_XDCI_GHWPARAMS1_REG) &
+                                           DWC_XDCI_GHWPARAMS1_NUM_INT_MASK) >>
+                                           DWC_XDCI_GHWPARAMS1_NUM_INT_BIT_POS);
+
+  DEBUG ((DEBUG_INFO, "Max dev int lines: %d\n", LocalCoreHandle->MaxDevIntLines));
+  //
+  // One event Buffer per interrupt line.
+  //  Need to align it to size of event Buffer
+  //  Buffer needs to be big enough. Otherwise the core
+  //  won't operate
+  //
+  LocalCoreHandle->AlignedEventBuffers = (DWC_XDCI_EVENT_BUFFER *)
+                                             ((UINT32)(UINTN)(LocalCoreHandle->EventBuffers) +
+                                             ((sizeof (DWC_XDCI_EVENT_BUFFER) * DWC_XDCI_MAX_EVENTS_PER_BUFFER) -
+                                             (((UINT32)(UINTN)(LocalCoreHandle->EventBuffers)) %
+                                             (sizeof (DWC_XDCI_EVENT_BUFFER) * DWC_XDCI_MAX_EVENTS_PER_BUFFER))));
+
+  for (i = 0; i < LocalCoreHandle->MaxDevIntLines; i++) {
+    UsbRegWrite (
+      BaseAddr,
+      DWC_XDCI_GEVNTADR_REG (i),
+      (UINT32)(UINTN)(LocalCoreHandle->AlignedEventBuffers + i * sizeof(DWC_XDCI_EVENT_BUFFER) * DWC_XDCI_MAX_EVENTS_PER_BUFFER)
+      );
+
+    //
+    // Clear High 32bit address register, GEVNTADR register is 64-bit register
+    // default is 0xffffffffffffffff
+    //
+    UsbRegWrite (BaseAddr, DWC_XDCI_GEVNTADR_REG (i) + 4, 0x00000000);
+
+    LocalCoreHandle->CurrentEventBuffer = LocalCoreHandle->AlignedEventBuffers;
+    //
+    // Write size and clear the mask
+    //
+    UsbRegWrite (
+      BaseAddr,
+      DWC_XDCI_EVNTSIZ_REG (i),
+      sizeof (DWC_XDCI_EVENT_BUFFER) * DWC_XDCI_MAX_EVENTS_PER_BUFFER
+      );
+
+    //
+    // Write 0 to the event count register as the last step
+    // for event configuration
+    //
+    UsbRegWrite (BaseAddr, DWC_XDCI_EVNTCOUNT_REG (i), 0);
+
+    DEBUG ((DEBUG_INFO, "Value of xDCI Event Buffer %d: %x, Size: %x, Count: %x\n",
+                        i,
+                        UsbRegRead (BaseAddr, DWC_XDCI_GEVNTADR_REG (i)),
+                        UsbRegRead (BaseAddr, DWC_XDCI_EVNTSIZ_REG (i)),
+                        UsbRegRead (BaseAddr, DWC_XDCI_EVNTCOUNT_REG (i))));
+  }
+
+    //
+    // Program Global Control Register to disable scaledown,
+    // disable clock gating
+    //
+    UsbRegWrite (
+      BaseAddr,
+      DWC_XDCI_GCTL_REG,
+      ((UsbRegRead(BaseAddr, DWC_XDCI_GCTL_REG) &
+                    ~(DWC_XDCI_GCTL_SCALE_DOWN_MODE_MASK + DWC_XDCI_GCTL_RAMCLKSEL_MASK + DWC_XDCI_GCTL_DISABLE_SCRAMB_MASK)) |
+                    DWC_XDCI_GCTL_DISABLE_CLK_GATING_MASK |
+                    (DWC_XDCI_GCTL_PRT_CAP_DEVICE << DWC_XDCI_GCTL_PRT_CAP_DIR_BIT_POS)));
+
+    DEBUG ((DEBUG_INFO, "Setup value of xDCI DWC_XDCI_GCTL_REG: 0x%x\n", UsbRegRead (BaseAddr, DWC_XDCI_GCTL_REG)));
+
+
+  //
+  // TODO: Program desired Speed and set LPM capable
+  // We will do this when SuperSpeed works. For now,
+  // force into High-Speed mode to aVOID anyone trying this
+  // on Super Speed port
+  //
+#ifdef SUPPORT_SUPER_SPEED
+  UsbRegWrite (
+    BaseAddr,
+    DWC_XDCI_DCFG_REG,
+    (UsbRegRead (BaseAddr, DWC_XDCI_DCFG_REG) & ~DWC_XDCI_DCFG_DESIRED_DEV_SPEED_MASK) | LocalCoreHandle->DesiredSpeed
+    );
+#else
+  UsbRegWrite (
+    BaseAddr,
+    DWC_XDCI_DCFG_REG,
+    (UsbRegRead (BaseAddr, DWC_XDCI_DCFG_REG) & ~DWC_XDCI_DCFG_DESIRED_DEV_SPEED_MASK) | DWC_XDCI_DCFG_DESIRED_HS_SPEED
+    );
+#endif
+
+  DEBUG ((DEBUG_INFO, "Setup value of xDCI DWC_XDCI_DCFG_REG: 0x%x\n", UsbRegRead (BaseAddr, DWC_XDCI_DCFG_REG)));
+  DEBUG ((DEBUG_INFO, "Setup value of xDCI DWC_XDCI_DSTS_REG: 0x%x\n", UsbRegRead (BaseAddr, DWC_XDCI_DSTS_REG)));
+
+  //
+  // Enable Device Interrupt Events
+  //
+  UsbRegWrite (
+    BaseAddr,
+    DWC_XDCI_DEVTEN_REG,
+    DWC_XDCI_DEVTEN_DEVICE_INTS
+    );
+
+  //
+  // Program the desired role
+  //
+  UsbRegWrite (
+    BaseAddr,
+    DWC_XDCI_GCTL_REG,
+    (UsbRegRead (BaseAddr, DWC_XDCI_GCTL_REG) & ~DWC_XDCI_GCTL_PRT_CAP_DIR_MASK) | (LocalCoreHandle->Role << DWC_XDCI_GCTL_PRT_CAP_DIR_BIT_POS)
+    );
+
+  //
+  // Clear USB2 suspend for start new config command
+  //
+  UsbRegWrite (
+    BaseAddr,
+    DWC_XDCI_GUSB2PHYCFG_REG (0),
+    (UsbRegRead (BaseAddr, DWC_XDCI_GUSB2PHYCFG_REG(0)) & ~DWC_XDCI_GUSB2PHYCFG_SUSPEND_PHY_MASK)
+    );
+  //
+  // Clear USB3 suspend for start new config command
+  //
+  UsbRegWrite (
+    BaseAddr,
+    DWC_XDCI_GUSB3PIPECTL_REG (0),
+    (UsbRegRead (BaseAddr, DWC_XDCI_GUSB3PIPECTL_REG(0)) & ~DWC_XDCI_GUSB3PIPECTL_SUSPEND_PHY_MASK)
+    );
+  //
+  // Issue DEPSTARTCFG command for EP0
+  //
+  status = DwcXdciCoreInitEpCmdParams (
+             LocalCoreHandle,
+             &LocalCoreHandle->EpHandles[0].EpInfo,
+             DWC_XDCI_PARAM0_SET_EP_CFG_ACTN_NONE,
+             EPCMD_START_NEW_CONFIG,
+             &EpCmdParams
+             );
+
+  if (status) {
+    DEBUG ((DEBUG_INFO, "DwcXdciCoreInit: Failed to init params for START_NEW_CONFIG EP command on xDCI\n"));
+    return status;
+  }
+
+  //
+  // Issue the command
+  //
+  status = DwcXdciCoreIssueEpCmd (
+             LocalCoreHandle,
+             0,
+             EPCMD_START_NEW_CONFIG,
+             &EpCmdParams
+             );
+
+  if (status) {
+    DEBUG ((DEBUG_INFO, "DwcXdciCoreInit: Failed to issue START_NEW_CONFIG EP command on xDCI\n"));
+    return status;
+  }
+
+  //
+  // Issue DEPCFG command for EP0
+  //
+  status = DwcXdciCoreInitEpCmdParams (
+             LocalCoreHandle,
+             &LocalCoreHandle->EpHandles[0].EpInfo,
+             DWC_XDCI_PARAM0_SET_EP_CFG_ACTN_INIT_STATE,
+             EPCMD_SET_EP_CONFIG,
+             &EpCmdParams
+             );
+
+  if (status) {
+    DEBUG ((DEBUG_INFO, "DwcXdciCoreInit: Failed to init params for SET_EP_CONFIG command on xDCI for EP0\n"));
+    return status;
+  }
+
+  //
+  // Issue the command
+  //
+  status = DwcXdciCoreIssueEpCmd (
+             LocalCoreHandle,
+             0,
+             EPCMD_SET_EP_CONFIG,
+             &EpCmdParams);
+
+  if (status) {
+    DEBUG ((DEBUG_INFO, "DwcXdciCoreInit: Failed to issue SET_EP_CONFIG command on xDCI for EP0\n"));
+    return status;
+  }
+
+  //
+  // Issue DEPCFG command for EP1
+  //
+  status = DwcXdciCoreInitEpCmdParams (
+             LocalCoreHandle,
+             &LocalCoreHandle->EpHandles[1].EpInfo,
+             DWC_XDCI_PARAM0_SET_EP_CFG_ACTN_INIT_STATE,
+             EPCMD_SET_EP_CONFIG,
+             &EpCmdParams
+             );
+
+  if (status) {
+    DEBUG ((DEBUG_INFO, "DwcXdciCoreInit: Failed to init params for SET_EP_CONFIG command on xDCI for EP1\n"));
+    return status;
+  }
+
+  //
+  // Issue the command
+  //
+  status = DwcXdciCoreIssueEpCmd (
+             LocalCoreHandle,
+             1,
+             EPCMD_SET_EP_CONFIG,
+             &EpCmdParams
+             );
+
+  if (status) {
+    DEBUG ((DEBUG_INFO, "DwcXdciCoreInit: Failed to issue SET_EP_CONFIG command on xDCI for EP1\n"));
+    return status;
+  }
+
+  //
+  // Issue DEPXFERCFG command for EP0
+  //
+  status = DwcXdciCoreInitEpCmdParams (
+             LocalCoreHandle,
+             &LocalCoreHandle->EpHandles[0].EpInfo,
+             DWC_XDCI_PARAM0_SET_EP_CFG_ACTN_NONE,
+             EPCMD_SET_EP_XFER_RES_CONFIG,
+             &EpCmdParams
+             );
+
+  if (status) {
+    DEBUG ((DEBUG_INFO, "DwcXdciCoreInit: Failed to init params for EPCMD_SET_EP_XFER_RES_CONFIG command on xDCI for EP0\n"));
+    return status;
+  }
+
+  //
+  // Issue the command
+  //
+  status = DwcXdciCoreIssueEpCmd (
+             LocalCoreHandle,
+             0,
+             EPCMD_SET_EP_XFER_RES_CONFIG,
+             &EpCmdParams
+             );
+
+  if (status) {
+    DEBUG ((DEBUG_INFO, "DwcXdciCoreInit: Failed to issue EPCMD_SET_EP_XFER_RES_CONFIG command on xDCI for EP0\n"));
+    return status;
+  }
+
+  //
+  // Issue DEPXFERCFG command for EP1
+  //
+  status = DwcXdciCoreInitEpCmdParams (
+             LocalCoreHandle,
+             &LocalCoreHandle->EpHandles[1].EpInfo,
+             DWC_XDCI_PARAM0_SET_EP_CFG_ACTN_NONE,
+             EPCMD_SET_EP_XFER_RES_CONFIG,
+             &EpCmdParams
+             );
+
+  if (status) {
+    DEBUG ((DEBUG_INFO, "DwcXdciCoreInit: Failed to init params for EPCMD_SET_EP_XFER_RES_CONFIG command on xDCI for EP1\n"));
+    return status;
+  }
+
+  //
+  // Issue the command
+  //
+  status = DwcXdciCoreIssueEpCmd (
+             LocalCoreHandle,
+             1,
+             EPCMD_SET_EP_XFER_RES_CONFIG,
+             &EpCmdParams
+             );
+
+  if (status) {
+    DEBUG ((DEBUG_INFO, "DwcXdciCoreInit: Failed to issue EPCMD_SET_EP_XFER_RES_CONFIG command on xDCI for EP1\n"));
+    return status;
+  }
+
+  //
+  // Prepare a Buffer for SETUP packet
+  //
+  LocalCoreHandle->Trbs = (DWC_XDCI_TRB *)((UINTN)
+                            LocalCoreHandle->UnalignedTrbs +
+                            (UINTN)(DWC_XDCI_TRB_BYTE_ALIGNMENT -
+                            ((UINT32)(UINTN)LocalCoreHandle->UnalignedTrbs %
+                            DWC_XDCI_TRB_BYTE_ALIGNMENT)));
+
+  DEBUG ((DEBUG_INFO, "(DwcXdciCoreInit)@@@@@@@@@ unalignedTrbs address is 0x%x\n", LocalCoreHandle->UnalignedTrbs));
+  DEBUG ((DEBUG_INFO, "(DwcXdciCoreInit)@@@@@@@@@ TRB address is 0x%x\n", LocalCoreHandle->Trbs));
+
+  //
+  // Allocate Setup Buffer that is 8-byte aligned
+  //
+  LocalCoreHandle->AlignedSetupBuffer = LocalCoreHandle->DefaultSetupBuffer +
+                                            (DWC_XDCI_SETUP_BUFF_SIZE -
+                                            ((UINT32)(UINTN)(LocalCoreHandle->DefaultSetupBuffer) % DWC_XDCI_SETUP_BUFF_SIZE));
+
+  //
+  // Aligned Buffer for status phase
+  //
+  LocalCoreHandle->AlignedMiscBuffer = LocalCoreHandle->MiscBuffer +
+                                           (DWC_XDCI_SETUP_BUFF_SIZE -
+                                           ((UINT32)(UINTN)(LocalCoreHandle->AlignedMiscBuffer) % DWC_XDCI_SETUP_BUFF_SIZE));
+
+  //
+  // We will queue SETUP request when we see bus reset
+  //
+
+  //
+  // Enable Physical Endpoints 0
+  //
+  UsbRegWrite (
+    BaseAddr,
+    DWC_XDCI_EP_DALEPENA_REG,
+    UsbRegRead (BaseAddr, DWC_XDCI_EP_DALEPENA_REG) | (1 << 0)
+    );
+
+  //
+  // Enable Physical Endpoints 1
+  //
+  UsbRegWrite (
+    BaseAddr,
+    DWC_XDCI_EP_DALEPENA_REG,
+    UsbRegRead (BaseAddr, DWC_XDCI_EP_DALEPENA_REG) | (1 << 1)
+    );
+
+  DEBUG ((DEBUG_INFO, "Default value of xDCI DWC_XDCI_DEVTEN_REG: 0x%x\n", UsbRegRead (BaseAddr, DWC_XDCI_DEVTEN_REG)));
+  return status;
+
+
+}
+
+
+EFI_STATUS
+UsbXdciCoreFlushEpFifo (
+  IN VOID           *CoreHandle,
+  IN USB_EP_INFO    *EpInfo
+  )
+{
+  EFI_STATUS  Status = EFI_DEVICE_ERROR;
+  UINT32      EpNum;
+
+  if (CoreHandle == NULL) {
+    DEBUG ((DEBUG_INFO, "DwcXdciEpCancelTransfer: INVALID handle\n"));
+    return EFI_DEVICE_ERROR;
+  }
+
+  //
+  // Get physical EP num
+  //
+  EpNum = DwcXdciGetPhysicalEpNum (EpInfo->EpNum, EpInfo->EpDir);
+  DwcXdciCoreFlushEpFifo(CoreHandle, EpNum);
+
+  return Status;
+}
diff --git a/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciDWC.h b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciDWC.h
new file mode 100644
index 0000000000..9c1b2d1d85
--- /dev/null
+++ b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciDWC.h
@@ -0,0 +1,741 @@
+/** @file
+  Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR>
+
+  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.
+
+**/
+
+#ifndef _XDCI_DWC_H_
+#define _XDCI_DWC_H_
+
+#include "XdciCommon.h"
+#include "XdciDevice.h"
+
+#define DWC_XDCI_MAX_ENDPOINTS                             (16)
+#define DWC_XDCI_SS_CTRL_EP_MPS                            (512)
+#define DWC_XDCI_HS_CTRL_EP_MPS                            (64)
+#define DWC_XDCI_FS_CTRL_EP_MPS                            (64)
+#define DWC_XDCI_LS_CTRL_EP_MPS                            (8)
+#define DWC_XDCI_SS_CTRL_BUF_SIZE                          (512)
+#define DWC_XDCI_SETUP_BUFF_SIZE                           (8)
+#define DWC_XDCI_MAX_EVENTS_PER_BUFFER                     (16)
+#define DWC_XDCI_TRB_BYTE_ALIGNMENT                        (16)
+#define DWC_XDCI_DEFAULT_TX_FIFO_SIZE                      (1024)
+#define DWC_XDCI_TRB_NUM                                   (32)
+#define DWC_XDCI_MASK                                      (DWC_XDCI_TRB_NUM - 1)
+
+#define DWC_XDCI_MAX_DELAY_ITERATIONS                      (1000)
+
+#define DWC_XDCI_GSBUSCFG0_REG                             (0xC100)
+#define DWC_XDCI_GSBUSCFG1_REG                             (0xC104)
+#define DWC_XDCI_GTXTHRCFG_REG                             (0xC108)
+#define DWC_XDCI_GRXTHRCFG_REG                             (0xC10C)
+
+//
+// Global Control Register and bit definitions
+//
+#define DWC_XDCI_GCTL_REG                                  (0xC110)
+#define DWC_XDCI_GCTL_PWRDNSCALE_MASK                      (0xFFF80000)
+#define DWC_XDCI_GCTL_PWRDNSCALE_VAL                       (0x13880000)
+#define DWC_XDCI_GCTL_U2RSTECN_MASK                        (0x00010000)
+#define DWC_XDCI_GCTL_PRT_CAP_DIR_MASK                     (0x00003000)
+#define DWC_XDCI_GCTL_PRT_CAP_DIR_BIT_POS                  (12)
+#define DWC_XDCI_GCTL_PRT_CAP_HOST                         (1)
+#define DWC_XDCI_GCTL_PRT_CAP_DEVICE                       (2)
+#define DWC_XDCI_GCTL_PRT_CAP_OTG                          (3)
+#define DWC_XDCI_GCTL_RAMCLKSEL_MASK                       (0x000000C0)
+#define DWC_XDCI_GCTL_SCALE_DOWN_MODE_MASK                 (0x00000030)
+#define DWC_XDCI_GCTL_DISABLE_CLK_GATING_MASK              (0x00000001)
+#define DWC_XDCI_GCTL_DISABLE_SCRAMB_MASK                  (0x00000008)
+
+#define DWC_XDCI_GSTS_REG                                  (0xC118)
+#define DWC_XDCI_GSNPSID_REG                               (0xC120)
+#define DWC_XDCI_GGPIO_REG                                 (0xC124)
+#define DWC_XDCI_GUID_REG                                  (0xC128)
+#define DWC_XDCI_GUCTL_REG                                 (0xC12C)
+#define DWC_XDCI_GBUSERRADDR                               (0xC130)
+
+//
+// Global Hardware Parameters Registers
+//
+#define DWC_XDCI_GHWPARAMS0_REG                            (0xC140)
+#define DWC_XDCI_GHWPARAMS1_REG                            (0xC144)
+#define DWC_XDCI_GHWPARAMS1_NUM_INT_MASK                   (0x1F8000)
+#define DWC_XDCI_GHWPARAMS1_NUM_INT_BIT_POS                (15)
+
+#define DWC_XDCI_GHWPARAMS2_REG                            (0xC148)
+#define DWC_XDCI_GHWPARAMS3_REG                            (0xC14C)
+#define DWC_XDCI_GHWPARAMS4_REG                            (0xC150)
+#define DWC_XDCI_GHWPARAMS4_CACHE_TRBS_PER_XFER_MASK       (0x0000003F)
+#define DWC_XDCI_GHWPARAMS5_REG                            (0xC154)
+#define DWC_XDCI_GHWPARAMS6_REG                            (0xC158)
+#define DWC_XDCI_GHWPARAMS7_REG                            (0xC15C)
+#define DWC_XDCI_GHWPARAMS8_REG                            (0xC600)
+
+#define DWC_XDCI_GDBGFIFOSPACE_REG                         (0xC160)
+
+#define DWC_XDCI_GUSB2PHYCFG_REG(n)                        (0xC200 + (n << 2))
+#define DWC_XDCI_GUSB2PHYCFG_ULPI_AUTO_RESUME_MASK         (0x00008000)
+#define DWC_XDCI_GUSB2PHYCFG_SUSPEND_PHY_MASK              (0x00000040)
+
+#define DWC_XDCI_GUSB3PIPECTL_REG(n)                       (0xC2C0 + (n << 2))
+#define DWC_XDCI_GUSB3PIPECTL_SUSPEND_PHY_MASK             (0x00020000)
+
+#define DWC_XDCI_GTXFIFOSIZ_REG(n)                         (0xC300 + (n << 2))
+#define DWC_XDCI_GTXFIFOSIZ_START_ADDRESS_MASK             (0xFFFF0000)
+#define DWC_XDCI_GTXFIFOSIZ_START_ADDRESS_BIT_POS          (16)
+#define DWC_XDCI_GRXFIFOSIZ_REG(n)                         (0xC380 + (n << 2))
+
+//
+// Global Event Buffer Registers
+//
+#define DWC_XDCI_GEVNTADR_REG(n)                           (0xC400 + (n << 4))
+#define DWC_XDCI_EVNTSIZ_REG(n)                            (0xC408 + (n << 4))
+#define DWC_XDCI_EVNTSIZ_MASK                              (0x0000FFFF)
+#define DWC_XDCI_EVNT_INTR_MASK                            (0x80000000)
+#define DWC_XDCI_EVNTCOUNT_REG(n)                          (0xC40C + (n << 4))
+#define DWC_XDCI_EVNTCOUNT_MASK                            (0x0000FFFF)
+
+//
+// Device Configuration Register and Bit Definitions
+//
+#define DWC_XDCI_DCFG_REG                                  (0xC700)
+#define DWC_XDCI_DCFG_LPM_CAPABLE_MASK                     (0x00400000)
+#define DWC_XDCI_DCFG_DEV_ADDRESS_MASK                     (0x000003F8)
+#define DWC_XDCI_DCFG_DEV_ADDRESS_BIT_POS                  (3)
+#define DWC_XDCI_DCFG_DESIRED_DEV_SPEED_MASK               (0x00000007)
+#define DWC_XDCI_DCFG_DESIRED_SS_SPEED                     (0x00000004)
+#define DWC_XDCI_DCFG_DESIRED_FS_SPEED                     (0x00000001)
+#define DWC_XDCI_DCFG_DESIRED_HS_SPEED                     (0x00000000)
+
+//
+// Device Control Register
+//
+#define DWC_XDCI_DCTL_REG                                  (0xC704)
+#define DWC_XDCI_DCTL_RUN_STOP_MASK                        (0x80000000)
+#define DWC_XDCI_DCTL_RUN_STOP_BIT_POS                     (31)
+#define DWC_XDCI_DCTL_CSFTRST_MASK                         (0x40000000)
+#define DWC_XDCI_DCTL_CSFTRST_BIT_POS                      (30)
+#define DWC_XDCI_DCTL_KEEP_CONNECT_MASK                    (0x00080000)
+#define DWC_XDCI_DCTL_KEEP_CONNECT_BIT_POS                 (19)
+#define DWC_XDCI_DCTL_CSFTRST_BIT_POS                      (30)
+#define DWC_XDCI_DCTL_STATE_CHANGE_REQ_MASK                (0x000001E0)
+#define DWC_XDCI_DCTL_STATE_CHANGE_REQ_BIT_POS             (5)
+#define DWC_XDCI_DCTL_STATE_CHANGE_REQ_NO_ACTION           (1)
+#define DWC_XDCI_DCTL_STATE_CHANGE_REQ_SS_DISABLED         (4)
+#define DWC_XDCI_DCTL_STATE_CHANGE_REQ_RX_DETECT           (5)
+#define DWC_XDCI_DCTL_STATE_CHANGE_REQ_SS_INACTIVE         (6)
+#define DWC_XDCI_DCTL_STATE_CHANGE_REQ_RECOVERY            (8)
+#define DWC_XDCI_DCTL_STATE_CHANGE_REQ_COMPLIANCE          (10)
+#define DWC_XDCI_DCTL_STATE_CHANGE_REQ_REMOTE_WAKEUP       (8)
+
+//
+// Device Event Enable Register
+//
+#define DWC_XDCI_DEVTEN_REG                                (0xC708)
+#define DWC_XDCI_DEVTEN_DISCONN_DET_EN_MASK                (0x00000001)
+#define DWC_XDCI_DEVTEN_RESET_DET_EN_MASK                  (0x00000002)
+#define DWC_XDCI_DEVTEN_CONN_DONE_DET_EN_MASK              (0x00000004)
+#define DWC_XDCI_DEVTEN_LINK_STATE_CHANGE_DET_EN_MASK      (0x00000008)
+#define DWC_XDCI_DEVTEN_RESUME_WAKEUP_DET_EN_MASK          (0x00000010)
+#define DWC_XDCI_DEVTEN_HIBERNATION_REQ_EN_MASK            (0x00000020)
+#define DWC_XDCI_DEVTEN_U3L2L1_DET_EN_MASK                 (0x00000040)
+#define DWC_XDCI_DEVTEN_SOF_DET_EN_MASK                    (0x00000080)
+#define DWC_XDCI_DEVTEN_ERRATIC_ERR_DET_EN_MASK            (0x00000200)
+#define DWC_XDCI_DEVTEN_VNDR_DEV_TST_RX_DET_EN_MASK        (0x00001000)
+
+#define DWC_XDCI_DEVTEN_DEVICE_INTS                        (DWC_XDCI_DEVTEN_DISCONN_DET_EN_MASK | \
+        DWC_XDCI_DEVTEN_RESET_DET_EN_MASK | DWC_XDCI_DEVTEN_CONN_DONE_DET_EN_MASK | \
+        DWC_XDCI_DEVTEN_LINK_STATE_CHANGE_DET_EN_MASK | DWC_XDCI_DEVTEN_RESUME_WAKEUP_DET_EN_MASK | \
+        DWC_XDCI_DEVTEN_HIBERNATION_REQ_EN_MASK | DWC_XDCI_DEVTEN_U3L2L1_DET_EN_MASK | \
+        DWC_XDCI_DEVTEN_ERRATIC_ERR_DET_EN_MASK)
+
+#define DWC_XDCI_EVENT_BUFF_BULK_STREAM_ID_MASK            (0xFFFF0000)
+#define DWC_XDCI_EVENT_BUFF_ISOCH_UFRAME_NUM_MASK          (0xFFFF0000)
+#define DWC_XDCI_EVENT_BUFF_EP_CMD_TYPE_MASK               (0x0F000000)
+#define DWC_XDCI_EVENT_BUFF_EP_XFER_RES_INDEX_MASK         (0x007F0000)
+#define DWC_XDCI_EVENT_BUFF_EP_XFER_ACTIVE_MASK            (0x00008000)
+#define DWC_XDCI_EVENT_BUFF_EP_CTRL_DATA_REQ_MASK          (0x00001000)
+#define DWC_XDCI_EVENT_BUFF_EP_CTRL_STATUS_REQ_MASK        (0x00002000)
+#define DWC_XDCI_EVENT_BUFF_EP_LST_MASK                    (0x00008000)
+#define DWC_XDCI_EVENT_BUFF_EP_MISSED_ISOCH_MASK           (0x00008000)
+#define DWC_XDCI_EVENT_BUFF_EP_IOC_MASK                    (0x00004000)
+#define DWC_XDCI_EVENT_BUFF_EP_LAST_PKT_MASK               (0x00002000)
+#define DWC_XDCI_EVENT_BUFF_EP_STREAM_NOT_FND_MASK         (0x00002000)
+#define DWC_XDCI_EVENT_BUFF_EP_STREAM_FND_MASK             (0x00001000)
+#define DWC_XDCI_EVENT_BUFF_EP_ERR_NO_RES_MASK             (0x00001000)
+#define DWC_XDCI_EVENT_BUFF_EP_INVALID_RES_MASK            (0x00001000)
+
+#define DWC_XDCI_EVENT_BUFF_EP_EVENT_MASK                  (0x000003C0)
+#define DWC_XDCI_EVENT_BUFF_EP_EVENT_BIT_POS               (6)
+#define DWC_XDCI_EVENT_BUFF_EP_XFER_CMPLT                  (1)
+#define DWC_XDCI_EVENT_BUFF_EP_XFER_IN_PROGRESS            (2)
+#define DWC_XDCI_EVENT_BUFF_EP_XFER_NOT_READY              (3)
+#define DWC_XDCI_EVENT_BUFF_EP_STREAM_EVENT                (6)
+#define DWC_XDCI_EVENT_BUFF_EP_CMD_CMPLT                   (7)
+
+#define DWC_XDCI_EVENT_BUFF_EP_NUM_MASK                    (0x0000003E)
+#define DWC_XDCI_EVENT_BUFF_EP_NUM_BIT_POS                 (1)
+
+#define DWC_XDCI_EVENT_BUFF_EP_EVENT_STATUS_MASK           (0x0000F000)
+
+
+#define DWC_XDCI_EVENT_BUFF_DEV_HIRD_MASK                  (0x01E00000)
+#define DWC_XDCI_EVENT_BUFF_DEV_HIRD_BIT_POS               (21)
+#define DWC_XDCI_EVENT_BUFF_DEV_SS_EVENT_MASK              (0x00100000)
+#define DWC_XDCI_EVENT_BUFF_DEV_LINK_STATE_MASK            (0x000F0000)
+#define DWC_XDCI_EVENT_BUFF_DEV_LINK_STATE_BIT_POS         (16)
+
+#define DWC_XDCI_EVENT_BUFF_DEV_EVT_MASK                   (0x00000F00)
+#define DWC_XDCI_EVENT_BUFF_DEV_EVT_BIT_POS                (8)
+#define DWC_XDCI_EVENT_BUFF_DEV_TST_LMP_RX_EVENT           (12)
+#define DWC_XDCI_EVENT_BUFF_DEV_BUFF_OVFL_EVENT            (11)
+#define DWC_XDCI_EVENT_BUFF_DEV_CMD_CMPLT_EVENT            (10)
+#define DWC_XDCI_EVENT_BUFF_DEV_ERRATIC_ERR_EVENT          (9)
+#define DWC_XDCI_EVENT_BUFF_DEV_SOF_EVENT                  (7)
+#define DWC_XDCI_EVENT_BUFF_DEV_HBRNTN_REQ_EVENT           (5)
+#define DWC_XDCI_EVENT_BUFF_DEV_WKUP_EVENT                 (4)
+#define DWC_XDCI_EVENT_BUFF_DEV_STATE_CHANGE_EVENT         (3)
+#define DWC_XDCI_EVENT_BUFF_DEV_CONN_DONE_EVENT            (2)
+#define DWC_XDCI_EVENT_BUFF_DEV_USB_RESET_EVENT            (1)
+#define DWC_XDCI_EVENT_BUFF_DEV_DISCONN_EVENT              (0)
+
+#define DWC_XDCI_EVENT_DEV_MASK                            (0x00000001)
+
+//
+// Device Status Register and Bit Definitions
+//
+#define DWC_XDCI_DSTS_REG                                  (0xC70C)
+#define DWC_XDCI_DSTS_DEV_CTRL_HALTED_MASK                 (0x00400000)
+#define DWC_XDCI_DSTS_DEV_CTRL_HALTED_BIT_POS              (22)
+#define DWC_XDCI_DSTS_CORE_IDLE                            (1 << 23)
+#define DWC_XDCI_DSTS_CONN_SPEED_MASK                      (0x00000007)
+#define DWC_XDCI_DSTS_LINK_STATE_MASK                      (0x003C0000)
+#define DWC_XDCI_DSTS_LINK_STATE_DISCONNECT                (0x00100000)
+
+//
+// Device Generic Command Parameter Register
+//
+#define DWC_XDCI_DGCMD_PARAM_REG                           (0xC710)
+#define DWC_XDCI_DGCMD_PARAM_TX_FIFO_NUM_MASK              (0x0000001F)
+#define DWC_XDCI_DGCMD_PARAM_TX_FIFO_DIR_MASK              (0x00000020)
+#define DWC_XDCI_DGCMD_PARAM_TX_FIFO_DIR_BIT_POS           (5)
+
+//
+// Device Generic Command Register
+//
+#define DWC_XDCI_DGCMD_REG                                 (0xC714)
+#define DWC_XDCI_DGCMD_CMD_STATUS_MASK                     (0x00008000)
+#define DWC_XDCI_DGCMD_CMD_ACTIVE_MASK                     (0x00000400)
+#define DWC_XDCI_DGCMD_CMD_IOC_MASK                        (0x00000100)
+#define DWC_XDCI_DGCMD_CMD_TYPE_MASK                       (0x000000FF)
+#define DWC_XDCI_DGCMD_CMD_SET_PERIODIC_PARAMS             (0x2)
+#define DWC_XDCI_DGCMD_CMD_SET_SCRATCH_PAD_BUFF_ARR_LO     (0x4)
+#define DWC_XDCI_DGCMD_CMD_SET_SCRATCH_PAD_BUFF_ARR_HI     (0x5)
+#define DWC_XDCI_DGCMD_CMD_XMIT_DEVICE_NOTIFICATION        (0x7)
+#define DWC_XDCI_DGCMD_CMD_SEL_FIFO_FLUSH                  (0x9)
+#define DWC_XDCI_DGCMD_CMD_ALL_FIFO_FLUSH                  (0xA)
+#define DWC_XDCI_DGCMD_CMD_SET_EP_NRDY                     (0xC)
+#define DWC_XDCI_DGCMD_CMD_RUN_SOC_BUS_LPBK                (0x10)
+
+//
+// Device Active USB EP Enable Register
+//
+#define DWC_XDCI_EP_DALEPENA_REG                           (0xC720)
+
+//
+// Device Physical EP CMD Param 2 Register. Value is 32-bit
+//
+#define DWC_XDCI_EPCMD_PARAM2_REG(n)                       (0xC800 + (n << 4))
+
+//
+// Device Physical EP CMD Param 1 Register. Value is 32-bit
+//
+#define DWC_XDCI_EPCMD_PARAM1_REG(n)                       (0xC804 + (n << 4))
+
+//
+// Device Physical EP CMD Param 0 Register. Value is 32-bit
+//
+#define DWC_XDCI_EPCMD_PARAM0_REG(n)                       (0xC808 + (n << 4))
+
+//
+// Device Physical EP Command Registers and Bit Definitions
+//
+#define DWC_XDCI_EPCMD_REG(n)                              (0xC80C + (n << 4))
+#define DWC_XDCI_EPCMD_RES_IDX_MASK                        (0x007F0000)
+#define DWC_XDCI_EPCMD_RES_IDX_BIT_POS                     (16)
+#define DWC_XDCI_EPCMD_CMDTYPE_MASK                        (0x0000000F)
+#define DWC_XDCI_EPCMD_SET_EP_CONFIG                       (0x1)
+#define DWC_XDCI_EPCMD_SET_EP_XFER_RES_CONFIG              (0x2)
+#define DWC_XDCI_EPCMD_GET_EP_STATE                        (0x3)
+#define DWC_XDCI_EPCMD_SET_STALL                           (0x4)
+#define DWC_XDCI_EPCMD_CLEAR_STALL                         (0x5)
+#define DWC_XDCI_EPCMD_START_XFER                          (0x6)
+#define DWC_XDCI_EPCMD_UPDATE_XFER                         (0x7)
+#define DWC_XDCI_EPCMD_END_XFER                            (0x8)
+#define DWC_XDCI_EPCMD_START_NEW_CONFIG                    (0x9)
+
+#define DWC_XDCI_EPCMD_CMD_IOC_MASK                        (0x00000100)
+#define DWC_XDCI_EPCMD_CMD_ACTIVE_MASK                     (0x00000400)
+#define DWC_XDCI_EPCMD_HIGH_PRIO_MASK                      (0x00000800)
+#define DWC_XDCI_EPCMD_FORCE_RM_MASK                       (0x00000800)
+
+//
+// Command status and parameter values same as event status and parameters values
+//
+#define DWC_XDCI_EPCMD_CMD_STATUS_MASK                     (0x0000F000)
+
+//
+// Command Params bit masks
+//
+#define DWC_XDCI_PARAM1_SET_EP_CFG_FIFO_BASED_MASK         (0x80000000)
+#define DWC_XDCI_PARAM1_SET_EP_CFG_BULK_BASED_MASK         (0x40000000)
+#define DWC_XDCI_PARAM1_SET_EP_CFG_EP_NUM_MASK             (0x3C000000)
+#define DWC_XDCI_PARAM1_SET_EP_CFG_EP_DIR_MASK             (0x02000000)
+#define DWC_XDCI_PARAM1_SET_EP_CFG_STRM_CAP_MASK           (0x01000000)
+#define DWC_XDCI_PARAM1_SET_EP_CFG_BINTM1_MASK             (0x00FF0000)
+#define DWC_XDCI_PARAM1_SET_EP_CFG_BINTM1_BIT_POS          (16)
+#define DWC_XDCI_PARAM1_SET_EP_CFG_EBC_MASK                (0x00008000)
+#define DWC_XDCI_PARAM1_SET_EP_CFG_EVT_EN_MASK             (0x00003F00)
+#define DWC_XDCI_PARAM1_SET_EP_CFG_EVT_EN_BIT_POS          (8)
+#define DWC_XDCI_PARAM1_SET_EP_CFG_EVT_STRM_MASK           (0x00002000)
+#define DWC_XDCI_PARAM1_SET_EP_CFG_EVT_XFER_NRDY_MASK      (0x00000400)
+#define DWC_XDCI_PARAM1_SET_EP_CFG_EVT_XFER_IN_PRG_MASK    (0x00000200)
+#define DWC_XDCI_PARAM1_SET_EP_CFG_EVT_XFER_CMPLT_MASK     (0x00000100)
+#define DWC_XDCI_PARAM1_SET_EP_CFG_INTR_NUM_MASK           (0x0000001F)
+
+//
+// CMD 1 param 0
+//
+#define DWC_XDCI_PARAM0_SET_EP_CFG_ACTN_MASK               (0xC0000000)
+#define DWC_XDCI_PARAM0_SET_EP_CFG_ACTN_BIT_POS            (30)
+#define DWC_XDCI_PARAM0_SET_EP_CFG_ACTN_INIT_STATE         (0)
+#define DWC_XDCI_PARAM0_SET_EP_CFG_ACTN_RESTORE_ST         (1)
+#define DWC_XDCI_PARAM0_SET_EP_CFG_ACTN_MDFY_STATE         (2)
+#define DWC_XDCI_PARAM0_SET_EP_CFG_ACTN_NONE               (3)
+#define DWC_XDCI_PARAM0_SET_EP_CFG_BRST_SIZE_MASK          (0x03C00000)
+#define DWC_XDCI_PARAM0_SET_EP_CFG_BRST_SIZE_BIT_POS       (22)
+#define DWC_XDCI_PARAM0_SET_EP_CFG_FIFO_NUM_MASK           (0x003E0000)
+#define DWC_XDCI_PARAM0_SET_EP_CFG_FIFO_NUM_BIT_POS        (17)
+#define DWC_XDCI_PARAM0_SET_EP_CFG_MPS_MASK                (0x00003FF8)
+#define DWC_XDCI_PARAM0_SET_EP_CFG_MPS_BIT_POS             (3)
+#define DWC_XDCI_PARAM0_SET_EP_CFG_EP_TYPE_MASK            (0x00000006)
+#define DWC_XDCI_PARAM0_SET_EP_CFG_EP_TYPE_BIT_POS         (1)
+#define DWC_XDCI_PARAM0_EP_TYPE_CTRL                       (0)
+#define DWC_XDCI_PARAM0_EP_TYPE_ISOCH                      (1)
+#define DWC_XDCI_PARAM0_EP_TYPE_BULK                       (2)
+#define DWC_XDCI_PARAM0_EP_TYPE_INTR                       (3)
+
+//
+// CMD 1 param 1
+//
+#define DWC_XDCI_PARAM1_SET_EP_CFG_BULK_BASED_MASK         (0x40000000)
+#define DWC_XDCI_PARAM1_SET_EP_CFG_EP_NUM_MASK             (0x3C000000)
+#define DWC_XDCI_PARAM1_SET_EP_CFG_EP_NUM_BIT_POS          (26)
+#define DWC_XDCI_PARAM1_SET_EP_CFG_EP_DIR_MASK             (0x02000000)
+#define DWC_XDCI_PARAM1_SET_EP_CFG_EP_DIR_BIT_POS          (25)
+#define DWC_XDCI_PARAM1_SET_EP_CFG_STRM_CAP_MASK           (0x01000000)
+#define DWC_XDCI_PARAM1_SET_EP_CFG_BINTM1_MASK             (0x00FF0000)
+#define DWC_XDCI_PARAM1_SET_EP_CFG_BINTM1_BIT_POS          (16)
+#define DWC_XDCI_PARAM1_SET_EP_CFG_EBC_MASK                (0x00008000)
+#define DWC_XDCI_PARAM1_SET_EP_CFG_EVT_EN_MASK             (0x00003F00)
+#define DWC_XDCI_PARAM1_SET_EP_CFG_EVT_EN_BIT_POS          (8)
+#define DWC_XDCI_PARAM1_SET_EP_CFG_EVT_STRM_MASK           (0x00002000)
+#define DWC_XDCI_PARAM1_SET_EP_CFG_EVT_XFER_NRDY_MASK      (0x00000400)
+#define DWC_XDCI_PARAM1_SET_EP_CFG_EVT_XFER_IN_PRG_MASK    (0x00000200)
+#define DWC_XDCI_PARAM1_SET_EP_CFG_EVT_XFER_CMPLT_MASK     (0x00000100)
+#define DWC_XDCI_PARAM1_SET_EP_CFG_INTR_NUM_MASK           (0x0000001F)
+
+//
+// CMD 2 param 0
+//
+#define DWC_XDCI_PARAM0_SET_EP_XFER_RES_NUM_MASK           (0x0000FFFF)
+
+//
+// CMD 3 param 2
+//
+#define DWC_XDCI_PARAM2_GET_EP_STATE_MASK                  (0xFFFFFFFF)
+
+//
+// CMD 6 param 1
+//
+#define DWC_XDCI_PARAM1_STRT_XFER_TD_ADDR_LO_MASK          (0xFFFFFFFF)
+
+//
+// CMD 6 param 0
+//
+#define DWC_XDCI_PARAM0_STRT_XFER_TD_ADDR_HI_MASK          (0xFFFFFFFF)
+
+//
+// Transfer Request Block Fields' Bit Definitions
+//
+#define DWC_XDCI_TRB_BUFF_SIZE_MASK                        (0x00FFFFFF)
+#define DWC_XDCI_TRB_PCM1_MASK                             (0x03000000)
+#define DWC_XDCI_TRB_PCM1_BIT_POS                          (24)
+#define DWC_XDCI_TRB_STATUS_MASK                           (0xF0000000)
+#define DWC_XDCI_TRB_STATUS_BIT_POS                        (28)
+#define DWC_XDCI_TRB_STATUS_OK                             (0)
+#define DWC_XDCI_TRB_STATUS_MISSED_ISOCH                   (1)
+#define DWC_XDCI_TRB_STATUS_SETUP_PENDING                  (2)
+
+#define DWC_XDCI_TRB_CTRL_HWO_MASK                         (0x00000001)
+#define DWC_XDCI_TRB_CTRL_LST_TRB_MASK                     (0x00000002)
+#define DWC_XDCI_TRB_CTRL_LST_TRB_BIT_POS                  (1)
+#define DWC_XDCI_TRB_CTRL_CHAIN_BUFF_MASK                  (0x00000004)
+#define DWC_XDCI_TRB_CTRL_CHAIN_BUFF_BIT_POS               (2)
+#define DWC_XDCI_TRB_CTRL_CSP_MASK                         (0x00000008)
+#define DWC_XDCI_TRB_CTRL_CSP_BIT_POS                      (3)
+#define DWC_XDCI_TRB_CTRL_TYPE_MASK                        (0x000003F0)
+#define DWC_XDCI_TRB_CTRL_TYPE_BIT_POS                     (4)
+#define DWC_XDCI_TRB_CTRL_TYPE_NORMAL                      (1)
+#define DWC_XDCI_TRB_CTRL_TYPE_SETUP                       (2)
+#define DWC_XDCI_TRB_CTRL_TYPE_STATUS2                     (3)
+#define DWC_XDCI_TRB_CTRL_TYPE_STATUS3                     (4)
+#define DWC_XDCI_TRB_CTRL_TYPE_DATA                        (5)
+#define DWC_XDCI_TRB_CTRL_TYPE_ISOCH_FIRST                 (6)
+#define DWC_XDCI_TRB_CTRL_TYPE_ISOCH                       (7)
+#define DWC_XDCI_TRB_CTRL_TYPE_LINK_TRB                    (8)
+#define DWC_XDCI_TRB_CTRL_IOSP_MISOCH_MASK                 (0x00000400)
+#define DWC_XDCI_TRB_CTRL_IOSP_MISOCH_BIT_POS              (10)
+#define DWC_XDCI_TRB_CTRL_IOC_MASK                         (0x00000800)
+#define DWC_XDCI_TRB_CTRL_IOC_BIT_POS                      (11)
+#define DWC_XDCI_TRB_CTRL_STRM_ID_SOF_NUM_MASK             (0x3FFFC000)
+#define DWC_XDCI_TRB_CTRL_STRM_ID_SOF_BIT_POS              (14)
+
+#define DWC_XDCI_DEV_EVENT_DEFAULT_SIZE_IN_BYTES           (4)
+#define DWC_XDCI_DEV_EVENT_TST_LMP_SIZE_IN_BYTES           (12)
+
+typedef enum {
+  EPCMD_SET_EP_CONFIG = 1,
+  EPCMD_SET_EP_XFER_RES_CONFIG,
+  EPCMD_GET_EP_STATE,
+  EPCMD_SET_STALL,
+  EPCMD_CLEAR_STALL,
+  EPCMD_START_XFER,
+  EPCMD_UPDATE_XFER,
+  EPCMD_END_XFER,
+  EPCMD_START_NEW_CONFIG = 9
+} DWC_XDCI_ENDPOINT_CMD;
+
+typedef enum {
+  ON = 0,
+  SLEEP = 2,
+  SUSPEND,
+  DISCONNECTED,
+  EARLY_SUSPEND,
+  RESET = 14,
+  RESUME = 15
+} DWC_XDCI_HS_LINK_STATE;
+
+typedef enum {
+  TRBCTL_NORMAL = 1,
+  TRBCTL_SETUP,
+  TRBCTL_2_PHASE,
+  TRBCTL_3_PHASE,
+  TRBCTL_CTRL_DATA_PHASE,
+  TRBCTL_ISOCH_FIRST,
+  TRBCTL_ISOCH,
+  TRBCTL_LINK
+} DWC_XDCI_TRB_CONTROL;
+
+//
+// DWC XDCI Endpoint Commands Parameters struct
+//
+typedef struct {
+  UINT32 Param2;
+  UINT32 Param1;
+  UINT32 Param0;
+} DWC_XDCI_ENDPOINT_CMD_PARAMS;
+
+//
+// Event Buffer Struct
+//
+typedef struct {
+  UINT32 Event;
+  UINT32 DevTstLmp1;
+  UINT32 DevTstLmp2;
+  UINT32 Reserved;
+} DWC_XDCI_EVENT_BUFFER;
+
+//
+// Transfer Request Block
+//
+typedef struct {
+  UINT32 BuffPtrLow;
+  UINT32 BuffPtrHigh;
+  UINT32 LenXferParams;
+  UINT32 TrbCtrl;
+} DWC_XDCI_TRB;
+
+typedef struct  {
+  USB_EP_INFO       EpInfo;
+  DWC_XDCI_TRB      *Trb;
+  USB_XFER_REQUEST  XferHandle;
+  UINT32            CurrentXferRscIdx;
+  VOID              *CoreHandle;
+  USB_EP_STATE      State;
+  USB_EP_STATE      OrgState;
+  BOOLEAN           CheckFlag;
+} DWC_XDCI_ENDPOINT;
+
+typedef struct {
+  //
+  // CbEventParams must be copied over by upper layer if
+  // it defers event processing
+  //
+  USB_DEVICE_CALLBACK_PARAM CbEventParams;
+
+  //
+  // Callback function list
+  //
+  USB_DEVICE_CALLBACK_FUNC  DevDisconnectCallback;
+  USB_DEVICE_CALLBACK_FUNC  DevBusResetCallback;
+  USB_DEVICE_CALLBACK_FUNC  DevResetDoneCallback;
+  USB_DEVICE_CALLBACK_FUNC  DevLinkStateCallback;
+  USB_DEVICE_CALLBACK_FUNC  DevWakeupCallback;
+  USB_DEVICE_CALLBACK_FUNC  DevHibernationCallback;
+  USB_DEVICE_CALLBACK_FUNC  DevSofCallback;
+  USB_DEVICE_CALLBACK_FUNC  DevErraticErrCallback;
+  USB_DEVICE_CALLBACK_FUNC  DevCmdCmpltCallback;
+  USB_DEVICE_CALLBACK_FUNC  DevBuffOvflwCallback;
+  USB_DEVICE_CALLBACK_FUNC  DevTestLmpRxCallback;
+  USB_DEVICE_CALLBACK_FUNC  DevSetupPktReceivedCallback;
+  USB_DEVICE_CALLBACK_FUNC  DevXferNrdyCallback;
+  USB_DEVICE_CALLBACK_FUNC  DevXferDoneCallback;
+} USB_DEV_CALLBACK_LIST;
+
+typedef struct {
+  VOID                     *ParentHandle;                                       // Pointer to the parent this driver is associated
+  USB_CONTROLLER_ID        Id;                                                  // ID of the controllers supported in our DCD
+  USB_SPEED                DesiredSpeed;                                        // Desired SS, HS, FS or LS Speeds for the core
+  USB_ROLE                 Role;                                                // Desired role i.e. host, Device or OTG
+  USB_SPEED                ActualSpeed;                                         // Actual Speed
+  USB_DEVICE_STATE         DevState;                                            // Device state
+  UINT32                   BaseAddress;                                         // Register Base address
+  UINT32                   Flags;                                               // Init flags
+  UINT32                   MaxDevIntLines;                                      // One event Buffer per interrupt line
+  DWC_XDCI_EVENT_BUFFER    EventBuffers [DWC_XDCI_MAX_EVENTS_PER_BUFFER * 2];   // Event Buffer pool
+  DWC_XDCI_EVENT_BUFFER    *AlignedEventBuffers;                                // Aligned event Buffer pool
+  DWC_XDCI_EVENT_BUFFER    *CurrentEventBuffer;                                 // Current event Buffer address
+  DWC_XDCI_TRB             UnalignedTrbs [(DWC_XDCI_MAX_ENDPOINTS + 1) * DWC_XDCI_TRB_NUM];    // TRBs.
+  DWC_XDCI_TRB             *Trbs;                                               // 16-bytes aligned TRBs.
+  DWC_XDCI_ENDPOINT        EpHandles [DWC_XDCI_MAX_ENDPOINTS];                  // EPs
+  UINT8                    DefaultSetupBuffer [DWC_XDCI_SETUP_BUFF_SIZE * 2];   // Unaligned setup Buffer
+  UINT8                    *AlignedSetupBuffer;                                 // Aligned setup Buffer. Aligned to 8-byte boundary
+  UINT8                    MiscBuffer [528];                                    // Unaligned misc Buffer
+  UINT8                    *AlignedMiscBuffer;                                  // Aligned misc Buffer
+  UINT32                   LinkState;                                           // Link state
+  UINT32                   HirdVal;                                             // HIRD value
+  USB_DEV_CALLBACK_LIST    EventCallbacks;
+  volatile BOOLEAN         InterrupProcessing;
+} XDCI_CORE_HANDLE;
+
+//
+// DWC XDCI API prototypes
+//
+EFI_STATUS
+EFIAPI
+DwcXdciCoreInit (
+  IN USB_DEV_CONFIG_PARAMS    *ConfigParams,
+  IN VOID                     *ParentHandle,
+  IN VOID                     **CoreHandle
+  );
+
+EFI_STATUS
+EFIAPI
+DwcXdciCoreDeinit (
+  IN VOID      *CoreHandle,
+  IN UINT32    flags
+  );
+
+EFI_STATUS
+EFIAPI
+DwcXdciCoreRegisterCallback (
+  IN VOID                      *CoreHandle,
+  IN USB_DEVICE_EVENT_ID       Event,
+  IN USB_DEVICE_CALLBACK_FUNC  CallbackFunc
+  );
+
+EFI_STATUS
+EFIAPI
+DwcXdciCoreUnregisterCallback (
+  IN VOID                   *CoreHandle,
+  IN USB_DEVICE_EVENT_ID    Event
+  );
+
+EFI_STATUS
+EFIAPI
+DwcXdciCoreIsrRoutine (
+  IN VOID *CoreHandle
+  );
+
+EFI_STATUS
+EFIAPI
+DwcXdciCoreIsrRoutineTimerBased (
+  IN VOID *CoreHandle
+  );
+
+EFI_STATUS
+EFIAPI
+DwcXdciCoreConnect (
+  IN VOID    *CoreHandle
+  );
+
+EFI_STATUS
+EFIAPI
+DwcXdciCoreDisconnect (
+  IN VOID *CoreHandle
+  );
+
+EFI_STATUS
+EFIAPI
+DwcXdciCoreGetSpeed (
+  IN VOID         *CoreHandle,
+  IN USB_SPEED    *Speed
+  );
+
+EFI_STATUS
+EFIAPI
+DwcXdciCoreSetAddress (
+  IN VOID      *CoreHandle,
+  IN UINT32    Address
+  );
+
+EFI_STATUS
+EFIAPI
+DwcXdciCoreSetConfig (
+  IN VOID      *CoreHandle,
+  IN UINT32    ConfigNum
+  );
+
+EFI_STATUS
+EFIAPI
+DwcXdciSetLinkState (
+  IN VOID                        *CoreHandle,
+  IN USB_DEVICE_SS_LINK_STATE    State
+  );
+
+EFI_STATUS
+EFIAPI
+DwcXdciInitEp (
+  IN VOID           *CoreHandle,
+  IN USB_EP_INFO    *EpInfo
+  );
+
+EFI_STATUS
+EFIAPI
+DwcXdciEpEnable (
+  IN VOID           *CoreHandle,
+  IN USB_EP_INFO    *EpInfo
+  );
+
+EFI_STATUS
+EFIAPI
+DwcXdciEpDisable (
+  IN VOID           *CoreHandle,
+  IN USB_EP_INFO    *EpInfo
+  );
+
+EFI_STATUS
+EFIAPI
+DwcXdciEpStall (
+  IN VOID           *CoreHandle,
+  IN USB_EP_INFO    *EpInfo
+  );
+
+EFI_STATUS
+EFIAPI
+DwcXdciEpClearStall (
+  IN VOID           *CoreHandle,
+  IN USB_EP_INFO    *EpInfo
+  );
+
+EFI_STATUS
+EFIAPI
+DwcXdciEpSetNrdy (
+  IN VOID           *CoreHandle,
+  IN USB_EP_INFO    *EpInfo
+  );
+
+EFI_STATUS
+EFIAPI
+DwcXdciEp0ReceiveSetupPkt (
+  IN VOID     *CoreHandle,
+  IN UINT8    *Buffer
+  );
+
+EFI_STATUS
+EFIAPI
+DwcXdciEp0ReceiveStatusPkt (
+  IN VOID    *CoreHandle
+  );
+
+EFI_STATUS
+EFIAPI
+DwcXdciEp0SendStatusPkt (
+  IN VOID    *CoreHandle
+  );
+
+EFI_STATUS
+EFIAPI
+DwcXdciEpTxData (
+  IN VOID                *CoreHandle,
+  IN USB_XFER_REQUEST    *XferReq
+  );
+
+EFI_STATUS
+EFIAPI
+DwcXdciEpRxData(
+  IN VOID                *CoreHandle,
+  IN USB_XFER_REQUEST    *XferReq
+  );
+
+EFI_STATUS
+EFIAPI
+DwcXdciEpCancelTransfer (
+  IN VOID           *CoreHandle,
+  IN USB_EP_INFO    *EpInfo
+  );
+
+EFI_STATUS
+usbProcessDeviceResetDet (
+  IN XDCI_CORE_HANDLE    *CoreHandle
+  );
+
+EFI_STATUS
+usbProcessDeviceResetDone (
+  IN XDCI_CORE_HANDLE    *CoreHandle
+  );
+
+UINT32
+UsbGetPhysicalEpNum (
+  IN UINT32        EndpointNum,
+  IN USB_EP_DIR    EndpointDir
+  );
+
+UINT32
+UsbRegRead (
+  IN UINT32    Base,
+  IN UINT32    Offset
+  );
+
+VOID
+UsbRegWrite (
+  IN UINT32    Base,
+  IN UINT32    Offset,
+  IN UINT32    val
+  );
+
+EFI_STATUS
+UsbXdciCoreFlushEpFifo (
+  IN VOID           *CoreHandle,
+  IN USB_EP_INFO    *EpInfo
+  );
+#endif
+
diff --git a/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciDevice.c b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciDevice.c
new file mode 100644
index 0000000000..7c94de0a60
--- /dev/null
+++ b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciDevice.c
@@ -0,0 +1,695 @@
+/** @file
+  Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR>
+
+  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.
+
+**/
+
+#include <Library/UsbDeviceLib.h>
+#include "XdciCommon.h"
+#include "XdciDevice.h"
+#include "XdciInterface.h"
+#include "UsbDeviceMode.h"
+
+/**
+  This function is used to initialize the device controller
+  @configParams: Parameters from app to configure the core
+  @DevCoreHandle: Return parameter for upper layers to use
+  for all HW-independent APIs
+
+**/
+EFI_STATUS
+UsbDeviceInit (
+  IN USB_DEV_CONFIG_PARAMS    *ConfigParams,
+  IN OUT VOID                 **DevCoreHandle
+  )
+{
+  USB_DEV_CORE    *DevCorePtr;
+  EFI_STATUS      Status = EFI_INVALID_PARAMETER;
+
+  DEBUG ((DEBUG_INFO, "Call UsbDeviceInit start\n"));
+
+  //
+  // Allocate device handle
+  //
+  DevCorePtr = AllocateZeroPool (sizeof (USB_DEV_CORE));
+  DEBUG ((DEBUG_INFO, "device handle = 0x%x\n", DevCorePtr));
+
+  if (DevCorePtr == NULL) {
+    DEBUG ((DEBUG_INFO, "UsbDeviceInit. ERROR: Failed to allocate memory\n"));
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  DEBUG ((DEBUG_INFO, "call UsbDeviceGetCoreDriver, ID=%x, \n", ConfigParams->ControllerId));
+
+  //
+  // Get the driver for this USB device core
+  //
+  DevCorePtr->CoreDriver = UsbDeviceGetCoreDriver(ConfigParams->ControllerId);
+  if (DevCorePtr->CoreDriver != NULL) {
+    DEBUG ((DEBUG_INFO, "call DevCoreInit\n"));
+    Status = DevCorePtr->CoreDriver->DevCoreInit(
+                                        ConfigParams,
+                                        (VOID*)DevCorePtr,
+                                        &DevCorePtr->ControllerHandle);
+  } else {
+    DEBUG ((DEBUG_INFO, "UsbDeviceInit. ERROR: Driver not found\n"));
+    return EFI_INVALID_PARAMETER;
+  }
+
+  *DevCoreHandle = (VOID *)DevCorePtr;
+  return Status;
+}
+
+/**
+  This function is used to de-initialize the device controller
+  @DevCoreHandle: Handle to HW-independent APIs for device
+  controller
+  @flags: Flags indicating what type of de-initialization is required
+
+**/
+EFI_STATUS
+UsbDeviceDeinit (
+  IN VOID      *DevCoreHandle,
+  IN UINT32    Flags
+  )
+{
+  USB_DEV_CORE    *Core = (USB_DEV_CORE *)DevCoreHandle;
+  EFI_STATUS      Status = EFI_DEVICE_ERROR;
+
+  if (Core == NULL) {
+    DEBUG ((DEBUG_INFO, "UsbDeviceDeinit: ERROR: INVALID HANDLE\n"));
+  } else {
+    if (Core->CoreDriver != NULL) {
+      Status = Core->CoreDriver->DevCoreDeinit(
+                                    Core->ControllerHandle,
+                                    Flags
+                                    );
+      FreePool(DevCoreHandle);
+    } else {
+      DEBUG ((DEBUG_INFO, "UsbDeviceDeinit: Driver not found\n"));
+      Status = EFI_INVALID_PARAMETER;
+    }
+  }
+
+  return Status;
+}
+
+/**
+  This function is used to register callback function for
+  specified event
+  @DevCoreHandle: Handle to HW-independent APIs for device
+  controller
+  @event: Event for which callback is to be registered
+  @callbackFn: Callback function to be called by the
+  controller driver for above event after critical processing
+
+**/
+EFI_STATUS
+UsbDeviceRegisterCallback (
+  IN VOID                      *DevCoreHandle,
+  IN USB_DEVICE_EVENT_ID       EventId,
+  IN USB_DEVICE_CALLBACK_FUNC  CallbackFunc
+  )
+{
+  EFI_STATUS    Status = EFI_DEVICE_ERROR;
+  USB_DEV_CORE  *core = (USB_DEV_CORE *)DevCoreHandle;
+
+  DEBUG ((DEBUG_INFO, "UsbDeviceRegisterCallback start\n"));
+
+  if (core == NULL) {
+    DEBUG ((DEBUG_INFO, "UsbDeviceRegisterCallback: ERROR: INVALID HANDLE\n"));
+  } else {
+    if (core->CoreDriver != NULL) {
+      DEBUG ((DEBUG_INFO, "Call DevCoreRegisterCallback\n"));
+      Status = core->CoreDriver->DevCoreRegisterCallback (
+                                    core->ControllerHandle,
+                                    EventId,
+                                    CallbackFunc
+                                    );
+    }
+  }
+
+  return Status;
+}
+
+/**
+  This function is used to register callback function for
+  specified event
+  @DevCoreHandle: Handle to HW-independent APIs for device
+  controller
+  @eventId: Event for which callback is to be unregistered
+
+**/
+EFI_STATUS
+UsbDeviceUnregisterCallback (
+  IN VOID                      *DevCoreHandle,
+  IN USB_DEVICE_EVENT_ID       EventId
+  )
+{
+  EFI_STATUS    Status = EFI_DEVICE_ERROR;
+  USB_DEV_CORE  *core = (USB_DEV_CORE *)DevCoreHandle;
+
+  if (core == NULL) {
+    DEBUG ((DEBUG_INFO, "UsbDeviceUnregisterCallback: ERROR: INVALID HANDLE\n"));
+  } else {
+    if (core->CoreDriver != NULL) {
+      Status = core->CoreDriver->DevCoreUnregisterCallback(
+                                    core->ControllerHandle,
+                                    EventId
+                                    );
+    }
+  }
+
+  return Status;
+}
+
+/**
+  This function is used to service interrupt events on device
+  controller. Use this API in your OS/stack-specific ISR framework
+  In polled mode scenario, invoke this API in a loop to service the
+  events
+  @DevCoreHandle: Handle to HW-independent APIs for device
+  controller
+
+**/
+EFI_STATUS
+UsbDeviceIsrRoutine (
+  IN VOID                      *DevCoreHandle
+  )
+{
+  USB_DEV_CORE  *core = (USB_DEV_CORE *)DevCoreHandle;
+  EFI_STATUS    Status = EFI_DEVICE_ERROR;
+
+  if (core == NULL) {
+    DEBUG ((DEBUG_INFO, "UsbDeviceIsrRoutine: ERROR: INVALID HANDLE\n"));
+  } else {
+    if (core->CoreDriver != NULL) {
+      Status = core->CoreDriver->DevCoreIsrRoutine (core->ControllerHandle);
+    }
+  }
+
+  return Status;
+}
+
+
+/**
+  This function is used to service interrupt events on device
+  controller. Use this API in your OS/stack-specific ISR framework
+  In polled mode scenario, invoke this API in a loop to service the
+  events
+  @DevCoreHandle: Handle to HW-independent APIs for device
+  controller
+
+**/
+EFI_STATUS
+UsbDeviceIsrRoutineTimerBased (
+  IN VOID                      *DevCoreHandle
+  )
+{
+  USB_DEV_CORE  *core = (USB_DEV_CORE *)DevCoreHandle;
+  EFI_STATUS    Status = EFI_DEVICE_ERROR;
+
+  if (core == NULL) {
+    DEBUG ((DEBUG_INFO, "UsbDeviceIsrRoutine: ERROR: INVALID HANDLE\n"));
+  } else {
+    if (core->CoreDriver != NULL) {
+      Status = core->CoreDriver->DevCoreIsrRoutineTimerBased (core->ControllerHandle);
+    }
+  }
+
+  return Status;
+}
+
+
+/**
+  This function is used to enable device controller to connect
+  to USB host
+  @DevCoreHandle: Handle to HW-independent APIs for device
+  controller
+
+**/
+EFI_STATUS
+UsbXdciDeviceConnect (
+  IN VOID                      *DevCoreHandle
+  )
+{
+  USB_DEV_CORE  *core = (USB_DEV_CORE *)DevCoreHandle;
+  EFI_STATUS    Status = EFI_DEVICE_ERROR;
+
+  if (core == NULL) {
+    DEBUG ((DEBUG_INFO, "UsbXdciDeviceConnect: ERROR: INVALID HANDLE\n"));
+  } else {
+    DEBUG ((DEBUG_INFO, "UsbXdciDeviceConnect\n"));
+    Status = core->CoreDriver->DevCoreConnect (core->ControllerHandle);
+  }
+
+  return Status;
+}
+
+/**
+  This function is used to disconnect device controller
+  from USB host
+  @DevCoreHandle: Handle to HW-independent APIs for device
+  controller
+
+**/
+EFI_STATUS
+UsbDeviceDisconnect (
+  IN VOID                      *DevCoreHandle
+  )
+{
+  USB_DEV_CORE  *core =(USB_DEV_CORE *)DevCoreHandle;
+  EFI_STATUS    Status = EFI_DEVICE_ERROR;
+
+  if (core == NULL) {
+    DEBUG ((DEBUG_INFO, "UsbDeviceDisconnect: ERROR: INVALID HANDLE\n"));
+  } else {
+    DEBUG ((DEBUG_INFO, "UsbDeviceDisconnect\n"));
+    Status = core->CoreDriver->DevCoreDisconnect(core->ControllerHandle);
+  }
+
+  return Status;
+}
+
+/**
+  This function is used to obtain USB bus Speed after bus reset complete
+  @DevCoreHandle: Handle to HW-independent APIs for device
+  controller
+  @Speed: negotiated Speed
+
+**/
+EFI_STATUS
+UsbDeviceGetSpeed (
+  IN VOID                      *DevCoreHandle,
+  IN USB_SPEED                 *Speed
+  )
+{
+  USB_DEV_CORE  *core = (USB_DEV_CORE *)DevCoreHandle;
+  EFI_STATUS    Status = EFI_DEVICE_ERROR;
+
+  if (core == NULL) {
+    DEBUG ((DEBUG_INFO, "UsbDeviceGetSpeed: ERROR: INVALID HANDLE\n"));
+  } else {
+    Status = core->CoreDriver->DevCoreGetSpeed(core->ControllerHandle, Speed);
+  }
+
+  return Status;
+}
+
+/**
+  This function is used to set USB device address
+  @DevCoreHandle: Handle to HW-independent APIs for device
+  controller
+  @address: USB device address to set
+
+**/
+EFI_STATUS
+UsbDeviceSetAddress (
+  IN VOID                      *DevCoreHandle,
+  IN UINT32                    Address
+  )
+{
+  USB_DEV_CORE  *core = (USB_DEV_CORE *)DevCoreHandle;
+  EFI_STATUS    Status = EFI_DEVICE_ERROR;
+
+  DEBUG ((DEBUG_INFO, "UsbDeviceSetAddress: enter......\n"));
+  if (core == NULL) {
+    DEBUG ((DEBUG_INFO, "UsbDeviceSetAddress: ERROR: INVALID HANDLE\n"));
+  } else {
+    Status = core->CoreDriver->DevCoreSetAddress(core->ControllerHandle, Address);
+  }
+  DEBUG ((DEBUG_INFO, "UsbDeviceSetAddress: exit......\n"));
+
+  return Status;
+}
+
+/**
+  This function is used to do device controller-specific processing
+  of set configuration device framework request
+  @DevCoreHandle: Handle to HW-independent APIs for device
+  controller
+  @ConfigNum: configuration number selected by USB host
+
+**/
+EFI_STATUS
+UsbDeviceSetConfiguration (
+  IN VOID                      *DevCoreHandle,
+  IN UINT32                    ConfigNum
+  )
+{
+  USB_DEV_CORE  *core = (USB_DEV_CORE *)DevCoreHandle;
+  EFI_STATUS    Status = EFI_DEVICE_ERROR;
+
+  if (core == NULL) {
+    DEBUG ((DEBUG_INFO, "UsbDeviceSetConfiguration: ERROR: INVALID HANDLE\n"));
+  } else {
+    Status = core->CoreDriver->DevCoreSetConfig (core->ControllerHandle, ConfigNum);
+  }
+
+  return Status;
+}
+
+/**
+  This function is used to set desired link state in device controller
+  @DevCoreHandle: Handle to HW-independent APIs for device
+  controller
+  @state: Desired link state
+
+**/
+EFI_STATUS
+UsbDeviceSetLinkState (
+  IN VOID                      *DevCoreHandle,
+  IN USB_DEVICE_SS_LINK_STATE  State
+  )
+{
+  USB_DEV_CORE  *core = (USB_DEV_CORE *)DevCoreHandle;
+  EFI_STATUS    Status = EFI_DEVICE_ERROR;
+
+  if (core == NULL) {
+    DEBUG ((DEBUG_INFO, "UsbDeviceSetLinkState: ERROR: INVALID HANDLE\n"));
+  } else {
+    Status = core->CoreDriver->DevCoreSetLinkState (core->ControllerHandle, State);
+  }
+
+  return Status;
+}
+
+/**
+  This function is used to initialize non-EP0 endpoints
+  @DevCoreHandle: Handle to HW-independent APIs for device
+  controller
+  @EpInfo: Endpoint information for EP to be initialized
+
+**/
+EFI_STATUS
+UsbDeviceInitEp (
+  IN VOID                      *DevCoreHandle,
+  IN USB_EP_INFO               *EpInfo
+  )
+{
+  USB_DEV_CORE  *core = (USB_DEV_CORE *)DevCoreHandle;
+  EFI_STATUS    Status = EFI_DEVICE_ERROR;
+
+  if (core == NULL) {
+    DEBUG ((DEBUG_INFO, "UsbDeviceInitEp: ERROR: INVALID HANDLE\n"));
+  } else {
+    Status = core->CoreDriver->DevCoreInitEp (core->ControllerHandle, EpInfo);
+  }
+
+  return Status;
+}
+
+/**
+  This function is used to enable an endpoint
+  @DevCoreHandle: Handle to HW-independent APIs for device
+  controller
+  @EpInfo: Endpoint information for EP to be enabled
+
+**/
+EFI_STATUS
+UsbDeviceEpEnable (
+  IN VOID                      *DevCoreHandle,
+  IN USB_EP_INFO               *EpInfo
+  )
+{
+  USB_DEV_CORE  *core = (USB_DEV_CORE *)DevCoreHandle;
+  EFI_STATUS    Status = EFI_DEVICE_ERROR;
+
+  if (core == NULL) {
+    DEBUG ((DEBUG_INFO, "UsbDeviceEpEnable: ERROR: INVALID HANDLE\n"));
+  } else {
+    Status = core->CoreDriver->DevCoreEpEnable (core->ControllerHandle, EpInfo);
+  }
+
+  return Status;
+}
+
+/**
+  This function is used to disable an endpoint
+  @DevCoreHandle: Handle to HW-independent APIs for device
+  controller
+  @EpInfo: Endpoint information for EP to be disabled
+
+**/
+EFI_STATUS
+UsbDeviceEpDisable (
+  IN VOID                      *DevCoreHandle,
+  IN USB_EP_INFO               *EpInfo
+  )
+{
+  USB_DEV_CORE  *core = (USB_DEV_CORE *)DevCoreHandle;
+  EFI_STATUS    Status = EFI_DEVICE_ERROR;
+
+  if (core == NULL) {
+    DEBUG ((DEBUG_INFO, "UsbDeviceEpDisable ERROR: INVALID HANDLE\n"));
+  } else {
+    Status = core->CoreDriver->DevCoreEpDisable (core->ControllerHandle, EpInfo);
+  }
+
+  return Status;
+}
+
+/**
+  This function is used to STALL an endpoint
+  @DevCoreHandle: Handle to HW-independent APIs for device
+  controller
+  @EpInfo: Endpoint information for EP to be stalled
+
+**/
+EFI_STATUS
+UsbDeviceEpStall (
+  IN VOID                      *DevCoreHandle,
+  IN USB_EP_INFO               *EpInfo
+  )
+{
+  USB_DEV_CORE  *core = (USB_DEV_CORE *)DevCoreHandle;
+  EFI_STATUS    Status = EFI_DEVICE_ERROR;
+
+  if (core == NULL) {
+    DEBUG ((DEBUG_INFO, "UsbDeviceEpStall ERROR: INVALID HANDLE\n"));
+  } else {
+    Status = core->CoreDriver->DevCoreEpStall (core->ControllerHandle, EpInfo);
+  }
+
+  return Status;
+}
+
+/**
+  This function is used to clear STALL on an endpoint
+  @DevCoreHandle: Handle to HW-independent APIs for device
+  controller
+  @EpInfo: Endpoint information for which STALL needs to be cleared
+
+**/
+EFI_STATUS
+UsbDeviceEpClearStall (
+  IN VOID                      *DevCoreHandle,
+  IN USB_EP_INFO               *EpInfo
+  )
+{
+  USB_DEV_CORE  *core = (USB_DEV_CORE *)DevCoreHandle;
+  EFI_STATUS    Status = EFI_DEVICE_ERROR;
+
+  if (core == NULL) {
+    DEBUG ((DEBUG_INFO, "UsbDeviceEpClearStall ERROR: INVALID HANDLE\n"));
+  } else {
+    Status = core->CoreDriver->DevCoreEpClearStall (core->ControllerHandle, EpInfo);
+  }
+
+  return Status;
+}
+
+/**
+  This function is used to set EP not ready state
+  @DevCoreHandle: Handle to HW-independent APIs for device
+  controller
+  @EpInfo: Endpoint information for EP that needs to be
+  set in not ready state
+
+**/
+EFI_STATUS
+UsbDeviceEpSetNrdy (
+  IN VOID                      *DevCoreHandle,
+  IN USB_EP_INFO               *EpInfo
+  )
+{
+  USB_DEV_CORE  *core = (USB_DEV_CORE *)DevCoreHandle;
+  EFI_STATUS    Status = EFI_DEVICE_ERROR;
+
+  if (core == NULL) {
+    DEBUG ((DEBUG_INFO, "UsbDeviceEpSetNrdy ERROR: INVALID HANDLE\n"));
+  } else {
+    Status = core->CoreDriver->DevCoreEpSetNrdy (core->ControllerHandle, EpInfo);
+  }
+
+  return Status;
+}
+
+/**
+  This function is used to queue request to receive SETUP packet
+  @DevCoreHandle: Handle to HW-independent APIs for device
+  controller
+  @Buffer: Buffer (bus-width aligned) where SETUP packet
+  needs to be received
+
+**/
+EFI_STATUS
+UsbDeviceEp0RxSetup (
+  IN VOID                      *DevCoreHandle,
+  IN UINT8                     *Buffer
+  )
+{
+  USB_DEV_CORE  *core = (USB_DEV_CORE *)DevCoreHandle;
+  EFI_STATUS    Status = EFI_DEVICE_ERROR;
+
+  if (core == NULL) {
+    DEBUG ((DEBUG_INFO, "UsbDeviceEp0RxSetup ERROR: INVALID HANDLE\n"));
+  } else {
+    Status = core->CoreDriver->DevCoreEp0RxSetupPkt (core->ControllerHandle, Buffer);
+  }
+
+  return Status;
+}
+
+/**
+  This function is used to queue request to receive status phase
+  for control transfer on EP0
+  @DevCoreHandle: Handle to HW-independent APIs for device
+  controller
+
+**/
+EFI_STATUS
+UsbDeviceEp0RxStatus (
+  IN VOID                      *DevCoreHandle
+  )
+{
+  USB_DEV_CORE  *core = (USB_DEV_CORE *)DevCoreHandle;
+  EFI_STATUS    Status = EFI_DEVICE_ERROR;
+
+  if (core == NULL) {
+    DEBUG ((DEBUG_INFO, "UsbDeviceEp0RxStatus ERROR: INVALID HANDLE\n"));
+  } else {
+    Status = core->CoreDriver->DevCoreEp0RxStatusPkt (core->ControllerHandle);
+  }
+  return Status;
+}
+
+/**
+  This function is used to queue request to send status phase for
+  control transfer on EP0
+  @DevCoreHandle: Handle to HW-independent APIs for device
+  controller
+
+**/
+EFI_STATUS
+UsbDeviceEp0TxStatus (
+  IN VOID                      *DevCoreHandle
+  )
+{
+  USB_DEV_CORE  *core = (USB_DEV_CORE *)DevCoreHandle;
+  EFI_STATUS    Status = EFI_DEVICE_ERROR;
+
+  if (core == NULL) {
+    DEBUG ((DEBUG_INFO, "UsbDeviceEp0TxStatus ERROR: INVALID HANDLE\n"));
+  } else {
+    Status = core->CoreDriver->DevCoreEp0TxStatusPkt (core->ControllerHandle);
+  }
+
+  return Status;
+}
+
+/**
+  This function is used to queue a single request to transmit data on
+  an endpoint. If more than one request need to be queued before
+  previous requests complete then a request queue needs to be
+  implemented in upper layers. This API should be not be invoked until
+  current request completes.
+  Callback for transfer completion is invoked when requested transfer length
+  is reached or if a short packet is received
+  @DevCoreHandle: Handle to HW-independent APIs for device
+  controller
+  @XferReq: Address to transfer request describing this transfer
+
+**/
+EFI_STATUS
+UsbXdciDeviceEpTxData (
+  IN VOID                      *DevCoreHandle,
+  IN USB_XFER_REQUEST          *XferReq
+  )
+{
+  USB_DEV_CORE  *core = (USB_DEV_CORE *)DevCoreHandle;
+  EFI_STATUS    Status = EFI_DEVICE_ERROR;
+
+  if (core == NULL) {
+    DEBUG ((DEBUG_INFO, "UsbXdciDeviceEpTxData ERROR: INVALID HANDLE\n"));
+  } else {
+    Status = core->CoreDriver->DevCoreEpTxData (core->ControllerHandle, XferReq);
+  }
+
+  return Status;
+}
+
+/**
+  This function is used to queue a single request to receive data on
+  an endpoint. If more than one request need to be queued before
+  previous requests complete then a request queue needs to be implemented
+  in upper layers. This API should be not be invoked until current request
+  completes.
+  Callback for transfer completion is invoked when requested transfer length
+  is reached or if a short packet is received
+  @DevCoreHandle: Handle to HW-independent APIs for device
+  controller
+  @XferReq: Address to transfer request describing this transfer
+
+**/
+EFI_STATUS
+UsbXdciDeviceEpRxData (
+  IN VOID                      *DevCoreHandle,
+  IN USB_XFER_REQUEST          *XferReq
+  )
+{
+  USB_DEV_CORE  *core = (USB_DEV_CORE *)DevCoreHandle;
+  EFI_STATUS    Status = EFI_DEVICE_ERROR;
+
+  if (core == NULL) {
+    DEBUG ((DEBUG_INFO, "UsbXdciDeviceEpRxData ERROR: INVALID HANDLE\n"));
+  } else {
+    Status = core->CoreDriver->DevCoreEpRxData (core->ControllerHandle, XferReq);
+  }
+
+  return Status;
+}
+
+/**
+  This function is used to cancel a transfer request that was
+  previously queued on an endpoint
+  @DevCoreHandle: Handle to HW-independent APIs for device
+  controller
+  @EpInfo: Endpoint info where transfer needs to be cancelled
+
+**/
+EFI_STATUS
+UsbDeviceEpCancelTransfer (
+  IN VOID                      *DevCoreHandle,
+  IN USB_EP_INFO               *EpInfo
+  )
+{
+  USB_DEV_CORE  *core = (USB_DEV_CORE *)DevCoreHandle;
+  EFI_STATUS    Status = EFI_DEVICE_ERROR;
+
+  if (core == NULL) {
+    DEBUG ((DEBUG_INFO, "UsbDeviceEpCancelTransfer ERROR: INVALID HANDLE\n"));
+  } else {
+    Status = core->CoreDriver->DevCoreEpCancelTransfer (core->ControllerHandle, EpInfo);
+  }
+
+  return Status;
+}
+
diff --git a/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciDevice.h b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciDevice.h
new file mode 100644
index 0000000000..a10ec61732
--- /dev/null
+++ b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciDevice.h
@@ -0,0 +1,184 @@
+/** @file
+  Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR>
+
+  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.
+
+**/
+
+#ifndef _USB_DEVICE_H_
+#define _USB_DEVICE_H_
+
+//
+// @USB_DEV_CONFIG_PARAMS: Struct to be filled in with configuration
+// parameters and passed to the init routine for device controller
+//
+typedef struct {
+  USB_CONTROLLER_ID  ControllerId; // Controller ID of the core
+  UINT32             BaseAddress;  // Base address of the controller registers and on-chip memory
+  UINT32             Flags;        // Initialization flags
+  USB_SPEED          Speed;        // Desired USB bus Speed
+  USB_ROLE           Role;         // Default USB role
+} USB_DEV_CONFIG_PARAMS;
+
+//
+// @USB_DEV_CORE: Struct used as a handle for all
+// hardware-independent APIs
+//
+typedef struct {
+  const struct UsbDeviceCoreDriver *CoreDriver;
+  VOID                                *ControllerHandle;
+} USB_DEV_CORE;
+
+typedef
+EFI_STATUS
+(EFIAPI *USB_DEVICE_CALLBACK_FUNC) (
+  IN USB_DEVICE_CALLBACK_PARAM  *Param
+  );
+
+EFI_STATUS
+UsbDeviceInit (
+  IN USB_DEV_CONFIG_PARAMS    *ConfigParams,
+  IN OUT VOID                 **DevCoreHandle
+  );
+
+EFI_STATUS
+UsbDeviceDeinit (
+  IN VOID                      *DevCoreHandle,
+  IN UINT32                    Flags
+  );
+
+EFI_STATUS
+UsbDeviceRegisterCallback (
+  IN VOID                      *DevCoreHandle,
+  IN USB_DEVICE_EVENT_ID       EventId,
+  IN USB_DEVICE_CALLBACK_FUNC  CallbackFunc
+  );
+
+EFI_STATUS
+UsbDeviceUnregisterCallback (
+  IN VOID                      *DevCoreHandle,
+  IN USB_DEVICE_EVENT_ID       EventId
+  );
+
+EFI_STATUS
+UsbDeviceIsrRoutine (
+  IN VOID                      *DevCoreHandle
+  );
+
+EFI_STATUS
+UsbDeviceIsrRoutineTimerBased (
+  IN VOID                      *DevCoreHandle
+  );
+
+EFI_STATUS
+UsbXdciDeviceConnect (
+  IN VOID                      *DevCoreHandle
+  );
+
+EFI_STATUS
+UsbDeviceDisconnect (
+  IN VOID                      *DevCoreHandle
+  );
+
+EFI_STATUS
+UsbDeviceGetSpeed (
+  IN VOID                      *DevCoreHandle,
+  IN USB_SPEED                 *Speed
+  );
+
+EFI_STATUS
+UsbDeviceSetLinkState (
+  IN VOID                      *DevCoreHandle,
+  IN USB_DEVICE_SS_LINK_STATE  State
+  );
+
+EFI_STATUS
+UsbDeviceSetAddress (
+  IN VOID                      *DevCoreHandle,
+  IN UINT32                    Address
+  );
+
+EFI_STATUS
+UsbDeviceSetConfiguration (
+  IN VOID                      *DevCoreHandle,
+  IN UINT32                    ConfigNum
+  );
+
+EFI_STATUS
+UsbDeviceInitEp (
+  IN VOID                      *DevCoreHandle,
+  IN USB_EP_INFO               *EpInfo
+  );
+
+EFI_STATUS
+UsbDeviceEpEnable (
+  IN VOID                      *DevCoreHandle,
+  IN USB_EP_INFO               *EpInfo
+  );
+
+EFI_STATUS
+UsbDeviceEpDisable (
+  IN VOID                      *DevCoreHandle,
+  IN USB_EP_INFO               *EpInfo
+  );
+
+EFI_STATUS
+UsbDeviceEpStall (
+  IN VOID                      *DevCoreHandle,
+  IN USB_EP_INFO               *EpInfo
+  );
+
+EFI_STATUS
+UsbDeviceEpClearStall (
+  IN VOID                      *DevCoreHandle,
+  IN USB_EP_INFO               *EpInfo
+  );
+
+EFI_STATUS
+UsbDeviceEpSetNrdy (
+  IN VOID                      *DevCoreHandle,
+  IN USB_EP_INFO               *EpInfo
+  );
+
+EFI_STATUS
+UsbDeviceEp0RxSetup (
+  IN VOID                      *DevCoreHandle,
+  IN UINT8                     *Buffer
+  );
+
+EFI_STATUS
+UsbDeviceEp0RxStatus (
+  IN VOID                      *DevCoreHandle
+  );
+
+EFI_STATUS
+UsbDeviceEp0TxStatus (
+  IN VOID                      *DevCoreHandle
+  );
+
+EFI_STATUS
+UsbXdciDeviceEpTxData (
+  IN VOID                      *DevCoreHandle,
+  IN USB_XFER_REQUEST          *XferReq
+  );
+
+EFI_STATUS
+UsbXdciDeviceEpRxData (
+  IN VOID                      *DevCoreHandle,
+  IN USB_XFER_REQUEST          *XferReq
+  );
+
+EFI_STATUS
+UsbDeviceEpCancelTransfer (
+  IN VOID                      *DevCoreHandle,
+  IN USB_EP_INFO               *EpInfo
+  );
+
+#endif
+
diff --git a/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciInterface.h b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciInterface.h
new file mode 100644
index 0000000000..75ce0ecab3
--- /dev/null
+++ b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciInterface.h
@@ -0,0 +1,241 @@
+/** @file
+  Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR>
+
+  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.
+
+**/
+
+#ifndef _USB_DCD_IF_H_
+#define _USB_DCD_IF_H_
+
+/* Core driver for device controller
+ * @DevCoreInit: Intializes device controller
+ * @DevCoreDeinit: De-initializes device controller
+ * @DevCoreRegisterCallback: Registers callback function for
+ * an event to be called by the controller driver
+ * @DevCoreUnregisterCallback: Unregisters callback function
+ * for an event
+ * @DevCoreIsrRoutine: core interrupt service routine for
+ * device controller to be used by OS/stack-i/f layer
+ * @DevCoreConnect: Enable device controller to connect to USB host
+ * @DevCoreDisconnect: Soft disconnect device controller from
+ * USB host
+ * @DevCoreGetSpeed: Get USB bus Speed on which device controller
+ * is attached
+ * @DevCoreSetAddress: Set USB device address in device controller
+ * @DevCoreSetConfig: Set configuration number for device controller
+ * @DevCoreSetLinkState: Set link state for device controller
+ * @DevCoreInitEp: Initialize non-EP0 endpoint
+ * @DevCoreEpEnable: Enable endpoint
+ * @DevCoreEpDisable: Disable endpoint
+ * @DevCoreEpStall: Stall/Halt endpoint
+ * @DevCoreEpClearStall: Clear Stall/Halt on endpoint
+ * @DevCoreEpSetNrdy: Set endpoint to not ready state
+ * @DevCoreEp0RxSetupPkt: Receive SETUP packet on EP0
+ * @DevCoreEp0RxStatusPkt: Receive status packet on EP0
+ * @DevCoreEp0TxStatusPkt: Transmit status packet from EP0
+ * @DevCoreEpTxData: Transmit data from EP
+ * @DevCoreEpRxData: Received data on EP
+ * @DevCoreEpCancelTransfer: Cancel transfer on EP
+ */
+
+typedef
+EFI_STATUS
+(EFIAPI *DEV_CORE_INIT) (
+  IN USB_DEV_CONFIG_PARAMS     *ConfigParams,
+  IN VOID                      *ParentHandle,
+  IN VOID                      **CoreHandle
+  );
+
+typedef
+EFI_STATUS
+(EFIAPI *DEV_CORE_DEINIT) (
+  IN VOID                      *CoreHandle,
+  IN UINT32                    Flags
+  );
+
+typedef
+EFI_STATUS
+(EFIAPI *DEV_CORE_REG_CALLBACK) (
+  IN VOID                      *CoreHandle,
+  IN USB_DEVICE_EVENT_ID       Event,
+  IN USB_DEVICE_CALLBACK_FUNC  CallbackFn
+  );
+
+typedef
+EFI_STATUS
+(EFIAPI *DEV_CORE_UNREG_CALLBACK) (
+  IN VOID                      *CoreHandle,
+  IN USB_DEVICE_EVENT_ID       Event
+  );
+
+typedef
+EFI_STATUS
+(EFIAPI *DEV_CORE_ISR_ROUTINE) (
+  IN VOID                      *CoreHandle
+  );
+
+typedef
+EFI_STATUS
+(EFIAPI *DEV_CORE_CONNECT) (
+  IN VOID                      *CoreHandle
+  );
+
+typedef
+EFI_STATUS
+(EFIAPI *DEV_CORE_DISCONNECT) (
+  IN VOID                      *CoreHandle
+  );
+
+typedef
+EFI_STATUS
+(EFIAPI *DEV_CORE_GET_SPEED) (
+  IN VOID                      *CoreHandle,
+  IN USB_SPEED                 *Speed
+  );
+
+typedef
+EFI_STATUS
+(EFIAPI *DEV_CORE_SET_ADDRESS) (
+  IN VOID                      *CoreHandle,
+  IN UINT32                    Address
+  );
+
+typedef
+EFI_STATUS
+(EFIAPI *DEV_CORE_SET_CONFIG) (
+  IN VOID                      *CoreHandle,
+  IN UINT32                    ConfigNum
+  );
+
+typedef
+EFI_STATUS
+(EFIAPI *DEV_CORE_SET_LINK_STATE) (
+  IN VOID                      *CoreHandle,
+  IN USB_DEVICE_SS_LINK_STATE  State
+  );
+
+typedef
+EFI_STATUS
+(EFIAPI *DEV_CORE_INIT_EP) (
+  IN VOID                      *CoreHandle,
+  IN USB_EP_INFO               *EpInfo
+  );
+
+typedef
+EFI_STATUS
+(EFIAPI *DEV_CORE_EP_ENABLE) (
+  IN VOID                      *CoreHandle,
+  IN USB_EP_INFO               *EpInfo
+  );
+
+typedef
+EFI_STATUS
+(EFIAPI *DEV_CORE_EP_DISABLE) (
+  IN VOID                      *CoreHandle,
+  IN USB_EP_INFO               *EpInfo
+  );
+
+typedef
+EFI_STATUS
+(EFIAPI *DEV_CORE_EP_STALL) (
+  IN VOID                      *CoreHandle,
+  IN USB_EP_INFO               *EpInfo
+  );
+
+typedef
+EFI_STATUS
+(EFIAPI *DEV_CORE_EP_CLEAR_STALL) (
+  IN VOID                      *CoreHandle,
+  IN USB_EP_INFO               *EpInfo
+  );
+
+typedef
+EFI_STATUS
+(EFIAPI *DEV_CORE_EP_SET_NRDY) (
+  IN VOID                      *CoreHandle,
+  IN USB_EP_INFO               *EpInfo
+  );
+
+typedef
+EFI_STATUS
+(EFIAPI *DEV_CORE_EP0_RX_SETUP_PKT) (
+  IN VOID                      *CoreHandle,
+  IN UINT8                     *Buffer
+  );
+
+typedef
+EFI_STATUS
+(EFIAPI *DEV_CORE_EP0_RX_STATUS_PKT) (
+  IN VOID                      *CoreHandle
+  );
+
+typedef
+EFI_STATUS
+(EFIAPI *DEV_CORE_EP0_TX_STATUS_PKT) (
+  IN VOID                      *CoreHandle
+  );
+
+typedef
+EFI_STATUS
+(EFIAPI *DEV_CORE_EP_TX_DATA) (
+  IN VOID                      *CoreHandle,
+  IN USB_XFER_REQUEST          *XferHandle
+  );
+
+typedef
+EFI_STATUS
+(EFIAPI *DEV_CORE_EP_RX_DATA) (
+  IN VOID                      *CoreHandle,
+  IN USB_XFER_REQUEST          *XferHandle
+  );
+
+typedef
+EFI_STATUS
+(EFIAPI *DEV_CORE_EP_CANCEL_TRANSFER) (
+  IN VOID                      *CoreHandle,
+  IN USB_EP_INFO               *EpInfo
+  );
+
+struct UsbDeviceCoreDriver {
+  DEV_CORE_INIT                 DevCoreInit;
+  DEV_CORE_DEINIT               DevCoreDeinit;
+  DEV_CORE_REG_CALLBACK         DevCoreRegisterCallback;
+  DEV_CORE_UNREG_CALLBACK       DevCoreUnregisterCallback;
+  DEV_CORE_ISR_ROUTINE          DevCoreIsrRoutine;
+  DEV_CORE_ISR_ROUTINE          DevCoreIsrRoutineTimerBased;
+  DEV_CORE_CONNECT              DevCoreConnect;
+  DEV_CORE_DISCONNECT           DevCoreDisconnect;
+  DEV_CORE_GET_SPEED            DevCoreGetSpeed;
+  DEV_CORE_SET_ADDRESS          DevCoreSetAddress;
+  DEV_CORE_SET_CONFIG           DevCoreSetConfig;
+  DEV_CORE_SET_LINK_STATE       DevCoreSetLinkState;
+  DEV_CORE_INIT_EP              DevCoreInitEp;
+  DEV_CORE_EP_ENABLE            DevCoreEpEnable;
+  DEV_CORE_EP_DISABLE           DevCoreEpDisable;
+  DEV_CORE_EP_STALL             DevCoreEpStall;
+  DEV_CORE_EP_CLEAR_STALL       DevCoreEpClearStall;
+  DEV_CORE_EP_SET_NRDY          DevCoreEpSetNrdy;
+  DEV_CORE_EP0_RX_SETUP_PKT     DevCoreEp0RxSetupPkt;
+  DEV_CORE_EP0_RX_STATUS_PKT    DevCoreEp0RxStatusPkt;
+  DEV_CORE_EP0_TX_STATUS_PKT    DevCoreEp0TxStatusPkt;
+  DEV_CORE_EP_TX_DATA           DevCoreEpTxData;
+  DEV_CORE_EP_RX_DATA           DevCoreEpRxData;
+  DEV_CORE_EP_CANCEL_TRANSFER   DevCoreEpCancelTransfer;
+};
+
+//
+// This API is used to obtain the driver handle for HW-independent API
+// @id: The ID of the core for which this driver is requested
+//
+const struct UsbDeviceCoreDriver *UsbDeviceGetCoreDriver(
+  USB_CONTROLLER_ID id);
+
+#endif
+
diff --git a/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciTable.c b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciTable.c
new file mode 100644
index 0000000000..97a97db3db
--- /dev/null
+++ b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciTable.c
@@ -0,0 +1,55 @@
+/** @file
+  Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR>
+
+  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.
+
+**/
+
+#include <Library/UsbDeviceLib.h>
+#include "XdciCommon.h"
+#include "XdciDevice.h"
+#include "XdciInterface.h"
+#include "XdciDWC.h"
+#include "UsbDeviceMode.h"
+
+static const struct UsbDeviceCoreDriver CoreDriverTbl[USB_CORE_ID_MAX] = {
+  DwcXdciCoreInit,
+  DwcXdciCoreDeinit,
+  DwcXdciCoreRegisterCallback,
+  DwcXdciCoreUnregisterCallback,
+  DwcXdciCoreIsrRoutine,
+  DwcXdciCoreIsrRoutineTimerBased,
+  DwcXdciCoreConnect,
+  DwcXdciCoreDisconnect,
+  DwcXdciCoreGetSpeed,
+  DwcXdciCoreSetAddress,
+  DwcXdciCoreSetConfig,
+  DwcXdciSetLinkState,
+  DwcXdciInitEp,
+  DwcXdciEpEnable,
+  DwcXdciEpDisable,
+  DwcXdciEpStall,
+  DwcXdciEpClearStall,
+  DwcXdciEpSetNrdy,
+  DwcXdciEp0ReceiveSetupPkt,
+  DwcXdciEp0ReceiveStatusPkt,
+  DwcXdciEp0SendStatusPkt,
+  DwcXdciEpTxData,
+  DwcXdciEpRxData,
+  DwcXdciEpCancelTransfer
+};
+
+const struct UsbDeviceCoreDriver *UsbDeviceGetCoreDriver(USB_CONTROLLER_ID id)
+{
+  if (id >= USB_CORE_ID_MAX)
+    return NULL;
+
+  return &CoreDriverTbl[id];
+}
+
diff --git a/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciUtility.c b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciUtility.c
new file mode 100644
index 0000000000..2e02475cd0
--- /dev/null
+++ b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciUtility.c
@@ -0,0 +1,148 @@
+/** @file
+  Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR>
+
+  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.
+
+**/
+
+#include "XdciUtility.h"
+
+VOID
+PrintDeviceDescriptor (
+  IN USB_DEVICE_DESCRIPTOR    *DevDesc
+  )
+{
+  DEBUG ((DEBUG_INFO, "--- Device Descriptor ---\n"));
+  DEBUG ((DEBUG_INFO, "Length            : 0x%x\n", DevDesc->Length));
+  DEBUG ((DEBUG_INFO, "DescriptorType    : 0x%x\n", DevDesc->DescriptorType));
+  DEBUG ((DEBUG_INFO, "BcdUSB            : 0x%x\n", DevDesc->BcdUSB));
+  DEBUG ((DEBUG_INFO, "DeviceClass       : 0x%x\n", DevDesc->DeviceClass));
+  DEBUG ((DEBUG_INFO, "DeviceSubClass    : 0x%x\n", DevDesc->DeviceSubClass));
+  DEBUG ((DEBUG_INFO, "DeviceProtocol    : 0x%x\n", DevDesc->DeviceProtocol));
+  DEBUG ((DEBUG_INFO, "MaxPacketSize0    : 0x%x\n", DevDesc->MaxPacketSize0));
+  DEBUG ((DEBUG_INFO, "IdVendor          : 0x%x\n", DevDesc->IdVendor));
+  DEBUG ((DEBUG_INFO, "IdProduct         : 0x%x\n", DevDesc->IdProduct));
+  DEBUG ((DEBUG_INFO, "BcdDevice         : 0x%x\n", DevDesc->BcdDevice));
+  DEBUG ((DEBUG_INFO, "StrManufacturer   : 0x%x\n", DevDesc->StrManufacturer));
+  DEBUG ((DEBUG_INFO, "StrProduct        : 0x%x\n", DevDesc->StrProduct));
+  DEBUG ((DEBUG_INFO, "StrSerialNumber   : 0x%x\n", DevDesc->StrSerialNumber));
+  DEBUG ((DEBUG_INFO, "NumConfigurations : 0x%x\n", DevDesc->NumConfigurations));
+  DEBUG ((DEBUG_INFO, "\n"));
+}
+
+VOID
+PrintConfigDescriptor (
+  IN EFI_USB_CONFIG_DESCRIPTOR    *ConfigDesc
+  )
+{
+  DEBUG ((DEBUG_INFO, "--- Configuration Descriptor ---\n"));
+  DEBUG ((DEBUG_INFO, "Length             : 0x%x\n", ConfigDesc->Length));
+  DEBUG ((DEBUG_INFO, "DescriptorType     : 0x%x\n", ConfigDesc->DescriptorType));
+  DEBUG ((DEBUG_INFO, "TotalLength        : 0x%x\n", ConfigDesc->TotalLength));
+  DEBUG ((DEBUG_INFO, "NumInterfaces      : 0x%x\n", ConfigDesc->NumInterfaces));
+  DEBUG ((DEBUG_INFO, "ConfigurationValue : 0x%x\n", ConfigDesc->ConfigurationValue));
+  DEBUG ((DEBUG_INFO, "Configuration      : 0x%x\n", ConfigDesc->Configuration));
+  DEBUG ((DEBUG_INFO, "Attributes         : 0x%x\n", ConfigDesc->Attributes));
+  DEBUG ((DEBUG_INFO, "MaxPower           : 0x%x\n", ConfigDesc->MaxPower));
+  DEBUG ((DEBUG_INFO, "\n"));
+}
+
+VOID
+PrintInterfaceDescriptor (
+  IN EFI_USB_INTERFACE_DESCRIPTOR    *IfDesc
+  )
+{
+  DEBUG ((DEBUG_INFO, "--- Interface Descriptor ---\n"));
+  DEBUG ((DEBUG_INFO, "Length            : 0x%x\n", IfDesc->Length));
+  DEBUG ((DEBUG_INFO, "DescriptorType    : 0x%x\n", IfDesc->DescriptorType));
+  DEBUG ((DEBUG_INFO, "InterfaceNumber   : 0x%x\n", IfDesc->InterfaceNumber));
+  DEBUG ((DEBUG_INFO, "AlternateSetting  : 0x%x\n", IfDesc->AlternateSetting));
+  DEBUG ((DEBUG_INFO, "NumEndpoints      : 0x%x\n", IfDesc->NumEndpoints));
+  DEBUG ((DEBUG_INFO, "InterfaceClass    : 0x%x\n", IfDesc->InterfaceClass));
+  DEBUG ((DEBUG_INFO, "InterfaceSubClass : 0x%x\n", IfDesc->InterfaceSubClass));
+  DEBUG ((DEBUG_INFO, "InterfaceProtocol : 0x%x\n", IfDesc->InterfaceProtocol));
+  DEBUG ((DEBUG_INFO, "Interface         : 0x%x\n", IfDesc->Interface));
+  DEBUG ((DEBUG_INFO, "\n"));
+}
+
+VOID
+PrintEpDescriptor (
+  IN EFI_USB_ENDPOINT_DESCRIPTOR    *EpDesc
+  )
+{
+  DEBUG ((DEBUG_INFO, "--- Endpoint Descriptor ---\n"));
+  DEBUG ((DEBUG_INFO, "Length          : 0x%x\n", EpDesc->Length));
+  DEBUG ((DEBUG_INFO, "DescriptorType  : 0x%x\n", EpDesc->DescriptorType));
+  DEBUG ((DEBUG_INFO, "EndpointAddress : 0x%x\n", EpDesc->EndpointAddress));
+  DEBUG ((DEBUG_INFO, "Attributes      : 0x%x\n", EpDesc->Attributes));
+  DEBUG ((DEBUG_INFO, "MaxPacketSize   : 0x%x\n", EpDesc->MaxPacketSize));
+  DEBUG ((DEBUG_INFO, "Interval        : 0x%x\n", EpDesc->Interval));
+  DEBUG ((DEBUG_INFO, "\n"));
+}
+
+VOID
+PrintEpCompDescriptor (
+  IN EFI_USB_ENDPOINT_COMPANION_DESCRIPTOR    *EpDesc
+  )
+{
+  DEBUG ((DEBUG_INFO, "--- Endpoint Companion Descriptor ---\n"));
+  DEBUG ((DEBUG_INFO, "Length           : 0x%x\n", EpDesc->Length));
+  DEBUG ((DEBUG_INFO, "DescriptorType   : 0x%x\n", EpDesc->DescriptorType));
+  DEBUG ((DEBUG_INFO, "MaxBurst         : 0x%x\n", EpDesc->MaxBurst));
+  DEBUG ((DEBUG_INFO, "Attributes       : 0x%x\n", EpDesc->Attributes));
+  DEBUG ((DEBUG_INFO, "BytesPerInterval : 0x%x\n", EpDesc->BytesPerInterval));
+  DEBUG ((DEBUG_INFO, "\n"));
+}
+
+VOID
+PrintStringDescriptor (
+  IN USB_STRING_DESCRIPTOR    *StrDesc
+  )
+{
+  UINT16 StrLen = 0;
+
+  if (StrDesc->Length > 2) {
+    StrLen = ((StrDesc->Length - 2) >> 1);
+    DEBUG ((DEBUG_INFO, "--- String Descriptor ---\n"));
+    DEBUG ((DEBUG_INFO, "Length         : 0x%x\n", StrDesc->Length));
+    DEBUG ((DEBUG_INFO, "DescriptorType : 0x%x\n", StrDesc->DescriptorType));
+    DEBUG ((DEBUG_INFO, "String         : %s\n",   StrDesc->LangID));
+  }
+  DEBUG ((DEBUG_INFO, "\n"));
+}
+
+VOID
+PrintDeviceRequest (
+  IN EFI_USB_DEVICE_REQUEST    *DevReq
+  )
+{
+  DEBUG ((DEBUG_INFO, "--- Device Request ---\n"));
+  DEBUG ((DEBUG_INFO, "RequestType : 0x%x\n", DevReq->RequestType));
+  DEBUG ((DEBUG_INFO, "Request     : 0x%x\n", DevReq->Request));
+  DEBUG ((DEBUG_INFO, "Value       : 0x%x\n", DevReq->Value));
+  DEBUG ((DEBUG_INFO, "Index       : 0x%x\n", DevReq->Index));
+  DEBUG ((DEBUG_INFO, "Length      : 0x%x\n", DevReq->Length));
+  DEBUG ((DEBUG_INFO, "\n"));
+}
+
+#ifdef SUPPORT_SUPER_SPEED
+VOID
+PrintBOSDescriptor (
+  IN EFI_USB_BOS_DESCRIPTOR    *BosDesc
+  )
+{
+  DEBUG ((DEBUG_INFO, "--- BOS Descriptor ---\n"));
+  DEBUG ((DEBUG_INFO, "Length           : 0x%x\n", BosDesc->Length));
+  DEBUG ((DEBUG_INFO, "DescriptorType   : 0x%x\n", BosDesc->DescriptorType));
+  DEBUG ((DEBUG_INFO, "TotalLength      : 0x%x\n", BosDesc->TotalLength));
+  DEBUG ((DEBUG_INFO, "NumDeviceCaps    : 0x%x\n", BosDesc->NumDeviceCaps));
+  DEBUG ((DEBUG_INFO, "\n"));
+}
+#endif
+
diff --git a/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciUtility.h b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciUtility.h
new file mode 100644
index 0000000000..e3d004e579
--- /dev/null
+++ b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciUtility.h
@@ -0,0 +1,62 @@
+/** @file
+  Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR>
+
+  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.
+
+**/
+
+#ifndef _XDCI_UTILITY_H_
+#define _XDCI_UTILITY_H_
+
+#include <Library/UsbDeviceLib.h>
+
+VOID
+PrintDeviceDescriptor (
+  IN USB_DEVICE_DESCRIPTOR    *DevDesc
+  );
+
+VOID
+PrintConfigDescriptor (
+  IN EFI_USB_CONFIG_DESCRIPTOR    *ConfigDesc
+  );
+
+VOID
+PrintInterfaceDescriptor (
+  IN EFI_USB_INTERFACE_DESCRIPTOR    *IfDesc
+  );
+
+VOID
+PrintEpDescriptor (
+  IN EFI_USB_ENDPOINT_DESCRIPTOR    *EpDesc
+  );
+
+VOID
+PrintEpCompDescriptor (
+  IN EFI_USB_ENDPOINT_COMPANION_DESCRIPTOR    *EpDesc
+  );
+
+VOID
+PrintStringDescriptor (
+  IN USB_STRING_DESCRIPTOR    *StrDesc
+  );
+
+VOID
+PrintDeviceRequest (
+  IN EFI_USB_DEVICE_REQUEST    *DevReq
+  );
+
+#ifdef SUPPORT_SUPER_SPEED
+VOID
+PrintBOSDescriptor (
+  IN EFI_USB_BOS_DESCRIPTOR    *BosDesc
+  );
+#endif
+
+#endif
+
diff --git a/Silicon/Synopsys/DesignWare/Include/Library/UsbDeviceLib.h b/Silicon/Synopsys/DesignWare/Include/Library/UsbDeviceLib.h
new file mode 100644
index 0000000000..fe5f3bcd03
--- /dev/null
+++ b/Silicon/Synopsys/DesignWare/Include/Library/UsbDeviceLib.h
@@ -0,0 +1,323 @@
+/** @file
+  Copyright (c) 2009 - 2016, Intel Corporation. All rights reserved.<BR>
+
+  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.
+
+**/
+
+#ifndef _EFI_XDCI_LIB_H_
+#define _EFI_XDCI_LIB_H_
+
+#include <Uefi.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Protocol/UsbIo.h>
+
+#define MAX_DESCRIPTOR_SIZE         64
+#define STRING_ARR_SIZE             (MAX_DESCRIPTOR_SIZE - 2)
+#define USB_ADDRESS_TABLE_SIZE      16  //4
+
+//
+// Endpoint Zero
+//
+#define USB_EP0_MAX_PKT_SIZE_HS     0x40 // High Speed mode is explicitly set as 64 bytes
+#define USB_EP0_MAX_PKT_SIZE_SS     0x9  // Must be 0x9 (2^9 = 512 Bytes) in SuperSpeed mode
+#define USB_EPO_MAX_PKT_SIZE_ALL    512  // Overall max bytes for any type
+
+//
+// Bulk Endpoints
+//
+#define USB_BULK_EP_PKT_SIZE_HS     0x200 // Bulk-Endpoint HighSpeed
+#define USB_BULK_EP_PKT_SIZE_SS     0x400 // Bulk-Endpoint SuperSpeed
+#define USB_BULK_EP_PKT_SIZE_MAX    USB_BULK_EP_PKT_SIZE_SS
+
+//
+// Transmit Direction Bits
+//
+#define USB_ENDPOINT_DIR_OUT                 0x00
+
+//
+// Endpoint Companion Bulk Attributes
+//
+#define USB_EP_BULK_BM_ATTR_MASK    0x1F
+
+//
+// Configuration Modifiers (Attributes)
+//
+#define USB_BM_ATTR_RESERVED        0x80
+#define USB_BM_ATTR_SELF_POWERED    0x40
+#define USB_BM_ATTR_REMOTE_WAKE     0X20
+
+//
+// USB BCD version
+//
+#define USB_BCD_VERSION_LS          0x0110
+#define USB_BCD_VERSION_HS          0x0200
+#define USB_BCD_VERSION_SS          0x0300
+
+//
+// Device RequestType Flags
+//
+#define USB_RT_TX_DIR_H_TO_D        (0x0)       // Tx direction Host to Device
+#define USB_RT_TX_DIR_D_TO_H        (0x1 << 7)  // Tx direction Device to Host
+#define USB_RT_TX_DIR_MASK          (0x80)
+
+//
+// USB request type
+//
+#define USB_REQ_TYPE_MASK           (0x60)
+
+//
+// Usb control transfer target
+//
+#define USB_TARGET_MASK             (0x1F)
+
+//
+// Device GetStatus bits
+//
+#define USB_STATUS_SELFPOWERED      (0x01)
+#define USB_STATUS_REMOTEWAKEUP     (0x02)
+
+//
+// USB Device class identifiers
+//
+#define USB_DEVICE_MS_CLASS         (0x08)
+#define USB_DEVICE_VENDOR_CLASS     (0xFF)
+
+//
+// USB Descriptor types
+//
+#define USB_DESC_TYPE_BOS                    0x0F
+#define USB_DESC_TYPE_DEVICE_CAPABILITY      0x10
+#define USB_DESC_TYPE_SS_ENDPOINT_COMPANION  0x30
+
+#ifdef SUPPORT_SUPER_SPEED
+//
+// USB device capability Type Codes
+// USB3 Table 9-13
+//
+typedef enum {
+  WirelessUSB = 0x01,
+  USB2Extension,
+  SuperSpeedUSB,
+  ContainerID,
+  SuperSpeedPlusUSB = 0x0A
+} USB_DEVICE_CAP_TYPE_CODE;
+#endif
+
+//
+// USB device states from USB spec sec 9.1
+//
+typedef enum {
+  UsbDevStateOff = 0,
+  UsbDevStateInit,
+  UsbDevStateAttached,
+  UsbDevStatePowered,
+  UsbDevStateDefault,
+  UsbDevStateAddress,
+  UsbDevStateConfigured,
+  UsbDevStateSuspended,
+  UsbDevStateError
+} USB_DEVICE_STATE;
+
+//
+// The following set of structs are used during USB data transaction
+// operatitions, including requests and completion events.
+//
+#pragma pack(1)
+
+typedef struct {
+  UINT32     EndpointNum;
+  UINT8      EndpointDir;
+  UINT8      EndpointType;
+  UINT32     Length;
+  VOID       *Buffer;
+} EFI_USB_DEVICE_XFER_INFO;
+
+//
+// SuperSpeed Endpoint companion descriptor
+// USB3 table 9-22
+//
+typedef struct {
+  UINT8      Length;
+  UINT8      DescriptorType;
+  UINT8      MaxBurst;
+  UINT8      Attributes;
+  UINT16     BytesPerInterval;
+} EFI_USB_ENDPOINT_COMPANION_DESCRIPTOR;
+
+typedef struct {
+  EFI_USB_ENDPOINT_DESCRIPTOR              *EndpointDesc;
+  EFI_USB_ENDPOINT_COMPANION_DESCRIPTOR    *EndpointCompDesc;
+} USB_DEVICE_ENDPOINT_INFO, USB_DEVICE_ENDPOINT_OBJ;
+
+typedef struct {
+  VOID        *Buffer;
+  UINT32      Length;
+} USB_DEVICE_IO_INFO;
+
+typedef struct {
+  USB_DEVICE_IO_INFO           IoInfo;
+  USB_DEVICE_ENDPOINT_INFO     EndpointInfo;
+} USB_DEVICE_IO_REQ;
+
+//
+// Optional string descriptor
+//
+typedef struct {
+  UINT8           Length;
+  UINT8           DescriptorType;
+  UINT16          LangID[STRING_ARR_SIZE];
+} USB_STRING_DESCRIPTOR;
+
+//
+// The following structures abstract the device descriptors a class
+// driver needs to provide to the USBD core.
+// These structures are filled & owned by the class/function layer.
+//
+typedef struct {
+  EFI_USB_INTERFACE_DESCRIPTOR         *InterfaceDesc;
+  USB_DEVICE_ENDPOINT_OBJ              *EndpointObjs;
+} USB_DEVICE_INTERFACE_OBJ;
+
+typedef struct {
+  EFI_USB_CONFIG_DESCRIPTOR     *ConfigDesc;
+  VOID                          *ConfigAll;
+  USB_DEVICE_INTERFACE_OBJ      *InterfaceObjs;
+} USB_DEVICE_CONFIG_OBJ;
+
+#ifdef SUPPORT_SUPER_SPEED
+//
+// SuperSpeed Binary Device Object Store(BOS) descriptor
+// USB3 9.6.2
+//
+typedef struct {
+  UINT8      Length;
+  UINT8      DescriptorType;
+  UINT16     TotalLength;
+  UINT8      NumDeviceCaps;
+} EFI_USB_BOS_DESCRIPTOR;
+
+//
+// Generic Header of Device Capability descriptor
+// USB3 9.6.2.2
+//
+typedef struct {
+  UINT8      Length;
+  UINT8      DescriptorType;
+  UINT8      DevCapabilityType;
+  UINT8      CapDependent;
+} EFI_USB_SS_DEVICE_CAP_DESCRIPTOR;
+
+//
+// USB2.0 Extension descriptor
+// USB3 Table 9-14
+//
+typedef struct {
+  UINT8      Length;
+  UINT8      DescriptorType;
+  UINT8      DeviceCapabilityType;
+  UINT32     Attributes;
+} EFI_USB_USB2_EXT_CAP_DESCRIPTOR;
+
+//
+// SuperSpeed USB Device Capability descriptor
+// USB3 Table 9-15
+//
+typedef struct {
+  UINT8      Length;
+  UINT8      DescriptorType;
+  UINT8      DeviceCapabilityType;
+  UINT8      Attributes;
+  UINT16     SpeedSupported;
+  UINT8      FunctionalitySupport;
+  UINT8      U1DevExitLat;
+  UINT16     U2DevExitLat;
+} EFI_USB_SS_USB_DEV_CAP_DESCRIPTOR;
+
+//
+// Container ID descriptor
+// USB3 Table 9-16
+//
+typedef struct {
+  UINT8      Length;
+  UINT8      DescriptorType;
+  UINT8      DeviceCapabilityType;
+  UINT8      Reserved;
+  UINT8      UUID[16];
+} EFI_USB_CONTAINER_ID_DESCRIPTOR;
+
+//
+// Container ID descriptor
+// USB3 Table 9-16
+//
+typedef struct {
+  UINT8      Length;
+  UINT8      DescriptorType;
+  UINT8      DeviceCapabilityType;
+  UINT8      ReservedByte;
+  UINT32     Attributes;
+  UINT16     FunctionalitySupport;
+  UINT16     ReservedWord;
+  UINT32     SublinkSpeedAttr[2];
+} EFI_USB_SS_PLUS_USB_DEV_CAP_DESCRIPTOR;
+
+#endif
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_USB_CONFIG_CALLBACK) (
+  IN UINT8                      CfgVal
+  );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_USB_SETUP_CALLBACK) (
+  IN EFI_USB_DEVICE_REQUEST     *CtrlRequest,
+  IN USB_DEVICE_IO_INFO         *IoInfo
+  );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_USB_DATA_CALLBACK) (
+  IN EFI_USB_DEVICE_XFER_INFO   *XferInfo
+  );
+
+typedef struct {
+  USB_DEVICE_DESCRIPTOR       *DeviceDesc;
+  USB_DEVICE_CONFIG_OBJ       *ConfigObjs;
+  USB_STRING_DESCRIPTOR       *StringTable;
+#ifdef SUPPORT_SUPER_SPEED
+  EFI_USB_BOS_DESCRIPTOR      *BosDesc;
+#endif
+  UINT8                       StrTblEntries;
+  EFI_USB_CONFIG_CALLBACK     ConfigCallback;
+  EFI_USB_SETUP_CALLBACK      SetupCallback;
+  EFI_USB_DATA_CALLBACK       DataCallback;
+} USB_DEVICE_OBJ;
+
+//
+// Main USBD driver object structure containing all data necessary
+// for USB device mode processing at this layer
+//
+typedef struct {
+  USB_DEVICE_OBJ              *UsbdDevObj;      /* pointer to a Device Object */
+  VOID                        *XdciDrvObj;      /* Opaque handle to XDCI driver */
+  BOOLEAN                     XdciInitialized;  /* flag to specify if the XDCI driver is initialized */
+  USB_DEVICE_CONFIG_OBJ       *ActiveConfigObj; /* pointer to currently active configuraiton */
+  USB_DEVICE_STATE            State;            /* current state of the USB Device state machine */
+  UINT8                       Address;          /* configured device address */
+} USB_DEVICE_DRIVER_OBJ;
+
+#pragma pack()
+
+#endif
+
diff --git a/Silicon/Synopsys/DesignWare/Include/Protocol/EfiUsbFnIo.h b/Silicon/Synopsys/DesignWare/Include/Protocol/EfiUsbFnIo.h
new file mode 100644
index 0000000000..97f276f1cc
--- /dev/null
+++ b/Silicon/Synopsys/DesignWare/Include/Protocol/EfiUsbFnIo.h
@@ -0,0 +1,430 @@
+/** @file
+  EFI USB function IO Protocol
+  This protocol supports Usb Function IO API.
+  Copyright (c) 1999 - 2017, Intel Corporation. All rights reserved.<BR>
+
+  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.
+
+**/
+
+#ifndef __EFI_USB_FUNC_IO_H__
+#define __EFI_USB_FUNC_IO_H__
+
+#include <IndustryStandard/Usb.h>
+
+#define EFI_USBFN_IO_PROTOCOL_REVISION   0x00010001
+
+//
+// {32D2963A-FE5D-4f30-B633-6E5DC55803CC}
+// #define EFI_USBFN_IO_PROTOCOL_GUID  {0x32d2963a, 0xfe5d, 0x4f30, 0xb6, 0x33, 0x6e, 0x5d, 0xc5, 0x58, 0x3, 0xcc };
+//
+
+typedef struct _EFI_USBFN_IO_PROTOCOL   EFI_USBFN_IO_PROTOCOL;
+
+//
+// USB standard descriptors and reqeust
+//
+typedef USB_DEVICE_REQUEST        EFI_USB_DEVICE_REQUEST;
+typedef USB_DEVICE_DESCRIPTOR     EFI_USB_DEVICE_DESCRIPTOR;
+typedef USB_CONFIG_DESCRIPTOR     EFI_USB_CONFIG_DESCRIPTOR;
+typedef USB_INTERFACE_DESCRIPTOR  EFI_USB_INTERFACE_DESCRIPTOR;
+typedef USB_ENDPOINT_DESCRIPTOR   EFI_USB_ENDPOINT_DESCRIPTOR;
+
+typedef enum _EFI_USBFN_PORT_TYPE {
+  EfiUsbUnknownPort = 0,
+  EfiUsbStandardDownstreamPort,
+  EfiUsbChargingDownstreamPort,
+  EfiUsbDedicatedChargingPort,
+  EfiUsbInvalidDedicatedChargingPort
+} EFI_USBFN_PORT_TYPE;
+
+/**
+ USB_DEVICE_DESCRIPTOR, USB_CONFIG_DESCRIPTOR, USB_INTERFACE_DESCRIPTOR, and
+ USB_ENDPOINT_DESCRIPTOR are already defined
+ in UEFI spec 2.3, as par USB 2.0 spec.
+**/
+
+typedef struct {
+  EFI_USB_INTERFACE_DESCRIPTOR        *InterfaceDescriptor;
+  EFI_USB_ENDPOINT_DESCRIPTOR         **EndpointDescriptorTable;
+} EFI_USB_INTERFACE_INFO;
+
+typedef struct {
+  EFI_USB_CONFIG_DESCRIPTOR           *ConfigDescriptor;
+  EFI_USB_INTERFACE_INFO              **InterfaceInfoTable;
+} EFI_USB_CONFIG_INFO;
+
+typedef struct {
+  EFI_USB_DEVICE_DESCRIPTOR           *DeviceDescriptor;
+  EFI_USB_CONFIG_INFO                 **ConfigInfoTable;
+} EFI_USB_DEVICE_INFO;
+
+
+typedef enum _EFI_USB_ENDPOINT_TYPE {
+  UsbEndpointControl     = 0x00,
+  UsbEndpointIsochronous = 0x01,
+  UsbEndpointBulk        = 0x02,
+  UsbEndpointInterrupt   = 0x03
+} EFI_USB_ENDPOINT_TYPE;
+
+
+typedef enum _EFI_USBFN_DEVICE_INFO_ID {
+  EfiUsbDeviceInfoUnknown = 0,
+  EfiUsbDeviceInfoSerialNumber,
+  EfiUsbDeviceInfoManufacturerName,
+  EfiUsbDeviceInfoProductName
+} EFI_USBFN_DEVICE_INFO_ID;
+
+
+typedef enum _EFI_USBFN_ENDPOINT_DIRECTION {
+  EfiUsbEndpointDirectionHostOut  = 0,
+  EfiUsbEndpointDirectionHostIn,
+  EfiUsbEndpointDirectionDeviceTx = EfiUsbEndpointDirectionHostIn,
+  EfiUsbEndpointDirectionDeviceRx = EfiUsbEndpointDirectionHostOut
+} EFI_USBFN_ENDPOINT_DIRECTION;
+
+
+typedef enum _EFI_USBFN_MESSAGE {
+  //
+  // Nothing
+  //
+  EfiUsbMsgNone = 0,
+  //
+  // SETUP packet is received, returned Buffer contains
+  // EFI_USB_DEVICE_REQUEST struct
+  //
+  EfiUsbMsgSetupPacket,
+  //
+  // Indicates that some of the requested data has been received from the
+  // host. It is the responsibility of the class driver to determine if it
+  // needs to wait for any remaining data. Returned Buffer contains
+  // EFI_USBFN_TRANSFER_RESULT struct containing endpoint number, transfer
+  // status and count of bytes received.
+  //
+  EfiUsbMsgEndpointStatusChangedRx,
+  //
+  // Indicates that some of the requested data has been transmitted to the
+  // host. It is the responsibility of the class driver to determine if any
+  // remaining data needs to be resent. Returned Buffer contains
+  // EFI_USBFN_TRANSFER_RESULT struct containing endpoint number, transfer
+  // status and count of bytes sent.
+  //
+  EfiUsbMsgEndpointStatusChangedTx,
+  //
+  // DETACH bus event signaled
+  //
+  EfiUsbMsgBusEventDetach,
+  //
+  // ATTACH bus event signaled
+  //
+  EfiUsbMsgBusEventAttach,
+  //
+  // RESET bus event signaled
+  //
+  EfiUsbMsgBusEventReset,
+  //
+  // SUSPEND bus event signaled
+  //
+  EfiUsbMsgBusEventSuspend,
+  //
+  // RESUME bus event signaled
+  //
+  EfiUsbMsgBusEventResume,
+  //
+  // Bus speed updated, returned buffer indicated bus speed using
+  // following enumeration named EFI_USB_BUS_SPEED
+  //
+  EfiUsbMsgBusEventSpeed
+} EFI_USBFN_MESSAGE;
+
+
+typedef enum _EFI_USBFN_TRANSFER_STATUS {
+  UsbTransferStatusUnknown = 0,
+  UsbTransferStatusComplete,
+  UsbTransferStatusAborted,
+  UsbTransferStatusActive,
+  UsbTransferStatusNone
+} EFI_USBFN_TRANSFER_STATUS;
+
+
+typedef struct _EFI_USBFN_TRANSFER_RESULT {
+  UINTN                         BytesTransferred;
+  EFI_USBFN_TRANSFER_STATUS     TransferStatus;
+  UINT8                         EndpointIndex;
+  EFI_USBFN_ENDPOINT_DIRECTION  Direction;
+  VOID                          *Buffer;
+} EFI_USBFN_TRANSFER_RESULT;
+
+typedef enum _EFI_USB_BUS_SPEED {
+  UsbBusSpeedUnknown = 0,
+  UsbBusSpeedLow,
+  UsbBusSpeedFull,
+  UsbBusSpeedHigh,
+  UsbBusSpeedSuper,
+  UsbBusSpeedMaximum = UsbBusSpeedSuper
+} EFI_USB_BUS_SPEED;
+
+typedef union _EFI_USBFN_MESSAGE_PAYLOAD {
+  EFI_USB_DEVICE_REQUEST      udr;
+  EFI_USBFN_TRANSFER_RESULT   utr;
+  EFI_USB_BUS_SPEED           ubs;
+} EFI_USBFN_MESSAGE_PAYLOAD;
+
+typedef enum _EFI_USBFN_POLICY_TYPE {
+  EfiUsbPolicyUndefined = 0,
+  EfiUsbPolicyMaxTransactionSize,
+  EfiUsbPolicyZeroLengthTerminationSupport,
+  EfiUsbPolicyZeroLengthTermination
+} EFI_USBFN_POLICY_TYPE;
+
+
+/**
+
+ Allocates transfer buffer of the specified size that satisfies
+ controller requirements.
+
+ The AllocateTransferBuffer function allocates a memory region of Size bytes and
+ returns the address of the allocated memory that satisfies underlying
+ controller requirements in the location referenced by Buffer.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI * EFI_USBFN_IO_ALLOCATE_TRANSFER_BUFFER) (
+  IN EFI_USBFN_IO_PROTOCOL    *This,
+  IN UINTN                    Size,
+  OUT VOID                    **Buffer
+  );
+
+/**
+
+  Deallocates the memory allocated for the transfer buffer by AllocateTransferBuffer function.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI * EFI_USBFN_IO_FREE_TRANSFER_BUFFER) (
+  IN EFI_USBFN_IO_PROTOCOL    *This,
+  IN VOID                     *Buffer
+  );
+
+/**
+  Returns information about what type of device was attached.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI * EFI_USBFN_IO_DETECT_PORT) (
+  IN EFI_USBFN_IO_PROTOCOL   *This,
+  OUT EFI_USBFN_PORT_TYPE    *PortType
+  );
+
+/**
+  Configure endpoints based on supplied device and configuration descriptors.
+**/
+typedef
+EFI_STATUS
+(EFIAPI * EFI_USBFN_IO_CONFIGURE_ENABLE_ENDPOINTS) (
+  IN EFI_USBFN_IO_PROTOCOL         *This,
+  IN EFI_USB_DEVICE_INFO           *DeviceInfo
+  );
+
+
+/**
+  Returns the maximum packet size of the specified endpoint type for the supplied bus speed.
+**/
+typedef
+EFI_STATUS
+(EFIAPI * EFI_USBFN_IO_GET_ENDPOINT_MAXPACKET_SIZE) (
+  IN EFI_USBFN_IO_PROTOCOL       *This,
+  IN EFI_USB_ENDPOINT_TYPE       EndpointType,
+  IN EFI_USB_BUS_SPEED           BusSpeed,
+  OUT UINT16                     *MaxPacketSize
+  );
+
+/**
+  Returns the maximum supported transfer size.
+**/
+typedef
+EFI_STATUS
+(EFIAPI * EFI_USBFN_IO_GET_MAXTRANSFER_SIZE) (
+  IN EFI_USBFN_IO_PROTOCOL     *This,
+  OUT UINTN                    *MaxTransferSize
+  );
+
+/**
+  Returns device specific information based on the supplied identifier as a
+  Unicode string.
+**/
+typedef
+EFI_STATUS
+(EFIAPI * EFI_USBFN_IO_GET_DEVICE_INFO) (
+  IN EFI_USBFN_IO_PROTOCOL      *This,
+  IN EFI_USBFN_DEVICE_INFO_ID   Id,
+  IN OUT UINTN                  *BufferSize,
+  OUT VOID                      *Buffer OPTIONAL
+  );
+
+/**
+  Returns vendor-id and product-id of the device.
+**/
+typedef
+EFI_STATUS
+(EFIAPI * EFI_USBFN_IO_GET_VENDOR_ID_PRODUCT_ID) (
+  IN EFI_USBFN_IO_PROTOCOL      *This,
+  OUT UINT16                    *Vid,
+  OUT UINT16                    *Pid
+  );
+
+/**
+  Aborts transfer on the specified endpoint.
+**/
+typedef
+EFI_STATUS
+(EFIAPI * EFI_USBFN_IO_ABORT_TRANSFER) (
+  IN EFI_USBFN_IO_PROTOCOL        *This,
+  IN UINT8                        EndpointIndex,
+  IN EFI_USBFN_ENDPOINT_DIRECTION Direction
+  );
+
+/**
+  Returns the stall state on the specified endpoint.
+**/
+typedef
+EFI_STATUS
+(EFIAPI * EFI_USBFN_IO_GET_ENDPOINT_STALL_STATE) (
+  IN EFI_USBFN_IO_PROTOCOL        *This,
+  IN UINT8                        EndpointIndex,
+  IN EFI_USBFN_ENDPOINT_DIRECTION Direction,
+  IN OUT BOOLEAN                  *State
+  );
+
+/**
+  Sets or clears the stall state on the specified endpoint.
+**/
+typedef
+EFI_STATUS
+(EFIAPI * EFI_USBFN_IO_SET_ENDPOINT_STALL_STATE) (
+  IN EFI_USBFN_IO_PROTOCOL        *This,
+  IN UINT8                        EndpointIndex,
+  IN EFI_USBFN_ENDPOINT_DIRECTION Direction,
+  IN BOOLEAN                      State
+  );
+
+
+/**
+  This function is called repeatedly to receive updates on USB bus states,
+  receive, transmit status changes on endpoints and setup packet on endpoint 0.
+**/
+typedef
+EFI_STATUS
+(EFIAPI * EFI_USBFN_IO_EVENTHANDLER) (
+  IN EFI_USBFN_IO_PROTOCOL        *This,
+  OUT EFI_USBFN_MESSAGE           *Message,
+  IN OUT UINTN                    *PayloadSize,
+  OUT EFI_USBFN_MESSAGE_PAYLOAD   *Payload
+  );
+
+/**
+  Primary function to handle transfer in either direction based on specified
+  direction and on the specified endpoint.
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_USBFN_IO_TRANSFER) (
+  IN EFI_USBFN_IO_PROTOCOL         *This,
+  IN UINT8                         EndpointIndex,
+  IN EFI_USBFN_ENDPOINT_DIRECTION  Direction,
+  IN OUT UINTN                     *BufferSize,
+  IN OUT VOID                      *Buffer
+  );
+
+/**
+  This function supplies power to the USB controller if needed,
+  initialize hardware and internal data structures, and then return.
+
+  The port must not be activated by this function.
+**/
+typedef
+EFI_STATUS
+(EFIAPI * EFI_USBFN_IO_START_CONTROLLER) (
+    IN EFI_USBFN_IO_PROTOCOL    *This
+    );
+
+/**
+  This function disables the hardware device by resetting the run/stop bit and
+  power off the USB controller if needed.
+**/
+typedef
+EFI_STATUS
+(EFIAPI * EFI_USBFN_IO_STOP_CONTROLLER) (
+    IN EFI_USBFN_IO_PROTOCOL    *This
+    );
+
+/**
+  This function sets the configuration policy for the specified non-control endpoint.
+
+  Refer to the description for calling restrictions.
+**/
+typedef
+EFI_STATUS
+(EFIAPI * EFI_USBFN_IO_SET_ENDPOINT_POLICY) (
+  IN EFI_USBFN_IO_PROTOCOL        *This,
+  IN UINT8                        EndpointIndex,
+  IN EFI_USBFN_ENDPOINT_DIRECTION Direction,
+  IN EFI_USBFN_POLICY_TYPE        PolicyType,
+  IN UINTN                        BufferSize,
+  IN VOID                         *Buffer
+  );
+
+/**
+  This function retrieves the configuration policy for the specified non-control endpoint.
+
+  There are no associated calling restrictions for this function.
+**/
+typedef
+EFI_STATUS
+(EFIAPI * EFI_USBFN_IO_GET_ENDPOINT_POLICY) (
+  IN EFI_USBFN_IO_PROTOCOL        *This,
+  IN UINT8                        EndpointIndex,
+  IN EFI_USBFN_ENDPOINT_DIRECTION Direction,
+  IN EFI_USBFN_POLICY_TYPE        PolicyType,
+  IN OUT UINTN                    *BufferSize,
+  IN OUT VOID                     *Buffer
+  );
+
+
+struct _EFI_USBFN_IO_PROTOCOL {
+  UINT32                                      Revision;
+  EFI_USBFN_IO_DETECT_PORT                    DetectPort;
+  EFI_USBFN_IO_CONFIGURE_ENABLE_ENDPOINTS     ConfigureEnableEndpoints;
+  EFI_USBFN_IO_GET_ENDPOINT_MAXPACKET_SIZE    GetEndpointMaxPacketSize;
+  EFI_USBFN_IO_GET_DEVICE_INFO                GetDeviceInfo;
+  EFI_USBFN_IO_GET_VENDOR_ID_PRODUCT_ID       GetVendorIdProductId;
+  EFI_USBFN_IO_ABORT_TRANSFER                 AbortTransfer;
+  EFI_USBFN_IO_GET_ENDPOINT_STALL_STATE       GetEndpointStallState;
+  EFI_USBFN_IO_SET_ENDPOINT_STALL_STATE       SetEndpointStallState;
+  EFI_USBFN_IO_EVENTHANDLER                   EventHandler;
+  EFI_USBFN_IO_TRANSFER                       Transfer;
+  EFI_USBFN_IO_GET_MAXTRANSFER_SIZE           GetMaxTransferSize;
+  EFI_USBFN_IO_ALLOCATE_TRANSFER_BUFFER       AllocateTransferBuffer;
+  EFI_USBFN_IO_FREE_TRANSFER_BUFFER           FreeTransferBuffer;
+  //
+  // Valid for version EFI_USBFN_IO_PROTOCOL_REVISION2 and above
+  //
+  EFI_USBFN_IO_START_CONTROLLER               StartController;
+  EFI_USBFN_IO_STOP_CONTROLLER                StopController;
+  EFI_USBFN_IO_SET_ENDPOINT_POLICY            SetEndpointPolicy;
+  EFI_USBFN_IO_GET_ENDPOINT_POLICY            GetEndpointPolicy;
+};
+
+
+extern EFI_GUID gEfiUsbFnIoProtocolGuid;
+#endif
+
diff --git a/Silicon/Synopsys/DesignWare/Include/Protocol/UsbDeviceModeProtocol.h b/Silicon/Synopsys/DesignWare/Include/Protocol/UsbDeviceModeProtocol.h
new file mode 100644
index 0000000000..c301fa00d3
--- /dev/null
+++ b/Silicon/Synopsys/DesignWare/Include/Protocol/UsbDeviceModeProtocol.h
@@ -0,0 +1,104 @@
+/** @file
+  Copyright (c) 1999 - 2017, Intel Corporation. All rights reserved.<BR>
+
+  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.
+
+**/
+
+
+#ifndef _USB_DEVICE_MODE_PROTOCOL_H_
+#define _USB_DEVICE_MODE_PROTOCOL_H_
+
+#include <Library/UsbDeviceLib.h>
+
+///
+/// UsbDeviceMode Protocol GUID.
+///
+#define EFI_USB_DEVICE_MODE_PROTOCOL_GUID \
+  {0xC9923F7E, 0x1746, 0x4802, { 0x86, 0x2e, 0x1, 0x1c, 0x2c, 0x2d, 0x9d, 0x86 } }
+
+typedef struct _EFI_USB_DEVICE_MODE_PROTOCOL EFI_USB_DEVICE_MODE_PROTOCOL;
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_USB_DEVICE_MODE_INIT_XDCI) (
+  IN EFI_USB_DEVICE_MODE_PROTOCOL               *This
+  );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_USB_DEVICE_MODE_CONNECT) (
+  IN EFI_USB_DEVICE_MODE_PROTOCOL               *This
+  );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_USB_DEVICE_MODE_DISCONNECT) (
+  IN EFI_USB_DEVICE_MODE_PROTOCOL               *This
+  );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_USB_DEVICE_EP_TX_DATA) (
+  IN EFI_USB_DEVICE_MODE_PROTOCOL               *This,
+  IN USB_DEVICE_IO_REQ                          *IoRequest
+  );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_USB_DEVICE_EP_RX_DATA) (
+  IN EFI_USB_DEVICE_MODE_PROTOCOL               *This,
+  IN USB_DEVICE_IO_REQ                          *IoRequest
+  );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_USB_DEVICE_MODE_BIND) (
+  IN EFI_USB_DEVICE_MODE_PROTOCOL               *This,
+  IN USB_DEVICE_OBJ                             *UsbdDevObj
+  );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_USB_DEVICE_MODE_UNBIND) (
+  IN EFI_USB_DEVICE_MODE_PROTOCOL               *This
+  );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_USB_DEVICE_MODE_STOP) (
+  IN EFI_USB_DEVICE_MODE_PROTOCOL               *This
+  );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_USB_DEVICE_MODE_RUN) (
+  IN EFI_USB_DEVICE_MODE_PROTOCOL               *This,
+  IN UINT32                                     TimeoutMs
+  );
+
+///
+/// Usb Device Mode Protocol Structure.
+///
+struct _EFI_USB_DEVICE_MODE_PROTOCOL {
+  EFI_USB_DEVICE_MODE_INIT_XDCI            InitXdci;
+  EFI_USB_DEVICE_MODE_CONNECT              Connect;
+  EFI_USB_DEVICE_MODE_DISCONNECT           DisConnect;
+  EFI_USB_DEVICE_EP_TX_DATA                EpTxData;
+  EFI_USB_DEVICE_EP_RX_DATA                EpRxData;
+  EFI_USB_DEVICE_MODE_BIND                 Bind;
+  EFI_USB_DEVICE_MODE_UNBIND               UnBind;
+  EFI_USB_DEVICE_MODE_RUN                  Run;
+  EFI_USB_DEVICE_MODE_STOP                 Stop;
+};
+
+extern EFI_GUID gEfiUsbDeviceModeProtocolGuid;
+
+#endif
+
-- 
2.27.0.windows.1


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [edk2-platforms PATCH 1/5] Silicon/Synopsys/DesignWare: Import DesignWare USB3 peripheral driver
  2020-07-17 10:01 [edk2-platforms PATCH 1/5] Silicon/Synopsys/DesignWare: Import DesignWare USB3 peripheral driver Vin Xue
@ 2020-07-20 17:43 ` Leif Lindholm
  2020-07-21  3:51   ` Vin Xue
  2020-07-21  8:17   ` Meenakshi Aggarwal (OSS)
  0 siblings, 2 replies; 6+ messages in thread
From: Leif Lindholm @ 2020-07-20 17:43 UTC (permalink / raw)
  To: Vin Xue; +Cc: devel, Ard Biesheuvel, Meenakshi Aggarwal

Hi Vin, +Meenakshi

Can you clarify the exact origin of this source code please?
We can only accept bsd+patent code contributions, and these days we
use only SPDX tags rather than full license statements at top of
files.

Meenakshi - I would certainly prefer to have a single (and
Arm-functional) driver for DWC3 rather than init-only drivers per
platform. Can you have a look at this code plese and see if it looks
feasible to integrate in the NXP platforms?

Regards,

Leif

On Fri, Jul 17, 2020 at 18:01:59 +0800, Vin Xue wrote:
> Incorporate the driver for the DesignWare USB3 DRD controller device
> mode (peripheral) that is defined in
> edk2-platforms/devel-IntelAtomProcessorE3900 branch.
> 
> The driver is supported by Intel Atom series (Merrifield/BayTrail/
> CherryTrail/Broxton/ApoloLake/GeminiLake etc.) and Core series
> (6th Generation and newer).
> 
> The driver verified on AAEON UP Squared developer board (Intel
> ApoloLake platform).
> 
> The driver supports Synopsys DesignWare DWC_usb3 and DWC_usb31 IP.
> 
> It is better if the driver can be ported to ARM silicon.
> 
> Cc: Ard Biesheuvel <ard.biesheuvel@arm.com>
> Cc: Leif Lindholm <leif@nuviainc.com>
> Signed-off-by: Vin Xue <vinxue@outlook.com>
> ---
>  .../Drivers/UsbDeviceDxe/ComponentName.c      |  305 ++
>  .../Drivers/UsbDeviceDxe/UsbDeviceDxe.c       |  395 ++
>  .../Drivers/UsbDeviceDxe/UsbDeviceDxe.h       |  159 +
>  .../Drivers/UsbDeviceDxe/UsbDeviceDxe.inf     |   74 +
>  .../Drivers/UsbDeviceDxe/UsbDeviceMode.c      | 1489 ++++++
>  .../Drivers/UsbDeviceDxe/UsbDeviceMode.h      |   39 +
>  .../Drivers/UsbDeviceDxe/UsbFuncIo.c          | 2221 +++++++++
>  .../Drivers/UsbDeviceDxe/UsbFuncIo.h          |  234 +
>  .../Drivers/UsbDeviceDxe/UsbIoNode.c          |  177 +
>  .../Drivers/UsbDeviceDxe/UsbIoNode.h          |   90 +
>  .../Drivers/UsbDeviceDxe/XdciCommon.h         |  156 +
>  .../DesignWare/Drivers/UsbDeviceDxe/XdciDWC.c | 4030 +++++++++++++++++
>  .../DesignWare/Drivers/UsbDeviceDxe/XdciDWC.h |  741 +++
>  .../Drivers/UsbDeviceDxe/XdciDevice.c         |  695 +++
>  .../Drivers/UsbDeviceDxe/XdciDevice.h         |  184 +
>  .../Drivers/UsbDeviceDxe/XdciInterface.h      |  241 +
>  .../Drivers/UsbDeviceDxe/XdciTable.c          |   55 +
>  .../Drivers/UsbDeviceDxe/XdciUtility.c        |  148 +
>  .../Drivers/UsbDeviceDxe/XdciUtility.h        |   62 +
>  .../DesignWare/Include/Library/UsbDeviceLib.h |  323 ++
>  .../DesignWare/Include/Protocol/EfiUsbFnIo.h  |  430 ++
>  .../Include/Protocol/UsbDeviceModeProtocol.h  |  104 +
>  22 files changed, 12352 insertions(+)
>  create mode 100644 Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/ComponentName.c
>  create mode 100644 Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbDeviceDxe.c
>  create mode 100644 Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbDeviceDxe.h
>  create mode 100644 Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbDeviceDxe.inf
>  create mode 100644 Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbDeviceMode.c
>  create mode 100644 Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbDeviceMode.h
>  create mode 100644 Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbFuncIo.c
>  create mode 100644 Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbFuncIo.h
>  create mode 100644 Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbIoNode.c
>  create mode 100644 Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbIoNode.h
>  create mode 100644 Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciCommon.h
>  create mode 100644 Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciDWC.c
>  create mode 100644 Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciDWC.h
>  create mode 100644 Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciDevice.c
>  create mode 100644 Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciDevice.h
>  create mode 100644 Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciInterface.h
>  create mode 100644 Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciTable.c
>  create mode 100644 Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciUtility.c
>  create mode 100644 Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciUtility.h
>  create mode 100644 Silicon/Synopsys/DesignWare/Include/Library/UsbDeviceLib.h
>  create mode 100644 Silicon/Synopsys/DesignWare/Include/Protocol/EfiUsbFnIo.h
>  create mode 100644 Silicon/Synopsys/DesignWare/Include/Protocol/UsbDeviceModeProtocol.h
> 
> diff --git a/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/ComponentName.c b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/ComponentName.c
> new file mode 100644
> index 0000000000..acb4b6a23d
> --- /dev/null
> +++ b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/ComponentName.c
> @@ -0,0 +1,305 @@
> +/** @file
> +  Copyright (c) 2004 - 2017, Intel Corporation. All rights reserved.<BR>
> +
> +  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.
> +
> +**/
> +
> +#include <Uefi.h>
> +#include <Library/UefiLib.h>
> +
> +
> +/**
> +  Retrieves a Unicode string that is the user readable name of the driver.
> +
> +  This function retrieves the user readable name of a driver in the form of a
> +  Unicode string. If the driver specified by This has a user readable name in
> +  the language specified by Language, then a pointer to the driver name is
> +  returned in DriverName, and EFI_SUCCESS is returned. If the driver specified
> +  by This does not support the language specified by Language,
> +  then EFI_UNSUPPORTED is returned.
> +
> +  @param  This[in]              A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
> +                                EFI_COMPONENT_NAME_PROTOCOL instance.
> +
> +  @param  Language[in]          A pointer to a Null-terminated ASCII string
> +                                array indicating the language. This is the
> +                                language of the driver name that the caller is
> +                                requesting, and it must match one of the
> +                                languages specified in SupportedLanguages. The
> +                                number of languages supported by a driver is up
> +                                to the driver writer. Language is specified
> +                                in RFC 4646 or ISO 639-2 language code format.
> +
> +  @param  DriverName[out]       A pointer to the Unicode string to return.
> +                                This Unicode string is the name of the
> +                                driver specified by This in the language
> +                                specified by Language.
> +
> +  @retval EFI_SUCCESS           The Unicode string for the Driver specified by
> +                                This and the language specified by Language was
> +                                returned in DriverName.
> +
> +  @retval EFI_INVALID_PARAMETER Language is NULL.
> +
> +  @retval EFI_INVALID_PARAMETER DriverName is NULL.
> +
> +  @retval EFI_UNSUPPORTED       The driver specified by This does not support
> +                                the language specified by Language.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +UsbDeviceDxeGetDriverName (
> +  IN  EFI_COMPONENT_NAME_PROTOCOL  *This,
> +  IN  CHAR8                        *Language,
> +  OUT CHAR16                       **DriverName
> +  );
> +
> +
> +/**
> +  Retrieves a Unicode string that is the user readable name of the controller
> +  that is being managed by a driver.
> +
> +  This function retrieves the user readable name of the controller specified by
> +  ControllerHandle and ChildHandle in the form of a Unicode string. If the
> +  driver specified by This has a user readable name in the language specified by
> +  Language, then a pointer to the controller name is returned in ControllerName,
> +  and EFI_SUCCESS is returned.  If the driver specified by This is not currently
> +  managing the controller specified by ControllerHandle and ChildHandle,
> +  then EFI_UNSUPPORTED is returned.  If the driver specified by This does not
> +  support the language specified by Language, then EFI_UNSUPPORTED is returned.
> +
> +  @param  This[in]              A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
> +                                EFI_COMPONENT_NAME_PROTOCOL instance.
> +
> +  @param  ControllerHandle[in]  The handle of a controller that the driver
> +                                specified by This is managing.  This handle
> +                                specifies the controller whose name is to be
> +                                returned.
> +
> +  @param  ChildHandle[in]       The handle of the child controller to retrieve
> +                                the name of.  This is an optional parameter that
> +                                may be NULL.  It will be NULL for device
> +                                drivers.  It will also be NULL for a bus drivers
> +                                that wish to retrieve the name of the bus
> +                                controller.  It will not be NULL for a bus
> +                                driver that wishes to retrieve the name of a
> +                                child controller.
> +
> +  @param  Language[in]          A pointer to a Null-terminated ASCII string
> +                                array indicating the language.  This is the
> +                                language of the driver name that the caller is
> +                                requesting, and it must match one of the
> +                                languages specified in SupportedLanguages. The
> +                                number of languages supported by a driver is up
> +                                to the driver writer. Language is specified in
> +                                RFC 4646 or ISO 639-2 language code format.
> +
> +  @param  ControllerName[out]   A pointer to the Unicode string to return.
> +                                This Unicode string is the name of the
> +                                controller specified by ControllerHandle and
> +                                ChildHandle in the language specified by
> +                                Language from the point of view of the driver
> +                                specified by This.
> +
> +  @retval EFI_SUCCESS           The Unicode string for the user readable name in
> +                                the language specified by Language for the
> +                                driver specified by This was returned in
> +                                DriverName.
> +
> +  @retval EFI_INVALID_PARAMETER ControllerHandle is NULL.
> +
> +  @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid
> +                                EFI_HANDLE.
> +
> +  @retval EFI_INVALID_PARAMETER Language is NULL.
> +
> +  @retval EFI_INVALID_PARAMETER ControllerName is NULL.
> +
> +  @retval EFI_UNSUPPORTED       The driver specified by This is not currently
> +                                managing the controller specified by
> +                                ControllerHandle and ChildHandle.
> +
> +  @retval EFI_UNSUPPORTED       The driver specified by This does not support
> +                                the language specified by Language.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +UsbDeviceDxeGetControllerName (
> +  IN  EFI_COMPONENT_NAME_PROTOCOL                     *This,
> +  IN  EFI_HANDLE                                      ControllerHandle,
> +  IN  EFI_HANDLE                                      ChildHandle        OPTIONAL,
> +  IN  CHAR8                                           *Language,
> +  OUT CHAR16                                          **ControllerName
> +  );
> +
> +
> +//
> +// EFI Component Name Protocol
> +//
> +GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME_PROTOCOL  mUsbDeviceDxeComponentName = {
> +  UsbDeviceDxeGetDriverName,
> +  UsbDeviceDxeGetControllerName,
> +  "eng"
> +};
> +
> +//
> +// EFI Component Name 2 Protocol
> +//
> +GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME2_PROTOCOL mUsbDeviceDxeComponentName2 = {
> +  (EFI_COMPONENT_NAME2_GET_DRIVER_NAME) UsbDeviceDxeGetDriverName,
> +  (EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME) UsbDeviceDxeGetControllerName,
> +  "en"
> +};
> +
> +
> +GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mUsbDeviceDxeDriverNameTable[] = {
> +  { "eng;en", L"Usb Device Driver" },
> +  { NULL , NULL }
> +};
> +
> +/**
> +  Retrieves a Unicode string that is the user readable name of the driver.
> +
> +  This function retrieves the user readable name of a driver in the form of a
> +  Unicode string. If the driver specified by This has a user readable name in
> +  the language specified by Language, then a pointer to the driver name is
> +  returned in DriverName, and EFI_SUCCESS is returned. If the driver specified
> +  by This does not support the language specified by Language,
> +  then EFI_UNSUPPORTED is returned.
> +
> +  @param  This[in]              A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
> +                                EFI_COMPONENT_NAME_PROTOCOL instance.
> +
> +  @param  Language[in]          A pointer to a Null-terminated ASCII string
> +                                array indicating the language. This is the
> +                                language of the driver name that the caller is
> +                                requesting, and it must match one of the
> +                                languages specified in SupportedLanguages. The
> +                                number of languages supported by a driver is up
> +                                to the driver writer. Language is specified
> +                                in RFC 4646 or ISO 639-2 language code format.
> +
> +  @param  DriverName[out]       A pointer to the Unicode string to return.
> +                                This Unicode string is the name of the
> +                                driver specified by This in the language
> +                                specified by Language.
> +
> +  @retval EFI_SUCCESS           The Unicode string for the Driver specified by
> +                                This and the language specified by Language was
> +                                returned in DriverName.
> +
> +  @retval EFI_INVALID_PARAMETER Language is NULL.
> +
> +  @retval EFI_INVALID_PARAMETER DriverName is NULL.
> +
> +  @retval EFI_UNSUPPORTED       The driver specified by This does not support
> +                                the language specified by Language.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +UsbDeviceDxeGetDriverName (
> +  IN  EFI_COMPONENT_NAME_PROTOCOL  *This,
> +  IN  CHAR8                        *Language,
> +  OUT CHAR16                       **DriverName
> +  )
> +{
> +  return LookupUnicodeString2 (
> +           Language,
> +           This->SupportedLanguages,
> +           mUsbDeviceDxeDriverNameTable,
> +           DriverName,
> +           (BOOLEAN)(This == &mUsbDeviceDxeComponentName)
> +           );
> +}
> +
> +/**
> +  Retrieves a Unicode string that is the user readable name of the controller
> +  that is being managed by a driver.
> +
> +  This function retrieves the user readable name of the controller specified by
> +  ControllerHandle and ChildHandle in the form of a Unicode string. If the
> +  driver specified by This has a user readable name in the language specified by
> +  Language, then a pointer to the controller name is returned in ControllerName,
> +  and EFI_SUCCESS is returned.  If the driver specified by This is not currently
> +  managing the controller specified by ControllerHandle and ChildHandle,
> +  then EFI_UNSUPPORTED is returned.  If the driver specified by This does not
> +  support the language specified by Language, then EFI_UNSUPPORTED is returned.
> +
> +  @param  This[in]              A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
> +                                EFI_COMPONENT_NAME_PROTOCOL instance.
> +
> +  @param  ControllerHandle[in]  The handle of a controller that the driver
> +                                specified by This is managing.  This handle
> +                                specifies the controller whose name is to be
> +                                returned.
> +
> +  @param  ChildHandle[in]       The handle of the child controller to retrieve
> +                                the name of.  This is an optional parameter that
> +                                may be NULL.  It will be NULL for device
> +                                drivers.  It will also be NULL for a bus drivers
> +                                that wish to retrieve the name of the bus
> +                                controller.  It will not be NULL for a bus
> +                                driver that wishes to retrieve the name of a
> +                                child controller.
> +
> +  @param  Language[in]          A pointer to a Null-terminated ASCII string
> +                                array indicating the language.  This is the
> +                                language of the driver name that the caller is
> +                                requesting, and it must match one of the
> +                                languages specified in SupportedLanguages. The
> +                                number of languages supported by a driver is up
> +                                to the driver writer. Language is specified in
> +                                RFC 4646 or ISO 639-2 language code format.
> +
> +  @param  ControllerName[out]   A pointer to the Unicode string to return.
> +                                This Unicode string is the name of the
> +                                controller specified by ControllerHandle and
> +                                ChildHandle in the language specified by
> +                                Language from the point of view of the driver
> +                                specified by This.
> +
> +  @retval EFI_SUCCESS           The Unicode string for the user readable name in
> +                                the language specified by Language for the
> +                                driver specified by This was returned in
> +                                DriverName.
> +
> +  @retval EFI_INVALID_PARAMETER ControllerHandle is not a valid EFI_HANDLE.
> +
> +  @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid
> +                                EFI_HANDLE.
> +
> +  @retval EFI_INVALID_PARAMETER Language is NULL.
> +
> +  @retval EFI_INVALID_PARAMETER ControllerName is NULL.
> +
> +  @retval EFI_UNSUPPORTED       The driver specified by This is not currently
> +                                managing the controller specified by
> +                                ControllerHandle and ChildHandle.
> +
> +  @retval EFI_UNSUPPORTED       The driver specified by This does not support
> +                                the language specified by Language.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +UsbDeviceDxeGetControllerName (
> +  IN  EFI_COMPONENT_NAME_PROTOCOL                     *This,
> +  IN  EFI_HANDLE                                      ControllerHandle,
> +  IN  EFI_HANDLE                                      ChildHandle        OPTIONAL,
> +  IN  CHAR8                                           *Language,
> +  OUT CHAR16                                          **ControllerName
> +  )
> +{
> +  return EFI_UNSUPPORTED;
> +}
> +
> diff --git a/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbDeviceDxe.c b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbDeviceDxe.c
> new file mode 100644
> index 0000000000..2732cc2e31
> --- /dev/null
> +++ b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbDeviceDxe.c
> @@ -0,0 +1,395 @@
> +/** @file
> +  Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR>
> +
> +  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.
> +
> +**/
> +
> +#include "UsbDeviceDxe.h"
> +#include <Guid/EventGroup.h>
> +
> +EFI_DRIVER_BINDING_PROTOCOL mUsbDeviceDxeDriverBinding = {
> +  UsbDeviceDxeDriverSupported,
> +  UsbDeviceDxeDriverStart,
> +  UsbDeviceDxeDriverStop,
> +  0x1,
> +  NULL,
> +  NULL
> +};
> +
> +
> +
> +VOID
> +EFIAPI
> +PlatformSpecificInit (
> +  VOID
> +  )
> +{
> +  UINTN                 XhciPciMmBase;
> +  EFI_PHYSICAL_ADDRESS  XhciMemBaseAddress;
> +
> +  XhciPciMmBase   = MmPciAddress (
> +                      0,
> +                      0,
> +                      PCI_DEVICE_NUMBER_XHCI,
> +                      PCI_FUNCTION_NUMBER_XHCI,
> +                      0
> +                      );
> +
> +
> +  XhciMemBaseAddress = MmioRead32 ((UINTN) (XhciPciMmBase + R_XHCI_MEM_BASE)) & B_XHCI_MEM_BASE_BA;
> +  DEBUG ((DEBUG_INFO, "XhciPciMmBase=%x, XhciMemBaseAddress=%x\n", XhciPciMmBase, XhciMemBaseAddress));
> +
> +  MmioWrite32 ((UINTN)(XhciMemBaseAddress + R_XHCI_MEM_DUAL_ROLE_CFG0), 0x1310800);
> +
> +  PmicUSBSwitchControl (TRUE);//conduction USB switch.
> +  return;
> +}
> +
> +
> +VOID
> +EFIAPI
> +UsbDeviceDxeExitBootService (
> +  EFI_EVENT  Event,
> +  VOID       *Context
> +  )
> +{
> +  USB_XDCI_DEV_CONTEXT  *UsbXdciDevContext;
> +
> +  UsbXdciDevContext = (USB_XDCI_DEV_CONTEXT *) Context;
> +  DEBUG ((EFI_D_INFO, "UsbDeviceDxeExitBootService enter\n"));
> +
> +  if (UsbXdciDevContext->XdciPollTimer != NULL) {
> +    gBS->SetTimer (UsbXdciDevContext->XdciPollTimer, TimerCancel, 0);
> +    gBS->CloseEvent (UsbXdciDevContext->XdciPollTimer);
> +    UsbXdciDevContext->XdciPollTimer = NULL;
> +    }
> +
> +  return;
> +}
> +
> +/**
> +  The USB bus driver entry pointer.
> +
> +  @param ImageHandle       The driver image handle.
> +  @param SystemTable       The system table.
> +
> +  @return EFI_SUCCESS      The component name protocol is installed.
> +  @return Others           Failed to init the usb driver.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +UsbDeviceDxeEntryPoint (
> +  IN EFI_HANDLE           ImageHandle,
> +  IN EFI_SYSTEM_TABLE     *SystemTable
> +  )
> +{
> +  return EfiLibInstallDriverBindingComponentName2 (
> +           ImageHandle,
> +           SystemTable,
> +           &mUsbDeviceDxeDriverBinding,
> +           ImageHandle,
> +           &mUsbDeviceDxeComponentName,
> +           &mUsbDeviceDxeComponentName2
> +           );
> +}
> +
> +/**
> +  Check whether USB bus driver support this device.
> +
> +  @param  This                   The USB bus driver binding protocol.
> +  @param  Controller             The controller handle to check.
> +  @param  RemainingDevicePath    The remaining device path.
> +
> +  @retval EFI_SUCCESS            The bus supports this controller.
> +  @retval EFI_UNSUPPORTED        This device isn't supported.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +UsbDeviceDxeDriverSupported (
> +  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
> +  IN EFI_HANDLE                   Controller,
> +  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath
> +  )
> +{
> +  EFI_STATUS                Status;
> +  EFI_PCI_IO_PROTOCOL       *PciIo;
> +  USB_CLASSC                UsbClassCReg;
> +
> +
> +  Status = gBS->OpenProtocol (
> +                  Controller,
> +                  &gEfiPciIoProtocolGuid,
> +                  (VOID **) &PciIo,
> +                  This->DriverBindingHandle,
> +                  Controller,
> +                  EFI_OPEN_PROTOCOL_BY_DRIVER
> +                  );
> +
> +  if (EFI_ERROR (Status)) {
> +    return EFI_UNSUPPORTED;
> +  }
> +
> +  Status = PciIo->Pci.Read (
> +                        PciIo,
> +                        EfiPciIoWidthUint8,
> +                        PCI_CLASSCODE_OFFSET,
> +                        sizeof (USB_CLASSC) / sizeof (UINT8),
> +                        &UsbClassCReg
> +                        );
> +
> +  if (EFI_ERROR (Status)) {
> +    Status = EFI_UNSUPPORTED;
> +    goto ON_EXIT;
> +  }
> +
> +  //
> +  // Test whether the controller belongs to USB device type
> +  //
> +  // 0x0C03FE / 0x0C0380
> +  //
> +  if ((UsbClassCReg.BaseCode != PCI_CLASS_SERIAL) ||
> +      (UsbClassCReg.SubClassCode != PCI_CLASS_SERIAL_USB) ||
> +      ((UsbClassCReg.ProgInterface != PCI_IF_USBDEV) && (UsbClassCReg.ProgInterface != 0x80))) {
> +    Status = EFI_UNSUPPORTED;
> +  }
> +
> +ON_EXIT:
> +  gBS->CloseProtocol (
> +         Controller,
> +         &gEfiPciIoProtocolGuid,
> +         This->DriverBindingHandle,
> +         Controller
> +         );
> +
> +  return Status;
> +}
> +
> +
> +/**
> +  Start to process the controller.
> +
> +  @param  This                   The USB bus driver binding instance.
> +  @param  Controller             The controller to check.
> +  @param  RemainingDevicePath    The remaining device patch.
> +
> +  @retval EFI_SUCCESS            The controller is controlled by the usb bus.
> +  @retval EFI_ALREADY_STARTED    The controller is already controlled by the usb
> +                                 bus.
> +  @retval EFI_OUT_OF_RESOURCES   Failed to allocate resources.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +UsbDeviceDxeDriverStart (
> +  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
> +  IN EFI_HANDLE                   Controller,
> +  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath
> +  )
> +{
> +  EFI_STATUS            Status;
> +  USB_XDCI_DEV_CONTEXT  *UsbXdciDevContext;
> +  EFI_PCI_IO_PROTOCOL   *PciIo;
> +  EFI_EVENT             ExitBootServicesEvent;
> +
> +  DEBUG ((USB_FUIO_DEBUG_LOAD, "UsbFunIoEntryPoint - Entry\n"));
> +
> +  UsbXdciDevContext = NULL;
> +
> +  //
> +  // Provide protocol interface
> +  //
> +  //
> +  // Get the PCI I/O Protocol on PciHandle
> +  //
> +  Status = gBS->OpenProtocol (
> +                  Controller,
> +                  &gEfiPciIoProtocolGuid,
> +                  (VOID **) &PciIo,
> +                  This->DriverBindingHandle,
> +                  Controller,
> +                  EFI_OPEN_PROTOCOL_BY_DRIVER
> +                  );
> +
> +  if (EFI_ERROR (Status)) {
> +    goto ErrorExit;
> +  }
> +
> +  UsbXdciDevContext = AllocateZeroPool (sizeof (USB_XDCI_DEV_CONTEXT));
> +  if (UsbXdciDevContext == NULL) {
> +    Status = EFI_OUT_OF_RESOURCES;
> +    goto ErrorExit;
> +  }
> +
> +  //
> +  // Initialize the driver context
> +  //
> +  UsbXdciDevContext->StartUpController = FALSE;
> +  UsbXdciDevContext->XdciHandle = Controller;
> +  UsbXdciDevContext->FirstNodePtr = NULL;
> +  UsbXdciDevContext->Signature = EFI_USB_DEV_SIGNATURE;
> +
> +  PciIo->Pci.Read (
> +               PciIo,
> +               EfiPciIoWidthUint32,
> +               R_OTG_BAR0,
> +               1,
> +               &UsbXdciDevContext->XdciMmioBarAddr
> +               );
> +
> +  UsbXdciDevContext->XdciMmioBarAddr &= B_OTG_BAR0_BA;
> +  DEBUG ((USB_FUIO_DEBUG_INFO, "USB DEV mode IO addr 0x%08x\n", UsbXdciDevContext->XdciMmioBarAddr));
> +
> +  CopyMem (
> +    &(UsbXdciDevContext->UsbFunIoProtocol),
> +    &mUsbFunIoProtocol,
> +    sizeof (EFI_USBFN_IO_PROTOCOL)
> +    );
> +
> +  CopyMem (
> +    &(UsbXdciDevContext->UsbDevModeProtocol),
> +    &mUsbDeviceModeProtocol,
> +    sizeof (EFI_USB_DEVICE_MODE_PROTOCOL)
> +    );
> +
> +  Status = gBS->CreateEventEx (
> +                  EVT_NOTIFY_SIGNAL,
> +                  TPL_NOTIFY,
> +                  UsbDeviceDxeExitBootService,
> +                  UsbXdciDevContext,
> +                  &gEfiEventExitBootServicesGuid,
> +                  &ExitBootServicesEvent
> +                  );
> +  if (EFI_ERROR (Status)) {
> +    goto ErrorExit;
> +  }
> +
> +  Status = gBS->InstallMultipleProtocolInterfaces (
> +                  &UsbXdciDevContext->XdciHandle,
> +                  &gEfiUsbFnIoProtocolGuid,
> +                  &UsbXdciDevContext->UsbFunIoProtocol,
> +                  &gEfiUsbDeviceModeProtocolGuid,
> +                  &UsbXdciDevContext->UsbDevModeProtocol,
> +                  NULL
> +                  );
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((USB_FUIO_DEBUG_ERROR, "ERROR - Failed to install upper protocol, Status: %r\n", Status));
> +    goto ErrorExit;
> +  }
> +
> +  DEBUG ((USB_FUIO_DEBUG_LOAD, "Done - install upper protocol complete\n"));
> +  DEBUG ((USB_FUIO_DEBUG_LOAD, "UsbFunIoEntryPoint - Exit\n"));
> +  return Status;
> +
> +ErrorExit:
> +  gBS->CloseProtocol (
> +         Controller,
> +         &gEfiPciIoProtocolGuid,
> +         This->DriverBindingHandle,
> +         Controller
> +         );
> +
> +  if (UsbXdciDevContext != NULL) {
> +    if (UsbXdciDevContext->XdciPollTimer != NULL) {
> +      gBS->CloseEvent (UsbXdciDevContext->XdciPollTimer);
> +      UsbXdciDevContext->XdciPollTimer = NULL;
> +    }
> +    FreePool (UsbXdciDevContext);
> +  }
> +
> +  DEBUG ((USB_FUIO_DEBUG_ERROR, "ERROR - UsbFunIoEntryPoint - Exit\n"));
> +  return Status;
> +}
> +
> +/**
> +  Stop handle the controller by this USB bus driver.
> +
> +  @param  This                   The USB bus driver binding protocol.
> +  @param  Controller             The controller to release.
> +  @param  NumberOfChildren       The child of USB bus that opened controller
> +                                 BY_CHILD.
> +  @param  ChildHandleBuffer      The array of child handle.
> +
> +  @retval EFI_SUCCESS            The controller or children are stopped.
> +  @retval EFI_DEVICE_ERROR       Failed to stop the driver.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +UsbDeviceDxeDriverStop (
> +  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
> +  IN EFI_HANDLE                   Controller,
> +  IN UINTN                        NumberOfChildren,
> +  IN EFI_HANDLE                   *ChildHandleBuffer
> +  )
> +{
> +  EFI_USBFN_IO_PROTOCOL           *UsbFunIoProtocol;
> +  EFI_STATUS                      Status;
> +  USB_XDCI_DEV_CONTEXT            *UsbXdciDevContext;
> +
> +
> +  //
> +  // Locate USB_BUS for the current host controller
> +  //
> +  Status = gBS->OpenProtocol (
> +                  Controller,
> +                  &gEfiUsbFnIoProtocolGuid,
> +                  (VOID **)&UsbFunIoProtocol,
> +                  This->DriverBindingHandle,
> +                  Controller,
> +                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
> +                  );
> +
> +
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  UsbXdciDevContext = USBFUIO_CONTEXT_FROM_PROTOCOL (UsbFunIoProtocol);
> +
> +  //
> +  // free pool
> +  //
> +  while (UsbXdciDevContext->FirstNodePtr != NULL) {
> +    RemoveNode (UsbFunIoProtocol, UsbXdciDevContext->FirstNodePtr);
> +  }
> +
> +  Status = gBS->UninstallMultipleProtocolInterfaces (
> +                  UsbXdciDevContext->XdciHandle,
> +                  &gEfiUsbFnIoProtocolGuid,
> +                  &UsbXdciDevContext->UsbFunIoProtocol,
> +                  &gEfiUsbDeviceModeProtocolGuid,
> +                  &UsbXdciDevContext->UsbDevModeProtocol,
> +                  NULL
> +                  );
> +
> +  if (UsbXdciDevContext->StartUpController == TRUE) {
> +    Status = StopController (UsbFunIoProtocol);
> +    DEBUG ((USB_FUIO_DEBUG_INFO, "USB DEV mode STOP UsbFnDeInitDevice %r\n", Status));
> +  }
> +
> +  if (UsbXdciDevContext->XdciPollTimer != NULL) {
> +    gBS->SetTimer (UsbXdciDevContext->XdciPollTimer, TimerCancel, 0);
> +    gBS->CloseEvent (UsbXdciDevContext->XdciPollTimer);
> +    UsbXdciDevContext->XdciPollTimer = NULL;
> +  }
> +
> +  gBS->CloseProtocol (
> +         Controller,
> +         &gEfiPciIoProtocolGuid,
> +         This->DriverBindingHandle,
> +         Controller
> +         );
> +
> +  FreePool (UsbXdciDevContext);
> +  return EFI_SUCCESS;
> +}
> +
> diff --git a/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbDeviceDxe.h b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbDeviceDxe.h
> new file mode 100644
> index 0000000000..36620f9b12
> --- /dev/null
> +++ b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbDeviceDxe.h
> @@ -0,0 +1,159 @@
> +/** @file
> +  Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR>
> +
> +  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.
> +
> +**/
> +
> +#ifndef __USB_DEVICE_DXE_H__
> +#define __USB_DEVICE_DXE_H__
> +
> +#include <Uefi.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/DevicePathLib.h>
> +#include <Library/DriverLib.h>
> +#include <Library/PcdLib.h>
> +#include <Library/IoLib.h>
> +#include <Protocol/EfiUsbFnIo.h>
> +#include <Protocol/UsbDeviceModeProtocol.h>
> +#include <PlatformBaseAddresses.h>
> +#include <ScAccess.h>
> +#include "UsbFuncIo.h"
> +#include "UsbDeviceMode.h"
> +
> +
> +#define PCI_IF_USBDEV                      0xFE
> +
> +#define EFI_USB_DEV_SIGNATURE              0x55534244 //"USBD"
> +#define USBFUIO_CONTEXT_FROM_PROTOCOL(a)   CR (a, USB_XDCI_DEV_CONTEXT, UsbFunIoProtocol, EFI_USB_DEV_SIGNATURE)
> +#define USBUSBD_CONTEXT_FROM_PROTOCOL(a)   CR (a, USB_XDCI_DEV_CONTEXT, UsbDevModeProtocol, EFI_USB_DEV_SIGNATURE)
> +
> +
> +typedef struct _USB_FUIO_EVENT_NODE   USB_FUIO_EVENT_NODE;
> +
> +#pragma pack(1)
> +struct _USB_FUIO_EVENT_NODE{
> +  EFI_USBFN_MESSAGE            Message;
> +  UINTN                        PayloadSize;
> +  EFI_USBFN_MESSAGE_PAYLOAD    Payload;
> +  USB_FUIO_EVENT_NODE          *Nextptr;
> +};
> +
> +typedef struct {
> +  UINTN                         Signature;
> +  UINTN                         XdciMmioBarAddr;
> +  EFI_HANDLE                    XdciHandle;
> +  //
> +  // Timer to handle EndPoint event periodically.
> +  //
> +  EFI_EVENT                     XdciPollTimer;
> +  EFI_USB_DEVICE_MODE_PROTOCOL  UsbDevModeProtocol;
> +  EFI_USBFN_IO_PROTOCOL         UsbFunIoProtocol;
> +
> +  //
> +  // Structure members used by UsbFunIoProtocol.
> +  //
> +  USB_MEM_NODE                  *FirstNodePtr;
> +  EFI_USB_DEVICE_INFO           *DevInfoPtr;
> +  EFI_USB_CONFIG_INFO           IndexPtrConfig;
> +  EFI_USB_INTERFACE_INFO        IndexPtrInteface;
> +  USB_DEVICE_ENDPOINT_INFO      IndexPtrInEp;
> +  USB_DEVICE_ENDPOINT_INFO      IndexPtrOutEp;
> +  XDCI_CORE_HANDLE              *XdciDrvIfHandle;
> +  USB_DEV_CORE                  *DrvCore;
> +  UINT16                        VendorId;
> +  UINT16                        DeviceId;
> +  USBD_EP_XFER_REC              EndPointXferRec[DWC_XDCI_MAX_ENDPOINTS];
> +  BOOLEAN                       StartUpController;
> +  BOOLEAN                       DevReConnect;
> +  BOOLEAN                       DevResetFlag;
> +  EFI_EVENT                     TimerEvent;
> +  USB_FUIO_EVENT_NODE           *EventNodePtr;
> +  //
> +  // Following structure members are used by UsbDevModeProtocol.
> +  //
> +
> +} USB_XDCI_DEV_CONTEXT;
> +#pragma pack()
> +
> +
> +
> +/**
> +  Check whether USB bus driver support this device.
> +
> +  @param  This                   The USB bus driver binding protocol.
> +  @param  Controller             The controller handle to check.
> +  @param  RemainingDevicePath    The remaining device path.
> +
> +  @retval EFI_SUCCESS            The bus supports this controller.
> +  @retval EFI_UNSUPPORTED        This device isn't supported.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +UsbDeviceDxeDriverSupported (
> +  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
> +  IN EFI_HANDLE                   Controller,
> +  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath
> +  );
> +
> +/**
> +  Start to process the controller.
> +
> +  @param  This                   The USB bus driver binding instance.
> +  @param  Controller             The controller to check.
> +  @param  RemainingDevicePath    The remaining device patch.
> +
> +  @retval EFI_SUCCESS            The controller is controlled by the usb bus.
> +  @retval EFI_ALREADY_STARTED    The controller is already controlled by the usb
> +                                 bus.
> +  @retval EFI_OUT_OF_RESOURCES   Failed to allocate resources.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +UsbDeviceDxeDriverStart (
> +  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
> +  IN EFI_HANDLE                   Controller,
> +  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath
> +  );
> +
> +/**
> +  Stop handle the controller by this USB bus driver.
> +
> +  @param  This                   The USB bus driver binding protocol.
> +  @param  Controller             The controller to release.
> +  @param  NumberOfChildren       The child of USB bus that opened controller
> +                                 BY_CHILD.
> +  @param  ChildHandleBuffer      The array of child handle.
> +
> +  @retval EFI_SUCCESS            The controller or children are stopped.
> +  @retval EFI_DEVICE_ERROR       Failed to stop the driver.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +UsbDeviceDxeDriverStop (
> +  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
> +  IN EFI_HANDLE                   Controller,
> +  IN UINTN                        NumberOfChildren,
> +  IN EFI_HANDLE                   *ChildHandleBuffer
> +  );
> +
> +VOID
> +EFIAPI
> +PlatformSpecificInit (
> +  VOID
> +  );
> +
> +extern EFI_COMPONENT_NAME_PROTOCOL    mUsbDeviceDxeComponentName;
> +extern EFI_COMPONENT_NAME2_PROTOCOL   mUsbDeviceDxeComponentName2;
> +
> +#endif
> +
> diff --git a/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbDeviceDxe.inf b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbDeviceDxe.inf
> new file mode 100644
> index 0000000000..acf5021327
> --- /dev/null
> +++ b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbDeviceDxe.inf
> @@ -0,0 +1,74 @@
> +## @file
> +#
> +#  Copyright (c) 2008 - 2017, Intel Corporation. All rights reserved.<BR>
> +#
> +#  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.
> +#
> +##
> +
> +[Defines]
> +  INF_VERSION                    = 0x00010005
> +  BASE_NAME                      = UsbDeviceDxe
> +  FILE_GUID                      = 42CF2D4A-78B4-4B80-80F9-96A83A630D70
> +  MODULE_TYPE                    = UEFI_DRIVER
> +  VERSION_STRING                 = 1.0
> +  ENTRY_POINT                    = UsbDeviceDxeEntryPoint
> +
> +#
> +# The following information is for reference only and not required by the build tools.
> +#
> +#  VALID_ARCHITECTURES           = IA32 X64
> +#
> +
> +[Sources.common]
> +  UsbDeviceDxe.c
> +  UsbFuncIo.c
> +  UsbIoNode.c
> +  ComponentName.c
> +  UsbDeviceMode.c
> +  XdciDevice.c
> +  XdciDWC.c
> +  XdciTable.c
> +  XdciUtility.c
> +
> +[Packages]
> +  MdePkg/MdePkg.dec
> +  BroxtonSiPkg/BroxtonSiPkg.dec
> +  BroxtonPlatformPkg/PlatformPkg.dec
> +
> +[LibraryClasses]
> +  BaseMemoryLib
> +  DebugLib
> +  DevicePathLib
> +  MemoryAllocationLib
> +  TimerLib
> +  PcdLib
> +  UefiBootServicesTableLib
> +  UefiDriverEntryPoint
> +  UefiLib
> +  PmicLib
> +
> +[Protocols]
> +  gEfiUsbDeviceModeProtocolGuid
> +  gEfiUsbFnIoProtocolGuid
> +  gEfiPciIoProtocolGuid
> +
> +[Pcd]
> +  gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress
> +
> +[Guids]
> +  gEfiEventExitBootServicesGuid
> +
> +#[BuildOptions]
> +#  MSFT:*_*_*_CC_FLAGS = /D SUPPORT_SUPER_SPEED
> +#  GCC:*_*_*_CC_FLAGS = -DSUPPORT_SUPER_SPEED
> +
> +[Depex]
> +  TRUE
> +
> diff --git a/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbDeviceMode.c b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbDeviceMode.c
> new file mode 100644
> index 0000000000..48a37a37fb
> --- /dev/null
> +++ b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbDeviceMode.c
> @@ -0,0 +1,1489 @@
> +/** @file
> +  Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR>
> +
> +  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.
> +
> +**/
> +
> +#include <Base.h>
> +#include <Library/BaseLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Library/IoLib.h>
> +#include <PlatformBaseAddresses.h>
> +#include <ScAccess.h>
> +#include "XdciUtility.h"
> +#include "UsbDeviceMode.h"
> +#include "UsbDeviceDxe.h"
> +
> +//
> +// Global USBD driver object. This is the main private driver object
> +// that contains all data needed for this driver to operate.
> +//
> +USB_DEVICE_DRIVER_OBJ mDrvObj;
> +
> +//
> +// Global data IO transaction request object
> +//
> +USB_DEVICE_IO_REQ  mCtrlIoReq = {
> +  //
> +  // IO information containing the Buffer and data size
> +  //
> +  {
> +    NULL,
> +    0,
> +  },
> +  //
> +  // Note: This object is used for Control Ep transfers only
> +  // therefore the endpoint info must always be NULL
> +  //
> +  {
> +    NULL,
> +    NULL,
> +  }
> +};
> +
> +//
> +// global flag to signal device event processing loop to run/stop
> +//
> +BOOLEAN mXdciRun = FALSE;
> +
> +STATIC VOID
> +XhciSwitchSwid(BOOLEAN enable)
> +{
> +  UINTN                             XhciPciMmBase;
> +  EFI_PHYSICAL_ADDRESS              XhciMemBaseAddress;
> +  UINT32                            DualRoleCfg0;
> +  UINT32                            DualRoleCfg1;
> +
> +  XhciPciMmBase = MmPciAddress (0, 0, PCI_DEVICE_NUMBER_XHCI, PCI_FUNCTION_NUMBER_XHCI, 0);
> +  XhciMemBaseAddress = MmioRead32 ((UINTN) (XhciPciMmBase + R_XHCI_MEM_BASE)) & B_XHCI_MEM_BASE_BA;
> +  DEBUG ((DEBUG_INFO, "XhciPciMmBase=%x, XhciMemBaseAddress=%x\n", XhciPciMmBase, XhciMemBaseAddress));
> +
> +  DualRoleCfg0 = MmioRead32 ((UINTN)(XhciMemBaseAddress + R_XHCI_MEM_DUAL_ROLE_CFG0));
> +  if (enable) {
> +    DualRoleCfg0 = DualRoleCfg0 | (1 << 24) | (1 << 21) | (1 << 20);
> +    DEBUG ((DEBUG_INFO, "DualRoleCfg0 : Set SW ID : 0x%x \n", DualRoleCfg0));
> +  }
> +  else {
> +    DualRoleCfg0 = DualRoleCfg0 & ~(1 << 24) & ~(1 << 21) & ~(1 << 20);
> +    DEBUG ((DEBUG_INFO, "DualRoleCfg0 : Clear SW ID : 0x%x \n", DualRoleCfg0));
> +  }
> +  MmioWrite32 ((UINTN)(XhciMemBaseAddress + R_XHCI_MEM_DUAL_ROLE_CFG0), DualRoleCfg0);
> +
> +  DualRoleCfg1 = MmioRead32 ((UINTN)(XhciMemBaseAddress + R_XHCI_MEM_DUAL_ROLE_CFG1));
> +  DEBUG ((DEBUG_INFO, "DualRoleCfg1 : 0x%x \n", DualRoleCfg1));
> +}
> +
> +VOID
> +EFIAPI
> +UsbdMonitorEvents (
> +  IN EFI_EVENT            Event,
> +  IN VOID                 *Context
> +  )
> +{
> +  USB_XDCI_DEV_CONTEXT    *XdciDevContext;
> +  UINT32                  EventCount;
> +  UINT32                  PreEventCount;
> +  UINT32                  LoopCount;
> +
> +  XdciDevContext = (USB_XDCI_DEV_CONTEXT *) Context;
> +  EventCount = UsbRegRead ((UINT32)XdciDevContext->XdciMmioBarAddr, DWC_XDCI_EVNTCOUNT_REG (0));
> +  if (EventCount == 0) {
> +    return;
> +  }
> +
> +  LoopCount = 0;
> +  PreEventCount = EventCount;
> +  while (EventCount != 0) {
> +    if (UsbDeviceIsrRoutineTimerBased (mDrvObj.XdciDrvObj) != EFI_SUCCESS) {
> +      DEBUG ((DEBUG_INFO, "UsbDeviceRun() - Failed to execute event ISR\n"));
> +    }
> +    EventCount = UsbRegRead ((UINT32)XdciDevContext->XdciMmioBarAddr, DWC_XDCI_EVNTCOUNT_REG (0));
> +    if (PreEventCount == EventCount) {
> +      LoopCount++;
> +      if (LoopCount >= 5) {
> +        DEBUG ((DEBUG_INFO, "USB is working on a long event...\n"));
> +        break;
> +      }
> +    } else {
> +      LoopCount = 0;
> +    }
> +  }
> +
> +  return;
> +}
> +
> +/**
> +  Initializes the XDCI core
> +
> +  @param MmioBar       Address of MMIO BAR
> +  @param XdciHndl      Double pointer to for XDCI layer to set as an
> +                       opaque handle to the driver to be used in subsequent
> +                       interactions with the XDCI layer.
> +
> +  @return EFI_SUCCESS if successfully initialized XDCI, EFI_DEVICE_ERROR otherwise
> +
> +**/
> +EFI_STATUS
> +UsbdInit (
> +  IN UINT32    MmioBar,
> +  IN VOID      **XdciHndl
> +  )
> +{
> +  EFI_STATUS               Status = EFI_DEVICE_ERROR;
> +  USB_DEV_CONFIG_PARAMS    ConfigParams;
> +
> +  XhciSwitchSwid(TRUE);
> +
> +  DEBUG ((DEBUG_INFO, "UsbdInit start\n"));
> +  ConfigParams.ControllerId = USB_ID_DWC_XDCI;
> +  ConfigParams.BaseAddress  = MmioBar;
> +  ConfigParams.Role = USB_ROLE_DEVICE;
> +  ConfigParams.Speed = USB_SPEED_SUPER;
> +
> +  Status = UsbDeviceInit (&ConfigParams, XdciHndl);
> +
> +  DEBUG ((DEBUG_INFO, "UsbdInit status is %x\n", Status));
> +  DEBUG ((DEBUG_INFO, "ConfigParams.BaseAddress 0x%x\n", ConfigParams.BaseAddress));
> +
> +  return Status;
> +}
> +
> +
> +/**
> +  Copies relevant endpoint data from standard USB endpoint descriptors
> +  to the usbEpInfo structure used by the XDCI
> +
> +  @param EpDest   destination structure
> +  @param EpSrc    source structure
> +
> +  @return VOID
> +
> +**/
> +VOID
> +UsbdSetEpInfo (
> +  IN USB_EP_INFO                 *EpDest,
> +  IN USB_DEVICE_ENDPOINT_INFO    *EpSrc
> +  )
> +{
> +  EFI_USB_ENDPOINT_DESCRIPTOR              *EpDesc = NULL;
> +  EFI_USB_ENDPOINT_COMPANION_DESCRIPTOR    *EpCompDesc = NULL;
> +
> +  //
> +  // start by clearing all data in the destination
> +  //
> +  SetMem (EpDest, sizeof(USB_EP_INFO), 0);
> +  EpDesc = EpSrc->EndpointDesc;
> +  EpCompDesc = EpSrc->EndpointCompDesc;
> +
> +  if (EpDesc != NULL) {
> +    EpDest->EpNum = EpDesc->EndpointAddress & 0x0F; //Bits 0-3 are ep num
> +    EpDest->EpDir = ((EpDesc->EndpointAddress & USB_ENDPOINT_DIR_IN) > 0) ? UsbEpDirIn : UsbEpDirOut;
> +    EpDest->EpType = EpDesc->Attributes & USB_ENDPOINT_TYPE_MASK;
> +    EpDest->MaxPktSize = EpDesc->MaxPacketSize;
> +    EpDest->Interval = EpDesc->Interval;
> +  }
> +  if (EpCompDesc != NULL) {
> +    EpDest->MaxStreams = EpCompDesc->Attributes & USB_EP_BULK_BM_ATTR_MASK;
> +    EpDest->BurstSize = EpCompDesc->MaxBurst;
> +    EpDest->Mult = EpCompDesc->BytesPerInterval;
> +  }
> +
> +  return;
> +}
> +
> +
> +/**
> +  Initializes the given endpoint
> +
> +  @param XdciHndl  Pointer (handle) to the XDCI driver object
> +  @param DevEpInfo Pointer to endpoint info structure
> +                   for the endpoint to initialize
> +
> +  @return EFI_SUCCESS if operation succeeded, EFI_DEVICE_ERROR otherwise
> +
> +**/
> +EFI_STATUS
> +UsbdInitEp (
> +  IN VOID                      *XdciHndl,
> +  IN USB_DEVICE_ENDPOINT_INFO  *DevEpInfo
> +  )
> +{
> +  EFI_STATUS   Status = EFI_DEVICE_ERROR;
> +  USB_EP_INFO  EpInfo;
> +
> +  UsbdSetEpInfo (&EpInfo, DevEpInfo);
> +  Status = UsbDeviceInitEp (XdciHndl, &EpInfo);
> +
> +  return Status;
> +}
> +
> +
> +/**
> +  Callback handler used when transfer operations complete. Calls
> +  upper layer routine to handle the operation.
> +
> +  @param XdciHndl  Pointer (handle) to the XDCI driver object
> +  @param XferReq   Pointer to the transfer request structure
> +
> +  @return VOID
> +
> +**/
> +VOID
> +EFIAPI
> +UsbdXferDoneHndlr (
> +  IN VOID                    *XdciHndl,
> +  IN USB_XFER_REQUEST        *XferReq
> +  )
> +{
> +  EFI_USB_DEVICE_XFER_INFO  XferInfo;
> +
> +  DEBUG ((DEBUG_INFO, "UsbdXferDoneHndlr\n"));
> +
> +  XferInfo.EndpointNum = (UINT8)XferReq->EpInfo.EpNum;
> +  XferInfo.EndpointDir = XferReq->EpInfo.EpDir;
> +  XferInfo.EndpointType = XferReq->EpInfo.EpType;
> +  XferInfo.Buffer = XferReq->XferBuffer;
> +  XferInfo.Length = XferReq->ActualXferLen;
> +
> +  //
> +  // If this is a non-control transfer complete, notify the class driver
> +  //
> +  if (XferInfo.EndpointNum > 0) {
> +    if (mDrvObj.UsbdDevObj->DataCallback != NULL) {
> +      mDrvObj.UsbdDevObj->DataCallback (&XferInfo);
> +    }
> +  }
> +
> +  return;
> +}
> +
> +
> +/**
> +  Queue a request to transmit data
> +
> +  @param XdciHndl  Pointer (handle) to the XDCI driver object
> +  @param IoReq     Pointer to IO structure containing details of the
> +                   transfer request
> +
> +  @return EFI_SUCCESS if operation succeeded, EFI_DEVICE_ERROR otherwise
> +
> +**/
> +EFI_STATUS
> +UsbdEpTxData (
> +  IN VOID               *XdciHndl,
> +  IN USB_DEVICE_IO_REQ  *IoReq
> +  )
> +{
> +  EFI_STATUS        Status = EFI_DEVICE_ERROR;
> +  USB_XFER_REQUEST  TxReq;
> +
> +  //
> +  //set endpoint data
> +  //
> +  UsbdSetEpInfo (&(TxReq.EpInfo), &(IoReq->EndpointInfo)); // set endpoint data
> +
> +  //
> +  //if this is a control endpoint, set the number and direction
> +  //
> +  if (IoReq->EndpointInfo.EndpointDesc == NULL) {
> +    TxReq.EpInfo.EpNum = 0;
> +    TxReq.EpInfo.EpDir = UsbEpDirIn;
> +  }
> +
> +  //
> +  // setup the trasfer request
> +  //
> +  TxReq.XferBuffer = IoReq->IoInfo.Buffer;
> +  TxReq.XferLen = IoReq->IoInfo.Length;
> +  TxReq.XferDone = UsbdXferDoneHndlr;
> +
> +  DEBUG ((DEBUG_INFO,  "TX REQUEST: EpNum: 0x%x, epDir: 0x%x, epType: 0x%x, MaxPktSize: 0x%x\n",\
> +          TxReq.EpInfo.EpNum, TxReq.EpInfo.EpDir, TxReq.EpInfo.EpType, TxReq.EpInfo.MaxPktSize));
> +
> +  Status = UsbXdciDeviceEpTxData (XdciHndl, &TxReq);
> +
> +  return Status;
> +}
> +
> +
> +/**
> +  Queue a request to receive data
> +
> +  @param XdciHndl  Pointer (handle) to the XDCI driver object
> +  @param IoReq     Pointer to IO structure containing details of the
> +                   receive request
> +
> +  @return EFI_SUCCESS if operation succeeded, EFI_DEVICE_ERROR otherwise
> +
> +**/
> +EFI_STATUS
> +UsbdEpRxData (
> +  IN VOID               *XdciHndl,
> +  IN USB_DEVICE_IO_REQ  *IoReq
> +  )
> +{
> +  EFI_STATUS        Status = EFI_DEVICE_ERROR;
> +  USB_XFER_REQUEST  RxReq;
> +  UINT32            ReqPacket;
> +
> +  DEBUG ((DEBUG_INFO,  "RX REQUEST in: IoReq->IoInfo.Length: 0x%x\n", IoReq->IoInfo.Length));
> +  DEBUG ((DEBUG_INFO,  "RX REQUEST in: MaxPacketSize: 0x%x\n", IoReq->EndpointInfo.EndpointDesc->MaxPacketSize));
> +
> +  if (IoReq->EndpointInfo.EndpointDesc->MaxPacketSize == 0) {
> +    return EFI_DEVICE_ERROR;
> +  }
> +
> +  //
> +  // set endpoint data
> +  //
> +  UsbdSetEpInfo (&(RxReq.EpInfo), &(IoReq->EndpointInfo));
> +
> +  //
> +  // setup the trasfer request
> +  //
> +  RxReq.XferBuffer = IoReq->IoInfo.Buffer;
> +
> +  //
> +  // Transfer length should be multiple of USB packet size.
> +  //
> +  ReqPacket = IoReq->IoInfo.Length / IoReq->EndpointInfo.EndpointDesc->MaxPacketSize;
> +  ReqPacket = ((IoReq->IoInfo.Length % IoReq->EndpointInfo.EndpointDesc->MaxPacketSize) == 0)? ReqPacket : ReqPacket + 1;
> +  RxReq.XferLen = ReqPacket * IoReq->EndpointInfo.EndpointDesc->MaxPacketSize;
> +
> +  RxReq.XferDone = UsbdXferDoneHndlr;
> +
> +  DEBUG ((DEBUG_INFO,  "RX REQUEST: EpNum: 0x%x, epDir: 0x%x, epType: 0x%x\n",\
> +          RxReq.EpInfo.EpNum, RxReq.EpInfo.EpDir, RxReq.EpInfo.EpType));
> +  DEBUG ((DEBUG_INFO,  "RX REQUEST send: XferLen: 0x%x\n", RxReq.XferLen));
> +
> +  Status = UsbXdciDeviceEpRxData (XdciHndl, &RxReq);
> +
> +  return Status;
> +}
> +
> +
> +/**
> +  Callback used to handle Reset events from the XDCI
> +
> +  @param Param Pointer to a generic callback parameter structure
> +
> +  @return XDCI usb status
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +UsbdResetEvtHndlr (
> +  IN USB_DEVICE_CALLBACK_PARAM  *Param
> +  )
> +{
> +  EFI_STATUS    Status = EFI_DEVICE_ERROR;
> +
> +  DEBUG ((DEBUG_INFO, "UsbdResetEvtHndlr\n"));
> +
> +  //
> +  // reset device address to 0
> +  //
> +  Status = UsbDeviceSetAddress (mDrvObj.XdciDrvObj, 0x0);
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((DEBUG_INFO, "UsbdResetHdlr() - Failed to set address in XDCI\n"));
> +  }
> +
> +  return Status;
> +}
> +
> +
> +/**
> +  Callback used to handle Connection done events from the XDCI
> +
> +  @param Param Pointer to a generic callback parameter structure
> +
> +  @return XDCI usb status
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +UsbdConnDoneEvtHndlr (
> +  IN USB_DEVICE_CALLBACK_PARAM *Param
> +  )
> +{
> +  EFI_STATUS    Status = EFI_DEVICE_ERROR;
> +
> +  DEBUG ((DEBUG_INFO, "UsbdConnDoneEvtHndlr\n"));
> +
> +  //
> +  //reset device address to 0
> +  //
> +  Status = UsbDeviceSetAddress (mDrvObj.XdciDrvObj, 0x0);
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((DEBUG_INFO, "UsbdConnDoneHdlr() - Failed to set address in XDCI\n"));
> +  }
> +
> +  //
> +  // set the device state to attached/connected
> +  //
> +  mDrvObj.State = UsbDevStateAttached;
> +
> +  return Status;
> +}
> +
> +
> +/**
> +  Callback used to handle Control Endpoint Setup events from the XDCI
> +
> +  @param Param Pointer to a generic callback parameter structure
> +
> +  @return XDCI usb status
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +UsbdSetupEvtHndlr (
> +  IN USB_DEVICE_CALLBACK_PARAM *Param
> +  )
> +{
> +  EFI_STATUS              Status = EFI_SUCCESS;
> +  EFI_USB_DEVICE_REQUEST  Req;
> +
> +  DEBUG ((DEBUG_INFO, "UsbdSetupEvtHndlr\n"));
> +
> +  //
> +  // Fill out request object from the incomming Buffer
> +  //
> +  CopyMem (&Req, Param->Buffer, sizeof(EFI_USB_DEVICE_REQUEST));
> +
> +  Status = UsbdSetupHdlr (&Req);
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((DEBUG_INFO, "UsbdSetupEvtHndlr: EFI_DEVICE_ERROR\n"));
> +  }
> +
> +  return Status;
> +}
> +
> +
> +/**
> + * Callback used to handle XferNotReady events from the XDCI
> + *
> + * @param Param Pointer to a generic callback parameter structure
> + *
> + * @return XDCI usb status
> + */
> +EFI_STATUS
> +EFIAPI
> +UsbdNrdyEvtHndlr (
> +  IN USB_DEVICE_CALLBACK_PARAM *Param
> +  )
> +{
> +  DEBUG ((DEBUG_INFO, "UsbdNrdyEvtHndlr\n"));
> +  return EFI_SUCCESS;
> +}
> +
> +
> +/**
> +  Registers callbacks for event handlers with the XDCI layer.
> +  The functions will be called as the registered events are triggered.
> +
> +  @param  XdciHndl to XDCI core driver
> +  @return EFI_SUCCESS if successful, EFI_DEVICE_ERROR otherwise
> +
> +**/
> +EFI_STATUS
> +UsbdRegisterCallbacks (
> +  IN VOID  *XdciHndl
> +  )
> +{
> +  if (UsbDeviceRegisterCallback (XdciHndl, USB_DEVICE_RESET_EVENT, UsbdResetEvtHndlr) != EFI_SUCCESS) {
> +    goto UdciRegCallbackError;
> +  }
> +
> +  if (UsbDeviceRegisterCallback (XdciHndl, USB_DEVICE_CONNECTION_DONE, UsbdConnDoneEvtHndlr) != EFI_SUCCESS) {
> +    goto UdciRegCallbackError;
> +  }
> +
> +  if (UsbDeviceRegisterCallback (XdciHndl, USB_DEVICE_SETUP_PKT_RECEIVED, UsbdSetupEvtHndlr) != EFI_SUCCESS) {
> +    goto UdciRegCallbackError;
> +  }
> +
> +  if (UsbDeviceRegisterCallback (XdciHndl, USB_DEVICE_XFER_NRDY, UsbdNrdyEvtHndlr) != EFI_SUCCESS) {
> +    goto UdciRegCallbackError;
> +  }
> +
> +  return EFI_SUCCESS;
> +
> +UdciRegCallbackError:
> +  return EFI_DEVICE_ERROR;
> +}
> +
> +
> +/**
> +  Returns the configuration descriptor for this device. The data
> +  Buffer returned will also contain all downstream interface and
> +  endpoint Buffers.
> +
> +  @param Buffer    Pointer to destination Buffer to copy descriptor data to
> +  @param DescIndex the index of the descriptor to return
> +  @param ReqLen    the length in bytes of the request Buffer
> +  @param DataLen   Pointer whos value is to be filled with the byte count of
> +                   data copied to the output Buffer
> +
> +  @return EFI_SUCCESS if descritor successfully copied, EFI_DEVICE_ERROR otherwise
> +
> +**/
> +EFI_STATUS
> +UsbdGetConfigDesc (
> +  IN VOID      *Buffer,
> +  IN UINT8     DescIndex,
> +  IN UINT32    ReqLen,
> +  IN UINT32    *DataLen
> +  )
> +{
> +  EFI_STATUS             Status = EFI_DEVICE_ERROR;
> +  UINT8                  NumConfigs = 0;
> +  UINT32                 ConfigLen = 0;
> +  USB_DEVICE_CONFIG_OBJ  *ConfigObj = NULL;
> +  VOID                   *Descriptor = 0;
> +  UINT32                 Length = 0;
> +
> +  DEBUG ((DEBUG_INFO, "UsbdGetConfigDesc()\n"));
> +
> +  //
> +  // For a CONFIGURATION request we send back all descriptors branching out
> +  // from this descriptor including the INTERFACE and ENDPOINT descriptors
> +  //
> +  //
> +  // Verify the requested configuration exists - check valid index
> +  //
> +  NumConfigs = mDrvObj.UsbdDevObj->DeviceDesc->NumConfigurations;
> +
> +  if (DescIndex < NumConfigs) {
> +    //
> +    // get the configuration object using the index Offset
> +    //
> +    ConfigObj = (mDrvObj.UsbdDevObj->ConfigObjs + DescIndex);
> +    //
> +    // get the complete configuration Buffer block including Interface and Endpoint data
> +    //
> +    Descriptor = ConfigObj->ConfigAll;
> +    //
> +    // The config descriptor TotalLength has the full value for all desc Buffers
> +    //
> +    ConfigLen = ConfigObj->ConfigDesc->TotalLength;
> +    //
> +    // copy the data to the output Buffer
> +    //
> +    Length = MIN (ReqLen, ConfigLen);
> +    CopyMem (Buffer, Descriptor, Length);
> +    *DataLen = Length;
> +    Status = EFI_SUCCESS;
> +  } else {
> +    DEBUG ((DEBUG_INFO, "UsbdGetConfigDesc() - Invalid Config index: %i\n", DescIndex));
> +  }
> +
> +  if (Status == EFI_SUCCESS) {
> +    if (ConfigObj != NULL) {
> +      PrintConfigDescriptor (ConfigObj->ConfigDesc);
> +    }
> +  }
> +
> +  return Status;
> +}
> +
> +
> +/**
> +  Sets the active configuration to the selected configuration index if it exists
> +
> +  @param CfgValue  the configuration value to set
> +
> +  @return EFI_SUCCESS if the configuration was set, EFI_DEVICE_ERROR otherwise
> +
> +**/
> +EFI_STATUS
> +UsbdSetConfig (
> +  UINT8  CfgValue
> +  )
> +{
> +  EFI_STATUS                 Status = EFI_DEVICE_ERROR;
> +  UINT8                      numConfigs = 0;
> +  USB_DEVICE_CONFIG_OBJ      *pConfigObj = NULL;
> +  USB_DEVICE_INTERFACE_OBJ   *pIfObj = NULL;
> +  USB_DEVICE_ENDPOINT_OBJ    *pEpObj = NULL;
> +  UINT8                      cfgItr = 0;
> +  UINT8                      ifItr = 0;
> +  UINT8                      epItr = 0;
> +  USB_DEVICE_ENDPOINT_INFO   EpInfo;
> +  USB_EP_INFO                UsbEpInfo;
> +
> +  DEBUG ((DEBUG_INFO, "UsbdSetConfig()\n"));
> +  //
> +  // Verify the requested configuration exists - check valid index
> +  //
> +  numConfigs = mDrvObj.UsbdDevObj->DeviceDesc->NumConfigurations;
> +
> +  if (CfgValue != 0) {
> +    //
> +    // Search for a matching configuration
> +    //
> +    for (cfgItr = 0; cfgItr < numConfigs; cfgItr++) {
> +      pConfigObj = (mDrvObj.UsbdDevObj->ConfigObjs + cfgItr);
> +      if (pConfigObj->ConfigDesc->ConfigurationValue == CfgValue) {
> +
> +        //
> +        // Set the active configuration object
> +        //
> +        mDrvObj.ActiveConfigObj = pConfigObj;
> +        //
> +        // Find all interface objects for this configuration
> +        //
> +        for (ifItr = 0; ifItr < pConfigObj->ConfigDesc->NumInterfaces; ifItr++) {
> +          pIfObj = (pConfigObj->InterfaceObjs + ifItr);
> +          //
> +          // Configure the Endpoints in the XDCI
> +          //
> +          for (epItr = 0; epItr < pIfObj->InterfaceDesc->NumEndpoints; epItr++) {
> +            pEpObj = (pIfObj->EndpointObjs + epItr);
> +
> +            EpInfo.EndpointDesc = pEpObj->EndpointDesc;
> +            EpInfo.EndpointCompDesc = pEpObj->EndpointCompDesc;
> +
> +            if (UsbdInitEp (mDrvObj.XdciDrvObj, &EpInfo) == EFI_SUCCESS) {
> +              UsbdSetEpInfo(&UsbEpInfo, &EpInfo);
> +              if (UsbDeviceEpEnable (mDrvObj.XdciDrvObj, &UsbEpInfo) == EFI_SUCCESS) {
> +                Status = EFI_SUCCESS;
> +              } else {
> +                DEBUG ((DEBUG_INFO, "UsbdSetConfig() - Failed to enable endpoint\n"));
> +              }
> +            } else {
> +              DEBUG ((DEBUG_INFO, "UsbdSetConfig() - Failed to initialize endpoint\n"));
> +            }
> +          }
> +        }
> +        //
> +        // Let the class driver know it is configured
> +        //
> +        if (Status == EFI_SUCCESS) {
> +          if (mDrvObj.UsbdDevObj->ConfigCallback != NULL) {
> +            mDrvObj.UsbdDevObj->ConfigCallback (CfgValue);
> +          }
> +        }
> +
> +        mDrvObj.State = UsbDevStateConfigured; // we are now configured
> +
> +        break; // break from config search loop
> +      }
> +    }
> +  }
> +
> +  if (EFI_ERROR (Status)) {
> +   DEBUG ((DEBUG_INFO, "UsbdSetConfig() - Invalid requested configuration value: %i\n", CfgValue));
> +  }
> +
> +  return Status;
> +}
> +
> +
> +/**
> +  Returns the currently active configuration value
> +
> +  @param Buffer    Pointer to destination Buffer to copy configuration value to
> +  @param ReqLen    the length in bytes of the request Buffer
> +  @param DataLen   Pointer whos value is to be filled with the byte count of
> +                   data copied to the output Buffer
> +
> +  @return EFI_SUCCESS if config value is successfully copied, EFI_DEVICE_ERROR otherwise
> +
> +**/
> +EFI_STATUS
> +UsbdGetConfig (
> +  VOID      *Buffer,
> +  UINT32    ReqLen,
> +  UINT32    *DataLen
> +  )
> +{
> +  EFI_STATUS    Status = EFI_DEVICE_ERROR;
> +
> +  DEBUG ((DEBUG_INFO, "UsbdGetConfig()\n"));
> +
> +  if (ReqLen >= 1) { // length of data expected must be 1
> +    if (mDrvObj.ActiveConfigObj != NULL) { // assure we have a config active
> +      *DataLen = 1; // one byte for ConfigurationValue
> +      *(UINT8*)Buffer = mDrvObj.ActiveConfigObj->ConfigDesc->ConfigurationValue;
> +
> +      Status = EFI_SUCCESS;
> +    } else {
> +      DEBUG ((DEBUG_INFO, "UsbdGetConfig() - No active configuration available\n"));
> +    }
> +  } else {
> +    DEBUG ((DEBUG_INFO, "UsbdGetConfig() - Invalid data length\n"));
> +  }
> +
> +  return Status;
> +}
> +
> +
> +/**
> +  Returns the requested string descriptor if it exists
> +
> +  @param Buffer    Pointer to destination Buffer to copy descriptor data to
> +  @param DescIndex the index of the descriptor to return
> +  @param LangId    the target language ID
> +  @param ReqLen    the length in bytes of the request Buffer
> +  @param DataLen   Pointer whos value is to be filled with the byte count of
> +                   data copied to the output Buffer
> +
> +  @return EFI_SUCCESS if descritor successfully copied, EFI_DEVICE_ERROR otherwise
> +
> +**/
> +EFI_STATUS
> +UsbdGetStringDesc (
> +  VOID      *Buffer,
> +  UINT8     DescIndex,
> +  UINT16    LangId,
> +  UINT32    ReqLen,
> +  UINT32    *DataLen
> +  )
> +{
> +  EFI_STATUS             Status = EFI_DEVICE_ERROR;
> +  UINT32                 Length = 0;
> +  USB_STRING_DESCRIPTOR  *StringDesc;
> +  UINT8                  Index = 0;
> +  UINT8                  StrLangEntries = 0;
> +  BOOLEAN                StrLangFound = FALSE;
> +
> +  DEBUG ((DEBUG_INFO, "UsbdGetStringDesc: Index: 0x%x, LangId: 0x%x, ReqLen: 0x%x\n", DescIndex, LangId, ReqLen));
> +
> +  //
> +  // index zero of the string table contains the supported language codes
> +  //
> +  if (DescIndex == 0) {
> +    StringDesc = (mDrvObj.UsbdDevObj->StringTable);
> +    Length = MIN (ReqLen, StringDesc->Length);
> +    CopyMem (Buffer, StringDesc, Length);
> +    *DataLen = Length;
> +    Status = EFI_SUCCESS;
> +  } else {
> +
> +    //
> +    // Verify the requested language ID is supported. String descriptor Zero
> +    // (First entry in the string table) is expected to contain the language list.
> +    // The requested language ID is specified in the Index member of the request.
> +    //
> +    StringDesc = mDrvObj.UsbdDevObj->StringTable; // get language string descriptor
> +    StrLangEntries = ((StringDesc->Length - 2) >> 1);
> +    DEBUG ((DEBUG_INFO, "StrLangEntries=%x\n", StrLangEntries));
> +
> +    DEBUG ((DEBUG_INFO, "Looking LangID: \n"));
> +
> +    for (Index = 0; Index < StrLangEntries; Index++) {
> +      DEBUG ((DEBUG_INFO, "LangID [%x]= %x\n", Index, StringDesc->LangID [Index]));
> +
> +      if (StringDesc->LangID [Index] == LangId) {
> +        DEBUG ((DEBUG_INFO, "Found it\n"));
> +        StrLangFound = TRUE;
> +      }
> +    }
> +
> +    //
> +    // If we found a matching language, attempt to get the string index requested
> +    //
> +    if (StrLangFound == TRUE) {
> +      DEBUG ((DEBUG_INFO, "UsbdGetStringDesc: StrLangFound=Found, DescIndex=%x, StrTblEntries=%x\n", DescIndex, mDrvObj.UsbdDevObj->StrTblEntries));
> +
> +      if (DescIndex < mDrvObj.UsbdDevObj->StrTblEntries) {
> +        //
> +        // get the string descriptor for the requested index
> +        //
> +        StringDesc = (mDrvObj.UsbdDevObj->StringTable + DescIndex);
> +
> +        Length = MIN (ReqLen, StringDesc->Length);
> +        DEBUG ((DEBUG_INFO, "ReqLen=%x, StringLength=%x, Length=%x\n", ReqLen, StringDesc->Length, Length));
> +
> +        CopyMem (Buffer, StringDesc, Length);
> +        *DataLen = Length;
> +        Status = EFI_SUCCESS;
> +      } else {
> +        DEBUG ((DEBUG_INFO, "UsbdGetStringDesc: Invalid String index in USB_REQ_GET_DESCRIPTOR request\n"));
> +      }
> +    } else {
> +      DEBUG ((DEBUG_INFO, "UsbdGetStringDesc: Unsupported String Language ID for USB_REQ_GET_DESCRIPTOR request\n"));
> +    }
> +  }
> +
> +  if (Status == EFI_SUCCESS) {
> +    PrintStringDescriptor (StringDesc);
> +  }
> +  return Status;
> +}
> +
> +
> +#ifdef SUPPORT_SUPER_SPEED
> +/**
> +  Returns the configuration descriptor for this device. The data
> +  Buffer returned will also contain all downstream interface and
> +  endpoint Buffers.
> +
> +  @param Buffer    Pointer to destination Buffer to copy descriptor data to
> +  @param ReqLen    the length in bytes of the request Buffer
> +  @param DataLen   Pointer whos value is to be filled with the byte count of
> +                   data copied to the output Buffer
> +
> +  @return EFI_SUCCESS if descritor successfully copied, EFI_DEVICE_ERROR otherwise
> +
> +**/
> +EFI_STATUS
> +UsbdGetBOSDesc (
> +  IN VOID      *Buffer,
> +  IN UINT32    ReqLen,
> +  IN UINT32    *DataLen
> +  )
> +{
> +  EFI_USB_BOS_DESCRIPTOR  *BosDesc = 0;
> +  UINT32                  Length = 0;
> +
> +  DEBUG ((DEBUG_INFO, "UsbdGetBOSDesc()\n"));
> +
> +  BosDesc = mDrvObj.UsbdDevObj->BosDesc;
> +  Length = MIN (ReqLen, mDrvObj.UsbdDevObj->BosDesc->TotalLength);
> +
> +  CopyMem(Buffer, BosDesc, Length);
> +  *DataLen = Length;
> +
> +  PrintBOSDescriptor (BosDesc);
> +
> +  return EFI_SUCCESS;
> +}
> +#endif
> +
> +/**
> +  Returns the current status for Device/Interface/Endpoint
> +
> +  @param Buffer    Pointer to destination Buffer to copy descriptor data to
> +  @param ReqType   The type of status to get
> +  @param ReqLen    the length in bytes of the request Buffer
> +  @param DataLen   Pointer whos value is to be filled with the byte count of
> +                   data copied to the output Buffer
> +
> +  @return EFI_SUCCESS if status successfully copied, EFI_DEVICE_ERROR otherwise
> +
> +**/
> +EFI_STATUS
> +UsbdGetStatus (
> +  VOID      *Buffer,
> +  UINT8     ReqType,
> +  UINT32    ReqLen,
> +  UINT32    *DataLen
> +  )
> +{
> +  EFI_STATUS  Status = EFI_DEVICE_ERROR;
> +
> +  DEBUG ((DEBUG_INFO, "UsbdGetStatus()\n"));
> +
> +  if (ReqLen >= 2) { // length of data must be at least 2 bytes
> +    switch (ReqType & USB_TARGET_MASK) {
> +      case USB_TARGET_DEVICE:
> +        *DataLen = 2; // two byte for status
> +        *(UINT16*)Buffer = USB_STATUS_SELFPOWERED;
> +        Status = EFI_SUCCESS;
> +        break;
> +
> +      case USB_TARGET_INTERFACE:
> +        //
> +        // No implementation needed at this time
> +        //
> +        break;
> +
> +      case USB_TARGET_ENDPOINT:
> +        //
> +        // No implementation needed at this time
> +        // Should specify if endpoint is halted. Implement as necessary.
> +        //
> +        break;
> +
> +      case USB_TARGET_OTHER:
> +        //
> +        // No implementation needed at this time
> +        //
> +        break;
> +
> +      default:
> +        break;
> +    }
> +  } else {
> +    DEBUG ((DEBUG_INFO, "UsbdGetStatus() - Invalid data length\n"));
> +  }
> +
> +  return Status;
> +}
> +
> +
> +/**
> +  Sets the address of the device
> +
> +  @param address   the address value to set
> +
> +  @return EFI_SUCCESS if address was set, EFI_DEVICE_ERROR otherwise
> +
> +**/
> +EFI_STATUS
> +UsbdSetAddress (
> +  UINT8    Address
> +  )
> +{
> +  EFI_STATUS  Status = EFI_DEVICE_ERROR;
> +
> +  DEBUG ((DEBUG_INFO, "UsbdSetAddress: setting address: 0x%x\n", Address));
> +
> +  if (Address <= 0x7F) { // address must not be > 127
> +    mDrvObj.Address = Address;
> +
> +    //
> +    // Configure Address in the XDCI
> +    //
> +    Status = UsbDeviceSetAddress (mDrvObj.XdciDrvObj, mDrvObj.Address);
> +    if (!EFI_ERROR (Status)) {
> +      mDrvObj.State = UsbDevStateAddress;
> +    } else {
> +      DEBUG ((DEBUG_INFO, "UsbdSetAddress: Failed to set address in XDCI\n"));
> +    }
> +  } else {
> +    DEBUG ((DEBUG_INFO, "UsbdSetAddress: Invalid address: 0x%x\n", Address));
> +  }
> +
> +  return Status;
> +}
> +
> +
> +/**
> +  Handles Setup device requests. Standard requests are immediately
> +  handled here, and any Class/Vendor specific requests are forwarded
> +  to the class driver
> +
> +  @param CtrlRequest  Pointer to a device request
> +
> +  @return EFI_SUCCESS if request successfully handled, FALSE otherwise
> +
> +**/
> +EFI_STATUS
> +UsbdSetupHdlr (
> +  IN EFI_USB_DEVICE_REQUEST    *CtrlRequest
> +  )
> +{
> +  EFI_STATUS              Status = EFI_DEVICE_ERROR;
> +  UINT8                   DescIndex = 0;
> +  USB_DEVICE_DESCRIPTOR   *DevDesc = 0;
> +
> +  //
> +  // Initialize the IO object
> +  //
> +  mCtrlIoReq.IoInfo.Length = 0;
> +
> +  DEBUG ((DEBUG_INFO, "UsbdSetupHdlr start\n"));
> +  PrintDeviceRequest (CtrlRequest);
> +
> +  //
> +  // Handle Standard Device Requests
> +  //
> +  if ((CtrlRequest->RequestType & USB_REQ_TYPE_MASK) == USB_REQ_TYPE_STANDARD) {
> +    switch (CtrlRequest->Request) {
> +      case USB_REQ_GET_DESCRIPTOR:
> +        DEBUG ((DEBUG_INFO, "UsbdSetupHdlr: Host requests get descriptor\n"));
> +        if (CtrlRequest->RequestType == USB_RT_TX_DIR_D_TO_H) {
> +          DescIndex = (CtrlRequest->Value & 0xff); // low byte is the index requested
> +          switch (CtrlRequest->Value >> 8) { // high byte contains request type
> +            case USB_DESC_TYPE_DEVICE:
> +              DEBUG ((DEBUG_INFO, "Descriptor tyep: Device\n"));
> +              DevDesc = mDrvObj.UsbdDevObj->DeviceDesc;
> +              //
> +              // copy the data to the output Buffer
> +              //
> +              mCtrlIoReq.IoInfo.Length = MIN (CtrlRequest->Length, DevDesc->Length);
> +              CopyMem (mCtrlIoReq.IoInfo.Buffer, DevDesc, mCtrlIoReq.IoInfo.Length);
> +              PrintDeviceDescriptor (DevDesc);
> +              break;
> +
> +            case USB_DESC_TYPE_CONFIG:
> +              DEBUG ((DEBUG_INFO, "Descriptor tyep: Configuration\n"));
> +              Status = UsbdGetConfigDesc (
> +                         mCtrlIoReq.IoInfo.Buffer,
> +                         DescIndex,
> +                         CtrlRequest->Length,
> +                         &(mCtrlIoReq.IoInfo.Length)
> +                         );
> +              break;
> +
> +            case USB_DESC_TYPE_STRING:
> +              DEBUG ((DEBUG_INFO, "Descriptor tyep: String\n"));
> +              Status = UsbdGetStringDesc (
> +                         mCtrlIoReq.IoInfo.Buffer,
> +                         DescIndex,
> +                         CtrlRequest->Index,
> +                         CtrlRequest->Length,
> +                         &(mCtrlIoReq.IoInfo.Length)
> +                         );
> +              break;
> +
> +#ifdef SUPPORT_SUPER_SPEED
> +            case USB_DESC_TYPE_BOS:
> +              DEBUG ((DEBUG_INFO, "Descriptor tyep: BOS\n"));
> +              Status = UsbdGetBOSDesc (
> +                         mCtrlIoReq.IoInfo.Buffer,
> +                         CtrlRequest->Length,
> +                         &(mCtrlIoReq.IoInfo.Length)
> +                         );
> +              break;
> +
> +            case USB_DESC_TYPE_SS_ENDPOINT_COMPANION:
> +              DEBUG ((DEBUG_INFO, "Descriptor tyep: Endpoint Companion\n"));
> +              break;
> +#endif
> +
> +            default:
> +              DEBUG ((DEBUG_INFO, "Descriptor tyep: Unsupported, USB_REQ_GET_DESCRIPTOR request: 0x%x\n", (CtrlRequest->Value >> 8)));
> +              break;
> +          }
> +        } else {
> +          DEBUG ((DEBUG_INFO, "UsbdSetupHdlr() - Invalid direction for USB_REQ_GET_DESCRIPTOR request\n"));
> +        }
> +        break;
> +
> +      case USB_REQ_GET_CONFIG:
> +        DEBUG ((DEBUG_INFO, "USB_REQ_GET_CONFIG\n"));
> +        if (CtrlRequest->RequestType == USB_RT_TX_DIR_D_TO_H) {
> +          Status = UsbdGetConfig (mCtrlIoReq.IoInfo.Buffer, CtrlRequest->Length, &(mCtrlIoReq.IoInfo.Length));
> +        } else {
> +          DEBUG ((DEBUG_INFO, "UsbdSetupHdlr: Invalid direction for USB_REQ_GET_CONFIG request\n"));
> +        }
> +        break;
> +
> +      case USB_REQ_SET_CONFIG:
> +        DEBUG ((DEBUG_INFO, "USB_REQ_SET_CONFIG\n"));
> +        if (CtrlRequest->RequestType == USB_RT_TX_DIR_H_TO_D) {
> +          Status = UsbdSetConfig ((UINT8)CtrlRequest->Value);
> +        } else {
> +          DEBUG ((DEBUG_INFO, "UsbdSetupHdlr: Invalid direction for USB_REQ_SET_CONFIG request\n"));
> +        }
> +        break;
> +
> +      case USB_REQ_SET_ADDRESS:
> +        DEBUG ((DEBUG_INFO, "USB_REQ_SET_ADDRESS\n"));
> +        if (CtrlRequest->RequestType == USB_RT_TX_DIR_H_TO_D) {
> +          Status = UsbdSetAddress ((UINT8)CtrlRequest->Value);
> +        } else {
> +          DEBUG ((DEBUG_INFO, "UsbdSetupHdlr: Invalid direction for USB_REQ_SET_ADDRESS request\n"));
> +        }
> +        break;
> +
> +      case USB_REQ_GET_STATUS:
> +        DEBUG ((DEBUG_INFO, "USB_REQ_GET_STATUS\n"));
> +        if (CtrlRequest->RequestType & USB_RT_TX_DIR_D_TO_H) {
> +          Status = UsbdGetStatus (mCtrlIoReq.IoInfo.Buffer, CtrlRequest->RequestType, CtrlRequest->Length, &(mCtrlIoReq.IoInfo.Length));
> +        } else {
> +          DEBUG ((DEBUG_INFO, "UsbdSetupHdlr: Invalid direction for USB_REQ_GET_STATUS request\n"));
> +        }
> +        break;
> +#ifdef SUPPORT_SUPER_SPEED
> +      case USB_REQ_CLEAR_FEATURE:
> +      case USB_REQ_SET_FEATURE:
> +      case USB_REQ_SET_DESCRIPTOR:
> +      case USB_REQ_GET_INTERFACE:
> +      case USB_REQ_SET_INTERFACE:
> +      case USB_REQ_SYNCH_FRAME:
> +#endif
> +      default:
> +         DEBUG ((DEBUG_INFO, "UsbdSetupHdlr: Unsupported Standard Request: 0x%x\n", CtrlRequest->Request));
> +          break;
> +    }
> +  } else { // This is not a Standard request, it specifies Class/Vendor handling
> +    //
> +    // Forward request to class driver
> +    //
> +    DEBUG ((DEBUG_INFO, "UsbdSetupHdlr: Class/Vendor Request\n"));
> +    if (mDrvObj.UsbdDevObj->SetupCallback != NULL) {
> +      mDrvObj.UsbdDevObj->SetupCallback (CtrlRequest, &(mCtrlIoReq.IoInfo));
> +    }
> +  }
> +
> +  DEBUG ((DEBUG_INFO, "dataLen=%x\n", mCtrlIoReq.IoInfo.Length));
> +  //
> +  // Transfer data according to request if necessary
> +  //
> +  if (mCtrlIoReq.IoInfo.Length> 0) {
> +    Status = UsbdEpTxData (mDrvObj.XdciDrvObj, &mCtrlIoReq);
> +    if (EFI_ERROR (Status)) {
> +      DEBUG ((DEBUG_INFO, "UsbdSetupHdlr: Failed to TX data\n"));
> +    }
> +  } else {
> +    //
> +    // If we are not responding with data, send control status
> +    //
> +    Status = UsbDeviceEp0TxStatus (mDrvObj.XdciDrvObj);
> +    if (EFI_ERROR (Status)) {
> +      DEBUG ((DEBUG_INFO, "UsbdSetupHdlr: Failed to Tx Ep0 Status\n"));
> +    }
> +  }
> +
> +  return Status;
> +}
> +
> +
> +/**
> +  Handles Connection done events. Sets the device address to zero.
> +
> +  @return EFI_SUCCESS if able to set the address, EFI_DEVICE_ERROR otherwise
> +
> +**/
> +EFI_STATUS
> +UsbdConnDoneHdlr (
> +  VOID
> +  )
> +{
> +  EFI_STATUS    Status = EFI_DEVICE_ERROR;
> +
> +  DEBUG ((DEBUG_INFO, "UsbdConnDoneHdlr()\n"));
> +
> +  //
> +  // reset device address to 0
> +  //
> +  Status = UsbDeviceSetAddress (mDrvObj.XdciDrvObj, 0x0);
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((DEBUG_INFO, "UsbdConnDoneHdlr() - Failed to set address in XDCI\n"));
> +  }
> +
> +  //
> +  // set the device state to attached/connected
> +  //
> +  mDrvObj.State = UsbDevStateAttached;
> +
> +  return Status;
> +}
> +
> +
> +/**
> +  Handles transmit/receive completion events. Directly handles
> +  control endpoint events and forwards class/vendor specific events
> +  to the class drivers.
> +
> +  @param   XferInfo   Pointer to Xfer structure
> +
> +  @return
> +
> +**/
> +VOID
> +UsbdXferDoneHdlr (
> +  IN EFI_USB_DEVICE_XFER_INFO    *XferInfo
> +  )
> +{
> +  //
> +  // If this is a non-control transfer complete, notify the class driver
> +  //
> +  if (XferInfo->EndpointNum > 0) {
> +    if (mDrvObj.UsbdDevObj->DataCallback != NULL) {
> +      mDrvObj.UsbdDevObj->DataCallback (XferInfo);
> +    }
> +  }
> +
> +  return;
> +}
> +
> +
> +/**
> +  Binds a USB class driver with this USB device driver core.
> +  After calling this routine, the driver is ready to begin
> +  USB processing.
> +
> +  @param  UsbdDevObj   Pointer to a usbd device object which contains
> +                       all relevant information for the class driver device
> +
> +  @return TRUE if binding was successful, FALSE otherwise
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +UsbDeviceBind (
> +  IN EFI_USB_DEVICE_MODE_PROTOCOL               *This,
> +  IN USB_DEVICE_OBJ                             *UsbdDevObj
> +  )
> +{
> +  EFI_STATUS  Status = EFI_SUCCESS;
> +
> +  //
> +  // allocate Tx Buffer
> +  //
> +  mCtrlIoReq.IoInfo.Buffer = AllocateZeroPool (USB_EPO_MAX_PKT_SIZE_ALL);
> +  if (mCtrlIoReq.IoInfo.Buffer != NULL) {
> +    mDrvObj.UsbdDevObj = UsbdDevObj;
> +    mDrvObj.ActiveConfigObj = NULL;
> +    mDrvObj.Address = 0;
> +    mDrvObj.State = UsbDevStateInit;
> +  } else {
> +    DEBUG ((DEBUG_INFO, "UsbDeviceBind() - Failed to allocate IO Buffer\n"));
> +    Status = EFI_DEVICE_ERROR;
> +  }
> +
> +  return Status;
> +}
> +
> +
> +/**
> +  Unbinds the USB class driver from this USB device driver core.
> +
> +  @return TRUE if successful, FALSE otherwise
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +UsbDeviceUnbind (
> +  IN EFI_USB_DEVICE_MODE_PROTOCOL               *This
> +  )
> +{
> +  mDrvObj.UsbdDevObj = NULL;
> +  mDrvObj.ActiveConfigObj = NULL;
> +  mDrvObj.Address = 0;
> +  mDrvObj.State = UsbDevStateOff;
> +  mDrvObj.XdciInitialized = FALSE;
> +
> +  //
> +  // release allocated Buffer data
> +  //
> +  if (mCtrlIoReq.IoInfo.Buffer) {
> +    FreePool (mCtrlIoReq.IoInfo.Buffer);
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +
> +/**
> +  Performs continual USB device event processing until a cancel
> +  event occurs
> +
> +  @param   TimeoutMs   Connection timeout in ms. If 0, waits forever.
> +  @return  TRUE if run executed normally, FALSE if error ocurred
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +UsbDeviceRun (
> +  IN EFI_USB_DEVICE_MODE_PROTOCOL               *This,
> +  IN UINT32                                     TimeoutMs
> +  )
> +{
> +  EFI_STATUS              Status = EFI_DEVICE_ERROR;
> +  USB_XDCI_DEV_CONTEXT    *XdciDevContext;
> +
> +  XdciDevContext = USBUSBD_CONTEXT_FROM_PROTOCOL (This);
> +
> +  //
> +  // can only run if XDCI is initialized
> +  //
> +  if ((mDrvObj.XdciInitialized == TRUE)) {
> +
> +    if ((mDrvObj.State == UsbDevStateConfigured) && (XdciDevContext->XdciPollTimer == NULL)) {
> +      Status = gBS->CreateEvent (
> +                      EVT_TIMER | EVT_NOTIFY_SIGNAL,
> +                      TPL_NOTIFY,
> +                      UsbdMonitorEvents,
> +                      XdciDevContext,
> +                      &XdciDevContext->XdciPollTimer
> +                      );
> +      if (!EFI_ERROR (Status)) {
> +        Status = gBS->SetTimer (XdciDevContext->XdciPollTimer, TimerPeriodic, EFI_TIMER_PERIOD_MILLISECONDS (20));
> +        DEBUG ((EFI_D_ERROR, "UsbDeviceRun Create Event\n"));
> +      }
> +    }
> +
> +    mXdciRun = TRUE; // set the run flag to active
> +    Status = EFI_SUCCESS;
> +
> +    //
> +    // start the Event processing loop
> +    //
> +    while (TRUE) {
> +      if (XdciDevContext->XdciPollTimer == NULL) {
> +        if (UsbDeviceIsrRoutine (mDrvObj.XdciDrvObj) != EFI_SUCCESS) {
> +          DEBUG ((DEBUG_INFO, "UsbDeviceRun() - Failed to execute event ISR\n"));
> +        }
> +      }
> +
> +      //
> +      // Check if a run cancel request exists, if so exit processing loop
> +      //
> +      if (mXdciRun == FALSE) {
> +        if (XdciDevContext->XdciPollTimer != NULL) {
> +          DEBUG ((EFI_D_ERROR, "UsbDeviceRun close Event\n"));
> +          gBS->SetTimer (XdciDevContext->XdciPollTimer, TimerCancel, 0);
> +          gBS->CloseEvent (XdciDevContext->XdciPollTimer);
> +          XdciDevContext->XdciPollTimer = NULL;
> +        }
> +        Status = EFI_SUCCESS;
> +        DEBUG ((DEBUG_INFO, "UsbDeviceRun() - processing was cancelled\n"));
> +        break;
> +      }
> +
> +      //
> +      // check for timeout
> +      //
> +      if (TimeoutMs == 0)
> +        return EFI_TIMEOUT;
> +      gBS->Stall (50);
> +      TimeoutMs--;
> +    }
> +  }
> +
> +  return Status;
> +}
> +
> +
> +/**
> +  Sets a flag to stop the running device processing loop
> +
> +  @return TRUE always
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +UsbDeviceStop (
> +  IN EFI_USB_DEVICE_MODE_PROTOCOL               *This
> +  )
> +{
> +  mXdciRun = FALSE; // set run flag to FALSE to stop processing
> +  return EFI_SUCCESS;
> +}
> +
> +
> +EFI_STATUS
> +EFIAPI
> +UsbDeviceInitXdci (
> +  IN EFI_USB_DEVICE_MODE_PROTOCOL               *This
> +  )
> +{
> +  EFI_STATUS            Status = EFI_DEVICE_ERROR;
> +  USB_XDCI_DEV_CONTEXT  *XdciDevContext;
> +
> +  XdciDevContext = USBUSBD_CONTEXT_FROM_PROTOCOL (This);
> +
> +  PlatformSpecificInit ();
> +
> +  if (mDrvObj.XdciInitialized == FALSE) {
> +    if (XdciDevContext->XdciMmioBarAddr != 0) {
> +
> +      //
> +      // Initialize device controller driver
> +      //
> +      DEBUG ((DEBUG_INFO, "UsbDeviceInitXdci() - Initializing Controller...\n"));
> +
> +      //
> +      // Initialize the device controller interface
> +      //
> +      if (UsbdInit ((UINT32)XdciDevContext->XdciMmioBarAddr, &mDrvObj.XdciDrvObj) == EFI_SUCCESS) {
> +
> +        //
> +        // Setup callbacks
> +        //
> +        if (UsbdRegisterCallbacks (mDrvObj.XdciDrvObj) == EFI_SUCCESS) {
> +
> +          mDrvObj.XdciInitialized = TRUE;
> +          Status = EFI_SUCCESS;
> +
> +          DEBUG ((DEBUG_INFO, "UsbDeviceInitXdci() - Controller initialization complete\n"));
> +        } else {
> +          DEBUG ((DEBUG_INFO, "UsbDeviceInitXdci() - Failed to register UDCI callbacks\n"));
> +        }
> +      } else {
> +        DEBUG ((DEBUG_INFO, "UsbDeviceInitXdci() - Failed to initialize UDCI\n"));
> +      }
> +    } else {
> +      DEBUG ((DEBUG_INFO, "UsbDeviceInitXdci() - XDCI MMIO BAR not set\n"));
> +    }
> +  } else {
> +    DEBUG ((DEBUG_INFO, "UsbDeviceInitXdci() - XDCI already initialized\n"));
> +    Status = EFI_ALREADY_STARTED;
> +  }
> +
> +  return Status;
> +}
> +
> +
> +EFI_STATUS
> +EFIAPI
> +UsbDeviceConnect(
> +  IN EFI_USB_DEVICE_MODE_PROTOCOL               *This
> +  )
> +{
> +  EFI_STATUS  Status = EFI_DEVICE_ERROR;
> +
> +  DEBUG ((DEBUG_INFO,  "UsbDeviceConnect \n"));
> +  if (UsbXdciDeviceConnect (mDrvObj.XdciDrvObj) == EFI_SUCCESS) {
> +    Status = EFI_SUCCESS;
> +  }
> +  return Status;
> +}
> +
> +
> +EFI_STATUS
> +EFIAPI
> +UsbDeviceDisConnect (
> +  IN EFI_USB_DEVICE_MODE_PROTOCOL               *This
> +  )
> +{
> +  EFI_STATUS  Status = EFI_DEVICE_ERROR;
> +
> +  DEBUG ((DEBUG_INFO,  "UsbDeviceDisConnect \n"));
> +  if (UsbDeviceDisconnect (mDrvObj.XdciDrvObj) == EFI_SUCCESS) {
> +    mDrvObj.State = UsbDevStateInit;
> +    Status = EFI_SUCCESS;
> +  }
> +
> +  XhciSwitchSwid(FALSE);
> +  return Status;
> +}
> +
> +
> +EFI_STATUS
> +EFIAPI
> +UsbDeviceEpTxData(
> +  IN EFI_USB_DEVICE_MODE_PROTOCOL               *This,
> +  IN USB_DEVICE_IO_REQ                          *IoRequest
> +  )
> +{
> +  EFI_STATUS  Status;
> +
> +  Status = UsbdEpTxData (mDrvObj.XdciDrvObj, IoRequest);
> +  return Status;
> +}
> +
> +
> +EFI_STATUS
> +EFIAPI
> +UsbDeviceEpRxData(
> +  IN EFI_USB_DEVICE_MODE_PROTOCOL               *This,
> +  IN USB_DEVICE_IO_REQ                          *IoRequest
> +  )
> +{
> +  EFI_STATUS  Status;
> +
> +  Status = UsbdEpRxData (mDrvObj.XdciDrvObj, IoRequest);
> +  return Status;
> +}
> +
> +
> +//
> +// The Runtime UsbDeviceMode Protocol instance produced by this driver
> +//
> +EFI_USB_DEVICE_MODE_PROTOCOL  mUsbDeviceModeProtocol = {
> +  UsbDeviceInitXdci,
> +  UsbDeviceConnect,
> +  UsbDeviceDisConnect,
> +  UsbDeviceEpTxData,
> +  UsbDeviceEpRxData,
> +  UsbDeviceBind,
> +  UsbDeviceUnbind,
> +  UsbDeviceRun,
> +  UsbDeviceStop
> +};
> +
> diff --git a/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbDeviceMode.h b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbDeviceMode.h
> new file mode 100644
> index 0000000000..ac9c89b2f1
> --- /dev/null
> +++ b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbDeviceMode.h
> @@ -0,0 +1,39 @@
> +/** @file
> +  Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR>
> +
> +  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.
> +
> +**/
> +
> +#ifndef _USB_DEVICE_MODE_DXE_H_
> +#define _USB_DEVICE_MODE_DXE_H_
> +
> +#include <Uefi.h>
> +#include <PiDxe.h>
> +#include <Library/DebugLib.h>
> +#include <Library/UefiDriverEntryPoint.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Library/UsbDeviceLib.h>
> +#include <Protocol/UsbDeviceModeProtocol.h>
> +#include "XdciCommon.h"
> +#include "XdciDevice.h"
> +
> +
> +///
> +/// Function declaration
> +///
> +EFI_STATUS
> +UsbdSetupHdlr (
> +  IN EFI_USB_DEVICE_REQUEST    *CtrlRequest
> +  );
> +
> +extern EFI_USB_DEVICE_MODE_PROTOCOL  mUsbDeviceModeProtocol;
> +
> +#endif
> +
> diff --git a/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbFuncIo.c b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbFuncIo.c
> new file mode 100644
> index 0000000000..a4138328fd
> --- /dev/null
> +++ b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbFuncIo.c
> @@ -0,0 +1,2221 @@
> +/** @file
> +  Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR>
> +
> +  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.
> +
> +**/
> +
> +#include "UsbDeviceDxe.h"
> +
> +//
> +// 16 bytes in a guid x 2 characters per byte, 4 chars for dashes and a NUL
> +//
> +#define CHARS_IN_GUID (sizeof(GUID) * 2 + 4 + 1)
> +
> +//
> +// Strings that get sent with the USB Connection
> +//
> +static CHAR16 mUsbFnDxeMfgString[] = L"Intel Corporation";
> +static CHAR16 mUsbFnDxeProductString[] = L"Broxton";
> +static CHAR16 mUsbFnDxeSerialNumber[] = L"INT123456";
> +
> +//
> +// Duplicated from MiscSystemManufacturerData.c Some parts of it will
> +// replaced with device-specific unique values.
> +//
> +static GUID mSmBiosUniqueGuid = {
> +        0x5e24fe9c, 0xc8d0, 0x45bd, 0xa7, 0x9f, 0x54, 0xea, 0x5f, 0xbd, 0x3d, 0x97
> +    };
> +
> +EFI_USBFN_IO_PROTOCOL         mUsbFunIoProtocol = {
> +  EFI_USBFN_IO_PROTOCOL_REVISION,
> +  DetectPort,
> +  ConfigureEnableEndpoints,
> +  GetEndpointMaxPacketSize,
> +  GetDeviceInfo,
> +  GetVendorIdProductId,
> +  AbortTransfer,
> +  GetEndpointStallState,
> +  SetEndpointStallState,
> +  EventHandler,
> +  Transfer,
> +  GetMaxTransferSize,
> +  AllocateTransferBuffer,
> +  FreeTransferBuffer,
> +  StartController,
> +  StopController,
> +  SetEndpointPolicy,
> +  GetEndpointPolicy
> +};
> +
> +
> +EFI_STATUS
> +PrintEventBuffer(
> +  IN  EFI_USBFN_IO_PROTOCOL  *This
> +  )
> +{
> +  UINT32                          EventCount;
> +  USB_XDCI_DEV_CONTEXT            *UsbFuncIoDevPtr;
> +  XDCI_CORE_HANDLE                *XdciCorePtr;
> +  USB_DEV_CORE                    *UsbDeviceCorePtr;
> +  UINT32                          Index;
> +  UINT32                          *DbBufPtr;
> +
> +  UsbFuncIoDevPtr = USBFUIO_CONTEXT_FROM_PROTOCOL (This);
> +
> +  UsbDeviceCorePtr = UsbFuncIoDevPtr->DrvCore;
> +  XdciCorePtr = UsbDeviceCorePtr->ControllerHandle;
> +
> +  EventCount = UsbRegRead ((UINT32)UsbFuncIoDevPtr->XdciMmioBarAddr, DWC_XDCI_EVNTCOUNT_REG(0));
> +
> +  DbBufPtr = (UINT32*)(UINTN)XdciCorePtr->CurrentEventBuffer;
> +  XdciCorePtr = UsbDeviceCorePtr->ControllerHandle;
> +  DEBUG ((USB_FUIO_DEBUG_EVENT_D, "FUEV:: XdciCorePtr->AlignedEventBuffers 0x%08x\n", (UINTN)XdciCorePtr->AlignedEventBuffers));
> +  DEBUG ((USB_FUIO_DEBUG_EVENT_D, "FUEV:: DUMP BUF_S\n"));
> +  for (Index = 0; Index < ((EventCount / 4) + 1); Index++) {
> +    DEBUG ((USB_FUIO_DEBUG_EVENT_D, "0x%08x\n", DbBufPtr[Index]));
> +  }
> +  DEBUG ((USB_FUIO_DEBUG_EVENT_D, "FUEV:: DUMP BUF_E\n"));
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +Debug End
> +**/
> +
> +/**
> +  Returns information about what type of device was attached.
> +
> +  @param[in]  This               A pointer to the EFI_USBFN_IO_PROTOCOL instance.
> +  @param[out] PortType           Returns the USB port type.
> +
> +
> +  @retval EFI_SUCCESS            The operation completed successfully.
> +  @retval EFI_INVALID_PARAMETER  A parameter is invalid.
> +  @retval EFI_DEVICE_ERROR       The physical device reported an error.
> +  @retval EFI_NOT_READY          The physical device is busy or not ready to
> +                                 process this request or the device is not
> +                                 attached to the host.
> +
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +DetectPort (
> +  IN  EFI_USBFN_IO_PROTOCOL  *This,
> +  OUT EFI_USBFN_PORT_TYPE    *PortType
> +  )
> +{
> +  USB_XDCI_DEV_CONTEXT  *UsbFuncIoDevPtr;
> +  EFI_STATUS            Status;
> +  UINT8                 Value8;
> +
> +  DEBUG ((USB_FUIO_DEBUG_INFO, "DetectPort - Entry\n"));
> +
> +  UsbFuncIoDevPtr = USBFUIO_CONTEXT_FROM_PROTOCOL (This);
> +
> +  //
> +  // USBSRCDETRSLT Bit[5:2]
> +  // Result of USB HW Source Detection algorithm
> +  // Power-Domain: VRTC
> +  // Result of USB HW Source Detection algorithm :
> +  // 0000 = Not determined
> +  // 0001 = SDP Attached
> +  // 0010 = DCP Attached
> +  // 0011 = CDP Attached
> +  // 0100 = ACA Attached
> +  // 0101 = SE1 Attached
> +  // 0110 = MHL Attached
> +  // 0111 = Floating D+/D- Attached
> +  // 1000 = Other Attached
> +  // 1001 = DCP detected by ext. USB PHY
> +  // 1010-1111 = Rsvd
> +  // Reset: 0000B
> +  //
> +
> +  Value8 =PmicRead8 (0x5E, 0X29);
> +  if ((Value8 & 0x03) != 0x02) {
> +    *PortType = EfiUsbUnknownPort;
> +    Status = EFI_NOT_READY;
> +    goto out;
> +  }
> +
> +  Value8 = Value8 >> 2 & 0x0f;
> +  Status = EFI_SUCCESS;
> +  switch (Value8) {
> +    case 1:
> +      *PortType = EfiUsbStandardDownstreamPort;
> +      break;
> +    case 2:
> +      *PortType = EfiUsbDedicatedChargingPort;
> +      break;
> +    case 3:
> +      *PortType = EfiUsbChargingDownstreamPort;
> +      break;
> +
> +    case 4:
> +    case 5:
> +    case 6:
> +    case 7:
> +    case 8:
> +    case 9:
> +      *PortType = EfiUsbUnknownPort;
> +      break;
> +    case 0:
> +    case 10:
> +    case 11:
> +    case 12:
> +    case 13:
> +    case 14:
> +    case 15:
> +      *PortType = EfiUsbUnknownPort;
> +      Status = EFI_NOT_READY;
> +     break;
> +  }
> +
> +out:
> +  DEBUG ((USB_FUIO_DEBUG_INFO, "DetectPort - Exit\n"));
> +  return EFI_SUCCESS;
> +}
> +
> +
> +/**
> +  The AllocateTransferBuffer function allocates a memory region of Size bytes
> +  and returns the address of the allocated memory that satisfies underlying
> +  controller requirements in the location referenced by Buffer.
> +
> +  @param[in] This               A pointer to the EFI_USBFN_IO_PROTOCOL instance.
> +  @param[in] Size               The number of bytes to allocate for the transfer
> +                                Buffer.
> +  @param[in] Buffer             A pointer to a pointer to the allocated Buffer
> +                                if the call succeeds; undefined otherwise.
> +
> +  @retval EFI_SUCCESS           The operation completed successfully.
> +  @retval EFI_INVALID_PARAMETER A parameter is invalid.
> +  @retval The requested transfer Buffer could not be allocated.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +AllocateTransferBuffer (
> +  IN EFI_USBFN_IO_PROTOCOL    *This,
> +  IN UINTN                    Size,
> +  OUT VOID                    **Buffer
> +  )
> +{
> +  EFI_STATUS            Status;
> +  USB_XDCI_DEV_CONTEXT  *UsbFuncIoDevPtr;
> +  VOID                  *AllocateBufferPtr;
> +  USB_MEM_NODE          *NodePtr;
> +
> +  DEBUG ((USB_FUIO_DEBUG_INFO, "AllocateTransferBuffer - Entry\n"));
> +
> +  UsbFuncIoDevPtr = USBFUIO_CONTEXT_FROM_PROTOCOL (This);
> +
> +  if (Size == 0) {
> +    Status = EFI_INVALID_PARAMETER;
> +    goto ErrorExit;
> +  }
> +
> +  AllocateBufferPtr = AllocateZeroPool (Size);
> +
> +  if (AllocateBufferPtr == NULL) {
> +    Status = EFI_OUT_OF_RESOURCES;
> +    goto ErrorExit;
> +  }
> +
> +  //
> +  // Create new node
> +  //
> +  Status = InsertNewNodeToHead (This, &NodePtr);
> +  if (EFI_ERROR (Status)) {
> +    Status = EFI_OUT_OF_RESOURCES;
> +    goto ErrorExit;
> +  }
> +
> +  NodePtr->Size = Size;
> +  NodePtr->AllocatePtr = AllocateBufferPtr;
> +
> +  *Buffer = AllocateBufferPtr;
> +
> +  DEBUG ((USB_FUIO_DEBUG_INFO, "AllocateTransferBuffer addr 0x%08x\n", AllocateBufferPtr));
> +  DEBUG ((USB_FUIO_DEBUG_INFO, "AllocateTransferBuffer - Exit\n"));
> +  return EFI_SUCCESS;
> +
> +ErrorExit:
> +
> +  DEBUG ((USB_FUIO_DEBUG_ERROR, "AllocateTransferBuffer - ERRROR %r\n",Status));
> +  return Status;
> +}
> +
> +
> +/**
> +  Deallocates the memory allocated for the transfer Buffer by
> +  AllocateTransferBuffer function.
> +
> +  @param[in] This               A pointer to the EFI_USBFN_IO_PROTOCOL instance.
> +  @param[in] Buffer             Buffer Pointer to the transfer Buffer
> +                                to deallocate.
> +  @retval EFI_SUCCESS           The function returned successfully.
> +  @retval EFI_INVALID_PARAMETER A parameter is invalid.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +FreeTransferBuffer (
> +  IN EFI_USBFN_IO_PROTOCOL    *This,
> +  IN VOID                     *Buffer
> +  )
> +{
> +  EFI_STATUS            Status;
> +  USB_XDCI_DEV_CONTEXT  *UsbFuncIoDevPtr;
> +
> +  UsbFuncIoDevPtr = USBFUIO_CONTEXT_FROM_PROTOCOL (This);
> +  DEBUG ((USB_FUIO_DEBUG_LOAD, "FreeTransferBuffer - Entry\n"));
> +
> +  Status = RemoveNode (This, Buffer);
> +  if (EFI_ERROR(Status)) {
> +    DEBUG ((USB_FUIO_DEBUG_LOAD, "FreeTransferBuffer - ERROR\n"));
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  DEBUG ((USB_FUIO_DEBUG_LOAD, "FreeTransferBuffer - Exit\n"));
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  Configure endpoints Based on supplied device and configuration descriptors.
> +
> +  @param[in] This               A pointer to the EFI_USBFN_IO_PROTOCOL instance.
> +  @param[in] DeviceInfo         A pointer to EFI_USBFN_DEVICE_INFO instance.
> +
> +  @retval EFI_SUCCESS           The function returned successfully.
> +  @retval EFI_INVALID_PARAMETER A parameter is invalid.
> +  @retval EFI_DEVICE_ERROR      The physical device reported an error.
> +  @retval EFI_NOT_READY         The physical device is busy or not ready to
> +                                process this request.
> +  @retval EFI_OUT_OF_RESOURCES  The request could not be completed due to
> +                                lack of resources.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +ConfigureEnableEndpoints (
> +  IN EFI_USBFN_IO_PROTOCOL         *This,
> +  IN EFI_USB_DEVICE_INFO           *DeviceInfo
> +  )
> +{
> +  EFI_STATUS                        Status;
> +  USB_XDCI_DEV_CONTEXT              *UsbFuncIoDevPtr;
> +
> +  UsbFuncIoDevPtr = USBFUIO_CONTEXT_FROM_PROTOCOL (This);
> +  Status = EFI_SUCCESS;
> +
> +  DEBUG ((USB_FUIO_DEBUG_LOAD, "ConfigureEnableEndpoints - Entry\n"));
> +  //
> +  //Assuming that the hardware has already been initialized,
> +  //this function configures the endpoints using supplied
> +  //DeviceInfo, activates the port, and starts receiving USB events
> +  //
> +  Status = EFI_SUCCESS;
> +  if (DeviceInfo == NULL) {
> +    Status = EFI_INVALID_PARAMETER;
> +    goto FUNC_EXIT;
> +  }
> +
> +  UsbFuncIoDevPtr->DevInfoPtr->DeviceDescriptor = DeviceInfo->DeviceDescriptor;
> +
> +  //
> +  // Set Configure table
> +  //
> +  if (DeviceInfo->DeviceDescriptor->NumConfigurations > 1) {
> +    DEBUG ((EFI_D_ERROR, "!!!Error ConfigNum over '1' %d\n", DeviceInfo->DeviceDescriptor->NumConfigurations));
> +  }
> +  UsbFuncIoDevPtr->IndexPtrConfig.ConfigDescriptor = DeviceInfo->ConfigInfoTable[0]->ConfigDescriptor;
> +  UsbFuncIoDevPtr->IndexPtrConfig.InterfaceInfoTable[0] = DeviceInfo->ConfigInfoTable[0]->InterfaceInfoTable[0];
> +
> +  //
> +  // Set Interface
> +  //
> +  if (DeviceInfo->ConfigInfoTable[0]->ConfigDescriptor->NumInterfaces > 1) {
> +    DEBUG ((EFI_D_ERROR, "!!!Error NumInterfaces[0] over '1' %d\n", DeviceInfo->ConfigInfoTable[0]->ConfigDescriptor->NumInterfaces));
> +  }
> +  UsbFuncIoDevPtr->IndexPtrInteface.InterfaceDescriptor = DeviceInfo->ConfigInfoTable[0]->InterfaceInfoTable[0]->InterfaceDescriptor;
> +
> +  //
> +  // Set Endpoint
> +  //
> +  if (UsbFuncIoDevPtr->IndexPtrInteface.InterfaceDescriptor->NumEndpoints > 2) {
> +    DEBUG ((EFI_D_ERROR, "!!!Error NumEndPoint[0] over '2' %d\n", UsbFuncIoDevPtr->IndexPtrInteface.InterfaceDescriptor->NumEndpoints));
> +  }
> +
> +  UsbFuncIoDevPtr->IndexPtrInEp.EndpointCompDesc = NULL;
> +  UsbFuncIoDevPtr->IndexPtrOutEp.EndpointCompDesc = NULL;
> +
> +  if ((DeviceInfo->ConfigInfoTable[0]->InterfaceInfoTable[0]->EndpointDescriptorTable[0]->EndpointAddress & USB_ENDPOINT_DIR_IN) != 0) {
> +    UsbFuncIoDevPtr->IndexPtrInEp.EndpointDesc = DeviceInfo->ConfigInfoTable[0]->InterfaceInfoTable[0]->EndpointDescriptorTable[0];
> +    UsbFuncIoDevPtr->IndexPtrOutEp.EndpointDesc = DeviceInfo->ConfigInfoTable[0]->InterfaceInfoTable[0]->EndpointDescriptorTable[1];
> +  } else {
> +    UsbFuncIoDevPtr->IndexPtrInEp.EndpointDesc = DeviceInfo->ConfigInfoTable[0]->InterfaceInfoTable[0]->EndpointDescriptorTable[1];
> +    UsbFuncIoDevPtr->IndexPtrOutEp.EndpointDesc = DeviceInfo->ConfigInfoTable[0]->InterfaceInfoTable[0]->EndpointDescriptorTable[0];
> +  }
> +
> +  DEBUG ((USB_FUIO_DEBUG_LOAD, " In Ep Num 0x%02x\n", UsbFuncIoDevPtr->IndexPtrInEp.EndpointDesc->EndpointAddress));
> +
> +  DEBUG ((USB_FUIO_DEBUG_LOAD, " Out Ep Num 0x%02x\n", UsbFuncIoDevPtr->IndexPtrOutEp.EndpointDesc->EndpointAddress));
> +
> +FUNC_EXIT:
> +  DEBUG ((USB_FUIO_DEBUG_LOAD, "ConfigureEnableEndpoints - exit %r\n", Status));
> +  return Status;
> +}
> +
> +/**
> +  Returns the maximum packet size of the specified endpoint type for
> +  the supplied bus Speed.
> +
> +  @param[in] This               A pointer to the EFI_USBFN_IO_PROTOCOL instance.
> +  @param[in] EndpointType       Endpoint type as defined as EFI_USB_ENDPOINT_TYPE.
> +  @param[in] BusSpeed           Bus Speed as defined as EFI_USB_BUS_SPEED.
> +  @param[in] MaxPacketSize      The maximum packet size, in bytes,
> +                                of the specified endpoint type.
> +
> +  @retval EFI_SUCCESS           The function returned successfully.
> +  @retval EFI_INVALID_PARAMETER A parameter is invalid.
> +  @retval EFI_DEVICE_ERROR      The physical device reported an error.
> +  @retval EFI_NOT_READY         The physical device is busy or not ready to
> +                                process this request.
> +**/
> +EFI_STATUS
> +EFIAPI
> +GetEndpointMaxPacketSize (
> +  IN EFI_USBFN_IO_PROTOCOL      *This,
> +  IN EFI_USB_ENDPOINT_TYPE      EndpointType,
> +  IN EFI_USB_BUS_SPEED          BusSpeed,
> +  OUT UINT16                    *MaxPacketSize
> +  )
> +{
> +  EFI_STATUS                        Status;
> +  USB_XDCI_DEV_CONTEXT              *UsbFuncIoDevPtr;
> +  USB_DEV_CORE                      *DevCorePtr;
> +  XDCI_CORE_HANDLE                  *XdciCorePtr;
> +
> +  UsbFuncIoDevPtr = USBFUIO_CONTEXT_FROM_PROTOCOL (This);
> +  DevCorePtr = UsbFuncIoDevPtr->DrvCore;
> +  XdciCorePtr = DevCorePtr->ControllerHandle;
> +  Status = EFI_SUCCESS;
> +
> +  DEBUG ((USB_FUIO_DEBUG_LOAD, "GetEndpointMaxPacketSize - Entry\n"));
> +
> +  switch (EndpointType) {
> +    case UsbEndpointControl:
> +#ifdef SUPPORT_SUPER_SPEED
> +      *MaxPacketSize = USB_EP0_MAX_PKT_SIZE_SS; // Default to super Speed
> +#else
> +      *MaxPacketSize = USB_EP0_MAX_PKT_SIZE_HS; // Default to high Speed
> +#endif
> +      break;
> +
> +    case UsbEndpointBulk:
> +#ifdef SUPPORT_SUPER_SPEED
> +      *MaxPacketSize = USB_BULK_EP_PKT_SIZE_SS; // Default to super Speed
> +#else
> +      *MaxPacketSize = USB_BULK_EP_PKT_SIZE_HS; // Default to high Speed
> +#endif
> +      break;
> +
> +    case UsbEndpointInterrupt:
> +      *MaxPacketSize = 1;
> +      break;
> +
> +    case UsbEndpointIsochronous:
> +    default:
> +      Status = EFI_DEVICE_ERROR;
> +      break;
> +  }
> +
> +  DEBUG ((USB_FUIO_DEBUG_LOAD, "GetEndpointMaxPacketSize - Exit %r\n", Status));
> +  return Status;
> +}
> +
> +
> +/**
> +  Returns the maximum supported transfer size.
> +
> +  @param[in] This               A pointer to the EFI_USBFN_IO_PROTOCOL instance.
> +  @param[in] MaxTransferSize    The maximum supported transfer size, in bytes.
> +
> +  @retval EFI_SUCCESS           The function returned successfully.
> +  @retval EFI_INVALID_PARAMETER A parameter is invalid.
> +  @retval EFI_DEVICE_ERROR      The physical device reported an error.
> +  @retval EFI_NOT_READY         The physical device is busy or not ready to
> +                                process this request.
> +**/
> +EFI_STATUS
> +EFIAPI
> +GetMaxTransferSize (
> +  IN EFI_USBFN_IO_PROTOCOL     *This,
> +  OUT UINTN                    *MaxTransferSize
> +  )
> +{
> +  //
> +  // Need to check, Make max transfer package to 8MB
> +  //
> +  *MaxTransferSize = MAX_TRANSFER_PACKET;
> +  return EFI_SUCCESS;
> +}
> +
> +
> +/**
> +  This function returns the unique device ID of the device--this matches
> +  what is populated in the SMBIOS table.
> +
> +  @param[in/out] BufferSize     On input, the size of the Buffer in bytes.
> +                                On output, the amount of data returned in Buffer
> +                                in bytes.
> +
> +  @param[out] Buffer            A pointer to a Buffer to return the requested
> +                                information as a Unicode string. What string are
> +                                we talking about
> +
> +  @retval EFI_SUCCESS           The function returned successfully.
> +  @retval EFI_BUFFER_TOO_SMALL  A parameter is invalid.
> +
> +**/
> +STATIC
> +EFI_STATUS
> +EFIAPI
> +GetDeviceSerialNumber (
> +    IN OUT UINTN *BufferSize,
> +    OUT VOID *Buffer OPTIONAL
> +  )
> +{
> +    EFI_STATUS Status = EFI_SUCCESS;
> +    CHAR16 UuidString[CHARS_IN_GUID];
> +    UINTN CharsCopied;
> +
> +    DEBUG ((USB_FUIO_DEBUG_LOAD, "+GetDeviceSerialNumber\n"));
> +    //
> +    // check bounds
> +    //
> +    if (*BufferSize < sizeof(UuidString)) {
> +        Status = EFI_BUFFER_TOO_SMALL;
> +        *BufferSize = 0;
> +        goto Error;
> +    }
> +
> +    //
> +    // The rest of mSmBiosUniqueGuid will be same. Note that we cannot
> +    // read the SMBIOS table directly, as it might not be ready by the time we
> +    // are to read it. The population of the data from the eMMC is ready
> +    // by the time we are here.
> +    //
> +
> +    //
> +    // Print to to a string, and copy it off
> +    //
> +    CharsCopied = UnicodeSPrint(UuidString, sizeof(UuidString), L"%g", &mSmBiosUniqueGuid);
> +    if (CharsCopied != (CHARS_IN_GUID - 1))
> +    {
> +        Status = EFI_BUFFER_TOO_SMALL;
> +        *BufferSize = 0;
> +        goto Error;
> +    }
> +    CopyMem(Buffer, UuidString, sizeof(UuidString));
> +    *BufferSize = sizeof(UuidString);
> +
> +Error:
> +
> +    DEBUG ((USB_FUIO_DEBUG_LOAD, "-GetDeviceSerialNumber, Status = 0x%08x\r\n", Status));
> +
> +    return Status;
> +}
> +
> +
> +/**
> +  Returns device specific information Based on the supplied identifier as
> +  a Unicode string
> +
> +  @param[in] This               A pointer to the EFI_USBFN_IO_PROTOCOL instance.
> +  @param[in] Id                 Requested information id.
> +  @param[in] BufferSize         On input, the size of the Buffer in bytes.
> +                                On output, the amount of data returned in Buffer
> +                                in bytes.
> +  @param[in] Buffer             A pointer to a Buffer to return the requested
> +                                information as a Unicode string. What string are
> +                                we talking about
> +
> +  @retval EFI_SUCCESS           The function returned successfully.
> +  @retval EFI_INVALID_PARAMETER A parameter is invalid.
> +  @retval EFI_DEVICE_ERROR      The physical device reported an error.
> +  @retval EFI_NOT_READY         The physical device is busy or not ready to
> +                                process this request.
> +**/
> +EFI_STATUS
> +EFIAPI
> +GetDeviceInfo (
> +  IN EFI_USBFN_IO_PROTOCOL      *This,
> +  IN EFI_USBFN_DEVICE_INFO_ID   Id,
> +  IN OUT UINTN                  *BufferSize,
> +  OUT VOID                      *Buffer OPTIONAL
> +  )
> +{
> +  EFI_STATUS                    Status;
> +  USB_XDCI_DEV_CONTEXT          *UsbFuncIoDevPtr;
> +
> +  UsbFuncIoDevPtr = USBFUIO_CONTEXT_FROM_PROTOCOL (This);
> +  Status = EFI_SUCCESS;
> +
> +  DEBUG ((USB_FUIO_DEBUG_LOAD, "GetDeviceInfo - Entry\n"));
> +
> +  if ((BufferSize == 0) || (Buffer == NULL)) {
> +    Status = EFI_INVALID_PARAMETER;
> +    goto FUN_EXIT;
> +  }
> +
> +  switch (Id) {
> +
> +    //
> +    // FIXME: Get real serial number of board
> +    //
> +    case EfiUsbDeviceInfoSerialNumber:
> +        if (*BufferSize < sizeof(mUsbFnDxeSerialNumber)) {
> +            Status = EFI_BUFFER_TOO_SMALL;
> +            *BufferSize = 0;
> +            goto FUN_EXIT;
> +        }
> +        CopyMem(Buffer, mUsbFnDxeSerialNumber, sizeof(mUsbFnDxeSerialNumber));
> +        *BufferSize = sizeof(mUsbFnDxeSerialNumber);
> +        break;
> +
> +    case EfiUsbDeviceInfoManufacturerName:
> +        if (*BufferSize < sizeof(mUsbFnDxeMfgString)) {
> +            Status = EFI_BUFFER_TOO_SMALL;
> +            *BufferSize = 0;
> +            goto FUN_EXIT;
> +        }
> +        CopyMem(Buffer, mUsbFnDxeMfgString, sizeof(mUsbFnDxeMfgString));
> +        *BufferSize = sizeof(mUsbFnDxeMfgString);
> +        break;
> +
> +    case EfiUsbDeviceInfoProductName:
> +        if (*BufferSize < sizeof(mUsbFnDxeProductString)) {
> +            Status = EFI_BUFFER_TOO_SMALL;
> +            *BufferSize = 0;
> +            goto FUN_EXIT;
> +        }
> +        CopyMem(Buffer, mUsbFnDxeProductString, sizeof(mUsbFnDxeProductString));
> +        *BufferSize = sizeof(mUsbFnDxeProductString);
> +        break;
> +
> +    case EfiUsbDeviceInfoUnknown:
> +    default:
> +      Status = EFI_UNSUPPORTED;
> +      *BufferSize = 0;
> +      DEBUG ((USB_FUIO_DEBUG_ERROR, "Unknown ID %d encountered.\r\n", Id));
> +      break;
> +  }
> +
> +FUN_EXIT:
> +  DEBUG ((USB_FUIO_DEBUG_LOAD, "UsbSetconfigure - ConfigDescriptor addr 0x%08x \n", (UINTN)UsbFuncIoDevPtr->IndexPtrConfig.ConfigDescriptor));
> +  DEBUG ((USB_FUIO_DEBUG_LOAD, "GetDeviceInfo - Exit %r\n", Status));
> +  return Status;
> +}
> +
> +
> +/**
> +  Returns vendor-id and product-id of the device.
> +
> +  @param[in]  This              A pointer to the EFI_USBFN_IO_PROTOCOL instance.
> +  @param[out] Vid               Returned vendor-id of the device.
> +  @param[out] Pid               Returned product-id of the device.
> +
> +  @retval EFI_SUCCESS           The function returned successfully.
> +  @retval EFI_INVALID_PARAMETER A parameter is invalid.
> +  @retval EFI_NOT_FOUND         Unable to return vid or pid.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +GetVendorIdProductId (
> +  IN EFI_USBFN_IO_PROTOCOL      *This,
> +  OUT UINT16                    *Vid,
> +  OUT UINT16                    *Pid
> +  )
> +{
> +  USB_XDCI_DEV_CONTEXT              *UsbFuncIoDevPtr;
> +
> +  UsbFuncIoDevPtr = USBFUIO_CONTEXT_FROM_PROTOCOL (This);
> +  //
> +  //   *Vid = 0x8086
> +  //   *Pid = 0x0A65
> +  //
> +  *Vid = UsbFuncIoDevPtr->VendorId;
> +  *Pid = UsbFuncIoDevPtr->DeviceId;
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  Aborts transfer on the specified endpoint.
> +
> +  @param[in]  This              A pointer to the EFI_USBFN_IO_PROTOCOL instance.
> +  @param[in]  EndpointIndex     Indicates the endpoint on which the ongoing
> +                                transfer needs to be canceled.
> +  @param[in]  Direction         Direction of the endpoint.
> +
> +
> +  @retval EFI_SUCCESS           The function returned successfully.
> +  @retval EFI_INVALID_PARAMETER A parameter is invalid.
> +  @retval EFI_DEVICE_ERROR      The physical device reported an error.
> +  @retval EFI_NOT_READY         The physical device is busy or not ready to
> +                                process this request.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +AbortTransfer (
> +  IN EFI_USBFN_IO_PROTOCOL        *This,
> +  IN UINT8                        EndpointIndex,
> +  IN EFI_USBFN_ENDPOINT_DIRECTION Direction
> +  )
> +{
> +  USB_XDCI_DEV_CONTEXT              *UsbFuncIoDevPtr;
> +  XDCI_CORE_HANDLE                  *XdciCorePtr;
> +  USB_DEV_CORE                      *UsbDeviceCorePtr;
> +  USB_EP_INFO                       EpInfo;
> +  EFI_STATUS                        Status;
> +
> +  DEBUG ((USB_FUIO_DEBUG_LOAD, "FU:AbortTransfer - Entry\n"));
> +  UsbFuncIoDevPtr = USBFUIO_CONTEXT_FROM_PROTOCOL (This);
> +  UsbDeviceCorePtr = UsbFuncIoDevPtr->DrvCore;
> +  XdciCorePtr = UsbDeviceCorePtr->ControllerHandle;
> +  Status = EFI_SUCCESS;
> +
> +  if (UsbFuncIoDevPtr->DevResetFlag == TRUE) {
> +    return Status;
> +  }
> +
> +  EpInfo.EpNum = EndpointIndex;
> +  EpInfo.EpDir = Direction? UsbEpDirIn : UsbEpDirOut;
> +
> +  Status = UsbDeviceEpCancelTransfer (UsbFuncIoDevPtr->DrvCore, &EpInfo);
> +
> +  DEBUG ((USB_FUIO_DEBUG_LOAD, "FU:AbortTransfer - Exit %r\n", Status));
> +  return Status;
> +}
> +
> +/**
> +  Returns the stall state on the specified endpoint.
> +
> +  @param[in]  This              A pointer to the EFI_USBFN_IO_PROTOCOL instance.
> +  @param[in]  EndpointIndex     Indicates the endpoint on which the ongoing
> +                                transfer needs to be canceled.
> +  @param[in]  Direction         Direction of the endpoint.
> +  @param[in]  State             Boolean, true value indicates that the endpoint
> +                                is in a stalled state, false otherwise.
> +
> +  @retval EFI_SUCCESS           The function returned successfully.
> +  @retval EFI_INVALID_PARAMETER A parameter is invalid.
> +  @retval EFI_DEVICE_ERROR      The physical device reported an error.
> +  @retval EFI_NOT_READY         The physical device is busy or not ready to
> +                                process this request.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +GetEndpointStallState (
> +  IN EFI_USBFN_IO_PROTOCOL        *This,
> +  IN UINT8                        EndpointIndex,
> +  IN EFI_USBFN_ENDPOINT_DIRECTION Direction,
> +  IN OUT BOOLEAN                  *State
> +  )
> +{
> +  USB_XDCI_DEV_CONTEXT              *UsbFuncIoDevPtr;
> +  XDCI_CORE_HANDLE                  *XdciCorePtr;
> +  UINT32                            EndPoint;
> +
> +  UsbFuncIoDevPtr = USBFUIO_CONTEXT_FROM_PROTOCOL (This);
> +  DEBUG ((USB_FUIO_DEBUG_LOAD, "GetEndpointStallState - Entry\n"));
> +
> +  EndPoint = UsbGetPhysicalEpNum (EndpointIndex, Direction ? UsbEpDirIn : UsbEpDirOut);
> +
> +  XdciCorePtr = UsbFuncIoDevPtr->XdciDrvIfHandle;
> +
> +  if (XdciCorePtr->EpHandles[EndPoint].State == USB_EP_STATE_STALLED) {
> +    *State = TRUE;
> +  } else {
> +    *State = FALSE;
> +  }
> +
> +  DEBUG ((USB_FUIO_DEBUG_LOAD, "GetEndpointStallState - Exit\n"));
> +  return EFI_SUCCESS;
> +}
> +
> +
> +EFI_STATUS
> +UsbSetAddress (
> +  IN EFI_USBFN_IO_PROTOCOL        *This,
> +  IN UINT32                        Address
> +  )
> +{
> +  EFI_STATUS                        Status;
> +  USB_XDCI_DEV_CONTEXT              *UsbFuncIoDevPtr;
> +  XDCI_CORE_HANDLE                  *XdciCorePtr;
> +  USB_DEV_CORE                      *UsbDeviceCorePtr;
> +
> +  DEBUG ((USB_FUIO_DEBUG_LOAD, "UsbSetAddress - 0x%04x Entry\n", Address));
> +
> +  UsbFuncIoDevPtr = USBFUIO_CONTEXT_FROM_PROTOCOL (This);
> +
> +  UsbDeviceCorePtr = UsbFuncIoDevPtr->DrvCore;
> +  XdciCorePtr = UsbDeviceCorePtr->ControllerHandle;
> +  Status = EFI_SUCCESS;
> +
> +  Status = UsbDeviceSetAddress (UsbDeviceCorePtr, (UINT32)Address);
> +
> +  if (Status != EFI_SUCCESS) {
> +    Status = EFI_DEVICE_ERROR;
> +    goto EXIT_SET_ADDRESS;
> +  }
> +
> +  Status = UsbDeviceEp0TxStatus (UsbDeviceCorePtr);
> +
> +  if (Status != EFI_SUCCESS) {
> +    Status = EFI_NO_RESPONSE;
> +    goto EXIT_SET_ADDRESS;
> +  }
> +
> +EXIT_SET_ADDRESS:
> +
> +  DEBUG ((USB_FUIO_DEBUG_LOAD, "UsbSetAddress - Exit %r\n", Status));
> +  return Status;
> +}
> +
> +
> +EFI_STATUS
> +EFIAPI
> +UsbSetconfigure (
> +  IN EFI_USBFN_IO_PROTOCOL        *This,
> +  IN UINT32                       InterFaceIndex
> +  )
> +{
> +  EFI_STATUS                      Status;
> +  USB_XDCI_DEV_CONTEXT            *UsbFuncIoDevPtr;
> +  XDCI_CORE_HANDLE                *XdciCorePtr;
> +  USB_DEV_CORE                    *UsbDeviceCorePtr;
> +  UINT32                          InterfaceNum;
> +  UINT32                          EndPointNum;
> +  UINT32                          EndPointIndex;
> +  EFI_USB_INTERFACE_INFO          *InterfaceInfoPtr;
> +  USB_EP_INFO                     EpInfo;
> +  USB_DEVICE_ENDPOINT_INFO        EpDescInfo;
> +
> +  DEBUG ((USB_FUIO_DEBUG_LOAD, "UsbSetconfigure - 0x%04x Entry\n", InterFaceIndex));
> +
> +  UsbFuncIoDevPtr = USBFUIO_CONTEXT_FROM_PROTOCOL (This);
> +  UsbDeviceCorePtr = UsbFuncIoDevPtr->DrvCore;
> +  XdciCorePtr = UsbDeviceCorePtr->ControllerHandle;
> +  Status = EFI_SUCCESS;
> +
> +  InterfaceNum = UsbFuncIoDevPtr->IndexPtrConfig.ConfigDescriptor->NumInterfaces;
> +  DEBUG ((USB_FUIO_DEBUG_LOAD, "UsbSetconfigure - ConfigDescriptor addr 0x%08x \n", (UINTN)UsbFuncIoDevPtr->IndexPtrConfig.ConfigDescriptor));
> +
> +  DEBUG ((USB_FUIO_DEBUG_LOAD, "UsbSetconfigure - DescriptorType 0x%04x ; ConfigurationValue 0x%04x\n",
> +          UsbFuncIoDevPtr->IndexPtrConfig.ConfigDescriptor->DescriptorType,
> +          UsbFuncIoDevPtr->IndexPtrConfig.ConfigDescriptor->ConfigurationValue
> +          ));
> +
> +  DEBUG ((USB_FUIO_DEBUG_LOAD, "UsbSetconfigure - InterfaceNum 0x%04x \n", InterfaceNum));
> +  if (InterfaceNum < InterFaceIndex) {
> +    Status = EFI_INVALID_PARAMETER;
> +    goto EXIT__SET_CONFIGURE;
> +  }
> +
> +  //
> +  // Arry strart form '0', Index start from '1'.
> +  //
> +  InterfaceInfoPtr = UsbFuncIoDevPtr->IndexPtrConfig.InterfaceInfoTable[InterFaceIndex - 1];
> +  EndPointNum = InterfaceInfoPtr->InterfaceDescriptor->NumEndpoints;
> +
> +  DEBUG ((USB_FUIO_DEBUG_LOAD, "UsbSetconfigure - Total EP NUM 0x%04x \n", EndPointNum));
> +
> +  for (EndPointIndex = 0; EndPointIndex < EndPointNum; EndPointIndex++) {
> +    EpDescInfo.EndpointDesc = InterfaceInfoPtr->EndpointDescriptorTable[EndPointIndex];
> +    EpDescInfo.EndpointCompDesc = NULL;
> +    UsbFnSetEpInfo (&EpInfo, &EpDescInfo);
> +    DEBUG ((USB_FUIO_DEBUG_LOAD, "EndpointAddress 0x%02x\n", EpDescInfo.EndpointDesc->EndpointAddress));
> +
> +    if (UsbDeviceInitEp (UsbDeviceCorePtr, &EpInfo) == EFI_SUCCESS) {
> +       if (UsbDeviceEpEnable (UsbDeviceCorePtr, &EpInfo) == EFI_SUCCESS) {
> +       } else {
> +         Status = EFI_DEVICE_ERROR;
> +         DEBUG ((DEBUG_INFO, "UsbDeviceEpEnable() - Failed to enable endpoint\n"));
> +       }
> +    } else {
> +       Status = EFI_DEVICE_ERROR;
> +       DEBUG ((DEBUG_INFO, "UsbDeviceInitEp() - Failed to initialize endpoint\n"));
> +    }
> +  }
> +
> +  Status = UsbDeviceEp0TxStatus (UsbDeviceCorePtr);
> +
> +  if (Status != EFI_SUCCESS) {
> +    Status = EFI_NO_RESPONSE;
> +    goto EXIT__SET_CONFIGURE;
> +  }
> +
> +
> +EXIT__SET_CONFIGURE:
> +  DEBUG ((USB_FUIO_DEBUG_LOAD, "UsbSetconfigure - Exit %r\n", Status));
> +
> +  return Status;
> +}
> +
> +/**
> +  Sets or clears the stall state on the specified endpoint.
> +
> +  @param[in]  This              A pointer to the EFI_USBFN_IO_PROTOCOL instance.
> +  @param[in]  EndpointIndex     Indicates the endpoint on which the ongoing
> +                                transfer needs to be canceled.
> +  @param[in]  Direction         Direction of the endpoint.
> +  @param[in]  State             Requested stall state on the specified endpoint.
> +                                True value causes the endpoint to stall;
> +                                false value clears an existing stall.
> +
> +  @retval EFI_SUCCESS           The function returned successfully.
> +  @retval EFI_INVALID_PARAMETER A parameter is invalid.
> +  @retval EFI_DEVICE_ERROR      The physical device reported an error.
> +  @retval EFI_NOT_READY         The physical device is busy or not ready to
> +                                process this request.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +SetEndpointStallState (
> +  IN EFI_USBFN_IO_PROTOCOL        *This,
> +  IN UINT8                        EndpointIndex,
> +  IN EFI_USBFN_ENDPOINT_DIRECTION Direction,
> +  IN BOOLEAN                      State
> +  )
> +{
> +  EFI_STATUS                        Status;
> +  USB_XDCI_DEV_CONTEXT              *UsbFuncIoDevPtr;
> +  USB_EP_INFO                       pEpInfo;
> +
> +  UsbFuncIoDevPtr = USBFUIO_CONTEXT_FROM_PROTOCOL (This);
> +
> +  DEBUG ((USB_FUIO_DEBUG_LOAD, "SetEndpointStallState - Entry\n"));
> +  Status = EFI_SUCCESS;
> +
> +  pEpInfo.EpNum = EndpointIndex;
> +  pEpInfo.EpDir = Direction? UsbEpDirIn : UsbEpDirOut;
> +
> +  if (State == TRUE) {
> +    Status = UsbDeviceEpStall (UsbFuncIoDevPtr->DrvCore, (VOID*)(UINTN) &pEpInfo);
> +  } else {
> +    Status = UsbDeviceEpClearStall (UsbFuncIoDevPtr->DrvCore, (VOID*)(UINTN) &pEpInfo);
> +  }
> +
> +  if (Status != EFI_SUCCESS) {
> +    Status = EFI_DEVICE_ERROR;
> +  }
> +
> +  DEBUG ((USB_FUIO_DEBUG_LOAD, "SetEndpointStallState - Exit\n"));
> +  return Status;
> +}
> +
> +EFI_STATUS
> +DeviceEventCheck(
> +  IN  EFI_USBFN_IO_PROTOCOL       *This,
> +  IN  USBD_EVENT_BUF              *EventIndex,
> +  OUT UINT32                      *ProcessSize,
> +  OUT EFI_USBFN_MESSAGE           *Message,
> +  OUT BOOLEAN                     *EventFlag
> +  )
> +{
> +  USB_XDCI_DEV_CONTEXT            *UsbFuncIoDevPtr;
> +  UINT32                          EventReg;
> +  USB_DEV_CORE                    *UsbDeviceCorePtr;
> +  XDCI_CORE_HANDLE                *XdciCorePtr;
> +
> +  DEBUG ((USB_FUIO_DEBUG_EVENT_D, "\n FUEV::DeviceEvent entry....\n"));
> +  UsbFuncIoDevPtr = USBFUIO_CONTEXT_FROM_PROTOCOL (This);
> +  UsbDeviceCorePtr = UsbFuncIoDevPtr->DrvCore;
> +  XdciCorePtr = UsbDeviceCorePtr->ControllerHandle;
> +  EventReg = (EventIndex->Event & DWC_XDCI_EVENT_BUFF_DEV_EVT_MASK);
> +  EventReg >>= DWC_XDCI_EVENT_BUFF_DEV_EVT_BIT_POS;
> +  *EventFlag = FALSE;
> +
> +  //
> +  // Assume default event size. Change it in switch case if
> +  // different
> +  //
> +  *ProcessSize =  DWC_XDCI_DEV_EVENT_DEFAULT_SIZE_IN_BYTES;
> +
> +  switch (EventReg) {
> +    case DWC_XDCI_EVENT_BUFF_DEV_DISCONN_EVENT:
> +      DEBUG ((USB_FUIO_DEBUG_EVENT_D, "USBFU_Device DWC_XDCI_EVENT_BUFF_DEV_DISCONN_EVENT\n"));
> +      *Message = EfiUsbMsgBusEventDetach;
> +      break;
> +
> +    case DWC_XDCI_EVENT_BUFF_DEV_USB_RESET_EVENT:
> +      DEBUG ((USB_FUIO_DEBUG_EVENT_D, "USBFU_Device DWC_XDCI_EVENT_BUFF_DEV_USB_RESET_EVENT\n"));
> +      //
> +      //  In resetDet will prepare setup Xfer package
> +      //
> +      UsbFuncIoDevPtr->DevReConnect = FALSE;
> +      UsbFuncIoDevPtr->DevResetFlag = TRUE;
> +
> +      usbProcessDeviceResetDet (XdciCorePtr);
> +      UsbDeviceSetAddress (UsbDeviceCorePtr, 0);
> +      *Message = EfiUsbMsgBusEventReset;
> +      *EventFlag = TRUE;
> +      break;
> +
> +    case DWC_XDCI_EVENT_BUFF_DEV_CONN_DONE_EVENT:
> +      DEBUG ((USB_FUIO_DEBUG_EVENT_D, "USBFU_Device DWC_XDCI_EVENT_BUFF_DEV_CONN_DONE_EVENT\n"));
> +      usbProcessDeviceResetDone(XdciCorePtr);
> +      UsbDeviceSetAddress(UsbDeviceCorePtr, 0);
> +      UsbFuncIoDevPtr->DevReConnect = TRUE;
> +      UsbFuncIoDevPtr->DevResetFlag = FALSE;
> +      *EventFlag = TRUE;
> +      *Message = EfiUsbMsgNone;
> +      break;
> +
> +    case DWC_XDCI_EVENT_BUFF_DEV_HBRNTN_REQ_EVENT:
> +      DEBUG ((USB_FUIO_DEBUG_EVENT_D, "USBFU_Device DWC_XDCI_EVENT_BUFF_DEV_HBRNTN_REQ_EVENT\n"));
> +      *Message = EfiUsbMsgBusEventSuspend;
> +      *EventFlag = TRUE;
> +      break;
> +
> +    case DWC_XDCI_EVENT_BUFF_DEV_WKUP_EVENT:
> +      DEBUG ((USB_FUIO_DEBUG_EVENT_D, "USBFU_Device DWC_XDCI_EVENT_BUFF_DEV_WKUP_EVENT\n"));
> +      *Message = EfiUsbMsgBusEventResume;
> +      break;
> +
> +    case DWC_XDCI_EVENT_BUFF_DEV_TST_LMP_RX_EVENT:
> +      *ProcessSize = DWC_XDCI_DEV_EVENT_TST_LMP_SIZE_IN_BYTES;
> +      *Message = EfiUsbMsgNone;
> +      DEBUG ((USB_FUIO_DEBUG_EVENT_D, "USBFUDwcXdciProcessDeviceEvent: UNHANDLED device event: %x\n", EventReg));
> +      break;
> +
> +    case DWC_XDCI_EVENT_BUFF_DEV_STATE_CHANGE_EVENT:
> +      DEBUG ((USB_FUIO_DEBUG_EVENT_D, "USBFU_Device DWC_XDCI_EVENT_BUFF_DEV_STATE_CHANGE_EVENT\n"));
> +      break;
> +
> +    case DWC_XDCI_EVENT_BUFF_DEV_SOF_EVENT:
> +      DEBUG ((USB_FUIO_DEBUG_EVENT_D, "USBFU_Device DWC_XDCI_EVENT_BUFF_DEV_SOF_EVENT\n"));
> +      break;
> +
> +    case DWC_XDCI_EVENT_BUFF_DEV_ERRATIC_ERR_EVENT:
> +      DEBUG ((USB_FUIO_DEBUG_EVENT_D, "USBFU_Device DWC_XDCI_EVENT_BUFF_DEV_ERRATIC_ERR_EVENT\n"));
> +      break;
> +
> +    case DWC_XDCI_EVENT_BUFF_DEV_CMD_CMPLT_EVENT:
> +      DEBUG ((USB_FUIO_DEBUG_EVENT_D, "USBFU_Device DWC_XDCI_EVENT_BUFF_DEV_CMD_CMPLT_EVENT\n"));
> +      break;
> +
> +    case DWC_XDCI_EVENT_BUFF_DEV_BUFF_OVFL_EVENT:
> +      DEBUG ((USB_FUIO_DEBUG_EVENT_D, "USBFU_Device DWC_XDCI_EVENT_BUFF_DEV_BUFF_OVFL_EVENT\n"));
> +      break;
> +
> +    default:
> +      *EventFlag = FALSE;
> +      *Message = EfiUsbMsgNone;
> +      DEBUG ((USB_FUIO_DEBUG_EVENT_I, "USBFUWcXdciProcessDeviceEvent: UNHANDLED device event: %x\n", EventReg));
> +      break;
> +  }
> +
> +  DEBUG ((USB_FUIO_DEBUG_EVENT_D, "\n FUEV::DeviceEvent entry exit.... \n"));
> +  return EFI_SUCCESS;
> +}
> +
> +
> +EFI_STATUS
> +Ep0XferDone(
> +  IN  EFI_USBFN_IO_PROTOCOL       *This,
> +  IN  UINT32                      EndPointNum,
> +  OUT EFI_USBFN_MESSAGE           *Message,
> +  IN OUT UINTN                    *PayloadSize,
> +  OUT EFI_USBFN_MESSAGE_PAYLOAD   *Payload
> +  )
> +{
> +  USB_DEV_CORE                    *UsbDeviceCorePtr;
> +  XDCI_CORE_HANDLE                *XdciCorePtr;
> +  USB_XDCI_DEV_CONTEXT            *UsbFuncIoDevPtr;
> +  DWC_XDCI_ENDPOINT               *EpHandle;
> +  DWC_XDCI_TRB                    *Trb;
> +  UINT32                          TrbCtrl;
> +  UINT32                          TrbSts;
> +  UINT32                          BufferLen;
> +  EFI_STATUS                      DevStatus;
> +  USB_EP_INFO                     EpInfo;
> +
> +  UsbFuncIoDevPtr = USBFUIO_CONTEXT_FROM_PROTOCOL (This);
> +  UsbDeviceCorePtr = UsbFuncIoDevPtr->DrvCore;
> +  XdciCorePtr = UsbDeviceCorePtr->ControllerHandle;
> +  EpHandle = &XdciCorePtr->EpHandles[EndPointNum];
> +  Trb = XdciCorePtr->Trbs + (EndPointNum * DWC_XDCI_TRB_NUM);
> +
> +  if (Trb->TrbCtrl & DWC_XDCI_TRB_CTRL_HWO_MASK) {
> +    DEBUG ((USB_FUIO_DEBUG_EVENT_D, "Ep0XferDone. HW owns TRB: %x!!!\n", (UINT32)(UINTN)Trb));
> +  }
> +
> +  DevStatus = EFI_SUCCESS;
> +  BufferLen = 0;
> +
> +  DEBUG ((USB_FUIO_DEBUG_EVENT_D, "EndPointNum:%d, TRB: Addr 0x%08x!!!\n", EndPointNum, (UINTN)Trb));
> +  DEBUG ((USB_FUIO_DEBUG_EVENT_D, "Ep0 done Trb->TrbCtrl: %x!!!\n", (UINT32)Trb->TrbCtrl));
> +  DEBUG ((USB_FUIO_DEBUG_EVENT_D, "Ep0 done Trb->LenXferParams: %x!!!\n", (UINT32)Trb->LenXferParams));
> +  DEBUG ((USB_FUIO_DEBUG_EVENT_D, "Ep0 done Trb->BuffPtrLow: %x!!!\n", (UINT32)Trb->BuffPtrLow));
> +  DEBUG ((USB_FUIO_DEBUG_EVENT_D, "Ep0 done Trb->BuffPtrHigh: %x!!!\n", (UINT32)Trb->BuffPtrHigh));
> +
> +  //
> +  // Set CheckFlag to FALSE for 'DwcXdciEpRxData' function
> +  // check the RX request complete and continue next transfer request
> +  //
> +  EpHandle->CheckFlag = FALSE;
> +  EpHandle->CurrentXferRscIdx = 0;
> +
> +  DEBUG ((USB_FUIO_DEBUG_EVENT_I, "Ep0 done D01!!\n"));
> +  TrbCtrl = (Trb->TrbCtrl & DWC_XDCI_TRB_CTRL_TYPE_MASK) >> DWC_XDCI_TRB_CTRL_TYPE_BIT_POS;
> +
> +  DEBUG ((USB_FUIO_DEBUG_EVENT_I, "Ep0 done D02!!\n"));
> +  TrbSts = (Trb->LenXferParams & DWC_XDCI_TRB_STATUS_MASK) >> DWC_XDCI_TRB_STATUS_BIT_POS;
> +
> +  DEBUG ((USB_FUIO_DEBUG_EVENT_I, "Ep0 done D03!!\n" ));
> +  BufferLen = Trb->LenXferParams & DWC_XDCI_TRB_BUFF_SIZE_MASK;
> +
> +  DEBUG ((USB_FUIO_DEBUG_EVENT_I, "Ep0 done D04 TrbCtrl :: %x!!\n", TrbCtrl));
> +  switch (TrbCtrl) {
> +    case DWC_XDCI_TRB_CTRL_TYPE_SETUP:
> +      DEBUG ((USB_FUIO_DEBUG_EVENT_D, "Ep0 done DWC_XDCI_TRB_CTRL_TYPE_SETUP!!\n"));
> +      //
> +      // This is delay for other host USB controller(none Intel), identify device get fail issue.
> +      //
> +      gBS->Stall(130);
> +      BufferLen = 8;
> +
> +      DEBUG ((USB_FUIO_DEBUG_EVENT_D, "DWC_XDCI_TRB_CTRL_TYPE_SETUP!!\n"));
> +      DEBUG ((USB_FUIO_DEBUG_EVENT_D, "AlignedSetupBuffer::0x%08x!!\n", XdciCorePtr->AlignedSetupBuffer));
> +      DEBUG ((USB_FUIO_DEBUG_EVENT_D, "Payload::0x%08x!!\n", (UINTN)Payload));
> +      DEBUG ((USB_FUIO_DEBUG_EVENT_D, "BufferLen::0x%08x!!\n", (UINTN)BufferLen));
> +      *Message = EfiUsbMsgSetupPacket;
> +      CopyMem (Payload, XdciCorePtr->AlignedSetupBuffer, BufferLen);
> +
> +      DEBUG ((USB_FUIO_DEBUG_EVENT_I, "Ep0 done D06!!\n"));
> +      if (!(XdciCorePtr->AlignedSetupBuffer[0] & USB_SETUP_DATA_PHASE_DIRECTION_MASK)) {
> +        if ((XdciCorePtr->AlignedSetupBuffer[0]  == 0x00) ) {
> +          if ((XdciCorePtr->AlignedSetupBuffer[1]  == USB_DEV_SET_ADDRESS)) {
> +            //
> +            // set address
> +            //
> +            UsbSetAddress (
> +              This,
> +              (UINT32)(XdciCorePtr->AlignedSetupBuffer[3] << 8 | XdciCorePtr->AlignedSetupBuffer[2])
> +              );
> +
> +            *Message = EfiUsbMsgNone;
> +          } else if ((XdciCorePtr->AlignedSetupBuffer[1]  == USB_DEV_SET_CONFIGURATION)) {
> +            DEBUG ((USB_FUIO_DEBUG_EVENT_I, "\n set configure !!!"));
> +            UsbSetconfigure (
> +              This,
> +              (UINT32)(XdciCorePtr->AlignedSetupBuffer[3] << 8 | XdciCorePtr->AlignedSetupBuffer[2])
> +              );
> +            *Message = EfiUsbMsgNone;
> +          }
> +        }
> +      }
> +
> +      DEBUG ((USB_FUIO_DEBUG_EVENT_I, "Ep0 done D07!!\n"));
> +      break;
> +
> +    case DWC_XDCI_TRB_CTRL_TYPE_DATA:
> +      DEBUG ((DEBUG_INFO, "Ep0 done DWC_XDCI_TRB_CTRL_TYPE_DATA!!\n"));
> +	  //
> +      // Notify upper layer of control transfer completion
> +      // if a callback function was registerd
> +      //
> +      if ((EndPointNum & 0x01) == 0) {
> +        *Message = EfiUsbMsgEndpointStatusChangedRx;
> +      } else {
> +        *Message = EfiUsbMsgEndpointStatusChangedTx;
> +      }
> +      Payload->utr.EndpointIndex = (UINT8)(EndPointNum >> 1);
> +      Payload->utr.Direction = (UINT8)(EndPointNum & 0x01);
> +      Payload->utr.Buffer = (VOID*)(UINTN)(Trb->BuffPtrLow);
> +
> +      DEBUG ((DEBUG_INFO, "Ep0 EndPointNum: %x!!!\n", (UINT32)EndPointNum));
> +      DEBUG ((DEBUG_INFO, "Ep0 done XferLength: %x!!!\n", (UINT32)UsbFuncIoDevPtr->EndPointXferRec[EndPointNum].XferLength));
> +      Payload->utr.Buffer = (VOID*)UsbFuncIoDevPtr->EndPointXferRec[EndPointNum].XferAddress;
> +      Payload->utr.BytesTransferred = UsbFuncIoDevPtr->EndPointXferRec[EndPointNum].XferLength;
> +
> +      if (TrbSts == 0) {
> +        if ((Trb->LenXferParams & DWC_XDCI_TRB_BUFF_SIZE_MASK) == 0) {
> +          Payload->utr.TransferStatus = UsbTransferStatusComplete;
> +        } else {
> +          Payload->utr.TransferStatus = UsbTransferStatusActive;
> +        }
> +      } else if (TrbSts != 0) {
> +        Trb->TrbCtrl |= DWC_XDCI_TRB_CTRL_HWO_MASK;
> +        *Message = EfiUsbMsgNone;
> +        Payload->utr.TransferStatus = UsbTransferStatusAborted;
> +        DEBUG ((DEBUG_INFO, "Flush FIFO!!!\n" ));
> +        EpInfo.EpNum = 0;
> +        EpInfo.EpDir =UsbEpDirIn;
> +        UsbXdciCoreFlushEpFifo(XdciCorePtr, &EpInfo);
> +        EpInfo.EpNum = 0;
> +        EpInfo.EpDir =UsbEpDirOut;
> +        UsbXdciCoreFlushEpFifo(XdciCorePtr, &EpInfo);
> +        DevStatus = UsbDeviceEp0RxSetup (UsbDeviceCorePtr, XdciCorePtr->AlignedSetupBuffer);
> +      }
> +
> +      break;
> +
> +    case DWC_XDCI_TRB_CTRL_TYPE_STATUS2:
> +    case DWC_XDCI_TRB_CTRL_TYPE_STATUS3:
> +      Payload->utr.Buffer = (VOID*) UsbFuncIoDevPtr->EndPointXferRec[EndPointNum].XferAddress;
> +      Payload->utr.BytesTransferred = 0;
> +      Payload->utr.EndpointIndex = (UINT8)(EndPointNum >> 1);
> +      if ((EndPointNum & 0x01) == 0) {
> +        *Message = EfiUsbMsgEndpointStatusChangedRx;
> +      } else {
> +        *Message = EfiUsbMsgEndpointStatusChangedTx;
> +      }
> +
> +      if (TrbSts == 0) {
> +        if ((Trb->LenXferParams & DWC_XDCI_TRB_BUFF_SIZE_MASK) == 0) {
> +          Payload->utr.TransferStatus = UsbTransferStatusComplete;
> +        } else {
> +          Payload->utr.TransferStatus = UsbTransferStatusActive;
> +        }
> +      } else if (TrbSts != 0) {
> +        Payload->utr.TransferStatus = UsbTransferStatusAborted;
> +      }
> +
> +      DevStatus = UsbDeviceEp0RxSetup (UsbDeviceCorePtr, XdciCorePtr->AlignedSetupBuffer);
> +
> +      if (DevStatus) {
> +        DEBUG ((DEBUG_INFO, "DwcXdciProcessEp0XferPhaseDone: FAILED to queue SETUP\n"));
> +      }
> +      DEBUG ((DEBUG_INFO, "Status phase done. Queue next SETUP packet==>\n"));
> +      break;
> +
> +    default:
> +      *Message = EfiUsbMsgNone;
> +      DEBUG ((DEBUG_INFO, "DwcXdciProcessEp0XferPhaseDone: UNHANDLED STATE in TRB\n"));
> +      break;
> +  }
> +  return EFI_SUCCESS;
> +}
> +
> +
> +EFI_STATUS
> +NoneEp0XferDone(
> +  IN  EFI_USBFN_IO_PROTOCOL       *This,
> +  IN  UINT32                      EndPointNum,
> +  OUT EFI_USBFN_MESSAGE           *Message,
> +  IN OUT UINTN                    *PayloadSize,
> +  OUT EFI_USBFN_MESSAGE_PAYLOAD   *Payload
> +  )
> +{
> +  USB_DEV_CORE                    *UsbDeviceCorePtr;
> +  XDCI_CORE_HANDLE                *XdciCorePtr;
> +  USB_XDCI_DEV_CONTEXT            *UsbFuncIoDevPtr;
> +  DWC_XDCI_ENDPOINT               *EpHandle;
> +  DWC_XDCI_TRB                    *Trb;
> +  UINT32                          TrbCtrl;
> +  UINT32                          TrbSts;
> +
> +  UsbFuncIoDevPtr = USBFUIO_CONTEXT_FROM_PROTOCOL (This);
> +  UsbDeviceCorePtr = UsbFuncIoDevPtr->DrvCore;
> +  XdciCorePtr = UsbDeviceCorePtr->ControllerHandle;
> +  EpHandle = &XdciCorePtr->EpHandles[EndPointNum];
> +  Trb = XdciCorePtr->Trbs + (EndPointNum * DWC_XDCI_TRB_NUM);
> +
> +  if (Trb->TrbCtrl & DWC_XDCI_TRB_CTRL_HWO_MASK) {
> +    DEBUG ((USB_FUIO_DEBUG_EVENT_D, "NoneEp0XferDone. HW owns TRB: %x!!!, EndPointNum: %x\n", (UINT32)(UINTN)Trb, EndPointNum));
> +  }
> +
> +  DEBUG ((USB_FUIO_DEBUG_EVENT_D, " TRB: Addr 0x%08x!!!\n", (UINTN)Trb));
> +  DEBUG ((USB_FUIO_DEBUG_EVENT_D, " Xfer done Trb->BuffPtrLow: %x!!!\n", (UINT32)Trb->BuffPtrLow));
> +  DEBUG ((USB_FUIO_DEBUG_EVENT_D, " Xfer done Trb->BuffPtrHigh: %x!!!\n", (UINT32)Trb->BuffPtrHigh));
> +  DEBUG ((USB_FUIO_DEBUG_EVENT_D, " Xfer done Trb->LenXferParams: %x!!!\n", (UINT32)Trb->LenXferParams));
> +  DEBUG ((USB_FUIO_DEBUG_EVENT_D, " Xfer done Trb->TrbCtrl: %x!!!\n", (UINT32)Trb->TrbCtrl));
> +
> +  //
> +  // Set CheckFlag to FALSE for 'DwcXdciEpRxData' function
> +  // check the RX request complete and continue next transfer request
> +  //
> +  EpHandle->CheckFlag = FALSE;
> +  EpHandle->CurrentXferRscIdx = 0;
> +  *Message = EfiUsbMsgNone;
> +
> +  TrbCtrl = (Trb->TrbCtrl & DWC_XDCI_TRB_CTRL_TYPE_MASK) >> DWC_XDCI_TRB_CTRL_TYPE_BIT_POS;
> +  TrbSts = (Trb->LenXferParams & DWC_XDCI_TRB_STATUS_MASK) >> DWC_XDCI_TRB_STATUS_BIT_POS;
> +
> +  Payload->utr.BytesTransferred = UsbFuncIoDevPtr->EndPointXferRec[EndPointNum].XferLength;
> +  Payload->utr.EndpointIndex = UsbFuncIoDevPtr->EndPointXferRec[EndPointNum].LogEpNum;
> +  Payload->utr.Direction = UsbFuncIoDevPtr->EndPointXferRec[EndPointNum].Direction;
> +  Payload->utr.Buffer = (VOID*)(UINTN)(Trb->BuffPtrLow);
> +  UsbFuncIoDevPtr->EndPointXferRec[EndPointNum].Complete = TRUE;
> +
> +  DEBUG ((USB_FUIO_DEBUG_EVENT_D, "EndPointAddress = 0x%08x\n", Payload->utr.EndpointIndex));
> +  if (Payload->utr.Direction == EfiUsbEndpointDirectionDeviceTx) {
> +    DEBUG ((USB_FUIO_DEBUG_EVENT_D, " Direction::EfiUsbEndpointDirectionDeviceTx\n"));
> +    *Message = EfiUsbMsgEndpointStatusChangedTx;
> +  } else {
> +    DEBUG ((USB_FUIO_DEBUG_EVENT_D, " Direction::EfiUsbEndpointDirectionDeviceRx\n"));
> +    *Message = EfiUsbMsgEndpointStatusChangedRx;
> +  }
> +
> +  if (TrbSts == 0) {
> +    if ((Trb->LenXferParams & DWC_XDCI_TRB_BUFF_SIZE_MASK) == 0) {
> +      Payload->utr.TransferStatus = UsbTransferStatusComplete;
> +      DEBUG ((USB_FUIO_DEBUG_EVENT_D, "XferStatus::UsbTransferStatusComplete\n"));
> +    } else {
> +      Payload->utr.TransferStatus = UsbTransferStatusComplete;
> +      Payload->utr.BytesTransferred -= (Trb->LenXferParams & DWC_XDCI_TRB_BUFF_SIZE_MASK);
> +      DEBUG ((USB_FUIO_DEBUG_EVENT_D, "XferStatus::UsbTransferStatusComplete\n"));
> +      DEBUG ((USB_FUIO_DEBUG_EVENT_D, "XferStatus::Length %d \n", Payload->utr.BytesTransferred ));
> +    }
> +  } else if (TrbSts != 0) {
> +    Payload->utr.TransferStatus = UsbTransferStatusAborted;
> +    DEBUG ((USB_FUIO_DEBUG_EVENT_D, "XferStatus::UsbTransferStatusAborted\n"));
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +EFI_STATUS
> +Ep0XferNotReady(
> +  IN  EFI_USBFN_IO_PROTOCOL       *This,
> +  IN  UINT32                      EndPointNum,
> +  OUT EFI_USBFN_MESSAGE           *Message,
> +  IN OUT UINTN                    *PayloadSize,
> +  OUT EFI_USBFN_MESSAGE_PAYLOAD   *Payload,
> +  IN  UINT32                      EpStatus
> +  )
> +{
> +  USB_DEV_CORE                    *UsbDeviceCorePtr;
> +  XDCI_CORE_HANDLE                *XdciCorePtr;
> +  USB_XDCI_DEV_CONTEXT            *UsbFuncIoDevPtr;
> +
> +  UsbFuncIoDevPtr = USBFUIO_CONTEXT_FROM_PROTOCOL(This);
> +  UsbDeviceCorePtr = UsbFuncIoDevPtr->DrvCore;
> +  XdciCorePtr = UsbDeviceCorePtr->ControllerHandle;
> +
> +  *Message = EfiUsbMsgNone;
> +
> +  return EFI_SUCCESS;
> +}
> +
> +
> +EFI_STATUS
> +EpEventCheck(
> +  IN  EFI_USBFN_IO_PROTOCOL       *This,
> +  IN  USBD_EVENT_BUF              *EventIndex,
> +  OUT UINT32                      *ProcessSize,
> +  OUT EFI_USBFN_MESSAGE           *Message,
> +  IN OUT UINTN                    *PayloadSize,
> +  OUT EFI_USBFN_MESSAGE_PAYLOAD   *Payload,
> +  OUT BOOLEAN                     *EventFlag
> +  )
> +{
> +  USB_DEV_CORE                    *UsbDeviceCorePtr;
> +  XDCI_CORE_HANDLE                *XdciCorePtr;
> +  USB_XDCI_DEV_CONTEXT            *UsbFuncIoDevPtr;
> +  UINT32                          EventReg;
> +  UINT32                          EpEvent;
> +  UINT32                          EndPointNumber;
> +  UINT32                          EventStatus;
> +  USB_EP_STATE                    Ep_State;
> +  UINTN                           TmpBufferSize;
> +
> +  DEBUG ((USB_FUIO_DEBUG_EVENT_I, "FUEV::EndPoint Event....\n"));
> +  UsbFuncIoDevPtr = USBFUIO_CONTEXT_FROM_PROTOCOL(This);
> +
> +  UsbDeviceCorePtr = UsbFuncIoDevPtr->DrvCore;
> +  XdciCorePtr = UsbDeviceCorePtr->ControllerHandle;
> +  EventReg = EventIndex->Event;
> +  *ProcessSize = DWC_XDCI_DEV_EVENT_DEFAULT_SIZE_IN_BYTES;
> +  *EventFlag = TRUE;
> +  TmpBufferSize = 0;
> +
> +  //
> +  // Get EP num
> +  //
> +  EndPointNumber = (EventReg & DWC_XDCI_EVENT_BUFF_EP_NUM_MASK) >> DWC_XDCI_EVENT_BUFF_EP_NUM_BIT_POS;
> +
> +  EventStatus = EventReg & DWC_XDCI_EVENT_BUFF_EP_EVENT_STATUS_MASK;
> +
> +  //
> +  // Interpret event and handle transfer completion here
> +  //
> +  EpEvent = (EventReg & DWC_XDCI_EVENT_BUFF_EP_EVENT_MASK) >> DWC_XDCI_EVENT_BUFF_EP_EVENT_BIT_POS;
> +
> +  DEBUG ((USB_FUIO_DEBUG_EVENT_I, "USBFU_EP EventReg 0x%08x\n", EventReg));
> +
> +  switch (EpEvent) {
> +    case DWC_XDCI_EVENT_BUFF_EP_XFER_CMPLT:
> +      DEBUG ((USB_FUIO_DEBUG_EVENT_D, "USBFU_EP DWC_XDCI_EVENT_BUFF_EP_XFER_CMPLT\n"));
> +      if (EndPointNumber > 1) {
> +        DEBUG ((USB_FUIO_DEBUG_EVENT_D, "USBFU_EP None_Control transfer\n"));
> +        NoneEp0XferDone (This, EndPointNumber, Message, PayloadSize, Payload);
> +      } else {
> +        //
> +        // Control transfer
> +        //
> +        DEBUG ((USB_FUIO_DEBUG_EVENT_D, "USBFU_EP Control transfer\n"));
> +        Ep0XferDone (This, EndPointNumber, Message, PayloadSize, Payload);
> +      }
> +      break;
> +
> +    case DWC_XDCI_EVENT_BUFF_EP_XFER_NOT_READY:
> +      DEBUG ((USB_FUIO_DEBUG_EVENT_D, "DWC_XDCI_EVENT_BUFF_EP_XFER_NOT_READY\n"));
> +      *Message = EfiUsbMsgNone;
> +      if(EndPointNumber < (sizeof(UsbFuncIoDevPtr->EndPointXferRec) / sizeof(UsbFuncIoDevPtr->EndPointXferRec[0]))) {
> +        if ((UsbFuncIoDevPtr->EndPointXferRec[EndPointNumber].ZlpFlag == TRUE) && \
> +              (UsbFuncIoDevPtr->EndPointXferRec[EndPointNumber].Complete == TRUE)) {
> +          DEBUG ((USB_FUIO_DEBUG_EVENT_D, "Request send ZLP\n"));
> +          if ((EndPointNumber & 0x01) != 0) {
> +            Transfer(This,
> +                     UsbFuncIoDevPtr->IndexPtrInEp.EndpointDesc->EndpointAddress,
> +                     EfiUsbEndpointDirectionDeviceTx,
> +                     &TmpBufferSize,
> +                     NULL
> +                    );
> +            UsbFuncIoDevPtr->EndPointXferRec[EndPointNumber].ZlpFlag = FALSE;
> +          }
> +
> +        }
> +      } else {
> +        //
> +        // Is it data stage or status stage
> +        //
> +        // Data Statge
> +        //
> +        Ep_State = USB_EP_STATE_DATA;
> +        //
> +        // Control transfer
> +        //
> +        DEBUG ((USB_FUIO_DEBUG_EVENT_D, "USBFU_EP Control transfer not ready\n"));
> +        Ep0XferNotReady (This, EndPointNumber, Message, PayloadSize, Payload, EventStatus);
> +        *EventFlag = FALSE;
> +      }
> +      break;
> +
> +    case DWC_XDCI_EVENT_BUFF_EP_XFER_IN_PROGRESS:
> +      DEBUG ((USB_FUIO_DEBUG_EVENT_D, "DWC_XDCI_EVENT_BUFF_EP_XFER_IN_PROGRESS\n"));
> +      break;
> +
> +    default:
> +      DEBUG ((USB_FUIO_DEBUG_EVENT_I, "USBFUDwcXdciProcessEpEvent: UNKNOWN EP event\n"));
> +      break;
> +  }
> +
> +  DEBUG ((USB_FUIO_DEBUG_EVENT_D, "FUEV::EndPoint Event....exit\n"));
> +  return EFI_SUCCESS;
> +}
> +
> +
> +EFI_STATUS
> +ProcessIntLineEvents(
> +  IN EFI_USBFN_IO_PROTOCOL        *This,
> +  IN UINT32                       EventCount,
> +  IN UINT32                       *ProceSsEvent,
> +  OUT EFI_USBFN_MESSAGE           *Message,
> +  IN OUT UINTN                    *PayloadSize,
> +  OUT EFI_USBFN_MESSAGE_PAYLOAD   *Payload,
> +  OUT BOOLEAN                     *EventFlag
> +  )
> +{
> +  USB_DEV_CORE                    *UsbDeviceCorePtr;
> +  XDCI_CORE_HANDLE                *XdciCorePtr;
> +  USB_XDCI_DEV_CONTEXT            *UsbFuncIoDevPtr;
> +  UINT32                          CurrentEventAddr;
> +  UINT32                          ProceSsEventSize;
> +  BOOLEAN                         EventReport;
> +  BOOLEAN                         EpEventReport;
> +
> +  UsbFuncIoDevPtr = USBFUIO_CONTEXT_FROM_PROTOCOL (This);
> +  UsbDeviceCorePtr = UsbFuncIoDevPtr->DrvCore;
> +  XdciCorePtr = UsbDeviceCorePtr->ControllerHandle;
> +  CurrentEventAddr = (UINT32)(UINTN)(XdciCorePtr->CurrentEventBuffer);
> +  EventReport = FALSE;
> +  EpEventReport = FALSE;
> +  ProceSsEventSize = 0;
> +   DEBUG ((USB_FUIO_DEBUG_EVENT_I, "FUEV:: ProcessIntLineEvents Entry\n"));
> +
> +   DEBUG ((USB_FUIO_DEBUG_EVENT_I, "FUEV:: XdciCorePtr->CurrentEventBuffer 0x%08x\n", XdciCorePtr->CurrentEventBuffer));
> +   DEBUG ((USB_FUIO_DEBUG_EVENT_I, "FUEV::EventCount0x%08x\n", EventCount));
> +   DEBUG ((USB_FUIO_DEBUG_EVENT_I, "FUEV::CurrentEventAddr 0x%08x\n", CurrentEventAddr));
> +
> +  while ((EventCount != 0) && (EventReport == FALSE)) {
> +     DEBUG ((USB_FUIO_DEBUG_EVENT_D, "FUEV::event0x%08x\n", XdciCorePtr->CurrentEventBuffer->Event));
> +     if ((XdciCorePtr->CurrentEventBuffer->Event & DWC_XDCI_EVENT_DEV_MASK) != 0) {
> +       //
> +       // Device event
> +       //
> +       DeviceEventCheck (
> +         This,
> +         (USBD_EVENT_BUF*)(UINTN)CurrentEventAddr,
> +         &ProceSsEventSize,
> +         Message,
> +         &EventReport
> +         );
> +       if (EventReport == TRUE) {
> +         *EventFlag = TRUE;
> +       }
> +
> +     } else {
> +       //
> +       // EndPoint Event
> +       //
> +       EpEventCheck (
> +         This,
> +         (USBD_EVENT_BUF*)(UINTN)CurrentEventAddr,
> +         &ProceSsEventSize,
> +         Message,
> +         PayloadSize,
> +         Payload,
> +         &EpEventReport
> +         );
> +     }
> +
> +     if ((*Message != EfiUsbMsgNone) || (EpEventReport == TRUE)) {
> +       EventReport = TRUE;
> +       *EventFlag = TRUE;
> +     }
> +
> +     DEBUG ((USB_FUIO_DEBUG_EVENT_D, "FUEV:: CurrentEventAddr 0x%08x :: ProceSsEventSize 0x%08x\n", (UINTN)CurrentEventAddr,ProceSsEventSize));
> +
> +     EventCount -= ProceSsEventSize;
> +     *ProceSsEvent += ProceSsEventSize;
> +     if ((CurrentEventAddr + ProceSsEventSize) >= \
> +         ((UINT32)(UINTN)(XdciCorePtr->AlignedEventBuffers) +
> +          (sizeof(DWC_XDCI_EVENT_BUFFER) * DWC_XDCI_MAX_EVENTS_PER_BUFFER))) {
> +       CurrentEventAddr = (UINT32)(UINTN)(XdciCorePtr->AlignedEventBuffers);
> +    } else {
> +      CurrentEventAddr += ProceSsEventSize;
> +    }
> +    DEBUG ((USB_FUIO_DEBUG_EVENT_D, "FUEV:: CurrentEventAddr Update 0x%08x :: ProceSsEventSize 0x%08x\n", CurrentEventAddr,ProceSsEventSize));
> +
> +    XdciCorePtr->CurrentEventBuffer = (DWC_XDCI_EVENT_BUFFER*)(UINTN)CurrentEventAddr;
> +  }
> +
> +  DEBUG ((USB_FUIO_DEBUG_EVENT_I, "FUEV:: ProcessIntLineEvents Exit\n\n"));
> +  return EFI_SUCCESS;
> +}
> +
> +
> +/**
> +  ISR inokes Event Handler.  Look at which interrupt has happened and see
> +  if there are event handler registerd and if so fire them 1 by one.
> +
> +  @param[in]  This              A pointer to the EFI_USBFN_IO_PROTOCOL instance.
> +  @param[in]  Message           Indicates the event that initiated this
> +                                notification.
> +  @param[in]  PayloadSize       On input, the size of the memory pointed by Payload.
> +                                On output, the amount of data returned in Payload.
> +  @param[in]  Payload           A pointer to EFI_USBFN_MESSAGE_PAYLOAD instance to
> +                                return additional payload for current message.
> +
> +
> +
> +
> +  @retval EFI_SUCCESS           The function returned successfully.
> +  @retval EFI_INVALID_PARAMETER A parameter is invalid.
> +  @retval EFI_DEVICE_ERROR      The physical device reported an error.
> +  @retval EFI_NOT_READY         The physical device is busy or not ready to
> +                                process this request.
> +  @retval EFI_BUFFER_TOO_SMALL  Supplied Buffer not large enough to hold
> +                                the message payload.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +EventHandler(
> +  IN EFI_USBFN_IO_PROTOCOL        *This,
> +  OUT EFI_USBFN_MESSAGE           *Message,
> +  IN OUT UINTN                    *PayloadSize,
> +  OUT EFI_USBFN_MESSAGE_PAYLOAD   *Payload
> +  )
> +{
> +  UINT32                          EventCount;
> +  UINT32                          PeventCount;
> +  USB_XDCI_DEV_CONTEXT            *UsbFuncIoDevPtr;
> +  UINT32                          MaxIntNum;
> +  UINT32                          IntIndex;
> +  USB_DEV_CORE                    *UsbDeviceCorePtr;
> +  XDCI_CORE_HANDLE                *XdciCorePtr;
> +  BOOLEAN                         EventFlag;
> +  EFI_TPL                         OriginalTpl;
> +
> +
> +  DEBUG ((USB_FUIO_DEBUG_EVENT_I, "USBFU_ EventHandler Entry\n"));
> +  UsbFuncIoDevPtr = USBFUIO_CONTEXT_FROM_PROTOCOL (This);
> +
> +  if (UsbFuncIoDevPtr->StartUpController == FALSE) {
> +    UsbFnInitDevice (This);
> +  }
> +  OriginalTpl = gBS->RaiseTPL (TPL_HIGH_LEVEL);
> +  *Message = EfiUsbMsgNone;
> +  MaxIntNum = (UsbRegRead ((UINT32)UsbFuncIoDevPtr->XdciMmioBarAddr, DWC_XDCI_GHWPARAMS1_REG) &
> +                 DWC_XDCI_GHWPARAMS1_NUM_INT_MASK) >>
> +                 DWC_XDCI_GHWPARAMS1_NUM_INT_BIT_POS;
> +
> +  UsbDeviceCorePtr = UsbFuncIoDevPtr->DrvCore;
> +  XdciCorePtr = UsbDeviceCorePtr->ControllerHandle;
> +  EventFlag = TRUE;
> +
> +  DEBUG ((USB_FUIO_DEBUG_EVENT_I, "XdciCorePtr->MaxDevIntLines 0x%08x\n", XdciCorePtr->MaxDevIntLines));
> +  EventCount = UsbRegRead ((UINT32)UsbFuncIoDevPtr->XdciMmioBarAddr, DWC_XDCI_EVNTCOUNT_REG(0));
> +
> +  for (IntIndex = 0; IntIndex < XdciCorePtr->MaxDevIntLines ; IntIndex++) {
> +    //
> +    // Get the number of events HW has written for this
> +    //  interrupt line
> +    //
> +    EventCount = UsbRegRead ((UINT32)UsbFuncIoDevPtr->XdciMmioBarAddr, DWC_XDCI_EVNTCOUNT_REG(IntIndex));
> +    EventCount &= DWC_XDCI_EVNTCOUNT_MASK;
> +    PeventCount = 0;
> +
> +    //
> +    // Process interrupt line Buffer only if count is non-zero
> +    //
> +    if (EventCount) {
> +      //
> +      // Process events in this Buffer
> +      //
> +      ProcessIntLineEvents (
> +        This,
> +        EventCount,
> +        &PeventCount,
> +        Message,
> +        PayloadSize,
> +        Payload,
> +        &EventFlag
> +        );
> +
> +      //
> +      // Write back the Processed number of events so HW decrements it from current
> +      // event count
> +      //
> +      UsbRegWrite ((UINT32)UsbFuncIoDevPtr->XdciMmioBarAddr, DWC_XDCI_EVNTCOUNT_REG(IntIndex), PeventCount);
> +
> +      //
> +      // for debug
> +      //
> +      if (*Message != EfiUsbMsgNone) {
> +        break;
> +      }
> +
> +      if (EventFlag == TRUE) {
> +        break;
> +      }
> +    }
> +  }
> +
> +  gBS->RestoreTPL (OriginalTpl);
> +  //
> +  //EVENT_EXIT:
> +  //
> +  DEBUG ((USB_FUIO_DEBUG_EVENT_I, "USBFU_ EventHandler Exit\n"));
> +  return EFI_SUCCESS;
> +}
> +
> +
> +
> +/**
> +  Copies relevant endpoint data from standard USB endpoint descriptors
> +  to the usbEpInfo structure used by the XDCI
> +
> +  @param pEpDest   destination structure
> +  @param pEpSrc    source structure
> +
> +  @return VOID
> +
> +**/
> +VOID
> +UsbFnSetEpInfo (
> +  IN USB_EP_INFO                 *EpDest,
> +  IN USB_DEVICE_ENDPOINT_INFO    *EpSrc
> +  )
> +{
> +  EFI_USB_ENDPOINT_DESCRIPTOR              *EpDesc = NULL;
> +  EFI_USB_ENDPOINT_COMPANION_DESCRIPTOR    *EpCompDesc = NULL;
> +
> +  //
> +  // start by clearing all data in the destination
> +  //
> +  SetMem (EpDest, sizeof(USB_EP_INFO), 0);
> +  EpDesc = EpSrc->EndpointDesc;
> +  EpCompDesc = EpSrc->EndpointCompDesc;
> +
> +  if (EpDesc != NULL) {
> +    EpDest->EpNum = EpDesc->EndpointAddress & 0x0F; // Bits 0-3 are ep num
> +    EpDest->EpDir = ((EpDesc->EndpointAddress & USB_ENDPOINT_DIR_IN) > 0) ? UsbEpDirIn : UsbEpDirOut;
> +    DEBUG ((DEBUG_INFO, "EpDest->EpNum 0x%02x\n", EpDest->EpNum));
> +    DEBUG ((DEBUG_INFO, "EpDest->EpDir 0x%02x\n", EpDest->EpDir));
> +    EpDest->EpType = EpDesc->Attributes & USB_ENDPOINT_TYPE_MASK;
> +    EpDest->MaxPktSize = EpDesc->MaxPacketSize;
> +    EpDest->Interval = EpDesc->Interval;
> +  }
> +  if (EpCompDesc != NULL) {
> +    EpDest->MaxStreams = EpCompDesc->Attributes & USB_EP_BULK_BM_ATTR_MASK;
> +    EpDest->BurstSize = EpCompDesc->MaxBurst;
> +    EpDest->Mult = EpCompDesc->BytesPerInterval;
> +  }
> +
> +  return;
> +}
> +
> +
> +EFI_STATUS
> +SetFnIoReqInfo(
> +  IN     EFI_USBFN_IO_PROTOCOL         *This,
> +  IN     UINT8                         EndpointIndex,
> +  IN     EFI_USBFN_ENDPOINT_DIRECTION  Direction,
> +  IN OUT UINTN                         *BufferSize,
> +  IN OUT VOID                          *Buffer,
> +  IN OUT USB_XFER_REQUEST              *XfIoreq
> +  )
> +{
> +  USB_XDCI_DEV_CONTEXT     *UsbFuncIoDevPtr;
> +  EFI_STATUS               Status;
> +  UINTN                    ReqPacket;
> +
> +  UsbFuncIoDevPtr = USBFUIO_CONTEXT_FROM_PROTOCOL (This);
> +  Status = EFI_SUCCESS;
> +  ReqPacket = 0;
> +
> +  switch (EndpointIndex) {
> +    case 0: // Control endpoint
> +      XfIoreq->EpInfo.EpNum = 0;
> +      XfIoreq->EpInfo.EpDir = Direction? UsbEpDirIn : UsbEpDirOut;
> +      break;
> +
> +
> +    default:
> +      if (Direction == EfiUsbEndpointDirectionDeviceTx) {
> +        UsbFnSetEpInfo (&XfIoreq->EpInfo, &UsbFuncIoDevPtr->IndexPtrInEp);
> +      } else {
> +        UsbFnSetEpInfo (&XfIoreq->EpInfo, &UsbFuncIoDevPtr->IndexPtrOutEp);
> +        //
> +        // reference from "UsbDeviceMode.c", function UsbdEpRxData
> +        //
> +
> +        //
> +        // Transfer length should be multiple of USB packet size.
> +        //
> +        ReqPacket = *BufferSize/ XfIoreq->EpInfo.MaxPktSize;
> +        ReqPacket = ((XfIoreq->XferLen % XfIoreq->EpInfo.MaxPktSize) == 0)? ReqPacket : ReqPacket + 1;
> +        XfIoreq->XferLen = (UINT32)ReqPacket * XfIoreq->EpInfo.MaxPktSize;
> +
> +      }
> +      break;
> +  }
> +
> +  if (EFI_ERROR(Status)) {
> +    return EFI_UNSUPPORTED;
> +  }
> +
> +  XfIoreq->XferBuffer = Buffer;
> +  XfIoreq->XferLen = (UINT32)(*BufferSize);
> +  XfIoreq->XferDone = NULL;
> +
> +  return EFI_SUCCESS;
> +}
> +
> +
> +/**
> +  Primary function to handle transfer in either direction Based on specified
> +  direction and on the specified endpoint.
> +
> +  @param[in]  This              A pointer to the EFI_USBFN_IO_PROTOCOL instance.
> +  @param[in]  EndpointIndex     Indicates the endpoint on which TX or RX transfer
> +                                needs to take place.
> +  @param[in]  Direction         Direction of the endpoint.
> +  @param[in]  BufferSize        If Direction is EfiUsbEndpointDirectionDeviceRx:
> +                                On input, the size of the Buffer in bytes.
> +                                On output, the amount of data returned in Buffer in bytes.
> +                                If Direction is EfiUsbEndpointDirectionDeviceTx:
> +                                On input, the size of the Buffer in bytes.
> +                                On output, the amount of data actually transmitted in bytes.
> +  @param[in]  Buffer            If Direction is EfiUsbEndpointDirectionDeviceRx:
> +                                The Buffer to return the received data.
> +                                If Direction is EfiUsbEndpointDirectionDeviceTx:
> +                                The Buffer that contains the data to be transmitted.
> +
> +  @retval EFI_SUCCESS           The function returned successfully.
> +  @retval EFI_INVALID_PARAMETER A parameter is invalid.
> +  @retval EFI_DEVICE_ERROR      The physical device reported an error.
> +  @retval EFI_NOT_READY         The physical device is busy or not ready to
> +                                process this request.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +Transfer (
> +  IN EFI_USBFN_IO_PROTOCOL         *This,
> +  IN UINT8                         EndpointIndex,
> +  IN EFI_USBFN_ENDPOINT_DIRECTION  Direction,
> +  IN OUT UINTN                     *BufferSize,
> +  IN OUT VOID                      *Buffer
> +  )
> +{
> +  USB_XDCI_DEV_CONTEXT              *UsbFuncIoDevPtr;
> +  USB_DEV_CORE                      *UsbDeviceCorePtr;
> +  XDCI_CORE_HANDLE                  *XdciCorePtr;
> +  EFI_STATUS                        Status;
> +  USB_XFER_REQUEST                  XferReq;
> +  UINT32                            EndPoint;
> +
> +  DEBUG ((USB_FUIO_DEBUG_LOAD, "\n FU:Transfer - Entry\n"));
> +  DEBUG ((USB_FUIO_DEBUG_LOAD, "\n FU:EndpointIndex 0x%02x\n", EndpointIndex));
> +  DEBUG ((USB_FUIO_DEBUG_LOAD, "\n FU:Direction 0x%02x\n", Direction));
> +
> +  UsbFuncIoDevPtr = USBFUIO_CONTEXT_FROM_PROTOCOL (This);
> +
> +  UsbDeviceCorePtr = UsbFuncIoDevPtr->DrvCore;
> +  XdciCorePtr = UsbDeviceCorePtr->ControllerHandle;
> +  EndPoint = UsbGetPhysicalEpNum (EndpointIndex, Direction ? UsbEpDirIn : UsbEpDirOut);
> +
> +  Status = SetFnIoReqInfo (
> +             This,
> +             EndpointIndex,
> +             Direction,
> +             BufferSize,
> +             Buffer,
> +             &XferReq
> +             );
> +
> +  if (EFI_ERROR(Status)) {
> +    DEBUG ((USB_FUIO_DEBUG_LOAD, "Set SetFnIoReqInfo - Error Stop!!!\n"));
> +    while(1);
> +    Status = EFI_DEVICE_ERROR;
> +    goto FUN_EXIT;
> +  }
> +
> +  UsbFuncIoDevPtr->EndPointXferRec[EndPoint].EpNum = EndPoint;
> +  UsbFuncIoDevPtr->EndPointXferRec[EndPoint].Direction = Direction;
> +  UsbFuncIoDevPtr->EndPointXferRec[EndPoint].XferAddress = (UINTN)Buffer;
> +  UsbFuncIoDevPtr->EndPointXferRec[EndPoint].XferLength = (UINT32)(*BufferSize);
> +  UsbFuncIoDevPtr->EndPointXferRec[EndPoint].LogEpNum = EndpointIndex;
> +  UsbFuncIoDevPtr->EndPointXferRec[EndPoint].Complete = FALSE;
> +  UsbFuncIoDevPtr->EndPointXferRec[EndPoint].ZlpFlag = FALSE;
> +
> +  Status = EFI_DEVICE_ERROR;
> +  switch (EndpointIndex) {
> +    case 0: // Control endpoint
> +      if (*BufferSize == 0) {
> +        if (Direction == EfiUsbEndpointDirectionDeviceTx) {
> +          Status = UsbDeviceEp0TxStatus(UsbDeviceCorePtr);
> +        } else {
> +          Status = UsbDeviceEp0RxStatus(UsbDeviceCorePtr);
> +        }
> +      } else if (Direction == EfiUsbEndpointDirectionDeviceTx) {
> +        Status = UsbXdciDeviceEpTxData(UsbDeviceCorePtr, &XferReq);
> +      } else if (Direction == EfiUsbEndpointDirectionDeviceRx) {
> +        DEBUG ((USB_FUIO_DEBUG_LOAD, "\n Set Setup Package - ??? Stop!!!\n"));
> +      }
> +      break;
> +
> +    default:
> +      Status = EFI_SUCCESS;
> +      if (Direction == EfiUsbEndpointDirectionDeviceTx) {
> +        DEBUG ((USB_FUIO_DEBUG_LOAD, "\n EfiUsbEndpointDirectionDeviceTx Size = %d\n",(*BufferSize) ));
> +        XferReq.Zlp = TRUE;
> +        if ((((*BufferSize) % 512) == 0) && ((*BufferSize) != 0)) {
> +          UsbFuncIoDevPtr->EndPointXferRec[EndPoint].ZlpFlag = TRUE;
> +          DEBUG ((USB_FUIO_DEBUG_LOAD, "\n Set Zlp flag\n"));
> +        }
> +        Status = UsbXdciDeviceEpTxData (UsbDeviceCorePtr, &XferReq);
> +      } else {
> +        DEBUG ((USB_FUIO_DEBUG_LOAD, "\n EfiUsbEndpointDirectionDeviceRx Size = %d\n",(*BufferSize) ));
> +        Status = UsbXdciDeviceEpRxData (UsbDeviceCorePtr, &XferReq);
> +      }
> +      break;
> +  }
> +
> +  if (EFI_ERROR(Status)) {
> +    goto FUN_EXIT;
> +  }
> +
> +  if (Status != EFI_SUCCESS) {
> +    Status = EFI_DEVICE_ERROR;
> +  }
> +
> +FUN_EXIT:
> +
> +  DEBUG ((USB_FUIO_DEBUG_LOAD, "FU:Transfer - Exit %r\n", Status));
> +  return Status;
> +}
> +
> +
> +/**
> +  This function supplies power to the USB controller if needed, initialize
> +  hardware and internal data structures, and then return.
> +  The port must not be activated by this function.
> +
> +  @param[in]  This              A pointer to the EFI_USBFN_IO_PROTOCOL instance.
> +
> +  @retval EFI_SUCCESS           The function returned successfully.
> +  @retval EFI_INVALID_PARAMETER A parameter is invalid.
> +  @retval EFI_DEVICE_ERROR      The physical device reported an error.
> +**/
> +EFI_STATUS
> +EFIAPI
> +StartXdciController (
> +  IN EFI_USBFN_IO_PROTOCOL    *This
> +  )
> +{
> +  USB_XDCI_DEV_CONTEXT         *UsbFuncIoDevPtr;
> +  USB_DEV_CONFIG_PARAMS        ConfigParams;
> +  EFI_STATUS                   Status;
> +
> +  Status = EFI_SUCCESS;
> +  UsbFuncIoDevPtr = USBFUIO_CONTEXT_FROM_PROTOCOL (This);
> +
> +  if (UsbFuncIoDevPtr->StartUpController == TRUE) {
> +    goto EXIT_START_CONTROLLER;
> +  }
> +
> +  ConfigParams.ControllerId = USB_ID_DWC_XDCI;
> +  ConfigParams.BaseAddress = (UINT32)UsbFuncIoDevPtr->XdciMmioBarAddr;
> +  ConfigParams.Role = USB_ROLE_DEVICE;
> +  ConfigParams.Speed = USB_SPEED_HIGH;
> +
> +  //
> +  //*Vid = 0x8086
> +  //*Pid = 0x0A65
> +  //
> +  UsbFuncIoDevPtr->VendorId = USBFU_VID;
> +  UsbFuncIoDevPtr->DeviceId = USBFU_PID;
> +  UsbFuncIoDevPtr->StartUpController = TRUE;
> +
> +  Status = UsbDeviceInit (&ConfigParams, (VOID **)&UsbFuncIoDevPtr->DrvCore);
> +  if (Status != EFI_SUCCESS) {
> +    Status = EFI_DEVICE_ERROR;
> +    goto EXIT_START_CONTROLLER;
> +  }
> +
> +  UsbFuncIoDevPtr->XdciDrvIfHandle = UsbFuncIoDevPtr->DrvCore->ControllerHandle;
> +
> +EXIT_START_CONTROLLER:
> +
> +  DEBUG ((USB_FUIO_DEBUG_LOAD, "StartXdciController - Exit :: %r\n", Status));
> +  return Status;
> +}
> +
> +
> +/**
> +  This function disables the hardware device by resetting the run/stop bit
> +  and power off the USB controller if needed.
> +
> +  @param[in]  This              A pointer to the EFI_USBFN_IO_PROTOCOL instance.
> +
> +  @retval EFI_SUCCESS           The function returned successfully.
> +  @retval EFI_INVALID_PARAMETER A parameter is invalid.
> +  @retval EFI_DEVICE_ERROR      The physical device reported an error.
> +**/
> +EFI_STATUS
> +EFIAPI
> +StopXdciController (
> +  IN EFI_USBFN_IO_PROTOCOL    *This
> +  )
> +{
> +  USB_XDCI_DEV_CONTEXT  *UsbFuncIoDevPtr;
> +  EFI_STATUS            DevStatus;
> +
> +  UsbFuncIoDevPtr = USBFUIO_CONTEXT_FROM_PROTOCOL (This);
> +  DEBUG ((USB_FUIO_DEBUG_LOAD, "StopController - Entry\n"));
> +
> +  if (UsbFuncIoDevPtr->StartUpController == FALSE) {
> +    DEBUG ((USB_FUIO_DEBUG_LOAD, "The Controller not yet start up skip deinit\n"));
> +    return EFI_SUCCESS;
> +  }
> +
> +  if (This == NULL) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  DevStatus = UsbDeviceDeinit (UsbFuncIoDevPtr->DrvCore, TRUE);
> +
> +  UsbFuncIoDevPtr->DrvCore = NULL;
> +  UsbFuncIoDevPtr->XdciDrvIfHandle = NULL;
> +  UsbFuncIoDevPtr->StartUpController = FALSE;
> +
> +  if (DevStatus != EFI_SUCCESS) {
> +    return EFI_DEVICE_ERROR;
> +  }
> +
> +  DEBUG ((USB_FUIO_DEBUG_LOAD, "StopController - Exit\n"));
> +  return EFI_SUCCESS;
> +}
> +
> +
> +/**
> +  This function sets the configuration policy for the specified non-control endpoint.
> +  Refer to the description for calling restrictions
> +
> +  @param[in]  This              A pointer to the EFI_USBFN_IO_PROTOCOL instance.
> +  @param[in]  EndpointIndex     Indicates the non-control endpoint for
> +                                which the policy needs to be set.
> +  @param[in]  Direction         Direction of the endpoint.
> +  @param[in]  PolicyType        Policy type the user is trying to set for
> +                                the specified non-control endpoint.
> +  @param[in]  BufferSize        The size of the Buffer in bytes.
> +  @param[in]  Buffer            The new value for the policy parameter that
> +                                PolicyType specifies.
> +
> +
> +  @retval EFI_SUCCESS           The function returned successfully.
> +  @retval EFI_INVALID_PARAMETER A parameter is invalid.
> +  @retval EFI_DEVICE_ERROR      The physical device reported an error.
> +  @retval EFI_UNSUPPORTED       Changing this policy value is not supported.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +SetEndpointPolicy (
> +  IN EFI_USBFN_IO_PROTOCOL        *This,
> +  IN UINT8                        EndpointIndex,
> +  IN EFI_USBFN_ENDPOINT_DIRECTION Direction,
> +  IN EFI_USBFN_POLICY_TYPE        PolicyType,
> +  IN UINTN                        BufferSize,
> +  IN VOID                         *Buffer
> +  )
> +{
> +  USB_XDCI_DEV_CONTEXT  *UsbFuncIoDevPtr;
> +  EFI_STATUS            Status;
> +  UINT32                EndPoint;
> +  UINT8                 *FlagPtr;
> +
> +  UsbFuncIoDevPtr = USBFUIO_CONTEXT_FROM_PROTOCOL (This);
> +  FlagPtr = NULL;
> +
> +  switch (PolicyType) {
> +    case EfiUsbPolicyUndefined:
> +    case EfiUsbPolicyMaxTransactionSize:
> +    case EfiUsbPolicyZeroLengthTerminationSupport:
> +
> +     Status = EFI_UNSUPPORTED;
> +     break;
> +
> +    default:
> +     FlagPtr = Buffer;
> +     Status = EFI_SUCCESS;
> +     break;
> +  }
> +
> +  if (BufferSize < 1) {
> +    Status = EFI_INVALID_PARAMETER;
> +  }
> +
> +  if (EFI_ERROR(Status)) {
> +    DEBUG ((USB_FUIO_DEBUG_LOAD, "SetEndpointPolicy - ERROR %r\n", Status));
> +    return Status;
> +  }
> +
> +  EndPoint = UsbGetPhysicalEpNum (EndpointIndex, Direction ? UsbEpDirIn : UsbEpDirOut);
> +
> +  UsbFuncIoDevPtr->EndPointXferRec[EndPoint].ZlpFlag = *FlagPtr;
> +
> +  return Status;
> +}
> +
> +
> +/**
> +  This function retrieves the configuration policy for the specified non-control
> +  endpoint. There are no associated calling restrictions for this function.
> +
> +  @param[in]  This              A pointer to the EFI_USBFN_IO_PROTOCOL instance.
> +  @param[in]  EndpointIndex     Indicates the non-control endpoint for
> +                                which the policy needs to be set.
> +  @param[in]  Direction         Direction of the endpoint.
> +  @param[in]  PolicyType        Policy type the user is trying to set for
> +                                the specified non-control endpoint.
> +  @param[in]  BufferSize        The size of the Buffer in bytes.
> +  @param[in]  Buffer            The new value for the policy parameter that
> +                                PolicyType specifies.
> +
> +
> +  @retval EFI_SUCCESS           The function returned successfully.
> +  @retval EFI_INVALID_PARAMETER A parameter is invalid.
> +  @retval EFI_DEVICE_ERROR      The physical device reported an error.
> +  @retval EFI_UNSUPPORTED       Changing this policy value is not supported.
> +  @retval EFI_BUFFER_TOO_SMALL  Supplied Buffer is not large enough to
> +                                hold requested policy value.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +GetEndpointPolicy (
> +  IN EFI_USBFN_IO_PROTOCOL        *This,
> +  IN UINT8                        EndpointIndex,
> +  IN EFI_USBFN_ENDPOINT_DIRECTION Direction,
> +  IN EFI_USBFN_POLICY_TYPE        PolicyType,
> +  IN OUT UINTN                    *BufferSize,
> +  IN OUT VOID                     *Buffer
> +  )
> +{
> +  USB_XDCI_DEV_CONTEXT  *UsbFuncIoDevPtr;
> +  EFI_STATUS            Status;
> +  UINT32                EndPoint;
> +  UINT32                MaxPacketSize;
> +  BOOLEAN               SetFlag;
> +
> +  UsbFuncIoDevPtr = USBFUIO_CONTEXT_FROM_PROTOCOL (This);
> +  MaxPacketSize = 0;
> +  SetFlag = FALSE;
> +
> +  switch (PolicyType) {
> +    case EfiUsbPolicyUndefined:
> +
> +     Status = EFI_UNSUPPORTED;
> +     break;
> +
> +    case EfiUsbPolicyMaxTransactionSize:
> +    case EfiUsbPolicyZeroLengthTerminationSupport:
> +    default:
> +     if (Buffer == NULL) {
> +       Status = EFI_INVALID_PARAMETER;
> +     } else {
> +       Status = EFI_SUCCESS;
> +     }
> +     break;
> +  }
> +
> +  EndPoint = UsbGetPhysicalEpNum (EndpointIndex, Direction ? UsbEpDirIn : UsbEpDirOut);
> +
> +  if (EFI_ERROR(Status)) {
> +    DEBUG ((USB_FUIO_DEBUG_LOAD, "GetEndpointPolicy - ERROR %r\n", Status));
> +    return Status;
> +  }
> +
> +  if (PolicyType == EfiUsbPolicyMaxTransactionSize) {
> +
> +    if (*BufferSize < sizeof(UINT32)) {
> +       Status = EFI_INVALID_PARAMETER;
> +    } else {
> +      MaxPacketSize = MAX_TRANSFER_PACKET;
> +      CopyMem (Buffer, &MaxPacketSize, sizeof(UINT32));
> +    }
> +
> +  } else if (PolicyType == EfiUsbPolicyZeroLengthTerminationSupport) {
> +    if (*BufferSize < sizeof(BOOLEAN)) {
> +       Status = EFI_INVALID_PARAMETER;
> +    } else {
> +      SetFlag = TRUE;
> +      CopyMem (Buffer, &SetFlag, sizeof(BOOLEAN));
> +    }
> +
> +  } else if (PolicyType == EfiUsbPolicyZeroLengthTermination) {
> +    if (*BufferSize < sizeof(BOOLEAN)) {
> +       Status = EFI_INVALID_PARAMETER;
> +    } else {
> +      SetFlag =  UsbFuncIoDevPtr->EndPointXferRec[EndPoint].ZlpFlag;
> +      CopyMem (Buffer, &SetFlag, sizeof(BOOLEAN));
> +    }
> +  } else {
> +    Status = EFI_INVALID_PARAMETER;
> +  }
> +
> +  return Status;
> +}
> +
> +EFI_STATUS
> +UsbFnInitDevice (
> +  IN EFI_USBFN_IO_PROTOCOL        *This
> +  )
> +{
> +  EFI_STATUS                   Status;
> +  USB_XDCI_DEV_CONTEXT         *UsbFuncIoDevPtr;
> +
> +  Status = EFI_SUCCESS;
> +  UsbFuncIoDevPtr = USBFUIO_CONTEXT_FROM_PROTOCOL (This);
> +
> +  PlatformSpecificInit ();
> +
> +  UsbFuncIoDevPtr->StartUpController = FALSE;
> +  Status = StartXdciController (&UsbFuncIoDevPtr->UsbFunIoProtocol);
> +  if (EFI_ERROR (Status)) {
> +    Status = EFI_DEVICE_ERROR;
> +    goto DEV_INIT_EXIT;
> +  }
> +
> +  Status = UsbXdciDeviceConnect (UsbFuncIoDevPtr->DrvCore);
> +  DEBUG ((USB_FUIO_DEBUG_LOAD, "UsbXdciDeviceConnect Status %x\n", Status));
> +  if (Status != EFI_SUCCESS) {
> +    Status = EFI_DEVICE_ERROR;
> +    goto DEV_INIT_EXIT;
> +  }
> +
> +
> +DEV_INIT_EXIT:
> +
> +  return Status;
> +}
> +
> +EFI_STATUS
> +EFIAPI
> +StartController (
> +  IN EFI_USBFN_IO_PROTOCOL        *This
> +  )
> +{
> +  return EFI_SUCCESS;
> +}
> +
> +
> +EFI_STATUS
> +UsbFnDeInitDevice (
> +  IN EFI_USBFN_IO_PROTOCOL        *This
> +  )
> +{
> +  EFI_STATUS                   Status;
> +  USB_XDCI_DEV_CONTEXT         *UsbFuncIoDevPtr;
> +
> +  UsbFuncIoDevPtr = USBFUIO_CONTEXT_FROM_PROTOCOL (This);
> +
> +  if (UsbFuncIoDevPtr->StartUpController == FALSE) {
> +    DEBUG ((USB_FUIO_DEBUG_LOAD, "UsbFn:StopController:The Controller not yet start up force return EFI_SUCCESS\n"));
> +    return EFI_SUCCESS;
> +  }
> +
> +  //
> +  // disconnect
> +  //
> +  Status = UsbDeviceDisconnect (UsbFuncIoDevPtr->DrvCore);
> +  DEBUG ((USB_FUIO_DEBUG_LOAD, "UsbDeviceDisconnect Status %x\n", Status));
> +  if (Status != EFI_SUCCESS) {
> +    Status = EFI_DEVICE_ERROR;
> +    goto DEV_DEINIT_EXIT;
> +  }
> +
> +  //
> +  // StopController
> +  //
> +  Status = StopXdciController (&UsbFuncIoDevPtr->UsbFunIoProtocol);
> +  UsbFuncIoDevPtr->StartUpController = FALSE;
> +
> +DEV_DEINIT_EXIT:
> +  return Status;
> +}
> +
> +EFI_STATUS
> +EFIAPI
> +StopController (
> +  IN EFI_USBFN_IO_PROTOCOL        *This
> +  )
> +{
> +  return UsbFnDeInitDevice(This);
> +}
> +
> diff --git a/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbFuncIo.h b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbFuncIo.h
> new file mode 100644
> index 0000000000..ad3d296db9
> --- /dev/null
> +++ b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbFuncIo.h
> @@ -0,0 +1,234 @@
> +/** @file
> +  Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR>
> +
> +  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.
> +
> +**/
> +
> +#ifndef __EFI_USB_FUNCTION_IO_INTERFACE_H__
> +#define __EFI_USB_FUNCTION_IO_INTERFACE_H__
> +
> +#include <Uefi.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/DevicePathLib.h>
> +#include <Library/DriverLib.h>
> +#include <Library/PcdLib.h>
> +#include <Protocol/EfiUsbFnIo.h>
> +#include <Library/PmicLib.h>
> +#include <Library/UsbDeviceLib.h>
> +#include <Library/PrintLib.h>
> +#include "UsbIoNode.h"
> +#include "XdciDWC.h"
> +#include "UsbDeviceMode.h"
> +
> +//
> +// Debug message setting
> +//
> +#define USB_FUIO_DEBUG_INFO              EFI_D_INFO
> +#define USB_FUIO_DEBUG_LOAD              EFI_D_LOAD
> +#define USB_FUIO_DEBUG_ERROR             EFI_D_ERROR
> +#define USB_FUIO_DEBUG_EVENT_I           0 //DEBUG_INIT
> +#define USB_FUIO_DEBUG_EVENT_D           EFI_D_ERROR
> +#define USB_FUIO_DEBUG_EVENT_NOTREADY_D  EFI_D_ERROR
> +#define USB_FUIO_DEBUG_EVENT_NOTREADY_I  0 //DEBUG_INIT
> +
> +#define MAX_TRANSFER_PACKET     (8 * 1024 * 1024)
> +
> +#define USBFU_VID     0x8086
> +#define USBFU_PID     0x0A65
> +
> +#pragma pack(1)
> +typedef struct {
> +  UINT8                     ProgInterface;
> +  UINT8                     SubClassCode;
> +  UINT8                     BaseCode;
> +} USB_CLASSC;
> +
> +//
> +// Event Buffer Struct
> +//
> +typedef struct  {
> +  UINT32 Event;
> +  UINT32 DevTstLmp1;
> +  UINT32 DevTstLmp2;
> +  UINT32 Reserved;
> +} USBD_EVENT_BUF;
> +
> +typedef struct  {
> +  UINT32                        EpNum;
> +  EFI_USBFN_ENDPOINT_DIRECTION  Direction;
> +  UINTN                         XferAddress;
> +  UINT32                        XferLength;
> +  UINT8                         LogEpNum;
> +  BOOLEAN                       Complete;
> +  BOOLEAN                       ZlpFlag;
> +} USBD_EP_XFER_REC;
> +
> +#pragma pack()
> +
> +EFI_STATUS
> +UsbFnInitDevice (
> +  IN EFI_USBFN_IO_PROTOCOL        *This
> +  );
> +
> +EFI_STATUS
> +UsbFnDeInitDevice (
> +  IN EFI_USBFN_IO_PROTOCOL        *This
> +  );
> +
> +EFI_STATUS
> +EFIAPI
> +DetectPort (
> +  IN EFI_USBFN_IO_PROTOCOL         *This,
> +  OUT EFI_USBFN_PORT_TYPE          *PortType
> +  );
> +
> +EFI_STATUS
> +EFIAPI
> +AllocateTransferBuffer (
> +  IN EFI_USBFN_IO_PROTOCOL         *This,
> +  IN UINTN                         Size,
> +  OUT VOID                         **Buffer
> +  );
> +
> +EFI_STATUS
> +EFIAPI
> +FreeTransferBuffer (
> +  IN EFI_USBFN_IO_PROTOCOL         *This,
> +  IN VOID                          *Buffer
> +  );
> +
> +EFI_STATUS
> +EFIAPI
> +ConfigureEnableEndpoints (
> +  IN EFI_USBFN_IO_PROTOCOL         *This,
> +  IN EFI_USB_DEVICE_INFO           *DeviceInfo
> + );
> +
> +EFI_STATUS
> +EFIAPI
> +GetEndpointMaxPacketSize (
> +  IN EFI_USBFN_IO_PROTOCOL         *This,
> +  IN EFI_USB_ENDPOINT_TYPE         EndpointType,
> +  IN EFI_USB_BUS_SPEED             BusSpeed,
> +  OUT UINT16                       *MaxPacketSize
> + );
> +
> +EFI_STATUS
> +EFIAPI
> +GetMaxTransferSize (
> +  IN EFI_USBFN_IO_PROTOCOL         *This,
> +  OUT UINTN                        *MaxTransferSize
> +  );
> +
> +EFI_STATUS
> +EFIAPI
> +GetDeviceInfo (
> +  IN EFI_USBFN_IO_PROTOCOL         *This,
> +  IN EFI_USBFN_DEVICE_INFO_ID      Id,
> +  IN OUT UINTN                     *BufferSize,
> +  OUT VOID                         *Buffer OPTIONAL
> +  );
> +
> +EFI_STATUS
> +EFIAPI
> +GetVendorIdProductId (
> +  IN EFI_USBFN_IO_PROTOCOL         *This,
> +  OUT UINT16                       *Vid,
> +  OUT UINT16                       *Pid
> +  );
> +
> +EFI_STATUS
> +EFIAPI
> +AbortTransfer (
> +  IN EFI_USBFN_IO_PROTOCOL        *This,
> +  IN UINT8                        EndpointIndex,
> +  IN EFI_USBFN_ENDPOINT_DIRECTION Direction
> +  );
> +
> +EFI_STATUS
> +EFIAPI
> +GetEndpointStallState (
> +  IN EFI_USBFN_IO_PROTOCOL         *This,
> +  IN UINT8                         EndpointIndex,
> +  IN EFI_USBFN_ENDPOINT_DIRECTION  Direction,
> +  IN OUT BOOLEAN                   *State
> +  );
> +
> +EFI_STATUS
> +EFIAPI
> +SetEndpointStallState (
> +  IN EFI_USBFN_IO_PROTOCOL         *This,
> +  IN UINT8                         EndpointIndex,
> +  IN EFI_USBFN_ENDPOINT_DIRECTION  Direction,
> +  IN BOOLEAN                       State
> +  );
> +
> +EFI_STATUS
> +EFIAPI
> +EventHandler (
> +  IN EFI_USBFN_IO_PROTOCOL         *This,
> +  OUT EFI_USBFN_MESSAGE            *Message,
> +  IN OUT UINTN                     *PayloadSize,
> +  OUT EFI_USBFN_MESSAGE_PAYLOAD    *Payload
> +  );
> +
> +EFI_STATUS
> +EFIAPI
> +Transfer (
> +  IN EFI_USBFN_IO_PROTOCOL         *This,
> +  IN UINT8                         EndpointIndex,
> +  IN EFI_USBFN_ENDPOINT_DIRECTION  Direction,
> +  IN OUT UINTN                     *BufferSize,
> +  IN OUT VOID                      *Buffer
> +  );
> +
> +EFI_STATUS
> +EFIAPI
> +StartController (
> +  IN EFI_USBFN_IO_PROTOCOL         *This
> +  );
> +
> +EFI_STATUS
> +EFIAPI
> +StopController (
> +  IN EFI_USBFN_IO_PROTOCOL         *This
> +  );
> +
> +EFI_STATUS
> +EFIAPI
> +SetEndpointPolicy (
> +  IN EFI_USBFN_IO_PROTOCOL         *This,
> +  IN UINT8                         EndpointIndex,
> +  IN EFI_USBFN_ENDPOINT_DIRECTION  Direction,
> +  IN EFI_USBFN_POLICY_TYPE         PolicyType,
> +  IN UINTN                         BufferSize,
> +  IN VOID                          *Buffer
> +  );
> +
> +EFI_STATUS
> +EFIAPI
> +GetEndpointPolicy (
> +  IN EFI_USBFN_IO_PROTOCOL         *This,
> +  IN UINT8                         EndpointIndex,
> +  IN EFI_USBFN_ENDPOINT_DIRECTION  Direction,
> +  IN EFI_USBFN_POLICY_TYPE         PolicyType,
> +  IN OUT UINTN                     *BufferSize,
> +  IN OUT VOID                      *Buffer
> +  );
> +
> +VOID
> +UsbFnSetEpInfo (
> +  IN USB_EP_INFO                 *EpDest,
> +  IN USB_DEVICE_ENDPOINT_INFO    *EpSrc
> +  );
> +
> +extern EFI_USBFN_IO_PROTOCOL         mUsbFunIoProtocol;
> +#endif
> +
> diff --git a/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbIoNode.c b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbIoNode.c
> new file mode 100644
> index 0000000000..8fc6e10046
> --- /dev/null
> +++ b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbIoNode.c
> @@ -0,0 +1,177 @@
> +/** @file
> +  Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR>
> +
> +  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.
> +
> +**/
> +
> +#include "UsbDeviceDxe.h"
> +
> +
> +/**
> +  The SearchNode function search a memory address for record the driver allocate
> +  memory region and the node to the head link list.
> +
> +  @param[in]  This              A pointer to the EFI_USBFN_IO_PROTOCOL instance.
> +  @param[in]  Buffer            The driver alocate memory address.
> +  @param[out] Node              The match node record of the driver aloocate
> +                                memory region.
> +  @param[out] PNode             The pervious match node record of the driver
> +                                aloocate memory region.
> +
> +  @retval EFI_SUCCESS           The operation completed successfully.
> +  @retval EFI_NOT_FOUND         The memory Buffer didn't find.
> +**/
> +EFI_STATUS
> +SearchNode (
> +  IN  EFI_USBFN_IO_PROTOCOL    *This,
> +  IN  VOID                     *Buffer,
> +  OUT USB_MEM_NODE             **Node,
> +  OUT USB_MEM_NODE             **PNode
> +  )
> +{
> +  USB_XDCI_DEV_CONTEXT *UsbFuncIoDevPtr;
> +  USB_MEM_NODE         *NodeL;
> +  USB_MEM_NODE         *PNodeL;
> +  EFI_STATUS           Status;
> +
> +  DEBUG ((USB_DEBUG_MEM_NODE_INFO, "SearchNode - Entry\n"));
> +
> +  UsbFuncIoDevPtr = USBFUIO_CONTEXT_FROM_PROTOCOL(This);
> +  NodeL = UsbFuncIoDevPtr->FirstNodePtr;
> +  PNodeL = NULL;
> +  Status = EFI_NOT_FOUND;
> +
> +  while (Node != NULL) {
> +    if (NodeL->AllocatePtr == Buffer) {
> +      break;
> +    }
> +
> +    PNodeL = NodeL;
> +    NodeL = NodeL->NextPtr;
> +  }
> +
> +  if (NodeL != NULL && Node != NULL) {
> +    *Node = NodeL;
> +    *PNode = PNodeL;
> +    Status = EFI_SUCCESS;
> +  }
> +
> +  DEBUG ((USB_DEBUG_MEM_NODE_INFO, "SearchNode - Exit %r\n", Status));
> +  return Status;
> +}
> +
> +/**
> +  The InsertNewNodeToHead function remove a memory for record the driver allocate
> +  memory region and the node to the head link list.
> +
> +  @param[in]  This              A pointer to the EFI_USBFN_IO_PROTOCOL instance.
> +  @param[in]  Buffer            The driver alocate memory address.
> +
> +  @retval EFI_SUCCESS           The operation completed successfully.
> +  @retval EFI_NOT_FOUND         The memory Buffer didn't find.
> +**/
> +EFI_STATUS
> +RemoveNode (
> +  IN  EFI_USBFN_IO_PROTOCOL    *This,
> +  IN  VOID                     *Buffer
> +  )
> +{
> +  USB_XDCI_DEV_CONTEXT *UsbFuncIoDevPtr;
> +  USB_MEM_NODE         *Node;
> +  USB_MEM_NODE         *PNode;
> +  EFI_STATUS           Status;
> +
> +  DEBUG ((USB_DEBUG_MEM_NODE_INFO, "RemoveNode - Entry\n"));
> +
> +  UsbFuncIoDevPtr = USBFUIO_CONTEXT_FROM_PROTOCOL (This);
> +
> +  Status = SearchNode (This, Buffer, &Node, &PNode);
> +
> +  if (EFI_ERROR(Status) || PNode == NULL) {
> +    DEBUG ((USB_DEBUG_MEM_NODE_ERROR, "RemoveNode - Node Not Found\n"));
> +    return EFI_NOT_FOUND;
> +  }
> +
> +  if (Node != UsbFuncIoDevPtr->FirstNodePtr) {
> +    PNode->NextPtr = Node->NextPtr;
> +  } else {
> +    UsbFuncIoDevPtr->FirstNodePtr = Node->NextPtr;
> +  }
> +
> +  FreePool (Node->AllocatePtr);
> +  FreePool (Node);
> +  DEBUG ((USB_DEBUG_MEM_NODE_INFO, "RemoveNode - Exit\n"));
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  The InsertNewNodeToHead function allocates a memory for record the driver allocate
> +  memory region and insert the node to the head link list.
> +
> +  @param[in]  This              A pointer to the EFI_USBFN_IO_PROTOCOL instance.
> +  @param[out] USB_MEM_NODE      return the new node address.
> +
> +  @retval EFI_SUCCESS           The operation completed successfully.
> +  @retval EFI_INVALID_PARAMETER A parameter is invalid.
> +  @retval EFI_OUT_OF_RESOURCES  The requested transfer Buffer could not be allocated.
> +
> +**/
> +EFI_STATUS
> +InsertNewNodeToHead (
> +  IN  EFI_USBFN_IO_PROTOCOL    *This,
> +  OUT USB_MEM_NODE             **Node
> +  )
> +{
> +  USB_MEM_NODE         *NewNodePtr;
> +  USB_MEM_NODE         *CurrentNodePtr;
> +  USB_XDCI_DEV_CONTEXT *UsbFuncIoDevPtr;
> +  EFI_STATUS           Status;
> +
> +  DEBUG ((USB_DEBUG_MEM_NODE_INFO, "CreateNewNode - Entry\n"));
> +
> +  if (This == NULL) {
> +    Status = EFI_INVALID_PARAMETER;
> +    goto ErrorExit;
> +  }
> +
> +  UsbFuncIoDevPtr = USBFUIO_CONTEXT_FROM_PROTOCOL(This);
> +
> +  //
> +  // Create the new node
> +  //
> +  NewNodePtr = AllocateZeroPool (sizeof(USB_MEM_NODE));
> +  DEBUG ((USB_DEBUG_MEM_NODE_INFO, "NewNodePtr - Addr = 0x%08x\n",(UINTN)NewNodePtr));
> +
> +  if (NewNodePtr == NULL) {
> +    Status = EFI_OUT_OF_RESOURCES;
> +    goto ErrorExit;
> +  }
> +
> +  //
> +  // insert the new node
> +  //
> +  CurrentNodePtr = UsbFuncIoDevPtr->FirstNodePtr;
> +  UsbFuncIoDevPtr->FirstNodePtr = NewNodePtr;
> +
> +  if (CurrentNodePtr != NULL) {
> +    NewNodePtr->NextPtr = CurrentNodePtr;
> +  }
> +
> +  *Node = NewNodePtr;
> +
> +  DEBUG ((USB_DEBUG_MEM_NODE_INFO, "CreateNewNode - Exit\n"));
> +  return EFI_SUCCESS;
> +
> +ErrorExit:
> +
> +  DEBUG ((USB_DEBUG_MEM_NODE_ERROR, "CreateNewNode - error %r\n",Status));
> +  return Status;
> +}
> +
> diff --git a/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbIoNode.h b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbIoNode.h
> new file mode 100644
> index 0000000000..ecedb2748b
> --- /dev/null
> +++ b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbIoNode.h
> @@ -0,0 +1,90 @@
> +/** @file
> +  Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR>
> +
> +  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.
> +
> +**/
> +
> +#ifndef __EFI_USB_FUIO_MEM_NODE__
> +#define __EFI_USB_FUIO_MEM_NODE__
> +
> +#include <Uefi.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/DevicePathLib.h>
> +#include <Library/DriverLib.h>
> +
> +#define  USB_DEBUG_MEM_NODE_INFO  EFI_D_INIT
> +#define  USB_DEBUG_MEM_NODE_ERROR EFI_D_ERROR
> +
> +
> +typedef struct {
> +  UINTN                         Size;
> +  VOID                          *AllocatePtr;
> +  VOID                          *NextPtr;
> +} USB_MEM_NODE;
> +
> +/**
> +  The SearchNode function search a memory address for record the driver allocate
> +  memory region and the node to the head link list.
> +
> +  @param[in]  This              A pointer to the EFI_USBFN_IO_PROTOCOL instance.
> +  @param[in]  Buffer            The driver alocate memory address.
> +  @param[out] Node              The match node record of the driver aloocate
> +                                memory region.
> +  @param[out] PNode             The pervious match node record of the driver
> +                                aloocate memory region.
> +
> +  @retval EFI_SUCCESS           The operation completed successfully.
> +  @retval EFI_NOT_FOUND         The memory Buffer didn't find.
> +**/
> +EFI_STATUS
> +SearchNode (
> +  IN  EFI_USBFN_IO_PROTOCOL    *This,
> +  IN  VOID                     *Buffer,
> +  OUT USB_MEM_NODE             **Node,
> +  OUT USB_MEM_NODE             **PNode
> +  );
> +
> +/**
> +  The InsertNewNodeToHead function remove a memory for record the driver allocate
> +  memory region and the node to the head link list.
> +
> +  @param[in]  This              A pointer to the EFI_USBFN_IO_PROTOCOL instance.
> +  @param[in]  Buffer            The driver alocate memory address.
> +
> +  @retval EFI_SUCCESS           The operation completed successfully.
> +  @retval EFI_NOT_FOUND         The memory Buffer didn't find.
> +**/
> +EFI_STATUS
> +RemoveNode (
> +  IN  EFI_USBFN_IO_PROTOCOL    *This,
> +  IN  VOID                     *Buffer
> +  );
> +
> +/**
> +  The InsertNewNodeToHead function allocates a memory for record the driver allocate
> +  memory region and insert the node to the head link list.
> +
> +  @param[in]  This              A pointer to the EFI_USBFN_IO_PROTOCOL instance.
> +  @param[out] USB_MEM_NODE      return the new node address.
> +
> +  @retval EFI_SUCCESS           The operation completed successfully.
> +  @retval EFI_INVALID_PARAMETER A parameter is invalid.
> +  @retval EFI_OUT_OF_RESOURCES  The requested transfer Buffer could not be allocated.
> +
> +**/
> +EFI_STATUS
> +InsertNewNodeToHead (
> +  IN  EFI_USBFN_IO_PROTOCOL    *This,
> +  OUT USB_MEM_NODE             **Node
> +  );
> +
> +  #endif
> +
> +
> diff --git a/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciCommon.h b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciCommon.h
> new file mode 100644
> index 0000000000..6a53068681
> --- /dev/null
> +++ b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciCommon.h
> @@ -0,0 +1,156 @@
> +/** @file
> +  Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR>
> +
> +  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.
> +
> +**/
> +
> +#ifndef _XDCI_COMMON_H_
> +#define _XDCI_COMMON_H_
> +
> +#define USB_SETUP_DATA_PHASE_DIRECTION_MASK  (0x80)
> +
> +//
> +// EP direction
> +//
> +typedef enum {
> +  UsbEpDirOut = 0,
> +  UsbEpDirIn  = 1
> +} USB_EP_DIR;
> +
> +//
> +// USB Speeds
> +//
> +typedef enum {
> +  USB_SPEED_HIGH  = 0,
> +  USB_SPEED_FULL,
> +  USB_SPEED_LOW,
> +  USB_SPEED_SUPER = 4
> +} USB_SPEED;
> +
> +typedef enum {
> +  USB_ID_DWC_XDCI = 0,
> +  USB_CORE_ID_MAX
> +} USB_CONTROLLER_ID;
> +
> +typedef enum {
> +  USB_ROLE_HOST = 1,
> +  USB_ROLE_DEVICE,
> +  USB_ROLE_OTG
> +} USB_ROLE;
> +
> +typedef enum {
> +  USB_XFER_QUEUED    = 0,
> +  USB_XFER_SUCCESSFUL,
> +  USB_XFER_STALL
> +} USB_XFER_STATUS;
> +
> +typedef enum {
> +  USB_DEVICE_DISCONNECT_EVENT       = 0,
> +  USB_DEVICE_RESET_EVENT,
> +  USB_DEVICE_CONNECTION_DONE,
> +  USB_DEVICE_STATE_CHANGE_EVENT,
> +  USB_DEVICE_WAKEUP_EVENT,
> +  USB_DEVICE_HIBERNATION_REQ_EVENT,
> +  USB_DEVICE_SOF_EVENT              = 7,
> +  USB_DEVICE_ERRATIC_ERR_EVENT      = 9,
> +  USB_DEVICE_CMD_CMPLT_EVENT,
> +  USB_DEVICE_BUFF_OVERFLOW_EVENT,
> +  USB_DEVICE_TEST_LMP_RX_EVENT,
> +  USB_DEVICE_SETUP_PKT_RECEIVED,
> +  USB_DEVICE_XFER_NRDY,
> +  USB_DEVICE_XFER_DONE
> +} USB_DEVICE_EVENT_ID;
> +
> +typedef enum {
> +  U0 = 0,
> +  U1,
> +  U2,
> +  U3,
> +  SS_DIS,
> +  RX_DET,
> +  SS_INACT,
> +  POLL,
> +  RECOV,
> +  HRESET,
> +  CMPLY,
> +  LPBK,
> +  RESUME_RESET = 15
> +} USB_DEVICE_SS_LINK_STATE;
> +
> +typedef enum {
> +  CTRL_SETUP_PHASE,
> +  CTRL_DATA_PHASE,
> +  CTRL_STATUS_PHASE
> +} USB_CONTROL_XFER_PHASE;
> +
> +typedef enum  {
> +  USB_EP_STATE_DISABLED = 0,
> +  USB_EP_STATE_ENABLED,
> +  USB_EP_STATE_STALLED,
> +  USB_EP_STATE_SETUP,
> +  USB_EP_STATE_IN_DATA,
> +  USB_EP_STATE_OUT_DATA,
> +  USB_EP_STATE_DATA,
> +  USB_EP_STATE_STATUS
> +} USB_EP_STATE;
> +
> +typedef struct  {
> +  VOID                      *ParentHandle;
> +  UINT32                    Hird;
> +  UINT32                    EpNum;
> +  USB_SPEED                 Speed;
> +  USB_EP_STATE              EpState;
> +  USB_EP_DIR                EpDir;
> +  UINT8                     EpType;
> +  USB_DEVICE_SS_LINK_STATE  LinkState;
> +  UINT8                     *Buffer;
> +  BOOLEAN                   SsEvent;
> +} USB_DEVICE_CALLBACK_PARAM;
> +
> +//
> +// USB endpoint
> +//
> +typedef struct {
> +  UINT32       EpNum;
> +  USB_EP_DIR   EpDir;
> +  UINT8        EpType;
> +  UINT32       MaxPktSize;
> +  UINT32       MaxStreams;
> +  UINT32       BurstSize;
> +  UINT32       Interval;
> +  UINT32       Mult;
> +} USB_EP_INFO;
> +
> +//
> +// USB transfer request
> +//
> +typedef struct _USB_XFER_REQUEST USB_XFER_REQUEST;
> +
> +typedef
> +VOID
> +(EFIAPI *USB_XFER_DONE_CALLBACK) (
> +  IN VOID                    *XdciHndl,
> +  IN USB_XFER_REQUEST        *XferReq
> +  );
> +
> +struct _USB_XFER_REQUEST {
> +  VOID                      *XferBuffer;     // Buffer address. bus-width aligned
> +  UINT32                    XferLen;         // Requested transfer length
> +  UINT32                    ActualXferLen;  // Actual transfer length at completion callback stage
> +  UINT32                    StreamId;        // Stream ID. Only relevant for bulk streaming
> +  UINT32                    FrameNum;        // Only relevant for periodic transfer
> +  USB_XFER_STATUS           XferStatus;      // Transfer status
> +  USB_EP_INFO               EpInfo;          // EP info
> +  USB_XFER_DONE_CALLBACK    XferDone;        // Transfer completion callback
> +  BOOLEAN                   Zlp;              // Do zero-length transfer
> +};
> +
> +#endif
> +
> diff --git a/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciDWC.c b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciDWC.c
> new file mode 100644
> index 0000000000..3569ba6975
> --- /dev/null
> +++ b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciDWC.c
> @@ -0,0 +1,4030 @@
> +/** @file
> +  Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR>
> +
> +  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.
> +
> +**/
> +
> +#include "UsbDeviceMode.h"
> +#include "XdciInterface.h"
> +#include "XdciDWC.h"
> +
> +
> +UINT32
> +UsbRegRead (
> +  IN UINT32    Base,
> +  IN UINT32    Offset
> +  )
> +{
> +  volatile UINT32 *addr = (volatile UINT32 *)((UINTN)(Base) + (UINTN)(Offset));
> +  return *addr;
> +}
> +
> +VOID
> +UsbRegWrite (
> +  IN UINT32    Base,
> +  IN UINT32    Offset,
> +  IN UINT32    val
> +  )
> +{
> +  volatile UINT32 *addr = (volatile UINT32 *)((UINTN)(Base) + (UINTN)(Offset));
> +  *addr = val;
> +}
> +
> +
> +/**
> +  Internal utility function:
> +  This function is used to obtain physical endpoint number
> +  xDCI needs physical endpoint number for EP registers
> +  We also use it to index into our EP array
> +  Note: Certain data structures/commands use logical EP numbers
> +  as opposed to physical endpoint numbers so one should be
> +  careful when interpreting EP numbers
> +  @EpNum: Logical endpoint number
> +  @epDir: Direction for the endpoint
> +
> +**/
> +STATIC
> +UINT32
> +DwcXdciGetPhysicalEpNum (
> +  IN UINT32        EndpointNum,
> +  IN USB_EP_DIR    EndpointDir
> +  )
> +{
> +  return EndpointDir? ((EndpointNum << 1) | EndpointDir) : (EndpointNum << 1);
> +}
> +
> +
> +/**
> +  Internal utility function:
> +  This function is used to obtain the MPS for control transfers
> +  Based on the Speed. If this is called before bus reset completes
> +  then it returns MPS Based on desired Speed. If it is after bus
> +  reset then MPS returned is Based on actual negotiated Speed
> +  @CoreHandle: xDCI controller handle address
> +  @mps: address of 32-bit variable to return the MPS
> +
> +**/
> +STATIC
> +EFI_STATUS
> +DwcXdciCoreGetCtrlMps (
> +  IN XDCI_CORE_HANDLE    *CoreHandle,
> +  IN UINT32              *mps
> +  )
> +{
> +  if (CoreHandle == NULL) {
> +      DEBUG ((DEBUG_INFO, "ERROR: DwcXdciCoreGetCtrlMps: INVALID handle\n"));
> +      return EFI_DEVICE_ERROR;
> +  }
> +
> +  if (mps == NULL) {
> +    DEBUG ((DEBUG_INFO, "ERROR: DwcXdciCoreGetCtrlMps: INVALID parameter\n"));
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  switch (CoreHandle->ActualSpeed) {
> +    case USB_SPEED_HIGH:
> +      *mps = DWC_XDCI_HS_CTRL_EP_MPS;
> +      break;
> +    case USB_SPEED_FULL:
> +      *mps = DWC_XDCI_FS_CTRL_EP_MPS;
> +      break;
> +    case USB_SPEED_LOW:
> +      *mps = DWC_XDCI_LS_CTRL_EP_MPS;
> +      break;
> +    case USB_SPEED_SUPER:
> +      *mps = DWC_XDCI_SS_CTRL_EP_MPS;
> +      break;
> +    default:
> +      *mps = 0;
> +      DEBUG ((DEBUG_INFO, "ERROR: DwcXdciCoreGetCtrlMps: UNKNOWN Speed\n"));
> +      break;
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +
> +/**
> +  Internal utility function:
> +  This function is used to initialize the parameters required
> +  for executing endpoint command
> +  @CoreHandle: xDCI controller handle address
> +  @EpInfo: EP info address
> +  @ConfigAction: Configuration action specific to EP command
> +  @EpCmd: xDCI EP command for which parameters are initialized
> +  @EpCmdParams: address of struct to return EP params
> +
> +**/
> +STATIC
> +EFI_STATUS
> +DwcXdciCoreInitEpCmdParams (
> +  IN XDCI_CORE_HANDLE                *CoreHandle,
> +  IN USB_EP_INFO                     *EpInfo,
> +  IN UINT32                          ConfigAction,
> +  IN DWC_XDCI_ENDPOINT_CMD           EpCmd,
> +  IN DWC_XDCI_ENDPOINT_CMD_PARAMS    *EpCmdParams
> +  )
> +{
> +  EFI_STATUS  status = EFI_SUCCESS;
> +
> +  if (CoreHandle == NULL) {
> +    DEBUG ((DEBUG_INFO, "ERROR: DwcXdciCoreInitEpCmdParams: INVALID handle\n"));
> +    return EFI_DEVICE_ERROR;
> +  }
> +
> +  //
> +  // Reset params
> +  //
> +  EpCmdParams->Param0 = EpCmdParams->Param1 = EpCmdParams->Param2 = 0;
> +
> +  switch (EpCmd) {
> +    case EPCMD_SET_EP_CONFIG:
> +      //
> +      // Issue DEPCFG command for EP
> +      // Issue a DEPCFG (Command 1) command for endpoint
> +      //
> +      if (EpInfo->MaxStreams) {
> +        EpCmdParams->Param1 = DWC_XDCI_PARAM1_SET_EP_CFG_STRM_CAP_MASK;
> +      }
> +
> +      if (EpInfo->Interval) {
> +        EpCmdParams->Param1 |= ((EpInfo->Interval-1) << DWC_XDCI_PARAM1_SET_EP_CFG_BINTM1_BIT_POS);
> +      }
> +
> +      //
> +      // Set EP num
> +      //
> +      EpCmdParams->Param1 |= (EpInfo->EpNum << DWC_XDCI_PARAM1_SET_EP_CFG_EP_NUM_BIT_POS);
> +      //
> +      // Set EP direction
> +      //
> +      EpCmdParams->Param1 |= (EpInfo->EpDir << DWC_XDCI_PARAM1_SET_EP_CFG_EP_DIR_BIT_POS);
> +      //
> +      // Set EP-specific Event enable for not ready and
> +      // complete events
> +      //
> +      EpCmdParams->Param1 &= ~DWC_XDCI_PARAM1_SET_EP_CFG_EVT_EN_MASK;
> +      //
> +      // Setup the events we want enabled for this EP
> +      //
> +      EpCmdParams->Param1 |= (DWC_XDCI_PARAM1_SET_EP_CFG_EVT_XFER_NRDY_MASK |
> +                                DWC_XDCI_PARAM1_SET_EP_CFG_EVT_XFER_IN_PRG_MASK |
> +                                DWC_XDCI_PARAM1_SET_EP_CFG_EVT_XFER_CMPLT_MASK);
> +
> +      //
> +      // We only have one interrupt line for this core.
> +      // Set interrupt number to 0
> +      //
> +      EpCmdParams->Param1 &= ~DWC_XDCI_PARAM1_SET_EP_CFG_INTR_NUM_MASK;
> +
> +      //
> +      // Set FIFOnum = 0 for control EP0
> +      //
> +      EpCmdParams->Param0 &= ~DWC_XDCI_PARAM0_SET_EP_CFG_FIFO_NUM_MASK;
> +
> +      //
> +      // Program FIFOnum for non-EP0 EPs
> +      //
> +      if (EpInfo->EpNum && EpInfo->EpDir) {
> +        EpCmdParams->Param0 |= (EpInfo->EpNum << DWC_XDCI_PARAM0_SET_EP_CFG_FIFO_NUM_BIT_POS);
> +      }
> +
> +      //
> +      // Program max packet size
> +      //
> +      EpCmdParams->Param0 &= ~DWC_XDCI_PARAM0_SET_EP_CFG_MPS_MASK;
> +      EpCmdParams->Param0 |= (EpInfo->MaxPktSize << DWC_XDCI_PARAM0_SET_EP_CFG_MPS_BIT_POS);
> +
> +      //
> +      // Set Burst size. 0 means burst size of 1
> +      //
> +      EpCmdParams->Param0 &= ~DWC_XDCI_PARAM0_SET_EP_CFG_BRST_SIZE_MASK;
> +      EpCmdParams->Param0 |= (EpInfo->BurstSize << DWC_XDCI_PARAM0_SET_EP_CFG_BRST_SIZE_BIT_POS);
> +
> +      //
> +      // Set EP type
> +      //
> +      EpCmdParams->Param0 &= ~DWC_XDCI_PARAM0_SET_EP_CFG_EP_TYPE_MASK;
> +      EpCmdParams->Param0 |= (EpInfo->EpType << DWC_XDCI_PARAM0_SET_EP_CFG_EP_TYPE_BIT_POS);
> +
> +      //
> +      // Set config action
> +      //
> +      EpCmdParams->Param0 &= ~DWC_XDCI_PARAM0_SET_EP_CFG_ACTN_MASK;
> +      EpCmdParams->Param0 |= (ConfigAction << DWC_XDCI_PARAM0_SET_EP_CFG_ACTN_BIT_POS);
> +      break;
> +
> +    case EPCMD_SET_EP_XFER_RES_CONFIG:
> +      // Set Param0 to 1. Same for all EPs when resource
> +      // configuration is done
> +      //
> +      EpCmdParams->Param0 = 1;
> +      break;
> +
> +    case EPCMD_END_XFER:
> +      //
> +      // Nothing to set. Already reset params for all cmds
> +      //
> +      break;
> +
> +    case EPCMD_START_NEW_CONFIG:
> +      //
> +      // Nothing to set. Already reset params for all cmds
> +      //
> +      break;
> +
> +    default:
> +      status = EFI_INVALID_PARAMETER;
> +      DEBUG ((DEBUG_INFO, "\nDwcXdciCoreInitEpCmdParams: INVALID Parameter"));
> +      break;
> +  }
> +
> +  return status;
> +}
> +
> +
> +/**
> +  Internal utility function:
> +  This function is used to issue the xDCI endpoint command
> +  @CoreHandle: xDCI controller handle address
> +  @EpNum: Physical EP num
> +  @EpCmd: xDCI EP command
> +  @EpCmdParams: EP command parameters address
> +
> +**/
> +STATIC
> +EFI_STATUS
> +DwcXdciCoreIssueEpCmd (
> +  IN XDCI_CORE_HANDLE                *CoreHandle,
> +  IN UINT32                          EpNum,
> +  IN UINT32                          EpCmd,
> +  IN DWC_XDCI_ENDPOINT_CMD_PARAMS    *EpCmdParams
> +  )
> +{
> +  UINT32 BaseAddr;
> +  UINT32 MaxDelayIter = 5000;//DWC_XDCI_MAX_DELAY_ITERATIONS;
> +
> +  if (CoreHandle == NULL) {
> +    DEBUG ((DEBUG_INFO, "ERROR: DwcXdciCoreIssueEpCmd: INVALID handle\n"));
> +    return EFI_DEVICE_ERROR;
> +  }
> +
> +  BaseAddr = CoreHandle->BaseAddress;
> +
> +  //
> +  // Set EP command parameter values
> +  //
> +  UsbRegWrite (
> +    BaseAddr,
> +    DWC_XDCI_EPCMD_PARAM2_REG(EpNum),
> +    EpCmdParams->Param2
> +    );
> +
> +  UsbRegWrite (
> +    BaseAddr,
> +    DWC_XDCI_EPCMD_PARAM1_REG(EpNum),
> +    EpCmdParams->Param1
> +    );
> +
> +  UsbRegWrite (
> +    BaseAddr,
> +    DWC_XDCI_EPCMD_PARAM0_REG(EpNum),
> +    EpCmdParams->Param0
> +    );
> +
> +  //
> +  // Set the command code and activate it
> +  //
> +  UsbRegWrite (
> +    BaseAddr,
> +    DWC_XDCI_EPCMD_REG(EpNum),
> +    EpCmd | DWC_XDCI_EPCMD_CMD_ACTIVE_MASK
> +    );
> +
> +  //
> +  // Wait until command completes
> +  //
> +  do {
> +    if (!(UsbRegRead (BaseAddr, DWC_XDCI_EPCMD_REG(EpNum)) & DWC_XDCI_EPCMD_CMD_ACTIVE_MASK))
> +      break;
> +    else
> +      gBS->Stall (DWC_XDCI_MAX_DELAY_ITERATIONS);
> +  } while (--MaxDelayIter);
> +
> +  if (!MaxDelayIter) {
> +    DEBUG ((DEBUG_INFO, "DwcXdciCoreIssueEpCmd. ERROR: Failed to issue Command\n"));
> +    return EFI_DEVICE_ERROR;
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +
> +/**
> +  Internal utility function:
> +  This function is used to flush all FIFOs
> +  @CoreHandle: xDCI controller handle address
> +
> +**/
> +STATIC
> +EFI_STATUS
> +DwcXdciCoreFlushAllFifos (
> +  IN XDCI_CORE_HANDLE    *CoreHandle
> +  )
> +{
> +  UINT32 BaseAddr;
> +  UINT32 MaxDelayIter = DWC_XDCI_MAX_DELAY_ITERATIONS;
> +
> +  if (CoreHandle == NULL) {
> +    DEBUG ((DEBUG_INFO, "ERROR: DwcXdciCoreFlushAllFifos: INVALID handle\n"));
> +    return EFI_DEVICE_ERROR;
> +  }
> +
> +  BaseAddr = CoreHandle->BaseAddress;
> +
> +  //
> +  // Write the command to flush all FIFOs
> +  //
> +  UsbRegWrite(
> +    BaseAddr,
> +    DWC_XDCI_DGCMD_REG,
> +    (UsbRegRead (BaseAddr, DWC_XDCI_DGCMD_REG) | DWC_XDCI_DGCMD_CMD_ALL_FIFO_FLUSH | DWC_XDCI_DGCMD_CMD_ACTIVE_MASK)
> +    );
> +
> +  //
> +  // Wait until command completes
> +  //
> +  do {
> +    if (!(UsbRegRead (BaseAddr, DWC_XDCI_DGCMD_REG) & DWC_XDCI_DGCMD_CMD_ACTIVE_MASK))
> +      break;
> +    else
> +      gBS->Stall (DWC_XDCI_MAX_DELAY_ITERATIONS);
> +  } while (--MaxDelayIter);
> +
> +  if (!MaxDelayIter) {
> +    DEBUG ((DEBUG_INFO, "Failed to issue Command\n"));
> +    return EFI_DEVICE_ERROR;
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +
> +/**
> +  Internal utility function:
> +  This function is used to flush Tx FIFO specific to an endpoint
> +  @CoreHandle: xDCI controller handle address
> +  @EpNum: Physical EP num
> +
> +**/
> +STATIC
> +EFI_STATUS
> +DwcXdciCoreFlushEpTxFifo (
> +  IN XDCI_CORE_HANDLE    *CoreHandle,
> +  IN UINT32              EpNum
> +  )
> +{
> +  UINT32 BaseAddr;
> +  UINT32 MaxDelayIter = DWC_XDCI_MAX_DELAY_ITERATIONS;
> +  UINT32 fifoNum;
> +
> +  if (CoreHandle == NULL) {
> +    DEBUG ((DEBUG_INFO, "ERROR: DwcXdciCoreFlushEpTxFifo: INVALID handle\n"));
> +    return EFI_DEVICE_ERROR;
> +  }
> +
> +  BaseAddr = CoreHandle->BaseAddress;
> +
> +  //
> +  // Translate to FIFOnum
> +  // NOTE: Assuming this is a Tx EP
> +  //
> +  fifoNum = (EpNum >> 1);
> +
> +  //
> +  // TODO: Currently we are only using TxFIFO 0. Later map these
> +  // Write the FIFO num/dir param for the generic command.
> +  //
> +  UsbRegWrite (
> +    BaseAddr,
> +    DWC_XDCI_DGCMD_PARAM_REG,
> +    ((UsbRegRead (BaseAddr, DWC_XDCI_DGCMD_PARAM_REG) & ~DWC_XDCI_DGCMD_PARAM_TX_FIFO_NUM_MASK) | DWC_XDCI_DGCMD_PARAM_TX_FIFO_DIR_MASK)
> +    );
> +
> +  //
> +  // Write the command to flush all FIFOs
> +  //
> +  UsbRegWrite (
> +    BaseAddr,
> +    DWC_XDCI_DGCMD_REG,
> +    (UsbRegRead(BaseAddr, DWC_XDCI_DGCMD_REG) | DWC_XDCI_DGCMD_CMD_SEL_FIFO_FLUSH | DWC_XDCI_DGCMD_CMD_ACTIVE_MASK)
> +    );
> +
> +
> +  //
> +  // Wait until command completes
> +  //
> +  do {
> +    if (!(UsbRegRead(BaseAddr, DWC_XDCI_DGCMD_REG) & DWC_XDCI_DGCMD_CMD_ACTIVE_MASK))
> +      break;
> +    else
> +      gBS->Stall (DWC_XDCI_MAX_DELAY_ITERATIONS);
> +  } while (--MaxDelayIter);
> +
> +  if (!MaxDelayIter) {
> +    DEBUG ((DEBUG_INFO, "Failed to issue Command\n"));
> +    return EFI_DEVICE_ERROR;
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +
> +
> +STATIC
> +EFI_STATUS
> +DwcXdciCorePrepareOneTrb (
> +  IN DWC_XDCI_TRB            *Trb,
> +  IN DWC_XDCI_TRB_CONTROL    TrbCtrl,
> +  IN UINT32                  LastBit,
> +  IN UINT32                  ChainBit,
> +  IN UINT8                   *BufferPtr,
> +  IN UINT32                  size
> +  )
> +{
> +  DEBUG ((DEBUG_INFO, "Trb is 0x%x, BufferPtr is 0x%x, size is 0x%x\n", Trb, BufferPtr, size));
> +
> +  Trb->BuffPtrLow = (UINT32)(UINTN)BufferPtr;
> +  Trb->BuffPtrHigh = 0;
> +  Trb->LenXferParams = size;
> +  Trb->TrbCtrl = TrbCtrl << DWC_XDCI_TRB_CTRL_TYPE_BIT_POS;
> +
> +  if (ChainBit)
> +    Trb->TrbCtrl |= ChainBit << DWC_XDCI_TRB_CTRL_CHAIN_BUFF_BIT_POS;
> +
> +  if (LastBit)
> +    Trb->TrbCtrl |= LastBit << DWC_XDCI_TRB_CTRL_LST_TRB_BIT_POS;
> +
> +  Trb->TrbCtrl |= DWC_XDCI_TRB_CTRL_IOSP_MISOCH_MASK| DWC_XDCI_TRB_CTRL_HWO_MASK;
> +
> +  DEBUG ((DEBUG_INFO, "(DwcXdciCorePrepareOneTrb) Trb->BuffPtrLow = 0x%x, Trb->LenXferParams is 0x%x, Trb->TrbCtrl is 0x%x\n",
> +                                                       Trb->BuffPtrLow, Trb->LenXferParams, Trb->TrbCtrl));
> +  return EFI_SUCCESS;
> +}
> +
> +
> +/**
> +  Internal utility function:
> +  This function is used to initialize transfer request block
> +  @CoreHandle: xDCI controller handle address
> +  @Trb: Address of TRB to initialize
> +  @TrbCtrl: TRB control value
> +  @buffPtr: Transfer Buffer address
> +  @size: Size of the transfer
> +
> +**/
> +STATIC
> +EFI_STATUS
> +DwcXdciCoreInitTrb (
> +  IN XDCI_CORE_HANDLE        *CoreHandle,
> +  IN DWC_XDCI_TRB            *Trb,
> +  IN DWC_XDCI_TRB_CONTROL    TrbCtrl,
> +  IN UINT8                   *BufferPtr,
> +  IN UINT32                  size
> +  )
> +{
> +#define ONE_TRB_SIZE      (DWC_XDCI_TRB_BUFF_SIZE_MASK & 0x00F00000)
> +  UINT8                   *TrbBuffer;
> +  UINT32                  TrbCtrlLast;
> +  UINT32                  TrbCtrlChain;
> +  UINT32                  TrbIndex;
> +
> +  if (CoreHandle == NULL) {
> +    DEBUG ((DEBUG_INFO, "ERROR: DwcXdciCoreInitTrb: INVALID handle\n"));
> +    return EFI_DEVICE_ERROR;
> +  }
> +
> +  if (Trb == NULL) {
> +    DEBUG ((DEBUG_INFO, "ERROR: DwcXdciCoreInitTrb: INVALID handle\n"));
> +    return EFI_INVALID_PARAMETER;
> +  }
> +  
> +   //
> +   // Init TRB fields
> +   // NOTE: Assuming we are only using 32-bit addresses
> +   // TODO: update for 64-bit addresses
> +   //
> +  if (size <= DWC_XDCI_TRB_BUFF_SIZE_MASK) {
> +    //
> +    // Can transfer in one TRB
> +    //
> +    TrbCtrlChain = 0;
> +    TrbCtrlLast = 1;
> +    DwcXdciCorePrepareOneTrb (Trb, TrbCtrl, TrbCtrlLast, TrbCtrlChain, BufferPtr, size);
> +    return EFI_SUCCESS;
> +  }
> +
> +  //
> +  // Can't transfer in one TRB.
> +  // Seperate it in every ONE_TRB_SIZE of TRB
> +  //
> +  TrbBuffer = BufferPtr;
> +  TrbIndex = 0;
> +  while (size > ONE_TRB_SIZE) {
> +    TrbCtrlChain = 1;
> +    TrbCtrlLast = 0;
> +    DwcXdciCorePrepareOneTrb (Trb, TrbCtrl, TrbCtrlLast, TrbCtrlChain, TrbBuffer, ONE_TRB_SIZE);
> +    TrbBuffer += ONE_TRB_SIZE;
> +    size -= ONE_TRB_SIZE;
> +    Trb++;
> +    TrbIndex++;
> +    if (TrbIndex >= DWC_XDCI_TRB_NUM)
> +      return EFI_OUT_OF_RESOURCES;
> +  }
> +  TrbCtrlChain = 0;
> +  TrbCtrlLast = 1;
> +  DwcXdciCorePrepareOneTrb (Trb, TrbCtrl, TrbCtrlLast, TrbCtrlChain, TrbBuffer, size);
> +
> +  return EFI_SUCCESS;
> +}
> +
> +
> +/**
> +  Internal function:
> +  This function is used to start a SETUP phase on control endpoint
> +  @CoreHandle: xDCI controller handle address
> +
> +**/
> +STATIC
> +EFI_STATUS
> +DwcXdciCoreStartEp0SetupXfer (
> +  IN XDCI_CORE_HANDLE    *CoreHandle
> +  )
> +{
> +  DWC_XDCI_ENDPOINT_CMD_PARAMS    EpCmdParams;
> +  EFI_STATUS                      status = EFI_DEVICE_ERROR;
> +  DWC_XDCI_TRB                    *Trb;
> +
> +  if (CoreHandle == NULL) {
> +    DEBUG ((DEBUG_INFO, "ERROR: DwcXdciCoreStartEp0SetupXfer: INVALID handle\n"));
> +    return EFI_DEVICE_ERROR;
> +  }
> +
> +  if (CoreHandle->EpHandles[0].State == USB_EP_STATE_SETUP) {
> +    DEBUG ((DEBUG_INFO, "EP0 was already in SETUP phase\n"));
> +    return EFI_SUCCESS;
> +  }
> +
> +  CoreHandle->EpHandles[0].State = USB_EP_STATE_SETUP;
> +  Trb = CoreHandle->Trbs;
> +  DEBUG ((DEBUG_INFO, "(DwcXdciCoreStartEp0SetupXfer)\n"));
> +
> +  status = DwcXdciCoreInitTrb (
> +             CoreHandle,
> +             Trb,
> +             TRBCTL_SETUP,
> +             CoreHandle->AlignedSetupBuffer,
> +             8
> +             );
> +
> +  if (status)
> +    return status;
> +
> +  //
> +  // Issue a DEPSTRTXFER for EP0
> +  // Reset params
> +  //
> +  EpCmdParams.Param0 = EpCmdParams.Param1 = EpCmdParams.Param2 = 0;
> +
> +  //
> +  // Init the lower re-bits for TRB address
> +  //
> +  EpCmdParams.Param1 = (UINT32)(UINTN)Trb;
> +
> +  //
> +  // Issue the command to start transfer on physical
> +  // endpoint 0
> +  //
> +  status = DwcXdciCoreIssueEpCmd (
> +             CoreHandle,
> +             0,
> +             EPCMD_START_XFER,
> +             &EpCmdParams
> +             );
> +
> +  //
> +  // Save new resource index for this transfer
> +  //
> +  CoreHandle->EpHandles[0].CurrentXferRscIdx = ((UsbRegRead (
> +                                                     CoreHandle->BaseAddress,
> +                                                     DWC_XDCI_EPCMD_REG(0)) & DWC_XDCI_EPCMD_RES_IDX_MASK) >> DWC_XDCI_EPCMD_RES_IDX_BIT_POS
> +                                                     );
> +
> +  return status;
> +}
> +
> +
> +/**
> +  Internal function:
> +  This function is used to process the state change event
> +  @CoreHandle: xDCI controller handle address
> +  @event: device event dword
> +
> +**/
> +STATIC
> +EFI_STATUS
> +DwcXdciProcessDeviceStateChangeEvent (
> +  IN XDCI_CORE_HANDLE    *CoreHandle,
> +  IN UINT32              Event
> +  )
> +{
> +  if (CoreHandle == NULL) {
> +    DEBUG ((DEBUG_INFO, "ERROR: DwcXdciProcessDeviceStateChangeEvent: INVALID handle\n"));
> +    return EFI_DEVICE_ERROR;
> +  }
> +
> +  CoreHandle->HirdVal = (Event & DWC_XDCI_EVENT_BUFF_DEV_HIRD_MASK) >> DWC_XDCI_EVENT_BUFF_DEV_HIRD_BIT_POS;
> +
> +  CoreHandle->LinkState = ((Event & DWC_XDCI_EVENT_BUFF_DEV_LINK_STATE_MASK) >> DWC_XDCI_EVENT_BUFF_DEV_LINK_STATE_BIT_POS);
> +
> +  if (CoreHandle->EventCallbacks.DevLinkStateCallback) {
> +    CoreHandle->EventCallbacks.CbEventParams.ParentHandle = CoreHandle->ParentHandle;
> +    CoreHandle->EventCallbacks.CbEventParams.LinkState = CoreHandle->LinkState;
> +    CoreHandle->EventCallbacks.CbEventParams.Hird = CoreHandle->HirdVal;
> +    CoreHandle->EventCallbacks.CbEventParams.SsEvent = (Event & DWC_XDCI_EVENT_BUFF_DEV_SS_EVENT_MASK) ? 1 : 0;
> +    CoreHandle->EventCallbacks.DevLinkStateCallback (&CoreHandle->EventCallbacks.CbEventParams);
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +
> +/**
> +  Internal function:
> +  This function is used to issue a command to end transfer
> +  @CoreHandle: xDCI controller handle address
> +  @EpNum: Physical EP num for which transfer is to be ended
> +
> +**/
> +STATIC
> +EFI_STATUS
> +DwcXdciEndXfer (
> +  IN XDCI_CORE_HANDLE    *CoreHandle,
> +  IN UINT32              EpNum
> +  )
> +{
> +  EFI_STATUS                      status;
> +  DWC_XDCI_ENDPOINT_CMD_PARAMS    EpCmdParams;
> +  UINT32                          cmdParams;
> +  DWC_XDCI_TRB                    *TrbPtr;
> +
> +  if (CoreHandle == NULL) {
> +    DEBUG ((DEBUG_INFO, "ERROR: DwcXdciEndXfer: INVALID handle\n"));
> +    return EFI_DEVICE_ERROR;
> +  }
> +
> +  CoreHandle->EpHandles[EpNum].CheckFlag = FALSE;
> +
> +  //
> +  // Issue a DEPENDXFER for EP
> +  // Reset params
> +  //
> +  EpCmdParams.Param0 = EpCmdParams.Param1 = EpCmdParams.Param2 = 0;
> +
> +  cmdParams = ((CoreHandle->EpHandles[EpNum].CurrentXferRscIdx << DWC_XDCI_EPCMD_RES_IDX_BIT_POS) | DWC_XDCI_EPCMD_FORCE_RM_MASK);
> +
> +  if (CoreHandle->EpHandles[EpNum].CurrentXferRscIdx == 0) {
> +    return EFI_SUCCESS;
> +  }
> +  //
> +  // Issue the command
> +  //
> +  status = DwcXdciCoreIssueEpCmd(
> +             CoreHandle,
> +             EpNum,
> +             cmdParams | DWC_XDCI_EPCMD_END_XFER,
> +             &EpCmdParams
> +             );
> +
> +  if (!status) {
> +    CoreHandle->EpHandles[EpNum].CurrentXferRscIdx = 0;
> +    TrbPtr = CoreHandle->Trbs + (EpNum * DWC_XDCI_TRB_NUM);
> +    ZeroMem (TrbPtr, DWC_XDCI_TRB_NUM * sizeof (DWC_XDCI_TRB));
> +  }
> +
> +  return status;
> +}
> +
> +
> +/**
> +  Internal function:
> +  This function is used to process bus reset detection event
> +  @CoreHandle: xDCI controller handle address
> +
> +**/
> +STATIC
> +EFI_STATUS
> +DwcXdciProcessDeviceResetDet (
> +  IN XDCI_CORE_HANDLE    *CoreHandle
> +  )
> +{
> +  EFI_STATUS  status = EFI_SUCCESS;
> +
> +  if (CoreHandle == NULL) {
> +    return EFI_DEVICE_ERROR;
> +  }
> +
> +  //
> +  // Flush all FIFOs
> +  //
> +  status = DwcXdciCoreFlushAllFifos(CoreHandle);
> +  if (status) {
> +    DEBUG ((DEBUG_INFO, "DwcXdciProcessDeviceResetDet: Failed to flush FIFOs\n"));
> +  }
> +
> +  //
> +  // Start SETUP phase on EP0
> +  //
> +  status = DwcXdciCoreStartEp0SetupXfer(CoreHandle);
> +
> +  if (status) {
> +    DEBUG ((DEBUG_INFO, "DwcXdciProcessDeviceResetDet: Failed to start SETUP phase for EP0\n"));
> +    return status;
> +  }
> +
> +  //
> +  // Notify upper layer if a callback is registerd for
> +  //  this event
> +  //
> +  if (CoreHandle->EventCallbacks.DevBusResetCallback) {
> +    CoreHandle->EventCallbacks.CbEventParams.ParentHandle = CoreHandle->ParentHandle;
> +    status = CoreHandle->EventCallbacks.DevBusResetCallback (&CoreHandle->EventCallbacks.CbEventParams);
> +  }
> +
> +  return status;
> +}
> +
> +
> +/**
> +  Internal function:
> +  This function is used to process connection done (means reset
> +  complete) event
> +  @CoreHandle: xDCI controller handle address
> +
> +**/
> +STATIC
> +EFI_STATUS
> +DwcXdciProcessDeviceResetDone (
> +  IN XDCI_CORE_HANDLE    *CoreHandle
> +  )
> +{
> +  DWC_XDCI_ENDPOINT_CMD_PARAMS    EpCmdParams;
> +  UINT32                          BaseAddr;
> +  EFI_STATUS                      status = EFI_SUCCESS;
> +
> +  if (CoreHandle == NULL) {
> +    DEBUG ((DEBUG_INFO, "ERROR: DwcXdciProcessDeviceResetDone: INVALID handle\n"));
> +    return EFI_DEVICE_ERROR;
> +  }
> +
> +  BaseAddr = CoreHandle->BaseAddress;
> +  CoreHandle->ActualSpeed = (UsbRegRead (BaseAddr, DWC_XDCI_DSTS_REG) & DWC_XDCI_DSTS_CONN_SPEED_MASK);
> +  DEBUG ((DEBUG_INFO, "DwcXdciProcessDeviceResetDone CoreHandle->ActualSpeed is %x\n", CoreHandle->ActualSpeed));
> +
> +  //
> +  // Program MPS Based on the negotiated Speed
> +  //
> +  DwcXdciCoreGetCtrlMps (CoreHandle, &CoreHandle->EpHandles[0].EpInfo.MaxPktSize);
> +  DwcXdciCoreGetCtrlMps (CoreHandle, &CoreHandle->EpHandles[1].EpInfo.MaxPktSize);
> +
> +  //
> +  // Init DEPCFG cmd params for EP0
> +  //
> +  status = DwcXdciCoreInitEpCmdParams (
> +             CoreHandle,
> +             &CoreHandle->EpHandles[0].EpInfo,
> +             DWC_XDCI_PARAM0_SET_EP_CFG_ACTN_MDFY_STATE,
> +             EPCMD_SET_EP_CONFIG,
> +             &EpCmdParams
> +             );
> +
> +  if (status) {
> +    return status;
> +  }
> +
> +  //
> +  // Issue the command
> +  //
> +  status = DwcXdciCoreIssueEpCmd (
> +             CoreHandle,
> +             0,
> +             EPCMD_SET_EP_CONFIG,
> +             &EpCmdParams
> +             );
> +
> +  if (status) {
> +    return status;
> +  }
> +
> +  //
> +  // Init DEPCFG cmd params for EP1
> +  //
> +  status = DwcXdciCoreInitEpCmdParams (
> +             CoreHandle,
> +             &CoreHandle->EpHandles[1].EpInfo,
> +             DWC_XDCI_PARAM0_SET_EP_CFG_ACTN_MDFY_STATE,
> +             EPCMD_SET_EP_CONFIG,
> +             &EpCmdParams
> +             );
> +
> +  //
> +  // Issue the command
> +  //
> +  status = DwcXdciCoreIssueEpCmd (
> +             CoreHandle,
> +             1,
> +             EPCMD_SET_EP_CONFIG,
> +             &EpCmdParams
> +             );
> +
> +  //
> +  // Put the other PHY into suspend
> +  //
> +  if (CoreHandle->ActualSpeed == USB_SPEED_SUPER) {
> +    //
> +    // Put HS PHY to suspend
> +    //
> +    UsbRegWrite (
> +      BaseAddr,
> +      DWC_XDCI_GUSB2PHYCFG_REG (0),
> +      (UsbRegRead (BaseAddr, DWC_XDCI_GUSB2PHYCFG_REG(0)) | DWC_XDCI_GUSB2PHYCFG_SUSPEND_PHY_MASK)
> +      );
> +
> +    //
> +    // Clear SS PHY's suspend mask
> +    //
> +    UsbRegWrite (
> +      BaseAddr,
> +      DWC_XDCI_GUSB3PIPECTL_REG (0),
> +      (UsbRegRead (BaseAddr, DWC_XDCI_GUSB3PIPECTL_REG(0)) & ~DWC_XDCI_GUSB3PIPECTL_SUSPEND_PHY_MASK)
> +      );
> +
> +  } else {
> +    //
> +    // Put SS PHY to suspend
> +    //
> +    UsbRegWrite (
> +      BaseAddr,
> +      DWC_XDCI_GUSB3PIPECTL_REG(0),
> +      (UsbRegRead(BaseAddr, DWC_XDCI_GUSB3PIPECTL_REG(0)) | DWC_XDCI_GUSB3PIPECTL_SUSPEND_PHY_MASK)
> +      );
> +
> +    //
> +    // Clear HS PHY's suspend mask
> +    //
> +    UsbRegWrite (
> +      BaseAddr,
> +      DWC_XDCI_GUSB2PHYCFG_REG(0),
> +      (UsbRegRead(BaseAddr, DWC_XDCI_GUSB2PHYCFG_REG(0)) & ~DWC_XDCI_GUSB2PHYCFG_SUSPEND_PHY_MASK)
> +      );
> +  }
> +
> +  //
> +  // Notify upper layer if callback is registered
> +  //
> +  if (CoreHandle->EventCallbacks.DevResetDoneCallback) {
> +    CoreHandle->EventCallbacks.CbEventParams.ParentHandle = CoreHandle->ParentHandle;
> +    CoreHandle->EventCallbacks.CbEventParams.Speed = CoreHandle->ActualSpeed;
> +    CoreHandle->EventCallbacks.DevResetDoneCallback (&CoreHandle->EventCallbacks.CbEventParams);
> +  }
> +
> +  return status;
> +}
> +
> +
> +/**
> +  Internal function:
> +  This function is used to process device event
> +  @CoreHandle: xDCI controller handle address
> +  @IntLineEventBuffer: event Buffer pointing to device event
> +  @ProcessedEventSize: address of variable to save the size of
> +  the event that was Processed
> +
> +**/
> +STATIC
> +EFI_STATUS
> +DwcXdciProcessDeviceEvent (
> +  IN XDCI_CORE_HANDLE         *CoreHandle,
> +  IN DWC_XDCI_EVENT_BUFFER    *IntLineEventBuffer,
> +  IN UINT32                   *ProcessedEventSize
> +  )
> +{
> +  UINT32 event;
> +
> +  if (CoreHandle == NULL) {
> +    DEBUG ((DEBUG_INFO, "ERROR: DwcXdciProcessDeviceEvent: INVALID handle\n"));
> +    return EFI_DEVICE_ERROR;
> +  }
> +
> +  //
> +  // Extract device event
> +  //
> +  event = (IntLineEventBuffer->Event & DWC_XDCI_EVENT_BUFF_DEV_EVT_MASK);
> +  event >>= DWC_XDCI_EVENT_BUFF_DEV_EVT_BIT_POS;
> +
> +  //
> +  // Assume default event size. Change it in switch case if
> +  //  different
> +  //
> +  *ProcessedEventSize = DWC_XDCI_DEV_EVENT_DEFAULT_SIZE_IN_BYTES;
> +
> +  switch (event) {
> +    case DWC_XDCI_EVENT_BUFF_DEV_DISCONN_EVENT:
> +      DEBUG ((DEBUG_INFO, "Device DWC_XDCI_EVENT_BUFF_DEV_DISCONN_EVENT\n"));
> +      break;
> +
> +    case DWC_XDCI_EVENT_BUFF_DEV_USB_RESET_EVENT:
> +      DEBUG ((DEBUG_INFO, "Device DWC_XDCI_EVENT_BUFF_DEV_USB_RESET_EVENT\n"));
> +      DwcXdciProcessDeviceResetDet (CoreHandle);
> +      break;
> +
> +    case DWC_XDCI_EVENT_BUFF_DEV_CONN_DONE_EVENT:
> +      DEBUG ((DEBUG_INFO, "Device DWC_XDCI_EVENT_BUFF_DEV_CONN_DONE_EVENT\n"));
> +      DwcXdciProcessDeviceResetDone (CoreHandle);
> +      break;
> +
> +    case DWC_XDCI_EVENT_BUFF_DEV_STATE_CHANGE_EVENT:
> +      DEBUG ((DEBUG_INFO, "Device DWC_XDCI_EVENT_BUFF_DEV_STATE_CHANGE_EVENT\n"));
> +      DwcXdciProcessDeviceStateChangeEvent (CoreHandle, IntLineEventBuffer->Event);
> +      break;
> +
> +    case DWC_XDCI_EVENT_BUFF_DEV_WKUP_EVENT:
> +      DEBUG ((DEBUG_INFO, "Device DWC_XDCI_EVENT_BUFF_DEV_WKUP_EVENT\n"));
> +      break;
> +
> +    case DWC_XDCI_EVENT_BUFF_DEV_HBRNTN_REQ_EVENT:
> +      DEBUG ((DEBUG_INFO, "Device DWC_XDCI_EVENT_BUFF_DEV_HBRNTN_REQ_EVENT\n"));
> +      break;
> +
> +    case DWC_XDCI_EVENT_BUFF_DEV_SOF_EVENT:
> +      DEBUG ((DEBUG_INFO, "Device DWC_XDCI_EVENT_BUFF_DEV_SOF_EVENT\n"));
> +      break;
> +
> +    case DWC_XDCI_EVENT_BUFF_DEV_ERRATIC_ERR_EVENT:
> +      DEBUG ((DEBUG_INFO, "Device DWC_XDCI_EVENT_BUFF_DEV_ERRATIC_ERR_EVENT\n"));
> +      break;
> +
> +    case DWC_XDCI_EVENT_BUFF_DEV_CMD_CMPLT_EVENT:
> +      DEBUG ((DEBUG_INFO, "Device DWC_XDCI_EVENT_BUFF_DEV_CMD_CMPLT_EVENT\n"));
> +      break;
> +
> +    case DWC_XDCI_EVENT_BUFF_DEV_BUFF_OVFL_EVENT:
> +      DEBUG ((DEBUG_INFO, "Device DWC_XDCI_EVENT_BUFF_DEV_BUFF_OVFL_EVENT\n"));
> +      break;
> +
> +    case DWC_XDCI_EVENT_BUFF_DEV_TST_LMP_RX_EVENT:
> +      DEBUG ((DEBUG_INFO, "Device DWC_XDCI_EVENT_BUFF_DEV_TST_LMP_RX_EVENT\n"));
> +      *ProcessedEventSize = DWC_XDCI_DEV_EVENT_TST_LMP_SIZE_IN_BYTES;
> +      break;
> +
> +    default:
> +      DEBUG ((DEBUG_INFO, "DwcXdciProcessDeviceEvent: UNHANDLED device event: %x\n", event));
> +      break;
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +
> +/**
> +  Internal function:
> +  This function is used to process EP not ready for
> +  non-control endpoints
> +  @CoreHandle: xDCI controller handle address
> +  @EpNum: Physical endpoint number
> +
> +**/
> +STATIC
> +EFI_STATUS
> +DwcXdciProcessEpXferNotReady (
> +  IN XDCI_CORE_HANDLE    *CoreHandle,
> +  IN UINT32              EpNum
> +  )
> +{
> +  //
> +  // TODO: Not doing on-demand transfers
> +  // Revisit if required for later use
> +  //
> +  return EFI_SUCCESS;
> +}
> +
> +
> +/**
> +  Internal function:
> +  This function is used to process EP not ready for
> +  control endpoints
> +  @CoreHandle: xDCI controller handle address
> +  @EpNum: Physical endpoint number
> +  @dataStage: EP not ready when data stage token was received
> +  @statusStage: EP not ready when status stage token was received
> +
> +**/
> +STATIC
> +EFI_STATUS
> +DwcXdciProcessEp0XferNotReady (
> +  IN XDCI_CORE_HANDLE    *CoreHandle,
> +  IN UINT32              EpNum,
> +  IN UINT32              epEventStatus
> +  )
> +{
> +  USB_EP_STATE        epState = USB_EP_STATE_SETUP;
> +
> +  if (CoreHandle == NULL) {
> +    DEBUG ((DEBUG_INFO, "ERROR: DwcXdciProcessEp0XferNotReady: INVALID handle\n"));
> +    return EFI_DEVICE_ERROR;
> +  }
> +  //
> +  // Is it data stage or status stage
> +  //
> +  if (epEventStatus & DWC_XDCI_EVENT_BUFF_EP_CTRL_DATA_REQ_MASK) {
> +    epState = USB_EP_STATE_DATA;
> +  } else if (epEventStatus & DWC_XDCI_EVENT_BUFF_EP_CTRL_STATUS_REQ_MASK) {
> +    epState = USB_EP_STATE_STATUS;
> +  }
> +
> +  if ((EpNum == 0) && (epState == USB_EP_STATE_STATUS)) {
> +    if (epEventStatus & DWC_XDCI_EVENT_BUFF_EP_XFER_ACTIVE_MASK) {
> +      DEBUG ((DEBUG_INFO, "XFER_ACTIVE\n"));
> +    } else {
> +      DEBUG ((DEBUG_INFO, "XFER_NOT_ACTIVE\n"));
> +    }
> +    DwcXdciEp0ReceiveStatusPkt (CoreHandle);
> +  }
> +
> +  //
> +  // Notify upper layer if a callback is registered for
> +  // this event
> +  //
> +  if (CoreHandle->EventCallbacks.DevXferNrdyCallback) {
> +    CoreHandle->EventCallbacks.CbEventParams.ParentHandle = CoreHandle->ParentHandle;
> +    CoreHandle->EventCallbacks.CbEventParams.EpState = epState;
> +    CoreHandle->EventCallbacks.DevXferNrdyCallback (&CoreHandle->EventCallbacks.CbEventParams);
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +
> +/**
> +  Internal function:
> +  This function is used to process transfer phone done for EP0
> +  @CoreHandle: xDCI controller handle address
> +  @EpNum: Physical endpoint number (0 for OUT and 1 for IN)
> +
> +**/
> +STATIC
> +EFI_STATUS
> +DwcXdciProcessEp0XferPhaseDone (
> +  IN XDCI_CORE_HANDLE    *CoreHandle,
> +  IN UINT32              EpNum
> +  )
> +{
> +  DWC_XDCI_ENDPOINT    *epHandle;
> +  DWC_XDCI_TRB         *Trb;
> +  EFI_STATUS           status = EFI_SUCCESS;
> +  UINT32               TrbSts;
> +  UINT32               TrbCtrl;
> +  UINT32               TrbBufsize;
> +
> +  if (CoreHandle == NULL) {
> +    DEBUG ((DEBUG_INFO, "ERROR: DwcXdciProcessEp0XferPhaseDone: INVALID handle\n"));
> +    return EFI_DEVICE_ERROR;
> +  }
> +
> +  epHandle = &CoreHandle->EpHandles[EpNum];
> +  Trb = CoreHandle->Trbs + (EpNum * DWC_XDCI_TRB_NUM);
> +  DEBUG ((DEBUG_INFO, "(DwcXdciProcessEp0XferPhaseDone)EpNum is %d\n", EpNum));
> +
> +  if (Trb->TrbCtrl & DWC_XDCI_TRB_CTRL_HWO_MASK) {
> +    DEBUG ((DEBUG_INFO, "DwcXdciProcessEp0XferPhaseDone. HW owns TRB: %x!!!\n", (UINT32)(UINTN)Trb));
> +  }
> +
> +  epHandle->CurrentXferRscIdx = 0;
> +  epHandle->State = USB_EP_STATE_ENABLED;
> +  TrbCtrl = (Trb->TrbCtrl & DWC_XDCI_TRB_CTRL_TYPE_MASK) >> DWC_XDCI_TRB_CTRL_TYPE_BIT_POS;
> +  TrbSts = (Trb->LenXferParams & DWC_XDCI_TRB_STATUS_MASK) >> DWC_XDCI_TRB_STATUS_BIT_POS;
> +  TrbBufsize = Trb->LenXferParams & DWC_XDCI_TRB_BUFF_SIZE_MASK;
> +
> +  switch (TrbCtrl) {
> +    case DWC_XDCI_TRB_CTRL_TYPE_SETUP:
> +      DEBUG ((DEBUG_INFO, "SETUP\n"));
> +      if (CoreHandle->EventCallbacks.DevSetupPktReceivedCallback) {
> +        CoreHandle->EventCallbacks.CbEventParams.ParentHandle = CoreHandle->ParentHandle;
> +        CoreHandle->EventCallbacks.CbEventParams.Buffer = CoreHandle->AlignedSetupBuffer;
> +        status = CoreHandle->EventCallbacks.DevSetupPktReceivedCallback (&CoreHandle->EventCallbacks.CbEventParams);
> +      }
> +
> +      if (!(CoreHandle->AlignedSetupBuffer[0] & USB_SETUP_DATA_PHASE_DIRECTION_MASK)) {
> +        //
> +        // Keep a Buffer ready for setup phase
> +        //
> +        DwcXdciCoreStartEp0SetupXfer (CoreHandle);
> +      }
> +
> +      break;
> +
> +    case DWC_XDCI_TRB_CTRL_TYPE_STATUS2:
> +      DEBUG ((DEBUG_INFO, "STATUS2\n"));
> +      break;
> +
> +    case DWC_XDCI_TRB_CTRL_TYPE_STATUS3:
> +      DEBUG ((DEBUG_INFO, "STATUS3\n"));
> +      //
> +      // Notify upper layer of control transfer completion
> +      // if a callback function was registerd
> +      //
> +      if (CoreHandle->EventCallbacks.DevXferDoneCallback) {
> +        CoreHandle->EventCallbacks.CbEventParams.ParentHandle = CoreHandle->ParentHandle;
> +        CoreHandle->EventCallbacks.CbEventParams.EpNum = (EpNum >> 1);
> +        CoreHandle->EventCallbacks.CbEventParams.EpDir = (EpNum & 1);
> +        CoreHandle->EventCallbacks.CbEventParams.Buffer = (UINT8 *)(UINTN)(Trb->BuffPtrLow);
> +        CoreHandle->EventCallbacks.DevXferDoneCallback (&CoreHandle->EventCallbacks.CbEventParams);
> +      }
> +
> +      //
> +      // Status phase done. Queue next SETUP packet
> +      //
> +      status = DwcXdciCoreStartEp0SetupXfer(CoreHandle);
> +
> +      if (status) {
> +        DEBUG ((DEBUG_INFO, "DwcXdciProcessEp0XferPhaseDone: FAILED to queue SETUP\n"));
> +      }
> +      break;
> +
> +    case DWC_XDCI_TRB_CTRL_TYPE_DATA:
> +      DEBUG ((DEBUG_INFO, "DATA\n"));
> +      if (TrbSts == DWC_XDCI_TRB_STATUS_SETUP_PENDING || TrbBufsize != 0) {
> +        DEBUG ((DEBUG_INFO, "ERROR: Control transfert aborted by host: Setup pending\n"));
> +        DwcXdciCoreStartEp0SetupXfer (CoreHandle);
> +      }
> +
> +      if (CoreHandle->EventCallbacks.DevXferDoneCallback) {
> +        CoreHandle->EventCallbacks.CbEventParams.ParentHandle = CoreHandle->ParentHandle;
> +        CoreHandle->EventCallbacks.CbEventParams.EpNum = (EpNum >> 1);
> +        CoreHandle->EventCallbacks.CbEventParams.EpDir = (EpNum & 1);
> +        CoreHandle->EventCallbacks.CbEventParams.Buffer = (UINT8 *)(UINTN)(Trb->BuffPtrLow);
> +        CoreHandle->EventCallbacks.DevXferDoneCallback (&CoreHandle->EventCallbacks.CbEventParams);
> +      }
> +      break;
> +
> +    default:
> +      DEBUG ((DEBUG_INFO, "DwcXdciProcessEp0XferPhaseDone: UNHANDLED STATE in TRB\n"));
> +      break;
> +  }
> +
> +  return status;
> +}
> +
> +
> +/**
> +  Internal function:
> +  This function is used to process transfer done for
> +  non-control endpoints
> +  @CoreHandle: xDCI controller handle address
> +  @EpNum: Physical endpoint number
> +
> +**/
> +STATIC
> +EFI_STATUS
> +DwcXdciProcessEpXferDone (
> +  IN XDCI_CORE_HANDLE    *CoreHandle,
> +  IN UINT32              EpNum
> +  )
> +{
> +  DWC_XDCI_ENDPOINT    *epHandle;
> +  DWC_XDCI_TRB         *Trb;
> +  USB_XFER_REQUEST     *XferReq;
> +  UINT32               remainingLen;
> +
> +  if (CoreHandle == NULL) {
> +    DEBUG ((DEBUG_INFO, "ERROR: DwcXdciProcessEpXferDone: INVALID handle\n"));
> +    return EFI_DEVICE_ERROR;
> +  }
> +
> +  epHandle = &CoreHandle->EpHandles[EpNum];
> +  epHandle->CurrentXferRscIdx = 0;
> +  Trb = epHandle->Trb;
> +  XferReq = &epHandle->XferHandle;
> +
> +  //
> +  // if transfer done, set CheckFlag to FALSE for allow next transfer request.
> +  //
> +  epHandle->CheckFlag = FALSE;
> +
> +  if ((Trb == NULL) || (XferReq == NULL)) {
> +    DEBUG ((DEBUG_INFO, "ERROR: DwcXdciProcessEpXferDone: INVALID parameter\n"));
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  //
> +  // Compute the actual transfer length
> +  //
> +  XferReq->ActualXferLen = XferReq->XferLen;
> +  remainingLen = (Trb->LenXferParams & DWC_XDCI_TRB_BUFF_SIZE_MASK);
> +
> +  if (remainingLen > XferReq->XferLen) {
> +    //
> +    // Buffer overrun? This should never happen
> +    //
> +    DEBUG ((DEBUG_INFO, "ERROR: DwcXdciProcessEpXferDone: Possible Buffer overrun\n"));
> +  } else {
> +    XferReq->ActualXferLen -= remainingLen;
> +  }
> +
> +  //
> +  // Notify upper layer of request-specific transfer completion
> +  // if there is a callback specifically for this request
> +  //
> +  if (XferReq->XferDone) {
> +    XferReq->XferDone(CoreHandle->ParentHandle, XferReq);
> +  }
> +
> +  //
> +  // Notify upper layer if a callback was registered
> +  //
> +  if (CoreHandle->EventCallbacks.DevXferDoneCallback) {
> +    CoreHandle->EventCallbacks.CbEventParams.ParentHandle = CoreHandle->ParentHandle;
> +    CoreHandle->EventCallbacks.CbEventParams.EpNum = (EpNum >> 1);
> +    CoreHandle->EventCallbacks.CbEventParams.EpDir = (EpNum & 1);
> +    CoreHandle->EventCallbacks.CbEventParams.EpType = epHandle->EpInfo.EpType;
> +    CoreHandle->EventCallbacks.CbEventParams.Buffer = (UINT8 *)(UINTN)(epHandle->Trb->BuffPtrLow);
> +    CoreHandle->EventCallbacks.DevXferDoneCallback (&CoreHandle->EventCallbacks.CbEventParams);
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +
> +/**
> +  Internal function:
> +  This function is used to process endpoint events
> +  @CoreHandle: xDCI controller handle address
> +  @IntLineEventBuffer:  address of Buffer containing event
> +  to process
> +  @ProcessedEventSize: address to save the size of event
> +  Processed
> +
> +**/
> +STATIC
> +EFI_STATUS
> +DwcXdciProcessEpEvent (
> +  IN XDCI_CORE_HANDLE         *CoreHandle,
> +  IN DWC_XDCI_EVENT_BUFFER    *IntLineEventBuffer,
> +  IN UINT32                   *ProcessedEventSize
> +  )
> +{
> +  UINT32          EpNum;
> +  UINT32          epEvent;
> +  UINT32          epEventStatus;
> +
> +  if (CoreHandle == NULL) {
> +    DEBUG ((DEBUG_INFO, "ERROR: DwcXdciProcessEpEvent: INVALID handle\n"));
> +    return EFI_DEVICE_ERROR;
> +  }
> +
> +  epEvent = IntLineEventBuffer->Event;
> +
> +  *ProcessedEventSize = DWC_XDCI_DEV_EVENT_DEFAULT_SIZE_IN_BYTES;
> +
> +  //
> +  // Get EP num
> +  //
> +  EpNum = ((epEvent & DWC_XDCI_EVENT_BUFF_EP_NUM_MASK) >> DWC_XDCI_EVENT_BUFF_EP_NUM_BIT_POS);
> +  epEventStatus = (epEvent & DWC_XDCI_EVENT_BUFF_EP_EVENT_STATUS_MASK);
> +
> +  //
> +  // Interpret event and handle transfer completion here
> +  //
> +  epEvent = ((epEvent & DWC_XDCI_EVENT_BUFF_EP_EVENT_MASK) >> DWC_XDCI_EVENT_BUFF_EP_EVENT_BIT_POS);
> +
> +  switch (epEvent) {
> +    case DWC_XDCI_EVENT_BUFF_EP_XFER_CMPLT:
> +      DEBUG ((DEBUG_INFO, "XFER_CMPLT ep %d\n", EpNum));
> +      if (EpNum > 1) {
> +        DwcXdciProcessEpXferDone (CoreHandle, EpNum);
> +      } else {
> +        DwcXdciProcessEp0XferPhaseDone (CoreHandle, EpNum);
> +      }
> +      break;
> +
> +    case DWC_XDCI_EVENT_BUFF_EP_XFER_IN_PROGRESS:
> +      DEBUG ((DEBUG_INFO, "IN_PROGRESS\n"));
> +      break;
> +
> +    case DWC_XDCI_EVENT_BUFF_EP_XFER_NOT_READY:
> +      DEBUG ((DEBUG_INFO, "NOT_READY ep %d\n", EpNum));
> +      if (EpNum > 1) {
> +        //
> +        // Endpoint transfer is not ready
> +        //
> +        DwcXdciProcessEpXferNotReady (CoreHandle, EpNum);
> +      } else {
> +        DwcXdciProcessEp0XferNotReady (CoreHandle, EpNum, epEventStatus);
> +      }
> +      break;
> +
> +    default:
> +      DEBUG ((DEBUG_INFO, "DwcXdciProcessEpEvent: UNKNOWN EP event\n"));
> +      break;
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +
> +/**
> +  Internal function:
> +  This function is used to process events on single interrupt line
> +  @CoreHandle: xDCI controller handle address
> +  @eventCount:  event bytes to process
> +  @ProcessedEventCount: address to save the size
> +  (in bytes) of event Processed
> +  Processed
> +
> +**/
> +STATIC
> +EFI_STATUS
> +DwcXdciProcessInterruptLineEvents (
> +  IN XDCI_CORE_HANDLE    *CoreHandle,
> +  IN UINT32              eventCount,
> +  IN UINT32              *ProcessedEventCount
> +  )
> +{
> +  UINT32    ProcessedEventSize = 0;
> +  UINT32    currentEventAddr;
> +
> +  if (CoreHandle == NULL) {
> +    DEBUG ((DEBUG_INFO, "ERROR: DwcXdciProcessInterruptLineEvents: INVALID handle\n"));
> +    return EFI_DEVICE_ERROR;
> +  }
> +
> +  if (CoreHandle->CurrentEventBuffer == NULL) {
> +    DEBUG ((DEBUG_INFO, "ERROR: DwcXdciProcessInterruptLineEvents: INVALID event Buffer\n"));
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  currentEventAddr = (UINT32)(UINTN)(CoreHandle->CurrentEventBuffer);
> +
> +  //
> +  // Process eventCount/eventSize number of events
> +  // in this run
> +  //
> +  while (eventCount) {
> +    if (CoreHandle->CurrentEventBuffer->Event & DWC_XDCI_EVENT_DEV_MASK) {
> +      DwcXdciProcessDeviceEvent (
> +        CoreHandle,
> +        CoreHandle->CurrentEventBuffer,
> +        &ProcessedEventSize
> +        );
> +    } else {
> +      DwcXdciProcessEpEvent (
> +        CoreHandle,
> +        CoreHandle->CurrentEventBuffer,
> +        &ProcessedEventSize);
> +    }
> +
> +    eventCount -= ProcessedEventSize;
> +    *ProcessedEventCount += ProcessedEventSize;
> +    if ((currentEventAddr + ProcessedEventSize) >=
> +        ((UINT32)(UINTN)(CoreHandle->AlignedEventBuffers) + (sizeof(DWC_XDCI_EVENT_BUFFER) * DWC_XDCI_MAX_EVENTS_PER_BUFFER))
> +       ) {
> +      currentEventAddr = (UINT32)(UINTN)(CoreHandle->AlignedEventBuffers);
> +      DEBUG ((DEBUG_INFO, "DwcXdciProcessInterruptLineEvents: Event Buffer bound reached\n"));
> +    } else {
> +      currentEventAddr += ProcessedEventSize;
> +    }
> +
> +    CoreHandle->CurrentEventBuffer = (DWC_XDCI_EVENT_BUFFER *)(UINTN)currentEventAddr;
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +//
> +// DWC XDCI APIs
> +//
> +
> +/**
> +  Interface:
> +
> +  This function is used to initialize the xDCI core
> +  @configParams: Parameters from app to configure the core
> +  @deviceCorePtr:  HW-independent APIs handle for device core
> +  @CoreHandle: xDCI controller handle retured
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +DwcXdciCoreInit (
> +  IN USB_DEV_CONFIG_PARAMS    *ConfigParams,
> +  IN VOID                     *deviceCorePtr,
> +  IN VOID                     **CoreHandle
> +  )
> +{
> +  EFI_STATUS                      status = EFI_DEVICE_ERROR;
> +  UINT32                          BaseAddr;
> +  XDCI_CORE_HANDLE                *LocalCoreHandle;
> +  DWC_XDCI_ENDPOINT_CMD_PARAMS    EpCmdParams;
> +  UINT32                          MaxDelayIter = DWC_XDCI_MAX_DELAY_ITERATIONS;
> +  UINT8                           i;
> +
> +  LocalCoreHandle = (XDCI_CORE_HANDLE *)AllocateZeroPool (sizeof(XDCI_CORE_HANDLE));
> +
> +  if (CoreHandle == NULL) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  if (LocalCoreHandle == NULL) {
> +    DEBUG ((DEBUG_INFO, "DwcXdciCoreInit: Failed to allocate handle for xDCI\n"));
> +    return EFI_OUT_OF_RESOURCES;
> +  }
> +
> +  ZeroMem (LocalCoreHandle, sizeof(XDCI_CORE_HANDLE));
> +
> +  LocalCoreHandle->ParentHandle = deviceCorePtr;
> +
> +  *CoreHandle = (VOID *)LocalCoreHandle;
> +
> +  LocalCoreHandle->Id = ConfigParams->ControllerId;
> +  LocalCoreHandle->BaseAddress = BaseAddr = ConfigParams->BaseAddress;
> +  LocalCoreHandle->Flags = ConfigParams->Flags;
> +  LocalCoreHandle->DesiredSpeed = LocalCoreHandle->ActualSpeed = ConfigParams->Speed;
> +  LocalCoreHandle->Role = ConfigParams->Role;
> +
> +  DEBUG ((DEBUG_INFO, "Resetting the USB core\n"));
> +  UsbRegWrite (
> +    BaseAddr,
> +    DWC_XDCI_DCTL_REG,
> +    UsbRegRead (BaseAddr, DWC_XDCI_DCTL_REG) | DWC_XDCI_DCTL_CSFTRST_MASK
> +    );
> +  //
> +  // Wait until core soft reset completes
> +  //
> +  do {
> +    if (!(UsbRegRead (BaseAddr, DWC_XDCI_DCTL_REG) & DWC_XDCI_DCTL_CSFTRST_MASK)) {
> +      break;
> +    } else {
> +      gBS->Stall (DWC_XDCI_MAX_DELAY_ITERATIONS);
> +    }
> +  } while (--MaxDelayIter);
> +
> +  if (!MaxDelayIter) {
> +    DEBUG ((DEBUG_INFO, "Failed to reset device controller\n"));
> +    return EFI_DEVICE_ERROR;
> +  }
> +
> +  DEBUG ((DEBUG_INFO, "USB core has been reset\n"));
> +
> +  //
> +  // All FIFOs are flushed at this point
> +  //
> +  //
> +  // Ensure we have EP0 Rx/Tx handles initialized
> +  //
> +  LocalCoreHandle->EpHandles[0].EpInfo.EpNum = 0;
> +  LocalCoreHandle->EpHandles[0].EpInfo.EpDir = UsbEpDirOut;
> +  LocalCoreHandle->EpHandles[0].EpInfo.EpType = USB_ENDPOINT_CONTROL;
> +  LocalCoreHandle->EpHandles[0].EpInfo.MaxPktSize = DWC_XDCI_SS_CTRL_EP_MPS;
> +  //
> +  // 0 means burst size of 1
> +  //
> +  LocalCoreHandle->EpHandles[0].EpInfo.BurstSize = 0;
> +
> +  LocalCoreHandle->EpHandles[1].EpInfo.EpNum = 0;
> +  LocalCoreHandle->EpHandles[1].EpInfo.EpDir = UsbEpDirIn;
> +  LocalCoreHandle->EpHandles[1].EpInfo.EpType = USB_ENDPOINT_CONTROL;
> +  LocalCoreHandle->EpHandles[1].EpInfo.MaxPktSize = DWC_XDCI_SS_CTRL_EP_MPS;
> +  //
> +  // 0 means burst size of 1
> +  //
> +  LocalCoreHandle->EpHandles[1].EpInfo.BurstSize = 0;
> +
> +  LocalCoreHandle->DevState = UsbDevStateDefault;
> +
> +  //
> +  // Clear KeepConnect bit so we can allow disconnect and
> +  // re-connect. Stay in RX_DETECT state
> +  //
> +  UsbRegWrite (
> +    BaseAddr,
> +    DWC_XDCI_DCTL_REG,
> +    UsbRegRead (BaseAddr, DWC_XDCI_DCTL_REG) &
> +    (~DWC_XDCI_DCTL_KEEP_CONNECT_MASK) &
> +    ((~DWC_XDCI_DCTL_STATE_CHANGE_REQ_MASK) | (DWC_XDCI_DCTL_STATE_CHANGE_REQ_RX_DETECT << DWC_XDCI_DCTL_STATE_CHANGE_REQ_BIT_POS))
> +    );
> +
> +  DEBUG ((DEBUG_INFO, "Device controller Synopsys ID: %x\n", UsbRegRead (BaseAddr, DWC_XDCI_GSNPSID_REG)));
> +  DEBUG ((DEBUG_INFO, "Default value of xDCI GSBUSCFG0 and GSBUSCFG1: %x, %x\n",
> +          UsbRegRead (BaseAddr, DWC_XDCI_GSBUSCFG0_REG),
> +          UsbRegRead (BaseAddr, DWC_XDCI_GSBUSCFG1_REG)));
> +
> +  DEBUG ((DEBUG_INFO, "Default value of xDCI GTXTHRCFG and GRXTHRCFG: %x, %x\n",
> +          UsbRegRead (BaseAddr, DWC_XDCI_GTXTHRCFG_REG),
> +          UsbRegRead (BaseAddr, DWC_XDCI_GRXTHRCFG_REG)));
> +
> +  //
> +  // Clear ULPI auto-resume bit
> +  //
> +  UsbRegWrite (
> +    BaseAddr,
> +    DWC_XDCI_GUSB2PHYCFG_REG (0),
> +    (UsbRegRead (BaseAddr, DWC_XDCI_GUSB2PHYCFG_REG (0)) & ~DWC_XDCI_GUSB2PHYCFG_ULPI_AUTO_RESUME_MASK)
> +    );
> +
> +  DEBUG ((DEBUG_INFO, "Default value of xDCI GUSB2PHYCFG and GUSB3PIPECTL: %x, %x\n",
> +          UsbRegRead (BaseAddr, DWC_XDCI_GUSB2PHYCFG_REG (0)),
> +          UsbRegRead (BaseAddr, DWC_XDCI_GUSB3PIPECTL_REG (0))));
> +  //
> +  // Only one RxFIFO
> +  //
> +  DEBUG ((DEBUG_INFO, "Default value of DWC_XDCI_GRXFIFOSIZ: %x\n",
> +          UsbRegRead (BaseAddr, DWC_XDCI_GRXFIFOSIZ_REG (0))));
> +
> +  for (i = 0; i < DWC_XDCI_MAX_ENDPOINTS; i++) {
> +    DEBUG ((DEBUG_INFO, "Default value of xDCI DWC_XDCI_GTXFIFOSIZ %d: %x\n",
> +            i, UsbRegRead (BaseAddr, DWC_XDCI_GTXFIFOSIZ_REG (i))));
> +  }
> +
> +  //
> +  // TODO: Need to check if TxFIFO should start where RxFIFO ends
> +  // or default is correct i.e. TxFIFO starts at 0 just like RxFIFO
> +  //
> +
> +  //
> +  // Allocate and Initialize Event Buffers
> +  //
> +  LocalCoreHandle->MaxDevIntLines = ((UsbRegRead (BaseAddr, DWC_XDCI_GHWPARAMS1_REG) &
> +                                           DWC_XDCI_GHWPARAMS1_NUM_INT_MASK) >>
> +                                           DWC_XDCI_GHWPARAMS1_NUM_INT_BIT_POS);
> +
> +  DEBUG ((DEBUG_INFO, "Max dev int lines: %d\n", LocalCoreHandle->MaxDevIntLines));
> +  //
> +  // One event Buffer per interrupt line.
> +  //  Need to align it to size of event Buffer
> +  //  Buffer needs to be big enough. Otherwise the core
> +  //  won't operate
> +  //
> +  LocalCoreHandle->AlignedEventBuffers = (DWC_XDCI_EVENT_BUFFER *)
> +                                             ((UINT32)(UINTN)(LocalCoreHandle->EventBuffers) +
> +                                             ((sizeof (DWC_XDCI_EVENT_BUFFER) * DWC_XDCI_MAX_EVENTS_PER_BUFFER) -
> +                                             (((UINT32)(UINTN)(LocalCoreHandle->EventBuffers)) %
> +                                             (sizeof (DWC_XDCI_EVENT_BUFFER) * DWC_XDCI_MAX_EVENTS_PER_BUFFER))));
> +
> +  for (i = 0; i < LocalCoreHandle->MaxDevIntLines; i++) {
> +    UsbRegWrite (
> +      BaseAddr,
> +      DWC_XDCI_GEVNTADR_REG (i),
> +      (UINT32)(UINTN)(LocalCoreHandle->AlignedEventBuffers + i * sizeof(DWC_XDCI_EVENT_BUFFER) * DWC_XDCI_MAX_EVENTS_PER_BUFFER)
> +      );
> +
> +    //
> +    // Clear High 32bit address register, GEVNTADR register is 64-bit register
> +    // default is 0xffffffffffffffff
> +    //
> +    UsbRegWrite (BaseAddr, DWC_XDCI_GEVNTADR_REG (i) + 4, 0x00000000);
> +
> +    LocalCoreHandle->CurrentEventBuffer = LocalCoreHandle->AlignedEventBuffers;
> +    //
> +    // Write size and clear the mask
> +    //
> +    UsbRegWrite (
> +      BaseAddr,
> +      DWC_XDCI_EVNTSIZ_REG (i),
> +      sizeof (DWC_XDCI_EVENT_BUFFER) * DWC_XDCI_MAX_EVENTS_PER_BUFFER
> +      );
> +
> +    //
> +    // Write 0 to the event count register as the last step
> +    //
> +    //  for event configuration
> +    //
> +    UsbRegWrite (BaseAddr, DWC_XDCI_EVNTCOUNT_REG (i), 0);
> +
> +    DEBUG ((DEBUG_INFO, "Value of xDCI Event Buffer %d: %x, Size: %x, Count: %x\n",
> +                        i,
> +                        UsbRegRead (BaseAddr, DWC_XDCI_GEVNTADR_REG (i)),
> +                        UsbRegRead (BaseAddr, DWC_XDCI_EVNTSIZ_REG (i)),
> +                        UsbRegRead (BaseAddr, DWC_XDCI_EVNTCOUNT_REG (i))));
> +  }
> +
> +    //
> +    // Program Global Control Register to disable scaledown,
> +    // disable clock gating
> +    //
> +    UsbRegWrite (
> +      BaseAddr,
> +      DWC_XDCI_GCTL_REG,
> +      ((UsbRegRead(BaseAddr, DWC_XDCI_GCTL_REG) &
> +                    ~(DWC_XDCI_GCTL_SCALE_DOWN_MODE_MASK + DWC_XDCI_GCTL_RAMCLKSEL_MASK + DWC_XDCI_GCTL_DISABLE_SCRAMB_MASK)) |
> +                    DWC_XDCI_GCTL_DISABLE_CLK_GATING_MASK |
> +                    (DWC_XDCI_GCTL_PRT_CAP_DEVICE << DWC_XDCI_GCTL_PRT_CAP_DIR_BIT_POS)));
> +
> +    DEBUG ((DEBUG_INFO, "Setup value of xDCI DWC_XDCI_GCTL_REG: 0x%x\n", UsbRegRead (BaseAddr, DWC_XDCI_GCTL_REG)));
> +
> +  //
> +  // TODO: Program desired Speed and set LPM capable
> +  // We will do this when SuperSpeed works. For now,
> +  // force into High-Speed mode to aVOID anyone trying this
> +  // on Super Speed port
> +  //
> +#ifdef SUPPORT_SUPER_SPEED
> +  UsbRegWrite (
> +    BaseAddr,
> +    DWC_XDCI_DCFG_REG,
> +    (UsbRegRead (BaseAddr, DWC_XDCI_DCFG_REG) & ~DWC_XDCI_DCFG_DESIRED_DEV_SPEED_MASK) | LocalCoreHandle->DesiredSpeed
> +    );
> +#else
> +  UsbRegWrite (
> +    BaseAddr,
> +    DWC_XDCI_DCFG_REG,
> +    (UsbRegRead (BaseAddr, DWC_XDCI_DCFG_REG) & ~DWC_XDCI_DCFG_DESIRED_DEV_SPEED_MASK) | DWC_XDCI_DCFG_DESIRED_HS_SPEED
> +    );
> +#endif
> +
> +  DEBUG ((DEBUG_INFO, "Setup value of xDCI DWC_XDCI_DCFG_REG: 0x%x\n", UsbRegRead (BaseAddr, DWC_XDCI_DCFG_REG)));
> +  DEBUG ((DEBUG_INFO, "Setup value of xDCI DWC_XDCI_DSTS_REG: 0x%x\n", UsbRegRead (BaseAddr, DWC_XDCI_DSTS_REG)));
> +
> +  //
> +  // Enable Device Interrupt Events
> +  //
> +  UsbRegWrite (
> +    BaseAddr,
> +    DWC_XDCI_DEVTEN_REG,
> +    DWC_XDCI_DEVTEN_DEVICE_INTS
> +    );
> +  //
> +  // Program the desired role
> +  //
> +  UsbRegWrite (
> +    BaseAddr,
> +    DWC_XDCI_GCTL_REG,
> +    (UsbRegRead (BaseAddr, DWC_XDCI_GCTL_REG) & ~DWC_XDCI_GCTL_PRT_CAP_DIR_MASK) | (LocalCoreHandle->Role << DWC_XDCI_GCTL_PRT_CAP_DIR_BIT_POS)
> +    );
> +  //
> +  // Clear USB2 suspend for start new config command
> +  //
> +  UsbRegWrite (
> +    BaseAddr,
> +    DWC_XDCI_GUSB2PHYCFG_REG (0),
> +    (UsbRegRead (BaseAddr, DWC_XDCI_GUSB2PHYCFG_REG(0)) & ~DWC_XDCI_GUSB2PHYCFG_SUSPEND_PHY_MASK)
> +    );
> +
> +  //
> +  // Clear USB3 suspend for start new config command
> +  //
> +  UsbRegWrite (
> +    BaseAddr,
> +    DWC_XDCI_GUSB3PIPECTL_REG (0),
> +    (UsbRegRead (BaseAddr, DWC_XDCI_GUSB3PIPECTL_REG(0)) & ~DWC_XDCI_GUSB3PIPECTL_SUSPEND_PHY_MASK)
> +    );
> +
> +  //
> +  // Issue DEPSTARTCFG command for EP0
> +  //
> +  status = DwcXdciCoreInitEpCmdParams (
> +             LocalCoreHandle,
> +             &LocalCoreHandle->EpHandles[0].EpInfo,
> +             DWC_XDCI_PARAM0_SET_EP_CFG_ACTN_NONE,
> +             EPCMD_START_NEW_CONFIG,
> +             &EpCmdParams
> +             );
> +
> +  if (status) {
> +    DEBUG ((DEBUG_INFO, "DwcXdciCoreInit: Failed to init params for START_NEW_CONFIG EP command on xDCI\n"));
> +    return status;
> +  }
> +
> +  //
> +  // Issue the command
> +  //
> +  status = DwcXdciCoreIssueEpCmd (
> +             LocalCoreHandle,
> +             0,
> +             EPCMD_START_NEW_CONFIG,
> +             &EpCmdParams
> +             );
> +
> +  if (status) {
> +    DEBUG ((DEBUG_INFO, "DwcXdciCoreInit: Failed to issue START_NEW_CONFIG EP command on xDCI\n"));
> +    return status;
> +  }
> +
> +  //
> +  // Issue DEPCFG command for EP0
> +  //
> +  status = DwcXdciCoreInitEpCmdParams (
> +             LocalCoreHandle,
> +             &LocalCoreHandle->EpHandles[0].EpInfo,
> +             DWC_XDCI_PARAM0_SET_EP_CFG_ACTN_INIT_STATE,
> +             EPCMD_SET_EP_CONFIG,
> +             &EpCmdParams
> +             );
> +
> +  if (status) {
> +    DEBUG ((DEBUG_INFO, "DwcXdciCoreInit: Failed to init params for SET_EP_CONFIG command on xDCI for EP0\n"));
> +    return status;
> +  }
> +
> +  //
> +  // Issue the command
> +  //
> +  status = DwcXdciCoreIssueEpCmd (
> +             LocalCoreHandle,
> +             0,
> +             EPCMD_SET_EP_CONFIG,
> +             &EpCmdParams);
> +
> +  if (status) {
> +    DEBUG ((DEBUG_INFO, "DwcXdciCoreInit: Failed to issue SET_EP_CONFIG command on xDCI for EP0\n"));
> +    return status;
> +  }
> +
> +  //
> +  // Issue DEPCFG command for EP1
> +  //
> +  status = DwcXdciCoreInitEpCmdParams (
> +             LocalCoreHandle,
> +             &LocalCoreHandle->EpHandles[1].EpInfo,
> +             DWC_XDCI_PARAM0_SET_EP_CFG_ACTN_INIT_STATE,
> +             EPCMD_SET_EP_CONFIG,
> +             &EpCmdParams
> +             );
> +
> +  if (status) {
> +    DEBUG ((DEBUG_INFO, "DwcXdciCoreInit: Failed to init params for SET_EP_CONFIG command on xDCI for EP1\n"));
> +    return status;
> +  }
> +
> +  //
> +  // Issue the command
> +  //
> +  status = DwcXdciCoreIssueEpCmd (
> +             LocalCoreHandle,
> +             1,
> +             EPCMD_SET_EP_CONFIG,
> +             &EpCmdParams
> +             );
> +
> +  if (status) {
> +    DEBUG ((DEBUG_INFO, "DwcXdciCoreInit: Failed to issue SET_EP_CONFIG command on xDCI for EP1\n"));
> +    return status;
> +  }
> +
> +  //
> +  // Issue DEPXFERCFG command for EP0
> +  //
> +  status = DwcXdciCoreInitEpCmdParams (
> +             LocalCoreHandle,
> +             &LocalCoreHandle->EpHandles[0].EpInfo,
> +             DWC_XDCI_PARAM0_SET_EP_CFG_ACTN_NONE,
> +             EPCMD_SET_EP_XFER_RES_CONFIG,
> +             &EpCmdParams
> +             );
> +
> +  if (status) {
> +    DEBUG ((DEBUG_INFO, "DwcXdciCoreInit: Failed to init params for EPCMD_SET_EP_XFER_RES_CONFIG command on xDCI for EP0\n"));
> +    return status;
> +  }
> +
> +  //
> +  // Issue the command
> +  //
> +  status = DwcXdciCoreIssueEpCmd (
> +             LocalCoreHandle,
> +             0,
> +             EPCMD_SET_EP_XFER_RES_CONFIG,
> +             &EpCmdParams
> +             );
> +
> +  if (status) {
> +    DEBUG ((DEBUG_INFO, "DwcXdciCoreInit: Failed to issue EPCMD_SET_EP_XFER_RES_CONFIG command on xDCI for EP0\n"));
> +    return status;
> +  }
> +
> +  //
> +  // Issue DEPXFERCFG command for EP1
> +  //
> +  status = DwcXdciCoreInitEpCmdParams (
> +             LocalCoreHandle,
> +             &LocalCoreHandle->EpHandles[1].EpInfo,
> +             DWC_XDCI_PARAM0_SET_EP_CFG_ACTN_NONE,
> +             EPCMD_SET_EP_XFER_RES_CONFIG,
> +             &EpCmdParams
> +             );
> +
> +  if (status) {
> +    DEBUG ((DEBUG_INFO, "DwcXdciCoreInit: Failed to init params for EPCMD_SET_EP_XFER_RES_CONFIG command on xDCI for EP1\n"));
> +    return status;
> +  }
> +
> +  //
> +  // Issue the command
> +  //
> +  status = DwcXdciCoreIssueEpCmd (
> +             LocalCoreHandle,
> +             1,
> +             EPCMD_SET_EP_XFER_RES_CONFIG,
> +             &EpCmdParams
> +             );
> +
> +  if (status) {
> +    DEBUG ((DEBUG_INFO, "DwcXdciCoreInit: Failed to issue EPCMD_SET_EP_XFER_RES_CONFIG command on xDCI for EP1\n"));
> +    return status;
> +  }
> +
> +  //
> +  // Prepare a Buffer for SETUP packet
> +  //
> +  LocalCoreHandle->Trbs = (DWC_XDCI_TRB *)((UINTN)
> +                            LocalCoreHandle->UnalignedTrbs +
> +                            (UINTN)(DWC_XDCI_TRB_BYTE_ALIGNMENT -
> +                            ((UINT32)(UINTN)LocalCoreHandle->UnalignedTrbs %
> +                            DWC_XDCI_TRB_BYTE_ALIGNMENT)));
> +
> +  DEBUG ((DEBUG_INFO, "(DwcXdciCoreInit)@@@@@@@@@ unalignedTrbs address is 0x%x\n", LocalCoreHandle->UnalignedTrbs));
> +  DEBUG ((DEBUG_INFO, "(DwcXdciCoreInit)@@@@@@@@@ TRB address is 0x%x\n", LocalCoreHandle->Trbs));
> +  //
> +  // Allocate Setup Buffer that is 8-byte aligned
> +  //
> +  LocalCoreHandle->AlignedSetupBuffer = LocalCoreHandle->DefaultSetupBuffer +
> +                                            (DWC_XDCI_SETUP_BUFF_SIZE -
> +                                            ((UINT32)(UINTN)(LocalCoreHandle->DefaultSetupBuffer) % DWC_XDCI_SETUP_BUFF_SIZE));
> +
> +  //
> +  // Aligned Buffer for status phase
> +  //
> +  LocalCoreHandle->AlignedMiscBuffer = LocalCoreHandle->MiscBuffer +
> +                                           (DWC_XDCI_SETUP_BUFF_SIZE -
> +                                           ((UINT32)(UINTN)(LocalCoreHandle->AlignedMiscBuffer) % DWC_XDCI_SETUP_BUFF_SIZE));
> +
> +
> +  //
> +  // Enable Physical Endpoints 0
> +  //
> +  UsbRegWrite (
> +    BaseAddr,
> +    DWC_XDCI_EP_DALEPENA_REG,
> +    UsbRegRead (BaseAddr, DWC_XDCI_EP_DALEPENA_REG) | (1 << 0)
> +    );
> +  //
> +  // Enable Physical Endpoints 1
> +  //
> +  UsbRegWrite (
> +    BaseAddr,
> +    DWC_XDCI_EP_DALEPENA_REG,
> +    UsbRegRead (BaseAddr, DWC_XDCI_EP_DALEPENA_REG) | (1 << 1)
> +    );
> +
> +  DEBUG ((DEBUG_INFO, "Default value of xDCI DWC_XDCI_DEVTEN_REG: 0x%x\n", UsbRegRead (BaseAddr, DWC_XDCI_DEVTEN_REG)));
> +  return status;
> +}
> +
> +
> +/**
> +  Interface:
> +  This function is used to de-initialize the xDCI core
> +  @CoreHandle: xDCI controller handle
> +  @flags: Special flags for de-initializing the core in
> +  particular way
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +DwcXdciCoreDeinit (
> +  IN VOID      *CoreHandle,
> +  IN UINT32    flags
> +  )
> +{
> +  FreePool (CoreHandle);
> +  return EFI_SUCCESS;
> +}
> +
> +
> +/**
> +  Interface:
> +  This function is used to register event callback function
> +  @CoreHandle: xDCI controller handle
> +  @event: Event for which callback is to be registered
> +  @callbackFn: Callback function to invoke after event occurs
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +DwcXdciCoreRegisterCallback (
> +  IN VOID                      *CoreHandle,
> +  IN USB_DEVICE_EVENT_ID       Event,
> +  IN USB_DEVICE_CALLBACK_FUNC  CallbackFunc
> +  )
> +{
> +  XDCI_CORE_HANDLE  *LocalCoreHandle = (XDCI_CORE_HANDLE *)CoreHandle;
> +
> +  if (LocalCoreHandle == NULL) {
> +    DEBUG ((DEBUG_INFO, "DwcXdciCoreRegisterCallback: INVALID handle\n"));
> +    return EFI_DEVICE_ERROR;
> +  }
> +
> +  DEBUG ((DEBUG_INFO, "DwcXdciCoreRegisterCallback: event is %d\n", Event));
> +  switch (Event) {
> +    case USB_DEVICE_DISCONNECT_EVENT:
> +      LocalCoreHandle->EventCallbacks.DevDisconnectCallback = CallbackFunc;
> +      break;
> +
> +    case USB_DEVICE_RESET_EVENT:
> +      LocalCoreHandle->EventCallbacks.DevBusResetCallback = CallbackFunc;
> +      break;
> +
> +    case USB_DEVICE_CONNECTION_DONE:
> +      LocalCoreHandle->EventCallbacks.DevResetDoneCallback = CallbackFunc;
> +      break;
> +
> +    case USB_DEVICE_STATE_CHANGE_EVENT:
> +      LocalCoreHandle->EventCallbacks.DevLinkStateCallback = CallbackFunc;
> +      break;
> +
> +    case USB_DEVICE_WAKEUP_EVENT:
> +      LocalCoreHandle->EventCallbacks.DevWakeupCallback = CallbackFunc;
> +      break;
> +
> +    case USB_DEVICE_HIBERNATION_REQ_EVENT:
> +      LocalCoreHandle->EventCallbacks.DevHibernationCallback = CallbackFunc;
> +      break;
> +
> +    case USB_DEVICE_SOF_EVENT:
> +      LocalCoreHandle->EventCallbacks.DevSofCallback = CallbackFunc;
> +      break;
> +
> +    case USB_DEVICE_ERRATIC_ERR_EVENT:
> +      LocalCoreHandle->EventCallbacks.DevErraticErrCallback = CallbackFunc;
> +      break;
> +
> +    case USB_DEVICE_CMD_CMPLT_EVENT:
> +      LocalCoreHandle->EventCallbacks.DevCmdCmpltCallback = CallbackFunc;
> +      break;
> +
> +    case USB_DEVICE_BUFF_OVERFLOW_EVENT:
> +      LocalCoreHandle->EventCallbacks.DevBuffOvflwCallback = CallbackFunc;
> +      break;
> +
> +    case USB_DEVICE_TEST_LMP_RX_EVENT:
> +      LocalCoreHandle->EventCallbacks.DevTestLmpRxCallback = CallbackFunc;
> +      break;
> +
> +    case USB_DEVICE_SETUP_PKT_RECEIVED:
> +      LocalCoreHandle->EventCallbacks.DevSetupPktReceivedCallback = CallbackFunc;
> +      break;
> +
> +    case USB_DEVICE_XFER_NRDY:
> +      LocalCoreHandle->EventCallbacks.DevXferNrdyCallback = CallbackFunc;
> +      break;
> +
> +    case USB_DEVICE_XFER_DONE:
> +      LocalCoreHandle->EventCallbacks.DevXferDoneCallback = CallbackFunc;
> +      break;
> +
> +    default:
> +      break;
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +
> +/**
> +  Interface:
> +  This function is used to unregister event callback function
> +  @CoreHandle: xDCI controller handle
> +  @event: Event for which callback function is to be unregistered
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +DwcXdciCoreUnregisterCallback (
> +  IN VOID                   *CoreHandle,
> +  IN USB_DEVICE_EVENT_ID    event
> +  )
> +{
> +  XDCI_CORE_HANDLE  *LocalCoreHandle = (XDCI_CORE_HANDLE *)CoreHandle;
> +
> +  if (LocalCoreHandle == NULL) {
> +    DEBUG ((DEBUG_INFO, "DwcXdciCoreUnregisterCallback: INVALID handle\n"));
> +    return EFI_DEVICE_ERROR;
> +  }
> +
> +  switch (event) {
> +    case USB_DEVICE_DISCONNECT_EVENT:
> +      LocalCoreHandle->EventCallbacks.DevDisconnectCallback = NULL;
> +      break;
> +
> +    case USB_DEVICE_RESET_EVENT:
> +      LocalCoreHandle->EventCallbacks.DevBusResetCallback = NULL;
> +      break;
> +
> +    case USB_DEVICE_CONNECTION_DONE:
> +      LocalCoreHandle->EventCallbacks.DevResetDoneCallback = NULL;
> +      break;
> +
> +    case USB_DEVICE_STATE_CHANGE_EVENT:
> +      LocalCoreHandle->EventCallbacks.DevLinkStateCallback = NULL;
> +      break;
> +
> +    case USB_DEVICE_WAKEUP_EVENT:
> +      LocalCoreHandle->EventCallbacks.DevWakeupCallback = NULL;
> +      break;
> +
> +    case USB_DEVICE_HIBERNATION_REQ_EVENT:
> +      LocalCoreHandle->EventCallbacks.DevHibernationCallback = NULL;
> +      break;
> +
> +    case USB_DEVICE_SOF_EVENT:
> +      LocalCoreHandle->EventCallbacks.DevSofCallback = NULL;
> +      break;
> +
> +    case USB_DEVICE_ERRATIC_ERR_EVENT:
> +      LocalCoreHandle->EventCallbacks.DevErraticErrCallback = NULL;
> +      break;
> +
> +    case USB_DEVICE_CMD_CMPLT_EVENT:
> +      LocalCoreHandle->EventCallbacks.DevCmdCmpltCallback = NULL;
> +      break;
> +
> +    case USB_DEVICE_BUFF_OVERFLOW_EVENT:
> +      LocalCoreHandle->EventCallbacks.DevBuffOvflwCallback = NULL;
> +      break;
> +
> +    case USB_DEVICE_TEST_LMP_RX_EVENT:
> +      LocalCoreHandle->EventCallbacks.DevTestLmpRxCallback = NULL;
> +      break;
> +
> +    case USB_DEVICE_SETUP_PKT_RECEIVED:
> +      LocalCoreHandle->EventCallbacks.DevSetupPktReceivedCallback = NULL;
> +      break;
> +
> +    case USB_DEVICE_XFER_NRDY:
> +      LocalCoreHandle->EventCallbacks.DevXferNrdyCallback = NULL;
> +      break;
> +
> +    case USB_DEVICE_XFER_DONE:
> +      LocalCoreHandle->EventCallbacks.DevXferDoneCallback = NULL;
> +      break;
> +
> +    default:
> +      break;
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +
> +/**
> +  Interface:
> +  This function is used as an interrupt service routine
> +  @CoreHandle: xDCI controller handle
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +DwcXdciCoreIsrRoutine (
> +  IN VOID     *CoreHandle
> +  )
> +{
> +  XDCI_CORE_HANDLE    *LocalCoreHandle = (XDCI_CORE_HANDLE *)CoreHandle;
> +  UINT32              BaseAddr;
> +  UINT32              eventCount;
> +  UINT32              ProcessedEventCount;
> +  UINT32              i;
> +
> +  if (CoreHandle == NULL) {
> +    DEBUG ((DEBUG_INFO, "DwcXdciCoreIsrRoutine: INVALID handle\n"));
> +    return EFI_DEVICE_ERROR;
> +  }
> +
> +  if (LocalCoreHandle->InterrupProcessing == TRUE) {
> +    DEBUG ((DEBUG_INFO, "interrupProcessing.........\n"));
> +    return EFI_SUCCESS;
> +  }
> +
> +  BaseAddr = LocalCoreHandle->BaseAddress;
> +  //
> +  // Event Buffer corresponding to each interrupt line needs
> +  // to be Processed
> +  //
> +  LocalCoreHandle->InterrupProcessing = TRUE;
> +  for (i = 0; i < LocalCoreHandle->MaxDevIntLines; i++) {
> +    //
> +    // Get the number of events HW has written for this
> +    //  interrupt line
> +    //
> +    eventCount = UsbRegRead (BaseAddr, DWC_XDCI_EVNTCOUNT_REG (i));
> +    eventCount &= DWC_XDCI_EVNTCOUNT_MASK;
> +    ProcessedEventCount = 0;
> +
> +    //
> +    // Process interrupt line Buffer only if count is non-zero
> +    //
> +    if (eventCount) {
> +      //
> +      // Process events in this Buffer
> +      //
> +      DwcXdciProcessInterruptLineEvents (LocalCoreHandle, eventCount, &ProcessedEventCount);
> +      //
> +      // Write back the Processed number of events so HW decrements it from current
> +      // event count
> +      //
> +      UsbRegWrite (BaseAddr, DWC_XDCI_EVNTCOUNT_REG (i), ProcessedEventCount);
> +    }
> +  }
> +  LocalCoreHandle->InterrupProcessing = FALSE;
> +  return EFI_SUCCESS;
> +}
> +
> +
> +/**
> +  Interface:
> +  This function is used as an interrupt service routine and it processes only one event at a time.
> +  @CoreHandle: xDCI controller handle
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +DwcXdciCoreIsrRoutineTimerBased (
> +  IN VOID     *CoreHandle
> +  )
> +{
> +  XDCI_CORE_HANDLE    *LocalCoreHandle = (XDCI_CORE_HANDLE *)CoreHandle;
> +  UINT32              BaseAddr;
> +  UINT32              eventCount;
> +  UINT32              ProcessedEventCount;
> +  UINT32              currentEventAddr;
> +  UINT32              ProcessedEventSize = 0;
> +
> +  if (CoreHandle == NULL) {
> +    DEBUG ((DEBUG_INFO, "DwcXdciCoreIsrRoutineTimerBased: INVALID handle\n"));
> +    return EFI_DEVICE_ERROR;
> +  }
> +
> +  if (LocalCoreHandle->CurrentEventBuffer == NULL) {
> +    DEBUG ((DEBUG_INFO, "ERROR: DwcXdciCoreIsrRoutineTimerBased: INVALID event Buffer\n"));
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  BaseAddr = LocalCoreHandle->BaseAddress;
> +
> +  eventCount = UsbRegRead (BaseAddr, DWC_XDCI_EVNTCOUNT_REG (0)) & DWC_XDCI_EVNTCOUNT_MASK;
> +
> +  if (LocalCoreHandle->InterrupProcessing == TRUE) {
> +    DEBUG ((DEBUG_INFO, "interrupProcessing.........\n"));
> +    return EFI_SUCCESS;
> +  }
> +
> +  LocalCoreHandle->InterrupProcessing = TRUE;
> +
> +  ProcessedEventCount = 0;
> +  currentEventAddr = (UINT32)(UINTN)(LocalCoreHandle->CurrentEventBuffer);
> +
> +  if (LocalCoreHandle->CurrentEventBuffer->Event & DWC_XDCI_EVENT_DEV_MASK) {
> +    DwcXdciProcessDeviceEvent (
> +      LocalCoreHandle,
> +      LocalCoreHandle->CurrentEventBuffer,
> +      &ProcessedEventSize
> +      );
> +  } else {
> +    DwcXdciProcessEpEvent (
> +      LocalCoreHandle,
> +      LocalCoreHandle->CurrentEventBuffer,
> +      &ProcessedEventSize);
> +  }
> +
> +  eventCount -= ProcessedEventSize;
> +  ProcessedEventCount += ProcessedEventSize;
> +  if ((currentEventAddr + ProcessedEventSize) >=
> +      ((UINT32)(UINTN)(LocalCoreHandle->AlignedEventBuffers) + (sizeof(DWC_XDCI_EVENT_BUFFER) * DWC_XDCI_MAX_EVENTS_PER_BUFFER))
> +     ) {
> +    currentEventAddr = (UINT32)(UINTN)(LocalCoreHandle->AlignedEventBuffers);
> +    DEBUG ((DEBUG_INFO, "DwcXdciProcessInterruptLineEvents: Event Buffer bound reached\n"));
> +  } else {
> +    currentEventAddr += ProcessedEventSize;
> +  }
> +
> +  LocalCoreHandle->CurrentEventBuffer = (DWC_XDCI_EVENT_BUFFER *)(UINTN)currentEventAddr;
> +  UsbRegWrite (BaseAddr, DWC_XDCI_EVNTCOUNT_REG (0), ProcessedEventCount);
> +  LocalCoreHandle->InterrupProcessing = FALSE;
> +
> +  return EFI_SUCCESS;
> +}
> +
> +
> +/**
> +  Interface:
> +  This function is used to enable xDCI to connect to the host
> +  @CoreHandle: xDCI controller handle
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +DwcXdciCoreConnect (
> +  IN VOID     *CoreHandle
> +  )
> +{
> +  XDCI_CORE_HANDLE    *LocalCoreHandle = (XDCI_CORE_HANDLE *)CoreHandle;
> +  UINT32              MaxDelayIter = DWC_XDCI_MAX_DELAY_ITERATIONS;
> +  UINT32              BaseAddr;
> +
> +  if (CoreHandle == NULL) {
> +    DEBUG ((DEBUG_INFO, "DwcXdciCoreConnect: INVALID handle\n"));
> +    return EFI_DEVICE_ERROR;
> +  }
> +
> +  BaseAddr = LocalCoreHandle->BaseAddress;
> +
> +  //
> +  // Clear KeepConnect bit so we can allow disconnect and re-connect
> +  // Also issue No action on state change to aVOID any link change
> +  //
> +  UsbRegWrite (
> +    BaseAddr,
> +    DWC_XDCI_DCTL_REG,
> +    (UsbRegRead(BaseAddr, DWC_XDCI_DCTL_REG) & ~DWC_XDCI_DCTL_KEEP_CONNECT_MASK) & ~DWC_XDCI_DCTL_STATE_CHANGE_REQ_MASK
> +    );
> +
> +  //
> +  // Set Run bit to connect to the host
> +  //
> +  UsbRegWrite (
> +    BaseAddr,
> +    DWC_XDCI_DCTL_REG,
> +    UsbRegRead (BaseAddr, DWC_XDCI_DCTL_REG) | DWC_XDCI_DCTL_RUN_STOP_MASK
> +    );
> +
> +  //
> +  // Wait until core starts running
> +  //
> +  do {
> +    if (!(UsbRegRead (BaseAddr, DWC_XDCI_DSTS_REG) & DWC_XDCI_DSTS_DEV_CTRL_HALTED_MASK)) {
> +      break;
> +    } else {
> +      gBS->Stall (DWC_XDCI_MAX_DELAY_ITERATIONS);
> +    }
> +  } while (--MaxDelayIter);
> +
> +  if (!MaxDelayIter) {
> +    DEBUG ((DEBUG_INFO, "Failed to run the device controller\n"));
> +    return EFI_DEVICE_ERROR;
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +
> +/**
> +  Interface:
> +  This function is used to disconnect xDCI from the host
> +  @CoreHandle: xDCI controller handle
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +DwcXdciCoreDisconnect (
> +  IN VOID    *CoreHandle
> +  )
> +{
> +  XDCI_CORE_HANDLE  *LocalCoreHandle = (XDCI_CORE_HANDLE *)CoreHandle;
> +  UINT32            MaxDelayIter = DWC_XDCI_MAX_DELAY_ITERATIONS;
> +  UINT32            BaseAddr;
> +  UINT32            eventCount;
> +  UINT32            dsts;
> +  UINT32            i;
> +
> +  if (CoreHandle == NULL) {
> +    DEBUG ((DEBUG_INFO, "DwcXdciCoreDisconnect: INVALID handle\n"));
> +    return EFI_DEVICE_ERROR;
> +  }
> +
> +  BaseAddr = LocalCoreHandle->BaseAddress;
> +
> +  eventCount = UsbRegRead (BaseAddr, DWC_XDCI_EVNTCOUNT_REG (0));
> +  eventCount &= DWC_XDCI_EVNTCOUNT_MASK;
> +
> +  DEBUG ((DEBUG_INFO, "DwcXdciCoreDisconnect: eventCount=%d\n", eventCount));
> +  while (eventCount) {
> +    DwcXdciCoreIsrRoutine(LocalCoreHandle);
> +    eventCount = UsbRegRead (BaseAddr, DWC_XDCI_EVNTCOUNT_REG (0));
> +    eventCount &= DWC_XDCI_EVNTCOUNT_MASK;
> +    DEBUG ((DEBUG_INFO, "DwcXdciCoreDisconnect: eventCount=%d\n", eventCount));
> +  }
> +
> +  //
> +  // Issue DEPENDXFER for active transfers
> +  //
> +  for (i = 0; i < DWC_XDCI_MAX_ENDPOINTS; i++){
> +    if (LocalCoreHandle->EpHandles[i].CurrentXferRscIdx){
> +      DwcXdciEndXfer(LocalCoreHandle, i);
> +    }
> +  }
> +  //
> +  // Clear Run bit to disconnect from host
> +  //
> +  UsbRegWrite (
> +    BaseAddr,
> +    DWC_XDCI_DCTL_REG,
> +    UsbRegRead(BaseAddr, DWC_XDCI_DCTL_REG) & ~DWC_XDCI_DCTL_RUN_STOP_MASK);
> +
> +  //
> +  // Wait until core is halted
> +  //
> +  do {
> +    dsts = UsbRegRead (BaseAddr, DWC_XDCI_DSTS_REG);
> +    DEBUG ((DEBUG_INFO, "DwcXdciCoreDisconnect: waiting halt: DSTS=0x%x\n", dsts));
> +    if ((dsts & DWC_XDCI_DSTS_DEV_CTRL_HALTED_MASK) != 0){
> +      break;
> +    } else {
> +      gBS->Stall (DWC_XDCI_MAX_DELAY_ITERATIONS);
> +    }
> +  } while (--MaxDelayIter);
> +
> +  if (!MaxDelayIter) {
> +    DEBUG ((DEBUG_INFO, "DwcXdciCoreDisconnect: Failed to halt the device controller\n"));
> +    return EFI_DEVICE_ERROR;
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +
> +/**
> +  Interface:
> +  This function is used to obtain current USB bus Speed
> +  @CoreHandle: xDCI controller handle
> +  @Speed: Address of variable to save the Speed
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +DwcXdciCoreGetSpeed (
> +  IN VOID         *CoreHandle,
> +  IN USB_SPEED    *Speed
> +  )
> +{
> +  XDCI_CORE_HANDLE *LocalCoreHandle = (XDCI_CORE_HANDLE *)CoreHandle;
> +
> +  if (CoreHandle == NULL) {
> +    DEBUG ((DEBUG_INFO, "DwcXdciCoreGetSpeed: INVALID handle\n"));
> +    return EFI_DEVICE_ERROR;
> +  }
> +
> +  if (Speed == NULL) {
> +    DEBUG ((DEBUG_INFO, "DwcXdciCoreGetSpeed: INVALID parameter\n"));
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  *Speed = UsbRegRead (LocalCoreHandle->BaseAddress, DWC_XDCI_DSTS_REG) & DWC_XDCI_DSTS_CONN_SPEED_MASK;
> +
> +  return EFI_SUCCESS;
> +}
> +
> +
> +/**
> +  Interface:
> +  This function is used to obtain current USB bus Speed
> +  @CoreHandle: xDCI controller handle
> +  @address: USB address to set (assigned by USB host)
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +DwcXdciCoreSetAddress (
> +  IN VOID      *CoreHandle,
> +  IN UINT32    address
> +  )
> +{
> +  XDCI_CORE_HANDLE  *LocalCoreHandle = (XDCI_CORE_HANDLE *)CoreHandle;
> +  UINT32            BaseAddr;
> +
> +  if (CoreHandle == NULL) {
> +    DEBUG ((DEBUG_INFO, "DwcXdciCoreSetAddress: INVALID handle\n"));
> +    return EFI_DEVICE_ERROR;
> +  }
> +
> +  BaseAddr = LocalCoreHandle->BaseAddress;
> +
> +  DEBUG ((DEBUG_INFO, "DwcXdciCoreSetAddress is 0x%x \n", address));
> +  //
> +  // Program USB device address
> +  //
> +  UsbRegWrite (
> +    BaseAddr,
> +    DWC_XDCI_DCFG_REG,
> +    (UsbRegRead(BaseAddr, DWC_XDCI_DCFG_REG) & ~DWC_XDCI_DCFG_DEV_ADDRESS_MASK) | (address << DWC_XDCI_DCFG_DEV_ADDRESS_BIT_POS)
> +    );
> +
> +  LocalCoreHandle->DevState = UsbDevStateAddress;
> +  DEBUG ((DEBUG_INFO, "Setup value of xDCI DWC_XDCI_GCTL_REG: 0x%x\n", UsbRegRead (BaseAddr, DWC_XDCI_GCTL_REG)));
> +  DEBUG ((DEBUG_INFO, "Setup value of xDCI DWC_XDCI_DEVTEN_REG: 0x%x\n", UsbRegRead (BaseAddr, DWC_XDCI_DEVTEN_REG)));
> +  DEBUG ((DEBUG_INFO, "Setup value of xDCI DWC_XDCI_DCFG_REG: 0x%x\n", UsbRegRead (BaseAddr, DWC_XDCI_DCFG_REG)));
> +  DEBUG ((DEBUG_INFO, "Setup value of xDCI DWC_XDCI_DSTS_REG: 0x%x\n", UsbRegRead (BaseAddr, DWC_XDCI_DSTS_REG)));
> +
> +  return EFI_SUCCESS;
> +}
> +
> +
> +/**
> +  Interface:
> +  This function is used to set configuration
> +  @CoreHandle: xDCI controller handle
> +  @ConfigNum: config num to set (assigned by USB host)
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +DwcXdciCoreSetConfig (
> +  IN VOID      *CoreHandle,
> +  IN UINT32    ConfigNum
> +  )
> +{
> +  XDCI_CORE_HANDLE              *LocalCoreHandle = (XDCI_CORE_HANDLE *)CoreHandle;
> +  DWC_XDCI_ENDPOINT_CMD_PARAMS  EpCmdParams;
> +  EFI_STATUS                    status;
> +
> +  if (CoreHandle == NULL) {
> +    DEBUG ((DEBUG_INFO, "DwcXdciCoreSetConfig: INVALID handle\n"));
> +    return EFI_DEVICE_ERROR;
> +  }
> +
> +  //
> +  // Issue DEPSTARTCFG command on EP0 (new config for
> +  // non-control EPs)
> +  //
> +  status = DwcXdciCoreInitEpCmdParams (
> +            LocalCoreHandle,
> +            &LocalCoreHandle->EpHandles[0].EpInfo,
> +            DWC_XDCI_PARAM0_SET_EP_CFG_ACTN_NONE,
> +            EPCMD_START_NEW_CONFIG,
> +            &EpCmdParams
> +            );
> +
> +  if (status) {
> +    DEBUG ((DEBUG_INFO, "DwcXdciCoreSetConfig: Failed to init params for EPCMD_START_NEW_CONFIG command\n"));
> +    return status;
> +  }
> +
> +  //
> +  // Issue the command
> +  //
> +  status = DwcXdciCoreIssueEpCmd (
> +             LocalCoreHandle,
> +             0,
> +             (EPCMD_START_NEW_CONFIG | (2 << DWC_XDCI_EPCMD_RES_IDX_BIT_POS)),
> +             &EpCmdParams
> +             );
> +
> +  if (status) {
> +    DEBUG ((DEBUG_INFO, "DwcXdciCoreSetConfig: Failed to issue EPCMD_START_NEW_CONFIG command\n"));
> +    return status;
> +  }
> +
> +  return status;
> +}
> +
> +
> +/**
> +  Interface:
> +  This function is used to set link state
> +  @CoreHandle: xDCI controller handle
> +  @state: Desired link state
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +DwcXdciSetLinkState (
> +  IN VOID                        *CoreHandle,
> +  IN USB_DEVICE_SS_LINK_STATE    state
> +  )
> +{
> +  XDCI_CORE_HANDLE  *LocalCoreHandle = (XDCI_CORE_HANDLE *)CoreHandle;
> +  UINT32            BaseAddr;
> +
> +  if (CoreHandle == NULL) {
> +    DEBUG ((DEBUG_INFO, "DwcXdciSetLinkState: INVALID handle\n"));
> +    return EFI_DEVICE_ERROR;
> +  }
> +
> +  BaseAddr = LocalCoreHandle->BaseAddress;
> +
> +  //
> +  // Clear old mask
> +  //
> +  UsbRegWrite (
> +    BaseAddr,
> +    DWC_XDCI_DCTL_REG,
> +    UsbRegRead (BaseAddr, DWC_XDCI_DCTL_REG) & ~DWC_XDCI_DCTL_STATE_CHANGE_REQ_MASK
> +    );
> +
> +  //
> +  // Request new state
> +  //
> +  UsbRegWrite (
> +    BaseAddr,
> +    DWC_XDCI_DCTL_REG,
> +    UsbRegRead (BaseAddr, DWC_XDCI_DCTL_REG) | (state << DWC_XDCI_DCTL_STATE_CHANGE_REQ_BIT_POS)
> +    );
> +
> +  return EFI_SUCCESS;
> +}
> +
> +
> +/**
> +  Interface:
> +  This function is used to initialize endpoint
> +  @CoreHandle: xDCI controller handle
> +  @EpInfo: Address of structure describing properties of EP
> +  to be initialized
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +DwcXdciInitEp (
> +  IN VOID           *CoreHandle,
> +  IN USB_EP_INFO    *EpInfo
> +  )
> +{
> +  XDCI_CORE_HANDLE              *LocalCoreHandle = (XDCI_CORE_HANDLE *)CoreHandle;
> +  DWC_XDCI_ENDPOINT_CMD_PARAMS  EpCmdParams;
> +  EFI_STATUS                    status;
> +  UINT32                        EpNum;
> +
> +  if (CoreHandle == NULL) {
> +    DEBUG ((DEBUG_INFO, "DwcXdciInitEp: INVALID handle\n"));
> +    return EFI_DEVICE_ERROR;
> +  }
> +
> +  //
> +  // Convert to physical endpoint
> +  //
> +  EpNum = DwcXdciGetPhysicalEpNum (EpInfo->EpNum, EpInfo->EpDir);
> +
> +  //
> +  // Save EP properties
> +  //
> +  CopyMem (&(LocalCoreHandle->EpHandles[EpNum].EpInfo), EpInfo, sizeof (USB_EP_INFO));
> +
> +  //
> +  // Init CheckFlag
> +  //
> +  LocalCoreHandle->EpHandles[EpNum].CheckFlag = FALSE;
> +
> +  //
> +  // Init DEPCFG cmd params for EP
> +  //
> +  status = DwcXdciCoreInitEpCmdParams (
> +             CoreHandle,
> +             &LocalCoreHandle->EpHandles[EpNum].EpInfo,
> +             DWC_XDCI_PARAM0_SET_EP_CFG_ACTN_INIT_STATE,
> +             EPCMD_SET_EP_CONFIG,
> +             &EpCmdParams
> +             );
> +
> +  if (status) {
> +    DEBUG ((DEBUG_INFO, "DwcXdciInitEp: Failed to init params for  EPCMD_SET_EP_CONFIG command\n"));
> +    return status;
> +  }
> +
> +  //
> +  // Issue the command
> +  //
> +  status = DwcXdciCoreIssueEpCmd (
> +             CoreHandle,
> +             EpNum,
> +             EPCMD_SET_EP_CONFIG,
> +             &EpCmdParams
> +             );
> +
> +  if (status) {
> +    DEBUG ((DEBUG_INFO, "DwcXdciInitEp: Failed to issue  EPCMD_SET_EP_CONFIG command\n"));
> +    return status;
> +  }
> +
> +  //
> +  // Issue a DEPXFERCFG command for endpoint
> +  //
> +  status = DwcXdciCoreInitEpCmdParams (
> +             LocalCoreHandle,
> +             &LocalCoreHandle->EpHandles[EpNum].EpInfo,
> +             DWC_XDCI_PARAM0_SET_EP_CFG_ACTN_NONE,
> +             EPCMD_SET_EP_XFER_RES_CONFIG,
> +             &EpCmdParams
> +             );
> +
> +  if (status) {
> +    DEBUG ((DEBUG_INFO, "DwcXdciInitEp: Failed to init params for  EPCMD_SET_EP_XFER_RES_CONFIG command\n"));
> +    return status;
> +  }
> +
> +  //
> +  // Issue the command
> +  //
> +  status = DwcXdciCoreIssueEpCmd (
> +             LocalCoreHandle,
> +             EpNum,
> +             EPCMD_SET_EP_XFER_RES_CONFIG,
> +             &EpCmdParams
> +             );
> +
> +  if (status) {
> +    DEBUG ((DEBUG_INFO, "DwcXdciInitEp: Failed to issue EPCMD_SET_EP_XFER_RES_CONFIG command\n"));
> +  }
> +
> +  return status;
> +}
> +
> +
> +/**
> +  Interface:
> +  This function is used to enable non-Ep0 endpoint
> +  @CoreHandle: xDCI controller handle
> +  @EpInfo: Address of structure describing properties of EP
> +  to be enabled
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +DwcXdciEpEnable (
> +  IN VOID           *CoreHandle,
> +  IN USB_EP_INFO    *EpInfo
> +  )
> +{
> +  XDCI_CORE_HANDLE  *LocalCoreHandle = (XDCI_CORE_HANDLE *)CoreHandle;
> +  UINT32            EpNum;
> +  UINT32            BaseAddr;
> +
> +  if (CoreHandle == NULL) {
> +    DEBUG ((DEBUG_INFO, "DwcXdciEpEnable: INVALID handle\n"));
> +    return EFI_DEVICE_ERROR;
> +  }
> +
> +  BaseAddr = LocalCoreHandle->BaseAddress;
> +
> +  //
> +  // Convert to physical endpoint
> +  //
> +  EpNum = DwcXdciGetPhysicalEpNum (EpInfo->EpNum, EpInfo->EpDir);
> +
> +  //
> +  // Enable Physical Endpoint EpNum
> +  //
> +  UsbRegWrite (
> +    BaseAddr,
> +    DWC_XDCI_EP_DALEPENA_REG,
> +    UsbRegRead (BaseAddr, DWC_XDCI_EP_DALEPENA_REG) | (1 << EpNum)
> +    );
> +
> +  return EFI_SUCCESS;
> +}
> +
> +
> +/**
> +  Interface:
> +  This function is used to disable non-Ep0 endpoint
> +  @CoreHandle: xDCI controller handle
> +  @EpInfo: Address of structure describing properties of EP
> +  to be enabled
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +DwcXdciEpDisable (
> +  IN VOID           *CoreHandle,
> +  IN USB_EP_INFO    *EpInfo
> +  )
> +{
> +  XDCI_CORE_HANDLE  *LocalCoreHandle = (XDCI_CORE_HANDLE *)CoreHandle;
> +  UINT32            EpNum;
> +  UINT32            BaseAddr;
> +
> +  if (CoreHandle == NULL) {
> +    DEBUG ((DEBUG_INFO, "DwcXdciEpDisable: INVALID handle\n"));
> +    return EFI_DEVICE_ERROR;
> +  }
> +
> +  BaseAddr = LocalCoreHandle->BaseAddress;
> +
> +  //
> +  // Convert to physical endpoint
> +  //
> +  EpNum = DwcXdciGetPhysicalEpNum (EpInfo->EpNum, EpInfo->EpDir);
> +
> +  //
> +  // Disable Physical Endpoint EpNum
> +  //
> +  UsbRegWrite (
> +    BaseAddr,
> +    DWC_XDCI_EP_DALEPENA_REG,
> +    UsbRegRead (BaseAddr, DWC_XDCI_EP_DALEPENA_REG) & ~(1 << EpNum)
> +    );
> +
> +  return EFI_SUCCESS;
> +}
> +
> +
> +/**
> +  Interface:
> +  This function is used to STALL and endpoint
> +  @CoreHandle: xDCI controller handle
> +  @EpInfo: Address of structure describing properties of EP
> +  to be enabled
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +DwcXdciEpStall (
> +  IN VOID           *CoreHandle,
> +  IN USB_EP_INFO    *EpInfo
> +  )
> +{
> +  XDCI_CORE_HANDLE              *LocalCoreHandle = (XDCI_CORE_HANDLE *)CoreHandle;
> +  DWC_XDCI_ENDPOINT_CMD_PARAMS  EpCmdParams;
> +  EFI_STATUS                    status;
> +  UINT32                        EpNum;
> +
> +  if (CoreHandle == NULL) {
> +    DEBUG ((DEBUG_INFO, "DwcXdciEpStall: INVALID handle\n"));
> +    return EFI_DEVICE_ERROR;
> +  }
> +
> +  //
> +  // Convert to physical endpoint
> +  //
> +  EpNum = DwcXdciGetPhysicalEpNum (EpInfo->EpNum, EpInfo->EpDir);
> +
> +  //
> +  // Set Ep State Info
> +  //
> +  if (LocalCoreHandle->EpHandles[EpNum].State != USB_EP_STATE_STALLED) {
> +    LocalCoreHandle->EpHandles[EpNum].OrgState = LocalCoreHandle->EpHandles[EpNum].State;
> +    LocalCoreHandle->EpHandles[EpNum].State = USB_EP_STATE_STALLED;
> +  }
> +  //
> +  // Issue a DWC_XDCI_EPCMD_SET_STALL for EP
> +  // Reset params
> +  //
> +  EpCmdParams.Param0 = EpCmdParams.Param1 = EpCmdParams.Param2 = 0;
> +
> + //
> + // Issue the command
> + //
> + status = DwcXdciCoreIssueEpCmd (
> +            LocalCoreHandle,
> +            EpNum,
> +            DWC_XDCI_EPCMD_SET_STALL,
> +            &EpCmdParams
> +            );
> +
> + if (status) {
> +   DEBUG ((DEBUG_INFO, "DwcXdciEpStall: Failed to issue EP stall command\n"));
> + }
> +
> + return status;
> +}
> +
> +
> +/**
> +  Interface:
> +  This function is used to clear endpoint STALL
> +  @CoreHandle: xDCI controller handle
> +  @EpInfo: Address of structure describing properties of EP
> +  to be enabled
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +DwcXdciEpClearStall (
> +  IN VOID           *CoreHandle,
> +  IN USB_EP_INFO    *EpInfo
> +  )
> +{
> +  XDCI_CORE_HANDLE              *LocalCoreHandle = (XDCI_CORE_HANDLE *)CoreHandle;
> +  DWC_XDCI_ENDPOINT_CMD_PARAMS  EpCmdParams;
> +  EFI_STATUS                    status;
> +  UINT32                        EpNum;
> +
> +  if (CoreHandle == NULL) {
> +    DEBUG ((DEBUG_INFO, "DwcXdciEpClearStall: INVALID handle\n"));
> +    return EFI_DEVICE_ERROR;
> +  }
> +
> +  //
> +  // Convert to physical endpoint
> +  //
> +  EpNum = DwcXdciGetPhysicalEpNum (EpInfo->EpNum, EpInfo->EpDir);
> +
> +  //
> +  // Set Ep State Info
> +  //
> +  LocalCoreHandle->EpHandles[EpNum].State = LocalCoreHandle->EpHandles[EpNum].OrgState;
> +
> +  //
> +  // Issue a DWC_XDCI_EPCMD_CLEAR_STALL for EP
> +  // Reset params
> +  //
> +  EpCmdParams.Param0 = EpCmdParams.Param1 = EpCmdParams.Param2 = 0;
> +
> +  //
> +  // Issue the command
> +  //
> + status = DwcXdciCoreIssueEpCmd (
> +            LocalCoreHandle,
> +            EpNum,
> +            DWC_XDCI_EPCMD_CLEAR_STALL,
> +            &EpCmdParams
> +            );
> +
> + if (status) {
> +   DEBUG ((DEBUG_INFO, "DwcXdciEpStall: Failed to issue EP clea stall command\n"));
> + }
> +
> + return status;
> +}
> +
> +
> +/**
> +  Interface:
> +  This function is used to set endpoint in NOT READY state
> +  @CoreHandle: xDCI controller handle
> +  @EpInfo: Address of structure describing properties of EP
> +  to be enabled
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +DwcXdciEpSetNrdy (
> +  IN VOID           *CoreHandle,
> +  IN USB_EP_INFO    *EpInfo
> +  )
> +{
> +  XDCI_CORE_HANDLE  *LocalCoreHandle = (XDCI_CORE_HANDLE *)CoreHandle;
> +  UINT32            EpNum;
> +  UINT32            BaseAddr;
> +  UINT32            MaxDelayIter = DWC_XDCI_MAX_DELAY_ITERATIONS;
> +
> +  if (CoreHandle == NULL) {
> +    DEBUG ((DEBUG_INFO, "DwcXdciEpSetNrdy: INVALID handle\n"));
> +    return EFI_DEVICE_ERROR;
> +  }
> +
> +  BaseAddr = LocalCoreHandle->BaseAddress;
> +
> +  //
> +  // Convert to physical endpoint
> +  //
> +  EpNum = DwcXdciGetPhysicalEpNum (EpInfo->EpNum, EpInfo->EpDir);
> +
> +  //
> +  // Program the EP number in command's param reg
> +  //
> +  UsbRegWrite (BaseAddr, DWC_XDCI_DGCMD_PARAM_REG, EpNum);
> +
> +  //
> +  // Issue EP not ready generic device command
> +  //
> +  UsbRegWrite (
> +    BaseAddr,
> +    DWC_XDCI_DGCMD_REG,
> +    (UsbRegRead (BaseAddr, DWC_XDCI_DGCMD_REG) | DWC_XDCI_DGCMD_CMD_SET_EP_NRDY)
> +    );
> +
> +  //
> +  // Activate the command
> +  //
> +  UsbRegWrite (
> +    BaseAddr,
> +    DWC_XDCI_DGCMD_REG,
> +    (UsbRegRead (BaseAddr, DWC_XDCI_DGCMD_REG) | DWC_XDCI_DGCMD_CMD_ACTIVE_MASK)
> +    );
> +
> +  //
> +  // Wait until command completes
> +  //
> +  do {
> +    if (!(UsbRegRead (BaseAddr, DWC_XDCI_DGCMD_REG) & DWC_XDCI_DGCMD_CMD_ACTIVE_MASK))
> +      break;
> +    else
> +      gBS->Stall (DWC_XDCI_MAX_DELAY_ITERATIONS);
> +  } while (--MaxDelayIter);
> +
> +  if (!MaxDelayIter) {
> +    DEBUG ((DEBUG_INFO, "Failed to issue Command\n"));
> +    return EFI_DEVICE_ERROR;
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +
> +/**
> +  Interface:
> +  This function is used to queue receive SETUP packet request
> +  @CoreHandle: xDCI controller handle
> +  @Buffer: Address of Buffer to receive SETUP packet
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +DwcXdciEp0ReceiveSetupPkt (
> +  IN VOID     *CoreHandle,
> +  IN UINT8    *Buffer
> +  )
> +{
> +  XDCI_CORE_HANDLE                *LocalCoreHandle = (XDCI_CORE_HANDLE *)CoreHandle;
> +  DWC_XDCI_ENDPOINT_CMD_PARAMS    EpCmdParams;
> +  EFI_STATUS                      Status = EFI_DEVICE_ERROR;
> +  DWC_XDCI_TRB                    *Trb;
> +
> +  if (CoreHandle == NULL) {
> +    DEBUG ((DEBUG_INFO, "DwcXdciEp0ReceiveSetupPkt: INVALID handle\n"));
> +    return EFI_DEVICE_ERROR;
> +  }
> +
> +  LocalCoreHandle->EpHandles[0].EpInfo.EpNum = 0;
> +  LocalCoreHandle->EpHandles[0].EpInfo.EpDir = 0;
> +  LocalCoreHandle->EpHandles[0].State = USB_EP_STATE_SETUP;
> +  Trb = LocalCoreHandle->Trbs;
> +  DEBUG ((DEBUG_INFO, "(DwcXdciEp0ReceiveSetupPkt)\n"));
> +
> +  Status = DwcXdciCoreInitTrb (
> +             LocalCoreHandle,
> +             Trb,
> +             TRBCTL_SETUP,
> +             Buffer,
> +             8
> +             );
> +
> +  if (Status) {
> +    DEBUG ((DEBUG_INFO, "DwcXdciEp0ReceiveSetupPkt: Init TRB Failed \n"));
> +    return Status;
> +  }
> +
> +  //
> +  // Issue a DEPSTRTXFER for EP0
> +  // Reset params
> +  //
> +  EpCmdParams.Param0 = EpCmdParams.Param1 = EpCmdParams.Param2 = 0;
> +
> +  //
> +  // Init the lower re-bits for TRB address
> +  //
> +  EpCmdParams.Param1 = (UINT32)(UINTN)Trb;
> +
> +  //
> +  // Issue the command
> +  //
> +  Status = DwcXdciCoreIssueEpCmd (
> +             LocalCoreHandle,
> +             0,
> +             EPCMD_START_XFER,
> +             &EpCmdParams
> +             );
> +
> +  if (Status) {
> +    DEBUG ((DEBUG_INFO, "\nDwcXdciEp0ReceiveSetupPkt: Failed to issue Start Transfer command"));
> +  }
> +
> +  //
> +  // Save new resource index for this transfer
> +  //
> +  LocalCoreHandle->EpHandles[0].CurrentXferRscIdx = ((UsbRegRead(LocalCoreHandle->BaseAddress, DWC_XDCI_EPCMD_REG(0)) &
> +                                                         DWC_XDCI_EPCMD_RES_IDX_MASK) >> DWC_XDCI_EPCMD_RES_IDX_BIT_POS
> +                                                         );
> +
> +  return Status;
> +}
> +
> +
> +/**
> +  Interface:
> +  This function is used to queue receive status packet on EP0
> +  @CoreHandle: xDCI controller handle
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +DwcXdciEp0ReceiveStatusPkt (
> +  IN VOID    *CoreHandle
> +  )
> +{
> +  XDCI_CORE_HANDLE                *LocalCoreHandle = (XDCI_CORE_HANDLE *)CoreHandle;
> +  DWC_XDCI_TRB                    *Trb;
> +  DWC_XDCI_TRB_CONTROL            TrbCtrl;
> +  DWC_XDCI_ENDPOINT_CMD_PARAMS    EpCmdParams;
> +  EFI_STATUS                      Status;
> +  UINT32                          BaseAddr;
> +
> +  if (CoreHandle == NULL) {
> +    DEBUG ((DEBUG_INFO, "DwcXdciEp0ReceiveStatusPkt: INVALID handle\n"));
> +    return EFI_DEVICE_ERROR;
> +  }
> +
> +  BaseAddr = LocalCoreHandle->BaseAddress;
> +
> +  //
> +  // We are receiving on EP0 so physical EP is 0
> +  //
> +  Trb = LocalCoreHandle->Trbs;
> +  DEBUG ((DEBUG_INFO, "(DwcXdciEp0ReceiveStatusPkt)\n"));
> +  if (Trb->TrbCtrl & DWC_XDCI_TRB_CTRL_HWO_MASK) {
> +    DEBUG ((DEBUG_INFO, "statusPkt still not transferred.\n"));
> +    return EFI_SUCCESS;
> +  }
> +
> +  LocalCoreHandle->EpHandles[0].EpInfo.EpNum = 0;
> +  LocalCoreHandle->EpHandles[0].EpInfo.EpDir = 0;
> +
> +  //
> +  // OUT data phase for 3-phased control transfer
> +  //
> +  TrbCtrl = TRBCTL_3_PHASE;
> +
> +  //
> +  // Init TRB for the transfer
> +  //
> +  Status = DwcXdciCoreInitTrb (
> +             LocalCoreHandle,
> +             Trb,
> +             TrbCtrl,
> +             LocalCoreHandle->AlignedSetupBuffer,
> +             0
> +             );
> +
> +  if (!Status) {
> +    //
> +    // Issue a DEPSTRTXFER for EP0
> +    // Reset params
> +    //
> +    EpCmdParams.Param0 = EpCmdParams.Param1 = EpCmdParams.Param2 = 0;
> +
> +    //
> +    // Init the lower bits for TRB address
> +    //
> +    EpCmdParams.Param1 = (UINT32)(UINTN)Trb;
> +
> +    //
> +    // Issue the command
> +    //
> +    Status = DwcXdciCoreIssueEpCmd (
> +               LocalCoreHandle,
> +               0,
> +               EPCMD_START_XFER,
> +               &EpCmdParams
> +               );
> +
> +    if (Status) {
> +      DEBUG ((DEBUG_INFO, "DwcXdciEp0ReceiveStatusPkt: Failed to issue Start Transfer command for EP0\n"));
> +    }
> +    //
> +    // Save new resource index for this transfer
> +    //
> +    LocalCoreHandle->EpHandles[0].CurrentXferRscIdx = ((UsbRegRead(BaseAddr, DWC_XDCI_EPCMD_REG(0)) & DWC_XDCI_EPCMD_RES_IDX_MASK) >> DWC_XDCI_EPCMD_RES_IDX_BIT_POS);
> +
> +    //
> +    // TODO: We are not using the EP state for control transfers
> +    // right now simply because we're only supporting IN
> +    // data phase. For the current use case, we don't
> +    // need OUT data phase. We can add that later and we will
> +    // add some of the state and SETUP packet awareness code
> +    //
> +    LocalCoreHandle->EpHandles[0].State = USB_EP_STATE_STATUS;
> +  }
> +
> +  return Status;
> +}
> +
> +
> +/**
> +  Interface:
> +  This function is used to send status packet on EP0
> +  @CoreHandle: xDCI controller handle
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +DwcXdciEp0SendStatusPkt (
> +  IN VOID    *CoreHandle
> +  )
> +{
> +  XDCI_CORE_HANDLE                *LocalCoreHandle = (XDCI_CORE_HANDLE *)CoreHandle;
> +  DWC_XDCI_TRB                    *Trb;
> +  DWC_XDCI_ENDPOINT_CMD_PARAMS    EpCmdParams;
> +  EFI_STATUS                      Status;
> +  UINT32                          BaseAddr;
> +
> +  if (CoreHandle == NULL) {
> +    DEBUG ((DEBUG_INFO, "DwcXdciEp0SendStatusPkt: INVALID handle\n"));
> +    return EFI_DEVICE_ERROR;
> +  }
> +
> +  BaseAddr = LocalCoreHandle->BaseAddress;
> +
> +  //
> +  // We are sending on EP0 so physical EP is 1
> +  //
> +  Trb = (LocalCoreHandle->Trbs + (1 * DWC_XDCI_TRB_NUM));
> +  DEBUG ((DEBUG_INFO, "(DwcXdciEp0SendStatusPkt)\n"));
> +
> +  LocalCoreHandle->EpHandles[0].State = USB_EP_STATE_STATUS;
> +  Status = DwcXdciCoreInitTrb (
> +             LocalCoreHandle,
> +             Trb,
> +             TRBCTL_2_PHASE,
> +             LocalCoreHandle->AlignedMiscBuffer,
> +             0
> +             );
> +
> +  if (Status) {
> +    DEBUG ((DEBUG_INFO, "DwcXdciEp0SendStatusPkt: TRB failed during status phase\n"));
> +    return Status;
> +  }
> +
> +  //
> +  // Issue a DEPSTRTXFER for EP1
> +  // Reset params
> +  //
> +  EpCmdParams.Param0 = EpCmdParams.Param1 = EpCmdParams.Param2 = 0;
> +
> +  //
> +  // Init the lower re-bits for TRB address
> +  //
> +  EpCmdParams.Param1 = (UINT32)(UINTN)Trb;
> +
> +  //
> +  // Issue the command
> +  //
> +  Status = DwcXdciCoreIssueEpCmd (
> +             LocalCoreHandle,
> +             1,
> +             EPCMD_START_XFER,
> +             &EpCmdParams
> +             );
> +
> +  if (Status) {
> +    DEBUG ((DEBUG_INFO, "DwcXdciEp0SendStatusPkt: Failed to issue Start Transfer on EP0\n"));
> +  }
> +
> +  //
> +  // Save new resource index for this transfer
> +  //
> +  LocalCoreHandle->EpHandles[1].CurrentXferRscIdx = ((UsbRegRead(BaseAddr, DWC_XDCI_EPCMD_REG(1)) & DWC_XDCI_EPCMD_RES_IDX_MASK) >> DWC_XDCI_EPCMD_RES_IDX_BIT_POS);
> +  LocalCoreHandle->EpHandles[0].State = USB_EP_STATE_STATUS;
> +
> +  return Status;
> +}
> +
> +
> +/**
> +  Interface:
> +  This function is used to send data on non-EP0 endpoint
> +  @CoreHandle: xDCI controller handle
> +  @EpInfo: Address of structure describing properties of EP
> +  @Buffer: Buffer containing data to transmit
> +  @size: Size of transfer (in bytes)
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +DwcXdciEpTxData (
> +  IN VOID                *CoreHandle,
> +  IN USB_XFER_REQUEST    *XferReq
> +  )
> +{
> +  XDCI_CORE_HANDLE              *LocalCoreHandle = (XDCI_CORE_HANDLE *)CoreHandle;
> +  DWC_XDCI_ENDPOINT_CMD_PARAMS  EpCmdParams;
> +  DWC_XDCI_TRB                  *Trb;
> +  DWC_XDCI_TRB_CONTROL          TrbCtrl;
> +  EFI_STATUS                    Status;
> +  UINT32                        EpNum;
> +  UINT32                        BaseAddr;
> +
> +  if (CoreHandle == NULL) {
> +    DEBUG ((DEBUG_INFO, "DwcXdciEpTxData: INVALID handle\n"));
> +    return EFI_DEVICE_ERROR;
> +  }
> +
> +  if (XferReq == NULL) {
> +    DEBUG ((DEBUG_INFO, "DwcXdciEpTxData: INVALID transfer request\n"));
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  BaseAddr = LocalCoreHandle->BaseAddress;
> +
> +  //
> +  // Convert to physical endpoint
> +  //
> +  EpNum = DwcXdciGetPhysicalEpNum (
> +             XferReq->EpInfo.EpNum,
> +             XferReq->EpInfo.EpDir
> +             );
> +
> +  Trb = (LocalCoreHandle->Trbs + (EpNum * DWC_XDCI_TRB_NUM));
> +  DEBUG ((DEBUG_INFO, "(DwcXdciEpTxData)EpNum is %d\n", EpNum));
> +
> +
> +  if (EpNum > 1)
> +    TrbCtrl = TRBCTL_NORMAL;
> +  else
> +    TrbCtrl = TRBCTL_CTRL_DATA_PHASE;
> +
> +  if (Trb->TrbCtrl & DWC_XDCI_TRB_CTRL_HWO_MASK) {
> +    Status = DwcXdciEndXfer (LocalCoreHandle, EpNum);
> +    if (Status) {
> +      DEBUG ((DEBUG_INFO, "DwcXdciEpTxData: Failed to end previous transfer\n"));
> +    }
> +
> +    Status = DwcXdciCoreFlushEpTxFifo (LocalCoreHandle, EpNum);
> +    if (Status) {
> +      DEBUG ((DEBUG_INFO, "DwcXdciEpTxData: Failed to end previous transfer\n"));
> +    }
> +  }
> +
> +  //
> +  // Data phase
> +  //
> +  CopyMem (&(LocalCoreHandle->EpHandles[EpNum].XferHandle), XferReq, sizeof (USB_XFER_REQUEST));
> +  LocalCoreHandle->EpHandles[EpNum].State = USB_EP_STATE_DATA;
> +
> +  LocalCoreHandle->EpHandles[EpNum].Trb = Trb;
> +
> +  Status = DwcXdciCoreInitTrb (
> +             LocalCoreHandle,
> +             Trb,
> +             TrbCtrl,
> +             XferReq->XferBuffer,
> +             XferReq->XferLen
> +             );
> +
> +  if (Status) {
> +    DEBUG ((DEBUG_INFO, "DwcXdciEpTxData: TRB failed\n"));
> +    return Status;
> +  }
> +
> +  //
> +  // Issue a DEPSTRTXFER for EP
> +  // Reset params
> +  //
> +  EpCmdParams.Param0 = EpCmdParams.Param1 = EpCmdParams.Param2 = 0;
> +
> +  //
> +  // Init the lower re-bits for TRB address
> +  //
> +  EpCmdParams.Param1 = (UINT32)(UINTN)Trb;
> +
> +  //
> +  // Issue the command
> +  //
> +  Status = DwcXdciCoreIssueEpCmd (
> +             LocalCoreHandle,
> +             EpNum,
> +             EPCMD_START_XFER,
> +             &EpCmdParams
> +             );
> +
> +  //
> +  // Save new resource index for this transfer
> +  //
> +  LocalCoreHandle->EpHandles[EpNum].CurrentXferRscIdx = ((UsbRegRead (BaseAddr, DWC_XDCI_EPCMD_REG(EpNum)) & DWC_XDCI_EPCMD_RES_IDX_MASK) >> DWC_XDCI_EPCMD_RES_IDX_BIT_POS);
> +
> +  return Status;
> +}
> +
> +
> +/**
> +  Interface:
> +  This function is used to receive data on non-EP0 endpoint
> +  @CoreHandle: xDCI controller handle
> +  @EpInfo: Address of structure describing properties of EP
> +  @Buffer: Buffer containing data to transmit
> +  @size: Size of transfer (in bytes)
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +DwcXdciEpRxData (
> +  IN VOID                *CoreHandle,
> +  IN USB_XFER_REQUEST    *XferReq
> +  )
> +{
> +  XDCI_CORE_HANDLE              *LocalCoreHandle = (XDCI_CORE_HANDLE *)CoreHandle;
> +  DWC_XDCI_ENDPOINT_CMD_PARAMS  EpCmdParams;
> +  DWC_XDCI_TRB                  *Trb;
> +  DWC_XDCI_TRB_CONTROL          TrbCtrl;
> +  EFI_STATUS                    Status;
> +  UINT32                        EpNum;
> +  UINT32                        BaseAddr;
> +
> +  if (CoreHandle == NULL) {
> +    DEBUG ((DEBUG_INFO, "DwcXdciEpRxData: INVALID handle\n"));
> +    return EFI_DEVICE_ERROR;
> +  }
> +
> +  if (XferReq == NULL) {
> +    DEBUG ((DEBUG_INFO, "DwcXdciEpRxData: INVALID transfer request\n"));
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  BaseAddr = LocalCoreHandle->BaseAddress;
> +
> +  //
> +  // Convert to physical endpoint
> +  //
> +  EpNum = DwcXdciGetPhysicalEpNum (XferReq->EpInfo.EpNum, XferReq->EpInfo.EpDir);
> +
> +  Trb = (LocalCoreHandle->Trbs + (EpNum * DWC_XDCI_TRB_NUM));
> +  DEBUG ((DEBUG_INFO, "(DwcXdciEpRxData)EpNum is %d\n", EpNum));
> +
> +  if (EpNum > 1)
> +    TrbCtrl = TRBCTL_NORMAL;
> +  else
> +    TrbCtrl = TRBCTL_CTRL_DATA_PHASE;
> +
> +  //
> +  // If CheckFlag didn't set to FALSE, means the previous transfer request didn't complete,
> +  // need to wait the previous request done.
> +  //
> +  if (LocalCoreHandle->EpHandles[EpNum].CheckFlag == TRUE) {
> +    return EFI_NOT_READY;
> +  }
> +
> +  LocalCoreHandle->EpHandles[EpNum].CheckFlag = TRUE;
> +
> +  //
> +  // Data phase
> +  //
> +  CopyMem (&(LocalCoreHandle->EpHandles[EpNum].XferHandle), XferReq, sizeof (USB_XFER_REQUEST));
> +
> +  LocalCoreHandle->EpHandles[EpNum].State = USB_EP_STATE_DATA;
> +
> +  LocalCoreHandle->EpHandles[EpNum].Trb = Trb;
> +
> +  DEBUG ((DEBUG_INFO, "(DwcXdciEpRxData)XferReq->XferLen is 0x%x\n", XferReq->XferLen));
> +
> +  Status = DwcXdciCoreInitTrb (
> +             LocalCoreHandle,
> +             Trb,
> +             TrbCtrl,
> +             XferReq->XferBuffer,
> +             XferReq->XferLen
> +             );
> +
> +  if (Status) {
> +    DEBUG ((DEBUG_INFO, "DwcXdciEpRxData: TRB failed\n"));
> +    return Status;
> +  }
> +  //
> +  // Issue a DEPSTRTXFER for EP
> +  // Reset params
> +  //
> +  EpCmdParams.Param0 = EpCmdParams.Param1 = EpCmdParams.Param2 = 0;
> +
> +  //
> +  // Init the lower re-bits for TRB address
> +  //
> +  EpCmdParams.Param1 = (UINT32)(UINTN)Trb;
> +
> +  //
> +  // Issue the command
> +  //
> +  Status = DwcXdciCoreIssueEpCmd (
> +             LocalCoreHandle,
> +             EpNum,
> +             EPCMD_START_XFER,
> +             &EpCmdParams
> +             );
> +
> +  if (Status) {
> +    DEBUG ((DEBUG_INFO, "DwcXdciEpRxData: Failed to start transfer\n"));
> +  }
> +
> +  //
> +  // Save new resource index for this transfer
> +  //
> +  LocalCoreHandle->EpHandles[EpNum].CurrentXferRscIdx = ((UsbRegRead(BaseAddr, DWC_XDCI_EPCMD_REG(EpNum)) & DWC_XDCI_EPCMD_RES_IDX_MASK) >> DWC_XDCI_EPCMD_RES_IDX_BIT_POS);
> +
> +  return Status;
> +}
> +
> +
> +
> +STATIC
> +EFI_STATUS
> +DwcXdciCoreFlushEpFifo (
> +  IN XDCI_CORE_HANDLE    *CoreHandle,
> +  IN UINT32              EpNum
> +  )
> +{
> +  UINT32 BaseAddr;
> +  UINT32 MaxDelayIter = DWC_XDCI_MAX_DELAY_ITERATIONS;
> +  UINT32 fifoNum;
> +  UINT32 Param;
> +
> +  if (CoreHandle == NULL) {
> +    DEBUG ((DEBUG_INFO, "ERROR: DwcXdciCoreFlushEpTxFifo: INVALID handle\n"));
> +    return EFI_DEVICE_ERROR;
> +  }
> +
> +  BaseAddr = CoreHandle->BaseAddress;
> +
> +  //
> +  // Translate to FIFOnum
> +  // NOTE: Assuming this is a Tx EP
> +  //
> +  fifoNum = (EpNum >> 1);
> +
> +  //
> +  // TODO: Currently we are only using TxFIFO 0. Later map these
> +  // Write the FIFO num/dir param for the generic command.
> +  //
> +
> +  Param = UsbRegRead (BaseAddr, DWC_XDCI_DGCMD_PARAM_REG);
> +  Param &= ~(DWC_XDCI_DGCMD_PARAM_TX_FIFO_NUM_MASK | DWC_XDCI_DGCMD_PARAM_TX_FIFO_DIR_MASK);
> +
> +  if ((EpNum & 0x01) != 0) {
> +    Param |= (fifoNum | DWC_XDCI_DGCMD_PARAM_TX_FIFO_DIR_MASK);
> +  } else {
> +    Param |= fifoNum;
> +  }
> +
> +  DEBUG ((DEBUG_INFO, "USB FU Flash: CMD 0x%08x :: Param 0x%08x\n",
> +        (UsbRegRead(BaseAddr, DWC_XDCI_DGCMD_REG) | DWC_XDCI_DGCMD_CMD_SEL_FIFO_FLUSH | DWC_XDCI_DGCMD_CMD_ACTIVE_MASK),
> +        Param));
> +
> +  UsbRegWrite (
> +    BaseAddr,
> +    DWC_XDCI_DGCMD_PARAM_REG,
> +    Param
> +    );
> +
> +  //
> +  // Write the command to flush all FIFOs
> +  //
> +  UsbRegWrite (
> +    BaseAddr,
> +    DWC_XDCI_DGCMD_REG,
> +    (UsbRegRead(BaseAddr, DWC_XDCI_DGCMD_REG) | DWC_XDCI_DGCMD_CMD_SEL_FIFO_FLUSH | DWC_XDCI_DGCMD_CMD_ACTIVE_MASK)
> +    );
> +
> +
> +  //
> +  // Wait until command completes
> +  //
> +  do {
> +    if (!(UsbRegRead(BaseAddr, DWC_XDCI_DGCMD_REG) & DWC_XDCI_DGCMD_CMD_ACTIVE_MASK))
> +      break;
> +    else
> +      gBS->Stall (DWC_XDCI_MAX_DELAY_ITERATIONS);
> +  } while (--MaxDelayIter);
> +
> +  if (!MaxDelayIter) {
> +    DEBUG ((DEBUG_INFO, "Failed to issue Command\n"));
> +    return EFI_DEVICE_ERROR;
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  Interface:
> +  This function is used to cancel a transfer on non-EP0 endpoint
> +  @CoreHandle: xDCI controller handle
> +  @EpInfo: Address of structure describing properties of EP
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +DwcXdciEpCancelTransfer (
> +  IN VOID           *CoreHandle,
> +  IN USB_EP_INFO    *EpInfo
> +  )
> +{
> +  EFI_STATUS  Status = EFI_DEVICE_ERROR;
> +  UINT32      EpNum;
> +
> +  if (CoreHandle == NULL) {
> +    DEBUG ((DEBUG_INFO, "DwcXdciEpCancelTransfer: INVALID handle\n"));
> +    return EFI_DEVICE_ERROR;
> +  }
> +
> +  //
> +  // Get physical EP num
> +  //
> +  EpNum = DwcXdciGetPhysicalEpNum (EpInfo->EpNum, EpInfo->EpDir);
> +  Status = DwcXdciEndXfer(CoreHandle, EpNum);
> +  DwcXdciCoreFlushEpFifo(CoreHandle, EpNum);
> +
> +  return Status;
> +}
> +
> +
> +EFI_STATUS
> +usbProcessDeviceResetDet (
> +  IN XDCI_CORE_HANDLE    *CoreHandle
> +  )
> +{
> +   return DwcXdciProcessDeviceResetDet (CoreHandle);
> +}
> +
> +EFI_STATUS
> +usbProcessDeviceResetDone (
> +  IN XDCI_CORE_HANDLE    *CoreHandle
> +  )
> +{
> +  return DwcXdciProcessDeviceResetDone (CoreHandle);
> +}
> +
> +UINT32
> +UsbGetPhysicalEpNum (
> +  IN UINT32        EndpointNum,
> +  IN USB_EP_DIR    EndpointDir
> +  )
> +{
> +  return DwcXdciGetPhysicalEpNum(
> +                            EndpointNum,
> +                            EndpointDir
> +                            );
> +}
> +
> +
> +EFI_STATUS
> +EFIAPI
> +UsbXdciCoreReinit (
> +  IN VOID                     *CoreHandle
> +  )
> +{
> +  EFI_STATUS                      status = EFI_DEVICE_ERROR;
> +  UINT32                          BaseAddr;
> +  XDCI_CORE_HANDLE                *LocalCoreHandle;
> +  DWC_XDCI_ENDPOINT_CMD_PARAMS    EpCmdParams;
> +  UINT32                          MaxDelayIter = DWC_XDCI_MAX_DELAY_ITERATIONS;
> +  UINT8                           i;
> +
> +  LocalCoreHandle = CoreHandle;
> +
> +  if (CoreHandle == NULL) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  if (LocalCoreHandle == NULL) {
> +    DEBUG ((DEBUG_INFO, "DwcXdciCoreInit: Failed to allocate handle for xDCI\n"));
> +    return EFI_OUT_OF_RESOURCES;
> +  }
> +
> +  BaseAddr = LocalCoreHandle->BaseAddress;
> +
> +  DEBUG ((DEBUG_INFO, "Resetting the USB core\n"));
> +  UsbRegWrite (
> +    BaseAddr,
> +    DWC_XDCI_DCTL_REG,
> +    UsbRegRead (BaseAddr, DWC_XDCI_DCTL_REG) | DWC_XDCI_DCTL_CSFTRST_MASK
> +    );
> +
> +  //
> +  // Wait until core soft reset completes
> +  //
> +  do {
> +    if (!(UsbRegRead (BaseAddr, DWC_XDCI_DCTL_REG) & DWC_XDCI_DCTL_CSFTRST_MASK)) {
> +      break;
> +    } else {
> +      gBS->Stall (DWC_XDCI_MAX_DELAY_ITERATIONS);
> +    }
> +  } while (--MaxDelayIter);
> +
> +  if (!MaxDelayIter) {
> +    DEBUG ((DEBUG_INFO, "Failed to reset device controller\n"));
> +    return EFI_DEVICE_ERROR;
> +  }
> +
> +  DEBUG ((DEBUG_INFO, "USB core has been reset\n"));
> +
> +  LocalCoreHandle->DevState = UsbDevStateDefault;
> +
> +  //
> +  // Clear KeepConnect bit so we can allow disconnect and
> +  // re-connect. Stay in RX_DETECT state
> +  //
> +  UsbRegWrite (
> +    BaseAddr,
> +    DWC_XDCI_DCTL_REG,
> +    UsbRegRead (BaseAddr, DWC_XDCI_DCTL_REG) &
> +    (~DWC_XDCI_DCTL_KEEP_CONNECT_MASK) &
> +    ((~DWC_XDCI_DCTL_STATE_CHANGE_REQ_MASK) |
> +    (DWC_XDCI_DCTL_STATE_CHANGE_REQ_RX_DETECT << DWC_XDCI_DCTL_STATE_CHANGE_REQ_BIT_POS))
> +    );
> +
> +  DEBUG ((DEBUG_INFO, "Device controller Synopsys ID: %x\n", UsbRegRead (BaseAddr, DWC_XDCI_GSNPSID_REG)));
> +  DEBUG ((DEBUG_INFO, "Default value of xDCI GSBUSCFG0 and GSBUSCFG1: %x, %x\n",
> +          UsbRegRead (BaseAddr, DWC_XDCI_GSBUSCFG0_REG),
> +          UsbRegRead (BaseAddr, DWC_XDCI_GSBUSCFG1_REG)));
> +
> +  DEBUG ((DEBUG_INFO, "Default value of xDCI GTXTHRCFG and GRXTHRCFG: %x, %x\n",
> +          UsbRegRead (BaseAddr, DWC_XDCI_GTXTHRCFG_REG),
> +          UsbRegRead (BaseAddr, DWC_XDCI_GRXTHRCFG_REG)));
> +
> +  //
> +  // Clear ULPI auto-resume bit
> +  //
> +  UsbRegWrite (
> +    BaseAddr,
> +    DWC_XDCI_GUSB2PHYCFG_REG (0),
> +    (UsbRegRead (BaseAddr, DWC_XDCI_GUSB2PHYCFG_REG (0)) & ~DWC_XDCI_GUSB2PHYCFG_ULPI_AUTO_RESUME_MASK)
> +    );
> +
> +  DEBUG ((DEBUG_INFO, "Default value of xDCI GUSB2PHYCFG and GUSB3PIPECTL: %x, %x\n",
> +          UsbRegRead (BaseAddr, DWC_XDCI_GUSB2PHYCFG_REG (0)),
> +          UsbRegRead (BaseAddr, DWC_XDCI_GUSB3PIPECTL_REG (0))));
> +
> +  //
> +  // Only one RxFIFO
> +  //
> +  DEBUG ((DEBUG_INFO, "Default value of DWC_XDCI_GRXFIFOSIZ: %x\n",
> +          UsbRegRead (BaseAddr, DWC_XDCI_GRXFIFOSIZ_REG (0))));
> +
> +  for (i = 0; i < DWC_XDCI_MAX_ENDPOINTS; i++) {
> +    DEBUG ((DEBUG_INFO, "Default value of xDCI DWC_XDCI_GTXFIFOSIZ %d: %x\n",
> +            i, UsbRegRead (BaseAddr, DWC_XDCI_GTXFIFOSIZ_REG (i))));
> +  }
> +
> +  //
> +  // TODO: Need to check if TxFIFO should start where RxFIFO ends
> +  // or default is correct i.e. TxFIFO starts at 0 just like RxFIFO
> +  //
> +
> +  //
> +  // Allocate and Initialize Event Buffers
> +  //
> +  LocalCoreHandle->MaxDevIntLines = ((UsbRegRead (BaseAddr, DWC_XDCI_GHWPARAMS1_REG) &
> +                                           DWC_XDCI_GHWPARAMS1_NUM_INT_MASK) >>
> +                                           DWC_XDCI_GHWPARAMS1_NUM_INT_BIT_POS);
> +
> +  DEBUG ((DEBUG_INFO, "Max dev int lines: %d\n", LocalCoreHandle->MaxDevIntLines));
> +  //
> +  // One event Buffer per interrupt line.
> +  //  Need to align it to size of event Buffer
> +  //  Buffer needs to be big enough. Otherwise the core
> +  //  won't operate
> +  //
> +  LocalCoreHandle->AlignedEventBuffers = (DWC_XDCI_EVENT_BUFFER *)
> +                                             ((UINT32)(UINTN)(LocalCoreHandle->EventBuffers) +
> +                                             ((sizeof (DWC_XDCI_EVENT_BUFFER) * DWC_XDCI_MAX_EVENTS_PER_BUFFER) -
> +                                             (((UINT32)(UINTN)(LocalCoreHandle->EventBuffers)) %
> +                                             (sizeof (DWC_XDCI_EVENT_BUFFER) * DWC_XDCI_MAX_EVENTS_PER_BUFFER))));
> +
> +  for (i = 0; i < LocalCoreHandle->MaxDevIntLines; i++) {
> +    UsbRegWrite (
> +      BaseAddr,
> +      DWC_XDCI_GEVNTADR_REG (i),
> +      (UINT32)(UINTN)(LocalCoreHandle->AlignedEventBuffers + i * sizeof(DWC_XDCI_EVENT_BUFFER) * DWC_XDCI_MAX_EVENTS_PER_BUFFER)
> +      );
> +
> +    //
> +    // Clear High 32bit address register, GEVNTADR register is 64-bit register
> +    // default is 0xffffffffffffffff
> +    //
> +    UsbRegWrite (BaseAddr, DWC_XDCI_GEVNTADR_REG (i) + 4, 0x00000000);
> +
> +    LocalCoreHandle->CurrentEventBuffer = LocalCoreHandle->AlignedEventBuffers;
> +    //
> +    // Write size and clear the mask
> +    //
> +    UsbRegWrite (
> +      BaseAddr,
> +      DWC_XDCI_EVNTSIZ_REG (i),
> +      sizeof (DWC_XDCI_EVENT_BUFFER) * DWC_XDCI_MAX_EVENTS_PER_BUFFER
> +      );
> +
> +    //
> +    // Write 0 to the event count register as the last step
> +    // for event configuration
> +    //
> +    UsbRegWrite (BaseAddr, DWC_XDCI_EVNTCOUNT_REG (i), 0);
> +
> +    DEBUG ((DEBUG_INFO, "Value of xDCI Event Buffer %d: %x, Size: %x, Count: %x\n",
> +                        i,
> +                        UsbRegRead (BaseAddr, DWC_XDCI_GEVNTADR_REG (i)),
> +                        UsbRegRead (BaseAddr, DWC_XDCI_EVNTSIZ_REG (i)),
> +                        UsbRegRead (BaseAddr, DWC_XDCI_EVNTCOUNT_REG (i))));
> +  }
> +
> +    //
> +    // Program Global Control Register to disable scaledown,
> +    // disable clock gating
> +    //
> +    UsbRegWrite (
> +      BaseAddr,
> +      DWC_XDCI_GCTL_REG,
> +      ((UsbRegRead(BaseAddr, DWC_XDCI_GCTL_REG) &
> +                    ~(DWC_XDCI_GCTL_SCALE_DOWN_MODE_MASK + DWC_XDCI_GCTL_RAMCLKSEL_MASK + DWC_XDCI_GCTL_DISABLE_SCRAMB_MASK)) |
> +                    DWC_XDCI_GCTL_DISABLE_CLK_GATING_MASK |
> +                    (DWC_XDCI_GCTL_PRT_CAP_DEVICE << DWC_XDCI_GCTL_PRT_CAP_DIR_BIT_POS)));
> +
> +    DEBUG ((DEBUG_INFO, "Setup value of xDCI DWC_XDCI_GCTL_REG: 0x%x\n", UsbRegRead (BaseAddr, DWC_XDCI_GCTL_REG)));
> +
> +
> +  //
> +  // TODO: Program desired Speed and set LPM capable
> +  // We will do this when SuperSpeed works. For now,
> +  // force into High-Speed mode to aVOID anyone trying this
> +  // on Super Speed port
> +  //
> +#ifdef SUPPORT_SUPER_SPEED
> +  UsbRegWrite (
> +    BaseAddr,
> +    DWC_XDCI_DCFG_REG,
> +    (UsbRegRead (BaseAddr, DWC_XDCI_DCFG_REG) & ~DWC_XDCI_DCFG_DESIRED_DEV_SPEED_MASK) | LocalCoreHandle->DesiredSpeed
> +    );
> +#else
> +  UsbRegWrite (
> +    BaseAddr,
> +    DWC_XDCI_DCFG_REG,
> +    (UsbRegRead (BaseAddr, DWC_XDCI_DCFG_REG) & ~DWC_XDCI_DCFG_DESIRED_DEV_SPEED_MASK) | DWC_XDCI_DCFG_DESIRED_HS_SPEED
> +    );
> +#endif
> +
> +  DEBUG ((DEBUG_INFO, "Setup value of xDCI DWC_XDCI_DCFG_REG: 0x%x\n", UsbRegRead (BaseAddr, DWC_XDCI_DCFG_REG)));
> +  DEBUG ((DEBUG_INFO, "Setup value of xDCI DWC_XDCI_DSTS_REG: 0x%x\n", UsbRegRead (BaseAddr, DWC_XDCI_DSTS_REG)));
> +
> +  //
> +  // Enable Device Interrupt Events
> +  //
> +  UsbRegWrite (
> +    BaseAddr,
> +    DWC_XDCI_DEVTEN_REG,
> +    DWC_XDCI_DEVTEN_DEVICE_INTS
> +    );
> +
> +  //
> +  // Program the desired role
> +  //
> +  UsbRegWrite (
> +    BaseAddr,
> +    DWC_XDCI_GCTL_REG,
> +    (UsbRegRead (BaseAddr, DWC_XDCI_GCTL_REG) & ~DWC_XDCI_GCTL_PRT_CAP_DIR_MASK) | (LocalCoreHandle->Role << DWC_XDCI_GCTL_PRT_CAP_DIR_BIT_POS)
> +    );
> +
> +  //
> +  // Clear USB2 suspend for start new config command
> +  //
> +  UsbRegWrite (
> +    BaseAddr,
> +    DWC_XDCI_GUSB2PHYCFG_REG (0),
> +    (UsbRegRead (BaseAddr, DWC_XDCI_GUSB2PHYCFG_REG(0)) & ~DWC_XDCI_GUSB2PHYCFG_SUSPEND_PHY_MASK)
> +    );
> +  //
> +  // Clear USB3 suspend for start new config command
> +  //
> +  UsbRegWrite (
> +    BaseAddr,
> +    DWC_XDCI_GUSB3PIPECTL_REG (0),
> +    (UsbRegRead (BaseAddr, DWC_XDCI_GUSB3PIPECTL_REG(0)) & ~DWC_XDCI_GUSB3PIPECTL_SUSPEND_PHY_MASK)
> +    );
> +  //
> +  // Issue DEPSTARTCFG command for EP0
> +  //
> +  status = DwcXdciCoreInitEpCmdParams (
> +             LocalCoreHandle,
> +             &LocalCoreHandle->EpHandles[0].EpInfo,
> +             DWC_XDCI_PARAM0_SET_EP_CFG_ACTN_NONE,
> +             EPCMD_START_NEW_CONFIG,
> +             &EpCmdParams
> +             );
> +
> +  if (status) {
> +    DEBUG ((DEBUG_INFO, "DwcXdciCoreInit: Failed to init params for START_NEW_CONFIG EP command on xDCI\n"));
> +    return status;
> +  }
> +
> +  //
> +  // Issue the command
> +  //
> +  status = DwcXdciCoreIssueEpCmd (
> +             LocalCoreHandle,
> +             0,
> +             EPCMD_START_NEW_CONFIG,
> +             &EpCmdParams
> +             );
> +
> +  if (status) {
> +    DEBUG ((DEBUG_INFO, "DwcXdciCoreInit: Failed to issue START_NEW_CONFIG EP command on xDCI\n"));
> +    return status;
> +  }
> +
> +  //
> +  // Issue DEPCFG command for EP0
> +  //
> +  status = DwcXdciCoreInitEpCmdParams (
> +             LocalCoreHandle,
> +             &LocalCoreHandle->EpHandles[0].EpInfo,
> +             DWC_XDCI_PARAM0_SET_EP_CFG_ACTN_INIT_STATE,
> +             EPCMD_SET_EP_CONFIG,
> +             &EpCmdParams
> +             );
> +
> +  if (status) {
> +    DEBUG ((DEBUG_INFO, "DwcXdciCoreInit: Failed to init params for SET_EP_CONFIG command on xDCI for EP0\n"));
> +    return status;
> +  }
> +
> +  //
> +  // Issue the command
> +  //
> +  status = DwcXdciCoreIssueEpCmd (
> +             LocalCoreHandle,
> +             0,
> +             EPCMD_SET_EP_CONFIG,
> +             &EpCmdParams);
> +
> +  if (status) {
> +    DEBUG ((DEBUG_INFO, "DwcXdciCoreInit: Failed to issue SET_EP_CONFIG command on xDCI for EP0\n"));
> +    return status;
> +  }
> +
> +  //
> +  // Issue DEPCFG command for EP1
> +  //
> +  status = DwcXdciCoreInitEpCmdParams (
> +             LocalCoreHandle,
> +             &LocalCoreHandle->EpHandles[1].EpInfo,
> +             DWC_XDCI_PARAM0_SET_EP_CFG_ACTN_INIT_STATE,
> +             EPCMD_SET_EP_CONFIG,
> +             &EpCmdParams
> +             );
> +
> +  if (status) {
> +    DEBUG ((DEBUG_INFO, "DwcXdciCoreInit: Failed to init params for SET_EP_CONFIG command on xDCI for EP1\n"));
> +    return status;
> +  }
> +
> +  //
> +  // Issue the command
> +  //
> +  status = DwcXdciCoreIssueEpCmd (
> +             LocalCoreHandle,
> +             1,
> +             EPCMD_SET_EP_CONFIG,
> +             &EpCmdParams
> +             );
> +
> +  if (status) {
> +    DEBUG ((DEBUG_INFO, "DwcXdciCoreInit: Failed to issue SET_EP_CONFIG command on xDCI for EP1\n"));
> +    return status;
> +  }
> +
> +  //
> +  // Issue DEPXFERCFG command for EP0
> +  //
> +  status = DwcXdciCoreInitEpCmdParams (
> +             LocalCoreHandle,
> +             &LocalCoreHandle->EpHandles[0].EpInfo,
> +             DWC_XDCI_PARAM0_SET_EP_CFG_ACTN_NONE,
> +             EPCMD_SET_EP_XFER_RES_CONFIG,
> +             &EpCmdParams
> +             );
> +
> +  if (status) {
> +    DEBUG ((DEBUG_INFO, "DwcXdciCoreInit: Failed to init params for EPCMD_SET_EP_XFER_RES_CONFIG command on xDCI for EP0\n"));
> +    return status;
> +  }
> +
> +  //
> +  // Issue the command
> +  //
> +  status = DwcXdciCoreIssueEpCmd (
> +             LocalCoreHandle,
> +             0,
> +             EPCMD_SET_EP_XFER_RES_CONFIG,
> +             &EpCmdParams
> +             );
> +
> +  if (status) {
> +    DEBUG ((DEBUG_INFO, "DwcXdciCoreInit: Failed to issue EPCMD_SET_EP_XFER_RES_CONFIG command on xDCI for EP0\n"));
> +    return status;
> +  }
> +
> +  //
> +  // Issue DEPXFERCFG command for EP1
> +  //
> +  status = DwcXdciCoreInitEpCmdParams (
> +             LocalCoreHandle,
> +             &LocalCoreHandle->EpHandles[1].EpInfo,
> +             DWC_XDCI_PARAM0_SET_EP_CFG_ACTN_NONE,
> +             EPCMD_SET_EP_XFER_RES_CONFIG,
> +             &EpCmdParams
> +             );
> +
> +  if (status) {
> +    DEBUG ((DEBUG_INFO, "DwcXdciCoreInit: Failed to init params for EPCMD_SET_EP_XFER_RES_CONFIG command on xDCI for EP1\n"));
> +    return status;
> +  }
> +
> +  //
> +  // Issue the command
> +  //
> +  status = DwcXdciCoreIssueEpCmd (
> +             LocalCoreHandle,
> +             1,
> +             EPCMD_SET_EP_XFER_RES_CONFIG,
> +             &EpCmdParams
> +             );
> +
> +  if (status) {
> +    DEBUG ((DEBUG_INFO, "DwcXdciCoreInit: Failed to issue EPCMD_SET_EP_XFER_RES_CONFIG command on xDCI for EP1\n"));
> +    return status;
> +  }
> +
> +  //
> +  // Prepare a Buffer for SETUP packet
> +  //
> +  LocalCoreHandle->Trbs = (DWC_XDCI_TRB *)((UINTN)
> +                            LocalCoreHandle->UnalignedTrbs +
> +                            (UINTN)(DWC_XDCI_TRB_BYTE_ALIGNMENT -
> +                            ((UINT32)(UINTN)LocalCoreHandle->UnalignedTrbs %
> +                            DWC_XDCI_TRB_BYTE_ALIGNMENT)));
> +
> +  DEBUG ((DEBUG_INFO, "(DwcXdciCoreInit)@@@@@@@@@ unalignedTrbs address is 0x%x\n", LocalCoreHandle->UnalignedTrbs));
> +  DEBUG ((DEBUG_INFO, "(DwcXdciCoreInit)@@@@@@@@@ TRB address is 0x%x\n", LocalCoreHandle->Trbs));
> +
> +  //
> +  // Allocate Setup Buffer that is 8-byte aligned
> +  //
> +  LocalCoreHandle->AlignedSetupBuffer = LocalCoreHandle->DefaultSetupBuffer +
> +                                            (DWC_XDCI_SETUP_BUFF_SIZE -
> +                                            ((UINT32)(UINTN)(LocalCoreHandle->DefaultSetupBuffer) % DWC_XDCI_SETUP_BUFF_SIZE));
> +
> +  //
> +  // Aligned Buffer for status phase
> +  //
> +  LocalCoreHandle->AlignedMiscBuffer = LocalCoreHandle->MiscBuffer +
> +                                           (DWC_XDCI_SETUP_BUFF_SIZE -
> +                                           ((UINT32)(UINTN)(LocalCoreHandle->AlignedMiscBuffer) % DWC_XDCI_SETUP_BUFF_SIZE));
> +
> +  //
> +  // We will queue SETUP request when we see bus reset
> +  //
> +
> +  //
> +  // Enable Physical Endpoints 0
> +  //
> +  UsbRegWrite (
> +    BaseAddr,
> +    DWC_XDCI_EP_DALEPENA_REG,
> +    UsbRegRead (BaseAddr, DWC_XDCI_EP_DALEPENA_REG) | (1 << 0)
> +    );
> +
> +  //
> +  // Enable Physical Endpoints 1
> +  //
> +  UsbRegWrite (
> +    BaseAddr,
> +    DWC_XDCI_EP_DALEPENA_REG,
> +    UsbRegRead (BaseAddr, DWC_XDCI_EP_DALEPENA_REG) | (1 << 1)
> +    );
> +
> +  DEBUG ((DEBUG_INFO, "Default value of xDCI DWC_XDCI_DEVTEN_REG: 0x%x\n", UsbRegRead (BaseAddr, DWC_XDCI_DEVTEN_REG)));
> +  return status;
> +
> +
> +}
> +
> +
> +EFI_STATUS
> +UsbXdciCoreFlushEpFifo (
> +  IN VOID           *CoreHandle,
> +  IN USB_EP_INFO    *EpInfo
> +  )
> +{
> +  EFI_STATUS  Status = EFI_DEVICE_ERROR;
> +  UINT32      EpNum;
> +
> +  if (CoreHandle == NULL) {
> +    DEBUG ((DEBUG_INFO, "DwcXdciEpCancelTransfer: INVALID handle\n"));
> +    return EFI_DEVICE_ERROR;
> +  }
> +
> +  //
> +  // Get physical EP num
> +  //
> +  EpNum = DwcXdciGetPhysicalEpNum (EpInfo->EpNum, EpInfo->EpDir);
> +  DwcXdciCoreFlushEpFifo(CoreHandle, EpNum);
> +
> +  return Status;
> +}
> diff --git a/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciDWC.h b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciDWC.h
> new file mode 100644
> index 0000000000..9c1b2d1d85
> --- /dev/null
> +++ b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciDWC.h
> @@ -0,0 +1,741 @@
> +/** @file
> +  Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR>
> +
> +  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.
> +
> +**/
> +
> +#ifndef _XDCI_DWC_H_
> +#define _XDCI_DWC_H_
> +
> +#include "XdciCommon.h"
> +#include "XdciDevice.h"
> +
> +#define DWC_XDCI_MAX_ENDPOINTS                             (16)
> +#define DWC_XDCI_SS_CTRL_EP_MPS                            (512)
> +#define DWC_XDCI_HS_CTRL_EP_MPS                            (64)
> +#define DWC_XDCI_FS_CTRL_EP_MPS                            (64)
> +#define DWC_XDCI_LS_CTRL_EP_MPS                            (8)
> +#define DWC_XDCI_SS_CTRL_BUF_SIZE                          (512)
> +#define DWC_XDCI_SETUP_BUFF_SIZE                           (8)
> +#define DWC_XDCI_MAX_EVENTS_PER_BUFFER                     (16)
> +#define DWC_XDCI_TRB_BYTE_ALIGNMENT                        (16)
> +#define DWC_XDCI_DEFAULT_TX_FIFO_SIZE                      (1024)
> +#define DWC_XDCI_TRB_NUM                                   (32)
> +#define DWC_XDCI_MASK                                      (DWC_XDCI_TRB_NUM - 1)
> +
> +#define DWC_XDCI_MAX_DELAY_ITERATIONS                      (1000)
> +
> +#define DWC_XDCI_GSBUSCFG0_REG                             (0xC100)
> +#define DWC_XDCI_GSBUSCFG1_REG                             (0xC104)
> +#define DWC_XDCI_GTXTHRCFG_REG                             (0xC108)
> +#define DWC_XDCI_GRXTHRCFG_REG                             (0xC10C)
> +
> +//
> +// Global Control Register and bit definitions
> +//
> +#define DWC_XDCI_GCTL_REG                                  (0xC110)
> +#define DWC_XDCI_GCTL_PWRDNSCALE_MASK                      (0xFFF80000)
> +#define DWC_XDCI_GCTL_PWRDNSCALE_VAL                       (0x13880000)
> +#define DWC_XDCI_GCTL_U2RSTECN_MASK                        (0x00010000)
> +#define DWC_XDCI_GCTL_PRT_CAP_DIR_MASK                     (0x00003000)
> +#define DWC_XDCI_GCTL_PRT_CAP_DIR_BIT_POS                  (12)
> +#define DWC_XDCI_GCTL_PRT_CAP_HOST                         (1)
> +#define DWC_XDCI_GCTL_PRT_CAP_DEVICE                       (2)
> +#define DWC_XDCI_GCTL_PRT_CAP_OTG                          (3)
> +#define DWC_XDCI_GCTL_RAMCLKSEL_MASK                       (0x000000C0)
> +#define DWC_XDCI_GCTL_SCALE_DOWN_MODE_MASK                 (0x00000030)
> +#define DWC_XDCI_GCTL_DISABLE_CLK_GATING_MASK              (0x00000001)
> +#define DWC_XDCI_GCTL_DISABLE_SCRAMB_MASK                  (0x00000008)
> +
> +#define DWC_XDCI_GSTS_REG                                  (0xC118)
> +#define DWC_XDCI_GSNPSID_REG                               (0xC120)
> +#define DWC_XDCI_GGPIO_REG                                 (0xC124)
> +#define DWC_XDCI_GUID_REG                                  (0xC128)
> +#define DWC_XDCI_GUCTL_REG                                 (0xC12C)
> +#define DWC_XDCI_GBUSERRADDR                               (0xC130)
> +
> +//
> +// Global Hardware Parameters Registers
> +//
> +#define DWC_XDCI_GHWPARAMS0_REG                            (0xC140)
> +#define DWC_XDCI_GHWPARAMS1_REG                            (0xC144)
> +#define DWC_XDCI_GHWPARAMS1_NUM_INT_MASK                   (0x1F8000)
> +#define DWC_XDCI_GHWPARAMS1_NUM_INT_BIT_POS                (15)
> +
> +#define DWC_XDCI_GHWPARAMS2_REG                            (0xC148)
> +#define DWC_XDCI_GHWPARAMS3_REG                            (0xC14C)
> +#define DWC_XDCI_GHWPARAMS4_REG                            (0xC150)
> +#define DWC_XDCI_GHWPARAMS4_CACHE_TRBS_PER_XFER_MASK       (0x0000003F)
> +#define DWC_XDCI_GHWPARAMS5_REG                            (0xC154)
> +#define DWC_XDCI_GHWPARAMS6_REG                            (0xC158)
> +#define DWC_XDCI_GHWPARAMS7_REG                            (0xC15C)
> +#define DWC_XDCI_GHWPARAMS8_REG                            (0xC600)
> +
> +#define DWC_XDCI_GDBGFIFOSPACE_REG                         (0xC160)
> +
> +#define DWC_XDCI_GUSB2PHYCFG_REG(n)                        (0xC200 + (n << 2))
> +#define DWC_XDCI_GUSB2PHYCFG_ULPI_AUTO_RESUME_MASK         (0x00008000)
> +#define DWC_XDCI_GUSB2PHYCFG_SUSPEND_PHY_MASK              (0x00000040)
> +
> +#define DWC_XDCI_GUSB3PIPECTL_REG(n)                       (0xC2C0 + (n << 2))
> +#define DWC_XDCI_GUSB3PIPECTL_SUSPEND_PHY_MASK             (0x00020000)
> +
> +#define DWC_XDCI_GTXFIFOSIZ_REG(n)                         (0xC300 + (n << 2))
> +#define DWC_XDCI_GTXFIFOSIZ_START_ADDRESS_MASK             (0xFFFF0000)
> +#define DWC_XDCI_GTXFIFOSIZ_START_ADDRESS_BIT_POS          (16)
> +#define DWC_XDCI_GRXFIFOSIZ_REG(n)                         (0xC380 + (n << 2))
> +
> +//
> +// Global Event Buffer Registers
> +//
> +#define DWC_XDCI_GEVNTADR_REG(n)                           (0xC400 + (n << 4))
> +#define DWC_XDCI_EVNTSIZ_REG(n)                            (0xC408 + (n << 4))
> +#define DWC_XDCI_EVNTSIZ_MASK                              (0x0000FFFF)
> +#define DWC_XDCI_EVNT_INTR_MASK                            (0x80000000)
> +#define DWC_XDCI_EVNTCOUNT_REG(n)                          (0xC40C + (n << 4))
> +#define DWC_XDCI_EVNTCOUNT_MASK                            (0x0000FFFF)
> +
> +//
> +// Device Configuration Register and Bit Definitions
> +//
> +#define DWC_XDCI_DCFG_REG                                  (0xC700)
> +#define DWC_XDCI_DCFG_LPM_CAPABLE_MASK                     (0x00400000)
> +#define DWC_XDCI_DCFG_DEV_ADDRESS_MASK                     (0x000003F8)
> +#define DWC_XDCI_DCFG_DEV_ADDRESS_BIT_POS                  (3)
> +#define DWC_XDCI_DCFG_DESIRED_DEV_SPEED_MASK               (0x00000007)
> +#define DWC_XDCI_DCFG_DESIRED_SS_SPEED                     (0x00000004)
> +#define DWC_XDCI_DCFG_DESIRED_FS_SPEED                     (0x00000001)
> +#define DWC_XDCI_DCFG_DESIRED_HS_SPEED                     (0x00000000)
> +
> +//
> +// Device Control Register
> +//
> +#define DWC_XDCI_DCTL_REG                                  (0xC704)
> +#define DWC_XDCI_DCTL_RUN_STOP_MASK                        (0x80000000)
> +#define DWC_XDCI_DCTL_RUN_STOP_BIT_POS                     (31)
> +#define DWC_XDCI_DCTL_CSFTRST_MASK                         (0x40000000)
> +#define DWC_XDCI_DCTL_CSFTRST_BIT_POS                      (30)
> +#define DWC_XDCI_DCTL_KEEP_CONNECT_MASK                    (0x00080000)
> +#define DWC_XDCI_DCTL_KEEP_CONNECT_BIT_POS                 (19)
> +#define DWC_XDCI_DCTL_CSFTRST_BIT_POS                      (30)
> +#define DWC_XDCI_DCTL_STATE_CHANGE_REQ_MASK                (0x000001E0)
> +#define DWC_XDCI_DCTL_STATE_CHANGE_REQ_BIT_POS             (5)
> +#define DWC_XDCI_DCTL_STATE_CHANGE_REQ_NO_ACTION           (1)
> +#define DWC_XDCI_DCTL_STATE_CHANGE_REQ_SS_DISABLED         (4)
> +#define DWC_XDCI_DCTL_STATE_CHANGE_REQ_RX_DETECT           (5)
> +#define DWC_XDCI_DCTL_STATE_CHANGE_REQ_SS_INACTIVE         (6)
> +#define DWC_XDCI_DCTL_STATE_CHANGE_REQ_RECOVERY            (8)
> +#define DWC_XDCI_DCTL_STATE_CHANGE_REQ_COMPLIANCE          (10)
> +#define DWC_XDCI_DCTL_STATE_CHANGE_REQ_REMOTE_WAKEUP       (8)
> +
> +//
> +// Device Event Enable Register
> +//
> +#define DWC_XDCI_DEVTEN_REG                                (0xC708)
> +#define DWC_XDCI_DEVTEN_DISCONN_DET_EN_MASK                (0x00000001)
> +#define DWC_XDCI_DEVTEN_RESET_DET_EN_MASK                  (0x00000002)
> +#define DWC_XDCI_DEVTEN_CONN_DONE_DET_EN_MASK              (0x00000004)
> +#define DWC_XDCI_DEVTEN_LINK_STATE_CHANGE_DET_EN_MASK      (0x00000008)
> +#define DWC_XDCI_DEVTEN_RESUME_WAKEUP_DET_EN_MASK          (0x00000010)
> +#define DWC_XDCI_DEVTEN_HIBERNATION_REQ_EN_MASK            (0x00000020)
> +#define DWC_XDCI_DEVTEN_U3L2L1_DET_EN_MASK                 (0x00000040)
> +#define DWC_XDCI_DEVTEN_SOF_DET_EN_MASK                    (0x00000080)
> +#define DWC_XDCI_DEVTEN_ERRATIC_ERR_DET_EN_MASK            (0x00000200)
> +#define DWC_XDCI_DEVTEN_VNDR_DEV_TST_RX_DET_EN_MASK        (0x00001000)
> +
> +#define DWC_XDCI_DEVTEN_DEVICE_INTS                        (DWC_XDCI_DEVTEN_DISCONN_DET_EN_MASK | \
> +        DWC_XDCI_DEVTEN_RESET_DET_EN_MASK | DWC_XDCI_DEVTEN_CONN_DONE_DET_EN_MASK | \
> +        DWC_XDCI_DEVTEN_LINK_STATE_CHANGE_DET_EN_MASK | DWC_XDCI_DEVTEN_RESUME_WAKEUP_DET_EN_MASK | \
> +        DWC_XDCI_DEVTEN_HIBERNATION_REQ_EN_MASK | DWC_XDCI_DEVTEN_U3L2L1_DET_EN_MASK | \
> +        DWC_XDCI_DEVTEN_ERRATIC_ERR_DET_EN_MASK)
> +
> +#define DWC_XDCI_EVENT_BUFF_BULK_STREAM_ID_MASK            (0xFFFF0000)
> +#define DWC_XDCI_EVENT_BUFF_ISOCH_UFRAME_NUM_MASK          (0xFFFF0000)
> +#define DWC_XDCI_EVENT_BUFF_EP_CMD_TYPE_MASK               (0x0F000000)
> +#define DWC_XDCI_EVENT_BUFF_EP_XFER_RES_INDEX_MASK         (0x007F0000)
> +#define DWC_XDCI_EVENT_BUFF_EP_XFER_ACTIVE_MASK            (0x00008000)
> +#define DWC_XDCI_EVENT_BUFF_EP_CTRL_DATA_REQ_MASK          (0x00001000)
> +#define DWC_XDCI_EVENT_BUFF_EP_CTRL_STATUS_REQ_MASK        (0x00002000)
> +#define DWC_XDCI_EVENT_BUFF_EP_LST_MASK                    (0x00008000)
> +#define DWC_XDCI_EVENT_BUFF_EP_MISSED_ISOCH_MASK           (0x00008000)
> +#define DWC_XDCI_EVENT_BUFF_EP_IOC_MASK                    (0x00004000)
> +#define DWC_XDCI_EVENT_BUFF_EP_LAST_PKT_MASK               (0x00002000)
> +#define DWC_XDCI_EVENT_BUFF_EP_STREAM_NOT_FND_MASK         (0x00002000)
> +#define DWC_XDCI_EVENT_BUFF_EP_STREAM_FND_MASK             (0x00001000)
> +#define DWC_XDCI_EVENT_BUFF_EP_ERR_NO_RES_MASK             (0x00001000)
> +#define DWC_XDCI_EVENT_BUFF_EP_INVALID_RES_MASK            (0x00001000)
> +
> +#define DWC_XDCI_EVENT_BUFF_EP_EVENT_MASK                  (0x000003C0)
> +#define DWC_XDCI_EVENT_BUFF_EP_EVENT_BIT_POS               (6)
> +#define DWC_XDCI_EVENT_BUFF_EP_XFER_CMPLT                  (1)
> +#define DWC_XDCI_EVENT_BUFF_EP_XFER_IN_PROGRESS            (2)
> +#define DWC_XDCI_EVENT_BUFF_EP_XFER_NOT_READY              (3)
> +#define DWC_XDCI_EVENT_BUFF_EP_STREAM_EVENT                (6)
> +#define DWC_XDCI_EVENT_BUFF_EP_CMD_CMPLT                   (7)
> +
> +#define DWC_XDCI_EVENT_BUFF_EP_NUM_MASK                    (0x0000003E)
> +#define DWC_XDCI_EVENT_BUFF_EP_NUM_BIT_POS                 (1)
> +
> +#define DWC_XDCI_EVENT_BUFF_EP_EVENT_STATUS_MASK           (0x0000F000)
> +
> +
> +#define DWC_XDCI_EVENT_BUFF_DEV_HIRD_MASK                  (0x01E00000)
> +#define DWC_XDCI_EVENT_BUFF_DEV_HIRD_BIT_POS               (21)
> +#define DWC_XDCI_EVENT_BUFF_DEV_SS_EVENT_MASK              (0x00100000)
> +#define DWC_XDCI_EVENT_BUFF_DEV_LINK_STATE_MASK            (0x000F0000)
> +#define DWC_XDCI_EVENT_BUFF_DEV_LINK_STATE_BIT_POS         (16)
> +
> +#define DWC_XDCI_EVENT_BUFF_DEV_EVT_MASK                   (0x00000F00)
> +#define DWC_XDCI_EVENT_BUFF_DEV_EVT_BIT_POS                (8)
> +#define DWC_XDCI_EVENT_BUFF_DEV_TST_LMP_RX_EVENT           (12)
> +#define DWC_XDCI_EVENT_BUFF_DEV_BUFF_OVFL_EVENT            (11)
> +#define DWC_XDCI_EVENT_BUFF_DEV_CMD_CMPLT_EVENT            (10)
> +#define DWC_XDCI_EVENT_BUFF_DEV_ERRATIC_ERR_EVENT          (9)
> +#define DWC_XDCI_EVENT_BUFF_DEV_SOF_EVENT                  (7)
> +#define DWC_XDCI_EVENT_BUFF_DEV_HBRNTN_REQ_EVENT           (5)
> +#define DWC_XDCI_EVENT_BUFF_DEV_WKUP_EVENT                 (4)
> +#define DWC_XDCI_EVENT_BUFF_DEV_STATE_CHANGE_EVENT         (3)
> +#define DWC_XDCI_EVENT_BUFF_DEV_CONN_DONE_EVENT            (2)
> +#define DWC_XDCI_EVENT_BUFF_DEV_USB_RESET_EVENT            (1)
> +#define DWC_XDCI_EVENT_BUFF_DEV_DISCONN_EVENT              (0)
> +
> +#define DWC_XDCI_EVENT_DEV_MASK                            (0x00000001)
> +
> +//
> +// Device Status Register and Bit Definitions
> +//
> +#define DWC_XDCI_DSTS_REG                                  (0xC70C)
> +#define DWC_XDCI_DSTS_DEV_CTRL_HALTED_MASK                 (0x00400000)
> +#define DWC_XDCI_DSTS_DEV_CTRL_HALTED_BIT_POS              (22)
> +#define DWC_XDCI_DSTS_CORE_IDLE                            (1 << 23)
> +#define DWC_XDCI_DSTS_CONN_SPEED_MASK                      (0x00000007)
> +#define DWC_XDCI_DSTS_LINK_STATE_MASK                      (0x003C0000)
> +#define DWC_XDCI_DSTS_LINK_STATE_DISCONNECT                (0x00100000)
> +
> +//
> +// Device Generic Command Parameter Register
> +//
> +#define DWC_XDCI_DGCMD_PARAM_REG                           (0xC710)
> +#define DWC_XDCI_DGCMD_PARAM_TX_FIFO_NUM_MASK              (0x0000001F)
> +#define DWC_XDCI_DGCMD_PARAM_TX_FIFO_DIR_MASK              (0x00000020)
> +#define DWC_XDCI_DGCMD_PARAM_TX_FIFO_DIR_BIT_POS           (5)
> +
> +//
> +// Device Generic Command Register
> +//
> +#define DWC_XDCI_DGCMD_REG                                 (0xC714)
> +#define DWC_XDCI_DGCMD_CMD_STATUS_MASK                     (0x00008000)
> +#define DWC_XDCI_DGCMD_CMD_ACTIVE_MASK                     (0x00000400)
> +#define DWC_XDCI_DGCMD_CMD_IOC_MASK                        (0x00000100)
> +#define DWC_XDCI_DGCMD_CMD_TYPE_MASK                       (0x000000FF)
> +#define DWC_XDCI_DGCMD_CMD_SET_PERIODIC_PARAMS             (0x2)
> +#define DWC_XDCI_DGCMD_CMD_SET_SCRATCH_PAD_BUFF_ARR_LO     (0x4)
> +#define DWC_XDCI_DGCMD_CMD_SET_SCRATCH_PAD_BUFF_ARR_HI     (0x5)
> +#define DWC_XDCI_DGCMD_CMD_XMIT_DEVICE_NOTIFICATION        (0x7)
> +#define DWC_XDCI_DGCMD_CMD_SEL_FIFO_FLUSH                  (0x9)
> +#define DWC_XDCI_DGCMD_CMD_ALL_FIFO_FLUSH                  (0xA)
> +#define DWC_XDCI_DGCMD_CMD_SET_EP_NRDY                     (0xC)
> +#define DWC_XDCI_DGCMD_CMD_RUN_SOC_BUS_LPBK                (0x10)
> +
> +//
> +// Device Active USB EP Enable Register
> +//
> +#define DWC_XDCI_EP_DALEPENA_REG                           (0xC720)
> +
> +//
> +// Device Physical EP CMD Param 2 Register. Value is 32-bit
> +//
> +#define DWC_XDCI_EPCMD_PARAM2_REG(n)                       (0xC800 + (n << 4))
> +
> +//
> +// Device Physical EP CMD Param 1 Register. Value is 32-bit
> +//
> +#define DWC_XDCI_EPCMD_PARAM1_REG(n)                       (0xC804 + (n << 4))
> +
> +//
> +// Device Physical EP CMD Param 0 Register. Value is 32-bit
> +//
> +#define DWC_XDCI_EPCMD_PARAM0_REG(n)                       (0xC808 + (n << 4))
> +
> +//
> +// Device Physical EP Command Registers and Bit Definitions
> +//
> +#define DWC_XDCI_EPCMD_REG(n)                              (0xC80C + (n << 4))
> +#define DWC_XDCI_EPCMD_RES_IDX_MASK                        (0x007F0000)
> +#define DWC_XDCI_EPCMD_RES_IDX_BIT_POS                     (16)
> +#define DWC_XDCI_EPCMD_CMDTYPE_MASK                        (0x0000000F)
> +#define DWC_XDCI_EPCMD_SET_EP_CONFIG                       (0x1)
> +#define DWC_XDCI_EPCMD_SET_EP_XFER_RES_CONFIG              (0x2)
> +#define DWC_XDCI_EPCMD_GET_EP_STATE                        (0x3)
> +#define DWC_XDCI_EPCMD_SET_STALL                           (0x4)
> +#define DWC_XDCI_EPCMD_CLEAR_STALL                         (0x5)
> +#define DWC_XDCI_EPCMD_START_XFER                          (0x6)
> +#define DWC_XDCI_EPCMD_UPDATE_XFER                         (0x7)
> +#define DWC_XDCI_EPCMD_END_XFER                            (0x8)
> +#define DWC_XDCI_EPCMD_START_NEW_CONFIG                    (0x9)
> +
> +#define DWC_XDCI_EPCMD_CMD_IOC_MASK                        (0x00000100)
> +#define DWC_XDCI_EPCMD_CMD_ACTIVE_MASK                     (0x00000400)
> +#define DWC_XDCI_EPCMD_HIGH_PRIO_MASK                      (0x00000800)
> +#define DWC_XDCI_EPCMD_FORCE_RM_MASK                       (0x00000800)
> +
> +//
> +// Command status and parameter values same as event status and parameters values
> +//
> +#define DWC_XDCI_EPCMD_CMD_STATUS_MASK                     (0x0000F000)
> +
> +//
> +// Command Params bit masks
> +//
> +#define DWC_XDCI_PARAM1_SET_EP_CFG_FIFO_BASED_MASK         (0x80000000)
> +#define DWC_XDCI_PARAM1_SET_EP_CFG_BULK_BASED_MASK         (0x40000000)
> +#define DWC_XDCI_PARAM1_SET_EP_CFG_EP_NUM_MASK             (0x3C000000)
> +#define DWC_XDCI_PARAM1_SET_EP_CFG_EP_DIR_MASK             (0x02000000)
> +#define DWC_XDCI_PARAM1_SET_EP_CFG_STRM_CAP_MASK           (0x01000000)
> +#define DWC_XDCI_PARAM1_SET_EP_CFG_BINTM1_MASK             (0x00FF0000)
> +#define DWC_XDCI_PARAM1_SET_EP_CFG_BINTM1_BIT_POS          (16)
> +#define DWC_XDCI_PARAM1_SET_EP_CFG_EBC_MASK                (0x00008000)
> +#define DWC_XDCI_PARAM1_SET_EP_CFG_EVT_EN_MASK             (0x00003F00)
> +#define DWC_XDCI_PARAM1_SET_EP_CFG_EVT_EN_BIT_POS          (8)
> +#define DWC_XDCI_PARAM1_SET_EP_CFG_EVT_STRM_MASK           (0x00002000)
> +#define DWC_XDCI_PARAM1_SET_EP_CFG_EVT_XFER_NRDY_MASK      (0x00000400)
> +#define DWC_XDCI_PARAM1_SET_EP_CFG_EVT_XFER_IN_PRG_MASK    (0x00000200)
> +#define DWC_XDCI_PARAM1_SET_EP_CFG_EVT_XFER_CMPLT_MASK     (0x00000100)
> +#define DWC_XDCI_PARAM1_SET_EP_CFG_INTR_NUM_MASK           (0x0000001F)
> +
> +//
> +// CMD 1 param 0
> +//
> +#define DWC_XDCI_PARAM0_SET_EP_CFG_ACTN_MASK               (0xC0000000)
> +#define DWC_XDCI_PARAM0_SET_EP_CFG_ACTN_BIT_POS            (30)
> +#define DWC_XDCI_PARAM0_SET_EP_CFG_ACTN_INIT_STATE         (0)
> +#define DWC_XDCI_PARAM0_SET_EP_CFG_ACTN_RESTORE_ST         (1)
> +#define DWC_XDCI_PARAM0_SET_EP_CFG_ACTN_MDFY_STATE         (2)
> +#define DWC_XDCI_PARAM0_SET_EP_CFG_ACTN_NONE               (3)
> +#define DWC_XDCI_PARAM0_SET_EP_CFG_BRST_SIZE_MASK          (0x03C00000)
> +#define DWC_XDCI_PARAM0_SET_EP_CFG_BRST_SIZE_BIT_POS       (22)
> +#define DWC_XDCI_PARAM0_SET_EP_CFG_FIFO_NUM_MASK           (0x003E0000)
> +#define DWC_XDCI_PARAM0_SET_EP_CFG_FIFO_NUM_BIT_POS        (17)
> +#define DWC_XDCI_PARAM0_SET_EP_CFG_MPS_MASK                (0x00003FF8)
> +#define DWC_XDCI_PARAM0_SET_EP_CFG_MPS_BIT_POS             (3)
> +#define DWC_XDCI_PARAM0_SET_EP_CFG_EP_TYPE_MASK            (0x00000006)
> +#define DWC_XDCI_PARAM0_SET_EP_CFG_EP_TYPE_BIT_POS         (1)
> +#define DWC_XDCI_PARAM0_EP_TYPE_CTRL                       (0)
> +#define DWC_XDCI_PARAM0_EP_TYPE_ISOCH                      (1)
> +#define DWC_XDCI_PARAM0_EP_TYPE_BULK                       (2)
> +#define DWC_XDCI_PARAM0_EP_TYPE_INTR                       (3)
> +
> +//
> +// CMD 1 param 1
> +//
> +#define DWC_XDCI_PARAM1_SET_EP_CFG_BULK_BASED_MASK         (0x40000000)
> +#define DWC_XDCI_PARAM1_SET_EP_CFG_EP_NUM_MASK             (0x3C000000)
> +#define DWC_XDCI_PARAM1_SET_EP_CFG_EP_NUM_BIT_POS          (26)
> +#define DWC_XDCI_PARAM1_SET_EP_CFG_EP_DIR_MASK             (0x02000000)
> +#define DWC_XDCI_PARAM1_SET_EP_CFG_EP_DIR_BIT_POS          (25)
> +#define DWC_XDCI_PARAM1_SET_EP_CFG_STRM_CAP_MASK           (0x01000000)
> +#define DWC_XDCI_PARAM1_SET_EP_CFG_BINTM1_MASK             (0x00FF0000)
> +#define DWC_XDCI_PARAM1_SET_EP_CFG_BINTM1_BIT_POS          (16)
> +#define DWC_XDCI_PARAM1_SET_EP_CFG_EBC_MASK                (0x00008000)
> +#define DWC_XDCI_PARAM1_SET_EP_CFG_EVT_EN_MASK             (0x00003F00)
> +#define DWC_XDCI_PARAM1_SET_EP_CFG_EVT_EN_BIT_POS          (8)
> +#define DWC_XDCI_PARAM1_SET_EP_CFG_EVT_STRM_MASK           (0x00002000)
> +#define DWC_XDCI_PARAM1_SET_EP_CFG_EVT_XFER_NRDY_MASK      (0x00000400)
> +#define DWC_XDCI_PARAM1_SET_EP_CFG_EVT_XFER_IN_PRG_MASK    (0x00000200)
> +#define DWC_XDCI_PARAM1_SET_EP_CFG_EVT_XFER_CMPLT_MASK     (0x00000100)
> +#define DWC_XDCI_PARAM1_SET_EP_CFG_INTR_NUM_MASK           (0x0000001F)
> +
> +//
> +// CMD 2 param 0
> +//
> +#define DWC_XDCI_PARAM0_SET_EP_XFER_RES_NUM_MASK           (0x0000FFFF)
> +
> +//
> +// CMD 3 param 2
> +//
> +#define DWC_XDCI_PARAM2_GET_EP_STATE_MASK                  (0xFFFFFFFF)
> +
> +//
> +// CMD 6 param 1
> +//
> +#define DWC_XDCI_PARAM1_STRT_XFER_TD_ADDR_LO_MASK          (0xFFFFFFFF)
> +
> +//
> +// CMD 6 param 0
> +//
> +#define DWC_XDCI_PARAM0_STRT_XFER_TD_ADDR_HI_MASK          (0xFFFFFFFF)
> +
> +//
> +// Transfer Request Block Fields' Bit Definitions
> +//
> +#define DWC_XDCI_TRB_BUFF_SIZE_MASK                        (0x00FFFFFF)
> +#define DWC_XDCI_TRB_PCM1_MASK                             (0x03000000)
> +#define DWC_XDCI_TRB_PCM1_BIT_POS                          (24)
> +#define DWC_XDCI_TRB_STATUS_MASK                           (0xF0000000)
> +#define DWC_XDCI_TRB_STATUS_BIT_POS                        (28)
> +#define DWC_XDCI_TRB_STATUS_OK                             (0)
> +#define DWC_XDCI_TRB_STATUS_MISSED_ISOCH                   (1)
> +#define DWC_XDCI_TRB_STATUS_SETUP_PENDING                  (2)
> +
> +#define DWC_XDCI_TRB_CTRL_HWO_MASK                         (0x00000001)
> +#define DWC_XDCI_TRB_CTRL_LST_TRB_MASK                     (0x00000002)
> +#define DWC_XDCI_TRB_CTRL_LST_TRB_BIT_POS                  (1)
> +#define DWC_XDCI_TRB_CTRL_CHAIN_BUFF_MASK                  (0x00000004)
> +#define DWC_XDCI_TRB_CTRL_CHAIN_BUFF_BIT_POS               (2)
> +#define DWC_XDCI_TRB_CTRL_CSP_MASK                         (0x00000008)
> +#define DWC_XDCI_TRB_CTRL_CSP_BIT_POS                      (3)
> +#define DWC_XDCI_TRB_CTRL_TYPE_MASK                        (0x000003F0)
> +#define DWC_XDCI_TRB_CTRL_TYPE_BIT_POS                     (4)
> +#define DWC_XDCI_TRB_CTRL_TYPE_NORMAL                      (1)
> +#define DWC_XDCI_TRB_CTRL_TYPE_SETUP                       (2)
> +#define DWC_XDCI_TRB_CTRL_TYPE_STATUS2                     (3)
> +#define DWC_XDCI_TRB_CTRL_TYPE_STATUS3                     (4)
> +#define DWC_XDCI_TRB_CTRL_TYPE_DATA                        (5)
> +#define DWC_XDCI_TRB_CTRL_TYPE_ISOCH_FIRST                 (6)
> +#define DWC_XDCI_TRB_CTRL_TYPE_ISOCH                       (7)
> +#define DWC_XDCI_TRB_CTRL_TYPE_LINK_TRB                    (8)
> +#define DWC_XDCI_TRB_CTRL_IOSP_MISOCH_MASK                 (0x00000400)
> +#define DWC_XDCI_TRB_CTRL_IOSP_MISOCH_BIT_POS              (10)
> +#define DWC_XDCI_TRB_CTRL_IOC_MASK                         (0x00000800)
> +#define DWC_XDCI_TRB_CTRL_IOC_BIT_POS                      (11)
> +#define DWC_XDCI_TRB_CTRL_STRM_ID_SOF_NUM_MASK             (0x3FFFC000)
> +#define DWC_XDCI_TRB_CTRL_STRM_ID_SOF_BIT_POS              (14)
> +
> +#define DWC_XDCI_DEV_EVENT_DEFAULT_SIZE_IN_BYTES           (4)
> +#define DWC_XDCI_DEV_EVENT_TST_LMP_SIZE_IN_BYTES           (12)
> +
> +typedef enum {
> +  EPCMD_SET_EP_CONFIG = 1,
> +  EPCMD_SET_EP_XFER_RES_CONFIG,
> +  EPCMD_GET_EP_STATE,
> +  EPCMD_SET_STALL,
> +  EPCMD_CLEAR_STALL,
> +  EPCMD_START_XFER,
> +  EPCMD_UPDATE_XFER,
> +  EPCMD_END_XFER,
> +  EPCMD_START_NEW_CONFIG = 9
> +} DWC_XDCI_ENDPOINT_CMD;
> +
> +typedef enum {
> +  ON = 0,
> +  SLEEP = 2,
> +  SUSPEND,
> +  DISCONNECTED,
> +  EARLY_SUSPEND,
> +  RESET = 14,
> +  RESUME = 15
> +} DWC_XDCI_HS_LINK_STATE;
> +
> +typedef enum {
> +  TRBCTL_NORMAL = 1,
> +  TRBCTL_SETUP,
> +  TRBCTL_2_PHASE,
> +  TRBCTL_3_PHASE,
> +  TRBCTL_CTRL_DATA_PHASE,
> +  TRBCTL_ISOCH_FIRST,
> +  TRBCTL_ISOCH,
> +  TRBCTL_LINK
> +} DWC_XDCI_TRB_CONTROL;
> +
> +//
> +// DWC XDCI Endpoint Commands Parameters struct
> +//
> +typedef struct {
> +  UINT32 Param2;
> +  UINT32 Param1;
> +  UINT32 Param0;
> +} DWC_XDCI_ENDPOINT_CMD_PARAMS;
> +
> +//
> +// Event Buffer Struct
> +//
> +typedef struct {
> +  UINT32 Event;
> +  UINT32 DevTstLmp1;
> +  UINT32 DevTstLmp2;
> +  UINT32 Reserved;
> +} DWC_XDCI_EVENT_BUFFER;
> +
> +//
> +// Transfer Request Block
> +//
> +typedef struct {
> +  UINT32 BuffPtrLow;
> +  UINT32 BuffPtrHigh;
> +  UINT32 LenXferParams;
> +  UINT32 TrbCtrl;
> +} DWC_XDCI_TRB;
> +
> +typedef struct  {
> +  USB_EP_INFO       EpInfo;
> +  DWC_XDCI_TRB      *Trb;
> +  USB_XFER_REQUEST  XferHandle;
> +  UINT32            CurrentXferRscIdx;
> +  VOID              *CoreHandle;
> +  USB_EP_STATE      State;
> +  USB_EP_STATE      OrgState;
> +  BOOLEAN           CheckFlag;
> +} DWC_XDCI_ENDPOINT;
> +
> +typedef struct {
> +  //
> +  // CbEventParams must be copied over by upper layer if
> +  // it defers event processing
> +  //
> +  USB_DEVICE_CALLBACK_PARAM CbEventParams;
> +
> +  //
> +  // Callback function list
> +  //
> +  USB_DEVICE_CALLBACK_FUNC  DevDisconnectCallback;
> +  USB_DEVICE_CALLBACK_FUNC  DevBusResetCallback;
> +  USB_DEVICE_CALLBACK_FUNC  DevResetDoneCallback;
> +  USB_DEVICE_CALLBACK_FUNC  DevLinkStateCallback;
> +  USB_DEVICE_CALLBACK_FUNC  DevWakeupCallback;
> +  USB_DEVICE_CALLBACK_FUNC  DevHibernationCallback;
> +  USB_DEVICE_CALLBACK_FUNC  DevSofCallback;
> +  USB_DEVICE_CALLBACK_FUNC  DevErraticErrCallback;
> +  USB_DEVICE_CALLBACK_FUNC  DevCmdCmpltCallback;
> +  USB_DEVICE_CALLBACK_FUNC  DevBuffOvflwCallback;
> +  USB_DEVICE_CALLBACK_FUNC  DevTestLmpRxCallback;
> +  USB_DEVICE_CALLBACK_FUNC  DevSetupPktReceivedCallback;
> +  USB_DEVICE_CALLBACK_FUNC  DevXferNrdyCallback;
> +  USB_DEVICE_CALLBACK_FUNC  DevXferDoneCallback;
> +} USB_DEV_CALLBACK_LIST;
> +
> +typedef struct {
> +  VOID                     *ParentHandle;                                       // Pointer to the parent this driver is associated
> +  USB_CONTROLLER_ID        Id;                                                  // ID of the controllers supported in our DCD
> +  USB_SPEED                DesiredSpeed;                                        // Desired SS, HS, FS or LS Speeds for the core
> +  USB_ROLE                 Role;                                                // Desired role i.e. host, Device or OTG
> +  USB_SPEED                ActualSpeed;                                         // Actual Speed
> +  USB_DEVICE_STATE         DevState;                                            // Device state
> +  UINT32                   BaseAddress;                                         // Register Base address
> +  UINT32                   Flags;                                               // Init flags
> +  UINT32                   MaxDevIntLines;                                      // One event Buffer per interrupt line
> +  DWC_XDCI_EVENT_BUFFER    EventBuffers [DWC_XDCI_MAX_EVENTS_PER_BUFFER * 2];   // Event Buffer pool
> +  DWC_XDCI_EVENT_BUFFER    *AlignedEventBuffers;                                // Aligned event Buffer pool
> +  DWC_XDCI_EVENT_BUFFER    *CurrentEventBuffer;                                 // Current event Buffer address
> +  DWC_XDCI_TRB             UnalignedTrbs [(DWC_XDCI_MAX_ENDPOINTS + 1) * DWC_XDCI_TRB_NUM];    // TRBs.
> +  DWC_XDCI_TRB             *Trbs;                                               // 16-bytes aligned TRBs.
> +  DWC_XDCI_ENDPOINT        EpHandles [DWC_XDCI_MAX_ENDPOINTS];                  // EPs
> +  UINT8                    DefaultSetupBuffer [DWC_XDCI_SETUP_BUFF_SIZE * 2];   // Unaligned setup Buffer
> +  UINT8                    *AlignedSetupBuffer;                                 // Aligned setup Buffer. Aligned to 8-byte boundary
> +  UINT8                    MiscBuffer [528];                                    // Unaligned misc Buffer
> +  UINT8                    *AlignedMiscBuffer;                                  // Aligned misc Buffer
> +  UINT32                   LinkState;                                           // Link state
> +  UINT32                   HirdVal;                                             // HIRD value
> +  USB_DEV_CALLBACK_LIST    EventCallbacks;
> +  volatile BOOLEAN         InterrupProcessing;
> +} XDCI_CORE_HANDLE;
> +
> +//
> +// DWC XDCI API prototypes
> +//
> +EFI_STATUS
> +EFIAPI
> +DwcXdciCoreInit (
> +  IN USB_DEV_CONFIG_PARAMS    *ConfigParams,
> +  IN VOID                     *ParentHandle,
> +  IN VOID                     **CoreHandle
> +  );
> +
> +EFI_STATUS
> +EFIAPI
> +DwcXdciCoreDeinit (
> +  IN VOID      *CoreHandle,
> +  IN UINT32    flags
> +  );
> +
> +EFI_STATUS
> +EFIAPI
> +DwcXdciCoreRegisterCallback (
> +  IN VOID                      *CoreHandle,
> +  IN USB_DEVICE_EVENT_ID       Event,
> +  IN USB_DEVICE_CALLBACK_FUNC  CallbackFunc
> +  );
> +
> +EFI_STATUS
> +EFIAPI
> +DwcXdciCoreUnregisterCallback (
> +  IN VOID                   *CoreHandle,
> +  IN USB_DEVICE_EVENT_ID    Event
> +  );
> +
> +EFI_STATUS
> +EFIAPI
> +DwcXdciCoreIsrRoutine (
> +  IN VOID *CoreHandle
> +  );
> +
> +EFI_STATUS
> +EFIAPI
> +DwcXdciCoreIsrRoutineTimerBased (
> +  IN VOID *CoreHandle
> +  );
> +
> +EFI_STATUS
> +EFIAPI
> +DwcXdciCoreConnect (
> +  IN VOID    *CoreHandle
> +  );
> +
> +EFI_STATUS
> +EFIAPI
> +DwcXdciCoreDisconnect (
> +  IN VOID *CoreHandle
> +  );
> +
> +EFI_STATUS
> +EFIAPI
> +DwcXdciCoreGetSpeed (
> +  IN VOID         *CoreHandle,
> +  IN USB_SPEED    *Speed
> +  );
> +
> +EFI_STATUS
> +EFIAPI
> +DwcXdciCoreSetAddress (
> +  IN VOID      *CoreHandle,
> +  IN UINT32    Address
> +  );
> +
> +EFI_STATUS
> +EFIAPI
> +DwcXdciCoreSetConfig (
> +  IN VOID      *CoreHandle,
> +  IN UINT32    ConfigNum
> +  );
> +
> +EFI_STATUS
> +EFIAPI
> +DwcXdciSetLinkState (
> +  IN VOID                        *CoreHandle,
> +  IN USB_DEVICE_SS_LINK_STATE    State
> +  );
> +
> +EFI_STATUS
> +EFIAPI
> +DwcXdciInitEp (
> +  IN VOID           *CoreHandle,
> +  IN USB_EP_INFO    *EpInfo
> +  );
> +
> +EFI_STATUS
> +EFIAPI
> +DwcXdciEpEnable (
> +  IN VOID           *CoreHandle,
> +  IN USB_EP_INFO    *EpInfo
> +  );
> +
> +EFI_STATUS
> +EFIAPI
> +DwcXdciEpDisable (
> +  IN VOID           *CoreHandle,
> +  IN USB_EP_INFO    *EpInfo
> +  );
> +
> +EFI_STATUS
> +EFIAPI
> +DwcXdciEpStall (
> +  IN VOID           *CoreHandle,
> +  IN USB_EP_INFO    *EpInfo
> +  );
> +
> +EFI_STATUS
> +EFIAPI
> +DwcXdciEpClearStall (
> +  IN VOID           *CoreHandle,
> +  IN USB_EP_INFO    *EpInfo
> +  );
> +
> +EFI_STATUS
> +EFIAPI
> +DwcXdciEpSetNrdy (
> +  IN VOID           *CoreHandle,
> +  IN USB_EP_INFO    *EpInfo
> +  );
> +
> +EFI_STATUS
> +EFIAPI
> +DwcXdciEp0ReceiveSetupPkt (
> +  IN VOID     *CoreHandle,
> +  IN UINT8    *Buffer
> +  );
> +
> +EFI_STATUS
> +EFIAPI
> +DwcXdciEp0ReceiveStatusPkt (
> +  IN VOID    *CoreHandle
> +  );
> +
> +EFI_STATUS
> +EFIAPI
> +DwcXdciEp0SendStatusPkt (
> +  IN VOID    *CoreHandle
> +  );
> +
> +EFI_STATUS
> +EFIAPI
> +DwcXdciEpTxData (
> +  IN VOID                *CoreHandle,
> +  IN USB_XFER_REQUEST    *XferReq
> +  );
> +
> +EFI_STATUS
> +EFIAPI
> +DwcXdciEpRxData(
> +  IN VOID                *CoreHandle,
> +  IN USB_XFER_REQUEST    *XferReq
> +  );
> +
> +EFI_STATUS
> +EFIAPI
> +DwcXdciEpCancelTransfer (
> +  IN VOID           *CoreHandle,
> +  IN USB_EP_INFO    *EpInfo
> +  );
> +
> +EFI_STATUS
> +usbProcessDeviceResetDet (
> +  IN XDCI_CORE_HANDLE    *CoreHandle
> +  );
> +
> +EFI_STATUS
> +usbProcessDeviceResetDone (
> +  IN XDCI_CORE_HANDLE    *CoreHandle
> +  );
> +
> +UINT32
> +UsbGetPhysicalEpNum (
> +  IN UINT32        EndpointNum,
> +  IN USB_EP_DIR    EndpointDir
> +  );
> +
> +UINT32
> +UsbRegRead (
> +  IN UINT32    Base,
> +  IN UINT32    Offset
> +  );
> +
> +VOID
> +UsbRegWrite (
> +  IN UINT32    Base,
> +  IN UINT32    Offset,
> +  IN UINT32    val
> +  );
> +
> +EFI_STATUS
> +UsbXdciCoreFlushEpFifo (
> +  IN VOID           *CoreHandle,
> +  IN USB_EP_INFO    *EpInfo
> +  );
> +#endif
> +
> diff --git a/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciDevice.c b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciDevice.c
> new file mode 100644
> index 0000000000..7c94de0a60
> --- /dev/null
> +++ b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciDevice.c
> @@ -0,0 +1,695 @@
> +/** @file
> +  Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR>
> +
> +  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.
> +
> +**/
> +
> +#include <Library/UsbDeviceLib.h>
> +#include "XdciCommon.h"
> +#include "XdciDevice.h"
> +#include "XdciInterface.h"
> +#include "UsbDeviceMode.h"
> +
> +/**
> +  This function is used to initialize the device controller
> +  @configParams: Parameters from app to configure the core
> +  @DevCoreHandle: Return parameter for upper layers to use
> +  for all HW-independent APIs
> +
> +**/
> +EFI_STATUS
> +UsbDeviceInit (
> +  IN USB_DEV_CONFIG_PARAMS    *ConfigParams,
> +  IN OUT VOID                 **DevCoreHandle
> +  )
> +{
> +  USB_DEV_CORE    *DevCorePtr;
> +  EFI_STATUS      Status = EFI_INVALID_PARAMETER;
> +
> +  DEBUG ((DEBUG_INFO, "Call UsbDeviceInit start\n"));
> +
> +  //
> +  // Allocate device handle
> +  //
> +  DevCorePtr = AllocateZeroPool (sizeof (USB_DEV_CORE));
> +  DEBUG ((DEBUG_INFO, "device handle = 0x%x\n", DevCorePtr));
> +
> +  if (DevCorePtr == NULL) {
> +    DEBUG ((DEBUG_INFO, "UsbDeviceInit. ERROR: Failed to allocate memory\n"));
> +    return EFI_OUT_OF_RESOURCES;
> +  }
> +
> +  DEBUG ((DEBUG_INFO, "call UsbDeviceGetCoreDriver, ID=%x, \n", ConfigParams->ControllerId));
> +
> +  //
> +  // Get the driver for this USB device core
> +  //
> +  DevCorePtr->CoreDriver = UsbDeviceGetCoreDriver(ConfigParams->ControllerId);
> +  if (DevCorePtr->CoreDriver != NULL) {
> +    DEBUG ((DEBUG_INFO, "call DevCoreInit\n"));
> +    Status = DevCorePtr->CoreDriver->DevCoreInit(
> +                                        ConfigParams,
> +                                        (VOID*)DevCorePtr,
> +                                        &DevCorePtr->ControllerHandle);
> +  } else {
> +    DEBUG ((DEBUG_INFO, "UsbDeviceInit. ERROR: Driver not found\n"));
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  *DevCoreHandle = (VOID *)DevCorePtr;
> +  return Status;
> +}
> +
> +/**
> +  This function is used to de-initialize the device controller
> +  @DevCoreHandle: Handle to HW-independent APIs for device
> +  controller
> +  @flags: Flags indicating what type of de-initialization is required
> +
> +**/
> +EFI_STATUS
> +UsbDeviceDeinit (
> +  IN VOID      *DevCoreHandle,
> +  IN UINT32    Flags
> +  )
> +{
> +  USB_DEV_CORE    *Core = (USB_DEV_CORE *)DevCoreHandle;
> +  EFI_STATUS      Status = EFI_DEVICE_ERROR;
> +
> +  if (Core == NULL) {
> +    DEBUG ((DEBUG_INFO, "UsbDeviceDeinit: ERROR: INVALID HANDLE\n"));
> +  } else {
> +    if (Core->CoreDriver != NULL) {
> +      Status = Core->CoreDriver->DevCoreDeinit(
> +                                    Core->ControllerHandle,
> +                                    Flags
> +                                    );
> +      FreePool(DevCoreHandle);
> +    } else {
> +      DEBUG ((DEBUG_INFO, "UsbDeviceDeinit: Driver not found\n"));
> +      Status = EFI_INVALID_PARAMETER;
> +    }
> +  }
> +
> +  return Status;
> +}
> +
> +/**
> +  This function is used to register callback function for
> +  specified event
> +  @DevCoreHandle: Handle to HW-independent APIs for device
> +  controller
> +  @event: Event for which callback is to be registered
> +  @callbackFn: Callback function to be called by the
> +  controller driver for above event after critical processing
> +
> +**/
> +EFI_STATUS
> +UsbDeviceRegisterCallback (
> +  IN VOID                      *DevCoreHandle,
> +  IN USB_DEVICE_EVENT_ID       EventId,
> +  IN USB_DEVICE_CALLBACK_FUNC  CallbackFunc
> +  )
> +{
> +  EFI_STATUS    Status = EFI_DEVICE_ERROR;
> +  USB_DEV_CORE  *core = (USB_DEV_CORE *)DevCoreHandle;
> +
> +  DEBUG ((DEBUG_INFO, "UsbDeviceRegisterCallback start\n"));
> +
> +  if (core == NULL) {
> +    DEBUG ((DEBUG_INFO, "UsbDeviceRegisterCallback: ERROR: INVALID HANDLE\n"));
> +  } else {
> +    if (core->CoreDriver != NULL) {
> +      DEBUG ((DEBUG_INFO, "Call DevCoreRegisterCallback\n"));
> +      Status = core->CoreDriver->DevCoreRegisterCallback (
> +                                    core->ControllerHandle,
> +                                    EventId,
> +                                    CallbackFunc
> +                                    );
> +    }
> +  }
> +
> +  return Status;
> +}
> +
> +/**
> +  This function is used to register callback function for
> +  specified event
> +  @DevCoreHandle: Handle to HW-independent APIs for device
> +  controller
> +  @eventId: Event for which callback is to be unregistered
> +
> +**/
> +EFI_STATUS
> +UsbDeviceUnregisterCallback (
> +  IN VOID                      *DevCoreHandle,
> +  IN USB_DEVICE_EVENT_ID       EventId
> +  )
> +{
> +  EFI_STATUS    Status = EFI_DEVICE_ERROR;
> +  USB_DEV_CORE  *core = (USB_DEV_CORE *)DevCoreHandle;
> +
> +  if (core == NULL) {
> +    DEBUG ((DEBUG_INFO, "UsbDeviceUnregisterCallback: ERROR: INVALID HANDLE\n"));
> +  } else {
> +    if (core->CoreDriver != NULL) {
> +      Status = core->CoreDriver->DevCoreUnregisterCallback(
> +                                    core->ControllerHandle,
> +                                    EventId
> +                                    );
> +    }
> +  }
> +
> +  return Status;
> +}
> +
> +/**
> +  This function is used to service interrupt events on device
> +  controller. Use this API in your OS/stack-specific ISR framework
> +  In polled mode scenario, invoke this API in a loop to service the
> +  events
> +  @DevCoreHandle: Handle to HW-independent APIs for device
> +  controller
> +
> +**/
> +EFI_STATUS
> +UsbDeviceIsrRoutine (
> +  IN VOID                      *DevCoreHandle
> +  )
> +{
> +  USB_DEV_CORE  *core = (USB_DEV_CORE *)DevCoreHandle;
> +  EFI_STATUS    Status = EFI_DEVICE_ERROR;
> +
> +  if (core == NULL) {
> +    DEBUG ((DEBUG_INFO, "UsbDeviceIsrRoutine: ERROR: INVALID HANDLE\n"));
> +  } else {
> +    if (core->CoreDriver != NULL) {
> +      Status = core->CoreDriver->DevCoreIsrRoutine (core->ControllerHandle);
> +    }
> +  }
> +
> +  return Status;
> +}
> +
> +
> +/**
> +  This function is used to service interrupt events on device
> +  controller. Use this API in your OS/stack-specific ISR framework
> +  In polled mode scenario, invoke this API in a loop to service the
> +  events
> +  @DevCoreHandle: Handle to HW-independent APIs for device
> +  controller
> +
> +**/
> +EFI_STATUS
> +UsbDeviceIsrRoutineTimerBased (
> +  IN VOID                      *DevCoreHandle
> +  )
> +{
> +  USB_DEV_CORE  *core = (USB_DEV_CORE *)DevCoreHandle;
> +  EFI_STATUS    Status = EFI_DEVICE_ERROR;
> +
> +  if (core == NULL) {
> +    DEBUG ((DEBUG_INFO, "UsbDeviceIsrRoutine: ERROR: INVALID HANDLE\n"));
> +  } else {
> +    if (core->CoreDriver != NULL) {
> +      Status = core->CoreDriver->DevCoreIsrRoutineTimerBased (core->ControllerHandle);
> +    }
> +  }
> +
> +  return Status;
> +}
> +
> +
> +/**
> +  This function is used to enable device controller to connect
> +  to USB host
> +  @DevCoreHandle: Handle to HW-independent APIs for device
> +  controller
> +
> +**/
> +EFI_STATUS
> +UsbXdciDeviceConnect (
> +  IN VOID                      *DevCoreHandle
> +  )
> +{
> +  USB_DEV_CORE  *core = (USB_DEV_CORE *)DevCoreHandle;
> +  EFI_STATUS    Status = EFI_DEVICE_ERROR;
> +
> +  if (core == NULL) {
> +    DEBUG ((DEBUG_INFO, "UsbXdciDeviceConnect: ERROR: INVALID HANDLE\n"));
> +  } else {
> +    DEBUG ((DEBUG_INFO, "UsbXdciDeviceConnect\n"));
> +    Status = core->CoreDriver->DevCoreConnect (core->ControllerHandle);
> +  }
> +
> +  return Status;
> +}
> +
> +/**
> +  This function is used to disconnect device controller
> +  from USB host
> +  @DevCoreHandle: Handle to HW-independent APIs for device
> +  controller
> +
> +**/
> +EFI_STATUS
> +UsbDeviceDisconnect (
> +  IN VOID                      *DevCoreHandle
> +  )
> +{
> +  USB_DEV_CORE  *core =(USB_DEV_CORE *)DevCoreHandle;
> +  EFI_STATUS    Status = EFI_DEVICE_ERROR;
> +
> +  if (core == NULL) {
> +    DEBUG ((DEBUG_INFO, "UsbDeviceDisconnect: ERROR: INVALID HANDLE\n"));
> +  } else {
> +    DEBUG ((DEBUG_INFO, "UsbDeviceDisconnect\n"));
> +    Status = core->CoreDriver->DevCoreDisconnect(core->ControllerHandle);
> +  }
> +
> +  return Status;
> +}
> +
> +/**
> +  This function is used to obtain USB bus Speed after bus reset complete
> +  @DevCoreHandle: Handle to HW-independent APIs for device
> +  controller
> +  @Speed: negotiated Speed
> +
> +**/
> +EFI_STATUS
> +UsbDeviceGetSpeed (
> +  IN VOID                      *DevCoreHandle,
> +  IN USB_SPEED                 *Speed
> +  )
> +{
> +  USB_DEV_CORE  *core = (USB_DEV_CORE *)DevCoreHandle;
> +  EFI_STATUS    Status = EFI_DEVICE_ERROR;
> +
> +  if (core == NULL) {
> +    DEBUG ((DEBUG_INFO, "UsbDeviceGetSpeed: ERROR: INVALID HANDLE\n"));
> +  } else {
> +    Status = core->CoreDriver->DevCoreGetSpeed(core->ControllerHandle, Speed);
> +  }
> +
> +  return Status;
> +}
> +
> +/**
> +  This function is used to set USB device address
> +  @DevCoreHandle: Handle to HW-independent APIs for device
> +  controller
> +  @address: USB device address to set
> +
> +**/
> +EFI_STATUS
> +UsbDeviceSetAddress (
> +  IN VOID                      *DevCoreHandle,
> +  IN UINT32                    Address
> +  )
> +{
> +  USB_DEV_CORE  *core = (USB_DEV_CORE *)DevCoreHandle;
> +  EFI_STATUS    Status = EFI_DEVICE_ERROR;
> +
> +  DEBUG ((DEBUG_INFO, "UsbDeviceSetAddress: enter......\n"));
> +  if (core == NULL) {
> +    DEBUG ((DEBUG_INFO, "UsbDeviceSetAddress: ERROR: INVALID HANDLE\n"));
> +  } else {
> +    Status = core->CoreDriver->DevCoreSetAddress(core->ControllerHandle, Address);
> +  }
> +  DEBUG ((DEBUG_INFO, "UsbDeviceSetAddress: exit......\n"));
> +
> +  return Status;
> +}
> +
> +/**
> +  This function is used to do device controller-specific processing
> +  of set configuration device framework request
> +  @DevCoreHandle: Handle to HW-independent APIs for device
> +  controller
> +  @ConfigNum: configuration number selected by USB host
> +
> +**/
> +EFI_STATUS
> +UsbDeviceSetConfiguration (
> +  IN VOID                      *DevCoreHandle,
> +  IN UINT32                    ConfigNum
> +  )
> +{
> +  USB_DEV_CORE  *core = (USB_DEV_CORE *)DevCoreHandle;
> +  EFI_STATUS    Status = EFI_DEVICE_ERROR;
> +
> +  if (core == NULL) {
> +    DEBUG ((DEBUG_INFO, "UsbDeviceSetConfiguration: ERROR: INVALID HANDLE\n"));
> +  } else {
> +    Status = core->CoreDriver->DevCoreSetConfig (core->ControllerHandle, ConfigNum);
> +  }
> +
> +  return Status;
> +}
> +
> +/**
> +  This function is used to set desired link state in device controller
> +  @DevCoreHandle: Handle to HW-independent APIs for device
> +  controller
> +  @state: Desired link state
> +
> +**/
> +EFI_STATUS
> +UsbDeviceSetLinkState (
> +  IN VOID                      *DevCoreHandle,
> +  IN USB_DEVICE_SS_LINK_STATE  State
> +  )
> +{
> +  USB_DEV_CORE  *core = (USB_DEV_CORE *)DevCoreHandle;
> +  EFI_STATUS    Status = EFI_DEVICE_ERROR;
> +
> +  if (core == NULL) {
> +    DEBUG ((DEBUG_INFO, "UsbDeviceSetLinkState: ERROR: INVALID HANDLE\n"));
> +  } else {
> +    Status = core->CoreDriver->DevCoreSetLinkState (core->ControllerHandle, State);
> +  }
> +
> +  return Status;
> +}
> +
> +/**
> +  This function is used to initialize non-EP0 endpoints
> +  @DevCoreHandle: Handle to HW-independent APIs for device
> +  controller
> +  @EpInfo: Endpoint information for EP to be initialized
> +
> +**/
> +EFI_STATUS
> +UsbDeviceInitEp (
> +  IN VOID                      *DevCoreHandle,
> +  IN USB_EP_INFO               *EpInfo
> +  )
> +{
> +  USB_DEV_CORE  *core = (USB_DEV_CORE *)DevCoreHandle;
> +  EFI_STATUS    Status = EFI_DEVICE_ERROR;
> +
> +  if (core == NULL) {
> +    DEBUG ((DEBUG_INFO, "UsbDeviceInitEp: ERROR: INVALID HANDLE\n"));
> +  } else {
> +    Status = core->CoreDriver->DevCoreInitEp (core->ControllerHandle, EpInfo);
> +  }
> +
> +  return Status;
> +}
> +
> +/**
> +  This function is used to enable an endpoint
> +  @DevCoreHandle: Handle to HW-independent APIs for device
> +  controller
> +  @EpInfo: Endpoint information for EP to be enabled
> +
> +**/
> +EFI_STATUS
> +UsbDeviceEpEnable (
> +  IN VOID                      *DevCoreHandle,
> +  IN USB_EP_INFO               *EpInfo
> +  )
> +{
> +  USB_DEV_CORE  *core = (USB_DEV_CORE *)DevCoreHandle;
> +  EFI_STATUS    Status = EFI_DEVICE_ERROR;
> +
> +  if (core == NULL) {
> +    DEBUG ((DEBUG_INFO, "UsbDeviceEpEnable: ERROR: INVALID HANDLE\n"));
> +  } else {
> +    Status = core->CoreDriver->DevCoreEpEnable (core->ControllerHandle, EpInfo);
> +  }
> +
> +  return Status;
> +}
> +
> +/**
> +  This function is used to disable an endpoint
> +  @DevCoreHandle: Handle to HW-independent APIs for device
> +  controller
> +  @EpInfo: Endpoint information for EP to be disabled
> +
> +**/
> +EFI_STATUS
> +UsbDeviceEpDisable (
> +  IN VOID                      *DevCoreHandle,
> +  IN USB_EP_INFO               *EpInfo
> +  )
> +{
> +  USB_DEV_CORE  *core = (USB_DEV_CORE *)DevCoreHandle;
> +  EFI_STATUS    Status = EFI_DEVICE_ERROR;
> +
> +  if (core == NULL) {
> +    DEBUG ((DEBUG_INFO, "UsbDeviceEpDisable ERROR: INVALID HANDLE\n"));
> +  } else {
> +    Status = core->CoreDriver->DevCoreEpDisable (core->ControllerHandle, EpInfo);
> +  }
> +
> +  return Status;
> +}
> +
> +/**
> +  This function is used to STALL an endpoint
> +  @DevCoreHandle: Handle to HW-independent APIs for device
> +  controller
> +  @EpInfo: Endpoint information for EP to be stalled
> +
> +**/
> +EFI_STATUS
> +UsbDeviceEpStall (
> +  IN VOID                      *DevCoreHandle,
> +  IN USB_EP_INFO               *EpInfo
> +  )
> +{
> +  USB_DEV_CORE  *core = (USB_DEV_CORE *)DevCoreHandle;
> +  EFI_STATUS    Status = EFI_DEVICE_ERROR;
> +
> +  if (core == NULL) {
> +    DEBUG ((DEBUG_INFO, "UsbDeviceEpStall ERROR: INVALID HANDLE\n"));
> +  } else {
> +    Status = core->CoreDriver->DevCoreEpStall (core->ControllerHandle, EpInfo);
> +  }
> +
> +  return Status;
> +}
> +
> +/**
> +  This function is used to clear STALL on an endpoint
> +  @DevCoreHandle: Handle to HW-independent APIs for device
> +  controller
> +  @EpInfo: Endpoint information for which STALL needs to be cleared
> +
> +**/
> +EFI_STATUS
> +UsbDeviceEpClearStall (
> +  IN VOID                      *DevCoreHandle,
> +  IN USB_EP_INFO               *EpInfo
> +  )
> +{
> +  USB_DEV_CORE  *core = (USB_DEV_CORE *)DevCoreHandle;
> +  EFI_STATUS    Status = EFI_DEVICE_ERROR;
> +
> +  if (core == NULL) {
> +    DEBUG ((DEBUG_INFO, "UsbDeviceEpClearStall ERROR: INVALID HANDLE\n"));
> +  } else {
> +    Status = core->CoreDriver->DevCoreEpClearStall (core->ControllerHandle, EpInfo);
> +  }
> +
> +  return Status;
> +}
> +
> +/**
> +  This function is used to set EP not ready state
> +  @DevCoreHandle: Handle to HW-independent APIs for device
> +  controller
> +  @EpInfo: Endpoint information for EP that needs to be
> +  set in not ready state
> +
> +**/
> +EFI_STATUS
> +UsbDeviceEpSetNrdy (
> +  IN VOID                      *DevCoreHandle,
> +  IN USB_EP_INFO               *EpInfo
> +  )
> +{
> +  USB_DEV_CORE  *core = (USB_DEV_CORE *)DevCoreHandle;
> +  EFI_STATUS    Status = EFI_DEVICE_ERROR;
> +
> +  if (core == NULL) {
> +    DEBUG ((DEBUG_INFO, "UsbDeviceEpSetNrdy ERROR: INVALID HANDLE\n"));
> +  } else {
> +    Status = core->CoreDriver->DevCoreEpSetNrdy (core->ControllerHandle, EpInfo);
> +  }
> +
> +  return Status;
> +}
> +
> +/**
> +  This function is used to queue request to receive SETUP packet
> +  @DevCoreHandle: Handle to HW-independent APIs for device
> +  controller
> +  @Buffer: Buffer (bus-width aligned) where SETUP packet
> +  needs to be received
> +
> +**/
> +EFI_STATUS
> +UsbDeviceEp0RxSetup (
> +  IN VOID                      *DevCoreHandle,
> +  IN UINT8                     *Buffer
> +  )
> +{
> +  USB_DEV_CORE  *core = (USB_DEV_CORE *)DevCoreHandle;
> +  EFI_STATUS    Status = EFI_DEVICE_ERROR;
> +
> +  if (core == NULL) {
> +    DEBUG ((DEBUG_INFO, "UsbDeviceEp0RxSetup ERROR: INVALID HANDLE\n"));
> +  } else {
> +    Status = core->CoreDriver->DevCoreEp0RxSetupPkt (core->ControllerHandle, Buffer);
> +  }
> +
> +  return Status;
> +}
> +
> +/**
> +  This function is used to queue request to receive status phase
> +  for control transfer on EP0
> +  @DevCoreHandle: Handle to HW-independent APIs for device
> +  controller
> +
> +**/
> +EFI_STATUS
> +UsbDeviceEp0RxStatus (
> +  IN VOID                      *DevCoreHandle
> +  )
> +{
> +  USB_DEV_CORE  *core = (USB_DEV_CORE *)DevCoreHandle;
> +  EFI_STATUS    Status = EFI_DEVICE_ERROR;
> +
> +  if (core == NULL) {
> +    DEBUG ((DEBUG_INFO, "UsbDeviceEp0RxStatus ERROR: INVALID HANDLE\n"));
> +  } else {
> +    Status = core->CoreDriver->DevCoreEp0RxStatusPkt (core->ControllerHandle);
> +  }
> +  return Status;
> +}
> +
> +/**
> +  This function is used to queue request to send status phase for
> +  control transfer on EP0
> +  @DevCoreHandle: Handle to HW-independent APIs for device
> +  controller
> +
> +**/
> +EFI_STATUS
> +UsbDeviceEp0TxStatus (
> +  IN VOID                      *DevCoreHandle
> +  )
> +{
> +  USB_DEV_CORE  *core = (USB_DEV_CORE *)DevCoreHandle;
> +  EFI_STATUS    Status = EFI_DEVICE_ERROR;
> +
> +  if (core == NULL) {
> +    DEBUG ((DEBUG_INFO, "UsbDeviceEp0TxStatus ERROR: INVALID HANDLE\n"));
> +  } else {
> +    Status = core->CoreDriver->DevCoreEp0TxStatusPkt (core->ControllerHandle);
> +  }
> +
> +  return Status;
> +}
> +
> +/**
> +  This function is used to queue a single request to transmit data on
> +  an endpoint. If more than one request need to be queued before
> +  previous requests complete then a request queue needs to be
> +  implemented in upper layers. This API should be not be invoked until
> +  current request completes.
> +  Callback for transfer completion is invoked when requested transfer length
> +  is reached or if a short packet is received
> +  @DevCoreHandle: Handle to HW-independent APIs for device
> +  controller
> +  @XferReq: Address to transfer request describing this transfer
> +
> +**/
> +EFI_STATUS
> +UsbXdciDeviceEpTxData (
> +  IN VOID                      *DevCoreHandle,
> +  IN USB_XFER_REQUEST          *XferReq
> +  )
> +{
> +  USB_DEV_CORE  *core = (USB_DEV_CORE *)DevCoreHandle;
> +  EFI_STATUS    Status = EFI_DEVICE_ERROR;
> +
> +  if (core == NULL) {
> +    DEBUG ((DEBUG_INFO, "UsbXdciDeviceEpTxData ERROR: INVALID HANDLE\n"));
> +  } else {
> +    Status = core->CoreDriver->DevCoreEpTxData (core->ControllerHandle, XferReq);
> +  }
> +
> +  return Status;
> +}
> +
> +/**
> +  This function is used to queue a single request to receive data on
> +  an endpoint. If more than one request need to be queued before
> +  previous requests complete then a request queue needs to be implemented
> +  in upper layers. This API should be not be invoked until current request
> +  completes.
> +  Callback for transfer completion is invoked when requested transfer length
> +  is reached or if a short packet is received
> +  @DevCoreHandle: Handle to HW-independent APIs for device
> +  controller
> +  @XferReq: Address to transfer request describing this transfer
> +
> +**/
> +EFI_STATUS
> +UsbXdciDeviceEpRxData (
> +  IN VOID                      *DevCoreHandle,
> +  IN USB_XFER_REQUEST          *XferReq
> +  )
> +{
> +  USB_DEV_CORE  *core = (USB_DEV_CORE *)DevCoreHandle;
> +  EFI_STATUS    Status = EFI_DEVICE_ERROR;
> +
> +  if (core == NULL) {
> +    DEBUG ((DEBUG_INFO, "UsbXdciDeviceEpRxData ERROR: INVALID HANDLE\n"));
> +  } else {
> +    Status = core->CoreDriver->DevCoreEpRxData (core->ControllerHandle, XferReq);
> +  }
> +
> +  return Status;
> +}
> +
> +/**
> +  This function is used to cancel a transfer request that was
> +  previously queued on an endpoint
> +  @DevCoreHandle: Handle to HW-independent APIs for device
> +  controller
> +  @EpInfo: Endpoint info where transfer needs to be cancelled
> +
> +**/
> +EFI_STATUS
> +UsbDeviceEpCancelTransfer (
> +  IN VOID                      *DevCoreHandle,
> +  IN USB_EP_INFO               *EpInfo
> +  )
> +{
> +  USB_DEV_CORE  *core = (USB_DEV_CORE *)DevCoreHandle;
> +  EFI_STATUS    Status = EFI_DEVICE_ERROR;
> +
> +  if (core == NULL) {
> +    DEBUG ((DEBUG_INFO, "UsbDeviceEpCancelTransfer ERROR: INVALID HANDLE\n"));
> +  } else {
> +    Status = core->CoreDriver->DevCoreEpCancelTransfer (core->ControllerHandle, EpInfo);
> +  }
> +
> +  return Status;
> +}
> +
> diff --git a/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciDevice.h b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciDevice.h
> new file mode 100644
> index 0000000000..a10ec61732
> --- /dev/null
> +++ b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciDevice.h
> @@ -0,0 +1,184 @@
> +/** @file
> +  Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR>
> +
> +  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.
> +
> +**/
> +
> +#ifndef _USB_DEVICE_H_
> +#define _USB_DEVICE_H_
> +
> +//
> +// @USB_DEV_CONFIG_PARAMS: Struct to be filled in with configuration
> +// parameters and passed to the init routine for device controller
> +//
> +typedef struct {
> +  USB_CONTROLLER_ID  ControllerId; // Controller ID of the core
> +  UINT32             BaseAddress;  // Base address of the controller registers and on-chip memory
> +  UINT32             Flags;        // Initialization flags
> +  USB_SPEED          Speed;        // Desired USB bus Speed
> +  USB_ROLE           Role;         // Default USB role
> +} USB_DEV_CONFIG_PARAMS;
> +
> +//
> +// @USB_DEV_CORE: Struct used as a handle for all
> +// hardware-independent APIs
> +//
> +typedef struct {
> +  const struct UsbDeviceCoreDriver *CoreDriver;
> +  VOID                                *ControllerHandle;
> +} USB_DEV_CORE;
> +
> +typedef
> +EFI_STATUS
> +(EFIAPI *USB_DEVICE_CALLBACK_FUNC) (
> +  IN USB_DEVICE_CALLBACK_PARAM  *Param
> +  );
> +
> +EFI_STATUS
> +UsbDeviceInit (
> +  IN USB_DEV_CONFIG_PARAMS    *ConfigParams,
> +  IN OUT VOID                 **DevCoreHandle
> +  );
> +
> +EFI_STATUS
> +UsbDeviceDeinit (
> +  IN VOID                      *DevCoreHandle,
> +  IN UINT32                    Flags
> +  );
> +
> +EFI_STATUS
> +UsbDeviceRegisterCallback (
> +  IN VOID                      *DevCoreHandle,
> +  IN USB_DEVICE_EVENT_ID       EventId,
> +  IN USB_DEVICE_CALLBACK_FUNC  CallbackFunc
> +  );
> +
> +EFI_STATUS
> +UsbDeviceUnregisterCallback (
> +  IN VOID                      *DevCoreHandle,
> +  IN USB_DEVICE_EVENT_ID       EventId
> +  );
> +
> +EFI_STATUS
> +UsbDeviceIsrRoutine (
> +  IN VOID                      *DevCoreHandle
> +  );
> +
> +EFI_STATUS
> +UsbDeviceIsrRoutineTimerBased (
> +  IN VOID                      *DevCoreHandle
> +  );
> +
> +EFI_STATUS
> +UsbXdciDeviceConnect (
> +  IN VOID                      *DevCoreHandle
> +  );
> +
> +EFI_STATUS
> +UsbDeviceDisconnect (
> +  IN VOID                      *DevCoreHandle
> +  );
> +
> +EFI_STATUS
> +UsbDeviceGetSpeed (
> +  IN VOID                      *DevCoreHandle,
> +  IN USB_SPEED                 *Speed
> +  );
> +
> +EFI_STATUS
> +UsbDeviceSetLinkState (
> +  IN VOID                      *DevCoreHandle,
> +  IN USB_DEVICE_SS_LINK_STATE  State
> +  );
> +
> +EFI_STATUS
> +UsbDeviceSetAddress (
> +  IN VOID                      *DevCoreHandle,
> +  IN UINT32                    Address
> +  );
> +
> +EFI_STATUS
> +UsbDeviceSetConfiguration (
> +  IN VOID                      *DevCoreHandle,
> +  IN UINT32                    ConfigNum
> +  );
> +
> +EFI_STATUS
> +UsbDeviceInitEp (
> +  IN VOID                      *DevCoreHandle,
> +  IN USB_EP_INFO               *EpInfo
> +  );
> +
> +EFI_STATUS
> +UsbDeviceEpEnable (
> +  IN VOID                      *DevCoreHandle,
> +  IN USB_EP_INFO               *EpInfo
> +  );
> +
> +EFI_STATUS
> +UsbDeviceEpDisable (
> +  IN VOID                      *DevCoreHandle,
> +  IN USB_EP_INFO               *EpInfo
> +  );
> +
> +EFI_STATUS
> +UsbDeviceEpStall (
> +  IN VOID                      *DevCoreHandle,
> +  IN USB_EP_INFO               *EpInfo
> +  );
> +
> +EFI_STATUS
> +UsbDeviceEpClearStall (
> +  IN VOID                      *DevCoreHandle,
> +  IN USB_EP_INFO               *EpInfo
> +  );
> +
> +EFI_STATUS
> +UsbDeviceEpSetNrdy (
> +  IN VOID                      *DevCoreHandle,
> +  IN USB_EP_INFO               *EpInfo
> +  );
> +
> +EFI_STATUS
> +UsbDeviceEp0RxSetup (
> +  IN VOID                      *DevCoreHandle,
> +  IN UINT8                     *Buffer
> +  );
> +
> +EFI_STATUS
> +UsbDeviceEp0RxStatus (
> +  IN VOID                      *DevCoreHandle
> +  );
> +
> +EFI_STATUS
> +UsbDeviceEp0TxStatus (
> +  IN VOID                      *DevCoreHandle
> +  );
> +
> +EFI_STATUS
> +UsbXdciDeviceEpTxData (
> +  IN VOID                      *DevCoreHandle,
> +  IN USB_XFER_REQUEST          *XferReq
> +  );
> +
> +EFI_STATUS
> +UsbXdciDeviceEpRxData (
> +  IN VOID                      *DevCoreHandle,
> +  IN USB_XFER_REQUEST          *XferReq
> +  );
> +
> +EFI_STATUS
> +UsbDeviceEpCancelTransfer (
> +  IN VOID                      *DevCoreHandle,
> +  IN USB_EP_INFO               *EpInfo
> +  );
> +
> +#endif
> +
> diff --git a/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciInterface.h b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciInterface.h
> new file mode 100644
> index 0000000000..75ce0ecab3
> --- /dev/null
> +++ b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciInterface.h
> @@ -0,0 +1,241 @@
> +/** @file
> +  Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR>
> +
> +  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.
> +
> +**/
> +
> +#ifndef _USB_DCD_IF_H_
> +#define _USB_DCD_IF_H_
> +
> +/* Core driver for device controller
> + * @DevCoreInit: Intializes device controller
> + * @DevCoreDeinit: De-initializes device controller
> + * @DevCoreRegisterCallback: Registers callback function for
> + * an event to be called by the controller driver
> + * @DevCoreUnregisterCallback: Unregisters callback function
> + * for an event
> + * @DevCoreIsrRoutine: core interrupt service routine for
> + * device controller to be used by OS/stack-i/f layer
> + * @DevCoreConnect: Enable device controller to connect to USB host
> + * @DevCoreDisconnect: Soft disconnect device controller from
> + * USB host
> + * @DevCoreGetSpeed: Get USB bus Speed on which device controller
> + * is attached
> + * @DevCoreSetAddress: Set USB device address in device controller
> + * @DevCoreSetConfig: Set configuration number for device controller
> + * @DevCoreSetLinkState: Set link state for device controller
> + * @DevCoreInitEp: Initialize non-EP0 endpoint
> + * @DevCoreEpEnable: Enable endpoint
> + * @DevCoreEpDisable: Disable endpoint
> + * @DevCoreEpStall: Stall/Halt endpoint
> + * @DevCoreEpClearStall: Clear Stall/Halt on endpoint
> + * @DevCoreEpSetNrdy: Set endpoint to not ready state
> + * @DevCoreEp0RxSetupPkt: Receive SETUP packet on EP0
> + * @DevCoreEp0RxStatusPkt: Receive status packet on EP0
> + * @DevCoreEp0TxStatusPkt: Transmit status packet from EP0
> + * @DevCoreEpTxData: Transmit data from EP
> + * @DevCoreEpRxData: Received data on EP
> + * @DevCoreEpCancelTransfer: Cancel transfer on EP
> + */
> +
> +typedef
> +EFI_STATUS
> +(EFIAPI *DEV_CORE_INIT) (
> +  IN USB_DEV_CONFIG_PARAMS     *ConfigParams,
> +  IN VOID                      *ParentHandle,
> +  IN VOID                      **CoreHandle
> +  );
> +
> +typedef
> +EFI_STATUS
> +(EFIAPI *DEV_CORE_DEINIT) (
> +  IN VOID                      *CoreHandle,
> +  IN UINT32                    Flags
> +  );
> +
> +typedef
> +EFI_STATUS
> +(EFIAPI *DEV_CORE_REG_CALLBACK) (
> +  IN VOID                      *CoreHandle,
> +  IN USB_DEVICE_EVENT_ID       Event,
> +  IN USB_DEVICE_CALLBACK_FUNC  CallbackFn
> +  );
> +
> +typedef
> +EFI_STATUS
> +(EFIAPI *DEV_CORE_UNREG_CALLBACK) (
> +  IN VOID                      *CoreHandle,
> +  IN USB_DEVICE_EVENT_ID       Event
> +  );
> +
> +typedef
> +EFI_STATUS
> +(EFIAPI *DEV_CORE_ISR_ROUTINE) (
> +  IN VOID                      *CoreHandle
> +  );
> +
> +typedef
> +EFI_STATUS
> +(EFIAPI *DEV_CORE_CONNECT) (
> +  IN VOID                      *CoreHandle
> +  );
> +
> +typedef
> +EFI_STATUS
> +(EFIAPI *DEV_CORE_DISCONNECT) (
> +  IN VOID                      *CoreHandle
> +  );
> +
> +typedef
> +EFI_STATUS
> +(EFIAPI *DEV_CORE_GET_SPEED) (
> +  IN VOID                      *CoreHandle,
> +  IN USB_SPEED                 *Speed
> +  );
> +
> +typedef
> +EFI_STATUS
> +(EFIAPI *DEV_CORE_SET_ADDRESS) (
> +  IN VOID                      *CoreHandle,
> +  IN UINT32                    Address
> +  );
> +
> +typedef
> +EFI_STATUS
> +(EFIAPI *DEV_CORE_SET_CONFIG) (
> +  IN VOID                      *CoreHandle,
> +  IN UINT32                    ConfigNum
> +  );
> +
> +typedef
> +EFI_STATUS
> +(EFIAPI *DEV_CORE_SET_LINK_STATE) (
> +  IN VOID                      *CoreHandle,
> +  IN USB_DEVICE_SS_LINK_STATE  State
> +  );
> +
> +typedef
> +EFI_STATUS
> +(EFIAPI *DEV_CORE_INIT_EP) (
> +  IN VOID                      *CoreHandle,
> +  IN USB_EP_INFO               *EpInfo
> +  );
> +
> +typedef
> +EFI_STATUS
> +(EFIAPI *DEV_CORE_EP_ENABLE) (
> +  IN VOID                      *CoreHandle,
> +  IN USB_EP_INFO               *EpInfo
> +  );
> +
> +typedef
> +EFI_STATUS
> +(EFIAPI *DEV_CORE_EP_DISABLE) (
> +  IN VOID                      *CoreHandle,
> +  IN USB_EP_INFO               *EpInfo
> +  );
> +
> +typedef
> +EFI_STATUS
> +(EFIAPI *DEV_CORE_EP_STALL) (
> +  IN VOID                      *CoreHandle,
> +  IN USB_EP_INFO               *EpInfo
> +  );
> +
> +typedef
> +EFI_STATUS
> +(EFIAPI *DEV_CORE_EP_CLEAR_STALL) (
> +  IN VOID                      *CoreHandle,
> +  IN USB_EP_INFO               *EpInfo
> +  );
> +
> +typedef
> +EFI_STATUS
> +(EFIAPI *DEV_CORE_EP_SET_NRDY) (
> +  IN VOID                      *CoreHandle,
> +  IN USB_EP_INFO               *EpInfo
> +  );
> +
> +typedef
> +EFI_STATUS
> +(EFIAPI *DEV_CORE_EP0_RX_SETUP_PKT) (
> +  IN VOID                      *CoreHandle,
> +  IN UINT8                     *Buffer
> +  );
> +
> +typedef
> +EFI_STATUS
> +(EFIAPI *DEV_CORE_EP0_RX_STATUS_PKT) (
> +  IN VOID                      *CoreHandle
> +  );
> +
> +typedef
> +EFI_STATUS
> +(EFIAPI *DEV_CORE_EP0_TX_STATUS_PKT) (
> +  IN VOID                      *CoreHandle
> +  );
> +
> +typedef
> +EFI_STATUS
> +(EFIAPI *DEV_CORE_EP_TX_DATA) (
> +  IN VOID                      *CoreHandle,
> +  IN USB_XFER_REQUEST          *XferHandle
> +  );
> +
> +typedef
> +EFI_STATUS
> +(EFIAPI *DEV_CORE_EP_RX_DATA) (
> +  IN VOID                      *CoreHandle,
> +  IN USB_XFER_REQUEST          *XferHandle
> +  );
> +
> +typedef
> +EFI_STATUS
> +(EFIAPI *DEV_CORE_EP_CANCEL_TRANSFER) (
> +  IN VOID                      *CoreHandle,
> +  IN USB_EP_INFO               *EpInfo
> +  );
> +
> +struct UsbDeviceCoreDriver {
> +  DEV_CORE_INIT                 DevCoreInit;
> +  DEV_CORE_DEINIT               DevCoreDeinit;
> +  DEV_CORE_REG_CALLBACK         DevCoreRegisterCallback;
> +  DEV_CORE_UNREG_CALLBACK       DevCoreUnregisterCallback;
> +  DEV_CORE_ISR_ROUTINE          DevCoreIsrRoutine;
> +  DEV_CORE_ISR_ROUTINE          DevCoreIsrRoutineTimerBased;
> +  DEV_CORE_CONNECT              DevCoreConnect;
> +  DEV_CORE_DISCONNECT           DevCoreDisconnect;
> +  DEV_CORE_GET_SPEED            DevCoreGetSpeed;
> +  DEV_CORE_SET_ADDRESS          DevCoreSetAddress;
> +  DEV_CORE_SET_CONFIG           DevCoreSetConfig;
> +  DEV_CORE_SET_LINK_STATE       DevCoreSetLinkState;
> +  DEV_CORE_INIT_EP              DevCoreInitEp;
> +  DEV_CORE_EP_ENABLE            DevCoreEpEnable;
> +  DEV_CORE_EP_DISABLE           DevCoreEpDisable;
> +  DEV_CORE_EP_STALL             DevCoreEpStall;
> +  DEV_CORE_EP_CLEAR_STALL       DevCoreEpClearStall;
> +  DEV_CORE_EP_SET_NRDY          DevCoreEpSetNrdy;
> +  DEV_CORE_EP0_RX_SETUP_PKT     DevCoreEp0RxSetupPkt;
> +  DEV_CORE_EP0_RX_STATUS_PKT    DevCoreEp0RxStatusPkt;
> +  DEV_CORE_EP0_TX_STATUS_PKT    DevCoreEp0TxStatusPkt;
> +  DEV_CORE_EP_TX_DATA           DevCoreEpTxData;
> +  DEV_CORE_EP_RX_DATA           DevCoreEpRxData;
> +  DEV_CORE_EP_CANCEL_TRANSFER   DevCoreEpCancelTransfer;
> +};
> +
> +//
> +// This API is used to obtain the driver handle for HW-independent API
> +// @id: The ID of the core for which this driver is requested
> +//
> +const struct UsbDeviceCoreDriver *UsbDeviceGetCoreDriver(
> +  USB_CONTROLLER_ID id);
> +
> +#endif
> +
> diff --git a/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciTable.c b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciTable.c
> new file mode 100644
> index 0000000000..97a97db3db
> --- /dev/null
> +++ b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciTable.c
> @@ -0,0 +1,55 @@
> +/** @file
> +  Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR>
> +
> +  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.
> +
> +**/
> +
> +#include <Library/UsbDeviceLib.h>
> +#include "XdciCommon.h"
> +#include "XdciDevice.h"
> +#include "XdciInterface.h"
> +#include "XdciDWC.h"
> +#include "UsbDeviceMode.h"
> +
> +static const struct UsbDeviceCoreDriver CoreDriverTbl[USB_CORE_ID_MAX] = {
> +  DwcXdciCoreInit,
> +  DwcXdciCoreDeinit,
> +  DwcXdciCoreRegisterCallback,
> +  DwcXdciCoreUnregisterCallback,
> +  DwcXdciCoreIsrRoutine,
> +  DwcXdciCoreIsrRoutineTimerBased,
> +  DwcXdciCoreConnect,
> +  DwcXdciCoreDisconnect,
> +  DwcXdciCoreGetSpeed,
> +  DwcXdciCoreSetAddress,
> +  DwcXdciCoreSetConfig,
> +  DwcXdciSetLinkState,
> +  DwcXdciInitEp,
> +  DwcXdciEpEnable,
> +  DwcXdciEpDisable,
> +  DwcXdciEpStall,
> +  DwcXdciEpClearStall,
> +  DwcXdciEpSetNrdy,
> +  DwcXdciEp0ReceiveSetupPkt,
> +  DwcXdciEp0ReceiveStatusPkt,
> +  DwcXdciEp0SendStatusPkt,
> +  DwcXdciEpTxData,
> +  DwcXdciEpRxData,
> +  DwcXdciEpCancelTransfer
> +};
> +
> +const struct UsbDeviceCoreDriver *UsbDeviceGetCoreDriver(USB_CONTROLLER_ID id)
> +{
> +  if (id >= USB_CORE_ID_MAX)
> +    return NULL;
> +
> +  return &CoreDriverTbl[id];
> +}
> +
> diff --git a/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciUtility.c b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciUtility.c
> new file mode 100644
> index 0000000000..2e02475cd0
> --- /dev/null
> +++ b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciUtility.c
> @@ -0,0 +1,148 @@
> +/** @file
> +  Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR>
> +
> +  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.
> +
> +**/
> +
> +#include "XdciUtility.h"
> +
> +VOID
> +PrintDeviceDescriptor (
> +  IN USB_DEVICE_DESCRIPTOR    *DevDesc
> +  )
> +{
> +  DEBUG ((DEBUG_INFO, "--- Device Descriptor ---\n"));
> +  DEBUG ((DEBUG_INFO, "Length            : 0x%x\n", DevDesc->Length));
> +  DEBUG ((DEBUG_INFO, "DescriptorType    : 0x%x\n", DevDesc->DescriptorType));
> +  DEBUG ((DEBUG_INFO, "BcdUSB            : 0x%x\n", DevDesc->BcdUSB));
> +  DEBUG ((DEBUG_INFO, "DeviceClass       : 0x%x\n", DevDesc->DeviceClass));
> +  DEBUG ((DEBUG_INFO, "DeviceSubClass    : 0x%x\n", DevDesc->DeviceSubClass));
> +  DEBUG ((DEBUG_INFO, "DeviceProtocol    : 0x%x\n", DevDesc->DeviceProtocol));
> +  DEBUG ((DEBUG_INFO, "MaxPacketSize0    : 0x%x\n", DevDesc->MaxPacketSize0));
> +  DEBUG ((DEBUG_INFO, "IdVendor          : 0x%x\n", DevDesc->IdVendor));
> +  DEBUG ((DEBUG_INFO, "IdProduct         : 0x%x\n", DevDesc->IdProduct));
> +  DEBUG ((DEBUG_INFO, "BcdDevice         : 0x%x\n", DevDesc->BcdDevice));
> +  DEBUG ((DEBUG_INFO, "StrManufacturer   : 0x%x\n", DevDesc->StrManufacturer));
> +  DEBUG ((DEBUG_INFO, "StrProduct        : 0x%x\n", DevDesc->StrProduct));
> +  DEBUG ((DEBUG_INFO, "StrSerialNumber   : 0x%x\n", DevDesc->StrSerialNumber));
> +  DEBUG ((DEBUG_INFO, "NumConfigurations : 0x%x\n", DevDesc->NumConfigurations));
> +  DEBUG ((DEBUG_INFO, "\n"));
> +}
> +
> +VOID
> +PrintConfigDescriptor (
> +  IN EFI_USB_CONFIG_DESCRIPTOR    *ConfigDesc
> +  )
> +{
> +  DEBUG ((DEBUG_INFO, "--- Configuration Descriptor ---\n"));
> +  DEBUG ((DEBUG_INFO, "Length             : 0x%x\n", ConfigDesc->Length));
> +  DEBUG ((DEBUG_INFO, "DescriptorType     : 0x%x\n", ConfigDesc->DescriptorType));
> +  DEBUG ((DEBUG_INFO, "TotalLength        : 0x%x\n", ConfigDesc->TotalLength));
> +  DEBUG ((DEBUG_INFO, "NumInterfaces      : 0x%x\n", ConfigDesc->NumInterfaces));
> +  DEBUG ((DEBUG_INFO, "ConfigurationValue : 0x%x\n", ConfigDesc->ConfigurationValue));
> +  DEBUG ((DEBUG_INFO, "Configuration      : 0x%x\n", ConfigDesc->Configuration));
> +  DEBUG ((DEBUG_INFO, "Attributes         : 0x%x\n", ConfigDesc->Attributes));
> +  DEBUG ((DEBUG_INFO, "MaxPower           : 0x%x\n", ConfigDesc->MaxPower));
> +  DEBUG ((DEBUG_INFO, "\n"));
> +}
> +
> +VOID
> +PrintInterfaceDescriptor (
> +  IN EFI_USB_INTERFACE_DESCRIPTOR    *IfDesc
> +  )
> +{
> +  DEBUG ((DEBUG_INFO, "--- Interface Descriptor ---\n"));
> +  DEBUG ((DEBUG_INFO, "Length            : 0x%x\n", IfDesc->Length));
> +  DEBUG ((DEBUG_INFO, "DescriptorType    : 0x%x\n", IfDesc->DescriptorType));
> +  DEBUG ((DEBUG_INFO, "InterfaceNumber   : 0x%x\n", IfDesc->InterfaceNumber));
> +  DEBUG ((DEBUG_INFO, "AlternateSetting  : 0x%x\n", IfDesc->AlternateSetting));
> +  DEBUG ((DEBUG_INFO, "NumEndpoints      : 0x%x\n", IfDesc->NumEndpoints));
> +  DEBUG ((DEBUG_INFO, "InterfaceClass    : 0x%x\n", IfDesc->InterfaceClass));
> +  DEBUG ((DEBUG_INFO, "InterfaceSubClass : 0x%x\n", IfDesc->InterfaceSubClass));
> +  DEBUG ((DEBUG_INFO, "InterfaceProtocol : 0x%x\n", IfDesc->InterfaceProtocol));
> +  DEBUG ((DEBUG_INFO, "Interface         : 0x%x\n", IfDesc->Interface));
> +  DEBUG ((DEBUG_INFO, "\n"));
> +}
> +
> +VOID
> +PrintEpDescriptor (
> +  IN EFI_USB_ENDPOINT_DESCRIPTOR    *EpDesc
> +  )
> +{
> +  DEBUG ((DEBUG_INFO, "--- Endpoint Descriptor ---\n"));
> +  DEBUG ((DEBUG_INFO, "Length          : 0x%x\n", EpDesc->Length));
> +  DEBUG ((DEBUG_INFO, "DescriptorType  : 0x%x\n", EpDesc->DescriptorType));
> +  DEBUG ((DEBUG_INFO, "EndpointAddress : 0x%x\n", EpDesc->EndpointAddress));
> +  DEBUG ((DEBUG_INFO, "Attributes      : 0x%x\n", EpDesc->Attributes));
> +  DEBUG ((DEBUG_INFO, "MaxPacketSize   : 0x%x\n", EpDesc->MaxPacketSize));
> +  DEBUG ((DEBUG_INFO, "Interval        : 0x%x\n", EpDesc->Interval));
> +  DEBUG ((DEBUG_INFO, "\n"));
> +}
> +
> +VOID
> +PrintEpCompDescriptor (
> +  IN EFI_USB_ENDPOINT_COMPANION_DESCRIPTOR    *EpDesc
> +  )
> +{
> +  DEBUG ((DEBUG_INFO, "--- Endpoint Companion Descriptor ---\n"));
> +  DEBUG ((DEBUG_INFO, "Length           : 0x%x\n", EpDesc->Length));
> +  DEBUG ((DEBUG_INFO, "DescriptorType   : 0x%x\n", EpDesc->DescriptorType));
> +  DEBUG ((DEBUG_INFO, "MaxBurst         : 0x%x\n", EpDesc->MaxBurst));
> +  DEBUG ((DEBUG_INFO, "Attributes       : 0x%x\n", EpDesc->Attributes));
> +  DEBUG ((DEBUG_INFO, "BytesPerInterval : 0x%x\n", EpDesc->BytesPerInterval));
> +  DEBUG ((DEBUG_INFO, "\n"));
> +}
> +
> +VOID
> +PrintStringDescriptor (
> +  IN USB_STRING_DESCRIPTOR    *StrDesc
> +  )
> +{
> +  UINT16 StrLen = 0;
> +
> +  if (StrDesc->Length > 2) {
> +    StrLen = ((StrDesc->Length - 2) >> 1);
> +    DEBUG ((DEBUG_INFO, "--- String Descriptor ---\n"));
> +    DEBUG ((DEBUG_INFO, "Length         : 0x%x\n", StrDesc->Length));
> +    DEBUG ((DEBUG_INFO, "DescriptorType : 0x%x\n", StrDesc->DescriptorType));
> +    DEBUG ((DEBUG_INFO, "String         : %s\n",   StrDesc->LangID));
> +  }
> +  DEBUG ((DEBUG_INFO, "\n"));
> +}
> +
> +VOID
> +PrintDeviceRequest (
> +  IN EFI_USB_DEVICE_REQUEST    *DevReq
> +  )
> +{
> +  DEBUG ((DEBUG_INFO, "--- Device Request ---\n"));
> +  DEBUG ((DEBUG_INFO, "RequestType : 0x%x\n", DevReq->RequestType));
> +  DEBUG ((DEBUG_INFO, "Request     : 0x%x\n", DevReq->Request));
> +  DEBUG ((DEBUG_INFO, "Value       : 0x%x\n", DevReq->Value));
> +  DEBUG ((DEBUG_INFO, "Index       : 0x%x\n", DevReq->Index));
> +  DEBUG ((DEBUG_INFO, "Length      : 0x%x\n", DevReq->Length));
> +  DEBUG ((DEBUG_INFO, "\n"));
> +}
> +
> +#ifdef SUPPORT_SUPER_SPEED
> +VOID
> +PrintBOSDescriptor (
> +  IN EFI_USB_BOS_DESCRIPTOR    *BosDesc
> +  )
> +{
> +  DEBUG ((DEBUG_INFO, "--- BOS Descriptor ---\n"));
> +  DEBUG ((DEBUG_INFO, "Length           : 0x%x\n", BosDesc->Length));
> +  DEBUG ((DEBUG_INFO, "DescriptorType   : 0x%x\n", BosDesc->DescriptorType));
> +  DEBUG ((DEBUG_INFO, "TotalLength      : 0x%x\n", BosDesc->TotalLength));
> +  DEBUG ((DEBUG_INFO, "NumDeviceCaps    : 0x%x\n", BosDesc->NumDeviceCaps));
> +  DEBUG ((DEBUG_INFO, "\n"));
> +}
> +#endif
> +
> diff --git a/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciUtility.h b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciUtility.h
> new file mode 100644
> index 0000000000..e3d004e579
> --- /dev/null
> +++ b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciUtility.h
> @@ -0,0 +1,62 @@
> +/** @file
> +  Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR>
> +
> +  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.
> +
> +**/
> +
> +#ifndef _XDCI_UTILITY_H_
> +#define _XDCI_UTILITY_H_
> +
> +#include <Library/UsbDeviceLib.h>
> +
> +VOID
> +PrintDeviceDescriptor (
> +  IN USB_DEVICE_DESCRIPTOR    *DevDesc
> +  );
> +
> +VOID
> +PrintConfigDescriptor (
> +  IN EFI_USB_CONFIG_DESCRIPTOR    *ConfigDesc
> +  );
> +
> +VOID
> +PrintInterfaceDescriptor (
> +  IN EFI_USB_INTERFACE_DESCRIPTOR    *IfDesc
> +  );
> +
> +VOID
> +PrintEpDescriptor (
> +  IN EFI_USB_ENDPOINT_DESCRIPTOR    *EpDesc
> +  );
> +
> +VOID
> +PrintEpCompDescriptor (
> +  IN EFI_USB_ENDPOINT_COMPANION_DESCRIPTOR    *EpDesc
> +  );
> +
> +VOID
> +PrintStringDescriptor (
> +  IN USB_STRING_DESCRIPTOR    *StrDesc
> +  );
> +
> +VOID
> +PrintDeviceRequest (
> +  IN EFI_USB_DEVICE_REQUEST    *DevReq
> +  );
> +
> +#ifdef SUPPORT_SUPER_SPEED
> +VOID
> +PrintBOSDescriptor (
> +  IN EFI_USB_BOS_DESCRIPTOR    *BosDesc
> +  );
> +#endif
> +
> +#endif
> +
> diff --git a/Silicon/Synopsys/DesignWare/Include/Library/UsbDeviceLib.h b/Silicon/Synopsys/DesignWare/Include/Library/UsbDeviceLib.h
> new file mode 100644
> index 0000000000..fe5f3bcd03
> --- /dev/null
> +++ b/Silicon/Synopsys/DesignWare/Include/Library/UsbDeviceLib.h
> @@ -0,0 +1,323 @@
> +/** @file
> +  Copyright (c) 2009 - 2016, Intel Corporation. All rights reserved.<BR>
> +
> +  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.
> +
> +**/
> +
> +#ifndef _EFI_XDCI_LIB_H_
> +#define _EFI_XDCI_LIB_H_
> +
> +#include <Uefi.h>
> +#include <Library/DebugLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Protocol/UsbIo.h>
> +
> +#define MAX_DESCRIPTOR_SIZE         64
> +#define STRING_ARR_SIZE             (MAX_DESCRIPTOR_SIZE - 2)
> +#define USB_ADDRESS_TABLE_SIZE      16  //4
> +
> +//
> +// Endpoint Zero
> +//
> +#define USB_EP0_MAX_PKT_SIZE_HS     0x40 // High Speed mode is explicitly set as 64 bytes
> +#define USB_EP0_MAX_PKT_SIZE_SS     0x9  // Must be 0x9 (2^9 = 512 Bytes) in SuperSpeed mode
> +#define USB_EPO_MAX_PKT_SIZE_ALL    512  // Overall max bytes for any type
> +
> +//
> +// Bulk Endpoints
> +//
> +#define USB_BULK_EP_PKT_SIZE_HS     0x200 // Bulk-Endpoint HighSpeed
> +#define USB_BULK_EP_PKT_SIZE_SS     0x400 // Bulk-Endpoint SuperSpeed
> +#define USB_BULK_EP_PKT_SIZE_MAX    USB_BULK_EP_PKT_SIZE_SS
> +
> +//
> +// Transmit Direction Bits
> +//
> +#define USB_ENDPOINT_DIR_OUT                 0x00
> +
> +//
> +// Endpoint Companion Bulk Attributes
> +//
> +#define USB_EP_BULK_BM_ATTR_MASK    0x1F
> +
> +//
> +// Configuration Modifiers (Attributes)
> +//
> +#define USB_BM_ATTR_RESERVED        0x80
> +#define USB_BM_ATTR_SELF_POWERED    0x40
> +#define USB_BM_ATTR_REMOTE_WAKE     0X20
> +
> +//
> +// USB BCD version
> +//
> +#define USB_BCD_VERSION_LS          0x0110
> +#define USB_BCD_VERSION_HS          0x0200
> +#define USB_BCD_VERSION_SS          0x0300
> +
> +//
> +// Device RequestType Flags
> +//
> +#define USB_RT_TX_DIR_H_TO_D        (0x0)       // Tx direction Host to Device
> +#define USB_RT_TX_DIR_D_TO_H        (0x1 << 7)  // Tx direction Device to Host
> +#define USB_RT_TX_DIR_MASK          (0x80)
> +
> +//
> +// USB request type
> +//
> +#define USB_REQ_TYPE_MASK           (0x60)
> +
> +//
> +// Usb control transfer target
> +//
> +#define USB_TARGET_MASK             (0x1F)
> +
> +//
> +// Device GetStatus bits
> +//
> +#define USB_STATUS_SELFPOWERED      (0x01)
> +#define USB_STATUS_REMOTEWAKEUP     (0x02)
> +
> +//
> +// USB Device class identifiers
> +//
> +#define USB_DEVICE_MS_CLASS         (0x08)
> +#define USB_DEVICE_VENDOR_CLASS     (0xFF)
> +
> +//
> +// USB Descriptor types
> +//
> +#define USB_DESC_TYPE_BOS                    0x0F
> +#define USB_DESC_TYPE_DEVICE_CAPABILITY      0x10
> +#define USB_DESC_TYPE_SS_ENDPOINT_COMPANION  0x30
> +
> +#ifdef SUPPORT_SUPER_SPEED
> +//
> +// USB device capability Type Codes
> +// USB3 Table 9-13
> +//
> +typedef enum {
> +  WirelessUSB = 0x01,
> +  USB2Extension,
> +  SuperSpeedUSB,
> +  ContainerID,
> +  SuperSpeedPlusUSB = 0x0A
> +} USB_DEVICE_CAP_TYPE_CODE;
> +#endif
> +
> +//
> +// USB device states from USB spec sec 9.1
> +//
> +typedef enum {
> +  UsbDevStateOff = 0,
> +  UsbDevStateInit,
> +  UsbDevStateAttached,
> +  UsbDevStatePowered,
> +  UsbDevStateDefault,
> +  UsbDevStateAddress,
> +  UsbDevStateConfigured,
> +  UsbDevStateSuspended,
> +  UsbDevStateError
> +} USB_DEVICE_STATE;
> +
> +//
> +// The following set of structs are used during USB data transaction
> +// operatitions, including requests and completion events.
> +//
> +#pragma pack(1)
> +
> +typedef struct {
> +  UINT32     EndpointNum;
> +  UINT8      EndpointDir;
> +  UINT8      EndpointType;
> +  UINT32     Length;
> +  VOID       *Buffer;
> +} EFI_USB_DEVICE_XFER_INFO;
> +
> +//
> +// SuperSpeed Endpoint companion descriptor
> +// USB3 table 9-22
> +//
> +typedef struct {
> +  UINT8      Length;
> +  UINT8      DescriptorType;
> +  UINT8      MaxBurst;
> +  UINT8      Attributes;
> +  UINT16     BytesPerInterval;
> +} EFI_USB_ENDPOINT_COMPANION_DESCRIPTOR;
> +
> +typedef struct {
> +  EFI_USB_ENDPOINT_DESCRIPTOR              *EndpointDesc;
> +  EFI_USB_ENDPOINT_COMPANION_DESCRIPTOR    *EndpointCompDesc;
> +} USB_DEVICE_ENDPOINT_INFO, USB_DEVICE_ENDPOINT_OBJ;
> +
> +typedef struct {
> +  VOID        *Buffer;
> +  UINT32      Length;
> +} USB_DEVICE_IO_INFO;
> +
> +typedef struct {
> +  USB_DEVICE_IO_INFO           IoInfo;
> +  USB_DEVICE_ENDPOINT_INFO     EndpointInfo;
> +} USB_DEVICE_IO_REQ;
> +
> +//
> +// Optional string descriptor
> +//
> +typedef struct {
> +  UINT8           Length;
> +  UINT8           DescriptorType;
> +  UINT16          LangID[STRING_ARR_SIZE];
> +} USB_STRING_DESCRIPTOR;
> +
> +//
> +// The following structures abstract the device descriptors a class
> +// driver needs to provide to the USBD core.
> +// These structures are filled & owned by the class/function layer.
> +//
> +typedef struct {
> +  EFI_USB_INTERFACE_DESCRIPTOR         *InterfaceDesc;
> +  USB_DEVICE_ENDPOINT_OBJ              *EndpointObjs;
> +} USB_DEVICE_INTERFACE_OBJ;
> +
> +typedef struct {
> +  EFI_USB_CONFIG_DESCRIPTOR     *ConfigDesc;
> +  VOID                          *ConfigAll;
> +  USB_DEVICE_INTERFACE_OBJ      *InterfaceObjs;
> +} USB_DEVICE_CONFIG_OBJ;
> +
> +#ifdef SUPPORT_SUPER_SPEED
> +//
> +// SuperSpeed Binary Device Object Store(BOS) descriptor
> +// USB3 9.6.2
> +//
> +typedef struct {
> +  UINT8      Length;
> +  UINT8      DescriptorType;
> +  UINT16     TotalLength;
> +  UINT8      NumDeviceCaps;
> +} EFI_USB_BOS_DESCRIPTOR;
> +
> +//
> +// Generic Header of Device Capability descriptor
> +// USB3 9.6.2.2
> +//
> +typedef struct {
> +  UINT8      Length;
> +  UINT8      DescriptorType;
> +  UINT8      DevCapabilityType;
> +  UINT8      CapDependent;
> +} EFI_USB_SS_DEVICE_CAP_DESCRIPTOR;
> +
> +//
> +// USB2.0 Extension descriptor
> +// USB3 Table 9-14
> +//
> +typedef struct {
> +  UINT8      Length;
> +  UINT8      DescriptorType;
> +  UINT8      DeviceCapabilityType;
> +  UINT32     Attributes;
> +} EFI_USB_USB2_EXT_CAP_DESCRIPTOR;
> +
> +//
> +// SuperSpeed USB Device Capability descriptor
> +// USB3 Table 9-15
> +//
> +typedef struct {
> +  UINT8      Length;
> +  UINT8      DescriptorType;
> +  UINT8      DeviceCapabilityType;
> +  UINT8      Attributes;
> +  UINT16     SpeedSupported;
> +  UINT8      FunctionalitySupport;
> +  UINT8      U1DevExitLat;
> +  UINT16     U2DevExitLat;
> +} EFI_USB_SS_USB_DEV_CAP_DESCRIPTOR;
> +
> +//
> +// Container ID descriptor
> +// USB3 Table 9-16
> +//
> +typedef struct {
> +  UINT8      Length;
> +  UINT8      DescriptorType;
> +  UINT8      DeviceCapabilityType;
> +  UINT8      Reserved;
> +  UINT8      UUID[16];
> +} EFI_USB_CONTAINER_ID_DESCRIPTOR;
> +
> +//
> +// Container ID descriptor
> +// USB3 Table 9-16
> +//
> +typedef struct {
> +  UINT8      Length;
> +  UINT8      DescriptorType;
> +  UINT8      DeviceCapabilityType;
> +  UINT8      ReservedByte;
> +  UINT32     Attributes;
> +  UINT16     FunctionalitySupport;
> +  UINT16     ReservedWord;
> +  UINT32     SublinkSpeedAttr[2];
> +} EFI_USB_SS_PLUS_USB_DEV_CAP_DESCRIPTOR;
> +
> +#endif
> +
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_USB_CONFIG_CALLBACK) (
> +  IN UINT8                      CfgVal
> +  );
> +
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_USB_SETUP_CALLBACK) (
> +  IN EFI_USB_DEVICE_REQUEST     *CtrlRequest,
> +  IN USB_DEVICE_IO_INFO         *IoInfo
> +  );
> +
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_USB_DATA_CALLBACK) (
> +  IN EFI_USB_DEVICE_XFER_INFO   *XferInfo
> +  );
> +
> +typedef struct {
> +  USB_DEVICE_DESCRIPTOR       *DeviceDesc;
> +  USB_DEVICE_CONFIG_OBJ       *ConfigObjs;
> +  USB_STRING_DESCRIPTOR       *StringTable;
> +#ifdef SUPPORT_SUPER_SPEED
> +  EFI_USB_BOS_DESCRIPTOR      *BosDesc;
> +#endif
> +  UINT8                       StrTblEntries;
> +  EFI_USB_CONFIG_CALLBACK     ConfigCallback;
> +  EFI_USB_SETUP_CALLBACK      SetupCallback;
> +  EFI_USB_DATA_CALLBACK       DataCallback;
> +} USB_DEVICE_OBJ;
> +
> +//
> +// Main USBD driver object structure containing all data necessary
> +// for USB device mode processing at this layer
> +//
> +typedef struct {
> +  USB_DEVICE_OBJ              *UsbdDevObj;      /* pointer to a Device Object */
> +  VOID                        *XdciDrvObj;      /* Opaque handle to XDCI driver */
> +  BOOLEAN                     XdciInitialized;  /* flag to specify if the XDCI driver is initialized */
> +  USB_DEVICE_CONFIG_OBJ       *ActiveConfigObj; /* pointer to currently active configuraiton */
> +  USB_DEVICE_STATE            State;            /* current state of the USB Device state machine */
> +  UINT8                       Address;          /* configured device address */
> +} USB_DEVICE_DRIVER_OBJ;
> +
> +#pragma pack()
> +
> +#endif
> +
> diff --git a/Silicon/Synopsys/DesignWare/Include/Protocol/EfiUsbFnIo.h b/Silicon/Synopsys/DesignWare/Include/Protocol/EfiUsbFnIo.h
> new file mode 100644
> index 0000000000..97f276f1cc
> --- /dev/null
> +++ b/Silicon/Synopsys/DesignWare/Include/Protocol/EfiUsbFnIo.h
> @@ -0,0 +1,430 @@
> +/** @file
> +  EFI USB function IO Protocol
> +  This protocol supports Usb Function IO API.
> +  Copyright (c) 1999 - 2017, Intel Corporation. All rights reserved.<BR>
> +
> +  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.
> +
> +**/
> +
> +#ifndef __EFI_USB_FUNC_IO_H__
> +#define __EFI_USB_FUNC_IO_H__
> +
> +#include <IndustryStandard/Usb.h>
> +
> +#define EFI_USBFN_IO_PROTOCOL_REVISION   0x00010001
> +
> +//
> +// {32D2963A-FE5D-4f30-B633-6E5DC55803CC}
> +// #define EFI_USBFN_IO_PROTOCOL_GUID  {0x32d2963a, 0xfe5d, 0x4f30, 0xb6, 0x33, 0x6e, 0x5d, 0xc5, 0x58, 0x3, 0xcc };
> +//
> +
> +typedef struct _EFI_USBFN_IO_PROTOCOL   EFI_USBFN_IO_PROTOCOL;
> +
> +//
> +// USB standard descriptors and reqeust
> +//
> +typedef USB_DEVICE_REQUEST        EFI_USB_DEVICE_REQUEST;
> +typedef USB_DEVICE_DESCRIPTOR     EFI_USB_DEVICE_DESCRIPTOR;
> +typedef USB_CONFIG_DESCRIPTOR     EFI_USB_CONFIG_DESCRIPTOR;
> +typedef USB_INTERFACE_DESCRIPTOR  EFI_USB_INTERFACE_DESCRIPTOR;
> +typedef USB_ENDPOINT_DESCRIPTOR   EFI_USB_ENDPOINT_DESCRIPTOR;
> +
> +typedef enum _EFI_USBFN_PORT_TYPE {
> +  EfiUsbUnknownPort = 0,
> +  EfiUsbStandardDownstreamPort,
> +  EfiUsbChargingDownstreamPort,
> +  EfiUsbDedicatedChargingPort,
> +  EfiUsbInvalidDedicatedChargingPort
> +} EFI_USBFN_PORT_TYPE;
> +
> +/**
> + USB_DEVICE_DESCRIPTOR, USB_CONFIG_DESCRIPTOR, USB_INTERFACE_DESCRIPTOR, and
> + USB_ENDPOINT_DESCRIPTOR are already defined
> + in UEFI spec 2.3, as par USB 2.0 spec.
> +**/
> +
> +typedef struct {
> +  EFI_USB_INTERFACE_DESCRIPTOR        *InterfaceDescriptor;
> +  EFI_USB_ENDPOINT_DESCRIPTOR         **EndpointDescriptorTable;
> +} EFI_USB_INTERFACE_INFO;
> +
> +typedef struct {
> +  EFI_USB_CONFIG_DESCRIPTOR           *ConfigDescriptor;
> +  EFI_USB_INTERFACE_INFO              **InterfaceInfoTable;
> +} EFI_USB_CONFIG_INFO;
> +
> +typedef struct {
> +  EFI_USB_DEVICE_DESCRIPTOR           *DeviceDescriptor;
> +  EFI_USB_CONFIG_INFO                 **ConfigInfoTable;
> +} EFI_USB_DEVICE_INFO;
> +
> +
> +typedef enum _EFI_USB_ENDPOINT_TYPE {
> +  UsbEndpointControl     = 0x00,
> +  UsbEndpointIsochronous = 0x01,
> +  UsbEndpointBulk        = 0x02,
> +  UsbEndpointInterrupt   = 0x03
> +} EFI_USB_ENDPOINT_TYPE;
> +
> +
> +typedef enum _EFI_USBFN_DEVICE_INFO_ID {
> +  EfiUsbDeviceInfoUnknown = 0,
> +  EfiUsbDeviceInfoSerialNumber,
> +  EfiUsbDeviceInfoManufacturerName,
> +  EfiUsbDeviceInfoProductName
> +} EFI_USBFN_DEVICE_INFO_ID;
> +
> +
> +typedef enum _EFI_USBFN_ENDPOINT_DIRECTION {
> +  EfiUsbEndpointDirectionHostOut  = 0,
> +  EfiUsbEndpointDirectionHostIn,
> +  EfiUsbEndpointDirectionDeviceTx = EfiUsbEndpointDirectionHostIn,
> +  EfiUsbEndpointDirectionDeviceRx = EfiUsbEndpointDirectionHostOut
> +} EFI_USBFN_ENDPOINT_DIRECTION;
> +
> +
> +typedef enum _EFI_USBFN_MESSAGE {
> +  //
> +  // Nothing
> +  //
> +  EfiUsbMsgNone = 0,
> +  //
> +  // SETUP packet is received, returned Buffer contains
> +  // EFI_USB_DEVICE_REQUEST struct
> +  //
> +  EfiUsbMsgSetupPacket,
> +  //
> +  // Indicates that some of the requested data has been received from the
> +  // host. It is the responsibility of the class driver to determine if it
> +  // needs to wait for any remaining data. Returned Buffer contains
> +  // EFI_USBFN_TRANSFER_RESULT struct containing endpoint number, transfer
> +  // status and count of bytes received.
> +  //
> +  EfiUsbMsgEndpointStatusChangedRx,
> +  //
> +  // Indicates that some of the requested data has been transmitted to the
> +  // host. It is the responsibility of the class driver to determine if any
> +  // remaining data needs to be resent. Returned Buffer contains
> +  // EFI_USBFN_TRANSFER_RESULT struct containing endpoint number, transfer
> +  // status and count of bytes sent.
> +  //
> +  EfiUsbMsgEndpointStatusChangedTx,
> +  //
> +  // DETACH bus event signaled
> +  //
> +  EfiUsbMsgBusEventDetach,
> +  //
> +  // ATTACH bus event signaled
> +  //
> +  EfiUsbMsgBusEventAttach,
> +  //
> +  // RESET bus event signaled
> +  //
> +  EfiUsbMsgBusEventReset,
> +  //
> +  // SUSPEND bus event signaled
> +  //
> +  EfiUsbMsgBusEventSuspend,
> +  //
> +  // RESUME bus event signaled
> +  //
> +  EfiUsbMsgBusEventResume,
> +  //
> +  // Bus speed updated, returned buffer indicated bus speed using
> +  // following enumeration named EFI_USB_BUS_SPEED
> +  //
> +  EfiUsbMsgBusEventSpeed
> +} EFI_USBFN_MESSAGE;
> +
> +
> +typedef enum _EFI_USBFN_TRANSFER_STATUS {
> +  UsbTransferStatusUnknown = 0,
> +  UsbTransferStatusComplete,
> +  UsbTransferStatusAborted,
> +  UsbTransferStatusActive,
> +  UsbTransferStatusNone
> +} EFI_USBFN_TRANSFER_STATUS;
> +
> +
> +typedef struct _EFI_USBFN_TRANSFER_RESULT {
> +  UINTN                         BytesTransferred;
> +  EFI_USBFN_TRANSFER_STATUS     TransferStatus;
> +  UINT8                         EndpointIndex;
> +  EFI_USBFN_ENDPOINT_DIRECTION  Direction;
> +  VOID                          *Buffer;
> +} EFI_USBFN_TRANSFER_RESULT;
> +
> +typedef enum _EFI_USB_BUS_SPEED {
> +  UsbBusSpeedUnknown = 0,
> +  UsbBusSpeedLow,
> +  UsbBusSpeedFull,
> +  UsbBusSpeedHigh,
> +  UsbBusSpeedSuper,
> +  UsbBusSpeedMaximum = UsbBusSpeedSuper
> +} EFI_USB_BUS_SPEED;
> +
> +typedef union _EFI_USBFN_MESSAGE_PAYLOAD {
> +  EFI_USB_DEVICE_REQUEST      udr;
> +  EFI_USBFN_TRANSFER_RESULT   utr;
> +  EFI_USB_BUS_SPEED           ubs;
> +} EFI_USBFN_MESSAGE_PAYLOAD;
> +
> +typedef enum _EFI_USBFN_POLICY_TYPE {
> +  EfiUsbPolicyUndefined = 0,
> +  EfiUsbPolicyMaxTransactionSize,
> +  EfiUsbPolicyZeroLengthTerminationSupport,
> +  EfiUsbPolicyZeroLengthTermination
> +} EFI_USBFN_POLICY_TYPE;
> +
> +
> +/**
> +
> + Allocates transfer buffer of the specified size that satisfies
> + controller requirements.
> +
> + The AllocateTransferBuffer function allocates a memory region of Size bytes and
> + returns the address of the allocated memory that satisfies underlying
> + controller requirements in the location referenced by Buffer.
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI * EFI_USBFN_IO_ALLOCATE_TRANSFER_BUFFER) (
> +  IN EFI_USBFN_IO_PROTOCOL    *This,
> +  IN UINTN                    Size,
> +  OUT VOID                    **Buffer
> +  );
> +
> +/**
> +
> +  Deallocates the memory allocated for the transfer buffer by AllocateTransferBuffer function.
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI * EFI_USBFN_IO_FREE_TRANSFER_BUFFER) (
> +  IN EFI_USBFN_IO_PROTOCOL    *This,
> +  IN VOID                     *Buffer
> +  );
> +
> +/**
> +  Returns information about what type of device was attached.
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI * EFI_USBFN_IO_DETECT_PORT) (
> +  IN EFI_USBFN_IO_PROTOCOL   *This,
> +  OUT EFI_USBFN_PORT_TYPE    *PortType
> +  );
> +
> +/**
> +  Configure endpoints based on supplied device and configuration descriptors.
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI * EFI_USBFN_IO_CONFIGURE_ENABLE_ENDPOINTS) (
> +  IN EFI_USBFN_IO_PROTOCOL         *This,
> +  IN EFI_USB_DEVICE_INFO           *DeviceInfo
> +  );
> +
> +
> +/**
> +  Returns the maximum packet size of the specified endpoint type for the supplied bus speed.
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI * EFI_USBFN_IO_GET_ENDPOINT_MAXPACKET_SIZE) (
> +  IN EFI_USBFN_IO_PROTOCOL       *This,
> +  IN EFI_USB_ENDPOINT_TYPE       EndpointType,
> +  IN EFI_USB_BUS_SPEED           BusSpeed,
> +  OUT UINT16                     *MaxPacketSize
> +  );
> +
> +/**
> +  Returns the maximum supported transfer size.
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI * EFI_USBFN_IO_GET_MAXTRANSFER_SIZE) (
> +  IN EFI_USBFN_IO_PROTOCOL     *This,
> +  OUT UINTN                    *MaxTransferSize
> +  );
> +
> +/**
> +  Returns device specific information based on the supplied identifier as a
> +  Unicode string.
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI * EFI_USBFN_IO_GET_DEVICE_INFO) (
> +  IN EFI_USBFN_IO_PROTOCOL      *This,
> +  IN EFI_USBFN_DEVICE_INFO_ID   Id,
> +  IN OUT UINTN                  *BufferSize,
> +  OUT VOID                      *Buffer OPTIONAL
> +  );
> +
> +/**
> +  Returns vendor-id and product-id of the device.
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI * EFI_USBFN_IO_GET_VENDOR_ID_PRODUCT_ID) (
> +  IN EFI_USBFN_IO_PROTOCOL      *This,
> +  OUT UINT16                    *Vid,
> +  OUT UINT16                    *Pid
> +  );
> +
> +/**
> +  Aborts transfer on the specified endpoint.
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI * EFI_USBFN_IO_ABORT_TRANSFER) (
> +  IN EFI_USBFN_IO_PROTOCOL        *This,
> +  IN UINT8                        EndpointIndex,
> +  IN EFI_USBFN_ENDPOINT_DIRECTION Direction
> +  );
> +
> +/**
> +  Returns the stall state on the specified endpoint.
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI * EFI_USBFN_IO_GET_ENDPOINT_STALL_STATE) (
> +  IN EFI_USBFN_IO_PROTOCOL        *This,
> +  IN UINT8                        EndpointIndex,
> +  IN EFI_USBFN_ENDPOINT_DIRECTION Direction,
> +  IN OUT BOOLEAN                  *State
> +  );
> +
> +/**
> +  Sets or clears the stall state on the specified endpoint.
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI * EFI_USBFN_IO_SET_ENDPOINT_STALL_STATE) (
> +  IN EFI_USBFN_IO_PROTOCOL        *This,
> +  IN UINT8                        EndpointIndex,
> +  IN EFI_USBFN_ENDPOINT_DIRECTION Direction,
> +  IN BOOLEAN                      State
> +  );
> +
> +
> +/**
> +  This function is called repeatedly to receive updates on USB bus states,
> +  receive, transmit status changes on endpoints and setup packet on endpoint 0.
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI * EFI_USBFN_IO_EVENTHANDLER) (
> +  IN EFI_USBFN_IO_PROTOCOL        *This,
> +  OUT EFI_USBFN_MESSAGE           *Message,
> +  IN OUT UINTN                    *PayloadSize,
> +  OUT EFI_USBFN_MESSAGE_PAYLOAD   *Payload
> +  );
> +
> +/**
> +  Primary function to handle transfer in either direction based on specified
> +  direction and on the specified endpoint.
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_USBFN_IO_TRANSFER) (
> +  IN EFI_USBFN_IO_PROTOCOL         *This,
> +  IN UINT8                         EndpointIndex,
> +  IN EFI_USBFN_ENDPOINT_DIRECTION  Direction,
> +  IN OUT UINTN                     *BufferSize,
> +  IN OUT VOID                      *Buffer
> +  );
> +
> +/**
> +  This function supplies power to the USB controller if needed,
> +  initialize hardware and internal data structures, and then return.
> +
> +  The port must not be activated by this function.
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI * EFI_USBFN_IO_START_CONTROLLER) (
> +    IN EFI_USBFN_IO_PROTOCOL    *This
> +    );
> +
> +/**
> +  This function disables the hardware device by resetting the run/stop bit and
> +  power off the USB controller if needed.
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI * EFI_USBFN_IO_STOP_CONTROLLER) (
> +    IN EFI_USBFN_IO_PROTOCOL    *This
> +    );
> +
> +/**
> +  This function sets the configuration policy for the specified non-control endpoint.
> +
> +  Refer to the description for calling restrictions.
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI * EFI_USBFN_IO_SET_ENDPOINT_POLICY) (
> +  IN EFI_USBFN_IO_PROTOCOL        *This,
> +  IN UINT8                        EndpointIndex,
> +  IN EFI_USBFN_ENDPOINT_DIRECTION Direction,
> +  IN EFI_USBFN_POLICY_TYPE        PolicyType,
> +  IN UINTN                        BufferSize,
> +  IN VOID                         *Buffer
> +  );
> +
> +/**
> +  This function retrieves the configuration policy for the specified non-control endpoint.
> +
> +  There are no associated calling restrictions for this function.
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI * EFI_USBFN_IO_GET_ENDPOINT_POLICY) (
> +  IN EFI_USBFN_IO_PROTOCOL        *This,
> +  IN UINT8                        EndpointIndex,
> +  IN EFI_USBFN_ENDPOINT_DIRECTION Direction,
> +  IN EFI_USBFN_POLICY_TYPE        PolicyType,
> +  IN OUT UINTN                    *BufferSize,
> +  IN OUT VOID                     *Buffer
> +  );
> +
> +
> +struct _EFI_USBFN_IO_PROTOCOL {
> +  UINT32                                      Revision;
> +  EFI_USBFN_IO_DETECT_PORT                    DetectPort;
> +  EFI_USBFN_IO_CONFIGURE_ENABLE_ENDPOINTS     ConfigureEnableEndpoints;
> +  EFI_USBFN_IO_GET_ENDPOINT_MAXPACKET_SIZE    GetEndpointMaxPacketSize;
> +  EFI_USBFN_IO_GET_DEVICE_INFO                GetDeviceInfo;
> +  EFI_USBFN_IO_GET_VENDOR_ID_PRODUCT_ID       GetVendorIdProductId;
> +  EFI_USBFN_IO_ABORT_TRANSFER                 AbortTransfer;
> +  EFI_USBFN_IO_GET_ENDPOINT_STALL_STATE       GetEndpointStallState;
> +  EFI_USBFN_IO_SET_ENDPOINT_STALL_STATE       SetEndpointStallState;
> +  EFI_USBFN_IO_EVENTHANDLER                   EventHandler;
> +  EFI_USBFN_IO_TRANSFER                       Transfer;
> +  EFI_USBFN_IO_GET_MAXTRANSFER_SIZE           GetMaxTransferSize;
> +  EFI_USBFN_IO_ALLOCATE_TRANSFER_BUFFER       AllocateTransferBuffer;
> +  EFI_USBFN_IO_FREE_TRANSFER_BUFFER           FreeTransferBuffer;
> +  //
> +  // Valid for version EFI_USBFN_IO_PROTOCOL_REVISION2 and above
> +  //
> +  EFI_USBFN_IO_START_CONTROLLER               StartController;
> +  EFI_USBFN_IO_STOP_CONTROLLER                StopController;
> +  EFI_USBFN_IO_SET_ENDPOINT_POLICY            SetEndpointPolicy;
> +  EFI_USBFN_IO_GET_ENDPOINT_POLICY            GetEndpointPolicy;
> +};
> +
> +
> +extern EFI_GUID gEfiUsbFnIoProtocolGuid;
> +#endif
> +
> diff --git a/Silicon/Synopsys/DesignWare/Include/Protocol/UsbDeviceModeProtocol.h b/Silicon/Synopsys/DesignWare/Include/Protocol/UsbDeviceModeProtocol.h
> new file mode 100644
> index 0000000000..c301fa00d3
> --- /dev/null
> +++ b/Silicon/Synopsys/DesignWare/Include/Protocol/UsbDeviceModeProtocol.h
> @@ -0,0 +1,104 @@
> +/** @file
> +  Copyright (c) 1999 - 2017, Intel Corporation. All rights reserved.<BR>
> +
> +  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.
> +
> +**/
> +
> +
> +#ifndef _USB_DEVICE_MODE_PROTOCOL_H_
> +#define _USB_DEVICE_MODE_PROTOCOL_H_
> +
> +#include <Library/UsbDeviceLib.h>
> +
> +///
> +/// UsbDeviceMode Protocol GUID.
> +///
> +#define EFI_USB_DEVICE_MODE_PROTOCOL_GUID \
> +  {0xC9923F7E, 0x1746, 0x4802, { 0x86, 0x2e, 0x1, 0x1c, 0x2c, 0x2d, 0x9d, 0x86 } }
> +
> +typedef struct _EFI_USB_DEVICE_MODE_PROTOCOL EFI_USB_DEVICE_MODE_PROTOCOL;
> +
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_USB_DEVICE_MODE_INIT_XDCI) (
> +  IN EFI_USB_DEVICE_MODE_PROTOCOL               *This
> +  );
> +
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_USB_DEVICE_MODE_CONNECT) (
> +  IN EFI_USB_DEVICE_MODE_PROTOCOL               *This
> +  );
> +
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_USB_DEVICE_MODE_DISCONNECT) (
> +  IN EFI_USB_DEVICE_MODE_PROTOCOL               *This
> +  );
> +
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_USB_DEVICE_EP_TX_DATA) (
> +  IN EFI_USB_DEVICE_MODE_PROTOCOL               *This,
> +  IN USB_DEVICE_IO_REQ                          *IoRequest
> +  );
> +
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_USB_DEVICE_EP_RX_DATA) (
> +  IN EFI_USB_DEVICE_MODE_PROTOCOL               *This,
> +  IN USB_DEVICE_IO_REQ                          *IoRequest
> +  );
> +
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_USB_DEVICE_MODE_BIND) (
> +  IN EFI_USB_DEVICE_MODE_PROTOCOL               *This,
> +  IN USB_DEVICE_OBJ                             *UsbdDevObj
> +  );
> +
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_USB_DEVICE_MODE_UNBIND) (
> +  IN EFI_USB_DEVICE_MODE_PROTOCOL               *This
> +  );
> +
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_USB_DEVICE_MODE_STOP) (
> +  IN EFI_USB_DEVICE_MODE_PROTOCOL               *This
> +  );
> +
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_USB_DEVICE_MODE_RUN) (
> +  IN EFI_USB_DEVICE_MODE_PROTOCOL               *This,
> +  IN UINT32                                     TimeoutMs
> +  );
> +
> +///
> +/// Usb Device Mode Protocol Structure.
> +///
> +struct _EFI_USB_DEVICE_MODE_PROTOCOL {
> +  EFI_USB_DEVICE_MODE_INIT_XDCI            InitXdci;
> +  EFI_USB_DEVICE_MODE_CONNECT              Connect;
> +  EFI_USB_DEVICE_MODE_DISCONNECT           DisConnect;
> +  EFI_USB_DEVICE_EP_TX_DATA                EpTxData;
> +  EFI_USB_DEVICE_EP_RX_DATA                EpRxData;
> +  EFI_USB_DEVICE_MODE_BIND                 Bind;
> +  EFI_USB_DEVICE_MODE_UNBIND               UnBind;
> +  EFI_USB_DEVICE_MODE_RUN                  Run;
> +  EFI_USB_DEVICE_MODE_STOP                 Stop;
> +};
> +
> +extern EFI_GUID gEfiUsbDeviceModeProtocolGuid;
> +
> +#endif
> +
> -- 
> 2.27.0.windows.1
> 

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [edk2-platforms PATCH 1/5] Silicon/Synopsys/DesignWare: Import DesignWare USB3 peripheral driver
  2020-07-20 17:43 ` Leif Lindholm
@ 2020-07-21  3:51   ` Vin Xue
  2020-07-30 12:18     ` Leif Lindholm
  2020-07-21  8:17   ` Meenakshi Aggarwal (OSS)
  1 sibling, 1 reply; 6+ messages in thread
From: Vin Xue @ 2020-07-21  3:51 UTC (permalink / raw)
  To: Leif Lindholm; +Cc: devel@edk2.groups.io, Ard Biesheuvel, Meenakshi Aggarwal

[-- Attachment #1: Type: text/plain, Size: 426632 bytes --]

Hi Leif,

The origin code is from edk2-platforms
/devel-IntelAtomProcessorE3900 branch.
https://github.com/tianocore/edk2-platforms/
tree/devel-IntelAtomProcessorE3900/Platform/
BroxtonPlatformPkg/Common/Features/UsbDeviceDxe

In Patch 1/5 is the origin source code with BSD2 license, and
I updated license to BSD+Patent license in Patch 2/5.
Please check it.

>From my review, the driver code flow is similar to Linux kernel
DWC3 driver. Maybe it's feasible to ARM platform if do some changes.

Best regards,
Vin

________________________________
From: Leif Lindholm <leif@nuviainc.com>
Sent: Tuesday, July 21, 2020 1:43 AM
To: Vin Xue <vinxue@outlook.com>
Cc: devel@edk2.groups.io <devel@edk2.groups.io>; Ard Biesheuvel <ard.biesheuvel@arm.com>; Meenakshi Aggarwal <meenakshi.aggarwal@oss.nxp.com>
Subject: Re: [edk2-platforms PATCH 1/5] Silicon/Synopsys/DesignWare: Import DesignWare USB3 peripheral driver

Hi Vin, +Meenakshi

Can you clarify the exact origin of this source code please?
We can only accept bsd+patent code contributions, and these days we
use only SPDX tags rather than full license statements at top of
files.

Meenakshi - I would certainly prefer to have a single (and
Arm-functional) driver for DWC3 rather than init-only drivers per
platform. Can you have a look at this code plese and see if it looks
feasible to integrate in the NXP platforms?

Regards,

Leif

On Fri, Jul 17, 2020 at 18:01:59 +0800, Vin Xue wrote:
> Incorporate the driver for the DesignWare USB3 DRD controller device
> mode (peripheral) that is defined in
> edk2-platforms/devel-IntelAtomProcessorE3900 branch.
>
> The driver is supported by Intel Atom series (Merrifield/BayTrail/
> CherryTrail/Broxton/ApoloLake/GeminiLake etc.) and Core series
> (6th Generation and newer).
>
> The driver verified on AAEON UP Squared developer board (Intel
> ApoloLake platform).
>
> The driver supports Synopsys DesignWare DWC_usb3 and DWC_usb31 IP.
>
> It is better if the driver can be ported to ARM silicon.
>
> Cc: Ard Biesheuvel <ard.biesheuvel@arm.com>
> Cc: Leif Lindholm <leif@nuviainc.com>
> Signed-off-by: Vin Xue <vinxue@outlook.com>
> ---
>  .../Drivers/UsbDeviceDxe/ComponentName.c      |  305 ++
>  .../Drivers/UsbDeviceDxe/UsbDeviceDxe.c       |  395 ++
>  .../Drivers/UsbDeviceDxe/UsbDeviceDxe.h       |  159 +
>  .../Drivers/UsbDeviceDxe/UsbDeviceDxe.inf     |   74 +
>  .../Drivers/UsbDeviceDxe/UsbDeviceMode.c      | 1489 ++++++
>  .../Drivers/UsbDeviceDxe/UsbDeviceMode.h      |   39 +
>  .../Drivers/UsbDeviceDxe/UsbFuncIo.c          | 2221 +++++++++
>  .../Drivers/UsbDeviceDxe/UsbFuncIo.h          |  234 +
>  .../Drivers/UsbDeviceDxe/UsbIoNode.c          |  177 +
>  .../Drivers/UsbDeviceDxe/UsbIoNode.h          |   90 +
>  .../Drivers/UsbDeviceDxe/XdciCommon.h         |  156 +
>  .../DesignWare/Drivers/UsbDeviceDxe/XdciDWC.c | 4030 +++++++++++++++++
>  .../DesignWare/Drivers/UsbDeviceDxe/XdciDWC.h |  741 +++
>  .../Drivers/UsbDeviceDxe/XdciDevice.c         |  695 +++
>  .../Drivers/UsbDeviceDxe/XdciDevice.h         |  184 +
>  .../Drivers/UsbDeviceDxe/XdciInterface.h      |  241 +
>  .../Drivers/UsbDeviceDxe/XdciTable.c          |   55 +
>  .../Drivers/UsbDeviceDxe/XdciUtility.c        |  148 +
>  .../Drivers/UsbDeviceDxe/XdciUtility.h        |   62 +
>  .../DesignWare/Include/Library/UsbDeviceLib.h |  323 ++
>  .../DesignWare/Include/Protocol/EfiUsbFnIo.h  |  430 ++
>  .../Include/Protocol/UsbDeviceModeProtocol.h  |  104 +
>  22 files changed, 12352 insertions(+)
>  create mode 100644 Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/ComponentName.c
>  create mode 100644 Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbDeviceDxe.c
>  create mode 100644 Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbDeviceDxe.h
>  create mode 100644 Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbDeviceDxe.inf
>  create mode 100644 Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbDeviceMode.c
>  create mode 100644 Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbDeviceMode.h
>  create mode 100644 Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbFuncIo.c
>  create mode 100644 Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbFuncIo.h
>  create mode 100644 Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbIoNode.c
>  create mode 100644 Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbIoNode.h
>  create mode 100644 Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciCommon.h
>  create mode 100644 Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciDWC.c
>  create mode 100644 Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciDWC.h
>  create mode 100644 Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciDevice.c
>  create mode 100644 Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciDevice.h
>  create mode 100644 Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciInterface.h
>  create mode 100644 Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciTable.c
>  create mode 100644 Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciUtility.c
>  create mode 100644 Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciUtility.h
>  create mode 100644 Silicon/Synopsys/DesignWare/Include/Library/UsbDeviceLib.h
>  create mode 100644 Silicon/Synopsys/DesignWare/Include/Protocol/EfiUsbFnIo.h
>  create mode 100644 Silicon/Synopsys/DesignWare/Include/Protocol/UsbDeviceModeProtocol.h
>
> diff --git a/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/ComponentName.c b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/ComponentName.c
> new file mode 100644
> index 0000000000..acb4b6a23d
> --- /dev/null
> +++ b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/ComponentName.c
> @@ -0,0 +1,305 @@
> +/** @file
> +  Copyright (c) 2004 - 2017, Intel Corporation. All rights reserved.<BR>
> +
> +  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.
> +
> +**/
> +
> +#include <Uefi.h>
> +#include <Library/UefiLib.h>
> +
> +
> +/**
> +  Retrieves a Unicode string that is the user readable name of the driver.
> +
> +  This function retrieves the user readable name of a driver in the form of a
> +  Unicode string. If the driver specified by This has a user readable name in
> +  the language specified by Language, then a pointer to the driver name is
> +  returned in DriverName, and EFI_SUCCESS is returned. If the driver specified
> +  by This does not support the language specified by Language,
> +  then EFI_UNSUPPORTED is returned.
> +
> +  @param  This[in]              A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
> +                                EFI_COMPONENT_NAME_PROTOCOL instance.
> +
> +  @param  Language[in]          A pointer to a Null-terminated ASCII string
> +                                array indicating the language. This is the
> +                                language of the driver name that the caller is
> +                                requesting, and it must match one of the
> +                                languages specified in SupportedLanguages. The
> +                                number of languages supported by a driver is up
> +                                to the driver writer. Language is specified
> +                                in RFC 4646 or ISO 639-2 language code format.
> +
> +  @param  DriverName[out]       A pointer to the Unicode string to return.
> +                                This Unicode string is the name of the
> +                                driver specified by This in the language
> +                                specified by Language.
> +
> +  @retval EFI_SUCCESS           The Unicode string for the Driver specified by
> +                                This and the language specified by Language was
> +                                returned in DriverName.
> +
> +  @retval EFI_INVALID_PARAMETER Language is NULL.
> +
> +  @retval EFI_INVALID_PARAMETER DriverName is NULL.
> +
> +  @retval EFI_UNSUPPORTED       The driver specified by This does not support
> +                                the language specified by Language.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +UsbDeviceDxeGetDriverName (
> +  IN  EFI_COMPONENT_NAME_PROTOCOL  *This,
> +  IN  CHAR8                        *Language,
> +  OUT CHAR16                       **DriverName
> +  );
> +
> +
> +/**
> +  Retrieves a Unicode string that is the user readable name of the controller
> +  that is being managed by a driver.
> +
> +  This function retrieves the user readable name of the controller specified by
> +  ControllerHandle and ChildHandle in the form of a Unicode string. If the
> +  driver specified by This has a user readable name in the language specified by
> +  Language, then a pointer to the controller name is returned in ControllerName,
> +  and EFI_SUCCESS is returned.  If the driver specified by This is not currently
> +  managing the controller specified by ControllerHandle and ChildHandle,
> +  then EFI_UNSUPPORTED is returned.  If the driver specified by This does not
> +  support the language specified by Language, then EFI_UNSUPPORTED is returned.
> +
> +  @param  This[in]              A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
> +                                EFI_COMPONENT_NAME_PROTOCOL instance.
> +
> +  @param  ControllerHandle[in]  The handle of a controller that the driver
> +                                specified by This is managing.  This handle
> +                                specifies the controller whose name is to be
> +                                returned.
> +
> +  @param  ChildHandle[in]       The handle of the child controller to retrieve
> +                                the name of.  This is an optional parameter that
> +                                may be NULL.  It will be NULL for device
> +                                drivers.  It will also be NULL for a bus drivers
> +                                that wish to retrieve the name of the bus
> +                                controller.  It will not be NULL for a bus
> +                                driver that wishes to retrieve the name of a
> +                                child controller.
> +
> +  @param  Language[in]          A pointer to a Null-terminated ASCII string
> +                                array indicating the language.  This is the
> +                                language of the driver name that the caller is
> +                                requesting, and it must match one of the
> +                                languages specified in SupportedLanguages. The
> +                                number of languages supported by a driver is up
> +                                to the driver writer. Language is specified in
> +                                RFC 4646 or ISO 639-2 language code format.
> +
> +  @param  ControllerName[out]   A pointer to the Unicode string to return.
> +                                This Unicode string is the name of the
> +                                controller specified by ControllerHandle and
> +                                ChildHandle in the language specified by
> +                                Language from the point of view of the driver
> +                                specified by This.
> +
> +  @retval EFI_SUCCESS           The Unicode string for the user readable name in
> +                                the language specified by Language for the
> +                                driver specified by This was returned in
> +                                DriverName.
> +
> +  @retval EFI_INVALID_PARAMETER ControllerHandle is NULL.
> +
> +  @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid
> +                                EFI_HANDLE.
> +
> +  @retval EFI_INVALID_PARAMETER Language is NULL.
> +
> +  @retval EFI_INVALID_PARAMETER ControllerName is NULL.
> +
> +  @retval EFI_UNSUPPORTED       The driver specified by This is not currently
> +                                managing the controller specified by
> +                                ControllerHandle and ChildHandle.
> +
> +  @retval EFI_UNSUPPORTED       The driver specified by This does not support
> +                                the language specified by Language.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +UsbDeviceDxeGetControllerName (
> +  IN  EFI_COMPONENT_NAME_PROTOCOL                     *This,
> +  IN  EFI_HANDLE                                      ControllerHandle,
> +  IN  EFI_HANDLE                                      ChildHandle        OPTIONAL,
> +  IN  CHAR8                                           *Language,
> +  OUT CHAR16                                          **ControllerName
> +  );
> +
> +
> +//
> +// EFI Component Name Protocol
> +//
> +GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME_PROTOCOL  mUsbDeviceDxeComponentName = {
> +  UsbDeviceDxeGetDriverName,
> +  UsbDeviceDxeGetControllerName,
> +  "eng"
> +};
> +
> +//
> +// EFI Component Name 2 Protocol
> +//
> +GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME2_PROTOCOL mUsbDeviceDxeComponentName2 = {
> +  (EFI_COMPONENT_NAME2_GET_DRIVER_NAME) UsbDeviceDxeGetDriverName,
> +  (EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME) UsbDeviceDxeGetControllerName,
> +  "en"
> +};
> +
> +
> +GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mUsbDeviceDxeDriverNameTable[] = {
> +  { "eng;en", L"Usb Device Driver" },
> +  { NULL , NULL }
> +};
> +
> +/**
> +  Retrieves a Unicode string that is the user readable name of the driver.
> +
> +  This function retrieves the user readable name of a driver in the form of a
> +  Unicode string. If the driver specified by This has a user readable name in
> +  the language specified by Language, then a pointer to the driver name is
> +  returned in DriverName, and EFI_SUCCESS is returned. If the driver specified
> +  by This does not support the language specified by Language,
> +  then EFI_UNSUPPORTED is returned.
> +
> +  @param  This[in]              A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
> +                                EFI_COMPONENT_NAME_PROTOCOL instance.
> +
> +  @param  Language[in]          A pointer to a Null-terminated ASCII string
> +                                array indicating the language. This is the
> +                                language of the driver name that the caller is
> +                                requesting, and it must match one of the
> +                                languages specified in SupportedLanguages. The
> +                                number of languages supported by a driver is up
> +                                to the driver writer. Language is specified
> +                                in RFC 4646 or ISO 639-2 language code format.
> +
> +  @param  DriverName[out]       A pointer to the Unicode string to return.
> +                                This Unicode string is the name of the
> +                                driver specified by This in the language
> +                                specified by Language.
> +
> +  @retval EFI_SUCCESS           The Unicode string for the Driver specified by
> +                                This and the language specified by Language was
> +                                returned in DriverName.
> +
> +  @retval EFI_INVALID_PARAMETER Language is NULL.
> +
> +  @retval EFI_INVALID_PARAMETER DriverName is NULL.
> +
> +  @retval EFI_UNSUPPORTED       The driver specified by This does not support
> +                                the language specified by Language.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +UsbDeviceDxeGetDriverName (
> +  IN  EFI_COMPONENT_NAME_PROTOCOL  *This,
> +  IN  CHAR8                        *Language,
> +  OUT CHAR16                       **DriverName
> +  )
> +{
> +  return LookupUnicodeString2 (
> +           Language,
> +           This->SupportedLanguages,
> +           mUsbDeviceDxeDriverNameTable,
> +           DriverName,
> +           (BOOLEAN)(This == &mUsbDeviceDxeComponentName)
> +           );
> +}
> +
> +/**
> +  Retrieves a Unicode string that is the user readable name of the controller
> +  that is being managed by a driver.
> +
> +  This function retrieves the user readable name of the controller specified by
> +  ControllerHandle and ChildHandle in the form of a Unicode string. If the
> +  driver specified by This has a user readable name in the language specified by
> +  Language, then a pointer to the controller name is returned in ControllerName,
> +  and EFI_SUCCESS is returned.  If the driver specified by This is not currently
> +  managing the controller specified by ControllerHandle and ChildHandle,
> +  then EFI_UNSUPPORTED is returned.  If the driver specified by This does not
> +  support the language specified by Language, then EFI_UNSUPPORTED is returned.
> +
> +  @param  This[in]              A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
> +                                EFI_COMPONENT_NAME_PROTOCOL instance.
> +
> +  @param  ControllerHandle[in]  The handle of a controller that the driver
> +                                specified by This is managing.  This handle
> +                                specifies the controller whose name is to be
> +                                returned.
> +
> +  @param  ChildHandle[in]       The handle of the child controller to retrieve
> +                                the name of.  This is an optional parameter that
> +                                may be NULL.  It will be NULL for device
> +                                drivers.  It will also be NULL for a bus drivers
> +                                that wish to retrieve the name of the bus
> +                                controller.  It will not be NULL for a bus
> +                                driver that wishes to retrieve the name of a
> +                                child controller.
> +
> +  @param  Language[in]          A pointer to a Null-terminated ASCII string
> +                                array indicating the language.  This is the
> +                                language of the driver name that the caller is
> +                                requesting, and it must match one of the
> +                                languages specified in SupportedLanguages. The
> +                                number of languages supported by a driver is up
> +                                to the driver writer. Language is specified in
> +                                RFC 4646 or ISO 639-2 language code format.
> +
> +  @param  ControllerName[out]   A pointer to the Unicode string to return.
> +                                This Unicode string is the name of the
> +                                controller specified by ControllerHandle and
> +                                ChildHandle in the language specified by
> +                                Language from the point of view of the driver
> +                                specified by This.
> +
> +  @retval EFI_SUCCESS           The Unicode string for the user readable name in
> +                                the language specified by Language for the
> +                                driver specified by This was returned in
> +                                DriverName.
> +
> +  @retval EFI_INVALID_PARAMETER ControllerHandle is not a valid EFI_HANDLE.
> +
> +  @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid
> +                                EFI_HANDLE.
> +
> +  @retval EFI_INVALID_PARAMETER Language is NULL.
> +
> +  @retval EFI_INVALID_PARAMETER ControllerName is NULL.
> +
> +  @retval EFI_UNSUPPORTED       The driver specified by This is not currently
> +                                managing the controller specified by
> +                                ControllerHandle and ChildHandle.
> +
> +  @retval EFI_UNSUPPORTED       The driver specified by This does not support
> +                                the language specified by Language.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +UsbDeviceDxeGetControllerName (
> +  IN  EFI_COMPONENT_NAME_PROTOCOL                     *This,
> +  IN  EFI_HANDLE                                      ControllerHandle,
> +  IN  EFI_HANDLE                                      ChildHandle        OPTIONAL,
> +  IN  CHAR8                                           *Language,
> +  OUT CHAR16                                          **ControllerName
> +  )
> +{
> +  return EFI_UNSUPPORTED;
> +}
> +
> diff --git a/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbDeviceDxe.c b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbDeviceDxe.c
> new file mode 100644
> index 0000000000..2732cc2e31
> --- /dev/null
> +++ b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbDeviceDxe.c
> @@ -0,0 +1,395 @@
> +/** @file
> +  Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR>
> +
> +  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.
> +
> +**/
> +
> +#include "UsbDeviceDxe.h"
> +#include <Guid/EventGroup.h>
> +
> +EFI_DRIVER_BINDING_PROTOCOL mUsbDeviceDxeDriverBinding = {
> +  UsbDeviceDxeDriverSupported,
> +  UsbDeviceDxeDriverStart,
> +  UsbDeviceDxeDriverStop,
> +  0x1,
> +  NULL,
> +  NULL
> +};
> +
> +
> +
> +VOID
> +EFIAPI
> +PlatformSpecificInit (
> +  VOID
> +  )
> +{
> +  UINTN                 XhciPciMmBase;
> +  EFI_PHYSICAL_ADDRESS  XhciMemBaseAddress;
> +
> +  XhciPciMmBase   = MmPciAddress (
> +                      0,
> +                      0,
> +                      PCI_DEVICE_NUMBER_XHCI,
> +                      PCI_FUNCTION_NUMBER_XHCI,
> +                      0
> +                      );
> +
> +
> +  XhciMemBaseAddress = MmioRead32 ((UINTN) (XhciPciMmBase + R_XHCI_MEM_BASE)) & B_XHCI_MEM_BASE_BA;
> +  DEBUG ((DEBUG_INFO, "XhciPciMmBase=%x, XhciMemBaseAddress=%x\n", XhciPciMmBase, XhciMemBaseAddress));
> +
> +  MmioWrite32 ((UINTN)(XhciMemBaseAddress + R_XHCI_MEM_DUAL_ROLE_CFG0), 0x1310800);
> +
> +  PmicUSBSwitchControl (TRUE);//conduction USB switch.
> +  return;
> +}
> +
> +
> +VOID
> +EFIAPI
> +UsbDeviceDxeExitBootService (
> +  EFI_EVENT  Event,
> +  VOID       *Context
> +  )
> +{
> +  USB_XDCI_DEV_CONTEXT  *UsbXdciDevContext;
> +
> +  UsbXdciDevContext = (USB_XDCI_DEV_CONTEXT *) Context;
> +  DEBUG ((EFI_D_INFO, "UsbDeviceDxeExitBootService enter\n"));
> +
> +  if (UsbXdciDevContext->XdciPollTimer != NULL) {
> +    gBS->SetTimer (UsbXdciDevContext->XdciPollTimer, TimerCancel, 0);
> +    gBS->CloseEvent (UsbXdciDevContext->XdciPollTimer);
> +    UsbXdciDevContext->XdciPollTimer = NULL;
> +    }
> +
> +  return;
> +}
> +
> +/**
> +  The USB bus driver entry pointer.
> +
> +  @param ImageHandle       The driver image handle.
> +  @param SystemTable       The system table.
> +
> +  @return EFI_SUCCESS      The component name protocol is installed.
> +  @return Others           Failed to init the usb driver.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +UsbDeviceDxeEntryPoint (
> +  IN EFI_HANDLE           ImageHandle,
> +  IN EFI_SYSTEM_TABLE     *SystemTable
> +  )
> +{
> +  return EfiLibInstallDriverBindingComponentName2 (
> +           ImageHandle,
> +           SystemTable,
> +           &mUsbDeviceDxeDriverBinding,
> +           ImageHandle,
> +           &mUsbDeviceDxeComponentName,
> +           &mUsbDeviceDxeComponentName2
> +           );
> +}
> +
> +/**
> +  Check whether USB bus driver support this device.
> +
> +  @param  This                   The USB bus driver binding protocol.
> +  @param  Controller             The controller handle to check.
> +  @param  RemainingDevicePath    The remaining device path.
> +
> +  @retval EFI_SUCCESS            The bus supports this controller.
> +  @retval EFI_UNSUPPORTED        This device isn't supported.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +UsbDeviceDxeDriverSupported (
> +  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
> +  IN EFI_HANDLE                   Controller,
> +  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath
> +  )
> +{
> +  EFI_STATUS                Status;
> +  EFI_PCI_IO_PROTOCOL       *PciIo;
> +  USB_CLASSC                UsbClassCReg;
> +
> +
> +  Status = gBS->OpenProtocol (
> +                  Controller,
> +                  &gEfiPciIoProtocolGuid,
> +                  (VOID **) &PciIo,
> +                  This->DriverBindingHandle,
> +                  Controller,
> +                  EFI_OPEN_PROTOCOL_BY_DRIVER
> +                  );
> +
> +  if (EFI_ERROR (Status)) {
> +    return EFI_UNSUPPORTED;
> +  }
> +
> +  Status = PciIo->Pci.Read (
> +                        PciIo,
> +                        EfiPciIoWidthUint8,
> +                        PCI_CLASSCODE_OFFSET,
> +                        sizeof (USB_CLASSC) / sizeof (UINT8),
> +                        &UsbClassCReg
> +                        );
> +
> +  if (EFI_ERROR (Status)) {
> +    Status = EFI_UNSUPPORTED;
> +    goto ON_EXIT;
> +  }
> +
> +  //
> +  // Test whether the controller belongs to USB device type
> +  //
> +  // 0x0C03FE / 0x0C0380
> +  //
> +  if ((UsbClassCReg.BaseCode != PCI_CLASS_SERIAL) ||
> +      (UsbClassCReg.SubClassCode != PCI_CLASS_SERIAL_USB) ||
> +      ((UsbClassCReg.ProgInterface != PCI_IF_USBDEV) && (UsbClassCReg.ProgInterface != 0x80))) {
> +    Status = EFI_UNSUPPORTED;
> +  }
> +
> +ON_EXIT:
> +  gBS->CloseProtocol (
> +         Controller,
> +         &gEfiPciIoProtocolGuid,
> +         This->DriverBindingHandle,
> +         Controller
> +         );
> +
> +  return Status;
> +}
> +
> +
> +/**
> +  Start to process the controller.
> +
> +  @param  This                   The USB bus driver binding instance.
> +  @param  Controller             The controller to check.
> +  @param  RemainingDevicePath    The remaining device patch.
> +
> +  @retval EFI_SUCCESS            The controller is controlled by the usb bus.
> +  @retval EFI_ALREADY_STARTED    The controller is already controlled by the usb
> +                                 bus.
> +  @retval EFI_OUT_OF_RESOURCES   Failed to allocate resources.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +UsbDeviceDxeDriverStart (
> +  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
> +  IN EFI_HANDLE                   Controller,
> +  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath
> +  )
> +{
> +  EFI_STATUS            Status;
> +  USB_XDCI_DEV_CONTEXT  *UsbXdciDevContext;
> +  EFI_PCI_IO_PROTOCOL   *PciIo;
> +  EFI_EVENT             ExitBootServicesEvent;
> +
> +  DEBUG ((USB_FUIO_DEBUG_LOAD, "UsbFunIoEntryPoint - Entry\n"));
> +
> +  UsbXdciDevContext = NULL;
> +
> +  //
> +  // Provide protocol interface
> +  //
> +  //
> +  // Get the PCI I/O Protocol on PciHandle
> +  //
> +  Status = gBS->OpenProtocol (
> +                  Controller,
> +                  &gEfiPciIoProtocolGuid,
> +                  (VOID **) &PciIo,
> +                  This->DriverBindingHandle,
> +                  Controller,
> +                  EFI_OPEN_PROTOCOL_BY_DRIVER
> +                  );
> +
> +  if (EFI_ERROR (Status)) {
> +    goto ErrorExit;
> +  }
> +
> +  UsbXdciDevContext = AllocateZeroPool (sizeof (USB_XDCI_DEV_CONTEXT));
> +  if (UsbXdciDevContext == NULL) {
> +    Status = EFI_OUT_OF_RESOURCES;
> +    goto ErrorExit;
> +  }
> +
> +  //
> +  // Initialize the driver context
> +  //
> +  UsbXdciDevContext->StartUpController = FALSE;
> +  UsbXdciDevContext->XdciHandle = Controller;
> +  UsbXdciDevContext->FirstNodePtr = NULL;
> +  UsbXdciDevContext->Signature = EFI_USB_DEV_SIGNATURE;
> +
> +  PciIo->Pci.Read (
> +               PciIo,
> +               EfiPciIoWidthUint32,
> +               R_OTG_BAR0,
> +               1,
> +               &UsbXdciDevContext->XdciMmioBarAddr
> +               );
> +
> +  UsbXdciDevContext->XdciMmioBarAddr &= B_OTG_BAR0_BA;
> +  DEBUG ((USB_FUIO_DEBUG_INFO, "USB DEV mode IO addr 0x%08x\n", UsbXdciDevContext->XdciMmioBarAddr));
> +
> +  CopyMem (
> +    &(UsbXdciDevContext->UsbFunIoProtocol),
> +    &mUsbFunIoProtocol,
> +    sizeof (EFI_USBFN_IO_PROTOCOL)
> +    );
> +
> +  CopyMem (
> +    &(UsbXdciDevContext->UsbDevModeProtocol),
> +    &mUsbDeviceModeProtocol,
> +    sizeof (EFI_USB_DEVICE_MODE_PROTOCOL)
> +    );
> +
> +  Status = gBS->CreateEventEx (
> +                  EVT_NOTIFY_SIGNAL,
> +                  TPL_NOTIFY,
> +                  UsbDeviceDxeExitBootService,
> +                  UsbXdciDevContext,
> +                  &gEfiEventExitBootServicesGuid,
> +                  &ExitBootServicesEvent
> +                  );
> +  if (EFI_ERROR (Status)) {
> +    goto ErrorExit;
> +  }
> +
> +  Status = gBS->InstallMultipleProtocolInterfaces (
> +                  &UsbXdciDevContext->XdciHandle,
> +                  &gEfiUsbFnIoProtocolGuid,
> +                  &UsbXdciDevContext->UsbFunIoProtocol,
> +                  &gEfiUsbDeviceModeProtocolGuid,
> +                  &UsbXdciDevContext->UsbDevModeProtocol,
> +                  NULL
> +                  );
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((USB_FUIO_DEBUG_ERROR, "ERROR - Failed to install upper protocol, Status: %r\n", Status));
> +    goto ErrorExit;
> +  }
> +
> +  DEBUG ((USB_FUIO_DEBUG_LOAD, "Done - install upper protocol complete\n"));
> +  DEBUG ((USB_FUIO_DEBUG_LOAD, "UsbFunIoEntryPoint - Exit\n"));
> +  return Status;
> +
> +ErrorExit:
> +  gBS->CloseProtocol (
> +         Controller,
> +         &gEfiPciIoProtocolGuid,
> +         This->DriverBindingHandle,
> +         Controller
> +         );
> +
> +  if (UsbXdciDevContext != NULL) {
> +    if (UsbXdciDevContext->XdciPollTimer != NULL) {
> +      gBS->CloseEvent (UsbXdciDevContext->XdciPollTimer);
> +      UsbXdciDevContext->XdciPollTimer = NULL;
> +    }
> +    FreePool (UsbXdciDevContext);
> +  }
> +
> +  DEBUG ((USB_FUIO_DEBUG_ERROR, "ERROR - UsbFunIoEntryPoint - Exit\n"));
> +  return Status;
> +}
> +
> +/**
> +  Stop handle the controller by this USB bus driver.
> +
> +  @param  This                   The USB bus driver binding protocol.
> +  @param  Controller             The controller to release.
> +  @param  NumberOfChildren       The child of USB bus that opened controller
> +                                 BY_CHILD.
> +  @param  ChildHandleBuffer      The array of child handle.
> +
> +  @retval EFI_SUCCESS            The controller or children are stopped.
> +  @retval EFI_DEVICE_ERROR       Failed to stop the driver.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +UsbDeviceDxeDriverStop (
> +  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
> +  IN EFI_HANDLE                   Controller,
> +  IN UINTN                        NumberOfChildren,
> +  IN EFI_HANDLE                   *ChildHandleBuffer
> +  )
> +{
> +  EFI_USBFN_IO_PROTOCOL           *UsbFunIoProtocol;
> +  EFI_STATUS                      Status;
> +  USB_XDCI_DEV_CONTEXT            *UsbXdciDevContext;
> +
> +
> +  //
> +  // Locate USB_BUS for the current host controller
> +  //
> +  Status = gBS->OpenProtocol (
> +                  Controller,
> +                  &gEfiUsbFnIoProtocolGuid,
> +                  (VOID **)&UsbFunIoProtocol,
> +                  This->DriverBindingHandle,
> +                  Controller,
> +                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
> +                  );
> +
> +
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  UsbXdciDevContext = USBFUIO_CONTEXT_FROM_PROTOCOL (UsbFunIoProtocol);
> +
> +  //
> +  // free pool
> +  //
> +  while (UsbXdciDevContext->FirstNodePtr != NULL) {
> +    RemoveNode (UsbFunIoProtocol, UsbXdciDevContext->FirstNodePtr);
> +  }
> +
> +  Status = gBS->UninstallMultipleProtocolInterfaces (
> +                  UsbXdciDevContext->XdciHandle,
> +                  &gEfiUsbFnIoProtocolGuid,
> +                  &UsbXdciDevContext->UsbFunIoProtocol,
> +                  &gEfiUsbDeviceModeProtocolGuid,
> +                  &UsbXdciDevContext->UsbDevModeProtocol,
> +                  NULL
> +                  );
> +
> +  if (UsbXdciDevContext->StartUpController == TRUE) {
> +    Status = StopController (UsbFunIoProtocol);
> +    DEBUG ((USB_FUIO_DEBUG_INFO, "USB DEV mode STOP UsbFnDeInitDevice %r\n", Status));
> +  }
> +
> +  if (UsbXdciDevContext->XdciPollTimer != NULL) {
> +    gBS->SetTimer (UsbXdciDevContext->XdciPollTimer, TimerCancel, 0);
> +    gBS->CloseEvent (UsbXdciDevContext->XdciPollTimer);
> +    UsbXdciDevContext->XdciPollTimer = NULL;
> +  }
> +
> +  gBS->CloseProtocol (
> +         Controller,
> +         &gEfiPciIoProtocolGuid,
> +         This->DriverBindingHandle,
> +         Controller
> +         );
> +
> +  FreePool (UsbXdciDevContext);
> +  return EFI_SUCCESS;
> +}
> +
> diff --git a/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbDeviceDxe.h b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbDeviceDxe.h
> new file mode 100644
> index 0000000000..36620f9b12
> --- /dev/null
> +++ b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbDeviceDxe.h
> @@ -0,0 +1,159 @@
> +/** @file
> +  Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR>
> +
> +  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.
> +
> +**/
> +
> +#ifndef __USB_DEVICE_DXE_H__
> +#define __USB_DEVICE_DXE_H__
> +
> +#include <Uefi.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/DevicePathLib.h>
> +#include <Library/DriverLib.h>
> +#include <Library/PcdLib.h>
> +#include <Library/IoLib.h>
> +#include <Protocol/EfiUsbFnIo.h>
> +#include <Protocol/UsbDeviceModeProtocol.h>
> +#include <PlatformBaseAddresses.h>
> +#include <ScAccess.h>
> +#include "UsbFuncIo.h"
> +#include "UsbDeviceMode.h"
> +
> +
> +#define PCI_IF_USBDEV                      0xFE
> +
> +#define EFI_USB_DEV_SIGNATURE              0x55534244 //"USBD"
> +#define USBFUIO_CONTEXT_FROM_PROTOCOL(a)   CR (a, USB_XDCI_DEV_CONTEXT, UsbFunIoProtocol, EFI_USB_DEV_SIGNATURE)
> +#define USBUSBD_CONTEXT_FROM_PROTOCOL(a)   CR (a, USB_XDCI_DEV_CONTEXT, UsbDevModeProtocol, EFI_USB_DEV_SIGNATURE)
> +
> +
> +typedef struct _USB_FUIO_EVENT_NODE   USB_FUIO_EVENT_NODE;
> +
> +#pragma pack(1)
> +struct _USB_FUIO_EVENT_NODE{
> +  EFI_USBFN_MESSAGE            Message;
> +  UINTN                        PayloadSize;
> +  EFI_USBFN_MESSAGE_PAYLOAD    Payload;
> +  USB_FUIO_EVENT_NODE          *Nextptr;
> +};
> +
> +typedef struct {
> +  UINTN                         Signature;
> +  UINTN                         XdciMmioBarAddr;
> +  EFI_HANDLE                    XdciHandle;
> +  //
> +  // Timer to handle EndPoint event periodically.
> +  //
> +  EFI_EVENT                     XdciPollTimer;
> +  EFI_USB_DEVICE_MODE_PROTOCOL  UsbDevModeProtocol;
> +  EFI_USBFN_IO_PROTOCOL         UsbFunIoProtocol;
> +
> +  //
> +  // Structure members used by UsbFunIoProtocol.
> +  //
> +  USB_MEM_NODE                  *FirstNodePtr;
> +  EFI_USB_DEVICE_INFO           *DevInfoPtr;
> +  EFI_USB_CONFIG_INFO           IndexPtrConfig;
> +  EFI_USB_INTERFACE_INFO        IndexPtrInteface;
> +  USB_DEVICE_ENDPOINT_INFO      IndexPtrInEp;
> +  USB_DEVICE_ENDPOINT_INFO      IndexPtrOutEp;
> +  XDCI_CORE_HANDLE              *XdciDrvIfHandle;
> +  USB_DEV_CORE                  *DrvCore;
> +  UINT16                        VendorId;
> +  UINT16                        DeviceId;
> +  USBD_EP_XFER_REC              EndPointXferRec[DWC_XDCI_MAX_ENDPOINTS];
> +  BOOLEAN                       StartUpController;
> +  BOOLEAN                       DevReConnect;
> +  BOOLEAN                       DevResetFlag;
> +  EFI_EVENT                     TimerEvent;
> +  USB_FUIO_EVENT_NODE           *EventNodePtr;
> +  //
> +  // Following structure members are used by UsbDevModeProtocol.
> +  //
> +
> +} USB_XDCI_DEV_CONTEXT;
> +#pragma pack()
> +
> +
> +
> +/**
> +  Check whether USB bus driver support this device.
> +
> +  @param  This                   The USB bus driver binding protocol.
> +  @param  Controller             The controller handle to check.
> +  @param  RemainingDevicePath    The remaining device path.
> +
> +  @retval EFI_SUCCESS            The bus supports this controller.
> +  @retval EFI_UNSUPPORTED        This device isn't supported.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +UsbDeviceDxeDriverSupported (
> +  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
> +  IN EFI_HANDLE                   Controller,
> +  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath
> +  );
> +
> +/**
> +  Start to process the controller.
> +
> +  @param  This                   The USB bus driver binding instance.
> +  @param  Controller             The controller to check.
> +  @param  RemainingDevicePath    The remaining device patch.
> +
> +  @retval EFI_SUCCESS            The controller is controlled by the usb bus.
> +  @retval EFI_ALREADY_STARTED    The controller is already controlled by the usb
> +                                 bus.
> +  @retval EFI_OUT_OF_RESOURCES   Failed to allocate resources.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +UsbDeviceDxeDriverStart (
> +  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
> +  IN EFI_HANDLE                   Controller,
> +  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath
> +  );
> +
> +/**
> +  Stop handle the controller by this USB bus driver.
> +
> +  @param  This                   The USB bus driver binding protocol.
> +  @param  Controller             The controller to release.
> +  @param  NumberOfChildren       The child of USB bus that opened controller
> +                                 BY_CHILD.
> +  @param  ChildHandleBuffer      The array of child handle.
> +
> +  @retval EFI_SUCCESS            The controller or children are stopped.
> +  @retval EFI_DEVICE_ERROR       Failed to stop the driver.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +UsbDeviceDxeDriverStop (
> +  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
> +  IN EFI_HANDLE                   Controller,
> +  IN UINTN                        NumberOfChildren,
> +  IN EFI_HANDLE                   *ChildHandleBuffer
> +  );
> +
> +VOID
> +EFIAPI
> +PlatformSpecificInit (
> +  VOID
> +  );
> +
> +extern EFI_COMPONENT_NAME_PROTOCOL    mUsbDeviceDxeComponentName;
> +extern EFI_COMPONENT_NAME2_PROTOCOL   mUsbDeviceDxeComponentName2;
> +
> +#endif
> +
> diff --git a/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbDeviceDxe.inf b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbDeviceDxe.inf
> new file mode 100644
> index 0000000000..acf5021327
> --- /dev/null
> +++ b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbDeviceDxe.inf
> @@ -0,0 +1,74 @@
> +## @file
> +#
> +#  Copyright (c) 2008 - 2017, Intel Corporation. All rights reserved.<BR>
> +#
> +#  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.
> +#
> +##
> +
> +[Defines]
> +  INF_VERSION                    = 0x00010005
> +  BASE_NAME                      = UsbDeviceDxe
> +  FILE_GUID                      = 42CF2D4A-78B4-4B80-80F9-96A83A630D70
> +  MODULE_TYPE                    = UEFI_DRIVER
> +  VERSION_STRING                 = 1.0
> +  ENTRY_POINT                    = UsbDeviceDxeEntryPoint
> +
> +#
> +# The following information is for reference only and not required by the build tools.
> +#
> +#  VALID_ARCHITECTURES           = IA32 X64
> +#
> +
> +[Sources.common]
> +  UsbDeviceDxe.c
> +  UsbFuncIo.c
> +  UsbIoNode.c
> +  ComponentName.c
> +  UsbDeviceMode.c
> +  XdciDevice.c
> +  XdciDWC.c
> +  XdciTable.c
> +  XdciUtility.c
> +
> +[Packages]
> +  MdePkg/MdePkg.dec
> +  BroxtonSiPkg/BroxtonSiPkg.dec
> +  BroxtonPlatformPkg/PlatformPkg.dec
> +
> +[LibraryClasses]
> +  BaseMemoryLib
> +  DebugLib
> +  DevicePathLib
> +  MemoryAllocationLib
> +  TimerLib
> +  PcdLib
> +  UefiBootServicesTableLib
> +  UefiDriverEntryPoint
> +  UefiLib
> +  PmicLib
> +
> +[Protocols]
> +  gEfiUsbDeviceModeProtocolGuid
> +  gEfiUsbFnIoProtocolGuid
> +  gEfiPciIoProtocolGuid
> +
> +[Pcd]
> +  gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress
> +
> +[Guids]
> +  gEfiEventExitBootServicesGuid
> +
> +#[BuildOptions]
> +#  MSFT:*_*_*_CC_FLAGS = /D SUPPORT_SUPER_SPEED
> +#  GCC:*_*_*_CC_FLAGS = -DSUPPORT_SUPER_SPEED
> +
> +[Depex]
> +  TRUE
> +
> diff --git a/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbDeviceMode.c b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbDeviceMode.c
> new file mode 100644
> index 0000000000..48a37a37fb
> --- /dev/null
> +++ b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbDeviceMode.c
> @@ -0,0 +1,1489 @@
> +/** @file
> +  Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR>
> +
> +  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.
> +
> +**/
> +
> +#include <Base.h>
> +#include <Library/BaseLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Library/IoLib.h>
> +#include <PlatformBaseAddresses.h>
> +#include <ScAccess.h>
> +#include "XdciUtility.h"
> +#include "UsbDeviceMode.h"
> +#include "UsbDeviceDxe.h"
> +
> +//
> +// Global USBD driver object. This is the main private driver object
> +// that contains all data needed for this driver to operate.
> +//
> +USB_DEVICE_DRIVER_OBJ mDrvObj;
> +
> +//
> +// Global data IO transaction request object
> +//
> +USB_DEVICE_IO_REQ  mCtrlIoReq = {
> +  //
> +  // IO information containing the Buffer and data size
> +  //
> +  {
> +    NULL,
> +    0,
> +  },
> +  //
> +  // Note: This object is used for Control Ep transfers only
> +  // therefore the endpoint info must always be NULL
> +  //
> +  {
> +    NULL,
> +    NULL,
> +  }
> +};
> +
> +//
> +// global flag to signal device event processing loop to run/stop
> +//
> +BOOLEAN mXdciRun = FALSE;
> +
> +STATIC VOID
> +XhciSwitchSwid(BOOLEAN enable)
> +{
> +  UINTN                             XhciPciMmBase;
> +  EFI_PHYSICAL_ADDRESS              XhciMemBaseAddress;
> +  UINT32                            DualRoleCfg0;
> +  UINT32                            DualRoleCfg1;
> +
> +  XhciPciMmBase = MmPciAddress (0, 0, PCI_DEVICE_NUMBER_XHCI, PCI_FUNCTION_NUMBER_XHCI, 0);
> +  XhciMemBaseAddress = MmioRead32 ((UINTN) (XhciPciMmBase + R_XHCI_MEM_BASE)) & B_XHCI_MEM_BASE_BA;
> +  DEBUG ((DEBUG_INFO, "XhciPciMmBase=%x, XhciMemBaseAddress=%x\n", XhciPciMmBase, XhciMemBaseAddress));
> +
> +  DualRoleCfg0 = MmioRead32 ((UINTN)(XhciMemBaseAddress + R_XHCI_MEM_DUAL_ROLE_CFG0));
> +  if (enable) {
> +    DualRoleCfg0 = DualRoleCfg0 | (1 << 24) | (1 << 21) | (1 << 20);
> +    DEBUG ((DEBUG_INFO, "DualRoleCfg0 : Set SW ID : 0x%x \n", DualRoleCfg0));
> +  }
> +  else {
> +    DualRoleCfg0 = DualRoleCfg0 & ~(1 << 24) & ~(1 << 21) & ~(1 << 20);
> +    DEBUG ((DEBUG_INFO, "DualRoleCfg0 : Clear SW ID : 0x%x \n", DualRoleCfg0));
> +  }
> +  MmioWrite32 ((UINTN)(XhciMemBaseAddress + R_XHCI_MEM_DUAL_ROLE_CFG0), DualRoleCfg0);
> +
> +  DualRoleCfg1 = MmioRead32 ((UINTN)(XhciMemBaseAddress + R_XHCI_MEM_DUAL_ROLE_CFG1));
> +  DEBUG ((DEBUG_INFO, "DualRoleCfg1 : 0x%x \n", DualRoleCfg1));
> +}
> +
> +VOID
> +EFIAPI
> +UsbdMonitorEvents (
> +  IN EFI_EVENT            Event,
> +  IN VOID                 *Context
> +  )
> +{
> +  USB_XDCI_DEV_CONTEXT    *XdciDevContext;
> +  UINT32                  EventCount;
> +  UINT32                  PreEventCount;
> +  UINT32                  LoopCount;
> +
> +  XdciDevContext = (USB_XDCI_DEV_CONTEXT *) Context;
> +  EventCount = UsbRegRead ((UINT32)XdciDevContext->XdciMmioBarAddr, DWC_XDCI_EVNTCOUNT_REG (0));
> +  if (EventCount == 0) {
> +    return;
> +  }
> +
> +  LoopCount = 0;
> +  PreEventCount = EventCount;
> +  while (EventCount != 0) {
> +    if (UsbDeviceIsrRoutineTimerBased (mDrvObj.XdciDrvObj) != EFI_SUCCESS) {
> +      DEBUG ((DEBUG_INFO, "UsbDeviceRun() - Failed to execute event ISR\n"));
> +    }
> +    EventCount = UsbRegRead ((UINT32)XdciDevContext->XdciMmioBarAddr, DWC_XDCI_EVNTCOUNT_REG (0));
> +    if (PreEventCount == EventCount) {
> +      LoopCount++;
> +      if (LoopCount >= 5) {
> +        DEBUG ((DEBUG_INFO, "USB is working on a long event...\n"));
> +        break;
> +      }
> +    } else {
> +      LoopCount = 0;
> +    }
> +  }
> +
> +  return;
> +}
> +
> +/**
> +  Initializes the XDCI core
> +
> +  @param MmioBar       Address of MMIO BAR
> +  @param XdciHndl      Double pointer to for XDCI layer to set as an
> +                       opaque handle to the driver to be used in subsequent
> +                       interactions with the XDCI layer.
> +
> +  @return EFI_SUCCESS if successfully initialized XDCI, EFI_DEVICE_ERROR otherwise
> +
> +**/
> +EFI_STATUS
> +UsbdInit (
> +  IN UINT32    MmioBar,
> +  IN VOID      **XdciHndl
> +  )
> +{
> +  EFI_STATUS               Status = EFI_DEVICE_ERROR;
> +  USB_DEV_CONFIG_PARAMS    ConfigParams;
> +
> +  XhciSwitchSwid(TRUE);
> +
> +  DEBUG ((DEBUG_INFO, "UsbdInit start\n"));
> +  ConfigParams.ControllerId = USB_ID_DWC_XDCI;
> +  ConfigParams.BaseAddress  = MmioBar;
> +  ConfigParams.Role = USB_ROLE_DEVICE;
> +  ConfigParams.Speed = USB_SPEED_SUPER;
> +
> +  Status = UsbDeviceInit (&ConfigParams, XdciHndl);
> +
> +  DEBUG ((DEBUG_INFO, "UsbdInit status is %x\n", Status));
> +  DEBUG ((DEBUG_INFO, "ConfigParams.BaseAddress 0x%x\n", ConfigParams.BaseAddress));
> +
> +  return Status;
> +}
> +
> +
> +/**
> +  Copies relevant endpoint data from standard USB endpoint descriptors
> +  to the usbEpInfo structure used by the XDCI
> +
> +  @param EpDest   destination structure
> +  @param EpSrc    source structure
> +
> +  @return VOID
> +
> +**/
> +VOID
> +UsbdSetEpInfo (
> +  IN USB_EP_INFO                 *EpDest,
> +  IN USB_DEVICE_ENDPOINT_INFO    *EpSrc
> +  )
> +{
> +  EFI_USB_ENDPOINT_DESCRIPTOR              *EpDesc = NULL;
> +  EFI_USB_ENDPOINT_COMPANION_DESCRIPTOR    *EpCompDesc = NULL;
> +
> +  //
> +  // start by clearing all data in the destination
> +  //
> +  SetMem (EpDest, sizeof(USB_EP_INFO), 0);
> +  EpDesc = EpSrc->EndpointDesc;
> +  EpCompDesc = EpSrc->EndpointCompDesc;
> +
> +  if (EpDesc != NULL) {
> +    EpDest->EpNum = EpDesc->EndpointAddress & 0x0F; //Bits 0-3 are ep num
> +    EpDest->EpDir = ((EpDesc->EndpointAddress & USB_ENDPOINT_DIR_IN) > 0) ? UsbEpDirIn : UsbEpDirOut;
> +    EpDest->EpType = EpDesc->Attributes & USB_ENDPOINT_TYPE_MASK;
> +    EpDest->MaxPktSize = EpDesc->MaxPacketSize;
> +    EpDest->Interval = EpDesc->Interval;
> +  }
> +  if (EpCompDesc != NULL) {
> +    EpDest->MaxStreams = EpCompDesc->Attributes & USB_EP_BULK_BM_ATTR_MASK;
> +    EpDest->BurstSize = EpCompDesc->MaxBurst;
> +    EpDest->Mult = EpCompDesc->BytesPerInterval;
> +  }
> +
> +  return;
> +}
> +
> +
> +/**
> +  Initializes the given endpoint
> +
> +  @param XdciHndl  Pointer (handle) to the XDCI driver object
> +  @param DevEpInfo Pointer to endpoint info structure
> +                   for the endpoint to initialize
> +
> +  @return EFI_SUCCESS if operation succeeded, EFI_DEVICE_ERROR otherwise
> +
> +**/
> +EFI_STATUS
> +UsbdInitEp (
> +  IN VOID                      *XdciHndl,
> +  IN USB_DEVICE_ENDPOINT_INFO  *DevEpInfo
> +  )
> +{
> +  EFI_STATUS   Status = EFI_DEVICE_ERROR;
> +  USB_EP_INFO  EpInfo;
> +
> +  UsbdSetEpInfo (&EpInfo, DevEpInfo);
> +  Status = UsbDeviceInitEp (XdciHndl, &EpInfo);
> +
> +  return Status;
> +}
> +
> +
> +/**
> +  Callback handler used when transfer operations complete. Calls
> +  upper layer routine to handle the operation.
> +
> +  @param XdciHndl  Pointer (handle) to the XDCI driver object
> +  @param XferReq   Pointer to the transfer request structure
> +
> +  @return VOID
> +
> +**/
> +VOID
> +EFIAPI
> +UsbdXferDoneHndlr (
> +  IN VOID                    *XdciHndl,
> +  IN USB_XFER_REQUEST        *XferReq
> +  )
> +{
> +  EFI_USB_DEVICE_XFER_INFO  XferInfo;
> +
> +  DEBUG ((DEBUG_INFO, "UsbdXferDoneHndlr\n"));
> +
> +  XferInfo.EndpointNum = (UINT8)XferReq->EpInfo.EpNum;
> +  XferInfo.EndpointDir = XferReq->EpInfo.EpDir;
> +  XferInfo.EndpointType = XferReq->EpInfo.EpType;
> +  XferInfo.Buffer = XferReq->XferBuffer;
> +  XferInfo.Length = XferReq->ActualXferLen;
> +
> +  //
> +  // If this is a non-control transfer complete, notify the class driver
> +  //
> +  if (XferInfo.EndpointNum > 0) {
> +    if (mDrvObj.UsbdDevObj->DataCallback != NULL) {
> +      mDrvObj.UsbdDevObj->DataCallback (&XferInfo);
> +    }
> +  }
> +
> +  return;
> +}
> +
> +
> +/**
> +  Queue a request to transmit data
> +
> +  @param XdciHndl  Pointer (handle) to the XDCI driver object
> +  @param IoReq     Pointer to IO structure containing details of the
> +                   transfer request
> +
> +  @return EFI_SUCCESS if operation succeeded, EFI_DEVICE_ERROR otherwise
> +
> +**/
> +EFI_STATUS
> +UsbdEpTxData (
> +  IN VOID               *XdciHndl,
> +  IN USB_DEVICE_IO_REQ  *IoReq
> +  )
> +{
> +  EFI_STATUS        Status = EFI_DEVICE_ERROR;
> +  USB_XFER_REQUEST  TxReq;
> +
> +  //
> +  //set endpoint data
> +  //
> +  UsbdSetEpInfo (&(TxReq.EpInfo), &(IoReq->EndpointInfo)); // set endpoint data
> +
> +  //
> +  //if this is a control endpoint, set the number and direction
> +  //
> +  if (IoReq->EndpointInfo.EndpointDesc == NULL) {
> +    TxReq.EpInfo.EpNum = 0;
> +    TxReq.EpInfo.EpDir = UsbEpDirIn;
> +  }
> +
> +  //
> +  // setup the trasfer request
> +  //
> +  TxReq.XferBuffer = IoReq->IoInfo.Buffer;
> +  TxReq.XferLen = IoReq->IoInfo.Length;
> +  TxReq.XferDone = UsbdXferDoneHndlr;
> +
> +  DEBUG ((DEBUG_INFO,  "TX REQUEST: EpNum: 0x%x, epDir: 0x%x, epType: 0x%x, MaxPktSize: 0x%x\n",\
> +          TxReq.EpInfo.EpNum, TxReq.EpInfo.EpDir, TxReq.EpInfo.EpType, TxReq.EpInfo.MaxPktSize));
> +
> +  Status = UsbXdciDeviceEpTxData (XdciHndl, &TxReq);
> +
> +  return Status;
> +}
> +
> +
> +/**
> +  Queue a request to receive data
> +
> +  @param XdciHndl  Pointer (handle) to the XDCI driver object
> +  @param IoReq     Pointer to IO structure containing details of the
> +                   receive request
> +
> +  @return EFI_SUCCESS if operation succeeded, EFI_DEVICE_ERROR otherwise
> +
> +**/
> +EFI_STATUS
> +UsbdEpRxData (
> +  IN VOID               *XdciHndl,
> +  IN USB_DEVICE_IO_REQ  *IoReq
> +  )
> +{
> +  EFI_STATUS        Status = EFI_DEVICE_ERROR;
> +  USB_XFER_REQUEST  RxReq;
> +  UINT32            ReqPacket;
> +
> +  DEBUG ((DEBUG_INFO,  "RX REQUEST in: IoReq->IoInfo.Length: 0x%x\n", IoReq->IoInfo.Length));
> +  DEBUG ((DEBUG_INFO,  "RX REQUEST in: MaxPacketSize: 0x%x\n", IoReq->EndpointInfo.EndpointDesc->MaxPacketSize));
> +
> +  if (IoReq->EndpointInfo.EndpointDesc->MaxPacketSize == 0) {
> +    return EFI_DEVICE_ERROR;
> +  }
> +
> +  //
> +  // set endpoint data
> +  //
> +  UsbdSetEpInfo (&(RxReq.EpInfo), &(IoReq->EndpointInfo));
> +
> +  //
> +  // setup the trasfer request
> +  //
> +  RxReq.XferBuffer = IoReq->IoInfo.Buffer;
> +
> +  //
> +  // Transfer length should be multiple of USB packet size.
> +  //
> +  ReqPacket = IoReq->IoInfo.Length / IoReq->EndpointInfo.EndpointDesc->MaxPacketSize;
> +  ReqPacket = ((IoReq->IoInfo.Length % IoReq->EndpointInfo.EndpointDesc->MaxPacketSize) == 0)? ReqPacket : ReqPacket + 1;
> +  RxReq.XferLen = ReqPacket * IoReq->EndpointInfo.EndpointDesc->MaxPacketSize;
> +
> +  RxReq.XferDone = UsbdXferDoneHndlr;
> +
> +  DEBUG ((DEBUG_INFO,  "RX REQUEST: EpNum: 0x%x, epDir: 0x%x, epType: 0x%x\n",\
> +          RxReq.EpInfo.EpNum, RxReq.EpInfo.EpDir, RxReq.EpInfo.EpType));
> +  DEBUG ((DEBUG_INFO,  "RX REQUEST send: XferLen: 0x%x\n", RxReq.XferLen));
> +
> +  Status = UsbXdciDeviceEpRxData (XdciHndl, &RxReq);
> +
> +  return Status;
> +}
> +
> +
> +/**
> +  Callback used to handle Reset events from the XDCI
> +
> +  @param Param Pointer to a generic callback parameter structure
> +
> +  @return XDCI usb status
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +UsbdResetEvtHndlr (
> +  IN USB_DEVICE_CALLBACK_PARAM  *Param
> +  )
> +{
> +  EFI_STATUS    Status = EFI_DEVICE_ERROR;
> +
> +  DEBUG ((DEBUG_INFO, "UsbdResetEvtHndlr\n"));
> +
> +  //
> +  // reset device address to 0
> +  //
> +  Status = UsbDeviceSetAddress (mDrvObj.XdciDrvObj, 0x0);
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((DEBUG_INFO, "UsbdResetHdlr() - Failed to set address in XDCI\n"));
> +  }
> +
> +  return Status;
> +}
> +
> +
> +/**
> +  Callback used to handle Connection done events from the XDCI
> +
> +  @param Param Pointer to a generic callback parameter structure
> +
> +  @return XDCI usb status
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +UsbdConnDoneEvtHndlr (
> +  IN USB_DEVICE_CALLBACK_PARAM *Param
> +  )
> +{
> +  EFI_STATUS    Status = EFI_DEVICE_ERROR;
> +
> +  DEBUG ((DEBUG_INFO, "UsbdConnDoneEvtHndlr\n"));
> +
> +  //
> +  //reset device address to 0
> +  //
> +  Status = UsbDeviceSetAddress (mDrvObj.XdciDrvObj, 0x0);
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((DEBUG_INFO, "UsbdConnDoneHdlr() - Failed to set address in XDCI\n"));
> +  }
> +
> +  //
> +  // set the device state to attached/connected
> +  //
> +  mDrvObj.State = UsbDevStateAttached;
> +
> +  return Status;
> +}
> +
> +
> +/**
> +  Callback used to handle Control Endpoint Setup events from the XDCI
> +
> +  @param Param Pointer to a generic callback parameter structure
> +
> +  @return XDCI usb status
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +UsbdSetupEvtHndlr (
> +  IN USB_DEVICE_CALLBACK_PARAM *Param
> +  )
> +{
> +  EFI_STATUS              Status = EFI_SUCCESS;
> +  EFI_USB_DEVICE_REQUEST  Req;
> +
> +  DEBUG ((DEBUG_INFO, "UsbdSetupEvtHndlr\n"));
> +
> +  //
> +  // Fill out request object from the incomming Buffer
> +  //
> +  CopyMem (&Req, Param->Buffer, sizeof(EFI_USB_DEVICE_REQUEST));
> +
> +  Status = UsbdSetupHdlr (&Req);
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((DEBUG_INFO, "UsbdSetupEvtHndlr: EFI_DEVICE_ERROR\n"));
> +  }
> +
> +  return Status;
> +}
> +
> +
> +/**
> + * Callback used to handle XferNotReady events from the XDCI
> + *
> + * @param Param Pointer to a generic callback parameter structure
> + *
> + * @return XDCI usb status
> + */
> +EFI_STATUS
> +EFIAPI
> +UsbdNrdyEvtHndlr (
> +  IN USB_DEVICE_CALLBACK_PARAM *Param
> +  )
> +{
> +  DEBUG ((DEBUG_INFO, "UsbdNrdyEvtHndlr\n"));
> +  return EFI_SUCCESS;
> +}
> +
> +
> +/**
> +  Registers callbacks for event handlers with the XDCI layer.
> +  The functions will be called as the registered events are triggered.
> +
> +  @param  XdciHndl to XDCI core driver
> +  @return EFI_SUCCESS if successful, EFI_DEVICE_ERROR otherwise
> +
> +**/
> +EFI_STATUS
> +UsbdRegisterCallbacks (
> +  IN VOID  *XdciHndl
> +  )
> +{
> +  if (UsbDeviceRegisterCallback (XdciHndl, USB_DEVICE_RESET_EVENT, UsbdResetEvtHndlr) != EFI_SUCCESS) {
> +    goto UdciRegCallbackError;
> +  }
> +
> +  if (UsbDeviceRegisterCallback (XdciHndl, USB_DEVICE_CONNECTION_DONE, UsbdConnDoneEvtHndlr) != EFI_SUCCESS) {
> +    goto UdciRegCallbackError;
> +  }
> +
> +  if (UsbDeviceRegisterCallback (XdciHndl, USB_DEVICE_SETUP_PKT_RECEIVED, UsbdSetupEvtHndlr) != EFI_SUCCESS) {
> +    goto UdciRegCallbackError;
> +  }
> +
> +  if (UsbDeviceRegisterCallback (XdciHndl, USB_DEVICE_XFER_NRDY, UsbdNrdyEvtHndlr) != EFI_SUCCESS) {
> +    goto UdciRegCallbackError;
> +  }
> +
> +  return EFI_SUCCESS;
> +
> +UdciRegCallbackError:
> +  return EFI_DEVICE_ERROR;
> +}
> +
> +
> +/**
> +  Returns the configuration descriptor for this device. The data
> +  Buffer returned will also contain all downstream interface and
> +  endpoint Buffers.
> +
> +  @param Buffer    Pointer to destination Buffer to copy descriptor data to
> +  @param DescIndex the index of the descriptor to return
> +  @param ReqLen    the length in bytes of the request Buffer
> +  @param DataLen   Pointer whos value is to be filled with the byte count of
> +                   data copied to the output Buffer
> +
> +  @return EFI_SUCCESS if descritor successfully copied, EFI_DEVICE_ERROR otherwise
> +
> +**/
> +EFI_STATUS
> +UsbdGetConfigDesc (
> +  IN VOID      *Buffer,
> +  IN UINT8     DescIndex,
> +  IN UINT32    ReqLen,
> +  IN UINT32    *DataLen
> +  )
> +{
> +  EFI_STATUS             Status = EFI_DEVICE_ERROR;
> +  UINT8                  NumConfigs = 0;
> +  UINT32                 ConfigLen = 0;
> +  USB_DEVICE_CONFIG_OBJ  *ConfigObj = NULL;
> +  VOID                   *Descriptor = 0;
> +  UINT32                 Length = 0;
> +
> +  DEBUG ((DEBUG_INFO, "UsbdGetConfigDesc()\n"));
> +
> +  //
> +  // For a CONFIGURATION request we send back all descriptors branching out
> +  // from this descriptor including the INTERFACE and ENDPOINT descriptors
> +  //
> +  //
> +  // Verify the requested configuration exists - check valid index
> +  //
> +  NumConfigs = mDrvObj.UsbdDevObj->DeviceDesc->NumConfigurations;
> +
> +  if (DescIndex < NumConfigs) {
> +    //
> +    // get the configuration object using the index Offset
> +    //
> +    ConfigObj = (mDrvObj.UsbdDevObj->ConfigObjs + DescIndex);
> +    //
> +    // get the complete configuration Buffer block including Interface and Endpoint data
> +    //
> +    Descriptor = ConfigObj->ConfigAll;
> +    //
> +    // The config descriptor TotalLength has the full value for all desc Buffers
> +    //
> +    ConfigLen = ConfigObj->ConfigDesc->TotalLength;
> +    //
> +    // copy the data to the output Buffer
> +    //
> +    Length = MIN (ReqLen, ConfigLen);
> +    CopyMem (Buffer, Descriptor, Length);
> +    *DataLen = Length;
> +    Status = EFI_SUCCESS;
> +  } else {
> +    DEBUG ((DEBUG_INFO, "UsbdGetConfigDesc() - Invalid Config index: %i\n", DescIndex));
> +  }
> +
> +  if (Status == EFI_SUCCESS) {
> +    if (ConfigObj != NULL) {
> +      PrintConfigDescriptor (ConfigObj->ConfigDesc);
> +    }
> +  }
> +
> +  return Status;
> +}
> +
> +
> +/**
> +  Sets the active configuration to the selected configuration index if it exists
> +
> +  @param CfgValue  the configuration value to set
> +
> +  @return EFI_SUCCESS if the configuration was set, EFI_DEVICE_ERROR otherwise
> +
> +**/
> +EFI_STATUS
> +UsbdSetConfig (
> +  UINT8  CfgValue
> +  )
> +{
> +  EFI_STATUS                 Status = EFI_DEVICE_ERROR;
> +  UINT8                      numConfigs = 0;
> +  USB_DEVICE_CONFIG_OBJ      *pConfigObj = NULL;
> +  USB_DEVICE_INTERFACE_OBJ   *pIfObj = NULL;
> +  USB_DEVICE_ENDPOINT_OBJ    *pEpObj = NULL;
> +  UINT8                      cfgItr = 0;
> +  UINT8                      ifItr = 0;
> +  UINT8                      epItr = 0;
> +  USB_DEVICE_ENDPOINT_INFO   EpInfo;
> +  USB_EP_INFO                UsbEpInfo;
> +
> +  DEBUG ((DEBUG_INFO, "UsbdSetConfig()\n"));
> +  //
> +  // Verify the requested configuration exists - check valid index
> +  //
> +  numConfigs = mDrvObj.UsbdDevObj->DeviceDesc->NumConfigurations;
> +
> +  if (CfgValue != 0) {
> +    //
> +    // Search for a matching configuration
> +    //
> +    for (cfgItr = 0; cfgItr < numConfigs; cfgItr++) {
> +      pConfigObj = (mDrvObj.UsbdDevObj->ConfigObjs + cfgItr);
> +      if (pConfigObj->ConfigDesc->ConfigurationValue == CfgValue) {
> +
> +        //
> +        // Set the active configuration object
> +        //
> +        mDrvObj.ActiveConfigObj = pConfigObj;
> +        //
> +        // Find all interface objects for this configuration
> +        //
> +        for (ifItr = 0; ifItr < pConfigObj->ConfigDesc->NumInterfaces; ifItr++) {
> +          pIfObj = (pConfigObj->InterfaceObjs + ifItr);
> +          //
> +          // Configure the Endpoints in the XDCI
> +          //
> +          for (epItr = 0; epItr < pIfObj->InterfaceDesc->NumEndpoints; epItr++) {
> +            pEpObj = (pIfObj->EndpointObjs + epItr);
> +
> +            EpInfo.EndpointDesc = pEpObj->EndpointDesc;
> +            EpInfo.EndpointCompDesc = pEpObj->EndpointCompDesc;
> +
> +            if (UsbdInitEp (mDrvObj.XdciDrvObj, &EpInfo) == EFI_SUCCESS) {
> +              UsbdSetEpInfo(&UsbEpInfo, &EpInfo);
> +              if (UsbDeviceEpEnable (mDrvObj.XdciDrvObj, &UsbEpInfo) == EFI_SUCCESS) {
> +                Status = EFI_SUCCESS;
> +              } else {
> +                DEBUG ((DEBUG_INFO, "UsbdSetConfig() - Failed to enable endpoint\n"));
> +              }
> +            } else {
> +              DEBUG ((DEBUG_INFO, "UsbdSetConfig() - Failed to initialize endpoint\n"));
> +            }
> +          }
> +        }
> +        //
> +        // Let the class driver know it is configured
> +        //
> +        if (Status == EFI_SUCCESS) {
> +          if (mDrvObj.UsbdDevObj->ConfigCallback != NULL) {
> +            mDrvObj.UsbdDevObj->ConfigCallback (CfgValue);
> +          }
> +        }
> +
> +        mDrvObj.State = UsbDevStateConfigured; // we are now configured
> +
> +        break; // break from config search loop
> +      }
> +    }
> +  }
> +
> +  if (EFI_ERROR (Status)) {
> +   DEBUG ((DEBUG_INFO, "UsbdSetConfig() - Invalid requested configuration value: %i\n", CfgValue));
> +  }
> +
> +  return Status;
> +}
> +
> +
> +/**
> +  Returns the currently active configuration value
> +
> +  @param Buffer    Pointer to destination Buffer to copy configuration value to
> +  @param ReqLen    the length in bytes of the request Buffer
> +  @param DataLen   Pointer whos value is to be filled with the byte count of
> +                   data copied to the output Buffer
> +
> +  @return EFI_SUCCESS if config value is successfully copied, EFI_DEVICE_ERROR otherwise
> +
> +**/
> +EFI_STATUS
> +UsbdGetConfig (
> +  VOID      *Buffer,
> +  UINT32    ReqLen,
> +  UINT32    *DataLen
> +  )
> +{
> +  EFI_STATUS    Status = EFI_DEVICE_ERROR;
> +
> +  DEBUG ((DEBUG_INFO, "UsbdGetConfig()\n"));
> +
> +  if (ReqLen >= 1) { // length of data expected must be 1
> +    if (mDrvObj.ActiveConfigObj != NULL) { // assure we have a config active
> +      *DataLen = 1; // one byte for ConfigurationValue
> +      *(UINT8*)Buffer = mDrvObj.ActiveConfigObj->ConfigDesc->ConfigurationValue;
> +
> +      Status = EFI_SUCCESS;
> +    } else {
> +      DEBUG ((DEBUG_INFO, "UsbdGetConfig() - No active configuration available\n"));
> +    }
> +  } else {
> +    DEBUG ((DEBUG_INFO, "UsbdGetConfig() - Invalid data length\n"));
> +  }
> +
> +  return Status;
> +}
> +
> +
> +/**
> +  Returns the requested string descriptor if it exists
> +
> +  @param Buffer    Pointer to destination Buffer to copy descriptor data to
> +  @param DescIndex the index of the descriptor to return
> +  @param LangId    the target language ID
> +  @param ReqLen    the length in bytes of the request Buffer
> +  @param DataLen   Pointer whos value is to be filled with the byte count of
> +                   data copied to the output Buffer
> +
> +  @return EFI_SUCCESS if descritor successfully copied, EFI_DEVICE_ERROR otherwise
> +
> +**/
> +EFI_STATUS
> +UsbdGetStringDesc (
> +  VOID      *Buffer,
> +  UINT8     DescIndex,
> +  UINT16    LangId,
> +  UINT32    ReqLen,
> +  UINT32    *DataLen
> +  )
> +{
> +  EFI_STATUS             Status = EFI_DEVICE_ERROR;
> +  UINT32                 Length = 0;
> +  USB_STRING_DESCRIPTOR  *StringDesc;
> +  UINT8                  Index = 0;
> +  UINT8                  StrLangEntries = 0;
> +  BOOLEAN                StrLangFound = FALSE;
> +
> +  DEBUG ((DEBUG_INFO, "UsbdGetStringDesc: Index: 0x%x, LangId: 0x%x, ReqLen: 0x%x\n", DescIndex, LangId, ReqLen));
> +
> +  //
> +  // index zero of the string table contains the supported language codes
> +  //
> +  if (DescIndex == 0) {
> +    StringDesc = (mDrvObj.UsbdDevObj->StringTable);
> +    Length = MIN (ReqLen, StringDesc->Length);
> +    CopyMem (Buffer, StringDesc, Length);
> +    *DataLen = Length;
> +    Status = EFI_SUCCESS;
> +  } else {
> +
> +    //
> +    // Verify the requested language ID is supported. String descriptor Zero
> +    // (First entry in the string table) is expected to contain the language list.
> +    // The requested language ID is specified in the Index member of the request.
> +    //
> +    StringDesc = mDrvObj.UsbdDevObj->StringTable; // get language string descriptor
> +    StrLangEntries = ((StringDesc->Length - 2) >> 1);
> +    DEBUG ((DEBUG_INFO, "StrLangEntries=%x\n", StrLangEntries));
> +
> +    DEBUG ((DEBUG_INFO, "Looking LangID: \n"));
> +
> +    for (Index = 0; Index < StrLangEntries; Index++) {
> +      DEBUG ((DEBUG_INFO, "LangID [%x]= %x\n", Index, StringDesc->LangID [Index]));
> +
> +      if (StringDesc->LangID [Index] == LangId) {
> +        DEBUG ((DEBUG_INFO, "Found it\n"));
> +        StrLangFound = TRUE;
> +      }
> +    }
> +
> +    //
> +    // If we found a matching language, attempt to get the string index requested
> +    //
> +    if (StrLangFound == TRUE) {
> +      DEBUG ((DEBUG_INFO, "UsbdGetStringDesc: StrLangFound=Found, DescIndex=%x, StrTblEntries=%x\n", DescIndex, mDrvObj.UsbdDevObj->StrTblEntries));
> +
> +      if (DescIndex < mDrvObj.UsbdDevObj->StrTblEntries) {
> +        //
> +        // get the string descriptor for the requested index
> +        //
> +        StringDesc = (mDrvObj.UsbdDevObj->StringTable + DescIndex);
> +
> +        Length = MIN (ReqLen, StringDesc->Length);
> +        DEBUG ((DEBUG_INFO, "ReqLen=%x, StringLength=%x, Length=%x\n", ReqLen, StringDesc->Length, Length));
> +
> +        CopyMem (Buffer, StringDesc, Length);
> +        *DataLen = Length;
> +        Status = EFI_SUCCESS;
> +      } else {
> +        DEBUG ((DEBUG_INFO, "UsbdGetStringDesc: Invalid String index in USB_REQ_GET_DESCRIPTOR request\n"));
> +      }
> +    } else {
> +      DEBUG ((DEBUG_INFO, "UsbdGetStringDesc: Unsupported String Language ID for USB_REQ_GET_DESCRIPTOR request\n"));
> +    }
> +  }
> +
> +  if (Status == EFI_SUCCESS) {
> +    PrintStringDescriptor (StringDesc);
> +  }
> +  return Status;
> +}
> +
> +
> +#ifdef SUPPORT_SUPER_SPEED
> +/**
> +  Returns the configuration descriptor for this device. The data
> +  Buffer returned will also contain all downstream interface and
> +  endpoint Buffers.
> +
> +  @param Buffer    Pointer to destination Buffer to copy descriptor data to
> +  @param ReqLen    the length in bytes of the request Buffer
> +  @param DataLen   Pointer whos value is to be filled with the byte count of
> +                   data copied to the output Buffer
> +
> +  @return EFI_SUCCESS if descritor successfully copied, EFI_DEVICE_ERROR otherwise
> +
> +**/
> +EFI_STATUS
> +UsbdGetBOSDesc (
> +  IN VOID      *Buffer,
> +  IN UINT32    ReqLen,
> +  IN UINT32    *DataLen
> +  )
> +{
> +  EFI_USB_BOS_DESCRIPTOR  *BosDesc = 0;
> +  UINT32                  Length = 0;
> +
> +  DEBUG ((DEBUG_INFO, "UsbdGetBOSDesc()\n"));
> +
> +  BosDesc = mDrvObj.UsbdDevObj->BosDesc;
> +  Length = MIN (ReqLen, mDrvObj.UsbdDevObj->BosDesc->TotalLength);
> +
> +  CopyMem(Buffer, BosDesc, Length);
> +  *DataLen = Length;
> +
> +  PrintBOSDescriptor (BosDesc);
> +
> +  return EFI_SUCCESS;
> +}
> +#endif
> +
> +/**
> +  Returns the current status for Device/Interface/Endpoint
> +
> +  @param Buffer    Pointer to destination Buffer to copy descriptor data to
> +  @param ReqType   The type of status to get
> +  @param ReqLen    the length in bytes of the request Buffer
> +  @param DataLen   Pointer whos value is to be filled with the byte count of
> +                   data copied to the output Buffer
> +
> +  @return EFI_SUCCESS if status successfully copied, EFI_DEVICE_ERROR otherwise
> +
> +**/
> +EFI_STATUS
> +UsbdGetStatus (
> +  VOID      *Buffer,
> +  UINT8     ReqType,
> +  UINT32    ReqLen,
> +  UINT32    *DataLen
> +  )
> +{
> +  EFI_STATUS  Status = EFI_DEVICE_ERROR;
> +
> +  DEBUG ((DEBUG_INFO, "UsbdGetStatus()\n"));
> +
> +  if (ReqLen >= 2) { // length of data must be at least 2 bytes
> +    switch (ReqType & USB_TARGET_MASK) {
> +      case USB_TARGET_DEVICE:
> +        *DataLen = 2; // two byte for status
> +        *(UINT16*)Buffer = USB_STATUS_SELFPOWERED;
> +        Status = EFI_SUCCESS;
> +        break;
> +
> +      case USB_TARGET_INTERFACE:
> +        //
> +        // No implementation needed at this time
> +        //
> +        break;
> +
> +      case USB_TARGET_ENDPOINT:
> +        //
> +        // No implementation needed at this time
> +        // Should specify if endpoint is halted. Implement as necessary.
> +        //
> +        break;
> +
> +      case USB_TARGET_OTHER:
> +        //
> +        // No implementation needed at this time
> +        //
> +        break;
> +
> +      default:
> +        break;
> +    }
> +  } else {
> +    DEBUG ((DEBUG_INFO, "UsbdGetStatus() - Invalid data length\n"));
> +  }
> +
> +  return Status;
> +}
> +
> +
> +/**
> +  Sets the address of the device
> +
> +  @param address   the address value to set
> +
> +  @return EFI_SUCCESS if address was set, EFI_DEVICE_ERROR otherwise
> +
> +**/
> +EFI_STATUS
> +UsbdSetAddress (
> +  UINT8    Address
> +  )
> +{
> +  EFI_STATUS  Status = EFI_DEVICE_ERROR;
> +
> +  DEBUG ((DEBUG_INFO, "UsbdSetAddress: setting address: 0x%x\n", Address));
> +
> +  if (Address <= 0x7F) { // address must not be > 127
> +    mDrvObj.Address = Address;
> +
> +    //
> +    // Configure Address in the XDCI
> +    //
> +    Status = UsbDeviceSetAddress (mDrvObj.XdciDrvObj, mDrvObj.Address);
> +    if (!EFI_ERROR (Status)) {
> +      mDrvObj.State = UsbDevStateAddress;
> +    } else {
> +      DEBUG ((DEBUG_INFO, "UsbdSetAddress: Failed to set address in XDCI\n"));
> +    }
> +  } else {
> +    DEBUG ((DEBUG_INFO, "UsbdSetAddress: Invalid address: 0x%x\n", Address));
> +  }
> +
> +  return Status;
> +}
> +
> +
> +/**
> +  Handles Setup device requests. Standard requests are immediately
> +  handled here, and any Class/Vendor specific requests are forwarded
> +  to the class driver
> +
> +  @param CtrlRequest  Pointer to a device request
> +
> +  @return EFI_SUCCESS if request successfully handled, FALSE otherwise
> +
> +**/
> +EFI_STATUS
> +UsbdSetupHdlr (
> +  IN EFI_USB_DEVICE_REQUEST    *CtrlRequest
> +  )
> +{
> +  EFI_STATUS              Status = EFI_DEVICE_ERROR;
> +  UINT8                   DescIndex = 0;
> +  USB_DEVICE_DESCRIPTOR   *DevDesc = 0;
> +
> +  //
> +  // Initialize the IO object
> +  //
> +  mCtrlIoReq.IoInfo.Length = 0;
> +
> +  DEBUG ((DEBUG_INFO, "UsbdSetupHdlr start\n"));
> +  PrintDeviceRequest (CtrlRequest);
> +
> +  //
> +  // Handle Standard Device Requests
> +  //
> +  if ((CtrlRequest->RequestType & USB_REQ_TYPE_MASK) == USB_REQ_TYPE_STANDARD) {
> +    switch (CtrlRequest->Request) {
> +      case USB_REQ_GET_DESCRIPTOR:
> +        DEBUG ((DEBUG_INFO, "UsbdSetupHdlr: Host requests get descriptor\n"));
> +        if (CtrlRequest->RequestType == USB_RT_TX_DIR_D_TO_H) {
> +          DescIndex = (CtrlRequest->Value & 0xff); // low byte is the index requested
> +          switch (CtrlRequest->Value >> 8) { // high byte contains request type
> +            case USB_DESC_TYPE_DEVICE:
> +              DEBUG ((DEBUG_INFO, "Descriptor tyep: Device\n"));
> +              DevDesc = mDrvObj.UsbdDevObj->DeviceDesc;
> +              //
> +              // copy the data to the output Buffer
> +              //
> +              mCtrlIoReq.IoInfo.Length = MIN (CtrlRequest->Length, DevDesc->Length);
> +              CopyMem (mCtrlIoReq.IoInfo.Buffer, DevDesc, mCtrlIoReq.IoInfo.Length);
> +              PrintDeviceDescriptor (DevDesc);
> +              break;
> +
> +            case USB_DESC_TYPE_CONFIG:
> +              DEBUG ((DEBUG_INFO, "Descriptor tyep: Configuration\n"));
> +              Status = UsbdGetConfigDesc (
> +                         mCtrlIoReq.IoInfo.Buffer,
> +                         DescIndex,
> +                         CtrlRequest->Length,
> +                         &(mCtrlIoReq.IoInfo.Length)
> +                         );
> +              break;
> +
> +            case USB_DESC_TYPE_STRING:
> +              DEBUG ((DEBUG_INFO, "Descriptor tyep: String\n"));
> +              Status = UsbdGetStringDesc (
> +                         mCtrlIoReq.IoInfo.Buffer,
> +                         DescIndex,
> +                         CtrlRequest->Index,
> +                         CtrlRequest->Length,
> +                         &(mCtrlIoReq.IoInfo.Length)
> +                         );
> +              break;
> +
> +#ifdef SUPPORT_SUPER_SPEED
> +            case USB_DESC_TYPE_BOS:
> +              DEBUG ((DEBUG_INFO, "Descriptor tyep: BOS\n"));
> +              Status = UsbdGetBOSDesc (
> +                         mCtrlIoReq.IoInfo.Buffer,
> +                         CtrlRequest->Length,
> +                         &(mCtrlIoReq.IoInfo.Length)
> +                         );
> +              break;
> +
> +            case USB_DESC_TYPE_SS_ENDPOINT_COMPANION:
> +              DEBUG ((DEBUG_INFO, "Descriptor tyep: Endpoint Companion\n"));
> +              break;
> +#endif
> +
> +            default:
> +              DEBUG ((DEBUG_INFO, "Descriptor tyep: Unsupported, USB_REQ_GET_DESCRIPTOR request: 0x%x\n", (CtrlRequest->Value >> 8)));
> +              break;
> +          }
> +        } else {
> +          DEBUG ((DEBUG_INFO, "UsbdSetupHdlr() - Invalid direction for USB_REQ_GET_DESCRIPTOR request\n"));
> +        }
> +        break;
> +
> +      case USB_REQ_GET_CONFIG:
> +        DEBUG ((DEBUG_INFO, "USB_REQ_GET_CONFIG\n"));
> +        if (CtrlRequest->RequestType == USB_RT_TX_DIR_D_TO_H) {
> +          Status = UsbdGetConfig (mCtrlIoReq.IoInfo.Buffer, CtrlRequest->Length, &(mCtrlIoReq.IoInfo.Length));
> +        } else {
> +          DEBUG ((DEBUG_INFO, "UsbdSetupHdlr: Invalid direction for USB_REQ_GET_CONFIG request\n"));
> +        }
> +        break;
> +
> +      case USB_REQ_SET_CONFIG:
> +        DEBUG ((DEBUG_INFO, "USB_REQ_SET_CONFIG\n"));
> +        if (CtrlRequest->RequestType == USB_RT_TX_DIR_H_TO_D) {
> +          Status = UsbdSetConfig ((UINT8)CtrlRequest->Value);
> +        } else {
> +          DEBUG ((DEBUG_INFO, "UsbdSetupHdlr: Invalid direction for USB_REQ_SET_CONFIG request\n"));
> +        }
> +        break;
> +
> +      case USB_REQ_SET_ADDRESS:
> +        DEBUG ((DEBUG_INFO, "USB_REQ_SET_ADDRESS\n"));
> +        if (CtrlRequest->RequestType == USB_RT_TX_DIR_H_TO_D) {
> +          Status = UsbdSetAddress ((UINT8)CtrlRequest->Value);
> +        } else {
> +          DEBUG ((DEBUG_INFO, "UsbdSetupHdlr: Invalid direction for USB_REQ_SET_ADDRESS request\n"));
> +        }
> +        break;
> +
> +      case USB_REQ_GET_STATUS:
> +        DEBUG ((DEBUG_INFO, "USB_REQ_GET_STATUS\n"));
> +        if (CtrlRequest->RequestType & USB_RT_TX_DIR_D_TO_H) {
> +          Status = UsbdGetStatus (mCtrlIoReq.IoInfo.Buffer, CtrlRequest->RequestType, CtrlRequest->Length, &(mCtrlIoReq.IoInfo.Length));
> +        } else {
> +          DEBUG ((DEBUG_INFO, "UsbdSetupHdlr: Invalid direction for USB_REQ_GET_STATUS request\n"));
> +        }
> +        break;
> +#ifdef SUPPORT_SUPER_SPEED
> +      case USB_REQ_CLEAR_FEATURE:
> +      case USB_REQ_SET_FEATURE:
> +      case USB_REQ_SET_DESCRIPTOR:
> +      case USB_REQ_GET_INTERFACE:
> +      case USB_REQ_SET_INTERFACE:
> +      case USB_REQ_SYNCH_FRAME:
> +#endif
> +      default:
> +         DEBUG ((DEBUG_INFO, "UsbdSetupHdlr: Unsupported Standard Request: 0x%x\n", CtrlRequest->Request));
> +          break;
> +    }
> +  } else { // This is not a Standard request, it specifies Class/Vendor handling
> +    //
> +    // Forward request to class driver
> +    //
> +    DEBUG ((DEBUG_INFO, "UsbdSetupHdlr: Class/Vendor Request\n"));
> +    if (mDrvObj.UsbdDevObj->SetupCallback != NULL) {
> +      mDrvObj.UsbdDevObj->SetupCallback (CtrlRequest, &(mCtrlIoReq.IoInfo));
> +    }
> +  }
> +
> +  DEBUG ((DEBUG_INFO, "dataLen=%x\n", mCtrlIoReq.IoInfo.Length));
> +  //
> +  // Transfer data according to request if necessary
> +  //
> +  if (mCtrlIoReq.IoInfo.Length> 0) {
> +    Status = UsbdEpTxData (mDrvObj.XdciDrvObj, &mCtrlIoReq);
> +    if (EFI_ERROR (Status)) {
> +      DEBUG ((DEBUG_INFO, "UsbdSetupHdlr: Failed to TX data\n"));
> +    }
> +  } else {
> +    //
> +    // If we are not responding with data, send control status
> +    //
> +    Status = UsbDeviceEp0TxStatus (mDrvObj.XdciDrvObj);
> +    if (EFI_ERROR (Status)) {
> +      DEBUG ((DEBUG_INFO, "UsbdSetupHdlr: Failed to Tx Ep0 Status\n"));
> +    }
> +  }
> +
> +  return Status;
> +}
> +
> +
> +/**
> +  Handles Connection done events. Sets the device address to zero.
> +
> +  @return EFI_SUCCESS if able to set the address, EFI_DEVICE_ERROR otherwise
> +
> +**/
> +EFI_STATUS
> +UsbdConnDoneHdlr (
> +  VOID
> +  )
> +{
> +  EFI_STATUS    Status = EFI_DEVICE_ERROR;
> +
> +  DEBUG ((DEBUG_INFO, "UsbdConnDoneHdlr()\n"));
> +
> +  //
> +  // reset device address to 0
> +  //
> +  Status = UsbDeviceSetAddress (mDrvObj.XdciDrvObj, 0x0);
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((DEBUG_INFO, "UsbdConnDoneHdlr() - Failed to set address in XDCI\n"));
> +  }
> +
> +  //
> +  // set the device state to attached/connected
> +  //
> +  mDrvObj.State = UsbDevStateAttached;
> +
> +  return Status;
> +}
> +
> +
> +/**
> +  Handles transmit/receive completion events. Directly handles
> +  control endpoint events and forwards class/vendor specific events
> +  to the class drivers.
> +
> +  @param   XferInfo   Pointer to Xfer structure
> +
> +  @return
> +
> +**/
> +VOID
> +UsbdXferDoneHdlr (
> +  IN EFI_USB_DEVICE_XFER_INFO    *XferInfo
> +  )
> +{
> +  //
> +  // If this is a non-control transfer complete, notify the class driver
> +  //
> +  if (XferInfo->EndpointNum > 0) {
> +    if (mDrvObj.UsbdDevObj->DataCallback != NULL) {
> +      mDrvObj.UsbdDevObj->DataCallback (XferInfo);
> +    }
> +  }
> +
> +  return;
> +}
> +
> +
> +/**
> +  Binds a USB class driver with this USB device driver core.
> +  After calling this routine, the driver is ready to begin
> +  USB processing.
> +
> +  @param  UsbdDevObj   Pointer to a usbd device object which contains
> +                       all relevant information for the class driver device
> +
> +  @return TRUE if binding was successful, FALSE otherwise
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +UsbDeviceBind (
> +  IN EFI_USB_DEVICE_MODE_PROTOCOL               *This,
> +  IN USB_DEVICE_OBJ                             *UsbdDevObj
> +  )
> +{
> +  EFI_STATUS  Status = EFI_SUCCESS;
> +
> +  //
> +  // allocate Tx Buffer
> +  //
> +  mCtrlIoReq.IoInfo.Buffer = AllocateZeroPool (USB_EPO_MAX_PKT_SIZE_ALL);
> +  if (mCtrlIoReq.IoInfo.Buffer != NULL) {
> +    mDrvObj.UsbdDevObj = UsbdDevObj;
> +    mDrvObj.ActiveConfigObj = NULL;
> +    mDrvObj.Address = 0;
> +    mDrvObj.State = UsbDevStateInit;
> +  } else {
> +    DEBUG ((DEBUG_INFO, "UsbDeviceBind() - Failed to allocate IO Buffer\n"));
> +    Status = EFI_DEVICE_ERROR;
> +  }
> +
> +  return Status;
> +}
> +
> +
> +/**
> +  Unbinds the USB class driver from this USB device driver core.
> +
> +  @return TRUE if successful, FALSE otherwise
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +UsbDeviceUnbind (
> +  IN EFI_USB_DEVICE_MODE_PROTOCOL               *This
> +  )
> +{
> +  mDrvObj.UsbdDevObj = NULL;
> +  mDrvObj.ActiveConfigObj = NULL;
> +  mDrvObj.Address = 0;
> +  mDrvObj.State = UsbDevStateOff;
> +  mDrvObj.XdciInitialized = FALSE;
> +
> +  //
> +  // release allocated Buffer data
> +  //
> +  if (mCtrlIoReq.IoInfo.Buffer) {
> +    FreePool (mCtrlIoReq.IoInfo.Buffer);
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +
> +/**
> +  Performs continual USB device event processing until a cancel
> +  event occurs
> +
> +  @param   TimeoutMs   Connection timeout in ms. If 0, waits forever.
> +  @return  TRUE if run executed normally, FALSE if error ocurred
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +UsbDeviceRun (
> +  IN EFI_USB_DEVICE_MODE_PROTOCOL               *This,
> +  IN UINT32                                     TimeoutMs
> +  )
> +{
> +  EFI_STATUS              Status = EFI_DEVICE_ERROR;
> +  USB_XDCI_DEV_CONTEXT    *XdciDevContext;
> +
> +  XdciDevContext = USBUSBD_CONTEXT_FROM_PROTOCOL (This);
> +
> +  //
> +  // can only run if XDCI is initialized
> +  //
> +  if ((mDrvObj.XdciInitialized == TRUE)) {
> +
> +    if ((mDrvObj.State == UsbDevStateConfigured) && (XdciDevContext->XdciPollTimer == NULL)) {
> +      Status = gBS->CreateEvent (
> +                      EVT_TIMER | EVT_NOTIFY_SIGNAL,
> +                      TPL_NOTIFY,
> +                      UsbdMonitorEvents,
> +                      XdciDevContext,
> +                      &XdciDevContext->XdciPollTimer
> +                      );
> +      if (!EFI_ERROR (Status)) {
> +        Status = gBS->SetTimer (XdciDevContext->XdciPollTimer, TimerPeriodic, EFI_TIMER_PERIOD_MILLISECONDS (20));
> +        DEBUG ((EFI_D_ERROR, "UsbDeviceRun Create Event\n"));
> +      }
> +    }
> +
> +    mXdciRun = TRUE; // set the run flag to active
> +    Status = EFI_SUCCESS;
> +
> +    //
> +    // start the Event processing loop
> +    //
> +    while (TRUE) {
> +      if (XdciDevContext->XdciPollTimer == NULL) {
> +        if (UsbDeviceIsrRoutine (mDrvObj.XdciDrvObj) != EFI_SUCCESS) {
> +          DEBUG ((DEBUG_INFO, "UsbDeviceRun() - Failed to execute event ISR\n"));
> +        }
> +      }
> +
> +      //
> +      // Check if a run cancel request exists, if so exit processing loop
> +      //
> +      if (mXdciRun == FALSE) {
> +        if (XdciDevContext->XdciPollTimer != NULL) {
> +          DEBUG ((EFI_D_ERROR, "UsbDeviceRun close Event\n"));
> +          gBS->SetTimer (XdciDevContext->XdciPollTimer, TimerCancel, 0);
> +          gBS->CloseEvent (XdciDevContext->XdciPollTimer);
> +          XdciDevContext->XdciPollTimer = NULL;
> +        }
> +        Status = EFI_SUCCESS;
> +        DEBUG ((DEBUG_INFO, "UsbDeviceRun() - processing was cancelled\n"));
> +        break;
> +      }
> +
> +      //
> +      // check for timeout
> +      //
> +      if (TimeoutMs == 0)
> +        return EFI_TIMEOUT;
> +      gBS->Stall (50);
> +      TimeoutMs--;
> +    }
> +  }
> +
> +  return Status;
> +}
> +
> +
> +/**
> +  Sets a flag to stop the running device processing loop
> +
> +  @return TRUE always
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +UsbDeviceStop (
> +  IN EFI_USB_DEVICE_MODE_PROTOCOL               *This
> +  )
> +{
> +  mXdciRun = FALSE; // set run flag to FALSE to stop processing
> +  return EFI_SUCCESS;
> +}
> +
> +
> +EFI_STATUS
> +EFIAPI
> +UsbDeviceInitXdci (
> +  IN EFI_USB_DEVICE_MODE_PROTOCOL               *This
> +  )
> +{
> +  EFI_STATUS            Status = EFI_DEVICE_ERROR;
> +  USB_XDCI_DEV_CONTEXT  *XdciDevContext;
> +
> +  XdciDevContext = USBUSBD_CONTEXT_FROM_PROTOCOL (This);
> +
> +  PlatformSpecificInit ();
> +
> +  if (mDrvObj.XdciInitialized == FALSE) {
> +    if (XdciDevContext->XdciMmioBarAddr != 0) {
> +
> +      //
> +      // Initialize device controller driver
> +      //
> +      DEBUG ((DEBUG_INFO, "UsbDeviceInitXdci() - Initializing Controller...\n"));
> +
> +      //
> +      // Initialize the device controller interface
> +      //
> +      if (UsbdInit ((UINT32)XdciDevContext->XdciMmioBarAddr, &mDrvObj.XdciDrvObj) == EFI_SUCCESS) {
> +
> +        //
> +        // Setup callbacks
> +        //
> +        if (UsbdRegisterCallbacks (mDrvObj.XdciDrvObj) == EFI_SUCCESS) {
> +
> +          mDrvObj.XdciInitialized = TRUE;
> +          Status = EFI_SUCCESS;
> +
> +          DEBUG ((DEBUG_INFO, "UsbDeviceInitXdci() - Controller initialization complete\n"));
> +        } else {
> +          DEBUG ((DEBUG_INFO, "UsbDeviceInitXdci() - Failed to register UDCI callbacks\n"));
> +        }
> +      } else {
> +        DEBUG ((DEBUG_INFO, "UsbDeviceInitXdci() - Failed to initialize UDCI\n"));
> +      }
> +    } else {
> +      DEBUG ((DEBUG_INFO, "UsbDeviceInitXdci() - XDCI MMIO BAR not set\n"));
> +    }
> +  } else {
> +    DEBUG ((DEBUG_INFO, "UsbDeviceInitXdci() - XDCI already initialized\n"));
> +    Status = EFI_ALREADY_STARTED;
> +  }
> +
> +  return Status;
> +}
> +
> +
> +EFI_STATUS
> +EFIAPI
> +UsbDeviceConnect(
> +  IN EFI_USB_DEVICE_MODE_PROTOCOL               *This
> +  )
> +{
> +  EFI_STATUS  Status = EFI_DEVICE_ERROR;
> +
> +  DEBUG ((DEBUG_INFO,  "UsbDeviceConnect \n"));
> +  if (UsbXdciDeviceConnect (mDrvObj.XdciDrvObj) == EFI_SUCCESS) {
> +    Status = EFI_SUCCESS;
> +  }
> +  return Status;
> +}
> +
> +
> +EFI_STATUS
> +EFIAPI
> +UsbDeviceDisConnect (
> +  IN EFI_USB_DEVICE_MODE_PROTOCOL               *This
> +  )
> +{
> +  EFI_STATUS  Status = EFI_DEVICE_ERROR;
> +
> +  DEBUG ((DEBUG_INFO,  "UsbDeviceDisConnect \n"));
> +  if (UsbDeviceDisconnect (mDrvObj.XdciDrvObj) == EFI_SUCCESS) {
> +    mDrvObj.State = UsbDevStateInit;
> +    Status = EFI_SUCCESS;
> +  }
> +
> +  XhciSwitchSwid(FALSE);
> +  return Status;
> +}
> +
> +
> +EFI_STATUS
> +EFIAPI
> +UsbDeviceEpTxData(
> +  IN EFI_USB_DEVICE_MODE_PROTOCOL               *This,
> +  IN USB_DEVICE_IO_REQ                          *IoRequest
> +  )
> +{
> +  EFI_STATUS  Status;
> +
> +  Status = UsbdEpTxData (mDrvObj.XdciDrvObj, IoRequest);
> +  return Status;
> +}
> +
> +
> +EFI_STATUS
> +EFIAPI
> +UsbDeviceEpRxData(
> +  IN EFI_USB_DEVICE_MODE_PROTOCOL               *This,
> +  IN USB_DEVICE_IO_REQ                          *IoRequest
> +  )
> +{
> +  EFI_STATUS  Status;
> +
> +  Status = UsbdEpRxData (mDrvObj.XdciDrvObj, IoRequest);
> +  return Status;
> +}
> +
> +
> +//
> +// The Runtime UsbDeviceMode Protocol instance produced by this driver
> +//
> +EFI_USB_DEVICE_MODE_PROTOCOL  mUsbDeviceModeProtocol = {
> +  UsbDeviceInitXdci,
> +  UsbDeviceConnect,
> +  UsbDeviceDisConnect,
> +  UsbDeviceEpTxData,
> +  UsbDeviceEpRxData,
> +  UsbDeviceBind,
> +  UsbDeviceUnbind,
> +  UsbDeviceRun,
> +  UsbDeviceStop
> +};
> +
> diff --git a/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbDeviceMode.h b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbDeviceMode.h
> new file mode 100644
> index 0000000000..ac9c89b2f1
> --- /dev/null
> +++ b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbDeviceMode.h
> @@ -0,0 +1,39 @@
> +/** @file
> +  Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR>
> +
> +  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.
> +
> +**/
> +
> +#ifndef _USB_DEVICE_MODE_DXE_H_
> +#define _USB_DEVICE_MODE_DXE_H_
> +
> +#include <Uefi.h>
> +#include <PiDxe.h>
> +#include <Library/DebugLib.h>
> +#include <Library/UefiDriverEntryPoint.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Library/UsbDeviceLib.h>
> +#include <Protocol/UsbDeviceModeProtocol.h>
> +#include "XdciCommon.h"
> +#include "XdciDevice.h"
> +
> +
> +///
> +/// Function declaration
> +///
> +EFI_STATUS
> +UsbdSetupHdlr (
> +  IN EFI_USB_DEVICE_REQUEST    *CtrlRequest
> +  );
> +
> +extern EFI_USB_DEVICE_MODE_PROTOCOL  mUsbDeviceModeProtocol;
> +
> +#endif
> +
> diff --git a/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbFuncIo.c b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbFuncIo.c
> new file mode 100644
> index 0000000000..a4138328fd
> --- /dev/null
> +++ b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbFuncIo.c
> @@ -0,0 +1,2221 @@
> +/** @file
> +  Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR>
> +
> +  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.
> +
> +**/
> +
> +#include "UsbDeviceDxe.h"
> +
> +//
> +// 16 bytes in a guid x 2 characters per byte, 4 chars for dashes and a NUL
> +//
> +#define CHARS_IN_GUID (sizeof(GUID) * 2 + 4 + 1)
> +
> +//
> +// Strings that get sent with the USB Connection
> +//
> +static CHAR16 mUsbFnDxeMfgString[] = L"Intel Corporation";
> +static CHAR16 mUsbFnDxeProductString[] = L"Broxton";
> +static CHAR16 mUsbFnDxeSerialNumber[] = L"INT123456";
> +
> +//
> +// Duplicated from MiscSystemManufacturerData.c Some parts of it will
> +// replaced with device-specific unique values.
> +//
> +static GUID mSmBiosUniqueGuid = {
> +        0x5e24fe9c, 0xc8d0, 0x45bd, 0xa7, 0x9f, 0x54, 0xea, 0x5f, 0xbd, 0x3d, 0x97
> +    };
> +
> +EFI_USBFN_IO_PROTOCOL         mUsbFunIoProtocol = {
> +  EFI_USBFN_IO_PROTOCOL_REVISION,
> +  DetectPort,
> +  ConfigureEnableEndpoints,
> +  GetEndpointMaxPacketSize,
> +  GetDeviceInfo,
> +  GetVendorIdProductId,
> +  AbortTransfer,
> +  GetEndpointStallState,
> +  SetEndpointStallState,
> +  EventHandler,
> +  Transfer,
> +  GetMaxTransferSize,
> +  AllocateTransferBuffer,
> +  FreeTransferBuffer,
> +  StartController,
> +  StopController,
> +  SetEndpointPolicy,
> +  GetEndpointPolicy
> +};
> +
> +
> +EFI_STATUS
> +PrintEventBuffer(
> +  IN  EFI_USBFN_IO_PROTOCOL  *This
> +  )
> +{
> +  UINT32                          EventCount;
> +  USB_XDCI_DEV_CONTEXT            *UsbFuncIoDevPtr;
> +  XDCI_CORE_HANDLE                *XdciCorePtr;
> +  USB_DEV_CORE                    *UsbDeviceCorePtr;
> +  UINT32                          Index;
> +  UINT32                          *DbBufPtr;
> +
> +  UsbFuncIoDevPtr = USBFUIO_CONTEXT_FROM_PROTOCOL (This);
> +
> +  UsbDeviceCorePtr = UsbFuncIoDevPtr->DrvCore;
> +  XdciCorePtr = UsbDeviceCorePtr->ControllerHandle;
> +
> +  EventCount = UsbRegRead ((UINT32)UsbFuncIoDevPtr->XdciMmioBarAddr, DWC_XDCI_EVNTCOUNT_REG(0));
> +
> +  DbBufPtr = (UINT32*)(UINTN)XdciCorePtr->CurrentEventBuffer;
> +  XdciCorePtr = UsbDeviceCorePtr->ControllerHandle;
> +  DEBUG ((USB_FUIO_DEBUG_EVENT_D, "FUEV:: XdciCorePtr->AlignedEventBuffers 0x%08x\n", (UINTN)XdciCorePtr->AlignedEventBuffers));
> +  DEBUG ((USB_FUIO_DEBUG_EVENT_D, "FUEV:: DUMP BUF_S\n"));
> +  for (Index = 0; Index < ((EventCount / 4) + 1); Index++) {
> +    DEBUG ((USB_FUIO_DEBUG_EVENT_D, "0x%08x\n", DbBufPtr[Index]));
> +  }
> +  DEBUG ((USB_FUIO_DEBUG_EVENT_D, "FUEV:: DUMP BUF_E\n"));
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +Debug End
> +**/
> +
> +/**
> +  Returns information about what type of device was attached.
> +
> +  @param[in]  This               A pointer to the EFI_USBFN_IO_PROTOCOL instance.
> +  @param[out] PortType           Returns the USB port type.
> +
> +
> +  @retval EFI_SUCCESS            The operation completed successfully.
> +  @retval EFI_INVALID_PARAMETER  A parameter is invalid.
> +  @retval EFI_DEVICE_ERROR       The physical device reported an error.
> +  @retval EFI_NOT_READY          The physical device is busy or not ready to
> +                                 process this request or the device is not
> +                                 attached to the host.
> +
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +DetectPort (
> +  IN  EFI_USBFN_IO_PROTOCOL  *This,
> +  OUT EFI_USBFN_PORT_TYPE    *PortType
> +  )
> +{
> +  USB_XDCI_DEV_CONTEXT  *UsbFuncIoDevPtr;
> +  EFI_STATUS            Status;
> +  UINT8                 Value8;
> +
> +  DEBUG ((USB_FUIO_DEBUG_INFO, "DetectPort - Entry\n"));
> +
> +  UsbFuncIoDevPtr = USBFUIO_CONTEXT_FROM_PROTOCOL (This);
> +
> +  //
> +  // USBSRCDETRSLT Bit[5:2]
> +  // Result of USB HW Source Detection algorithm
> +  // Power-Domain: VRTC
> +  // Result of USB HW Source Detection algorithm :
> +  // 0000 = Not determined
> +  // 0001 = SDP Attached
> +  // 0010 = DCP Attached
> +  // 0011 = CDP Attached
> +  // 0100 = ACA Attached
> +  // 0101 = SE1 Attached
> +  // 0110 = MHL Attached
> +  // 0111 = Floating D+/D- Attached
> +  // 1000 = Other Attached
> +  // 1001 = DCP detected by ext. USB PHY
> +  // 1010-1111 = Rsvd
> +  // Reset: 0000B
> +  //
> +
> +  Value8 =PmicRead8 (0x5E, 0X29);
> +  if ((Value8 & 0x03) != 0x02) {
> +    *PortType = EfiUsbUnknownPort;
> +    Status = EFI_NOT_READY;
> +    goto out;
> +  }
> +
> +  Value8 = Value8 >> 2 & 0x0f;
> +  Status = EFI_SUCCESS;
> +  switch (Value8) {
> +    case 1:
> +      *PortType = EfiUsbStandardDownstreamPort;
> +      break;
> +    case 2:
> +      *PortType = EfiUsbDedicatedChargingPort;
> +      break;
> +    case 3:
> +      *PortType = EfiUsbChargingDownstreamPort;
> +      break;
> +
> +    case 4:
> +    case 5:
> +    case 6:
> +    case 7:
> +    case 8:
> +    case 9:
> +      *PortType = EfiUsbUnknownPort;
> +      break;
> +    case 0:
> +    case 10:
> +    case 11:
> +    case 12:
> +    case 13:
> +    case 14:
> +    case 15:
> +      *PortType = EfiUsbUnknownPort;
> +      Status = EFI_NOT_READY;
> +     break;
> +  }
> +
> +out:
> +  DEBUG ((USB_FUIO_DEBUG_INFO, "DetectPort - Exit\n"));
> +  return EFI_SUCCESS;
> +}
> +
> +
> +/**
> +  The AllocateTransferBuffer function allocates a memory region of Size bytes
> +  and returns the address of the allocated memory that satisfies underlying
> +  controller requirements in the location referenced by Buffer.
> +
> +  @param[in] This               A pointer to the EFI_USBFN_IO_PROTOCOL instance.
> +  @param[in] Size               The number of bytes to allocate for the transfer
> +                                Buffer.
> +  @param[in] Buffer             A pointer to a pointer to the allocated Buffer
> +                                if the call succeeds; undefined otherwise.
> +
> +  @retval EFI_SUCCESS           The operation completed successfully.
> +  @retval EFI_INVALID_PARAMETER A parameter is invalid.
> +  @retval The requested transfer Buffer could not be allocated.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +AllocateTransferBuffer (
> +  IN EFI_USBFN_IO_PROTOCOL    *This,
> +  IN UINTN                    Size,
> +  OUT VOID                    **Buffer
> +  )
> +{
> +  EFI_STATUS            Status;
> +  USB_XDCI_DEV_CONTEXT  *UsbFuncIoDevPtr;
> +  VOID                  *AllocateBufferPtr;
> +  USB_MEM_NODE          *NodePtr;
> +
> +  DEBUG ((USB_FUIO_DEBUG_INFO, "AllocateTransferBuffer - Entry\n"));
> +
> +  UsbFuncIoDevPtr = USBFUIO_CONTEXT_FROM_PROTOCOL (This);
> +
> +  if (Size == 0) {
> +    Status = EFI_INVALID_PARAMETER;
> +    goto ErrorExit;
> +  }
> +
> +  AllocateBufferPtr = AllocateZeroPool (Size);
> +
> +  if (AllocateBufferPtr == NULL) {
> +    Status = EFI_OUT_OF_RESOURCES;
> +    goto ErrorExit;
> +  }
> +
> +  //
> +  // Create new node
> +  //
> +  Status = InsertNewNodeToHead (This, &NodePtr);
> +  if (EFI_ERROR (Status)) {
> +    Status = EFI_OUT_OF_RESOURCES;
> +    goto ErrorExit;
> +  }
> +
> +  NodePtr->Size = Size;
> +  NodePtr->AllocatePtr = AllocateBufferPtr;
> +
> +  *Buffer = AllocateBufferPtr;
> +
> +  DEBUG ((USB_FUIO_DEBUG_INFO, "AllocateTransferBuffer addr 0x%08x\n", AllocateBufferPtr));
> +  DEBUG ((USB_FUIO_DEBUG_INFO, "AllocateTransferBuffer - Exit\n"));
> +  return EFI_SUCCESS;
> +
> +ErrorExit:
> +
> +  DEBUG ((USB_FUIO_DEBUG_ERROR, "AllocateTransferBuffer - ERRROR %r\n",Status));
> +  return Status;
> +}
> +
> +
> +/**
> +  Deallocates the memory allocated for the transfer Buffer by
> +  AllocateTransferBuffer function.
> +
> +  @param[in] This               A pointer to the EFI_USBFN_IO_PROTOCOL instance.
> +  @param[in] Buffer             Buffer Pointer to the transfer Buffer
> +                                to deallocate.
> +  @retval EFI_SUCCESS           The function returned successfully.
> +  @retval EFI_INVALID_PARAMETER A parameter is invalid.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +FreeTransferBuffer (
> +  IN EFI_USBFN_IO_PROTOCOL    *This,
> +  IN VOID                     *Buffer
> +  )
> +{
> +  EFI_STATUS            Status;
> +  USB_XDCI_DEV_CONTEXT  *UsbFuncIoDevPtr;
> +
> +  UsbFuncIoDevPtr = USBFUIO_CONTEXT_FROM_PROTOCOL (This);
> +  DEBUG ((USB_FUIO_DEBUG_LOAD, "FreeTransferBuffer - Entry\n"));
> +
> +  Status = RemoveNode (This, Buffer);
> +  if (EFI_ERROR(Status)) {
> +    DEBUG ((USB_FUIO_DEBUG_LOAD, "FreeTransferBuffer - ERROR\n"));
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  DEBUG ((USB_FUIO_DEBUG_LOAD, "FreeTransferBuffer - Exit\n"));
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  Configure endpoints Based on supplied device and configuration descriptors.
> +
> +  @param[in] This               A pointer to the EFI_USBFN_IO_PROTOCOL instance.
> +  @param[in] DeviceInfo         A pointer to EFI_USBFN_DEVICE_INFO instance.
> +
> +  @retval EFI_SUCCESS           The function returned successfully.
> +  @retval EFI_INVALID_PARAMETER A parameter is invalid.
> +  @retval EFI_DEVICE_ERROR      The physical device reported an error.
> +  @retval EFI_NOT_READY         The physical device is busy or not ready to
> +                                process this request.
> +  @retval EFI_OUT_OF_RESOURCES  The request could not be completed due to
> +                                lack of resources.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +ConfigureEnableEndpoints (
> +  IN EFI_USBFN_IO_PROTOCOL         *This,
> +  IN EFI_USB_DEVICE_INFO           *DeviceInfo
> +  )
> +{
> +  EFI_STATUS                        Status;
> +  USB_XDCI_DEV_CONTEXT              *UsbFuncIoDevPtr;
> +
> +  UsbFuncIoDevPtr = USBFUIO_CONTEXT_FROM_PROTOCOL (This);
> +  Status = EFI_SUCCESS;
> +
> +  DEBUG ((USB_FUIO_DEBUG_LOAD, "ConfigureEnableEndpoints - Entry\n"));
> +  //
> +  //Assuming that the hardware has already been initialized,
> +  //this function configures the endpoints using supplied
> +  //DeviceInfo, activates the port, and starts receiving USB events
> +  //
> +  Status = EFI_SUCCESS;
> +  if (DeviceInfo == NULL) {
> +    Status = EFI_INVALID_PARAMETER;
> +    goto FUNC_EXIT;
> +  }
> +
> +  UsbFuncIoDevPtr->DevInfoPtr->DeviceDescriptor = DeviceInfo->DeviceDescriptor;
> +
> +  //
> +  // Set Configure table
> +  //
> +  if (DeviceInfo->DeviceDescriptor->NumConfigurations > 1) {
> +    DEBUG ((EFI_D_ERROR, "!!!Error ConfigNum over '1' %d\n", DeviceInfo->DeviceDescriptor->NumConfigurations));
> +  }
> +  UsbFuncIoDevPtr->IndexPtrConfig.ConfigDescriptor = DeviceInfo->ConfigInfoTable[0]->ConfigDescriptor;
> +  UsbFuncIoDevPtr->IndexPtrConfig.InterfaceInfoTable[0] = DeviceInfo->ConfigInfoTable[0]->InterfaceInfoTable[0];
> +
> +  //
> +  // Set Interface
> +  //
> +  if (DeviceInfo->ConfigInfoTable[0]->ConfigDescriptor->NumInterfaces > 1) {
> +    DEBUG ((EFI_D_ERROR, "!!!Error NumInterfaces[0] over '1' %d\n", DeviceInfo->ConfigInfoTable[0]->ConfigDescriptor->NumInterfaces));
> +  }
> +  UsbFuncIoDevPtr->IndexPtrInteface.InterfaceDescriptor = DeviceInfo->ConfigInfoTable[0]->InterfaceInfoTable[0]->InterfaceDescriptor;
> +
> +  //
> +  // Set Endpoint
> +  //
> +  if (UsbFuncIoDevPtr->IndexPtrInteface.InterfaceDescriptor->NumEndpoints > 2) {
> +    DEBUG ((EFI_D_ERROR, "!!!Error NumEndPoint[0] over '2' %d\n", UsbFuncIoDevPtr->IndexPtrInteface.InterfaceDescriptor->NumEndpoints));
> +  }
> +
> +  UsbFuncIoDevPtr->IndexPtrInEp.EndpointCompDesc = NULL;
> +  UsbFuncIoDevPtr->IndexPtrOutEp.EndpointCompDesc = NULL;
> +
> +  if ((DeviceInfo->ConfigInfoTable[0]->InterfaceInfoTable[0]->EndpointDescriptorTable[0]->EndpointAddress & USB_ENDPOINT_DIR_IN) != 0) {
> +    UsbFuncIoDevPtr->IndexPtrInEp.EndpointDesc = DeviceInfo->ConfigInfoTable[0]->InterfaceInfoTable[0]->EndpointDescriptorTable[0];
> +    UsbFuncIoDevPtr->IndexPtrOutEp.EndpointDesc = DeviceInfo->ConfigInfoTable[0]->InterfaceInfoTable[0]->EndpointDescriptorTable[1];
> +  } else {
> +    UsbFuncIoDevPtr->IndexPtrInEp.EndpointDesc = DeviceInfo->ConfigInfoTable[0]->InterfaceInfoTable[0]->EndpointDescriptorTable[1];
> +    UsbFuncIoDevPtr->IndexPtrOutEp.EndpointDesc = DeviceInfo->ConfigInfoTable[0]->InterfaceInfoTable[0]->EndpointDescriptorTable[0];
> +  }
> +
> +  DEBUG ((USB_FUIO_DEBUG_LOAD, " In Ep Num 0x%02x\n", UsbFuncIoDevPtr->IndexPtrInEp.EndpointDesc->EndpointAddress));
> +
> +  DEBUG ((USB_FUIO_DEBUG_LOAD, " Out Ep Num 0x%02x\n", UsbFuncIoDevPtr->IndexPtrOutEp.EndpointDesc->EndpointAddress));
> +
> +FUNC_EXIT:
> +  DEBUG ((USB_FUIO_DEBUG_LOAD, "ConfigureEnableEndpoints - exit %r\n", Status));
> +  return Status;
> +}
> +
> +/**
> +  Returns the maximum packet size of the specified endpoint type for
> +  the supplied bus Speed.
> +
> +  @param[in] This               A pointer to the EFI_USBFN_IO_PROTOCOL instance.
> +  @param[in] EndpointType       Endpoint type as defined as EFI_USB_ENDPOINT_TYPE.
> +  @param[in] BusSpeed           Bus Speed as defined as EFI_USB_BUS_SPEED.
> +  @param[in] MaxPacketSize      The maximum packet size, in bytes,
> +                                of the specified endpoint type.
> +
> +  @retval EFI_SUCCESS           The function returned successfully.
> +  @retval EFI_INVALID_PARAMETER A parameter is invalid.
> +  @retval EFI_DEVICE_ERROR      The physical device reported an error.
> +  @retval EFI_NOT_READY         The physical device is busy or not ready to
> +                                process this request.
> +**/
> +EFI_STATUS
> +EFIAPI
> +GetEndpointMaxPacketSize (
> +  IN EFI_USBFN_IO_PROTOCOL      *This,
> +  IN EFI_USB_ENDPOINT_TYPE      EndpointType,
> +  IN EFI_USB_BUS_SPEED          BusSpeed,
> +  OUT UINT16                    *MaxPacketSize
> +  )
> +{
> +  EFI_STATUS                        Status;
> +  USB_XDCI_DEV_CONTEXT              *UsbFuncIoDevPtr;
> +  USB_DEV_CORE                      *DevCorePtr;
> +  XDCI_CORE_HANDLE                  *XdciCorePtr;
> +
> +  UsbFuncIoDevPtr = USBFUIO_CONTEXT_FROM_PROTOCOL (This);
> +  DevCorePtr = UsbFuncIoDevPtr->DrvCore;
> +  XdciCorePtr = DevCorePtr->ControllerHandle;
> +  Status = EFI_SUCCESS;
> +
> +  DEBUG ((USB_FUIO_DEBUG_LOAD, "GetEndpointMaxPacketSize - Entry\n"));
> +
> +  switch (EndpointType) {
> +    case UsbEndpointControl:
> +#ifdef SUPPORT_SUPER_SPEED
> +      *MaxPacketSize = USB_EP0_MAX_PKT_SIZE_SS; // Default to super Speed
> +#else
> +      *MaxPacketSize = USB_EP0_MAX_PKT_SIZE_HS; // Default to high Speed
> +#endif
> +      break;
> +
> +    case UsbEndpointBulk:
> +#ifdef SUPPORT_SUPER_SPEED
> +      *MaxPacketSize = USB_BULK_EP_PKT_SIZE_SS; // Default to super Speed
> +#else
> +      *MaxPacketSize = USB_BULK_EP_PKT_SIZE_HS; // Default to high Speed
> +#endif
> +      break;
> +
> +    case UsbEndpointInterrupt:
> +      *MaxPacketSize = 1;
> +      break;
> +
> +    case UsbEndpointIsochronous:
> +    default:
> +      Status = EFI_DEVICE_ERROR;
> +      break;
> +  }
> +
> +  DEBUG ((USB_FUIO_DEBUG_LOAD, "GetEndpointMaxPacketSize - Exit %r\n", Status));
> +  return Status;
> +}
> +
> +
> +/**
> +  Returns the maximum supported transfer size.
> +
> +  @param[in] This               A pointer to the EFI_USBFN_IO_PROTOCOL instance.
> +  @param[in] MaxTransferSize    The maximum supported transfer size, in bytes.
> +
> +  @retval EFI_SUCCESS           The function returned successfully.
> +  @retval EFI_INVALID_PARAMETER A parameter is invalid.
> +  @retval EFI_DEVICE_ERROR      The physical device reported an error.
> +  @retval EFI_NOT_READY         The physical device is busy or not ready to
> +                                process this request.
> +**/
> +EFI_STATUS
> +EFIAPI
> +GetMaxTransferSize (
> +  IN EFI_USBFN_IO_PROTOCOL     *This,
> +  OUT UINTN                    *MaxTransferSize
> +  )
> +{
> +  //
> +  // Need to check, Make max transfer package to 8MB
> +  //
> +  *MaxTransferSize = MAX_TRANSFER_PACKET;
> +  return EFI_SUCCESS;
> +}
> +
> +
> +/**
> +  This function returns the unique device ID of the device--this matches
> +  what is populated in the SMBIOS table.
> +
> +  @param[in/out] BufferSize     On input, the size of the Buffer in bytes.
> +                                On output, the amount of data returned in Buffer
> +                                in bytes.
> +
> +  @param[out] Buffer            A pointer to a Buffer to return the requested
> +                                information as a Unicode string. What string are
> +                                we talking about
> +
> +  @retval EFI_SUCCESS           The function returned successfully.
> +  @retval EFI_BUFFER_TOO_SMALL  A parameter is invalid.
> +
> +**/
> +STATIC
> +EFI_STATUS
> +EFIAPI
> +GetDeviceSerialNumber (
> +    IN OUT UINTN *BufferSize,
> +    OUT VOID *Buffer OPTIONAL
> +  )
> +{
> +    EFI_STATUS Status = EFI_SUCCESS;
> +    CHAR16 UuidString[CHARS_IN_GUID];
> +    UINTN CharsCopied;
> +
> +    DEBUG ((USB_FUIO_DEBUG_LOAD, "+GetDeviceSerialNumber\n"));
> +    //
> +    // check bounds
> +    //
> +    if (*BufferSize < sizeof(UuidString)) {
> +        Status = EFI_BUFFER_TOO_SMALL;
> +        *BufferSize = 0;
> +        goto Error;
> +    }
> +
> +    //
> +    // The rest of mSmBiosUniqueGuid will be same. Note that we cannot
> +    // read the SMBIOS table directly, as it might not be ready by the time we
> +    // are to read it. The population of the data from the eMMC is ready
> +    // by the time we are here.
> +    //
> +
> +    //
> +    // Print to to a string, and copy it off
> +    //
> +    CharsCopied = UnicodeSPrint(UuidString, sizeof(UuidString), L"%g", &mSmBiosUniqueGuid);
> +    if (CharsCopied != (CHARS_IN_GUID - 1))
> +    {
> +        Status = EFI_BUFFER_TOO_SMALL;
> +        *BufferSize = 0;
> +        goto Error;
> +    }
> +    CopyMem(Buffer, UuidString, sizeof(UuidString));
> +    *BufferSize = sizeof(UuidString);
> +
> +Error:
> +
> +    DEBUG ((USB_FUIO_DEBUG_LOAD, "-GetDeviceSerialNumber, Status = 0x%08x\r\n", Status));
> +
> +    return Status;
> +}
> +
> +
> +/**
> +  Returns device specific information Based on the supplied identifier as
> +  a Unicode string
> +
> +  @param[in] This               A pointer to the EFI_USBFN_IO_PROTOCOL instance.
> +  @param[in] Id                 Requested information id.
> +  @param[in] BufferSize         On input, the size of the Buffer in bytes.
> +                                On output, the amount of data returned in Buffer
> +                                in bytes.
> +  @param[in] Buffer             A pointer to a Buffer to return the requested
> +                                information as a Unicode string. What string are
> +                                we talking about
> +
> +  @retval EFI_SUCCESS           The function returned successfully.
> +  @retval EFI_INVALID_PARAMETER A parameter is invalid.
> +  @retval EFI_DEVICE_ERROR      The physical device reported an error.
> +  @retval EFI_NOT_READY         The physical device is busy or not ready to
> +                                process this request.
> +**/
> +EFI_STATUS
> +EFIAPI
> +GetDeviceInfo (
> +  IN EFI_USBFN_IO_PROTOCOL      *This,
> +  IN EFI_USBFN_DEVICE_INFO_ID   Id,
> +  IN OUT UINTN                  *BufferSize,
> +  OUT VOID                      *Buffer OPTIONAL
> +  )
> +{
> +  EFI_STATUS                    Status;
> +  USB_XDCI_DEV_CONTEXT          *UsbFuncIoDevPtr;
> +
> +  UsbFuncIoDevPtr = USBFUIO_CONTEXT_FROM_PROTOCOL (This);
> +  Status = EFI_SUCCESS;
> +
> +  DEBUG ((USB_FUIO_DEBUG_LOAD, "GetDeviceInfo - Entry\n"));
> +
> +  if ((BufferSize == 0) || (Buffer == NULL)) {
> +    Status = EFI_INVALID_PARAMETER;
> +    goto FUN_EXIT;
> +  }
> +
> +  switch (Id) {
> +
> +    //
> +    // FIXME: Get real serial number of board
> +    //
> +    case EfiUsbDeviceInfoSerialNumber:
> +        if (*BufferSize < sizeof(mUsbFnDxeSerialNumber)) {
> +            Status = EFI_BUFFER_TOO_SMALL;
> +            *BufferSize = 0;
> +            goto FUN_EXIT;
> +        }
> +        CopyMem(Buffer, mUsbFnDxeSerialNumber, sizeof(mUsbFnDxeSerialNumber));
> +        *BufferSize = sizeof(mUsbFnDxeSerialNumber);
> +        break;
> +
> +    case EfiUsbDeviceInfoManufacturerName:
> +        if (*BufferSize < sizeof(mUsbFnDxeMfgString)) {
> +            Status = EFI_BUFFER_TOO_SMALL;
> +            *BufferSize = 0;
> +            goto FUN_EXIT;
> +        }
> +        CopyMem(Buffer, mUsbFnDxeMfgString, sizeof(mUsbFnDxeMfgString));
> +        *BufferSize = sizeof(mUsbFnDxeMfgString);
> +        break;
> +
> +    case EfiUsbDeviceInfoProductName:
> +        if (*BufferSize < sizeof(mUsbFnDxeProductString)) {
> +            Status = EFI_BUFFER_TOO_SMALL;
> +            *BufferSize = 0;
> +            goto FUN_EXIT;
> +        }
> +        CopyMem(Buffer, mUsbFnDxeProductString, sizeof(mUsbFnDxeProductString));
> +        *BufferSize = sizeof(mUsbFnDxeProductString);
> +        break;
> +
> +    case EfiUsbDeviceInfoUnknown:
> +    default:
> +      Status = EFI_UNSUPPORTED;
> +      *BufferSize = 0;
> +      DEBUG ((USB_FUIO_DEBUG_ERROR, "Unknown ID %d encountered.\r\n", Id));
> +      break;
> +  }
> +
> +FUN_EXIT:
> +  DEBUG ((USB_FUIO_DEBUG_LOAD, "UsbSetconfigure - ConfigDescriptor addr 0x%08x \n", (UINTN)UsbFuncIoDevPtr->IndexPtrConfig.ConfigDescriptor));
> +  DEBUG ((USB_FUIO_DEBUG_LOAD, "GetDeviceInfo - Exit %r\n", Status));
> +  return Status;
> +}
> +
> +
> +/**
> +  Returns vendor-id and product-id of the device.
> +
> +  @param[in]  This              A pointer to the EFI_USBFN_IO_PROTOCOL instance.
> +  @param[out] Vid               Returned vendor-id of the device.
> +  @param[out] Pid               Returned product-id of the device.
> +
> +  @retval EFI_SUCCESS           The function returned successfully.
> +  @retval EFI_INVALID_PARAMETER A parameter is invalid.
> +  @retval EFI_NOT_FOUND         Unable to return vid or pid.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +GetVendorIdProductId (
> +  IN EFI_USBFN_IO_PROTOCOL      *This,
> +  OUT UINT16                    *Vid,
> +  OUT UINT16                    *Pid
> +  )
> +{
> +  USB_XDCI_DEV_CONTEXT              *UsbFuncIoDevPtr;
> +
> +  UsbFuncIoDevPtr = USBFUIO_CONTEXT_FROM_PROTOCOL (This);
> +  //
> +  //   *Vid = 0x8086
> +  //   *Pid = 0x0A65
> +  //
> +  *Vid = UsbFuncIoDevPtr->VendorId;
> +  *Pid = UsbFuncIoDevPtr->DeviceId;
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  Aborts transfer on the specified endpoint.
> +
> +  @param[in]  This              A pointer to the EFI_USBFN_IO_PROTOCOL instance.
> +  @param[in]  EndpointIndex     Indicates the endpoint on which the ongoing
> +                                transfer needs to be canceled.
> +  @param[in]  Direction         Direction of the endpoint.
> +
> +
> +  @retval EFI_SUCCESS           The function returned successfully.
> +  @retval EFI_INVALID_PARAMETER A parameter is invalid.
> +  @retval EFI_DEVICE_ERROR      The physical device reported an error.
> +  @retval EFI_NOT_READY         The physical device is busy or not ready to
> +                                process this request.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +AbortTransfer (
> +  IN EFI_USBFN_IO_PROTOCOL        *This,
> +  IN UINT8                        EndpointIndex,
> +  IN EFI_USBFN_ENDPOINT_DIRECTION Direction
> +  )
> +{
> +  USB_XDCI_DEV_CONTEXT              *UsbFuncIoDevPtr;
> +  XDCI_CORE_HANDLE                  *XdciCorePtr;
> +  USB_DEV_CORE                      *UsbDeviceCorePtr;
> +  USB_EP_INFO                       EpInfo;
> +  EFI_STATUS                        Status;
> +
> +  DEBUG ((USB_FUIO_DEBUG_LOAD, "FU:AbortTransfer - Entry\n"));
> +  UsbFuncIoDevPtr = USBFUIO_CONTEXT_FROM_PROTOCOL (This);
> +  UsbDeviceCorePtr = UsbFuncIoDevPtr->DrvCore;
> +  XdciCorePtr = UsbDeviceCorePtr->ControllerHandle;
> +  Status = EFI_SUCCESS;
> +
> +  if (UsbFuncIoDevPtr->DevResetFlag == TRUE) {
> +    return Status;
> +  }
> +
> +  EpInfo.EpNum = EndpointIndex;
> +  EpInfo.EpDir = Direction? UsbEpDirIn : UsbEpDirOut;
> +
> +  Status = UsbDeviceEpCancelTransfer (UsbFuncIoDevPtr->DrvCore, &EpInfo);
> +
> +  DEBUG ((USB_FUIO_DEBUG_LOAD, "FU:AbortTransfer - Exit %r\n", Status));
> +  return Status;
> +}
> +
> +/**
> +  Returns the stall state on the specified endpoint.
> +
> +  @param[in]  This              A pointer to the EFI_USBFN_IO_PROTOCOL instance.
> +  @param[in]  EndpointIndex     Indicates the endpoint on which the ongoing
> +                                transfer needs to be canceled.
> +  @param[in]  Direction         Direction of the endpoint.
> +  @param[in]  State             Boolean, true value indicates that the endpoint
> +                                is in a stalled state, false otherwise.
> +
> +  @retval EFI_SUCCESS           The function returned successfully.
> +  @retval EFI_INVALID_PARAMETER A parameter is invalid.
> +  @retval EFI_DEVICE_ERROR      The physical device reported an error.
> +  @retval EFI_NOT_READY         The physical device is busy or not ready to
> +                                process this request.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +GetEndpointStallState (
> +  IN EFI_USBFN_IO_PROTOCOL        *This,
> +  IN UINT8                        EndpointIndex,
> +  IN EFI_USBFN_ENDPOINT_DIRECTION Direction,
> +  IN OUT BOOLEAN                  *State
> +  )
> +{
> +  USB_XDCI_DEV_CONTEXT              *UsbFuncIoDevPtr;
> +  XDCI_CORE_HANDLE                  *XdciCorePtr;
> +  UINT32                            EndPoint;
> +
> +  UsbFuncIoDevPtr = USBFUIO_CONTEXT_FROM_PROTOCOL (This);
> +  DEBUG ((USB_FUIO_DEBUG_LOAD, "GetEndpointStallState - Entry\n"));
> +
> +  EndPoint = UsbGetPhysicalEpNum (EndpointIndex, Direction ? UsbEpDirIn : UsbEpDirOut);
> +
> +  XdciCorePtr = UsbFuncIoDevPtr->XdciDrvIfHandle;
> +
> +  if (XdciCorePtr->EpHandles[EndPoint].State == USB_EP_STATE_STALLED) {
> +    *State = TRUE;
> +  } else {
> +    *State = FALSE;
> +  }
> +
> +  DEBUG ((USB_FUIO_DEBUG_LOAD, "GetEndpointStallState - Exit\n"));
> +  return EFI_SUCCESS;
> +}
> +
> +
> +EFI_STATUS
> +UsbSetAddress (
> +  IN EFI_USBFN_IO_PROTOCOL        *This,
> +  IN UINT32                        Address
> +  )
> +{
> +  EFI_STATUS                        Status;
> +  USB_XDCI_DEV_CONTEXT              *UsbFuncIoDevPtr;
> +  XDCI_CORE_HANDLE                  *XdciCorePtr;
> +  USB_DEV_CORE                      *UsbDeviceCorePtr;
> +
> +  DEBUG ((USB_FUIO_DEBUG_LOAD, "UsbSetAddress - 0x%04x Entry\n", Address));
> +
> +  UsbFuncIoDevPtr = USBFUIO_CONTEXT_FROM_PROTOCOL (This);
> +
> +  UsbDeviceCorePtr = UsbFuncIoDevPtr->DrvCore;
> +  XdciCorePtr = UsbDeviceCorePtr->ControllerHandle;
> +  Status = EFI_SUCCESS;
> +
> +  Status = UsbDeviceSetAddress (UsbDeviceCorePtr, (UINT32)Address);
> +
> +  if (Status != EFI_SUCCESS) {
> +    Status = EFI_DEVICE_ERROR;
> +    goto EXIT_SET_ADDRESS;
> +  }
> +
> +  Status = UsbDeviceEp0TxStatus (UsbDeviceCorePtr);
> +
> +  if (Status != EFI_SUCCESS) {
> +    Status = EFI_NO_RESPONSE;
> +    goto EXIT_SET_ADDRESS;
> +  }
> +
> +EXIT_SET_ADDRESS:
> +
> +  DEBUG ((USB_FUIO_DEBUG_LOAD, "UsbSetAddress - Exit %r\n", Status));
> +  return Status;
> +}
> +
> +
> +EFI_STATUS
> +EFIAPI
> +UsbSetconfigure (
> +  IN EFI_USBFN_IO_PROTOCOL        *This,
> +  IN UINT32                       InterFaceIndex
> +  )
> +{
> +  EFI_STATUS                      Status;
> +  USB_XDCI_DEV_CONTEXT            *UsbFuncIoDevPtr;
> +  XDCI_CORE_HANDLE                *XdciCorePtr;
> +  USB_DEV_CORE                    *UsbDeviceCorePtr;
> +  UINT32                          InterfaceNum;
> +  UINT32                          EndPointNum;
> +  UINT32                          EndPointIndex;
> +  EFI_USB_INTERFACE_INFO          *InterfaceInfoPtr;
> +  USB_EP_INFO                     EpInfo;
> +  USB_DEVICE_ENDPOINT_INFO        EpDescInfo;
> +
> +  DEBUG ((USB_FUIO_DEBUG_LOAD, "UsbSetconfigure - 0x%04x Entry\n", InterFaceIndex));
> +
> +  UsbFuncIoDevPtr = USBFUIO_CONTEXT_FROM_PROTOCOL (This);
> +  UsbDeviceCorePtr = UsbFuncIoDevPtr->DrvCore;
> +  XdciCorePtr = UsbDeviceCorePtr->ControllerHandle;
> +  Status = EFI_SUCCESS;
> +
> +  InterfaceNum = UsbFuncIoDevPtr->IndexPtrConfig.ConfigDescriptor->NumInterfaces;
> +  DEBUG ((USB_FUIO_DEBUG_LOAD, "UsbSetconfigure - ConfigDescriptor addr 0x%08x \n", (UINTN)UsbFuncIoDevPtr->IndexPtrConfig.ConfigDescriptor));
> +
> +  DEBUG ((USB_FUIO_DEBUG_LOAD, "UsbSetconfigure - DescriptorType 0x%04x ; ConfigurationValue 0x%04x\n",
> +          UsbFuncIoDevPtr->IndexPtrConfig.ConfigDescriptor->DescriptorType,
> +          UsbFuncIoDevPtr->IndexPtrConfig.ConfigDescriptor->ConfigurationValue
> +          ));
> +
> +  DEBUG ((USB_FUIO_DEBUG_LOAD, "UsbSetconfigure - InterfaceNum 0x%04x \n", InterfaceNum));
> +  if (InterfaceNum < InterFaceIndex) {
> +    Status = EFI_INVALID_PARAMETER;
> +    goto EXIT__SET_CONFIGURE;
> +  }
> +
> +  //
> +  // Arry strart form '0', Index start from '1'.
> +  //
> +  InterfaceInfoPtr = UsbFuncIoDevPtr->IndexPtrConfig.InterfaceInfoTable[InterFaceIndex - 1];
> +  EndPointNum = InterfaceInfoPtr->InterfaceDescriptor->NumEndpoints;
> +
> +  DEBUG ((USB_FUIO_DEBUG_LOAD, "UsbSetconfigure - Total EP NUM 0x%04x \n", EndPointNum));
> +
> +  for (EndPointIndex = 0; EndPointIndex < EndPointNum; EndPointIndex++) {
> +    EpDescInfo.EndpointDesc = InterfaceInfoPtr->EndpointDescriptorTable[EndPointIndex];
> +    EpDescInfo.EndpointCompDesc = NULL;
> +    UsbFnSetEpInfo (&EpInfo, &EpDescInfo);
> +    DEBUG ((USB_FUIO_DEBUG_LOAD, "EndpointAddress 0x%02x\n", EpDescInfo.EndpointDesc->EndpointAddress));
> +
> +    if (UsbDeviceInitEp (UsbDeviceCorePtr, &EpInfo) == EFI_SUCCESS) {
> +       if (UsbDeviceEpEnable (UsbDeviceCorePtr, &EpInfo) == EFI_SUCCESS) {
> +       } else {
> +         Status = EFI_DEVICE_ERROR;
> +         DEBUG ((DEBUG_INFO, "UsbDeviceEpEnable() - Failed to enable endpoint\n"));
> +       }
> +    } else {
> +       Status = EFI_DEVICE_ERROR;
> +       DEBUG ((DEBUG_INFO, "UsbDeviceInitEp() - Failed to initialize endpoint\n"));
> +    }
> +  }
> +
> +  Status = UsbDeviceEp0TxStatus (UsbDeviceCorePtr);
> +
> +  if (Status != EFI_SUCCESS) {
> +    Status = EFI_NO_RESPONSE;
> +    goto EXIT__SET_CONFIGURE;
> +  }
> +
> +
> +EXIT__SET_CONFIGURE:
> +  DEBUG ((USB_FUIO_DEBUG_LOAD, "UsbSetconfigure - Exit %r\n", Status));
> +
> +  return Status;
> +}
> +
> +/**
> +  Sets or clears the stall state on the specified endpoint.
> +
> +  @param[in]  This              A pointer to the EFI_USBFN_IO_PROTOCOL instance.
> +  @param[in]  EndpointIndex     Indicates the endpoint on which the ongoing
> +                                transfer needs to be canceled.
> +  @param[in]  Direction         Direction of the endpoint.
> +  @param[in]  State             Requested stall state on the specified endpoint.
> +                                True value causes the endpoint to stall;
> +                                false value clears an existing stall.
> +
> +  @retval EFI_SUCCESS           The function returned successfully.
> +  @retval EFI_INVALID_PARAMETER A parameter is invalid.
> +  @retval EFI_DEVICE_ERROR      The physical device reported an error.
> +  @retval EFI_NOT_READY         The physical device is busy or not ready to
> +                                process this request.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +SetEndpointStallState (
> +  IN EFI_USBFN_IO_PROTOCOL        *This,
> +  IN UINT8                        EndpointIndex,
> +  IN EFI_USBFN_ENDPOINT_DIRECTION Direction,
> +  IN BOOLEAN                      State
> +  )
> +{
> +  EFI_STATUS                        Status;
> +  USB_XDCI_DEV_CONTEXT              *UsbFuncIoDevPtr;
> +  USB_EP_INFO                       pEpInfo;
> +
> +  UsbFuncIoDevPtr = USBFUIO_CONTEXT_FROM_PROTOCOL (This);
> +
> +  DEBUG ((USB_FUIO_DEBUG_LOAD, "SetEndpointStallState - Entry\n"));
> +  Status = EFI_SUCCESS;
> +
> +  pEpInfo.EpNum = EndpointIndex;
> +  pEpInfo.EpDir = Direction? UsbEpDirIn : UsbEpDirOut;
> +
> +  if (State == TRUE) {
> +    Status = UsbDeviceEpStall (UsbFuncIoDevPtr->DrvCore, (VOID*)(UINTN) &pEpInfo);
> +  } else {
> +    Status = UsbDeviceEpClearStall (UsbFuncIoDevPtr->DrvCore, (VOID*)(UINTN) &pEpInfo);
> +  }
> +
> +  if (Status != EFI_SUCCESS) {
> +    Status = EFI_DEVICE_ERROR;
> +  }
> +
> +  DEBUG ((USB_FUIO_DEBUG_LOAD, "SetEndpointStallState - Exit\n"));
> +  return Status;
> +}
> +
> +EFI_STATUS
> +DeviceEventCheck(
> +  IN  EFI_USBFN_IO_PROTOCOL       *This,
> +  IN  USBD_EVENT_BUF              *EventIndex,
> +  OUT UINT32                      *ProcessSize,
> +  OUT EFI_USBFN_MESSAGE           *Message,
> +  OUT BOOLEAN                     *EventFlag
> +  )
> +{
> +  USB_XDCI_DEV_CONTEXT            *UsbFuncIoDevPtr;
> +  UINT32                          EventReg;
> +  USB_DEV_CORE                    *UsbDeviceCorePtr;
> +  XDCI_CORE_HANDLE                *XdciCorePtr;
> +
> +  DEBUG ((USB_FUIO_DEBUG_EVENT_D, "\n FUEV::DeviceEvent entry....\n"));
> +  UsbFuncIoDevPtr = USBFUIO_CONTEXT_FROM_PROTOCOL (This);
> +  UsbDeviceCorePtr = UsbFuncIoDevPtr->DrvCore;
> +  XdciCorePtr = UsbDeviceCorePtr->ControllerHandle;
> +  EventReg = (EventIndex->Event & DWC_XDCI_EVENT_BUFF_DEV_EVT_MASK);
> +  EventReg >>= DWC_XDCI_EVENT_BUFF_DEV_EVT_BIT_POS;
> +  *EventFlag = FALSE;
> +
> +  //
> +  // Assume default event size. Change it in switch case if
> +  // different
> +  //
> +  *ProcessSize =  DWC_XDCI_DEV_EVENT_DEFAULT_SIZE_IN_BYTES;
> +
> +  switch (EventReg) {
> +    case DWC_XDCI_EVENT_BUFF_DEV_DISCONN_EVENT:
> +      DEBUG ((USB_FUIO_DEBUG_EVENT_D, "USBFU_Device DWC_XDCI_EVENT_BUFF_DEV_DISCONN_EVENT\n"));
> +      *Message = EfiUsbMsgBusEventDetach;
> +      break;
> +
> +    case DWC_XDCI_EVENT_BUFF_DEV_USB_RESET_EVENT:
> +      DEBUG ((USB_FUIO_DEBUG_EVENT_D, "USBFU_Device DWC_XDCI_EVENT_BUFF_DEV_USB_RESET_EVENT\n"));
> +      //
> +      //  In resetDet will prepare setup Xfer package
> +      //
> +      UsbFuncIoDevPtr->DevReConnect = FALSE;
> +      UsbFuncIoDevPtr->DevResetFlag = TRUE;
> +
> +      usbProcessDeviceResetDet (XdciCorePtr);
> +      UsbDeviceSetAddress (UsbDeviceCorePtr, 0);
> +      *Message = EfiUsbMsgBusEventReset;
> +      *EventFlag = TRUE;
> +      break;
> +
> +    case DWC_XDCI_EVENT_BUFF_DEV_CONN_DONE_EVENT:
> +      DEBUG ((USB_FUIO_DEBUG_EVENT_D, "USBFU_Device DWC_XDCI_EVENT_BUFF_DEV_CONN_DONE_EVENT\n"));
> +      usbProcessDeviceResetDone(XdciCorePtr);
> +      UsbDeviceSetAddress(UsbDeviceCorePtr, 0);
> +      UsbFuncIoDevPtr->DevReConnect = TRUE;
> +      UsbFuncIoDevPtr->DevResetFlag = FALSE;
> +      *EventFlag = TRUE;
> +      *Message = EfiUsbMsgNone;
> +      break;
> +
> +    case DWC_XDCI_EVENT_BUFF_DEV_HBRNTN_REQ_EVENT:
> +      DEBUG ((USB_FUIO_DEBUG_EVENT_D, "USBFU_Device DWC_XDCI_EVENT_BUFF_DEV_HBRNTN_REQ_EVENT\n"));
> +      *Message = EfiUsbMsgBusEventSuspend;
> +      *EventFlag = TRUE;
> +      break;
> +
> +    case DWC_XDCI_EVENT_BUFF_DEV_WKUP_EVENT:
> +      DEBUG ((USB_FUIO_DEBUG_EVENT_D, "USBFU_Device DWC_XDCI_EVENT_BUFF_DEV_WKUP_EVENT\n"));
> +      *Message = EfiUsbMsgBusEventResume;
> +      break;
> +
> +    case DWC_XDCI_EVENT_BUFF_DEV_TST_LMP_RX_EVENT:
> +      *ProcessSize = DWC_XDCI_DEV_EVENT_TST_LMP_SIZE_IN_BYTES;
> +      *Message = EfiUsbMsgNone;
> +      DEBUG ((USB_FUIO_DEBUG_EVENT_D, "USBFUDwcXdciProcessDeviceEvent: UNHANDLED device event: %x\n", EventReg));
> +      break;
> +
> +    case DWC_XDCI_EVENT_BUFF_DEV_STATE_CHANGE_EVENT:
> +      DEBUG ((USB_FUIO_DEBUG_EVENT_D, "USBFU_Device DWC_XDCI_EVENT_BUFF_DEV_STATE_CHANGE_EVENT\n"));
> +      break;
> +
> +    case DWC_XDCI_EVENT_BUFF_DEV_SOF_EVENT:
> +      DEBUG ((USB_FUIO_DEBUG_EVENT_D, "USBFU_Device DWC_XDCI_EVENT_BUFF_DEV_SOF_EVENT\n"));
> +      break;
> +
> +    case DWC_XDCI_EVENT_BUFF_DEV_ERRATIC_ERR_EVENT:
> +      DEBUG ((USB_FUIO_DEBUG_EVENT_D, "USBFU_Device DWC_XDCI_EVENT_BUFF_DEV_ERRATIC_ERR_EVENT\n"));
> +      break;
> +
> +    case DWC_XDCI_EVENT_BUFF_DEV_CMD_CMPLT_EVENT:
> +      DEBUG ((USB_FUIO_DEBUG_EVENT_D, "USBFU_Device DWC_XDCI_EVENT_BUFF_DEV_CMD_CMPLT_EVENT\n"));
> +      break;
> +
> +    case DWC_XDCI_EVENT_BUFF_DEV_BUFF_OVFL_EVENT:
> +      DEBUG ((USB_FUIO_DEBUG_EVENT_D, "USBFU_Device DWC_XDCI_EVENT_BUFF_DEV_BUFF_OVFL_EVENT\n"));
> +      break;
> +
> +    default:
> +      *EventFlag = FALSE;
> +      *Message = EfiUsbMsgNone;
> +      DEBUG ((USB_FUIO_DEBUG_EVENT_I, "USBFUWcXdciProcessDeviceEvent: UNHANDLED device event: %x\n", EventReg));
> +      break;
> +  }
> +
> +  DEBUG ((USB_FUIO_DEBUG_EVENT_D, "\n FUEV::DeviceEvent entry exit.... \n"));
> +  return EFI_SUCCESS;
> +}
> +
> +
> +EFI_STATUS
> +Ep0XferDone(
> +  IN  EFI_USBFN_IO_PROTOCOL       *This,
> +  IN  UINT32                      EndPointNum,
> +  OUT EFI_USBFN_MESSAGE           *Message,
> +  IN OUT UINTN                    *PayloadSize,
> +  OUT EFI_USBFN_MESSAGE_PAYLOAD   *Payload
> +  )
> +{
> +  USB_DEV_CORE                    *UsbDeviceCorePtr;
> +  XDCI_CORE_HANDLE                *XdciCorePtr;
> +  USB_XDCI_DEV_CONTEXT            *UsbFuncIoDevPtr;
> +  DWC_XDCI_ENDPOINT               *EpHandle;
> +  DWC_XDCI_TRB                    *Trb;
> +  UINT32                          TrbCtrl;
> +  UINT32                          TrbSts;
> +  UINT32                          BufferLen;
> +  EFI_STATUS                      DevStatus;
> +  USB_EP_INFO                     EpInfo;
> +
> +  UsbFuncIoDevPtr = USBFUIO_CONTEXT_FROM_PROTOCOL (This);
> +  UsbDeviceCorePtr = UsbFuncIoDevPtr->DrvCore;
> +  XdciCorePtr = UsbDeviceCorePtr->ControllerHandle;
> +  EpHandle = &XdciCorePtr->EpHandles[EndPointNum];
> +  Trb = XdciCorePtr->Trbs + (EndPointNum * DWC_XDCI_TRB_NUM);
> +
> +  if (Trb->TrbCtrl & DWC_XDCI_TRB_CTRL_HWO_MASK) {
> +    DEBUG ((USB_FUIO_DEBUG_EVENT_D, "Ep0XferDone. HW owns TRB: %x!!!\n", (UINT32)(UINTN)Trb));
> +  }
> +
> +  DevStatus = EFI_SUCCESS;
> +  BufferLen = 0;
> +
> +  DEBUG ((USB_FUIO_DEBUG_EVENT_D, "EndPointNum:%d, TRB: Addr 0x%08x!!!\n", EndPointNum, (UINTN)Trb));
> +  DEBUG ((USB_FUIO_DEBUG_EVENT_D, "Ep0 done Trb->TrbCtrl: %x!!!\n", (UINT32)Trb->TrbCtrl));
> +  DEBUG ((USB_FUIO_DEBUG_EVENT_D, "Ep0 done Trb->LenXferParams: %x!!!\n", (UINT32)Trb->LenXferParams));
> +  DEBUG ((USB_FUIO_DEBUG_EVENT_D, "Ep0 done Trb->BuffPtrLow: %x!!!\n", (UINT32)Trb->BuffPtrLow));
> +  DEBUG ((USB_FUIO_DEBUG_EVENT_D, "Ep0 done Trb->BuffPtrHigh: %x!!!\n", (UINT32)Trb->BuffPtrHigh));
> +
> +  //
> +  // Set CheckFlag to FALSE for 'DwcXdciEpRxData' function
> +  // check the RX request complete and continue next transfer request
> +  //
> +  EpHandle->CheckFlag = FALSE;
> +  EpHandle->CurrentXferRscIdx = 0;
> +
> +  DEBUG ((USB_FUIO_DEBUG_EVENT_I, "Ep0 done D01!!\n"));
> +  TrbCtrl = (Trb->TrbCtrl & DWC_XDCI_TRB_CTRL_TYPE_MASK) >> DWC_XDCI_TRB_CTRL_TYPE_BIT_POS;
> +
> +  DEBUG ((USB_FUIO_DEBUG_EVENT_I, "Ep0 done D02!!\n"));
> +  TrbSts = (Trb->LenXferParams & DWC_XDCI_TRB_STATUS_MASK) >> DWC_XDCI_TRB_STATUS_BIT_POS;
> +
> +  DEBUG ((USB_FUIO_DEBUG_EVENT_I, "Ep0 done D03!!\n" ));
> +  BufferLen = Trb->LenXferParams & DWC_XDCI_TRB_BUFF_SIZE_MASK;
> +
> +  DEBUG ((USB_FUIO_DEBUG_EVENT_I, "Ep0 done D04 TrbCtrl :: %x!!\n", TrbCtrl));
> +  switch (TrbCtrl) {
> +    case DWC_XDCI_TRB_CTRL_TYPE_SETUP:
> +      DEBUG ((USB_FUIO_DEBUG_EVENT_D, "Ep0 done DWC_XDCI_TRB_CTRL_TYPE_SETUP!!\n"));
> +      //
> +      // This is delay for other host USB controller(none Intel), identify device get fail issue.
> +      //
> +      gBS->Stall(130);
> +      BufferLen = 8;
> +
> +      DEBUG ((USB_FUIO_DEBUG_EVENT_D, "DWC_XDCI_TRB_CTRL_TYPE_SETUP!!\n"));
> +      DEBUG ((USB_FUIO_DEBUG_EVENT_D, "AlignedSetupBuffer::0x%08x!!\n", XdciCorePtr->AlignedSetupBuffer));
> +      DEBUG ((USB_FUIO_DEBUG_EVENT_D, "Payload::0x%08x!!\n", (UINTN)Payload));
> +      DEBUG ((USB_FUIO_DEBUG_EVENT_D, "BufferLen::0x%08x!!\n", (UINTN)BufferLen));
> +      *Message = EfiUsbMsgSetupPacket;
> +      CopyMem (Payload, XdciCorePtr->AlignedSetupBuffer, BufferLen);
> +
> +      DEBUG ((USB_FUIO_DEBUG_EVENT_I, "Ep0 done D06!!\n"));
> +      if (!(XdciCorePtr->AlignedSetupBuffer[0] & USB_SETUP_DATA_PHASE_DIRECTION_MASK)) {
> +        if ((XdciCorePtr->AlignedSetupBuffer[0]  == 0x00) ) {
> +          if ((XdciCorePtr->AlignedSetupBuffer[1]  == USB_DEV_SET_ADDRESS)) {
> +            //
> +            // set address
> +            //
> +            UsbSetAddress (
> +              This,
> +              (UINT32)(XdciCorePtr->AlignedSetupBuffer[3] << 8 | XdciCorePtr->AlignedSetupBuffer[2])
> +              );
> +
> +            *Message = EfiUsbMsgNone;
> +          } else if ((XdciCorePtr->AlignedSetupBuffer[1]  == USB_DEV_SET_CONFIGURATION)) {
> +            DEBUG ((USB_FUIO_DEBUG_EVENT_I, "\n set configure !!!"));
> +            UsbSetconfigure (
> +              This,
> +              (UINT32)(XdciCorePtr->AlignedSetupBuffer[3] << 8 | XdciCorePtr->AlignedSetupBuffer[2])
> +              );
> +            *Message = EfiUsbMsgNone;
> +          }
> +        }
> +      }
> +
> +      DEBUG ((USB_FUIO_DEBUG_EVENT_I, "Ep0 done D07!!\n"));
> +      break;
> +
> +    case DWC_XDCI_TRB_CTRL_TYPE_DATA:
> +      DEBUG ((DEBUG_INFO, "Ep0 done DWC_XDCI_TRB_CTRL_TYPE_DATA!!\n"));
> +       //
> +      // Notify upper layer of control transfer completion
> +      // if a callback function was registerd
> +      //
> +      if ((EndPointNum & 0x01) == 0) {
> +        *Message = EfiUsbMsgEndpointStatusChangedRx;
> +      } else {
> +        *Message = EfiUsbMsgEndpointStatusChangedTx;
> +      }
> +      Payload->utr.EndpointIndex = (UINT8)(EndPointNum >> 1);
> +      Payload->utr.Direction = (UINT8)(EndPointNum & 0x01);
> +      Payload->utr.Buffer = (VOID*)(UINTN)(Trb->BuffPtrLow);
> +
> +      DEBUG ((DEBUG_INFO, "Ep0 EndPointNum: %x!!!\n", (UINT32)EndPointNum));
> +      DEBUG ((DEBUG_INFO, "Ep0 done XferLength: %x!!!\n", (UINT32)UsbFuncIoDevPtr->EndPointXferRec[EndPointNum].XferLength));
> +      Payload->utr.Buffer = (VOID*)UsbFuncIoDevPtr->EndPointXferRec[EndPointNum].XferAddress;
> +      Payload->utr.BytesTransferred = UsbFuncIoDevPtr->EndPointXferRec[EndPointNum].XferLength;
> +
> +      if (TrbSts == 0) {
> +        if ((Trb->LenXferParams & DWC_XDCI_TRB_BUFF_SIZE_MASK) == 0) {
> +          Payload->utr.TransferStatus = UsbTransferStatusComplete;
> +        } else {
> +          Payload->utr.TransferStatus = UsbTransferStatusActive;
> +        }
> +      } else if (TrbSts != 0) {
> +        Trb->TrbCtrl |= DWC_XDCI_TRB_CTRL_HWO_MASK;
> +        *Message = EfiUsbMsgNone;
> +        Payload->utr.TransferStatus = UsbTransferStatusAborted;
> +        DEBUG ((DEBUG_INFO, "Flush FIFO!!!\n" ));
> +        EpInfo.EpNum = 0;
> +        EpInfo.EpDir =UsbEpDirIn;
> +        UsbXdciCoreFlushEpFifo(XdciCorePtr, &EpInfo);
> +        EpInfo.EpNum = 0;
> +        EpInfo.EpDir =UsbEpDirOut;
> +        UsbXdciCoreFlushEpFifo(XdciCorePtr, &EpInfo);
> +        DevStatus = UsbDeviceEp0RxSetup (UsbDeviceCorePtr, XdciCorePtr->AlignedSetupBuffer);
> +      }
> +
> +      break;
> +
> +    case DWC_XDCI_TRB_CTRL_TYPE_STATUS2:
> +    case DWC_XDCI_TRB_CTRL_TYPE_STATUS3:
> +      Payload->utr.Buffer = (VOID*) UsbFuncIoDevPtr->EndPointXferRec[EndPointNum].XferAddress;
> +      Payload->utr.BytesTransferred = 0;
> +      Payload->utr.EndpointIndex = (UINT8)(EndPointNum >> 1);
> +      if ((EndPointNum & 0x01) == 0) {
> +        *Message = EfiUsbMsgEndpointStatusChangedRx;
> +      } else {
> +        *Message = EfiUsbMsgEndpointStatusChangedTx;
> +      }
> +
> +      if (TrbSts == 0) {
> +        if ((Trb->LenXferParams & DWC_XDCI_TRB_BUFF_SIZE_MASK) == 0) {
> +          Payload->utr.TransferStatus = UsbTransferStatusComplete;
> +        } else {
> +          Payload->utr.TransferStatus = UsbTransferStatusActive;
> +        }
> +      } else if (TrbSts != 0) {
> +        Payload->utr.TransferStatus = UsbTransferStatusAborted;
> +      }
> +
> +      DevStatus = UsbDeviceEp0RxSetup (UsbDeviceCorePtr, XdciCorePtr->AlignedSetupBuffer);
> +
> +      if (DevStatus) {
> +        DEBUG ((DEBUG_INFO, "DwcXdciProcessEp0XferPhaseDone: FAILED to queue SETUP\n"));
> +      }
> +      DEBUG ((DEBUG_INFO, "Status phase done. Queue next SETUP packet==>\n"));
> +      break;
> +
> +    default:
> +      *Message = EfiUsbMsgNone;
> +      DEBUG ((DEBUG_INFO, "DwcXdciProcessEp0XferPhaseDone: UNHANDLED STATE in TRB\n"));
> +      break;
> +  }
> +  return EFI_SUCCESS;
> +}
> +
> +
> +EFI_STATUS
> +NoneEp0XferDone(
> +  IN  EFI_USBFN_IO_PROTOCOL       *This,
> +  IN  UINT32                      EndPointNum,
> +  OUT EFI_USBFN_MESSAGE           *Message,
> +  IN OUT UINTN                    *PayloadSize,
> +  OUT EFI_USBFN_MESSAGE_PAYLOAD   *Payload
> +  )
> +{
> +  USB_DEV_CORE                    *UsbDeviceCorePtr;
> +  XDCI_CORE_HANDLE                *XdciCorePtr;
> +  USB_XDCI_DEV_CONTEXT            *UsbFuncIoDevPtr;
> +  DWC_XDCI_ENDPOINT               *EpHandle;
> +  DWC_XDCI_TRB                    *Trb;
> +  UINT32                          TrbCtrl;
> +  UINT32                          TrbSts;
> +
> +  UsbFuncIoDevPtr = USBFUIO_CONTEXT_FROM_PROTOCOL (This);
> +  UsbDeviceCorePtr = UsbFuncIoDevPtr->DrvCore;
> +  XdciCorePtr = UsbDeviceCorePtr->ControllerHandle;
> +  EpHandle = &XdciCorePtr->EpHandles[EndPointNum];
> +  Trb = XdciCorePtr->Trbs + (EndPointNum * DWC_XDCI_TRB_NUM);
> +
> +  if (Trb->TrbCtrl & DWC_XDCI_TRB_CTRL_HWO_MASK) {
> +    DEBUG ((USB_FUIO_DEBUG_EVENT_D, "NoneEp0XferDone. HW owns TRB: %x!!!, EndPointNum: %x\n", (UINT32)(UINTN)Trb, EndPointNum));
> +  }
> +
> +  DEBUG ((USB_FUIO_DEBUG_EVENT_D, " TRB: Addr 0x%08x!!!\n", (UINTN)Trb));
> +  DEBUG ((USB_FUIO_DEBUG_EVENT_D, " Xfer done Trb->BuffPtrLow: %x!!!\n", (UINT32)Trb->BuffPtrLow));
> +  DEBUG ((USB_FUIO_DEBUG_EVENT_D, " Xfer done Trb->BuffPtrHigh: %x!!!\n", (UINT32)Trb->BuffPtrHigh));
> +  DEBUG ((USB_FUIO_DEBUG_EVENT_D, " Xfer done Trb->LenXferParams: %x!!!\n", (UINT32)Trb->LenXferParams));
> +  DEBUG ((USB_FUIO_DEBUG_EVENT_D, " Xfer done Trb->TrbCtrl: %x!!!\n", (UINT32)Trb->TrbCtrl));
> +
> +  //
> +  // Set CheckFlag to FALSE for 'DwcXdciEpRxData' function
> +  // check the RX request complete and continue next transfer request
> +  //
> +  EpHandle->CheckFlag = FALSE;
> +  EpHandle->CurrentXferRscIdx = 0;
> +  *Message = EfiUsbMsgNone;
> +
> +  TrbCtrl = (Trb->TrbCtrl & DWC_XDCI_TRB_CTRL_TYPE_MASK) >> DWC_XDCI_TRB_CTRL_TYPE_BIT_POS;
> +  TrbSts = (Trb->LenXferParams & DWC_XDCI_TRB_STATUS_MASK) >> DWC_XDCI_TRB_STATUS_BIT_POS;
> +
> +  Payload->utr.BytesTransferred = UsbFuncIoDevPtr->EndPointXferRec[EndPointNum].XferLength;
> +  Payload->utr.EndpointIndex = UsbFuncIoDevPtr->EndPointXferRec[EndPointNum].LogEpNum;
> +  Payload->utr.Direction = UsbFuncIoDevPtr->EndPointXferRec[EndPointNum].Direction;
> +  Payload->utr.Buffer = (VOID*)(UINTN)(Trb->BuffPtrLow);
> +  UsbFuncIoDevPtr->EndPointXferRec[EndPointNum].Complete = TRUE;
> +
> +  DEBUG ((USB_FUIO_DEBUG_EVENT_D, "EndPointAddress = 0x%08x\n", Payload->utr.EndpointIndex));
> +  if (Payload->utr.Direction == EfiUsbEndpointDirectionDeviceTx) {
> +    DEBUG ((USB_FUIO_DEBUG_EVENT_D, " Direction::EfiUsbEndpointDirectionDeviceTx\n"));
> +    *Message = EfiUsbMsgEndpointStatusChangedTx;
> +  } else {
> +    DEBUG ((USB_FUIO_DEBUG_EVENT_D, " Direction::EfiUsbEndpointDirectionDeviceRx\n"));
> +    *Message = EfiUsbMsgEndpointStatusChangedRx;
> +  }
> +
> +  if (TrbSts == 0) {
> +    if ((Trb->LenXferParams & DWC_XDCI_TRB_BUFF_SIZE_MASK) == 0) {
> +      Payload->utr.TransferStatus = UsbTransferStatusComplete;
> +      DEBUG ((USB_FUIO_DEBUG_EVENT_D, "XferStatus::UsbTransferStatusComplete\n"));
> +    } else {
> +      Payload->utr.TransferStatus = UsbTransferStatusComplete;
> +      Payload->utr.BytesTransferred -= (Trb->LenXferParams & DWC_XDCI_TRB_BUFF_SIZE_MASK);
> +      DEBUG ((USB_FUIO_DEBUG_EVENT_D, "XferStatus::UsbTransferStatusComplete\n"));
> +      DEBUG ((USB_FUIO_DEBUG_EVENT_D, "XferStatus::Length %d \n", Payload->utr.BytesTransferred ));
> +    }
> +  } else if (TrbSts != 0) {
> +    Payload->utr.TransferStatus = UsbTransferStatusAborted;
> +    DEBUG ((USB_FUIO_DEBUG_EVENT_D, "XferStatus::UsbTransferStatusAborted\n"));
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +EFI_STATUS
> +Ep0XferNotReady(
> +  IN  EFI_USBFN_IO_PROTOCOL       *This,
> +  IN  UINT32                      EndPointNum,
> +  OUT EFI_USBFN_MESSAGE           *Message,
> +  IN OUT UINTN                    *PayloadSize,
> +  OUT EFI_USBFN_MESSAGE_PAYLOAD   *Payload,
> +  IN  UINT32                      EpStatus
> +  )
> +{
> +  USB_DEV_CORE                    *UsbDeviceCorePtr;
> +  XDCI_CORE_HANDLE                *XdciCorePtr;
> +  USB_XDCI_DEV_CONTEXT            *UsbFuncIoDevPtr;
> +
> +  UsbFuncIoDevPtr = USBFUIO_CONTEXT_FROM_PROTOCOL(This);
> +  UsbDeviceCorePtr = UsbFuncIoDevPtr->DrvCore;
> +  XdciCorePtr = UsbDeviceCorePtr->ControllerHandle;
> +
> +  *Message = EfiUsbMsgNone;
> +
> +  return EFI_SUCCESS;
> +}
> +
> +
> +EFI_STATUS
> +EpEventCheck(
> +  IN  EFI_USBFN_IO_PROTOCOL       *This,
> +  IN  USBD_EVENT_BUF              *EventIndex,
> +  OUT UINT32                      *ProcessSize,
> +  OUT EFI_USBFN_MESSAGE           *Message,
> +  IN OUT UINTN                    *PayloadSize,
> +  OUT EFI_USBFN_MESSAGE_PAYLOAD   *Payload,
> +  OUT BOOLEAN                     *EventFlag
> +  )
> +{
> +  USB_DEV_CORE                    *UsbDeviceCorePtr;
> +  XDCI_CORE_HANDLE                *XdciCorePtr;
> +  USB_XDCI_DEV_CONTEXT            *UsbFuncIoDevPtr;
> +  UINT32                          EventReg;
> +  UINT32                          EpEvent;
> +  UINT32                          EndPointNumber;
> +  UINT32                          EventStatus;
> +  USB_EP_STATE                    Ep_State;
> +  UINTN                           TmpBufferSize;
> +
> +  DEBUG ((USB_FUIO_DEBUG_EVENT_I, "FUEV::EndPoint Event....\n"));
> +  UsbFuncIoDevPtr = USBFUIO_CONTEXT_FROM_PROTOCOL(This);
> +
> +  UsbDeviceCorePtr = UsbFuncIoDevPtr->DrvCore;
> +  XdciCorePtr = UsbDeviceCorePtr->ControllerHandle;
> +  EventReg = EventIndex->Event;
> +  *ProcessSize = DWC_XDCI_DEV_EVENT_DEFAULT_SIZE_IN_BYTES;
> +  *EventFlag = TRUE;
> +  TmpBufferSize = 0;
> +
> +  //
> +  // Get EP num
> +  //
> +  EndPointNumber = (EventReg & DWC_XDCI_EVENT_BUFF_EP_NUM_MASK) >> DWC_XDCI_EVENT_BUFF_EP_NUM_BIT_POS;
> +
> +  EventStatus = EventReg & DWC_XDCI_EVENT_BUFF_EP_EVENT_STATUS_MASK;
> +
> +  //
> +  // Interpret event and handle transfer completion here
> +  //
> +  EpEvent = (EventReg & DWC_XDCI_EVENT_BUFF_EP_EVENT_MASK) >> DWC_XDCI_EVENT_BUFF_EP_EVENT_BIT_POS;
> +
> +  DEBUG ((USB_FUIO_DEBUG_EVENT_I, "USBFU_EP EventReg 0x%08x\n", EventReg));
> +
> +  switch (EpEvent) {
> +    case DWC_XDCI_EVENT_BUFF_EP_XFER_CMPLT:
> +      DEBUG ((USB_FUIO_DEBUG_EVENT_D, "USBFU_EP DWC_XDCI_EVENT_BUFF_EP_XFER_CMPLT\n"));
> +      if (EndPointNumber > 1) {
> +        DEBUG ((USB_FUIO_DEBUG_EVENT_D, "USBFU_EP None_Control transfer\n"));
> +        NoneEp0XferDone (This, EndPointNumber, Message, PayloadSize, Payload);
> +      } else {
> +        //
> +        // Control transfer
> +        //
> +        DEBUG ((USB_FUIO_DEBUG_EVENT_D, "USBFU_EP Control transfer\n"));
> +        Ep0XferDone (This, EndPointNumber, Message, PayloadSize, Payload);
> +      }
> +      break;
> +
> +    case DWC_XDCI_EVENT_BUFF_EP_XFER_NOT_READY:
> +      DEBUG ((USB_FUIO_DEBUG_EVENT_D, "DWC_XDCI_EVENT_BUFF_EP_XFER_NOT_READY\n"));
> +      *Message = EfiUsbMsgNone;
> +      if(EndPointNumber < (sizeof(UsbFuncIoDevPtr->EndPointXferRec) / sizeof(UsbFuncIoDevPtr->EndPointXferRec[0]))) {
> +        if ((UsbFuncIoDevPtr->EndPointXferRec[EndPointNumber].ZlpFlag == TRUE) && \
> +              (UsbFuncIoDevPtr->EndPointXferRec[EndPointNumber].Complete == TRUE)) {
> +          DEBUG ((USB_FUIO_DEBUG_EVENT_D, "Request send ZLP\n"));
> +          if ((EndPointNumber & 0x01) != 0) {
> +            Transfer(This,
> +                     UsbFuncIoDevPtr->IndexPtrInEp.EndpointDesc->EndpointAddress,
> +                     EfiUsbEndpointDirectionDeviceTx,
> +                     &TmpBufferSize,
> +                     NULL
> +                    );
> +            UsbFuncIoDevPtr->EndPointXferRec[EndPointNumber].ZlpFlag = FALSE;
> +          }
> +
> +        }
> +      } else {
> +        //
> +        // Is it data stage or status stage
> +        //
> +        // Data Statge
> +        //
> +        Ep_State = USB_EP_STATE_DATA;
> +        //
> +        // Control transfer
> +        //
> +        DEBUG ((USB_FUIO_DEBUG_EVENT_D, "USBFU_EP Control transfer not ready\n"));
> +        Ep0XferNotReady (This, EndPointNumber, Message, PayloadSize, Payload, EventStatus);
> +        *EventFlag = FALSE;
> +      }
> +      break;
> +
> +    case DWC_XDCI_EVENT_BUFF_EP_XFER_IN_PROGRESS:
> +      DEBUG ((USB_FUIO_DEBUG_EVENT_D, "DWC_XDCI_EVENT_BUFF_EP_XFER_IN_PROGRESS\n"));
> +      break;
> +
> +    default:
> +      DEBUG ((USB_FUIO_DEBUG_EVENT_I, "USBFUDwcXdciProcessEpEvent: UNKNOWN EP event\n"));
> +      break;
> +  }
> +
> +  DEBUG ((USB_FUIO_DEBUG_EVENT_D, "FUEV::EndPoint Event....exit\n"));
> +  return EFI_SUCCESS;
> +}
> +
> +
> +EFI_STATUS
> +ProcessIntLineEvents(
> +  IN EFI_USBFN_IO_PROTOCOL        *This,
> +  IN UINT32                       EventCount,
> +  IN UINT32                       *ProceSsEvent,
> +  OUT EFI_USBFN_MESSAGE           *Message,
> +  IN OUT UINTN                    *PayloadSize,
> +  OUT EFI_USBFN_MESSAGE_PAYLOAD   *Payload,
> +  OUT BOOLEAN                     *EventFlag
> +  )
> +{
> +  USB_DEV_CORE                    *UsbDeviceCorePtr;
> +  XDCI_CORE_HANDLE                *XdciCorePtr;
> +  USB_XDCI_DEV_CONTEXT            *UsbFuncIoDevPtr;
> +  UINT32                          CurrentEventAddr;
> +  UINT32                          ProceSsEventSize;
> +  BOOLEAN                         EventReport;
> +  BOOLEAN                         EpEventReport;
> +
> +  UsbFuncIoDevPtr = USBFUIO_CONTEXT_FROM_PROTOCOL (This);
> +  UsbDeviceCorePtr = UsbFuncIoDevPtr->DrvCore;
> +  XdciCorePtr = UsbDeviceCorePtr->ControllerHandle;
> +  CurrentEventAddr = (UINT32)(UINTN)(XdciCorePtr->CurrentEventBuffer);
> +  EventReport = FALSE;
> +  EpEventReport = FALSE;
> +  ProceSsEventSize = 0;
> +   DEBUG ((USB_FUIO_DEBUG_EVENT_I, "FUEV:: ProcessIntLineEvents Entry\n"));
> +
> +   DEBUG ((USB_FUIO_DEBUG_EVENT_I, "FUEV:: XdciCorePtr->CurrentEventBuffer 0x%08x\n", XdciCorePtr->CurrentEventBuffer));
> +   DEBUG ((USB_FUIO_DEBUG_EVENT_I, "FUEV::EventCount0x%08x\n", EventCount));
> +   DEBUG ((USB_FUIO_DEBUG_EVENT_I, "FUEV::CurrentEventAddr 0x%08x\n", CurrentEventAddr));
> +
> +  while ((EventCount != 0) && (EventReport == FALSE)) {
> +     DEBUG ((USB_FUIO_DEBUG_EVENT_D, "FUEV::event0x%08x\n", XdciCorePtr->CurrentEventBuffer->Event));
> +     if ((XdciCorePtr->CurrentEventBuffer->Event & DWC_XDCI_EVENT_DEV_MASK) != 0) {
> +       //
> +       // Device event
> +       //
> +       DeviceEventCheck (
> +         This,
> +         (USBD_EVENT_BUF*)(UINTN)CurrentEventAddr,
> +         &ProceSsEventSize,
> +         Message,
> +         &EventReport
> +         );
> +       if (EventReport == TRUE) {
> +         *EventFlag = TRUE;
> +       }
> +
> +     } else {
> +       //
> +       // EndPoint Event
> +       //
> +       EpEventCheck (
> +         This,
> +         (USBD_EVENT_BUF*)(UINTN)CurrentEventAddr,
> +         &ProceSsEventSize,
> +         Message,
> +         PayloadSize,
> +         Payload,
> +         &EpEventReport
> +         );
> +     }
> +
> +     if ((*Message != EfiUsbMsgNone) || (EpEventReport == TRUE)) {
> +       EventReport = TRUE;
> +       *EventFlag = TRUE;
> +     }
> +
> +     DEBUG ((USB_FUIO_DEBUG_EVENT_D, "FUEV:: CurrentEventAddr 0x%08x :: ProceSsEventSize 0x%08x\n", (UINTN)CurrentEventAddr,ProceSsEventSize));
> +
> +     EventCount -= ProceSsEventSize;
> +     *ProceSsEvent += ProceSsEventSize;
> +     if ((CurrentEventAddr + ProceSsEventSize) >= \
> +         ((UINT32)(UINTN)(XdciCorePtr->AlignedEventBuffers) +
> +          (sizeof(DWC_XDCI_EVENT_BUFFER) * DWC_XDCI_MAX_EVENTS_PER_BUFFER))) {
> +       CurrentEventAddr = (UINT32)(UINTN)(XdciCorePtr->AlignedEventBuffers);
> +    } else {
> +      CurrentEventAddr += ProceSsEventSize;
> +    }
> +    DEBUG ((USB_FUIO_DEBUG_EVENT_D, "FUEV:: CurrentEventAddr Update 0x%08x :: ProceSsEventSize 0x%08x\n", CurrentEventAddr,ProceSsEventSize));
> +
> +    XdciCorePtr->CurrentEventBuffer = (DWC_XDCI_EVENT_BUFFER*)(UINTN)CurrentEventAddr;
> +  }
> +
> +  DEBUG ((USB_FUIO_DEBUG_EVENT_I, "FUEV:: ProcessIntLineEvents Exit\n\n"));
> +  return EFI_SUCCESS;
> +}
> +
> +
> +/**
> +  ISR inokes Event Handler.  Look at which interrupt has happened and see
> +  if there are event handler registerd and if so fire them 1 by one.
> +
> +  @param[in]  This              A pointer to the EFI_USBFN_IO_PROTOCOL instance.
> +  @param[in]  Message           Indicates the event that initiated this
> +                                notification.
> +  @param[in]  PayloadSize       On input, the size of the memory pointed by Payload.
> +                                On output, the amount of data returned in Payload.
> +  @param[in]  Payload           A pointer to EFI_USBFN_MESSAGE_PAYLOAD instance to
> +                                return additional payload for current message.
> +
> +
> +
> +
> +  @retval EFI_SUCCESS           The function returned successfully.
> +  @retval EFI_INVALID_PARAMETER A parameter is invalid.
> +  @retval EFI_DEVICE_ERROR      The physical device reported an error.
> +  @retval EFI_NOT_READY         The physical device is busy or not ready to
> +                                process this request.
> +  @retval EFI_BUFFER_TOO_SMALL  Supplied Buffer not large enough to hold
> +                                the message payload.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +EventHandler(
> +  IN EFI_USBFN_IO_PROTOCOL        *This,
> +  OUT EFI_USBFN_MESSAGE           *Message,
> +  IN OUT UINTN                    *PayloadSize,
> +  OUT EFI_USBFN_MESSAGE_PAYLOAD   *Payload
> +  )
> +{
> +  UINT32                          EventCount;
> +  UINT32                          PeventCount;
> +  USB_XDCI_DEV_CONTEXT            *UsbFuncIoDevPtr;
> +  UINT32                          MaxIntNum;
> +  UINT32                          IntIndex;
> +  USB_DEV_CORE                    *UsbDeviceCorePtr;
> +  XDCI_CORE_HANDLE                *XdciCorePtr;
> +  BOOLEAN                         EventFlag;
> +  EFI_TPL                         OriginalTpl;
> +
> +
> +  DEBUG ((USB_FUIO_DEBUG_EVENT_I, "USBFU_ EventHandler Entry\n"));
> +  UsbFuncIoDevPtr = USBFUIO_CONTEXT_FROM_PROTOCOL (This);
> +
> +  if (UsbFuncIoDevPtr->StartUpController == FALSE) {
> +    UsbFnInitDevice (This);
> +  }
> +  OriginalTpl = gBS->RaiseTPL (TPL_HIGH_LEVEL);
> +  *Message = EfiUsbMsgNone;
> +  MaxIntNum = (UsbRegRead ((UINT32)UsbFuncIoDevPtr->XdciMmioBarAddr, DWC_XDCI_GHWPARAMS1_REG) &
> +                 DWC_XDCI_GHWPARAMS1_NUM_INT_MASK) >>
> +                 DWC_XDCI_GHWPARAMS1_NUM_INT_BIT_POS;
> +
> +  UsbDeviceCorePtr = UsbFuncIoDevPtr->DrvCore;
> +  XdciCorePtr = UsbDeviceCorePtr->ControllerHandle;
> +  EventFlag = TRUE;
> +
> +  DEBUG ((USB_FUIO_DEBUG_EVENT_I, "XdciCorePtr->MaxDevIntLines 0x%08x\n", XdciCorePtr->MaxDevIntLines));
> +  EventCount = UsbRegRead ((UINT32)UsbFuncIoDevPtr->XdciMmioBarAddr, DWC_XDCI_EVNTCOUNT_REG(0));
> +
> +  for (IntIndex = 0; IntIndex < XdciCorePtr->MaxDevIntLines ; IntIndex++) {
> +    //
> +    // Get the number of events HW has written for this
> +    //  interrupt line
> +    //
> +    EventCount = UsbRegRead ((UINT32)UsbFuncIoDevPtr->XdciMmioBarAddr, DWC_XDCI_EVNTCOUNT_REG(IntIndex));
> +    EventCount &= DWC_XDCI_EVNTCOUNT_MASK;
> +    PeventCount = 0;
> +
> +    //
> +    // Process interrupt line Buffer only if count is non-zero
> +    //
> +    if (EventCount) {
> +      //
> +      // Process events in this Buffer
> +      //
> +      ProcessIntLineEvents (
> +        This,
> +        EventCount,
> +        &PeventCount,
> +        Message,
> +        PayloadSize,
> +        Payload,
> +        &EventFlag
> +        );
> +
> +      //
> +      // Write back the Processed number of events so HW decrements it from current
> +      // event count
> +      //
> +      UsbRegWrite ((UINT32)UsbFuncIoDevPtr->XdciMmioBarAddr, DWC_XDCI_EVNTCOUNT_REG(IntIndex), PeventCount);
> +
> +      //
> +      // for debug
> +      //
> +      if (*Message != EfiUsbMsgNone) {
> +        break;
> +      }
> +
> +      if (EventFlag == TRUE) {
> +        break;
> +      }
> +    }
> +  }
> +
> +  gBS->RestoreTPL (OriginalTpl);
> +  //
> +  //EVENT_EXIT:
> +  //
> +  DEBUG ((USB_FUIO_DEBUG_EVENT_I, "USBFU_ EventHandler Exit\n"));
> +  return EFI_SUCCESS;
> +}
> +
> +
> +
> +/**
> +  Copies relevant endpoint data from standard USB endpoint descriptors
> +  to the usbEpInfo structure used by the XDCI
> +
> +  @param pEpDest   destination structure
> +  @param pEpSrc    source structure
> +
> +  @return VOID
> +
> +**/
> +VOID
> +UsbFnSetEpInfo (
> +  IN USB_EP_INFO                 *EpDest,
> +  IN USB_DEVICE_ENDPOINT_INFO    *EpSrc
> +  )
> +{
> +  EFI_USB_ENDPOINT_DESCRIPTOR              *EpDesc = NULL;
> +  EFI_USB_ENDPOINT_COMPANION_DESCRIPTOR    *EpCompDesc = NULL;
> +
> +  //
> +  // start by clearing all data in the destination
> +  //
> +  SetMem (EpDest, sizeof(USB_EP_INFO), 0);
> +  EpDesc = EpSrc->EndpointDesc;
> +  EpCompDesc = EpSrc->EndpointCompDesc;
> +
> +  if (EpDesc != NULL) {
> +    EpDest->EpNum = EpDesc->EndpointAddress & 0x0F; // Bits 0-3 are ep num
> +    EpDest->EpDir = ((EpDesc->EndpointAddress & USB_ENDPOINT_DIR_IN) > 0) ? UsbEpDirIn : UsbEpDirOut;
> +    DEBUG ((DEBUG_INFO, "EpDest->EpNum 0x%02x\n", EpDest->EpNum));
> +    DEBUG ((DEBUG_INFO, "EpDest->EpDir 0x%02x\n", EpDest->EpDir));
> +    EpDest->EpType = EpDesc->Attributes & USB_ENDPOINT_TYPE_MASK;
> +    EpDest->MaxPktSize = EpDesc->MaxPacketSize;
> +    EpDest->Interval = EpDesc->Interval;
> +  }
> +  if (EpCompDesc != NULL) {
> +    EpDest->MaxStreams = EpCompDesc->Attributes & USB_EP_BULK_BM_ATTR_MASK;
> +    EpDest->BurstSize = EpCompDesc->MaxBurst;
> +    EpDest->Mult = EpCompDesc->BytesPerInterval;
> +  }
> +
> +  return;
> +}
> +
> +
> +EFI_STATUS
> +SetFnIoReqInfo(
> +  IN     EFI_USBFN_IO_PROTOCOL         *This,
> +  IN     UINT8                         EndpointIndex,
> +  IN     EFI_USBFN_ENDPOINT_DIRECTION  Direction,
> +  IN OUT UINTN                         *BufferSize,
> +  IN OUT VOID                          *Buffer,
> +  IN OUT USB_XFER_REQUEST              *XfIoreq
> +  )
> +{
> +  USB_XDCI_DEV_CONTEXT     *UsbFuncIoDevPtr;
> +  EFI_STATUS               Status;
> +  UINTN                    ReqPacket;
> +
> +  UsbFuncIoDevPtr = USBFUIO_CONTEXT_FROM_PROTOCOL (This);
> +  Status = EFI_SUCCESS;
> +  ReqPacket = 0;
> +
> +  switch (EndpointIndex) {
> +    case 0: // Control endpoint
> +      XfIoreq->EpInfo.EpNum = 0;
> +      XfIoreq->EpInfo.EpDir = Direction? UsbEpDirIn : UsbEpDirOut;
> +      break;
> +
> +
> +    default:
> +      if (Direction == EfiUsbEndpointDirectionDeviceTx) {
> +        UsbFnSetEpInfo (&XfIoreq->EpInfo, &UsbFuncIoDevPtr->IndexPtrInEp);
> +      } else {
> +        UsbFnSetEpInfo (&XfIoreq->EpInfo, &UsbFuncIoDevPtr->IndexPtrOutEp);
> +        //
> +        // reference from "UsbDeviceMode.c", function UsbdEpRxData
> +        //
> +
> +        //
> +        // Transfer length should be multiple of USB packet size.
> +        //
> +        ReqPacket = *BufferSize/ XfIoreq->EpInfo.MaxPktSize;
> +        ReqPacket = ((XfIoreq->XferLen % XfIoreq->EpInfo.MaxPktSize) == 0)? ReqPacket : ReqPacket + 1;
> +        XfIoreq->XferLen = (UINT32)ReqPacket * XfIoreq->EpInfo.MaxPktSize;
> +
> +      }
> +      break;
> +  }
> +
> +  if (EFI_ERROR(Status)) {
> +    return EFI_UNSUPPORTED;
> +  }
> +
> +  XfIoreq->XferBuffer = Buffer;
> +  XfIoreq->XferLen = (UINT32)(*BufferSize);
> +  XfIoreq->XferDone = NULL;
> +
> +  return EFI_SUCCESS;
> +}
> +
> +
> +/**
> +  Primary function to handle transfer in either direction Based on specified
> +  direction and on the specified endpoint.
> +
> +  @param[in]  This              A pointer to the EFI_USBFN_IO_PROTOCOL instance.
> +  @param[in]  EndpointIndex     Indicates the endpoint on which TX or RX transfer
> +                                needs to take place.
> +  @param[in]  Direction         Direction of the endpoint.
> +  @param[in]  BufferSize        If Direction is EfiUsbEndpointDirectionDeviceRx:
> +                                On input, the size of the Buffer in bytes.
> +                                On output, the amount of data returned in Buffer in bytes.
> +                                If Direction is EfiUsbEndpointDirectionDeviceTx:
> +                                On input, the size of the Buffer in bytes.
> +                                On output, the amount of data actually transmitted in bytes.
> +  @param[in]  Buffer            If Direction is EfiUsbEndpointDirectionDeviceRx:
> +                                The Buffer to return the received data.
> +                                If Direction is EfiUsbEndpointDirectionDeviceTx:
> +                                The Buffer that contains the data to be transmitted.
> +
> +  @retval EFI_SUCCESS           The function returned successfully.
> +  @retval EFI_INVALID_PARAMETER A parameter is invalid.
> +  @retval EFI_DEVICE_ERROR      The physical device reported an error.
> +  @retval EFI_NOT_READY         The physical device is busy or not ready to
> +                                process this request.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +Transfer (
> +  IN EFI_USBFN_IO_PROTOCOL         *This,
> +  IN UINT8                         EndpointIndex,
> +  IN EFI_USBFN_ENDPOINT_DIRECTION  Direction,
> +  IN OUT UINTN                     *BufferSize,
> +  IN OUT VOID                      *Buffer
> +  )
> +{
> +  USB_XDCI_DEV_CONTEXT              *UsbFuncIoDevPtr;
> +  USB_DEV_CORE                      *UsbDeviceCorePtr;
> +  XDCI_CORE_HANDLE                  *XdciCorePtr;
> +  EFI_STATUS                        Status;
> +  USB_XFER_REQUEST                  XferReq;
> +  UINT32                            EndPoint;
> +
> +  DEBUG ((USB_FUIO_DEBUG_LOAD, "\n FU:Transfer - Entry\n"));
> +  DEBUG ((USB_FUIO_DEBUG_LOAD, "\n FU:EndpointIndex 0x%02x\n", EndpointIndex));
> +  DEBUG ((USB_FUIO_DEBUG_LOAD, "\n FU:Direction 0x%02x\n", Direction));
> +
> +  UsbFuncIoDevPtr = USBFUIO_CONTEXT_FROM_PROTOCOL (This);
> +
> +  UsbDeviceCorePtr = UsbFuncIoDevPtr->DrvCore;
> +  XdciCorePtr = UsbDeviceCorePtr->ControllerHandle;
> +  EndPoint = UsbGetPhysicalEpNum (EndpointIndex, Direction ? UsbEpDirIn : UsbEpDirOut);
> +
> +  Status = SetFnIoReqInfo (
> +             This,
> +             EndpointIndex,
> +             Direction,
> +             BufferSize,
> +             Buffer,
> +             &XferReq
> +             );
> +
> +  if (EFI_ERROR(Status)) {
> +    DEBUG ((USB_FUIO_DEBUG_LOAD, "Set SetFnIoReqInfo - Error Stop!!!\n"));
> +    while(1);
> +    Status = EFI_DEVICE_ERROR;
> +    goto FUN_EXIT;
> +  }
> +
> +  UsbFuncIoDevPtr->EndPointXferRec[EndPoint].EpNum = EndPoint;
> +  UsbFuncIoDevPtr->EndPointXferRec[EndPoint].Direction = Direction;
> +  UsbFuncIoDevPtr->EndPointXferRec[EndPoint].XferAddress = (UINTN)Buffer;
> +  UsbFuncIoDevPtr->EndPointXferRec[EndPoint].XferLength = (UINT32)(*BufferSize);
> +  UsbFuncIoDevPtr->EndPointXferRec[EndPoint].LogEpNum = EndpointIndex;
> +  UsbFuncIoDevPtr->EndPointXferRec[EndPoint].Complete = FALSE;
> +  UsbFuncIoDevPtr->EndPointXferRec[EndPoint].ZlpFlag = FALSE;
> +
> +  Status = EFI_DEVICE_ERROR;
> +  switch (EndpointIndex) {
> +    case 0: // Control endpoint
> +      if (*BufferSize == 0) {
> +        if (Direction == EfiUsbEndpointDirectionDeviceTx) {
> +          Status = UsbDeviceEp0TxStatus(UsbDeviceCorePtr);
> +        } else {
> +          Status = UsbDeviceEp0RxStatus(UsbDeviceCorePtr);
> +        }
> +      } else if (Direction == EfiUsbEndpointDirectionDeviceTx) {
> +        Status = UsbXdciDeviceEpTxData(UsbDeviceCorePtr, &XferReq);
> +      } else if (Direction == EfiUsbEndpointDirectionDeviceRx) {
> +        DEBUG ((USB_FUIO_DEBUG_LOAD, "\n Set Setup Package - ??? Stop!!!\n"));
> +      }
> +      break;
> +
> +    default:
> +      Status = EFI_SUCCESS;
> +      if (Direction == EfiUsbEndpointDirectionDeviceTx) {
> +        DEBUG ((USB_FUIO_DEBUG_LOAD, "\n EfiUsbEndpointDirectionDeviceTx Size = %d\n",(*BufferSize) ));
> +        XferReq.Zlp = TRUE;
> +        if ((((*BufferSize) % 512) == 0) && ((*BufferSize) != 0)) {
> +          UsbFuncIoDevPtr->EndPointXferRec[EndPoint].ZlpFlag = TRUE;
> +          DEBUG ((USB_FUIO_DEBUG_LOAD, "\n Set Zlp flag\n"));
> +        }
> +        Status = UsbXdciDeviceEpTxData (UsbDeviceCorePtr, &XferReq);
> +      } else {
> +        DEBUG ((USB_FUIO_DEBUG_LOAD, "\n EfiUsbEndpointDirectionDeviceRx Size = %d\n",(*BufferSize) ));
> +        Status = UsbXdciDeviceEpRxData (UsbDeviceCorePtr, &XferReq);
> +      }
> +      break;
> +  }
> +
> +  if (EFI_ERROR(Status)) {
> +    goto FUN_EXIT;
> +  }
> +
> +  if (Status != EFI_SUCCESS) {
> +    Status = EFI_DEVICE_ERROR;
> +  }
> +
> +FUN_EXIT:
> +
> +  DEBUG ((USB_FUIO_DEBUG_LOAD, "FU:Transfer - Exit %r\n", Status));
> +  return Status;
> +}
> +
> +
> +/**
> +  This function supplies power to the USB controller if needed, initialize
> +  hardware and internal data structures, and then return.
> +  The port must not be activated by this function.
> +
> +  @param[in]  This              A pointer to the EFI_USBFN_IO_PROTOCOL instance.
> +
> +  @retval EFI_SUCCESS           The function returned successfully.
> +  @retval EFI_INVALID_PARAMETER A parameter is invalid.
> +  @retval EFI_DEVICE_ERROR      The physical device reported an error.
> +**/
> +EFI_STATUS
> +EFIAPI
> +StartXdciController (
> +  IN EFI_USBFN_IO_PROTOCOL    *This
> +  )
> +{
> +  USB_XDCI_DEV_CONTEXT         *UsbFuncIoDevPtr;
> +  USB_DEV_CONFIG_PARAMS        ConfigParams;
> +  EFI_STATUS                   Status;
> +
> +  Status = EFI_SUCCESS;
> +  UsbFuncIoDevPtr = USBFUIO_CONTEXT_FROM_PROTOCOL (This);
> +
> +  if (UsbFuncIoDevPtr->StartUpController == TRUE) {
> +    goto EXIT_START_CONTROLLER;
> +  }
> +
> +  ConfigParams.ControllerId = USB_ID_DWC_XDCI;
> +  ConfigParams.BaseAddress = (UINT32)UsbFuncIoDevPtr->XdciMmioBarAddr;
> +  ConfigParams.Role = USB_ROLE_DEVICE;
> +  ConfigParams.Speed = USB_SPEED_HIGH;
> +
> +  //
> +  //*Vid = 0x8086
> +  //*Pid = 0x0A65
> +  //
> +  UsbFuncIoDevPtr->VendorId = USBFU_VID;
> +  UsbFuncIoDevPtr->DeviceId = USBFU_PID;
> +  UsbFuncIoDevPtr->StartUpController = TRUE;
> +
> +  Status = UsbDeviceInit (&ConfigParams, (VOID **)&UsbFuncIoDevPtr->DrvCore);
> +  if (Status != EFI_SUCCESS) {
> +    Status = EFI_DEVICE_ERROR;
> +    goto EXIT_START_CONTROLLER;
> +  }
> +
> +  UsbFuncIoDevPtr->XdciDrvIfHandle = UsbFuncIoDevPtr->DrvCore->ControllerHandle;
> +
> +EXIT_START_CONTROLLER:
> +
> +  DEBUG ((USB_FUIO_DEBUG_LOAD, "StartXdciController - Exit :: %r\n", Status));
> +  return Status;
> +}
> +
> +
> +/**
> +  This function disables the hardware device by resetting the run/stop bit
> +  and power off the USB controller if needed.
> +
> +  @param[in]  This              A pointer to the EFI_USBFN_IO_PROTOCOL instance.
> +
> +  @retval EFI_SUCCESS           The function returned successfully.
> +  @retval EFI_INVALID_PARAMETER A parameter is invalid.
> +  @retval EFI_DEVICE_ERROR      The physical device reported an error.
> +**/
> +EFI_STATUS
> +EFIAPI
> +StopXdciController (
> +  IN EFI_USBFN_IO_PROTOCOL    *This
> +  )
> +{
> +  USB_XDCI_DEV_CONTEXT  *UsbFuncIoDevPtr;
> +  EFI_STATUS            DevStatus;
> +
> +  UsbFuncIoDevPtr = USBFUIO_CONTEXT_FROM_PROTOCOL (This);
> +  DEBUG ((USB_FUIO_DEBUG_LOAD, "StopController - Entry\n"));
> +
> +  if (UsbFuncIoDevPtr->StartUpController == FALSE) {
> +    DEBUG ((USB_FUIO_DEBUG_LOAD, "The Controller not yet start up skip deinit\n"));
> +    return EFI_SUCCESS;
> +  }
> +
> +  if (This == NULL) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  DevStatus = UsbDeviceDeinit (UsbFuncIoDevPtr->DrvCore, TRUE);
> +
> +  UsbFuncIoDevPtr->DrvCore = NULL;
> +  UsbFuncIoDevPtr->XdciDrvIfHandle = NULL;
> +  UsbFuncIoDevPtr->StartUpController = FALSE;
> +
> +  if (DevStatus != EFI_SUCCESS) {
> +    return EFI_DEVICE_ERROR;
> +  }
> +
> +  DEBUG ((USB_FUIO_DEBUG_LOAD, "StopController - Exit\n"));
> +  return EFI_SUCCESS;
> +}
> +
> +
> +/**
> +  This function sets the configuration policy for the specified non-control endpoint.
> +  Refer to the description for calling restrictions
> +
> +  @param[in]  This              A pointer to the EFI_USBFN_IO_PROTOCOL instance.
> +  @param[in]  EndpointIndex     Indicates the non-control endpoint for
> +                                which the policy needs to be set.
> +  @param[in]  Direction         Direction of the endpoint.
> +  @param[in]  PolicyType        Policy type the user is trying to set for
> +                                the specified non-control endpoint.
> +  @param[in]  BufferSize        The size of the Buffer in bytes.
> +  @param[in]  Buffer            The new value for the policy parameter that
> +                                PolicyType specifies.
> +
> +
> +  @retval EFI_SUCCESS           The function returned successfully.
> +  @retval EFI_INVALID_PARAMETER A parameter is invalid.
> +  @retval EFI_DEVICE_ERROR      The physical device reported an error.
> +  @retval EFI_UNSUPPORTED       Changing this policy value is not supported.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +SetEndpointPolicy (
> +  IN EFI_USBFN_IO_PROTOCOL        *This,
> +  IN UINT8                        EndpointIndex,
> +  IN EFI_USBFN_ENDPOINT_DIRECTION Direction,
> +  IN EFI_USBFN_POLICY_TYPE        PolicyType,
> +  IN UINTN                        BufferSize,
> +  IN VOID                         *Buffer
> +  )
> +{
> +  USB_XDCI_DEV_CONTEXT  *UsbFuncIoDevPtr;
> +  EFI_STATUS            Status;
> +  UINT32                EndPoint;
> +  UINT8                 *FlagPtr;
> +
> +  UsbFuncIoDevPtr = USBFUIO_CONTEXT_FROM_PROTOCOL (This);
> +  FlagPtr = NULL;
> +
> +  switch (PolicyType) {
> +    case EfiUsbPolicyUndefined:
> +    case EfiUsbPolicyMaxTransactionSize:
> +    case EfiUsbPolicyZeroLengthTerminationSupport:
> +
> +     Status = EFI_UNSUPPORTED;
> +     break;
> +
> +    default:
> +     FlagPtr = Buffer;
> +     Status = EFI_SUCCESS;
> +     break;
> +  }
> +
> +  if (BufferSize < 1) {
> +    Status = EFI_INVALID_PARAMETER;
> +  }
> +
> +  if (EFI_ERROR(Status)) {
> +    DEBUG ((USB_FUIO_DEBUG_LOAD, "SetEndpointPolicy - ERROR %r\n", Status));
> +    return Status;
> +  }
> +
> +  EndPoint = UsbGetPhysicalEpNum (EndpointIndex, Direction ? UsbEpDirIn : UsbEpDirOut);
> +
> +  UsbFuncIoDevPtr->EndPointXferRec[EndPoint].ZlpFlag = *FlagPtr;
> +
> +  return Status;
> +}
> +
> +
> +/**
> +  This function retrieves the configuration policy for the specified non-control
> +  endpoint. There are no associated calling restrictions for this function.
> +
> +  @param[in]  This              A pointer to the EFI_USBFN_IO_PROTOCOL instance.
> +  @param[in]  EndpointIndex     Indicates the non-control endpoint for
> +                                which the policy needs to be set.
> +  @param[in]  Direction         Direction of the endpoint.
> +  @param[in]  PolicyType        Policy type the user is trying to set for
> +                                the specified non-control endpoint.
> +  @param[in]  BufferSize        The size of the Buffer in bytes.
> +  @param[in]  Buffer            The new value for the policy parameter that
> +                                PolicyType specifies.
> +
> +
> +  @retval EFI_SUCCESS           The function returned successfully.
> +  @retval EFI_INVALID_PARAMETER A parameter is invalid.
> +  @retval EFI_DEVICE_ERROR      The physical device reported an error.
> +  @retval EFI_UNSUPPORTED       Changing this policy value is not supported.
> +  @retval EFI_BUFFER_TOO_SMALL  Supplied Buffer is not large enough to
> +                                hold requested policy value.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +GetEndpointPolicy (
> +  IN EFI_USBFN_IO_PROTOCOL        *This,
> +  IN UINT8                        EndpointIndex,
> +  IN EFI_USBFN_ENDPOINT_DIRECTION Direction,
> +  IN EFI_USBFN_POLICY_TYPE        PolicyType,
> +  IN OUT UINTN                    *BufferSize,
> +  IN OUT VOID                     *Buffer
> +  )
> +{
> +  USB_XDCI_DEV_CONTEXT  *UsbFuncIoDevPtr;
> +  EFI_STATUS            Status;
> +  UINT32                EndPoint;
> +  UINT32                MaxPacketSize;
> +  BOOLEAN               SetFlag;
> +
> +  UsbFuncIoDevPtr = USBFUIO_CONTEXT_FROM_PROTOCOL (This);
> +  MaxPacketSize = 0;
> +  SetFlag = FALSE;
> +
> +  switch (PolicyType) {
> +    case EfiUsbPolicyUndefined:
> +
> +     Status = EFI_UNSUPPORTED;
> +     break;
> +
> +    case EfiUsbPolicyMaxTransactionSize:
> +    case EfiUsbPolicyZeroLengthTerminationSupport:
> +    default:
> +     if (Buffer == NULL) {
> +       Status = EFI_INVALID_PARAMETER;
> +     } else {
> +       Status = EFI_SUCCESS;
> +     }
> +     break;
> +  }
> +
> +  EndPoint = UsbGetPhysicalEpNum (EndpointIndex, Direction ? UsbEpDirIn : UsbEpDirOut);
> +
> +  if (EFI_ERROR(Status)) {
> +    DEBUG ((USB_FUIO_DEBUG_LOAD, "GetEndpointPolicy - ERROR %r\n", Status));
> +    return Status;
> +  }
> +
> +  if (PolicyType == EfiUsbPolicyMaxTransactionSize) {
> +
> +    if (*BufferSize < sizeof(UINT32)) {
> +       Status = EFI_INVALID_PARAMETER;
> +    } else {
> +      MaxPacketSize = MAX_TRANSFER_PACKET;
> +      CopyMem (Buffer, &MaxPacketSize, sizeof(UINT32));
> +    }
> +
> +  } else if (PolicyType == EfiUsbPolicyZeroLengthTerminationSupport) {
> +    if (*BufferSize < sizeof(BOOLEAN)) {
> +       Status = EFI_INVALID_PARAMETER;
> +    } else {
> +      SetFlag = TRUE;
> +      CopyMem (Buffer, &SetFlag, sizeof(BOOLEAN));
> +    }
> +
> +  } else if (PolicyType == EfiUsbPolicyZeroLengthTermination) {
> +    if (*BufferSize < sizeof(BOOLEAN)) {
> +       Status = EFI_INVALID_PARAMETER;
> +    } else {
> +      SetFlag =  UsbFuncIoDevPtr->EndPointXferRec[EndPoint].ZlpFlag;
> +      CopyMem (Buffer, &SetFlag, sizeof(BOOLEAN));
> +    }
> +  } else {
> +    Status = EFI_INVALID_PARAMETER;
> +  }
> +
> +  return Status;
> +}
> +
> +EFI_STATUS
> +UsbFnInitDevice (
> +  IN EFI_USBFN_IO_PROTOCOL        *This
> +  )
> +{
> +  EFI_STATUS                   Status;
> +  USB_XDCI_DEV_CONTEXT         *UsbFuncIoDevPtr;
> +
> +  Status = EFI_SUCCESS;
> +  UsbFuncIoDevPtr = USBFUIO_CONTEXT_FROM_PROTOCOL (This);
> +
> +  PlatformSpecificInit ();
> +
> +  UsbFuncIoDevPtr->StartUpController = FALSE;
> +  Status = StartXdciController (&UsbFuncIoDevPtr->UsbFunIoProtocol);
> +  if (EFI_ERROR (Status)) {
> +    Status = EFI_DEVICE_ERROR;
> +    goto DEV_INIT_EXIT;
> +  }
> +
> +  Status = UsbXdciDeviceConnect (UsbFuncIoDevPtr->DrvCore);
> +  DEBUG ((USB_FUIO_DEBUG_LOAD, "UsbXdciDeviceConnect Status %x\n", Status));
> +  if (Status != EFI_SUCCESS) {
> +    Status = EFI_DEVICE_ERROR;
> +    goto DEV_INIT_EXIT;
> +  }
> +
> +
> +DEV_INIT_EXIT:
> +
> +  return Status;
> +}
> +
> +EFI_STATUS
> +EFIAPI
> +StartController (
> +  IN EFI_USBFN_IO_PROTOCOL        *This
> +  )
> +{
> +  return EFI_SUCCESS;
> +}
> +
> +
> +EFI_STATUS
> +UsbFnDeInitDevice (
> +  IN EFI_USBFN_IO_PROTOCOL        *This
> +  )
> +{
> +  EFI_STATUS                   Status;
> +  USB_XDCI_DEV_CONTEXT         *UsbFuncIoDevPtr;
> +
> +  UsbFuncIoDevPtr = USBFUIO_CONTEXT_FROM_PROTOCOL (This);
> +
> +  if (UsbFuncIoDevPtr->StartUpController == FALSE) {
> +    DEBUG ((USB_FUIO_DEBUG_LOAD, "UsbFn:StopController:The Controller not yet start up force return EFI_SUCCESS\n"));
> +    return EFI_SUCCESS;
> +  }
> +
> +  //
> +  // disconnect
> +  //
> +  Status = UsbDeviceDisconnect (UsbFuncIoDevPtr->DrvCore);
> +  DEBUG ((USB_FUIO_DEBUG_LOAD, "UsbDeviceDisconnect Status %x\n", Status));
> +  if (Status != EFI_SUCCESS) {
> +    Status = EFI_DEVICE_ERROR;
> +    goto DEV_DEINIT_EXIT;
> +  }
> +
> +  //
> +  // StopController
> +  //
> +  Status = StopXdciController (&UsbFuncIoDevPtr->UsbFunIoProtocol);
> +  UsbFuncIoDevPtr->StartUpController = FALSE;
> +
> +DEV_DEINIT_EXIT:
> +  return Status;
> +}
> +
> +EFI_STATUS
> +EFIAPI
> +StopController (
> +  IN EFI_USBFN_IO_PROTOCOL        *This
> +  )
> +{
> +  return UsbFnDeInitDevice(This);
> +}
> +
> diff --git a/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbFuncIo.h b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbFuncIo.h
> new file mode 100644
> index 0000000000..ad3d296db9
> --- /dev/null
> +++ b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbFuncIo.h
> @@ -0,0 +1,234 @@
> +/** @file
> +  Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR>
> +
> +  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.
> +
> +**/
> +
> +#ifndef __EFI_USB_FUNCTION_IO_INTERFACE_H__
> +#define __EFI_USB_FUNCTION_IO_INTERFACE_H__
> +
> +#include <Uefi.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/DevicePathLib.h>
> +#include <Library/DriverLib.h>
> +#include <Library/PcdLib.h>
> +#include <Protocol/EfiUsbFnIo.h>
> +#include <Library/PmicLib.h>
> +#include <Library/UsbDeviceLib.h>
> +#include <Library/PrintLib.h>
> +#include "UsbIoNode.h"
> +#include "XdciDWC.h"
> +#include "UsbDeviceMode.h"
> +
> +//
> +// Debug message setting
> +//
> +#define USB_FUIO_DEBUG_INFO              EFI_D_INFO
> +#define USB_FUIO_DEBUG_LOAD              EFI_D_LOAD
> +#define USB_FUIO_DEBUG_ERROR             EFI_D_ERROR
> +#define USB_FUIO_DEBUG_EVENT_I           0 //DEBUG_INIT
> +#define USB_FUIO_DEBUG_EVENT_D           EFI_D_ERROR
> +#define USB_FUIO_DEBUG_EVENT_NOTREADY_D  EFI_D_ERROR
> +#define USB_FUIO_DEBUG_EVENT_NOTREADY_I  0 //DEBUG_INIT
> +
> +#define MAX_TRANSFER_PACKET     (8 * 1024 * 1024)
> +
> +#define USBFU_VID     0x8086
> +#define USBFU_PID     0x0A65
> +
> +#pragma pack(1)
> +typedef struct {
> +  UINT8                     ProgInterface;
> +  UINT8                     SubClassCode;
> +  UINT8                     BaseCode;
> +} USB_CLASSC;
> +
> +//
> +// Event Buffer Struct
> +//
> +typedef struct  {
> +  UINT32 Event;
> +  UINT32 DevTstLmp1;
> +  UINT32 DevTstLmp2;
> +  UINT32 Reserved;
> +} USBD_EVENT_BUF;
> +
> +typedef struct  {
> +  UINT32                        EpNum;
> +  EFI_USBFN_ENDPOINT_DIRECTION  Direction;
> +  UINTN                         XferAddress;
> +  UINT32                        XferLength;
> +  UINT8                         LogEpNum;
> +  BOOLEAN                       Complete;
> +  BOOLEAN                       ZlpFlag;
> +} USBD_EP_XFER_REC;
> +
> +#pragma pack()
> +
> +EFI_STATUS
> +UsbFnInitDevice (
> +  IN EFI_USBFN_IO_PROTOCOL        *This
> +  );
> +
> +EFI_STATUS
> +UsbFnDeInitDevice (
> +  IN EFI_USBFN_IO_PROTOCOL        *This
> +  );
> +
> +EFI_STATUS
> +EFIAPI
> +DetectPort (
> +  IN EFI_USBFN_IO_PROTOCOL         *This,
> +  OUT EFI_USBFN_PORT_TYPE          *PortType
> +  );
> +
> +EFI_STATUS
> +EFIAPI
> +AllocateTransferBuffer (
> +  IN EFI_USBFN_IO_PROTOCOL         *This,
> +  IN UINTN                         Size,
> +  OUT VOID                         **Buffer
> +  );
> +
> +EFI_STATUS
> +EFIAPI
> +FreeTransferBuffer (
> +  IN EFI_USBFN_IO_PROTOCOL         *This,
> +  IN VOID                          *Buffer
> +  );
> +
> +EFI_STATUS
> +EFIAPI
> +ConfigureEnableEndpoints (
> +  IN EFI_USBFN_IO_PROTOCOL         *This,
> +  IN EFI_USB_DEVICE_INFO           *DeviceInfo
> + );
> +
> +EFI_STATUS
> +EFIAPI
> +GetEndpointMaxPacketSize (
> +  IN EFI_USBFN_IO_PROTOCOL         *This,
> +  IN EFI_USB_ENDPOINT_TYPE         EndpointType,
> +  IN EFI_USB_BUS_SPEED             BusSpeed,
> +  OUT UINT16                       *MaxPacketSize
> + );
> +
> +EFI_STATUS
> +EFIAPI
> +GetMaxTransferSize (
> +  IN EFI_USBFN_IO_PROTOCOL         *This,
> +  OUT UINTN                        *MaxTransferSize
> +  );
> +
> +EFI_STATUS
> +EFIAPI
> +GetDeviceInfo (
> +  IN EFI_USBFN_IO_PROTOCOL         *This,
> +  IN EFI_USBFN_DEVICE_INFO_ID      Id,
> +  IN OUT UINTN                     *BufferSize,
> +  OUT VOID                         *Buffer OPTIONAL
> +  );
> +
> +EFI_STATUS
> +EFIAPI
> +GetVendorIdProductId (
> +  IN EFI_USBFN_IO_PROTOCOL         *This,
> +  OUT UINT16                       *Vid,
> +  OUT UINT16                       *Pid
> +  );
> +
> +EFI_STATUS
> +EFIAPI
> +AbortTransfer (
> +  IN EFI_USBFN_IO_PROTOCOL        *This,
> +  IN UINT8                        EndpointIndex,
> +  IN EFI_USBFN_ENDPOINT_DIRECTION Direction
> +  );
> +
> +EFI_STATUS
> +EFIAPI
> +GetEndpointStallState (
> +  IN EFI_USBFN_IO_PROTOCOL         *This,
> +  IN UINT8                         EndpointIndex,
> +  IN EFI_USBFN_ENDPOINT_DIRECTION  Direction,
> +  IN OUT BOOLEAN                   *State
> +  );
> +
> +EFI_STATUS
> +EFIAPI
> +SetEndpointStallState (
> +  IN EFI_USBFN_IO_PROTOCOL         *This,
> +  IN UINT8                         EndpointIndex,
> +  IN EFI_USBFN_ENDPOINT_DIRECTION  Direction,
> +  IN BOOLEAN                       State
> +  );
> +
> +EFI_STATUS
> +EFIAPI
> +EventHandler (
> +  IN EFI_USBFN_IO_PROTOCOL         *This,
> +  OUT EFI_USBFN_MESSAGE            *Message,
> +  IN OUT UINTN                     *PayloadSize,
> +  OUT EFI_USBFN_MESSAGE_PAYLOAD    *Payload
> +  );
> +
> +EFI_STATUS
> +EFIAPI
> +Transfer (
> +  IN EFI_USBFN_IO_PROTOCOL         *This,
> +  IN UINT8                         EndpointIndex,
> +  IN EFI_USBFN_ENDPOINT_DIRECTION  Direction,
> +  IN OUT UINTN                     *BufferSize,
> +  IN OUT VOID                      *Buffer
> +  );
> +
> +EFI_STATUS
> +EFIAPI
> +StartController (
> +  IN EFI_USBFN_IO_PROTOCOL         *This
> +  );
> +
> +EFI_STATUS
> +EFIAPI
> +StopController (
> +  IN EFI_USBFN_IO_PROTOCOL         *This
> +  );
> +
> +EFI_STATUS
> +EFIAPI
> +SetEndpointPolicy (
> +  IN EFI_USBFN_IO_PROTOCOL         *This,
> +  IN UINT8                         EndpointIndex,
> +  IN EFI_USBFN_ENDPOINT_DIRECTION  Direction,
> +  IN EFI_USBFN_POLICY_TYPE         PolicyType,
> +  IN UINTN                         BufferSize,
> +  IN VOID                          *Buffer
> +  );
> +
> +EFI_STATUS
> +EFIAPI
> +GetEndpointPolicy (
> +  IN EFI_USBFN_IO_PROTOCOL         *This,
> +  IN UINT8                         EndpointIndex,
> +  IN EFI_USBFN_ENDPOINT_DIRECTION  Direction,
> +  IN EFI_USBFN_POLICY_TYPE         PolicyType,
> +  IN OUT UINTN                     *BufferSize,
> +  IN OUT VOID                      *Buffer
> +  );
> +
> +VOID
> +UsbFnSetEpInfo (
> +  IN USB_EP_INFO                 *EpDest,
> +  IN USB_DEVICE_ENDPOINT_INFO    *EpSrc
> +  );
> +
> +extern EFI_USBFN_IO_PROTOCOL         mUsbFunIoProtocol;
> +#endif
> +
> diff --git a/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbIoNode.c b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbIoNode.c
> new file mode 100644
> index 0000000000..8fc6e10046
> --- /dev/null
> +++ b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbIoNode.c
> @@ -0,0 +1,177 @@
> +/** @file
> +  Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR>
> +
> +  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.
> +
> +**/
> +
> +#include "UsbDeviceDxe.h"
> +
> +
> +/**
> +  The SearchNode function search a memory address for record the driver allocate
> +  memory region and the node to the head link list.
> +
> +  @param[in]  This              A pointer to the EFI_USBFN_IO_PROTOCOL instance.
> +  @param[in]  Buffer            The driver alocate memory address.
> +  @param[out] Node              The match node record of the driver aloocate
> +                                memory region.
> +  @param[out] PNode             The pervious match node record of the driver
> +                                aloocate memory region.
> +
> +  @retval EFI_SUCCESS           The operation completed successfully.
> +  @retval EFI_NOT_FOUND         The memory Buffer didn't find.
> +**/
> +EFI_STATUS
> +SearchNode (
> +  IN  EFI_USBFN_IO_PROTOCOL    *This,
> +  IN  VOID                     *Buffer,
> +  OUT USB_MEM_NODE             **Node,
> +  OUT USB_MEM_NODE             **PNode
> +  )
> +{
> +  USB_XDCI_DEV_CONTEXT *UsbFuncIoDevPtr;
> +  USB_MEM_NODE         *NodeL;
> +  USB_MEM_NODE         *PNodeL;
> +  EFI_STATUS           Status;
> +
> +  DEBUG ((USB_DEBUG_MEM_NODE_INFO, "SearchNode - Entry\n"));
> +
> +  UsbFuncIoDevPtr = USBFUIO_CONTEXT_FROM_PROTOCOL(This);
> +  NodeL = UsbFuncIoDevPtr->FirstNodePtr;
> +  PNodeL = NULL;
> +  Status = EFI_NOT_FOUND;
> +
> +  while (Node != NULL) {
> +    if (NodeL->AllocatePtr == Buffer) {
> +      break;
> +    }
> +
> +    PNodeL = NodeL;
> +    NodeL = NodeL->NextPtr;
> +  }
> +
> +  if (NodeL != NULL && Node != NULL) {
> +    *Node = NodeL;
> +    *PNode = PNodeL;
> +    Status = EFI_SUCCESS;
> +  }
> +
> +  DEBUG ((USB_DEBUG_MEM_NODE_INFO, "SearchNode - Exit %r\n", Status));
> +  return Status;
> +}
> +
> +/**
> +  The InsertNewNodeToHead function remove a memory for record the driver allocate
> +  memory region and the node to the head link list.
> +
> +  @param[in]  This              A pointer to the EFI_USBFN_IO_PROTOCOL instance.
> +  @param[in]  Buffer            The driver alocate memory address.
> +
> +  @retval EFI_SUCCESS           The operation completed successfully.
> +  @retval EFI_NOT_FOUND         The memory Buffer didn't find.
> +**/
> +EFI_STATUS
> +RemoveNode (
> +  IN  EFI_USBFN_IO_PROTOCOL    *This,
> +  IN  VOID                     *Buffer
> +  )
> +{
> +  USB_XDCI_DEV_CONTEXT *UsbFuncIoDevPtr;
> +  USB_MEM_NODE         *Node;
> +  USB_MEM_NODE         *PNode;
> +  EFI_STATUS           Status;
> +
> +  DEBUG ((USB_DEBUG_MEM_NODE_INFO, "RemoveNode - Entry\n"));
> +
> +  UsbFuncIoDevPtr = USBFUIO_CONTEXT_FROM_PROTOCOL (This);
> +
> +  Status = SearchNode (This, Buffer, &Node, &PNode);
> +
> +  if (EFI_ERROR(Status) || PNode == NULL) {
> +    DEBUG ((USB_DEBUG_MEM_NODE_ERROR, "RemoveNode - Node Not Found\n"));
> +    return EFI_NOT_FOUND;
> +  }
> +
> +  if (Node != UsbFuncIoDevPtr->FirstNodePtr) {
> +    PNode->NextPtr = Node->NextPtr;
> +  } else {
> +    UsbFuncIoDevPtr->FirstNodePtr = Node->NextPtr;
> +  }
> +
> +  FreePool (Node->AllocatePtr);
> +  FreePool (Node);
> +  DEBUG ((USB_DEBUG_MEM_NODE_INFO, "RemoveNode - Exit\n"));
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  The InsertNewNodeToHead function allocates a memory for record the driver allocate
> +  memory region and insert the node to the head link list.
> +
> +  @param[in]  This              A pointer to the EFI_USBFN_IO_PROTOCOL instance.
> +  @param[out] USB_MEM_NODE      return the new node address.
> +
> +  @retval EFI_SUCCESS           The operation completed successfully.
> +  @retval EFI_INVALID_PARAMETER A parameter is invalid.
> +  @retval EFI_OUT_OF_RESOURCES  The requested transfer Buffer could not be allocated.
> +
> +**/
> +EFI_STATUS
> +InsertNewNodeToHead (
> +  IN  EFI_USBFN_IO_PROTOCOL    *This,
> +  OUT USB_MEM_NODE             **Node
> +  )
> +{
> +  USB_MEM_NODE         *NewNodePtr;
> +  USB_MEM_NODE         *CurrentNodePtr;
> +  USB_XDCI_DEV_CONTEXT *UsbFuncIoDevPtr;
> +  EFI_STATUS           Status;
> +
> +  DEBUG ((USB_DEBUG_MEM_NODE_INFO, "CreateNewNode - Entry\n"));
> +
> +  if (This == NULL) {
> +    Status = EFI_INVALID_PARAMETER;
> +    goto ErrorExit;
> +  }
> +
> +  UsbFuncIoDevPtr = USBFUIO_CONTEXT_FROM_PROTOCOL(This);
> +
> +  //
> +  // Create the new node
> +  //
> +  NewNodePtr = AllocateZeroPool (sizeof(USB_MEM_NODE));
> +  DEBUG ((USB_DEBUG_MEM_NODE_INFO, "NewNodePtr - Addr = 0x%08x\n",(UINTN)NewNodePtr));
> +
> +  if (NewNodePtr == NULL) {
> +    Status = EFI_OUT_OF_RESOURCES;
> +    goto ErrorExit;
> +  }
> +
> +  //
> +  // insert the new node
> +  //
> +  CurrentNodePtr = UsbFuncIoDevPtr->FirstNodePtr;
> +  UsbFuncIoDevPtr->FirstNodePtr = NewNodePtr;
> +
> +  if (CurrentNodePtr != NULL) {
> +    NewNodePtr->NextPtr = CurrentNodePtr;
> +  }
> +
> +  *Node = NewNodePtr;
> +
> +  DEBUG ((USB_DEBUG_MEM_NODE_INFO, "CreateNewNode - Exit\n"));
> +  return EFI_SUCCESS;
> +
> +ErrorExit:
> +
> +  DEBUG ((USB_DEBUG_MEM_NODE_ERROR, "CreateNewNode - error %r\n",Status));
> +  return Status;
> +}
> +
> diff --git a/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbIoNode.h b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbIoNode.h
> new file mode 100644
> index 0000000000..ecedb2748b
> --- /dev/null
> +++ b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbIoNode.h
> @@ -0,0 +1,90 @@
> +/** @file
> +  Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR>
> +
> +  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.
> +
> +**/
> +
> +#ifndef __EFI_USB_FUIO_MEM_NODE__
> +#define __EFI_USB_FUIO_MEM_NODE__
> +
> +#include <Uefi.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/DevicePathLib.h>
> +#include <Library/DriverLib.h>
> +
> +#define  USB_DEBUG_MEM_NODE_INFO  EFI_D_INIT
> +#define  USB_DEBUG_MEM_NODE_ERROR EFI_D_ERROR
> +
> +
> +typedef struct {
> +  UINTN                         Size;
> +  VOID                          *AllocatePtr;
> +  VOID                          *NextPtr;
> +} USB_MEM_NODE;
> +
> +/**
> +  The SearchNode function search a memory address for record the driver allocate
> +  memory region and the node to the head link list.
> +
> +  @param[in]  This              A pointer to the EFI_USBFN_IO_PROTOCOL instance.
> +  @param[in]  Buffer            The driver alocate memory address.
> +  @param[out] Node              The match node record of the driver aloocate
> +                                memory region.
> +  @param[out] PNode             The pervious match node record of the driver
> +                                aloocate memory region.
> +
> +  @retval EFI_SUCCESS           The operation completed successfully.
> +  @retval EFI_NOT_FOUND         The memory Buffer didn't find.
> +**/
> +EFI_STATUS
> +SearchNode (
> +  IN  EFI_USBFN_IO_PROTOCOL    *This,
> +  IN  VOID                     *Buffer,
> +  OUT USB_MEM_NODE             **Node,
> +  OUT USB_MEM_NODE             **PNode
> +  );
> +
> +/**
> +  The InsertNewNodeToHead function remove a memory for record the driver allocate
> +  memory region and the node to the head link list.
> +
> +  @param[in]  This              A pointer to the EFI_USBFN_IO_PROTOCOL instance.
> +  @param[in]  Buffer            The driver alocate memory address.
> +
> +  @retval EFI_SUCCESS           The operation completed successfully.
> +  @retval EFI_NOT_FOUND         The memory Buffer didn't find.
> +**/
> +EFI_STATUS
> +RemoveNode (
> +  IN  EFI_USBFN_IO_PROTOCOL    *This,
> +  IN  VOID                     *Buffer
> +  );
> +
> +/**
> +  The InsertNewNodeToHead function allocates a memory for record the driver allocate
> +  memory region and insert the node to the head link list.
> +
> +  @param[in]  This              A pointer to the EFI_USBFN_IO_PROTOCOL instance.
> +  @param[out] USB_MEM_NODE      return the new node address.
> +
> +  @retval EFI_SUCCESS           The operation completed successfully.
> +  @retval EFI_INVALID_PARAMETER A parameter is invalid.
> +  @retval EFI_OUT_OF_RESOURCES  The requested transfer Buffer could not be allocated.
> +
> +**/
> +EFI_STATUS
> +InsertNewNodeToHead (
> +  IN  EFI_USBFN_IO_PROTOCOL    *This,
> +  OUT USB_MEM_NODE             **Node
> +  );
> +
> +  #endif
> +
> +
> diff --git a/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciCommon.h b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciCommon.h
> new file mode 100644
> index 0000000000..6a53068681
> --- /dev/null
> +++ b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciCommon.h
> @@ -0,0 +1,156 @@
> +/** @file
> +  Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR>
> +
> +  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.
> +
> +**/
> +
> +#ifndef _XDCI_COMMON_H_
> +#define _XDCI_COMMON_H_
> +
> +#define USB_SETUP_DATA_PHASE_DIRECTION_MASK  (0x80)
> +
> +//
> +// EP direction
> +//
> +typedef enum {
> +  UsbEpDirOut = 0,
> +  UsbEpDirIn  = 1
> +} USB_EP_DIR;
> +
> +//
> +// USB Speeds
> +//
> +typedef enum {
> +  USB_SPEED_HIGH  = 0,
> +  USB_SPEED_FULL,
> +  USB_SPEED_LOW,
> +  USB_SPEED_SUPER = 4
> +} USB_SPEED;
> +
> +typedef enum {
> +  USB_ID_DWC_XDCI = 0,
> +  USB_CORE_ID_MAX
> +} USB_CONTROLLER_ID;
> +
> +typedef enum {
> +  USB_ROLE_HOST = 1,
> +  USB_ROLE_DEVICE,
> +  USB_ROLE_OTG
> +} USB_ROLE;
> +
> +typedef enum {
> +  USB_XFER_QUEUED    = 0,
> +  USB_XFER_SUCCESSFUL,
> +  USB_XFER_STALL
> +} USB_XFER_STATUS;
> +
> +typedef enum {
> +  USB_DEVICE_DISCONNECT_EVENT       = 0,
> +  USB_DEVICE_RESET_EVENT,
> +  USB_DEVICE_CONNECTION_DONE,
> +  USB_DEVICE_STATE_CHANGE_EVENT,
> +  USB_DEVICE_WAKEUP_EVENT,
> +  USB_DEVICE_HIBERNATION_REQ_EVENT,
> +  USB_DEVICE_SOF_EVENT              = 7,
> +  USB_DEVICE_ERRATIC_ERR_EVENT      = 9,
> +  USB_DEVICE_CMD_CMPLT_EVENT,
> +  USB_DEVICE_BUFF_OVERFLOW_EVENT,
> +  USB_DEVICE_TEST_LMP_RX_EVENT,
> +  USB_DEVICE_SETUP_PKT_RECEIVED,
> +  USB_DEVICE_XFER_NRDY,
> +  USB_DEVICE_XFER_DONE
> +} USB_DEVICE_EVENT_ID;
> +
> +typedef enum {
> +  U0 = 0,
> +  U1,
> +  U2,
> +  U3,
> +  SS_DIS,
> +  RX_DET,
> +  SS_INACT,
> +  POLL,
> +  RECOV,
> +  HRESET,
> +  CMPLY,
> +  LPBK,
> +  RESUME_RESET = 15
> +} USB_DEVICE_SS_LINK_STATE;
> +
> +typedef enum {
> +  CTRL_SETUP_PHASE,
> +  CTRL_DATA_PHASE,
> +  CTRL_STATUS_PHASE
> +} USB_CONTROL_XFER_PHASE;
> +
> +typedef enum  {
> +  USB_EP_STATE_DISABLED = 0,
> +  USB_EP_STATE_ENABLED,
> +  USB_EP_STATE_STALLED,
> +  USB_EP_STATE_SETUP,
> +  USB_EP_STATE_IN_DATA,
> +  USB_EP_STATE_OUT_DATA,
> +  USB_EP_STATE_DATA,
> +  USB_EP_STATE_STATUS
> +} USB_EP_STATE;
> +
> +typedef struct  {
> +  VOID                      *ParentHandle;
> +  UINT32                    Hird;
> +  UINT32                    EpNum;
> +  USB_SPEED                 Speed;
> +  USB_EP_STATE              EpState;
> +  USB_EP_DIR                EpDir;
> +  UINT8                     EpType;
> +  USB_DEVICE_SS_LINK_STATE  LinkState;
> +  UINT8                     *Buffer;
> +  BOOLEAN                   SsEvent;
> +} USB_DEVICE_CALLBACK_PARAM;
> +
> +//
> +// USB endpoint
> +//
> +typedef struct {
> +  UINT32       EpNum;
> +  USB_EP_DIR   EpDir;
> +  UINT8        EpType;
> +  UINT32       MaxPktSize;
> +  UINT32       MaxStreams;
> +  UINT32       BurstSize;
> +  UINT32       Interval;
> +  UINT32       Mult;
> +} USB_EP_INFO;
> +
> +//
> +// USB transfer request
> +//
> +typedef struct _USB_XFER_REQUEST USB_XFER_REQUEST;
> +
> +typedef
> +VOID
> +(EFIAPI *USB_XFER_DONE_CALLBACK) (
> +  IN VOID                    *XdciHndl,
> +  IN USB_XFER_REQUEST        *XferReq
> +  );
> +
> +struct _USB_XFER_REQUEST {
> +  VOID                      *XferBuffer;     // Buffer address. bus-width aligned
> +  UINT32                    XferLen;         // Requested transfer length
> +  UINT32                    ActualXferLen;  // Actual transfer length at completion callback stage
> +  UINT32                    StreamId;        // Stream ID. Only relevant for bulk streaming
> +  UINT32                    FrameNum;        // Only relevant for periodic transfer
> +  USB_XFER_STATUS           XferStatus;      // Transfer status
> +  USB_EP_INFO               EpInfo;          // EP info
> +  USB_XFER_DONE_CALLBACK    XferDone;        // Transfer completion callback
> +  BOOLEAN                   Zlp;              // Do zero-length transfer
> +};
> +
> +#endif
> +
> diff --git a/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciDWC.c b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciDWC.c
> new file mode 100644
> index 0000000000..3569ba6975
> --- /dev/null
> +++ b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciDWC.c
> @@ -0,0 +1,4030 @@
> +/** @file
> +  Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR>
> +
> +  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.
> +
> +**/
> +
> +#include "UsbDeviceMode.h"
> +#include "XdciInterface.h"
> +#include "XdciDWC.h"
> +
> +
> +UINT32
> +UsbRegRead (
> +  IN UINT32    Base,
> +  IN UINT32    Offset
> +  )
> +{
> +  volatile UINT32 *addr = (volatile UINT32 *)((UINTN)(Base) + (UINTN)(Offset));
> +  return *addr;
> +}
> +
> +VOID
> +UsbRegWrite (
> +  IN UINT32    Base,
> +  IN UINT32    Offset,
> +  IN UINT32    val
> +  )
> +{
> +  volatile UINT32 *addr = (volatile UINT32 *)((UINTN)(Base) + (UINTN)(Offset));
> +  *addr = val;
> +}
> +
> +
> +/**
> +  Internal utility function:
> +  This function is used to obtain physical endpoint number
> +  xDCI needs physical endpoint number for EP registers
> +  We also use it to index into our EP array
> +  Note: Certain data structures/commands use logical EP numbers
> +  as opposed to physical endpoint numbers so one should be
> +  careful when interpreting EP numbers
> +  @EpNum: Logical endpoint number
> +  @epDir: Direction for the endpoint
> +
> +**/
> +STATIC
> +UINT32
> +DwcXdciGetPhysicalEpNum (
> +  IN UINT32        EndpointNum,
> +  IN USB_EP_DIR    EndpointDir
> +  )
> +{
> +  return EndpointDir? ((EndpointNum << 1) | EndpointDir) : (EndpointNum << 1);
> +}
> +
> +
> +/**
> +  Internal utility function:
> +  This function is used to obtain the MPS for control transfers
> +  Based on the Speed. If this is called before bus reset completes
> +  then it returns MPS Based on desired Speed. If it is after bus
> +  reset then MPS returned is Based on actual negotiated Speed
> +  @CoreHandle: xDCI controller handle address
> +  @mps: address of 32-bit variable to return the MPS
> +
> +**/
> +STATIC
> +EFI_STATUS
> +DwcXdciCoreGetCtrlMps (
> +  IN XDCI_CORE_HANDLE    *CoreHandle,
> +  IN UINT32              *mps
> +  )
> +{
> +  if (CoreHandle == NULL) {
> +      DEBUG ((DEBUG_INFO, "ERROR: DwcXdciCoreGetCtrlMps: INVALID handle\n"));
> +      return EFI_DEVICE_ERROR;
> +  }
> +
> +  if (mps == NULL) {
> +    DEBUG ((DEBUG_INFO, "ERROR: DwcXdciCoreGetCtrlMps: INVALID parameter\n"));
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  switch (CoreHandle->ActualSpeed) {
> +    case USB_SPEED_HIGH:
> +      *mps = DWC_XDCI_HS_CTRL_EP_MPS;
> +      break;
> +    case USB_SPEED_FULL:
> +      *mps = DWC_XDCI_FS_CTRL_EP_MPS;
> +      break;
> +    case USB_SPEED_LOW:
> +      *mps = DWC_XDCI_LS_CTRL_EP_MPS;
> +      break;
> +    case USB_SPEED_SUPER:
> +      *mps = DWC_XDCI_SS_CTRL_EP_MPS;
> +      break;
> +    default:
> +      *mps = 0;
> +      DEBUG ((DEBUG_INFO, "ERROR: DwcXdciCoreGetCtrlMps: UNKNOWN Speed\n"));
> +      break;
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +
> +/**
> +  Internal utility function:
> +  This function is used to initialize the parameters required
> +  for executing endpoint command
> +  @CoreHandle: xDCI controller handle address
> +  @EpInfo: EP info address
> +  @ConfigAction: Configuration action specific to EP command
> +  @EpCmd: xDCI EP command for which parameters are initialized
> +  @EpCmdParams: address of struct to return EP params
> +
> +**/
> +STATIC
> +EFI_STATUS
> +DwcXdciCoreInitEpCmdParams (
> +  IN XDCI_CORE_HANDLE                *CoreHandle,
> +  IN USB_EP_INFO                     *EpInfo,
> +  IN UINT32                          ConfigAction,
> +  IN DWC_XDCI_ENDPOINT_CMD           EpCmd,
> +  IN DWC_XDCI_ENDPOINT_CMD_PARAMS    *EpCmdParams
> +  )
> +{
> +  EFI_STATUS  status = EFI_SUCCESS;
> +
> +  if (CoreHandle == NULL) {
> +    DEBUG ((DEBUG_INFO, "ERROR: DwcXdciCoreInitEpCmdParams: INVALID handle\n"));
> +    return EFI_DEVICE_ERROR;
> +  }
> +
> +  //
> +  // Reset params
> +  //
> +  EpCmdParams->Param0 = EpCmdParams->Param1 = EpCmdParams->Param2 = 0;
> +
> +  switch (EpCmd) {
> +    case EPCMD_SET_EP_CONFIG:
> +      //
> +      // Issue DEPCFG command for EP
> +      // Issue a DEPCFG (Command 1) command for endpoint
> +      //
> +      if (EpInfo->MaxStreams) {
> +        EpCmdParams->Param1 = DWC_XDCI_PARAM1_SET_EP_CFG_STRM_CAP_MASK;
> +      }
> +
> +      if (EpInfo->Interval) {
> +        EpCmdParams->Param1 |= ((EpInfo->Interval-1) << DWC_XDCI_PARAM1_SET_EP_CFG_BINTM1_BIT_POS);
> +      }
> +
> +      //
> +      // Set EP num
> +      //
> +      EpCmdParams->Param1 |= (EpInfo->EpNum << DWC_XDCI_PARAM1_SET_EP_CFG_EP_NUM_BIT_POS);
> +      //
> +      // Set EP direction
> +      //
> +      EpCmdParams->Param1 |= (EpInfo->EpDir << DWC_XDCI_PARAM1_SET_EP_CFG_EP_DIR_BIT_POS);
> +      //
> +      // Set EP-specific Event enable for not ready and
> +      // complete events
> +      //
> +      EpCmdParams->Param1 &= ~DWC_XDCI_PARAM1_SET_EP_CFG_EVT_EN_MASK;
> +      //
> +      // Setup the events we want enabled for this EP
> +      //
> +      EpCmdParams->Param1 |= (DWC_XDCI_PARAM1_SET_EP_CFG_EVT_XFER_NRDY_MASK |
> +                                DWC_XDCI_PARAM1_SET_EP_CFG_EVT_XFER_IN_PRG_MASK |
> +                                DWC_XDCI_PARAM1_SET_EP_CFG_EVT_XFER_CMPLT_MASK);
> +
> +      //
> +      // We only have one interrupt line for this core.
> +      // Set interrupt number to 0
> +      //
> +      EpCmdParams->Param1 &= ~DWC_XDCI_PARAM1_SET_EP_CFG_INTR_NUM_MASK;
> +
> +      //
> +      // Set FIFOnum = 0 for control EP0
> +      //
> +      EpCmdParams->Param0 &= ~DWC_XDCI_PARAM0_SET_EP_CFG_FIFO_NUM_MASK;
> +
> +      //
> +      // Program FIFOnum for non-EP0 EPs
> +      //
> +      if (EpInfo->EpNum && EpInfo->EpDir) {
> +        EpCmdParams->Param0 |= (EpInfo->EpNum << DWC_XDCI_PARAM0_SET_EP_CFG_FIFO_NUM_BIT_POS);
> +      }
> +
> +      //
> +      // Program max packet size
> +      //
> +      EpCmdParams->Param0 &= ~DWC_XDCI_PARAM0_SET_EP_CFG_MPS_MASK;
> +      EpCmdParams->Param0 |= (EpInfo->MaxPktSize << DWC_XDCI_PARAM0_SET_EP_CFG_MPS_BIT_POS);
> +
> +      //
> +      // Set Burst size. 0 means burst size of 1
> +      //
> +      EpCmdParams->Param0 &= ~DWC_XDCI_PARAM0_SET_EP_CFG_BRST_SIZE_MASK;
> +      EpCmdParams->Param0 |= (EpInfo->BurstSize << DWC_XDCI_PARAM0_SET_EP_CFG_BRST_SIZE_BIT_POS);
> +
> +      //
> +      // Set EP type
> +      //
> +      EpCmdParams->Param0 &= ~DWC_XDCI_PARAM0_SET_EP_CFG_EP_TYPE_MASK;
> +      EpCmdParams->Param0 |= (EpInfo->EpType << DWC_XDCI_PARAM0_SET_EP_CFG_EP_TYPE_BIT_POS);
> +
> +      //
> +      // Set config action
> +      //
> +      EpCmdParams->Param0 &= ~DWC_XDCI_PARAM0_SET_EP_CFG_ACTN_MASK;
> +      EpCmdParams->Param0 |= (ConfigAction << DWC_XDCI_PARAM0_SET_EP_CFG_ACTN_BIT_POS);
> +      break;
> +
> +    case EPCMD_SET_EP_XFER_RES_CONFIG:
> +      // Set Param0 to 1. Same for all EPs when resource
> +      // configuration is done
> +      //
> +      EpCmdParams->Param0 = 1;
> +      break;
> +
> +    case EPCMD_END_XFER:
> +      //
> +      // Nothing to set. Already reset params for all cmds
> +      //
> +      break;
> +
> +    case EPCMD_START_NEW_CONFIG:
> +      //
> +      // Nothing to set. Already reset params for all cmds
> +      //
> +      break;
> +
> +    default:
> +      status = EFI_INVALID_PARAMETER;
> +      DEBUG ((DEBUG_INFO, "\nDwcXdciCoreInitEpCmdParams: INVALID Parameter"));
> +      break;
> +  }
> +
> +  return status;
> +}
> +
> +
> +/**
> +  Internal utility function:
> +  This function is used to issue the xDCI endpoint command
> +  @CoreHandle: xDCI controller handle address
> +  @EpNum: Physical EP num
> +  @EpCmd: xDCI EP command
> +  @EpCmdParams: EP command parameters address
> +
> +**/
> +STATIC
> +EFI_STATUS
> +DwcXdciCoreIssueEpCmd (
> +  IN XDCI_CORE_HANDLE                *CoreHandle,
> +  IN UINT32                          EpNum,
> +  IN UINT32                          EpCmd,
> +  IN DWC_XDCI_ENDPOINT_CMD_PARAMS    *EpCmdParams
> +  )
> +{
> +  UINT32 BaseAddr;
> +  UINT32 MaxDelayIter = 5000;//DWC_XDCI_MAX_DELAY_ITERATIONS;
> +
> +  if (CoreHandle == NULL) {
> +    DEBUG ((DEBUG_INFO, "ERROR: DwcXdciCoreIssueEpCmd: INVALID handle\n"));
> +    return EFI_DEVICE_ERROR;
> +  }
> +
> +  BaseAddr = CoreHandle->BaseAddress;
> +
> +  //
> +  // Set EP command parameter values
> +  //
> +  UsbRegWrite (
> +    BaseAddr,
> +    DWC_XDCI_EPCMD_PARAM2_REG(EpNum),
> +    EpCmdParams->Param2
> +    );
> +
> +  UsbRegWrite (
> +    BaseAddr,
> +    DWC_XDCI_EPCMD_PARAM1_REG(EpNum),
> +    EpCmdParams->Param1
> +    );
> +
> +  UsbRegWrite (
> +    BaseAddr,
> +    DWC_XDCI_EPCMD_PARAM0_REG(EpNum),
> +    EpCmdParams->Param0
> +    );
> +
> +  //
> +  // Set the command code and activate it
> +  //
> +  UsbRegWrite (
> +    BaseAddr,
> +    DWC_XDCI_EPCMD_REG(EpNum),
> +    EpCmd | DWC_XDCI_EPCMD_CMD_ACTIVE_MASK
> +    );
> +
> +  //
> +  // Wait until command completes
> +  //
> +  do {
> +    if (!(UsbRegRead (BaseAddr, DWC_XDCI_EPCMD_REG(EpNum)) & DWC_XDCI_EPCMD_CMD_ACTIVE_MASK))
> +      break;
> +    else
> +      gBS->Stall (DWC_XDCI_MAX_DELAY_ITERATIONS);
> +  } while (--MaxDelayIter);
> +
> +  if (!MaxDelayIter) {
> +    DEBUG ((DEBUG_INFO, "DwcXdciCoreIssueEpCmd. ERROR: Failed to issue Command\n"));
> +    return EFI_DEVICE_ERROR;
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +
> +/**
> +  Internal utility function:
> +  This function is used to flush all FIFOs
> +  @CoreHandle: xDCI controller handle address
> +
> +**/
> +STATIC
> +EFI_STATUS
> +DwcXdciCoreFlushAllFifos (
> +  IN XDCI_CORE_HANDLE    *CoreHandle
> +  )
> +{
> +  UINT32 BaseAddr;
> +  UINT32 MaxDelayIter = DWC_XDCI_MAX_DELAY_ITERATIONS;
> +
> +  if (CoreHandle == NULL) {
> +    DEBUG ((DEBUG_INFO, "ERROR: DwcXdciCoreFlushAllFifos: INVALID handle\n"));
> +    return EFI_DEVICE_ERROR;
> +  }
> +
> +  BaseAddr = CoreHandle->BaseAddress;
> +
> +  //
> +  // Write the command to flush all FIFOs
> +  //
> +  UsbRegWrite(
> +    BaseAddr,
> +    DWC_XDCI_DGCMD_REG,
> +    (UsbRegRead (BaseAddr, DWC_XDCI_DGCMD_REG) | DWC_XDCI_DGCMD_CMD_ALL_FIFO_FLUSH | DWC_XDCI_DGCMD_CMD_ACTIVE_MASK)
> +    );
> +
> +  //
> +  // Wait until command completes
> +  //
> +  do {
> +    if (!(UsbRegRead (BaseAddr, DWC_XDCI_DGCMD_REG) & DWC_XDCI_DGCMD_CMD_ACTIVE_MASK))
> +      break;
> +    else
> +      gBS->Stall (DWC_XDCI_MAX_DELAY_ITERATIONS);
> +  } while (--MaxDelayIter);
> +
> +  if (!MaxDelayIter) {
> +    DEBUG ((DEBUG_INFO, "Failed to issue Command\n"));
> +    return EFI_DEVICE_ERROR;
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +
> +/**
> +  Internal utility function:
> +  This function is used to flush Tx FIFO specific to an endpoint
> +  @CoreHandle: xDCI controller handle address
> +  @EpNum: Physical EP num
> +
> +**/
> +STATIC
> +EFI_STATUS
> +DwcXdciCoreFlushEpTxFifo (
> +  IN XDCI_CORE_HANDLE    *CoreHandle,
> +  IN UINT32              EpNum
> +  )
> +{
> +  UINT32 BaseAddr;
> +  UINT32 MaxDelayIter = DWC_XDCI_MAX_DELAY_ITERATIONS;
> +  UINT32 fifoNum;
> +
> +  if (CoreHandle == NULL) {
> +    DEBUG ((DEBUG_INFO, "ERROR: DwcXdciCoreFlushEpTxFifo: INVALID handle\n"));
> +    return EFI_DEVICE_ERROR;
> +  }
> +
> +  BaseAddr = CoreHandle->BaseAddress;
> +
> +  //
> +  // Translate to FIFOnum
> +  // NOTE: Assuming this is a Tx EP
> +  //
> +  fifoNum = (EpNum >> 1);
> +
> +  //
> +  // TODO: Currently we are only using TxFIFO 0. Later map these
> +  // Write the FIFO num/dir param for the generic command.
> +  //
> +  UsbRegWrite (
> +    BaseAddr,
> +    DWC_XDCI_DGCMD_PARAM_REG,
> +    ((UsbRegRead (BaseAddr, DWC_XDCI_DGCMD_PARAM_REG) & ~DWC_XDCI_DGCMD_PARAM_TX_FIFO_NUM_MASK) | DWC_XDCI_DGCMD_PARAM_TX_FIFO_DIR_MASK)
> +    );
> +
> +  //
> +  // Write the command to flush all FIFOs
> +  //
> +  UsbRegWrite (
> +    BaseAddr,
> +    DWC_XDCI_DGCMD_REG,
> +    (UsbRegRead(BaseAddr, DWC_XDCI_DGCMD_REG) | DWC_XDCI_DGCMD_CMD_SEL_FIFO_FLUSH | DWC_XDCI_DGCMD_CMD_ACTIVE_MASK)
> +    );
> +
> +
> +  //
> +  // Wait until command completes
> +  //
> +  do {
> +    if (!(UsbRegRead(BaseAddr, DWC_XDCI_DGCMD_REG) & DWC_XDCI_DGCMD_CMD_ACTIVE_MASK))
> +      break;
> +    else
> +      gBS->Stall (DWC_XDCI_MAX_DELAY_ITERATIONS);
> +  } while (--MaxDelayIter);
> +
> +  if (!MaxDelayIter) {
> +    DEBUG ((DEBUG_INFO, "Failed to issue Command\n"));
> +    return EFI_DEVICE_ERROR;
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +
> +
> +STATIC
> +EFI_STATUS
> +DwcXdciCorePrepareOneTrb (
> +  IN DWC_XDCI_TRB            *Trb,
> +  IN DWC_XDCI_TRB_CONTROL    TrbCtrl,
> +  IN UINT32                  LastBit,
> +  IN UINT32                  ChainBit,
> +  IN UINT8                   *BufferPtr,
> +  IN UINT32                  size
> +  )
> +{
> +  DEBUG ((DEBUG_INFO, "Trb is 0x%x, BufferPtr is 0x%x, size is 0x%x\n", Trb, BufferPtr, size));
> +
> +  Trb->BuffPtrLow = (UINT32)(UINTN)BufferPtr;
> +  Trb->BuffPtrHigh = 0;
> +  Trb->LenXferParams = size;
> +  Trb->TrbCtrl = TrbCtrl << DWC_XDCI_TRB_CTRL_TYPE_BIT_POS;
> +
> +  if (ChainBit)
> +    Trb->TrbCtrl |= ChainBit << DWC_XDCI_TRB_CTRL_CHAIN_BUFF_BIT_POS;
> +
> +  if (LastBit)
> +    Trb->TrbCtrl |= LastBit << DWC_XDCI_TRB_CTRL_LST_TRB_BIT_POS;
> +
> +  Trb->TrbCtrl |= DWC_XDCI_TRB_CTRL_IOSP_MISOCH_MASK| DWC_XDCI_TRB_CTRL_HWO_MASK;
> +
> +  DEBUG ((DEBUG_INFO, "(DwcXdciCorePrepareOneTrb) Trb->BuffPtrLow = 0x%x, Trb->LenXferParams is 0x%x, Trb->TrbCtrl is 0x%x\n",
> +                                                       Trb->BuffPtrLow, Trb->LenXferParams, Trb->TrbCtrl));
> +  return EFI_SUCCESS;
> +}
> +
> +
> +/**
> +  Internal utility function:
> +  This function is used to initialize transfer request block
> +  @CoreHandle: xDCI controller handle address
> +  @Trb: Address of TRB to initialize
> +  @TrbCtrl: TRB control value
> +  @buffPtr: Transfer Buffer address
> +  @size: Size of the transfer
> +
> +**/
> +STATIC
> +EFI_STATUS
> +DwcXdciCoreInitTrb (
> +  IN XDCI_CORE_HANDLE        *CoreHandle,
> +  IN DWC_XDCI_TRB            *Trb,
> +  IN DWC_XDCI_TRB_CONTROL    TrbCtrl,
> +  IN UINT8                   *BufferPtr,
> +  IN UINT32                  size
> +  )
> +{
> +#define ONE_TRB_SIZE      (DWC_XDCI_TRB_BUFF_SIZE_MASK & 0x00F00000)
> +  UINT8                   *TrbBuffer;
> +  UINT32                  TrbCtrlLast;
> +  UINT32                  TrbCtrlChain;
> +  UINT32                  TrbIndex;
> +
> +  if (CoreHandle == NULL) {
> +    DEBUG ((DEBUG_INFO, "ERROR: DwcXdciCoreInitTrb: INVALID handle\n"));
> +    return EFI_DEVICE_ERROR;
> +  }
> +
> +  if (Trb == NULL) {
> +    DEBUG ((DEBUG_INFO, "ERROR: DwcXdciCoreInitTrb: INVALID handle\n"));
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +   //
> +   // Init TRB fields
> +   // NOTE: Assuming we are only using 32-bit addresses
> +   // TODO: update for 64-bit addresses
> +   //
> +  if (size <= DWC_XDCI_TRB_BUFF_SIZE_MASK) {
> +    //
> +    // Can transfer in one TRB
> +    //
> +    TrbCtrlChain = 0;
> +    TrbCtrlLast = 1;
> +    DwcXdciCorePrepareOneTrb (Trb, TrbCtrl, TrbCtrlLast, TrbCtrlChain, BufferPtr, size);
> +    return EFI_SUCCESS;
> +  }
> +
> +  //
> +  // Can't transfer in one TRB.
> +  // Seperate it in every ONE_TRB_SIZE of TRB
> +  //
> +  TrbBuffer = BufferPtr;
> +  TrbIndex = 0;
> +  while (size > ONE_TRB_SIZE) {
> +    TrbCtrlChain = 1;
> +    TrbCtrlLast = 0;
> +    DwcXdciCorePrepareOneTrb (Trb, TrbCtrl, TrbCtrlLast, TrbCtrlChain, TrbBuffer, ONE_TRB_SIZE);
> +    TrbBuffer += ONE_TRB_SIZE;
> +    size -= ONE_TRB_SIZE;
> +    Trb++;
> +    TrbIndex++;
> +    if (TrbIndex >= DWC_XDCI_TRB_NUM)
> +      return EFI_OUT_OF_RESOURCES;
> +  }
> +  TrbCtrlChain = 0;
> +  TrbCtrlLast = 1;
> +  DwcXdciCorePrepareOneTrb (Trb, TrbCtrl, TrbCtrlLast, TrbCtrlChain, TrbBuffer, size);
> +
> +  return EFI_SUCCESS;
> +}
> +
> +
> +/**
> +  Internal function:
> +  This function is used to start a SETUP phase on control endpoint
> +  @CoreHandle: xDCI controller handle address
> +
> +**/
> +STATIC
> +EFI_STATUS
> +DwcXdciCoreStartEp0SetupXfer (
> +  IN XDCI_CORE_HANDLE    *CoreHandle
> +  )
> +{
> +  DWC_XDCI_ENDPOINT_CMD_PARAMS    EpCmdParams;
> +  EFI_STATUS                      status = EFI_DEVICE_ERROR;
> +  DWC_XDCI_TRB                    *Trb;
> +
> +  if (CoreHandle == NULL) {
> +    DEBUG ((DEBUG_INFO, "ERROR: DwcXdciCoreStartEp0SetupXfer: INVALID handle\n"));
> +    return EFI_DEVICE_ERROR;
> +  }
> +
> +  if (CoreHandle->EpHandles[0].State == USB_EP_STATE_SETUP) {
> +    DEBUG ((DEBUG_INFO, "EP0 was already in SETUP phase\n"));
> +    return EFI_SUCCESS;
> +  }
> +
> +  CoreHandle->EpHandles[0].State = USB_EP_STATE_SETUP;
> +  Trb = CoreHandle->Trbs;
> +  DEBUG ((DEBUG_INFO, "(DwcXdciCoreStartEp0SetupXfer)\n"));
> +
> +  status = DwcXdciCoreInitTrb (
> +             CoreHandle,
> +             Trb,
> +             TRBCTL_SETUP,
> +             CoreHandle->AlignedSetupBuffer,
> +             8
> +             );
> +
> +  if (status)
> +    return status;
> +
> +  //
> +  // Issue a DEPSTRTXFER for EP0
> +  // Reset params
> +  //
> +  EpCmdParams.Param0 = EpCmdParams.Param1 = EpCmdParams.Param2 = 0;
> +
> +  //
> +  // Init the lower re-bits for TRB address
> +  //
> +  EpCmdParams.Param1 = (UINT32)(UINTN)Trb;
> +
> +  //
> +  // Issue the command to start transfer on physical
> +  // endpoint 0
> +  //
> +  status = DwcXdciCoreIssueEpCmd (
> +             CoreHandle,
> +             0,
> +             EPCMD_START_XFER,
> +             &EpCmdParams
> +             );
> +
> +  //
> +  // Save new resource index for this transfer
> +  //
> +  CoreHandle->EpHandles[0].CurrentXferRscIdx = ((UsbRegRead (
> +                                                     CoreHandle->BaseAddress,
> +                                                     DWC_XDCI_EPCMD_REG(0)) & DWC_XDCI_EPCMD_RES_IDX_MASK) >> DWC_XDCI_EPCMD_RES_IDX_BIT_POS
> +                                                     );
> +
> +  return status;
> +}
> +
> +
> +/**
> +  Internal function:
> +  This function is used to process the state change event
> +  @CoreHandle: xDCI controller handle address
> +  @event: device event dword
> +
> +**/
> +STATIC
> +EFI_STATUS
> +DwcXdciProcessDeviceStateChangeEvent (
> +  IN XDCI_CORE_HANDLE    *CoreHandle,
> +  IN UINT32              Event
> +  )
> +{
> +  if (CoreHandle == NULL) {
> +    DEBUG ((DEBUG_INFO, "ERROR: DwcXdciProcessDeviceStateChangeEvent: INVALID handle\n"));
> +    return EFI_DEVICE_ERROR;
> +  }
> +
> +  CoreHandle->HirdVal = (Event & DWC_XDCI_EVENT_BUFF_DEV_HIRD_MASK) >> DWC_XDCI_EVENT_BUFF_DEV_HIRD_BIT_POS;
> +
> +  CoreHandle->LinkState = ((Event & DWC_XDCI_EVENT_BUFF_DEV_LINK_STATE_MASK) >> DWC_XDCI_EVENT_BUFF_DEV_LINK_STATE_BIT_POS);
> +
> +  if (CoreHandle->EventCallbacks.DevLinkStateCallback) {
> +    CoreHandle->EventCallbacks.CbEventParams.ParentHandle = CoreHandle->ParentHandle;
> +    CoreHandle->EventCallbacks.CbEventParams.LinkState = CoreHandle->LinkState;
> +    CoreHandle->EventCallbacks.CbEventParams.Hird = CoreHandle->HirdVal;
> +    CoreHandle->EventCallbacks.CbEventParams.SsEvent = (Event & DWC_XDCI_EVENT_BUFF_DEV_SS_EVENT_MASK) ? 1 : 0;
> +    CoreHandle->EventCallbacks.DevLinkStateCallback (&CoreHandle->EventCallbacks.CbEventParams);
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +
> +/**
> +  Internal function:
> +  This function is used to issue a command to end transfer
> +  @CoreHandle: xDCI controller handle address
> +  @EpNum: Physical EP num for which transfer is to be ended
> +
> +**/
> +STATIC
> +EFI_STATUS
> +DwcXdciEndXfer (
> +  IN XDCI_CORE_HANDLE    *CoreHandle,
> +  IN UINT32              EpNum
> +  )
> +{
> +  EFI_STATUS                      status;
> +  DWC_XDCI_ENDPOINT_CMD_PARAMS    EpCmdParams;
> +  UINT32                          cmdParams;
> +  DWC_XDCI_TRB                    *TrbPtr;
> +
> +  if (CoreHandle == NULL) {
> +    DEBUG ((DEBUG_INFO, "ERROR: DwcXdciEndXfer: INVALID handle\n"));
> +    return EFI_DEVICE_ERROR;
> +  }
> +
> +  CoreHandle->EpHandles[EpNum].CheckFlag = FALSE;
> +
> +  //
> +  // Issue a DEPENDXFER for EP
> +  // Reset params
> +  //
> +  EpCmdParams.Param0 = EpCmdParams.Param1 = EpCmdParams.Param2 = 0;
> +
> +  cmdParams = ((CoreHandle->EpHandles[EpNum].CurrentXferRscIdx << DWC_XDCI_EPCMD_RES_IDX_BIT_POS) | DWC_XDCI_EPCMD_FORCE_RM_MASK);
> +
> +  if (CoreHandle->EpHandles[EpNum].CurrentXferRscIdx == 0) {
> +    return EFI_SUCCESS;
> +  }
> +  //
> +  // Issue the command
> +  //
> +  status = DwcXdciCoreIssueEpCmd(
> +             CoreHandle,
> +             EpNum,
> +             cmdParams | DWC_XDCI_EPCMD_END_XFER,
> +             &EpCmdParams
> +             );
> +
> +  if (!status) {
> +    CoreHandle->EpHandles[EpNum].CurrentXferRscIdx = 0;
> +    TrbPtr = CoreHandle->Trbs + (EpNum * DWC_XDCI_TRB_NUM);
> +    ZeroMem (TrbPtr, DWC_XDCI_TRB_NUM * sizeof (DWC_XDCI_TRB));
> +  }
> +
> +  return status;
> +}
> +
> +
> +/**
> +  Internal function:
> +  This function is used to process bus reset detection event
> +  @CoreHandle: xDCI controller handle address
> +
> +**/
> +STATIC
> +EFI_STATUS
> +DwcXdciProcessDeviceResetDet (
> +  IN XDCI_CORE_HANDLE    *CoreHandle
> +  )
> +{
> +  EFI_STATUS  status = EFI_SUCCESS;
> +
> +  if (CoreHandle == NULL) {
> +    return EFI_DEVICE_ERROR;
> +  }
> +
> +  //
> +  // Flush all FIFOs
> +  //
> +  status = DwcXdciCoreFlushAllFifos(CoreHandle);
> +  if (status) {
> +    DEBUG ((DEBUG_INFO, "DwcXdciProcessDeviceResetDet: Failed to flush FIFOs\n"));
> +  }
> +
> +  //
> +  // Start SETUP phase on EP0
> +  //
> +  status = DwcXdciCoreStartEp0SetupXfer(CoreHandle);
> +
> +  if (status) {
> +    DEBUG ((DEBUG_INFO, "DwcXdciProcessDeviceResetDet: Failed to start SETUP phase for EP0\n"));
> +    return status;
> +  }
> +
> +  //
> +  // Notify upper layer if a callback is registerd for
> +  //  this event
> +  //
> +  if (CoreHandle->EventCallbacks.DevBusResetCallback) {
> +    CoreHandle->EventCallbacks.CbEventParams.ParentHandle = CoreHandle->ParentHandle;
> +    status = CoreHandle->EventCallbacks.DevBusResetCallback (&CoreHandle->EventCallbacks.CbEventParams);
> +  }
> +
> +  return status;
> +}
> +
> +
> +/**
> +  Internal function:
> +  This function is used to process connection done (means reset
> +  complete) event
> +  @CoreHandle: xDCI controller handle address
> +
> +**/
> +STATIC
> +EFI_STATUS
> +DwcXdciProcessDeviceResetDone (
> +  IN XDCI_CORE_HANDLE    *CoreHandle
> +  )
> +{
> +  DWC_XDCI_ENDPOINT_CMD_PARAMS    EpCmdParams;
> +  UINT32                          BaseAddr;
> +  EFI_STATUS                      status = EFI_SUCCESS;
> +
> +  if (CoreHandle == NULL) {
> +    DEBUG ((DEBUG_INFO, "ERROR: DwcXdciProcessDeviceResetDone: INVALID handle\n"));
> +    return EFI_DEVICE_ERROR;
> +  }
> +
> +  BaseAddr = CoreHandle->BaseAddress;
> +  CoreHandle->ActualSpeed = (UsbRegRead (BaseAddr, DWC_XDCI_DSTS_REG) & DWC_XDCI_DSTS_CONN_SPEED_MASK);
> +  DEBUG ((DEBUG_INFO, "DwcXdciProcessDeviceResetDone CoreHandle->ActualSpeed is %x\n", CoreHandle->ActualSpeed));
> +
> +  //
> +  // Program MPS Based on the negotiated Speed
> +  //
> +  DwcXdciCoreGetCtrlMps (CoreHandle, &CoreHandle->EpHandles[0].EpInfo.MaxPktSize);
> +  DwcXdciCoreGetCtrlMps (CoreHandle, &CoreHandle->EpHandles[1].EpInfo.MaxPktSize);
> +
> +  //
> +  // Init DEPCFG cmd params for EP0
> +  //
> +  status = DwcXdciCoreInitEpCmdParams (
> +             CoreHandle,
> +             &CoreHandle->EpHandles[0].EpInfo,
> +             DWC_XDCI_PARAM0_SET_EP_CFG_ACTN_MDFY_STATE,
> +             EPCMD_SET_EP_CONFIG,
> +             &EpCmdParams
> +             );
> +
> +  if (status) {
> +    return status;
> +  }
> +
> +  //
> +  // Issue the command
> +  //
> +  status = DwcXdciCoreIssueEpCmd (
> +             CoreHandle,
> +             0,
> +             EPCMD_SET_EP_CONFIG,
> +             &EpCmdParams
> +             );
> +
> +  if (status) {
> +    return status;
> +  }
> +
> +  //
> +  // Init DEPCFG cmd params for EP1
> +  //
> +  status = DwcXdciCoreInitEpCmdParams (
> +             CoreHandle,
> +             &CoreHandle->EpHandles[1].EpInfo,
> +             DWC_XDCI_PARAM0_SET_EP_CFG_ACTN_MDFY_STATE,
> +             EPCMD_SET_EP_CONFIG,
> +             &EpCmdParams
> +             );
> +
> +  //
> +  // Issue the command
> +  //
> +  status = DwcXdciCoreIssueEpCmd (
> +             CoreHandle,
> +             1,
> +             EPCMD_SET_EP_CONFIG,
> +             &EpCmdParams
> +             );
> +
> +  //
> +  // Put the other PHY into suspend
> +  //
> +  if (CoreHandle->ActualSpeed == USB_SPEED_SUPER) {
> +    //
> +    // Put HS PHY to suspend
> +    //
> +    UsbRegWrite (
> +      BaseAddr,
> +      DWC_XDCI_GUSB2PHYCFG_REG (0),
> +      (UsbRegRead (BaseAddr, DWC_XDCI_GUSB2PHYCFG_REG(0)) | DWC_XDCI_GUSB2PHYCFG_SUSPEND_PHY_MASK)
> +      );
> +
> +    //
> +    // Clear SS PHY's suspend mask
> +    //
> +    UsbRegWrite (
> +      BaseAddr,
> +      DWC_XDCI_GUSB3PIPECTL_REG (0),
> +      (UsbRegRead (BaseAddr, DWC_XDCI_GUSB3PIPECTL_REG(0)) & ~DWC_XDCI_GUSB3PIPECTL_SUSPEND_PHY_MASK)
> +      );
> +
> +  } else {
> +    //
> +    // Put SS PHY to suspend
> +    //
> +    UsbRegWrite (
> +      BaseAddr,
> +      DWC_XDCI_GUSB3PIPECTL_REG(0),
> +      (UsbRegRead(BaseAddr, DWC_XDCI_GUSB3PIPECTL_REG(0)) | DWC_XDCI_GUSB3PIPECTL_SUSPEND_PHY_MASK)
> +      );
> +
> +    //
> +    // Clear HS PHY's suspend mask
> +    //
> +    UsbRegWrite (
> +      BaseAddr,
> +      DWC_XDCI_GUSB2PHYCFG_REG(0),
> +      (UsbRegRead(BaseAddr, DWC_XDCI_GUSB2PHYCFG_REG(0)) & ~DWC_XDCI_GUSB2PHYCFG_SUSPEND_PHY_MASK)
> +      );
> +  }
> +
> +  //
> +  // Notify upper layer if callback is registered
> +  //
> +  if (CoreHandle->EventCallbacks.DevResetDoneCallback) {
> +    CoreHandle->EventCallbacks.CbEventParams.ParentHandle = CoreHandle->ParentHandle;
> +    CoreHandle->EventCallbacks.CbEventParams.Speed = CoreHandle->ActualSpeed;
> +    CoreHandle->EventCallbacks.DevResetDoneCallback (&CoreHandle->EventCallbacks.CbEventParams);
> +  }
> +
> +  return status;
> +}
> +
> +
> +/**
> +  Internal function:
> +  This function is used to process device event
> +  @CoreHandle: xDCI controller handle address
> +  @IntLineEventBuffer: event Buffer pointing to device event
> +  @ProcessedEventSize: address of variable to save the size of
> +  the event that was Processed
> +
> +**/
> +STATIC
> +EFI_STATUS
> +DwcXdciProcessDeviceEvent (
> +  IN XDCI_CORE_HANDLE         *CoreHandle,
> +  IN DWC_XDCI_EVENT_BUFFER    *IntLineEventBuffer,
> +  IN UINT32                   *ProcessedEventSize
> +  )
> +{
> +  UINT32 event;
> +
> +  if (CoreHandle == NULL) {
> +    DEBUG ((DEBUG_INFO, "ERROR: DwcXdciProcessDeviceEvent: INVALID handle\n"));
> +    return EFI_DEVICE_ERROR;
> +  }
> +
> +  //
> +  // Extract device event
> +  //
> +  event = (IntLineEventBuffer->Event & DWC_XDCI_EVENT_BUFF_DEV_EVT_MASK);
> +  event >>= DWC_XDCI_EVENT_BUFF_DEV_EVT_BIT_POS;
> +
> +  //
> +  // Assume default event size. Change it in switch case if
> +  //  different
> +  //
> +  *ProcessedEventSize = DWC_XDCI_DEV_EVENT_DEFAULT_SIZE_IN_BYTES;
> +
> +  switch (event) {
> +    case DWC_XDCI_EVENT_BUFF_DEV_DISCONN_EVENT:
> +      DEBUG ((DEBUG_INFO, "Device DWC_XDCI_EVENT_BUFF_DEV_DISCONN_EVENT\n"));
> +      break;
> +
> +    case DWC_XDCI_EVENT_BUFF_DEV_USB_RESET_EVENT:
> +      DEBUG ((DEBUG_INFO, "Device DWC_XDCI_EVENT_BUFF_DEV_USB_RESET_EVENT\n"));
> +      DwcXdciProcessDeviceResetDet (CoreHandle);
> +      break;
> +
> +    case DWC_XDCI_EVENT_BUFF_DEV_CONN_DONE_EVENT:
> +      DEBUG ((DEBUG_INFO, "Device DWC_XDCI_EVENT_BUFF_DEV_CONN_DONE_EVENT\n"));
> +      DwcXdciProcessDeviceResetDone (CoreHandle);
> +      break;
> +
> +    case DWC_XDCI_EVENT_BUFF_DEV_STATE_CHANGE_EVENT:
> +      DEBUG ((DEBUG_INFO, "Device DWC_XDCI_EVENT_BUFF_DEV_STATE_CHANGE_EVENT\n"));
> +      DwcXdciProcessDeviceStateChangeEvent (CoreHandle, IntLineEventBuffer->Event);
> +      break;
> +
> +    case DWC_XDCI_EVENT_BUFF_DEV_WKUP_EVENT:
> +      DEBUG ((DEBUG_INFO, "Device DWC_XDCI_EVENT_BUFF_DEV_WKUP_EVENT\n"));
> +      break;
> +
> +    case DWC_XDCI_EVENT_BUFF_DEV_HBRNTN_REQ_EVENT:
> +      DEBUG ((DEBUG_INFO, "Device DWC_XDCI_EVENT_BUFF_DEV_HBRNTN_REQ_EVENT\n"));
> +      break;
> +
> +    case DWC_XDCI_EVENT_BUFF_DEV_SOF_EVENT:
> +      DEBUG ((DEBUG_INFO, "Device DWC_XDCI_EVENT_BUFF_DEV_SOF_EVENT\n"));
> +      break;
> +
> +    case DWC_XDCI_EVENT_BUFF_DEV_ERRATIC_ERR_EVENT:
> +      DEBUG ((DEBUG_INFO, "Device DWC_XDCI_EVENT_BUFF_DEV_ERRATIC_ERR_EVENT\n"));
> +      break;
> +
> +    case DWC_XDCI_EVENT_BUFF_DEV_CMD_CMPLT_EVENT:
> +      DEBUG ((DEBUG_INFO, "Device DWC_XDCI_EVENT_BUFF_DEV_CMD_CMPLT_EVENT\n"));
> +      break;
> +
> +    case DWC_XDCI_EVENT_BUFF_DEV_BUFF_OVFL_EVENT:
> +      DEBUG ((DEBUG_INFO, "Device DWC_XDCI_EVENT_BUFF_DEV_BUFF_OVFL_EVENT\n"));
> +      break;
> +
> +    case DWC_XDCI_EVENT_BUFF_DEV_TST_LMP_RX_EVENT:
> +      DEBUG ((DEBUG_INFO, "Device DWC_XDCI_EVENT_BUFF_DEV_TST_LMP_RX_EVENT\n"));
> +      *ProcessedEventSize = DWC_XDCI_DEV_EVENT_TST_LMP_SIZE_IN_BYTES;
> +      break;
> +
> +    default:
> +      DEBUG ((DEBUG_INFO, "DwcXdciProcessDeviceEvent: UNHANDLED device event: %x\n", event));
> +      break;
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +
> +/**
> +  Internal function:
> +  This function is used to process EP not ready for
> +  non-control endpoints
> +  @CoreHandle: xDCI controller handle address
> +  @EpNum: Physical endpoint number
> +
> +**/
> +STATIC
> +EFI_STATUS
> +DwcXdciProcessEpXferNotReady (
> +  IN XDCI_CORE_HANDLE    *CoreHandle,
> +  IN UINT32              EpNum
> +  )
> +{
> +  //
> +  // TODO: Not doing on-demand transfers
> +  // Revisit if required for later use
> +  //
> +  return EFI_SUCCESS;
> +}
> +
> +
> +/**
> +  Internal function:
> +  This function is used to process EP not ready for
> +  control endpoints
> +  @CoreHandle: xDCI controller handle address
> +  @EpNum: Physical endpoint number
> +  @dataStage: EP not ready when data stage token was received
> +  @statusStage: EP not ready when status stage token was received
> +
> +**/
> +STATIC
> +EFI_STATUS
> +DwcXdciProcessEp0XferNotReady (
> +  IN XDCI_CORE_HANDLE    *CoreHandle,
> +  IN UINT32              EpNum,
> +  IN UINT32              epEventStatus
> +  )
> +{
> +  USB_EP_STATE        epState = USB_EP_STATE_SETUP;
> +
> +  if (CoreHandle == NULL) {
> +    DEBUG ((DEBUG_INFO, "ERROR: DwcXdciProcessEp0XferNotReady: INVALID handle\n"));
> +    return EFI_DEVICE_ERROR;
> +  }
> +  //
> +  // Is it data stage or status stage
> +  //
> +  if (epEventStatus & DWC_XDCI_EVENT_BUFF_EP_CTRL_DATA_REQ_MASK) {
> +    epState = USB_EP_STATE_DATA;
> +  } else if (epEventStatus & DWC_XDCI_EVENT_BUFF_EP_CTRL_STATUS_REQ_MASK) {
> +    epState = USB_EP_STATE_STATUS;
> +  }
> +
> +  if ((EpNum == 0) && (epState == USB_EP_STATE_STATUS)) {
> +    if (epEventStatus & DWC_XDCI_EVENT_BUFF_EP_XFER_ACTIVE_MASK) {
> +      DEBUG ((DEBUG_INFO, "XFER_ACTIVE\n"));
> +    } else {
> +      DEBUG ((DEBUG_INFO, "XFER_NOT_ACTIVE\n"));
> +    }
> +    DwcXdciEp0ReceiveStatusPkt (CoreHandle);
> +  }
> +
> +  //
> +  // Notify upper layer if a callback is registered for
> +  // this event
> +  //
> +  if (CoreHandle->EventCallbacks.DevXferNrdyCallback) {
> +    CoreHandle->EventCallbacks.CbEventParams.ParentHandle = CoreHandle->ParentHandle;
> +    CoreHandle->EventCallbacks.CbEventParams.EpState = epState;
> +    CoreHandle->EventCallbacks.DevXferNrdyCallback (&CoreHandle->EventCallbacks.CbEventParams);
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +
> +/**
> +  Internal function:
> +  This function is used to process transfer phone done for EP0
> +  @CoreHandle: xDCI controller handle address
> +  @EpNum: Physical endpoint number (0 for OUT and 1 for IN)
> +
> +**/
> +STATIC
> +EFI_STATUS
> +DwcXdciProcessEp0XferPhaseDone (
> +  IN XDCI_CORE_HANDLE    *CoreHandle,
> +  IN UINT32              EpNum
> +  )
> +{
> +  DWC_XDCI_ENDPOINT    *epHandle;
> +  DWC_XDCI_TRB         *Trb;
> +  EFI_STATUS           status = EFI_SUCCESS;
> +  UINT32               TrbSts;
> +  UINT32               TrbCtrl;
> +  UINT32               TrbBufsize;
> +
> +  if (CoreHandle == NULL) {
> +    DEBUG ((DEBUG_INFO, "ERROR: DwcXdciProcessEp0XferPhaseDone: INVALID handle\n"));
> +    return EFI_DEVICE_ERROR;
> +  }
> +
> +  epHandle = &CoreHandle->EpHandles[EpNum];
> +  Trb = CoreHandle->Trbs + (EpNum * DWC_XDCI_TRB_NUM);
> +  DEBUG ((DEBUG_INFO, "(DwcXdciProcessEp0XferPhaseDone)EpNum is %d\n", EpNum));
> +
> +  if (Trb->TrbCtrl & DWC_XDCI_TRB_CTRL_HWO_MASK) {
> +    DEBUG ((DEBUG_INFO, "DwcXdciProcessEp0XferPhaseDone. HW owns TRB: %x!!!\n", (UINT32)(UINTN)Trb));
> +  }
> +
> +  epHandle->CurrentXferRscIdx = 0;
> +  epHandle->State = USB_EP_STATE_ENABLED;
> +  TrbCtrl = (Trb->TrbCtrl & DWC_XDCI_TRB_CTRL_TYPE_MASK) >> DWC_XDCI_TRB_CTRL_TYPE_BIT_POS;
> +  TrbSts = (Trb->LenXferParams & DWC_XDCI_TRB_STATUS_MASK) >> DWC_XDCI_TRB_STATUS_BIT_POS;
> +  TrbBufsize = Trb->LenXferParams & DWC_XDCI_TRB_BUFF_SIZE_MASK;
> +
> +  switch (TrbCtrl) {
> +    case DWC_XDCI_TRB_CTRL_TYPE_SETUP:
> +      DEBUG ((DEBUG_INFO, "SETUP\n"));
> +      if (CoreHandle->EventCallbacks.DevSetupPktReceivedCallback) {
> +        CoreHandle->EventCallbacks.CbEventParams.ParentHandle = CoreHandle->ParentHandle;
> +        CoreHandle->EventCallbacks.CbEventParams.Buffer = CoreHandle->AlignedSetupBuffer;
> +        status = CoreHandle->EventCallbacks.DevSetupPktReceivedCallback (&CoreHandle->EventCallbacks.CbEventParams);
> +      }
> +
> +      if (!(CoreHandle->AlignedSetupBuffer[0] & USB_SETUP_DATA_PHASE_DIRECTION_MASK)) {
> +        //
> +        // Keep a Buffer ready for setup phase
> +        //
> +        DwcXdciCoreStartEp0SetupXfer (CoreHandle);
> +      }
> +
> +      break;
> +
> +    case DWC_XDCI_TRB_CTRL_TYPE_STATUS2:
> +      DEBUG ((DEBUG_INFO, "STATUS2\n"));
> +      break;
> +
> +    case DWC_XDCI_TRB_CTRL_TYPE_STATUS3:
> +      DEBUG ((DEBUG_INFO, "STATUS3\n"));
> +      //
> +      // Notify upper layer of control transfer completion
> +      // if a callback function was registerd
> +      //
> +      if (CoreHandle->EventCallbacks.DevXferDoneCallback) {
> +        CoreHandle->EventCallbacks.CbEventParams.ParentHandle = CoreHandle->ParentHandle;
> +        CoreHandle->EventCallbacks.CbEventParams.EpNum = (EpNum >> 1);
> +        CoreHandle->EventCallbacks.CbEventParams.EpDir = (EpNum & 1);
> +        CoreHandle->EventCallbacks.CbEventParams.Buffer = (UINT8 *)(UINTN)(Trb->BuffPtrLow);
> +        CoreHandle->EventCallbacks.DevXferDoneCallback (&CoreHandle->EventCallbacks.CbEventParams);
> +      }
> +
> +      //
> +      // Status phase done. Queue next SETUP packet
> +      //
> +      status = DwcXdciCoreStartEp0SetupXfer(CoreHandle);
> +
> +      if (status) {
> +        DEBUG ((DEBUG_INFO, "DwcXdciProcessEp0XferPhaseDone: FAILED to queue SETUP\n"));
> +      }
> +      break;
> +
> +    case DWC_XDCI_TRB_CTRL_TYPE_DATA:
> +      DEBUG ((DEBUG_INFO, "DATA\n"));
> +      if (TrbSts == DWC_XDCI_TRB_STATUS_SETUP_PENDING || TrbBufsize != 0) {
> +        DEBUG ((DEBUG_INFO, "ERROR: Control transfert aborted by host: Setup pending\n"));
> +        DwcXdciCoreStartEp0SetupXfer (CoreHandle);
> +      }
> +
> +      if (CoreHandle->EventCallbacks.DevXferDoneCallback) {
> +        CoreHandle->EventCallbacks.CbEventParams.ParentHandle = CoreHandle->ParentHandle;
> +        CoreHandle->EventCallbacks.CbEventParams.EpNum = (EpNum >> 1);
> +        CoreHandle->EventCallbacks.CbEventParams.EpDir = (EpNum & 1);
> +        CoreHandle->EventCallbacks.CbEventParams.Buffer = (UINT8 *)(UINTN)(Trb->BuffPtrLow);
> +        CoreHandle->EventCallbacks.DevXferDoneCallback (&CoreHandle->EventCallbacks.CbEventParams);
> +      }
> +      break;
> +
> +    default:
> +      DEBUG ((DEBUG_INFO, "DwcXdciProcessEp0XferPhaseDone: UNHANDLED STATE in TRB\n"));
> +      break;
> +  }
> +
> +  return status;
> +}
> +
> +
> +/**
> +  Internal function:
> +  This function is used to process transfer done for
> +  non-control endpoints
> +  @CoreHandle: xDCI controller handle address
> +  @EpNum: Physical endpoint number
> +
> +**/
> +STATIC
> +EFI_STATUS
> +DwcXdciProcessEpXferDone (
> +  IN XDCI_CORE_HANDLE    *CoreHandle,
> +  IN UINT32              EpNum
> +  )
> +{
> +  DWC_XDCI_ENDPOINT    *epHandle;
> +  DWC_XDCI_TRB         *Trb;
> +  USB_XFER_REQUEST     *XferReq;
> +  UINT32               remainingLen;
> +
> +  if (CoreHandle == NULL) {
> +    DEBUG ((DEBUG_INFO, "ERROR: DwcXdciProcessEpXferDone: INVALID handle\n"));
> +    return EFI_DEVICE_ERROR;
> +  }
> +
> +  epHandle = &CoreHandle->EpHandles[EpNum];
> +  epHandle->CurrentXferRscIdx = 0;
> +  Trb = epHandle->Trb;
> +  XferReq = &epHandle->XferHandle;
> +
> +  //
> +  // if transfer done, set CheckFlag to FALSE for allow next transfer request.
> +  //
> +  epHandle->CheckFlag = FALSE;
> +
> +  if ((Trb == NULL) || (XferReq == NULL)) {
> +    DEBUG ((DEBUG_INFO, "ERROR: DwcXdciProcessEpXferDone: INVALID parameter\n"));
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  //
> +  // Compute the actual transfer length
> +  //
> +  XferReq->ActualXferLen = XferReq->XferLen;
> +  remainingLen = (Trb->LenXferParams & DWC_XDCI_TRB_BUFF_SIZE_MASK);
> +
> +  if (remainingLen > XferReq->XferLen) {
> +    //
> +    // Buffer overrun? This should never happen
> +    //
> +    DEBUG ((DEBUG_INFO, "ERROR: DwcXdciProcessEpXferDone: Possible Buffer overrun\n"));
> +  } else {
> +    XferReq->ActualXferLen -= remainingLen;
> +  }
> +
> +  //
> +  // Notify upper layer of request-specific transfer completion
> +  // if there is a callback specifically for this request
> +  //
> +  if (XferReq->XferDone) {
> +    XferReq->XferDone(CoreHandle->ParentHandle, XferReq);
> +  }
> +
> +  //
> +  // Notify upper layer if a callback was registered
> +  //
> +  if (CoreHandle->EventCallbacks.DevXferDoneCallback) {
> +    CoreHandle->EventCallbacks.CbEventParams.ParentHandle = CoreHandle->ParentHandle;
> +    CoreHandle->EventCallbacks.CbEventParams.EpNum = (EpNum >> 1);
> +    CoreHandle->EventCallbacks.CbEventParams.EpDir = (EpNum & 1);
> +    CoreHandle->EventCallbacks.CbEventParams.EpType = epHandle->EpInfo.EpType;
> +    CoreHandle->EventCallbacks.CbEventParams.Buffer = (UINT8 *)(UINTN)(epHandle->Trb->BuffPtrLow);
> +    CoreHandle->EventCallbacks.DevXferDoneCallback (&CoreHandle->EventCallbacks.CbEventParams);
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +
> +/**
> +  Internal function:
> +  This function is used to process endpoint events
> +  @CoreHandle: xDCI controller handle address
> +  @IntLineEventBuffer:  address of Buffer containing event
> +  to process
> +  @ProcessedEventSize: address to save the size of event
> +  Processed
> +
> +**/
> +STATIC
> +EFI_STATUS
> +DwcXdciProcessEpEvent (
> +  IN XDCI_CORE_HANDLE         *CoreHandle,
> +  IN DWC_XDCI_EVENT_BUFFER    *IntLineEventBuffer,
> +  IN UINT32                   *ProcessedEventSize
> +  )
> +{
> +  UINT32          EpNum;
> +  UINT32          epEvent;
> +  UINT32          epEventStatus;
> +
> +  if (CoreHandle == NULL) {
> +    DEBUG ((DEBUG_INFO, "ERROR: DwcXdciProcessEpEvent: INVALID handle\n"));
> +    return EFI_DEVICE_ERROR;
> +  }
> +
> +  epEvent = IntLineEventBuffer->Event;
> +
> +  *ProcessedEventSize = DWC_XDCI_DEV_EVENT_DEFAULT_SIZE_IN_BYTES;
> +
> +  //
> +  // Get EP num
> +  //
> +  EpNum = ((epEvent & DWC_XDCI_EVENT_BUFF_EP_NUM_MASK) >> DWC_XDCI_EVENT_BUFF_EP_NUM_BIT_POS);
> +  epEventStatus = (epEvent & DWC_XDCI_EVENT_BUFF_EP_EVENT_STATUS_MASK);
> +
> +  //
> +  // Interpret event and handle transfer completion here
> +  //
> +  epEvent = ((epEvent & DWC_XDCI_EVENT_BUFF_EP_EVENT_MASK) >> DWC_XDCI_EVENT_BUFF_EP_EVENT_BIT_POS);
> +
> +  switch (epEvent) {
> +    case DWC_XDCI_EVENT_BUFF_EP_XFER_CMPLT:
> +      DEBUG ((DEBUG_INFO, "XFER_CMPLT ep %d\n", EpNum));
> +      if (EpNum > 1) {
> +        DwcXdciProcessEpXferDone (CoreHandle, EpNum);
> +      } else {
> +        DwcXdciProcessEp0XferPhaseDone (CoreHandle, EpNum);
> +      }
> +      break;
> +
> +    case DWC_XDCI_EVENT_BUFF_EP_XFER_IN_PROGRESS:
> +      DEBUG ((DEBUG_INFO, "IN_PROGRESS\n"));
> +      break;
> +
> +    case DWC_XDCI_EVENT_BUFF_EP_XFER_NOT_READY:
> +      DEBUG ((DEBUG_INFO, "NOT_READY ep %d\n", EpNum));
> +      if (EpNum > 1) {
> +        //
> +        // Endpoint transfer is not ready
> +        //
> +        DwcXdciProcessEpXferNotReady (CoreHandle, EpNum);
> +      } else {
> +        DwcXdciProcessEp0XferNotReady (CoreHandle, EpNum, epEventStatus);
> +      }
> +      break;
> +
> +    default:
> +      DEBUG ((DEBUG_INFO, "DwcXdciProcessEpEvent: UNKNOWN EP event\n"));
> +      break;
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +
> +/**
> +  Internal function:
> +  This function is used to process events on single interrupt line
> +  @CoreHandle: xDCI controller handle address
> +  @eventCount:  event bytes to process
> +  @ProcessedEventCount: address to save the size
> +  (in bytes) of event Processed
> +  Processed
> +
> +**/
> +STATIC
> +EFI_STATUS
> +DwcXdciProcessInterruptLineEvents (
> +  IN XDCI_CORE_HANDLE    *CoreHandle,
> +  IN UINT32              eventCount,
> +  IN UINT32              *ProcessedEventCount
> +  )
> +{
> +  UINT32    ProcessedEventSize = 0;
> +  UINT32    currentEventAddr;
> +
> +  if (CoreHandle == NULL) {
> +    DEBUG ((DEBUG_INFO, "ERROR: DwcXdciProcessInterruptLineEvents: INVALID handle\n"));
> +    return EFI_DEVICE_ERROR;
> +  }
> +
> +  if (CoreHandle->CurrentEventBuffer == NULL) {
> +    DEBUG ((DEBUG_INFO, "ERROR: DwcXdciProcessInterruptLineEvents: INVALID event Buffer\n"));
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  currentEventAddr = (UINT32)(UINTN)(CoreHandle->CurrentEventBuffer);
> +
> +  //
> +  // Process eventCount/eventSize number of events
> +  // in this run
> +  //
> +  while (eventCount) {
> +    if (CoreHandle->CurrentEventBuffer->Event & DWC_XDCI_EVENT_DEV_MASK) {
> +      DwcXdciProcessDeviceEvent (
> +        CoreHandle,
> +        CoreHandle->CurrentEventBuffer,
> +        &ProcessedEventSize
> +        );
> +    } else {
> +      DwcXdciProcessEpEvent (
> +        CoreHandle,
> +        CoreHandle->CurrentEventBuffer,
> +        &ProcessedEventSize);
> +    }
> +
> +    eventCount -= ProcessedEventSize;
> +    *ProcessedEventCount += ProcessedEventSize;
> +    if ((currentEventAddr + ProcessedEventSize) >=
> +        ((UINT32)(UINTN)(CoreHandle->AlignedEventBuffers) + (sizeof(DWC_XDCI_EVENT_BUFFER) * DWC_XDCI_MAX_EVENTS_PER_BUFFER))
> +       ) {
> +      currentEventAddr = (UINT32)(UINTN)(CoreHandle->AlignedEventBuffers);
> +      DEBUG ((DEBUG_INFO, "DwcXdciProcessInterruptLineEvents: Event Buffer bound reached\n"));
> +    } else {
> +      currentEventAddr += ProcessedEventSize;
> +    }
> +
> +    CoreHandle->CurrentEventBuffer = (DWC_XDCI_EVENT_BUFFER *)(UINTN)currentEventAddr;
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +//
> +// DWC XDCI APIs
> +//
> +
> +/**
> +  Interface:
> +
> +  This function is used to initialize the xDCI core
> +  @configParams: Parameters from app to configure the core
> +  @deviceCorePtr:  HW-independent APIs handle for device core
> +  @CoreHandle: xDCI controller handle retured
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +DwcXdciCoreInit (
> +  IN USB_DEV_CONFIG_PARAMS    *ConfigParams,
> +  IN VOID                     *deviceCorePtr,
> +  IN VOID                     **CoreHandle
> +  )
> +{
> +  EFI_STATUS                      status = EFI_DEVICE_ERROR;
> +  UINT32                          BaseAddr;
> +  XDCI_CORE_HANDLE                *LocalCoreHandle;
> +  DWC_XDCI_ENDPOINT_CMD_PARAMS    EpCmdParams;
> +  UINT32                          MaxDelayIter = DWC_XDCI_MAX_DELAY_ITERATIONS;
> +  UINT8                           i;
> +
> +  LocalCoreHandle = (XDCI_CORE_HANDLE *)AllocateZeroPool (sizeof(XDCI_CORE_HANDLE));
> +
> +  if (CoreHandle == NULL) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  if (LocalCoreHandle == NULL) {
> +    DEBUG ((DEBUG_INFO, "DwcXdciCoreInit: Failed to allocate handle for xDCI\n"));
> +    return EFI_OUT_OF_RESOURCES;
> +  }
> +
> +  ZeroMem (LocalCoreHandle, sizeof(XDCI_CORE_HANDLE));
> +
> +  LocalCoreHandle->ParentHandle = deviceCorePtr;
> +
> +  *CoreHandle = (VOID *)LocalCoreHandle;
> +
> +  LocalCoreHandle->Id = ConfigParams->ControllerId;
> +  LocalCoreHandle->BaseAddress = BaseAddr = ConfigParams->BaseAddress;
> +  LocalCoreHandle->Flags = ConfigParams->Flags;
> +  LocalCoreHandle->DesiredSpeed = LocalCoreHandle->ActualSpeed = ConfigParams->Speed;
> +  LocalCoreHandle->Role = ConfigParams->Role;
> +
> +  DEBUG ((DEBUG_INFO, "Resetting the USB core\n"));
> +  UsbRegWrite (
> +    BaseAddr,
> +    DWC_XDCI_DCTL_REG,
> +    UsbRegRead (BaseAddr, DWC_XDCI_DCTL_REG) | DWC_XDCI_DCTL_CSFTRST_MASK
> +    );
> +  //
> +  // Wait until core soft reset completes
> +  //
> +  do {
> +    if (!(UsbRegRead (BaseAddr, DWC_XDCI_DCTL_REG) & DWC_XDCI_DCTL_CSFTRST_MASK)) {
> +      break;
> +    } else {
> +      gBS->Stall (DWC_XDCI_MAX_DELAY_ITERATIONS);
> +    }
> +  } while (--MaxDelayIter);
> +
> +  if (!MaxDelayIter) {
> +    DEBUG ((DEBUG_INFO, "Failed to reset device controller\n"));
> +    return EFI_DEVICE_ERROR;
> +  }
> +
> +  DEBUG ((DEBUG_INFO, "USB core has been reset\n"));
> +
> +  //
> +  // All FIFOs are flushed at this point
> +  //
> +  //
> +  // Ensure we have EP0 Rx/Tx handles initialized
> +  //
> +  LocalCoreHandle->EpHandles[0].EpInfo.EpNum = 0;
> +  LocalCoreHandle->EpHandles[0].EpInfo.EpDir = UsbEpDirOut;
> +  LocalCoreHandle->EpHandles[0].EpInfo.EpType = USB_ENDPOINT_CONTROL;
> +  LocalCoreHandle->EpHandles[0].EpInfo.MaxPktSize = DWC_XDCI_SS_CTRL_EP_MPS;
> +  //
> +  // 0 means burst size of 1
> +  //
> +  LocalCoreHandle->EpHandles[0].EpInfo.BurstSize = 0;
> +
> +  LocalCoreHandle->EpHandles[1].EpInfo.EpNum = 0;
> +  LocalCoreHandle->EpHandles[1].EpInfo.EpDir = UsbEpDirIn;
> +  LocalCoreHandle->EpHandles[1].EpInfo.EpType = USB_ENDPOINT_CONTROL;
> +  LocalCoreHandle->EpHandles[1].EpInfo.MaxPktSize = DWC_XDCI_SS_CTRL_EP_MPS;
> +  //
> +  // 0 means burst size of 1
> +  //
> +  LocalCoreHandle->EpHandles[1].EpInfo.BurstSize = 0;
> +
> +  LocalCoreHandle->DevState = UsbDevStateDefault;
> +
> +  //
> +  // Clear KeepConnect bit so we can allow disconnect and
> +  // re-connect. Stay in RX_DETECT state
> +  //
> +  UsbRegWrite (
> +    BaseAddr,
> +    DWC_XDCI_DCTL_REG,
> +    UsbRegRead (BaseAddr, DWC_XDCI_DCTL_REG) &
> +    (~DWC_XDCI_DCTL_KEEP_CONNECT_MASK) &
> +    ((~DWC_XDCI_DCTL_STATE_CHANGE_REQ_MASK) | (DWC_XDCI_DCTL_STATE_CHANGE_REQ_RX_DETECT << DWC_XDCI_DCTL_STATE_CHANGE_REQ_BIT_POS))
> +    );
> +
> +  DEBUG ((DEBUG_INFO, "Device controller Synopsys ID: %x\n", UsbRegRead (BaseAddr, DWC_XDCI_GSNPSID_REG)));
> +  DEBUG ((DEBUG_INFO, "Default value of xDCI GSBUSCFG0 and GSBUSCFG1: %x, %x\n",
> +          UsbRegRead (BaseAddr, DWC_XDCI_GSBUSCFG0_REG),
> +          UsbRegRead (BaseAddr, DWC_XDCI_GSBUSCFG1_REG)));
> +
> +  DEBUG ((DEBUG_INFO, "Default value of xDCI GTXTHRCFG and GRXTHRCFG: %x, %x\n",
> +          UsbRegRead (BaseAddr, DWC_XDCI_GTXTHRCFG_REG),
> +          UsbRegRead (BaseAddr, DWC_XDCI_GRXTHRCFG_REG)));
> +
> +  //
> +  // Clear ULPI auto-resume bit
> +  //
> +  UsbRegWrite (
> +    BaseAddr,
> +    DWC_XDCI_GUSB2PHYCFG_REG (0),
> +    (UsbRegRead (BaseAddr, DWC_XDCI_GUSB2PHYCFG_REG (0)) & ~DWC_XDCI_GUSB2PHYCFG_ULPI_AUTO_RESUME_MASK)
> +    );
> +
> +  DEBUG ((DEBUG_INFO, "Default value of xDCI GUSB2PHYCFG and GUSB3PIPECTL: %x, %x\n",
> +          UsbRegRead (BaseAddr, DWC_XDCI_GUSB2PHYCFG_REG (0)),
> +          UsbRegRead (BaseAddr, DWC_XDCI_GUSB3PIPECTL_REG (0))));
> +  //
> +  // Only one RxFIFO
> +  //
> +  DEBUG ((DEBUG_INFO, "Default value of DWC_XDCI_GRXFIFOSIZ: %x\n",
> +          UsbRegRead (BaseAddr, DWC_XDCI_GRXFIFOSIZ_REG (0))));
> +
> +  for (i = 0; i < DWC_XDCI_MAX_ENDPOINTS; i++) {
> +    DEBUG ((DEBUG_INFO, "Default value of xDCI DWC_XDCI_GTXFIFOSIZ %d: %x\n",
> +            i, UsbRegRead (BaseAddr, DWC_XDCI_GTXFIFOSIZ_REG (i))));
> +  }
> +
> +  //
> +  // TODO: Need to check if TxFIFO should start where RxFIFO ends
> +  // or default is correct i.e. TxFIFO starts at 0 just like RxFIFO
> +  //
> +
> +  //
> +  // Allocate and Initialize Event Buffers
> +  //
> +  LocalCoreHandle->MaxDevIntLines = ((UsbRegRead (BaseAddr, DWC_XDCI_GHWPARAMS1_REG) &
> +                                           DWC_XDCI_GHWPARAMS1_NUM_INT_MASK) >>
> +                                           DWC_XDCI_GHWPARAMS1_NUM_INT_BIT_POS);
> +
> +  DEBUG ((DEBUG_INFO, "Max dev int lines: %d\n", LocalCoreHandle->MaxDevIntLines));
> +  //
> +  // One event Buffer per interrupt line.
> +  //  Need to align it to size of event Buffer
> +  //  Buffer needs to be big enough. Otherwise the core
> +  //  won't operate
> +  //
> +  LocalCoreHandle->AlignedEventBuffers = (DWC_XDCI_EVENT_BUFFER *)
> +                                             ((UINT32)(UINTN)(LocalCoreHandle->EventBuffers) +
> +                                             ((sizeof (DWC_XDCI_EVENT_BUFFER) * DWC_XDCI_MAX_EVENTS_PER_BUFFER) -
> +                                             (((UINT32)(UINTN)(LocalCoreHandle->EventBuffers)) %
> +                                             (sizeof (DWC_XDCI_EVENT_BUFFER) * DWC_XDCI_MAX_EVENTS_PER_BUFFER))));
> +
> +  for (i = 0; i < LocalCoreHandle->MaxDevIntLines; i++) {
> +    UsbRegWrite (
> +      BaseAddr,
> +      DWC_XDCI_GEVNTADR_REG (i),
> +      (UINT32)(UINTN)(LocalCoreHandle->AlignedEventBuffers + i * sizeof(DWC_XDCI_EVENT_BUFFER) * DWC_XDCI_MAX_EVENTS_PER_BUFFER)
> +      );
> +
> +    //
> +    // Clear High 32bit address register, GEVNTADR register is 64-bit register
> +    // default is 0xffffffffffffffff
> +    //
> +    UsbRegWrite (BaseAddr, DWC_XDCI_GEVNTADR_REG (i) + 4, 0x00000000);
> +
> +    LocalCoreHandle->CurrentEventBuffer = LocalCoreHandle->AlignedEventBuffers;
> +    //
> +    // Write size and clear the mask
> +    //
> +    UsbRegWrite (
> +      BaseAddr,
> +      DWC_XDCI_EVNTSIZ_REG (i),
> +      sizeof (DWC_XDCI_EVENT_BUFFER) * DWC_XDCI_MAX_EVENTS_PER_BUFFER
> +      );
> +
> +    //
> +    // Write 0 to the event count register as the last step
> +    //
> +    //  for event configuration
> +    //
> +    UsbRegWrite (BaseAddr, DWC_XDCI_EVNTCOUNT_REG (i), 0);
> +
> +    DEBUG ((DEBUG_INFO, "Value of xDCI Event Buffer %d: %x, Size: %x, Count: %x\n",
> +                        i,
> +                        UsbRegRead (BaseAddr, DWC_XDCI_GEVNTADR_REG (i)),
> +                        UsbRegRead (BaseAddr, DWC_XDCI_EVNTSIZ_REG (i)),
> +                        UsbRegRead (BaseAddr, DWC_XDCI_EVNTCOUNT_REG (i))));
> +  }
> +
> +    //
> +    // Program Global Control Register to disable scaledown,
> +    // disable clock gating
> +    //
> +    UsbRegWrite (
> +      BaseAddr,
> +      DWC_XDCI_GCTL_REG,
> +      ((UsbRegRead(BaseAddr, DWC_XDCI_GCTL_REG) &
> +                    ~(DWC_XDCI_GCTL_SCALE_DOWN_MODE_MASK + DWC_XDCI_GCTL_RAMCLKSEL_MASK + DWC_XDCI_GCTL_DISABLE_SCRAMB_MASK)) |
> +                    DWC_XDCI_GCTL_DISABLE_CLK_GATING_MASK |
> +                    (DWC_XDCI_GCTL_PRT_CAP_DEVICE << DWC_XDCI_GCTL_PRT_CAP_DIR_BIT_POS)));
> +
> +    DEBUG ((DEBUG_INFO, "Setup value of xDCI DWC_XDCI_GCTL_REG: 0x%x\n", UsbRegRead (BaseAddr, DWC_XDCI_GCTL_REG)));
> +
> +  //
> +  // TODO: Program desired Speed and set LPM capable
> +  // We will do this when SuperSpeed works. For now,
> +  // force into High-Speed mode to aVOID anyone trying this
> +  // on Super Speed port
> +  //
> +#ifdef SUPPORT_SUPER_SPEED
> +  UsbRegWrite (
> +    BaseAddr,
> +    DWC_XDCI_DCFG_REG,
> +    (UsbRegRead (BaseAddr, DWC_XDCI_DCFG_REG) & ~DWC_XDCI_DCFG_DESIRED_DEV_SPEED_MASK) | LocalCoreHandle->DesiredSpeed
> +    );
> +#else
> +  UsbRegWrite (
> +    BaseAddr,
> +    DWC_XDCI_DCFG_REG,
> +    (UsbRegRead (BaseAddr, DWC_XDCI_DCFG_REG) & ~DWC_XDCI_DCFG_DESIRED_DEV_SPEED_MASK) | DWC_XDCI_DCFG_DESIRED_HS_SPEED
> +    );
> +#endif
> +
> +  DEBUG ((DEBUG_INFO, "Setup value of xDCI DWC_XDCI_DCFG_REG: 0x%x\n", UsbRegRead (BaseAddr, DWC_XDCI_DCFG_REG)));
> +  DEBUG ((DEBUG_INFO, "Setup value of xDCI DWC_XDCI_DSTS_REG: 0x%x\n", UsbRegRead (BaseAddr, DWC_XDCI_DSTS_REG)));
> +
> +  //
> +  // Enable Device Interrupt Events
> +  //
> +  UsbRegWrite (
> +    BaseAddr,
> +    DWC_XDCI_DEVTEN_REG,
> +    DWC_XDCI_DEVTEN_DEVICE_INTS
> +    );
> +  //
> +  // Program the desired role
> +  //
> +  UsbRegWrite (
> +    BaseAddr,
> +    DWC_XDCI_GCTL_REG,
> +    (UsbRegRead (BaseAddr, DWC_XDCI_GCTL_REG) & ~DWC_XDCI_GCTL_PRT_CAP_DIR_MASK) | (LocalCoreHandle->Role << DWC_XDCI_GCTL_PRT_CAP_DIR_BIT_POS)
> +    );
> +  //
> +  // Clear USB2 suspend for start new config command
> +  //
> +  UsbRegWrite (
> +    BaseAddr,
> +    DWC_XDCI_GUSB2PHYCFG_REG (0),
> +    (UsbRegRead (BaseAddr, DWC_XDCI_GUSB2PHYCFG_REG(0)) & ~DWC_XDCI_GUSB2PHYCFG_SUSPEND_PHY_MASK)
> +    );
> +
> +  //
> +  // Clear USB3 suspend for start new config command
> +  //
> +  UsbRegWrite (
> +    BaseAddr,
> +    DWC_XDCI_GUSB3PIPECTL_REG (0),
> +    (UsbRegRead (BaseAddr, DWC_XDCI_GUSB3PIPECTL_REG(0)) & ~DWC_XDCI_GUSB3PIPECTL_SUSPEND_PHY_MASK)
> +    );
> +
> +  //
> +  // Issue DEPSTARTCFG command for EP0
> +  //
> +  status = DwcXdciCoreInitEpCmdParams (
> +             LocalCoreHandle,
> +             &LocalCoreHandle->EpHandles[0].EpInfo,
> +             DWC_XDCI_PARAM0_SET_EP_CFG_ACTN_NONE,
> +             EPCMD_START_NEW_CONFIG,
> +             &EpCmdParams
> +             );
> +
> +  if (status) {
> +    DEBUG ((DEBUG_INFO, "DwcXdciCoreInit: Failed to init params for START_NEW_CONFIG EP command on xDCI\n"));
> +    return status;
> +  }
> +
> +  //
> +  // Issue the command
> +  //
> +  status = DwcXdciCoreIssueEpCmd (
> +             LocalCoreHandle,
> +             0,
> +             EPCMD_START_NEW_CONFIG,
> +             &EpCmdParams
> +             );
> +
> +  if (status) {
> +    DEBUG ((DEBUG_INFO, "DwcXdciCoreInit: Failed to issue START_NEW_CONFIG EP command on xDCI\n"));
> +    return status;
> +  }
> +
> +  //
> +  // Issue DEPCFG command for EP0
> +  //
> +  status = DwcXdciCoreInitEpCmdParams (
> +             LocalCoreHandle,
> +             &LocalCoreHandle->EpHandles[0].EpInfo,
> +             DWC_XDCI_PARAM0_SET_EP_CFG_ACTN_INIT_STATE,
> +             EPCMD_SET_EP_CONFIG,
> +             &EpCmdParams
> +             );
> +
> +  if (status) {
> +    DEBUG ((DEBUG_INFO, "DwcXdciCoreInit: Failed to init params for SET_EP_CONFIG command on xDCI for EP0\n"));
> +    return status;
> +  }
> +
> +  //
> +  // Issue the command
> +  //
> +  status = DwcXdciCoreIssueEpCmd (
> +             LocalCoreHandle,
> +             0,
> +             EPCMD_SET_EP_CONFIG,
> +             &EpCmdParams);
> +
> +  if (status) {
> +    DEBUG ((DEBUG_INFO, "DwcXdciCoreInit: Failed to issue SET_EP_CONFIG command on xDCI for EP0\n"));
> +    return status;
> +  }
> +
> +  //
> +  // Issue DEPCFG command for EP1
> +  //
> +  status = DwcXdciCoreInitEpCmdParams (
> +             LocalCoreHandle,
> +             &LocalCoreHandle->EpHandles[1].EpInfo,
> +             DWC_XDCI_PARAM0_SET_EP_CFG_ACTN_INIT_STATE,
> +             EPCMD_SET_EP_CONFIG,
> +             &EpCmdParams
> +             );
> +
> +  if (status) {
> +    DEBUG ((DEBUG_INFO, "DwcXdciCoreInit: Failed to init params for SET_EP_CONFIG command on xDCI for EP1\n"));
> +    return status;
> +  }
> +
> +  //
> +  // Issue the command
> +  //
> +  status = DwcXdciCoreIssueEpCmd (
> +             LocalCoreHandle,
> +             1,
> +             EPCMD_SET_EP_CONFIG,
> +             &EpCmdParams
> +             );
> +
> +  if (status) {
> +    DEBUG ((DEBUG_INFO, "DwcXdciCoreInit: Failed to issue SET_EP_CONFIG command on xDCI for EP1\n"));
> +    return status;
> +  }
> +
> +  //
> +  // Issue DEPXFERCFG command for EP0
> +  //
> +  status = DwcXdciCoreInitEpCmdParams (
> +             LocalCoreHandle,
> +             &LocalCoreHandle->EpHandles[0].EpInfo,
> +             DWC_XDCI_PARAM0_SET_EP_CFG_ACTN_NONE,
> +             EPCMD_SET_EP_XFER_RES_CONFIG,
> +             &EpCmdParams
> +             );
> +
> +  if (status) {
> +    DEBUG ((DEBUG_INFO, "DwcXdciCoreInit: Failed to init params for EPCMD_SET_EP_XFER_RES_CONFIG command on xDCI for EP0\n"));
> +    return status;
> +  }
> +
> +  //
> +  // Issue the command
> +  //
> +  status = DwcXdciCoreIssueEpCmd (
> +             LocalCoreHandle,
> +             0,
> +             EPCMD_SET_EP_XFER_RES_CONFIG,
> +             &EpCmdParams
> +             );
> +
> +  if (status) {
> +    DEBUG ((DEBUG_INFO, "DwcXdciCoreInit: Failed to issue EPCMD_SET_EP_XFER_RES_CONFIG command on xDCI for EP0\n"));
> +    return status;
> +  }
> +
> +  //
> +  // Issue DEPXFERCFG command for EP1
> +  //
> +  status = DwcXdciCoreInitEpCmdParams (
> +             LocalCoreHandle,
> +             &LocalCoreHandle->EpHandles[1].EpInfo,
> +             DWC_XDCI_PARAM0_SET_EP_CFG_ACTN_NONE,
> +             EPCMD_SET_EP_XFER_RES_CONFIG,
> +             &EpCmdParams
> +             );
> +
> +  if (status) {
> +    DEBUG ((DEBUG_INFO, "DwcXdciCoreInit: Failed to init params for EPCMD_SET_EP_XFER_RES_CONFIG command on xDCI for EP1\n"));
> +    return status;
> +  }
> +
> +  //
> +  // Issue the command
> +  //
> +  status = DwcXdciCoreIssueEpCmd (
> +             LocalCoreHandle,
> +             1,
> +             EPCMD_SET_EP_XFER_RES_CONFIG,
> +             &EpCmdParams
> +             );
> +
> +  if (status) {
> +    DEBUG ((DEBUG_INFO, "DwcXdciCoreInit: Failed to issue EPCMD_SET_EP_XFER_RES_CONFIG command on xDCI for EP1\n"));
> +    return status;
> +  }
> +
> +  //
> +  // Prepare a Buffer for SETUP packet
> +  //
> +  LocalCoreHandle->Trbs = (DWC_XDCI_TRB *)((UINTN)
> +                            LocalCoreHandle->UnalignedTrbs +
> +                            (UINTN)(DWC_XDCI_TRB_BYTE_ALIGNMENT -
> +                            ((UINT32)(UINTN)LocalCoreHandle->UnalignedTrbs %
> +                            DWC_XDCI_TRB_BYTE_ALIGNMENT)));
> +
> +  DEBUG ((DEBUG_INFO, "(DwcXdciCoreInit)@@@@@@@@@ unalignedTrbs address is 0x%x\n", LocalCoreHandle->UnalignedTrbs));
> +  DEBUG ((DEBUG_INFO, "(DwcXdciCoreInit)@@@@@@@@@ TRB address is 0x%x\n", LocalCoreHandle->Trbs));
> +  //
> +  // Allocate Setup Buffer that is 8-byte aligned
> +  //
> +  LocalCoreHandle->AlignedSetupBuffer = LocalCoreHandle->DefaultSetupBuffer +
> +                                            (DWC_XDCI_SETUP_BUFF_SIZE -
> +                                            ((UINT32)(UINTN)(LocalCoreHandle->DefaultSetupBuffer) % DWC_XDCI_SETUP_BUFF_SIZE));
> +
> +  //
> +  // Aligned Buffer for status phase
> +  //
> +  LocalCoreHandle->AlignedMiscBuffer = LocalCoreHandle->MiscBuffer +
> +                                           (DWC_XDCI_SETUP_BUFF_SIZE -
> +                                           ((UINT32)(UINTN)(LocalCoreHandle->AlignedMiscBuffer) % DWC_XDCI_SETUP_BUFF_SIZE));
> +
> +
> +  //
> +  // Enable Physical Endpoints 0
> +  //
> +  UsbRegWrite (
> +    BaseAddr,
> +    DWC_XDCI_EP_DALEPENA_REG,
> +    UsbRegRead (BaseAddr, DWC_XDCI_EP_DALEPENA_REG) | (1 << 0)
> +    );
> +  //
> +  // Enable Physical Endpoints 1
> +  //
> +  UsbRegWrite (
> +    BaseAddr,
> +    DWC_XDCI_EP_DALEPENA_REG,
> +    UsbRegRead (BaseAddr, DWC_XDCI_EP_DALEPENA_REG) | (1 << 1)
> +    );
> +
> +  DEBUG ((DEBUG_INFO, "Default value of xDCI DWC_XDCI_DEVTEN_REG: 0x%x\n", UsbRegRead (BaseAddr, DWC_XDCI_DEVTEN_REG)));
> +  return status;
> +}
> +
> +
> +/**
> +  Interface:
> +  This function is used to de-initialize the xDCI core
> +  @CoreHandle: xDCI controller handle
> +  @flags: Special flags for de-initializing the core in
> +  particular way
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +DwcXdciCoreDeinit (
> +  IN VOID      *CoreHandle,
> +  IN UINT32    flags
> +  )
> +{
> +  FreePool (CoreHandle);
> +  return EFI_SUCCESS;
> +}
> +
> +
> +/**
> +  Interface:
> +  This function is used to register event callback function
> +  @CoreHandle: xDCI controller handle
> +  @event: Event for which callback is to be registered
> +  @callbackFn: Callback function to invoke after event occurs
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +DwcXdciCoreRegisterCallback (
> +  IN VOID                      *CoreHandle,
> +  IN USB_DEVICE_EVENT_ID       Event,
> +  IN USB_DEVICE_CALLBACK_FUNC  CallbackFunc
> +  )
> +{
> +  XDCI_CORE_HANDLE  *LocalCoreHandle = (XDCI_CORE_HANDLE *)CoreHandle;
> +
> +  if (LocalCoreHandle == NULL) {
> +    DEBUG ((DEBUG_INFO, "DwcXdciCoreRegisterCallback: INVALID handle\n"));
> +    return EFI_DEVICE_ERROR;
> +  }
> +
> +  DEBUG ((DEBUG_INFO, "DwcXdciCoreRegisterCallback: event is %d\n", Event));
> +  switch (Event) {
> +    case USB_DEVICE_DISCONNECT_EVENT:
> +      LocalCoreHandle->EventCallbacks.DevDisconnectCallback = CallbackFunc;
> +      break;
> +
> +    case USB_DEVICE_RESET_EVENT:
> +      LocalCoreHandle->EventCallbacks.DevBusResetCallback = CallbackFunc;
> +      break;
> +
> +    case USB_DEVICE_CONNECTION_DONE:
> +      LocalCoreHandle->EventCallbacks.DevResetDoneCallback = CallbackFunc;
> +      break;
> +
> +    case USB_DEVICE_STATE_CHANGE_EVENT:
> +      LocalCoreHandle->EventCallbacks.DevLinkStateCallback = CallbackFunc;
> +      break;
> +
> +    case USB_DEVICE_WAKEUP_EVENT:
> +      LocalCoreHandle->EventCallbacks.DevWakeupCallback = CallbackFunc;
> +      break;
> +
> +    case USB_DEVICE_HIBERNATION_REQ_EVENT:
> +      LocalCoreHandle->EventCallbacks.DevHibernationCallback = CallbackFunc;
> +      break;
> +
> +    case USB_DEVICE_SOF_EVENT:
> +      LocalCoreHandle->EventCallbacks.DevSofCallback = CallbackFunc;
> +      break;
> +
> +    case USB_DEVICE_ERRATIC_ERR_EVENT:
> +      LocalCoreHandle->EventCallbacks.DevErraticErrCallback = CallbackFunc;
> +      break;
> +
> +    case USB_DEVICE_CMD_CMPLT_EVENT:
> +      LocalCoreHandle->EventCallbacks.DevCmdCmpltCallback = CallbackFunc;
> +      break;
> +
> +    case USB_DEVICE_BUFF_OVERFLOW_EVENT:
> +      LocalCoreHandle->EventCallbacks.DevBuffOvflwCallback = CallbackFunc;
> +      break;
> +
> +    case USB_DEVICE_TEST_LMP_RX_EVENT:
> +      LocalCoreHandle->EventCallbacks.DevTestLmpRxCallback = CallbackFunc;
> +      break;
> +
> +    case USB_DEVICE_SETUP_PKT_RECEIVED:
> +      LocalCoreHandle->EventCallbacks.DevSetupPktReceivedCallback = CallbackFunc;
> +      break;
> +
> +    case USB_DEVICE_XFER_NRDY:
> +      LocalCoreHandle->EventCallbacks.DevXferNrdyCallback = CallbackFunc;
> +      break;
> +
> +    case USB_DEVICE_XFER_DONE:
> +      LocalCoreHandle->EventCallbacks.DevXferDoneCallback = CallbackFunc;
> +      break;
> +
> +    default:
> +      break;
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +
> +/**
> +  Interface:
> +  This function is used to unregister event callback function
> +  @CoreHandle: xDCI controller handle
> +  @event: Event for which callback function is to be unregistered
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +DwcXdciCoreUnregisterCallback (
> +  IN VOID                   *CoreHandle,
> +  IN USB_DEVICE_EVENT_ID    event
> +  )
> +{
> +  XDCI_CORE_HANDLE  *LocalCoreHandle = (XDCI_CORE_HANDLE *)CoreHandle;
> +
> +  if (LocalCoreHandle == NULL) {
> +    DEBUG ((DEBUG_INFO, "DwcXdciCoreUnregisterCallback: INVALID handle\n"));
> +    return EFI_DEVICE_ERROR;
> +  }
> +
> +  switch (event) {
> +    case USB_DEVICE_DISCONNECT_EVENT:
> +      LocalCoreHandle->EventCallbacks.DevDisconnectCallback = NULL;
> +      break;
> +
> +    case USB_DEVICE_RESET_EVENT:
> +      LocalCoreHandle->EventCallbacks.DevBusResetCallback = NULL;
> +      break;
> +
> +    case USB_DEVICE_CONNECTION_DONE:
> +      LocalCoreHandle->EventCallbacks.DevResetDoneCallback = NULL;
> +      break;
> +
> +    case USB_DEVICE_STATE_CHANGE_EVENT:
> +      LocalCoreHandle->EventCallbacks.DevLinkStateCallback = NULL;
> +      break;
> +
> +    case USB_DEVICE_WAKEUP_EVENT:
> +      LocalCoreHandle->EventCallbacks.DevWakeupCallback = NULL;
> +      break;
> +
> +    case USB_DEVICE_HIBERNATION_REQ_EVENT:
> +      LocalCoreHandle->EventCallbacks.DevHibernationCallback = NULL;
> +      break;
> +
> +    case USB_DEVICE_SOF_EVENT:
> +      LocalCoreHandle->EventCallbacks.DevSofCallback = NULL;
> +      break;
> +
> +    case USB_DEVICE_ERRATIC_ERR_EVENT:
> +      LocalCoreHandle->EventCallbacks.DevErraticErrCallback = NULL;
> +      break;
> +
> +    case USB_DEVICE_CMD_CMPLT_EVENT:
> +      LocalCoreHandle->EventCallbacks.DevCmdCmpltCallback = NULL;
> +      break;
> +
> +    case USB_DEVICE_BUFF_OVERFLOW_EVENT:
> +      LocalCoreHandle->EventCallbacks.DevBuffOvflwCallback = NULL;
> +      break;
> +
> +    case USB_DEVICE_TEST_LMP_RX_EVENT:
> +      LocalCoreHandle->EventCallbacks.DevTestLmpRxCallback = NULL;
> +      break;
> +
> +    case USB_DEVICE_SETUP_PKT_RECEIVED:
> +      LocalCoreHandle->EventCallbacks.DevSetupPktReceivedCallback = NULL;
> +      break;
> +
> +    case USB_DEVICE_XFER_NRDY:
> +      LocalCoreHandle->EventCallbacks.DevXferNrdyCallback = NULL;
> +      break;
> +
> +    case USB_DEVICE_XFER_DONE:
> +      LocalCoreHandle->EventCallbacks.DevXferDoneCallback = NULL;
> +      break;
> +
> +    default:
> +      break;
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +
> +/**
> +  Interface:
> +  This function is used as an interrupt service routine
> +  @CoreHandle: xDCI controller handle
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +DwcXdciCoreIsrRoutine (
> +  IN VOID     *CoreHandle
> +  )
> +{
> +  XDCI_CORE_HANDLE    *LocalCoreHandle = (XDCI_CORE_HANDLE *)CoreHandle;
> +  UINT32              BaseAddr;
> +  UINT32              eventCount;
> +  UINT32              ProcessedEventCount;
> +  UINT32              i;
> +
> +  if (CoreHandle == NULL) {
> +    DEBUG ((DEBUG_INFO, "DwcXdciCoreIsrRoutine: INVALID handle\n"));
> +    return EFI_DEVICE_ERROR;
> +  }
> +
> +  if (LocalCoreHandle->InterrupProcessing == TRUE) {
> +    DEBUG ((DEBUG_INFO, "interrupProcessing.........\n"));
> +    return EFI_SUCCESS;
> +  }
> +
> +  BaseAddr = LocalCoreHandle->BaseAddress;
> +  //
> +  // Event Buffer corresponding to each interrupt line needs
> +  // to be Processed
> +  //
> +  LocalCoreHandle->InterrupProcessing = TRUE;
> +  for (i = 0; i < LocalCoreHandle->MaxDevIntLines; i++) {
> +    //
> +    // Get the number of events HW has written for this
> +    //  interrupt line
> +    //
> +    eventCount = UsbRegRead (BaseAddr, DWC_XDCI_EVNTCOUNT_REG (i));
> +    eventCount &= DWC_XDCI_EVNTCOUNT_MASK;
> +    ProcessedEventCount = 0;
> +
> +    //
> +    // Process interrupt line Buffer only if count is non-zero
> +    //
> +    if (eventCount) {
> +      //
> +      // Process events in this Buffer
> +      //
> +      DwcXdciProcessInterruptLineEvents (LocalCoreHandle, eventCount, &ProcessedEventCount);
> +      //
> +      // Write back the Processed number of events so HW decrements it from current
> +      // event count
> +      //
> +      UsbRegWrite (BaseAddr, DWC_XDCI_EVNTCOUNT_REG (i), ProcessedEventCount);
> +    }
> +  }
> +  LocalCoreHandle->InterrupProcessing = FALSE;
> +  return EFI_SUCCESS;
> +}
> +
> +
> +/**
> +  Interface:
> +  This function is used as an interrupt service routine and it processes only one event at a time.
> +  @CoreHandle: xDCI controller handle
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +DwcXdciCoreIsrRoutineTimerBased (
> +  IN VOID     *CoreHandle
> +  )
> +{
> +  XDCI_CORE_HANDLE    *LocalCoreHandle = (XDCI_CORE_HANDLE *)CoreHandle;
> +  UINT32              BaseAddr;
> +  UINT32              eventCount;
> +  UINT32              ProcessedEventCount;
> +  UINT32              currentEventAddr;
> +  UINT32              ProcessedEventSize = 0;
> +
> +  if (CoreHandle == NULL) {
> +    DEBUG ((DEBUG_INFO, "DwcXdciCoreIsrRoutineTimerBased: INVALID handle\n"));
> +    return EFI_DEVICE_ERROR;
> +  }
> +
> +  if (LocalCoreHandle->CurrentEventBuffer == NULL) {
> +    DEBUG ((DEBUG_INFO, "ERROR: DwcXdciCoreIsrRoutineTimerBased: INVALID event Buffer\n"));
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  BaseAddr = LocalCoreHandle->BaseAddress;
> +
> +  eventCount = UsbRegRead (BaseAddr, DWC_XDCI_EVNTCOUNT_REG (0)) & DWC_XDCI_EVNTCOUNT_MASK;
> +
> +  if (LocalCoreHandle->InterrupProcessing == TRUE) {
> +    DEBUG ((DEBUG_INFO, "interrupProcessing.........\n"));
> +    return EFI_SUCCESS;
> +  }
> +
> +  LocalCoreHandle->InterrupProcessing = TRUE;
> +
> +  ProcessedEventCount = 0;
> +  currentEventAddr = (UINT32)(UINTN)(LocalCoreHandle->CurrentEventBuffer);
> +
> +  if (LocalCoreHandle->CurrentEventBuffer->Event & DWC_XDCI_EVENT_DEV_MASK) {
> +    DwcXdciProcessDeviceEvent (
> +      LocalCoreHandle,
> +      LocalCoreHandle->CurrentEventBuffer,
> +      &ProcessedEventSize
> +      );
> +  } else {
> +    DwcXdciProcessEpEvent (
> +      LocalCoreHandle,
> +      LocalCoreHandle->CurrentEventBuffer,
> +      &ProcessedEventSize);
> +  }
> +
> +  eventCount -= ProcessedEventSize;
> +  ProcessedEventCount += ProcessedEventSize;
> +  if ((currentEventAddr + ProcessedEventSize) >=
> +      ((UINT32)(UINTN)(LocalCoreHandle->AlignedEventBuffers) + (sizeof(DWC_XDCI_EVENT_BUFFER) * DWC_XDCI_MAX_EVENTS_PER_BUFFER))
> +     ) {
> +    currentEventAddr = (UINT32)(UINTN)(LocalCoreHandle->AlignedEventBuffers);
> +    DEBUG ((DEBUG_INFO, "DwcXdciProcessInterruptLineEvents: Event Buffer bound reached\n"));
> +  } else {
> +    currentEventAddr += ProcessedEventSize;
> +  }
> +
> +  LocalCoreHandle->CurrentEventBuffer = (DWC_XDCI_EVENT_BUFFER *)(UINTN)currentEventAddr;
> +  UsbRegWrite (BaseAddr, DWC_XDCI_EVNTCOUNT_REG (0), ProcessedEventCount);
> +  LocalCoreHandle->InterrupProcessing = FALSE;
> +
> +  return EFI_SUCCESS;
> +}
> +
> +
> +/**
> +  Interface:
> +  This function is used to enable xDCI to connect to the host
> +  @CoreHandle: xDCI controller handle
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +DwcXdciCoreConnect (
> +  IN VOID     *CoreHandle
> +  )
> +{
> +  XDCI_CORE_HANDLE    *LocalCoreHandle = (XDCI_CORE_HANDLE *)CoreHandle;
> +  UINT32              MaxDelayIter = DWC_XDCI_MAX_DELAY_ITERATIONS;
> +  UINT32              BaseAddr;
> +
> +  if (CoreHandle == NULL) {
> +    DEBUG ((DEBUG_INFO, "DwcXdciCoreConnect: INVALID handle\n"));
> +    return EFI_DEVICE_ERROR;
> +  }
> +
> +  BaseAddr = LocalCoreHandle->BaseAddress;
> +
> +  //
> +  // Clear KeepConnect bit so we can allow disconnect and re-connect
> +  // Also issue No action on state change to aVOID any link change
> +  //
> +  UsbRegWrite (
> +    BaseAddr,
> +    DWC_XDCI_DCTL_REG,
> +    (UsbRegRead(BaseAddr, DWC_XDCI_DCTL_REG) & ~DWC_XDCI_DCTL_KEEP_CONNECT_MASK) & ~DWC_XDCI_DCTL_STATE_CHANGE_REQ_MASK
> +    );
> +
> +  //
> +  // Set Run bit to connect to the host
> +  //
> +  UsbRegWrite (
> +    BaseAddr,
> +    DWC_XDCI_DCTL_REG,
> +    UsbRegRead (BaseAddr, DWC_XDCI_DCTL_REG) | DWC_XDCI_DCTL_RUN_STOP_MASK
> +    );
> +
> +  //
> +  // Wait until core starts running
> +  //
> +  do {
> +    if (!(UsbRegRead (BaseAddr, DWC_XDCI_DSTS_REG) & DWC_XDCI_DSTS_DEV_CTRL_HALTED_MASK)) {
> +      break;
> +    } else {
> +      gBS->Stall (DWC_XDCI_MAX_DELAY_ITERATIONS);
> +    }
> +  } while (--MaxDelayIter);
> +
> +  if (!MaxDelayIter) {
> +    DEBUG ((DEBUG_INFO, "Failed to run the device controller\n"));
> +    return EFI_DEVICE_ERROR;
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +
> +/**
> +  Interface:
> +  This function is used to disconnect xDCI from the host
> +  @CoreHandle: xDCI controller handle
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +DwcXdciCoreDisconnect (
> +  IN VOID    *CoreHandle
> +  )
> +{
> +  XDCI_CORE_HANDLE  *LocalCoreHandle = (XDCI_CORE_HANDLE *)CoreHandle;
> +  UINT32            MaxDelayIter = DWC_XDCI_MAX_DELAY_ITERATIONS;
> +  UINT32            BaseAddr;
> +  UINT32            eventCount;
> +  UINT32            dsts;
> +  UINT32            i;
> +
> +  if (CoreHandle == NULL) {
> +    DEBUG ((DEBUG_INFO, "DwcXdciCoreDisconnect: INVALID handle\n"));
> +    return EFI_DEVICE_ERROR;
> +  }
> +
> +  BaseAddr = LocalCoreHandle->BaseAddress;
> +
> +  eventCount = UsbRegRead (BaseAddr, DWC_XDCI_EVNTCOUNT_REG (0));
> +  eventCount &= DWC_XDCI_EVNTCOUNT_MASK;
> +
> +  DEBUG ((DEBUG_INFO, "DwcXdciCoreDisconnect: eventCount=%d\n", eventCount));
> +  while (eventCount) {
> +    DwcXdciCoreIsrRoutine(LocalCoreHandle);
> +    eventCount = UsbRegRead (BaseAddr, DWC_XDCI_EVNTCOUNT_REG (0));
> +    eventCount &= DWC_XDCI_EVNTCOUNT_MASK;
> +    DEBUG ((DEBUG_INFO, "DwcXdciCoreDisconnect: eventCount=%d\n", eventCount));
> +  }
> +
> +  //
> +  // Issue DEPENDXFER for active transfers
> +  //
> +  for (i = 0; i < DWC_XDCI_MAX_ENDPOINTS; i++){
> +    if (LocalCoreHandle->EpHandles[i].CurrentXferRscIdx){
> +      DwcXdciEndXfer(LocalCoreHandle, i);
> +    }
> +  }
> +  //
> +  // Clear Run bit to disconnect from host
> +  //
> +  UsbRegWrite (
> +    BaseAddr,
> +    DWC_XDCI_DCTL_REG,
> +    UsbRegRead(BaseAddr, DWC_XDCI_DCTL_REG) & ~DWC_XDCI_DCTL_RUN_STOP_MASK);
> +
> +  //
> +  // Wait until core is halted
> +  //
> +  do {
> +    dsts = UsbRegRead (BaseAddr, DWC_XDCI_DSTS_REG);
> +    DEBUG ((DEBUG_INFO, "DwcXdciCoreDisconnect: waiting halt: DSTS=0x%x\n", dsts));
> +    if ((dsts & DWC_XDCI_DSTS_DEV_CTRL_HALTED_MASK) != 0){
> +      break;
> +    } else {
> +      gBS->Stall (DWC_XDCI_MAX_DELAY_ITERATIONS);
> +    }
> +  } while (--MaxDelayIter);
> +
> +  if (!MaxDelayIter) {
> +    DEBUG ((DEBUG_INFO, "DwcXdciCoreDisconnect: Failed to halt the device controller\n"));
> +    return EFI_DEVICE_ERROR;
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +
> +/**
> +  Interface:
> +  This function is used to obtain current USB bus Speed
> +  @CoreHandle: xDCI controller handle
> +  @Speed: Address of variable to save the Speed
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +DwcXdciCoreGetSpeed (
> +  IN VOID         *CoreHandle,
> +  IN USB_SPEED    *Speed
> +  )
> +{
> +  XDCI_CORE_HANDLE *LocalCoreHandle = (XDCI_CORE_HANDLE *)CoreHandle;
> +
> +  if (CoreHandle == NULL) {
> +    DEBUG ((DEBUG_INFO, "DwcXdciCoreGetSpeed: INVALID handle\n"));
> +    return EFI_DEVICE_ERROR;
> +  }
> +
> +  if (Speed == NULL) {
> +    DEBUG ((DEBUG_INFO, "DwcXdciCoreGetSpeed: INVALID parameter\n"));
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  *Speed = UsbRegRead (LocalCoreHandle->BaseAddress, DWC_XDCI_DSTS_REG) & DWC_XDCI_DSTS_CONN_SPEED_MASK;
> +
> +  return EFI_SUCCESS;
> +}
> +
> +
> +/**
> +  Interface:
> +  This function is used to obtain current USB bus Speed
> +  @CoreHandle: xDCI controller handle
> +  @address: USB address to set (assigned by USB host)
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +DwcXdciCoreSetAddress (
> +  IN VOID      *CoreHandle,
> +  IN UINT32    address
> +  )
> +{
> +  XDCI_CORE_HANDLE  *LocalCoreHandle = (XDCI_CORE_HANDLE *)CoreHandle;
> +  UINT32            BaseAddr;
> +
> +  if (CoreHandle == NULL) {
> +    DEBUG ((DEBUG_INFO, "DwcXdciCoreSetAddress: INVALID handle\n"));
> +    return EFI_DEVICE_ERROR;
> +  }
> +
> +  BaseAddr = LocalCoreHandle->BaseAddress;
> +
> +  DEBUG ((DEBUG_INFO, "DwcXdciCoreSetAddress is 0x%x \n", address));
> +  //
> +  // Program USB device address
> +  //
> +  UsbRegWrite (
> +    BaseAddr,
> +    DWC_XDCI_DCFG_REG,
> +    (UsbRegRead(BaseAddr, DWC_XDCI_DCFG_REG) & ~DWC_XDCI_DCFG_DEV_ADDRESS_MASK) | (address << DWC_XDCI_DCFG_DEV_ADDRESS_BIT_POS)
> +    );
> +
> +  LocalCoreHandle->DevState = UsbDevStateAddress;
> +  DEBUG ((DEBUG_INFO, "Setup value of xDCI DWC_XDCI_GCTL_REG: 0x%x\n", UsbRegRead (BaseAddr, DWC_XDCI_GCTL_REG)));
> +  DEBUG ((DEBUG_INFO, "Setup value of xDCI DWC_XDCI_DEVTEN_REG: 0x%x\n", UsbRegRead (BaseAddr, DWC_XDCI_DEVTEN_REG)));
> +  DEBUG ((DEBUG_INFO, "Setup value of xDCI DWC_XDCI_DCFG_REG: 0x%x\n", UsbRegRead (BaseAddr, DWC_XDCI_DCFG_REG)));
> +  DEBUG ((DEBUG_INFO, "Setup value of xDCI DWC_XDCI_DSTS_REG: 0x%x\n", UsbRegRead (BaseAddr, DWC_XDCI_DSTS_REG)));
> +
> +  return EFI_SUCCESS;
> +}
> +
> +
> +/**
> +  Interface:
> +  This function is used to set configuration
> +  @CoreHandle: xDCI controller handle
> +  @ConfigNum: config num to set (assigned by USB host)
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +DwcXdciCoreSetConfig (
> +  IN VOID      *CoreHandle,
> +  IN UINT32    ConfigNum
> +  )
> +{
> +  XDCI_CORE_HANDLE              *LocalCoreHandle = (XDCI_CORE_HANDLE *)CoreHandle;
> +  DWC_XDCI_ENDPOINT_CMD_PARAMS  EpCmdParams;
> +  EFI_STATUS                    status;
> +
> +  if (CoreHandle == NULL) {
> +    DEBUG ((DEBUG_INFO, "DwcXdciCoreSetConfig: INVALID handle\n"));
> +    return EFI_DEVICE_ERROR;
> +  }
> +
> +  //
> +  // Issue DEPSTARTCFG command on EP0 (new config for
> +  // non-control EPs)
> +  //
> +  status = DwcXdciCoreInitEpCmdParams (
> +            LocalCoreHandle,
> +            &LocalCoreHandle->EpHandles[0].EpInfo,
> +            DWC_XDCI_PARAM0_SET_EP_CFG_ACTN_NONE,
> +            EPCMD_START_NEW_CONFIG,
> +            &EpCmdParams
> +            );
> +
> +  if (status) {
> +    DEBUG ((DEBUG_INFO, "DwcXdciCoreSetConfig: Failed to init params for EPCMD_START_NEW_CONFIG command\n"));
> +    return status;
> +  }
> +
> +  //
> +  // Issue the command
> +  //
> +  status = DwcXdciCoreIssueEpCmd (
> +             LocalCoreHandle,
> +             0,
> +             (EPCMD_START_NEW_CONFIG | (2 << DWC_XDCI_EPCMD_RES_IDX_BIT_POS)),
> +             &EpCmdParams
> +             );
> +
> +  if (status) {
> +    DEBUG ((DEBUG_INFO, "DwcXdciCoreSetConfig: Failed to issue EPCMD_START_NEW_CONFIG command\n"));
> +    return status;
> +  }
> +
> +  return status;
> +}
> +
> +
> +/**
> +  Interface:
> +  This function is used to set link state
> +  @CoreHandle: xDCI controller handle
> +  @state: Desired link state
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +DwcXdciSetLinkState (
> +  IN VOID                        *CoreHandle,
> +  IN USB_DEVICE_SS_LINK_STATE    state
> +  )
> +{
> +  XDCI_CORE_HANDLE  *LocalCoreHandle = (XDCI_CORE_HANDLE *)CoreHandle;
> +  UINT32            BaseAddr;
> +
> +  if (CoreHandle == NULL) {
> +    DEBUG ((DEBUG_INFO, "DwcXdciSetLinkState: INVALID handle\n"));
> +    return EFI_DEVICE_ERROR;
> +  }
> +
> +  BaseAddr = LocalCoreHandle->BaseAddress;
> +
> +  //
> +  // Clear old mask
> +  //
> +  UsbRegWrite (
> +    BaseAddr,
> +    DWC_XDCI_DCTL_REG,
> +    UsbRegRead (BaseAddr, DWC_XDCI_DCTL_REG) & ~DWC_XDCI_DCTL_STATE_CHANGE_REQ_MASK
> +    );
> +
> +  //
> +  // Request new state
> +  //
> +  UsbRegWrite (
> +    BaseAddr,
> +    DWC_XDCI_DCTL_REG,
> +    UsbRegRead (BaseAddr, DWC_XDCI_DCTL_REG) | (state << DWC_XDCI_DCTL_STATE_CHANGE_REQ_BIT_POS)
> +    );
> +
> +  return EFI_SUCCESS;
> +}
> +
> +
> +/**
> +  Interface:
> +  This function is used to initialize endpoint
> +  @CoreHandle: xDCI controller handle
> +  @EpInfo: Address of structure describing properties of EP
> +  to be initialized
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +DwcXdciInitEp (
> +  IN VOID           *CoreHandle,
> +  IN USB_EP_INFO    *EpInfo
> +  )
> +{
> +  XDCI_CORE_HANDLE              *LocalCoreHandle = (XDCI_CORE_HANDLE *)CoreHandle;
> +  DWC_XDCI_ENDPOINT_CMD_PARAMS  EpCmdParams;
> +  EFI_STATUS                    status;
> +  UINT32                        EpNum;
> +
> +  if (CoreHandle == NULL) {
> +    DEBUG ((DEBUG_INFO, "DwcXdciInitEp: INVALID handle\n"));
> +    return EFI_DEVICE_ERROR;
> +  }
> +
> +  //
> +  // Convert to physical endpoint
> +  //
> +  EpNum = DwcXdciGetPhysicalEpNum (EpInfo->EpNum, EpInfo->EpDir);
> +
> +  //
> +  // Save EP properties
> +  //
> +  CopyMem (&(LocalCoreHandle->EpHandles[EpNum].EpInfo), EpInfo, sizeof (USB_EP_INFO));
> +
> +  //
> +  // Init CheckFlag
> +  //
> +  LocalCoreHandle->EpHandles[EpNum].CheckFlag = FALSE;
> +
> +  //
> +  // Init DEPCFG cmd params for EP
> +  //
> +  status = DwcXdciCoreInitEpCmdParams (
> +             CoreHandle,
> +             &LocalCoreHandle->EpHandles[EpNum].EpInfo,
> +             DWC_XDCI_PARAM0_SET_EP_CFG_ACTN_INIT_STATE,
> +             EPCMD_SET_EP_CONFIG,
> +             &EpCmdParams
> +             );
> +
> +  if (status) {
> +    DEBUG ((DEBUG_INFO, "DwcXdciInitEp: Failed to init params for  EPCMD_SET_EP_CONFIG command\n"));
> +    return status;
> +  }
> +
> +  //
> +  // Issue the command
> +  //
> +  status = DwcXdciCoreIssueEpCmd (
> +             CoreHandle,
> +             EpNum,
> +             EPCMD_SET_EP_CONFIG,
> +             &EpCmdParams
> +             );
> +
> +  if (status) {
> +    DEBUG ((DEBUG_INFO, "DwcXdciInitEp: Failed to issue  EPCMD_SET_EP_CONFIG command\n"));
> +    return status;
> +  }
> +
> +  //
> +  // Issue a DEPXFERCFG command for endpoint
> +  //
> +  status = DwcXdciCoreInitEpCmdParams (
> +             LocalCoreHandle,
> +             &LocalCoreHandle->EpHandles[EpNum].EpInfo,
> +             DWC_XDCI_PARAM0_SET_EP_CFG_ACTN_NONE,
> +             EPCMD_SET_EP_XFER_RES_CONFIG,
> +             &EpCmdParams
> +             );
> +
> +  if (status) {
> +    DEBUG ((DEBUG_INFO, "DwcXdciInitEp: Failed to init params for  EPCMD_SET_EP_XFER_RES_CONFIG command\n"));
> +    return status;
> +  }
> +
> +  //
> +  // Issue the command
> +  //
> +  status = DwcXdciCoreIssueEpCmd (
> +             LocalCoreHandle,
> +             EpNum,
> +             EPCMD_SET_EP_XFER_RES_CONFIG,
> +             &EpCmdParams
> +             );
> +
> +  if (status) {
> +    DEBUG ((DEBUG_INFO, "DwcXdciInitEp: Failed to issue EPCMD_SET_EP_XFER_RES_CONFIG command\n"));
> +  }
> +
> +  return status;
> +}
> +
> +
> +/**
> +  Interface:
> +  This function is used to enable non-Ep0 endpoint
> +  @CoreHandle: xDCI controller handle
> +  @EpInfo: Address of structure describing properties of EP
> +  to be enabled
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +DwcXdciEpEnable (
> +  IN VOID           *CoreHandle,
> +  IN USB_EP_INFO    *EpInfo
> +  )
> +{
> +  XDCI_CORE_HANDLE  *LocalCoreHandle = (XDCI_CORE_HANDLE *)CoreHandle;
> +  UINT32            EpNum;
> +  UINT32            BaseAddr;
> +
> +  if (CoreHandle == NULL) {
> +    DEBUG ((DEBUG_INFO, "DwcXdciEpEnable: INVALID handle\n"));
> +    return EFI_DEVICE_ERROR;
> +  }
> +
> +  BaseAddr = LocalCoreHandle->BaseAddress;
> +
> +  //
> +  // Convert to physical endpoint
> +  //
> +  EpNum = DwcXdciGetPhysicalEpNum (EpInfo->EpNum, EpInfo->EpDir);
> +
> +  //
> +  // Enable Physical Endpoint EpNum
> +  //
> +  UsbRegWrite (
> +    BaseAddr,
> +    DWC_XDCI_EP_DALEPENA_REG,
> +    UsbRegRead (BaseAddr, DWC_XDCI_EP_DALEPENA_REG) | (1 << EpNum)
> +    );
> +
> +  return EFI_SUCCESS;
> +}
> +
> +
> +/**
> +  Interface:
> +  This function is used to disable non-Ep0 endpoint
> +  @CoreHandle: xDCI controller handle
> +  @EpInfo: Address of structure describing properties of EP
> +  to be enabled
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +DwcXdciEpDisable (
> +  IN VOID           *CoreHandle,
> +  IN USB_EP_INFO    *EpInfo
> +  )
> +{
> +  XDCI_CORE_HANDLE  *LocalCoreHandle = (XDCI_CORE_HANDLE *)CoreHandle;
> +  UINT32            EpNum;
> +  UINT32            BaseAddr;
> +
> +  if (CoreHandle == NULL) {
> +    DEBUG ((DEBUG_INFO, "DwcXdciEpDisable: INVALID handle\n"));
> +    return EFI_DEVICE_ERROR;
> +  }
> +
> +  BaseAddr = LocalCoreHandle->BaseAddress;
> +
> +  //
> +  // Convert to physical endpoint
> +  //
> +  EpNum = DwcXdciGetPhysicalEpNum (EpInfo->EpNum, EpInfo->EpDir);
> +
> +  //
> +  // Disable Physical Endpoint EpNum
> +  //
> +  UsbRegWrite (
> +    BaseAddr,
> +    DWC_XDCI_EP_DALEPENA_REG,
> +    UsbRegRead (BaseAddr, DWC_XDCI_EP_DALEPENA_REG) & ~(1 << EpNum)
> +    );
> +
> +  return EFI_SUCCESS;
> +}
> +
> +
> +/**
> +  Interface:
> +  This function is used to STALL and endpoint
> +  @CoreHandle: xDCI controller handle
> +  @EpInfo: Address of structure describing properties of EP
> +  to be enabled
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +DwcXdciEpStall (
> +  IN VOID           *CoreHandle,
> +  IN USB_EP_INFO    *EpInfo
> +  )
> +{
> +  XDCI_CORE_HANDLE              *LocalCoreHandle = (XDCI_CORE_HANDLE *)CoreHandle;
> +  DWC_XDCI_ENDPOINT_CMD_PARAMS  EpCmdParams;
> +  EFI_STATUS                    status;
> +  UINT32                        EpNum;
> +
> +  if (CoreHandle == NULL) {
> +    DEBUG ((DEBUG_INFO, "DwcXdciEpStall: INVALID handle\n"));
> +    return EFI_DEVICE_ERROR;
> +  }
> +
> +  //
> +  // Convert to physical endpoint
> +  //
> +  EpNum = DwcXdciGetPhysicalEpNum (EpInfo->EpNum, EpInfo->EpDir);
> +
> +  //
> +  // Set Ep State Info
> +  //
> +  if (LocalCoreHandle->EpHandles[EpNum].State != USB_EP_STATE_STALLED) {
> +    LocalCoreHandle->EpHandles[EpNum].OrgState = LocalCoreHandle->EpHandles[EpNum].State;
> +    LocalCoreHandle->EpHandles[EpNum].State = USB_EP_STATE_STALLED;
> +  }
> +  //
> +  // Issue a DWC_XDCI_EPCMD_SET_STALL for EP
> +  // Reset params
> +  //
> +  EpCmdParams.Param0 = EpCmdParams.Param1 = EpCmdParams.Param2 = 0;
> +
> + //
> + // Issue the command
> + //
> + status = DwcXdciCoreIssueEpCmd (
> +            LocalCoreHandle,
> +            EpNum,
> +            DWC_XDCI_EPCMD_SET_STALL,
> +            &EpCmdParams
> +            );
> +
> + if (status) {
> +   DEBUG ((DEBUG_INFO, "DwcXdciEpStall: Failed to issue EP stall command\n"));
> + }
> +
> + return status;
> +}
> +
> +
> +/**
> +  Interface:
> +  This function is used to clear endpoint STALL
> +  @CoreHandle: xDCI controller handle
> +  @EpInfo: Address of structure describing properties of EP
> +  to be enabled
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +DwcXdciEpClearStall (
> +  IN VOID           *CoreHandle,
> +  IN USB_EP_INFO    *EpInfo
> +  )
> +{
> +  XDCI_CORE_HANDLE              *LocalCoreHandle = (XDCI_CORE_HANDLE *)CoreHandle;
> +  DWC_XDCI_ENDPOINT_CMD_PARAMS  EpCmdParams;
> +  EFI_STATUS                    status;
> +  UINT32                        EpNum;
> +
> +  if (CoreHandle == NULL) {
> +    DEBUG ((DEBUG_INFO, "DwcXdciEpClearStall: INVALID handle\n"));
> +    return EFI_DEVICE_ERROR;
> +  }
> +
> +  //
> +  // Convert to physical endpoint
> +  //
> +  EpNum = DwcXdciGetPhysicalEpNum (EpInfo->EpNum, EpInfo->EpDir);
> +
> +  //
> +  // Set Ep State Info
> +  //
> +  LocalCoreHandle->EpHandles[EpNum].State = LocalCoreHandle->EpHandles[EpNum].OrgState;
> +
> +  //
> +  // Issue a DWC_XDCI_EPCMD_CLEAR_STALL for EP
> +  // Reset params
> +  //
> +  EpCmdParams.Param0 = EpCmdParams.Param1 = EpCmdParams.Param2 = 0;
> +
> +  //
> +  // Issue the command
> +  //
> + status = DwcXdciCoreIssueEpCmd (
> +            LocalCoreHandle,
> +            EpNum,
> +            DWC_XDCI_EPCMD_CLEAR_STALL,
> +            &EpCmdParams
> +            );
> +
> + if (status) {
> +   DEBUG ((DEBUG_INFO, "DwcXdciEpStall: Failed to issue EP clea stall command\n"));
> + }
> +
> + return status;
> +}
> +
> +
> +/**
> +  Interface:
> +  This function is used to set endpoint in NOT READY state
> +  @CoreHandle: xDCI controller handle
> +  @EpInfo: Address of structure describing properties of EP
> +  to be enabled
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +DwcXdciEpSetNrdy (
> +  IN VOID           *CoreHandle,
> +  IN USB_EP_INFO    *EpInfo
> +  )
> +{
> +  XDCI_CORE_HANDLE  *LocalCoreHandle = (XDCI_CORE_HANDLE *)CoreHandle;
> +  UINT32            EpNum;
> +  UINT32            BaseAddr;
> +  UINT32            MaxDelayIter = DWC_XDCI_MAX_DELAY_ITERATIONS;
> +
> +  if (CoreHandle == NULL) {
> +    DEBUG ((DEBUG_INFO, "DwcXdciEpSetNrdy: INVALID handle\n"));
> +    return EFI_DEVICE_ERROR;
> +  }
> +
> +  BaseAddr = LocalCoreHandle->BaseAddress;
> +
> +  //
> +  // Convert to physical endpoint
> +  //
> +  EpNum = DwcXdciGetPhysicalEpNum (EpInfo->EpNum, EpInfo->EpDir);
> +
> +  //
> +  // Program the EP number in command's param reg
> +  //
> +  UsbRegWrite (BaseAddr, DWC_XDCI_DGCMD_PARAM_REG, EpNum);
> +
> +  //
> +  // Issue EP not ready generic device command
> +  //
> +  UsbRegWrite (
> +    BaseAddr,
> +    DWC_XDCI_DGCMD_REG,
> +    (UsbRegRead (BaseAddr, DWC_XDCI_DGCMD_REG) | DWC_XDCI_DGCMD_CMD_SET_EP_NRDY)
> +    );
> +
> +  //
> +  // Activate the command
> +  //
> +  UsbRegWrite (
> +    BaseAddr,
> +    DWC_XDCI_DGCMD_REG,
> +    (UsbRegRead (BaseAddr, DWC_XDCI_DGCMD_REG) | DWC_XDCI_DGCMD_CMD_ACTIVE_MASK)
> +    );
> +
> +  //
> +  // Wait until command completes
> +  //
> +  do {
> +    if (!(UsbRegRead (BaseAddr, DWC_XDCI_DGCMD_REG) & DWC_XDCI_DGCMD_CMD_ACTIVE_MASK))
> +      break;
> +    else
> +      gBS->Stall (DWC_XDCI_MAX_DELAY_ITERATIONS);
> +  } while (--MaxDelayIter);
> +
> +  if (!MaxDelayIter) {
> +    DEBUG ((DEBUG_INFO, "Failed to issue Command\n"));
> +    return EFI_DEVICE_ERROR;
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +
> +/**
> +  Interface:
> +  This function is used to queue receive SETUP packet request
> +  @CoreHandle: xDCI controller handle
> +  @Buffer: Address of Buffer to receive SETUP packet
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +DwcXdciEp0ReceiveSetupPkt (
> +  IN VOID     *CoreHandle,
> +  IN UINT8    *Buffer
> +  )
> +{
> +  XDCI_CORE_HANDLE                *LocalCoreHandle = (XDCI_CORE_HANDLE *)CoreHandle;
> +  DWC_XDCI_ENDPOINT_CMD_PARAMS    EpCmdParams;
> +  EFI_STATUS                      Status = EFI_DEVICE_ERROR;
> +  DWC_XDCI_TRB                    *Trb;
> +
> +  if (CoreHandle == NULL) {
> +    DEBUG ((DEBUG_INFO, "DwcXdciEp0ReceiveSetupPkt: INVALID handle\n"));
> +    return EFI_DEVICE_ERROR;
> +  }
> +
> +  LocalCoreHandle->EpHandles[0].EpInfo.EpNum = 0;
> +  LocalCoreHandle->EpHandles[0].EpInfo.EpDir = 0;
> +  LocalCoreHandle->EpHandles[0].State = USB_EP_STATE_SETUP;
> +  Trb = LocalCoreHandle->Trbs;
> +  DEBUG ((DEBUG_INFO, "(DwcXdciEp0ReceiveSetupPkt)\n"));
> +
> +  Status = DwcXdciCoreInitTrb (
> +             LocalCoreHandle,
> +             Trb,
> +             TRBCTL_SETUP,
> +             Buffer,
> +             8
> +             );
> +
> +  if (Status) {
> +    DEBUG ((DEBUG_INFO, "DwcXdciEp0ReceiveSetupPkt: Init TRB Failed \n"));
> +    return Status;
> +  }
> +
> +  //
> +  // Issue a DEPSTRTXFER for EP0
> +  // Reset params
> +  //
> +  EpCmdParams.Param0 = EpCmdParams.Param1 = EpCmdParams.Param2 = 0;
> +
> +  //
> +  // Init the lower re-bits for TRB address
> +  //
> +  EpCmdParams.Param1 = (UINT32)(UINTN)Trb;
> +
> +  //
> +  // Issue the command
> +  //
> +  Status = DwcXdciCoreIssueEpCmd (
> +             LocalCoreHandle,
> +             0,
> +             EPCMD_START_XFER,
> +             &EpCmdParams
> +             );
> +
> +  if (Status) {
> +    DEBUG ((DEBUG_INFO, "\nDwcXdciEp0ReceiveSetupPkt: Failed to issue Start Transfer command"));
> +  }
> +
> +  //
> +  // Save new resource index for this transfer
> +  //
> +  LocalCoreHandle->EpHandles[0].CurrentXferRscIdx = ((UsbRegRead(LocalCoreHandle->BaseAddress, DWC_XDCI_EPCMD_REG(0)) &
> +                                                         DWC_XDCI_EPCMD_RES_IDX_MASK) >> DWC_XDCI_EPCMD_RES_IDX_BIT_POS
> +                                                         );
> +
> +  return Status;
> +}
> +
> +
> +/**
> +  Interface:
> +  This function is used to queue receive status packet on EP0
> +  @CoreHandle: xDCI controller handle
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +DwcXdciEp0ReceiveStatusPkt (
> +  IN VOID    *CoreHandle
> +  )
> +{
> +  XDCI_CORE_HANDLE                *LocalCoreHandle = (XDCI_CORE_HANDLE *)CoreHandle;
> +  DWC_XDCI_TRB                    *Trb;
> +  DWC_XDCI_TRB_CONTROL            TrbCtrl;
> +  DWC_XDCI_ENDPOINT_CMD_PARAMS    EpCmdParams;
> +  EFI_STATUS                      Status;
> +  UINT32                          BaseAddr;
> +
> +  if (CoreHandle == NULL) {
> +    DEBUG ((DEBUG_INFO, "DwcXdciEp0ReceiveStatusPkt: INVALID handle\n"));
> +    return EFI_DEVICE_ERROR;
> +  }
> +
> +  BaseAddr = LocalCoreHandle->BaseAddress;
> +
> +  //
> +  // We are receiving on EP0 so physical EP is 0
> +  //
> +  Trb = LocalCoreHandle->Trbs;
> +  DEBUG ((DEBUG_INFO, "(DwcXdciEp0ReceiveStatusPkt)\n"));
> +  if (Trb->TrbCtrl & DWC_XDCI_TRB_CTRL_HWO_MASK) {
> +    DEBUG ((DEBUG_INFO, "statusPkt still not transferred.\n"));
> +    return EFI_SUCCESS;
> +  }
> +
> +  LocalCoreHandle->EpHandles[0].EpInfo.EpNum = 0;
> +  LocalCoreHandle->EpHandles[0].EpInfo.EpDir = 0;
> +
> +  //
> +  // OUT data phase for 3-phased control transfer
> +  //
> +  TrbCtrl = TRBCTL_3_PHASE;
> +
> +  //
> +  // Init TRB for the transfer
> +  //
> +  Status = DwcXdciCoreInitTrb (
> +             LocalCoreHandle,
> +             Trb,
> +             TrbCtrl,
> +             LocalCoreHandle->AlignedSetupBuffer,
> +             0
> +             );
> +
> +  if (!Status) {
> +    //
> +    // Issue a DEPSTRTXFER for EP0
> +    // Reset params
> +    //
> +    EpCmdParams.Param0 = EpCmdParams.Param1 = EpCmdParams.Param2 = 0;
> +
> +    //
> +    // Init the lower bits for TRB address
> +    //
> +    EpCmdParams.Param1 = (UINT32)(UINTN)Trb;
> +
> +    //
> +    // Issue the command
> +    //
> +    Status = DwcXdciCoreIssueEpCmd (
> +               LocalCoreHandle,
> +               0,
> +               EPCMD_START_XFER,
> +               &EpCmdParams
> +               );
> +
> +    if (Status) {
> +      DEBUG ((DEBUG_INFO, "DwcXdciEp0ReceiveStatusPkt: Failed to issue Start Transfer command for EP0\n"));
> +    }
> +    //
> +    // Save new resource index for this transfer
> +    //
> +    LocalCoreHandle->EpHandles[0].CurrentXferRscIdx = ((UsbRegRead(BaseAddr, DWC_XDCI_EPCMD_REG(0)) & DWC_XDCI_EPCMD_RES_IDX_MASK) >> DWC_XDCI_EPCMD_RES_IDX_BIT_POS);
> +
> +    //
> +    // TODO: We are not using the EP state for control transfers
> +    // right now simply because we're only supporting IN
> +    // data phase. For the current use case, we don't
> +    // need OUT data phase. We can add that later and we will
> +    // add some of the state and SETUP packet awareness code
> +    //
> +    LocalCoreHandle->EpHandles[0].State = USB_EP_STATE_STATUS;
> +  }
> +
> +  return Status;
> +}
> +
> +
> +/**
> +  Interface:
> +  This function is used to send status packet on EP0
> +  @CoreHandle: xDCI controller handle
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +DwcXdciEp0SendStatusPkt (
> +  IN VOID    *CoreHandle
> +  )
> +{
> +  XDCI_CORE_HANDLE                *LocalCoreHandle = (XDCI_CORE_HANDLE *)CoreHandle;
> +  DWC_XDCI_TRB                    *Trb;
> +  DWC_XDCI_ENDPOINT_CMD_PARAMS    EpCmdParams;
> +  EFI_STATUS                      Status;
> +  UINT32                          BaseAddr;
> +
> +  if (CoreHandle == NULL) {
> +    DEBUG ((DEBUG_INFO, "DwcXdciEp0SendStatusPkt: INVALID handle\n"));
> +    return EFI_DEVICE_ERROR;
> +  }
> +
> +  BaseAddr = LocalCoreHandle->BaseAddress;
> +
> +  //
> +  // We are sending on EP0 so physical EP is 1
> +  //
> +  Trb = (LocalCoreHandle->Trbs + (1 * DWC_XDCI_TRB_NUM));
> +  DEBUG ((DEBUG_INFO, "(DwcXdciEp0SendStatusPkt)\n"));
> +
> +  LocalCoreHandle->EpHandles[0].State = USB_EP_STATE_STATUS;
> +  Status = DwcXdciCoreInitTrb (
> +             LocalCoreHandle,
> +             Trb,
> +             TRBCTL_2_PHASE,
> +             LocalCoreHandle->AlignedMiscBuffer,
> +             0
> +             );
> +
> +  if (Status) {
> +    DEBUG ((DEBUG_INFO, "DwcXdciEp0SendStatusPkt: TRB failed during status phase\n"));
> +    return Status;
> +  }
> +
> +  //
> +  // Issue a DEPSTRTXFER for EP1
> +  // Reset params
> +  //
> +  EpCmdParams.Param0 = EpCmdParams.Param1 = EpCmdParams.Param2 = 0;
> +
> +  //
> +  // Init the lower re-bits for TRB address
> +  //
> +  EpCmdParams.Param1 = (UINT32)(UINTN)Trb;
> +
> +  //
> +  // Issue the command
> +  //
> +  Status = DwcXdciCoreIssueEpCmd (
> +             LocalCoreHandle,
> +             1,
> +             EPCMD_START_XFER,
> +             &EpCmdParams
> +             );
> +
> +  if (Status) {
> +    DEBUG ((DEBUG_INFO, "DwcXdciEp0SendStatusPkt: Failed to issue Start Transfer on EP0\n"));
> +  }
> +
> +  //
> +  // Save new resource index for this transfer
> +  //
> +  LocalCoreHandle->EpHandles[1].CurrentXferRscIdx = ((UsbRegRead(BaseAddr, DWC_XDCI_EPCMD_REG(1)) & DWC_XDCI_EPCMD_RES_IDX_MASK) >> DWC_XDCI_EPCMD_RES_IDX_BIT_POS);
> +  LocalCoreHandle->EpHandles[0].State = USB_EP_STATE_STATUS;
> +
> +  return Status;
> +}
> +
> +
> +/**
> +  Interface:
> +  This function is used to send data on non-EP0 endpoint
> +  @CoreHandle: xDCI controller handle
> +  @EpInfo: Address of structure describing properties of EP
> +  @Buffer: Buffer containing data to transmit
> +  @size: Size of transfer (in bytes)
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +DwcXdciEpTxData (
> +  IN VOID                *CoreHandle,
> +  IN USB_XFER_REQUEST    *XferReq
> +  )
> +{
> +  XDCI_CORE_HANDLE              *LocalCoreHandle = (XDCI_CORE_HANDLE *)CoreHandle;
> +  DWC_XDCI_ENDPOINT_CMD_PARAMS  EpCmdParams;
> +  DWC_XDCI_TRB                  *Trb;
> +  DWC_XDCI_TRB_CONTROL          TrbCtrl;
> +  EFI_STATUS                    Status;
> +  UINT32                        EpNum;
> +  UINT32                        BaseAddr;
> +
> +  if (CoreHandle == NULL) {
> +    DEBUG ((DEBUG_INFO, "DwcXdciEpTxData: INVALID handle\n"));
> +    return EFI_DEVICE_ERROR;
> +  }
> +
> +  if (XferReq == NULL) {
> +    DEBUG ((DEBUG_INFO, "DwcXdciEpTxData: INVALID transfer request\n"));
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  BaseAddr = LocalCoreHandle->BaseAddress;
> +
> +  //
> +  // Convert to physical endpoint
> +  //
> +  EpNum = DwcXdciGetPhysicalEpNum (
> +             XferReq->EpInfo.EpNum,
> +             XferReq->EpInfo.EpDir
> +             );
> +
> +  Trb = (LocalCoreHandle->Trbs + (EpNum * DWC_XDCI_TRB_NUM));
> +  DEBUG ((DEBUG_INFO, "(DwcXdciEpTxData)EpNum is %d\n", EpNum));
> +
> +
> +  if (EpNum > 1)
> +    TrbCtrl = TRBCTL_NORMAL;
> +  else
> +    TrbCtrl = TRBCTL_CTRL_DATA_PHASE;
> +
> +  if (Trb->TrbCtrl & DWC_XDCI_TRB_CTRL_HWO_MASK) {
> +    Status = DwcXdciEndXfer (LocalCoreHandle, EpNum);
> +    if (Status) {
> +      DEBUG ((DEBUG_INFO, "DwcXdciEpTxData: Failed to end previous transfer\n"));
> +    }
> +
> +    Status = DwcXdciCoreFlushEpTxFifo (LocalCoreHandle, EpNum);
> +    if (Status) {
> +      DEBUG ((DEBUG_INFO, "DwcXdciEpTxData: Failed to end previous transfer\n"));
> +    }
> +  }
> +
> +  //
> +  // Data phase
> +  //
> +  CopyMem (&(LocalCoreHandle->EpHandles[EpNum].XferHandle), XferReq, sizeof (USB_XFER_REQUEST));
> +  LocalCoreHandle->EpHandles[EpNum].State = USB_EP_STATE_DATA;
> +
> +  LocalCoreHandle->EpHandles[EpNum].Trb = Trb;
> +
> +  Status = DwcXdciCoreInitTrb (
> +             LocalCoreHandle,
> +             Trb,
> +             TrbCtrl,
> +             XferReq->XferBuffer,
> +             XferReq->XferLen
> +             );
> +
> +  if (Status) {
> +    DEBUG ((DEBUG_INFO, "DwcXdciEpTxData: TRB failed\n"));
> +    return Status;
> +  }
> +
> +  //
> +  // Issue a DEPSTRTXFER for EP
> +  // Reset params
> +  //
> +  EpCmdParams.Param0 = EpCmdParams.Param1 = EpCmdParams.Param2 = 0;
> +
> +  //
> +  // Init the lower re-bits for TRB address
> +  //
> +  EpCmdParams.Param1 = (UINT32)(UINTN)Trb;
> +
> +  //
> +  // Issue the command
> +  //
> +  Status = DwcXdciCoreIssueEpCmd (
> +             LocalCoreHandle,
> +             EpNum,
> +             EPCMD_START_XFER,
> +             &EpCmdParams
> +             );
> +
> +  //
> +  // Save new resource index for this transfer
> +  //
> +  LocalCoreHandle->EpHandles[EpNum].CurrentXferRscIdx = ((UsbRegRead (BaseAddr, DWC_XDCI_EPCMD_REG(EpNum)) & DWC_XDCI_EPCMD_RES_IDX_MASK) >> DWC_XDCI_EPCMD_RES_IDX_BIT_POS);
> +
> +  return Status;
> +}
> +
> +
> +/**
> +  Interface:
> +  This function is used to receive data on non-EP0 endpoint
> +  @CoreHandle: xDCI controller handle
> +  @EpInfo: Address of structure describing properties of EP
> +  @Buffer: Buffer containing data to transmit
> +  @size: Size of transfer (in bytes)
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +DwcXdciEpRxData (
> +  IN VOID                *CoreHandle,
> +  IN USB_XFER_REQUEST    *XferReq
> +  )
> +{
> +  XDCI_CORE_HANDLE              *LocalCoreHandle = (XDCI_CORE_HANDLE *)CoreHandle;
> +  DWC_XDCI_ENDPOINT_CMD_PARAMS  EpCmdParams;
> +  DWC_XDCI_TRB                  *Trb;
> +  DWC_XDCI_TRB_CONTROL          TrbCtrl;
> +  EFI_STATUS                    Status;
> +  UINT32                        EpNum;
> +  UINT32                        BaseAddr;
> +
> +  if (CoreHandle == NULL) {
> +    DEBUG ((DEBUG_INFO, "DwcXdciEpRxData: INVALID handle\n"));
> +    return EFI_DEVICE_ERROR;
> +  }
> +
> +  if (XferReq == NULL) {
> +    DEBUG ((DEBUG_INFO, "DwcXdciEpRxData: INVALID transfer request\n"));
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  BaseAddr = LocalCoreHandle->BaseAddress;
> +
> +  //
> +  // Convert to physical endpoint
> +  //
> +  EpNum = DwcXdciGetPhysicalEpNum (XferReq->EpInfo.EpNum, XferReq->EpInfo.EpDir);
> +
> +  Trb = (LocalCoreHandle->Trbs + (EpNum * DWC_XDCI_TRB_NUM));
> +  DEBUG ((DEBUG_INFO, "(DwcXdciEpRxData)EpNum is %d\n", EpNum));
> +
> +  if (EpNum > 1)
> +    TrbCtrl = TRBCTL_NORMAL;
> +  else
> +    TrbCtrl = TRBCTL_CTRL_DATA_PHASE;
> +
> +  //
> +  // If CheckFlag didn't set to FALSE, means the previous transfer request didn't complete,
> +  // need to wait the previous request done.
> +  //
> +  if (LocalCoreHandle->EpHandles[EpNum].CheckFlag == TRUE) {
> +    return EFI_NOT_READY;
> +  }
> +
> +  LocalCoreHandle->EpHandles[EpNum].CheckFlag = TRUE;
> +
> +  //
> +  // Data phase
> +  //
> +  CopyMem (&(LocalCoreHandle->EpHandles[EpNum].XferHandle), XferReq, sizeof (USB_XFER_REQUEST));
> +
> +  LocalCoreHandle->EpHandles[EpNum].State = USB_EP_STATE_DATA;
> +
> +  LocalCoreHandle->EpHandles[EpNum].Trb = Trb;
> +
> +  DEBUG ((DEBUG_INFO, "(DwcXdciEpRxData)XferReq->XferLen is 0x%x\n", XferReq->XferLen));
> +
> +  Status = DwcXdciCoreInitTrb (
> +             LocalCoreHandle,
> +             Trb,
> +             TrbCtrl,
> +             XferReq->XferBuffer,
> +             XferReq->XferLen
> +             );
> +
> +  if (Status) {
> +    DEBUG ((DEBUG_INFO, "DwcXdciEpRxData: TRB failed\n"));
> +    return Status;
> +  }
> +  //
> +  // Issue a DEPSTRTXFER for EP
> +  // Reset params
> +  //
> +  EpCmdParams.Param0 = EpCmdParams.Param1 = EpCmdParams.Param2 = 0;
> +
> +  //
> +  // Init the lower re-bits for TRB address
> +  //
> +  EpCmdParams.Param1 = (UINT32)(UINTN)Trb;
> +
> +  //
> +  // Issue the command
> +  //
> +  Status = DwcXdciCoreIssueEpCmd (
> +             LocalCoreHandle,
> +             EpNum,
> +             EPCMD_START_XFER,
> +             &EpCmdParams
> +             );
> +
> +  if (Status) {
> +    DEBUG ((DEBUG_INFO, "DwcXdciEpRxData: Failed to start transfer\n"));
> +  }
> +
> +  //
> +  // Save new resource index for this transfer
> +  //
> +  LocalCoreHandle->EpHandles[EpNum].CurrentXferRscIdx = ((UsbRegRead(BaseAddr, DWC_XDCI_EPCMD_REG(EpNum)) & DWC_XDCI_EPCMD_RES_IDX_MASK) >> DWC_XDCI_EPCMD_RES_IDX_BIT_POS);
> +
> +  return Status;
> +}
> +
> +
> +
> +STATIC
> +EFI_STATUS
> +DwcXdciCoreFlushEpFifo (
> +  IN XDCI_CORE_HANDLE    *CoreHandle,
> +  IN UINT32              EpNum
> +  )
> +{
> +  UINT32 BaseAddr;
> +  UINT32 MaxDelayIter = DWC_XDCI_MAX_DELAY_ITERATIONS;
> +  UINT32 fifoNum;
> +  UINT32 Param;
> +
> +  if (CoreHandle == NULL) {
> +    DEBUG ((DEBUG_INFO, "ERROR: DwcXdciCoreFlushEpTxFifo: INVALID handle\n"));
> +    return EFI_DEVICE_ERROR;
> +  }
> +
> +  BaseAddr = CoreHandle->BaseAddress;
> +
> +  //
> +  // Translate to FIFOnum
> +  // NOTE: Assuming this is a Tx EP
> +  //
> +  fifoNum = (EpNum >> 1);
> +
> +  //
> +  // TODO: Currently we are only using TxFIFO 0. Later map these
> +  // Write the FIFO num/dir param for the generic command.
> +  //
> +
> +  Param = UsbRegRead (BaseAddr, DWC_XDCI_DGCMD_PARAM_REG);
> +  Param &= ~(DWC_XDCI_DGCMD_PARAM_TX_FIFO_NUM_MASK | DWC_XDCI_DGCMD_PARAM_TX_FIFO_DIR_MASK);
> +
> +  if ((EpNum & 0x01) != 0) {
> +    Param |= (fifoNum | DWC_XDCI_DGCMD_PARAM_TX_FIFO_DIR_MASK);
> +  } else {
> +    Param |= fifoNum;
> +  }
> +
> +  DEBUG ((DEBUG_INFO, "USB FU Flash: CMD 0x%08x :: Param 0x%08x\n",
> +        (UsbRegRead(BaseAddr, DWC_XDCI_DGCMD_REG) | DWC_XDCI_DGCMD_CMD_SEL_FIFO_FLUSH | DWC_XDCI_DGCMD_CMD_ACTIVE_MASK),
> +        Param));
> +
> +  UsbRegWrite (
> +    BaseAddr,
> +    DWC_XDCI_DGCMD_PARAM_REG,
> +    Param
> +    );
> +
> +  //
> +  // Write the command to flush all FIFOs
> +  //
> +  UsbRegWrite (
> +    BaseAddr,
> +    DWC_XDCI_DGCMD_REG,
> +    (UsbRegRead(BaseAddr, DWC_XDCI_DGCMD_REG) | DWC_XDCI_DGCMD_CMD_SEL_FIFO_FLUSH | DWC_XDCI_DGCMD_CMD_ACTIVE_MASK)
> +    );
> +
> +
> +  //
> +  // Wait until command completes
> +  //
> +  do {
> +    if (!(UsbRegRead(BaseAddr, DWC_XDCI_DGCMD_REG) & DWC_XDCI_DGCMD_CMD_ACTIVE_MASK))
> +      break;
> +    else
> +      gBS->Stall (DWC_XDCI_MAX_DELAY_ITERATIONS);
> +  } while (--MaxDelayIter);
> +
> +  if (!MaxDelayIter) {
> +    DEBUG ((DEBUG_INFO, "Failed to issue Command\n"));
> +    return EFI_DEVICE_ERROR;
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  Interface:
> +  This function is used to cancel a transfer on non-EP0 endpoint
> +  @CoreHandle: xDCI controller handle
> +  @EpInfo: Address of structure describing properties of EP
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +DwcXdciEpCancelTransfer (
> +  IN VOID           *CoreHandle,
> +  IN USB_EP_INFO    *EpInfo
> +  )
> +{
> +  EFI_STATUS  Status = EFI_DEVICE_ERROR;
> +  UINT32      EpNum;
> +
> +  if (CoreHandle == NULL) {
> +    DEBUG ((DEBUG_INFO, "DwcXdciEpCancelTransfer: INVALID handle\n"));
> +    return EFI_DEVICE_ERROR;
> +  }
> +
> +  //
> +  // Get physical EP num
> +  //
> +  EpNum = DwcXdciGetPhysicalEpNum (EpInfo->EpNum, EpInfo->EpDir);
> +  Status = DwcXdciEndXfer(CoreHandle, EpNum);
> +  DwcXdciCoreFlushEpFifo(CoreHandle, EpNum);
> +
> +  return Status;
> +}
> +
> +
> +EFI_STATUS
> +usbProcessDeviceResetDet (
> +  IN XDCI_CORE_HANDLE    *CoreHandle
> +  )
> +{
> +   return DwcXdciProcessDeviceResetDet (CoreHandle);
> +}
> +
> +EFI_STATUS
> +usbProcessDeviceResetDone (
> +  IN XDCI_CORE_HANDLE    *CoreHandle
> +  )
> +{
> +  return DwcXdciProcessDeviceResetDone (CoreHandle);
> +}
> +
> +UINT32
> +UsbGetPhysicalEpNum (
> +  IN UINT32        EndpointNum,
> +  IN USB_EP_DIR    EndpointDir
> +  )
> +{
> +  return DwcXdciGetPhysicalEpNum(
> +                            EndpointNum,
> +                            EndpointDir
> +                            );
> +}
> +
> +
> +EFI_STATUS
> +EFIAPI
> +UsbXdciCoreReinit (
> +  IN VOID                     *CoreHandle
> +  )
> +{
> +  EFI_STATUS                      status = EFI_DEVICE_ERROR;
> +  UINT32                          BaseAddr;
> +  XDCI_CORE_HANDLE                *LocalCoreHandle;
> +  DWC_XDCI_ENDPOINT_CMD_PARAMS    EpCmdParams;
> +  UINT32                          MaxDelayIter = DWC_XDCI_MAX_DELAY_ITERATIONS;
> +  UINT8                           i;
> +
> +  LocalCoreHandle = CoreHandle;
> +
> +  if (CoreHandle == NULL) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  if (LocalCoreHandle == NULL) {
> +    DEBUG ((DEBUG_INFO, "DwcXdciCoreInit: Failed to allocate handle for xDCI\n"));
> +    return EFI_OUT_OF_RESOURCES;
> +  }
> +
> +  BaseAddr = LocalCoreHandle->BaseAddress;
> +
> +  DEBUG ((DEBUG_INFO, "Resetting the USB core\n"));
> +  UsbRegWrite (
> +    BaseAddr,
> +    DWC_XDCI_DCTL_REG,
> +    UsbRegRead (BaseAddr, DWC_XDCI_DCTL_REG) | DWC_XDCI_DCTL_CSFTRST_MASK
> +    );
> +
> +  //
> +  // Wait until core soft reset completes
> +  //
> +  do {
> +    if (!(UsbRegRead (BaseAddr, DWC_XDCI_DCTL_REG) & DWC_XDCI_DCTL_CSFTRST_MASK)) {
> +      break;
> +    } else {
> +      gBS->Stall (DWC_XDCI_MAX_DELAY_ITERATIONS);
> +    }
> +  } while (--MaxDelayIter);
> +
> +  if (!MaxDelayIter) {
> +    DEBUG ((DEBUG_INFO, "Failed to reset device controller\n"));
> +    return EFI_DEVICE_ERROR;
> +  }
> +
> +  DEBUG ((DEBUG_INFO, "USB core has been reset\n"));
> +
> +  LocalCoreHandle->DevState = UsbDevStateDefault;
> +
> +  //
> +  // Clear KeepConnect bit so we can allow disconnect and
> +  // re-connect. Stay in RX_DETECT state
> +  //
> +  UsbRegWrite (
> +    BaseAddr,
> +    DWC_XDCI_DCTL_REG,
> +    UsbRegRead (BaseAddr, DWC_XDCI_DCTL_REG) &
> +    (~DWC_XDCI_DCTL_KEEP_CONNECT_MASK) &
> +    ((~DWC_XDCI_DCTL_STATE_CHANGE_REQ_MASK) |
> +    (DWC_XDCI_DCTL_STATE_CHANGE_REQ_RX_DETECT << DWC_XDCI_DCTL_STATE_CHANGE_REQ_BIT_POS))
> +    );
> +
> +  DEBUG ((DEBUG_INFO, "Device controller Synopsys ID: %x\n", UsbRegRead (BaseAddr, DWC_XDCI_GSNPSID_REG)));
> +  DEBUG ((DEBUG_INFO, "Default value of xDCI GSBUSCFG0 and GSBUSCFG1: %x, %x\n",
> +          UsbRegRead (BaseAddr, DWC_XDCI_GSBUSCFG0_REG),
> +          UsbRegRead (BaseAddr, DWC_XDCI_GSBUSCFG1_REG)));
> +
> +  DEBUG ((DEBUG_INFO, "Default value of xDCI GTXTHRCFG and GRXTHRCFG: %x, %x\n",
> +          UsbRegRead (BaseAddr, DWC_XDCI_GTXTHRCFG_REG),
> +          UsbRegRead (BaseAddr, DWC_XDCI_GRXTHRCFG_REG)));
> +
> +  //
> +  // Clear ULPI auto-resume bit
> +  //
> +  UsbRegWrite (
> +    BaseAddr,
> +    DWC_XDCI_GUSB2PHYCFG_REG (0),
> +    (UsbRegRead (BaseAddr, DWC_XDCI_GUSB2PHYCFG_REG (0)) & ~DWC_XDCI_GUSB2PHYCFG_ULPI_AUTO_RESUME_MASK)
> +    );
> +
> +  DEBUG ((DEBUG_INFO, "Default value of xDCI GUSB2PHYCFG and GUSB3PIPECTL: %x, %x\n",
> +          UsbRegRead (BaseAddr, DWC_XDCI_GUSB2PHYCFG_REG (0)),
> +          UsbRegRead (BaseAddr, DWC_XDCI_GUSB3PIPECTL_REG (0))));
> +
> +  //
> +  // Only one RxFIFO
> +  //
> +  DEBUG ((DEBUG_INFO, "Default value of DWC_XDCI_GRXFIFOSIZ: %x\n",
> +          UsbRegRead (BaseAddr, DWC_XDCI_GRXFIFOSIZ_REG (0))));
> +
> +  for (i = 0; i < DWC_XDCI_MAX_ENDPOINTS; i++) {
> +    DEBUG ((DEBUG_INFO, "Default value of xDCI DWC_XDCI_GTXFIFOSIZ %d: %x\n",
> +            i, UsbRegRead (BaseAddr, DWC_XDCI_GTXFIFOSIZ_REG (i))));
> +  }
> +
> +  //
> +  // TODO: Need to check if TxFIFO should start where RxFIFO ends
> +  // or default is correct i.e. TxFIFO starts at 0 just like RxFIFO
> +  //
> +
> +  //
> +  // Allocate and Initialize Event Buffers
> +  //
> +  LocalCoreHandle->MaxDevIntLines = ((UsbRegRead (BaseAddr, DWC_XDCI_GHWPARAMS1_REG) &
> +                                           DWC_XDCI_GHWPARAMS1_NUM_INT_MASK) >>
> +                                           DWC_XDCI_GHWPARAMS1_NUM_INT_BIT_POS);
> +
> +  DEBUG ((DEBUG_INFO, "Max dev int lines: %d\n", LocalCoreHandle->MaxDevIntLines));
> +  //
> +  // One event Buffer per interrupt line.
> +  //  Need to align it to size of event Buffer
> +  //  Buffer needs to be big enough. Otherwise the core
> +  //  won't operate
> +  //
> +  LocalCoreHandle->AlignedEventBuffers = (DWC_XDCI_EVENT_BUFFER *)
> +                                             ((UINT32)(UINTN)(LocalCoreHandle->EventBuffers) +
> +                                             ((sizeof (DWC_XDCI_EVENT_BUFFER) * DWC_XDCI_MAX_EVENTS_PER_BUFFER) -
> +                                             (((UINT32)(UINTN)(LocalCoreHandle->EventBuffers)) %
> +                                             (sizeof (DWC_XDCI_EVENT_BUFFER) * DWC_XDCI_MAX_EVENTS_PER_BUFFER))));
> +
> +  for (i = 0; i < LocalCoreHandle->MaxDevIntLines; i++) {
> +    UsbRegWrite (
> +      BaseAddr,
> +      DWC_XDCI_GEVNTADR_REG (i),
> +      (UINT32)(UINTN)(LocalCoreHandle->AlignedEventBuffers + i * sizeof(DWC_XDCI_EVENT_BUFFER) * DWC_XDCI_MAX_EVENTS_PER_BUFFER)
> +      );
> +
> +    //
> +    // Clear High 32bit address register, GEVNTADR register is 64-bit register
> +    // default is 0xffffffffffffffff
> +    //
> +    UsbRegWrite (BaseAddr, DWC_XDCI_GEVNTADR_REG (i) + 4, 0x00000000);
> +
> +    LocalCoreHandle->CurrentEventBuffer = LocalCoreHandle->AlignedEventBuffers;
> +    //
> +    // Write size and clear the mask
> +    //
> +    UsbRegWrite (
> +      BaseAddr,
> +      DWC_XDCI_EVNTSIZ_REG (i),
> +      sizeof (DWC_XDCI_EVENT_BUFFER) * DWC_XDCI_MAX_EVENTS_PER_BUFFER
> +      );
> +
> +    //
> +    // Write 0 to the event count register as the last step
> +    // for event configuration
> +    //
> +    UsbRegWrite (BaseAddr, DWC_XDCI_EVNTCOUNT_REG (i), 0);
> +
> +    DEBUG ((DEBUG_INFO, "Value of xDCI Event Buffer %d: %x, Size: %x, Count: %x\n",
> +                        i,
> +                        UsbRegRead (BaseAddr, DWC_XDCI_GEVNTADR_REG (i)),
> +                        UsbRegRead (BaseAddr, DWC_XDCI_EVNTSIZ_REG (i)),
> +                        UsbRegRead (BaseAddr, DWC_XDCI_EVNTCOUNT_REG (i))));
> +  }
> +
> +    //
> +    // Program Global Control Register to disable scaledown,
> +    // disable clock gating
> +    //
> +    UsbRegWrite (
> +      BaseAddr,
> +      DWC_XDCI_GCTL_REG,
> +      ((UsbRegRead(BaseAddr, DWC_XDCI_GCTL_REG) &
> +                    ~(DWC_XDCI_GCTL_SCALE_DOWN_MODE_MASK + DWC_XDCI_GCTL_RAMCLKSEL_MASK + DWC_XDCI_GCTL_DISABLE_SCRAMB_MASK)) |
> +                    DWC_XDCI_GCTL_DISABLE_CLK_GATING_MASK |
> +                    (DWC_XDCI_GCTL_PRT_CAP_DEVICE << DWC_XDCI_GCTL_PRT_CAP_DIR_BIT_POS)));
> +
> +    DEBUG ((DEBUG_INFO, "Setup value of xDCI DWC_XDCI_GCTL_REG: 0x%x\n", UsbRegRead (BaseAddr, DWC_XDCI_GCTL_REG)));
> +
> +
> +  //
> +  // TODO: Program desired Speed and set LPM capable
> +  // We will do this when SuperSpeed works. For now,
> +  // force into High-Speed mode to aVOID anyone trying this
> +  // on Super Speed port
> +  //
> +#ifdef SUPPORT_SUPER_SPEED
> +  UsbRegWrite (
> +    BaseAddr,
> +    DWC_XDCI_DCFG_REG,
> +    (UsbRegRead (BaseAddr, DWC_XDCI_DCFG_REG) & ~DWC_XDCI_DCFG_DESIRED_DEV_SPEED_MASK) | LocalCoreHandle->DesiredSpeed
> +    );
> +#else
> +  UsbRegWrite (
> +    BaseAddr,
> +    DWC_XDCI_DCFG_REG,
> +    (UsbRegRead (BaseAddr, DWC_XDCI_DCFG_REG) & ~DWC_XDCI_DCFG_DESIRED_DEV_SPEED_MASK) | DWC_XDCI_DCFG_DESIRED_HS_SPEED
> +    );
> +#endif
> +
> +  DEBUG ((DEBUG_INFO, "Setup value of xDCI DWC_XDCI_DCFG_REG: 0x%x\n", UsbRegRead (BaseAddr, DWC_XDCI_DCFG_REG)));
> +  DEBUG ((DEBUG_INFO, "Setup value of xDCI DWC_XDCI_DSTS_REG: 0x%x\n", UsbRegRead (BaseAddr, DWC_XDCI_DSTS_REG)));
> +
> +  //
> +  // Enable Device Interrupt Events
> +  //
> +  UsbRegWrite (
> +    BaseAddr,
> +    DWC_XDCI_DEVTEN_REG,
> +    DWC_XDCI_DEVTEN_DEVICE_INTS
> +    );
> +
> +  //
> +  // Program the desired role
> +  //
> +  UsbRegWrite (
> +    BaseAddr,
> +    DWC_XDCI_GCTL_REG,
> +    (UsbRegRead (BaseAddr, DWC_XDCI_GCTL_REG) & ~DWC_XDCI_GCTL_PRT_CAP_DIR_MASK) | (LocalCoreHandle->Role << DWC_XDCI_GCTL_PRT_CAP_DIR_BIT_POS)
> +    );
> +
> +  //
> +  // Clear USB2 suspend for start new config command
> +  //
> +  UsbRegWrite (
> +    BaseAddr,
> +    DWC_XDCI_GUSB2PHYCFG_REG (0),
> +    (UsbRegRead (BaseAddr, DWC_XDCI_GUSB2PHYCFG_REG(0)) & ~DWC_XDCI_GUSB2PHYCFG_SUSPEND_PHY_MASK)
> +    );
> +  //
> +  // Clear USB3 suspend for start new config command
> +  //
> +  UsbRegWrite (
> +    BaseAddr,
> +    DWC_XDCI_GUSB3PIPECTL_REG (0),
> +    (UsbRegRead (BaseAddr, DWC_XDCI_GUSB3PIPECTL_REG(0)) & ~DWC_XDCI_GUSB3PIPECTL_SUSPEND_PHY_MASK)
> +    );
> +  //
> +  // Issue DEPSTARTCFG command for EP0
> +  //
> +  status = DwcXdciCoreInitEpCmdParams (
> +             LocalCoreHandle,
> +             &LocalCoreHandle->EpHandles[0].EpInfo,
> +             DWC_XDCI_PARAM0_SET_EP_CFG_ACTN_NONE,
> +             EPCMD_START_NEW_CONFIG,
> +             &EpCmdParams
> +             );
> +
> +  if (status) {
> +    DEBUG ((DEBUG_INFO, "DwcXdciCoreInit: Failed to init params for START_NEW_CONFIG EP command on xDCI\n"));
> +    return status;
> +  }
> +
> +  //
> +  // Issue the command
> +  //
> +  status = DwcXdciCoreIssueEpCmd (
> +             LocalCoreHandle,
> +             0,
> +             EPCMD_START_NEW_CONFIG,
> +             &EpCmdParams
> +             );
> +
> +  if (status) {
> +    DEBUG ((DEBUG_INFO, "DwcXdciCoreInit: Failed to issue START_NEW_CONFIG EP command on xDCI\n"));
> +    return status;
> +  }
> +
> +  //
> +  // Issue DEPCFG command for EP0
> +  //
> +  status = DwcXdciCoreInitEpCmdParams (
> +             LocalCoreHandle,
> +             &LocalCoreHandle->EpHandles[0].EpInfo,
> +             DWC_XDCI_PARAM0_SET_EP_CFG_ACTN_INIT_STATE,
> +             EPCMD_SET_EP_CONFIG,
> +             &EpCmdParams
> +             );
> +
> +  if (status) {
> +    DEBUG ((DEBUG_INFO, "DwcXdciCoreInit: Failed to init params for SET_EP_CONFIG command on xDCI for EP0\n"));
> +    return status;
> +  }
> +
> +  //
> +  // Issue the command
> +  //
> +  status = DwcXdciCoreIssueEpCmd (
> +             LocalCoreHandle,
> +             0,
> +             EPCMD_SET_EP_CONFIG,
> +             &EpCmdParams);
> +
> +  if (status) {
> +    DEBUG ((DEBUG_INFO, "DwcXdciCoreInit: Failed to issue SET_EP_CONFIG command on xDCI for EP0\n"));
> +    return status;
> +  }
> +
> +  //
> +  // Issue DEPCFG command for EP1
> +  //
> +  status = DwcXdciCoreInitEpCmdParams (
> +             LocalCoreHandle,
> +             &LocalCoreHandle->EpHandles[1].EpInfo,
> +             DWC_XDCI_PARAM0_SET_EP_CFG_ACTN_INIT_STATE,
> +             EPCMD_SET_EP_CONFIG,
> +             &EpCmdParams
> +             );
> +
> +  if (status) {
> +    DEBUG ((DEBUG_INFO, "DwcXdciCoreInit: Failed to init params for SET_EP_CONFIG command on xDCI for EP1\n"));
> +    return status;
> +  }
> +
> +  //
> +  // Issue the command
> +  //
> +  status = DwcXdciCoreIssueEpCmd (
> +             LocalCoreHandle,
> +             1,
> +             EPCMD_SET_EP_CONFIG,
> +             &EpCmdParams
> +             );
> +
> +  if (status) {
> +    DEBUG ((DEBUG_INFO, "DwcXdciCoreInit: Failed to issue SET_EP_CONFIG command on xDCI for EP1\n"));
> +    return status;
> +  }
> +
> +  //
> +  // Issue DEPXFERCFG command for EP0
> +  //
> +  status = DwcXdciCoreInitEpCmdParams (
> +             LocalCoreHandle,
> +             &LocalCoreHandle->EpHandles[0].EpInfo,
> +             DWC_XDCI_PARAM0_SET_EP_CFG_ACTN_NONE,
> +             EPCMD_SET_EP_XFER_RES_CONFIG,
> +             &EpCmdParams
> +             );
> +
> +  if (status) {
> +    DEBUG ((DEBUG_INFO, "DwcXdciCoreInit: Failed to init params for EPCMD_SET_EP_XFER_RES_CONFIG command on xDCI for EP0\n"));
> +    return status;
> +  }
> +
> +  //
> +  // Issue the command
> +  //
> +  status = DwcXdciCoreIssueEpCmd (
> +             LocalCoreHandle,
> +             0,
> +             EPCMD_SET_EP_XFER_RES_CONFIG,
> +             &EpCmdParams
> +             );
> +
> +  if (status) {
> +    DEBUG ((DEBUG_INFO, "DwcXdciCoreInit: Failed to issue EPCMD_SET_EP_XFER_RES_CONFIG command on xDCI for EP0\n"));
> +    return status;
> +  }
> +
> +  //
> +  // Issue DEPXFERCFG command for EP1
> +  //
> +  status = DwcXdciCoreInitEpCmdParams (
> +             LocalCoreHandle,
> +             &LocalCoreHandle->EpHandles[1].EpInfo,
> +             DWC_XDCI_PARAM0_SET_EP_CFG_ACTN_NONE,
> +             EPCMD_SET_EP_XFER_RES_CONFIG,
> +             &EpCmdParams
> +             );
> +
> +  if (status) {
> +    DEBUG ((DEBUG_INFO, "DwcXdciCoreInit: Failed to init params for EPCMD_SET_EP_XFER_RES_CONFIG command on xDCI for EP1\n"));
> +    return status;
> +  }
> +
> +  //
> +  // Issue the command
> +  //
> +  status = DwcXdciCoreIssueEpCmd (
> +             LocalCoreHandle,
> +             1,
> +             EPCMD_SET_EP_XFER_RES_CONFIG,
> +             &EpCmdParams
> +             );
> +
> +  if (status) {
> +    DEBUG ((DEBUG_INFO, "DwcXdciCoreInit: Failed to issue EPCMD_SET_EP_XFER_RES_CONFIG command on xDCI for EP1\n"));
> +    return status;
> +  }
> +
> +  //
> +  // Prepare a Buffer for SETUP packet
> +  //
> +  LocalCoreHandle->Trbs = (DWC_XDCI_TRB *)((UINTN)
> +                            LocalCoreHandle->UnalignedTrbs +
> +                            (UINTN)(DWC_XDCI_TRB_BYTE_ALIGNMENT -
> +                            ((UINT32)(UINTN)LocalCoreHandle->UnalignedTrbs %
> +                            DWC_XDCI_TRB_BYTE_ALIGNMENT)));
> +
> +  DEBUG ((DEBUG_INFO, "(DwcXdciCoreInit)@@@@@@@@@ unalignedTrbs address is 0x%x\n", LocalCoreHandle->UnalignedTrbs));
> +  DEBUG ((DEBUG_INFO, "(DwcXdciCoreInit)@@@@@@@@@ TRB address is 0x%x\n", LocalCoreHandle->Trbs));
> +
> +  //
> +  // Allocate Setup Buffer that is 8-byte aligned
> +  //
> +  LocalCoreHandle->AlignedSetupBuffer = LocalCoreHandle->DefaultSetupBuffer +
> +                                            (DWC_XDCI_SETUP_BUFF_SIZE -
> +                                            ((UINT32)(UINTN)(LocalCoreHandle->DefaultSetupBuffer) % DWC_XDCI_SETUP_BUFF_SIZE));
> +
> +  //
> +  // Aligned Buffer for status phase
> +  //
> +  LocalCoreHandle->AlignedMiscBuffer = LocalCoreHandle->MiscBuffer +
> +                                           (DWC_XDCI_SETUP_BUFF_SIZE -
> +                                           ((UINT32)(UINTN)(LocalCoreHandle->AlignedMiscBuffer) % DWC_XDCI_SETUP_BUFF_SIZE));
> +
> +  //
> +  // We will queue SETUP request when we see bus reset
> +  //
> +
> +  //
> +  // Enable Physical Endpoints 0
> +  //
> +  UsbRegWrite (
> +    BaseAddr,
> +    DWC_XDCI_EP_DALEPENA_REG,
> +    UsbRegRead (BaseAddr, DWC_XDCI_EP_DALEPENA_REG) | (1 << 0)
> +    );
> +
> +  //
> +  // Enable Physical Endpoints 1
> +  //
> +  UsbRegWrite (
> +    BaseAddr,
> +    DWC_XDCI_EP_DALEPENA_REG,
> +    UsbRegRead (BaseAddr, DWC_XDCI_EP_DALEPENA_REG) | (1 << 1)
> +    );
> +
> +  DEBUG ((DEBUG_INFO, "Default value of xDCI DWC_XDCI_DEVTEN_REG: 0x%x\n", UsbRegRead (BaseAddr, DWC_XDCI_DEVTEN_REG)));
> +  return status;
> +
> +
> +}
> +
> +
> +EFI_STATUS
> +UsbXdciCoreFlushEpFifo (
> +  IN VOID           *CoreHandle,
> +  IN USB_EP_INFO    *EpInfo
> +  )
> +{
> +  EFI_STATUS  Status = EFI_DEVICE_ERROR;
> +  UINT32      EpNum;
> +
> +  if (CoreHandle == NULL) {
> +    DEBUG ((DEBUG_INFO, "DwcXdciEpCancelTransfer: INVALID handle\n"));
> +    return EFI_DEVICE_ERROR;
> +  }
> +
> +  //
> +  // Get physical EP num
> +  //
> +  EpNum = DwcXdciGetPhysicalEpNum (EpInfo->EpNum, EpInfo->EpDir);
> +  DwcXdciCoreFlushEpFifo(CoreHandle, EpNum);
> +
> +  return Status;
> +}
> diff --git a/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciDWC.h b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciDWC.h
> new file mode 100644
> index 0000000000..9c1b2d1d85
> --- /dev/null
> +++ b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciDWC.h
> @@ -0,0 +1,741 @@
> +/** @file
> +  Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR>
> +
> +  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.
> +
> +**/
> +
> +#ifndef _XDCI_DWC_H_
> +#define _XDCI_DWC_H_
> +
> +#include "XdciCommon.h"
> +#include "XdciDevice.h"
> +
> +#define DWC_XDCI_MAX_ENDPOINTS                             (16)
> +#define DWC_XDCI_SS_CTRL_EP_MPS                            (512)
> +#define DWC_XDCI_HS_CTRL_EP_MPS                            (64)
> +#define DWC_XDCI_FS_CTRL_EP_MPS                            (64)
> +#define DWC_XDCI_LS_CTRL_EP_MPS                            (8)
> +#define DWC_XDCI_SS_CTRL_BUF_SIZE                          (512)
> +#define DWC_XDCI_SETUP_BUFF_SIZE                           (8)
> +#define DWC_XDCI_MAX_EVENTS_PER_BUFFER                     (16)
> +#define DWC_XDCI_TRB_BYTE_ALIGNMENT                        (16)
> +#define DWC_XDCI_DEFAULT_TX_FIFO_SIZE                      (1024)
> +#define DWC_XDCI_TRB_NUM                                   (32)
> +#define DWC_XDCI_MASK                                      (DWC_XDCI_TRB_NUM - 1)
> +
> +#define DWC_XDCI_MAX_DELAY_ITERATIONS                      (1000)
> +
> +#define DWC_XDCI_GSBUSCFG0_REG                             (0xC100)
> +#define DWC_XDCI_GSBUSCFG1_REG                             (0xC104)
> +#define DWC_XDCI_GTXTHRCFG_REG                             (0xC108)
> +#define DWC_XDCI_GRXTHRCFG_REG                             (0xC10C)
> +
> +//
> +// Global Control Register and bit definitions
> +//
> +#define DWC_XDCI_GCTL_REG                                  (0xC110)
> +#define DWC_XDCI_GCTL_PWRDNSCALE_MASK                      (0xFFF80000)
> +#define DWC_XDCI_GCTL_PWRDNSCALE_VAL                       (0x13880000)
> +#define DWC_XDCI_GCTL_U2RSTECN_MASK                        (0x00010000)
> +#define DWC_XDCI_GCTL_PRT_CAP_DIR_MASK                     (0x00003000)
> +#define DWC_XDCI_GCTL_PRT_CAP_DIR_BIT_POS                  (12)
> +#define DWC_XDCI_GCTL_PRT_CAP_HOST                         (1)
> +#define DWC_XDCI_GCTL_PRT_CAP_DEVICE                       (2)
> +#define DWC_XDCI_GCTL_PRT_CAP_OTG                          (3)
> +#define DWC_XDCI_GCTL_RAMCLKSEL_MASK                       (0x000000C0)
> +#define DWC_XDCI_GCTL_SCALE_DOWN_MODE_MASK                 (0x00000030)
> +#define DWC_XDCI_GCTL_DISABLE_CLK_GATING_MASK              (0x00000001)
> +#define DWC_XDCI_GCTL_DISABLE_SCRAMB_MASK                  (0x00000008)
> +
> +#define DWC_XDCI_GSTS_REG                                  (0xC118)
> +#define DWC_XDCI_GSNPSID_REG                               (0xC120)
> +#define DWC_XDCI_GGPIO_REG                                 (0xC124)
> +#define DWC_XDCI_GUID_REG                                  (0xC128)
> +#define DWC_XDCI_GUCTL_REG                                 (0xC12C)
> +#define DWC_XDCI_GBUSERRADDR                               (0xC130)
> +
> +//
> +// Global Hardware Parameters Registers
> +//
> +#define DWC_XDCI_GHWPARAMS0_REG                            (0xC140)
> +#define DWC_XDCI_GHWPARAMS1_REG                            (0xC144)
> +#define DWC_XDCI_GHWPARAMS1_NUM_INT_MASK                   (0x1F8000)
> +#define DWC_XDCI_GHWPARAMS1_NUM_INT_BIT_POS                (15)
> +
> +#define DWC_XDCI_GHWPARAMS2_REG                            (0xC148)
> +#define DWC_XDCI_GHWPARAMS3_REG                            (0xC14C)
> +#define DWC_XDCI_GHWPARAMS4_REG                            (0xC150)
> +#define DWC_XDCI_GHWPARAMS4_CACHE_TRBS_PER_XFER_MASK       (0x0000003F)
> +#define DWC_XDCI_GHWPARAMS5_REG                            (0xC154)
> +#define DWC_XDCI_GHWPARAMS6_REG                            (0xC158)
> +#define DWC_XDCI_GHWPARAMS7_REG                            (0xC15C)
> +#define DWC_XDCI_GHWPARAMS8_REG                            (0xC600)
> +
> +#define DWC_XDCI_GDBGFIFOSPACE_REG                         (0xC160)
> +
> +#define DWC_XDCI_GUSB2PHYCFG_REG(n)                        (0xC200 + (n << 2))
> +#define DWC_XDCI_GUSB2PHYCFG_ULPI_AUTO_RESUME_MASK         (0x00008000)
> +#define DWC_XDCI_GUSB2PHYCFG_SUSPEND_PHY_MASK              (0x00000040)
> +
> +#define DWC_XDCI_GUSB3PIPECTL_REG(n)                       (0xC2C0 + (n << 2))
> +#define DWC_XDCI_GUSB3PIPECTL_SUSPEND_PHY_MASK             (0x00020000)
> +
> +#define DWC_XDCI_GTXFIFOSIZ_REG(n)                         (0xC300 + (n << 2))
> +#define DWC_XDCI_GTXFIFOSIZ_START_ADDRESS_MASK             (0xFFFF0000)
> +#define DWC_XDCI_GTXFIFOSIZ_START_ADDRESS_BIT_POS          (16)
> +#define DWC_XDCI_GRXFIFOSIZ_REG(n)                         (0xC380 + (n << 2))
> +
> +//
> +// Global Event Buffer Registers
> +//
> +#define DWC_XDCI_GEVNTADR_REG(n)                           (0xC400 + (n << 4))
> +#define DWC_XDCI_EVNTSIZ_REG(n)                            (0xC408 + (n << 4))
> +#define DWC_XDCI_EVNTSIZ_MASK                              (0x0000FFFF)
> +#define DWC_XDCI_EVNT_INTR_MASK                            (0x80000000)
> +#define DWC_XDCI_EVNTCOUNT_REG(n)                          (0xC40C + (n << 4))
> +#define DWC_XDCI_EVNTCOUNT_MASK                            (0x0000FFFF)
> +
> +//
> +// Device Configuration Register and Bit Definitions
> +//
> +#define DWC_XDCI_DCFG_REG                                  (0xC700)
> +#define DWC_XDCI_DCFG_LPM_CAPABLE_MASK                     (0x00400000)
> +#define DWC_XDCI_DCFG_DEV_ADDRESS_MASK                     (0x000003F8)
> +#define DWC_XDCI_DCFG_DEV_ADDRESS_BIT_POS                  (3)
> +#define DWC_XDCI_DCFG_DESIRED_DEV_SPEED_MASK               (0x00000007)
> +#define DWC_XDCI_DCFG_DESIRED_SS_SPEED                     (0x00000004)
> +#define DWC_XDCI_DCFG_DESIRED_FS_SPEED                     (0x00000001)
> +#define DWC_XDCI_DCFG_DESIRED_HS_SPEED                     (0x00000000)
> +
> +//
> +// Device Control Register
> +//
> +#define DWC_XDCI_DCTL_REG                                  (0xC704)
> +#define DWC_XDCI_DCTL_RUN_STOP_MASK                        (0x80000000)
> +#define DWC_XDCI_DCTL_RUN_STOP_BIT_POS                     (31)
> +#define DWC_XDCI_DCTL_CSFTRST_MASK                         (0x40000000)
> +#define DWC_XDCI_DCTL_CSFTRST_BIT_POS                      (30)
> +#define DWC_XDCI_DCTL_KEEP_CONNECT_MASK                    (0x00080000)
> +#define DWC_XDCI_DCTL_KEEP_CONNECT_BIT_POS                 (19)
> +#define DWC_XDCI_DCTL_CSFTRST_BIT_POS                      (30)
> +#define DWC_XDCI_DCTL_STATE_CHANGE_REQ_MASK                (0x000001E0)
> +#define DWC_XDCI_DCTL_STATE_CHANGE_REQ_BIT_POS             (5)
> +#define DWC_XDCI_DCTL_STATE_CHANGE_REQ_NO_ACTION           (1)
> +#define DWC_XDCI_DCTL_STATE_CHANGE_REQ_SS_DISABLED         (4)
> +#define DWC_XDCI_DCTL_STATE_CHANGE_REQ_RX_DETECT           (5)
> +#define DWC_XDCI_DCTL_STATE_CHANGE_REQ_SS_INACTIVE         (6)
> +#define DWC_XDCI_DCTL_STATE_CHANGE_REQ_RECOVERY            (8)
> +#define DWC_XDCI_DCTL_STATE_CHANGE_REQ_COMPLIANCE          (10)
> +#define DWC_XDCI_DCTL_STATE_CHANGE_REQ_REMOTE_WAKEUP       (8)
> +
> +//
> +// Device Event Enable Register
> +//
> +#define DWC_XDCI_DEVTEN_REG                                (0xC708)
> +#define DWC_XDCI_DEVTEN_DISCONN_DET_EN_MASK                (0x00000001)
> +#define DWC_XDCI_DEVTEN_RESET_DET_EN_MASK                  (0x00000002)
> +#define DWC_XDCI_DEVTEN_CONN_DONE_DET_EN_MASK              (0x00000004)
> +#define DWC_XDCI_DEVTEN_LINK_STATE_CHANGE_DET_EN_MASK      (0x00000008)
> +#define DWC_XDCI_DEVTEN_RESUME_WAKEUP_DET_EN_MASK          (0x00000010)
> +#define DWC_XDCI_DEVTEN_HIBERNATION_REQ_EN_MASK            (0x00000020)
> +#define DWC_XDCI_DEVTEN_U3L2L1_DET_EN_MASK                 (0x00000040)
> +#define DWC_XDCI_DEVTEN_SOF_DET_EN_MASK                    (0x00000080)
> +#define DWC_XDCI_DEVTEN_ERRATIC_ERR_DET_EN_MASK            (0x00000200)
> +#define DWC_XDCI_DEVTEN_VNDR_DEV_TST_RX_DET_EN_MASK        (0x00001000)
> +
> +#define DWC_XDCI_DEVTEN_DEVICE_INTS                        (DWC_XDCI_DEVTEN_DISCONN_DET_EN_MASK | \
> +        DWC_XDCI_DEVTEN_RESET_DET_EN_MASK | DWC_XDCI_DEVTEN_CONN_DONE_DET_EN_MASK | \
> +        DWC_XDCI_DEVTEN_LINK_STATE_CHANGE_DET_EN_MASK | DWC_XDCI_DEVTEN_RESUME_WAKEUP_DET_EN_MASK | \
> +        DWC_XDCI_DEVTEN_HIBERNATION_REQ_EN_MASK | DWC_XDCI_DEVTEN_U3L2L1_DET_EN_MASK | \
> +        DWC_XDCI_DEVTEN_ERRATIC_ERR_DET_EN_MASK)
> +
> +#define DWC_XDCI_EVENT_BUFF_BULK_STREAM_ID_MASK            (0xFFFF0000)
> +#define DWC_XDCI_EVENT_BUFF_ISOCH_UFRAME_NUM_MASK          (0xFFFF0000)
> +#define DWC_XDCI_EVENT_BUFF_EP_CMD_TYPE_MASK               (0x0F000000)
> +#define DWC_XDCI_EVENT_BUFF_EP_XFER_RES_INDEX_MASK         (0x007F0000)
> +#define DWC_XDCI_EVENT_BUFF_EP_XFER_ACTIVE_MASK            (0x00008000)
> +#define DWC_XDCI_EVENT_BUFF_EP_CTRL_DATA_REQ_MASK          (0x00001000)
> +#define DWC_XDCI_EVENT_BUFF_EP_CTRL_STATUS_REQ_MASK        (0x00002000)
> +#define DWC_XDCI_EVENT_BUFF_EP_LST_MASK                    (0x00008000)
> +#define DWC_XDCI_EVENT_BUFF_EP_MISSED_ISOCH_MASK           (0x00008000)
> +#define DWC_XDCI_EVENT_BUFF_EP_IOC_MASK                    (0x00004000)
> +#define DWC_XDCI_EVENT_BUFF_EP_LAST_PKT_MASK               (0x00002000)
> +#define DWC_XDCI_EVENT_BUFF_EP_STREAM_NOT_FND_MASK         (0x00002000)
> +#define DWC_XDCI_EVENT_BUFF_EP_STREAM_FND_MASK             (0x00001000)
> +#define DWC_XDCI_EVENT_BUFF_EP_ERR_NO_RES_MASK             (0x00001000)
> +#define DWC_XDCI_EVENT_BUFF_EP_INVALID_RES_MASK            (0x00001000)
> +
> +#define DWC_XDCI_EVENT_BUFF_EP_EVENT_MASK                  (0x000003C0)
> +#define DWC_XDCI_EVENT_BUFF_EP_EVENT_BIT_POS               (6)
> +#define DWC_XDCI_EVENT_BUFF_EP_XFER_CMPLT                  (1)
> +#define DWC_XDCI_EVENT_BUFF_EP_XFER_IN_PROGRESS            (2)
> +#define DWC_XDCI_EVENT_BUFF_EP_XFER_NOT_READY              (3)
> +#define DWC_XDCI_EVENT_BUFF_EP_STREAM_EVENT                (6)
> +#define DWC_XDCI_EVENT_BUFF_EP_CMD_CMPLT                   (7)
> +
> +#define DWC_XDCI_EVENT_BUFF_EP_NUM_MASK                    (0x0000003E)
> +#define DWC_XDCI_EVENT_BUFF_EP_NUM_BIT_POS                 (1)
> +
> +#define DWC_XDCI_EVENT_BUFF_EP_EVENT_STATUS_MASK           (0x0000F000)
> +
> +
> +#define DWC_XDCI_EVENT_BUFF_DEV_HIRD_MASK                  (0x01E00000)
> +#define DWC_XDCI_EVENT_BUFF_DEV_HIRD_BIT_POS               (21)
> +#define DWC_XDCI_EVENT_BUFF_DEV_SS_EVENT_MASK              (0x00100000)
> +#define DWC_XDCI_EVENT_BUFF_DEV_LINK_STATE_MASK            (0x000F0000)
> +#define DWC_XDCI_EVENT_BUFF_DEV_LINK_STATE_BIT_POS         (16)
> +
> +#define DWC_XDCI_EVENT_BUFF_DEV_EVT_MASK                   (0x00000F00)
> +#define DWC_XDCI_EVENT_BUFF_DEV_EVT_BIT_POS                (8)
> +#define DWC_XDCI_EVENT_BUFF_DEV_TST_LMP_RX_EVENT           (12)
> +#define DWC_XDCI_EVENT_BUFF_DEV_BUFF_OVFL_EVENT            (11)
> +#define DWC_XDCI_EVENT_BUFF_DEV_CMD_CMPLT_EVENT            (10)
> +#define DWC_XDCI_EVENT_BUFF_DEV_ERRATIC_ERR_EVENT          (9)
> +#define DWC_XDCI_EVENT_BUFF_DEV_SOF_EVENT                  (7)
> +#define DWC_XDCI_EVENT_BUFF_DEV_HBRNTN_REQ_EVENT           (5)
> +#define DWC_XDCI_EVENT_BUFF_DEV_WKUP_EVENT                 (4)
> +#define DWC_XDCI_EVENT_BUFF_DEV_STATE_CHANGE_EVENT         (3)
> +#define DWC_XDCI_EVENT_BUFF_DEV_CONN_DONE_EVENT            (2)
> +#define DWC_XDCI_EVENT_BUFF_DEV_USB_RESET_EVENT            (1)
> +#define DWC_XDCI_EVENT_BUFF_DEV_DISCONN_EVENT              (0)
> +
> +#define DWC_XDCI_EVENT_DEV_MASK                            (0x00000001)
> +
> +//
> +// Device Status Register and Bit Definitions
> +//
> +#define DWC_XDCI_DSTS_REG                                  (0xC70C)
> +#define DWC_XDCI_DSTS_DEV_CTRL_HALTED_MASK                 (0x00400000)
> +#define DWC_XDCI_DSTS_DEV_CTRL_HALTED_BIT_POS              (22)
> +#define DWC_XDCI_DSTS_CORE_IDLE                            (1 << 23)
> +#define DWC_XDCI_DSTS_CONN_SPEED_MASK                      (0x00000007)
> +#define DWC_XDCI_DSTS_LINK_STATE_MASK                      (0x003C0000)
> +#define DWC_XDCI_DSTS_LINK_STATE_DISCONNECT                (0x00100000)
> +
> +//
> +// Device Generic Command Parameter Register
> +//
> +#define DWC_XDCI_DGCMD_PARAM_REG                           (0xC710)
> +#define DWC_XDCI_DGCMD_PARAM_TX_FIFO_NUM_MASK              (0x0000001F)
> +#define DWC_XDCI_DGCMD_PARAM_TX_FIFO_DIR_MASK              (0x00000020)
> +#define DWC_XDCI_DGCMD_PARAM_TX_FIFO_DIR_BIT_POS           (5)
> +
> +//
> +// Device Generic Command Register
> +//
> +#define DWC_XDCI_DGCMD_REG                                 (0xC714)
> +#define DWC_XDCI_DGCMD_CMD_STATUS_MASK                     (0x00008000)
> +#define DWC_XDCI_DGCMD_CMD_ACTIVE_MASK                     (0x00000400)
> +#define DWC_XDCI_DGCMD_CMD_IOC_MASK                        (0x00000100)
> +#define DWC_XDCI_DGCMD_CMD_TYPE_MASK                       (0x000000FF)
> +#define DWC_XDCI_DGCMD_CMD_SET_PERIODIC_PARAMS             (0x2)
> +#define DWC_XDCI_DGCMD_CMD_SET_SCRATCH_PAD_BUFF_ARR_LO     (0x4)
> +#define DWC_XDCI_DGCMD_CMD_SET_SCRATCH_PAD_BUFF_ARR_HI     (0x5)
> +#define DWC_XDCI_DGCMD_CMD_XMIT_DEVICE_NOTIFICATION        (0x7)
> +#define DWC_XDCI_DGCMD_CMD_SEL_FIFO_FLUSH                  (0x9)
> +#define DWC_XDCI_DGCMD_CMD_ALL_FIFO_FLUSH                  (0xA)
> +#define DWC_XDCI_DGCMD_CMD_SET_EP_NRDY                     (0xC)
> +#define DWC_XDCI_DGCMD_CMD_RUN_SOC_BUS_LPBK                (0x10)
> +
> +//
> +// Device Active USB EP Enable Register
> +//
> +#define DWC_XDCI_EP_DALEPENA_REG                           (0xC720)
> +
> +//
> +// Device Physical EP CMD Param 2 Register. Value is 32-bit
> +//
> +#define DWC_XDCI_EPCMD_PARAM2_REG(n)                       (0xC800 + (n << 4))
> +
> +//
> +// Device Physical EP CMD Param 1 Register. Value is 32-bit
> +//
> +#define DWC_XDCI_EPCMD_PARAM1_REG(n)                       (0xC804 + (n << 4))
> +
> +//
> +// Device Physical EP CMD Param 0 Register. Value is 32-bit
> +//
> +#define DWC_XDCI_EPCMD_PARAM0_REG(n)                       (0xC808 + (n << 4))
> +
> +//
> +// Device Physical EP Command Registers and Bit Definitions
> +//
> +#define DWC_XDCI_EPCMD_REG(n)                              (0xC80C + (n << 4))
> +#define DWC_XDCI_EPCMD_RES_IDX_MASK                        (0x007F0000)
> +#define DWC_XDCI_EPCMD_RES_IDX_BIT_POS                     (16)
> +#define DWC_XDCI_EPCMD_CMDTYPE_MASK                        (0x0000000F)
> +#define DWC_XDCI_EPCMD_SET_EP_CONFIG                       (0x1)
> +#define DWC_XDCI_EPCMD_SET_EP_XFER_RES_CONFIG              (0x2)
> +#define DWC_XDCI_EPCMD_GET_EP_STATE                        (0x3)
> +#define DWC_XDCI_EPCMD_SET_STALL                           (0x4)
> +#define DWC_XDCI_EPCMD_CLEAR_STALL                         (0x5)
> +#define DWC_XDCI_EPCMD_START_XFER                          (0x6)
> +#define DWC_XDCI_EPCMD_UPDATE_XFER                         (0x7)
> +#define DWC_XDCI_EPCMD_END_XFER                            (0x8)
> +#define DWC_XDCI_EPCMD_START_NEW_CONFIG                    (0x9)
> +
> +#define DWC_XDCI_EPCMD_CMD_IOC_MASK                        (0x00000100)
> +#define DWC_XDCI_EPCMD_CMD_ACTIVE_MASK                     (0x00000400)
> +#define DWC_XDCI_EPCMD_HIGH_PRIO_MASK                      (0x00000800)
> +#define DWC_XDCI_EPCMD_FORCE_RM_MASK                       (0x00000800)
> +
> +//
> +// Command status and parameter values same as event status and parameters values
> +//
> +#define DWC_XDCI_EPCMD_CMD_STATUS_MASK                     (0x0000F000)
> +
> +//
> +// Command Params bit masks
> +//
> +#define DWC_XDCI_PARAM1_SET_EP_CFG_FIFO_BASED_MASK         (0x80000000)
> +#define DWC_XDCI_PARAM1_SET_EP_CFG_BULK_BASED_MASK         (0x40000000)
> +#define DWC_XDCI_PARAM1_SET_EP_CFG_EP_NUM_MASK             (0x3C000000)
> +#define DWC_XDCI_PARAM1_SET_EP_CFG_EP_DIR_MASK             (0x02000000)
> +#define DWC_XDCI_PARAM1_SET_EP_CFG_STRM_CAP_MASK           (0x01000000)
> +#define DWC_XDCI_PARAM1_SET_EP_CFG_BINTM1_MASK             (0x00FF0000)
> +#define DWC_XDCI_PARAM1_SET_EP_CFG_BINTM1_BIT_POS          (16)
> +#define DWC_XDCI_PARAM1_SET_EP_CFG_EBC_MASK                (0x00008000)
> +#define DWC_XDCI_PARAM1_SET_EP_CFG_EVT_EN_MASK             (0x00003F00)
> +#define DWC_XDCI_PARAM1_SET_EP_CFG_EVT_EN_BIT_POS          (8)
> +#define DWC_XDCI_PARAM1_SET_EP_CFG_EVT_STRM_MASK           (0x00002000)
> +#define DWC_XDCI_PARAM1_SET_EP_CFG_EVT_XFER_NRDY_MASK      (0x00000400)
> +#define DWC_XDCI_PARAM1_SET_EP_CFG_EVT_XFER_IN_PRG_MASK    (0x00000200)
> +#define DWC_XDCI_PARAM1_SET_EP_CFG_EVT_XFER_CMPLT_MASK     (0x00000100)
> +#define DWC_XDCI_PARAM1_SET_EP_CFG_INTR_NUM_MASK           (0x0000001F)
> +
> +//
> +// CMD 1 param 0
> +//
> +#define DWC_XDCI_PARAM0_SET_EP_CFG_ACTN_MASK               (0xC0000000)
> +#define DWC_XDCI_PARAM0_SET_EP_CFG_ACTN_BIT_POS            (30)
> +#define DWC_XDCI_PARAM0_SET_EP_CFG_ACTN_INIT_STATE         (0)
> +#define DWC_XDCI_PARAM0_SET_EP_CFG_ACTN_RESTORE_ST         (1)
> +#define DWC_XDCI_PARAM0_SET_EP_CFG_ACTN_MDFY_STATE         (2)
> +#define DWC_XDCI_PARAM0_SET_EP_CFG_ACTN_NONE               (3)
> +#define DWC_XDCI_PARAM0_SET_EP_CFG_BRST_SIZE_MASK          (0x03C00000)
> +#define DWC_XDCI_PARAM0_SET_EP_CFG_BRST_SIZE_BIT_POS       (22)
> +#define DWC_XDCI_PARAM0_SET_EP_CFG_FIFO_NUM_MASK           (0x003E0000)
> +#define DWC_XDCI_PARAM0_SET_EP_CFG_FIFO_NUM_BIT_POS        (17)
> +#define DWC_XDCI_PARAM0_SET_EP_CFG_MPS_MASK                (0x00003FF8)
> +#define DWC_XDCI_PARAM0_SET_EP_CFG_MPS_BIT_POS             (3)
> +#define DWC_XDCI_PARAM0_SET_EP_CFG_EP_TYPE_MASK            (0x00000006)
> +#define DWC_XDCI_PARAM0_SET_EP_CFG_EP_TYPE_BIT_POS         (1)
> +#define DWC_XDCI_PARAM0_EP_TYPE_CTRL                       (0)
> +#define DWC_XDCI_PARAM0_EP_TYPE_ISOCH                      (1)
> +#define DWC_XDCI_PARAM0_EP_TYPE_BULK                       (2)
> +#define DWC_XDCI_PARAM0_EP_TYPE_INTR                       (3)
> +
> +//
> +// CMD 1 param 1
> +//
> +#define DWC_XDCI_PARAM1_SET_EP_CFG_BULK_BASED_MASK         (0x40000000)
> +#define DWC_XDCI_PARAM1_SET_EP_CFG_EP_NUM_MASK             (0x3C000000)
> +#define DWC_XDCI_PARAM1_SET_EP_CFG_EP_NUM_BIT_POS          (26)
> +#define DWC_XDCI_PARAM1_SET_EP_CFG_EP_DIR_MASK             (0x02000000)
> +#define DWC_XDCI_PARAM1_SET_EP_CFG_EP_DIR_BIT_POS          (25)
> +#define DWC_XDCI_PARAM1_SET_EP_CFG_STRM_CAP_MASK           (0x01000000)
> +#define DWC_XDCI_PARAM1_SET_EP_CFG_BINTM1_MASK             (0x00FF0000)
> +#define DWC_XDCI_PARAM1_SET_EP_CFG_BINTM1_BIT_POS          (16)
> +#define DWC_XDCI_PARAM1_SET_EP_CFG_EBC_MASK                (0x00008000)
> +#define DWC_XDCI_PARAM1_SET_EP_CFG_EVT_EN_MASK             (0x00003F00)
> +#define DWC_XDCI_PARAM1_SET_EP_CFG_EVT_EN_BIT_POS          (8)
> +#define DWC_XDCI_PARAM1_SET_EP_CFG_EVT_STRM_MASK           (0x00002000)
> +#define DWC_XDCI_PARAM1_SET_EP_CFG_EVT_XFER_NRDY_MASK      (0x00000400)
> +#define DWC_XDCI_PARAM1_SET_EP_CFG_EVT_XFER_IN_PRG_MASK    (0x00000200)
> +#define DWC_XDCI_PARAM1_SET_EP_CFG_EVT_XFER_CMPLT_MASK     (0x00000100)
> +#define DWC_XDCI_PARAM1_SET_EP_CFG_INTR_NUM_MASK           (0x0000001F)
> +
> +//
> +// CMD 2 param 0
> +//
> +#define DWC_XDCI_PARAM0_SET_EP_XFER_RES_NUM_MASK           (0x0000FFFF)
> +
> +//
> +// CMD 3 param 2
> +//
> +#define DWC_XDCI_PARAM2_GET_EP_STATE_MASK                  (0xFFFFFFFF)
> +
> +//
> +// CMD 6 param 1
> +//
> +#define DWC_XDCI_PARAM1_STRT_XFER_TD_ADDR_LO_MASK          (0xFFFFFFFF)
> +
> +//
> +// CMD 6 param 0
> +//
> +#define DWC_XDCI_PARAM0_STRT_XFER_TD_ADDR_HI_MASK          (0xFFFFFFFF)
> +
> +//
> +// Transfer Request Block Fields' Bit Definitions
> +//
> +#define DWC_XDCI_TRB_BUFF_SIZE_MASK                        (0x00FFFFFF)
> +#define DWC_XDCI_TRB_PCM1_MASK                             (0x03000000)
> +#define DWC_XDCI_TRB_PCM1_BIT_POS                          (24)
> +#define DWC_XDCI_TRB_STATUS_MASK                           (0xF0000000)
> +#define DWC_XDCI_TRB_STATUS_BIT_POS                        (28)
> +#define DWC_XDCI_TRB_STATUS_OK                             (0)
> +#define DWC_XDCI_TRB_STATUS_MISSED_ISOCH                   (1)
> +#define DWC_XDCI_TRB_STATUS_SETUP_PENDING                  (2)
> +
> +#define DWC_XDCI_TRB_CTRL_HWO_MASK                         (0x00000001)
> +#define DWC_XDCI_TRB_CTRL_LST_TRB_MASK                     (0x00000002)
> +#define DWC_XDCI_TRB_CTRL_LST_TRB_BIT_POS                  (1)
> +#define DWC_XDCI_TRB_CTRL_CHAIN_BUFF_MASK                  (0x00000004)
> +#define DWC_XDCI_TRB_CTRL_CHAIN_BUFF_BIT_POS               (2)
> +#define DWC_XDCI_TRB_CTRL_CSP_MASK                         (0x00000008)
> +#define DWC_XDCI_TRB_CTRL_CSP_BIT_POS                      (3)
> +#define DWC_XDCI_TRB_CTRL_TYPE_MASK                        (0x000003F0)
> +#define DWC_XDCI_TRB_CTRL_TYPE_BIT_POS                     (4)
> +#define DWC_XDCI_TRB_CTRL_TYPE_NORMAL                      (1)
> +#define DWC_XDCI_TRB_CTRL_TYPE_SETUP                       (2)
> +#define DWC_XDCI_TRB_CTRL_TYPE_STATUS2                     (3)
> +#define DWC_XDCI_TRB_CTRL_TYPE_STATUS3                     (4)
> +#define DWC_XDCI_TRB_CTRL_TYPE_DATA                        (5)
> +#define DWC_XDCI_TRB_CTRL_TYPE_ISOCH_FIRST                 (6)
> +#define DWC_XDCI_TRB_CTRL_TYPE_ISOCH                       (7)
> +#define DWC_XDCI_TRB_CTRL_TYPE_LINK_TRB                    (8)
> +#define DWC_XDCI_TRB_CTRL_IOSP_MISOCH_MASK                 (0x00000400)
> +#define DWC_XDCI_TRB_CTRL_IOSP_MISOCH_BIT_POS              (10)
> +#define DWC_XDCI_TRB_CTRL_IOC_MASK                         (0x00000800)
> +#define DWC_XDCI_TRB_CTRL_IOC_BIT_POS                      (11)
> +#define DWC_XDCI_TRB_CTRL_STRM_ID_SOF_NUM_MASK             (0x3FFFC000)
> +#define DWC_XDCI_TRB_CTRL_STRM_ID_SOF_BIT_POS              (14)
> +
> +#define DWC_XDCI_DEV_EVENT_DEFAULT_SIZE_IN_BYTES           (4)
> +#define DWC_XDCI_DEV_EVENT_TST_LMP_SIZE_IN_BYTES           (12)
> +
> +typedef enum {
> +  EPCMD_SET_EP_CONFIG = 1,
> +  EPCMD_SET_EP_XFER_RES_CONFIG,
> +  EPCMD_GET_EP_STATE,
> +  EPCMD_SET_STALL,
> +  EPCMD_CLEAR_STALL,
> +  EPCMD_START_XFER,
> +  EPCMD_UPDATE_XFER,
> +  EPCMD_END_XFER,
> +  EPCMD_START_NEW_CONFIG = 9
> +} DWC_XDCI_ENDPOINT_CMD;
> +
> +typedef enum {
> +  ON = 0,
> +  SLEEP = 2,
> +  SUSPEND,
> +  DISCONNECTED,
> +  EARLY_SUSPEND,
> +  RESET = 14,
> +  RESUME = 15
> +} DWC_XDCI_HS_LINK_STATE;
> +
> +typedef enum {
> +  TRBCTL_NORMAL = 1,
> +  TRBCTL_SETUP,
> +  TRBCTL_2_PHASE,
> +  TRBCTL_3_PHASE,
> +  TRBCTL_CTRL_DATA_PHASE,
> +  TRBCTL_ISOCH_FIRST,
> +  TRBCTL_ISOCH,
> +  TRBCTL_LINK
> +} DWC_XDCI_TRB_CONTROL;
> +
> +//
> +// DWC XDCI Endpoint Commands Parameters struct
> +//
> +typedef struct {
> +  UINT32 Param2;
> +  UINT32 Param1;
> +  UINT32 Param0;
> +} DWC_XDCI_ENDPOINT_CMD_PARAMS;
> +
> +//
> +// Event Buffer Struct
> +//
> +typedef struct {
> +  UINT32 Event;
> +  UINT32 DevTstLmp1;
> +  UINT32 DevTstLmp2;
> +  UINT32 Reserved;
> +} DWC_XDCI_EVENT_BUFFER;
> +
> +//
> +// Transfer Request Block
> +//
> +typedef struct {
> +  UINT32 BuffPtrLow;
> +  UINT32 BuffPtrHigh;
> +  UINT32 LenXferParams;
> +  UINT32 TrbCtrl;
> +} DWC_XDCI_TRB;
> +
> +typedef struct  {
> +  USB_EP_INFO       EpInfo;
> +  DWC_XDCI_TRB      *Trb;
> +  USB_XFER_REQUEST  XferHandle;
> +  UINT32            CurrentXferRscIdx;
> +  VOID              *CoreHandle;
> +  USB_EP_STATE      State;
> +  USB_EP_STATE      OrgState;
> +  BOOLEAN           CheckFlag;
> +} DWC_XDCI_ENDPOINT;
> +
> +typedef struct {
> +  //
> +  // CbEventParams must be copied over by upper layer if
> +  // it defers event processing
> +  //
> +  USB_DEVICE_CALLBACK_PARAM CbEventParams;
> +
> +  //
> +  // Callback function list
> +  //
> +  USB_DEVICE_CALLBACK_FUNC  DevDisconnectCallback;
> +  USB_DEVICE_CALLBACK_FUNC  DevBusResetCallback;
> +  USB_DEVICE_CALLBACK_FUNC  DevResetDoneCallback;
> +  USB_DEVICE_CALLBACK_FUNC  DevLinkStateCallback;
> +  USB_DEVICE_CALLBACK_FUNC  DevWakeupCallback;
> +  USB_DEVICE_CALLBACK_FUNC  DevHibernationCallback;
> +  USB_DEVICE_CALLBACK_FUNC  DevSofCallback;
> +  USB_DEVICE_CALLBACK_FUNC  DevErraticErrCallback;
> +  USB_DEVICE_CALLBACK_FUNC  DevCmdCmpltCallback;
> +  USB_DEVICE_CALLBACK_FUNC  DevBuffOvflwCallback;
> +  USB_DEVICE_CALLBACK_FUNC  DevTestLmpRxCallback;
> +  USB_DEVICE_CALLBACK_FUNC  DevSetupPktReceivedCallback;
> +  USB_DEVICE_CALLBACK_FUNC  DevXferNrdyCallback;
> +  USB_DEVICE_CALLBACK_FUNC  DevXferDoneCallback;
> +} USB_DEV_CALLBACK_LIST;
> +
> +typedef struct {
> +  VOID                     *ParentHandle;                                       // Pointer to the parent this driver is associated
> +  USB_CONTROLLER_ID        Id;                                                  // ID of the controllers supported in our DCD
> +  USB_SPEED                DesiredSpeed;                                        // Desired SS, HS, FS or LS Speeds for the core
> +  USB_ROLE                 Role;                                                // Desired role i.e. host, Device or OTG
> +  USB_SPEED                ActualSpeed;                                         // Actual Speed
> +  USB_DEVICE_STATE         DevState;                                            // Device state
> +  UINT32                   BaseAddress;                                         // Register Base address
> +  UINT32                   Flags;                                               // Init flags
> +  UINT32                   MaxDevIntLines;                                      // One event Buffer per interrupt line
> +  DWC_XDCI_EVENT_BUFFER    EventBuffers [DWC_XDCI_MAX_EVENTS_PER_BUFFER * 2];   // Event Buffer pool
> +  DWC_XDCI_EVENT_BUFFER    *AlignedEventBuffers;                                // Aligned event Buffer pool
> +  DWC_XDCI_EVENT_BUFFER    *CurrentEventBuffer;                                 // Current event Buffer address
> +  DWC_XDCI_TRB             UnalignedTrbs [(DWC_XDCI_MAX_ENDPOINTS + 1) * DWC_XDCI_TRB_NUM];    // TRBs.
> +  DWC_XDCI_TRB             *Trbs;                                               // 16-bytes aligned TRBs.
> +  DWC_XDCI_ENDPOINT        EpHandles [DWC_XDCI_MAX_ENDPOINTS];                  // EPs
> +  UINT8                    DefaultSetupBuffer [DWC_XDCI_SETUP_BUFF_SIZE * 2];   // Unaligned setup Buffer
> +  UINT8                    *AlignedSetupBuffer;                                 // Aligned setup Buffer. Aligned to 8-byte boundary
> +  UINT8                    MiscBuffer [528];                                    // Unaligned misc Buffer
> +  UINT8                    *AlignedMiscBuffer;                                  // Aligned misc Buffer
> +  UINT32                   LinkState;                                           // Link state
> +  UINT32                   HirdVal;                                             // HIRD value
> +  USB_DEV_CALLBACK_LIST    EventCallbacks;
> +  volatile BOOLEAN         InterrupProcessing;
> +} XDCI_CORE_HANDLE;
> +
> +//
> +// DWC XDCI API prototypes
> +//
> +EFI_STATUS
> +EFIAPI
> +DwcXdciCoreInit (
> +  IN USB_DEV_CONFIG_PARAMS    *ConfigParams,
> +  IN VOID                     *ParentHandle,
> +  IN VOID                     **CoreHandle
> +  );
> +
> +EFI_STATUS
> +EFIAPI
> +DwcXdciCoreDeinit (
> +  IN VOID      *CoreHandle,
> +  IN UINT32    flags
> +  );
> +
> +EFI_STATUS
> +EFIAPI
> +DwcXdciCoreRegisterCallback (
> +  IN VOID                      *CoreHandle,
> +  IN USB_DEVICE_EVENT_ID       Event,
> +  IN USB_DEVICE_CALLBACK_FUNC  CallbackFunc
> +  );
> +
> +EFI_STATUS
> +EFIAPI
> +DwcXdciCoreUnregisterCallback (
> +  IN VOID                   *CoreHandle,
> +  IN USB_DEVICE_EVENT_ID    Event
> +  );
> +
> +EFI_STATUS
> +EFIAPI
> +DwcXdciCoreIsrRoutine (
> +  IN VOID *CoreHandle
> +  );
> +
> +EFI_STATUS
> +EFIAPI
> +DwcXdciCoreIsrRoutineTimerBased (
> +  IN VOID *CoreHandle
> +  );
> +
> +EFI_STATUS
> +EFIAPI
> +DwcXdciCoreConnect (
> +  IN VOID    *CoreHandle
> +  );
> +
> +EFI_STATUS
> +EFIAPI
> +DwcXdciCoreDisconnect (
> +  IN VOID *CoreHandle
> +  );
> +
> +EFI_STATUS
> +EFIAPI
> +DwcXdciCoreGetSpeed (
> +  IN VOID         *CoreHandle,
> +  IN USB_SPEED    *Speed
> +  );
> +
> +EFI_STATUS
> +EFIAPI
> +DwcXdciCoreSetAddress (
> +  IN VOID      *CoreHandle,
> +  IN UINT32    Address
> +  );
> +
> +EFI_STATUS
> +EFIAPI
> +DwcXdciCoreSetConfig (
> +  IN VOID      *CoreHandle,
> +  IN UINT32    ConfigNum
> +  );
> +
> +EFI_STATUS
> +EFIAPI
> +DwcXdciSetLinkState (
> +  IN VOID                        *CoreHandle,
> +  IN USB_DEVICE_SS_LINK_STATE    State
> +  );
> +
> +EFI_STATUS
> +EFIAPI
> +DwcXdciInitEp (
> +  IN VOID           *CoreHandle,
> +  IN USB_EP_INFO    *EpInfo
> +  );
> +
> +EFI_STATUS
> +EFIAPI
> +DwcXdciEpEnable (
> +  IN VOID           *CoreHandle,
> +  IN USB_EP_INFO    *EpInfo
> +  );
> +
> +EFI_STATUS
> +EFIAPI
> +DwcXdciEpDisable (
> +  IN VOID           *CoreHandle,
> +  IN USB_EP_INFO    *EpInfo
> +  );
> +
> +EFI_STATUS
> +EFIAPI
> +DwcXdciEpStall (
> +  IN VOID           *CoreHandle,
> +  IN USB_EP_INFO    *EpInfo
> +  );
> +
> +EFI_STATUS
> +EFIAPI
> +DwcXdciEpClearStall (
> +  IN VOID           *CoreHandle,
> +  IN USB_EP_INFO    *EpInfo
> +  );
> +
> +EFI_STATUS
> +EFIAPI
> +DwcXdciEpSetNrdy (
> +  IN VOID           *CoreHandle,
> +  IN USB_EP_INFO    *EpInfo
> +  );
> +
> +EFI_STATUS
> +EFIAPI
> +DwcXdciEp0ReceiveSetupPkt (
> +  IN VOID     *CoreHandle,
> +  IN UINT8    *Buffer
> +  );
> +
> +EFI_STATUS
> +EFIAPI
> +DwcXdciEp0ReceiveStatusPkt (
> +  IN VOID    *CoreHandle
> +  );
> +
> +EFI_STATUS
> +EFIAPI
> +DwcXdciEp0SendStatusPkt (
> +  IN VOID    *CoreHandle
> +  );
> +
> +EFI_STATUS
> +EFIAPI
> +DwcXdciEpTxData (
> +  IN VOID                *CoreHandle,
> +  IN USB_XFER_REQUEST    *XferReq
> +  );
> +
> +EFI_STATUS
> +EFIAPI
> +DwcXdciEpRxData(
> +  IN VOID                *CoreHandle,
> +  IN USB_XFER_REQUEST    *XferReq
> +  );
> +
> +EFI_STATUS
> +EFIAPI
> +DwcXdciEpCancelTransfer (
> +  IN VOID           *CoreHandle,
> +  IN USB_EP_INFO    *EpInfo
> +  );
> +
> +EFI_STATUS
> +usbProcessDeviceResetDet (
> +  IN XDCI_CORE_HANDLE    *CoreHandle
> +  );
> +
> +EFI_STATUS
> +usbProcessDeviceResetDone (
> +  IN XDCI_CORE_HANDLE    *CoreHandle
> +  );
> +
> +UINT32
> +UsbGetPhysicalEpNum (
> +  IN UINT32        EndpointNum,
> +  IN USB_EP_DIR    EndpointDir
> +  );
> +
> +UINT32
> +UsbRegRead (
> +  IN UINT32    Base,
> +  IN UINT32    Offset
> +  );
> +
> +VOID
> +UsbRegWrite (
> +  IN UINT32    Base,
> +  IN UINT32    Offset,
> +  IN UINT32    val
> +  );
> +
> +EFI_STATUS
> +UsbXdciCoreFlushEpFifo (
> +  IN VOID           *CoreHandle,
> +  IN USB_EP_INFO    *EpInfo
> +  );
> +#endif
> +
> diff --git a/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciDevice.c b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciDevice.c
> new file mode 100644
> index 0000000000..7c94de0a60
> --- /dev/null
> +++ b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciDevice.c
> @@ -0,0 +1,695 @@
> +/** @file
> +  Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR>
> +
> +  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.
> +
> +**/
> +
> +#include <Library/UsbDeviceLib.h>
> +#include "XdciCommon.h"
> +#include "XdciDevice.h"
> +#include "XdciInterface.h"
> +#include "UsbDeviceMode.h"
> +
> +/**
> +  This function is used to initialize the device controller
> +  @configParams: Parameters from app to configure the core
> +  @DevCoreHandle: Return parameter for upper layers to use
> +  for all HW-independent APIs
> +
> +**/
> +EFI_STATUS
> +UsbDeviceInit (
> +  IN USB_DEV_CONFIG_PARAMS    *ConfigParams,
> +  IN OUT VOID                 **DevCoreHandle
> +  )
> +{
> +  USB_DEV_CORE    *DevCorePtr;
> +  EFI_STATUS      Status = EFI_INVALID_PARAMETER;
> +
> +  DEBUG ((DEBUG_INFO, "Call UsbDeviceInit start\n"));
> +
> +  //
> +  // Allocate device handle
> +  //
> +  DevCorePtr = AllocateZeroPool (sizeof (USB_DEV_CORE));
> +  DEBUG ((DEBUG_INFO, "device handle = 0x%x\n", DevCorePtr));
> +
> +  if (DevCorePtr == NULL) {
> +    DEBUG ((DEBUG_INFO, "UsbDeviceInit. ERROR: Failed to allocate memory\n"));
> +    return EFI_OUT_OF_RESOURCES;
> +  }
> +
> +  DEBUG ((DEBUG_INFO, "call UsbDeviceGetCoreDriver, ID=%x, \n", ConfigParams->ControllerId));
> +
> +  //
> +  // Get the driver for this USB device core
> +  //
> +  DevCorePtr->CoreDriver = UsbDeviceGetCoreDriver(ConfigParams->ControllerId);
> +  if (DevCorePtr->CoreDriver != NULL) {
> +    DEBUG ((DEBUG_INFO, "call DevCoreInit\n"));
> +    Status = DevCorePtr->CoreDriver->DevCoreInit(
> +                                        ConfigParams,
> +                                        (VOID*)DevCorePtr,
> +                                        &DevCorePtr->ControllerHandle);
> +  } else {
> +    DEBUG ((DEBUG_INFO, "UsbDeviceInit. ERROR: Driver not found\n"));
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  *DevCoreHandle = (VOID *)DevCorePtr;
> +  return Status;
> +}
> +
> +/**
> +  This function is used to de-initialize the device controller
> +  @DevCoreHandle: Handle to HW-independent APIs for device
> +  controller
> +  @flags: Flags indicating what type of de-initialization is required
> +
> +**/
> +EFI_STATUS
> +UsbDeviceDeinit (
> +  IN VOID      *DevCoreHandle,
> +  IN UINT32    Flags
> +  )
> +{
> +  USB_DEV_CORE    *Core = (USB_DEV_CORE *)DevCoreHandle;
> +  EFI_STATUS      Status = EFI_DEVICE_ERROR;
> +
> +  if (Core == NULL) {
> +    DEBUG ((DEBUG_INFO, "UsbDeviceDeinit: ERROR: INVALID HANDLE\n"));
> +  } else {
> +    if (Core->CoreDriver != NULL) {
> +      Status = Core->CoreDriver->DevCoreDeinit(
> +                                    Core->ControllerHandle,
> +                                    Flags
> +                                    );
> +      FreePool(DevCoreHandle);
> +    } else {
> +      DEBUG ((DEBUG_INFO, "UsbDeviceDeinit: Driver not found\n"));
> +      Status = EFI_INVALID_PARAMETER;
> +    }
> +  }
> +
> +  return Status;
> +}
> +
> +/**
> +  This function is used to register callback function for
> +  specified event
> +  @DevCoreHandle: Handle to HW-independent APIs for device
> +  controller
> +  @event: Event for which callback is to be registered
> +  @callbackFn: Callback function to be called by the
> +  controller driver for above event after critical processing
> +
> +**/
> +EFI_STATUS
> +UsbDeviceRegisterCallback (
> +  IN VOID                      *DevCoreHandle,
> +  IN USB_DEVICE_EVENT_ID       EventId,
> +  IN USB_DEVICE_CALLBACK_FUNC  CallbackFunc
> +  )
> +{
> +  EFI_STATUS    Status = EFI_DEVICE_ERROR;
> +  USB_DEV_CORE  *core = (USB_DEV_CORE *)DevCoreHandle;
> +
> +  DEBUG ((DEBUG_INFO, "UsbDeviceRegisterCallback start\n"));
> +
> +  if (core == NULL) {
> +    DEBUG ((DEBUG_INFO, "UsbDeviceRegisterCallback: ERROR: INVALID HANDLE\n"));
> +  } else {
> +    if (core->CoreDriver != NULL) {
> +      DEBUG ((DEBUG_INFO, "Call DevCoreRegisterCallback\n"));
> +      Status = core->CoreDriver->DevCoreRegisterCallback (
> +                                    core->ControllerHandle,
> +                                    EventId,
> +                                    CallbackFunc
> +                                    );
> +    }
> +  }
> +
> +  return Status;
> +}
> +
> +/**
> +  This function is used to register callback function for
> +  specified event
> +  @DevCoreHandle: Handle to HW-independent APIs for device
> +  controller
> +  @eventId: Event for which callback is to be unregistered
> +
> +**/
> +EFI_STATUS
> +UsbDeviceUnregisterCallback (
> +  IN VOID                      *DevCoreHandle,
> +  IN USB_DEVICE_EVENT_ID       EventId
> +  )
> +{
> +  EFI_STATUS    Status = EFI_DEVICE_ERROR;
> +  USB_DEV_CORE  *core = (USB_DEV_CORE *)DevCoreHandle;
> +
> +  if (core == NULL) {
> +    DEBUG ((DEBUG_INFO, "UsbDeviceUnregisterCallback: ERROR: INVALID HANDLE\n"));
> +  } else {
> +    if (core->CoreDriver != NULL) {
> +      Status = core->CoreDriver->DevCoreUnregisterCallback(
> +                                    core->ControllerHandle,
> +                                    EventId
> +                                    );
> +    }
> +  }
> +
> +  return Status;
> +}
> +
> +/**
> +  This function is used to service interrupt events on device
> +  controller. Use this API in your OS/stack-specific ISR framework
> +  In polled mode scenario, invoke this API in a loop to service the
> +  events
> +  @DevCoreHandle: Handle to HW-independent APIs for device
> +  controller
> +
> +**/
> +EFI_STATUS
> +UsbDeviceIsrRoutine (
> +  IN VOID                      *DevCoreHandle
> +  )
> +{
> +  USB_DEV_CORE  *core = (USB_DEV_CORE *)DevCoreHandle;
> +  EFI_STATUS    Status = EFI_DEVICE_ERROR;
> +
> +  if (core == NULL) {
> +    DEBUG ((DEBUG_INFO, "UsbDeviceIsrRoutine: ERROR: INVALID HANDLE\n"));
> +  } else {
> +    if (core->CoreDriver != NULL) {
> +      Status = core->CoreDriver->DevCoreIsrRoutine (core->ControllerHandle);
> +    }
> +  }
> +
> +  return Status;
> +}
> +
> +
> +/**
> +  This function is used to service interrupt events on device
> +  controller. Use this API in your OS/stack-specific ISR framework
> +  In polled mode scenario, invoke this API in a loop to service the
> +  events
> +  @DevCoreHandle: Handle to HW-independent APIs for device
> +  controller
> +
> +**/
> +EFI_STATUS
> +UsbDeviceIsrRoutineTimerBased (
> +  IN VOID                      *DevCoreHandle
> +  )
> +{
> +  USB_DEV_CORE  *core = (USB_DEV_CORE *)DevCoreHandle;
> +  EFI_STATUS    Status = EFI_DEVICE_ERROR;
> +
> +  if (core == NULL) {
> +    DEBUG ((DEBUG_INFO, "UsbDeviceIsrRoutine: ERROR: INVALID HANDLE\n"));
> +  } else {
> +    if (core->CoreDriver != NULL) {
> +      Status = core->CoreDriver->DevCoreIsrRoutineTimerBased (core->ControllerHandle);
> +    }
> +  }
> +
> +  return Status;
> +}
> +
> +
> +/**
> +  This function is used to enable device controller to connect
> +  to USB host
> +  @DevCoreHandle: Handle to HW-independent APIs for device
> +  controller
> +
> +**/
> +EFI_STATUS
> +UsbXdciDeviceConnect (
> +  IN VOID                      *DevCoreHandle
> +  )
> +{
> +  USB_DEV_CORE  *core = (USB_DEV_CORE *)DevCoreHandle;
> +  EFI_STATUS    Status = EFI_DEVICE_ERROR;
> +
> +  if (core == NULL) {
> +    DEBUG ((DEBUG_INFO, "UsbXdciDeviceConnect: ERROR: INVALID HANDLE\n"));
> +  } else {
> +    DEBUG ((DEBUG_INFO, "UsbXdciDeviceConnect\n"));
> +    Status = core->CoreDriver->DevCoreConnect (core->ControllerHandle);
> +  }
> +
> +  return Status;
> +}
> +
> +/**
> +  This function is used to disconnect device controller
> +  from USB host
> +  @DevCoreHandle: Handle to HW-independent APIs for device
> +  controller
> +
> +**/
> +EFI_STATUS
> +UsbDeviceDisconnect (
> +  IN VOID                      *DevCoreHandle
> +  )
> +{
> +  USB_DEV_CORE  *core =(USB_DEV_CORE *)DevCoreHandle;
> +  EFI_STATUS    Status = EFI_DEVICE_ERROR;
> +
> +  if (core == NULL) {
> +    DEBUG ((DEBUG_INFO, "UsbDeviceDisconnect: ERROR: INVALID HANDLE\n"));
> +  } else {
> +    DEBUG ((DEBUG_INFO, "UsbDeviceDisconnect\n"));
> +    Status = core->CoreDriver->DevCoreDisconnect(core->ControllerHandle);
> +  }
> +
> +  return Status;
> +}
> +
> +/**
> +  This function is used to obtain USB bus Speed after bus reset complete
> +  @DevCoreHandle: Handle to HW-independent APIs for device
> +  controller
> +  @Speed: negotiated Speed
> +
> +**/
> +EFI_STATUS
> +UsbDeviceGetSpeed (
> +  IN VOID                      *DevCoreHandle,
> +  IN USB_SPEED                 *Speed
> +  )
> +{
> +  USB_DEV_CORE  *core = (USB_DEV_CORE *)DevCoreHandle;
> +  EFI_STATUS    Status = EFI_DEVICE_ERROR;
> +
> +  if (core == NULL) {
> +    DEBUG ((DEBUG_INFO, "UsbDeviceGetSpeed: ERROR: INVALID HANDLE\n"));
> +  } else {
> +    Status = core->CoreDriver->DevCoreGetSpeed(core->ControllerHandle, Speed);
> +  }
> +
> +  return Status;
> +}
> +
> +/**
> +  This function is used to set USB device address
> +  @DevCoreHandle: Handle to HW-independent APIs for device
> +  controller
> +  @address: USB device address to set
> +
> +**/
> +EFI_STATUS
> +UsbDeviceSetAddress (
> +  IN VOID                      *DevCoreHandle,
> +  IN UINT32                    Address
> +  )
> +{
> +  USB_DEV_CORE  *core = (USB_DEV_CORE *)DevCoreHandle;
> +  EFI_STATUS    Status = EFI_DEVICE_ERROR;
> +
> +  DEBUG ((DEBUG_INFO, "UsbDeviceSetAddress: enter......\n"));
> +  if (core == NULL) {
> +    DEBUG ((DEBUG_INFO, "UsbDeviceSetAddress: ERROR: INVALID HANDLE\n"));
> +  } else {
> +    Status = core->CoreDriver->DevCoreSetAddress(core->ControllerHandle, Address);
> +  }
> +  DEBUG ((DEBUG_INFO, "UsbDeviceSetAddress: exit......\n"));
> +
> +  return Status;
> +}
> +
> +/**
> +  This function is used to do device controller-specific processing
> +  of set configuration device framework request
> +  @DevCoreHandle: Handle to HW-independent APIs for device
> +  controller
> +  @ConfigNum: configuration number selected by USB host
> +
> +**/
> +EFI_STATUS
> +UsbDeviceSetConfiguration (
> +  IN VOID                      *DevCoreHandle,
> +  IN UINT32                    ConfigNum
> +  )
> +{
> +  USB_DEV_CORE  *core = (USB_DEV_CORE *)DevCoreHandle;
> +  EFI_STATUS    Status = EFI_DEVICE_ERROR;
> +
> +  if (core == NULL) {
> +    DEBUG ((DEBUG_INFO, "UsbDeviceSetConfiguration: ERROR: INVALID HANDLE\n"));
> +  } else {
> +    Status = core->CoreDriver->DevCoreSetConfig (core->ControllerHandle, ConfigNum);
> +  }
> +
> +  return Status;
> +}
> +
> +/**
> +  This function is used to set desired link state in device controller
> +  @DevCoreHandle: Handle to HW-independent APIs for device
> +  controller
> +  @state: Desired link state
> +
> +**/
> +EFI_STATUS
> +UsbDeviceSetLinkState (
> +  IN VOID                      *DevCoreHandle,
> +  IN USB_DEVICE_SS_LINK_STATE  State
> +  )
> +{
> +  USB_DEV_CORE  *core = (USB_DEV_CORE *)DevCoreHandle;
> +  EFI_STATUS    Status = EFI_DEVICE_ERROR;
> +
> +  if (core == NULL) {
> +    DEBUG ((DEBUG_INFO, "UsbDeviceSetLinkState: ERROR: INVALID HANDLE\n"));
> +  } else {
> +    Status = core->CoreDriver->DevCoreSetLinkState (core->ControllerHandle, State);
> +  }
> +
> +  return Status;
> +}
> +
> +/**
> +  This function is used to initialize non-EP0 endpoints
> +  @DevCoreHandle: Handle to HW-independent APIs for device
> +  controller
> +  @EpInfo: Endpoint information for EP to be initialized
> +
> +**/
> +EFI_STATUS
> +UsbDeviceInitEp (
> +  IN VOID                      *DevCoreHandle,
> +  IN USB_EP_INFO               *EpInfo
> +  )
> +{
> +  USB_DEV_CORE  *core = (USB_DEV_CORE *)DevCoreHandle;
> +  EFI_STATUS    Status = EFI_DEVICE_ERROR;
> +
> +  if (core == NULL) {
> +    DEBUG ((DEBUG_INFO, "UsbDeviceInitEp: ERROR: INVALID HANDLE\n"));
> +  } else {
> +    Status = core->CoreDriver->DevCoreInitEp (core->ControllerHandle, EpInfo);
> +  }
> +
> +  return Status;
> +}
> +
> +/**
> +  This function is used to enable an endpoint
> +  @DevCoreHandle: Handle to HW-independent APIs for device
> +  controller
> +  @EpInfo: Endpoint information for EP to be enabled
> +
> +**/
> +EFI_STATUS
> +UsbDeviceEpEnable (
> +  IN VOID                      *DevCoreHandle,
> +  IN USB_EP_INFO               *EpInfo
> +  )
> +{
> +  USB_DEV_CORE  *core = (USB_DEV_CORE *)DevCoreHandle;
> +  EFI_STATUS    Status = EFI_DEVICE_ERROR;
> +
> +  if (core == NULL) {
> +    DEBUG ((DEBUG_INFO, "UsbDeviceEpEnable: ERROR: INVALID HANDLE\n"));
> +  } else {
> +    Status = core->CoreDriver->DevCoreEpEnable (core->ControllerHandle, EpInfo);
> +  }
> +
> +  return Status;
> +}
> +
> +/**
> +  This function is used to disable an endpoint
> +  @DevCoreHandle: Handle to HW-independent APIs for device
> +  controller
> +  @EpInfo: Endpoint information for EP to be disabled
> +
> +**/
> +EFI_STATUS
> +UsbDeviceEpDisable (
> +  IN VOID                      *DevCoreHandle,
> +  IN USB_EP_INFO               *EpInfo
> +  )
> +{
> +  USB_DEV_CORE  *core = (USB_DEV_CORE *)DevCoreHandle;
> +  EFI_STATUS    Status = EFI_DEVICE_ERROR;
> +
> +  if (core == NULL) {
> +    DEBUG ((DEBUG_INFO, "UsbDeviceEpDisable ERROR: INVALID HANDLE\n"));
> +  } else {
> +    Status = core->CoreDriver->DevCoreEpDisable (core->ControllerHandle, EpInfo);
> +  }
> +
> +  return Status;
> +}
> +
> +/**
> +  This function is used to STALL an endpoint
> +  @DevCoreHandle: Handle to HW-independent APIs for device
> +  controller
> +  @EpInfo: Endpoint information for EP to be stalled
> +
> +**/
> +EFI_STATUS
> +UsbDeviceEpStall (
> +  IN VOID                      *DevCoreHandle,
> +  IN USB_EP_INFO               *EpInfo
> +  )
> +{
> +  USB_DEV_CORE  *core = (USB_DEV_CORE *)DevCoreHandle;
> +  EFI_STATUS    Status = EFI_DEVICE_ERROR;
> +
> +  if (core == NULL) {
> +    DEBUG ((DEBUG_INFO, "UsbDeviceEpStall ERROR: INVALID HANDLE\n"));
> +  } else {
> +    Status = core->CoreDriver->DevCoreEpStall (core->ControllerHandle, EpInfo);
> +  }
> +
> +  return Status;
> +}
> +
> +/**
> +  This function is used to clear STALL on an endpoint
> +  @DevCoreHandle: Handle to HW-independent APIs for device
> +  controller
> +  @EpInfo: Endpoint information for which STALL needs to be cleared
> +
> +**/
> +EFI_STATUS
> +UsbDeviceEpClearStall (
> +  IN VOID                      *DevCoreHandle,
> +  IN USB_EP_INFO               *EpInfo
> +  )
> +{
> +  USB_DEV_CORE  *core = (USB_DEV_CORE *)DevCoreHandle;
> +  EFI_STATUS    Status = EFI_DEVICE_ERROR;
> +
> +  if (core == NULL) {
> +    DEBUG ((DEBUG_INFO, "UsbDeviceEpClearStall ERROR: INVALID HANDLE\n"));
> +  } else {
> +    Status = core->CoreDriver->DevCoreEpClearStall (core->ControllerHandle, EpInfo);
> +  }
> +
> +  return Status;
> +}
> +
> +/**
> +  This function is used to set EP not ready state
> +  @DevCoreHandle: Handle to HW-independent APIs for device
> +  controller
> +  @EpInfo: Endpoint information for EP that needs to be
> +  set in not ready state
> +
> +**/
> +EFI_STATUS
> +UsbDeviceEpSetNrdy (
> +  IN VOID                      *DevCoreHandle,
> +  IN USB_EP_INFO               *EpInfo
> +  )
> +{
> +  USB_DEV_CORE  *core = (USB_DEV_CORE *)DevCoreHandle;
> +  EFI_STATUS    Status = EFI_DEVICE_ERROR;
> +
> +  if (core == NULL) {
> +    DEBUG ((DEBUG_INFO, "UsbDeviceEpSetNrdy ERROR: INVALID HANDLE\n"));
> +  } else {
> +    Status = core->CoreDriver->DevCoreEpSetNrdy (core->ControllerHandle, EpInfo);
> +  }
> +
> +  return Status;
> +}
> +
> +/**
> +  This function is used to queue request to receive SETUP packet
> +  @DevCoreHandle: Handle to HW-independent APIs for device
> +  controller
> +  @Buffer: Buffer (bus-width aligned) where SETUP packet
> +  needs to be received
> +
> +**/
> +EFI_STATUS
> +UsbDeviceEp0RxSetup (
> +  IN VOID                      *DevCoreHandle,
> +  IN UINT8                     *Buffer
> +  )
> +{
> +  USB_DEV_CORE  *core = (USB_DEV_CORE *)DevCoreHandle;
> +  EFI_STATUS    Status = EFI_DEVICE_ERROR;
> +
> +  if (core == NULL) {
> +    DEBUG ((DEBUG_INFO, "UsbDeviceEp0RxSetup ERROR: INVALID HANDLE\n"));
> +  } else {
> +    Status = core->CoreDriver->DevCoreEp0RxSetupPkt (core->ControllerHandle, Buffer);
> +  }
> +
> +  return Status;
> +}
> +
> +/**
> +  This function is used to queue request to receive status phase
> +  for control transfer on EP0
> +  @DevCoreHandle: Handle to HW-independent APIs for device
> +  controller
> +
> +**/
> +EFI_STATUS
> +UsbDeviceEp0RxStatus (
> +  IN VOID                      *DevCoreHandle
> +  )
> +{
> +  USB_DEV_CORE  *core = (USB_DEV_CORE *)DevCoreHandle;
> +  EFI_STATUS    Status = EFI_DEVICE_ERROR;
> +
> +  if (core == NULL) {
> +    DEBUG ((DEBUG_INFO, "UsbDeviceEp0RxStatus ERROR: INVALID HANDLE\n"));
> +  } else {
> +    Status = core->CoreDriver->DevCoreEp0RxStatusPkt (core->ControllerHandle);
> +  }
> +  return Status;
> +}
> +
> +/**
> +  This function is used to queue request to send status phase for
> +  control transfer on EP0
> +  @DevCoreHandle: Handle to HW-independent APIs for device
> +  controller
> +
> +**/
> +EFI_STATUS
> +UsbDeviceEp0TxStatus (
> +  IN VOID                      *DevCoreHandle
> +  )
> +{
> +  USB_DEV_CORE  *core = (USB_DEV_CORE *)DevCoreHandle;
> +  EFI_STATUS    Status = EFI_DEVICE_ERROR;
> +
> +  if (core == NULL) {
> +    DEBUG ((DEBUG_INFO, "UsbDeviceEp0TxStatus ERROR: INVALID HANDLE\n"));
> +  } else {
> +    Status = core->CoreDriver->DevCoreEp0TxStatusPkt (core->ControllerHandle);
> +  }
> +
> +  return Status;
> +}
> +
> +/**
> +  This function is used to queue a single request to transmit data on
> +  an endpoint. If more than one request need to be queued before
> +  previous requests complete then a request queue needs to be
> +  implemented in upper layers. This API should be not be invoked until
> +  current request completes.
> +  Callback for transfer completion is invoked when requested transfer length
> +  is reached or if a short packet is received
> +  @DevCoreHandle: Handle to HW-independent APIs for device
> +  controller
> +  @XferReq: Address to transfer request describing this transfer
> +
> +**/
> +EFI_STATUS
> +UsbXdciDeviceEpTxData (
> +  IN VOID                      *DevCoreHandle,
> +  IN USB_XFER_REQUEST          *XferReq
> +  )
> +{
> +  USB_DEV_CORE  *core = (USB_DEV_CORE *)DevCoreHandle;
> +  EFI_STATUS    Status = EFI_DEVICE_ERROR;
> +
> +  if (core == NULL) {
> +    DEBUG ((DEBUG_INFO, "UsbXdciDeviceEpTxData ERROR: INVALID HANDLE\n"));
> +  } else {
> +    Status = core->CoreDriver->DevCoreEpTxData (core->ControllerHandle, XferReq);
> +  }
> +
> +  return Status;
> +}
> +
> +/**
> +  This function is used to queue a single request to receive data on
> +  an endpoint. If more than one request need to be queued before
> +  previous requests complete then a request queue needs to be implemented
> +  in upper layers. This API should be not be invoked until current request
> +  completes.
> +  Callback for transfer completion is invoked when requested transfer length
> +  is reached or if a short packet is received
> +  @DevCoreHandle: Handle to HW-independent APIs for device
> +  controller
> +  @XferReq: Address to transfer request describing this transfer
> +
> +**/
> +EFI_STATUS
> +UsbXdciDeviceEpRxData (
> +  IN VOID                      *DevCoreHandle,
> +  IN USB_XFER_REQUEST          *XferReq
> +  )
> +{
> +  USB_DEV_CORE  *core = (USB_DEV_CORE *)DevCoreHandle;
> +  EFI_STATUS    Status = EFI_DEVICE_ERROR;
> +
> +  if (core == NULL) {
> +    DEBUG ((DEBUG_INFO, "UsbXdciDeviceEpRxData ERROR: INVALID HANDLE\n"));
> +  } else {
> +    Status = core->CoreDriver->DevCoreEpRxData (core->ControllerHandle, XferReq);
> +  }
> +
> +  return Status;
> +}
> +
> +/**
> +  This function is used to cancel a transfer request that was
> +  previously queued on an endpoint
> +  @DevCoreHandle: Handle to HW-independent APIs for device
> +  controller
> +  @EpInfo: Endpoint info where transfer needs to be cancelled
> +
> +**/
> +EFI_STATUS
> +UsbDeviceEpCancelTransfer (
> +  IN VOID                      *DevCoreHandle,
> +  IN USB_EP_INFO               *EpInfo
> +  )
> +{
> +  USB_DEV_CORE  *core = (USB_DEV_CORE *)DevCoreHandle;
> +  EFI_STATUS    Status = EFI_DEVICE_ERROR;
> +
> +  if (core == NULL) {
> +    DEBUG ((DEBUG_INFO, "UsbDeviceEpCancelTransfer ERROR: INVALID HANDLE\n"));
> +  } else {
> +    Status = core->CoreDriver->DevCoreEpCancelTransfer (core->ControllerHandle, EpInfo);
> +  }
> +
> +  return Status;
> +}
> +
> diff --git a/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciDevice.h b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciDevice.h
> new file mode 100644
> index 0000000000..a10ec61732
> --- /dev/null
> +++ b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciDevice.h
> @@ -0,0 +1,184 @@
> +/** @file
> +  Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR>
> +
> +  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.
> +
> +**/
> +
> +#ifndef _USB_DEVICE_H_
> +#define _USB_DEVICE_H_
> +
> +//
> +// @USB_DEV_CONFIG_PARAMS: Struct to be filled in with configuration
> +// parameters and passed to the init routine for device controller
> +//
> +typedef struct {
> +  USB_CONTROLLER_ID  ControllerId; // Controller ID of the core
> +  UINT32             BaseAddress;  // Base address of the controller registers and on-chip memory
> +  UINT32             Flags;        // Initialization flags
> +  USB_SPEED          Speed;        // Desired USB bus Speed
> +  USB_ROLE           Role;         // Default USB role
> +} USB_DEV_CONFIG_PARAMS;
> +
> +//
> +// @USB_DEV_CORE: Struct used as a handle for all
> +// hardware-independent APIs
> +//
> +typedef struct {
> +  const struct UsbDeviceCoreDriver *CoreDriver;
> +  VOID                                *ControllerHandle;
> +} USB_DEV_CORE;
> +
> +typedef
> +EFI_STATUS
> +(EFIAPI *USB_DEVICE_CALLBACK_FUNC) (
> +  IN USB_DEVICE_CALLBACK_PARAM  *Param
> +  );
> +
> +EFI_STATUS
> +UsbDeviceInit (
> +  IN USB_DEV_CONFIG_PARAMS    *ConfigParams,
> +  IN OUT VOID                 **DevCoreHandle
> +  );
> +
> +EFI_STATUS
> +UsbDeviceDeinit (
> +  IN VOID                      *DevCoreHandle,
> +  IN UINT32                    Flags
> +  );
> +
> +EFI_STATUS
> +UsbDeviceRegisterCallback (
> +  IN VOID                      *DevCoreHandle,
> +  IN USB_DEVICE_EVENT_ID       EventId,
> +  IN USB_DEVICE_CALLBACK_FUNC  CallbackFunc
> +  );
> +
> +EFI_STATUS
> +UsbDeviceUnregisterCallback (
> +  IN VOID                      *DevCoreHandle,
> +  IN USB_DEVICE_EVENT_ID       EventId
> +  );
> +
> +EFI_STATUS
> +UsbDeviceIsrRoutine (
> +  IN VOID                      *DevCoreHandle
> +  );
> +
> +EFI_STATUS
> +UsbDeviceIsrRoutineTimerBased (
> +  IN VOID                      *DevCoreHandle
> +  );
> +
> +EFI_STATUS
> +UsbXdciDeviceConnect (
> +  IN VOID                      *DevCoreHandle
> +  );
> +
> +EFI_STATUS
> +UsbDeviceDisconnect (
> +  IN VOID                      *DevCoreHandle
> +  );
> +
> +EFI_STATUS
> +UsbDeviceGetSpeed (
> +  IN VOID                      *DevCoreHandle,
> +  IN USB_SPEED                 *Speed
> +  );
> +
> +EFI_STATUS
> +UsbDeviceSetLinkState (
> +  IN VOID                      *DevCoreHandle,
> +  IN USB_DEVICE_SS_LINK_STATE  State
> +  );
> +
> +EFI_STATUS
> +UsbDeviceSetAddress (
> +  IN VOID                      *DevCoreHandle,
> +  IN UINT32                    Address
> +  );
> +
> +EFI_STATUS
> +UsbDeviceSetConfiguration (
> +  IN VOID                      *DevCoreHandle,
> +  IN UINT32                    ConfigNum
> +  );
> +
> +EFI_STATUS
> +UsbDeviceInitEp (
> +  IN VOID                      *DevCoreHandle,
> +  IN USB_EP_INFO               *EpInfo
> +  );
> +
> +EFI_STATUS
> +UsbDeviceEpEnable (
> +  IN VOID                      *DevCoreHandle,
> +  IN USB_EP_INFO               *EpInfo
> +  );
> +
> +EFI_STATUS
> +UsbDeviceEpDisable (
> +  IN VOID                      *DevCoreHandle,
> +  IN USB_EP_INFO               *EpInfo
> +  );
> +
> +EFI_STATUS
> +UsbDeviceEpStall (
> +  IN VOID                      *DevCoreHandle,
> +  IN USB_EP_INFO               *EpInfo
> +  );
> +
> +EFI_STATUS
> +UsbDeviceEpClearStall (
> +  IN VOID                      *DevCoreHandle,
> +  IN USB_EP_INFO               *EpInfo
> +  );
> +
> +EFI_STATUS
> +UsbDeviceEpSetNrdy (
> +  IN VOID                      *DevCoreHandle,
> +  IN USB_EP_INFO               *EpInfo
> +  );
> +
> +EFI_STATUS
> +UsbDeviceEp0RxSetup (
> +  IN VOID                      *DevCoreHandle,
> +  IN UINT8                     *Buffer
> +  );
> +
> +EFI_STATUS
> +UsbDeviceEp0RxStatus (
> +  IN VOID                      *DevCoreHandle
> +  );
> +
> +EFI_STATUS
> +UsbDeviceEp0TxStatus (
> +  IN VOID                      *DevCoreHandle
> +  );
> +
> +EFI_STATUS
> +UsbXdciDeviceEpTxData (
> +  IN VOID                      *DevCoreHandle,
> +  IN USB_XFER_REQUEST          *XferReq
> +  );
> +
> +EFI_STATUS
> +UsbXdciDeviceEpRxData (
> +  IN VOID                      *DevCoreHandle,
> +  IN USB_XFER_REQUEST          *XferReq
> +  );
> +
> +EFI_STATUS
> +UsbDeviceEpCancelTransfer (
> +  IN VOID                      *DevCoreHandle,
> +  IN USB_EP_INFO               *EpInfo
> +  );
> +
> +#endif
> +
> diff --git a/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciInterface.h b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciInterface.h
> new file mode 100644
> index 0000000000..75ce0ecab3
> --- /dev/null
> +++ b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciInterface.h
> @@ -0,0 +1,241 @@
> +/** @file
> +  Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR>
> +
> +  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.
> +
> +**/
> +
> +#ifndef _USB_DCD_IF_H_
> +#define _USB_DCD_IF_H_
> +
> +/* Core driver for device controller
> + * @DevCoreInit: Intializes device controller
> + * @DevCoreDeinit: De-initializes device controller
> + * @DevCoreRegisterCallback: Registers callback function for
> + * an event to be called by the controller driver
> + * @DevCoreUnregisterCallback: Unregisters callback function
> + * for an event
> + * @DevCoreIsrRoutine: core interrupt service routine for
> + * device controller to be used by OS/stack-i/f layer
> + * @DevCoreConnect: Enable device controller to connect to USB host
> + * @DevCoreDisconnect: Soft disconnect device controller from
> + * USB host
> + * @DevCoreGetSpeed: Get USB bus Speed on which device controller
> + * is attached
> + * @DevCoreSetAddress: Set USB device address in device controller
> + * @DevCoreSetConfig: Set configuration number for device controller
> + * @DevCoreSetLinkState: Set link state for device controller
> + * @DevCoreInitEp: Initialize non-EP0 endpoint
> + * @DevCoreEpEnable: Enable endpoint
> + * @DevCoreEpDisable: Disable endpoint
> + * @DevCoreEpStall: Stall/Halt endpoint
> + * @DevCoreEpClearStall: Clear Stall/Halt on endpoint
> + * @DevCoreEpSetNrdy: Set endpoint to not ready state
> + * @DevCoreEp0RxSetupPkt: Receive SETUP packet on EP0
> + * @DevCoreEp0RxStatusPkt: Receive status packet on EP0
> + * @DevCoreEp0TxStatusPkt: Transmit status packet from EP0
> + * @DevCoreEpTxData: Transmit data from EP
> + * @DevCoreEpRxData: Received data on EP
> + * @DevCoreEpCancelTransfer: Cancel transfer on EP
> + */
> +
> +typedef
> +EFI_STATUS
> +(EFIAPI *DEV_CORE_INIT) (
> +  IN USB_DEV_CONFIG_PARAMS     *ConfigParams,
> +  IN VOID                      *ParentHandle,
> +  IN VOID                      **CoreHandle
> +  );
> +
> +typedef
> +EFI_STATUS
> +(EFIAPI *DEV_CORE_DEINIT) (
> +  IN VOID                      *CoreHandle,
> +  IN UINT32                    Flags
> +  );
> +
> +typedef
> +EFI_STATUS
> +(EFIAPI *DEV_CORE_REG_CALLBACK) (
> +  IN VOID                      *CoreHandle,
> +  IN USB_DEVICE_EVENT_ID       Event,
> +  IN USB_DEVICE_CALLBACK_FUNC  CallbackFn
> +  );
> +
> +typedef
> +EFI_STATUS
> +(EFIAPI *DEV_CORE_UNREG_CALLBACK) (
> +  IN VOID                      *CoreHandle,
> +  IN USB_DEVICE_EVENT_ID       Event
> +  );
> +
> +typedef
> +EFI_STATUS
> +(EFIAPI *DEV_CORE_ISR_ROUTINE) (
> +  IN VOID                      *CoreHandle
> +  );
> +
> +typedef
> +EFI_STATUS
> +(EFIAPI *DEV_CORE_CONNECT) (
> +  IN VOID                      *CoreHandle
> +  );
> +
> +typedef
> +EFI_STATUS
> +(EFIAPI *DEV_CORE_DISCONNECT) (
> +  IN VOID                      *CoreHandle
> +  );
> +
> +typedef
> +EFI_STATUS
> +(EFIAPI *DEV_CORE_GET_SPEED) (
> +  IN VOID                      *CoreHandle,
> +  IN USB_SPEED                 *Speed
> +  );
> +
> +typedef
> +EFI_STATUS
> +(EFIAPI *DEV_CORE_SET_ADDRESS) (
> +  IN VOID                      *CoreHandle,
> +  IN UINT32                    Address
> +  );
> +
> +typedef
> +EFI_STATUS
> +(EFIAPI *DEV_CORE_SET_CONFIG) (
> +  IN VOID                      *CoreHandle,
> +  IN UINT32                    ConfigNum
> +  );
> +
> +typedef
> +EFI_STATUS
> +(EFIAPI *DEV_CORE_SET_LINK_STATE) (
> +  IN VOID                      *CoreHandle,
> +  IN USB_DEVICE_SS_LINK_STATE  State
> +  );
> +
> +typedef
> +EFI_STATUS
> +(EFIAPI *DEV_CORE_INIT_EP) (
> +  IN VOID                      *CoreHandle,
> +  IN USB_EP_INFO               *EpInfo
> +  );
> +
> +typedef
> +EFI_STATUS
> +(EFIAPI *DEV_CORE_EP_ENABLE) (
> +  IN VOID                      *CoreHandle,
> +  IN USB_EP_INFO               *EpInfo
> +  );
> +
> +typedef
> +EFI_STATUS
> +(EFIAPI *DEV_CORE_EP_DISABLE) (
> +  IN VOID                      *CoreHandle,
> +  IN USB_EP_INFO               *EpInfo
> +  );
> +
> +typedef
> +EFI_STATUS
> +(EFIAPI *DEV_CORE_EP_STALL) (
> +  IN VOID                      *CoreHandle,
> +  IN USB_EP_INFO               *EpInfo
> +  );
> +
> +typedef
> +EFI_STATUS
> +(EFIAPI *DEV_CORE_EP_CLEAR_STALL) (
> +  IN VOID                      *CoreHandle,
> +  IN USB_EP_INFO               *EpInfo
> +  );
> +
> +typedef
> +EFI_STATUS
> +(EFIAPI *DEV_CORE_EP_SET_NRDY) (
> +  IN VOID                      *CoreHandle,
> +  IN USB_EP_INFO               *EpInfo
> +  );
> +
> +typedef
> +EFI_STATUS
> +(EFIAPI *DEV_CORE_EP0_RX_SETUP_PKT) (
> +  IN VOID                      *CoreHandle,
> +  IN UINT8                     *Buffer
> +  );
> +
> +typedef
> +EFI_STATUS
> +(EFIAPI *DEV_CORE_EP0_RX_STATUS_PKT) (
> +  IN VOID                      *CoreHandle
> +  );
> +
> +typedef
> +EFI_STATUS
> +(EFIAPI *DEV_CORE_EP0_TX_STATUS_PKT) (
> +  IN VOID                      *CoreHandle
> +  );
> +
> +typedef
> +EFI_STATUS
> +(EFIAPI *DEV_CORE_EP_TX_DATA) (
> +  IN VOID                      *CoreHandle,
> +  IN USB_XFER_REQUEST          *XferHandle
> +  );
> +
> +typedef
> +EFI_STATUS
> +(EFIAPI *DEV_CORE_EP_RX_DATA) (
> +  IN VOID                      *CoreHandle,
> +  IN USB_XFER_REQUEST          *XferHandle
> +  );
> +
> +typedef
> +EFI_STATUS
> +(EFIAPI *DEV_CORE_EP_CANCEL_TRANSFER) (
> +  IN VOID                      *CoreHandle,
> +  IN USB_EP_INFO               *EpInfo
> +  );
> +
> +struct UsbDeviceCoreDriver {
> +  DEV_CORE_INIT                 DevCoreInit;
> +  DEV_CORE_DEINIT               DevCoreDeinit;
> +  DEV_CORE_REG_CALLBACK         DevCoreRegisterCallback;
> +  DEV_CORE_UNREG_CALLBACK       DevCoreUnregisterCallback;
> +  DEV_CORE_ISR_ROUTINE          DevCoreIsrRoutine;
> +  DEV_CORE_ISR_ROUTINE          DevCoreIsrRoutineTimerBased;
> +  DEV_CORE_CONNECT              DevCoreConnect;
> +  DEV_CORE_DISCONNECT           DevCoreDisconnect;
> +  DEV_CORE_GET_SPEED            DevCoreGetSpeed;
> +  DEV_CORE_SET_ADDRESS          DevCoreSetAddress;
> +  DEV_CORE_SET_CONFIG           DevCoreSetConfig;
> +  DEV_CORE_SET_LINK_STATE       DevCoreSetLinkState;
> +  DEV_CORE_INIT_EP              DevCoreInitEp;
> +  DEV_CORE_EP_ENABLE            DevCoreEpEnable;
> +  DEV_CORE_EP_DISABLE           DevCoreEpDisable;
> +  DEV_CORE_EP_STALL             DevCoreEpStall;
> +  DEV_CORE_EP_CLEAR_STALL       DevCoreEpClearStall;
> +  DEV_CORE_EP_SET_NRDY          DevCoreEpSetNrdy;
> +  DEV_CORE_EP0_RX_SETUP_PKT     DevCoreEp0RxSetupPkt;
> +  DEV_CORE_EP0_RX_STATUS_PKT    DevCoreEp0RxStatusPkt;
> +  DEV_CORE_EP0_TX_STATUS_PKT    DevCoreEp0TxStatusPkt;
> +  DEV_CORE_EP_TX_DATA           DevCoreEpTxData;
> +  DEV_CORE_EP_RX_DATA           DevCoreEpRxData;
> +  DEV_CORE_EP_CANCEL_TRANSFER   DevCoreEpCancelTransfer;
> +};
> +
> +//
> +// This API is used to obtain the driver handle for HW-independent API
> +// @id: The ID of the core for which this driver is requested
> +//
> +const struct UsbDeviceCoreDriver *UsbDeviceGetCoreDriver(
> +  USB_CONTROLLER_ID id);
> +
> +#endif
> +
> diff --git a/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciTable.c b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciTable.c
> new file mode 100644
> index 0000000000..97a97db3db
> --- /dev/null
> +++ b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciTable.c
> @@ -0,0 +1,55 @@
> +/** @file
> +  Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR>
> +
> +  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.
> +
> +**/
> +
> +#include <Library/UsbDeviceLib.h>
> +#include "XdciCommon.h"
> +#include "XdciDevice.h"
> +#include "XdciInterface.h"
> +#include "XdciDWC.h"
> +#include "UsbDeviceMode.h"
> +
> +static const struct UsbDeviceCoreDriver CoreDriverTbl[USB_CORE_ID_MAX] = {
> +  DwcXdciCoreInit,
> +  DwcXdciCoreDeinit,
> +  DwcXdciCoreRegisterCallback,
> +  DwcXdciCoreUnregisterCallback,
> +  DwcXdciCoreIsrRoutine,
> +  DwcXdciCoreIsrRoutineTimerBased,
> +  DwcXdciCoreConnect,
> +  DwcXdciCoreDisconnect,
> +  DwcXdciCoreGetSpeed,
> +  DwcXdciCoreSetAddress,
> +  DwcXdciCoreSetConfig,
> +  DwcXdciSetLinkState,
> +  DwcXdciInitEp,
> +  DwcXdciEpEnable,
> +  DwcXdciEpDisable,
> +  DwcXdciEpStall,
> +  DwcXdciEpClearStall,
> +  DwcXdciEpSetNrdy,
> +  DwcXdciEp0ReceiveSetupPkt,
> +  DwcXdciEp0ReceiveStatusPkt,
> +  DwcXdciEp0SendStatusPkt,
> +  DwcXdciEpTxData,
> +  DwcXdciEpRxData,
> +  DwcXdciEpCancelTransfer
> +};
> +
> +const struct UsbDeviceCoreDriver *UsbDeviceGetCoreDriver(USB_CONTROLLER_ID id)
> +{
> +  if (id >= USB_CORE_ID_MAX)
> +    return NULL;
> +
> +  return &CoreDriverTbl[id];
> +}
> +
> diff --git a/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciUtility.c b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciUtility.c
> new file mode 100644
> index 0000000000..2e02475cd0
> --- /dev/null
> +++ b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciUtility.c
> @@ -0,0 +1,148 @@
> +/** @file
> +  Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR>
> +
> +  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.
> +
> +**/
> +
> +#include "XdciUtility.h"
> +
> +VOID
> +PrintDeviceDescriptor (
> +  IN USB_DEVICE_DESCRIPTOR    *DevDesc
> +  )
> +{
> +  DEBUG ((DEBUG_INFO, "--- Device Descriptor ---\n"));
> +  DEBUG ((DEBUG_INFO, "Length            : 0x%x\n", DevDesc->Length));
> +  DEBUG ((DEBUG_INFO, "DescriptorType    : 0x%x\n", DevDesc->DescriptorType));
> +  DEBUG ((DEBUG_INFO, "BcdUSB            : 0x%x\n", DevDesc->BcdUSB));
> +  DEBUG ((DEBUG_INFO, "DeviceClass       : 0x%x\n", DevDesc->DeviceClass));
> +  DEBUG ((DEBUG_INFO, "DeviceSubClass    : 0x%x\n", DevDesc->DeviceSubClass));
> +  DEBUG ((DEBUG_INFO, "DeviceProtocol    : 0x%x\n", DevDesc->DeviceProtocol));
> +  DEBUG ((DEBUG_INFO, "MaxPacketSize0    : 0x%x\n", DevDesc->MaxPacketSize0));
> +  DEBUG ((DEBUG_INFO, "IdVendor          : 0x%x\n", DevDesc->IdVendor));
> +  DEBUG ((DEBUG_INFO, "IdProduct         : 0x%x\n", DevDesc->IdProduct));
> +  DEBUG ((DEBUG_INFO, "BcdDevice         : 0x%x\n", DevDesc->BcdDevice));
> +  DEBUG ((DEBUG_INFO, "StrManufacturer   : 0x%x\n", DevDesc->StrManufacturer));
> +  DEBUG ((DEBUG_INFO, "StrProduct        : 0x%x\n", DevDesc->StrProduct));
> +  DEBUG ((DEBUG_INFO, "StrSerialNumber   : 0x%x\n", DevDesc->StrSerialNumber));
> +  DEBUG ((DEBUG_INFO, "NumConfigurations : 0x%x\n", DevDesc->NumConfigurations));
> +  DEBUG ((DEBUG_INFO, "\n"));
> +}
> +
> +VOID
> +PrintConfigDescriptor (
> +  IN EFI_USB_CONFIG_DESCRIPTOR    *ConfigDesc
> +  )
> +{
> +  DEBUG ((DEBUG_INFO, "--- Configuration Descriptor ---\n"));
> +  DEBUG ((DEBUG_INFO, "Length             : 0x%x\n", ConfigDesc->Length));
> +  DEBUG ((DEBUG_INFO, "DescriptorType     : 0x%x\n", ConfigDesc->DescriptorType));
> +  DEBUG ((DEBUG_INFO, "TotalLength        : 0x%x\n", ConfigDesc->TotalLength));
> +  DEBUG ((DEBUG_INFO, "NumInterfaces      : 0x%x\n", ConfigDesc->NumInterfaces));
> +  DEBUG ((DEBUG_INFO, "ConfigurationValue : 0x%x\n", ConfigDesc->ConfigurationValue));
> +  DEBUG ((DEBUG_INFO, "Configuration      : 0x%x\n", ConfigDesc->Configuration));
> +  DEBUG ((DEBUG_INFO, "Attributes         : 0x%x\n", ConfigDesc->Attributes));
> +  DEBUG ((DEBUG_INFO, "MaxPower           : 0x%x\n", ConfigDesc->MaxPower));
> +  DEBUG ((DEBUG_INFO, "\n"));
> +}
> +
> +VOID
> +PrintInterfaceDescriptor (
> +  IN EFI_USB_INTERFACE_DESCRIPTOR    *IfDesc
> +  )
> +{
> +  DEBUG ((DEBUG_INFO, "--- Interface Descriptor ---\n"));
> +  DEBUG ((DEBUG_INFO, "Length            : 0x%x\n", IfDesc->Length));
> +  DEBUG ((DEBUG_INFO, "DescriptorType    : 0x%x\n", IfDesc->DescriptorType));
> +  DEBUG ((DEBUG_INFO, "InterfaceNumber   : 0x%x\n", IfDesc->InterfaceNumber));
> +  DEBUG ((DEBUG_INFO, "AlternateSetting  : 0x%x\n", IfDesc->AlternateSetting));
> +  DEBUG ((DEBUG_INFO, "NumEndpoints      : 0x%x\n", IfDesc->NumEndpoints));
> +  DEBUG ((DEBUG_INFO, "InterfaceClass    : 0x%x\n", IfDesc->InterfaceClass));
> +  DEBUG ((DEBUG_INFO, "InterfaceSubClass : 0x%x\n", IfDesc->InterfaceSubClass));
> +  DEBUG ((DEBUG_INFO, "InterfaceProtocol : 0x%x\n", IfDesc->InterfaceProtocol));
> +  DEBUG ((DEBUG_INFO, "Interface         : 0x%x\n", IfDesc->Interface));
> +  DEBUG ((DEBUG_INFO, "\n"));
> +}
> +
> +VOID
> +PrintEpDescriptor (
> +  IN EFI_USB_ENDPOINT_DESCRIPTOR    *EpDesc
> +  )
> +{
> +  DEBUG ((DEBUG_INFO, "--- Endpoint Descriptor ---\n"));
> +  DEBUG ((DEBUG_INFO, "Length          : 0x%x\n", EpDesc->Length));
> +  DEBUG ((DEBUG_INFO, "DescriptorType  : 0x%x\n", EpDesc->DescriptorType));
> +  DEBUG ((DEBUG_INFO, "EndpointAddress : 0x%x\n", EpDesc->EndpointAddress));
> +  DEBUG ((DEBUG_INFO, "Attributes      : 0x%x\n", EpDesc->Attributes));
> +  DEBUG ((DEBUG_INFO, "MaxPacketSize   : 0x%x\n", EpDesc->MaxPacketSize));
> +  DEBUG ((DEBUG_INFO, "Interval        : 0x%x\n", EpDesc->Interval));
> +  DEBUG ((DEBUG_INFO, "\n"));
> +}
> +
> +VOID
> +PrintEpCompDescriptor (
> +  IN EFI_USB_ENDPOINT_COMPANION_DESCRIPTOR    *EpDesc
> +  )
> +{
> +  DEBUG ((DEBUG_INFO, "--- Endpoint Companion Descriptor ---\n"));
> +  DEBUG ((DEBUG_INFO, "Length           : 0x%x\n", EpDesc->Length));
> +  DEBUG ((DEBUG_INFO, "DescriptorType   : 0x%x\n", EpDesc->DescriptorType));
> +  DEBUG ((DEBUG_INFO, "MaxBurst         : 0x%x\n", EpDesc->MaxBurst));
> +  DEBUG ((DEBUG_INFO, "Attributes       : 0x%x\n", EpDesc->Attributes));
> +  DEBUG ((DEBUG_INFO, "BytesPerInterval : 0x%x\n", EpDesc->BytesPerInterval));
> +  DEBUG ((DEBUG_INFO, "\n"));
> +}
> +
> +VOID
> +PrintStringDescriptor (
> +  IN USB_STRING_DESCRIPTOR    *StrDesc
> +  )
> +{
> +  UINT16 StrLen = 0;
> +
> +  if (StrDesc->Length > 2) {
> +    StrLen = ((StrDesc->Length - 2) >> 1);
> +    DEBUG ((DEBUG_INFO, "--- String Descriptor ---\n"));
> +    DEBUG ((DEBUG_INFO, "Length         : 0x%x\n", StrDesc->Length));
> +    DEBUG ((DEBUG_INFO, "DescriptorType : 0x%x\n", StrDesc->DescriptorType));
> +    DEBUG ((DEBUG_INFO, "String         : %s\n",   StrDesc->LangID));
> +  }
> +  DEBUG ((DEBUG_INFO, "\n"));
> +}
> +
> +VOID
> +PrintDeviceRequest (
> +  IN EFI_USB_DEVICE_REQUEST    *DevReq
> +  )
> +{
> +  DEBUG ((DEBUG_INFO, "--- Device Request ---\n"));
> +  DEBUG ((DEBUG_INFO, "RequestType : 0x%x\n", DevReq->RequestType));
> +  DEBUG ((DEBUG_INFO, "Request     : 0x%x\n", DevReq->Request));
> +  DEBUG ((DEBUG_INFO, "Value       : 0x%x\n", DevReq->Value));
> +  DEBUG ((DEBUG_INFO, "Index       : 0x%x\n", DevReq->Index));
> +  DEBUG ((DEBUG_INFO, "Length      : 0x%x\n", DevReq->Length));
> +  DEBUG ((DEBUG_INFO, "\n"));
> +}
> +
> +#ifdef SUPPORT_SUPER_SPEED
> +VOID
> +PrintBOSDescriptor (
> +  IN EFI_USB_BOS_DESCRIPTOR    *BosDesc
> +  )
> +{
> +  DEBUG ((DEBUG_INFO, "--- BOS Descriptor ---\n"));
> +  DEBUG ((DEBUG_INFO, "Length           : 0x%x\n", BosDesc->Length));
> +  DEBUG ((DEBUG_INFO, "DescriptorType   : 0x%x\n", BosDesc->DescriptorType));
> +  DEBUG ((DEBUG_INFO, "TotalLength      : 0x%x\n", BosDesc->TotalLength));
> +  DEBUG ((DEBUG_INFO, "NumDeviceCaps    : 0x%x\n", BosDesc->NumDeviceCaps));
> +  DEBUG ((DEBUG_INFO, "\n"));
> +}
> +#endif
> +
> diff --git a/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciUtility.h b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciUtility.h
> new file mode 100644
> index 0000000000..e3d004e579
> --- /dev/null
> +++ b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciUtility.h
> @@ -0,0 +1,62 @@
> +/** @file
> +  Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR>
> +
> +  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.
> +
> +**/
> +
> +#ifndef _XDCI_UTILITY_H_
> +#define _XDCI_UTILITY_H_
> +
> +#include <Library/UsbDeviceLib.h>
> +
> +VOID
> +PrintDeviceDescriptor (
> +  IN USB_DEVICE_DESCRIPTOR    *DevDesc
> +  );
> +
> +VOID
> +PrintConfigDescriptor (
> +  IN EFI_USB_CONFIG_DESCRIPTOR    *ConfigDesc
> +  );
> +
> +VOID
> +PrintInterfaceDescriptor (
> +  IN EFI_USB_INTERFACE_DESCRIPTOR    *IfDesc
> +  );
> +
> +VOID
> +PrintEpDescriptor (
> +  IN EFI_USB_ENDPOINT_DESCRIPTOR    *EpDesc
> +  );
> +
> +VOID
> +PrintEpCompDescriptor (
> +  IN EFI_USB_ENDPOINT_COMPANION_DESCRIPTOR    *EpDesc
> +  );
> +
> +VOID
> +PrintStringDescriptor (
> +  IN USB_STRING_DESCRIPTOR    *StrDesc
> +  );
> +
> +VOID
> +PrintDeviceRequest (
> +  IN EFI_USB_DEVICE_REQUEST    *DevReq
> +  );
> +
> +#ifdef SUPPORT_SUPER_SPEED
> +VOID
> +PrintBOSDescriptor (
> +  IN EFI_USB_BOS_DESCRIPTOR    *BosDesc
> +  );
> +#endif
> +
> +#endif
> +
> diff --git a/Silicon/Synopsys/DesignWare/Include/Library/UsbDeviceLib.h b/Silicon/Synopsys/DesignWare/Include/Library/UsbDeviceLib.h
> new file mode 100644
> index 0000000000..fe5f3bcd03
> --- /dev/null
> +++ b/Silicon/Synopsys/DesignWare/Include/Library/UsbDeviceLib.h
> @@ -0,0 +1,323 @@
> +/** @file
> +  Copyright (c) 2009 - 2016, Intel Corporation. All rights reserved.<BR>
> +
> +  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.
> +
> +**/
> +
> +#ifndef _EFI_XDCI_LIB_H_
> +#define _EFI_XDCI_LIB_H_
> +
> +#include <Uefi.h>
> +#include <Library/DebugLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Protocol/UsbIo.h>
> +
> +#define MAX_DESCRIPTOR_SIZE         64
> +#define STRING_ARR_SIZE             (MAX_DESCRIPTOR_SIZE - 2)
> +#define USB_ADDRESS_TABLE_SIZE      16  //4
> +
> +//
> +// Endpoint Zero
> +//
> +#define USB_EP0_MAX_PKT_SIZE_HS     0x40 // High Speed mode is explicitly set as 64 bytes
> +#define USB_EP0_MAX_PKT_SIZE_SS     0x9  // Must be 0x9 (2^9 = 512 Bytes) in SuperSpeed mode
> +#define USB_EPO_MAX_PKT_SIZE_ALL    512  // Overall max bytes for any type
> +
> +//
> +// Bulk Endpoints
> +//
> +#define USB_BULK_EP_PKT_SIZE_HS     0x200 // Bulk-Endpoint HighSpeed
> +#define USB_BULK_EP_PKT_SIZE_SS     0x400 // Bulk-Endpoint SuperSpeed
> +#define USB_BULK_EP_PKT_SIZE_MAX    USB_BULK_EP_PKT_SIZE_SS
> +
> +//
> +// Transmit Direction Bits
> +//
> +#define USB_ENDPOINT_DIR_OUT                 0x00
> +
> +//
> +// Endpoint Companion Bulk Attributes
> +//
> +#define USB_EP_BULK_BM_ATTR_MASK    0x1F
> +
> +//
> +// Configuration Modifiers (Attributes)
> +//
> +#define USB_BM_ATTR_RESERVED        0x80
> +#define USB_BM_ATTR_SELF_POWERED    0x40
> +#define USB_BM_ATTR_REMOTE_WAKE     0X20
> +
> +//
> +// USB BCD version
> +//
> +#define USB_BCD_VERSION_LS          0x0110
> +#define USB_BCD_VERSION_HS          0x0200
> +#define USB_BCD_VERSION_SS          0x0300
> +
> +//
> +// Device RequestType Flags
> +//
> +#define USB_RT_TX_DIR_H_TO_D        (0x0)       // Tx direction Host to Device
> +#define USB_RT_TX_DIR_D_TO_H        (0x1 << 7)  // Tx direction Device to Host
> +#define USB_RT_TX_DIR_MASK          (0x80)
> +
> +//
> +// USB request type
> +//
> +#define USB_REQ_TYPE_MASK           (0x60)
> +
> +//
> +// Usb control transfer target
> +//
> +#define USB_TARGET_MASK             (0x1F)
> +
> +//
> +// Device GetStatus bits
> +//
> +#define USB_STATUS_SELFPOWERED      (0x01)
> +#define USB_STATUS_REMOTEWAKEUP     (0x02)
> +
> +//
> +// USB Device class identifiers
> +//
> +#define USB_DEVICE_MS_CLASS         (0x08)
> +#define USB_DEVICE_VENDOR_CLASS     (0xFF)
> +
> +//
> +// USB Descriptor types
> +//
> +#define USB_DESC_TYPE_BOS                    0x0F
> +#define USB_DESC_TYPE_DEVICE_CAPABILITY      0x10
> +#define USB_DESC_TYPE_SS_ENDPOINT_COMPANION  0x30
> +
> +#ifdef SUPPORT_SUPER_SPEED
> +//
> +// USB device capability Type Codes
> +// USB3 Table 9-13
> +//
> +typedef enum {
> +  WirelessUSB = 0x01,
> +  USB2Extension,
> +  SuperSpeedUSB,
> +  ContainerID,
> +  SuperSpeedPlusUSB = 0x0A
> +} USB_DEVICE_CAP_TYPE_CODE;
> +#endif
> +
> +//
> +// USB device states from USB spec sec 9.1
> +//
> +typedef enum {
> +  UsbDevStateOff = 0,
> +  UsbDevStateInit,
> +  UsbDevStateAttached,
> +  UsbDevStatePowered,
> +  UsbDevStateDefault,
> +  UsbDevStateAddress,
> +  UsbDevStateConfigured,
> +  UsbDevStateSuspended,
> +  UsbDevStateError
> +} USB_DEVICE_STATE;
> +
> +//
> +// The following set of structs are used during USB data transaction
> +// operatitions, including requests and completion events.
> +//
> +#pragma pack(1)
> +
> +typedef struct {
> +  UINT32     EndpointNum;
> +  UINT8      EndpointDir;
> +  UINT8      EndpointType;
> +  UINT32     Length;
> +  VOID       *Buffer;
> +} EFI_USB_DEVICE_XFER_INFO;
> +
> +//
> +// SuperSpeed Endpoint companion descriptor
> +// USB3 table 9-22
> +//
> +typedef struct {
> +  UINT8      Length;
> +  UINT8      DescriptorType;
> +  UINT8      MaxBurst;
> +  UINT8      Attributes;
> +  UINT16     BytesPerInterval;
> +} EFI_USB_ENDPOINT_COMPANION_DESCRIPTOR;
> +
> +typedef struct {
> +  EFI_USB_ENDPOINT_DESCRIPTOR              *EndpointDesc;
> +  EFI_USB_ENDPOINT_COMPANION_DESCRIPTOR    *EndpointCompDesc;
> +} USB_DEVICE_ENDPOINT_INFO, USB_DEVICE_ENDPOINT_OBJ;
> +
> +typedef struct {
> +  VOID        *Buffer;
> +  UINT32      Length;
> +} USB_DEVICE_IO_INFO;
> +
> +typedef struct {
> +  USB_DEVICE_IO_INFO           IoInfo;
> +  USB_DEVICE_ENDPOINT_INFO     EndpointInfo;
> +} USB_DEVICE_IO_REQ;
> +
> +//
> +// Optional string descriptor
> +//
> +typedef struct {
> +  UINT8           Length;
> +  UINT8           DescriptorType;
> +  UINT16          LangID[STRING_ARR_SIZE];
> +} USB_STRING_DESCRIPTOR;
> +
> +//
> +// The following structures abstract the device descriptors a class
> +// driver needs to provide to the USBD core.
> +// These structures are filled & owned by the class/function layer.
> +//
> +typedef struct {
> +  EFI_USB_INTERFACE_DESCRIPTOR         *InterfaceDesc;
> +  USB_DEVICE_ENDPOINT_OBJ              *EndpointObjs;
> +} USB_DEVICE_INTERFACE_OBJ;
> +
> +typedef struct {
> +  EFI_USB_CONFIG_DESCRIPTOR     *ConfigDesc;
> +  VOID                          *ConfigAll;
> +  USB_DEVICE_INTERFACE_OBJ      *InterfaceObjs;
> +} USB_DEVICE_CONFIG_OBJ;
> +
> +#ifdef SUPPORT_SUPER_SPEED
> +//
> +// SuperSpeed Binary Device Object Store(BOS) descriptor
> +// USB3 9.6.2
> +//
> +typedef struct {
> +  UINT8      Length;
> +  UINT8      DescriptorType;
> +  UINT16     TotalLength;
> +  UINT8      NumDeviceCaps;
> +} EFI_USB_BOS_DESCRIPTOR;
> +
> +//
> +// Generic Header of Device Capability descriptor
> +// USB3 9.6.2.2
> +//
> +typedef struct {
> +  UINT8      Length;
> +  UINT8      DescriptorType;
> +  UINT8      DevCapabilityType;
> +  UINT8      CapDependent;
> +} EFI_USB_SS_DEVICE_CAP_DESCRIPTOR;
> +
> +//
> +// USB2.0 Extension descriptor
> +// USB3 Table 9-14
> +//
> +typedef struct {
> +  UINT8      Length;
> +  UINT8      DescriptorType;
> +  UINT8      DeviceCapabilityType;
> +  UINT32     Attributes;
> +} EFI_USB_USB2_EXT_CAP_DESCRIPTOR;
> +
> +//
> +// SuperSpeed USB Device Capability descriptor
> +// USB3 Table 9-15
> +//
> +typedef struct {
> +  UINT8      Length;
> +  UINT8      DescriptorType;
> +  UINT8      DeviceCapabilityType;
> +  UINT8      Attributes;
> +  UINT16     SpeedSupported;
> +  UINT8      FunctionalitySupport;
> +  UINT8      U1DevExitLat;
> +  UINT16     U2DevExitLat;
> +} EFI_USB_SS_USB_DEV_CAP_DESCRIPTOR;
> +
> +//
> +// Container ID descriptor
> +// USB3 Table 9-16
> +//
> +typedef struct {
> +  UINT8      Length;
> +  UINT8      DescriptorType;
> +  UINT8      DeviceCapabilityType;
> +  UINT8      Reserved;
> +  UINT8      UUID[16];
> +} EFI_USB_CONTAINER_ID_DESCRIPTOR;
> +
> +//
> +// Container ID descriptor
> +// USB3 Table 9-16
> +//
> +typedef struct {
> +  UINT8      Length;
> +  UINT8      DescriptorType;
> +  UINT8      DeviceCapabilityType;
> +  UINT8      ReservedByte;
> +  UINT32     Attributes;
> +  UINT16     FunctionalitySupport;
> +  UINT16     ReservedWord;
> +  UINT32     SublinkSpeedAttr[2];
> +} EFI_USB_SS_PLUS_USB_DEV_CAP_DESCRIPTOR;
> +
> +#endif
> +
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_USB_CONFIG_CALLBACK) (
> +  IN UINT8                      CfgVal
> +  );
> +
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_USB_SETUP_CALLBACK) (
> +  IN EFI_USB_DEVICE_REQUEST     *CtrlRequest,
> +  IN USB_DEVICE_IO_INFO         *IoInfo
> +  );
> +
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_USB_DATA_CALLBACK) (
> +  IN EFI_USB_DEVICE_XFER_INFO   *XferInfo
> +  );
> +
> +typedef struct {
> +  USB_DEVICE_DESCRIPTOR       *DeviceDesc;
> +  USB_DEVICE_CONFIG_OBJ       *ConfigObjs;
> +  USB_STRING_DESCRIPTOR       *StringTable;
> +#ifdef SUPPORT_SUPER_SPEED
> +  EFI_USB_BOS_DESCRIPTOR      *BosDesc;
> +#endif
> +  UINT8                       StrTblEntries;
> +  EFI_USB_CONFIG_CALLBACK     ConfigCallback;
> +  EFI_USB_SETUP_CALLBACK      SetupCallback;
> +  EFI_USB_DATA_CALLBACK       DataCallback;
> +} USB_DEVICE_OBJ;
> +
> +//
> +// Main USBD driver object structure containing all data necessary
> +// for USB device mode processing at this layer
> +//
> +typedef struct {
> +  USB_DEVICE_OBJ              *UsbdDevObj;      /* pointer to a Device Object */
> +  VOID                        *XdciDrvObj;      /* Opaque handle to XDCI driver */
> +  BOOLEAN                     XdciInitialized;  /* flag to specify if the XDCI driver is initialized */
> +  USB_DEVICE_CONFIG_OBJ       *ActiveConfigObj; /* pointer to currently active configuraiton */
> +  USB_DEVICE_STATE            State;            /* current state of the USB Device state machine */
> +  UINT8                       Address;          /* configured device address */
> +} USB_DEVICE_DRIVER_OBJ;
> +
> +#pragma pack()
> +
> +#endif
> +
> diff --git a/Silicon/Synopsys/DesignWare/Include/Protocol/EfiUsbFnIo.h b/Silicon/Synopsys/DesignWare/Include/Protocol/EfiUsbFnIo.h
> new file mode 100644
> index 0000000000..97f276f1cc
> --- /dev/null
> +++ b/Silicon/Synopsys/DesignWare/Include/Protocol/EfiUsbFnIo.h
> @@ -0,0 +1,430 @@
> +/** @file
> +  EFI USB function IO Protocol
> +  This protocol supports Usb Function IO API.
> +  Copyright (c) 1999 - 2017, Intel Corporation. All rights reserved.<BR>
> +
> +  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.
> +
> +**/
> +
> +#ifndef __EFI_USB_FUNC_IO_H__
> +#define __EFI_USB_FUNC_IO_H__
> +
> +#include <IndustryStandard/Usb.h>
> +
> +#define EFI_USBFN_IO_PROTOCOL_REVISION   0x00010001
> +
> +//
> +// {32D2963A-FE5D-4f30-B633-6E5DC55803CC}
> +// #define EFI_USBFN_IO_PROTOCOL_GUID  {0x32d2963a, 0xfe5d, 0x4f30, 0xb6, 0x33, 0x6e, 0x5d, 0xc5, 0x58, 0x3, 0xcc };
> +//
> +
> +typedef struct _EFI_USBFN_IO_PROTOCOL   EFI_USBFN_IO_PROTOCOL;
> +
> +//
> +// USB standard descriptors and reqeust
> +//
> +typedef USB_DEVICE_REQUEST        EFI_USB_DEVICE_REQUEST;
> +typedef USB_DEVICE_DESCRIPTOR     EFI_USB_DEVICE_DESCRIPTOR;
> +typedef USB_CONFIG_DESCRIPTOR     EFI_USB_CONFIG_DESCRIPTOR;
> +typedef USB_INTERFACE_DESCRIPTOR  EFI_USB_INTERFACE_DESCRIPTOR;
> +typedef USB_ENDPOINT_DESCRIPTOR   EFI_USB_ENDPOINT_DESCRIPTOR;
> +
> +typedef enum _EFI_USBFN_PORT_TYPE {
> +  EfiUsbUnknownPort = 0,
> +  EfiUsbStandardDownstreamPort,
> +  EfiUsbChargingDownstreamPort,
> +  EfiUsbDedicatedChargingPort,
> +  EfiUsbInvalidDedicatedChargingPort
> +} EFI_USBFN_PORT_TYPE;
> +
> +/**
> + USB_DEVICE_DESCRIPTOR, USB_CONFIG_DESCRIPTOR, USB_INTERFACE_DESCRIPTOR, and
> + USB_ENDPOINT_DESCRIPTOR are already defined
> + in UEFI spec 2.3, as par USB 2.0 spec.
> +**/
> +
> +typedef struct {
> +  EFI_USB_INTERFACE_DESCRIPTOR        *InterfaceDescriptor;
> +  EFI_USB_ENDPOINT_DESCRIPTOR         **EndpointDescriptorTable;
> +} EFI_USB_INTERFACE_INFO;
> +
> +typedef struct {
> +  EFI_USB_CONFIG_DESCRIPTOR           *ConfigDescriptor;
> +  EFI_USB_INTERFACE_INFO              **InterfaceInfoTable;
> +} EFI_USB_CONFIG_INFO;
> +
> +typedef struct {
> +  EFI_USB_DEVICE_DESCRIPTOR           *DeviceDescriptor;
> +  EFI_USB_CONFIG_INFO                 **ConfigInfoTable;
> +} EFI_USB_DEVICE_INFO;
> +
> +
> +typedef enum _EFI_USB_ENDPOINT_TYPE {
> +  UsbEndpointControl     = 0x00,
> +  UsbEndpointIsochronous = 0x01,
> +  UsbEndpointBulk        = 0x02,
> +  UsbEndpointInterrupt   = 0x03
> +} EFI_USB_ENDPOINT_TYPE;
> +
> +
> +typedef enum _EFI_USBFN_DEVICE_INFO_ID {
> +  EfiUsbDeviceInfoUnknown = 0,
> +  EfiUsbDeviceInfoSerialNumber,
> +  EfiUsbDeviceInfoManufacturerName,
> +  EfiUsbDeviceInfoProductName
> +} EFI_USBFN_DEVICE_INFO_ID;
> +
> +
> +typedef enum _EFI_USBFN_ENDPOINT_DIRECTION {
> +  EfiUsbEndpointDirectionHostOut  = 0,
> +  EfiUsbEndpointDirectionHostIn,
> +  EfiUsbEndpointDirectionDeviceTx = EfiUsbEndpointDirectionHostIn,
> +  EfiUsbEndpointDirectionDeviceRx = EfiUsbEndpointDirectionHostOut
> +} EFI_USBFN_ENDPOINT_DIRECTION;
> +
> +
> +typedef enum _EFI_USBFN_MESSAGE {
> +  //
> +  // Nothing
> +  //
> +  EfiUsbMsgNone = 0,
> +  //
> +  // SETUP packet is received, returned Buffer contains
> +  // EFI_USB_DEVICE_REQUEST struct
> +  //
> +  EfiUsbMsgSetupPacket,
> +  //
> +  // Indicates that some of the requested data has been received from the
> +  // host. It is the responsibility of the class driver to determine if it
> +  // needs to wait for any remaining data. Returned Buffer contains
> +  // EFI_USBFN_TRANSFER_RESULT struct containing endpoint number, transfer
> +  // status and count of bytes received.
> +  //
> +  EfiUsbMsgEndpointStatusChangedRx,
> +  //
> +  // Indicates that some of the requested data has been transmitted to the
> +  // host. It is the responsibility of the class driver to determine if any
> +  // remaining data needs to be resent. Returned Buffer contains
> +  // EFI_USBFN_TRANSFER_RESULT struct containing endpoint number, transfer
> +  // status and count of bytes sent.
> +  //
> +  EfiUsbMsgEndpointStatusChangedTx,
> +  //
> +  // DETACH bus event signaled
> +  //
> +  EfiUsbMsgBusEventDetach,
> +  //
> +  // ATTACH bus event signaled
> +  //
> +  EfiUsbMsgBusEventAttach,
> +  //
> +  // RESET bus event signaled
> +  //
> +  EfiUsbMsgBusEventReset,
> +  //
> +  // SUSPEND bus event signaled
> +  //
> +  EfiUsbMsgBusEventSuspend,
> +  //
> +  // RESUME bus event signaled
> +  //
> +  EfiUsbMsgBusEventResume,
> +  //
> +  // Bus speed updated, returned buffer indicated bus speed using
> +  // following enumeration named EFI_USB_BUS_SPEED
> +  //
> +  EfiUsbMsgBusEventSpeed
> +} EFI_USBFN_MESSAGE;
> +
> +
> +typedef enum _EFI_USBFN_TRANSFER_STATUS {
> +  UsbTransferStatusUnknown = 0,
> +  UsbTransferStatusComplete,
> +  UsbTransferStatusAborted,
> +  UsbTransferStatusActive,
> +  UsbTransferStatusNone
> +} EFI_USBFN_TRANSFER_STATUS;
> +
> +
> +typedef struct _EFI_USBFN_TRANSFER_RESULT {
> +  UINTN                         BytesTransferred;
> +  EFI_USBFN_TRANSFER_STATUS     TransferStatus;
> +  UINT8                         EndpointIndex;
> +  EFI_USBFN_ENDPOINT_DIRECTION  Direction;
> +  VOID                          *Buffer;
> +} EFI_USBFN_TRANSFER_RESULT;
> +
> +typedef enum _EFI_USB_BUS_SPEED {
> +  UsbBusSpeedUnknown = 0,
> +  UsbBusSpeedLow,
> +  UsbBusSpeedFull,
> +  UsbBusSpeedHigh,
> +  UsbBusSpeedSuper,
> +  UsbBusSpeedMaximum = UsbBusSpeedSuper
> +} EFI_USB_BUS_SPEED;
> +
> +typedef union _EFI_USBFN_MESSAGE_PAYLOAD {
> +  EFI_USB_DEVICE_REQUEST      udr;
> +  EFI_USBFN_TRANSFER_RESULT   utr;
> +  EFI_USB_BUS_SPEED           ubs;
> +} EFI_USBFN_MESSAGE_PAYLOAD;
> +
> +typedef enum _EFI_USBFN_POLICY_TYPE {
> +  EfiUsbPolicyUndefined = 0,
> +  EfiUsbPolicyMaxTransactionSize,
> +  EfiUsbPolicyZeroLengthTerminationSupport,
> +  EfiUsbPolicyZeroLengthTermination
> +} EFI_USBFN_POLICY_TYPE;
> +
> +
> +/**
> +
> + Allocates transfer buffer of the specified size that satisfies
> + controller requirements.
> +
> + The AllocateTransferBuffer function allocates a memory region of Size bytes and
> + returns the address of the allocated memory that satisfies underlying
> + controller requirements in the location referenced by Buffer.
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI * EFI_USBFN_IO_ALLOCATE_TRANSFER_BUFFER) (
> +  IN EFI_USBFN_IO_PROTOCOL    *This,
> +  IN UINTN                    Size,
> +  OUT VOID                    **Buffer
> +  );
> +
> +/**
> +
> +  Deallocates the memory allocated for the transfer buffer by AllocateTransferBuffer function.
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI * EFI_USBFN_IO_FREE_TRANSFER_BUFFER) (
> +  IN EFI_USBFN_IO_PROTOCOL    *This,
> +  IN VOID                     *Buffer
> +  );
> +
> +/**
> +  Returns information about what type of device was attached.
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI * EFI_USBFN_IO_DETECT_PORT) (
> +  IN EFI_USBFN_IO_PROTOCOL   *This,
> +  OUT EFI_USBFN_PORT_TYPE    *PortType
> +  );
> +
> +/**
> +  Configure endpoints based on supplied device and configuration descriptors.
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI * EFI_USBFN_IO_CONFIGURE_ENABLE_ENDPOINTS) (
> +  IN EFI_USBFN_IO_PROTOCOL         *This,
> +  IN EFI_USB_DEVICE_INFO           *DeviceInfo
> +  );
> +
> +
> +/**
> +  Returns the maximum packet size of the specified endpoint type for the supplied bus speed.
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI * EFI_USBFN_IO_GET_ENDPOINT_MAXPACKET_SIZE) (
> +  IN EFI_USBFN_IO_PROTOCOL       *This,
> +  IN EFI_USB_ENDPOINT_TYPE       EndpointType,
> +  IN EFI_USB_BUS_SPEED           BusSpeed,
> +  OUT UINT16                     *MaxPacketSize
> +  );
> +
> +/**
> +  Returns the maximum supported transfer size.
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI * EFI_USBFN_IO_GET_MAXTRANSFER_SIZE) (
> +  IN EFI_USBFN_IO_PROTOCOL     *This,
> +  OUT UINTN                    *MaxTransferSize
> +  );
> +
> +/**
> +  Returns device specific information based on the supplied identifier as a
> +  Unicode string.
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI * EFI_USBFN_IO_GET_DEVICE_INFO) (
> +  IN EFI_USBFN_IO_PROTOCOL      *This,
> +  IN EFI_USBFN_DEVICE_INFO_ID   Id,
> +  IN OUT UINTN                  *BufferSize,
> +  OUT VOID                      *Buffer OPTIONAL
> +  );
> +
> +/**
> +  Returns vendor-id and product-id of the device.
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI * EFI_USBFN_IO_GET_VENDOR_ID_PRODUCT_ID) (
> +  IN EFI_USBFN_IO_PROTOCOL      *This,
> +  OUT UINT16                    *Vid,
> +  OUT UINT16                    *Pid
> +  );
> +
> +/**
> +  Aborts transfer on the specified endpoint.
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI * EFI_USBFN_IO_ABORT_TRANSFER) (
> +  IN EFI_USBFN_IO_PROTOCOL        *This,
> +  IN UINT8                        EndpointIndex,
> +  IN EFI_USBFN_ENDPOINT_DIRECTION Direction
> +  );
> +
> +/**
> +  Returns the stall state on the specified endpoint.
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI * EFI_USBFN_IO_GET_ENDPOINT_STALL_STATE) (
> +  IN EFI_USBFN_IO_PROTOCOL        *This,
> +  IN UINT8                        EndpointIndex,
> +  IN EFI_USBFN_ENDPOINT_DIRECTION Direction,
> +  IN OUT BOOLEAN                  *State
> +  );
> +
> +/**
> +  Sets or clears the stall state on the specified endpoint.
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI * EFI_USBFN_IO_SET_ENDPOINT_STALL_STATE) (
> +  IN EFI_USBFN_IO_PROTOCOL        *This,
> +  IN UINT8                        EndpointIndex,
> +  IN EFI_USBFN_ENDPOINT_DIRECTION Direction,
> +  IN BOOLEAN                      State
> +  );
> +
> +
> +/**
> +  This function is called repeatedly to receive updates on USB bus states,
> +  receive, transmit status changes on endpoints and setup packet on endpoint 0.
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI * EFI_USBFN_IO_EVENTHANDLER) (
> +  IN EFI_USBFN_IO_PROTOCOL        *This,
> +  OUT EFI_USBFN_MESSAGE           *Message,
> +  IN OUT UINTN                    *PayloadSize,
> +  OUT EFI_USBFN_MESSAGE_PAYLOAD   *Payload
> +  );
> +
> +/**
> +  Primary function to handle transfer in either direction based on specified
> +  direction and on the specified endpoint.
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_USBFN_IO_TRANSFER) (
> +  IN EFI_USBFN_IO_PROTOCOL         *This,
> +  IN UINT8                         EndpointIndex,
> +  IN EFI_USBFN_ENDPOINT_DIRECTION  Direction,
> +  IN OUT UINTN                     *BufferSize,
> +  IN OUT VOID                      *Buffer
> +  );
> +
> +/**
> +  This function supplies power to the USB controller if needed,
> +  initialize hardware and internal data structures, and then return.
> +
> +  The port must not be activated by this function.
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI * EFI_USBFN_IO_START_CONTROLLER) (
> +    IN EFI_USBFN_IO_PROTOCOL    *This
> +    );
> +
> +/**
> +  This function disables the hardware device by resetting the run/stop bit and
> +  power off the USB controller if needed.
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI * EFI_USBFN_IO_STOP_CONTROLLER) (
> +    IN EFI_USBFN_IO_PROTOCOL    *This
> +    );
> +
> +/**
> +  This function sets the configuration policy for the specified non-control endpoint.
> +
> +  Refer to the description for calling restrictions.
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI * EFI_USBFN_IO_SET_ENDPOINT_POLICY) (
> +  IN EFI_USBFN_IO_PROTOCOL        *This,
> +  IN UINT8                        EndpointIndex,
> +  IN EFI_USBFN_ENDPOINT_DIRECTION Direction,
> +  IN EFI_USBFN_POLICY_TYPE        PolicyType,
> +  IN UINTN                        BufferSize,
> +  IN VOID                         *Buffer
> +  );
> +
> +/**
> +  This function retrieves the configuration policy for the specified non-control endpoint.
> +
> +  There are no associated calling restrictions for this function.
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI * EFI_USBFN_IO_GET_ENDPOINT_POLICY) (
> +  IN EFI_USBFN_IO_PROTOCOL        *This,
> +  IN UINT8                        EndpointIndex,
> +  IN EFI_USBFN_ENDPOINT_DIRECTION Direction,
> +  IN EFI_USBFN_POLICY_TYPE        PolicyType,
> +  IN OUT UINTN                    *BufferSize,
> +  IN OUT VOID                     *Buffer
> +  );
> +
> +
> +struct _EFI_USBFN_IO_PROTOCOL {
> +  UINT32                                      Revision;
> +  EFI_USBFN_IO_DETECT_PORT                    DetectPort;
> +  EFI_USBFN_IO_CONFIGURE_ENABLE_ENDPOINTS     ConfigureEnableEndpoints;
> +  EFI_USBFN_IO_GET_ENDPOINT_MAXPACKET_SIZE    GetEndpointMaxPacketSize;
> +  EFI_USBFN_IO_GET_DEVICE_INFO                GetDeviceInfo;
> +  EFI_USBFN_IO_GET_VENDOR_ID_PRODUCT_ID       GetVendorIdProductId;
> +  EFI_USBFN_IO_ABORT_TRANSFER                 AbortTransfer;
> +  EFI_USBFN_IO_GET_ENDPOINT_STALL_STATE       GetEndpointStallState;
> +  EFI_USBFN_IO_SET_ENDPOINT_STALL_STATE       SetEndpointStallState;
> +  EFI_USBFN_IO_EVENTHANDLER                   EventHandler;
> +  EFI_USBFN_IO_TRANSFER                       Transfer;
> +  EFI_USBFN_IO_GET_MAXTRANSFER_SIZE           GetMaxTransferSize;
> +  EFI_USBFN_IO_ALLOCATE_TRANSFER_BUFFER       AllocateTransferBuffer;
> +  EFI_USBFN_IO_FREE_TRANSFER_BUFFER           FreeTransferBuffer;
> +  //
> +  // Valid for version EFI_USBFN_IO_PROTOCOL_REVISION2 and above
> +  //
> +  EFI_USBFN_IO_START_CONTROLLER               StartController;
> +  EFI_USBFN_IO_STOP_CONTROLLER                StopController;
> +  EFI_USBFN_IO_SET_ENDPOINT_POLICY            SetEndpointPolicy;
> +  EFI_USBFN_IO_GET_ENDPOINT_POLICY            GetEndpointPolicy;
> +};
> +
> +
> +extern EFI_GUID gEfiUsbFnIoProtocolGuid;
> +#endif
> +
> diff --git a/Silicon/Synopsys/DesignWare/Include/Protocol/UsbDeviceModeProtocol.h b/Silicon/Synopsys/DesignWare/Include/Protocol/UsbDeviceModeProtocol.h
> new file mode 100644
> index 0000000000..c301fa00d3
> --- /dev/null
> +++ b/Silicon/Synopsys/DesignWare/Include/Protocol/UsbDeviceModeProtocol.h
> @@ -0,0 +1,104 @@
> +/** @file
> +  Copyright (c) 1999 - 2017, Intel Corporation. All rights reserved.<BR>
> +
> +  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.
> +
> +**/
> +
> +
> +#ifndef _USB_DEVICE_MODE_PROTOCOL_H_
> +#define _USB_DEVICE_MODE_PROTOCOL_H_
> +
> +#include <Library/UsbDeviceLib.h>
> +
> +///
> +/// UsbDeviceMode Protocol GUID.
> +///
> +#define EFI_USB_DEVICE_MODE_PROTOCOL_GUID \
> +  {0xC9923F7E, 0x1746, 0x4802, { 0x86, 0x2e, 0x1, 0x1c, 0x2c, 0x2d, 0x9d, 0x86 } }
> +
> +typedef struct _EFI_USB_DEVICE_MODE_PROTOCOL EFI_USB_DEVICE_MODE_PROTOCOL;
> +
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_USB_DEVICE_MODE_INIT_XDCI) (
> +  IN EFI_USB_DEVICE_MODE_PROTOCOL               *This
> +  );
> +
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_USB_DEVICE_MODE_CONNECT) (
> +  IN EFI_USB_DEVICE_MODE_PROTOCOL               *This
> +  );
> +
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_USB_DEVICE_MODE_DISCONNECT) (
> +  IN EFI_USB_DEVICE_MODE_PROTOCOL               *This
> +  );
> +
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_USB_DEVICE_EP_TX_DATA) (
> +  IN EFI_USB_DEVICE_MODE_PROTOCOL               *This,
> +  IN USB_DEVICE_IO_REQ                          *IoRequest
> +  );
> +
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_USB_DEVICE_EP_RX_DATA) (
> +  IN EFI_USB_DEVICE_MODE_PROTOCOL               *This,
> +  IN USB_DEVICE_IO_REQ                          *IoRequest
> +  );
> +
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_USB_DEVICE_MODE_BIND) (
> +  IN EFI_USB_DEVICE_MODE_PROTOCOL               *This,
> +  IN USB_DEVICE_OBJ                             *UsbdDevObj
> +  );
> +
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_USB_DEVICE_MODE_UNBIND) (
> +  IN EFI_USB_DEVICE_MODE_PROTOCOL               *This
> +  );
> +
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_USB_DEVICE_MODE_STOP) (
> +  IN EFI_USB_DEVICE_MODE_PROTOCOL               *This
> +  );
> +
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_USB_DEVICE_MODE_RUN) (
> +  IN EFI_USB_DEVICE_MODE_PROTOCOL               *This,
> +  IN UINT32                                     TimeoutMs
> +  );
> +
> +///
> +/// Usb Device Mode Protocol Structure.
> +///
> +struct _EFI_USB_DEVICE_MODE_PROTOCOL {
> +  EFI_USB_DEVICE_MODE_INIT_XDCI            InitXdci;
> +  EFI_USB_DEVICE_MODE_CONNECT              Connect;
> +  EFI_USB_DEVICE_MODE_DISCONNECT           DisConnect;
> +  EFI_USB_DEVICE_EP_TX_DATA                EpTxData;
> +  EFI_USB_DEVICE_EP_RX_DATA                EpRxData;
> +  EFI_USB_DEVICE_MODE_BIND                 Bind;
> +  EFI_USB_DEVICE_MODE_UNBIND               UnBind;
> +  EFI_USB_DEVICE_MODE_RUN                  Run;
> +  EFI_USB_DEVICE_MODE_STOP                 Stop;
> +};
> +
> +extern EFI_GUID gEfiUsbDeviceModeProtocolGuid;
> +
> +#endif
> +
> --
> 2.27.0.windows.1
>

[-- Attachment #2: Type: text/html, Size: 831905 bytes --]

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [edk2-platforms PATCH 1/5] Silicon/Synopsys/DesignWare: Import DesignWare USB3 peripheral driver
  2020-07-20 17:43 ` Leif Lindholm
  2020-07-21  3:51   ` Vin Xue
@ 2020-07-21  8:17   ` Meenakshi Aggarwal (OSS)
  1 sibling, 0 replies; 6+ messages in thread
From: Meenakshi Aggarwal (OSS) @ 2020-07-21  8:17 UTC (permalink / raw)
  To: Leif Lindholm, Vin Xue
  Cc: devel@edk2.groups.io, Ard Biesheuvel, Meenakshi Aggarwal (OSS),
	Pankaj Bansal, Varun Sethi

Hi Leif,

I completely agree that we should always try to have one common driver rather platform specific.
But integrating and testing this driver will be a time consuming for me as I need to implement a platform specific library/driver to apply erratas
and anything else if needed.

We will keep this work in our bucket list but ,for now, we really appreciate if you please accept our patches as its been years since we are trying to upstream these.
We have gone through a number of review cycles and we do not want to further delay our upstreaming process.

Please help with this.

Thanks,
Meenakshi

> -----Original Message-----
> From: Leif Lindholm <leif@nuviainc.com>
> Sent: Monday, July 20, 2020 11:13 PM
> To: Vin Xue <vinxue@outlook.com>
> Cc: devel@edk2.groups.io; Ard Biesheuvel <ard.biesheuvel@arm.com>;
> Meenakshi Aggarwal (OSS) <meenakshi.aggarwal@oss.nxp.com>
> Subject: Re: [edk2-platforms PATCH 1/5] Silicon/Synopsys/DesignWare:
> Import DesignWare USB3 peripheral driver
> 
> Hi Vin, +Meenakshi
> 
> Can you clarify the exact origin of this source code please?
> We can only accept bsd+patent code contributions, and these days we
> use only SPDX tags rather than full license statements at top of
> files.
> 
> Meenakshi - I would certainly prefer to have a single (and
> Arm-functional) driver for DWC3 rather than init-only drivers per
> platform. Can you have a look at this code plese and see if it looks
> feasible to integrate in the NXP platforms?
> 
> Regards,
> 
> Leif
> 
> On Fri, Jul 17, 2020 at 18:01:59 +0800, Vin Xue wrote:
> > Incorporate the driver for the DesignWare USB3 DRD controller device
> > mode (peripheral) that is defined in
> > edk2-platforms/devel-IntelAtomProcessorE3900 branch.
> >
> > The driver is supported by Intel Atom series (Merrifield/BayTrail/
> > CherryTrail/Broxton/ApoloLake/GeminiLake etc.) and Core series
> > (6th Generation and newer).
> >
> > The driver verified on AAEON UP Squared developer board (Intel
> > ApoloLake platform).
> >
> > The driver supports Synopsys DesignWare DWC_usb3 and DWC_usb31 IP.
> >
> > It is better if the driver can be ported to ARM silicon.
> >
> > Cc: Ard Biesheuvel <ard.biesheuvel@arm.com>
> > Cc: Leif Lindholm <leif@nuviainc.com>
> > Signed-off-by: Vin Xue <vinxue@outlook.com>
> > ---
> >  .../Drivers/UsbDeviceDxe/ComponentName.c      |  305 ++
> >  .../Drivers/UsbDeviceDxe/UsbDeviceDxe.c       |  395 ++
> >  .../Drivers/UsbDeviceDxe/UsbDeviceDxe.h       |  159 +
> >  .../Drivers/UsbDeviceDxe/UsbDeviceDxe.inf     |   74 +
> >  .../Drivers/UsbDeviceDxe/UsbDeviceMode.c      | 1489 ++++++
> >  .../Drivers/UsbDeviceDxe/UsbDeviceMode.h      |   39 +
> >  .../Drivers/UsbDeviceDxe/UsbFuncIo.c          | 2221 +++++++++
> >  .../Drivers/UsbDeviceDxe/UsbFuncIo.h          |  234 +
> >  .../Drivers/UsbDeviceDxe/UsbIoNode.c          |  177 +
> >  .../Drivers/UsbDeviceDxe/UsbIoNode.h          |   90 +
> >  .../Drivers/UsbDeviceDxe/XdciCommon.h         |  156 +
> >  .../DesignWare/Drivers/UsbDeviceDxe/XdciDWC.c | 4030
> +++++++++++++++++
> >  .../DesignWare/Drivers/UsbDeviceDxe/XdciDWC.h |  741 +++
> >  .../Drivers/UsbDeviceDxe/XdciDevice.c         |  695 +++
> >  .../Drivers/UsbDeviceDxe/XdciDevice.h         |  184 +
> >  .../Drivers/UsbDeviceDxe/XdciInterface.h      |  241 +
> >  .../Drivers/UsbDeviceDxe/XdciTable.c          |   55 +
> >  .../Drivers/UsbDeviceDxe/XdciUtility.c        |  148 +
> >  .../Drivers/UsbDeviceDxe/XdciUtility.h        |   62 +
> >  .../DesignWare/Include/Library/UsbDeviceLib.h |  323 ++
> >  .../DesignWare/Include/Protocol/EfiUsbFnIo.h  |  430 ++
> >  .../Include/Protocol/UsbDeviceModeProtocol.h  |  104 +
> >  22 files changed, 12352 insertions(+)
> >  create mode 100644
> Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/ComponentName.c
> >  create mode 100644
> Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbDeviceDxe.c
> >  create mode 100644
> Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbDeviceDxe.h
> >  create mode 100644
> Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbDeviceDxe.inf
> >  create mode 100644
> Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbDeviceMode.c
> >  create mode 100644
> Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbDeviceMode.h
> >  create mode 100644
> Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbFuncIo.c
> >  create mode 100644
> Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbFuncIo.h
> >  create mode 100644
> Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbIoNode.c
> >  create mode 100644
> Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbIoNode.h
> >  create mode 100644
> Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciCommon.h
> >  create mode 100644
> Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciDWC.c
> >  create mode 100644
> Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciDWC.h
> >  create mode 100644
> Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciDevice.c
> >  create mode 100644
> Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciDevice.h
> >  create mode 100644
> Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciInterface.h
> >  create mode 100644
> Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciTable.c
> >  create mode 100644
> Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciUtility.c
> >  create mode 100644
> Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciUtility.h
> >  create mode 100644
> Silicon/Synopsys/DesignWare/Include/Library/UsbDeviceLib.h
> >  create mode 100644
> Silicon/Synopsys/DesignWare/Include/Protocol/EfiUsbFnIo.h
> >  create mode 100644
> Silicon/Synopsys/DesignWare/Include/Protocol/UsbDeviceModeProtocol.h
> >
> > diff --git
> a/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/ComponentName.c
> b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/ComponentName.c
> > new file mode 100644
> > index 0000000000..acb4b6a23d
> > --- /dev/null
> > +++
> b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/ComponentName.c
> > @@ -0,0 +1,305 @@
> > +/** @file
> > +  Copyright (c) 2004 - 2017, Intel Corporation. All rights reserved.<BR>
> > +
> > +  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.
> > +
> > +**/
> > +
> > +#include <Uefi.h>
> > +#include <Library/UefiLib.h>
> > +
> > +
> > +/**
> > +  Retrieves a Unicode string that is the user readable name of the driver.
> > +
> > +  This function retrieves the user readable name of a driver in the form of
> a
> > +  Unicode string. If the driver specified by This has a user readable name in
> > +  the language specified by Language, then a pointer to the driver name is
> > +  returned in DriverName, and EFI_SUCCESS is returned. If the driver
> specified
> > +  by This does not support the language specified by Language,
> > +  then EFI_UNSUPPORTED is returned.
> > +
> > +  @param  This[in]              A pointer to the
> EFI_COMPONENT_NAME2_PROTOCOL or
> > +                                EFI_COMPONENT_NAME_PROTOCOL instance.
> > +
> > +  @param  Language[in]          A pointer to a Null-terminated ASCII string
> > +                                array indicating the language. This is the
> > +                                language of the driver name that the caller is
> > +                                requesting, and it must match one of the
> > +                                languages specified in SupportedLanguages. The
> > +                                number of languages supported by a driver is up
> > +                                to the driver writer. Language is specified
> > +                                in RFC 4646 or ISO 639-2 language code format.
> > +
> > +  @param  DriverName[out]       A pointer to the Unicode string to return.
> > +                                This Unicode string is the name of the
> > +                                driver specified by This in the language
> > +                                specified by Language.
> > +
> > +  @retval EFI_SUCCESS           The Unicode string for the Driver specified by
> > +                                This and the language specified by Language was
> > +                                returned in DriverName.
> > +
> > +  @retval EFI_INVALID_PARAMETER Language is NULL.
> > +
> > +  @retval EFI_INVALID_PARAMETER DriverName is NULL.
> > +
> > +  @retval EFI_UNSUPPORTED       The driver specified by This does not
> support
> > +                                the language specified by Language.
> > +
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +UsbDeviceDxeGetDriverName (
> > +  IN  EFI_COMPONENT_NAME_PROTOCOL  *This,
> > +  IN  CHAR8                        *Language,
> > +  OUT CHAR16                       **DriverName
> > +  );
> > +
> > +
> > +/**
> > +  Retrieves a Unicode string that is the user readable name of the
> controller
> > +  that is being managed by a driver.
> > +
> > +  This function retrieves the user readable name of the controller specified
> by
> > +  ControllerHandle and ChildHandle in the form of a Unicode string. If the
> > +  driver specified by This has a user readable name in the language
> specified by
> > +  Language, then a pointer to the controller name is returned in
> ControllerName,
> > +  and EFI_SUCCESS is returned.  If the driver specified by This is not
> currently
> > +  managing the controller specified by ControllerHandle and ChildHandle,
> > +  then EFI_UNSUPPORTED is returned.  If the driver specified by This does
> not
> > +  support the language specified by Language, then EFI_UNSUPPORTED is
> returned.
> > +
> > +  @param  This[in]              A pointer to the
> EFI_COMPONENT_NAME2_PROTOCOL or
> > +                                EFI_COMPONENT_NAME_PROTOCOL instance.
> > +
> > +  @param  ControllerHandle[in]  The handle of a controller that the driver
> > +                                specified by This is managing.  This handle
> > +                                specifies the controller whose name is to be
> > +                                returned.
> > +
> > +  @param  ChildHandle[in]       The handle of the child controller to
> retrieve
> > +                                the name of.  This is an optional parameter that
> > +                                may be NULL.  It will be NULL for device
> > +                                drivers.  It will also be NULL for a bus drivers
> > +                                that wish to retrieve the name of the bus
> > +                                controller.  It will not be NULL for a bus
> > +                                driver that wishes to retrieve the name of a
> > +                                child controller.
> > +
> > +  @param  Language[in]          A pointer to a Null-terminated ASCII string
> > +                                array indicating the language.  This is the
> > +                                language of the driver name that the caller is
> > +                                requesting, and it must match one of the
> > +                                languages specified in SupportedLanguages. The
> > +                                number of languages supported by a driver is up
> > +                                to the driver writer. Language is specified in
> > +                                RFC 4646 or ISO 639-2 language code format.
> > +
> > +  @param  ControllerName[out]   A pointer to the Unicode string to
> return.
> > +                                This Unicode string is the name of the
> > +                                controller specified by ControllerHandle and
> > +                                ChildHandle in the language specified by
> > +                                Language from the point of view of the driver
> > +                                specified by This.
> > +
> > +  @retval EFI_SUCCESS           The Unicode string for the user readable
> name in
> > +                                the language specified by Language for the
> > +                                driver specified by This was returned in
> > +                                DriverName.
> > +
> > +  @retval EFI_INVALID_PARAMETER ControllerHandle is NULL.
> > +
> > +  @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a
> valid
> > +                                EFI_HANDLE.
> > +
> > +  @retval EFI_INVALID_PARAMETER Language is NULL.
> > +
> > +  @retval EFI_INVALID_PARAMETER ControllerName is NULL.
> > +
> > +  @retval EFI_UNSUPPORTED       The driver specified by This is not
> currently
> > +                                managing the controller specified by
> > +                                ControllerHandle and ChildHandle.
> > +
> > +  @retval EFI_UNSUPPORTED       The driver specified by This does not
> support
> > +                                the language specified by Language.
> > +
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +UsbDeviceDxeGetControllerName (
> > +  IN  EFI_COMPONENT_NAME_PROTOCOL                     *This,
> > +  IN  EFI_HANDLE                                      ControllerHandle,
> > +  IN  EFI_HANDLE                                      ChildHandle        OPTIONAL,
> > +  IN  CHAR8                                           *Language,
> > +  OUT CHAR16                                          **ControllerName
> > +  );
> > +
> > +
> > +//
> > +// EFI Component Name Protocol
> > +//
> > +GLOBAL_REMOVE_IF_UNREFERENCED
> EFI_COMPONENT_NAME_PROTOCOL  mUsbDeviceDxeComponentName = {
> > +  UsbDeviceDxeGetDriverName,
> > +  UsbDeviceDxeGetControllerName,
> > +  "eng"
> > +};
> > +
> > +//
> > +// EFI Component Name 2 Protocol
> > +//
> > +GLOBAL_REMOVE_IF_UNREFERENCED
> EFI_COMPONENT_NAME2_PROTOCOL mUsbDeviceDxeComponentName2 = {
> > +  (EFI_COMPONENT_NAME2_GET_DRIVER_NAME)
> UsbDeviceDxeGetDriverName,
> > +  (EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME)
> UsbDeviceDxeGetControllerName,
> > +  "en"
> > +};
> > +
> > +
> > +GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE
> mUsbDeviceDxeDriverNameTable[] = {
> > +  { "eng;en", L"Usb Device Driver" },
> > +  { NULL , NULL }
> > +};
> > +
> > +/**
> > +  Retrieves a Unicode string that is the user readable name of the driver.
> > +
> > +  This function retrieves the user readable name of a driver in the form of
> a
> > +  Unicode string. If the driver specified by This has a user readable name in
> > +  the language specified by Language, then a pointer to the driver name is
> > +  returned in DriverName, and EFI_SUCCESS is returned. If the driver
> specified
> > +  by This does not support the language specified by Language,
> > +  then EFI_UNSUPPORTED is returned.
> > +
> > +  @param  This[in]              A pointer to the
> EFI_COMPONENT_NAME2_PROTOCOL or
> > +                                EFI_COMPONENT_NAME_PROTOCOL instance.
> > +
> > +  @param  Language[in]          A pointer to a Null-terminated ASCII string
> > +                                array indicating the language. This is the
> > +                                language of the driver name that the caller is
> > +                                requesting, and it must match one of the
> > +                                languages specified in SupportedLanguages. The
> > +                                number of languages supported by a driver is up
> > +                                to the driver writer. Language is specified
> > +                                in RFC 4646 or ISO 639-2 language code format.
> > +
> > +  @param  DriverName[out]       A pointer to the Unicode string to return.
> > +                                This Unicode string is the name of the
> > +                                driver specified by This in the language
> > +                                specified by Language.
> > +
> > +  @retval EFI_SUCCESS           The Unicode string for the Driver specified by
> > +                                This and the language specified by Language was
> > +                                returned in DriverName.
> > +
> > +  @retval EFI_INVALID_PARAMETER Language is NULL.
> > +
> > +  @retval EFI_INVALID_PARAMETER DriverName is NULL.
> > +
> > +  @retval EFI_UNSUPPORTED       The driver specified by This does not
> support
> > +                                the language specified by Language.
> > +
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +UsbDeviceDxeGetDriverName (
> > +  IN  EFI_COMPONENT_NAME_PROTOCOL  *This,
> > +  IN  CHAR8                        *Language,
> > +  OUT CHAR16                       **DriverName
> > +  )
> > +{
> > +  return LookupUnicodeString2 (
> > +           Language,
> > +           This->SupportedLanguages,
> > +           mUsbDeviceDxeDriverNameTable,
> > +           DriverName,
> > +           (BOOLEAN)(This == &mUsbDeviceDxeComponentName)
> > +           );
> > +}
> > +
> > +/**
> > +  Retrieves a Unicode string that is the user readable name of the
> controller
> > +  that is being managed by a driver.
> > +
> > +  This function retrieves the user readable name of the controller specified
> by
> > +  ControllerHandle and ChildHandle in the form of a Unicode string. If the
> > +  driver specified by This has a user readable name in the language
> specified by
> > +  Language, then a pointer to the controller name is returned in
> ControllerName,
> > +  and EFI_SUCCESS is returned.  If the driver specified by This is not
> currently
> > +  managing the controller specified by ControllerHandle and ChildHandle,
> > +  then EFI_UNSUPPORTED is returned.  If the driver specified by This does
> not
> > +  support the language specified by Language, then EFI_UNSUPPORTED is
> returned.
> > +
> > +  @param  This[in]              A pointer to the
> EFI_COMPONENT_NAME2_PROTOCOL or
> > +                                EFI_COMPONENT_NAME_PROTOCOL instance.
> > +
> > +  @param  ControllerHandle[in]  The handle of a controller that the driver
> > +                                specified by This is managing.  This handle
> > +                                specifies the controller whose name is to be
> > +                                returned.
> > +
> > +  @param  ChildHandle[in]       The handle of the child controller to
> retrieve
> > +                                the name of.  This is an optional parameter that
> > +                                may be NULL.  It will be NULL for device
> > +                                drivers.  It will also be NULL for a bus drivers
> > +                                that wish to retrieve the name of the bus
> > +                                controller.  It will not be NULL for a bus
> > +                                driver that wishes to retrieve the name of a
> > +                                child controller.
> > +
> > +  @param  Language[in]          A pointer to a Null-terminated ASCII string
> > +                                array indicating the language.  This is the
> > +                                language of the driver name that the caller is
> > +                                requesting, and it must match one of the
> > +                                languages specified in SupportedLanguages. The
> > +                                number of languages supported by a driver is up
> > +                                to the driver writer. Language is specified in
> > +                                RFC 4646 or ISO 639-2 language code format.
> > +
> > +  @param  ControllerName[out]   A pointer to the Unicode string to
> return.
> > +                                This Unicode string is the name of the
> > +                                controller specified by ControllerHandle and
> > +                                ChildHandle in the language specified by
> > +                                Language from the point of view of the driver
> > +                                specified by This.
> > +
> > +  @retval EFI_SUCCESS           The Unicode string for the user readable
> name in
> > +                                the language specified by Language for the
> > +                                driver specified by This was returned in
> > +                                DriverName.
> > +
> > +  @retval EFI_INVALID_PARAMETER ControllerHandle is not a valid
> EFI_HANDLE.
> > +
> > +  @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a
> valid
> > +                                EFI_HANDLE.
> > +
> > +  @retval EFI_INVALID_PARAMETER Language is NULL.
> > +
> > +  @retval EFI_INVALID_PARAMETER ControllerName is NULL.
> > +
> > +  @retval EFI_UNSUPPORTED       The driver specified by This is not
> currently
> > +                                managing the controller specified by
> > +                                ControllerHandle and ChildHandle.
> > +
> > +  @retval EFI_UNSUPPORTED       The driver specified by This does not
> support
> > +                                the language specified by Language.
> > +
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +UsbDeviceDxeGetControllerName (
> > +  IN  EFI_COMPONENT_NAME_PROTOCOL                     *This,
> > +  IN  EFI_HANDLE                                      ControllerHandle,
> > +  IN  EFI_HANDLE                                      ChildHandle        OPTIONAL,
> > +  IN  CHAR8                                           *Language,
> > +  OUT CHAR16                                          **ControllerName
> > +  )
> > +{
> > +  return EFI_UNSUPPORTED;
> > +}
> > +
> > diff --git
> a/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbDeviceDxe.c
> b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbDeviceDxe.c
> > new file mode 100644
> > index 0000000000..2732cc2e31
> > --- /dev/null
> > +++
> b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbDeviceDxe.c
> > @@ -0,0 +1,395 @@
> > +/** @file
> > +  Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR>
> > +
> > +  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.
> > +
> > +**/
> > +
> > +#include "UsbDeviceDxe.h"
> > +#include <Guid/EventGroup.h>
> > +
> > +EFI_DRIVER_BINDING_PROTOCOL mUsbDeviceDxeDriverBinding = {
> > +  UsbDeviceDxeDriverSupported,
> > +  UsbDeviceDxeDriverStart,
> > +  UsbDeviceDxeDriverStop,
> > +  0x1,
> > +  NULL,
> > +  NULL
> > +};
> > +
> > +
> > +
> > +VOID
> > +EFIAPI
> > +PlatformSpecificInit (
> > +  VOID
> > +  )
> > +{
> > +  UINTN                 XhciPciMmBase;
> > +  EFI_PHYSICAL_ADDRESS  XhciMemBaseAddress;
> > +
> > +  XhciPciMmBase   = MmPciAddress (
> > +                      0,
> > +                      0,
> > +                      PCI_DEVICE_NUMBER_XHCI,
> > +                      PCI_FUNCTION_NUMBER_XHCI,
> > +                      0
> > +                      );
> > +
> > +
> > +  XhciMemBaseAddress = MmioRead32 ((UINTN) (XhciPciMmBase +
> R_XHCI_MEM_BASE)) & B_XHCI_MEM_BASE_BA;
> > +  DEBUG ((DEBUG_INFO, "XhciPciMmBase=%x,
> XhciMemBaseAddress=%x\n", XhciPciMmBase, XhciMemBaseAddress));
> > +
> > +  MmioWrite32 ((UINTN)(XhciMemBaseAddress +
> R_XHCI_MEM_DUAL_ROLE_CFG0), 0x1310800);
> > +
> > +  PmicUSBSwitchControl (TRUE);//conduction USB switch.
> > +  return;
> > +}
> > +
> > +
> > +VOID
> > +EFIAPI
> > +UsbDeviceDxeExitBootService (
> > +  EFI_EVENT  Event,
> > +  VOID       *Context
> > +  )
> > +{
> > +  USB_XDCI_DEV_CONTEXT  *UsbXdciDevContext;
> > +
> > +  UsbXdciDevContext = (USB_XDCI_DEV_CONTEXT *) Context;
> > +  DEBUG ((EFI_D_INFO, "UsbDeviceDxeExitBootService enter\n"));
> > +
> > +  if (UsbXdciDevContext->XdciPollTimer != NULL) {
> > +    gBS->SetTimer (UsbXdciDevContext->XdciPollTimer, TimerCancel, 0);
> > +    gBS->CloseEvent (UsbXdciDevContext->XdciPollTimer);
> > +    UsbXdciDevContext->XdciPollTimer = NULL;
> > +    }
> > +
> > +  return;
> > +}
> > +
> > +/**
> > +  The USB bus driver entry pointer.
> > +
> > +  @param ImageHandle       The driver image handle.
> > +  @param SystemTable       The system table.
> > +
> > +  @return EFI_SUCCESS      The component name protocol is installed.
> > +  @return Others           Failed to init the usb driver.
> > +
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +UsbDeviceDxeEntryPoint (
> > +  IN EFI_HANDLE           ImageHandle,
> > +  IN EFI_SYSTEM_TABLE     *SystemTable
> > +  )
> > +{
> > +  return EfiLibInstallDriverBindingComponentName2 (
> > +           ImageHandle,
> > +           SystemTable,
> > +           &mUsbDeviceDxeDriverBinding,
> > +           ImageHandle,
> > +           &mUsbDeviceDxeComponentName,
> > +           &mUsbDeviceDxeComponentName2
> > +           );
> > +}
> > +
> > +/**
> > +  Check whether USB bus driver support this device.
> > +
> > +  @param  This                   The USB bus driver binding protocol.
> > +  @param  Controller             The controller handle to check.
> > +  @param  RemainingDevicePath    The remaining device path.
> > +
> > +  @retval EFI_SUCCESS            The bus supports this controller.
> > +  @retval EFI_UNSUPPORTED        This device isn't supported.
> > +
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +UsbDeviceDxeDriverSupported (
> > +  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
> > +  IN EFI_HANDLE                   Controller,
> > +  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath
> > +  )
> > +{
> > +  EFI_STATUS                Status;
> > +  EFI_PCI_IO_PROTOCOL       *PciIo;
> > +  USB_CLASSC                UsbClassCReg;
> > +
> > +
> > +  Status = gBS->OpenProtocol (
> > +                  Controller,
> > +                  &gEfiPciIoProtocolGuid,
> > +                  (VOID **) &PciIo,
> > +                  This->DriverBindingHandle,
> > +                  Controller,
> > +                  EFI_OPEN_PROTOCOL_BY_DRIVER
> > +                  );
> > +
> > +  if (EFI_ERROR (Status)) {
> > +    return EFI_UNSUPPORTED;
> > +  }
> > +
> > +  Status = PciIo->Pci.Read (
> > +                        PciIo,
> > +                        EfiPciIoWidthUint8,
> > +                        PCI_CLASSCODE_OFFSET,
> > +                        sizeof (USB_CLASSC) / sizeof (UINT8),
> > +                        &UsbClassCReg
> > +                        );
> > +
> > +  if (EFI_ERROR (Status)) {
> > +    Status = EFI_UNSUPPORTED;
> > +    goto ON_EXIT;
> > +  }
> > +
> > +  //
> > +  // Test whether the controller belongs to USB device type
> > +  //
> > +  // 0x0C03FE / 0x0C0380
> > +  //
> > +  if ((UsbClassCReg.BaseCode != PCI_CLASS_SERIAL) ||
> > +      (UsbClassCReg.SubClassCode != PCI_CLASS_SERIAL_USB) ||
> > +      ((UsbClassCReg.ProgInterface != PCI_IF_USBDEV) &&
> (UsbClassCReg.ProgInterface != 0x80))) {
> > +    Status = EFI_UNSUPPORTED;
> > +  }
> > +
> > +ON_EXIT:
> > +  gBS->CloseProtocol (
> > +         Controller,
> > +         &gEfiPciIoProtocolGuid,
> > +         This->DriverBindingHandle,
> > +         Controller
> > +         );
> > +
> > +  return Status;
> > +}
> > +
> > +
> > +/**
> > +  Start to process the controller.
> > +
> > +  @param  This                   The USB bus driver binding instance.
> > +  @param  Controller             The controller to check.
> > +  @param  RemainingDevicePath    The remaining device patch.
> > +
> > +  @retval EFI_SUCCESS            The controller is controlled by the usb bus.
> > +  @retval EFI_ALREADY_STARTED    The controller is already controlled by
> the usb
> > +                                 bus.
> > +  @retval EFI_OUT_OF_RESOURCES   Failed to allocate resources.
> > +
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +UsbDeviceDxeDriverStart (
> > +  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
> > +  IN EFI_HANDLE                   Controller,
> > +  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath
> > +  )
> > +{
> > +  EFI_STATUS            Status;
> > +  USB_XDCI_DEV_CONTEXT  *UsbXdciDevContext;
> > +  EFI_PCI_IO_PROTOCOL   *PciIo;
> > +  EFI_EVENT             ExitBootServicesEvent;
> > +
> > +  DEBUG ((USB_FUIO_DEBUG_LOAD, "UsbFunIoEntryPoint - Entry\n"));
> > +
> > +  UsbXdciDevContext = NULL;
> > +
> > +  //
> > +  // Provide protocol interface
> > +  //
> > +  //
> > +  // Get the PCI I/O Protocol on PciHandle
> > +  //
> > +  Status = gBS->OpenProtocol (
> > +                  Controller,
> > +                  &gEfiPciIoProtocolGuid,
> > +                  (VOID **) &PciIo,
> > +                  This->DriverBindingHandle,
> > +                  Controller,
> > +                  EFI_OPEN_PROTOCOL_BY_DRIVER
> > +                  );
> > +
> > +  if (EFI_ERROR (Status)) {
> > +    goto ErrorExit;
> > +  }
> > +
> > +  UsbXdciDevContext = AllocateZeroPool (sizeof
> (USB_XDCI_DEV_CONTEXT));
> > +  if (UsbXdciDevContext == NULL) {
> > +    Status = EFI_OUT_OF_RESOURCES;
> > +    goto ErrorExit;
> > +  }
> > +
> > +  //
> > +  // Initialize the driver context
> > +  //
> > +  UsbXdciDevContext->StartUpController = FALSE;
> > +  UsbXdciDevContext->XdciHandle = Controller;
> > +  UsbXdciDevContext->FirstNodePtr = NULL;
> > +  UsbXdciDevContext->Signature = EFI_USB_DEV_SIGNATURE;
> > +
> > +  PciIo->Pci.Read (
> > +               PciIo,
> > +               EfiPciIoWidthUint32,
> > +               R_OTG_BAR0,
> > +               1,
> > +               &UsbXdciDevContext->XdciMmioBarAddr
> > +               );
> > +
> > +  UsbXdciDevContext->XdciMmioBarAddr &= B_OTG_BAR0_BA;
> > +  DEBUG ((USB_FUIO_DEBUG_INFO, "USB DEV mode IO addr 0x%08x\n",
> UsbXdciDevContext->XdciMmioBarAddr));
> > +
> > +  CopyMem (
> > +    &(UsbXdciDevContext->UsbFunIoProtocol),
> > +    &mUsbFunIoProtocol,
> > +    sizeof (EFI_USBFN_IO_PROTOCOL)
> > +    );
> > +
> > +  CopyMem (
> > +    &(UsbXdciDevContext->UsbDevModeProtocol),
> > +    &mUsbDeviceModeProtocol,
> > +    sizeof (EFI_USB_DEVICE_MODE_PROTOCOL)
> > +    );
> > +
> > +  Status = gBS->CreateEventEx (
> > +                  EVT_NOTIFY_SIGNAL,
> > +                  TPL_NOTIFY,
> > +                  UsbDeviceDxeExitBootService,
> > +                  UsbXdciDevContext,
> > +                  &gEfiEventExitBootServicesGuid,
> > +                  &ExitBootServicesEvent
> > +                  );
> > +  if (EFI_ERROR (Status)) {
> > +    goto ErrorExit;
> > +  }
> > +
> > +  Status = gBS->InstallMultipleProtocolInterfaces (
> > +                  &UsbXdciDevContext->XdciHandle,
> > +                  &gEfiUsbFnIoProtocolGuid,
> > +                  &UsbXdciDevContext->UsbFunIoProtocol,
> > +                  &gEfiUsbDeviceModeProtocolGuid,
> > +                  &UsbXdciDevContext->UsbDevModeProtocol,
> > +                  NULL
> > +                  );
> > +  if (EFI_ERROR (Status)) {
> > +    DEBUG ((USB_FUIO_DEBUG_ERROR, "ERROR - Failed to install upper
> protocol, Status: %r\n", Status));
> > +    goto ErrorExit;
> > +  }
> > +
> > +  DEBUG ((USB_FUIO_DEBUG_LOAD, "Done - install upper protocol
> complete\n"));
> > +  DEBUG ((USB_FUIO_DEBUG_LOAD, "UsbFunIoEntryPoint - Exit\n"));
> > +  return Status;
> > +
> > +ErrorExit:
> > +  gBS->CloseProtocol (
> > +         Controller,
> > +         &gEfiPciIoProtocolGuid,
> > +         This->DriverBindingHandle,
> > +         Controller
> > +         );
> > +
> > +  if (UsbXdciDevContext != NULL) {
> > +    if (UsbXdciDevContext->XdciPollTimer != NULL) {
> > +      gBS->CloseEvent (UsbXdciDevContext->XdciPollTimer);
> > +      UsbXdciDevContext->XdciPollTimer = NULL;
> > +    }
> > +    FreePool (UsbXdciDevContext);
> > +  }
> > +
> > +  DEBUG ((USB_FUIO_DEBUG_ERROR, "ERROR - UsbFunIoEntryPoint -
> Exit\n"));
> > +  return Status;
> > +}
> > +
> > +/**
> > +  Stop handle the controller by this USB bus driver.
> > +
> > +  @param  This                   The USB bus driver binding protocol.
> > +  @param  Controller             The controller to release.
> > +  @param  NumberOfChildren       The child of USB bus that opened
> controller
> > +                                 BY_CHILD.
> > +  @param  ChildHandleBuffer      The array of child handle.
> > +
> > +  @retval EFI_SUCCESS            The controller or children are stopped.
> > +  @retval EFI_DEVICE_ERROR       Failed to stop the driver.
> > +
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +UsbDeviceDxeDriverStop (
> > +  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
> > +  IN EFI_HANDLE                   Controller,
> > +  IN UINTN                        NumberOfChildren,
> > +  IN EFI_HANDLE                   *ChildHandleBuffer
> > +  )
> > +{
> > +  EFI_USBFN_IO_PROTOCOL           *UsbFunIoProtocol;
> > +  EFI_STATUS                      Status;
> > +  USB_XDCI_DEV_CONTEXT            *UsbXdciDevContext;
> > +
> > +
> > +  //
> > +  // Locate USB_BUS for the current host controller
> > +  //
> > +  Status = gBS->OpenProtocol (
> > +                  Controller,
> > +                  &gEfiUsbFnIoProtocolGuid,
> > +                  (VOID **)&UsbFunIoProtocol,
> > +                  This->DriverBindingHandle,
> > +                  Controller,
> > +                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
> > +                  );
> > +
> > +
> > +  if (EFI_ERROR (Status)) {
> > +    return Status;
> > +  }
> > +
> > +  UsbXdciDevContext = USBFUIO_CONTEXT_FROM_PROTOCOL
> (UsbFunIoProtocol);
> > +
> > +  //
> > +  // free pool
> > +  //
> > +  while (UsbXdciDevContext->FirstNodePtr != NULL) {
> > +    RemoveNode (UsbFunIoProtocol, UsbXdciDevContext->FirstNodePtr);
> > +  }
> > +
> > +  Status = gBS->UninstallMultipleProtocolInterfaces (
> > +                  UsbXdciDevContext->XdciHandle,
> > +                  &gEfiUsbFnIoProtocolGuid,
> > +                  &UsbXdciDevContext->UsbFunIoProtocol,
> > +                  &gEfiUsbDeviceModeProtocolGuid,
> > +                  &UsbXdciDevContext->UsbDevModeProtocol,
> > +                  NULL
> > +                  );
> > +
> > +  if (UsbXdciDevContext->StartUpController == TRUE) {
> > +    Status = StopController (UsbFunIoProtocol);
> > +    DEBUG ((USB_FUIO_DEBUG_INFO, "USB DEV mode STOP
> UsbFnDeInitDevice %r\n", Status));
> > +  }
> > +
> > +  if (UsbXdciDevContext->XdciPollTimer != NULL) {
> > +    gBS->SetTimer (UsbXdciDevContext->XdciPollTimer, TimerCancel, 0);
> > +    gBS->CloseEvent (UsbXdciDevContext->XdciPollTimer);
> > +    UsbXdciDevContext->XdciPollTimer = NULL;
> > +  }
> > +
> > +  gBS->CloseProtocol (
> > +         Controller,
> > +         &gEfiPciIoProtocolGuid,
> > +         This->DriverBindingHandle,
> > +         Controller
> > +         );
> > +
> > +  FreePool (UsbXdciDevContext);
> > +  return EFI_SUCCESS;
> > +}
> > +
> > diff --git
> a/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbDeviceDxe.h
> b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbDeviceDxe.h
> > new file mode 100644
> > index 0000000000..36620f9b12
> > --- /dev/null
> > +++
> b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbDeviceDxe.h
> > @@ -0,0 +1,159 @@
> > +/** @file
> > +  Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR>
> > +
> > +  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.
> > +
> > +**/
> > +
> > +#ifndef __USB_DEVICE_DXE_H__
> > +#define __USB_DEVICE_DXE_H__
> > +
> > +#include <Uefi.h>
> > +#include <Library/BaseMemoryLib.h>
> > +#include <Library/DevicePathLib.h>
> > +#include <Library/DriverLib.h>
> > +#include <Library/PcdLib.h>
> > +#include <Library/IoLib.h>
> > +#include <Protocol/EfiUsbFnIo.h>
> > +#include <Protocol/UsbDeviceModeProtocol.h>
> > +#include <PlatformBaseAddresses.h>
> > +#include <ScAccess.h>
> > +#include "UsbFuncIo.h"
> > +#include "UsbDeviceMode.h"
> > +
> > +
> > +#define PCI_IF_USBDEV                      0xFE
> > +
> > +#define EFI_USB_DEV_SIGNATURE              0x55534244 //"USBD"
> > +#define USBFUIO_CONTEXT_FROM_PROTOCOL(a)   CR (a,
> USB_XDCI_DEV_CONTEXT, UsbFunIoProtocol, EFI_USB_DEV_SIGNATURE)
> > +#define USBUSBD_CONTEXT_FROM_PROTOCOL(a)   CR (a,
> USB_XDCI_DEV_CONTEXT, UsbDevModeProtocol, EFI_USB_DEV_SIGNATURE)
> > +
> > +
> > +typedef struct _USB_FUIO_EVENT_NODE   USB_FUIO_EVENT_NODE;
> > +
> > +#pragma pack(1)
> > +struct _USB_FUIO_EVENT_NODE{
> > +  EFI_USBFN_MESSAGE            Message;
> > +  UINTN                        PayloadSize;
> > +  EFI_USBFN_MESSAGE_PAYLOAD    Payload;
> > +  USB_FUIO_EVENT_NODE          *Nextptr;
> > +};
> > +
> > +typedef struct {
> > +  UINTN                         Signature;
> > +  UINTN                         XdciMmioBarAddr;
> > +  EFI_HANDLE                    XdciHandle;
> > +  //
> > +  // Timer to handle EndPoint event periodically.
> > +  //
> > +  EFI_EVENT                     XdciPollTimer;
> > +  EFI_USB_DEVICE_MODE_PROTOCOL  UsbDevModeProtocol;
> > +  EFI_USBFN_IO_PROTOCOL         UsbFunIoProtocol;
> > +
> > +  //
> > +  // Structure members used by UsbFunIoProtocol.
> > +  //
> > +  USB_MEM_NODE                  *FirstNodePtr;
> > +  EFI_USB_DEVICE_INFO           *DevInfoPtr;
> > +  EFI_USB_CONFIG_INFO           IndexPtrConfig;
> > +  EFI_USB_INTERFACE_INFO        IndexPtrInteface;
> > +  USB_DEVICE_ENDPOINT_INFO      IndexPtrInEp;
> > +  USB_DEVICE_ENDPOINT_INFO      IndexPtrOutEp;
> > +  XDCI_CORE_HANDLE              *XdciDrvIfHandle;
> > +  USB_DEV_CORE                  *DrvCore;
> > +  UINT16                        VendorId;
> > +  UINT16                        DeviceId;
> > +  USBD_EP_XFER_REC
> EndPointXferRec[DWC_XDCI_MAX_ENDPOINTS];
> > +  BOOLEAN                       StartUpController;
> > +  BOOLEAN                       DevReConnect;
> > +  BOOLEAN                       DevResetFlag;
> > +  EFI_EVENT                     TimerEvent;
> > +  USB_FUIO_EVENT_NODE           *EventNodePtr;
> > +  //
> > +  // Following structure members are used by UsbDevModeProtocol.
> > +  //
> > +
> > +} USB_XDCI_DEV_CONTEXT;
> > +#pragma pack()
> > +
> > +
> > +
> > +/**
> > +  Check whether USB bus driver support this device.
> > +
> > +  @param  This                   The USB bus driver binding protocol.
> > +  @param  Controller             The controller handle to check.
> > +  @param  RemainingDevicePath    The remaining device path.
> > +
> > +  @retval EFI_SUCCESS            The bus supports this controller.
> > +  @retval EFI_UNSUPPORTED        This device isn't supported.
> > +
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +UsbDeviceDxeDriverSupported (
> > +  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
> > +  IN EFI_HANDLE                   Controller,
> > +  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath
> > +  );
> > +
> > +/**
> > +  Start to process the controller.
> > +
> > +  @param  This                   The USB bus driver binding instance.
> > +  @param  Controller             The controller to check.
> > +  @param  RemainingDevicePath    The remaining device patch.
> > +
> > +  @retval EFI_SUCCESS            The controller is controlled by the usb bus.
> > +  @retval EFI_ALREADY_STARTED    The controller is already controlled by
> the usb
> > +                                 bus.
> > +  @retval EFI_OUT_OF_RESOURCES   Failed to allocate resources.
> > +
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +UsbDeviceDxeDriverStart (
> > +  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
> > +  IN EFI_HANDLE                   Controller,
> > +  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath
> > +  );
> > +
> > +/**
> > +  Stop handle the controller by this USB bus driver.
> > +
> > +  @param  This                   The USB bus driver binding protocol.
> > +  @param  Controller             The controller to release.
> > +  @param  NumberOfChildren       The child of USB bus that opened
> controller
> > +                                 BY_CHILD.
> > +  @param  ChildHandleBuffer      The array of child handle.
> > +
> > +  @retval EFI_SUCCESS            The controller or children are stopped.
> > +  @retval EFI_DEVICE_ERROR       Failed to stop the driver.
> > +
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +UsbDeviceDxeDriverStop (
> > +  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
> > +  IN EFI_HANDLE                   Controller,
> > +  IN UINTN                        NumberOfChildren,
> > +  IN EFI_HANDLE                   *ChildHandleBuffer
> > +  );
> > +
> > +VOID
> > +EFIAPI
> > +PlatformSpecificInit (
> > +  VOID
> > +  );
> > +
> > +extern EFI_COMPONENT_NAME_PROTOCOL
> mUsbDeviceDxeComponentName;
> > +extern EFI_COMPONENT_NAME2_PROTOCOL
> mUsbDeviceDxeComponentName2;
> > +
> > +#endif
> > +
> > diff --git
> a/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbDeviceDxe.inf
> b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbDeviceDxe.inf
> > new file mode 100644
> > index 0000000000..acf5021327
> > --- /dev/null
> > +++
> b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbDeviceDxe.inf
> > @@ -0,0 +1,74 @@
> > +## @file
> > +#
> > +#  Copyright (c) 2008 - 2017, Intel Corporation. All rights reserved.<BR>
> > +#
> > +#  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.
> > +#
> > +##
> > +
> > +[Defines]
> > +  INF_VERSION                    = 0x00010005
> > +  BASE_NAME                      = UsbDeviceDxe
> > +  FILE_GUID                      = 42CF2D4A-78B4-4B80-80F9-96A83A630D70
> > +  MODULE_TYPE                    = UEFI_DRIVER
> > +  VERSION_STRING                 = 1.0
> > +  ENTRY_POINT                    = UsbDeviceDxeEntryPoint
> > +
> > +#
> > +# The following information is for reference only and not required by the
> build tools.
> > +#
> > +#  VALID_ARCHITECTURES           = IA32 X64
> > +#
> > +
> > +[Sources.common]
> > +  UsbDeviceDxe.c
> > +  UsbFuncIo.c
> > +  UsbIoNode.c
> > +  ComponentName.c
> > +  UsbDeviceMode.c
> > +  XdciDevice.c
> > +  XdciDWC.c
> > +  XdciTable.c
> > +  XdciUtility.c
> > +
> > +[Packages]
> > +  MdePkg/MdePkg.dec
> > +  BroxtonSiPkg/BroxtonSiPkg.dec
> > +  BroxtonPlatformPkg/PlatformPkg.dec
> > +
> > +[LibraryClasses]
> > +  BaseMemoryLib
> > +  DebugLib
> > +  DevicePathLib
> > +  MemoryAllocationLib
> > +  TimerLib
> > +  PcdLib
> > +  UefiBootServicesTableLib
> > +  UefiDriverEntryPoint
> > +  UefiLib
> > +  PmicLib
> > +
> > +[Protocols]
> > +  gEfiUsbDeviceModeProtocolGuid
> > +  gEfiUsbFnIoProtocolGuid
> > +  gEfiPciIoProtocolGuid
> > +
> > +[Pcd]
> > +  gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress
> > +
> > +[Guids]
> > +  gEfiEventExitBootServicesGuid
> > +
> > +#[BuildOptions]
> > +#  MSFT:*_*_*_CC_FLAGS = /D SUPPORT_SUPER_SPEED
> > +#  GCC:*_*_*_CC_FLAGS = -DSUPPORT_SUPER_SPEED
> > +
> > +[Depex]
> > +  TRUE
> > +
> > diff --git
> a/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbDeviceMode.c
> b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbDeviceMode.c
> > new file mode 100644
> > index 0000000000..48a37a37fb
> > --- /dev/null
> > +++
> b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbDeviceMode.c
> > @@ -0,0 +1,1489 @@
> > +/** @file
> > +  Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR>
> > +
> > +  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.
> > +
> > +**/
> > +
> > +#include <Base.h>
> > +#include <Library/BaseLib.h>
> > +#include <Library/UefiBootServicesTableLib.h>
> > +#include <Library/IoLib.h>
> > +#include <PlatformBaseAddresses.h>
> > +#include <ScAccess.h>
> > +#include "XdciUtility.h"
> > +#include "UsbDeviceMode.h"
> > +#include "UsbDeviceDxe.h"
> > +
> > +//
> > +// Global USBD driver object. This is the main private driver object
> > +// that contains all data needed for this driver to operate.
> > +//
> > +USB_DEVICE_DRIVER_OBJ mDrvObj;
> > +
> > +//
> > +// Global data IO transaction request object
> > +//
> > +USB_DEVICE_IO_REQ  mCtrlIoReq = {
> > +  //
> > +  // IO information containing the Buffer and data size
> > +  //
> > +  {
> > +    NULL,
> > +    0,
> > +  },
> > +  //
> > +  // Note: This object is used for Control Ep transfers only
> > +  // therefore the endpoint info must always be NULL
> > +  //
> > +  {
> > +    NULL,
> > +    NULL,
> > +  }
> > +};
> > +
> > +//
> > +// global flag to signal device event processing loop to run/stop
> > +//
> > +BOOLEAN mXdciRun = FALSE;
> > +
> > +STATIC VOID
> > +XhciSwitchSwid(BOOLEAN enable)
> > +{
> > +  UINTN                             XhciPciMmBase;
> > +  EFI_PHYSICAL_ADDRESS              XhciMemBaseAddress;
> > +  UINT32                            DualRoleCfg0;
> > +  UINT32                            DualRoleCfg1;
> > +
> > +  XhciPciMmBase = MmPciAddress (0, 0, PCI_DEVICE_NUMBER_XHCI,
> PCI_FUNCTION_NUMBER_XHCI, 0);
> > +  XhciMemBaseAddress = MmioRead32 ((UINTN) (XhciPciMmBase +
> R_XHCI_MEM_BASE)) & B_XHCI_MEM_BASE_BA;
> > +  DEBUG ((DEBUG_INFO, "XhciPciMmBase=%x,
> XhciMemBaseAddress=%x\n", XhciPciMmBase, XhciMemBaseAddress));
> > +
> > +  DualRoleCfg0 = MmioRead32 ((UINTN)(XhciMemBaseAddress +
> R_XHCI_MEM_DUAL_ROLE_CFG0));
> > +  if (enable) {
> > +    DualRoleCfg0 = DualRoleCfg0 | (1 << 24) | (1 << 21) | (1 << 20);
> > +    DEBUG ((DEBUG_INFO, "DualRoleCfg0 : Set SW ID : 0x%x \n",
> DualRoleCfg0));
> > +  }
> > +  else {
> > +    DualRoleCfg0 = DualRoleCfg0 & ~(1 << 24) & ~(1 << 21) & ~(1 << 20);
> > +    DEBUG ((DEBUG_INFO, "DualRoleCfg0 : Clear SW ID : 0x%x \n",
> DualRoleCfg0));
> > +  }
> > +  MmioWrite32 ((UINTN)(XhciMemBaseAddress +
> R_XHCI_MEM_DUAL_ROLE_CFG0), DualRoleCfg0);
> > +
> > +  DualRoleCfg1 = MmioRead32 ((UINTN)(XhciMemBaseAddress +
> R_XHCI_MEM_DUAL_ROLE_CFG1));
> > +  DEBUG ((DEBUG_INFO, "DualRoleCfg1 : 0x%x \n", DualRoleCfg1));
> > +}
> > +
> > +VOID
> > +EFIAPI
> > +UsbdMonitorEvents (
> > +  IN EFI_EVENT            Event,
> > +  IN VOID                 *Context
> > +  )
> > +{
> > +  USB_XDCI_DEV_CONTEXT    *XdciDevContext;
> > +  UINT32                  EventCount;
> > +  UINT32                  PreEventCount;
> > +  UINT32                  LoopCount;
> > +
> > +  XdciDevContext = (USB_XDCI_DEV_CONTEXT *) Context;
> > +  EventCount = UsbRegRead ((UINT32)XdciDevContext->XdciMmioBarAddr,
> DWC_XDCI_EVNTCOUNT_REG (0));
> > +  if (EventCount == 0) {
> > +    return;
> > +  }
> > +
> > +  LoopCount = 0;
> > +  PreEventCount = EventCount;
> > +  while (EventCount != 0) {
> > +    if (UsbDeviceIsrRoutineTimerBased (mDrvObj.XdciDrvObj) !=
> EFI_SUCCESS) {
> > +      DEBUG ((DEBUG_INFO, "UsbDeviceRun() - Failed to execute event
> ISR\n"));
> > +    }
> > +    EventCount = UsbRegRead ((UINT32)XdciDevContext-
> >XdciMmioBarAddr, DWC_XDCI_EVNTCOUNT_REG (0));
> > +    if (PreEventCount == EventCount) {
> > +      LoopCount++;
> > +      if (LoopCount >= 5) {
> > +        DEBUG ((DEBUG_INFO, "USB is working on a long event...\n"));
> > +        break;
> > +      }
> > +    } else {
> > +      LoopCount = 0;
> > +    }
> > +  }
> > +
> > +  return;
> > +}
> > +
> > +/**
> > +  Initializes the XDCI core
> > +
> > +  @param MmioBar       Address of MMIO BAR
> > +  @param XdciHndl      Double pointer to for XDCI layer to set as an
> > +                       opaque handle to the driver to be used in subsequent
> > +                       interactions with the XDCI layer.
> > +
> > +  @return EFI_SUCCESS if successfully initialized XDCI, EFI_DEVICE_ERROR
> otherwise
> > +
> > +**/
> > +EFI_STATUS
> > +UsbdInit (
> > +  IN UINT32    MmioBar,
> > +  IN VOID      **XdciHndl
> > +  )
> > +{
> > +  EFI_STATUS               Status = EFI_DEVICE_ERROR;
> > +  USB_DEV_CONFIG_PARAMS    ConfigParams;
> > +
> > +  XhciSwitchSwid(TRUE);
> > +
> > +  DEBUG ((DEBUG_INFO, "UsbdInit start\n"));
> > +  ConfigParams.ControllerId = USB_ID_DWC_XDCI;
> > +  ConfigParams.BaseAddress  = MmioBar;
> > +  ConfigParams.Role = USB_ROLE_DEVICE;
> > +  ConfigParams.Speed = USB_SPEED_SUPER;
> > +
> > +  Status = UsbDeviceInit (&ConfigParams, XdciHndl);
> > +
> > +  DEBUG ((DEBUG_INFO, "UsbdInit status is %x\n", Status));
> > +  DEBUG ((DEBUG_INFO, "ConfigParams.BaseAddress 0x%x\n",
> ConfigParams.BaseAddress));
> > +
> > +  return Status;
> > +}
> > +
> > +
> > +/**
> > +  Copies relevant endpoint data from standard USB endpoint descriptors
> > +  to the usbEpInfo structure used by the XDCI
> > +
> > +  @param EpDest   destination structure
> > +  @param EpSrc    source structure
> > +
> > +  @return VOID
> > +
> > +**/
> > +VOID
> > +UsbdSetEpInfo (
> > +  IN USB_EP_INFO                 *EpDest,
> > +  IN USB_DEVICE_ENDPOINT_INFO    *EpSrc
> > +  )
> > +{
> > +  EFI_USB_ENDPOINT_DESCRIPTOR              *EpDesc = NULL;
> > +  EFI_USB_ENDPOINT_COMPANION_DESCRIPTOR    *EpCompDesc = NULL;
> > +
> > +  //
> > +  // start by clearing all data in the destination
> > +  //
> > +  SetMem (EpDest, sizeof(USB_EP_INFO), 0);
> > +  EpDesc = EpSrc->EndpointDesc;
> > +  EpCompDesc = EpSrc->EndpointCompDesc;
> > +
> > +  if (EpDesc != NULL) {
> > +    EpDest->EpNum = EpDesc->EndpointAddress & 0x0F; //Bits 0-3 are ep
> num
> > +    EpDest->EpDir = ((EpDesc->EndpointAddress & USB_ENDPOINT_DIR_IN)
> > 0) ? UsbEpDirIn : UsbEpDirOut;
> > +    EpDest->EpType = EpDesc->Attributes & USB_ENDPOINT_TYPE_MASK;
> > +    EpDest->MaxPktSize = EpDesc->MaxPacketSize;
> > +    EpDest->Interval = EpDesc->Interval;
> > +  }
> > +  if (EpCompDesc != NULL) {
> > +    EpDest->MaxStreams = EpCompDesc->Attributes &
> USB_EP_BULK_BM_ATTR_MASK;
> > +    EpDest->BurstSize = EpCompDesc->MaxBurst;
> > +    EpDest->Mult = EpCompDesc->BytesPerInterval;
> > +  }
> > +
> > +  return;
> > +}
> > +
> > +
> > +/**
> > +  Initializes the given endpoint
> > +
> > +  @param XdciHndl  Pointer (handle) to the XDCI driver object
> > +  @param DevEpInfo Pointer to endpoint info structure
> > +                   for the endpoint to initialize
> > +
> > +  @return EFI_SUCCESS if operation succeeded, EFI_DEVICE_ERROR
> otherwise
> > +
> > +**/
> > +EFI_STATUS
> > +UsbdInitEp (
> > +  IN VOID                      *XdciHndl,
> > +  IN USB_DEVICE_ENDPOINT_INFO  *DevEpInfo
> > +  )
> > +{
> > +  EFI_STATUS   Status = EFI_DEVICE_ERROR;
> > +  USB_EP_INFO  EpInfo;
> > +
> > +  UsbdSetEpInfo (&EpInfo, DevEpInfo);
> > +  Status = UsbDeviceInitEp (XdciHndl, &EpInfo);
> > +
> > +  return Status;
> > +}
> > +
> > +
> > +/**
> > +  Callback handler used when transfer operations complete. Calls
> > +  upper layer routine to handle the operation.
> > +
> > +  @param XdciHndl  Pointer (handle) to the XDCI driver object
> > +  @param XferReq   Pointer to the transfer request structure
> > +
> > +  @return VOID
> > +
> > +**/
> > +VOID
> > +EFIAPI
> > +UsbdXferDoneHndlr (
> > +  IN VOID                    *XdciHndl,
> > +  IN USB_XFER_REQUEST        *XferReq
> > +  )
> > +{
> > +  EFI_USB_DEVICE_XFER_INFO  XferInfo;
> > +
> > +  DEBUG ((DEBUG_INFO, "UsbdXferDoneHndlr\n"));
> > +
> > +  XferInfo.EndpointNum = (UINT8)XferReq->EpInfo.EpNum;
> > +  XferInfo.EndpointDir = XferReq->EpInfo.EpDir;
> > +  XferInfo.EndpointType = XferReq->EpInfo.EpType;
> > +  XferInfo.Buffer = XferReq->XferBuffer;
> > +  XferInfo.Length = XferReq->ActualXferLen;
> > +
> > +  //
> > +  // If this is a non-control transfer complete, notify the class driver
> > +  //
> > +  if (XferInfo.EndpointNum > 0) {
> > +    if (mDrvObj.UsbdDevObj->DataCallback != NULL) {
> > +      mDrvObj.UsbdDevObj->DataCallback (&XferInfo);
> > +    }
> > +  }
> > +
> > +  return;
> > +}
> > +
> > +
> > +/**
> > +  Queue a request to transmit data
> > +
> > +  @param XdciHndl  Pointer (handle) to the XDCI driver object
> > +  @param IoReq     Pointer to IO structure containing details of the
> > +                   transfer request
> > +
> > +  @return EFI_SUCCESS if operation succeeded, EFI_DEVICE_ERROR
> otherwise
> > +
> > +**/
> > +EFI_STATUS
> > +UsbdEpTxData (
> > +  IN VOID               *XdciHndl,
> > +  IN USB_DEVICE_IO_REQ  *IoReq
> > +  )
> > +{
> > +  EFI_STATUS        Status = EFI_DEVICE_ERROR;
> > +  USB_XFER_REQUEST  TxReq;
> > +
> > +  //
> > +  //set endpoint data
> > +  //
> > +  UsbdSetEpInfo (&(TxReq.EpInfo), &(IoReq->EndpointInfo)); // set
> endpoint data
> > +
> > +  //
> > +  //if this is a control endpoint, set the number and direction
> > +  //
> > +  if (IoReq->EndpointInfo.EndpointDesc == NULL) {
> > +    TxReq.EpInfo.EpNum = 0;
> > +    TxReq.EpInfo.EpDir = UsbEpDirIn;
> > +  }
> > +
> > +  //
> > +  // setup the trasfer request
> > +  //
> > +  TxReq.XferBuffer = IoReq->IoInfo.Buffer;
> > +  TxReq.XferLen = IoReq->IoInfo.Length;
> > +  TxReq.XferDone = UsbdXferDoneHndlr;
> > +
> > +  DEBUG ((DEBUG_INFO,  "TX REQUEST: EpNum: 0x%x, epDir: 0x%x,
> epType: 0x%x, MaxPktSize: 0x%x\n",\
> > +          TxReq.EpInfo.EpNum, TxReq.EpInfo.EpDir, TxReq.EpInfo.EpType,
> TxReq.EpInfo.MaxPktSize));
> > +
> > +  Status = UsbXdciDeviceEpTxData (XdciHndl, &TxReq);
> > +
> > +  return Status;
> > +}
> > +
> > +
> > +/**
> > +  Queue a request to receive data
> > +
> > +  @param XdciHndl  Pointer (handle) to the XDCI driver object
> > +  @param IoReq     Pointer to IO structure containing details of the
> > +                   receive request
> > +
> > +  @return EFI_SUCCESS if operation succeeded, EFI_DEVICE_ERROR
> otherwise
> > +
> > +**/
> > +EFI_STATUS
> > +UsbdEpRxData (
> > +  IN VOID               *XdciHndl,
> > +  IN USB_DEVICE_IO_REQ  *IoReq
> > +  )
> > +{
> > +  EFI_STATUS        Status = EFI_DEVICE_ERROR;
> > +  USB_XFER_REQUEST  RxReq;
> > +  UINT32            ReqPacket;
> > +
> > +  DEBUG ((DEBUG_INFO,  "RX REQUEST in: IoReq->IoInfo.Length: 0x%x\n",
> IoReq->IoInfo.Length));
> > +  DEBUG ((DEBUG_INFO,  "RX REQUEST in: MaxPacketSize: 0x%x\n", IoReq-
> >EndpointInfo.EndpointDesc->MaxPacketSize));
> > +
> > +  if (IoReq->EndpointInfo.EndpointDesc->MaxPacketSize == 0) {
> > +    return EFI_DEVICE_ERROR;
> > +  }
> > +
> > +  //
> > +  // set endpoint data
> > +  //
> > +  UsbdSetEpInfo (&(RxReq.EpInfo), &(IoReq->EndpointInfo));
> > +
> > +  //
> > +  // setup the trasfer request
> > +  //
> > +  RxReq.XferBuffer = IoReq->IoInfo.Buffer;
> > +
> > +  //
> > +  // Transfer length should be multiple of USB packet size.
> > +  //
> > +  ReqPacket = IoReq->IoInfo.Length / IoReq->EndpointInfo.EndpointDesc-
> >MaxPacketSize;
> > +  ReqPacket = ((IoReq->IoInfo.Length % IoReq-
> >EndpointInfo.EndpointDesc->MaxPacketSize) == 0)? ReqPacket : ReqPacket
> + 1;
> > +  RxReq.XferLen = ReqPacket * IoReq->EndpointInfo.EndpointDesc-
> >MaxPacketSize;
> > +
> > +  RxReq.XferDone = UsbdXferDoneHndlr;
> > +
> > +  DEBUG ((DEBUG_INFO,  "RX REQUEST: EpNum: 0x%x, epDir: 0x%x,
> epType: 0x%x\n",\
> > +          RxReq.EpInfo.EpNum, RxReq.EpInfo.EpDir, RxReq.EpInfo.EpType));
> > +  DEBUG ((DEBUG_INFO,  "RX REQUEST send: XferLen: 0x%x\n",
> RxReq.XferLen));
> > +
> > +  Status = UsbXdciDeviceEpRxData (XdciHndl, &RxReq);
> > +
> > +  return Status;
> > +}
> > +
> > +
> > +/**
> > +  Callback used to handle Reset events from the XDCI
> > +
> > +  @param Param Pointer to a generic callback parameter structure
> > +
> > +  @return XDCI usb status
> > +
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +UsbdResetEvtHndlr (
> > +  IN USB_DEVICE_CALLBACK_PARAM  *Param
> > +  )
> > +{
> > +  EFI_STATUS    Status = EFI_DEVICE_ERROR;
> > +
> > +  DEBUG ((DEBUG_INFO, "UsbdResetEvtHndlr\n"));
> > +
> > +  //
> > +  // reset device address to 0
> > +  //
> > +  Status = UsbDeviceSetAddress (mDrvObj.XdciDrvObj, 0x0);
> > +  if (EFI_ERROR (Status)) {
> > +    DEBUG ((DEBUG_INFO, "UsbdResetHdlr() - Failed to set address in
> XDCI\n"));
> > +  }
> > +
> > +  return Status;
> > +}
> > +
> > +
> > +/**
> > +  Callback used to handle Connection done events from the XDCI
> > +
> > +  @param Param Pointer to a generic callback parameter structure
> > +
> > +  @return XDCI usb status
> > +
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +UsbdConnDoneEvtHndlr (
> > +  IN USB_DEVICE_CALLBACK_PARAM *Param
> > +  )
> > +{
> > +  EFI_STATUS    Status = EFI_DEVICE_ERROR;
> > +
> > +  DEBUG ((DEBUG_INFO, "UsbdConnDoneEvtHndlr\n"));
> > +
> > +  //
> > +  //reset device address to 0
> > +  //
> > +  Status = UsbDeviceSetAddress (mDrvObj.XdciDrvObj, 0x0);
> > +  if (EFI_ERROR (Status)) {
> > +    DEBUG ((DEBUG_INFO, "UsbdConnDoneHdlr() - Failed to set address in
> XDCI\n"));
> > +  }
> > +
> > +  //
> > +  // set the device state to attached/connected
> > +  //
> > +  mDrvObj.State = UsbDevStateAttached;
> > +
> > +  return Status;
> > +}
> > +
> > +
> > +/**
> > +  Callback used to handle Control Endpoint Setup events from the XDCI
> > +
> > +  @param Param Pointer to a generic callback parameter structure
> > +
> > +  @return XDCI usb status
> > +
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +UsbdSetupEvtHndlr (
> > +  IN USB_DEVICE_CALLBACK_PARAM *Param
> > +  )
> > +{
> > +  EFI_STATUS              Status = EFI_SUCCESS;
> > +  EFI_USB_DEVICE_REQUEST  Req;
> > +
> > +  DEBUG ((DEBUG_INFO, "UsbdSetupEvtHndlr\n"));
> > +
> > +  //
> > +  // Fill out request object from the incomming Buffer
> > +  //
> > +  CopyMem (&Req, Param->Buffer, sizeof(EFI_USB_DEVICE_REQUEST));
> > +
> > +  Status = UsbdSetupHdlr (&Req);
> > +  if (EFI_ERROR (Status)) {
> > +    DEBUG ((DEBUG_INFO, "UsbdSetupEvtHndlr: EFI_DEVICE_ERROR\n"));
> > +  }
> > +
> > +  return Status;
> > +}
> > +
> > +
> > +/**
> > + * Callback used to handle XferNotReady events from the XDCI
> > + *
> > + * @param Param Pointer to a generic callback parameter structure
> > + *
> > + * @return XDCI usb status
> > + */
> > +EFI_STATUS
> > +EFIAPI
> > +UsbdNrdyEvtHndlr (
> > +  IN USB_DEVICE_CALLBACK_PARAM *Param
> > +  )
> > +{
> > +  DEBUG ((DEBUG_INFO, "UsbdNrdyEvtHndlr\n"));
> > +  return EFI_SUCCESS;
> > +}
> > +
> > +
> > +/**
> > +  Registers callbacks for event handlers with the XDCI layer.
> > +  The functions will be called as the registered events are triggered.
> > +
> > +  @param  XdciHndl to XDCI core driver
> > +  @return EFI_SUCCESS if successful, EFI_DEVICE_ERROR otherwise
> > +
> > +**/
> > +EFI_STATUS
> > +UsbdRegisterCallbacks (
> > +  IN VOID  *XdciHndl
> > +  )
> > +{
> > +  if (UsbDeviceRegisterCallback (XdciHndl, USB_DEVICE_RESET_EVENT,
> UsbdResetEvtHndlr) != EFI_SUCCESS) {
> > +    goto UdciRegCallbackError;
> > +  }
> > +
> > +  if (UsbDeviceRegisterCallback (XdciHndl,
> USB_DEVICE_CONNECTION_DONE, UsbdConnDoneEvtHndlr) !=
> EFI_SUCCESS) {
> > +    goto UdciRegCallbackError;
> > +  }
> > +
> > +  if (UsbDeviceRegisterCallback (XdciHndl,
> USB_DEVICE_SETUP_PKT_RECEIVED, UsbdSetupEvtHndlr) != EFI_SUCCESS) {
> > +    goto UdciRegCallbackError;
> > +  }
> > +
> > +  if (UsbDeviceRegisterCallback (XdciHndl, USB_DEVICE_XFER_NRDY,
> UsbdNrdyEvtHndlr) != EFI_SUCCESS) {
> > +    goto UdciRegCallbackError;
> > +  }
> > +
> > +  return EFI_SUCCESS;
> > +
> > +UdciRegCallbackError:
> > +  return EFI_DEVICE_ERROR;
> > +}
> > +
> > +
> > +/**
> > +  Returns the configuration descriptor for this device. The data
> > +  Buffer returned will also contain all downstream interface and
> > +  endpoint Buffers.
> > +
> > +  @param Buffer    Pointer to destination Buffer to copy descriptor data to
> > +  @param DescIndex the index of the descriptor to return
> > +  @param ReqLen    the length in bytes of the request Buffer
> > +  @param DataLen   Pointer whos value is to be filled with the byte count
> of
> > +                   data copied to the output Buffer
> > +
> > +  @return EFI_SUCCESS if descritor successfully copied,
> EFI_DEVICE_ERROR otherwise
> > +
> > +**/
> > +EFI_STATUS
> > +UsbdGetConfigDesc (
> > +  IN VOID      *Buffer,
> > +  IN UINT8     DescIndex,
> > +  IN UINT32    ReqLen,
> > +  IN UINT32    *DataLen
> > +  )
> > +{
> > +  EFI_STATUS             Status = EFI_DEVICE_ERROR;
> > +  UINT8                  NumConfigs = 0;
> > +  UINT32                 ConfigLen = 0;
> > +  USB_DEVICE_CONFIG_OBJ  *ConfigObj = NULL;
> > +  VOID                   *Descriptor = 0;
> > +  UINT32                 Length = 0;
> > +
> > +  DEBUG ((DEBUG_INFO, "UsbdGetConfigDesc()\n"));
> > +
> > +  //
> > +  // For a CONFIGURATION request we send back all descriptors branching
> out
> > +  // from this descriptor including the INTERFACE and ENDPOINT
> descriptors
> > +  //
> > +  //
> > +  // Verify the requested configuration exists - check valid index
> > +  //
> > +  NumConfigs = mDrvObj.UsbdDevObj->DeviceDesc->NumConfigurations;
> > +
> > +  if (DescIndex < NumConfigs) {
> > +    //
> > +    // get the configuration object using the index Offset
> > +    //
> > +    ConfigObj = (mDrvObj.UsbdDevObj->ConfigObjs + DescIndex);
> > +    //
> > +    // get the complete configuration Buffer block including Interface and
> Endpoint data
> > +    //
> > +    Descriptor = ConfigObj->ConfigAll;
> > +    //
> > +    // The config descriptor TotalLength has the full value for all desc
> Buffers
> > +    //
> > +    ConfigLen = ConfigObj->ConfigDesc->TotalLength;
> > +    //
> > +    // copy the data to the output Buffer
> > +    //
> > +    Length = MIN (ReqLen, ConfigLen);
> > +    CopyMem (Buffer, Descriptor, Length);
> > +    *DataLen = Length;
> > +    Status = EFI_SUCCESS;
> > +  } else {
> > +    DEBUG ((DEBUG_INFO, "UsbdGetConfigDesc() - Invalid Config index:
> %i\n", DescIndex));
> > +  }
> > +
> > +  if (Status == EFI_SUCCESS) {
> > +    if (ConfigObj != NULL) {
> > +      PrintConfigDescriptor (ConfigObj->ConfigDesc);
> > +    }
> > +  }
> > +
> > +  return Status;
> > +}
> > +
> > +
> > +/**
> > +  Sets the active configuration to the selected configuration index if it exists
> > +
> > +  @param CfgValue  the configuration value to set
> > +
> > +  @return EFI_SUCCESS if the configuration was set, EFI_DEVICE_ERROR
> otherwise
> > +
> > +**/
> > +EFI_STATUS
> > +UsbdSetConfig (
> > +  UINT8  CfgValue
> > +  )
> > +{
> > +  EFI_STATUS                 Status = EFI_DEVICE_ERROR;
> > +  UINT8                      numConfigs = 0;
> > +  USB_DEVICE_CONFIG_OBJ      *pConfigObj = NULL;
> > +  USB_DEVICE_INTERFACE_OBJ   *pIfObj = NULL;
> > +  USB_DEVICE_ENDPOINT_OBJ    *pEpObj = NULL;
> > +  UINT8                      cfgItr = 0;
> > +  UINT8                      ifItr = 0;
> > +  UINT8                      epItr = 0;
> > +  USB_DEVICE_ENDPOINT_INFO   EpInfo;
> > +  USB_EP_INFO                UsbEpInfo;
> > +
> > +  DEBUG ((DEBUG_INFO, "UsbdSetConfig()\n"));
> > +  //
> > +  // Verify the requested configuration exists - check valid index
> > +  //
> > +  numConfigs = mDrvObj.UsbdDevObj->DeviceDesc->NumConfigurations;
> > +
> > +  if (CfgValue != 0) {
> > +    //
> > +    // Search for a matching configuration
> > +    //
> > +    for (cfgItr = 0; cfgItr < numConfigs; cfgItr++) {
> > +      pConfigObj = (mDrvObj.UsbdDevObj->ConfigObjs + cfgItr);
> > +      if (pConfigObj->ConfigDesc->ConfigurationValue == CfgValue) {
> > +
> > +        //
> > +        // Set the active configuration object
> > +        //
> > +        mDrvObj.ActiveConfigObj = pConfigObj;
> > +        //
> > +        // Find all interface objects for this configuration
> > +        //
> > +        for (ifItr = 0; ifItr < pConfigObj->ConfigDesc->NumInterfaces; ifItr++) {
> > +          pIfObj = (pConfigObj->InterfaceObjs + ifItr);
> > +          //
> > +          // Configure the Endpoints in the XDCI
> > +          //
> > +          for (epItr = 0; epItr < pIfObj->InterfaceDesc->NumEndpoints;
> epItr++) {
> > +            pEpObj = (pIfObj->EndpointObjs + epItr);
> > +
> > +            EpInfo.EndpointDesc = pEpObj->EndpointDesc;
> > +            EpInfo.EndpointCompDesc = pEpObj->EndpointCompDesc;
> > +
> > +            if (UsbdInitEp (mDrvObj.XdciDrvObj, &EpInfo) == EFI_SUCCESS) {
> > +              UsbdSetEpInfo(&UsbEpInfo, &EpInfo);
> > +              if (UsbDeviceEpEnable (mDrvObj.XdciDrvObj, &UsbEpInfo) ==
> EFI_SUCCESS) {
> > +                Status = EFI_SUCCESS;
> > +              } else {
> > +                DEBUG ((DEBUG_INFO, "UsbdSetConfig() - Failed to enable
> endpoint\n"));
> > +              }
> > +            } else {
> > +              DEBUG ((DEBUG_INFO, "UsbdSetConfig() - Failed to initialize
> endpoint\n"));
> > +            }
> > +          }
> > +        }
> > +        //
> > +        // Let the class driver know it is configured
> > +        //
> > +        if (Status == EFI_SUCCESS) {
> > +          if (mDrvObj.UsbdDevObj->ConfigCallback != NULL) {
> > +            mDrvObj.UsbdDevObj->ConfigCallback (CfgValue);
> > +          }
> > +        }
> > +
> > +        mDrvObj.State = UsbDevStateConfigured; // we are now configured
> > +
> > +        break; // break from config search loop
> > +      }
> > +    }
> > +  }
> > +
> > +  if (EFI_ERROR (Status)) {
> > +   DEBUG ((DEBUG_INFO, "UsbdSetConfig() - Invalid requested
> configuration value: %i\n", CfgValue));
> > +  }
> > +
> > +  return Status;
> > +}
> > +
> > +
> > +/**
> > +  Returns the currently active configuration value
> > +
> > +  @param Buffer    Pointer to destination Buffer to copy configuration
> value to
> > +  @param ReqLen    the length in bytes of the request Buffer
> > +  @param DataLen   Pointer whos value is to be filled with the byte count
> of
> > +                   data copied to the output Buffer
> > +
> > +  @return EFI_SUCCESS if config value is successfully copied,
> EFI_DEVICE_ERROR otherwise
> > +
> > +**/
> > +EFI_STATUS
> > +UsbdGetConfig (
> > +  VOID      *Buffer,
> > +  UINT32    ReqLen,
> > +  UINT32    *DataLen
> > +  )
> > +{
> > +  EFI_STATUS    Status = EFI_DEVICE_ERROR;
> > +
> > +  DEBUG ((DEBUG_INFO, "UsbdGetConfig()\n"));
> > +
> > +  if (ReqLen >= 1) { // length of data expected must be 1
> > +    if (mDrvObj.ActiveConfigObj != NULL) { // assure we have a config active
> > +      *DataLen = 1; // one byte for ConfigurationValue
> > +      *(UINT8*)Buffer = mDrvObj.ActiveConfigObj->ConfigDesc-
> >ConfigurationValue;
> > +
> > +      Status = EFI_SUCCESS;
> > +    } else {
> > +      DEBUG ((DEBUG_INFO, "UsbdGetConfig() - No active configuration
> available\n"));
> > +    }
> > +  } else {
> > +    DEBUG ((DEBUG_INFO, "UsbdGetConfig() - Invalid data length\n"));
> > +  }
> > +
> > +  return Status;
> > +}
> > +
> > +
> > +/**
> > +  Returns the requested string descriptor if it exists
> > +
> > +  @param Buffer    Pointer to destination Buffer to copy descriptor data to
> > +  @param DescIndex the index of the descriptor to return
> > +  @param LangId    the target language ID
> > +  @param ReqLen    the length in bytes of the request Buffer
> > +  @param DataLen   Pointer whos value is to be filled with the byte count
> of
> > +                   data copied to the output Buffer
> > +
> > +  @return EFI_SUCCESS if descritor successfully copied,
> EFI_DEVICE_ERROR otherwise
> > +
> > +**/
> > +EFI_STATUS
> > +UsbdGetStringDesc (
> > +  VOID      *Buffer,
> > +  UINT8     DescIndex,
> > +  UINT16    LangId,
> > +  UINT32    ReqLen,
> > +  UINT32    *DataLen
> > +  )
> > +{
> > +  EFI_STATUS             Status = EFI_DEVICE_ERROR;
> > +  UINT32                 Length = 0;
> > +  USB_STRING_DESCRIPTOR  *StringDesc;
> > +  UINT8                  Index = 0;
> > +  UINT8                  StrLangEntries = 0;
> > +  BOOLEAN                StrLangFound = FALSE;
> > +
> > +  DEBUG ((DEBUG_INFO, "UsbdGetStringDesc: Index: 0x%x, LangId: 0x%x,
> ReqLen: 0x%x\n", DescIndex, LangId, ReqLen));
> > +
> > +  //
> > +  // index zero of the string table contains the supported language codes
> > +  //
> > +  if (DescIndex == 0) {
> > +    StringDesc = (mDrvObj.UsbdDevObj->StringTable);
> > +    Length = MIN (ReqLen, StringDesc->Length);
> > +    CopyMem (Buffer, StringDesc, Length);
> > +    *DataLen = Length;
> > +    Status = EFI_SUCCESS;
> > +  } else {
> > +
> > +    //
> > +    // Verify the requested language ID is supported. String descriptor Zero
> > +    // (First entry in the string table) is expected to contain the language list.
> > +    // The requested language ID is specified in the Index member of the
> request.
> > +    //
> > +    StringDesc = mDrvObj.UsbdDevObj->StringTable; // get language string
> descriptor
> > +    StrLangEntries = ((StringDesc->Length - 2) >> 1);
> > +    DEBUG ((DEBUG_INFO, "StrLangEntries=%x\n", StrLangEntries));
> > +
> > +    DEBUG ((DEBUG_INFO, "Looking LangID: \n"));
> > +
> > +    for (Index = 0; Index < StrLangEntries; Index++) {
> > +      DEBUG ((DEBUG_INFO, "LangID [%x]= %x\n", Index, StringDesc-
> >LangID [Index]));
> > +
> > +      if (StringDesc->LangID [Index] == LangId) {
> > +        DEBUG ((DEBUG_INFO, "Found it\n"));
> > +        StrLangFound = TRUE;
> > +      }
> > +    }
> > +
> > +    //
> > +    // If we found a matching language, attempt to get the string index
> requested
> > +    //
> > +    if (StrLangFound == TRUE) {
> > +      DEBUG ((DEBUG_INFO, "UsbdGetStringDesc: StrLangFound=Found,
> DescIndex=%x, StrTblEntries=%x\n", DescIndex, mDrvObj.UsbdDevObj-
> >StrTblEntries));
> > +
> > +      if (DescIndex < mDrvObj.UsbdDevObj->StrTblEntries) {
> > +        //
> > +        // get the string descriptor for the requested index
> > +        //
> > +        StringDesc = (mDrvObj.UsbdDevObj->StringTable + DescIndex);
> > +
> > +        Length = MIN (ReqLen, StringDesc->Length);
> > +        DEBUG ((DEBUG_INFO, "ReqLen=%x, StringLength=%x, Length=%x\n",
> ReqLen, StringDesc->Length, Length));
> > +
> > +        CopyMem (Buffer, StringDesc, Length);
> > +        *DataLen = Length;
> > +        Status = EFI_SUCCESS;
> > +      } else {
> > +        DEBUG ((DEBUG_INFO, "UsbdGetStringDesc: Invalid String index in
> USB_REQ_GET_DESCRIPTOR request\n"));
> > +      }
> > +    } else {
> > +      DEBUG ((DEBUG_INFO, "UsbdGetStringDesc: Unsupported String
> Language ID for USB_REQ_GET_DESCRIPTOR request\n"));
> > +    }
> > +  }
> > +
> > +  if (Status == EFI_SUCCESS) {
> > +    PrintStringDescriptor (StringDesc);
> > +  }
> > +  return Status;
> > +}
> > +
> > +
> > +#ifdef SUPPORT_SUPER_SPEED
> > +/**
> > +  Returns the configuration descriptor for this device. The data
> > +  Buffer returned will also contain all downstream interface and
> > +  endpoint Buffers.
> > +
> > +  @param Buffer    Pointer to destination Buffer to copy descriptor data to
> > +  @param ReqLen    the length in bytes of the request Buffer
> > +  @param DataLen   Pointer whos value is to be filled with the byte count
> of
> > +                   data copied to the output Buffer
> > +
> > +  @return EFI_SUCCESS if descritor successfully copied,
> EFI_DEVICE_ERROR otherwise
> > +
> > +**/
> > +EFI_STATUS
> > +UsbdGetBOSDesc (
> > +  IN VOID      *Buffer,
> > +  IN UINT32    ReqLen,
> > +  IN UINT32    *DataLen
> > +  )
> > +{
> > +  EFI_USB_BOS_DESCRIPTOR  *BosDesc = 0;
> > +  UINT32                  Length = 0;
> > +
> > +  DEBUG ((DEBUG_INFO, "UsbdGetBOSDesc()\n"));
> > +
> > +  BosDesc = mDrvObj.UsbdDevObj->BosDesc;
> > +  Length = MIN (ReqLen, mDrvObj.UsbdDevObj->BosDesc->TotalLength);
> > +
> > +  CopyMem(Buffer, BosDesc, Length);
> > +  *DataLen = Length;
> > +
> > +  PrintBOSDescriptor (BosDesc);
> > +
> > +  return EFI_SUCCESS;
> > +}
> > +#endif
> > +
> > +/**
> > +  Returns the current status for Device/Interface/Endpoint
> > +
> > +  @param Buffer    Pointer to destination Buffer to copy descriptor data to
> > +  @param ReqType   The type of status to get
> > +  @param ReqLen    the length in bytes of the request Buffer
> > +  @param DataLen   Pointer whos value is to be filled with the byte count
> of
> > +                   data copied to the output Buffer
> > +
> > +  @return EFI_SUCCESS if status successfully copied, EFI_DEVICE_ERROR
> otherwise
> > +
> > +**/
> > +EFI_STATUS
> > +UsbdGetStatus (
> > +  VOID      *Buffer,
> > +  UINT8     ReqType,
> > +  UINT32    ReqLen,
> > +  UINT32    *DataLen
> > +  )
> > +{
> > +  EFI_STATUS  Status = EFI_DEVICE_ERROR;
> > +
> > +  DEBUG ((DEBUG_INFO, "UsbdGetStatus()\n"));
> > +
> > +  if (ReqLen >= 2) { // length of data must be at least 2 bytes
> > +    switch (ReqType & USB_TARGET_MASK) {
> > +      case USB_TARGET_DEVICE:
> > +        *DataLen = 2; // two byte for status
> > +        *(UINT16*)Buffer = USB_STATUS_SELFPOWERED;
> > +        Status = EFI_SUCCESS;
> > +        break;
> > +
> > +      case USB_TARGET_INTERFACE:
> > +        //
> > +        // No implementation needed at this time
> > +        //
> > +        break;
> > +
> > +      case USB_TARGET_ENDPOINT:
> > +        //
> > +        // No implementation needed at this time
> > +        // Should specify if endpoint is halted. Implement as necessary.
> > +        //
> > +        break;
> > +
> > +      case USB_TARGET_OTHER:
> > +        //
> > +        // No implementation needed at this time
> > +        //
> > +        break;
> > +
> > +      default:
> > +        break;
> > +    }
> > +  } else {
> > +    DEBUG ((DEBUG_INFO, "UsbdGetStatus() - Invalid data length\n"));
> > +  }
> > +
> > +  return Status;
> > +}
> > +
> > +
> > +/**
> > +  Sets the address of the device
> > +
> > +  @param address   the address value to set
> > +
> > +  @return EFI_SUCCESS if address was set, EFI_DEVICE_ERROR otherwise
> > +
> > +**/
> > +EFI_STATUS
> > +UsbdSetAddress (
> > +  UINT8    Address
> > +  )
> > +{
> > +  EFI_STATUS  Status = EFI_DEVICE_ERROR;
> > +
> > +  DEBUG ((DEBUG_INFO, "UsbdSetAddress: setting address: 0x%x\n",
> Address));
> > +
> > +  if (Address <= 0x7F) { // address must not be > 127
> > +    mDrvObj.Address = Address;
> > +
> > +    //
> > +    // Configure Address in the XDCI
> > +    //
> > +    Status = UsbDeviceSetAddress (mDrvObj.XdciDrvObj,
> mDrvObj.Address);
> > +    if (!EFI_ERROR (Status)) {
> > +      mDrvObj.State = UsbDevStateAddress;
> > +    } else {
> > +      DEBUG ((DEBUG_INFO, "UsbdSetAddress: Failed to set address in
> XDCI\n"));
> > +    }
> > +  } else {
> > +    DEBUG ((DEBUG_INFO, "UsbdSetAddress: Invalid address: 0x%x\n",
> Address));
> > +  }
> > +
> > +  return Status;
> > +}
> > +
> > +
> > +/**
> > +  Handles Setup device requests. Standard requests are immediately
> > +  handled here, and any Class/Vendor specific requests are forwarded
> > +  to the class driver
> > +
> > +  @param CtrlRequest  Pointer to a device request
> > +
> > +  @return EFI_SUCCESS if request successfully handled, FALSE otherwise
> > +
> > +**/
> > +EFI_STATUS
> > +UsbdSetupHdlr (
> > +  IN EFI_USB_DEVICE_REQUEST    *CtrlRequest
> > +  )
> > +{
> > +  EFI_STATUS              Status = EFI_DEVICE_ERROR;
> > +  UINT8                   DescIndex = 0;
> > +  USB_DEVICE_DESCRIPTOR   *DevDesc = 0;
> > +
> > +  //
> > +  // Initialize the IO object
> > +  //
> > +  mCtrlIoReq.IoInfo.Length = 0;
> > +
> > +  DEBUG ((DEBUG_INFO, "UsbdSetupHdlr start\n"));
> > +  PrintDeviceRequest (CtrlRequest);
> > +
> > +  //
> > +  // Handle Standard Device Requests
> > +  //
> > +  if ((CtrlRequest->RequestType & USB_REQ_TYPE_MASK) ==
> USB_REQ_TYPE_STANDARD) {
> > +    switch (CtrlRequest->Request) {
> > +      case USB_REQ_GET_DESCRIPTOR:
> > +        DEBUG ((DEBUG_INFO, "UsbdSetupHdlr: Host requests get
> descriptor\n"));
> > +        if (CtrlRequest->RequestType == USB_RT_TX_DIR_D_TO_H) {
> > +          DescIndex = (CtrlRequest->Value & 0xff); // low byte is the index
> requested
> > +          switch (CtrlRequest->Value >> 8) { // high byte contains request type
> > +            case USB_DESC_TYPE_DEVICE:
> > +              DEBUG ((DEBUG_INFO, "Descriptor tyep: Device\n"));
> > +              DevDesc = mDrvObj.UsbdDevObj->DeviceDesc;
> > +              //
> > +              // copy the data to the output Buffer
> > +              //
> > +              mCtrlIoReq.IoInfo.Length = MIN (CtrlRequest->Length, DevDesc-
> >Length);
> > +              CopyMem (mCtrlIoReq.IoInfo.Buffer, DevDesc,
> mCtrlIoReq.IoInfo.Length);
> > +              PrintDeviceDescriptor (DevDesc);
> > +              break;
> > +
> > +            case USB_DESC_TYPE_CONFIG:
> > +              DEBUG ((DEBUG_INFO, "Descriptor tyep: Configuration\n"));
> > +              Status = UsbdGetConfigDesc (
> > +                         mCtrlIoReq.IoInfo.Buffer,
> > +                         DescIndex,
> > +                         CtrlRequest->Length,
> > +                         &(mCtrlIoReq.IoInfo.Length)
> > +                         );
> > +              break;
> > +
> > +            case USB_DESC_TYPE_STRING:
> > +              DEBUG ((DEBUG_INFO, "Descriptor tyep: String\n"));
> > +              Status = UsbdGetStringDesc (
> > +                         mCtrlIoReq.IoInfo.Buffer,
> > +                         DescIndex,
> > +                         CtrlRequest->Index,
> > +                         CtrlRequest->Length,
> > +                         &(mCtrlIoReq.IoInfo.Length)
> > +                         );
> > +              break;
> > +
> > +#ifdef SUPPORT_SUPER_SPEED
> > +            case USB_DESC_TYPE_BOS:
> > +              DEBUG ((DEBUG_INFO, "Descriptor tyep: BOS\n"));
> > +              Status = UsbdGetBOSDesc (
> > +                         mCtrlIoReq.IoInfo.Buffer,
> > +                         CtrlRequest->Length,
> > +                         &(mCtrlIoReq.IoInfo.Length)
> > +                         );
> > +              break;
> > +
> > +            case USB_DESC_TYPE_SS_ENDPOINT_COMPANION:
> > +              DEBUG ((DEBUG_INFO, "Descriptor tyep: Endpoint
> Companion\n"));
> > +              break;
> > +#endif
> > +
> > +            default:
> > +              DEBUG ((DEBUG_INFO, "Descriptor tyep: Unsupported,
> USB_REQ_GET_DESCRIPTOR request: 0x%x\n", (CtrlRequest->Value >> 8)));
> > +              break;
> > +          }
> > +        } else {
> > +          DEBUG ((DEBUG_INFO, "UsbdSetupHdlr() - Invalid direction for
> USB_REQ_GET_DESCRIPTOR request\n"));
> > +        }
> > +        break;
> > +
> > +      case USB_REQ_GET_CONFIG:
> > +        DEBUG ((DEBUG_INFO, "USB_REQ_GET_CONFIG\n"));
> > +        if (CtrlRequest->RequestType == USB_RT_TX_DIR_D_TO_H) {
> > +          Status = UsbdGetConfig (mCtrlIoReq.IoInfo.Buffer, CtrlRequest-
> >Length, &(mCtrlIoReq.IoInfo.Length));
> > +        } else {
> > +          DEBUG ((DEBUG_INFO, "UsbdSetupHdlr: Invalid direction for
> USB_REQ_GET_CONFIG request\n"));
> > +        }
> > +        break;
> > +
> > +      case USB_REQ_SET_CONFIG:
> > +        DEBUG ((DEBUG_INFO, "USB_REQ_SET_CONFIG\n"));
> > +        if (CtrlRequest->RequestType == USB_RT_TX_DIR_H_TO_D) {
> > +          Status = UsbdSetConfig ((UINT8)CtrlRequest->Value);
> > +        } else {
> > +          DEBUG ((DEBUG_INFO, "UsbdSetupHdlr: Invalid direction for
> USB_REQ_SET_CONFIG request\n"));
> > +        }
> > +        break;
> > +
> > +      case USB_REQ_SET_ADDRESS:
> > +        DEBUG ((DEBUG_INFO, "USB_REQ_SET_ADDRESS\n"));
> > +        if (CtrlRequest->RequestType == USB_RT_TX_DIR_H_TO_D) {
> > +          Status = UsbdSetAddress ((UINT8)CtrlRequest->Value);
> > +        } else {
> > +          DEBUG ((DEBUG_INFO, "UsbdSetupHdlr: Invalid direction for
> USB_REQ_SET_ADDRESS request\n"));
> > +        }
> > +        break;
> > +
> > +      case USB_REQ_GET_STATUS:
> > +        DEBUG ((DEBUG_INFO, "USB_REQ_GET_STATUS\n"));
> > +        if (CtrlRequest->RequestType & USB_RT_TX_DIR_D_TO_H) {
> > +          Status = UsbdGetStatus (mCtrlIoReq.IoInfo.Buffer, CtrlRequest-
> >RequestType, CtrlRequest->Length, &(mCtrlIoReq.IoInfo.Length));
> > +        } else {
> > +          DEBUG ((DEBUG_INFO, "UsbdSetupHdlr: Invalid direction for
> USB_REQ_GET_STATUS request\n"));
> > +        }
> > +        break;
> > +#ifdef SUPPORT_SUPER_SPEED
> > +      case USB_REQ_CLEAR_FEATURE:
> > +      case USB_REQ_SET_FEATURE:
> > +      case USB_REQ_SET_DESCRIPTOR:
> > +      case USB_REQ_GET_INTERFACE:
> > +      case USB_REQ_SET_INTERFACE:
> > +      case USB_REQ_SYNCH_FRAME:
> > +#endif
> > +      default:
> > +         DEBUG ((DEBUG_INFO, "UsbdSetupHdlr: Unsupported Standard
> Request: 0x%x\n", CtrlRequest->Request));
> > +          break;
> > +    }
> > +  } else { // This is not a Standard request, it specifies Class/Vendor
> handling
> > +    //
> > +    // Forward request to class driver
> > +    //
> > +    DEBUG ((DEBUG_INFO, "UsbdSetupHdlr: Class/Vendor Request\n"));
> > +    if (mDrvObj.UsbdDevObj->SetupCallback != NULL) {
> > +      mDrvObj.UsbdDevObj->SetupCallback (CtrlRequest,
> &(mCtrlIoReq.IoInfo));
> > +    }
> > +  }
> > +
> > +  DEBUG ((DEBUG_INFO, "dataLen=%x\n", mCtrlIoReq.IoInfo.Length));
> > +  //
> > +  // Transfer data according to request if necessary
> > +  //
> > +  if (mCtrlIoReq.IoInfo.Length> 0) {
> > +    Status = UsbdEpTxData (mDrvObj.XdciDrvObj, &mCtrlIoReq);
> > +    if (EFI_ERROR (Status)) {
> > +      DEBUG ((DEBUG_INFO, "UsbdSetupHdlr: Failed to TX data\n"));
> > +    }
> > +  } else {
> > +    //
> > +    // If we are not responding with data, send control status
> > +    //
> > +    Status = UsbDeviceEp0TxStatus (mDrvObj.XdciDrvObj);
> > +    if (EFI_ERROR (Status)) {
> > +      DEBUG ((DEBUG_INFO, "UsbdSetupHdlr: Failed to Tx Ep0 Status\n"));
> > +    }
> > +  }
> > +
> > +  return Status;
> > +}
> > +
> > +
> > +/**
> > +  Handles Connection done events. Sets the device address to zero.
> > +
> > +  @return EFI_SUCCESS if able to set the address, EFI_DEVICE_ERROR
> otherwise
> > +
> > +**/
> > +EFI_STATUS
> > +UsbdConnDoneHdlr (
> > +  VOID
> > +  )
> > +{
> > +  EFI_STATUS    Status = EFI_DEVICE_ERROR;
> > +
> > +  DEBUG ((DEBUG_INFO, "UsbdConnDoneHdlr()\n"));
> > +
> > +  //
> > +  // reset device address to 0
> > +  //
> > +  Status = UsbDeviceSetAddress (mDrvObj.XdciDrvObj, 0x0);
> > +  if (EFI_ERROR (Status)) {
> > +    DEBUG ((DEBUG_INFO, "UsbdConnDoneHdlr() - Failed to set address in
> XDCI\n"));
> > +  }
> > +
> > +  //
> > +  // set the device state to attached/connected
> > +  //
> > +  mDrvObj.State = UsbDevStateAttached;
> > +
> > +  return Status;
> > +}
> > +
> > +
> > +/**
> > +  Handles transmit/receive completion events. Directly handles
> > +  control endpoint events and forwards class/vendor specific events
> > +  to the class drivers.
> > +
> > +  @param   XferInfo   Pointer to Xfer structure
> > +
> > +  @return
> > +
> > +**/
> > +VOID
> > +UsbdXferDoneHdlr (
> > +  IN EFI_USB_DEVICE_XFER_INFO    *XferInfo
> > +  )
> > +{
> > +  //
> > +  // If this is a non-control transfer complete, notify the class driver
> > +  //
> > +  if (XferInfo->EndpointNum > 0) {
> > +    if (mDrvObj.UsbdDevObj->DataCallback != NULL) {
> > +      mDrvObj.UsbdDevObj->DataCallback (XferInfo);
> > +    }
> > +  }
> > +
> > +  return;
> > +}
> > +
> > +
> > +/**
> > +  Binds a USB class driver with this USB device driver core.
> > +  After calling this routine, the driver is ready to begin
> > +  USB processing.
> > +
> > +  @param  UsbdDevObj   Pointer to a usbd device object which contains
> > +                       all relevant information for the class driver device
> > +
> > +  @return TRUE if binding was successful, FALSE otherwise
> > +
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +UsbDeviceBind (
> > +  IN EFI_USB_DEVICE_MODE_PROTOCOL               *This,
> > +  IN USB_DEVICE_OBJ                             *UsbdDevObj
> > +  )
> > +{
> > +  EFI_STATUS  Status = EFI_SUCCESS;
> > +
> > +  //
> > +  // allocate Tx Buffer
> > +  //
> > +  mCtrlIoReq.IoInfo.Buffer = AllocateZeroPool
> (USB_EPO_MAX_PKT_SIZE_ALL);
> > +  if (mCtrlIoReq.IoInfo.Buffer != NULL) {
> > +    mDrvObj.UsbdDevObj = UsbdDevObj;
> > +    mDrvObj.ActiveConfigObj = NULL;
> > +    mDrvObj.Address = 0;
> > +    mDrvObj.State = UsbDevStateInit;
> > +  } else {
> > +    DEBUG ((DEBUG_INFO, "UsbDeviceBind() - Failed to allocate IO
> Buffer\n"));
> > +    Status = EFI_DEVICE_ERROR;
> > +  }
> > +
> > +  return Status;
> > +}
> > +
> > +
> > +/**
> > +  Unbinds the USB class driver from this USB device driver core.
> > +
> > +  @return TRUE if successful, FALSE otherwise
> > +
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +UsbDeviceUnbind (
> > +  IN EFI_USB_DEVICE_MODE_PROTOCOL               *This
> > +  )
> > +{
> > +  mDrvObj.UsbdDevObj = NULL;
> > +  mDrvObj.ActiveConfigObj = NULL;
> > +  mDrvObj.Address = 0;
> > +  mDrvObj.State = UsbDevStateOff;
> > +  mDrvObj.XdciInitialized = FALSE;
> > +
> > +  //
> > +  // release allocated Buffer data
> > +  //
> > +  if (mCtrlIoReq.IoInfo.Buffer) {
> > +    FreePool (mCtrlIoReq.IoInfo.Buffer);
> > +  }
> > +
> > +  return EFI_SUCCESS;
> > +}
> > +
> > +
> > +/**
> > +  Performs continual USB device event processing until a cancel
> > +  event occurs
> > +
> > +  @param   TimeoutMs   Connection timeout in ms. If 0, waits forever.
> > +  @return  TRUE if run executed normally, FALSE if error ocurred
> > +
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +UsbDeviceRun (
> > +  IN EFI_USB_DEVICE_MODE_PROTOCOL               *This,
> > +  IN UINT32                                     TimeoutMs
> > +  )
> > +{
> > +  EFI_STATUS              Status = EFI_DEVICE_ERROR;
> > +  USB_XDCI_DEV_CONTEXT    *XdciDevContext;
> > +
> > +  XdciDevContext = USBUSBD_CONTEXT_FROM_PROTOCOL (This);
> > +
> > +  //
> > +  // can only run if XDCI is initialized
> > +  //
> > +  if ((mDrvObj.XdciInitialized == TRUE)) {
> > +
> > +    if ((mDrvObj.State == UsbDevStateConfigured) && (XdciDevContext-
> >XdciPollTimer == NULL)) {
> > +      Status = gBS->CreateEvent (
> > +                      EVT_TIMER | EVT_NOTIFY_SIGNAL,
> > +                      TPL_NOTIFY,
> > +                      UsbdMonitorEvents,
> > +                      XdciDevContext,
> > +                      &XdciDevContext->XdciPollTimer
> > +                      );
> > +      if (!EFI_ERROR (Status)) {
> > +        Status = gBS->SetTimer (XdciDevContext->XdciPollTimer,
> TimerPeriodic, EFI_TIMER_PERIOD_MILLISECONDS (20));
> > +        DEBUG ((EFI_D_ERROR, "UsbDeviceRun Create Event\n"));
> > +      }
> > +    }
> > +
> > +    mXdciRun = TRUE; // set the run flag to active
> > +    Status = EFI_SUCCESS;
> > +
> > +    //
> > +    // start the Event processing loop
> > +    //
> > +    while (TRUE) {
> > +      if (XdciDevContext->XdciPollTimer == NULL) {
> > +        if (UsbDeviceIsrRoutine (mDrvObj.XdciDrvObj) != EFI_SUCCESS) {
> > +          DEBUG ((DEBUG_INFO, "UsbDeviceRun() - Failed to execute event
> ISR\n"));
> > +        }
> > +      }
> > +
> > +      //
> > +      // Check if a run cancel request exists, if so exit processing loop
> > +      //
> > +      if (mXdciRun == FALSE) {
> > +        if (XdciDevContext->XdciPollTimer != NULL) {
> > +          DEBUG ((EFI_D_ERROR, "UsbDeviceRun close Event\n"));
> > +          gBS->SetTimer (XdciDevContext->XdciPollTimer, TimerCancel, 0);
> > +          gBS->CloseEvent (XdciDevContext->XdciPollTimer);
> > +          XdciDevContext->XdciPollTimer = NULL;
> > +        }
> > +        Status = EFI_SUCCESS;
> > +        DEBUG ((DEBUG_INFO, "UsbDeviceRun() - processing was
> cancelled\n"));
> > +        break;
> > +      }
> > +
> > +      //
> > +      // check for timeout
> > +      //
> > +      if (TimeoutMs == 0)
> > +        return EFI_TIMEOUT;
> > +      gBS->Stall (50);
> > +      TimeoutMs--;
> > +    }
> > +  }
> > +
> > +  return Status;
> > +}
> > +
> > +
> > +/**
> > +  Sets a flag to stop the running device processing loop
> > +
> > +  @return TRUE always
> > +
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +UsbDeviceStop (
> > +  IN EFI_USB_DEVICE_MODE_PROTOCOL               *This
> > +  )
> > +{
> > +  mXdciRun = FALSE; // set run flag to FALSE to stop processing
> > +  return EFI_SUCCESS;
> > +}
> > +
> > +
> > +EFI_STATUS
> > +EFIAPI
> > +UsbDeviceInitXdci (
> > +  IN EFI_USB_DEVICE_MODE_PROTOCOL               *This
> > +  )
> > +{
> > +  EFI_STATUS            Status = EFI_DEVICE_ERROR;
> > +  USB_XDCI_DEV_CONTEXT  *XdciDevContext;
> > +
> > +  XdciDevContext = USBUSBD_CONTEXT_FROM_PROTOCOL (This);
> > +
> > +  PlatformSpecificInit ();
> > +
> > +  if (mDrvObj.XdciInitialized == FALSE) {
> > +    if (XdciDevContext->XdciMmioBarAddr != 0) {
> > +
> > +      //
> > +      // Initialize device controller driver
> > +      //
> > +      DEBUG ((DEBUG_INFO, "UsbDeviceInitXdci() - Initializing
> Controller...\n"));
> > +
> > +      //
> > +      // Initialize the device controller interface
> > +      //
> > +      if (UsbdInit ((UINT32)XdciDevContext->XdciMmioBarAddr,
> &mDrvObj.XdciDrvObj) == EFI_SUCCESS) {
> > +
> > +        //
> > +        // Setup callbacks
> > +        //
> > +        if (UsbdRegisterCallbacks (mDrvObj.XdciDrvObj) == EFI_SUCCESS) {
> > +
> > +          mDrvObj.XdciInitialized = TRUE;
> > +          Status = EFI_SUCCESS;
> > +
> > +          DEBUG ((DEBUG_INFO, "UsbDeviceInitXdci() - Controller initialization
> complete\n"));
> > +        } else {
> > +          DEBUG ((DEBUG_INFO, "UsbDeviceInitXdci() - Failed to register UDCI
> callbacks\n"));
> > +        }
> > +      } else {
> > +        DEBUG ((DEBUG_INFO, "UsbDeviceInitXdci() - Failed to initialize
> UDCI\n"));
> > +      }
> > +    } else {
> > +      DEBUG ((DEBUG_INFO, "UsbDeviceInitXdci() - XDCI MMIO BAR not
> set\n"));
> > +    }
> > +  } else {
> > +    DEBUG ((DEBUG_INFO, "UsbDeviceInitXdci() - XDCI already
> initialized\n"));
> > +    Status = EFI_ALREADY_STARTED;
> > +  }
> > +
> > +  return Status;
> > +}
> > +
> > +
> > +EFI_STATUS
> > +EFIAPI
> > +UsbDeviceConnect(
> > +  IN EFI_USB_DEVICE_MODE_PROTOCOL               *This
> > +  )
> > +{
> > +  EFI_STATUS  Status = EFI_DEVICE_ERROR;
> > +
> > +  DEBUG ((DEBUG_INFO,  "UsbDeviceConnect \n"));
> > +  if (UsbXdciDeviceConnect (mDrvObj.XdciDrvObj) == EFI_SUCCESS) {
> > +    Status = EFI_SUCCESS;
> > +  }
> > +  return Status;
> > +}
> > +
> > +
> > +EFI_STATUS
> > +EFIAPI
> > +UsbDeviceDisConnect (
> > +  IN EFI_USB_DEVICE_MODE_PROTOCOL               *This
> > +  )
> > +{
> > +  EFI_STATUS  Status = EFI_DEVICE_ERROR;
> > +
> > +  DEBUG ((DEBUG_INFO,  "UsbDeviceDisConnect \n"));
> > +  if (UsbDeviceDisconnect (mDrvObj.XdciDrvObj) == EFI_SUCCESS) {
> > +    mDrvObj.State = UsbDevStateInit;
> > +    Status = EFI_SUCCESS;
> > +  }
> > +
> > +  XhciSwitchSwid(FALSE);
> > +  return Status;
> > +}
> > +
> > +
> > +EFI_STATUS
> > +EFIAPI
> > +UsbDeviceEpTxData(
> > +  IN EFI_USB_DEVICE_MODE_PROTOCOL               *This,
> > +  IN USB_DEVICE_IO_REQ                          *IoRequest
> > +  )
> > +{
> > +  EFI_STATUS  Status;
> > +
> > +  Status = UsbdEpTxData (mDrvObj.XdciDrvObj, IoRequest);
> > +  return Status;
> > +}
> > +
> > +
> > +EFI_STATUS
> > +EFIAPI
> > +UsbDeviceEpRxData(
> > +  IN EFI_USB_DEVICE_MODE_PROTOCOL               *This,
> > +  IN USB_DEVICE_IO_REQ                          *IoRequest
> > +  )
> > +{
> > +  EFI_STATUS  Status;
> > +
> > +  Status = UsbdEpRxData (mDrvObj.XdciDrvObj, IoRequest);
> > +  return Status;
> > +}
> > +
> > +
> > +//
> > +// The Runtime UsbDeviceMode Protocol instance produced by this driver
> > +//
> > +EFI_USB_DEVICE_MODE_PROTOCOL  mUsbDeviceModeProtocol = {
> > +  UsbDeviceInitXdci,
> > +  UsbDeviceConnect,
> > +  UsbDeviceDisConnect,
> > +  UsbDeviceEpTxData,
> > +  UsbDeviceEpRxData,
> > +  UsbDeviceBind,
> > +  UsbDeviceUnbind,
> > +  UsbDeviceRun,
> > +  UsbDeviceStop
> > +};
> > +
> > diff --git
> a/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbDeviceMode.h
> b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbDeviceMode.h
> > new file mode 100644
> > index 0000000000..ac9c89b2f1
> > --- /dev/null
> > +++
> b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbDeviceMode.h
> > @@ -0,0 +1,39 @@
> > +/** @file
> > +  Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR>
> > +
> > +  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.
> > +
> > +**/
> > +
> > +#ifndef _USB_DEVICE_MODE_DXE_H_
> > +#define _USB_DEVICE_MODE_DXE_H_
> > +
> > +#include <Uefi.h>
> > +#include <PiDxe.h>
> > +#include <Library/DebugLib.h>
> > +#include <Library/UefiDriverEntryPoint.h>
> > +#include <Library/UefiBootServicesTableLib.h>
> > +#include <Library/UsbDeviceLib.h>
> > +#include <Protocol/UsbDeviceModeProtocol.h>
> > +#include "XdciCommon.h"
> > +#include "XdciDevice.h"
> > +
> > +
> > +///
> > +/// Function declaration
> > +///
> > +EFI_STATUS
> > +UsbdSetupHdlr (
> > +  IN EFI_USB_DEVICE_REQUEST    *CtrlRequest
> > +  );
> > +
> > +extern EFI_USB_DEVICE_MODE_PROTOCOL  mUsbDeviceModeProtocol;
> > +
> > +#endif
> > +
> > diff --git
> a/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbFuncIo.c
> b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbFuncIo.c
> > new file mode 100644
> > index 0000000000..a4138328fd
> > --- /dev/null
> > +++ b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbFuncIo.c
> > @@ -0,0 +1,2221 @@
> > +/** @file
> > +  Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR>
> > +
> > +  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.
> > +
> > +**/
> > +
> > +#include "UsbDeviceDxe.h"
> > +
> > +//
> > +// 16 bytes in a guid x 2 characters per byte, 4 chars for dashes and a NUL
> > +//
> > +#define CHARS_IN_GUID (sizeof(GUID) * 2 + 4 + 1)
> > +
> > +//
> > +// Strings that get sent with the USB Connection
> > +//
> > +static CHAR16 mUsbFnDxeMfgString[] = L"Intel Corporation";
> > +static CHAR16 mUsbFnDxeProductString[] = L"Broxton";
> > +static CHAR16 mUsbFnDxeSerialNumber[] = L"INT123456";
> > +
> > +//
> > +// Duplicated from MiscSystemManufacturerData.c Some parts of it will
> > +// replaced with device-specific unique values.
> > +//
> > +static GUID mSmBiosUniqueGuid = {
> > +        0x5e24fe9c, 0xc8d0, 0x45bd, 0xa7, 0x9f, 0x54, 0xea, 0x5f, 0xbd, 0x3d,
> 0x97
> > +    };
> > +
> > +EFI_USBFN_IO_PROTOCOL         mUsbFunIoProtocol = {
> > +  EFI_USBFN_IO_PROTOCOL_REVISION,
> > +  DetectPort,
> > +  ConfigureEnableEndpoints,
> > +  GetEndpointMaxPacketSize,
> > +  GetDeviceInfo,
> > +  GetVendorIdProductId,
> > +  AbortTransfer,
> > +  GetEndpointStallState,
> > +  SetEndpointStallState,
> > +  EventHandler,
> > +  Transfer,
> > +  GetMaxTransferSize,
> > +  AllocateTransferBuffer,
> > +  FreeTransferBuffer,
> > +  StartController,
> > +  StopController,
> > +  SetEndpointPolicy,
> > +  GetEndpointPolicy
> > +};
> > +
> > +
> > +EFI_STATUS
> > +PrintEventBuffer(
> > +  IN  EFI_USBFN_IO_PROTOCOL  *This
> > +  )
> > +{
> > +  UINT32                          EventCount;
> > +  USB_XDCI_DEV_CONTEXT            *UsbFuncIoDevPtr;
> > +  XDCI_CORE_HANDLE                *XdciCorePtr;
> > +  USB_DEV_CORE                    *UsbDeviceCorePtr;
> > +  UINT32                          Index;
> > +  UINT32                          *DbBufPtr;
> > +
> > +  UsbFuncIoDevPtr = USBFUIO_CONTEXT_FROM_PROTOCOL (This);
> > +
> > +  UsbDeviceCorePtr = UsbFuncIoDevPtr->DrvCore;
> > +  XdciCorePtr = UsbDeviceCorePtr->ControllerHandle;
> > +
> > +  EventCount = UsbRegRead ((UINT32)UsbFuncIoDevPtr-
> >XdciMmioBarAddr, DWC_XDCI_EVNTCOUNT_REG(0));
> > +
> > +  DbBufPtr = (UINT32*)(UINTN)XdciCorePtr->CurrentEventBuffer;
> > +  XdciCorePtr = UsbDeviceCorePtr->ControllerHandle;
> > +  DEBUG ((USB_FUIO_DEBUG_EVENT_D, "FUEV:: XdciCorePtr-
> >AlignedEventBuffers 0x%08x\n", (UINTN)XdciCorePtr-
> >AlignedEventBuffers));
> > +  DEBUG ((USB_FUIO_DEBUG_EVENT_D, "FUEV:: DUMP BUF_S\n"));
> > +  for (Index = 0; Index < ((EventCount / 4) + 1); Index++) {
> > +    DEBUG ((USB_FUIO_DEBUG_EVENT_D, "0x%08x\n", DbBufPtr[Index]));
> > +  }
> > +  DEBUG ((USB_FUIO_DEBUG_EVENT_D, "FUEV:: DUMP BUF_E\n"));
> > +
> > +  return EFI_SUCCESS;
> > +}
> > +
> > +/**
> > +Debug End
> > +**/
> > +
> > +/**
> > +  Returns information about what type of device was attached.
> > +
> > +  @param[in]  This               A pointer to the EFI_USBFN_IO_PROTOCOL
> instance.
> > +  @param[out] PortType           Returns the USB port type.
> > +
> > +
> > +  @retval EFI_SUCCESS            The operation completed successfully.
> > +  @retval EFI_INVALID_PARAMETER  A parameter is invalid.
> > +  @retval EFI_DEVICE_ERROR       The physical device reported an error.
> > +  @retval EFI_NOT_READY          The physical device is busy or not ready to
> > +                                 process this request or the device is not
> > +                                 attached to the host.
> > +
> > +
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +DetectPort (
> > +  IN  EFI_USBFN_IO_PROTOCOL  *This,
> > +  OUT EFI_USBFN_PORT_TYPE    *PortType
> > +  )
> > +{
> > +  USB_XDCI_DEV_CONTEXT  *UsbFuncIoDevPtr;
> > +  EFI_STATUS            Status;
> > +  UINT8                 Value8;
> > +
> > +  DEBUG ((USB_FUIO_DEBUG_INFO, "DetectPort - Entry\n"));
> > +
> > +  UsbFuncIoDevPtr = USBFUIO_CONTEXT_FROM_PROTOCOL (This);
> > +
> > +  //
> > +  // USBSRCDETRSLT Bit[5:2]
> > +  // Result of USB HW Source Detection algorithm
> > +  // Power-Domain: VRTC
> > +  // Result of USB HW Source Detection algorithm :
> > +  // 0000 = Not determined
> > +  // 0001 = SDP Attached
> > +  // 0010 = DCP Attached
> > +  // 0011 = CDP Attached
> > +  // 0100 = ACA Attached
> > +  // 0101 = SE1 Attached
> > +  // 0110 = MHL Attached
> > +  // 0111 = Floating D+/D- Attached
> > +  // 1000 = Other Attached
> > +  // 1001 = DCP detected by ext. USB PHY
> > +  // 1010-1111 = Rsvd
> > +  // Reset: 0000B
> > +  //
> > +
> > +  Value8 =PmicRead8 (0x5E, 0X29);
> > +  if ((Value8 & 0x03) != 0x02) {
> > +    *PortType = EfiUsbUnknownPort;
> > +    Status = EFI_NOT_READY;
> > +    goto out;
> > +  }
> > +
> > +  Value8 = Value8 >> 2 & 0x0f;
> > +  Status = EFI_SUCCESS;
> > +  switch (Value8) {
> > +    case 1:
> > +      *PortType = EfiUsbStandardDownstreamPort;
> > +      break;
> > +    case 2:
> > +      *PortType = EfiUsbDedicatedChargingPort;
> > +      break;
> > +    case 3:
> > +      *PortType = EfiUsbChargingDownstreamPort;
> > +      break;
> > +
> > +    case 4:
> > +    case 5:
> > +    case 6:
> > +    case 7:
> > +    case 8:
> > +    case 9:
> > +      *PortType = EfiUsbUnknownPort;
> > +      break;
> > +    case 0:
> > +    case 10:
> > +    case 11:
> > +    case 12:
> > +    case 13:
> > +    case 14:
> > +    case 15:
> > +      *PortType = EfiUsbUnknownPort;
> > +      Status = EFI_NOT_READY;
> > +     break;
> > +  }
> > +
> > +out:
> > +  DEBUG ((USB_FUIO_DEBUG_INFO, "DetectPort - Exit\n"));
> > +  return EFI_SUCCESS;
> > +}
> > +
> > +
> > +/**
> > +  The AllocateTransferBuffer function allocates a memory region of Size
> bytes
> > +  and returns the address of the allocated memory that satisfies
> underlying
> > +  controller requirements in the location referenced by Buffer.
> > +
> > +  @param[in] This               A pointer to the EFI_USBFN_IO_PROTOCOL
> instance.
> > +  @param[in] Size               The number of bytes to allocate for the transfer
> > +                                Buffer.
> > +  @param[in] Buffer             A pointer to a pointer to the allocated Buffer
> > +                                if the call succeeds; undefined otherwise.
> > +
> > +  @retval EFI_SUCCESS           The operation completed successfully.
> > +  @retval EFI_INVALID_PARAMETER A parameter is invalid.
> > +  @retval The requested transfer Buffer could not be allocated.
> > +
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +AllocateTransferBuffer (
> > +  IN EFI_USBFN_IO_PROTOCOL    *This,
> > +  IN UINTN                    Size,
> > +  OUT VOID                    **Buffer
> > +  )
> > +{
> > +  EFI_STATUS            Status;
> > +  USB_XDCI_DEV_CONTEXT  *UsbFuncIoDevPtr;
> > +  VOID                  *AllocateBufferPtr;
> > +  USB_MEM_NODE          *NodePtr;
> > +
> > +  DEBUG ((USB_FUIO_DEBUG_INFO, "AllocateTransferBuffer - Entry\n"));
> > +
> > +  UsbFuncIoDevPtr = USBFUIO_CONTEXT_FROM_PROTOCOL (This);
> > +
> > +  if (Size == 0) {
> > +    Status = EFI_INVALID_PARAMETER;
> > +    goto ErrorExit;
> > +  }
> > +
> > +  AllocateBufferPtr = AllocateZeroPool (Size);
> > +
> > +  if (AllocateBufferPtr == NULL) {
> > +    Status = EFI_OUT_OF_RESOURCES;
> > +    goto ErrorExit;
> > +  }
> > +
> > +  //
> > +  // Create new node
> > +  //
> > +  Status = InsertNewNodeToHead (This, &NodePtr);
> > +  if (EFI_ERROR (Status)) {
> > +    Status = EFI_OUT_OF_RESOURCES;
> > +    goto ErrorExit;
> > +  }
> > +
> > +  NodePtr->Size = Size;
> > +  NodePtr->AllocatePtr = AllocateBufferPtr;
> > +
> > +  *Buffer = AllocateBufferPtr;
> > +
> > +  DEBUG ((USB_FUIO_DEBUG_INFO, "AllocateTransferBuffer addr
> 0x%08x\n", AllocateBufferPtr));
> > +  DEBUG ((USB_FUIO_DEBUG_INFO, "AllocateTransferBuffer - Exit\n"));
> > +  return EFI_SUCCESS;
> > +
> > +ErrorExit:
> > +
> > +  DEBUG ((USB_FUIO_DEBUG_ERROR, "AllocateTransferBuffer - ERRROR
> %r\n",Status));
> > +  return Status;
> > +}
> > +
> > +
> > +/**
> > +  Deallocates the memory allocated for the transfer Buffer by
> > +  AllocateTransferBuffer function.
> > +
> > +  @param[in] This               A pointer to the EFI_USBFN_IO_PROTOCOL
> instance.
> > +  @param[in] Buffer             Buffer Pointer to the transfer Buffer
> > +                                to deallocate.
> > +  @retval EFI_SUCCESS           The function returned successfully.
> > +  @retval EFI_INVALID_PARAMETER A parameter is invalid.
> > +
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +FreeTransferBuffer (
> > +  IN EFI_USBFN_IO_PROTOCOL    *This,
> > +  IN VOID                     *Buffer
> > +  )
> > +{
> > +  EFI_STATUS            Status;
> > +  USB_XDCI_DEV_CONTEXT  *UsbFuncIoDevPtr;
> > +
> > +  UsbFuncIoDevPtr = USBFUIO_CONTEXT_FROM_PROTOCOL (This);
> > +  DEBUG ((USB_FUIO_DEBUG_LOAD, "FreeTransferBuffer - Entry\n"));
> > +
> > +  Status = RemoveNode (This, Buffer);
> > +  if (EFI_ERROR(Status)) {
> > +    DEBUG ((USB_FUIO_DEBUG_LOAD, "FreeTransferBuffer - ERROR\n"));
> > +    return EFI_INVALID_PARAMETER;
> > +  }
> > +
> > +  DEBUG ((USB_FUIO_DEBUG_LOAD, "FreeTransferBuffer - Exit\n"));
> > +  return EFI_SUCCESS;
> > +}
> > +
> > +/**
> > +  Configure endpoints Based on supplied device and configuration
> descriptors.
> > +
> > +  @param[in] This               A pointer to the EFI_USBFN_IO_PROTOCOL
> instance.
> > +  @param[in] DeviceInfo         A pointer to EFI_USBFN_DEVICE_INFO
> instance.
> > +
> > +  @retval EFI_SUCCESS           The function returned successfully.
> > +  @retval EFI_INVALID_PARAMETER A parameter is invalid.
> > +  @retval EFI_DEVICE_ERROR      The physical device reported an error.
> > +  @retval EFI_NOT_READY         The physical device is busy or not ready to
> > +                                process this request.
> > +  @retval EFI_OUT_OF_RESOURCES  The request could not be completed
> due to
> > +                                lack of resources.
> > +
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +ConfigureEnableEndpoints (
> > +  IN EFI_USBFN_IO_PROTOCOL         *This,
> > +  IN EFI_USB_DEVICE_INFO           *DeviceInfo
> > +  )
> > +{
> > +  EFI_STATUS                        Status;
> > +  USB_XDCI_DEV_CONTEXT              *UsbFuncIoDevPtr;
> > +
> > +  UsbFuncIoDevPtr = USBFUIO_CONTEXT_FROM_PROTOCOL (This);
> > +  Status = EFI_SUCCESS;
> > +
> > +  DEBUG ((USB_FUIO_DEBUG_LOAD, "ConfigureEnableEndpoints -
> Entry\n"));
> > +  //
> > +  //Assuming that the hardware has already been initialized,
> > +  //this function configures the endpoints using supplied
> > +  //DeviceInfo, activates the port, and starts receiving USB events
> > +  //
> > +  Status = EFI_SUCCESS;
> > +  if (DeviceInfo == NULL) {
> > +    Status = EFI_INVALID_PARAMETER;
> > +    goto FUNC_EXIT;
> > +  }
> > +
> > +  UsbFuncIoDevPtr->DevInfoPtr->DeviceDescriptor = DeviceInfo-
> >DeviceDescriptor;
> > +
> > +  //
> > +  // Set Configure table
> > +  //
> > +  if (DeviceInfo->DeviceDescriptor->NumConfigurations > 1) {
> > +    DEBUG ((EFI_D_ERROR, "!!!Error ConfigNum over '1' %d\n", DeviceInfo-
> >DeviceDescriptor->NumConfigurations));
> > +  }
> > +  UsbFuncIoDevPtr->IndexPtrConfig.ConfigDescriptor = DeviceInfo-
> >ConfigInfoTable[0]->ConfigDescriptor;
> > +  UsbFuncIoDevPtr->IndexPtrConfig.InterfaceInfoTable[0] = DeviceInfo-
> >ConfigInfoTable[0]->InterfaceInfoTable[0];
> > +
> > +  //
> > +  // Set Interface
> > +  //
> > +  if (DeviceInfo->ConfigInfoTable[0]->ConfigDescriptor->NumInterfaces >
> 1) {
> > +    DEBUG ((EFI_D_ERROR, "!!!Error NumInterfaces[0] over '1' %d\n",
> DeviceInfo->ConfigInfoTable[0]->ConfigDescriptor->NumInterfaces));
> > +  }
> > +  UsbFuncIoDevPtr->IndexPtrInteface.InterfaceDescriptor = DeviceInfo-
> >ConfigInfoTable[0]->InterfaceInfoTable[0]->InterfaceDescriptor;
> > +
> > +  //
> > +  // Set Endpoint
> > +  //
> > +  if (UsbFuncIoDevPtr->IndexPtrInteface.InterfaceDescriptor-
> >NumEndpoints > 2) {
> > +    DEBUG ((EFI_D_ERROR, "!!!Error NumEndPoint[0] over '2' %d\n",
> UsbFuncIoDevPtr->IndexPtrInteface.InterfaceDescriptor->NumEndpoints));
> > +  }
> > +
> > +  UsbFuncIoDevPtr->IndexPtrInEp.EndpointCompDesc = NULL;
> > +  UsbFuncIoDevPtr->IndexPtrOutEp.EndpointCompDesc = NULL;
> > +
> > +  if ((DeviceInfo->ConfigInfoTable[0]->InterfaceInfoTable[0]-
> >EndpointDescriptorTable[0]->EndpointAddress & USB_ENDPOINT_DIR_IN)
> != 0) {
> > +    UsbFuncIoDevPtr->IndexPtrInEp.EndpointDesc = DeviceInfo-
> >ConfigInfoTable[0]->InterfaceInfoTable[0]->EndpointDescriptorTable[0];
> > +    UsbFuncIoDevPtr->IndexPtrOutEp.EndpointDesc = DeviceInfo-
> >ConfigInfoTable[0]->InterfaceInfoTable[0]->EndpointDescriptorTable[1];
> > +  } else {
> > +    UsbFuncIoDevPtr->IndexPtrInEp.EndpointDesc = DeviceInfo-
> >ConfigInfoTable[0]->InterfaceInfoTable[0]->EndpointDescriptorTable[1];
> > +    UsbFuncIoDevPtr->IndexPtrOutEp.EndpointDesc = DeviceInfo-
> >ConfigInfoTable[0]->InterfaceInfoTable[0]->EndpointDescriptorTable[0];
> > +  }
> > +
> > +  DEBUG ((USB_FUIO_DEBUG_LOAD, " In Ep Num 0x%02x\n",
> UsbFuncIoDevPtr->IndexPtrInEp.EndpointDesc->EndpointAddress));
> > +
> > +  DEBUG ((USB_FUIO_DEBUG_LOAD, " Out Ep Num 0x%02x\n",
> UsbFuncIoDevPtr->IndexPtrOutEp.EndpointDesc->EndpointAddress));
> > +
> > +FUNC_EXIT:
> > +  DEBUG ((USB_FUIO_DEBUG_LOAD, "ConfigureEnableEndpoints - exit
> %r\n", Status));
> > +  return Status;
> > +}
> > +
> > +/**
> > +  Returns the maximum packet size of the specified endpoint type for
> > +  the supplied bus Speed.
> > +
> > +  @param[in] This               A pointer to the EFI_USBFN_IO_PROTOCOL
> instance.
> > +  @param[in] EndpointType       Endpoint type as defined as
> EFI_USB_ENDPOINT_TYPE.
> > +  @param[in] BusSpeed           Bus Speed as defined as
> EFI_USB_BUS_SPEED.
> > +  @param[in] MaxPacketSize      The maximum packet size, in bytes,
> > +                                of the specified endpoint type.
> > +
> > +  @retval EFI_SUCCESS           The function returned successfully.
> > +  @retval EFI_INVALID_PARAMETER A parameter is invalid.
> > +  @retval EFI_DEVICE_ERROR      The physical device reported an error.
> > +  @retval EFI_NOT_READY         The physical device is busy or not ready to
> > +                                process this request.
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +GetEndpointMaxPacketSize (
> > +  IN EFI_USBFN_IO_PROTOCOL      *This,
> > +  IN EFI_USB_ENDPOINT_TYPE      EndpointType,
> > +  IN EFI_USB_BUS_SPEED          BusSpeed,
> > +  OUT UINT16                    *MaxPacketSize
> > +  )
> > +{
> > +  EFI_STATUS                        Status;
> > +  USB_XDCI_DEV_CONTEXT              *UsbFuncIoDevPtr;
> > +  USB_DEV_CORE                      *DevCorePtr;
> > +  XDCI_CORE_HANDLE                  *XdciCorePtr;
> > +
> > +  UsbFuncIoDevPtr = USBFUIO_CONTEXT_FROM_PROTOCOL (This);
> > +  DevCorePtr = UsbFuncIoDevPtr->DrvCore;
> > +  XdciCorePtr = DevCorePtr->ControllerHandle;
> > +  Status = EFI_SUCCESS;
> > +
> > +  DEBUG ((USB_FUIO_DEBUG_LOAD, "GetEndpointMaxPacketSize -
> Entry\n"));
> > +
> > +  switch (EndpointType) {
> > +    case UsbEndpointControl:
> > +#ifdef SUPPORT_SUPER_SPEED
> > +      *MaxPacketSize = USB_EP0_MAX_PKT_SIZE_SS; // Default to super
> Speed
> > +#else
> > +      *MaxPacketSize = USB_EP0_MAX_PKT_SIZE_HS; // Default to high
> Speed
> > +#endif
> > +      break;
> > +
> > +    case UsbEndpointBulk:
> > +#ifdef SUPPORT_SUPER_SPEED
> > +      *MaxPacketSize = USB_BULK_EP_PKT_SIZE_SS; // Default to super
> Speed
> > +#else
> > +      *MaxPacketSize = USB_BULK_EP_PKT_SIZE_HS; // Default to high
> Speed
> > +#endif
> > +      break;
> > +
> > +    case UsbEndpointInterrupt:
> > +      *MaxPacketSize = 1;
> > +      break;
> > +
> > +    case UsbEndpointIsochronous:
> > +    default:
> > +      Status = EFI_DEVICE_ERROR;
> > +      break;
> > +  }
> > +
> > +  DEBUG ((USB_FUIO_DEBUG_LOAD, "GetEndpointMaxPacketSize - Exit
> %r\n", Status));
> > +  return Status;
> > +}
> > +
> > +
> > +/**
> > +  Returns the maximum supported transfer size.
> > +
> > +  @param[in] This               A pointer to the EFI_USBFN_IO_PROTOCOL
> instance.
> > +  @param[in] MaxTransferSize    The maximum supported transfer size, in
> bytes.
> > +
> > +  @retval EFI_SUCCESS           The function returned successfully.
> > +  @retval EFI_INVALID_PARAMETER A parameter is invalid.
> > +  @retval EFI_DEVICE_ERROR      The physical device reported an error.
> > +  @retval EFI_NOT_READY         The physical device is busy or not ready to
> > +                                process this request.
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +GetMaxTransferSize (
> > +  IN EFI_USBFN_IO_PROTOCOL     *This,
> > +  OUT UINTN                    *MaxTransferSize
> > +  )
> > +{
> > +  //
> > +  // Need to check, Make max transfer package to 8MB
> > +  //
> > +  *MaxTransferSize = MAX_TRANSFER_PACKET;
> > +  return EFI_SUCCESS;
> > +}
> > +
> > +
> > +/**
> > +  This function returns the unique device ID of the device--this matches
> > +  what is populated in the SMBIOS table.
> > +
> > +  @param[in/out] BufferSize     On input, the size of the Buffer in bytes.
> > +                                On output, the amount of data returned in Buffer
> > +                                in bytes.
> > +
> > +  @param[out] Buffer            A pointer to a Buffer to return the requested
> > +                                information as a Unicode string. What string are
> > +                                we talking about
> > +
> > +  @retval EFI_SUCCESS           The function returned successfully.
> > +  @retval EFI_BUFFER_TOO_SMALL  A parameter is invalid.
> > +
> > +**/
> > +STATIC
> > +EFI_STATUS
> > +EFIAPI
> > +GetDeviceSerialNumber (
> > +    IN OUT UINTN *BufferSize,
> > +    OUT VOID *Buffer OPTIONAL
> > +  )
> > +{
> > +    EFI_STATUS Status = EFI_SUCCESS;
> > +    CHAR16 UuidString[CHARS_IN_GUID];
> > +    UINTN CharsCopied;
> > +
> > +    DEBUG ((USB_FUIO_DEBUG_LOAD, "+GetDeviceSerialNumber\n"));
> > +    //
> > +    // check bounds
> > +    //
> > +    if (*BufferSize < sizeof(UuidString)) {
> > +        Status = EFI_BUFFER_TOO_SMALL;
> > +        *BufferSize = 0;
> > +        goto Error;
> > +    }
> > +
> > +    //
> > +    // The rest of mSmBiosUniqueGuid will be same. Note that we cannot
> > +    // read the SMBIOS table directly, as it might not be ready by the time
> we
> > +    // are to read it. The population of the data from the eMMC is ready
> > +    // by the time we are here.
> > +    //
> > +
> > +    //
> > +    // Print to to a string, and copy it off
> > +    //
> > +    CharsCopied = UnicodeSPrint(UuidString, sizeof(UuidString), L"%g",
> &mSmBiosUniqueGuid);
> > +    if (CharsCopied != (CHARS_IN_GUID - 1))
> > +    {
> > +        Status = EFI_BUFFER_TOO_SMALL;
> > +        *BufferSize = 0;
> > +        goto Error;
> > +    }
> > +    CopyMem(Buffer, UuidString, sizeof(UuidString));
> > +    *BufferSize = sizeof(UuidString);
> > +
> > +Error:
> > +
> > +    DEBUG ((USB_FUIO_DEBUG_LOAD, "-GetDeviceSerialNumber, Status =
> 0x%08x\r\n", Status));
> > +
> > +    return Status;
> > +}
> > +
> > +
> > +/**
> > +  Returns device specific information Based on the supplied identifier as
> > +  a Unicode string
> > +
> > +  @param[in] This               A pointer to the EFI_USBFN_IO_PROTOCOL
> instance.
> > +  @param[in] Id                 Requested information id.
> > +  @param[in] BufferSize         On input, the size of the Buffer in bytes.
> > +                                On output, the amount of data returned in Buffer
> > +                                in bytes.
> > +  @param[in] Buffer             A pointer to a Buffer to return the requested
> > +                                information as a Unicode string. What string are
> > +                                we talking about
> > +
> > +  @retval EFI_SUCCESS           The function returned successfully.
> > +  @retval EFI_INVALID_PARAMETER A parameter is invalid.
> > +  @retval EFI_DEVICE_ERROR      The physical device reported an error.
> > +  @retval EFI_NOT_READY         The physical device is busy or not ready to
> > +                                process this request.
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +GetDeviceInfo (
> > +  IN EFI_USBFN_IO_PROTOCOL      *This,
> > +  IN EFI_USBFN_DEVICE_INFO_ID   Id,
> > +  IN OUT UINTN                  *BufferSize,
> > +  OUT VOID                      *Buffer OPTIONAL
> > +  )
> > +{
> > +  EFI_STATUS                    Status;
> > +  USB_XDCI_DEV_CONTEXT          *UsbFuncIoDevPtr;
> > +
> > +  UsbFuncIoDevPtr = USBFUIO_CONTEXT_FROM_PROTOCOL (This);
> > +  Status = EFI_SUCCESS;
> > +
> > +  DEBUG ((USB_FUIO_DEBUG_LOAD, "GetDeviceInfo - Entry\n"));
> > +
> > +  if ((BufferSize == 0) || (Buffer == NULL)) {
> > +    Status = EFI_INVALID_PARAMETER;
> > +    goto FUN_EXIT;
> > +  }
> > +
> > +  switch (Id) {
> > +
> > +    //
> > +    // FIXME: Get real serial number of board
> > +    //
> > +    case EfiUsbDeviceInfoSerialNumber:
> > +        if (*BufferSize < sizeof(mUsbFnDxeSerialNumber)) {
> > +            Status = EFI_BUFFER_TOO_SMALL;
> > +            *BufferSize = 0;
> > +            goto FUN_EXIT;
> > +        }
> > +        CopyMem(Buffer, mUsbFnDxeSerialNumber,
> sizeof(mUsbFnDxeSerialNumber));
> > +        *BufferSize = sizeof(mUsbFnDxeSerialNumber);
> > +        break;
> > +
> > +    case EfiUsbDeviceInfoManufacturerName:
> > +        if (*BufferSize < sizeof(mUsbFnDxeMfgString)) {
> > +            Status = EFI_BUFFER_TOO_SMALL;
> > +            *BufferSize = 0;
> > +            goto FUN_EXIT;
> > +        }
> > +        CopyMem(Buffer, mUsbFnDxeMfgString,
> sizeof(mUsbFnDxeMfgString));
> > +        *BufferSize = sizeof(mUsbFnDxeMfgString);
> > +        break;
> > +
> > +    case EfiUsbDeviceInfoProductName:
> > +        if (*BufferSize < sizeof(mUsbFnDxeProductString)) {
> > +            Status = EFI_BUFFER_TOO_SMALL;
> > +            *BufferSize = 0;
> > +            goto FUN_EXIT;
> > +        }
> > +        CopyMem(Buffer, mUsbFnDxeProductString,
> sizeof(mUsbFnDxeProductString));
> > +        *BufferSize = sizeof(mUsbFnDxeProductString);
> > +        break;
> > +
> > +    case EfiUsbDeviceInfoUnknown:
> > +    default:
> > +      Status = EFI_UNSUPPORTED;
> > +      *BufferSize = 0;
> > +      DEBUG ((USB_FUIO_DEBUG_ERROR, "Unknown ID %d
> encountered.\r\n", Id));
> > +      break;
> > +  }
> > +
> > +FUN_EXIT:
> > +  DEBUG ((USB_FUIO_DEBUG_LOAD, "UsbSetconfigure - ConfigDescriptor
> addr 0x%08x \n", (UINTN)UsbFuncIoDevPtr-
> >IndexPtrConfig.ConfigDescriptor));
> > +  DEBUG ((USB_FUIO_DEBUG_LOAD, "GetDeviceInfo - Exit %r\n", Status));
> > +  return Status;
> > +}
> > +
> > +
> > +/**
> > +  Returns vendor-id and product-id of the device.
> > +
> > +  @param[in]  This              A pointer to the EFI_USBFN_IO_PROTOCOL
> instance.
> > +  @param[out] Vid               Returned vendor-id of the device.
> > +  @param[out] Pid               Returned product-id of the device.
> > +
> > +  @retval EFI_SUCCESS           The function returned successfully.
> > +  @retval EFI_INVALID_PARAMETER A parameter is invalid.
> > +  @retval EFI_NOT_FOUND         Unable to return vid or pid.
> > +
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +GetVendorIdProductId (
> > +  IN EFI_USBFN_IO_PROTOCOL      *This,
> > +  OUT UINT16                    *Vid,
> > +  OUT UINT16                    *Pid
> > +  )
> > +{
> > +  USB_XDCI_DEV_CONTEXT              *UsbFuncIoDevPtr;
> > +
> > +  UsbFuncIoDevPtr = USBFUIO_CONTEXT_FROM_PROTOCOL (This);
> > +  //
> > +  //   *Vid = 0x8086
> > +  //   *Pid = 0x0A65
> > +  //
> > +  *Vid = UsbFuncIoDevPtr->VendorId;
> > +  *Pid = UsbFuncIoDevPtr->DeviceId;
> > +  return EFI_SUCCESS;
> > +}
> > +
> > +/**
> > +  Aborts transfer on the specified endpoint.
> > +
> > +  @param[in]  This              A pointer to the EFI_USBFN_IO_PROTOCOL
> instance.
> > +  @param[in]  EndpointIndex     Indicates the endpoint on which the
> ongoing
> > +                                transfer needs to be canceled.
> > +  @param[in]  Direction         Direction of the endpoint.
> > +
> > +
> > +  @retval EFI_SUCCESS           The function returned successfully.
> > +  @retval EFI_INVALID_PARAMETER A parameter is invalid.
> > +  @retval EFI_DEVICE_ERROR      The physical device reported an error.
> > +  @retval EFI_NOT_READY         The physical device is busy or not ready to
> > +                                process this request.
> > +
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +AbortTransfer (
> > +  IN EFI_USBFN_IO_PROTOCOL        *This,
> > +  IN UINT8                        EndpointIndex,
> > +  IN EFI_USBFN_ENDPOINT_DIRECTION Direction
> > +  )
> > +{
> > +  USB_XDCI_DEV_CONTEXT              *UsbFuncIoDevPtr;
> > +  XDCI_CORE_HANDLE                  *XdciCorePtr;
> > +  USB_DEV_CORE                      *UsbDeviceCorePtr;
> > +  USB_EP_INFO                       EpInfo;
> > +  EFI_STATUS                        Status;
> > +
> > +  DEBUG ((USB_FUIO_DEBUG_LOAD, "FU:AbortTransfer - Entry\n"));
> > +  UsbFuncIoDevPtr = USBFUIO_CONTEXT_FROM_PROTOCOL (This);
> > +  UsbDeviceCorePtr = UsbFuncIoDevPtr->DrvCore;
> > +  XdciCorePtr = UsbDeviceCorePtr->ControllerHandle;
> > +  Status = EFI_SUCCESS;
> > +
> > +  if (UsbFuncIoDevPtr->DevResetFlag == TRUE) {
> > +    return Status;
> > +  }
> > +
> > +  EpInfo.EpNum = EndpointIndex;
> > +  EpInfo.EpDir = Direction? UsbEpDirIn : UsbEpDirOut;
> > +
> > +  Status = UsbDeviceEpCancelTransfer (UsbFuncIoDevPtr->DrvCore,
> &EpInfo);
> > +
> > +  DEBUG ((USB_FUIO_DEBUG_LOAD, "FU:AbortTransfer - Exit %r\n",
> Status));
> > +  return Status;
> > +}
> > +
> > +/**
> > +  Returns the stall state on the specified endpoint.
> > +
> > +  @param[in]  This              A pointer to the EFI_USBFN_IO_PROTOCOL
> instance.
> > +  @param[in]  EndpointIndex     Indicates the endpoint on which the
> ongoing
> > +                                transfer needs to be canceled.
> > +  @param[in]  Direction         Direction of the endpoint.
> > +  @param[in]  State             Boolean, true value indicates that the endpoint
> > +                                is in a stalled state, false otherwise.
> > +
> > +  @retval EFI_SUCCESS           The function returned successfully.
> > +  @retval EFI_INVALID_PARAMETER A parameter is invalid.
> > +  @retval EFI_DEVICE_ERROR      The physical device reported an error.
> > +  @retval EFI_NOT_READY         The physical device is busy or not ready to
> > +                                process this request.
> > +
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +GetEndpointStallState (
> > +  IN EFI_USBFN_IO_PROTOCOL        *This,
> > +  IN UINT8                        EndpointIndex,
> > +  IN EFI_USBFN_ENDPOINT_DIRECTION Direction,
> > +  IN OUT BOOLEAN                  *State
> > +  )
> > +{
> > +  USB_XDCI_DEV_CONTEXT              *UsbFuncIoDevPtr;
> > +  XDCI_CORE_HANDLE                  *XdciCorePtr;
> > +  UINT32                            EndPoint;
> > +
> > +  UsbFuncIoDevPtr = USBFUIO_CONTEXT_FROM_PROTOCOL (This);
> > +  DEBUG ((USB_FUIO_DEBUG_LOAD, "GetEndpointStallState - Entry\n"));
> > +
> > +  EndPoint = UsbGetPhysicalEpNum (EndpointIndex, Direction ?
> UsbEpDirIn : UsbEpDirOut);
> > +
> > +  XdciCorePtr = UsbFuncIoDevPtr->XdciDrvIfHandle;
> > +
> > +  if (XdciCorePtr->EpHandles[EndPoint].State == USB_EP_STATE_STALLED) {
> > +    *State = TRUE;
> > +  } else {
> > +    *State = FALSE;
> > +  }
> > +
> > +  DEBUG ((USB_FUIO_DEBUG_LOAD, "GetEndpointStallState - Exit\n"));
> > +  return EFI_SUCCESS;
> > +}
> > +
> > +
> > +EFI_STATUS
> > +UsbSetAddress (
> > +  IN EFI_USBFN_IO_PROTOCOL        *This,
> > +  IN UINT32                        Address
> > +  )
> > +{
> > +  EFI_STATUS                        Status;
> > +  USB_XDCI_DEV_CONTEXT              *UsbFuncIoDevPtr;
> > +  XDCI_CORE_HANDLE                  *XdciCorePtr;
> > +  USB_DEV_CORE                      *UsbDeviceCorePtr;
> > +
> > +  DEBUG ((USB_FUIO_DEBUG_LOAD, "UsbSetAddress - 0x%04x Entry\n",
> Address));
> > +
> > +  UsbFuncIoDevPtr = USBFUIO_CONTEXT_FROM_PROTOCOL (This);
> > +
> > +  UsbDeviceCorePtr = UsbFuncIoDevPtr->DrvCore;
> > +  XdciCorePtr = UsbDeviceCorePtr->ControllerHandle;
> > +  Status = EFI_SUCCESS;
> > +
> > +  Status = UsbDeviceSetAddress (UsbDeviceCorePtr, (UINT32)Address);
> > +
> > +  if (Status != EFI_SUCCESS) {
> > +    Status = EFI_DEVICE_ERROR;
> > +    goto EXIT_SET_ADDRESS;
> > +  }
> > +
> > +  Status = UsbDeviceEp0TxStatus (UsbDeviceCorePtr);
> > +
> > +  if (Status != EFI_SUCCESS) {
> > +    Status = EFI_NO_RESPONSE;
> > +    goto EXIT_SET_ADDRESS;
> > +  }
> > +
> > +EXIT_SET_ADDRESS:
> > +
> > +  DEBUG ((USB_FUIO_DEBUG_LOAD, "UsbSetAddress - Exit %r\n", Status));
> > +  return Status;
> > +}
> > +
> > +
> > +EFI_STATUS
> > +EFIAPI
> > +UsbSetconfigure (
> > +  IN EFI_USBFN_IO_PROTOCOL        *This,
> > +  IN UINT32                       InterFaceIndex
> > +  )
> > +{
> > +  EFI_STATUS                      Status;
> > +  USB_XDCI_DEV_CONTEXT            *UsbFuncIoDevPtr;
> > +  XDCI_CORE_HANDLE                *XdciCorePtr;
> > +  USB_DEV_CORE                    *UsbDeviceCorePtr;
> > +  UINT32                          InterfaceNum;
> > +  UINT32                          EndPointNum;
> > +  UINT32                          EndPointIndex;
> > +  EFI_USB_INTERFACE_INFO          *InterfaceInfoPtr;
> > +  USB_EP_INFO                     EpInfo;
> > +  USB_DEVICE_ENDPOINT_INFO        EpDescInfo;
> > +
> > +  DEBUG ((USB_FUIO_DEBUG_LOAD, "UsbSetconfigure - 0x%04x Entry\n",
> InterFaceIndex));
> > +
> > +  UsbFuncIoDevPtr = USBFUIO_CONTEXT_FROM_PROTOCOL (This);
> > +  UsbDeviceCorePtr = UsbFuncIoDevPtr->DrvCore;
> > +  XdciCorePtr = UsbDeviceCorePtr->ControllerHandle;
> > +  Status = EFI_SUCCESS;
> > +
> > +  InterfaceNum = UsbFuncIoDevPtr->IndexPtrConfig.ConfigDescriptor-
> >NumInterfaces;
> > +  DEBUG ((USB_FUIO_DEBUG_LOAD, "UsbSetconfigure - ConfigDescriptor
> addr 0x%08x \n", (UINTN)UsbFuncIoDevPtr-
> >IndexPtrConfig.ConfigDescriptor));
> > +
> > +  DEBUG ((USB_FUIO_DEBUG_LOAD, "UsbSetconfigure - DescriptorType
> 0x%04x ; ConfigurationValue 0x%04x\n",
> > +          UsbFuncIoDevPtr->IndexPtrConfig.ConfigDescriptor-
> >DescriptorType,
> > +          UsbFuncIoDevPtr->IndexPtrConfig.ConfigDescriptor-
> >ConfigurationValue
> > +          ));
> > +
> > +  DEBUG ((USB_FUIO_DEBUG_LOAD, "UsbSetconfigure - InterfaceNum
> 0x%04x \n", InterfaceNum));
> > +  if (InterfaceNum < InterFaceIndex) {
> > +    Status = EFI_INVALID_PARAMETER;
> > +    goto EXIT__SET_CONFIGURE;
> > +  }
> > +
> > +  //
> > +  // Arry strart form '0', Index start from '1'.
> > +  //
> > +  InterfaceInfoPtr = UsbFuncIoDevPtr-
> >IndexPtrConfig.InterfaceInfoTable[InterFaceIndex - 1];
> > +  EndPointNum = InterfaceInfoPtr->InterfaceDescriptor->NumEndpoints;
> > +
> > +  DEBUG ((USB_FUIO_DEBUG_LOAD, "UsbSetconfigure - Total EP NUM
> 0x%04x \n", EndPointNum));
> > +
> > +  for (EndPointIndex = 0; EndPointIndex < EndPointNum; EndPointIndex++)
> {
> > +    EpDescInfo.EndpointDesc = InterfaceInfoPtr-
> >EndpointDescriptorTable[EndPointIndex];
> > +    EpDescInfo.EndpointCompDesc = NULL;
> > +    UsbFnSetEpInfo (&EpInfo, &EpDescInfo);
> > +    DEBUG ((USB_FUIO_DEBUG_LOAD, "EndpointAddress 0x%02x\n",
> EpDescInfo.EndpointDesc->EndpointAddress));
> > +
> > +    if (UsbDeviceInitEp (UsbDeviceCorePtr, &EpInfo) == EFI_SUCCESS) {
> > +       if (UsbDeviceEpEnable (UsbDeviceCorePtr, &EpInfo) == EFI_SUCCESS) {
> > +       } else {
> > +         Status = EFI_DEVICE_ERROR;
> > +         DEBUG ((DEBUG_INFO, "UsbDeviceEpEnable() - Failed to enable
> endpoint\n"));
> > +       }
> > +    } else {
> > +       Status = EFI_DEVICE_ERROR;
> > +       DEBUG ((DEBUG_INFO, "UsbDeviceInitEp() - Failed to initialize
> endpoint\n"));
> > +    }
> > +  }
> > +
> > +  Status = UsbDeviceEp0TxStatus (UsbDeviceCorePtr);
> > +
> > +  if (Status != EFI_SUCCESS) {
> > +    Status = EFI_NO_RESPONSE;
> > +    goto EXIT__SET_CONFIGURE;
> > +  }
> > +
> > +
> > +EXIT__SET_CONFIGURE:
> > +  DEBUG ((USB_FUIO_DEBUG_LOAD, "UsbSetconfigure - Exit %r\n",
> Status));
> > +
> > +  return Status;
> > +}
> > +
> > +/**
> > +  Sets or clears the stall state on the specified endpoint.
> > +
> > +  @param[in]  This              A pointer to the EFI_USBFN_IO_PROTOCOL
> instance.
> > +  @param[in]  EndpointIndex     Indicates the endpoint on which the
> ongoing
> > +                                transfer needs to be canceled.
> > +  @param[in]  Direction         Direction of the endpoint.
> > +  @param[in]  State             Requested stall state on the specified endpoint.
> > +                                True value causes the endpoint to stall;
> > +                                false value clears an existing stall.
> > +
> > +  @retval EFI_SUCCESS           The function returned successfully.
> > +  @retval EFI_INVALID_PARAMETER A parameter is invalid.
> > +  @retval EFI_DEVICE_ERROR      The physical device reported an error.
> > +  @retval EFI_NOT_READY         The physical device is busy or not ready to
> > +                                process this request.
> > +
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +SetEndpointStallState (
> > +  IN EFI_USBFN_IO_PROTOCOL        *This,
> > +  IN UINT8                        EndpointIndex,
> > +  IN EFI_USBFN_ENDPOINT_DIRECTION Direction,
> > +  IN BOOLEAN                      State
> > +  )
> > +{
> > +  EFI_STATUS                        Status;
> > +  USB_XDCI_DEV_CONTEXT              *UsbFuncIoDevPtr;
> > +  USB_EP_INFO                       pEpInfo;
> > +
> > +  UsbFuncIoDevPtr = USBFUIO_CONTEXT_FROM_PROTOCOL (This);
> > +
> > +  DEBUG ((USB_FUIO_DEBUG_LOAD, "SetEndpointStallState - Entry\n"));
> > +  Status = EFI_SUCCESS;
> > +
> > +  pEpInfo.EpNum = EndpointIndex;
> > +  pEpInfo.EpDir = Direction? UsbEpDirIn : UsbEpDirOut;
> > +
> > +  if (State == TRUE) {
> > +    Status = UsbDeviceEpStall (UsbFuncIoDevPtr->DrvCore, (VOID*)(UINTN)
> &pEpInfo);
> > +  } else {
> > +    Status = UsbDeviceEpClearStall (UsbFuncIoDevPtr->DrvCore,
> (VOID*)(UINTN) &pEpInfo);
> > +  }
> > +
> > +  if (Status != EFI_SUCCESS) {
> > +    Status = EFI_DEVICE_ERROR;
> > +  }
> > +
> > +  DEBUG ((USB_FUIO_DEBUG_LOAD, "SetEndpointStallState - Exit\n"));
> > +  return Status;
> > +}
> > +
> > +EFI_STATUS
> > +DeviceEventCheck(
> > +  IN  EFI_USBFN_IO_PROTOCOL       *This,
> > +  IN  USBD_EVENT_BUF              *EventIndex,
> > +  OUT UINT32                      *ProcessSize,
> > +  OUT EFI_USBFN_MESSAGE           *Message,
> > +  OUT BOOLEAN                     *EventFlag
> > +  )
> > +{
> > +  USB_XDCI_DEV_CONTEXT            *UsbFuncIoDevPtr;
> > +  UINT32                          EventReg;
> > +  USB_DEV_CORE                    *UsbDeviceCorePtr;
> > +  XDCI_CORE_HANDLE                *XdciCorePtr;
> > +
> > +  DEBUG ((USB_FUIO_DEBUG_EVENT_D, "\n FUEV::DeviceEvent
> entry....\n"));
> > +  UsbFuncIoDevPtr = USBFUIO_CONTEXT_FROM_PROTOCOL (This);
> > +  UsbDeviceCorePtr = UsbFuncIoDevPtr->DrvCore;
> > +  XdciCorePtr = UsbDeviceCorePtr->ControllerHandle;
> > +  EventReg = (EventIndex->Event &
> DWC_XDCI_EVENT_BUFF_DEV_EVT_MASK);
> > +  EventReg >>= DWC_XDCI_EVENT_BUFF_DEV_EVT_BIT_POS;
> > +  *EventFlag = FALSE;
> > +
> > +  //
> > +  // Assume default event size. Change it in switch case if
> > +  // different
> > +  //
> > +  *ProcessSize =  DWC_XDCI_DEV_EVENT_DEFAULT_SIZE_IN_BYTES;
> > +
> > +  switch (EventReg) {
> > +    case DWC_XDCI_EVENT_BUFF_DEV_DISCONN_EVENT:
> > +      DEBUG ((USB_FUIO_DEBUG_EVENT_D, "USBFU_Device
> DWC_XDCI_EVENT_BUFF_DEV_DISCONN_EVENT\n"));
> > +      *Message = EfiUsbMsgBusEventDetach;
> > +      break;
> > +
> > +    case DWC_XDCI_EVENT_BUFF_DEV_USB_RESET_EVENT:
> > +      DEBUG ((USB_FUIO_DEBUG_EVENT_D, "USBFU_Device
> DWC_XDCI_EVENT_BUFF_DEV_USB_RESET_EVENT\n"));
> > +      //
> > +      //  In resetDet will prepare setup Xfer package
> > +      //
> > +      UsbFuncIoDevPtr->DevReConnect = FALSE;
> > +      UsbFuncIoDevPtr->DevResetFlag = TRUE;
> > +
> > +      usbProcessDeviceResetDet (XdciCorePtr);
> > +      UsbDeviceSetAddress (UsbDeviceCorePtr, 0);
> > +      *Message = EfiUsbMsgBusEventReset;
> > +      *EventFlag = TRUE;
> > +      break;
> > +
> > +    case DWC_XDCI_EVENT_BUFF_DEV_CONN_DONE_EVENT:
> > +      DEBUG ((USB_FUIO_DEBUG_EVENT_D, "USBFU_Device
> DWC_XDCI_EVENT_BUFF_DEV_CONN_DONE_EVENT\n"));
> > +      usbProcessDeviceResetDone(XdciCorePtr);
> > +      UsbDeviceSetAddress(UsbDeviceCorePtr, 0);
> > +      UsbFuncIoDevPtr->DevReConnect = TRUE;
> > +      UsbFuncIoDevPtr->DevResetFlag = FALSE;
> > +      *EventFlag = TRUE;
> > +      *Message = EfiUsbMsgNone;
> > +      break;
> > +
> > +    case DWC_XDCI_EVENT_BUFF_DEV_HBRNTN_REQ_EVENT:
> > +      DEBUG ((USB_FUIO_DEBUG_EVENT_D, "USBFU_Device
> DWC_XDCI_EVENT_BUFF_DEV_HBRNTN_REQ_EVENT\n"));
> > +      *Message = EfiUsbMsgBusEventSuspend;
> > +      *EventFlag = TRUE;
> > +      break;
> > +
> > +    case DWC_XDCI_EVENT_BUFF_DEV_WKUP_EVENT:
> > +      DEBUG ((USB_FUIO_DEBUG_EVENT_D, "USBFU_Device
> DWC_XDCI_EVENT_BUFF_DEV_WKUP_EVENT\n"));
> > +      *Message = EfiUsbMsgBusEventResume;
> > +      break;
> > +
> > +    case DWC_XDCI_EVENT_BUFF_DEV_TST_LMP_RX_EVENT:
> > +      *ProcessSize = DWC_XDCI_DEV_EVENT_TST_LMP_SIZE_IN_BYTES;
> > +      *Message = EfiUsbMsgNone;
> > +      DEBUG ((USB_FUIO_DEBUG_EVENT_D,
> "USBFUDwcXdciProcessDeviceEvent: UNHANDLED device event: %x\n",
> EventReg));
> > +      break;
> > +
> > +    case DWC_XDCI_EVENT_BUFF_DEV_STATE_CHANGE_EVENT:
> > +      DEBUG ((USB_FUIO_DEBUG_EVENT_D, "USBFU_Device
> DWC_XDCI_EVENT_BUFF_DEV_STATE_CHANGE_EVENT\n"));
> > +      break;
> > +
> > +    case DWC_XDCI_EVENT_BUFF_DEV_SOF_EVENT:
> > +      DEBUG ((USB_FUIO_DEBUG_EVENT_D, "USBFU_Device
> DWC_XDCI_EVENT_BUFF_DEV_SOF_EVENT\n"));
> > +      break;
> > +
> > +    case DWC_XDCI_EVENT_BUFF_DEV_ERRATIC_ERR_EVENT:
> > +      DEBUG ((USB_FUIO_DEBUG_EVENT_D, "USBFU_Device
> DWC_XDCI_EVENT_BUFF_DEV_ERRATIC_ERR_EVENT\n"));
> > +      break;
> > +
> > +    case DWC_XDCI_EVENT_BUFF_DEV_CMD_CMPLT_EVENT:
> > +      DEBUG ((USB_FUIO_DEBUG_EVENT_D, "USBFU_Device
> DWC_XDCI_EVENT_BUFF_DEV_CMD_CMPLT_EVENT\n"));
> > +      break;
> > +
> > +    case DWC_XDCI_EVENT_BUFF_DEV_BUFF_OVFL_EVENT:
> > +      DEBUG ((USB_FUIO_DEBUG_EVENT_D, "USBFU_Device
> DWC_XDCI_EVENT_BUFF_DEV_BUFF_OVFL_EVENT\n"));
> > +      break;
> > +
> > +    default:
> > +      *EventFlag = FALSE;
> > +      *Message = EfiUsbMsgNone;
> > +      DEBUG ((USB_FUIO_DEBUG_EVENT_I,
> "USBFUWcXdciProcessDeviceEvent: UNHANDLED device event: %x\n",
> EventReg));
> > +      break;
> > +  }
> > +
> > +  DEBUG ((USB_FUIO_DEBUG_EVENT_D, "\n FUEV::DeviceEvent entry
> exit.... \n"));
> > +  return EFI_SUCCESS;
> > +}
> > +
> > +
> > +EFI_STATUS
> > +Ep0XferDone(
> > +  IN  EFI_USBFN_IO_PROTOCOL       *This,
> > +  IN  UINT32                      EndPointNum,
> > +  OUT EFI_USBFN_MESSAGE           *Message,
> > +  IN OUT UINTN                    *PayloadSize,
> > +  OUT EFI_USBFN_MESSAGE_PAYLOAD   *Payload
> > +  )
> > +{
> > +  USB_DEV_CORE                    *UsbDeviceCorePtr;
> > +  XDCI_CORE_HANDLE                *XdciCorePtr;
> > +  USB_XDCI_DEV_CONTEXT            *UsbFuncIoDevPtr;
> > +  DWC_XDCI_ENDPOINT               *EpHandle;
> > +  DWC_XDCI_TRB                    *Trb;
> > +  UINT32                          TrbCtrl;
> > +  UINT32                          TrbSts;
> > +  UINT32                          BufferLen;
> > +  EFI_STATUS                      DevStatus;
> > +  USB_EP_INFO                     EpInfo;
> > +
> > +  UsbFuncIoDevPtr = USBFUIO_CONTEXT_FROM_PROTOCOL (This);
> > +  UsbDeviceCorePtr = UsbFuncIoDevPtr->DrvCore;
> > +  XdciCorePtr = UsbDeviceCorePtr->ControllerHandle;
> > +  EpHandle = &XdciCorePtr->EpHandles[EndPointNum];
> > +  Trb = XdciCorePtr->Trbs + (EndPointNum * DWC_XDCI_TRB_NUM);
> > +
> > +  if (Trb->TrbCtrl & DWC_XDCI_TRB_CTRL_HWO_MASK) {
> > +    DEBUG ((USB_FUIO_DEBUG_EVENT_D, "Ep0XferDone. HW owns TRB:
> %x!!!\n", (UINT32)(UINTN)Trb));
> > +  }
> > +
> > +  DevStatus = EFI_SUCCESS;
> > +  BufferLen = 0;
> > +
> > +  DEBUG ((USB_FUIO_DEBUG_EVENT_D, "EndPointNum:%d, TRB: Addr
> 0x%08x!!!\n", EndPointNum, (UINTN)Trb));
> > +  DEBUG ((USB_FUIO_DEBUG_EVENT_D, "Ep0 done Trb->TrbCtrl: %x!!!\n",
> (UINT32)Trb->TrbCtrl));
> > +  DEBUG ((USB_FUIO_DEBUG_EVENT_D, "Ep0 done Trb->LenXferParams:
> %x!!!\n", (UINT32)Trb->LenXferParams));
> > +  DEBUG ((USB_FUIO_DEBUG_EVENT_D, "Ep0 done Trb->BuffPtrLow:
> %x!!!\n", (UINT32)Trb->BuffPtrLow));
> > +  DEBUG ((USB_FUIO_DEBUG_EVENT_D, "Ep0 done Trb->BuffPtrHigh:
> %x!!!\n", (UINT32)Trb->BuffPtrHigh));
> > +
> > +  //
> > +  // Set CheckFlag to FALSE for 'DwcXdciEpRxData' function
> > +  // check the RX request complete and continue next transfer request
> > +  //
> > +  EpHandle->CheckFlag = FALSE;
> > +  EpHandle->CurrentXferRscIdx = 0;
> > +
> > +  DEBUG ((USB_FUIO_DEBUG_EVENT_I, "Ep0 done D01!!\n"));
> > +  TrbCtrl = (Trb->TrbCtrl & DWC_XDCI_TRB_CTRL_TYPE_MASK) >>
> DWC_XDCI_TRB_CTRL_TYPE_BIT_POS;
> > +
> > +  DEBUG ((USB_FUIO_DEBUG_EVENT_I, "Ep0 done D02!!\n"));
> > +  TrbSts = (Trb->LenXferParams & DWC_XDCI_TRB_STATUS_MASK) >>
> DWC_XDCI_TRB_STATUS_BIT_POS;
> > +
> > +  DEBUG ((USB_FUIO_DEBUG_EVENT_I, "Ep0 done D03!!\n" ));
> > +  BufferLen = Trb->LenXferParams & DWC_XDCI_TRB_BUFF_SIZE_MASK;
> > +
> > +  DEBUG ((USB_FUIO_DEBUG_EVENT_I, "Ep0 done D04 TrbCtrl :: %x!!\n",
> TrbCtrl));
> > +  switch (TrbCtrl) {
> > +    case DWC_XDCI_TRB_CTRL_TYPE_SETUP:
> > +      DEBUG ((USB_FUIO_DEBUG_EVENT_D, "Ep0 done
> DWC_XDCI_TRB_CTRL_TYPE_SETUP!!\n"));
> > +      //
> > +      // This is delay for other host USB controller(none Intel), identify
> device get fail issue.
> > +      //
> > +      gBS->Stall(130);
> > +      BufferLen = 8;
> > +
> > +      DEBUG ((USB_FUIO_DEBUG_EVENT_D,
> "DWC_XDCI_TRB_CTRL_TYPE_SETUP!!\n"));
> > +      DEBUG ((USB_FUIO_DEBUG_EVENT_D,
> "AlignedSetupBuffer::0x%08x!!\n", XdciCorePtr->AlignedSetupBuffer));
> > +      DEBUG ((USB_FUIO_DEBUG_EVENT_D, "Payload::0x%08x!!\n",
> (UINTN)Payload));
> > +      DEBUG ((USB_FUIO_DEBUG_EVENT_D, "BufferLen::0x%08x!!\n",
> (UINTN)BufferLen));
> > +      *Message = EfiUsbMsgSetupPacket;
> > +      CopyMem (Payload, XdciCorePtr->AlignedSetupBuffer, BufferLen);
> > +
> > +      DEBUG ((USB_FUIO_DEBUG_EVENT_I, "Ep0 done D06!!\n"));
> > +      if (!(XdciCorePtr->AlignedSetupBuffer[0] &
> USB_SETUP_DATA_PHASE_DIRECTION_MASK)) {
> > +        if ((XdciCorePtr->AlignedSetupBuffer[0]  == 0x00) ) {
> > +          if ((XdciCorePtr->AlignedSetupBuffer[1]  ==
> USB_DEV_SET_ADDRESS)) {
> > +            //
> > +            // set address
> > +            //
> > +            UsbSetAddress (
> > +              This,
> > +              (UINT32)(XdciCorePtr->AlignedSetupBuffer[3] << 8 | XdciCorePtr-
> >AlignedSetupBuffer[2])
> > +              );
> > +
> > +            *Message = EfiUsbMsgNone;
> > +          } else if ((XdciCorePtr->AlignedSetupBuffer[1]  ==
> USB_DEV_SET_CONFIGURATION)) {
> > +            DEBUG ((USB_FUIO_DEBUG_EVENT_I, "\n set configure !!!"));
> > +            UsbSetconfigure (
> > +              This,
> > +              (UINT32)(XdciCorePtr->AlignedSetupBuffer[3] << 8 | XdciCorePtr-
> >AlignedSetupBuffer[2])
> > +              );
> > +            *Message = EfiUsbMsgNone;
> > +          }
> > +        }
> > +      }
> > +
> > +      DEBUG ((USB_FUIO_DEBUG_EVENT_I, "Ep0 done D07!!\n"));
> > +      break;
> > +
> > +    case DWC_XDCI_TRB_CTRL_TYPE_DATA:
> > +      DEBUG ((DEBUG_INFO, "Ep0 done
> DWC_XDCI_TRB_CTRL_TYPE_DATA!!\n"));
> > +	  //
> > +      // Notify upper layer of control transfer completion
> > +      // if a callback function was registerd
> > +      //
> > +      if ((EndPointNum & 0x01) == 0) {
> > +        *Message = EfiUsbMsgEndpointStatusChangedRx;
> > +      } else {
> > +        *Message = EfiUsbMsgEndpointStatusChangedTx;
> > +      }
> > +      Payload->utr.EndpointIndex = (UINT8)(EndPointNum >> 1);
> > +      Payload->utr.Direction = (UINT8)(EndPointNum & 0x01);
> > +      Payload->utr.Buffer = (VOID*)(UINTN)(Trb->BuffPtrLow);
> > +
> > +      DEBUG ((DEBUG_INFO, "Ep0 EndPointNum: %x!!!\n",
> (UINT32)EndPointNum));
> > +      DEBUG ((DEBUG_INFO, "Ep0 done XferLength: %x!!!\n",
> (UINT32)UsbFuncIoDevPtr->EndPointXferRec[EndPointNum].XferLength));
> > +      Payload->utr.Buffer = (VOID*)UsbFuncIoDevPtr-
> >EndPointXferRec[EndPointNum].XferAddress;
> > +      Payload->utr.BytesTransferred = UsbFuncIoDevPtr-
> >EndPointXferRec[EndPointNum].XferLength;
> > +
> > +      if (TrbSts == 0) {
> > +        if ((Trb->LenXferParams & DWC_XDCI_TRB_BUFF_SIZE_MASK) == 0) {
> > +          Payload->utr.TransferStatus = UsbTransferStatusComplete;
> > +        } else {
> > +          Payload->utr.TransferStatus = UsbTransferStatusActive;
> > +        }
> > +      } else if (TrbSts != 0) {
> > +        Trb->TrbCtrl |= DWC_XDCI_TRB_CTRL_HWO_MASK;
> > +        *Message = EfiUsbMsgNone;
> > +        Payload->utr.TransferStatus = UsbTransferStatusAborted;
> > +        DEBUG ((DEBUG_INFO, "Flush FIFO!!!\n" ));
> > +        EpInfo.EpNum = 0;
> > +        EpInfo.EpDir =UsbEpDirIn;
> > +        UsbXdciCoreFlushEpFifo(XdciCorePtr, &EpInfo);
> > +        EpInfo.EpNum = 0;
> > +        EpInfo.EpDir =UsbEpDirOut;
> > +        UsbXdciCoreFlushEpFifo(XdciCorePtr, &EpInfo);
> > +        DevStatus = UsbDeviceEp0RxSetup (UsbDeviceCorePtr, XdciCorePtr-
> >AlignedSetupBuffer);
> > +      }
> > +
> > +      break;
> > +
> > +    case DWC_XDCI_TRB_CTRL_TYPE_STATUS2:
> > +    case DWC_XDCI_TRB_CTRL_TYPE_STATUS3:
> > +      Payload->utr.Buffer = (VOID*) UsbFuncIoDevPtr-
> >EndPointXferRec[EndPointNum].XferAddress;
> > +      Payload->utr.BytesTransferred = 0;
> > +      Payload->utr.EndpointIndex = (UINT8)(EndPointNum >> 1);
> > +      if ((EndPointNum & 0x01) == 0) {
> > +        *Message = EfiUsbMsgEndpointStatusChangedRx;
> > +      } else {
> > +        *Message = EfiUsbMsgEndpointStatusChangedTx;
> > +      }
> > +
> > +      if (TrbSts == 0) {
> > +        if ((Trb->LenXferParams & DWC_XDCI_TRB_BUFF_SIZE_MASK) == 0) {
> > +          Payload->utr.TransferStatus = UsbTransferStatusComplete;
> > +        } else {
> > +          Payload->utr.TransferStatus = UsbTransferStatusActive;
> > +        }
> > +      } else if (TrbSts != 0) {
> > +        Payload->utr.TransferStatus = UsbTransferStatusAborted;
> > +      }
> > +
> > +      DevStatus = UsbDeviceEp0RxSetup (UsbDeviceCorePtr, XdciCorePtr-
> >AlignedSetupBuffer);
> > +
> > +      if (DevStatus) {
> > +        DEBUG ((DEBUG_INFO, "DwcXdciProcessEp0XferPhaseDone: FAILED
> to queue SETUP\n"));
> > +      }
> > +      DEBUG ((DEBUG_INFO, "Status phase done. Queue next SETUP
> packet==>\n"));
> > +      break;
> > +
> > +    default:
> > +      *Message = EfiUsbMsgNone;
> > +      DEBUG ((DEBUG_INFO, "DwcXdciProcessEp0XferPhaseDone:
> UNHANDLED STATE in TRB\n"));
> > +      break;
> > +  }
> > +  return EFI_SUCCESS;
> > +}
> > +
> > +
> > +EFI_STATUS
> > +NoneEp0XferDone(
> > +  IN  EFI_USBFN_IO_PROTOCOL       *This,
> > +  IN  UINT32                      EndPointNum,
> > +  OUT EFI_USBFN_MESSAGE           *Message,
> > +  IN OUT UINTN                    *PayloadSize,
> > +  OUT EFI_USBFN_MESSAGE_PAYLOAD   *Payload
> > +  )
> > +{
> > +  USB_DEV_CORE                    *UsbDeviceCorePtr;
> > +  XDCI_CORE_HANDLE                *XdciCorePtr;
> > +  USB_XDCI_DEV_CONTEXT            *UsbFuncIoDevPtr;
> > +  DWC_XDCI_ENDPOINT               *EpHandle;
> > +  DWC_XDCI_TRB                    *Trb;
> > +  UINT32                          TrbCtrl;
> > +  UINT32                          TrbSts;
> > +
> > +  UsbFuncIoDevPtr = USBFUIO_CONTEXT_FROM_PROTOCOL (This);
> > +  UsbDeviceCorePtr = UsbFuncIoDevPtr->DrvCore;
> > +  XdciCorePtr = UsbDeviceCorePtr->ControllerHandle;
> > +  EpHandle = &XdciCorePtr->EpHandles[EndPointNum];
> > +  Trb = XdciCorePtr->Trbs + (EndPointNum * DWC_XDCI_TRB_NUM);
> > +
> > +  if (Trb->TrbCtrl & DWC_XDCI_TRB_CTRL_HWO_MASK) {
> > +    DEBUG ((USB_FUIO_DEBUG_EVENT_D, "NoneEp0XferDone. HW owns
> TRB: %x!!!, EndPointNum: %x\n", (UINT32)(UINTN)Trb, EndPointNum));
> > +  }
> > +
> > +  DEBUG ((USB_FUIO_DEBUG_EVENT_D, " TRB: Addr 0x%08x!!!\n",
> (UINTN)Trb));
> > +  DEBUG ((USB_FUIO_DEBUG_EVENT_D, " Xfer done Trb->BuffPtrLow:
> %x!!!\n", (UINT32)Trb->BuffPtrLow));
> > +  DEBUG ((USB_FUIO_DEBUG_EVENT_D, " Xfer done Trb->BuffPtrHigh:
> %x!!!\n", (UINT32)Trb->BuffPtrHigh));
> > +  DEBUG ((USB_FUIO_DEBUG_EVENT_D, " Xfer done Trb->LenXferParams:
> %x!!!\n", (UINT32)Trb->LenXferParams));
> > +  DEBUG ((USB_FUIO_DEBUG_EVENT_D, " Xfer done Trb->TrbCtrl:
> %x!!!\n", (UINT32)Trb->TrbCtrl));
> > +
> > +  //
> > +  // Set CheckFlag to FALSE for 'DwcXdciEpRxData' function
> > +  // check the RX request complete and continue next transfer request
> > +  //
> > +  EpHandle->CheckFlag = FALSE;
> > +  EpHandle->CurrentXferRscIdx = 0;
> > +  *Message = EfiUsbMsgNone;
> > +
> > +  TrbCtrl = (Trb->TrbCtrl & DWC_XDCI_TRB_CTRL_TYPE_MASK) >>
> DWC_XDCI_TRB_CTRL_TYPE_BIT_POS;
> > +  TrbSts = (Trb->LenXferParams & DWC_XDCI_TRB_STATUS_MASK) >>
> DWC_XDCI_TRB_STATUS_BIT_POS;
> > +
> > +  Payload->utr.BytesTransferred = UsbFuncIoDevPtr-
> >EndPointXferRec[EndPointNum].XferLength;
> > +  Payload->utr.EndpointIndex = UsbFuncIoDevPtr-
> >EndPointXferRec[EndPointNum].LogEpNum;
> > +  Payload->utr.Direction = UsbFuncIoDevPtr-
> >EndPointXferRec[EndPointNum].Direction;
> > +  Payload->utr.Buffer = (VOID*)(UINTN)(Trb->BuffPtrLow);
> > +  UsbFuncIoDevPtr->EndPointXferRec[EndPointNum].Complete = TRUE;
> > +
> > +  DEBUG ((USB_FUIO_DEBUG_EVENT_D, "EndPointAddress = 0x%08x\n",
> Payload->utr.EndpointIndex));
> > +  if (Payload->utr.Direction == EfiUsbEndpointDirectionDeviceTx) {
> > +    DEBUG ((USB_FUIO_DEBUG_EVENT_D, "
> Direction::EfiUsbEndpointDirectionDeviceTx\n"));
> > +    *Message = EfiUsbMsgEndpointStatusChangedTx;
> > +  } else {
> > +    DEBUG ((USB_FUIO_DEBUG_EVENT_D, "
> Direction::EfiUsbEndpointDirectionDeviceRx\n"));
> > +    *Message = EfiUsbMsgEndpointStatusChangedRx;
> > +  }
> > +
> > +  if (TrbSts == 0) {
> > +    if ((Trb->LenXferParams & DWC_XDCI_TRB_BUFF_SIZE_MASK) == 0) {
> > +      Payload->utr.TransferStatus = UsbTransferStatusComplete;
> > +      DEBUG ((USB_FUIO_DEBUG_EVENT_D,
> "XferStatus::UsbTransferStatusComplete\n"));
> > +    } else {
> > +      Payload->utr.TransferStatus = UsbTransferStatusComplete;
> > +      Payload->utr.BytesTransferred -= (Trb->LenXferParams &
> DWC_XDCI_TRB_BUFF_SIZE_MASK);
> > +      DEBUG ((USB_FUIO_DEBUG_EVENT_D,
> "XferStatus::UsbTransferStatusComplete\n"));
> > +      DEBUG ((USB_FUIO_DEBUG_EVENT_D, "XferStatus::Length %d \n",
> Payload->utr.BytesTransferred ));
> > +    }
> > +  } else if (TrbSts != 0) {
> > +    Payload->utr.TransferStatus = UsbTransferStatusAborted;
> > +    DEBUG ((USB_FUIO_DEBUG_EVENT_D,
> "XferStatus::UsbTransferStatusAborted\n"));
> > +  }
> > +
> > +  return EFI_SUCCESS;
> > +}
> > +
> > +EFI_STATUS
> > +Ep0XferNotReady(
> > +  IN  EFI_USBFN_IO_PROTOCOL       *This,
> > +  IN  UINT32                      EndPointNum,
> > +  OUT EFI_USBFN_MESSAGE           *Message,
> > +  IN OUT UINTN                    *PayloadSize,
> > +  OUT EFI_USBFN_MESSAGE_PAYLOAD   *Payload,
> > +  IN  UINT32                      EpStatus
> > +  )
> > +{
> > +  USB_DEV_CORE                    *UsbDeviceCorePtr;
> > +  XDCI_CORE_HANDLE                *XdciCorePtr;
> > +  USB_XDCI_DEV_CONTEXT            *UsbFuncIoDevPtr;
> > +
> > +  UsbFuncIoDevPtr = USBFUIO_CONTEXT_FROM_PROTOCOL(This);
> > +  UsbDeviceCorePtr = UsbFuncIoDevPtr->DrvCore;
> > +  XdciCorePtr = UsbDeviceCorePtr->ControllerHandle;
> > +
> > +  *Message = EfiUsbMsgNone;
> > +
> > +  return EFI_SUCCESS;
> > +}
> > +
> > +
> > +EFI_STATUS
> > +EpEventCheck(
> > +  IN  EFI_USBFN_IO_PROTOCOL       *This,
> > +  IN  USBD_EVENT_BUF              *EventIndex,
> > +  OUT UINT32                      *ProcessSize,
> > +  OUT EFI_USBFN_MESSAGE           *Message,
> > +  IN OUT UINTN                    *PayloadSize,
> > +  OUT EFI_USBFN_MESSAGE_PAYLOAD   *Payload,
> > +  OUT BOOLEAN                     *EventFlag
> > +  )
> > +{
> > +  USB_DEV_CORE                    *UsbDeviceCorePtr;
> > +  XDCI_CORE_HANDLE                *XdciCorePtr;
> > +  USB_XDCI_DEV_CONTEXT            *UsbFuncIoDevPtr;
> > +  UINT32                          EventReg;
> > +  UINT32                          EpEvent;
> > +  UINT32                          EndPointNumber;
> > +  UINT32                          EventStatus;
> > +  USB_EP_STATE                    Ep_State;
> > +  UINTN                           TmpBufferSize;
> > +
> > +  DEBUG ((USB_FUIO_DEBUG_EVENT_I, "FUEV::EndPoint Event....\n"));
> > +  UsbFuncIoDevPtr = USBFUIO_CONTEXT_FROM_PROTOCOL(This);
> > +
> > +  UsbDeviceCorePtr = UsbFuncIoDevPtr->DrvCore;
> > +  XdciCorePtr = UsbDeviceCorePtr->ControllerHandle;
> > +  EventReg = EventIndex->Event;
> > +  *ProcessSize = DWC_XDCI_DEV_EVENT_DEFAULT_SIZE_IN_BYTES;
> > +  *EventFlag = TRUE;
> > +  TmpBufferSize = 0;
> > +
> > +  //
> > +  // Get EP num
> > +  //
> > +  EndPointNumber = (EventReg &
> DWC_XDCI_EVENT_BUFF_EP_NUM_MASK) >>
> DWC_XDCI_EVENT_BUFF_EP_NUM_BIT_POS;
> > +
> > +  EventStatus = EventReg &
> DWC_XDCI_EVENT_BUFF_EP_EVENT_STATUS_MASK;
> > +
> > +  //
> > +  // Interpret event and handle transfer completion here
> > +  //
> > +  EpEvent = (EventReg & DWC_XDCI_EVENT_BUFF_EP_EVENT_MASK) >>
> DWC_XDCI_EVENT_BUFF_EP_EVENT_BIT_POS;
> > +
> > +  DEBUG ((USB_FUIO_DEBUG_EVENT_I, "USBFU_EP EventReg 0x%08x\n",
> EventReg));
> > +
> > +  switch (EpEvent) {
> > +    case DWC_XDCI_EVENT_BUFF_EP_XFER_CMPLT:
> > +      DEBUG ((USB_FUIO_DEBUG_EVENT_D, "USBFU_EP
> DWC_XDCI_EVENT_BUFF_EP_XFER_CMPLT\n"));
> > +      if (EndPointNumber > 1) {
> > +        DEBUG ((USB_FUIO_DEBUG_EVENT_D, "USBFU_EP None_Control
> transfer\n"));
> > +        NoneEp0XferDone (This, EndPointNumber, Message, PayloadSize,
> Payload);
> > +      } else {
> > +        //
> > +        // Control transfer
> > +        //
> > +        DEBUG ((USB_FUIO_DEBUG_EVENT_D, "USBFU_EP Control
> transfer\n"));
> > +        Ep0XferDone (This, EndPointNumber, Message, PayloadSize,
> Payload);
> > +      }
> > +      break;
> > +
> > +    case DWC_XDCI_EVENT_BUFF_EP_XFER_NOT_READY:
> > +      DEBUG ((USB_FUIO_DEBUG_EVENT_D,
> "DWC_XDCI_EVENT_BUFF_EP_XFER_NOT_READY\n"));
> > +      *Message = EfiUsbMsgNone;
> > +      if(EndPointNumber < (sizeof(UsbFuncIoDevPtr->EndPointXferRec) /
> sizeof(UsbFuncIoDevPtr->EndPointXferRec[0]))) {
> > +        if ((UsbFuncIoDevPtr->EndPointXferRec[EndPointNumber].ZlpFlag ==
> TRUE) && \
> > +              (UsbFuncIoDevPtr->EndPointXferRec[EndPointNumber].Complete
> == TRUE)) {
> > +          DEBUG ((USB_FUIO_DEBUG_EVENT_D, "Request send ZLP\n"));
> > +          if ((EndPointNumber & 0x01) != 0) {
> > +            Transfer(This,
> > +                     UsbFuncIoDevPtr->IndexPtrInEp.EndpointDesc-
> >EndpointAddress,
> > +                     EfiUsbEndpointDirectionDeviceTx,
> > +                     &TmpBufferSize,
> > +                     NULL
> > +                    );
> > +            UsbFuncIoDevPtr->EndPointXferRec[EndPointNumber].ZlpFlag =
> FALSE;
> > +          }
> > +
> > +        }
> > +      } else {
> > +        //
> > +        // Is it data stage or status stage
> > +        //
> > +        // Data Statge
> > +        //
> > +        Ep_State = USB_EP_STATE_DATA;
> > +        //
> > +        // Control transfer
> > +        //
> > +        DEBUG ((USB_FUIO_DEBUG_EVENT_D, "USBFU_EP Control transfer
> not ready\n"));
> > +        Ep0XferNotReady (This, EndPointNumber, Message, PayloadSize,
> Payload, EventStatus);
> > +        *EventFlag = FALSE;
> > +      }
> > +      break;
> > +
> > +    case DWC_XDCI_EVENT_BUFF_EP_XFER_IN_PROGRESS:
> > +      DEBUG ((USB_FUIO_DEBUG_EVENT_D,
> "DWC_XDCI_EVENT_BUFF_EP_XFER_IN_PROGRESS\n"));
> > +      break;
> > +
> > +    default:
> > +      DEBUG ((USB_FUIO_DEBUG_EVENT_I, "USBFUDwcXdciProcessEpEvent:
> UNKNOWN EP event\n"));
> > +      break;
> > +  }
> > +
> > +  DEBUG ((USB_FUIO_DEBUG_EVENT_D, "FUEV::EndPoint
> Event....exit\n"));
> > +  return EFI_SUCCESS;
> > +}
> > +
> > +
> > +EFI_STATUS
> > +ProcessIntLineEvents(
> > +  IN EFI_USBFN_IO_PROTOCOL        *This,
> > +  IN UINT32                       EventCount,
> > +  IN UINT32                       *ProceSsEvent,
> > +  OUT EFI_USBFN_MESSAGE           *Message,
> > +  IN OUT UINTN                    *PayloadSize,
> > +  OUT EFI_USBFN_MESSAGE_PAYLOAD   *Payload,
> > +  OUT BOOLEAN                     *EventFlag
> > +  )
> > +{
> > +  USB_DEV_CORE                    *UsbDeviceCorePtr;
> > +  XDCI_CORE_HANDLE                *XdciCorePtr;
> > +  USB_XDCI_DEV_CONTEXT            *UsbFuncIoDevPtr;
> > +  UINT32                          CurrentEventAddr;
> > +  UINT32                          ProceSsEventSize;
> > +  BOOLEAN                         EventReport;
> > +  BOOLEAN                         EpEventReport;
> > +
> > +  UsbFuncIoDevPtr = USBFUIO_CONTEXT_FROM_PROTOCOL (This);
> > +  UsbDeviceCorePtr = UsbFuncIoDevPtr->DrvCore;
> > +  XdciCorePtr = UsbDeviceCorePtr->ControllerHandle;
> > +  CurrentEventAddr = (UINT32)(UINTN)(XdciCorePtr->CurrentEventBuffer);
> > +  EventReport = FALSE;
> > +  EpEventReport = FALSE;
> > +  ProceSsEventSize = 0;
> > +   DEBUG ((USB_FUIO_DEBUG_EVENT_I, "FUEV:: ProcessIntLineEvents
> Entry\n"));
> > +
> > +   DEBUG ((USB_FUIO_DEBUG_EVENT_I, "FUEV:: XdciCorePtr-
> >CurrentEventBuffer 0x%08x\n", XdciCorePtr->CurrentEventBuffer));
> > +   DEBUG ((USB_FUIO_DEBUG_EVENT_I, "FUEV::EventCount0x%08x\n",
> EventCount));
> > +   DEBUG ((USB_FUIO_DEBUG_EVENT_I, "FUEV::CurrentEventAddr
> 0x%08x\n", CurrentEventAddr));
> > +
> > +  while ((EventCount != 0) && (EventReport == FALSE)) {
> > +     DEBUG ((USB_FUIO_DEBUG_EVENT_D, "FUEV::event0x%08x\n",
> XdciCorePtr->CurrentEventBuffer->Event));
> > +     if ((XdciCorePtr->CurrentEventBuffer->Event &
> DWC_XDCI_EVENT_DEV_MASK) != 0) {
> > +       //
> > +       // Device event
> > +       //
> > +       DeviceEventCheck (
> > +         This,
> > +         (USBD_EVENT_BUF*)(UINTN)CurrentEventAddr,
> > +         &ProceSsEventSize,
> > +         Message,
> > +         &EventReport
> > +         );
> > +       if (EventReport == TRUE) {
> > +         *EventFlag = TRUE;
> > +       }
> > +
> > +     } else {
> > +       //
> > +       // EndPoint Event
> > +       //
> > +       EpEventCheck (
> > +         This,
> > +         (USBD_EVENT_BUF*)(UINTN)CurrentEventAddr,
> > +         &ProceSsEventSize,
> > +         Message,
> > +         PayloadSize,
> > +         Payload,
> > +         &EpEventReport
> > +         );
> > +     }
> > +
> > +     if ((*Message != EfiUsbMsgNone) || (EpEventReport == TRUE)) {
> > +       EventReport = TRUE;
> > +       *EventFlag = TRUE;
> > +     }
> > +
> > +     DEBUG ((USB_FUIO_DEBUG_EVENT_D, "FUEV:: CurrentEventAddr
> 0x%08x :: ProceSsEventSize 0x%08x\n",
> (UINTN)CurrentEventAddr,ProceSsEventSize));
> > +
> > +     EventCount -= ProceSsEventSize;
> > +     *ProceSsEvent += ProceSsEventSize;
> > +     if ((CurrentEventAddr + ProceSsEventSize) >= \
> > +         ((UINT32)(UINTN)(XdciCorePtr->AlignedEventBuffers) +
> > +          (sizeof(DWC_XDCI_EVENT_BUFFER) *
> DWC_XDCI_MAX_EVENTS_PER_BUFFER))) {
> > +       CurrentEventAddr = (UINT32)(UINTN)(XdciCorePtr-
> >AlignedEventBuffers);
> > +    } else {
> > +      CurrentEventAddr += ProceSsEventSize;
> > +    }
> > +    DEBUG ((USB_FUIO_DEBUG_EVENT_D, "FUEV:: CurrentEventAddr
> Update 0x%08x :: ProceSsEventSize 0x%08x\n",
> CurrentEventAddr,ProceSsEventSize));
> > +
> > +    XdciCorePtr->CurrentEventBuffer =
> (DWC_XDCI_EVENT_BUFFER*)(UINTN)CurrentEventAddr;
> > +  }
> > +
> > +  DEBUG ((USB_FUIO_DEBUG_EVENT_I, "FUEV:: ProcessIntLineEvents
> Exit\n\n"));
> > +  return EFI_SUCCESS;
> > +}
> > +
> > +
> > +/**
> > +  ISR inokes Event Handler.  Look at which interrupt has happened and see
> > +  if there are event handler registerd and if so fire them 1 by one.
> > +
> > +  @param[in]  This              A pointer to the EFI_USBFN_IO_PROTOCOL
> instance.
> > +  @param[in]  Message           Indicates the event that initiated this
> > +                                notification.
> > +  @param[in]  PayloadSize       On input, the size of the memory pointed by
> Payload.
> > +                                On output, the amount of data returned in Payload.
> > +  @param[in]  Payload           A pointer to EFI_USBFN_MESSAGE_PAYLOAD
> instance to
> > +                                return additional payload for current message.
> > +
> > +
> > +
> > +
> > +  @retval EFI_SUCCESS           The function returned successfully.
> > +  @retval EFI_INVALID_PARAMETER A parameter is invalid.
> > +  @retval EFI_DEVICE_ERROR      The physical device reported an error.
> > +  @retval EFI_NOT_READY         The physical device is busy or not ready to
> > +                                process this request.
> > +  @retval EFI_BUFFER_TOO_SMALL  Supplied Buffer not large enough to
> hold
> > +                                the message payload.
> > +
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +EventHandler(
> > +  IN EFI_USBFN_IO_PROTOCOL        *This,
> > +  OUT EFI_USBFN_MESSAGE           *Message,
> > +  IN OUT UINTN                    *PayloadSize,
> > +  OUT EFI_USBFN_MESSAGE_PAYLOAD   *Payload
> > +  )
> > +{
> > +  UINT32                          EventCount;
> > +  UINT32                          PeventCount;
> > +  USB_XDCI_DEV_CONTEXT            *UsbFuncIoDevPtr;
> > +  UINT32                          MaxIntNum;
> > +  UINT32                          IntIndex;
> > +  USB_DEV_CORE                    *UsbDeviceCorePtr;
> > +  XDCI_CORE_HANDLE                *XdciCorePtr;
> > +  BOOLEAN                         EventFlag;
> > +  EFI_TPL                         OriginalTpl;
> > +
> > +
> > +  DEBUG ((USB_FUIO_DEBUG_EVENT_I, "USBFU_ EventHandler Entry\n"));
> > +  UsbFuncIoDevPtr = USBFUIO_CONTEXT_FROM_PROTOCOL (This);
> > +
> > +  if (UsbFuncIoDevPtr->StartUpController == FALSE) {
> > +    UsbFnInitDevice (This);
> > +  }
> > +  OriginalTpl = gBS->RaiseTPL (TPL_HIGH_LEVEL);
> > +  *Message = EfiUsbMsgNone;
> > +  MaxIntNum = (UsbRegRead ((UINT32)UsbFuncIoDevPtr-
> >XdciMmioBarAddr, DWC_XDCI_GHWPARAMS1_REG) &
> > +                 DWC_XDCI_GHWPARAMS1_NUM_INT_MASK) >>
> > +                 DWC_XDCI_GHWPARAMS1_NUM_INT_BIT_POS;
> > +
> > +  UsbDeviceCorePtr = UsbFuncIoDevPtr->DrvCore;
> > +  XdciCorePtr = UsbDeviceCorePtr->ControllerHandle;
> > +  EventFlag = TRUE;
> > +
> > +  DEBUG ((USB_FUIO_DEBUG_EVENT_I, "XdciCorePtr->MaxDevIntLines
> 0x%08x\n", XdciCorePtr->MaxDevIntLines));
> > +  EventCount = UsbRegRead ((UINT32)UsbFuncIoDevPtr-
> >XdciMmioBarAddr, DWC_XDCI_EVNTCOUNT_REG(0));
> > +
> > +  for (IntIndex = 0; IntIndex < XdciCorePtr->MaxDevIntLines ; IntIndex++) {
> > +    //
> > +    // Get the number of events HW has written for this
> > +    //  interrupt line
> > +    //
> > +    EventCount = UsbRegRead ((UINT32)UsbFuncIoDevPtr-
> >XdciMmioBarAddr, DWC_XDCI_EVNTCOUNT_REG(IntIndex));
> > +    EventCount &= DWC_XDCI_EVNTCOUNT_MASK;
> > +    PeventCount = 0;
> > +
> > +    //
> > +    // Process interrupt line Buffer only if count is non-zero
> > +    //
> > +    if (EventCount) {
> > +      //
> > +      // Process events in this Buffer
> > +      //
> > +      ProcessIntLineEvents (
> > +        This,
> > +        EventCount,
> > +        &PeventCount,
> > +        Message,
> > +        PayloadSize,
> > +        Payload,
> > +        &EventFlag
> > +        );
> > +
> > +      //
> > +      // Write back the Processed number of events so HW decrements it
> from current
> > +      // event count
> > +      //
> > +      UsbRegWrite ((UINT32)UsbFuncIoDevPtr->XdciMmioBarAddr,
> DWC_XDCI_EVNTCOUNT_REG(IntIndex), PeventCount);
> > +
> > +      //
> > +      // for debug
> > +      //
> > +      if (*Message != EfiUsbMsgNone) {
> > +        break;
> > +      }
> > +
> > +      if (EventFlag == TRUE) {
> > +        break;
> > +      }
> > +    }
> > +  }
> > +
> > +  gBS->RestoreTPL (OriginalTpl);
> > +  //
> > +  //EVENT_EXIT:
> > +  //
> > +  DEBUG ((USB_FUIO_DEBUG_EVENT_I, "USBFU_ EventHandler Exit\n"));
> > +  return EFI_SUCCESS;
> > +}
> > +
> > +
> > +
> > +/**
> > +  Copies relevant endpoint data from standard USB endpoint descriptors
> > +  to the usbEpInfo structure used by the XDCI
> > +
> > +  @param pEpDest   destination structure
> > +  @param pEpSrc    source structure
> > +
> > +  @return VOID
> > +
> > +**/
> > +VOID
> > +UsbFnSetEpInfo (
> > +  IN USB_EP_INFO                 *EpDest,
> > +  IN USB_DEVICE_ENDPOINT_INFO    *EpSrc
> > +  )
> > +{
> > +  EFI_USB_ENDPOINT_DESCRIPTOR              *EpDesc = NULL;
> > +  EFI_USB_ENDPOINT_COMPANION_DESCRIPTOR    *EpCompDesc = NULL;
> > +
> > +  //
> > +  // start by clearing all data in the destination
> > +  //
> > +  SetMem (EpDest, sizeof(USB_EP_INFO), 0);
> > +  EpDesc = EpSrc->EndpointDesc;
> > +  EpCompDesc = EpSrc->EndpointCompDesc;
> > +
> > +  if (EpDesc != NULL) {
> > +    EpDest->EpNum = EpDesc->EndpointAddress & 0x0F; // Bits 0-3 are ep
> num
> > +    EpDest->EpDir = ((EpDesc->EndpointAddress & USB_ENDPOINT_DIR_IN)
> > 0) ? UsbEpDirIn : UsbEpDirOut;
> > +    DEBUG ((DEBUG_INFO, "EpDest->EpNum 0x%02x\n", EpDest->EpNum));
> > +    DEBUG ((DEBUG_INFO, "EpDest->EpDir 0x%02x\n", EpDest->EpDir));
> > +    EpDest->EpType = EpDesc->Attributes & USB_ENDPOINT_TYPE_MASK;
> > +    EpDest->MaxPktSize = EpDesc->MaxPacketSize;
> > +    EpDest->Interval = EpDesc->Interval;
> > +  }
> > +  if (EpCompDesc != NULL) {
> > +    EpDest->MaxStreams = EpCompDesc->Attributes &
> USB_EP_BULK_BM_ATTR_MASK;
> > +    EpDest->BurstSize = EpCompDesc->MaxBurst;
> > +    EpDest->Mult = EpCompDesc->BytesPerInterval;
> > +  }
> > +
> > +  return;
> > +}
> > +
> > +
> > +EFI_STATUS
> > +SetFnIoReqInfo(
> > +  IN     EFI_USBFN_IO_PROTOCOL         *This,
> > +  IN     UINT8                         EndpointIndex,
> > +  IN     EFI_USBFN_ENDPOINT_DIRECTION  Direction,
> > +  IN OUT UINTN                         *BufferSize,
> > +  IN OUT VOID                          *Buffer,
> > +  IN OUT USB_XFER_REQUEST              *XfIoreq
> > +  )
> > +{
> > +  USB_XDCI_DEV_CONTEXT     *UsbFuncIoDevPtr;
> > +  EFI_STATUS               Status;
> > +  UINTN                    ReqPacket;
> > +
> > +  UsbFuncIoDevPtr = USBFUIO_CONTEXT_FROM_PROTOCOL (This);
> > +  Status = EFI_SUCCESS;
> > +  ReqPacket = 0;
> > +
> > +  switch (EndpointIndex) {
> > +    case 0: // Control endpoint
> > +      XfIoreq->EpInfo.EpNum = 0;
> > +      XfIoreq->EpInfo.EpDir = Direction? UsbEpDirIn : UsbEpDirOut;
> > +      break;
> > +
> > +
> > +    default:
> > +      if (Direction == EfiUsbEndpointDirectionDeviceTx) {
> > +        UsbFnSetEpInfo (&XfIoreq->EpInfo, &UsbFuncIoDevPtr-
> >IndexPtrInEp);
> > +      } else {
> > +        UsbFnSetEpInfo (&XfIoreq->EpInfo, &UsbFuncIoDevPtr-
> >IndexPtrOutEp);
> > +        //
> > +        // reference from "UsbDeviceMode.c", function UsbdEpRxData
> > +        //
> > +
> > +        //
> > +        // Transfer length should be multiple of USB packet size.
> > +        //
> > +        ReqPacket = *BufferSize/ XfIoreq->EpInfo.MaxPktSize;
> > +        ReqPacket = ((XfIoreq->XferLen % XfIoreq->EpInfo.MaxPktSize) == 0)?
> ReqPacket : ReqPacket + 1;
> > +        XfIoreq->XferLen = (UINT32)ReqPacket * XfIoreq->EpInfo.MaxPktSize;
> > +
> > +      }
> > +      break;
> > +  }
> > +
> > +  if (EFI_ERROR(Status)) {
> > +    return EFI_UNSUPPORTED;
> > +  }
> > +
> > +  XfIoreq->XferBuffer = Buffer;
> > +  XfIoreq->XferLen = (UINT32)(*BufferSize);
> > +  XfIoreq->XferDone = NULL;
> > +
> > +  return EFI_SUCCESS;
> > +}
> > +
> > +
> > +/**
> > +  Primary function to handle transfer in either direction Based on specified
> > +  direction and on the specified endpoint.
> > +
> > +  @param[in]  This              A pointer to the EFI_USBFN_IO_PROTOCOL
> instance.
> > +  @param[in]  EndpointIndex     Indicates the endpoint on which TX or RX
> transfer
> > +                                needs to take place.
> > +  @param[in]  Direction         Direction of the endpoint.
> > +  @param[in]  BufferSize        If Direction is
> EfiUsbEndpointDirectionDeviceRx:
> > +                                On input, the size of the Buffer in bytes.
> > +                                On output, the amount of data returned in Buffer in
> bytes.
> > +                                If Direction is EfiUsbEndpointDirectionDeviceTx:
> > +                                On input, the size of the Buffer in bytes.
> > +                                On output, the amount of data actually transmitted in
> bytes.
> > +  @param[in]  Buffer            If Direction is
> EfiUsbEndpointDirectionDeviceRx:
> > +                                The Buffer to return the received data.
> > +                                If Direction is EfiUsbEndpointDirectionDeviceTx:
> > +                                The Buffer that contains the data to be transmitted.
> > +
> > +  @retval EFI_SUCCESS           The function returned successfully.
> > +  @retval EFI_INVALID_PARAMETER A parameter is invalid.
> > +  @retval EFI_DEVICE_ERROR      The physical device reported an error.
> > +  @retval EFI_NOT_READY         The physical device is busy or not ready to
> > +                                process this request.
> > +
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +Transfer (
> > +  IN EFI_USBFN_IO_PROTOCOL         *This,
> > +  IN UINT8                         EndpointIndex,
> > +  IN EFI_USBFN_ENDPOINT_DIRECTION  Direction,
> > +  IN OUT UINTN                     *BufferSize,
> > +  IN OUT VOID                      *Buffer
> > +  )
> > +{
> > +  USB_XDCI_DEV_CONTEXT              *UsbFuncIoDevPtr;
> > +  USB_DEV_CORE                      *UsbDeviceCorePtr;
> > +  XDCI_CORE_HANDLE                  *XdciCorePtr;
> > +  EFI_STATUS                        Status;
> > +  USB_XFER_REQUEST                  XferReq;
> > +  UINT32                            EndPoint;
> > +
> > +  DEBUG ((USB_FUIO_DEBUG_LOAD, "\n FU:Transfer - Entry\n"));
> > +  DEBUG ((USB_FUIO_DEBUG_LOAD, "\n FU:EndpointIndex 0x%02x\n",
> EndpointIndex));
> > +  DEBUG ((USB_FUIO_DEBUG_LOAD, "\n FU:Direction 0x%02x\n",
> Direction));
> > +
> > +  UsbFuncIoDevPtr = USBFUIO_CONTEXT_FROM_PROTOCOL (This);
> > +
> > +  UsbDeviceCorePtr = UsbFuncIoDevPtr->DrvCore;
> > +  XdciCorePtr = UsbDeviceCorePtr->ControllerHandle;
> > +  EndPoint = UsbGetPhysicalEpNum (EndpointIndex, Direction ?
> UsbEpDirIn : UsbEpDirOut);
> > +
> > +  Status = SetFnIoReqInfo (
> > +             This,
> > +             EndpointIndex,
> > +             Direction,
> > +             BufferSize,
> > +             Buffer,
> > +             &XferReq
> > +             );
> > +
> > +  if (EFI_ERROR(Status)) {
> > +    DEBUG ((USB_FUIO_DEBUG_LOAD, "Set SetFnIoReqInfo - Error
> Stop!!!\n"));
> > +    while(1);
> > +    Status = EFI_DEVICE_ERROR;
> > +    goto FUN_EXIT;
> > +  }
> > +
> > +  UsbFuncIoDevPtr->EndPointXferRec[EndPoint].EpNum = EndPoint;
> > +  UsbFuncIoDevPtr->EndPointXferRec[EndPoint].Direction = Direction;
> > +  UsbFuncIoDevPtr->EndPointXferRec[EndPoint].XferAddress =
> (UINTN)Buffer;
> > +  UsbFuncIoDevPtr->EndPointXferRec[EndPoint].XferLength =
> (UINT32)(*BufferSize);
> > +  UsbFuncIoDevPtr->EndPointXferRec[EndPoint].LogEpNum =
> EndpointIndex;
> > +  UsbFuncIoDevPtr->EndPointXferRec[EndPoint].Complete = FALSE;
> > +  UsbFuncIoDevPtr->EndPointXferRec[EndPoint].ZlpFlag = FALSE;
> > +
> > +  Status = EFI_DEVICE_ERROR;
> > +  switch (EndpointIndex) {
> > +    case 0: // Control endpoint
> > +      if (*BufferSize == 0) {
> > +        if (Direction == EfiUsbEndpointDirectionDeviceTx) {
> > +          Status = UsbDeviceEp0TxStatus(UsbDeviceCorePtr);
> > +        } else {
> > +          Status = UsbDeviceEp0RxStatus(UsbDeviceCorePtr);
> > +        }
> > +      } else if (Direction == EfiUsbEndpointDirectionDeviceTx) {
> > +        Status = UsbXdciDeviceEpTxData(UsbDeviceCorePtr, &XferReq);
> > +      } else if (Direction == EfiUsbEndpointDirectionDeviceRx) {
> > +        DEBUG ((USB_FUIO_DEBUG_LOAD, "\n Set Setup Package - ???
> Stop!!!\n"));
> > +      }
> > +      break;
> > +
> > +    default:
> > +      Status = EFI_SUCCESS;
> > +      if (Direction == EfiUsbEndpointDirectionDeviceTx) {
> > +        DEBUG ((USB_FUIO_DEBUG_LOAD, "\n
> EfiUsbEndpointDirectionDeviceTx Size = %d\n",(*BufferSize) ));
> > +        XferReq.Zlp = TRUE;
> > +        if ((((*BufferSize) % 512) == 0) && ((*BufferSize) != 0)) {
> > +          UsbFuncIoDevPtr->EndPointXferRec[EndPoint].ZlpFlag = TRUE;
> > +          DEBUG ((USB_FUIO_DEBUG_LOAD, "\n Set Zlp flag\n"));
> > +        }
> > +        Status = UsbXdciDeviceEpTxData (UsbDeviceCorePtr, &XferReq);
> > +      } else {
> > +        DEBUG ((USB_FUIO_DEBUG_LOAD, "\n
> EfiUsbEndpointDirectionDeviceRx Size = %d\n",(*BufferSize) ));
> > +        Status = UsbXdciDeviceEpRxData (UsbDeviceCorePtr, &XferReq);
> > +      }
> > +      break;
> > +  }
> > +
> > +  if (EFI_ERROR(Status)) {
> > +    goto FUN_EXIT;
> > +  }
> > +
> > +  if (Status != EFI_SUCCESS) {
> > +    Status = EFI_DEVICE_ERROR;
> > +  }
> > +
> > +FUN_EXIT:
> > +
> > +  DEBUG ((USB_FUIO_DEBUG_LOAD, "FU:Transfer - Exit %r\n", Status));
> > +  return Status;
> > +}
> > +
> > +
> > +/**
> > +  This function supplies power to the USB controller if needed, initialize
> > +  hardware and internal data structures, and then return.
> > +  The port must not be activated by this function.
> > +
> > +  @param[in]  This              A pointer to the EFI_USBFN_IO_PROTOCOL
> instance.
> > +
> > +  @retval EFI_SUCCESS           The function returned successfully.
> > +  @retval EFI_INVALID_PARAMETER A parameter is invalid.
> > +  @retval EFI_DEVICE_ERROR      The physical device reported an error.
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +StartXdciController (
> > +  IN EFI_USBFN_IO_PROTOCOL    *This
> > +  )
> > +{
> > +  USB_XDCI_DEV_CONTEXT         *UsbFuncIoDevPtr;
> > +  USB_DEV_CONFIG_PARAMS        ConfigParams;
> > +  EFI_STATUS                   Status;
> > +
> > +  Status = EFI_SUCCESS;
> > +  UsbFuncIoDevPtr = USBFUIO_CONTEXT_FROM_PROTOCOL (This);
> > +
> > +  if (UsbFuncIoDevPtr->StartUpController == TRUE) {
> > +    goto EXIT_START_CONTROLLER;
> > +  }
> > +
> > +  ConfigParams.ControllerId = USB_ID_DWC_XDCI;
> > +  ConfigParams.BaseAddress = (UINT32)UsbFuncIoDevPtr-
> >XdciMmioBarAddr;
> > +  ConfigParams.Role = USB_ROLE_DEVICE;
> > +  ConfigParams.Speed = USB_SPEED_HIGH;
> > +
> > +  //
> > +  //*Vid = 0x8086
> > +  //*Pid = 0x0A65
> > +  //
> > +  UsbFuncIoDevPtr->VendorId = USBFU_VID;
> > +  UsbFuncIoDevPtr->DeviceId = USBFU_PID;
> > +  UsbFuncIoDevPtr->StartUpController = TRUE;
> > +
> > +  Status = UsbDeviceInit (&ConfigParams, (VOID **)&UsbFuncIoDevPtr-
> >DrvCore);
> > +  if (Status != EFI_SUCCESS) {
> > +    Status = EFI_DEVICE_ERROR;
> > +    goto EXIT_START_CONTROLLER;
> > +  }
> > +
> > +  UsbFuncIoDevPtr->XdciDrvIfHandle = UsbFuncIoDevPtr->DrvCore-
> >ControllerHandle;
> > +
> > +EXIT_START_CONTROLLER:
> > +
> > +  DEBUG ((USB_FUIO_DEBUG_LOAD, "StartXdciController - Exit :: %r\n",
> Status));
> > +  return Status;
> > +}
> > +
> > +
> > +/**
> > +  This function disables the hardware device by resetting the run/stop bit
> > +  and power off the USB controller if needed.
> > +
> > +  @param[in]  This              A pointer to the EFI_USBFN_IO_PROTOCOL
> instance.
> > +
> > +  @retval EFI_SUCCESS           The function returned successfully.
> > +  @retval EFI_INVALID_PARAMETER A parameter is invalid.
> > +  @retval EFI_DEVICE_ERROR      The physical device reported an error.
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +StopXdciController (
> > +  IN EFI_USBFN_IO_PROTOCOL    *This
> > +  )
> > +{
> > +  USB_XDCI_DEV_CONTEXT  *UsbFuncIoDevPtr;
> > +  EFI_STATUS            DevStatus;
> > +
> > +  UsbFuncIoDevPtr = USBFUIO_CONTEXT_FROM_PROTOCOL (This);
> > +  DEBUG ((USB_FUIO_DEBUG_LOAD, "StopController - Entry\n"));
> > +
> > +  if (UsbFuncIoDevPtr->StartUpController == FALSE) {
> > +    DEBUG ((USB_FUIO_DEBUG_LOAD, "The Controller not yet start up skip
> deinit\n"));
> > +    return EFI_SUCCESS;
> > +  }
> > +
> > +  if (This == NULL) {
> > +    return EFI_INVALID_PARAMETER;
> > +  }
> > +
> > +  DevStatus = UsbDeviceDeinit (UsbFuncIoDevPtr->DrvCore, TRUE);
> > +
> > +  UsbFuncIoDevPtr->DrvCore = NULL;
> > +  UsbFuncIoDevPtr->XdciDrvIfHandle = NULL;
> > +  UsbFuncIoDevPtr->StartUpController = FALSE;
> > +
> > +  if (DevStatus != EFI_SUCCESS) {
> > +    return EFI_DEVICE_ERROR;
> > +  }
> > +
> > +  DEBUG ((USB_FUIO_DEBUG_LOAD, "StopController - Exit\n"));
> > +  return EFI_SUCCESS;
> > +}
> > +
> > +
> > +/**
> > +  This function sets the configuration policy for the specified non-control
> endpoint.
> > +  Refer to the description for calling restrictions
> > +
> > +  @param[in]  This              A pointer to the EFI_USBFN_IO_PROTOCOL
> instance.
> > +  @param[in]  EndpointIndex     Indicates the non-control endpoint for
> > +                                which the policy needs to be set.
> > +  @param[in]  Direction         Direction of the endpoint.
> > +  @param[in]  PolicyType        Policy type the user is trying to set for
> > +                                the specified non-control endpoint.
> > +  @param[in]  BufferSize        The size of the Buffer in bytes.
> > +  @param[in]  Buffer            The new value for the policy parameter that
> > +                                PolicyType specifies.
> > +
> > +
> > +  @retval EFI_SUCCESS           The function returned successfully.
> > +  @retval EFI_INVALID_PARAMETER A parameter is invalid.
> > +  @retval EFI_DEVICE_ERROR      The physical device reported an error.
> > +  @retval EFI_UNSUPPORTED       Changing this policy value is not
> supported.
> > +
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +SetEndpointPolicy (
> > +  IN EFI_USBFN_IO_PROTOCOL        *This,
> > +  IN UINT8                        EndpointIndex,
> > +  IN EFI_USBFN_ENDPOINT_DIRECTION Direction,
> > +  IN EFI_USBFN_POLICY_TYPE        PolicyType,
> > +  IN UINTN                        BufferSize,
> > +  IN VOID                         *Buffer
> > +  )
> > +{
> > +  USB_XDCI_DEV_CONTEXT  *UsbFuncIoDevPtr;
> > +  EFI_STATUS            Status;
> > +  UINT32                EndPoint;
> > +  UINT8                 *FlagPtr;
> > +
> > +  UsbFuncIoDevPtr = USBFUIO_CONTEXT_FROM_PROTOCOL (This);
> > +  FlagPtr = NULL;
> > +
> > +  switch (PolicyType) {
> > +    case EfiUsbPolicyUndefined:
> > +    case EfiUsbPolicyMaxTransactionSize:
> > +    case EfiUsbPolicyZeroLengthTerminationSupport:
> > +
> > +     Status = EFI_UNSUPPORTED;
> > +     break;
> > +
> > +    default:
> > +     FlagPtr = Buffer;
> > +     Status = EFI_SUCCESS;
> > +     break;
> > +  }
> > +
> > +  if (BufferSize < 1) {
> > +    Status = EFI_INVALID_PARAMETER;
> > +  }
> > +
> > +  if (EFI_ERROR(Status)) {
> > +    DEBUG ((USB_FUIO_DEBUG_LOAD, "SetEndpointPolicy - ERROR %r\n",
> Status));
> > +    return Status;
> > +  }
> > +
> > +  EndPoint = UsbGetPhysicalEpNum (EndpointIndex, Direction ?
> UsbEpDirIn : UsbEpDirOut);
> > +
> > +  UsbFuncIoDevPtr->EndPointXferRec[EndPoint].ZlpFlag = *FlagPtr;
> > +
> > +  return Status;
> > +}
> > +
> > +
> > +/**
> > +  This function retrieves the configuration policy for the specified non-
> control
> > +  endpoint. There are no associated calling restrictions for this function.
> > +
> > +  @param[in]  This              A pointer to the EFI_USBFN_IO_PROTOCOL
> instance.
> > +  @param[in]  EndpointIndex     Indicates the non-control endpoint for
> > +                                which the policy needs to be set.
> > +  @param[in]  Direction         Direction of the endpoint.
> > +  @param[in]  PolicyType        Policy type the user is trying to set for
> > +                                the specified non-control endpoint.
> > +  @param[in]  BufferSize        The size of the Buffer in bytes.
> > +  @param[in]  Buffer            The new value for the policy parameter that
> > +                                PolicyType specifies.
> > +
> > +
> > +  @retval EFI_SUCCESS           The function returned successfully.
> > +  @retval EFI_INVALID_PARAMETER A parameter is invalid.
> > +  @retval EFI_DEVICE_ERROR      The physical device reported an error.
> > +  @retval EFI_UNSUPPORTED       Changing this policy value is not
> supported.
> > +  @retval EFI_BUFFER_TOO_SMALL  Supplied Buffer is not large enough to
> > +                                hold requested policy value.
> > +
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +GetEndpointPolicy (
> > +  IN EFI_USBFN_IO_PROTOCOL        *This,
> > +  IN UINT8                        EndpointIndex,
> > +  IN EFI_USBFN_ENDPOINT_DIRECTION Direction,
> > +  IN EFI_USBFN_POLICY_TYPE        PolicyType,
> > +  IN OUT UINTN                    *BufferSize,
> > +  IN OUT VOID                     *Buffer
> > +  )
> > +{
> > +  USB_XDCI_DEV_CONTEXT  *UsbFuncIoDevPtr;
> > +  EFI_STATUS            Status;
> > +  UINT32                EndPoint;
> > +  UINT32                MaxPacketSize;
> > +  BOOLEAN               SetFlag;
> > +
> > +  UsbFuncIoDevPtr = USBFUIO_CONTEXT_FROM_PROTOCOL (This);
> > +  MaxPacketSize = 0;
> > +  SetFlag = FALSE;
> > +
> > +  switch (PolicyType) {
> > +    case EfiUsbPolicyUndefined:
> > +
> > +     Status = EFI_UNSUPPORTED;
> > +     break;
> > +
> > +    case EfiUsbPolicyMaxTransactionSize:
> > +    case EfiUsbPolicyZeroLengthTerminationSupport:
> > +    default:
> > +     if (Buffer == NULL) {
> > +       Status = EFI_INVALID_PARAMETER;
> > +     } else {
> > +       Status = EFI_SUCCESS;
> > +     }
> > +     break;
> > +  }
> > +
> > +  EndPoint = UsbGetPhysicalEpNum (EndpointIndex, Direction ?
> UsbEpDirIn : UsbEpDirOut);
> > +
> > +  if (EFI_ERROR(Status)) {
> > +    DEBUG ((USB_FUIO_DEBUG_LOAD, "GetEndpointPolicy - ERROR %r\n",
> Status));
> > +    return Status;
> > +  }
> > +
> > +  if (PolicyType == EfiUsbPolicyMaxTransactionSize) {
> > +
> > +    if (*BufferSize < sizeof(UINT32)) {
> > +       Status = EFI_INVALID_PARAMETER;
> > +    } else {
> > +      MaxPacketSize = MAX_TRANSFER_PACKET;
> > +      CopyMem (Buffer, &MaxPacketSize, sizeof(UINT32));
> > +    }
> > +
> > +  } else if (PolicyType == EfiUsbPolicyZeroLengthTerminationSupport) {
> > +    if (*BufferSize < sizeof(BOOLEAN)) {
> > +       Status = EFI_INVALID_PARAMETER;
> > +    } else {
> > +      SetFlag = TRUE;
> > +      CopyMem (Buffer, &SetFlag, sizeof(BOOLEAN));
> > +    }
> > +
> > +  } else if (PolicyType == EfiUsbPolicyZeroLengthTermination) {
> > +    if (*BufferSize < sizeof(BOOLEAN)) {
> > +       Status = EFI_INVALID_PARAMETER;
> > +    } else {
> > +      SetFlag =  UsbFuncIoDevPtr->EndPointXferRec[EndPoint].ZlpFlag;
> > +      CopyMem (Buffer, &SetFlag, sizeof(BOOLEAN));
> > +    }
> > +  } else {
> > +    Status = EFI_INVALID_PARAMETER;
> > +  }
> > +
> > +  return Status;
> > +}
> > +
> > +EFI_STATUS
> > +UsbFnInitDevice (
> > +  IN EFI_USBFN_IO_PROTOCOL        *This
> > +  )
> > +{
> > +  EFI_STATUS                   Status;
> > +  USB_XDCI_DEV_CONTEXT         *UsbFuncIoDevPtr;
> > +
> > +  Status = EFI_SUCCESS;
> > +  UsbFuncIoDevPtr = USBFUIO_CONTEXT_FROM_PROTOCOL (This);
> > +
> > +  PlatformSpecificInit ();
> > +
> > +  UsbFuncIoDevPtr->StartUpController = FALSE;
> > +  Status = StartXdciController (&UsbFuncIoDevPtr->UsbFunIoProtocol);
> > +  if (EFI_ERROR (Status)) {
> > +    Status = EFI_DEVICE_ERROR;
> > +    goto DEV_INIT_EXIT;
> > +  }
> > +
> > +  Status = UsbXdciDeviceConnect (UsbFuncIoDevPtr->DrvCore);
> > +  DEBUG ((USB_FUIO_DEBUG_LOAD, "UsbXdciDeviceConnect Status
> %x\n", Status));
> > +  if (Status != EFI_SUCCESS) {
> > +    Status = EFI_DEVICE_ERROR;
> > +    goto DEV_INIT_EXIT;
> > +  }
> > +
> > +
> > +DEV_INIT_EXIT:
> > +
> > +  return Status;
> > +}
> > +
> > +EFI_STATUS
> > +EFIAPI
> > +StartController (
> > +  IN EFI_USBFN_IO_PROTOCOL        *This
> > +  )
> > +{
> > +  return EFI_SUCCESS;
> > +}
> > +
> > +
> > +EFI_STATUS
> > +UsbFnDeInitDevice (
> > +  IN EFI_USBFN_IO_PROTOCOL        *This
> > +  )
> > +{
> > +  EFI_STATUS                   Status;
> > +  USB_XDCI_DEV_CONTEXT         *UsbFuncIoDevPtr;
> > +
> > +  UsbFuncIoDevPtr = USBFUIO_CONTEXT_FROM_PROTOCOL (This);
> > +
> > +  if (UsbFuncIoDevPtr->StartUpController == FALSE) {
> > +    DEBUG ((USB_FUIO_DEBUG_LOAD, "UsbFn:StopController:The
> Controller not yet start up force return EFI_SUCCESS\n"));
> > +    return EFI_SUCCESS;
> > +  }
> > +
> > +  //
> > +  // disconnect
> > +  //
> > +  Status = UsbDeviceDisconnect (UsbFuncIoDevPtr->DrvCore);
> > +  DEBUG ((USB_FUIO_DEBUG_LOAD, "UsbDeviceDisconnect Status %x\n",
> Status));
> > +  if (Status != EFI_SUCCESS) {
> > +    Status = EFI_DEVICE_ERROR;
> > +    goto DEV_DEINIT_EXIT;
> > +  }
> > +
> > +  //
> > +  // StopController
> > +  //
> > +  Status = StopXdciController (&UsbFuncIoDevPtr->UsbFunIoProtocol);
> > +  UsbFuncIoDevPtr->StartUpController = FALSE;
> > +
> > +DEV_DEINIT_EXIT:
> > +  return Status;
> > +}
> > +
> > +EFI_STATUS
> > +EFIAPI
> > +StopController (
> > +  IN EFI_USBFN_IO_PROTOCOL        *This
> > +  )
> > +{
> > +  return UsbFnDeInitDevice(This);
> > +}
> > +
> > diff --git
> a/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbFuncIo.h
> b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbFuncIo.h
> > new file mode 100644
> > index 0000000000..ad3d296db9
> > --- /dev/null
> > +++ b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbFuncIo.h
> > @@ -0,0 +1,234 @@
> > +/** @file
> > +  Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR>
> > +
> > +  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.
> > +
> > +**/
> > +
> > +#ifndef __EFI_USB_FUNCTION_IO_INTERFACE_H__
> > +#define __EFI_USB_FUNCTION_IO_INTERFACE_H__
> > +
> > +#include <Uefi.h>
> > +#include <Library/BaseMemoryLib.h>
> > +#include <Library/DevicePathLib.h>
> > +#include <Library/DriverLib.h>
> > +#include <Library/PcdLib.h>
> > +#include <Protocol/EfiUsbFnIo.h>
> > +#include <Library/PmicLib.h>
> > +#include <Library/UsbDeviceLib.h>
> > +#include <Library/PrintLib.h>
> > +#include "UsbIoNode.h"
> > +#include "XdciDWC.h"
> > +#include "UsbDeviceMode.h"
> > +
> > +//
> > +// Debug message setting
> > +//
> > +#define USB_FUIO_DEBUG_INFO              EFI_D_INFO
> > +#define USB_FUIO_DEBUG_LOAD              EFI_D_LOAD
> > +#define USB_FUIO_DEBUG_ERROR             EFI_D_ERROR
> > +#define USB_FUIO_DEBUG_EVENT_I           0 //DEBUG_INIT
> > +#define USB_FUIO_DEBUG_EVENT_D           EFI_D_ERROR
> > +#define USB_FUIO_DEBUG_EVENT_NOTREADY_D  EFI_D_ERROR
> > +#define USB_FUIO_DEBUG_EVENT_NOTREADY_I  0 //DEBUG_INIT
> > +
> > +#define MAX_TRANSFER_PACKET     (8 * 1024 * 1024)
> > +
> > +#define USBFU_VID     0x8086
> > +#define USBFU_PID     0x0A65
> > +
> > +#pragma pack(1)
> > +typedef struct {
> > +  UINT8                     ProgInterface;
> > +  UINT8                     SubClassCode;
> > +  UINT8                     BaseCode;
> > +} USB_CLASSC;
> > +
> > +//
> > +// Event Buffer Struct
> > +//
> > +typedef struct  {
> > +  UINT32 Event;
> > +  UINT32 DevTstLmp1;
> > +  UINT32 DevTstLmp2;
> > +  UINT32 Reserved;
> > +} USBD_EVENT_BUF;
> > +
> > +typedef struct  {
> > +  UINT32                        EpNum;
> > +  EFI_USBFN_ENDPOINT_DIRECTION  Direction;
> > +  UINTN                         XferAddress;
> > +  UINT32                        XferLength;
> > +  UINT8                         LogEpNum;
> > +  BOOLEAN                       Complete;
> > +  BOOLEAN                       ZlpFlag;
> > +} USBD_EP_XFER_REC;
> > +
> > +#pragma pack()
> > +
> > +EFI_STATUS
> > +UsbFnInitDevice (
> > +  IN EFI_USBFN_IO_PROTOCOL        *This
> > +  );
> > +
> > +EFI_STATUS
> > +UsbFnDeInitDevice (
> > +  IN EFI_USBFN_IO_PROTOCOL        *This
> > +  );
> > +
> > +EFI_STATUS
> > +EFIAPI
> > +DetectPort (
> > +  IN EFI_USBFN_IO_PROTOCOL         *This,
> > +  OUT EFI_USBFN_PORT_TYPE          *PortType
> > +  );
> > +
> > +EFI_STATUS
> > +EFIAPI
> > +AllocateTransferBuffer (
> > +  IN EFI_USBFN_IO_PROTOCOL         *This,
> > +  IN UINTN                         Size,
> > +  OUT VOID                         **Buffer
> > +  );
> > +
> > +EFI_STATUS
> > +EFIAPI
> > +FreeTransferBuffer (
> > +  IN EFI_USBFN_IO_PROTOCOL         *This,
> > +  IN VOID                          *Buffer
> > +  );
> > +
> > +EFI_STATUS
> > +EFIAPI
> > +ConfigureEnableEndpoints (
> > +  IN EFI_USBFN_IO_PROTOCOL         *This,
> > +  IN EFI_USB_DEVICE_INFO           *DeviceInfo
> > + );
> > +
> > +EFI_STATUS
> > +EFIAPI
> > +GetEndpointMaxPacketSize (
> > +  IN EFI_USBFN_IO_PROTOCOL         *This,
> > +  IN EFI_USB_ENDPOINT_TYPE         EndpointType,
> > +  IN EFI_USB_BUS_SPEED             BusSpeed,
> > +  OUT UINT16                       *MaxPacketSize
> > + );
> > +
> > +EFI_STATUS
> > +EFIAPI
> > +GetMaxTransferSize (
> > +  IN EFI_USBFN_IO_PROTOCOL         *This,
> > +  OUT UINTN                        *MaxTransferSize
> > +  );
> > +
> > +EFI_STATUS
> > +EFIAPI
> > +GetDeviceInfo (
> > +  IN EFI_USBFN_IO_PROTOCOL         *This,
> > +  IN EFI_USBFN_DEVICE_INFO_ID      Id,
> > +  IN OUT UINTN                     *BufferSize,
> > +  OUT VOID                         *Buffer OPTIONAL
> > +  );
> > +
> > +EFI_STATUS
> > +EFIAPI
> > +GetVendorIdProductId (
> > +  IN EFI_USBFN_IO_PROTOCOL         *This,
> > +  OUT UINT16                       *Vid,
> > +  OUT UINT16                       *Pid
> > +  );
> > +
> > +EFI_STATUS
> > +EFIAPI
> > +AbortTransfer (
> > +  IN EFI_USBFN_IO_PROTOCOL        *This,
> > +  IN UINT8                        EndpointIndex,
> > +  IN EFI_USBFN_ENDPOINT_DIRECTION Direction
> > +  );
> > +
> > +EFI_STATUS
> > +EFIAPI
> > +GetEndpointStallState (
> > +  IN EFI_USBFN_IO_PROTOCOL         *This,
> > +  IN UINT8                         EndpointIndex,
> > +  IN EFI_USBFN_ENDPOINT_DIRECTION  Direction,
> > +  IN OUT BOOLEAN                   *State
> > +  );
> > +
> > +EFI_STATUS
> > +EFIAPI
> > +SetEndpointStallState (
> > +  IN EFI_USBFN_IO_PROTOCOL         *This,
> > +  IN UINT8                         EndpointIndex,
> > +  IN EFI_USBFN_ENDPOINT_DIRECTION  Direction,
> > +  IN BOOLEAN                       State
> > +  );
> > +
> > +EFI_STATUS
> > +EFIAPI
> > +EventHandler (
> > +  IN EFI_USBFN_IO_PROTOCOL         *This,
> > +  OUT EFI_USBFN_MESSAGE            *Message,
> > +  IN OUT UINTN                     *PayloadSize,
> > +  OUT EFI_USBFN_MESSAGE_PAYLOAD    *Payload
> > +  );
> > +
> > +EFI_STATUS
> > +EFIAPI
> > +Transfer (
> > +  IN EFI_USBFN_IO_PROTOCOL         *This,
> > +  IN UINT8                         EndpointIndex,
> > +  IN EFI_USBFN_ENDPOINT_DIRECTION  Direction,
> > +  IN OUT UINTN                     *BufferSize,
> > +  IN OUT VOID                      *Buffer
> > +  );
> > +
> > +EFI_STATUS
> > +EFIAPI
> > +StartController (
> > +  IN EFI_USBFN_IO_PROTOCOL         *This
> > +  );
> > +
> > +EFI_STATUS
> > +EFIAPI
> > +StopController (
> > +  IN EFI_USBFN_IO_PROTOCOL         *This
> > +  );
> > +
> > +EFI_STATUS
> > +EFIAPI
> > +SetEndpointPolicy (
> > +  IN EFI_USBFN_IO_PROTOCOL         *This,
> > +  IN UINT8                         EndpointIndex,
> > +  IN EFI_USBFN_ENDPOINT_DIRECTION  Direction,
> > +  IN EFI_USBFN_POLICY_TYPE         PolicyType,
> > +  IN UINTN                         BufferSize,
> > +  IN VOID                          *Buffer
> > +  );
> > +
> > +EFI_STATUS
> > +EFIAPI
> > +GetEndpointPolicy (
> > +  IN EFI_USBFN_IO_PROTOCOL         *This,
> > +  IN UINT8                         EndpointIndex,
> > +  IN EFI_USBFN_ENDPOINT_DIRECTION  Direction,
> > +  IN EFI_USBFN_POLICY_TYPE         PolicyType,
> > +  IN OUT UINTN                     *BufferSize,
> > +  IN OUT VOID                      *Buffer
> > +  );
> > +
> > +VOID
> > +UsbFnSetEpInfo (
> > +  IN USB_EP_INFO                 *EpDest,
> > +  IN USB_DEVICE_ENDPOINT_INFO    *EpSrc
> > +  );
> > +
> > +extern EFI_USBFN_IO_PROTOCOL         mUsbFunIoProtocol;
> > +#endif
> > +
> > diff --git
> a/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbIoNode.c
> b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbIoNode.c
> > new file mode 100644
> > index 0000000000..8fc6e10046
> > --- /dev/null
> > +++ b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbIoNode.c
> > @@ -0,0 +1,177 @@
> > +/** @file
> > +  Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR>
> > +
> > +  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.
> > +
> > +**/
> > +
> > +#include "UsbDeviceDxe.h"
> > +
> > +
> > +/**
> > +  The SearchNode function search a memory address for record the driver
> allocate
> > +  memory region and the node to the head link list.
> > +
> > +  @param[in]  This              A pointer to the EFI_USBFN_IO_PROTOCOL
> instance.
> > +  @param[in]  Buffer            The driver alocate memory address.
> > +  @param[out] Node              The match node record of the driver aloocate
> > +                                memory region.
> > +  @param[out] PNode             The pervious match node record of the
> driver
> > +                                aloocate memory region.
> > +
> > +  @retval EFI_SUCCESS           The operation completed successfully.
> > +  @retval EFI_NOT_FOUND         The memory Buffer didn't find.
> > +**/
> > +EFI_STATUS
> > +SearchNode (
> > +  IN  EFI_USBFN_IO_PROTOCOL    *This,
> > +  IN  VOID                     *Buffer,
> > +  OUT USB_MEM_NODE             **Node,
> > +  OUT USB_MEM_NODE             **PNode
> > +  )
> > +{
> > +  USB_XDCI_DEV_CONTEXT *UsbFuncIoDevPtr;
> > +  USB_MEM_NODE         *NodeL;
> > +  USB_MEM_NODE         *PNodeL;
> > +  EFI_STATUS           Status;
> > +
> > +  DEBUG ((USB_DEBUG_MEM_NODE_INFO, "SearchNode - Entry\n"));
> > +
> > +  UsbFuncIoDevPtr = USBFUIO_CONTEXT_FROM_PROTOCOL(This);
> > +  NodeL = UsbFuncIoDevPtr->FirstNodePtr;
> > +  PNodeL = NULL;
> > +  Status = EFI_NOT_FOUND;
> > +
> > +  while (Node != NULL) {
> > +    if (NodeL->AllocatePtr == Buffer) {
> > +      break;
> > +    }
> > +
> > +    PNodeL = NodeL;
> > +    NodeL = NodeL->NextPtr;
> > +  }
> > +
> > +  if (NodeL != NULL && Node != NULL) {
> > +    *Node = NodeL;
> > +    *PNode = PNodeL;
> > +    Status = EFI_SUCCESS;
> > +  }
> > +
> > +  DEBUG ((USB_DEBUG_MEM_NODE_INFO, "SearchNode - Exit %r\n",
> Status));
> > +  return Status;
> > +}
> > +
> > +/**
> > +  The InsertNewNodeToHead function remove a memory for record the
> driver allocate
> > +  memory region and the node to the head link list.
> > +
> > +  @param[in]  This              A pointer to the EFI_USBFN_IO_PROTOCOL
> instance.
> > +  @param[in]  Buffer            The driver alocate memory address.
> > +
> > +  @retval EFI_SUCCESS           The operation completed successfully.
> > +  @retval EFI_NOT_FOUND         The memory Buffer didn't find.
> > +**/
> > +EFI_STATUS
> > +RemoveNode (
> > +  IN  EFI_USBFN_IO_PROTOCOL    *This,
> > +  IN  VOID                     *Buffer
> > +  )
> > +{
> > +  USB_XDCI_DEV_CONTEXT *UsbFuncIoDevPtr;
> > +  USB_MEM_NODE         *Node;
> > +  USB_MEM_NODE         *PNode;
> > +  EFI_STATUS           Status;
> > +
> > +  DEBUG ((USB_DEBUG_MEM_NODE_INFO, "RemoveNode - Entry\n"));
> > +
> > +  UsbFuncIoDevPtr = USBFUIO_CONTEXT_FROM_PROTOCOL (This);
> > +
> > +  Status = SearchNode (This, Buffer, &Node, &PNode);
> > +
> > +  if (EFI_ERROR(Status) || PNode == NULL) {
> > +    DEBUG ((USB_DEBUG_MEM_NODE_ERROR, "RemoveNode - Node Not
> Found\n"));
> > +    return EFI_NOT_FOUND;
> > +  }
> > +
> > +  if (Node != UsbFuncIoDevPtr->FirstNodePtr) {
> > +    PNode->NextPtr = Node->NextPtr;
> > +  } else {
> > +    UsbFuncIoDevPtr->FirstNodePtr = Node->NextPtr;
> > +  }
> > +
> > +  FreePool (Node->AllocatePtr);
> > +  FreePool (Node);
> > +  DEBUG ((USB_DEBUG_MEM_NODE_INFO, "RemoveNode - Exit\n"));
> > +  return EFI_SUCCESS;
> > +}
> > +
> > +/**
> > +  The InsertNewNodeToHead function allocates a memory for record the
> driver allocate
> > +  memory region and insert the node to the head link list.
> > +
> > +  @param[in]  This              A pointer to the EFI_USBFN_IO_PROTOCOL
> instance.
> > +  @param[out] USB_MEM_NODE      return the new node address.
> > +
> > +  @retval EFI_SUCCESS           The operation completed successfully.
> > +  @retval EFI_INVALID_PARAMETER A parameter is invalid.
> > +  @retval EFI_OUT_OF_RESOURCES  The requested transfer Buffer could
> not be allocated.
> > +
> > +**/
> > +EFI_STATUS
> > +InsertNewNodeToHead (
> > +  IN  EFI_USBFN_IO_PROTOCOL    *This,
> > +  OUT USB_MEM_NODE             **Node
> > +  )
> > +{
> > +  USB_MEM_NODE         *NewNodePtr;
> > +  USB_MEM_NODE         *CurrentNodePtr;
> > +  USB_XDCI_DEV_CONTEXT *UsbFuncIoDevPtr;
> > +  EFI_STATUS           Status;
> > +
> > +  DEBUG ((USB_DEBUG_MEM_NODE_INFO, "CreateNewNode - Entry\n"));
> > +
> > +  if (This == NULL) {
> > +    Status = EFI_INVALID_PARAMETER;
> > +    goto ErrorExit;
> > +  }
> > +
> > +  UsbFuncIoDevPtr = USBFUIO_CONTEXT_FROM_PROTOCOL(This);
> > +
> > +  //
> > +  // Create the new node
> > +  //
> > +  NewNodePtr = AllocateZeroPool (sizeof(USB_MEM_NODE));
> > +  DEBUG ((USB_DEBUG_MEM_NODE_INFO, "NewNodePtr - Addr =
> 0x%08x\n",(UINTN)NewNodePtr));
> > +
> > +  if (NewNodePtr == NULL) {
> > +    Status = EFI_OUT_OF_RESOURCES;
> > +    goto ErrorExit;
> > +  }
> > +
> > +  //
> > +  // insert the new node
> > +  //
> > +  CurrentNodePtr = UsbFuncIoDevPtr->FirstNodePtr;
> > +  UsbFuncIoDevPtr->FirstNodePtr = NewNodePtr;
> > +
> > +  if (CurrentNodePtr != NULL) {
> > +    NewNodePtr->NextPtr = CurrentNodePtr;
> > +  }
> > +
> > +  *Node = NewNodePtr;
> > +
> > +  DEBUG ((USB_DEBUG_MEM_NODE_INFO, "CreateNewNode - Exit\n"));
> > +  return EFI_SUCCESS;
> > +
> > +ErrorExit:
> > +
> > +  DEBUG ((USB_DEBUG_MEM_NODE_ERROR, "CreateNewNode - error
> %r\n",Status));
> > +  return Status;
> > +}
> > +
> > diff --git
> a/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbIoNode.h
> b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbIoNode.h
> > new file mode 100644
> > index 0000000000..ecedb2748b
> > --- /dev/null
> > +++ b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbIoNode.h
> > @@ -0,0 +1,90 @@
> > +/** @file
> > +  Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR>
> > +
> > +  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.
> > +
> > +**/
> > +
> > +#ifndef __EFI_USB_FUIO_MEM_NODE__
> > +#define __EFI_USB_FUIO_MEM_NODE__
> > +
> > +#include <Uefi.h>
> > +#include <Library/BaseMemoryLib.h>
> > +#include <Library/DevicePathLib.h>
> > +#include <Library/DriverLib.h>
> > +
> > +#define  USB_DEBUG_MEM_NODE_INFO  EFI_D_INIT
> > +#define  USB_DEBUG_MEM_NODE_ERROR EFI_D_ERROR
> > +
> > +
> > +typedef struct {
> > +  UINTN                         Size;
> > +  VOID                          *AllocatePtr;
> > +  VOID                          *NextPtr;
> > +} USB_MEM_NODE;
> > +
> > +/**
> > +  The SearchNode function search a memory address for record the driver
> allocate
> > +  memory region and the node to the head link list.
> > +
> > +  @param[in]  This              A pointer to the EFI_USBFN_IO_PROTOCOL
> instance.
> > +  @param[in]  Buffer            The driver alocate memory address.
> > +  @param[out] Node              The match node record of the driver aloocate
> > +                                memory region.
> > +  @param[out] PNode             The pervious match node record of the
> driver
> > +                                aloocate memory region.
> > +
> > +  @retval EFI_SUCCESS           The operation completed successfully.
> > +  @retval EFI_NOT_FOUND         The memory Buffer didn't find.
> > +**/
> > +EFI_STATUS
> > +SearchNode (
> > +  IN  EFI_USBFN_IO_PROTOCOL    *This,
> > +  IN  VOID                     *Buffer,
> > +  OUT USB_MEM_NODE             **Node,
> > +  OUT USB_MEM_NODE             **PNode
> > +  );
> > +
> > +/**
> > +  The InsertNewNodeToHead function remove a memory for record the
> driver allocate
> > +  memory region and the node to the head link list.
> > +
> > +  @param[in]  This              A pointer to the EFI_USBFN_IO_PROTOCOL
> instance.
> > +  @param[in]  Buffer            The driver alocate memory address.
> > +
> > +  @retval EFI_SUCCESS           The operation completed successfully.
> > +  @retval EFI_NOT_FOUND         The memory Buffer didn't find.
> > +**/
> > +EFI_STATUS
> > +RemoveNode (
> > +  IN  EFI_USBFN_IO_PROTOCOL    *This,
> > +  IN  VOID                     *Buffer
> > +  );
> > +
> > +/**
> > +  The InsertNewNodeToHead function allocates a memory for record the
> driver allocate
> > +  memory region and insert the node to the head link list.
> > +
> > +  @param[in]  This              A pointer to the EFI_USBFN_IO_PROTOCOL
> instance.
> > +  @param[out] USB_MEM_NODE      return the new node address.
> > +
> > +  @retval EFI_SUCCESS           The operation completed successfully.
> > +  @retval EFI_INVALID_PARAMETER A parameter is invalid.
> > +  @retval EFI_OUT_OF_RESOURCES  The requested transfer Buffer could
> not be allocated.
> > +
> > +**/
> > +EFI_STATUS
> > +InsertNewNodeToHead (
> > +  IN  EFI_USBFN_IO_PROTOCOL    *This,
> > +  OUT USB_MEM_NODE             **Node
> > +  );
> > +
> > +  #endif
> > +
> > +
> > diff --git
> a/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciCommon.h
> b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciCommon.h
> > new file mode 100644
> > index 0000000000..6a53068681
> > --- /dev/null
> > +++
> b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciCommon.h
> > @@ -0,0 +1,156 @@
> > +/** @file
> > +  Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR>
> > +
> > +  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.
> > +
> > +**/
> > +
> > +#ifndef _XDCI_COMMON_H_
> > +#define _XDCI_COMMON_H_
> > +
> > +#define USB_SETUP_DATA_PHASE_DIRECTION_MASK  (0x80)
> > +
> > +//
> > +// EP direction
> > +//
> > +typedef enum {
> > +  UsbEpDirOut = 0,
> > +  UsbEpDirIn  = 1
> > +} USB_EP_DIR;
> > +
> > +//
> > +// USB Speeds
> > +//
> > +typedef enum {
> > +  USB_SPEED_HIGH  = 0,
> > +  USB_SPEED_FULL,
> > +  USB_SPEED_LOW,
> > +  USB_SPEED_SUPER = 4
> > +} USB_SPEED;
> > +
> > +typedef enum {
> > +  USB_ID_DWC_XDCI = 0,
> > +  USB_CORE_ID_MAX
> > +} USB_CONTROLLER_ID;
> > +
> > +typedef enum {
> > +  USB_ROLE_HOST = 1,
> > +  USB_ROLE_DEVICE,
> > +  USB_ROLE_OTG
> > +} USB_ROLE;
> > +
> > +typedef enum {
> > +  USB_XFER_QUEUED    = 0,
> > +  USB_XFER_SUCCESSFUL,
> > +  USB_XFER_STALL
> > +} USB_XFER_STATUS;
> > +
> > +typedef enum {
> > +  USB_DEVICE_DISCONNECT_EVENT       = 0,
> > +  USB_DEVICE_RESET_EVENT,
> > +  USB_DEVICE_CONNECTION_DONE,
> > +  USB_DEVICE_STATE_CHANGE_EVENT,
> > +  USB_DEVICE_WAKEUP_EVENT,
> > +  USB_DEVICE_HIBERNATION_REQ_EVENT,
> > +  USB_DEVICE_SOF_EVENT              = 7,
> > +  USB_DEVICE_ERRATIC_ERR_EVENT      = 9,
> > +  USB_DEVICE_CMD_CMPLT_EVENT,
> > +  USB_DEVICE_BUFF_OVERFLOW_EVENT,
> > +  USB_DEVICE_TEST_LMP_RX_EVENT,
> > +  USB_DEVICE_SETUP_PKT_RECEIVED,
> > +  USB_DEVICE_XFER_NRDY,
> > +  USB_DEVICE_XFER_DONE
> > +} USB_DEVICE_EVENT_ID;
> > +
> > +typedef enum {
> > +  U0 = 0,
> > +  U1,
> > +  U2,
> > +  U3,
> > +  SS_DIS,
> > +  RX_DET,
> > +  SS_INACT,
> > +  POLL,
> > +  RECOV,
> > +  HRESET,
> > +  CMPLY,
> > +  LPBK,
> > +  RESUME_RESET = 15
> > +} USB_DEVICE_SS_LINK_STATE;
> > +
> > +typedef enum {
> > +  CTRL_SETUP_PHASE,
> > +  CTRL_DATA_PHASE,
> > +  CTRL_STATUS_PHASE
> > +} USB_CONTROL_XFER_PHASE;
> > +
> > +typedef enum  {
> > +  USB_EP_STATE_DISABLED = 0,
> > +  USB_EP_STATE_ENABLED,
> > +  USB_EP_STATE_STALLED,
> > +  USB_EP_STATE_SETUP,
> > +  USB_EP_STATE_IN_DATA,
> > +  USB_EP_STATE_OUT_DATA,
> > +  USB_EP_STATE_DATA,
> > +  USB_EP_STATE_STATUS
> > +} USB_EP_STATE;
> > +
> > +typedef struct  {
> > +  VOID                      *ParentHandle;
> > +  UINT32                    Hird;
> > +  UINT32                    EpNum;
> > +  USB_SPEED                 Speed;
> > +  USB_EP_STATE              EpState;
> > +  USB_EP_DIR                EpDir;
> > +  UINT8                     EpType;
> > +  USB_DEVICE_SS_LINK_STATE  LinkState;
> > +  UINT8                     *Buffer;
> > +  BOOLEAN                   SsEvent;
> > +} USB_DEVICE_CALLBACK_PARAM;
> > +
> > +//
> > +// USB endpoint
> > +//
> > +typedef struct {
> > +  UINT32       EpNum;
> > +  USB_EP_DIR   EpDir;
> > +  UINT8        EpType;
> > +  UINT32       MaxPktSize;
> > +  UINT32       MaxStreams;
> > +  UINT32       BurstSize;
> > +  UINT32       Interval;
> > +  UINT32       Mult;
> > +} USB_EP_INFO;
> > +
> > +//
> > +// USB transfer request
> > +//
> > +typedef struct _USB_XFER_REQUEST USB_XFER_REQUEST;
> > +
> > +typedef
> > +VOID
> > +(EFIAPI *USB_XFER_DONE_CALLBACK) (
> > +  IN VOID                    *XdciHndl,
> > +  IN USB_XFER_REQUEST        *XferReq
> > +  );
> > +
> > +struct _USB_XFER_REQUEST {
> > +  VOID                      *XferBuffer;     // Buffer address. bus-width aligned
> > +  UINT32                    XferLen;         // Requested transfer length
> > +  UINT32                    ActualXferLen;  // Actual transfer length at completion
> callback stage
> > +  UINT32                    StreamId;        // Stream ID. Only relevant for bulk
> streaming
> > +  UINT32                    FrameNum;        // Only relevant for periodic transfer
> > +  USB_XFER_STATUS           XferStatus;      // Transfer status
> > +  USB_EP_INFO               EpInfo;          // EP info
> > +  USB_XFER_DONE_CALLBACK    XferDone;        // Transfer completion
> callback
> > +  BOOLEAN                   Zlp;              // Do zero-length transfer
> > +};
> > +
> > +#endif
> > +
> > diff --git a/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciDWC.c
> b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciDWC.c
> > new file mode 100644
> > index 0000000000..3569ba6975
> > --- /dev/null
> > +++ b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciDWC.c
> > @@ -0,0 +1,4030 @@
> > +/** @file
> > +  Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR>
> > +
> > +  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.
> > +
> > +**/
> > +
> > +#include "UsbDeviceMode.h"
> > +#include "XdciInterface.h"
> > +#include "XdciDWC.h"
> > +
> > +
> > +UINT32
> > +UsbRegRead (
> > +  IN UINT32    Base,
> > +  IN UINT32    Offset
> > +  )
> > +{
> > +  volatile UINT32 *addr = (volatile UINT32 *)((UINTN)(Base) +
> (UINTN)(Offset));
> > +  return *addr;
> > +}
> > +
> > +VOID
> > +UsbRegWrite (
> > +  IN UINT32    Base,
> > +  IN UINT32    Offset,
> > +  IN UINT32    val
> > +  )
> > +{
> > +  volatile UINT32 *addr = (volatile UINT32 *)((UINTN)(Base) +
> (UINTN)(Offset));
> > +  *addr = val;
> > +}
> > +
> > +
> > +/**
> > +  Internal utility function:
> > +  This function is used to obtain physical endpoint number
> > +  xDCI needs physical endpoint number for EP registers
> > +  We also use it to index into our EP array
> > +  Note: Certain data structures/commands use logical EP numbers
> > +  as opposed to physical endpoint numbers so one should be
> > +  careful when interpreting EP numbers
> > +  @EpNum: Logical endpoint number
> > +  @epDir: Direction for the endpoint
> > +
> > +**/
> > +STATIC
> > +UINT32
> > +DwcXdciGetPhysicalEpNum (
> > +  IN UINT32        EndpointNum,
> > +  IN USB_EP_DIR    EndpointDir
> > +  )
> > +{
> > +  return EndpointDir? ((EndpointNum << 1) | EndpointDir) : (EndpointNum
> << 1);
> > +}
> > +
> > +
> > +/**
> > +  Internal utility function:
> > +  This function is used to obtain the MPS for control transfers
> > +  Based on the Speed. If this is called before bus reset completes
> > +  then it returns MPS Based on desired Speed. If it is after bus
> > +  reset then MPS returned is Based on actual negotiated Speed
> > +  @CoreHandle: xDCI controller handle address
> > +  @mps: address of 32-bit variable to return the MPS
> > +
> > +**/
> > +STATIC
> > +EFI_STATUS
> > +DwcXdciCoreGetCtrlMps (
> > +  IN XDCI_CORE_HANDLE    *CoreHandle,
> > +  IN UINT32              *mps
> > +  )
> > +{
> > +  if (CoreHandle == NULL) {
> > +      DEBUG ((DEBUG_INFO, "ERROR: DwcXdciCoreGetCtrlMps: INVALID
> handle\n"));
> > +      return EFI_DEVICE_ERROR;
> > +  }
> > +
> > +  if (mps == NULL) {
> > +    DEBUG ((DEBUG_INFO, "ERROR: DwcXdciCoreGetCtrlMps: INVALID
> parameter\n"));
> > +    return EFI_INVALID_PARAMETER;
> > +  }
> > +
> > +  switch (CoreHandle->ActualSpeed) {
> > +    case USB_SPEED_HIGH:
> > +      *mps = DWC_XDCI_HS_CTRL_EP_MPS;
> > +      break;
> > +    case USB_SPEED_FULL:
> > +      *mps = DWC_XDCI_FS_CTRL_EP_MPS;
> > +      break;
> > +    case USB_SPEED_LOW:
> > +      *mps = DWC_XDCI_LS_CTRL_EP_MPS;
> > +      break;
> > +    case USB_SPEED_SUPER:
> > +      *mps = DWC_XDCI_SS_CTRL_EP_MPS;
> > +      break;
> > +    default:
> > +      *mps = 0;
> > +      DEBUG ((DEBUG_INFO, "ERROR: DwcXdciCoreGetCtrlMps: UNKNOWN
> Speed\n"));
> > +      break;
> > +  }
> > +
> > +  return EFI_SUCCESS;
> > +}
> > +
> > +
> > +/**
> > +  Internal utility function:
> > +  This function is used to initialize the parameters required
> > +  for executing endpoint command
> > +  @CoreHandle: xDCI controller handle address
> > +  @EpInfo: EP info address
> > +  @ConfigAction: Configuration action specific to EP command
> > +  @EpCmd: xDCI EP command for which parameters are initialized
> > +  @EpCmdParams: address of struct to return EP params
> > +
> > +**/
> > +STATIC
> > +EFI_STATUS
> > +DwcXdciCoreInitEpCmdParams (
> > +  IN XDCI_CORE_HANDLE                *CoreHandle,
> > +  IN USB_EP_INFO                     *EpInfo,
> > +  IN UINT32                          ConfigAction,
> > +  IN DWC_XDCI_ENDPOINT_CMD           EpCmd,
> > +  IN DWC_XDCI_ENDPOINT_CMD_PARAMS    *EpCmdParams
> > +  )
> > +{
> > +  EFI_STATUS  status = EFI_SUCCESS;
> > +
> > +  if (CoreHandle == NULL) {
> > +    DEBUG ((DEBUG_INFO, "ERROR: DwcXdciCoreInitEpCmdParams:
> INVALID handle\n"));
> > +    return EFI_DEVICE_ERROR;
> > +  }
> > +
> > +  //
> > +  // Reset params
> > +  //
> > +  EpCmdParams->Param0 = EpCmdParams->Param1 = EpCmdParams-
> >Param2 = 0;
> > +
> > +  switch (EpCmd) {
> > +    case EPCMD_SET_EP_CONFIG:
> > +      //
> > +      // Issue DEPCFG command for EP
> > +      // Issue a DEPCFG (Command 1) command for endpoint
> > +      //
> > +      if (EpInfo->MaxStreams) {
> > +        EpCmdParams->Param1 =
> DWC_XDCI_PARAM1_SET_EP_CFG_STRM_CAP_MASK;
> > +      }
> > +
> > +      if (EpInfo->Interval) {
> > +        EpCmdParams->Param1 |= ((EpInfo->Interval-1) <<
> DWC_XDCI_PARAM1_SET_EP_CFG_BINTM1_BIT_POS);
> > +      }
> > +
> > +      //
> > +      // Set EP num
> > +      //
> > +      EpCmdParams->Param1 |= (EpInfo->EpNum <<
> DWC_XDCI_PARAM1_SET_EP_CFG_EP_NUM_BIT_POS);
> > +      //
> > +      // Set EP direction
> > +      //
> > +      EpCmdParams->Param1 |= (EpInfo->EpDir <<
> DWC_XDCI_PARAM1_SET_EP_CFG_EP_DIR_BIT_POS);
> > +      //
> > +      // Set EP-specific Event enable for not ready and
> > +      // complete events
> > +      //
> > +      EpCmdParams->Param1 &=
> ~DWC_XDCI_PARAM1_SET_EP_CFG_EVT_EN_MASK;
> > +      //
> > +      // Setup the events we want enabled for this EP
> > +      //
> > +      EpCmdParams->Param1 |=
> (DWC_XDCI_PARAM1_SET_EP_CFG_EVT_XFER_NRDY_MASK |
> > +
> DWC_XDCI_PARAM1_SET_EP_CFG_EVT_XFER_IN_PRG_MASK |
> > +
> DWC_XDCI_PARAM1_SET_EP_CFG_EVT_XFER_CMPLT_MASK);
> > +
> > +      //
> > +      // We only have one interrupt line for this core.
> > +      // Set interrupt number to 0
> > +      //
> > +      EpCmdParams->Param1 &=
> ~DWC_XDCI_PARAM1_SET_EP_CFG_INTR_NUM_MASK;
> > +
> > +      //
> > +      // Set FIFOnum = 0 for control EP0
> > +      //
> > +      EpCmdParams->Param0 &=
> ~DWC_XDCI_PARAM0_SET_EP_CFG_FIFO_NUM_MASK;
> > +
> > +      //
> > +      // Program FIFOnum for non-EP0 EPs
> > +      //
> > +      if (EpInfo->EpNum && EpInfo->EpDir) {
> > +        EpCmdParams->Param0 |= (EpInfo->EpNum <<
> DWC_XDCI_PARAM0_SET_EP_CFG_FIFO_NUM_BIT_POS);
> > +      }
> > +
> > +      //
> > +      // Program max packet size
> > +      //
> > +      EpCmdParams->Param0 &=
> ~DWC_XDCI_PARAM0_SET_EP_CFG_MPS_MASK;
> > +      EpCmdParams->Param0 |= (EpInfo->MaxPktSize <<
> DWC_XDCI_PARAM0_SET_EP_CFG_MPS_BIT_POS);
> > +
> > +      //
> > +      // Set Burst size. 0 means burst size of 1
> > +      //
> > +      EpCmdParams->Param0 &=
> ~DWC_XDCI_PARAM0_SET_EP_CFG_BRST_SIZE_MASK;
> > +      EpCmdParams->Param0 |= (EpInfo->BurstSize <<
> DWC_XDCI_PARAM0_SET_EP_CFG_BRST_SIZE_BIT_POS);
> > +
> > +      //
> > +      // Set EP type
> > +      //
> > +      EpCmdParams->Param0 &=
> ~DWC_XDCI_PARAM0_SET_EP_CFG_EP_TYPE_MASK;
> > +      EpCmdParams->Param0 |= (EpInfo->EpType <<
> DWC_XDCI_PARAM0_SET_EP_CFG_EP_TYPE_BIT_POS);
> > +
> > +      //
> > +      // Set config action
> > +      //
> > +      EpCmdParams->Param0 &=
> ~DWC_XDCI_PARAM0_SET_EP_CFG_ACTN_MASK;
> > +      EpCmdParams->Param0 |= (ConfigAction <<
> DWC_XDCI_PARAM0_SET_EP_CFG_ACTN_BIT_POS);
> > +      break;
> > +
> > +    case EPCMD_SET_EP_XFER_RES_CONFIG:
> > +      // Set Param0 to 1. Same for all EPs when resource
> > +      // configuration is done
> > +      //
> > +      EpCmdParams->Param0 = 1;
> > +      break;
> > +
> > +    case EPCMD_END_XFER:
> > +      //
> > +      // Nothing to set. Already reset params for all cmds
> > +      //
> > +      break;
> > +
> > +    case EPCMD_START_NEW_CONFIG:
> > +      //
> > +      // Nothing to set. Already reset params for all cmds
> > +      //
> > +      break;
> > +
> > +    default:
> > +      status = EFI_INVALID_PARAMETER;
> > +      DEBUG ((DEBUG_INFO, "\nDwcXdciCoreInitEpCmdParams: INVALID
> Parameter"));
> > +      break;
> > +  }
> > +
> > +  return status;
> > +}
> > +
> > +
> > +/**
> > +  Internal utility function:
> > +  This function is used to issue the xDCI endpoint command
> > +  @CoreHandle: xDCI controller handle address
> > +  @EpNum: Physical EP num
> > +  @EpCmd: xDCI EP command
> > +  @EpCmdParams: EP command parameters address
> > +
> > +**/
> > +STATIC
> > +EFI_STATUS
> > +DwcXdciCoreIssueEpCmd (
> > +  IN XDCI_CORE_HANDLE                *CoreHandle,
> > +  IN UINT32                          EpNum,
> > +  IN UINT32                          EpCmd,
> > +  IN DWC_XDCI_ENDPOINT_CMD_PARAMS    *EpCmdParams
> > +  )
> > +{
> > +  UINT32 BaseAddr;
> > +  UINT32 MaxDelayIter = 5000;//DWC_XDCI_MAX_DELAY_ITERATIONS;
> > +
> > +  if (CoreHandle == NULL) {
> > +    DEBUG ((DEBUG_INFO, "ERROR: DwcXdciCoreIssueEpCmd: INVALID
> handle\n"));
> > +    return EFI_DEVICE_ERROR;
> > +  }
> > +
> > +  BaseAddr = CoreHandle->BaseAddress;
> > +
> > +  //
> > +  // Set EP command parameter values
> > +  //
> > +  UsbRegWrite (
> > +    BaseAddr,
> > +    DWC_XDCI_EPCMD_PARAM2_REG(EpNum),
> > +    EpCmdParams->Param2
> > +    );
> > +
> > +  UsbRegWrite (
> > +    BaseAddr,
> > +    DWC_XDCI_EPCMD_PARAM1_REG(EpNum),
> > +    EpCmdParams->Param1
> > +    );
> > +
> > +  UsbRegWrite (
> > +    BaseAddr,
> > +    DWC_XDCI_EPCMD_PARAM0_REG(EpNum),
> > +    EpCmdParams->Param0
> > +    );
> > +
> > +  //
> > +  // Set the command code and activate it
> > +  //
> > +  UsbRegWrite (
> > +    BaseAddr,
> > +    DWC_XDCI_EPCMD_REG(EpNum),
> > +    EpCmd | DWC_XDCI_EPCMD_CMD_ACTIVE_MASK
> > +    );
> > +
> > +  //
> > +  // Wait until command completes
> > +  //
> > +  do {
> > +    if (!(UsbRegRead (BaseAddr, DWC_XDCI_EPCMD_REG(EpNum)) &
> DWC_XDCI_EPCMD_CMD_ACTIVE_MASK))
> > +      break;
> > +    else
> > +      gBS->Stall (DWC_XDCI_MAX_DELAY_ITERATIONS);
> > +  } while (--MaxDelayIter);
> > +
> > +  if (!MaxDelayIter) {
> > +    DEBUG ((DEBUG_INFO, "DwcXdciCoreIssueEpCmd. ERROR: Failed to
> issue Command\n"));
> > +    return EFI_DEVICE_ERROR;
> > +  }
> > +
> > +  return EFI_SUCCESS;
> > +}
> > +
> > +
> > +/**
> > +  Internal utility function:
> > +  This function is used to flush all FIFOs
> > +  @CoreHandle: xDCI controller handle address
> > +
> > +**/
> > +STATIC
> > +EFI_STATUS
> > +DwcXdciCoreFlushAllFifos (
> > +  IN XDCI_CORE_HANDLE    *CoreHandle
> > +  )
> > +{
> > +  UINT32 BaseAddr;
> > +  UINT32 MaxDelayIter = DWC_XDCI_MAX_DELAY_ITERATIONS;
> > +
> > +  if (CoreHandle == NULL) {
> > +    DEBUG ((DEBUG_INFO, "ERROR: DwcXdciCoreFlushAllFifos: INVALID
> handle\n"));
> > +    return EFI_DEVICE_ERROR;
> > +  }
> > +
> > +  BaseAddr = CoreHandle->BaseAddress;
> > +
> > +  //
> > +  // Write the command to flush all FIFOs
> > +  //
> > +  UsbRegWrite(
> > +    BaseAddr,
> > +    DWC_XDCI_DGCMD_REG,
> > +    (UsbRegRead (BaseAddr, DWC_XDCI_DGCMD_REG) |
> DWC_XDCI_DGCMD_CMD_ALL_FIFO_FLUSH |
> DWC_XDCI_DGCMD_CMD_ACTIVE_MASK)
> > +    );
> > +
> > +  //
> > +  // Wait until command completes
> > +  //
> > +  do {
> > +    if (!(UsbRegRead (BaseAddr, DWC_XDCI_DGCMD_REG) &
> DWC_XDCI_DGCMD_CMD_ACTIVE_MASK))
> > +      break;
> > +    else
> > +      gBS->Stall (DWC_XDCI_MAX_DELAY_ITERATIONS);
> > +  } while (--MaxDelayIter);
> > +
> > +  if (!MaxDelayIter) {
> > +    DEBUG ((DEBUG_INFO, "Failed to issue Command\n"));
> > +    return EFI_DEVICE_ERROR;
> > +  }
> > +
> > +  return EFI_SUCCESS;
> > +}
> > +
> > +
> > +/**
> > +  Internal utility function:
> > +  This function is used to flush Tx FIFO specific to an endpoint
> > +  @CoreHandle: xDCI controller handle address
> > +  @EpNum: Physical EP num
> > +
> > +**/
> > +STATIC
> > +EFI_STATUS
> > +DwcXdciCoreFlushEpTxFifo (
> > +  IN XDCI_CORE_HANDLE    *CoreHandle,
> > +  IN UINT32              EpNum
> > +  )
> > +{
> > +  UINT32 BaseAddr;
> > +  UINT32 MaxDelayIter = DWC_XDCI_MAX_DELAY_ITERATIONS;
> > +  UINT32 fifoNum;
> > +
> > +  if (CoreHandle == NULL) {
> > +    DEBUG ((DEBUG_INFO, "ERROR: DwcXdciCoreFlushEpTxFifo: INVALID
> handle\n"));
> > +    return EFI_DEVICE_ERROR;
> > +  }
> > +
> > +  BaseAddr = CoreHandle->BaseAddress;
> > +
> > +  //
> > +  // Translate to FIFOnum
> > +  // NOTE: Assuming this is a Tx EP
> > +  //
> > +  fifoNum = (EpNum >> 1);
> > +
> > +  //
> > +  // TODO: Currently we are only using TxFIFO 0. Later map these
> > +  // Write the FIFO num/dir param for the generic command.
> > +  //
> > +  UsbRegWrite (
> > +    BaseAddr,
> > +    DWC_XDCI_DGCMD_PARAM_REG,
> > +    ((UsbRegRead (BaseAddr, DWC_XDCI_DGCMD_PARAM_REG) &
> ~DWC_XDCI_DGCMD_PARAM_TX_FIFO_NUM_MASK) |
> DWC_XDCI_DGCMD_PARAM_TX_FIFO_DIR_MASK)
> > +    );
> > +
> > +  //
> > +  // Write the command to flush all FIFOs
> > +  //
> > +  UsbRegWrite (
> > +    BaseAddr,
> > +    DWC_XDCI_DGCMD_REG,
> > +    (UsbRegRead(BaseAddr, DWC_XDCI_DGCMD_REG) |
> DWC_XDCI_DGCMD_CMD_SEL_FIFO_FLUSH |
> DWC_XDCI_DGCMD_CMD_ACTIVE_MASK)
> > +    );
> > +
> > +
> > +  //
> > +  // Wait until command completes
> > +  //
> > +  do {
> > +    if (!(UsbRegRead(BaseAddr, DWC_XDCI_DGCMD_REG) &
> DWC_XDCI_DGCMD_CMD_ACTIVE_MASK))
> > +      break;
> > +    else
> > +      gBS->Stall (DWC_XDCI_MAX_DELAY_ITERATIONS);
> > +  } while (--MaxDelayIter);
> > +
> > +  if (!MaxDelayIter) {
> > +    DEBUG ((DEBUG_INFO, "Failed to issue Command\n"));
> > +    return EFI_DEVICE_ERROR;
> > +  }
> > +
> > +  return EFI_SUCCESS;
> > +}
> > +
> > +
> > +
> > +STATIC
> > +EFI_STATUS
> > +DwcXdciCorePrepareOneTrb (
> > +  IN DWC_XDCI_TRB            *Trb,
> > +  IN DWC_XDCI_TRB_CONTROL    TrbCtrl,
> > +  IN UINT32                  LastBit,
> > +  IN UINT32                  ChainBit,
> > +  IN UINT8                   *BufferPtr,
> > +  IN UINT32                  size
> > +  )
> > +{
> > +  DEBUG ((DEBUG_INFO, "Trb is 0x%x, BufferPtr is 0x%x, size is 0x%x\n",
> Trb, BufferPtr, size));
> > +
> > +  Trb->BuffPtrLow = (UINT32)(UINTN)BufferPtr;
> > +  Trb->BuffPtrHigh = 0;
> > +  Trb->LenXferParams = size;
> > +  Trb->TrbCtrl = TrbCtrl << DWC_XDCI_TRB_CTRL_TYPE_BIT_POS;
> > +
> > +  if (ChainBit)
> > +    Trb->TrbCtrl |= ChainBit <<
> DWC_XDCI_TRB_CTRL_CHAIN_BUFF_BIT_POS;
> > +
> > +  if (LastBit)
> > +    Trb->TrbCtrl |= LastBit << DWC_XDCI_TRB_CTRL_LST_TRB_BIT_POS;
> > +
> > +  Trb->TrbCtrl |= DWC_XDCI_TRB_CTRL_IOSP_MISOCH_MASK|
> DWC_XDCI_TRB_CTRL_HWO_MASK;
> > +
> > +  DEBUG ((DEBUG_INFO, "(DwcXdciCorePrepareOneTrb) Trb->BuffPtrLow
> = 0x%x, Trb->LenXferParams is 0x%x, Trb->TrbCtrl is 0x%x\n",
> > +                                                       Trb->BuffPtrLow, Trb->LenXferParams, Trb-
> >TrbCtrl));
> > +  return EFI_SUCCESS;
> > +}
> > +
> > +
> > +/**
> > +  Internal utility function:
> > +  This function is used to initialize transfer request block
> > +  @CoreHandle: xDCI controller handle address
> > +  @Trb: Address of TRB to initialize
> > +  @TrbCtrl: TRB control value
> > +  @buffPtr: Transfer Buffer address
> > +  @size: Size of the transfer
> > +
> > +**/
> > +STATIC
> > +EFI_STATUS
> > +DwcXdciCoreInitTrb (
> > +  IN XDCI_CORE_HANDLE        *CoreHandle,
> > +  IN DWC_XDCI_TRB            *Trb,
> > +  IN DWC_XDCI_TRB_CONTROL    TrbCtrl,
> > +  IN UINT8                   *BufferPtr,
> > +  IN UINT32                  size
> > +  )
> > +{
> > +#define ONE_TRB_SIZE      (DWC_XDCI_TRB_BUFF_SIZE_MASK &
> 0x00F00000)
> > +  UINT8                   *TrbBuffer;
> > +  UINT32                  TrbCtrlLast;
> > +  UINT32                  TrbCtrlChain;
> > +  UINT32                  TrbIndex;
> > +
> > +  if (CoreHandle == NULL) {
> > +    DEBUG ((DEBUG_INFO, "ERROR: DwcXdciCoreInitTrb: INVALID
> handle\n"));
> > +    return EFI_DEVICE_ERROR;
> > +  }
> > +
> > +  if (Trb == NULL) {
> > +    DEBUG ((DEBUG_INFO, "ERROR: DwcXdciCoreInitTrb: INVALID
> handle\n"));
> > +    return EFI_INVALID_PARAMETER;
> > +  }
> > +
> > +   //
> > +   // Init TRB fields
> > +   // NOTE: Assuming we are only using 32-bit addresses
> > +   // TODO: update for 64-bit addresses
> > +   //
> > +  if (size <= DWC_XDCI_TRB_BUFF_SIZE_MASK) {
> > +    //
> > +    // Can transfer in one TRB
> > +    //
> > +    TrbCtrlChain = 0;
> > +    TrbCtrlLast = 1;
> > +    DwcXdciCorePrepareOneTrb (Trb, TrbCtrl, TrbCtrlLast, TrbCtrlChain,
> BufferPtr, size);
> > +    return EFI_SUCCESS;
> > +  }
> > +
> > +  //
> > +  // Can't transfer in one TRB.
> > +  // Seperate it in every ONE_TRB_SIZE of TRB
> > +  //
> > +  TrbBuffer = BufferPtr;
> > +  TrbIndex = 0;
> > +  while (size > ONE_TRB_SIZE) {
> > +    TrbCtrlChain = 1;
> > +    TrbCtrlLast = 0;
> > +    DwcXdciCorePrepareOneTrb (Trb, TrbCtrl, TrbCtrlLast, TrbCtrlChain,
> TrbBuffer, ONE_TRB_SIZE);
> > +    TrbBuffer += ONE_TRB_SIZE;
> > +    size -= ONE_TRB_SIZE;
> > +    Trb++;
> > +    TrbIndex++;
> > +    if (TrbIndex >= DWC_XDCI_TRB_NUM)
> > +      return EFI_OUT_OF_RESOURCES;
> > +  }
> > +  TrbCtrlChain = 0;
> > +  TrbCtrlLast = 1;
> > +  DwcXdciCorePrepareOneTrb (Trb, TrbCtrl, TrbCtrlLast, TrbCtrlChain,
> TrbBuffer, size);
> > +
> > +  return EFI_SUCCESS;
> > +}
> > +
> > +
> > +/**
> > +  Internal function:
> > +  This function is used to start a SETUP phase on control endpoint
> > +  @CoreHandle: xDCI controller handle address
> > +
> > +**/
> > +STATIC
> > +EFI_STATUS
> > +DwcXdciCoreStartEp0SetupXfer (
> > +  IN XDCI_CORE_HANDLE    *CoreHandle
> > +  )
> > +{
> > +  DWC_XDCI_ENDPOINT_CMD_PARAMS    EpCmdParams;
> > +  EFI_STATUS                      status = EFI_DEVICE_ERROR;
> > +  DWC_XDCI_TRB                    *Trb;
> > +
> > +  if (CoreHandle == NULL) {
> > +    DEBUG ((DEBUG_INFO, "ERROR: DwcXdciCoreStartEp0SetupXfer:
> INVALID handle\n"));
> > +    return EFI_DEVICE_ERROR;
> > +  }
> > +
> > +  if (CoreHandle->EpHandles[0].State == USB_EP_STATE_SETUP) {
> > +    DEBUG ((DEBUG_INFO, "EP0 was already in SETUP phase\n"));
> > +    return EFI_SUCCESS;
> > +  }
> > +
> > +  CoreHandle->EpHandles[0].State = USB_EP_STATE_SETUP;
> > +  Trb = CoreHandle->Trbs;
> > +  DEBUG ((DEBUG_INFO, "(DwcXdciCoreStartEp0SetupXfer)\n"));
> > +
> > +  status = DwcXdciCoreInitTrb (
> > +             CoreHandle,
> > +             Trb,
> > +             TRBCTL_SETUP,
> > +             CoreHandle->AlignedSetupBuffer,
> > +             8
> > +             );
> > +
> > +  if (status)
> > +    return status;
> > +
> > +  //
> > +  // Issue a DEPSTRTXFER for EP0
> > +  // Reset params
> > +  //
> > +  EpCmdParams.Param0 = EpCmdParams.Param1 =
> EpCmdParams.Param2 = 0;
> > +
> > +  //
> > +  // Init the lower re-bits for TRB address
> > +  //
> > +  EpCmdParams.Param1 = (UINT32)(UINTN)Trb;
> > +
> > +  //
> > +  // Issue the command to start transfer on physical
> > +  // endpoint 0
> > +  //
> > +  status = DwcXdciCoreIssueEpCmd (
> > +             CoreHandle,
> > +             0,
> > +             EPCMD_START_XFER,
> > +             &EpCmdParams
> > +             );
> > +
> > +  //
> > +  // Save new resource index for this transfer
> > +  //
> > +  CoreHandle->EpHandles[0].CurrentXferRscIdx = ((UsbRegRead (
> > +                                                     CoreHandle->BaseAddress,
> > +                                                     DWC_XDCI_EPCMD_REG(0)) &
> DWC_XDCI_EPCMD_RES_IDX_MASK) >>
> DWC_XDCI_EPCMD_RES_IDX_BIT_POS
> > +                                                     );
> > +
> > +  return status;
> > +}
> > +
> > +
> > +/**
> > +  Internal function:
> > +  This function is used to process the state change event
> > +  @CoreHandle: xDCI controller handle address
> > +  @event: device event dword
> > +
> > +**/
> > +STATIC
> > +EFI_STATUS
> > +DwcXdciProcessDeviceStateChangeEvent (
> > +  IN XDCI_CORE_HANDLE    *CoreHandle,
> > +  IN UINT32              Event
> > +  )
> > +{
> > +  if (CoreHandle == NULL) {
> > +    DEBUG ((DEBUG_INFO, "ERROR:
> DwcXdciProcessDeviceStateChangeEvent: INVALID handle\n"));
> > +    return EFI_DEVICE_ERROR;
> > +  }
> > +
> > +  CoreHandle->HirdVal = (Event &
> DWC_XDCI_EVENT_BUFF_DEV_HIRD_MASK) >>
> DWC_XDCI_EVENT_BUFF_DEV_HIRD_BIT_POS;
> > +
> > +  CoreHandle->LinkState = ((Event &
> DWC_XDCI_EVENT_BUFF_DEV_LINK_STATE_MASK) >>
> DWC_XDCI_EVENT_BUFF_DEV_LINK_STATE_BIT_POS);
> > +
> > +  if (CoreHandle->EventCallbacks.DevLinkStateCallback) {
> > +    CoreHandle->EventCallbacks.CbEventParams.ParentHandle =
> CoreHandle->ParentHandle;
> > +    CoreHandle->EventCallbacks.CbEventParams.LinkState = CoreHandle-
> >LinkState;
> > +    CoreHandle->EventCallbacks.CbEventParams.Hird = CoreHandle-
> >HirdVal;
> > +    CoreHandle->EventCallbacks.CbEventParams.SsEvent = (Event &
> DWC_XDCI_EVENT_BUFF_DEV_SS_EVENT_MASK) ? 1 : 0;
> > +    CoreHandle->EventCallbacks.DevLinkStateCallback (&CoreHandle-
> >EventCallbacks.CbEventParams);
> > +  }
> > +
> > +  return EFI_SUCCESS;
> > +}
> > +
> > +
> > +/**
> > +  Internal function:
> > +  This function is used to issue a command to end transfer
> > +  @CoreHandle: xDCI controller handle address
> > +  @EpNum: Physical EP num for which transfer is to be ended
> > +
> > +**/
> > +STATIC
> > +EFI_STATUS
> > +DwcXdciEndXfer (
> > +  IN XDCI_CORE_HANDLE    *CoreHandle,
> > +  IN UINT32              EpNum
> > +  )
> > +{
> > +  EFI_STATUS                      status;
> > +  DWC_XDCI_ENDPOINT_CMD_PARAMS    EpCmdParams;
> > +  UINT32                          cmdParams;
> > +  DWC_XDCI_TRB                    *TrbPtr;
> > +
> > +  if (CoreHandle == NULL) {
> > +    DEBUG ((DEBUG_INFO, "ERROR: DwcXdciEndXfer: INVALID handle\n"));
> > +    return EFI_DEVICE_ERROR;
> > +  }
> > +
> > +  CoreHandle->EpHandles[EpNum].CheckFlag = FALSE;
> > +
> > +  //
> > +  // Issue a DEPENDXFER for EP
> > +  // Reset params
> > +  //
> > +  EpCmdParams.Param0 = EpCmdParams.Param1 =
> EpCmdParams.Param2 = 0;
> > +
> > +  cmdParams = ((CoreHandle->EpHandles[EpNum].CurrentXferRscIdx <<
> DWC_XDCI_EPCMD_RES_IDX_BIT_POS) |
> DWC_XDCI_EPCMD_FORCE_RM_MASK);
> > +
> > +  if (CoreHandle->EpHandles[EpNum].CurrentXferRscIdx == 0) {
> > +    return EFI_SUCCESS;
> > +  }
> > +  //
> > +  // Issue the command
> > +  //
> > +  status = DwcXdciCoreIssueEpCmd(
> > +             CoreHandle,
> > +             EpNum,
> > +             cmdParams | DWC_XDCI_EPCMD_END_XFER,
> > +             &EpCmdParams
> > +             );
> > +
> > +  if (!status) {
> > +    CoreHandle->EpHandles[EpNum].CurrentXferRscIdx = 0;
> > +    TrbPtr = CoreHandle->Trbs + (EpNum * DWC_XDCI_TRB_NUM);
> > +    ZeroMem (TrbPtr, DWC_XDCI_TRB_NUM * sizeof (DWC_XDCI_TRB));
> > +  }
> > +
> > +  return status;
> > +}
> > +
> > +
> > +/**
> > +  Internal function:
> > +  This function is used to process bus reset detection event
> > +  @CoreHandle: xDCI controller handle address
> > +
> > +**/
> > +STATIC
> > +EFI_STATUS
> > +DwcXdciProcessDeviceResetDet (
> > +  IN XDCI_CORE_HANDLE    *CoreHandle
> > +  )
> > +{
> > +  EFI_STATUS  status = EFI_SUCCESS;
> > +
> > +  if (CoreHandle == NULL) {
> > +    return EFI_DEVICE_ERROR;
> > +  }
> > +
> > +  //
> > +  // Flush all FIFOs
> > +  //
> > +  status = DwcXdciCoreFlushAllFifos(CoreHandle);
> > +  if (status) {
> > +    DEBUG ((DEBUG_INFO, "DwcXdciProcessDeviceResetDet: Failed to flush
> FIFOs\n"));
> > +  }
> > +
> > +  //
> > +  // Start SETUP phase on EP0
> > +  //
> > +  status = DwcXdciCoreStartEp0SetupXfer(CoreHandle);
> > +
> > +  if (status) {
> > +    DEBUG ((DEBUG_INFO, "DwcXdciProcessDeviceResetDet: Failed to start
> SETUP phase for EP0\n"));
> > +    return status;
> > +  }
> > +
> > +  //
> > +  // Notify upper layer if a callback is registerd for
> > +  //  this event
> > +  //
> > +  if (CoreHandle->EventCallbacks.DevBusResetCallback) {
> > +    CoreHandle->EventCallbacks.CbEventParams.ParentHandle =
> CoreHandle->ParentHandle;
> > +    status = CoreHandle->EventCallbacks.DevBusResetCallback
> (&CoreHandle->EventCallbacks.CbEventParams);
> > +  }
> > +
> > +  return status;
> > +}
> > +
> > +
> > +/**
> > +  Internal function:
> > +  This function is used to process connection done (means reset
> > +  complete) event
> > +  @CoreHandle: xDCI controller handle address
> > +
> > +**/
> > +STATIC
> > +EFI_STATUS
> > +DwcXdciProcessDeviceResetDone (
> > +  IN XDCI_CORE_HANDLE    *CoreHandle
> > +  )
> > +{
> > +  DWC_XDCI_ENDPOINT_CMD_PARAMS    EpCmdParams;
> > +  UINT32                          BaseAddr;
> > +  EFI_STATUS                      status = EFI_SUCCESS;
> > +
> > +  if (CoreHandle == NULL) {
> > +    DEBUG ((DEBUG_INFO, "ERROR: DwcXdciProcessDeviceResetDone:
> INVALID handle\n"));
> > +    return EFI_DEVICE_ERROR;
> > +  }
> > +
> > +  BaseAddr = CoreHandle->BaseAddress;
> > +  CoreHandle->ActualSpeed = (UsbRegRead (BaseAddr,
> DWC_XDCI_DSTS_REG) & DWC_XDCI_DSTS_CONN_SPEED_MASK);
> > +  DEBUG ((DEBUG_INFO, "DwcXdciProcessDeviceResetDone CoreHandle-
> >ActualSpeed is %x\n", CoreHandle->ActualSpeed));
> > +
> > +  //
> > +  // Program MPS Based on the negotiated Speed
> > +  //
> > +  DwcXdciCoreGetCtrlMps (CoreHandle, &CoreHandle-
> >EpHandles[0].EpInfo.MaxPktSize);
> > +  DwcXdciCoreGetCtrlMps (CoreHandle, &CoreHandle-
> >EpHandles[1].EpInfo.MaxPktSize);
> > +
> > +  //
> > +  // Init DEPCFG cmd params for EP0
> > +  //
> > +  status = DwcXdciCoreInitEpCmdParams (
> > +             CoreHandle,
> > +             &CoreHandle->EpHandles[0].EpInfo,
> > +             DWC_XDCI_PARAM0_SET_EP_CFG_ACTN_MDFY_STATE,
> > +             EPCMD_SET_EP_CONFIG,
> > +             &EpCmdParams
> > +             );
> > +
> > +  if (status) {
> > +    return status;
> > +  }
> > +
> > +  //
> > +  // Issue the command
> > +  //
> > +  status = DwcXdciCoreIssueEpCmd (
> > +             CoreHandle,
> > +             0,
> > +             EPCMD_SET_EP_CONFIG,
> > +             &EpCmdParams
> > +             );
> > +
> > +  if (status) {
> > +    return status;
> > +  }
> > +
> > +  //
> > +  // Init DEPCFG cmd params for EP1
> > +  //
> > +  status = DwcXdciCoreInitEpCmdParams (
> > +             CoreHandle,
> > +             &CoreHandle->EpHandles[1].EpInfo,
> > +             DWC_XDCI_PARAM0_SET_EP_CFG_ACTN_MDFY_STATE,
> > +             EPCMD_SET_EP_CONFIG,
> > +             &EpCmdParams
> > +             );
> > +
> > +  //
> > +  // Issue the command
> > +  //
> > +  status = DwcXdciCoreIssueEpCmd (
> > +             CoreHandle,
> > +             1,
> > +             EPCMD_SET_EP_CONFIG,
> > +             &EpCmdParams
> > +             );
> > +
> > +  //
> > +  // Put the other PHY into suspend
> > +  //
> > +  if (CoreHandle->ActualSpeed == USB_SPEED_SUPER) {
> > +    //
> > +    // Put HS PHY to suspend
> > +    //
> > +    UsbRegWrite (
> > +      BaseAddr,
> > +      DWC_XDCI_GUSB2PHYCFG_REG (0),
> > +      (UsbRegRead (BaseAddr, DWC_XDCI_GUSB2PHYCFG_REG(0)) |
> DWC_XDCI_GUSB2PHYCFG_SUSPEND_PHY_MASK)
> > +      );
> > +
> > +    //
> > +    // Clear SS PHY's suspend mask
> > +    //
> > +    UsbRegWrite (
> > +      BaseAddr,
> > +      DWC_XDCI_GUSB3PIPECTL_REG (0),
> > +      (UsbRegRead (BaseAddr, DWC_XDCI_GUSB3PIPECTL_REG(0)) &
> ~DWC_XDCI_GUSB3PIPECTL_SUSPEND_PHY_MASK)
> > +      );
> > +
> > +  } else {
> > +    //
> > +    // Put SS PHY to suspend
> > +    //
> > +    UsbRegWrite (
> > +      BaseAddr,
> > +      DWC_XDCI_GUSB3PIPECTL_REG(0),
> > +      (UsbRegRead(BaseAddr, DWC_XDCI_GUSB3PIPECTL_REG(0)) |
> DWC_XDCI_GUSB3PIPECTL_SUSPEND_PHY_MASK)
> > +      );
> > +
> > +    //
> > +    // Clear HS PHY's suspend mask
> > +    //
> > +    UsbRegWrite (
> > +      BaseAddr,
> > +      DWC_XDCI_GUSB2PHYCFG_REG(0),
> > +      (UsbRegRead(BaseAddr, DWC_XDCI_GUSB2PHYCFG_REG(0)) &
> ~DWC_XDCI_GUSB2PHYCFG_SUSPEND_PHY_MASK)
> > +      );
> > +  }
> > +
> > +  //
> > +  // Notify upper layer if callback is registered
> > +  //
> > +  if (CoreHandle->EventCallbacks.DevResetDoneCallback) {
> > +    CoreHandle->EventCallbacks.CbEventParams.ParentHandle =
> CoreHandle->ParentHandle;
> > +    CoreHandle->EventCallbacks.CbEventParams.Speed = CoreHandle-
> >ActualSpeed;
> > +    CoreHandle->EventCallbacks.DevResetDoneCallback (&CoreHandle-
> >EventCallbacks.CbEventParams);
> > +  }
> > +
> > +  return status;
> > +}
> > +
> > +
> > +/**
> > +  Internal function:
> > +  This function is used to process device event
> > +  @CoreHandle: xDCI controller handle address
> > +  @IntLineEventBuffer: event Buffer pointing to device event
> > +  @ProcessedEventSize: address of variable to save the size of
> > +  the event that was Processed
> > +
> > +**/
> > +STATIC
> > +EFI_STATUS
> > +DwcXdciProcessDeviceEvent (
> > +  IN XDCI_CORE_HANDLE         *CoreHandle,
> > +  IN DWC_XDCI_EVENT_BUFFER    *IntLineEventBuffer,
> > +  IN UINT32                   *ProcessedEventSize
> > +  )
> > +{
> > +  UINT32 event;
> > +
> > +  if (CoreHandle == NULL) {
> > +    DEBUG ((DEBUG_INFO, "ERROR: DwcXdciProcessDeviceEvent: INVALID
> handle\n"));
> > +    return EFI_DEVICE_ERROR;
> > +  }
> > +
> > +  //
> > +  // Extract device event
> > +  //
> > +  event = (IntLineEventBuffer->Event &
> DWC_XDCI_EVENT_BUFF_DEV_EVT_MASK);
> > +  event >>= DWC_XDCI_EVENT_BUFF_DEV_EVT_BIT_POS;
> > +
> > +  //
> > +  // Assume default event size. Change it in switch case if
> > +  //  different
> > +  //
> > +  *ProcessedEventSize =
> DWC_XDCI_DEV_EVENT_DEFAULT_SIZE_IN_BYTES;
> > +
> > +  switch (event) {
> > +    case DWC_XDCI_EVENT_BUFF_DEV_DISCONN_EVENT:
> > +      DEBUG ((DEBUG_INFO, "Device
> DWC_XDCI_EVENT_BUFF_DEV_DISCONN_EVENT\n"));
> > +      break;
> > +
> > +    case DWC_XDCI_EVENT_BUFF_DEV_USB_RESET_EVENT:
> > +      DEBUG ((DEBUG_INFO, "Device
> DWC_XDCI_EVENT_BUFF_DEV_USB_RESET_EVENT\n"));
> > +      DwcXdciProcessDeviceResetDet (CoreHandle);
> > +      break;
> > +
> > +    case DWC_XDCI_EVENT_BUFF_DEV_CONN_DONE_EVENT:
> > +      DEBUG ((DEBUG_INFO, "Device
> DWC_XDCI_EVENT_BUFF_DEV_CONN_DONE_EVENT\n"));
> > +      DwcXdciProcessDeviceResetDone (CoreHandle);
> > +      break;
> > +
> > +    case DWC_XDCI_EVENT_BUFF_DEV_STATE_CHANGE_EVENT:
> > +      DEBUG ((DEBUG_INFO, "Device
> DWC_XDCI_EVENT_BUFF_DEV_STATE_CHANGE_EVENT\n"));
> > +      DwcXdciProcessDeviceStateChangeEvent (CoreHandle,
> IntLineEventBuffer->Event);
> > +      break;
> > +
> > +    case DWC_XDCI_EVENT_BUFF_DEV_WKUP_EVENT:
> > +      DEBUG ((DEBUG_INFO, "Device
> DWC_XDCI_EVENT_BUFF_DEV_WKUP_EVENT\n"));
> > +      break;
> > +
> > +    case DWC_XDCI_EVENT_BUFF_DEV_HBRNTN_REQ_EVENT:
> > +      DEBUG ((DEBUG_INFO, "Device
> DWC_XDCI_EVENT_BUFF_DEV_HBRNTN_REQ_EVENT\n"));
> > +      break;
> > +
> > +    case DWC_XDCI_EVENT_BUFF_DEV_SOF_EVENT:
> > +      DEBUG ((DEBUG_INFO, "Device
> DWC_XDCI_EVENT_BUFF_DEV_SOF_EVENT\n"));
> > +      break;
> > +
> > +    case DWC_XDCI_EVENT_BUFF_DEV_ERRATIC_ERR_EVENT:
> > +      DEBUG ((DEBUG_INFO, "Device
> DWC_XDCI_EVENT_BUFF_DEV_ERRATIC_ERR_EVENT\n"));
> > +      break;
> > +
> > +    case DWC_XDCI_EVENT_BUFF_DEV_CMD_CMPLT_EVENT:
> > +      DEBUG ((DEBUG_INFO, "Device
> DWC_XDCI_EVENT_BUFF_DEV_CMD_CMPLT_EVENT\n"));
> > +      break;
> > +
> > +    case DWC_XDCI_EVENT_BUFF_DEV_BUFF_OVFL_EVENT:
> > +      DEBUG ((DEBUG_INFO, "Device
> DWC_XDCI_EVENT_BUFF_DEV_BUFF_OVFL_EVENT\n"));
> > +      break;
> > +
> > +    case DWC_XDCI_EVENT_BUFF_DEV_TST_LMP_RX_EVENT:
> > +      DEBUG ((DEBUG_INFO, "Device
> DWC_XDCI_EVENT_BUFF_DEV_TST_LMP_RX_EVENT\n"));
> > +      *ProcessedEventSize =
> DWC_XDCI_DEV_EVENT_TST_LMP_SIZE_IN_BYTES;
> > +      break;
> > +
> > +    default:
> > +      DEBUG ((DEBUG_INFO, "DwcXdciProcessDeviceEvent: UNHANDLED
> device event: %x\n", event));
> > +      break;
> > +  }
> > +
> > +  return EFI_SUCCESS;
> > +}
> > +
> > +
> > +/**
> > +  Internal function:
> > +  This function is used to process EP not ready for
> > +  non-control endpoints
> > +  @CoreHandle: xDCI controller handle address
> > +  @EpNum: Physical endpoint number
> > +
> > +**/
> > +STATIC
> > +EFI_STATUS
> > +DwcXdciProcessEpXferNotReady (
> > +  IN XDCI_CORE_HANDLE    *CoreHandle,
> > +  IN UINT32              EpNum
> > +  )
> > +{
> > +  //
> > +  // TODO: Not doing on-demand transfers
> > +  // Revisit if required for later use
> > +  //
> > +  return EFI_SUCCESS;
> > +}
> > +
> > +
> > +/**
> > +  Internal function:
> > +  This function is used to process EP not ready for
> > +  control endpoints
> > +  @CoreHandle: xDCI controller handle address
> > +  @EpNum: Physical endpoint number
> > +  @dataStage: EP not ready when data stage token was received
> > +  @statusStage: EP not ready when status stage token was received
> > +
> > +**/
> > +STATIC
> > +EFI_STATUS
> > +DwcXdciProcessEp0XferNotReady (
> > +  IN XDCI_CORE_HANDLE    *CoreHandle,
> > +  IN UINT32              EpNum,
> > +  IN UINT32              epEventStatus
> > +  )
> > +{
> > +  USB_EP_STATE        epState = USB_EP_STATE_SETUP;
> > +
> > +  if (CoreHandle == NULL) {
> > +    DEBUG ((DEBUG_INFO, "ERROR: DwcXdciProcessEp0XferNotReady:
> INVALID handle\n"));
> > +    return EFI_DEVICE_ERROR;
> > +  }
> > +  //
> > +  // Is it data stage or status stage
> > +  //
> > +  if (epEventStatus &
> DWC_XDCI_EVENT_BUFF_EP_CTRL_DATA_REQ_MASK) {
> > +    epState = USB_EP_STATE_DATA;
> > +  } else if (epEventStatus &
> DWC_XDCI_EVENT_BUFF_EP_CTRL_STATUS_REQ_MASK) {
> > +    epState = USB_EP_STATE_STATUS;
> > +  }
> > +
> > +  if ((EpNum == 0) && (epState == USB_EP_STATE_STATUS)) {
> > +    if (epEventStatus & DWC_XDCI_EVENT_BUFF_EP_XFER_ACTIVE_MASK) {
> > +      DEBUG ((DEBUG_INFO, "XFER_ACTIVE\n"));
> > +    } else {
> > +      DEBUG ((DEBUG_INFO, "XFER_NOT_ACTIVE\n"));
> > +    }
> > +    DwcXdciEp0ReceiveStatusPkt (CoreHandle);
> > +  }
> > +
> > +  //
> > +  // Notify upper layer if a callback is registered for
> > +  // this event
> > +  //
> > +  if (CoreHandle->EventCallbacks.DevXferNrdyCallback) {
> > +    CoreHandle->EventCallbacks.CbEventParams.ParentHandle =
> CoreHandle->ParentHandle;
> > +    CoreHandle->EventCallbacks.CbEventParams.EpState = epState;
> > +    CoreHandle->EventCallbacks.DevXferNrdyCallback (&CoreHandle-
> >EventCallbacks.CbEventParams);
> > +  }
> > +
> > +  return EFI_SUCCESS;
> > +}
> > +
> > +
> > +/**
> > +  Internal function:
> > +  This function is used to process transfer phone done for EP0
> > +  @CoreHandle: xDCI controller handle address
> > +  @EpNum: Physical endpoint number (0 for OUT and 1 for IN)
> > +
> > +**/
> > +STATIC
> > +EFI_STATUS
> > +DwcXdciProcessEp0XferPhaseDone (
> > +  IN XDCI_CORE_HANDLE    *CoreHandle,
> > +  IN UINT32              EpNum
> > +  )
> > +{
> > +  DWC_XDCI_ENDPOINT    *epHandle;
> > +  DWC_XDCI_TRB         *Trb;
> > +  EFI_STATUS           status = EFI_SUCCESS;
> > +  UINT32               TrbSts;
> > +  UINT32               TrbCtrl;
> > +  UINT32               TrbBufsize;
> > +
> > +  if (CoreHandle == NULL) {
> > +    DEBUG ((DEBUG_INFO, "ERROR: DwcXdciProcessEp0XferPhaseDone:
> INVALID handle\n"));
> > +    return EFI_DEVICE_ERROR;
> > +  }
> > +
> > +  epHandle = &CoreHandle->EpHandles[EpNum];
> > +  Trb = CoreHandle->Trbs + (EpNum * DWC_XDCI_TRB_NUM);
> > +  DEBUG ((DEBUG_INFO, "(DwcXdciProcessEp0XferPhaseDone)EpNum is
> %d\n", EpNum));
> > +
> > +  if (Trb->TrbCtrl & DWC_XDCI_TRB_CTRL_HWO_MASK) {
> > +    DEBUG ((DEBUG_INFO, "DwcXdciProcessEp0XferPhaseDone. HW owns
> TRB: %x!!!\n", (UINT32)(UINTN)Trb));
> > +  }
> > +
> > +  epHandle->CurrentXferRscIdx = 0;
> > +  epHandle->State = USB_EP_STATE_ENABLED;
> > +  TrbCtrl = (Trb->TrbCtrl & DWC_XDCI_TRB_CTRL_TYPE_MASK) >>
> DWC_XDCI_TRB_CTRL_TYPE_BIT_POS;
> > +  TrbSts = (Trb->LenXferParams & DWC_XDCI_TRB_STATUS_MASK) >>
> DWC_XDCI_TRB_STATUS_BIT_POS;
> > +  TrbBufsize = Trb->LenXferParams & DWC_XDCI_TRB_BUFF_SIZE_MASK;
> > +
> > +  switch (TrbCtrl) {
> > +    case DWC_XDCI_TRB_CTRL_TYPE_SETUP:
> > +      DEBUG ((DEBUG_INFO, "SETUP\n"));
> > +      if (CoreHandle->EventCallbacks.DevSetupPktReceivedCallback) {
> > +        CoreHandle->EventCallbacks.CbEventParams.ParentHandle =
> CoreHandle->ParentHandle;
> > +        CoreHandle->EventCallbacks.CbEventParams.Buffer = CoreHandle-
> >AlignedSetupBuffer;
> > +        status = CoreHandle->EventCallbacks.DevSetupPktReceivedCallback
> (&CoreHandle->EventCallbacks.CbEventParams);
> > +      }
> > +
> > +      if (!(CoreHandle->AlignedSetupBuffer[0] &
> USB_SETUP_DATA_PHASE_DIRECTION_MASK)) {
> > +        //
> > +        // Keep a Buffer ready for setup phase
> > +        //
> > +        DwcXdciCoreStartEp0SetupXfer (CoreHandle);
> > +      }
> > +
> > +      break;
> > +
> > +    case DWC_XDCI_TRB_CTRL_TYPE_STATUS2:
> > +      DEBUG ((DEBUG_INFO, "STATUS2\n"));
> > +      break;
> > +
> > +    case DWC_XDCI_TRB_CTRL_TYPE_STATUS3:
> > +      DEBUG ((DEBUG_INFO, "STATUS3\n"));
> > +      //
> > +      // Notify upper layer of control transfer completion
> > +      // if a callback function was registerd
> > +      //
> > +      if (CoreHandle->EventCallbacks.DevXferDoneCallback) {
> > +        CoreHandle->EventCallbacks.CbEventParams.ParentHandle =
> CoreHandle->ParentHandle;
> > +        CoreHandle->EventCallbacks.CbEventParams.EpNum = (EpNum >> 1);
> > +        CoreHandle->EventCallbacks.CbEventParams.EpDir = (EpNum & 1);
> > +        CoreHandle->EventCallbacks.CbEventParams.Buffer = (UINT8
> *)(UINTN)(Trb->BuffPtrLow);
> > +        CoreHandle->EventCallbacks.DevXferDoneCallback (&CoreHandle-
> >EventCallbacks.CbEventParams);
> > +      }
> > +
> > +      //
> > +      // Status phase done. Queue next SETUP packet
> > +      //
> > +      status = DwcXdciCoreStartEp0SetupXfer(CoreHandle);
> > +
> > +      if (status) {
> > +        DEBUG ((DEBUG_INFO, "DwcXdciProcessEp0XferPhaseDone: FAILED
> to queue SETUP\n"));
> > +      }
> > +      break;
> > +
> > +    case DWC_XDCI_TRB_CTRL_TYPE_DATA:
> > +      DEBUG ((DEBUG_INFO, "DATA\n"));
> > +      if (TrbSts == DWC_XDCI_TRB_STATUS_SETUP_PENDING || TrbBufsize
> != 0) {
> > +        DEBUG ((DEBUG_INFO, "ERROR: Control transfert aborted by host:
> Setup pending\n"));
> > +        DwcXdciCoreStartEp0SetupXfer (CoreHandle);
> > +      }
> > +
> > +      if (CoreHandle->EventCallbacks.DevXferDoneCallback) {
> > +        CoreHandle->EventCallbacks.CbEventParams.ParentHandle =
> CoreHandle->ParentHandle;
> > +        CoreHandle->EventCallbacks.CbEventParams.EpNum = (EpNum >> 1);
> > +        CoreHandle->EventCallbacks.CbEventParams.EpDir = (EpNum & 1);
> > +        CoreHandle->EventCallbacks.CbEventParams.Buffer = (UINT8
> *)(UINTN)(Trb->BuffPtrLow);
> > +        CoreHandle->EventCallbacks.DevXferDoneCallback (&CoreHandle-
> >EventCallbacks.CbEventParams);
> > +      }
> > +      break;
> > +
> > +    default:
> > +      DEBUG ((DEBUG_INFO, "DwcXdciProcessEp0XferPhaseDone:
> UNHANDLED STATE in TRB\n"));
> > +      break;
> > +  }
> > +
> > +  return status;
> > +}
> > +
> > +
> > +/**
> > +  Internal function:
> > +  This function is used to process transfer done for
> > +  non-control endpoints
> > +  @CoreHandle: xDCI controller handle address
> > +  @EpNum: Physical endpoint number
> > +
> > +**/
> > +STATIC
> > +EFI_STATUS
> > +DwcXdciProcessEpXferDone (
> > +  IN XDCI_CORE_HANDLE    *CoreHandle,
> > +  IN UINT32              EpNum
> > +  )
> > +{
> > +  DWC_XDCI_ENDPOINT    *epHandle;
> > +  DWC_XDCI_TRB         *Trb;
> > +  USB_XFER_REQUEST     *XferReq;
> > +  UINT32               remainingLen;
> > +
> > +  if (CoreHandle == NULL) {
> > +    DEBUG ((DEBUG_INFO, "ERROR: DwcXdciProcessEpXferDone: INVALID
> handle\n"));
> > +    return EFI_DEVICE_ERROR;
> > +  }
> > +
> > +  epHandle = &CoreHandle->EpHandles[EpNum];
> > +  epHandle->CurrentXferRscIdx = 0;
> > +  Trb = epHandle->Trb;
> > +  XferReq = &epHandle->XferHandle;
> > +
> > +  //
> > +  // if transfer done, set CheckFlag to FALSE for allow next transfer
> request.
> > +  //
> > +  epHandle->CheckFlag = FALSE;
> > +
> > +  if ((Trb == NULL) || (XferReq == NULL)) {
> > +    DEBUG ((DEBUG_INFO, "ERROR: DwcXdciProcessEpXferDone: INVALID
> parameter\n"));
> > +    return EFI_INVALID_PARAMETER;
> > +  }
> > +
> > +  //
> > +  // Compute the actual transfer length
> > +  //
> > +  XferReq->ActualXferLen = XferReq->XferLen;
> > +  remainingLen = (Trb->LenXferParams &
> DWC_XDCI_TRB_BUFF_SIZE_MASK);
> > +
> > +  if (remainingLen > XferReq->XferLen) {
> > +    //
> > +    // Buffer overrun? This should never happen
> > +    //
> > +    DEBUG ((DEBUG_INFO, "ERROR: DwcXdciProcessEpXferDone: Possible
> Buffer overrun\n"));
> > +  } else {
> > +    XferReq->ActualXferLen -= remainingLen;
> > +  }
> > +
> > +  //
> > +  // Notify upper layer of request-specific transfer completion
> > +  // if there is a callback specifically for this request
> > +  //
> > +  if (XferReq->XferDone) {
> > +    XferReq->XferDone(CoreHandle->ParentHandle, XferReq);
> > +  }
> > +
> > +  //
> > +  // Notify upper layer if a callback was registered
> > +  //
> > +  if (CoreHandle->EventCallbacks.DevXferDoneCallback) {
> > +    CoreHandle->EventCallbacks.CbEventParams.ParentHandle =
> CoreHandle->ParentHandle;
> > +    CoreHandle->EventCallbacks.CbEventParams.EpNum = (EpNum >> 1);
> > +    CoreHandle->EventCallbacks.CbEventParams.EpDir = (EpNum & 1);
> > +    CoreHandle->EventCallbacks.CbEventParams.EpType = epHandle-
> >EpInfo.EpType;
> > +    CoreHandle->EventCallbacks.CbEventParams.Buffer = (UINT8
> *)(UINTN)(epHandle->Trb->BuffPtrLow);
> > +    CoreHandle->EventCallbacks.DevXferDoneCallback (&CoreHandle-
> >EventCallbacks.CbEventParams);
> > +  }
> > +
> > +  return EFI_SUCCESS;
> > +}
> > +
> > +
> > +/**
> > +  Internal function:
> > +  This function is used to process endpoint events
> > +  @CoreHandle: xDCI controller handle address
> > +  @IntLineEventBuffer:  address of Buffer containing event
> > +  to process
> > +  @ProcessedEventSize: address to save the size of event
> > +  Processed
> > +
> > +**/
> > +STATIC
> > +EFI_STATUS
> > +DwcXdciProcessEpEvent (
> > +  IN XDCI_CORE_HANDLE         *CoreHandle,
> > +  IN DWC_XDCI_EVENT_BUFFER    *IntLineEventBuffer,
> > +  IN UINT32                   *ProcessedEventSize
> > +  )
> > +{
> > +  UINT32          EpNum;
> > +  UINT32          epEvent;
> > +  UINT32          epEventStatus;
> > +
> > +  if (CoreHandle == NULL) {
> > +    DEBUG ((DEBUG_INFO, "ERROR: DwcXdciProcessEpEvent: INVALID
> handle\n"));
> > +    return EFI_DEVICE_ERROR;
> > +  }
> > +
> > +  epEvent = IntLineEventBuffer->Event;
> > +
> > +  *ProcessedEventSize =
> DWC_XDCI_DEV_EVENT_DEFAULT_SIZE_IN_BYTES;
> > +
> > +  //
> > +  // Get EP num
> > +  //
> > +  EpNum = ((epEvent & DWC_XDCI_EVENT_BUFF_EP_NUM_MASK) >>
> DWC_XDCI_EVENT_BUFF_EP_NUM_BIT_POS);
> > +  epEventStatus = (epEvent &
> DWC_XDCI_EVENT_BUFF_EP_EVENT_STATUS_MASK);
> > +
> > +  //
> > +  // Interpret event and handle transfer completion here
> > +  //
> > +  epEvent = ((epEvent & DWC_XDCI_EVENT_BUFF_EP_EVENT_MASK) >>
> DWC_XDCI_EVENT_BUFF_EP_EVENT_BIT_POS);
> > +
> > +  switch (epEvent) {
> > +    case DWC_XDCI_EVENT_BUFF_EP_XFER_CMPLT:
> > +      DEBUG ((DEBUG_INFO, "XFER_CMPLT ep %d\n", EpNum));
> > +      if (EpNum > 1) {
> > +        DwcXdciProcessEpXferDone (CoreHandle, EpNum);
> > +      } else {
> > +        DwcXdciProcessEp0XferPhaseDone (CoreHandle, EpNum);
> > +      }
> > +      break;
> > +
> > +    case DWC_XDCI_EVENT_BUFF_EP_XFER_IN_PROGRESS:
> > +      DEBUG ((DEBUG_INFO, "IN_PROGRESS\n"));
> > +      break;
> > +
> > +    case DWC_XDCI_EVENT_BUFF_EP_XFER_NOT_READY:
> > +      DEBUG ((DEBUG_INFO, "NOT_READY ep %d\n", EpNum));
> > +      if (EpNum > 1) {
> > +        //
> > +        // Endpoint transfer is not ready
> > +        //
> > +        DwcXdciProcessEpXferNotReady (CoreHandle, EpNum);
> > +      } else {
> > +        DwcXdciProcessEp0XferNotReady (CoreHandle, EpNum,
> epEventStatus);
> > +      }
> > +      break;
> > +
> > +    default:
> > +      DEBUG ((DEBUG_INFO, "DwcXdciProcessEpEvent: UNKNOWN EP
> event\n"));
> > +      break;
> > +  }
> > +
> > +  return EFI_SUCCESS;
> > +}
> > +
> > +
> > +/**
> > +  Internal function:
> > +  This function is used to process events on single interrupt line
> > +  @CoreHandle: xDCI controller handle address
> > +  @eventCount:  event bytes to process
> > +  @ProcessedEventCount: address to save the size
> > +  (in bytes) of event Processed
> > +  Processed
> > +
> > +**/
> > +STATIC
> > +EFI_STATUS
> > +DwcXdciProcessInterruptLineEvents (
> > +  IN XDCI_CORE_HANDLE    *CoreHandle,
> > +  IN UINT32              eventCount,
> > +  IN UINT32              *ProcessedEventCount
> > +  )
> > +{
> > +  UINT32    ProcessedEventSize = 0;
> > +  UINT32    currentEventAddr;
> > +
> > +  if (CoreHandle == NULL) {
> > +    DEBUG ((DEBUG_INFO, "ERROR: DwcXdciProcessInterruptLineEvents:
> INVALID handle\n"));
> > +    return EFI_DEVICE_ERROR;
> > +  }
> > +
> > +  if (CoreHandle->CurrentEventBuffer == NULL) {
> > +    DEBUG ((DEBUG_INFO, "ERROR: DwcXdciProcessInterruptLineEvents:
> INVALID event Buffer\n"));
> > +    return EFI_INVALID_PARAMETER;
> > +  }
> > +
> > +  currentEventAddr = (UINT32)(UINTN)(CoreHandle->CurrentEventBuffer);
> > +
> > +  //
> > +  // Process eventCount/eventSize number of events
> > +  // in this run
> > +  //
> > +  while (eventCount) {
> > +    if (CoreHandle->CurrentEventBuffer->Event &
> DWC_XDCI_EVENT_DEV_MASK) {
> > +      DwcXdciProcessDeviceEvent (
> > +        CoreHandle,
> > +        CoreHandle->CurrentEventBuffer,
> > +        &ProcessedEventSize
> > +        );
> > +    } else {
> > +      DwcXdciProcessEpEvent (
> > +        CoreHandle,
> > +        CoreHandle->CurrentEventBuffer,
> > +        &ProcessedEventSize);
> > +    }
> > +
> > +    eventCount -= ProcessedEventSize;
> > +    *ProcessedEventCount += ProcessedEventSize;
> > +    if ((currentEventAddr + ProcessedEventSize) >=
> > +        ((UINT32)(UINTN)(CoreHandle->AlignedEventBuffers) +
> (sizeof(DWC_XDCI_EVENT_BUFFER) *
> DWC_XDCI_MAX_EVENTS_PER_BUFFER))
> > +       ) {
> > +      currentEventAddr = (UINT32)(UINTN)(CoreHandle-
> >AlignedEventBuffers);
> > +      DEBUG ((DEBUG_INFO, "DwcXdciProcessInterruptLineEvents: Event
> Buffer bound reached\n"));
> > +    } else {
> > +      currentEventAddr += ProcessedEventSize;
> > +    }
> > +
> > +    CoreHandle->CurrentEventBuffer = (DWC_XDCI_EVENT_BUFFER
> *)(UINTN)currentEventAddr;
> > +  }
> > +
> > +  return EFI_SUCCESS;
> > +}
> > +
> > +//
> > +// DWC XDCI APIs
> > +//
> > +
> > +/**
> > +  Interface:
> > +
> > +  This function is used to initialize the xDCI core
> > +  @configParams: Parameters from app to configure the core
> > +  @deviceCorePtr:  HW-independent APIs handle for device core
> > +  @CoreHandle: xDCI controller handle retured
> > +
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +DwcXdciCoreInit (
> > +  IN USB_DEV_CONFIG_PARAMS    *ConfigParams,
> > +  IN VOID                     *deviceCorePtr,
> > +  IN VOID                     **CoreHandle
> > +  )
> > +{
> > +  EFI_STATUS                      status = EFI_DEVICE_ERROR;
> > +  UINT32                          BaseAddr;
> > +  XDCI_CORE_HANDLE                *LocalCoreHandle;
> > +  DWC_XDCI_ENDPOINT_CMD_PARAMS    EpCmdParams;
> > +  UINT32                          MaxDelayIter =
> DWC_XDCI_MAX_DELAY_ITERATIONS;
> > +  UINT8                           i;
> > +
> > +  LocalCoreHandle = (XDCI_CORE_HANDLE *)AllocateZeroPool
> (sizeof(XDCI_CORE_HANDLE));
> > +
> > +  if (CoreHandle == NULL) {
> > +    return EFI_INVALID_PARAMETER;
> > +  }
> > +
> > +  if (LocalCoreHandle == NULL) {
> > +    DEBUG ((DEBUG_INFO, "DwcXdciCoreInit: Failed to allocate handle for
> xDCI\n"));
> > +    return EFI_OUT_OF_RESOURCES;
> > +  }
> > +
> > +  ZeroMem (LocalCoreHandle, sizeof(XDCI_CORE_HANDLE));
> > +
> > +  LocalCoreHandle->ParentHandle = deviceCorePtr;
> > +
> > +  *CoreHandle = (VOID *)LocalCoreHandle;
> > +
> > +  LocalCoreHandle->Id = ConfigParams->ControllerId;
> > +  LocalCoreHandle->BaseAddress = BaseAddr = ConfigParams-
> >BaseAddress;
> > +  LocalCoreHandle->Flags = ConfigParams->Flags;
> > +  LocalCoreHandle->DesiredSpeed = LocalCoreHandle->ActualSpeed =
> ConfigParams->Speed;
> > +  LocalCoreHandle->Role = ConfigParams->Role;
> > +
> > +  DEBUG ((DEBUG_INFO, "Resetting the USB core\n"));
> > +  UsbRegWrite (
> > +    BaseAddr,
> > +    DWC_XDCI_DCTL_REG,
> > +    UsbRegRead (BaseAddr, DWC_XDCI_DCTL_REG) |
> DWC_XDCI_DCTL_CSFTRST_MASK
> > +    );
> > +  //
> > +  // Wait until core soft reset completes
> > +  //
> > +  do {
> > +    if (!(UsbRegRead (BaseAddr, DWC_XDCI_DCTL_REG) &
> DWC_XDCI_DCTL_CSFTRST_MASK)) {
> > +      break;
> > +    } else {
> > +      gBS->Stall (DWC_XDCI_MAX_DELAY_ITERATIONS);
> > +    }
> > +  } while (--MaxDelayIter);
> > +
> > +  if (!MaxDelayIter) {
> > +    DEBUG ((DEBUG_INFO, "Failed to reset device controller\n"));
> > +    return EFI_DEVICE_ERROR;
> > +  }
> > +
> > +  DEBUG ((DEBUG_INFO, "USB core has been reset\n"));
> > +
> > +  //
> > +  // All FIFOs are flushed at this point
> > +  //
> > +  //
> > +  // Ensure we have EP0 Rx/Tx handles initialized
> > +  //
> > +  LocalCoreHandle->EpHandles[0].EpInfo.EpNum = 0;
> > +  LocalCoreHandle->EpHandles[0].EpInfo.EpDir = UsbEpDirOut;
> > +  LocalCoreHandle->EpHandles[0].EpInfo.EpType =
> USB_ENDPOINT_CONTROL;
> > +  LocalCoreHandle->EpHandles[0].EpInfo.MaxPktSize =
> DWC_XDCI_SS_CTRL_EP_MPS;
> > +  //
> > +  // 0 means burst size of 1
> > +  //
> > +  LocalCoreHandle->EpHandles[0].EpInfo.BurstSize = 0;
> > +
> > +  LocalCoreHandle->EpHandles[1].EpInfo.EpNum = 0;
> > +  LocalCoreHandle->EpHandles[1].EpInfo.EpDir = UsbEpDirIn;
> > +  LocalCoreHandle->EpHandles[1].EpInfo.EpType =
> USB_ENDPOINT_CONTROL;
> > +  LocalCoreHandle->EpHandles[1].EpInfo.MaxPktSize =
> DWC_XDCI_SS_CTRL_EP_MPS;
> > +  //
> > +  // 0 means burst size of 1
> > +  //
> > +  LocalCoreHandle->EpHandles[1].EpInfo.BurstSize = 0;
> > +
> > +  LocalCoreHandle->DevState = UsbDevStateDefault;
> > +
> > +  //
> > +  // Clear KeepConnect bit so we can allow disconnect and
> > +  // re-connect. Stay in RX_DETECT state
> > +  //
> > +  UsbRegWrite (
> > +    BaseAddr,
> > +    DWC_XDCI_DCTL_REG,
> > +    UsbRegRead (BaseAddr, DWC_XDCI_DCTL_REG) &
> > +    (~DWC_XDCI_DCTL_KEEP_CONNECT_MASK) &
> > +    ((~DWC_XDCI_DCTL_STATE_CHANGE_REQ_MASK) |
> (DWC_XDCI_DCTL_STATE_CHANGE_REQ_RX_DETECT <<
> DWC_XDCI_DCTL_STATE_CHANGE_REQ_BIT_POS))
> > +    );
> > +
> > +  DEBUG ((DEBUG_INFO, "Device controller Synopsys ID: %x\n",
> UsbRegRead (BaseAddr, DWC_XDCI_GSNPSID_REG)));
> > +  DEBUG ((DEBUG_INFO, "Default value of xDCI GSBUSCFG0 and
> GSBUSCFG1: %x, %x\n",
> > +          UsbRegRead (BaseAddr, DWC_XDCI_GSBUSCFG0_REG),
> > +          UsbRegRead (BaseAddr, DWC_XDCI_GSBUSCFG1_REG)));
> > +
> > +  DEBUG ((DEBUG_INFO, "Default value of xDCI GTXTHRCFG and
> GRXTHRCFG: %x, %x\n",
> > +          UsbRegRead (BaseAddr, DWC_XDCI_GTXTHRCFG_REG),
> > +          UsbRegRead (BaseAddr, DWC_XDCI_GRXTHRCFG_REG)));
> > +
> > +  //
> > +  // Clear ULPI auto-resume bit
> > +  //
> > +  UsbRegWrite (
> > +    BaseAddr,
> > +    DWC_XDCI_GUSB2PHYCFG_REG (0),
> > +    (UsbRegRead (BaseAddr, DWC_XDCI_GUSB2PHYCFG_REG (0)) &
> ~DWC_XDCI_GUSB2PHYCFG_ULPI_AUTO_RESUME_MASK)
> > +    );
> > +
> > +  DEBUG ((DEBUG_INFO, "Default value of xDCI GUSB2PHYCFG and
> GUSB3PIPECTL: %x, %x\n",
> > +          UsbRegRead (BaseAddr, DWC_XDCI_GUSB2PHYCFG_REG (0)),
> > +          UsbRegRead (BaseAddr, DWC_XDCI_GUSB3PIPECTL_REG (0))));
> > +  //
> > +  // Only one RxFIFO
> > +  //
> > +  DEBUG ((DEBUG_INFO, "Default value of DWC_XDCI_GRXFIFOSIZ: %x\n",
> > +          UsbRegRead (BaseAddr, DWC_XDCI_GRXFIFOSIZ_REG (0))));
> > +
> > +  for (i = 0; i < DWC_XDCI_MAX_ENDPOINTS; i++) {
> > +    DEBUG ((DEBUG_INFO, "Default value of xDCI DWC_XDCI_GTXFIFOSIZ
> %d: %x\n",
> > +            i, UsbRegRead (BaseAddr, DWC_XDCI_GTXFIFOSIZ_REG (i))));
> > +  }
> > +
> > +  //
> > +  // TODO: Need to check if TxFIFO should start where RxFIFO ends
> > +  // or default is correct i.e. TxFIFO starts at 0 just like RxFIFO
> > +  //
> > +
> > +  //
> > +  // Allocate and Initialize Event Buffers
> > +  //
> > +  LocalCoreHandle->MaxDevIntLines = ((UsbRegRead (BaseAddr,
> DWC_XDCI_GHWPARAMS1_REG) &
> > +                                           DWC_XDCI_GHWPARAMS1_NUM_INT_MASK) >>
> > +                                           DWC_XDCI_GHWPARAMS1_NUM_INT_BIT_POS);
> > +
> > +  DEBUG ((DEBUG_INFO, "Max dev int lines: %d\n", LocalCoreHandle-
> >MaxDevIntLines));
> > +  //
> > +  // One event Buffer per interrupt line.
> > +  //  Need to align it to size of event Buffer
> > +  //  Buffer needs to be big enough. Otherwise the core
> > +  //  won't operate
> > +  //
> > +  LocalCoreHandle->AlignedEventBuffers = (DWC_XDCI_EVENT_BUFFER *)
> > +                                             ((UINT32)(UINTN)(LocalCoreHandle-
> >EventBuffers) +
> > +                                             ((sizeof (DWC_XDCI_EVENT_BUFFER) *
> DWC_XDCI_MAX_EVENTS_PER_BUFFER) -
> > +                                             (((UINT32)(UINTN)(LocalCoreHandle-
> >EventBuffers)) %
> > +                                             (sizeof (DWC_XDCI_EVENT_BUFFER) *
> DWC_XDCI_MAX_EVENTS_PER_BUFFER))));
> > +
> > +  for (i = 0; i < LocalCoreHandle->MaxDevIntLines; i++) {
> > +    UsbRegWrite (
> > +      BaseAddr,
> > +      DWC_XDCI_GEVNTADR_REG (i),
> > +      (UINT32)(UINTN)(LocalCoreHandle->AlignedEventBuffers + i *
> sizeof(DWC_XDCI_EVENT_BUFFER) *
> DWC_XDCI_MAX_EVENTS_PER_BUFFER)
> > +      );
> > +
> > +    //
> > +    // Clear High 32bit address register, GEVNTADR register is 64-bit register
> > +    // default is 0xffffffffffffffff
> > +    //
> > +    UsbRegWrite (BaseAddr, DWC_XDCI_GEVNTADR_REG (i) + 4,
> 0x00000000);
> > +
> > +    LocalCoreHandle->CurrentEventBuffer = LocalCoreHandle-
> >AlignedEventBuffers;
> > +    //
> > +    // Write size and clear the mask
> > +    //
> > +    UsbRegWrite (
> > +      BaseAddr,
> > +      DWC_XDCI_EVNTSIZ_REG (i),
> > +      sizeof (DWC_XDCI_EVENT_BUFFER) *
> DWC_XDCI_MAX_EVENTS_PER_BUFFER
> > +      );
> > +
> > +    //
> > +    // Write 0 to the event count register as the last step
> > +    //
> > +    //  for event configuration
> > +    //
> > +    UsbRegWrite (BaseAddr, DWC_XDCI_EVNTCOUNT_REG (i), 0);
> > +
> > +    DEBUG ((DEBUG_INFO, "Value of xDCI Event Buffer %d: %x, Size: %x,
> Count: %x\n",
> > +                        i,
> > +                        UsbRegRead (BaseAddr, DWC_XDCI_GEVNTADR_REG (i)),
> > +                        UsbRegRead (BaseAddr, DWC_XDCI_EVNTSIZ_REG (i)),
> > +                        UsbRegRead (BaseAddr, DWC_XDCI_EVNTCOUNT_REG (i))));
> > +  }
> > +
> > +    //
> > +    // Program Global Control Register to disable scaledown,
> > +    // disable clock gating
> > +    //
> > +    UsbRegWrite (
> > +      BaseAddr,
> > +      DWC_XDCI_GCTL_REG,
> > +      ((UsbRegRead(BaseAddr, DWC_XDCI_GCTL_REG) &
> > +                    ~(DWC_XDCI_GCTL_SCALE_DOWN_MODE_MASK +
> DWC_XDCI_GCTL_RAMCLKSEL_MASK +
> DWC_XDCI_GCTL_DISABLE_SCRAMB_MASK)) |
> > +                    DWC_XDCI_GCTL_DISABLE_CLK_GATING_MASK |
> > +                    (DWC_XDCI_GCTL_PRT_CAP_DEVICE <<
> DWC_XDCI_GCTL_PRT_CAP_DIR_BIT_POS)));
> > +
> > +    DEBUG ((DEBUG_INFO, "Setup value of xDCI DWC_XDCI_GCTL_REG:
> 0x%x\n", UsbRegRead (BaseAddr, DWC_XDCI_GCTL_REG)));
> > +
> > +  //
> > +  // TODO: Program desired Speed and set LPM capable
> > +  // We will do this when SuperSpeed works. For now,
> > +  // force into High-Speed mode to aVOID anyone trying this
> > +  // on Super Speed port
> > +  //
> > +#ifdef SUPPORT_SUPER_SPEED
> > +  UsbRegWrite (
> > +    BaseAddr,
> > +    DWC_XDCI_DCFG_REG,
> > +    (UsbRegRead (BaseAddr, DWC_XDCI_DCFG_REG) &
> ~DWC_XDCI_DCFG_DESIRED_DEV_SPEED_MASK) | LocalCoreHandle-
> >DesiredSpeed
> > +    );
> > +#else
> > +  UsbRegWrite (
> > +    BaseAddr,
> > +    DWC_XDCI_DCFG_REG,
> > +    (UsbRegRead (BaseAddr, DWC_XDCI_DCFG_REG) &
> ~DWC_XDCI_DCFG_DESIRED_DEV_SPEED_MASK) |
> DWC_XDCI_DCFG_DESIRED_HS_SPEED
> > +    );
> > +#endif
> > +
> > +  DEBUG ((DEBUG_INFO, "Setup value of xDCI DWC_XDCI_DCFG_REG:
> 0x%x\n", UsbRegRead (BaseAddr, DWC_XDCI_DCFG_REG)));
> > +  DEBUG ((DEBUG_INFO, "Setup value of xDCI DWC_XDCI_DSTS_REG:
> 0x%x\n", UsbRegRead (BaseAddr, DWC_XDCI_DSTS_REG)));
> > +
> > +  //
> > +  // Enable Device Interrupt Events
> > +  //
> > +  UsbRegWrite (
> > +    BaseAddr,
> > +    DWC_XDCI_DEVTEN_REG,
> > +    DWC_XDCI_DEVTEN_DEVICE_INTS
> > +    );
> > +  //
> > +  // Program the desired role
> > +  //
> > +  UsbRegWrite (
> > +    BaseAddr,
> > +    DWC_XDCI_GCTL_REG,
> > +    (UsbRegRead (BaseAddr, DWC_XDCI_GCTL_REG) &
> ~DWC_XDCI_GCTL_PRT_CAP_DIR_MASK) | (LocalCoreHandle->Role <<
> DWC_XDCI_GCTL_PRT_CAP_DIR_BIT_POS)
> > +    );
> > +  //
> > +  // Clear USB2 suspend for start new config command
> > +  //
> > +  UsbRegWrite (
> > +    BaseAddr,
> > +    DWC_XDCI_GUSB2PHYCFG_REG (0),
> > +    (UsbRegRead (BaseAddr, DWC_XDCI_GUSB2PHYCFG_REG(0)) &
> ~DWC_XDCI_GUSB2PHYCFG_SUSPEND_PHY_MASK)
> > +    );
> > +
> > +  //
> > +  // Clear USB3 suspend for start new config command
> > +  //
> > +  UsbRegWrite (
> > +    BaseAddr,
> > +    DWC_XDCI_GUSB3PIPECTL_REG (0),
> > +    (UsbRegRead (BaseAddr, DWC_XDCI_GUSB3PIPECTL_REG(0)) &
> ~DWC_XDCI_GUSB3PIPECTL_SUSPEND_PHY_MASK)
> > +    );
> > +
> > +  //
> > +  // Issue DEPSTARTCFG command for EP0
> > +  //
> > +  status = DwcXdciCoreInitEpCmdParams (
> > +             LocalCoreHandle,
> > +             &LocalCoreHandle->EpHandles[0].EpInfo,
> > +             DWC_XDCI_PARAM0_SET_EP_CFG_ACTN_NONE,
> > +             EPCMD_START_NEW_CONFIG,
> > +             &EpCmdParams
> > +             );
> > +
> > +  if (status) {
> > +    DEBUG ((DEBUG_INFO, "DwcXdciCoreInit: Failed to init params for
> START_NEW_CONFIG EP command on xDCI\n"));
> > +    return status;
> > +  }
> > +
> > +  //
> > +  // Issue the command
> > +  //
> > +  status = DwcXdciCoreIssueEpCmd (
> > +             LocalCoreHandle,
> > +             0,
> > +             EPCMD_START_NEW_CONFIG,
> > +             &EpCmdParams
> > +             );
> > +
> > +  if (status) {
> > +    DEBUG ((DEBUG_INFO, "DwcXdciCoreInit: Failed to issue
> START_NEW_CONFIG EP command on xDCI\n"));
> > +    return status;
> > +  }
> > +
> > +  //
> > +  // Issue DEPCFG command for EP0
> > +  //
> > +  status = DwcXdciCoreInitEpCmdParams (
> > +             LocalCoreHandle,
> > +             &LocalCoreHandle->EpHandles[0].EpInfo,
> > +             DWC_XDCI_PARAM0_SET_EP_CFG_ACTN_INIT_STATE,
> > +             EPCMD_SET_EP_CONFIG,
> > +             &EpCmdParams
> > +             );
> > +
> > +  if (status) {
> > +    DEBUG ((DEBUG_INFO, "DwcXdciCoreInit: Failed to init params for
> SET_EP_CONFIG command on xDCI for EP0\n"));
> > +    return status;
> > +  }
> > +
> > +  //
> > +  // Issue the command
> > +  //
> > +  status = DwcXdciCoreIssueEpCmd (
> > +             LocalCoreHandle,
> > +             0,
> > +             EPCMD_SET_EP_CONFIG,
> > +             &EpCmdParams);
> > +
> > +  if (status) {
> > +    DEBUG ((DEBUG_INFO, "DwcXdciCoreInit: Failed to issue
> SET_EP_CONFIG command on xDCI for EP0\n"));
> > +    return status;
> > +  }
> > +
> > +  //
> > +  // Issue DEPCFG command for EP1
> > +  //
> > +  status = DwcXdciCoreInitEpCmdParams (
> > +             LocalCoreHandle,
> > +             &LocalCoreHandle->EpHandles[1].EpInfo,
> > +             DWC_XDCI_PARAM0_SET_EP_CFG_ACTN_INIT_STATE,
> > +             EPCMD_SET_EP_CONFIG,
> > +             &EpCmdParams
> > +             );
> > +
> > +  if (status) {
> > +    DEBUG ((DEBUG_INFO, "DwcXdciCoreInit: Failed to init params for
> SET_EP_CONFIG command on xDCI for EP1\n"));
> > +    return status;
> > +  }
> > +
> > +  //
> > +  // Issue the command
> > +  //
> > +  status = DwcXdciCoreIssueEpCmd (
> > +             LocalCoreHandle,
> > +             1,
> > +             EPCMD_SET_EP_CONFIG,
> > +             &EpCmdParams
> > +             );
> > +
> > +  if (status) {
> > +    DEBUG ((DEBUG_INFO, "DwcXdciCoreInit: Failed to issue
> SET_EP_CONFIG command on xDCI for EP1\n"));
> > +    return status;
> > +  }
> > +
> > +  //
> > +  // Issue DEPXFERCFG command for EP0
> > +  //
> > +  status = DwcXdciCoreInitEpCmdParams (
> > +             LocalCoreHandle,
> > +             &LocalCoreHandle->EpHandles[0].EpInfo,
> > +             DWC_XDCI_PARAM0_SET_EP_CFG_ACTN_NONE,
> > +             EPCMD_SET_EP_XFER_RES_CONFIG,
> > +             &EpCmdParams
> > +             );
> > +
> > +  if (status) {
> > +    DEBUG ((DEBUG_INFO, "DwcXdciCoreInit: Failed to init params for
> EPCMD_SET_EP_XFER_RES_CONFIG command on xDCI for EP0\n"));
> > +    return status;
> > +  }
> > +
> > +  //
> > +  // Issue the command
> > +  //
> > +  status = DwcXdciCoreIssueEpCmd (
> > +             LocalCoreHandle,
> > +             0,
> > +             EPCMD_SET_EP_XFER_RES_CONFIG,
> > +             &EpCmdParams
> > +             );
> > +
> > +  if (status) {
> > +    DEBUG ((DEBUG_INFO, "DwcXdciCoreInit: Failed to issue
> EPCMD_SET_EP_XFER_RES_CONFIG command on xDCI for EP0\n"));
> > +    return status;
> > +  }
> > +
> > +  //
> > +  // Issue DEPXFERCFG command for EP1
> > +  //
> > +  status = DwcXdciCoreInitEpCmdParams (
> > +             LocalCoreHandle,
> > +             &LocalCoreHandle->EpHandles[1].EpInfo,
> > +             DWC_XDCI_PARAM0_SET_EP_CFG_ACTN_NONE,
> > +             EPCMD_SET_EP_XFER_RES_CONFIG,
> > +             &EpCmdParams
> > +             );
> > +
> > +  if (status) {
> > +    DEBUG ((DEBUG_INFO, "DwcXdciCoreInit: Failed to init params for
> EPCMD_SET_EP_XFER_RES_CONFIG command on xDCI for EP1\n"));
> > +    return status;
> > +  }
> > +
> > +  //
> > +  // Issue the command
> > +  //
> > +  status = DwcXdciCoreIssueEpCmd (
> > +             LocalCoreHandle,
> > +             1,
> > +             EPCMD_SET_EP_XFER_RES_CONFIG,
> > +             &EpCmdParams
> > +             );
> > +
> > +  if (status) {
> > +    DEBUG ((DEBUG_INFO, "DwcXdciCoreInit: Failed to issue
> EPCMD_SET_EP_XFER_RES_CONFIG command on xDCI for EP1\n"));
> > +    return status;
> > +  }
> > +
> > +  //
> > +  // Prepare a Buffer for SETUP packet
> > +  //
> > +  LocalCoreHandle->Trbs = (DWC_XDCI_TRB *)((UINTN)
> > +                            LocalCoreHandle->UnalignedTrbs +
> > +                            (UINTN)(DWC_XDCI_TRB_BYTE_ALIGNMENT -
> > +                            ((UINT32)(UINTN)LocalCoreHandle->UnalignedTrbs %
> > +                            DWC_XDCI_TRB_BYTE_ALIGNMENT)));
> > +
> > +  DEBUG ((DEBUG_INFO, "(DwcXdciCoreInit)@@@@@@@@@
> unalignedTrbs address is 0x%x\n", LocalCoreHandle->UnalignedTrbs));
> > +  DEBUG ((DEBUG_INFO, "(DwcXdciCoreInit)@@@@@@@@@ TRB
> address is 0x%x\n", LocalCoreHandle->Trbs));
> > +  //
> > +  // Allocate Setup Buffer that is 8-byte aligned
> > +  //
> > +  LocalCoreHandle->AlignedSetupBuffer = LocalCoreHandle-
> >DefaultSetupBuffer +
> > +                                            (DWC_XDCI_SETUP_BUFF_SIZE -
> > +                                            ((UINT32)(UINTN)(LocalCoreHandle-
> >DefaultSetupBuffer) % DWC_XDCI_SETUP_BUFF_SIZE));
> > +
> > +  //
> > +  // Aligned Buffer for status phase
> > +  //
> > +  LocalCoreHandle->AlignedMiscBuffer = LocalCoreHandle->MiscBuffer +
> > +                                           (DWC_XDCI_SETUP_BUFF_SIZE -
> > +                                           ((UINT32)(UINTN)(LocalCoreHandle-
> >AlignedMiscBuffer) % DWC_XDCI_SETUP_BUFF_SIZE));
> > +
> > +
> > +  //
> > +  // Enable Physical Endpoints 0
> > +  //
> > +  UsbRegWrite (
> > +    BaseAddr,
> > +    DWC_XDCI_EP_DALEPENA_REG,
> > +    UsbRegRead (BaseAddr, DWC_XDCI_EP_DALEPENA_REG) | (1 << 0)
> > +    );
> > +  //
> > +  // Enable Physical Endpoints 1
> > +  //
> > +  UsbRegWrite (
> > +    BaseAddr,
> > +    DWC_XDCI_EP_DALEPENA_REG,
> > +    UsbRegRead (BaseAddr, DWC_XDCI_EP_DALEPENA_REG) | (1 << 1)
> > +    );
> > +
> > +  DEBUG ((DEBUG_INFO, "Default value of xDCI DWC_XDCI_DEVTEN_REG:
> 0x%x\n", UsbRegRead (BaseAddr, DWC_XDCI_DEVTEN_REG)));
> > +  return status;
> > +}
> > +
> > +
> > +/**
> > +  Interface:
> > +  This function is used to de-initialize the xDCI core
> > +  @CoreHandle: xDCI controller handle
> > +  @flags: Special flags for de-initializing the core in
> > +  particular way
> > +
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +DwcXdciCoreDeinit (
> > +  IN VOID      *CoreHandle,
> > +  IN UINT32    flags
> > +  )
> > +{
> > +  FreePool (CoreHandle);
> > +  return EFI_SUCCESS;
> > +}
> > +
> > +
> > +/**
> > +  Interface:
> > +  This function is used to register event callback function
> > +  @CoreHandle: xDCI controller handle
> > +  @event: Event for which callback is to be registered
> > +  @callbackFn: Callback function to invoke after event occurs
> > +
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +DwcXdciCoreRegisterCallback (
> > +  IN VOID                      *CoreHandle,
> > +  IN USB_DEVICE_EVENT_ID       Event,
> > +  IN USB_DEVICE_CALLBACK_FUNC  CallbackFunc
> > +  )
> > +{
> > +  XDCI_CORE_HANDLE  *LocalCoreHandle = (XDCI_CORE_HANDLE
> *)CoreHandle;
> > +
> > +  if (LocalCoreHandle == NULL) {
> > +    DEBUG ((DEBUG_INFO, "DwcXdciCoreRegisterCallback: INVALID
> handle\n"));
> > +    return EFI_DEVICE_ERROR;
> > +  }
> > +
> > +  DEBUG ((DEBUG_INFO, "DwcXdciCoreRegisterCallback: event is %d\n",
> Event));
> > +  switch (Event) {
> > +    case USB_DEVICE_DISCONNECT_EVENT:
> > +      LocalCoreHandle->EventCallbacks.DevDisconnectCallback =
> CallbackFunc;
> > +      break;
> > +
> > +    case USB_DEVICE_RESET_EVENT:
> > +      LocalCoreHandle->EventCallbacks.DevBusResetCallback =
> CallbackFunc;
> > +      break;
> > +
> > +    case USB_DEVICE_CONNECTION_DONE:
> > +      LocalCoreHandle->EventCallbacks.DevResetDoneCallback =
> CallbackFunc;
> > +      break;
> > +
> > +    case USB_DEVICE_STATE_CHANGE_EVENT:
> > +      LocalCoreHandle->EventCallbacks.DevLinkStateCallback =
> CallbackFunc;
> > +      break;
> > +
> > +    case USB_DEVICE_WAKEUP_EVENT:
> > +      LocalCoreHandle->EventCallbacks.DevWakeupCallback = CallbackFunc;
> > +      break;
> > +
> > +    case USB_DEVICE_HIBERNATION_REQ_EVENT:
> > +      LocalCoreHandle->EventCallbacks.DevHibernationCallback =
> CallbackFunc;
> > +      break;
> > +
> > +    case USB_DEVICE_SOF_EVENT:
> > +      LocalCoreHandle->EventCallbacks.DevSofCallback = CallbackFunc;
> > +      break;
> > +
> > +    case USB_DEVICE_ERRATIC_ERR_EVENT:
> > +      LocalCoreHandle->EventCallbacks.DevErraticErrCallback =
> CallbackFunc;
> > +      break;
> > +
> > +    case USB_DEVICE_CMD_CMPLT_EVENT:
> > +      LocalCoreHandle->EventCallbacks.DevCmdCmpltCallback =
> CallbackFunc;
> > +      break;
> > +
> > +    case USB_DEVICE_BUFF_OVERFLOW_EVENT:
> > +      LocalCoreHandle->EventCallbacks.DevBuffOvflwCallback =
> CallbackFunc;
> > +      break;
> > +
> > +    case USB_DEVICE_TEST_LMP_RX_EVENT:
> > +      LocalCoreHandle->EventCallbacks.DevTestLmpRxCallback =
> CallbackFunc;
> > +      break;
> > +
> > +    case USB_DEVICE_SETUP_PKT_RECEIVED:
> > +      LocalCoreHandle->EventCallbacks.DevSetupPktReceivedCallback =
> CallbackFunc;
> > +      break;
> > +
> > +    case USB_DEVICE_XFER_NRDY:
> > +      LocalCoreHandle->EventCallbacks.DevXferNrdyCallback =
> CallbackFunc;
> > +      break;
> > +
> > +    case USB_DEVICE_XFER_DONE:
> > +      LocalCoreHandle->EventCallbacks.DevXferDoneCallback =
> CallbackFunc;
> > +      break;
> > +
> > +    default:
> > +      break;
> > +  }
> > +
> > +  return EFI_SUCCESS;
> > +}
> > +
> > +
> > +/**
> > +  Interface:
> > +  This function is used to unregister event callback function
> > +  @CoreHandle: xDCI controller handle
> > +  @event: Event for which callback function is to be unregistered
> > +
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +DwcXdciCoreUnregisterCallback (
> > +  IN VOID                   *CoreHandle,
> > +  IN USB_DEVICE_EVENT_ID    event
> > +  )
> > +{
> > +  XDCI_CORE_HANDLE  *LocalCoreHandle = (XDCI_CORE_HANDLE
> *)CoreHandle;
> > +
> > +  if (LocalCoreHandle == NULL) {
> > +    DEBUG ((DEBUG_INFO, "DwcXdciCoreUnregisterCallback: INVALID
> handle\n"));
> > +    return EFI_DEVICE_ERROR;
> > +  }
> > +
> > +  switch (event) {
> > +    case USB_DEVICE_DISCONNECT_EVENT:
> > +      LocalCoreHandle->EventCallbacks.DevDisconnectCallback = NULL;
> > +      break;
> > +
> > +    case USB_DEVICE_RESET_EVENT:
> > +      LocalCoreHandle->EventCallbacks.DevBusResetCallback = NULL;
> > +      break;
> > +
> > +    case USB_DEVICE_CONNECTION_DONE:
> > +      LocalCoreHandle->EventCallbacks.DevResetDoneCallback = NULL;
> > +      break;
> > +
> > +    case USB_DEVICE_STATE_CHANGE_EVENT:
> > +      LocalCoreHandle->EventCallbacks.DevLinkStateCallback = NULL;
> > +      break;
> > +
> > +    case USB_DEVICE_WAKEUP_EVENT:
> > +      LocalCoreHandle->EventCallbacks.DevWakeupCallback = NULL;
> > +      break;
> > +
> > +    case USB_DEVICE_HIBERNATION_REQ_EVENT:
> > +      LocalCoreHandle->EventCallbacks.DevHibernationCallback = NULL;
> > +      break;
> > +
> > +    case USB_DEVICE_SOF_EVENT:
> > +      LocalCoreHandle->EventCallbacks.DevSofCallback = NULL;
> > +      break;
> > +
> > +    case USB_DEVICE_ERRATIC_ERR_EVENT:
> > +      LocalCoreHandle->EventCallbacks.DevErraticErrCallback = NULL;
> > +      break;
> > +
> > +    case USB_DEVICE_CMD_CMPLT_EVENT:
> > +      LocalCoreHandle->EventCallbacks.DevCmdCmpltCallback = NULL;
> > +      break;
> > +
> > +    case USB_DEVICE_BUFF_OVERFLOW_EVENT:
> > +      LocalCoreHandle->EventCallbacks.DevBuffOvflwCallback = NULL;
> > +      break;
> > +
> > +    case USB_DEVICE_TEST_LMP_RX_EVENT:
> > +      LocalCoreHandle->EventCallbacks.DevTestLmpRxCallback = NULL;
> > +      break;
> > +
> > +    case USB_DEVICE_SETUP_PKT_RECEIVED:
> > +      LocalCoreHandle->EventCallbacks.DevSetupPktReceivedCallback =
> NULL;
> > +      break;
> > +
> > +    case USB_DEVICE_XFER_NRDY:
> > +      LocalCoreHandle->EventCallbacks.DevXferNrdyCallback = NULL;
> > +      break;
> > +
> > +    case USB_DEVICE_XFER_DONE:
> > +      LocalCoreHandle->EventCallbacks.DevXferDoneCallback = NULL;
> > +      break;
> > +
> > +    default:
> > +      break;
> > +  }
> > +
> > +  return EFI_SUCCESS;
> > +}
> > +
> > +
> > +/**
> > +  Interface:
> > +  This function is used as an interrupt service routine
> > +  @CoreHandle: xDCI controller handle
> > +
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +DwcXdciCoreIsrRoutine (
> > +  IN VOID     *CoreHandle
> > +  )
> > +{
> > +  XDCI_CORE_HANDLE    *LocalCoreHandle = (XDCI_CORE_HANDLE
> *)CoreHandle;
> > +  UINT32              BaseAddr;
> > +  UINT32              eventCount;
> > +  UINT32              ProcessedEventCount;
> > +  UINT32              i;
> > +
> > +  if (CoreHandle == NULL) {
> > +    DEBUG ((DEBUG_INFO, "DwcXdciCoreIsrRoutine: INVALID handle\n"));
> > +    return EFI_DEVICE_ERROR;
> > +  }
> > +
> > +  if (LocalCoreHandle->InterrupProcessing == TRUE) {
> > +    DEBUG ((DEBUG_INFO, "interrupProcessing.........\n"));
> > +    return EFI_SUCCESS;
> > +  }
> > +
> > +  BaseAddr = LocalCoreHandle->BaseAddress;
> > +  //
> > +  // Event Buffer corresponding to each interrupt line needs
> > +  // to be Processed
> > +  //
> > +  LocalCoreHandle->InterrupProcessing = TRUE;
> > +  for (i = 0; i < LocalCoreHandle->MaxDevIntLines; i++) {
> > +    //
> > +    // Get the number of events HW has written for this
> > +    //  interrupt line
> > +    //
> > +    eventCount = UsbRegRead (BaseAddr, DWC_XDCI_EVNTCOUNT_REG
> (i));
> > +    eventCount &= DWC_XDCI_EVNTCOUNT_MASK;
> > +    ProcessedEventCount = 0;
> > +
> > +    //
> > +    // Process interrupt line Buffer only if count is non-zero
> > +    //
> > +    if (eventCount) {
> > +      //
> > +      // Process events in this Buffer
> > +      //
> > +      DwcXdciProcessInterruptLineEvents (LocalCoreHandle, eventCount,
> &ProcessedEventCount);
> > +      //
> > +      // Write back the Processed number of events so HW decrements it
> from current
> > +      // event count
> > +      //
> > +      UsbRegWrite (BaseAddr, DWC_XDCI_EVNTCOUNT_REG (i),
> ProcessedEventCount);
> > +    }
> > +  }
> > +  LocalCoreHandle->InterrupProcessing = FALSE;
> > +  return EFI_SUCCESS;
> > +}
> > +
> > +
> > +/**
> > +  Interface:
> > +  This function is used as an interrupt service routine and it processes only
> one event at a time.
> > +  @CoreHandle: xDCI controller handle
> > +
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +DwcXdciCoreIsrRoutineTimerBased (
> > +  IN VOID     *CoreHandle
> > +  )
> > +{
> > +  XDCI_CORE_HANDLE    *LocalCoreHandle = (XDCI_CORE_HANDLE
> *)CoreHandle;
> > +  UINT32              BaseAddr;
> > +  UINT32              eventCount;
> > +  UINT32              ProcessedEventCount;
> > +  UINT32              currentEventAddr;
> > +  UINT32              ProcessedEventSize = 0;
> > +
> > +  if (CoreHandle == NULL) {
> > +    DEBUG ((DEBUG_INFO, "DwcXdciCoreIsrRoutineTimerBased: INVALID
> handle\n"));
> > +    return EFI_DEVICE_ERROR;
> > +  }
> > +
> > +  if (LocalCoreHandle->CurrentEventBuffer == NULL) {
> > +    DEBUG ((DEBUG_INFO, "ERROR: DwcXdciCoreIsrRoutineTimerBased:
> INVALID event Buffer\n"));
> > +    return EFI_INVALID_PARAMETER;
> > +  }
> > +
> > +  BaseAddr = LocalCoreHandle->BaseAddress;
> > +
> > +  eventCount = UsbRegRead (BaseAddr, DWC_XDCI_EVNTCOUNT_REG (0))
> & DWC_XDCI_EVNTCOUNT_MASK;
> > +
> > +  if (LocalCoreHandle->InterrupProcessing == TRUE) {
> > +    DEBUG ((DEBUG_INFO, "interrupProcessing.........\n"));
> > +    return EFI_SUCCESS;
> > +  }
> > +
> > +  LocalCoreHandle->InterrupProcessing = TRUE;
> > +
> > +  ProcessedEventCount = 0;
> > +  currentEventAddr = (UINT32)(UINTN)(LocalCoreHandle-
> >CurrentEventBuffer);
> > +
> > +  if (LocalCoreHandle->CurrentEventBuffer->Event &
> DWC_XDCI_EVENT_DEV_MASK) {
> > +    DwcXdciProcessDeviceEvent (
> > +      LocalCoreHandle,
> > +      LocalCoreHandle->CurrentEventBuffer,
> > +      &ProcessedEventSize
> > +      );
> > +  } else {
> > +    DwcXdciProcessEpEvent (
> > +      LocalCoreHandle,
> > +      LocalCoreHandle->CurrentEventBuffer,
> > +      &ProcessedEventSize);
> > +  }
> > +
> > +  eventCount -= ProcessedEventSize;
> > +  ProcessedEventCount += ProcessedEventSize;
> > +  if ((currentEventAddr + ProcessedEventSize) >=
> > +      ((UINT32)(UINTN)(LocalCoreHandle->AlignedEventBuffers) +
> (sizeof(DWC_XDCI_EVENT_BUFFER) *
> DWC_XDCI_MAX_EVENTS_PER_BUFFER))
> > +     ) {
> > +    currentEventAddr = (UINT32)(UINTN)(LocalCoreHandle-
> >AlignedEventBuffers);
> > +    DEBUG ((DEBUG_INFO, "DwcXdciProcessInterruptLineEvents: Event
> Buffer bound reached\n"));
> > +  } else {
> > +    currentEventAddr += ProcessedEventSize;
> > +  }
> > +
> > +  LocalCoreHandle->CurrentEventBuffer = (DWC_XDCI_EVENT_BUFFER
> *)(UINTN)currentEventAddr;
> > +  UsbRegWrite (BaseAddr, DWC_XDCI_EVNTCOUNT_REG (0),
> ProcessedEventCount);
> > +  LocalCoreHandle->InterrupProcessing = FALSE;
> > +
> > +  return EFI_SUCCESS;
> > +}
> > +
> > +
> > +/**
> > +  Interface:
> > +  This function is used to enable xDCI to connect to the host
> > +  @CoreHandle: xDCI controller handle
> > +
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +DwcXdciCoreConnect (
> > +  IN VOID     *CoreHandle
> > +  )
> > +{
> > +  XDCI_CORE_HANDLE    *LocalCoreHandle = (XDCI_CORE_HANDLE
> *)CoreHandle;
> > +  UINT32              MaxDelayIter = DWC_XDCI_MAX_DELAY_ITERATIONS;
> > +  UINT32              BaseAddr;
> > +
> > +  if (CoreHandle == NULL) {
> > +    DEBUG ((DEBUG_INFO, "DwcXdciCoreConnect: INVALID handle\n"));
> > +    return EFI_DEVICE_ERROR;
> > +  }
> > +
> > +  BaseAddr = LocalCoreHandle->BaseAddress;
> > +
> > +  //
> > +  // Clear KeepConnect bit so we can allow disconnect and re-connect
> > +  // Also issue No action on state change to aVOID any link change
> > +  //
> > +  UsbRegWrite (
> > +    BaseAddr,
> > +    DWC_XDCI_DCTL_REG,
> > +    (UsbRegRead(BaseAddr, DWC_XDCI_DCTL_REG) &
> ~DWC_XDCI_DCTL_KEEP_CONNECT_MASK) &
> ~DWC_XDCI_DCTL_STATE_CHANGE_REQ_MASK
> > +    );
> > +
> > +  //
> > +  // Set Run bit to connect to the host
> > +  //
> > +  UsbRegWrite (
> > +    BaseAddr,
> > +    DWC_XDCI_DCTL_REG,
> > +    UsbRegRead (BaseAddr, DWC_XDCI_DCTL_REG) |
> DWC_XDCI_DCTL_RUN_STOP_MASK
> > +    );
> > +
> > +  //
> > +  // Wait until core starts running
> > +  //
> > +  do {
> > +    if (!(UsbRegRead (BaseAddr, DWC_XDCI_DSTS_REG) &
> DWC_XDCI_DSTS_DEV_CTRL_HALTED_MASK)) {
> > +      break;
> > +    } else {
> > +      gBS->Stall (DWC_XDCI_MAX_DELAY_ITERATIONS);
> > +    }
> > +  } while (--MaxDelayIter);
> > +
> > +  if (!MaxDelayIter) {
> > +    DEBUG ((DEBUG_INFO, "Failed to run the device controller\n"));
> > +    return EFI_DEVICE_ERROR;
> > +  }
> > +
> > +  return EFI_SUCCESS;
> > +}
> > +
> > +
> > +/**
> > +  Interface:
> > +  This function is used to disconnect xDCI from the host
> > +  @CoreHandle: xDCI controller handle
> > +
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +DwcXdciCoreDisconnect (
> > +  IN VOID    *CoreHandle
> > +  )
> > +{
> > +  XDCI_CORE_HANDLE  *LocalCoreHandle = (XDCI_CORE_HANDLE
> *)CoreHandle;
> > +  UINT32            MaxDelayIter = DWC_XDCI_MAX_DELAY_ITERATIONS;
> > +  UINT32            BaseAddr;
> > +  UINT32            eventCount;
> > +  UINT32            dsts;
> > +  UINT32            i;
> > +
> > +  if (CoreHandle == NULL) {
> > +    DEBUG ((DEBUG_INFO, "DwcXdciCoreDisconnect: INVALID handle\n"));
> > +    return EFI_DEVICE_ERROR;
> > +  }
> > +
> > +  BaseAddr = LocalCoreHandle->BaseAddress;
> > +
> > +  eventCount = UsbRegRead (BaseAddr, DWC_XDCI_EVNTCOUNT_REG
> (0));
> > +  eventCount &= DWC_XDCI_EVNTCOUNT_MASK;
> > +
> > +  DEBUG ((DEBUG_INFO, "DwcXdciCoreDisconnect: eventCount=%d\n",
> eventCount));
> > +  while (eventCount) {
> > +    DwcXdciCoreIsrRoutine(LocalCoreHandle);
> > +    eventCount = UsbRegRead (BaseAddr, DWC_XDCI_EVNTCOUNT_REG
> (0));
> > +    eventCount &= DWC_XDCI_EVNTCOUNT_MASK;
> > +    DEBUG ((DEBUG_INFO, "DwcXdciCoreDisconnect: eventCount=%d\n",
> eventCount));
> > +  }
> > +
> > +  //
> > +  // Issue DEPENDXFER for active transfers
> > +  //
> > +  for (i = 0; i < DWC_XDCI_MAX_ENDPOINTS; i++){
> > +    if (LocalCoreHandle->EpHandles[i].CurrentXferRscIdx){
> > +      DwcXdciEndXfer(LocalCoreHandle, i);
> > +    }
> > +  }
> > +  //
> > +  // Clear Run bit to disconnect from host
> > +  //
> > +  UsbRegWrite (
> > +    BaseAddr,
> > +    DWC_XDCI_DCTL_REG,
> > +    UsbRegRead(BaseAddr, DWC_XDCI_DCTL_REG) &
> ~DWC_XDCI_DCTL_RUN_STOP_MASK);
> > +
> > +  //
> > +  // Wait until core is halted
> > +  //
> > +  do {
> > +    dsts = UsbRegRead (BaseAddr, DWC_XDCI_DSTS_REG);
> > +    DEBUG ((DEBUG_INFO, "DwcXdciCoreDisconnect: waiting halt:
> DSTS=0x%x\n", dsts));
> > +    if ((dsts & DWC_XDCI_DSTS_DEV_CTRL_HALTED_MASK) != 0){
> > +      break;
> > +    } else {
> > +      gBS->Stall (DWC_XDCI_MAX_DELAY_ITERATIONS);
> > +    }
> > +  } while (--MaxDelayIter);
> > +
> > +  if (!MaxDelayIter) {
> > +    DEBUG ((DEBUG_INFO, "DwcXdciCoreDisconnect: Failed to halt the
> device controller\n"));
> > +    return EFI_DEVICE_ERROR;
> > +  }
> > +
> > +  return EFI_SUCCESS;
> > +}
> > +
> > +
> > +/**
> > +  Interface:
> > +  This function is used to obtain current USB bus Speed
> > +  @CoreHandle: xDCI controller handle
> > +  @Speed: Address of variable to save the Speed
> > +
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +DwcXdciCoreGetSpeed (
> > +  IN VOID         *CoreHandle,
> > +  IN USB_SPEED    *Speed
> > +  )
> > +{
> > +  XDCI_CORE_HANDLE *LocalCoreHandle = (XDCI_CORE_HANDLE
> *)CoreHandle;
> > +
> > +  if (CoreHandle == NULL) {
> > +    DEBUG ((DEBUG_INFO, "DwcXdciCoreGetSpeed: INVALID handle\n"));
> > +    return EFI_DEVICE_ERROR;
> > +  }
> > +
> > +  if (Speed == NULL) {
> > +    DEBUG ((DEBUG_INFO, "DwcXdciCoreGetSpeed: INVALID
> parameter\n"));
> > +    return EFI_INVALID_PARAMETER;
> > +  }
> > +
> > +  *Speed = UsbRegRead (LocalCoreHandle->BaseAddress,
> DWC_XDCI_DSTS_REG) & DWC_XDCI_DSTS_CONN_SPEED_MASK;
> > +
> > +  return EFI_SUCCESS;
> > +}
> > +
> > +
> > +/**
> > +  Interface:
> > +  This function is used to obtain current USB bus Speed
> > +  @CoreHandle: xDCI controller handle
> > +  @address: USB address to set (assigned by USB host)
> > +
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +DwcXdciCoreSetAddress (
> > +  IN VOID      *CoreHandle,
> > +  IN UINT32    address
> > +  )
> > +{
> > +  XDCI_CORE_HANDLE  *LocalCoreHandle = (XDCI_CORE_HANDLE
> *)CoreHandle;
> > +  UINT32            BaseAddr;
> > +
> > +  if (CoreHandle == NULL) {
> > +    DEBUG ((DEBUG_INFO, "DwcXdciCoreSetAddress: INVALID handle\n"));
> > +    return EFI_DEVICE_ERROR;
> > +  }
> > +
> > +  BaseAddr = LocalCoreHandle->BaseAddress;
> > +
> > +  DEBUG ((DEBUG_INFO, "DwcXdciCoreSetAddress is 0x%x \n", address));
> > +  //
> > +  // Program USB device address
> > +  //
> > +  UsbRegWrite (
> > +    BaseAddr,
> > +    DWC_XDCI_DCFG_REG,
> > +    (UsbRegRead(BaseAddr, DWC_XDCI_DCFG_REG) &
> ~DWC_XDCI_DCFG_DEV_ADDRESS_MASK) | (address <<
> DWC_XDCI_DCFG_DEV_ADDRESS_BIT_POS)
> > +    );
> > +
> > +  LocalCoreHandle->DevState = UsbDevStateAddress;
> > +  DEBUG ((DEBUG_INFO, "Setup value of xDCI DWC_XDCI_GCTL_REG:
> 0x%x\n", UsbRegRead (BaseAddr, DWC_XDCI_GCTL_REG)));
> > +  DEBUG ((DEBUG_INFO, "Setup value of xDCI DWC_XDCI_DEVTEN_REG:
> 0x%x\n", UsbRegRead (BaseAddr, DWC_XDCI_DEVTEN_REG)));
> > +  DEBUG ((DEBUG_INFO, "Setup value of xDCI DWC_XDCI_DCFG_REG:
> 0x%x\n", UsbRegRead (BaseAddr, DWC_XDCI_DCFG_REG)));
> > +  DEBUG ((DEBUG_INFO, "Setup value of xDCI DWC_XDCI_DSTS_REG:
> 0x%x\n", UsbRegRead (BaseAddr, DWC_XDCI_DSTS_REG)));
> > +
> > +  return EFI_SUCCESS;
> > +}
> > +
> > +
> > +/**
> > +  Interface:
> > +  This function is used to set configuration
> > +  @CoreHandle: xDCI controller handle
> > +  @ConfigNum: config num to set (assigned by USB host)
> > +
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +DwcXdciCoreSetConfig (
> > +  IN VOID      *CoreHandle,
> > +  IN UINT32    ConfigNum
> > +  )
> > +{
> > +  XDCI_CORE_HANDLE              *LocalCoreHandle = (XDCI_CORE_HANDLE
> *)CoreHandle;
> > +  DWC_XDCI_ENDPOINT_CMD_PARAMS  EpCmdParams;
> > +  EFI_STATUS                    status;
> > +
> > +  if (CoreHandle == NULL) {
> > +    DEBUG ((DEBUG_INFO, "DwcXdciCoreSetConfig: INVALID handle\n"));
> > +    return EFI_DEVICE_ERROR;
> > +  }
> > +
> > +  //
> > +  // Issue DEPSTARTCFG command on EP0 (new config for
> > +  // non-control EPs)
> > +  //
> > +  status = DwcXdciCoreInitEpCmdParams (
> > +            LocalCoreHandle,
> > +            &LocalCoreHandle->EpHandles[0].EpInfo,
> > +            DWC_XDCI_PARAM0_SET_EP_CFG_ACTN_NONE,
> > +            EPCMD_START_NEW_CONFIG,
> > +            &EpCmdParams
> > +            );
> > +
> > +  if (status) {
> > +    DEBUG ((DEBUG_INFO, "DwcXdciCoreSetConfig: Failed to init params
> for EPCMD_START_NEW_CONFIG command\n"));
> > +    return status;
> > +  }
> > +
> > +  //
> > +  // Issue the command
> > +  //
> > +  status = DwcXdciCoreIssueEpCmd (
> > +             LocalCoreHandle,
> > +             0,
> > +             (EPCMD_START_NEW_CONFIG | (2 <<
> DWC_XDCI_EPCMD_RES_IDX_BIT_POS)),
> > +             &EpCmdParams
> > +             );
> > +
> > +  if (status) {
> > +    DEBUG ((DEBUG_INFO, "DwcXdciCoreSetConfig: Failed to issue
> EPCMD_START_NEW_CONFIG command\n"));
> > +    return status;
> > +  }
> > +
> > +  return status;
> > +}
> > +
> > +
> > +/**
> > +  Interface:
> > +  This function is used to set link state
> > +  @CoreHandle: xDCI controller handle
> > +  @state: Desired link state
> > +
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +DwcXdciSetLinkState (
> > +  IN VOID                        *CoreHandle,
> > +  IN USB_DEVICE_SS_LINK_STATE    state
> > +  )
> > +{
> > +  XDCI_CORE_HANDLE  *LocalCoreHandle = (XDCI_CORE_HANDLE
> *)CoreHandle;
> > +  UINT32            BaseAddr;
> > +
> > +  if (CoreHandle == NULL) {
> > +    DEBUG ((DEBUG_INFO, "DwcXdciSetLinkState: INVALID handle\n"));
> > +    return EFI_DEVICE_ERROR;
> > +  }
> > +
> > +  BaseAddr = LocalCoreHandle->BaseAddress;
> > +
> > +  //
> > +  // Clear old mask
> > +  //
> > +  UsbRegWrite (
> > +    BaseAddr,
> > +    DWC_XDCI_DCTL_REG,
> > +    UsbRegRead (BaseAddr, DWC_XDCI_DCTL_REG) &
> ~DWC_XDCI_DCTL_STATE_CHANGE_REQ_MASK
> > +    );
> > +
> > +  //
> > +  // Request new state
> > +  //
> > +  UsbRegWrite (
> > +    BaseAddr,
> > +    DWC_XDCI_DCTL_REG,
> > +    UsbRegRead (BaseAddr, DWC_XDCI_DCTL_REG) | (state <<
> DWC_XDCI_DCTL_STATE_CHANGE_REQ_BIT_POS)
> > +    );
> > +
> > +  return EFI_SUCCESS;
> > +}
> > +
> > +
> > +/**
> > +  Interface:
> > +  This function is used to initialize endpoint
> > +  @CoreHandle: xDCI controller handle
> > +  @EpInfo: Address of structure describing properties of EP
> > +  to be initialized
> > +
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +DwcXdciInitEp (
> > +  IN VOID           *CoreHandle,
> > +  IN USB_EP_INFO    *EpInfo
> > +  )
> > +{
> > +  XDCI_CORE_HANDLE              *LocalCoreHandle = (XDCI_CORE_HANDLE
> *)CoreHandle;
> > +  DWC_XDCI_ENDPOINT_CMD_PARAMS  EpCmdParams;
> > +  EFI_STATUS                    status;
> > +  UINT32                        EpNum;
> > +
> > +  if (CoreHandle == NULL) {
> > +    DEBUG ((DEBUG_INFO, "DwcXdciInitEp: INVALID handle\n"));
> > +    return EFI_DEVICE_ERROR;
> > +  }
> > +
> > +  //
> > +  // Convert to physical endpoint
> > +  //
> > +  EpNum = DwcXdciGetPhysicalEpNum (EpInfo->EpNum, EpInfo->EpDir);
> > +
> > +  //
> > +  // Save EP properties
> > +  //
> > +  CopyMem (&(LocalCoreHandle->EpHandles[EpNum].EpInfo), EpInfo,
> sizeof (USB_EP_INFO));
> > +
> > +  //
> > +  // Init CheckFlag
> > +  //
> > +  LocalCoreHandle->EpHandles[EpNum].CheckFlag = FALSE;
> > +
> > +  //
> > +  // Init DEPCFG cmd params for EP
> > +  //
> > +  status = DwcXdciCoreInitEpCmdParams (
> > +             CoreHandle,
> > +             &LocalCoreHandle->EpHandles[EpNum].EpInfo,
> > +             DWC_XDCI_PARAM0_SET_EP_CFG_ACTN_INIT_STATE,
> > +             EPCMD_SET_EP_CONFIG,
> > +             &EpCmdParams
> > +             );
> > +
> > +  if (status) {
> > +    DEBUG ((DEBUG_INFO, "DwcXdciInitEp: Failed to init params for
> EPCMD_SET_EP_CONFIG command\n"));
> > +    return status;
> > +  }
> > +
> > +  //
> > +  // Issue the command
> > +  //
> > +  status = DwcXdciCoreIssueEpCmd (
> > +             CoreHandle,
> > +             EpNum,
> > +             EPCMD_SET_EP_CONFIG,
> > +             &EpCmdParams
> > +             );
> > +
> > +  if (status) {
> > +    DEBUG ((DEBUG_INFO, "DwcXdciInitEp: Failed to issue
> EPCMD_SET_EP_CONFIG command\n"));
> > +    return status;
> > +  }
> > +
> > +  //
> > +  // Issue a DEPXFERCFG command for endpoint
> > +  //
> > +  status = DwcXdciCoreInitEpCmdParams (
> > +             LocalCoreHandle,
> > +             &LocalCoreHandle->EpHandles[EpNum].EpInfo,
> > +             DWC_XDCI_PARAM0_SET_EP_CFG_ACTN_NONE,
> > +             EPCMD_SET_EP_XFER_RES_CONFIG,
> > +             &EpCmdParams
> > +             );
> > +
> > +  if (status) {
> > +    DEBUG ((DEBUG_INFO, "DwcXdciInitEp: Failed to init params for
> EPCMD_SET_EP_XFER_RES_CONFIG command\n"));
> > +    return status;
> > +  }
> > +
> > +  //
> > +  // Issue the command
> > +  //
> > +  status = DwcXdciCoreIssueEpCmd (
> > +             LocalCoreHandle,
> > +             EpNum,
> > +             EPCMD_SET_EP_XFER_RES_CONFIG,
> > +             &EpCmdParams
> > +             );
> > +
> > +  if (status) {
> > +    DEBUG ((DEBUG_INFO, "DwcXdciInitEp: Failed to issue
> EPCMD_SET_EP_XFER_RES_CONFIG command\n"));
> > +  }
> > +
> > +  return status;
> > +}
> > +
> > +
> > +/**
> > +  Interface:
> > +  This function is used to enable non-Ep0 endpoint
> > +  @CoreHandle: xDCI controller handle
> > +  @EpInfo: Address of structure describing properties of EP
> > +  to be enabled
> > +
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +DwcXdciEpEnable (
> > +  IN VOID           *CoreHandle,
> > +  IN USB_EP_INFO    *EpInfo
> > +  )
> > +{
> > +  XDCI_CORE_HANDLE  *LocalCoreHandle = (XDCI_CORE_HANDLE
> *)CoreHandle;
> > +  UINT32            EpNum;
> > +  UINT32            BaseAddr;
> > +
> > +  if (CoreHandle == NULL) {
> > +    DEBUG ((DEBUG_INFO, "DwcXdciEpEnable: INVALID handle\n"));
> > +    return EFI_DEVICE_ERROR;
> > +  }
> > +
> > +  BaseAddr = LocalCoreHandle->BaseAddress;
> > +
> > +  //
> > +  // Convert to physical endpoint
> > +  //
> > +  EpNum = DwcXdciGetPhysicalEpNum (EpInfo->EpNum, EpInfo->EpDir);
> > +
> > +  //
> > +  // Enable Physical Endpoint EpNum
> > +  //
> > +  UsbRegWrite (
> > +    BaseAddr,
> > +    DWC_XDCI_EP_DALEPENA_REG,
> > +    UsbRegRead (BaseAddr, DWC_XDCI_EP_DALEPENA_REG) | (1 <<
> EpNum)
> > +    );
> > +
> > +  return EFI_SUCCESS;
> > +}
> > +
> > +
> > +/**
> > +  Interface:
> > +  This function is used to disable non-Ep0 endpoint
> > +  @CoreHandle: xDCI controller handle
> > +  @EpInfo: Address of structure describing properties of EP
> > +  to be enabled
> > +
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +DwcXdciEpDisable (
> > +  IN VOID           *CoreHandle,
> > +  IN USB_EP_INFO    *EpInfo
> > +  )
> > +{
> > +  XDCI_CORE_HANDLE  *LocalCoreHandle = (XDCI_CORE_HANDLE
> *)CoreHandle;
> > +  UINT32            EpNum;
> > +  UINT32            BaseAddr;
> > +
> > +  if (CoreHandle == NULL) {
> > +    DEBUG ((DEBUG_INFO, "DwcXdciEpDisable: INVALID handle\n"));
> > +    return EFI_DEVICE_ERROR;
> > +  }
> > +
> > +  BaseAddr = LocalCoreHandle->BaseAddress;
> > +
> > +  //
> > +  // Convert to physical endpoint
> > +  //
> > +  EpNum = DwcXdciGetPhysicalEpNum (EpInfo->EpNum, EpInfo->EpDir);
> > +
> > +  //
> > +  // Disable Physical Endpoint EpNum
> > +  //
> > +  UsbRegWrite (
> > +    BaseAddr,
> > +    DWC_XDCI_EP_DALEPENA_REG,
> > +    UsbRegRead (BaseAddr, DWC_XDCI_EP_DALEPENA_REG) & ~(1 <<
> EpNum)
> > +    );
> > +
> > +  return EFI_SUCCESS;
> > +}
> > +
> > +
> > +/**
> > +  Interface:
> > +  This function is used to STALL and endpoint
> > +  @CoreHandle: xDCI controller handle
> > +  @EpInfo: Address of structure describing properties of EP
> > +  to be enabled
> > +
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +DwcXdciEpStall (
> > +  IN VOID           *CoreHandle,
> > +  IN USB_EP_INFO    *EpInfo
> > +  )
> > +{
> > +  XDCI_CORE_HANDLE              *LocalCoreHandle = (XDCI_CORE_HANDLE
> *)CoreHandle;
> > +  DWC_XDCI_ENDPOINT_CMD_PARAMS  EpCmdParams;
> > +  EFI_STATUS                    status;
> > +  UINT32                        EpNum;
> > +
> > +  if (CoreHandle == NULL) {
> > +    DEBUG ((DEBUG_INFO, "DwcXdciEpStall: INVALID handle\n"));
> > +    return EFI_DEVICE_ERROR;
> > +  }
> > +
> > +  //
> > +  // Convert to physical endpoint
> > +  //
> > +  EpNum = DwcXdciGetPhysicalEpNum (EpInfo->EpNum, EpInfo->EpDir);
> > +
> > +  //
> > +  // Set Ep State Info
> > +  //
> > +  if (LocalCoreHandle->EpHandles[EpNum].State !=
> USB_EP_STATE_STALLED) {
> > +    LocalCoreHandle->EpHandles[EpNum].OrgState = LocalCoreHandle-
> >EpHandles[EpNum].State;
> > +    LocalCoreHandle->EpHandles[EpNum].State = USB_EP_STATE_STALLED;
> > +  }
> > +  //
> > +  // Issue a DWC_XDCI_EPCMD_SET_STALL for EP
> > +  // Reset params
> > +  //
> > +  EpCmdParams.Param0 = EpCmdParams.Param1 =
> EpCmdParams.Param2 = 0;
> > +
> > + //
> > + // Issue the command
> > + //
> > + status = DwcXdciCoreIssueEpCmd (
> > +            LocalCoreHandle,
> > +            EpNum,
> > +            DWC_XDCI_EPCMD_SET_STALL,
> > +            &EpCmdParams
> > +            );
> > +
> > + if (status) {
> > +   DEBUG ((DEBUG_INFO, "DwcXdciEpStall: Failed to issue EP stall
> command\n"));
> > + }
> > +
> > + return status;
> > +}
> > +
> > +
> > +/**
> > +  Interface:
> > +  This function is used to clear endpoint STALL
> > +  @CoreHandle: xDCI controller handle
> > +  @EpInfo: Address of structure describing properties of EP
> > +  to be enabled
> > +
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +DwcXdciEpClearStall (
> > +  IN VOID           *CoreHandle,
> > +  IN USB_EP_INFO    *EpInfo
> > +  )
> > +{
> > +  XDCI_CORE_HANDLE              *LocalCoreHandle = (XDCI_CORE_HANDLE
> *)CoreHandle;
> > +  DWC_XDCI_ENDPOINT_CMD_PARAMS  EpCmdParams;
> > +  EFI_STATUS                    status;
> > +  UINT32                        EpNum;
> > +
> > +  if (CoreHandle == NULL) {
> > +    DEBUG ((DEBUG_INFO, "DwcXdciEpClearStall: INVALID handle\n"));
> > +    return EFI_DEVICE_ERROR;
> > +  }
> > +
> > +  //
> > +  // Convert to physical endpoint
> > +  //
> > +  EpNum = DwcXdciGetPhysicalEpNum (EpInfo->EpNum, EpInfo->EpDir);
> > +
> > +  //
> > +  // Set Ep State Info
> > +  //
> > +  LocalCoreHandle->EpHandles[EpNum].State = LocalCoreHandle-
> >EpHandles[EpNum].OrgState;
> > +
> > +  //
> > +  // Issue a DWC_XDCI_EPCMD_CLEAR_STALL for EP
> > +  // Reset params
> > +  //
> > +  EpCmdParams.Param0 = EpCmdParams.Param1 =
> EpCmdParams.Param2 = 0;
> > +
> > +  //
> > +  // Issue the command
> > +  //
> > + status = DwcXdciCoreIssueEpCmd (
> > +            LocalCoreHandle,
> > +            EpNum,
> > +            DWC_XDCI_EPCMD_CLEAR_STALL,
> > +            &EpCmdParams
> > +            );
> > +
> > + if (status) {
> > +   DEBUG ((DEBUG_INFO, "DwcXdciEpStall: Failed to issue EP clea stall
> command\n"));
> > + }
> > +
> > + return status;
> > +}
> > +
> > +
> > +/**
> > +  Interface:
> > +  This function is used to set endpoint in NOT READY state
> > +  @CoreHandle: xDCI controller handle
> > +  @EpInfo: Address of structure describing properties of EP
> > +  to be enabled
> > +
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +DwcXdciEpSetNrdy (
> > +  IN VOID           *CoreHandle,
> > +  IN USB_EP_INFO    *EpInfo
> > +  )
> > +{
> > +  XDCI_CORE_HANDLE  *LocalCoreHandle = (XDCI_CORE_HANDLE
> *)CoreHandle;
> > +  UINT32            EpNum;
> > +  UINT32            BaseAddr;
> > +  UINT32            MaxDelayIter = DWC_XDCI_MAX_DELAY_ITERATIONS;
> > +
> > +  if (CoreHandle == NULL) {
> > +    DEBUG ((DEBUG_INFO, "DwcXdciEpSetNrdy: INVALID handle\n"));
> > +    return EFI_DEVICE_ERROR;
> > +  }
> > +
> > +  BaseAddr = LocalCoreHandle->BaseAddress;
> > +
> > +  //
> > +  // Convert to physical endpoint
> > +  //
> > +  EpNum = DwcXdciGetPhysicalEpNum (EpInfo->EpNum, EpInfo->EpDir);
> > +
> > +  //
> > +  // Program the EP number in command's param reg
> > +  //
> > +  UsbRegWrite (BaseAddr, DWC_XDCI_DGCMD_PARAM_REG, EpNum);
> > +
> > +  //
> > +  // Issue EP not ready generic device command
> > +  //
> > +  UsbRegWrite (
> > +    BaseAddr,
> > +    DWC_XDCI_DGCMD_REG,
> > +    (UsbRegRead (BaseAddr, DWC_XDCI_DGCMD_REG) |
> DWC_XDCI_DGCMD_CMD_SET_EP_NRDY)
> > +    );
> > +
> > +  //
> > +  // Activate the command
> > +  //
> > +  UsbRegWrite (
> > +    BaseAddr,
> > +    DWC_XDCI_DGCMD_REG,
> > +    (UsbRegRead (BaseAddr, DWC_XDCI_DGCMD_REG) |
> DWC_XDCI_DGCMD_CMD_ACTIVE_MASK)
> > +    );
> > +
> > +  //
> > +  // Wait until command completes
> > +  //
> > +  do {
> > +    if (!(UsbRegRead (BaseAddr, DWC_XDCI_DGCMD_REG) &
> DWC_XDCI_DGCMD_CMD_ACTIVE_MASK))
> > +      break;
> > +    else
> > +      gBS->Stall (DWC_XDCI_MAX_DELAY_ITERATIONS);
> > +  } while (--MaxDelayIter);
> > +
> > +  if (!MaxDelayIter) {
> > +    DEBUG ((DEBUG_INFO, "Failed to issue Command\n"));
> > +    return EFI_DEVICE_ERROR;
> > +  }
> > +
> > +  return EFI_SUCCESS;
> > +}
> > +
> > +
> > +/**
> > +  Interface:
> > +  This function is used to queue receive SETUP packet request
> > +  @CoreHandle: xDCI controller handle
> > +  @Buffer: Address of Buffer to receive SETUP packet
> > +
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +DwcXdciEp0ReceiveSetupPkt (
> > +  IN VOID     *CoreHandle,
> > +  IN UINT8    *Buffer
> > +  )
> > +{
> > +  XDCI_CORE_HANDLE                *LocalCoreHandle = (XDCI_CORE_HANDLE
> *)CoreHandle;
> > +  DWC_XDCI_ENDPOINT_CMD_PARAMS    EpCmdParams;
> > +  EFI_STATUS                      Status = EFI_DEVICE_ERROR;
> > +  DWC_XDCI_TRB                    *Trb;
> > +
> > +  if (CoreHandle == NULL) {
> > +    DEBUG ((DEBUG_INFO, "DwcXdciEp0ReceiveSetupPkt: INVALID
> handle\n"));
> > +    return EFI_DEVICE_ERROR;
> > +  }
> > +
> > +  LocalCoreHandle->EpHandles[0].EpInfo.EpNum = 0;
> > +  LocalCoreHandle->EpHandles[0].EpInfo.EpDir = 0;
> > +  LocalCoreHandle->EpHandles[0].State = USB_EP_STATE_SETUP;
> > +  Trb = LocalCoreHandle->Trbs;
> > +  DEBUG ((DEBUG_INFO, "(DwcXdciEp0ReceiveSetupPkt)\n"));
> > +
> > +  Status = DwcXdciCoreInitTrb (
> > +             LocalCoreHandle,
> > +             Trb,
> > +             TRBCTL_SETUP,
> > +             Buffer,
> > +             8
> > +             );
> > +
> > +  if (Status) {
> > +    DEBUG ((DEBUG_INFO, "DwcXdciEp0ReceiveSetupPkt: Init TRB Failed
> \n"));
> > +    return Status;
> > +  }
> > +
> > +  //
> > +  // Issue a DEPSTRTXFER for EP0
> > +  // Reset params
> > +  //
> > +  EpCmdParams.Param0 = EpCmdParams.Param1 =
> EpCmdParams.Param2 = 0;
> > +
> > +  //
> > +  // Init the lower re-bits for TRB address
> > +  //
> > +  EpCmdParams.Param1 = (UINT32)(UINTN)Trb;
> > +
> > +  //
> > +  // Issue the command
> > +  //
> > +  Status = DwcXdciCoreIssueEpCmd (
> > +             LocalCoreHandle,
> > +             0,
> > +             EPCMD_START_XFER,
> > +             &EpCmdParams
> > +             );
> > +
> > +  if (Status) {
> > +    DEBUG ((DEBUG_INFO, "\nDwcXdciEp0ReceiveSetupPkt: Failed to issue
> Start Transfer command"));
> > +  }
> > +
> > +  //
> > +  // Save new resource index for this transfer
> > +  //
> > +  LocalCoreHandle->EpHandles[0].CurrentXferRscIdx =
> ((UsbRegRead(LocalCoreHandle->BaseAddress, DWC_XDCI_EPCMD_REG(0))
> &
> > +                                                         DWC_XDCI_EPCMD_RES_IDX_MASK) >>
> DWC_XDCI_EPCMD_RES_IDX_BIT_POS
> > +                                                         );
> > +
> > +  return Status;
> > +}
> > +
> > +
> > +/**
> > +  Interface:
> > +  This function is used to queue receive status packet on EP0
> > +  @CoreHandle: xDCI controller handle
> > +
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +DwcXdciEp0ReceiveStatusPkt (
> > +  IN VOID    *CoreHandle
> > +  )
> > +{
> > +  XDCI_CORE_HANDLE                *LocalCoreHandle = (XDCI_CORE_HANDLE
> *)CoreHandle;
> > +  DWC_XDCI_TRB                    *Trb;
> > +  DWC_XDCI_TRB_CONTROL            TrbCtrl;
> > +  DWC_XDCI_ENDPOINT_CMD_PARAMS    EpCmdParams;
> > +  EFI_STATUS                      Status;
> > +  UINT32                          BaseAddr;
> > +
> > +  if (CoreHandle == NULL) {
> > +    DEBUG ((DEBUG_INFO, "DwcXdciEp0ReceiveStatusPkt: INVALID
> handle\n"));
> > +    return EFI_DEVICE_ERROR;
> > +  }
> > +
> > +  BaseAddr = LocalCoreHandle->BaseAddress;
> > +
> > +  //
> > +  // We are receiving on EP0 so physical EP is 0
> > +  //
> > +  Trb = LocalCoreHandle->Trbs;
> > +  DEBUG ((DEBUG_INFO, "(DwcXdciEp0ReceiveStatusPkt)\n"));
> > +  if (Trb->TrbCtrl & DWC_XDCI_TRB_CTRL_HWO_MASK) {
> > +    DEBUG ((DEBUG_INFO, "statusPkt still not transferred.\n"));
> > +    return EFI_SUCCESS;
> > +  }
> > +
> > +  LocalCoreHandle->EpHandles[0].EpInfo.EpNum = 0;
> > +  LocalCoreHandle->EpHandles[0].EpInfo.EpDir = 0;
> > +
> > +  //
> > +  // OUT data phase for 3-phased control transfer
> > +  //
> > +  TrbCtrl = TRBCTL_3_PHASE;
> > +
> > +  //
> > +  // Init TRB for the transfer
> > +  //
> > +  Status = DwcXdciCoreInitTrb (
> > +             LocalCoreHandle,
> > +             Trb,
> > +             TrbCtrl,
> > +             LocalCoreHandle->AlignedSetupBuffer,
> > +             0
> > +             );
> > +
> > +  if (!Status) {
> > +    //
> > +    // Issue a DEPSTRTXFER for EP0
> > +    // Reset params
> > +    //
> > +    EpCmdParams.Param0 = EpCmdParams.Param1 =
> EpCmdParams.Param2 = 0;
> > +
> > +    //
> > +    // Init the lower bits for TRB address
> > +    //
> > +    EpCmdParams.Param1 = (UINT32)(UINTN)Trb;
> > +
> > +    //
> > +    // Issue the command
> > +    //
> > +    Status = DwcXdciCoreIssueEpCmd (
> > +               LocalCoreHandle,
> > +               0,
> > +               EPCMD_START_XFER,
> > +               &EpCmdParams
> > +               );
> > +
> > +    if (Status) {
> > +      DEBUG ((DEBUG_INFO, "DwcXdciEp0ReceiveStatusPkt: Failed to issue
> Start Transfer command for EP0\n"));
> > +    }
> > +    //
> > +    // Save new resource index for this transfer
> > +    //
> > +    LocalCoreHandle->EpHandles[0].CurrentXferRscIdx =
> ((UsbRegRead(BaseAddr, DWC_XDCI_EPCMD_REG(0)) &
> DWC_XDCI_EPCMD_RES_IDX_MASK) >>
> DWC_XDCI_EPCMD_RES_IDX_BIT_POS);
> > +
> > +    //
> > +    // TODO: We are not using the EP state for control transfers
> > +    // right now simply because we're only supporting IN
> > +    // data phase. For the current use case, we don't
> > +    // need OUT data phase. We can add that later and we will
> > +    // add some of the state and SETUP packet awareness code
> > +    //
> > +    LocalCoreHandle->EpHandles[0].State = USB_EP_STATE_STATUS;
> > +  }
> > +
> > +  return Status;
> > +}
> > +
> > +
> > +/**
> > +  Interface:
> > +  This function is used to send status packet on EP0
> > +  @CoreHandle: xDCI controller handle
> > +
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +DwcXdciEp0SendStatusPkt (
> > +  IN VOID    *CoreHandle
> > +  )
> > +{
> > +  XDCI_CORE_HANDLE                *LocalCoreHandle = (XDCI_CORE_HANDLE
> *)CoreHandle;
> > +  DWC_XDCI_TRB                    *Trb;
> > +  DWC_XDCI_ENDPOINT_CMD_PARAMS    EpCmdParams;
> > +  EFI_STATUS                      Status;
> > +  UINT32                          BaseAddr;
> > +
> > +  if (CoreHandle == NULL) {
> > +    DEBUG ((DEBUG_INFO, "DwcXdciEp0SendStatusPkt: INVALID
> handle\n"));
> > +    return EFI_DEVICE_ERROR;
> > +  }
> > +
> > +  BaseAddr = LocalCoreHandle->BaseAddress;
> > +
> > +  //
> > +  // We are sending on EP0 so physical EP is 1
> > +  //
> > +  Trb = (LocalCoreHandle->Trbs + (1 * DWC_XDCI_TRB_NUM));
> > +  DEBUG ((DEBUG_INFO, "(DwcXdciEp0SendStatusPkt)\n"));
> > +
> > +  LocalCoreHandle->EpHandles[0].State = USB_EP_STATE_STATUS;
> > +  Status = DwcXdciCoreInitTrb (
> > +             LocalCoreHandle,
> > +             Trb,
> > +             TRBCTL_2_PHASE,
> > +             LocalCoreHandle->AlignedMiscBuffer,
> > +             0
> > +             );
> > +
> > +  if (Status) {
> > +    DEBUG ((DEBUG_INFO, "DwcXdciEp0SendStatusPkt: TRB failed during
> status phase\n"));
> > +    return Status;
> > +  }
> > +
> > +  //
> > +  // Issue a DEPSTRTXFER for EP1
> > +  // Reset params
> > +  //
> > +  EpCmdParams.Param0 = EpCmdParams.Param1 =
> EpCmdParams.Param2 = 0;
> > +
> > +  //
> > +  // Init the lower re-bits for TRB address
> > +  //
> > +  EpCmdParams.Param1 = (UINT32)(UINTN)Trb;
> > +
> > +  //
> > +  // Issue the command
> > +  //
> > +  Status = DwcXdciCoreIssueEpCmd (
> > +             LocalCoreHandle,
> > +             1,
> > +             EPCMD_START_XFER,
> > +             &EpCmdParams
> > +             );
> > +
> > +  if (Status) {
> > +    DEBUG ((DEBUG_INFO, "DwcXdciEp0SendStatusPkt: Failed to issue Start
> Transfer on EP0\n"));
> > +  }
> > +
> > +  //
> > +  // Save new resource index for this transfer
> > +  //
> > +  LocalCoreHandle->EpHandles[1].CurrentXferRscIdx =
> ((UsbRegRead(BaseAddr, DWC_XDCI_EPCMD_REG(1)) &
> DWC_XDCI_EPCMD_RES_IDX_MASK) >>
> DWC_XDCI_EPCMD_RES_IDX_BIT_POS);
> > +  LocalCoreHandle->EpHandles[0].State = USB_EP_STATE_STATUS;
> > +
> > +  return Status;
> > +}
> > +
> > +
> > +/**
> > +  Interface:
> > +  This function is used to send data on non-EP0 endpoint
> > +  @CoreHandle: xDCI controller handle
> > +  @EpInfo: Address of structure describing properties of EP
> > +  @Buffer: Buffer containing data to transmit
> > +  @size: Size of transfer (in bytes)
> > +
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +DwcXdciEpTxData (
> > +  IN VOID                *CoreHandle,
> > +  IN USB_XFER_REQUEST    *XferReq
> > +  )
> > +{
> > +  XDCI_CORE_HANDLE              *LocalCoreHandle = (XDCI_CORE_HANDLE
> *)CoreHandle;
> > +  DWC_XDCI_ENDPOINT_CMD_PARAMS  EpCmdParams;
> > +  DWC_XDCI_TRB                  *Trb;
> > +  DWC_XDCI_TRB_CONTROL          TrbCtrl;
> > +  EFI_STATUS                    Status;
> > +  UINT32                        EpNum;
> > +  UINT32                        BaseAddr;
> > +
> > +  if (CoreHandle == NULL) {
> > +    DEBUG ((DEBUG_INFO, "DwcXdciEpTxData: INVALID handle\n"));
> > +    return EFI_DEVICE_ERROR;
> > +  }
> > +
> > +  if (XferReq == NULL) {
> > +    DEBUG ((DEBUG_INFO, "DwcXdciEpTxData: INVALID transfer
> request\n"));
> > +    return EFI_INVALID_PARAMETER;
> > +  }
> > +
> > +  BaseAddr = LocalCoreHandle->BaseAddress;
> > +
> > +  //
> > +  // Convert to physical endpoint
> > +  //
> > +  EpNum = DwcXdciGetPhysicalEpNum (
> > +             XferReq->EpInfo.EpNum,
> > +             XferReq->EpInfo.EpDir
> > +             );
> > +
> > +  Trb = (LocalCoreHandle->Trbs + (EpNum * DWC_XDCI_TRB_NUM));
> > +  DEBUG ((DEBUG_INFO, "(DwcXdciEpTxData)EpNum is %d\n", EpNum));
> > +
> > +
> > +  if (EpNum > 1)
> > +    TrbCtrl = TRBCTL_NORMAL;
> > +  else
> > +    TrbCtrl = TRBCTL_CTRL_DATA_PHASE;
> > +
> > +  if (Trb->TrbCtrl & DWC_XDCI_TRB_CTRL_HWO_MASK) {
> > +    Status = DwcXdciEndXfer (LocalCoreHandle, EpNum);
> > +    if (Status) {
> > +      DEBUG ((DEBUG_INFO, "DwcXdciEpTxData: Failed to end previous
> transfer\n"));
> > +    }
> > +
> > +    Status = DwcXdciCoreFlushEpTxFifo (LocalCoreHandle, EpNum);
> > +    if (Status) {
> > +      DEBUG ((DEBUG_INFO, "DwcXdciEpTxData: Failed to end previous
> transfer\n"));
> > +    }
> > +  }
> > +
> > +  //
> > +  // Data phase
> > +  //
> > +  CopyMem (&(LocalCoreHandle->EpHandles[EpNum].XferHandle),
> XferReq, sizeof (USB_XFER_REQUEST));
> > +  LocalCoreHandle->EpHandles[EpNum].State = USB_EP_STATE_DATA;
> > +
> > +  LocalCoreHandle->EpHandles[EpNum].Trb = Trb;
> > +
> > +  Status = DwcXdciCoreInitTrb (
> > +             LocalCoreHandle,
> > +             Trb,
> > +             TrbCtrl,
> > +             XferReq->XferBuffer,
> > +             XferReq->XferLen
> > +             );
> > +
> > +  if (Status) {
> > +    DEBUG ((DEBUG_INFO, "DwcXdciEpTxData: TRB failed\n"));
> > +    return Status;
> > +  }
> > +
> > +  //
> > +  // Issue a DEPSTRTXFER for EP
> > +  // Reset params
> > +  //
> > +  EpCmdParams.Param0 = EpCmdParams.Param1 =
> EpCmdParams.Param2 = 0;
> > +
> > +  //
> > +  // Init the lower re-bits for TRB address
> > +  //
> > +  EpCmdParams.Param1 = (UINT32)(UINTN)Trb;
> > +
> > +  //
> > +  // Issue the command
> > +  //
> > +  Status = DwcXdciCoreIssueEpCmd (
> > +             LocalCoreHandle,
> > +             EpNum,
> > +             EPCMD_START_XFER,
> > +             &EpCmdParams
> > +             );
> > +
> > +  //
> > +  // Save new resource index for this transfer
> > +  //
> > +  LocalCoreHandle->EpHandles[EpNum].CurrentXferRscIdx =
> ((UsbRegRead (BaseAddr, DWC_XDCI_EPCMD_REG(EpNum)) &
> DWC_XDCI_EPCMD_RES_IDX_MASK) >>
> DWC_XDCI_EPCMD_RES_IDX_BIT_POS);
> > +
> > +  return Status;
> > +}
> > +
> > +
> > +/**
> > +  Interface:
> > +  This function is used to receive data on non-EP0 endpoint
> > +  @CoreHandle: xDCI controller handle
> > +  @EpInfo: Address of structure describing properties of EP
> > +  @Buffer: Buffer containing data to transmit
> > +  @size: Size of transfer (in bytes)
> > +
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +DwcXdciEpRxData (
> > +  IN VOID                *CoreHandle,
> > +  IN USB_XFER_REQUEST    *XferReq
> > +  )
> > +{
> > +  XDCI_CORE_HANDLE              *LocalCoreHandle = (XDCI_CORE_HANDLE
> *)CoreHandle;
> > +  DWC_XDCI_ENDPOINT_CMD_PARAMS  EpCmdParams;
> > +  DWC_XDCI_TRB                  *Trb;
> > +  DWC_XDCI_TRB_CONTROL          TrbCtrl;
> > +  EFI_STATUS                    Status;
> > +  UINT32                        EpNum;
> > +  UINT32                        BaseAddr;
> > +
> > +  if (CoreHandle == NULL) {
> > +    DEBUG ((DEBUG_INFO, "DwcXdciEpRxData: INVALID handle\n"));
> > +    return EFI_DEVICE_ERROR;
> > +  }
> > +
> > +  if (XferReq == NULL) {
> > +    DEBUG ((DEBUG_INFO, "DwcXdciEpRxData: INVALID transfer
> request\n"));
> > +    return EFI_INVALID_PARAMETER;
> > +  }
> > +
> > +  BaseAddr = LocalCoreHandle->BaseAddress;
> > +
> > +  //
> > +  // Convert to physical endpoint
> > +  //
> > +  EpNum = DwcXdciGetPhysicalEpNum (XferReq->EpInfo.EpNum, XferReq-
> >EpInfo.EpDir);
> > +
> > +  Trb = (LocalCoreHandle->Trbs + (EpNum * DWC_XDCI_TRB_NUM));
> > +  DEBUG ((DEBUG_INFO, "(DwcXdciEpRxData)EpNum is %d\n", EpNum));
> > +
> > +  if (EpNum > 1)
> > +    TrbCtrl = TRBCTL_NORMAL;
> > +  else
> > +    TrbCtrl = TRBCTL_CTRL_DATA_PHASE;
> > +
> > +  //
> > +  // If CheckFlag didn't set to FALSE, means the previous transfer request
> didn't complete,
> > +  // need to wait the previous request done.
> > +  //
> > +  if (LocalCoreHandle->EpHandles[EpNum].CheckFlag == TRUE) {
> > +    return EFI_NOT_READY;
> > +  }
> > +
> > +  LocalCoreHandle->EpHandles[EpNum].CheckFlag = TRUE;
> > +
> > +  //
> > +  // Data phase
> > +  //
> > +  CopyMem (&(LocalCoreHandle->EpHandles[EpNum].XferHandle),
> XferReq, sizeof (USB_XFER_REQUEST));
> > +
> > +  LocalCoreHandle->EpHandles[EpNum].State = USB_EP_STATE_DATA;
> > +
> > +  LocalCoreHandle->EpHandles[EpNum].Trb = Trb;
> > +
> > +  DEBUG ((DEBUG_INFO, "(DwcXdciEpRxData)XferReq->XferLen is
> 0x%x\n", XferReq->XferLen));
> > +
> > +  Status = DwcXdciCoreInitTrb (
> > +             LocalCoreHandle,
> > +             Trb,
> > +             TrbCtrl,
> > +             XferReq->XferBuffer,
> > +             XferReq->XferLen
> > +             );
> > +
> > +  if (Status) {
> > +    DEBUG ((DEBUG_INFO, "DwcXdciEpRxData: TRB failed\n"));
> > +    return Status;
> > +  }
> > +  //
> > +  // Issue a DEPSTRTXFER for EP
> > +  // Reset params
> > +  //
> > +  EpCmdParams.Param0 = EpCmdParams.Param1 =
> EpCmdParams.Param2 = 0;
> > +
> > +  //
> > +  // Init the lower re-bits for TRB address
> > +  //
> > +  EpCmdParams.Param1 = (UINT32)(UINTN)Trb;
> > +
> > +  //
> > +  // Issue the command
> > +  //
> > +  Status = DwcXdciCoreIssueEpCmd (
> > +             LocalCoreHandle,
> > +             EpNum,
> > +             EPCMD_START_XFER,
> > +             &EpCmdParams
> > +             );
> > +
> > +  if (Status) {
> > +    DEBUG ((DEBUG_INFO, "DwcXdciEpRxData: Failed to start transfer\n"));
> > +  }
> > +
> > +  //
> > +  // Save new resource index for this transfer
> > +  //
> > +  LocalCoreHandle->EpHandles[EpNum].CurrentXferRscIdx =
> ((UsbRegRead(BaseAddr, DWC_XDCI_EPCMD_REG(EpNum)) &
> DWC_XDCI_EPCMD_RES_IDX_MASK) >>
> DWC_XDCI_EPCMD_RES_IDX_BIT_POS);
> > +
> > +  return Status;
> > +}
> > +
> > +
> > +
> > +STATIC
> > +EFI_STATUS
> > +DwcXdciCoreFlushEpFifo (
> > +  IN XDCI_CORE_HANDLE    *CoreHandle,
> > +  IN UINT32              EpNum
> > +  )
> > +{
> > +  UINT32 BaseAddr;
> > +  UINT32 MaxDelayIter = DWC_XDCI_MAX_DELAY_ITERATIONS;
> > +  UINT32 fifoNum;
> > +  UINT32 Param;
> > +
> > +  if (CoreHandle == NULL) {
> > +    DEBUG ((DEBUG_INFO, "ERROR: DwcXdciCoreFlushEpTxFifo: INVALID
> handle\n"));
> > +    return EFI_DEVICE_ERROR;
> > +  }
> > +
> > +  BaseAddr = CoreHandle->BaseAddress;
> > +
> > +  //
> > +  // Translate to FIFOnum
> > +  // NOTE: Assuming this is a Tx EP
> > +  //
> > +  fifoNum = (EpNum >> 1);
> > +
> > +  //
> > +  // TODO: Currently we are only using TxFIFO 0. Later map these
> > +  // Write the FIFO num/dir param for the generic command.
> > +  //
> > +
> > +  Param = UsbRegRead (BaseAddr, DWC_XDCI_DGCMD_PARAM_REG);
> > +  Param &= ~(DWC_XDCI_DGCMD_PARAM_TX_FIFO_NUM_MASK |
> DWC_XDCI_DGCMD_PARAM_TX_FIFO_DIR_MASK);
> > +
> > +  if ((EpNum & 0x01) != 0) {
> > +    Param |= (fifoNum |
> DWC_XDCI_DGCMD_PARAM_TX_FIFO_DIR_MASK);
> > +  } else {
> > +    Param |= fifoNum;
> > +  }
> > +
> > +  DEBUG ((DEBUG_INFO, "USB FU Flash: CMD 0x%08x :: Param 0x%08x\n",
> > +        (UsbRegRead(BaseAddr, DWC_XDCI_DGCMD_REG) |
> DWC_XDCI_DGCMD_CMD_SEL_FIFO_FLUSH |
> DWC_XDCI_DGCMD_CMD_ACTIVE_MASK),
> > +        Param));
> > +
> > +  UsbRegWrite (
> > +    BaseAddr,
> > +    DWC_XDCI_DGCMD_PARAM_REG,
> > +    Param
> > +    );
> > +
> > +  //
> > +  // Write the command to flush all FIFOs
> > +  //
> > +  UsbRegWrite (
> > +    BaseAddr,
> > +    DWC_XDCI_DGCMD_REG,
> > +    (UsbRegRead(BaseAddr, DWC_XDCI_DGCMD_REG) |
> DWC_XDCI_DGCMD_CMD_SEL_FIFO_FLUSH |
> DWC_XDCI_DGCMD_CMD_ACTIVE_MASK)
> > +    );
> > +
> > +
> > +  //
> > +  // Wait until command completes
> > +  //
> > +  do {
> > +    if (!(UsbRegRead(BaseAddr, DWC_XDCI_DGCMD_REG) &
> DWC_XDCI_DGCMD_CMD_ACTIVE_MASK))
> > +      break;
> > +    else
> > +      gBS->Stall (DWC_XDCI_MAX_DELAY_ITERATIONS);
> > +  } while (--MaxDelayIter);
> > +
> > +  if (!MaxDelayIter) {
> > +    DEBUG ((DEBUG_INFO, "Failed to issue Command\n"));
> > +    return EFI_DEVICE_ERROR;
> > +  }
> > +
> > +  return EFI_SUCCESS;
> > +}
> > +
> > +/**
> > +  Interface:
> > +  This function is used to cancel a transfer on non-EP0 endpoint
> > +  @CoreHandle: xDCI controller handle
> > +  @EpInfo: Address of structure describing properties of EP
> > +
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +DwcXdciEpCancelTransfer (
> > +  IN VOID           *CoreHandle,
> > +  IN USB_EP_INFO    *EpInfo
> > +  )
> > +{
> > +  EFI_STATUS  Status = EFI_DEVICE_ERROR;
> > +  UINT32      EpNum;
> > +
> > +  if (CoreHandle == NULL) {
> > +    DEBUG ((DEBUG_INFO, "DwcXdciEpCancelTransfer: INVALID
> handle\n"));
> > +    return EFI_DEVICE_ERROR;
> > +  }
> > +
> > +  //
> > +  // Get physical EP num
> > +  //
> > +  EpNum = DwcXdciGetPhysicalEpNum (EpInfo->EpNum, EpInfo->EpDir);
> > +  Status = DwcXdciEndXfer(CoreHandle, EpNum);
> > +  DwcXdciCoreFlushEpFifo(CoreHandle, EpNum);
> > +
> > +  return Status;
> > +}
> > +
> > +
> > +EFI_STATUS
> > +usbProcessDeviceResetDet (
> > +  IN XDCI_CORE_HANDLE    *CoreHandle
> > +  )
> > +{
> > +   return DwcXdciProcessDeviceResetDet (CoreHandle);
> > +}
> > +
> > +EFI_STATUS
> > +usbProcessDeviceResetDone (
> > +  IN XDCI_CORE_HANDLE    *CoreHandle
> > +  )
> > +{
> > +  return DwcXdciProcessDeviceResetDone (CoreHandle);
> > +}
> > +
> > +UINT32
> > +UsbGetPhysicalEpNum (
> > +  IN UINT32        EndpointNum,
> > +  IN USB_EP_DIR    EndpointDir
> > +  )
> > +{
> > +  return DwcXdciGetPhysicalEpNum(
> > +                            EndpointNum,
> > +                            EndpointDir
> > +                            );
> > +}
> > +
> > +
> > +EFI_STATUS
> > +EFIAPI
> > +UsbXdciCoreReinit (
> > +  IN VOID                     *CoreHandle
> > +  )
> > +{
> > +  EFI_STATUS                      status = EFI_DEVICE_ERROR;
> > +  UINT32                          BaseAddr;
> > +  XDCI_CORE_HANDLE                *LocalCoreHandle;
> > +  DWC_XDCI_ENDPOINT_CMD_PARAMS    EpCmdParams;
> > +  UINT32                          MaxDelayIter =
> DWC_XDCI_MAX_DELAY_ITERATIONS;
> > +  UINT8                           i;
> > +
> > +  LocalCoreHandle = CoreHandle;
> > +
> > +  if (CoreHandle == NULL) {
> > +    return EFI_INVALID_PARAMETER;
> > +  }
> > +
> > +  if (LocalCoreHandle == NULL) {
> > +    DEBUG ((DEBUG_INFO, "DwcXdciCoreInit: Failed to allocate handle for
> xDCI\n"));
> > +    return EFI_OUT_OF_RESOURCES;
> > +  }
> > +
> > +  BaseAddr = LocalCoreHandle->BaseAddress;
> > +
> > +  DEBUG ((DEBUG_INFO, "Resetting the USB core\n"));
> > +  UsbRegWrite (
> > +    BaseAddr,
> > +    DWC_XDCI_DCTL_REG,
> > +    UsbRegRead (BaseAddr, DWC_XDCI_DCTL_REG) |
> DWC_XDCI_DCTL_CSFTRST_MASK
> > +    );
> > +
> > +  //
> > +  // Wait until core soft reset completes
> > +  //
> > +  do {
> > +    if (!(UsbRegRead (BaseAddr, DWC_XDCI_DCTL_REG) &
> DWC_XDCI_DCTL_CSFTRST_MASK)) {
> > +      break;
> > +    } else {
> > +      gBS->Stall (DWC_XDCI_MAX_DELAY_ITERATIONS);
> > +    }
> > +  } while (--MaxDelayIter);
> > +
> > +  if (!MaxDelayIter) {
> > +    DEBUG ((DEBUG_INFO, "Failed to reset device controller\n"));
> > +    return EFI_DEVICE_ERROR;
> > +  }
> > +
> > +  DEBUG ((DEBUG_INFO, "USB core has been reset\n"));
> > +
> > +  LocalCoreHandle->DevState = UsbDevStateDefault;
> > +
> > +  //
> > +  // Clear KeepConnect bit so we can allow disconnect and
> > +  // re-connect. Stay in RX_DETECT state
> > +  //
> > +  UsbRegWrite (
> > +    BaseAddr,
> > +    DWC_XDCI_DCTL_REG,
> > +    UsbRegRead (BaseAddr, DWC_XDCI_DCTL_REG) &
> > +    (~DWC_XDCI_DCTL_KEEP_CONNECT_MASK) &
> > +    ((~DWC_XDCI_DCTL_STATE_CHANGE_REQ_MASK) |
> > +    (DWC_XDCI_DCTL_STATE_CHANGE_REQ_RX_DETECT <<
> DWC_XDCI_DCTL_STATE_CHANGE_REQ_BIT_POS))
> > +    );
> > +
> > +  DEBUG ((DEBUG_INFO, "Device controller Synopsys ID: %x\n",
> UsbRegRead (BaseAddr, DWC_XDCI_GSNPSID_REG)));
> > +  DEBUG ((DEBUG_INFO, "Default value of xDCI GSBUSCFG0 and
> GSBUSCFG1: %x, %x\n",
> > +          UsbRegRead (BaseAddr, DWC_XDCI_GSBUSCFG0_REG),
> > +          UsbRegRead (BaseAddr, DWC_XDCI_GSBUSCFG1_REG)));
> > +
> > +  DEBUG ((DEBUG_INFO, "Default value of xDCI GTXTHRCFG and
> GRXTHRCFG: %x, %x\n",
> > +          UsbRegRead (BaseAddr, DWC_XDCI_GTXTHRCFG_REG),
> > +          UsbRegRead (BaseAddr, DWC_XDCI_GRXTHRCFG_REG)));
> > +
> > +  //
> > +  // Clear ULPI auto-resume bit
> > +  //
> > +  UsbRegWrite (
> > +    BaseAddr,
> > +    DWC_XDCI_GUSB2PHYCFG_REG (0),
> > +    (UsbRegRead (BaseAddr, DWC_XDCI_GUSB2PHYCFG_REG (0)) &
> ~DWC_XDCI_GUSB2PHYCFG_ULPI_AUTO_RESUME_MASK)
> > +    );
> > +
> > +  DEBUG ((DEBUG_INFO, "Default value of xDCI GUSB2PHYCFG and
> GUSB3PIPECTL: %x, %x\n",
> > +          UsbRegRead (BaseAddr, DWC_XDCI_GUSB2PHYCFG_REG (0)),
> > +          UsbRegRead (BaseAddr, DWC_XDCI_GUSB3PIPECTL_REG (0))));
> > +
> > +  //
> > +  // Only one RxFIFO
> > +  //
> > +  DEBUG ((DEBUG_INFO, "Default value of DWC_XDCI_GRXFIFOSIZ: %x\n",
> > +          UsbRegRead (BaseAddr, DWC_XDCI_GRXFIFOSIZ_REG (0))));
> > +
> > +  for (i = 0; i < DWC_XDCI_MAX_ENDPOINTS; i++) {
> > +    DEBUG ((DEBUG_INFO, "Default value of xDCI DWC_XDCI_GTXFIFOSIZ
> %d: %x\n",
> > +            i, UsbRegRead (BaseAddr, DWC_XDCI_GTXFIFOSIZ_REG (i))));
> > +  }
> > +
> > +  //
> > +  // TODO: Need to check if TxFIFO should start where RxFIFO ends
> > +  // or default is correct i.e. TxFIFO starts at 0 just like RxFIFO
> > +  //
> > +
> > +  //
> > +  // Allocate and Initialize Event Buffers
> > +  //
> > +  LocalCoreHandle->MaxDevIntLines = ((UsbRegRead (BaseAddr,
> DWC_XDCI_GHWPARAMS1_REG) &
> > +                                           DWC_XDCI_GHWPARAMS1_NUM_INT_MASK) >>
> > +                                           DWC_XDCI_GHWPARAMS1_NUM_INT_BIT_POS);
> > +
> > +  DEBUG ((DEBUG_INFO, "Max dev int lines: %d\n", LocalCoreHandle-
> >MaxDevIntLines));
> > +  //
> > +  // One event Buffer per interrupt line.
> > +  //  Need to align it to size of event Buffer
> > +  //  Buffer needs to be big enough. Otherwise the core
> > +  //  won't operate
> > +  //
> > +  LocalCoreHandle->AlignedEventBuffers = (DWC_XDCI_EVENT_BUFFER *)
> > +                                             ((UINT32)(UINTN)(LocalCoreHandle-
> >EventBuffers) +
> > +                                             ((sizeof (DWC_XDCI_EVENT_BUFFER) *
> DWC_XDCI_MAX_EVENTS_PER_BUFFER) -
> > +                                             (((UINT32)(UINTN)(LocalCoreHandle-
> >EventBuffers)) %
> > +                                             (sizeof (DWC_XDCI_EVENT_BUFFER) *
> DWC_XDCI_MAX_EVENTS_PER_BUFFER))));
> > +
> > +  for (i = 0; i < LocalCoreHandle->MaxDevIntLines; i++) {
> > +    UsbRegWrite (
> > +      BaseAddr,
> > +      DWC_XDCI_GEVNTADR_REG (i),
> > +      (UINT32)(UINTN)(LocalCoreHandle->AlignedEventBuffers + i *
> sizeof(DWC_XDCI_EVENT_BUFFER) *
> DWC_XDCI_MAX_EVENTS_PER_BUFFER)
> > +      );
> > +
> > +    //
> > +    // Clear High 32bit address register, GEVNTADR register is 64-bit register
> > +    // default is 0xffffffffffffffff
> > +    //
> > +    UsbRegWrite (BaseAddr, DWC_XDCI_GEVNTADR_REG (i) + 4,
> 0x00000000);
> > +
> > +    LocalCoreHandle->CurrentEventBuffer = LocalCoreHandle-
> >AlignedEventBuffers;
> > +    //
> > +    // Write size and clear the mask
> > +    //
> > +    UsbRegWrite (
> > +      BaseAddr,
> > +      DWC_XDCI_EVNTSIZ_REG (i),
> > +      sizeof (DWC_XDCI_EVENT_BUFFER) *
> DWC_XDCI_MAX_EVENTS_PER_BUFFER
> > +      );
> > +
> > +    //
> > +    // Write 0 to the event count register as the last step
> > +    // for event configuration
> > +    //
> > +    UsbRegWrite (BaseAddr, DWC_XDCI_EVNTCOUNT_REG (i), 0);
> > +
> > +    DEBUG ((DEBUG_INFO, "Value of xDCI Event Buffer %d: %x, Size: %x,
> Count: %x\n",
> > +                        i,
> > +                        UsbRegRead (BaseAddr, DWC_XDCI_GEVNTADR_REG (i)),
> > +                        UsbRegRead (BaseAddr, DWC_XDCI_EVNTSIZ_REG (i)),
> > +                        UsbRegRead (BaseAddr, DWC_XDCI_EVNTCOUNT_REG (i))));
> > +  }
> > +
> > +    //
> > +    // Program Global Control Register to disable scaledown,
> > +    // disable clock gating
> > +    //
> > +    UsbRegWrite (
> > +      BaseAddr,
> > +      DWC_XDCI_GCTL_REG,
> > +      ((UsbRegRead(BaseAddr, DWC_XDCI_GCTL_REG) &
> > +                    ~(DWC_XDCI_GCTL_SCALE_DOWN_MODE_MASK +
> DWC_XDCI_GCTL_RAMCLKSEL_MASK +
> DWC_XDCI_GCTL_DISABLE_SCRAMB_MASK)) |
> > +                    DWC_XDCI_GCTL_DISABLE_CLK_GATING_MASK |
> > +                    (DWC_XDCI_GCTL_PRT_CAP_DEVICE <<
> DWC_XDCI_GCTL_PRT_CAP_DIR_BIT_POS)));
> > +
> > +    DEBUG ((DEBUG_INFO, "Setup value of xDCI DWC_XDCI_GCTL_REG:
> 0x%x\n", UsbRegRead (BaseAddr, DWC_XDCI_GCTL_REG)));
> > +
> > +
> > +  //
> > +  // TODO: Program desired Speed and set LPM capable
> > +  // We will do this when SuperSpeed works. For now,
> > +  // force into High-Speed mode to aVOID anyone trying this
> > +  // on Super Speed port
> > +  //
> > +#ifdef SUPPORT_SUPER_SPEED
> > +  UsbRegWrite (
> > +    BaseAddr,
> > +    DWC_XDCI_DCFG_REG,
> > +    (UsbRegRead (BaseAddr, DWC_XDCI_DCFG_REG) &
> ~DWC_XDCI_DCFG_DESIRED_DEV_SPEED_MASK) | LocalCoreHandle-
> >DesiredSpeed
> > +    );
> > +#else
> > +  UsbRegWrite (
> > +    BaseAddr,
> > +    DWC_XDCI_DCFG_REG,
> > +    (UsbRegRead (BaseAddr, DWC_XDCI_DCFG_REG) &
> ~DWC_XDCI_DCFG_DESIRED_DEV_SPEED_MASK) |
> DWC_XDCI_DCFG_DESIRED_HS_SPEED
> > +    );
> > +#endif
> > +
> > +  DEBUG ((DEBUG_INFO, "Setup value of xDCI DWC_XDCI_DCFG_REG:
> 0x%x\n", UsbRegRead (BaseAddr, DWC_XDCI_DCFG_REG)));
> > +  DEBUG ((DEBUG_INFO, "Setup value of xDCI DWC_XDCI_DSTS_REG:
> 0x%x\n", UsbRegRead (BaseAddr, DWC_XDCI_DSTS_REG)));
> > +
> > +  //
> > +  // Enable Device Interrupt Events
> > +  //
> > +  UsbRegWrite (
> > +    BaseAddr,
> > +    DWC_XDCI_DEVTEN_REG,
> > +    DWC_XDCI_DEVTEN_DEVICE_INTS
> > +    );
> > +
> > +  //
> > +  // Program the desired role
> > +  //
> > +  UsbRegWrite (
> > +    BaseAddr,
> > +    DWC_XDCI_GCTL_REG,
> > +    (UsbRegRead (BaseAddr, DWC_XDCI_GCTL_REG) &
> ~DWC_XDCI_GCTL_PRT_CAP_DIR_MASK) | (LocalCoreHandle->Role <<
> DWC_XDCI_GCTL_PRT_CAP_DIR_BIT_POS)
> > +    );
> > +
> > +  //
> > +  // Clear USB2 suspend for start new config command
> > +  //
> > +  UsbRegWrite (
> > +    BaseAddr,
> > +    DWC_XDCI_GUSB2PHYCFG_REG (0),
> > +    (UsbRegRead (BaseAddr, DWC_XDCI_GUSB2PHYCFG_REG(0)) &
> ~DWC_XDCI_GUSB2PHYCFG_SUSPEND_PHY_MASK)
> > +    );
> > +  //
> > +  // Clear USB3 suspend for start new config command
> > +  //
> > +  UsbRegWrite (
> > +    BaseAddr,
> > +    DWC_XDCI_GUSB3PIPECTL_REG (0),
> > +    (UsbRegRead (BaseAddr, DWC_XDCI_GUSB3PIPECTL_REG(0)) &
> ~DWC_XDCI_GUSB3PIPECTL_SUSPEND_PHY_MASK)
> > +    );
> > +  //
> > +  // Issue DEPSTARTCFG command for EP0
> > +  //
> > +  status = DwcXdciCoreInitEpCmdParams (
> > +             LocalCoreHandle,
> > +             &LocalCoreHandle->EpHandles[0].EpInfo,
> > +             DWC_XDCI_PARAM0_SET_EP_CFG_ACTN_NONE,
> > +             EPCMD_START_NEW_CONFIG,
> > +             &EpCmdParams
> > +             );
> > +
> > +  if (status) {
> > +    DEBUG ((DEBUG_INFO, "DwcXdciCoreInit: Failed to init params for
> START_NEW_CONFIG EP command on xDCI\n"));
> > +    return status;
> > +  }
> > +
> > +  //
> > +  // Issue the command
> > +  //
> > +  status = DwcXdciCoreIssueEpCmd (
> > +             LocalCoreHandle,
> > +             0,
> > +             EPCMD_START_NEW_CONFIG,
> > +             &EpCmdParams
> > +             );
> > +
> > +  if (status) {
> > +    DEBUG ((DEBUG_INFO, "DwcXdciCoreInit: Failed to issue
> START_NEW_CONFIG EP command on xDCI\n"));
> > +    return status;
> > +  }
> > +
> > +  //
> > +  // Issue DEPCFG command for EP0
> > +  //
> > +  status = DwcXdciCoreInitEpCmdParams (
> > +             LocalCoreHandle,
> > +             &LocalCoreHandle->EpHandles[0].EpInfo,
> > +             DWC_XDCI_PARAM0_SET_EP_CFG_ACTN_INIT_STATE,
> > +             EPCMD_SET_EP_CONFIG,
> > +             &EpCmdParams
> > +             );
> > +
> > +  if (status) {
> > +    DEBUG ((DEBUG_INFO, "DwcXdciCoreInit: Failed to init params for
> SET_EP_CONFIG command on xDCI for EP0\n"));
> > +    return status;
> > +  }
> > +
> > +  //
> > +  // Issue the command
> > +  //
> > +  status = DwcXdciCoreIssueEpCmd (
> > +             LocalCoreHandle,
> > +             0,
> > +             EPCMD_SET_EP_CONFIG,
> > +             &EpCmdParams);
> > +
> > +  if (status) {
> > +    DEBUG ((DEBUG_INFO, "DwcXdciCoreInit: Failed to issue
> SET_EP_CONFIG command on xDCI for EP0\n"));
> > +    return status;
> > +  }
> > +
> > +  //
> > +  // Issue DEPCFG command for EP1
> > +  //
> > +  status = DwcXdciCoreInitEpCmdParams (
> > +             LocalCoreHandle,
> > +             &LocalCoreHandle->EpHandles[1].EpInfo,
> > +             DWC_XDCI_PARAM0_SET_EP_CFG_ACTN_INIT_STATE,
> > +             EPCMD_SET_EP_CONFIG,
> > +             &EpCmdParams
> > +             );
> > +
> > +  if (status) {
> > +    DEBUG ((DEBUG_INFO, "DwcXdciCoreInit: Failed to init params for
> SET_EP_CONFIG command on xDCI for EP1\n"));
> > +    return status;
> > +  }
> > +
> > +  //
> > +  // Issue the command
> > +  //
> > +  status = DwcXdciCoreIssueEpCmd (
> > +             LocalCoreHandle,
> > +             1,
> > +             EPCMD_SET_EP_CONFIG,
> > +             &EpCmdParams
> > +             );
> > +
> > +  if (status) {
> > +    DEBUG ((DEBUG_INFO, "DwcXdciCoreInit: Failed to issue
> SET_EP_CONFIG command on xDCI for EP1\n"));
> > +    return status;
> > +  }
> > +
> > +  //
> > +  // Issue DEPXFERCFG command for EP0
> > +  //
> > +  status = DwcXdciCoreInitEpCmdParams (
> > +             LocalCoreHandle,
> > +             &LocalCoreHandle->EpHandles[0].EpInfo,
> > +             DWC_XDCI_PARAM0_SET_EP_CFG_ACTN_NONE,
> > +             EPCMD_SET_EP_XFER_RES_CONFIG,
> > +             &EpCmdParams
> > +             );
> > +
> > +  if (status) {
> > +    DEBUG ((DEBUG_INFO, "DwcXdciCoreInit: Failed to init params for
> EPCMD_SET_EP_XFER_RES_CONFIG command on xDCI for EP0\n"));
> > +    return status;
> > +  }
> > +
> > +  //
> > +  // Issue the command
> > +  //
> > +  status = DwcXdciCoreIssueEpCmd (
> > +             LocalCoreHandle,
> > +             0,
> > +             EPCMD_SET_EP_XFER_RES_CONFIG,
> > +             &EpCmdParams
> > +             );
> > +
> > +  if (status) {
> > +    DEBUG ((DEBUG_INFO, "DwcXdciCoreInit: Failed to issue
> EPCMD_SET_EP_XFER_RES_CONFIG command on xDCI for EP0\n"));
> > +    return status;
> > +  }
> > +
> > +  //
> > +  // Issue DEPXFERCFG command for EP1
> > +  //
> > +  status = DwcXdciCoreInitEpCmdParams (
> > +             LocalCoreHandle,
> > +             &LocalCoreHandle->EpHandles[1].EpInfo,
> > +             DWC_XDCI_PARAM0_SET_EP_CFG_ACTN_NONE,
> > +             EPCMD_SET_EP_XFER_RES_CONFIG,
> > +             &EpCmdParams
> > +             );
> > +
> > +  if (status) {
> > +    DEBUG ((DEBUG_INFO, "DwcXdciCoreInit: Failed to init params for
> EPCMD_SET_EP_XFER_RES_CONFIG command on xDCI for EP1\n"));
> > +    return status;
> > +  }
> > +
> > +  //
> > +  // Issue the command
> > +  //
> > +  status = DwcXdciCoreIssueEpCmd (
> > +             LocalCoreHandle,
> > +             1,
> > +             EPCMD_SET_EP_XFER_RES_CONFIG,
> > +             &EpCmdParams
> > +             );
> > +
> > +  if (status) {
> > +    DEBUG ((DEBUG_INFO, "DwcXdciCoreInit: Failed to issue
> EPCMD_SET_EP_XFER_RES_CONFIG command on xDCI for EP1\n"));
> > +    return status;
> > +  }
> > +
> > +  //
> > +  // Prepare a Buffer for SETUP packet
> > +  //
> > +  LocalCoreHandle->Trbs = (DWC_XDCI_TRB *)((UINTN)
> > +                            LocalCoreHandle->UnalignedTrbs +
> > +                            (UINTN)(DWC_XDCI_TRB_BYTE_ALIGNMENT -
> > +                            ((UINT32)(UINTN)LocalCoreHandle->UnalignedTrbs %
> > +                            DWC_XDCI_TRB_BYTE_ALIGNMENT)));
> > +
> > +  DEBUG ((DEBUG_INFO, "(DwcXdciCoreInit)@@@@@@@@@
> unalignedTrbs address is 0x%x\n", LocalCoreHandle->UnalignedTrbs));
> > +  DEBUG ((DEBUG_INFO, "(DwcXdciCoreInit)@@@@@@@@@ TRB
> address is 0x%x\n", LocalCoreHandle->Trbs));
> > +
> > +  //
> > +  // Allocate Setup Buffer that is 8-byte aligned
> > +  //
> > +  LocalCoreHandle->AlignedSetupBuffer = LocalCoreHandle-
> >DefaultSetupBuffer +
> > +                                            (DWC_XDCI_SETUP_BUFF_SIZE -
> > +                                            ((UINT32)(UINTN)(LocalCoreHandle-
> >DefaultSetupBuffer) % DWC_XDCI_SETUP_BUFF_SIZE));
> > +
> > +  //
> > +  // Aligned Buffer for status phase
> > +  //
> > +  LocalCoreHandle->AlignedMiscBuffer = LocalCoreHandle->MiscBuffer +
> > +                                           (DWC_XDCI_SETUP_BUFF_SIZE -
> > +                                           ((UINT32)(UINTN)(LocalCoreHandle-
> >AlignedMiscBuffer) % DWC_XDCI_SETUP_BUFF_SIZE));
> > +
> > +  //
> > +  // We will queue SETUP request when we see bus reset
> > +  //
> > +
> > +  //
> > +  // Enable Physical Endpoints 0
> > +  //
> > +  UsbRegWrite (
> > +    BaseAddr,
> > +    DWC_XDCI_EP_DALEPENA_REG,
> > +    UsbRegRead (BaseAddr, DWC_XDCI_EP_DALEPENA_REG) | (1 << 0)
> > +    );
> > +
> > +  //
> > +  // Enable Physical Endpoints 1
> > +  //
> > +  UsbRegWrite (
> > +    BaseAddr,
> > +    DWC_XDCI_EP_DALEPENA_REG,
> > +    UsbRegRead (BaseAddr, DWC_XDCI_EP_DALEPENA_REG) | (1 << 1)
> > +    );
> > +
> > +  DEBUG ((DEBUG_INFO, "Default value of xDCI DWC_XDCI_DEVTEN_REG:
> 0x%x\n", UsbRegRead (BaseAddr, DWC_XDCI_DEVTEN_REG)));
> > +  return status;
> > +
> > +
> > +}
> > +
> > +
> > +EFI_STATUS
> > +UsbXdciCoreFlushEpFifo (
> > +  IN VOID           *CoreHandle,
> > +  IN USB_EP_INFO    *EpInfo
> > +  )
> > +{
> > +  EFI_STATUS  Status = EFI_DEVICE_ERROR;
> > +  UINT32      EpNum;
> > +
> > +  if (CoreHandle == NULL) {
> > +    DEBUG ((DEBUG_INFO, "DwcXdciEpCancelTransfer: INVALID
> handle\n"));
> > +    return EFI_DEVICE_ERROR;
> > +  }
> > +
> > +  //
> > +  // Get physical EP num
> > +  //
> > +  EpNum = DwcXdciGetPhysicalEpNum (EpInfo->EpNum, EpInfo->EpDir);
> > +  DwcXdciCoreFlushEpFifo(CoreHandle, EpNum);
> > +
> > +  return Status;
> > +}
> > diff --git
> a/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciDWC.h
> b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciDWC.h
> > new file mode 100644
> > index 0000000000..9c1b2d1d85
> > --- /dev/null
> > +++ b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciDWC.h
> > @@ -0,0 +1,741 @@
> > +/** @file
> > +  Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR>
> > +
> > +  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.
> > +
> > +**/
> > +
> > +#ifndef _XDCI_DWC_H_
> > +#define _XDCI_DWC_H_
> > +
> > +#include "XdciCommon.h"
> > +#include "XdciDevice.h"
> > +
> > +#define DWC_XDCI_MAX_ENDPOINTS                             (16)
> > +#define DWC_XDCI_SS_CTRL_EP_MPS                            (512)
> > +#define DWC_XDCI_HS_CTRL_EP_MPS                            (64)
> > +#define DWC_XDCI_FS_CTRL_EP_MPS                            (64)
> > +#define DWC_XDCI_LS_CTRL_EP_MPS                            (8)
> > +#define DWC_XDCI_SS_CTRL_BUF_SIZE                          (512)
> > +#define DWC_XDCI_SETUP_BUFF_SIZE                           (8)
> > +#define DWC_XDCI_MAX_EVENTS_PER_BUFFER                     (16)
> > +#define DWC_XDCI_TRB_BYTE_ALIGNMENT                        (16)
> > +#define DWC_XDCI_DEFAULT_TX_FIFO_SIZE                      (1024)
> > +#define DWC_XDCI_TRB_NUM                                   (32)
> > +#define DWC_XDCI_MASK                                      (DWC_XDCI_TRB_NUM - 1)
> > +
> > +#define DWC_XDCI_MAX_DELAY_ITERATIONS                      (1000)
> > +
> > +#define DWC_XDCI_GSBUSCFG0_REG                             (0xC100)
> > +#define DWC_XDCI_GSBUSCFG1_REG                             (0xC104)
> > +#define DWC_XDCI_GTXTHRCFG_REG                             (0xC108)
> > +#define DWC_XDCI_GRXTHRCFG_REG                             (0xC10C)
> > +
> > +//
> > +// Global Control Register and bit definitions
> > +//
> > +#define DWC_XDCI_GCTL_REG                                  (0xC110)
> > +#define DWC_XDCI_GCTL_PWRDNSCALE_MASK                      (0xFFF80000)
> > +#define DWC_XDCI_GCTL_PWRDNSCALE_VAL                       (0x13880000)
> > +#define DWC_XDCI_GCTL_U2RSTECN_MASK                        (0x00010000)
> > +#define DWC_XDCI_GCTL_PRT_CAP_DIR_MASK                     (0x00003000)
> > +#define DWC_XDCI_GCTL_PRT_CAP_DIR_BIT_POS                  (12)
> > +#define DWC_XDCI_GCTL_PRT_CAP_HOST                         (1)
> > +#define DWC_XDCI_GCTL_PRT_CAP_DEVICE                       (2)
> > +#define DWC_XDCI_GCTL_PRT_CAP_OTG                          (3)
> > +#define DWC_XDCI_GCTL_RAMCLKSEL_MASK                       (0x000000C0)
> > +#define DWC_XDCI_GCTL_SCALE_DOWN_MODE_MASK
> (0x00000030)
> > +#define DWC_XDCI_GCTL_DISABLE_CLK_GATING_MASK
> (0x00000001)
> > +#define DWC_XDCI_GCTL_DISABLE_SCRAMB_MASK
> (0x00000008)
> > +
> > +#define DWC_XDCI_GSTS_REG                                  (0xC118)
> > +#define DWC_XDCI_GSNPSID_REG                               (0xC120)
> > +#define DWC_XDCI_GGPIO_REG                                 (0xC124)
> > +#define DWC_XDCI_GUID_REG                                  (0xC128)
> > +#define DWC_XDCI_GUCTL_REG                                 (0xC12C)
> > +#define DWC_XDCI_GBUSERRADDR                               (0xC130)
> > +
> > +//
> > +// Global Hardware Parameters Registers
> > +//
> > +#define DWC_XDCI_GHWPARAMS0_REG                            (0xC140)
> > +#define DWC_XDCI_GHWPARAMS1_REG                            (0xC144)
> > +#define DWC_XDCI_GHWPARAMS1_NUM_INT_MASK
> (0x1F8000)
> > +#define DWC_XDCI_GHWPARAMS1_NUM_INT_BIT_POS                (15)
> > +
> > +#define DWC_XDCI_GHWPARAMS2_REG                            (0xC148)
> > +#define DWC_XDCI_GHWPARAMS3_REG                            (0xC14C)
> > +#define DWC_XDCI_GHWPARAMS4_REG                            (0xC150)
> > +#define DWC_XDCI_GHWPARAMS4_CACHE_TRBS_PER_XFER_MASK
> (0x0000003F)
> > +#define DWC_XDCI_GHWPARAMS5_REG                            (0xC154)
> > +#define DWC_XDCI_GHWPARAMS6_REG                            (0xC158)
> > +#define DWC_XDCI_GHWPARAMS7_REG                            (0xC15C)
> > +#define DWC_XDCI_GHWPARAMS8_REG                            (0xC600)
> > +
> > +#define DWC_XDCI_GDBGFIFOSPACE_REG                         (0xC160)
> > +
> > +#define DWC_XDCI_GUSB2PHYCFG_REG(n)                        (0xC200 + (n <<
> 2))
> > +#define DWC_XDCI_GUSB2PHYCFG_ULPI_AUTO_RESUME_MASK
> (0x00008000)
> > +#define DWC_XDCI_GUSB2PHYCFG_SUSPEND_PHY_MASK
> (0x00000040)
> > +
> > +#define DWC_XDCI_GUSB3PIPECTL_REG(n)                       (0xC2C0 + (n << 2))
> > +#define DWC_XDCI_GUSB3PIPECTL_SUSPEND_PHY_MASK
> (0x00020000)
> > +
> > +#define DWC_XDCI_GTXFIFOSIZ_REG(n)                         (0xC300 + (n << 2))
> > +#define DWC_XDCI_GTXFIFOSIZ_START_ADDRESS_MASK
> (0xFFFF0000)
> > +#define DWC_XDCI_GTXFIFOSIZ_START_ADDRESS_BIT_POS          (16)
> > +#define DWC_XDCI_GRXFIFOSIZ_REG(n)                         (0xC380 + (n << 2))
> > +
> > +//
> > +// Global Event Buffer Registers
> > +//
> > +#define DWC_XDCI_GEVNTADR_REG(n)                           (0xC400 + (n << 4))
> > +#define DWC_XDCI_EVNTSIZ_REG(n)                            (0xC408 + (n << 4))
> > +#define DWC_XDCI_EVNTSIZ_MASK                              (0x0000FFFF)
> > +#define DWC_XDCI_EVNT_INTR_MASK                            (0x80000000)
> > +#define DWC_XDCI_EVNTCOUNT_REG(n)                          (0xC40C + (n << 4))
> > +#define DWC_XDCI_EVNTCOUNT_MASK                            (0x0000FFFF)
> > +
> > +//
> > +// Device Configuration Register and Bit Definitions
> > +//
> > +#define DWC_XDCI_DCFG_REG                                  (0xC700)
> > +#define DWC_XDCI_DCFG_LPM_CAPABLE_MASK                     (0x00400000)
> > +#define DWC_XDCI_DCFG_DEV_ADDRESS_MASK                     (0x000003F8)
> > +#define DWC_XDCI_DCFG_DEV_ADDRESS_BIT_POS                  (3)
> > +#define DWC_XDCI_DCFG_DESIRED_DEV_SPEED_MASK
> (0x00000007)
> > +#define DWC_XDCI_DCFG_DESIRED_SS_SPEED                     (0x00000004)
> > +#define DWC_XDCI_DCFG_DESIRED_FS_SPEED                     (0x00000001)
> > +#define DWC_XDCI_DCFG_DESIRED_HS_SPEED                     (0x00000000)
> > +
> > +//
> > +// Device Control Register
> > +//
> > +#define DWC_XDCI_DCTL_REG                                  (0xC704)
> > +#define DWC_XDCI_DCTL_RUN_STOP_MASK                        (0x80000000)
> > +#define DWC_XDCI_DCTL_RUN_STOP_BIT_POS                     (31)
> > +#define DWC_XDCI_DCTL_CSFTRST_MASK                         (0x40000000)
> > +#define DWC_XDCI_DCTL_CSFTRST_BIT_POS                      (30)
> > +#define DWC_XDCI_DCTL_KEEP_CONNECT_MASK                    (0x00080000)
> > +#define DWC_XDCI_DCTL_KEEP_CONNECT_BIT_POS                 (19)
> > +#define DWC_XDCI_DCTL_CSFTRST_BIT_POS                      (30)
> > +#define DWC_XDCI_DCTL_STATE_CHANGE_REQ_MASK
> (0x000001E0)
> > +#define DWC_XDCI_DCTL_STATE_CHANGE_REQ_BIT_POS             (5)
> > +#define DWC_XDCI_DCTL_STATE_CHANGE_REQ_NO_ACTION           (1)
> > +#define DWC_XDCI_DCTL_STATE_CHANGE_REQ_SS_DISABLED         (4)
> > +#define DWC_XDCI_DCTL_STATE_CHANGE_REQ_RX_DETECT           (5)
> > +#define DWC_XDCI_DCTL_STATE_CHANGE_REQ_SS_INACTIVE         (6)
> > +#define DWC_XDCI_DCTL_STATE_CHANGE_REQ_RECOVERY            (8)
> > +#define DWC_XDCI_DCTL_STATE_CHANGE_REQ_COMPLIANCE          (10)
> > +#define DWC_XDCI_DCTL_STATE_CHANGE_REQ_REMOTE_WAKEUP       (8)
> > +
> > +//
> > +// Device Event Enable Register
> > +//
> > +#define DWC_XDCI_DEVTEN_REG                                (0xC708)
> > +#define DWC_XDCI_DEVTEN_DISCONN_DET_EN_MASK
> (0x00000001)
> > +#define DWC_XDCI_DEVTEN_RESET_DET_EN_MASK
> (0x00000002)
> > +#define DWC_XDCI_DEVTEN_CONN_DONE_DET_EN_MASK
> (0x00000004)
> > +#define DWC_XDCI_DEVTEN_LINK_STATE_CHANGE_DET_EN_MASK
> (0x00000008)
> > +#define DWC_XDCI_DEVTEN_RESUME_WAKEUP_DET_EN_MASK
> (0x00000010)
> > +#define DWC_XDCI_DEVTEN_HIBERNATION_REQ_EN_MASK
> (0x00000020)
> > +#define DWC_XDCI_DEVTEN_U3L2L1_DET_EN_MASK
> (0x00000040)
> > +#define DWC_XDCI_DEVTEN_SOF_DET_EN_MASK                    (0x00000080)
> > +#define DWC_XDCI_DEVTEN_ERRATIC_ERR_DET_EN_MASK
> (0x00000200)
> > +#define DWC_XDCI_DEVTEN_VNDR_DEV_TST_RX_DET_EN_MASK
> (0x00001000)
> > +
> > +#define DWC_XDCI_DEVTEN_DEVICE_INTS
> (DWC_XDCI_DEVTEN_DISCONN_DET_EN_MASK | \
> > +        DWC_XDCI_DEVTEN_RESET_DET_EN_MASK |
> DWC_XDCI_DEVTEN_CONN_DONE_DET_EN_MASK | \
> > +        DWC_XDCI_DEVTEN_LINK_STATE_CHANGE_DET_EN_MASK |
> DWC_XDCI_DEVTEN_RESUME_WAKEUP_DET_EN_MASK | \
> > +        DWC_XDCI_DEVTEN_HIBERNATION_REQ_EN_MASK |
> DWC_XDCI_DEVTEN_U3L2L1_DET_EN_MASK | \
> > +        DWC_XDCI_DEVTEN_ERRATIC_ERR_DET_EN_MASK)
> > +
> > +#define DWC_XDCI_EVENT_BUFF_BULK_STREAM_ID_MASK
> (0xFFFF0000)
> > +#define DWC_XDCI_EVENT_BUFF_ISOCH_UFRAME_NUM_MASK
> (0xFFFF0000)
> > +#define DWC_XDCI_EVENT_BUFF_EP_CMD_TYPE_MASK
> (0x0F000000)
> > +#define DWC_XDCI_EVENT_BUFF_EP_XFER_RES_INDEX_MASK
> (0x007F0000)
> > +#define DWC_XDCI_EVENT_BUFF_EP_XFER_ACTIVE_MASK
> (0x00008000)
> > +#define DWC_XDCI_EVENT_BUFF_EP_CTRL_DATA_REQ_MASK
> (0x00001000)
> > +#define DWC_XDCI_EVENT_BUFF_EP_CTRL_STATUS_REQ_MASK
> (0x00002000)
> > +#define DWC_XDCI_EVENT_BUFF_EP_LST_MASK                    (0x00008000)
> > +#define DWC_XDCI_EVENT_BUFF_EP_MISSED_ISOCH_MASK
> (0x00008000)
> > +#define DWC_XDCI_EVENT_BUFF_EP_IOC_MASK                    (0x00004000)
> > +#define DWC_XDCI_EVENT_BUFF_EP_LAST_PKT_MASK
> (0x00002000)
> > +#define DWC_XDCI_EVENT_BUFF_EP_STREAM_NOT_FND_MASK
> (0x00002000)
> > +#define DWC_XDCI_EVENT_BUFF_EP_STREAM_FND_MASK
> (0x00001000)
> > +#define DWC_XDCI_EVENT_BUFF_EP_ERR_NO_RES_MASK
> (0x00001000)
> > +#define DWC_XDCI_EVENT_BUFF_EP_INVALID_RES_MASK
> (0x00001000)
> > +
> > +#define DWC_XDCI_EVENT_BUFF_EP_EVENT_MASK
> (0x000003C0)
> > +#define DWC_XDCI_EVENT_BUFF_EP_EVENT_BIT_POS               (6)
> > +#define DWC_XDCI_EVENT_BUFF_EP_XFER_CMPLT                  (1)
> > +#define DWC_XDCI_EVENT_BUFF_EP_XFER_IN_PROGRESS            (2)
> > +#define DWC_XDCI_EVENT_BUFF_EP_XFER_NOT_READY              (3)
> > +#define DWC_XDCI_EVENT_BUFF_EP_STREAM_EVENT                (6)
> > +#define DWC_XDCI_EVENT_BUFF_EP_CMD_CMPLT                   (7)
> > +
> > +#define DWC_XDCI_EVENT_BUFF_EP_NUM_MASK
> (0x0000003E)
> > +#define DWC_XDCI_EVENT_BUFF_EP_NUM_BIT_POS                 (1)
> > +
> > +#define DWC_XDCI_EVENT_BUFF_EP_EVENT_STATUS_MASK
> (0x0000F000)
> > +
> > +
> > +#define DWC_XDCI_EVENT_BUFF_DEV_HIRD_MASK
> (0x01E00000)
> > +#define DWC_XDCI_EVENT_BUFF_DEV_HIRD_BIT_POS               (21)
> > +#define DWC_XDCI_EVENT_BUFF_DEV_SS_EVENT_MASK
> (0x00100000)
> > +#define DWC_XDCI_EVENT_BUFF_DEV_LINK_STATE_MASK
> (0x000F0000)
> > +#define DWC_XDCI_EVENT_BUFF_DEV_LINK_STATE_BIT_POS         (16)
> > +
> > +#define DWC_XDCI_EVENT_BUFF_DEV_EVT_MASK                   (0x00000F00)
> > +#define DWC_XDCI_EVENT_BUFF_DEV_EVT_BIT_POS                (8)
> > +#define DWC_XDCI_EVENT_BUFF_DEV_TST_LMP_RX_EVENT           (12)
> > +#define DWC_XDCI_EVENT_BUFF_DEV_BUFF_OVFL_EVENT            (11)
> > +#define DWC_XDCI_EVENT_BUFF_DEV_CMD_CMPLT_EVENT            (10)
> > +#define DWC_XDCI_EVENT_BUFF_DEV_ERRATIC_ERR_EVENT          (9)
> > +#define DWC_XDCI_EVENT_BUFF_DEV_SOF_EVENT                  (7)
> > +#define DWC_XDCI_EVENT_BUFF_DEV_HBRNTN_REQ_EVENT           (5)
> > +#define DWC_XDCI_EVENT_BUFF_DEV_WKUP_EVENT                 (4)
> > +#define DWC_XDCI_EVENT_BUFF_DEV_STATE_CHANGE_EVENT         (3)
> > +#define DWC_XDCI_EVENT_BUFF_DEV_CONN_DONE_EVENT            (2)
> > +#define DWC_XDCI_EVENT_BUFF_DEV_USB_RESET_EVENT            (1)
> > +#define DWC_XDCI_EVENT_BUFF_DEV_DISCONN_EVENT              (0)
> > +
> > +#define DWC_XDCI_EVENT_DEV_MASK                            (0x00000001)
> > +
> > +//
> > +// Device Status Register and Bit Definitions
> > +//
> > +#define DWC_XDCI_DSTS_REG                                  (0xC70C)
> > +#define DWC_XDCI_DSTS_DEV_CTRL_HALTED_MASK
> (0x00400000)
> > +#define DWC_XDCI_DSTS_DEV_CTRL_HALTED_BIT_POS              (22)
> > +#define DWC_XDCI_DSTS_CORE_IDLE                            (1 << 23)
> > +#define DWC_XDCI_DSTS_CONN_SPEED_MASK                      (0x00000007)
> > +#define DWC_XDCI_DSTS_LINK_STATE_MASK                      (0x003C0000)
> > +#define DWC_XDCI_DSTS_LINK_STATE_DISCONNECT
> (0x00100000)
> > +
> > +//
> > +// Device Generic Command Parameter Register
> > +//
> > +#define DWC_XDCI_DGCMD_PARAM_REG                           (0xC710)
> > +#define DWC_XDCI_DGCMD_PARAM_TX_FIFO_NUM_MASK
> (0x0000001F)
> > +#define DWC_XDCI_DGCMD_PARAM_TX_FIFO_DIR_MASK
> (0x00000020)
> > +#define DWC_XDCI_DGCMD_PARAM_TX_FIFO_DIR_BIT_POS           (5)
> > +
> > +//
> > +// Device Generic Command Register
> > +//
> > +#define DWC_XDCI_DGCMD_REG                                 (0xC714)
> > +#define DWC_XDCI_DGCMD_CMD_STATUS_MASK
> (0x00008000)
> > +#define DWC_XDCI_DGCMD_CMD_ACTIVE_MASK
> (0x00000400)
> > +#define DWC_XDCI_DGCMD_CMD_IOC_MASK                        (0x00000100)
> > +#define DWC_XDCI_DGCMD_CMD_TYPE_MASK                       (0x000000FF)
> > +#define DWC_XDCI_DGCMD_CMD_SET_PERIODIC_PARAMS             (0x2)
> > +#define DWC_XDCI_DGCMD_CMD_SET_SCRATCH_PAD_BUFF_ARR_LO
> (0x4)
> > +#define DWC_XDCI_DGCMD_CMD_SET_SCRATCH_PAD_BUFF_ARR_HI
> (0x5)
> > +#define DWC_XDCI_DGCMD_CMD_XMIT_DEVICE_NOTIFICATION
> (0x7)
> > +#define DWC_XDCI_DGCMD_CMD_SEL_FIFO_FLUSH                  (0x9)
> > +#define DWC_XDCI_DGCMD_CMD_ALL_FIFO_FLUSH                  (0xA)
> > +#define DWC_XDCI_DGCMD_CMD_SET_EP_NRDY                     (0xC)
> > +#define DWC_XDCI_DGCMD_CMD_RUN_SOC_BUS_LPBK                (0x10)
> > +
> > +//
> > +// Device Active USB EP Enable Register
> > +//
> > +#define DWC_XDCI_EP_DALEPENA_REG                           (0xC720)
> > +
> > +//
> > +// Device Physical EP CMD Param 2 Register. Value is 32-bit
> > +//
> > +#define DWC_XDCI_EPCMD_PARAM2_REG(n)                       (0xC800 + (n <<
> 4))
> > +
> > +//
> > +// Device Physical EP CMD Param 1 Register. Value is 32-bit
> > +//
> > +#define DWC_XDCI_EPCMD_PARAM1_REG(n)                       (0xC804 + (n <<
> 4))
> > +
> > +//
> > +// Device Physical EP CMD Param 0 Register. Value is 32-bit
> > +//
> > +#define DWC_XDCI_EPCMD_PARAM0_REG(n)                       (0xC808 + (n <<
> 4))
> > +
> > +//
> > +// Device Physical EP Command Registers and Bit Definitions
> > +//
> > +#define DWC_XDCI_EPCMD_REG(n)                              (0xC80C + (n << 4))
> > +#define DWC_XDCI_EPCMD_RES_IDX_MASK                        (0x007F0000)
> > +#define DWC_XDCI_EPCMD_RES_IDX_BIT_POS                     (16)
> > +#define DWC_XDCI_EPCMD_CMDTYPE_MASK                        (0x0000000F)
> > +#define DWC_XDCI_EPCMD_SET_EP_CONFIG                       (0x1)
> > +#define DWC_XDCI_EPCMD_SET_EP_XFER_RES_CONFIG              (0x2)
> > +#define DWC_XDCI_EPCMD_GET_EP_STATE                        (0x3)
> > +#define DWC_XDCI_EPCMD_SET_STALL                           (0x4)
> > +#define DWC_XDCI_EPCMD_CLEAR_STALL                         (0x5)
> > +#define DWC_XDCI_EPCMD_START_XFER                          (0x6)
> > +#define DWC_XDCI_EPCMD_UPDATE_XFER                         (0x7)
> > +#define DWC_XDCI_EPCMD_END_XFER                            (0x8)
> > +#define DWC_XDCI_EPCMD_START_NEW_CONFIG                    (0x9)
> > +
> > +#define DWC_XDCI_EPCMD_CMD_IOC_MASK                        (0x00000100)
> > +#define DWC_XDCI_EPCMD_CMD_ACTIVE_MASK                     (0x00000400)
> > +#define DWC_XDCI_EPCMD_HIGH_PRIO_MASK                      (0x00000800)
> > +#define DWC_XDCI_EPCMD_FORCE_RM_MASK                       (0x00000800)
> > +
> > +//
> > +// Command status and parameter values same as event status and
> parameters values
> > +//
> > +#define DWC_XDCI_EPCMD_CMD_STATUS_MASK
> (0x0000F000)
> > +
> > +//
> > +// Command Params bit masks
> > +//
> > +#define DWC_XDCI_PARAM1_SET_EP_CFG_FIFO_BASED_MASK
> (0x80000000)
> > +#define DWC_XDCI_PARAM1_SET_EP_CFG_BULK_BASED_MASK
> (0x40000000)
> > +#define DWC_XDCI_PARAM1_SET_EP_CFG_EP_NUM_MASK
> (0x3C000000)
> > +#define DWC_XDCI_PARAM1_SET_EP_CFG_EP_DIR_MASK
> (0x02000000)
> > +#define DWC_XDCI_PARAM1_SET_EP_CFG_STRM_CAP_MASK
> (0x01000000)
> > +#define DWC_XDCI_PARAM1_SET_EP_CFG_BINTM1_MASK
> (0x00FF0000)
> > +#define DWC_XDCI_PARAM1_SET_EP_CFG_BINTM1_BIT_POS          (16)
> > +#define DWC_XDCI_PARAM1_SET_EP_CFG_EBC_MASK
> (0x00008000)
> > +#define DWC_XDCI_PARAM1_SET_EP_CFG_EVT_EN_MASK
> (0x00003F00)
> > +#define DWC_XDCI_PARAM1_SET_EP_CFG_EVT_EN_BIT_POS          (8)
> > +#define DWC_XDCI_PARAM1_SET_EP_CFG_EVT_STRM_MASK
> (0x00002000)
> > +#define DWC_XDCI_PARAM1_SET_EP_CFG_EVT_XFER_NRDY_MASK
> (0x00000400)
> > +#define DWC_XDCI_PARAM1_SET_EP_CFG_EVT_XFER_IN_PRG_MASK
> (0x00000200)
> > +#define DWC_XDCI_PARAM1_SET_EP_CFG_EVT_XFER_CMPLT_MASK
> (0x00000100)
> > +#define DWC_XDCI_PARAM1_SET_EP_CFG_INTR_NUM_MASK
> (0x0000001F)
> > +
> > +//
> > +// CMD 1 param 0
> > +//
> > +#define DWC_XDCI_PARAM0_SET_EP_CFG_ACTN_MASK
> (0xC0000000)
> > +#define DWC_XDCI_PARAM0_SET_EP_CFG_ACTN_BIT_POS            (30)
> > +#define DWC_XDCI_PARAM0_SET_EP_CFG_ACTN_INIT_STATE         (0)
> > +#define DWC_XDCI_PARAM0_SET_EP_CFG_ACTN_RESTORE_ST         (1)
> > +#define DWC_XDCI_PARAM0_SET_EP_CFG_ACTN_MDFY_STATE         (2)
> > +#define DWC_XDCI_PARAM0_SET_EP_CFG_ACTN_NONE               (3)
> > +#define DWC_XDCI_PARAM0_SET_EP_CFG_BRST_SIZE_MASK
> (0x03C00000)
> > +#define DWC_XDCI_PARAM0_SET_EP_CFG_BRST_SIZE_BIT_POS       (22)
> > +#define DWC_XDCI_PARAM0_SET_EP_CFG_FIFO_NUM_MASK
> (0x003E0000)
> > +#define DWC_XDCI_PARAM0_SET_EP_CFG_FIFO_NUM_BIT_POS        (17)
> > +#define DWC_XDCI_PARAM0_SET_EP_CFG_MPS_MASK
> (0x00003FF8)
> > +#define DWC_XDCI_PARAM0_SET_EP_CFG_MPS_BIT_POS             (3)
> > +#define DWC_XDCI_PARAM0_SET_EP_CFG_EP_TYPE_MASK
> (0x00000006)
> > +#define DWC_XDCI_PARAM0_SET_EP_CFG_EP_TYPE_BIT_POS         (1)
> > +#define DWC_XDCI_PARAM0_EP_TYPE_CTRL                       (0)
> > +#define DWC_XDCI_PARAM0_EP_TYPE_ISOCH                      (1)
> > +#define DWC_XDCI_PARAM0_EP_TYPE_BULK                       (2)
> > +#define DWC_XDCI_PARAM0_EP_TYPE_INTR                       (3)
> > +
> > +//
> > +// CMD 1 param 1
> > +//
> > +#define DWC_XDCI_PARAM1_SET_EP_CFG_BULK_BASED_MASK
> (0x40000000)
> > +#define DWC_XDCI_PARAM1_SET_EP_CFG_EP_NUM_MASK
> (0x3C000000)
> > +#define DWC_XDCI_PARAM1_SET_EP_CFG_EP_NUM_BIT_POS          (26)
> > +#define DWC_XDCI_PARAM1_SET_EP_CFG_EP_DIR_MASK
> (0x02000000)
> > +#define DWC_XDCI_PARAM1_SET_EP_CFG_EP_DIR_BIT_POS          (25)
> > +#define DWC_XDCI_PARAM1_SET_EP_CFG_STRM_CAP_MASK
> (0x01000000)
> > +#define DWC_XDCI_PARAM1_SET_EP_CFG_BINTM1_MASK
> (0x00FF0000)
> > +#define DWC_XDCI_PARAM1_SET_EP_CFG_BINTM1_BIT_POS          (16)
> > +#define DWC_XDCI_PARAM1_SET_EP_CFG_EBC_MASK
> (0x00008000)
> > +#define DWC_XDCI_PARAM1_SET_EP_CFG_EVT_EN_MASK
> (0x00003F00)
> > +#define DWC_XDCI_PARAM1_SET_EP_CFG_EVT_EN_BIT_POS          (8)
> > +#define DWC_XDCI_PARAM1_SET_EP_CFG_EVT_STRM_MASK
> (0x00002000)
> > +#define DWC_XDCI_PARAM1_SET_EP_CFG_EVT_XFER_NRDY_MASK
> (0x00000400)
> > +#define DWC_XDCI_PARAM1_SET_EP_CFG_EVT_XFER_IN_PRG_MASK
> (0x00000200)
> > +#define DWC_XDCI_PARAM1_SET_EP_CFG_EVT_XFER_CMPLT_MASK
> (0x00000100)
> > +#define DWC_XDCI_PARAM1_SET_EP_CFG_INTR_NUM_MASK
> (0x0000001F)
> > +
> > +//
> > +// CMD 2 param 0
> > +//
> > +#define DWC_XDCI_PARAM0_SET_EP_XFER_RES_NUM_MASK
> (0x0000FFFF)
> > +
> > +//
> > +// CMD 3 param 2
> > +//
> > +#define DWC_XDCI_PARAM2_GET_EP_STATE_MASK
> (0xFFFFFFFF)
> > +
> > +//
> > +// CMD 6 param 1
> > +//
> > +#define DWC_XDCI_PARAM1_STRT_XFER_TD_ADDR_LO_MASK
> (0xFFFFFFFF)
> > +
> > +//
> > +// CMD 6 param 0
> > +//
> > +#define DWC_XDCI_PARAM0_STRT_XFER_TD_ADDR_HI_MASK
> (0xFFFFFFFF)
> > +
> > +//
> > +// Transfer Request Block Fields' Bit Definitions
> > +//
> > +#define DWC_XDCI_TRB_BUFF_SIZE_MASK                        (0x00FFFFFF)
> > +#define DWC_XDCI_TRB_PCM1_MASK                             (0x03000000)
> > +#define DWC_XDCI_TRB_PCM1_BIT_POS                          (24)
> > +#define DWC_XDCI_TRB_STATUS_MASK                           (0xF0000000)
> > +#define DWC_XDCI_TRB_STATUS_BIT_POS                        (28)
> > +#define DWC_XDCI_TRB_STATUS_OK                             (0)
> > +#define DWC_XDCI_TRB_STATUS_MISSED_ISOCH                   (1)
> > +#define DWC_XDCI_TRB_STATUS_SETUP_PENDING                  (2)
> > +
> > +#define DWC_XDCI_TRB_CTRL_HWO_MASK                         (0x00000001)
> > +#define DWC_XDCI_TRB_CTRL_LST_TRB_MASK                     (0x00000002)
> > +#define DWC_XDCI_TRB_CTRL_LST_TRB_BIT_POS                  (1)
> > +#define DWC_XDCI_TRB_CTRL_CHAIN_BUFF_MASK
> (0x00000004)
> > +#define DWC_XDCI_TRB_CTRL_CHAIN_BUFF_BIT_POS               (2)
> > +#define DWC_XDCI_TRB_CTRL_CSP_MASK                         (0x00000008)
> > +#define DWC_XDCI_TRB_CTRL_CSP_BIT_POS                      (3)
> > +#define DWC_XDCI_TRB_CTRL_TYPE_MASK                        (0x000003F0)
> > +#define DWC_XDCI_TRB_CTRL_TYPE_BIT_POS                     (4)
> > +#define DWC_XDCI_TRB_CTRL_TYPE_NORMAL                      (1)
> > +#define DWC_XDCI_TRB_CTRL_TYPE_SETUP                       (2)
> > +#define DWC_XDCI_TRB_CTRL_TYPE_STATUS2                     (3)
> > +#define DWC_XDCI_TRB_CTRL_TYPE_STATUS3                     (4)
> > +#define DWC_XDCI_TRB_CTRL_TYPE_DATA                        (5)
> > +#define DWC_XDCI_TRB_CTRL_TYPE_ISOCH_FIRST                 (6)
> > +#define DWC_XDCI_TRB_CTRL_TYPE_ISOCH                       (7)
> > +#define DWC_XDCI_TRB_CTRL_TYPE_LINK_TRB                    (8)
> > +#define DWC_XDCI_TRB_CTRL_IOSP_MISOCH_MASK
> (0x00000400)
> > +#define DWC_XDCI_TRB_CTRL_IOSP_MISOCH_BIT_POS              (10)
> > +#define DWC_XDCI_TRB_CTRL_IOC_MASK                         (0x00000800)
> > +#define DWC_XDCI_TRB_CTRL_IOC_BIT_POS                      (11)
> > +#define DWC_XDCI_TRB_CTRL_STRM_ID_SOF_NUM_MASK
> (0x3FFFC000)
> > +#define DWC_XDCI_TRB_CTRL_STRM_ID_SOF_BIT_POS              (14)
> > +
> > +#define DWC_XDCI_DEV_EVENT_DEFAULT_SIZE_IN_BYTES           (4)
> > +#define DWC_XDCI_DEV_EVENT_TST_LMP_SIZE_IN_BYTES           (12)
> > +
> > +typedef enum {
> > +  EPCMD_SET_EP_CONFIG = 1,
> > +  EPCMD_SET_EP_XFER_RES_CONFIG,
> > +  EPCMD_GET_EP_STATE,
> > +  EPCMD_SET_STALL,
> > +  EPCMD_CLEAR_STALL,
> > +  EPCMD_START_XFER,
> > +  EPCMD_UPDATE_XFER,
> > +  EPCMD_END_XFER,
> > +  EPCMD_START_NEW_CONFIG = 9
> > +} DWC_XDCI_ENDPOINT_CMD;
> > +
> > +typedef enum {
> > +  ON = 0,
> > +  SLEEP = 2,
> > +  SUSPEND,
> > +  DISCONNECTED,
> > +  EARLY_SUSPEND,
> > +  RESET = 14,
> > +  RESUME = 15
> > +} DWC_XDCI_HS_LINK_STATE;
> > +
> > +typedef enum {
> > +  TRBCTL_NORMAL = 1,
> > +  TRBCTL_SETUP,
> > +  TRBCTL_2_PHASE,
> > +  TRBCTL_3_PHASE,
> > +  TRBCTL_CTRL_DATA_PHASE,
> > +  TRBCTL_ISOCH_FIRST,
> > +  TRBCTL_ISOCH,
> > +  TRBCTL_LINK
> > +} DWC_XDCI_TRB_CONTROL;
> > +
> > +//
> > +// DWC XDCI Endpoint Commands Parameters struct
> > +//
> > +typedef struct {
> > +  UINT32 Param2;
> > +  UINT32 Param1;
> > +  UINT32 Param0;
> > +} DWC_XDCI_ENDPOINT_CMD_PARAMS;
> > +
> > +//
> > +// Event Buffer Struct
> > +//
> > +typedef struct {
> > +  UINT32 Event;
> > +  UINT32 DevTstLmp1;
> > +  UINT32 DevTstLmp2;
> > +  UINT32 Reserved;
> > +} DWC_XDCI_EVENT_BUFFER;
> > +
> > +//
> > +// Transfer Request Block
> > +//
> > +typedef struct {
> > +  UINT32 BuffPtrLow;
> > +  UINT32 BuffPtrHigh;
> > +  UINT32 LenXferParams;
> > +  UINT32 TrbCtrl;
> > +} DWC_XDCI_TRB;
> > +
> > +typedef struct  {
> > +  USB_EP_INFO       EpInfo;
> > +  DWC_XDCI_TRB      *Trb;
> > +  USB_XFER_REQUEST  XferHandle;
> > +  UINT32            CurrentXferRscIdx;
> > +  VOID              *CoreHandle;
> > +  USB_EP_STATE      State;
> > +  USB_EP_STATE      OrgState;
> > +  BOOLEAN           CheckFlag;
> > +} DWC_XDCI_ENDPOINT;
> > +
> > +typedef struct {
> > +  //
> > +  // CbEventParams must be copied over by upper layer if
> > +  // it defers event processing
> > +  //
> > +  USB_DEVICE_CALLBACK_PARAM CbEventParams;
> > +
> > +  //
> > +  // Callback function list
> > +  //
> > +  USB_DEVICE_CALLBACK_FUNC  DevDisconnectCallback;
> > +  USB_DEVICE_CALLBACK_FUNC  DevBusResetCallback;
> > +  USB_DEVICE_CALLBACK_FUNC  DevResetDoneCallback;
> > +  USB_DEVICE_CALLBACK_FUNC  DevLinkStateCallback;
> > +  USB_DEVICE_CALLBACK_FUNC  DevWakeupCallback;
> > +  USB_DEVICE_CALLBACK_FUNC  DevHibernationCallback;
> > +  USB_DEVICE_CALLBACK_FUNC  DevSofCallback;
> > +  USB_DEVICE_CALLBACK_FUNC  DevErraticErrCallback;
> > +  USB_DEVICE_CALLBACK_FUNC  DevCmdCmpltCallback;
> > +  USB_DEVICE_CALLBACK_FUNC  DevBuffOvflwCallback;
> > +  USB_DEVICE_CALLBACK_FUNC  DevTestLmpRxCallback;
> > +  USB_DEVICE_CALLBACK_FUNC  DevSetupPktReceivedCallback;
> > +  USB_DEVICE_CALLBACK_FUNC  DevXferNrdyCallback;
> > +  USB_DEVICE_CALLBACK_FUNC  DevXferDoneCallback;
> > +} USB_DEV_CALLBACK_LIST;
> > +
> > +typedef struct {
> > +  VOID                     *ParentHandle;                                       // Pointer to the
> parent this driver is associated
> > +  USB_CONTROLLER_ID        Id;                                                  // ID of the
> controllers supported in our DCD
> > +  USB_SPEED                DesiredSpeed;                                        // Desired SS,
> HS, FS or LS Speeds for the core
> > +  USB_ROLE                 Role;                                                // Desired role i.e.
> host, Device or OTG
> > +  USB_SPEED                ActualSpeed;                                         // Actual Speed
> > +  USB_DEVICE_STATE         DevState;                                            // Device state
> > +  UINT32                   BaseAddress;                                         // Register Base
> address
> > +  UINT32                   Flags;                                               // Init flags
> > +  UINT32                   MaxDevIntLines;                                      // One event
> Buffer per interrupt line
> > +  DWC_XDCI_EVENT_BUFFER    EventBuffers
> [DWC_XDCI_MAX_EVENTS_PER_BUFFER * 2];   // Event Buffer pool
> > +  DWC_XDCI_EVENT_BUFFER    *AlignedEventBuffers;                                //
> Aligned event Buffer pool
> > +  DWC_XDCI_EVENT_BUFFER    *CurrentEventBuffer;                                 //
> Current event Buffer address
> > +  DWC_XDCI_TRB             UnalignedTrbs [(DWC_XDCI_MAX_ENDPOINTS +
> 1) * DWC_XDCI_TRB_NUM];    // TRBs.
> > +  DWC_XDCI_TRB             *Trbs;                                               // 16-bytes
> aligned TRBs.
> > +  DWC_XDCI_ENDPOINT        EpHandles [DWC_XDCI_MAX_ENDPOINTS];
> // EPs
> > +  UINT8                    DefaultSetupBuffer [DWC_XDCI_SETUP_BUFF_SIZE * 2];
> // Unaligned setup Buffer
> > +  UINT8                    *AlignedSetupBuffer;                                 // Aligned setup
> Buffer. Aligned to 8-byte boundary
> > +  UINT8                    MiscBuffer [528];                                    // Unaligned misc
> Buffer
> > +  UINT8                    *AlignedMiscBuffer;                                  // Aligned misc
> Buffer
> > +  UINT32                   LinkState;                                           // Link state
> > +  UINT32                   HirdVal;                                             // HIRD value
> > +  USB_DEV_CALLBACK_LIST    EventCallbacks;
> > +  volatile BOOLEAN         InterrupProcessing;
> > +} XDCI_CORE_HANDLE;
> > +
> > +//
> > +// DWC XDCI API prototypes
> > +//
> > +EFI_STATUS
> > +EFIAPI
> > +DwcXdciCoreInit (
> > +  IN USB_DEV_CONFIG_PARAMS    *ConfigParams,
> > +  IN VOID                     *ParentHandle,
> > +  IN VOID                     **CoreHandle
> > +  );
> > +
> > +EFI_STATUS
> > +EFIAPI
> > +DwcXdciCoreDeinit (
> > +  IN VOID      *CoreHandle,
> > +  IN UINT32    flags
> > +  );
> > +
> > +EFI_STATUS
> > +EFIAPI
> > +DwcXdciCoreRegisterCallback (
> > +  IN VOID                      *CoreHandle,
> > +  IN USB_DEVICE_EVENT_ID       Event,
> > +  IN USB_DEVICE_CALLBACK_FUNC  CallbackFunc
> > +  );
> > +
> > +EFI_STATUS
> > +EFIAPI
> > +DwcXdciCoreUnregisterCallback (
> > +  IN VOID                   *CoreHandle,
> > +  IN USB_DEVICE_EVENT_ID    Event
> > +  );
> > +
> > +EFI_STATUS
> > +EFIAPI
> > +DwcXdciCoreIsrRoutine (
> > +  IN VOID *CoreHandle
> > +  );
> > +
> > +EFI_STATUS
> > +EFIAPI
> > +DwcXdciCoreIsrRoutineTimerBased (
> > +  IN VOID *CoreHandle
> > +  );
> > +
> > +EFI_STATUS
> > +EFIAPI
> > +DwcXdciCoreConnect (
> > +  IN VOID    *CoreHandle
> > +  );
> > +
> > +EFI_STATUS
> > +EFIAPI
> > +DwcXdciCoreDisconnect (
> > +  IN VOID *CoreHandle
> > +  );
> > +
> > +EFI_STATUS
> > +EFIAPI
> > +DwcXdciCoreGetSpeed (
> > +  IN VOID         *CoreHandle,
> > +  IN USB_SPEED    *Speed
> > +  );
> > +
> > +EFI_STATUS
> > +EFIAPI
> > +DwcXdciCoreSetAddress (
> > +  IN VOID      *CoreHandle,
> > +  IN UINT32    Address
> > +  );
> > +
> > +EFI_STATUS
> > +EFIAPI
> > +DwcXdciCoreSetConfig (
> > +  IN VOID      *CoreHandle,
> > +  IN UINT32    ConfigNum
> > +  );
> > +
> > +EFI_STATUS
> > +EFIAPI
> > +DwcXdciSetLinkState (
> > +  IN VOID                        *CoreHandle,
> > +  IN USB_DEVICE_SS_LINK_STATE    State
> > +  );
> > +
> > +EFI_STATUS
> > +EFIAPI
> > +DwcXdciInitEp (
> > +  IN VOID           *CoreHandle,
> > +  IN USB_EP_INFO    *EpInfo
> > +  );
> > +
> > +EFI_STATUS
> > +EFIAPI
> > +DwcXdciEpEnable (
> > +  IN VOID           *CoreHandle,
> > +  IN USB_EP_INFO    *EpInfo
> > +  );
> > +
> > +EFI_STATUS
> > +EFIAPI
> > +DwcXdciEpDisable (
> > +  IN VOID           *CoreHandle,
> > +  IN USB_EP_INFO    *EpInfo
> > +  );
> > +
> > +EFI_STATUS
> > +EFIAPI
> > +DwcXdciEpStall (
> > +  IN VOID           *CoreHandle,
> > +  IN USB_EP_INFO    *EpInfo
> > +  );
> > +
> > +EFI_STATUS
> > +EFIAPI
> > +DwcXdciEpClearStall (
> > +  IN VOID           *CoreHandle,
> > +  IN USB_EP_INFO    *EpInfo
> > +  );
> > +
> > +EFI_STATUS
> > +EFIAPI
> > +DwcXdciEpSetNrdy (
> > +  IN VOID           *CoreHandle,
> > +  IN USB_EP_INFO    *EpInfo
> > +  );
> > +
> > +EFI_STATUS
> > +EFIAPI
> > +DwcXdciEp0ReceiveSetupPkt (
> > +  IN VOID     *CoreHandle,
> > +  IN UINT8    *Buffer
> > +  );
> > +
> > +EFI_STATUS
> > +EFIAPI
> > +DwcXdciEp0ReceiveStatusPkt (
> > +  IN VOID    *CoreHandle
> > +  );
> > +
> > +EFI_STATUS
> > +EFIAPI
> > +DwcXdciEp0SendStatusPkt (
> > +  IN VOID    *CoreHandle
> > +  );
> > +
> > +EFI_STATUS
> > +EFIAPI
> > +DwcXdciEpTxData (
> > +  IN VOID                *CoreHandle,
> > +  IN USB_XFER_REQUEST    *XferReq
> > +  );
> > +
> > +EFI_STATUS
> > +EFIAPI
> > +DwcXdciEpRxData(
> > +  IN VOID                *CoreHandle,
> > +  IN USB_XFER_REQUEST    *XferReq
> > +  );
> > +
> > +EFI_STATUS
> > +EFIAPI
> > +DwcXdciEpCancelTransfer (
> > +  IN VOID           *CoreHandle,
> > +  IN USB_EP_INFO    *EpInfo
> > +  );
> > +
> > +EFI_STATUS
> > +usbProcessDeviceResetDet (
> > +  IN XDCI_CORE_HANDLE    *CoreHandle
> > +  );
> > +
> > +EFI_STATUS
> > +usbProcessDeviceResetDone (
> > +  IN XDCI_CORE_HANDLE    *CoreHandle
> > +  );
> > +
> > +UINT32
> > +UsbGetPhysicalEpNum (
> > +  IN UINT32        EndpointNum,
> > +  IN USB_EP_DIR    EndpointDir
> > +  );
> > +
> > +UINT32
> > +UsbRegRead (
> > +  IN UINT32    Base,
> > +  IN UINT32    Offset
> > +  );
> > +
> > +VOID
> > +UsbRegWrite (
> > +  IN UINT32    Base,
> > +  IN UINT32    Offset,
> > +  IN UINT32    val
> > +  );
> > +
> > +EFI_STATUS
> > +UsbXdciCoreFlushEpFifo (
> > +  IN VOID           *CoreHandle,
> > +  IN USB_EP_INFO    *EpInfo
> > +  );
> > +#endif
> > +
> > diff --git
> a/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciDevice.c
> b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciDevice.c
> > new file mode 100644
> > index 0000000000..7c94de0a60
> > --- /dev/null
> > +++ b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciDevice.c
> > @@ -0,0 +1,695 @@
> > +/** @file
> > +  Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR>
> > +
> > +  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.
> > +
> > +**/
> > +
> > +#include <Library/UsbDeviceLib.h>
> > +#include "XdciCommon.h"
> > +#include "XdciDevice.h"
> > +#include "XdciInterface.h"
> > +#include "UsbDeviceMode.h"
> > +
> > +/**
> > +  This function is used to initialize the device controller
> > +  @configParams: Parameters from app to configure the core
> > +  @DevCoreHandle: Return parameter for upper layers to use
> > +  for all HW-independent APIs
> > +
> > +**/
> > +EFI_STATUS
> > +UsbDeviceInit (
> > +  IN USB_DEV_CONFIG_PARAMS    *ConfigParams,
> > +  IN OUT VOID                 **DevCoreHandle
> > +  )
> > +{
> > +  USB_DEV_CORE    *DevCorePtr;
> > +  EFI_STATUS      Status = EFI_INVALID_PARAMETER;
> > +
> > +  DEBUG ((DEBUG_INFO, "Call UsbDeviceInit start\n"));
> > +
> > +  //
> > +  // Allocate device handle
> > +  //
> > +  DevCorePtr = AllocateZeroPool (sizeof (USB_DEV_CORE));
> > +  DEBUG ((DEBUG_INFO, "device handle = 0x%x\n", DevCorePtr));
> > +
> > +  if (DevCorePtr == NULL) {
> > +    DEBUG ((DEBUG_INFO, "UsbDeviceInit. ERROR: Failed to allocate
> memory\n"));
> > +    return EFI_OUT_OF_RESOURCES;
> > +  }
> > +
> > +  DEBUG ((DEBUG_INFO, "call UsbDeviceGetCoreDriver, ID=%x, \n",
> ConfigParams->ControllerId));
> > +
> > +  //
> > +  // Get the driver for this USB device core
> > +  //
> > +  DevCorePtr->CoreDriver = UsbDeviceGetCoreDriver(ConfigParams-
> >ControllerId);
> > +  if (DevCorePtr->CoreDriver != NULL) {
> > +    DEBUG ((DEBUG_INFO, "call DevCoreInit\n"));
> > +    Status = DevCorePtr->CoreDriver->DevCoreInit(
> > +                                        ConfigParams,
> > +                                        (VOID*)DevCorePtr,
> > +                                        &DevCorePtr->ControllerHandle);
> > +  } else {
> > +    DEBUG ((DEBUG_INFO, "UsbDeviceInit. ERROR: Driver not found\n"));
> > +    return EFI_INVALID_PARAMETER;
> > +  }
> > +
> > +  *DevCoreHandle = (VOID *)DevCorePtr;
> > +  return Status;
> > +}
> > +
> > +/**
> > +  This function is used to de-initialize the device controller
> > +  @DevCoreHandle: Handle to HW-independent APIs for device
> > +  controller
> > +  @flags: Flags indicating what type of de-initialization is required
> > +
> > +**/
> > +EFI_STATUS
> > +UsbDeviceDeinit (
> > +  IN VOID      *DevCoreHandle,
> > +  IN UINT32    Flags
> > +  )
> > +{
> > +  USB_DEV_CORE    *Core = (USB_DEV_CORE *)DevCoreHandle;
> > +  EFI_STATUS      Status = EFI_DEVICE_ERROR;
> > +
> > +  if (Core == NULL) {
> > +    DEBUG ((DEBUG_INFO, "UsbDeviceDeinit: ERROR: INVALID
> HANDLE\n"));
> > +  } else {
> > +    if (Core->CoreDriver != NULL) {
> > +      Status = Core->CoreDriver->DevCoreDeinit(
> > +                                    Core->ControllerHandle,
> > +                                    Flags
> > +                                    );
> > +      FreePool(DevCoreHandle);
> > +    } else {
> > +      DEBUG ((DEBUG_INFO, "UsbDeviceDeinit: Driver not found\n"));
> > +      Status = EFI_INVALID_PARAMETER;
> > +    }
> > +  }
> > +
> > +  return Status;
> > +}
> > +
> > +/**
> > +  This function is used to register callback function for
> > +  specified event
> > +  @DevCoreHandle: Handle to HW-independent APIs for device
> > +  controller
> > +  @event: Event for which callback is to be registered
> > +  @callbackFn: Callback function to be called by the
> > +  controller driver for above event after critical processing
> > +
> > +**/
> > +EFI_STATUS
> > +UsbDeviceRegisterCallback (
> > +  IN VOID                      *DevCoreHandle,
> > +  IN USB_DEVICE_EVENT_ID       EventId,
> > +  IN USB_DEVICE_CALLBACK_FUNC  CallbackFunc
> > +  )
> > +{
> > +  EFI_STATUS    Status = EFI_DEVICE_ERROR;
> > +  USB_DEV_CORE  *core = (USB_DEV_CORE *)DevCoreHandle;
> > +
> > +  DEBUG ((DEBUG_INFO, "UsbDeviceRegisterCallback start\n"));
> > +
> > +  if (core == NULL) {
> > +    DEBUG ((DEBUG_INFO, "UsbDeviceRegisterCallback: ERROR: INVALID
> HANDLE\n"));
> > +  } else {
> > +    if (core->CoreDriver != NULL) {
> > +      DEBUG ((DEBUG_INFO, "Call DevCoreRegisterCallback\n"));
> > +      Status = core->CoreDriver->DevCoreRegisterCallback (
> > +                                    core->ControllerHandle,
> > +                                    EventId,
> > +                                    CallbackFunc
> > +                                    );
> > +    }
> > +  }
> > +
> > +  return Status;
> > +}
> > +
> > +/**
> > +  This function is used to register callback function for
> > +  specified event
> > +  @DevCoreHandle: Handle to HW-independent APIs for device
> > +  controller
> > +  @eventId: Event for which callback is to be unregistered
> > +
> > +**/
> > +EFI_STATUS
> > +UsbDeviceUnregisterCallback (
> > +  IN VOID                      *DevCoreHandle,
> > +  IN USB_DEVICE_EVENT_ID       EventId
> > +  )
> > +{
> > +  EFI_STATUS    Status = EFI_DEVICE_ERROR;
> > +  USB_DEV_CORE  *core = (USB_DEV_CORE *)DevCoreHandle;
> > +
> > +  if (core == NULL) {
> > +    DEBUG ((DEBUG_INFO, "UsbDeviceUnregisterCallback: ERROR: INVALID
> HANDLE\n"));
> > +  } else {
> > +    if (core->CoreDriver != NULL) {
> > +      Status = core->CoreDriver->DevCoreUnregisterCallback(
> > +                                    core->ControllerHandle,
> > +                                    EventId
> > +                                    );
> > +    }
> > +  }
> > +
> > +  return Status;
> > +}
> > +
> > +/**
> > +  This function is used to service interrupt events on device
> > +  controller. Use this API in your OS/stack-specific ISR framework
> > +  In polled mode scenario, invoke this API in a loop to service the
> > +  events
> > +  @DevCoreHandle: Handle to HW-independent APIs for device
> > +  controller
> > +
> > +**/
> > +EFI_STATUS
> > +UsbDeviceIsrRoutine (
> > +  IN VOID                      *DevCoreHandle
> > +  )
> > +{
> > +  USB_DEV_CORE  *core = (USB_DEV_CORE *)DevCoreHandle;
> > +  EFI_STATUS    Status = EFI_DEVICE_ERROR;
> > +
> > +  if (core == NULL) {
> > +    DEBUG ((DEBUG_INFO, "UsbDeviceIsrRoutine: ERROR: INVALID
> HANDLE\n"));
> > +  } else {
> > +    if (core->CoreDriver != NULL) {
> > +      Status = core->CoreDriver->DevCoreIsrRoutine (core-
> >ControllerHandle);
> > +    }
> > +  }
> > +
> > +  return Status;
> > +}
> > +
> > +
> > +/**
> > +  This function is used to service interrupt events on device
> > +  controller. Use this API in your OS/stack-specific ISR framework
> > +  In polled mode scenario, invoke this API in a loop to service the
> > +  events
> > +  @DevCoreHandle: Handle to HW-independent APIs for device
> > +  controller
> > +
> > +**/
> > +EFI_STATUS
> > +UsbDeviceIsrRoutineTimerBased (
> > +  IN VOID                      *DevCoreHandle
> > +  )
> > +{
> > +  USB_DEV_CORE  *core = (USB_DEV_CORE *)DevCoreHandle;
> > +  EFI_STATUS    Status = EFI_DEVICE_ERROR;
> > +
> > +  if (core == NULL) {
> > +    DEBUG ((DEBUG_INFO, "UsbDeviceIsrRoutine: ERROR: INVALID
> HANDLE\n"));
> > +  } else {
> > +    if (core->CoreDriver != NULL) {
> > +      Status = core->CoreDriver->DevCoreIsrRoutineTimerBased (core-
> >ControllerHandle);
> > +    }
> > +  }
> > +
> > +  return Status;
> > +}
> > +
> > +
> > +/**
> > +  This function is used to enable device controller to connect
> > +  to USB host
> > +  @DevCoreHandle: Handle to HW-independent APIs for device
> > +  controller
> > +
> > +**/
> > +EFI_STATUS
> > +UsbXdciDeviceConnect (
> > +  IN VOID                      *DevCoreHandle
> > +  )
> > +{
> > +  USB_DEV_CORE  *core = (USB_DEV_CORE *)DevCoreHandle;
> > +  EFI_STATUS    Status = EFI_DEVICE_ERROR;
> > +
> > +  if (core == NULL) {
> > +    DEBUG ((DEBUG_INFO, "UsbXdciDeviceConnect: ERROR: INVALID
> HANDLE\n"));
> > +  } else {
> > +    DEBUG ((DEBUG_INFO, "UsbXdciDeviceConnect\n"));
> > +    Status = core->CoreDriver->DevCoreConnect (core->ControllerHandle);
> > +  }
> > +
> > +  return Status;
> > +}
> > +
> > +/**
> > +  This function is used to disconnect device controller
> > +  from USB host
> > +  @DevCoreHandle: Handle to HW-independent APIs for device
> > +  controller
> > +
> > +**/
> > +EFI_STATUS
> > +UsbDeviceDisconnect (
> > +  IN VOID                      *DevCoreHandle
> > +  )
> > +{
> > +  USB_DEV_CORE  *core =(USB_DEV_CORE *)DevCoreHandle;
> > +  EFI_STATUS    Status = EFI_DEVICE_ERROR;
> > +
> > +  if (core == NULL) {
> > +    DEBUG ((DEBUG_INFO, "UsbDeviceDisconnect: ERROR: INVALID
> HANDLE\n"));
> > +  } else {
> > +    DEBUG ((DEBUG_INFO, "UsbDeviceDisconnect\n"));
> > +    Status = core->CoreDriver->DevCoreDisconnect(core-
> >ControllerHandle);
> > +  }
> > +
> > +  return Status;
> > +}
> > +
> > +/**
> > +  This function is used to obtain USB bus Speed after bus reset complete
> > +  @DevCoreHandle: Handle to HW-independent APIs for device
> > +  controller
> > +  @Speed: negotiated Speed
> > +
> > +**/
> > +EFI_STATUS
> > +UsbDeviceGetSpeed (
> > +  IN VOID                      *DevCoreHandle,
> > +  IN USB_SPEED                 *Speed
> > +  )
> > +{
> > +  USB_DEV_CORE  *core = (USB_DEV_CORE *)DevCoreHandle;
> > +  EFI_STATUS    Status = EFI_DEVICE_ERROR;
> > +
> > +  if (core == NULL) {
> > +    DEBUG ((DEBUG_INFO, "UsbDeviceGetSpeed: ERROR: INVALID
> HANDLE\n"));
> > +  } else {
> > +    Status = core->CoreDriver->DevCoreGetSpeed(core->ControllerHandle,
> Speed);
> > +  }
> > +
> > +  return Status;
> > +}
> > +
> > +/**
> > +  This function is used to set USB device address
> > +  @DevCoreHandle: Handle to HW-independent APIs for device
> > +  controller
> > +  @address: USB device address to set
> > +
> > +**/
> > +EFI_STATUS
> > +UsbDeviceSetAddress (
> > +  IN VOID                      *DevCoreHandle,
> > +  IN UINT32                    Address
> > +  )
> > +{
> > +  USB_DEV_CORE  *core = (USB_DEV_CORE *)DevCoreHandle;
> > +  EFI_STATUS    Status = EFI_DEVICE_ERROR;
> > +
> > +  DEBUG ((DEBUG_INFO, "UsbDeviceSetAddress: enter......\n"));
> > +  if (core == NULL) {
> > +    DEBUG ((DEBUG_INFO, "UsbDeviceSetAddress: ERROR: INVALID
> HANDLE\n"));
> > +  } else {
> > +    Status = core->CoreDriver->DevCoreSetAddress(core-
> >ControllerHandle, Address);
> > +  }
> > +  DEBUG ((DEBUG_INFO, "UsbDeviceSetAddress: exit......\n"));
> > +
> > +  return Status;
> > +}
> > +
> > +/**
> > +  This function is used to do device controller-specific processing
> > +  of set configuration device framework request
> > +  @DevCoreHandle: Handle to HW-independent APIs for device
> > +  controller
> > +  @ConfigNum: configuration number selected by USB host
> > +
> > +**/
> > +EFI_STATUS
> > +UsbDeviceSetConfiguration (
> > +  IN VOID                      *DevCoreHandle,
> > +  IN UINT32                    ConfigNum
> > +  )
> > +{
> > +  USB_DEV_CORE  *core = (USB_DEV_CORE *)DevCoreHandle;
> > +  EFI_STATUS    Status = EFI_DEVICE_ERROR;
> > +
> > +  if (core == NULL) {
> > +    DEBUG ((DEBUG_INFO, "UsbDeviceSetConfiguration: ERROR: INVALID
> HANDLE\n"));
> > +  } else {
> > +    Status = core->CoreDriver->DevCoreSetConfig (core->ControllerHandle,
> ConfigNum);
> > +  }
> > +
> > +  return Status;
> > +}
> > +
> > +/**
> > +  This function is used to set desired link state in device controller
> > +  @DevCoreHandle: Handle to HW-independent APIs for device
> > +  controller
> > +  @state: Desired link state
> > +
> > +**/
> > +EFI_STATUS
> > +UsbDeviceSetLinkState (
> > +  IN VOID                      *DevCoreHandle,
> > +  IN USB_DEVICE_SS_LINK_STATE  State
> > +  )
> > +{
> > +  USB_DEV_CORE  *core = (USB_DEV_CORE *)DevCoreHandle;
> > +  EFI_STATUS    Status = EFI_DEVICE_ERROR;
> > +
> > +  if (core == NULL) {
> > +    DEBUG ((DEBUG_INFO, "UsbDeviceSetLinkState: ERROR: INVALID
> HANDLE\n"));
> > +  } else {
> > +    Status = core->CoreDriver->DevCoreSetLinkState (core-
> >ControllerHandle, State);
> > +  }
> > +
> > +  return Status;
> > +}
> > +
> > +/**
> > +  This function is used to initialize non-EP0 endpoints
> > +  @DevCoreHandle: Handle to HW-independent APIs for device
> > +  controller
> > +  @EpInfo: Endpoint information for EP to be initialized
> > +
> > +**/
> > +EFI_STATUS
> > +UsbDeviceInitEp (
> > +  IN VOID                      *DevCoreHandle,
> > +  IN USB_EP_INFO               *EpInfo
> > +  )
> > +{
> > +  USB_DEV_CORE  *core = (USB_DEV_CORE *)DevCoreHandle;
> > +  EFI_STATUS    Status = EFI_DEVICE_ERROR;
> > +
> > +  if (core == NULL) {
> > +    DEBUG ((DEBUG_INFO, "UsbDeviceInitEp: ERROR: INVALID
> HANDLE\n"));
> > +  } else {
> > +    Status = core->CoreDriver->DevCoreInitEp (core->ControllerHandle,
> EpInfo);
> > +  }
> > +
> > +  return Status;
> > +}
> > +
> > +/**
> > +  This function is used to enable an endpoint
> > +  @DevCoreHandle: Handle to HW-independent APIs for device
> > +  controller
> > +  @EpInfo: Endpoint information for EP to be enabled
> > +
> > +**/
> > +EFI_STATUS
> > +UsbDeviceEpEnable (
> > +  IN VOID                      *DevCoreHandle,
> > +  IN USB_EP_INFO               *EpInfo
> > +  )
> > +{
> > +  USB_DEV_CORE  *core = (USB_DEV_CORE *)DevCoreHandle;
> > +  EFI_STATUS    Status = EFI_DEVICE_ERROR;
> > +
> > +  if (core == NULL) {
> > +    DEBUG ((DEBUG_INFO, "UsbDeviceEpEnable: ERROR: INVALID
> HANDLE\n"));
> > +  } else {
> > +    Status = core->CoreDriver->DevCoreEpEnable (core->ControllerHandle,
> EpInfo);
> > +  }
> > +
> > +  return Status;
> > +}
> > +
> > +/**
> > +  This function is used to disable an endpoint
> > +  @DevCoreHandle: Handle to HW-independent APIs for device
> > +  controller
> > +  @EpInfo: Endpoint information for EP to be disabled
> > +
> > +**/
> > +EFI_STATUS
> > +UsbDeviceEpDisable (
> > +  IN VOID                      *DevCoreHandle,
> > +  IN USB_EP_INFO               *EpInfo
> > +  )
> > +{
> > +  USB_DEV_CORE  *core = (USB_DEV_CORE *)DevCoreHandle;
> > +  EFI_STATUS    Status = EFI_DEVICE_ERROR;
> > +
> > +  if (core == NULL) {
> > +    DEBUG ((DEBUG_INFO, "UsbDeviceEpDisable ERROR: INVALID
> HANDLE\n"));
> > +  } else {
> > +    Status = core->CoreDriver->DevCoreEpDisable (core->ControllerHandle,
> EpInfo);
> > +  }
> > +
> > +  return Status;
> > +}
> > +
> > +/**
> > +  This function is used to STALL an endpoint
> > +  @DevCoreHandle: Handle to HW-independent APIs for device
> > +  controller
> > +  @EpInfo: Endpoint information for EP to be stalled
> > +
> > +**/
> > +EFI_STATUS
> > +UsbDeviceEpStall (
> > +  IN VOID                      *DevCoreHandle,
> > +  IN USB_EP_INFO               *EpInfo
> > +  )
> > +{
> > +  USB_DEV_CORE  *core = (USB_DEV_CORE *)DevCoreHandle;
> > +  EFI_STATUS    Status = EFI_DEVICE_ERROR;
> > +
> > +  if (core == NULL) {
> > +    DEBUG ((DEBUG_INFO, "UsbDeviceEpStall ERROR: INVALID
> HANDLE\n"));
> > +  } else {
> > +    Status = core->CoreDriver->DevCoreEpStall (core->ControllerHandle,
> EpInfo);
> > +  }
> > +
> > +  return Status;
> > +}
> > +
> > +/**
> > +  This function is used to clear STALL on an endpoint
> > +  @DevCoreHandle: Handle to HW-independent APIs for device
> > +  controller
> > +  @EpInfo: Endpoint information for which STALL needs to be cleared
> > +
> > +**/
> > +EFI_STATUS
> > +UsbDeviceEpClearStall (
> > +  IN VOID                      *DevCoreHandle,
> > +  IN USB_EP_INFO               *EpInfo
> > +  )
> > +{
> > +  USB_DEV_CORE  *core = (USB_DEV_CORE *)DevCoreHandle;
> > +  EFI_STATUS    Status = EFI_DEVICE_ERROR;
> > +
> > +  if (core == NULL) {
> > +    DEBUG ((DEBUG_INFO, "UsbDeviceEpClearStall ERROR: INVALID
> HANDLE\n"));
> > +  } else {
> > +    Status = core->CoreDriver->DevCoreEpClearStall (core-
> >ControllerHandle, EpInfo);
> > +  }
> > +
> > +  return Status;
> > +}
> > +
> > +/**
> > +  This function is used to set EP not ready state
> > +  @DevCoreHandle: Handle to HW-independent APIs for device
> > +  controller
> > +  @EpInfo: Endpoint information for EP that needs to be
> > +  set in not ready state
> > +
> > +**/
> > +EFI_STATUS
> > +UsbDeviceEpSetNrdy (
> > +  IN VOID                      *DevCoreHandle,
> > +  IN USB_EP_INFO               *EpInfo
> > +  )
> > +{
> > +  USB_DEV_CORE  *core = (USB_DEV_CORE *)DevCoreHandle;
> > +  EFI_STATUS    Status = EFI_DEVICE_ERROR;
> > +
> > +  if (core == NULL) {
> > +    DEBUG ((DEBUG_INFO, "UsbDeviceEpSetNrdy ERROR: INVALID
> HANDLE\n"));
> > +  } else {
> > +    Status = core->CoreDriver->DevCoreEpSetNrdy (core->ControllerHandle,
> EpInfo);
> > +  }
> > +
> > +  return Status;
> > +}
> > +
> > +/**
> > +  This function is used to queue request to receive SETUP packet
> > +  @DevCoreHandle: Handle to HW-independent APIs for device
> > +  controller
> > +  @Buffer: Buffer (bus-width aligned) where SETUP packet
> > +  needs to be received
> > +
> > +**/
> > +EFI_STATUS
> > +UsbDeviceEp0RxSetup (
> > +  IN VOID                      *DevCoreHandle,
> > +  IN UINT8                     *Buffer
> > +  )
> > +{
> > +  USB_DEV_CORE  *core = (USB_DEV_CORE *)DevCoreHandle;
> > +  EFI_STATUS    Status = EFI_DEVICE_ERROR;
> > +
> > +  if (core == NULL) {
> > +    DEBUG ((DEBUG_INFO, "UsbDeviceEp0RxSetup ERROR: INVALID
> HANDLE\n"));
> > +  } else {
> > +    Status = core->CoreDriver->DevCoreEp0RxSetupPkt (core-
> >ControllerHandle, Buffer);
> > +  }
> > +
> > +  return Status;
> > +}
> > +
> > +/**
> > +  This function is used to queue request to receive status phase
> > +  for control transfer on EP0
> > +  @DevCoreHandle: Handle to HW-independent APIs for device
> > +  controller
> > +
> > +**/
> > +EFI_STATUS
> > +UsbDeviceEp0RxStatus (
> > +  IN VOID                      *DevCoreHandle
> > +  )
> > +{
> > +  USB_DEV_CORE  *core = (USB_DEV_CORE *)DevCoreHandle;
> > +  EFI_STATUS    Status = EFI_DEVICE_ERROR;
> > +
> > +  if (core == NULL) {
> > +    DEBUG ((DEBUG_INFO, "UsbDeviceEp0RxStatus ERROR: INVALID
> HANDLE\n"));
> > +  } else {
> > +    Status = core->CoreDriver->DevCoreEp0RxStatusPkt (core-
> >ControllerHandle);
> > +  }
> > +  return Status;
> > +}
> > +
> > +/**
> > +  This function is used to queue request to send status phase for
> > +  control transfer on EP0
> > +  @DevCoreHandle: Handle to HW-independent APIs for device
> > +  controller
> > +
> > +**/
> > +EFI_STATUS
> > +UsbDeviceEp0TxStatus (
> > +  IN VOID                      *DevCoreHandle
> > +  )
> > +{
> > +  USB_DEV_CORE  *core = (USB_DEV_CORE *)DevCoreHandle;
> > +  EFI_STATUS    Status = EFI_DEVICE_ERROR;
> > +
> > +  if (core == NULL) {
> > +    DEBUG ((DEBUG_INFO, "UsbDeviceEp0TxStatus ERROR: INVALID
> HANDLE\n"));
> > +  } else {
> > +    Status = core->CoreDriver->DevCoreEp0TxStatusPkt (core-
> >ControllerHandle);
> > +  }
> > +
> > +  return Status;
> > +}
> > +
> > +/**
> > +  This function is used to queue a single request to transmit data on
> > +  an endpoint. If more than one request need to be queued before
> > +  previous requests complete then a request queue needs to be
> > +  implemented in upper layers. This API should be not be invoked until
> > +  current request completes.
> > +  Callback for transfer completion is invoked when requested transfer
> length
> > +  is reached or if a short packet is received
> > +  @DevCoreHandle: Handle to HW-independent APIs for device
> > +  controller
> > +  @XferReq: Address to transfer request describing this transfer
> > +
> > +**/
> > +EFI_STATUS
> > +UsbXdciDeviceEpTxData (
> > +  IN VOID                      *DevCoreHandle,
> > +  IN USB_XFER_REQUEST          *XferReq
> > +  )
> > +{
> > +  USB_DEV_CORE  *core = (USB_DEV_CORE *)DevCoreHandle;
> > +  EFI_STATUS    Status = EFI_DEVICE_ERROR;
> > +
> > +  if (core == NULL) {
> > +    DEBUG ((DEBUG_INFO, "UsbXdciDeviceEpTxData ERROR: INVALID
> HANDLE\n"));
> > +  } else {
> > +    Status = core->CoreDriver->DevCoreEpTxData (core->ControllerHandle,
> XferReq);
> > +  }
> > +
> > +  return Status;
> > +}
> > +
> > +/**
> > +  This function is used to queue a single request to receive data on
> > +  an endpoint. If more than one request need to be queued before
> > +  previous requests complete then a request queue needs to be
> implemented
> > +  in upper layers. This API should be not be invoked until current request
> > +  completes.
> > +  Callback for transfer completion is invoked when requested transfer
> length
> > +  is reached or if a short packet is received
> > +  @DevCoreHandle: Handle to HW-independent APIs for device
> > +  controller
> > +  @XferReq: Address to transfer request describing this transfer
> > +
> > +**/
> > +EFI_STATUS
> > +UsbXdciDeviceEpRxData (
> > +  IN VOID                      *DevCoreHandle,
> > +  IN USB_XFER_REQUEST          *XferReq
> > +  )
> > +{
> > +  USB_DEV_CORE  *core = (USB_DEV_CORE *)DevCoreHandle;
> > +  EFI_STATUS    Status = EFI_DEVICE_ERROR;
> > +
> > +  if (core == NULL) {
> > +    DEBUG ((DEBUG_INFO, "UsbXdciDeviceEpRxData ERROR: INVALID
> HANDLE\n"));
> > +  } else {
> > +    Status = core->CoreDriver->DevCoreEpRxData (core->ControllerHandle,
> XferReq);
> > +  }
> > +
> > +  return Status;
> > +}
> > +
> > +/**
> > +  This function is used to cancel a transfer request that was
> > +  previously queued on an endpoint
> > +  @DevCoreHandle: Handle to HW-independent APIs for device
> > +  controller
> > +  @EpInfo: Endpoint info where transfer needs to be cancelled
> > +
> > +**/
> > +EFI_STATUS
> > +UsbDeviceEpCancelTransfer (
> > +  IN VOID                      *DevCoreHandle,
> > +  IN USB_EP_INFO               *EpInfo
> > +  )
> > +{
> > +  USB_DEV_CORE  *core = (USB_DEV_CORE *)DevCoreHandle;
> > +  EFI_STATUS    Status = EFI_DEVICE_ERROR;
> > +
> > +  if (core == NULL) {
> > +    DEBUG ((DEBUG_INFO, "UsbDeviceEpCancelTransfer ERROR: INVALID
> HANDLE\n"));
> > +  } else {
> > +    Status = core->CoreDriver->DevCoreEpCancelTransfer (core-
> >ControllerHandle, EpInfo);
> > +  }
> > +
> > +  return Status;
> > +}
> > +
> > diff --git
> a/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciDevice.h
> b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciDevice.h
> > new file mode 100644
> > index 0000000000..a10ec61732
> > --- /dev/null
> > +++ b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciDevice.h
> > @@ -0,0 +1,184 @@
> > +/** @file
> > +  Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR>
> > +
> > +  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.
> > +
> > +**/
> > +
> > +#ifndef _USB_DEVICE_H_
> > +#define _USB_DEVICE_H_
> > +
> > +//
> > +// @USB_DEV_CONFIG_PARAMS: Struct to be filled in with configuration
> > +// parameters and passed to the init routine for device controller
> > +//
> > +typedef struct {
> > +  USB_CONTROLLER_ID  ControllerId; // Controller ID of the core
> > +  UINT32             BaseAddress;  // Base address of the controller registers
> and on-chip memory
> > +  UINT32             Flags;        // Initialization flags
> > +  USB_SPEED          Speed;        // Desired USB bus Speed
> > +  USB_ROLE           Role;         // Default USB role
> > +} USB_DEV_CONFIG_PARAMS;
> > +
> > +//
> > +// @USB_DEV_CORE: Struct used as a handle for all
> > +// hardware-independent APIs
> > +//
> > +typedef struct {
> > +  const struct UsbDeviceCoreDriver *CoreDriver;
> > +  VOID                                *ControllerHandle;
> > +} USB_DEV_CORE;
> > +
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI *USB_DEVICE_CALLBACK_FUNC) (
> > +  IN USB_DEVICE_CALLBACK_PARAM  *Param
> > +  );
> > +
> > +EFI_STATUS
> > +UsbDeviceInit (
> > +  IN USB_DEV_CONFIG_PARAMS    *ConfigParams,
> > +  IN OUT VOID                 **DevCoreHandle
> > +  );
> > +
> > +EFI_STATUS
> > +UsbDeviceDeinit (
> > +  IN VOID                      *DevCoreHandle,
> > +  IN UINT32                    Flags
> > +  );
> > +
> > +EFI_STATUS
> > +UsbDeviceRegisterCallback (
> > +  IN VOID                      *DevCoreHandle,
> > +  IN USB_DEVICE_EVENT_ID       EventId,
> > +  IN USB_DEVICE_CALLBACK_FUNC  CallbackFunc
> > +  );
> > +
> > +EFI_STATUS
> > +UsbDeviceUnregisterCallback (
> > +  IN VOID                      *DevCoreHandle,
> > +  IN USB_DEVICE_EVENT_ID       EventId
> > +  );
> > +
> > +EFI_STATUS
> > +UsbDeviceIsrRoutine (
> > +  IN VOID                      *DevCoreHandle
> > +  );
> > +
> > +EFI_STATUS
> > +UsbDeviceIsrRoutineTimerBased (
> > +  IN VOID                      *DevCoreHandle
> > +  );
> > +
> > +EFI_STATUS
> > +UsbXdciDeviceConnect (
> > +  IN VOID                      *DevCoreHandle
> > +  );
> > +
> > +EFI_STATUS
> > +UsbDeviceDisconnect (
> > +  IN VOID                      *DevCoreHandle
> > +  );
> > +
> > +EFI_STATUS
> > +UsbDeviceGetSpeed (
> > +  IN VOID                      *DevCoreHandle,
> > +  IN USB_SPEED                 *Speed
> > +  );
> > +
> > +EFI_STATUS
> > +UsbDeviceSetLinkState (
> > +  IN VOID                      *DevCoreHandle,
> > +  IN USB_DEVICE_SS_LINK_STATE  State
> > +  );
> > +
> > +EFI_STATUS
> > +UsbDeviceSetAddress (
> > +  IN VOID                      *DevCoreHandle,
> > +  IN UINT32                    Address
> > +  );
> > +
> > +EFI_STATUS
> > +UsbDeviceSetConfiguration (
> > +  IN VOID                      *DevCoreHandle,
> > +  IN UINT32                    ConfigNum
> > +  );
> > +
> > +EFI_STATUS
> > +UsbDeviceInitEp (
> > +  IN VOID                      *DevCoreHandle,
> > +  IN USB_EP_INFO               *EpInfo
> > +  );
> > +
> > +EFI_STATUS
> > +UsbDeviceEpEnable (
> > +  IN VOID                      *DevCoreHandle,
> > +  IN USB_EP_INFO               *EpInfo
> > +  );
> > +
> > +EFI_STATUS
> > +UsbDeviceEpDisable (
> > +  IN VOID                      *DevCoreHandle,
> > +  IN USB_EP_INFO               *EpInfo
> > +  );
> > +
> > +EFI_STATUS
> > +UsbDeviceEpStall (
> > +  IN VOID                      *DevCoreHandle,
> > +  IN USB_EP_INFO               *EpInfo
> > +  );
> > +
> > +EFI_STATUS
> > +UsbDeviceEpClearStall (
> > +  IN VOID                      *DevCoreHandle,
> > +  IN USB_EP_INFO               *EpInfo
> > +  );
> > +
> > +EFI_STATUS
> > +UsbDeviceEpSetNrdy (
> > +  IN VOID                      *DevCoreHandle,
> > +  IN USB_EP_INFO               *EpInfo
> > +  );
> > +
> > +EFI_STATUS
> > +UsbDeviceEp0RxSetup (
> > +  IN VOID                      *DevCoreHandle,
> > +  IN UINT8                     *Buffer
> > +  );
> > +
> > +EFI_STATUS
> > +UsbDeviceEp0RxStatus (
> > +  IN VOID                      *DevCoreHandle
> > +  );
> > +
> > +EFI_STATUS
> > +UsbDeviceEp0TxStatus (
> > +  IN VOID                      *DevCoreHandle
> > +  );
> > +
> > +EFI_STATUS
> > +UsbXdciDeviceEpTxData (
> > +  IN VOID                      *DevCoreHandle,
> > +  IN USB_XFER_REQUEST          *XferReq
> > +  );
> > +
> > +EFI_STATUS
> > +UsbXdciDeviceEpRxData (
> > +  IN VOID                      *DevCoreHandle,
> > +  IN USB_XFER_REQUEST          *XferReq
> > +  );
> > +
> > +EFI_STATUS
> > +UsbDeviceEpCancelTransfer (
> > +  IN VOID                      *DevCoreHandle,
> > +  IN USB_EP_INFO               *EpInfo
> > +  );
> > +
> > +#endif
> > +
> > diff --git
> a/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciInterface.h
> b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciInterface.h
> > new file mode 100644
> > index 0000000000..75ce0ecab3
> > --- /dev/null
> > +++ b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciInterface.h
> > @@ -0,0 +1,241 @@
> > +/** @file
> > +  Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR>
> > +
> > +  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.
> > +
> > +**/
> > +
> > +#ifndef _USB_DCD_IF_H_
> > +#define _USB_DCD_IF_H_
> > +
> > +/* Core driver for device controller
> > + * @DevCoreInit: Intializes device controller
> > + * @DevCoreDeinit: De-initializes device controller
> > + * @DevCoreRegisterCallback: Registers callback function for
> > + * an event to be called by the controller driver
> > + * @DevCoreUnregisterCallback: Unregisters callback function
> > + * for an event
> > + * @DevCoreIsrRoutine: core interrupt service routine for
> > + * device controller to be used by OS/stack-i/f layer
> > + * @DevCoreConnect: Enable device controller to connect to USB host
> > + * @DevCoreDisconnect: Soft disconnect device controller from
> > + * USB host
> > + * @DevCoreGetSpeed: Get USB bus Speed on which device controller
> > + * is attached
> > + * @DevCoreSetAddress: Set USB device address in device controller
> > + * @DevCoreSetConfig: Set configuration number for device controller
> > + * @DevCoreSetLinkState: Set link state for device controller
> > + * @DevCoreInitEp: Initialize non-EP0 endpoint
> > + * @DevCoreEpEnable: Enable endpoint
> > + * @DevCoreEpDisable: Disable endpoint
> > + * @DevCoreEpStall: Stall/Halt endpoint
> > + * @DevCoreEpClearStall: Clear Stall/Halt on endpoint
> > + * @DevCoreEpSetNrdy: Set endpoint to not ready state
> > + * @DevCoreEp0RxSetupPkt: Receive SETUP packet on EP0
> > + * @DevCoreEp0RxStatusPkt: Receive status packet on EP0
> > + * @DevCoreEp0TxStatusPkt: Transmit status packet from EP0
> > + * @DevCoreEpTxData: Transmit data from EP
> > + * @DevCoreEpRxData: Received data on EP
> > + * @DevCoreEpCancelTransfer: Cancel transfer on EP
> > + */
> > +
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI *DEV_CORE_INIT) (
> > +  IN USB_DEV_CONFIG_PARAMS     *ConfigParams,
> > +  IN VOID                      *ParentHandle,
> > +  IN VOID                      **CoreHandle
> > +  );
> > +
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI *DEV_CORE_DEINIT) (
> > +  IN VOID                      *CoreHandle,
> > +  IN UINT32                    Flags
> > +  );
> > +
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI *DEV_CORE_REG_CALLBACK) (
> > +  IN VOID                      *CoreHandle,
> > +  IN USB_DEVICE_EVENT_ID       Event,
> > +  IN USB_DEVICE_CALLBACK_FUNC  CallbackFn
> > +  );
> > +
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI *DEV_CORE_UNREG_CALLBACK) (
> > +  IN VOID                      *CoreHandle,
> > +  IN USB_DEVICE_EVENT_ID       Event
> > +  );
> > +
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI *DEV_CORE_ISR_ROUTINE) (
> > +  IN VOID                      *CoreHandle
> > +  );
> > +
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI *DEV_CORE_CONNECT) (
> > +  IN VOID                      *CoreHandle
> > +  );
> > +
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI *DEV_CORE_DISCONNECT) (
> > +  IN VOID                      *CoreHandle
> > +  );
> > +
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI *DEV_CORE_GET_SPEED) (
> > +  IN VOID                      *CoreHandle,
> > +  IN USB_SPEED                 *Speed
> > +  );
> > +
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI *DEV_CORE_SET_ADDRESS) (
> > +  IN VOID                      *CoreHandle,
> > +  IN UINT32                    Address
> > +  );
> > +
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI *DEV_CORE_SET_CONFIG) (
> > +  IN VOID                      *CoreHandle,
> > +  IN UINT32                    ConfigNum
> > +  );
> > +
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI *DEV_CORE_SET_LINK_STATE) (
> > +  IN VOID                      *CoreHandle,
> > +  IN USB_DEVICE_SS_LINK_STATE  State
> > +  );
> > +
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI *DEV_CORE_INIT_EP) (
> > +  IN VOID                      *CoreHandle,
> > +  IN USB_EP_INFO               *EpInfo
> > +  );
> > +
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI *DEV_CORE_EP_ENABLE) (
> > +  IN VOID                      *CoreHandle,
> > +  IN USB_EP_INFO               *EpInfo
> > +  );
> > +
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI *DEV_CORE_EP_DISABLE) (
> > +  IN VOID                      *CoreHandle,
> > +  IN USB_EP_INFO               *EpInfo
> > +  );
> > +
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI *DEV_CORE_EP_STALL) (
> > +  IN VOID                      *CoreHandle,
> > +  IN USB_EP_INFO               *EpInfo
> > +  );
> > +
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI *DEV_CORE_EP_CLEAR_STALL) (
> > +  IN VOID                      *CoreHandle,
> > +  IN USB_EP_INFO               *EpInfo
> > +  );
> > +
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI *DEV_CORE_EP_SET_NRDY) (
> > +  IN VOID                      *CoreHandle,
> > +  IN USB_EP_INFO               *EpInfo
> > +  );
> > +
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI *DEV_CORE_EP0_RX_SETUP_PKT) (
> > +  IN VOID                      *CoreHandle,
> > +  IN UINT8                     *Buffer
> > +  );
> > +
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI *DEV_CORE_EP0_RX_STATUS_PKT) (
> > +  IN VOID                      *CoreHandle
> > +  );
> > +
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI *DEV_CORE_EP0_TX_STATUS_PKT) (
> > +  IN VOID                      *CoreHandle
> > +  );
> > +
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI *DEV_CORE_EP_TX_DATA) (
> > +  IN VOID                      *CoreHandle,
> > +  IN USB_XFER_REQUEST          *XferHandle
> > +  );
> > +
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI *DEV_CORE_EP_RX_DATA) (
> > +  IN VOID                      *CoreHandle,
> > +  IN USB_XFER_REQUEST          *XferHandle
> > +  );
> > +
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI *DEV_CORE_EP_CANCEL_TRANSFER) (
> > +  IN VOID                      *CoreHandle,
> > +  IN USB_EP_INFO               *EpInfo
> > +  );
> > +
> > +struct UsbDeviceCoreDriver {
> > +  DEV_CORE_INIT                 DevCoreInit;
> > +  DEV_CORE_DEINIT               DevCoreDeinit;
> > +  DEV_CORE_REG_CALLBACK         DevCoreRegisterCallback;
> > +  DEV_CORE_UNREG_CALLBACK       DevCoreUnregisterCallback;
> > +  DEV_CORE_ISR_ROUTINE          DevCoreIsrRoutine;
> > +  DEV_CORE_ISR_ROUTINE          DevCoreIsrRoutineTimerBased;
> > +  DEV_CORE_CONNECT              DevCoreConnect;
> > +  DEV_CORE_DISCONNECT           DevCoreDisconnect;
> > +  DEV_CORE_GET_SPEED            DevCoreGetSpeed;
> > +  DEV_CORE_SET_ADDRESS          DevCoreSetAddress;
> > +  DEV_CORE_SET_CONFIG           DevCoreSetConfig;
> > +  DEV_CORE_SET_LINK_STATE       DevCoreSetLinkState;
> > +  DEV_CORE_INIT_EP              DevCoreInitEp;
> > +  DEV_CORE_EP_ENABLE            DevCoreEpEnable;
> > +  DEV_CORE_EP_DISABLE           DevCoreEpDisable;
> > +  DEV_CORE_EP_STALL             DevCoreEpStall;
> > +  DEV_CORE_EP_CLEAR_STALL       DevCoreEpClearStall;
> > +  DEV_CORE_EP_SET_NRDY          DevCoreEpSetNrdy;
> > +  DEV_CORE_EP0_RX_SETUP_PKT     DevCoreEp0RxSetupPkt;
> > +  DEV_CORE_EP0_RX_STATUS_PKT    DevCoreEp0RxStatusPkt;
> > +  DEV_CORE_EP0_TX_STATUS_PKT    DevCoreEp0TxStatusPkt;
> > +  DEV_CORE_EP_TX_DATA           DevCoreEpTxData;
> > +  DEV_CORE_EP_RX_DATA           DevCoreEpRxData;
> > +  DEV_CORE_EP_CANCEL_TRANSFER   DevCoreEpCancelTransfer;
> > +};
> > +
> > +//
> > +// This API is used to obtain the driver handle for HW-independent API
> > +// @id: The ID of the core for which this driver is requested
> > +//
> > +const struct UsbDeviceCoreDriver *UsbDeviceGetCoreDriver(
> > +  USB_CONTROLLER_ID id);
> > +
> > +#endif
> > +
> > diff --git
> a/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciTable.c
> b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciTable.c
> > new file mode 100644
> > index 0000000000..97a97db3db
> > --- /dev/null
> > +++ b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciTable.c
> > @@ -0,0 +1,55 @@
> > +/** @file
> > +  Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR>
> > +
> > +  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.
> > +
> > +**/
> > +
> > +#include <Library/UsbDeviceLib.h>
> > +#include "XdciCommon.h"
> > +#include "XdciDevice.h"
> > +#include "XdciInterface.h"
> > +#include "XdciDWC.h"
> > +#include "UsbDeviceMode.h"
> > +
> > +static const struct UsbDeviceCoreDriver
> CoreDriverTbl[USB_CORE_ID_MAX] = {
> > +  DwcXdciCoreInit,
> > +  DwcXdciCoreDeinit,
> > +  DwcXdciCoreRegisterCallback,
> > +  DwcXdciCoreUnregisterCallback,
> > +  DwcXdciCoreIsrRoutine,
> > +  DwcXdciCoreIsrRoutineTimerBased,
> > +  DwcXdciCoreConnect,
> > +  DwcXdciCoreDisconnect,
> > +  DwcXdciCoreGetSpeed,
> > +  DwcXdciCoreSetAddress,
> > +  DwcXdciCoreSetConfig,
> > +  DwcXdciSetLinkState,
> > +  DwcXdciInitEp,
> > +  DwcXdciEpEnable,
> > +  DwcXdciEpDisable,
> > +  DwcXdciEpStall,
> > +  DwcXdciEpClearStall,
> > +  DwcXdciEpSetNrdy,
> > +  DwcXdciEp0ReceiveSetupPkt,
> > +  DwcXdciEp0ReceiveStatusPkt,
> > +  DwcXdciEp0SendStatusPkt,
> > +  DwcXdciEpTxData,
> > +  DwcXdciEpRxData,
> > +  DwcXdciEpCancelTransfer
> > +};
> > +
> > +const struct UsbDeviceCoreDriver
> *UsbDeviceGetCoreDriver(USB_CONTROLLER_ID id)
> > +{
> > +  if (id >= USB_CORE_ID_MAX)
> > +    return NULL;
> > +
> > +  return &CoreDriverTbl[id];
> > +}
> > +
> > diff --git
> a/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciUtility.c
> b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciUtility.c
> > new file mode 100644
> > index 0000000000..2e02475cd0
> > --- /dev/null
> > +++ b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciUtility.c
> > @@ -0,0 +1,148 @@
> > +/** @file
> > +  Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR>
> > +
> > +  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.
> > +
> > +**/
> > +
> > +#include "XdciUtility.h"
> > +
> > +VOID
> > +PrintDeviceDescriptor (
> > +  IN USB_DEVICE_DESCRIPTOR    *DevDesc
> > +  )
> > +{
> > +  DEBUG ((DEBUG_INFO, "--- Device Descriptor ---\n"));
> > +  DEBUG ((DEBUG_INFO, "Length            : 0x%x\n", DevDesc->Length));
> > +  DEBUG ((DEBUG_INFO, "DescriptorType    : 0x%x\n", DevDesc-
> >DescriptorType));
> > +  DEBUG ((DEBUG_INFO, "BcdUSB            : 0x%x\n", DevDesc->BcdUSB));
> > +  DEBUG ((DEBUG_INFO, "DeviceClass       : 0x%x\n", DevDesc-
> >DeviceClass));
> > +  DEBUG ((DEBUG_INFO, "DeviceSubClass    : 0x%x\n", DevDesc-
> >DeviceSubClass));
> > +  DEBUG ((DEBUG_INFO, "DeviceProtocol    : 0x%x\n", DevDesc-
> >DeviceProtocol));
> > +  DEBUG ((DEBUG_INFO, "MaxPacketSize0    : 0x%x\n", DevDesc-
> >MaxPacketSize0));
> > +  DEBUG ((DEBUG_INFO, "IdVendor          : 0x%x\n", DevDesc->IdVendor));
> > +  DEBUG ((DEBUG_INFO, "IdProduct         : 0x%x\n", DevDesc->IdProduct));
> > +  DEBUG ((DEBUG_INFO, "BcdDevice         : 0x%x\n", DevDesc-
> >BcdDevice));
> > +  DEBUG ((DEBUG_INFO, "StrManufacturer   : 0x%x\n", DevDesc-
> >StrManufacturer));
> > +  DEBUG ((DEBUG_INFO, "StrProduct        : 0x%x\n", DevDesc-
> >StrProduct));
> > +  DEBUG ((DEBUG_INFO, "StrSerialNumber   : 0x%x\n", DevDesc-
> >StrSerialNumber));
> > +  DEBUG ((DEBUG_INFO, "NumConfigurations : 0x%x\n", DevDesc-
> >NumConfigurations));
> > +  DEBUG ((DEBUG_INFO, "\n"));
> > +}
> > +
> > +VOID
> > +PrintConfigDescriptor (
> > +  IN EFI_USB_CONFIG_DESCRIPTOR    *ConfigDesc
> > +  )
> > +{
> > +  DEBUG ((DEBUG_INFO, "--- Configuration Descriptor ---\n"));
> > +  DEBUG ((DEBUG_INFO, "Length             : 0x%x\n", ConfigDesc->Length));
> > +  DEBUG ((DEBUG_INFO, "DescriptorType     : 0x%x\n", ConfigDesc-
> >DescriptorType));
> > +  DEBUG ((DEBUG_INFO, "TotalLength        : 0x%x\n", ConfigDesc-
> >TotalLength));
> > +  DEBUG ((DEBUG_INFO, "NumInterfaces      : 0x%x\n", ConfigDesc-
> >NumInterfaces));
> > +  DEBUG ((DEBUG_INFO, "ConfigurationValue : 0x%x\n", ConfigDesc-
> >ConfigurationValue));
> > +  DEBUG ((DEBUG_INFO, "Configuration      : 0x%x\n", ConfigDesc-
> >Configuration));
> > +  DEBUG ((DEBUG_INFO, "Attributes         : 0x%x\n", ConfigDesc-
> >Attributes));
> > +  DEBUG ((DEBUG_INFO, "MaxPower           : 0x%x\n", ConfigDesc-
> >MaxPower));
> > +  DEBUG ((DEBUG_INFO, "\n"));
> > +}
> > +
> > +VOID
> > +PrintInterfaceDescriptor (
> > +  IN EFI_USB_INTERFACE_DESCRIPTOR    *IfDesc
> > +  )
> > +{
> > +  DEBUG ((DEBUG_INFO, "--- Interface Descriptor ---\n"));
> > +  DEBUG ((DEBUG_INFO, "Length            : 0x%x\n", IfDesc->Length));
> > +  DEBUG ((DEBUG_INFO, "DescriptorType    : 0x%x\n", IfDesc-
> >DescriptorType));
> > +  DEBUG ((DEBUG_INFO, "InterfaceNumber   : 0x%x\n", IfDesc-
> >InterfaceNumber));
> > +  DEBUG ((DEBUG_INFO, "AlternateSetting  : 0x%x\n", IfDesc-
> >AlternateSetting));
> > +  DEBUG ((DEBUG_INFO, "NumEndpoints      : 0x%x\n", IfDesc-
> >NumEndpoints));
> > +  DEBUG ((DEBUG_INFO, "InterfaceClass    : 0x%x\n", IfDesc-
> >InterfaceClass));
> > +  DEBUG ((DEBUG_INFO, "InterfaceSubClass : 0x%x\n", IfDesc-
> >InterfaceSubClass));
> > +  DEBUG ((DEBUG_INFO, "InterfaceProtocol : 0x%x\n", IfDesc-
> >InterfaceProtocol));
> > +  DEBUG ((DEBUG_INFO, "Interface         : 0x%x\n", IfDesc->Interface));
> > +  DEBUG ((DEBUG_INFO, "\n"));
> > +}
> > +
> > +VOID
> > +PrintEpDescriptor (
> > +  IN EFI_USB_ENDPOINT_DESCRIPTOR    *EpDesc
> > +  )
> > +{
> > +  DEBUG ((DEBUG_INFO, "--- Endpoint Descriptor ---\n"));
> > +  DEBUG ((DEBUG_INFO, "Length          : 0x%x\n", EpDesc->Length));
> > +  DEBUG ((DEBUG_INFO, "DescriptorType  : 0x%x\n", EpDesc-
> >DescriptorType));
> > +  DEBUG ((DEBUG_INFO, "EndpointAddress : 0x%x\n", EpDesc-
> >EndpointAddress));
> > +  DEBUG ((DEBUG_INFO, "Attributes      : 0x%x\n", EpDesc->Attributes));
> > +  DEBUG ((DEBUG_INFO, "MaxPacketSize   : 0x%x\n", EpDesc-
> >MaxPacketSize));
> > +  DEBUG ((DEBUG_INFO, "Interval        : 0x%x\n", EpDesc->Interval));
> > +  DEBUG ((DEBUG_INFO, "\n"));
> > +}
> > +
> > +VOID
> > +PrintEpCompDescriptor (
> > +  IN EFI_USB_ENDPOINT_COMPANION_DESCRIPTOR    *EpDesc
> > +  )
> > +{
> > +  DEBUG ((DEBUG_INFO, "--- Endpoint Companion Descriptor ---\n"));
> > +  DEBUG ((DEBUG_INFO, "Length           : 0x%x\n", EpDesc->Length));
> > +  DEBUG ((DEBUG_INFO, "DescriptorType   : 0x%x\n", EpDesc-
> >DescriptorType));
> > +  DEBUG ((DEBUG_INFO, "MaxBurst         : 0x%x\n", EpDesc->MaxBurst));
> > +  DEBUG ((DEBUG_INFO, "Attributes       : 0x%x\n", EpDesc->Attributes));
> > +  DEBUG ((DEBUG_INFO, "BytesPerInterval : 0x%x\n", EpDesc-
> >BytesPerInterval));
> > +  DEBUG ((DEBUG_INFO, "\n"));
> > +}
> > +
> > +VOID
> > +PrintStringDescriptor (
> > +  IN USB_STRING_DESCRIPTOR    *StrDesc
> > +  )
> > +{
> > +  UINT16 StrLen = 0;
> > +
> > +  if (StrDesc->Length > 2) {
> > +    StrLen = ((StrDesc->Length - 2) >> 1);
> > +    DEBUG ((DEBUG_INFO, "--- String Descriptor ---\n"));
> > +    DEBUG ((DEBUG_INFO, "Length         : 0x%x\n", StrDesc->Length));
> > +    DEBUG ((DEBUG_INFO, "DescriptorType : 0x%x\n", StrDesc-
> >DescriptorType));
> > +    DEBUG ((DEBUG_INFO, "String         : %s\n",   StrDesc->LangID));
> > +  }
> > +  DEBUG ((DEBUG_INFO, "\n"));
> > +}
> > +
> > +VOID
> > +PrintDeviceRequest (
> > +  IN EFI_USB_DEVICE_REQUEST    *DevReq
> > +  )
> > +{
> > +  DEBUG ((DEBUG_INFO, "--- Device Request ---\n"));
> > +  DEBUG ((DEBUG_INFO, "RequestType : 0x%x\n", DevReq-
> >RequestType));
> > +  DEBUG ((DEBUG_INFO, "Request     : 0x%x\n", DevReq->Request));
> > +  DEBUG ((DEBUG_INFO, "Value       : 0x%x\n", DevReq->Value));
> > +  DEBUG ((DEBUG_INFO, "Index       : 0x%x\n", DevReq->Index));
> > +  DEBUG ((DEBUG_INFO, "Length      : 0x%x\n", DevReq->Length));
> > +  DEBUG ((DEBUG_INFO, "\n"));
> > +}
> > +
> > +#ifdef SUPPORT_SUPER_SPEED
> > +VOID
> > +PrintBOSDescriptor (
> > +  IN EFI_USB_BOS_DESCRIPTOR    *BosDesc
> > +  )
> > +{
> > +  DEBUG ((DEBUG_INFO, "--- BOS Descriptor ---\n"));
> > +  DEBUG ((DEBUG_INFO, "Length           : 0x%x\n", BosDesc->Length));
> > +  DEBUG ((DEBUG_INFO, "DescriptorType   : 0x%x\n", BosDesc-
> >DescriptorType));
> > +  DEBUG ((DEBUG_INFO, "TotalLength      : 0x%x\n", BosDesc-
> >TotalLength));
> > +  DEBUG ((DEBUG_INFO, "NumDeviceCaps    : 0x%x\n", BosDesc-
> >NumDeviceCaps));
> > +  DEBUG ((DEBUG_INFO, "\n"));
> > +}
> > +#endif
> > +
> > diff --git
> a/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciUtility.h
> b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciUtility.h
> > new file mode 100644
> > index 0000000000..e3d004e579
> > --- /dev/null
> > +++ b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciUtility.h
> > @@ -0,0 +1,62 @@
> > +/** @file
> > +  Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR>
> > +
> > +  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.
> > +
> > +**/
> > +
> > +#ifndef _XDCI_UTILITY_H_
> > +#define _XDCI_UTILITY_H_
> > +
> > +#include <Library/UsbDeviceLib.h>
> > +
> > +VOID
> > +PrintDeviceDescriptor (
> > +  IN USB_DEVICE_DESCRIPTOR    *DevDesc
> > +  );
> > +
> > +VOID
> > +PrintConfigDescriptor (
> > +  IN EFI_USB_CONFIG_DESCRIPTOR    *ConfigDesc
> > +  );
> > +
> > +VOID
> > +PrintInterfaceDescriptor (
> > +  IN EFI_USB_INTERFACE_DESCRIPTOR    *IfDesc
> > +  );
> > +
> > +VOID
> > +PrintEpDescriptor (
> > +  IN EFI_USB_ENDPOINT_DESCRIPTOR    *EpDesc
> > +  );
> > +
> > +VOID
> > +PrintEpCompDescriptor (
> > +  IN EFI_USB_ENDPOINT_COMPANION_DESCRIPTOR    *EpDesc
> > +  );
> > +
> > +VOID
> > +PrintStringDescriptor (
> > +  IN USB_STRING_DESCRIPTOR    *StrDesc
> > +  );
> > +
> > +VOID
> > +PrintDeviceRequest (
> > +  IN EFI_USB_DEVICE_REQUEST    *DevReq
> > +  );
> > +
> > +#ifdef SUPPORT_SUPER_SPEED
> > +VOID
> > +PrintBOSDescriptor (
> > +  IN EFI_USB_BOS_DESCRIPTOR    *BosDesc
> > +  );
> > +#endif
> > +
> > +#endif
> > +
> > diff --git a/Silicon/Synopsys/DesignWare/Include/Library/UsbDeviceLib.h
> b/Silicon/Synopsys/DesignWare/Include/Library/UsbDeviceLib.h
> > new file mode 100644
> > index 0000000000..fe5f3bcd03
> > --- /dev/null
> > +++ b/Silicon/Synopsys/DesignWare/Include/Library/UsbDeviceLib.h
> > @@ -0,0 +1,323 @@
> > +/** @file
> > +  Copyright (c) 2009 - 2016, Intel Corporation. All rights reserved.<BR>
> > +
> > +  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.
> > +
> > +**/
> > +
> > +#ifndef _EFI_XDCI_LIB_H_
> > +#define _EFI_XDCI_LIB_H_
> > +
> > +#include <Uefi.h>
> > +#include <Library/DebugLib.h>
> > +#include <Library/BaseMemoryLib.h>
> > +#include <Library/MemoryAllocationLib.h>
> > +#include <Library/UefiBootServicesTableLib.h>
> > +#include <Protocol/UsbIo.h>
> > +
> > +#define MAX_DESCRIPTOR_SIZE         64
> > +#define STRING_ARR_SIZE             (MAX_DESCRIPTOR_SIZE - 2)
> > +#define USB_ADDRESS_TABLE_SIZE      16  //4
> > +
> > +//
> > +// Endpoint Zero
> > +//
> > +#define USB_EP0_MAX_PKT_SIZE_HS     0x40 // High Speed mode is
> explicitly set as 64 bytes
> > +#define USB_EP0_MAX_PKT_SIZE_SS     0x9  // Must be 0x9 (2^9 = 512
> Bytes) in SuperSpeed mode
> > +#define USB_EPO_MAX_PKT_SIZE_ALL    512  // Overall max bytes for any
> type
> > +
> > +//
> > +// Bulk Endpoints
> > +//
> > +#define USB_BULK_EP_PKT_SIZE_HS     0x200 // Bulk-Endpoint HighSpeed
> > +#define USB_BULK_EP_PKT_SIZE_SS     0x400 // Bulk-Endpoint SuperSpeed
> > +#define USB_BULK_EP_PKT_SIZE_MAX    USB_BULK_EP_PKT_SIZE_SS
> > +
> > +//
> > +// Transmit Direction Bits
> > +//
> > +#define USB_ENDPOINT_DIR_OUT                 0x00
> > +
> > +//
> > +// Endpoint Companion Bulk Attributes
> > +//
> > +#define USB_EP_BULK_BM_ATTR_MASK    0x1F
> > +
> > +//
> > +// Configuration Modifiers (Attributes)
> > +//
> > +#define USB_BM_ATTR_RESERVED        0x80
> > +#define USB_BM_ATTR_SELF_POWERED    0x40
> > +#define USB_BM_ATTR_REMOTE_WAKE     0X20
> > +
> > +//
> > +// USB BCD version
> > +//
> > +#define USB_BCD_VERSION_LS          0x0110
> > +#define USB_BCD_VERSION_HS          0x0200
> > +#define USB_BCD_VERSION_SS          0x0300
> > +
> > +//
> > +// Device RequestType Flags
> > +//
> > +#define USB_RT_TX_DIR_H_TO_D        (0x0)       // Tx direction Host to
> Device
> > +#define USB_RT_TX_DIR_D_TO_H        (0x1 << 7)  // Tx direction Device to
> Host
> > +#define USB_RT_TX_DIR_MASK          (0x80)
> > +
> > +//
> > +// USB request type
> > +//
> > +#define USB_REQ_TYPE_MASK           (0x60)
> > +
> > +//
> > +// Usb control transfer target
> > +//
> > +#define USB_TARGET_MASK             (0x1F)
> > +
> > +//
> > +// Device GetStatus bits
> > +//
> > +#define USB_STATUS_SELFPOWERED      (0x01)
> > +#define USB_STATUS_REMOTEWAKEUP     (0x02)
> > +
> > +//
> > +// USB Device class identifiers
> > +//
> > +#define USB_DEVICE_MS_CLASS         (0x08)
> > +#define USB_DEVICE_VENDOR_CLASS     (0xFF)
> > +
> > +//
> > +// USB Descriptor types
> > +//
> > +#define USB_DESC_TYPE_BOS                    0x0F
> > +#define USB_DESC_TYPE_DEVICE_CAPABILITY      0x10
> > +#define USB_DESC_TYPE_SS_ENDPOINT_COMPANION  0x30
> > +
> > +#ifdef SUPPORT_SUPER_SPEED
> > +//
> > +// USB device capability Type Codes
> > +// USB3 Table 9-13
> > +//
> > +typedef enum {
> > +  WirelessUSB = 0x01,
> > +  USB2Extension,
> > +  SuperSpeedUSB,
> > +  ContainerID,
> > +  SuperSpeedPlusUSB = 0x0A
> > +} USB_DEVICE_CAP_TYPE_CODE;
> > +#endif
> > +
> > +//
> > +// USB device states from USB spec sec 9.1
> > +//
> > +typedef enum {
> > +  UsbDevStateOff = 0,
> > +  UsbDevStateInit,
> > +  UsbDevStateAttached,
> > +  UsbDevStatePowered,
> > +  UsbDevStateDefault,
> > +  UsbDevStateAddress,
> > +  UsbDevStateConfigured,
> > +  UsbDevStateSuspended,
> > +  UsbDevStateError
> > +} USB_DEVICE_STATE;
> > +
> > +//
> > +// The following set of structs are used during USB data transaction
> > +// operatitions, including requests and completion events.
> > +//
> > +#pragma pack(1)
> > +
> > +typedef struct {
> > +  UINT32     EndpointNum;
> > +  UINT8      EndpointDir;
> > +  UINT8      EndpointType;
> > +  UINT32     Length;
> > +  VOID       *Buffer;
> > +} EFI_USB_DEVICE_XFER_INFO;
> > +
> > +//
> > +// SuperSpeed Endpoint companion descriptor
> > +// USB3 table 9-22
> > +//
> > +typedef struct {
> > +  UINT8      Length;
> > +  UINT8      DescriptorType;
> > +  UINT8      MaxBurst;
> > +  UINT8      Attributes;
> > +  UINT16     BytesPerInterval;
> > +} EFI_USB_ENDPOINT_COMPANION_DESCRIPTOR;
> > +
> > +typedef struct {
> > +  EFI_USB_ENDPOINT_DESCRIPTOR              *EndpointDesc;
> > +  EFI_USB_ENDPOINT_COMPANION_DESCRIPTOR    *EndpointCompDesc;
> > +} USB_DEVICE_ENDPOINT_INFO, USB_DEVICE_ENDPOINT_OBJ;
> > +
> > +typedef struct {
> > +  VOID        *Buffer;
> > +  UINT32      Length;
> > +} USB_DEVICE_IO_INFO;
> > +
> > +typedef struct {
> > +  USB_DEVICE_IO_INFO           IoInfo;
> > +  USB_DEVICE_ENDPOINT_INFO     EndpointInfo;
> > +} USB_DEVICE_IO_REQ;
> > +
> > +//
> > +// Optional string descriptor
> > +//
> > +typedef struct {
> > +  UINT8           Length;
> > +  UINT8           DescriptorType;
> > +  UINT16          LangID[STRING_ARR_SIZE];
> > +} USB_STRING_DESCRIPTOR;
> > +
> > +//
> > +// The following structures abstract the device descriptors a class
> > +// driver needs to provide to the USBD core.
> > +// These structures are filled & owned by the class/function layer.
> > +//
> > +typedef struct {
> > +  EFI_USB_INTERFACE_DESCRIPTOR         *InterfaceDesc;
> > +  USB_DEVICE_ENDPOINT_OBJ              *EndpointObjs;
> > +} USB_DEVICE_INTERFACE_OBJ;
> > +
> > +typedef struct {
> > +  EFI_USB_CONFIG_DESCRIPTOR     *ConfigDesc;
> > +  VOID                          *ConfigAll;
> > +  USB_DEVICE_INTERFACE_OBJ      *InterfaceObjs;
> > +} USB_DEVICE_CONFIG_OBJ;
> > +
> > +#ifdef SUPPORT_SUPER_SPEED
> > +//
> > +// SuperSpeed Binary Device Object Store(BOS) descriptor
> > +// USB3 9.6.2
> > +//
> > +typedef struct {
> > +  UINT8      Length;
> > +  UINT8      DescriptorType;
> > +  UINT16     TotalLength;
> > +  UINT8      NumDeviceCaps;
> > +} EFI_USB_BOS_DESCRIPTOR;
> > +
> > +//
> > +// Generic Header of Device Capability descriptor
> > +// USB3 9.6.2.2
> > +//
> > +typedef struct {
> > +  UINT8      Length;
> > +  UINT8      DescriptorType;
> > +  UINT8      DevCapabilityType;
> > +  UINT8      CapDependent;
> > +} EFI_USB_SS_DEVICE_CAP_DESCRIPTOR;
> > +
> > +//
> > +// USB2.0 Extension descriptor
> > +// USB3 Table 9-14
> > +//
> > +typedef struct {
> > +  UINT8      Length;
> > +  UINT8      DescriptorType;
> > +  UINT8      DeviceCapabilityType;
> > +  UINT32     Attributes;
> > +} EFI_USB_USB2_EXT_CAP_DESCRIPTOR;
> > +
> > +//
> > +// SuperSpeed USB Device Capability descriptor
> > +// USB3 Table 9-15
> > +//
> > +typedef struct {
> > +  UINT8      Length;
> > +  UINT8      DescriptorType;
> > +  UINT8      DeviceCapabilityType;
> > +  UINT8      Attributes;
> > +  UINT16     SpeedSupported;
> > +  UINT8      FunctionalitySupport;
> > +  UINT8      U1DevExitLat;
> > +  UINT16     U2DevExitLat;
> > +} EFI_USB_SS_USB_DEV_CAP_DESCRIPTOR;
> > +
> > +//
> > +// Container ID descriptor
> > +// USB3 Table 9-16
> > +//
> > +typedef struct {
> > +  UINT8      Length;
> > +  UINT8      DescriptorType;
> > +  UINT8      DeviceCapabilityType;
> > +  UINT8      Reserved;
> > +  UINT8      UUID[16];
> > +} EFI_USB_CONTAINER_ID_DESCRIPTOR;
> > +
> > +//
> > +// Container ID descriptor
> > +// USB3 Table 9-16
> > +//
> > +typedef struct {
> > +  UINT8      Length;
> > +  UINT8      DescriptorType;
> > +  UINT8      DeviceCapabilityType;
> > +  UINT8      ReservedByte;
> > +  UINT32     Attributes;
> > +  UINT16     FunctionalitySupport;
> > +  UINT16     ReservedWord;
> > +  UINT32     SublinkSpeedAttr[2];
> > +} EFI_USB_SS_PLUS_USB_DEV_CAP_DESCRIPTOR;
> > +
> > +#endif
> > +
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI *EFI_USB_CONFIG_CALLBACK) (
> > +  IN UINT8                      CfgVal
> > +  );
> > +
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI *EFI_USB_SETUP_CALLBACK) (
> > +  IN EFI_USB_DEVICE_REQUEST     *CtrlRequest,
> > +  IN USB_DEVICE_IO_INFO         *IoInfo
> > +  );
> > +
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI *EFI_USB_DATA_CALLBACK) (
> > +  IN EFI_USB_DEVICE_XFER_INFO   *XferInfo
> > +  );
> > +
> > +typedef struct {
> > +  USB_DEVICE_DESCRIPTOR       *DeviceDesc;
> > +  USB_DEVICE_CONFIG_OBJ       *ConfigObjs;
> > +  USB_STRING_DESCRIPTOR       *StringTable;
> > +#ifdef SUPPORT_SUPER_SPEED
> > +  EFI_USB_BOS_DESCRIPTOR      *BosDesc;
> > +#endif
> > +  UINT8                       StrTblEntries;
> > +  EFI_USB_CONFIG_CALLBACK     ConfigCallback;
> > +  EFI_USB_SETUP_CALLBACK      SetupCallback;
> > +  EFI_USB_DATA_CALLBACK       DataCallback;
> > +} USB_DEVICE_OBJ;
> > +
> > +//
> > +// Main USBD driver object structure containing all data necessary
> > +// for USB device mode processing at this layer
> > +//
> > +typedef struct {
> > +  USB_DEVICE_OBJ              *UsbdDevObj;      /* pointer to a Device Object
> */
> > +  VOID                        *XdciDrvObj;      /* Opaque handle to XDCI driver */
> > +  BOOLEAN                     XdciInitialized;  /* flag to specify if the XDCI driver is
> initialized */
> > +  USB_DEVICE_CONFIG_OBJ       *ActiveConfigObj; /* pointer to currently
> active configuraiton */
> > +  USB_DEVICE_STATE            State;            /* current state of the USB Device
> state machine */
> > +  UINT8                       Address;          /* configured device address */
> > +} USB_DEVICE_DRIVER_OBJ;
> > +
> > +#pragma pack()
> > +
> > +#endif
> > +
> > diff --git a/Silicon/Synopsys/DesignWare/Include/Protocol/EfiUsbFnIo.h
> b/Silicon/Synopsys/DesignWare/Include/Protocol/EfiUsbFnIo.h
> > new file mode 100644
> > index 0000000000..97f276f1cc
> > --- /dev/null
> > +++ b/Silicon/Synopsys/DesignWare/Include/Protocol/EfiUsbFnIo.h
> > @@ -0,0 +1,430 @@
> > +/** @file
> > +  EFI USB function IO Protocol
> > +  This protocol supports Usb Function IO API.
> > +  Copyright (c) 1999 - 2017, Intel Corporation. All rights reserved.<BR>
> > +
> > +  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.
> > +
> > +**/
> > +
> > +#ifndef __EFI_USB_FUNC_IO_H__
> > +#define __EFI_USB_FUNC_IO_H__
> > +
> > +#include <IndustryStandard/Usb.h>
> > +
> > +#define EFI_USBFN_IO_PROTOCOL_REVISION   0x00010001
> > +
> > +//
> > +// {32D2963A-FE5D-4f30-B633-6E5DC55803CC}
> > +// #define EFI_USBFN_IO_PROTOCOL_GUID  {0x32d2963a, 0xfe5d, 0x4f30,
> 0xb6, 0x33, 0x6e, 0x5d, 0xc5, 0x58, 0x3, 0xcc };
> > +//
> > +
> > +typedef struct _EFI_USBFN_IO_PROTOCOL   EFI_USBFN_IO_PROTOCOL;
> > +
> > +//
> > +// USB standard descriptors and reqeust
> > +//
> > +typedef USB_DEVICE_REQUEST        EFI_USB_DEVICE_REQUEST;
> > +typedef USB_DEVICE_DESCRIPTOR     EFI_USB_DEVICE_DESCRIPTOR;
> > +typedef USB_CONFIG_DESCRIPTOR     EFI_USB_CONFIG_DESCRIPTOR;
> > +typedef USB_INTERFACE_DESCRIPTOR  EFI_USB_INTERFACE_DESCRIPTOR;
> > +typedef USB_ENDPOINT_DESCRIPTOR   EFI_USB_ENDPOINT_DESCRIPTOR;
> > +
> > +typedef enum _EFI_USBFN_PORT_TYPE {
> > +  EfiUsbUnknownPort = 0,
> > +  EfiUsbStandardDownstreamPort,
> > +  EfiUsbChargingDownstreamPort,
> > +  EfiUsbDedicatedChargingPort,
> > +  EfiUsbInvalidDedicatedChargingPort
> > +} EFI_USBFN_PORT_TYPE;
> > +
> > +/**
> > + USB_DEVICE_DESCRIPTOR, USB_CONFIG_DESCRIPTOR,
> USB_INTERFACE_DESCRIPTOR, and
> > + USB_ENDPOINT_DESCRIPTOR are already defined
> > + in UEFI spec 2.3, as par USB 2.0 spec.
> > +**/
> > +
> > +typedef struct {
> > +  EFI_USB_INTERFACE_DESCRIPTOR        *InterfaceDescriptor;
> > +  EFI_USB_ENDPOINT_DESCRIPTOR         **EndpointDescriptorTable;
> > +} EFI_USB_INTERFACE_INFO;
> > +
> > +typedef struct {
> > +  EFI_USB_CONFIG_DESCRIPTOR           *ConfigDescriptor;
> > +  EFI_USB_INTERFACE_INFO              **InterfaceInfoTable;
> > +} EFI_USB_CONFIG_INFO;
> > +
> > +typedef struct {
> > +  EFI_USB_DEVICE_DESCRIPTOR           *DeviceDescriptor;
> > +  EFI_USB_CONFIG_INFO                 **ConfigInfoTable;
> > +} EFI_USB_DEVICE_INFO;
> > +
> > +
> > +typedef enum _EFI_USB_ENDPOINT_TYPE {
> > +  UsbEndpointControl     = 0x00,
> > +  UsbEndpointIsochronous = 0x01,
> > +  UsbEndpointBulk        = 0x02,
> > +  UsbEndpointInterrupt   = 0x03
> > +} EFI_USB_ENDPOINT_TYPE;
> > +
> > +
> > +typedef enum _EFI_USBFN_DEVICE_INFO_ID {
> > +  EfiUsbDeviceInfoUnknown = 0,
> > +  EfiUsbDeviceInfoSerialNumber,
> > +  EfiUsbDeviceInfoManufacturerName,
> > +  EfiUsbDeviceInfoProductName
> > +} EFI_USBFN_DEVICE_INFO_ID;
> > +
> > +
> > +typedef enum _EFI_USBFN_ENDPOINT_DIRECTION {
> > +  EfiUsbEndpointDirectionHostOut  = 0,
> > +  EfiUsbEndpointDirectionHostIn,
> > +  EfiUsbEndpointDirectionDeviceTx = EfiUsbEndpointDirectionHostIn,
> > +  EfiUsbEndpointDirectionDeviceRx = EfiUsbEndpointDirectionHostOut
> > +} EFI_USBFN_ENDPOINT_DIRECTION;
> > +
> > +
> > +typedef enum _EFI_USBFN_MESSAGE {
> > +  //
> > +  // Nothing
> > +  //
> > +  EfiUsbMsgNone = 0,
> > +  //
> > +  // SETUP packet is received, returned Buffer contains
> > +  // EFI_USB_DEVICE_REQUEST struct
> > +  //
> > +  EfiUsbMsgSetupPacket,
> > +  //
> > +  // Indicates that some of the requested data has been received from the
> > +  // host. It is the responsibility of the class driver to determine if it
> > +  // needs to wait for any remaining data. Returned Buffer contains
> > +  // EFI_USBFN_TRANSFER_RESULT struct containing endpoint number,
> transfer
> > +  // status and count of bytes received.
> > +  //
> > +  EfiUsbMsgEndpointStatusChangedRx,
> > +  //
> > +  // Indicates that some of the requested data has been transmitted to the
> > +  // host. It is the responsibility of the class driver to determine if any
> > +  // remaining data needs to be resent. Returned Buffer contains
> > +  // EFI_USBFN_TRANSFER_RESULT struct containing endpoint number,
> transfer
> > +  // status and count of bytes sent.
> > +  //
> > +  EfiUsbMsgEndpointStatusChangedTx,
> > +  //
> > +  // DETACH bus event signaled
> > +  //
> > +  EfiUsbMsgBusEventDetach,
> > +  //
> > +  // ATTACH bus event signaled
> > +  //
> > +  EfiUsbMsgBusEventAttach,
> > +  //
> > +  // RESET bus event signaled
> > +  //
> > +  EfiUsbMsgBusEventReset,
> > +  //
> > +  // SUSPEND bus event signaled
> > +  //
> > +  EfiUsbMsgBusEventSuspend,
> > +  //
> > +  // RESUME bus event signaled
> > +  //
> > +  EfiUsbMsgBusEventResume,
> > +  //
> > +  // Bus speed updated, returned buffer indicated bus speed using
> > +  // following enumeration named EFI_USB_BUS_SPEED
> > +  //
> > +  EfiUsbMsgBusEventSpeed
> > +} EFI_USBFN_MESSAGE;
> > +
> > +
> > +typedef enum _EFI_USBFN_TRANSFER_STATUS {
> > +  UsbTransferStatusUnknown = 0,
> > +  UsbTransferStatusComplete,
> > +  UsbTransferStatusAborted,
> > +  UsbTransferStatusActive,
> > +  UsbTransferStatusNone
> > +} EFI_USBFN_TRANSFER_STATUS;
> > +
> > +
> > +typedef struct _EFI_USBFN_TRANSFER_RESULT {
> > +  UINTN                         BytesTransferred;
> > +  EFI_USBFN_TRANSFER_STATUS     TransferStatus;
> > +  UINT8                         EndpointIndex;
> > +  EFI_USBFN_ENDPOINT_DIRECTION  Direction;
> > +  VOID                          *Buffer;
> > +} EFI_USBFN_TRANSFER_RESULT;
> > +
> > +typedef enum _EFI_USB_BUS_SPEED {
> > +  UsbBusSpeedUnknown = 0,
> > +  UsbBusSpeedLow,
> > +  UsbBusSpeedFull,
> > +  UsbBusSpeedHigh,
> > +  UsbBusSpeedSuper,
> > +  UsbBusSpeedMaximum = UsbBusSpeedSuper
> > +} EFI_USB_BUS_SPEED;
> > +
> > +typedef union _EFI_USBFN_MESSAGE_PAYLOAD {
> > +  EFI_USB_DEVICE_REQUEST      udr;
> > +  EFI_USBFN_TRANSFER_RESULT   utr;
> > +  EFI_USB_BUS_SPEED           ubs;
> > +} EFI_USBFN_MESSAGE_PAYLOAD;
> > +
> > +typedef enum _EFI_USBFN_POLICY_TYPE {
> > +  EfiUsbPolicyUndefined = 0,
> > +  EfiUsbPolicyMaxTransactionSize,
> > +  EfiUsbPolicyZeroLengthTerminationSupport,
> > +  EfiUsbPolicyZeroLengthTermination
> > +} EFI_USBFN_POLICY_TYPE;
> > +
> > +
> > +/**
> > +
> > + Allocates transfer buffer of the specified size that satisfies
> > + controller requirements.
> > +
> > + The AllocateTransferBuffer function allocates a memory region of Size
> bytes and
> > + returns the address of the allocated memory that satisfies underlying
> > + controller requirements in the location referenced by Buffer.
> > +
> > +**/
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI * EFI_USBFN_IO_ALLOCATE_TRANSFER_BUFFER) (
> > +  IN EFI_USBFN_IO_PROTOCOL    *This,
> > +  IN UINTN                    Size,
> > +  OUT VOID                    **Buffer
> > +  );
> > +
> > +/**
> > +
> > +  Deallocates the memory allocated for the transfer buffer by
> AllocateTransferBuffer function.
> > +
> > +**/
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI * EFI_USBFN_IO_FREE_TRANSFER_BUFFER) (
> > +  IN EFI_USBFN_IO_PROTOCOL    *This,
> > +  IN VOID                     *Buffer
> > +  );
> > +
> > +/**
> > +  Returns information about what type of device was attached.
> > +
> > +**/
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI * EFI_USBFN_IO_DETECT_PORT) (
> > +  IN EFI_USBFN_IO_PROTOCOL   *This,
> > +  OUT EFI_USBFN_PORT_TYPE    *PortType
> > +  );
> > +
> > +/**
> > +  Configure endpoints based on supplied device and configuration
> descriptors.
> > +**/
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI * EFI_USBFN_IO_CONFIGURE_ENABLE_ENDPOINTS) (
> > +  IN EFI_USBFN_IO_PROTOCOL         *This,
> > +  IN EFI_USB_DEVICE_INFO           *DeviceInfo
> > +  );
> > +
> > +
> > +/**
> > +  Returns the maximum packet size of the specified endpoint type for the
> supplied bus speed.
> > +**/
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI * EFI_USBFN_IO_GET_ENDPOINT_MAXPACKET_SIZE) (
> > +  IN EFI_USBFN_IO_PROTOCOL       *This,
> > +  IN EFI_USB_ENDPOINT_TYPE       EndpointType,
> > +  IN EFI_USB_BUS_SPEED           BusSpeed,
> > +  OUT UINT16                     *MaxPacketSize
> > +  );
> > +
> > +/**
> > +  Returns the maximum supported transfer size.
> > +**/
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI * EFI_USBFN_IO_GET_MAXTRANSFER_SIZE) (
> > +  IN EFI_USBFN_IO_PROTOCOL     *This,
> > +  OUT UINTN                    *MaxTransferSize
> > +  );
> > +
> > +/**
> > +  Returns device specific information based on the supplied identifier as a
> > +  Unicode string.
> > +**/
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI * EFI_USBFN_IO_GET_DEVICE_INFO) (
> > +  IN EFI_USBFN_IO_PROTOCOL      *This,
> > +  IN EFI_USBFN_DEVICE_INFO_ID   Id,
> > +  IN OUT UINTN                  *BufferSize,
> > +  OUT VOID                      *Buffer OPTIONAL
> > +  );
> > +
> > +/**
> > +  Returns vendor-id and product-id of the device.
> > +**/
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI * EFI_USBFN_IO_GET_VENDOR_ID_PRODUCT_ID) (
> > +  IN EFI_USBFN_IO_PROTOCOL      *This,
> > +  OUT UINT16                    *Vid,
> > +  OUT UINT16                    *Pid
> > +  );
> > +
> > +/**
> > +  Aborts transfer on the specified endpoint.
> > +**/
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI * EFI_USBFN_IO_ABORT_TRANSFER) (
> > +  IN EFI_USBFN_IO_PROTOCOL        *This,
> > +  IN UINT8                        EndpointIndex,
> > +  IN EFI_USBFN_ENDPOINT_DIRECTION Direction
> > +  );
> > +
> > +/**
> > +  Returns the stall state on the specified endpoint.
> > +**/
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI * EFI_USBFN_IO_GET_ENDPOINT_STALL_STATE) (
> > +  IN EFI_USBFN_IO_PROTOCOL        *This,
> > +  IN UINT8                        EndpointIndex,
> > +  IN EFI_USBFN_ENDPOINT_DIRECTION Direction,
> > +  IN OUT BOOLEAN                  *State
> > +  );
> > +
> > +/**
> > +  Sets or clears the stall state on the specified endpoint.
> > +**/
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI * EFI_USBFN_IO_SET_ENDPOINT_STALL_STATE) (
> > +  IN EFI_USBFN_IO_PROTOCOL        *This,
> > +  IN UINT8                        EndpointIndex,
> > +  IN EFI_USBFN_ENDPOINT_DIRECTION Direction,
> > +  IN BOOLEAN                      State
> > +  );
> > +
> > +
> > +/**
> > +  This function is called repeatedly to receive updates on USB bus states,
> > +  receive, transmit status changes on endpoints and setup packet on
> endpoint 0.
> > +**/
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI * EFI_USBFN_IO_EVENTHANDLER) (
> > +  IN EFI_USBFN_IO_PROTOCOL        *This,
> > +  OUT EFI_USBFN_MESSAGE           *Message,
> > +  IN OUT UINTN                    *PayloadSize,
> > +  OUT EFI_USBFN_MESSAGE_PAYLOAD   *Payload
> > +  );
> > +
> > +/**
> > +  Primary function to handle transfer in either direction based on specified
> > +  direction and on the specified endpoint.
> > +**/
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI *EFI_USBFN_IO_TRANSFER) (
> > +  IN EFI_USBFN_IO_PROTOCOL         *This,
> > +  IN UINT8                         EndpointIndex,
> > +  IN EFI_USBFN_ENDPOINT_DIRECTION  Direction,
> > +  IN OUT UINTN                     *BufferSize,
> > +  IN OUT VOID                      *Buffer
> > +  );
> > +
> > +/**
> > +  This function supplies power to the USB controller if needed,
> > +  initialize hardware and internal data structures, and then return.
> > +
> > +  The port must not be activated by this function.
> > +**/
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI * EFI_USBFN_IO_START_CONTROLLER) (
> > +    IN EFI_USBFN_IO_PROTOCOL    *This
> > +    );
> > +
> > +/**
> > +  This function disables the hardware device by resetting the run/stop bit
> and
> > +  power off the USB controller if needed.
> > +**/
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI * EFI_USBFN_IO_STOP_CONTROLLER) (
> > +    IN EFI_USBFN_IO_PROTOCOL    *This
> > +    );
> > +
> > +/**
> > +  This function sets the configuration policy for the specified non-control
> endpoint.
> > +
> > +  Refer to the description for calling restrictions.
> > +**/
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI * EFI_USBFN_IO_SET_ENDPOINT_POLICY) (
> > +  IN EFI_USBFN_IO_PROTOCOL        *This,
> > +  IN UINT8                        EndpointIndex,
> > +  IN EFI_USBFN_ENDPOINT_DIRECTION Direction,
> > +  IN EFI_USBFN_POLICY_TYPE        PolicyType,
> > +  IN UINTN                        BufferSize,
> > +  IN VOID                         *Buffer
> > +  );
> > +
> > +/**
> > +  This function retrieves the configuration policy for the specified non-
> control endpoint.
> > +
> > +  There are no associated calling restrictions for this function.
> > +**/
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI * EFI_USBFN_IO_GET_ENDPOINT_POLICY) (
> > +  IN EFI_USBFN_IO_PROTOCOL        *This,
> > +  IN UINT8                        EndpointIndex,
> > +  IN EFI_USBFN_ENDPOINT_DIRECTION Direction,
> > +  IN EFI_USBFN_POLICY_TYPE        PolicyType,
> > +  IN OUT UINTN                    *BufferSize,
> > +  IN OUT VOID                     *Buffer
> > +  );
> > +
> > +
> > +struct _EFI_USBFN_IO_PROTOCOL {
> > +  UINT32                                      Revision;
> > +  EFI_USBFN_IO_DETECT_PORT                    DetectPort;
> > +  EFI_USBFN_IO_CONFIGURE_ENABLE_ENDPOINTS
> ConfigureEnableEndpoints;
> > +  EFI_USBFN_IO_GET_ENDPOINT_MAXPACKET_SIZE
> GetEndpointMaxPacketSize;
> > +  EFI_USBFN_IO_GET_DEVICE_INFO                GetDeviceInfo;
> > +  EFI_USBFN_IO_GET_VENDOR_ID_PRODUCT_ID
> GetVendorIdProductId;
> > +  EFI_USBFN_IO_ABORT_TRANSFER                 AbortTransfer;
> > +  EFI_USBFN_IO_GET_ENDPOINT_STALL_STATE       GetEndpointStallState;
> > +  EFI_USBFN_IO_SET_ENDPOINT_STALL_STATE       SetEndpointStallState;
> > +  EFI_USBFN_IO_EVENTHANDLER                   EventHandler;
> > +  EFI_USBFN_IO_TRANSFER                       Transfer;
> > +  EFI_USBFN_IO_GET_MAXTRANSFER_SIZE           GetMaxTransferSize;
> > +  EFI_USBFN_IO_ALLOCATE_TRANSFER_BUFFER       AllocateTransferBuffer;
> > +  EFI_USBFN_IO_FREE_TRANSFER_BUFFER           FreeTransferBuffer;
> > +  //
> > +  // Valid for version EFI_USBFN_IO_PROTOCOL_REVISION2 and above
> > +  //
> > +  EFI_USBFN_IO_START_CONTROLLER               StartController;
> > +  EFI_USBFN_IO_STOP_CONTROLLER                StopController;
> > +  EFI_USBFN_IO_SET_ENDPOINT_POLICY            SetEndpointPolicy;
> > +  EFI_USBFN_IO_GET_ENDPOINT_POLICY            GetEndpointPolicy;
> > +};
> > +
> > +
> > +extern EFI_GUID gEfiUsbFnIoProtocolGuid;
> > +#endif
> > +
> > diff --git
> a/Silicon/Synopsys/DesignWare/Include/Protocol/UsbDeviceModeProtocol.h
> b/Silicon/Synopsys/DesignWare/Include/Protocol/UsbDeviceModeProtocol.h
> > new file mode 100644
> > index 0000000000..c301fa00d3
> > --- /dev/null
> > +++
> b/Silicon/Synopsys/DesignWare/Include/Protocol/UsbDeviceModeProtocol.h
> > @@ -0,0 +1,104 @@
> > +/** @file
> > +  Copyright (c) 1999 - 2017, Intel Corporation. All rights reserved.<BR>
> > +
> > +  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.
> > +
> > +**/
> > +
> > +
> > +#ifndef _USB_DEVICE_MODE_PROTOCOL_H_
> > +#define _USB_DEVICE_MODE_PROTOCOL_H_
> > +
> > +#include <Library/UsbDeviceLib.h>
> > +
> > +///
> > +/// UsbDeviceMode Protocol GUID.
> > +///
> > +#define EFI_USB_DEVICE_MODE_PROTOCOL_GUID \
> > +  {0xC9923F7E, 0x1746, 0x4802, { 0x86, 0x2e, 0x1, 0x1c, 0x2c, 0x2d, 0x9d,
> 0x86 } }
> > +
> > +typedef struct _EFI_USB_DEVICE_MODE_PROTOCOL
> EFI_USB_DEVICE_MODE_PROTOCOL;
> > +
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI *EFI_USB_DEVICE_MODE_INIT_XDCI) (
> > +  IN EFI_USB_DEVICE_MODE_PROTOCOL               *This
> > +  );
> > +
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI *EFI_USB_DEVICE_MODE_CONNECT) (
> > +  IN EFI_USB_DEVICE_MODE_PROTOCOL               *This
> > +  );
> > +
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI *EFI_USB_DEVICE_MODE_DISCONNECT) (
> > +  IN EFI_USB_DEVICE_MODE_PROTOCOL               *This
> > +  );
> > +
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI *EFI_USB_DEVICE_EP_TX_DATA) (
> > +  IN EFI_USB_DEVICE_MODE_PROTOCOL               *This,
> > +  IN USB_DEVICE_IO_REQ                          *IoRequest
> > +  );
> > +
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI *EFI_USB_DEVICE_EP_RX_DATA) (
> > +  IN EFI_USB_DEVICE_MODE_PROTOCOL               *This,
> > +  IN USB_DEVICE_IO_REQ                          *IoRequest
> > +  );
> > +
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI *EFI_USB_DEVICE_MODE_BIND) (
> > +  IN EFI_USB_DEVICE_MODE_PROTOCOL               *This,
> > +  IN USB_DEVICE_OBJ                             *UsbdDevObj
> > +  );
> > +
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI *EFI_USB_DEVICE_MODE_UNBIND) (
> > +  IN EFI_USB_DEVICE_MODE_PROTOCOL               *This
> > +  );
> > +
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI *EFI_USB_DEVICE_MODE_STOP) (
> > +  IN EFI_USB_DEVICE_MODE_PROTOCOL               *This
> > +  );
> > +
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI *EFI_USB_DEVICE_MODE_RUN) (
> > +  IN EFI_USB_DEVICE_MODE_PROTOCOL               *This,
> > +  IN UINT32                                     TimeoutMs
> > +  );
> > +
> > +///
> > +/// Usb Device Mode Protocol Structure.
> > +///
> > +struct _EFI_USB_DEVICE_MODE_PROTOCOL {
> > +  EFI_USB_DEVICE_MODE_INIT_XDCI            InitXdci;
> > +  EFI_USB_DEVICE_MODE_CONNECT              Connect;
> > +  EFI_USB_DEVICE_MODE_DISCONNECT           DisConnect;
> > +  EFI_USB_DEVICE_EP_TX_DATA                EpTxData;
> > +  EFI_USB_DEVICE_EP_RX_DATA                EpRxData;
> > +  EFI_USB_DEVICE_MODE_BIND                 Bind;
> > +  EFI_USB_DEVICE_MODE_UNBIND               UnBind;
> > +  EFI_USB_DEVICE_MODE_RUN                  Run;
> > +  EFI_USB_DEVICE_MODE_STOP                 Stop;
> > +};
> > +
> > +extern EFI_GUID gEfiUsbDeviceModeProtocolGuid;
> > +
> > +#endif
> > +
> > --
> > 2.27.0.windows.1
> >

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [edk2-platforms PATCH 1/5] Silicon/Synopsys/DesignWare: Import DesignWare USB3 peripheral driver
  2020-07-21  3:51   ` Vin Xue
@ 2020-07-30 12:18     ` Leif Lindholm
  2020-08-05 10:50       ` Vin Xue
  0 siblings, 1 reply; 6+ messages in thread
From: Leif Lindholm @ 2020-07-30 12:18 UTC (permalink / raw)
  To: Vin Xue; +Cc: devel@edk2.groups.io, Michael D Kinney

Hi Vin, +Mike,

Sorry for delay in responding.
OK, so we know where it comes from - but we can no longer accept code
under the plan 2-clause BSD license into edk2-platforms master.
However, 2-clause BSD can be relicensed as 2-clause BSD + patent.

Please do so, converting the comment header license statements to
SPDX-License-Identifier: BSD-2-Clause-Patent
tags.

I also think there is more than one DesignWare USB controller, so we
could probably do with a more specific directory name than
"UsbDeviceDxe".

Best Regards,

Leif

On Tue, Jul 21, 2020 at 03:51:19 +0000, Vin Xue wrote:
> Hi Leif,
> 
> The origin code is from edk2-platforms
> /devel-IntelAtomProcessorE3900 branch.
> https://github.com/tianocore/edk2-platforms/
> tree/devel-IntelAtomProcessorE3900/Platform/
> BroxtonPlatformPkg/Common/Features/UsbDeviceDxe
> 
> In Patch 1/5 is the origin source code with BSD2 license, and
> I updated license to BSD+Patent license in Patch 2/5.
> Please check it.
> 
> From my review, the driver code flow is similar to Linux kernel
> DWC3 driver. Maybe it's feasible to ARM platform if do some changes.
> 
> Best regards,
> Vin
> 
> ________________________________
> From: Leif Lindholm <leif@nuviainc.com>
> Sent: Tuesday, July 21, 2020 1:43 AM
> To: Vin Xue <vinxue@outlook.com>
> Cc: devel@edk2.groups.io <devel@edk2.groups.io>; Ard Biesheuvel <ard.biesheuvel@arm.com>; Meenakshi Aggarwal <meenakshi.aggarwal@oss.nxp.com>
> Subject: Re: [edk2-platforms PATCH 1/5] Silicon/Synopsys/DesignWare: Import DesignWare USB3 peripheral driver
> 
> Hi Vin, +Meenakshi
> 
> Can you clarify the exact origin of this source code please?
> We can only accept bsd+patent code contributions, and these days we
> use only SPDX tags rather than full license statements at top of
> files.
> 
> Meenakshi - I would certainly prefer to have a single (and
> Arm-functional) driver for DWC3 rather than init-only drivers per
> platform. Can you have a look at this code plese and see if it looks
> feasible to integrate in the NXP platforms?
> 
> Regards,
> 
> Leif
> 
> On Fri, Jul 17, 2020 at 18:01:59 +0800, Vin Xue wrote:
> > Incorporate the driver for the DesignWare USB3 DRD controller device
> > mode (peripheral) that is defined in
> > edk2-platforms/devel-IntelAtomProcessorE3900 branch.
> >
> > The driver is supported by Intel Atom series (Merrifield/BayTrail/
> > CherryTrail/Broxton/ApoloLake/GeminiLake etc.) and Core series
> > (6th Generation and newer).
> >
> > The driver verified on AAEON UP Squared developer board (Intel
> > ApoloLake platform).
> >
> > The driver supports Synopsys DesignWare DWC_usb3 and DWC_usb31 IP.
> >
> > It is better if the driver can be ported to ARM silicon.
> >
> > Cc: Ard Biesheuvel <ard.biesheuvel@arm.com>
> > Cc: Leif Lindholm <leif@nuviainc.com>
> > Signed-off-by: Vin Xue <vinxue@outlook.com>
> > ---
> >  .../Drivers/UsbDeviceDxe/ComponentName.c      |  305 ++
> >  .../Drivers/UsbDeviceDxe/UsbDeviceDxe.c       |  395 ++
> >  .../Drivers/UsbDeviceDxe/UsbDeviceDxe.h       |  159 +
> >  .../Drivers/UsbDeviceDxe/UsbDeviceDxe.inf     |   74 +
> >  .../Drivers/UsbDeviceDxe/UsbDeviceMode.c      | 1489 ++++++
> >  .../Drivers/UsbDeviceDxe/UsbDeviceMode.h      |   39 +
> >  .../Drivers/UsbDeviceDxe/UsbFuncIo.c          | 2221 +++++++++
> >  .../Drivers/UsbDeviceDxe/UsbFuncIo.h          |  234 +
> >  .../Drivers/UsbDeviceDxe/UsbIoNode.c          |  177 +
> >  .../Drivers/UsbDeviceDxe/UsbIoNode.h          |   90 +
> >  .../Drivers/UsbDeviceDxe/XdciCommon.h         |  156 +
> >  .../DesignWare/Drivers/UsbDeviceDxe/XdciDWC.c | 4030 +++++++++++++++++
> >  .../DesignWare/Drivers/UsbDeviceDxe/XdciDWC.h |  741 +++
> >  .../Drivers/UsbDeviceDxe/XdciDevice.c         |  695 +++
> >  .../Drivers/UsbDeviceDxe/XdciDevice.h         |  184 +
> >  .../Drivers/UsbDeviceDxe/XdciInterface.h      |  241 +
> >  .../Drivers/UsbDeviceDxe/XdciTable.c          |   55 +
> >  .../Drivers/UsbDeviceDxe/XdciUtility.c        |  148 +
> >  .../Drivers/UsbDeviceDxe/XdciUtility.h        |   62 +
> >  .../DesignWare/Include/Library/UsbDeviceLib.h |  323 ++
> >  .../DesignWare/Include/Protocol/EfiUsbFnIo.h  |  430 ++
> >  .../Include/Protocol/UsbDeviceModeProtocol.h  |  104 +
> >  22 files changed, 12352 insertions(+)
> >  create mode 100644 Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/ComponentName.c
> >  create mode 100644 Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbDeviceDxe.c
> >  create mode 100644 Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbDeviceDxe.h
> >  create mode 100644 Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbDeviceDxe.inf
> >  create mode 100644 Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbDeviceMode.c
> >  create mode 100644 Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbDeviceMode.h
> >  create mode 100644 Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbFuncIo.c
> >  create mode 100644 Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbFuncIo.h
> >  create mode 100644 Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbIoNode.c
> >  create mode 100644 Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbIoNode.h
> >  create mode 100644 Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciCommon.h
> >  create mode 100644 Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciDWC.c
> >  create mode 100644 Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciDWC.h
> >  create mode 100644 Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciDevice.c
> >  create mode 100644 Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciDevice.h
> >  create mode 100644 Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciInterface.h
> >  create mode 100644 Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciTable.c
> >  create mode 100644 Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciUtility.c
> >  create mode 100644 Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciUtility.h
> >  create mode 100644 Silicon/Synopsys/DesignWare/Include/Library/UsbDeviceLib.h
> >  create mode 100644 Silicon/Synopsys/DesignWare/Include/Protocol/EfiUsbFnIo.h
> >  create mode 100644 Silicon/Synopsys/DesignWare/Include/Protocol/UsbDeviceModeProtocol.h

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [edk2-platforms PATCH 1/5] Silicon/Synopsys/DesignWare: Import DesignWare USB3 peripheral driver
  2020-07-30 12:18     ` Leif Lindholm
@ 2020-08-05 10:50       ` Vin Xue
  0 siblings, 0 replies; 6+ messages in thread
From: Vin Xue @ 2020-08-05 10:50 UTC (permalink / raw)
  To: Leif Lindholm; +Cc: devel@edk2.groups.io, Michael D Kinney

[-- Attachment #1: Type: text/plain, Size: 7042 bytes --]

Hi Leif,

Sorry I missed your mail.

For License issue I will update it later.

I know there are some DesignWare USB controller driver, but most of them
are for USB Host Mode. The driver "UsbDeviceDxe" is for USB Device Mode
(i.e. peripheral). Usually it can be as the driver to support Android Fastboot
feature. How about your suggestion about directory name? (Also change driver
name?)

Best regards,
Vin

________________________________
From: Leif Lindholm <leif@nuviainc.com>
Sent: Thursday, July 30, 2020 8:18 PM
To: Vin Xue <vinxue@outlook.com>
Cc: devel@edk2.groups.io <devel@edk2.groups.io>; Michael D Kinney <michael.d.kinney@intel.com>
Subject: Re: [edk2-platforms PATCH 1/5] Silicon/Synopsys/DesignWare: Import DesignWare USB3 peripheral driver

Hi Vin, +Mike,

Sorry for delay in responding.
OK, so we know where it comes from - but we can no longer accept code
under the plan 2-clause BSD license into edk2-platforms master.
However, 2-clause BSD can be relicensed as 2-clause BSD + patent.

Please do so, converting the comment header license statements to
SPDX-License-Identifier: BSD-2-Clause-Patent
tags.

I also think there is more than one DesignWare USB controller, so we
could probably do with a more specific directory name than
"UsbDeviceDxe".

Best Regards,

Leif

On Tue, Jul 21, 2020 at 03:51:19 +0000, Vin Xue wrote:
> Hi Leif,
>
> The origin code is from edk2-platforms
> /devel-IntelAtomProcessorE3900 branch.
> https://github.com/tianocore/edk2-platforms/
> tree/devel-IntelAtomProcessorE3900/Platform/
> BroxtonPlatformPkg/Common/Features/UsbDeviceDxe
>
> In Patch 1/5 is the origin source code with BSD2 license, and
> I updated license to BSD+Patent license in Patch 2/5.
> Please check it.
>
> From my review, the driver code flow is similar to Linux kernel
> DWC3 driver. Maybe it's feasible to ARM platform if do some changes.
>
> Best regards,
> Vin
>
> ________________________________
> From: Leif Lindholm <leif@nuviainc.com>
> Sent: Tuesday, July 21, 2020 1:43 AM
> To: Vin Xue <vinxue@outlook.com>
> Cc: devel@edk2.groups.io <devel@edk2.groups.io>; Ard Biesheuvel <ard.biesheuvel@arm.com>; Meenakshi Aggarwal <meenakshi.aggarwal@oss.nxp.com>
> Subject: Re: [edk2-platforms PATCH 1/5] Silicon/Synopsys/DesignWare: Import DesignWare USB3 peripheral driver
>
> Hi Vin, +Meenakshi
>
> Can you clarify the exact origin of this source code please?
> We can only accept bsd+patent code contributions, and these days we
> use only SPDX tags rather than full license statements at top of
> files.
>
> Meenakshi - I would certainly prefer to have a single (and
> Arm-functional) driver for DWC3 rather than init-only drivers per
> platform. Can you have a look at this code plese and see if it looks
> feasible to integrate in the NXP platforms?
>
> Regards,
>
> Leif
>
> On Fri, Jul 17, 2020 at 18:01:59 +0800, Vin Xue wrote:
> > Incorporate the driver for the DesignWare USB3 DRD controller device
> > mode (peripheral) that is defined in
> > edk2-platforms/devel-IntelAtomProcessorE3900 branch.
> >
> > The driver is supported by Intel Atom series (Merrifield/BayTrail/
> > CherryTrail/Broxton/ApoloLake/GeminiLake etc.) and Core series
> > (6th Generation and newer).
> >
> > The driver verified on AAEON UP Squared developer board (Intel
> > ApoloLake platform).
> >
> > The driver supports Synopsys DesignWare DWC_usb3 and DWC_usb31 IP.
> >
> > It is better if the driver can be ported to ARM silicon.
> >
> > Cc: Ard Biesheuvel <ard.biesheuvel@arm.com>
> > Cc: Leif Lindholm <leif@nuviainc.com>
> > Signed-off-by: Vin Xue <vinxue@outlook.com>
> > ---
> >  .../Drivers/UsbDeviceDxe/ComponentName.c      |  305 ++
> >  .../Drivers/UsbDeviceDxe/UsbDeviceDxe.c       |  395 ++
> >  .../Drivers/UsbDeviceDxe/UsbDeviceDxe.h       |  159 +
> >  .../Drivers/UsbDeviceDxe/UsbDeviceDxe.inf     |   74 +
> >  .../Drivers/UsbDeviceDxe/UsbDeviceMode.c      | 1489 ++++++
> >  .../Drivers/UsbDeviceDxe/UsbDeviceMode.h      |   39 +
> >  .../Drivers/UsbDeviceDxe/UsbFuncIo.c          | 2221 +++++++++
> >  .../Drivers/UsbDeviceDxe/UsbFuncIo.h          |  234 +
> >  .../Drivers/UsbDeviceDxe/UsbIoNode.c          |  177 +
> >  .../Drivers/UsbDeviceDxe/UsbIoNode.h          |   90 +
> >  .../Drivers/UsbDeviceDxe/XdciCommon.h         |  156 +
> >  .../DesignWare/Drivers/UsbDeviceDxe/XdciDWC.c | 4030 +++++++++++++++++
> >  .../DesignWare/Drivers/UsbDeviceDxe/XdciDWC.h |  741 +++
> >  .../Drivers/UsbDeviceDxe/XdciDevice.c         |  695 +++
> >  .../Drivers/UsbDeviceDxe/XdciDevice.h         |  184 +
> >  .../Drivers/UsbDeviceDxe/XdciInterface.h      |  241 +
> >  .../Drivers/UsbDeviceDxe/XdciTable.c          |   55 +
> >  .../Drivers/UsbDeviceDxe/XdciUtility.c        |  148 +
> >  .../Drivers/UsbDeviceDxe/XdciUtility.h        |   62 +
> >  .../DesignWare/Include/Library/UsbDeviceLib.h |  323 ++
> >  .../DesignWare/Include/Protocol/EfiUsbFnIo.h  |  430 ++
> >  .../Include/Protocol/UsbDeviceModeProtocol.h  |  104 +
> >  22 files changed, 12352 insertions(+)
> >  create mode 100644 Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/ComponentName.c
> >  create mode 100644 Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbDeviceDxe.c
> >  create mode 100644 Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbDeviceDxe.h
> >  create mode 100644 Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbDeviceDxe.inf
> >  create mode 100644 Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbDeviceMode.c
> >  create mode 100644 Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbDeviceMode.h
> >  create mode 100644 Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbFuncIo.c
> >  create mode 100644 Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbFuncIo.h
> >  create mode 100644 Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbIoNode.c
> >  create mode 100644 Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbIoNode.h
> >  create mode 100644 Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciCommon.h
> >  create mode 100644 Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciDWC.c
> >  create mode 100644 Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciDWC.h
> >  create mode 100644 Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciDevice.c
> >  create mode 100644 Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciDevice.h
> >  create mode 100644 Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciInterface.h
> >  create mode 100644 Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciTable.c
> >  create mode 100644 Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciUtility.c
> >  create mode 100644 Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciUtility.h
> >  create mode 100644 Silicon/Synopsys/DesignWare/Include/Library/UsbDeviceLib.h
> >  create mode 100644 Silicon/Synopsys/DesignWare/Include/Protocol/EfiUsbFnIo.h
> >  create mode 100644 Silicon/Synopsys/DesignWare/Include/Protocol/UsbDeviceModeProtocol.h

[-- Attachment #2: Type: text/html, Size: 11633 bytes --]

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2020-08-05 10:50 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2020-07-17 10:01 [edk2-platforms PATCH 1/5] Silicon/Synopsys/DesignWare: Import DesignWare USB3 peripheral driver Vin Xue
2020-07-20 17:43 ` Leif Lindholm
2020-07-21  3:51   ` Vin Xue
2020-07-30 12:18     ` Leif Lindholm
2020-08-05 10:50       ` Vin Xue
2020-07-21  8:17   ` Meenakshi Aggarwal (OSS)

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox