summaryrefslogtreecommitdiff
path: root/Core/EM/UsbRecovery/UsbBotPeimSrc
diff options
context:
space:
mode:
Diffstat (limited to 'Core/EM/UsbRecovery/UsbBotPeimSrc')
-rw-r--r--Core/EM/UsbRecovery/UsbBotPeimSrc/BotPeim.c482
-rw-r--r--Core/EM/UsbRecovery/UsbBotPeimSrc/BotPeim.h201
-rw-r--r--Core/EM/UsbRecovery/UsbBotPeimSrc/PeiAtapi.c832
-rw-r--r--Core/EM/UsbRecovery/UsbBotPeimSrc/UsbBotPeim.c726
-rw-r--r--Core/EM/UsbRecovery/UsbBotPeimSrc/UsbBotPeim.cif14
-rw-r--r--Core/EM/UsbRecovery/UsbBotPeimSrc/UsbBotPeim.dxs106
-rw-r--r--Core/EM/UsbRecovery/UsbBotPeimSrc/UsbBotPeim.h362
-rw-r--r--Core/EM/UsbRecovery/UsbBotPeimSrc/atapi.h418
8 files changed, 3141 insertions, 0 deletions
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
+//
+//*****************************************************************************
+
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------------
+//
+// 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
+//
+//----------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+/*++
+ 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
diff --git a/Core/EM/UsbRecovery/UsbBotPeimSrc/BotPeim.h b/Core/EM/UsbRecovery/UsbBotPeimSrc/BotPeim.h
new file mode 100644
index 0000000..25c3e56
--- /dev/null
+++ b/Core/EM/UsbRecovery/UsbBotPeimSrc/BotPeim.h
@@ -0,0 +1,201 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (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/UsbBotPeimSrc/BotPeim.h 5 11/24/12 5:47a Ryanchou $
+//
+// $Revision: 5 $
+//
+// $Date: 11/24/12 5:47a $
+//
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/USBRecovery/UsbBotPeimSrc/BotPeim.h $
+//
+// 5 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
+//
+// 4 7/10/08 6:38p Michaela
+// Updated to support OHCI controllers
+//
+// 3 4/16/07 12:46p 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:40a Meenakshim
+//
+// 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
+//
+//*****************************************************************************
+
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: BotPeim.h
+//
+// Description: This file belongs to "Framework".
+// This file is modified by AMI to include copyright message,
+// appropriate header and integration code.
+//
+//----------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+//
+// 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.h
+
+ Abstract:
+
+ BOT Transportation implementation
+
+ --*/
+
+#ifndef _PEI_BOT_PEIM_H
+#define _PEI_BOT_PEIM_H
+
+#define STATIC static
+
+#include "Atapi.h"
+#include "AmiPeiLib.h"
+
+#pragma pack(1)
+
+//
+//Bulk Only device protocol
+//
+typedef struct
+{
+ UINT32 dCBWSignature;
+ UINT32 dCBWTag;
+ UINT32 dCBWDataTransferLength;
+ UINT8 bmCBWFlags;
+ UINT8 bCBWLUN;
+ UINT8 bCBWCBLength;
+ UINT8 CBWCB[16];
+} CBW;
+
+typedef struct
+{
+ UINT32 dCSWSignature;
+ UINT32 dCSWTag;
+ UINT32 dCSWDataResidue;
+ UINT8 bCSWStatus;
+ UINT8 Filler[18];
+} CSW;
+
+#pragma pack()
+
+//
+// Status code, see Usb Bot device spec
+//
+#define CSWSIG 0x53425355
+#define CBWSIG 0x43425355
+
+EFI_STATUS
+PeiUsbInquiry (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_BOT_DEVICE *PeiBotDevice );
+
+EFI_STATUS
+PeiUsbTestUnitReady (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_BOT_DEVICE *PeiBotDevice );
+
+EFI_STATUS
+PeiUsbRequestSense (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_BOT_DEVICE *PeiBotDevice,
+ IN UINT8 *SenseKeyBuffer );
+
+EFI_STATUS
+PeiUsbReadCapacity (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_BOT_DEVICE *PeiBotDevice );
+
+EFI_STATUS
+PeiUsbReadFormattedCapacity (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_BOT_DEVICE *PeiBotDevice );
+
+EFI_STATUS
+PeiUsbRead10 (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_BOT_DEVICE *PeiBotDevice,
+ IN VOID *Buffer,
+ IN EFI_PEI_LBA Lba,
+ IN UINTN NumberOfBlocks );
+
+BOOLEAN
+IsNoMedia (
+ IN REQUEST_SENSE_DATA *SenseData,
+ IN UINTN SenseCounts );
+
+BOOLEAN
+IsMediaError (
+ IN REQUEST_SENSE_DATA *SenseData,
+ IN UINTN SenseCounts );
+
+BOOLEAN
+IsMediaChange (
+ IN REQUEST_SENSE_DATA *SenseData,
+ IN UINTN SenseCounts );
+
+#endif
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (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/UsbBotPeimSrc/PeiAtapi.c b/Core/EM/UsbRecovery/UsbBotPeimSrc/PeiAtapi.c
new file mode 100644
index 0000000..24917af
--- /dev/null
+++ b/Core/EM/UsbRecovery/UsbBotPeimSrc/PeiAtapi.c
@@ -0,0 +1,832 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (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/PeiAtapi.c 11 11/24/12 5:47a Ryanchou $
+//
+// $Revision: 11 $
+//
+// $Date: 11/24/12 5:47a $
+//
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/USBRecovery/UsbBotPeimSrc/PeiAtapi.c $
+//
+// 11 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
+//
+// 10 10/24/11 5:59a Ryanchou
+// [TAG] EIP69936
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] USB ODD recovery fail
+// [RootCause] The device needs 4 sec to respond to Inquiry command, the
+// current timeout value is 2 sec
+// [Solution] Increase the timeout value to 4 sec.
+// [Files] PeiAtapi.c
+//
+// 9 8/18/10 4:19p Olegi
+// Klockwork related fixes; EIP37978
+//
+// 8 4/06/10 3:27p Fasihm
+// EIP#31987 - Added the generic USBRecovery Fix in the module.
+//
+// 7 10/21/08 5:58p 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.)
+//
+// 6 7/29/08 5:51p 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
+//
+// 5 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)
+//
+// 4 7/10/08 6:38p Michaela
+// Updated to support OHCI controllers
+//
+// 3 8/17/07 4:35p Ambikas
+//
+// 2 10/02/06 7:24p Sivagarn
+// - Fixed the bug in identifying partition table entries
+// - Updated function headers and converted to AMI coding standard
+//
+// 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
+//
+//*****************************************************************************
+
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: PeiAtapi.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 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:
+
+ PeiAtapi.c
+
+ Abstract:
+
+ Pei USB ATATPI command implementations
+
+ --*/
+
+#include "UsbBotPeim.h"
+#include "BotPeim.h"
+#include "Atapi.h"
+
+#define MAXSENSEKEY 5
+
+// External function declaration
+
+extern VOID ZeroMem (
+ IN VOID *Buffer,
+ IN UINTN Size );
+
+// Function prototype
+
+VOID PeiUsbValidatePartitionTable (
+ EFI_PEI_SERVICES **PeiServices,
+ UINT8 *Buffer,
+ UINTN LastBlock,
+ UINT32 *FdEmulOffset );
+
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: PeiUsbInquiry
+//
+// Description: This function issues the ATA Inquiry command to the USB
+// mass storage device
+//
+// Input: **PeiServices Pointer to the PEI services table
+// *PeiBotDevice Pointer to the PEI_BOT_DEVICE structure
+//
+// Output: Return Status based on the command
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS PeiUsbInquiry (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_BOT_DEVICE *PeiBotDevice )
+{
+ ATAPI_PACKET_COMMAND Packet;
+ EFI_STATUS Status;
+ USB_INQUIRY_DATA Idata;
+
+ // Fill command packet
+ ZeroMem( &Packet, sizeof(ATAPI_PACKET_COMMAND) );
+ ZeroMem( &Idata, sizeof(USB_INQUIRY_DATA) );
+
+ Packet.Inquiry.opcode = INQUIRY;
+ Packet.Inquiry.page_code = 0;
+ Packet.Inquiry.allocation_length = sizeof(USB_INQUIRY_DATA);
+
+ // Send command packet
+ Status = PeiAtapiCommand( PeiServices, PeiBotDevice, &Packet,
+ sizeof(ATAPI_PACKET_COMMAND), &Idata,
+ sizeof(USB_INQUIRY_DATA), EfiUsbDataIn, 4000 ); //(EIP69936)
+ if ( EFI_ERROR( Status ) ) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ if ( (Idata.peripheral_type & 0x1f) == 0x05 ) {
+ PeiBotDevice->DeviceType = USBCDROM;
+ PeiBotDevice->Media.BlockSize = 0x800;
+ }
+ else {
+ PeiBotDevice->DeviceType = USBFLOPPY;
+ PeiBotDevice->Media.BlockSize = 0x200;
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: PeiUsbTestUnitReady
+//
+// Description: This function issues the ATA Test Unit Ready command to the USB
+// mass storage device
+//
+// Input: **PeiServices Pointer to the PEI services table
+// *PeiBotDevice Pointer to the PEI_BOT_DEVICE structure
+//
+// Output: Return Status based on the command
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS PeiUsbTestUnitReady (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_BOT_DEVICE *PeiBotDevice )
+{
+ EFI_STATUS Status;
+ ATAPI_PACKET_COMMAND Packet;
+
+ // Fill command packet
+ ZeroMem( &Packet, sizeof(ATAPI_PACKET_COMMAND) );
+ Packet.TestUnitReady.opcode = TEST_UNIT_READY;
+
+ // Send command packet
+ Status = PeiAtapiCommand( PeiServices, PeiBotDevice, &Packet,
+ sizeof(ATAPI_PACKET_COMMAND), NULL, 0, EfiUsbNoData,
+ 2000 );
+ if ( EFI_ERROR( Status ) ) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: PeiUsbRequestSense
+//
+// Description: This function issues the ATA Request Sense command to the USB
+// mass storage device
+//
+// Input: **PeiServices Pointer to the PEI services table
+// *PeiBotDevice Pointer to the PEI_BOT_DEVICE structure
+// *SenseCounts Buffer to return sense key data
+// *SenseKeyBuffer Buffer used for internal use
+//
+// Output: Return Status based on the command
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS PeiUsbRequestSense (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_BOT_DEVICE *PeiBotDevice,
+ IN UINT8 *SenseKeyBuffer )
+{
+ EFI_STATUS Status;
+ ATAPI_PACKET_COMMAND Packet;
+
+ // Fill command packet for Request Sense Packet Command
+ ZeroMem( &Packet, sizeof(ATAPI_PACKET_COMMAND) );
+ Packet.RequestSence.opcode = REQUEST_SENSE;
+ Packet.RequestSence.allocation_length = sizeof(REQUEST_SENSE_DATA);
+
+
+ // Send out Request Sense Packet Command and get one Sense
+ // data form device.
+ Status = PeiAtapiCommand( PeiServices, PeiBotDevice, &Packet,
+ sizeof(ATAPI_PACKET_COMMAND),
+ (VOID *) SenseKeyBuffer,
+ sizeof(REQUEST_SENSE_DATA),
+ EfiUsbDataIn,
+ 2000 );
+
+ // Failed to get Sense data
+ if ( EFI_ERROR( Status ) ) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: PeiUsbReadCapacity
+//
+// Description: This function issues the ATA Read Capacity command to the USB
+// mass storage device
+//
+// Input: **PeiServices Pointer to the PEI services table
+// *PeiBotDevice Pointer to the PEI_BOT_DEVICE structure
+//
+// Output: Return Status based on the command
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS PeiUsbReadCapacity (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_BOT_DEVICE *PeiBotDevice )
+{
+ EFI_STATUS Status;
+ ATAPI_PACKET_COMMAND Packet;
+ READ_CAPACITY_DATA Data;
+ UINT8 Buffer[512];
+
+
+ ZeroMem( &Data, sizeof(READ_CAPACITY_DATA) );
+ ZeroMem( &Packet, sizeof(ATAPI_PACKET_COMMAND) );
+
+ Packet.Inquiry.opcode = READ_CAPACITY;
+
+ // Send command packet
+ Status = PeiAtapiCommand( PeiServices, PeiBotDevice, &Packet,
+ sizeof(ATAPI_PACKET_COMMAND),
+ (VOID *) &Data,
+ sizeof(READ_CAPACITY_DATA),
+ EfiUsbDataIn,
+ 2000 );
+ if ( EFI_ERROR( Status ) ) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ PeiBotDevice->Media.LastBlock = (Data.LastLba3 << 24) |
+ (Data.LastLba2 << 16) |
+ (Data.LastLba1 << 8) |
+ Data.LastLba0;
+
+ // AMI Changes ->>
+ //This is the right place to set Medium BlockSize.
+ PeiBotDevice->Media.BlockSize = (Data.BlockSize3 << 24) |
+ (Data.BlockSize2 << 16) |
+ (Data.BlockSize1 << 8) |
+ Data.BlockSize0;
+ // <-- AMI Changes
+
+ PeiBotDevice->Media.MediaPresent = TRUE;
+
+ // BIOS Forced FDD option to emulate USB Key Hard Drive as Floppy
+ // Do Floppy emulation only for Harddrive/Direct Access Device
+ if (PeiBotDevice->DeviceType == USBFLOPPY) {
+ Status = PeiUsbRead10( PeiServices, PeiBotDevice, Buffer,
+ 0, /*StartLBA*/ 1 /*NumberOfBlocks*/ );
+ if ( EFI_ERROR( Status ) ) {
+ // Don't return error, as this shouldn't
+ // messup with ReadCapacity
+ return EFI_SUCCESS;
+ }
+ PeiUsbValidatePartitionTable( PeiServices, Buffer,
+ PeiBotDevice->Media.LastBlock, &(PeiBotDevice->FdEmulOffset) );
+ }
+ return EFI_SUCCESS;
+}
+
+
+// AMI Changes ->>
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: PeiUsbValidatePartitionTable
+//
+// Description: This function validates the existence of the partition table
+// from the LBA 0 data provided and return FdEmulOffset value
+// (hidden sector) from the partition table
+//
+// Input: **PeiServices Pointer to the PEI services table
+// *Buffer Pointer to the buffer containing LBA 0
+// data
+// LastBlock Last LBA address
+//
+// *FdEmulOffset Returned FD emulation hidden sector value
+// Output: Nothing
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID PeiUsbValidatePartitionTable (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN UINT8 *Buffer,
+ IN UINTN LastBlock,
+ OUT UINT32 *FdEmulOffset )
+{
+ UINT8 i;
+ UINT8 *pTable = Buffer + 0x1be; // Start offset of partition
+ // table
+ UINT8 *active_partition_addr = NULL;
+ UINT8 PartitionFound = 0; // Total number of valid
+ // partitions
+ UINT8 *PartitionTableEntries[4];
+
+ for (i = 0; i < 4; i++) {
+ PartitionTableEntries[i] = 0;
+
+ // Boot flag check added to ensure that boot sector will not be
+ // treated as a valid partation table.
+ if (*pTable & 0x7f) {
+ return; // BootFlag should be 0x0 or 0x80
+
+ }
+ // Check whether beginning LBA is reasonable
+ if (*(UINT32 *) (pTable + 8) > LastBlock) {
+ return;
+ }
+
+ // Check whether the size is reasonable
+
+ /** This check has to be refined
+ #if HDD_PART_SIZE_CHECK
+ if (*(UINT32*)(pTable + 0xc) > LastBlock)
+ return;
+ #endif
+ **/
+ PartitionFound++;
+ PartitionTableEntries[i] = pTable;
+ // Update active entry offset
+ if (*pTable & 0x80) {
+ active_partition_addr = pTable;
+ }
+
+ pTable += 0x10; //Get next Partition
+ }
+
+ if (PartitionFound == 0) {
+ return;
+ }
+
+ // If no active partition table entry found use first entry
+ if (active_partition_addr == NULL) {
+ for (i = 0; (i < 4) && !PartitionTableEntries[i]; i++) {
+ ;
+ }
+ if (i == 4) return;
+ active_partition_addr = PartitionTableEntries[i];
+ }
+
+ *FdEmulOffset = *( (UINT32 *) (active_partition_addr + 8) );
+ PEI_TRACE( (EFI_D_ERROR, PeiServices,
+ "USBPEIM: PeiUsbValidatePartitionTable() FdEmulOffset %x\n",
+ *FdEmulOffset) );
+}
+
+
+// <-- AMI Changes
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: PeiUsbReadFormattedCapacity
+//
+// Description: This function issues the ATA Read Formatted Capacity command
+// to the USB mass storage device
+//
+// Input: **PeiServices Pointer to the PEI services table
+// *PeiBotDevice Pointer to the PEI_BOT_DEVICE structure
+//
+// Output: Return Status based on the command
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS PeiUsbReadFormattedCapacity (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_BOT_DEVICE *PeiBotDevice )
+{
+ EFI_STATUS Status;
+ ATAPI_PACKET_COMMAND Packet;
+ READ_FORMAT_CAPACITY_DATA FormatData;
+
+ ZeroMem( &FormatData, sizeof(READ_FORMAT_CAPACITY_DATA) );
+ ZeroMem( &Packet, sizeof(ATAPI_PACKET_COMMAND) );
+
+ Packet.ReadFormatCapacity.opcode = READ_FORMAT_CAPACITY;
+ Packet.ReadFormatCapacity.allocation_length_lo = 12;
+
+ // Send command packet
+ Status = PeiAtapiCommand( PeiServices, PeiBotDevice, &Packet,
+ sizeof(ATAPI_PACKET_COMMAND), (VOID *) &FormatData,
+ sizeof(READ_FORMAT_CAPACITY_DATA), EfiUsbDataIn, 2000 );
+ if ( EFI_ERROR( Status ) ) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ if (FormatData.DesCode == 3) {
+ // Media is not present
+ PeiBotDevice->Media.MediaPresent = FALSE;
+ PeiBotDevice->Media.LastBlock = 0;
+ }
+ else {
+ PeiBotDevice->Media.LastBlock = (FormatData.LastLba3 << 24) |
+ (FormatData.LastLba2 << 16) |
+ (FormatData.LastLba1 << 8) |
+ FormatData.LastLba0;
+
+ PeiBotDevice->Media.LastBlock--;
+ PeiBotDevice->Media.MediaPresent = TRUE;
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: PeiUsbRead10
+//
+// Description: This function issues the ATA Read (10) command to the USB
+// mass storage device
+//
+// Input: **PeiServices Pointer to the PEI services table
+// *PeiBotDevice Pointer to the PEI_BOT_DEVICE structure
+// *Buffer Buffer to read the data into
+// Lba Start LBA Number
+// NumberOfBlocks Number of blocks to read
+//
+// Output: Return Status based on the command
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS PeiUsbRead10 (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_BOT_DEVICE *PeiBotDevice,
+ IN VOID *Buffer,
+ IN EFI_PEI_LBA Lba,
+ IN UINTN NumberOfBlocks )
+{
+ VOID *ptrBuffer;
+ UINT16 MaxBlock;
+ UINT16 BlocksRemaining;
+ UINT16 SectorCount;
+ UINT16 TimeOut;
+ // UINT32 BufferSize;
+ UINT32 Lba32;
+ UINT32 BlockSize;
+ UINT32 ByteCount;
+ EFI_STATUS Status;
+ READ10_CMD *Read10Packet;
+ ATAPI_PACKET_COMMAND Packet;
+
+ // Prepare command packet for the Inquiry Packet Command.
+ ZeroMem( &Packet, sizeof(ATAPI_PACKET_COMMAND) );
+ Read10Packet = &Packet.Read10;
+ Lba32 = (UINT32) Lba;
+ ptrBuffer = Buffer;
+
+ BlockSize = (UINT32) PeiBotDevice->Media.BlockSize;
+ // AMI Changes -->
+ MaxBlock = (UINT16) (65536 / BlockSize);
+ // BufferSize = NumberOfBlocks * BlockSize;
+ // MaxBlock = (UINT16)(BufferSize /BlockSize);
+ // <-- AMI Changes
+ BlocksRemaining = (UINT16) NumberOfBlocks;
+
+ Status = EFI_SUCCESS;
+ while (BlocksRemaining > 0) {
+ if (BlocksRemaining <= MaxBlock) {
+ SectorCount = BlocksRemaining;
+ }
+ else {
+ SectorCount = MaxBlock;
+ }
+
+ // Fill the Packet data structure
+ Read10Packet->opcode = READ_10;
+
+ // Lba0 ~ Lba3 specify the start logical block
+ // address of the data transfer.
+ // Lba0 is MSB, Lba3 is LSB
+ Read10Packet->Lba3 = (UINT8) (Lba32 & 0xff);
+ Read10Packet->Lba2 = (UINT8) (Lba32 >> 8);
+ Read10Packet->Lba1 = (UINT8) (Lba32 >> 16);
+ Read10Packet->Lba0 = (UINT8) (Lba32 >> 24);
+
+ // TranLen0 ~ TranLen1 specify the transfer length in block unit.
+ // TranLen0 is MSB, TranLen is LSB
+ Read10Packet->TranLen1 = (UINT8) (SectorCount & 0xff);
+ Read10Packet->TranLen0 = (UINT8) (SectorCount >> 8);
+
+ ByteCount = SectorCount * BlockSize;
+
+ TimeOut = (UINT16) (SectorCount * 2000);
+
+ // Send command packet
+ Status = PeiAtapiCommand( PeiServices, PeiBotDevice, &Packet,
+ sizeof(ATAPI_PACKET_COMMAND), (VOID *) ptrBuffer, ByteCount,
+ EfiUsbDataIn, TimeOut );
+ if (Status != EFI_SUCCESS) {
+ return Status;
+ }
+
+ Lba32 += SectorCount;
+ ptrBuffer = (UINT8 *) ptrBuffer + SectorCount * BlockSize;
+ BlocksRemaining = (UINT16) (BlocksRemaining - SectorCount);
+ }
+
+ return Status;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: IsNoMedia
+//
+// Description: This function verifies whether Media is present in the drive
+// or not by checking the Sense Data obtained from the drive
+//
+// Input: *SenseData Sense data obtained from the drive
+// SenseCounts Sense count value
+//
+// Output: Returns TRUE if media is present
+// FALSE otherwise
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+BOOLEAN IsNoMedia (
+ IN REQUEST_SENSE_DATA *SenseData,
+ IN UINTN SenseCounts )
+{
+ UINTN i;
+ BOOLEAN NoMedia;
+ REQUEST_SENSE_DATA *SensePtr;
+
+ NoMedia = FALSE;
+ SensePtr = SenseData;
+
+ for (i = 0; i < SenseCounts; i++) {
+ switch (SensePtr->sense_key)
+ {
+ case SK_NOT_READY:
+ switch (SensePtr->addnl_sense_code)
+ {
+ // If no media, fill IdeDev parameter with specific info.
+ case ASC_NO_MEDIA:
+ NoMedia = TRUE;
+ break;
+
+ default:
+ break;
+ }
+ break;
+
+ default:
+ break;
+ }
+ SensePtr++;
+ }
+
+ return NoMedia;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: IsMediaError
+//
+// Description: This function verifies whether Media access is having problem
+// or not by checking the Sense Data obtained from the drive
+//
+// Input: *SenseData Sense data obtained from the drive
+// SenseCounts Sense count value
+//
+// Output: Returns TRUE if media has error
+// FALSE otherwise
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+BOOLEAN IsMediaError (
+ IN REQUEST_SENSE_DATA *SenseData,
+ IN UINTN SenseCounts )
+{
+ UINTN i;
+ BOOLEAN Error;
+ REQUEST_SENSE_DATA *SensePtr;
+
+ SensePtr = SenseData;
+ Error = FALSE;
+
+ for (i = 0; i < SenseCounts; i++) {
+ switch (SensePtr->sense_key)
+ {
+ // Medium error case
+ case SK_MEDIUM_ERROR:
+ switch (SensePtr->addnl_sense_code)
+ {
+ case ASC_MEDIA_ERR1: // fall through
+ case ASC_MEDIA_ERR2: // fall through
+ case ASC_MEDIA_ERR3: // fall through
+ case ASC_MEDIA_ERR4:
+ Error = TRUE;
+ break;
+
+ default:
+ break;
+ }
+ break;
+
+ // Medium upside-down case
+ case SK_NOT_READY:
+ switch (SensePtr->addnl_sense_code)
+ {
+ case ASC_MEDIA_UPSIDE_DOWN:
+ Error = TRUE;
+ break;
+
+ default:
+ break;
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ SensePtr++;
+ }
+
+ return Error;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: IsMediaChange
+//
+// Description: This function verifies whether Media change had happened
+// or not by checking the Sense Data obtained from the drive
+//
+// Input: *SenseData Sense data obtained from the drive
+// SenseCounts Sense count value
+//
+// Output: Returns TRUE if media has changed
+// FALSE otherwise
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+BOOLEAN IsMediaChange (
+ IN REQUEST_SENSE_DATA *SenseData,
+ IN UINTN SenseCounts )
+{
+ UINTN i;
+ BOOLEAN MediaChange;
+ REQUEST_SENSE_DATA *SensePtr;
+
+ MediaChange = FALSE;
+ SensePtr = SenseData;
+ for (i = 0; i < SenseCounts; i++) {
+ // Catch media change sense key and addition sense data
+ switch (SensePtr->sense_key)
+ {
+ case SK_UNIT_ATTENTION:
+ switch (SensePtr->addnl_sense_code)
+ {
+ case ASC_MEDIA_CHANGE:
+ MediaChange = TRUE;
+ break;
+
+ default:
+ break;
+ }
+ break;
+
+ default:
+ break;
+ }
+ SensePtr++;
+ }
+
+ return MediaChange;
+}
+
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (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/UsbBotPeimSrc/UsbBotPeim.c b/Core/EM/UsbRecovery/UsbBotPeimSrc/UsbBotPeim.c
new file mode 100644
index 0000000..6a0ce90
--- /dev/null
+++ b/Core/EM/UsbRecovery/UsbBotPeimSrc/UsbBotPeim.c
@@ -0,0 +1,726 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (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/UsbBotPeim.c 13 11/24/12 5:47a Ryanchou $
+//
+// $Revision: 13 $
+//
+// $Date: 11/24/12 5:47a $
+//
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/USBRecovery/UsbBotPeimSrc/UsbBotPeim.c $
+//
+// 13 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
+//
+// 12 4/16/11 3:42a Ryanchou
+// [TAG] EIP50311
+// [Category] New Feature
+// [Description] Multiple LUN device support added.
+// [Files] BotPeim.c, UsbBotPeim.c, UsbBotPeim.h
+//
+// 11 10/12/10 11:20a Olegi
+// XHCI support added.
+//
+// 10 2/23/10 3:36p Olegi
+// Bugfixes found by Coverity tests: EIP34507.
+//
+// 9 3/03/09 7:22p Olegi
+// Added EHCI support.
+//
+// 8 10/21/08 5:58p 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.)
+//
+// 7 7/29/08 5:51p 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
+//
+// 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:38p Michaela
+// Updated to support OHCI controllers
+//
+// 4 10/23/07 5:42p Ambikas
+//
+// 3 8/17/07 4:35p Ambikas
+//
+// 2 8/17/07 4:11p 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
+//
+//*****************************************************************************
+
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: UsbbotPeim.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 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:
+
+ UsbBotPeim.c
+
+ Abstract:
+
+ Usb Bus PPI
+
+ --*/
+
+#include "UsbBotPeim.h"
+#include "BotPeim.h"
+#define PAGESIZE 4096
+#include EFI_PPI_DEFINITION( Stall )
+#include EFI_PPI_DEFINITION( LoadFile )
+
+static EFI_GUID gPeiStallPpiGuid = PEI_STALL_PPI_GUID;
+static EFI_GUID gPeiBlockIoPpiGuid = EFI_PEI_VIRTUAL_BLOCK_IO_PPI;
+static EFI_GUID gPeiUsbIoPpiGuid = PEI_USB_IO_PPI_GUID;
+
+//
+// Global function
+//
+STATIC
+EFI_PEI_NOTIFY_DESCRIPTOR mNotifyList = {
+ EFI_PEI_PPI_DESCRIPTOR_NOTIFY_DISPATCH |
+ EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
+ &gPeiUsbIoPpiGuid,
+ NotifyOnUsbIoPpi
+};
+
+STATIC
+EFI_PEI_RECOVERY_BLOCK_IO_PPI mRecoveryBlkIoPpi = {
+ BotGetNumberOfBlockDevices,
+ BotGetMediaInfo,
+ BotReadBlocks
+};
+
+STATIC
+EFI_PEI_PPI_DESCRIPTOR mPpiList = {
+ EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
+ &gPeiBlockIoPpiGuid,
+ NULL
+};
+
+//
+// Driver Entry Point
+//
+EFI_STATUS
+PeimInitializeUsbBot (
+ IN EFI_FFS_FILE_HEADER *FfsHeader,
+ IN EFI_PEI_SERVICES **PeiServices );
+
+STATIC
+EFI_STATUS
+PeiBotDetectMedia (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_BOT_DEVICE *PeiBotDev );
+
+EFI_STATUS PeimInitializeUsbBot (
+ IN EFI_FFS_FILE_HEADER *FfsHeader,
+ IN EFI_PEI_SERVICES **PeiServices )
+{
+ EFI_STATUS Status;
+ UINTN UsbIoPpiInstance;
+ EFI_PEI_PPI_DESCRIPTOR *TempPpiDescriptor;
+ PEI_USB_IO_PPI *UsbIoPpi;
+ UINTN PpiInstance;
+
+ for (PpiInstance = 0; PpiInstance < PEI_MAX_USB_RECOVERY_INIT_PPI; PpiInstance++)
+ {
+ PEI_USB_CHIP_INIT_PPI *UsbChipsetRecoveryInitPpi;
+ static EFI_GUID gPeiChipUsbRecoveryInitPpiGuid = PEI_USB_CHIP_INIT_PPI_GUID;
+
+ Status = (**PeiServices).LocatePpi( PeiServices, &gPeiChipUsbRecoveryInitPpiGuid,
+ PpiInstance, NULL, &UsbChipsetRecoveryInitPpi );
+ if (EFI_ERROR( Status ) ) break;
+
+ UsbChipsetRecoveryInitPpi->EnableChipUsbRecovery(PeiServices);
+ }
+
+ #if (PEI_EHCI_SUPPORT == 1)
+ EhciPeiUsbEntryPoint( FfsHeader, PeiServices );
+ #endif
+ #if (PEI_UHCI_SUPPORT == 1)
+ UhciPeiUsbEntryPoint( FfsHeader, PeiServices );
+ UhcPeimEntry( FfsHeader, PeiServices );
+ #endif
+ #if (PEI_OHCI_SUPPORT == 1)
+ OhciPeiUsbEntryPoint( FfsHeader, PeiServices ); // 0xff02
+ #endif
+ #if (PEI_XHCI_SUPPORT == 1)
+ XhciPeiUsbEntryPoint( FfsHeader, PeiServices ); // 0xff02
+ #endif
+ PeimInitializeUsb( FfsHeader, PeiServices ); // 0xff05
+
+
+ //
+ // locate all usb io PPIs
+ //
+ for (UsbIoPpiInstance = 0;
+ UsbIoPpiInstance < PEI_FAT_MAX_USB_IO_PPI;
+ UsbIoPpiInstance++)
+ {
+ Status = (**PeiServices).LocatePpi( PeiServices,
+ &gPeiUsbIoPpiGuid,
+ UsbIoPpiInstance,
+ &TempPpiDescriptor,
+ &UsbIoPpi
+ );
+ if ( EFI_ERROR( Status ) ) {
+ break;
+ }
+
+ InitUsbBot( PeiServices, UsbIoPpi );
+
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+EFI_STATUS NotifyOnUsbIoPpi (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDesc,
+ IN VOID *InvokePpi )
+{
+ PEI_USB_IO_PPI *UsbIoPpi;
+
+ UsbIoPpi = (PEI_USB_IO_PPI *) InvokePpi;
+
+ InitUsbBot( PeiServices, UsbIoPpi );
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS GetMaxLun (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_USB_IO_PPI *UsbIoPpi,
+ IN UINT8 Port,
+ OUT UINT8 *MaxLun )
+{
+ EFI_USB_DEVICE_REQUEST DevReq;
+ EFI_STATUS EfiStatus;
+ UINT32 Timeout;
+
+ ZeroMem( &DevReq, sizeof(EFI_USB_DEVICE_REQUEST) );
+
+ //
+ // Fill Device request packet
+ //
+ DevReq.RequestType = 0xA1;
+ DevReq.Request = 0x0FE;
+ DevReq.Value = 0;
+ DevReq.Index = Port;
+ DevReq.Length = sizeof(UINT8);
+
+ Timeout = 3000;
+
+ EfiStatus = UsbIoPpi->UsbControlTransfer(
+ PeiServices,
+ UsbIoPpi,
+ &DevReq,
+ UsbDataIn,
+ Timeout,
+ MaxLun,
+ sizeof(UINT8)
+ );
+
+ return EfiStatus;
+}
+
+
+EFI_STATUS InitUsbBot (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_USB_IO_PPI *UsbIoPpi )
+{
+ STATIC UINTN UsbIoPpiIndex = 0;
+
+ PEI_BOT_DEVICE *PeiBotDevice;
+ EFI_STATUS Status;
+ EFI_USB_INTERFACE_DESCRIPTOR *InterfaceDesc;
+ UINT8 *AllocateAddress;
+ EFI_USB_ENDPOINT_DESCRIPTOR *EndpointDesc;
+ UINT8 i;
+ UINT8 MaxLun = 0;
+ UINT8 CurrentLun;
+
+ //
+ // Check its interface
+ //
+ Status = UsbIoPpi->UsbGetInterfaceDescriptor( PeiServices,
+ UsbIoPpi, &InterfaceDesc );
+ if ( EFI_ERROR( Status ) ) {
+ return Status;
+ }
+
+ //
+ // Check if it is the BOT device we support
+ //
+
+ if ( (InterfaceDesc->InterfaceClass != BASE_CLASS_MASS_STORAGE)
+ || (InterfaceDesc->InterfaceProtocol != PROTOCOL_BOT) ) {
+
+ return EFI_NOT_FOUND;
+ }
+
+ Status = GetMaxLun(PeiServices,UsbIoPpi,InterfaceDesc->InterfaceNumber,&MaxLun);
+
+ for(CurrentLun = 0; CurrentLun <= MaxLun; CurrentLun++) {
+
+ Status = (*PeiServices)->AllocatePool( PeiServices,
+ sizeof(PEI_BOT_DEVICE), &AllocateAddress );
+ if ( EFI_ERROR( Status ) ) {
+ return Status;
+ }
+
+ PeiBotDevice = (PEI_BOT_DEVICE *) ( (UINTN) AllocateAddress );
+ (**PeiServices).SetMem(PeiBotDevice, sizeof(PEI_BOT_DEVICE), 0);
+
+ PeiBotDevice->Signature = PEI_BOT_DEVICE_SIGNATURE;
+ PeiBotDevice->UsbIoPpi = UsbIoPpi;
+ PeiBotDevice->BotInterface = InterfaceDesc;
+ PeiBotDevice->FdEmulOffset = 0; //bala
+ //
+ // Default value
+ //
+ PeiBotDevice->Media.DeviceType = UsbMassStorage;
+ PeiBotDevice->Media.BlockSize = 0x200;
+ PeiBotDevice->Lun = CurrentLun;
+
+ //
+ // Check its Bulk-in/Bulk-out endpoint
+ //
+ for (i = 0; i < 2; i++) {
+ Status = UsbIoPpi->UsbGetEndpointDescriptor( PeiServices,
+ UsbIoPpi, i, &EndpointDesc );
+ if ( EFI_ERROR( Status ) ) {
+ return Status;
+ }
+
+ if (EndpointDesc->Attributes != 2) {
+ continue;
+ }
+
+ if ( (EndpointDesc->EndpointAddress & 0x80) != 0 ) {
+ PeiBotDevice->BulkInEndpoint = EndpointDesc;
+ }
+ else {
+ PeiBotDevice->BulkOutEndpoint = EndpointDesc;
+ }
+
+ }
+
+ PeiBotDevice->BlkIoPpi = mRecoveryBlkIoPpi;
+ PeiBotDevice->BlkIoPpiList = mPpiList;
+ PeiBotDevice->BlkIoPpiList.Ppi = &PeiBotDevice->BlkIoPpi;
+
+ Status = PeiUsbInquiry( PeiServices, PeiBotDevice );
+ if ( EFI_ERROR( Status ) ) {
+ return Status;
+ }
+
+ Status = (**PeiServices).InstallPpi( PeiServices,
+ &PeiBotDevice->BlkIoPpiList );
+ if ( EFI_ERROR( Status ) ) {
+ return Status;
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+EFI_STATUS BotGetNumberOfBlockDevices (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_RECOVERY_BLOCK_IO_PPI *This,
+ OUT UINTN *NumberBlockDevices )
+{
+ //
+ // For Usb devices, this value should be always 1
+ //
+
+ *NumberBlockDevices = 1;
+ return EFI_SUCCESS;
+}
+
+
+EFI_STATUS BotGetMediaInfo (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_RECOVERY_BLOCK_IO_PPI *This,
+ IN UINTN DeviceIndex,
+ OUT EFI_PEI_BLOCK_IO_MEDIA *MediaInfo )
+{
+ PEI_BOT_DEVICE *PeiBotDev;
+ EFI_STATUS Status = EFI_SUCCESS;
+
+ PeiBotDev = PEI_BOT_DEVICE_FROM_THIS( This );
+
+ Status = PeiBotDetectMedia(
+ PeiServices,
+ PeiBotDev
+ );
+
+ if ( EFI_ERROR( Status ) ) {
+ return Status;
+ }
+
+ *MediaInfo = PeiBotDev->Media;
+
+ return EFI_SUCCESS;
+}
+
+
+EFI_STATUS PeiBotDetectMedia (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_BOT_DEVICE *PeiBotDev )
+{
+
+ EFI_STATUS Status = EFI_SUCCESS;
+ UINT8 *AllocateAddress;
+ REQUEST_SENSE_DATA *SensePtr;
+ UINT8 SenseKey, ASC, ASCQ;
+ UINT8 RetryCount, RetryReq = 0;
+ PEI_STALL_PPI *StallPpi;
+ UINT32 Temp;
+ UINT32 Temp1, Temp2, Temp3;
+
+ //PeiUsbReadCapacity fills PeiBotDev structure for
+ //BlockSize, LastBlock, Media Present
+ for (RetryCount = 0; RetryCount < 25; RetryCount++)
+ {
+ Status = PeiUsbReadCapacity(
+ PeiServices,
+ PeiBotDev
+ );
+
+ if ( EFI_ERROR( Status ) )
+ {
+ Temp = RetryCount;
+
+ //If ReadCapcity fails, then find out type of error
+ if (RetryCount == 0)
+ {
+ if (PeiBotDev->SensePtr == NULL) {
+ //During the first retry allocate the memory
+ Status = (**PeiServices).AllocatePool(
+ PeiServices,
+ sizeof(REQUEST_SENSE_DATA),
+ &AllocateAddress
+ );
+ if ( EFI_ERROR( Status ) )
+ {
+ return Status;
+ }
+ PeiBotDev->SensePtr = (REQUEST_SENSE_DATA *)AllocateAddress;
+ }
+ SensePtr = PeiBotDev->SensePtr;
+ (**PeiServices).SetMem((VOID*)SensePtr, sizeof(REQUEST_SENSE_DATA), 0);
+ Status = (**PeiServices).LocatePpi( PeiServices,
+ &gPeiStallPpiGuid, 0, NULL, &StallPpi );
+ }
+
+ Status = PeiUsbRequestSense(
+ PeiServices,
+ PeiBotDev,
+ (UINT8 *) SensePtr
+ );
+ if ( EFI_ERROR( Status ) )
+ {
+ //If RequestSense also fails, then there is an serious error
+ //Return to the caller with appropriate error code
+ // PeiBotDev->Media.MediaPresent = FALSE;
+ // PeiBotDev->Media.BlockSize = 0;
+ // Status = EFI_DEVICE_ERROR;
+ // return EFI_DEVICE_ERROR;
+ }
+ //TODO:Parse the sense buffer for the error
+ //If media getting ready, then wait for few mSec, then
+ //retry ReadCapacity
+ //For all other errors, return with error condition
+
+ SenseKey = SensePtr->sense_key;
+ ASC = SensePtr->addnl_sense_code;
+ ASCQ = SensePtr->addnl_sense_code_qualifier;
+ Temp1 = SenseKey;
+ Temp2 = ASC;
+ Temp3 = ASCQ;
+
+ if ( (SenseKey == 0x02) && (ASC == 0x3a) && (ASCQ == 00) )
+ {
+ //medium Not Present.
+ //Don't retry.
+ return EFI_DEVICE_ERROR;
+
+ }
+ // The following retry logic is broken, assigning RetryReq 1 does
+ // not make sense and leads to a dead code later: "if (!RetryReq)"
+ // Remove this assignment. EIP34507
+ //For all error retry ReadCapacity 25 times
+ //RetryReq = 1; //Do retry
+ if (SenseKey == 0x02)
+ {
+ //Logical Unit Problem
+ if (ASC == 0x04)
+ {
+ //Becoming Ready/Init Required/ Busy/ Format in Progress.
+ RetryReq = 1; //Do retry
+
+ }
+ if ( (ASC == 0x06) || (ASC == 0x08) )
+ {
+ //No ref. found/ Comm failure
+ RetryReq = 1; //Do retry
+ }
+ }
+
+
+ PeiBotDev->Media.MediaPresent = FALSE;
+ PeiBotDev->Media.BlockSize = 0;
+ Status = EFI_DEVICE_ERROR;
+ if (!RetryReq) {
+ return Status;
+ }
+ }
+ else {
+ Status = EFI_SUCCESS;
+ return Status; //Command Passed so return to caller
+ }
+
+ //Wait for 100 msec
+ StallPpi->Stall( PeiServices, StallPpi, 100 * 1000 );
+ }
+ return Status;
+}
+
+
+EFI_STATUS BotReadBlocks (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_RECOVERY_BLOCK_IO_PPI *This,
+ IN UINTN DeviceIndex,
+ IN EFI_PEI_LBA StartLBA,
+ IN UINTN BufferSize,
+ OUT VOID *Buffer )
+{
+ PEI_BOT_DEVICE *PeiBotDev;
+ EFI_STATUS Status = EFI_SUCCESS;
+ UINTN BlockSize;
+ UINTN NumberOfBlocks;
+ UINT8 *AllocateAddress;
+ REQUEST_SENSE_DATA *SensePtr;
+ UINT8 SenseKey, ASC, ASCQ;
+ UINT8 RetryCount;
+ PEI_STALL_PPI *StallPpi;
+ UINT32 Temp1, Temp2, Temp3;
+
+ PeiBotDev = PEI_BOT_DEVICE_FROM_THIS( This );
+
+ Temp1 = (UINT32) StartLBA;
+
+ StartLBA += PeiBotDev->FdEmulOffset;
+
+ //
+ // Check parameters
+ //
+ if (Buffer == NULL)
+ {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (BufferSize == 0)
+ {
+ return EFI_SUCCESS;
+ }
+
+ BlockSize = PeiBotDev->Media.BlockSize;
+
+ if (BufferSize % BlockSize != 0)
+ {
+ Status = EFI_BAD_BUFFER_SIZE;
+ }
+
+ if (!PeiBotDev->Media.MediaPresent)
+ {
+ return EFI_NO_MEDIA;
+ }
+
+ if (StartLBA > PeiBotDev->Media.LastBlock)
+ {
+ Status = EFI_INVALID_PARAMETER;
+ }
+
+ NumberOfBlocks = BufferSize / (PeiBotDev->Media.BlockSize);
+
+ for (RetryCount = 0; RetryCount < 3; RetryCount++)
+ {
+ Status = PeiUsbRead10(
+ PeiServices,
+ PeiBotDev,
+ Buffer,
+ StartLBA,
+ NumberOfBlocks
+ );
+ if ( EFI_ERROR( Status ) )
+ {
+
+ if (RetryCount == 0)
+ {
+ if (PeiBotDev->SensePtr == NULL) {
+ Status = (**PeiServices).AllocatePool(
+ PeiServices,
+ sizeof(REQUEST_SENSE_DATA),
+ &AllocateAddress
+ );
+ if ( EFI_ERROR( Status ) )
+ {
+ return Status;
+ }
+ PeiBotDev->SensePtr = (REQUEST_SENSE_DATA *) AllocateAddress;
+ }
+ SensePtr = PeiBotDev->SensePtr;
+ (**PeiServices).SetMem((VOID*)SensePtr, sizeof(REQUEST_SENSE_DATA), 0);
+ Status = (**PeiServices).LocatePpi( PeiServices,
+ &gPeiStallPpiGuid, 0, NULL, &StallPpi );
+ }
+
+ Status = PeiUsbRequestSense(
+ PeiServices,
+ PeiBotDev,
+ (UINT8 *) SensePtr
+ );
+ if ( EFI_ERROR( Status ) )
+ {
+ //If RequestSense also fails, then there is an serious error
+ //Return to the caller with appropriate error code
+ return EFI_DEVICE_ERROR;
+ }
+ //TODO:Parse the sense buffer for the error
+ //If media getting ready, then wait for few mSec, then
+ //retry ReadCapacity
+ //For all other errors, return with error condition
+
+ SenseKey = SensePtr->sense_key;
+ ASC = SensePtr->addnl_sense_code;
+ ASCQ = SensePtr->addnl_sense_code_qualifier;
+ Temp1 = SenseKey;
+ Temp2 = ASC;
+ Temp3 = ASCQ;
+ StallPpi->Stall( PeiServices, StallPpi, 9000 );
+
+ }
+ break; //break the for loop
+ }
+ return EFI_SUCCESS;
+
+}
+
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (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/UsbBotPeimSrc/UsbBotPeim.cif b/Core/EM/UsbRecovery/UsbBotPeimSrc/UsbBotPeim.cif
new file mode 100644
index 0000000..ec62a8d
--- /dev/null
+++ b/Core/EM/UsbRecovery/UsbBotPeimSrc/UsbBotPeim.cif
@@ -0,0 +1,14 @@
+<component>
+ name = "UsbBotPeimSrc"
+ category = ModulePart
+ LocalRoot = "Core\em\UsbRecovery\UsbBotPeimSrc"
+ RefName = "UsbBotPeimSrc"
+[files]
+"UsbBotPeim.dxs" = "dxs"
+"BotPeim.c"
+"BotPeim.h"
+"PeiAtapi.c"
+"UsbBotPeim.c"
+"UsbBotPeim.h"
+"atapi.h"
+<endComponent>
diff --git a/Core/EM/UsbRecovery/UsbBotPeimSrc/UsbBotPeim.dxs b/Core/EM/UsbRecovery/UsbBotPeimSrc/UsbBotPeim.dxs
new file mode 100644
index 0000000..baa6bb6
--- /dev/null
+++ b/Core/EM/UsbRecovery/UsbBotPeimSrc/UsbBotPeim.dxs
@@ -0,0 +1,106 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (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/UsbBotPeim.dxs 4 7/10/08 6:38p Michaela $
+//
+// $Revision: 4 $
+//
+// $Date: 7/10/08 6:38p $
+//
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/USBRecovery/UsbBotPeimSrc/UsbBotPeim.dxs $
+//
+// 4 7/10/08 6:38p Michaela
+// Updated to support OHCI controllers
+//
+// 3 10/23/07 5:41p Ambikas
+//
+// 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
+//
+//
+//**********************************************************************
+
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: UsbBotPeim.DXS
+//
+// Description: This file is the dependency file for the USB BOT protocol PEIM
+//
+//----------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+/*++
+ 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:
+
+ UsbBotPeim.dxs
+
+Abstract:
+
+ Dependency expression file for Usb Bot PEIM.
+ PEI_USB_IO_PPI_GUID AND
+--*/
+
+#include "pei.h"
+#include "ppi\LoadFile.h"
+#include "ppi\UsbIo.h"
+
+DEPENDENCY_START
+ EFI_PEI_FV_FILE_LOADER_GUID AND
+ EFI_PEI_BOOT_IN_RECOVERY_MODE_PEIM_PPI AND
+ EFI_PEI_PERMANENT_MEMORY_INSTALLED_PPI
+DEPENDENCY_END
+
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2006, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/UsbRecovery/UsbBotPeimSrc/UsbBotPeim.h b/Core/EM/UsbRecovery/UsbBotPeimSrc/UsbBotPeim.h
new file mode 100644
index 0000000..92a8668
--- /dev/null
+++ b/Core/EM/UsbRecovery/UsbBotPeimSrc/UsbBotPeim.h
@@ -0,0 +1,362 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (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/UsbBotPeimSrc/UsbBotPeim.h 12 11/24/12 5:47a Ryanchou $
+//
+// $Revision: 12 $
+//
+// $Date: 11/24/12 5:47a $
+//
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/USBRecovery/UsbBotPeimSrc/UsbBotPeim.h $
+//
+// 12 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
+//
+// 11 4/16/11 3:42a Ryanchou
+// [TAG] EIP50311
+// [Category] New Feature
+// [Description] Multiple LUN device support added.
+// [Files] BotPeim.c, UsbBotPeim.c, UsbBotPeim.h
+//
+// 10 10/12/10 11:20a Olegi
+// XHCI support added.
+//
+// 9 3/03/09 7:23p Olegi
+// Added EHCI support.
+//
+// 8 10/21/08 5:58p 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.)
+//
+// 7 7/29/08 5:51p 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
+//
+// 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:38p Michaela
+// Updated to support OHCI controllers
+//
+// 4 8/17/07 4:11p Ambikas
+//
+// 3 4/16/07 12:49p 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:52a Meenakshim
+//
+// 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
+//
+//*****************************************************************************
+
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: UsbBotPeim.h
+//
+// Description: This file belongs to "Framework".
+// This file is modified by AMI to include copyright message,
+// appropriate header and integration code.
+//
+//----------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+
+//
+// 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:
+
+ UsbBotPeim.h
+
+ Abstract:
+
+ Usb BOT Peim definition
+
+ --*/
+
+#ifndef _PEI_USB_BOT_PEIM_H
+#define _PEI_USB_BOT_PEIM_H
+
+#include "Efi.h"
+#include "Pei.h"
+// #include "PeiLib.h"
+#include "usb.h"
+#include "Atapi.h"
+#include "AmiMapping.h"
+
+//
+// Driver consumed PPI Prototypes
+//
+#include "Include\Ppi\UsbIo.h"
+
+//
+// Driver produces PPI Prototypes
+//
+#include "Include\Ppi\DeviceRecoveryBlockIo.h"
+#include <Token.h>
+
+#define PEI_FAT_MAX_USB_IO_PPI 127
+
+//---------------------------------------------------------------------------
+// Values for InterfaceDescriptor.BaseClass
+//---------------------------------------------------------------------------
+#define BASE_CLASS_HID 0x03
+#define BASE_CLASS_MASS_STORAGE 0x08
+#define BASE_CLASS_HUB 0x09
+//----------------------------------------------------------------------------
+
+//---------------------------------------------------------------------------
+// Values for InterfaceDescriptor.Protocol
+//---------------------------------------------------------------------------
+#define PROTOCOL_KEYBOARD 0x01 // Keyboard device protocol
+#define PROTOCOL_MOUSE 0x02 // Mouse device protocol?
+
+// Mass storage related protocol equates
+#define PROTOCOL_CBI 0x00 // Mass Storage Control/Bulk/Interrupt
+ // with command completion interrupt
+#define PROTOCOL_CBI_NO_INT 0x01 // MASS STORAGE Control/Bulk/Interrupt
+ // with NO command completion interrupt
+#define PROTOCOL_BOT 0x50 // Mass Storage Bulk-Only Transport
+#define PROTOCOL_VENDOR 0xff // Vendor specific mass protocol
+//---------------------------------------------------------------------------
+
+//
+// BlockIo PPI prototype
+//
+EFI_STATUS
+BotGetNumberOfBlockDevices (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_RECOVERY_BLOCK_IO_PPI *This,
+ OUT UINTN *NumberBlockDevices );
+
+EFI_STATUS
+BotGetMediaInfo (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_RECOVERY_BLOCK_IO_PPI *This,
+ IN UINTN DeviceIndex,
+ OUT EFI_PEI_BLOCK_IO_MEDIA *MediaInfo );
+
+EFI_STATUS
+BotReadBlocks (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_RECOVERY_BLOCK_IO_PPI *This,
+ IN UINTN DeviceIndex,
+ IN EFI_PEI_LBA StartLBA,
+ IN UINTN BufferSize,
+ OUT VOID *Buffer );
+
+//
+// UsbIo PPI Notification
+//
+EFI_STATUS
+NotifyOnUsbIoPpi (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDesc,
+ IN VOID *InvokePpi );
+
+EFI_STATUS
+InitUsbBot (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_USB_IO_PPI *UsbIoPpi );
+
+#define USBFLOPPY 1
+#define USBFLOPPY2 2 // for those that use ReadCapacity(0x25)
+ // command to retrieve media capacity
+#define USBCDROM 3
+//
+// Bot device structure
+//
+#define PEI_BOT_DEVICE_SIGNATURE EFI_SIGNATURE_32( 'U', 'B', 'O', 'T' )
+typedef struct
+{
+ UINTN Signature;
+ EFI_PEI_RECOVERY_BLOCK_IO_PPI BlkIoPpi;
+ EFI_PEI_PPI_DESCRIPTOR BlkIoPpiList;
+ EFI_PEI_BLOCK_IO_MEDIA Media;
+ PEI_USB_IO_PPI *UsbIoPpi;
+ EFI_USB_INTERFACE_DESCRIPTOR *BotInterface;
+ EFI_USB_ENDPOINT_DESCRIPTOR *BulkInEndpoint;
+ EFI_USB_ENDPOINT_DESCRIPTOR *BulkOutEndpoint;
+ UINTN DeviceType;
+ REQUEST_SENSE_DATA *SensePtr;
+ UINT32 FdEmulOffset;
+ UINT8 Lun;
+} PEI_BOT_DEVICE;
+
+#define PEI_BOT_DEVICE_FROM_THIS( a ) \
+ PEI_CR( a, PEI_BOT_DEVICE, BlkIoPpi, PEI_BOT_DEVICE_SIGNATURE )
+
+//
+// USB ATATPI command
+//
+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 );
+
+
+extern VOID ZeroMem (
+ IN VOID *Buffer,
+ IN UINTN Size );
+
+#define ONE_SECOND_DELAY 1000000 // 1 second = 1000000 microseconds
+
+// Controller-specific externs
+#if (PEI_UHCI_SUPPORT == 1)
+EFI_STATUS UhciPeiUsbEntryPoint (
+ IN EFI_FFS_FILE_HEADER *FfsHeader,
+ IN EFI_PEI_SERVICES **PeiServices );
+
+extern EFI_STATUS UhcPeimEntry (
+ IN EFI_FFS_FILE_HEADER *FfsHeader,
+ IN EFI_PEI_SERVICES **PeiServices );
+#endif
+
+#if (PEI_OHCI_SUPPORT == 1)
+EFI_STATUS OhciPeiUsbEntryPoint (
+ IN EFI_FFS_FILE_HEADER *FfsHeader,
+ IN EFI_PEI_SERVICES **PeiServices );
+#endif
+
+#if (PEI_EHCI_SUPPORT == 1)
+EFI_STATUS EhciPeiUsbEntryPoint (
+ IN EFI_FFS_FILE_HEADER *FfsHeader,
+ IN EFI_PEI_SERVICES **PeiServices );
+#endif
+
+#if (PEI_XHCI_SUPPORT == 1)
+EFI_STATUS XhciPeiUsbEntryPoint (
+ IN EFI_FFS_FILE_HEADER *FfsHeader,
+ IN EFI_PEI_SERVICES **PeiServices );
+#endif
+
+extern EFI_STATUS PeimInitializeUsb (
+ IN EFI_FFS_FILE_HEADER *FfsHeader,
+ IN EFI_PEI_SERVICES **PeiServices );
+
+#define PEI_MAX_USB_RECOVERY_INIT_PPI 16
+
+// The following section should eventually go to SBPPI.H.
+#ifndef PEI_USB_CHIP_INIT_PPI_GUID
+#define PEI_USB_CHIP_INIT_PPI_GUID \
+ { 0xdb75358d, 0xfef0, 0x4471, 0xa8, 0xd, 0x2e, 0xeb, 0x13, 0x8, 0x2d, 0x2d }
+
+typedef EFI_STATUS (EFIAPI *PEI_ENABLE_CHIP_USB_RECOVERY) (
+ IN EFI_PEI_SERVICES **PeiServices
+ );
+
+typedef struct _PEI_USB_CHIP_INIT_PPI PEI_USB_CHIP_INIT_PPI;
+
+typedef struct _PEI_USB_CHIP_INIT_PPI {
+ PEI_ENABLE_CHIP_USB_RECOVERY EnableChipUsbRecovery;
+} PEI_USB_CHIP_INIT_PPI;
+#endif
+
+#endif
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2007, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/UsbRecovery/UsbBotPeimSrc/atapi.h b/Core/EM/UsbRecovery/UsbBotPeimSrc/atapi.h
new file mode 100644
index 0000000..2d6d376
--- /dev/null
+++ b/Core/EM/UsbRecovery/UsbBotPeimSrc/atapi.h
@@ -0,0 +1,418 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (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/atapi.h 2 7/10/08 6:38p Michaela $
+//
+// $Revision: 2 $
+//
+// $Date: 7/10/08 6:38p $
+//
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/USBRecovery/UsbBotPeimSrc/atapi.h $
+//
+// 2 7/10/08 6:38p Michaela
+// Updated to support OHCI controllers
+//
+// 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
+//
+//*****************************************************************************
+
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: Atapi.h
+//
+// Description: This file belongs to "Framework".
+// This file is modified by AMI to include copyright message,
+// appropriate header and integration code.
+//
+//----------------------------------------------------------------------------
+//<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:
+
+ Atapi.h
+
+ Abstract:
+
+
+ Revision History
+ --*/
+
+#ifndef _PEI_RECOVERY_ATAPI_H
+#define _PEI_RECOVERY_ATAPI_H
+
+#include "Efi.h"
+
+#pragma pack(1)
+
+typedef struct
+{
+ UINT16 config; // General Configuration
+ UINT16 cylinders; // Number of Cylinders
+ UINT16 reserved_2;
+ UINT16 heads; // Number of logical heads
+ UINT16 vendor_data1;
+ UINT16 vendoe_data2;
+ UINT16 sectors_per_track;
+ UINT16 vendor_specific_7_9[3];
+ CHAR8 SerialNo[20]; // ASCII
+ UINT16 vendor_specific_20_21[2];
+ UINT16 ecc_bytes_available;
+ CHAR8 FirmwareVer[8]; // ASCII
+ CHAR8 ModelName[40]; // ASCII
+ UINT16 multi_sector_cmd_max_sct_cnt;
+ UINT16 reserved_48;
+ UINT16 capabilities;
+ UINT16 reserved_50;
+ UINT16 pio_cycle_timing;
+ UINT16 reserved_52;
+ UINT16 field_validity;
+ UINT16 current_cylinders;
+ UINT16 current_heads;
+ UINT16 current_sectors;
+ UINT16 CurrentCapacityLsb;
+ UINT16 CurrentCapacityMsb;
+ UINT16 reserved_59;
+ UINT16 user_addressable_sectors_lo;
+ UINT16 user_addressable_sectors_hi;
+ UINT16 reserved_62;
+ UINT16 multi_word_dma_mode;
+ UINT16 advanced_pio_modes;
+ UINT16 min_multi_word_dma_cycle_time;
+ UINT16 rec_multi_word_dma_cycle_time;
+ UINT16 min_pio_cycle_time_without_flow_control;
+ UINT16 min_pio_cycle_time_with_flow_control;
+ UINT16 reserved_69_79[11];
+ UINT16 major_version_no;
+ UINT16 minor_version_no;
+ UINT16 reserved_82_127[46];
+ UINT16 security_status;
+ UINT16 vendor_data_129_159[31];
+ UINT16 reserved_160_255[96];
+} IDENTIFY;
+
+typedef struct
+{
+ UINT8 peripheral_type;
+ UINT8 RMB;
+ UINT8 version;
+ UINT8 response_data_format;
+ UINT8 addnl_length;
+ UINT8 reserved_5;
+ UINT8 reserved_6;
+ UINT8 reserved_7;
+ UINT8 vendor_info[8];
+ UINT8 product_id[12];
+ UINT8 eeprom_product_code[4];
+ UINT8 firmware_rev_level[4];
+ UINT8 firmware_sub_rev_level[1];
+ UINT8 reserved_37;
+ UINT8 reserved_38;
+ UINT8 reserved_39;
+ UINT8 max_capacity_hi;
+ UINT8 max_capacity_mid;
+ UINT8 max_capacity_lo;
+ UINT8 reserved_43_95[95 - 43 + 1];
+ UINT8 vendor_id[20];
+ UINT8 eeprom_drive_sno[12];
+} INQUIRY_DATA;
+
+typedef struct
+{
+ UINT8 error_code : 7;
+ UINT8 valid : 1;
+ UINT8 reserved_1;
+ UINT8 sense_key : 4;
+ UINT8 reserved_21 : 1;
+ UINT8 ILI : 1;
+ UINT8 reserved_22 : 2;
+ UINT8 vendor_specific_3;
+ UINT8 vendor_specific_4;
+ UINT8 vendor_specific_5;
+ UINT8 vendor_specific_6;
+ UINT8 addnl_sense_length; // n - 7
+ UINT8 vendor_specific_8;
+ UINT8 vendor_specific_9;
+ UINT8 vendor_specific_10;
+ UINT8 vendor_specific_11;
+ UINT8 addnl_sense_code; // mandatory
+ UINT8 addnl_sense_code_qualifier; // mandatory
+ UINT8 field_replaceable_unit_code; // optional
+ UINT8 reserved_15;
+ UINT8 reserved_16;
+ UINT8 reserved_17;
+ // Followed by additional sense bytes : FIXME
+} REQUEST_SENSE_DATA;
+
+typedef struct
+{
+ UINT8 LastLba3;
+ UINT8 LastLba2;
+ UINT8 LastLba1;
+ UINT8 LastLba0;
+ UINT8 BlockSize3;
+ UINT8 BlockSize2;
+ UINT8 BlockSize1;
+ UINT8 BlockSize0;
+} READ_CAPACITY_DATA;
+
+typedef struct
+{
+ UINT8 reserved_0;
+ UINT8 reserved_1;
+ UINT8 reserved_2;
+ UINT8 Capacity_Length;
+ UINT8 LastLba3;
+ UINT8 LastLba2;
+ UINT8 LastLba1;
+ UINT8 LastLba0;
+ UINT8 DesCode : 2;
+ UINT8 reserved_9 : 6;
+ UINT8 BlockSize2;
+ UINT8 BlockSize1;
+ UINT8 BlockSize0;
+} READ_FORMAT_CAPACITY_DATA;
+
+#pragma pack()
+
+//
+// ATAPI Command
+//
+#define ATAPI_SOFT_RESET_CMD 0x08
+#define PACKET_CMD 0xa0
+#define ATAPI_IDENTIFY_DEVICE_CMD 0xa1
+#define ATAPI_SERVICE_CMD 0xa2
+
+//
+// ATAPI Packet Command
+//
+#pragma pack(1)
+
+typedef struct
+{
+ UINT8 opcode;
+ UINT8 reserved_1;
+ UINT8 reserved_2;
+ UINT8 reserved_3;
+ UINT8 reserved_4;
+ UINT8 reserved_5;
+ UINT8 reserved_6;
+ UINT8 reserved_7;
+ UINT8 reserved_8;
+ UINT8 reserved_9;
+ UINT8 reserved_10;
+ UINT8 reserved_11;
+} TEST_UNIT_READY_CMD;
+
+typedef struct
+{
+ UINT8 opcode;
+ UINT8 reserved_1 : 4;
+ UINT8 lun : 4;
+ UINT8 page_code;
+ UINT8 reserved_3;
+ UINT8 allocation_length;
+ UINT8 reserved_5;
+ UINT8 reserved_6;
+ UINT8 reserved_7;
+ UINT8 reserved_8;
+ UINT8 reserved_9;
+ UINT8 reserved_10;
+ UINT8 reserved_11;
+} INQUIRY_CMD;
+
+
+typedef struct
+{
+ UINT8 opcode;
+ UINT8 reserved_1 : 4;
+ UINT8 lun : 4;
+ UINT8 reserved_2;
+ UINT8 reserved_3;
+ UINT8 allocation_length;
+ UINT8 reserved_5;
+ UINT8 reserved_6;
+ UINT8 reserved_7;
+ UINT8 reserved_8;
+ UINT8 reserved_9;
+ UINT8 reserved_10;
+ UINT8 reserved_11;
+} REQUEST_SENSE_CMD;
+
+typedef struct
+{
+ UINT8 opcode;
+ UINT8 reserved_1 : 5;
+ UINT8 lun : 3;
+ UINT8 Lba0;
+ UINT8 Lba1;
+ UINT8 Lba2;
+ UINT8 Lba3;
+ UINT8 reserved_6;
+ UINT8 TranLen0;
+ UINT8 TranLen1;
+ UINT8 reserved_9;
+ UINT8 reserved_10;
+ UINT8 reserved_11;
+} READ10_CMD;
+
+typedef struct
+{
+ UINT8 opcode;
+ UINT8 reserved_1;
+ UINT8 reserved_2;
+ UINT8 reserved_3;
+ UINT8 reserved_4;
+ UINT8 reserved_5;
+ UINT8 reserved_6;
+ UINT8 allocation_length_hi;
+ UINT8 allocation_length_lo;
+ UINT8 reserved_9;
+ UINT8 reserved_10;
+ UINT8 reserved_11;
+} READ_FORMAT_CAP_CMD;
+
+typedef struct
+{
+ UINT8 peripheral_type;
+ UINT8 RMB;
+ UINT8 version;
+ UINT8 response_data_format;
+ UINT8 addnl_length;
+ UINT8 reserved_5;
+ UINT8 reserved_6;
+ UINT8 reserved_7;
+ UINT8 vendor_info[8];
+ UINT8 product_id[12];
+ UINT8 eeprom_product_code[4];
+ UINT8 firmware_rev_level[4];
+} USB_INQUIRY_DATA;
+
+typedef union {
+ UINT16 Data16[6];
+ TEST_UNIT_READY_CMD TestUnitReady;
+ READ10_CMD Read10;
+ REQUEST_SENSE_CMD RequestSence;
+ INQUIRY_CMD Inquiry;
+ READ_FORMAT_CAP_CMD ReadFormatCapacity;
+} ATAPI_PACKET_COMMAND;
+
+#pragma pack()
+
+//
+// Packet Command Code
+//
+#define TEST_UNIT_READY 0x00
+#define REQUEST_SENSE 0x03
+#define INQUIRY 0x12
+#define READ_FORMAT_CAPACITY 0x23
+#define READ_CAPACITY 0x25
+#define READ_10 0x28
+
+#define DEFAULT_CTL (0x0a) // default content of device
+ // control register,
+ // disable INT
+#define DEFAULT_CMD (0xa0)
+
+#define MAX_ATAPI_BYTE_COUNT (0xfffe)
+
+//
+// Sense Key
+//
+#define REQUEST_SENSE_ERROR (0x70)
+#define SK_NO_SENSE (0x0)
+#define SK_RECOVERY_ERROR (0x1)
+#define SK_NOT_READY (0x2)
+#define SK_MEDIUM_ERROR (0x3)
+#define SK_HARDWARE_ERROR (0x4)
+#define SK_ILLEGAL_REQUEST (0x5)
+#define SK_UNIT_ATTENTION (0x6)
+#define SK_DATA_PROTECT (0x7)
+#define SK_BLANK_CHECK (0x8)
+#define SK_VENDOR_SPECIFIC (0x9)
+#define SK_RESERVED_A (0xa)
+#define SK_ABORT (0xb)
+#define SK_RESERVED_C (0xc)
+#define SK_OVERFLOW (0xd)
+#define SK_MISCOMPARE (0xe)
+#define SK_RESERVED_F (0xf)
+
+//
+// Additional Sense Codes
+//
+#define ASC_NOT_READY (0x04)
+#define ASC_MEDIA_ERR1 (0x10)
+#define ASC_MEDIA_ERR2 (0x11)
+#define ASC_MEDIA_ERR3 (0x14)
+#define ASC_MEDIA_ERR4 (0x30)
+#define ASC_MEDIA_UPSIDE_DOWN (0x06)
+#define ASC_INVALID_CMD (0x20)
+#define ASC_LBA_OUT_OF_RANGE (0x21)
+#define ASC_INVALID_FIELD (0x24)
+#define ASC_WRITE_PROTECTED (0x27)
+#define ASC_MEDIA_CHANGE (0x28)
+#define ASC_RESET (0x29) // Power On Reset or Bus Reset occurred
+#define ASC_ILLEGAL_FIELD (0x26)
+#define ASC_NO_MEDIA (0x3a)
+#define ASC_ILLEGAL_MODE_FOR_THIS_TRACK (0x64)
+
+//
+// Additional Sense Code Qualifier
+//
+#define ASCQ_IN_PROGRESS (0x01)
+
+#endif
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (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