]> git.proxmox.com Git - mirror_edk2.git/commitdiff
update Ehci driver to distinct pci memory address and host address
authorerictian <erictian@6f19259b-4bc3-4df7-8a09-765794883524>
Sun, 28 Feb 2010 13:00:58 +0000 (13:00 +0000)
committererictian <erictian@6f19259b-4bc3-4df7-8a09-765794883524>
Sun, 28 Feb 2010 13:00:58 +0000 (13:00 +0000)
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@10121 6f19259b-4bc3-4df7-8a09-765794883524

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

index 3161ede9498ff0340105f003c4664c7619f7b22d..6cf4aefea668e596780eea7401147e7ea3135671 100644 (file)
@@ -969,7 +969,8 @@ EhcAsyncInterruptTransfer (
   //\r
   // Validate parameters\r
   //\r
-  if (!EHCI_IS_DATAIN (EndPointAddress)) {\r
+  if (!(EndPointAddress >= 0x01 && EndPointAddress <= 0x0F)\r
+    && !(EndPointAddress >= 0x81 && EndPointAddress <= 0x8F)) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
@@ -1118,7 +1119,8 @@ EhcSyncInterruptTransfer (
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
-  if (!EHCI_IS_DATAIN (EndPointAddress)) {\r
+  if (!(EndPointAddress >= 0x01 && EndPointAddress <= 0x0F)\r
+    && !(EndPointAddress >= 0x81 && EndPointAddress <= 0x8F)) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
index 07abcaf82c2056e6e65085f6bccee1493ebffc70..d6f0003557fb286b9604d47473b8304c25fedd3d 100644 (file)
@@ -139,8 +139,8 @@ struct _USB2_HC_DEV {
   //\r
   // Peroidic (interrupt) transfer schedule data:\r
   //\r
-  VOID                      *PeriodFrame;     // Mapped as common buffer\r
-  VOID                      *PeriodFrameHost;\r
+  VOID                      *PeriodFrame;     // the buffer pointed by this pointer is used to store pci bus address of the QH descriptor.\r
+  VOID                      *PeriodFrameHost; // the buffer pointed by this pointer is used to store host memory address of the QH descriptor.\r
   VOID                      *PeriodFrameMap;\r
 \r
   EHC_QH                    *PeriodOne;\r
@@ -152,7 +152,6 @@ struct _USB2_HC_DEV {
   UINT32                    HcStructParams; // Cache of HC structure parameter, EHC_HCSPARAMS_OFFSET\r
   UINT32                    HcCapParams;    // Cache of HC capability parameter, HCCPARAMS\r
   UINT32                    CapLen;         // Capability length\r
-  UINT32                    High32bitAddr;\r
 \r
   //\r
   // Misc\r
index 7a533d78e13d9afd81a025985cdcee6082f78b9d..0b8187a52d73b81f01bcc5436d9bb5dacef09151 100644 (file)
@@ -564,7 +564,7 @@ EhcInitHC (
   // Allocate the periodic frame and associated memeory\r
   // management facilities if not already done.\r
   //\r
-  if (Ehc->PeriodFrameHost != NULL) {\r
+  if (Ehc->PeriodFrame != NULL) {\r
     EhcFreeSched (Ehc);\r
   }\r
 \r
@@ -573,24 +573,20 @@ EhcInitHC (
   if (EFI_ERROR (Status)) {\r
     return Status;\r
   }\r
-  //\r
-  // 1. Program the CTRLDSSEGMENT register with the high 32 bit addr\r
-  //\r
-  EhcWriteOpReg (Ehc, EHC_CTRLDSSEG_OFFSET, Ehc->High32bitAddr);\r
 \r
   //\r
-  // 2. Clear USBINTR to disable all the interrupt. UEFI works by polling\r
+  // 1. Clear USBINTR to disable all the interrupt. UEFI works by polling\r
   //\r
   EhcWriteOpReg (Ehc, EHC_USBINTR_OFFSET, 0);\r
 \r
   //\r
-  // 3. Program periodic frame list, already done in EhcInitSched\r
-  // 4. Start the Host Controller\r
+  // 2. Program periodic frame list, already done in EhcInitSched\r
+  // 3. Start the Host Controller\r
   //\r
   EhcSetOpRegBit (Ehc, EHC_USBCMD_OFFSET, USBCMD_RUN);\r
 \r
   //\r
-  // 5. Set all ports routing to EHC\r
+  // 4. Set all ports routing to EHC\r
   //\r
   EhcSetOpRegBit (Ehc, EHC_CONFIG_FLAG_OFFSET, CONFIGFLAG_ROUTE_EHC);\r
 \r
index c1d44f52827c0f2d5bae0bfe1a345916ae43c7fa..208620640498e55eb377bea6e3ea9dbdcfbcd6dd 100644 (file)
@@ -116,7 +116,6 @@ EhcInitSched (
   UINTN                 Pages;\r
   UINTN                 Bytes;\r
   UINTN                 Index;\r
-  UINT32                *Desc;\r
   EFI_STATUS            Status;\r
   EFI_PHYSICAL_ADDRESS  PciAddr;\r
 \r
@@ -159,10 +158,17 @@ EhcInitSched (
     return EFI_OUT_OF_RESOURCES;\r
   }\r
 \r
-  Ehc->PeriodFrameHost  = Buf;\r
-  Ehc->PeriodFrame      = (VOID *) ((UINTN) PhyAddr);\r
+  Ehc->PeriodFrame      = Buf;\r
   Ehc->PeriodFrameMap   = Map;\r
-  Ehc->High32bitAddr    = EHC_HIGH_32BIT (PhyAddr);\r
+\r
+  //\r
+  // Program the FRAMELISTBASE register with the low 32 bit addr\r
+  //\r
+  EhcWriteOpReg (Ehc, EHC_FRAME_BASE_OFFSET, EHC_LOW_32BIT (PhyAddr));\r
+  //\r
+  // Program the CTRLDSSEGMENT register with the high 32 bit addr\r
+  //\r
+  EhcWriteOpReg (Ehc, EHC_CTRLDSSEG_OFFSET, EHC_HIGH_32BIT (PhyAddr));\r
 \r
   //\r
   // Init memory pool management then create the helper\r
@@ -172,31 +178,41 @@ EhcInitSched (
   Ehc->MemPool = UsbHcInitMemPool (\r
                    PciIo,\r
                    EHC_BIT_IS_SET (Ehc->HcCapParams, HCCP_64BIT),\r
-                   Ehc->High32bitAddr\r
+                   EHC_HIGH_32BIT (PhyAddr)\r
                    );\r
 \r
   if (Ehc->MemPool == NULL) {\r
-    return EFI_OUT_OF_RESOURCES;\r
+    goto ErrorExit;\r
   }\r
 \r
   Status = EhcCreateHelpQ (Ehc);\r
 \r
   if (EFI_ERROR (Status)) {\r
-    return Status;\r
+    goto ErrorExit;\r
   }\r
 \r
   //\r
   // Initialize the frame list entries then set the registers\r
   //\r
-  Desc = (UINT32 *) Ehc->PeriodFrameHost;\r
+  Ehc->PeriodFrameHost      = AllocateZeroPool (EHC_FRAME_LEN * sizeof (UINTN));\r
+  if (Ehc->PeriodFrameHost == NULL) {\r
+    Status = EFI_OUT_OF_RESOURCES;\r
+    goto ErrorExit;\r
+  }\r
+\r
+  PciAddr  = UsbHcGetPciAddressForHostMem (Ehc->MemPool, Ehc->PeriodOne, sizeof (EHC_QH));\r
 \r
   for (Index = 0; Index < EHC_FRAME_LEN; Index++) {\r
-    PciAddr     = UsbHcGetPciAddressForHostMem (Ehc->MemPool, Ehc->PeriodOne, sizeof (EHC_QH));\r
-    Desc[Index] = QH_LINK (PciAddr, EHC_TYPE_QH, FALSE);\r
+    //\r
+    // Store the pci bus address of the QH in period frame list which will be accessed by pci bus master.\r
+    //\r
+    ((UINT32 *)(Ehc->PeriodFrame))[Index] = QH_LINK (PciAddr, EHC_TYPE_QH, FALSE);\r
+    //\r
+    // Store the host address of the QH in period frame list which will be accessed by host.\r
+    //\r
+    ((UINTN *)(Ehc->PeriodFrameHost))[Index] = (UINTN)Ehc->PeriodOne;\r
   }\r
 \r
-  EhcWriteOpReg (Ehc, EHC_FRAME_BASE_OFFSET, EHC_LOW_32BIT (Ehc->PeriodFrame));\r
-\r
   //\r
   // Second initialize the asynchronous schedule:\r
   // Only need to set the AsynListAddr register to\r
@@ -205,6 +221,26 @@ EhcInitSched (
   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
+ErrorExit:\r
+  PciIo->FreeBuffer (PciIo, Pages, Buf);\r
+  PciIo->Unmap (PciIo, Map);\r
+\r
+  if (Ehc->PeriodOne != NULL) {\r
+    UsbHcFreeMem (Ehc->MemPool, Ehc->PeriodOne, sizeof (EHC_QH));\r
+    Ehc->PeriodOne = NULL;\r
+  }\r
+\r
+  if (Ehc->ReclaimHead != NULL) {\r
+    UsbHcFreeMem (Ehc->MemPool, Ehc->ReclaimHead, sizeof (EHC_QH));\r
+    Ehc->ReclaimHead = NULL;\r
+  }\r
+\r
+  if (Ehc->ShortReadStop != NULL) {\r
+    UsbHcFreeMem (Ehc->MemPool, Ehc->ShortReadStop, sizeof (EHC_QTD));\r
+    Ehc->ShortReadStop = NULL;\r
+  }\r
+  return Status;\r
 }\r
 \r
 \r
@@ -244,7 +280,7 @@ EhcFreeSched (
     Ehc->MemPool = NULL;\r
   }\r
 \r
-  if (Ehc->PeriodFrameHost != NULL) {\r
+  if (Ehc->PeriodFrame != NULL) {\r
     PciIo = Ehc->PciIo;\r
     ASSERT (PciIo != NULL);\r
 \r
@@ -253,11 +289,15 @@ EhcFreeSched (
     PciIo->FreeBuffer (\r
              PciIo,\r
              EFI_SIZE_TO_PAGES (EFI_PAGE_SIZE),\r
-             Ehc->PeriodFrameHost\r
+             Ehc->PeriodFrame\r
              );\r
 \r
+    Ehc->PeriodFrame = NULL;\r
+  }\r
+\r
+  if (Ehc->PeriodFrameHost != NULL) {\r
+    FreePool (Ehc->PeriodFrameHost);\r
     Ehc->PeriodFrameHost = NULL;\r
-    Ehc->PeriodFrame     = NULL;\r
   }\r
 }\r
 \r
@@ -293,7 +333,7 @@ EhcLinkQhToAsync (
   Head->NextQh            = Qh;\r
 \r
   PciAddr = UsbHcGetPciAddressForHostMem (Ehc->MemPool, Head, sizeof (EHC_QH));\r
-  Qh->QhHw.HorizonLink    = QH_LINK (PciAddr, EHC_TYPE_QH, FALSE);;\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
@@ -358,21 +398,18 @@ EhcLinkQhToPeriod (
   IN EHC_QH               *Qh\r
   )\r
 {\r
-  UINT32                  *Frames;\r
   UINTN                   Index;\r
   EHC_QH                  *Prev;\r
   EHC_QH                  *Next;\r
   EFI_PHYSICAL_ADDRESS    PciAddr;\r
 \r
-  Frames = Ehc->PeriodFrameHost;\r
-\r
   for (Index = 0; Index < EHC_FRAME_LEN; Index += Qh->Interval) {\r
     //\r
     // First QH can't be NULL because we always keep PeriodOne\r
     // heads on the frame list\r
     //\r
-    ASSERT (!EHC_LINK_TERMINATED (Frames[Index]));\r
-    Next  = EHC_ADDR (Ehc->High32bitAddr, Frames[Index]);\r
+    ASSERT (!EHC_LINK_TERMINATED (((UINT32*)Ehc->PeriodFrame)[Index]));\r
+    Next  = (EHC_QH*)((UINTN*)Ehc->PeriodFrameHost)[Index];\r
     Prev  = NULL;\r
 \r
     //\r
@@ -439,7 +476,8 @@ EhcLinkQhToPeriod (
     PciAddr = UsbHcGetPciAddressForHostMem (Ehc->MemPool, Qh, sizeof (EHC_QH));\r
 \r
     if (Prev == NULL) {\r
-      Frames[Index] = QH_LINK (PciAddr, EHC_TYPE_QH, FALSE);\r
+      ((UINT32*)Ehc->PeriodFrame)[Index]     = QH_LINK (PciAddr, EHC_TYPE_QH, FALSE);\r
+      ((UINTN*)Ehc->PeriodFrameHost)[Index]  = (UINTN)Qh;\r
     } else {\r
       Prev->NextQh            = Qh;\r
       Prev->QhHw.HorizonLink  = QH_LINK (PciAddr, EHC_TYPE_QH, FALSE);\r
@@ -462,20 +500,17 @@ EhcUnlinkQhFromPeriod (
   IN EHC_QH               *Qh\r
   )\r
 {\r
-  UINT32                  *Frames;\r
   UINTN                   Index;\r
   EHC_QH                  *Prev;\r
   EHC_QH                  *This;\r
 \r
-  Frames = Ehc->PeriodFrameHost;\r
-\r
   for (Index = 0; Index < EHC_FRAME_LEN; Index += Qh->Interval) {\r
     //\r
     // Frame link can't be NULL because we always keep PeroidOne\r
     // on the frame list\r
     //\r
-    ASSERT (!EHC_LINK_TERMINATED (Frames[Index]));\r
-    This  = EHC_ADDR (Ehc->High32bitAddr, Frames[Index]);\r
+    ASSERT (!EHC_LINK_TERMINATED (((UINT32*)Ehc->PeriodFrame)[Index]));\r
+    This  = (EHC_QH*)((UINTN*)Ehc->PeriodFrameHost)[Index];\r
     Prev  = NULL;\r
 \r
     //\r
@@ -499,7 +534,8 @@ EhcUnlinkQhFromPeriod (
       //\r
       // Qh is the first entry in the frame\r
       //\r
-      Frames[Index] = Qh->QhHw.HorizonLink;\r
+      ((UINT32*)Ehc->PeriodFrame)[Index] = Qh->QhHw.HorizonLink;\r
+      ((UINTN*)Ehc->PeriodFrameHost)[Index] = (UINTN)Qh->NextQh;\r
     } else {\r
       Prev->NextQh            = Qh->NextQh;\r
       Prev->QhHw.HorizonLink  = Qh->QhHw.HorizonLink;\r
index 069ee5f57552901bc0e95fb17fb8118e1826aa72..5194d540a719bae1049fdd311047b8f1303caa3a 100644 (file)
@@ -218,15 +218,15 @@ UsbHcAllocMemFromBlock (
     NEXT_BIT (Byte, Bit);\r
   }\r
 \r
-  return Block->Buf + (StartByte * 8 + StartBit) * USBHC_MEM_UNIT;\r
+  return Block->BufHost + (StartByte * 8 + StartBit) * USBHC_MEM_UNIT;\r
 }\r
 \r
 /**\r
-  Get the pci memory address according to the allocated host memory address.\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 memory to free.\r
-  @param  Size           The size of the memory to free.\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
@@ -251,7 +251,7 @@ UsbHcGetPciAddressForHostMem (
     // 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
+    if ((Block->BufHost <= (UINT8 *) Mem) && (((UINT8 *) Mem + AllocSize) <= (Block->BufHost + Block->BufLen))) {\r
       break;\r
     }\r
   }\r
@@ -522,12 +522,12 @@ UsbHcFreeMem (
     // scan the memory block list for the memory block that\r
     // completely contains the memory to free.\r
     //\r
-    if ((Block->Buf <= ToFree) && ((ToFree + AllocSize) <= (Block->Buf + Block->BufLen))) {\r
+    if ((Block->BufHost <= ToFree) && ((ToFree + AllocSize) <= (Block->BufHost + Block->BufLen))) {\r
       //\r
       // compute the start byte and bit in the bit array\r
       //\r
-      Byte  = ((ToFree - Block->Buf) / USBHC_MEM_UNIT) / 8;\r
-      Bit   = ((ToFree - Block->Buf) / USBHC_MEM_UNIT) % 8;\r
+      Byte  = ((ToFree - Block->BufHost) / USBHC_MEM_UNIT) / 8;\r
+      Bit   = ((ToFree - Block->BufHost) / USBHC_MEM_UNIT) % 8;\r
 \r
       //\r
       // reset associated bits in bit arry\r
index 3394c9b99e681256617c5a9dbc8143047cb96191..f851868d10e1fbaffd75e4323c71602629f5aef3 100644 (file)
@@ -139,11 +139,11 @@ UsbHcFreeMem (
   );\r
 \r
 /**\r
-  Get the pci memory address according to the allocated host memory address.\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 memory to free.\r
-  @param  Size           The size of the memory to free.\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