audk/EdkModulePkg/Bus/Usb/UsbBus/Dxe/usbutil.c

557 lines
11 KiB
C

/*++
Copyright (c) 2006, Intel Corporation
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
Module Name:
usbutil.c
Abstract:
Helper functions for USB
Revision History
--*/
#include "usbbus.h"
//
// Following APIs are used to query Port Status
//
BOOLEAN
IsPortConnect (
IN UINT16 PortStatus
)
/*++
Routine Description:
Tell if there is a device connected to that port according to
the Port Status.
Parameters:
PortStatus - The status value of that port.
Return Value:
TRUE
FALSE
--*/
{
//
// return the bit 0 value of PortStatus
//
if ((PortStatus & USB_PORT_STAT_CONNECTION) != 0) {
return TRUE;
} else {
return FALSE;
}
}
BOOLEAN
IsPortEnable (
IN UINT16 PortStatus
)
/*++
Routine Description:
Tell if Port is enabled.
Arguments:
PortStatus - The status value of that port.
Returns:
TRUE - Port is enable
FALSE - Port is disable
--*/
{
//
// return the bit 1 value of PortStatus
//
if ((PortStatus & USB_PORT_STAT_ENABLE) != 0) {
return TRUE;
} else {
return FALSE;
}
}
BOOLEAN
IsPortInReset (
IN UINT16 PortStatus
)
/*++
Routine Description:
Tell if the port is being reset.
Arguments:
PortStatus - The status value of that port.
Returns:
TRUE
FALSE
--*/
{
//
// return the bit 4 value of PortStatus
//
if ((PortStatus & USB_PORT_STAT_RESET) != 0) {
return TRUE;
} else {
return FALSE;
}
}
BOOLEAN
IsPortPowerApplied (
IN UINT16 PortStatus
)
/*++
Routine Description:
Tell if there is power applied to that port.
Arguments:
PortStatus - The status value of that port.
Returns:
TRUE
FALSE
--*/
{
//
// return the bit 8 value of PortStatus
//
if ((PortStatus & USB_PORT_STAT_POWER) != 0) {
return TRUE;
} else {
return FALSE;
}
}
BOOLEAN
IsPortLowSpeedDeviceAttached (
IN UINT16 PortStatus
)
/*++
Routine Description:
Tell if the connected device is a low device.
Arguments:
PortStatus - The status value of that port.
Returns:
TRUE
FALSE
--*/
{
//
// return the bit 9 value of PortStatus
//
if ((PortStatus & USB_PORT_STAT_LOW_SPEED) != 0) {
return TRUE;
} else {
return FALSE;
}
}
BOOLEAN
IsPortSuspend (
IN UINT16 PortStatus
)
/*++
Routine Description:
Tell if the port is suspend.
Arguments:
PortStatus - The status value of that port.
Returns:
TRUE
FALSE
--*/
{
//
// return the bit 2 value of PortStatus
//
if ((PortStatus & USB_PORT_STAT_SUSPEND) != 0) {
return TRUE;
} else {
return FALSE;
}
}
//
// Following APIs are used to query Port Change Status
//
BOOLEAN
IsPortConnectChange (
IN UINT16 PortChangeStatus
)
/*++
Routine Description:
Tell if there is a Connect Change status in that port.
Arguments:
PortChangeStatus - The status value of that port.
Returns:
TRUE
FALSE
--*/
{
//
// return the bit 0 value of PortChangeStatus
//
if ((PortChangeStatus & USB_PORT_STAT_C_CONNECTION) != 0) {
return TRUE;
} else {
return FALSE;
}
}
BOOLEAN
IsPortEnableDisableChange (
IN UINT16 PortChangeStatus
)
/*++
Routine Description:
Tell if there is a Enable/Disable change in that port.
Arguments:
PortChangeStatus - The status value of that port.
Returns:
TRUE
FALSE
--*/
{
//
// return the bit 1 value of PortChangeStatus
//
if ((PortChangeStatus & USB_PORT_STAT_C_ENABLE) != 0) {
return TRUE;
} else {
return FALSE;
}
}
BOOLEAN
IsPortResetChange (
IN UINT16 PortChangeStatus
)
/*++
Routine Description:
Tell if there is a Port Reset Change status in that port.
Arguments:
PortChangeStatus - The status value of that port.
Returns:
TRUE
FALSE
--*/
{
//
// return the bit 4 value of PortChangeStatus
//
if ((PortChangeStatus & USB_PORT_STAT_C_RESET) != 0) {
return TRUE;
} else {
return FALSE;
}
}
BOOLEAN
IsPortSuspendChange (
IN UINT16 PortChangeStatus
)
/*++
Routine Description:
Tell if there is a Suspend Change Status in that port.
Arguments:
PortChangeStatus - The status value of that port.
Returns:
TRUE
FALSE
--*/
{
//
// return the bit 2 value of PortChangeStatus
//
if ((PortChangeStatus & USB_PORT_STAT_C_SUSPEND) != 0) {
return TRUE;
} else {
return FALSE;
}
}
INTERFACE_DESC_LIST_ENTRY*
FindInterfaceListEntry (
IN EFI_USB_IO_PROTOCOL *This
)
/*++
Routine Description:
Find Interface ListEntry.
Arguments:
This - EFI_USB_IO_PROTOCOL
Returns:
INTERFACE_DESC_LIST_ENTRY pointer
--*/
{
USB_IO_CONTROLLER_DEVICE *UsbIoController;
USB_IO_DEVICE *UsbIoDev;
LIST_ENTRY *InterfaceListHead;
INTERFACE_DESC_LIST_ENTRY *InterfaceListEntry;
UsbIoController = USB_IO_CONTROLLER_DEVICE_FROM_USB_IO_THIS (This);
UsbIoDev = UsbIoController->UsbDevice;
if (!UsbIoDev->IsConfigured) {
return NULL;
}
InterfaceListHead = &UsbIoDev->ActiveConfig->InterfaceDescListHead;
InterfaceListEntry = (INTERFACE_DESC_LIST_ENTRY *) (InterfaceListHead->ForwardLink);
//
// Loop all interface descriptor to get match one.
//
while (InterfaceListEntry != (INTERFACE_DESC_LIST_ENTRY *) InterfaceListHead) {
if (InterfaceListEntry->InterfaceDescriptor.InterfaceNumber == UsbIoController->InterfaceNumber) {
return InterfaceListEntry;
}
InterfaceListEntry = (INTERFACE_DESC_LIST_ENTRY *) InterfaceListEntry->Link.ForwardLink;
}
return NULL;
}
ENDPOINT_DESC_LIST_ENTRY*
FindEndPointListEntry (
IN EFI_USB_IO_PROTOCOL *This,
IN UINT8 EndPointAddress
)
/*++
Routine Description:
Find EndPoint ListEntry.
Arguments:
This - EFI_USB_IO_PROTOCOL
EndpointAddr - Endpoint address.
Returns:
ENDPOINT_DESC_LIST_ENTRY pointer
--*/
{
INTERFACE_DESC_LIST_ENTRY *InterfaceListEntry;
LIST_ENTRY *EndpointDescListHead;
ENDPOINT_DESC_LIST_ENTRY *EndPointListEntry;
InterfaceListEntry = FindInterfaceListEntry (This);
if (InterfaceListEntry != NULL) {
EndpointDescListHead = &InterfaceListEntry->EndpointDescListHead;
EndPointListEntry = (ENDPOINT_DESC_LIST_ENTRY *) (EndpointDescListHead->ForwardLink);
//
// Loop all interface descriptor to get match one.
//
while (EndPointListEntry != (ENDPOINT_DESC_LIST_ENTRY *) EndpointDescListHead) {
if (EndPointListEntry->EndpointDescriptor.EndpointAddress == EndPointAddress) {
return EndPointListEntry;
}
EndPointListEntry = (ENDPOINT_DESC_LIST_ENTRY *) EndPointListEntry->Link.ForwardLink;
}
}
return NULL;
}
VOID
GetDataToggleBit (
IN EFI_USB_IO_PROTOCOL *UsbIo,
IN UINT8 EndpointAddr,
OUT UINT8 *DataToggle
)
/*++
Routine Description:
Get the datatoggle of a specified endpoint.
Arguments:
UsbIo - Given Usb Controller device.
EndpointAddr - Given Endpoint address.
DataToggle - The current data toggle of that endpoint
Returns:
N/A
--*/
{
ENDPOINT_DESC_LIST_ENTRY *EndpointListEntry;
*DataToggle = 0;
EndpointListEntry = FindEndPointListEntry (UsbIo, EndpointAddr);
if (EndpointListEntry == NULL) {
return ;
}
*DataToggle = (UINT8) (EndpointListEntry->Toggle);
return ;
}
VOID
SetDataToggleBit (
IN EFI_USB_IO_PROTOCOL *UsbIo,
IN UINT8 EndpointAddr,
IN UINT8 DataToggle
)
/*++
Routine Description:
Set the datatoggle of a specified endpoint
Arguments:
UsbIo - Given Usb Controller device.
EndpointAddr - Given Endpoint address.
DataToggle - The current data toggle of that endpoint to be set
Returns:
N/A
--*/
{
ENDPOINT_DESC_LIST_ENTRY *EndpointListEntry;
EndpointListEntry = FindEndPointListEntry (UsbIo, EndpointAddr);
if (EndpointListEntry == NULL) {
return ;
}
EndpointListEntry->Toggle = DataToggle;
return ;
}
VOID
GetDeviceEndPointMaxPacketLength (
IN EFI_USB_IO_PROTOCOL *UsbIo,
IN UINT8 EndpointAddr,
OUT UINT8 *MaxPacketLength
)
/*++
Routine Description:
Get the Max Packet Length of the speified Endpoint.
Arguments:
UsbIo - Given Usb Controller device.
EndpointAddr - Given Endpoint address.
MaxPacketLength - The max packet length of that endpoint
Returns:
N/A
--*/
{
ENDPOINT_DESC_LIST_ENTRY *EndpointListEntry;
*MaxPacketLength = 0;
EndpointListEntry = FindEndPointListEntry (UsbIo, EndpointAddr);
if (EndpointListEntry == NULL) {
return ;
}
*MaxPacketLength = (UINT8) (EndpointListEntry->EndpointDescriptor.MaxPacketSize);
return ;
}
EFI_STATUS
UsbSetDeviceAddress (
IN EFI_USB_IO_PROTOCOL *UsbIo,
IN UINT16 AddressValue,
OUT UINT32 *Status
)
/*++
Routine Description:
Usb Set Device Address
Arguments:
UsbIo - EFI_USB_IO_PROTOCOL
AddressValue - Device address
Status - Transfer status
Returns:
EFI_INVALID_PARAMETER - Parameter is error
EFI_SUCCESS - Success
EFI_TIMEOUT - Device has no response
--*/
{
EFI_USB_DEVICE_REQUEST DevReq;
if (UsbIo == NULL) {
return EFI_INVALID_PARAMETER;
}
ZeroMem (&DevReq, sizeof (EFI_USB_DEVICE_REQUEST));
DevReq.RequestType = USB_DEV_SET_ADDRESS_REQ_TYPE;
DevReq.Request = USB_DEV_SET_ADDRESS;
DevReq.Value = AddressValue;
return UsbIo->UsbControlTransfer (
UsbIo,
&DevReq,
EfiUsbNoData,
TIMEOUT_VALUE,
NULL,
0,
Status
);
}