3339 lines
117 KiB
C
3339 lines
117 KiB
C
/** @file
|
|
File for USBFN protocol implementation.
|
|
|
|
@copyright
|
|
INTEL CONFIDENTIAL
|
|
Copyright 2015 - 2020 Intel Corporation.
|
|
|
|
The source code contained or described herein and all documents related to the
|
|
source code ("Material") are owned by Intel Corporation or its suppliers or
|
|
licensors. Title to the Material remains with Intel Corporation or its suppliers
|
|
and licensors. The Material may contain trade secrets and proprietary and
|
|
confidential information of Intel Corporation and its suppliers and licensors,
|
|
and is protected by worldwide copyright and trade secret laws and treaty
|
|
provisions. No part of the Material may be used, copied, reproduced, modified,
|
|
published, uploaded, posted, transmitted, distributed, or disclosed in any way
|
|
without Intel's prior express written permission.
|
|
|
|
No license under any patent, copyright, trade secret or other intellectual
|
|
property right is granted to or conferred upon you by disclosure or delivery
|
|
of the Materials, either expressly, by implication, inducement, estoppel or
|
|
otherwise. Any license under such intellectual property rights must be
|
|
express and approved by Intel in writing.
|
|
|
|
Unless otherwise agreed by Intel in writing, you may not remove or alter
|
|
this notice or any other notice embedded in Materials by Intel or
|
|
Intel's suppliers or licensors in any way.
|
|
|
|
This file contains a 'Sample Driver' and is licensed as such under the terms
|
|
of your license agreement with Intel or your vendor. This file may be modified
|
|
by the user, subject to the additional terms of the license agreement.
|
|
|
|
@par Specification Reference:
|
|
**/
|
|
|
|
#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"AlderLake";
|
|
|
|
/**
|
|
* 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,
|
|
ConfigureEnableEndpointsEx
|
|
};
|
|
|
|
|
|
/**
|
|
Debug Start
|
|
**/
|
|
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->controller_handle;
|
|
|
|
EventCount = usb_reg_read (UsbFuncIoDevPtr->XdciMmioBarAddr, DWC_XDCI_EVNTCOUNT_REG(0));
|
|
//DEBUG ((USB_FUIO_DEBUG_EVENT_D, "\n ==>> EventCount = 0x%08x \n", EventCount));
|
|
|
|
DbBufPtr = (UINT32*)(UINTN)XdciCorePtr->current_event_buffer;
|
|
XdciCorePtr = UsbDeviceCorePtr->controller_handle;
|
|
DEBUG ((USB_FUIO_DEBUG_EVENT_D, "FUEV:: XdciCorePtr->aligned_event_buffers 0x%08x\n", (UINTN)XdciCorePtr->aligned_event_buffers));
|
|
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
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
UINT8 Value8;
|
|
|
|
DEBUG ((USB_FUIO_DEBUG_INFO, "DetectPort - Entry\n"));
|
|
|
|
|
|
// 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 = 1;
|
|
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 Status;
|
|
}
|
|
|
|
|
|
/**
|
|
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;
|
|
VOID *AllocateBufferPtr;
|
|
USB_MEM_NODE *NodePtr;
|
|
|
|
DEBUG ((USB_FUIO_DEBUG_INFO, "AllocateTransferBuffer - Entry\n"));
|
|
|
|
|
|
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;
|
|
|
|
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;
|
|
}
|
|
|
|
/**
|
|
Frees the input InterfaceInfo structure (and all sub-elements of that structure.)
|
|
|
|
@param[in] InterfaceInfo A pointer to EFI_USB_INTERFACE_INFO instance.
|
|
|
|
@retval - None
|
|
|
|
**/
|
|
VOID
|
|
FreeEndpointDescriptorTable(
|
|
IN EFI_USB_SUPERSPEED_ENDPOINT_DESCRIPTOR *InterfaceInfo
|
|
)
|
|
{
|
|
if (InterfaceInfo == NULL) {
|
|
return;
|
|
}
|
|
DEBUG((USB_FUIO_DEBUG_INFO, "[%a] Start.\n", __FUNCTION__));
|
|
if (InterfaceInfo->EndpointDescriptor != NULL) {
|
|
//Free the endpoint table if present
|
|
if (InterfaceInfo->EndpointCompanionDescriptor != NULL) {
|
|
DEBUG((USB_FUIO_DEBUG_INFO, "[%a] Freeing InterfaceInfo->EndpointDescriptorTable.\n", __FUNCTION__));
|
|
FreePool(InterfaceInfo->EndpointCompanionDescriptor);
|
|
}
|
|
DEBUG((USB_FUIO_DEBUG_INFO, "[%a] Freeing InterfaceInfo->EndpointDescriptorTable\n", __FUNCTION__));
|
|
FreePool(InterfaceInfo->EndpointDescriptor);
|
|
}
|
|
}
|
|
/**
|
|
Frees the input InterfaceInfo structure (and all sub-elements of that structure.)
|
|
|
|
@param[in] InterfaceInfo A pointer to EFI_USB_INTERFACE_INFO instance.
|
|
|
|
@retval - None
|
|
|
|
**/
|
|
VOID
|
|
FreeSSInterfaceInfo(
|
|
IN EFI_USB_SUPERSPEED_INTERFACE_INFO *InterfaceInfo
|
|
)
|
|
{
|
|
if (InterfaceInfo == NULL) {
|
|
return;
|
|
}
|
|
DEBUG((USB_FUIO_DEBUG_INFO, "[%a] Start.\n", __FUNCTION__));
|
|
if (InterfaceInfo->InterfaceDescriptor != NULL) {
|
|
//Free the endpoint table if present
|
|
if (InterfaceInfo->EndpointDescriptorTable != NULL) {
|
|
for (UINTN EndpointIdx = 0; EndpointIdx < InterfaceInfo->InterfaceDescriptor->NumEndpoints; EndpointIdx++) {
|
|
//Free the endpoint table entry if present
|
|
if (InterfaceInfo->EndpointDescriptorTable[EndpointIdx] != NULL) {
|
|
DEBUG((USB_FUIO_DEBUG_INFO, "[%a] Freeing InterfaceInfo->EndpointDescriptorTable[%d].\n", __FUNCTION__, EndpointIdx));
|
|
FreeEndpointDescriptorTable(InterfaceInfo->EndpointDescriptorTable[EndpointIdx]);
|
|
FreePool(InterfaceInfo->EndpointDescriptorTable[EndpointIdx]);
|
|
}
|
|
}
|
|
DEBUG((USB_FUIO_DEBUG_INFO, "[%a] Freeing InterfaceInfo->EndpointDescriptorTable\n", __FUNCTION__));
|
|
FreePool(InterfaceInfo->EndpointDescriptorTable);
|
|
}
|
|
DEBUG((USB_FUIO_DEBUG_INFO, "[%a] Freeing InterfaceInfo->InterfaceDescriptor\n", __FUNCTION__));
|
|
FreePool(InterfaceInfo->InterfaceDescriptor);
|
|
}
|
|
}
|
|
|
|
/**
|
|
Frees the input ConfigInfo structure (and all sub-elements of that structure.)
|
|
|
|
@param[in] ConfigInfo A pointer to EFI_USB_CONFIG_INFO instance.
|
|
|
|
@retval - None
|
|
|
|
**/
|
|
VOID
|
|
FreeSSConfigInfo(
|
|
IN EFI_USB_SUPERSPEED_CONFIG_INFO *ConfigInfo
|
|
)
|
|
{
|
|
if (ConfigInfo == NULL) {
|
|
return;
|
|
}
|
|
DEBUG((USB_FUIO_DEBUG_INFO, "[%a] Start.\n", __FUNCTION__));
|
|
if (ConfigInfo->ConfigDescriptor != NULL) {
|
|
//Free the interface table if present.
|
|
if (ConfigInfo->InterfaceInfoTable != NULL) {
|
|
for (UINTN InterfaceIdx = 0; InterfaceIdx < ConfigInfo->ConfigDescriptor->NumInterfaces; InterfaceIdx++) {
|
|
//Free the interface table entry if present
|
|
if (ConfigInfo->InterfaceInfoTable[InterfaceIdx] != NULL) {
|
|
DEBUG((USB_FUIO_DEBUG_INFO, "[%a] Freeing ConfigInfo->InterfaceInfoTable[%d].\n", __FUNCTION__, InterfaceIdx));
|
|
FreeSSInterfaceInfo(ConfigInfo->InterfaceInfoTable[InterfaceIdx]);
|
|
FreePool(ConfigInfo->InterfaceInfoTable[InterfaceIdx]);
|
|
}
|
|
}
|
|
DEBUG((USB_FUIO_DEBUG_INFO, "[%a] Freeing ConfigInfo->InterfaceInfoTable\n", __FUNCTION__));
|
|
FreePool(ConfigInfo->InterfaceInfoTable);
|
|
}
|
|
DEBUG((USB_FUIO_DEBUG_INFO, "[%a] Freeing ConfigInfo->ConfigDescriptor\n", __FUNCTION__));
|
|
FreePool(ConfigInfo->ConfigDescriptor);
|
|
}
|
|
}
|
|
|
|
/**
|
|
Frees the input DeviceInfo structure (and all sub-elements of that structure.)
|
|
|
|
@param[in] DeviceInfo A pointer to EFI_USB_DEVICE_INFO instance.
|
|
|
|
@retval - None
|
|
|
|
**/
|
|
VOID
|
|
FreeSSDeviceInfo(
|
|
IN EFI_USB_SUPERSPEED_DEVICE_INFO *DeviceInfo
|
|
)
|
|
{
|
|
if (DeviceInfo == NULL) {
|
|
return;
|
|
}
|
|
DEBUG((USB_FUIO_DEBUG_INFO, "[%a] Start.\n", __FUNCTION__));
|
|
if (DeviceInfo->DeviceDescriptor != NULL) {
|
|
//Free the config info table if present.
|
|
if (DeviceInfo->ConfigInfoTable != NULL) {
|
|
for (UINTN ConfigIdx = 0; ConfigIdx < DeviceInfo->DeviceDescriptor->NumConfigurations; ConfigIdx++) {
|
|
//Free the config table entry if present
|
|
if (DeviceInfo->ConfigInfoTable[ConfigIdx] != NULL) {
|
|
DEBUG((USB_FUIO_DEBUG_INFO, "[%a] Freeing DeviceInfo->ConfigInfoTable[%d].\n", __FUNCTION__, ConfigIdx));
|
|
FreeSSConfigInfo(DeviceInfo->ConfigInfoTable[ConfigIdx]);
|
|
FreePool(DeviceInfo->ConfigInfoTable[ConfigIdx]);
|
|
}
|
|
}
|
|
DEBUG((USB_FUIO_DEBUG_INFO, "[%a] Freeing DeviceInfo->ConfigInfoTable\n", __FUNCTION__));
|
|
FreePool(DeviceInfo->ConfigInfoTable);
|
|
}
|
|
DEBUG((USB_FUIO_DEBUG_INFO, "[%a] Freeing DeviceInfo->DeviceDescriptor\n", __FUNCTION__));
|
|
FreePool(DeviceInfo->DeviceDescriptor);
|
|
}
|
|
}
|
|
|
|
/**
|
|
Frees the input InterfaceInfo structure (and all sub-elements of that structure.)
|
|
|
|
@param[in] InterfaceInfo A pointer to EFI_USB_INTERFACE_INFO instance.
|
|
|
|
@retval - None
|
|
|
|
**/
|
|
VOID
|
|
FreeInterfaceInfo(
|
|
IN EFI_USB_INTERFACE_INFO *InterfaceInfo
|
|
)
|
|
{
|
|
if (InterfaceInfo == NULL) {
|
|
return;
|
|
}
|
|
DEBUG((USB_FUIO_DEBUG_INFO, "[%a] Start.\n", __FUNCTION__));
|
|
if (InterfaceInfo->InterfaceDescriptor != NULL) {
|
|
//Free the endpoint table if present
|
|
if (InterfaceInfo->EndpointDescriptorTable != NULL) {
|
|
for (UINTN EndpointIdx=0; EndpointIdx < InterfaceInfo->InterfaceDescriptor->NumEndpoints; EndpointIdx++) {
|
|
//Free the endpoint table entry if present
|
|
if (InterfaceInfo->EndpointDescriptorTable[EndpointIdx] != NULL) {
|
|
DEBUG((USB_FUIO_DEBUG_INFO, "[%a] Freeing InterfaceInfo->EndpointDescriptorTable[%d].\n", __FUNCTION__, EndpointIdx));
|
|
FreePool(InterfaceInfo->EndpointDescriptorTable[EndpointIdx]);
|
|
}
|
|
}
|
|
DEBUG((USB_FUIO_DEBUG_INFO, "[%a] Freeing InterfaceInfo->EndpointDescriptorTable\n", __FUNCTION__));
|
|
FreePool(InterfaceInfo->EndpointDescriptorTable);
|
|
}
|
|
DEBUG((USB_FUIO_DEBUG_INFO, "[%a] Freeing InterfaceInfo->InterfaceDescriptor\n", __FUNCTION__));
|
|
FreePool(InterfaceInfo->InterfaceDescriptor);
|
|
}
|
|
}
|
|
|
|
/**
|
|
Frees the input ConfigInfo structure (and all sub-elements of that structure.)
|
|
|
|
@param[in] ConfigInfo A pointer to EFI_USB_CONFIG_INFO instance.
|
|
|
|
@retval - None
|
|
|
|
**/
|
|
VOID
|
|
FreeConfigInfo(
|
|
IN EFI_USB_CONFIG_INFO *ConfigInfo
|
|
)
|
|
{
|
|
if (ConfigInfo == NULL) {
|
|
return;
|
|
}
|
|
DEBUG((USB_FUIO_DEBUG_INFO, "[%a] Start.\n", __FUNCTION__));
|
|
if (ConfigInfo->ConfigDescriptor != NULL) {
|
|
//Free the interface table if present.
|
|
if (ConfigInfo->InterfaceInfoTable != NULL) {
|
|
for (UINTN InterfaceIdx = 0; InterfaceIdx < ConfigInfo->ConfigDescriptor->NumInterfaces; InterfaceIdx++) {
|
|
//Free the interface table entry if present
|
|
if (ConfigInfo->InterfaceInfoTable[InterfaceIdx] != NULL) {
|
|
DEBUG((USB_FUIO_DEBUG_INFO, "[%a] Freeing ConfigInfo->InterfaceInfoTable[%d].\n", __FUNCTION__, InterfaceIdx));
|
|
FreeInterfaceInfo(ConfigInfo->InterfaceInfoTable[InterfaceIdx]);
|
|
FreePool(ConfigInfo->InterfaceInfoTable[InterfaceIdx]);
|
|
}
|
|
}
|
|
DEBUG((USB_FUIO_DEBUG_INFO, "[%a] Freeing ConfigInfo->InterfaceInfoTable\n", __FUNCTION__));
|
|
FreePool(ConfigInfo->InterfaceInfoTable);
|
|
}
|
|
DEBUG((USB_FUIO_DEBUG_INFO, "[%a] Freeing ConfigInfo->ConfigDescriptor\n", __FUNCTION__));
|
|
FreePool(ConfigInfo->ConfigDescriptor);
|
|
}
|
|
}
|
|
|
|
/**
|
|
Frees the input DeviceInfo structure (and all sub-elements of that structure.)
|
|
|
|
@param[in] DeviceInfo A pointer to EFI_USB_DEVICE_INFO instance.
|
|
|
|
@retval - None
|
|
|
|
**/
|
|
VOID
|
|
FreeDeviceInfo(
|
|
IN EFI_USB_DEVICE_INFO *DeviceInfo
|
|
)
|
|
{
|
|
if (DeviceInfo == NULL) {
|
|
return;
|
|
}
|
|
DEBUG((USB_FUIO_DEBUG_INFO, "[%a] Start.\n", __FUNCTION__));
|
|
if (DeviceInfo->DeviceDescriptor != NULL) {
|
|
//Free the config info table if present.
|
|
if (DeviceInfo->ConfigInfoTable != NULL) {
|
|
for (UINTN ConfigIdx = 0; ConfigIdx < DeviceInfo->DeviceDescriptor->NumConfigurations; ConfigIdx++) {
|
|
//Free the config table entry if present
|
|
if(DeviceInfo->ConfigInfoTable[ConfigIdx] != NULL) {
|
|
DEBUG((USB_FUIO_DEBUG_INFO, "[%a] Freeing DeviceInfo->ConfigInfoTable[%d].\n", __FUNCTION__, ConfigIdx));
|
|
FreeConfigInfo(DeviceInfo->ConfigInfoTable[ConfigIdx]);
|
|
FreePool(DeviceInfo->ConfigInfoTable[ConfigIdx]);
|
|
}
|
|
}
|
|
DEBUG((USB_FUIO_DEBUG_INFO, "[%a] Freeing DeviceInfo->ConfigInfoTable\n", __FUNCTION__));
|
|
FreePool(DeviceInfo->ConfigInfoTable);
|
|
}
|
|
DEBUG((USB_FUIO_DEBUG_INFO, "[%a] Freeing DeviceInfo->DeviceDescriptor\n", __FUNCTION__));
|
|
FreePool(DeviceInfo->DeviceDescriptor);
|
|
}
|
|
}
|
|
|
|
/**
|
|
Performs a deep-copy of the Source EFI_USB_INTERFACE_INFO structure into the Target EFI_USB_INTERFACE_INFO structure.
|
|
|
|
1. Allocates and copies the Endpoint Descriptor
|
|
2. Allocates and copies the Endpoint CompanionDescriptor
|
|
|
|
@param[in] SourceEndPointDescriptor A pointer to EFI_USB_INTERFACE_INFO instance to copy from.
|
|
@param[in] TargetEndPointDescriptor A pointer to EFI_USB_INTERFACE_INFO instance to copy into.
|
|
|
|
@retval - EFI_SUCCESS - copy created successfully.
|
|
@retval - Other - failed to create copy.
|
|
**/
|
|
EFI_STATUS
|
|
CopySSEndPointDescriptor(
|
|
IN EFI_USB_SUPERSPEED_ENDPOINT_DESCRIPTOR *SourceEndPointDescriptor,
|
|
IN EFI_USB_SUPERSPEED_ENDPOINT_DESCRIPTOR *TargetEndPointDescriptor
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
|
|
if (SourceEndPointDescriptor == NULL || TargetEndPointDescriptor == NULL) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
DEBUG((USB_FUIO_DEBUG_INFO, "[%a] Start.\n", __FUNCTION__));
|
|
|
|
//Allocate and copy Interface Descriptor
|
|
TargetEndPointDescriptor->EndpointDescriptor = AllocateZeroPool(sizeof(EFI_USB_ENDPOINT_DESCRIPTOR));
|
|
if (TargetEndPointDescriptor->EndpointDescriptor == NULL) {
|
|
Status = EFI_OUT_OF_RESOURCES;
|
|
goto Cleanup;
|
|
}
|
|
CopyMem(TargetEndPointDescriptor->EndpointDescriptor, SourceEndPointDescriptor->EndpointDescriptor, sizeof(EFI_USB_ENDPOINT_DESCRIPTOR));
|
|
|
|
DEBUG((USB_FUIO_DEBUG_INFO, "[%a] EndpointDescriptor allocated and copied.\n", __FUNCTION__));
|
|
|
|
//Allocate space for EndpointDescriptorTable
|
|
TargetEndPointDescriptor->EndpointCompanionDescriptor = AllocateZeroPool(sizeof(EFI_USB_SUPERSPEED_ENDPOINT_COMPANION_DESCRIPTOR));
|
|
if (TargetEndPointDescriptor->EndpointCompanionDescriptor == NULL) {
|
|
Status = EFI_OUT_OF_RESOURCES;
|
|
goto Cleanup;
|
|
}
|
|
//Copy Endpoint Descriptors
|
|
Status = EFI_SUCCESS;
|
|
|
|
//Copy the endpoint descriptor
|
|
CopyMem(TargetEndPointDescriptor->EndpointCompanionDescriptor, SourceEndPointDescriptor->EndpointCompanionDescriptor, sizeof(EFI_USB_SUPERSPEED_ENDPOINT_COMPANION_DESCRIPTOR));
|
|
DEBUG((USB_FUIO_DEBUG_INFO, "[%a] EndpointCompanionDescriptor allocated and copied.\n", __FUNCTION__));
|
|
Cleanup:
|
|
DEBUG((USB_FUIO_DEBUG_INFO, "[%a] done. Status %r\n", __FUNCTION__, Status));
|
|
if (EFI_ERROR(Status)) {
|
|
FreeEndpointDescriptorTable(TargetEndPointDescriptor);
|
|
}
|
|
return Status;
|
|
}
|
|
/**
|
|
Performs a deep-copy of the Source EFI_USB_INTERFACE_INFO structure into the Target EFI_USB_INTERFACE_INFO structure.
|
|
|
|
1. Allocates and copies the Interface Descriptor
|
|
2. Allocates and copies all entries in the EndpointDescriptorTable.
|
|
|
|
@param[in] SourceInterfaceInfo A pointer to EFI_USB_INTERFACE_INFO instance to copy from.
|
|
@param[in] TargetInterfaceInfo A pointer to EFI_USB_INTERFACE_INFO instance to copy into.
|
|
|
|
@retval - EFI_SUCCESS - copy created successfully.
|
|
@retval - Other - failed to create copy.
|
|
**/
|
|
EFI_STATUS
|
|
CopyInterfaceDescriptor(
|
|
IN EFI_USB_INTERFACE_INFO *SourceInterfaceInfo,
|
|
IN EFI_USB_INTERFACE_INFO *TargetInterfaceInfo
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
|
|
if(SourceInterfaceInfo == NULL || TargetInterfaceInfo == NULL) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
DEBUG((USB_FUIO_DEBUG_INFO, "[%a] Start.\n", __FUNCTION__));
|
|
|
|
//Allocate and copy Interface Descriptor
|
|
TargetInterfaceInfo->InterfaceDescriptor = AllocateZeroPool(sizeof(EFI_USB_INTERFACE_DESCRIPTOR));
|
|
if (TargetInterfaceInfo->InterfaceDescriptor == NULL) {
|
|
Status = EFI_OUT_OF_RESOURCES;
|
|
goto Cleanup;
|
|
}
|
|
CopyMem(TargetInterfaceInfo->InterfaceDescriptor, SourceInterfaceInfo->InterfaceDescriptor, sizeof(EFI_USB_INTERFACE_DESCRIPTOR));
|
|
|
|
DEBUG((USB_FUIO_DEBUG_INFO, "[%a] InterfaceDescriptor allocated and copied.\n", __FUNCTION__));
|
|
|
|
//Allocate space for EndpointDescriptorTable
|
|
TargetInterfaceInfo->EndpointDescriptorTable =
|
|
AllocateZeroPool(sizeof(EFI_USB_ENDPOINT_DESCRIPTOR*) * TargetInterfaceInfo->InterfaceDescriptor->NumEndpoints);
|
|
if (TargetInterfaceInfo->EndpointDescriptorTable == NULL) {
|
|
Status = EFI_OUT_OF_RESOURCES;
|
|
goto Cleanup;
|
|
}
|
|
|
|
DEBUG((USB_FUIO_DEBUG_INFO, "[%a] EndpointDescriptorTable allocated (%d entries).\n", __FUNCTION__,
|
|
TargetInterfaceInfo->InterfaceDescriptor->NumEndpoints));
|
|
|
|
//Copy Endpoint Descriptors
|
|
Status = EFI_SUCCESS;
|
|
for (UINTN EndpointIdx = 0; EndpointIdx < TargetInterfaceInfo->InterfaceDescriptor->NumEndpoints; EndpointIdx++) {
|
|
//Allocate table entry
|
|
TargetInterfaceInfo->EndpointDescriptorTable[EndpointIdx] =
|
|
AllocateZeroPool(sizeof(EFI_USB_ENDPOINT_DESCRIPTOR));
|
|
if (TargetInterfaceInfo->EndpointDescriptorTable[EndpointIdx] == NULL) {
|
|
Status = EFI_OUT_OF_RESOURCES;
|
|
goto Cleanup;
|
|
}
|
|
|
|
//Copy the endpoint descriptor
|
|
CopyMem(TargetInterfaceInfo->EndpointDescriptorTable[EndpointIdx],
|
|
SourceInterfaceInfo->EndpointDescriptorTable[EndpointIdx],
|
|
sizeof(EFI_USB_ENDPOINT_DESCRIPTOR));
|
|
DEBUG((USB_FUIO_DEBUG_INFO, "[%a] EndpointDescriptorTable[%d] allocated and copied.\n", __FUNCTION__, EndpointIdx));
|
|
}
|
|
Cleanup:
|
|
DEBUG((USB_FUIO_DEBUG_INFO, "[%a] done. Status %r\n", __FUNCTION__, Status));
|
|
if (EFI_ERROR(Status)) {
|
|
FreeInterfaceInfo(TargetInterfaceInfo);
|
|
}
|
|
return Status;
|
|
}
|
|
|
|
/**
|
|
Performs a deep-copy of the Source EFI_USB_INTERFACE_INFO structure into the Target EFI_USB_INTERFACE_INFO structure.
|
|
|
|
1. Allocates and copies the Interface Descriptor
|
|
2. Allocates and copies all entries in the EndpointDescriptorTable.
|
|
|
|
@param[in] SourceInterfaceInfo A pointer to EFI_USB_INTERFACE_INFO instance to copy from.
|
|
@param[in] TargetInterfaceInfo A pointer to EFI_USB_INTERFACE_INFO instance to copy into.
|
|
|
|
@retval - EFI_SUCCESS - copy created successfully.
|
|
@retval - Other - failed to create copy.
|
|
**/
|
|
EFI_STATUS
|
|
CopySSInterfaceDescriptor(
|
|
IN EFI_USB_SUPERSPEED_INTERFACE_INFO *SourceInterfaceInfo,
|
|
IN EFI_USB_SUPERSPEED_INTERFACE_INFO *TargetInterfaceInfo
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
|
|
if (SourceInterfaceInfo == NULL || TargetInterfaceInfo == NULL) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
DEBUG((USB_FUIO_DEBUG_INFO, "[%a] Start.\n", __FUNCTION__));
|
|
|
|
//Allocate and copy Interface Descriptor
|
|
TargetInterfaceInfo->InterfaceDescriptor = AllocateZeroPool(sizeof(EFI_USB_INTERFACE_DESCRIPTOR));
|
|
if (TargetInterfaceInfo->InterfaceDescriptor == NULL) {
|
|
Status = EFI_OUT_OF_RESOURCES;
|
|
goto Cleanup;
|
|
}
|
|
CopyMem(TargetInterfaceInfo->InterfaceDescriptor, SourceInterfaceInfo->InterfaceDescriptor, sizeof(EFI_USB_INTERFACE_DESCRIPTOR));
|
|
|
|
DEBUG((USB_FUIO_DEBUG_INFO, "[%a] InterfaceDescriptor allocated and copied.\n", __FUNCTION__));
|
|
|
|
//Allocate space for EndpointDescriptorTable
|
|
TargetInterfaceInfo->EndpointDescriptorTable =
|
|
AllocateZeroPool(sizeof(EFI_USB_SUPERSPEED_ENDPOINT_DESCRIPTOR*)* TargetInterfaceInfo->InterfaceDescriptor->NumEndpoints);
|
|
if (TargetInterfaceInfo->EndpointDescriptorTable == NULL) {
|
|
Status = EFI_OUT_OF_RESOURCES;
|
|
goto Cleanup;
|
|
}
|
|
|
|
DEBUG((USB_FUIO_DEBUG_INFO, "[%a] EndpointDescriptorTable allocated (%d entries).\n", __FUNCTION__,
|
|
TargetInterfaceInfo->InterfaceDescriptor->NumEndpoints));
|
|
|
|
//Copy Endpoint Descriptors
|
|
Status = EFI_SUCCESS;
|
|
for (UINTN EndpointIdx = 0; EndpointIdx < TargetInterfaceInfo->InterfaceDescriptor->NumEndpoints; EndpointIdx++) {
|
|
//Allocate table entry
|
|
TargetInterfaceInfo->EndpointDescriptorTable[EndpointIdx] =
|
|
AllocateZeroPool(sizeof(EFI_USB_SUPERSPEED_ENDPOINT_DESCRIPTOR));
|
|
if (TargetInterfaceInfo->EndpointDescriptorTable[EndpointIdx] == NULL) {
|
|
Status = EFI_OUT_OF_RESOURCES;
|
|
goto Cleanup;
|
|
}
|
|
//Copy the endpoint descriptor
|
|
Status = CopySSEndPointDescriptor(SourceInterfaceInfo->EndpointDescriptorTable[EndpointIdx], TargetInterfaceInfo->EndpointDescriptorTable[EndpointIdx]);
|
|
}
|
|
Cleanup:
|
|
DEBUG((USB_FUIO_DEBUG_INFO, "[%a] done. Status %r\n", __FUNCTION__, Status));
|
|
if (EFI_ERROR(Status)) {
|
|
FreeSSInterfaceInfo(TargetInterfaceInfo);
|
|
}
|
|
return Status;
|
|
}
|
|
/**
|
|
Performs a deep-copy of the Source EFI_USB_CONFIG_INFO structure into the Target EFI_USB_CONFIG_INFO structure.
|
|
|
|
1. Allocates and copies the Config Descriptor
|
|
2. Allocates and copies all entries in the InterfaceInfoTable.
|
|
|
|
@param[in] SourceConfigInfo A pointer to EFI_USB_CONFIG_INFO instance to copy from.
|
|
@param[in] TargetConfigInfo A pointer to EFI_USB_CONFIG_INFO instance to copy into.
|
|
|
|
@retval - EFI_SUCCESS - copy created successfully.
|
|
@retval - Other - failed to create copy.
|
|
**/
|
|
EFI_STATUS
|
|
CopyConfigDescriptor(
|
|
IN EFI_USB_CONFIG_INFO *SourceConfigInfo,
|
|
IN EFI_USB_CONFIG_INFO *TargetConfigInfo
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
|
|
if (SourceConfigInfo == NULL || TargetConfigInfo == NULL) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
DEBUG((USB_FUIO_DEBUG_INFO, "[%a] Start.\n", __FUNCTION__));
|
|
|
|
//Allocate and copy ConfigDescriptor
|
|
TargetConfigInfo->ConfigDescriptor = AllocateZeroPool(sizeof(EFI_USB_CONFIG_DESCRIPTOR));
|
|
if (TargetConfigInfo->ConfigDescriptor == NULL) {
|
|
Status = EFI_OUT_OF_RESOURCES;
|
|
goto Cleanup;
|
|
}
|
|
CopyMem(TargetConfigInfo->ConfigDescriptor, SourceConfigInfo->ConfigDescriptor, sizeof(EFI_USB_CONFIG_DESCRIPTOR));
|
|
|
|
DEBUG((USB_FUIO_DEBUG_INFO, "[%a] ConfigDescriptor allocated and copied.\n", __FUNCTION__));
|
|
|
|
//Allocate space for InterfaceInfoTable
|
|
TargetConfigInfo->InterfaceInfoTable =
|
|
AllocateZeroPool(sizeof(EFI_USB_INTERFACE_INFO*) * TargetConfigInfo->ConfigDescriptor->NumInterfaces);
|
|
if (TargetConfigInfo->InterfaceInfoTable == NULL) {
|
|
Status = EFI_OUT_OF_RESOURCES;
|
|
goto Cleanup;
|
|
}
|
|
|
|
DEBUG((USB_FUIO_DEBUG_INFO, "[%a] InterfaceInfoTable allocated (%d entries).\n", __FUNCTION__,
|
|
TargetConfigInfo->ConfigDescriptor->NumInterfaces));
|
|
|
|
//Copy Interface Table Entries
|
|
Status = EFI_SUCCESS;
|
|
for (UINTN InterfaceIdx = 0; InterfaceIdx < TargetConfigInfo->ConfigDescriptor->NumInterfaces;InterfaceIdx++) {
|
|
//Allocate table entry
|
|
TargetConfigInfo->InterfaceInfoTable[InterfaceIdx] = AllocateZeroPool(sizeof(EFI_USB_INTERFACE_INFO));
|
|
if (TargetConfigInfo->InterfaceInfoTable[InterfaceIdx] == NULL) {
|
|
Status = EFI_OUT_OF_RESOURCES;
|
|
goto Cleanup;
|
|
}
|
|
|
|
//Deep-Copy the Interface Descriptor (and sub-structures)
|
|
Status = CopyInterfaceDescriptor(
|
|
SourceConfigInfo->InterfaceInfoTable[InterfaceIdx],
|
|
TargetConfigInfo->InterfaceInfoTable[InterfaceIdx]
|
|
);
|
|
|
|
DEBUG((USB_FUIO_DEBUG_INFO, "[%a] InterfaceInfoTable[%d] allocated and copied.\n", __FUNCTION__, InterfaceIdx));
|
|
}
|
|
Cleanup:
|
|
DEBUG((USB_FUIO_DEBUG_INFO, "[%a] done. Status %r\n", __FUNCTION__, Status));
|
|
if (EFI_ERROR(Status)) {
|
|
FreeConfigInfo(TargetConfigInfo);
|
|
}
|
|
return Status;
|
|
}
|
|
|
|
/**
|
|
Performs a deep-copy of the Source EFI_USB_CONFIG_INFO structure into the Target EFI_USB_CONFIG_INFO structure.
|
|
|
|
1. Allocates and copies the Config Descriptor
|
|
2. Allocates and copies all entries in the InterfaceInfoTable.
|
|
|
|
@param[in] SourceConfigInfo A pointer to EFI_USB_CONFIG_INFO instance to copy from.
|
|
@param[in] TargetConfigInfo A pointer to EFI_USB_CONFIG_INFO instance to copy into.
|
|
|
|
@retval - EFI_SUCCESS - copy created successfully.
|
|
@retval - Other - failed to create copy.
|
|
**/
|
|
EFI_STATUS
|
|
CopySSConfigDescriptor(
|
|
IN EFI_USB_SUPERSPEED_CONFIG_INFO *SourceConfigInfo,
|
|
IN EFI_USB_SUPERSPEED_CONFIG_INFO *TargetConfigInfo
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
|
|
if (SourceConfigInfo == NULL || TargetConfigInfo == NULL) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
DEBUG((USB_FUIO_DEBUG_INFO, "[%a] Start.\n", __FUNCTION__));
|
|
|
|
//Allocate and copy ConfigDescriptor
|
|
TargetConfigInfo->ConfigDescriptor = AllocateZeroPool(sizeof(EFI_USB_CONFIG_DESCRIPTOR));
|
|
if (TargetConfigInfo->ConfigDescriptor == NULL) {
|
|
Status = EFI_OUT_OF_RESOURCES;
|
|
goto Cleanup;
|
|
}
|
|
CopyMem(TargetConfigInfo->ConfigDescriptor, SourceConfigInfo->ConfigDescriptor, sizeof(EFI_USB_CONFIG_DESCRIPTOR));
|
|
|
|
DEBUG((USB_FUIO_DEBUG_INFO, "[%a] ConfigDescriptor allocated and copied.\n", __FUNCTION__));
|
|
|
|
//Allocate space for InterfaceInfoTable
|
|
TargetConfigInfo->InterfaceInfoTable =
|
|
AllocateZeroPool(sizeof(EFI_USB_SUPERSPEED_INTERFACE_INFO*)* TargetConfigInfo->ConfigDescriptor->NumInterfaces);
|
|
if (TargetConfigInfo->InterfaceInfoTable == NULL) {
|
|
Status = EFI_OUT_OF_RESOURCES;
|
|
goto Cleanup;
|
|
}
|
|
|
|
DEBUG((USB_FUIO_DEBUG_INFO, "[%a] InterfaceInfoTable allocated (%d entries).\n", __FUNCTION__,
|
|
TargetConfigInfo->ConfigDescriptor->NumInterfaces));
|
|
|
|
//Copy Interface Table Entries
|
|
Status = EFI_SUCCESS;
|
|
for (UINTN InterfaceIdx = 0; InterfaceIdx < TargetConfigInfo->ConfigDescriptor->NumInterfaces; InterfaceIdx++) {
|
|
//Allocate table entry
|
|
TargetConfigInfo->InterfaceInfoTable[InterfaceIdx] = AllocateZeroPool(sizeof(EFI_USB_SUPERSPEED_INTERFACE_INFO));
|
|
if (TargetConfigInfo->InterfaceInfoTable[InterfaceIdx] == NULL) {
|
|
Status = EFI_OUT_OF_RESOURCES;
|
|
goto Cleanup;
|
|
}
|
|
|
|
//Deep-Copy the Interface Descriptor (and sub-structures)
|
|
Status = CopySSInterfaceDescriptor(
|
|
SourceConfigInfo->InterfaceInfoTable[InterfaceIdx],
|
|
TargetConfigInfo->InterfaceInfoTable[InterfaceIdx]
|
|
);
|
|
|
|
DEBUG((USB_FUIO_DEBUG_INFO, "[%a] InterfaceInfoTable[%d] allocated and copied.\n", __FUNCTION__, InterfaceIdx));
|
|
}
|
|
Cleanup:
|
|
DEBUG((USB_FUIO_DEBUG_INFO, "[%a] done. Status %r\n", __FUNCTION__, Status));
|
|
if (EFI_ERROR(Status)) {
|
|
FreeSSConfigInfo(TargetConfigInfo);
|
|
}
|
|
return Status;
|
|
}
|
|
/**
|
|
Performs a deep-copy of the Source EFI_USB_DEVICE_INFO structure into the Target EFI_USB_DEVICE_INFO structure.
|
|
|
|
1. Allocates and copies the Device Descriptor
|
|
2. Allocates and copies all entries in the ConfigInfoTable.
|
|
|
|
@param[in] SourceDeviceInfo A pointer to EFI_USB_DEVICE_INFO instance to copy from.
|
|
@param[in] TargetDeviceInfo A pointer to EFI_USB_DEVICE_INFO instance to copy into.
|
|
|
|
@retval - EFI_SUCCESS - copy created successfully.
|
|
@retval - Other - failed to create copy.
|
|
**/
|
|
EFI_STATUS
|
|
CopyDeviceDescriptor(
|
|
IN EFI_USB_DEVICE_INFO *SourceDeviceInfo,
|
|
IN EFI_USB_DEVICE_INFO *TargetDeviceInfo
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
|
|
if (SourceDeviceInfo == NULL || TargetDeviceInfo == NULL) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
DEBUG((USB_FUIO_DEBUG_INFO, "[%a] Start.\n", __FUNCTION__));
|
|
|
|
//Allocate and copy DeviceDescriptor
|
|
TargetDeviceInfo->DeviceDescriptor = AllocateZeroPool(sizeof(EFI_USB_DEVICE_DESCRIPTOR));
|
|
if (TargetDeviceInfo->DeviceDescriptor == NULL) {
|
|
Status = EFI_OUT_OF_RESOURCES;
|
|
goto Cleanup;
|
|
}
|
|
CopyMem(TargetDeviceInfo->DeviceDescriptor, SourceDeviceInfo->DeviceDescriptor, sizeof(EFI_USB_DEVICE_DESCRIPTOR));
|
|
|
|
DEBUG((USB_FUIO_DEBUG_INFO, "[%a] DeviceDescriptor allocated and copied.\n", __FUNCTION__));
|
|
|
|
//Allocate space for ConfigInfoTable
|
|
TargetDeviceInfo->ConfigInfoTable =
|
|
AllocateZeroPool(sizeof(EFI_USB_CONFIG_INFO*) * TargetDeviceInfo->DeviceDescriptor->NumConfigurations);
|
|
if (TargetDeviceInfo->ConfigInfoTable == NULL) {
|
|
Status = EFI_OUT_OF_RESOURCES;
|
|
goto Cleanup;
|
|
}
|
|
|
|
DEBUG((USB_FUIO_DEBUG_INFO, "[%a] ConfigInfoTable allocated (%d entries).\n", __FUNCTION__,
|
|
TargetDeviceInfo->DeviceDescriptor->NumConfigurations));
|
|
|
|
//Copy Config Table Entries
|
|
Status = EFI_SUCCESS;
|
|
for (UINTN ConfigIdx = 0; ConfigIdx < TargetDeviceInfo->DeviceDescriptor->NumConfigurations; ConfigIdx++) {
|
|
//Allocate table entry
|
|
TargetDeviceInfo->ConfigInfoTable[ConfigIdx] =
|
|
AllocateZeroPool(sizeof(EFI_USB_CONFIG_INFO));
|
|
if (TargetDeviceInfo->ConfigInfoTable[ConfigIdx] == NULL) {
|
|
Status = EFI_OUT_OF_RESOURCES;
|
|
goto Cleanup;
|
|
}
|
|
|
|
//Deep-Copy the Config Descriptor (and sub-structures)
|
|
Status = CopyConfigDescriptor(
|
|
SourceDeviceInfo->ConfigInfoTable[ConfigIdx],
|
|
TargetDeviceInfo->ConfigInfoTable[ConfigIdx]);
|
|
|
|
DEBUG((USB_FUIO_DEBUG_INFO, "[%a] ConfigInfoTable[%d] allocated and copied.\n", __FUNCTION__, ConfigIdx));
|
|
}
|
|
|
|
Cleanup:
|
|
DEBUG((USB_FUIO_DEBUG_INFO, "[%a] done. Status %r\n", __FUNCTION__, Status));
|
|
if (EFI_ERROR(Status)) {
|
|
FreeDeviceInfo(TargetDeviceInfo);
|
|
}
|
|
return Status;
|
|
}
|
|
|
|
/**
|
|
Performs a deep-copy of the Source EFI_USB_DEVICE_INFO structure into the Target EFI_USB_DEVICE_INFO structure.
|
|
|
|
1. Allocates and copies the Device Descriptor
|
|
2. Allocates and copies all entries in the ConfigInfoTable.
|
|
|
|
@param[in] SourceDeviceInfo A pointer to EFI_USB_DEVICE_INFO instance to copy from.
|
|
@param[in] TargetDeviceInfo A pointer to EFI_USB_DEVICE_INFO instance to copy into.
|
|
|
|
@retval - EFI_SUCCESS - copy created successfully.
|
|
@retval - Other - failed to create copy.
|
|
**/
|
|
EFI_STATUS
|
|
CopySSDeviceDescriptor(
|
|
IN EFI_USB_SUPERSPEED_DEVICE_INFO *SourceDeviceInfo,
|
|
IN EFI_USB_SUPERSPEED_DEVICE_INFO *TargetDeviceInfo
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
|
|
if (SourceDeviceInfo == NULL || TargetDeviceInfo == NULL) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
DEBUG((USB_FUIO_DEBUG_INFO, "[%a] Start.\n", __FUNCTION__));
|
|
|
|
//Allocate and copy DeviceDescriptor
|
|
TargetDeviceInfo->DeviceDescriptor = AllocateZeroPool(sizeof(EFI_USB_DEVICE_DESCRIPTOR));
|
|
if (TargetDeviceInfo->DeviceDescriptor == NULL) {
|
|
Status = EFI_OUT_OF_RESOURCES;
|
|
goto Cleanup;
|
|
}
|
|
CopyMem(TargetDeviceInfo->DeviceDescriptor, SourceDeviceInfo->DeviceDescriptor, sizeof(EFI_USB_DEVICE_DESCRIPTOR));
|
|
|
|
DEBUG((USB_FUIO_DEBUG_INFO, "[%a] DeviceDescriptor allocated and copied.\n", __FUNCTION__));
|
|
|
|
//Allocate space for ConfigInfoTable
|
|
TargetDeviceInfo->ConfigInfoTable =
|
|
AllocateZeroPool(sizeof(EFI_USB_SUPERSPEED_CONFIG_INFO*)* TargetDeviceInfo->DeviceDescriptor->NumConfigurations);
|
|
if (TargetDeviceInfo->ConfigInfoTable == NULL) {
|
|
Status = EFI_OUT_OF_RESOURCES;
|
|
goto Cleanup;
|
|
}
|
|
|
|
DEBUG((USB_FUIO_DEBUG_INFO, "[%a] ConfigInfoTable allocated (%d entries).\n", __FUNCTION__,
|
|
TargetDeviceInfo->DeviceDescriptor->NumConfigurations));
|
|
|
|
//Copy Config Table Entries
|
|
Status = EFI_SUCCESS;
|
|
for (UINTN ConfigIdx = 0; ConfigIdx < TargetDeviceInfo->DeviceDescriptor->NumConfigurations; ConfigIdx++) {
|
|
//Allocate table entry
|
|
TargetDeviceInfo->ConfigInfoTable[ConfigIdx] =
|
|
AllocateZeroPool(sizeof(EFI_USB_SUPERSPEED_CONFIG_INFO));
|
|
if (TargetDeviceInfo->ConfigInfoTable[ConfigIdx] == NULL) {
|
|
Status = EFI_OUT_OF_RESOURCES;
|
|
goto Cleanup;
|
|
}
|
|
|
|
//Deep-Copy the Config Descriptor (and sub-structures)
|
|
Status = CopySSConfigDescriptor(
|
|
SourceDeviceInfo->ConfigInfoTable[ConfigIdx],
|
|
TargetDeviceInfo->ConfigInfoTable[ConfigIdx]);
|
|
|
|
DEBUG((USB_FUIO_DEBUG_INFO, "[%a] ConfigInfoTable[%d] allocated and copied.\n", __FUNCTION__, ConfigIdx));
|
|
}
|
|
|
|
//Allocate and copy DeviceDescriptor
|
|
TargetDeviceInfo->BosDescriptor = AllocateZeroPool(sizeof(EFI_USB_BOS_DESCRIPTOR));
|
|
if (TargetDeviceInfo->BosDescriptor == NULL) {
|
|
Status = EFI_OUT_OF_RESOURCES;
|
|
goto Cleanup;
|
|
}
|
|
CopyMem(TargetDeviceInfo->BosDescriptor, SourceDeviceInfo->BosDescriptor, sizeof(EFI_USB_BOS_DESCRIPTOR));
|
|
|
|
DEBUG((USB_FUIO_DEBUG_INFO, "[%a] BosDescriptor allocated and copied.\n", __FUNCTION__));
|
|
|
|
Cleanup:
|
|
DEBUG((USB_FUIO_DEBUG_INFO, "[%a] done. Status %r\n", __FUNCTION__, Status));
|
|
if (EFI_ERROR(Status)) {
|
|
FreeSSDeviceInfo(TargetDeviceInfo);
|
|
}
|
|
return Status;
|
|
}
|
|
|
|
/**
|
|
Allocates and returns a new DeviceInfo structure that is a copy of the specified DeviceInfo Structure.
|
|
|
|
@param[in] DeviceInfo A pointer to EFI_USB_DEVICE_INFO instance to copy.
|
|
@param[in] NewDeviceInfo A pointer to a pointer to EFI_USB_DEVICE_INFO to receive the newly allocated copy.
|
|
|
|
@retval - EFI_SUCCESS - copy created successfully.
|
|
@retval - Other - failed to create copy. NewDeviceInfo unmodified.
|
|
**/
|
|
EFI_STATUS
|
|
CopyDeviceInfo(
|
|
IN EFI_USB_DEVICE_INFO *DeviceInfo,
|
|
OUT EFI_USB_DEVICE_INFO **NewDeviceInfo
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
EFI_USB_DEVICE_INFO *WorkingDeviceInfo;
|
|
|
|
if (DeviceInfo == NULL || NewDeviceInfo == NULL) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
DEBUG((USB_FUIO_DEBUG_INFO, "[%a] Start.\n", __FUNCTION__));
|
|
|
|
//Allocate space for the new DeviceInfo
|
|
WorkingDeviceInfo = AllocateZeroPool(sizeof (EFI_USB_DEVICE_INFO));
|
|
if (WorkingDeviceInfo == NULL) {
|
|
Status = EFI_OUT_OF_RESOURCES;
|
|
goto Cleanup;
|
|
}
|
|
|
|
//Deep-Copy the Device Descriptor (and sub-structures)
|
|
Status = CopyDeviceDescriptor(DeviceInfo, WorkingDeviceInfo);
|
|
|
|
Cleanup:
|
|
DEBUG((USB_FUIO_DEBUG_INFO, "[%a] done. Status %r\n", __FUNCTION__, Status));
|
|
if (EFI_ERROR(Status)) {
|
|
if (WorkingDeviceInfo != NULL) {
|
|
FreePool(WorkingDeviceInfo);
|
|
}
|
|
} else {
|
|
*NewDeviceInfo = WorkingDeviceInfo;
|
|
}
|
|
return Status;
|
|
}
|
|
|
|
/**
|
|
Allocates and returns a new DeviceInfo structure that is a copy of the specified DeviceInfo Structure.
|
|
|
|
@param[in] DeviceInfo A pointer to EFI_USB_DEVICE_INFO instance to copy.
|
|
@param[in] NewDeviceInfo A pointer to a pointer to EFI_USB_DEVICE_INFO to receive the newly allocated copy.
|
|
|
|
@retval - EFI_SUCCESS - copy created successfully.
|
|
@retval - Other - failed to create copy. NewDeviceInfo unmodified.
|
|
**/
|
|
EFI_STATUS
|
|
CopySSDeviceInfo(
|
|
IN EFI_USB_SUPERSPEED_DEVICE_INFO *DeviceInfo,
|
|
OUT EFI_USB_SUPERSPEED_DEVICE_INFO **NewDeviceInfo
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
EFI_USB_SUPERSPEED_DEVICE_INFO *WorkingDeviceInfo;
|
|
|
|
if (DeviceInfo == NULL || NewDeviceInfo == NULL) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
DEBUG((USB_FUIO_DEBUG_INFO, "[%a] Start.\n", __FUNCTION__));
|
|
|
|
//Allocate space for the new DeviceInfo
|
|
WorkingDeviceInfo = AllocateZeroPool(sizeof (EFI_USB_SUPERSPEED_DEVICE_INFO));
|
|
if (WorkingDeviceInfo == NULL) {
|
|
Status = EFI_OUT_OF_RESOURCES;
|
|
goto Cleanup;
|
|
}
|
|
|
|
//Deep-Copy the Device Descriptor (and sub-structures)
|
|
Status = CopySSDeviceDescriptor(DeviceInfo, WorkingDeviceInfo);
|
|
|
|
Cleanup:
|
|
DEBUG((USB_FUIO_DEBUG_INFO, "[%a] done. Status %r\n", __FUNCTION__, Status));
|
|
if (EFI_ERROR(Status)) {
|
|
if (WorkingDeviceInfo != NULL) {
|
|
FreePool(WorkingDeviceInfo);
|
|
}
|
|
}
|
|
else {
|
|
*NewDeviceInfo = WorkingDeviceInfo;
|
|
}
|
|
return Status;
|
|
}
|
|
|
|
/**
|
|
Configure Super Speed endpoints based on supplied device and configuration descriptors.
|
|
|
|
@param[in] This A pointer to the EFI_USBFN_IO_PROTOCOL instance.
|
|
@param[in] SSDeviceInfo A pointer to EFI_USB_SUPERSPEED_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
|
|
ConfigureEnableSSEndpoints (
|
|
IN EFI_USBFN_IO_PROTOCOL *This,
|
|
IN EFI_USB_SUPERSPEED_DEVICE_INFO *SSDeviceInfo
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
USB_XDCI_DEV_CONTEXT *UsbFuncIoDevPtr;
|
|
EFI_USB_SUPERSPEED_DEVICE_INFO *TmpDeviceInfo;
|
|
|
|
UsbFuncIoDevPtr = USBFUIO_CONTEXT_FROM_PROTOCOL(This);
|
|
Status = EFI_SUCCESS;
|
|
|
|
DEBUG((USB_FUIO_DEBUG_LOAD, "ConfigureEnableSSEndpoints - 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 (SSDeviceInfo == NULL) {
|
|
Status = EFI_INVALID_PARAMETER;
|
|
goto FUNC_EXIT;
|
|
}
|
|
|
|
DEBUG((USB_FUIO_DEBUG_INFO, "[%a] Starting validation\n", __FUNCTION__));
|
|
|
|
//Validate Device Info before allocating new device info.
|
|
if (SSDeviceInfo->DeviceDescriptor->NumConfigurations < 1) {
|
|
DEBUG((DEBUG_ERROR, "[%a] - Warning - DeviceDescriptor->NumConfigurations (%d) < 1\n", __FUNCTION__, SSDeviceInfo->DeviceDescriptor->NumConfigurations));
|
|
Status = EFI_INVALID_PARAMETER;
|
|
goto FUNC_EXIT;
|
|
}
|
|
if (SSDeviceInfo->DeviceDescriptor->NumConfigurations > 1) {
|
|
DEBUG((DEBUG_WARN, "[%a] - Warning - DeviceDescriptor->NumConfigurations (%d) > 1\n", __FUNCTION__, SSDeviceInfo->DeviceDescriptor->NumConfigurations));
|
|
}
|
|
|
|
if (SSDeviceInfo->ConfigInfoTable[0]->ConfigDescriptor->NumInterfaces < 1) {
|
|
DEBUG((DEBUG_ERROR, "[%a] - Error - SSDeviceInfo->ConfigInfoTable[0]->ConfigDescriptor->NumInterfaces (%d) < 1\n", __FUNCTION__, SSDeviceInfo->ConfigInfoTable[0]->ConfigDescriptor->NumInterfaces));
|
|
Status = EFI_INVALID_PARAMETER;
|
|
goto FUNC_EXIT;
|
|
}
|
|
if (SSDeviceInfo->ConfigInfoTable[0]->ConfigDescriptor->NumInterfaces > 1) {
|
|
DEBUG((DEBUG_WARN, "[%a] - Warning - SSDeviceInfo->ConfigInfoTable[0]->ConfigDescriptor->NumInterfaces (%d) > 1\n", __FUNCTION__, SSDeviceInfo->ConfigInfoTable[0]->ConfigDescriptor->NumInterfaces));
|
|
}
|
|
|
|
if (SSDeviceInfo->ConfigInfoTable[0]->InterfaceInfoTable[0]->InterfaceDescriptor->NumEndpoints < 2) {
|
|
DEBUG((DEBUG_ERROR, "[%a] - Error - SSDeviceInfo->ConfigInfoTable[0]->InterfaceInfoTable[0]->InterfaceDescriptor->NumEndpoints (%d) < 2\n",
|
|
__FUNCTION__, SSDeviceInfo->ConfigInfoTable[0]->InterfaceInfoTable[0]->InterfaceDescriptor->NumEndpoints));
|
|
Status = EFI_INVALID_PARAMETER;
|
|
goto FUNC_EXIT;
|
|
}
|
|
if (SSDeviceInfo->ConfigInfoTable[0]->InterfaceInfoTable[0]->InterfaceDescriptor->NumEndpoints > 2) {
|
|
DEBUG((DEBUG_WARN, "[%a] - Warning - SSDeviceInfo->ConfigInfoTable[0]->InterfaceInfoTable[0]->InterfaceDescriptor->NumEndpoints (%d) > 2\n",
|
|
__FUNCTION__, SSDeviceInfo->ConfigInfoTable[0]->InterfaceInfoTable[0]->InterfaceDescriptor->NumEndpoints));
|
|
}
|
|
|
|
DEBUG((USB_FUIO_DEBUG_INFO, "[%a] Device Info Valid\n", __FUNCTION__));
|
|
|
|
//
|
|
// Allocate new Device Info and copy provided device info.
|
|
//
|
|
TmpDeviceInfo = NULL;
|
|
Status = CopySSDeviceInfo(SSDeviceInfo, &TmpDeviceInfo);
|
|
if (EFI_ERROR(Status)) {
|
|
DEBUG((USB_FUIO_DEBUG_INFO, "[%a] - Failed to copy SSDeviceInfo: %r\n", __FUNCTION__, Status));
|
|
goto FUNC_EXIT;
|
|
}
|
|
|
|
DEBUG((USB_FUIO_DEBUG_INFO, "[%a] Copy SSDeviceInfo succeeded\n", __FUNCTION__));
|
|
|
|
//If successful, free the old devinfo (if present), and update it to new dev info
|
|
if (UsbFuncIoDevPtr->SSDevInfoPtr != NULL) {
|
|
FreeSSDeviceInfo(UsbFuncIoDevPtr->SSDevInfoPtr);
|
|
return EFI_SUCCESS;
|
|
}
|
|
UsbFuncIoDevPtr->SSDevInfoPtr = TmpDeviceInfo;
|
|
|
|
//
|
|
// Set Configure table
|
|
//
|
|
UsbFuncIoDevPtr->SSIndexPtrConfig.ConfigDescriptor = UsbFuncIoDevPtr->SSDevInfoPtr->ConfigInfoTable[0]->ConfigDescriptor;
|
|
UsbFuncIoDevPtr->SSIndexPtrConfig.InterfaceInfoTable = UsbFuncIoDevPtr->SSDevInfoPtr->ConfigInfoTable[0]->InterfaceInfoTable;
|
|
|
|
DEBUG((USB_FUIO_DEBUG_INFO, "[%a] Set Configure table done.\n", __FUNCTION__));
|
|
|
|
//
|
|
// Set Interface
|
|
//
|
|
UsbFuncIoDevPtr->SSIndexPtrInteface.InterfaceDescriptor = UsbFuncIoDevPtr->SSDevInfoPtr->ConfigInfoTable[0]->InterfaceInfoTable[0]->InterfaceDescriptor;
|
|
|
|
DEBUG((USB_FUIO_DEBUG_INFO, "[%a] Set Interface done.\n", __FUNCTION__));
|
|
|
|
//
|
|
// Set Endpoint
|
|
//
|
|
UsbFuncIoDevPtr->IndexPtrInEp.EndpointCompDesc = NULL;
|
|
UsbFuncIoDevPtr->IndexPtrOutEp.EndpointCompDesc = NULL;
|
|
|
|
if ((UsbFuncIoDevPtr->SSDevInfoPtr->ConfigInfoTable[0]->InterfaceInfoTable[0]->EndpointDescriptorTable[0]->EndpointDescriptor->EndpointAddress & USB_ENDPOINT_DIR_IN) != 0) {
|
|
UsbFuncIoDevPtr->SSIndexPtrInEp.EndpointDesc = UsbFuncIoDevPtr->SSDevInfoPtr->ConfigInfoTable[0]->InterfaceInfoTable[0]->EndpointDescriptorTable[0]->EndpointDescriptor;
|
|
UsbFuncIoDevPtr->SSIndexPtrOutEp.EndpointDesc = UsbFuncIoDevPtr->SSDevInfoPtr->ConfigInfoTable[0]->InterfaceInfoTable[0]->EndpointDescriptorTable[1]->EndpointDescriptor;
|
|
}
|
|
else {
|
|
UsbFuncIoDevPtr->SSIndexPtrInEp.EndpointDesc = UsbFuncIoDevPtr->SSDevInfoPtr->ConfigInfoTable[0]->InterfaceInfoTable[0]->EndpointDescriptorTable[1]->EndpointDescriptor;
|
|
UsbFuncIoDevPtr->SSIndexPtrOutEp.EndpointDesc = UsbFuncIoDevPtr->SSDevInfoPtr->ConfigInfoTable[0]->InterfaceInfoTable[0]->EndpointDescriptorTable[0]->EndpointDescriptor;
|
|
}
|
|
|
|
DEBUG((USB_FUIO_DEBUG_INFO, "[%a] Set Endpoint done.\n", __FUNCTION__));
|
|
|
|
DEBUG((USB_FUIO_DEBUG_LOAD, " In Ep Num 0x%02x\n", UsbFuncIoDevPtr->SSIndexPtrInEp.EndpointDesc->EndpointAddress));
|
|
|
|
DEBUG((USB_FUIO_DEBUG_LOAD, " Out Ep Num 0x%02x\n", UsbFuncIoDevPtr->SSIndexPtrOutEp.EndpointDesc->EndpointAddress));
|
|
|
|
FUNC_EXIT:
|
|
DEBUG((USB_FUIO_DEBUG_LOAD, "ConfigureEnableEndpoints - exit %r\n", Status));
|
|
return Status;
|
|
}
|
|
/**
|
|
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;
|
|
EFI_USB_DEVICE_INFO *TmpDeviceInfo;
|
|
|
|
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;
|
|
}
|
|
|
|
DEBUG((USB_FUIO_DEBUG_INFO, "[%a] Starting validation\n", __FUNCTION__));
|
|
|
|
//Validate Device Info before allocating new device info.
|
|
if (DeviceInfo->DeviceDescriptor->NumConfigurations < 1) {
|
|
DEBUG ((DEBUG_ERROR, "[%a] - Warning - DeviceDescriptor->NumConfigurations (%d) < 1\n", __FUNCTION__, DeviceInfo->DeviceDescriptor->NumConfigurations));
|
|
Status = EFI_INVALID_PARAMETER;
|
|
goto FUNC_EXIT;
|
|
}
|
|
if (DeviceInfo->DeviceDescriptor->NumConfigurations > 1) {
|
|
DEBUG ((DEBUG_WARN, "[%a] - Warning - DeviceDescriptor->NumConfigurations (%d) > 1\n", __FUNCTION__, DeviceInfo->DeviceDescriptor->NumConfigurations));
|
|
}
|
|
|
|
if (DeviceInfo->ConfigInfoTable[0]->ConfigDescriptor->NumInterfaces < 1) {
|
|
DEBUG ((DEBUG_ERROR, "[%a] - Error - DeviceInfo->ConfigInfoTable[0]->ConfigDescriptor->NumInterfaces (%d) < 1\n", __FUNCTION__, DeviceInfo->ConfigInfoTable[0]->ConfigDescriptor->NumInterfaces));
|
|
Status = EFI_INVALID_PARAMETER;
|
|
goto FUNC_EXIT;
|
|
}
|
|
if (DeviceInfo->ConfigInfoTable[0]->ConfigDescriptor->NumInterfaces > 1) {
|
|
DEBUG ((DEBUG_WARN, "[%a] - Warning - DeviceInfo->ConfigInfoTable[0]->ConfigDescriptor->NumInterfaces (%d) > 1\n", __FUNCTION__, DeviceInfo->ConfigInfoTable[0]->ConfigDescriptor->NumInterfaces));
|
|
}
|
|
|
|
if (DeviceInfo->ConfigInfoTable[0]->InterfaceInfoTable[0]->InterfaceDescriptor->NumEndpoints < 2) {
|
|
DEBUG ((DEBUG_ERROR, "[%a] - Error - DeviceInfo->ConfigInfoTable[0]->InterfaceInfoTable[0]->InterfaceDescriptor->NumEndpoints (%d) < 2\n",
|
|
__FUNCTION__, DeviceInfo->ConfigInfoTable[0]->InterfaceInfoTable[0]->InterfaceDescriptor->NumEndpoints));
|
|
Status = EFI_INVALID_PARAMETER;
|
|
goto FUNC_EXIT;
|
|
}
|
|
if (DeviceInfo->ConfigInfoTable[0]->InterfaceInfoTable[0]->InterfaceDescriptor->NumEndpoints > 2) {
|
|
DEBUG ((DEBUG_WARN, "[%a] - Warning - DeviceInfo->ConfigInfoTable[0]->InterfaceInfoTable[0]->InterfaceDescriptor->NumEndpoints (%d) > 2\n",
|
|
__FUNCTION__, DeviceInfo->ConfigInfoTable[0]->InterfaceInfoTable[0]->InterfaceDescriptor->NumEndpoints));
|
|
}
|
|
|
|
DEBUG((USB_FUIO_DEBUG_INFO, "[%a] Device Info Valid\n", __FUNCTION__));
|
|
|
|
//
|
|
// Allocate new Device Info and copy provided device info.
|
|
//
|
|
TmpDeviceInfo = NULL;
|
|
Status = CopyDeviceInfo(DeviceInfo, &TmpDeviceInfo);
|
|
if (EFI_ERROR(Status)) {
|
|
DEBUG((USB_FUIO_DEBUG_INFO, "[%a] - Failed to copy DeviceInfo: %r\n", __FUNCTION__, Status));
|
|
goto FUNC_EXIT;
|
|
}
|
|
|
|
DEBUG((USB_FUIO_DEBUG_INFO, "[%a] Copy DeviceInfo succeeded\n", __FUNCTION__));
|
|
|
|
//If successful, free the old devinfo (if present), and update it to new dev info
|
|
if (UsbFuncIoDevPtr->DevInfoPtr != NULL) {
|
|
FreeDeviceInfo(UsbFuncIoDevPtr->DevInfoPtr);
|
|
}
|
|
UsbFuncIoDevPtr->DevInfoPtr = TmpDeviceInfo;
|
|
|
|
//
|
|
// Set Configure table
|
|
//
|
|
UsbFuncIoDevPtr->IndexPtrConfig.ConfigDescriptor = UsbFuncIoDevPtr->DevInfoPtr->ConfigInfoTable[0]->ConfigDescriptor;
|
|
UsbFuncIoDevPtr->IndexPtrConfig.InterfaceInfoTable = UsbFuncIoDevPtr->DevInfoPtr->ConfigInfoTable[0]->InterfaceInfoTable;
|
|
|
|
DEBUG((USB_FUIO_DEBUG_INFO, "[%a] Set Configure table done.\n", __FUNCTION__));
|
|
|
|
//
|
|
// Set Interface
|
|
//
|
|
UsbFuncIoDevPtr->IndexPtrInteface.InterfaceDescriptor = UsbFuncIoDevPtr->DevInfoPtr->ConfigInfoTable[0]->InterfaceInfoTable[0]->InterfaceDescriptor;
|
|
|
|
DEBUG((USB_FUIO_DEBUG_INFO, "[%a] Set Interface done.\n", __FUNCTION__));
|
|
|
|
//
|
|
// Set Endpoint
|
|
//
|
|
UsbFuncIoDevPtr->IndexPtrInEp.EndpointCompDesc = NULL;
|
|
UsbFuncIoDevPtr->IndexPtrOutEp.EndpointCompDesc = NULL;
|
|
|
|
if ((UsbFuncIoDevPtr->DevInfoPtr->ConfigInfoTable[0]->InterfaceInfoTable[0]->EndpointDescriptorTable[0]->EndpointAddress & USB_ENDPOINT_DIR_IN) != 0) {
|
|
UsbFuncIoDevPtr->IndexPtrInEp.EndpointDesc = UsbFuncIoDevPtr->DevInfoPtr->ConfigInfoTable[0]->InterfaceInfoTable[0]->EndpointDescriptorTable[0];
|
|
UsbFuncIoDevPtr->IndexPtrOutEp.EndpointDesc = UsbFuncIoDevPtr->DevInfoPtr->ConfigInfoTable[0]->InterfaceInfoTable[0]->EndpointDescriptorTable[1];
|
|
} else {
|
|
UsbFuncIoDevPtr->IndexPtrInEp.EndpointDesc = UsbFuncIoDevPtr->DevInfoPtr->ConfigInfoTable[0]->InterfaceInfoTable[0]->EndpointDescriptorTable[1];
|
|
UsbFuncIoDevPtr->IndexPtrOutEp.EndpointDesc = UsbFuncIoDevPtr->DevInfoPtr->ConfigInfoTable[0]->InterfaceInfoTable[0]->EndpointDescriptorTable[0];
|
|
}
|
|
|
|
DEBUG((USB_FUIO_DEBUG_INFO, "[%a] Set Endpoint done.\n", __FUNCTION__));
|
|
|
|
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;
|
|
|
|
Status = EFI_SUCCESS;
|
|
|
|
DEBUG ((USB_FUIO_DEBUG_LOAD, "GetEndpointMaxPacketSize - Entry\n"));
|
|
|
|
switch (EndpointType) {
|
|
case UsbEndpointControl:
|
|
//*MaxPacketSize = USB_EP0_MAX_PKT_SIZE_HS;
|
|
#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
|
|
)
|
|
{
|
|
//#ifdef SUPPORT_SUPER_SPEED
|
|
// *MaxTransferSize = USB_BULK_EP_PKT_SIZE_SS;
|
|
//#else
|
|
// *MaxTransferSize = USB_BULK_EP_PKT_SIZE_HS;
|
|
//#endif
|
|
|
|
//
|
|
// 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)) {
|
|
DEBUG((USB_FUIO_DEBUG_LOAD, "+GetDeviceSerialNumber 1\n"));
|
|
Status = EFI_BUFFER_TOO_SMALL;
|
|
*BufferSize = 0;
|
|
goto Error;
|
|
}
|
|
|
|
/* Data1 will get the product serial number (populated from the eMMC) */
|
|
//mSmBiosUniqueGuid.Data1 = PcdGet32(PcdProductSerialNumber);
|
|
|
|
/* Data4[0] will contain the manufacturer ID (populated from the eMMC) */
|
|
//mSmBiosUniqueGuid.Data4[0] = PcdGet8(PcdEmmcManufacturerId);
|
|
|
|
/**
|
|
* 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))
|
|
{
|
|
DEBUG((USB_FUIO_DEBUG_LOAD, "+GetDeviceSerialNumber 2\n"));
|
|
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.
|
|
|
|
@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) {
|
|
|
|
case EfiUsbDeviceInfoSerialNumber:
|
|
Status = GetDeviceSerialNumber(BufferSize, Buffer);
|
|
if (!EFI_ERROR(Status))
|
|
{
|
|
goto FUN_EXIT;
|
|
}
|
|
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, "GetDeviceInfo - 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;
|
|
USB_EP_INFO EpInfo;
|
|
EFI_STATUS Status;
|
|
|
|
DEBUG ((USB_FUIO_DEBUG_LOAD, "FU:AbortTransfer EP 0x%02x- Direction %d __Entry\n", EndpointIndex, Direction));
|
|
UsbFuncIoDevPtr = USBFUIO_CONTEXT_FROM_PROTOCOL (This);
|
|
Status = EFI_SUCCESS;
|
|
|
|
if (UsbFuncIoDevPtr->DevResetFlag == TRUE) {
|
|
return Status;
|
|
}
|
|
|
|
EpInfo.ep_num = EndpointIndex;
|
|
EpInfo.ep_dir = Direction? UsbEpDirIn : UsbEpDirOut;
|
|
|
|
Status = usb_device_ep_cancel_transfer (UsbFuncIoDevPtr->DrvCore, &EpInfo);
|
|
if (EndpointIndex == 0x00 && Direction == EfiUsbEndpointDirectionHostOut) {
|
|
SetEndpointStallState(This,EndpointIndex,Direction,TRUE);
|
|
}
|
|
|
|
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 = usb_get_physical_ep_num (EndpointIndex, Direction ? UsbEpDirIn : UsbEpDirOut);
|
|
|
|
XdciCorePtr = UsbFuncIoDevPtr->XdciDrvIfHandle;
|
|
|
|
if (XdciCorePtr->ep_handles[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;
|
|
USB_DEV_CORE *UsbDeviceCorePtr;
|
|
|
|
DEBUG ((USB_FUIO_DEBUG_LOAD, "UsbSetAddress - 0x%04x Entry\n", Address));
|
|
|
|
UsbFuncIoDevPtr = USBFUIO_CONTEXT_FROM_PROTOCOL (This);
|
|
|
|
UsbDeviceCorePtr = UsbFuncIoDevPtr->DrvCore;
|
|
Status = EFI_SUCCESS;
|
|
|
|
Status = usb_device_set_address (UsbDeviceCorePtr, (UINT32)Address);
|
|
|
|
if (Status != EFI_SUCCESS) {
|
|
Status = EFI_DEVICE_ERROR;
|
|
goto EXIT_SET_ADDRESS;
|
|
}
|
|
|
|
Status = usb_device_ep0_tx_status (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;
|
|
USB_DEV_CORE *UsbDeviceCorePtr;
|
|
UINT32 InterfaceNum;
|
|
UINT32 EndPointNum;
|
|
UINT32 EndPointIndex;
|
|
EFI_USB_INTERFACE_INFO *InterfaceInfoPtr;
|
|
EFI_USB_SUPERSPEED_INTERFACE_INFO *SSInterfaceInfoPtr;
|
|
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;
|
|
Status = EFI_SUCCESS;
|
|
if (UsbFuncIoDevPtr->XdciDrvIfHandle->actual_speed == USB_SPEED_SUPER) {
|
|
InterfaceNum = UsbFuncIoDevPtr->SSIndexPtrConfig.ConfigDescriptor->NumInterfaces;
|
|
DEBUG((USB_FUIO_DEBUG_LOAD, "UsbSetconfigure - ConfigDescriptor addr 0x%08x \n", (UINTN)UsbFuncIoDevPtr->SSIndexPtrConfig.ConfigDescriptor));
|
|
|
|
DEBUG((USB_FUIO_DEBUG_LOAD, "UsbSetconfigure - DescriptorType 0x%04x ; ConfigurationValue 0x%04x\n",
|
|
UsbFuncIoDevPtr->SSIndexPtrConfig.ConfigDescriptor->DescriptorType,
|
|
UsbFuncIoDevPtr->SSIndexPtrConfig.ConfigDescriptor->ConfigurationValue
|
|
));
|
|
} else {
|
|
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'.
|
|
//
|
|
if (UsbFuncIoDevPtr->XdciDrvIfHandle->actual_speed == USB_SPEED_SUPER) {
|
|
SSInterfaceInfoPtr = UsbFuncIoDevPtr->SSIndexPtrConfig.InterfaceInfoTable[InterFaceIndex - 1];
|
|
EndPointNum = SSInterfaceInfoPtr->InterfaceDescriptor->NumEndpoints;
|
|
} else {
|
|
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++) {
|
|
if (UsbFuncIoDevPtr->XdciDrvIfHandle->actual_speed == USB_SPEED_SUPER) {
|
|
EpDescInfo.EndpointDesc = SSInterfaceInfoPtr->EndpointDescriptorTable[EndPointIndex]->EndpointDescriptor;
|
|
EpDescInfo.EndpointCompDesc = (EFI_USB_ENDPOINT_COMPANION_DESCRIPTOR *) SSInterfaceInfoPtr->EndpointDescriptorTable[EndPointIndex]->EndpointCompanionDescriptor;
|
|
} else {
|
|
EpDescInfo.EndpointDesc = InterfaceInfoPtr->EndpointDescriptorTable[EndPointIndex];
|
|
EpDescInfo.EndpointCompDesc = NULL;
|
|
}
|
|
UsbFnSetEpInfo (&EpInfo, &EpDescInfo);
|
|
DEBUG ((USB_FUIO_DEBUG_LOAD, "EndpointAddress 0x%02x\n", EpDescInfo.EndpointDesc->EndpointAddress));
|
|
|
|
if (usb_device_init_ep (UsbDeviceCorePtr, &EpInfo) == EFI_SUCCESS) {
|
|
if (usb_device_ep_enable (UsbDeviceCorePtr, &EpInfo) == EFI_SUCCESS) {
|
|
} else {
|
|
Status = EFI_DEVICE_ERROR;
|
|
DEBUG ((DEBUG_INFO, "usb_device_ep_enable() - Failed to enable endpoint\n"));
|
|
}
|
|
} else {
|
|
Status = EFI_DEVICE_ERROR;
|
|
DEBUG ((DEBUG_INFO, "usb_device_init_ep() - Failed to initialize endpoint\n"));
|
|
}
|
|
}
|
|
if (UsbFuncIoDevPtr->XdciDrvIfHandle->actual_speed != USB_SPEED_SUPER) {
|
|
Status = usb_device_ep0_tx_status (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.ep_num = EndpointIndex;
|
|
pEpInfo.ep_dir = Direction? UsbEpDirIn : UsbEpDirOut;
|
|
|
|
if (State == TRUE) {
|
|
Status = usb_device_ep_stall (UsbFuncIoDevPtr->DrvCore, (VOID*)(UINTN) &pEpInfo);
|
|
} else {
|
|
Status = usb_device_ep_clear_stall (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,
|
|
IN OUT UINTN *PayloadSize,
|
|
OUT EFI_USBFN_MESSAGE_PAYLOAD *Payload,
|
|
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->controller_handle;
|
|
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"));
|
|
UsbFuncIoDevPtr->DevDisReConnect = TRUE;
|
|
*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 reset_det will prepare setup xfer package
|
|
//
|
|
UsbFuncIoDevPtr->DevReConnect = FALSE;
|
|
UsbFuncIoDevPtr->DevResetFlag = TRUE;
|
|
if(UsbFuncIoDevPtr->DevDisReConnect == TRUE) {
|
|
usb_xdci_core_reinit (XdciCorePtr);
|
|
UsbFuncIoDevPtr->DevDisReConnect = FALSE;
|
|
}
|
|
usb_process_device_reset_det(XdciCorePtr);
|
|
usb_device_set_address (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"));
|
|
usb_process_device_reset_done(XdciCorePtr);
|
|
usb_device_set_address(UsbDeviceCorePtr, 0);
|
|
|
|
*Message = EfiUsbMsgBusEventSpeed;
|
|
if (UsbFuncIoDevPtr->XdciDrvIfHandle->actual_speed == USB_SPEED_SUPER) {
|
|
DEBUG ((USB_FUIO_DEBUG_EVENT_D, "ReportSpeed UsbBusSpeedSuper\n"));
|
|
Payload->ubs = UsbBusSpeedSuper;
|
|
} else {
|
|
DEBUG ((USB_FUIO_DEBUG_EVENT_D, "ReportSpeed UsbBusSpeedHigh\n"));
|
|
Payload->ubs = UsbBusSpeedHigh;
|
|
}
|
|
|
|
DEBUG ((USB_FUIO_DEBUG_EVENT_D, "Payload->ubs %02x\n", UsbFuncIoDevPtr->XdciDrvIfHandle->actual_speed ));
|
|
|
|
UsbFuncIoDevPtr->DevReConnect = TRUE;
|
|
UsbFuncIoDevPtr->DevResetFlag = FALSE;
|
|
*EventFlag = TRUE;
|
|
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, "USBFU_dwc_xdci_process_device_event: 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:
|
|
// refer page 457
|
|
usb_process_device_disconnect (XdciCorePtr);
|
|
usb_xdci_core_reinit(XdciCorePtr);
|
|
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, "USBFU_wc_xdci_process_device_event: 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->controller_handle;
|
|
EpHandle = &XdciCorePtr->ep_handles[EndPointNum];
|
|
Trb = XdciCorePtr->trbs + (EndPointNum * DWC_XDCI_TRB_NUM);
|
|
|
|
if (Trb->trb_ctrl & 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->trb_ctrl: %x!!!\n", (UINT32)Trb->trb_ctrl));
|
|
DEBUG ((USB_FUIO_DEBUG_EVENT_D, "Ep0 done Trb->len_xfer_params: %x!!!\n", (UINT32)Trb->len_xfer_params));
|
|
DEBUG ((USB_FUIO_DEBUG_EVENT_D, "Ep0 done Trb->buff_ptr_low: %x!!!\n", (UINT32)Trb->buff_ptr_low));
|
|
DEBUG ((USB_FUIO_DEBUG_EVENT_D, "Ep0 done Trb->buff_ptr_high: %x!!!\n", (UINT32)Trb->buff_ptr_high));
|
|
|
|
//
|
|
// Set CheckFlag to FALSE for 'dwc_xdci_ep_rx_data' 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->trb_ctrl & 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->len_xfer_params & DWC_XDCI_TRB_STATUS_MASK) >> DWC_XDCI_TRB_STATUS_BIT_POS;
|
|
|
|
DEBUG ((USB_FUIO_DEBUG_EVENT_I, "Ep0 done D03!!\n" ));
|
|
BufferLen = Trb->len_xfer_params & 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;
|
|
|
|
if (UsbFuncIoDevPtr->EndPointXferRec[EndPointNum].Ep0RxData == TRUE) {
|
|
|
|
UsbFuncIoDevPtr->EndPointXferRec[EndPointNum].Ep0RxData = FALSE;
|
|
|
|
*Message = EfiUsbMsgEndpointStatusChangedRx;
|
|
Payload->utr.EndpointIndex = (UINT8)(EndPointNum >> 1);
|
|
Payload->utr.Direction = (UINT8)(EndPointNum & 0x01);
|
|
Payload->utr.TransferStatus = UsbTransferStatusComplete;
|
|
Payload->utr.BytesTransferred = UsbFuncIoDevPtr->EndPointXferRec[EndPointNum].XferLength;
|
|
|
|
DEBUG ((USB_FUIO_DEBUG_EVENT_D, "Payload->utr.BytesTransferred::0x%08x!!\n",\
|
|
(UINTN)Payload->utr.BytesTransferred));
|
|
DEBUG ((USB_FUIO_DEBUG_EVENT_D, "UsbFuncIoDevPtr->EndPointXferRec[EndPointNum].XferLength::0x%08x!!\n", \
|
|
(UINTN)UsbFuncIoDevPtr->EndPointXferRec[EndPointNum].XferLength));
|
|
|
|
CopyMem ((UINT8*)UsbFuncIoDevPtr->EndPointXferRec[EndPointNum].XferAddress, \
|
|
XdciCorePtr->aligned_setup_buffer, \
|
|
UsbFuncIoDevPtr->EndPointXferRec[EndPointNum].XferLength);
|
|
break;
|
|
}
|
|
|
|
DEBUG ((USB_FUIO_DEBUG_EVENT_D, "DWC_XDCI_TRB_CTRL_TYPE_SETUP!!\n"));
|
|
DEBUG ((USB_FUIO_DEBUG_EVENT_D, "aligned_setup_buffer::0x%08x!!\n", XdciCorePtr->aligned_setup_buffer));
|
|
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->aligned_setup_buffer, BufferLen);
|
|
|
|
DEBUG ((USB_FUIO_DEBUG_EVENT_I, "Ep0 done D06!!\n"));
|
|
if (!(XdciCorePtr->aligned_setup_buffer[0] & USB_SETUP_DATA_PHASE_DIRECTION_MASK)) {
|
|
/* Keep a buffer ready for setup phase */
|
|
// dwc_xdci_core_start_ep0_setup_xfer(XdciCorePtr);
|
|
if ((XdciCorePtr->aligned_setup_buffer[0] == 0x00) ) {
|
|
if ((XdciCorePtr->aligned_setup_buffer[1] == USB_DEV_SET_ADDRESS)) {
|
|
// set address
|
|
UsbSetAddress (
|
|
This,
|
|
(UINT32)(XdciCorePtr->aligned_setup_buffer[3] << 8 | XdciCorePtr->aligned_setup_buffer[2])
|
|
);
|
|
|
|
*Message = EfiUsbMsgNone;
|
|
} else if ((XdciCorePtr->aligned_setup_buffer[1] == USB_DEV_SET_CONFIGURATION)) {
|
|
DEBUG ((USB_FUIO_DEBUG_EVENT_I, "\n set configure !!!"));
|
|
UsbSetconfigure (
|
|
This,
|
|
(UINT32)(XdciCorePtr->aligned_setup_buffer[3] << 8 | XdciCorePtr->aligned_setup_buffer[2])
|
|
);
|
|
//*Message = EfiUsbMsgNone;
|
|
} else if ((XdciCorePtr->aligned_setup_buffer[1] == 0x00)) {
|
|
|
|
DEBUG ((USB_FUIO_DEBUG_EVENT_D, "Got NULL Package resend RX_SETUP!!\n"));
|
|
usb_device_ep0_rx_setup (UsbDeviceCorePtr, XdciCorePtr->aligned_setup_buffer);
|
|
}
|
|
}
|
|
}
|
|
|
|
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.BytesTransferred = (Trb->buff_ptr_high - Trb->buff_ptr_low);
|
|
Payload->utr.EndpointIndex = (UINT8)(EndPointNum >> 1);
|
|
Payload->utr.Direction = (UINT8)(EndPointNum & 0x01);
|
|
Payload->utr.Buffer = (VOID*)(UINTN)(Trb->buff_ptr_low);
|
|
|
|
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->len_xfer_params & DWC_XDCI_TRB_BUFF_SIZE_MASK) == 0) {
|
|
Payload->utr.TransferStatus = UsbTransferStatusComplete;
|
|
} else {
|
|
Payload->utr.TransferStatus = UsbTransferStatusActive;
|
|
}
|
|
} else if (TrbSts != 0) {
|
|
Trb->trb_ctrl |= DWC_XDCI_TRB_CTRL_HWO_MASK;
|
|
*Message = EfiUsbMsgNone;
|
|
Payload->utr.TransferStatus = UsbTransferStatusAborted;
|
|
DEBUG ((DEBUG_INFO, "Flush FIFO!!!\n" ));
|
|
EpInfo.ep_num = 0;
|
|
EpInfo.ep_dir =UsbEpDirIn;
|
|
usb_xdci_core_flush_ep_fifo(XdciCorePtr, &EpInfo);
|
|
EpInfo.ep_num = 0;
|
|
EpInfo.ep_dir =UsbEpDirOut;
|
|
usb_xdci_core_flush_ep_fifo(XdciCorePtr, &EpInfo);
|
|
DevStatus = usb_device_ep0_rx_setup (UsbDeviceCorePtr, XdciCorePtr->aligned_setup_buffer);
|
|
}
|
|
|
|
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->len_xfer_params & 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 = usb_device_ep0_rx_setup (UsbDeviceCorePtr, XdciCorePtr->aligned_setup_buffer);
|
|
|
|
if (DevStatus) {
|
|
DEBUG ((DEBUG_INFO, "dwc_xdci_process_ep0_xfer_phase_done: FAILED to queue SETUP\n"));
|
|
}
|
|
DEBUG ((DEBUG_INFO, "Status phase done. Queue next SETUP packet==>\n"));
|
|
break;
|
|
|
|
default:
|
|
*Message = EfiUsbMsgNone;
|
|
DEBUG ((DEBUG_INFO, "dwc_xdci_process_ep0_xfer_phase_done: 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 TrbSts;
|
|
UINTN TmpBufferSize;
|
|
UINT8 EndpointIndex;
|
|
|
|
UsbFuncIoDevPtr = USBFUIO_CONTEXT_FROM_PROTOCOL (This);
|
|
UsbDeviceCorePtr = UsbFuncIoDevPtr->DrvCore;
|
|
XdciCorePtr = UsbDeviceCorePtr->controller_handle;
|
|
EpHandle = &XdciCorePtr->ep_handles[EndPointNum];
|
|
Trb = XdciCorePtr->trbs + (EndPointNum * DWC_XDCI_TRB_NUM);
|
|
|
|
if (Trb->trb_ctrl & 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->buff_ptr_low: %x!!!\n", (UINT32)Trb->buff_ptr_low));
|
|
DEBUG ((USB_FUIO_DEBUG_EVENT_D, " Xfer done Trb->buff_ptr_high: %x!!!\n", (UINT32)Trb->buff_ptr_high));
|
|
DEBUG ((USB_FUIO_DEBUG_EVENT_D, " Xfer done Trb->len_xfer_params: %x!!!\n", (UINT32)Trb->len_xfer_params));
|
|
DEBUG ((USB_FUIO_DEBUG_EVENT_D, " Xfer done Trb->trb_ctrl: %x!!!\n", (UINT32)Trb->trb_ctrl));
|
|
|
|
//
|
|
// Set CheckFlag to FALSE for 'dwc_xdci_ep_rx_data' function
|
|
// check the RX request complete and continue next transfer request
|
|
//
|
|
EpHandle->CheckFlag = FALSE;
|
|
EpHandle->currentXferRscIdx = 0;
|
|
*Message = EfiUsbMsgNone;
|
|
|
|
TrbSts = (Trb->len_xfer_params & DWC_XDCI_TRB_STATUS_MASK) >> DWC_XDCI_TRB_STATUS_BIT_POS;
|
|
|
|
Payload->utr.EndpointIndex = UsbFuncIoDevPtr->EndPointXferRec[EndPointNum].LogEpNum;
|
|
Payload->utr.Direction = UsbFuncIoDevPtr->EndPointXferRec[EndPointNum].Direction;
|
|
Payload->utr.Buffer = (VOID*)(UINTN)(Trb->buff_ptr_low);
|
|
Payload->utr.BytesTransferred = UsbFuncIoDevPtr->EndPointXferRec[EndPointNum].ActualXferLength;
|
|
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->len_xfer_params & 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->len_xfer_params & 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"));
|
|
}
|
|
|
|
if (UsbFuncIoDevPtr->EndPointXferRec[EndPointNum].ZlpActive == TRUE) {
|
|
DEBUG ((USB_FUIO_DEBUG_EVENT_D, "ZLP completed. Sending Payload Response data from original transfer\n"));
|
|
CopyMem(&Payload->utr, &UsbFuncIoDevPtr->EndPointXferRec[EndPointNum].ZlpPendingTransferResult, sizeof(EFI_USBFN_TRANSFER_RESULT));
|
|
UsbFuncIoDevPtr->EndPointXferRec[EndPointNum].ZlpActive = FALSE;
|
|
*Message = EfiUsbMsgEndpointStatusChangedTx;
|
|
} else if ((UsbFuncIoDevPtr->EndPointXferRec[EndPointNum].ZlpFlag == TRUE) && (UsbFuncIoDevPtr->EndPointXferRec[EndPointNum].Complete == TRUE)) {
|
|
if ((EndPointNum & 0x01) != 0) {
|
|
DEBUG ((USB_FUIO_DEBUG_EVENT_D, "ZLP requested. Caching original payload and queuing ZLP transfer.\n"));
|
|
CopyMem(&UsbFuncIoDevPtr->EndPointXferRec[EndPointNum].ZlpPendingTransferResult, &Payload->utr, sizeof(EFI_USBFN_TRANSFER_RESULT));
|
|
UsbFuncIoDevPtr->EndPointXferRec[EndPointNum].ZlpActive = TRUE;
|
|
TmpBufferSize = 0;
|
|
if (UsbFuncIoDevPtr->XdciDrvIfHandle->actual_speed == USB_SPEED_SUPER) {
|
|
EndpointIndex = UsbFuncIoDevPtr->SSIndexPtrInEp.EndpointDesc->EndpointAddress;
|
|
} else {
|
|
EndpointIndex = UsbFuncIoDevPtr->IndexPtrInEp.EndpointDesc->EndpointAddress;
|
|
}
|
|
Transfer(This,
|
|
EndpointIndex,
|
|
EfiUsbEndpointDirectionDeviceTx,
|
|
&TmpBufferSize,
|
|
NULL
|
|
);
|
|
*Message = EfiUsbMsgNone;
|
|
} else {
|
|
DEBUG ((USB_FUIO_DEBUG_ERROR, "ZLP requested on bad Endpoint!\n"));
|
|
ASSERT(FALSE); //Just proceed without scheduling the ZLP transfer in this case.
|
|
}
|
|
UsbFuncIoDevPtr->EndPointXferRec[EndPointNum].ZlpFlag = FALSE;
|
|
}
|
|
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
|
|
)
|
|
{
|
|
if ((EpStatus & DWC_XDCI_EVENT_BUFF_EP_CTRL_STATUS_REQ_MASK) != 0) {
|
|
//
|
|
// Check need to do ??
|
|
//
|
|
}
|
|
|
|
*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
|
|
)
|
|
{
|
|
UINT32 EventReg;
|
|
UINT32 EpEvent;
|
|
UINT32 EndPointNumber;
|
|
|
|
DEBUG ((USB_FUIO_DEBUG_EVENT_I, "FUEV::EndPoint Event....\n"));
|
|
|
|
EventReg = EventIndex->event;
|
|
*ProcessSize = DWC_XDCI_DEV_EVENT_DEFAULT_SIZE_IN_BYTES;
|
|
*EventFlag = TRUE;
|
|
|
|
/* Get EP num */
|
|
EndPointNumber = (EventReg & DWC_XDCI_EVENT_BUFF_EP_NUM_MASK) >> DWC_XDCI_EVENT_BUFF_EP_NUM_BIT_POS;
|
|
|
|
|
|
/* 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;
|
|
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, "USBFU_dwc_xdci_process_ep_event: 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->controller_handle;
|
|
CurrentEventAddr = (UINT32)(UINTN)(XdciCorePtr->current_event_buffer);
|
|
EventReport = FALSE;
|
|
EpEventReport = FALSE;
|
|
ProcessEventSize = 0;
|
|
DEBUG ((USB_FUIO_DEBUG_EVENT_I, "FUEV:: ProcessIntLineEvents Entry\n"));
|
|
|
|
DEBUG ((USB_FUIO_DEBUG_EVENT_I, "FUEV:: XdciCorePtr->current_event_buffer 0x%08x\n", XdciCorePtr->current_event_buffer));
|
|
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->current_event_buffer->event));
|
|
if ((XdciCorePtr->current_event_buffer->event & DWC_XDCI_EVENT_DEV_MASK) != 0) {
|
|
//
|
|
// Device event
|
|
//
|
|
DeviceEventCheck (
|
|
This,
|
|
(USBD_EVENT_BUF*)(UINTN)CurrentEventAddr,
|
|
&ProcessEventSize,
|
|
Message,
|
|
PayloadSize,
|
|
Payload,
|
|
&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->aligned_event_buffers) +
|
|
(sizeof(DWC_XDCI_EVENT_BUFFER) * DWC_XDCI_MAX_EVENTS_PER_BUFFER))) {
|
|
CurrentEventAddr = (UINT32)(UINTN)(XdciCorePtr->aligned_event_buffers);
|
|
//DEBUG ((DEBUG_INFO, "FUEV::dwc_xdci_process_interrupt_line_events: Event buffer bound reached\n"));
|
|
} else {
|
|
CurrentEventAddr += ProcessEventSize;
|
|
}
|
|
DEBUG ((USB_FUIO_DEBUG_EVENT_D, "FUEV:: CurrentEventAddr Update 0x%08x :: ProcessEventSize 0x%08x\n", CurrentEventAddr,ProcessEventSize));
|
|
|
|
XdciCorePtr->current_event_buffer = (DWC_XDCI_EVENT_BUFFER*)(UINTN)CurrentEventAddr;
|
|
} // While end
|
|
|
|
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 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_CALLBACK);
|
|
*Message = EfiUsbMsgNone;
|
|
|
|
UsbDeviceCorePtr = UsbFuncIoDevPtr->DrvCore;
|
|
XdciCorePtr = UsbDeviceCorePtr->controller_handle;
|
|
EventFlag = TRUE;
|
|
|
|
DEBUG ((USB_FUIO_DEBUG_EVENT_I, "XdciCorePtr->max_dev_int_lines 0x%08x\n", XdciCorePtr->max_dev_int_lines));
|
|
EventCount = usb_reg_read (UsbFuncIoDevPtr->XdciMmioBarAddr, DWC_XDCI_EVNTCOUNT_REG(0));
|
|
//DEBUG ((USB_FUIO_DEBUG_EVENT_D, "\n ==>> EventCount = 0x%08x \n", EventCount));
|
|
|
|
for (IntIndex = 0; IntIndex < XdciCorePtr->max_dev_int_lines ; IntIndex++) {
|
|
/* Get the number of events HW has written for this
|
|
* interrupt line
|
|
*/
|
|
EventCount = usb_reg_read (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
|
|
*/
|
|
usb_reg_write (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 usb_ep_info 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->ep_num = EpDesc->EndpointAddress & 0x0F; /* Bits 0-3 are ep num */
|
|
EpDest->ep_dir = ((EpDesc->EndpointAddress & USB_ENDPOINT_DIR_IN) > 0) ? UsbEpDirIn : UsbEpDirOut;
|
|
DEBUG ((DEBUG_INFO, "EpDest->ep_num 0x%02x\n", EpDest->ep_num));
|
|
DEBUG ((DEBUG_INFO, "EpDest->ep_dir 0x%02x\n", EpDest->ep_dir));
|
|
EpDest->ep_type = EpDesc->Attributes & USB_ENDPOINT_TYPE_MASK;
|
|
EpDest->max_pkt_size = EpDesc->MaxPacketSize;
|
|
EpDest->interval = EpDesc->Interval;
|
|
}
|
|
if (EpCompDesc != NULL) {
|
|
EpDest->max_streams = EpCompDesc->Attributes & USB_EP_BULK_BM_ATTR_MASK;
|
|
EpDest->burst_size = 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->ep_info.ep_num = 0;
|
|
XfIoreq->ep_info.ep_dir = Direction? UsbEpDirIn : UsbEpDirOut;
|
|
XfIoreq->xfer_len = (UINT32)(*BufferSize);
|
|
break;
|
|
|
|
|
|
default:
|
|
if (Direction == EfiUsbEndpointDirectionDeviceTx) {
|
|
if (UsbFuncIoDevPtr->XdciDrvIfHandle->actual_speed != USB_SPEED_SUPER) {
|
|
UsbFnSetEpInfo(&XfIoreq->ep_info, &UsbFuncIoDevPtr->IndexPtrInEp);
|
|
}
|
|
else {
|
|
UsbFnSetEpInfo(&XfIoreq->ep_info, &UsbFuncIoDevPtr->SSIndexPtrInEp);
|
|
}
|
|
XfIoreq->xfer_len = (UINT32)(*BufferSize);
|
|
} else {
|
|
if (UsbFuncIoDevPtr->XdciDrvIfHandle->actual_speed != USB_SPEED_SUPER) {
|
|
UsbFnSetEpInfo(&XfIoreq->ep_info, &UsbFuncIoDevPtr->IndexPtrOutEp);
|
|
}
|
|
else {
|
|
UsbFnSetEpInfo(&XfIoreq->ep_info, &UsbFuncIoDevPtr->SSIndexPtrOutEp);
|
|
}
|
|
//
|
|
// reference from "UsbDeviceMode.c", function UsbdEpRxData
|
|
//
|
|
|
|
//
|
|
// Transfer length should be multiple of USB packet size.
|
|
//
|
|
ReqPacket = *BufferSize/ XfIoreq->ep_info.max_pkt_size;
|
|
ReqPacket = (((*BufferSize) % XfIoreq->ep_info.max_pkt_size) == 0)? ReqPacket : ReqPacket + 1;
|
|
|
|
DEBUG ((USB_FUIO_DEBUG_LOAD, "\n FU:XfIoreq->ep_info.max_pkt_size 0x%08x\n", XfIoreq->ep_info.max_pkt_size));
|
|
DEBUG ((USB_FUIO_DEBUG_LOAD, "\n FU:ReqPacket 0x%08x\n", ReqPacket));
|
|
|
|
XfIoreq->xfer_len = (UINT32)ReqPacket * XfIoreq->ep_info.max_pkt_size;
|
|
DEBUG ((USB_FUIO_DEBUG_LOAD, "\n FU:XfIoreq->xfer_len 0x%08x\n", XfIoreq->xfer_len));
|
|
|
|
}
|
|
break;
|
|
}
|
|
|
|
if (EFI_ERROR(Status)) {
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
|
|
XfIoreq->xfer_buffer = Buffer;
|
|
XfIoreq->xfer_done = 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 Xfer_req;
|
|
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->controller_handle;
|
|
EndPoint = usb_get_physical_ep_num (EndpointIndex, Direction ? UsbEpDirIn : UsbEpDirOut);
|
|
|
|
Status = SetFnIoReqInfo (
|
|
This,
|
|
EndpointIndex,
|
|
Direction,
|
|
BufferSize,
|
|
Buffer,
|
|
&Xfer_req
|
|
);
|
|
|
|
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].ActualXferLength = Xfer_req.xfer_len;
|
|
UsbFuncIoDevPtr->EndPointXferRec[EndPoint].LogEpNum = EndpointIndex;
|
|
UsbFuncIoDevPtr->EndPointXferRec[EndPoint].Complete = FALSE;
|
|
UsbFuncIoDevPtr->EndPointXferRec[EndPoint].ZlpFlag = FALSE;
|
|
UsbFuncIoDevPtr->EndPointXferRec[EndPoint].Ep0RxData = FALSE;
|
|
|
|
|
|
Status = EFI_DEVICE_ERROR;
|
|
switch (EndpointIndex) {
|
|
case 0: // Control endpoint
|
|
if (*BufferSize == 0) {
|
|
if (Direction == EfiUsbEndpointDirectionDeviceTx) {
|
|
Status = usb_device_ep0_tx_status(UsbDeviceCorePtr);
|
|
} else {
|
|
Status = usb_device_ep0_rx_status(UsbDeviceCorePtr);
|
|
}
|
|
} else if (Direction == EfiUsbEndpointDirectionDeviceTx) {
|
|
Status = usb_device_ep_tx_data(UsbDeviceCorePtr, &Xfer_req);
|
|
} else if (Direction == EfiUsbEndpointDirectionDeviceRx) {
|
|
DEBUG ((USB_FUIO_DEBUG_LOAD, "\n Set Setup Package - ??? Stop!!!\n"));
|
|
|
|
Status = usb_device_ep0_rx_setup (UsbDeviceCorePtr, XdciCorePtr->aligned_setup_buffer);
|
|
if (!EFI_ERROR(Status)) {
|
|
UsbFuncIoDevPtr->EndPointXferRec[EndPoint].Ep0RxData = TRUE;
|
|
}
|
|
|
|
}
|
|
break;
|
|
|
|
default:
|
|
Status = EFI_SUCCESS;
|
|
if (Direction == EfiUsbEndpointDirectionDeviceTx) {
|
|
DEBUG ((USB_FUIO_DEBUG_LOAD, "\n EfiUsbEndpointDirectionDeviceTx Size = %d\n",(*BufferSize) ));
|
|
Xfer_req.zlp = TRUE;
|
|
if ((((*BufferSize) % 512) == 0) && ((*BufferSize) != 0) && (UsbFuncIoDevPtr->EndPointXferRec[EndPoint].ZlpSupport)) {
|
|
UsbFuncIoDevPtr->EndPointXferRec[EndPoint].ZlpFlag = TRUE;
|
|
DEBUG ((USB_FUIO_DEBUG_LOAD, "\n Set Zlp flag\n"));
|
|
}
|
|
Status = usb_device_ep_tx_data (UsbDeviceCorePtr, &Xfer_req);
|
|
} else {
|
|
DEBUG ((USB_FUIO_DEBUG_LOAD, "\n EfiUsbEndpointDirectionDeviceRx Size = %d\n",(*BufferSize) ));
|
|
Status = usb_device_ep_rx_data (UsbDeviceCorePtr, &Xfer_req);
|
|
}
|
|
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 = UsbFuncIoDevPtr->XdciMmioBarAddr;
|
|
ConfigParams.Role = USB_ROLE_DEVICE;
|
|
#ifdef SUPPORT_SUPER_SPEED
|
|
ConfigParams.Speed = USB_SPEED_SUPER;
|
|
#else
|
|
ConfigParams.Speed = USB_SPEED_HIGH;
|
|
#endif
|
|
|
|
//*Vid = 0x8086;
|
|
//*Pid = 0x0A65
|
|
UsbFuncIoDevPtr->VendorId = USBFU_VID;
|
|
UsbFuncIoDevPtr->DeviceId = USBFU_PID;
|
|
UsbFuncIoDevPtr->StartUpController = TRUE;
|
|
|
|
Status = usb_device_init (&ConfigParams, (VOID**)&UsbFuncIoDevPtr->DrvCore);
|
|
if (Status != EFI_SUCCESS) {
|
|
Status = EFI_DEVICE_ERROR;
|
|
goto EXIT_START_CONTROLLER;
|
|
}
|
|
|
|
UsbFuncIoDevPtr->XdciDrvIfHandle = UsbFuncIoDevPtr->DrvCore->controller_handle;
|
|
|
|
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 = usb_device_deinit (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_USB_ENDPOINT_DIRECTION Direction,
|
|
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 = usb_get_physical_ep_num (EndpointIndex, Direction ? UsbEpDirIn : UsbEpDirOut);
|
|
|
|
UsbFuncIoDevPtr->EndPointXferRec[EndPoint].ZlpSupport = *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_USB_ENDPOINT_DIRECTION Direction,
|
|
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 = usb_get_physical_ep_num (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;
|
|
}
|
|
|
|
/**
|
|
This function Configures endpoints based on supplied list of 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.
|
|
@param[in] SSDeviceInfo A pointer to EFI_USBFN_SUPERSPEED_DEVICE_INFO instance
|
|
|
|
@retval EFI_SUCCESS The function returned successfully.
|
|
@retval EFI_UNSUPPORTED This operation is not supported.
|
|
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
ConfigureEnableEndpointsEx (
|
|
IN EFI_USBFN_IO_PROTOCOL *This,
|
|
IN EFI_USB_DEVICE_INFO *DeviceInfo,
|
|
IN EFI_USB_SUPERSPEED_DEVICE_INFO *SSDeviceInfo
|
|
)
|
|
{
|
|
//
|
|
// Set Configure table
|
|
//
|
|
ConfigureEnableEndpoints(This,DeviceInfo);
|
|
ConfigureEnableSSEndpoints(This,SSDeviceInfo);
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
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 = usb_device_connect (UsbFuncIoDevPtr->DrvCore);
|
|
DEBUG ((USB_FUIO_DEBUG_LOAD, "usb_device_connect 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;
|
|
return UsbFnInitDevice(This);
|
|
}
|
|
|
|
|
|
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 = usb_device_disconnect (UsbFuncIoDevPtr->DrvCore);
|
|
DEBUG ((USB_FUIO_DEBUG_LOAD, "usb_device_disconnect 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);
|
|
}
|
|
|