/** @file
   This file contains all helper functions on the ATAPI command 
  
  Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR>
  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  = (UINT8) 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 = (UINT8) 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 = ((UINT32) 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 = ((UINT32) 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;

}



