]> git.proxmox.com Git - mirror_edk2.git/commitdiff
MdeModulePkg/AtaAtapiPassThru: Handle timeout 0 as indefinitely wait to strictly...
authorTian, Feng <feng.tian@intel.com>
Thu, 15 May 2014 07:09:14 +0000 (07:09 +0000)
committererictian <erictian@6f19259b-4bc3-4df7-8a09-765794883524>
Thu, 15 May 2014 07:09:14 +0000 (07:09 +0000)
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Tian, Feng <feng.tian@intel.com>
Reviewed-by: Li, Elvin <elvin.li@intel.com>
git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@15534 6f19259b-4bc3-4df7-8a09-765794883524

MdeModulePkg/Bus/Ata/AtaAtapiPassThru/AhciMode.c
MdeModulePkg/Bus/Ata/AtaAtapiPassThru/AtaAtapiPassThru.c
MdeModulePkg/Bus/Ata/AtaAtapiPassThru/AtaAtapiPassThru.h
MdeModulePkg/Bus/Ata/AtaAtapiPassThru/IdeMode.c

index 950b5da03882ccfec156d042b082653e04c6c79f..df22d517fddd93af51d8a3293dcc3578f934daa2 100644 (file)
@@ -156,9 +156,16 @@ AhciWaitMmioSet (
   )\r
 {\r
   UINT32     Value;\r
-  UINT32     Delay;\r
+  UINT64     Delay;\r
+  BOOLEAN    InfiniteWait;\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
 \r
   do {\r
     //\r
@@ -177,7 +184,7 @@ AhciWaitMmioSet (
 \r
     Delay--;\r
 \r
-  } while (Delay > 0);\r
+  } while (InfiniteWait || (Delay > 0));\r
 \r
   return EFI_TIMEOUT;\r
 }\r
@@ -204,9 +211,16 @@ AhciWaitMemSet (
   )\r
 {\r
   UINT32     Value;\r
-  UINT32     Delay;\r
+  UINT64     Delay;\r
+  BOOLEAN    InfiniteWait;\r
+\r
+  if (Timeout == 0) {\r
+    InfiniteWait = TRUE;\r
+  } else {\r
+    InfiniteWait = FALSE;\r
+  }\r
 \r
-  Delay = (UINT32) (DivU64x32 (Timeout, 1000) + 1);\r
+  Delay =  DivU64x32 (Timeout, 1000) + 1;\r
 \r
   do {\r
     //\r
@@ -231,7 +245,7 @@ AhciWaitMemSet (
 \r
     Delay--;\r
 \r
-  } while (Delay > 0);\r
+  } while (InfiniteWait || (Delay > 0));\r
 \r
   return EFI_TIMEOUT;\r
 }\r
@@ -242,7 +256,8 @@ AhciWaitMemSet (
   @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. If 0, then just try once.\r
+  @param[in, out]  Task              Optional. Pointer to the ATA_NONBLOCK_TASK used by\r
+                                     non-blocking mode. If NULL, 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
@@ -255,13 +270,13 @@ AhciCheckMemSet (
   IN     UINTN                     Address,\r
   IN     UINT32                    MaskValue,\r
   IN     UINT32                    TestValue,\r
-  IN OUT UINTN                     *RetryTimes OPTIONAL\r
+  IN OUT ATA_NONBLOCK_TASK         *Task\r
   )\r
 {\r
   UINT32     Value;\r
 \r
-  if (RetryTimes != NULL) {\r
-    (*RetryTimes)--;\r
+  if (Task != NULL) {\r
+    Task->RetryTimes--;\r
   }\r
 \r
   Value  = *(volatile UINT32 *) Address;\r
@@ -271,7 +286,7 @@ AhciCheckMemSet (
     return EFI_SUCCESS;\r
   }\r
 \r
-  if ((RetryTimes != NULL) && (*RetryTimes == 0)) {\r
+  if ((Task != NULL) && !Task->InfiniteWait && (Task->RetryTimes == 0)) {\r
     return EFI_TIMEOUT;\r
   } else {\r
     return EFI_NOT_READY;\r
@@ -683,11 +698,18 @@ AhciPioTransfer (
   VOID                          *Map;\r
   UINTN                         MapLength;\r
   EFI_PCI_IO_PROTOCOL_OPERATION Flag;\r
-  UINT32                        Delay;\r
+  UINT64                        Delay;\r
   EFI_AHCI_COMMAND_FIS          CFis;\r
   EFI_AHCI_COMMAND_LIST         CmdList;\r
   UINT32                        PortTfd;\r
   UINT32                        PrdCount;\r
+  BOOLEAN                       InfiniteWait;\r
+\r
+  if (Timeout == 0) {\r
+    InfiniteWait = TRUE;\r
+  } else {\r
+    InfiniteWait = FALSE;\r
+  }\r
 \r
   if (Read) {\r
     Flag = EfiPciIoOperationBusMasterWrite;\r
@@ -756,11 +778,11 @@ AhciPioTransfer (
     // Wait device sends the PIO setup fis before data transfer\r
     //\r
     Status = EFI_TIMEOUT;\r
-    Delay  = (UINT32) (DivU64x32 (Timeout, 1000) + 1);\r
+    Delay  = DivU64x32 (Timeout, 1000) + 1;\r
     do {\r
       Offset = FisBaseAddr + EFI_AHCI_PIO_FIS_OFFSET;\r
 \r
-      Status = AhciCheckMemSet (Offset, EFI_AHCI_FIS_TYPE_MASK, EFI_AHCI_FIS_PIO_SETUP, 0);\r
+      Status = AhciCheckMemSet (Offset, EFI_AHCI_FIS_TYPE_MASK, EFI_AHCI_FIS_PIO_SETUP, NULL);\r
       if (!EFI_ERROR (Status)) {\r
         Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + EFI_AHCI_PORT_TFD;\r
         PortTfd = AhciReadReg (PciIo, (UINT32) Offset);\r
@@ -780,7 +802,7 @@ AhciPioTransfer (
       }\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
+      Status = AhciCheckMemSet (Offset, EFI_AHCI_FIS_TYPE_MASK, EFI_AHCI_FIS_REGISTER_D2H, NULL);\r
       if (!EFI_ERROR (Status)) {\r
         Status = EFI_DEVICE_ERROR;\r
         break;\r
@@ -792,7 +814,7 @@ AhciPioTransfer (
       MicroSecondDelay(100);\r
 \r
       Delay--;\r
-    } while (Delay > 0);\r
+    } while (InfiniteWait || (Delay > 0));\r
   } else {\r
     //\r
     // Wait for D2H Fis is received\r
@@ -924,7 +946,6 @@ AhciDmaTransfer (
     //\r
     if (Task != NULL) {\r
       Task->IsStart      = TRUE;\r
-      Task->RetryTimes   = (UINT32) (DivU64x32(Timeout, 1000) + 1);\r
     }\r
     if (Read) {\r
       Flag = EfiPciIoOperationBusMasterWrite;\r
@@ -1000,7 +1021,7 @@ AhciDmaTransfer (
                Offset,\r
                EFI_AHCI_FIS_TYPE_MASK,\r
                EFI_AHCI_FIS_REGISTER_D2H,\r
-               (UINTN *) (&Task->RetryTimes)\r
+               Task\r
                );\r
   } else {\r
     Status = AhciWaitMemSet (\r
@@ -1402,14 +1423,14 @@ AhciReset (
   IN  UINT64                    Timeout\r
   )\r
 {\r
-  UINT32                 Delay;\r
+  UINT64                 Delay;\r
   UINT32                 Value;\r
 \r
   AhciOrReg (PciIo, EFI_AHCI_GHC_OFFSET, EFI_AHCI_GHC_ENABLE);\r
 \r
   AhciOrReg (PciIo, EFI_AHCI_GHC_OFFSET, EFI_AHCI_GHC_RESET);\r
 \r
-  Delay = (UINT32) (DivU64x32(Timeout, 1000) + 1);\r
+  Delay = DivU64x32(Timeout, 1000) + 1;\r
 \r
   do {\r
     Value = AhciReadReg(PciIo, EFI_AHCI_GHC_OFFSET);\r
index a3b9ccd484f7be880bfcccfcf2948761f52a2da8..12a40d413e09ead34287172ef4fea145c53d418d 100644 (file)
@@ -1339,7 +1339,12 @@ AtaPassThruPassThru (
     Task->Packet         = Packet;\r
     Task->Event          = Event;\r
     Task->IsStart        = FALSE;\r
-    Task->RetryTimes     = 0;\r
+    Task->RetryTimes     = DivU64x32(Packet->Timeout, 1000) + 1;\r
+    if (Packet->Timeout == 0) {\r
+      Task->InfiniteWait = TRUE;\r
+    } else {\r
+      Task->InfiniteWait = FALSE;\r
+    }\r
 \r
     OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
     InsertTailList (&Instance->NonBlockingTaskList, &Task->Link);\r
index 0d93e5446752daeacb63d8ca2378c1c19ef9d79a..6f3407c01aa8ae0d1e05d47810fe794684336065 100644 (file)
@@ -135,10 +135,11 @@ struct _ATA_NONBLOCK_TASK {
   BOOLEAN                           IsStart;\r
   EFI_EVENT                         Event;\r
   UINT64                            RetryTimes;\r
-  VOID                              *Map; // Pointer to map.\r
-  VOID                              *TableMap;// Pointer to PRD table map.\r
+  BOOLEAN                           InfiniteWait;\r
+  VOID                              *Map;            // Pointer to map.\r
+  VOID                              *TableMap;       // Pointer to PRD table map.\r
   EFI_ATA_DMA_PRD                   *MapBaseAddress; //  Pointer to range Base address for Map.\r
-  UINTN                             PageCount;      //  The page numbers used by PCIO freebuffer.\r
+  UINTN                             PageCount;       //  The page numbers used by PCIO freebuffer.\r
 };\r
 \r
 //\r
index 5f362d1e1513357e5ec10133e36ef8e8f58e40b4..e5beea65a22d1489613eb4987db133b71d3a3998 100644 (file)
@@ -353,13 +353,20 @@ DRQClear (
   IN  UINT64                    Timeout\r
   )\r
 {\r
-  UINT32  Delay;\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
@@ -381,7 +388,7 @@ DRQClear (
 \r
     Delay--;\r
 \r
-  } while (Delay > 0);\r
+  } while (InfiniteWait || (Delay > 0));\r
 \r
   return EFI_TIMEOUT;\r
 }\r
@@ -409,13 +416,20 @@ DRQClear2 (
   IN  UINT64               Timeout\r
   )\r
 {\r
-  UINT32  Delay;\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
@@ -437,7 +451,7 @@ DRQClear2 (
 \r
     Delay--;\r
 \r
-  } while (Delay > 0);\r
+  } while (InfiniteWait || (Delay > 0));\r
 \r
   return EFI_TIMEOUT;\r
 }\r
@@ -468,14 +482,21 @@ DRQReady (
   IN  UINT64               Timeout\r
   )\r
 {\r
-  UINT32  Delay;\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
@@ -508,7 +529,7 @@ DRQReady (
     MicroSecondDelay (100);\r
 \r
     Delay--;\r
-  } while (Delay > 0);\r
+  } while (InfiniteWait || (Delay > 0));\r
 \r
   return EFI_TIMEOUT;\r
 }\r
@@ -535,14 +556,21 @@ DRQReady2 (
   IN  UINT64               Timeout\r
   )\r
 {\r
-  UINT32  Delay;\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
+  if (Timeout == 0) {\r
+    InfiniteWait = TRUE;\r
+  } else {\r
+    InfiniteWait = FALSE;\r
+  }\r
+\r
+  Delay = DivU64x32(Timeout, 1000) + 1;\r
 \r
   do {\r
     //\r
@@ -575,7 +603,7 @@ DRQReady2 (
     MicroSecondDelay (100);\r
 \r
     Delay--;\r
-  } while (Delay > 0);\r
+  } while (InfiniteWait || (Delay > 0));\r
 \r
   return EFI_TIMEOUT;\r
 }\r
@@ -602,14 +630,21 @@ DRDYReady (
   IN  UINT64               Timeout\r
   )\r
 {\r
-  UINT32  Delay;\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
     StatusRegister = IdeReadPortB (PciIo, IdeRegisters->CmdOrStatus);\r
     //\r
@@ -638,7 +673,7 @@ DRDYReady (
     MicroSecondDelay (100);\r
 \r
     Delay--;\r
-  } while (Delay > 0);\r
+  } while (InfiniteWait || (Delay > 0));\r
 \r
   return EFI_TIMEOUT;\r
 }\r
@@ -666,14 +701,21 @@ DRDYReady2 (
   IN  UINT64               Timeout\r
   )\r
 {\r
-  UINT32  Delay;\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
+  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
@@ -702,7 +744,7 @@ DRDYReady2 (
     MicroSecondDelay (100);\r
 \r
     Delay--;\r
-  } while (Delay > 0);\r
+  } while (InfiniteWait || (Delay > 0));\r
 \r
   return EFI_TIMEOUT;\r
 }\r
@@ -728,13 +770,20 @@ WaitForBSYClear (
   IN  UINT64               Timeout\r
   )\r
 {\r
-  UINT32  Delay;\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
@@ -749,7 +798,7 @@ WaitForBSYClear (
 \r
     Delay--;\r
 \r
-  } while (Delay > 0);\r
+  } while (InfiniteWait || (Delay > 0));\r
 \r
   return EFI_TIMEOUT;\r
 }\r
@@ -775,13 +824,20 @@ WaitForBSYClear2 (
   IN  UINT64               Timeout\r
   )\r
 {\r
-  UINT32  Delay;\r
+  UINT64  Delay;\r
   UINT8   AltStatusRegister;\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
     AltStatusRegister = IdeReadPortB (PciIo, IdeRegisters->AltOrDev);\r
 \r
@@ -796,7 +852,7 @@ WaitForBSYClear2 (
 \r
     Delay--;\r
 \r
-  } while (Delay > 0);\r
+  } while (InfiniteWait || (Delay > 0));\r
 \r
   return EFI_TIMEOUT;\r
 }\r
@@ -1312,6 +1368,7 @@ Exit:
 \r
   @param[in]  PciIo           The PCI IO protocol instance.\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
@@ -1320,18 +1377,26 @@ Exit:
 **/\r
 EFI_STATUS\r
 AtaUdmStatusWait (\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
+  IN  UINT64                    Timeout\r
  )\r
 {\r
   UINT8                         RegisterValue;\r
   EFI_STATUS                    Status;\r
   UINT16                        IoPortForBmis;\r
-  UINT64                        Timeout;\r
+  UINT64                        Delay;\r
+  BOOLEAN                       InfiniteWait;\r
+\r
+  if (Timeout == 0) {\r
+    InfiniteWait = TRUE;\r
+  } else {\r
+    InfiniteWait = FALSE;\r
+  }\r
 \r
-  Timeout = 2000;\r
+  Delay = DivU64x32 (Timeout, 1000) + 1;\r
 \r
-  while (TRUE) {\r
+  do {\r
     Status = CheckStatusRegister (PciIo, IdeRegisters);\r
     if (EFI_ERROR (Status)) {\r
       Status = EFI_DEVICE_ERROR;\r
@@ -1351,11 +1416,11 @@ AtaUdmStatusWait (
       break;\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
@@ -1404,7 +1469,7 @@ AtaUdmStatusCheck (
     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
@@ -1664,12 +1729,6 @@ AtaUdmaInOut (
     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
@@ -1703,14 +1762,11 @@ AtaUdmaInOut (
 \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, IdeRegisters);\r
   } else {\r
-    Status = AtaUdmStatusWait (PciIo, IdeRegisters);\r
+    Status = AtaUdmStatusWait (PciIo, IdeRegisters, Timeout);\r
   }\r
 \r
   //\r