mirror of
				https://git.proxmox.com/git/mirror_edk2
				synced 2025-11-04 03:57:26 +00:00 
			
		
		
		
	git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@3 6f19259b-4bc3-4df7-8a09-765794883524
		
			
				
	
	
		
			557 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			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
 | 
						|
                  );
 | 
						|
}
 | 
						|
 |