From: "Leif Lindholm" <leif@nuviainc.com>
To: Vin Xue <vinxue@outlook.com>
Cc: 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
Date: Mon, 20 Jul 2020 18:43:24 +0100 [thread overview]
Message-ID: <20200720174324.GR12303@vanye> (raw)
In-Reply-To: <SL2PR03MB4442ED3E414E5FCB952E88E9C57C0@SL2PR03MB4442.apcprd03.prod.outlook.com>
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
>
next prev parent reply other threads:[~2020-07-20 17:43 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-07-17 10:01 [edk2-platforms PATCH 1/5] Silicon/Synopsys/DesignWare: Import DesignWare USB3 peripheral driver Vin Xue
2020-07-20 17:43 ` Leif Lindholm [this message]
2020-07-21 3:51 ` Vin Xue
2020-07-30 12:18 ` Leif Lindholm
2020-08-05 10:50 ` Vin Xue
2020-07-21 8:17 ` Meenakshi Aggarwal (OSS)
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-list from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20200720174324.GR12303@vanye \
--to=devel@edk2.groups.io \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox