]> 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
-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
@@ -301,7 +301,7 @@ EhcFreeQtds (
     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
@@ -318,13 +318,21 @@ EhcFreeUrb (
   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
-    UsbHcFreeMem (Ehc->MemPool, Urb->Qh, sizeof (PEI_EHC_QH));\r
+    UsbHcFreeMem (Ehc, Ehc->MemPool, Urb->Qh, sizeof (PEI_EHC_QH));\r
   }\r
 }\r
 \r
@@ -527,13 +535,11 @@ EhcCreateUrb (
 {\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
-\r
-    \r
-  Map = NULL;\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
-    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
+  } else {\r
+    Urb->RequestPhy = NULL;\r
+    Urb->RequestMap = NULL;\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
+  } else {\r
+    Urb->DataPhy  = NULL;\r
+    Urb->DataMap  = NULL;\r
   }\r
 \r
   Status = EhcCreateQtds (Ehc, Urb);\r