]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Bus/Pci/UhciDxe/UhciSched.c
when timeout is 0, infinite loop on the timeout request to follow UEFI spec
[mirror_edk2.git] / MdeModulePkg / Bus / Pci / UhciDxe / UhciSched.c
index 759f7a05cb73c75b8faba7594793c458848111c6..0d97bccabadd52c6b84da016a8d48210a9416348 100644 (file)
@@ -2,8 +2,8 @@
 \r
   The EHCI register operation routines.\r
 \r
-Copyright (c) 2007 - 2009, Intel Corporation\r
-All rights reserved. This program and the accompanying materials\r
+Copyright (c) 2007 - 2011, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials\r
 are licensed and made available under the terms and conditions of the BSD License\r
 which accompanies this distribution.  The full text of the license may be found at\r
 http://opensource.org/licenses/bsd-license.php\r
@@ -38,7 +38,6 @@ UhciInitFrameList (
   UINTN                 Pages;\r
   UINTN                 Bytes;\r
   UINTN                 Index;\r
-  UINTN                 Len;\r
   EFI_PHYSICAL_ADDRESS  PhyAddr;\r
 \r
   //\r
@@ -77,10 +76,15 @@ UhciInitFrameList (
     goto ON_ERROR;\r
   }\r
 \r
-  Uhc->FrameBase           = (UINT32 *) (UINTN) Buffer; // Cpu memory address\r
-  Uhc->FrameBasePciMemAddr = (UINT32 *) (UINTN) MappedAddr; // Pci memory address\r
+  Uhc->FrameBase           = (UINT32 *) (UINTN) Buffer;\r
   Uhc->FrameMapping        = Mapping;\r
 \r
+  //\r
+  // Tell the Host Controller where the Frame List lies,\r
+  // by set the Frame List Base Address Register.\r
+  //\r
+  UhciSetFrameListBaseAddr (Uhc->PciIo, (VOID *) (UINTN) MappedAddr);\r
+\r
   //\r
   // Allocate the QH used by sync interrupt/control/bulk transfer.\r
   // FS ctrl/bulk queue head is set to loopback so additional BW\r
@@ -104,30 +108,11 @@ UhciInitFrameList (
   // Each frame entry is linked to this sequence of QH. These QH\r
   // will remain on the schedul, never got removed\r
   //\r
-  Len    = sizeof (UHCI_QH_HW);\r
-  Status = Uhc->PciIo->Map (\r
-                         Uhc->PciIo,\r
-                         EfiPciIoOperationBusMasterRead,\r
-                         Uhc->CtrlQh,\r
-                         &Len,\r
-                         &PhyAddr,\r
-                         &Mapping\r
-                         );\r
-  ASSERT (!EFI_ERROR (Status));\r
-\r
+  PhyAddr = UsbHcGetPciAddressForHostMem (Uhc->MemPool, Uhc->CtrlQh, sizeof (UHCI_QH_HW));\r
   Uhc->SyncIntQh->QhHw.HorizonLink  = QH_HLINK (PhyAddr, FALSE);\r
   Uhc->SyncIntQh->NextQh            = Uhc->CtrlQh;\r
 \r
-  Status = Uhc->PciIo->Map (\r
-                         Uhc->PciIo,\r
-                         EfiPciIoOperationBusMasterRead,\r
-                         Uhc->BulkQh,\r
-                         &Len,\r
-                         &PhyAddr,\r
-                         &Mapping\r
-                         );\r
-  ASSERT (!EFI_ERROR (Status));\r
-\r
+  PhyAddr = UsbHcGetPciAddressForHostMem (Uhc->MemPool, Uhc->BulkQh, sizeof (UHCI_QH_HW));\r
   Uhc->CtrlQh->QhHw.HorizonLink     = QH_HLINK (PhyAddr, FALSE);\r
   Uhc->CtrlQh->NextQh               = Uhc->BulkQh;\r
 \r
@@ -140,27 +125,18 @@ UhciInitFrameList (
 \r
   Uhc->BulkQh->NextQh               = NULL;\r
 \r
-  Len    = sizeof (UHCI_QH_HW);\r
-  Status = Uhc->PciIo->Map (\r
-                         Uhc->PciIo,\r
-                         EfiPciIoOperationBusMasterRead,\r
-                         Uhc->SyncIntQh,\r
-                         &Len,\r
-                         &PhyAddr,\r
-                         &Mapping\r
-                         );\r
-  ASSERT (!EFI_ERROR (Status));\r
+  Uhc->FrameBaseHostAddr = AllocateZeroPool (4096);\r
+  if (Uhc->FrameBaseHostAddr == NULL) {\r
+    Status = EFI_OUT_OF_RESOURCES;\r
+    goto ON_ERROR;\r
+  }\r
 \r
+  PhyAddr = UsbHcGetPciAddressForHostMem (Uhc->MemPool, Uhc->SyncIntQh, sizeof (UHCI_QH_HW));\r
   for (Index = 0; Index < UHCI_FRAME_NUM; Index++) {\r
-    Uhc->FrameBase[Index] = QH_HLINK (Uhc->SyncIntQh, FALSE);\r
-    Uhc->FrameBasePciMemAddr[Index] = QH_HLINK (PhyAddr, FALSE);\r
+    Uhc->FrameBase[Index] = QH_HLINK (PhyAddr, FALSE);\r
+    Uhc->FrameBaseHostAddr[Index] = (UINT32)(UINTN)Uhc->SyncIntQh;\r
   }\r
 \r
-  //\r
-  // Tell the Host Controller where the Frame List lies,\r
-  // by set the Frame List Base Address Register.\r
-  //\r
-  UhciSetFrameListBaseAddr (Uhc->PciIo, (VOID *) (Uhc->FrameBasePciMemAddr));\r
   return EFI_SUCCESS;\r
 \r
 ON_ERROR:\r
@@ -205,6 +181,10 @@ UhciDestoryFrameList (
                 (VOID *) Uhc->FrameBase\r
                 );\r
 \r
+  if (Uhc->FrameBaseHostAddr != NULL) {\r
+    FreePool (Uhc->FrameBaseHostAddr);\r
+  }\r
+\r
   if (Uhc->SyncIntQh != NULL) {\r
     UsbHcFreeMem (Uhc->MemPool, Uhc->SyncIntQh, sizeof (UHCI_QH_SW));\r
   }\r
@@ -218,7 +198,7 @@ UhciDestoryFrameList (
   }\r
 \r
   Uhc->FrameBase           = NULL;\r
-  Uhc->FrameBasePciMemAddr = NULL;\r
+  Uhc->FrameBaseHostAddr   = NULL;\r
   Uhc->SyncIntQh           = NULL;\r
   Uhc->CtrlQh              = NULL;\r
   Uhc->BulkQh              = NULL;\r
@@ -274,24 +254,12 @@ UhciLinkQhToFrameList (
   UINTN                   Index;\r
   UHCI_QH_SW              *Prev;\r
   UHCI_QH_SW              *Next;\r
-  UINTN                   Len;\r
   EFI_PHYSICAL_ADDRESS    PhyAddr;\r
   EFI_PHYSICAL_ADDRESS    QhPciAddr;\r
-  VOID*                   Map;\r
-  EFI_STATUS              Status;\r
 \r
   ASSERT ((Uhc->FrameBase != NULL) && (Qh != NULL));\r
 \r
-  Len    = sizeof (UHCI_QH_HW);\r
-  Status = Uhc->PciIo->Map (\r
-                            Uhc->PciIo,\r
-                            EfiPciIoOperationBusMasterRead,\r
-                            Qh,\r
-                            &Len,\r
-                            &QhPciAddr,\r
-                            &Map\r
-                            );\r
-  ASSERT (!EFI_ERROR (Status));\r
+  QhPciAddr = UsbHcGetPciAddressForHostMem (Uhc->MemPool, Qh, sizeof (UHCI_QH_HW));\r
 \r
   for (Index = 0; Index < UHCI_FRAME_NUM; Index += Qh->Interval) {\r
     //\r
@@ -299,7 +267,7 @@ UhciLinkQhToFrameList (
     // heads on the frame list\r
     //\r
     ASSERT (!LINK_TERMINATED (Uhc->FrameBase[Index]));\r
-    Next  = UHCI_ADDR (Uhc->FrameBase[Index]);\r
+    Next  = (UHCI_QH_SW*)(UINTN)Uhc->FrameBaseHostAddr[Index];\r
     Prev  = NULL;\r
 \r
     //\r
@@ -362,24 +330,13 @@ UhciLinkQhToFrameList (
     //\r
     if (Qh->NextQh == NULL) {\r
       Qh->NextQh            = Next;\r
-\r
-      Len    = sizeof (UHCI_QH_HW);\r
-      Status = Uhc->PciIo->Map (\r
-                            Uhc->PciIo,\r
-                            EfiPciIoOperationBusMasterRead,\r
-                            Next,\r
-                            &Len,\r
-                            &PhyAddr,\r
-                            &Map\r
-                            );\r
-      ASSERT (!EFI_ERROR (Status));\r
-\r
+      PhyAddr = UsbHcGetPciAddressForHostMem (Uhc->MemPool, Next, sizeof (UHCI_QH_HW));\r
       Qh->QhHw.HorizonLink  = QH_HLINK (PhyAddr, FALSE);\r
     }\r
 \r
     if (Prev == NULL) {\r
-      Uhc->FrameBase[Index]           = QH_HLINK (Qh, FALSE);\r
-      Uhc->FrameBasePciMemAddr[Index] = QH_HLINK (QhPciAddr, FALSE);\r
+      Uhc->FrameBase[Index]           = QH_HLINK (QhPciAddr, FALSE);\r
+      Uhc->FrameBaseHostAddr[Index]   = (UINT32)(UINTN)Qh;\r
     } else {\r
       Prev->NextQh            = Qh;\r
       Prev->QhHw.HorizonLink  = QH_HLINK (QhPciAddr, FALSE);\r
@@ -415,7 +372,7 @@ UhciUnlinkQhFromFrameList (
     // queue heads on the frame list\r
     //\r
     ASSERT (!LINK_TERMINATED (Uhc->FrameBase[Index]));\r
-    This  = UHCI_ADDR (Uhc->FrameBase[Index]);\r
+    This  = (UHCI_QH_SW*)(UINTN)Uhc->FrameBaseHostAddr[Index];\r
     Prev  = NULL;\r
 \r
     //\r
@@ -439,8 +396,8 @@ UhciUnlinkQhFromFrameList (
       //\r
       // Qh is the first entry in the frame\r
       //\r
-      Uhc->FrameBase[Index]           = (UINT32)(UINTN)Qh->NextQh;\r
-      Uhc->FrameBasePciMemAddr[Index] = Qh->QhHw.HorizonLink;\r
+      Uhc->FrameBase[Index]           = Qh->QhHw.HorizonLink;\r
+      Uhc->FrameBaseHostAddr[Index]   = (UINT32)(UINTN)Qh->NextQh;\r
     } else {\r
       Prev->NextQh            = Qh->NextQh;\r
       Prev->QhHw.HorizonLink  = Qh->QhHw.HorizonLink;\r
@@ -619,12 +576,23 @@ UhciExecuteTransfer (
   UINTN                   Delay;\r
   BOOLEAN                 Finished;\r
   EFI_STATUS              Status;\r
+  BOOLEAN                 InfiniteLoop;\r
 \r
-  Finished = FALSE;\r
-  Status   = EFI_SUCCESS;\r
-  Delay    = (TimeOut * UHC_1_MILLISECOND / UHC_SYNC_POLL_INTERVAL) + 1;\r
+  Finished     = FALSE;\r
+  Status       = EFI_SUCCESS;\r
+  Delay        = (TimeOut * UHC_1_MILLISECOND / UHC_SYNC_POLL_INTERVAL) + 1;\r
+  InfiniteLoop = FALSE;\r
 \r
-  for (Index = 0; Index < Delay; Index++) {\r
+  //\r
+  // According to UEFI spec section 16.2.4, If Timeout is 0, then the caller\r
+  // must wait for the function to be completed until EFI_SUCCESS or EFI_DEVICE_ERROR\r
+  // is returned.\r
+  //\r
+  if (TimeOut == 0) {\r
+    InfiniteLoop = TRUE;\r
+  }\r
+\r
+  for (Index = 0; InfiniteLoop || (Index < Delay); Index++) {\r
     Finished = UhciCheckTdStatus (Uhc, Td, IsLow, QhResult);\r
 \r
     //\r
@@ -712,7 +680,6 @@ UhciUpdateAsyncReq (
   @param  EndPoint               EndPoint Address.\r
   @param  DataLen                Data length.\r
   @param  Interval               Polling Interval when inserted to frame list.\r
-  @param  Mapping                Mapping value.\r
   @param  Data                   Data buffer, unmapped.\r
   @param  Callback               Callback after interrupt transfeer.\r
   @param  Context                Callback Context passed as function parameter.\r
@@ -732,7 +699,6 @@ UhciCreateAsyncReq (
   IN UINT8                            EndPoint,\r
   IN UINTN                            DataLen,\r
   IN UINTN                            Interval,\r
-  IN VOID                             *Mapping,\r
   IN UINT8                            *Data,\r
   IN EFI_ASYNC_USB_TRANSFER_CALLBACK  Callback,\r
   IN VOID                             *Context,\r
@@ -755,7 +721,6 @@ UhciCreateAsyncReq (
   AsyncReq->EndPoint    = EndPoint;\r
   AsyncReq->DataLen     = DataLen;\r
   AsyncReq->Interval    = UhciConvertPollRate(Interval);\r
-  AsyncReq->Mapping     = Mapping;\r
   AsyncReq->Data        = Data;\r
   AsyncReq->Callback    = Callback;\r
   AsyncReq->Context     = Context;\r
@@ -793,10 +758,6 @@ UhciFreeAsyncReq (
   UhciDestoryTds (Uhc, AsyncReq->FirstTd);\r
   UsbHcFreeMem (Uhc->MemPool, AsyncReq->QhSw, sizeof (UHCI_QH_SW));\r
 \r
-  if (AsyncReq->Mapping != NULL) {\r
-    Uhc->PciIo->Unmap (Uhc->PciIo, AsyncReq->Mapping);\r
-  }\r
-\r
   if (AsyncReq->Data != NULL) {\r
     UsbHcFreeMem (Uhc->MemPool, AsyncReq->Data, AsyncReq->DataLen);\r
   }\r