]> git.proxmox.com Git - mirror_edk2.git/commitdiff
MdeModulePkg: ATA performance tuning.
authorerictian <erictian@6f19259b-4bc3-4df7-8a09-765794883524>
Thu, 3 Nov 2011 12:38:21 +0000 (12:38 +0000)
committererictian <erictian@6f19259b-4bc3-4df7-8a09-765794883524>
Thu, 3 Nov 2011 12:38:21 +0000 (12:38 +0000)
1. Boost IDE mode boot when slave device is absent.
2. Use D2H FIS to check if the PIO OUT/DMA IN/DMA OUT transfer is finished or error happened. ATA PIO IN has special check as it may just receive PIO SETUP FIS for success case.
3. Add command status register check for IDE DMA transfer.
4. ScsiDiskReadCapacity() in ScsiDisk should return EFI_SUCCESS if SENSE Data request is success.

Signed-off-by: erictian
Reviewed-by: rsun3
Reviewed-by: xdu2
Reviewed-by: mdkinney
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@12658 6f19259b-4bc3-4df7-8a09-765794883524

MdeModulePkg/Bus/Ata/AtaAtapiPassThru/AhciMode.c
MdeModulePkg/Bus/Ata/AtaAtapiPassThru/AhciMode.h
MdeModulePkg/Bus/Ata/AtaAtapiPassThru/AtaAtapiPassThru.h
MdeModulePkg/Bus/Ata/AtaAtapiPassThru/IdeMode.c
MdeModulePkg/Bus/Ata/AtaBusDxe/AtaBus.c
MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDisk.c

index 0bc54abbf7255512837cf0f71e30cd1f52fe50a4..a9b126acfa7fa92221667800d5b2d9fbd8ef1345 100644 (file)
@@ -133,24 +133,23 @@ AhciOrReg (
 }\r
 \r
 /**\r
-  Wait for memory set to the test value.\r
+  Wait for the value of the specified MMIO register set to the test value.\r
     \r
   @param  PciIo             The PCI IO protocol instance.\r
-  @param  Offset            The memory address to test.\r
+  @param  Offset            The MMIO address to test.\r
   @param  MaskValue         The mask value of memory.\r
   @param  TestValue         The test value of memory.\r
-  @param  Timeout           The time out value for wait memory set.\r
+  @param  Timeout           The time out value for wait memory set, 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
-  @retval EFI_SUCCESS       The memory is correct set.\r
+  @retval EFI_TIMEOUT       The MMIO setting is time out.\r
+  @retval EFI_SUCCESS       The MMIO is correct set.\r
 \r
 **/\r
 EFI_STATUS\r
 EFIAPI\r
-AhciWaitMemSet (\r
+AhciWaitMmioSet (\r
   IN  EFI_PCI_IO_PROTOCOL       *PciIo,\r
-  IN  UINT32                    Offset,\r
+  IN  UINT                    Offset,\r
   IN  UINT32                    MaskValue,\r
   IN  UINT32                    TestValue,\r
   IN  UINT64                    Timeout\r
@@ -159,10 +158,13 @@ AhciWaitMemSet (
   UINT32     Value;  \r
   UINT32     Delay;\r
 \r
-  Delay = (UINT32) (DivU64x32(Timeout, 1000) + 1);\r
+  Delay = (UINT32) (DivU64x32 (Timeout, 1000) + 1);\r
 \r
   do {\r
-    Value = AhciReadReg (PciIo, Offset) & MaskValue;\r
+    //\r
+    // Access PCI MMIO space to see if the value is the tested one.\r
+    //\r
+    Value = AhciReadReg (PciIo, (UINT32) Offset) & MaskValue;\r
 \r
     if (Value == TestValue) {\r
       return EFI_SUCCESS;\r
@@ -177,21 +179,70 @@ AhciWaitMemSet (
 \r
   } while (Delay > 0);\r
 \r
-  if (Delay == 0) {\r
-    return EFI_TIMEOUT;\r
-  }\r
+  return EFI_TIMEOUT;\r
+}\r
+\r
+/**\r
+  Wait for the value of the specified system memory set to the test value.\r
+    \r
+  @param  Address           The system memory address to test.\r
+  @param  MaskValue         The mask value of memory.\r
+  @param  TestValue         The test value of memory.\r
+  @param  Timeout           The time out value for wait memory set, uses 100ns as a unit.\r
+\r
+  @retval EFI_TIMEOUT       The system memory setting is time out.\r
+  @retval EFI_SUCCESS       The system memory is correct set.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+AhciWaitMemSet (\r
+  IN  EFI_PHYSICAL_ADDRESS      Address,\r
+  IN  UINT32                    MaskValue,\r
+  IN  UINT32                    TestValue,\r
+  IN  UINT64                    Timeout\r
+  )\r
+{\r
+  UINT32     Value;  \r
+  UINT32     Delay;\r
+\r
+  Delay = (UINT32) (DivU64x32 (Timeout, 1000) + 1);\r
+\r
+  do {\r
+    //\r
+    // Access sytem memory to see if the value is the tested one.\r
+    //\r
+    // The system memory pointed by Address will be updated by the\r
+    // SATA Host Controller, "volatile" is introduced to prevent\r
+    // compiler from optimizing the access to the memory address\r
+    // to only read once.\r
+    //\r
+    Value  = *(volatile UINT32 *) (UINTN) Address;\r
+    Value &= MaskValue;\r
+\r
+    if (Value == TestValue) {\r
+      return EFI_SUCCESS;\r
+    }\r
+\r
+    //\r
+    // Stall for 100 microseconds.\r
+    //\r
+    MicroSecondDelay (100);\r
+\r
+    Delay--;\r
 \r
-  return EFI_DEVICE_ERROR;\r
+  } while (Delay > 0);\r
+\r
+  return EFI_TIMEOUT;\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]       Address           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
+  @param[in, out]  RetryTimes        The retry times value for waitting memory set. If 0, then just try once.\r
 \r
   @retval EFI_NOTREADY      The memory is not set.\r
   @retval EFI_TIMEOUT       The memory setting retry times out.\r
@@ -201,24 +252,26 @@ AhciWaitMemSet (
 EFI_STATUS\r
 EFIAPI\r
 AhciCheckMemSet (\r
-  IN     EFI_PCI_IO_PROTOCOL       *PciIo,\r
-  IN     UINT32                    Offset,\r
+  IN     UINTN                     Address,\r
   IN     UINT32                    MaskValue,\r
   IN     UINT32                    TestValue,\r
-  IN OUT UINTN                     *RetryTimes\r
+  IN OUT UINTN                     *RetryTimes OPTIONAL\r
   )\r
 {\r
   UINT32     Value;\r
 \r
-  (*RetryTimes) --;\r
-  \r
-  Value = AhciReadReg (PciIo, Offset) & MaskValue;\r
+  if (RetryTimes != NULL) {\r
+    (*RetryTimes)--;\r
+  }\r
\r
+  Value  = *(volatile UINT32 *) Address;\r
+  Value &= MaskValue;\r
 \r
   if (Value == TestValue) {\r
     return EFI_SUCCESS;\r
   }\r
 \r
-  if ((*RetryTimes) == 0) {\r
+  if ((RetryTimes != NULL) && (*RetryTimes == 0)) {\r
     return EFI_TIMEOUT;\r
   } else {\r
     return EFI_NOT_READY;\r
@@ -338,7 +391,7 @@ AhciDumpPortStatus (
     \r
   @param      PciIo          The PCI IO protocol instance.\r
   @param      Port           The number of port.\r
-  @param      Timeout        The timeout value of enabling FIS.\r
+  @param      Timeout        The timeout value of enabling FIS, uses 100ns as a unit.\r
 \r
   @retval EFI_DEVICE_ERROR   The FIS enable setting fails.\r
   @retval EFI_TIMEOUT        The FIS enable setting is time out.\r
@@ -358,7 +411,7 @@ AhciEnableFisReceive (
   Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_CMD;\r
   AhciOrReg (PciIo, Offset, EFI_AHCI_PORT_CMD_FRE);\r
 \r
-  return AhciWaitMemSet (\r
+  return AhciWaitMmioSet (\r
            PciIo, \r
            Offset,\r
            EFI_AHCI_PORT_CMD_FR,\r
@@ -372,7 +425,7 @@ AhciEnableFisReceive (
 \r
   @param      PciIo          The PCI IO protocol instance.\r
   @param      Port           The number of port.\r
-  @param      Timeout        The timeout value of disabling FIS.\r
+  @param      Timeout        The timeout value of disabling FIS, uses 100ns as a unit.\r
 \r
   @retval EFI_DEVICE_ERROR   The FIS disable setting fails.\r
   @retval EFI_TIMEOUT        The FIS disable setting is time out.\r
@@ -410,7 +463,7 @@ AhciDisableFisReceive (
 \r
   AhciAndReg (PciIo, Offset, (UINT32)~(EFI_AHCI_PORT_CMD_FRE));\r
 \r
-  return AhciWaitMemSet (\r
+  return AhciWaitMmioSet (\r
            PciIo,\r
            Offset,\r
            EFI_AHCI_PORT_CMD_FR,\r
@@ -596,7 +649,7 @@ AhciBuildCommandFis (
   @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]       Timeout             The timeout value of non data transfer, uses 100ns as a unit.\r
   @param[in]       Task                Optional. Pointer to the ATA_NONBLOCK_TASK\r
                                        used by non-blocking mode.\r
 \r
@@ -626,15 +679,16 @@ AhciPioTransfer (
 {\r
   EFI_STATUS                    Status;\r
   UINTN                         FisBaseAddr;\r
-  UINT32                        Offset;\r
-  UINT32                        Value;\r
+  UINTN                         Offset;\r
   EFI_PHYSICAL_ADDRESS          PhyAddr;\r
   VOID                          *Map;\r
   UINTN                         MapLength;\r
   EFI_PCI_IO_PROTOCOL_OPERATION Flag;\r
   UINT32                        Delay;\r
   EFI_AHCI_COMMAND_FIS          CFis;\r
-  EFI_AHCI_COMMAND_LIST         CmdList;\r
+  EFI_AHCI_COMMAND_LIST         CmdList; \r
+  UINT32                        PortTfd;\r
+  UINT32                        PrdCount;\r
 \r
   if (Read) {\r
     Flag = EfiPciIoOperationBusMasterWrite;\r
@@ -697,56 +751,66 @@ AhciPioTransfer (
   // Check the status and wait the driver sending data\r
   //\r
   FisBaseAddr = (UINTN)AhciRegisters->AhciRFis + Port * sizeof (EFI_AHCI_RECEIVED_FIS);\r
-  //\r
-  // Wait device sends the PIO setup fis before data transfer\r
-  //\r
-  Delay = (UINT32) (DivU64x32(Timeout, 1000) + 1);\r
-  do {\r
-    Value = *(volatile UINT32 *) (FisBaseAddr + EFI_AHCI_PIO_FIS_OFFSET);\r
-\r
-    if ((Value & EFI_AHCI_FIS_TYPE_MASK) == EFI_AHCI_FIS_PIO_SETUP) {\r
-      break;\r
-    }\r
 \r
+  if (Read && (AtapiCommand == 0)) {\r
     //\r
-    // Stall for 100 microseconds.\r
+    // Wait device sends the PIO setup fis before data transfer\r
     //\r
-    MicroSecondDelay(100);\r
+    Status = EFI_TIMEOUT;\r
+    Delay  = (UINT32) (DivU64x32 (Timeout, 1000) + 1);\r
+    do {\r
+      Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_TFD;\r
+      PortTfd = AhciReadReg (PciIo, (UINT32) Offset);\r
+\r
+      if ((PortTfd & EFI_AHCI_PORT_TFD_ERR) != 0) {\r
+        Status = EFI_DEVICE_ERROR;\r
+        break;\r
+      }\r
+      Offset = FisBaseAddr + EFI_AHCI_PIO_FIS_OFFSET;\r
 \r
-    Delay--;\r
-  } while (Delay > 0);\r
+      Status = AhciCheckMemSet (Offset, EFI_AHCI_FIS_TYPE_MASK, EFI_AHCI_FIS_PIO_SETUP, 0);\r
+      if (!EFI_ERROR (Status)) {\r
+        PrdCount = *(volatile UINT32 *) (&(AhciRegisters->AhciCmdList[0].AhciCmdPrdbc));\r
+        if (PrdCount == DataCount) {\r
+          break;\r
+        }\r
+      }\r
 \r
-  if (Delay == 0) {\r
-    Status = EFI_TIMEOUT;\r
-    goto Exit;\r
-  }\r
+      Offset = FisBaseAddr + EFI_AHCI_D2H_FIS_OFFSET;\r
+      Status = AhciCheckMemSet (Offset, EFI_AHCI_FIS_TYPE_MASK, EFI_AHCI_FIS_REGISTER_D2H, 0);\r
+      if (!EFI_ERROR (Status)) {\r
+        Status = EFI_DEVICE_ERROR;\r
+        break;\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
+      //\r
+      // Stall for 100 microseconds.\r
+      //\r
+      MicroSecondDelay(100);\r
 \r
-  if (EFI_ERROR (Status)) {\r
-    goto Exit;\r
-  }\r
+      Delay--;\r
+    } while (Delay > 0);\r
+  } else {\r
+    //\r
+    // Wait for D2H Fis is received\r
+    //\r
+    Offset = FisBaseAddr + EFI_AHCI_D2H_FIS_OFFSET;\r
+    Status = AhciWaitMemSet (\r
+               Offset,\r
+               EFI_AHCI_FIS_TYPE_MASK,\r
+               EFI_AHCI_FIS_REGISTER_D2H,\r
+               Timeout\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_PSS,\r
-             EFI_AHCI_PORT_IS_PSS,\r
-             Timeout\r
-             );\r
-  if (EFI_ERROR (Status)) {\r
-    goto Exit;\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_TFD;\r
+    PortTfd = AhciReadReg (PciIo, (UINT32) Offset);\r
+    if ((PortTfd & EFI_AHCI_PORT_TFD_ERR) != 0) {\r
+      Status = EFI_DEVICE_ERROR;\r
+    }\r
   }\r
 \r
 Exit:\r
@@ -787,7 +851,7 @@ Exit:
   @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]       Timeout             The timeout value of non data transfer, uses 100ns as a unit.\r
   @param[in]       Task                Optional. Pointer to the ATA_NONBLOCK_TASK\r
                                        used by non-blocking mode.\r
 \r
@@ -810,22 +874,24 @@ AhciDmaTransfer (
   IN     EFI_ATA_COMMAND_BLOCK      *AtaCommandBlock,\r
   IN OUT EFI_ATA_STATUS_BLOCK       *AtaStatusBlock,\r
   IN OUT VOID                       *MemoryAddr,\r
-  IN     UINT                     DataCount,\r
+  IN     UINT32                     DataCount,\r
   IN     UINT64                     Timeout,\r
   IN     ATA_NONBLOCK_TASK          *Task\r
   )\r
 {\r
   EFI_STATUS                    Status;\r
-  UINT32                        Offset;\r
+  UINT                        Offset;\r
   EFI_PHYSICAL_ADDRESS          PhyAddr;\r
   VOID                          *Map;\r
   UINTN                         MapLength;\r
   EFI_PCI_IO_PROTOCOL_OPERATION Flag;\r
   EFI_AHCI_COMMAND_FIS          CFis;\r
   EFI_AHCI_COMMAND_LIST         CmdList;\r
+  UINTN                         FisBaseAddr;\r
+  UINT32                        PortTfd;\r
 \r
-  EFI_PCI_IO_PROTOCOL          *PciIo;\r
-  EFI_TPL                      OldTpl;\r
+  EFI_PCI_IO_PROTOCOL           *PciIo;\r
+  EFI_TPL                       OldTpl;\r
 \r
   Map   = NULL;\r
   PciIo = Instance->PciIo;\r
@@ -916,45 +982,28 @@ AhciDmaTransfer (
     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
+  FisBaseAddr = (UINTN)AhciRegisters->AhciRFis + Port * sizeof (EFI_AHCI_RECEIVED_FIS);\r
+  Offset      = FisBaseAddr + EFI_AHCI_D2H_FIS_OFFSET;\r
   if (Task != NULL) {\r
     //\r
     // For Non-blocking\r
     //\r
     Status = AhciCheckMemSet (\r
-               PciIo,\r
                Offset,\r
-               0xFFFFFFFF,\r
-               0,\r
+               EFI_AHCI_FIS_TYPE_MASK,\r
+               EFI_AHCI_FIS_REGISTER_D2H,\r
                (UINTN *) (&Task->RetryTimes)\r
                );\r
   } else {\r
     Status = AhciWaitMemSet (\r
-               PciIo,\r
                Offset,\r
-               0xFFFFFFFF,\r
-               0,\r
+               EFI_AHCI_FIS_TYPE_MASK,\r
+               EFI_AHCI_FIS_REGISTER_D2H,\r
                Timeout\r
                );\r
   }\r
@@ -963,31 +1012,10 @@ AhciDmaTransfer (
     goto Exit;\r
   }\r
 \r
-  Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_IS;\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
+  Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_TFD;\r
+  PortTfd = AhciReadReg (PciIo, (UINT32) Offset);\r
+  if ((PortTfd & EFI_AHCI_PORT_TFD_ERR) != 0) {\r
+    Status = EFI_DEVICE_ERROR;\r
   }\r
 \r
 Exit:\r
@@ -1039,7 +1067,7 @@ Exit:
   @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]       Timeout             The timeout value of non data transfer, uses 100ns as a unit.\r
   @param[in]       Task                Optional. Pointer to the ATA_NONBLOCK_TASK\r
                                        used by non-blocking mode.\r
 \r
@@ -1066,10 +1094,8 @@ AhciNonDataTransfer (
 {\r
   EFI_STATUS                   Status;\r
   UINTN                        FisBaseAddr;\r
-  UINT32                       Offset;\r
-  UINT32                       Value;\r
-  UINT32                       Delay;\r
-\r
+  UINTN                        Offset;\r
+  UINT32                       PortTfd;\r
   EFI_AHCI_COMMAND_FIS         CFis;\r
   EFI_AHCI_COMMAND_LIST        CmdList;\r
 \r
@@ -1110,39 +1136,23 @@ AhciNonDataTransfer (
   // Wait device sends the Response Fis\r
   //\r
   FisBaseAddr = (UINTN)AhciRegisters->AhciRFis + Port * sizeof (EFI_AHCI_RECEIVED_FIS);\r
-  //\r
-  // Wait device sends the PIO setup fis before data transfer\r
-  //\r
-  Delay = (UINT32) (DivU64x32(Timeout, 1000) + 1);\r
-  do {\r
-    Value = *(volatile UINT32 *) (FisBaseAddr + EFI_AHCI_D2H_FIS_OFFSET);\r
-\r
-    if ((Value & EFI_AHCI_FIS_TYPE_MASK) == EFI_AHCI_FIS_REGISTER_D2H) {\r
-      break;\r
-    }\r
+  Offset      = FisBaseAddr + EFI_AHCI_D2H_FIS_OFFSET;\r
+  Status      = AhciWaitMemSet (\r
+                  Offset,\r
+                  EFI_AHCI_FIS_TYPE_MASK,\r
+                  EFI_AHCI_FIS_REGISTER_D2H,\r
+                  Timeout\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
-    Status = EFI_TIMEOUT;\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_CI;\r
-\r
-  Status = AhciWaitMemSet (\r
-             PciIo,\r
-             Offset,\r
-             0xFFFFFFFF,\r
-             0,\r
-             Timeout\r
-             );\r
+  Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_TFD;\r
+  PortTfd = AhciReadReg (PciIo, (UINT32) Offset);\r
+  if ((PortTfd & EFI_AHCI_PORT_TFD_ERR) != 0) {\r
+    Status = EFI_DEVICE_ERROR;\r
+  }\r
 \r
 Exit:\r
   AhciStopCommand (\r
@@ -1167,7 +1177,7 @@ Exit:
     \r
   @param  PciIo              The PCI IO protocol instance.\r
   @param  Port               The number of port.\r
-  @param  Timeout            The timeout value of stop.\r
+  @param  Timeout            The timeout value of stop, uses 100ns as a unit.\r
    \r
   @retval EFI_DEVICE_ERROR   The command stop unsuccessfully.\r
   @retval EFI_TIMEOUT        The operation is time out.\r
@@ -1196,7 +1206,7 @@ AhciStopCommand (
     AhciAndReg (PciIo, Offset, (UINT32)~(EFI_AHCI_PORT_CMD_ST));\r
   }\r
 \r
-  return AhciWaitMemSet (\r
+  return AhciWaitMmioSet (\r
            PciIo,\r
            Offset,\r
            EFI_AHCI_PORT_CMD_CR,\r
@@ -1211,7 +1221,7 @@ AhciStopCommand (
   @param  PciIo              The PCI IO protocol instance.\r
   @param  Port               The number of port.\r
   @param  CommandSlot        The number of Command Slot.\r
-  @param  Timeout            The timeout value of start.\r
+  @param  Timeout            The timeout value of start, uses 100ns as a unit.\r
 \r
   @retval EFI_DEVICE_ERROR   The command start unsuccessfully.\r
   @retval EFI_TIMEOUT        The operation is time out.\r
@@ -1275,7 +1285,7 @@ AhciStartCommand (
       Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_CMD;\r
       AhciOrReg (PciIo, Offset, EFI_AHCI_PORT_CMD_CLO);\r
 \r
-      AhciWaitMemSet (\r
+      AhciWaitMmioSet (\r
         PciIo,\r
         Offset,\r
         EFI_AHCI_PORT_CMD_CLO,\r
@@ -1307,7 +1317,7 @@ AhciStartCommand (
 \r
   @param  PciIo              The PCI IO protocol instance.\r
   @param  Port               The number of port.\r
-  @param  Timeout            The timeout value of reset.\r
+  @param  Timeout            The timeout value of reset, uses 100ns as a unit.\r
    \r
   @retval EFI_DEVICE_ERROR   The port reset unsuccessfully\r
   @retval EFI_TIMEOUT        The reset operation is time out.\r
@@ -1353,7 +1363,7 @@ AhciPortReset (
   // Wait for communication to be re-established\r
   //\r
   Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_SSTS;\r
-  Status = AhciWaitMemSet (\r
+  Status = AhciWaitMmioSet (\r
              PciIo,\r
              Offset,\r
              EFI_AHCI_PORT_SSTS_DET_MASK,\r
@@ -1375,7 +1385,7 @@ AhciPortReset (
   Do AHCI HBA reset.\r
 \r
   @param  PciIo              The PCI IO protocol instance.\r
-  @param  Timeout            The timeout value of reset.\r
+  @param  Timeout            The timeout value of reset, uses 100ns as a unit.\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
@@ -2238,7 +2248,7 @@ AhciModeInitialization (
       //\r
       Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_CMD;\r
       AhciOrReg (PciIo, Offset, EFI_AHCI_PORT_CMD_FRE);\r
-      Status = AhciWaitMemSet (\r
+      Status = AhciWaitMmioSet (\r
                  PciIo, \r
                  Offset,\r
                  EFI_AHCI_PORT_CMD_FR,\r
@@ -2301,7 +2311,7 @@ AhciModeInitialization (
       // When the first D2H register FIS is received, the content of PxSIG register is updated.\r
       //\r
       Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_SIG;\r
-      Status = AhciWaitMemSet (\r
+      Status = AhciWaitMmioSet (\r
                  PciIo, \r
                  Offset,\r
                  0x0000FFFF,\r
index 032b97cd2f2226b7a32fb1b72071ede321434827..052e7837f5bd38878d3bdd07536733d6327f1293 100644 (file)
@@ -327,7 +327,7 @@ AhciPacketCommandExecute (
   @param  PciIo              The PCI IO protocol instance.\r
   @param  Port               The number of port.\r
   @param  CommandSlot        The number of CommandSlot.\r
-  @param  Timeout            The timeout value of start.\r
+  @param  Timeout            The timeout value of start, uses 100ns as a unit.\r
    \r
   @retval EFI_DEVICE_ERROR   The command start unsuccessfully.\r
   @retval EFI_TIMEOUT        The operation is time out.\r
@@ -348,7 +348,7 @@ AhciStartCommand (
     \r
   @param  PciIo              The PCI IO protocol instance.\r
   @param  Port               The number of port.\r
-  @param  Timeout            The timeout value of stop.\r
+  @param  Timeout            The timeout value of stop, uses 100ns as a unit.\r
    \r
   @retval EFI_DEVICE_ERROR   The command stop unsuccessfully.\r
   @retval EFI_TIMEOUT        The operation is time out.\r
index 0bbad0a01a5fe00754f339bd13a3ff180861e503..5be8d24bd73d2d870f5b4d2436b946d9a246ff7a 100644 (file)
@@ -101,7 +101,7 @@ typedef struct {
   //
   LIST_ENTRY                        DeviceList;
   UINT64                            OriginalPciAttributes;
-\r
+
   //
   // For AtaPassThru protocol, using the following bytes to record the previous call in 
   // GetNextPort()/GetNextDevice().
@@ -1078,7 +1078,7 @@ AhciModeInitialization (
   @param[in]       AtapiCommandLength  The length of the atapi command.
   @param[in]       AtaCommandBlock     The EFI_ATA_COMMAND_BLOCK data.
   @param[in, out]  AtaStatusBlock      The EFI_ATA_STATUS_BLOCK data.
-  @param[in]       Timeout             The timeout value of non data transfer.
+  @param[in]       Timeout             The timeout value of non data transfer, uses 100ns as a unit.
   @param[in]       Task                Optional. Pointer to the ATA_NONBLOCK_TASK
                                        used by non-blocking mode.
 
@@ -1118,7 +1118,7 @@ AhciNonDataTransfer (
   @param[in, out]  AtaStatusBlock      The EFI_ATA_STATUS_BLOCK data.
   @param[in, out]  MemoryAddr          The pointer to the data buffer.
   @param[in]       DataCount           The data count to be transferred.
-  @param[in]       Timeout             The timeout value of non data transfer.
+  @param[in]       Timeout             The timeout value of non data transfer, uses 100ns as a unit.
   @param[in]       Task                Optional. Pointer to the ATA_NONBLOCK_TASK
                                        used by non-blocking mode.
 
@@ -1141,7 +1141,7 @@ AhciDmaTransfer (
   IN     EFI_ATA_COMMAND_BLOCK        *AtaCommandBlock,
   IN OUT EFI_ATA_STATUS_BLOCK         *AtaStatusBlock,
   IN OUT VOID                         *MemoryAddr,
-  IN     UINT                       DataCount,
+  IN     UINT32                       DataCount,
   IN     UINT64                       Timeout, 
   IN     ATA_NONBLOCK_TASK            *Task
   );
@@ -1161,7 +1161,7 @@ AhciDmaTransfer (
   @param[in, out]  AtaStatusBlock      The EFI_ATA_STATUS_BLOCK data.
   @param[in, out]  MemoryAddr          The pointer to the data buffer.
   @param[in]       DataCount           The data count to be transferred.
-  @param[in]       Timeout             The timeout value of non data transfer.
+  @param[in]       Timeout             The timeout value of non data transfer, uses 100ns as a unit.
   @param[in]       Task                Optional. Pointer to the ATA_NONBLOCK_TASK
                                        used by non-blocking mode.
 
@@ -1198,7 +1198,7 @@ AhciPioTransfer (
   @param[in]      AtaCommandBlock  A pointer to EFI_ATA_COMMAND_BLOCK data
                                    structure.
   @param[in, out] AtaStatusBlock   A pointer to EFI_ATA_STATUS_BLOCK data structure.
-  @param[in]      Timeout          The time to complete the command.
+  @param[in]      Timeout          The time to complete the command, uses 100ns as a unit.
   @param[in]      Task             Optional. Pointer to the ATA_NONBLOCK_TASK
                                    used by non-blocking mode.
 
@@ -1232,7 +1232,7 @@ AtaNonDataCommandIn (
   @param[in]      DataLength       The length of  the data.
   @param[in]      AtaCommandBlock  A pointer to EFI_ATA_COMMAND_BLOCK data structure.
   @param[in, out] AtaStatusBlock   A pointer to EFI_ATA_STATUS_BLOCK data structure.
-  @param[in]      Timeout          The time to complete the command.
+  @param[in]      Timeout          The time to complete the command, uses 100ns as a unit.
   @param[in]      Task             Optional. Pointer to the ATA_NONBLOCK_TASK
                                    used by non-blocking mode.
 
@@ -1270,7 +1270,7 @@ AtaUdmaInOut (
                                    from host to device.
   @param[in]      AtaCommandBlock  A pointer to EFI_ATA_COMMAND_BLOCK data structure.
   @param[in, out] AtaStatusBlock   A pointer to EFI_ATA_STATUS_BLOCK data structure.
-  @param[in]      Timeout          The time to complete the command.
+  @param[in]      Timeout          The time to complete the command, uses 100ns as a unit.
   @param[in]      Task             Optional. Pointer to the ATA_NONBLOCK_TASK
                                    used by non-blocking mode.
   
index 79310fcb49a311033550d48d11180dbf5846a0b2..0604a9d4c3cbd60774a25615cb2925b9ce90091a 100644 (file)
@@ -17,7 +17,7 @@
 /**\r
   read a one-byte data from a IDE port.\r
 \r
-  @param  PciIo  The PCI IO protocol instance\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
@@ -51,7 +51,7 @@ IdeReadPortB (
 /**\r
   write a 1-byte data to a specific IDE port.\r
 \r
-  @param  PciIo  The PCI IO protocol instance\r
+  @param  PciIo  A pointer to EFI_PCI_IO_PROTOCOL data structure\r
   @param  Port   The IDE port to be writen\r
   @param  Data   The data to write to the port\r
 **/\r
@@ -81,7 +81,7 @@ IdeWritePortB (
 /**\r
   write a 1-word data to a specific IDE port.\r
 \r
-  @param  PciIo  PCI IO protocol instance\r
+  @param  PciIo  A pointer to EFI_PCI_IO_PROTOCOL data structure\r
   @param  Port   The IDE port to be writen\r
   @param  Data   The data to write to the port\r
 **/\r
@@ -111,7 +111,7 @@ IdeWritePortW (
 /**\r
   write a 2-word data to a specific IDE port.\r
 \r
-  @param  PciIo  PCI IO protocol instance\r
+  @param  PciIo  A pointer to EFI_PCI_IO_PROTOCOL data structure\r
   @param  Port   The IDE port to be writen\r
   @param  Data   The data to write to the port\r
 **/\r
@@ -143,7 +143,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
@@ -180,7 +180,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
@@ -217,7 +217,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
@@ -294,11 +294,10 @@ DumpAllIdeRegisters (
 }\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
@@ -312,7 +311,6 @@ CheckStatusRegister (
   IN  EFI_IDE_REGISTERS        *IdeRegisters\r
   )\r
 {\r
-  EFI_STATUS      Status;\r
   UINT8           StatusRegister;\r
 \r
   ASSERT (PciIo != NULL);\r
@@ -320,13 +318,14 @@ CheckStatusRegister (
 \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 +333,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
@@ -356,7 +355,6 @@ DRQClear (
 {\r
   UINT32  Delay;\r
   UINT8   StatusRegister;\r
-  UINT8   ErrorRegister;\r
 \r
   ASSERT (PciIo != NULL);\r
   ASSERT (IdeRegisters != NULL);\r
@@ -366,22 +364,18 @@ DRQClear (
     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
@@ -389,11 +383,7 @@ DRQClear (
 \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
   This function is used to poll for the DRQ bit clear in the Alternate\r
@@ -401,9 +391,9 @@ DRQClear (
   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
@@ -421,7 +411,6 @@ DRQClear2 (
 {\r
   UINT32  Delay;\r
   UINT8   AltRegister;\r
-  UINT8   ErrorRegister;\r
 \r
   ASSERT (PciIo != NULL);\r
   ASSERT (IdeRegisters != NULL);\r
@@ -431,17 +420,13 @@ DRQClear2 (
     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
@@ -454,11 +439,7 @@ DRQClear2 (
 \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,9 +449,9 @@ 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          DRQ bit set within the time out.\r
   @retval EFI_TIMEOUT          DRQ bit not set within the time out.\r
@@ -497,22 +478,27 @@ DRQReady (
   Delay = (UINT32) (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
+        return EFI_DEVICE_ERROR;\r
+      }\r
 \r
-      if ((ErrorRegister & ATA_ERRREG_ABRT) == ATA_ERRREG_ABRT) {\r
-        return EFI_ABORTED;\r
+      if ((StatusRegister & ATA_STSREG_DRQ) == ATA_STSREG_DRQ) {\r
+        return EFI_SUCCESS;\r
+      } else {\r
+        return EFI_NOT_READY;\r
       }\r
     }\r
 \r
@@ -524,20 +510,16 @@ DRQReady (
     Delay--;\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
   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
   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
+  @param Timeout          The time to complete the command, uses 100ns as a unit.\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
@@ -564,21 +546,26 @@ DRQReady2 (
 \r
   do {\r
     //\r
-    //  Read Alternate Status Register will not clear interrupt status\r
+    // Read Alternate Status Register will not clear interrupt status\r
     //\r
     AltRegister = IdeReadPortB (PciIo, IdeRegisters->AltOrDev);\r
     //\r
-    // BSY == 0 , DRQ == 1\r
+    // Wait for BSY == 0, then judge if DRQ is clear or ERR is set\r
     //\r
-    if ((AltRegister & (ATA_STSREG_BSY | ATA_STSREG_DRQ)) == ATA_STSREG_DRQ) {\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
+        return EFI_DEVICE_ERROR;\r
+      }\r
 \r
-      if ((ErrorRegister & ATA_ERRREG_ABRT) == ATA_ERRREG_ABRT) {\r
-        return EFI_ABORTED;\r
+      if ((AltRegister & ATA_STSREG_DRQ) == ATA_STSREG_DRQ) {\r
+        return EFI_SUCCESS;\r
+      } else {\r
+        return EFI_NOT_READY;\r
       }\r
     }\r
 \r
@@ -590,11 +577,7 @@ DRQReady2 (
     Delay--;\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
@@ -602,9 +585,9 @@ DRQReady2 (
   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
 \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         DRDY bit set within the time out.\r
   @retval EFI_TIMEOUT         DRDY bit not set within the time out.\r
@@ -630,17 +613,22 @@ DRDYReady (
   do {\r
     StatusRegister = IdeReadPortB (PciIo, IdeRegisters->CmdOrStatus);\r
     //\r
-    //  BSY == 0 , DRDY == 1\r
+    // Wait for BSY == 0, then judge if DRDY is set or ERR is set\r
     //\r
-    if ((StatusRegister & (ATA_STSREG_DRDY | ATA_STSREG_BSY)) == ATA_STSREG_DRDY) {\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
+        return EFI_DEVICE_ERROR;\r
+      }\r
 \r
-      if ((ErrorRegister & ATA_ERRREG_ABRT) == ATA_ERRREG_ABRT) {\r
-        return EFI_ABORTED;\r
+      if ((StatusRegister & ATA_STSREG_DRDY) == ATA_STSREG_DRDY) {\r
+        return EFI_SUCCESS;\r
+      } else {\r
+        return EFI_DEVICE_ERROR;\r
       }\r
     }\r
 \r
@@ -652,11 +640,7 @@ DRDYReady (
     Delay--;\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
@@ -664,9 +648,9 @@ DRDYReady (
   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 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      DRDY bit set within the time out.\r
   @retval EFI_TIMEOUT      DRDY bit not set within the time out.\r
@@ -693,17 +677,22 @@ DRDYReady2 (
   do {\r
     AltRegister = IdeReadPortB (PciIo, IdeRegisters->AltOrDev);\r
     //\r
-    //  BSY == 0 , DRDY == 1\r
+    // Wait for BSY == 0, then judge if DRDY is set 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
+        return EFI_DEVICE_ERROR;\r
+      }\r
 \r
-      if ((ErrorRegister & ATA_ERRREG_ABRT) == ATA_ERRREG_ABRT) {\r
-        return EFI_ABORTED;\r
+      if ((AltRegister & ATA_STSREG_DRDY) == ATA_STSREG_DRDY) {\r
+        return EFI_SUCCESS;\r
+      } else {\r
+        return EFI_DEVICE_ERROR;\r
       }\r
     }\r
 \r
@@ -715,11 +704,7 @@ DRDYReady2 (
     Delay--;\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
@@ -728,7 +713,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
@@ -754,7 +739,7 @@ WaitForBSYClear (
     StatusRegister = IdeReadPortB (PciIo, IdeRegisters->CmdOrStatus);\r
 \r
     if ((StatusRegister & ATA_STSREG_BSY) == 0x00) {\r
-      break;\r
+      return EFI_SUCCESS;\r
     }\r
 \r
     //\r
@@ -766,11 +751,7 @@ WaitForBSYClear (
 \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
@@ -779,7 +760,7 @@ WaitForBSYClear (
 \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
@@ -805,7 +786,7 @@ WaitForBSYClear2 (
     AltStatusRegister = IdeReadPortB (PciIo, IdeRegisters->AltOrDev);\r
 \r
     if ((AltStatusRegister & ATA_STSREG_BSY) == 0x00) {\r
-      break;\r
+      return EFI_SUCCESS;\r
     }\r
 \r
     //\r
@@ -817,11 +798,7 @@ WaitForBSYClear2 (
 \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
@@ -978,7 +955,7 @@ GetIdeRegisterIoAddr (
 \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       Soft reset completes successfully.\r
   @retval EFI_DEVICE_ERROR  Any step during the reset process is failed.\r
@@ -1038,7 +1015,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
@@ -1134,7 +1111,7 @@ 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
@@ -1268,7 +1245,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
@@ -1334,7 +1311,7 @@ Exit:
   Wait for memory to be set.\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
 \r
   @retval EFI_DEVICE_ERROR  The memory is not set.\r
   @retval EFI_TIMEOUT       The memory setting is time out.\r
@@ -1344,18 +1321,25 @@ Exit:
 EFI_STATUS\r
 AtaUdmStatusWait (\r
   IN     EFI_PCI_IO_PROTOCOL       *PciIo,\r
-  IN     UINT16                    PortNum\r
+  IN     EFI_IDE_REGISTERS         *IdeRegisters\r
  ) \r
 {\r
   UINT8                         RegisterValue;\r
   EFI_STATUS                    Status;\r
+  UINT16                        IoPortForBmis;\r
   UINT64                        Timeout;\r
 \r
   Timeout = 2000;\r
 \r
   while (TRUE) {\r
-    RegisterValue  = IdeReadPortB (PciIo, PortNum);\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
       Status = EFI_DEVICE_ERROR;\r
@@ -1382,7 +1366,7 @@ AtaUdmStatusWait (
   @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
@@ -1394,13 +1378,22 @@ EFI_STATUS
 AtaUdmStatusCheck (\r
   IN     EFI_PCI_IO_PROTOCOL        *PciIo,\r
   IN     ATA_NONBLOCK_TASK          *Task,\r
-  IN     UINT16                     PortForBit\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
@@ -1435,7 +1428,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
@@ -1652,7 +1645,7 @@ AtaUdmaInOut (
     //\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
@@ -1680,6 +1673,11 @@ 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
     // Set START bit of BMIC register\r
     //\r
@@ -1709,9 +1707,9 @@ AtaUdmaInOut (
   // 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);\r
   }\r
 \r
   //\r
@@ -1829,7 +1827,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
@@ -1933,7 +1932,7 @@ 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
@@ -1951,7 +1950,7 @@ AtaPacketReadWrite (
   @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
+  @param[in] Timeout         The timeout value to execute this cmd, uses 100ns as a unit.\r
 \r
   @retval EFI_SUCCESS        Send out the ATAPI packet command successfully.\r
   @retval EFI_DEVICE_ERROR   The device failed to send data.\r
@@ -2207,7 +2206,6 @@ 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
index eb6502298623b803f0563f0d468fe0094d43503f..27d0a1c3dbd3fe1208546da85ce32d69055dc2ab 100644 (file)
@@ -506,7 +506,7 @@ UnregisterAtaDevice (
   }\r
 \r
   ReleaseAtaResources (AtaDevice);\r
-  return EFI_SUCCESS;\r
+  return Status;\r
 }\r
 \r
 \r
index e8c8ee7a4b064d81ed32facf860170340f9681cc..0e8aa34ad63c61e6dc26d370db253d7b29c0cc9c 100644 (file)
@@ -1265,7 +1265,7 @@ DetectMediaParsingSenseKeys (
   @param  NumberOfSenseKeys  The number of sense key\r
 \r
   @retval EFI_DEVICE_ERROR   Indicates that error occurs\r
-  @retval EFI_SUCCESS        Successfully to read capacity\r
+  @retval EFI_SUCCESS        Successfully to read capacity or sense data is received.\r
 \r
 **/\r
 EFI_STATUS\r
@@ -1402,8 +1402,7 @@ ScsiDiskReadCapacity (
               TRUE\r
               );\r
     if (!EFI_ERROR (Status)) {\r
-      *NeedRetry = TRUE;\r
-      return EFI_DEVICE_ERROR;\r
+      return EFI_SUCCESS;\r
     }\r
 \r
     if (!*NeedRetry) {\r