git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@1037 6f19259b-4bc3-4df7-8a09-765794883524
		
			
				
	
	
		
			555 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			555 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.
 | |
| 
 | |
|   Arguments:
 | |
|     PortStatus  -   The status value of that port.
 | |
| 
 | |
|   Returns:
 | |
|     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   
 | |
|     EndPointAddress -  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 UINTN                  *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 = (UINTN) (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
 | |
|                   );
 | |
| }
 | |
| 
 |