}\r
}\r
\r
+STATIC\r
+EFI_STATUS\r
+EhcFlushAsyncIntMap (\r
+ IN USB2_HC_DEV *Ehc,\r
+ IN URB *Urb\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Flush data from PCI controller specific address to mapped system \r
+ memory address.\r
+\r
+Arguments:\r
+\r
+ Ehc - The EHCI device\r
+ Urb - The URB to unmap\r
+ \r
+Returns:\r
+\r
+ EFI_SUCCESS - Success to flush data to mapped system memory\r
+ EFI_DEVICE_ERROR - Fail to flush data to mapped system memory\r
+\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
/**\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
+ EHC_ERROR (("EhcMoniteAsyncRequests: 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