]> git.proxmox.com Git - mirror_edk2.git/blobdiff - IntelFrameworkModulePkg/Bus/Pci/IdeBusDxe/Atapi.c
IntelFrameworkModulePkg/IdeBusDxe: Fix undefined behavior in signed left shift
[mirror_edk2.git] / IntelFrameworkModulePkg / Bus / Pci / IdeBusDxe / Atapi.c
index 1f989e72f67dd239865f88942ff3a911fe8ed662..c641dc5714bcc5d678aa0d4ed9bb4e9fdfd39988 100644 (file)
@@ -1,6 +1,8 @@
 /** @file\r
-  Copyright (c) 2006 - 2008, Intel Corporation                                                        \r
-  All rights reserved. This program and the accompanying materials                          \r
+   This file contains all helper functions on the ATAPI command \r
+  \r
+  Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR>\r
+  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
   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
+  @param IdeDev   pointer pointing to IDE_BLK_IO_DEV data structure, used\r
+                  to record all the information of the IDE device.\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
+  @retval EFI_SUCCESS         The media status is achieved successfully and the media\r
+                              can be read/written.\r
+  @retval EFI_DEVICE_ERROR    Get Media Status Command is failed.\r
+  @retval EFI_NO_MEDIA        There is no media in the drive.\r
+  @retval EFI_WRITE_PROTECTED The media is writing protected.\r
 \r
+  @note  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
 EFI_STATUS\r
 LS120GetMediaStatus (\r
@@ -100,25 +92,17 @@ LS120GetMediaStatus (
     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
+  @param IdeDev pointer pointing to IDE_BLK_IO_DEV data structure, used\r
+                to record all the information of the IDE device.\r
 \r
+  @param Enable a flag that indicates whether enable or disable media\r
+                status notification.\r
+  @retval EFI_SUCCESS      If command completes successfully.\r
+  @retval EFI_DEVICE_ERROR If command failed.\r
 **/\r
 EFI_STATUS\r
 LS120EnableMediaStatus (\r
@@ -179,301 +163,202 @@ LS120EnableMediaStatus (
 \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
+  This function reads the pending data in the device.\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
+  @param IdeDev   Indicates the calling context.\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
+  @retval EFI_SUCCESS   Successfully read.\r
+  @retval EFI_NOT_READY The BSY is set avoiding reading.\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
+EFI_STATUS\r
+AtapiReadPendingData (\r
+  IN IDE_BLK_IO_DEV     *IdeDev\r
+  )\r
+{\r
+  UINT8     AltRegister;\r
+  UINT16    TempWordBuffer;\r
 \r
-  @note\r
-  Parameter "IdeDev" will be updated in this function.\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
-  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
+  This function is called by either AtapiPacketCommandIn() or AtapiPacketCommandOut(). \r
+  It is used to transfer data between host and device. The data direction is specified\r
+  by the fourth parameter.\r
+\r
+  @param IdeDev     pointer pointing to IDE_BLK_IO_DEV data structure, used to record\r
+                    all the information of the IDE device.\r
+  @param Buffer     buffer contained data transferred between host and device.\r
+  @param ByteCount  data size in byte unit of the buffer.\r
+  @param Read       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
+  @param TimeOut    timeout value for wait DRQ ready before each data stream's transfer.\r
+\r
+  @retval EFI_SUCCESS      data is transferred successfully.\r
+  @retval EFI_DEVICE_ERROR the device failed to transfer data.\r
 **/\r
 EFI_STATUS\r
-ATAPIIdentify (\r
-  IN  IDE_BLK_IO_DEV  *IdeDev\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
-  EFI_IDENTIFY_DATA *AtapiIdentifyPointer;\r
-  UINT8             DeviceSelect;\r
-  EFI_STATUS        Status;\r
-\r
   //\r
-  // device select bit\r
+  // required transfer data in word unit.\r
   //\r
-  DeviceSelect          = (UINT8) ((IdeDev->Device) << 4);\r
+  UINT32      RequiredWordCount;\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
+  // actual transfer data in word unit.\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
+  UINT32      ActualWordCount;\r
+  UINT32      WordCount;\r
+  EFI_STATUS  Status;\r
+  UINT16      *PtrBuffer;\r
 \r
   //\r
-  // Send ATAPI Inquiry Packet Command to get INQUIRY data.\r
+  // No data transfer is premitted.\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
+  if (ByteCount == 0) {\r
+    return EFI_SUCCESS;\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
+  // 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
-  // Magnetic Disk\r
+  // ActuralWordCount means the word count of data really transferred.\r
   //\r
-  case 0x00:\r
+  ActualWordCount = 0;\r
 \r
+  while (ActualWordCount < RequiredWordCount) {\r
+    \r
     //\r
-    // device is LS120 or ZIP drive.\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
-    IdeDev->Type = IdeMagnetic;\r
-\r
-    IdeDev->BlkIo.Media->MediaId      = 0;\r
+    Status = DRQReady2 (IdeDev, TimeOut);\r
+    if (EFI_ERROR (Status)) {\r
+      return CheckErrorStatus (IdeDev);\r
+    }\r
+    \r
     //\r
-    // Give initial value\r
+    // read Status Register will clear interrupt\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
+    IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Status);\r
 \r
-    IdeDev->Type                      = IdeCdRom;\r
-    IdeDev->BlkIo.Media->MediaId      = 0;\r
     //\r
-    // Give initial value\r
+    // get current data transfer size from Cylinder Registers.\r
     //\r
-    IdeDev->BlkIo.Media->MediaPresent = FALSE;\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
-    IdeDev->BlkIo.Media->LastBlock  = 0;\r
-    IdeDev->BlkIo.Media->BlockSize  = 0x800;\r
-    IdeDev->BlkIo.Media->ReadOnly   = TRUE;\r
-    break;\r
+    WordCount = MIN (WordCount, (RequiredWordCount - ActualWordCount));\r
 \r
-  //\r
-  // Tape\r
-  //\r
-  case 0x01:\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
-  //\r
-  // WORM\r
-  //\r
-  case 0x04:\r
+    PtrBuffer += WordCount;\r
+    ActualWordCount += WordCount;\r
+  }\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
+  if (Read) {\r
     //\r
-    // Make sure the pIdData and pInquiryData will not be freed again.\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
-    IdeDev->pIdData       = NULL;\r
-    IdeDev->pInquiryData  = NULL;\r
-    return EFI_DEVICE_ERROR;\r
+    AtapiReadPendingData (IdeDev);\r
   }\r
 \r
   //\r
-  // original sense data numbers\r
+  // After data transfer is completed, normally, DRQ bit should clear.\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
+  Status = DRQClear2 (IdeDev, ATAPITIMEOUT);\r
+  if (EFI_ERROR (Status)) {\r
+    return EFI_DEVICE_ERROR;\r
   }\r
 \r
-  return EFI_SUCCESS;\r
+  //\r
+  // read status register to check whether error happens.\r
+  //\r
+  return CheckErrorStatus (IdeDev);\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
+  This function is used to send out ATAPI commands conforms to the Packet Command \r
+  with PIO Data In Protocol.\r
+\r
+  @param IdeDev    pointer pointing to IDE_BLK_IO_DEV data structure, used\r
+                   to record all the information of the IDE device.\r
+  @param Packet    pointer pointing to ATAPI_PACKET_COMMAND data structure\r
+                   which contains the contents of the command.     \r
+  @param Buffer    buffer contained data transferred from device to host.\r
+  @param ByteCount data size in byte unit of the buffer.\r
+  @param TimeOut   this parameter is used to specify the timeout value for the \r
+                   PioReadWriteData() function. \r
+\r
+  @retval EFI_SUCCESS       send out the ATAPI packet command successfully\r
+                            and device sends data successfully.\r
+  @retval EFI_DEVICE_ERROR  the device failed to send data.\r
 \r
 **/\r
 EFI_STATUS\r
-AtapiInquiry (\r
-  IN  IDE_BLK_IO_DEV  *IdeDev\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
-  ATAPI_PACKET_COMMAND  Packet;\r
-  EFI_STATUS            Status;\r
-  ATAPI_INQUIRY_DATA          *InquiryData;\r
+  UINT16      *CommandIndex;\r
+  EFI_STATUS  Status;\r
+  UINT32      Count;\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
+  // 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
@@ -542,35 +427,21 @@ AtapiPacketCommandIn (
   //\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
+  This function is used to send out ATAPI commands conforms to the Packet Command\r
+  with PIO Data Out Protocol.\r
+\r
+  @param IdeDev      pointer pointing to IDE_BLK_IO_DEV data structure, used\r
+                     to record all the information of the IDE device.\r
+  @param Packet      pointer pointing to ATAPI_PACKET_COMMAND data structure\r
+                     which contains the contents of the command.\r
+  @param Buffer      buffer contained data transferred from host to device.\r
+  @param ByteCount   data size in byte unit of the buffer.\r
+  @param TimeOut     this parameter is used to specify the timeout value \r
+                     for the PioReadWriteData() function. \r
+  @retval EFI_SUCCESS      send out the ATAPI packet command successfully\r
+                           and device received data successfully.  \r
+  @retval EFI_DEVICE_ERROR the device failed to send data.\r
 \r
 **/\r
 EFI_STATUS\r
@@ -655,213 +526,249 @@ AtapiPacketCommandOut (
   //\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
+  Sends out ATAPI Inquiry Packet Command to the specified device. This command will\r
+  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
+  @param IdeDev 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
+  @retval EFI_SUCCESS       Inquiry command completes successfully.\r
+  @retval EFI_DEVICE_ERROR  Inquiry command failed.\r
 \r
-  @param[in] ByteCount\r
-  data size in byte unit of the buffer.\r
+  @note  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
-  @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
+  // 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  = (UINT8) sizeof (ATAPI_INQUIRY_DATA);\r
 \r
-  @param[in] TimeOut\r
-  timeout value for wait DRQ ready before each data \r
-  stream's transfer.\r
+  InquiryData                       = AllocatePool (sizeof (ATAPI_INQUIRY_DATA));\r
+  if (InquiryData == NULL) {\r
+    return EFI_DEVICE_ERROR;\r
+  }\r
 \r
-  @retval EFI_SUCCESS\r
-  data is transferred successfully.\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->InquiryData = InquiryData;\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+/**\r
+  This function is called by DiscoverIdeDevice() during its device\r
+  identification.\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
+  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
+  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
+  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
-  @retval EFI_DEVICE_ERROR\r
-  the device failed to transfer data.\r
+  @param IdeDev 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       Identify ATAPI device successfully.\r
+  @retval EFI_DEVICE_ERROR  ATAPI Identify Device Command failed or device type\r
+                            is not supported by this IDE driver.\r
+  @retval EFI_OUT_OF_RESOURCES Allocate memory for sense data failed \r
+\r
+  @note   Parameter "IdeDev" will be updated in this function.\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
+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
-  // required transfer data in word unit.\r
+  // device select bit\r
   //\r
-  UINT32      RequiredWordCount;\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
-  // actual transfer data in word unit.\r
+  // Send ATAPI Identify Command to get IDENTIFY data.\r
   //\r
-  UINT32      ActualWordCount;\r
-  UINT32      WordCount;\r
-  EFI_STATUS  Status;\r
-  UINT16      *PtrBuffer;\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->IdData = AtapiIdentifyPointer;\r
+  PrintAtaModuleName (IdeDev);\r
 \r
   //\r
-  // No data transfer is premitted.\r
+  // Send ATAPI Inquiry Packet Command to get INQUIRY data.\r
   //\r
-  if (ByteCount == 0) {\r
-    return EFI_SUCCESS;\r
+  Status = AtapiInquiry (IdeDev);\r
+  if (EFI_ERROR (Status)) {\r
+    gBS->FreePool (IdeDev->IdData);\r
+    //\r
+    // Make sure the pIdData will not be freed again.\r
+    //\r
+    IdeDev->IdData = NULL;\r
+    return EFI_DEVICE_ERROR;\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
+  // Get media removable info from INQUIRY data.\r
   //\r
-  // ActuralWordCount means the word count of data really transferred.\r
+  IdeDev->BlkIo.Media->RemovableMedia = (UINT8) ((IdeDev->InquiryData->RMB & 0x80) == 0x80);\r
+\r
   //\r
-  ActualWordCount = 0;\r
+  // Identify device type via INQUIRY data.\r
+  //\r
+  switch (IdeDev->InquiryData->peripheral_type & 0x1f) {\r
+\r
+  //\r
+  // Magnetic Disk\r
+  //\r
+  case 0x00:\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
+    // device is LS120 or ZIP drive.\r
     //\r
-    IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Status);\r
+    IdeDev->Type = IdeMagnetic;\r
 \r
+    IdeDev->BlkIo.Media->MediaId      = 0;\r
     //\r
-    // get current data transfer size from Cylinder Registers.\r
+    // Give initial value\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
+    IdeDev->BlkIo.Media->MediaPresent = FALSE;\r
 \r
-    WordCount = MIN (WordCount, (RequiredWordCount - ActualWordCount));\r
+    IdeDev->BlkIo.Media->LastBlock  = 0;\r
+    IdeDev->BlkIo.Media->BlockSize  = 0x200;\r
+    break;\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
+  // CD-ROM\r
+  //\r
+  case 0x05:\r
 \r
-    PtrBuffer += WordCount;\r
-    ActualWordCount += WordCount;\r
-  }\r
-  \r
-  if (Read) {\r
+    IdeDev->Type                      = IdeCdRom;\r
+    IdeDev->BlkIo.Media->MediaId      = 0;\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
+    // Give initial value\r
     //\r
-    AtapiReadPendingData (IdeDev);\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
-  // After data transfer is completed, normally, DRQ bit should clear.\r
+  // Tape\r
   //\r
-  Status = DRQClear2 (IdeDev, ATAPITIMEOUT);\r
-  if (EFI_ERROR (Status)) {\r
-    return EFI_DEVICE_ERROR;\r
-  }\r
+  case 0x01:\r
 \r
   //\r
-  // read status register to check whether error happens.\r
+  // WORM\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[out] *SResult   Sense result 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 SENSE_RESULT    *SResult  \r
-  )\r
-{\r
-  ATAPI_PACKET_COMMAND  Packet;\r
-  EFI_STATUS            Status;\r
-  UINTN                                SenseCount;\r
-\r
+  case 0x04:\r
+  \r
   //\r
-  // fill command packet\r
+  // Optical\r
   //\r
-  ZeroMem (&Packet, sizeof (ATAPI_PACKET_COMMAND));\r
-  Packet.TestUnitReady.opcode = ATA_CMD_TEST_UNIT_READY;\r
+  case 0x07:\r
+\r
+  default:\r
+    IdeDev->Type = IdeUnknown;\r
+    gBS->FreePool (IdeDev->IdData);\r
+    gBS->FreePool (IdeDev->InquiryData);\r
+    //\r
+    // Make sure the pIdData and pInquiryData will not be freed again.\r
+    //\r
+    IdeDev->IdData       = NULL;\r
+    IdeDev->InquiryData  = NULL;\r
+    return EFI_DEVICE_ERROR;\r
+  }\r
 \r
   //\r
-  // send command packet\r
+  // original sense data numbers\r
   //\r
-  Status = AtapiPacketCommandIn (IdeDev, &Packet, NULL, 0, ATAPITIMEOUT);\r
-  if (EFI_ERROR (Status)) {\r
-    return Status;\r
-  }\r
+  IdeDev->SenseDataNumber = 20;\r
 \r
-  Status = AtapiRequestSense (IdeDev, &SenseCount);\r
-  if (EFI_ERROR (Status)) {\r
-    return Status;\r
+  IdeDev->SenseData = AllocatePool (IdeDev->SenseDataNumber * sizeof (ATAPI_REQUEST_SENSE_DATA));\r
+  if (IdeDev->SenseData == NULL) {\r
+    gBS->FreePool (IdeDev->IdData);\r
+    gBS->FreePool (IdeDev->InquiryData);\r
+    //\r
+    // Make sure the pIdData and pInquiryData will not be freed again.\r
+    //\r
+    IdeDev->IdData       = NULL;\r
+    IdeDev->InquiryData  = NULL;\r
+    return EFI_OUT_OF_RESOURCES;\r
   }\r
 \r
-  ParseSenseData (IdeDev, SenseCount, SResult);\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] **SenseCounts\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
-  @retval EFI_SUCCESS\r
-  Request Sense command completes successfully.\r
-  \r
-  @retval EFI_DEVICE_ERROR\r
-  Request Sense command failed.\r
-\r
+  Sends out ATAPI Request Sense Packet Command to the specified device. This command\r
+  will return all the current Sense data in the device.  This function will pack \r
+  all the Sense data in one single buffer.\r
+\r
+  @param IdeDev       pointer pointing to IDE_BLK_IO_DEV data structure, used\r
+                      to record all the information of the IDE device.\r
+  @param SenseCounts  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
+  @retval EFI_SUCCESS      Request Sense command completes successfully.\r
+  @retval EFI_DEVICE_ERROR Request Sense command failed.\r
 **/\r
 EFI_STATUS\r
 AtapiRequestSense (\r
@@ -883,7 +790,7 @@ AtapiRequestSense (
   //\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
+  Packet.RequestSence.allocation_length = (UINT8) sizeof (ATAPI_REQUEST_SENSE_DATA);\r
 \r
   //\r
   // initialize pointer\r
@@ -918,30 +825,148 @@ AtapiRequestSense (
       }\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
+    (*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
+  This function is used to parse sense data. Only the first sense data is honoured\r
+  \r
+  @param IdeDev     Indicates the calling context.\r
+  @param SenseCount Count of sense data.\r
+  @param 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
+  Sends out ATAPI Test Unit Ready Packet Command to the specified device\r
+  to find out whether device is accessible.\r
+\r
+  @param IdeDev    Pointer pointing to IDE_BLK_IO_DEV data structure, used\r
+                   to record all the information of the IDE device.\r
+  @param SResult   Sense result 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 SENSE_RESULT    *SResult  \r
+  )\r
+{\r
+  ATAPI_PACKET_COMMAND  Packet;\r
+  EFI_STATUS            Status;\r
+  UINTN                                SenseCount;\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
-    } else {\r
-      //\r
-      // when no sense key, skip out the loop\r
-      //\r
-      FetchSenseData = FALSE;\r
-    }\r
+  Status = AtapiRequestSense (IdeDev, &SenseCount);\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
   }\r
 \r
+  ParseSenseData (IdeDev, SenseCount, SResult);\r
   return EFI_SUCCESS;\r
 }\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
@@ -953,16 +978,17 @@ AtapiRequestSense (
   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[out] SResult   Sense result for this packet command\r
+  @param IdeDev    Pointer pointing to IDE_BLK_IO_DEV data structure, used\r
+                   to record all the information of the IDE device.\r
+  @param SResult   Sense result 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
+  @retval EFI_NOT_READY    Operation succeeds but returned capacity is 0\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
 **/\r
 EFI_STATUS\r
 AtapiReadCapacity (\r
@@ -1027,12 +1053,12 @@ AtapiReadCapacity (
        if (!EFI_ERROR (Status) && *SResult == SenseNoSenseKey) {\r
       if (IdeDev->Type == IdeCdRom) {\r
 \r
-        IdeDev->BlkIo.Media->LastBlock = (Data.LastLba3 << 24) |\r
+        IdeDev->BlkIo.Media->LastBlock = ((UINT32) Data.LastLba3 << 24) |\r
           (Data.LastLba2 << 16) |\r
           (Data.LastLba1 << 8) |\r
           Data.LastLba0;\r
 \r
-               IdeDev->BlkIo.Media->MediaPresent = TRUE;\r
+             IdeDev->BlkIo.Media->MediaPresent = TRUE;\r
 \r
         IdeDev->BlkIo.Media->ReadOnly = TRUE;\r
 \r
@@ -1050,7 +1076,7 @@ AtapiReadCapacity (
           IdeDev->BlkIo.Media->LastBlock    = 0;\r
         } else {\r
 \r
-          IdeDev->BlkIo.Media->LastBlock =  (FormatData.LastLba3 << 24) |\r
+          IdeDev->BlkIo.Media->LastBlock = ((UINT32) FormatData.LastLba3 << 24) |\r
             (FormatData.LastLba2 << 16) | \r
             (FormatData.LastLba1 << 8)  |\r
             FormatData.LastLba0;\r
@@ -1082,30 +1108,70 @@ AtapiReadCapacity (
     return EFI_DEVICE_ERROR;\r
   }\r
 }\r
+/**\r
+  This function is used to test the current media write-protected or not residing\r
+  in the LS-120 drive or ZIP drive. \r
+  @param IdeDev          pointer pointing to IDE_BLK_IO_DEV data structure, used\r
+                         to record all the information of the IDE device.\r
+  @param WriteProtected  if True, current media is write protected.\r
+                         if FALSE, current media is writable\r
+\r
+  @retval EFI_SUCCESS         The media write-protected status is achieved successfully\r
+  @retval EFI_DEVICE_ERROR    Get Media Status Command is failed.\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
 \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
+  Used before read/write blocks from/to ATAPI device media. Since ATAPI device \r
+  media is removable, it is necessary to detect whether media is present and \r
+  get current present media's information, and if media has been changed, Block\r
+  I/O Protocol need to be reinstalled.\r
+\r
+  @param IdeDev       pointer pointing to IDE_BLK_IO_DEV data structure, used\r
+                      to record all the information of the IDE device.\r
+  @param MediaChange  return value that indicates if the media of the device has been\r
+                      changed.\r
+\r
+  @retval EFI_SUCCESS       media found successfully.\r
+  @retval EFI_DEVICE_ERROR  any error encounters during media detection.\r
+  @retval EFI_NO_MEDIA      media not found.\r
 \r
   @note\r
   parameter IdeDev may be updated in this function.\r
@@ -1350,22 +1416,14 @@ AtapiDetectMedia (
   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
+  @param IdeDev           pointer pointing to IDE_BLK_IO_DEV data structure, used\r
+                          to record all the information of the IDE device.\r
+  @param Buffer           A pointer to the destination buffer for the data. \r
+  @param Lba              The starting logical block address to read from on the \r
+                          device media.\r
+  @param NumberOfBlocks   The number of transfer data blocks.\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
+  @return status is fully dependent on the return status of AtapiPacketCommandIn() function.\r
 \r
 **/\r
 EFI_STATUS\r
@@ -1475,22 +1533,14 @@ AtapiReadSectors (
   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
+  @param IdeDev          pointer pointing to IDE_BLK_IO_DEV data structure, used\r
+                         to record all the information of the IDE device.\r
+  @param Buffer          A pointer to the source buffer for the data. \r
+  @param Lba             The starting logical block address to write onto \r
+                         the device media.\r
+  @param NumberOfBlocks  The number of transfer data blocks.\r
+  \r
+  @return status is fully dependent on the return status of AtapiPacketCommandOut() function.\r
 \r
 **/\r
 EFI_STATUS\r
@@ -1586,7 +1636,6 @@ AtapiWriteSectors (
 \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
@@ -1599,15 +1648,11 @@ AtapiWriteSectors (
   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
+  @param IdeDev    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
+  @retval EFI_SUCCESS      Soft reset completes successfully.\r
+  @retval EFI_DEVICE_ERROR Any step during the reset process is failed.\r
 \r
 **/\r
 EFI_STATUS\r
@@ -1651,51 +1696,29 @@ AtapiSoftReset (
   This function is the ATAPI implementation for ReadBlocks in the\r
   Block I/O Protocol interface.\r
 \r
-  @param[in] *IdeBlkIoDevice\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
+  @param IdeBlkIoDevice Indicates the calling context.\r
+  @param MediaId        The media id that the read request is for.\r
+  @param Lba            The starting logical block address to read from on the device.\r
+  @param BufferSize     The size of the Buffer in bytes. This must be a multiple\r
+                        of the intrinsic block size of the device.\r
+  @param Buffer         A pointer to the destination buffer for the data. The caller\r
+                        is responsible for either having implicit or explicit \r
+                        ownership of the memory that data is read into.\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
+  @retval EFI_SUCCESS           Read Blocks successfully.\r
+  @retval EFI_DEVICE_ERROR      Read Blocks failed.\r
+  @retval EFI_NO_MEDIA          There is no media in the device.\r
+  @retval EFI_MEDIA_CHANGED     The MediaId is not for the current media.\r
+  @retval EFI_BAD_BUFFER_SIZE   The BufferSize parameter is not a multiple of the\r
+                                intrinsic block size of the device.\r
+  @retval EFI_INVALID_PARAMETER The read request contains LBAs that are not valid,\r
+                                or the data buffer is not valid.\r
 **/\r
 EFI_STATUS\r
 AtapiBlkIoReadBlocks (\r
   IN IDE_BLK_IO_DEV   *IdeBlkIoDevice,\r
   IN UINT32           MediaId,\r
-  IN EFI_LBA          LBA,\r
+  IN EFI_LBA          Lba,\r
   IN UINTN            BufferSize,\r
   OUT VOID            *Buffer\r
   )\r
@@ -1761,11 +1784,11 @@ AtapiBlkIoReadBlocks (
     return EFI_BAD_BUFFER_SIZE;\r
   }\r
 \r
-  if (LBA > Media->LastBlock) {\r
+  if (Lba > Media->LastBlock) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
-  if ((LBA + NumberOfBlocks - 1) > Media->LastBlock) {\r
+  if ((Lba + NumberOfBlocks - 1) > Media->LastBlock) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
@@ -1777,7 +1800,7 @@ AtapiBlkIoReadBlocks (
   // 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
+  Status = AtapiReadSectors (IdeBlkIoDevice, Buffer, Lba, NumberOfBlocks);\r
   if (EFI_ERROR (Status)) {\r
     return EFI_DEVICE_ERROR;\r
   }\r
@@ -1789,7 +1812,7 @@ AtapiBlkIoReadBlocks (
   //\r
   // save the first block to the cache for performance\r
   //\r
-  if (LBA == 0 && (IdeBlkIoDevice->Cache == NULL)) {\r
+  if (Lba == 0 && (IdeBlkIoDevice->Cache == NULL)) {\r
     IdeBlkIoDevice->Cache = AllocatePool (BlockSize);\r
     if (IdeBlkIoDevice->Cache!= NULL) {\r
       CopyMem ((UINT8 *) IdeBlkIoDevice->Cache, (UINT8 *) Buffer, BlockSize);\r
@@ -1799,59 +1822,35 @@ AtapiBlkIoReadBlocks (
   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] *IdeBlkIoDevice\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
+  @param IdeBlkIoDevice  Indicates the calling context.\r
+  @param MediaId         The media id that the write request is for.\r
+  @param Lba             The starting logical block address to write onto the device.\r
+  @param BufferSize      The size of the Buffer in bytes. This must be a multiple\r
+                         of the intrinsic block size of the device.\r
+  @param Buffer          A pointer to the source buffer for the data. The caller\r
+                         is responsible for either having implicit or explicit ownership\r
+                         of the memory that data is written from.\r
+\r
+  @retval EFI_SUCCESS            Write Blocks successfully.\r
+  @retval EFI_DEVICE_ERROR       Write Blocks failed.\r
+  @retval EFI_NO_MEDIA           There is no media in the device.\r
+  @retval EFI_MEDIA_CHANGE       The MediaId is not for the current media.\r
+  @retval EFI_BAD_BUFFER_SIZE    The BufferSize parameter is not a multiple of the\r
+                                 intrinsic block size of the device.  \r
+  @retval EFI_INVALID_PARAMETER  The write request contains LBAs that are not valid, \r
+                                 or the data buffer is not valid.\r
+\r
+  @retval EFI_WRITE_PROTECTED    The write protected is enabled or the media does not support write\r
 **/\r
 EFI_STATUS\r
 AtapiBlkIoWriteBlocks (\r
   IN IDE_BLK_IO_DEV   *IdeBlkIoDevice,\r
   IN UINT32           MediaId,\r
-  IN EFI_LBA          LBA,\r
+  IN EFI_LBA          Lba,\r
   IN UINTN            BufferSize,\r
   OUT VOID            *Buffer\r
   )\r
@@ -1863,7 +1862,7 @@ AtapiBlkIoWriteBlocks (
   EFI_STATUS          Status;\r
   BOOLEAN             MediaChange;\r
 \r
-  if (LBA == 0 && IdeBlkIoDevice->Cache != NULL) {\r
+  if (Lba == 0 && IdeBlkIoDevice->Cache != NULL) {\r
     gBS->FreePool (IdeBlkIoDevice->Cache);\r
     IdeBlkIoDevice->Cache = NULL;\r
   }\r
@@ -1884,7 +1883,7 @@ AtapiBlkIoWriteBlocks (
   Status      = AtapiDetectMedia (IdeBlkIoDevice, &MediaChange);\r
   if (EFI_ERROR (Status)) {\r
 \r
-    if (LBA == 0 && IdeBlkIoDevice->Cache != NULL) {\r
+    if (Lba == 0 && IdeBlkIoDevice->Cache != NULL) {\r
       gBS->FreePool (IdeBlkIoDevice->Cache);\r
       IdeBlkIoDevice->Cache = NULL;\r
     }\r
@@ -1900,7 +1899,7 @@ AtapiBlkIoWriteBlocks (
 \r
   if (!(Media->MediaPresent)) {\r
 \r
-    if (LBA == 0 && IdeBlkIoDevice->Cache != NULL) {\r
+    if (Lba == 0 && IdeBlkIoDevice->Cache != NULL) {\r
       gBS->FreePool (IdeBlkIoDevice->Cache);\r
       IdeBlkIoDevice->Cache = NULL;\r
     }\r
@@ -1909,7 +1908,7 @@ AtapiBlkIoWriteBlocks (
 \r
   if ((MediaId != Media->MediaId) || MediaChange) {\r
 \r
-    if (LBA == 0 && IdeBlkIoDevice->Cache != NULL) {\r
+    if (Lba == 0 && IdeBlkIoDevice->Cache != NULL) {\r
       gBS->FreePool (IdeBlkIoDevice->Cache);\r
       IdeBlkIoDevice->Cache = NULL;\r
     }\r
@@ -1924,11 +1923,11 @@ AtapiBlkIoWriteBlocks (
     return EFI_BAD_BUFFER_SIZE;\r
   }\r
 \r
-  if (LBA > Media->LastBlock) {\r
+  if (Lba > Media->LastBlock) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
-  if ((LBA + NumberOfBlocks - 1) > Media->LastBlock) {\r
+  if ((Lba + NumberOfBlocks - 1) > Media->LastBlock) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
@@ -1940,7 +1939,7 @@ AtapiBlkIoWriteBlocks (
   // 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
+  Status = AtapiWriteSectors (IdeBlkIoDevice, Buffer, Lba, NumberOfBlocks);\r
   if (EFI_ERROR (Status)) {\r
     return EFI_DEVICE_ERROR;\r
   }\r
@@ -1949,162 +1948,5 @@ AtapiBlkIoWriteBlocks (
 \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