666 lines
20 KiB
C
666 lines
20 KiB
C
/** @file
|
|
Usb Io PPI
|
|
|
|
;******************************************************************************
|
|
;* Copyright (c) 2012 - 2019, Insyde Software Corp. All Rights Reserved.
|
|
;*
|
|
;* You may not reproduce, distribute, publish, display, perform, modify, adapt,
|
|
;* transmit, broadcast, present, recite, release, license or otherwise exploit
|
|
;* any part of this publication in any form, by any means, without the prior
|
|
;* written permission of Insyde Software Corporation.
|
|
;*
|
|
;******************************************************************************
|
|
*/
|
|
|
|
#include "UsbBus.h"
|
|
#include "UsbHelper.h"
|
|
|
|
/**
|
|
|
|
Pei Usb Control Transfer
|
|
|
|
@param PeiServices EFI_PEI_SERVICES
|
|
@param This PEI_USB3_IO_PPI
|
|
@param Request Request packet
|
|
@param Direction IN/OUT/NODATA
|
|
@param Timeout Time out value in millisecond
|
|
@param Data Data buffer
|
|
@param DataLength Data length
|
|
|
|
@retval EFI_SUCCESS Success
|
|
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
PeiUsbControlTransfer (
|
|
IN EFI_PEI_SERVICES **PeiServices,
|
|
IN PEI_USB_IO_PPI *This,
|
|
IN EFI_USB_DEVICE_REQUEST *Request,
|
|
IN EFI_USB_DATA_DIRECTION Direction,
|
|
IN UINT32 Timeout,
|
|
IN OUT VOID *Data, OPTIONAL
|
|
IN UINTN DataLength OPTIONAL
|
|
)
|
|
{
|
|
PEI_USB_DEVICE *PeiUsbDev;
|
|
|
|
PeiUsbDev = PEI_USB_DEVICE_FROM_THIS (This);
|
|
return PeiUsbDev->Usb3IoPpi.UsbControlTransfer (
|
|
PeiServices,
|
|
&PeiUsbDev->Usb3IoPpi,
|
|
Request,
|
|
Direction,
|
|
Timeout,
|
|
Data,
|
|
DataLength
|
|
);
|
|
}
|
|
|
|
/**
|
|
|
|
Pei Usb Bulk Transfer
|
|
|
|
@param PeiServices EFI_PEI_SERVICES
|
|
@param This PEI_USB3_IO_PPI
|
|
@param DeviceEndpoint Device Endpoint
|
|
@param Data Data buffer
|
|
@param DataLength Data length
|
|
@param Timeout Time out value in millisecond
|
|
|
|
@retval EFI_SUCCESS Success
|
|
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
PeiUsbBulkTransfer (
|
|
IN EFI_PEI_SERVICES **PeiServices,
|
|
IN PEI_USB_IO_PPI *This,
|
|
IN UINT8 DeviceEndpoint,
|
|
IN OUT VOID *Data,
|
|
IN OUT UINTN *DataLength,
|
|
IN UINTN Timeout
|
|
)
|
|
{
|
|
PEI_USB_DEVICE *PeiUsbDev;
|
|
|
|
PeiUsbDev = PEI_USB_DEVICE_FROM_THIS (This);
|
|
return PeiUsbDev->Usb3IoPpi.UsbBulkTransfer (
|
|
PeiServices,
|
|
&PeiUsbDev->Usb3IoPpi,
|
|
DeviceEndpoint,
|
|
Data,
|
|
DataLength,
|
|
Timeout
|
|
);
|
|
}
|
|
|
|
/**
|
|
|
|
Retrieves the interface Descriptor for that controller.
|
|
|
|
@param PeiServices EFI_PEI_SERVICES
|
|
@param This Indicates the calling context.
|
|
@param InterfaceDescriptor A pointer to the caller allocated USB interface
|
|
Descriptor.
|
|
|
|
@retval EFI_SUCCESS
|
|
@retval EFI_INVALID_PARAMETER
|
|
@retval EFI_NOT_FOUND
|
|
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
PeiUsbGetInterfaceDescriptor (
|
|
IN EFI_PEI_SERVICES **PeiServices,
|
|
IN PEI_USB_IO_PPI *This,
|
|
OUT EFI_USB_INTERFACE_DESCRIPTOR **InterfaceDescriptor
|
|
)
|
|
{
|
|
PEI_USB_DEVICE *PeiUsbDev;
|
|
|
|
PeiUsbDev = PEI_USB_DEVICE_FROM_THIS (This);
|
|
return PeiUsbDev->Usb3IoPpi.UsbGetInterfaceDescriptor (
|
|
PeiServices,
|
|
&PeiUsbDev->Usb3IoPpi,
|
|
InterfaceDescriptor
|
|
);
|
|
}
|
|
|
|
/**
|
|
|
|
Retrieves the endpoint Descriptor for a given endpoint.
|
|
|
|
@param PeiServices EFI_PEI_SERVICES
|
|
@param This Indicates the calling context.
|
|
@param EndpointIndex Indicates which endpoint descriptor to retrieve.
|
|
The valid range is 0..15.
|
|
@param EndpointDescriptor A pointer to the caller allocated USB Endpoint
|
|
Descriptor of a USB controller.
|
|
|
|
@retval EFI_SUCCESS The endpoint descriptor was retrieved successfully.
|
|
@retval EFI_INVALID_PARAMETER EndpointIndex is not valid.
|
|
EndpointDescriptor is NULL.
|
|
@retval EFI_NOT_FOUND The endpoint descriptor cannot be found.
|
|
The device may not be correctly configured.
|
|
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
PeiUsbGetEndpointDescriptor (
|
|
IN EFI_PEI_SERVICES **PeiServices,
|
|
IN PEI_USB_IO_PPI *This,
|
|
IN UINT8 EndpointIndex,
|
|
OUT EFI_USB_ENDPOINT_DESCRIPTOR **EndpointDescriptor
|
|
)
|
|
{
|
|
PEI_USB_DEVICE *PeiUsbDev;
|
|
|
|
PeiUsbDev = PEI_USB_DEVICE_FROM_THIS (This);
|
|
return PeiUsbDev->Usb3IoPpi.UsbGetEndpointDescriptor (
|
|
PeiServices,
|
|
&PeiUsbDev->Usb3IoPpi,
|
|
EndpointIndex,
|
|
EndpointDescriptor
|
|
);
|
|
}
|
|
|
|
/**
|
|
|
|
Pei Usb PortReset
|
|
|
|
@param PeiServices EFI_PEI_SERVICES
|
|
@param This PEI_USB3_IO_PPI
|
|
|
|
@retval EFI_SUCCESS Success
|
|
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
PeiUsbPortReset (
|
|
IN EFI_PEI_SERVICES **PeiServices,
|
|
IN PEI_USB_IO_PPI *This
|
|
)
|
|
{
|
|
PEI_USB_DEVICE *PeiUsbDev;
|
|
|
|
PeiUsbDev = PEI_USB_DEVICE_FROM_THIS (This);
|
|
return PeiUsbDev->Usb3IoPpi.UsbPortReset (
|
|
PeiServices,
|
|
&PeiUsbDev->Usb3IoPpi
|
|
);
|
|
}
|
|
|
|
/**
|
|
|
|
Pei Usb Control Transfer
|
|
|
|
@param PeiServices EFI_PEI_SERVICES
|
|
@param This PEI_USB3_IO_PPI
|
|
@param Request Request packet
|
|
@param Direction IN/OUT/NODATA
|
|
@param Timeout Time out value in millisecond
|
|
@param Data Data buffer
|
|
@param DataLength Data length
|
|
|
|
@retval EFI_SUCCESS Success
|
|
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
PeiUsb3ControlTransfer (
|
|
IN EFI_PEI_SERVICES **PeiServices,
|
|
IN PEI_USB3_IO_PPI *This,
|
|
IN EFI_USB_DEVICE_REQUEST *Request,
|
|
IN EFI_USB_DATA_DIRECTION Direction,
|
|
IN UINT32 Timeout,
|
|
IN OUT VOID *Data, OPTIONAL
|
|
IN UINTN DataLength OPTIONAL
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
PEI_USB_DEVICE *PeiUsbDev;
|
|
PEI_USB3_HOST_CONTROLLER_PPI *UsbHcPpi;
|
|
UINT32 TransferResult;
|
|
|
|
PeiUsbDev = PEI_USB3_DEVICE_FROM_THIS (This);
|
|
UsbHcPpi = PeiUsbDev->UsbHcPpi;
|
|
Status = UsbHcPpi->ControlTransfer (
|
|
PeiServices,
|
|
UsbHcPpi,
|
|
PeiUsbDev->DeviceAddress,
|
|
PeiUsbDev->DeviceSpeed,
|
|
(PeiUsbDev->MaxPacketSize0 == 9) ? 0x200 : PeiUsbDev->MaxPacketSize0,
|
|
Request,
|
|
Direction,
|
|
Data,
|
|
&DataLength,
|
|
Timeout,
|
|
&PeiUsbDev->Translator,
|
|
&TransferResult
|
|
);
|
|
return Status;
|
|
}
|
|
|
|
/**
|
|
|
|
Pei Usb Bulk Transfer
|
|
|
|
@param PeiServices EFI_PEI_SERVICES
|
|
@param This PEI_USB3_IO_PPI
|
|
@param DeviceEndpoint Device Endpoint
|
|
@param Data Data buffer
|
|
@param DataLength Data length
|
|
@param Timeout Time out value in millisecond
|
|
|
|
@retval EFI_SUCCESS Success
|
|
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
PeiUsb3BulkTransfer (
|
|
IN EFI_PEI_SERVICES **PeiServices,
|
|
IN PEI_USB3_IO_PPI *This,
|
|
IN UINT8 DeviceEndpoint,
|
|
IN OUT VOID *Data,
|
|
IN OUT UINTN *DataLength,
|
|
IN UINTN Timeout
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
PEI_USB_DEVICE *PeiUsbDev;
|
|
PEI_USB3_HOST_CONTROLLER_PPI *UsbHcPpi;
|
|
UINT32 TransferResult;
|
|
UINTN MaxPacketLength;
|
|
UINT8 DataToggle;
|
|
UINT8 OldToggle;
|
|
EFI_USB_ENDPOINT_DESCRIPTOR *EndpointDescriptor;
|
|
UINT8 EndpointIndex;
|
|
|
|
PeiUsbDev = PEI_USB3_DEVICE_FROM_THIS (This);
|
|
UsbHcPpi = PeiUsbDev->UsbHcPpi;
|
|
|
|
EndpointDescriptor = NULL;
|
|
EndpointIndex = 0;
|
|
while (EndpointIndex < MAX_ENDPOINT) {
|
|
Status = PeiUsb3GetEndpointDescriptor (PeiServices, This, EndpointIndex, &EndpointDescriptor);
|
|
if (EFI_ERROR (Status)) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
if (EndpointDescriptor->EndpointAddress == DeviceEndpoint) {
|
|
break;
|
|
}
|
|
EndpointIndex++;
|
|
}
|
|
if (EndpointIndex == MAX_ENDPOINT) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
MaxPacketLength = PeiUsbDev->EndpointDesc[EndpointIndex]->MaxPacketSize;
|
|
if ((PeiUsbDev->DataToggle & (1 << EndpointIndex)) != 0) {
|
|
DataToggle = 1;
|
|
} else {
|
|
DataToggle = 0;
|
|
}
|
|
OldToggle = DataToggle;
|
|
Status = UsbHcPpi->BulkTransfer (
|
|
PeiServices,
|
|
UsbHcPpi,
|
|
PeiUsbDev->DeviceAddress,
|
|
DeviceEndpoint,
|
|
PeiUsbDev->DeviceSpeed,
|
|
MaxPacketLength,
|
|
&Data,
|
|
DataLength,
|
|
&DataToggle,
|
|
Timeout,
|
|
&PeiUsbDev->Translator,
|
|
&TransferResult
|
|
);
|
|
if (OldToggle != DataToggle) {
|
|
PeiUsbDev->DataToggle = (UINT8) (PeiUsbDev->DataToggle ^ (1 << EndpointIndex));
|
|
}
|
|
return Status;
|
|
}
|
|
|
|
/**
|
|
|
|
Pei Usb Sync Interrupt Transfer
|
|
|
|
@param PeiServices EFI_PEI_SERVICES
|
|
@param This PEI_USB3_IO_PPI
|
|
@param DeviceEndpoint Device Endpoint
|
|
@param Data Data buffer
|
|
@param DataLength Data length
|
|
@param Timeout Time out value in millisecond
|
|
|
|
@retval EFI_SUCCESS Success
|
|
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
PeiUsb3SyncInterruptTransfer (
|
|
IN EFI_PEI_SERVICES **PeiServices,
|
|
IN PEI_USB3_IO_PPI *This,
|
|
IN UINT8 DeviceEndpoint,
|
|
IN OUT VOID *Data,
|
|
IN OUT UINTN *DataLength,
|
|
IN UINTN Timeout
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
PEI_USB_DEVICE *PeiUsbDev;
|
|
PEI_USB3_HOST_CONTROLLER_PPI *UsbHcPpi;
|
|
UINT32 TransferResult;
|
|
UINTN MaxPacketLength;
|
|
UINT8 DataToggle, OldToggle;
|
|
EFI_USB_ENDPOINT_DESCRIPTOR *EndpointDescriptor;
|
|
UINT8 EndpointIndex;
|
|
|
|
PeiUsbDev = PEI_USB3_DEVICE_FROM_THIS (This);
|
|
UsbHcPpi = PeiUsbDev->UsbHcPpi;
|
|
EndpointDescriptor = NULL;
|
|
EndpointIndex = 0;
|
|
while (EndpointIndex < MAX_ENDPOINT) {
|
|
Status = PeiUsb3GetEndpointDescriptor (PeiServices, This, EndpointIndex, &EndpointDescriptor);
|
|
if ( EFI_ERROR(Status)) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
if (EndpointDescriptor->EndpointAddress == DeviceEndpoint) {
|
|
break;
|
|
}
|
|
EndpointIndex++;
|
|
}
|
|
if (EndpointIndex == MAX_ENDPOINT) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
MaxPacketLength = PeiUsbDev->EndpointDesc[EndpointIndex]->MaxPacketSize;
|
|
if ((PeiUsbDev->DataToggle & (1 << EndpointIndex)) != 0) {
|
|
DataToggle = 1;
|
|
} else {
|
|
DataToggle = 0;
|
|
}
|
|
OldToggle = DataToggle;
|
|
Status = UsbHcPpi->InterruptTransfer (
|
|
PeiServices,
|
|
UsbHcPpi,
|
|
PeiUsbDev->DeviceAddress,
|
|
DeviceEndpoint,
|
|
PeiUsbDev->DeviceSpeed,
|
|
MaxPacketLength,
|
|
Data,
|
|
DataLength,
|
|
&DataToggle,
|
|
Timeout,
|
|
&PeiUsbDev->Translator,
|
|
NULL,
|
|
NULL,
|
|
0,
|
|
&TransferResult
|
|
);
|
|
|
|
if (OldToggle != DataToggle) {
|
|
PeiUsbDev->DataToggle = (UINT8)(PeiUsbDev->DataToggle ^ (1 << EndpointIndex));
|
|
}
|
|
return Status;
|
|
}
|
|
|
|
/**
|
|
|
|
Pei Usb Async Interrupt Transfer
|
|
|
|
@param PeiServices EFI_PEI_SERVICES
|
|
@param This PEI_USB3_IO_PPI
|
|
@param DeviceEndpoint Device Endpoint
|
|
@param Data Data buffer
|
|
@param DataLength Data length
|
|
@param InterruptCallBack The Callback function. This function is called if
|
|
the asynchronous interrupt transfer is completed.
|
|
@param Context Passed to InterruptCallback
|
|
|
|
@retval EFI_SUCCESS Success
|
|
@retval EFI_INVALID_PARAMETER
|
|
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
PeiUsb3AsyncInterruptTransfer (
|
|
IN EFI_PEI_SERVICES **PeiServices,
|
|
IN PEI_USB3_IO_PPI *This,
|
|
IN UINT8 DeviceEndpoint,
|
|
IN OUT VOID *Data,
|
|
IN OUT UINTN *DataLength,
|
|
IN EFI_ASYNC_USB_TRANSFER_CALLBACK InterruptCallBack ,
|
|
IN VOID *Context,
|
|
IN UINTN PollingInterval
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
PEI_USB_DEVICE *PeiUsbDev;
|
|
PEI_USB3_HOST_CONTROLLER_PPI *UsbHcPpi;
|
|
UINTN MaxPacketLength;
|
|
UINT8 DataToggle;
|
|
EFI_USB_ENDPOINT_DESCRIPTOR *EndpointDescriptor;
|
|
UINT8 EndpointIndex;
|
|
UINT32 TransferResult;
|
|
|
|
PeiUsbDev = PEI_USB3_DEVICE_FROM_THIS (This);
|
|
UsbHcPpi = PeiUsbDev->UsbHcPpi;
|
|
EndpointDescriptor = NULL;
|
|
EndpointIndex = 0;
|
|
|
|
while (EndpointIndex < MAX_ENDPOINT) {
|
|
Status = PeiUsb3GetEndpointDescriptor (PeiServices, This, EndpointIndex, &EndpointDescriptor);
|
|
if ( EFI_ERROR(Status)) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
if (EndpointDescriptor->EndpointAddress == DeviceEndpoint) {
|
|
break;
|
|
}
|
|
EndpointIndex++;
|
|
}
|
|
|
|
if (EndpointIndex == MAX_ENDPOINT) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
MaxPacketLength = PeiUsbDev->EndpointDesc[EndpointIndex]->MaxPacketSize;
|
|
DataToggle = (UINT8)PeiUsbDev->DataToggle;
|
|
|
|
Status = UsbHcPpi->InterruptTransfer (
|
|
PeiServices,
|
|
UsbHcPpi,
|
|
PeiUsbDev->DeviceAddress,
|
|
DeviceEndpoint,
|
|
PeiUsbDev->DeviceSpeed,
|
|
MaxPacketLength,
|
|
NULL,
|
|
DataLength,
|
|
&DataToggle,
|
|
0,
|
|
&PeiUsbDev->Translator,
|
|
InterruptCallBack,
|
|
Context,
|
|
PollingInterval,
|
|
&TransferResult
|
|
);
|
|
|
|
return Status;
|
|
}
|
|
|
|
|
|
/**
|
|
|
|
Retrieves the interface Descriptor for that controller.
|
|
|
|
@param PeiServices EFI_PEI_SERVICES
|
|
@param This Indicates the calling context.
|
|
@param InterfaceDescriptor A pointer to the caller allocated USB interface
|
|
Descriptor.
|
|
|
|
@retval EFI_SUCCESS
|
|
@retval EFI_INVALID_PARAMETER
|
|
@retval EFI_NOT_FOUND
|
|
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
PeiUsb3GetInterfaceDescriptor (
|
|
IN EFI_PEI_SERVICES **PeiServices,
|
|
IN PEI_USB3_IO_PPI *This,
|
|
OUT EFI_USB_INTERFACE_DESCRIPTOR **InterfaceDescriptor
|
|
)
|
|
{
|
|
PEI_USB_DEVICE *PeiUsbDev;
|
|
PeiUsbDev = PEI_USB3_DEVICE_FROM_THIS (This);
|
|
*InterfaceDescriptor = PeiUsbDev->InterfaceDesc;
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
|
|
Retrieves the endpoint Descriptor for a given endpoint.
|
|
|
|
@param PeiServices EFI_PEI_SERVICES
|
|
@param This Indicates the calling context.
|
|
@param EndpointIndex Indicates which endpoint descriptor to retrieve.
|
|
The valid range is 0..15.
|
|
@param EndpointDescriptor A pointer to the caller allocated USB Endpoint
|
|
Descriptor of a USB controller.
|
|
|
|
@retval EFI_SUCCESS The endpoint descriptor was retrieved successfully.
|
|
@retval EFI_INVALID_PARAMETER EndpointIndex is not valid.
|
|
EndpointDescriptor is NULL.
|
|
@retval EFI_NOT_FOUND The endpoint descriptor cannot be found.
|
|
The device may not be correctly configured.
|
|
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
PeiUsb3GetEndpointDescriptor (
|
|
IN EFI_PEI_SERVICES **PeiServices,
|
|
IN PEI_USB3_IO_PPI *This,
|
|
IN UINT8 EndpointIndex,
|
|
OUT EFI_USB_ENDPOINT_DESCRIPTOR **EndpointDescriptor
|
|
)
|
|
{
|
|
PEI_USB_DEVICE *PeiUsbDev;
|
|
PeiUsbDev = PEI_USB3_DEVICE_FROM_THIS (This);
|
|
if (EndpointIndex >= PeiUsbDev->InterfaceDesc->NumEndpoints) {
|
|
return EFI_NOT_FOUND;
|
|
}
|
|
*EndpointDescriptor = PeiUsbDev->EndpointDesc[EndpointIndex];
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
|
|
Pei Usb PortReset
|
|
|
|
@param PeiServices EFI_PEI_SERVICES
|
|
@param This PEI_USB3_IO_PPI
|
|
|
|
@retval EFI_SUCCESS Success
|
|
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
PeiUsb3PortReset (
|
|
IN EFI_PEI_SERVICES **PeiServices,
|
|
IN PEI_USB3_IO_PPI *This
|
|
)
|
|
{
|
|
PEI_USB_DEVICE *PeiUsbDev;
|
|
EFI_STATUS Status;
|
|
UINT8 Address;
|
|
|
|
PeiUsbDev = PEI_USB3_DEVICE_FROM_THIS (This);
|
|
ResetRootPort (
|
|
PeiUsbDev,
|
|
PeiUsbDev->DeviceAddress
|
|
);
|
|
//
|
|
// Set address
|
|
//
|
|
Address = PeiUsbDev->DeviceAddress;
|
|
PeiUsbDev->DeviceAddress = 0;
|
|
Status = PeiUsbSetDeviceAddress (
|
|
PeiServices,
|
|
This,
|
|
Address
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
PeiUsbDev->DeviceAddress = Address;
|
|
//
|
|
// Set default configuration
|
|
//
|
|
Status = PeiUsbSetConfiguration (
|
|
PeiServices,
|
|
This
|
|
);
|
|
return Status;
|
|
}
|
|
|
|
/**
|
|
|
|
Clear Endpoint Halt
|
|
|
|
@param PeiServices EFI_PEI_SERVICES
|
|
@param This PEI_USB3_IO_PPI
|
|
@param EndpointAddress Endpoint Address
|
|
|
|
@retval EFI_SUCCESS Success
|
|
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
PeiUsb3ClearEndpointHalt (
|
|
IN EFI_PEI_SERVICES **PeiServices,
|
|
IN PEI_USB3_IO_PPI *This,
|
|
IN UINT8 EndpointAddress
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
PEI_USB_DEVICE *PeiUsbDev;
|
|
EFI_USB_ENDPOINT_DESCRIPTOR *EndpointDescriptor;
|
|
UINT8 EndpointIndex;
|
|
|
|
EndpointDescriptor = NULL;
|
|
EndpointIndex = 0;
|
|
PeiUsbDev = PEI_USB3_DEVICE_FROM_THIS (This);
|
|
|
|
while (EndpointIndex < MAX_ENDPOINT) {
|
|
Status = PeiUsb3GetEndpointDescriptor (PeiServices, This, EndpointIndex, &EndpointDescriptor);
|
|
if (EFI_ERROR (Status)) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
if (EndpointDescriptor->EndpointAddress == EndpointAddress) {
|
|
break;
|
|
}
|
|
|
|
EndpointIndex++;
|
|
}
|
|
|
|
if (EndpointIndex == MAX_ENDPOINT) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
Status = PeiUsbClearDeviceFeature (
|
|
PeiServices,
|
|
This,
|
|
USB_TARGET_ENDPOINT,
|
|
USB_FEATURE_ENDPOINT_HALT,
|
|
EndpointAddress
|
|
);
|
|
|
|
//
|
|
// set data toggle to zero.
|
|
//
|
|
if ((PeiUsbDev->DataToggle & (1 << EndpointIndex)) != 0) {
|
|
PeiUsbDev->DataToggle = (UINT8) (PeiUsbDev->DataToggle ^ (1 << EndpointIndex));
|
|
}
|
|
|
|
return Status;
|
|
}
|