/**\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 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
+ @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
\r
@return Created URB or NULL\r
\r
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
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
ASSERT_EFI_ERROR (Status);\r
if (EFI_ERROR (Status)) {\r
DEBUG ((EFI_D_ERROR, "XhcCreateUrb: XhcCreateTransferTrb Failed, Status = %r\n", Status));\r
- XhcFreeUrb (Xhc, Urb);\r
+ FreePool (Urb);\r
Urb = NULL;\r
}\r
\r
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
// No need to remap.\r
//\r
if ((Urb->Data != NULL) && (Urb->DataMap == NULL)) {\r
- if (Urb->AllocateCommonBuffer) {\r
- MapOp = EfiPciIoOperationBusMasterCommonBuffer;\r
+ if (((UINT8) (Urb->Ep.Direction)) == EfiUsbDataIn) {\r
+ MapOp = EfiPciIoOperationBusMasterWrite;\r
} else {\r
- if (((UINT8) (Urb->Ep.Direction)) == EfiUsbDataIn) {\r
- MapOp = EfiPciIoOperationBusMasterWrite;\r
- } else {\r
- MapOp = EfiPciIoOperationBusMasterRead;\r
- }\r
+ MapOp = EfiPciIoOperationBusMasterRead;\r
}\r
\r
Len = Urb->DataLen;\r
}\r
\r
RemoveEntryList (&Urb->UrbList);\r
+ FreePool (Urb->Data);\r
XhcFreeUrb (Xhc, Urb);\r
return EFI_SUCCESS;\r
}\r
}\r
\r
RemoveEntryList (&Urb->UrbList);\r
+ FreePool (Urb->Data);\r
XhcFreeUrb (Xhc, Urb);\r
}\r
}\r
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
MaxPacket,\r
XHC_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
+ FreePool (Data);\r
return NULL;\r
}\r
\r
}\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
UINT8 *ProcBuf;\r
URB *Urb;\r
UINT8 SlotId;\r
+ EFI_STATUS Status;\r
EFI_TPL OldTpl;\r
\r
OldTpl = gBS->RaiseTPL (XHC_TPL);\r
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
//\r
USB_ENDPOINT Ep;\r
EFI_USB_DEVICE_REQUEST *Request;\r
- BOOLEAN AllocateCommonBuffer;\r
VOID *Data;\r
UINTN DataLen;\r
VOID *DataPhy;\r
/**\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 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
+ @param Xhc The XHCI Instance\r
+ @param DevAddr The device address\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
\r
@return Created URB or NULL\r
\r
URB*\r
XhcCreateUrb (\r
IN USB_XHCI_INSTANCE *Xhc,\r
- IN UINT8 BusAddr,\r
+ IN UINT8 DevAddr,\r
IN UINT8 EpAddr,\r
IN UINT8 DevSpeed,\r
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