]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Bus/Pci/EhciPei/EhciUrb.c
MdeModulePkg EhciPei: Support IoMmu
[mirror_edk2.git] / MdeModulePkg / Bus / Pci / EhciPei / EhciUrb.c
index 597a4947f5bc6e7bd9fba11463125ec5c70ce7c5..3dadcd60b6fec69825b64f98fa2d8041ad831ef6 100644 (file)
@@ -2,7 +2,7 @@
 PEIM to produce gPeiUsb2HostControllerPpiGuid based on gPeiUsbControllerPpiGuid\r
 which is used to enable recovery function from USB Drivers.\r
 \r
 PEIM to produce gPeiUsb2HostControllerPpiGuid based on gPeiUsbControllerPpiGuid\r
 which is used to enable recovery function from USB Drivers.\r
 \r
-Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2010 - 2017, Intel Corporation. All rights reserved.<BR>\r
   \r
 This program and the accompanying materials\r
 are licensed and made available under the terms and conditions\r
   \r
 This program and the accompanying materials\r
 are licensed and made available under the terms and conditions\r
@@ -301,7 +301,7 @@ EhcFreeQtds (
     Qtd = EFI_LIST_CONTAINER (Entry, PEI_EHC_QTD, QtdList);\r
 \r
     RemoveEntryList (&Qtd->QtdList);\r
     Qtd = EFI_LIST_CONTAINER (Entry, PEI_EHC_QTD, QtdList);\r
 \r
     RemoveEntryList (&Qtd->QtdList);\r
-    UsbHcFreeMem (Ehc->MemPool, Qtd, sizeof (PEI_EHC_QTD));\r
+    UsbHcFreeMem (Ehc, Ehc->MemPool, Qtd, sizeof (PEI_EHC_QTD));\r
   }\r
 }\r
 \r
   }\r
 }\r
 \r
@@ -318,13 +318,21 @@ EhcFreeUrb (
   IN PEI_URB              *Urb\r
   )\r
 {\r
   IN PEI_URB              *Urb\r
   )\r
 {\r
+  if (Urb->RequestPhy != NULL) {\r
+    IoMmuUnmap (Ehc->IoMmu, Urb->RequestMap);\r
+  }\r
+\r
+  if (Urb->DataMap != NULL) {\r
+    IoMmuUnmap (Ehc->IoMmu, Urb->DataMap);\r
+  }\r
+\r
   if (Urb->Qh != NULL) {\r
     //\r
     // Ensure that this queue head has been unlinked from the\r
     // schedule data structures. Free all the associated QTDs\r
     //\r
     EhcFreeQtds (Ehc, &Urb->Qh->Qtds);\r
   if (Urb->Qh != NULL) {\r
     //\r
     // Ensure that this queue head has been unlinked from the\r
     // schedule data structures. Free all the associated QTDs\r
     //\r
     EhcFreeQtds (Ehc, &Urb->Qh->Qtds);\r
-    UsbHcFreeMem (Ehc->MemPool, Urb->Qh, sizeof (PEI_EHC_QH));\r
+    UsbHcFreeMem (Ehc, Ehc->MemPool, Urb->Qh, sizeof (PEI_EHC_QH));\r
   }\r
 }\r
 \r
   }\r
 }\r
 \r
@@ -527,13 +535,11 @@ EhcCreateUrb (
 {\r
   USB_ENDPOINT                  *Ep;\r
   EFI_PHYSICAL_ADDRESS          PhyAddr;\r
 {\r
   USB_ENDPOINT                  *Ep;\r
   EFI_PHYSICAL_ADDRESS          PhyAddr;\r
+  EDKII_IOMMU_OPERATION         MapOp;\r
   EFI_STATUS                    Status;\r
   UINTN                         Len;\r
   PEI_URB                       *Urb;\r
   VOID                          *Map;\r
   EFI_STATUS                    Status;\r
   UINTN                         Len;\r
   PEI_URB                       *Urb;\r
   VOID                          *Map;\r
-\r
-    \r
-  Map = NULL;\r
   \r
   Urb = Ehc->Urb;\r
   Urb->Signature  = EHC_URB_SIG;\r
   \r
   Urb = Ehc->Urb;\r
   Urb->Signature  = EHC_URB_SIG;\r
@@ -576,24 +582,40 @@ EhcCreateUrb (
   //\r
   if (Request != NULL) {\r
     Len     = sizeof (EFI_USB_DEVICE_REQUEST);\r
   //\r
   if (Request != NULL) {\r
     Len     = sizeof (EFI_USB_DEVICE_REQUEST);\r
-    PhyAddr =  (EFI_PHYSICAL_ADDRESS) (UINTN) Request ;\r
-    if ( (Len != sizeof (EFI_USB_DEVICE_REQUEST))) {\r
+    MapOp   = EdkiiIoMmuOperationBusMasterRead;\r
+    Status  = IoMmuMap (Ehc->IoMmu, MapOp, Request, &Len, &PhyAddr, &Map);\r
+\r
+    if (EFI_ERROR (Status) || (Len != sizeof (EFI_USB_DEVICE_REQUEST))) {\r
       goto ON_ERROR;\r
     }\r
 \r
     Urb->RequestPhy = (VOID *) ((UINTN) PhyAddr);\r
     Urb->RequestMap = Map;\r
       goto ON_ERROR;\r
     }\r
 \r
     Urb->RequestPhy = (VOID *) ((UINTN) PhyAddr);\r
     Urb->RequestMap = Map;\r
+  } else {\r
+    Urb->RequestPhy = NULL;\r
+    Urb->RequestMap = NULL;\r
   }\r
 \r
   if (Data != NULL) {\r
     Len      = DataLen;\r
   }\r
 \r
   if (Data != NULL) {\r
     Len      = DataLen;\r
-    PhyAddr  =  (EFI_PHYSICAL_ADDRESS) (UINTN) Data ;\r
-    if ( (Len != DataLen)) {\r
+\r
+    if (Ep->Direction == EfiUsbDataIn) {\r
+      MapOp = EdkiiIoMmuOperationBusMasterWrite;\r
+    } else {\r
+      MapOp = EdkiiIoMmuOperationBusMasterRead;\r
+    }\r
+\r
+    Status  = IoMmuMap (Ehc->IoMmu, MapOp, Data, &Len, &PhyAddr, &Map);\r
+\r
+    if (EFI_ERROR (Status) || (Len != DataLen)) {\r
       goto ON_ERROR;\r
     }\r
 \r
     Urb->DataPhy  = (VOID *) ((UINTN) PhyAddr);\r
     Urb->DataMap  = Map;\r
       goto ON_ERROR;\r
     }\r
 \r
     Urb->DataPhy  = (VOID *) ((UINTN) PhyAddr);\r
     Urb->DataMap  = Map;\r
+  } else {\r
+    Urb->DataPhy  = NULL;\r
+    Urb->DataMap  = NULL;\r
   }\r
 \r
   Status = EhcCreateQtds (Ehc, Urb);\r
   }\r
 \r
   Status = EhcCreateQtds (Ehc, Urb);\r