mirror of https://github.com/acidanthera/audk.git
332 lines
9.3 KiB
C
332 lines
9.3 KiB
C
/** @file
|
|
Common Libarary for PEI USB.
|
|
|
|
Copyright (c) 2006, Intel Corporation. All rights reserved.<BR>
|
|
|
|
This program and the accompanying materials
|
|
are licensed and made available under the terms and conditions
|
|
of the BSD License which accompanies this distribution. The
|
|
full text of the license may be found at
|
|
http://opensource.org/licenses/bsd-license.php
|
|
|
|
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
|
|
|
**/
|
|
|
|
#include "UsbPeim.h"
|
|
#include "PeiUsbLib.h"
|
|
|
|
/**
|
|
Get a given usb descriptor.
|
|
|
|
@param PeiServices General-purpose services that are available to every PEIM.
|
|
@param UsbIoPpi Indicates the PEI_USB_IO_PPI instance.
|
|
@param Value Request Value.
|
|
@param Index Request Index.
|
|
@param DescriptorLength Request descriptor Length.
|
|
@param Descriptor Request descriptor.
|
|
|
|
|
|
@retval EFI_SUCCESS Usb descriptor is obtained successfully.
|
|
@retval EFI_DEVICE_ERROR Cannot get the usb descriptor due to a hardware error.
|
|
@retval Others Other failure occurs.
|
|
|
|
**/
|
|
EFI_STATUS
|
|
PeiUsbGetDescriptor (
|
|
IN EFI_PEI_SERVICES **PeiServices,
|
|
IN PEI_USB_IO_PPI *UsbIoPpi,
|
|
IN UINT16 Value,
|
|
IN UINT16 Index,
|
|
IN UINT16 DescriptorLength,
|
|
OUT VOID *Descriptor
|
|
)
|
|
{
|
|
EFI_USB_DEVICE_REQUEST DevReq;
|
|
|
|
ASSERT (UsbIoPpi != NULL);
|
|
|
|
DevReq.RequestType = USB_DEV_GET_DESCRIPTOR_REQ_TYPE;
|
|
DevReq.Request = USB_DEV_GET_DESCRIPTOR;
|
|
DevReq.Value = Value;
|
|
DevReq.Index = Index;
|
|
DevReq.Length = DescriptorLength;
|
|
|
|
return UsbIoPpi->UsbControlTransfer (
|
|
PeiServices,
|
|
UsbIoPpi,
|
|
&DevReq,
|
|
EfiUsbDataIn,
|
|
PcdGet32 (PcdUsbTransferTimeoutValue),
|
|
Descriptor,
|
|
DescriptorLength
|
|
);
|
|
}
|
|
|
|
/**
|
|
Set a usb device with a specified address.
|
|
|
|
@param PeiServices General-purpose services that are available to every PEIM.
|
|
@param UsbIoPpi Indicates the PEI_USB_IO_PPI instance.
|
|
@param AddressValue The address to assign.
|
|
|
|
@retval EFI_SUCCESS Usb device address is set successfully.
|
|
@retval EFI_DEVICE_ERROR Cannot set the usb address due to a hardware error.
|
|
@retval Others Other failure occurs.
|
|
|
|
**/
|
|
EFI_STATUS
|
|
PeiUsbSetDeviceAddress (
|
|
IN EFI_PEI_SERVICES **PeiServices,
|
|
IN PEI_USB_IO_PPI *UsbIoPpi,
|
|
IN UINT16 AddressValue
|
|
)
|
|
{
|
|
EFI_USB_DEVICE_REQUEST DevReq;
|
|
|
|
ASSERT (UsbIoPpi != NULL);
|
|
|
|
DevReq.RequestType = USB_DEV_SET_ADDRESS_REQ_TYPE;
|
|
DevReq.Request = USB_DEV_SET_ADDRESS;
|
|
DevReq.Value = AddressValue;
|
|
DevReq.Index = 0;
|
|
DevReq.Length = 0;
|
|
|
|
return UsbIoPpi->UsbControlTransfer (
|
|
PeiServices,
|
|
UsbIoPpi,
|
|
&DevReq,
|
|
EfiUsbNoData,
|
|
PcdGet32 (PcdUsbTransferTimeoutValue),
|
|
NULL,
|
|
0
|
|
);
|
|
}
|
|
|
|
/**
|
|
Clear a given usb feature.
|
|
|
|
@param PeiServices General-purpose services that are available to every PEIM.
|
|
@param UsbIoPpi Indicates the PEI_USB_IO_PPI instance.
|
|
@param Recipient The recipient of ClearFeature Request, should be one of Device/Interface/Endpoint.
|
|
@param Value Request Value.
|
|
@param Target Request Index.
|
|
|
|
@retval EFI_SUCCESS Usb feature is cleared successfully.
|
|
@retval EFI_DEVICE_ERROR Cannot clear the usb feature due to a hardware error.
|
|
@retval Others Other failure occurs.
|
|
|
|
**/
|
|
EFI_STATUS
|
|
PeiUsbClearDeviceFeature (
|
|
IN EFI_PEI_SERVICES **PeiServices,
|
|
IN PEI_USB_IO_PPI *UsbIoPpi,
|
|
IN EFI_USB_RECIPIENT Recipient,
|
|
IN UINT16 Value,
|
|
IN UINT16 Target
|
|
)
|
|
{
|
|
EFI_USB_DEVICE_REQUEST DevReq;
|
|
|
|
ASSERT (UsbIoPpi != NULL);
|
|
|
|
switch (Recipient) {
|
|
case EfiUsbDevice:
|
|
DevReq.RequestType = USB_DEV_CLEAR_FEATURE_REQ_TYPE_D;
|
|
break;
|
|
|
|
case EfiUsbInterface:
|
|
DevReq.RequestType = USB_DEV_CLEAR_FEATURE_REQ_TYPE_I;
|
|
break;
|
|
|
|
case EfiUsbEndpoint:
|
|
DevReq.RequestType = USB_DEV_CLEAR_FEATURE_REQ_TYPE_E;
|
|
break;
|
|
}
|
|
|
|
DevReq.Request = USB_DEV_CLEAR_FEATURE;
|
|
DevReq.Value = Value;
|
|
DevReq.Index = Target;
|
|
DevReq.Length = 0;
|
|
|
|
return UsbIoPpi->UsbControlTransfer (
|
|
PeiServices,
|
|
UsbIoPpi,
|
|
&DevReq,
|
|
EfiUsbNoData,
|
|
PcdGet32 (PcdUsbTransferTimeoutValue),
|
|
NULL,
|
|
0
|
|
);
|
|
}
|
|
|
|
/**
|
|
Configure a usb device to Configuration 1.
|
|
|
|
@param PeiServices General-purpose services that are available to every PEIM.
|
|
@param UsbIoPpi Indicates the PEI_USB_IO_PPI instance.
|
|
|
|
@retval EFI_SUCCESS Usb device is set to use Configuration 1 successfully.
|
|
@retval EFI_DEVICE_ERROR Cannot set the usb device due to a hardware error.
|
|
@retval Others Other failure occurs.
|
|
|
|
**/
|
|
EFI_STATUS
|
|
PeiUsbSetConfiguration (
|
|
IN EFI_PEI_SERVICES **PeiServices,
|
|
IN PEI_USB_IO_PPI *UsbIoPpi
|
|
)
|
|
{
|
|
EFI_USB_DEVICE_REQUEST DevReq;
|
|
ZeroMem (&DevReq, sizeof (EFI_USB_DEVICE_REQUEST));
|
|
|
|
DevReq.RequestType = USB_DEV_SET_CONFIGURATION_REQ_TYPE;
|
|
DevReq.Request = USB_DEV_SET_CONFIGURATION;
|
|
DevReq.Value = 1;
|
|
|
|
return UsbIoPpi->UsbControlTransfer (
|
|
PeiServices,
|
|
UsbIoPpi,
|
|
&DevReq,
|
|
EfiUsbNoData,
|
|
PcdGet32 (PcdUsbTransferTimeoutValue),
|
|
NULL,
|
|
0
|
|
);
|
|
}
|
|
|
|
/**
|
|
Clear Endpoint Halt.
|
|
|
|
@param PeiServices General-purpose services that are available to every PEIM.
|
|
@param UsbIoPpi Indicates the PEI_USB_IO_PPI instance.
|
|
@param EndpointAddress The endpoint address.
|
|
|
|
@retval EFI_SUCCESS Endpoint halt is cleared successfully.
|
|
@retval EFI_DEVICE_ERROR Cannot clear the endpoint halt status due to a hardware error.
|
|
@retval Others Other failure occurs.
|
|
|
|
**/
|
|
EFI_STATUS
|
|
PeiUsbClearEndpointHalt (
|
|
IN EFI_PEI_SERVICES **PeiServices,
|
|
IN PEI_USB_IO_PPI *UsbIoPpi,
|
|
IN UINT8 EndpointAddress
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
PEI_USB_DEVICE *PeiUsbDev;
|
|
EFI_USB_ENDPOINT_DESCRIPTOR *EndpointDescriptor;
|
|
UINT8 EndpointIndex;
|
|
|
|
EndpointIndex = 0;
|
|
PeiUsbDev = PEI_USB_DEVICE_FROM_THIS (UsbIoPpi);
|
|
|
|
while (EndpointIndex < MAX_ENDPOINT) {
|
|
Status = UsbIoPpi->UsbGetEndpointDescriptor (PeiServices, UsbIoPpi, 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,
|
|
UsbIoPpi,
|
|
EfiUsbEndpoint,
|
|
EfiUsbEndpointHalt,
|
|
EndpointAddress
|
|
);
|
|
|
|
//
|
|
// set data toggle to zero.
|
|
//
|
|
if ((PeiUsbDev->DataToggle & (1 << EndpointIndex)) != 0) {
|
|
PeiUsbDev->DataToggle = (UINT8) (PeiUsbDev->DataToggle ^ (1 << EndpointIndex));
|
|
}
|
|
|
|
return Status;
|
|
}
|
|
|
|
/**
|
|
Judge if the port is connected with a usb device or not.
|
|
|
|
@param PortStatus The usb port status gotten.
|
|
|
|
@retval TRUE A usb device is connected with the port.
|
|
@retval FALSE No usb device is connected with the port.
|
|
|
|
**/
|
|
BOOLEAN
|
|
IsPortConnect (
|
|
IN UINT16 PortStatus
|
|
)
|
|
{
|
|
//
|
|
// return the bit 0 value of PortStatus
|
|
//
|
|
if ((PortStatus & USB_PORT_STAT_CONNECTION) != 0) {
|
|
return TRUE;
|
|
} else {
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
/**
|
|
Judge if the port is connected with a low-speed usb device or not.
|
|
|
|
@param PortStatus The usb port status gotten.
|
|
|
|
@retval TRUE A low-speed usb device is connected with the port.
|
|
@retval FALSE No low-speed usb device is connected with the port.
|
|
|
|
**/
|
|
BOOLEAN
|
|
IsPortLowSpeedDeviceAttached (
|
|
IN UINT16 PortStatus
|
|
)
|
|
{
|
|
//
|
|
// return the bit 9 value of PortStatus
|
|
//
|
|
if ((PortStatus & USB_PORT_STAT_LOW_SPEED) != 0) {
|
|
return TRUE;
|
|
} else {
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
/**
|
|
Judge if the port is in "connection change" status or not.
|
|
|
|
@param PortChangeStatus The usb port change status gotten.
|
|
|
|
@retval TRUE The port is in "connection change" status.
|
|
@retval FALSE The port is NOT in "connection change" status.
|
|
|
|
**/
|
|
BOOLEAN
|
|
IsPortConnectChange (
|
|
IN UINT16 PortChangeStatus
|
|
)
|
|
{
|
|
//
|
|
// return the bit 0 value of PortChangeStatus
|
|
//
|
|
if ((PortChangeStatus & USB_PORT_STAT_C_CONNECTION) != 0) {
|
|
return TRUE;
|
|
} else {
|
|
return FALSE;
|
|
}
|
|
}
|