alder_lake_bios/Intel/AlderLake/AlderLakePlatSamplePkg/Features/Usb/UsbDeviceDxe/UsbFuncIo.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);
}