diff options
Diffstat (limited to 'Core/EM/UsbRecovery/UsbPeimSrc/HubPeim.c')
-rw-r--r-- | Core/EM/UsbRecovery/UsbPeimSrc/HubPeim.c | 889 |
1 files changed, 889 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 |