Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Star Zeng <star.zeng@intel.com> Reviewed-by: Feng Tian <feng.tian@intel.com> git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@15611 6f19259b-4bc3-4df7-8a09-765794883524
		
			
				
	
	
		
			671 lines
		
	
	
		
			19 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			671 lines
		
	
	
		
			19 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/** @file
 | 
						|
Usb Hub Request Support In PEI Phase
 | 
						|
 | 
						|
Copyright (c) 2006 - 2014, 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 "HubPeim.h"
 | 
						|
#include "PeiUsbLib.h"
 | 
						|
 | 
						|
/**
 | 
						|
  Get a given hub port status.
 | 
						|
 | 
						|
  @param  PeiServices   General-purpose services that are available to every PEIM.
 | 
						|
  @param  UsbIoPpi      Indicates the PEI_USB_IO_PPI instance.
 | 
						|
  @param  Port          Usb hub port number (starting from 1).
 | 
						|
  @param  PortStatus    Current Hub port status and change status.
 | 
						|
 | 
						|
  @retval EFI_SUCCESS       Port status is obtained successfully.
 | 
						|
  @retval EFI_DEVICE_ERROR  Cannot get the port status due to a hardware error.
 | 
						|
  @retval Others            Other failure occurs.
 | 
						|
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
PeiHubGetPortStatus (
 | 
						|
  IN  EFI_PEI_SERVICES    **PeiServices,
 | 
						|
  IN  PEI_USB_IO_PPI      *UsbIoPpi,
 | 
						|
  IN  UINT8               Port,
 | 
						|
  OUT UINT32              *PortStatus
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_USB_DEVICE_REQUEST  DeviceRequest;
 | 
						|
 | 
						|
  ZeroMem (&DeviceRequest, sizeof (EFI_USB_DEVICE_REQUEST));
 | 
						|
 | 
						|
  //
 | 
						|
  // Fill Device request packet
 | 
						|
  //
 | 
						|
  DeviceRequest.RequestType = USB_HUB_GET_PORT_STATUS_REQ_TYPE;
 | 
						|
  DeviceRequest.Request     = USB_HUB_GET_PORT_STATUS;
 | 
						|
  DeviceRequest.Index       = Port;
 | 
						|
  DeviceRequest.Length      = (UINT16) sizeof (UINT32);
 | 
						|
 | 
						|
 | 
						|
  return UsbIoPpi->UsbControlTransfer (
 | 
						|
                     PeiServices,
 | 
						|
                     UsbIoPpi,
 | 
						|
                     &DeviceRequest,
 | 
						|
                     EfiUsbDataIn,
 | 
						|
                     PcdGet32 (PcdUsbTransferTimeoutValue),
 | 
						|
                     PortStatus,
 | 
						|
                     sizeof (UINT32)
 | 
						|
                     );
 | 
						|
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Set specified feature to a given hub port.
 | 
						|
 | 
						|
  @param  PeiServices   General-purpose services that are available to every PEIM.
 | 
						|
  @param  UsbIoPpi      Indicates the PEI_USB_IO_PPI instance.
 | 
						|
  @param  Port          Usb hub port number (starting from 1).
 | 
						|
  @param  Value         New feature value.
 | 
						|
 | 
						|
  @retval EFI_SUCCESS       Port feature is set successfully.
 | 
						|
  @retval EFI_DEVICE_ERROR  Cannot set the port feature due to a hardware error.
 | 
						|
  @retval Others            Other failure occurs.
 | 
						|
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
PeiHubSetPortFeature (
 | 
						|
  IN EFI_PEI_SERVICES    **PeiServices,
 | 
						|
  IN PEI_USB_IO_PPI      *UsbIoPpi,
 | 
						|
  IN UINT8               Port,
 | 
						|
  IN UINT8               Value
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_USB_DEVICE_REQUEST      DeviceRequest;
 | 
						|
 | 
						|
  ZeroMem (&DeviceRequest, sizeof (EFI_USB_DEVICE_REQUEST));
 | 
						|
 | 
						|
  //
 | 
						|
  // Fill Device request packet
 | 
						|
  //
 | 
						|
  DeviceRequest.RequestType = USB_HUB_SET_PORT_FEATURE_REQ_TYPE;
 | 
						|
  DeviceRequest.Request     = USB_HUB_SET_PORT_FEATURE;
 | 
						|
  DeviceRequest.Value       = Value;
 | 
						|
  DeviceRequest.Index       = Port;
 | 
						|
 | 
						|
  return UsbIoPpi->UsbControlTransfer (
 | 
						|
                     PeiServices,
 | 
						|
                     UsbIoPpi,
 | 
						|
                     &DeviceRequest,
 | 
						|
                     EfiUsbNoData,
 | 
						|
                     PcdGet32 (PcdUsbTransferTimeoutValue),
 | 
						|
                     NULL,
 | 
						|
                     0
 | 
						|
                     );
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Clear specified feature on a given hub port.
 | 
						|
 | 
						|
  @param  PeiServices   General-purpose services that are available to every PEIM.
 | 
						|
  @param  UsbIoPpi      Indicates the PEI_USB_IO_PPI instance.
 | 
						|
  @param  Port          Usb hub port number (starting from 1).
 | 
						|
  @param  Value         Feature value that will be cleared from the hub port.
 | 
						|
 | 
						|
  @retval EFI_SUCCESS       Port feature is cleared successfully.
 | 
						|
  @retval EFI_DEVICE_ERROR  Cannot clear the port feature due to a hardware error.
 | 
						|
  @retval Others            Other failure occurs.
 | 
						|
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
PeiHubClearPortFeature (
 | 
						|
  IN EFI_PEI_SERVICES    **PeiServices,
 | 
						|
  IN PEI_USB_IO_PPI      *UsbIoPpi,
 | 
						|
  IN UINT8               Port,
 | 
						|
  IN UINT8               Value
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_USB_DEVICE_REQUEST      DeviceRequest;
 | 
						|
 | 
						|
  ZeroMem (&DeviceRequest, sizeof (EFI_USB_DEVICE_REQUEST));
 | 
						|
 | 
						|
  //
 | 
						|
  // Fill Device request packet
 | 
						|
  //
 | 
						|
  DeviceRequest.RequestType = USB_HUB_CLEAR_FEATURE_PORT_REQ_TYPE;
 | 
						|
  DeviceRequest.Request     = USB_HUB_CLEAR_FEATURE_PORT;
 | 
						|
  DeviceRequest.Value       = Value;
 | 
						|
  DeviceRequest.Index       = Port;
 | 
						|
 | 
						|
  return UsbIoPpi->UsbControlTransfer (
 | 
						|
                     PeiServices,
 | 
						|
                     UsbIoPpi,
 | 
						|
                     &DeviceRequest,
 | 
						|
                     EfiUsbNoData,
 | 
						|
                     PcdGet32 (PcdUsbTransferTimeoutValue),
 | 
						|
                     NULL,
 | 
						|
                     0
 | 
						|
                     );
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Get a given hub status.
 | 
						|
 | 
						|
  @param  PeiServices   General-purpose services that are available to every PEIM.
 | 
						|
  @param  UsbIoPpi      Indicates the PEI_USB_IO_PPI instance.
 | 
						|
  @param  HubStatus     Current Hub status and change status.
 | 
						|
 | 
						|
  @retval EFI_SUCCESS       Hub status is obtained successfully.
 | 
						|
  @retval EFI_DEVICE_ERROR  Cannot get the hub status due to a hardware error.
 | 
						|
  @retval Others            Other failure occurs.
 | 
						|
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
PeiHubGetHubStatus (
 | 
						|
  IN  EFI_PEI_SERVICES    **PeiServices,
 | 
						|
  IN  PEI_USB_IO_PPI      *UsbIoPpi,
 | 
						|
  OUT UINT32              *HubStatus
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_USB_DEVICE_REQUEST  DeviceRequest;
 | 
						|
 | 
						|
  ZeroMem (&DeviceRequest, sizeof (EFI_USB_DEVICE_REQUEST));
 | 
						|
 | 
						|
  //
 | 
						|
  // Fill Device request packet
 | 
						|
  //
 | 
						|
  DeviceRequest.RequestType = USB_HUB_GET_HUB_STATUS_REQ_TYPE;
 | 
						|
  DeviceRequest.Request     = USB_HUB_GET_HUB_STATUS;
 | 
						|
  DeviceRequest.Length      = (UINT16) sizeof (UINT32);
 | 
						|
 | 
						|
  return UsbIoPpi->UsbControlTransfer (
 | 
						|
                     PeiServices,
 | 
						|
                     UsbIoPpi,
 | 
						|
                     &DeviceRequest,
 | 
						|
                     EfiUsbDataIn,
 | 
						|
                     PcdGet32 (PcdUsbTransferTimeoutValue),
 | 
						|
                     HubStatus,
 | 
						|
                     sizeof (UINT32)
 | 
						|
                     );
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Set specified feature to a given hub.
 | 
						|
 | 
						|
  @param  PeiServices   General-purpose services that are available to every PEIM.
 | 
						|
  @param  UsbIoPpi      Indicates the PEI_USB_IO_PPI instance.
 | 
						|
  @param  Value         New feature value.
 | 
						|
 | 
						|
  @retval EFI_SUCCESS       Port feature is set successfully.
 | 
						|
  @retval EFI_DEVICE_ERROR  Cannot set the port feature due to a hardware error.
 | 
						|
  @retval Others            Other failure occurs.
 | 
						|
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
PeiHubSetHubFeature (
 | 
						|
  IN EFI_PEI_SERVICES    **PeiServices,
 | 
						|
  IN PEI_USB_IO_PPI      *UsbIoPpi,
 | 
						|
  IN UINT8               Value
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_USB_DEVICE_REQUEST      DeviceRequest;
 | 
						|
 | 
						|
  ZeroMem (&DeviceRequest, sizeof (EFI_USB_DEVICE_REQUEST));
 | 
						|
 | 
						|
  //
 | 
						|
  // Fill Device request packet
 | 
						|
  //
 | 
						|
  DeviceRequest.RequestType = USB_HUB_SET_HUB_FEATURE_REQ_TYPE;
 | 
						|
  DeviceRequest.Request     = USB_HUB_SET_HUB_FEATURE;
 | 
						|
  DeviceRequest.Value       = Value;
 | 
						|
 | 
						|
  return UsbIoPpi->UsbControlTransfer (
 | 
						|
                     PeiServices,
 | 
						|
                     UsbIoPpi,
 | 
						|
                     &DeviceRequest,
 | 
						|
                     EfiUsbNoData,
 | 
						|
                     PcdGet32 (PcdUsbTransferTimeoutValue),
 | 
						|
                     NULL,
 | 
						|
                     0
 | 
						|
                     );
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Clear specified feature on a given hub.
 | 
						|
 | 
						|
  @param  PeiServices   General-purpose services that are available to every PEIM.
 | 
						|
  @param  UsbIoPpi      Indicates the PEI_USB_IO_PPI instance.
 | 
						|
  @param  Value         Feature value that will be cleared from the hub port.
 | 
						|
 | 
						|
  @retval EFI_SUCCESS       Hub feature is cleared successfully.
 | 
						|
  @retval EFI_DEVICE_ERROR  Cannot clear the hub feature due to a hardware error.
 | 
						|
  @retval Others            Other failure occurs.
 | 
						|
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
PeiHubClearHubFeature (
 | 
						|
  IN EFI_PEI_SERVICES    **PeiServices,
 | 
						|
  IN PEI_USB_IO_PPI      *UsbIoPpi,
 | 
						|
  IN UINT8               Value
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_USB_DEVICE_REQUEST      DeviceRequest;
 | 
						|
 | 
						|
  ZeroMem (&DeviceRequest, sizeof (EFI_USB_DEVICE_REQUEST));
 | 
						|
 | 
						|
  //
 | 
						|
  // Fill Device request packet
 | 
						|
  //
 | 
						|
  DeviceRequest.RequestType = USB_HUB_CLEAR_FEATURE_REQ_TYPE;
 | 
						|
  DeviceRequest.Request     = USB_HUB_CLEAR_FEATURE;
 | 
						|
  DeviceRequest.Value       = Value;
 | 
						|
 | 
						|
  return  UsbIoPpi->UsbControlTransfer (
 | 
						|
                      PeiServices,
 | 
						|
                      UsbIoPpi,
 | 
						|
                      &DeviceRequest,
 | 
						|
                      EfiUsbNoData,
 | 
						|
                      PcdGet32 (PcdUsbTransferTimeoutValue),
 | 
						|
                      NULL,
 | 
						|
                      0
 | 
						|
                      );
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Get a given hub descriptor.
 | 
						|
 | 
						|
  @param  PeiServices    General-purpose services that are available to every PEIM.
 | 
						|
  @param  UsbIoPpi       Indicates the PEI_USB_IO_PPI instance.
 | 
						|
  @param  DescriptorSize The length of Hub Descriptor buffer.
 | 
						|
  @param  HubDescriptor  Caller allocated buffer to store the hub descriptor if
 | 
						|
                         successfully returned.
 | 
						|
 | 
						|
  @retval EFI_SUCCESS       Hub descriptor is obtained successfully.
 | 
						|
  @retval EFI_DEVICE_ERROR  Cannot get the hub descriptor due to a hardware error.
 | 
						|
  @retval Others            Other failure occurs.
 | 
						|
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
PeiGetHubDescriptor (
 | 
						|
  IN  EFI_PEI_SERVICES          **PeiServices,
 | 
						|
  IN  PEI_USB_IO_PPI            *UsbIoPpi,
 | 
						|
  IN  UINTN                     DescriptorSize,
 | 
						|
  OUT EFI_USB_HUB_DESCRIPTOR    *HubDescriptor
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_USB_DEVICE_REQUEST      DevReq;
 | 
						|
  ZeroMem (&DevReq, sizeof (EFI_USB_DEVICE_REQUEST));
 | 
						|
 | 
						|
  //
 | 
						|
  // Fill Device request packet
 | 
						|
  //
 | 
						|
  DevReq.RequestType = USB_RT_HUB | 0x80;
 | 
						|
  DevReq.Request     = USB_HUB_GET_DESCRIPTOR;
 | 
						|
  DevReq.Value       = USB_DT_HUB << 8;
 | 
						|
  DevReq.Length      = (UINT16)DescriptorSize;
 | 
						|
 | 
						|
  return  UsbIoPpi->UsbControlTransfer (
 | 
						|
                      PeiServices,
 | 
						|
                      UsbIoPpi,
 | 
						|
                      &DevReq,
 | 
						|
                      EfiUsbDataIn,
 | 
						|
                      PcdGet32 (PcdUsbTransferTimeoutValue),
 | 
						|
                      HubDescriptor,
 | 
						|
                      (UINT16)DescriptorSize
 | 
						|
                      );
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Get a given SuperSpeed hub descriptor.
 | 
						|
 | 
						|
  @param  PeiServices       General-purpose services that are available to every PEIM.
 | 
						|
  @param  UsbIoPpi          Indicates the PEI_USB_IO_PPI instance.
 | 
						|
  @param  HubDescriptor     Caller allocated buffer to store the hub descriptor if
 | 
						|
                            successfully returned.
 | 
						|
 | 
						|
  @retval EFI_SUCCESS       Hub descriptor is obtained successfully.
 | 
						|
  @retval EFI_DEVICE_ERROR  Cannot get the hub descriptor due to a hardware error.
 | 
						|
  @retval Others            Other failure occurs.
 | 
						|
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
PeiGetSuperSpeedHubDesc (
 | 
						|
  IN  EFI_PEI_SERVICES          **PeiServices,
 | 
						|
  IN  PEI_USB_IO_PPI            *UsbIoPpi,
 | 
						|
  OUT EFI_USB_HUB_DESCRIPTOR    *HubDescriptor
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_USB_DEVICE_REQUEST        DevReq;
 | 
						|
  ZeroMem (&DevReq, sizeof (EFI_USB_DEVICE_REQUEST));
 | 
						|
 | 
						|
  //
 | 
						|
  // Fill Device request packet
 | 
						|
  //
 | 
						|
  DevReq.RequestType = USB_RT_HUB | 0x80;
 | 
						|
  DevReq.Request     = USB_HUB_GET_DESCRIPTOR;
 | 
						|
  DevReq.Value       = USB_DT_SUPERSPEED_HUB << 8;
 | 
						|
  DevReq.Length      = 12;
 | 
						|
 | 
						|
  return  UsbIoPpi->UsbControlTransfer (
 | 
						|
                      PeiServices,
 | 
						|
                      UsbIoPpi,
 | 
						|
                      &DevReq,
 | 
						|
                      EfiUsbDataIn,
 | 
						|
                      PcdGet32 (PcdUsbTransferTimeoutValue),
 | 
						|
                      HubDescriptor,
 | 
						|
                      12
 | 
						|
                      );
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Read the whole usb hub descriptor. It is necessary
 | 
						|
  to do it in two steps because hub descriptor is of
 | 
						|
  variable length.
 | 
						|
 | 
						|
  @param  PeiServices       General-purpose services that are available to every PEIM.
 | 
						|
  @param  PeiUsbDevice      Indicates the hub controller device.
 | 
						|
  @param  UsbIoPpi          Indicates the PEI_USB_IO_PPI instance.
 | 
						|
  @param  HubDescriptor     Caller allocated buffer to store the hub descriptor if
 | 
						|
                            successfully returned.
 | 
						|
 | 
						|
  @retval EFI_SUCCESS       Hub descriptor is obtained successfully.
 | 
						|
  @retval EFI_DEVICE_ERROR  Cannot get the hub descriptor due to a hardware error.
 | 
						|
  @retval Others            Other failure occurs.
 | 
						|
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
PeiUsbHubReadDesc (
 | 
						|
  IN EFI_PEI_SERVICES           **PeiServices,
 | 
						|
  IN PEI_USB_DEVICE             *PeiUsbDevice,
 | 
						|
  IN PEI_USB_IO_PPI             *UsbIoPpi,
 | 
						|
  OUT EFI_USB_HUB_DESCRIPTOR    *HubDescriptor
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_STATUS Status;
 | 
						|
 | 
						|
  if (PeiUsbDevice->DeviceSpeed == EFI_USB_SPEED_SUPER) {
 | 
						|
    //
 | 
						|
    // Get the super speed hub descriptor
 | 
						|
    //
 | 
						|
    Status = PeiGetSuperSpeedHubDesc (PeiServices, UsbIoPpi, HubDescriptor);
 | 
						|
  } else {
 | 
						|
 | 
						|
    //
 | 
						|
    // First get the hub descriptor length
 | 
						|
    //
 | 
						|
    Status = PeiGetHubDescriptor (PeiServices, UsbIoPpi, 2, HubDescriptor);
 | 
						|
 | 
						|
    if (EFI_ERROR (Status)) {
 | 
						|
      return Status;
 | 
						|
    }
 | 
						|
 | 
						|
    //
 | 
						|
    // Get the whole hub descriptor
 | 
						|
    //
 | 
						|
    Status = PeiGetHubDescriptor (PeiServices, UsbIoPpi, HubDescriptor->Length, HubDescriptor);
 | 
						|
  }
 | 
						|
 | 
						|
  return Status;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  USB hub control transfer to set the hub depth.
 | 
						|
 | 
						|
  @param  PeiServices       General-purpose services that are available to every PEIM.
 | 
						|
  @param  PeiUsbDevice      Indicates the hub controller device.
 | 
						|
  @param  UsbIoPpi          Indicates the PEI_USB_IO_PPI instance.
 | 
						|
 | 
						|
  @retval EFI_SUCCESS       Depth of the hub is set.
 | 
						|
  @retval Others            Failed to set the depth.
 | 
						|
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
PeiUsbHubCtrlSetHubDepth (
 | 
						|
  IN EFI_PEI_SERVICES           **PeiServices,
 | 
						|
  IN PEI_USB_DEVICE             *PeiUsbDevice,
 | 
						|
  IN PEI_USB_IO_PPI             *UsbIoPpi
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_USB_DEVICE_REQUEST        DevReq;
 | 
						|
  ZeroMem (&DevReq, sizeof (EFI_USB_DEVICE_REQUEST));
 | 
						|
 | 
						|
  //
 | 
						|
  // Fill Device request packet
 | 
						|
  //
 | 
						|
  DevReq.RequestType = USB_RT_HUB;
 | 
						|
  DevReq.Request     = USB_HUB_REQ_SET_DEPTH;
 | 
						|
  DevReq.Value       = PeiUsbDevice->Tier;
 | 
						|
  DevReq.Length      = 0;
 | 
						|
 | 
						|
  return  UsbIoPpi->UsbControlTransfer (
 | 
						|
                      PeiServices,
 | 
						|
                      UsbIoPpi,
 | 
						|
                      &DevReq,
 | 
						|
                      EfiUsbNoData,
 | 
						|
                      PcdGet32 (PcdUsbTransferTimeoutValue),
 | 
						|
                      NULL,
 | 
						|
                      0
 | 
						|
                      );
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Configure a given hub.
 | 
						|
 | 
						|
  @param  PeiServices    General-purpose services that are available to every PEIM.
 | 
						|
  @param  PeiUsbDevice   Indicating the hub controller device that will be configured
 | 
						|
 | 
						|
  @retval EFI_SUCCESS       Hub configuration is done successfully.
 | 
						|
  @retval EFI_DEVICE_ERROR  Cannot configure the hub due to a hardware error.
 | 
						|
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
PeiDoHubConfig (
 | 
						|
  IN EFI_PEI_SERVICES    **PeiServices,
 | 
						|
  IN PEI_USB_DEVICE      *PeiUsbDevice
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_USB_HUB_DESCRIPTOR  HubDescriptor;
 | 
						|
  EFI_STATUS              Status;
 | 
						|
  EFI_USB_HUB_STATUS      HubStatus;
 | 
						|
  UINTN                   Index;
 | 
						|
  PEI_USB_IO_PPI          *UsbIoPpi;
 | 
						|
 | 
						|
  ZeroMem (&HubDescriptor, sizeof (HubDescriptor));
 | 
						|
  UsbIoPpi = &PeiUsbDevice->UsbIoPpi;
 | 
						|
 | 
						|
  //
 | 
						|
  // Get the hub descriptor 
 | 
						|
  //
 | 
						|
  Status = PeiUsbHubReadDesc (
 | 
						|
            PeiServices,
 | 
						|
            PeiUsbDevice,
 | 
						|
            UsbIoPpi,
 | 
						|
            &HubDescriptor
 | 
						|
            );
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    return EFI_DEVICE_ERROR;
 | 
						|
  }
 | 
						|
 | 
						|
  PeiUsbDevice->DownStreamPortNo = HubDescriptor.NbrPorts;
 | 
						|
 | 
						|
  if (PeiUsbDevice->DeviceSpeed == EFI_USB_SPEED_SUPER) {
 | 
						|
    DEBUG ((EFI_D_INFO, "PeiDoHubConfig: Set Hub Depth as 0x%x\n", PeiUsbDevice->Tier));
 | 
						|
    PeiUsbHubCtrlSetHubDepth (
 | 
						|
      PeiServices,
 | 
						|
      PeiUsbDevice,
 | 
						|
      UsbIoPpi
 | 
						|
      );
 | 
						|
  } else {
 | 
						|
    //
 | 
						|
    //  Power all the hub ports
 | 
						|
    //
 | 
						|
    for (Index = 0; Index < PeiUsbDevice->DownStreamPortNo; Index++) {
 | 
						|
      Status = PeiHubSetPortFeature (
 | 
						|
                PeiServices,
 | 
						|
                UsbIoPpi,
 | 
						|
                (UINT8) (Index + 1),
 | 
						|
                EfiUsbPortPower
 | 
						|
                );
 | 
						|
      if (EFI_ERROR (Status)) {
 | 
						|
        DEBUG (( EFI_D_ERROR, "PeiDoHubConfig: PeiHubSetPortFeature EfiUsbPortPower failed %x\n", Index));
 | 
						|
        continue;
 | 
						|
      }
 | 
						|
    }
 | 
						|
 | 
						|
    DEBUG (( EFI_D_INFO, "PeiDoHubConfig: HubDescriptor.PwrOn2PwrGood: 0x%x\n", HubDescriptor.PwrOn2PwrGood));
 | 
						|
    if (HubDescriptor.PwrOn2PwrGood > 0) {
 | 
						|
      MicroSecondDelay (HubDescriptor.PwrOn2PwrGood * USB_SET_PORT_POWER_STALL);
 | 
						|
    }
 | 
						|
 | 
						|
    //
 | 
						|
    // Clear Hub Status Change
 | 
						|
    //
 | 
						|
    Status = PeiHubGetHubStatus (
 | 
						|
              PeiServices,
 | 
						|
              UsbIoPpi,
 | 
						|
              (UINT32 *) &HubStatus
 | 
						|
              );
 | 
						|
    if (EFI_ERROR (Status)) {
 | 
						|
      return EFI_DEVICE_ERROR;
 | 
						|
    } else {
 | 
						|
      //
 | 
						|
      // Hub power supply change happens
 | 
						|
      //
 | 
						|
      if ((HubStatus.HubChangeStatus & HUB_CHANGE_LOCAL_POWER) != 0) {
 | 
						|
        PeiHubClearHubFeature (
 | 
						|
          PeiServices,
 | 
						|
          UsbIoPpi,
 | 
						|
          C_HUB_LOCAL_POWER
 | 
						|
          );
 | 
						|
      }
 | 
						|
      //
 | 
						|
      // Hub change overcurrent happens
 | 
						|
      //
 | 
						|
      if ((HubStatus.HubChangeStatus & HUB_CHANGE_OVERCURRENT) != 0) {
 | 
						|
        PeiHubClearHubFeature (
 | 
						|
          PeiServices,
 | 
						|
          UsbIoPpi,
 | 
						|
          C_HUB_OVER_CURRENT
 | 
						|
          );
 | 
						|
      }
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  return EFI_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Send reset signal over the given root hub port.
 | 
						|
 | 
						|
  @param  PeiServices    General-purpose services that are available to every PEIM.
 | 
						|
  @param  UsbIoPpi       Indicates the PEI_USB_IO_PPI instance.
 | 
						|
  @param  PortNum        Usb hub port number (starting from 1).
 | 
						|
 | 
						|
**/
 | 
						|
VOID
 | 
						|
PeiResetHubPort (
 | 
						|
  IN EFI_PEI_SERVICES    **PeiServices,
 | 
						|
  IN PEI_USB_IO_PPI      *UsbIoPpi,
 | 
						|
  IN UINT8               PortNum
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_STATUS          Status;
 | 
						|
  UINTN               Index;
 | 
						|
  EFI_USB_PORT_STATUS HubPortStatus;
 | 
						|
 | 
						|
  MicroSecondDelay (100 * 1000);
 | 
						|
 | 
						|
  //
 | 
						|
  // reset root port
 | 
						|
  //
 | 
						|
  PeiHubSetPortFeature (
 | 
						|
    PeiServices,
 | 
						|
    UsbIoPpi,
 | 
						|
    PortNum,
 | 
						|
    EfiUsbPortReset
 | 
						|
    );
 | 
						|
 | 
						|
  //
 | 
						|
  // Drive the reset signal for worst 20ms. Check USB 2.0 Spec
 | 
						|
  // section 7.1.7.5 for timing requirements.
 | 
						|
  //
 | 
						|
  MicroSecondDelay (USB_SET_PORT_RESET_STALL);
 | 
						|
 | 
						|
  //
 | 
						|
  // Check USB_PORT_STAT_C_RESET bit to see if the resetting state is done.
 | 
						|
  //
 | 
						|
  ZeroMem (&HubPortStatus, sizeof (EFI_USB_PORT_STATUS));
 | 
						|
 | 
						|
  for (Index = 0; Index < USB_WAIT_PORT_STS_CHANGE_LOOP; Index++) {
 | 
						|
    Status = PeiHubGetPortStatus (
 | 
						|
               PeiServices,
 | 
						|
               UsbIoPpi,
 | 
						|
               PortNum,
 | 
						|
               (UINT32 *) &HubPortStatus
 | 
						|
               );
 | 
						|
 | 
						|
    if (EFI_ERROR (Status)) {
 | 
						|
      return;
 | 
						|
    }
 | 
						|
 | 
						|
    if (USB_BIT_IS_SET (HubPortStatus.PortChangeStatus, USB_PORT_STAT_C_RESET)) {
 | 
						|
      break;
 | 
						|
    }
 | 
						|
 | 
						|
    MicroSecondDelay (USB_WAIT_PORT_STS_CHANGE_STALL);
 | 
						|
  }
 | 
						|
 | 
						|
  if (Index == USB_WAIT_PORT_STS_CHANGE_LOOP) {
 | 
						|
    DEBUG ((EFI_D_ERROR, "PeiResetHubPort: reset not finished in time on port %d\n", PortNum));
 | 
						|
    return;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // clear reset change root port
 | 
						|
  //
 | 
						|
  PeiHubClearPortFeature (
 | 
						|
    PeiServices,
 | 
						|
    UsbIoPpi,
 | 
						|
    PortNum,
 | 
						|
    EfiUsbPortResetChange
 | 
						|
    );
 | 
						|
 | 
						|
  MicroSecondDelay (1 * 1000);
 | 
						|
 | 
						|
  PeiHubClearPortFeature (
 | 
						|
    PeiServices,
 | 
						|
    UsbIoPpi,
 | 
						|
    PortNum,
 | 
						|
    EfiUsbPortConnectChange
 | 
						|
    );
 | 
						|
 | 
						|
  //
 | 
						|
  // Set port enable
 | 
						|
  //
 | 
						|
  PeiHubSetPortFeature (
 | 
						|
    PeiServices,
 | 
						|
    UsbIoPpi,
 | 
						|
    PortNum,
 | 
						|
    EfiUsbPortEnable
 | 
						|
    );
 | 
						|
 | 
						|
  //
 | 
						|
  // Clear any change status
 | 
						|
  //
 | 
						|
 | 
						|
  PeiHubClearPortFeature (
 | 
						|
    PeiServices,
 | 
						|
    UsbIoPpi,
 | 
						|
    PortNum,
 | 
						|
    EfiUsbPortEnableChange
 | 
						|
    );
 | 
						|
 | 
						|
  MicroSecondDelay (10 * 1000);
 | 
						|
 | 
						|
  return;
 | 
						|
}
 |