]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Bus/Ata/AtaAtapiPassThru/AhciMode.c
Add BlockIO2 Protocol.
[mirror_edk2.git] / MdeModulePkg / Bus / Ata / AtaAtapiPassThru / AhciMode.c
index 8ba0201563478f68b945668cb9842d13bd9fbdd2..7765bfc75c892ba5acf0064aea10f5b7ff456c7a 100644 (file)
@@ -184,9 +184,50 @@ AhciWaitMemSet (
   return EFI_DEVICE_ERROR;\r
 }\r
 \r
+/**\r
+  Check the memory status to the test value.\r
+    \r
+  @param[in]       PciIo             The PCI IO protocol instance.\r
+  @param[in]       Offset            The memory address to test.\r
+  @param[in]       MaskValue         The mask value of memory.\r
+  @param[in]       TestValue         The test value of memory.\r
+  @param[in, out]  RetryTimes        The retry times value for waitting memory set.\r
+\r
+  @retval EFI_NOTREADY      The memory is not set.\r
+  @retval EFI_TIMEOUT       The memory setting retry times out.\r
+  @retval EFI_SUCCESS       The memory is correct set.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+AhciCheckMemSet (\r
+  IN  EFI_PCI_IO_PROTOCOL       *PciIo,\r
+  IN  UINT32                    Offset,\r
+  IN  UINT32                    MaskValue,\r
+  IN  UINT32                    TestValue,\r
+  IN  UINTN                     *RetryTimes\r
+  )\r
+{\r
+  UINT32     Value;\r
+\r
+  (*RetryTimes) --;\r
+  \r
+  Value = AhciReadReg (PciIo, Offset) & MaskValue;\r
+\r
+  if (Value == TestValue) {\r
+    return EFI_SUCCESS;\r
+  }\r
+\r
+  if ((*RetryTimes) == 0) {\r
+    return EFI_TIMEOUT;\r
+  } else {\r
+    return EFI_NOT_READY;\r
+  }\r
+}\r
+\r
 /**\r
   Check if the device is still on port. It also checks if the AHCI controller \r
-  supports the address and data count will be transfered.\r
+  supports the address and data count will be transferred.\r
 \r
   @param  PciIo            The PCI IO protocol instance.\r
   @param  Port             The number of port.\r
@@ -206,7 +247,7 @@ AhciCheckDeviceStatus (
   IN  UINT8                  Port\r
   )\r
 {\r
-  UINT32      Data; \r
+  UINT32      Data;\r
   UINT32      Offset;\r
 \r
   Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_SSTS;\r
@@ -214,7 +255,7 @@ AhciCheckDeviceStatus (
   Data   = AhciReadReg (PciIo, Offset) & EFI_AHCI_PORT_SSTS_DET_MASK;\r
 \r
   if (Data == EFI_AHCI_PORT_SSTS_DET_PCE) {\r
-    return EFI_SUCCESS;      \r
+    return EFI_SUCCESS;\r
   }\r
 \r
   return EFI_NOT_READY;\r
@@ -240,7 +281,7 @@ AhciClearPortStatus (
 \r
   //\r
   // Clear any error status\r
-  //  \r
+  //\r
   Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_SERR;\r
   AhciWriteReg (PciIo, Offset, AhciReadReg (PciIo, Offset));\r
 \r
@@ -310,8 +351,8 @@ AhciEnableFisReceive (
   IN  EFI_PCI_IO_PROTOCOL       *PciIo,\r
   IN  UINT8                     Port,\r
   IN  UINT64                    Timeout\r
-  )     \r
-{ \r
+  )\r
+{\r
   UINT32 Offset;\r
 \r
   Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_CMD;\r
@@ -370,12 +411,12 @@ AhciDisableFisReceive (
   AhciAndReg (PciIo, Offset, (UINT32)~(EFI_AHCI_PORT_CMD_FRE));\r
 \r
   return AhciWaitMemSet (\r
-           PciIo, \r
+           PciIo,\r
            Offset,\r
            EFI_AHCI_PORT_CMD_FR,\r
            0,\r
            Timeout\r
-           ); \r
+           );\r
 }\r
 \r
 \r
@@ -412,7 +453,7 @@ AhciBuildCommand (
   IN     UINT64                     DataLength\r
   )   \r
 {\r
-  UINT64     BaseAddr; \r
+  UINT64     BaseAddr;\r
   UINT64     PrdtNumber;\r
   UINT64     PrdtIndex;\r
   UINTN      RemainedData;\r
@@ -436,7 +477,7 @@ AhciBuildCommand (
 \r
   BaseAddr = Data64.Uint64;\r
   \r
-  ZeroMem ((VOID *)((UINTN) BaseAddr), sizeof (EFI_AHCI_RECEIVED_FIS));  \r
+  ZeroMem ((VOID *)((UINTN) BaseAddr), sizeof (EFI_AHCI_RECEIVED_FIS));\r
     \r
   ZeroMem (AhciRegisters->AhciCommandTable, sizeof (EFI_AHCI_COMMAND_TABLE));\r
 \r
@@ -466,7 +507,7 @@ AhciBuildCommand (
   CommandList->AhciCmdPrdtl = (UINT32)PrdtNumber;\r
   \r
   for (PrdtIndex = 0; PrdtIndex < PrdtNumber; PrdtIndex++) {\r
-    if (RemainedData < EFI_AHCI_MAX_DATA_PER_PRDT) {     \r
+    if (RemainedData < EFI_AHCI_MAX_DATA_PER_PRDT) {\r
       AhciRegisters->AhciCommandTable->PrdtTable[PrdtIndex].AhciPrdtDbc = (UINT32)RemainedData - 1;\r
     } else {\r
       AhciRegisters->AhciCommandTable->PrdtTable[PrdtIndex].AhciPrdtDbc = EFI_AHCI_MAX_DATA_PER_PRDT - 1;\r
@@ -475,7 +516,7 @@ AhciBuildCommand (
     Data64.Uint64 = (UINT64)MemAddr;\r
     AhciRegisters->AhciCommandTable->PrdtTable[PrdtIndex].AhciPrdtDba  = Data64.Uint32.Lower32;\r
     AhciRegisters->AhciCommandTable->PrdtTable[PrdtIndex].AhciPrdtDbau = Data64.Uint32.Upper32;\r
-    RemainedData -= EFI_AHCI_MAX_DATA_PER_PRDT;    \r
+    RemainedData -= EFI_AHCI_MAX_DATA_PER_PRDT;\r
     MemAddr      += EFI_AHCI_MAX_DATA_PER_PRDT;\r
   }\r
 \r
@@ -543,18 +584,21 @@ AhciBuildCommandFis (
 /**\r
   Start a PIO data transfer on specific port.\r
     \r
-  @param  PciIo               The PCI IO protocol instance.\r
-  @param  AhciRegisters       The pointer to the EFI_AHCI_REGISTERS.\r
-  @param  Port                The number of port.\r
-  @param  PortMultiplier      The timeout value of stop.\r
-  @param  AtapiCommand        The atapi command will be used for the transfer.\r
-  @param  AtapiCommandLength  The length of the atapi command.\r
-  @param  Read                The transfer direction.\r
-  @param  AtaCommandBlock     The EFI_ATA_COMMAND_BLOCK data.\r
-  @param  AtaStatusBlock      The EFI_ATA_STATUS_BLOCK data.\r
-  @param  MemoryAddr          The pointer to the data buffer.\r
-  @param  DataCount           The data count to be transferred.\r
-  @param  Timeout             The timeout value of non data transfer.\r
+  @param[in]       PciIo               The PCI IO protocol instance.\r
+  @param[in]       AhciRegisters       The pointer to the EFI_AHCI_REGISTERS.\r
+  @param[in]       Port                The number of port.\r
+  @param[in]       PortMultiplier      The timeout value of stop.\r
+  @param[in]       AtapiCommand        The atapi command will be used for the\r
+                                       transfer.\r
+  @param[in]       AtapiCommandLength  The length of the atapi command.\r
+  @param[in]       Read                The transfer direction.\r
+  @param[in]       AtaCommandBlock     The EFI_ATA_COMMAND_BLOCK data.\r
+  @param[in, out]  AtaStatusBlock      The EFI_ATA_STATUS_BLOCK data.\r
+  @param[in, out]  MemoryAddr          The pointer to the data buffer.\r
+  @param[in]       DataCount           The data count to be transferred.\r
+  @param[in]       Timeout             The timeout value of non data transfer.\r
+  @param[in]       Task                Optional. Pointer to the ATA_NONBLOCK_TASK\r
+                                       used by non-blocking mode.\r
 \r
   @retval EFI_DEVICE_ERROR    The PIO data transfer abort with error occurs.\r
   @retval EFI_TIMEOUT         The operation is time out.\r
@@ -576,7 +620,8 @@ AhciPioTransfer (
   IN OUT EFI_ATA_STATUS_BLOCK       *AtaStatusBlock,\r
   IN OUT VOID                       *MemoryAddr,\r
   IN     UINT32                     DataCount,\r
-  IN     UINT64                     Timeout \r
+  IN     UINT64                     Timeout,\r
+  IN     ATA_NONBLOCK_TASK          *Task\r
   )\r
 {\r
   EFI_STATUS                    Status;\r
@@ -639,17 +684,17 @@ AhciPioTransfer (
     );    \r
   \r
   Status = AhciStartCommand (\r
-             PciIo, \r
-             Port, \r
+             PciIo,\r
+             Port,\r
              0,\r
              Timeout\r
              );\r
   if (EFI_ERROR (Status)) {\r
     goto Exit;\r
   }\r
-  \r
+\r
   //\r
-  // Checking the status and wait the driver sending data\r
+  // Check the status and wait the driver sending data\r
   //\r
   FisBaseAddr = (UINTN)AhciRegisters->AhciRFis + Port * sizeof (EFI_AHCI_RECEIVED_FIS);\r
   //\r
@@ -668,7 +713,7 @@ AhciPioTransfer (
     //\r
     MicroSecondDelay(100);\r
 \r
-    Delay--;    \r
+    Delay--;\r
   } while (Delay > 0);\r
 \r
   if (Delay == 0) {\r
@@ -689,30 +734,30 @@ AhciPioTransfer (
              );\r
 \r
   if (EFI_ERROR (Status)) {\r
-    goto Exit;   \r
+    goto Exit;\r
   }\r
 \r
   Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_IS;\r
   Status = AhciWaitMemSet (\r
              PciIo,\r
-             Offset,            \r
+             Offset,\r
              EFI_AHCI_PORT_IS_PSS,\r
              EFI_AHCI_PORT_IS_PSS,\r
              Timeout\r
-             );  \r
+             );\r
   if (EFI_ERROR (Status)) {\r
-    goto Exit;  \r
+    goto Exit;\r
   }\r
 \r
-Exit: \r
+Exit:\r
   AhciStopCommand (\r
-    PciIo, \r
+    PciIo,\r
     Port,\r
     Timeout\r
     );\r
   \r
   AhciDisableFisReceive (\r
-    PciIo, \r
+    PciIo,\r
     Port,\r
     Timeout\r
     );\r
@@ -730,29 +775,32 @@ Exit:
 /**\r
   Start a DMA data transfer on specific port\r
 \r
-  @param  PciIo               The PCI IO protocol instance.\r
-  @param  AhciRegisters       The pointer to the EFI_AHCI_REGISTERS.\r
-  @param  Port                The number of port.\r
-  @param  PortMultiplier      The timeout value of stop.\r
-  @param  AtapiCommand        The atapi command will be used for the transfer.\r
-  @param  AtapiCommandLength  The length of the atapi command.\r
-  @param  Read                The transfer direction.\r
-  @param  AtaCommandBlock     The EFI_ATA_COMMAND_BLOCK data.\r
-  @param  AtaStatusBlock      The EFI_ATA_STATUS_BLOCK data.\r
-  @param  MemoryAddr          The pointer to the data buffer.\r
-  @param  DataCount           The data count to be transferred.\r
-  @param  Timeout             The timeout value of non data transfer.\r
+  @param[in]       Instance            The ATA_ATAPI_PASS_THRU_INSTANCE protocol instance.\r
+  @param[in]       AhciRegisters       The pointer to the EFI_AHCI_REGISTERS.\r
+  @param[in]       Port                The number of port.\r
+  @param[in]       PortMultiplier      The timeout value of stop.\r
+  @param[in]       AtapiCommand        The atapi command will be used for the\r
+                                       transfer.\r
+  @param[in]       AtapiCommandLength  The length of the atapi command.\r
+  @param[in]       Read                The transfer direction.\r
+  @param[in]       AtaCommandBlock     The EFI_ATA_COMMAND_BLOCK data.\r
+  @param[in, out]  AtaStatusBlock      The EFI_ATA_STATUS_BLOCK data.\r
+  @param[in, out]  MemoryAddr          The pointer to the data buffer.\r
+  @param[in]       DataCount           The data count to be transferred.\r
+  @param[in]       Timeout             The timeout value of non data transfer.\r
+  @param[in]       Task                Optional. Pointer to the ATA_NONBLOCK_TASK\r
+                                       used by non-blocking mode.\r
 \r
   @retval EFI_DEVICE_ERROR    The DMA data transfer abort with error occurs.\r
   @retval EFI_TIMEOUT         The operation is time out.\r
   @retval EFI_UNSUPPORTED     The device is not ready for transfer.\r
   @retval EFI_SUCCESS         The DMA data transfer executes successfully.\r
-   \r
+\r
 **/\r
 EFI_STATUS\r
 EFIAPI\r
 AhciDmaTransfer (\r
-  IN     EFI_PCI_IO_PROTOCOL        *PciIo,\r
+  IN     ATA_ATAPI_PASS_THRU_INSTANCE *Instance,\r
   IN     EFI_AHCI_REGISTERS         *AhciRegisters,\r
   IN     UINT8                      Port,\r
   IN     UINT8                      PortMultiplier,\r
@@ -763,7 +811,8 @@ AhciDmaTransfer (
   IN OUT EFI_ATA_STATUS_BLOCK       *AtaStatusBlock,\r
   IN OUT VOID                       *MemoryAddr,\r
   IN     UINTN                      DataCount,\r
-  IN     UINT64                     Timeout\r
+  IN     UINT64                     Timeout,\r
+  IN     ATA_NONBLOCK_TASK          *Task\r
   )\r
 {\r
   EFI_STATUS                    Status;\r
@@ -775,141 +824,224 @@ AhciDmaTransfer (
   EFI_AHCI_COMMAND_FIS          CFis;\r
   EFI_AHCI_COMMAND_LIST         CmdList;\r
 \r
-  if (Read) {\r
-    Flag = EfiPciIoOperationBusMasterWrite;\r
-  } else {\r
-    Flag = EfiPciIoOperationBusMasterRead;\r
-  }\r
+  EFI_PCI_IO_PROTOCOL          *PciIo;\r
+  EFI_TPL                      OldTpl;\r
 \r
-  //\r
-  // construct command list and command table with pci bus address\r
-  //\r
-  MapLength = DataCount;\r
-  Status = PciIo->Map (\r
-                    PciIo,\r
-                    Flag,\r
-                    MemoryAddr,\r
-                    &MapLength,\r
-                    &PhyAddr,\r
-                    &Map\r
-                    );\r
+  Map   = NULL;\r
+  PciIo = Instance->PciIo;\r
 \r
-  if (EFI_ERROR (Status) || (DataCount != MapLength)) {\r
-    return EFI_OUT_OF_RESOURCES;\r
+  if (PciIo == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
   }\r
 \r
   //\r
-  // Package read needed\r
+  // Before starting the Blocking BlockIO operation, push to finish all non-blocking\r
+  // BlockIO tasks.\r
+  // Delay 100us to simulate the blocking time out checking.\r
   //\r
-  AhciBuildCommandFis (&CFis, AtaCommandBlock);\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 100us.\r
+    //\r
+    MicroSecondDelay (100);\r
+  }\r
 \r
-  ZeroMem (&CmdList, sizeof (EFI_AHCI_COMMAND_LIST));\r
+  if ((Task == NULL) || ((Task != NULL) && (!Task->IsStart))) {\r
+    //\r
+    // Mark the Task to indicate that it has been started.\r
+    //\r
+    if (Task != NULL) {\r
+      Task->IsStart      = TRUE;\r
+      Task->RetryTimes   = (UINT32) (DivU64x32(Timeout, 1000) + 1);\r
+    }\r
+    if (Read) {\r
+      Flag = EfiPciIoOperationBusMasterWrite;\r
+    } else {\r
+      Flag = EfiPciIoOperationBusMasterRead;\r
+    }\r
 \r
-  CmdList.AhciCmdCfl = EFI_AHCI_FIS_REGISTER_H2D_LENGTH / 4;\r
-  CmdList.AhciCmdW   = Read ? 0 : 1;\r
+    //\r
+    // Construct command list and command table with pci bus address.\r
+    //\r
+    MapLength = DataCount;\r
+    Status = PciIo->Map (\r
+                      PciIo,\r
+                      Flag,\r
+                      MemoryAddr,\r
+                      &MapLength,\r
+                      &PhyAddr,\r
+                      &Map\r
+                      );\r
+\r
+    if (EFI_ERROR (Status) || (DataCount != MapLength)) {\r
+      return EFI_OUT_OF_RESOURCES;\r
+    }\r
 \r
-  AhciBuildCommand (\r
-    PciIo,\r
-    AhciRegisters,\r
-    Port,\r
-    PortMultiplier,\r
-    &CFis,\r
-    &CmdList,\r
-    AtapiCommand,\r
-    AtapiCommandLength,\r
-    0,\r
-    (VOID *)(UINTN)PhyAddr,\r
-    DataCount\r
-    ); \r
-  \r
-  Status = AhciStartCommand (\r
-             PciIo, \r
-             Port, \r
-             0,\r
-             Timeout\r
-             );\r
-  if (EFI_ERROR (Status)) {\r
-    goto Exit;\r
-  }\r
-  \r
-  //\r
-  // Wait device PRD processed\r
-  //\r
-  Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_IS;\r
-  Status = AhciWaitMemSet (\r
-             PciIo,\r
-             Offset,\r
-             EFI_AHCI_PORT_IS_DPS,\r
-             EFI_AHCI_PORT_IS_DPS,\r
-             Timeout\r
-             ); \r
-  \r
-  if (EFI_ERROR (Status)) {\r
-    goto Exit;\r
+    if (Task != NULL) {\r
+      Task->Map = Map;\r
+    }\r
+    //\r
+    // Package read needed\r
+    //\r
+    AhciBuildCommandFis (&CFis, AtaCommandBlock);\r
+\r
+    ZeroMem (&CmdList, sizeof (EFI_AHCI_COMMAND_LIST));\r
+\r
+    CmdList.AhciCmdCfl = EFI_AHCI_FIS_REGISTER_H2D_LENGTH / 4;\r
+    CmdList.AhciCmdW   = Read ? 0 : 1;\r
+\r
+    AhciBuildCommand (\r
+      PciIo,\r
+      AhciRegisters,\r
+      Port,\r
+      PortMultiplier,\r
+      &CFis,\r
+      &CmdList,\r
+      AtapiCommand,\r
+      AtapiCommandLength,\r
+      0,\r
+      (VOID *)(UINTN)PhyAddr,\r
+      DataCount\r
+      );\r
+\r
+    Status = AhciStartCommand (\r
+               PciIo,\r
+               Port,\r
+               0,\r
+               Timeout\r
+               );\r
+    if (EFI_ERROR (Status)) {\r
+      goto Exit;\r
+    }\r
+\r
+    //\r
+    // Wait device PRD processed\r
+    //\r
+    Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_IS;\r
+    Status = AhciWaitMemSet (\r
+               PciIo,\r
+               Offset,\r
+               EFI_AHCI_PORT_IS_DPS,\r
+               EFI_AHCI_PORT_IS_DPS,\r
+               Timeout\r
+               );\r
+\r
+    if (EFI_ERROR (Status)) {\r
+      goto Exit;\r
+    }\r
   }\r
 \r
   //\r
   // Wait for command compelte\r
   //\r
   Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_CI;\r
-  Status = AhciWaitMemSet (\r
-             PciIo,\r
-             Offset,\r
-             0xFFFFFFFF,\r
-             0,\r
-             Timeout\r
-             );\r
+  if (Task != NULL) {\r
+    //\r
+    // For Non-blocking\r
+    //\r
+    Status = AhciCheckMemSet (\r
+               PciIo,\r
+               Offset,\r
+               0xFFFFFFFF,\r
+               0,\r
+               (UINTN *) (&Task->RetryTimes)\r
+               );\r
+  } else {\r
+    Status = AhciWaitMemSet (\r
+               PciIo,\r
+               Offset,\r
+               0xFFFFFFFF,\r
+               0,\r
+               Timeout\r
+               );\r
+  }\r
+\r
   if (EFI_ERROR (Status)) {\r
     goto Exit;\r
   }\r
 \r
   Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_IS;\r
-  Status = AhciWaitMemSet (\r
-             PciIo,\r
-             Offset,\r
-             EFI_AHCI_PORT_IS_DHRS,\r
-             EFI_AHCI_PORT_IS_DHRS,\r
-             Timeout\r
-             );  \r
+\r
+  if (Task != NULL) {\r
+    //\r
+    // For Non-blocking\r
+    //\r
+    Status = AhciCheckMemSet (\r
+               PciIo,\r
+               Offset,\r
+               EFI_AHCI_PORT_IS_DHRS,\r
+               EFI_AHCI_PORT_IS_DHRS,\r
+               (UINTN *) (&Task->RetryTimes)\r
+             );\r
+  } else {\r
+    Status = AhciWaitMemSet (\r
+               PciIo,\r
+               Offset,\r
+               EFI_AHCI_PORT_IS_DHRS,\r
+               EFI_AHCI_PORT_IS_DHRS,\r
+               Timeout\r
+               );\r
+  }\r
+\r
   if (EFI_ERROR (Status)) {\r
     goto Exit;\r
   }\r
 \r
-Exit: \r
-  AhciStopCommand (\r
-    PciIo, \r
-    Port,\r
-    Timeout\r
-    );\r
+Exit:\r
+  //\r
+  // For Blocking mode, the command should be stopped, the Fis should be disabled\r
+  // and the PciIo should be unmapped.\r
+  // For non-blocking mode, only when a error is happened (if the return status is \r
+  // EFI_NOT_READY that means the command doesn't finished, try again.), first do the \r
+  // context cleanup, then set the packet's Asb status.\r
+  //\r
+  if (Task == NULL ||\r
+      ((Task != NULL) && (Status != EFI_NOT_READY))\r
+     ) {\r
+    AhciStopCommand (\r
+      PciIo, \r
+      Port,\r
+      Timeout\r
+      );\r
 \r
-  AhciDisableFisReceive (\r
-    PciIo, \r
-    Port,\r
-    Timeout\r
-    );\r
+    AhciDisableFisReceive (\r
+      PciIo, \r
+      Port,\r
+      Timeout\r
+      );\r
 \r
-  PciIo->Unmap (\r
-           PciIo,\r
-           Map\r
-           );  \r
-  \r
-  AhciDumpPortStatus (PciIo, Port, AtaStatusBlock);\r
+    PciIo->Unmap (\r
+             PciIo,\r
+             (Task != NULL) ? Task->Map : Map\r
+             );\r
 \r
+    if (Task != NULL) {\r
+      Task->Packet->Asb->AtaStatus = 0x01;\r
+    }\r
+  }\r
+\r
+  AhciDumpPortStatus (PciIo, Port, AtaStatusBlock);\r
   return Status;\r
 }\r
 \r
 /**\r
   Start a non data transfer on specific port.\r
     \r
-  @param  PciIo               The PCI IO protocol instance.\r
-  @param  AhciRegisters       The pointer to the EFI_AHCI_REGISTERS.\r
-  @param  Port                The number of port.\r
-  @param  PortMultiplier      The timeout value of stop.\r
-  @param  AtapiCommand        The atapi command will be used for the transfer.\r
-  @param  AtapiCommandLength  The length of the atapi command.\r
-  @param  AtaCommandBlock     The EFI_ATA_COMMAND_BLOCK data.\r
-  @param  AtaStatusBlock      The EFI_ATA_STATUS_BLOCK data.\r
-  @param  Timeout             The timeout value of non data transfer.\r
+  @param[in]       PciIo               The PCI IO protocol instance.\r
+  @param[in]       AhciRegisters       The pointer to the EFI_AHCI_REGISTERS.\r
+  @param[in]       Port                The number of port.\r
+  @param[in]       PortMultiplier      The timeout value of stop.\r
+  @param[in]       AtapiCommand        The atapi command will be used for the\r
+                                       transfer.\r
+  @param[in]       AtapiCommandLength  The length of the atapi command.\r
+  @param[in]       AtaCommandBlock     The EFI_ATA_COMMAND_BLOCK data.\r
+  @param[in, out]  AtaStatusBlock      The EFI_ATA_STATUS_BLOCK data.\r
+  @param[in]       Timeout             The timeout value of non data transfer.\r
+  @param[in]       Task                Optional. Pointer to the ATA_NONBLOCK_TASK\r
+                                       used by non-blocking mode.\r
 \r
   @retval EFI_DEVICE_ERROR    The non data transfer abort with error occurs.\r
   @retval EFI_TIMEOUT         The operation is time out.\r
@@ -928,15 +1060,16 @@ AhciNonDataTransfer (
   IN     UINT8                         AtapiCommandLength,\r
   IN     EFI_ATA_COMMAND_BLOCK         *AtaCommandBlock,\r
   IN OUT EFI_ATA_STATUS_BLOCK          *AtaStatusBlock,\r
-  IN     UINT64                        Timeout\r
-  ) \r
+  IN     UINT64                        Timeout,\r
+  IN     ATA_NONBLOCK_TASK             *Task\r
+  )\r
 {\r
-  EFI_STATUS                   Status;  \r
+  EFI_STATUS                   Status;\r
   UINTN                        FisBaseAddr;\r
   UINT32                       Offset;\r
   UINT32                       Value;\r
   UINT32                       Delay;\r
-  \r
+\r
   EFI_AHCI_COMMAND_FIS         CFis;\r
   EFI_AHCI_COMMAND_LIST        CmdList;\r
 \r
@@ -961,18 +1094,18 @@ AhciNonDataTransfer (
     0,\r
     NULL,\r
     0\r
-    ); \r
-  \r
+    );\r
+\r
   Status = AhciStartCommand (\r
-             PciIo, \r
-             Port, \r
+             PciIo,\r
+             Port,\r
              0,\r
              Timeout\r
              );\r
   if (EFI_ERROR (Status)) {\r
     goto Exit;\r
   }\r
-  \r
+\r
   //\r
   // Wait device sends the Response Fis\r
   //\r
@@ -993,7 +1126,7 @@ AhciNonDataTransfer (
     //\r
     MicroSecondDelay(100);\r
 \r
-    Delay --;    \r
+    Delay --;\r
   } while (Delay > 0);\r
 \r
   if (Delay == 0) {\r
@@ -1009,17 +1142,17 @@ AhciNonDataTransfer (
              0xFFFFFFFF,\r
              0,\r
              Timeout\r
-             );  \r
-  \r
-Exit:  \r
+             );\r
+\r
+Exit:\r
   AhciStopCommand (\r
-    PciIo, \r
+    PciIo,\r
     Port,\r
     Timeout\r
     );\r
 \r
   AhciDisableFisReceive (\r
-    PciIo, \r
+    PciIo,\r
     Port,\r
     Timeout\r
     );\r
@@ -1056,7 +1189,7 @@ AhciStopCommand (
   Data   = AhciReadReg (PciIo, Offset);\r
 \r
   if ((Data & (EFI_AHCI_PORT_CMD_ST |  EFI_AHCI_PORT_CMD_CR)) == 0) {\r
-    return EFI_SUCCESS;    \r
+    return EFI_SUCCESS;\r
   }\r
 \r
   if ((Data & EFI_AHCI_PORT_CMD_ST) != 0) {\r
@@ -1064,22 +1197,22 @@ AhciStopCommand (
   }\r
 \r
   return AhciWaitMemSet (\r
-           PciIo, \r
+           PciIo,\r
            Offset,\r
            EFI_AHCI_PORT_CMD_CR,\r
            0,\r
            Timeout\r
-           ); \r
+           );\r
 }\r
 \r
 /**\r
   Start command for give slot on specific port.\r
-    \r
+\r
   @param  PciIo              The PCI IO protocol instance.\r
   @param  Port               The number of port.\r
-  @param  CommandSlot        The number of CommandSlot.\r
+  @param  CommandSlot        The number of Command Slot.\r
   @param  Timeout            The timeout value of start.\r
-   \r
+\r
   @retval EFI_DEVICE_ERROR   The command start unsuccessfully.\r
   @retval EFI_TIMEOUT        The operation is time out.\r
   @retval EFI_SUCCESS        The command start successfully.\r
@@ -1119,14 +1252,14 @@ AhciStartCommand (
              Port,\r
              Timeout\r
              );\r
-  \r
+\r
   if (EFI_ERROR (Status)) {\r
     return Status;\r
   }\r
 \r
   Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_CMD;\r
   PortStatus = AhciReadReg (PciIo, Offset);\r
-  \r
+\r
   StartCmd = 0;\r
   if ((PortStatus & EFI_AHCI_PORT_CMD_ALPE) != 0) {\r
     StartCmd = AhciReadReg (PciIo, Offset);\r
@@ -1143,12 +1276,12 @@ AhciStartCommand (
       AhciOrReg (PciIo, Offset, EFI_AHCI_PORT_CMD_COL);\r
 \r
       AhciWaitMemSet (\r
-        PciIo, \r
+        PciIo,\r
         Offset,\r
         EFI_AHCI_PORT_CMD_COL,\r
         0,\r
         Timeout\r
-        ); \r
+        );\r
     }\r
   }\r
 \r
@@ -1190,8 +1323,8 @@ AhciPortReset (
   )\r
 {\r
   EFI_STATUS      Status;\r
-  UINT32          Offset;  \r
-  \r
+  UINT32          Offset;\r
+\r
   AhciClearPortStatus (PciIo, Port);\r
 \r
   AhciStopCommand (PciIo, Port, Timeout);\r
@@ -1205,14 +1338,14 @@ AhciPortReset (
   AhciOrReg (PciIo, Offset, EFI_AHCI_PORT_SCTL_DET_INIT);\r
 \r
   //\r
-  // wait 5 milliseceond before de-assert DET  \r
+  // wait 5 millisecond before de-assert DET\r
   //\r
   MicroSecondDelay (5000);\r
 \r
   AhciAndReg (PciIo, Offset, (UINT32)EFI_AHCI_PORT_SCTL_MASK);\r
 \r
   //\r
-  // wait 5 milliseceond before de-assert DET  \r
+  // wait 5 millisecond before de-assert DET\r
   //\r
   MicroSecondDelay (5000);\r
 \r
@@ -1226,7 +1359,7 @@ AhciPortReset (
              EFI_AHCI_PORT_SSTS_DET_MASK,\r
              EFI_AHCI_PORT_SSTS_DET_PCE,\r
              Timeout\r
-             ); \r
+             );\r
 \r
   if (EFI_ERROR (Status)) {\r
     return Status;\r
@@ -1240,11 +1373,10 @@ AhciPortReset (
 \r
 /**\r
   Do AHCI HBA reset.\r
-    \r
+\r
   @param  PciIo              The PCI IO protocol instance.\r
   @param  Timeout            The timeout value of reset.\r
\r
-   \r
+\r
   @retval EFI_DEVICE_ERROR   AHCI controller is failed to complete hardware reset.\r
   @retval EFI_TIMEOUT        The reset operation is time out.\r
   @retval EFI_SUCCESS        AHCI controller is reset successfully.\r
@@ -1340,7 +1472,8 @@ AhciAtaSmartReturnStatusCheck (
              0,\r
              &AtaCommandBlock,\r
              AtaStatusBlock,\r
-             ATA_ATAPI_TIMEOUT\r
+             ATA_ATAPI_TIMEOUT,\r
+             NULL\r
              );\r
 \r
   if (EFI_ERROR (Status)) {\r
@@ -1390,7 +1523,7 @@ AhciAtaSmartSupport (
   IN EFI_AHCI_REGISTERS            *AhciRegisters,\r
   IN UINT8                         Port,\r
   IN UINT8                         PortMultiplier,\r
-  IN EFI_IDENTIFY_DATA             *IdentifyData,  \r
+  IN EFI_IDENTIFY_DATA             *IdentifyData,\r
   IN OUT EFI_ATA_STATUS_BLOCK      *AtaStatusBlock\r
   )\r
 {\r
@@ -1430,7 +1563,8 @@ AhciAtaSmartSupport (
                  0,\r
                  &AtaCommandBlock,\r
                  AtaStatusBlock,\r
-                 ATA_ATAPI_TIMEOUT\r
+                 ATA_ATAPI_TIMEOUT,\r
+                 NULL\r
                  );\r
 \r
 \r
@@ -1455,7 +1589,8 @@ AhciAtaSmartSupport (
                    0,\r
                    &AtaCommandBlock,\r
                    AtaStatusBlock,\r
-                   ATA_ATAPI_TIMEOUT\r
+                   ATA_ATAPI_TIMEOUT,\r
+                   NULL\r
                    );\r
 \r
         if (!EFI_ERROR (Status)) {\r
@@ -1469,7 +1604,7 @@ AhciAtaSmartSupport (
         }\r
       }\r
     }\r
-    DEBUG ((EFI_D_INFO, "Enabled S.M.A.R.T feature at port [%d] PortMultiplier [%d]!\n", \r
+    DEBUG ((EFI_D_INFO, "Enabled S.M.A.R.T feature at port [%d] PortMultiplier [%d]!\n",\r
             Port, PortMultiplier));\r
   }\r
 \r
@@ -1511,7 +1646,7 @@ AhciIdentify (
 \r
   ZeroMem (&AtaCommandBlock, sizeof (EFI_ATA_COMMAND_BLOCK));\r
   ZeroMem (&AtaStatusBlock, sizeof (EFI_ATA_STATUS_BLOCK));\r
-  \r
+\r
   AtaCommandBlock.AtaCommand     = ATA_CMD_IDENTIFY_DRIVE;\r
   AtaCommandBlock.AtaSectorCount = 1;\r
 \r
@@ -1527,7 +1662,8 @@ AhciIdentify (
              &AtaStatusBlock,\r
              Buffer,\r
              sizeof (EFI_IDENTIFY_DATA),\r
-             ATA_ATAPI_TIMEOUT\r
+             ATA_ATAPI_TIMEOUT, \r
+             NULL\r
              );\r
 \r
   return Status;\r
@@ -1565,7 +1701,7 @@ AhciIdentifyPacket (
   if (PciIo == NULL || AhciRegisters == NULL) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
-  \r
+\r
   ZeroMem (&AtaCommandBlock, sizeof (EFI_ATA_COMMAND_BLOCK));\r
   ZeroMem (&AtaStatusBlock, sizeof (EFI_ATA_STATUS_BLOCK));\r
 \r
@@ -1584,7 +1720,8 @@ AhciIdentifyPacket (
              &AtaStatusBlock,\r
              Buffer,\r
              sizeof (EFI_IDENTIFY_DATA),\r
-             ATA_ATAPI_TIMEOUT\r
+             ATA_ATAPI_TIMEOUT,\r
+             NULL\r
              );\r
 \r
   return Status;\r
@@ -1623,7 +1760,7 @@ AhciDeviceSetFeature (
 \r
   ZeroMem (&AtaCommandBlock, sizeof (EFI_ATA_COMMAND_BLOCK));\r
   ZeroMem (&AtaStatusBlock, sizeof (EFI_ATA_STATUS_BLOCK));\r
-  \r
+\r
   AtaCommandBlock.AtaCommand      = ATA_CMD_SET_FEATURES;\r
   AtaCommandBlock.AtaFeatures     = (UINT8) Feature;\r
   AtaCommandBlock.AtaFeaturesExp  = (UINT8) (Feature >> 8);\r
@@ -1641,7 +1778,8 @@ AhciDeviceSetFeature (
              0,\r
              &AtaCommandBlock,\r
              &AtaStatusBlock,\r
-             ATA_ATAPI_TIMEOUT\r
+             ATA_ATAPI_TIMEOUT, \r
+             NULL\r
              );\r
 \r
   return Status;\r
@@ -1708,7 +1846,7 @@ AhciPacketCommandExecute (
     Read = FALSE;\r
   }\r
 \r
-  if (Length == 0) {    \r
+  if (Length == 0) {\r
     Status = AhciNonDataTransfer (\r
                PciIo,\r
                AhciRegisters,\r
@@ -1718,7 +1856,8 @@ AhciPacketCommandExecute (
                Packet->CdbLength,\r
                &AtaCommandBlock,\r
                &AtaStatusBlock,\r
-               Packet->Timeout\r
+               Packet->Timeout, \r
+               NULL\r
                );\r
   } else {\r
     //\r
@@ -1742,7 +1881,8 @@ AhciPacketCommandExecute (
                  &AtaStatusBlock,\r
                  Buffer,\r
                  Length,\r
-                 Packet->Timeout\r
+                 Packet->Timeout, \r
+                 NULL\r
                  );\r
       if (!EFI_ERROR (Status)) {\r
         break;\r