summaryrefslogtreecommitdiff
path: root/Core/EM/UsbRecovery/UsbPeimSrc
diff options
context:
space:
mode:
authorraywu <raywu0301@gmail.com>2018-06-15 00:00:50 +0800
committerraywu <raywu0301@gmail.com>2018-06-15 00:00:50 +0800
commitb7c51c9cf4864df6aabb99a1ae843becd577237c (patch)
treeeebe9b0d0ca03062955223097e57da84dd618b9a /Core/EM/UsbRecovery/UsbPeimSrc
downloadzprj-master.tar.xz
init. 1AQQW051HEADmaster
Diffstat (limited to 'Core/EM/UsbRecovery/UsbPeimSrc')
-rw-r--r--Core/EM/UsbRecovery/UsbPeimSrc/HubPeim.c889
-rw-r--r--Core/EM/UsbRecovery/UsbPeimSrc/UsbIoPeim.c334
-rw-r--r--Core/EM/UsbRecovery/UsbPeimSrc/UsbPeim.c1006
-rw-r--r--Core/EM/UsbRecovery/UsbPeimSrc/UsbPeimSrc.cif12
4 files changed, 2241 insertions, 0 deletions
diff --git a/Core/EM/UsbRecovery/UsbPeimSrc/HubPeim.c b/Core/EM/UsbRecovery/UsbPeimSrc/HubPeim.c
new file mode 100644
index 0000000..a2a2246
--- /dev/null
+++ b/Core/EM/UsbRecovery/UsbPeimSrc/HubPeim.c
@@ -0,0 +1,889 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2007, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+//**********************************************************************
+//
+// $Header: /Alaska/SOURCE/Modules/USBRecovery/UsbPeimSrc/HubPeim.c 12 11/24/12 5:46a Ryanchou $
+//
+// $Revision: 12 $
+//
+// $Date: 11/24/12 5:46a $
+//
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/USBRecovery/UsbPeimSrc/HubPeim.c $
+//
+// 12 11/24/12 5:46a Ryanchou
+// [TAG] EIP103990
+// [Category] Improvement
+// [Description] Synchronized with USB PEI module 4.6.3_USB_08.10.24.
+// [Files] EhciPei.c, EhciPei.h, OhciPei.c, OhciPei.h, UhcPeim.c,
+// BotPeim.c, BotPeim.h, PeiAtapi.c, UsbBotPeim.c, UsbBotPeim.h,
+// HubPeim.c, UsbPeim.c, XhciPei.c, XhciPei.h, HubPeim.h, PeiUsbLib.c,
+// PeiUsbLib.h, UsbPeim.h
+//
+// 11 8/24/11 4:24a Roberthsu
+// [TAG] EIP67320
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] USB recovery will fail when plug-in USB touch panel on
+// Oaktrail platform
+// [RootCause] Usbrecovery will exit when get portchanged.Touch panel
+// port status is early than usbkey.So usbrecovery fail.
+// [Solution] Add delay after hub set port power.
+// [Files] HubPeim.c
+//
+// 10 1/18/11 12:54a Ryanchou
+// [TAG] EIP47931
+// [Category] Improvement
+// [Description] Added USB 3.0 hub support.
+// [Files] EhciPei.c, EhciPei.h, HubPeim.c, HubPeim.h, OhciPei.c,
+// OhciPei.h, UhcPeim.c, UhcPeim.h, usb.h, UsbHostController.h,
+// UsbIoPeim.c, UsbPeim.c, UsbPeim.h, XhciPei.c, XhciPei.h
+//
+// 9 4/26/10 4:17p Krishnakumarg
+// DebugRx causes the system to hang in Recovery mode EIP#34401
+//
+// 8 4/06/10 3:31p Fasihm
+// EIP#31987 - Added the generic USBRecovery Fix in the module.
+//
+// 7 3/17/09 5:03p Olegi
+// Removed unnecessary CLEAR_FEATURE (Reset) and SET_FEATURE (Enable) in
+// the hub enumeration routine.
+//
+// 6 7/18/08 5:05p Michaela
+// 1 File-level debugging is now available
+// 2 AMI_USB_DEBUG_INTERFACE.WaitConsoleKey() now returns
+// the keypress so that conditional debugging can
+// be dynamic (alphanumeric keys only)
+// 3 Added more function headers.
+// 4 Removed code that will never be used (I.e., Bala?).
+// 5 Moved typedef, contants and extern declarations
+// into header files.
+// 6 Now all controller blocks are enabled for SB700
+// (EHCI controllers route to companion controller
+// by default)
+// 7 Removed unused constants and typedefs n OhciPei.h
+// (also reorganized the file to make it more
+// readable.)
+// 8 Renamed many functions/variables according to
+// coding standard.
+// 9 Removed code initializing data structures for
+// periodic lists, as this is not needed.
+// 10 Removed the CONTROLLER_TYPE SDL token to
+// allow UHCI and OHCI controllers to supported
+// simultaneously. (modified MAKE files
+// accordingly)
+//
+// 5 7/10/08 6:37p Michaela
+// Updated to support OHCI controllers
+//
+// 4 8/17/07 4:14p Ambikas
+//
+// 3 4/16/07 12:54p Sivagarn
+// - Updated as per coding standard review
+// - In previous check-in, TIANO.H file is removed and AMIMAPPING.H file
+// is included
+//
+// 2 3/28/07 3:38a Meenakshim
+//
+// 1 9/22/06 12:19p Sivagarn
+// - Initial Checkin
+// - Included Recovery code in Source
+//
+//*****************************************************************************
+
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: HubPeim.C
+//
+// Description: This file belongs to "Framework".
+// This file is modified by AMI to include copyright message,
+// appropriate header and integration code.
+// This file contains generic routines needed for USB recovery
+// PEIM
+//
+//----------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+/*++
+ This file contains 'Framework Code' and is licensed as such
+ under the terms of your license agreement with Intel or your
+ vendor. This file may not be modified, except as allowed by
+ additional terms of your license agreement.
+ --*/
+
+/*++
+
+ Copyright (c) 1999 - 2002 Intel Corporation. All rights reserved
+ This software and associated documentation (if any) is furnished
+ under a license and may only be used or copied in accordance
+ with the terms of the license. Except as permitted by such
+ license, no part of this software or documentation may be
+ reproduced, stored in a retrieval system, or transmitted in any
+ form or by any means without the express written consent of
+ Intel Corporation.
+
+
+ Module Name:
+
+ HubPeim.c
+
+ Abstract:
+
+ Usb Hub Request Support In PEI Phase
+
+ Revision History
+
+ --*/
+//NOT NEEDED FOR APTIO
+//#include "Efi.h"
+//#include "EfiDriverLib.h"
+//#include "usb.h"
+
+#include "HubPeim.h"
+#include "UsbPeim.h"
+#include "PeiUsbLib.h"
+
+#include EFI_PPI_DEFINITION( Stall )
+static EFI_GUID gPeiStallPpiGuid = EFI_PEI_STALL_PPI_GUID;
+
+//NOT NEEDED FOR APTIO
+//#include "usbbus.h"
+//#include "usblib.h"
+//#include "hub.h"
+
+extern VOID ZeroMem (
+ IN VOID *Buffer,
+ IN UINTN Size );
+
+typedef struct {
+ UINT32 HubPortStatus;
+ UINT32 EfiPortStatus;
+} EFI_USB_PORT_STATUS_MAP;
+
+EFI_USB_PORT_STATUS_MAP HubPortStatusMap[] = {
+ // Port status bits
+ {HUB_PORT_CONNECTION, USB_PORT_STAT_CONNECTION},
+ {HUB_PORT_ENABLE, USB_PORT_STAT_ENABLE},
+ {HUB_PORT_SUSPEND, USB_PORT_STAT_SUSPEND},
+ {HUB_PORT_OVER_CURRENT, USB_PORT_STAT_OVERCURRENT},
+ {HUB_PORT_RESET, USB_PORT_STAT_RESET},
+ {HUB_PORT_POWER, USB_PORT_STAT_POWER},
+ {HUB_PORT_LOW_SPEED, USB_PORT_STAT_LOW_SPEED},
+ {HUB_PORT_HIGH_SPEED, USB_PORT_STAT_HIGH_SPEED},
+ // Port status change bits
+ {HUB_C_PORT_CONNECTION << 16, USB_PORT_STAT_C_CONNECTION << 16},
+ {HUB_C_PORT_ENABLE << 16, USB_PORT_STAT_C_ENABLE << 16},
+ {HUB_C_PORT_SUSPEND << 16, USB_PORT_STAT_C_SUSPEND << 16},
+ {HUB_C_PORT_OVER_CURRENT << 16, USB_PORT_STAT_C_OVERCURRENT << 16},
+ {HUB_C_PORT_RESET << 16, USB_PORT_STAT_C_RESET << 16}
+};
+
+EFI_USB_PORT_STATUS_MAP SsHubPortStatusMap[] = {
+ // Port status bits
+ {SS_HUB_PORT_CONNECTION, USB_PORT_STAT_CONNECTION | USB_PORT_STAT_SUPER_SPEED},
+ {SS_HUB_PORT_ENABLE, USB_PORT_STAT_ENABLE},
+ {SS_HUB_PORT_OVER_CURRENT, USB_PORT_STAT_OVERCURRENT},
+ {SS_HUB_PORT_RESET, USB_PORT_STAT_RESET},
+ {SS_HUB_PORT_POWER, USB_PORT_STAT_POWER},
+ // Port status change bits
+ {SS_HUB_C_PORT_CONNECTION << 16, USB_PORT_STAT_C_CONNECTION << 16},
+ {SS_HUB_C_PORT_ENABLE << 16, USB_PORT_STAT_C_ENABLE << 16},
+ {SS_HUB_C_PORT_SUSPEND << 16, USB_PORT_STAT_C_SUSPEND << 16},
+ {SS_HUB_C_PORT_OVER_CURRENT << 16, USB_PORT_STAT_C_OVERCURRENT << 16},
+ {SS_HUB_C_PORT_RESET << 16, USB_PORT_STAT_C_RESET << 16}
+};
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: PeiHubGetPortStatus
+//
+// Description:
+// This function uses a device's PEI_USB_IO_PPI interface to execute a
+// control transfer on the default control pipe to issue a Hub
+// Class-specific request to obtain the port status and port status
+// change bits.
+//
+// Input:
+// IN EFI_PEI_SERVICES **PeiServices
+// -- PEI Sevices table pointer
+// IN PEI_USB_IO_PPI *UsbIoPpi
+// -- PEI_USB_IO_PPI interface pointer for the device
+// that is being accessed
+// IN UINT8 Port
+// -- This value is the hub port number for which the
+// status is to be returned.
+// OUT UINT32 *PortStatus
+// -- This output value is the USB Specification
+// (Revision 2.0) Hub Port Status field (upper word)
+// and Change Status field (lower word) values as
+// returned by the Get Port Status Hub Class device
+// standard request.
+//
+// Output:
+// EFI_STATUS (Return Value)
+// = EFI_SUCCESS on successful completion
+// or valid EFI error code
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS PeiHubGetPortStatus (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_USB_IO_PPI *UsbIoPpi,
+ IN UINT8 Port,
+ OUT UINT32 *PortStatus )
+{
+ EFI_USB_DEVICE_REQUEST DevReq;
+ PEI_USB_DEVICE *PeiUsbDev;
+ EFI_STATUS EfiStatus;
+ UINT32 HubPortStatus = 0;
+ UINT32 Timeout;
+ EFI_USB_PORT_STATUS_MAP *PortStatusMap;
+ UINT8 Index;
+ UINT8 Count;
+
+ PeiUsbDev = PEI_USB_DEVICE_FROM_THIS( UsbIoPpi );
+ ZeroMem( &DevReq, sizeof(EFI_USB_DEVICE_REQUEST) );
+
+ //
+ // Fill Device request packet
+ //
+ DevReq.RequestType = HUB_GET_PORT_STATUS_REQ_TYPE;
+ DevReq.Request = HUB_GET_PORT_STATUS;
+ DevReq.Value = 0;
+ DevReq.Index = Port;
+ DevReq.Length = sizeof(UINT32);
+
+ Timeout = 3000;
+
+ EfiStatus = UsbIoPpi->UsbControlTransfer(
+ PeiServices,
+ UsbIoPpi,
+ &DevReq,
+ EfiUsbDataIn,
+ Timeout,
+ &HubPortStatus,
+ sizeof(UINT32)
+ );
+
+ if (PeiUsbDev->DeviceSpeed != USB_SUPER_SPEED_DEVICE) {
+ PortStatusMap = HubPortStatusMap;
+ Count = sizeof(HubPortStatusMap) / sizeof(EFI_USB_PORT_STATUS_MAP);
+ } else {
+ PortStatusMap = SsHubPortStatusMap;
+ Count = sizeof(SsHubPortStatusMap) / sizeof(EFI_USB_PORT_STATUS_MAP);
+ }
+
+ for (*PortStatus = 0, Index = 0; Index < Count; Index++) {
+ if (HubPortStatus & PortStatusMap[Index].HubPortStatus) {
+ *PortStatus |= PortStatusMap[Index].EfiPortStatus;
+ }
+ }
+
+ return EfiStatus;
+}
+
+
+EFI_STATUS PeiHubSetPortFeature (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_USB_IO_PPI *UsbIoPpi,
+ IN UINT8 Port,
+ IN UINT8 Value )
+
+/*++
+
+ Routine Description:
+ Set specified feature to a give hub port
+
+ Arguments:
+ UsbIoPpi - EFI_USB_IO_PROTOCOL instance
+ Port - Usb hub port number (starting from 1).
+ Value - New feature value.
+
+ Returns:
+ EFI_SUCCESS
+ EFI_DEVICE
+ EFI_TIME_OUT
+ EFI_INVALID_PARAMETER
+
+ --*/
+
+{
+ EFI_USB_DEVICE_REQUEST DevReq;
+ EFI_STATUS EfiStatus;
+ UINT32 Timeout;
+
+ ZeroMem( &DevReq, sizeof(EFI_USB_DEVICE_REQUEST) );
+
+ //
+ // Fill Device request packet
+ //
+ DevReq.RequestType = HUB_SET_PORT_FEATURE_REQ_TYPE;
+ DevReq.Request = HUB_SET_PORT_FEATURE;
+ DevReq.Value = Value;
+ DevReq.Index = Port;
+ DevReq.Length = 0;
+
+ Timeout = 3000;
+ EfiStatus = UsbIoPpi->UsbControlTransfer(
+ PeiServices,
+ UsbIoPpi,
+ &DevReq,
+ EfiUsbNoData,
+ Timeout,
+ NULL,
+ 0
+ );
+
+ return EfiStatus;
+}
+
+
+EFI_STATUS PeiHubClearPortFeature (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_USB_IO_PPI *UsbIoPpi,
+ IN UINT8 Port,
+ IN UINT8 Value )
+
+/*++
+
+ Routine Description:
+ Clear a specified feature of a given hub port
+
+ Arguments:
+ UsbIoPpi - EFI_USB_IO_PROTOCOL instance
+ Port - Usb hub port number (starting from 1).
+ Value - Feature value that will be cleared from
+ that hub port.
+
+ Returns:
+ EFI_SUCCESS
+ EFI_DEVICE
+ EFI_TIME_OUT
+ EFI_INVALID_PARAMETER
+
+ --*/
+{
+ EFI_USB_DEVICE_REQUEST DevReq;
+ EFI_STATUS EfiStatus;
+ UINT32 Timeout;
+
+ ZeroMem( &DevReq, sizeof(EFI_USB_DEVICE_REQUEST) );
+
+ //
+ // Fill Device request packet
+ //
+ DevReq.RequestType = HUB_CLEAR_FEATURE_PORT_REQ_TYPE;
+ DevReq.Request = HUB_CLEAR_FEATURE_PORT;
+ DevReq.Value = Value;
+ DevReq.Index = Port;
+ DevReq.Length = 0;
+
+ Timeout = 3000;
+ EfiStatus = UsbIoPpi->UsbControlTransfer(
+ PeiServices,
+ UsbIoPpi,
+ &DevReq,
+ EfiUsbNoData,
+ Timeout,
+ NULL,
+ 0
+ );
+
+ return EfiStatus;
+}
+
+
+EFI_STATUS PeiHubGetHubStatus (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_USB_IO_PPI *UsbIoPpi,
+ OUT UINT32 *HubStatus )
+
+/*++
+
+ Routine Description:
+ Get Hub Status
+
+ Arguments:
+ UsbIoPpi - EFI_USB_IO_PROTOCOL instance
+ HubStatus - Current Hub status and change status.
+
+ Returns:
+ EFI_SUCCESS
+ EFI_DEVICE
+ EFI_TIME_OUT
+
+ --*/
+{
+ EFI_USB_DEVICE_REQUEST DevReq;
+ EFI_STATUS EfiStatus;
+ UINT32 Timeout;
+
+ ZeroMem( &DevReq, sizeof(EFI_USB_DEVICE_REQUEST) );
+
+ //
+ // Fill Device request packet
+ //
+ DevReq.RequestType = HUB_GET_HUB_STATUS_REQ_TYPE;
+ DevReq.Request = HUB_GET_HUB_STATUS;
+ DevReq.Value = 0;
+ DevReq.Index = 0;
+ DevReq.Length = sizeof(UINT32);
+
+ Timeout = 3000;
+ EfiStatus = UsbIoPpi->UsbControlTransfer(
+ PeiServices,
+ UsbIoPpi,
+ &DevReq,
+ EfiUsbDataIn,
+ Timeout,
+ HubStatus,
+ sizeof(UINT32)
+ );
+
+ return EfiStatus;
+}
+
+
+EFI_STATUS PeiHubSetHubFeature (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_USB_IO_PPI *UsbIoPpi,
+ IN UINT8 Value )
+
+/*++
+
+ Routine Description:
+ Set a specified feature to the hub
+
+ Arguments:
+ UsbIoPpi - EFI_USB_IO_PROTOCOL instance
+ Value - Feature value that will be set to the hub.
+
+ Returns:
+ EFI_SUCCESS
+ EFI_DEVICE
+ EFI_TIME_OUT
+
+ --*/
+{
+ EFI_USB_DEVICE_REQUEST DevReq;
+ EFI_STATUS EfiStatus;
+ UINT32 Timeout;
+
+ ZeroMem( &DevReq, sizeof(EFI_USB_DEVICE_REQUEST) );
+
+ //
+ // Fill Device request packet
+ //
+ DevReq.RequestType = HUB_SET_HUB_FEATURE_REQ_TYPE;
+ DevReq.Request = HUB_SET_HUB_FEATURE;
+ DevReq.Value = Value;
+ DevReq.Index = 0;
+ DevReq.Length = 0;
+
+ Timeout = 3000;
+ EfiStatus = UsbIoPpi->UsbControlTransfer(
+ PeiServices,
+ UsbIoPpi,
+ &DevReq,
+ EfiUsbNoData,
+ Timeout,
+ NULL,
+ 0
+ );
+
+ return EfiStatus;
+}
+
+
+EFI_STATUS PeiHubClearHubFeature (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_USB_IO_PPI *UsbIoPpi,
+ IN UINT8 Value )
+
+/*++
+
+ Routine Description:
+ Set a specified feature to the hub
+
+ Arguments:
+ UsbIoPpi - EFI_USB_IO_PROTOCOL instance
+ Value - Feature value that will be cleared from the hub.
+
+ Returns:
+ EFI_SUCCESS
+ EFI_DEVICE
+ EFI_TIME_OUT
+
+ --*/
+{
+ EFI_USB_DEVICE_REQUEST DevReq;
+ EFI_STATUS EfiStatus;
+ UINT32 Timeout;
+
+ ZeroMem( &DevReq, sizeof(EFI_USB_DEVICE_REQUEST) );
+
+ //
+ // Fill Device request packet
+ //
+ DevReq.RequestType = HUB_CLEAR_FEATURE_REQ_TYPE;
+ DevReq.Request = HUB_CLEAR_FEATURE;
+ DevReq.Value = Value;
+ DevReq.Index = 0;
+ DevReq.Length = 0;
+
+ Timeout = 3000;
+ EfiStatus = UsbIoPpi->UsbControlTransfer(
+ PeiServices,
+ UsbIoPpi,
+ &DevReq,
+ EfiUsbNoData,
+ Timeout,
+ NULL,
+ 0
+ );
+
+ return EfiStatus;
+
+}
+
+EFI_STATUS PeiSetHubDepth (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_USB_IO_PPI *UsbIoPpi,
+ IN UINT16 HubDepth)
+{
+ EFI_USB_DEVICE_REQUEST DevReq;
+ PEI_USB_DEVICE *PeiUsbDev;
+ EFI_STATUS EfiStatus;
+ UINT32 Timeout;
+
+ PeiUsbDev = PEI_USB_DEVICE_FROM_THIS( UsbIoPpi );
+ if (PeiUsbDev->DeviceSpeed != USB_SUPER_SPEED_DEVICE) {
+ return EFI_SUCCESS;
+ }
+
+ ZeroMem( &DevReq, sizeof(EFI_USB_DEVICE_REQUEST) );
+
+ //
+ // Fill Device request packet
+ //
+ DevReq.RequestType = HUB_SET_HUB_DEPTH_REQ_TYPE;
+ DevReq.Request = HUB_SET_HUB_DEPTH;
+ DevReq.Value = HubDepth;
+ DevReq.Index = 0;
+ DevReq.Length = 0;
+
+ Timeout = 3000;
+ EfiStatus = UsbIoPpi->UsbControlTransfer(
+ PeiServices,
+ UsbIoPpi,
+ &DevReq,
+ EfiUsbNoData,
+ Timeout,
+ NULL,
+ 0
+ );
+
+ return EfiStatus;
+}
+
+EFI_STATUS PeiGetHubDescriptor (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_USB_IO_PPI *UsbIoPpi,
+ IN UINTN DescriptorSize,
+ OUT EFI_USB_HUB_DESCRIPTOR *HubDescriptor )
+
+/*++
+
+ Routine Description:
+ Get the hub descriptor
+
+ Arguments:
+ UsbIoPpi - EFI_USB_IO_PROTOCOL instance
+ DescriptorSize - The length of Hub Descriptor buffer.
+ HubDescriptor - Caller allocated buffer to store the hub descriptor
+ if successfully returned.
+
+ Returns:
+ EFI_SUCCESS
+ EFI_DEVICE
+ EFI_TIME_OUT
+
+ --*/
+{
+ EFI_USB_DEVICE_REQUEST DevReq;
+ PEI_USB_DEVICE *PeiUsbDev;
+ EFI_STATUS EfiStatus;
+ UINT32 Timeout;
+
+ PeiUsbDev = PEI_USB_DEVICE_FROM_THIS( UsbIoPpi );
+ ZeroMem( &DevReq, sizeof(EFI_USB_DEVICE_REQUEST) );
+
+ //
+ // Fill Device request packet
+ //
+ DevReq.RequestType = USB_RT_HUB | 0x80;
+ DevReq.Request = HUB_GET_DESCRIPTOR;
+ DevReq.Value = PeiUsbDev->DeviceSpeed == USB_SUPER_SPEED_DEVICE ?
+ USB_DT_SS_HUB << 8: USB_DT_HUB << 8;
+ DevReq.Index = 0;
+ DevReq.Length = (UINT16) DescriptorSize;
+
+ Timeout = 3000;
+ EfiStatus = UsbIoPpi->UsbControlTransfer(
+ PeiServices,
+ UsbIoPpi,
+ &DevReq,
+ EfiUsbDataIn,
+ Timeout,
+ HubDescriptor,
+ (UINT16) DescriptorSize
+ );
+
+ return EfiStatus;
+
+}
+
+
+EFI_STATUS PeiDoHubConfig (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_USB_DEVICE *PeiUsbDevice )
+
+/*++
+
+ Routine Description:
+ Configure the hub
+
+ Arguments:
+ PeiUsbDevice - Indicating the hub controller device that
+ will be configured
+
+ Returns:
+ EFI_SUCCESS
+ EFI_DEVICE_ERROR
+
+ --*/
+{
+ EFI_USB_HUB_DESCRIPTOR HubDescriptor;
+ EFI_STATUS Status;
+ EFI_USB_HUB_STATUS HubStatus;
+ UINTN i;
+ UINT32 PortStatus;
+ PEI_USB_IO_PPI *UsbIoPpi;
+
+ BOOLEAN SkipDebugPort = PeiUsbDevice->UsbHcPpi->DebugPortUsed;
+//(EIP67320+)>
+ PEI_STALL_PPI *PeiStall;
+ (**PeiServices).LocatePpi(
+ PeiServices,
+ &gPeiStallPpiGuid,
+ 0,
+ NULL,
+ &PeiStall
+ );
+//<(EIP67320+)
+ ZeroMem( &HubDescriptor, sizeof(HubDescriptor) );
+ UsbIoPpi = &PeiUsbDevice->UsbIoPpi;
+
+ Status = PeiSetHubDepth(PeiServices,
+ UsbIoPpi,
+ PeiUsbDevice->HubDepth);
+ if ( EFI_ERROR( Status ) ) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ //
+ // First get the whole descriptor, then
+ // get the number of hub ports
+ //
+ Status = PeiGetHubDescriptor(
+ PeiServices,
+ UsbIoPpi,
+ sizeof(EFI_USB_HUB_DESCRIPTOR),
+ &HubDescriptor
+ );
+ if ( EFI_ERROR( Status ) ) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ PeiUsbDevice->DownStreamPortNo = HubDescriptor.NbrPorts;
+
+ Status = PeiHubGetHubStatus( PeiServices,
+ UsbIoPpi,
+ (UINT32 *) &HubStatus
+ );
+
+ if ( EFI_ERROR( Status ) ) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ //
+ // Get all hub ports status
+ //
+ for (i = 0; i < PeiUsbDevice->DownStreamPortNo; i++) {
+
+// Intel Debug port - Second port of the controller
+ if(SkipDebugPort && (i == 1) )
+ continue;
+
+ Status = PeiHubGetPortStatus( PeiServices,
+ UsbIoPpi,
+ (UINT8) (i + 1),
+ &PortStatus
+ );
+ if ( EFI_ERROR( Status ) ) {
+ continue;
+ }
+ }
+
+ //
+ // Power all the hub ports
+ //
+ for (i = 0; i < PeiUsbDevice->DownStreamPortNo; i++) {
+// Intel Debug port - Second port of the controller
+ if( SkipDebugPort && (i == 1) )
+ continue;
+
+ Status = PeiHubSetPortFeature( PeiServices,
+ UsbIoPpi,
+ (UINT8) (i + 1),
+ EfiUsbPortPower
+ );
+ if ( EFI_ERROR( Status ) ) {
+ continue;
+ }
+ }
+
+ //
+ // 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.HubChange & HUB_CHANGE_LOCAL_POWER) {
+ PeiHubClearHubFeature( PeiServices,
+ UsbIoPpi,
+ C_HUB_LOCAL_POWER
+ );
+ }
+
+ //
+ // Hub change overcurrent happens
+ //
+ if (HubStatus.HubChange & HUB_CHANGE_OVERCURRENT) {
+ PeiHubClearHubFeature( PeiServices,
+ UsbIoPpi,
+ C_HUB_OVER_CURRENT
+ );
+ }
+ }
+ PeiStall->Stall( PeiServices, PeiStall, (HubDescriptor.PwrOn2PwrGood << 1) *1000); //(EIP67320)
+ return EFI_SUCCESS;
+
+}
+
+
+//
+// Send reset signal over the given root hub port
+//
+VOID PeiResetHubPort (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_USB_IO_PPI *UsbIoPpi,
+ UINT8 PortNum )
+{
+ PEI_STALL_PPI *PeiStall;
+ UINT8 n;
+ EFI_USB_PORT_STATUS HubPortStatus;
+
+
+ (**PeiServices).LocatePpi(
+ PeiServices,
+ &gPeiStallPpiGuid,
+ 0,
+ NULL,
+ &PeiStall
+ );
+
+ //
+ // reset root port
+ //
+ PeiHubSetPortFeature(
+ PeiServices,
+ UsbIoPpi,
+ PortNum,
+ EfiUsbPortReset
+ );
+
+ n = 20;
+ do {
+ PeiHubGetPortStatus(
+ PeiServices,
+ UsbIoPpi,
+ PortNum,
+ (UINT32 *) &HubPortStatus
+ );
+ PeiStall->Stall(
+ PeiServices,
+ PeiStall,
+ 1000
+ );
+ n -= 1;
+ } while ( (HubPortStatus.PortChangeStatus &
+ USB_PORT_STAT_C_RESET) == 0 && n > 0 );
+
+ PeiStall->Stall(
+ PeiServices,
+ PeiStall,
+ 500
+ );
+ //
+ // Clear any change status
+ //
+ PeiHubClearPortFeature(
+ PeiServices,
+ UsbIoPpi,
+ PortNum,
+ EfiUsbPortResetChange
+ );
+
+ return;
+}
+
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2007, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+//********************************************************************** \ No newline at end of file
diff --git a/Core/EM/UsbRecovery/UsbPeimSrc/UsbIoPeim.c b/Core/EM/UsbRecovery/UsbPeimSrc/UsbIoPeim.c
new file mode 100644
index 0000000..157cb9b
--- /dev/null
+++ b/Core/EM/UsbRecovery/UsbPeimSrc/UsbIoPeim.c
@@ -0,0 +1,334 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2006, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+//**********************************************************************
+//
+// $Header: /Alaska/SOURCE/Modules/USBRecovery/UsbPeimSrc/UsbIoPeim.c 6 1/18/11 1:05a Ryanchou $
+//
+// $Revision: 6 $
+//
+// $Date: 1/18/11 1:05a $
+//
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/USBRecovery/UsbPeimSrc/UsbIoPeim.c $
+//
+// 6 1/18/11 1:05a Ryanchou
+// [TAG] EIP47931
+// [Category] Improvement
+// [Description] Added USB 3.0 hub support.
+// [Files] EhciPei.c, EhciPei.h, HubPeim.c, HubPeim.h, OhciPei.c,
+// OhciPei.h, UhcPeim.c, UhcPeim.h, usb.h, UsbHostController.h,
+// UsbIoPeim.c, UsbPeim.c, UsbPeim.h, XhciPei.c, XhciPei.h
+//
+// 5 3/17/09 5:04p Olegi
+// Added TransactionTranslator for slow/full speed devices behind USB2
+// hub.
+//
+// 4 3/03/09 7:21p Olegi
+// Changed the type of MaxPktSize from UINT8 to UINT16.
+//
+// 3 7/18/08 5:05p Michaela
+// 1 File-level debugging is now available
+// 2 AMI_USB_DEBUG_INTERFACE.WaitConsoleKey() now returns
+// the keypress so that conditional debugging can
+// be dynamic (alphanumeric keys only)
+// 3 Added more function headers.
+// 4 Removed code that will never be used (I.e., Bala?).
+// 5 Moved typedef, contants and extern declarations
+// into header files.
+// 6 Now all controller blocks are enabled for SB700
+// (EHCI controllers route to companion controller
+// by default)
+// 7 Removed unused constants and typedefs n OhciPei.h
+// (also reorganized the file to make it more
+// readable.)
+// 8 Renamed many functions/variables according to
+// coding standard.
+// 9 Removed code initializing data structures for
+// periodic lists, as this is not needed.
+// 10 Removed the CONTROLLER_TYPE SDL token to
+// allow UHCI and OHCI controllers to supported
+// simultaneously. (modified MAKE files
+// accordingly)
+//
+// 2 7/10/08 6:37p Michaela
+// Updated to support OHCI controllers
+//
+// 1 9/22/06 12:19p Sivagarn
+// - Initial Checkin
+// - Included Recovery code in Source
+//
+//*****************************************************************************
+
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: UsbIoPeim.C
+//
+// Description: This file belongs to "Framework".
+// This file is modified by AMI to include copyright message,
+// appropriate header and integration code.
+// This file contains generic routines needed for USB recovery
+// PEIM
+//
+//----------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+/*++
+ This file contains 'Framework Code' and is licensed as such
+ under the terms of your license agreement with Intel or your
+ vendor. This file may not be modified, except as allowed by
+ additional terms of your license agreement.
+ --*/
+
+/*++
+
+ Copyright (c) 1999 - 2002 Intel Corporation. All rights reserved
+ This software and associated documentation (if any) is furnished
+ under a license and may only be used or copied in accordance
+ with the terms of the license. Except as permitted by such
+ license, no part of this software or documentation may be
+ reproduced, stored in a retrieval system, or transmitted in any
+ form or by any means without the express written consent of
+ Intel Corporation.
+
+
+ Module Name:
+
+ UsbIoPeim.c
+
+ Abstract:
+
+ Usb Io PPI
+
+ --*/
+
+#include "UsbPeim.h"
+#include "PeiUsbLib.h"
+
+#define PAGESIZE 4096
+
+VOID
+ResetRootPort (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_USB_HOST_CONTROLLER_PPI *UsbHcPpi,
+ UINT8 PortNum );
+
+EFI_STATUS PeiUsbControlTransfer (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_USB_IO_PPI *This,
+ IN EFI_USB_DEVICE_REQUEST *Request,
+ IN EFI_USB_DATA_DIRECTION Direction,
+ IN UINT32 Timeout,
+ IN OUT VOID *Data OPTIONAL,
+ IN UINTN DataLength OPTIONAL )
+{
+ EFI_STATUS Status;
+ PEI_USB_DEVICE *PeiUsbDev;
+ PEI_USB_HOST_CONTROLLER_PPI *UsbHcPpi;
+ UINT32 TransferResult;
+
+ PeiUsbDev = PEI_USB_DEVICE_FROM_THIS( This );
+ UsbHcPpi = PeiUsbDev->UsbHcPpi;
+
+ Status = UsbHcPpi->ControlTransfer(
+ PeiServices,
+ UsbHcPpi,
+ PeiUsbDev->DeviceAddress,
+ PeiUsbDev->DeviceSpeed,
+ PeiUsbDev->MaxPacketSize0,
+ PeiUsbDev->TransactionTranslator,
+ Request,
+ Direction,
+ Data,
+ &DataLength,
+ Timeout,
+ &TransferResult
+ );
+
+ return Status;
+}
+
+
+EFI_STATUS PeiUsbBulkTransfer (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_USB_IO_PPI *This,
+ IN UINT8 DeviceEndpoint,
+ IN OUT VOID *Data,
+ IN OUT UINTN *DataLength,
+ IN UINTN Timeout )
+{
+ EFI_STATUS Status;
+ PEI_USB_DEVICE *PeiUsbDev;
+ PEI_USB_HOST_CONTROLLER_PPI *UsbHcPpi;
+ UINT32 TransferResult;
+ UINT16 MaxPacketLength;
+ UINT8 DataToggle;
+ UINT8 OldToggle;
+ EFI_USB_ENDPOINT_DESCRIPTOR *EndpointDescriptor;
+ UINT8 EndpointIndex;
+
+ PeiUsbDev = PEI_USB_DEVICE_FROM_THIS( This );
+ UsbHcPpi = PeiUsbDev->UsbHcPpi;
+
+ EndpointIndex = 0;
+
+ while (EndpointIndex < MAX_ENDPOINT) {
+ Status = PeiUsbGetEndpointDescriptor( PeiServices,
+ This, EndpointIndex, &EndpointDescriptor );
+ if ( EFI_ERROR( Status ) ) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (EndpointDescriptor->EndpointAddress == DeviceEndpoint) {
+ break;
+ }
+
+ EndpointIndex++;
+ }
+
+ if (EndpointIndex == MAX_ENDPOINT) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ MaxPacketLength = (PeiUsbDev->EndpointDesc[EndpointIndex]->MaxPacketSize);
+ if ( ( PeiUsbDev->DataToggle & (1 << EndpointIndex) ) != 0 ) {
+ DataToggle = 1;
+ }
+ else {
+ DataToggle = 0;
+ }
+
+ OldToggle = DataToggle;
+
+ Status = UsbHcPpi->BulkTransfer(
+ PeiServices,
+ UsbHcPpi,
+ PeiUsbDev->DeviceAddress,
+ DeviceEndpoint,
+ PeiUsbDev->DeviceSpeed,
+ MaxPacketLength,
+ PeiUsbDev->TransactionTranslator,
+ Data,
+ DataLength,
+ &DataToggle,
+ Timeout,
+ &TransferResult
+ );
+
+ if (OldToggle != DataToggle) {
+ PeiUsbDev->DataToggle =
+ (UINT8) ( PeiUsbDev->DataToggle ^ (1 << EndpointIndex) );
+ }
+
+ return Status;
+}
+
+
+EFI_STATUS PeiUsbGetInterfaceDescriptor (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_USB_IO_PPI *This,
+ IN EFI_USB_INTERFACE_DESCRIPTOR **InterfaceDescriptor )
+{
+ PEI_USB_DEVICE *PeiUsbDev;
+
+ PeiUsbDev = PEI_USB_DEVICE_FROM_THIS( This );
+
+ *InterfaceDescriptor = PeiUsbDev->InterfaceDesc;
+
+ return EFI_SUCCESS;
+}
+
+
+EFI_STATUS PeiUsbGetEndpointDescriptor (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_USB_IO_PPI *This,
+ IN UINT8 EndpointIndex,
+ IN EFI_USB_ENDPOINT_DESCRIPTOR **EndpointDescriptor )
+{
+ PEI_USB_DEVICE *PeiUsbDev;
+
+ PeiUsbDev = PEI_USB_DEVICE_FROM_THIS( This );
+
+ if (EndpointIndex >= PeiUsbDev->InterfaceDesc->NumEndpoints) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ *EndpointDescriptor = PeiUsbDev->EndpointDesc[EndpointIndex];
+
+ return EFI_SUCCESS;
+}
+
+
+EFI_STATUS PeiUsbPortReset (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_USB_IO_PPI *This )
+{
+ PEI_USB_DEVICE *PeiUsbDev;
+ EFI_STATUS Status;
+ UINT8 Address;
+
+ PeiUsbDev = PEI_USB_DEVICE_FROM_THIS( This );
+
+ ResetRootPort(
+ PeiServices,
+ PeiUsbDev->UsbHcPpi,
+ PeiUsbDev->DeviceAddress
+ );
+
+ //
+ // Set address
+ //
+ Address = PeiUsbDev->DeviceAddress;
+ PeiUsbDev->DeviceAddress = 0;
+
+ Status = PeiUsbSetDeviceAddress(
+ PeiServices,
+ This,
+ Address
+ );
+
+ if ( EFI_ERROR( Status ) ) {
+ return Status;
+ }
+
+ PeiUsbDev->DeviceAddress = Address;
+
+ //
+ // Set default configuration
+ //
+ Status = PeiUsbSetConfiguration(
+ PeiServices,
+ This
+ );
+
+ return Status;
+}
+
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2006, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+//********************************************************************** \ No newline at end of file
diff --git a/Core/EM/UsbRecovery/UsbPeimSrc/UsbPeim.c b/Core/EM/UsbRecovery/UsbPeimSrc/UsbPeim.c
new file mode 100644
index 0000000..87afc78
--- /dev/null
+++ b/Core/EM/UsbRecovery/UsbPeimSrc/UsbPeim.c
@@ -0,0 +1,1006 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2008, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+//**********************************************************************
+//
+// $Header: /Alaska/SOURCE/Modules/USBRecovery/UsbPeimSrc/UsbPeim.c 17 11/24/12 5:46a Ryanchou $
+//
+// $Revision: 17 $
+//
+// $Date: 11/24/12 5:46a $
+//
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/USBRecovery/UsbPeimSrc/UsbPeim.c $
+//
+// 17 11/24/12 5:46a Ryanchou
+// [TAG] EIP103990
+// [Category] Improvement
+// [Description] Synchronized with USB PEI module 4.6.3_USB_08.10.24.
+// [Files] EhciPei.c, EhciPei.h, OhciPei.c, OhciPei.h, UhcPeim.c,
+// BotPeim.c, BotPeim.h, PeiAtapi.c, UsbBotPeim.c, UsbBotPeim.h,
+// HubPeim.c, UsbPeim.c, XhciPei.c, XhciPei.h, HubPeim.h, PeiUsbLib.c,
+// PeiUsbLib.h, UsbPeim.h
+//
+// 16 8/23/12 10:01p Wilsonlee
+// [TAG] EIP97069
+// [Category] Improvement
+// [Description] Reset root port algorythm update.
+// [Files] EhciPei.c, EhciPei.h, OhciPei.c, OhciPei.h, UhcPeim.c,
+// UhcPeim.h, UsbPeim.c, usb.h
+//
+// 15 1/18/11 1:06a Ryanchou
+// [TAG] EIP47931
+// [Category] Improvement
+// [Description] Added USB 3.0 hub support.
+// [Files] EhciPei.c, EhciPei.h, HubPeim.c, HubPeim.h, OhciPei.c,
+// OhciPei.h, UhcPeim.c, UhcPeim.h, usb.h, UsbHostController.h,
+// UsbIoPeim.c, UsbPeim.c, UsbPeim.h, XhciPei.c, XhciPei.h
+//
+// 14 10/22/10 2:55a Rameshr
+// [TAG]- EIP 43687
+// [Category]-IMPROVEMENT
+// [Description]- Build warning from UsbRecovery driver -
+// UsbHostController.obj : warning LNK4221: no public symbols found;
+// archive member will be inaccessible.
+// [Files]- uhcpeim.c, usbpeim.c, UsbHostcontroller.h
+//
+// 13 10/12/10 11:20a Olegi
+// XHCI support added.
+//
+// 12 1/06/10 11:23a Olegi
+// Fix for EIP32503: The Interface descriptor of some devices is not
+// directly after the configuration descriptor, and the first Endpoint
+// descriptor is not directly after the Interface either. Changed the
+// descriptior data parser.
+//
+// 11 10/20/09 9:17a Olegi
+// EIP#28255: Set proper TransactionTranslator field for a non-hispeed USB
+// device.
+//
+// 10 3/17/09 5:07p Olegi
+// Added TransactionTranslator for slow/full speed devices behind USB2
+// hub.
+//
+// 9 10/21/08 5:57p Michaela
+// Added EHCI-related fixes for issues
+// that may occur if EHCI is used before
+// USB Recovery is invoked:
+// Added SDL Tokens:
+// PEI_EHCI_PCI_BDFS and
+// PEI_EHCI_MEM_BASE_ADDRESSES.
+//
+// Removed/modified some debugging
+// development code:
+// Removed SDL Tokens:
+// USBR_DEBUG_SUPPORT and
+// USBR_SERIAL_PORT_AVAILABLE
+// Removed Elinks:
+// UsbRecoveryDebug_DIR and
+// $(BUILD_DIR)\UsbRecoveryDebugDxe.ffs
+// Modified SDL Token:
+// FORCE_RECOVERY to default value of 0.
+//
+// (See this module's Help documentation
+// for more information.)
+//
+// 8 7/29/08 5:52p Michaela
+// 1) Updated code to move most porting tasks to SDL
+// 2) Added more debug break points and improved interactive
+// debugging capability for when a serial port is not available.
+// 3) Updated help files
+//
+// 7 7/18/08 5:05p Michaela
+// 1 File-level debugging is now available
+// 2 AMI_USB_DEBUG_INTERFACE.WaitConsoleKey() now returns
+// the keypress so that conditional debugging can
+// be dynamic (alphanumeric keys only)
+// 3 Added more function headers.
+// 4 Removed code that will never be used (I.e., Bala?).
+// 5 Moved typedef, contants and extern declarations
+// into header files.
+// 6 Now all controller blocks are enabled for SB700
+// (EHCI controllers route to companion controller
+// by default)
+// 7 Removed unused constants and typedefs n OhciPei.h
+// (also reorganized the file to make it more
+// readable.)
+// 8 Renamed many functions/variables according to
+// coding standard.
+// 9 Removed code initializing data structures for
+// periodic lists, as this is not needed.
+// 10 Removed the CONTROLLER_TYPE SDL token to
+// allow UHCI and OHCI controllers to supported
+// simultaneously. (modified MAKE files
+// accordingly)
+//
+// 6 7/10/08 6:37p Michaela
+// Updated to support OHCI controllers
+//
+// 5 10/23/07 5:41p Ambikas
+//
+// 4 8/17/07 4:13p Ambikas
+//
+// 3 4/16/07 12:55p Sivagarn
+// - Updated as per coding standard review
+// - In previous check-in, TIANO.H file is removed and AMIMAPPING.H file
+// is included
+//
+// 2 3/28/07 3:36a Meenakshim
+//
+// 1 9/22/06 12:19p Sivagarn
+// - Initial Checkin
+// - Included Recovery code in Source
+//
+//*****************************************************************************
+
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: UsbPeim.C
+//
+// Description: This file belongs to "Framework".
+// This file is modified by AMI to include copyright message,
+// appropriate header and integration code.
+// This file contains generic routines needed for USB recovery
+// PEIM
+//
+//----------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+/*++
+ This file contains 'Framework Code' and is licensed as such
+ under the terms of your license agreement with Intel or your
+ vendor. This file may not be modified, except as allowed by
+ additional terms of your license agreement.
+ --*/
+
+/*++
+
+ Copyright (c) 1999 - 2002 Intel Corporation. All rights reserved
+ This software and associated documentation (if any) is furnished
+ under a license and may only be used or copied in accordance
+ with the terms of the license. Except as permitted by such
+ license, no part of this software or documentation may be
+ reproduced, stored in a retrieval system, or transmitted in any
+ form or by any means without the express written consent of
+ Intel Corporation.
+
+
+ Module Name:
+
+ UsbPeim.c
+
+ Abstract:
+
+ Usb Bus PPI
+
+ --*/
+
+#include "UsbPeim.h"
+#include "HubPeim.h"
+#include "PeiUsbLib.h"
+
+
+#include EFI_PPI_DEFINITION (Stall)
+#include EFI_PPI_DEFINITION (LoadFile)
+
+EFI_GUID gPeiUsbIoPpiGuid = PEI_USB_IO_PPI_GUID;
+
+extern EFI_GUID gPeiStallPpiGuid;
+
+
+#define PAGESIZE 4096
+
+//static BOOLEAN mImageInMemory = FALSE;
+
+
+//
+// Driver Entry Point
+//
+
+
+EFI_STATUS
+PeimInitializeUsb (
+ IN EFI_FFS_FILE_HEADER *FfsHeader,
+ IN EFI_PEI_SERVICES **PeiServices );
+
+//
+// UsbIo PPI interface function
+//
+STATIC PEI_USB_IO_PPI mUsbIoPpi = {
+ PeiUsbControlTransfer,
+ PeiUsbBulkTransfer,
+ PeiUsbGetInterfaceDescriptor,
+ PeiUsbGetEndpointDescriptor,
+ PeiUsbPortReset
+};
+
+STATIC EFI_PEI_PPI_DESCRIPTOR mUsbIoPpiList = {
+ (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+ &gPeiUsbIoPpiGuid,
+ NULL
+};
+
+//
+// Helper functions
+//
+STATIC
+EFI_STATUS
+PeiUsbEnumeration (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_USB_HOST_CONTROLLER_PPI *UsbHcPpi );
+
+STATIC
+EFI_STATUS
+PeiConfigureUsbDevice (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_USB_DEVICE *PeiUsbDevice,
+ IN UINT8 Port,
+ IN OUT UINT8 *DeviceAddress );
+
+STATIC
+EFI_STATUS
+PeiUsbGetAllConfiguration (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_USB_DEVICE *PeiUsbDevice );
+
+
+VOID
+ResetRootPort (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_USB_HOST_CONTROLLER_PPI *UsbHcPpi,
+ UINT8 PortNum );
+
+extern VOID ZeroMem (
+ IN VOID *Buffer,
+ IN UINTN Size );
+
+
+
+//
+// PEIM Entry Point
+//
+// EFI_PEIM_ENTRY_POINT (PeimInitializeUsb);
+
+EFI_STATUS PeimInitializeUsb (
+ IN EFI_FFS_FILE_HEADER *FfsHeader,
+ IN EFI_PEI_SERVICES **PeiServices )
+{
+ EFI_STATUS Status;
+ UINTN i;
+ PEI_USB_HOST_CONTROLLER_PPI *UsbHcPpi;
+
+ // Assign resources and enable UHCI controllers
+ //
+ // when the image is in flash, the global variable
+ // mImageInMemory could not be modified;
+ // when the image is successfully loaded into memory,
+ // mImageInMemory could be modified to TRUE.
+ //
+
+ i = 0;
+ while (TRUE) {
+ //
+ // Get UsbHcPpi at first.
+ //
+ Status = (**PeiServices).LocatePpi( PeiServices,
+ &gPeiUsbHostControllerPpiGuid, i, NULL, &UsbHcPpi );
+
+ if ( EFI_ERROR( Status ) ) {
+ break;
+ }
+
+ PeiUsbEnumeration( PeiServices, UsbHcPpi ); // 0xff06
+ i++;
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+STATIC
+EFI_STATUS PeiHubEnumeration (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_USB_DEVICE *PeiUsbDevice,
+ IN UINT8 *CurrentAddress )
+//
+// Since we are not going to support hot-plug, we will do a
+// dedicated polling process to get all ports change event
+// discovered. This can help to avoid introduce interrupt
+// transfer into the system, for each hub, we will wait for
+// 3s and if one port is enabled we will not wait for others
+// We will start parsing each of them in sequence.
+//
+{
+ UINTN Delay;
+ UINT8 Port;
+ EFI_STATUS Status;
+ PEI_USB_IO_PPI *UsbIoPpi;
+ EFI_USB_PORT_STATUS PortStatus;
+ BOOLEAN PortChanged;
+ UINT8 *AllocateAddress;
+ PEI_USB_DEVICE *NewPeiUsbDevice;
+ PEI_STALL_PPI *StallPpi;
+
+
+ PortChanged = FALSE;
+
+ UsbIoPpi = &PeiUsbDevice->UsbIoPpi;
+ Status = (**PeiServices).LocatePpi( PeiServices, &gPeiStallPpiGuid,
+ 0, NULL, &StallPpi );
+
+ Delay = (HUB_TIME_OUT * STALL_1_MILLI_SECOND / 50000) + 1;
+
+ //
+ // Do while will do a 3s scan for the USB HUB for a connected
+ // device. If we have found one, the waiting process will be
+ // breaked since we assue other ports will be discovered at
+ // the same time.
+ //
+ do {
+ for (Port = 1; Port <= PeiUsbDevice->DownStreamPortNo; Port++) {
+
+ Status = PeiHubGetPortStatus( PeiServices, UsbIoPpi,
+ Port, (UINT32 *) &PortStatus );
+
+ if ( EFI_ERROR( Status ) ) {
+ continue;
+ }
+
+ if ( IsPortConnectChange( PortStatus.PortChangeStatus ) ) {
+ PortChanged = TRUE;
+ PeiHubClearPortFeature( PeiServices, UsbIoPpi,
+ Port, EfiUsbPortConnectChange );
+
+ if ( IsPortConnect( PortStatus.PortStatus ) ) {
+
+ if (IsPortEnable(PortStatus.PortStatus) == FALSE) {
+ //
+ // First reset and enable this port
+ //
+ PeiResetHubPort( PeiServices, UsbIoPpi, Port );
+
+ PeiHubGetPortStatus( PeiServices, UsbIoPpi,
+ Port, (UINT32 *) &PortStatus );
+ }
+
+ //
+ // Begin to deal with the new device
+ //
+ Status = (*PeiServices)->AllocatePool( PeiServices,
+ sizeof(PEI_USB_DEVICE), &AllocateAddress );
+ if ( EFI_ERROR( Status ) ) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ NewPeiUsbDevice = (PEI_USB_DEVICE *)AllocateAddress;
+
+ ZeroMem( NewPeiUsbDevice, sizeof(PEI_USB_DEVICE) );
+
+ NewPeiUsbDevice->Signature =
+ PEI_USB_DEVICE_SIGNATURE;
+ NewPeiUsbDevice->DeviceAddress = 0;
+ NewPeiUsbDevice->MaxPacketSize0 = 8;
+ NewPeiUsbDevice->DataToggle = 0;
+ NewPeiUsbDevice->UsbIoPpi = mUsbIoPpi;
+ NewPeiUsbDevice->UsbIoPpiList = mUsbIoPpiList;
+ NewPeiUsbDevice->UsbIoPpiList.Ppi =
+ &NewPeiUsbDevice->UsbIoPpi;
+ NewPeiUsbDevice->UsbHcPpi =
+ PeiUsbDevice->UsbHcPpi;
+ NewPeiUsbDevice->DeviceSpeed =
+ USB_FULL_SPEED_DEVICE;
+ NewPeiUsbDevice->IsHub = 0x0;
+ NewPeiUsbDevice->DownStreamPortNo = 0x0;
+ NewPeiUsbDevice->TransactionTranslator =
+ (UINT16)(Port << 7) + PeiUsbDevice->DeviceAddress;
+ NewPeiUsbDevice->HubDepth = 0x0;
+ //(EIP28255+)>
+ if ( (PeiUsbDevice->DeviceSpeed == USB_SLOW_SPEED_DEVICE) ||
+ (PeiUsbDevice->DeviceSpeed == USB_FULL_SPEED_DEVICE) )
+ {
+ NewPeiUsbDevice->TransactionTranslator = PeiUsbDevice->TransactionTranslator;
+ }
+ //<(EIP28255+)
+ if ( IsPortLowSpeedDeviceAttached( PortStatus.PortStatus ) )
+ {
+ NewPeiUsbDevice->DeviceSpeed = USB_SLOW_SPEED_DEVICE;
+ }
+
+ if ( IsPortHighSpeedDeviceAttached( PortStatus.PortStatus ) )
+ {
+ NewPeiUsbDevice->DeviceSpeed = USB_HIGH_SPEED_DEVICE;
+ }
+
+ if ( IsPortSuperSpeedDeviceAttached( PortStatus.PortStatus ) )
+ {
+ NewPeiUsbDevice->DeviceSpeed = USB_SUPER_SPEED_DEVICE;
+ }
+
+ //
+ // Configure that Usb Device
+ //
+ Status = PeiConfigureUsbDevice( PeiServices,
+ NewPeiUsbDevice, Port, CurrentAddress );
+
+ if ( EFI_ERROR( Status ) ) {
+ PeiHubClearPortFeature( PeiServices, UsbIoPpi,
+ Port, EfiUsbPortEnable );
+ continue;
+ }
+
+ Status = (**PeiServices).InstallPpi( PeiServices,
+ &NewPeiUsbDevice->UsbIoPpiList );
+
+ if (NewPeiUsbDevice->InterfaceDesc->InterfaceClass
+ == BASE_CLASS_HUB)
+ {
+ NewPeiUsbDevice->IsHub = 0x1;
+ NewPeiUsbDevice->HubDepth = PeiUsbDevice->HubDepth + 1;
+
+ Status = PeiDoHubConfig( PeiServices,
+ NewPeiUsbDevice );
+ if ( EFI_ERROR( Status ) ) {
+ return Status;
+ }
+ PeiHubEnumeration( PeiServices, NewPeiUsbDevice,
+ CurrentAddress );
+ }
+ }
+
+ }
+ }
+
+ if (PortChanged) {
+ break;
+ }
+ StallPpi->Stall( PeiServices, StallPpi, 50000 );
+
+ } while (Delay--);
+
+ return EFI_SUCCESS;
+}
+
+
+STATIC
+EFI_STATUS PeiUsbEnumeration (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_USB_HOST_CONTROLLER_PPI *UsbHcPpi )
+{
+ UINT8 NumOfRootPort;
+ EFI_STATUS Status;
+ UINT8 Port;
+ EFI_USB_PORT_STATUS PortStatus;
+ PEI_USB_DEVICE *PeiUsbDevice;
+ UINT8 *AllocateAddress;
+ UINT8 CurrentAddress;
+ PEI_STALL_PPI *PeiStall;
+
+ (**PeiServices).LocatePpi(
+ PeiServices,
+ &gPeiStallPpiGuid,
+ 0,
+ NULL,
+ &PeiStall
+ );
+
+ CurrentAddress = 0;
+ UsbHcPpi->GetRootHubPortNumber(
+ PeiServices,
+ UsbHcPpi,
+ (UINT8 *) &NumOfRootPort
+ );
+
+
+ for (Port = 1; Port <= NumOfRootPort; Port++) {
+ //
+ // First get root port status to detect changes happen
+ //
+ UsbHcPpi->GetRootHubPortStatus(
+ PeiServices,
+ UsbHcPpi,
+ Port,
+ &PortStatus
+ );
+
+ if ( IsPortConnectChange( PortStatus.PortChangeStatus ) ) {
+
+ //
+ // Changes happen, first clear this change status
+ //
+ UsbHcPpi->ClearRootHubPortFeature(
+ PeiServices,
+ UsbHcPpi,
+ Port,
+ EfiUsbPortConnectChange
+ );
+
+ if ( IsPortConnect( PortStatus.PortStatus ) ) {
+
+ if (IsPortEnable(PortStatus.PortStatus) == FALSE) {
+ //
+ // First reset and enable this port
+ //
+ ResetRootPort( PeiServices, UsbHcPpi, Port );
+
+ UsbHcPpi->GetRootHubPortStatus(
+ PeiServices,
+ UsbHcPpi,
+ Port,
+ &PortStatus
+ );
+ }
+
+ //
+ // Connect change happen
+ //
+ Status = (*PeiServices)->AllocatePool(
+ PeiServices,
+ sizeof(PEI_USB_DEVICE),
+ &AllocateAddress
+ );
+ if ( EFI_ERROR( Status ) ) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ PeiUsbDevice = (PEI_USB_DEVICE *) ( (UINTN) AllocateAddress );
+ ZeroMem( PeiUsbDevice, sizeof(PEI_USB_DEVICE) );
+
+ PeiUsbDevice->Signature = PEI_USB_DEVICE_SIGNATURE;
+ PeiUsbDevice->DeviceAddress = 0;
+ PeiUsbDevice->MaxPacketSize0 = 8;
+ PeiUsbDevice->DataToggle = 0;
+ PeiUsbDevice->UsbIoPpi = mUsbIoPpi;
+ PeiUsbDevice->UsbIoPpiList = mUsbIoPpiList;
+ PeiUsbDevice->UsbIoPpiList.Ppi = &PeiUsbDevice->UsbIoPpi;
+ PeiUsbDevice->UsbHcPpi = UsbHcPpi;
+ PeiUsbDevice->DeviceSpeed = USB_FULL_SPEED_DEVICE;
+ PeiUsbDevice->IsHub = 0x0;
+ PeiUsbDevice->DownStreamPortNo = 0x0;
+ PeiUsbDevice->TransactionTranslator = 0x0;
+ PeiUsbDevice->HubDepth = 0x0;
+
+ if ( IsPortLowSpeedDeviceAttached( PortStatus.PortStatus ) )
+ {
+ PeiUsbDevice->DeviceSpeed = USB_SLOW_SPEED_DEVICE;
+ }
+
+ if ( IsPortHighSpeedDeviceAttached( PortStatus.PortStatus ) )
+ {
+ PeiUsbDevice->DeviceSpeed = USB_HIGH_SPEED_DEVICE;
+ }
+
+ if ( IsPortSuperSpeedDeviceAttached( PortStatus.PortStatus ) )
+ {
+ PeiUsbDevice->DeviceSpeed = USB_SUPER_SPEED_DEVICE;
+ }
+
+ //
+ // Delay some times to enable usb devices to initiate.
+ //
+ PeiStall->Stall(
+ PeiServices,
+ PeiStall,
+ 5000
+ );
+
+ //
+ // Configure that Usb Device
+ //
+ Status = PeiConfigureUsbDevice(
+ PeiServices,
+ PeiUsbDevice,
+ Port,
+ &CurrentAddress
+ );
+
+ if ( EFI_ERROR( Status ) ) {
+ UsbHcPpi->ClearRootHubPortFeature(
+ PeiServices,
+ UsbHcPpi,
+ Port,
+ EfiUsbPortEnable
+ );
+ continue;
+ }
+
+ Status = (**PeiServices).InstallPpi(
+ PeiServices,
+ &PeiUsbDevice->UsbIoPpiList
+ );
+
+ if (PeiUsbDevice->InterfaceDesc->InterfaceClass
+ == BASE_CLASS_HUB)
+ {
+ PeiUsbDevice->IsHub = 0x1;
+
+ Status = PeiDoHubConfig( PeiServices, PeiUsbDevice );
+ if ( EFI_ERROR( Status ) ) {
+ return Status;
+ }
+
+ PeiHubEnumeration( PeiServices, PeiUsbDevice,
+ &CurrentAddress );
+ }
+ }
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+STATIC EFI_STATUS PeiConfigureUsbDevice (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_USB_DEVICE *PeiUsbDevice,
+ IN UINT8 Port,
+ IN OUT UINT8 *DeviceAddress )
+{
+ EFI_USB_DEVICE_DESCRIPTOR DeviceDescriptor;
+ EFI_STATUS Status;
+ PEI_USB_IO_PPI *UsbIoPpi;
+ UINT8 i;
+ PEI_STALL_PPI *StallPpi = NULL;
+ UINT8 Retry = 2;
+
+ ( **PeiServices ).LocatePpi( PeiServices, &gPeiStallPpiGuid,
+ 0, NULL, &StallPpi );
+
+ if (PeiUsbDevice->UsbHcPpi->PreConfigureDevice != NULL) {
+ Status = PeiUsbDevice->UsbHcPpi->PreConfigureDevice( PeiServices,
+ PeiUsbDevice->UsbHcPpi, Port, PeiUsbDevice->DeviceSpeed,
+ PeiUsbDevice->TransactionTranslator);
+ if ( EFI_ERROR( Status ) ) {
+ return Status;
+ }
+ }
+
+ UsbIoPpi = &PeiUsbDevice->UsbIoPpi;
+
+ //-----------------------------------------------------------------------
+ // Try 5 times to read the first 8 bytes to determine the size
+ for (i = 0; i < 5; i++) {
+ Status = PeiUsbGetDescriptor( PeiServices,
+ UsbIoPpi,
+ SET_DESCRIPTOR_TYPE( USB_DT_DEVICE ), // Value = Type << 8 | Index
+ 0, // Index
+ 8, // DescriptorLength
+ &DeviceDescriptor );
+ if ( !EFI_ERROR( Status ) ) {
+ break;
+ }
+ StallPpi->Stall( PeiServices, StallPpi, 100 * 1000 ); // 100msec delay
+ }
+ if ( EFI_ERROR( Status ) ) {
+ return Status;
+ }
+
+ //-----------------------------------------------------------------------
+ // Set MaxPacketSize0 = 0x40 if packet size is not specified
+ PeiUsbDevice->MaxPacketSize0 = (DeviceDescriptor.MaxPacketSize0)
+ ? DeviceDescriptor.MaxPacketSize0
+ : 0x40;
+
+
+ //-----------------------------------------------------------------------
+ // Get the entire USB device descriptor
+ StallPpi->Stall( PeiServices, StallPpi, 10 * 1000 ); // 10msec delay
+ Status = PeiUsbGetDescriptor(
+ PeiServices,
+ UsbIoPpi,
+ SET_DESCRIPTOR_TYPE( USB_DT_DEVICE ), // Value = Type << 8 | Index
+ 0, // Index
+ sizeof(EFI_USB_DEVICE_DESCRIPTOR), // DescriptorLength
+ &DeviceDescriptor );
+
+ if ( EFI_ERROR( Status ) ) {
+ return Status;
+ }
+
+ //-----------------------------------------------------------------------
+ // Get its default configuration and its first interface
+ StallPpi->Stall( PeiServices, StallPpi, 10 * 1000 ); // 10msec delay
+ Status = PeiUsbGetAllConfiguration(
+ PeiServices,
+ PeiUsbDevice );
+ if ( EFI_ERROR( Status ) ) {
+ return Status;
+ }
+
+ //-----------------------------------------------------------------------
+ // Set the device's address
+ StallPpi->Stall( PeiServices, StallPpi, 10 * 1000 ); // 10msec delay
+ (*DeviceAddress)++;
+ Status = PeiUsbSetDeviceAddress(
+ PeiServices,
+ UsbIoPpi,
+ *DeviceAddress );
+ if ( EFI_ERROR( Status ) ) {
+ return Status;
+ }
+ PeiUsbDevice->DeviceAddress = *DeviceAddress;
+
+
+ StallPpi->Stall( PeiServices, StallPpi, 200 * 1000 ); // 200msec delay
+
+ Status = PeiUsbSetConfiguration(
+ PeiServices,
+ UsbIoPpi );
+
+ if ( EFI_ERROR( Status ) ) {
+ return Status;
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+STATIC EFI_STATUS PeiUsbGetAllConfiguration (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_USB_DEVICE *Device )
+{
+ EFI_USB_CONFIG_DESCRIPTOR ConfigDesc = {0};
+ EFI_USB_ENDPOINT_DESCRIPTOR *EndPointDesc = NULL; //(EIP32503+)
+ EFI_STATUS Status;
+ PEI_USB_IO_PPI *UsbIoPpi = &Device->UsbIoPpi;
+ UINTN i;
+ UINT8 *LastAddress = 0;
+
+
+ // Here we are parsing the descriptors for the device
+ // configurations where the hierarchy of descriptors
+ // is as follows:
+ //
+ // +----------------+
+ // | Configuration1 |
+ // +----------------+
+ // | +------------+
+ // +---------| Interface1 |----+------------------+
+ // | +------------+ | |
+ // | +-----------+ +-------------+
+ // | | Endpoint1 | ... | EndpointMax |
+ // | +-----------+ +-------------+
+ // | :
+ // | :
+ // | :
+ // |
+ // | +--------------+
+ // +---------| InterfaceMax |----+------------------+
+ // +--------------+ | |
+ // : +-----------+ +-------------+
+ // : | Endpoint1 | ... | EndpointMax |
+ // +-----------+ +-------------+
+ // +------------------+
+ // | ConfigurationMax |
+ // +------------------+
+ // | +------------+
+ // +---------| Interface1 |----+------------------+
+ // | +------------+ | |
+ // | +-----------+ +-------------+
+ // | | Endpoint1 | ... | EndpointMax |
+ // | +-----------+ +-------------+
+ // | :
+ // | :
+ // | :
+ // | +--------------+
+ // +---------| InterfaceMax |----+------------------+
+ // +--------------+ | |
+ // +-----------+ +-------------+
+ // | Endpoint1 | ... | EndpointMax |
+ // +-----------+ +-------------+
+
+
+ //-------------------------------------------------------------
+ // Fortunately, we are only interested in the first/default
+ // configuration and its first/default interface, so life is
+ // simple!
+ //-------------------------------------------------------------
+
+ //-------------------------------------------------------------
+ // First get the device's 9-byte configuration descriptor to
+ // determine the length of all descriptors
+ Status = PeiUsbGetDescriptor(
+ PeiServices,
+ UsbIoPpi,
+ USB_DT_CONFIG << 8,
+ 0,
+ 9,
+ &ConfigDesc );
+ if ( EFI_ERROR( Status ) ) {
+ return Status;
+ }
+
+ Status = (*PeiServices)->AllocatePool( PeiServices,
+ ConfigDesc.TotalLength, &Device->ConfigurationData );
+ if ( EFI_ERROR( Status ) ) {
+ return Status;
+ }
+ //-------------------------------------------------------------
+ // Get all the descriptors for this configuration using
+ // TotalLength from the first 9 bytes previously read.
+ // Then, save the Configuration descriptor into the
+ // device management structure.
+ Status = PeiUsbGetDescriptor(
+ PeiServices,
+ UsbIoPpi,
+ USB_DT_CONFIG << 8,
+ 0,
+ ConfigDesc.TotalLength,
+ (VOID *) Device->ConfigurationData );
+ if ( EFI_ERROR( Status ) ) {
+ return Status;
+ }
+ Device->ConfigDesc =
+ (EFI_USB_CONFIG_DESCRIPTOR *) Device->ConfigurationData;
+
+ LastAddress = Device->ConfigurationData +
+ Device->ConfigDesc->TotalLength - 1;
+
+ if (Device->UsbHcPpi->EnableEndpoints != NULL) {
+ Status = Device->UsbHcPpi->EnableEndpoints(PeiServices,
+ Device->UsbHcPpi, Device->ConfigurationData);
+
+ if ( EFI_ERROR( Status ) ) {
+ return Status;
+ }
+ }
+
+ //--------------------------------------------------------------
+ // Assume the Interface descriptor is directly after the
+ // configuration descriptor.
+ //--------------------------------------------------------------
+ Device->InterfaceDesc = (EFI_USB_INTERFACE_DESCRIPTOR *)
+ ( (UINT8 *) Device->ConfigDesc +
+ Device->ConfigDesc->Length );
+ //(EIP32503+)>
+ while ((UINT8 *)Device->InterfaceDesc < LastAddress &&
+ Device->InterfaceDesc->DescriptorType != USB_DT_INTERFACE)
+ {
+ Device->InterfaceDesc = (EFI_USB_INTERFACE_DESCRIPTOR *)
+ ( (UINT8 *) Device->InterfaceDesc +
+ Device->InterfaceDesc->Length );
+ }
+ //<(EIP32503+)
+ //--------------------------------------------------------------
+ // Assume the first Endpoint descriptor is directly after the
+ // Interface descriptor.
+ //--------------------------------------------------------------
+ //(EIP32503)>
+ EndPointDesc = (EFI_USB_ENDPOINT_DESCRIPTOR *)
+ ( (UINT8 *) Device->InterfaceDesc +
+ Device->InterfaceDesc->Length );
+
+ for (i = 0; i < Device->InterfaceDesc->NumEndpoints &&
+ (UINT8 *)EndPointDesc < LastAddress; )
+ {
+ if(EndPointDesc->DescriptorType == USB_DT_ENDPOINT)
+ {
+ Device->EndpointDesc[i++] = EndPointDesc;
+ }
+ EndPointDesc = (EFI_USB_ENDPOINT_DESCRIPTOR *)
+ ( (UINT8 *) EndPointDesc +
+ EndPointDesc->Length );
+ }
+ //<(EIP32503)
+ return EFI_SUCCESS;
+}
+
+
+//
+// Send reset signal over the given root hub port
+//
+VOID ResetRootPort (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_USB_HOST_CONTROLLER_PPI *UsbHcPpi,
+ UINT8 PortNum )
+{
+ EFI_PEI_STALL_PPI *PeiStall;
+ EFI_USB_PORT_STATUS PortStatus;
+ UINT8 i;
+
+ ( **PeiServices ).LocatePpi(
+ PeiServices,
+ &gPeiStallPpiGuid,
+ 0,
+ NULL,
+ &PeiStall
+ );
+
+
+ //
+ // reset root port
+ //
+ UsbHcPpi->SetRootHubPortFeature(
+ PeiServices,
+ UsbHcPpi,
+ PortNum,
+ EfiUsbPortReset
+ );
+
+ for (i = 0; i < 100; i++) {
+ UsbHcPpi->GetRootHubPortStatus(
+ PeiServices,
+ UsbHcPpi,
+ PortNum,
+ &PortStatus
+ );
+
+ if ((PortStatus.PortChangeStatus & USB_PORT_STAT_C_RESET) != 0) {
+ break;
+ }
+
+ PeiStall->Stall(
+ PeiServices,
+ PeiStall,
+ 1 * 1000 // NVS - Changed to 10 msec (as per AMI USB Code)
+ );
+ }
+
+ if ((PortStatus.PortChangeStatus & USB_PORT_STAT_C_RESET) == 0) {
+ return;
+ }
+
+ //
+ // clear reset root port
+ //
+ UsbHcPpi->ClearRootHubPortFeature(
+ PeiServices,
+ UsbHcPpi,
+ PortNum,
+ EfiUsbPortResetChange
+ );
+
+
+ UsbHcPpi->GetRootHubPortStatus(
+ PeiServices,
+ UsbHcPpi,
+ PortNum,
+ &PortStatus
+ );
+
+ if ((PortStatus.PortChangeStatus & USB_PORT_STAT_ENABLE) == 0) {
+ //
+ // Set port enable
+ //
+ UsbHcPpi->SetRootHubPortFeature(
+ PeiServices,
+ UsbHcPpi,
+ PortNum,
+ EfiUsbPortEnable
+ );
+ PeiStall->Stall(
+ PeiServices,
+ PeiStall,
+ 100 * 1000 // NVS - Changed to 100msec as per AMI USB code
+ );
+ }
+
+ return;
+}
+
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2008, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//********************************************************************** \ No newline at end of file
diff --git a/Core/EM/UsbRecovery/UsbPeimSrc/UsbPeimSrc.cif b/Core/EM/UsbRecovery/UsbPeimSrc/UsbPeimSrc.cif
new file mode 100644
index 0000000..4eca72e
--- /dev/null
+++ b/Core/EM/UsbRecovery/UsbPeimSrc/UsbPeimSrc.cif
@@ -0,0 +1,12 @@
+<component>
+ name = "UsbPeimSrc"
+ category = ModulePart
+ LocalRoot = "Core\EM\UsbRecovery\UsbPeimSrc\"
+ RefName = "UsbPeimSrc"
+[files]
+"HubPeim.c"
+"UsbIoPeim.c"
+"UsbPeim.c"
+[parts]
+"UsbIoPpi"
+<endComponent>