summaryrefslogtreecommitdiff
path: root/Core/EM/UsbRecovery/UsbBotPeimSrc/PeiAtapi.c
diff options
context:
space:
mode:
Diffstat (limited to 'Core/EM/UsbRecovery/UsbBotPeimSrc/PeiAtapi.c')
-rw-r--r--Core/EM/UsbRecovery/UsbBotPeimSrc/PeiAtapi.c832
1 files changed, 832 insertions, 0 deletions
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