* 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