]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Bus/Ata/AtaAtapiPassThru/IdeMode.c
MdeModulePkg: Apply uncrustify changes
[mirror_edk2.git] / MdeModulePkg / Bus / Ata / AtaAtapiPassThru / IdeMode.c
index 1a4ac45bc1dc89c4a18391549b487a6f8b3e88eb..75403886e44a1df2c778dee3a95f62c3154b9d56 100644 (file)
@@ -1,14 +1,8 @@
 /** @file\r
   Header file for AHCI mode of ATA host controller.\r
-  \r
-  Copyright (c) 2010 - 2011, 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
 \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
+  Copyright (c) 2010 - 2015, Intel Corporation. All rights reserved.<BR>\r
+  SPDX-License-Identifier: BSD-2-Clause-Patent\r
 \r
 **/\r
 \r
 /**\r
   read a one-byte data from a IDE port.\r
 \r
-  @param  PciIo  The PCI IO protocol instance\r
-  @param  Port   The IDE Port number \r
+  @param  PciIo  A pointer to EFI_PCI_IO_PROTOCOL data structure\r
+  @param  Port   The IDE Port number\r
 \r
   @return  the one-byte data read from IDE port\r
 **/\r
 UINT8\r
 EFIAPI\r
 IdeReadPortB (\r
-  IN  EFI_PCI_IO_PROTOCOL   *PciIo,\r
-  IN  UINT16                Port\r
+  IN  EFI_PCI_IO_PROTOCOL  *PciIo,\r
+  IN  UINT16               Port\r
   )\r
 {\r
-  UINT8 Data;\r
+  UINT8  Data;\r
 \r
   ASSERT (PciIo != NULL);\r
 \r
@@ -41,7 +35,7 @@ IdeReadPortB (
               PciIo,\r
               EfiPciIoWidthUint8,\r
               EFI_PCI_IO_PASS_THROUGH_BAR,\r
-              (UINT64) Port,\r
+              (UINT64)Port,\r
               1,\r
               &Data\r
               );\r
@@ -51,16 +45,16 @@ IdeReadPortB (
 /**\r
   write a 1-byte data to a specific IDE port.\r
 \r
-  @param  PciIo  The PCI IO protocol instance\r
-  @param  Port   The IDE port to be writen\r
+  @param  PciIo  A pointer to EFI_PCI_IO_PROTOCOL data structure\r
+  @param  Port   The IDE port to be written\r
   @param  Data   The data to write to the port\r
 **/\r
 VOID\r
 EFIAPI\r
 IdeWritePortB (\r
-  IN  EFI_PCI_IO_PROTOCOL   *PciIo,\r
-  IN  UINT16                Port,\r
-  IN  UINT8                 Data\r
+  IN  EFI_PCI_IO_PROTOCOL  *PciIo,\r
+  IN  UINT16               Port,\r
+  IN  UINT8                Data\r
   )\r
 {\r
   ASSERT (PciIo != NULL);\r
@@ -72,7 +66,7 @@ IdeWritePortB (
               PciIo,\r
               EfiPciIoWidthUint8,\r
               EFI_PCI_IO_PASS_THROUGH_BAR,\r
-              (UINT64) Port,\r
+              (UINT64)Port,\r
               1,\r
               &Data\r
               );\r
@@ -81,16 +75,16 @@ IdeWritePortB (
 /**\r
   write a 1-word data to a specific IDE port.\r
 \r
-  @param  PciIo  PCI IO protocol instance\r
-  @param  Port   The IDE port to be writen\r
+  @param  PciIo  A pointer to EFI_PCI_IO_PROTOCOL data structure\r
+  @param  Port   The IDE port to be written\r
   @param  Data   The data to write to the port\r
 **/\r
 VOID\r
 EFIAPI\r
 IdeWritePortW (\r
-  IN  EFI_PCI_IO_PROTOCOL   *PciIo,\r
-  IN  UINT16                Port,\r
-  IN  UINT16                Data\r
+  IN  EFI_PCI_IO_PROTOCOL  *PciIo,\r
+  IN  UINT16               Port,\r
+  IN  UINT16               Data\r
   )\r
 {\r
   ASSERT (PciIo != NULL);\r
@@ -102,7 +96,7 @@ IdeWritePortW (
               PciIo,\r
               EfiPciIoWidthUint16,\r
               EFI_PCI_IO_PASS_THROUGH_BAR,\r
-              (UINT64) Port,\r
+              (UINT64)Port,\r
               1,\r
               &Data\r
               );\r
@@ -111,16 +105,16 @@ IdeWritePortW (
 /**\r
   write a 2-word data to a specific IDE port.\r
 \r
-  @param  PciIo  PCI IO protocol instance\r
-  @param  Port   The IDE port to be writen\r
+  @param  PciIo  A pointer to EFI_PCI_IO_PROTOCOL data structure\r
+  @param  Port   The IDE port to be written\r
   @param  Data   The data to write to the port\r
 **/\r
 VOID\r
 EFIAPI\r
 IdeWritePortDW (\r
-  IN  EFI_PCI_IO_PROTOCOL   *PciIo,\r
-  IN  UINT16                Port,\r
-  IN  UINT32                Data\r
+  IN  EFI_PCI_IO_PROTOCOL  *PciIo,\r
+  IN  UINT16               Port,\r
+  IN  UINT32               Data\r
   )\r
 {\r
   ASSERT (PciIo != NULL);\r
@@ -132,7 +126,7 @@ IdeWritePortDW (
               PciIo,\r
               EfiPciIoWidthUint32,\r
               EFI_PCI_IO_PASS_THROUGH_BAR,\r
-              (UINT64) Port,\r
+              (UINT64)Port,\r
               1,\r
               &Data\r
               );\r
@@ -143,7 +137,7 @@ IdeWritePortDW (
   Call the IO abstraction once to do the complete read,\r
   not one word at a time\r
 \r
-  @param  PciIo      Pointer to the EFI_PCI_IO instance\r
+  @param  PciIo      A pointer to EFI_PCI_IO_PROTOCOL data structure\r
   @param  Port       IO port to read\r
   @param  Count      No. of UINT16's to read\r
   @param  Buffer     Pointer to the data buffer for read\r
@@ -152,10 +146,10 @@ IdeWritePortDW (
 VOID\r
 EFIAPI\r
 IdeWritePortWMultiple (\r
-  IN  EFI_PCI_IO_PROTOCOL   *PciIo,\r
-  IN  UINT16                Port,\r
-  IN  UINTN                 Count,\r
-  IN  VOID                  *Buffer\r
+  IN  EFI_PCI_IO_PROTOCOL  *PciIo,\r
+  IN  UINT16               Port,\r
+  IN  UINTN                Count,\r
+  IN  VOID                 *Buffer\r
   )\r
 {\r
   ASSERT (PciIo  != NULL);\r
@@ -168,11 +162,10 @@ IdeWritePortWMultiple (
               PciIo,\r
               EfiPciIoWidthFifoUint16,\r
               EFI_PCI_IO_PASS_THROUGH_BAR,\r
-              (UINT64) Port,\r
+              (UINT64)Port,\r
               Count,\r
-              (UINT16 *) Buffer\r
+              (UINT16 *)Buffer\r
               );\r
-\r
 }\r
 \r
 /**\r
@@ -180,7 +173,7 @@ IdeWritePortWMultiple (
   Call the IO abstraction once to do the complete read,\r
   not one word at a time\r
 \r
-  @param  PciIo    Pointer to the EFI_PCI_IO instance\r
+  @param  PciIo    A pointer to EFI_PCI_IO_PROTOCOL data structure\r
   @param  Port     IO port to read\r
   @param  Count    Number of UINT16's to read\r
   @param  Buffer   Pointer to the data buffer for read\r
@@ -189,10 +182,10 @@ IdeWritePortWMultiple (
 VOID\r
 EFIAPI\r
 IdeReadPortWMultiple (\r
-  IN  EFI_PCI_IO_PROTOCOL   *PciIo,\r
-  IN  UINT16                Port,\r
-  IN  UINTN                 Count,\r
-  IN  VOID                  *Buffer\r
+  IN  EFI_PCI_IO_PROTOCOL  *PciIo,\r
+  IN  UINT16               Port,\r
+  IN  UINTN                Count,\r
+  IN  VOID                 *Buffer\r
   )\r
 {\r
   ASSERT (PciIo  != NULL);\r
@@ -205,11 +198,10 @@ IdeReadPortWMultiple (
               PciIo,\r
               EfiPciIoWidthFifoUint16,\r
               EFI_PCI_IO_PASS_THROUGH_BAR,\r
-              (UINT64) Port,\r
+              (UINT64)Port,\r
               Count,\r
-              (UINT16 *) Buffer\r
+              (UINT16 *)Buffer\r
               );\r
-\r
 }\r
 \r
 /**\r
@@ -217,7 +209,7 @@ IdeReadPortWMultiple (
   some debug information and if there is ERR bit set in the Status\r
   Register, the Error Register's value is also be parsed and print out.\r
 \r
-  @param PciIo            A pointer to ATA_ATAPI_PASS_THRU_INSTANCE data structure.\r
+  @param PciIo            A pointer to EFI_PCI_IO_PROTOCOL data structure.\r
   @param IdeRegisters     A pointer to EFI_IDE_REGISTERS data structure.\r
   @param AtaStatusBlock   A pointer to EFI_ATA_STATUS_BLOCK data structure.\r
 \r
@@ -225,12 +217,12 @@ IdeReadPortWMultiple (
 VOID\r
 EFIAPI\r
 DumpAllIdeRegisters (\r
-  IN     EFI_PCI_IO_PROTOCOL      *PciIo,\r
-  IN     EFI_IDE_REGISTERS        *IdeRegisters,\r
-  IN OUT EFI_ATA_STATUS_BLOCK     *AtaStatusBlock\r
+  IN     EFI_PCI_IO_PROTOCOL   *PciIo,\r
+  IN     EFI_IDE_REGISTERS     *IdeRegisters,\r
+  IN OUT EFI_ATA_STATUS_BLOCK  *AtaStatusBlock\r
   )\r
 {\r
-  EFI_ATA_STATUS_BLOCK StatusBlock;\r
+  EFI_ATA_STATUS_BLOCK  StatusBlock;\r
 \r
   ASSERT (PciIo != NULL);\r
   ASSERT (IdeRegisters != NULL);\r
@@ -258,47 +250,47 @@ DumpAllIdeRegisters (
 \r
   DEBUG_CODE_BEGIN ();\r
   if ((StatusBlock.AtaStatus & ATA_STSREG_DWF) != 0) {\r
-    DEBUG ((EFI_D_ERROR, "CheckRegisterStatus()-- %02x : Error : Write Fault\n", StatusBlock.AtaStatus));\r
+    DEBUG ((DEBUG_ERROR, "CheckRegisterStatus()-- %02x : Error : Write Fault\n", StatusBlock.AtaStatus));\r
   }\r
 \r
   if ((StatusBlock.AtaStatus & ATA_STSREG_CORR) != 0) {\r
-    DEBUG ((EFI_D_ERROR, "CheckRegisterStatus()-- %02x : Error : Corrected Data\n", StatusBlock.AtaStatus));\r
+    DEBUG ((DEBUG_ERROR, "CheckRegisterStatus()-- %02x : Error : Corrected Data\n", StatusBlock.AtaStatus));\r
   }\r
 \r
   if ((StatusBlock.AtaStatus & ATA_STSREG_ERR) != 0) {\r
     if ((StatusBlock.AtaError & ATA_ERRREG_BBK) != 0) {\r
-      DEBUG ((EFI_D_ERROR, "CheckRegisterStatus()-- %02x : Error : Bad Block Detected\n", StatusBlock.AtaError));\r
+      DEBUG ((DEBUG_ERROR, "CheckRegisterStatus()-- %02x : Error : Bad Block Detected\n", StatusBlock.AtaError));\r
     }\r
 \r
     if ((StatusBlock.AtaError & ATA_ERRREG_UNC) != 0) {\r
-      DEBUG ((EFI_D_ERROR, "CheckRegisterStatus()-- %02x : Error : Uncorrectable Data\n", StatusBlock.AtaError));\r
+      DEBUG ((DEBUG_ERROR, "CheckRegisterStatus()-- %02x : Error : Uncorrectable Data\n", StatusBlock.AtaError));\r
     }\r
 \r
     if ((StatusBlock.AtaError & ATA_ERRREG_MC) != 0) {\r
-      DEBUG ((EFI_D_ERROR, "CheckRegisterStatus()-- %02x : Error : Media Change\n", StatusBlock.AtaError));\r
+      DEBUG ((DEBUG_ERROR, "CheckRegisterStatus()-- %02x : Error : Media Change\n", StatusBlock.AtaError));\r
     }\r
 \r
     if ((StatusBlock.AtaError & ATA_ERRREG_ABRT) != 0) {\r
-      DEBUG ((EFI_D_ERROR, "CheckRegisterStatus()-- %02x : Error : Abort\n", StatusBlock.AtaError));\r
+      DEBUG ((DEBUG_ERROR, "CheckRegisterStatus()-- %02x : Error : Abort\n", StatusBlock.AtaError));\r
     }\r
 \r
     if ((StatusBlock.AtaError & ATA_ERRREG_TK0NF) != 0) {\r
-      DEBUG ((EFI_D_ERROR, "CheckRegisterStatus()-- %02x : Error : Track 0 Not Found\n", StatusBlock.AtaError));\r
+      DEBUG ((DEBUG_ERROR, "CheckRegisterStatus()-- %02x : Error : Track 0 Not Found\n", StatusBlock.AtaError));\r
     }\r
 \r
     if ((StatusBlock.AtaError & ATA_ERRREG_AMNF) != 0) {\r
-      DEBUG ((EFI_D_ERROR, "CheckRegisterStatus()-- %02x : Error : Address Mark Not Found\n", StatusBlock.AtaError));\r
+      DEBUG ((DEBUG_ERROR, "CheckRegisterStatus()-- %02x : Error : Address Mark Not Found\n", StatusBlock.AtaError));\r
     }\r
   }\r
+\r
   DEBUG_CODE_END ();\r
 }\r
 \r
 /**\r
-  This function is used to analyze the Status Register and print out\r
-  some debug information and if there is ERR bit set in the Status\r
-  Register, the Error Register's value is also be parsed and print out.\r
+  This function is used to analyze the Status Register at the condition that BSY is zero.\r
+  if there is ERR bit set in the Status Register, then return error.\r
 \r
-  @param PciIo            A pointer to ATA_ATAPI_PASS_THRU_INSTANCE data structure.\r
+  @param PciIo            A pointer to EFI_PCI_IO_PROTOCOL data structure.\r
   @param IdeRegisters     A pointer to EFI_IDE_REGISTERS data structure.\r
 \r
   @retval EFI_SUCCESS       No err information in the Status Register.\r
@@ -308,25 +300,26 @@ DumpAllIdeRegisters (
 EFI_STATUS\r
 EFIAPI\r
 CheckStatusRegister (\r
-  IN  EFI_PCI_IO_PROTOCOL      *PciIo,\r
-  IN  EFI_IDE_REGISTERS        *IdeRegisters\r
+  IN  EFI_PCI_IO_PROTOCOL  *PciIo,\r
+  IN  EFI_IDE_REGISTERS    *IdeRegisters\r
   )\r
 {\r
-  EFI_STATUS      Status;\r
-  UINT8           StatusRegister;\r
+  UINT8  StatusRegister;\r
 \r
   ASSERT (PciIo != NULL);\r
   ASSERT (IdeRegisters != NULL);\r
 \r
   StatusRegister = IdeReadPortB (PciIo, IdeRegisters->CmdOrStatus);\r
 \r
-  if ((StatusRegister & (ATA_STSREG_ERR | ATA_STSREG_DWF | ATA_STSREG_CORR)) == 0) {\r
-    Status = EFI_SUCCESS;\r
-  } else {\r
-    Status = EFI_DEVICE_ERROR;\r
+  if ((StatusRegister & ATA_STSREG_BSY) == 0) {\r
+    if ((StatusRegister & (ATA_STSREG_ERR | ATA_STSREG_DWF | ATA_STSREG_CORR)) == 0) {\r
+      return EFI_SUCCESS;\r
+    } else {\r
+      return EFI_DEVICE_ERROR;\r
+    }\r
   }\r
 \r
-  return Status;\r
+  return EFI_SUCCESS;\r
 }\r
 \r
 /**\r
@@ -334,9 +327,9 @@ CheckStatusRegister (
   Register. DRQ is cleared when the device is finished transferring data.\r
   So this function is called after data transfer is finished.\r
 \r
-  @param PciIo            A pointer to ATA_ATAPI_PASS_THRU_INSTANCE data structure.\r
+  @param PciIo            A pointer to EFI_PCI_IO_PROTOCOL data structure.\r
   @param IdeRegisters     A pointer to EFI_IDE_REGISTERS data structure.\r
-  @param Timeout          The time to complete the command.\r
+  @param Timeout          The time to complete the command, uses 100ns as a unit.\r
 \r
   @retval EFI_SUCCESS     DRQ bit clear within the time out.\r
 \r
@@ -349,61 +342,59 @@ CheckStatusRegister (
 EFI_STATUS\r
 EFIAPI\r
 DRQClear (\r
-  IN  EFI_PCI_IO_PROTOCOL       *PciIo,\r
-  IN  EFI_IDE_REGISTERS         *IdeRegisters,\r
-  IN  UINT64                    Timeout\r
+  IN  EFI_PCI_IO_PROTOCOL  *PciIo,\r
+  IN  EFI_IDE_REGISTERS    *IdeRegisters,\r
+  IN  UINT64               Timeout\r
   )\r
 {\r
-  UINT32  Delay;\r
-  UINT8   StatusRegister;\r
-  UINT8   ErrorRegister;\r
+  UINT64   Delay;\r
+  UINT8    StatusRegister;\r
+  BOOLEAN  InfiniteWait;\r
 \r
   ASSERT (PciIo != NULL);\r
   ASSERT (IdeRegisters != NULL);\r
 \r
-  Delay = (UINT32) (DivU64x32(Timeout, 1000) + 1);\r
+  if (Timeout == 0) {\r
+    InfiniteWait = TRUE;\r
+  } else {\r
+    InfiniteWait = FALSE;\r
+  }\r
+\r
+  Delay = DivU64x32 (Timeout, 1000) + 1;\r
   do {\r
     StatusRegister = IdeReadPortB (PciIo, IdeRegisters->CmdOrStatus);\r
 \r
     //\r
-    // wait for BSY == 0 and DRQ == 0\r
+    // Wait for BSY == 0, then judge if DRQ is clear\r
     //\r
-    if ((StatusRegister & (ATA_STSREG_DRQ | ATA_STSREG_BSY)) == 0) {\r
-      break;\r
-    }\r
-\r
-    if ((StatusRegister & (ATA_STSREG_BSY | ATA_STSREG_ERR)) == ATA_STSREG_ERR) {\r
-      ErrorRegister = IdeReadPortB (PciIo, IdeRegisters->ErrOrFeature);\r
-\r
-      if ((ErrorRegister & ATA_ERRREG_ABRT) == ATA_ERRREG_ABRT) {\r
-        return EFI_ABORTED;\r
+    if ((StatusRegister & ATA_STSREG_BSY) == 0) {\r
+      if ((StatusRegister & ATA_STSREG_DRQ) == ATA_STSREG_DRQ) {\r
+        return EFI_DEVICE_ERROR;\r
+      } else {\r
+        return EFI_SUCCESS;\r
       }\r
     }\r
 \r
     //\r
-    //  Stall for 100 microseconds.\r
+    // Stall for 100 microseconds.\r
     //\r
     MicroSecondDelay (100);\r
 \r
     Delay--;\r
+  } while (InfiniteWait || (Delay > 0));\r
 \r
-  } while (Delay > 0);\r
-\r
-  if (Delay == 0) {\r
-    return EFI_TIMEOUT;\r
-  }\r
-\r
-  return EFI_SUCCESS;\r
+  return EFI_TIMEOUT;\r
 }\r
+\r
 /**\r
   This function is used to poll for the DRQ bit clear in the Alternate\r
   Status Register. DRQ is cleared when the device is finished\r
   transferring data. So this function is called after data transfer\r
   is finished.\r
 \r
-  @param PciIo            A pointer to ATA_ATAPI_PASS_THRU_INSTANCE data structure.\r
+  @param PciIo            A pointer to EFI_PCI_IO_PROTOCOL data structure.\r
   @param IdeRegisters     A pointer to EFI_IDE_REGISTERS data structure.\r
-  @param Timeout          The time to complete the command.\r
+  @param Timeout          The time to complete the command, uses 100ns as a unit.\r
 \r
   @retval EFI_SUCCESS     DRQ bit clear within the time out.\r
 \r
@@ -419,29 +410,31 @@ DRQClear2 (
   IN  UINT64               Timeout\r
   )\r
 {\r
-  UINT32  Delay;\r
-  UINT8   AltRegister;\r
-  UINT8   ErrorRegister;\r
+  UINT64   Delay;\r
+  UINT8    AltRegister;\r
+  BOOLEAN  InfiniteWait;\r
 \r
   ASSERT (PciIo != NULL);\r
   ASSERT (IdeRegisters != NULL);\r
 \r
-  Delay = (UINT32) (DivU64x32(Timeout, 1000) + 1);\r
+  if (Timeout == 0) {\r
+    InfiniteWait = TRUE;\r
+  } else {\r
+    InfiniteWait = FALSE;\r
+  }\r
+\r
+  Delay = DivU64x32 (Timeout, 1000) + 1;\r
   do {\r
     AltRegister = IdeReadPortB (PciIo, IdeRegisters->AltOrDev);\r
 \r
     //\r
-    //  wait for BSY == 0 and DRQ == 0\r
+    // Wait for BSY == 0, then judge if DRQ is clear\r
     //\r
-    if ((AltRegister & (ATA_STSREG_DRQ | ATA_STSREG_BSY)) == 0) {\r
-      break;\r
-    }\r
-\r
-    if ((AltRegister & (ATA_STSREG_BSY | ATA_STSREG_ERR)) == ATA_STSREG_ERR) {\r
-      ErrorRegister = IdeReadPortB (PciIo, IdeRegisters->ErrOrFeature);\r
-\r
-      if ((ErrorRegister & ATA_ERRREG_ABRT) == ATA_ERRREG_ABRT) {\r
-        return EFI_ABORTED;\r
+    if ((AltRegister & ATA_STSREG_BSY) == 0) {\r
+      if ((AltRegister & ATA_STSREG_DRQ) == ATA_STSREG_DRQ) {\r
+        return EFI_DEVICE_ERROR;\r
+      } else {\r
+        return EFI_SUCCESS;\r
       }\r
     }\r
 \r
@@ -451,14 +444,9 @@ DRQClear2 (
     MicroSecondDelay (100);\r
 \r
     Delay--;\r
+  } while (InfiniteWait || (Delay > 0));\r
 \r
-  } while (Delay > 0);\r
-\r
-  if (Delay == 0) {\r
-    return EFI_TIMEOUT;\r
-  }\r
-\r
-  return EFI_SUCCESS;\r
+  return EFI_TIMEOUT;\r
 }\r
 \r
 /**\r
@@ -468,13 +456,22 @@ DRQClear2 (
   is called after the command is sent to the device and before required\r
   data is transferred.\r
 \r
-  @param PciIo            A pointer to ATA_ATAPI_PASS_THRU_INSTANCE data structure.\r
+  @param PciIo            A pointer to EFI_PCI_IO_PROTOCOL data structure.\r
   @param IdeRegisters     A pointer to EFI_IDE_REGISTERS data structure.\r
-  @param Timeout          The time to complete the command.\r
+  @param Timeout          The time to complete the command, uses 100ns as a unit.\r
+\r
+  @retval EFI_SUCCESS           BSY bit cleared and DRQ bit set within the\r
+                                timeout.\r
+\r
+  @retval EFI_TIMEOUT           BSY bit not cleared within the timeout.\r
+\r
+  @retval EFI_ABORTED           Polling abandoned due to command abort.\r
 \r
-  @retval EFI_SUCCESS          DRQ bit set within the time out.\r
-  @retval EFI_TIMEOUT          DRQ bit not set within the time out.\r
-  @retval EFI_ABORTED          DRQ bit not set caused by the command abort.\r
+  @retval EFI_DEVICE_ERROR      Polling abandoned due to a non-abort error.\r
+\r
+  @retval EFI_NOT_READY         BSY bit cleared within timeout, and device\r
+                                reported "command complete" by clearing DRQ\r
+                                bit.\r
 \r
   @note  Read Status Register will clear interrupt status.\r
 \r
@@ -487,32 +484,45 @@ DRQReady (
   IN  UINT64               Timeout\r
   )\r
 {\r
-  UINT32  Delay;\r
-  UINT8   StatusRegister;\r
-  UINT8   ErrorRegister;\r
+  UINT64   Delay;\r
+  UINT8    StatusRegister;\r
+  UINT8    ErrorRegister;\r
+  BOOLEAN  InfiniteWait;\r
 \r
   ASSERT (PciIo != NULL);\r
   ASSERT (IdeRegisters != NULL);\r
 \r
-  Delay = (UINT32) (DivU64x32(Timeout, 1000) + 1);\r
+  if (Timeout == 0) {\r
+    InfiniteWait = TRUE;\r
+  } else {\r
+    InfiniteWait = FALSE;\r
+  }\r
+\r
+  Delay = DivU64x32 (Timeout, 1000) + 1;\r
   do {\r
     //\r
-    //  read Status Register will clear interrupt\r
+    // Read Status Register will clear interrupt\r
     //\r
     StatusRegister = IdeReadPortB (PciIo, IdeRegisters->CmdOrStatus);\r
 \r
     //\r
-    //  BSY==0,DRQ==1\r
+    // Wait for BSY == 0, then judge if DRQ is clear or ERR is set\r
     //\r
-    if ((StatusRegister & (ATA_STSREG_BSY | ATA_STSREG_DRQ)) == ATA_STSREG_DRQ) {\r
-      break;\r
-    }\r
+    if ((StatusRegister & ATA_STSREG_BSY) == 0) {\r
+      if ((StatusRegister & ATA_STSREG_ERR) == ATA_STSREG_ERR) {\r
+        ErrorRegister = IdeReadPortB (PciIo, IdeRegisters->ErrOrFeature);\r
 \r
-    if ((StatusRegister & (ATA_STSREG_BSY | ATA_STSREG_ERR)) == ATA_STSREG_ERR) {\r
-      ErrorRegister = IdeReadPortB (PciIo, IdeRegisters->ErrOrFeature);\r
+        if ((ErrorRegister & ATA_ERRREG_ABRT) == ATA_ERRREG_ABRT) {\r
+          return EFI_ABORTED;\r
+        }\r
 \r
-      if ((ErrorRegister & ATA_ERRREG_ABRT) == ATA_ERRREG_ABRT) {\r
-        return EFI_ABORTED;\r
+        return EFI_DEVICE_ERROR;\r
+      }\r
+\r
+      if ((StatusRegister & ATA_STSREG_DRQ) == ATA_STSREG_DRQ) {\r
+        return EFI_SUCCESS;\r
+      } else {\r
+        return EFI_NOT_READY;\r
       }\r
     }\r
 \r
@@ -522,188 +532,83 @@ DRQReady (
     MicroSecondDelay (100);\r
 \r
     Delay--;\r
-  } while (Delay > 0);\r
+  } while (InfiniteWait || (Delay > 0));\r
 \r
-  if (Delay == 0) {\r
-    return EFI_TIMEOUT;\r
-  }\r
-\r
-  return EFI_SUCCESS;\r
+  return EFI_TIMEOUT;\r
 }\r
+\r
 /**\r
   This function is used to poll for the DRQ bit set in the Alternate Status Register.\r
-  DRQ is set when the device is ready to transfer data. So this function is called after \r
+  DRQ is set when the device is ready to transfer data. So this function is called after\r
   the command is sent to the device and before required data is transferred.\r
 \r
-  @param PciIo            A pointer to ATA_ATAPI_PASS_THRU_INSTANCE data structure.\r
+  @param PciIo            A pointer to EFI_PCI_IO_PROTOCOL data structure.\r
   @param IdeRegisters     A pointer to EFI_IDE_REGISTERS data structure.\r
-  @param Timeout          The time to complete the command.\r
-\r
-  @retval EFI_SUCCESS           DRQ bit set within the time out.\r
-  @retval EFI_TIMEOUT           DRQ bit not set within the time out.\r
-  @retval EFI_ABORTED           DRQ bit not set caused by the command abort.\r
-  @note  Read Alternate Status Register will not clear interrupt status.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-DRQReady2 (\r
-  IN  EFI_PCI_IO_PROTOCOL  *PciIo,\r
-  IN  EFI_IDE_REGISTERS    *IdeRegisters,\r
-  IN  UINT64               Timeout\r
-  )\r
-{\r
-  UINT32  Delay;\r
-  UINT8   AltRegister;\r
-  UINT8   ErrorRegister;\r
-\r
-  ASSERT (PciIo != NULL);\r
-  ASSERT (IdeRegisters != NULL);\r
-\r
-  Delay = (UINT32) (DivU64x32(Timeout, 1000) + 1);\r
-\r
-  do {\r
-    //\r
-    //  Read Alternate Status Register will not clear interrupt status\r
-    //\r
-    AltRegister = IdeReadPortB (PciIo, IdeRegisters->AltOrDev);\r
-    //\r
-    // BSY == 0 , DRQ == 1\r
-    //\r
-    if ((AltRegister & (ATA_STSREG_BSY | ATA_STSREG_DRQ)) == ATA_STSREG_DRQ) {\r
-      break;\r
-    }\r
-\r
-    if ((AltRegister & (ATA_STSREG_BSY | ATA_STSREG_ERR)) == ATA_STSREG_ERR) {\r
-      ErrorRegister = IdeReadPortB (PciIo, IdeRegisters->ErrOrFeature);\r
-\r
-      if ((ErrorRegister & ATA_ERRREG_ABRT) == ATA_ERRREG_ABRT) {\r
-        return EFI_ABORTED;\r
-      }\r
-    }\r
-\r
-    //\r
-    // Stall for 100 microseconds.\r
-    //\r
-    MicroSecondDelay (100);\r
+  @param Timeout          The time to complete the command, uses 100ns as a unit.\r
 \r
-    Delay--;\r
-  } while (Delay > 0);\r
+  @retval EFI_SUCCESS           BSY bit cleared and DRQ bit set within the\r
+                                timeout.\r
 \r
-  if (Delay == 0) {\r
-    return EFI_TIMEOUT;\r
-  }\r
+  @retval EFI_TIMEOUT           BSY bit not cleared within the timeout.\r
 \r
-  return EFI_SUCCESS;\r
-}\r
+  @retval EFI_ABORTED           Polling abandoned due to command abort.\r
 \r
-/**\r
-  This function is used to poll for the DRDY bit set in the Status Register. DRDY\r
-  bit is set when the device is ready to accept command. Most ATA commands must be \r
-  sent after DRDY set except the ATAPI Packet Command.\r
+  @retval EFI_DEVICE_ERROR      Polling abandoned due to a non-abort error.\r
 \r
-  @param PciIo            A pointer to ATA_ATAPI_PASS_THRU_INSTANCE data structure.\r
-  @param IdeRegisters     A pointer to EFI_IDE_REGISTERS data structure.\r
-  @param Timeout          The time to complete the command.\r
+  @retval EFI_NOT_READY         BSY bit cleared within timeout, and device\r
+                                reported "command complete" by clearing DRQ\r
+                                bit.\r
 \r
-  @retval EFI_SUCCESS         DRDY bit set within the time out.\r
-  @retval EFI_TIMEOUT         DRDY bit not set within the time out.\r
+  @note  Read Alternate Status Register will not clear interrupt status.\r
 \r
-  @note  Read Status Register will clear interrupt status.\r
 **/\r
 EFI_STATUS\r
 EFIAPI\r
-DRDYReady (\r
+DRQReady2 (\r
   IN  EFI_PCI_IO_PROTOCOL  *PciIo,\r
   IN  EFI_IDE_REGISTERS    *IdeRegisters,\r
   IN  UINT64               Timeout\r
   )\r
 {\r
-  UINT32  Delay;\r
-  UINT8   StatusRegister;\r
-  UINT8   ErrorRegister;\r
+  UINT64   Delay;\r
+  UINT8    AltRegister;\r
+  UINT8    ErrorRegister;\r
+  BOOLEAN  InfiniteWait;\r
 \r
   ASSERT (PciIo != NULL);\r
   ASSERT (IdeRegisters != NULL);\r
 \r
-  Delay = (UINT32) (DivU64x32(Timeout, 1000) + 1);\r
-  do {\r
-    StatusRegister = IdeReadPortB (PciIo, IdeRegisters->CmdOrStatus);\r
-    //\r
-    //  BSY == 0 , DRDY == 1\r
-    //\r
-    if ((StatusRegister & (ATA_STSREG_DRDY | ATA_STSREG_BSY)) == ATA_STSREG_DRDY) {\r
-      break;\r
-    }\r
-\r
-    if ((StatusRegister & (ATA_STSREG_BSY | ATA_STSREG_ERR)) == ATA_STSREG_ERR) {\r
-      ErrorRegister = IdeReadPortB (PciIo, IdeRegisters->ErrOrFeature);\r
-\r
-      if ((ErrorRegister & ATA_ERRREG_ABRT) == ATA_ERRREG_ABRT) {\r
-        return EFI_ABORTED;\r
-      }\r
-    }\r
-\r
-    //\r
-    // Stall for 100 microseconds.\r
-    //\r
-    MicroSecondDelay (100);\r
-\r
-    Delay--;\r
-  } while (Delay > 0);\r
-\r
-  if (Delay == 0) {\r
-    return EFI_TIMEOUT;\r
+  if (Timeout == 0) {\r
+    InfiniteWait = TRUE;\r
+  } else {\r
+    InfiniteWait = FALSE;\r
   }\r
 \r
-  return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
-  This function is used to poll for the DRDY bit set in the Alternate Status Register. \r
-  DRDY bit is set when the device is ready to accept command. Most ATA commands must \r
-  be sent after DRDY set except the ATAPI Packet Command.\r
-\r
-  @param PciIo            A pointer to ATA_ATAPI_PASS_THRU_INSTANCE data structure.\r
-  @param IdeRegisters     A pointer to EFI_IDE_REGISTERS data structure.\r
-  @param Timeout          The time to complete the command.\r
+  Delay = DivU64x32 (Timeout, 1000) + 1;\r
 \r
-  @retval EFI_SUCCESS      DRDY bit set within the time out.\r
-  @retval EFI_TIMEOUT      DRDY bit not set within the time out.\r
-\r
-  @note  Read Alternate Status Register will clear interrupt status.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-DRDYReady2 (\r
-  IN  EFI_PCI_IO_PROTOCOL  *PciIo,\r
-  IN  EFI_IDE_REGISTERS    *IdeRegisters,\r
-  IN  UINT64               Timeout\r
-  )\r
-{\r
-  UINT32  Delay;\r
-  UINT8   AltRegister;\r
-  UINT8   ErrorRegister;\r
-\r
-  ASSERT (PciIo != NULL);\r
-  ASSERT (IdeRegisters != NULL);\r
-\r
-  Delay = (UINT32) (DivU64x32(Timeout, 1000) + 1);\r
   do {\r
+    //\r
+    // Read Alternate Status Register will not clear interrupt status\r
+    //\r
     AltRegister = IdeReadPortB (PciIo, IdeRegisters->AltOrDev);\r
     //\r
-    //  BSY == 0 , DRDY == 1\r
+    // Wait for BSY == 0, then judge if DRQ is clear or ERR is set\r
     //\r
-    if ((AltRegister & (ATA_STSREG_DRDY | ATA_STSREG_BSY)) == ATA_STSREG_DRDY) {\r
-      break;\r
-    }\r
+    if ((AltRegister & ATA_STSREG_BSY) == 0) {\r
+      if ((AltRegister & ATA_STSREG_ERR) == ATA_STSREG_ERR) {\r
+        ErrorRegister = IdeReadPortB (PciIo, IdeRegisters->ErrOrFeature);\r
 \r
-    if ((AltRegister & (ATA_STSREG_BSY | ATA_STSREG_ERR)) == ATA_STSREG_ERR) {\r
-      ErrorRegister = IdeReadPortB (PciIo, IdeRegisters->ErrOrFeature);\r
+        if ((ErrorRegister & ATA_ERRREG_ABRT) == ATA_ERRREG_ABRT) {\r
+          return EFI_ABORTED;\r
+        }\r
 \r
-      if ((ErrorRegister & ATA_ERRREG_ABRT) == ATA_ERRREG_ABRT) {\r
-        return EFI_ABORTED;\r
+        return EFI_DEVICE_ERROR;\r
+      }\r
+\r
+      if ((AltRegister & ATA_STSREG_DRQ) == ATA_STSREG_DRQ) {\r
+        return EFI_SUCCESS;\r
+      } else {\r
+        return EFI_NOT_READY;\r
       }\r
     }\r
 \r
@@ -713,13 +618,9 @@ DRDYReady2 (
     MicroSecondDelay (100);\r
 \r
     Delay--;\r
-  } while (Delay > 0);\r
-\r
-  if (Delay == 0) {\r
-    return EFI_TIMEOUT;\r
-  }\r
+  } while (InfiniteWait || (Delay > 0));\r
 \r
-  return EFI_SUCCESS;\r
+  return EFI_TIMEOUT;\r
 }\r
 \r
 /**\r
@@ -728,7 +629,7 @@ DRDYReady2 (
 \r
   @param PciIo            A pointer to ATA_ATAPI_PASS_THRU_INSTANCE data structure.\r
   @param IdeRegisters     A pointer to EFI_IDE_REGISTERS data structure.\r
-  @param Timeout          The time to complete the command.\r
+  @param Timeout          The time to complete the command, uses 100ns as a unit.\r
 \r
   @retval EFI_SUCCESS          BSY bit clear within the time out.\r
   @retval EFI_TIMEOUT          BSY bit not clear within the time out.\r
@@ -743,69 +644,25 @@ WaitForBSYClear (
   IN  UINT64               Timeout\r
   )\r
 {\r
-  UINT32  Delay;\r
-  UINT8   StatusRegister;\r
+  UINT64   Delay;\r
+  UINT8    StatusRegister;\r
+  BOOLEAN  InfiniteWait;\r
 \r
   ASSERT (PciIo != NULL);\r
   ASSERT (IdeRegisters != NULL);\r
 \r
-  Delay = (UINT32) (DivU64x32(Timeout, 1000) + 1);\r
-  do {\r
-    StatusRegister = IdeReadPortB (PciIo, IdeRegisters->CmdOrStatus);\r
-\r
-    if ((StatusRegister & ATA_STSREG_BSY) == 0x00) {\r
-      break;\r
-    }\r
-\r
-    //\r
-    // Stall for 100 microseconds.\r
-    //\r
-    MicroSecondDelay (100);\r
-\r
-    Delay--;\r
-\r
-  } while (Delay > 0);\r
-\r
-  if (Delay == 0) {\r
-    return EFI_TIMEOUT;\r
+  if (Timeout == 0) {\r
+    InfiniteWait = TRUE;\r
+  } else {\r
+    InfiniteWait = FALSE;\r
   }\r
 \r
-  return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
-  This function is used to poll for the BSY bit clear in the Status Register. BSY\r
-  is clear when the device is not busy. Every command must be sent after device is not busy.\r
-\r
-  @param PciIo            A pointer to ATA_ATAPI_PASS_THRU_INSTANCE data structure.\r
-  @param IdeRegisters     A pointer to EFI_IDE_REGISTERS data structure.\r
-  @param Timeout          The time to complete the command.\r
-\r
-  @retval EFI_SUCCESS          BSY bit clear within the time out.\r
-  @retval EFI_TIMEOUT          BSY bit not clear within the time out.\r
-\r
-  @note Read Status Register will clear interrupt status.\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-WaitForBSYClear2 (\r
-  IN  EFI_PCI_IO_PROTOCOL  *PciIo,\r
-  IN  EFI_IDE_REGISTERS    *IdeRegisters,\r
-  IN  UINT64               Timeout\r
-  )\r
-{\r
-  UINT32  Delay;\r
-  UINT8   AltStatusRegister;\r
-\r
-  ASSERT (PciIo != NULL);\r
-  ASSERT (IdeRegisters != NULL);\r
-\r
-  Delay = (UINT32) (DivU64x32(Timeout, 1000) + 1);\r
+  Delay = DivU64x32 (Timeout, 1000) + 1;\r
   do {\r
-    AltStatusRegister = IdeReadPortB (PciIo, IdeRegisters->AltOrDev);\r
+    StatusRegister = IdeReadPortB (PciIo, IdeRegisters->CmdOrStatus);\r
 \r
-    if ((AltStatusRegister & ATA_STSREG_BSY) == 0x00) {\r
-      break;\r
+    if ((StatusRegister & ATA_STSREG_BSY) == 0x00) {\r
+      return EFI_SUCCESS;\r
     }\r
 \r
     //\r
@@ -814,18 +671,13 @@ WaitForBSYClear2 (
     MicroSecondDelay (100);\r
 \r
     Delay--;\r
+  } while (InfiniteWait || (Delay > 0));\r
 \r
-  } while (Delay > 0);\r
-\r
-  if (Delay == 0) {\r
-    return EFI_TIMEOUT;\r
-  }\r
-\r
-  return EFI_SUCCESS;\r
+  return EFI_TIMEOUT;\r
 }\r
 \r
 /**\r
-  Get IDE i/o port registers' base addresses by mode. \r
+  Get IDE i/o port registers' base addresses by mode.\r
 \r
   In 'Compatibility' mode, use fixed addresses.\r
   In Native-PCI mode, get base addresses from BARs in the PCI IDE controller's\r
@@ -848,7 +700,7 @@ WaitForBSYClear2 (
   |___________|_______________|_______________|\r
 \r
   Table 1. Compatibility resource mappings\r
-  \r
+\r
   b) In Native-PCI mode, IDE registers are mapped into IO space using the BARs\r
   in IDE controller's PCI Configuration Space, shown in the Table 2 below.\r
    ___________________________________________________\r
@@ -863,26 +715,26 @@ WaitForBSYClear2 (
   Table 2. BARs for Register Mapping\r
 \r
   @param[in]      PciIo          Pointer to the EFI_PCI_IO_PROTOCOL instance\r
-  @param[in, out] IdeRegisters    Pointer to EFI_IDE_REGISTERS which is used to\r
+  @param[in, out] IdeRegisters   Pointer to EFI_IDE_REGISTERS which is used to\r
                                  store the IDE i/o port registers' base addresses\r
-           \r
+\r
   @retval EFI_UNSUPPORTED        Return this value when the BARs is not IO type\r
   @retval EFI_SUCCESS            Get the Base address successfully\r
-  @retval Other                  Read the pci configureation data error\r
+  @retval Other                  Read the pci configuration data error\r
 \r
 **/\r
 EFI_STATUS\r
 EFIAPI\r
 GetIdeRegisterIoAddr (\r
-  IN     EFI_PCI_IO_PROTOCOL         *PciIo,\r
-  IN OUT EFI_IDE_REGISTERS           *IdeRegisters\r
+  IN     EFI_PCI_IO_PROTOCOL  *PciIo,\r
+  IN OUT EFI_IDE_REGISTERS    *IdeRegisters\r
   )\r
 {\r
-  EFI_STATUS        Status;\r
-  PCI_TYPE00        PciData;\r
-  UINT16            CommandBlockBaseAddr;\r
-  UINT16            ControlBlockBaseAddr;\r
-  UINT16            BusMasterBaseAddr;\r
+  EFI_STATUS  Status;\r
+  PCI_TYPE00  PciData;\r
+  UINT16      CommandBlockBaseAddr;\r
+  UINT16      ControlBlockBaseAddr;\r
+  UINT16      BusMasterBaseAddr;\r
 \r
   if ((PciIo == NULL) || (IdeRegisters == NULL)) {\r
     return EFI_INVALID_PARAMETER;\r
@@ -900,7 +752,7 @@ GetIdeRegisterIoAddr (
     return Status;\r
   }\r
 \r
-  BusMasterBaseAddr    = (UINT16) ((PciData.Device.Bar[4] & 0x0000fff0));\r
+  BusMasterBaseAddr = (UINT16)((PciData.Device.Bar[4] & 0x0000fff0));\r
 \r
   if ((PciData.Hdr.ClassCode[0] & IDE_PRIMARY_OPERATING_MODE) == 0) {\r
     CommandBlockBaseAddr = 0x1f0;\r
@@ -909,26 +761,27 @@ GetIdeRegisterIoAddr (
     //\r
     // The BARs should be of IO type\r
     //\r
-    if ((PciData.Device.Bar[0] & BIT0) == 0 ||\r
-        (PciData.Device.Bar[1] & BIT0) == 0) {\r
+    if (((PciData.Device.Bar[0] & BIT0) == 0) ||\r
+        ((PciData.Device.Bar[1] & BIT0) == 0))\r
+    {\r
       return EFI_UNSUPPORTED;\r
     }\r
 \r
-    CommandBlockBaseAddr = (UINT16) (PciData.Device.Bar[0] & 0x0000fff8);\r
-    ControlBlockBaseAddr = (UINT16) ((PciData.Device.Bar[1] & 0x0000fffc) + 2);\r
+    CommandBlockBaseAddr = (UINT16)(PciData.Device.Bar[0] & 0x0000fff8);\r
+    ControlBlockBaseAddr = (UINT16)((PciData.Device.Bar[1] & 0x0000fffc) + 2);\r
   }\r
 \r
   //\r
   // Calculate IDE primary channel I/O register base address.\r
   //\r
   IdeRegisters[EfiIdePrimary].Data              = CommandBlockBaseAddr;\r
-  IdeRegisters[EfiIdePrimary].ErrOrFeature      = (UINT16) (CommandBlockBaseAddr + 0x01);\r
-  IdeRegisters[EfiIdePrimary].SectorCount       = (UINT16) (CommandBlockBaseAddr + 0x02);\r
-  IdeRegisters[EfiIdePrimary].SectorNumber      = (UINT16) (CommandBlockBaseAddr + 0x03);\r
-  IdeRegisters[EfiIdePrimary].CylinderLsb       = (UINT16) (CommandBlockBaseAddr + 0x04);\r
-  IdeRegisters[EfiIdePrimary].CylinderMsb       = (UINT16) (CommandBlockBaseAddr + 0x05);\r
-  IdeRegisters[EfiIdePrimary].Head              = (UINT16) (CommandBlockBaseAddr + 0x06);\r
-  IdeRegisters[EfiIdePrimary].CmdOrStatus       = (UINT16) (CommandBlockBaseAddr + 0x07);\r
+  IdeRegisters[EfiIdePrimary].ErrOrFeature      = (UINT16)(CommandBlockBaseAddr + 0x01);\r
+  IdeRegisters[EfiIdePrimary].SectorCount       = (UINT16)(CommandBlockBaseAddr + 0x02);\r
+  IdeRegisters[EfiIdePrimary].SectorNumber      = (UINT16)(CommandBlockBaseAddr + 0x03);\r
+  IdeRegisters[EfiIdePrimary].CylinderLsb       = (UINT16)(CommandBlockBaseAddr + 0x04);\r
+  IdeRegisters[EfiIdePrimary].CylinderMsb       = (UINT16)(CommandBlockBaseAddr + 0x05);\r
+  IdeRegisters[EfiIdePrimary].Head              = (UINT16)(CommandBlockBaseAddr + 0x06);\r
+  IdeRegisters[EfiIdePrimary].CmdOrStatus       = (UINT16)(CommandBlockBaseAddr + 0x07);\r
   IdeRegisters[EfiIdePrimary].AltOrDev          = ControlBlockBaseAddr;\r
   IdeRegisters[EfiIdePrimary].BusMasterBaseAddr = BusMasterBaseAddr;\r
 \r
@@ -939,95 +792,29 @@ GetIdeRegisterIoAddr (
     //\r
     // The BARs should be of IO type\r
     //\r
-    if ((PciData.Device.Bar[2] & BIT0) == 0 ||\r
-        (PciData.Device.Bar[3] & BIT0) == 0) {\r
+    if (((PciData.Device.Bar[2] & BIT0) == 0) ||\r
+        ((PciData.Device.Bar[3] & BIT0) == 0))\r
+    {\r
       return EFI_UNSUPPORTED;\r
     }\r
 \r
-    CommandBlockBaseAddr = (UINT16) (PciData.Device.Bar[2] & 0x0000fff8);\r
-    ControlBlockBaseAddr = (UINT16) ((PciData.Device.Bar[3] & 0x0000fffc) + 2);\r
+    CommandBlockBaseAddr = (UINT16)(PciData.Device.Bar[2] & 0x0000fff8);\r
+    ControlBlockBaseAddr = (UINT16)((PciData.Device.Bar[3] & 0x0000fffc) + 2);\r
   }\r
 \r
   //\r
   // Calculate IDE secondary channel I/O register base address.\r
   //\r
   IdeRegisters[EfiIdeSecondary].Data              = CommandBlockBaseAddr;\r
-  IdeRegisters[EfiIdeSecondary].ErrOrFeature      = (UINT16) (CommandBlockBaseAddr + 0x01);\r
-  IdeRegisters[EfiIdeSecondary].SectorCount       = (UINT16) (CommandBlockBaseAddr + 0x02);\r
-  IdeRegisters[EfiIdeSecondary].SectorNumber      = (UINT16) (CommandBlockBaseAddr + 0x03);\r
-  IdeRegisters[EfiIdeSecondary].CylinderLsb       = (UINT16) (CommandBlockBaseAddr + 0x04);\r
-  IdeRegisters[EfiIdeSecondary].CylinderMsb       = (UINT16) (CommandBlockBaseAddr + 0x05);\r
-  IdeRegisters[EfiIdeSecondary].Head              = (UINT16) (CommandBlockBaseAddr + 0x06);\r
-  IdeRegisters[EfiIdeSecondary].CmdOrStatus       = (UINT16) (CommandBlockBaseAddr + 0x07);\r
+  IdeRegisters[EfiIdeSecondary].ErrOrFeature      = (UINT16)(CommandBlockBaseAddr + 0x01);\r
+  IdeRegisters[EfiIdeSecondary].SectorCount       = (UINT16)(CommandBlockBaseAddr + 0x02);\r
+  IdeRegisters[EfiIdeSecondary].SectorNumber      = (UINT16)(CommandBlockBaseAddr + 0x03);\r
+  IdeRegisters[EfiIdeSecondary].CylinderLsb       = (UINT16)(CommandBlockBaseAddr + 0x04);\r
+  IdeRegisters[EfiIdeSecondary].CylinderMsb       = (UINT16)(CommandBlockBaseAddr + 0x05);\r
+  IdeRegisters[EfiIdeSecondary].Head              = (UINT16)(CommandBlockBaseAddr + 0x06);\r
+  IdeRegisters[EfiIdeSecondary].CmdOrStatus       = (UINT16)(CommandBlockBaseAddr + 0x07);\r
   IdeRegisters[EfiIdeSecondary].AltOrDev          = ControlBlockBaseAddr;\r
-  IdeRegisters[EfiIdeSecondary].BusMasterBaseAddr = (UINT16) (BusMasterBaseAddr + 0x8);\r
-\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
-  This function is used to implement the Soft Reset on the specified device. But,\r
-  the ATA Soft Reset mechanism is so strong a reset method that it will force \r
-  resetting on both devices connected to the same cable.\r
-\r
-  It is called by IdeBlkIoReset(), a interface function of Block\r
-  I/O protocol.\r
-\r
-  This function can also be used by the ATAPI device to perform reset when\r
-  ATAPI Reset command is failed.\r
-\r
-  @param PciIo            A pointer to ATA_ATAPI_PASS_THRU_INSTANCE data structure.\r
-  @param IdeRegisters     A pointer to EFI_IDE_REGISTERS data structure.\r
-  @param Timeout          The time to complete the command.\r
-\r
-  @retval EFI_SUCCESS       Soft reset completes successfully.\r
-  @retval EFI_DEVICE_ERROR  Any step during the reset process is failed.\r
-\r
-  @note  The registers initial values after ATA soft reset are different\r
-         to the ATA device and ATAPI device.\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-AtaSoftReset (\r
-  IN  EFI_PCI_IO_PROTOCOL  *PciIo,\r
-  IN  EFI_IDE_REGISTERS    *IdeRegisters,\r
-  IN  UINT64               Timeout\r
-  )\r
-{\r
-  UINT8 DeviceControl;\r
-\r
-  DeviceControl = 0;\r
-  //\r
-  // disable Interrupt and set SRST bit to initiate soft reset\r
-  //\r
-  DeviceControl = ATA_CTLREG_SRST | ATA_CTLREG_IEN_L;\r
-\r
-  IdeWritePortB (PciIo, IdeRegisters->AltOrDev, DeviceControl);\r
-\r
-  //\r
-  // SRST should assert for at least 5 us, we use 10 us for\r
-  // better compatibility\r
-  //\r
-  MicroSecondDelay (10);\r
-\r
-  //\r
-  // Enable interrupt to support UDMA, and clear SRST bit\r
-  //\r
-  DeviceControl = 0;\r
-  IdeWritePortB (PciIo, IdeRegisters->AltOrDev, DeviceControl);\r
-\r
-  //\r
-  // Wait for at least 10 ms to check BSY status, we use 10 ms\r
-  // for better compatibility\r
-  //  \r
-  MicroSecondDelay (10000);\r
-\r
-  //\r
-  // slave device needs at most 31ms to clear BSY\r
-  //\r
-  if (WaitForBSYClear (PciIo, IdeRegisters, Timeout) == EFI_TIMEOUT) {\r
-    return EFI_DEVICE_ERROR;\r
-  }\r
+  IdeRegisters[EfiIdeSecondary].BusMasterBaseAddr = (UINT16)(BusMasterBaseAddr + 0x8);\r
 \r
   return EFI_SUCCESS;\r
 }\r
@@ -1038,7 +825,7 @@ AtaSoftReset (
   @param PciIo            A pointer to ATA_ATAPI_PASS_THRU_INSTANCE data structure.\r
   @param IdeRegisters     A pointer to EFI_IDE_REGISTERS data structure.\r
   @param AtaCommandBlock  A pointer to EFI_ATA_COMMAND_BLOCK data structure.\r
-  @param Timeout          The time to complete the command.\r
+  @param Timeout          The time to complete the command, uses 100ns as a unit.\r
 \r
   @retval  EFI_SUCCESS Reading succeed\r
   @retval  EFI_DEVICE_ERROR Error executing commands on this device.\r
@@ -1047,10 +834,10 @@ AtaSoftReset (
 EFI_STATUS\r
 EFIAPI\r
 AtaIssueCommand (\r
-  IN  EFI_PCI_IO_PROTOCOL       *PciIo,\r
-  IN  EFI_IDE_REGISTERS         *IdeRegisters,\r
-  IN  EFI_ATA_COMMAND_BLOCK     *AtaCommandBlock,\r
-  IN  UINT64                    Timeout\r
+  IN  EFI_PCI_IO_PROTOCOL    *PciIo,\r
+  IN  EFI_IDE_REGISTERS      *IdeRegisters,\r
+  IN  EFI_ATA_COMMAND_BLOCK  *AtaCommandBlock,\r
+  IN  UINT64                 Timeout\r
   )\r
 {\r
   EFI_STATUS  Status;\r
@@ -1072,7 +859,7 @@ AtaIssueCommand (
   //\r
   // Select device (bit4), set LBA mode(bit6) (use 0xe0 for compatibility)\r
   //\r
-  IdeWritePortB (PciIo, IdeRegisters->Head, (UINT8) (0xe0 | DeviceHead));\r
+  IdeWritePortB (PciIo, IdeRegisters->Head, (UINT8)(0xe0 | DeviceHead));\r
 \r
   //\r
   // set all the command parameters\r
@@ -1134,26 +921,26 @@ AtaIssueCommand (
                                    from host to device.\r
   @param[in]      AtaCommandBlock  A pointer to EFI_ATA_COMMAND_BLOCK data structure.\r
   @param[in, out] AtaStatusBlock   A pointer to EFI_ATA_STATUS_BLOCK data structure.\r
-  @param[in]      Timeout          The time to complete the command.\r
+  @param[in]      Timeout          The time to complete the command, uses 100ns as a unit.\r
   @param[in]      Task             Optional. Pointer to the ATA_NONBLOCK_TASK\r
                                    used by non-blocking mode.\r
-  \r
+\r
   @retval EFI_SUCCESS      send out the ATA command and device send required data successfully.\r
   @retval EFI_DEVICE_ERROR command sent failed.\r
 \r
 **/\r
 EFI_STATUS\r
 EFIAPI\r
-AtaPioDataInOut (  \r
-  IN     EFI_PCI_IO_PROTOCOL       *PciIo,\r
-  IN     EFI_IDE_REGISTERS         *IdeRegisters,\r
-  IN OUT VOID                      *Buffer,\r
-  IN     UINT64                    ByteCount,\r
-  IN     BOOLEAN                   Read,\r
-  IN     EFI_ATA_COMMAND_BLOCK     *AtaCommandBlock,\r
-  IN OUT EFI_ATA_STATUS_BLOCK      *AtaStatusBlock,\r
-  IN     UINT64                    Timeout,\r
-  IN     ATA_NONBLOCK_TASK         *Task\r
+AtaPioDataInOut (\r
+  IN     EFI_PCI_IO_PROTOCOL    *PciIo,\r
+  IN     EFI_IDE_REGISTERS      *IdeRegisters,\r
+  IN OUT VOID                   *Buffer,\r
+  IN     UINT64                 ByteCount,\r
+  IN     BOOLEAN                Read,\r
+  IN     EFI_ATA_COMMAND_BLOCK  *AtaCommandBlock,\r
+  IN OUT EFI_ATA_STATUS_BLOCK   *AtaStatusBlock,\r
+  IN     UINT64                 Timeout,\r
+  IN     ATA_NONBLOCK_TASK      *Task\r
   )\r
 {\r
   UINTN       WordCount;\r
@@ -1174,7 +961,7 @@ AtaPioDataInOut (
     goto Exit;\r
   }\r
 \r
-  Buffer16 = (UINT16 *) Buffer;\r
+  Buffer16 = (UINT16 *)Buffer;\r
 \r
   //\r
   // According to PIO data in protocol, host can perform a series of reads to\r
@@ -1194,16 +981,16 @@ AtaPioDataInOut (
   Increment = 256;\r
 \r
   //\r
-  // used to record bytes of currently transfered data\r
+  // used to record bytes of currently transferred data\r
   //\r
   WordCount = 0;\r
 \r
-  while (WordCount < RShiftU64(ByteCount, 1)) {\r
+  while (WordCount < RShiftU64 (ByteCount, 1)) {\r
     //\r
     // Poll DRQ bit set, data transfer can be performed only when DRQ is ready\r
     //\r
     Status = DRQReady2 (PciIo, IdeRegisters, Timeout);\r
-    if (EFI_ERROR (Status)) {      \r
+    if (EFI_ERROR (Status)) {\r
       Status = EFI_DEVICE_ERROR;\r
       goto Exit;\r
     }\r
@@ -1211,8 +998,8 @@ AtaPioDataInOut (
     //\r
     // Get the byte count for one series of read\r
     //\r
-    if ((WordCount + Increment) > RShiftU64(ByteCount, 1)) {\r
-      Increment = (UINTN)(RShiftU64(ByteCount, 1) - WordCount);\r
+    if ((WordCount + Increment) > RShiftU64 (ByteCount, 1)) {\r
+      Increment = (UINTN)(RShiftU64 (ByteCount, 1) - WordCount);\r
     }\r
 \r
     if (Read) {\r
@@ -1268,7 +1055,7 @@ Exit:
   @param[in]      AtaCommandBlock  A pointer to EFI_ATA_COMMAND_BLOCK data\r
                                    structure.\r
   @param[in, out] AtaStatusBlock   A pointer to EFI_ATA_STATUS_BLOCK data structure.\r
-  @param[in]      Timeout          The time to complete the command.\r
+  @param[in]      Timeout          The time to complete the command, uses 100ns as a unit.\r
   @param[in]      Task             Optional. Pointer to the ATA_NONBLOCK_TASK\r
                                    used by non-blocking mode.\r
 \r
@@ -1279,13 +1066,13 @@ Exit:
 **/\r
 EFI_STATUS\r
 EFIAPI\r
-AtaNonDataCommandIn (  \r
-  IN     EFI_PCI_IO_PROTOCOL       *PciIo,\r
-  IN     EFI_IDE_REGISTERS         *IdeRegisters,\r
-  IN     EFI_ATA_COMMAND_BLOCK     *AtaCommandBlock,\r
-  IN OUT EFI_ATA_STATUS_BLOCK      *AtaStatusBlock,\r
-  IN     UINT64                    Timeout,\r
-  IN     ATA_NONBLOCK_TASK         *Task\r
+AtaNonDataCommandIn (\r
+  IN     EFI_PCI_IO_PROTOCOL    *PciIo,\r
+  IN     EFI_IDE_REGISTERS      *IdeRegisters,\r
+  IN     EFI_ATA_COMMAND_BLOCK  *AtaCommandBlock,\r
+  IN OUT EFI_ATA_STATUS_BLOCK   *AtaStatusBlock,\r
+  IN     UINT64                 Timeout,\r
+  IN     ATA_NONBLOCK_TASK      *Task\r
   )\r
 {\r
   EFI_STATUS  Status;\r
@@ -1311,7 +1098,7 @@ AtaNonDataCommandIn (
     Status = EFI_DEVICE_ERROR;\r
     goto Exit;\r
   }\r
-  \r
+\r
   Status = CheckStatusRegister (PciIo, IdeRegisters);\r
   if (EFI_ERROR (Status)) {\r
     Status = EFI_DEVICE_ERROR;\r
@@ -1323,7 +1110,7 @@ Exit:
   // Dump All Ide registers to ATA_STATUS_BLOCK\r
   //\r
   DumpAllIdeRegisters (PciIo, IdeRegisters, AtaStatusBlock);\r
-  \r
+\r
   //\r
   // Not support the Non-blocking now,just do the blocking process.\r
   //\r
@@ -1332,9 +1119,10 @@ Exit:
 \r
 /**\r
   Wait for memory to be set.\r
-    \r
+\r
   @param[in]  PciIo           The PCI IO protocol instance.\r
-  @param[in]  PortNum         The IDE Port number.\r
+  @param[in]  IdeRegisters    A pointer to EFI_IDE_REGISTERS data structure.\r
+  @param[in]  Timeout         The time to complete the command, uses 100ns as a unit.\r
 \r
   @retval EFI_DEVICE_ERROR  The memory is not set.\r
   @retval EFI_TIMEOUT       The memory setting is time out.\r
@@ -1343,47 +1131,62 @@ Exit:
 **/\r
 EFI_STATUS\r
 AtaUdmStatusWait (\r
-  IN     EFI_PCI_IO_PROTOCOL       *PciIo,\r
-  IN     UINT16                    PortNum\r
- ) \r
+  IN  EFI_PCI_IO_PROTOCOL  *PciIo,\r
+  IN  EFI_IDE_REGISTERS    *IdeRegisters,\r
+  IN  UINT64               Timeout\r
+  )\r
 {\r
-  UINT8                         RegisterValue;\r
-  EFI_STATUS                    Status;\r
-  UINT64                        Timeout;\r
+  UINT8       RegisterValue;\r
+  EFI_STATUS  Status;\r
+  UINT16      IoPortForBmis;\r
+  UINT64      Delay;\r
+  BOOLEAN     InfiniteWait;\r
 \r
-  Timeout = 2000;\r
+  if (Timeout == 0) {\r
+    InfiniteWait = TRUE;\r
+  } else {\r
+    InfiniteWait = FALSE;\r
+  }\r
+\r
+  Delay = DivU64x32 (Timeout, 1000) + 1;\r
 \r
-  while (TRUE) {\r
-    RegisterValue  = IdeReadPortB (PciIo, PortNum);\r
+  do {\r
+    Status = CheckStatusRegister (PciIo, IdeRegisters);\r
+    if (EFI_ERROR (Status)) {\r
+      Status = EFI_DEVICE_ERROR;\r
+      break;\r
+    }\r
 \r
+    IoPortForBmis = (UINT16)(IdeRegisters->BusMasterBaseAddr + BMIS_OFFSET);\r
+    RegisterValue = IdeReadPortB (PciIo, IoPortForBmis);\r
     if (((RegisterValue & BMIS_ERROR) != 0) || (Timeout == 0)) {\r
-      DEBUG ((EFI_D_ERROR, "ATA UDMA operation fails\n"));\r
+      DEBUG ((DEBUG_ERROR, "ATA UDMA operation fails\n"));\r
       Status = EFI_DEVICE_ERROR;\r
       break;\r
     }\r
 \r
     if ((RegisterValue & BMIS_INTERRUPT) != 0) {\r
       Status = EFI_SUCCESS;\r
-      DEBUG ((DEBUG_INFO, "Task->RetryTimes = %x\n", Timeout));      \r
       break;\r
     }\r
+\r
     //\r
-    // Stall for 1 milliseconds.\r
+    // Stall for 100 microseconds.\r
     //\r
-    MicroSecondDelay (1000);\r
-    Timeout--;\r
-  }\r
+    MicroSecondDelay (100);\r
+    Delay--;\r
+  } while (InfiniteWait || (Delay > 0));\r
 \r
   return Status;\r
 }\r
 \r
 /**\r
   Check if the memory to be set.\r
-    \r
+\r
   @param[in]  PciIo           The PCI IO protocol instance.\r
   @param[in]  Task            Optional. Pointer to the ATA_NONBLOCK_TASK\r
                               used by non-blocking mode.\r
-  @param[in]  PortForBit      The bit to be checked.\r
+  @param[in]  IdeRegisters    A pointer to EFI_IDE_REGISTERS data structure.\r
 \r
   @retval EFI_DEVICE_ERROR  The memory setting met a issue.\r
   @retval EFI_NOT_READY     The memory is not set.\r
@@ -1393,27 +1196,35 @@ AtaUdmStatusWait (
 **/\r
 EFI_STATUS\r
 AtaUdmStatusCheck (\r
-  IN     EFI_PCI_IO_PROTOCOL        *PciIo,\r
-  IN     ATA_NONBLOCK_TASK          *Task,\r
-  IN     UINT16                     PortForBit\r
- )\r
+  IN     EFI_PCI_IO_PROTOCOL  *PciIo,\r
+  IN     ATA_NONBLOCK_TASK    *Task,\r
+  IN     EFI_IDE_REGISTERS    *IdeRegisters\r
 )\r
 {\r
-  UINT8                         RegisterValue;\r
+  UINT8       RegisterValue;\r
+  UINT16      IoPortForBmis;\r
+  EFI_STATUS  Status;\r
 \r
   Task->RetryTimes--;\r
-  RegisterValue  = IdeReadPortB(PciIo, PortForBit);\r
+\r
+  Status = CheckStatusRegister (PciIo, IdeRegisters);\r
+  if (EFI_ERROR (Status)) {\r
+    return EFI_DEVICE_ERROR;\r
+  }\r
+\r
+  IoPortForBmis = (UINT16)(IdeRegisters->BusMasterBaseAddr + BMIS_OFFSET);\r
+  RegisterValue = IdeReadPortB (PciIo, IoPortForBmis);\r
 \r
   if ((RegisterValue & BMIS_ERROR) != 0) {\r
-    DEBUG ((EFI_D_ERROR, "ATA UDMA operation fails\n"));\r
+    DEBUG ((DEBUG_ERROR, "ATA UDMA operation fails\n"));\r
     return EFI_DEVICE_ERROR;\r
   }\r
 \r
   if ((RegisterValue & BMIS_INTERRUPT) != 0) {\r
-    DEBUG ((DEBUG_INFO, "Task->RetryTimes = %x\n", Task->RetryTimes));\r
     return EFI_SUCCESS;\r
   }\r
 \r
-  if (Task->RetryTimes == 0) {\r
+  if (!Task->InfiniteWait && (Task->RetryTimes == 0)) {\r
     return EFI_TIMEOUT;\r
   } else {\r
     //\r
@@ -1437,7 +1248,7 @@ AtaUdmStatusCheck (
   @param[in]      DataLength       The length of  the data.\r
   @param[in]      AtaCommandBlock  A pointer to EFI_ATA_COMMAND_BLOCK data structure.\r
   @param[in, out] AtaStatusBlock   A pointer to EFI_ATA_STATUS_BLOCK data structure.\r
-  @param[in]      Timeout          The time to complete the command.\r
+  @param[in]      Timeout          The time to complete the command, uses 100ns as a unit.\r
   @param[in]      Task             Optional. Pointer to the ATA_NONBLOCK_TASK\r
                                    used by non-blocking mode.\r
 \r
@@ -1461,38 +1272,43 @@ AtaUdmaInOut (
   IN     ATA_NONBLOCK_TASK             *Task\r
   )\r
 {\r
-  EFI_STATUS                    Status;\r
-  UINT16                        IoPortForBmic;\r
-  UINT16                        IoPortForBmis;\r
-  UINT16                        IoPortForBmid;\r
-\r
-  UINTN                         PrdTableSize;\r
-  EFI_PHYSICAL_ADDRESS          PrdTableMapAddr;\r
-  VOID                          *PrdTableMap;\r
-  EFI_ATA_DMA_PRD               *PrdBaseAddr;\r
-  UINTN                         PrdTableNum;\r
-\r
-  UINT8                         RegisterValue;\r
-  UINTN                         PageCount;\r
-  UINTN                         ByteCount;\r
-  UINTN                         ByteRemaining;\r
-  UINT8                         DeviceControl;\r
-\r
-  VOID                          *BufferMap;\r
-  EFI_PHYSICAL_ADDRESS          BufferMapAddress;\r
-  EFI_PCI_IO_PROTOCOL_OPERATION PciIoOperation;\r
-\r
-  UINT8                         DeviceHead;\r
-  UINT8                         AtaCommand;\r
-  EFI_PCI_IO_PROTOCOL           *PciIo;\r
-  EFI_TPL                       OldTpl;\r
-\r
+  EFI_STATUS  Status;\r
+  UINT16      IoPortForBmic;\r
+  UINT16      IoPortForBmis;\r
+  UINT16      IoPortForBmid;\r
+\r
+  UINTN                 PrdTableSize;\r
+  EFI_PHYSICAL_ADDRESS  PrdTableMapAddr;\r
+  VOID                  *PrdTableMap;\r
+  EFI_PHYSICAL_ADDRESS  PrdTableBaseAddr;\r
+  EFI_ATA_DMA_PRD       *TempPrdBaseAddr;\r
+  UINTN                 PrdTableNum;\r
+\r
+  UINT8  RegisterValue;\r
+  UINTN  PageCount;\r
+  UINTN  ByteCount;\r
+  UINTN  ByteRemaining;\r
+  UINT8  DeviceControl;\r
+\r
+  VOID                           *BufferMap;\r
+  EFI_PHYSICAL_ADDRESS           BufferMapAddress;\r
+  EFI_PCI_IO_PROTOCOL_OPERATION  PciIoOperation;\r
+\r
+  UINT8                DeviceHead;\r
+  EFI_PCI_IO_PROTOCOL  *PciIo;\r
+  EFI_TPL              OldTpl;\r
+\r
+  UINTN                 AlignmentMask;\r
+  UINTN                 RealPageCount;\r
+  EFI_PHYSICAL_ADDRESS  BaseAddr;\r
+  EFI_PHYSICAL_ADDRESS  BaseMapAddr;\r
 \r
   Status        = EFI_SUCCESS;\r
-  PrdBaseAddr   = NULL;\r
   PrdTableMap   = NULL;\r
   BufferMap     = NULL;\r
   PageCount     = 0;\r
+  RealPageCount = 0;\r
+  BaseAddr      = 0;\r
   PciIo         = Instance->PciIo;\r
 \r
   if ((PciIo == NULL) || (IdeRegisters == NULL) || (DataBuffer == NULL) || (AtaCommandBlock == NULL)) {\r
@@ -1504,15 +1320,16 @@ AtaUdmaInOut (
   // BlockIO tasks.\r
   // Delay 1ms to simulate the blocking time out checking.\r
   //\r
+  OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
   while ((Task == NULL) && (!IsListEmpty (&Instance->NonBlockingTaskList))) {\r
-    OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
     AsyncNonBlockingTransferRoutine (NULL, Instance);\r
-    gBS->RestoreTPL (OldTpl);\r
     //\r
     // Stall for 1 milliseconds.\r
     //\r
     MicroSecondDelay (1000);\r
-  } \r
+  }\r
+\r
+  gBS->RestoreTPL (OldTpl);\r
 \r
   //\r
   // The data buffer should be even alignment\r
@@ -1524,21 +1341,21 @@ AtaUdmaInOut (
   //\r
   // Set relevant IO Port address.\r
   //\r
-  IoPortForBmic = (UINT16) (IdeRegisters->BusMasterBaseAddr + BMIC_OFFSET);\r
-  IoPortForBmis = (UINT16) (IdeRegisters->BusMasterBaseAddr + BMIS_OFFSET);\r
-  IoPortForBmid = (UINT16) (IdeRegisters->BusMasterBaseAddr + BMID_OFFSET);\r
+  IoPortForBmic = (UINT16)(IdeRegisters->BusMasterBaseAddr + BMIC_OFFSET);\r
+  IoPortForBmis = (UINT16)(IdeRegisters->BusMasterBaseAddr + BMIS_OFFSET);\r
+  IoPortForBmid = (UINT16)(IdeRegisters->BusMasterBaseAddr + BMID_OFFSET);\r
 \r
   //\r
-  // For Blocking mode, start the command. \r
+  // For Blocking mode, start the command.\r
   // For non-blocking mode, when the command is not started, start it, otherwise\r
   // go to check the status.\r
-  //  \r
+  //\r
   if (((Task != NULL) && (!Task->IsStart)) || (Task == NULL)) {\r
     //\r
     // Calculate the number of PRD entry.\r
     // Every entry in PRD table can specify a 64K memory region.\r
     //\r
-    PrdTableNum   = (UINTN)(RShiftU64(DataLength, 16) + 1);\r
+    PrdTableNum = (UINTN)(RShiftU64 (DataLength, 16) + 1);\r
 \r
     //\r
     // Make sure that the memory region of PRD table is not cross 64K boundary\r
@@ -1550,40 +1367,56 @@ AtaUdmaInOut (
 \r
     //\r
     // Allocate buffer for PRD table initialization.\r
+    // Note Ide Bus Master spec said the descriptor table must be aligned on a 4 byte\r
+    // boundary and the table cannot cross a 64K boundary in memory.\r
     //\r
-    PageCount = EFI_SIZE_TO_PAGES (PrdTableSize);\r
-    Status    = PciIo->AllocateBuffer (\r
-                         PciIo,\r
-                         AllocateAnyPages,\r
-                         EfiBootServicesData,\r
-                         PageCount,\r
-                         (VOID **)&PrdBaseAddr,\r
-                         0\r
-                         );\r
+    PageCount     = EFI_SIZE_TO_PAGES (PrdTableSize);\r
+    RealPageCount = PageCount + EFI_SIZE_TO_PAGES (SIZE_64KB);\r
+\r
+    //\r
+    // Make sure that PageCount plus EFI_SIZE_TO_PAGES (SIZE_64KB) does not overflow.\r
+    //\r
+    ASSERT (RealPageCount > PageCount);\r
+\r
+    Status = PciIo->AllocateBuffer (\r
+                      PciIo,\r
+                      AllocateAnyPages,\r
+                      EfiBootServicesData,\r
+                      RealPageCount,\r
+                      (VOID **)&BaseAddr,\r
+                      0\r
+                      );\r
     if (EFI_ERROR (Status)) {\r
       return EFI_OUT_OF_RESOURCES;\r
     }\r
 \r
-    ByteCount = EFI_PAGES_TO_SIZE (PageCount);\r
+    ByteCount = EFI_PAGES_TO_SIZE (RealPageCount);\r
     Status    = PciIo->Map (\r
                          PciIo,\r
                          EfiPciIoOperationBusMasterCommonBuffer,\r
-                         PrdBaseAddr,\r
+                         (VOID *)(UINTN)BaseAddr,\r
                          &ByteCount,\r
-                         &PrdTableMapAddr,\r
+                         &BaseMapAddr,\r
                          &PrdTableMap\r
                          );\r
-    if (EFI_ERROR (Status) || (ByteCount != EFI_PAGES_TO_SIZE (PageCount))) {\r
+    if (EFI_ERROR (Status) || (ByteCount != EFI_PAGES_TO_SIZE (RealPageCount))) {\r
       //\r
       // If the data length actually mapped is not equal to the requested amount,\r
       // it means the DMA operation may be broken into several discontinuous smaller chunks.\r
       // Can't handle this case.\r
       //\r
-      PciIo->FreeBuffer (PciIo, PageCount, PrdBaseAddr);\r
+      PciIo->FreeBuffer (PciIo, RealPageCount, (VOID *)(UINTN)BaseAddr);\r
       return EFI_OUT_OF_RESOURCES;\r
     }\r
 \r
-    ZeroMem ((VOID *) ((UINTN) PrdBaseAddr), ByteCount);\r
+    ZeroMem ((VOID *)((UINTN)BaseAddr), ByteCount);\r
+\r
+    //\r
+    // Calculate the 64K align address as PRD Table base address.\r
+    //\r
+    AlignmentMask    = SIZE_64KB - 1;\r
+    PrdTableBaseAddr = ((UINTN)BaseAddr + AlignmentMask) & ~AlignmentMask;\r
+    PrdTableMapAddr  = ((UINTN)BaseMapAddr + AlignmentMask) & ~AlignmentMask;\r
 \r
     //\r
     // Map the host address of DataBuffer to DMA master address.\r
@@ -1605,7 +1438,7 @@ AtaUdmaInOut (
                          );\r
     if (EFI_ERROR (Status) || (ByteCount != DataLength)) {\r
       PciIo->Unmap (PciIo, PrdTableMap);\r
-      PciIo->FreeBuffer (PciIo, PageCount, PrdBaseAddr);\r
+      PciIo->FreeBuffer (PciIo, RealPageCount, (VOID *)(UINTN)BaseAddr);\r
       return EFI_OUT_OF_RESOURCES;\r
     }\r
 \r
@@ -1618,28 +1451,28 @@ AtaUdmaInOut (
     //\r
     // Fill the PRD table with appropriate bus master address of data buffer and data length.\r
     //\r
-    ByteRemaining = ByteCount;\r
+    ByteRemaining   = ByteCount;\r
+    TempPrdBaseAddr = (EFI_ATA_DMA_PRD *)(UINTN)PrdTableBaseAddr;\r
     while (ByteRemaining != 0) {\r
       if (ByteRemaining <= 0x10000) {\r
-        PrdBaseAddr->RegionBaseAddr = (UINT32) ((UINTN) BufferMapAddress);\r
-        PrdBaseAddr->ByteCount      = (UINT16) ByteRemaining;\r
-        PrdBaseAddr->EndOfTable     = 0x8000;\r
+        TempPrdBaseAddr->RegionBaseAddr = (UINT32)((UINTN)BufferMapAddress);\r
+        TempPrdBaseAddr->ByteCount      = (UINT16)ByteRemaining;\r
+        TempPrdBaseAddr->EndOfTable     = 0x8000;\r
         break;\r
       }\r
 \r
-      PrdBaseAddr->RegionBaseAddr = (UINT32) ((UINTN) BufferMapAddress);\r
-      PrdBaseAddr->ByteCount      = (UINT16) 0x0;\r
+      TempPrdBaseAddr->RegionBaseAddr = (UINT32)((UINTN)BufferMapAddress);\r
+      TempPrdBaseAddr->ByteCount      = (UINT16)0x0;\r
 \r
       ByteRemaining    -= 0x10000;\r
       BufferMapAddress += 0x10000;\r
-      PrdBaseAddr++;\r
+      TempPrdBaseAddr++;\r
     }\r
 \r
     //\r
     // Start to enable the DMA operation\r
     //\r
     DeviceHead = AtaCommandBlock->AtaDeviceHead;\r
-    AtaCommand = AtaCommandBlock->AtaCommand;\r
 \r
     IdeWritePortB (PciIo, IdeRegisters->Head, (UINT8)(0xe0 | DeviceHead));\r
 \r
@@ -1652,9 +1485,9 @@ AtaUdmaInOut (
     //\r
     // Read BMIS register and clear ERROR and INTR bit\r
     //\r
-    RegisterValue  = IdeReadPortB(PciIo, IoPortForBmis);\r
+    RegisterValue  = IdeReadPortB (PciIo, IoPortForBmis);\r
     RegisterValue |= (BMIS_INTERRUPT | BMIS_ERROR);\r
-    IdeWritePortB(PciIo, IoPortForBmis, RegisterValue);\r
+    IdeWritePortB (PciIo, IoPortForBmis, RegisterValue);\r
 \r
     //\r
     // Set the base address to BMID register\r
@@ -1664,14 +1497,23 @@ AtaUdmaInOut (
     //\r
     // Set BMIC register to identify the operation direction\r
     //\r
-    RegisterValue = IdeReadPortB(PciIo, IoPortForBmic);\r
+    RegisterValue = IdeReadPortB (PciIo, IoPortForBmic);\r
     if (Read) {\r
       RegisterValue |= BMIC_NREAD;\r
     } else {\r
-      RegisterValue &= ~((UINT8) BMIC_NREAD);\r
+      RegisterValue &= ~((UINT8)BMIC_NREAD);\r
     }\r
+\r
     IdeWritePortB (PciIo, IoPortForBmic, RegisterValue);\r
 \r
+    if (Task != NULL) {\r
+      Task->Map            = BufferMap;\r
+      Task->TableMap       = PrdTableMap;\r
+      Task->MapBaseAddress = (EFI_ATA_DMA_PRD *)(UINTN)BaseAddr;\r
+      Task->PageCount      = RealPageCount;\r
+      Task->IsStart        = TRUE;\r
+    }\r
+\r
     //\r
     // Issue ATA command\r
     //\r
@@ -1682,38 +1524,27 @@ AtaUdmaInOut (
       goto Exit;\r
     }\r
 \r
+    Status = CheckStatusRegister (PciIo, IdeRegisters);\r
+    if (EFI_ERROR (Status)) {\r
+      Status = EFI_DEVICE_ERROR;\r
+      goto Exit;\r
+    }\r
+\r
     //\r
     // Set START bit of BMIC register\r
     //\r
-    RegisterValue  = IdeReadPortB(PciIo, IoPortForBmic);\r
+    RegisterValue  = IdeReadPortB (PciIo, IoPortForBmic);\r
     RegisterValue |= BMIC_START;\r
-    IdeWritePortB(PciIo, IoPortForBmic, RegisterValue);\r
-\r
-    if (Task != NULL) {\r
-      //\r
-      // Max transfer number of sectors for one command is 65536(32Mbyte),\r
-      // it will cost 1 second to transfer these data in UDMA mode 2(33.3MBps).\r
-      // So set the variable Count to 2000, for about 2 second Timeout time.\r
-      //\r
-      Task->RetryTimes     = 2000;\r
-      Task->Map            = BufferMap;\r
-      Task->TableMap       = PrdTableMap;\r
-      Task->MapBaseAddress = PrdBaseAddr;\r
-      Task->PageCount      = PageCount;\r
-      Task->IsStart        = TRUE;\r
-    }\r
+    IdeWritePortB (PciIo, IoPortForBmic, RegisterValue);\r
   }\r
 \r
   //\r
   // Check the INTERRUPT and ERROR bit of BMIS\r
-  // Max transfer number of sectors for one command is 65536(32Mbyte),\r
-  // it will cost 1 second to transfer these data in UDMA mode 2(33.3MBps).\r
-  // So set the variable Count to 2000, for about 2 second Timeout time.\r
   //\r
   if (Task != NULL) {\r
-    Status = AtaUdmStatusCheck (PciIo, Task, IoPortForBmis);\r
+    Status = AtaUdmStatusCheck (PciIo, Task, IdeRegisters);\r
   } else {\r
-    Status = AtaUdmStatusWait (PciIo, IoPortForBmis);\r
+    Status = AtaUdmStatusWait (PciIo, IdeRegisters, Timeout);\r
   }\r
 \r
   //\r
@@ -1722,7 +1553,7 @@ AtaUdmaInOut (
   // out, or a error has been happened, it needs to clear the register and free\r
   // buffer.\r
   //\r
-  if ((Task == NULL) || Status != EFI_NOT_READY) {\r
+  if ((Task == NULL) || (Status != EFI_NOT_READY)) {\r
     //\r
     // Read BMIS register and clear ERROR and INTR bit\r
     //\r
@@ -1733,13 +1564,13 @@ AtaUdmaInOut (
     //\r
     // Read Status Register of IDE device to clear interrupt\r
     //\r
-    RegisterValue  = IdeReadPortB(PciIo, IdeRegisters->CmdOrStatus);\r
+    RegisterValue = IdeReadPortB (PciIo, IdeRegisters->CmdOrStatus);\r
 \r
     //\r
     // Clear START bit of BMIC register\r
     //\r
-    RegisterValue  = IdeReadPortB(PciIo, IoPortForBmic);\r
-    RegisterValue &= ~((UINT8) BMIC_START);\r
+    RegisterValue  = IdeReadPortB (PciIo, IoPortForBmic);\r
+    RegisterValue &= ~((UINT8)BMIC_START);\r
     IdeWritePortB (PciIo, IoPortForBmic, RegisterValue);\r
 \r
     //\r
@@ -1752,21 +1583,20 @@ AtaUdmaInOut (
     // Stall for 10 milliseconds.\r
     //\r
     MicroSecondDelay (10000);\r
-\r
   }\r
 \r
 Exit:\r
   //\r
   // Free all allocated resource\r
   //\r
-  if ((Task == NULL) || Status != EFI_NOT_READY) {\r
+  if ((Task == NULL) || (Status != EFI_NOT_READY)) {\r
     if (Task != NULL) {\r
       PciIo->Unmap (PciIo, Task->TableMap);\r
       PciIo->FreeBuffer (PciIo, Task->PageCount, Task->MapBaseAddress);\r
       PciIo->Unmap (PciIo, Task->Map);\r
     } else {\r
       PciIo->Unmap (PciIo, PrdTableMap);\r
-      PciIo->FreeBuffer (PciIo, PageCount, PrdBaseAddr);\r
+      PciIo->FreeBuffer (PciIo, RealPageCount, (VOID *)(UINTN)BaseAddr);\r
       PciIo->Unmap (PciIo, BufferMap);\r
     }\r
 \r
@@ -1775,7 +1605,7 @@ Exit:
     //\r
     DumpAllIdeRegisters (PciIo, IdeRegisters, AtaStatusBlock);\r
   }\r
-  \r
+\r
   return Status;\r
 }\r
 \r
@@ -1792,12 +1622,12 @@ Exit:
 EFI_STATUS\r
 EFIAPI\r
 AtaPacketReadPendingData (\r
-  IN  EFI_PCI_IO_PROTOCOL       *PciIo,\r
-  IN  EFI_IDE_REGISTERS         *IdeRegisters\r
+  IN  EFI_PCI_IO_PROTOCOL  *PciIo,\r
+  IN  EFI_IDE_REGISTERS    *IdeRegisters\r
   )\r
 {\r
-  UINT8     AltRegister;\r
-  UINT16    TempWordBuffer;\r
+  UINT8   AltRegister;\r
+  UINT16  TempWordBuffer;\r
 \r
   AltRegister = IdeReadPortB (PciIo, IdeRegisters->AltOrDev);\r
   if ((AltRegister & ATA_STSREG_BSY) == ATA_STSREG_BSY) {\r
@@ -1809,18 +1639,19 @@ AtaPacketReadPendingData (
     while ((TempWordBuffer & (ATA_STSREG_BSY | ATA_STSREG_DRQ)) == ATA_STSREG_DRQ) {\r
       IdeReadPortWMultiple (\r
         PciIo,\r
-        IdeRegisters->Data, \r
-        1, \r
+        IdeRegisters->Data,\r
+        1,\r
         &TempWordBuffer\r
         );\r
       TempWordBuffer = IdeReadPortB (PciIo, IdeRegisters->AltOrDev);\r
     }\r
   }\r
+\r
   return EFI_SUCCESS;\r
 }\r
 \r
 /**\r
-  This function is called by AtaPacketCommandExecute(). \r
+  This function is called by AtaPacketCommandExecute().\r
   It is used to transfer data between host and device. The data direction is specified\r
   by the fourth parameter.\r
 \r
@@ -1831,7 +1662,8 @@ AtaPacketReadPendingData (
   @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
+  @param Timeout       Timeout value for wait DRQ ready before each data stream's transfer\r
+                       , uses 100ns as a unit.\r
 \r
   @retval EFI_SUCCESS      data is transferred successfully.\r
   @retval EFI_DEVICE_ERROR the device failed to transfer data.\r
@@ -1839,12 +1671,12 @@ AtaPacketReadPendingData (
 EFI_STATUS\r
 EFIAPI\r
 AtaPacketReadWrite (\r
-  IN     EFI_PCI_IO_PROTOCOL       *PciIo,\r
-  IN     EFI_IDE_REGISTERS         *IdeRegisters,\r
-  IN OUT VOID                      *Buffer,\r
-  IN     UINT64                    ByteCount,\r
-  IN     BOOLEAN                   Read,\r
-  IN     UINT64                    Timeout\r
+  IN     EFI_PCI_IO_PROTOCOL  *PciIo,\r
+  IN     EFI_IDE_REGISTERS    *IdeRegisters,\r
+  IN OUT VOID                 *Buffer,\r
+  IN OUT UINT32               *ByteCount,\r
+  IN     BOOLEAN              Read,\r
+  IN     UINT64               Timeout\r
   )\r
 {\r
   UINT32      RequiredWordCount;\r
@@ -1853,17 +1685,18 @@ AtaPacketReadWrite (
   EFI_STATUS  Status;\r
   UINT16      *PtrBuffer;\r
 \r
+  PtrBuffer         = Buffer;\r
+  RequiredWordCount = *ByteCount >> 1;\r
+\r
   //\r
-  // No data transfer is premitted.\r
+  // No data transfer is permitted.\r
   //\r
-  if (ByteCount == 0) {\r
+  if (RequiredWordCount == 0) {\r
     return EFI_SUCCESS;\r
   }\r
-  \r
-  PtrBuffer         = Buffer;\r
-  RequiredWordCount = (UINT32)RShiftU64(ByteCount, 1);\r
+\r
   //\r
-  // ActuralWordCount means the word count of data really transferred.\r
+  // ActualWordCount means the word count of data really transferred.\r
   //\r
   ActualWordCount = 0;\r
 \r
@@ -1874,7 +1707,15 @@ AtaPacketReadWrite (
     //\r
     Status = DRQReady2 (PciIo, IdeRegisters, Timeout);\r
     if (EFI_ERROR (Status)) {\r
-      return CheckStatusRegister (PciIo, IdeRegisters);\r
+      if (Status == EFI_NOT_READY) {\r
+        //\r
+        // Device provided less data than we intended to read, or wanted less\r
+        // data than we intended to write, but it may still be successful.\r
+        //\r
+        break;\r
+      } else {\r
+        return Status;\r
+      }\r
     }\r
 \r
     //\r
@@ -1914,7 +1755,7 @@ AtaPacketReadWrite (
     PtrBuffer       += WordCount;\r
     ActualWordCount += WordCount;\r
   }\r
-  \r
+\r
   if (Read) {\r
     //\r
     // In the case where the drive wants to send more data than we need to read,\r
@@ -1935,66 +1776,17 @@ AtaPacketReadWrite (
   //\r
   // After data transfer is completed, normally, DRQ bit should clear.\r
   //\r
-  Status = DRQClear2 (PciIo, IdeRegisters, Timeout);\r
+  Status = DRQClear (PciIo, IdeRegisters, Timeout);\r
   if (EFI_ERROR (Status)) {\r
     return EFI_DEVICE_ERROR;\r
   }\r
-  \r
-  return Status;\r
-}\r
-\r
-/**\r
-  Sumbit ATAPI request sense command.\r
-\r
-  @param[in] PciIo           Pointer to the EFI_PCI_IO_PROTOCOL instance\r
-  @param[in] IdeRegisters    Pointer to EFI_IDE_REGISTERS which is used to\r
-                             store the IDE i/o port registers' base addresses\r
-  @param[in] Channel         The channel number of device.\r
-  @param[in] Device          The device number of device.\r
-  @param[in] SenseData       A pointer to store sense data.\r
-  @param[in] SenseDataLength The sense data length.\r
-  @param[in] Timeout         The timeout value to execute this cmd.\r
-\r
-  @retval EFI_SUCCESS        Send out the ATAPI packet command successfully.\r
-  @retval EFI_DEVICE_ERROR   The device failed to send data.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-AtaPacketRequestSense (\r
-  IN  EFI_PCI_IO_PROTOCOL               *PciIo,\r
-  IN  EFI_IDE_REGISTERS                 *IdeRegisters,\r
-  IN  UINT8                             Channel,\r
-  IN  UINT8                             Device,\r
-  IN  VOID                              *SenseData,\r
-  IN  UINT8                             SenseDataLength,\r
-  IN  UINT64                            Timeout\r
-  )\r
-{\r
-  EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET  Packet;\r
-  UINT8                                       Cdb[12];\r
-  EFI_STATUS                                  Status;\r
-\r
-  ZeroMem (&Packet, sizeof (EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET));\r
-  ZeroMem (Cdb, 12);\r
-\r
-  Cdb[0] = ATA_CMD_REQUEST_SENSE;\r
-  Cdb[4] = SenseDataLength;\r
-\r
-  Packet.Timeout          = Timeout;\r
-  Packet.Cdb              = Cdb;\r
-  Packet.CdbLength        = 12;\r
-  Packet.DataDirection    = EFI_EXT_SCSI_DATA_DIRECTION_READ;\r
-  Packet.InDataBuffer     = SenseData;\r
-  Packet.InTransferLength = SenseDataLength;\r
-\r
-  Status = AtaPacketCommandExecute (PciIo, IdeRegisters, Channel, Device, &Packet);\r
 \r
+  *ByteCount = ActualWordCount << 1;\r
   return Status;\r
 }\r
 \r
 /**\r
-  This function is used to send out ATAPI commands conforms to the Packet Command \r
+  This function is used to send out ATAPI commands conforms to the Packet Command\r
   with PIO Data In Protocol.\r
 \r
   @param[in] PciIo          Pointer to the EFI_PCI_IO_PROTOCOL instance\r
@@ -2012,18 +1804,17 @@ AtaPacketRequestSense (
 EFI_STATUS\r
 EFIAPI\r
 AtaPacketCommandExecute (\r
-  IN  EFI_PCI_IO_PROTOCOL                           *PciIo,\r
-  IN  EFI_IDE_REGISTERS                             *IdeRegisters,\r
-  IN  UINT8                                         Channel,\r
-  IN  UINT8                                         Device,\r
-  IN  EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET    *Packet\r
+  IN  EFI_PCI_IO_PROTOCOL                         *PciIo,\r
+  IN  EFI_IDE_REGISTERS                           *IdeRegisters,\r
+  IN  UINT8                                       Channel,\r
+  IN  UINT8                                       Device,\r
+  IN  EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET  *Packet\r
   )\r
 {\r
-  EFI_STATUS                  PacketCommandStatus;\r
-  EFI_ATA_COMMAND_BLOCK       AtaCommandBlock;\r
-  EFI_STATUS                  Status;\r
-  UINT8                       Count;\r
-  UINT8                       PacketCommand[12];\r
+  EFI_ATA_COMMAND_BLOCK  AtaCommandBlock;\r
+  EFI_STATUS             Status;\r
+  UINT8                  Count;\r
+  UINT8                  PacketCommand[12];\r
 \r
   ZeroMem (&AtaCommandBlock, sizeof (EFI_ATA_COMMAND_BLOCK));\r
 \r
@@ -2046,9 +1837,9 @@ AtaPacketCommandExecute (
   // set the transfersize to ATAPI_MAX_BYTE_COUNT to let the device\r
   // determine how many data should be transferred.\r
   //\r
-  AtaCommandBlock.AtaCylinderLow  = (UINT8) (ATAPI_MAX_BYTE_COUNT & 0x00ff);\r
-  AtaCommandBlock.AtaCylinderHigh = (UINT8) (ATAPI_MAX_BYTE_COUNT >> 8);\r
-  AtaCommandBlock.AtaDeviceHead   = (UINT8) (Device << 0x4);\r
+  AtaCommandBlock.AtaCylinderLow  = (UINT8)(ATAPI_MAX_BYTE_COUNT & 0x00ff);\r
+  AtaCommandBlock.AtaCylinderHigh = (UINT8)(ATAPI_MAX_BYTE_COUNT >> 8);\r
+  AtaCommandBlock.AtaDeviceHead   = (UINT8)(Device << 0x4);\r
   AtaCommandBlock.AtaCommand      = ATA_CMD_PACKET;\r
 \r
   IdeWritePortB (PciIo, IdeRegisters->Head, (UINT8)(0xe0 | (Device << 0x4)));\r
@@ -2074,7 +1865,7 @@ AtaPacketCommandExecute (
   // Send out ATAPI command packet\r
   //\r
   for (Count = 0; Count < 6; Count++) {\r
-    IdeWritePortW (PciIo, IdeRegisters->Data, *((UINT16*)PacketCommand + Count)); \r
+    IdeWritePortW (PciIo, IdeRegisters->Data, *((UINT16 *)PacketCommand + Count));\r
     //\r
     // Stall for 10 microseconds.\r
     //\r
@@ -2085,59 +1876,28 @@ AtaPacketCommandExecute (
   // Read/Write the data of ATAPI Command\r
   //\r
   if (Packet->DataDirection == EFI_EXT_SCSI_DATA_DIRECTION_READ) {\r
-    PacketCommandStatus = AtaPacketReadWrite (\r
-                            PciIo,\r
-                            IdeRegisters,\r
-                            Packet->InDataBuffer,\r
-                            Packet->InTransferLength,\r
-                            TRUE,\r
-                            Packet->Timeout\r
-                            );\r
+    Status = AtaPacketReadWrite (\r
+               PciIo,\r
+               IdeRegisters,\r
+               Packet->InDataBuffer,\r
+               &Packet->InTransferLength,\r
+               TRUE,\r
+               Packet->Timeout\r
+               );\r
   } else {\r
-    PacketCommandStatus = AtaPacketReadWrite (\r
-                            PciIo,\r
-                            IdeRegisters,\r
-                            Packet->OutDataBuffer,\r
-                            Packet->OutTransferLength,\r
-                            FALSE,\r
-                            Packet->Timeout\r
-                            );\r
+    Status = AtaPacketReadWrite (\r
+               PciIo,\r
+               IdeRegisters,\r
+               Packet->OutDataBuffer,\r
+               &Packet->OutTransferLength,\r
+               FALSE,\r
+               Packet->Timeout\r
+               );\r
   }\r
 \r
-  if (!EFI_ERROR (PacketCommandStatus)) {\r
-    return PacketCommandStatus;\r
-  }\r
-\r
-  //\r
-  // Return SenseData if PacketCommandStatus matches\r
-  // the following return codes.\r
-  //\r
-  if ((PacketCommandStatus == EFI_BAD_BUFFER_SIZE) ||\r
-      (PacketCommandStatus == EFI_DEVICE_ERROR) ||\r
-      (PacketCommandStatus == EFI_TIMEOUT)) {\r
-\r
-    //\r
-    // avoid submit request sense command continuously.\r
-    //\r
-    if ((Packet->SenseData == NULL) || (((UINT8 *)Packet->Cdb)[0] == ATA_CMD_REQUEST_SENSE)) {\r
-      return PacketCommandStatus;\r
-    }\r
-\r
-    AtaPacketRequestSense (\r
-      PciIo,\r
-      IdeRegisters,\r
-      Channel,\r
-      Device,\r
-      Packet->SenseData,\r
-      Packet->SenseDataLength,\r
-      Packet->Timeout\r
-      );\r
-  }\r
-\r
-  return PacketCommandStatus;\r
+  return Status;\r
 }\r
 \r
-\r
 /**\r
   Set the calculated Best transfer mode to a detected device.\r
 \r
@@ -2162,8 +1922,8 @@ SetDeviceTransferMode (
   IN OUT EFI_ATA_STATUS_BLOCK          *AtaStatusBlock\r
   )\r
 {\r
-  EFI_STATUS              Status;\r
-  EFI_ATA_COMMAND_BLOCK   AtaCommandBlock;\r
+  EFI_STATUS             Status;\r
+  EFI_ATA_COMMAND_BLOCK  AtaCommandBlock;\r
 \r
   ZeroMem (&AtaCommandBlock, sizeof (EFI_ATA_COMMAND_BLOCK));\r
 \r
@@ -2209,17 +1969,16 @@ SetDriveParameters (
   IN     UINT8                         Device,\r
   IN     EFI_ATA_DRIVE_PARMS           *DriveParameters,\r
   IN OUT EFI_ATA_STATUS_BLOCK          *AtaStatusBlock\r
-  \r
   )\r
 {\r
-  EFI_STATUS              Status;\r
-  EFI_ATA_COMMAND_BLOCK   AtaCommandBlock;\r
+  EFI_STATUS             Status;\r
+  EFI_ATA_COMMAND_BLOCK  AtaCommandBlock;\r
 \r
   ZeroMem (&AtaCommandBlock, sizeof (EFI_ATA_COMMAND_BLOCK));\r
\r
+\r
   AtaCommandBlock.AtaCommand     = ATA_CMD_INIT_DRIVE_PARAM;\r
   AtaCommandBlock.AtaSectorCount = DriveParameters->Sector;\r
-  AtaCommandBlock.AtaDeviceHead  = (UINT8) ((Device << 0x4) + DriveParameters->Heads);\r
+  AtaCommandBlock.AtaDeviceHead  = (UINT8)((Device << 0x4) + DriveParameters->Heads);\r
 \r
   //\r
   // Send Init drive parameters\r
@@ -2229,7 +1988,7 @@ SetDriveParameters (
              &Instance->IdeRegisters[Channel],\r
              &AtaCommandBlock,\r
              AtaStatusBlock,\r
-             ATA_ATAPI_TIMEOUT, \r
+             ATA_ATAPI_TIMEOUT,\r
              NULL\r
              );\r
 \r
@@ -2245,7 +2004,7 @@ SetDriveParameters (
              &Instance->IdeRegisters[Channel],\r
              &AtaCommandBlock,\r
              AtaStatusBlock,\r
-             ATA_ATAPI_TIMEOUT, \r
+             ATA_ATAPI_TIMEOUT,\r
              NULL\r
              );\r
 \r
@@ -2273,10 +2032,10 @@ IdeAtaSmartReturnStatusCheck (
   IN OUT EFI_ATA_STATUS_BLOCK          *AtaStatusBlock\r
   )\r
 {\r
-  EFI_STATUS              Status;\r
-  EFI_ATA_COMMAND_BLOCK   AtaCommandBlock;\r
-  UINT8                   LBAMid;\r
-  UINT8                   LBAHigh;\r
+  EFI_STATUS             Status;\r
+  EFI_ATA_COMMAND_BLOCK  AtaCommandBlock;\r
+  UINT8                  LBAMid;\r
+  UINT8                  LBAHigh;\r
 \r
   ZeroMem (&AtaCommandBlock, sizeof (EFI_ATA_COMMAND_BLOCK));\r
 \r
@@ -2284,7 +2043,7 @@ IdeAtaSmartReturnStatusCheck (
   AtaCommandBlock.AtaFeatures     = ATA_SMART_RETURN_STATUS;\r
   AtaCommandBlock.AtaCylinderLow  = ATA_CONSTANT_4F;\r
   AtaCommandBlock.AtaCylinderHigh = ATA_CONSTANT_C2;\r
-  AtaCommandBlock.AtaDeviceHead   = (UINT8) ((Device << 0x4) | 0xe0);\r
+  AtaCommandBlock.AtaDeviceHead   = (UINT8)((Device << 0x4) | 0xe0);\r
 \r
   //\r
   // Send S.M.A.R.T Read Return Status command to device\r
@@ -2299,9 +2058,18 @@ IdeAtaSmartReturnStatusCheck (
              );\r
 \r
   if (EFI_ERROR (Status)) {\r
+    REPORT_STATUS_CODE (\r
+      EFI_ERROR_CODE | EFI_ERROR_MINOR,\r
+      (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_ATA_BUS_SMART_DISABLED)\r
+      );\r
     return EFI_DEVICE_ERROR;\r
   }\r
 \r
+  REPORT_STATUS_CODE (\r
+    EFI_PROGRESS_CODE,\r
+    (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_ATA_BUS_SMART_ENABLE)\r
+    );\r
+\r
   LBAMid  = IdeReadPortB (Instance->PciIo, Instance->IdeRegisters[Channel].CylinderLsb);\r
   LBAHigh = IdeReadPortB (Instance->PciIo, Instance->IdeRegisters[Channel].CylinderMsb);\r
 \r
@@ -2309,13 +2077,20 @@ IdeAtaSmartReturnStatusCheck (
     //\r
     // The threshold exceeded condition is not detected by the device\r
     //\r
-    DEBUG ((EFI_D_INFO, "The S.M.A.R.T threshold exceeded condition is not detected\n"));\r
-\r
+    DEBUG ((DEBUG_INFO, "The S.M.A.R.T threshold exceeded condition is not detected\n"));\r
+    REPORT_STATUS_CODE (\r
+      EFI_PROGRESS_CODE,\r
+      (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_ATA_BUS_SMART_UNDERTHRESHOLD)\r
+      );\r
   } else if ((LBAMid == 0xf4) && (LBAHigh == 0x2c)) {\r
     //\r
     // The threshold exceeded condition is detected by the device\r
     //\r
-    DEBUG ((EFI_D_INFO, "The S.M.A.R.T threshold exceeded condition is detected\n"));\r
+    DEBUG ((DEBUG_INFO, "The S.M.A.R.T threshold exceeded condition is detected\n"));\r
+    REPORT_STATUS_CODE (\r
+      EFI_PROGRESS_CODE,\r
+      (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_ATA_BUS_SMART_OVERTHRESHOLD)\r
+      );\r
   }\r
 \r
   return EFI_SUCCESS;\r
@@ -2341,8 +2116,8 @@ IdeAtaSmartSupport (
   IN OUT EFI_ATA_STATUS_BLOCK          *AtaStatusBlock\r
   )\r
 {\r
-  EFI_STATUS              Status;\r
-  EFI_ATA_COMMAND_BLOCK   AtaCommandBlock;\r
+  EFI_STATUS             Status;\r
+  EFI_ATA_COMMAND_BLOCK  AtaCommandBlock;\r
 \r
   //\r
   // Detect if the device supports S.M.A.R.T.\r
@@ -2351,13 +2126,25 @@ IdeAtaSmartSupport (
     //\r
     // S.M.A.R.T is not supported by the device\r
     //\r
-    DEBUG ((EFI_D_INFO, "S.M.A.R.T feature is not supported at [%a] channel [%a] device!\n", \r
-            (Channel == 1) ? "secondary" : "primary", (Device == 1) ? "slave" : "master"));\r
+    DEBUG ((\r
+      DEBUG_INFO,\r
+      "S.M.A.R.T feature is not supported at [%a] channel [%a] device!\n",\r
+      (Channel == 1) ? "secondary" : "primary",\r
+      (Device == 1) ? "slave" : "master"\r
+      ));\r
+    REPORT_STATUS_CODE (\r
+      EFI_ERROR_CODE | EFI_ERROR_MINOR,\r
+      (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_ATA_BUS_SMART_NOTSUPPORTED)\r
+      );\r
   } else {\r
     //\r
     // Check if the feature is enabled. If not, then enable S.M.A.R.T.\r
     //\r
     if ((IdentifyData->AtaData.command_set_feature_enb_85 & 0x0001) != 0x0001) {\r
+      REPORT_STATUS_CODE (\r
+        EFI_PROGRESS_CODE,\r
+        (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_ATA_BUS_SMART_DISABLE)\r
+        );\r
 \r
       ZeroMem (&AtaCommandBlock, sizeof (EFI_ATA_COMMAND_BLOCK));\r
 \r
@@ -2365,7 +2152,7 @@ IdeAtaSmartSupport (
       AtaCommandBlock.AtaFeatures     = ATA_SMART_ENABLE_OPERATION;\r
       AtaCommandBlock.AtaCylinderLow  = ATA_CONSTANT_4F;\r
       AtaCommandBlock.AtaCylinderHigh = ATA_CONSTANT_C2;\r
-      AtaCommandBlock.AtaDeviceHead   = (UINT8) ((Device << 0x4) | 0xe0);\r
+      AtaCommandBlock.AtaDeviceHead   = (UINT8)((Device << 0x4) | 0xe0);\r
 \r
       //\r
       // Send S.M.A.R.T Enable command to device\r
@@ -2390,7 +2177,7 @@ IdeAtaSmartSupport (
         AtaCommandBlock.AtaSectorCount  = 0xF1;\r
         AtaCommandBlock.AtaCylinderLow  = ATA_CONSTANT_4F;\r
         AtaCommandBlock.AtaCylinderHigh = ATA_CONSTANT_C2;\r
-        AtaCommandBlock.AtaDeviceHead   = (UINT8) ((Device << 0x4) | 0xe0);\r
+        AtaCommandBlock.AtaDeviceHead   = (UINT8)((Device << 0x4) | 0xe0);\r
 \r
         Status = AtaNonDataCommandIn (\r
                    Instance->PciIo,\r
@@ -2411,15 +2198,17 @@ IdeAtaSmartSupport (
       }\r
     }\r
 \r
-    DEBUG ((EFI_D_INFO, "Enabled S.M.A.R.T feature at [%a] channel [%a] device!\n", \r
-           (Channel == 1) ? "secondary" : "primary", (Device == 1) ? "slave" : "master"));\r
-\r
+    DEBUG ((\r
+      DEBUG_INFO,\r
+      "Enabled S.M.A.R.T feature at [%a] channel [%a] device!\n",\r
+      (Channel == 1) ? "secondary" : "primary",\r
+      (Device == 1) ? "slave" : "master"\r
+      ));\r
   }\r
 \r
-  return ;\r
+  return;\r
 }\r
 \r
-\r
 /**\r
   Sends out an ATA Identify Command to the specified device.\r
 \r
@@ -2482,19 +2271,19 @@ AtaIdentify (
   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
+  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
+  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
+  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
+\r
   @param Instance         A pointer to ATA_ATAPI_PASS_THRU_INSTANCE data structure.\r
   @param Channel          The channel number of device.\r
   @param Device           The device number of device.\r
@@ -2521,7 +2310,7 @@ AtaIdentifyPacket (
   EFI_ATA_COMMAND_BLOCK  AtaCommandBlock;\r
 \r
   ZeroMem (&AtaCommandBlock, sizeof (EFI_ATA_COMMAND_BLOCK));\r
-  \r
+\r
   AtaCommandBlock.AtaCommand    = ATA_CMD_IDENTIFY_DEVICE;\r
   AtaCommandBlock.AtaDeviceHead = (UINT8)(Device << 0x4);\r
 \r
@@ -2531,7 +2320,7 @@ AtaIdentifyPacket (
   Status = AtaPioDataInOut (\r
              Instance->PciIo,\r
              &Instance->IdeRegisters[Channel],\r
-             (VOID *) Buffer,\r
+             (VOID *)Buffer,\r
              sizeof (EFI_IDENTIFY_DATA),\r
              TRUE,\r
              &AtaCommandBlock,\r
@@ -2543,7 +2332,6 @@ AtaIdentifyPacket (
   return Status;\r
 }\r
 \r
-\r
 /**\r
   This function is used for detect whether the IDE device exists in the\r
   specified Channel as the specified Device Number.\r
@@ -2573,37 +2361,42 @@ DetectAndConfigIdeDevice (
   IN  UINT8                         IdeChannel\r
   )\r
 {\r
-  EFI_STATUS                        Status;\r
-  UINT8                             SectorCountReg;\r
-  UINT8                             LBALowReg;\r
-  UINT8                             LBAMidReg;\r
-  UINT8                             LBAHighReg;\r
-  EFI_ATA_DEVICE_TYPE               DeviceType;\r
-  UINT8                             IdeDevice;\r
-  EFI_IDE_REGISTERS                 *IdeRegisters;\r
-  EFI_IDENTIFY_DATA                 Buffer;\r
+  EFI_STATUS           Status;\r
+  UINT8                SectorCountReg;\r
+  UINT8                LBALowReg;\r
+  UINT8                LBAMidReg;\r
+  UINT8                LBAHighReg;\r
+  EFI_ATA_DEVICE_TYPE  DeviceType;\r
+  UINT8                IdeDevice;\r
+  EFI_IDE_REGISTERS    *IdeRegisters;\r
+  EFI_IDENTIFY_DATA    Buffer;\r
 \r
   EFI_IDE_CONTROLLER_INIT_PROTOCOL  *IdeInit;\r
   EFI_PCI_IO_PROTOCOL               *PciIo;\r
 \r
-  EFI_ATA_COLLECTIVE_MODE           *SupportedModes;\r
-  EFI_ATA_TRANSFER_MODE             TransferMode;\r
-  EFI_ATA_DRIVE_PARMS               DriveParameters;\r
+  EFI_ATA_COLLECTIVE_MODE  *SupportedModes;\r
+  EFI_ATA_TRANSFER_MODE    TransferMode;\r
+  EFI_ATA_DRIVE_PARMS      DriveParameters;\r
 \r
   IdeRegisters = &Instance->IdeRegisters[IdeChannel];\r
   IdeInit      = Instance->IdeControllerInit;\r
   PciIo        = Instance->PciIo;\r
 \r
   for (IdeDevice = 0; IdeDevice < EfiIdeMaxDevice; IdeDevice++) {\r
+    //\r
+    // Select Master or Slave device to get the return signature for ATA DEVICE DIAGNOSTIC cmd.\r
+    //\r
+    IdeWritePortB (PciIo, IdeRegisters->Head, (UINT8)((IdeDevice << 4) | 0xe0));\r
+\r
     //\r
     // Send ATA Device Execut Diagnostic command.\r
     // This command should work no matter DRDY is ready or not\r
     //\r
     IdeWritePortB (PciIo, IdeRegisters->CmdOrStatus, ATA_CMD_EXEC_DRIVE_DIAG);\r
-  \r
+\r
     Status = WaitForBSYClear (PciIo, IdeRegisters, 350000000);\r
     if (EFI_ERROR (Status)) {\r
-      DEBUG((EFI_D_ERROR, "New detecting method: Send Execute Diagnostic Command: WaitForBSYClear: Status: %d\n", Status));\r
+      DEBUG ((DEBUG_ERROR, "New detecting method: Send Execute Diagnostic Command: WaitForBSYClear: Status: %d\n", Status));\r
       continue;\r
     }\r
 \r
@@ -2641,6 +2434,8 @@ DetectAndConfigIdeDevice (
       // if identifying ata device is failure, then try to send identify packet cmd.\r
       //\r
       if (EFI_ERROR (Status)) {\r
+        REPORT_STATUS_CODE (EFI_PROGRESS_CODE, (EFI_PERIPHERAL_FIXED_MEDIA | EFI_P_EC_NOT_DETECTED));\r
+\r
         DeviceType = EfiIdeCdrom;\r
         Status     = AtaIdentifyPacket (Instance, IdeChannel, IdeDevice, &Buffer, NULL);\r
       }\r
@@ -2662,13 +2457,17 @@ DetectAndConfigIdeDevice (
       continue;\r
     }\r
 \r
-    DEBUG ((EFI_D_INFO, "[%a] channel [%a] [%a] device\n", \r
-            (IdeChannel == 1) ? "secondary" : "primary  ", (IdeDevice == 1) ? "slave " : "master",\r
-            DeviceType == EfiIdeCdrom ? "cdrom   " : "harddisk"));\r
+    DEBUG ((\r
+      DEBUG_INFO,\r
+      "[%a] channel [%a] [%a] device\n",\r
+      (IdeChannel == 1) ? "secondary" : "primary  ",\r
+      (IdeDevice == 1) ? "slave " : "master",\r
+      DeviceType == EfiIdeCdrom ? "cdrom   " : "harddisk"\r
+      ));\r
     //\r
     // If the device is a hard disk, then try to enable S.M.A.R.T feature\r
     //\r
-    if (DeviceType == EfiIdeHarddisk) {\r
+    if ((DeviceType == EfiIdeHarddisk) && PcdGetBool (PcdAtaSmartEnable)) {\r
       IdeAtaSmartSupport (\r
         Instance,\r
         IdeChannel,\r
@@ -2693,7 +2492,7 @@ DetectAndConfigIdeDevice (
                         &SupportedModes\r
                         );\r
     if (EFI_ERROR (Status)) {\r
-      DEBUG ((EFI_D_ERROR, "Calculate Mode Fail, Status = %r\n", Status));\r
+      DEBUG ((DEBUG_ERROR, "Calculate Mode Fail, Status = %r\n", Status));\r
       continue;\r
     }\r
 \r
@@ -2706,39 +2505,39 @@ DetectAndConfigIdeDevice (
       TransferMode.ModeCategory = EFI_ATA_MODE_FLOW_PIO;\r
     }\r
 \r
-    TransferMode.ModeNumber = (UINT8) (SupportedModes->PioMode.Mode);\r
+    TransferMode.ModeNumber = (UINT8)(SupportedModes->PioMode.Mode);\r
 \r
-    if (SupportedModes->ExtModeCount == 0){\r
+    if (SupportedModes->ExtModeCount == 0) {\r
       Status = SetDeviceTransferMode (Instance, IdeChannel, IdeDevice, &TransferMode, NULL);\r
 \r
       if (EFI_ERROR (Status)) {\r
-        DEBUG ((EFI_D_ERROR, "Set transfer Mode Fail, Status = %r\n", Status));\r
+        DEBUG ((DEBUG_ERROR, "Set transfer Mode Fail, Status = %r\n", Status));\r
         continue;\r
       }\r
     }\r
 \r
     //\r
-    // Set supported DMA mode on this IDE device. Note that UDMA & MDMA cann't\r
+    // Set supported DMA mode on this IDE device. Note that UDMA & MDMA can't\r
     // be set together. Only one DMA mode can be set to a device. If setting\r
     // DMA mode operation fails, we can continue moving on because we only use\r
     // PIO mode at boot time. DMA modes are used by certain kind of OS booting\r
     //\r
     if (SupportedModes->UdmaMode.Valid) {\r
       TransferMode.ModeCategory = EFI_ATA_MODE_UDMA;\r
-      TransferMode.ModeNumber   = (UINT8) (SupportedModes->UdmaMode.Mode);\r
-      Status = SetDeviceTransferMode (Instance, IdeChannel, IdeDevice, &TransferMode, NULL);\r
+      TransferMode.ModeNumber   = (UINT8)(SupportedModes->UdmaMode.Mode);\r
+      Status                    = SetDeviceTransferMode (Instance, IdeChannel, IdeDevice, &TransferMode, NULL);\r
 \r
       if (EFI_ERROR (Status)) {\r
-        DEBUG ((EFI_D_ERROR, "Set transfer Mode Fail, Status = %r\n", Status));\r
+        DEBUG ((DEBUG_ERROR, "Set transfer Mode Fail, Status = %r\n", Status));\r
         continue;\r
       }\r
     } else if (SupportedModes->MultiWordDmaMode.Valid) {\r
       TransferMode.ModeCategory = EFI_ATA_MODE_MDMA;\r
-      TransferMode.ModeNumber   = (UINT8) SupportedModes->MultiWordDmaMode.Mode;\r
-      Status = SetDeviceTransferMode (Instance, IdeChannel, IdeDevice, &TransferMode, NULL);\r
+      TransferMode.ModeNumber   = (UINT8)SupportedModes->MultiWordDmaMode.Mode;\r
+      Status                    = SetDeviceTransferMode (Instance, IdeChannel, IdeDevice, &TransferMode, NULL);\r
 \r
       if (EFI_ERROR (Status)) {\r
-        DEBUG ((EFI_D_ERROR, "Set transfer Mode Fail, Status = %r\n", Status));\r
+        DEBUG ((DEBUG_ERROR, "Set transfer Mode Fail, Status = %r\n", Status));\r
         continue;\r
       }\r
     }\r
@@ -2752,9 +2551,9 @@ DetectAndConfigIdeDevice (
       //\r
       // Init driver parameters\r
       //\r
-      DriveParameters.Sector         = (UINT8) ((ATA5_IDENTIFY_DATA *)(&Buffer.AtaData))->sectors_per_track;\r
-      DriveParameters.Heads          = (UINT8) (((ATA5_IDENTIFY_DATA *)(&Buffer.AtaData))->heads - 1);\r
-      DriveParameters.MultipleSector = (UINT8) ((ATA5_IDENTIFY_DATA *)(&Buffer.AtaData))->multi_sector_cmd_max_sct_cnt;\r
+      DriveParameters.Sector         = (UINT8)((ATA5_IDENTIFY_DATA *)(&Buffer.AtaData))->sectors_per_track;\r
+      DriveParameters.Heads          = (UINT8)(((ATA5_IDENTIFY_DATA *)(&Buffer.AtaData))->heads - 1);\r
+      DriveParameters.MultipleSector = (UINT8)((ATA5_IDENTIFY_DATA *)(&Buffer.AtaData))->multi_sector_cmd_max_sct_cnt;\r
 \r
       Status = SetDriveParameters (Instance, IdeChannel, IdeDevice, &DriveParameters, NULL);\r
     }\r
@@ -2772,26 +2571,29 @@ DetectAndConfigIdeDevice (
     if (EFI_ERROR (Status)) {\r
       continue;\r
     }\r
+\r
+    if (DeviceType == EfiIdeHarddisk) {\r
+      REPORT_STATUS_CODE (EFI_PROGRESS_CODE, (EFI_PERIPHERAL_FIXED_MEDIA | EFI_P_PC_ENABLE));\r
+    }\r
   }\r
+\r
   return EFI_SUCCESS;\r
 }\r
 \r
-\r
 /**\r
   Initialize ATA host controller at IDE mode.\r
-  \r
-  The function is designed to initialize ATA host controller. \r
-  \r
+\r
+  The function is designed to initialize ATA host controller.\r
+\r
   @param[in]  Instance          A pointer to the ATA_ATAPI_PASS_THRU_INSTANCE instance.\r
 \r
 **/\r
 EFI_STATUS\r
 EFIAPI\r
 IdeModeInitialization (\r
-  IN  ATA_ATAPI_PASS_THRU_INSTANCE    *Instance\r
+  IN  ATA_ATAPI_PASS_THRU_INSTANCE  *Instance\r
   )\r
 {\r
-  BOOLEAN                           EnumAll;\r
   EFI_STATUS                        Status;\r
   EFI_IDE_CONTROLLER_INIT_PROTOCOL  *IdeInit;\r
   EFI_PCI_IO_PROTOCOL               *PciIo;\r
@@ -2802,7 +2604,6 @@ IdeModeInitialization (
 \r
   IdeInit = Instance->IdeControllerInit;\r
   PciIo   = Instance->PciIo;\r
-  EnumAll = IdeInit->EnumAll;\r
   Channel = IdeInit->ChannelCount;\r
 \r
   //\r
@@ -2826,7 +2627,7 @@ IdeModeInitialization (
                         &MaxDevices\r
                         );\r
     if (EFI_ERROR (Status)) {\r
-      DEBUG ((EFI_D_ERROR, "[GetChannel, Status=%x]", Status));\r
+      DEBUG ((DEBUG_ERROR, "[GetChannel, Status=%x]", Status));\r
       continue;\r
     }\r
 \r
@@ -2865,4 +2666,3 @@ IdeModeInitialization (
 ErrorExit:\r
   return Status;\r
 }\r
-\r