From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-wr1-f66.google.com (mail-wr1-f66.google.com [209.85.221.66]) by mx.groups.io with SMTP id smtpd.web11.618.1595267011283611182 for ; Mon, 20 Jul 2020 10:43:32 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@nuviainc-com.20150623.gappssmtp.com header.s=20150623 header.b=ZTxNlAdC; spf=pass (domain: nuviainc.com, ip: 209.85.221.66, mailfrom: leif@nuviainc.com) Received: by mail-wr1-f66.google.com with SMTP id f7so18707783wrw.1 for ; Mon, 20 Jul 2020 10:43:31 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nuviainc-com.20150623.gappssmtp.com; s=20150623; h=date:from:to:cc:subject:message-id:references:mime-version :content-disposition:in-reply-to:user-agent; bh=hzIjKlz7yKPife6SJfCUaQmNlkizw9NzpAA/ZpwNJzE=; b=ZTxNlAdCxgn7skN91GEslfU28xxARULcH/s0Gjt3IAxvPXXy6SkrCJrht5OS/YAxT8 Ob6NLpu8C72cZf9Kp74GxR7kH1r+Ln5qCm6JpvXE172k12zLomdydhJ/pGjKRo71aGSL 94l0BMntyOSoVwql0nnwKh7vuQO4R4enhtHE0omOtn5SqVh0LFUQEZRp7eE8+W+IpAZ2 jslWdllcU0Y1OfZhNRRVTU8X0HcYOV90k6EaOHOZg+5DAH+BnBiIQViDJwwO/1xdRjVe l0E36XkN7p5c3NahT4Otk7UDMzTBxSrBuKUx1Li4xEQ4SfUIzGjKpSO/HFbOTIomDktf fT6w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:from:to:cc:subject:message-id:references :mime-version:content-disposition:in-reply-to:user-agent; bh=hzIjKlz7yKPife6SJfCUaQmNlkizw9NzpAA/ZpwNJzE=; b=G6uLi96OznOely8rfOpgJKs3pGZIw7Vs+FPpYw7JFqjS5TeuVi0OlR8EH0KK0KWaOb IZjVGOdwY8rDDdfLEUdfXatBRGI1nKEa1xdwsa3jScWM13w+p81z2Wd2pOkYMjiP/5Te 8akpaEawyaafunkiHOVzm9MBmzFACVXjM42OwkNLm16bwgmuyb2AGLyoBg31U/P0XrLW 3dD99UNhEqKj4p+7dKUzjyitm1u9PKHfg+TCU4uJ1Lm/ELoeex6osbLyk4T7gAENI625 nKHjmWSFPvtDgc5rKN9pTby8vlRg8E0CbflbYjKGWLWOn0ls0Wqy7GI2A1cc6FbfHhZj 3sNQ== X-Gm-Message-State: AOAM530AQoxvcEr5A0CLoEPZj0D0him3WXj25FlOZlycKYV7QghCjCR6 VdhDr+rEiCIAD1reU+yWef2kaA== X-Google-Smtp-Source: ABdhPJyzoQWyYD9r/x1nnQ4cxgW6OJ+JtYzZuW/cKt7oIv1lL/Mn4fCaBMwNhqfNXNj8PXGY2F3t8A== X-Received: by 2002:adf:e901:: with SMTP id f1mr23277274wrm.80.1595267008172; Mon, 20 Jul 2020 10:43:28 -0700 (PDT) Return-Path: Received: from vanye ([2001:470:1f09:12f0:b26e:bfff:fea9:f1b8]) by smtp.gmail.com with ESMTPSA id l15sm33277916wro.33.2020.07.20.10.43.26 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 20 Jul 2020 10:43:27 -0700 (PDT) Date: Mon, 20 Jul 2020 18:43:24 +0100 From: "Leif Lindholm" To: Vin Xue Cc: devel@edk2.groups.io, Ard Biesheuvel , Meenakshi Aggarwal Subject: Re: [edk2-platforms PATCH 1/5] Silicon/Synopsys/DesignWare: Import DesignWare USB3 peripheral driver Message-ID: <20200720174324.GR12303@vanye> References: MIME-Version: 1.0 In-Reply-To: User-Agent: Mutt/1.10.1 (2018-07-13) Content-Type: text/plain; charset=us-ascii Content-Disposition: inline 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 > Cc: Leif Lindholm > Signed-off-by: Vin Xue > --- > .../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.
> + > + 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 > +#include > + > + > +/** > + 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.
> + > + 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 > + > +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.
> + > + 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 > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#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.
> +# > +# 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.
> + > + 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 > +#include > +#include > +#include > +#include > +#include > +#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.
> + > + 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 > +#include > +#include > +#include > +#include > +#include > +#include > +#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.
> + > + 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.
> + > + 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 > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#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.
> + > + 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.
> + > + 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 > +#include > +#include > +#include > + > +#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.
> + > + 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.
> + > + 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.
> + > + 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.
> + > + 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 > +#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.
> + > + 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.
> + > + 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.
> + > + 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 > +#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.
> + > + 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.
> + > + 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 > + > +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.
> + > + 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 > +#include > +#include > +#include > +#include > +#include > + > +#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.
> + > + 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 > + > +#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.
> + > + 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 > + > +/// > +/// 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 >