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