/** @file
  Routines that use BIOS to support INT 13 devices.

Copyright (c) 1999 - 2015, 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 "BiosBlkIo.h"

//
// Module global variables
//
//
// Address packet is a buffer under 1 MB for all version EDD calls
//
extern EDD_DEVICE_ADDRESS_PACKET  *mEddBufferUnder1Mb;

//
// This is a buffer for INT 13h func 48 information
//
extern BIOS_LEGACY_DRIVE          *mLegacyDriverUnder1Mb;

//
// Buffer of 0xFE00 bytes for EDD 1.1 transfer must be under 1 MB
//  0xFE00 bytes is the max transfer size supported.
//
extern VOID                       *mEdd11Buffer;


/**
  Initialize block I/O device instance

  @param  Dev   Instance of block I/O device instance

  @retval TRUE  Initialization succeeds.
  @retval FALSE Initialization fails.

**/
BOOLEAN
BiosInitBlockIo (
  IN  BIOS_BLOCK_IO_DEV         *Dev
  )
{
  EFI_BLOCK_IO_PROTOCOL *BlockIo;
  EFI_BLOCK_IO_MEDIA    *BlockMedia;
  BIOS_LEGACY_DRIVE     *Bios;

  BlockIo         = &Dev->BlockIo;
  BlockIo->Media  = &Dev->BlockMedia;
  BlockMedia      = BlockIo->Media;
  Bios            = &Dev->Bios;

  if (Int13GetDeviceParameters (Dev, Bios) != 0) {
    if (Int13Extensions (Dev, Bios) != 0) {
      BlockMedia->LastBlock = (EFI_LBA) Bios->Parameters.PhysicalSectors - 1;
      BlockMedia->BlockSize = (UINT32) Bios->Parameters.BytesPerSector;

      if ((Bios->Parameters.Flags & EDD_DEVICE_REMOVABLE) == EDD_DEVICE_REMOVABLE) {
        BlockMedia->RemovableMedia = TRUE;
      }

    } else {
      //
      // Legacy Interfaces
      //
      BlockMedia->BlockSize = 512;
      BlockMedia->LastBlock = (Bios->MaxHead + 1) * Bios->MaxSector * (Bios->MaxCylinder + 1) - 1;
    }

    DEBUG ((DEBUG_INIT, "BlockSize = %d  LastBlock = %d\n", BlockMedia->BlockSize, BlockMedia->LastBlock));

    BlockMedia->LogicalPartition  = FALSE;
    BlockMedia->WriteCaching      = FALSE;

    //
    // BugBug: Need to set this for removable media devices if they do not
    //  have media present
    //
    BlockMedia->ReadOnly      = FALSE;
    BlockMedia->MediaPresent  = TRUE;

    BlockIo->Reset            = BiosBlockIoReset;
    BlockIo->FlushBlocks      = BiosBlockIoFlushBlocks;

    if (!Bios->ExtendedInt13) {
      //
      // Legacy interfaces
      //
      BlockIo->ReadBlocks   = BiosReadLegacyDrive;
      BlockIo->WriteBlocks  = BiosWriteLegacyDrive;
    } else if ((Bios->EddVersion == EDD_VERSION_30) && (Bios->Extensions64Bit)) {
      //
      // EDD 3.0 Required for Device path, but extended reads are not required.
      //
      BlockIo->ReadBlocks   = Edd30BiosReadBlocks;
      BlockIo->WriteBlocks  = Edd30BiosWriteBlocks;
    } else {
      //
      // Assume EDD 1.1 - Read and Write functions.
      //  This could be EDD 3.0 without Extensions64Bit being set.
      // If it's EDD 1.1 this will work, but the device path will not
      //  be correct. This will cause confusion to EFI OS installation.
      //
      BlockIo->ReadBlocks   = Edd11BiosReadBlocks;
      BlockIo->WriteBlocks  = Edd11BiosWriteBlocks;
    }

    BlockMedia->LogicalPartition  = FALSE;
    BlockMedia->WriteCaching      = FALSE;

    return TRUE;
  }

  return FALSE;
}

/**
  Gets parameters of block I/O device.

  @param  BiosBlockIoDev Instance of block I/O device.
  @param  Drive          Legacy drive.

  @return  Result of device parameter retrieval.
 
**/
UINTN
Int13GetDeviceParameters (
  IN  BIOS_BLOCK_IO_DEV    *BiosBlockIoDev,
  IN  BIOS_LEGACY_DRIVE    *Drive
  )
{
  UINTN                 CarryFlag;
  UINT16                Cylinder;
  EFI_IA32_REGISTER_SET Regs;

  ZeroMem (&Regs, sizeof (EFI_IA32_REGISTER_SET));

  Regs.H.AH = 0x08;
  Regs.H.DL = Drive->Number;
  CarryFlag = BiosBlockIoDev->LegacyBios->Int86 (BiosBlockIoDev->LegacyBios, 0x13, &Regs);
  DEBUG ((DEBUG_INIT, "Int13GetDeviceParameters: INT 13 08 DL=%02x : CF=%d AH=%02x\n", Drive->Number, CarryFlag, Regs.H.AH));
  if (CarryFlag != 0 || Regs.H.AH != 0x00) {
    Drive->ErrorCode = Regs.H.AH;
    return FALSE;
  }

  if (Drive->Floppy) {
    if (Regs.H.BL == 0x10) {
      Drive->AtapiFloppy = TRUE;
    } else {
      Drive->MaxHead      = Regs.H.DH;
      Drive->MaxSector    = Regs.H.CL;
      Drive->MaxCylinder  = Regs.H.CH;
      if (Drive->MaxSector == 0) {
        //
        // BugBug: You can not trust the Carry flag.
        //
        return FALSE;
      }
    }
  } else {
    Drive->MaxHead  = (UINT8) (Regs.H.DH & 0x3f);
    Cylinder        = (UINT16) (((UINT16) Regs.H.DH & 0xc0) << 4);
    Cylinder        = (UINT16) (Cylinder | ((UINT16) Regs.H.CL & 0xc0) << 2);
    Drive->MaxCylinder  = (UINT16) (Cylinder + Regs.H.CH);
    Drive->MaxSector    = (UINT8) (Regs.H.CL & 0x3f);
  }

  return TRUE;
}

/**
  Extension of INT13 call.

  @param  BiosBlockIoDev Instance of block I/O device.
  @param  Drive          Legacy drive.

  @return  Result of this extension.
 
**/
UINTN
Int13Extensions (
  IN  BIOS_BLOCK_IO_DEV    *BiosBlockIoDev,
  IN  BIOS_LEGACY_DRIVE    *Drive
  )
{
  INTN                  CarryFlag;
  EFI_IA32_REGISTER_SET Regs;

  ZeroMem (&Regs, sizeof (EFI_IA32_REGISTER_SET));

  Regs.H.AH = 0x41;
  Regs.X.BX = 0x55aa;
  Regs.H.DL = Drive->Number;
  CarryFlag = BiosBlockIoDev->LegacyBios->Int86 (BiosBlockIoDev->LegacyBios, 0x13, &Regs);
  DEBUG ((DEBUG_INIT, "Int13Extensions: INT 13 41 DL=%02x : CF=%d BX=%04x\n", Drive->Number, CarryFlag, Regs.X.BX));
  if (CarryFlag != 0 || Regs.X.BX != 0xaa55) {
    Drive->ExtendedInt13            = FALSE;
    Drive->DriveLockingAndEjecting  = FALSE;
    Drive->Edd                      = FALSE;
    return FALSE;
  }

  Drive->EddVersion               = Regs.H.AH;
  Drive->ExtendedInt13            = (BOOLEAN) ((Regs.X.CX & 0x01) == 0x01);
  Drive->DriveLockingAndEjecting  = (BOOLEAN) ((Regs.X.CX & 0x02) == 0x02);
  Drive->Edd                      = (BOOLEAN) ((Regs.X.CX & 0x04) == 0x04);
  Drive->Extensions64Bit          = (BOOLEAN) (Regs.X.CX & 0x08);

  Drive->ParametersValid          = (UINT8) GetDriveParameters (BiosBlockIoDev, Drive);
  return TRUE;
}

/**
  Gets parameters of legacy drive.

  @param  BiosBlockIoDev Instance of block I/O device.
  @param  Drive          Legacy drive.

  @return  Result of drive parameter retrieval.
 
**/
UINTN
GetDriveParameters (
  IN  BIOS_BLOCK_IO_DEV   *BiosBlockIoDev,
  IN  BIOS_LEGACY_DRIVE   *Drive
  )
{
  INTN                  CarryFlag;
  EFI_IA32_REGISTER_SET Regs;
  UINTN                 PointerMath;

  ZeroMem (&Regs, sizeof (EFI_IA32_REGISTER_SET));

  Regs.H.AH = 0x48;
  Regs.H.DL = Drive->Number;

  //
  // EDD Buffer must be passed in with max buffer size as first entry in the buffer
  //
  mLegacyDriverUnder1Mb->Parameters.StructureSize = (UINT16) sizeof (EDD_DRIVE_PARAMETERS);
  Regs.X.DS = EFI_SEGMENT ((UINTN)(&mLegacyDriverUnder1Mb->Parameters));
  Regs.X.SI = EFI_OFFSET ((UINTN)(&mLegacyDriverUnder1Mb->Parameters));
  CarryFlag = BiosBlockIoDev->LegacyBios->Int86 (BiosBlockIoDev->LegacyBios, 0x13, &Regs);
  DEBUG ((DEBUG_INIT, "GetDriveParameters: INT 13 48 DL=%02x : CF=%d AH=%02x\n", Drive->Number, CarryFlag, Regs.H.AH));
  if (CarryFlag != 0 || Regs.H.AH != 0x00) {
    Drive->ErrorCode = Regs.H.AH;
    SetMem (&Drive->Parameters, sizeof (Drive->Parameters), 0xaf);
    return FALSE;
  }
  //
  // We only have one buffer < 1MB, so copy into our instance data
  //
  CopyMem (
    &Drive->Parameters,
    &mLegacyDriverUnder1Mb->Parameters,
    sizeof (Drive->Parameters)
    );

  if (Drive->AtapiFloppy) {
    //
    // Sense Media Type
    //
    Regs.H.AH = 0x20;
    Regs.H.DL = Drive->Number;
    CarryFlag = BiosBlockIoDev->LegacyBios->Int86 (BiosBlockIoDev->LegacyBios, 0x13, &Regs);
    DEBUG ((DEBUG_INIT, "GetDriveParameters: INT 13 20 DL=%02x : CF=%d AL=%02x\n", Drive->Number, CarryFlag, Regs.H.AL));
    if (CarryFlag != 0) {
      //
      // Media not present or unknown media present
      //
      if ((Drive->Parameters.Flags & EDD_GEOMETRY_VALID) == EDD_GEOMETRY_VALID) {
        Drive->MaxHead    = (UINT8) (Drive->Parameters.MaxHeads - 1);
        Drive->MaxSector  = (UINT8) Drive->Parameters.SectorsPerTrack;
        ASSERT (Drive->MaxSector != 0);
        Drive->MaxCylinder = (UINT16) (Drive->Parameters.MaxCylinders - 1);
      } else {
        Drive->MaxHead      = 0;
        Drive->MaxSector    = 1;
        Drive->MaxCylinder  = 0;
      }

    } else {
      //
      // Media Present
      //
      switch (Regs.H.AL) {
      case 0x03:
        //
        // 720 KB
        //
        Drive->MaxHead      = 1;
        Drive->MaxSector    = 9;
        Drive->MaxCylinder  = 79;
        break;

      case 0x04:
        //
        // 1.44MB
        //
        Drive->MaxHead      = 1;
        Drive->MaxSector    = 18;
        Drive->MaxCylinder  = 79;
        break;

      case 0x06:
        //
        // 2.88MB
        //
        Drive->MaxHead      = 1;
        Drive->MaxSector    = 36;
        Drive->MaxCylinder  = 79;
        break;

      case 0x0C:
        //
        // 360 KB
        //
        Drive->MaxHead      = 1;
        Drive->MaxSector    = 9;
        Drive->MaxCylinder  = 39;
        break;

      case 0x0D:
        //
        // 1.2 MB
        //
        Drive->MaxHead      = 1;
        Drive->MaxSector    = 15;
        Drive->MaxCylinder  = 79;
        break;

      case 0x0E:
        //
        // Toshiba 3 mode
        //
      case 0x0F:
        //
        // NEC 3 mode
        //
      case 0x10:
        //
        // Default Media
        //
        if ((Drive->Parameters.Flags & EDD_GEOMETRY_VALID) == EDD_GEOMETRY_VALID) {
          Drive->MaxHead    = (UINT8) (Drive->Parameters.MaxHeads - 1);
          Drive->MaxSector  = (UINT8) Drive->Parameters.SectorsPerTrack;
          ASSERT (Drive->MaxSector != 0);
          Drive->MaxCylinder = (UINT16) (Drive->Parameters.MaxCylinders - 1);
        } else {
          Drive->MaxHead      = 0;
          Drive->MaxSector    = 1;
          Drive->MaxCylinder  = 0;
        }
        break;

      default:
        //
        // Unknown media type.
        //
        Drive->MaxHead      = 0;
        Drive->MaxSector    = 1;
        Drive->MaxCylinder  = 0;
        break;
      }
    }

    Drive->Parameters.PhysicalSectors = (Drive->MaxHead + 1) * Drive->MaxSector * (Drive->MaxCylinder + 1);
    Drive->Parameters.BytesPerSector  = 512;
  }
  //
  // This data comes from the BIOS so it may not allways be valid
  //  since the BIOS may reuse this buffer for future accesses
  //
  PointerMath = EFI_SEGMENT (Drive->Parameters.Fdpt) << 4;
  PointerMath += EFI_OFFSET (Drive->Parameters.Fdpt);
  Drive->FdptPointer = (VOID *) PointerMath;

  return TRUE;
}
//
// Block IO Routines
//

/**
  Read BufferSize bytes from Lba into Buffer.

  @param  This       Indicates a pointer to the calling context.
  @param  MediaId    Id of the media, changes every time the media is replaced.
  @param  Lba        The starting Logical Block Address to read from
  @param  BufferSize Size of Buffer, must be a multiple of device block size.
  @param  Buffer     A pointer to the destination buffer for the data. The caller is
                     responsible for either having implicit or explicit ownership of the buffer.

  @retval EFI_SUCCESS           The data was read correctly from the device.
  @retval EFI_DEVICE_ERROR      The device reported an error while performing the read.
  @retval EFI_NO_MEDIA          There is no media in the device.
  @retval EFI_MEDIA_CHANGED     The MediaId does not matched the current device.
  @retval EFI_BAD_BUFFER_SIZE   The Buffer was not a multiple of the block size of the device.
  @retval EFI_INVALID_PARAMETER The read request contains LBAs that are not valid, 
                                or the buffer is not on proper alignment.

**/
EFI_STATUS
EFIAPI
Edd30BiosReadBlocks (
  IN  EFI_BLOCK_IO_PROTOCOL *This,
  IN  UINT32                MediaId,
  IN  EFI_LBA               Lba,
  IN  UINTN                 BufferSize,
  OUT VOID                  *Buffer
  )
{
  EFI_BLOCK_IO_MEDIA        *Media;
  BIOS_BLOCK_IO_DEV         *BiosBlockIoDev;
  EDD_DEVICE_ADDRESS_PACKET *AddressPacket;
  //
  // I exist only for readability
  //
  EFI_IA32_REGISTER_SET     Regs;
  UINT64                    TransferBuffer;
  UINTN                     NumberOfBlocks;
  UINTN                     TransferByteSize;
  UINTN                     BlockSize;
  BIOS_LEGACY_DRIVE         *Bios;
  UINTN                     CarryFlag;
  UINTN                     MaxTransferBlocks;
  EFI_BLOCK_IO_PROTOCOL     *BlockIo;

  Media     = This->Media;
  BlockSize = Media->BlockSize;

  ZeroMem (&Regs, sizeof (EFI_IA32_REGISTER_SET));

  if (MediaId != Media->MediaId) {
    return EFI_MEDIA_CHANGED;
  }

  if (Lba > Media->LastBlock) {
    return EFI_INVALID_PARAMETER;
  }

  if ((Lba + (BufferSize / BlockSize) - 1) > Media->LastBlock) {
    return EFI_INVALID_PARAMETER;
  }

  if (BufferSize % BlockSize != 0) {
    return EFI_BAD_BUFFER_SIZE;
  }

  if (Buffer == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  if (BufferSize == 0) {
    return EFI_SUCCESS;
  }

  BiosBlockIoDev    = BIOS_BLOCK_IO_FROM_THIS (This);
  AddressPacket     = mEddBufferUnder1Mb;

  MaxTransferBlocks = MAX_EDD11_XFER / BlockSize;

  TransferBuffer    = (UINT64)(UINTN) Buffer;
  for (; BufferSize > 0;) {
    NumberOfBlocks  = BufferSize / BlockSize;
    NumberOfBlocks  = NumberOfBlocks > MaxTransferBlocks ? MaxTransferBlocks : NumberOfBlocks;
    //
    // Max transfer MaxTransferBlocks
    //
    AddressPacket->PacketSizeInBytes  = (UINT8) sizeof (EDD_DEVICE_ADDRESS_PACKET);
    AddressPacket->Zero               = 0;
    AddressPacket->NumberOfBlocks     = (UINT8) NumberOfBlocks;
    AddressPacket->Zero2              = 0;
    AddressPacket->SegOffset          = 0xffffffff;
    AddressPacket->Lba                = (UINT64) Lba;
    AddressPacket->TransferBuffer     = TransferBuffer;

    Regs.H.AH                         = 0x42;
    Regs.H.DL                         = BiosBlockIoDev->Bios.Number;
    Regs.X.SI                         = EFI_OFFSET (AddressPacket);
    Regs.X.DS                         = EFI_SEGMENT (AddressPacket);

    CarryFlag                         = BiosBlockIoDev->LegacyBios->Int86 (BiosBlockIoDev->LegacyBios, 0x13, &Regs);
    DEBUG (
      (
      DEBUG_BLKIO, "Edd30BiosReadBlocks: INT 13 42 DL=%02x : CF=%d AH=%02x\n", BiosBlockIoDev->Bios.Number,
      CarryFlag, Regs.H.AH
      )
      );

    Media->MediaPresent = TRUE;
    if (CarryFlag != 0) {
      //
      // Return Error Status
      //
      BiosBlockIoDev->Bios.ErrorCode = Regs.H.AH;
      if (BiosBlockIoDev->Bios.ErrorCode == BIOS_DISK_CHANGED) {
        Media->MediaId++;
        Bios = &BiosBlockIoDev->Bios;
        if (Int13GetDeviceParameters (BiosBlockIoDev, Bios) != 0) {
          if (Int13Extensions (BiosBlockIoDev, Bios) != 0) {
            Media->LastBlock  = (EFI_LBA) Bios->Parameters.PhysicalSectors - 1;
            Media->BlockSize  = (UINT32) Bios->Parameters.BytesPerSector;
          } else {
            ASSERT (FALSE);
          }

          Media->ReadOnly = FALSE;
          gBS->HandleProtocol (BiosBlockIoDev->Handle, &gEfiBlockIoProtocolGuid, (VOID **) &BlockIo);
          gBS->ReinstallProtocolInterface (BiosBlockIoDev->Handle, &gEfiBlockIoProtocolGuid, BlockIo, BlockIo);
          return EFI_MEDIA_CHANGED;
        }
      }

      if (Media->RemovableMedia) {
        Media->MediaPresent = FALSE;
      }

      return EFI_DEVICE_ERROR;
    }

    TransferByteSize  = NumberOfBlocks * BlockSize;
    BufferSize        = BufferSize - TransferByteSize;
    TransferBuffer += TransferByteSize;
    Lba += NumberOfBlocks;
  }

  return EFI_SUCCESS;
}

/**
  Write BufferSize bytes from Lba into Buffer.

  @param  This       Indicates a pointer to the calling context.
  @param  MediaId    The media ID that the write request is for.
  @param  Lba        The starting logical block address to be written. The caller is
                     responsible for writing to only legitimate locations.
  @param  BufferSize Size of Buffer, must be a multiple of device block size.
  @param  Buffer     A pointer to the source buffer for the data.

  @retval EFI_SUCCESS           The data was written correctly to the device.
  @retval EFI_WRITE_PROTECTED   The device can not be written to.
  @retval EFI_DEVICE_ERROR      The device reported an error while performing the write.
  @retval EFI_NO_MEDIA          There is no media in the device.
  @retval EFI_MEDIA_CHNAGED     The MediaId does not matched the current device.
  @retval EFI_BAD_BUFFER_SIZE   The Buffer was not a multiple of the block size of the device.
  @retval EFI_INVALID_PARAMETER The write request contains LBAs that are not valid, 
                                or the buffer is not on proper alignment.

**/
EFI_STATUS
EFIAPI
Edd30BiosWriteBlocks (
  IN  EFI_BLOCK_IO_PROTOCOL *This,
  IN  UINT32                MediaId,
  IN  EFI_LBA               Lba,
  IN  UINTN                 BufferSize,
  OUT VOID                  *Buffer
  )
{
  EFI_BLOCK_IO_MEDIA        *Media;
  BIOS_BLOCK_IO_DEV         *BiosBlockIoDev;
  EDD_DEVICE_ADDRESS_PACKET *AddressPacket;
  //
  // I exist only for readability
  //
  EFI_IA32_REGISTER_SET     Regs;
  UINT64                    TransferBuffer;
  UINTN                     NumberOfBlocks;
  UINTN                     TransferByteSize;
  UINTN                     BlockSize;
  BIOS_LEGACY_DRIVE         *Bios;
  UINTN                     CarryFlag;
  UINTN                     MaxTransferBlocks;
  EFI_BLOCK_IO_PROTOCOL     *BlockIo;

  Media     = This->Media;
  BlockSize = Media->BlockSize;

  ZeroMem (&Regs, sizeof (EFI_IA32_REGISTER_SET));

  if (MediaId != Media->MediaId) {
    return EFI_MEDIA_CHANGED;
  }

  if (Lba > Media->LastBlock) {
    return EFI_DEVICE_ERROR;
  }

  if ((Lba + (BufferSize / BlockSize) - 1) > Media->LastBlock) {
    return EFI_INVALID_PARAMETER;
  }

  if (BufferSize % BlockSize != 0) {
    return EFI_BAD_BUFFER_SIZE;
  }

  if (Buffer == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  if (BufferSize == 0) {
    return EFI_SUCCESS;
  }

  BiosBlockIoDev    = BIOS_BLOCK_IO_FROM_THIS (This);
  AddressPacket     = mEddBufferUnder1Mb;

  MaxTransferBlocks = MAX_EDD11_XFER / BlockSize;

  TransferBuffer    = (UINT64)(UINTN) Buffer;
  for (; BufferSize > 0;) {
    NumberOfBlocks  = BufferSize / BlockSize;
    NumberOfBlocks  = NumberOfBlocks > MaxTransferBlocks ? MaxTransferBlocks : NumberOfBlocks;
    //
    // Max transfer MaxTransferBlocks
    //
    AddressPacket->PacketSizeInBytes  = (UINT8) sizeof (EDD_DEVICE_ADDRESS_PACKET);
    AddressPacket->Zero               = 0;
    AddressPacket->NumberOfBlocks     = (UINT8) NumberOfBlocks;
    AddressPacket->Zero2              = 0;
    AddressPacket->SegOffset          = 0xffffffff;
    AddressPacket->Lba                = (UINT64) Lba;
    AddressPacket->TransferBuffer     = TransferBuffer;

    Regs.H.AH                         = 0x43;
    Regs.H.AL                         = 0x00;
    //
    // Write Verify Off
    //
    Regs.H.DL = (UINT8) (BiosBlockIoDev->Bios.Number);
    Regs.X.SI = EFI_OFFSET (AddressPacket);
    Regs.X.DS = EFI_SEGMENT (AddressPacket);

    CarryFlag = BiosBlockIoDev->LegacyBios->Int86 (BiosBlockIoDev->LegacyBios, 0x13, &Regs);
    DEBUG (
      (
      DEBUG_BLKIO, "Edd30BiosWriteBlocks: INT 13 43 DL=%02x : CF=%d AH=%02x\n", BiosBlockIoDev->Bios.Number,
      CarryFlag, Regs.H.AH
      )
      );

    Media->MediaPresent = TRUE;
    if (CarryFlag != 0) {
      //
      // Return Error Status
      //
      BiosBlockIoDev->Bios.ErrorCode = Regs.H.AH;
      if (BiosBlockIoDev->Bios.ErrorCode == BIOS_DISK_CHANGED) {
        Media->MediaId++;
        Bios = &BiosBlockIoDev->Bios;
        if (Int13GetDeviceParameters (BiosBlockIoDev, Bios) != 0) {
          if (Int13Extensions (BiosBlockIoDev, Bios) != 0) {
            Media->LastBlock  = (EFI_LBA) Bios->Parameters.PhysicalSectors - 1;
            Media->BlockSize  = (UINT32) Bios->Parameters.BytesPerSector;
          } else {
            ASSERT (FALSE);
          }

          Media->ReadOnly = FALSE;
          gBS->HandleProtocol (BiosBlockIoDev->Handle, &gEfiBlockIoProtocolGuid, (VOID **) &BlockIo);
          gBS->ReinstallProtocolInterface (BiosBlockIoDev->Handle, &gEfiBlockIoProtocolGuid, BlockIo, BlockIo);
          return EFI_MEDIA_CHANGED;
        }
      } else if (BiosBlockIoDev->Bios.ErrorCode == BIOS_WRITE_PROTECTED) {
        Media->ReadOnly = TRUE;
        return EFI_WRITE_PROTECTED;
      }

      if (Media->RemovableMedia) {
        Media->MediaPresent = FALSE;
      }

      return EFI_DEVICE_ERROR;
    }

    Media->ReadOnly   = FALSE;
    TransferByteSize  = NumberOfBlocks * BlockSize;
    BufferSize        = BufferSize - TransferByteSize;
    TransferBuffer += TransferByteSize;
    Lba += NumberOfBlocks;
  }

  return EFI_SUCCESS;
}

/**
  Flush the Block Device.

  @param  This              Indicates a pointer to the calling context.

  @retval EFI_SUCCESS       All outstanding data was written to the device
  @retval EFI_DEVICE_ERROR  The device reported an error while writting back the data
  @retval EFI_NO_MEDIA      There is no media in the device.

**/
EFI_STATUS
EFIAPI
BiosBlockIoFlushBlocks (
  IN  EFI_BLOCK_IO_PROTOCOL  *This
  )
{
  return EFI_SUCCESS;
}

/**
  Reset the Block Device.

  @param  This                 Indicates a pointer to the calling context.
  @param  ExtendedVerification Driver may perform diagnostics on reset.

  @retval EFI_SUCCESS          The device was reset.
  @retval EFI_DEVICE_ERROR     The device is not functioning properly and could
                               not be reset.

**/
EFI_STATUS
EFIAPI
BiosBlockIoReset (
  IN  EFI_BLOCK_IO_PROTOCOL *This,
  IN  BOOLEAN               ExtendedVerification
  )
{
  BIOS_BLOCK_IO_DEV     *BiosBlockIoDev;
  EFI_IA32_REGISTER_SET Regs;
  UINTN                 CarryFlag;

  BiosBlockIoDev  = BIOS_BLOCK_IO_FROM_THIS (This);

  ZeroMem (&Regs, sizeof (EFI_IA32_REGISTER_SET));

  Regs.H.AH       = 0x00;
  Regs.H.DL       = BiosBlockIoDev->Bios.Number;
  CarryFlag       = BiosBlockIoDev->LegacyBios->Int86 (BiosBlockIoDev->LegacyBios, 0x13, &Regs);
  DEBUG (
    (
    DEBUG_INIT, "BiosBlockIoReset: INT 13 00 DL=%02x : CF=%d AH=%02x\n", BiosBlockIoDev->Bios.Number, CarryFlag,
    Regs.H.AH
    )
    );
  if (CarryFlag != 0) {
    if (Regs.H.AL == BIOS_RESET_FAILED) {
      Regs.H.AH = 0x00;
      Regs.H.DL = BiosBlockIoDev->Bios.Number;
      CarryFlag = BiosBlockIoDev->LegacyBios->Int86 (BiosBlockIoDev->LegacyBios, 0x13, &Regs);
      DEBUG (
        (
        DEBUG_INIT, "BiosBlockIoReset: INT 13 00 DL=%02x : CF=%d AH=%02x\n", BiosBlockIoDev->Bios.Number, CarryFlag,
        Regs.H.AH
        )
        );
      if (CarryFlag != 0) {
        BiosBlockIoDev->Bios.ErrorCode = Regs.H.AH;
        return EFI_DEVICE_ERROR;
      }
    }
  }

  return EFI_SUCCESS;
}
//
//
// These functions need to double buffer all data under 1MB!
//
//

/**
  Read BufferSize bytes from Lba into Buffer.

  @param  This       Indicates a pointer to the calling context.
  @param  MediaId    Id of the media, changes every time the media is replaced.
  @param  Lba        The starting Logical Block Address to read from
  @param  BufferSize Size of Buffer, must be a multiple of device block size.
  @param  Buffer     A pointer to the destination buffer for the data. The caller is
                     responsible for either having implicit or explicit ownership of the buffer.

  @retval EFI_SUCCESS           The data was read correctly from the device.
  @retval EFI_DEVICE_ERROR      The device reported an error while performing the read.
  @retval EFI_NO_MEDIA          There is no media in the device.
  @retval EFI_MEDIA_CHANGED     The MediaId does not matched the current device.
  @retval EFI_BAD_BUFFER_SIZE   The Buffer was not a multiple of the block size of the device.
  @retval EFI_INVALID_PARAMETER The read request contains LBAs that are not valid, 
                                or the buffer is not on proper alignment.

**/
EFI_STATUS
EFIAPI
Edd11BiosReadBlocks (
  IN  EFI_BLOCK_IO_PROTOCOL *This,
  IN  UINT32                MediaId,
  IN  EFI_LBA               Lba,
  IN  UINTN                 BufferSize,
  OUT VOID                  *Buffer
  )
{
  EFI_BLOCK_IO_MEDIA        *Media;
  BIOS_BLOCK_IO_DEV         *BiosBlockIoDev;
  EDD_DEVICE_ADDRESS_PACKET *AddressPacket;
  //
  // I exist only for readability
  //
  EFI_IA32_REGISTER_SET     Regs;
  UINT64                    TransferBuffer;
  UINTN                     NumberOfBlocks;
  UINTN                     TransferByteSize;
  UINTN                     BlockSize;
  BIOS_LEGACY_DRIVE         *Bios;
  UINTN                     CarryFlag;
  UINTN                     MaxTransferBlocks;
  EFI_BLOCK_IO_PROTOCOL     *BlockIo;

  Media     = This->Media;
  BlockSize = Media->BlockSize;

  ZeroMem (&Regs, sizeof (EFI_IA32_REGISTER_SET));

  if (MediaId != Media->MediaId) {
    return EFI_MEDIA_CHANGED;
  }

  if (Lba > Media->LastBlock) {
    return EFI_INVALID_PARAMETER;
  }

  if ((Lba + (BufferSize / BlockSize) - 1) > Media->LastBlock) {
    return EFI_INVALID_PARAMETER;
  }

  if (BufferSize % BlockSize != 0) {
    return EFI_BAD_BUFFER_SIZE;
  }

  if (Buffer == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  if (BufferSize == 0) {
    return EFI_SUCCESS;
  }

  BiosBlockIoDev    = BIOS_BLOCK_IO_FROM_THIS (This);
  AddressPacket     = mEddBufferUnder1Mb;

  MaxTransferBlocks = MAX_EDD11_XFER / BlockSize;

  TransferBuffer    = (UINT64)(UINTN) mEdd11Buffer;
  for (; BufferSize > 0;) {
    NumberOfBlocks  = BufferSize / BlockSize;
    NumberOfBlocks  = NumberOfBlocks > MaxTransferBlocks ? MaxTransferBlocks : NumberOfBlocks;
    //
    // Max transfer MaxTransferBlocks
    //
    AddressPacket->PacketSizeInBytes  = (UINT8) sizeof (EDD_DEVICE_ADDRESS_PACKET);
    AddressPacket->Zero               = 0;
    AddressPacket->NumberOfBlocks     = (UINT8) NumberOfBlocks;
    AddressPacket->Zero2              = 0;
    //
    // TransferBuffer has been 4KB alignment. Normalize TransferBuffer to make offset as 0 in seg:offset
    // format to transfer maximum 127 blocks of data.
    // Otherwise when offset adding data size exceeds 0xFFFF, if OpROM does not normalize TransferBuffer,
    // INT13 function 42H will return data boundary error 09H.
    //
    AddressPacket->SegOffset = (UINT32) LShiftU64 (RShiftU64(TransferBuffer, 4), 16);
    AddressPacket->Lba  = (UINT64) Lba;

    Regs.H.AH           = 0x42;
    Regs.H.DL           = BiosBlockIoDev->Bios.Number;
    Regs.X.SI           = EFI_OFFSET (AddressPacket);
    Regs.X.DS           = EFI_SEGMENT (AddressPacket);

    CarryFlag           = BiosBlockIoDev->LegacyBios->Int86 (BiosBlockIoDev->LegacyBios, 0x13, &Regs);
    DEBUG (
      (
      DEBUG_BLKIO, "Edd11BiosReadBlocks: INT 13 42 DL=%02x : CF=%d AH=%02x : LBA 0x%lx  Block(s) %0d \n",
      BiosBlockIoDev->Bios.Number, CarryFlag, Regs.H.AH, Lba, NumberOfBlocks
      )
      );
    Media->MediaPresent = TRUE;
    if (CarryFlag != 0) {
      //
      // Return Error Status
      //
      BiosBlockIoDev->Bios.ErrorCode = Regs.H.AH;
      if (BiosBlockIoDev->Bios.ErrorCode == BIOS_DISK_CHANGED) {
        Media->MediaId++;
        Bios = &BiosBlockIoDev->Bios;
        if (Int13GetDeviceParameters (BiosBlockIoDev, Bios) != 0) {
          if (Int13Extensions (BiosBlockIoDev, Bios) != 0) {
            Media->LastBlock  = (EFI_LBA) Bios->Parameters.PhysicalSectors - 1;
            Media->BlockSize  = (UINT32) Bios->Parameters.BytesPerSector;
          } else {
            ASSERT (FALSE);
          }

          Media->ReadOnly = FALSE;
          gBS->HandleProtocol (BiosBlockIoDev->Handle, &gEfiBlockIoProtocolGuid, (VOID **) &BlockIo);
          gBS->ReinstallProtocolInterface (BiosBlockIoDev->Handle, &gEfiBlockIoProtocolGuid, BlockIo, BlockIo);
          return EFI_MEDIA_CHANGED;
        }
      }

      if (Media->RemovableMedia) {
        Media->MediaPresent = FALSE;
      }

      return EFI_DEVICE_ERROR;
    }

    TransferByteSize = NumberOfBlocks * BlockSize;
    CopyMem (Buffer, (VOID *) (UINTN) TransferBuffer, TransferByteSize);
    BufferSize  = BufferSize - TransferByteSize;
    Buffer      = (VOID *) ((UINT8 *) Buffer + TransferByteSize);
    Lba += NumberOfBlocks;
  }

  return EFI_SUCCESS;
}

/**
  Write BufferSize bytes from Lba into Buffer.

  @param  This       Indicates a pointer to the calling context.
  @param  MediaId    The media ID that the write request is for.
  @param  Lba        The starting logical block address to be written. The caller is
                     responsible for writing to only legitimate locations.
  @param  BufferSize Size of Buffer, must be a multiple of device block size.
  @param  Buffer     A pointer to the source buffer for the data.

  @retval EFI_SUCCESS           The data was written correctly to the device.
  @retval EFI_WRITE_PROTECTED   The device can not be written to.
  @retval EFI_DEVICE_ERROR      The device reported an error while performing the write.
  @retval EFI_NO_MEDIA          There is no media in the device.
  @retval EFI_MEDIA_CHNAGED     The MediaId does not matched the current device.
  @retval EFI_BAD_BUFFER_SIZE   The Buffer was not a multiple of the block size of the device.
  @retval EFI_INVALID_PARAMETER The write request contains LBAs that are not valid, 
                                or the buffer is not on proper alignment.

**/
EFI_STATUS
EFIAPI
Edd11BiosWriteBlocks (
  IN  EFI_BLOCK_IO_PROTOCOL *This,
  IN  UINT32                MediaId,
  IN  EFI_LBA               Lba,
  IN  UINTN                 BufferSize,
  OUT VOID                  *Buffer
  )
{
  EFI_BLOCK_IO_MEDIA        *Media;
  BIOS_BLOCK_IO_DEV         *BiosBlockIoDev;
  EDD_DEVICE_ADDRESS_PACKET *AddressPacket;
  //
  // I exist only for readability
  //
  EFI_IA32_REGISTER_SET     Regs;
  UINT64                    TransferBuffer;
  UINTN                     NumberOfBlocks;
  UINTN                     TransferByteSize;
  UINTN                     BlockSize;
  BIOS_LEGACY_DRIVE         *Bios;
  UINTN                     CarryFlag;
  UINTN                     MaxTransferBlocks;
  EFI_BLOCK_IO_PROTOCOL     *BlockIo;

  Media     = This->Media;
  BlockSize = Media->BlockSize;

  ZeroMem (&Regs, sizeof (EFI_IA32_REGISTER_SET));

  if (MediaId != Media->MediaId) {
    return EFI_MEDIA_CHANGED;
  }

  if (Lba > Media->LastBlock) {
    return EFI_INVALID_PARAMETER;
  }

  if ((Lba + (BufferSize / BlockSize) - 1) > Media->LastBlock) {
    return EFI_INVALID_PARAMETER;
  }

  if (BufferSize % BlockSize != 0) {
    return EFI_BAD_BUFFER_SIZE;
  }

  if (Buffer == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  if (BufferSize == 0) {
    return EFI_SUCCESS;
  }

  BiosBlockIoDev    = BIOS_BLOCK_IO_FROM_THIS (This);
  AddressPacket     = mEddBufferUnder1Mb;

  MaxTransferBlocks = MAX_EDD11_XFER / BlockSize;

  TransferBuffer    = (UINT64)(UINTN) mEdd11Buffer;
  for (; BufferSize > 0;) {
    NumberOfBlocks  = BufferSize / BlockSize;
    NumberOfBlocks  = NumberOfBlocks > MaxTransferBlocks ? MaxTransferBlocks : NumberOfBlocks;
    //
    // Max transfer MaxTransferBlocks
    //
    AddressPacket->PacketSizeInBytes  = (UINT8) sizeof (EDD_DEVICE_ADDRESS_PACKET);
    AddressPacket->Zero               = 0;
    AddressPacket->NumberOfBlocks     = (UINT8) NumberOfBlocks;
    AddressPacket->Zero2              = 0;
    //
    // TransferBuffer has been 4KB alignment. Normalize TransferBuffer to make offset as 0 in seg:offset
    // format to transfer maximum 127 blocks of data.
    // Otherwise when offset adding data size exceeds 0xFFFF, if OpROM does not normalize TransferBuffer,
    // INT13 function 42H will return data boundary error 09H.
    //
    AddressPacket->SegOffset = (UINT32) LShiftU64 (RShiftU64(TransferBuffer, 4), 16);
    AddressPacket->Lba  = (UINT64) Lba;

    Regs.H.AH           = 0x43;
    Regs.H.AL           = 0x00;
    //
    // Write Verify disable
    //
    Regs.H.DL         = BiosBlockIoDev->Bios.Number;
    Regs.X.SI         = EFI_OFFSET (AddressPacket);
    Regs.X.DS         = EFI_SEGMENT (AddressPacket);

    TransferByteSize  = NumberOfBlocks * BlockSize;
    CopyMem ((VOID *) (UINTN) TransferBuffer, Buffer, TransferByteSize);

    CarryFlag = BiosBlockIoDev->LegacyBios->Int86 (BiosBlockIoDev->LegacyBios, 0x13, &Regs);
    DEBUG (
      (
      DEBUG_BLKIO, "Edd11BiosWriteBlocks: INT 13 43 DL=%02x : CF=%d AH=%02x\n: LBA 0x%lx  Block(s) %0d \n",
      BiosBlockIoDev->Bios.Number, CarryFlag, Regs.H.AH, Lba, NumberOfBlocks
      )
      );
    Media->MediaPresent = TRUE;
    if (CarryFlag != 0) {
      //
      // Return Error Status
      //
      BiosBlockIoDev->Bios.ErrorCode = Regs.H.AH;
      if (BiosBlockIoDev->Bios.ErrorCode == BIOS_DISK_CHANGED) {
        Media->MediaId++;
        Bios = &BiosBlockIoDev->Bios;
        if (Int13GetDeviceParameters (BiosBlockIoDev, Bios) != 0) {
          if (Int13Extensions (BiosBlockIoDev, Bios) != 0) {
            Media->LastBlock  = (EFI_LBA) Bios->Parameters.PhysicalSectors - 1;
            Media->BlockSize  = (UINT32) Bios->Parameters.BytesPerSector;
          } else {
            ASSERT (FALSE);
          }

          Media->ReadOnly = FALSE;
          gBS->HandleProtocol (BiosBlockIoDev->Handle, &gEfiBlockIoProtocolGuid, (VOID **) &BlockIo);
          gBS->ReinstallProtocolInterface (BiosBlockIoDev->Handle, &gEfiBlockIoProtocolGuid, BlockIo, BlockIo);
          return EFI_MEDIA_CHANGED;
        }
      } else if (BiosBlockIoDev->Bios.ErrorCode == BIOS_WRITE_PROTECTED) {
        Media->ReadOnly = TRUE;
        return EFI_WRITE_PROTECTED;
      }

      if (Media->RemovableMedia) {
        Media->MediaPresent = FALSE;
      }

      return EFI_DEVICE_ERROR;
    }

    Media->ReadOnly = FALSE;
    BufferSize      = BufferSize - TransferByteSize;
    Buffer          = (VOID *) ((UINT8 *) Buffer + TransferByteSize);
    Lba += NumberOfBlocks;
  }

  return EFI_SUCCESS;
}

/**
  Read BufferSize bytes from Lba into Buffer.

  @param  This       Indicates a pointer to the calling context.
  @param  MediaId    Id of the media, changes every time the media is replaced.
  @param  Lba        The starting Logical Block Address to read from
  @param  BufferSize Size of Buffer, must be a multiple of device block size.
  @param  Buffer     A pointer to the destination buffer for the data. The caller is
                     responsible for either having implicit or explicit ownership of the buffer.

  @retval EFI_SUCCESS           The data was read correctly from the device.
  @retval EFI_DEVICE_ERROR      The device reported an error while performing the read.
  @retval EFI_NO_MEDIA          There is no media in the device.
  @retval EFI_MEDIA_CHANGED     The MediaId does not matched the current device.
  @retval EFI_BAD_BUFFER_SIZE   The Buffer was not a multiple of the block size of the device.
  @retval EFI_INVALID_PARAMETER The read request contains LBAs that are not valid, 
                                or the buffer is not on proper alignment.

**/
EFI_STATUS
EFIAPI
BiosReadLegacyDrive (
  IN  EFI_BLOCK_IO_PROTOCOL *This,
  IN  UINT32                MediaId,
  IN  EFI_LBA               Lba,
  IN  UINTN                 BufferSize,
  OUT VOID                  *Buffer
  )
{
  EFI_BLOCK_IO_MEDIA    *Media;
  BIOS_BLOCK_IO_DEV     *BiosBlockIoDev;
  EFI_IA32_REGISTER_SET Regs;
  UINTN                 UpperCylinder;
  UINTN                 Temp;
  UINTN                 Cylinder;
  UINTN                 Head;
  UINTN                 Sector;
  UINTN                 NumberOfBlocks;
  UINTN                 TransferByteSize;
  UINTN                 ShortLba;
  UINTN                 CheckLba;
  UINTN                 BlockSize;
  BIOS_LEGACY_DRIVE     *Bios;
  UINTN                 CarryFlag;
  UINTN                 Retry;
  EFI_BLOCK_IO_PROTOCOL *BlockIo;

  Media     = This->Media;
  BlockSize = Media->BlockSize;

  ZeroMem (&Regs, sizeof (EFI_IA32_REGISTER_SET));

  if (MediaId != Media->MediaId) {
    return EFI_MEDIA_CHANGED;
  }

  if (Lba > Media->LastBlock) {
    return EFI_INVALID_PARAMETER;
  }

  if ((Lba + (BufferSize / BlockSize) - 1) > Media->LastBlock) {
    return EFI_INVALID_PARAMETER;
  }

  if (BufferSize % BlockSize != 0) {
    return EFI_BAD_BUFFER_SIZE;
  }

  if (Buffer == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  if (BufferSize == 0) {
    return EFI_SUCCESS;
  }

  BiosBlockIoDev  = BIOS_BLOCK_IO_FROM_THIS (This);
  ShortLba        = (UINTN) Lba;

  while (BufferSize != 0) {
    //
    // Compute I/O location in Sector, Head, Cylinder format
    //
    Sector    = (ShortLba % BiosBlockIoDev->Bios.MaxSector) + 1;
    Temp      = ShortLba / BiosBlockIoDev->Bios.MaxSector;
    Head      = Temp % (BiosBlockIoDev->Bios.MaxHead + 1);
    Cylinder  = Temp / (BiosBlockIoDev->Bios.MaxHead + 1);

    //
    // Limit transfer to this Head & Cylinder
    //
    NumberOfBlocks  = BufferSize / BlockSize;
    Temp            = BiosBlockIoDev->Bios.MaxSector - Sector + 1;
    NumberOfBlocks  = NumberOfBlocks > Temp ? Temp : NumberOfBlocks;

    Retry           = 3;
    do {
      //
      // Perform the IO
      //
      Regs.H.AH     = 2;
      Regs.H.AL     = (UINT8) NumberOfBlocks;
      Regs.H.DL     = BiosBlockIoDev->Bios.Number;

      UpperCylinder = (Cylinder & 0x0f00) >> 2;

      CheckLba      = Cylinder * (BiosBlockIoDev->Bios.MaxHead + 1) + Head;
      CheckLba      = CheckLba * BiosBlockIoDev->Bios.MaxSector + Sector - 1;

      DEBUG (
        (DEBUG_BLKIO,
        "RLD: LBA %x (%x), Sector %x (%x), Head %x (%x), Cyl %x, UCyl %x\n",
        ShortLba,
        CheckLba,
        Sector,
        BiosBlockIoDev->Bios.MaxSector,
        Head,
        BiosBlockIoDev->Bios.MaxHead,
        Cylinder,
        UpperCylinder)
        );
      ASSERT (CheckLba == ShortLba);

      Regs.H.CL = (UINT8) ((Sector & 0x3f) + (UpperCylinder & 0xff));
      Regs.H.DH = (UINT8) (Head & 0x3f);
      Regs.H.CH = (UINT8) (Cylinder & 0xff);

      Regs.X.BX = EFI_OFFSET (mEdd11Buffer);
      Regs.X.ES = EFI_SEGMENT (mEdd11Buffer);

      DEBUG (
        (DEBUG_BLKIO,
        "INT 13h: AX:(02%02x) DX:(%02x%02x) CX:(%02x%02x) BX:(%04x) ES:(%04x)\n",
        Regs.H.AL,
        (UINT8) (Head & 0x3f),
        Regs.H.DL,
        (UINT8) (Cylinder & 0xff),
        (UINT8) ((Sector & 0x3f) + (UpperCylinder & 0xff)),
        EFI_OFFSET (mEdd11Buffer),
        EFI_SEGMENT (mEdd11Buffer))
        );

      CarryFlag = BiosBlockIoDev->LegacyBios->Int86 (BiosBlockIoDev->LegacyBios, 0x13, &Regs);
      DEBUG (
        (
        DEBUG_BLKIO, "BiosReadLegacyDrive: INT 13 02 DL=%02x : CF=%d AH=%02x\n", BiosBlockIoDev->Bios.Number,
        CarryFlag, Regs.H.AH
        )
        );
      Retry--;
    } while (CarryFlag != 0 && Retry != 0 && Regs.H.AH != BIOS_DISK_CHANGED);

    Media->MediaPresent = TRUE;
    if (CarryFlag != 0) {
      //
      // Return Error Status
      //
      BiosBlockIoDev->Bios.ErrorCode = Regs.H.AH;
      if (BiosBlockIoDev->Bios.ErrorCode == BIOS_DISK_CHANGED) {
        Media->MediaId++;
        Bios = &BiosBlockIoDev->Bios;
        if (Int13GetDeviceParameters (BiosBlockIoDev, Bios) != 0) {
          //
          // If the size of the media changed we need to reset the disk geometry
          //
          if (Int13Extensions (BiosBlockIoDev, Bios) != 0) {
            Media->LastBlock  = (EFI_LBA) Bios->Parameters.PhysicalSectors - 1;
            Media->BlockSize  = (UINT32) Bios->Parameters.BytesPerSector;
          } else {
            //
            // Legacy Interfaces
            //
            Media->LastBlock  = (Bios->MaxHead + 1) * Bios->MaxSector * (Bios->MaxCylinder + 1) - 1;
            Media->BlockSize  = 512;
          }

          Media->ReadOnly = FALSE;
          gBS->HandleProtocol (BiosBlockIoDev->Handle, &gEfiBlockIoProtocolGuid, (VOID **) &BlockIo);
          gBS->ReinstallProtocolInterface (BiosBlockIoDev->Handle, &gEfiBlockIoProtocolGuid, BlockIo, BlockIo);
          return EFI_MEDIA_CHANGED;
        }
      }

      if (Media->RemovableMedia) {
        Media->MediaPresent = FALSE;
      }

      return EFI_DEVICE_ERROR;
    }

    TransferByteSize = NumberOfBlocks * BlockSize;
    CopyMem (Buffer, mEdd11Buffer, TransferByteSize);

    ShortLba    = ShortLba + NumberOfBlocks;
    BufferSize  = BufferSize - TransferByteSize;
    Buffer      = (VOID *) ((UINT8 *) Buffer + TransferByteSize);
  }

  return EFI_SUCCESS;
}

/**
  Write BufferSize bytes from Lba into Buffer.

  @param  This       Indicates a pointer to the calling context.
  @param  MediaId    The media ID that the write request is for.
  @param  Lba        The starting logical block address to be written. The caller is
                     responsible for writing to only legitimate locations.
  @param  BufferSize Size of Buffer, must be a multiple of device block size.
  @param  Buffer     A pointer to the source buffer for the data.

  @retval EFI_SUCCESS           The data was written correctly to the device.
  @retval EFI_WRITE_PROTECTED   The device can not be written to.
  @retval EFI_DEVICE_ERROR      The device reported an error while performing the write.
  @retval EFI_NO_MEDIA          There is no media in the device.
  @retval EFI_MEDIA_CHNAGED     The MediaId does not matched the current device.
  @retval EFI_BAD_BUFFER_SIZE   The Buffer was not a multiple of the block size of the device.
  @retval EFI_INVALID_PARAMETER The write request contains LBAs that are not valid, 
                                or the buffer is not on proper alignment.

**/
EFI_STATUS
EFIAPI
BiosWriteLegacyDrive (
  IN  EFI_BLOCK_IO_PROTOCOL *This,
  IN  UINT32                MediaId,
  IN  EFI_LBA               Lba,
  IN  UINTN                 BufferSize,
  OUT VOID                  *Buffer
  )
{
  EFI_BLOCK_IO_MEDIA    *Media;
  BIOS_BLOCK_IO_DEV     *BiosBlockIoDev;
  EFI_IA32_REGISTER_SET Regs;
  UINTN                 UpperCylinder;
  UINTN                 Temp;
  UINTN                 Cylinder;
  UINTN                 Head;
  UINTN                 Sector;
  UINTN                 NumberOfBlocks;
  UINTN                 TransferByteSize;
  UINTN                 ShortLba;
  UINTN                 CheckLba;
  UINTN                 BlockSize;
  BIOS_LEGACY_DRIVE     *Bios;
  UINTN                 CarryFlag;
  UINTN                 Retry;
  EFI_BLOCK_IO_PROTOCOL *BlockIo;

  Media     = This->Media;
  BlockSize = Media->BlockSize;

  ZeroMem (&Regs, sizeof (EFI_IA32_REGISTER_SET));

  if (MediaId != Media->MediaId) {
    return EFI_MEDIA_CHANGED;
  }

  if (Lba > Media->LastBlock) {
    return EFI_INVALID_PARAMETER;
  }

  if ((Lba + (BufferSize / BlockSize) - 1) > Media->LastBlock) {
    return EFI_INVALID_PARAMETER;
  }

  if (BufferSize % BlockSize != 0) {
    return EFI_BAD_BUFFER_SIZE;
  }

  if (Buffer == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  if (BufferSize == 0) {
    return EFI_SUCCESS;
  }

  BiosBlockIoDev  = BIOS_BLOCK_IO_FROM_THIS (This);
  ShortLba        = (UINTN) Lba;

  while (BufferSize != 0) {
    //
    // Compute I/O location in Sector, Head, Cylinder format
    //
    Sector    = (ShortLba % BiosBlockIoDev->Bios.MaxSector) + 1;
    Temp      = ShortLba / BiosBlockIoDev->Bios.MaxSector;
    Head      = Temp % (BiosBlockIoDev->Bios.MaxHead + 1);
    Cylinder  = Temp / (BiosBlockIoDev->Bios.MaxHead + 1);

    //
    // Limit transfer to this Head & Cylinder
    //
    NumberOfBlocks  = BufferSize / BlockSize;
    Temp            = BiosBlockIoDev->Bios.MaxSector - Sector + 1;
    NumberOfBlocks  = NumberOfBlocks > Temp ? Temp : NumberOfBlocks;

    Retry           = 3;
    do {
      //
      // Perform the IO
      //
      Regs.H.AH     = 3;
      Regs.H.AL     = (UINT8) NumberOfBlocks;
      Regs.H.DL     = BiosBlockIoDev->Bios.Number;

      UpperCylinder = (Cylinder & 0x0f00) >> 2;

      CheckLba      = Cylinder * (BiosBlockIoDev->Bios.MaxHead + 1) + Head;
      CheckLba      = CheckLba * BiosBlockIoDev->Bios.MaxSector + Sector - 1;

      DEBUG (
        (DEBUG_BLKIO,
        "RLD: LBA %x (%x), Sector %x (%x), Head %x (%x), Cyl %x, UCyl %x\n",
        ShortLba,
        CheckLba,
        Sector,
        BiosBlockIoDev->Bios.MaxSector,
        Head,
        BiosBlockIoDev->Bios.MaxHead,
        Cylinder,
        UpperCylinder)
        );
      ASSERT (CheckLba == ShortLba);

      Regs.H.CL         = (UINT8) ((Sector & 0x3f) + (UpperCylinder & 0xff));
      Regs.H.DH         = (UINT8) (Head & 0x3f);
      Regs.H.CH         = (UINT8) (Cylinder & 0xff);

      Regs.X.BX         = EFI_OFFSET (mEdd11Buffer);
      Regs.X.ES         = EFI_SEGMENT (mEdd11Buffer);

      TransferByteSize  = NumberOfBlocks * BlockSize;
      CopyMem (mEdd11Buffer, Buffer, TransferByteSize);

      DEBUG (
        (DEBUG_BLKIO,
        "INT 13h: AX:(03%02x) DX:(%02x%02x) CX:(%02x%02x) BX:(%04x) ES:(%04x)\n",
        Regs.H.AL,
        (UINT8) (Head & 0x3f),
        Regs.H.DL,
        (UINT8) (Cylinder & 0xff),
        (UINT8) ((Sector & 0x3f) + (UpperCylinder & 0xff)),
        EFI_OFFSET (mEdd11Buffer),
        EFI_SEGMENT (mEdd11Buffer))
        );

      CarryFlag = BiosBlockIoDev->LegacyBios->Int86 (BiosBlockIoDev->LegacyBios, 0x13, &Regs);
      DEBUG (
        (
        DEBUG_BLKIO, "BiosWriteLegacyDrive: INT 13 03 DL=%02x : CF=%d AH=%02x\n", BiosBlockIoDev->Bios.Number,
        CarryFlag, Regs.H.AH
        )
        );
      Retry--;
    } while (CarryFlag != 0 && Retry != 0 && Regs.H.AH != BIOS_DISK_CHANGED);

    Media->MediaPresent = TRUE;
    if (CarryFlag != 0) {
      //
      // Return Error Status
      //
      BiosBlockIoDev->Bios.ErrorCode = Regs.H.AH;
      if (BiosBlockIoDev->Bios.ErrorCode == BIOS_DISK_CHANGED) {
        Media->MediaId++;
        Bios = &BiosBlockIoDev->Bios;
        if (Int13GetDeviceParameters (BiosBlockIoDev, Bios) != 0) {
          if (Int13Extensions (BiosBlockIoDev, Bios) != 0) {
            Media->LastBlock  = (EFI_LBA) Bios->Parameters.PhysicalSectors - 1;
            Media->BlockSize  = (UINT32) Bios->Parameters.BytesPerSector;
          } else {
            //
            // Legacy Interfaces
            //
            Media->LastBlock  = (Bios->MaxHead + 1) * Bios->MaxSector * (Bios->MaxCylinder + 1) - 1;
            Media->BlockSize  = 512;
          }
          //
          // If the size of the media changed we need to reset the disk geometry
          //
          Media->ReadOnly = FALSE;
          gBS->HandleProtocol (BiosBlockIoDev->Handle, &gEfiBlockIoProtocolGuid, (VOID **) &BlockIo);
          gBS->ReinstallProtocolInterface (BiosBlockIoDev->Handle, &gEfiBlockIoProtocolGuid, BlockIo, BlockIo);
          return EFI_MEDIA_CHANGED;
        }
      } else if (BiosBlockIoDev->Bios.ErrorCode == BIOS_WRITE_PROTECTED) {
        Media->ReadOnly = TRUE;
        return EFI_WRITE_PROTECTED;
      }

      if (Media->RemovableMedia) {
        Media->MediaPresent = FALSE;
      }

      return EFI_DEVICE_ERROR;
    }

    Media->ReadOnly = FALSE;
    ShortLba        = ShortLba + NumberOfBlocks;
    BufferSize      = BufferSize - TransferByteSize;
    Buffer          = (VOID *) ((UINT8 *) Buffer + TransferByteSize);
  }

  return EFI_SUCCESS;
}
