]> git.proxmox.com Git - mirror_edk2.git/commitdiff
update code to eliminate the wrong assumption that pci address is equal to host addre...
authoreric_tian <eric_tian@6f19259b-4bc3-4df7-8a09-765794883524>
Wed, 14 Oct 2009 06:22:49 +0000 (06:22 +0000)
committereric_tian <eric_tian@6f19259b-4bc3-4df7-8a09-765794883524>
Wed, 14 Oct 2009 06:22:49 +0000 (06:22 +0000)
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@9339 6f19259b-4bc3-4df7-8a09-765794883524

MdeModulePkg/Bus/Pci/EhciDxe/EhciReg.c
MdeModulePkg/Bus/Pci/EhciDxe/EhciSched.c
MdeModulePkg/Bus/Pci/EhciDxe/EhciUrb.c
MdeModulePkg/Bus/Pci/EhciDxe/EhciUrb.h
MdeModulePkg/Bus/Pci/EhciDxe/UsbHcMem.c
MdeModulePkg/Bus/Pci/EhciDxe/UsbHcMem.h

index eca9b0b2728ba34facc27285d9176e18cfdd414b..9a5c76f098a6e10c997a7ba70e6a7ae9bd2c9b0a 100644 (file)
@@ -561,7 +561,7 @@ EhcInitHC (
   // Allocate the periodic frame and associated memeory\r
   // management facilities if not already done.\r
   //\r
-  if (Ehc->PeriodFrame != NULL) {\r
+  if (Ehc->PeriodFrameHost != NULL) {\r
     EhcFreeSched (Ehc);\r
   }\r
 \r
index 4b1cc7399f026febce6689466df448f61f85d4e9..2d8dc024b931c0243797ed5dbadb45dceb091ffd 100644 (file)
@@ -34,11 +34,12 @@ EhcCreateHelpQ (
   EHC_QH                  *Qh;\r
   QH_HW                   *QhHw;\r
   EHC_QTD                 *Qtd;\r
+  EFI_PHYSICAL_ADDRESS    PciAddr;\r
 \r
   //\r
   // Create an inactive Qtd to terminate the short packet read.\r
   //\r
-  Qtd = EhcCreateQtd (Ehc, NULL, 0, QTD_PID_INPUT, 0, 64);\r
+  Qtd = EhcCreateQtd (Ehc, NULL, NULL, 0, QTD_PID_INPUT, 0, 64);\r
 \r
   if (Qtd == NULL) {\r
     return EFI_OUT_OF_RESOURCES;\r
@@ -68,8 +69,9 @@ EhcCreateHelpQ (
     return EFI_OUT_OF_RESOURCES;\r
   }\r
 \r
+  PciAddr           = UsbHcGetPciAddressForHostMem (Ehc->MemPool, Qh, sizeof (EHC_QH));\r
   QhHw              = &Qh->QhHw;\r
-  QhHw->HorizonLink = QH_LINK (QhHw, EHC_TYPE_QH, FALSE);\r
+  QhHw->HorizonLink = QH_LINK (PciAddr + OFFSET_OF(EHC_QH, QhHw), EHC_TYPE_QH, FALSE);\r
   QhHw->Status      = QTD_STAT_HALTED;\r
   QhHw->ReclaimHead = 1;\r
   Ehc->ReclaimHead  = Qh;\r
@@ -116,6 +118,7 @@ EhcInitSched (
   UINTN                 Index;\r
   UINT32                *Desc;\r
   EFI_STATUS            Status;\r
+  EFI_PHYSICAL_ADDRESS  PciAddr;\r
 \r
   //\r
   // First initialize the periodical schedule data:\r
@@ -185,10 +188,11 @@ EhcInitSched (
   //\r
   // Initialize the frame list entries then set the registers\r
   //\r
-  Desc = (UINT32 *) Ehc->PeriodFrame;\r
+  Desc = (UINT32 *) Ehc->PeriodFrameHost;\r
 \r
   for (Index = 0; Index < EHC_FRAME_LEN; Index++) {\r
-    Desc[Index] = QH_LINK (Ehc->PeriodOne, EHC_TYPE_QH, FALSE);\r
+    PciAddr     = UsbHcGetPciAddressForHostMem (Ehc->MemPool, Ehc->PeriodOne, sizeof (EHC_QH));\r
+    Desc[Index] = QH_LINK (PciAddr, EHC_TYPE_QH, FALSE);\r
   }\r
 \r
   EhcWriteOpReg (Ehc, EHC_FRAME_BASE_OFFSET, EHC_LOW_32BIT (Ehc->PeriodFrame));\r
@@ -198,7 +202,8 @@ EhcInitSched (
   // Only need to set the AsynListAddr register to\r
   // the reclamation header\r
   //\r
-  EhcWriteOpReg (Ehc, EHC_ASYNC_HEAD_OFFSET, EHC_LOW_32BIT (Ehc->ReclaimHead));\r
+  PciAddr = UsbHcGetPciAddressForHostMem (Ehc->MemPool, Ehc->ReclaimHead, sizeof (EHC_QH));\r
+  EhcWriteOpReg (Ehc, EHC_ASYNC_HEAD_OFFSET, EHC_LOW_32BIT (PciAddr));\r
   return EFI_SUCCESS;\r
 }\r
 \r
@@ -239,7 +244,7 @@ EhcFreeSched (
     Ehc->MemPool = NULL;\r
   }\r
 \r
-  if (Ehc->PeriodFrame != NULL) {\r
+  if (Ehc->PeriodFrameHost != NULL) {\r
     PciIo = Ehc->PciIo;\r
     ASSERT (PciIo != NULL);\r
 \r
@@ -251,7 +256,8 @@ EhcFreeSched (
              Ehc->PeriodFrameHost\r
              );\r
 \r
-    Ehc->PeriodFrame = NULL;\r
+    Ehc->PeriodFrameHost = NULL;\r
+    Ehc->PeriodFrame     = NULL;\r
   }\r
 }\r
 \r
@@ -274,6 +280,7 @@ EhcLinkQhToAsync (
   )\r
 {\r
   EHC_QH                  *Head;\r
+  EFI_PHYSICAL_ADDRESS    PciAddr;\r
 \r
   //\r
   // Append the queue head after the reclaim header, then\r
@@ -285,8 +292,10 @@ EhcLinkQhToAsync (
   Qh->NextQh              = Head->NextQh;\r
   Head->NextQh            = Qh;\r
 \r
-  Qh->QhHw.HorizonLink    = QH_LINK (Head, EHC_TYPE_QH, FALSE);;\r
-  Head->QhHw.HorizonLink  = QH_LINK (Qh, EHC_TYPE_QH, FALSE);\r
+  PciAddr = UsbHcGetPciAddressForHostMem (Ehc->MemPool, Head, sizeof (EHC_QH));\r
+  Qh->QhHw.HorizonLink    = QH_LINK (PciAddr, EHC_TYPE_QH, FALSE);;\r
+  PciAddr = UsbHcGetPciAddressForHostMem (Ehc->MemPool, Qh, sizeof (EHC_QH));\r
+  Head->QhHw.HorizonLink  = QH_LINK (PciAddr, EHC_TYPE_QH, FALSE);\r
 }\r
 \r
 \r
@@ -306,6 +315,7 @@ EhcUnlinkQhFromAsync (
 {\r
   EHC_QH                  *Head;\r
   EFI_STATUS              Status;\r
+  EFI_PHYSICAL_ADDRESS    PciAddr;\r
 \r
   ASSERT (Ehc->ReclaimHead->NextQh == Qh);\r
 \r
@@ -319,7 +329,8 @@ EhcUnlinkQhFromAsync (
   Head->NextQh            = Qh->NextQh;\r
   Qh->NextQh              = NULL;\r
 \r
-  Head->QhHw.HorizonLink  = QH_LINK (Head, EHC_TYPE_QH, FALSE);\r
+  PciAddr = UsbHcGetPciAddressForHostMem (Ehc->MemPool, Head, sizeof (EHC_QH));\r
+  Head->QhHw.HorizonLink  = QH_LINK (PciAddr, EHC_TYPE_QH, FALSE);\r
 \r
   //\r
   // Set and wait the door bell to synchronize with the hardware\r
@@ -351,8 +362,9 @@ EhcLinkQhToPeriod (
   UINTN                   Index;\r
   EHC_QH                  *Prev;\r
   EHC_QH                  *Next;\r
+  EFI_PHYSICAL_ADDRESS    PciAddr;\r
 \r
-  Frames = Ehc->PeriodFrame;\r
+  Frames = Ehc->PeriodFrameHost;\r
 \r
   for (Index = 0; Index < EHC_FRAME_LEN; Index += Qh->Interval) {\r
     //\r
@@ -408,7 +420,8 @@ EhcLinkQhToPeriod (
       Prev->NextQh            = Qh;\r
 \r
       Qh->QhHw.HorizonLink    = Prev->QhHw.HorizonLink;\r
-      Prev->QhHw.HorizonLink  = QH_LINK (Qh, EHC_TYPE_QH, FALSE);\r
+      PciAddr = UsbHcGetPciAddressForHostMem (Ehc->MemPool, Qh, sizeof (EHC_QH));\r
+      Prev->QhHw.HorizonLink  = QH_LINK (PciAddr, EHC_TYPE_QH, FALSE);\r
       break;\r
     }\r
 \r
@@ -419,14 +432,17 @@ EhcLinkQhToPeriod (
     //\r
     if (Qh->NextQh == NULL) {\r
       Qh->NextQh              = Next;\r
-      Qh->QhHw.HorizonLink    = QH_LINK (Next, EHC_TYPE_QH, FALSE);\r
+      PciAddr = UsbHcGetPciAddressForHostMem (Ehc->MemPool, Next, sizeof (EHC_QH));\r
+      Qh->QhHw.HorizonLink    = QH_LINK (PciAddr, EHC_TYPE_QH, FALSE);\r
     }\r
 \r
+    PciAddr = UsbHcGetPciAddressForHostMem (Ehc->MemPool, Qh, sizeof (EHC_QH));\r
+\r
     if (Prev == NULL) {\r
-      Frames[Index] = QH_LINK (Qh, EHC_TYPE_QH, FALSE);\r
+      Frames[Index] = QH_LINK (PciAddr, EHC_TYPE_QH, FALSE);\r
     } else {\r
       Prev->NextQh            = Qh;\r
-      Prev->QhHw.HorizonLink  = QH_LINK (Qh, EHC_TYPE_QH, FALSE);\r
+      Prev->QhHw.HorizonLink  = QH_LINK (PciAddr, EHC_TYPE_QH, FALSE);\r
     }\r
   }\r
 }\r
@@ -451,7 +467,7 @@ EhcUnlinkQhFromPeriod (
   EHC_QH                  *Prev;\r
   EHC_QH                  *This;\r
 \r
-  Frames = Ehc->PeriodFrame;\r
+  Frames = Ehc->PeriodFrameHost;\r
 \r
   for (Index = 0; Index < EHC_FRAME_LEN; Index += Qh->Interval) {\r
     //\r
@@ -513,6 +529,7 @@ EhcCheckUrbResult (
   QTD_HW                  *QtdHw;\r
   UINT8                   State;\r
   BOOLEAN                 Finished;\r
+  EFI_PHYSICAL_ADDRESS    PciAddr;\r
 \r
   ASSERT ((Ehc != NULL) && (Urb != NULL) && (Urb->Qh != NULL));\r
 \r
@@ -582,7 +599,8 @@ EhcCheckUrbResult (
         // ShortReadStop. If it is a setup transfer, need to check the\r
         // Status Stage of the setup transfer to get the finial result\r
         //\r
-        if (QtdHw->AltNext == QTD_LINK (Ehc->ShortReadStop, FALSE)) {\r
+        PciAddr = UsbHcGetPciAddressForHostMem (Ehc->MemPool, Ehc->ShortReadStop, sizeof (EHC_QTD));\r
+        if (QtdHw->AltNext == QTD_LINK (PciAddr, FALSE)) {\r
           DEBUG ((EFI_D_INFO, "EhcCheckUrbResult: Short packet read, break\n"));\r
 \r
           Finished = TRUE;\r
@@ -803,11 +821,13 @@ ON_ERROR:
 /**\r
   Update the queue head for next round of asynchronous transfer.\r
 \r
+  @param  Ehc                   The EHCI device.\r
   @param  Urb                   The URB to update.\r
 \r
 **/\r
 VOID\r
 EhcUpdateAsyncRequest (\r
+  IN  USB2_HC_DEV         *Ehc,\r
   IN URB                  *Urb\r
   )\r
 {\r
@@ -817,6 +837,7 @@ EhcUpdateAsyncRequest (
   EHC_QTD                 *Qtd;\r
   QTD_HW                  *QtdHw;\r
   UINTN                   Index;\r
+  EFI_PHYSICAL_ADDRESS    PciAddr;\r
 \r
   Qtd = NULL;\r
 \r
@@ -868,7 +889,8 @@ EhcUpdateAsyncRequest (
       QhHw->PageHigh[Index] = 0;\r
     }\r
 \r
-    QhHw->NextQtd = QTD_LINK (FirstQtd, FALSE);\r
+    PciAddr = UsbHcGetPciAddressForHostMem (Ehc->MemPool, FirstQtd, sizeof (EHC_QTD));\r
+    QhHw->NextQtd = QTD_LINK (PciAddr, FALSE);\r
   }\r
 \r
   return ;\r
@@ -936,14 +958,14 @@ EhcMonitorAsyncRequests (
       ProcBuf = AllocatePool (Urb->Completed);\r
 \r
       if (ProcBuf == NULL) {\r
-        EhcUpdateAsyncRequest (Urb);\r
+        EhcUpdateAsyncRequest (Ehc, Urb);\r
         continue;\r
       }\r
 \r
       CopyMem (ProcBuf, Urb->Data, Urb->Completed);\r
     }\r
 \r
-    EhcUpdateAsyncRequest (Urb);\r
+    EhcUpdateAsyncRequest (Ehc, Urb);\r
 \r
     //\r
     // Leave error recovery to its related device driver. A\r
index 6d1bf9b3367e2e8351af4e819fd3cd89ef2e0fca..ba98f099ab36bff09e616ddd3eba5ed28264fc79 100644 (file)
@@ -21,7 +21,8 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
   Create a single QTD to hold the data.\r
 \r
   @param  Ehc                   The EHCI device.\r
-  @param  Data                  Current data not associated with a QTD.\r
+  @param  Data                  The cpu memory address of current data not associated with a QTD.\r
+  @param  DataPhy               The pci bus address of current data not associated with a QTD.\r
   @param  DataLen               The length of the data.\r
   @param  PktId                 Packet ID to use in the QTD.\r
   @param  Toggle                Data toggle to use in the QTD.\r
@@ -34,6 +35,7 @@ EHC_QTD *
 EhcCreateQtd (\r
   IN USB2_HC_DEV          *Ehc,\r
   IN UINT8                *Data,\r
+  IN UINT8                *DataPhy,\r
   IN UINTN                DataLen,\r
   IN UINT8                PktId,\r
   IN UINT8                Toggle,\r
@@ -82,10 +84,10 @@ EhcCreateQtd (
       // compute the offset and clear Reserved fields. This is already\r
       // done in the data point.\r
       //\r
-      QtdHw->Page[Index]      = EHC_LOW_32BIT (Data);\r
-      QtdHw->PageHigh[Index]  = EHC_HIGH_32BIT (Data);\r
+      QtdHw->Page[Index]      = EHC_LOW_32BIT (DataPhy);\r
+      QtdHw->PageHigh[Index]  = EHC_HIGH_32BIT (DataPhy);\r
 \r
-      ThisBufLen              = QTD_BUF_LEN - (EHC_LOW_32BIT (Data) & QTD_BUF_MASK);\r
+      ThisBufLen              = QTD_BUF_LEN - (EHC_LOW_32BIT (DataPhy) & QTD_BUF_MASK);\r
 \r
       if (Len + ThisBufLen >= DataLen) {\r
         Len = DataLen;\r
@@ -94,6 +96,7 @@ EhcCreateQtd (
 \r
       Len += ThisBufLen;\r
       Data += ThisBufLen;\r
+      DataPhy += ThisBufLen;\r
     }\r
 \r
     //\r
@@ -375,6 +378,7 @@ EhcCreateQtds (
   UINT8                   Toggle;\r
   UINTN                   Len;\r
   UINT8                   Pid;\r
+  EFI_PHYSICAL_ADDRESS    PhyAddr;\r
 \r
   ASSERT ((Urb != NULL) && (Urb->Qh != NULL));\r
 \r
@@ -390,8 +394,9 @@ EhcCreateQtds (
   StatusQtd = NULL;\r
   AlterNext = QTD_LINK (NULL, TRUE);\r
 \r
+  PhyAddr   = UsbHcGetPciAddressForHostMem (Ehc->MemPool, Ehc->ShortReadStop, sizeof (EHC_QTD));\r
   if (Ep->Direction == EfiUsbDataIn) {\r
-    AlterNext = QTD_LINK (Ehc->ShortReadStop, FALSE);\r
+    AlterNext = QTD_LINK (PhyAddr, FALSE);\r
   }\r
 \r
   //\r
@@ -399,7 +404,7 @@ EhcCreateQtds (
   //\r
   if (Urb->Ep.Type == EHC_CTRL_TRANSFER) {\r
     Len = sizeof (EFI_USB_DEVICE_REQUEST);\r
-    Qtd = EhcCreateQtd (Ehc, Urb->RequestPhy, Len, QTD_PID_SETUP, 0, Ep->MaxPacket);\r
+    Qtd = EhcCreateQtd (Ehc, (UINT8 *)Urb->Request, (UINT8 *)Urb->RequestPhy, Len, QTD_PID_SETUP, 0, Ep->MaxPacket);\r
 \r
     if (Qtd == NULL) {\r
       return EFI_OUT_OF_RESOURCES;\r
@@ -419,14 +424,15 @@ EhcCreateQtds (
       Pid = QTD_PID_INPUT;\r
     }\r
 \r
-    StatusQtd = EhcCreateQtd (Ehc, NULL, 0, Pid, 1, Ep->MaxPacket);\r
+    StatusQtd = EhcCreateQtd (Ehc, NULL, NULL, 0, Pid, 1, Ep->MaxPacket);\r
 \r
     if (StatusQtd == NULL) {\r
       goto ON_ERROR;\r
     }\r
 \r
     if (Ep->Direction == EfiUsbDataIn) {\r
-      AlterNext = QTD_LINK (StatusQtd, FALSE);\r
+      PhyAddr   = UsbHcGetPciAddressForHostMem (Ehc->MemPool, StatusQtd, sizeof (EHC_QTD));\r
+      AlterNext = QTD_LINK (PhyAddr, FALSE);\r
     }\r
 \r
     Toggle = 1;\r
@@ -447,6 +453,7 @@ EhcCreateQtds (
   while (Len < Urb->DataLen) {\r
     Qtd = EhcCreateQtd (\r
             Ehc,\r
+            (UINT8 *) Urb->Data + Len,\r
             (UINT8 *) Urb->DataPhy + Len,\r
             Urb->DataLen - Len,\r
             Pid,\r
@@ -492,14 +499,16 @@ EhcCreateQtds (
     }\r
 \r
     NextQtd             = EFI_LIST_CONTAINER (Entry->ForwardLink, EHC_QTD, QtdList);\r
-    Qtd->QtdHw.NextQtd  = QTD_LINK (NextQtd, FALSE);\r
+    PhyAddr             = UsbHcGetPciAddressForHostMem (Ehc->MemPool, NextQtd, sizeof (EHC_QTD));\r
+    Qtd->QtdHw.NextQtd  = QTD_LINK (PhyAddr, FALSE);\r
   }\r
 \r
   //\r
   // Link the QTDs to the queue head\r
   //\r
   NextQtd           = EFI_LIST_CONTAINER (Qh->Qtds.ForwardLink, EHC_QTD, QtdList);\r
-  Qh->QhHw.NextQtd  = QTD_LINK (NextQtd, FALSE);\r
+  PhyAddr           = UsbHcGetPciAddressForHostMem (Ehc->MemPool, NextQtd, sizeof (EHC_QTD));\r
+  Qh->QhHw.NextQtd  = QTD_LINK (PhyAddr, FALSE);\r
   return EFI_SUCCESS;\r
 \r
 ON_ERROR:\r
index 1079be003b77891c36eca3f57d5d6eb18f0c4a69..2e0637530f9adebfe4790db177e336c03d8d682b 100644 (file)
@@ -244,7 +244,8 @@ struct _URB {
   Create a single QTD to hold the data.\r
 \r
   @param  Ehc        The EHCI device.\r
-  @param  Data       Current data not associated with a QTD.\r
+  @param  Data       The cpu memory address of current data not associated with a QTD.\r
+  @param  DataPhy    The pci bus address of current data not associated with a QTD.\r
   @param  DataLen    The length of the data.\r
   @param  PktId      Packet ID to use in the QTD.\r
   @param  Toggle     Data toggle to use in the QTD.\r
@@ -257,6 +258,7 @@ EHC_QTD *
 EhcCreateQtd (\r
   IN USB2_HC_DEV          *Ehc,\r
   IN UINT8                *Data,\r
+  IN UINT8                *DataPhy,\r
   IN UINTN                DataLen,\r
   IN UINT8                PktId,\r
   IN UINT8                Toggle,\r
index af8070e569baa4c77d158e6234dcecf458248c06..177c49f1e4070f0cbcf481c0e4d8b048cd8f9abe 100644 (file)
@@ -221,6 +221,50 @@ UsbHcAllocMemFromBlock (
   return Block->Buf + (StartByte * 8 + StartBit) * USBHC_MEM_UNIT;\r
 }\r
 \r
+/**\r
+  Get the pci memory address according to the allocated host memory address.\r
+\r
+  @param  Pool           The memory pool of the host controller.\r
+  @param  Mem            The memory to free.\r
+  @param  Size           The size of the memory to free.\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
+  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->Buf <= (UINT8 *) Mem) && (((UINT8 *) Mem + AllocSize) <= (Block->Buf + 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)(Block->Buf + Offset);\r
+  return PhyAddr;\r
+}\r
+\r
 \r
 /**\r
   Insert the memory block to the pool's list of the blocks.\r
index 8152ce813ba8a29207d932af3f8de445feaeb591..ce0a78298f93e59b26038426ca9f2768976970a5 100644 (file)
@@ -135,4 +135,21 @@ UsbHcFreeMem (
   IN VOID                 *Mem,\r
   IN UINTN                Size\r
   );\r
+\r
+/**\r
+  Get the pci memory address according to the allocated host memory address.\r
+\r
+  @param  Pool           The memory pool of the host controller.\r
+  @param  Mem            The memory to free.\r
+  @param  Size           The size of the memory to free.\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