/** @file
   This file contains all helper functions on the ATAPI command 
  
  Copyright (c) 2006 - 2008, Intel Corporation                                                        
  All rights reserved. This program and the accompanying materials                          
  are licensed and made available under the terms and conditions of the BSD License         
  which accompanies this distribution.  The full text of the license may be found at        
  http://opensource.org/licenses/bsd-license.php                                            

  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     
  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             

**/

#include "IdeBus.h"

/**
  This function is used to get the current status of the media residing
  in the LS-120 drive or ZIP drive. The media status is returned in the 
  Error Status.

  @param IdeDev   pointer pointing to IDE_BLK_IO_DEV data structure, used
                  to record all the information of the IDE device.

  @retval EFI_SUCCESS         The media status is achieved successfully and the media
                              can be read/written.
  @retval EFI_DEVICE_ERROR    Get Media Status Command is failed.
  @retval EFI_NO_MEDIA        There is no media in the drive.
  @retval EFI_WRITE_PROTECTED The media is writing protected.

  @note  This function must be called after the LS120EnableMediaStatus() 
         with second parameter set to TRUE 
         (means enable media status notification) is called.
**/
EFI_STATUS
LS120GetMediaStatus (
  IN  IDE_BLK_IO_DEV  *IdeDev
  )
{
  UINT8       DeviceSelect;
  UINT8       StatusValue;
  EFI_STATUS  EfiStatus;
  //
  // Poll Alternate Register for BSY clear within timeout.
  //
  EfiStatus = WaitForBSYClear2 (IdeDev, ATATIMEOUT);
  if (EFI_ERROR (EfiStatus)) {
    return EFI_DEVICE_ERROR;
  }

  //
  // Select device via Device/Head Register.
  //
  DeviceSelect = (UINT8) ((IdeDev->Device) << 4 | 0xe0);
  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Head, DeviceSelect);

  //
  // Poll Alternate Register for DRDY set within timeout.
  // After device is selected, DRDY set indicates the device is ready to
  // accept command.
  //
  EfiStatus = DRDYReady2 (IdeDev, ATATIMEOUT);
  if (EFI_ERROR (EfiStatus)) {
    return EFI_DEVICE_ERROR;
  }

  //
  // Get Media Status Command is sent
  //
  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Command, 0xDA);

  //
  // BSY bit will clear after command is complete.
  //
  EfiStatus = WaitForBSYClear2 (IdeDev, ATATIMEOUT);
  if (EFI_ERROR (EfiStatus)) {
    return EFI_DEVICE_ERROR;
  }

  //
  // the media status is returned by the command in the ERROR register
  //
  StatusValue = IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Reg1.Error);

  if ((StatusValue & BIT1) != 0) {
    return EFI_NO_MEDIA;
  }

  if ((StatusValue & BIT6) != 0) {
    return EFI_WRITE_PROTECTED;
  } else {
    return EFI_SUCCESS;
  }
}
/**
  This function is used to send Enable Media Status Notification Command
  or Disable Media Status Notification Command.

  @param IdeDev pointer pointing to IDE_BLK_IO_DEV data structure, used
                to record all the information of the IDE device.

  @param Enable a flag that indicates whether enable or disable media
                status notification.
  @retval EFI_SUCCESS      If command completes successfully.
  @retval EFI_DEVICE_ERROR If command failed.
**/
EFI_STATUS
LS120EnableMediaStatus (
  IN  IDE_BLK_IO_DEV  *IdeDev,
  IN  BOOLEAN         Enable
  )
{
  UINT8       DeviceSelect;
  EFI_STATUS  Status;

  //
  // Poll Alternate Register for BSY clear within timeout.
  //
  Status = WaitForBSYClear2 (IdeDev, ATATIMEOUT);
  if (EFI_ERROR (Status)) {
    return EFI_DEVICE_ERROR;
  }

  //
  // Select device via Device/Head Register.
  //
  DeviceSelect = (UINT8) ((IdeDev->Device) << 4 | 0xe0);
  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Head, DeviceSelect);

  //
  // Poll Alternate Register for DRDY set within timeout.
  // After device is selected, DRDY set indicates the device is ready to
  // accept command.
  //
  Status = DRDYReady2 (IdeDev, ATATIMEOUT);
  if (EFI_ERROR (Status)) {
    return EFI_DEVICE_ERROR;
  }

  if (Enable) {
    //
    // 0x95: Enable media status notification
    //
    IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg1.Feature, 0x95);
  } else {
    //
    // 0x31: Disable media status notification
    //
    IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg1.Feature, 0x31);
  }
  //
  // Set Feature Command is sent
  //
  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Command, 0xEF);

  //
  // BSY bit will clear after command is complete.
  //
  Status = WaitForBSYClear (IdeDev, ATATIMEOUT);
  if (EFI_ERROR (Status)) {
    return EFI_DEVICE_ERROR;
  }

  return EFI_SUCCESS;
}
/**
  This function reads the pending data in the device.

  @param IdeDev   Indicates the calling context.

  @retval EFI_SUCCESS   Successfully read.
  @retval EFI_NOT_READY The BSY is set avoiding reading.

**/
EFI_STATUS
AtapiReadPendingData (
  IN IDE_BLK_IO_DEV     *IdeDev
  )
{
  UINT8     AltRegister;
  UINT16    TempWordBuffer;

  AltRegister = IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Alt.AltStatus);
  if ((AltRegister & ATA_STSREG_BSY) == ATA_STSREG_BSY) {
    return EFI_NOT_READY;
  }
  if ((AltRegister & (ATA_STSREG_BSY | ATA_STSREG_DRQ)) == ATA_STSREG_DRQ) {
    TempWordBuffer = IDEReadPortB (IdeDev->PciIo,IdeDev->IoPort->Alt.AltStatus);
    while ((TempWordBuffer & (ATA_STSREG_BSY | ATA_STSREG_DRQ)) == ATA_STSREG_DRQ) {
      IDEReadPortWMultiple (
        IdeDev->PciIo,
        IdeDev->IoPort->Data, 
        1, 
        &TempWordBuffer
        );
      TempWordBuffer = IDEReadPortB (IdeDev->PciIo,IdeDev->IoPort->Alt.AltStatus);
    }
  }
  return EFI_SUCCESS;
}

/**
  This function is called by either AtapiPacketCommandIn() or AtapiPacketCommandOut(). 
  It is used to transfer data between host and device. The data direction is specified
  by the fourth parameter.

  @param IdeDev     pointer pointing to IDE_BLK_IO_DEV data structure, used to record
                    all the information of the IDE device.
  @param Buffer     buffer contained data transferred between host and device.
  @param ByteCount  data size in byte unit of the buffer.
  @param Read       flag used to determine the data transfer direction.
                    Read equals 1, means data transferred from device to host;
                    Read equals 0, means data transferred from host to device.
  @param TimeOut    timeout value for wait DRQ ready before each data stream's transfer.

  @retval EFI_SUCCESS      data is transferred successfully.
  @retval EFI_DEVICE_ERROR the device failed to transfer data.
**/
EFI_STATUS
PioReadWriteData (
  IN  IDE_BLK_IO_DEV  *IdeDev,
  IN  UINT16          *Buffer,
  IN  UINT32          ByteCount,
  IN  BOOLEAN         Read,
  IN  UINTN           TimeOut
  )
{
  //
  // required transfer data in word unit.
  //
  UINT32      RequiredWordCount;

  //
  // actual transfer data in word unit.
  //
  UINT32      ActualWordCount;
  UINT32      WordCount;
  EFI_STATUS  Status;
  UINT16      *PtrBuffer;

  //
  // No data transfer is premitted.
  //
  if (ByteCount == 0) {
    return EFI_SUCCESS;
  }
  //
  // for performance, we assert the ByteCount is an even number
  // which is actually a resonable assumption  
  ASSERT((ByteCount%2) == 0);
  
  PtrBuffer         = Buffer;
  RequiredWordCount = ByteCount / 2;
  //
  // ActuralWordCount means the word count of data really transferred.
  //
  ActualWordCount = 0;

  while (ActualWordCount < RequiredWordCount) {
    
    //
    // before each data transfer stream, the host should poll DRQ bit ready,
    // to see whether indicates device is ready to transfer data.
    //
    Status = DRQReady2 (IdeDev, TimeOut);
    if (EFI_ERROR (Status)) {
      return CheckErrorStatus (IdeDev);
    }
    
    //
    // read Status Register will clear interrupt
    //
    IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Status);

    //
    // get current data transfer size from Cylinder Registers.
    //
    WordCount = IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->CylinderMsb) << 8;
    WordCount = WordCount | IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->CylinderLsb);
    WordCount = WordCount & 0xffff;
    WordCount /= 2;

    WordCount = MIN (WordCount, (RequiredWordCount - ActualWordCount));

    if (Read) {
      IDEReadPortWMultiple (
        IdeDev->PciIo,
        IdeDev->IoPort->Data,
        WordCount,
        PtrBuffer
        );
    } else {
      IDEWritePortWMultiple (
        IdeDev->PciIo,
        IdeDev->IoPort->Data,
        WordCount,
        PtrBuffer
        );
    }

    PtrBuffer += WordCount;
    ActualWordCount += WordCount;
  }
  
  if (Read) {
    //
    // In the case where the drive wants to send more data than we need to read,
    // the DRQ bit will be set and cause delays from DRQClear2().
    // We need to read data from the drive until it clears DRQ so we can move on.
    //
    AtapiReadPendingData (IdeDev);
  }

  //
  // After data transfer is completed, normally, DRQ bit should clear.
  //
  Status = DRQClear2 (IdeDev, ATAPITIMEOUT);
  if (EFI_ERROR (Status)) {
    return EFI_DEVICE_ERROR;
  }

  //
  // read status register to check whether error happens.
  //
  return CheckErrorStatus (IdeDev);
}

/**
  This function is used to send out ATAPI commands conforms to the Packet Command 
  with PIO Data In Protocol.

  @param IdeDev    pointer pointing to IDE_BLK_IO_DEV data structure, used
                   to record all the information of the IDE device.
  @param Packet    pointer pointing to ATAPI_PACKET_COMMAND data structure
                   which contains the contents of the command.     
  @param Buffer    buffer contained data transferred from device to host.
  @param ByteCount data size in byte unit of the buffer.
  @param TimeOut   this parameter is used to specify the timeout value for the 
                   PioReadWriteData() function. 

  @retval EFI_SUCCESS       send out the ATAPI packet command successfully
                            and device sends data successfully.
  @retval EFI_DEVICE_ERROR  the device failed to send data.

**/
EFI_STATUS
AtapiPacketCommandIn (
  IN  IDE_BLK_IO_DEV        *IdeDev,
  IN  ATAPI_PACKET_COMMAND  *Packet,
  IN  UINT16                *Buffer,
  IN  UINT32                ByteCount,
  IN  UINTN                 TimeOut
  )
{
  UINT16      *CommandIndex;
  EFI_STATUS  Status;
  UINT32      Count;

  //
  // Set all the command parameters by fill related registers.
  // Before write to all the following registers, BSY and DRQ must be 0.
  //
  Status = DRQClear2 (IdeDev, ATAPITIMEOUT);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Select device via Device/Head Register.
  //
  IDEWritePortB (
    IdeDev->PciIo,
    IdeDev->IoPort->Head,
    (UINT8) ((IdeDev->Device << 4) | ATA_DEFAULT_CMD)  // DEFAULT_CMD: 0xa0 (1010,0000)
    );

  //
  // No OVL; No DMA
  //
  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg1.Feature, 0x00);

  //
  // set the transfersize to ATAPI_MAX_BYTE_COUNT to let the device
  // determine how many data should be transferred.
  //
  IDEWritePortB (
    IdeDev->PciIo,
    IdeDev->IoPort->CylinderLsb,
    (UINT8) (ATAPI_MAX_BYTE_COUNT & 0x00ff)
    );
  IDEWritePortB (
    IdeDev->PciIo,
    IdeDev->IoPort->CylinderMsb,
    (UINT8) (ATAPI_MAX_BYTE_COUNT >> 8)
    );

  //
  //  ATA_DEFAULT_CTL:0x0a (0000,1010)
  //  Disable interrupt
  //
  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Alt.DeviceControl, ATA_DEFAULT_CTL);

  //
  // Send Packet command to inform device
  // that the following data bytes are command packet.
  //
  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Command, ATA_CMD_PACKET);

  Status = DRQReady (IdeDev, ATAPITIMEOUT);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Send out command packet
  //
  CommandIndex = Packet->Data16;
  for (Count = 0; Count < 6; Count++, CommandIndex++) {

    IDEWritePortW (IdeDev->PciIo, IdeDev->IoPort->Data, *CommandIndex);
    gBS->Stall (10);
  }

  //
  // call PioReadWriteData() function to get
  // requested transfer data form device.
  //
  return PioReadWriteData (IdeDev, Buffer, ByteCount, 1, TimeOut);
}
/**
  This function is used to send out ATAPI commands conforms to the Packet Command
  with PIO Data Out Protocol.

  @param IdeDev      pointer pointing to IDE_BLK_IO_DEV data structure, used
                     to record all the information of the IDE device.
  @param Packet      pointer pointing to ATAPI_PACKET_COMMAND data structure
                     which contains the contents of the command.
  @param Buffer      buffer contained data transferred from host to device.
  @param ByteCount   data size in byte unit of the buffer.
  @param TimeOut     this parameter is used to specify the timeout value 
                     for the PioReadWriteData() function. 
  @retval EFI_SUCCESS      send out the ATAPI packet command successfully
                           and device received data successfully.  
  @retval EFI_DEVICE_ERROR the device failed to send data.

**/
EFI_STATUS
AtapiPacketCommandOut (
  IN  IDE_BLK_IO_DEV        *IdeDev,
  IN  ATAPI_PACKET_COMMAND  *Packet,
  IN  UINT16                *Buffer,
  IN  UINT32                ByteCount,
  IN  UINTN                 TimeOut
  )
{
  UINT16      *CommandIndex;
  EFI_STATUS  Status;
  UINT32      Count;

  //
  // set all the command parameters
  // Before write to all the following registers, BSY and DRQ must be 0.
  //
  Status = DRQClear2 (IdeDev, ATAPITIMEOUT);
  if (EFI_ERROR (Status)) {
    return Status;
  }
  
  //
  // Select device via Device/Head Register.
  //
  IDEWritePortB (
    IdeDev->PciIo,
    IdeDev->IoPort->Head,
    (UINT8) ((IdeDev->Device << 4) | ATA_DEFAULT_CMD)   // ATA_DEFAULT_CMD: 0xa0 (1010,0000)
    );

  //
  // No OVL; No DMA
  //
  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg1.Feature, 0x00);

  //
  // set the transfersize to ATAPI_MAX_BYTE_COUNT to
  // let the device determine how many data should be transferred.
  //
  IDEWritePortB (
    IdeDev->PciIo,
    IdeDev->IoPort->CylinderLsb,
    (UINT8) (ATAPI_MAX_BYTE_COUNT & 0x00ff)
    );
  IDEWritePortB (
    IdeDev->PciIo,
    IdeDev->IoPort->CylinderMsb,
    (UINT8) (ATAPI_MAX_BYTE_COUNT >> 8)
    );

  //
  //  DEFAULT_CTL:0x0a (0000,1010)
  //  Disable interrupt
  //
  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Alt.DeviceControl, ATA_DEFAULT_CTL);

  //
  // Send Packet command to inform device
  // that the following data bytes are command packet.
  //
  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Command, ATA_CMD_PACKET);

  Status = DRQReady2 (IdeDev, ATAPITIMEOUT);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Send out command packet
  //
  CommandIndex = Packet->Data16;
  for (Count = 0; Count < 6; Count++, CommandIndex++) {
    IDEWritePortW (IdeDev->PciIo, IdeDev->IoPort->Data, *CommandIndex);
    gBS->Stall (10);
  }

  //
  // call PioReadWriteData() function to send requested transfer data to device.
  //
  return PioReadWriteData (IdeDev, Buffer, ByteCount, 0, TimeOut);
}
/**
  Sends out ATAPI Inquiry Packet Command to the specified device. This command will
  return INQUIRY data of the device.

  @param IdeDev pointer pointing to IDE_BLK_IO_DEV data structure, used
                to record all the information of the IDE device.

  @retval EFI_SUCCESS       Inquiry command completes successfully.
  @retval EFI_DEVICE_ERROR  Inquiry command failed.

  @note  Parameter "IdeDev" will be updated in this function.

**/
EFI_STATUS
AtapiInquiry (
  IN  IDE_BLK_IO_DEV  *IdeDev
  )
{
  ATAPI_PACKET_COMMAND  Packet;
  EFI_STATUS            Status;
  ATAPI_INQUIRY_DATA          *InquiryData;

  //
  // prepare command packet for the ATAPI Inquiry Packet Command.
  //
  ZeroMem (&Packet, sizeof (ATAPI_PACKET_COMMAND));
  Packet.Inquiry.opcode             = ATA_CMD_INQUIRY;
  Packet.Inquiry.page_code          = 0;
  Packet.Inquiry.allocation_length  = sizeof (ATAPI_INQUIRY_DATA);

  InquiryData                       = AllocatePool (sizeof (ATAPI_INQUIRY_DATA));
  if (InquiryData == NULL) {
    return EFI_DEVICE_ERROR;
  }

  //
  // Send command packet and get requested Inquiry data.
  //
  Status = AtapiPacketCommandIn (
            IdeDev,
            &Packet,
            (UINT16 *) InquiryData,
            sizeof (ATAPI_INQUIRY_DATA),
            ATAPITIMEOUT
            );
  if (EFI_ERROR (Status)) {
    gBS->FreePool (InquiryData);
    return EFI_DEVICE_ERROR;
  }

  IdeDev->InquiryData = InquiryData;

  return EFI_SUCCESS;
}
/**
  This function is called by DiscoverIdeDevice() during its device
  identification.
  Its main purpose is to get enough information for the device media
  to fill in the Media data structure of the Block I/O Protocol interface.

  There are 5 steps to reach such objective:
  1. Sends out the ATAPI Identify Command to the specified device. 
  Only ATAPI device responses to this command. If the command succeeds,
  it returns the Identify data structure which filled with information 
  about the device. Since the ATAPI device contains removable media, 
  the only meaningful information is the device module name.
  2. Sends out ATAPI Inquiry Packet Command to the specified device.
  This command will return inquiry data of the device, which contains
  the device type information.
  3. Allocate sense data space for future use. We don't detect the media
  presence here to improvement boot performance, especially when CD 
  media is present. The media detection will be performed just before
  each BLK_IO read/write
  
  @param IdeDev pointer pointing to IDE_BLK_IO_DEV data structure, used
                 to record all the information of the IDE device.

  @retval EFI_SUCCESS       Identify ATAPI device successfully.
  @retval EFI_DEVICE_ERROR  ATAPI Identify Device Command failed or device type
                            is not supported by this IDE driver.
  @retval EFI_OUT_OF_RESOURCES Allocate memory for sense data failed 

  @note   Parameter "IdeDev" will be updated in this function.
**/
EFI_STATUS
ATAPIIdentify (
  IN  IDE_BLK_IO_DEV  *IdeDev
  )
{
  EFI_IDENTIFY_DATA *AtapiIdentifyPointer;
  UINT8             DeviceSelect;
  EFI_STATUS        Status;

  //
  // device select bit
  //
  DeviceSelect          = (UINT8) ((IdeDev->Device) << 4);

  AtapiIdentifyPointer  = AllocatePool (sizeof (EFI_IDENTIFY_DATA));
  if (AtapiIdentifyPointer == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }
  //
  // Send ATAPI Identify Command to get IDENTIFY data.
  //
  Status = AtaPioDataIn (
            IdeDev,
            (VOID *) AtapiIdentifyPointer,
            sizeof (EFI_IDENTIFY_DATA),
            ATA_CMD_IDENTIFY_DEVICE,
            DeviceSelect,
            0,
            0,
            0,
            0
            );

  if (EFI_ERROR (Status)) {
    gBS->FreePool (AtapiIdentifyPointer);
    return EFI_DEVICE_ERROR;
  }

  IdeDev->IdData = AtapiIdentifyPointer;
  PrintAtaModuleName (IdeDev);

  //
  // Send ATAPI Inquiry Packet Command to get INQUIRY data.
  //
  Status = AtapiInquiry (IdeDev);
  if (EFI_ERROR (Status)) {
    gBS->FreePool (IdeDev->IdData);
    //
    // Make sure the pIdData will not be freed again.
    //
    IdeDev->IdData = NULL;
    return EFI_DEVICE_ERROR;
  }
  //
  // Get media removable info from INQUIRY data.
  //
  IdeDev->BlkIo.Media->RemovableMedia = (UINT8) ((IdeDev->InquiryData->RMB & 0x80) == 0x80);

  //
  // Identify device type via INQUIRY data.
  //
  switch (IdeDev->InquiryData->peripheral_type & 0x1f) {

  //
  // Magnetic Disk
  //
  case 0x00:

    //
    // device is LS120 or ZIP drive.
    //
    IdeDev->Type = IdeMagnetic;

    IdeDev->BlkIo.Media->MediaId      = 0;
    //
    // Give initial value
    //
    IdeDev->BlkIo.Media->MediaPresent = FALSE;

    IdeDev->BlkIo.Media->LastBlock  = 0;
    IdeDev->BlkIo.Media->BlockSize  = 0x200;
    break;

  //
  // CD-ROM
  //
  case 0x05:

    IdeDev->Type                      = IdeCdRom;
    IdeDev->BlkIo.Media->MediaId      = 0;
    //
    // Give initial value
    //
    IdeDev->BlkIo.Media->MediaPresent = FALSE;

    IdeDev->BlkIo.Media->LastBlock  = 0;
    IdeDev->BlkIo.Media->BlockSize  = 0x800;
    IdeDev->BlkIo.Media->ReadOnly   = TRUE;
    break;

  //
  // Tape
  //
  case 0x01:

  //
  // WORM
  //
  case 0x04:
  
  //
  // Optical
  //
  case 0x07:

  default:
    IdeDev->Type = IdeUnknown;
    gBS->FreePool (IdeDev->IdData);
    gBS->FreePool (IdeDev->InquiryData);
    //
    // Make sure the pIdData and pInquiryData will not be freed again.
    //
    IdeDev->IdData       = NULL;
    IdeDev->InquiryData  = NULL;
    return EFI_DEVICE_ERROR;
  }

  //
  // original sense data numbers
  //
  IdeDev->SenseDataNumber = 20;

  IdeDev->SenseData = AllocatePool (IdeDev->SenseDataNumber * sizeof (ATAPI_REQUEST_SENSE_DATA));
  if (IdeDev->SenseData == NULL) {
    gBS->FreePool (IdeDev->IdData);
    gBS->FreePool (IdeDev->InquiryData);
    //
    // Make sure the pIdData and pInquiryData will not be freed again.
    //
    IdeDev->IdData       = NULL;
    IdeDev->InquiryData  = NULL;
    return EFI_OUT_OF_RESOURCES;
  }

  return EFI_SUCCESS;
}
/**
  Sends out ATAPI Request Sense Packet Command to the specified device. This command
  will return all the current Sense data in the device.  This function will pack 
  all the Sense data in one single buffer.

  @param IdeDev       pointer pointing to IDE_BLK_IO_DEV data structure, used
                      to record all the information of the IDE device.
  @param SenseCounts  allocated in this function, and freed by the calling function.
                      This buffer is used to accommodate all the sense data returned 
                      by the device.

  @retval EFI_SUCCESS      Request Sense command completes successfully.
  @retval EFI_DEVICE_ERROR Request Sense command failed.
**/
EFI_STATUS
AtapiRequestSense (
  IN  IDE_BLK_IO_DEV  *IdeDev,
  OUT UINTN           *SenseCounts
  )
{
  EFI_STATUS            Status;
  ATAPI_REQUEST_SENSE_DATA    *Sense;
  UINT16                *Ptr;
  BOOLEAN               FetchSenseData;
  ATAPI_PACKET_COMMAND  Packet;

  *SenseCounts = 0;

  ZeroMem (IdeDev->SenseData, sizeof (ATAPI_REQUEST_SENSE_DATA) * (IdeDev->SenseDataNumber));
  //
  // fill command packet for Request Sense Packet Command
  //
  ZeroMem (&Packet, sizeof (ATAPI_PACKET_COMMAND));
  Packet.RequestSence.opcode            = ATA_CMD_REQUEST_SENSE;
  Packet.RequestSence.allocation_length = sizeof (ATAPI_REQUEST_SENSE_DATA);

  //
  // initialize pointer
  //
  Ptr = (UINT16 *) IdeDev->SenseData;
  //
  //  request sense data from device continuously until no sense data
  //  exists in the device.
  //
  for (FetchSenseData = TRUE; FetchSenseData;) {

    Sense = (ATAPI_REQUEST_SENSE_DATA *) Ptr;

    //
    // send out Request Sense Packet Command and get one Sense data form device
    //
    Status = AtapiPacketCommandIn (
              IdeDev,
              &Packet,
              Ptr,
              sizeof (ATAPI_REQUEST_SENSE_DATA),
              ATAPITIMEOUT
              );
    //
    // failed to get Sense data
    //
    if (EFI_ERROR (Status)) {
      if (*SenseCounts == 0) {
        return EFI_DEVICE_ERROR;
      } else {
        return EFI_SUCCESS;
      }
    }

    (*SenseCounts)++;
    //
    // We limit MAX sense data count to 20 in order to avoid dead loop. Some
    // incompatible ATAPI devices don't retrive NO_SENSE when there is no media.
    // In this case, dead loop occurs if we don't have a gatekeeper. 20 is
    // supposed to be large enough for any ATAPI device.
    //
    if ((Sense->sense_key != ATA_SK_NO_SENSE) && ((*SenseCounts) < 20)) {
      //
      // Ptr is word-based pointer
      //
      Ptr += (sizeof (ATAPI_REQUEST_SENSE_DATA) + 1) >> 1;

    } else {
      //
      // when no sense key, skip out the loop
      //
      FetchSenseData = FALSE;
    }
  }

  return EFI_SUCCESS;
}
/**
  This function is used to parse sense data. Only the first sense data is honoured
  
  @param IdeDev     Indicates the calling context.
  @param SenseCount Count of sense data.
  @param Result    The parsed result.

  @retval EFI_SUCCESS           Successfully parsed.
  @retval EFI_INVALID_PARAMETER Count of sense data is zero.

**/
EFI_STATUS
ParseSenseData (
  IN IDE_BLK_IO_DEV     *IdeDev,
  IN UINTN              SenseCount,
  OUT SENSE_RESULT      *Result
  )
{
  ATAPI_REQUEST_SENSE_DATA      *SenseData;

  if (SenseCount == 0) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // Only use the first sense data
  //
  SenseData = IdeDev->SenseData;
  *Result   = SenseOtherSense;

  switch (SenseData->sense_key) {
  case ATA_SK_NO_SENSE:
    *Result = SenseNoSenseKey;
    break;
  case ATA_SK_NOT_READY:
    switch (SenseData->addnl_sense_code) {
    case ATA_ASC_NO_MEDIA:
      *Result = SenseNoMedia;
      break;
    case ATA_ASC_MEDIA_UPSIDE_DOWN:
      *Result = SenseMediaError;
      break;
    case ATA_ASC_NOT_READY:
      if (SenseData->addnl_sense_code_qualifier == ATA_ASCQ_IN_PROGRESS) {
        *Result = SenseDeviceNotReadyNeedRetry;
      } else {
        *Result = SenseDeviceNotReadyNoRetry;
      }
      break;
    }
    break;
  case ATA_SK_UNIT_ATTENTION:
    if (SenseData->addnl_sense_code == ATA_ASC_MEDIA_CHANGE) {
      *Result = SenseMediaChange;
    }
    break;
  case ATA_SK_MEDIUM_ERROR:
    switch (SenseData->addnl_sense_code) {
    case ATA_ASC_MEDIA_ERR1:
    case ATA_ASC_MEDIA_ERR2:
    case ATA_ASC_MEDIA_ERR3:
    case ATA_ASC_MEDIA_ERR4:
      *Result = SenseMediaError;
      break;
    }
    break;
  default:
    break;
  }

  return EFI_SUCCESS;
}

/**
  Sends out ATAPI Test Unit Ready Packet Command to the specified device
  to find out whether device is accessible.

  @param IdeDev    Pointer pointing to IDE_BLK_IO_DEV data structure, used
                   to record all the information of the IDE device.
  @param SResult   Sense result for this packet command.

  @retval EFI_SUCCESS      Device is accessible.
  @retval EFI_DEVICE_ERROR Device is not accessible.

**/
EFI_STATUS
AtapiTestUnitReady (
  IN  IDE_BLK_IO_DEV  *IdeDev,
  OUT SENSE_RESULT    *SResult  
  )
{
  ATAPI_PACKET_COMMAND  Packet;
  EFI_STATUS            Status;
  UINTN 				SenseCount;

  //
  // fill command packet
  //
  ZeroMem (&Packet, sizeof (ATAPI_PACKET_COMMAND));
  Packet.TestUnitReady.opcode = ATA_CMD_TEST_UNIT_READY;

  //
  // send command packet
  //
  Status = AtapiPacketCommandIn (IdeDev, &Packet, NULL, 0, ATAPITIMEOUT);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  Status = AtapiRequestSense (IdeDev, &SenseCount);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  ParseSenseData (IdeDev, SenseCount, SResult);
  return EFI_SUCCESS;
}


/**
  Sends out ATAPI Read Capacity Packet Command to the specified device.
  This command will return the information regarding the capacity of the
  media in the device.

  Current device status will impact device's response to the Read Capacity
  Command. For example, if the device once reset, the Read Capacity
  Command will fail. The Sense data record the current device status, so 
  if the Read Capacity Command failed, the Sense data must be requested
  and be analyzed to determine if the Read Capacity Command should retry.

  @param IdeDev    Pointer pointing to IDE_BLK_IO_DEV data structure, used
                   to record all the information of the IDE device.
  @param SResult   Sense result for this packet command

  @retval EFI_SUCCESS      Read Capacity Command finally completes successfully.
  @retval EFI_DEVICE_ERROR Read Capacity Command failed because of device error.
  @retval EFI_NOT_READY    Operation succeeds but returned capacity is 0

  @note Parameter "IdeDev" will be updated in this function.

  
**/
EFI_STATUS
AtapiReadCapacity (
  IN  IDE_BLK_IO_DEV  *IdeDev,
  OUT SENSE_RESULT	  *SResult  
  )
{
  //
  // status returned by Read Capacity Packet Command
  //
  EFI_STATUS                Status;
  EFI_STATUS                SenseStatus;
  ATAPI_PACKET_COMMAND      Packet;
  UINTN 					SenseCount;

  //
  // used for capacity data returned from ATAPI device
  //
  ATAPI_READ_CAPACITY_DATA        Data;
  ATAPI_READ_FORMAT_CAPACITY_DATA FormatData;

  ZeroMem (&Data, sizeof (Data));
  ZeroMem (&FormatData, sizeof (FormatData));

  if (IdeDev->Type == IdeCdRom) {

    ZeroMem (&Packet, sizeof (ATAPI_PACKET_COMMAND));
    Packet.Inquiry.opcode = ATA_CMD_READ_CAPACITY;
    Status = AtapiPacketCommandIn (
               IdeDev,
               &Packet,
               (UINT16 *) &Data,
               sizeof (ATAPI_READ_CAPACITY_DATA),
               ATAPITIMEOUT
               );

  } else {
    //
    // Type == IdeMagnetic
    //
    ZeroMem (&Packet, sizeof (ATAPI_PACKET_COMMAND));
    Packet.ReadFormatCapacity.opcode                = ATA_CMD_READ_FORMAT_CAPACITY;
    Packet.ReadFormatCapacity.allocation_length_lo  = 12;
    Status = AtapiPacketCommandIn (
               IdeDev,
               &Packet,
               (UINT16 *) &FormatData,
               sizeof (ATAPI_READ_FORMAT_CAPACITY_DATA),
               ATAPITIMEOUT
               );
  }

  if (Status == EFI_TIMEOUT) {
    return Status;
  }

  SenseStatus = AtapiRequestSense (IdeDev, &SenseCount);

  if (!EFI_ERROR (SenseStatus)) {
	ParseSenseData (IdeDev, SenseCount, SResult);			 
															 
	if (!EFI_ERROR (Status) && *SResult == SenseNoSenseKey) {
      if (IdeDev->Type == IdeCdRom) {

        IdeDev->BlkIo.Media->LastBlock = (Data.LastLba3 << 24) |
          (Data.LastLba2 << 16) |
          (Data.LastLba1 << 8) |
          Data.LastLba0;

	      IdeDev->BlkIo.Media->MediaPresent = TRUE;

        IdeDev->BlkIo.Media->ReadOnly = TRUE;

        //
        // Because the user data portion in the sector of the Data CD supported
        // is always 0x800
        //
        IdeDev->BlkIo.Media->BlockSize = 0x800;
      }

      if (IdeDev->Type == IdeMagnetic) {

        if (FormatData.DesCode == 3) {
          IdeDev->BlkIo.Media->MediaPresent = FALSE;
          IdeDev->BlkIo.Media->LastBlock    = 0;
        } else {

          IdeDev->BlkIo.Media->LastBlock =  (FormatData.LastLba3 << 24) |
            (FormatData.LastLba2 << 16) | 
            (FormatData.LastLba1 << 8)  |
            FormatData.LastLba0;
          if (IdeDev->BlkIo.Media->LastBlock != 0) {
            IdeDev->BlkIo.Media->LastBlock--;

            IdeDev->BlkIo.Media->BlockSize = (FormatData.BlockSize2 << 16) |
              (FormatData.BlockSize1 << 8) |
              FormatData.BlockSize0;

            IdeDev->BlkIo.Media->MediaPresent = TRUE;
          } else {
            IdeDev->BlkIo.Media->MediaPresent = FALSE;
            //
            // Return EFI_NOT_READY operation succeeds but returned capacity is 0
            //
            return EFI_NOT_READY;
          }

          IdeDev->BlkIo.Media->BlockSize = 0x200;

        }
      }
    }

    return EFI_SUCCESS;

  } else {
    return EFI_DEVICE_ERROR;
  }
}
/**
  This function is used to test the current media write-protected or not residing
  in the LS-120 drive or ZIP drive. 
  @param IdeDev          pointer pointing to IDE_BLK_IO_DEV data structure, used
                         to record all the information of the IDE device.
  @param WriteProtected  if True, current media is write protected.
                         if FALSE, current media is writable

  @retval EFI_SUCCESS         The media write-protected status is achieved successfully
  @retval EFI_DEVICE_ERROR    Get Media Status Command is failed.
**/
EFI_STATUS
IsLS120orZipWriteProtected (
  IN  IDE_BLK_IO_DEV    *IdeDev,
  OUT BOOLEAN           *WriteProtected
  )
{
  EFI_STATUS  Status;

  *WriteProtected = FALSE;

  Status          = LS120EnableMediaStatus (IdeDev, TRUE);
  if (EFI_ERROR (Status)) {
    return EFI_DEVICE_ERROR;
  }

  //
  // the Get Media Status Command is only valid
  // if a Set Features/Enable Media Status Command has been priviously issued.
  //
  if (LS120GetMediaStatus (IdeDev) == EFI_WRITE_PROTECTED) {

    *WriteProtected = TRUE;
  } else {

    *WriteProtected = FALSE;
  }

  //
  // After Get Media Status Command completes,
  // Set Features/Disable Media Command should be sent.
  //
  Status = LS120EnableMediaStatus (IdeDev, FALSE);
  if (EFI_ERROR (Status)) {
    return EFI_DEVICE_ERROR;
  }

  return EFI_SUCCESS;
}

/**
  Used before read/write blocks from/to ATAPI device media. Since ATAPI device 
  media is removable, it is necessary to detect whether media is present and 
  get current present media's information, and if media has been changed, Block
  I/O Protocol need to be reinstalled.

  @param IdeDev       pointer pointing to IDE_BLK_IO_DEV data structure, used
                      to record all the information of the IDE device.
  @param MediaChange  return value that indicates if the media of the device has been
                      changed.

  @retval EFI_SUCCESS       media found successfully.
  @retval EFI_DEVICE_ERROR  any error encounters during media detection.
  @retval EFI_NO_MEDIA      media not found.

  @note
  parameter IdeDev may be updated in this function.

**/
EFI_STATUS
AtapiDetectMedia (
  IN  IDE_BLK_IO_DEV  *IdeDev,
  OUT BOOLEAN         *MediaChange
  )
{
  EFI_STATUS                    Status;
  EFI_STATUS                    CleanStateStatus;
  EFI_BLOCK_IO_MEDIA            OldMediaInfo;
  UINTN                         RetryTimes;
  UINTN                         RetryNotReady;
  SENSE_RESULT                  SResult;
  BOOLEAN                       WriteProtected;

  CopyMem (&OldMediaInfo, IdeDev->BlkIo.Media, sizeof (EFI_BLOCK_IO_MEDIA));
  *MediaChange  = FALSE;
  //
  // Retry for SenseDeviceNotReadyNeedRetry.
  // Each retry takes 1s and we limit the upper boundary to
  // 120 times about 2 min.
  //
  RetryNotReady = 120;

  //
  // Do Test Unit Ready
  //
 DoTUR:
  //
  // Retry 5 times
  //
  RetryTimes = 5;
  while (RetryTimes != 0) {

    Status = AtapiTestUnitReady (IdeDev, &SResult);

    if (EFI_ERROR (Status)) {
      //
      // Test Unit Ready error without sense data.
      // For some devices, this means there's extra data
      // that has not been read, so we read these extra
      // data out before going on.
      //
      CleanStateStatus = AtapiReadPendingData (IdeDev);
      if (EFI_ERROR (CleanStateStatus)) {
        //
        // Busy wait failed, try again
        //
        RetryTimes--;
      }
      //
      // Try again without counting down RetryTimes
      //
      continue;
    } else {
      switch (SResult) {
      case SenseNoSenseKey:
        if (IdeDev->BlkIo.Media->MediaPresent) {
          goto Done;
        } else {
          //
          // Media present but the internal structure need refreshed.
          // Try Read Capacity
          //
          goto DoRC;
        }
        break;

      case SenseDeviceNotReadyNeedRetry:
        if (--RetryNotReady == 0) {
          return EFI_DEVICE_ERROR;
        }
        gBS->Stall (1000 * STALL_1_MILLI_SECOND);
        continue;
        break;

      case SenseNoMedia:
        IdeDev->BlkIo.Media->MediaPresent = FALSE;
        IdeDev->BlkIo.Media->LastBlock    = 0;
        goto Done;
        break;

      case SenseDeviceNotReadyNoRetry:
      case SenseMediaError:
        return EFI_DEVICE_ERROR;

      case SenseMediaChange:
        IdeDev->BlkIo.Media->MediaId++;
        goto DoRC;
        break;

      default:
        RetryTimes--;
        break;
      }
    }
  }

  return EFI_DEVICE_ERROR;

  //
  // Do Read Capacity
  //
 DoRC:
    RetryTimes = 5;

    while (RetryTimes != 0) {

      Status = AtapiReadCapacity (IdeDev, &SResult);

      if (EFI_ERROR (Status)) {
        RetryTimes--;
        continue;
      } else {
        switch (SResult) {
        case SenseNoSenseKey:
          goto Done;
          break;

        case SenseDeviceNotReadyNeedRetry:
          //
          // We use Test Unit Ready to retry which
          // is faster.
          //
          goto DoTUR;
          break;

        case SenseNoMedia:
          IdeDev->BlkIo.Media->MediaPresent = FALSE;
          IdeDev->BlkIo.Media->LastBlock    = 0;
          goto Done;
          break;

        case SenseDeviceNotReadyNoRetry:
        case SenseMediaError:
          return EFI_DEVICE_ERROR;

        case SenseMediaChange:
          IdeDev->BlkIo.Media->MediaId++;
          continue;
          break;

        default:
          RetryTimes--;
          break;
        }
      }
    }

  return EFI_DEVICE_ERROR;

 Done:
  //
  // the following code is to check the write-protected for LS120 media
  //
  if ((IdeDev->BlkIo.Media->MediaPresent) && (IdeDev->Type == IdeMagnetic)) {

    Status = IsLS120orZipWriteProtected (IdeDev, &WriteProtected);
    if (!EFI_ERROR (Status)) {

      if (WriteProtected) {

        IdeDev->BlkIo.Media->ReadOnly = TRUE;
      } else {

        IdeDev->BlkIo.Media->ReadOnly = FALSE;
      }

    }
  }

  if (IdeDev->BlkIo.Media->MediaId != OldMediaInfo.MediaId) {
    //
    // Media change information got from the device
    //
    *MediaChange = TRUE;
  }

  if (IdeDev->BlkIo.Media->ReadOnly != OldMediaInfo.ReadOnly) {
    *MediaChange = TRUE;
    IdeDev->BlkIo.Media->MediaId += 1;
  }

  if (IdeDev->BlkIo.Media->BlockSize != OldMediaInfo.BlockSize) {
    *MediaChange = TRUE;
    IdeDev->BlkIo.Media->MediaId += 1;
  }

  if (IdeDev->BlkIo.Media->LastBlock != OldMediaInfo.LastBlock) {
    *MediaChange = TRUE;
    IdeDev->BlkIo.Media->MediaId += 1;
  }

  if (IdeDev->BlkIo.Media->MediaPresent != OldMediaInfo.MediaPresent) {
    if (IdeDev->BlkIo.Media->MediaPresent) {
      //
      // when change from no media to media present, reset the MediaId to 1.
      //
      IdeDev->BlkIo.Media->MediaId = 1;
    } else {
      //
      // when no media, reset the MediaId to zero.
      //
      IdeDev->BlkIo.Media->MediaId = 0;
    }

    *MediaChange = TRUE;
  }

  //
  // if any change on current existing media,
  // the Block I/O protocol need to be reinstalled.
  //
  if (*MediaChange) {
    gBS->ReinstallProtocolInterface (
          IdeDev->Handle,
          &gEfiBlockIoProtocolGuid,
          &IdeDev->BlkIo,
          &IdeDev->BlkIo
          );
  }

  if (IdeDev->BlkIo.Media->MediaPresent) {
    return EFI_SUCCESS;
  } else {
    return EFI_NO_MEDIA;
  }
}

/**
  This function is called by the AtapiBlkIoReadBlocks() to perform
  read from media in block unit.

  The main command used to access media here is READ(10) Command. 
  READ(10) Command requests that the ATAPI device media transfer 
  specified data to the host. Data is transferred in block(sector) 
  unit. The maximum number of blocks that can be transferred once is
  65536. This is the main difference between READ(10) and READ(12) 
  Command. The maximum number of blocks in READ(12) is 2 power 32.

  @param IdeDev           pointer pointing to IDE_BLK_IO_DEV data structure, used
                          to record all the information of the IDE device.
  @param Buffer           A pointer to the destination buffer for the data. 
  @param Lba              The starting logical block address to read from on the 
                          device media.
  @param NumberOfBlocks   The number of transfer data blocks.

  @return status is fully dependent on the return status of AtapiPacketCommandIn() function.

**/
EFI_STATUS
AtapiReadSectors (
  IN  IDE_BLK_IO_DEV  *IdeDev,
  IN  VOID            *Buffer,
  IN  EFI_LBA         Lba,
  IN  UINTN           NumberOfBlocks
  )
{

  ATAPI_PACKET_COMMAND  Packet;
  ATAPI_READ10_CMD            *Read10Packet;
  EFI_STATUS            Status;
  UINTN                 BlocksRemaining;
  UINT32                Lba32;
  UINT32                BlockSize;
  UINT32                ByteCount;
  UINT16                SectorCount;
  VOID                  *PtrBuffer;
  UINT16                MaxBlock;
  UINTN                 TimeOut;

  //
  // fill command packet for Read(10) command
  //
  ZeroMem (&Packet, sizeof (ATAPI_PACKET_COMMAND));
  Read10Packet  = &Packet.Read10;
  Lba32         = (UINT32) Lba;
  PtrBuffer     = Buffer;

  BlockSize     = IdeDev->BlkIo.Media->BlockSize;

  //
  // limit the data bytes that can be transferred by one Read(10) Command
  //
  MaxBlock        = 65535;

  BlocksRemaining = NumberOfBlocks;

  Status          = EFI_SUCCESS;
  while (BlocksRemaining > 0) {

    if (BlocksRemaining <= MaxBlock) {

      SectorCount = (UINT16) BlocksRemaining;
    } else {

      SectorCount = MaxBlock;
    }

    //
    // fill the Packet data structure
    //

    Read10Packet->opcode = ATA_CMD_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;

    if (IdeDev->Type == IdeCdRom) {
      TimeOut = CDROMLONGTIMEOUT;
    } else {
      TimeOut = ATAPILONGTIMEOUT;
    }

    Status = AtapiPacketCommandIn (
              IdeDev,
              &Packet,
              (UINT16 *) PtrBuffer,
              ByteCount,
              TimeOut
              );
    if (EFI_ERROR (Status)) {
      return Status;
    }

    Lba32 += SectorCount;
    PtrBuffer = (UINT8 *) PtrBuffer + SectorCount * BlockSize;
    BlocksRemaining -= SectorCount;
  }

  return Status;
}

/**
  This function is called by the AtapiBlkIoWriteBlocks() to perform
  write onto media in block unit.
  The main command used to access media here is Write(10) Command. 
  Write(10) Command requests that the ATAPI device media transfer 
  specified data to the host. Data is transferred in block (sector) 
  unit. The maximum number of blocks that can be transferred once is
  65536. 

  @param IdeDev          pointer pointing to IDE_BLK_IO_DEV data structure, used
                         to record all the information of the IDE device.
  @param Buffer          A pointer to the source buffer for the data. 
  @param Lba             The starting logical block address to write onto 
                         the device media.
  @param NumberOfBlocks  The number of transfer data blocks.
  
  @return status is fully dependent on the return status of AtapiPacketCommandOut() function.

**/
EFI_STATUS
AtapiWriteSectors (
  IN  IDE_BLK_IO_DEV  *IdeDev,
  IN  VOID            *Buffer,
  IN  EFI_LBA         Lba,
  IN  UINTN           NumberOfBlocks
  )
{

  ATAPI_PACKET_COMMAND  Packet;
  ATAPI_READ10_CMD            *Read10Packet;

  EFI_STATUS            Status;
  UINTN                 BlocksRemaining;
  UINT32                Lba32;
  UINT32                BlockSize;
  UINT32                ByteCount;
  UINT16                SectorCount;
  VOID                  *PtrBuffer;
  UINT16                MaxBlock;

  //
  // fill command packet for Write(10) command
  // Write(10) command packet has the same data structure as
  // Read(10) command packet,
  // so here use the Read10Packet data structure
  // for the Write(10) command packet.
  //
  ZeroMem (&Packet, sizeof (ATAPI_PACKET_COMMAND));
  Read10Packet  = &Packet.Read10;

  Lba32         = (UINT32) Lba;
  PtrBuffer     = Buffer;

  BlockSize     = IdeDev->BlkIo.Media->BlockSize;

  //
  // limit the data bytes that can be transferred by one Read(10) Command
  //
  MaxBlock        = (UINT16) (65536 / BlockSize);

  BlocksRemaining = NumberOfBlocks;

  Status          = EFI_SUCCESS;
  while (BlocksRemaining > 0) {

    if (BlocksRemaining >= MaxBlock) {
      SectorCount = MaxBlock;
    } else {
      SectorCount = (UINT16) BlocksRemaining;
    }
  
    //
    // Command code is WRITE_10.
    //
    Read10Packet->opcode = ATA_CMD_WRITE_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;

    Status = AtapiPacketCommandOut (
              IdeDev,
              &Packet,
              (UINT16 *) PtrBuffer,
              ByteCount,
              ATAPILONGTIMEOUT
              );
    if (EFI_ERROR (Status)) {
      return Status;
    }

    Lba32 += SectorCount;
    PtrBuffer = ((UINT8 *) PtrBuffer + SectorCount * BlockSize);
    BlocksRemaining -= SectorCount;
  }

  return Status;
}
/**
  This function is used to implement the Soft Reset on the specified
  ATAPI device. Different from the AtaSoftReset(), here reset is a ATA
  Soft Reset Command special for ATAPI device, and it only take effects
  on the specified ATAPI device, not on the whole IDE bus.
  Since the ATAPI soft reset is needed when device is in exceptional
  condition (such as BSY bit is always set ), I think the Soft Reset
  command should be sent without waiting for the BSY clear and DRDY
  set.
  This function is called by IdeBlkIoReset(), 
  a interface function of Block I/O protocol.

  @param IdeDev    pointer pointing to IDE_BLK_IO_DEV data structure, used
                   to record all the information of the IDE device.

  @retval EFI_SUCCESS      Soft reset completes successfully.
  @retval EFI_DEVICE_ERROR Any step during the reset process is failed.

**/
EFI_STATUS
AtapiSoftReset (
  IN  IDE_BLK_IO_DEV  *IdeDev
  )
{
  UINT8       Command;
  UINT8       DeviceSelect;
  EFI_STATUS  Status;

  //
  // for ATAPI device, no need to wait DRDY ready after device selecting.
  // (bit7 and bit5 are both set to 1 for backward compatibility)
  //
  DeviceSelect = (UINT8) (((BIT7 | BIT5) | (IdeDev->Device << 4)));
  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Head, DeviceSelect);

  Command = ATA_CMD_SOFT_RESET;
  IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Command, Command);

  //
  // BSY cleared is the only status return to the host by the device
  // when reset is completed.
  // slave device needs at most 31s to clear BSY
  //
  Status = WaitForBSYClear (IdeDev, 31000);
  if (EFI_ERROR (Status)) {
    return EFI_DEVICE_ERROR;
  }
  
  //
  // stall 5 seconds to make the device status stable
  //
  gBS->Stall (5000000);

  return EFI_SUCCESS;
}

/**
  This function is the ATAPI implementation for ReadBlocks in the
  Block I/O Protocol interface.

  @param IdeBlkIoDevice Indicates the calling context.
  @param MediaId        The media id that the read request is for.
  @param Lba            The starting logical block address to read from on the device.
  @param BufferSize     The size of the Buffer in bytes. This must be a multiple
                        of the intrinsic block size of the device.
  @param Buffer         A pointer to the destination buffer for the data. The caller
                        is responsible for either having implicit or explicit 
                        ownership of the memory that data is read into.
  
  @retval EFI_SUCCESS           Read Blocks successfully.
  @retval EFI_DEVICE_ERROR      Read Blocks failed.
  @retval EFI_NO_MEDIA          There is no media in the device.
  @retval EFI_MEDIA_CHANGED     The MediaId is not for the current media.
  @retval EFI_BAD_BUFFER_SIZE   The BufferSize parameter is not a multiple of the
                                intrinsic block size of the device.
  @retval EFI_INVALID_PARAMETER The read request contains LBAs that are not valid,
                                or the data buffer is not valid.
**/
EFI_STATUS
AtapiBlkIoReadBlocks (
  IN IDE_BLK_IO_DEV   *IdeBlkIoDevice,
  IN UINT32           MediaId,
  IN EFI_LBA          Lba,
  IN UINTN            BufferSize,
  OUT VOID            *Buffer
  )
{
  EFI_BLOCK_IO_MEDIA  *Media;
  UINTN               BlockSize;
  UINTN               NumberOfBlocks;
  EFI_STATUS          Status;

  BOOLEAN             MediaChange;

  if (Buffer == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  if (BufferSize == 0) {
    return EFI_SUCCESS;
  }

  //
  // ATAPI device media is removable, so it is a must
  // to detect media first before read operation
  //
  MediaChange = FALSE;
  Status      = AtapiDetectMedia (IdeBlkIoDevice, &MediaChange);
  if (EFI_ERROR (Status)) {

    if (IdeBlkIoDevice->Cache != NULL) {
      gBS->FreePool (IdeBlkIoDevice->Cache);
      IdeBlkIoDevice->Cache = NULL;
    }

    return Status;
  }
  //
  // Get the intrinsic block size
  //
  Media           = IdeBlkIoDevice->BlkIo.Media;
  BlockSize       = Media->BlockSize;

  NumberOfBlocks  = BufferSize / BlockSize;

  if (!(Media->MediaPresent)) {

    if (IdeBlkIoDevice->Cache != NULL) {
      gBS->FreePool (IdeBlkIoDevice->Cache);
      IdeBlkIoDevice->Cache = NULL;
    }
    return EFI_NO_MEDIA;

  }

  if ((MediaId != Media->MediaId) || MediaChange) {

    if (IdeBlkIoDevice->Cache != NULL) {
      gBS->FreePool (IdeBlkIoDevice->Cache);
      IdeBlkIoDevice->Cache = NULL;
    }
    return EFI_MEDIA_CHANGED;
  }

  if (BufferSize % BlockSize != 0) {
    return EFI_BAD_BUFFER_SIZE;
  }

  if (Lba > Media->LastBlock) {
    return EFI_INVALID_PARAMETER;
  }

  if ((Lba + NumberOfBlocks - 1) > Media->LastBlock) {
    return EFI_INVALID_PARAMETER;
  }

  if ((Media->IoAlign > 1) && (((UINTN) Buffer & (Media->IoAlign - 1)) != 0)) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // if all the parameters are valid, then perform read sectors command
  // to transfer data from device to host.
  //
  Status = AtapiReadSectors (IdeBlkIoDevice, Buffer, Lba, NumberOfBlocks);
  if (EFI_ERROR (Status)) {
    return EFI_DEVICE_ERROR;
  }
  
  //
  // Read blocks succeeded
  //
  
  //
  // save the first block to the cache for performance
  //
  if (Lba == 0 && (IdeBlkIoDevice->Cache == NULL)) {
    IdeBlkIoDevice->Cache = AllocatePool (BlockSize);
    if (IdeBlkIoDevice->Cache!= NULL) {
      CopyMem ((UINT8 *) IdeBlkIoDevice->Cache, (UINT8 *) Buffer, BlockSize);
    }
  }

  return EFI_SUCCESS;

}
/**
  This function is the ATAPI implementation for WriteBlocks in the
  Block I/O Protocol interface.

  @param IdeBlkIoDevice  Indicates the calling context.
  @param MediaId         The media id that the write request is for.
  @param Lba             The starting logical block address to write onto the device.
  @param BufferSize      The size of the Buffer in bytes. This must be a multiple
                         of the intrinsic block size of the device.
  @param Buffer          A pointer to the source buffer for the data. The caller
                         is responsible for either having implicit or explicit ownership
                         of the memory that data is written from.

  @retval EFI_SUCCESS            Write Blocks successfully.
  @retval EFI_DEVICE_ERROR       Write Blocks failed.
  @retval EFI_NO_MEDIA           There is no media in the device.
  @retval EFI_MEDIA_CHANGE       The MediaId is not for the current media.
  @retval EFI_BAD_BUFFER_SIZE    The BufferSize parameter is not a multiple of the
                                 intrinsic block size of the device.  
  @retval EFI_INVALID_PARAMETER  The write request contains LBAs that are not valid, 
                                 or the data buffer is not valid.

  @retval EFI_WRITE_PROTECTED    The write protected is enabled or the media does not support write
**/
EFI_STATUS
AtapiBlkIoWriteBlocks (
  IN IDE_BLK_IO_DEV   *IdeBlkIoDevice,
  IN UINT32           MediaId,
  IN EFI_LBA          Lba,
  IN UINTN            BufferSize,
  OUT VOID            *Buffer
  )
{

  EFI_BLOCK_IO_MEDIA  *Media;
  UINTN               BlockSize;
  UINTN               NumberOfBlocks;
  EFI_STATUS          Status;
  BOOLEAN             MediaChange;

  if (Lba == 0 && IdeBlkIoDevice->Cache != NULL) {
    gBS->FreePool (IdeBlkIoDevice->Cache);
    IdeBlkIoDevice->Cache = NULL;
  }

  if (Buffer == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  if (BufferSize == 0) {
    return EFI_SUCCESS;
  }

  //
  // ATAPI device media is removable,
  // so it is a must to detect media first before write operation
  //
  MediaChange = FALSE;
  Status      = AtapiDetectMedia (IdeBlkIoDevice, &MediaChange);
  if (EFI_ERROR (Status)) {

    if (Lba == 0 && IdeBlkIoDevice->Cache != NULL) {
      gBS->FreePool (IdeBlkIoDevice->Cache);
      IdeBlkIoDevice->Cache = NULL;
    }
    return Status;
  }
  
  //
  // Get the intrinsic block size
  //
  Media           = IdeBlkIoDevice->BlkIo.Media;
  BlockSize       = Media->BlockSize;
  NumberOfBlocks  = BufferSize / BlockSize;

  if (!(Media->MediaPresent)) {

    if (Lba == 0 && IdeBlkIoDevice->Cache != NULL) {
      gBS->FreePool (IdeBlkIoDevice->Cache);
      IdeBlkIoDevice->Cache = NULL;
    }
    return EFI_NO_MEDIA;
  }

  if ((MediaId != Media->MediaId) || MediaChange) {

    if (Lba == 0 && IdeBlkIoDevice->Cache != NULL) {
      gBS->FreePool (IdeBlkIoDevice->Cache);
      IdeBlkIoDevice->Cache = NULL;
    }
    return EFI_MEDIA_CHANGED;
  }

  if (Media->ReadOnly) {
    return EFI_WRITE_PROTECTED;
  }

  if (BufferSize % BlockSize != 0) {
    return EFI_BAD_BUFFER_SIZE;
  }

  if (Lba > Media->LastBlock) {
    return EFI_INVALID_PARAMETER;
  }

  if ((Lba + NumberOfBlocks - 1) > Media->LastBlock) {
    return EFI_INVALID_PARAMETER;
  }

  if ((Media->IoAlign > 1) && (((UINTN) Buffer & (Media->IoAlign - 1)) != 0)) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // if all the parameters are valid,
  // then perform write sectors command to transfer data from host to device.
  //
  Status = AtapiWriteSectors (IdeBlkIoDevice, Buffer, Lba, NumberOfBlocks);
  if (EFI_ERROR (Status)) {
    return EFI_DEVICE_ERROR;
  }

  return EFI_SUCCESS;

}



