From b7c51c9cf4864df6aabb99a1ae843becd577237c Mon Sep 17 00:00:00 2001 From: raywu Date: Fri, 15 Jun 2018 00:00:50 +0800 Subject: init. 1AQQW051 --- Core/EM/UsbRecovery/UsbBotPeimSrc/BotPeim.c | 482 ++++++++++++++++++++++++++++ 1 file changed, 482 insertions(+) create mode 100644 Core/EM/UsbRecovery/UsbBotPeimSrc/BotPeim.c (limited to 'Core/EM/UsbRecovery/UsbBotPeimSrc/BotPeim.c') diff --git a/Core/EM/UsbRecovery/UsbBotPeimSrc/BotPeim.c b/Core/EM/UsbRecovery/UsbBotPeimSrc/BotPeim.c new file mode 100644 index 0000000..7ebdb88 --- /dev/null +++ b/Core/EM/UsbRecovery/UsbBotPeimSrc/BotPeim.c @@ -0,0 +1,482 @@ +//********************************************************************** +//********************************************************************** +//** ** +//** (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/UsbBotPeimSrc/BotPeim.c 7 11/24/12 5:47a Ryanchou $ +// +// $Revision: 7 $ +// +// $Date: 11/24/12 5:47a $ +// +//********************************************************************** +// Revision History +// ---------------- +// $Log: /Alaska/SOURCE/Modules/USBRecovery/UsbBotPeimSrc/BotPeim.c $ +// +// 7 11/24/12 5:47a 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 +// +// 6 4/16/11 3:41a Ryanchou +// [TAG] EIP50311 +// [Category] New Feature +// [Description] Multiple LUN device support added. +// [Files] BotPeim.c, UsbBotPeim.c, UsbBotPeim.h +// +// 5 2/18/11 2:13a Ryanchou +// [TAG] EIP52191 +// [Category] Bug Fix +// [Severity] Minor +// [Symptom] Recovery from card reader causes "EHCI Time-Out". +// [RootCause] The card reader returns zero length during BOT data +// transport, BIOS will do data transport again if the remain data length +// isn't zero, then CSW will be received in data transport phase. +// [Solution] Added the code that check if the transfered length is less +// than expect length, break the loop. +// [Files] BotPeim.c +// +// 4 4/06/10 3:27p Fasihm +// EIP#31987 - Added the generic USBRecovery Fix in the module. +// +// 3 7/10/08 6:38p Michaela +// Updated to support OHCI controllers +// +// 2 8/17/07 4:12p Ambikas +// +// 1 9/22/06 12:17p Sivagarn +// - Included Recovery code in Source +// +// 1 9/22/06 12:14p Sivagarn +// - Initial checkin +// - Included Recovery code in Source +// +//***************************************************************************** + +// +//---------------------------------------------------------------------------- +// +// Name: BotPeim.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 +// Mass Storage BOT PEIM +// +//---------------------------------------------------------------------------- +// + +/*++ + This file contains a 'Sample Driver' and is licensed as such + under the terms of your license agreement with Intel or your + vendor. This file may be modified by the user, subject to + the additional terms of the 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: + + BotPeim.c + + Abstract: + + BOT Transportation implementation + + --*/ + +#include "UsbBotPeim.h" +#include "BotPeim.h" +#include "PeiUsbLib.h" + +extern VOID ZeroMem ( + IN VOID *Buffer, + IN UINTN Size ); +extern VOID PeiCopyMem ( + IN VOID *Destination, + IN VOID *Source, + IN UINTN Length ); + + +STATIC +EFI_STATUS BotRecoveryReset ( + IN EFI_PEI_SERVICES **PeiServices, + IN PEI_BOT_DEVICE *PeiBotDev ) +{ + EFI_USB_DEVICE_REQUEST DevReq; + UINT32 Timeout; + PEI_USB_IO_PPI *UsbIoPpi; + UINT8 EndpointAddr; + EFI_STATUS Status; + + UsbIoPpi = PeiBotDev->UsbIoPpi; + + if (UsbIoPpi == NULL) { + return EFI_INVALID_PARAMETER; + } + + ZeroMem( &DevReq, sizeof(EFI_USB_DEVICE_REQUEST) ); + + DevReq.RequestType = 0x21; + DevReq.Request = 0xff; + DevReq.Value = 0; + DevReq.Index = 0; + DevReq.Length = 0; + + Timeout = 3000; + + Status = UsbIoPpi->UsbControlTransfer( + PeiServices, + UsbIoPpi, + &DevReq, + EfiUsbNoData, + Timeout, + NULL, + 0 + ); + + // + // clear bulk in endpoint stall feature + // + EndpointAddr = (PeiBotDev->BulkInEndpoint)->EndpointAddress; + PeiUsbClearEndpointHalt( PeiServices, UsbIoPpi, EndpointAddr ); + + // + // clear bulk out endpoint stall feature + // + EndpointAddr = (PeiBotDev->BulkOutEndpoint)->EndpointAddress; + PeiUsbClearEndpointHalt( PeiServices, UsbIoPpi, EndpointAddr ); + + return Status; +} + + +STATIC +EFI_STATUS BotCommandPhase ( + IN EFI_PEI_SERVICES **PeiServices, + IN PEI_BOT_DEVICE *PeiBotDev, + IN VOID *Command, + IN UINT8 CommandSize, + IN UINT32 DataTransferLength, + IN EFI_USB_DATA_DIRECTION Direction, + IN UINT16 Timeout ) +{ + CBW cbw; + EFI_STATUS Status; + PEI_USB_IO_PPI *UsbIoPpi; + UINTN DataSize; + + UsbIoPpi = PeiBotDev->UsbIoPpi; + + ZeroMem( &cbw, sizeof(CBW) ); + + // + // Fill the command block, detailed see BOT spec + // + cbw.dCBWSignature = CBWSIG; + cbw.dCBWTag = 0x01; + cbw.dCBWDataTransferLength = DataTransferLength; + cbw.bmCBWFlags = (Direction == EfiUsbDataIn)? 0x80 : 0; + cbw.bCBWLUN = PeiBotDev->Lun; + cbw.bCBWCBLength = CommandSize; + + PeiCopyMem( cbw.CBWCB, Command, CommandSize ); + + DataSize = sizeof(CBW); + + Status = UsbIoPpi->UsbBulkTransfer( + PeiServices, + UsbIoPpi, + (PeiBotDev->BulkOutEndpoint)->EndpointAddress, + (UINT8 *) &cbw, + &DataSize, + Timeout + ); + if ( EFI_ERROR( Status ) ) { + // + // Command phase fail, we need to recovery reset this device + // + BotRecoveryReset( PeiServices, PeiBotDev ); + return EFI_DEVICE_ERROR; + } + + return EFI_SUCCESS; +} + + +STATIC +EFI_STATUS BotDataPhase ( + IN EFI_PEI_SERVICES **PeiServices, + IN PEI_BOT_DEVICE *PeiBotDev, + IN UINT32 *DataSize, + IN OUT VOID *DataBuffer, + IN EFI_USB_DATA_DIRECTION Direction, + IN UINT16 Timeout ) +{ + EFI_STATUS Status; + PEI_USB_IO_PPI *UsbIoPpi; + UINT8 EndpointAddr; + UINTN Remain; + UINTN Increment; + UINT32 MaxPacketLen; + UINT8 *BufferPtr; + UINTN TransferredSize; + UINTN TransferSize; + + UsbIoPpi = PeiBotDev->UsbIoPpi; + + Remain = *DataSize; + BufferPtr = (UINT8 *) DataBuffer; + TransferredSize = 0; + + // + // retrieve the the max packet length of the given endpoint + // + if (Direction == EfiUsbDataIn) { + MaxPacketLen = (PeiBotDev->BulkInEndpoint)->MaxPacketSize; + EndpointAddr = (PeiBotDev->BulkInEndpoint)->EndpointAddress; + } + else { + MaxPacketLen = (PeiBotDev->BulkOutEndpoint)->MaxPacketSize; + EndpointAddr = (PeiBotDev->BulkOutEndpoint)->EndpointAddress; + } + + while (Remain > 0) { + // + // Using 15 packets to avoid Bitstuff error + // + if (Remain > 16 * MaxPacketLen) { + TransferSize = 16 * MaxPacketLen; + } + else { + TransferSize = Remain; + } + + Increment = TransferSize; + + Status = UsbIoPpi->UsbBulkTransfer( + PeiServices, + UsbIoPpi, + EndpointAddr, + BufferPtr, + &Increment, + Timeout + ); + + TransferredSize += Increment; + + if ( EFI_ERROR( Status ) ) { + PeiUsbClearEndpointHalt( PeiServices, UsbIoPpi, EndpointAddr ); + return Status; + } + + if (Increment < TransferSize) { + break; + } + + BufferPtr += Increment; + Remain -= Increment; + } + + *DataSize = (UINT32) TransferredSize; + + return EFI_SUCCESS; +} + + +STATIC +EFI_STATUS BotStatusPhase ( + IN EFI_PEI_SERVICES **PeiServices, + IN PEI_BOT_DEVICE *PeiBotDev, + OUT UINT8 *TransferStatus, + IN UINT16 Timeout ) +{ + CSW csw; + EFI_STATUS Status; + PEI_USB_IO_PPI *UsbIoPpi; + UINT8 EndpointAddr; + UINTN DataSize; + + //UINT32 Temp; + + UsbIoPpi = PeiBotDev->UsbIoPpi; + + ZeroMem( &csw, sizeof(CSW) ); + + EndpointAddr = (PeiBotDev->BulkInEndpoint)->EndpointAddress; + + // DataSize = sizeof(CSW); + DataSize = 0x0d; //bala changed + + // + // Get the status field from bulk transfer + // + Status = UsbIoPpi->UsbBulkTransfer( + PeiServices, + UsbIoPpi, + EndpointAddr, + &csw, + &DataSize, + Timeout + ); + + if ( EFI_ERROR( Status ) ) { + return Status; + } + + if (csw.dCSWSignature == CSWSIG) + { + *TransferStatus = csw.bCSWStatus; + } + else { + return EFI_DEVICE_ERROR; + } + + return EFI_SUCCESS; +} + + +EFI_STATUS PeiAtapiCommand ( + IN EFI_PEI_SERVICES **PeiServices, + IN PEI_BOT_DEVICE *PeiBotDev, + IN VOID *Command, + IN UINT8 CommandSize, + IN VOID *DataBuffer, + IN UINT32 BufferLength, + IN EFI_USB_DATA_DIRECTION Direction, + IN UINT16 TimeOutInMilliSeconds ) + +/*++ + + Routine Description: + Send ATAPI command using BOT protocol. + + Arguments: + This - Protocol instance pointer. + Command - Command buffer + CommandSize - Size of Command Buffer + DataBuffer - Data buffer + BufferLength - Length of Data buffer + Direction - Data direction of this command + TimeoutInMilliseconds - Timeout value in ms + + Returns: + EFI_SUCCES - Commond succeeded. + EFI_DEVICE_ERROR - Command failed. + + --*/ +{ + EFI_STATUS Status; + EFI_STATUS BotDataStatus = EFI_SUCCESS; + UINT8 TransferStatus; + UINT32 BufferSize; + UINT8 *Tmp; + UINT32 Temp; + + Tmp = (UINT8 *) Command; + Temp = Tmp[0]; + PEI_TRACE( (EFI_D_ERROR, PeiServices, "Executing ScsiCmd(%x)\n", Temp) ); + // + // First send ATAPI command through Bot + // + Status = BotCommandPhase( + PeiServices, + PeiBotDev, + Command, + CommandSize, + BufferLength, + Direction, + TimeOutInMilliSeconds + ); + + if ( EFI_ERROR( Status ) ) { + return EFI_DEVICE_ERROR; + } + + // + // Send/Get Data if there is a Data Stage + // + switch (Direction) + { + case EfiUsbDataIn: + case EfiUsbDataOut: + BufferSize = BufferLength; + + BotDataStatus = BotDataPhase( + PeiServices, + PeiBotDev, + &BufferSize, + DataBuffer, + Direction, + TimeOutInMilliSeconds + ); + + break; + + case EfiUsbNoData: + break; + } + + // + // Status Phase + // + + Status = BotStatusPhase( + PeiServices, + PeiBotDev, + &TransferStatus, + TimeOutInMilliSeconds + ); + if ( EFI_ERROR( Status ) ) { + BotRecoveryReset( PeiServices, PeiBotDev ); + return EFI_DEVICE_ERROR; + } + + if (TransferStatus == 0x01) { + return EFI_DEVICE_ERROR; + } + + return BotDataStatus; +} + + +//********************************************************************** +//********************************************************************** +//** ** +//** (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 -- cgit v1.2.3