]> git.proxmox.com Git - mirror_edk2.git/commitdiff
Fix a bug that usb keybarod can not work well when it is inserted at a usb 2.0 hub.
authorerictian <erictian@6f19259b-4bc3-4df7-8a09-765794883524>
Fri, 19 Mar 2010 06:54:35 +0000 (06:54 +0000)
committererictian <erictian@6f19259b-4bc3-4df7-8a09-765794883524>
Fri, 19 Mar 2010 06:54:35 +0000 (06:54 +0000)
It's due to AsyncInterruptList does not update the corresponding QTDHw->Data with pci bus master address.

git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@10286 6f19259b-4bc3-4df7-8a09-765794883524

MdeModulePkg/Bus/Pci/EhciDxe/EhciSched.c
MdeModulePkg/Bus/Pci/UhciDxe/Uhci.c
MdeModulePkg/Bus/Pci/UhciDxe/Uhci.h
MdeModulePkg/Bus/Pci/UhciDxe/UhciQueue.c
MdeModulePkg/Bus/Pci/UhciDxe/UhciSched.c
MdeModulePkg/Bus/Pci/UhciDxe/UhciSched.h
MdeModulePkg/Bus/Pci/UhciDxe/UsbHcMem.c
MdeModulePkg/Bus/Pci/UhciDxe/UsbHcMem.h

index 58d4a303dc78265906e76cccf12c4ffa7b5b8bce..0b9d7608ace8a2a18ecde7eea2f0f9bd0a4bd3c1 100644 (file)
@@ -904,7 +904,12 @@ EhcUpdateAsyncRequest (
       QtdHw->ErrCnt     = QTD_MAX_ERR;\r
       QtdHw->CurPage    = 0;\r
       QtdHw->TotalBytes = (UINT32) Qtd->DataLen;\r
-      QtdHw->Page[0]    = EHC_LOW_32BIT (Qtd->Data);\r
+      //\r
+      // calculate physical address by offset.\r
+      //\r
+      PciAddr = (UINTN)Urb->DataPhy + ((UINTN)Qtd->Data - (UINTN)Urb->Data); \r
+      QtdHw->Page[0]    = EHC_LOW_32BIT (PciAddr);\r
+      QtdHw->PageHigh[0]= EHC_HIGH_32BIT (PciAddr);\r
     }\r
 \r
     //\r
index c2d560b48c91db3cf156786e294e381a2c8fcc7b..bc7cfb9c90f5a6b14e6f5ea1306dc5e5a9f4a293 100644 (file)
@@ -949,7 +949,6 @@ Uhci2AsyncInterruptTransfer (
   EFI_STATUS          Status;\r
   UINT8               *DataPtr;\r
   UINT8               *DataPhy;\r
-  VOID                *DataMap;\r
   UINT8               PktId;\r
 \r
   Uhc       = UHC_FROM_USB2_HC_PROTO (This);\r
@@ -957,7 +956,6 @@ Uhci2AsyncInterruptTransfer (
   IntTds    = NULL;\r
   DataPtr   = NULL;\r
   DataPhy   = NULL;\r
-  DataMap   = NULL;\r
 \r
   IsSlowDevice  = (BOOLEAN) ((EFI_USB_SPEED_LOW == DeviceSpeed) ? TRUE : FALSE);\r
 \r
@@ -998,40 +996,30 @@ Uhci2AsyncInterruptTransfer (
     return EFI_DEVICE_ERROR;\r
   }\r
 \r
+  if ((EndPointAddress & 0x80) == 0) {\r
+    PktId = OUTPUT_PACKET_ID;\r
+  } else {\r
+    PktId = INPUT_PACKET_ID;\r
+  }\r
+\r
   //\r
   // Allocate and map source data buffer for bus master access.\r
   //\r
-  DataPtr     = UsbHcAllocateMem (Uhc->MemPool, DataLength);\r
+  DataPtr = UsbHcAllocateMem (Uhc->MemPool, DataLength);\r
 \r
   if (DataPtr == NULL) {\r
     return EFI_OUT_OF_RESOURCES;\r
   }\r
 \r
-  OldTpl = gBS->RaiseTPL (UHCI_TPL);\r
-\r
-  //\r
-  // Map the user data then create a queue head and\r
-  // list of TD for it.\r
-  //\r
-  Status = UhciMapUserData (\r
-             Uhc,\r
-             EfiUsbDataIn,\r
-             DataPtr,\r
-             &DataLength,\r
-             &PktId,\r
-             &DataPhy,\r
-             &DataMap\r
-             );\r
+  DataPhy = (UINT8 *)UsbHcGetPciAddressForHostMem (Uhc->MemPool, DataPtr, DataLength);\r
 \r
-  if (EFI_ERROR (Status)) {\r
-    goto FREE_DATA;\r
-  }\r
+  OldTpl = gBS->RaiseTPL (UHCI_TPL);\r
 \r
   Qh = UhciCreateQh (Uhc, PollingInterval);\r
 \r
   if (Qh == NULL) {\r
     Status = EFI_OUT_OF_RESOURCES;\r
-    goto UNMAP_DATA;\r
+    goto FREE_DATA;\r
   }\r
 \r
   IntTds = UhciCreateBulkOrIntTds (\r
@@ -1066,7 +1054,6 @@ Uhci2AsyncInterruptTransfer (
              EndPointAddress,\r
              DataLength,\r
              PollingInterval,\r
-             DataMap,\r
              DataPtr,\r
              CallBackFunction,\r
              Context,\r
@@ -1085,11 +1072,8 @@ Uhci2AsyncInterruptTransfer (
 DESTORY_QH:\r
   UsbHcFreeMem (Uhc->MemPool, Qh, sizeof (UHCI_QH_SW));\r
 \r
-UNMAP_DATA:\r
-  Uhc->PciIo->Unmap (Uhc->PciIo, DataMap);\r
-\r
 FREE_DATA:\r
-  gBS->FreePool (DataPtr);\r
+  UsbHcFreeMem (Uhc->MemPool, DataPtr, DataLength);\r
   Uhc->PciIo->Flush (Uhc->PciIo);\r
 \r
   gBS->RestoreTPL (OldTpl);\r
index c2377bf3a7980cbf4d4a2afe1dcc8bccbb1c2f75..096af248029cccc79b7a7ff0ed02dae610daaa58 100644 (file)
@@ -117,8 +117,8 @@ struct _USB_HC_DEV {
   //\r
   // Schedule data structures\r
   //\r
-  UINT32                    *FrameBase;\r
-  UINT32                    *FrameBasePciMemAddr;\r
+  UINT32                    *FrameBase; // the buffer pointed by this pointer is used to store pci bus address of the QH descriptor.\r
+  UINT32                    *FrameBaseHostAddr; // the buffer pointed by this pointer is used to store host memory address of the QH descriptor.\r
   UHCI_QH_SW                *SyncIntQh;\r
   UHCI_QH_SW                *CtrlQh;\r
   UHCI_QH_SW                *BulkQh;\r
index a816956bbedf6fe7cd7ec91d3806777bc9ce6dd7..39dbe4ceb7c535756c5a3b40c284f1a760dd8006 100644 (file)
@@ -2,7 +2,7 @@
 \r
   The UHCI register operation routines.\r
 \r
-Copyright (c) 2007 - 2008, Intel Corporation\r
+Copyright (c) 2007 - 2010, Intel Corporation\r
 All rights reserved. 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
@@ -164,22 +164,11 @@ UhciLinkTdToQh (
   IN UHCI_TD_SW           *Td\r
   )\r
 {\r
-  EFI_STATUS            Status;\r
-  UINTN                 Len;\r
   EFI_PHYSICAL_ADDRESS  PhyAddr;\r
-  VOID*                 Map;\r
 \r
-  Len    = sizeof (UHCI_TD_HW);\r
-  Status = Uhc->PciIo->Map (\r
-                         Uhc->PciIo,\r
-                         EfiPciIoOperationBusMasterRead,\r
-                         Td,\r
-                         &Len,\r
-                         &PhyAddr,\r
-                         &Map\r
-                         );\r
+  PhyAddr = UsbHcGetPciAddressForHostMem (Uhc->MemPool, Td, sizeof (UHCI_TD_HW));\r
 \r
-  ASSERT (!EFI_ERROR (Status) && (Qh != NULL) && (Td != NULL));\r
+  ASSERT ((Qh != NULL) && (Td != NULL));\r
 \r
   Qh->QhHw.VerticalLink = QH_VLINK (PhyAddr, FALSE);\r
   Qh->TDs               = (VOID *) Td;\r
@@ -221,22 +210,11 @@ UhciAppendTd (
   IN UHCI_TD_SW     *ThisTd\r
   )\r
 {\r
-  EFI_STATUS            Status;\r
-  UINTN                 Len;\r
   EFI_PHYSICAL_ADDRESS  PhyAddr;\r
-  VOID*                 Map;\r
 \r
-  Len    = sizeof (UHCI_TD_HW);\r
-  Status = Uhc->PciIo->Map (\r
-                         Uhc->PciIo,\r
-                         EfiPciIoOperationBusMasterRead,\r
-                         ThisTd,\r
-                         &Len,\r
-                         &PhyAddr,\r
-                         &Map\r
-                         );\r
+  PhyAddr = UsbHcGetPciAddressForHostMem (Uhc->MemPool, ThisTd, sizeof (UHCI_TD_HW));\r
 \r
-  ASSERT (!EFI_ERROR (Status) && (PrevTd != NULL) && (ThisTd != NULL));\r
+  ASSERT ((PrevTd != NULL) && (ThisTd != NULL));\r
 \r
   PrevTd->TdHw.NextLink = TD_LINK (PhyAddr, TRUE, FALSE);\r
   PrevTd->NextTd        = (VOID *) ThisTd;\r
@@ -324,6 +302,7 @@ UhciCreateTd (
     return NULL;\r
   }\r
 \r
+  Td->TdHw.NextLink = TD_LINK (NULL, FALSE, TRUE);\r
   Td->NextTd        = NULL;\r
   Td->Data          = NULL;\r
   Td->DataLen       = 0;\r
@@ -428,7 +407,7 @@ UhciCreateDataTd (
   Td->TdHw.ShortPacket  = FALSE;\r
   Td->TdHw.IsIsoch      = FALSE;\r
   Td->TdHw.IntOnCpl     = FALSE;\r
-  Td->TdHw.ErrorCount   = 0X03;\r
+  Td->TdHw.ErrorCount   = 0x03;\r
   Td->TdHw.Status       = USBTD_ACTIVE;\r
   Td->TdHw.LowSpeed     = IsLow ? 1 : 0;\r
   Td->TdHw.DataToggle   = Toggle & 0x01;\r
index 759f7a05cb73c75b8faba7594793c458848111c6..4d6957d70a47392624e471ffa8ecd403343599aa 100644 (file)
@@ -2,7 +2,7 @@
 \r
   The EHCI register operation routines.\r
 \r
-Copyright (c) 2007 - 2009, Intel Corporation\r
+Copyright (c) 2007 - 2010, Intel Corporation\r
 All rights reserved. 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
@@ -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 *) 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
@@ -712,7 +669,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 +688,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 +710,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 +747,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
index 310dfa0ab26cb173f35c0ed0cd9be7b672ba4a95..e46aa88bff5cf13876c9c23e69220296bd654537 100644 (file)
@@ -190,7 +190,6 @@ UhciExecuteTransfer (
   @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
@@ -210,7 +209,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
index ca7877da1dfa5ee2c48d63893e991a5b046c7eca..074451d9b31d853cef2e2fc4b03d0de61021b06c 100644 (file)
@@ -2,7 +2,7 @@
 \r
   The routine procedure for uhci memory allocate/free.\r
 \r
-Copyright (c) 2007, Intel Corporation\r
+Copyright (c) 2007 - 2010, Intel Corporation\r
 All rights reserved. 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
@@ -220,6 +220,53 @@ UsbHcAllocMemFromBlock (
   return Block->Buf + (StartByte * 8 + StartBit) * USBHC_MEM_UNIT;\r
 }\r
 \r
+/**\r
+  Calculate the corresponding pci bus address according to the Mem parameter.\r
+\r
+  @param  Pool           The memory pool of the host controller.\r
+  @param  Mem            The pointer to host memory.\r
+  @param  Size           The size of the memory region.\r
+\r
+  @return the pci memory address\r
+**/\r
+EFI_PHYSICAL_ADDRESS\r
+UsbHcGetPciAddressForHostMem (\r
+  IN USBHC_MEM_POOL       *Pool,\r
+  IN VOID                 *Mem,\r
+  IN UINTN                Size\r
+  )\r
+{\r
+  USBHC_MEM_BLOCK         *Head;\r
+  USBHC_MEM_BLOCK         *Block;\r
+  UINTN                   AllocSize;\r
+  EFI_PHYSICAL_ADDRESS    PhyAddr;\r
+  UINTN                   Offset;\r
+\r
+  Head      = Pool->Head;\r
+  AllocSize = USBHC_MEM_ROUND (Size);\r
+\r
+  if (Mem == NULL) {\r
+    return 0;\r
+  }\r
+\r
+  for (Block = Head; Block != NULL; Block = Block->Next) {\r
+    //\r
+    // scan the memory block list for the memory block that\r
+    // completely contains the allocated memory.\r
+    //\r
+    if ((Block->BufHost <= (UINT8 *) Mem) && (((UINT8 *) Mem + AllocSize) <= (Block->BufHost + Block->BufLen))) {\r
+      break;\r
+    }\r
+  }\r
+\r
+  ASSERT ((Block != NULL));\r
+  //\r
+  // calculate the pci memory address for host memory address.\r
+  //\r
+  Offset = (UINT8 *)Mem - Block->BufHost;\r
+  PhyAddr = (EFI_PHYSICAL_ADDRESS)(UINTN) (Block->Buf + Offset);\r
+  return PhyAddr;\r
+}\r
 \r
 /**\r
   Insert the memory block to the pool's list of the blocks.\r
index 5ad9f97683af68eb3496890d7786e812e2356a53..2d69a927d8053cccef224b99a38a8bce28f6c66e 100644 (file)
@@ -141,4 +141,21 @@ UsbHcFreeMem (
   IN VOID                 *Mem,\r
   IN UINTN                Size\r
   );\r
+\r
+/**\r
+  Calculate the corresponding pci bus address according to the Mem parameter.\r
+\r
+  @param  Pool           The memory pool of the host controller.\r
+  @param  Mem            The pointer to host memory.\r
+  @param  Size           The size of the memory region.\r
+\r
+  @return the pci memory address\r
+**/\r
+EFI_PHYSICAL_ADDRESS\r
+UsbHcGetPciAddressForHostMem (\r
+  IN USBHC_MEM_POOL       *Pool,\r
+  IN VOID                 *Mem,\r
+  IN UINTN                Size\r
+  );\r
+\r
 #endif\r