EhcUnlinkQhFromPeriod (Ehc, Urb->Qh);\r
RemoveEntryList (&Urb->UrbList);\r
\r
+ gBS->FreePool (Urb->Data);\r
EhcFreeUrb (Ehc, Urb);\r
return EFI_SUCCESS;\r
}\r
EhcUnlinkQhFromPeriod (Ehc, Urb->Qh);\r
RemoveEntryList (&Urb->UrbList);\r
\r
+ gBS->FreePool (Urb->Data);\r
EhcFreeUrb (Ehc, Urb);\r
}\r
}\r
IN UINTN Interval\r
)\r
{\r
+ VOID *Data;\r
URB *Urb;\r
\r
+ Data = AllocatePool (DataLen);\r
+\r
+ if (Data == NULL) {\r
+ DEBUG ((DEBUG_ERROR, "%a: failed to allocate buffer\n", __FUNCTION__));\r
+ return NULL;\r
+ }\r
+\r
Urb = EhcCreateUrb (\r
Ehc,\r
DevAddr,\r
Hub,\r
EHC_INT_TRANSFER_ASYNC,\r
NULL,\r
- TRUE,\r
- NULL,\r
+ Data,\r
DataLen,\r
Callback,\r
Context,\r
\r
if (Urb == NULL) {\r
DEBUG ((DEBUG_ERROR, "%a: failed to create URB\n", __FUNCTION__));\r
+ gBS->FreePool (Data);\r
return NULL;\r
}\r
\r
return Urb;\r
}\r
\r
+/**\r
+ Flush data from PCI controller specific address to mapped system\r
+ memory address.\r
+\r
+ @param Ehc The EHCI 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
+EhcFlushAsyncIntMap (\r
+ IN USB2_HC_DEV *Ehc,\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 = Ehc->PciIo;\r
+ Len = Urb->DataLen;\r
+\r
+ if (Urb->Ep.Direction == EfiUsbDataIn) {\r
+ MapOp = EfiPciIoOperationBusMasterWrite;\r
+ } else {\r
+ MapOp = EfiPciIoOperationBusMasterRead;\r
+ }\r
+\r
+ Status = PciIo->Unmap (PciIo, Urb->DataMap);\r
+ if (EFI_ERROR (Status)) {\r
+ goto ON_ERROR;\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
/**\r
Update the queue head for next round of asynchronous transfer.\r
\r
BOOLEAN Finished;\r
UINT8 *ProcBuf;\r
URB *Urb;\r
+ EFI_STATUS Status;\r
\r
OldTpl = gBS->RaiseTPL (EHC_TPL);\r
Ehc = (USB2_HC_DEV *) Context;\r
continue;\r
}\r
\r
+ //\r
+ // Flush any PCI posted write transactions from a PCI host\r
+ // bridge to system memory.\r
+ //\r
+ Status = EhcFlushAsyncIntMap (Ehc, Urb);\r
+ if (EFI_ERROR (Status)) {\r
+ DEBUG ((EFI_D_ERROR, "EhcMonitorAsyncRequests: 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