]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Bus/Pci/XhciDxe/XhciSched.c
MdeModulePkg XhciDxe: Use common buffer for AsyncInterruptTransfer
[mirror_edk2.git] / MdeModulePkg / Bus / Pci / XhciDxe / XhciSched.c
index 75959ae08363eab97b9411e7cfacc10289576d1a..9dd45e93a272e491f944bd28b1d7ff9e6630db18 100644 (file)
@@ -118,17 +118,18 @@ ON_EXIT:
 /**\r
   Create a new URB for a new transaction.\r
 \r
-  @param  Xhc       The XHCI Instance\r
-  @param  BusAddr   The logical device address assigned by UsbBus driver\r
-  @param  EpAddr    Endpoint addrress\r
-  @param  DevSpeed  The device speed\r
-  @param  MaxPacket The max packet length of the endpoint\r
-  @param  Type      The transaction type\r
-  @param  Request   The standard USB request for control transfer\r
-  @param  Data      The user data to transfer\r
-  @param  DataLen   The length of data buffer\r
-  @param  Callback  The function to call when data is transferred\r
-  @param  Context   The context to the callback\r
+  @param  Xhc                   The XHCI Instance\r
+  @param  BusAddr               The logical device address assigned by UsbBus driver\r
+  @param  EpAddr                Endpoint addrress\r
+  @param  DevSpeed              The device speed\r
+  @param  MaxPacket             The max packet length of the endpoint\r
+  @param  Type                  The transaction type\r
+  @param  Request               The standard USB request for control transfer\r
+  @param  AllocateCommonBuffer  Indicate whether need to allocate common buffer for data transfer\r
+  @param  Data                  The user data to transfer, NULL if AllocateCommonBuffer is TRUE\r
+  @param  DataLen               The length of data buffer\r
+  @param  Callback              The function to call when data is transferred\r
+  @param  Context               The context to the callback\r
 \r
   @return Created URB or NULL\r
 \r
@@ -142,6 +143,7 @@ XhcCreateUrb (
   IN UINTN                              MaxPacket,\r
   IN UINTN                              Type,\r
   IN EFI_USB_DEVICE_REQUEST             *Request,\r
+  IN BOOLEAN                            AllocateCommonBuffer,\r
   IN VOID                               *Data,\r
   IN UINTN                              DataLen,\r
   IN EFI_ASYNC_USB_TRANSFER_CALLBACK    Callback,\r
@@ -169,8 +171,24 @@ XhcCreateUrb (
   Ep->Type      = Type;\r
 \r
   Urb->Request  = Request;\r
+  if (AllocateCommonBuffer) {\r
+    ASSERT (Data == NULL);\r
+    Status = Xhc->PciIo->AllocateBuffer (\r
+                           Xhc->PciIo,\r
+                           AllocateAnyPages,\r
+                           EfiBootServicesData,\r
+                           EFI_SIZE_TO_PAGES (DataLen),\r
+                           &Data,\r
+                           0\r
+                           );\r
+    if (EFI_ERROR (Status) || (Data == NULL)) {\r
+      FreePool (Urb);\r
+      return NULL;\r
+    }\r
+  }\r
   Urb->Data     = Data;\r
   Urb->DataLen  = DataLen;\r
+  Urb->AllocateCommonBuffer = AllocateCommonBuffer;\r
   Urb->Callback = Callback;\r
   Urb->Context  = Context;\r
 \r
@@ -178,7 +196,7 @@ XhcCreateUrb (
   ASSERT_EFI_ERROR (Status);\r
   if (EFI_ERROR (Status)) {\r
     DEBUG ((EFI_D_ERROR, "XhcCreateUrb: XhcCreateTransferTrb Failed, Status = %r\n", Status));\r
-    FreePool (Urb);\r
+    XhcFreeUrb (Xhc, Urb);\r
     Urb = NULL;\r
   }\r
 \r
@@ -206,6 +224,14 @@ XhcFreeUrb (
     Xhc->PciIo->Unmap (Xhc->PciIo, Urb->DataMap);\r
   }\r
 \r
+  if (Urb->AllocateCommonBuffer) {\r
+    Xhc->PciIo->FreeBuffer (\r
+                  Xhc->PciIo,\r
+                  EFI_SIZE_TO_PAGES (Urb->DataLen),\r
+                  Urb->Data\r
+                  );\r
+  }\r
+\r
   FreePool (Urb);\r
 }\r
 \r
@@ -264,10 +290,14 @@ XhcCreateTransferTrb (
   // No need to remap.\r
   //\r
   if ((Urb->Data != NULL) && (Urb->DataMap == NULL)) {\r
-    if (((UINT8) (Urb->Ep.Direction)) == EfiUsbDataIn) {\r
-      MapOp = EfiPciIoOperationBusMasterWrite;\r
+    if (Urb->AllocateCommonBuffer) {\r
+      MapOp = EfiPciIoOperationBusMasterCommonBuffer;\r
     } else {\r
-      MapOp = EfiPciIoOperationBusMasterRead;\r
+      if (((UINT8) (Urb->Ep.Direction)) == EfiUsbDataIn) {\r
+        MapOp = EfiPciIoOperationBusMasterWrite;\r
+      } else {\r
+        MapOp = EfiPciIoOperationBusMasterRead;\r
+      }\r
     }\r
 \r
     Len = Urb->DataLen;\r
@@ -1367,7 +1397,6 @@ XhciDelAsyncIntTransfer (
       }\r
 \r
       RemoveEntryList (&Urb->UrbList);\r
-      FreePool (Urb->Data);\r
       XhcFreeUrb (Xhc, Urb);\r
       return EFI_SUCCESS;\r
     }\r
@@ -1405,7 +1434,6 @@ XhciDelAllAsyncIntTransfers (
     }\r
 \r
     RemoveEntryList (&Urb->UrbList);\r
-    FreePool (Urb->Data);\r
     XhcFreeUrb (Xhc, Urb);\r
   }\r
 }\r
@@ -1438,15 +1466,8 @@ XhciInsertAsyncIntTransfer (
   IN VOID                               *Context\r
   )\r
 {\r
-  VOID      *Data;\r
   URB       *Urb;\r
 \r
-  Data = AllocateZeroPool (DataLen);\r
-  if (Data == NULL) {\r
-    DEBUG ((DEBUG_ERROR, "%a: failed to allocate buffer\n", __FUNCTION__));\r
-    return NULL;\r
-  }\r
-\r
   Urb = XhcCreateUrb (\r
           Xhc,\r
           BusAddr,\r
@@ -1455,14 +1476,14 @@ XhciInsertAsyncIntTransfer (
           MaxPacket,\r
           XHC_INT_TRANSFER_ASYNC,\r
           NULL,\r
-          Data,\r
+          TRUE,\r
+          NULL,\r
           DataLen,\r
           Callback,\r
           Context\r
           );\r
   if (Urb == NULL) {\r
     DEBUG ((DEBUG_ERROR, "%a: failed to create URB\n", __FUNCTION__));\r
-    FreePool (Data);\r
     return NULL;\r
   }\r
 \r
@@ -1502,61 +1523,6 @@ XhcUpdateAsyncRequest (
   }\r
 }\r
 \r
-/**\r
-  Flush data from PCI controller specific address to mapped system\r
-  memory address.\r
-\r
-  @param  Xhc                The XHCI device.\r
-  @param  Urb                The URB to unmap.\r
-\r
-  @retval EFI_SUCCESS        Success to flush data to mapped system memory.\r
-  @retval EFI_DEVICE_ERROR   Fail to flush data to mapped system memory.\r
-\r
-**/\r
-EFI_STATUS\r
-XhcFlushAsyncIntMap (\r
-  IN  USB_XHCI_INSTANCE   *Xhc,\r
-  IN  URB                 *Urb\r
-  )\r
-{\r
-  EFI_STATUS                    Status;\r
-  EFI_PHYSICAL_ADDRESS          PhyAddr;\r
-  EFI_PCI_IO_PROTOCOL_OPERATION MapOp;\r
-  EFI_PCI_IO_PROTOCOL           *PciIo;\r
-  UINTN                         Len;\r
-  VOID                          *Map;\r
-\r
-  PciIo = Xhc->PciIo;\r
-  Len   = Urb->DataLen;\r
-\r
-  if (Urb->Ep.Direction == EfiUsbDataIn) {\r
-    MapOp = EfiPciIoOperationBusMasterWrite;\r
-  } else {\r
-    MapOp = EfiPciIoOperationBusMasterRead;\r
-  }\r
-\r
-  if (Urb->DataMap != NULL) {\r
-    Status = PciIo->Unmap (PciIo, Urb->DataMap);\r
-    if (EFI_ERROR (Status)) {\r
-      goto ON_ERROR;\r
-    }\r
-  }\r
-\r
-  Urb->DataMap = NULL;\r
-\r
-  Status = PciIo->Map (PciIo, MapOp, Urb->Data, &Len, &PhyAddr, &Map);\r
-  if (EFI_ERROR (Status) || (Len != Urb->DataLen)) {\r
-    goto ON_ERROR;\r
-  }\r
-\r
-  Urb->DataPhy  = (VOID *) ((UINTN) PhyAddr);\r
-  Urb->DataMap  = Map;\r
-  return EFI_SUCCESS;\r
-\r
-ON_ERROR:\r
-  return EFI_DEVICE_ERROR;\r
-}\r
-\r
 /**\r
   Interrupt transfer periodic check handler.\r
 \r
@@ -1577,7 +1543,6 @@ XhcMonitorAsyncRequests (
   UINT8                   *ProcBuf;\r
   URB                     *Urb;\r
   UINT8                   SlotId;\r
-  EFI_STATUS              Status;\r
   EFI_TPL                 OldTpl;\r
 \r
   OldTpl = gBS->RaiseTPL (XHC_TPL);\r
@@ -1605,15 +1570,6 @@ XhcMonitorAsyncRequests (
       continue;\r
     }\r
 \r
-    //\r
-    // Flush any PCI posted write transactions from a PCI host\r
-    // bridge to system memory.\r
-    //\r
-    Status = XhcFlushAsyncIntMap (Xhc, Urb);\r
-    if (EFI_ERROR (Status)) {\r
-      DEBUG ((EFI_D_ERROR, "XhcMonitorAsyncRequests: Fail to Flush AsyncInt Mapped Memeory\n"));\r
-    }\r
-\r
     //\r
     // Allocate a buffer then copy the transferred data for user.\r
     // If failed to allocate the buffer, update the URB for next\r